diff --git a/ports/stm32/usb.c b/ports/stm32/usb.c index e86f69ac55..e253cf0118 100644 --- a/ports/stm32/usb.c +++ b/ports/stm32/usb.c @@ -127,7 +127,7 @@ bool pyb_usb_dev_init(uint16_t vid, uint16_t pid, usb_device_mode_t mode, USBD_H usbd->pClass = &USBD_CDC_MSC_HID; usb_dev->usbd_cdc_msc_hid_state.pdev = usbd; usb_dev->usbd_cdc_msc_hid_state.cdc = &usb_dev->usbd_cdc_itf.base; - usb_dev->usbd_cdc_msc_hid_state.hid = &usb_dev->usbd_hid_itf; + usb_dev->usbd_cdc_msc_hid_state.hid = &usb_dev->usbd_hid_itf.base; usbd->pClassData = &usb_dev->usbd_cdc_msc_hid_state; // configure the VID, PID and the USBD mode (interfaces it will expose) diff --git a/ports/stm32/usbd_hid_interface.c b/ports/stm32/usbd_hid_interface.c index 9ab5986b66..d8c160fe7b 100644 --- a/ports/stm32/usbd_hid_interface.c +++ b/ports/stm32/usbd_hid_interface.c @@ -42,8 +42,9 @@ #include "irq.h" #include "usb.h" -uint8_t *usbd_hid_init(usbd_hid_itf_t *hid, usbd_cdc_msc_hid_state_t *usbd) { - hid->usbd = usbd; +uint8_t *usbd_hid_init(usbd_hid_state_t *hid_in) { + usbd_hid_itf_t *hid = (usbd_hid_itf_t*)hid_in; + hid->current_read_buffer = 0; hid->last_read_len = 0; hid->current_write_buffer = 0; @@ -55,13 +56,15 @@ uint8_t *usbd_hid_init(usbd_hid_itf_t *hid, usbd_cdc_msc_hid_state_t *usbd) { // Data received over USB OUT endpoint is processed here. // len: number of bytes received into the buffer we passed to USBD_HID_ReceivePacket // Returns USBD_OK if all operations are OK else USBD_FAIL -int8_t usbd_hid_receive(usbd_hid_itf_t *hid, size_t len) { +int8_t usbd_hid_receive(usbd_hid_state_t *hid_in, size_t len) { + usbd_hid_itf_t *hid = (usbd_hid_itf_t*)hid_in; + hid->current_write_buffer = !hid->current_write_buffer; hid->last_read_len = len; // initiate next USB packet transfer, to append to existing data in buffer - USBD_HID_ReceivePacket(hid->usbd, hid->buffer[hid->current_write_buffer]); + USBD_HID_ReceivePacket(hid->base.usbd, hid->buffer[hid->current_write_buffer]); // Set NAK to indicate we need to process read buffer - USBD_HID_SetNAK(hid->usbd); + USBD_HID_SetNAK(hid->base.usbd); return USBD_OK; } @@ -99,7 +102,7 @@ int usbd_hid_rx(usbd_hid_itf_t *hid, size_t len, uint8_t *buf, uint32_t timeout) hid->current_read_buffer = !hid->current_read_buffer; // Clear NAK to indicate we are ready to read more data - USBD_HID_ClearNAK(hid->usbd); + USBD_HID_ClearNAK(hid->base.usbd); // Success, return number of bytes read return read_len; diff --git a/ports/stm32/usbd_hid_interface.h b/ports/stm32/usbd_hid_interface.h index d9adf8a5f3..777fa93403 100644 --- a/ports/stm32/usbd_hid_interface.h +++ b/ports/stm32/usbd_hid_interface.h @@ -7,7 +7,7 @@ #include "usbd_cdc_msc_hid.h" typedef struct _usbd_hid_itf_t { - usbd_cdc_msc_hid_state_t *usbd; // the parent USB device + usbd_hid_state_t base; // state for the base HID layer uint8_t buffer[2][HID_DATA_FS_MAX_PACKET_SIZE]; // pair of buffers to read individual packets into int8_t current_read_buffer; // which buffer to read from diff --git a/ports/stm32/usbdev/class/inc/usbd_cdc_msc_hid.h b/ports/stm32/usbdev/class/inc/usbd_cdc_msc_hid.h index 43a494ebd9..18c2c56c3c 100644 --- a/ports/stm32/usbdev/class/inc/usbd_cdc_msc_hid.h +++ b/ports/stm32/usbdev/class/inc/usbd_cdc_msc_hid.h @@ -98,25 +98,25 @@ typedef enum { } HID_StateTypeDef; typedef struct { - uint32_t Protocol; - uint32_t IdleState; - uint32_t AltSetting; - HID_StateTypeDef state; -} USBD_HID_HandleTypeDef; + struct _usbd_cdc_msc_hid_state_t *usbd; // The parent USB device + uint8_t iface_num; + uint8_t in_ep; + uint8_t out_ep; + uint8_t state; + uint8_t ctl_protocol; + uint8_t ctl_idle_state; + uint8_t ctl_alt_setting; + uint8_t *desc; + const uint8_t *report_desc; +} usbd_hid_state_t; typedef struct _usbd_cdc_msc_hid_state_t { USBD_HandleTypeDef *pdev; uint8_t usbd_mode; - uint8_t hid_in_ep; - uint8_t hid_out_ep; - uint8_t hid_iface_num; uint8_t usbd_config_desc_size; - uint8_t *hid_desc; - const uint8_t *hid_report_desc; USBD_MSC_BOT_HandleTypeDef MSC_BOT_ClassData; - USBD_HID_HandleTypeDef HID_ClassData; // RAM to hold the current descriptors, which we configure on the fly __ALIGN_BEGIN uint8_t usbd_device_desc[USB_LEN_DEV_DESC] __ALIGN_END; @@ -124,7 +124,7 @@ typedef struct _usbd_cdc_msc_hid_state_t { __ALIGN_BEGIN uint8_t usbd_config_desc[MAX_TEMPLATE_CONFIG_DESC_SIZE] __ALIGN_END; usbd_cdc_state_t *cdc; - void *hid; + usbd_hid_state_t *hid; } usbd_cdc_msc_hid_state_t; #define USBD_HID_MOUSE_MAX_PACKET (4) @@ -185,8 +185,7 @@ int8_t usbd_cdc_control(usbd_cdc_state_t *cdc, uint8_t cmd, uint8_t* pbuf, uint1 int8_t usbd_cdc_receive(usbd_cdc_state_t *cdc, size_t len); // These are provided externally to implement the HID interface -struct _usbd_hid_itf_t; -uint8_t *usbd_hid_init(struct _usbd_hid_itf_t *hid, usbd_cdc_msc_hid_state_t *usbd); -int8_t usbd_hid_receive(struct _usbd_hid_itf_t *hid, size_t len); +uint8_t *usbd_hid_init(usbd_hid_state_t *hid); +int8_t usbd_hid_receive(usbd_hid_state_t *hid, size_t len); #endif // _USB_CDC_MSC_CORE_H_ diff --git a/ports/stm32/usbdev/class/src/usbd_cdc_msc_hid.c b/ports/stm32/usbdev/class/src/usbd_cdc_msc_hid.c index 7944ae7778..9ef92a1a6e 100644 --- a/ports/stm32/usbdev/class/src/usbd_cdc_msc_hid.c +++ b/ports/stm32/usbdev/class/src/usbd_cdc_msc_hid.c @@ -624,10 +624,10 @@ int USBD_SelectMode(usbd_cdc_msc_hid_state_t *usbd, uint32_t mode, USBD_HID_Mode usbd->usbd_config_desc_size = sizeof(cdc_hid_template_config_desc); memcpy(usbd->usbd_config_desc, cdc_hid_template_config_desc, sizeof(cdc_hid_template_config_desc)); usbd->cdc->iface_num = CDC_IFACE_NUM_WITH_HID; - usbd->hid_in_ep = HID_IN_EP_WITH_CDC; - usbd->hid_out_ep = HID_OUT_EP_WITH_CDC; - usbd->hid_iface_num = HID_IFACE_NUM_WITH_CDC; - usbd->hid_desc = usbd->usbd_config_desc + CDC_HID_TEMPLATE_HID_DESC_OFFSET; + usbd->hid->in_ep = HID_IN_EP_WITH_CDC; + usbd->hid->out_ep = HID_OUT_EP_WITH_CDC; + usbd->hid->iface_num = HID_IFACE_NUM_WITH_CDC; + usbd->hid->desc = usbd->usbd_config_desc + CDC_HID_TEMPLATE_HID_DESC_OFFSET; break; case USBD_MODE_CDC: @@ -652,7 +652,7 @@ int USBD_SelectMode(usbd_cdc_msc_hid_state_t *usbd, uint32_t mode, USBD_HID_Mode // configure the HID descriptor, if needed if (usbd->usbd_mode & USBD_MODE_HID) { - uint8_t *hid_desc = usbd->hid_desc; + uint8_t *hid_desc = usbd->hid->desc; hid_desc[HID_DESC_OFFSET_SUBCLASS] = hid_info->subclass; hid_desc[HID_DESC_OFFSET_PROTOCOL] = hid_info->protocol; hid_desc[HID_DESC_OFFSET_REPORT_DESC_LEN] = hid_info->report_desc_len; @@ -662,7 +662,7 @@ int USBD_SelectMode(usbd_cdc_msc_hid_state_t *usbd, uint32_t mode, USBD_HID_Mode hid_desc[HID_DESC_OFFSET_MAX_PACKET_OUT_LO] = hid_info->max_packet_len; hid_desc[HID_DESC_OFFSET_MAX_PACKET_OUT_HI] = 0; hid_desc[HID_DESC_OFFSET_POLLING_INTERVAL_OUT] = hid_info->polling_interval; - usbd->hid_report_desc = hid_info->report_desc; + usbd->hid->report_desc = hid_info->report_desc; } return 0; @@ -739,30 +739,26 @@ static uint8_t USBD_CDC_MSC_HID_Init(USBD_HandleTypeDef *pdev, uint8_t cfgidx) { // get max packet lengths from descriptor uint16_t mps_in = - usbd->hid_desc[HID_DESC_OFFSET_MAX_PACKET_LO] - | (usbd->hid_desc[HID_DESC_OFFSET_MAX_PACKET_HI] << 8); + usbd->hid->desc[HID_DESC_OFFSET_MAX_PACKET_LO] + | (usbd->hid->desc[HID_DESC_OFFSET_MAX_PACKET_HI] << 8); uint16_t mps_out = - usbd->hid_desc[HID_DESC_OFFSET_MAX_PACKET_OUT_LO] - | (usbd->hid_desc[HID_DESC_OFFSET_MAX_PACKET_OUT_HI] << 8); + usbd->hid->desc[HID_DESC_OFFSET_MAX_PACKET_OUT_LO] + | (usbd->hid->desc[HID_DESC_OFFSET_MAX_PACKET_OUT_HI] << 8); // Open EP IN - USBD_LL_OpenEP(pdev, - usbd->hid_in_ep, - USBD_EP_TYPE_INTR, - mps_in); + USBD_LL_OpenEP(pdev, usbd->hid->in_ep, USBD_EP_TYPE_INTR, mps_in); // Open EP OUT - USBD_LL_OpenEP(pdev, - usbd->hid_out_ep, - USBD_EP_TYPE_INTR, - mps_out); + USBD_LL_OpenEP(pdev, usbd->hid->out_ep, USBD_EP_TYPE_INTR, mps_out); - uint8_t *buf = usbd_hid_init(usbd->hid, usbd); + + usbd->hid->usbd = usbd; + uint8_t *buf = usbd_hid_init(usbd->hid); // Prepare Out endpoint to receive next packet - USBD_LL_PrepareReceive(pdev, usbd->hid_out_ep, buf, mps_out); + USBD_LL_PrepareReceive(pdev, usbd->hid->out_ep, buf, mps_out); - usbd->HID_ClassData.state = HID_IDLE; + usbd->hid->state = HID_IDLE; } return 0; @@ -795,8 +791,8 @@ static uint8_t USBD_CDC_MSC_HID_DeInit(USBD_HandleTypeDef *pdev, uint8_t cfgidx) // HID component // close endpoints - USBD_LL_CloseEP(pdev, usbd->hid_in_ep); - USBD_LL_CloseEP(pdev, usbd->hid_out_ep); + USBD_LL_CloseEP(pdev, usbd->hid->in_ep); + USBD_LL_CloseEP(pdev, usbd->hid->out_ep); } return 0; @@ -832,7 +828,7 @@ static uint8_t USBD_CDC_MSC_HID_Setup(USBD_HandleTypeDef *pdev, USBD_SetupReqTyp recipient = USBD_MODE_CDC; } else if ((mode & USBD_MODE_MSC) && iface == MSC_IFACE_NUM_WITH_CDC) { recipient = USBD_MODE_MSC; - } else if ((mode & USBD_MODE_HID) && iface == usbd->hid_iface_num) { + } else if ((mode & USBD_MODE_HID) && iface == usbd->hid->iface_num) { recipient = USBD_MODE_HID; } break; @@ -843,7 +839,7 @@ static uint8_t USBD_CDC_MSC_HID_Setup(USBD_HandleTypeDef *pdev, USBD_SetupReqTyp recipient = USBD_MODE_CDC; } else if ((mode & USBD_MODE_MSC) && ep == MSC_OUT_EP) { recipient = USBD_MODE_MSC; - } else if ((mode & USBD_MODE_HID) && ep == usbd->hid_out_ep) { + } else if ((mode & USBD_MODE_HID) && ep == usbd->hid->out_ep) { recipient = USBD_MODE_HID; } break; @@ -905,19 +901,19 @@ static uint8_t USBD_CDC_MSC_HID_Setup(USBD_HandleTypeDef *pdev, USBD_SetupReqTyp } else if (recipient == USBD_MODE_HID) { switch (req->bRequest) { case HID_REQ_SET_PROTOCOL: - usbd->HID_ClassData.Protocol = (uint8_t)(req->wValue); + usbd->hid->ctl_protocol = (uint8_t)(req->wValue); break; case HID_REQ_GET_PROTOCOL: - USBD_CtlSendData(pdev, (uint8_t *)&usbd->HID_ClassData.Protocol, 1); + USBD_CtlSendData(pdev, &usbd->hid->ctl_protocol, 1); break; case HID_REQ_SET_IDLE: - usbd->HID_ClassData.IdleState = (uint8_t)(req->wValue >> 8); + usbd->hid->ctl_idle_state = (uint8_t)(req->wValue >> 8); break; case HID_REQ_GET_IDLE: - USBD_CtlSendData(pdev, (uint8_t *)&usbd->HID_ClassData.IdleState, 1); + USBD_CtlSendData(pdev, &usbd->hid->ctl_idle_state, 1); break; default: @@ -961,23 +957,23 @@ static uint8_t USBD_CDC_MSC_HID_Setup(USBD_HandleTypeDef *pdev, USBD_SetupReqTyp uint16_t len = 0; const uint8_t *pbuf = NULL; if (req->wValue >> 8 == HID_REPORT_DESC) { - len = usbd->hid_desc[HID_DESC_OFFSET_REPORT_DESC_LEN]; + len = usbd->hid->desc[HID_DESC_OFFSET_REPORT_DESC_LEN]; len = MIN(len, req->wLength); - pbuf = usbd->hid_report_desc; + pbuf = usbd->hid->report_desc; } else if (req->wValue >> 8 == HID_DESCRIPTOR_TYPE) { len = MIN(HID_SUBDESC_LEN, req->wLength); - pbuf = usbd->hid_desc + HID_DESC_OFFSET_SUBDESC; + pbuf = usbd->hid->desc + HID_DESC_OFFSET_SUBDESC; } USBD_CtlSendData(pdev, (uint8_t*)pbuf, len); break; } case USB_REQ_GET_INTERFACE: - USBD_CtlSendData(pdev, (uint8_t *)&usbd->HID_ClassData.AltSetting, 1); + USBD_CtlSendData(pdev, &usbd->hid->ctl_alt_setting, 1); break; case USB_REQ_SET_INTERFACE: - usbd->HID_ClassData.AltSetting = (uint8_t)(req->wValue); + usbd->hid->ctl_alt_setting = (uint8_t)(req->wValue); break; } } @@ -1009,10 +1005,10 @@ static uint8_t USBD_CDC_MSC_HID_DataIn(USBD_HandleTypeDef *pdev, uint8_t epnum) } else if ((usbd->usbd_mode & USBD_MODE_MSC) && epnum == (MSC_IN_EP & 0x7f)) { MSC_BOT_DataIn(pdev, epnum); return USBD_OK; - } else if ((usbd->usbd_mode & USBD_MODE_HID) && epnum == (usbd->hid_in_ep & 0x7f)) { + } else if ((usbd->usbd_mode & USBD_MODE_HID) && epnum == (usbd->hid->in_ep & 0x7f)) { /* Ensure that the FIFO is empty before a new transfer, this condition could be caused by a new transfer before the end of the previous transfer */ - usbd->HID_ClassData.state = HID_IDLE; + usbd->hid->state = HID_IDLE; return USBD_OK; } @@ -1033,7 +1029,7 @@ static uint8_t USBD_CDC_MSC_HID_DataOut(USBD_HandleTypeDef *pdev, uint8_t epnum) } else if ((usbd->usbd_mode & USBD_MODE_MSC) && epnum == (MSC_OUT_EP & 0x7f)) { MSC_BOT_DataOut(pdev, epnum); return USBD_OK; - } else if ((usbd->usbd_mode & USBD_MODE_HID) && epnum == (usbd->hid_out_ep & 0x7f)) { + } else if ((usbd->usbd_mode & USBD_MODE_HID) && epnum == (usbd->hid->out_ep & 0x7f)) { size_t len = USBD_LL_GetRxDataSize(pdev, epnum); usbd_hid_receive(usbd->hid, len); } @@ -1147,22 +1143,22 @@ uint8_t USBD_HID_ReceivePacket(usbd_cdc_msc_hid_state_t *usbd, uint8_t *buf) { // Prepare Out endpoint to receive next packet uint16_t mps_out = - usbd->hid_desc[HID_DESC_OFFSET_MAX_PACKET_OUT_LO] - | (usbd->hid_desc[HID_DESC_OFFSET_MAX_PACKET_OUT_HI] << 8); - USBD_LL_PrepareReceive(usbd->pdev, usbd->hid_out_ep, buf, mps_out); + usbd->hid->desc[HID_DESC_OFFSET_MAX_PACKET_OUT_LO] + | (usbd->hid->desc[HID_DESC_OFFSET_MAX_PACKET_OUT_HI] << 8); + USBD_LL_PrepareReceive(usbd->pdev, usbd->hid->out_ep, buf, mps_out); return USBD_OK; } int USBD_HID_CanSendReport(usbd_cdc_msc_hid_state_t *usbd) { - return usbd->pdev->dev_state == USBD_STATE_CONFIGURED && usbd->HID_ClassData.state == HID_IDLE; + return usbd->pdev->dev_state == USBD_STATE_CONFIGURED && usbd->hid->state == HID_IDLE; } uint8_t USBD_HID_SendReport(usbd_cdc_msc_hid_state_t *usbd, uint8_t *report, uint16_t len) { if (usbd->pdev->dev_state == USBD_STATE_CONFIGURED) { - if (usbd->HID_ClassData.state == HID_IDLE) { - usbd->HID_ClassData.state = HID_BUSY; - USBD_LL_Transmit(usbd->pdev, usbd->hid_in_ep, report, len); + if (usbd->hid->state == HID_IDLE) { + usbd->hid->state = HID_BUSY; + USBD_LL_Transmit(usbd->pdev, usbd->hid->in_ep, report, len); return USBD_OK; } }