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