2 #include "stm32f1xx_hal.h"
8 void _Error_Handler(char * file, int line); // FIXME
10 void usb_init(struct usb *usb, PCD_HandleTypeDef *hpcd)
12 memset(usb, 0, sizeof(*usb));
14 usb->state = USB_STATE_DEFAULT;
15 usb->ep0_state = USB_EP0_IDLE;
17 HAL_PCDEx_PMAConfig(hpcd, 0x00, PCD_SNG_BUF, 0x18);
18 HAL_PCDEx_PMAConfig(hpcd, 0x80, PCD_SNG_BUF, 0x58);
23 static inline uint get_u16(byte *p)
25 return (p[1] << 8) | p[0];
28 static inline void put_u16(byte *p, u16 x)
35 static struct usb_endpoint *ep_by_addr(struct usb *usb, byte ep_addr)
37 return ((ep_addr & 0x80) ? usb->ep_in : usb->ep_out) + (ep_addr & 0x7f);
41 static void usb_ctl_send_status(struct usb *usb)
43 usb->ep0_state = USB_EP0_STATUS_IN;
44 usb_ep_transmit(usb, 0x00, NULL, 0);
48 static void usb_ctl_recv_status(struct usb *usb)
50 usb->ep0_state = USB_EP0_STATUS_OUT;
51 usb_ep_receive(usb, 0x00, NULL, 0);
55 static void usb_ctl_send_data(struct usb *usb, byte *data, uint len)
57 usb->ep0_state = USB_EP0_DATA_IN;
58 usb->ep0_total_length = len;
59 usb->ep0_remaining_length = len;
60 usb_ep_transmit(usb, 0x00, data, len);
64 static void usb_ctl_recv_data(struct usb *usb, byte *data, uint len)
66 usb->ep0_state = USB_EP0_DATA_OUT;
67 usb->ep0_total_length = len;
68 usb->ep0_remaining_length = len;
69 usb_ep_transmit(usb, 0x00, data, len);
73 static void usb_ctl_send_byte(struct usb *usb, byte data)
75 usb->status_buf[0] = data;
76 usb_ctl_send_data(usb, usb->status_buf, 1);
79 static void usb_ctl_send_u16(struct usb *usb, u16 data)
81 put_u16(usb->status_buf, data);
82 usb_ctl_send_data(usb, usb->status_buf, 2);
85 static void usb_ctl_error(struct usb *usb)
87 usb_ep_stall(usb, 0x00);
88 usb_ep_stall(usb, 0x80);
91 struct setup_request {
99 static void usb_ctl_setup_error(struct usb *usb, struct setup_request *setup)
101 usb_ep_stall(usb, setup->bmRequest & USB_REQ_DIRECTION);
104 static void dev_get_status(struct usb *usb, struct setup_request *setup)
106 if ((usb->state != USB_STATE_ADDRESSED && usb->state != USB_STATE_CONFIGURED) ||
107 setup->wValue || setup->wIndex || setup->wLength != 2)
108 return usb_ctl_error(usb);
111 #ifdef USB_SELF_POWERED
112 stat |= USB_DEV_STATUS_SELF_POWERED;
114 if (usb->remote_wakeup)
115 stat |= USB_DEV_STATUS_REMOTE_WAKEUP;
116 usb_ctl_send_u16(usb, stat);
119 static void dev_clear_feature(struct usb *usb, struct setup_request *setup)
121 if (setup->wIndex || setup->wLength)
122 return usb_ctl_error(usb);
124 if (setup->wValue == USB_FEATURE_REMOTE_WAKEUP)
126 usb->remote_wakeup = 0;
127 usb_ctl_send_status(usb);
133 static void dev_set_feature(struct usb *usb, struct setup_request *setup)
135 if (setup->wIndex || setup->wLength)
136 return usb_ctl_error(usb);
138 if (setup->wValue == USB_FEATURE_REMOTE_WAKEUP)
140 usb->remote_wakeup = 1;
141 usb_ctl_send_status(usb);
147 static void dev_set_address(struct usb *usb, struct setup_request *setup)
149 if (setup->wIndex || setup->wLength)
150 return usb_ctl_error(usb);
152 uint addr = setup->wValue & 0x7f;
153 if (usb->state == USB_STATE_CONFIGURED)
158 HAL_PCD_SetAddress(usb->hpcd, addr);
159 usb_ctl_send_status(usb);
160 usb->state = addr ? USB_STATE_ADDRESSED : USB_STATE_DEFAULT;
164 static void dev_get_descriptor(struct usb *usb, struct setup_request *setup)
168 static void dev_get_configuration(struct usb *usb, struct setup_request *setup)
170 if (setup->wValue || setup->wIndex || setup->wLength != 1)
171 return usb_ctl_error(usb);
175 case USB_STATE_ADDRESSED:
176 usb_ctl_send_byte(usb, 0);
178 case USB_STATE_CONFIGURED:
179 usb_ctl_send_byte(usb, usb->config);
186 static void dev_set_configuration(struct usb *usb, struct setup_request *setup)
188 byte cfg = setup->wValue & 0xff;
190 // FIXME: Support more configurations
191 if (cfg > 1 || setup->wIndex || setup->wLength)
192 return usb_ctl_error(usb);
196 case USB_STATE_ADDRESSED:
200 usb->state = USB_STATE_CONFIGURED;
201 // FIXME: Notify that the device was configured
203 usb_ctl_send_status(usb);
205 case USB_STATE_CONFIGURED:
210 usb->state = USB_STATE_ADDRESSED;
211 // FIXME: Notify that the device was unconfigured
213 else if (cfg != usb->config)
216 // FIXME: Notify about configuration change
218 usb_ctl_send_status(usb);
225 static void dev_setup(struct usb *usb, struct setup_request *setup)
227 switch (setup->bRequest)
229 case USB_REQ_GET_STATUS:
230 return dev_get_status(usb, setup);
231 case USB_REQ_CLEAR_FEATURE:
232 return dev_clear_feature(usb, setup);
233 case USB_REQ_SET_FEATURE:
234 return dev_set_feature(usb, setup);
235 case USB_REQ_SET_ADDRESS:
236 return dev_set_address(usb, setup);
237 case USB_REQ_GET_DESCRIPTOR:
238 return dev_get_descriptor(usb, setup);
239 case USB_REQ_GET_CONFIGURATION:
240 return dev_get_configuration(usb, setup);
241 case USB_REQ_SET_CONFIGURATION:
242 return dev_set_configuration(usb, setup);
245 usb_ctl_setup_error(usb, setup);
248 static void intf_setup(struct usb *usb, struct setup_request *setup)
250 byte intf = setup->wIndex & 0xff;
254 // FIXME: Support more interfaces
259 switch (setup->bRequest)
261 case USB_REQ_GET_STATUS:
262 if (setup->wValue || setup->wLength != 2 || usb->state != USB_STATE_CONFIGURED)
265 usb_ctl_send_u16(usb, 0);
268 case USB_REQ_CLEAR_FEATURE:
269 case USB_REQ_SET_FEATURE:
270 // Interfaces have no standard features
271 return usb_ctl_error(usb);
274 usb_ctl_setup_error(usb, setup);
277 static void ep_setup(struct usb *usb, struct setup_request *setup)
279 byte ep_addr = setup->wIndex & 0x8f;
281 switch (setup->bRequest)
283 case USB_REQ_GET_STATUS:
284 if (setup->wValue || setup->wLength != 2)
285 return usb_ctl_error(usb);
288 case USB_STATE_ADDRESSED:
292 case USB_STATE_CONFIGURED:
294 if (usb_ep_is_stalled(usb, ep_addr))
295 usb_ctl_send_u16(usb, 1);
297 usb_ctl_send_u16(usb, 0);
301 return usb_ctl_error(usb);
305 case USB_REQ_SET_FEATURE:
307 return usb_ctl_error(usb);
310 case USB_STATE_ADDRESSED:
314 case USB_STATE_CONFIGURED:
315 if (setup->wValue == USB_FEATURE_EP_HALT)
318 usb_ep_stall(usb, ep_addr);
320 usb_ctl_send_status(usb);
327 case USB_REQ_CLEAR_FEATURE:
329 return usb_ctl_error(usb);
332 case USB_STATE_ADDRESSED:
336 case USB_STATE_CONFIGURED:
337 if (setup->wValue == USB_FEATURE_EP_HALT)
340 usb_ep_unstall(usb, ep_addr);
342 usb_ctl_send_status(usb);
350 usb_ctl_setup_error(usb, setup);
353 static void usb_handle_setup(struct usb *usb, struct setup_request *setup)
355 usb->ep0_state = USB_EP0_SETUP;
356 usb->ep0_setup_data_length = setup->wLength;
358 if ((setup->bmRequest & USB_REQ_TYPE_MASK) != USB_REQ_TYPE_STANDARD)
360 // FIXME: Class-specific and vendor-specific setup packets not supported
361 // FIXME: Check USB_STATE_CONFIGURED here
362 usb_ctl_setup_error(usb, setup);
365 switch (setup->bmRequest & USB_REQ_RECIPIENT_MASK)
367 case USB_REQ_RECIPIENT_DEVICE:
368 return dev_setup(usb, setup);
369 case USB_REQ_RECIPIENT_INTERFACE:
370 return intf_setup(usb, setup);
371 case USB_REQ_RECIPIENT_ENDPOINT:
372 return ep_setup(usb, setup);
375 usb_ctl_setup_error(usb, setup);
378 void HAL_PCD_SetupStageCallback(PCD_HandleTypeDef *hpcd)
380 struct usb *usb = hpcd->pData;
381 byte *req = (byte *) hpcd->Setup;
383 struct setup_request setup = {
386 .wValue = get_u16(req+2),
387 .wIndex = get_u16(req+4),
388 .wLength = get_u16(req+2),
390 usb_handle_setup(usb, &setup);
393 void HAL_PCD_DataOutStageCallback(PCD_HandleTypeDef *hpcd, uint8_t epnum)
395 struct usb *usb = hpcd->pData;
396 PCD_EPTypeDef *ep = &hpcd->IN_ep[epnum];
400 // HAL/LL handle EP0 transfers in a completely different way, we have to do many things ourselves
401 if (usb->ep0_state != USB_EP0_DATA_OUT)
403 if (usb->ep0_remaining_length > ep->maxpacket)
405 usb->ep0_remaining_length -= ep->maxpacket;
406 usb_ep_receive(usb, 0x00, ep->xfer_buff, MIN(usb->ep0_remaining_length, ep->maxpacket));
410 if (usb->state == USB_STATE_CONFIGURED)
412 // FIXME: Handle incoming control packet
414 usb_ctl_send_status(usb);
419 if (usb->state == USB_STATE_CONFIGURED)
421 // FIXME: Custom data callback
426 void HAL_PCD_DataInStageCallback(PCD_HandleTypeDef *hpcd, uint8_t epnum)
428 struct usb *usb = hpcd->pData;
429 PCD_EPTypeDef *ep = &hpcd->IN_ep[epnum];
433 // HAL/LL handle EP0 transfers in a completely different way, we have to do many things ourselves
434 if (usb->ep0_state != USB_EP0_DATA_IN)
436 if (usb->ep0_remaining_length > ep->maxpacket)
438 usb->ep0_remaining_length -= ep->maxpacket;
439 usb_ep_transmit(usb, 0x00, ep->xfer_buff, usb->ep0_remaining_length);
440 usb_ep_receive(usb, 0x00, NULL, 0);
442 else if (usb->ep0_total_length && usb->ep0_total_length % ep->maxpacket == 0 && usb->ep0_total_length < usb->ep0_setup_data_length)
445 * Each data transfer must be terminated by either a small packet (less than maxpacket)
446 * or by reaching the answer size requested in the setup packet. Send an empty final packet
449 usb_ep_transmit(usb, 0x00, NULL, 0);
450 usb->ep0_setup_data_length = 0;
451 usb_ep_receive(usb, 0x00, NULL, 0);
455 if (usb->state == USB_STATE_CONFIGURED)
457 // FIXME: Custom data callback
458 // All data have been sent
464 if (usb->state == USB_STATE_CONFIGURED)
466 // FIXME: Custom data callback
467 // This gets called when a complete message is sent
472 void HAL_PCD_SOFCallback(PCD_HandleTypeDef *hpcd)
474 // We are not interested in Start of frame packets
475 // (neither we set hpcd->Init.Sof_enable, so this callback does not get called)
478 void HAL_PCD_ResetCallback(PCD_HandleTypeDef *hpcd)
480 struct usb *usb = hpcd->pData;
482 usb->state = USB_STATE_DEFAULT;
484 usb_ep_open(usb, 0x00, USB_EP_TYPE_CTRL, USB_MAX_EP0_SIZE);
485 usb_ep_open(usb, 0x80, USB_EP_TYPE_CTRL, USB_MAX_EP0_SIZE);
488 void HAL_PCD_SuspendCallback(PCD_HandleTypeDef *hpcd)
490 struct usb *usb = hpcd->pData;
492 usb->pre_suspend_state = usb->state;
493 usb->state = USB_STATE_SUSPENDED;
495 if (hpcd->Init.low_power_enable)
496 SCB->SCR |= (uint32_t)((uint32_t)(SCB_SCR_SLEEPDEEP_Msk | SCB_SCR_SLEEPONEXIT_Msk));
499 void HAL_PCD_ResumeCallback(PCD_HandleTypeDef *hpcd)
501 struct usb *usb = hpcd->pData;
502 usb->state = usb->pre_suspend_state;
505 void HAL_PCD_ISOOUTIncompleteCallback(PCD_HandleTypeDef *hpcd, uint8_t epnum)
507 // We do not support isochronous mode
510 void HAL_PCD_ISOINIncompleteCallback(PCD_HandleTypeDef *hpcd, uint8_t epnum)
512 // We do not support isochronous mode
515 void HAL_PCD_ConnectCallback(PCD_HandleTypeDef *hpcd)
519 void HAL_PCD_DisconnectCallback(PCD_HandleTypeDef *hpcd)
521 struct usb *usb = hpcd->pData;
522 usb->state = USB_STATE_DEFAULT;