]> mj.ucw.cz Git - home-hw.git/blob - Src/usb.c
Whoa! Interrupt-driven I2C is working!
[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 usb_init(struct usb *usb, PCD_HandleTypeDef *hpcd)
10 {
11   memset(usb, 0, sizeof(*usb));
12   usb->hpcd = hpcd;
13   usb->state = USB_STATE_DEFAULT;
14   usb->ep0_state = USB_EP0_IDLE;
15   hpcd->pData = usb;
16 }
17
18 void usb_start(struct usb *usb)
19 {
20   HAL_PCDEx_PMAConfig(usb->hpcd, 0x00, PCD_SNG_BUF, 0x18);
21   HAL_PCDEx_PMAConfig(usb->hpcd, 0x80, PCD_SNG_BUF, 0x58);
22
23   HAL_PCD_Start(usb->hpcd);
24 }
25
26 void usb_ctl_send_status(struct usb *usb)
27 {
28   usb_debug("Control send: status\n");
29   usb->ep0_state = USB_EP0_STATUS_IN;
30   usb_ep_send(usb, 0x00, NULL, 0);
31 }
32
33 void usb_ctl_recv_status(struct usb *usb)
34 {
35   usb->ep0_state = USB_EP0_STATUS_OUT;
36   usb_ep_receive(usb, 0x00, NULL, 0);
37 }
38
39 void usb_ctl_send_data(struct usb *usb, const byte *data, uint len)
40 {
41   usb_debug("Control send: %u bytes\n", len);
42   usb->ep0_state = USB_EP0_DATA_IN;
43   usb->ep0_total_length = len;
44   usb->ep0_remaining_length = len;
45   usb_ep_send(usb, 0x00, data, len);
46 }
47
48 void usb_ctl_recv_data(struct usb *usb, byte *data, uint len)
49 {
50   usb_debug("Control recv: %u bytes\n", len);
51   usb->ep0_state = USB_EP0_DATA_OUT;
52   usb->ep0_total_length = len;
53   usb->ep0_remaining_length = len;
54   usb_ep_send(usb, 0x00, data, len);
55 }
56
57 static void usb_ctl_send_byte(struct usb *usb, byte data)
58 {
59   usb->ep0_buf[0] = data;
60   usb_ctl_send_data(usb, usb->ep0_buf, 1);
61 }
62
63 static void usb_ctl_send_u16(struct usb *usb, u16 data)
64 {
65   put_u16_le(usb->ep0_buf, data);
66   usb_ctl_send_data(usb, usb->ep0_buf, 2);
67 }
68
69 void usb_ctl_error(struct usb *usb)
70 {
71   usb_debug("Control packet error\n");
72   usb_ep_stall(usb, 0x00);
73   usb_ep_stall(usb, 0x80);
74 }
75
76 void usb_ctl_setup_error(struct usb *usb, struct setup_request *setup)
77 {
78   usb_debug("Setup packet error\n");
79   usb_ep_stall(usb, setup->bmRequest & USB_REQ_DIRECTION);
80 }
81
82 static void dev_get_status(struct usb *usb, struct setup_request *setup)
83 {
84   if ((usb->state != USB_STATE_ADDRESSED && usb->state != USB_STATE_CONFIGURED) ||
85       setup->wValue || setup->wIndex || setup->wLength != 2)
86     return usb_ctl_error(usb);
87
88   uint stat = 0;
89 #ifdef USB_SELF_POWERED
90   stat |= USB_DEV_STATUS_SELF_POWERED;
91 #endif
92   if (usb->remote_wakeup)
93     stat |= USB_DEV_STATUS_REMOTE_WAKEUP;
94   usb_ctl_send_u16(usb, stat);
95 }
96
97 static void dev_clear_feature(struct usb *usb, struct setup_request *setup)
98 {
99   if (setup->wIndex || setup->wLength)
100     return usb_ctl_error(usb);
101
102   if (setup->wValue == USB_FEATURE_REMOTE_WAKEUP)
103     {
104       usb->remote_wakeup = 0;
105       usb_ctl_send_status(usb);
106     }
107   else
108     usb_ctl_error(usb);
109 }
110
111 static void dev_set_feature(struct usb *usb, struct setup_request *setup)
112 {
113   if (setup->wIndex || setup->wLength)
114     return usb_ctl_error(usb);
115
116   if (setup->wValue == USB_FEATURE_REMOTE_WAKEUP)
117     {
118       usb->remote_wakeup = 1;
119       usb_ctl_send_status(usb);
120     }
121   else
122     usb_ctl_error(usb);
123 }
124
125 static void dev_set_address(struct usb *usb, struct setup_request *setup)
126 {
127   if (setup->wIndex || setup->wLength)
128     return usb_ctl_error(usb);
129
130   uint addr = setup->wValue & 0x7f;
131   if (usb->state == USB_STATE_CONFIGURED)
132     usb_ctl_error(usb);
133   else
134     {
135       usb->address = addr;
136       HAL_PCD_SetAddress(usb->hpcd, addr);
137       usb_ctl_send_status(usb);
138       usb->state = addr ? USB_STATE_ADDRESSED : USB_STATE_DEFAULT;
139     }
140 }
141
142 static void dev_desc_send(struct usb *usb, struct setup_request *setup, const byte *desc, uint len)
143 {
144   len = MIN(len, setup->wLength);
145   if (len)
146     usb_ctl_send_data(usb, desc, len);
147 }
148
149 static void dev_desc_send_string(struct usb *usb, struct setup_request *setup, const char *str)
150 {
151   byte *buf = usb->ep0_buf;
152   uint len = strlen(str);
153   uint i = 0;
154
155   buf[i++] = 2*len + 2;
156   buf[i++] = USB_DESC_TYPE_STRING;
157
158   while (i <= USB_EP0_BUF_SIZE - 2 && *str)
159     {
160       buf[i++] = *str++;
161       buf[i++] = 0;
162     }
163
164   dev_desc_send(usb, setup, buf, i);
165 }
166
167 static void dev_get_descriptor(struct usb *usb, struct setup_request *setup)
168 {
169   byte desc_type = setup->wValue >> 8;
170   byte desc_index = setup->wValue & 0xff;
171
172   switch (desc_type)
173     {
174     case USB_DESC_TYPE_DEVICE:
175       return dev_desc_send(usb, setup, usb->desc_device, usb->desc_device_len);
176     case USB_DESC_TYPE_CONFIGURATION:
177       return dev_desc_send(usb, setup, usb->desc_config, usb->desc_config_len);
178     case USB_DESC_TYPE_STRING:
179       if (!desc_index)
180         return dev_desc_send(usb, setup, usb->desc_languages, usb->desc_languages_len);
181       if (desc_index < usb->desc_string_items)
182         return dev_desc_send_string(usb, setup, usb->desc_string[desc_index]);
183       break;
184     case USB_DESC_TYPE_DEVICE_QUALIFIER:
185     case USB_DESC_TYPE_OTHER_SPEED_CONFIGURATION:
186       // We do not support high-speed USB
187       break;
188     }
189
190   usb_ctl_error(usb);
191 }
192
193 static void dev_get_configuration(struct usb *usb, struct setup_request *setup)
194 {
195   if (setup->wValue || setup->wIndex || setup->wLength != 1)
196     return usb_ctl_error(usb);
197
198   switch (usb->state)
199     {
200     case USB_STATE_ADDRESSED:
201       usb_ctl_send_byte(usb, 0);
202       break;
203     case USB_STATE_CONFIGURED:
204       usb_ctl_send_byte(usb, usb->config);
205       break;
206     default:
207       usb_ctl_error(usb);
208     }
209 }
210
211 static void dev_set_configuration(struct usb *usb, struct setup_request *setup)
212 {
213   byte cfg = setup->wValue & 0xff;
214
215   // FIXME: Support more configurations
216   if (cfg > 1 || setup->wIndex || setup->wLength)
217     return usb_ctl_error(usb);
218
219   switch (usb->state)
220     {
221     case USB_STATE_ADDRESSED:
222       if (cfg)
223         {
224           usb->config = cfg;
225           usb->state = USB_STATE_CONFIGURED;
226           usb_dev_configure(usb);
227         }
228       usb_ctl_send_status(usb);
229       break;
230     case USB_STATE_CONFIGURED:
231       if (!cfg)
232         {
233           // Unconfiguring
234           usb_dev_unconfigure(usb);
235           usb->config = 0;
236           usb->state = USB_STATE_ADDRESSED;
237         }
238       else if (cfg != usb->config)
239         {
240           usb_dev_unconfigure(usb);
241           usb->config = cfg;
242           usb_dev_configure(usb);
243         }
244       usb_ctl_send_status(usb);
245       break;
246     default:
247       usb_ctl_error(usb);
248     }
249 }
250
251 static void dev_setup(struct usb *usb, struct setup_request *setup)
252 {
253   switch (setup->bRequest)
254     {
255     case USB_REQ_GET_STATUS:
256       return dev_get_status(usb, setup);
257     case USB_REQ_CLEAR_FEATURE:
258       return dev_clear_feature(usb, setup);
259     case USB_REQ_SET_FEATURE:
260       return dev_set_feature(usb, setup);
261     case USB_REQ_SET_ADDRESS:
262       return dev_set_address(usb, setup);
263     case USB_REQ_GET_DESCRIPTOR:
264       return dev_get_descriptor(usb, setup);
265     case USB_REQ_GET_CONFIGURATION:
266       return dev_get_configuration(usb, setup);
267     case USB_REQ_SET_CONFIGURATION:
268       return dev_set_configuration(usb, setup);
269     }
270
271   usb_ctl_setup_error(usb, setup);
272 }
273
274 static void intf_setup(struct usb *usb, struct setup_request *setup)
275 {
276   byte intf = setup->wIndex & 0xff;
277
278   if (!intf)
279     {
280       // FIXME: Currently, we do not support more than 1 interface per configuration
281       usb_ctl_error(usb);
282       return;
283     }
284
285   switch (setup->bRequest)
286     {
287     case USB_REQ_GET_STATUS:
288       if (setup->wValue || setup->wLength != 2 || usb->state != USB_STATE_CONFIGURED)
289         usb_ctl_error(usb);
290       else
291         usb_ctl_send_u16(usb, 0);
292       return;
293
294     case USB_REQ_CLEAR_FEATURE:
295     case USB_REQ_SET_FEATURE:
296       // Interfaces have no standard features
297       return usb_ctl_error(usb);
298     }
299
300   usb_ctl_setup_error(usb, setup);
301 }
302
303 static void ep_setup(struct usb *usb, struct setup_request *setup)
304 {
305   byte ep_addr = setup->wIndex & 0x8f;
306
307   switch (setup->bRequest)
308     {
309     case USB_REQ_GET_STATUS:
310       if (setup->wValue || setup->wLength != 2)
311         return usb_ctl_error(usb);
312       switch (usb->state)
313         {
314         case USB_STATE_ADDRESSED:
315           if (ep_addr & 0x7f)
316             usb_ctl_error(usb);
317           return;
318         case USB_STATE_CONFIGURED:
319           {
320             if (usb_ep_is_stalled(usb, ep_addr))
321               usb_ctl_send_u16(usb, 1);
322             else
323               usb_ctl_send_u16(usb, 0);
324             return;
325           }
326         default:
327           return usb_ctl_error(usb);
328         }
329       break;
330
331     case USB_REQ_SET_FEATURE:
332       if (setup->wLength)
333         return usb_ctl_error(usb);
334       switch (usb->state)
335         {
336         case USB_STATE_ADDRESSED:
337           if (ep_addr & 0x7f)
338             usb_ctl_error(usb);
339           return;
340         case USB_STATE_CONFIGURED:
341           if (setup->wValue == USB_FEATURE_EP_HALT)
342             {
343               if (ep_addr & 0x7f)
344                 usb_ep_stall(usb, ep_addr);
345             }
346           usb_ctl_send_status(usb);
347           return;
348         default:
349           usb_ctl_error(usb);
350         }
351       break;
352
353     case USB_REQ_CLEAR_FEATURE:
354       if (setup->wLength)
355         return usb_ctl_error(usb);
356       switch (usb->state)
357         {
358         case USB_STATE_ADDRESSED:
359           if (ep_addr & 0x7f)
360             usb_ctl_error(usb);
361           return;
362         case USB_STATE_CONFIGURED:
363           if (setup->wValue == USB_FEATURE_EP_HALT)
364             {
365               if (ep_addr & 0x7f)
366                 usb_ep_unstall(usb, ep_addr);
367             }
368           usb_ctl_send_status(usb);
369           return;
370         default:
371           usb_ctl_error(usb);
372         }
373       break;
374     }
375
376   usb_ctl_setup_error(usb, setup);
377 }
378
379 static void usb_handle_setup(struct usb *usb, struct setup_request *setup)
380 {
381   usb_debug("Setup: type=%02x req=%02x val=%04x idx=%04x len=%04x\n", setup->bmRequest, setup->bRequest, setup->wValue, setup->wIndex, setup->wLength);
382   usb->ep0_state = USB_EP0_SETUP;
383   usb->ep0_setup_data_length = setup->wLength;
384
385   if (usb_dev_setup_hook(usb, setup))
386     return;
387
388   if ((setup->bmRequest & USB_REQ_TYPE_MASK) == USB_REQ_TYPE_STANDARD)
389     {
390       switch (setup->bmRequest & USB_REQ_RECIPIENT_MASK)
391         {
392         case USB_REQ_RECIPIENT_DEVICE:
393           return dev_setup(usb, setup);
394         case USB_REQ_RECIPIENT_INTERFACE:
395           return intf_setup(usb, setup);
396         case USB_REQ_RECIPIENT_ENDPOINT:
397           return ep_setup(usb, setup);
398         }
399     }
400
401   usb_ctl_setup_error(usb, setup);
402 }
403
404 void HAL_PCD_SetupStageCallback(PCD_HandleTypeDef *hpcd)
405 {
406   struct usb *usb = hpcd->pData;
407   byte *req = (byte *) hpcd->Setup;
408
409   struct setup_request setup = {
410     .bmRequest = req[0],
411     .bRequest = req[1],
412     .wValue = get_u16_le(req+2),
413     .wIndex = get_u16_le(req+4),
414     .wLength = get_u16_le(req+6),
415   };
416   usb_handle_setup(usb, &setup);
417 }
418
419 void HAL_PCD_DataOutStageCallback(PCD_HandleTypeDef *hpcd, uint8_t epnum)
420 {
421   struct usb *usb = hpcd->pData;
422   PCD_EPTypeDef *ep = &hpcd->IN_ep[epnum];
423
424   if (!epnum)
425     {
426       // HAL/LL handle EP0 transfers in a completely different way, we have to do many things ourselves
427       usb_debug("Ep0 OUT: state=%u rem=%u total=%u\n", usb->ep0_state, usb->ep0_remaining_length, usb->ep0_total_length);
428       if (usb->ep0_state != USB_EP0_DATA_OUT)
429         return;
430       if (usb->ep0_remaining_length > ep->maxpacket)
431         {
432           usb->ep0_remaining_length -= ep->maxpacket;
433           usb_ep_receive(usb, 0x00, ep->xfer_buff, MIN(usb->ep0_remaining_length, ep->maxpacket));
434         }
435       else
436         {
437           if (usb->state == USB_STATE_CONFIGURED)
438             usb_dev_ctl_recv_done(usb);
439           usb_ctl_send_status(usb);
440         }
441     }
442   else
443     {
444       if (usb->state == USB_STATE_CONFIGURED)
445         usb_dev_recv_done(usb, epnum);
446     }
447 }
448
449 void HAL_PCD_DataInStageCallback(PCD_HandleTypeDef *hpcd, uint8_t epnum)
450 {
451   struct usb *usb = hpcd->pData;
452   PCD_EPTypeDef *ep = &hpcd->IN_ep[epnum];
453
454   if (!epnum)
455     {
456       // HAL/LL handle EP0 transfers in a completely different way, we have to do many things ourselves
457       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);
458       if (usb->ep0_state != USB_EP0_DATA_IN)
459         return;
460       if (usb->ep0_remaining_length > ep->maxpacket)
461         {
462           usb->ep0_remaining_length -= ep->maxpacket;
463           usb_ep_send(usb, 0x00, ep->xfer_buff, usb->ep0_remaining_length);
464           usb_ep_receive(usb, 0x00, NULL, 0);
465         }
466       else if (usb->ep0_total_length && usb->ep0_total_length % ep->maxpacket == 0 && usb->ep0_total_length < usb->ep0_setup_data_length)
467         {
468           /*
469            *  Each data transfer must be terminated by either a small packet (less than maxpacket)
470            *  or by reaching the answer size requested in the setup packet. Send an empty final packet
471            *  if needed.
472            */
473           usb_ep_send(usb, 0x00, NULL, 0);
474           usb->ep0_setup_data_length = 0;
475           usb_ep_receive(usb, 0x00, NULL, 0);
476         }
477       else
478         {
479           if (usb->state == USB_STATE_CONFIGURED)
480             usb_dev_ctl_send_done(usb);
481           usb_ctl_recv_status(usb);
482         }
483     }
484   else
485     {
486       if (usb->state == USB_STATE_CONFIGURED)
487         usb_dev_send_done(usb, epnum);
488     }
489 }
490
491 void HAL_PCD_SOFCallback(PCD_HandleTypeDef *hpcd)
492 {
493   // We are not interested in Start of frame packets
494   // (neither we set hpcd->Init.Sof_enable, so this callback does not get called)
495 }
496
497 void HAL_PCD_ResetCallback(PCD_HandleTypeDef *hpcd)
498 {
499   struct usb *usb = hpcd->pData;
500
501   usb->state = USB_STATE_DEFAULT;
502   usb_dev_reset(usb);
503
504   usb_ep_open(usb, 0x00, USB_EP_TYPE_CTRL, USB_MAX_EP0_SIZE);
505   usb_ep_open(usb, 0x80, USB_EP_TYPE_CTRL, USB_MAX_EP0_SIZE);
506 }
507
508 void HAL_PCD_SuspendCallback(PCD_HandleTypeDef *hpcd)
509 {
510   struct usb *usb = hpcd->pData;
511
512   usb->pre_suspend_state = usb->state;
513   usb->state = USB_STATE_SUSPENDED;
514
515   if (hpcd->Init.low_power_enable)
516     SCB->SCR |= (uint32_t)((uint32_t)(SCB_SCR_SLEEPDEEP_Msk | SCB_SCR_SLEEPONEXIT_Msk));
517 }
518
519 void HAL_PCD_ResumeCallback(PCD_HandleTypeDef *hpcd)
520 {
521   struct usb *usb = hpcd->pData;
522   usb->state = usb->pre_suspend_state;
523 }
524
525 void HAL_PCD_ISOOUTIncompleteCallback(PCD_HandleTypeDef *hpcd, uint8_t epnum)
526 {
527   // We do not support isochronous mode
528 }
529
530 void HAL_PCD_ISOINIncompleteCallback(PCD_HandleTypeDef *hpcd, uint8_t epnum)
531 {
532   // We do not support isochronous mode
533 }
534
535 void HAL_PCD_ConnectCallback(PCD_HandleTypeDef *hpcd)
536 {
537 }
538
539 void HAL_PCD_DisconnectCallback(PCD_HandleTypeDef *hpcd)
540 {
541   struct usb *usb = hpcd->pData;
542   usb->state = USB_STATE_DEFAULT;
543 }