19 #define USB_FIFO_SIZE 64 20 static uint8_t txbuffer[USB_FIFO_SIZE];
23 static const uint8_t mask = USB_FIFO_SIZE-1;
26 static uint8_t usbd_control_buffer[128];
29 static usbd_device *usbd_dev;
32 static void (*data_handler)(uint8_t byte);
34 static void cdcacm_data_rx_cb(usbd_device *usbd_dev_dum, uint8_t ep);
36 static const struct usb_device_descriptor dev = {
37 .bLength = USB_DT_DEVICE_SIZE,
38 .bDescriptorType = USB_DT_DEVICE,
41 .bDeviceSubClass = 0x0,
42 .bDeviceProtocol = 0x0,
43 .bMaxPacketSize0 = 64,
50 .bNumConfigurations = 1,
53 static const struct usb_endpoint_descriptor comm_endp[] = {{
54 .bLength = USB_DT_ENDPOINT_SIZE,
55 .bDescriptorType = USB_DT_ENDPOINT,
56 .bEndpointAddress = 0x83,
57 .bmAttributes = USB_ENDPOINT_ATTR_INTERRUPT,
62 static const struct usb_endpoint_descriptor data_endp[] = {{
63 .bLength = USB_DT_ENDPOINT_SIZE,
64 .bDescriptorType = USB_DT_ENDPOINT,
65 .bEndpointAddress = 0x01,
66 .bmAttributes = USB_ENDPOINT_ATTR_BULK,
70 .bLength = USB_DT_ENDPOINT_SIZE,
71 .bDescriptorType = USB_DT_ENDPOINT,
72 .bEndpointAddress = 0x82,
73 .bmAttributes = USB_ENDPOINT_ATTR_BULK,
79 struct usb_cdc_header_descriptor header;
80 struct usb_cdc_call_management_descriptor call_mgmt;
81 struct usb_cdc_acm_descriptor acm;
82 struct usb_cdc_union_descriptor cdc_union;
83 } __attribute__((packed)) cdcacm_functional_descriptors = {
85 .bFunctionLength =
sizeof(
struct usb_cdc_header_descriptor),
86 .bDescriptorType = CS_INTERFACE,
87 .bDescriptorSubtype = USB_CDC_TYPE_HEADER,
92 sizeof(
struct usb_cdc_call_management_descriptor),
93 .bDescriptorType = CS_INTERFACE,
94 .bDescriptorSubtype = USB_CDC_TYPE_CALL_MANAGEMENT,
99 .bFunctionLength =
sizeof(
struct usb_cdc_acm_descriptor),
100 .bDescriptorType = CS_INTERFACE,
101 .bDescriptorSubtype = USB_CDC_TYPE_ACM,
105 .bFunctionLength =
sizeof(
struct usb_cdc_union_descriptor),
106 .bDescriptorType = CS_INTERFACE,
107 .bDescriptorSubtype = USB_CDC_TYPE_UNION,
108 .bControlInterface = 0,
109 .bSubordinateInterface0 = 1,
113 static const struct usb_interface_descriptor comm_iface[] = {{
114 .bLength = USB_DT_INTERFACE_SIZE,
115 .bDescriptorType = USB_DT_INTERFACE,
116 .bInterfaceNumber = 0,
117 .bAlternateSetting = 0,
119 .bInterfaceClass = USB_CLASS_CDC,
120 .bInterfaceSubClass = USB_CDC_SUBCLASS_ACM,
121 .bInterfaceProtocol = USB_CDC_PROTOCOL_AT,
124 .endpoint = comm_endp,
126 .extra = &cdcacm_functional_descriptors,
127 .extralen =
sizeof(cdcacm_functional_descriptors),
130 static const struct usb_interface_descriptor data_iface[] = {{
131 .bLength = USB_DT_INTERFACE_SIZE,
132 .bDescriptorType = USB_DT_INTERFACE,
133 .bInterfaceNumber = 1,
134 .bAlternateSetting = 0,
136 .bInterfaceClass = USB_CLASS_DATA,
137 .bInterfaceSubClass = 0,
138 .bInterfaceProtocol = 0,
141 .endpoint = data_endp,
144 static const struct usb_interface ifaces[] = {{
146 .altsetting = comm_iface,
149 .altsetting = data_iface,
152 static const struct usb_config_descriptor config = {
153 .bLength = USB_DT_CONFIGURATION_SIZE,
154 .bDescriptorType = USB_DT_CONFIGURATION,
157 .bConfigurationValue = 1,
159 .bmAttributes = 0x80,
165 static const char *usb_strings[] = {
170 static int cdcacm_control_request(usbd_device *usbd_dev_dum,
171 struct usb_setup_data *req, uint8_t **buf,
172 uint16_t *len,
void (**complete)(usbd_device *usbd_dev,
173 struct usb_setup_data *req)){
179 switch (req->bRequest) {
180 case USB_CDC_REQ_SET_CONTROL_LINE_STATE: {
183 struct usb_cdc_notification *notif = (
void *)local_buf;
186 notif->bmRequestType = 0xA1;
187 notif->bNotification = USB_CDC_NOTIFY_SERIAL_STATE;
191 local_buf[8] = req->wValue & 3;
197 case USB_CDC_REQ_SET_LINE_CODING:
198 if (*len <
sizeof(
struct usb_cdc_line_coding))
206 static void cdcacm_set_config(usbd_device *usbd_dev_dum, uint16_t wValue)
211 usbd_ep_setup(usbd_dev, 0x01, USB_ENDPOINT_ATTR_BULK, 64, cdcacm_data_rx_cb);
212 usbd_ep_setup(usbd_dev, 0x82, USB_ENDPOINT_ATTR_BULK, 64, NULL);
213 usbd_ep_setup(usbd_dev, 0x83, USB_ENDPOINT_ATTR_INTERRUPT, 16, NULL);
215 usbd_register_control_callback(
217 USB_REQ_TYPE_CLASS | USB_REQ_TYPE_INTERFACE,
218 USB_REQ_TYPE_TYPE | USB_REQ_TYPE_RECIPIENT,
219 (usbd_control_callback)cdcacm_control_request);
223 static void cdcacm_data_rx_cb(usbd_device *usbd_dev_dum, uint8_t ep)
229 static uint8_t flashPos = 0;
230 static volatile uint8_t last;
233 length = usbd_ep_read_packet(usbd_dev, 0x01, buffer, 64);
235 for(uint8_t i = 0; i < length; i++){
241 if((buffer[i] ==
'\0') && (last ==
'\0')){
247 rcc_periph_clock_enable(RCC_BKP);
248 rcc_periph_clock_enable(RCC_PWR);
249 pwr_disable_backup_domain_write_protect();
251 pwr_enable_backup_domain_write_protect();
263 if(data_handler != NULL){
265 data_handler(buffer[i]);
274 *((uint32_t*)( 0x40005C40)) |= 0x03;
283 for(
volatile int i = 0; i < 120000;i++);
291 usbd_dev = usbd_init(&st_usbfs_v1_usb_driver,
297 sizeof(usbd_control_buffer));
298 usbd_register_set_config_callback(usbd_dev, cdcacm_set_config);
302 for(
volatile int i = 0; i < 50000; i++){
312 data_handler = data_available;
320 uint8_t toSend[USB_FIFO_SIZE];
325 toSend[pos++] = txbuffer[tail];
327 tail = (tail & mask);
333 usbd_ep_write_packet(usbd_dev, 0x82, toSend, pos);
342 txbuffer[head] = byte;
344 head = (head & mask);
Setup the port for digital output.
void pinLow(gpio_port port, gpio_pin pin)
Set a given gpio pin on a port to logic low.
void USB_put(uint8_t byte)
Send a single byte on USB.
void USB_setGet(void(*data_available)(uint8_t))
Set the function called when data is received on the USB.
void USB_disconnect(void)
Dissconnect the USB device from the HOST.
void POWER_reset(void)
Resets the system.
void USB_setup(void)
Initialize the USB device.
mcu_error pinSetup(gpio_mode mode, gpio_port port, gpio_pin pin)
Setup a GPIO pin for a given function.
void USB_update(void)
Update the USB peripheral.
Header file for stm32f103cb USB.