From 3a5cd786dc0b4dbb8505e2cbc0e81863014af51e Mon Sep 17 00:00:00 2001 From: Conor Patrick Date: Tue, 21 May 2019 20:17:37 -0400 Subject: [PATCH] enumerates correctly --- targets/stm32l432/build/common.mk | 3 +- targets/stm32l432/lib/usbd/usbd_ccid.c | 334 ++++++++++++++++++++ targets/stm32l432/lib/usbd/usbd_ccid.h | 33 ++ targets/stm32l432/lib/usbd/usbd_composite.c | 23 +- targets/stm32l432/lib/usbd/usbd_composite.h | 2 +- targets/stm32l432/src/init.c | 6 +- 6 files changed, 392 insertions(+), 9 deletions(-) create mode 100644 targets/stm32l432/lib/usbd/usbd_ccid.c diff --git a/targets/stm32l432/build/common.mk b/targets/stm32l432/build/common.mk index 7c0ae32..f018bce 100644 --- a/targets/stm32l432/build/common.mk +++ b/targets/stm32l432/build/common.mk @@ -10,7 +10,8 @@ DRIVER_LIBS := lib/stm32l4xx_hal_pcd.c lib/stm32l4xx_hal_pcd_ex.c lib/stm32l4xx_ USB_LIB := lib/usbd/usbd_cdc.c lib/usbd/usbd_cdc_if.c lib/usbd/usbd_composite.c \ lib/usbd/usbd_conf.c lib/usbd/usbd_core.c lib/usbd/usbd_ioreq.c \ - lib/usbd/usbd_ctlreq.c lib/usbd/usbd_desc.c lib/usbd/usbd_hid.c + lib/usbd/usbd_ctlreq.c lib/usbd/usbd_desc.c lib/usbd/usbd_hid.c \ + lib/usbd/usbd_ccid.c VERSION:=$(shell git describe --abbrev=0 ) VERSION_FULL:=$(shell git describe) diff --git a/targets/stm32l432/lib/usbd/usbd_ccid.c b/targets/stm32l432/lib/usbd/usbd_ccid.c new file mode 100644 index 0000000..e202ffe --- /dev/null +++ b/targets/stm32l432/lib/usbd/usbd_ccid.c @@ -0,0 +1,334 @@ +#include +#include "usbd_ccid.h" +#include "usbd_ctlreq.h" +#include "usbd_conf.h" +#include "usbd_core.h" + +#include "log.h" + +static uint8_t USBD_CCID_Init (USBD_HandleTypeDef *pdev, + uint8_t cfgidx); + +static uint8_t USBD_CCID_DeInit (USBD_HandleTypeDef *pdev, + uint8_t cfgidx); + +static uint8_t USBD_CCID_Setup (USBD_HandleTypeDef *pdev, + USBD_SetupReqTypedef *req); + +static uint8_t USBD_CCID_DataIn (USBD_HandleTypeDef *pdev, + uint8_t epnum); + +static uint8_t USBD_CCID_DataOut (USBD_HandleTypeDef *pdev, + uint8_t epnum); + +static uint8_t USBD_CCID_EP0_RxReady (USBD_HandleTypeDef *pdev); + + +USBD_ClassTypeDef USBD_CCID = +{ + USBD_CCID_Init, + USBD_CCID_DeInit, + USBD_CCID_Setup, + NULL, /* EP0_TxSent, */ + USBD_CCID_EP0_RxReady, + USBD_CCID_DataIn, + USBD_CCID_DataOut, + NULL, + NULL, + NULL, + + NULL, + NULL, + NULL, + NULL, +}; + +static uint8_t ccidmsg_buf[CCID_DATA_PACKET_SIZE]; + +static uint8_t USBD_CCID_Init (USBD_HandleTypeDef *pdev, uint8_t cfgidx) +{ + uint8_t ret = 0U; + USBD_CCID_HandleTypeDef *hcdc; + + //Y + USBD_LL_OpenEP(pdev, CCID_IN_EP, USBD_EP_TYPE_BULK, + CCID_DATA_PACKET_SIZE); + + pdev->ep_in[CCID_IN_EP & 0xFU].is_used = 1U; + + USBD_LL_OpenEP(pdev, CCID_OUT_EP, USBD_EP_TYPE_BULK, + CCID_DATA_PACKET_SIZE); + + pdev->ep_out[CCID_OUT_EP & 0xFU].is_used = 1U; + + + USBD_LL_OpenEP(pdev, CCID_CMD_EP, USBD_EP_TYPE_INTR, CCID_DATA_PACKET_SIZE); + pdev->ep_in[CCID_CMD_EP & 0xFU].is_used = 1U; + + static USBD_CCID_HandleTypeDef mem; + pdev->pClassData = &mem; + + hcdc = (USBD_CCID_HandleTypeDef*) pdev->pClassData; + + // init transfer states + hcdc->TxState = 0U; + hcdc->RxState = 0U; + + USBD_LL_PrepareReceive(&Solo_USBD_Device, CCID_OUT_EP, ccidmsg_buf, + CCID_DATA_PACKET_SIZE); + + return ret; +} + +static uint8_t USBD_CCID_DeInit (USBD_HandleTypeDef *pdev, uint8_t cfgidx) +{ + uint8_t ret = 0U; + //N + + USBD_LL_CloseEP(pdev, CCID_IN_EP); + pdev->ep_in[CCID_IN_EP & 0xFU].is_used = 0U; + + USBD_LL_CloseEP(pdev, CCID_OUT_EP); + pdev->ep_out[CCID_OUT_EP & 0xFU].is_used = 0U; + + USBD_LL_CloseEP(pdev, CCID_CMD_EP); + pdev->ep_in[CCID_CMD_EP & 0xFU].is_used = 0U; + + /* DeInit physical Interface components */ + if(pdev->pClassData != NULL) + { + pdev->pClassData = NULL; + } + + return ret; +} + +/** + * @brief USBD_CDC_Setup + * Handle the CDC specific requests + * @param pdev: instance + * @param req: usb requests + * @retval status + */ +static uint8_t USBD_CCID_Setup (USBD_HandleTypeDef *pdev, + USBD_SetupReqTypedef *req) +{ + USBD_CCID_HandleTypeDef *hcdc = (USBD_CCID_HandleTypeDef*) pdev->pClassData; + uint8_t ifalt = 0U; + uint16_t status_info = 0U; + uint8_t ret = USBD_OK; + //N + + switch (req->bmRequest & USB_REQ_TYPE_MASK) + { + case USB_REQ_TYPE_CLASS : + if (req->wLength) + { + if (req->bmRequest & 0x80U) + { + USBD_CtlSendData (pdev, (uint8_t *)(void *)hcdc->data, req->wLength); + } + else + { + hcdc->CmdOpCode = req->bRequest; + hcdc->CmdLength = (uint8_t)req->wLength; + + USBD_CtlPrepareRx (pdev, (uint8_t *)(void *)hcdc->data, req->wLength); + } + } + else + { + + } + break; + + case USB_REQ_TYPE_STANDARD: + switch (req->bRequest) + { + case USB_REQ_GET_STATUS: + if (pdev->dev_state == USBD_STATE_CONFIGURED) + { + USBD_CtlSendData (pdev, (uint8_t *)(void *)&status_info, 2U); + } + else + { + USBD_CtlError (pdev, req); + ret = USBD_FAIL; + } + break; + + case USB_REQ_GET_INTERFACE: + if (pdev->dev_state == USBD_STATE_CONFIGURED) + { + USBD_CtlSendData (pdev, &ifalt, 1U); + } + else + { + USBD_CtlError (pdev, req); + ret = USBD_FAIL; + } + break; + + case USB_REQ_SET_INTERFACE: + if (pdev->dev_state != USBD_STATE_CONFIGURED) + { + USBD_CtlError (pdev, req); + ret = USBD_FAIL; + } + break; + case USB_REQ_GET_DESCRIPTOR: + break; + default: + USBD_CtlError (pdev, req); + ret = USBD_FAIL; + break; + } + break; + + default: + USBD_CtlError (pdev, req); + ret = USBD_FAIL; + break; + } + + return ret; +} + + +/** + * @brief USBD_CDC_DataIn + * Data sent on non-control IN endpoint + * @param pdev: device instance + * @param epnum: endpoint number + * @retval status + */ +static uint8_t USBD_CCID_DataIn (USBD_HandleTypeDef *pdev, uint8_t epnum) +{ + //N + USBD_CCID_HandleTypeDef *hcdc = (USBD_CCID_HandleTypeDef*)pdev->pClassData; + PCD_HandleTypeDef *hpcd = pdev->pData; + + if(pdev->pClassData != NULL) + { + if((pdev->ep_in[epnum].total_length > 0U) && ((pdev->ep_in[epnum].total_length % hpcd->IN_ep[epnum].maxpacket) == 0U)) + { + /* Update the packet total length */ + pdev->ep_in[epnum].total_length = 0U; + + /* Send ZLP */ + USBD_LL_Transmit (pdev, epnum, NULL, 0U); + } + else + { + hcdc->TxState = 0U; + } + return USBD_OK; + } + else + { + return USBD_FAIL; + } +} + +uint8_t USBD_CCID_TransmitPacket(uint8_t * msg, int len) +{ + /* Update the packet total length */ + Solo_USBD_Device.ep_in[CCID_IN_EP & 0xFU].total_length = len; + + /* Transmit next packet */ + USBD_LL_Transmit(&Solo_USBD_Device, CCID_IN_EP, msg, + len); + + return USBD_OK; +} + +#define CCID_HEADER_SIZE 10 +typedef struct +{ + uint8_t type; + uint32_t len; + uint8_t slot; + uint8_t seq; + uint8_t rsvd; + uint16_t param; +} __attribute__((packed)) CCID_HEADER; + +void ccid_send_status(CCID_HEADER * c) +{ + uint8_t msg[CCID_HEADER_SIZE]; + memset(msg,0,sizeof(msg)); + + msg[0] = CCID_SLOT_STATUS_RES; + msg[6] = c->seq; + + USBD_CCID_TransmitPacket(msg, sizeof(msg)); + +} + + + + +void handle_ccid(uint8_t * msg, int len) +{ + CCID_HEADER * h = (CCID_HEADER *) msg; + switch(h->type) + { + case CCID_SLOT_STATUS: + ccid_send_status(h); + break; + default: + break; + } +} + +/** + * @brief USBD_CDC_DataOut + * Data received on non-control Out endpoint + * @param pdev: device instance + * @param epnum: endpoint number + * @retval status + */ +static uint8_t USBD_CCID_DataOut (USBD_HandleTypeDef *pdev, uint8_t epnum) +{ + while(1) + { + led_rgb(0xff3520); + } + USBD_CCID_HandleTypeDef *hcdc = (USBD_CCID_HandleTypeDef*) pdev->pClassData; + + /* Get the received data length */ + hcdc->RxLength = USBD_LL_GetRxDataSize (pdev, epnum); + + /* USB data will be immediately processed, this allow next USB traffic being + NAKed till the end of the application Xfer */ + if(pdev->pClassData != NULL) + { + // printf1(TAG_GREEN,"ccid>> "); + // dump_hex1(TAG_GREEN, hcdc->RxBuffer, hcdc->RxLength); + + handle_ccid(hcdc->RxBuffer, hcdc->RxLength); + + return USBD_OK; + } + else + { + return USBD_FAIL; + } +} + +/** + * @brief USBD_CDC_EP0_RxReady + * Handle EP0 Rx Ready event + * @param pdev: device instance + * @retval status + */ +static uint8_t USBD_CCID_EP0_RxReady (USBD_HandleTypeDef *pdev) +{ + USBD_CCID_HandleTypeDef *hcdc = (USBD_CCID_HandleTypeDef*) pdev->pClassData; + + if((pdev->pUserData != NULL) && (hcdc->CmdOpCode != 0xFFU)) + { + hcdc->CmdOpCode = 0xFFU; + } + return USBD_OK; +} diff --git a/targets/stm32l432/lib/usbd/usbd_ccid.h b/targets/stm32l432/lib/usbd/usbd_ccid.h index ce38be1..cecf170 100644 --- a/targets/stm32l432/lib/usbd/usbd_ccid.h +++ b/targets/stm32l432/lib/usbd/usbd_ccid.h @@ -1,8 +1,41 @@ #ifndef _USBD_H_ #define _USBD_H_ +#include "usbd_ioreq.h" + #define CCID_IN_EP 0x84U /* EP1 for data IN */ #define CCID_OUT_EP 0x04U /* EP1 for data OUT */ #define CCID_CMD_EP 0x85U /* EP2 for CDC commands */ +#define CCID_DATA_PACKET_SIZE 64 + +#define CCID_SET_PARAMS 0x61 +#define CCID_POWER_ON 0x62 +#define CCID_POWER_OFF 0x63 +#define CCID_SLOT_STATUS 0x65 +#define CCID_SECURE 0x69 +#define CCID_GET_PARAMS 0x6C +#define CCID_RESET_PARAMS 0x6D +#define CCID_XFR_BLOCK 0x6F +#define CCID_DATA_BLOCK_RES 0x80 +#define CCID_SLOT_STATUS_RES 0x81 +#define CCID_PARAMS_RES 0x82 + +extern USBD_ClassTypeDef USBD_CCID; + +typedef struct +{ + uint32_t data[CCID_DATA_PACKET_SIZE / 4U]; + uint8_t CmdOpCode; + uint8_t CmdLength; + uint8_t *RxBuffer; + uint8_t *TxBuffer; + uint32_t RxLength; + uint32_t TxLength; + + __IO uint32_t TxState; + __IO uint32_t RxState; +} +USBD_CCID_HandleTypeDef; + #endif diff --git a/targets/stm32l432/lib/usbd/usbd_composite.c b/targets/stm32l432/lib/usbd/usbd_composite.c index cf820d2..a70db6a 100644 --- a/targets/stm32l432/lib/usbd/usbd_composite.c +++ b/targets/stm32l432/lib/usbd/usbd_composite.c @@ -39,6 +39,7 @@ static uint8_t *USBD_Composite_GetDeviceQualifierDescriptor (uint16_t *length); #define HID_INTF_NUM 0 #define CDC_INTF_NUM 1 +#define CCID_INTF_NUM 2 __ALIGN_BEGIN uint8_t COMPOSITE_CDC_HID_DESCRIPTOR[COMPOSITE_CDC_HID_DESCRIPTOR_SIZE] __ALIGN_END = { /*Configuration Descriptor*/ @@ -176,7 +177,7 @@ __ALIGN_BEGIN uint8_t COMPOSITE_CDC_HID_DESCRIPTOR[COMPOSITE_CDC_HID_DESCRIPTOR_ /* CCID Interface Descriptor */ 9, /* bLength: Interface Descriptor size */ USB_DESC_TYPE_INTERFACE, /* bDescriptorType: Interface */ -0, /* bInterfaceNumber: CCID Interface */ +CCID_INTF_NUM, /* bInterfaceNumber: CCID Interface */ 0, /* Alternate setting for this interface */ 3, /* bNumEndpoints: Bulk-IN, Bulk-OUT, Intr-IN */ 0x0B, /* CCID class */ @@ -273,19 +274,26 @@ int in_endpoint_to_class[MAX_ENDPOINTS]; int out_endpoint_to_class[MAX_ENDPOINTS]; -void USBD_Composite_Set_Classes(USBD_ClassTypeDef *class0, USBD_ClassTypeDef *class1) { +void USBD_Composite_Set_Classes(USBD_ClassTypeDef *class0, USBD_ClassTypeDef *class1, USBD_ClassTypeDef *class2) +{ + //Y USBD_Classes[0] = class0; USBD_Classes[1] = class1; + USBD_Classes[2] = class2; + //Y } static uint8_t USBD_Composite_Init (USBD_HandleTypeDef *pdev, uint8_t cfgidx) { int i; + + //N + for(i = 0; i < NUM_INTERFACES; i++) { if (USBD_Classes[i]->Init(pdev, cfgidx) != USBD_OK) { return USBD_FAIL; } } - + //N return USBD_OK; } @@ -302,6 +310,7 @@ static uint8_t USBD_Composite_DeInit (USBD_HandleTypeDef *pdev, uint8_t cfgidx) static uint8_t USBD_Composite_Setup (USBD_HandleTypeDef *pdev, USBD_SetupReqTypedef *req) { int i; + //N switch (req->bmRequest & USB_REQ_TYPE_MASK) { case USB_REQ_TYPE_CLASS : if (req->wIndex < NUM_INTERFACES) @@ -363,16 +372,19 @@ static uint8_t USBD_Composite_EP0_RxReady (USBD_HandleTypeDef *pdev) { } static uint8_t *USBD_Composite_GetFSCfgDesc (uint16_t *length) { + //Y *length = COMPOSITE_CDC_HID_DESCRIPTOR_SIZE; return COMPOSITE_CDC_HID_DESCRIPTOR; } static uint8_t *USBD_Composite_GetHSCfgDesc (uint16_t *length) { + //N *length = COMPOSITE_CDC_HID_DESCRIPTOR_SIZE; return COMPOSITE_CDC_HID_DESCRIPTOR; } static uint8_t *USBD_Composite_GetOtherSpeedCfgDesc (uint16_t *length) { + *length = COMPOSITE_CDC_HID_DESCRIPTOR_SIZE; return COMPOSITE_CDC_HID_DESCRIPTOR; } @@ -393,6 +405,7 @@ __ALIGN_BEGIN static uint8_t USBD_Composite_DeviceQualifierDesc[USB_LEN_DEV_QUAL }; uint8_t *USBD_Composite_GetDeviceQualifierDescriptor (uint16_t *length) { - *length = sizeof (USBD_Composite_DeviceQualifierDesc); - return USBD_Composite_DeviceQualifierDesc; + //N + *length = sizeof (USBD_Composite_DeviceQualifierDesc); + return USBD_Composite_DeviceQualifierDesc; } diff --git a/targets/stm32l432/lib/usbd/usbd_composite.h b/targets/stm32l432/lib/usbd/usbd_composite.h index 7599b39..0fdc513 100644 --- a/targets/stm32l432/lib/usbd/usbd_composite.h +++ b/targets/stm32l432/lib/usbd/usbd_composite.h @@ -17,7 +17,7 @@ extern int in_endpoint_to_class[MAX_ENDPOINTS]; extern int out_endpoint_to_class[MAX_ENDPOINTS]; -void USBD_Composite_Set_Classes(USBD_ClassTypeDef *class0, USBD_ClassTypeDef *class1); +void USBD_Composite_Set_Classes(USBD_ClassTypeDef *class0, USBD_ClassTypeDef *class1, USBD_ClassTypeDef *class2); #ifdef __cplusplus } diff --git a/targets/stm32l432/src/init.c b/targets/stm32l432/src/init.c index e7fa953..93ca071 100644 --- a/targets/stm32l432/src/init.c +++ b/targets/stm32l432/src/init.c @@ -27,6 +27,7 @@ #include "usbd_desc.h" #include "usbd_hid.h" #include "usbd_cdc.h" +#include "usbd_ccid.h" #include "usbd_composite.h" #include "usbd_cdc_if.h" #include "device.h" @@ -706,7 +707,7 @@ void init_usb() SET_BIT(RCC->APB1ENR1, RCC_APB1ENR1_USBFSEN); #if DEBUG_LEVEL > 0 - USBD_Composite_Set_Classes(&USBD_HID, &USBD_CDC); + USBD_Composite_Set_Classes(&USBD_HID, &USBD_CDC, &USBD_CCID); in_endpoint_to_class[HID_EPIN_ADDR & 0x7F] = 0; out_endpoint_to_class[HID_EPOUT_ADDR & 0x7F] = 0; @@ -723,8 +724,9 @@ void init_usb() USBD_Init(&Solo_USBD_Device, &Solo_Desc, 0); USBD_RegisterClass(&Solo_USBD_Device, &USBD_HID); #endif - + //Y USBD_Start(&Solo_USBD_Device); + //Y } void init_pwm(void)