#include "stm32f1xx.h"
#include "stm32f1xx_hal.h"
+#include "util.h"
#include "usb.h"
#include <string.h>
USB_DESC_TYPE_INTERFACE, // bDescriptorType
0x00, // bInterfaceNumber
0x00, // bAlternateSetting
- 0x01, // bNumEndpoints
+ 0x02, // bNumEndpoints
0xff, // bInterfaceClass: vendor-defined
0x00, // bInterfaceSubClass
0x00, // nInterfaceProtocol
};
static const char * const desc_string[] = {
- "", // DESC_STR_NONE
+ NULL, // DESC_STR_NONE
"United Computer Wizards", // DESC_STR_MANUFACTURER
"Mysterious Gadget", // DESC_STR_PRODUCT
"00000042", // DESC_STR_SERIAL
"Default Interface", // DESC_STR_INTERFACE
};
+static const byte desc_languages[] = {
+ 4, // bLength
+ USB_DESC_TYPE_STRING, // bDescriptorType
+ DESC_U16(1033), // English
+};
+
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;
+ hpcd->pData = usb;
+}
- HAL_PCDEx_PMAConfig(hpcd, 0x00, PCD_SNG_BUF, 0x18);
- HAL_PCDEx_PMAConfig(hpcd, 0x80, PCD_SNG_BUF, 0x58);
+void usb_start(struct usb *usb)
+{
+ HAL_PCDEx_PMAConfig(usb->hpcd, 0x00, PCD_SNG_BUF, 0x18);
+ HAL_PCDEx_PMAConfig(usb->hpcd, 0x80, PCD_SNG_BUF, 0x58);
- HAL_PCD_Start(hpcd);
+ HAL_PCD_Start(usb->hpcd);
}
static inline uint get_u16(byte *p)
p[1] = x >> 8;
}
-#if 0 // FIXME
-static struct usb_endpoint *ep_by_addr(struct usb *usb, byte ep_addr)
-{
- return ((ep_addr & 0x80) ? usb->ep_in : usb->ep_out) + (ep_addr & 0x7f);
-}
-#endif
-
static void usb_ctl_send_status(struct usb *usb)
{
+ usb_debug("Control send: status\n");
usb->ep0_state = USB_EP0_STATUS_IN;
usb_ep_transmit(usb, 0x00, NULL, 0);
}
-#if 0 // FIXME
static void usb_ctl_recv_status(struct usb *usb)
{
usb->ep0_state = USB_EP0_STATUS_OUT;
usb_ep_receive(usb, 0x00, NULL, 0);
}
-#endif
static void usb_ctl_send_data(struct usb *usb, const byte *data, uint len)
{
+ usb_debug("Control send: %u bytes\n", len);
usb->ep0_state = USB_EP0_DATA_IN;
usb->ep0_total_length = len;
usb->ep0_remaining_length = len;
#if 0 // FIXME
static void usb_ctl_recv_data(struct usb *usb, byte *data, uint len)
{
+ usb_debug("Control recv: %u bytes\n", len);
usb->ep0_state = USB_EP0_DATA_OUT;
usb->ep0_total_length = len;
usb->ep0_remaining_length = len;
static void usb_ctl_error(struct usb *usb)
{
+ usb_debug("Control packet error\n");
usb_ep_stall(usb, 0x00);
usb_ep_stall(usb, 0x80);
}
static void usb_ctl_setup_error(struct usb *usb, struct setup_request *setup)
{
+ usb_debug("Setup packet error\n");
usb_ep_stall(usb, setup->bmRequest & USB_REQ_DIRECTION);
}
case USB_DESC_TYPE_CONFIGURATION:
return dev_desc_send(usb, setup, desc_config, sizeof(desc_config));
case USB_DESC_TYPE_STRING:
+ if (!desc_index)
+ return dev_desc_send(usb, setup, desc_languages, sizeof(desc_languages));
if (desc_index < sizeof(desc_string) / sizeof(desc_string[0]))
return dev_desc_send_string(usb, setup, desc_string[desc_index]);
break;
static void usb_handle_setup(struct usb *usb, struct setup_request *setup)
{
+ usb_debug("Setup: type=%02x req=%02x val=%04x idx=%04x len=%04x\n", setup->bmRequest, setup->bRequest, setup->wValue, setup->wIndex, setup->wLength);
+
usb->ep0_state = USB_EP0_SETUP;
usb->ep0_setup_data_length = setup->wLength;
.bRequest = req[1],
.wValue = get_u16(req+2),
.wIndex = get_u16(req+4),
- .wLength = get_u16(req+2),
+ .wLength = get_u16(req+6),
};
usb_handle_setup(usb, &setup);
}
if (!epnum)
{
// HAL/LL handle EP0 transfers in a completely different way, we have to do many things ourselves
+ usb_debug("Ep0 OUT: state=%u rem=%u total=%u\n", usb->ep0_state, usb->ep0_remaining_length, usb->ep0_total_length);
if (usb->ep0_state != USB_EP0_DATA_OUT)
return;
if (usb->ep0_remaining_length > ep->maxpacket)
if (!epnum)
{
// HAL/LL handle EP0 transfers in a completely different way, we have to do many things ourselves
+ 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);
if (usb->ep0_state != USB_EP0_DATA_IN)
return;
if (usb->ep0_remaining_length > ep->maxpacket)
// FIXME: Custom data callback
// All data have been sent
}
+ usb_ctl_recv_status(usb);
}
}
else