#define USBD_VID 1155 #define USBD_LANGID_STRING 1033 #define USBD_MANUFACTURER_STRING "STMicroelectronics" #define USBD_PID_FS 22336 #define USBD_PRODUCT_STRING_FS "STM32 Virtual ComPort" #define USBD_SERIALNUMBER_STRING_FS "00000000001A" #define USBD_CONFIGURATION_STRING_FS "CDC Config" #define USBD_INTERFACE_STRING_FS "CDC Interface" #define USBD_MAX_NUM_CONFIGURATION 1 /* USB Standard Device Descriptor */ __ALIGN_BEGIN uint8_t USBD_FS_DeviceDesc[USB_LEN_DEV_DESC] __ALIGN_END = { 0x12, /*bLength */ USB_DESC_TYPE_DEVICE, /*bDescriptorType*/ 0x00, /* bcdUSB */ 0x02, 0x02, /*bDeviceClass*/ 0x02, /*bDeviceSubClass*/ 0x00, /*bDeviceProtocol*/ USB_MAX_EP0_SIZE, /*bMaxPacketSize*/ LOBYTE(USBD_VID), /*idVendor*/ HIBYTE(USBD_VID), /*idVendor*/ LOBYTE(USBD_PID_FS), /*idVendor*/ HIBYTE(USBD_PID_FS), /*idVendor*/ 0x00, /*bcdDevice rel. 2.00*/ 0x02, USBD_IDX_MFC_STR, /*Index of manufacturer string*/ USBD_IDX_PRODUCT_STR, /*Index of product string*/ USBD_IDX_SERIAL_STR, /*Index of serial number string*/ USBD_MAX_NUM_CONFIGURATION /*bNumConfigurations*/ } ; /* USB_DeviceDescriptor */
__ALIGN_BEGIN const uint8_t USBD_CDC_CfgHSDesc[USB_CDC_CONFIG_DESC_SIZ] __ALIGN_END = { /*Configuration Descriptor*/ 0x09, /* bLength: Configuration Descriptor size */ USB_DESC_TYPE_CONFIGURATION, /* bDescriptorType: Configuration */ USB_CDC_CONFIG_DESC_SIZ, /* wTotalLength:no of returned bytes */ 0x00, 0x02, /* bNumInterfaces: 2 interface */ 0x01, /* bConfigurationValue: Configuration value */ 0x00, /* iConfiguration: Index of string descriptor describing the configuration */ 0xC0, /* bmAttributes: self powered */ 0x32, /* MaxPower 100 mA */
/*Interface Descriptor */ 0x09, /* bLength: Interface Descriptor size */ USB_DESC_TYPE_INTERFACE, /* bDescriptorType: Interface */ /* Interface descriptor type */ 0x00, /* bInterfaceNumber: Number of Interface */ 0x00, /* bAlternateSetting: Alternate setting */ 0x01, /* bNumEndpoints: One endpoints used */ 0x02, /* bInterfaceClass: Communication Interface Class */ 0x02, /* bInterfaceSubClass: Abstract Control Model */ 0x01, /* bInterfaceProtocol: Common AT commands */ 0x00, /* iInterface: */
/*Header Functional Descriptor*/ 0x05, /* bLength: Endpoint Descriptor size */ 0x24, /* bDescriptorType: CS_INTERFACE */ 0x00, /* bDescriptorSubtype: Header Func Desc */ 0x10, /* bcdCDC: spec release number */ 0x01, /*Call Management Functional Descriptor*/ 0x05, /* bFunctionLength */ 0x24, /* bDescriptorType: CS_INTERFACE */ 0x01, /* bDescriptorSubtype: Call Management Func Desc */ 0x00, /* bmCapabilities: D0+D1 */ 0x01, /* bDataInterface: 1 */ /*ACM Functional Descriptor*/ 0x04, /* bFunctionLength */ 0x24, /* bDescriptorType: CS_INTERFACE */ 0x02, /* bDescriptorSubtype: Abstract Control Management desc */ 0x02, /* bmCapabilities */ /*Union Functional Descriptor*/ 0x05, /* bFunctionLength */ 0x24, /* bDescriptorType: CS_INTERFACE */ 0x06, /* bDescriptorSubtype: Union func desc */ 0x00, /* bMasterInterface: Communication class interface */ 0x01, /* bSlaveInterface0: Data Class Interface */
/*Endpoint 2 Descriptor*/ 0x07, /* bLength: Endpoint Descriptor size */ USB_DESC_TYPE_ENDPOINT, /* bDescriptorType: Endpoint */ CDC_CMD_EP, /* bEndpointAddress */ 0x03, /* bmAttributes: Interrupt */ LOBYTE(CDC_CMD_PACKET_SIZE), /* wMaxPacketSize: */ HIBYTE(CDC_CMD_PACKET_SIZE), 0x10, /* bInterval: */
/*Data class interface descriptor*/ 0x09, /* bLength: Endpoint Descriptor size */ USB_DESC_TYPE_INTERFACE, /* bDescriptorType: */ 0x01, /* bInterfaceNumber: Number of Interface */ 0x00, /* bAlternateSetting: Alternate setting */ 0x02, /* bNumEndpoints: Two endpoints used */ 0x0A, /* bInterfaceClass: CDC */ 0x00, /* bInterfaceSubClass: */ 0x00, /* bInterfaceProtocol: */ 0x00, /* iInterface: */ /*Endpoint OUT Descriptor*/ 0x07, /* bLength: Endpoint Descriptor size */ USB_DESC_TYPE_ENDPOINT, /* bDescriptorType: Endpoint */ CDC_OUT_EP, /* bEndpointAddress */ 0x02, /* bmAttributes: Bulk */ LOBYTE(CDC_DATA_HS_MAX_PACKET_SIZE), /* wMaxPacketSize: */ HIBYTE(CDC_DATA_HS_MAX_PACKET_SIZE), 0x00, /* bInterval: ignore for Bulk transfer */ /*Endpoint IN Descriptor*/ 0x07, /* bLength: Endpoint Descriptor size */ USB_DESC_TYPE_ENDPOINT, /* bDescriptorType: Endpoint */ CDC_IN_EP, /* bEndpointAddress */ 0x02, /* bmAttributes: Bulk */ LOBYTE(CDC_DATA_HS_MAX_PACKET_SIZE), /* wMaxPacketSize: */ HIBYTE(CDC_DATA_HS_MAX_PACKET_SIZE), 0x00 /* bInterval: ignore for Bulk transfer */
/** * @brief Initializes the Low Level portion of the Device driver. * @param pdev: Device handle * @retval USBD Status */ USBD_StatusTypeDef USBD_LL_Init (USBD_HandleTypeDef *pdev) { /* Init USB_IP */ /* Link The driver to the stack */ hpcd_USB_FS.pData = pdev; pdev->pData = &hpcd_USB_FS; hpcd_USB_FS.Instance = USB; hpcd_USB_FS.Init.dev_endpoints = 8; hpcd_USB_FS.Init.speed = PCD_SPEED_FULL; hpcd_USB_FS.Init.ep0_mps = DEP0CTL_MPS_8; hpcd_USB_FS.Init.low_power_enable = DISABLE; hpcd_USB_FS.Init.lpm_enable = DISABLE; hpcd_USB_FS.Init.battery_charging_enable = DISABLE; if (HAL_PCD_Init(&hpcd_USB_FS) != HAL_OK) { Error_Handler(); } HAL_PCDEx_PMAConfig((PCD_HandleTypeDef*)pdev->pData , 0x00 , PCD_SNG_BUF, 0x18); HAL_PCDEx_PMAConfig((PCD_HandleTypeDef*)pdev->pData , 0x80 , PCD_SNG_BUF, 0x58); HAL_PCDEx_PMAConfig((PCD_HandleTypeDef*)pdev->pData , 0x81 , PCD_SNG_BUF, 0xC0); HAL_PCDEx_PMAConfig((PCD_HandleTypeDef*)pdev->pData , 0x01 , PCD_SNG_BUF, 0x110); HAL_PCDEx_PMAConfig((PCD_HandleTypeDef*)pdev->pData , 0x82 , PCD_SNG_BUF, 0x100); return USBD_OK; }
/** * @brief CDC_Transmit_FS * Data send over USB IN endpoint are sent over CDC interface * through this function. * @note * * * @param Buf: Buffer of data to be send * @param Len: Number of data to be send (in bytes) * @retval Result of the operation: USBD_OK if all operations are OK else USBD_FAIL or USBD_BUSY */ uint8_t CDC_Transmit_FS(uint8_t* Buf, uint16_t Len) { uint8_t result = USBD_OK; USBD_CDC_HandleTypeDef *hcdc = (USBD_CDC_HandleTypeDef*)hUsbDeviceFS.pClassData; if (hcdc->TxState != 0){ return USBD_BUSY; } USBD_CDC_SetTxBuffer(&hUsbDeviceFS, Buf, Len); result = USBD_CDC_TransmitPacket(&hUsbDeviceFS); return result; }
/** * @brief CDC_Receive_FS * Data received over USB OUT endpoint are sent over CDC interface * through this function. * * @note * This function will block any OUT packet reception on USB endpoint * untill exiting this function. If you exit this function before transfer * is complete on CDC interface (ie. using DMA controller) it will result * in receiving more data while previous ones are still not sent. * * @param Buf: Buffer of data to be received * @param Len: Number of data received (in bytes) * @retval Result of the operation: USBD_OK if all operations are OK else USBD_FAIL */ static int8_t CDC_Receive_FS (uint8_t* Buf, uint32_t *Len) { uint16_t len = *Len; CDCDataReceivedCallback(Buf, len); // Prepare for next reception USBD_CDC_ReceivePacket(&hUsbDeviceFS); return (USBD_OK); }
USBD_Init(&hUsbDeviceFS, &FS_Desc, DEVICE_FS); USBD_RegisterClass(&hUsbDeviceFS, &USBD_CDC); USBD_CDC_RegisterInterface(&hUsbDeviceFS, &USBD_Interface_fops_FS); USBD_Start(&hUsbDeviceFS);
* USB Standard Device Descriptor */ __ALIGN_BEGIN uint8_t USBD_FS_DeviceDesc[USB_LEN_DEV_DESC] __ALIGN_END = { 0x12, /*bLength */ USB_DESC_TYPE_DEVICE, /*bDescriptorType*/ 0x00, /* bcdUSB */ 0x02, 0x00, /*bDeviceClass*/ 0x00, /*bDeviceSubClass*/ 0x00, /*bDeviceProtocol*/ USB_MAX_EP0_SIZE, /*bMaxPacketSize*/ LOBYTE(USBD_VID), /*idVendor*/ HIBYTE(USBD_VID), /*idVendor*/ LOBYTE(USBD_PID_FS), /*idVendor*/ HIBYTE(USBD_PID_FS), /*idVendor*/ 0x00, /*bcdDevice rel. 2.00*/ 0x02, USBD_IDX_MFC_STR, /*Index of manufacturer string*/ USBD_IDX_PRODUCT_STR, /*Index of product string*/ USBD_IDX_SERIAL_STR, /*Index of serial number string*/ USBD_MAX_NUM_CONFIGURATION /*bNumConfigurations*/ } ; /* USB_DeviceDescriptor */
0x09, /* bLength: Configuation Descriptor size */ USB_DESC_TYPE_CONFIGURATION, /* bDescriptorType: Configuration */ USB_MSC_CONFIG_DESC_SIZ, 0x00, 0x01, /* bNumInterfaces: 1 interface */ 0x01, /* bConfigurationValue: */ 0x04, /* iConfiguration: */ 0xC0, /* bmAttributes: */ 0x32, /* MaxPower 100 mA */
0x09, /* bLength: Interface Descriptor size */ 0x04, /* bDescriptorType: */ 0x00, /* bInterfaceNumber: Number of Interface */ 0x00, /* bAlternateSetting: Alternate setting */ 0x02, /* bNumEndpoints*/ 0x08, /* bInterfaceClass: MSC Class */ 0x06, /* bInterfaceSubClass : SCSI transparent*/ 0x50, /* nInterfaceProtocol */ 0x05, /* iInterface: */
0x07, /*Endpoint descriptor length = 7*/ 0x05, /*Endpoint descriptor type */ MSC_EPIN_ADDR, /*Endpoint address (IN, address 1) */ 0x02, /*Bulk endpoint type */ LOBYTE(MSC_MAX_FS_PACKET), HIBYTE(MSC_MAX_FS_PACKET), 0x00, /*Polling interval in milliseconds */ 0x07, /*Endpoint descriptor length = 7 */ 0x05, /*Endpoint descriptor type */ MSC_EPOUT_ADDR, /*Endpoint address (OUT, address 1) */ 0x02, /*Bulk endpoint type */ LOBYTE(MSC_MAX_FS_PACKET), HIBYTE(MSC_MAX_FS_PACKET), 0x00 /*Polling interval in milliseconds*/
HAL_PCDEx_PMAConfig((PCD_HandleTypeDef*)pdev->pData , 0x00 , PCD_SNG_BUF, 0x18); HAL_PCDEx_PMAConfig((PCD_HandleTypeDef*)pdev->pData , 0x80 , PCD_SNG_BUF, 0x58); HAL_PCDEx_PMAConfig((PCD_HandleTypeDef*)pdev->pData , 0x81 , PCD_SNG_BUF, 0x98); HAL_PCDEx_PMAConfig((PCD_HandleTypeDef*)pdev->pData , 0x01 , PCD_SNG_BUF, 0xD8);
/** @defgroup USB_CORE_Exported_Types * @{ */ typedef struct _USBD_STORAGE { int8_t (* Init) (uint8_t lun); int8_t (* GetCapacity) (uint8_t lun, uint32_t *block_num, uint16_t *block_size); int8_t (* IsReady) (uint8_t lun); int8_t (* IsWriteProtected) (uint8_t lun); int8_t (* Read) (uint8_t lun, uint8_t *buf, uint32_t blk_addr, uint16_t blk_len); int8_t (* Write)(uint8_t lun, uint8_t *buf, uint32_t blk_addr, uint16_t blk_len); int8_t (* GetMaxLun)(void); int8_t *pInquiry; }USBD_StorageTypeDef;
int8_t SD_MSC_Init (uint8_t lun) { (void)lun; // Not used // if(!initSD()) // return USBD_FAIL; return (USBD_OK); }
SdFatSPIDriver spiDriver; SdSpiCard card; bool initSD() { return card.begin(&spiDriver, PA4, SPI_FULL_SPEED); }
int8_t SD_MSC_GetCapacity (uint8_t lun, uint32_t *block_num, uint16_t *block_size) { (void)lun; // Not used *block_num = card.cardSize(); *block_size = 512; return (USBD_OK); }
int8_t SD_MSC_Read (uint8_t lun, uint8_t *buf, uint32_t blk_addr, uint16_t blk_len) { (void)lun; // Not used if(!card.readBlocks(blk_addr, buf, blk_len)) return USBD_FAIL; return (USBD_OK); } int8_t SD_MSC_Write (uint8_t lun, uint8_t *buf, uint32_t blk_addr, uint16_t blk_len) { (void)lun; // Not used if(!card.writeBlocks(blk_addr, buf, blk_len)) return USBD_FAIL; return (USBD_OK); }
int8_t SD_MSC_IsReady (uint8_t lun) { (void)lun; // Not used return (USBD_OK); } int8_t SD_MSC_IsWriteProtected (uint8_t lun) { (void)lun; // Not used return (USBD_OK); // Never write protected }
int8_t SD_MSC_GetMaxLun (void) { return 0; // We have just 1 Logic unit number (LUN) which is zero }
const uint8_t SD_MSC_Inquirydata[] = {/* 36 */ /* LUN 0 */ 0x00, 0x80, 0x02, 0x02, (STANDARD_INQUIRY_DATA_LEN - 5), 0x00, 0x00, 0x00, 'S', 'T', 'M', ' ', ' ', ' ', ' ', ' ', /* Manufacturer : 8 bytes */ 'P', 'r', 'o', 'd', 'u', 'c', 't', ' ', /* Product : 16 Bytes */ ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', '0', '.', '0' ,'1' /* Version : 4 Bytes */ };
USBD_StatusTypeDef res = USBD_Init(&hUsbDeviceFS, &FS_Desc, DEVICE_FS); USBD_RegisterClass(&hUsbDeviceFS, &USBD_MSC); USBD_MSC_RegisterStorage(&hUsbDeviceFS, &SdMscDriver); USBD_Start(&hUsbDeviceFS);
#define MSC_INTERFACE_IDX 0x0 // Index of MSC interface #define CDC_INTERFACE_IDX 0x1 // Index of CDC interface // endpoints numbers // endpoints numbers #define MSC_EP_IDX 0x01 #define CDC_CMD_EP_IDX 0x02 #define CDC_EP_IDX 0x03 #define IN_EP_DIR 0x80 // Adds a direction bit #define MSC_OUT_EP MSC_EP_IDX /* EP1 for BULK OUT */ #define MSC_IN_EP MSC_EP_IDX | IN_EP_DIR /* EP1 for BULK IN */ #define CDC_CMD_EP CDC_CMD_EP_IDX| IN_EP_DIR /* EP2 for CDC commands */ #define CDC_OUT_EP CDC_EP_IDX /* EP3 for data OUT */ #define CDC_IN_EP CDC_EP_IDX | IN_EP_DIR /* EP3 for data IN */
IMPORTANT! USB , , . , USB .
#define USBD_VID 0x0483 #define USBD_PID 0x5741 #define USBD_LANGID_STRING 0x409 #define USBD_MANUFACTURER_STRING "STMicroelectronics" #define USBD_PRODUCT_FS_STRING "Composite MSC CDC" #define USBD_SERIALNUMBER_FS_STRING "00000000055C" #define USBD_CONFIGURATION_FS_STRING "Config Name" #define USBD_INTERFACE_FS_STRING "Interface Name"
__ALIGN_BEGIN const uint8_t USBD_FS_DeviceDesc[USB_LEN_DEV_DESC] __ALIGN_END = { 0x12, /*bLength */ USB_DESC_TYPE_DEVICE, /*bDescriptorType*/ 0x00, /*bcdUSB */ 0x02, 0xEF, /*bDeviceClass*/ 0x02, /*bDeviceSubClass*/ 0x01, /*bDeviceProtocol*/ USB_MAX_EP0_SIZE, /*bMaxPacketSize*/ LOBYTE(USBD_VID), /*idVendor*/ HIBYTE(USBD_VID), /*idVendor*/ LOBYTE(USBD_PID), /*idVendor*/ HIBYTE(USBD_PID), /*idVendor*/ 0x00, /*bcdDevice rel. 2.00*/ 0x02, USBD_IDX_MFC_STR, /*Index of manufacturer string*/ USBD_IDX_PRODUCT_STR, /*Index of product string*/ USBD_IDX_SERIAL_STR, /*Index of serial number string*/ USBD_MAX_NUM_CONFIGURATION /*bNumConfigurations*/ };
#define USB_MSC_CDC_CONFIG_DESC_SIZ 98 /* USB MSC+CDC device Configuration Descriptor */ static const uint8_t USBD_MSC_CDC_CfgDesc[USB_MSC_CDC_CONFIG_DESC_SIZ] = { 0x09, /* bLength: Configuation Descriptor size */ USB_DESC_TYPE_CONFIGURATION, /* bDescriptorType: Configuration */ USB_MSC_CDC_CONFIG_DESC_SIZ, /* wTotalLength: Bytes returned */ 0x00, 0x03, /*bNumInterfaces: 3 interface*/ 0x01, /*bConfigurationValue: Configuration value*/ 0x02, /*iConfiguration: Index of string descriptor describing the configuration*/ 0xC0, /*bmAttributes: bus powered and Supports Remote Wakeup */ 0x32, /*MaxPower 100 mA: this current is used for detecting Vbus*/ /* 09 bytes */
/******************** Mass Storage interface ********************/ 0x09, /* bLength: Interface Descriptor size */ 0x04, /* bDescriptorType: */ MSC_INTERFACE_IDX, /* bInterfaceNumber: Number of Interface */ 0x00, /* bAlternateSetting: Alternate setting */ 0x02, /* bNumEndpoints*/ 0x08, /* bInterfaceClass: MSC Class */ 0x06, /* bInterfaceSubClass : SCSI transparent command set*/ 0x50, /* nInterfaceProtocol */ USBD_IDX_INTERFACE_STR, /* iInterface: */ /* 09 bytes */ /******************** Mass Storage Endpoints ********************/ 0x07, /*Endpoint descriptor length = 7*/ 0x05, /*Endpoint descriptor type */ MSC_IN_EP, /*Endpoint address (IN, address 1) */ 0x02, /*Bulk endpoint type */ LOBYTE(USB_MAX_PACKET_SIZE), HIBYTE(USB_MAX_PACKET_SIZE), 0x00, /*Polling interval in milliseconds */ /* 07 bytes */ 0x07, /*Endpoint descriptor length = 7 */ 0x05, /*Endpoint descriptor type */ MSC_OUT_EP, /*Endpoint address (OUT, address 1) */ 0x02, /*Bulk endpoint type */ LOBYTE(USB_MAX_PACKET_SIZE), HIBYTE(USB_MAX_PACKET_SIZE), 0x00, /*Polling interval in milliseconds*/ /* 07 bytes */
/******** IAD should be positioned just before the CDC interfaces ****** IAD to associate the two CDC interfaces */ 0x08, /* bLength */ 0x0B, /* bDescriptorType */ CDC_INTERFACE_IDX, /* bFirstInterface */ 0x02, /* bInterfaceCount */ 0x02, /* bFunctionClass */ 0x02, /* bFunctionSubClass */ 0x01, /* bFunctionProtocol */ 0x00, /* iFunction (Index of string descriptor describing this function) */ /* 08 bytes */
/******************** CDC interfaces ********************/ /*Interface Descriptor */ 0x09, /* bLength: Interface Descriptor size */ USB_DESC_TYPE_INTERFACE, /* bDescriptorType: Interface */ /* Interface descriptor type */ CDC_INTERFACE_IDX, /* bInterfaceNumber: Number of Interface */ 0x00, /* bAlternateSetting: Alternate setting */ 0x01, /* bNumEndpoints: One endpoints used */ 0x02, /* bInterfaceClass: Communication Interface Class */ 0x02, /* bInterfaceSubClass: Abstract Control Model */ 0x01, /* bInterfaceProtocol: Common AT commands */ 0x01, /* iInterface: */ /* 09 bytes */ /*Header Functional Descriptor*/ 0x05, /* bLength: Endpoint Descriptor size */ 0x24, /* bDescriptorType: CS_INTERFACE */ 0x00, /* bDescriptorSubtype: Header Func Desc */ 0x10, /* bcdCDC: spec release number */ 0x01, /* 05 bytes */ /*Call Management Functional Descriptor*/ 0x05, /* bFunctionLength */ 0x24, /* bDescriptorType: CS_INTERFACE */ 0x01, /* bDescriptorSubtype: Call Management Func Desc */ 0x00, /* bmCapabilities: D0+D1 */ CDC_INTERFACE_IDX + 1, /* bDataInterface: 2 */ /* 05 bytes */ /*ACM Functional Descriptor*/ 0x04, /* bFunctionLength */ 0x24, /* bDescriptorType: CS_INTERFACE */ 0x02, /* bDescriptorSubtype: Abstract Control Management desc */ 0x02, /* bmCapabilities */ /* 04 bytes */ /*Union Functional Descriptor*/ 0x05, /* bFunctionLength */ 0x24, /* bDescriptorType: CS_INTERFACE */ 0x06, /* bDescriptorSubtype: Union func desc */ CDC_INTERFACE_IDX, /* bMasterInterface: Communication class interface */ CDC_INTERFACE_IDX + 1, /* bSlaveInterface0: Data Class Interface */ /* 05 bytes */ /*Endpoint 2 Descriptor*/ 0x07, /* bLength: Endpoint Descriptor size */ USB_DESC_TYPE_ENDPOINT, /* bDescriptorType: Endpoint */ CDC_CMD_EP, /* bEndpointAddress */ 0x03, /* bmAttributes: Interrupt */ LOBYTE(CDC_CMD_PACKET_SIZE), /* wMaxPacketSize: */ HIBYTE(CDC_CMD_PACKET_SIZE), 0x10, /* bInterval: */ /* 07 bytes */ /*Data class interface descriptor*/ 0x09, /* bLength: Endpoint Descriptor size */ USB_DESC_TYPE_INTERFACE, /* bDescriptorType: */ CDC_INTERFACE_IDX + 1, /* bInterfaceNumber: Number of Interface */ 0x00, /* bAlternateSetting: Alternate setting */ 0x02, /* bNumEndpoints: Two endpoints used */ 0x0A, /* bInterfaceClass: CDC */ 0x00, /* bInterfaceSubClass: */ 0x00, /* bInterfaceProtocol: */ 0x00, /* iInterface: */ /* 09 bytes */ /*Endpoint OUT Descriptor*/ 0x07, /* bLength: Endpoint Descriptor size */ USB_DESC_TYPE_ENDPOINT, /* bDescriptorType: Endpoint */ CDC_OUT_EP, /* bEndpointAddress */ 0x02, /* bmAttributes: Bulk */ LOBYTE(CDC_DATA_PACKET_SIZE), /* wMaxPacketSize: */ HIBYTE(CDC_DATA_PACKET_SIZE), 0x00, /* bInterval: ignore for Bulk transfer */ /* 07 bytes */ /*Endpoint IN Descriptor*/ 0x07, /* bLength: Endpoint Descriptor size */ USB_DESC_TYPE_ENDPOINT, /* bDescriptorType: Endpoint */ CDC_IN_EP, /* bEndpointAddress */ 0x02, /* bmAttributes: Bulk */ LOBYTE(CDC_DATA_PACKET_SIZE), /* wMaxPacketSize: */ HIBYTE(CDC_DATA_PACKET_SIZE), 0x00, /* bInterval */ /* 07 bytes */
#define USB_CDC_CONFIG_DESC_SIZ 98
typedef struct _Device_cb { uint8_t (*Init) (struct _USBD_HandleTypeDef *pdev , uint8_t cfgidx); uint8_t (*DeInit) (struct _USBD_HandleTypeDef *pdev , uint8_t cfgidx); /* Control Endpoints*/ uint8_t (*Setup) (struct _USBD_HandleTypeDef *pdev , USBD_SetupReqTypedef *req); uint8_t (*EP0_TxSent) (struct _USBD_HandleTypeDef *pdev ); uint8_t (*EP0_RxReady) (struct _USBD_HandleTypeDef *pdev ); /* Class Specific Endpoints*/ uint8_t (*DataIn) (struct _USBD_HandleTypeDef *pdev , uint8_t epnum); uint8_t (*DataOut) (struct _USBD_HandleTypeDef *pdev , uint8_t epnum); uint8_t (*SOF) (struct _USBD_HandleTypeDef *pdev); uint8_t (*IsoINIncomplete) (struct _USBD_HandleTypeDef *pdev , uint8_t epnum); uint8_t (*IsoOUTIncomplete) (struct _USBD_HandleTypeDef *pdev , uint8_t epnum); const uint8_t *(*GetHSConfigDescriptor)(uint16_t *length); const uint8_t *(*GetFSConfigDescriptor)(uint16_t *length); const uint8_t *(*GetOtherSpeedConfigDescriptor)(uint16_t *length); const uint8_t *(*GetDeviceQualifierDescriptor)(uint16_t *length); #if (USBD_SUPPORT_USER_STRING == 1) uint8_t *(*GetUsrStrDescriptor)(struct _USBD_HandleTypeDef *pdev ,uint8_t index, uint16_t *length); #endif } USBD_ClassTypeDef;
/** * @brief USBD_MSC_CDC_Init * Initialize the MSC+CDC interface * @param pdev: device instance * @param cfgidx: Configuration index * @retval status */ static uint8_t USBD_MSC_CDC_Init (USBD_HandleTypeDef *pdev, uint8_t cfgidx) { /* MSC initialization */ uint8_t ret = USBD_MSC_Init (pdev, cfgidx); if(ret != USBD_OK) return ret; /* CDC initialization */ ret = USBD_CDC_Init (pdev, cfgidx); if(ret != USBD_OK) return ret; return USBD_OK; } /** * @brief USBD_MSC_CDC_Init * DeInitialize the MSC+CDC layer * @param pdev: device instance * @param cfgidx: Configuration index * @retval status */ static uint8_t USBD_MSC_CDC_DeInit (USBD_HandleTypeDef *pdev, uint8_t cfgidx) { /* MSC De-initialization */ USBD_MSC_DeInit(pdev, cfgidx); /* CDC De-initialization */ USBD_CDC_DeInit(pdev, cfgidx); return USBD_OK; }
/** * @brief USBD_MSC_CDC_Setup * Handle the MSC+CDC specific requests * @param pdev: instance * @param req: usb requests * @retval status */ static uint8_t USBD_MSC_CDC_Setup (USBD_HandleTypeDef *pdev, USBD_SetupReqTypedef *req) { // Route requests to MSC interface or its endpoints to MSC class implementaion if(((req->bmRequest & USB_REQ_RECIPIENT_MASK) == USB_REQ_RECIPIENT_INTERFACE && req->wIndex == MSC_INTERFACE_IDX) || ((req->bmRequest & USB_REQ_RECIPIENT_MASK) == USB_REQ_RECIPIENT_ENDPOINT && ((req->wIndex & 0x7F) == MSC_EP_IDX))) { return USBD_MSC_Setup(pdev, req); } return USBD_CDC_Setup(pdev, req); }
#define USBD_MAX_NUM_INTERFACES 3
/** * @brief USBD_MSC_CDC_DataIn * handle data IN Stage * @param pdev: device instance * @param epnum: endpoint index * @retval status */ static uint8_t USBD_MSC_CDC_DataIn (USBD_HandleTypeDef *pdev, uint8_t epnum) { if(epnum == MSC_EP_IDX) return USBD_MSC_DataIn(pdev, epnum); return USBD_CDC_DataIn(pdev, epnum); } /** * @brief USBD_MSC_CDC_DataOut * handle data OUT Stage * @param pdev: device instance * @param epnum: endpoint index * @retval status */ static uint8_t USBD_MSC_CDC_DataOut (USBD_HandleTypeDef *pdev, uint8_t epnum) { if(epnum == MSC_EP_IDX) return USBD_MSC_DataOut(pdev, epnum); return USBD_CDC_DataOut(pdev, epnum); }
/** * @brief USBD_MSC_CDC_EP0_RxReady * handle EP0 Rx Ready event * @param pdev: device instance * @retval status */ static uint8_t USBD_MSC_CDC_EP0_RxReady (USBD_HandleTypeDef *pdev) { return USBD_CDC_EP0_RxReady(pdev); }
USBD_ClassTypeDef USBD_MSC_CDC_ClassDriver = { USBD_MSC_CDC_Init, USBD_MSC_CDC_DeInit, USBD_MSC_CDC_Setup, NULL, //USBD_MSC_CDC_EP0_TxReady, USBD_MSC_CDC_EP0_RxReady, USBD_MSC_CDC_DataIn, USBD_MSC_CDC_DataOut, NULL, //USBD_MSC_CDC_SOF, NULL, //USBD_MSC_CDC_IsoINIncomplete, NULL, //USBD_MSC_CDC_IsoOutIncomplete, USBD_MSC_CDC_GetCfgDesc, USBD_MSC_CDC_GetCfgDesc, USBD_MSC_CDC_GetCfgDesc, USBD_MSC_CDC_GetDeviceQualifierDesc, };
USBD_Init(&hUsbDeviceFS, &FS_Desc, 0); USBD_RegisterClass(&hUsbDeviceFS, &USBD_MSC_CDC_ClassDriver); USBD_CDC_RegisterInterface(&hUsbDeviceFS, &USBD_Interface_fops_FS); USBD_MSC_RegisterStorage(&hUsbDeviceFS, &SdMscDriver); USBD_Start(&hUsbDeviceFS);
/* USB Device handle structure */ typedef struct _USBD_HandleTypeDef { ... void *pClassData; void *pUserData; void *pData; } USBD_HandleTypeDef;
typedef struct _USBD_HandleTypeDef { ... USBD_MSC_BOT_HandleTypeDef *pClassDataMSC; const USBD_StorageTypeDef *pClassSpecificInterfaceMSC; USBD_CDC_HandleTypeDef *pClassDataCDC; const USBD_CDC_ItfTypeDef *pClassSpecificInterfaceCDC; PCD_HandleTypeDef *pPCDHandle; } USBD_HandleTypeDef;
About the organization of the project. In some IDE projects can be built as follows. The USB library and source code for the class drivers come with the STM32 Cube, but some of the files are suggested to be written to the user. It may happen that the library lies somewhere in a common location and is used by several projects. It should be understood that I now we are changing the code of the USB library and therefore it is better to have our own copy so as not to disturb anyone.
USBD_StatusTypeDef USBD_LL_Reset(USBD_HandleTypeDef *pdev) { ... if (pdev->pClassData) pdev->pClass->DeInit(pdev, pdev->dev_config); ... }
static uint8_t USBD_CDC_Init (USBD_HandleTypeDef *pdev, uint8_t cfgidx) { ... pdev->pClassData = USBD_malloc(sizeof (USBD_CDC_HandleTypeDef)); ... }
void *USBD_static_malloc(uint32_t size) { static uint32_t mem[(sizeof(USBD_CDC_HandleTypeDef)/4+1)];/* On 32-bit boundary */ return mem; }
// A CDC object USBD_CDC_HandleTypeDef cdcInstance; ... uint8_t USBD_CDC_Init (USBD_HandleTypeDef *pdev, uint8_t cfgidx) { ... pdev->pClassDataCDC = &cdcInstance; hcdc = pdev->pClassDataCDC; ... }
HAL_PCDEx_PMAConfig(pdev->pPCDHandle , 0x00 , PCD_SNG_BUF, 0x20); HAL_PCDEx_PMAConfig(pdev->pPCDHandle , 0x80 , PCD_SNG_BUF, 0x60); HAL_PCDEx_PMAConfig(pdev->pPCDHandle , MSC_IN_EP, PCD_SNG_BUF, 0xA0); HAL_PCDEx_PMAConfig(pdev->pPCDHandle , MSC_OUT_EP, PCD_SNG_BUF, 0xE0); HAL_PCDEx_PMAConfig(pdev->pPCDHandle, CDC_CMD_EP, PCD_SNG_BUF, 0x100); HAL_PCDEx_PMAConfig(pdev->pPCDHandle, CDC_IN_EP, PCD_SNG_BUF, 0x140); HAL_PCDEx_PMAConfig(pdev->pPCDHandle, CDC_OUT_EP, PCD_SNG_BUF, 0x180);
%DESCRIPTION%=DriverInstall,USB\VID_0483&PID_5740
%DESCRIPTION%=DriverInstall,USB\VID_0483&PID_5741&MI_01
Source: https://habr.com/ru/post/335018/
All Articles