]> mj.ucw.cz Git - home-hw.git/blob - Src/usb.c
Basic handling of descriptors
[home-hw.git] / Src / usb.c
1 #include "stm32f1xx.h"
2 #include "stm32f1xx_hal.h"
3
4 #include "usb.h"
5
6 #include <string.h>
7
8 void _Error_Handler(char * file, int line);     // FIXME
9
10 #define DESC_U16(x) ((x) & 0xff), ((x) >> 8)
11
12 enum desc_string {
13   DESC_STR_NONE = 0,
14   DESC_STR_MANUFACTURER,
15   DESC_STR_PRODUCT,
16   DESC_STR_SERIAL,
17   DESC_STR_CONFIGURATION,
18   DESC_STR_INTERFACE,
19 };
20
21 static const byte desc_device[] = {
22   18,                           // bLength
23   USB_DESC_TYPE_DEVICE,         // bDescriptorType
24   DESC_U16(0x0200),             // bcdUSB
25   0x00,                         // bDeviceClass
26   0x00,                         // bDeviceSubClass
27   0x00,                         // bDeviceProtocol
28   USB_MAX_EP0_SIZE,             // bMaxPacketSize
29   DESC_U16(0x4242),             // idVendor
30   DESC_U16(0x0001),             // idProduct
31   DESC_U16(0x0200),             // bcdDevice
32   DESC_STR_MANUFACTURER,        // iManufacturer
33   DESC_STR_PRODUCT,             // iProduct
34   DESC_STR_SERIAL,              // iSerialNumber
35   USB_NUM_CONFIGURATIONS,       // bNumConfigurations
36 };
37
38 static const byte desc_config[] = {
39   // Configuration descriptor
40   9,                            // bLength
41   USB_DESC_TYPE_CONFIGURATION,  // bDescriptorType
42   32,                           // wTotalLength
43   0,
44   0x01,                         // bNumInterfaces
45   0x01,                         // bConfigurationValue
46   DESC_STR_CONFIGURATION,       // iConfiguration
47   0xc0,                         // bmAttributes: bus-powered, supports remote wakeup
48   0x32,                         // Max power: 100 mA
49   // Interface descriptor
50   9,                            // bLength
51   USB_DESC_TYPE_INTERFACE,      // bDescriptorType
52   0x00,                         // bInterfaceNumber
53   0x00,                         // bAlternateSetting
54   0x01,                         // bNumEndpoints
55   0xff,                         // bInterfaceClass: vendor-defined
56   0x00,                         // bInterfaceSubClass
57   0x00,                         // nInterfaceProtocol
58   DESC_STR_INTERFACE,           // iInterface
59   // End-point descriptor
60   7,                            // bLength
61   USB_DESC_TYPE_ENDPOINT,       // bDescriptorType
62   0x01,                         // bEndpointAddress
63   USB_EP_TYPE_BULK,             // bmAttributes
64   0x40, 0x00,                   // wMaxPacketSize
65   0x00,                         // bInterval: unused
66   // End-point descriptor
67   7,                            // bLength
68   USB_DESC_TYPE_ENDPOINT,       // bDescriptorType
69   0x81,                         // bEndpointAddress
70   USB_EP_TYPE_BULK,             // bmAttributes
71   0x40, 0x00,                   // wMaxPacketSize
72   0x00,                         // bInterval: unused
73 };
74
75 static const char * const desc_string[] = {
76   "",                           // DESC_STR_NONE
77   "United Computer Wizards",    // DESC_STR_MANUFACTURER
78   "Mysterious Gadget",          // DESC_STR_PRODUCT
79   "00000042",                   // DESC_STR_SERIAL
80   "Default Configuration",      // DESC_STR_CONFIGURATION
81   "Default Interface",          // DESC_STR_INTERFACE
82 };
83
84 void usb_init(struct usb *usb, PCD_HandleTypeDef *hpcd)
85 {
86   memset(usb, 0, sizeof(*usb));
87   usb->hpcd = hpcd;
88   usb->state = USB_STATE_DEFAULT;
89   usb->ep0_state = USB_EP0_IDLE;
90
91   HAL_PCDEx_PMAConfig(hpcd, 0x00, PCD_SNG_BUF, 0x18);
92   HAL_PCDEx_PMAConfig(hpcd, 0x80, PCD_SNG_BUF, 0x58);
93
94   HAL_PCD_Start(hpcd);
95 }
96
97 static inline uint get_u16(byte *p)
98 {
99   return (p[1] << 8) | p[0];
100 }
101
102 static inline void put_u16(byte *p, u16 x)
103 {
104   p[0] = x;
105   p[1] = x >> 8;
106 }
107
108 #if 0  // FIXME
109 static struct usb_endpoint *ep_by_addr(struct usb *usb, byte ep_addr)
110 {
111   return ((ep_addr & 0x80) ? usb->ep_in : usb->ep_out) + (ep_addr & 0x7f);
112 }
113 #endif
114
115 static void usb_ctl_send_status(struct usb *usb)
116 {
117   usb->ep0_state = USB_EP0_STATUS_IN;
118   usb_ep_transmit(usb, 0x00, NULL, 0);
119 }
120
121 #if 0  // FIXME
122 static void usb_ctl_recv_status(struct usb *usb)
123 {
124   usb->ep0_state = USB_EP0_STATUS_OUT;
125   usb_ep_receive(usb, 0x00, NULL, 0);
126 }
127 #endif
128
129 static void usb_ctl_send_data(struct usb *usb, const byte *data, uint len)
130 {
131   usb->ep0_state = USB_EP0_DATA_IN;
132   usb->ep0_total_length = len;
133   usb->ep0_remaining_length = len;
134   usb_ep_transmit(usb, 0x00, data, len);
135 }
136
137 #if 0  // FIXME
138 static void usb_ctl_recv_data(struct usb *usb, byte *data, uint len)
139 {
140   usb->ep0_state = USB_EP0_DATA_OUT;
141   usb->ep0_total_length = len;
142   usb->ep0_remaining_length = len;
143   usb_ep_transmit(usb, 0x00, data, len);
144 }
145 #endif
146
147 static void usb_ctl_send_byte(struct usb *usb, byte data)
148 {
149   usb->ep0_buf[0] = data;
150   usb_ctl_send_data(usb, usb->ep0_buf, 1);
151 }
152
153 static void usb_ctl_send_u16(struct usb *usb, u16 data)
154 {
155   put_u16(usb->ep0_buf, data);
156   usb_ctl_send_data(usb, usb->ep0_buf, 2);
157 }
158
159 static void usb_ctl_error(struct usb *usb)
160 {
161   usb_ep_stall(usb, 0x00);
162   usb_ep_stall(usb, 0x80);
163 }
164
165 struct setup_request {
166   byte bmRequest;
167   byte bRequest;
168   u16 wValue;
169   u16 wIndex;
170   u16 wLength;
171 };
172
173 static void usb_ctl_setup_error(struct usb *usb, struct setup_request *setup)
174 {
175   usb_ep_stall(usb, setup->bmRequest & USB_REQ_DIRECTION);
176 }
177
178 static void dev_get_status(struct usb *usb, struct setup_request *setup)
179 {
180   if ((usb->state != USB_STATE_ADDRESSED && usb->state != USB_STATE_CONFIGURED) ||
181       setup->wValue || setup->wIndex || setup->wLength != 2)
182     return usb_ctl_error(usb);
183
184   uint stat = 0;
185 #ifdef USB_SELF_POWERED
186   stat |= USB_DEV_STATUS_SELF_POWERED;
187 #endif
188   if (usb->remote_wakeup)
189     stat |= USB_DEV_STATUS_REMOTE_WAKEUP;
190   usb_ctl_send_u16(usb, stat);
191 }
192
193 static void dev_clear_feature(struct usb *usb, struct setup_request *setup)
194 {
195   if (setup->wIndex || setup->wLength)
196     return usb_ctl_error(usb);
197
198   if (setup->wValue == USB_FEATURE_REMOTE_WAKEUP)
199     {
200       usb->remote_wakeup = 0;
201       usb_ctl_send_status(usb);
202     }
203   else
204     usb_ctl_error(usb);
205 }
206
207 static void dev_set_feature(struct usb *usb, struct setup_request *setup)
208 {
209   if (setup->wIndex || setup->wLength)
210     return usb_ctl_error(usb);
211
212   if (setup->wValue == USB_FEATURE_REMOTE_WAKEUP)
213     {
214       usb->remote_wakeup = 1;
215       usb_ctl_send_status(usb);
216     }
217   else
218     usb_ctl_error(usb);
219 }
220
221 static void dev_set_address(struct usb *usb, struct setup_request *setup)
222 {
223   if (setup->wIndex || setup->wLength)
224     return usb_ctl_error(usb);
225
226   uint addr = setup->wValue & 0x7f;
227   if (usb->state == USB_STATE_CONFIGURED)
228     usb_ctl_error(usb);
229   else
230     {
231       usb->address = addr;
232       HAL_PCD_SetAddress(usb->hpcd, addr);
233       usb_ctl_send_status(usb);
234       usb->state = addr ? USB_STATE_ADDRESSED : USB_STATE_DEFAULT;
235     }
236 }
237
238 static void dev_desc_send(struct usb *usb, struct setup_request *setup, const byte *desc, uint len)
239 {
240   len = MIN(len, setup->wLength);
241   if (len)
242     usb_ctl_send_data(usb, desc, len);
243 }
244
245 static void dev_desc_send_string(struct usb *usb, struct setup_request *setup, const char *str)
246 {
247   byte *buf = usb->ep0_buf;
248   uint len = strlen(str);
249   uint i = 0;
250
251   buf[i++] = 2*len + 2;
252   buf[i++] = USB_DESC_TYPE_STRING;
253
254   while (i <= USB_EP0_BUF_SIZE - 2 && *str)
255     {
256       buf[i++] = *str++;
257       buf[i++] = 0;
258     }
259
260   dev_desc_send(usb, setup, buf, i);
261 }
262
263 static void dev_get_descriptor(struct usb *usb, struct setup_request *setup)
264 {
265   byte desc_type = setup->wValue >> 8;
266   byte desc_index = setup->wValue & 0xff;
267
268   switch (desc_type)
269     {
270     case USB_DESC_TYPE_DEVICE:
271       return dev_desc_send(usb, setup, desc_device, sizeof(desc_device));
272     case USB_DESC_TYPE_CONFIGURATION:
273       return dev_desc_send(usb, setup, desc_config, sizeof(desc_config));
274     case USB_DESC_TYPE_STRING:
275       if (desc_index < sizeof(desc_string) / sizeof(desc_string[0]))
276         return dev_desc_send_string(usb, setup, desc_string[desc_index]);
277       break;
278     case USB_DESC_TYPE_DEVICE_QUALIFIER:
279       // FIXME
280     case USB_DESC_TYPE_OTHER_SPEED_CONFIGURATION:
281       // FIXME
282       // if (usb->hpcd->Init.speed == PCD_SPEED_HIGH)
283       ;
284     }
285
286   usb_ctl_error(usb);
287 }
288
289 static void dev_get_configuration(struct usb *usb, struct setup_request *setup)
290 {
291   if (setup->wValue || setup->wIndex || setup->wLength != 1)
292     return usb_ctl_error(usb);
293
294   switch (usb->state)
295     {
296     case USB_STATE_ADDRESSED:
297       usb_ctl_send_byte(usb, 0);
298       break;
299     case USB_STATE_CONFIGURED:
300       usb_ctl_send_byte(usb, usb->config);
301       break;
302     default:
303       usb_ctl_error(usb);
304     }
305 }
306
307 static void dev_set_configuration(struct usb *usb, struct setup_request *setup)
308 {
309   byte cfg = setup->wValue & 0xff;
310
311   // FIXME: Support more configurations
312   if (cfg > 1 || setup->wIndex || setup->wLength)
313     return usb_ctl_error(usb);
314
315   switch (usb->state)
316     {
317     case USB_STATE_ADDRESSED:
318       if (cfg)
319         {
320           usb->config = cfg;
321           usb->state = USB_STATE_CONFIGURED;
322           // FIXME: Notify that the device was configured
323         }
324       usb_ctl_send_status(usb);
325       break;
326     case USB_STATE_CONFIGURED:
327       if (!cfg)
328         {
329           // Unconfiguring
330           usb->config = 0;
331           usb->state = USB_STATE_ADDRESSED;
332           // FIXME: Notify that the device was unconfigured
333         }
334       else if (cfg != usb->config)
335         {
336           usb->config = cfg;
337           // FIXME: Notify about configuration change
338         }
339       usb_ctl_send_status(usb);
340       break;
341     default:
342       usb_ctl_error(usb);
343     }
344 }
345
346 static void dev_setup(struct usb *usb, struct setup_request *setup)
347 {
348   switch (setup->bRequest)
349     {
350     case USB_REQ_GET_STATUS:
351       return dev_get_status(usb, setup);
352     case USB_REQ_CLEAR_FEATURE:
353       return dev_clear_feature(usb, setup);
354     case USB_REQ_SET_FEATURE:
355       return dev_set_feature(usb, setup);
356     case USB_REQ_SET_ADDRESS:
357       return dev_set_address(usb, setup);
358     case USB_REQ_GET_DESCRIPTOR:
359       return dev_get_descriptor(usb, setup);
360     case USB_REQ_GET_CONFIGURATION:
361       return dev_get_configuration(usb, setup);
362     case USB_REQ_SET_CONFIGURATION:
363       return dev_set_configuration(usb, setup);
364     }
365
366   usb_ctl_setup_error(usb, setup);
367 }
368
369 static void intf_setup(struct usb *usb, struct setup_request *setup)
370 {
371   byte intf = setup->wIndex & 0xff;
372
373   if (!intf)
374     {
375       // FIXME: Support more interfaces
376       usb_ctl_error(usb);
377       return;
378     }
379
380   switch (setup->bRequest)
381     {
382     case USB_REQ_GET_STATUS:
383       if (setup->wValue || setup->wLength != 2 || usb->state != USB_STATE_CONFIGURED)
384         usb_ctl_error(usb);
385       else
386         usb_ctl_send_u16(usb, 0);
387       return;
388
389     case USB_REQ_CLEAR_FEATURE:
390     case USB_REQ_SET_FEATURE:
391       // Interfaces have no standard features
392       return usb_ctl_error(usb);
393     }
394
395   usb_ctl_setup_error(usb, setup);
396 }
397
398 static void ep_setup(struct usb *usb, struct setup_request *setup)
399 {
400   byte ep_addr = setup->wIndex & 0x8f;
401
402   switch (setup->bRequest)
403     {
404     case USB_REQ_GET_STATUS:
405       if (setup->wValue || setup->wLength != 2)
406         return usb_ctl_error(usb);
407       switch (usb->state)
408         {
409         case USB_STATE_ADDRESSED:
410           if (ep_addr & 0x7f)
411             usb_ctl_error(usb);
412           return;
413         case USB_STATE_CONFIGURED:
414           {
415             if (usb_ep_is_stalled(usb, ep_addr))
416               usb_ctl_send_u16(usb, 1);
417             else
418               usb_ctl_send_u16(usb, 0);
419             return;
420           }
421         default:
422           return usb_ctl_error(usb);
423         }
424       break;
425
426     case USB_REQ_SET_FEATURE:
427       if (setup->wLength)
428         return usb_ctl_error(usb);
429       switch (usb->state)
430         {
431         case USB_STATE_ADDRESSED:
432           if (ep_addr & 0x7f)
433             usb_ctl_error(usb);
434           return;
435         case USB_STATE_CONFIGURED:
436           if (setup->wValue == USB_FEATURE_EP_HALT)
437             {
438               if (ep_addr & 0x7f)
439                 usb_ep_stall(usb, ep_addr);
440             }
441           usb_ctl_send_status(usb);
442           return;
443         default:
444           usb_ctl_error(usb);
445         }
446       break;
447
448     case USB_REQ_CLEAR_FEATURE:
449       if (setup->wLength)
450         return usb_ctl_error(usb);
451       switch (usb->state)
452         {
453         case USB_STATE_ADDRESSED:
454           if (ep_addr & 0x7f)
455             usb_ctl_error(usb);
456           return;
457         case USB_STATE_CONFIGURED:
458           if (setup->wValue == USB_FEATURE_EP_HALT)
459             {
460               if (ep_addr & 0x7f)
461                 usb_ep_unstall(usb, ep_addr);
462             }
463           usb_ctl_send_status(usb);
464           return;
465         default:
466           usb_ctl_error(usb);
467         }
468       break;
469     }
470
471   usb_ctl_setup_error(usb, setup);
472 }
473
474 static void usb_handle_setup(struct usb *usb, struct setup_request *setup)
475 {
476   usb->ep0_state = USB_EP0_SETUP;
477   usb->ep0_setup_data_length = setup->wLength;
478
479   if ((setup->bmRequest & USB_REQ_TYPE_MASK) != USB_REQ_TYPE_STANDARD)
480     {
481       // FIXME: Class-specific and vendor-specific setup packets not supported
482       // FIXME: Check USB_STATE_CONFIGURED here
483       usb_ctl_setup_error(usb, setup);
484     }
485
486   switch (setup->bmRequest & USB_REQ_RECIPIENT_MASK)
487     {
488     case USB_REQ_RECIPIENT_DEVICE:
489       return dev_setup(usb, setup);
490     case USB_REQ_RECIPIENT_INTERFACE:
491       return intf_setup(usb, setup);
492     case USB_REQ_RECIPIENT_ENDPOINT:
493       return ep_setup(usb, setup);
494     }
495
496   usb_ctl_setup_error(usb, setup);
497 }
498
499 void HAL_PCD_SetupStageCallback(PCD_HandleTypeDef *hpcd)
500 {
501   struct usb *usb = hpcd->pData;
502   byte *req = (byte *) hpcd->Setup;
503
504   struct setup_request setup = {
505     .bmRequest = req[0],
506     .bRequest = req[1],
507     .wValue = get_u16(req+2),
508     .wIndex = get_u16(req+4),
509     .wLength = get_u16(req+2),
510   };
511   usb_handle_setup(usb, &setup);
512 }
513
514 void HAL_PCD_DataOutStageCallback(PCD_HandleTypeDef *hpcd, uint8_t epnum)
515 {
516   struct usb *usb = hpcd->pData;
517   PCD_EPTypeDef *ep = &hpcd->IN_ep[epnum];
518
519   if (!epnum)
520     {
521       // HAL/LL handle EP0 transfers in a completely different way, we have to do many things ourselves
522       if (usb->ep0_state != USB_EP0_DATA_OUT)
523         return;
524       if (usb->ep0_remaining_length > ep->maxpacket)
525         {
526           usb->ep0_remaining_length -= ep->maxpacket;
527           usb_ep_receive(usb, 0x00, ep->xfer_buff, MIN(usb->ep0_remaining_length, ep->maxpacket));
528         }
529       else
530         {
531           if (usb->state == USB_STATE_CONFIGURED)
532             {
533               // FIXME: Handle incoming control packet
534             }
535           usb_ctl_send_status(usb);
536         }
537     }
538   else
539     {
540       if (usb->state == USB_STATE_CONFIGURED)
541         {
542           // FIXME: Custom data callback
543         }
544     }
545 }
546
547 void HAL_PCD_DataInStageCallback(PCD_HandleTypeDef *hpcd, uint8_t epnum)
548 {
549   struct usb *usb = hpcd->pData;
550   PCD_EPTypeDef *ep = &hpcd->IN_ep[epnum];
551
552   if (!epnum)
553     {
554       // HAL/LL handle EP0 transfers in a completely different way, we have to do many things ourselves
555       if (usb->ep0_state != USB_EP0_DATA_IN)
556         return;
557       if (usb->ep0_remaining_length > ep->maxpacket)
558         {
559           usb->ep0_remaining_length -= ep->maxpacket;
560           usb_ep_transmit(usb, 0x00, ep->xfer_buff, usb->ep0_remaining_length);
561           usb_ep_receive(usb, 0x00, NULL, 0);
562         }
563       else if (usb->ep0_total_length && usb->ep0_total_length % ep->maxpacket == 0 && usb->ep0_total_length < usb->ep0_setup_data_length)
564         {
565           /*
566            *  Each data transfer must be terminated by either a small packet (less than maxpacket)
567            *  or by reaching the answer size requested in the setup packet. Send an empty final packet
568            *  if needed.
569            */
570           usb_ep_transmit(usb, 0x00, NULL, 0);
571           usb->ep0_setup_data_length = 0;
572           usb_ep_receive(usb, 0x00, NULL, 0);
573         }
574       else
575         {
576           if (usb->state == USB_STATE_CONFIGURED)
577             {
578               // FIXME: Custom data callback
579               // All data have been sent
580             }
581         }
582     }
583   else
584     {
585       if (usb->state == USB_STATE_CONFIGURED)
586         {
587           // FIXME: Custom data callback
588           // This gets called when a complete message is sent
589         }
590     }
591 }
592
593 void HAL_PCD_SOFCallback(PCD_HandleTypeDef *hpcd)
594 {
595   // We are not interested in Start of frame packets
596   // (neither we set hpcd->Init.Sof_enable, so this callback does not get called)
597 }
598
599 void HAL_PCD_ResetCallback(PCD_HandleTypeDef *hpcd)
600
601   struct usb *usb = hpcd->pData;
602
603   usb->state = USB_STATE_DEFAULT;
604
605   usb_ep_open(usb, 0x00, USB_EP_TYPE_CTRL, USB_MAX_EP0_SIZE);
606   usb_ep_open(usb, 0x80, USB_EP_TYPE_CTRL, USB_MAX_EP0_SIZE);
607 }
608
609 void HAL_PCD_SuspendCallback(PCD_HandleTypeDef *hpcd)
610 {
611   struct usb *usb = hpcd->pData;
612
613   usb->pre_suspend_state = usb->state;
614   usb->state = USB_STATE_SUSPENDED;
615
616   if (hpcd->Init.low_power_enable)
617     SCB->SCR |= (uint32_t)((uint32_t)(SCB_SCR_SLEEPDEEP_Msk | SCB_SCR_SLEEPONEXIT_Msk));
618 }
619
620 void HAL_PCD_ResumeCallback(PCD_HandleTypeDef *hpcd)
621 {
622   struct usb *usb = hpcd->pData;
623   usb->state = usb->pre_suspend_state;
624 }
625
626 void HAL_PCD_ISOOUTIncompleteCallback(PCD_HandleTypeDef *hpcd, uint8_t epnum)
627 {
628   // We do not support isochronous mode
629 }
630
631 void HAL_PCD_ISOINIncompleteCallback(PCD_HandleTypeDef *hpcd, uint8_t epnum)
632 {
633   // We do not support isochronous mode
634 }
635
636 void HAL_PCD_ConnectCallback(PCD_HandleTypeDef *hpcd)
637 {
638 }
639
640 void HAL_PCD_DisconnectCallback(PCD_HandleTypeDef *hpcd)
641 {
642   struct usb *usb = hpcd->pData;
643   usb->state = USB_STATE_DEFAULT;
644 }