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