From 514b48b7205e1be5e1b0fc66bc073aa724dd98c9 Mon Sep 17 00:00:00 2001 From: Martin Mares Date: Sun, 24 Jun 2018 13:40:15 +0200 Subject: [PATCH] Cleaned up handling of endpoints --- Inc/usb.h | 13 +++---------- Src/usb.c | 58 +++++++++++++++++++++++++++++++++++-------------------- 2 files changed, 40 insertions(+), 31 deletions(-) diff --git a/Inc/usb.h b/Inc/usb.h index ec7cc23..589774d 100644 --- a/Inc/usb.h +++ b/Inc/usb.h @@ -12,24 +12,17 @@ typedef int32_t s32; /*** USB state structure ***/ -struct usb_endpoint { - u32 max_packet_size; - u32 total_length; - u32 remaining_length; -}; - struct usb { PCD_HandleTypeDef *hpcd; byte state; // USB_STATE_xxx byte pre_suspend_state; byte address; - byte speed; // PCD_SPEED_xxx byte config; byte remote_wakeup; byte ep0_state; // USB_EP0_xxx - byte ep0_data_len; - struct usb_endpoint ep_in[15]; - struct usb_endpoint ep_out[15]; + u16 ep0_setup_data_length; + u16 ep0_remaining_length; + u16 ep0_total_length; byte status_buf[2]; }; diff --git a/Src/usb.c b/Src/usb.c index 434408d..b7604ab 100644 --- a/Src/usb.c +++ b/Src/usb.c @@ -3,10 +3,13 @@ #include "usb.h" +#include + void _Error_Handler(char * file, int line); // FIXME void usb_init(struct usb *usb, PCD_HandleTypeDef *hpcd) { + memset(usb, 0, sizeof(*usb)); usb->hpcd = hpcd; usb->state = USB_STATE_DEFAULT; usb->ep0_state = USB_EP0_IDLE; @@ -52,10 +55,20 @@ static void usb_ctl_recv_status(struct usb *usb) static void usb_ctl_send_data(struct usb *usb, byte *data, uint len) { usb->ep0_state = USB_EP0_DATA_IN; - usb->ep_in[0].total_length = len; - usb->ep_in[0].remaining_length = len; + usb->ep0_total_length = len; + usb->ep0_remaining_length = len; + usb_ep_transmit(usb, 0x00, data, len); +} + +#if 0 // FIXME +static void usb_ctl_recv_data(struct usb *usb, byte *data, uint len) +{ + usb->ep0_state = USB_EP0_DATA_OUT; + usb->ep0_total_length = len; + usb->ep0_remaining_length = len; usb_ep_transmit(usb, 0x00, data, len); } +#endif static void usb_ctl_send_byte(struct usb *usb, byte data) { @@ -340,7 +353,7 @@ static void ep_setup(struct usb *usb, struct setup_request *setup) static void usb_handle_setup(struct usb *usb, struct setup_request *setup) { usb->ep0_state = USB_EP0_SETUP; - usb->ep0_data_len = setup->wLength; + usb->ep0_setup_data_length = setup->wLength; if ((setup->bmRequest & USB_REQ_TYPE_MASK) != USB_REQ_TYPE_STANDARD) { @@ -380,17 +393,17 @@ void HAL_PCD_SetupStageCallback(PCD_HandleTypeDef *hpcd) void HAL_PCD_DataOutStageCallback(PCD_HandleTypeDef *hpcd, uint8_t epnum) { struct usb *usb = hpcd->pData; - struct usb_endpoint *ep = &usb->ep_out[epnum]; - byte *data = hpcd->OUT_ep[epnum].xfer_buff; + PCD_EPTypeDef *ep = &hpcd->IN_ep[epnum]; if (!epnum) { + // HAL/LL handle EP0 transfers in a completely different way, we have to do many things ourselves if (usb->ep0_state != USB_EP0_DATA_OUT) return; - if (ep->remaining_length > ep->max_packet_size) + if (usb->ep0_remaining_length > ep->maxpacket) { - ep->remaining_length -= ep->max_packet_size; - usb_ep_receive(usb, 0x00, data, MIN(ep->remaining_length, ep->max_packet_size)); + usb->ep0_remaining_length -= ep->maxpacket; + usb_ep_receive(usb, 0x00, ep->xfer_buff, MIN(usb->ep0_remaining_length, ep->maxpacket)); } else { @@ -413,24 +426,28 @@ void HAL_PCD_DataOutStageCallback(PCD_HandleTypeDef *hpcd, uint8_t epnum) void HAL_PCD_DataInStageCallback(PCD_HandleTypeDef *hpcd, uint8_t epnum) { struct usb *usb = hpcd->pData; - struct usb_endpoint *ep = &usb->ep_in[epnum]; - byte *data = hpcd->IN_ep[epnum].xfer_buff; + PCD_EPTypeDef *ep = &hpcd->IN_ep[epnum]; if (!epnum) { + // HAL/LL handle EP0 transfers in a completely different way, we have to do many things ourselves if (usb->ep0_state != USB_EP0_DATA_IN) return; - if (ep->remaining_length > ep->max_packet_size) + if (usb->ep0_remaining_length > ep->maxpacket) { - ep->remaining_length -= ep->max_packet_size; - usb_ep_transmit(usb, 0x00, data, ep->remaining_length); + usb->ep0_remaining_length -= ep->maxpacket; + usb_ep_transmit(usb, 0x00, ep->xfer_buff, usb->ep0_remaining_length); usb_ep_receive(usb, 0x00, NULL, 0); } - else if (ep->total_length && ep->total_length % ep->max_packet_size == 0 && ep->total_length < usb->ep0_data_len) + else if (usb->ep0_total_length && usb->ep0_total_length % ep->maxpacket == 0 && usb->ep0_total_length < usb->ep0_setup_data_length) { - // Send an empty packet if total length is divisible by MTU + /* + * Each data transfer must be terminated by either a small packet (less than maxpacket) + * or by reaching the answer size requested in the setup packet. Send an empty final packet + * if needed. + */ usb_ep_transmit(usb, 0x00, NULL, 0); - usb->ep0_data_len = 0; + usb->ep0_setup_data_length = 0; usb_ep_receive(usb, 0x00, NULL, 0); } else @@ -438,6 +455,7 @@ void HAL_PCD_DataInStageCallback(PCD_HandleTypeDef *hpcd, uint8_t epnum) if (usb->state == USB_STATE_CONFIGURED) { // FIXME: Custom data callback + // All data have been sent } } } @@ -446,13 +464,15 @@ void HAL_PCD_DataInStageCallback(PCD_HandleTypeDef *hpcd, uint8_t epnum) if (usb->state == USB_STATE_CONFIGURED) { // FIXME: Custom data callback + // This gets called when a complete message is sent } } } void HAL_PCD_SOFCallback(PCD_HandleTypeDef *hpcd) { - // FIXME + // We are not interested in Start of frame packets + // (neither we set hpcd->Init.Sof_enable, so this callback does not get called) } void HAL_PCD_ResetCallback(PCD_HandleTypeDef *hpcd) @@ -460,13 +480,9 @@ void HAL_PCD_ResetCallback(PCD_HandleTypeDef *hpcd) struct usb *usb = hpcd->pData; usb->state = USB_STATE_DEFAULT; - usb->speed = hpcd->Init.speed; usb_ep_open(usb, 0x00, USB_EP_TYPE_CTRL, USB_MAX_EP0_SIZE); - usb->ep_out[0].max_packet_size = USB_MAX_EP0_SIZE; - usb_ep_open(usb, 0x80, USB_EP_TYPE_CTRL, USB_MAX_EP0_SIZE); - usb->ep_in[0].max_packet_size = USB_MAX_EP0_SIZE; } void HAL_PCD_SuspendCallback(PCD_HandleTypeDef *hpcd) -- 2.39.2