Initial USB device stack for STM32.

Patch provided by Gareth McMullin <gareth@blacksphere.co.nz>,
thanks a lot!
This commit is contained in:
Uwe Hermann
2010-11-02 02:02:21 +01:00
parent 1621fde1f4
commit 6e090ccee1
30 changed files with 2913 additions and 10 deletions

View File

@@ -396,8 +396,10 @@ void rcc_set_adcpre(u32 adcpre);
void rcc_set_ppre2(u32 ppre2);
void rcc_set_ppre1(u32 ppre1);
void rcc_set_hpre(u32 hpre);
void rcc_set_usbpre(u32 usbpre);
u32 rcc_get_system_clock_source(int i);
void rcc_clock_setup_in_hsi_out_64mhz(void);
void rcc_clock_setup_in_hsi_out_48mhz(void);
void rcc_clock_setup_in_hse_8mhz_out_72mhz(void);
void rcc_clock_setup_in_hse_16mhz_out_72mhz(void);
void rcc_backupdomain_reset(void);

View File

@@ -122,6 +122,7 @@
/* VECTKEYSTAT[31:16]/ VECTKEY[31:16] Register key */
#define SCB_AIRCR_VECTKEYSTAT_LSB 16
#define SCB_AIRCR_VECTKEY 0x05FA0000
/* ENDIANESS Data endianness bit */
#define SCB_AIRCR_ENDIANESS (1 << 15)
/* Bits [14:11]: reserved - must be kept cleared */
@@ -291,6 +292,8 @@
/* BFAR [31:0]: Bus fault address */
/* --- SCB functions ------------------------------------------------------- */
void scb_reset_core(void);
void scb_reset_system(void);
/* TODO: */

View File

@@ -51,7 +51,7 @@
* TODO: We may need a faster implementation of that one?
*/
#define TOG_SET_REG_BIT_MSK(REG, MSK, BIT) \
{ \
do { \
register u16 toggle_mask = GET_REG(REG) & MSK; \
register u16 bit_selector; \
for (bit_selector = 1; bit_selector; bit_selector <<= 1) { \
@@ -59,6 +59,6 @@
toggle_mask ^= bit_selector; \
} \
SET_REG(REG, toggle_mask); \
}
} while(0)
#endif

View File

@@ -20,6 +20,10 @@
#ifndef LIBOPENSTM32_USB_H
#define LIBOPENSTM32_USB_H
#include <libopenstm32/memorymap.h>
#include <libopenstm32/common.h>
#include <libopenstm32/tools.h>
/******************************************************************************
* USB base addresses
******************************************************************************/
@@ -42,7 +46,7 @@
/* USB Buffer table address register */
#define USB_BTABLE_REG ((volatile u32 *)(USB_DEV_FS_BASE + 0x50))
/* USB EP register */
#define USB_EP_REG(EP) ((volatile u32 *)(USB_DEV_FS_BASE + EP))
#define USB_EP_REG(EP) ((volatile u32 *)(USB_DEV_FS_BASE) + (EP))
/******************************************************************************
* USB control register masks / bits

73
include/usbd.h Normal file
View File

@@ -0,0 +1,73 @@
/*
* This file is part of the libopenstm32 project.
*
* Copyright (C) 2010 Gareth McMullin <gareth@blacksphere.co.nz>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef __USBD_H
#define __USBD_H
#include <usbstd.h>
/* Static buffer for control transactions:
* This is defined as weak in the library, applicaiton
* may provide if a larger buffer is requred. */
extern uint8_t usbd_control_buffer[];
/* <usb.c> */
extern int usbd_init(const struct usb_device_descriptor *dev,
const struct usb_config_descriptor *conf,
const char **strings);
extern void usbd_set_control_buffer_size(uint16_t size);
extern void usbd_register_reset_callback(void (*callback)(void));
extern void usbd_register_suspend_callback(void (*callback)(void));
extern void usbd_register_resume_callback(void (*callback)(void));
/* <usb_control.c> */
extern void usbd_register_control_command_callback(
int (*callback)(struct usb_setup_data *req,
void (**complete)(struct usb_setup_data *req)));
extern void usbd_register_control_read_callback(
int (*callback)(struct usb_setup_data *req, uint8_t **buf,
uint16_t *len, void (**complete)(struct usb_setup_data *req)));
extern void usbd_register_control_write_callback(
int (*callback)(struct usb_setup_data *req, uint8_t *buf,
uint16_t len, void (**complete)(struct usb_setup_data *req)));
/* <usb_standard.c> */
extern void
usbd_register_set_config_callback(void (*callback)(uint16_t wValue));
/* Functions to be provided by the hardware abstraction layer */
extern void usbd_poll(void);
extern void usbd_ep_setup(uint8_t addr, uint8_t type, uint16_t max_size,
void (*callback)(uint8_t ep));
extern uint16_t
usbd_ep_write_packet(uint8_t addr, const void *buf, uint16_t len);
extern uint16_t
usbd_ep_read_packet(uint8_t addr, void *buf, uint16_t len);
extern void usbd_ep_stall(uint8_t addr);
/* Optional */
extern void usbd_cable_connect(uint8_t on);
#endif

198
include/usbstd.h Normal file
View File

@@ -0,0 +1,198 @@
/*
* This file is part of the libopenstm32 project.
*
* Copyright (C) 2010 Gareth McMullin <gareth@blacksphere.co.nz>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef __USBSTD_H
#define __USBSTD_H
/*
* This file contains structure definitions for the USB control structures
* defined in chapter 9 of the "Univeral Serial Bus Specification Revision 2.0"
* Available from the USB Implementers Forum - http://www.usb.org/
*/
#include <stdint.h>
/* USB Setup Data structure - Table 9-2 */
struct usb_setup_data {
uint8_t bmRequestType;
uint8_t bRequest;
uint16_t wValue;
uint16_t wIndex;
uint16_t wLength;
} __attribute__((packed));
/* bmRequestType bit definitions */
#define USB_REQ_TYPE_IN 0x80
#define USB_REQ_TYPE_STANDARD 0x00
#define USB_REQ_TYPE_CLASS 0x20
#define USB_REQ_TYPE_VENDOR 0x40
#define USB_REQ_TYPE_DEVICE 0x00
#define USB_REQ_TYPE_INTERFACE 0x01
#define USB_REQ_TYPE_ENDPOINT 0x02
/* USB Standard Request Codes - Table 9-4 */
#define USB_REQ_GET_STATUS 0
#define USB_REQ_CLEAR_FEATURE 1
/* Reserved for future use: 2 */
#define USB_REQ_SET_FEATURE 3
/* Reserved for future use: 3 */
#define USB_REQ_SET_ADDRESS 5
#define USB_REQ_GET_DESCRIPTOR 6
#define USB_REQ_SET_DESCRIPTOR 7
#define USB_REQ_GET_CONFIGURATION 8
#define USB_REQ_SET_CONFIGURATION 9
#define USB_REQ_GET_INTERFACE 10
#define USB_REQ_SET_INTERFACE 11
#define USB_REQ_SET_SYNCH_FRAME 12
/* USB Descriptor Types - Table 9-5 */
#define USB_DT_DEVICE 1
#define USB_DT_CONFIGURATION 2
#define USB_DT_STRING 3
#define USB_DT_INTERFACE 4
#define USB_DT_ENDPOINT 5
#define USB_DT_DEVICE_QUALIFIER 6
#define USB_DT_OTHER_SPEED_CONFIGURATION 7
#define USB_DT_INTERFACE_POWER 8
/* USB Standard Feature Selectors - Table 9-6 */
#define USB_FEAT_DEVICE_REMOTE_WAKEUP 1
#define USB_FEAT_ENDPOINT_HALT 0
#define USB_FEAT_TEST_MOED 2
/* Information Returned by a GetStatus() Request to a Device - Figure 9-4 */
#define USB_DEV_STATUS_SELF_POWERED 0x01
#define USB_DEV_STATUS_REMOTE_WAKEUP 0x02
/* USB Standard Device Descriptor - Table 9-8 */
struct usb_device_descriptor {
uint8_t bLength;
uint8_t bDescriptorType;
uint16_t bcdUSB;
uint8_t bDeviceClass;
uint8_t bDeviceSubClass;
uint8_t bDeviceProtocol;
uint8_t bMaxPacketSize0;
uint16_t idVendor;
uint16_t idProduct;
uint16_t bcdDevice;
uint8_t iManufacturer;
uint8_t iProduct;
uint8_t iSerialNumber;
uint8_t bNumConfigurations;
} __attribute__((packed));
#define USB_DT_DEVICE_SIZE sizeof(struct usb_device_descriptor)
/* USB Device_Qualifier Descriptor - Table 9-9
* Not used in this implementation.
*/
struct usb_device_qualifier_descriptor {
uint8_t bLength;
uint8_t bDescriptorType;
uint16_t bcdUSB;
uint8_t bDeviceClass;
uint8_t bDeviceSubClass;
uint8_t bDeviceProtocol;
uint8_t bMaxPacketSize0;
uint8_t bNumConfigurations;
uint8_t bReserved;
} __attribute__((packed));
/* USB Standard Configuration Descriptor - Table 9-10 */
struct usb_config_descriptor {
uint8_t bLength;
uint8_t bDescriptorType;
uint16_t wTotalLength;
uint8_t bNumInterfaces;
uint8_t bConfigurationValue;
uint8_t iConfiguration;
uint8_t bmAttributes;
uint8_t bMaxPower;
/* Descriptor ends here. The following are used internally: */
const struct usb_interface {
int num_altsetting;
const struct usb_interface_descriptor *altsetting;
} *interface;
} __attribute__((packed));
#define USB_DT_CONFIGURATION_SIZE 9
/* USB Configuration Descriptor bmAttributes bit definitions */
#define USB_CONFIG_ATTR_SELF_POWERED 0x40
#define USB_CONFIG_ATTR_REMOTE_WAKEUP 0x20
/* Other Speed Configuration is the same as Configuration Descriptor.
* - Table 9-11
*/
/* USB Standard Interface Descriptor - Table 9-12 */
struct usb_interface_descriptor {
uint8_t bLength;
uint8_t bDescriptorType;
uint8_t bInterfaceNumber;
uint8_t bAlternateSetting;
uint8_t bNumEndpoints;
uint8_t bInterfaceClass;
uint8_t bInterfaceSubClass;
uint8_t bInterfaceProtocol;
uint8_t iInterface;
/* Descriptor ends here. The following are used internally: */
const struct usb_endpoint_descriptor *endpoint;
const void *extra;
int extralen;
} __attribute__((packed));
#define USB_DT_INTERFACE_SIZE 9
/* USB Standard Endpoint Descriptor - Table 9-13 */
struct usb_endpoint_descriptor {
uint8_t bLength;
uint8_t bDescriptorType;
uint8_t bEndpointAddress;
uint8_t bmAttributes;
uint16_t wMaxPacketSize;
uint8_t bInterval;
} __attribute__((packed));
#define USB_DT_ENDPOINT_SIZE sizeof(struct usb_endpoint_descriptor)
/* USB Endpoint Descriptor bmAttributes bit definitions */
#define USB_ENDPOINT_ATTR_CONTROL 0x00
#define USB_ENDPOINT_ATTR_ISOCHRONOUS 0x01
#define USB_ENDPOINT_ATTR_BULK 0x02
#define USB_ENDPOINT_ATTR_INTERRUPT 0x03
#define USB_ENDPOINT_ATTR_NOSYNC 0x00
#define USB_ENDPOINT_ATTR_ASYNC 0x04
#define USB_ENDPOINT_ATTR_ADAPTIVE 0x08
#define USB_ENDPOINT_ATTR_SYNC 0x0C
#define USB_ENDPOINT_ATTR_DATA 0x00
#define USB_ENDPOINT_ATTR_FEEDBACK 0x10
#define USB_ENDPOINT_ATTR_IMPLICIT_FEEDBACK_DATA 0x20
/* Table 9-15 specifies String Descriptor Zero.
* Table 9-16 specified UNICODE String Descriptor.
*/
struct usb_string_descriptor {
uint8_t bLength;
uint8_t bDescriptorType;
uint16_t wData[];
} __attribute__((packed));
#endif