#include "usb.h"
+#include <string.h>
+
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;
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)
{
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)
{
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
{
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
if (usb->state == USB_STATE_CONFIGURED)
{
// FIXME: Custom data callback
+ // All data have been sent
}
}
}
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)
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)