diff --git a/cores/arduino/stm32/usb/cdc/usbd_cdc.c b/cores/arduino/stm32/usb/cdc/usbd_cdc.c index 9ee0d7885a..b4e42b17b2 100644 --- a/cores/arduino/stm32/usb/cdc/usbd_cdc.c +++ b/cores/arduino/stm32/usb/cdc/usbd_cdc.c @@ -108,7 +108,7 @@ static uint8_t *USBD_CDC_GetFSCfgDesc(uint16_t *length); static uint8_t *USBD_CDC_GetHSCfgDesc(uint16_t *length); static uint8_t *USBD_CDC_GetOtherSpeedCfgDesc(uint16_t *length); static uint8_t *USBD_CDC_GetOtherSpeedCfgDesc(uint16_t *length); -uint8_t *USBD_CDC_GetDeviceQualifierDescriptor(uint16_t *length); +uint8_t *USBD_CDC_GetDeviceQualifierDescriptor(uint16_t *length); /* USB Standard Device Descriptor */ __ALIGN_BEGIN static uint8_t USBD_CDC_DeviceQualifierDesc[USB_LEN_DEV_QUALIFIER_DESC] __ALIGN_END = { @@ -138,7 +138,7 @@ USBD_ClassTypeDef USBD_CDC = { USBD_CDC_Init, USBD_CDC_DeInit, USBD_CDC_Setup, - NULL, /* EP0_TxSent, */ + NULL, /* EP0_TxSent */ USBD_CDC_EP0_RxReady, USBD_CDC_DataIn, USBD_CDC_DataOut, @@ -154,252 +154,291 @@ USBD_ClassTypeDef USBD_CDC = { /* USB CDC device Configuration Descriptor */ __ALIGN_BEGIN static 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 */ + 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 0 mA */ + 0x02, /* bNumInterfaces: 2 interfaces */ + 0x01, /* bConfigurationValue: Configuration value */ + 0x00, /* iConfiguration: Index of string descriptor describing the configuration */ +#if (USBD_SELF_POWERED == 1U) + 0xC0, /* bmAttributes: Bus Powered according to user configuration */ +#else + 0x80, /* bmAttributes: Bus Powered according to user configuration */ +#endif + USBD_MAX_POWER, /* MaxPower (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 */ - 0x00, /* bInterfaceProtocol: No specific protocol */ - 0x00, /* iInterface: */ + 0x09, /* bLength: Interface Descriptor size */ + USB_DESC_TYPE_INTERFACE, /* bDescriptorType: Interface */ + 0x00, /* bInterfaceNumber: Number of Interface */ + 0x00, /* bAlternateSetting: Alternate setting */ + 0x01, /* bNumEndpoints: One endpoints used */ + 0x02, /* bInterfaceClass: Communication Interface Class */ + 0x02, /* bInterfaceSubClass: Abstract Control Model */ + 0x00, /* bInterfaceProtocol: No specific protocol */ + 0x00, /* iInterface */ + /* Header Functional Descriptor */ - 0x05, /* bLength: Endpoint Descriptor size */ - 0x24, /* bDescriptorType: CS_INTERFACE */ - 0x00, /* bDescriptorSubtype: Header Func Desc */ - 0x10, /* bcdCDC: spec release number */ + 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 */ + 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 */ + 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 */ + 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: */ + 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), - CDC_HS_BINTERVAL, /* bInterval: */ + CDC_HS_BINTERVAL, /* 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: */ + 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: */ + 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 */ + 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: */ + 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 */ + 0x00 /* bInterval: ignore for Bulk transfer */ }; /* USB CDC device Configuration Descriptor */ __ALIGN_BEGIN static uint8_t USBD_CDC_CfgFSDesc[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 */ + 0x09, /* bLength: Configuration Descriptor size */ + USB_DESC_TYPE_CONFIGURATION, /* bDescriptorType: Configuration */ + USB_CDC_CONFIG_DESC_SIZ, /* wTotalLength: nb 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 0 mA */ + 0x02, /* bNumInterfaces: 2 interfaces */ + 0x01, /* bConfigurationValue: Configuration value */ + 0x00, /* iConfiguration: Index of string descriptor describing the configuration */ +#if (USBD_SELF_POWERED == 1U) + 0xC0, /* bmAttributes: Bus Powered according to user configuration */ +#else + 0x80, /* bmAttributes: Bus Powered according to user configuration */ +#endif + USBD_MAX_POWER, /* MaxPower (mA) */ + /*---------------------------------------------------------------------------*/ + /* Interface Descriptor */ - 0x09, /* bLength: Interface Descriptor size */ - USB_DESC_TYPE_INTERFACE, /* bDescriptorType: Interface */ + 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 */ - 0x00, /* bInterfaceProtocol: No specific protocol */ - 0x00, /* iInterface: */ + 0x00, /* bInterfaceNumber: Number of Interface */ + 0x00, /* bAlternateSetting: Alternate setting */ + 0x01, /* bNumEndpoints: One endpoint used */ + 0x02, /* bInterfaceClass: Communication Interface Class */ + 0x02, /* bInterfaceSubClass: Abstract Control Model */ + 0x00, /* bInterfaceProtocol: No specific protocol */ + 0x00, /* iInterface */ + /* Header Functional Descriptor */ - 0x05, /* bLength: Endpoint Descriptor size */ - 0x24, /* bDescriptorType: CS_INTERFACE */ - 0x00, /* bDescriptorSubtype: Header Func Desc */ - 0x10, /* bcdCDC: spec release number */ + 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 */ + 0x05, /* bFunctionLength */ + 0x24, /* bDescriptorType: CS_INTERFACE */ + 0x01, /* bDescriptorSubtype: Call Management Func Desc */ + 0x00, /* bmCapabilities: D0+D1 */ + 0x01, /* bDataInterface */ + /* ACM Functional Descriptor */ - 0x04, /* bFunctionLength */ - 0x24, /* bDescriptorType: CS_INTERFACE */ - 0x02, /* bDescriptorSubtype: Abstract Control Management desc */ - 0x02, /* bmCapabilities */ + 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 */ + 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: */ + 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), - CDC_FS_BINTERVAL, /* bInterval: */ + CDC_FS_BINTERVAL, /* 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: */ + 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_FS_MAX_PACKET_SIZE), /* wMaxPacketSize: */ + 0x07, /* bLength: Endpoint Descriptor size */ + USB_DESC_TYPE_ENDPOINT, /* bDescriptorType: Endpoint */ + CDC_OUT_EP, /* bEndpointAddress */ + 0x02, /* bmAttributes: Bulk */ + LOBYTE(CDC_DATA_FS_MAX_PACKET_SIZE), /* wMaxPacketSize */ HIBYTE(CDC_DATA_FS_MAX_PACKET_SIZE), - 0x00, /* bInterval: ignore for Bulk transfer */ + 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_FS_MAX_PACKET_SIZE), /* wMaxPacketSize: */ + 0x07, /* bLength: Endpoint Descriptor size */ + USB_DESC_TYPE_ENDPOINT, /* bDescriptorType: Endpoint */ + CDC_IN_EP, /* bEndpointAddress */ + 0x02, /* bmAttributes: Bulk */ + LOBYTE(CDC_DATA_FS_MAX_PACKET_SIZE), /* wMaxPacketSize */ HIBYTE(CDC_DATA_FS_MAX_PACKET_SIZE), - 0x00 /* bInterval: ignore for Bulk transfer */ + 0x00 /* bInterval: ignore for Bulk transfer */ }; __ALIGN_BEGIN static uint8_t USBD_CDC_OtherSpeedCfgDesc[USB_CDC_CONFIG_DESC_SIZ] __ALIGN_END = { - 0x09, /* bLength: Configuation Descriptor size */ + 0x09, /* bLength: Configuation Descriptor size */ USB_DESC_TYPE_OTHER_SPEED_CONFIGURATION, USB_CDC_CONFIG_DESC_SIZ, 0x00, - 0x02, /* bNumInterfaces: 2 interfaces */ - 0x01, /* bConfigurationValue: */ - 0x04, /* iConfiguration: */ - 0xC0, /* bmAttributes: */ - 0x32, /* MaxPower 100 mA */ - /*Interface Descriptor */ - 0x09, /* bLength: Interface Descriptor size */ - USB_DESC_TYPE_INTERFACE, /* bDescriptorType: Interface */ + 0x02, /* bNumInterfaces: 2 interfaces */ + 0x01, /* bConfigurationValue */ + 0x04, /* iConfiguration */ +#if (USBD_SELF_POWERED == 1U) + 0xC0, /* bmAttributes: Bus Powered according to user configuration */ +#else + 0x80, /* bmAttributes: Bus Powered according to user configuration */ +#endif + USBD_MAX_POWER, /* MaxPower (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 */ - 0x00, /* bInterfaceProtocol: No specific protocol */ - 0x00, /* iInterface: */ + 0x00, /* bInterfaceNumber: Number of Interface */ + 0x00, /* bAlternateSetting: Alternate setting */ + 0x01, /* bNumEndpoints: One endpoints used */ + 0x02, /* bInterfaceClass: Communication Interface Class */ + 0x02, /* bInterfaceSubClass: Abstract Control Model */ + 0x00, /* bInterfaceProtocol: No specific protocol */ + 0x00, /* iInterface */ + /* Header Functional Descriptor */ - 0x05, /* bLength: Endpoint Descriptor size */ - 0x24, /* bDescriptorType: CS_INTERFACE */ - 0x00, /* bDescriptorSubtype: Header Func Desc */ - 0x10, /* bcdCDC: spec release number */ + 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: */ + + /* Call Management Functional Descriptor */ + 0x05, /* bFunctionLength */ + 0x24, /* bDescriptorType: CS_INTERFACE */ + 0x01, /* bDescriptorSubtype: Call Management Func Desc */ + 0x00, /* bmCapabilities */ + 0x01, /* bDataInterface */ + + /* 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), - CDC_FS_BINTERVAL, /* bInterval: */ + CDC_FS_BINTERVAL, /* 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: */ + 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 */ - 0x40, /* wMaxPacketSize: */ + 0x07, /* bLength: Endpoint Descriptor size */ + USB_DESC_TYPE_ENDPOINT, /* bDescriptorType: Endpoint */ + CDC_OUT_EP, /* bEndpointAddress */ + 0x02, /* bmAttributes: Bulk */ + 0x40, /* wMaxPacketSize */ 0x00, - 0x00, /* bInterval: ignore for Bulk transfer */ + 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 */ - 0x40, /* wMaxPacketSize: */ + 0x07, /* bLength: Endpoint Descriptor size */ + USB_DESC_TYPE_ENDPOINT, /* bDescriptorType: Endpoint */ + CDC_IN_EP, /* bEndpointAddress */ + 0x02, /* bmAttributes: Bulk */ + 0x40, /* wMaxPacketSize */ 0x00, - 0x00 /* bInterval */ + 0x00 /* bInterval */ }; /** @@ -417,12 +456,12 @@ __ALIGN_BEGIN static uint8_t USBD_CDC_OtherSpeedCfgDesc[USB_CDC_CONFIG_DESC_SIZ] * @param cfgidx: Configuration index * @retval status */ -static uint8_t USBD_CDC_Init(USBD_HandleTypeDef *pdev, uint8_t cfgidx) +static uint8_t USBD_CDC_Init(USBD_HandleTypeDef *pdev, uint8_t cfgidx) { UNUSED(cfgidx); - USBD_CDC_HandleTypeDef *hcdc; + USBD_CDC_HandleTypeDef *hcdc; - hcdc = USBD_malloc(sizeof(USBD_CDC_HandleTypeDef)); + hcdc = (USBD_CDC_HandleTypeDef *)USBD_malloc(sizeof(USBD_CDC_HandleTypeDef)); if (hcdc == NULL) { pdev->pClassData = NULL; @@ -494,10 +533,9 @@ static uint8_t USBD_CDC_Init(USBD_HandleTypeDef *pdev, uint8_t cfgidx) * @param cfgidx: Configuration index * @retval status */ -static uint8_t USBD_CDC_DeInit(USBD_HandleTypeDef *pdev, uint8_t cfgidx) +static uint8_t USBD_CDC_DeInit(USBD_HandleTypeDef *pdev, uint8_t cfgidx) { UNUSED(cfgidx); - uint8_t ret = 0U; /* Close EP IN */ (void)USBD_LL_CloseEP(pdev, CDC_IN_EP); @@ -519,7 +557,7 @@ static uint8_t USBD_CDC_DeInit(USBD_HandleTypeDef *pdev, uint8_t cfgidx) pdev->pClassData = NULL; } - return ret; + return (uint8_t)USBD_OK; } /** @@ -529,14 +567,19 @@ static uint8_t USBD_CDC_DeInit(USBD_HandleTypeDef *pdev, uint8_t cfgidx) * @param req: usb requests * @retval status */ -static uint8_t USBD_CDC_Setup(USBD_HandleTypeDef *pdev, - USBD_SetupReqTypedef *req) +static uint8_t USBD_CDC_Setup(USBD_HandleTypeDef *pdev, + USBD_SetupReqTypedef *req) { - USBD_CDC_HandleTypeDef *hcdc = (USBD_CDC_HandleTypeDef *) pdev->pClassData; + USBD_CDC_HandleTypeDef *hcdc = (USBD_CDC_HandleTypeDef *)pdev->pClassData; + uint16_t len; uint8_t ifalt = 0U; uint16_t status_info = 0U; USBD_StatusTypeDef ret = USBD_OK; + if (hcdc == NULL) { + return (uint8_t)USBD_FAIL; + } + switch (req->bmRequest & USB_REQ_TYPE_MASK) { case USB_REQ_TYPE_CLASS: if (req->wLength != 0U) { @@ -545,12 +588,13 @@ static uint8_t USBD_CDC_Setup(USBD_HandleTypeDef *pdev, (uint8_t *)hcdc->data, req->wLength); - (void)USBD_CtlSendData(pdev, (uint8_t *)hcdc->data, req->wLength); + len = MIN(CDC_REQ_MAX_DATA_SIZE, req->wLength); + (void)USBD_CtlSendData(pdev, (uint8_t *)hcdc->data, len); } else { hcdc->CmdOpCode = req->bRequest; - hcdc->CmdLength = (uint8_t)req->wLength; + hcdc->CmdLength = (uint8_t)MIN(req->wLength, USB_MAX_EP0_SIZE); - (void)USBD_CtlPrepareRx(pdev, (uint8_t *)hcdc->data, req->wLength); + (void)USBD_CtlPrepareRx(pdev, (uint8_t *)hcdc->data, hcdc->CmdLength); } } else { ((USBD_CDC_ItfTypeDef *)pdev->pUserData)->Control(req->bRequest, @@ -611,17 +655,17 @@ static uint8_t USBD_CDC_Setup(USBD_HandleTypeDef *pdev, * @param epnum: endpoint number * @retval status */ -static uint8_t USBD_CDC_DataIn(USBD_HandleTypeDef *pdev, uint8_t epnum) +static uint8_t USBD_CDC_DataIn(USBD_HandleTypeDef *pdev, uint8_t epnum) { - USBD_CDC_HandleTypeDef *hcdc; + USBD_CDC_HandleTypeDef *hcdc = (USBD_CDC_HandleTypeDef *)pdev->pClassData; PCD_HandleTypeDef *hpcd = pdev->pData; - if (pdev->pClassData == NULL) { + if (hcdc == NULL) { return (uint8_t)USBD_FAIL; } - hcdc = (USBD_CDC_HandleTypeDef *)pdev->pClassData; - if ((pdev->ep_in[epnum].total_length > 0U) && ((pdev->ep_in[epnum].total_length % hpcd->IN_ep[epnum].maxpacket) == 0U)) { + 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; @@ -629,7 +673,10 @@ static uint8_t USBD_CDC_DataIn(USBD_HandleTypeDef *pdev, uint8_t epnum) (void)USBD_LL_Transmit(pdev, epnum, NULL, 0U); } else { hcdc->TxState = 0U; - ((USBD_CDC_ItfTypeDef *)pdev->pUserData)->TransmitCplt(hcdc->TxBuffer, &hcdc->TxLength, epnum); + + if (((USBD_CDC_ItfTypeDef *)pdev->pUserData)->TransmitCplt != NULL) { + ((USBD_CDC_ItfTypeDef *)pdev->pUserData)->TransmitCplt(hcdc->TxBuffer, &hcdc->TxLength, epnum); + } } return (uint8_t)USBD_OK; @@ -642,11 +689,11 @@ static uint8_t USBD_CDC_DataIn(USBD_HandleTypeDef *pdev, uint8_t epnum) * @param epnum: endpoint number * @retval status */ -static uint8_t USBD_CDC_DataOut(USBD_HandleTypeDef *pdev, uint8_t epnum) +static uint8_t USBD_CDC_DataOut(USBD_HandleTypeDef *pdev, uint8_t epnum) { USBD_CDC_HandleTypeDef *hcdc = (USBD_CDC_HandleTypeDef *)pdev->pClassData; - if (pdev->pClassData == NULL) { + if (hcdc == NULL) { return (uint8_t)USBD_FAIL; } @@ -667,16 +714,19 @@ static uint8_t USBD_CDC_DataOut(USBD_HandleTypeDef *pdev, uint8_t epnum) * @param pdev: device instance * @retval status */ -static uint8_t USBD_CDC_EP0_RxReady(USBD_HandleTypeDef *pdev) +static uint8_t USBD_CDC_EP0_RxReady(USBD_HandleTypeDef *pdev) { - USBD_CDC_HandleTypeDef *hcdc = (USBD_CDC_HandleTypeDef *)pdev->pClassData; + USBD_CDC_HandleTypeDef *hcdc = (USBD_CDC_HandleTypeDef *)pdev->pClassData; + + if (hcdc == NULL) { + return (uint8_t)USBD_FAIL; + } if ((pdev->pUserData != NULL) && (hcdc->CmdOpCode != 0xFFU)) { ((USBD_CDC_ItfTypeDef *)pdev->pUserData)->Control(hcdc->CmdOpCode, (uint8_t *)hcdc->data, (uint16_t)hcdc->CmdLength); hcdc->CmdOpCode = 0xFFU; - } return (uint8_t)USBD_OK; @@ -689,7 +739,7 @@ static uint8_t USBD_CDC_EP0_RxReady(USBD_HandleTypeDef *pdev) * @param length : pointer data length * @retval pointer to descriptor buffer */ -static uint8_t *USBD_CDC_GetFSCfgDesc(uint16_t *length) +static uint8_t *USBD_CDC_GetFSCfgDesc(uint16_t *length) { *length = (uint16_t)sizeof(USBD_CDC_CfgFSDesc); @@ -703,7 +753,7 @@ static uint8_t *USBD_CDC_GetFSCfgDesc(uint16_t *length) * @param length : pointer data length * @retval pointer to descriptor buffer */ -static uint8_t *USBD_CDC_GetHSCfgDesc(uint16_t *length) +static uint8_t *USBD_CDC_GetHSCfgDesc(uint16_t *length) { *length = (uint16_t)sizeof(USBD_CDC_CfgHSDesc); @@ -711,13 +761,13 @@ static uint8_t *USBD_CDC_GetHSCfgDesc(uint16_t *length) } /** - * @brief USBD_CDC_GetCfgDesc + * @brief USBD_CDC_GetOtherSpeedCfgDesc * Return configuration descriptor * @param speed : current device speed * @param length : pointer data length * @retval pointer to descriptor buffer */ -static uint8_t *USBD_CDC_GetOtherSpeedCfgDesc(uint16_t *length) +static uint8_t *USBD_CDC_GetOtherSpeedCfgDesc(uint16_t *length) { *length = (uint16_t)sizeof(USBD_CDC_OtherSpeedCfgDesc); @@ -725,12 +775,12 @@ static uint8_t *USBD_CDC_GetOtherSpeedCfgDesc(uint16_t *length) } /** -* @brief DeviceQualifierDescriptor -* return Device Qualifier descriptor -* @param length : pointer data length -* @retval pointer to descriptor buffer -*/ -uint8_t *USBD_CDC_GetDeviceQualifierDescriptor(uint16_t *length) + * @brief USBD_CDC_GetDeviceQualifierDescriptor + * return Device Qualifier descriptor + * @param length : pointer data length + * @retval pointer to descriptor buffer + */ +uint8_t *USBD_CDC_GetDeviceQualifierDescriptor(uint16_t *length) { *length = (uint16_t)sizeof(USBD_CDC_DeviceQualifierDesc); @@ -738,13 +788,13 @@ uint8_t *USBD_CDC_GetDeviceQualifierDescriptor(uint16_t *length) } /** -* @brief USBD_CDC_RegisterInterface + * @brief USBD_CDC_RegisterInterface * @param pdev: device instance * @param fops: CD Interface callback * @retval status */ -uint8_t USBD_CDC_RegisterInterface(USBD_HandleTypeDef *pdev, - USBD_CDC_ItfTypeDef *fops) +uint8_t USBD_CDC_RegisterInterface(USBD_HandleTypeDef *pdev, + USBD_CDC_ItfTypeDef *fops) { if (fops == NULL) { return (uint8_t)USBD_FAIL; @@ -761,10 +811,14 @@ uint8_t USBD_CDC_RegisterInterface(USBD_HandleTypeDef *pdev, * @param pbuff: Tx Buffer * @retval status */ -uint8_t USBD_CDC_SetTxBuffer(USBD_HandleTypeDef *pdev, - uint8_t *pbuff, uint32_t length) +uint8_t USBD_CDC_SetTxBuffer(USBD_HandleTypeDef *pdev, + uint8_t *pbuff, uint32_t length) { - USBD_CDC_HandleTypeDef *hcdc = (USBD_CDC_HandleTypeDef *)pdev->pClassData; + USBD_CDC_HandleTypeDef *hcdc = (USBD_CDC_HandleTypeDef *)pdev->pClassData; + + if (hcdc == NULL) { + return (uint8_t)USBD_FAIL; + } hcdc->TxBuffer = pbuff; hcdc->TxLength = length; @@ -772,16 +826,19 @@ uint8_t USBD_CDC_SetTxBuffer(USBD_HandleTypeDef *pdev, return (uint8_t)USBD_OK; } - /** * @brief USBD_CDC_SetRxBuffer * @param pdev: device instance * @param pbuff: Rx Buffer * @retval status */ -uint8_t USBD_CDC_SetRxBuffer(USBD_HandleTypeDef *pdev, uint8_t *pbuff) +uint8_t USBD_CDC_SetRxBuffer(USBD_HandleTypeDef *pdev, uint8_t *pbuff) { - USBD_CDC_HandleTypeDef *hcdc = (USBD_CDC_HandleTypeDef *)pdev->pClassData; + USBD_CDC_HandleTypeDef *hcdc = (USBD_CDC_HandleTypeDef *)pdev->pClassData; + + if (hcdc == NULL) { + return (uint8_t)USBD_FAIL; + } hcdc->RxBuffer = pbuff; @@ -794,12 +851,12 @@ uint8_t USBD_CDC_SetRxBuffer(USBD_HandleTypeDef *pdev, uint8_t *pbuff) * @param pdev: device instance * @retval status */ -uint8_t USBD_CDC_TransmitPacket(USBD_HandleTypeDef *pdev) +uint8_t USBD_CDC_TransmitPacket(USBD_HandleTypeDef *pdev) { - USBD_CDC_HandleTypeDef *hcdc = (USBD_CDC_HandleTypeDef *)pdev->pClassData; + USBD_CDC_HandleTypeDef *hcdc = (USBD_CDC_HandleTypeDef *)pdev->pClassData; USBD_StatusTypeDef ret = USBD_BUSY; - if (pdev->pClassData == NULL) { + if (hcdc == NULL) { return (uint8_t)USBD_FAIL; } @@ -819,18 +876,17 @@ uint8_t USBD_CDC_TransmitPacket(USBD_HandleTypeDef *pdev) return (uint8_t)ret; } - /** * @brief USBD_CDC_ReceivePacket * prepare OUT Endpoint for reception * @param pdev: device instance * @retval status */ -uint8_t USBD_CDC_ReceivePacket(USBD_HandleTypeDef *pdev) +uint8_t USBD_CDC_ReceivePacket(USBD_HandleTypeDef *pdev) { - USBD_CDC_HandleTypeDef *hcdc = (USBD_CDC_HandleTypeDef *)pdev->pClassData; + USBD_CDC_HandleTypeDef *hcdc = (USBD_CDC_HandleTypeDef *)pdev->pClassData; - if (pdev->pClassData == NULL) { + if (hcdc == NULL) { return (uint8_t)USBD_FAIL; } diff --git a/cores/arduino/stm32/usb/cdc/usbd_cdc.h b/cores/arduino/stm32/usb/cdc/usbd_cdc.h index 5395708c06..814ffb2567 100644 --- a/cores/arduino/stm32/usb/cdc/usbd_cdc.h +++ b/cores/arduino/stm32/usb/cdc/usbd_cdc.h @@ -38,6 +38,7 @@ extern "C" { * @{ */ + /** @defgroup usbd_cdc_Exported_Defines * @{ */ @@ -58,6 +59,7 @@ extern "C" { #define CDC_DATA_FS_IN_PACKET_SIZE CDC_DATA_FS_MAX_PACKET_SIZE #define CDC_DATA_FS_OUT_PACKET_SIZE CDC_DATA_FS_MAX_PACKET_SIZE +#define CDC_REQ_MAX_DATA_SIZE 0x7U /*---------------------------------------------------------------------*/ /* CDC definitions */ /*---------------------------------------------------------------------*/ @@ -100,7 +102,7 @@ typedef struct _USBD_CDC_Itf { typedef struct { - uint32_t data[CDC_DATA_HS_MAX_PACKET_SIZE / 4U]; /* Force 32bits alignment */ + uint32_t data[CDC_DATA_HS_MAX_PACKET_SIZE / 4U]; /* Force 32-bit alignment */ uint8_t CmdOpCode; uint8_t CmdLength; uint8_t *RxBuffer; @@ -126,8 +128,8 @@ typedef struct { * @{ */ -extern USBD_ClassTypeDef USBD_CDC; -#define USBD_CDC_CLASS &USBD_CDC +extern USBD_ClassTypeDef USBD_CDC; +#define USBD_CDC_CLASS &USBD_CDC /** * @} */ @@ -135,16 +137,16 @@ extern USBD_ClassTypeDef USBD_CDC; /** @defgroup USB_CORE_Exported_Functions * @{ */ -uint8_t USBD_CDC_RegisterInterface(USBD_HandleTypeDef *pdev, - USBD_CDC_ItfTypeDef *fops); +uint8_t USBD_CDC_RegisterInterface(USBD_HandleTypeDef *pdev, + USBD_CDC_ItfTypeDef *fops); -uint8_t USBD_CDC_SetTxBuffer(USBD_HandleTypeDef *pdev, uint8_t *pbuff, - uint32_t length); +uint8_t USBD_CDC_SetTxBuffer(USBD_HandleTypeDef *pdev, uint8_t *pbuff, + uint32_t length); -uint8_t USBD_CDC_SetRxBuffer(USBD_HandleTypeDef *pdev, uint8_t *pbuff); -uint8_t USBD_CDC_ReceivePacket(USBD_HandleTypeDef *pdev); -uint8_t USBD_CDC_ClearBuffer(USBD_HandleTypeDef *pdev); -uint8_t USBD_CDC_TransmitPacket(USBD_HandleTypeDef *pdev); +uint8_t USBD_CDC_SetRxBuffer(USBD_HandleTypeDef *pdev, uint8_t *pbuff); +uint8_t USBD_CDC_ReceivePacket(USBD_HandleTypeDef *pdev); +uint8_t USBD_CDC_ClearBuffer(USBD_HandleTypeDef *pdev); +uint8_t USBD_CDC_TransmitPacket(USBD_HandleTypeDef *pdev); /** * @} */ diff --git a/cores/arduino/stm32/usb/cdc/usbd_cdc_if.c b/cores/arduino/stm32/usb/cdc/usbd_cdc_if.c index c09675f95e..dbe8245a74 100644 --- a/cores/arduino/stm32/usb/cdc/usbd_cdc_if.c +++ b/cores/arduino/stm32/usb/cdc/usbd_cdc_if.c @@ -243,7 +243,7 @@ static int8_t USBD_CDC_Receive(uint8_t *Buf, uint32_t *Len) /** * @brief USBD_CDC_TransmitCplt - * Data transmited callback + * Data transmitted callback * * @note * This function is IN transfer complete callback used to inform user that diff --git a/cores/arduino/stm32/usb/hid/usbd_hid_composite.c b/cores/arduino/stm32/usb/hid/usbd_hid_composite.c index c7aafed319..2a6457615e 100644 --- a/cores/arduino/stm32/usb/hid/usbd_hid_composite.c +++ b/cores/arduino/stm32/usb/hid/usbd_hid_composite.c @@ -45,6 +45,7 @@ #include "usbd_hid_composite.h" #include "usbd_ctlreq.h" + /** @addtogroup STM32_USB_DEVICE_LIBRARY * @{ */ @@ -79,6 +80,7 @@ * @} */ + /** @defgroup USBD_HID_Private_FunctionPrototypes * @{ */ @@ -107,11 +109,11 @@ USBD_ClassTypeDef USBD_COMPOSITE_HID = { USBD_HID_Init, USBD_HID_DeInit, USBD_COMPOSITE_HID_Setup, - NULL, /* EP0_TxSent */ - NULL, /* EP0_RxReady */ - USBD_HID_DataIn, /* DataIn */ - NULL, /* DataOut */ - NULL, /* SOF */ + NULL, /* EP0_TxSent */ + NULL, /* EP0_RxReady */ + USBD_HID_DataIn, /* DataIn */ + NULL, /* DataOut */ + NULL, /* SOF */ NULL, NULL, USBD_HID_GetHSCfgDesc, @@ -122,272 +124,286 @@ USBD_ClassTypeDef USBD_COMPOSITE_HID = { /* USB HID device FS Configuration Descriptor */ __ALIGN_BEGIN static uint8_t USBD_HID_CfgFSDesc[USB_COMPOSITE_HID_CONFIG_DESC_SIZ] __ALIGN_END = { - 0x09, /* bLength: Configuration Descriptor size */ - USB_DESC_TYPE_CONFIGURATION, /* bDescriptorType: Configuration */ - LOBYTE(USB_COMPOSITE_HID_CONFIG_DESC_SIZ), /* wTotalLength: Bytes returned */ + 0x09, /* bLength: Configuration Descriptor size */ + USB_DESC_TYPE_CONFIGURATION, /* bDescriptorType: Configuration */ + LOBYTE(USB_COMPOSITE_HID_CONFIG_DESC_SIZ), /* wTotalLength: Bytes returned */ HIBYTE(USB_COMPOSITE_HID_CONFIG_DESC_SIZ), - 0x02, /* bNumInterfaces: 2 interface */ - 0x01, /* bConfigurationValue: Configuration value */ - 0x00, /* iConfiguration: Index of string descriptor describing the configuration */ - 0xC0, /* bmAttributes: bus powered and no Support Remote Wake-up */ - 0x32, /* MaxPower 100 mA: this current is used for detecting Vbus */ + 0x02, /* bNumInterfaces: 2 interface */ + 0x01, /* bConfigurationValue: Configuration value */ + 0x00, /* iConfiguration: Index of string descriptor describing the configuration */ +#if (USBD_SELF_POWERED == 1U) + 0xC0, /* bmAttributes: Bus Powered according to user configuration */ +#else + 0x80, /* bmAttributes: Bus Powered according to user configuration */ +#endif + USBD_MAX_POWER, /* MaxPower (mA) */ + /************** Descriptor of Joystick Mouse interface ****************/ /* 09 */ - 0x09, /* bLength: Interface Descriptor size */ - USB_DESC_TYPE_INTERFACE, /* bDescriptorType: Interface descriptor type */ - HID_MOUSE_INTERFACE, /* bInterfaceNumber: Number of Interface */ - 0x00, /* bAlternateSetting: Alternate setting */ - 0x01, /* bNumEndpoints */ - 0x03, /* bInterfaceClass: HID */ - 0x01, /* bInterfaceSubClass : 1=BOOT, 0=no boot */ - 0x02, /* nInterfaceProtocol : 0=none, 1=keyboard, 2=mouse */ - 0x00, /* iInterface: Index of string descriptor */ + 0x09, /* bLength: Interface Descriptor size */ + USB_DESC_TYPE_INTERFACE, /* bDescriptorType: Interface descriptor type */ + HID_MOUSE_INTERFACE, /* bInterfaceNumber: Number of Interface */ + 0x00, /* bAlternateSetting: Alternate setting */ + 0x01, /* bNumEndpoints */ + 0x03, /* bInterfaceClass: HID */ + 0x01, /* bInterfaceSubClass : 1=BOOT, 0=no boot */ + 0x02, /* nInterfaceProtocol : 0=none, 1=keyboard, 2=mouse */ + 0x00, /* iInterface: Index of string descriptor */ /******************** Descriptor of Joystick Mouse HID ********************/ /* 18 */ - 0x09, /* bLength: HID Descriptor size */ - HID_DESCRIPTOR_TYPE, /* bDescriptorType: HID */ - 0x11, /* bcdHID: HID Class Spec release number */ + 0x09, /* bLength: HID Descriptor size */ + HID_DESCRIPTOR_TYPE, /* bDescriptorType: HID */ + 0x11, /* bcdHID: HID Class Spec release number */ 0x01, - 0x00, /* bCountryCode: Hardware target country */ - 0x01, /* bNumDescriptors: Number of HID class descriptors to follow */ - 0x22, /* bDescriptorType */ - HID_MOUSE_REPORT_DESC_SIZE, /* wItemLength: Total length of Report descriptor */ + 0x00, /* bCountryCode: Hardware target country */ + 0x01, /* bNumDescriptors: Number of HID class descriptors to follow */ + 0x22, /* bDescriptorType */ + HID_MOUSE_REPORT_DESC_SIZE, /* wItemLength: Total length of Report descriptor */ 0x00, /******************** Descriptor of Mouse endpoint ********************/ /* 27 */ - 0x07, /* bLength: Endpoint Descriptor size */ - USB_DESC_TYPE_ENDPOINT, /* bDescriptorType: */ - HID_MOUSE_EPIN_ADDR, /* bEndpointAddress: Endpoint Address (IN) */ - 0x03, /* bmAttributes: Interrupt endpoint*/ - HID_MOUSE_EPIN_SIZE, /* wMaxPacketSize: 4 Byte max */ + 0x07, /* bLength: Endpoint Descriptor size */ + USB_DESC_TYPE_ENDPOINT, /* bDescriptorType: */ + HID_MOUSE_EPIN_ADDR, /* bEndpointAddress: Endpoint Address (IN) */ + 0x03, /* bmAttributes: Interrupt endpoint */ + HID_MOUSE_EPIN_SIZE, /* wMaxPacketSize: 4 Bytes max */ 0x00, - HID_FS_BINTERVAL, /* bInterval: Polling Interval*/ + HID_FS_BINTERVAL, /* bInterval: Polling Interval*/ /******************************************************************** Keyboard *********************************************************************/ /************** Descriptor of HID Keyboard interface ****************/ /* 34 */ - 0x09, /* bLength: Interface Descriptor size */ - USB_DESC_TYPE_INTERFACE, /* bDescriptorType: Interface descriptor type */ - HID_KEYBOARD_INTERFACE, /* bInterfaceNumber: Number of Interface */ - 0x00, /* bAlternateSetting: Alternate setting */ - 0x01, /* bNumEndpoints */ - 0x03, /* bInterfaceClass: HID */ - 0x01, /* bInterfaceSubClass : 1=BOOT, 0=no boot */ - 0x01, /* nInterfaceProtocol : 0=none, 1=keyboard, 2=mouse */ - 0x00, /* iInterface: Index of string descriptor */ + 0x09, /* bLength: Interface Descriptor size */ + USB_DESC_TYPE_INTERFACE, /* bDescriptorType: Interface descriptor type */ + HID_KEYBOARD_INTERFACE, /* bInterfaceNumber: Number of Interface */ + 0x00, /* bAlternateSetting: Alternate setting */ + 0x01, /* bNumEndpoints */ + 0x03, /* bInterfaceClass: HID */ + 0x01, /* bInterfaceSubClass : 1=BOOT, 0=no boot */ + 0x01, /* nInterfaceProtocol : 0=none, 1=keyboard, 2=mouse */ + 0x00, /* iInterface: Index of string descriptor */ /******************** HID Descriptor ********************/ /* 43 */ - 0x09, /* bLength: HID Descriptor size */ - HID_DESCRIPTOR_TYPE, /* bDescriptorType: HID */ - 0x11, /* bcdHID: HID Class Spec release number */ + 0x09, /* bLength: HID Descriptor size */ + HID_DESCRIPTOR_TYPE, /* bDescriptorType: HID */ + 0x11, /* bcdHID: HID Class Spec release number */ 0x01, - 0x00, /* bCountryCode: Hardware target country */ - 0x01, /* bNumDescriptors: Number of HID class descriptors to follow */ - 0x22, /* bDescriptorType */ - HID_KEYBOARD_REPORT_DESC_SIZE, /* wItemLength: Total length of Report descriptor */ + 0x00, /* bCountryCode: Hardware target country */ + 0x01, /* bNumDescriptors: Number of HID class descriptors to follow */ + 0x22, /* bDescriptorType */ + HID_KEYBOARD_REPORT_DESC_SIZE, /* wItemLength: Total length of Report descriptor */ 0x00, /******************** Descriptor of Keyboard endpoint ********************/ /* 52 */ - 0x07, /* bLength: Endpoint Descriptor size */ - USB_DESC_TYPE_ENDPOINT, /* bDescriptorType: */ - HID_KEYBOARD_EPIN_ADDR, /* bEndpointAddress: Endpoint Address (IN) */ - 0x03, /* bmAttributes: Interrupt endpoint */ - HID_KEYBOARD_EPIN_SIZE, /* wMaxPacketSize: 8 Byte max */ + 0x07, /* bLength: Endpoint Descriptor size */ + USB_DESC_TYPE_ENDPOINT, /* bDescriptorType: */ + HID_KEYBOARD_EPIN_ADDR, /* bEndpointAddress: Endpoint Address (IN) */ + 0x03, /* bmAttributes: Interrupt endpoint */ + HID_KEYBOARD_EPIN_SIZE, /* wMaxPacketSize: 8 Byte max */ 0x00, - HID_FS_BINTERVAL /* bInterval: Polling Interval */ + HID_FS_BINTERVAL /* bInterval: Polling Interval */ /* 59 */ } ; /* USB HID device HS Configuration Descriptor */ __ALIGN_BEGIN static uint8_t USBD_HID_CfgHSDesc[USB_COMPOSITE_HID_CONFIG_DESC_SIZ] __ALIGN_END = { - 0x09, /* bLength: Configuration Descriptor size */ - USB_DESC_TYPE_CONFIGURATION, /* bDescriptorType: Configuration */ - LOBYTE(USB_COMPOSITE_HID_CONFIG_DESC_SIZ), /* wTotalLength: Bytes returned */ + 0x09, /* bLength: Configuration Descriptor size */ + USB_DESC_TYPE_CONFIGURATION, /* bDescriptorType: Configuration */ + LOBYTE(USB_COMPOSITE_HID_CONFIG_DESC_SIZ), /* wTotalLength: Bytes returned */ HIBYTE(USB_COMPOSITE_HID_CONFIG_DESC_SIZ), - 0x02, /* bNumInterfaces: 2 interface */ - 0x01, /* bConfigurationValue: Configuration value */ - 0x00, /* iConfiguration: Index of string descriptor describing the configuration */ - 0xC0, /* bmAttributes: bus powered and no Support Remote Wake-up */ - 0x32, /* MaxPower 100 mA: this current is used for detecting Vbus */ + 0x02, /* bNumInterfaces: 2 interface */ + 0x01, /* bConfigurationValue: Configuration value */ + 0x00, /* iConfiguration: Index of string descriptor describing the configuration */ +#if (USBD_SELF_POWERED == 1U) + 0xC0, /* bmAttributes: Bus Powered according to user configuration */ +#else + 0x80, /* bmAttributes: Bus Powered according to user configuration */ +#endif + USBD_MAX_POWER, /* MaxPower (mA) */ + /************** Descriptor of Joystick Mouse interface ****************/ /* 09 */ - 0x09, /* bLength: Interface Descriptor size */ - USB_DESC_TYPE_INTERFACE, /* bDescriptorType: Interface descriptor type */ - HID_MOUSE_INTERFACE, /* bInterfaceNumber: Number of Interface */ - 0x00, /* bAlternateSetting: Alternate setting */ - 0x01, /* bNumEndpoints */ - 0x03, /* bInterfaceClass: HID */ - 0x01, /* bInterfaceSubClass : 1=BOOT, 0=no boot */ - 0x02, /* nInterfaceProtocol : 0=none, 1=keyboard, 2=mouse */ - 0, /* iInterface: Index of string descriptor */ + 0x09, /* bLength: Interface Descriptor size */ + USB_DESC_TYPE_INTERFACE, /* bDescriptorType: Interface descriptor type */ + HID_MOUSE_INTERFACE, /* bInterfaceNumber: Number of Interface */ + 0x00, /* bAlternateSetting: Alternate setting */ + 0x01, /* bNumEndpoints */ + 0x03, /* bInterfaceClass: HID */ + 0x01, /* bInterfaceSubClass : 1=BOOT, 0=no boot */ + 0x02, /* nInterfaceProtocol : 0=none, 1=keyboard, 2=mouse */ + 0, /* iInterface: Index of string descriptor */ /******************** Descriptor of Joystick Mouse HID ********************/ /* 18 */ - 0x09, /* bLength: HID Descriptor size */ - HID_DESCRIPTOR_TYPE, /* bDescriptorType: HID */ - 0x11, /* bcdHID: HID Class Spec release number */ + 0x09, /* bLength: HID Descriptor size */ + HID_DESCRIPTOR_TYPE, /* bDescriptorType: HID */ + 0x11, /* bcdHID: HID Class Spec release number */ 0x01, - 0x00, /* bCountryCode: Hardware target country */ - 0x01, /* bNumDescriptors: Number of HID class descriptors to follow */ - 0x22, /* bDescriptorType */ - HID_MOUSE_REPORT_DESC_SIZE, /* wItemLength: Total length of Report descriptor */ + 0x00, /* bCountryCode: Hardware target country */ + 0x01, /* bNumDescriptors: Number of HID class descriptors to follow */ + 0x22, /* bDescriptorType */ + HID_MOUSE_REPORT_DESC_SIZE, /* wItemLength: Total length of Report descriptor */ 0x00, /******************** Descriptor of Mouse endpoint ********************/ /* 27 */ - 0x07, /* bLength: Endpoint Descriptor size */ - USB_DESC_TYPE_ENDPOINT, /* bDescriptorType: */ - HID_MOUSE_EPIN_ADDR, /* bEndpointAddress: Endpoint Address (IN) */ - 0x03, /* bmAttributes: Interrupt endpoint */ - HID_MOUSE_EPIN_SIZE, /* wMaxPacketSize: 4 Byte max */ + 0x07, /* bLength: Endpoint Descriptor size */ + USB_DESC_TYPE_ENDPOINT, /* bDescriptorType: */ + HID_MOUSE_EPIN_ADDR, /* bEndpointAddress: Endpoint Address (IN) */ + 0x03, /* bmAttributes: Interrupt endpoint */ + HID_MOUSE_EPIN_SIZE, /* wMaxPacketSize: 4 Bytes max */ 0x00, - HID_HS_BINTERVAL, /* bInterval: Polling Interval*/ + HID_HS_BINTERVAL, /* bInterval: Polling Interval*/ /******************************************************************** Keyboard *********************************************************************/ /************** Descriptor of HID Keyboard interface ****************/ /* 34 */ - 0x09, /* bLength: Interface Descriptor size */ - USB_DESC_TYPE_INTERFACE, /* bDescriptorType: Interface descriptor type */ - HID_KEYBOARD_INTERFACE, /* bInterfaceNumber: Number of Interface */ - 0x00, /* bAlternateSetting: Alternate setting */ - 0x01, /* bNumEndpoints */ - 0x03, /* bInterfaceClass: HID */ - 0x01, /* bInterfaceSubClass : 1=BOOT, 0=no boot */ - 0x01, /* nInterfaceProtocol : 0=none, 1=keyboard, 2=mouse */ - 0x00, /* iInterface: Index of string descriptor */ + 0x09, /* bLength: Interface Descriptor size */ + USB_DESC_TYPE_INTERFACE, /* bDescriptorType: Interface descriptor type */ + HID_KEYBOARD_INTERFACE, /* bInterfaceNumber: Number of Interface */ + 0x00, /* bAlternateSetting: Alternate setting */ + 0x01, /* bNumEndpoints */ + 0x03, /* bInterfaceClass: HID */ + 0x01, /* bInterfaceSubClass : 1=BOOT, 0=no boot */ + 0x01, /* nInterfaceProtocol : 0=none, 1=keyboard, 2=mouse */ + 0x00, /* iInterface: Index of string descriptor */ /******************** HID Descriptor ********************/ /* 43 */ - 0x09, /* bLength: HID Descriptor size */ - HID_DESCRIPTOR_TYPE, /* bDescriptorType: HID */ - 0x11, /* bcdHID: HID Class Spec release number */ + 0x09, /* bLength: HID Descriptor size */ + HID_DESCRIPTOR_TYPE, /* bDescriptorType: HID */ + 0x11, /* bcdHID: HID Class Spec release number */ 0x01, - 0x00, /* bCountryCode: Hardware target country */ - 0x01, /* bNumDescriptors: Number of HID class descriptors to follow */ - 0x22, /* bDescriptorType */ - HID_KEYBOARD_REPORT_DESC_SIZE, /* wItemLength: Total length of Report descriptor */ + 0x00, /* bCountryCode: Hardware target country */ + 0x01, /* bNumDescriptors: Number of HID class descriptors to follow */ + 0x22, /* bDescriptorType */ + HID_KEYBOARD_REPORT_DESC_SIZE, /* wItemLength: Total length of Report descriptor */ 0x00, /******************** Descriptor of Keyboard endpoint ********************/ /* 52 */ - 0x07, /* bLength: Endpoint Descriptor size */ - USB_DESC_TYPE_ENDPOINT, /* bDescriptorType: */ - HID_KEYBOARD_EPIN_ADDR, /* bEndpointAddress: Endpoint Address (IN) */ - 0x03, /* bmAttributes: Interrupt endpoint */ - HID_KEYBOARD_EPIN_SIZE, /* wMaxPacketSize: 8 Byte max */ + 0x07, /* bLength: Endpoint Descriptor size */ + USB_DESC_TYPE_ENDPOINT, /* bDescriptorType: */ + HID_KEYBOARD_EPIN_ADDR, /* bEndpointAddress: Endpoint Address (IN) */ + 0x03, /* bmAttributes: Interrupt endpoint */ + HID_KEYBOARD_EPIN_SIZE, /* wMaxPacketSize: 8 Byte max */ 0x00, - HID_HS_BINTERVAL /* bInterval: Polling Interval */ + HID_HS_BINTERVAL /* bInterval: Polling Interval */ /* 59 */ } ; /* USB HID device Other Speed Configuration Descriptor */ __ALIGN_BEGIN static uint8_t USBD_HID_OtherSpeedCfgDesc[USB_COMPOSITE_HID_CONFIG_DESC_SIZ] __ALIGN_END = { - 0x09, /* bLength: Configuration Descriptor size */ - USB_DESC_TYPE_CONFIGURATION, /* bDescriptorType: Configuration */ - LOBYTE(USB_COMPOSITE_HID_CONFIG_DESC_SIZ), /* wTotalLength: Bytes returned */ + 0x09, /* bLength: Configuration Descriptor size */ + USB_DESC_TYPE_CONFIGURATION, /* bDescriptorType: Configuration */ + LOBYTE(USB_COMPOSITE_HID_CONFIG_DESC_SIZ), /* wTotalLength: Bytes returned */ HIBYTE(USB_COMPOSITE_HID_CONFIG_DESC_SIZ), - 0x02, /* bNumInterfaces: 2 interface */ - 0x01, /* bConfigurationValue: Configuration value */ - 0x00, /* iConfiguration: Index of string descriptor describing the configuration */ - 0xC0, /* bmAttributes: bus powered and no Support Remote Wake-up */ - 0x32, /* MaxPower 100 mA: this current is used for detecting Vbus */ + 0x02, /* bNumInterfaces: 2 interface */ + 0x01, /* bConfigurationValue: Configuration value */ + 0x00, /* iConfiguration: Index of string descriptor describing the configuration */ +#if (USBD_SELF_POWERED == 1U) + 0xC0, /* bmAttributes: Bus Powered according to user configuration */ +#else + 0x80, /* bmAttributes: Bus Powered according to user configuration */ +#endif + USBD_MAX_POWER, /* MaxPower (mA) */ /************** Descriptor of Joystick Mouse interface ****************/ /* 09 */ - 0x09, /* bLength: Interface Descriptor size */ - USB_DESC_TYPE_INTERFACE, /* bDescriptorType: Interface descriptor type */ - HID_MOUSE_INTERFACE, /* bInterfaceNumber: Number of Interface */ - 0x00, /* bAlternateSetting: Alternate setting */ - 0x01, /* bNumEndpoints */ - 0x03, /* bInterfaceClass: HID */ - 0x01, /* bInterfaceSubClass : 1=BOOT, 0=no boot */ - 0x02, /* nInterfaceProtocol : 0=none, 1=keyboard, 2=mouse */ - 0, /* iInterface: Index of string descriptor */ + 0x09, /* bLength: Interface Descriptor size */ + USB_DESC_TYPE_INTERFACE, /* bDescriptorType: Interface descriptor type */ + HID_MOUSE_INTERFACE, /* bInterfaceNumber: Number of Interface */ + 0x00, /* bAlternateSetting: Alternate setting */ + 0x01, /* bNumEndpoints */ + 0x03, /* bInterfaceClass: HID */ + 0x01, /* bInterfaceSubClass : 1=BOOT, 0=no boot */ + 0x02, /* nInterfaceProtocol : 0=none, 1=keyboard, 2=mouse */ + 0, /* iInterface: Index of string descriptor */ /******************** Descriptor of Joystick Mouse HID ********************/ /* 18 */ - 0x09, /* bLength: HID Descriptor size */ - HID_DESCRIPTOR_TYPE, /* bDescriptorType: HID */ - 0x11, /* bcdHID: HID Class Spec release number */ + 0x09, /* bLength: HID Descriptor size */ + HID_DESCRIPTOR_TYPE, /* bDescriptorType: HID */ + 0x11, /* bcdHID: HID Class Spec release number */ 0x01, - 0x00, /* bCountryCode: Hardware target country */ - 0x01, /* bNumDescriptors: Number of HID class descriptors to follow */ - 0x22, /* bDescriptorType */ - HID_MOUSE_REPORT_DESC_SIZE, /* wItemLength: Total length of Report descriptor */ + 0x00, /* bCountryCode: Hardware target country */ + 0x01, /* bNumDescriptors: Number of HID class descriptors to follow */ + 0x22, /* bDescriptorType */ + HID_MOUSE_REPORT_DESC_SIZE, /* wItemLength: Total length of Report descriptor */ 0x00, /******************** Descriptor of Mouse endpoint ********************/ /* 27 */ - 0x07, /* bLength: Endpoint Descriptor size */ - USB_DESC_TYPE_ENDPOINT, /* bDescriptorType: */ + 0x07, /* bLength: Endpoint Descriptor size */ + USB_DESC_TYPE_ENDPOINT, /* bDescriptorType: */ - HID_MOUSE_EPIN_ADDR, /* bEndpointAddress: Endpoint Address (IN) */ - 0x03, /* bmAttributes: Interrupt endpoint */ - HID_MOUSE_EPIN_SIZE, /* wMaxPacketSize: 4 Byte max */ + HID_MOUSE_EPIN_ADDR, /* bEndpointAddress: Endpoint Address (IN) */ + 0x03, /* bmAttributes: Interrupt endpoint */ + HID_MOUSE_EPIN_SIZE, /* wMaxPacketSize: 4 Bytes max */ 0x00, - HID_FS_BINTERVAL, /* bInterval: Polling Interval */ + HID_FS_BINTERVAL, /* bInterval: Polling Interval */ /******************************************************************** Keyboard *********************************************************************/ /************** Descriptor of HID Keyboard interface ****************/ /* 34 */ - 0x09, /* bLength: Interface Descriptor size */ - USB_DESC_TYPE_INTERFACE, /* bDescriptorType: Interface descriptor type */ - HID_KEYBOARD_INTERFACE, /* bInterfaceNumber: Number of Interface */ - 0x00, /* bAlternateSetting: Alternate setting */ - 0x01, /* bNumEndpoints */ - 0x03, /* bInterfaceClass: HID */ - 0x01, /* bInterfaceSubClass : 1=BOOT, 0=no boot */ - 0x01, /* nInterfaceProtocol : 0=none, 1=keyboard, 2=mouse */ - 0x00, /* iInterface: Index of string descriptor */ + 0x09, /* bLength: Interface Descriptor size */ + USB_DESC_TYPE_INTERFACE, /* bDescriptorType: Interface descriptor type */ + HID_KEYBOARD_INTERFACE, /* bInterfaceNumber: Number of Interface */ + 0x00, /* bAlternateSetting: Alternate setting */ + 0x01, /* bNumEndpoints */ + 0x03, /* bInterfaceClass: HID */ + 0x01, /* bInterfaceSubClass : 1=BOOT, 0=no boot */ + 0x01, /* nInterfaceProtocol : 0=none, 1=keyboard, 2=mouse */ + 0x00, /* iInterface: Index of string descriptor */ /******************** HID Descriptor ********************/ /* 43 */ - 0x09, /* bLength: HID Descriptor size */ - HID_DESCRIPTOR_TYPE, /* bDescriptorType: HID */ - 0x11, /* bcdHID: HID Class Spec release number */ + 0x09, /* bLength: HID Descriptor size */ + HID_DESCRIPTOR_TYPE, /* bDescriptorType: HID */ + 0x11, /* bcdHID: HID Class Spec release number */ 0x01, - 0x00, /* bCountryCode: Hardware target country */ - 0x01, /* bNumDescriptors: Number of HID class descriptors to follow */ - 0x22, /* bDescriptorType */ - HID_KEYBOARD_REPORT_DESC_SIZE, /* wItemLength: Total length of Report descriptor */ + 0x00, /* bCountryCode: Hardware target country */ + 0x01, /* bNumDescriptors: Number of HID class descriptors to follow */ + 0x22, /* bDescriptorType */ + HID_KEYBOARD_REPORT_DESC_SIZE, /* wItemLength: Total length of Report descriptor */ 0x00, /******************** Descriptor of Keyboard endpoint ********************/ /* 52 */ - 0x07, /* bLength: Endpoint Descriptor size */ - USB_DESC_TYPE_ENDPOINT, /* bDescriptorType: */ - HID_KEYBOARD_EPIN_ADDR, /* bEndpointAddress: Endpoint Address (IN) */ - 0x03, /* bmAttributes: Interrupt endpoint */ - HID_KEYBOARD_EPIN_SIZE, /* wMaxPacketSize: 8 Byte max */ + 0x07, /* bLength: Endpoint Descriptor size */ + USB_DESC_TYPE_ENDPOINT, /* bDescriptorType: */ + HID_KEYBOARD_EPIN_ADDR, /* bEndpointAddress: Endpoint Address (IN) */ + 0x03, /* bmAttributes: Interrupt endpoint */ + HID_KEYBOARD_EPIN_SIZE, /* wMaxPacketSize: 8 Byte max */ 0x00, - HID_FS_BINTERVAL /* bInterval: Polling Interval */ + HID_FS_BINTERVAL /* bInterval: Polling Interval */ /* 59 */ } ; /* USB HID device Configuration Descriptor */ __ALIGN_BEGIN static uint8_t USBD_MOUSE_HID_Desc[USB_HID_DESC_SIZ] __ALIGN_END = { - 0x09, /* bLength: HID Descriptor size */ - HID_DESCRIPTOR_TYPE, /* bDescriptorType: HID */ - 0x11, /* bcdHID: HID Class Spec release number */ + 0x09, /* bLength: HID Descriptor size */ + HID_DESCRIPTOR_TYPE, /* bDescriptorType: HID */ + 0x11, /* bcdHID: HID Class Spec release number */ 0x01, - 0x00, /* bCountryCode: Hardware target country */ - 0x01, /* bNumDescriptors: Number of HID class descriptors to follow */ - 0x22, /* bDescriptorType */ - HID_MOUSE_REPORT_DESC_SIZE, /* wItemLength: Total length of Report descriptor */ + 0x00, /* bCountryCode: Hardware target country */ + 0x01, /* bNumDescriptors: Number of HID class descriptors to follow */ + 0x22, /* bDescriptorType */ + HID_MOUSE_REPORT_DESC_SIZE, /* wItemLength: Total length of Report descriptor */ 0x00 }; /* USB HID device Configuration Descriptor */ __ALIGN_BEGIN static uint8_t USBD_KEYBOARD_HID_Desc[USB_HID_DESC_SIZ] __ALIGN_END = { - 0x09, /* bLength: HID Descriptor size */ - HID_DESCRIPTOR_TYPE, /* bDescriptorType: HID */ - 0x11, /* bcdHID: HID Class Spec release number */ + 0x09, /* bLength: HID Descriptor size */ + HID_DESCRIPTOR_TYPE, /* bDescriptorType: HID */ + 0x11, /* bcdHID: HID Class Spec release number */ 0x01, - 0x00, /* bCountryCode: Hardware target country */ - 0x01, /* bNumDescriptors: Number of HID class descriptors to follow */ - 0x22, /* bDescriptorType */ - HID_KEYBOARD_REPORT_DESC_SIZE, /* wItemLength: Total length of Report descriptor */ + 0x00, /* bCountryCode: Hardware target country */ + 0x01, /* bNumDescriptors: Number of HID class descriptors to follow */ + 0x22, /* bDescriptorType */ + HID_KEYBOARD_REPORT_DESC_SIZE, /* wItemLength: Total length of Report descriptor */ 0x00, }; /* USB Standard Device Descriptor */ -__ALIGN_BEGIN static uint8_t USBD_HID_DeviceQualifierDesc[USB_LEN_DEV_QUALIFIER_DESC] __ALIGN_END = { +__ALIGN_BEGIN static uint8_t USBD_HID_DeviceQualifierDesc[USB_LEN_DEV_QUALIFIER_DESC] __ALIGN_END = { USB_LEN_DEV_QUALIFIER_DESC, USB_DESC_TYPE_DEVICE_QUALIFIER, 0x00, @@ -400,53 +416,45 @@ __ALIGN_BEGIN static uint8_t USBD_HID_DeviceQualifierDesc[USB_LEN_DEV_QUALIFIER_ 0x00, }; -__ALIGN_BEGIN static uint8_t HID_MOUSE_ReportDesc[HID_MOUSE_REPORT_DESC_SIZE] __ALIGN_END = { - 0x05, 0x01, - 0x09, 0x02, - 0xA1, 0x01, - 0x09, 0x01, - - 0xA1, 0x00, - 0x05, 0x09, - 0x19, 0x01, - 0x29, 0x03, - - 0x15, 0x00, - 0x25, 0x01, - 0x95, 0x03, - 0x75, 0x01, - - 0x81, 0x02, - 0x95, 0x01, - 0x75, 0x05, - 0x81, 0x01, - - 0x05, 0x01, - 0x09, 0x30, - 0x09, 0x31, - 0x09, 0x38, - - 0x15, 0x81, - 0x25, 0x7F, - 0x75, 0x08, - 0x95, 0x03, - - 0x81, 0x06, - 0xC0, 0x09, - 0x3c, 0x05, - 0xff, 0x09, - - 0x01, 0x15, - 0x00, 0x25, - 0x01, 0x75, - 0x01, 0x95, - - 0x02, 0xb1, - 0x22, 0x75, - 0x06, 0x95, - 0x01, 0xb1, - - 0x01, 0xc0 +__ALIGN_BEGIN static uint8_t HID_MOUSE_ReportDesc[HID_MOUSE_REPORT_DESC_SIZE] __ALIGN_END = { + 0x05, 0x01, /* Usage Page (Generic Desktop Ctrls) */ + 0x09, 0x02, /* Usage (Mouse) */ + 0xA1, 0x01, /* Collection (Application) */ + 0x09, 0x01, /* Usage (Pointer) */ + 0xA1, 0x00, /* Collection (Physical) */ + 0x05, 0x09, /* Usage Page (Button) */ + 0x19, 0x01, /* Usage Minimum (0x01) */ + 0x29, 0x03, /* Usage Maximum (0x03) */ + 0x15, 0x00, /* Logical Minimum (0) */ + 0x25, 0x01, /* Logical Maximum (1) */ + 0x95, 0x03, /* Report Count (3) */ + 0x75, 0x01, /* Report Size (1) */ + 0x81, 0x02, /* Input (Data,Var,Abs) */ + 0x95, 0x01, /* Report Count (1) */ + 0x75, 0x05, /* Report Size (5) */ + 0x81, 0x01, /* Input (Const,Array,Abs) */ + 0x05, 0x01, /* Usage Page (Generic Desktop Ctrls) */ + 0x09, 0x30, /* Usage (X) */ + 0x09, 0x31, /* Usage (Y) */ + 0x09, 0x38, /* Usage (Wheel) */ + 0x15, 0x81, /* Logical Minimum (-127) */ + 0x25, 0x7F, /* Logical Maximum (127) */ + 0x75, 0x08, /* Report Size (8) */ + 0x95, 0x03, /* Report Count (3) */ + 0x81, 0x06, /* Input (Data,Var,Rel) */ + 0xC0, /* End Collection */ + 0x09, 0x3C, /* Usage (Motion Wakeup) */ + 0x05, 0xFF, /* Usage Page (Reserved 0xFF) */ + 0x09, 0x01, /* Usage (0x01) */ + 0x15, 0x00, /* Logical Minimum (0) */ + 0x25, 0x01, /* Logical Maximum (1) */ + 0x75, 0x01, /* Report Size (1) */ + 0x95, 0x02, /* Report Count (2) */ + 0xB1, 0x22, /* Feature (Data,Var,Abs,NoWrp) */ + 0x75, 0x06, /* Report Size (6) */ + 0x95, 0x01, /* Report Count (1) */ + 0xB1, 0x01, /* Feature (Const,Array,Abs,NoWrp) */ + 0xC0 /* End Collection */ }; __ALIGN_BEGIN static uint8_t HID_KEYBOARD_ReportDesc[HID_KEYBOARD_REPORT_DESC_SIZE] __ALIGN_END = { @@ -494,13 +502,14 @@ __ALIGN_BEGIN static uint8_t HID_KEYBOARD_ReportDesc[HID_KEYBOARD_REPORT_DESC_SI * @param cfgidx: Configuration index * @retval status */ -static uint8_t USBD_HID_Init(USBD_HandleTypeDef *pdev, - uint8_t cfgidx) +static uint8_t USBD_HID_Init(USBD_HandleTypeDef *pdev, + uint8_t cfgidx) { UNUSED(cfgidx); + USBD_HID_HandleTypeDef *hhid; - hhid = USBD_malloc(sizeof(USBD_HID_HandleTypeDef)); + hhid = (USBD_HID_HandleTypeDef *)USBD_malloc(sizeof(USBD_HID_HandleTypeDef)); if (hhid == NULL) { pdev->pClassData = NULL; @@ -534,25 +543,28 @@ static uint8_t USBD_HID_Init(USBD_HandleTypeDef *pdev, } /** - * @brief USBD_HID_Init + * @brief USBD_HID_DeInit * DeInitialize the HID layer * @param pdev: device instance * @param cfgidx: Configuration index * @retval status */ -static uint8_t USBD_HID_DeInit(USBD_HandleTypeDef *pdev, - uint8_t cfgidx) +static uint8_t USBD_HID_DeInit(USBD_HandleTypeDef *pdev, + uint8_t cfgidx) { UNUSED(cfgidx); + /* Close HID EPs */ (void)USBD_LL_CloseEP(pdev, HID_MOUSE_EPIN_ADDR); pdev->ep_in[HID_MOUSE_EPIN_ADDR & 0xFU].is_used = 0U; + pdev->ep_in[HID_MOUSE_EPIN_ADDR & 0xFU].bInterval = 0U; USBD_LL_CloseEP(pdev, HID_KEYBOARD_EPIN_ADDR); pdev->ep_in[HID_KEYBOARD_EPIN_ADDR & 0xFU].is_used = 0U; + pdev->ep_in[HID_KEYBOARD_EPIN_ADDR & 0xFU].bInterval = 0U; /* Free allocated memory */ if (pdev->pClassData != NULL) { - USBD_free(pdev->pClassData); + (void)USBD_free(pdev->pClassData); pdev->pClassData = NULL; } @@ -587,11 +599,15 @@ static uint8_t USBD_COMPOSITE_HID_Setup(USBD_HandleTypeDef *pdev, static uint8_t USBD_HID_MOUSE_Setup(USBD_HandleTypeDef *pdev, USBD_SetupReqTypedef *req) { - USBD_HID_HandleTypeDef *hhid = (USBD_HID_HandleTypeDef *) pdev->pClassData; + USBD_HID_HandleTypeDef *hhid = (USBD_HID_HandleTypeDef *)pdev->pClassData; + USBD_StatusTypeDef ret = USBD_OK; uint16_t len = 0U; uint8_t *pbuf = NULL; uint16_t status_info = 0U; - USBD_StatusTypeDef ret = USBD_OK; + + if (hhid == NULL) { + return (uint8_t)USBD_FAIL; + } switch (req->bmRequest & USB_REQ_TYPE_MASK) { case USB_REQ_TYPE_CLASS: @@ -618,7 +634,6 @@ static uint8_t USBD_HID_MOUSE_Setup(USBD_HandleTypeDef *pdev, break; } break; - case USB_REQ_TYPE_STANDARD: switch (req->bRequest) { case USB_REQ_GET_STATUS: @@ -664,6 +679,9 @@ static uint8_t USBD_HID_MOUSE_Setup(USBD_HandleTypeDef *pdev, } break; + case USB_REQ_CLEAR_FEATURE: + break; + default: USBD_CtlError(pdev, req); ret = USBD_FAIL; @@ -769,6 +787,9 @@ static uint8_t USBD_HID_KEYBOARD_Setup(USBD_HandleTypeDef *pdev, } break; + case USB_REQ_CLEAR_FEATURE: + break; + default: USBD_CtlError(pdev, req); ret = USBD_FAIL; @@ -796,14 +817,12 @@ uint8_t USBD_HID_MOUSE_SendReport(USBD_HandleTypeDef *pdev, uint8_t *report, uint16_t len) { - USBD_HID_HandleTypeDef *hhid; + USBD_HID_HandleTypeDef *hhid = (USBD_HID_HandleTypeDef *)pdev->pClassData; - if (pdev->pClassData == NULL) { + if (hhid == NULL) { return (uint8_t)USBD_FAIL; } - hhid = (USBD_HID_HandleTypeDef *)pdev->pClassData; - if (pdev->dev_state == USBD_STATE_CONFIGURED) { if (hhid->Mousestate == HID_IDLE) { hhid->Mousestate = HID_BUSY; @@ -826,13 +845,12 @@ uint8_t USBD_HID_KEYBOARD_SendReport(USBD_HandleTypeDef *pdev, uint8_t *report, uint16_t len) { - USBD_HID_HandleTypeDef *hhid; + USBD_HID_HandleTypeDef *hhid = (USBD_HID_HandleTypeDef *)pdev->pClassData; - if (pdev->pClassData == NULL) { + if (hhid == NULL) { return (uint8_t)USBD_FAIL; } - hhid = (USBD_HID_HandleTypeDef *)pdev->pClassData; if (pdev->dev_state == USBD_STATE_CONFIGURED) { if (hhid->Keyboardstate == HID_IDLE) { @@ -880,6 +898,7 @@ uint32_t USBD_HID_GetPollingInterval(USBD_HandleTypeDef *pdev) static uint8_t *USBD_HID_GetFSCfgDesc(uint16_t *length) { *length = (uint16_t)sizeof(USBD_HID_CfgFSDesc); + return USBD_HID_CfgFSDesc; } @@ -893,6 +912,7 @@ static uint8_t *USBD_HID_GetFSCfgDesc(uint16_t *length) static uint8_t *USBD_HID_GetHSCfgDesc(uint16_t *length) { *length = (uint16_t)sizeof(USBD_HID_CfgHSDesc); + return USBD_HID_CfgHSDesc; } @@ -903,9 +923,10 @@ static uint8_t *USBD_HID_GetHSCfgDesc(uint16_t *length) * @param length : pointer data length * @retval pointer to descriptor buffer */ -static uint8_t *USBD_HID_GetOtherSpeedCfgDesc(uint16_t *length) +static uint8_t *USBD_HID_GetOtherSpeedCfgDesc(uint16_t *length) { *length = (uint16_t)sizeof(USBD_HID_OtherSpeedCfgDesc); + return USBD_HID_OtherSpeedCfgDesc; } @@ -932,14 +953,15 @@ static uint8_t USBD_HID_DataIn(USBD_HandleTypeDef *pdev, /** -* @brief DeviceQualifierDescriptor -* return Device Qualifier descriptor -* @param length : pointer data length -* @retval pointer to descriptor buffer -*/ + * @brief DeviceQualifierDescriptor + * return Device Qualifier descriptor + * @param length : pointer data length + * @retval pointer to descriptor buffer + */ static uint8_t *USBD_HID_GetDeviceQualifierDesc(uint16_t *length) { *length = (uint16_t)sizeof(USBD_HID_DeviceQualifierDesc); + return USBD_HID_DeviceQualifierDesc; } #endif /* USBD_USE_HID_COMPOSITE */ diff --git a/cores/arduino/stm32/usb/usbd_conf.c b/cores/arduino/stm32/usb/usbd_conf.c index 228e965632..6dcfa66c4e 100644 --- a/cores/arduino/stm32/usb/usbd_conf.c +++ b/cores/arduino/stm32/usb/usbd_conf.c @@ -73,23 +73,22 @@ void HAL_PCD_MspInit(PCD_HandleTypeDef *hpcd) /* Enable USB FS Clock */ __HAL_RCC_USB_CLK_ENABLE(); -#if defined (USE_USB_INTERRUPT_REMAPPED) - /*USB interrupt remapping enable */ +#if defined(SYSCFG_CFGR1_USB_IT_RMP) && defined(USE_USB_INTERRUPT_REMAPPED) + /* USB interrupt remapping enable */ __HAL_REMAPINTERRUPT_USB_ENABLE(); #endif -#if defined(STM32G4xx) || defined(STM32WBxx) +#if defined(USB_H_IRQn) + /* Set USB High priority Interrupt priority */ HAL_NVIC_SetPriority(USB_HP_IRQn, USBD_IRQ_PRIO, USBD_IRQ_SUBPRIO); + /* Enable USB High priority Interrupt */ HAL_NVIC_EnableIRQ(USB_HP_IRQn); - HAL_NVIC_SetPriority(USB_LP_IRQn, USBD_IRQ_PRIO, USBD_IRQ_SUBPRIO); - HAL_NVIC_EnableIRQ(USB_LP_IRQn); -#else - /* Set USB FS Interrupt priority */ +#endif + /* Set USB Interrupt priority */ HAL_NVIC_SetPriority(USB_IRQn, USBD_IRQ_PRIO, USBD_IRQ_SUBPRIO); - /* Enable USB FS Interrupt */ + /* Enable USB Interrupt */ HAL_NVIC_EnableIRQ(USB_IRQn); -#endif /* STM32WBxx */ if (hpcd->Init.low_power_enable == 1) { /* Enable EXTI for USB wakeup */ @@ -100,12 +99,12 @@ void HAL_PCD_MspInit(PCD_HandleTypeDef *hpcd) __HAL_USB_WAKEUP_EXTI_ENABLE_RISING_EDGE(); #endif __HAL_USB_WAKEUP_EXTI_ENABLE_IT(); -#if defined(STM32F1xx) || defined(STM32F3xx) +#if defined(USB_WKUP_IRQn) /* USB Wakeup Interrupt */ - HAL_NVIC_EnableIRQ(USBWakeUp_IRQn); + HAL_NVIC_EnableIRQ(USB_WKUP_IRQn); /* Enable USB Wake-up interrupt */ - HAL_NVIC_SetPriority(USBWakeUp_IRQn, 0, 0); + HAL_NVIC_SetPriority(USB_WKUP_IRQn, 0, 0); #endif } } @@ -163,7 +162,7 @@ void HAL_PCD_MspInit(PCD_HandleTypeDef *hpcd) /* Enable USB HS Clocks */ __HAL_RCC_USB_OTG_HS_CLK_ENABLE(); - /* Set USBHS Interrupt priority */ + /* Set USB HS Interrupt priority */ HAL_NVIC_SetPriority(OTG_HS_IRQn, USBD_IRQ_PRIO, USBD_IRQ_SUBPRIO); /* Enable USB HS Interrupt */ @@ -318,7 +317,7 @@ void HAL_PCD_SuspendCallback(PCD_HandleTypeDef *hpcd) void HAL_PCD_ResumeCallback(PCD_HandleTypeDef *hpcd) { if (hpcd->Init.low_power_enable) { - SystemClock_Config(); + USBD_SystemClockConfigFromResume(); /* Reset SLEEPDEEP bit of Cortex System Control Register */ SCB->SCR &= (uint32_t)~((uint32_t)(SCB_SCR_SLEEPDEEP_Msk | SCB_SCR_SLEEPONEXIT_Msk)); @@ -369,8 +368,6 @@ void HAL_PCD_DisconnectCallback(PCD_HandleTypeDef *hpcd) USBD_LL_DevDisconnected(hpcd->pData); } - - /** * @brief This function handles USB-On-The-Go FS/HS global interrupt request. * @param None @@ -387,29 +384,20 @@ void HAL_PCD_DisconnectCallback(PCD_HandleTypeDef *hpcd) HAL_PCD_IRQHandler(&g_hpcd); } -#if defined(STM32WBxx) +#if defined(USB_H_IRQn) /** * @brief This function handles USB high priority interrupt. * @param None * @retval None */ -void USB_HP_IRQHandler(void) +void USB_H_IRQHandler(void) { HAL_PCD_IRQHandler(&g_hpcd); } +#endif /* USB_H_IRQn */ /** - * @brief This function handles USB low priority interrupt, USB wake-up interrupt through EXTI line 28. - * @param None - * @retval None - */ -void USB_LP_IRQHandler(void) -{ - HAL_PCD_IRQHandler(&g_hpcd); -} -#else -/** - * @brief This function handles USB OTG FS Wakeup IRQ Handler. + * @brief This function handles USB Wakeup IRQ Handler. * @param None * @retval None */ @@ -417,17 +405,18 @@ void USB_LP_IRQHandler(void) void OTG_HS_WKUP_IRQHandler(void) #elif defined(USB_OTG_FS) void OTG_FS_WKUP_IRQHandler(void) +#elif defined(USB_WKUP_IRQHandler) + void USB_WKUP_IRQHandler(void) #else - void USBWakeUp_IRQHandler(void) + void USBWakeUp_IRQHandler_dummy(void) #endif { if ((&g_hpcd)->Init.low_power_enable) { /* Reset SLEEPDEEP bit of Cortex System Control Register */ SCB->SCR &= (uint32_t)~((uint32_t)(SCB_SCR_SLEEPDEEP_Msk | SCB_SCR_SLEEPONEXIT_Msk)); - /* Configures system clock after wake-up from STOP: enable HSE, PLL and select - PLL as system clock source (HSE and PLL are disabled in STOP mode) */ - SystemClock_Config(); + /* Configures system clock after wake-up */ + USBD_SystemClockConfigFromResume(); /* ungate PHY clock */ __HAL_PCD_UNGATE_PHYCLOCK((&g_hpcd)); @@ -442,7 +431,7 @@ void USB_LP_IRQHandler(void) __HAL_USB_WAKEUP_EXTI_CLEAR_FLAG(); #endif } -#endif + /******************************************************************************* LL Driver Interface (USB Device Library --> PCD) *******************************************************************************/ @@ -644,7 +633,7 @@ uint8_t USBD_LL_IsStallEP(USBD_HandleTypeDef *pdev, uint8_t ep_addr) /** * @brief Assigns a USB address to the device. * @param pdev: Device handle - * @param ep_addr: Endpoint Number + * @param dev_addr: Endpoint Number * @retval USBD Status */ USBD_StatusTypeDef USBD_LL_SetUSBAddress(USBD_HandleTypeDef *pdev, uint8_t dev_addr) diff --git a/cores/arduino/stm32/usb/usbd_conf.h b/cores/arduino/stm32/usb/usbd_conf.h index f1479599ab..3cb2894241 100644 --- a/cores/arduino/stm32/usb/usbd_conf.h +++ b/cores/arduino/stm32/usb/usbd_conf.h @@ -42,24 +42,34 @@ extern "C" { #if defined(USB_BASE) -#if defined(STM32F1xx) -#define USB_IRQn USB_LP_CAN1_RX0_IRQn -#define USB_IRQHandler USB_LP_CAN1_RX0_IRQHandler -#elif defined(STM32F3xx) -/* ToDo: Check remap on USB_LP_IRQn */ -#ifndef USE_USB_INTERRUPT_REMAPPED -#define USB_IRQn USB_LP_CAN_RX0_IRQn -#define USB_IRQHandler USB_LP_CAN_RX0_IRQHandler +#if defined(STM32F1xx) || defined(STM32F3xx) || defined(STM32G4xx) || \ + defined(STM32L1xx) || defined(STM32WBxx) +#if defined(SYSCFG_CFGR1_USB_IT_RMP) && !defined(USE_USB_INTERRUPT_REMAPPED) +#define USB_IRQn USB_LP_CAN_RX0_IRQn +#define USB_IRQHandler USB_LP_CAN_RX0_IRQHandler +#define USB_H_IRQn USB_HP_CAN_TX_IRQn +#define USB_H_IRQHandler USB_HP_CAN_TX_IRQHandler +#define USB_WKUP_IRQn USBWakeUp_IRQn +#define USB_WKUP_IRQHandler USBWakeUp_IRQHandler #else -#define USB_IRQn USB_LP_IRQn -#define USB_IRQHandler USB_LP_IRQHandler -#endif /* USE_USB_INTERRUPT_REMAPPED */ +#define USB_IRQn USB_LP_IRQn +#define USB_IRQHandler USB_LP_IRQHandler +#define USB_H_IRQn USB_HP_IRQn +#define USB_H_IRQHandler USB_HP_IRQHandler +#if defined(SYSCFG_CFGR1_USB_IT_RMP) && defined(USE_USB_INTERRUPT_REMAPPED) +#define USB_WKUP_IRQn USBWakeUp_RMP_IRQn +#define USB_WKUP_IRQHandler USBWakeUp_RMP_IRQHandler +#elif defined(STM32F1xx) || defined(STM32F3xx) || defined(STM32G4xx) +#define USB_WKUP_IRQn USBWakeUp_IRQn +#define USB_WKUP_IRQHandler USBWakeUp_IRQHandler #elif defined(STM32L1xx) -#define USB_IRQn USB_LP_IRQn -#define USB_IRQHandler USB_LP_IRQHandler +#define USB_WKUP_IRQn USB_FS_WKUP_IRQn +#define USB_WKUP_IRQHandler USB_FS_WKUP_IRQHandler +#endif +#endif #elif defined(STM32L5xx) -#define USB_IRQn USB_FS_IRQn -#define USB_IRQHandler USB_FS_IRQHandler +#define USB_IRQn USB_FS_IRQn +#define USB_IRQHandler USB_FS_IRQHandler #endif #endif /* USB_BASE */ @@ -73,97 +83,190 @@ extern "C" { #endif #ifndef USBD_MAX_NUM_INTERFACES -#define USBD_MAX_NUM_INTERFACES 2U +#define USBD_MAX_NUM_INTERFACES 2U #endif /* USBD_MAX_NUM_INTERFACES */ #ifndef USBD_MAX_NUM_CONFIGURATION -#define USBD_MAX_NUM_CONFIGURATION 1U +#define USBD_MAX_NUM_CONFIGURATION 1U #endif /* USBD_MAX_NUM_CONFIGURATION */ #ifndef USBD_MAX_STR_DESC_SIZ -#define USBD_MAX_STR_DESC_SIZ 0x100U +#define USBD_MAX_STR_DESC_SIZ 0x100U #endif /* USBD_MAX_STR_DESC_SIZ */ #ifndef USBD_SELF_POWERED -#define USBD_SELF_POWERED 1U +#define USBD_SELF_POWERED 1U #endif /* USBD_SELF_POWERED */ #ifndef USBD_DEBUG_LEVEL -#define USBD_DEBUG_LEVEL 0U +#define USBD_DEBUG_LEVEL 0U #endif /* USBD_DEBUG_LEVEL */ /* ECM, RNDIS, DFU Class Config */ #ifndef USBD_SUPPORT_USER_STRING_DESC -#define USBD_SUPPORT_USER_STRING_DESC 0U +#define USBD_SUPPORT_USER_STRING_DESC 0U #endif /* USBD_SUPPORT_USER_STRING_DESC */ /* BillBoard Class Config */ #ifndef USBD_CLASS_USER_STRING_DESC -#define USBD_CLASS_USER_STRING_DESC 1U +#define USBD_CLASS_USER_STRING_DESC 1U #endif /* USBD_CLASS_USER_STRING_DESC */ #ifndef USBD_CLASS_BOS_ENABLED -#define USBD_CLASS_BOS_ENABLED 0U +#define USBD_CLASS_BOS_ENABLED 0U #endif /* USBD_CLASS_BOS_ENABLED */ #ifndef USB_BB_MAX_NUM_ALT_MODE -#define USB_BB_MAX_NUM_ALT_MODE 0x2U +#define USB_BB_MAX_NUM_ALT_MODE 0x2U #endif /* USB_BB_MAX_NUM_ALT_MODE */ /* MSC Class Config */ #ifndef MSC_MEDIA_PACKET -#define MSC_MEDIA_PACKET 8192U +#define MSC_MEDIA_PACKET 8192U #endif /* MSC_MEDIA_PACKET */ /* CDC Class Config */ #ifndef USBD_CDC_INTERVAL -#define USBD_CDC_INTERVAL 2000U +#define USBD_CDC_INTERVAL 2000U #endif /* USBD_CDC_INTERVAL */ /* DFU Class Config */ #ifndef USBD_DFU_MAX_ITF_NUM -#define USBD_DFU_MAX_ITF_NUM 1U +#define USBD_DFU_MAX_ITF_NUM 1U #endif /* USBD_DFU_MAX_ITF_NUM */ #ifndef USBD_DFU_XFERS_IZE -#define USBD_DFU_XFERS_IZE 1024U +#define USBD_DFU_XFERS_IZE 1024U #endif /* USBD_DFU_XFERS_IZE */ /* AUDIO Class Config */ #ifndef USBD_AUDIO_FREQ -#define USBD_AUDIO_FREQ 22100U +#define USBD_AUDIO_FREQ 22100U #endif /* USBD_AUDIO_FREQ */ +/* CustomHID Class Config */ +#ifndef CUSTOM_HID_HS_BINTERVAL +#define CUSTOM_HID_HS_BINTERVAL 0x05U +#endif /* CUSTOM_HID_HS_BINTERVAL */ +#ifndef CUSTOM_HID_FS_BINTERVAL +#define CUSTOM_HID_FS_BINTERVAL 0x05U +#endif /* CUSTOM_HID_FS_BINTERVAL */ +#ifndef USBD_CUSTOMHID_OUTREPORT_BUF_SIZE +#define USBD_CUSTOMHID_OUTREPORT_BUF_SIZE 0x02U +#endif /* USBD_CUSTOMHID_OUTREPORT_BUF_SIZE */ +#ifndef USBD_CUSTOM_HID_REPORT_DESC_SIZE +#define USBD_CUSTOM_HID_REPORT_DESC_SIZE 163U +#endif /* USBD_CUSTOM_HID_REPORT_DESC_SIZE */ + +/* VIDEO Class Config */ +#ifndef UVC_1_1 +#define UVC_1_1 /* #define UVC_1_0 */ +#endif /* UVC_1_1 */ + +/* To be used only with YUY2 and NV12 Video format, shouldn't be defined for MJPEG format */ +#ifndef USBD_UVC_FORMAT_UNCOMPRESSED +#define USBD_UVC_FORMAT_UNCOMPRESSED +#endif /* USBD_UVC_FORMAT_UNCOMPRESSED */ + +#ifdef USBD_UVC_FORMAT_UNCOMPRESSED +#ifndef UVC_BITS_PER_PIXEL +#define UVC_BITS_PER_PIXEL 12U +#endif /* UVC_BITS_PER_PIXEL */ +#ifndef UVC_UNCOMPRESSED_GUID +#define UVC_UNCOMPRESSED_GUID UVC_GUID_NV12 /* UVC_GUID_YUY2 */ +#endif /* UVC_UNCOMPRESSED_GUID */ + +/* refer to Table 3-18 Color Matching Descriptor video class v1.1 */ +#ifndef UVC_COLOR_PRIMARIE +#define UVC_COLOR_PRIMARIE 0x01U +#endif /* UVC_COLOR_PRIMARIE */ +#ifndef UVC_TFR_CHARACTERISTICS +#define UVC_TFR_CHARACTERISTICS 0x01U +#endif /* UVC_TFR_CHARACTERISTICS */ +#ifndef UVC_MATRIX_COEFFICIENTS +#define UVC_MATRIX_COEFFICIENTS 0x04U +#endif /* UVC_MATRIX_COEFFICIENTS */ +#endif + +/* Video Stream frame width and height */ +#ifndef UVC_WIDTH +#define UVC_WIDTH 176U +#endif /* UVC_WIDTH */ +#ifndef UVC_HEIGHT +#define UVC_HEIGHT 144U +#endif /* UVC_HEIGHT */ + +/* bEndpointAddress in Endpoint Descriptor */ +#ifndef UVC_IN_EP +#define UVC_IN_EP 0x81U +#endif /* UVC_IN_EP */ + +#ifndef UVC_CAM_FPS_FS +#define UVC_CAM_FPS_FS 10U +#endif /* UVC_CAM_FPS_FS */ +#ifndef UVC_CAM_FPS_HS +#define UVC_CAM_FPS_HS 5U +#endif /* UVC_CAM_FPS_HS */ + +#ifndef UVC_ISO_HS_MPS +#define UVC_ISO_FS_MPS 512U +#endif /* UVC_ISO_HS_MPS */ +#ifndef UVC_ISO_HS_MPS +#define UVC_ISO_HS_MPS 512U +#endif /* UVC_ISO_HS_MPS */ + +#ifndef UVC_PACKET_SIZE +#define UVC_PACKET_SIZE UVC_ISO_FS_MPS +#endif /* UVC_PACKET_SIZE */ +/* To be used with Device Only IP supporting double buffer mode */ +/* #define UVC_HEADER_PACKET_CNT 0x02U */ +/* #define UVC_PACKET_SIZE (UVC_ISO_FS_MPS * UVC_HEADER_PACKET_CNT) */ + +#ifndef UVC_MAX_FRAME_SIZE +#define UVC_MAX_FRAME_SIZE (UVC_WIDTH * UVC_HEIGHT * 16U / 8U) +#endif /* UVC_MAX_FRAME_SIZE */ + /* Interrupt priority */ #ifndef USBD_IRQ_PRIO -#define USBD_IRQ_PRIO 1 +#define USBD_IRQ_PRIO 1 #endif /* USBD_IRQ_PRIO */ + #ifndef USBD_IRQ_SUBPRIO -#define USBD_IRQ_SUBPRIO 0 +#define USBD_IRQ_SUBPRIO 0 #endif /* USBD_IRQ_SUBPRIO */ -/* Memory management macros */ +/* Memory management macros make sure to use static memory allocation */ +/* Currently dynamic memory allocation usage */ +/** Alias for memory allocation. */ #ifndef USBD_malloc -#define USBD_malloc malloc +#define USBD_malloc malloc #endif /* USBD_malloc */ + +/** Alias for memory release. */ #ifndef USBD_free -#define USBD_free free +#define USBD_free free #endif /* USBD_free */ + +/** Alias for memory set. */ #ifndef USBD_memset -#define USBD_memset memset +#define USBD_memset memset #endif /* USBD_memset */ + +/** Alias for memory copy. */ #ifndef USBD_memcpy -#define USBD_memcpy memcpy +#define USBD_memcpy memcpy #endif /* USBD_memcpy */ + +/** Alias for delay. */ #ifndef USBD_Delay -#define USBD_Delay HAL_Delay +#define USBD_Delay HAL_Delay #endif /* USBD_Delay */ /* DEBUG macros */ #if (USBD_DEBUG_LEVEL > 0U) #define USBD_UsrLog(...) do { \ - printf(__VA_ARGS__); \ - printf("\n"); \ -} while (0) + printf(__VA_ARGS__); \ + printf("\n"); \ + } while (0) #else #define USBD_UsrLog(...) do {} while (0) #endif @@ -171,24 +274,28 @@ extern "C" { #if (USBD_DEBUG_LEVEL > 1U) #define USBD_ErrLog(...) do { \ - printf("ERROR: ") ; \ - printf(__VA_ARGS__); \ - printf("\n"); \ -} while (0) + printf("ERROR: ") ; \ + printf(__VA_ARGS__); \ + printf("\n"); \ + } while (0) #else #define USBD_ErrLog(...) do {} while (0) #endif #if (USBD_DEBUG_LEVEL > 2U) #define USBD_DbgLog(...) do { \ - printf("DEBUG : ") ; \ - printf(__VA_ARGS__); \ - printf("\n"); \ -} while (0) + printf("DEBUG : ") ; \ + printf(__VA_ARGS__); \ + printf("\n"); \ + } while (0) #else #define USBD_DbgLog(...) do {} while (0) #endif +/* Exported functions -------------------------------------------------------*/ +void *USBD_static_malloc(uint32_t size); +void USBD_static_free(void *p); + #endif /* USBCON */ #ifdef __cplusplus diff --git a/cores/arduino/stm32/usb/usbd_desc.c b/cores/arduino/stm32/usb/usbd_desc.c index 229112ea5f..6474dba238 100644 --- a/cores/arduino/stm32/usb/usbd_desc.c +++ b/cores/arduino/stm32/usb/usbd_desc.c @@ -257,8 +257,8 @@ __ALIGN_BEGIN uint8_t USBD_BOSDesc[USB_SIZ_BOS_DESC] __ALIGN_END = { 0x00, /* bAlternateMode[0] Index of the Alternate Mode within the SVID as returned in response to a Discover Modes command. Example: - 0 � first Mode entry - 1 � second mode entry */ + 0 first Mode entry + 1 second mode entry */ USBD_BB_ALTMODE0_STRING_INDEX, /* iAlternateModeString[0]: Index of string descriptor describing protocol. It is optional to support this string. */ @@ -268,8 +268,8 @@ __ALIGN_BEGIN uint8_t USBD_BOSDesc[USB_SIZ_BOS_DESC] __ALIGN_END = { 0x01, /* bAlternateMode[1] Index of the Alternate Mode within the SVID as returned in response to a Discover Modes command. Example: - 0 � first Mode entry - 1 � second Mode entry */ + 0 first Mode entry + 1 second Mode entry */ USBD_BB_ALTMODE1_STRING_INDEX, /* iAlternateModeString[1]: Index of string descriptor describing protocol. It is optional to support this string. */ diff --git a/cores/arduino/stm32/usb/usbd_desc.h b/cores/arduino/stm32/usb/usbd_desc.h index 3264b93263..bb757e939a 100644 --- a/cores/arduino/stm32/usb/usbd_desc.h +++ b/cores/arduino/stm32/usb/usbd_desc.h @@ -27,8 +27,8 @@ /* Exported types ------------------------------------------------------------*/ /* Exported constants --------------------------------------------------------*/ #define DEVICE_ID1 (UID_BASE) - #define DEVICE_ID2 (UID_BASE + 0x4) - #define DEVICE_ID3 (UID_BASE + 0x8) + #define DEVICE_ID2 (UID_BASE + 0x4U) + #define DEVICE_ID3 (UID_BASE + 0x8U) /* * USB Billboard Class USER string desc Defines Template @@ -46,7 +46,7 @@ #define USBD_BB_ALTMODE1_STR_DESC (uint8_t *)"STM32 Alternate1 Mode" #endif - #define USB_SIZ_STRING_SERIAL 0x1A + #define USB_SIZ_STRING_SERIAL 0x1AU #if (USBD_LPM_ENABLED == 1) #define USB_SIZ_BOS_DESC 0x0CU diff --git a/cores/arduino/stm32/usb/usbd_if.c b/cores/arduino/stm32/usb/usbd_if.c index 046912062f..d0a87a79c5 100644 --- a/cores/arduino/stm32/usb/usbd_if.c +++ b/cores/arduino/stm32/usb/usbd_if.c @@ -175,4 +175,19 @@ void USBD_CDC_init(void) CDC_init(); } #endif /* USBD_USE_CDC */ + +/** + * @brief Configures system clock and system IP clocks after wake-up from USB + * resume callBack + * @note Weaked function which can be redefined by user at the sketch level. + * By default, calls 'SystemClock_Config()'. + * @param None + * @retval None + */ +WEAK void USBD_SystemClockConfigFromResume(void) +{ + configIPClock(); + SystemClock_Config(); +} + #endif /* USBCON */ diff --git a/cores/arduino/stm32/usb/usbd_if.h b/cores/arduino/stm32/usb/usbd_if.h index dc026240fe..b21a328db0 100644 --- a/cores/arduino/stm32/usb/usbd_if.h +++ b/cores/arduino/stm32/usb/usbd_if.h @@ -27,6 +27,10 @@ void USBD_reenumerate(void); #ifdef USBD_USE_CDC void USBD_CDC_init(void); #endif + +/* Weaked function */ +void USBD_SystemClockConfigFromResume(void); + #ifdef __cplusplus } #endif diff --git a/libraries/SrcWrapper/src/stm32/hw_config.c b/libraries/SrcWrapper/src/stm32/hw_config.c index b0b0eb518c..7eb8562f47 100644 --- a/libraries/SrcWrapper/src/stm32/hw_config.c +++ b/libraries/SrcWrapper/src/stm32/hw_config.c @@ -28,6 +28,11 @@ void hw_config_init(void) { configIPClock(); +#if defined(PWR_CR3_UCPD_DBDIS) || defined(STM32L5xx) + /* Disable the internal Pull-Up in Dead Battery pins of UCPD peripheral */ + HAL_PWREx_DisableUCPDDeadBattery(); +#endif + /* Init DWT if present */ #ifdef DWT_BASE dwt_init(); diff --git a/system/Middlewares/ST/STM32_USB_Device_Library/Class/AUDIO/Src/usbd_audio.c b/system/Middlewares/ST/STM32_USB_Device_Library/Class/AUDIO/Src/usbd_audio.c index 1dce51a31a..acaaf053c0 100644 --- a/system/Middlewares/ST/STM32_USB_Device_Library/Class/AUDIO/Src/usbd_audio.c +++ b/system/Middlewares/ST/STM32_USB_Device_Library/Class/AUDIO/Src/usbd_audio.c @@ -157,13 +157,17 @@ __ALIGN_BEGIN static uint8_t USBD_AUDIO_CfgDesc[USB_AUDIO_CONFIG_DESC_SIZ] __ALI /* Configuration 1 */ 0x09, /* bLength */ USB_DESC_TYPE_CONFIGURATION, /* bDescriptorType */ - LOBYTE(USB_AUDIO_CONFIG_DESC_SIZ), /* wTotalLength 109 bytes*/ + LOBYTE(USB_AUDIO_CONFIG_DESC_SIZ), /* wTotalLength */ HIBYTE(USB_AUDIO_CONFIG_DESC_SIZ), 0x02, /* bNumInterfaces */ 0x01, /* bConfigurationValue */ 0x00, /* iConfiguration */ - 0xC0, /* bmAttributes BUS Powred*/ - 0x32, /* bMaxPower = 100 mA*/ +#if (USBD_SELF_POWERED == 1U) + 0xC0, /* bmAttributes: Bus Powered according to user configuration */ +#else + 0x80, /* bmAttributes: Bus Powered according to user configuration */ +#endif + USBD_MAX_POWER, /* MaxPower (mA) */ /* 09 byte*/ /* USB Speaker Standard interface descriptor */ @@ -184,7 +188,7 @@ __ALIGN_BEGIN static uint8_t USBD_AUDIO_CfgDesc[USB_AUDIO_CONFIG_DESC_SIZ] __ALI AUDIO_CONTROL_HEADER, /* bDescriptorSubtype */ 0x00, /* 1.00 */ /* bcdADC */ 0x01, - 0x27, /* wTotalLength = 39*/ + 0x27, /* wTotalLength */ 0x00, 0x01, /* bInCollection */ 0x01, /* baInterfaceNr */ @@ -215,22 +219,22 @@ __ALIGN_BEGIN static uint8_t USBD_AUDIO_CfgDesc[USB_AUDIO_CONFIG_DESC_SIZ] __ALI AUDIO_CONTROL_MUTE, /* bmaControls(0) */ 0, /* bmaControls(1) */ 0x00, /* iTerminal */ - /* 09 byte*/ + /* 09 byte */ - /*USB Speaker Output Terminal Descriptor */ + /* USB Speaker Output Terminal Descriptor */ 0x09, /* bLength */ AUDIO_INTERFACE_DESCRIPTOR_TYPE, /* bDescriptorType */ AUDIO_CONTROL_OUTPUT_TERMINAL, /* bDescriptorSubtype */ 0x03, /* bTerminalID */ - 0x01, /* wTerminalType 0x0301*/ + 0x01, /* wTerminalType 0x0301 */ 0x03, 0x00, /* bAssocTerminal */ 0x02, /* bSourceID */ 0x00, /* iTerminal */ - /* 09 byte*/ + /* 09 byte */ - /* USB Speaker Standard AS Interface Descriptor - Audio Streaming Zero Bandwith */ - /* Interface 1, Alternate Setting 0 */ + /* USB Speaker Standard AS Interface Descriptor - Audio Streaming Zero Bandwidth */ + /* Interface 1, Alternate Setting 0 */ AUDIO_INTERFACE_DESC_SIZE, /* bLength */ USB_DESC_TYPE_INTERFACE, /* bDescriptorType */ 0x01, /* bInterfaceNumber */ @@ -288,7 +292,7 @@ __ALIGN_BEGIN static uint8_t USBD_AUDIO_CfgDesc[USB_AUDIO_CONFIG_DESC_SIZ] __ALI 0x00, /* bSynchAddress */ /* 09 byte*/ - /* Endpoint - Audio Streaming Descriptor*/ + /* Endpoint - Audio Streaming Descriptor */ AUDIO_STREAMING_ENDPOINT_DESC_SIZE, /* bLength */ AUDIO_ENDPOINT_DESCRIPTOR_TYPE, /* bDescriptorType */ AUDIO_ENDPOINT_GENERAL, /* bDescriptor */ @@ -334,8 +338,8 @@ static uint8_t USBD_AUDIO_Init(USBD_HandleTypeDef *pdev, uint8_t cfgidx) UNUSED(cfgidx); USBD_AUDIO_HandleTypeDef *haudio; - /* Allocate Audio structure */ - haudio = USBD_malloc(sizeof(USBD_AUDIO_HandleTypeDef)); + /* Allocate Audio structure */ + haudio = (USBD_AUDIO_HandleTypeDef *)USBD_malloc(sizeof(USBD_AUDIO_HandleTypeDef)); if (haudio == NULL) { @@ -424,97 +428,102 @@ static uint8_t USBD_AUDIO_Setup(USBD_HandleTypeDef *pdev, haudio = (USBD_AUDIO_HandleTypeDef *)pdev->pClassData; - switch (req->bmRequest & USB_REQ_TYPE_MASK) + if (haudio == NULL) { - case USB_REQ_TYPE_CLASS: - switch (req->bRequest) - { - case AUDIO_REQ_GET_CUR: - AUDIO_REQ_GetCurrent(pdev, req); - break; - - case AUDIO_REQ_SET_CUR: - AUDIO_REQ_SetCurrent(pdev, req); - break; - - default: - USBD_CtlError(pdev, req); - ret = USBD_FAIL; - break; - } - break; - - case USB_REQ_TYPE_STANDARD: - switch (req->bRequest) - { - case USB_REQ_GET_STATUS: - if (pdev->dev_state == USBD_STATE_CONFIGURED) - { - (void)USBD_CtlSendData(pdev, (uint8_t *)&status_info, 2U); - } - else - { - USBD_CtlError(pdev, req); - ret = USBD_FAIL; - } - break; + return (uint8_t)USBD_FAIL; + } - case USB_REQ_GET_DESCRIPTOR: - if ((req->wValue >> 8) == AUDIO_DESCRIPTOR_TYPE) + switch (req->bmRequest & USB_REQ_TYPE_MASK) + { + case USB_REQ_TYPE_CLASS: + switch (req->bRequest) { - pbuf = USBD_AUDIO_CfgDesc + 18; - len = MIN(USB_AUDIO_DESC_SIZ, req->wLength); + case AUDIO_REQ_GET_CUR: + AUDIO_REQ_GetCurrent(pdev, req); + break; - (void)USBD_CtlSendData(pdev, pbuf, len); - } - break; + case AUDIO_REQ_SET_CUR: + AUDIO_REQ_SetCurrent(pdev, req); + break; - case USB_REQ_GET_INTERFACE: - if (pdev->dev_state == USBD_STATE_CONFIGURED) - { - (void)USBD_CtlSendData(pdev, (uint8_t *)&haudio->alt_setting, 1U); - } - else - { - USBD_CtlError(pdev, req); - ret = USBD_FAIL; + default: + USBD_CtlError(pdev, req); + ret = USBD_FAIL; + break; } break; - case USB_REQ_SET_INTERFACE: - if (pdev->dev_state == USBD_STATE_CONFIGURED) + case USB_REQ_TYPE_STANDARD: + switch (req->bRequest) { - if ((uint8_t)(req->wValue) <= USBD_MAX_NUM_INTERFACES) - { - haudio->alt_setting = (uint8_t)(req->wValue); - } - else - { - /* Call the error management function (command will be nacked */ + case USB_REQ_GET_STATUS: + if (pdev->dev_state == USBD_STATE_CONFIGURED) + { + (void)USBD_CtlSendData(pdev, (uint8_t *)&status_info, 2U); + } + else + { + USBD_CtlError(pdev, req); + ret = USBD_FAIL; + } + break; + + case USB_REQ_GET_DESCRIPTOR: + if ((req->wValue >> 8) == AUDIO_DESCRIPTOR_TYPE) + { + pbuf = USBD_AUDIO_CfgDesc + 18; + len = MIN(USB_AUDIO_DESC_SIZ, req->wLength); + + (void)USBD_CtlSendData(pdev, pbuf, len); + } + break; + + case USB_REQ_GET_INTERFACE: + if (pdev->dev_state == USBD_STATE_CONFIGURED) + { + (void)USBD_CtlSendData(pdev, (uint8_t *)&haudio->alt_setting, 1U); + } + else + { + USBD_CtlError(pdev, req); + ret = USBD_FAIL; + } + break; + + case USB_REQ_SET_INTERFACE: + if (pdev->dev_state == USBD_STATE_CONFIGURED) + { + if ((uint8_t)(req->wValue) <= USBD_MAX_NUM_INTERFACES) + { + haudio->alt_setting = (uint8_t)(req->wValue); + } + else + { + /* Call the error management function (command will be NAKed */ + USBD_CtlError(pdev, req); + ret = USBD_FAIL; + } + } + else + { + USBD_CtlError(pdev, req); + ret = USBD_FAIL; + } + break; + + case USB_REQ_CLEAR_FEATURE: + break; + + default: USBD_CtlError(pdev, req); ret = USBD_FAIL; - } - } - else - { - USBD_CtlError(pdev, req); - ret = USBD_FAIL; + break; } break; - - case USB_REQ_CLEAR_FEATURE: - break; - default: USBD_CtlError(pdev, req); ret = USBD_FAIL; break; - } - break; - default: - USBD_CtlError(pdev, req); - ret = USBD_FAIL; - break; } return (uint8_t)ret; @@ -562,6 +571,11 @@ static uint8_t USBD_AUDIO_EP0_RxReady(USBD_HandleTypeDef *pdev) USBD_AUDIO_HandleTypeDef *haudio; haudio = (USBD_AUDIO_HandleTypeDef *)pdev->pClassData; + if (haudio == NULL) + { + return (uint8_t)USBD_FAIL; + } + if (haudio->control.cmd == AUDIO_REQ_SET_CUR) { /* In this driver, to simplify code, only SET_CUR request is managed */ @@ -651,13 +665,13 @@ void USBD_AUDIO_Sync(USBD_HandleTypeDef *pdev, AUDIO_OffsetTypeDef offset) { if ((haudio->wr_ptr - haudio->rd_ptr) < AUDIO_OUT_PACKET) { - BufferSize -= 4U; + BufferSize -= 4U; } else { if ((haudio->wr_ptr - haudio->rd_ptr) > (AUDIO_TOTAL_BUF_SIZE - AUDIO_OUT_PACKET)) { - BufferSize += 4U; + BufferSize += 4U; } } } @@ -712,6 +726,11 @@ static uint8_t USBD_AUDIO_DataOut(USBD_HandleTypeDef *pdev, uint8_t epnum) haudio = (USBD_AUDIO_HandleTypeDef *)pdev->pClassData; + if (haudio == NULL) + { + return (uint8_t)USBD_FAIL; + } + if (epnum == AUDIO_OUT_EP) { /* Get received data packet length */ @@ -767,10 +786,16 @@ static void AUDIO_REQ_GetCurrent(USBD_HandleTypeDef *pdev, USBD_SetupReqTypedef USBD_AUDIO_HandleTypeDef *haudio; haudio = (USBD_AUDIO_HandleTypeDef *)pdev->pClassData; - (void)USBD_memset(haudio->control.data, 0, 64U); + if (haudio == NULL) + { + return; + } + + (void)USBD_memset(haudio->control.data, 0, USB_MAX_EP0_SIZE); /* Send the current mute state */ - (void)USBD_CtlSendData(pdev, haudio->control.data, req->wLength); + (void)USBD_CtlSendData(pdev, haudio->control.data, + MIN(req->wLength, USB_MAX_EP0_SIZE)); } /** @@ -785,24 +810,29 @@ static void AUDIO_REQ_SetCurrent(USBD_HandleTypeDef *pdev, USBD_SetupReqTypedef USBD_AUDIO_HandleTypeDef *haudio; haudio = (USBD_AUDIO_HandleTypeDef *)pdev->pClassData; - if (req->wLength != 0U) + if (haudio == NULL) { - /* Prepare the reception of the buffer over EP0 */ - (void)USBD_CtlPrepareRx(pdev, haudio->control.data, req->wLength); + return; + } + if (req->wLength != 0U) + { haudio->control.cmd = AUDIO_REQ_SET_CUR; /* Set the request value */ - haudio->control.len = (uint8_t)req->wLength; /* Set the request data length */ + haudio->control.len = (uint8_t)MIN(req->wLength, USB_MAX_EP0_SIZE); /* Set the request data length */ haudio->control.unit = HIBYTE(req->wIndex); /* Set the request target unit */ + + /* Prepare the reception of the buffer over EP0 */ + (void)USBD_CtlPrepareRx(pdev, haudio->control.data, haudio->control.len); } } /** -* @brief DeviceQualifierDescriptor -* return Device Qualifier descriptor -* @param length : pointer data length -* @retval pointer to descriptor buffer -*/ + * @brief DeviceQualifierDescriptor + * return Device Qualifier descriptor + * @param length : pointer data length + * @retval pointer to descriptor buffer + */ static uint8_t *USBD_AUDIO_GetDeviceQualifierDesc(uint16_t *length) { *length = (uint16_t)sizeof(USBD_AUDIO_DeviceQualifierDesc); @@ -811,10 +841,10 @@ static uint8_t *USBD_AUDIO_GetDeviceQualifierDesc(uint16_t *length) } /** -* @brief USBD_AUDIO_RegisterInterface -* @param fops: Audio interface callback -* @retval status -*/ + * @brief USBD_AUDIO_RegisterInterface + * @param fops: Audio interface callback + * @retval status + */ uint8_t USBD_AUDIO_RegisterInterface(USBD_HandleTypeDef *pdev, USBD_AUDIO_ItfTypeDef *fops) { diff --git a/system/Middlewares/ST/STM32_USB_Device_Library/Class/BillBoard/Src/usbd_billboard.c b/system/Middlewares/ST/STM32_USB_Device_Library/Class/BillBoard/Src/usbd_billboard.c index b9e6d1906c..e0bacaa047 100644 --- a/system/Middlewares/ST/STM32_USB_Device_Library/Class/BillBoard/Src/usbd_billboard.c +++ b/system/Middlewares/ST/STM32_USB_Device_Library/Class/BillBoard/Src/usbd_billboard.c @@ -7,7 +7,7 @@ * - Initialization and Configuration of high and low layer * - Enumeration as BillBoard Device * - Error management - * @verbatim + * @verbatim * * =================================================================== * BillBoard Class Description @@ -150,8 +150,12 @@ __ALIGN_BEGIN static uint8_t USBD_BB_CfgDesc[USB_BB_CONFIG_DESC_SIZ] __ALIGN_EN 0x01, /* bNumInterfaces: 1 interface */ 0x01, /* bConfigurationValue: Configuration value */ USBD_IDX_CONFIG_STR, /* iConfiguration: Index of string descriptor describing the configuration */ - 0xC0, /* bmAttributes: bus powered and Support Remote Wake-up */ - 0x00, /* MaxPower 100 mA: this current is used for detecting Vbus */ +#if (USBD_SELF_POWERED == 1U) + 0xC0, /* bmAttributes: Bus Powered according to user configuration */ +#else + 0x80, /* bmAttributes: Bus Powered according to user configuration */ +#endif + USBD_MAX_POWER, /* MaxPower (mA) */ /* 09 */ /************** Descriptor of BillBoard interface ****************/ @@ -170,15 +174,19 @@ __ALIGN_BEGIN static uint8_t USBD_BB_CfgDesc[USB_BB_CONFIG_DESC_SIZ] __ALIGN_EN /* USB device Other Speed Configuration Descriptor */ __ALIGN_BEGIN static uint8_t USBD_BB_OtherSpeedCfgDesc[USB_BB_CONFIG_DESC_SIZ] __ALIGN_END = { - 0x09, /* bLength: Configuation Descriptor size */ + 0x09, /* bLength: Configuration Descriptor size */ USB_DESC_TYPE_OTHER_SPEED_CONFIGURATION, USB_BB_CONFIG_DESC_SIZ, 0x00, 0x01, /* bNumInterfaces: 1 interface */ - 0x01, /* bConfigurationValue: */ - USBD_IDX_CONFIG_STR, /* iConfiguration: */ - 0xC0, /* bmAttributes: */ - 0x00, /* MaxPower 100 mA */ + 0x01, /* bConfigurationValue */ + USBD_IDX_CONFIG_STR, /* iConfiguration */ +#if (USBD_SELF_POWERED == 1U) + 0xC0, /* bmAttributes: Bus Powered according to user configuration */ +#else + 0x80, /* bmAttributes: Bus Powered according to user configuration */ +#endif + USBD_MAX_POWER, /* MaxPower (mA) */ /************** Descriptor of BillBoard interface ****************/ /* 09 */ @@ -248,50 +256,50 @@ static uint8_t USBD_BB_Setup(USBD_HandleTypeDef *pdev, USBD_SetupReqTypedef *req switch (req->bmRequest & USB_REQ_TYPE_MASK) { - case USB_REQ_TYPE_CLASS: - break; - case USB_REQ_TYPE_STANDARD: - switch (req->bRequest) - { - case USB_REQ_GET_STATUS: - if (pdev->dev_state == USBD_STATE_CONFIGURED) - { - (void)USBD_CtlSendData(pdev, (uint8_t *)&status_info, 2U); - } - else - { - USBD_CtlError(pdev, req); - ret = USBD_FAIL; - } + case USB_REQ_TYPE_CLASS: break; - - case USB_REQ_GET_INTERFACE: - if (pdev->dev_state == USBD_STATE_CONFIGURED) - { - (void)USBD_CtlSendData(pdev, (uint8_t *)&AltSetting, 1U); - } - else + case USB_REQ_TYPE_STANDARD: + switch (req->bRequest) { - USBD_CtlError(pdev, req); - ret = USBD_FAIL; - } - break; + case USB_REQ_GET_STATUS: + if (pdev->dev_state == USBD_STATE_CONFIGURED) + { + (void)USBD_CtlSendData(pdev, (uint8_t *)&status_info, 2U); + } + else + { + USBD_CtlError(pdev, req); + ret = USBD_FAIL; + } + break; - case USB_REQ_SET_INTERFACE: - case USB_REQ_CLEAR_FEATURE: + case USB_REQ_GET_INTERFACE: + if (pdev->dev_state == USBD_STATE_CONFIGURED) + { + (void)USBD_CtlSendData(pdev, (uint8_t *)&AltSetting, 1U); + } + else + { + USBD_CtlError(pdev, req); + ret = USBD_FAIL; + } + break; + + case USB_REQ_SET_INTERFACE: + case USB_REQ_CLEAR_FEATURE: + break; + + default: + USBD_CtlError(pdev, req); + ret = USBD_FAIL; + break; + } break; default: USBD_CtlError(pdev, req); ret = USBD_FAIL; break; - } - break; - - default: - USBD_CtlError(pdev, req); - ret = USBD_FAIL; - break; } return (uint8_t)ret; @@ -391,10 +399,10 @@ static uint8_t *USBD_BB_GetDeviceQualifierDesc(uint16_t *length) */ USBD_BB_DescHeader_t *USBD_BB_GetNextDesc(uint8_t *pbuf, uint16_t *ptr) { - USBD_BB_DescHeader_t *pnext = (USBD_BB_DescHeader_t *)pbuf; + USBD_BB_DescHeader_t *pnext = (USBD_BB_DescHeader_t *)(void *)pbuf; *ptr += pnext->bLength; - pnext = (USBD_BB_DescHeader_t *)(pbuf + pnext->bLength); + pnext = (USBD_BB_DescHeader_t *)(void *)(pbuf + pnext->bLength); return (pnext); } @@ -411,8 +419,8 @@ void *USBD_BB_GetCapDesc(USBD_HandleTypeDef *pdev, uint8_t *pBosDesc) { UNUSED(pdev); - USBD_BB_DescHeader_t *pdesc = (USBD_BB_DescHeader_t *)pBosDesc; - USBD_BosDescTypedef *desc = (USBD_BosDescTypedef *)pBosDesc; + USBD_BB_DescHeader_t *pdesc = (USBD_BB_DescHeader_t *)(void *)pBosDesc; + USBD_BosDescTypedef *desc = (USBD_BosDescTypedef *)(void *)pBosDesc; USBD_BosBBCapDescTypedef *pCapDesc = NULL; uint16_t ptr; @@ -426,7 +434,7 @@ void *USBD_BB_GetCapDesc(USBD_HandleTypeDef *pdev, uint8_t *pBosDesc) if (pdesc->bDevCapabilityType == USBD_BILLBOARD_CAPABILITY) { - pCapDesc = (USBD_BosBBCapDescTypedef *)pdesc; + pCapDesc = (USBD_BosBBCapDescTypedef *)(void *)pdesc; break; } } @@ -447,8 +455,8 @@ void *USBD_BB_GetAltModeDesc(USBD_HandleTypeDef *pdev, uint8_t *pBosDesc, uint8_ { UNUSED(pdev); - USBD_BB_DescHeader_t *pdesc = (USBD_BB_DescHeader_t *)pBosDesc; - USBD_BosDescTypedef *desc = (USBD_BosDescTypedef *)pBosDesc; + USBD_BB_DescHeader_t *pdesc = (USBD_BB_DescHeader_t *)(void *)pBosDesc; + USBD_BosDescTypedef *desc = (USBD_BosDescTypedef *)(void *)pBosDesc; USBD_BB_AltModeCapDescTypeDef *pAltModDesc = NULL; uint8_t cnt = 0U; uint16_t ptr; @@ -465,7 +473,7 @@ void *USBD_BB_GetAltModeDesc(USBD_HandleTypeDef *pdev, uint8_t *pBosDesc, uint8_ { if (cnt == idx) { - pAltModDesc = (USBD_BB_AltModeCapDescTypeDef *)pdesc; + pAltModDesc = (USBD_BB_AltModeCapDescTypeDef *)(void *)pdesc; break; } else diff --git a/system/Middlewares/ST/STM32_USB_Device_Library/Class/CDC/Inc/usbd_cdc.h b/system/Middlewares/ST/STM32_USB_Device_Library/Class/CDC/Inc/usbd_cdc.h index b484218e0f..cb5c6d8ae8 100644 --- a/system/Middlewares/ST/STM32_USB_Device_Library/Class/CDC/Inc/usbd_cdc.h +++ b/system/Middlewares/ST/STM32_USB_Device_Library/Class/CDC/Inc/usbd_cdc.h @@ -65,6 +65,7 @@ extern "C" { #define CDC_DATA_FS_IN_PACKET_SIZE CDC_DATA_FS_MAX_PACKET_SIZE #define CDC_DATA_FS_OUT_PACKET_SIZE CDC_DATA_FS_MAX_PACKET_SIZE +#define CDC_REQ_MAX_DATA_SIZE 0x7U /*---------------------------------------------------------------------*/ /* CDC definitions */ /*---------------------------------------------------------------------*/ @@ -110,7 +111,7 @@ typedef struct _USBD_CDC_Itf typedef struct { - uint32_t data[CDC_DATA_HS_MAX_PACKET_SIZE / 4U]; /* Force 32bits alignment */ + uint32_t data[CDC_DATA_HS_MAX_PACKET_SIZE / 4U]; /* Force 32-bit alignment */ uint8_t CmdOpCode; uint8_t CmdLength; uint8_t *RxBuffer; diff --git a/system/Middlewares/ST/STM32_USB_Device_Library/Class/CDC/Src/usbd_cdc.c b/system/Middlewares/ST/STM32_USB_Device_Library/Class/CDC/Src/usbd_cdc.c index 017e4cdc9e..d6ed6ce316 100644 --- a/system/Middlewares/ST/STM32_USB_Device_Library/Class/CDC/Src/usbd_cdc.c +++ b/system/Middlewares/ST/STM32_USB_Device_Library/Class/CDC/Src/usbd_cdc.c @@ -142,7 +142,7 @@ USBD_ClassTypeDef USBD_CDC = USBD_CDC_Init, USBD_CDC_DeInit, USBD_CDC_Setup, - NULL, /* EP0_TxSent, */ + NULL, /* EP0_TxSent */ USBD_CDC_EP0_RxReady, USBD_CDC_DataIn, USBD_CDC_DataOut, @@ -163,25 +163,28 @@ __ALIGN_BEGIN static uint8_t USBD_CDC_CfgHSDesc[USB_CDC_CONFIG_DESC_SIZ] __ALIGN USB_DESC_TYPE_CONFIGURATION, /* bDescriptorType: Configuration */ USB_CDC_CONFIG_DESC_SIZ, /* wTotalLength:no of returned bytes */ 0x00, - 0x02, /* bNumInterfaces: 2 interface */ + 0x02, /* bNumInterfaces: 2 interfaces */ 0x01, /* bConfigurationValue: Configuration value */ 0x00, /* iConfiguration: Index of string descriptor describing the configuration */ - 0xC0, /* bmAttributes: self powered */ - 0x32, /* MaxPower 0 mA */ +#if (USBD_SELF_POWERED == 1U) + 0xC0, /* bmAttributes: Bus Powered according to user configuration */ +#else + 0x80, /* bmAttributes: Bus Powered according to user configuration */ +#endif + USBD_MAX_POWER, /* MaxPower (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: */ + 0x00, /* iInterface */ /* Header Functional Descriptor */ 0x05, /* bLength: Endpoint Descriptor size */ @@ -215,9 +218,9 @@ __ALIGN_BEGIN static uint8_t USBD_CDC_CfgHSDesc[USB_CDC_CONFIG_DESC_SIZ] __ALIGN USB_DESC_TYPE_ENDPOINT, /* bDescriptorType: Endpoint */ CDC_CMD_EP, /* bEndpointAddress */ 0x03, /* bmAttributes: Interrupt */ - LOBYTE(CDC_CMD_PACKET_SIZE), /* wMaxPacketSize: */ + LOBYTE(CDC_CMD_PACKET_SIZE), /* wMaxPacketSize */ HIBYTE(CDC_CMD_PACKET_SIZE), - CDC_HS_BINTERVAL, /* bInterval: */ + CDC_HS_BINTERVAL, /* bInterval */ /*---------------------------------------------------------------------------*/ /* Data class interface descriptor */ @@ -227,27 +230,27 @@ __ALIGN_BEGIN static uint8_t USBD_CDC_CfgHSDesc[USB_CDC_CONFIG_DESC_SIZ] __ALIGN 0x00, /* bAlternateSetting: Alternate setting */ 0x02, /* bNumEndpoints: Two endpoints used */ 0x0A, /* bInterfaceClass: CDC */ - 0x00, /* bInterfaceSubClass: */ - 0x00, /* bInterfaceProtocol: */ - 0x00, /* iInterface: */ + 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: */ + LOBYTE(CDC_DATA_HS_MAX_PACKET_SIZE), /* wMaxPacketSize */ HIBYTE(CDC_DATA_HS_MAX_PACKET_SIZE), - 0x00, /* bInterval: ignore for Bulk transfer */ + 0x00, /* bInterval */ /* 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: */ + LOBYTE(CDC_DATA_HS_MAX_PACKET_SIZE), /* wMaxPacketSize */ HIBYTE(CDC_DATA_HS_MAX_PACKET_SIZE), - 0x00 /* bInterval: ignore for Bulk transfer */ + 0x00 /* bInterval */ }; @@ -257,13 +260,17 @@ __ALIGN_BEGIN static uint8_t USBD_CDC_CfgFSDesc[USB_CDC_CONFIG_DESC_SIZ] __ALIGN /* Configuration Descriptor */ 0x09, /* bLength: Configuration Descriptor size */ USB_DESC_TYPE_CONFIGURATION, /* bDescriptorType: Configuration */ - USB_CDC_CONFIG_DESC_SIZ, /* wTotalLength:no of returned bytes */ + USB_CDC_CONFIG_DESC_SIZ, /* wTotalLength */ 0x00, - 0x02, /* bNumInterfaces: 2 interface */ + 0x02, /* bNumInterfaces: 2 interfaces */ 0x01, /* bConfigurationValue: Configuration value */ 0x00, /* iConfiguration: Index of string descriptor describing the configuration */ - 0xC0, /* bmAttributes: self powered */ - 0x32, /* MaxPower 0 mA */ +#if (USBD_SELF_POWERED == 1U) + 0xC0, /* bmAttributes: Bus Powered according to user configuration */ +#else + 0x80, /* bmAttributes: Bus Powered according to user configuration */ +#endif + USBD_MAX_POWER, /* MaxPower (mA) */ /*---------------------------------------------------------------------------*/ @@ -273,11 +280,11 @@ __ALIGN_BEGIN static uint8_t USBD_CDC_CfgFSDesc[USB_CDC_CONFIG_DESC_SIZ] __ALIGN /* Interface descriptor type */ 0x00, /* bInterfaceNumber: Number of Interface */ 0x00, /* bAlternateSetting: Alternate setting */ - 0x01, /* bNumEndpoints: One endpoints used */ + 0x01, /* bNumEndpoints: One endpoint used */ 0x02, /* bInterfaceClass: Communication Interface Class */ 0x02, /* bInterfaceSubClass: Abstract Control Model */ 0x01, /* bInterfaceProtocol: Common AT commands */ - 0x00, /* iInterface: */ + 0x00, /* iInterface */ /* Header Functional Descriptor */ 0x05, /* bLength: Endpoint Descriptor size */ @@ -291,7 +298,7 @@ __ALIGN_BEGIN static uint8_t USBD_CDC_CfgFSDesc[USB_CDC_CONFIG_DESC_SIZ] __ALIGN 0x24, /* bDescriptorType: CS_INTERFACE */ 0x01, /* bDescriptorSubtype: Call Management Func Desc */ 0x00, /* bmCapabilities: D0+D1 */ - 0x01, /* bDataInterface: 1 */ + 0x01, /* bDataInterface */ /* ACM Functional Descriptor */ 0x04, /* bFunctionLength */ @@ -311,9 +318,9 @@ __ALIGN_BEGIN static uint8_t USBD_CDC_CfgFSDesc[USB_CDC_CONFIG_DESC_SIZ] __ALIGN USB_DESC_TYPE_ENDPOINT, /* bDescriptorType: Endpoint */ CDC_CMD_EP, /* bEndpointAddress */ 0x03, /* bmAttributes: Interrupt */ - LOBYTE(CDC_CMD_PACKET_SIZE), /* wMaxPacketSize: */ + LOBYTE(CDC_CMD_PACKET_SIZE), /* wMaxPacketSize */ HIBYTE(CDC_CMD_PACKET_SIZE), - CDC_FS_BINTERVAL, /* bInterval: */ + CDC_FS_BINTERVAL, /* bInterval */ /*---------------------------------------------------------------------------*/ /* Data class interface descriptor */ @@ -323,42 +330,46 @@ __ALIGN_BEGIN static uint8_t USBD_CDC_CfgFSDesc[USB_CDC_CONFIG_DESC_SIZ] __ALIGN 0x00, /* bAlternateSetting: Alternate setting */ 0x02, /* bNumEndpoints: Two endpoints used */ 0x0A, /* bInterfaceClass: CDC */ - 0x00, /* bInterfaceSubClass: */ - 0x00, /* bInterfaceProtocol: */ - 0x00, /* iInterface: */ + 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_FS_MAX_PACKET_SIZE), /* wMaxPacketSize: */ + LOBYTE(CDC_DATA_FS_MAX_PACKET_SIZE), /* wMaxPacketSize */ HIBYTE(CDC_DATA_FS_MAX_PACKET_SIZE), - 0x00, /* bInterval: ignore for Bulk transfer */ + 0x00, /* bInterval */ /* Endpoint IN Descriptor */ 0x07, /* bLength: Endpoint Descriptor size */ USB_DESC_TYPE_ENDPOINT, /* bDescriptorType: Endpoint */ CDC_IN_EP, /* bEndpointAddress */ 0x02, /* bmAttributes: Bulk */ - LOBYTE(CDC_DATA_FS_MAX_PACKET_SIZE), /* wMaxPacketSize: */ + LOBYTE(CDC_DATA_FS_MAX_PACKET_SIZE), /* wMaxPacketSize */ HIBYTE(CDC_DATA_FS_MAX_PACKET_SIZE), - 0x00 /* bInterval: ignore for Bulk transfer */ + 0x00 /* bInterval */ }; __ALIGN_BEGIN static uint8_t USBD_CDC_OtherSpeedCfgDesc[USB_CDC_CONFIG_DESC_SIZ] __ALIGN_END = { - 0x09, /* bLength: Configuation Descriptor size */ + 0x09, /* bLength: Configuration Descriptor size */ USB_DESC_TYPE_OTHER_SPEED_CONFIGURATION, USB_CDC_CONFIG_DESC_SIZ, 0x00, 0x02, /* bNumInterfaces: 2 interfaces */ - 0x01, /* bConfigurationValue: */ - 0x04, /* iConfiguration: */ - 0xC0, /* bmAttributes: */ - 0x32, /* MaxPower 100 mA */ + 0x01, /* bConfigurationValue */ + 0x04, /* iConfiguration */ +#if (USBD_SELF_POWERED == 1U) + 0xC0, /* bmAttributes: Bus Powered according to user configuration */ +#else + 0x80, /* bmAttributes: Bus Powered according to user configuration */ +#endif + USBD_MAX_POWER, /* MaxPower (mA) */ - /*Interface Descriptor */ + /* Interface Descriptor */ 0x09, /* bLength: Interface Descriptor size */ USB_DESC_TYPE_INTERFACE, /* bDescriptorType: Interface */ /* Interface descriptor type */ @@ -368,7 +379,7 @@ __ALIGN_BEGIN static uint8_t USBD_CDC_OtherSpeedCfgDesc[USB_CDC_CONFIG_DESC_SIZ] 0x02, /* bInterfaceClass: Communication Interface Class */ 0x02, /* bInterfaceSubClass: Abstract Control Model */ 0x01, /* bInterfaceProtocol: Common AT commands */ - 0x00, /* iInterface: */ + 0x00, /* iInterface */ /* Header Functional Descriptor */ 0x05, /* bLength: Endpoint Descriptor size */ @@ -377,34 +388,34 @@ __ALIGN_BEGIN static uint8_t USBD_CDC_OtherSpeedCfgDesc[USB_CDC_CONFIG_DESC_SIZ] 0x10, /* bcdCDC: spec release number */ 0x01, - /*Call Management Functional Descriptor*/ + /* Call Management Functional Descriptor */ 0x05, /* bFunctionLength */ 0x24, /* bDescriptorType: CS_INTERFACE */ 0x01, /* bDescriptorSubtype: Call Management Func Desc */ - 0x00, /* bmCapabilities: D0+D1 */ - 0x01, /* bDataInterface: 1 */ + 0x00, /* bmCapabilities */ + 0x01, /* bDataInterface */ - /*ACM Functional Descriptor*/ + /* ACM Functional Descriptor */ 0x04, /* bFunctionLength */ 0x24, /* bDescriptorType: CS_INTERFACE */ 0x02, /* bDescriptorSubtype: Abstract Control Management desc */ 0x02, /* bmCapabilities */ - /*Union Functional Descriptor*/ + /* 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*/ + /* 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: */ + LOBYTE(CDC_CMD_PACKET_SIZE), /* wMaxPacketSize */ HIBYTE(CDC_CMD_PACKET_SIZE), - CDC_FS_BINTERVAL, /* bInterval: */ + CDC_FS_BINTERVAL, /* bInterval */ /*---------------------------------------------------------------------------*/ @@ -415,25 +426,25 @@ __ALIGN_BEGIN static uint8_t USBD_CDC_OtherSpeedCfgDesc[USB_CDC_CONFIG_DESC_SIZ] 0x00, /* bAlternateSetting: Alternate setting */ 0x02, /* bNumEndpoints: Two endpoints used */ 0x0A, /* bInterfaceClass: CDC */ - 0x00, /* bInterfaceSubClass: */ - 0x00, /* bInterfaceProtocol: */ - 0x00, /* iInterface: */ + 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 */ - 0x40, /* wMaxPacketSize: */ + 0x40, /* wMaxPacketSize */ 0x00, - 0x00, /* bInterval: ignore for Bulk transfer */ + 0x00, /* bInterval */ /*Endpoint IN Descriptor*/ 0x07, /* bLength: Endpoint Descriptor size */ USB_DESC_TYPE_ENDPOINT, /* bDescriptorType: Endpoint */ CDC_IN_EP, /* bEndpointAddress */ 0x02, /* bmAttributes: Bulk */ - 0x40, /* wMaxPacketSize: */ + 0x40, /* wMaxPacketSize */ 0x00, 0x00 /* bInterval */ }; @@ -458,7 +469,7 @@ static uint8_t USBD_CDC_Init(USBD_HandleTypeDef *pdev, uint8_t cfgidx) UNUSED(cfgidx); USBD_CDC_HandleTypeDef *hcdc; - hcdc = USBD_malloc(sizeof(USBD_CDC_HandleTypeDef)); + hcdc = (USBD_CDC_HandleTypeDef *)USBD_malloc(sizeof(USBD_CDC_HandleTypeDef)); if (hcdc == NULL) { @@ -474,16 +485,16 @@ static uint8_t USBD_CDC_Init(USBD_HandleTypeDef *pdev, uint8_t cfgidx) (void)USBD_LL_OpenEP(pdev, CDC_IN_EP, USBD_EP_TYPE_BULK, CDC_DATA_HS_IN_PACKET_SIZE); - pdev->ep_in[CDC_IN_EP & 0xFU].is_used = 1U; + pdev->ep_in[CDC_IN_EP & 0xFU].is_used = 1U; - /* Open EP OUT */ - (void)USBD_LL_OpenEP(pdev, CDC_OUT_EP, USBD_EP_TYPE_BULK, - CDC_DATA_HS_OUT_PACKET_SIZE); + /* Open EP OUT */ + (void)USBD_LL_OpenEP(pdev, CDC_OUT_EP, USBD_EP_TYPE_BULK, + CDC_DATA_HS_OUT_PACKET_SIZE); - pdev->ep_out[CDC_OUT_EP & 0xFU].is_used = 1U; + pdev->ep_out[CDC_OUT_EP & 0xFU].is_used = 1U; - /* Set bInterval for CDC CMD Endpoint */ - pdev->ep_in[CDC_CMD_EP & 0xFU].bInterval = CDC_HS_BINTERVAL; + /* Set bInterval for CDC CMD Endpoint */ + pdev->ep_in[CDC_CMD_EP & 0xFU].bInterval = CDC_HS_BINTERVAL; } else { @@ -491,16 +502,16 @@ static uint8_t USBD_CDC_Init(USBD_HandleTypeDef *pdev, uint8_t cfgidx) (void)USBD_LL_OpenEP(pdev, CDC_IN_EP, USBD_EP_TYPE_BULK, CDC_DATA_FS_IN_PACKET_SIZE); - pdev->ep_in[CDC_IN_EP & 0xFU].is_used = 1U; + pdev->ep_in[CDC_IN_EP & 0xFU].is_used = 1U; - /* Open EP OUT */ - (void)USBD_LL_OpenEP(pdev, CDC_OUT_EP, USBD_EP_TYPE_BULK, - CDC_DATA_FS_OUT_PACKET_SIZE); + /* Open EP OUT */ + (void)USBD_LL_OpenEP(pdev, CDC_OUT_EP, USBD_EP_TYPE_BULK, + CDC_DATA_FS_OUT_PACKET_SIZE); - pdev->ep_out[CDC_OUT_EP & 0xFU].is_used = 1U; + pdev->ep_out[CDC_OUT_EP & 0xFU].is_used = 1U; - /* Set bInterval for CMD Endpoint */ - pdev->ep_in[CDC_CMD_EP & 0xFU].bInterval = CDC_FS_BINTERVAL; + /* Set bInterval for CMD Endpoint */ + pdev->ep_in[CDC_CMD_EP & 0xFU].bInterval = CDC_FS_BINTERVAL; } /* Open Command IN EP */ @@ -540,7 +551,6 @@ static uint8_t USBD_CDC_Init(USBD_HandleTypeDef *pdev, uint8_t cfgidx) static uint8_t USBD_CDC_DeInit(USBD_HandleTypeDef *pdev, uint8_t cfgidx) { UNUSED(cfgidx); - uint8_t ret = 0U; /* Close EP IN */ (void)USBD_LL_CloseEP(pdev, CDC_IN_EP); @@ -563,7 +573,7 @@ static uint8_t USBD_CDC_DeInit(USBD_HandleTypeDef *pdev, uint8_t cfgidx) pdev->pClassData = NULL; } - return ret; + return (uint8_t)USBD_OK; } /** @@ -577,87 +587,94 @@ static uint8_t USBD_CDC_Setup(USBD_HandleTypeDef *pdev, USBD_SetupReqTypedef *req) { USBD_CDC_HandleTypeDef *hcdc = (USBD_CDC_HandleTypeDef *)pdev->pClassData; + uint16_t len; uint8_t ifalt = 0U; uint16_t status_info = 0U; USBD_StatusTypeDef ret = USBD_OK; - switch (req->bmRequest & USB_REQ_TYPE_MASK) + if (hcdc == NULL) { - case USB_REQ_TYPE_CLASS: - if (req->wLength != 0U) - { - if ((req->bmRequest & 0x80U) != 0U) - { - ((USBD_CDC_ItfTypeDef *)pdev->pUserData)->Control(req->bRequest, - (uint8_t *)hcdc->data, - req->wLength); - - (void)USBD_CtlSendData(pdev, (uint8_t *)hcdc->data, req->wLength); - } - else - { - hcdc->CmdOpCode = req->bRequest; - hcdc->CmdLength = (uint8_t)req->wLength; - - (void)USBD_CtlPrepareRx(pdev, (uint8_t *)hcdc->data, req->wLength); - } - } - else - { - ((USBD_CDC_ItfTypeDef *)pdev->pUserData)->Control(req->bRequest, - (uint8_t *)req, 0U); - } - break; - - case USB_REQ_TYPE_STANDARD: - switch (req->bRequest) - { - case USB_REQ_GET_STATUS: - if (pdev->dev_state == USBD_STATE_CONFIGURED) - { - (void)USBD_CtlSendData(pdev, (uint8_t *)&status_info, 2U); - } - else - { - USBD_CtlError(pdev, req); - ret = USBD_FAIL; - } - break; + return (uint8_t)USBD_FAIL; + } - case USB_REQ_GET_INTERFACE: - if (pdev->dev_state == USBD_STATE_CONFIGURED) + switch (req->bmRequest & USB_REQ_TYPE_MASK) + { + case USB_REQ_TYPE_CLASS: + if (req->wLength != 0U) { - (void)USBD_CtlSendData(pdev, &ifalt, 1U); + if ((req->bmRequest & 0x80U) != 0U) + { + ((USBD_CDC_ItfTypeDef *)pdev->pUserData)->Control(req->bRequest, + (uint8_t *)hcdc->data, + req->wLength); + + len = MIN(CDC_REQ_MAX_DATA_SIZE, req->wLength); + (void)USBD_CtlSendData(pdev, (uint8_t *)hcdc->data, len); + } + else + { + hcdc->CmdOpCode = req->bRequest; + hcdc->CmdLength = (uint8_t)MIN(req->wLength, USB_MAX_EP0_SIZE); + + (void)USBD_CtlPrepareRx(pdev, (uint8_t *)hcdc->data, hcdc->CmdLength); + } } else { - USBD_CtlError(pdev, req); - ret = USBD_FAIL; + ((USBD_CDC_ItfTypeDef *)pdev->pUserData)->Control(req->bRequest, + (uint8_t *)req, 0U); } break; - case USB_REQ_SET_INTERFACE: - if (pdev->dev_state != USBD_STATE_CONFIGURED) + case USB_REQ_TYPE_STANDARD: + switch (req->bRequest) { - USBD_CtlError(pdev, req); - ret = USBD_FAIL; + case USB_REQ_GET_STATUS: + if (pdev->dev_state == USBD_STATE_CONFIGURED) + { + (void)USBD_CtlSendData(pdev, (uint8_t *)&status_info, 2U); + } + else + { + USBD_CtlError(pdev, req); + ret = USBD_FAIL; + } + break; + + case USB_REQ_GET_INTERFACE: + if (pdev->dev_state == USBD_STATE_CONFIGURED) + { + (void)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_CLEAR_FEATURE: + break; + + default: + USBD_CtlError(pdev, req); + ret = USBD_FAIL; + break; } break; - case USB_REQ_CLEAR_FEATURE: - break; - default: USBD_CtlError(pdev, req); ret = USBD_FAIL; break; - } - break; - - default: - USBD_CtlError(pdev, req); - ret = USBD_FAIL; - break; } return (uint8_t)ret; @@ -694,7 +711,11 @@ static uint8_t USBD_CDC_DataIn(USBD_HandleTypeDef *pdev, uint8_t epnum) else { hcdc->TxState = 0U; - ((USBD_CDC_ItfTypeDef *)pdev->pUserData)->TransmitCplt(hcdc->TxBuffer, &hcdc->TxLength, epnum); + + if (((USBD_CDC_ItfTypeDef *)pdev->pUserData)->TransmitCplt != NULL) + { + ((USBD_CDC_ItfTypeDef *)pdev->pUserData)->TransmitCplt(hcdc->TxBuffer, &hcdc->TxLength, epnum); + } } return (uint8_t)USBD_OK; @@ -737,13 +758,17 @@ static uint8_t USBD_CDC_EP0_RxReady(USBD_HandleTypeDef *pdev) { USBD_CDC_HandleTypeDef *hcdc = (USBD_CDC_HandleTypeDef *)pdev->pClassData; + if (hcdc == NULL) + { + return (uint8_t)USBD_FAIL; + } + if ((pdev->pUserData != NULL) && (hcdc->CmdOpCode != 0xFFU)) { ((USBD_CDC_ItfTypeDef *)pdev->pUserData)->Control(hcdc->CmdOpCode, (uint8_t *)hcdc->data, (uint16_t)hcdc->CmdLength); hcdc->CmdOpCode = 0xFFU; - } return (uint8_t)USBD_OK; @@ -778,7 +803,7 @@ static uint8_t *USBD_CDC_GetHSCfgDesc(uint16_t *length) } /** - * @brief USBD_CDC_GetCfgDesc + * @brief USBD_CDC_GetOtherSpeedCfgDesc * Return configuration descriptor * @param speed : current device speed * @param length : pointer data length @@ -792,11 +817,11 @@ static uint8_t *USBD_CDC_GetOtherSpeedCfgDesc(uint16_t *length) } /** -* @brief DeviceQualifierDescriptor -* return Device Qualifier descriptor -* @param length : pointer data length -* @retval pointer to descriptor buffer -*/ + * @brief USBD_CDC_GetDeviceQualifierDescriptor + * return Device Qualifier descriptor + * @param length : pointer data length + * @retval pointer to descriptor buffer + */ uint8_t *USBD_CDC_GetDeviceQualifierDescriptor(uint16_t *length) { *length = (uint16_t)sizeof(USBD_CDC_DeviceQualifierDesc); @@ -805,7 +830,7 @@ uint8_t *USBD_CDC_GetDeviceQualifierDescriptor(uint16_t *length) } /** -* @brief USBD_CDC_RegisterInterface + * @brief USBD_CDC_RegisterInterface * @param pdev: device instance * @param fops: CD Interface callback * @retval status @@ -834,13 +859,17 @@ uint8_t USBD_CDC_SetTxBuffer(USBD_HandleTypeDef *pdev, { USBD_CDC_HandleTypeDef *hcdc = (USBD_CDC_HandleTypeDef *)pdev->pClassData; + if (hcdc == NULL) + { + return (uint8_t)USBD_FAIL; + } + hcdc->TxBuffer = pbuff; hcdc->TxLength = length; return (uint8_t)USBD_OK; } - /** * @brief USBD_CDC_SetRxBuffer * @param pdev: device instance @@ -851,6 +880,11 @@ uint8_t USBD_CDC_SetRxBuffer(USBD_HandleTypeDef *pdev, uint8_t *pbuff) { USBD_CDC_HandleTypeDef *hcdc = (USBD_CDC_HandleTypeDef *)pdev->pClassData; + if (hcdc == NULL) + { + return (uint8_t)USBD_FAIL; + } + hcdc->RxBuffer = pbuff; return (uint8_t)USBD_OK; @@ -889,7 +923,6 @@ uint8_t USBD_CDC_TransmitPacket(USBD_HandleTypeDef *pdev) return (uint8_t)ret; } - /** * @brief USBD_CDC_ReceivePacket * prepare OUT Endpoint for reception diff --git a/system/Middlewares/ST/STM32_USB_Device_Library/Class/CDC/Src/usbd_cdc_if_template.c b/system/Middlewares/ST/STM32_USB_Device_Library/Class/CDC/Src/usbd_cdc_if_template.c index 60748c39ff..f863ce1bbb 100644 --- a/system/Middlewares/ST/STM32_USB_Device_Library/Class/CDC/Src/usbd_cdc_if_template.c +++ b/system/Middlewares/ST/STM32_USB_Device_Library/Class/CDC/Src/usbd_cdc_if_template.c @@ -213,7 +213,7 @@ static int8_t TEMPLATE_Receive(uint8_t *Buf, uint32_t *Len) /** * @brief TEMPLATE_TransmitCplt - * Data transmited callback + * Data transmitted callback * * @note * This function is IN transfer complete callback used to inform user that diff --git a/system/Middlewares/ST/STM32_USB_Device_Library/Class/CDC_ECM/Inc/usbd_cdc_ecm.h b/system/Middlewares/ST/STM32_USB_Device_Library/Class/CDC_ECM/Inc/usbd_cdc_ecm.h index f4bef2c718..1cd71fa17f 100644 --- a/system/Middlewares/ST/STM32_USB_Device_Library/Class/CDC_ECM/Inc/usbd_cdc_ecm.h +++ b/system/Middlewares/ST/STM32_USB_Device_Library/Class/CDC_ECM/Inc/usbd_cdc_ecm.h @@ -75,6 +75,8 @@ extern "C" { #define CDC_ECM_CONFIG_DESC_SIZ 79U +#define CDC_ECM_DATA_BUFFER_SIZE 2000U + #define CDC_ECM_DATA_HS_IN_PACKET_SIZE CDC_ECM_DATA_HS_MAX_PACKET_SIZE #define CDC_ECM_DATA_HS_OUT_PACKET_SIZE CDC_ECM_DATA_HS_MAX_PACKET_SIZE @@ -173,7 +175,7 @@ typedef struct typedef struct { - uint32_t data[2000 / 4]; /* Force 32bits alignment */ + uint32_t data[CDC_ECM_DATA_BUFFER_SIZE / 4U]; /* Force 32-bit alignment */ uint8_t CmdOpCode; uint8_t CmdLength; uint8_t Reserved1; /* Reserved Byte to force 4 bytes alignment of following fields */ diff --git a/system/Middlewares/ST/STM32_USB_Device_Library/Class/CDC_ECM/Src/usbd_cdc_ecm.c b/system/Middlewares/ST/STM32_USB_Device_Library/Class/CDC_ECM/Src/usbd_cdc_ecm.c index edc5d220d0..4b34d7c937 100644 --- a/system/Middlewares/ST/STM32_USB_Device_Library/Class/CDC_ECM/Src/usbd_cdc_ecm.c +++ b/system/Middlewares/ST/STM32_USB_Device_Library/Class/CDC_ECM/Src/usbd_cdc_ecm.c @@ -113,7 +113,8 @@ __ALIGN_BEGIN static uint8_t USBD_CDC_ECM_DeviceQualifierDesc[USB_LEN_DEV_QUALIF }; static uint32_t ConnSpeedTab[2] = {CDC_ECM_CONNECT_SPEED_UPSTREAM, - CDC_ECM_CONNECT_SPEED_DOWNSTREAM}; + CDC_ECM_CONNECT_SPEED_DOWNSTREAM + }; /** * @} @@ -154,11 +155,15 @@ __ALIGN_BEGIN static uint8_t USBD_CDC_ECM_CfgHSDesc[] __ALIGN_END = USB_DESC_TYPE_CONFIGURATION, /* bDescriptorType: Configuration */ LOBYTE(CDC_ECM_CONFIG_DESC_SIZ), /* wTotalLength:no of returned bytes */ HIBYTE(CDC_ECM_CONFIG_DESC_SIZ), - 0x02, /* bNumInterfaces: 2 interface */ + 0x02, /* bNumInterfaces: 2 interfaces */ 0x01, /* bConfigurationValue: Configuration value */ 0x00, /* iConfiguration: Index of string descriptor describing the configuration */ - 0xC0, /* bmAttributes: self powered */ - 0x32, /* MaxPower 0 mA */ +#if (USBD_SELF_POWERED == 1U) + 0xC0, /* bmAttributes: Bus Powered according to user configuration */ +#else + 0x80, /* bmAttributes: Bus Powered according to user configuration */ +#endif + USBD_MAX_POWER, /* MaxPower (mA) */ /*---------------------------------------------------------------------------*/ @@ -181,7 +186,7 @@ __ALIGN_BEGIN static uint8_t USBD_CDC_ECM_CfgHSDesc[] __ALIGN_END = 0x02, /* bInterfaceClass: Communication Interface Class */ 0x06, /* bInterfaceSubClass: Ethernet Control Model */ 0x00, /* bInterfaceProtocol: No specific protocol required */ - 0x00, /* iInterface: */ + 0x00, /* iInterface */ /* Header Functional Descriptor */ 0x05, /* bLength: Endpoint Descriptor size */ @@ -217,7 +222,7 @@ __ALIGN_BEGIN static uint8_t USBD_CDC_ECM_CfgHSDesc[] __ALIGN_END = USB_DESC_TYPE_ENDPOINT, /* bDescriptorType: Endpoint */ CDC_ECM_CMD_EP, /* bEndpointAddress */ 0x03, /* bmAttributes: Interrupt */ - LOBYTE(CDC_ECM_CMD_PACKET_SIZE), /* wMaxPacketSize: */ + LOBYTE(CDC_ECM_CMD_PACKET_SIZE), /* wMaxPacketSize */ HIBYTE(CDC_ECM_CMD_PACKET_SIZE), CDC_ECM_HS_BINTERVAL, /* bInterval */ @@ -230,27 +235,27 @@ __ALIGN_BEGIN static uint8_t USBD_CDC_ECM_CfgHSDesc[] __ALIGN_END = 0x00, /* bAlternateSetting: Alternate setting */ 0x02, /* bNumEndpoints: Two endpoints used */ 0x0A, /* bInterfaceClass: CDC */ - 0x00, /* bInterfaceSubClass: */ - 0x00, /* bInterfaceProtocol: */ - 0x00, /* iInterface: */ + 0x00, /* bInterfaceSubClass */ + 0x00, /* bInterfaceProtocol */ + 0x00, /* iInterface */ /* Endpoint OUT Descriptor */ 0x07, /* bLength: Endpoint Descriptor size */ USB_DESC_TYPE_ENDPOINT, /* bDescriptorType: Endpoint */ CDC_ECM_OUT_EP, /* bEndpointAddress */ 0x02, /* bmAttributes: Bulk */ - LOBYTE(CDC_ECM_DATA_HS_MAX_PACKET_SIZE), /* wMaxPacketSize: */ + LOBYTE(CDC_ECM_DATA_HS_MAX_PACKET_SIZE), /* wMaxPacketSize */ HIBYTE(CDC_ECM_DATA_HS_MAX_PACKET_SIZE), - 0xFF, /* bInterval: ignore for Bulk transfer */ + 0x00, /* bInterval */ /* Endpoint IN Descriptor */ 0x07, /* bLength: Endpoint Descriptor size */ USB_DESC_TYPE_ENDPOINT, /* bDescriptorType: Endpoint */ CDC_ECM_IN_EP, /* bEndpointAddress */ 0x02, /* bmAttributes: Bulk */ - LOBYTE(CDC_ECM_DATA_HS_MAX_PACKET_SIZE), /* wMaxPacketSize: */ + LOBYTE(CDC_ECM_DATA_HS_MAX_PACKET_SIZE), /* wMaxPacketSize */ HIBYTE(CDC_ECM_DATA_HS_MAX_PACKET_SIZE), - 0xFF /* bInterval: ignore for Bulk transfer */ + 0x00 /* bInterval */ }; @@ -262,11 +267,15 @@ __ALIGN_BEGIN static uint8_t USBD_CDC_ECM_CfgFSDesc[] __ALIGN_END = USB_DESC_TYPE_CONFIGURATION, /* bDescriptorType: Configuration */ LOBYTE(CDC_ECM_CONFIG_DESC_SIZ), /* wTotalLength: Total size of the Config descriptor */ HIBYTE(CDC_ECM_CONFIG_DESC_SIZ), - 0x02, /* bNumInterfaces: 2 interface */ + 0x02, /* bNumInterfaces: 2 interfaces */ 0x01, /* bConfigurationValue: Configuration value */ 0x00, /* iConfiguration: Index of string descriptor describing the configuration */ - 0xC0, /* bmAttributes: self powered */ - 0x32, /* MaxPower 0 mA */ +#if (USBD_SELF_POWERED == 1U) + 0xC0, /* bmAttributes: Bus Powered according to user configuration */ +#else + 0x80, /* bmAttributes: Bus Powered according to user configuration */ +#endif + USBD_MAX_POWER, /* MaxPower (mA) */ /*---------------------------------------------------------------------------*/ /* IAD descriptor */ @@ -288,7 +297,7 @@ __ALIGN_BEGIN static uint8_t USBD_CDC_ECM_CfgFSDesc[] __ALIGN_END = 0x02, /* bInterfaceClass: Communication Interface Class */ 0x06, /* bInterfaceSubClass: Ethernet Control Model */ 0x00, /* bInterfaceProtocol: No specific protocol required */ - 0x00, /* iInterface: */ + 0x00, /* iInterface */ /* Header Functional Descriptor */ 0x05, /* bLength: Endpoint Descriptor size */ @@ -325,7 +334,7 @@ __ALIGN_BEGIN static uint8_t USBD_CDC_ECM_CfgFSDesc[] __ALIGN_END = USB_DESC_TYPE_ENDPOINT, /* bDescriptorType: Endpoint */ CDC_ECM_CMD_EP, /* bEndpointAddress */ 0x03, /* bmAttributes: Interrupt */ - LOBYTE(CDC_ECM_CMD_PACKET_SIZE), /* wMaxPacketSize: */ + LOBYTE(CDC_ECM_CMD_PACKET_SIZE), /* wMaxPacketSize */ HIBYTE(CDC_ECM_CMD_PACKET_SIZE), CDC_ECM_FS_BINTERVAL, /* bInterval */ @@ -338,27 +347,27 @@ __ALIGN_BEGIN static uint8_t USBD_CDC_ECM_CfgFSDesc[] __ALIGN_END = 0x00, /* bAlternateSetting: Alternate setting */ 0x02, /* bNumEndpoints: Two endpoints used */ 0x0A, /* bInterfaceClass: CDC_ECM */ - 0x00, /* bInterfaceSubClass: */ - 0x00, /* bInterfaceProtocol: */ - 0x00, /* iInterface: */ + 0x00, /* bInterfaceSubClass */ + 0x00, /* bInterfaceProtocol */ + 0x00, /* iInterface */ /* Endpoint OUT Descriptor */ 0x07, /* bLength: Endpoint Descriptor size */ USB_DESC_TYPE_ENDPOINT, /* bDescriptorType: Endpoint */ CDC_ECM_OUT_EP, /* bEndpointAddress */ 0x02, /* bmAttributes: Bulk */ - LOBYTE(CDC_ECM_DATA_FS_MAX_PACKET_SIZE), /* wMaxPacketSize: */ + LOBYTE(CDC_ECM_DATA_FS_MAX_PACKET_SIZE), /* wMaxPacketSize */ HIBYTE(CDC_ECM_DATA_FS_MAX_PACKET_SIZE), - 0xFF, /* bInterval: ignore for Bulk transfer */ + 0x00, /* bInterval */ /* Endpoint IN Descriptor */ 0x07, /* bLength: Endpoint Descriptor size */ USB_DESC_TYPE_ENDPOINT, /* bDescriptorType: Endpoint */ CDC_ECM_IN_EP, /* bEndpointAddress */ 0x02, /* bmAttributes: Bulk */ - LOBYTE(CDC_ECM_DATA_FS_MAX_PACKET_SIZE), /* wMaxPacketSize: */ + LOBYTE(CDC_ECM_DATA_FS_MAX_PACKET_SIZE), /* wMaxPacketSize */ HIBYTE(CDC_ECM_DATA_FS_MAX_PACKET_SIZE), - 0xFF /* bInterval: ignore for Bulk transfer */ + 0x00 /* bInterval */ } ; __ALIGN_BEGIN static uint8_t USBD_CDC_ECM_OtherSpeedCfgDesc[] __ALIGN_END = @@ -366,13 +375,17 @@ __ALIGN_BEGIN static uint8_t USBD_CDC_ECM_OtherSpeedCfgDesc[] __ALIGN_END = /* Configuration Descriptor */ 0x09, /* bLength: Configuration Descriptor size */ USB_DESC_TYPE_CONFIGURATION, /* bDescriptorType: Configuration */ - LOBYTE(CDC_ECM_CONFIG_DESC_SIZ), /* wTotalLength:no of returned bytes */ + LOBYTE(CDC_ECM_CONFIG_DESC_SIZ), /* wTotalLength */ HIBYTE(CDC_ECM_CONFIG_DESC_SIZ), - 0x02, /* bNumInterfaces: 2 interface */ + 0x02, /* bNumInterfaces: 2 interfaces */ 0x01, /* bConfigurationValue: Configuration value */ 0x04, /* iConfiguration: Index of string descriptor describing the configuration */ - 0xC0, /* bmAttributes: self powered */ - 0x32, /* MaxPower 0 mA */ +#if (USBD_SELF_POWERED == 1U) + 0xC0, /* bmAttributes: Bus Powered according to user configuration */ +#else + 0x80, /* bmAttributes: Bus Powered according to user configuration */ +#endif + USBD_MAX_POWER, /* MaxPower (mA) */ /*--------------------------------------- ------------------------------------*/ /* IAD descriptor */ @@ -430,7 +443,7 @@ __ALIGN_BEGIN static uint8_t USBD_CDC_ECM_OtherSpeedCfgDesc[] __ALIGN_END = USB_DESC_TYPE_ENDPOINT, /* bDescriptorType: Endpoint */ CDC_ECM_CMD_EP, /* bEndpointAddress */ 0x03, /* bmAttributes: Interrupt */ - LOBYTE(CDC_ECM_CMD_PACKET_SIZE), /* wMaxPacketSize: */ + LOBYTE(CDC_ECM_CMD_PACKET_SIZE), /* wMaxPacketSize */ HIBYTE(CDC_ECM_CMD_PACKET_SIZE), CDC_ECM_FS_BINTERVAL, /* bInterval */ @@ -438,13 +451,13 @@ __ALIGN_BEGIN static uint8_t USBD_CDC_ECM_OtherSpeedCfgDesc[] __ALIGN_END = /* Data class interface descriptor */ 0x09, /* bLength: Endpoint Descriptor size */ - USB_DESC_TYPE_INTERFACE, /* bDescriptorType: */ + USB_DESC_TYPE_INTERFACE, /* bDescriptorType: interface */ 0x01, /* bInterfaceNumber: Number of Interface */ 0x00, /* bAlternateSetting: Alternate setting */ 0x02, /* bNumEndpoints: Two endpoints used */ 0x0A, /* bInterfaceClass: CDC */ - 0x00, /* bInterfaceSubClass: */ - 0x00, /* bInterfaceProtocol: */ + 0x00, /* bInterfaceSubClass */ + 0x00, /* bInterfaceProtocol */ 0x00, /* iInterface: */ /* Endpoint OUT Descriptor */ @@ -452,18 +465,18 @@ __ALIGN_BEGIN static uint8_t USBD_CDC_ECM_OtherSpeedCfgDesc[] __ALIGN_END = USB_DESC_TYPE_ENDPOINT, /* bDescriptorType: Endpoint */ CDC_ECM_OUT_EP, /* bEndpointAddress */ 0x02, /* bmAttributes: Bulk */ - 0x40, /* wMaxPacketSize: */ + 0x40, /* wMaxPacketSize */ 0x00, - 0xFF, /* bInterval: ignore for Bulk transfer */ + 0x00, /* bInterval */ /* Endpoint IN Descriptor */ 0x07, /* bLength: Endpoint Descriptor size */ USB_DESC_TYPE_ENDPOINT, /* bDescriptorType: Endpoint */ CDC_ECM_IN_EP, /* bEndpointAddress */ 0x02, /* bmAttributes: Bulk */ - 0x40, /* wMaxPacketSize: */ + 0x40, /* wMaxPacketSize */ 0x00, - 0xFF /* bInterval: ignore for Bulk transfer */ + 0x00 /* bInterval */ }; /** @@ -487,7 +500,7 @@ static uint8_t USBD_CDC_ECM_Init(USBD_HandleTypeDef *pdev, uint8_t cfgidx) USBD_CDC_ECM_HandleTypeDef *hcdc; - hcdc = USBD_malloc(sizeof(USBD_CDC_ECM_HandleTypeDef)); + hcdc = (USBD_CDC_ECM_HandleTypeDef *)USBD_malloc(sizeof(USBD_CDC_ECM_HandleTypeDef)); if (hcdc == NULL) { @@ -602,84 +615,91 @@ static uint8_t USBD_CDC_ECM_Setup(USBD_HandleTypeDef *pdev, USBD_CDC_ECM_HandleTypeDef *hcdc = (USBD_CDC_ECM_HandleTypeDef *) pdev->pClassData; USBD_CDC_ECM_ItfTypeDef *EcmInterface = (USBD_CDC_ECM_ItfTypeDef *)pdev->pUserData; USBD_StatusTypeDef ret = USBD_OK; - uint8_t ifalt = 0U; + uint16_t len; uint16_t status_info = 0U; + uint8_t ifalt = 0U; - switch (req->bmRequest & USB_REQ_TYPE_MASK) + if (hcdc == NULL) { - case USB_REQ_TYPE_CLASS : - if (req->wLength != 0U) - { - if ((req->bmRequest & 0x80U) != 0U) - { - EcmInterface->Control(req->bRequest, - (uint8_t *)hcdc->data, req->wLength); + return (uint8_t)USBD_FAIL; + } - (void)USBD_CtlSendData(pdev, (uint8_t *)hcdc->data, req->wLength); - } - else + switch (req->bmRequest & USB_REQ_TYPE_MASK) + { + case USB_REQ_TYPE_CLASS : + if (req->wLength != 0U) { - hcdc->CmdOpCode = req->bRequest; - hcdc->CmdLength = (uint8_t)req->wLength; - - (void)USBD_CtlPrepareRx(pdev, (uint8_t *)hcdc->data, req->wLength); - } - } - else - { - EcmInterface->Control(req->bRequest, (uint8_t *)req, 0U); - } - break; + if ((req->bmRequest & 0x80U) != 0U) + { + EcmInterface->Control(req->bRequest, + (uint8_t *)hcdc->data, req->wLength); - case USB_REQ_TYPE_STANDARD: - switch (req->bRequest) - { - case USB_REQ_GET_STATUS: - if (pdev->dev_state == USBD_STATE_CONFIGURED) - { - (void)USBD_CtlSendData(pdev, (uint8_t *)&status_info, 2U); - } - else - { - USBD_CtlError(pdev, req); - ret = USBD_FAIL; - } - break; + len = MIN(CDC_ECM_DATA_BUFFER_SIZE, req->wLength); + (void)USBD_CtlSendData(pdev, (uint8_t *)hcdc->data, len); + } + else + { + hcdc->CmdOpCode = req->bRequest; + hcdc->CmdLength = (uint8_t)MIN(req->wLength, USB_MAX_EP0_SIZE); - case USB_REQ_GET_INTERFACE: - if (pdev->dev_state == USBD_STATE_CONFIGURED) - { - (void)USBD_CtlSendData(pdev, &ifalt, 1U); + (void)USBD_CtlPrepareRx(pdev, (uint8_t *)hcdc->data, hcdc->CmdLength); + } } else { - USBD_CtlError(pdev, req); - ret = USBD_FAIL; + EcmInterface->Control(req->bRequest, (uint8_t *)req, 0U); } break; - case USB_REQ_SET_INTERFACE: - if (pdev->dev_state != USBD_STATE_CONFIGURED) + case USB_REQ_TYPE_STANDARD: + switch (req->bRequest) { - USBD_CtlError(pdev, req); - ret = USBD_FAIL; + case USB_REQ_GET_STATUS: + if (pdev->dev_state == USBD_STATE_CONFIGURED) + { + (void)USBD_CtlSendData(pdev, (uint8_t *)&status_info, 2U); + } + else + { + USBD_CtlError(pdev, req); + ret = USBD_FAIL; + } + break; + + case USB_REQ_GET_INTERFACE: + if (pdev->dev_state == USBD_STATE_CONFIGURED) + { + (void)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_CLEAR_FEATURE: + break; + + default: + USBD_CtlError(pdev, req); + ret = USBD_FAIL; + break; } break; - case USB_REQ_CLEAR_FEATURE: - break; - default: USBD_CtlError(pdev, req); ret = USBD_FAIL; break; - } - break; - - default: - USBD_CtlError(pdev, req); - ret = USBD_FAIL; - break; } return (uint8_t)ret; @@ -716,7 +736,10 @@ static uint8_t USBD_CDC_ECM_DataIn(USBD_HandleTypeDef *pdev, uint8_t epnum) else { hcdc->TxState = 0U; - ((USBD_CDC_ECM_ItfTypeDef *)pdev->pUserData)->TransmitCplt(hcdc->TxBuffer, &hcdc->TxLength, epnum); + if (((USBD_CDC_ECM_ItfTypeDef *)pdev->pUserData)->TransmitCplt != NULL) + { + ((USBD_CDC_ECM_ItfTypeDef *)pdev->pUserData)->TransmitCplt(hcdc->TxBuffer, &hcdc->TxLength, epnum); + } } } else if (epnum == (CDC_ECM_CMD_EP & 0x7FU)) @@ -766,7 +789,7 @@ static uint8_t USBD_CDC_ECM_DataOut(USBD_HandleTypeDef *pdev, uint8_t epnum) if ((CurrPcktLen < hcdc->MaxPcktLen) || (hcdc->RxLength >= CDC_ECM_ETH_MAX_SEGSZE)) { /* USB data will be immediately processed, this allow next USB traffic being - NACKed till the end of the application Xfer */ + NAKed till the end of the application Xfer */ /* Process data by application (ie. copy to app buffer or notify user) hcdc->RxLength must be reset to zero at the end of the call of this function */ @@ -798,6 +821,11 @@ static uint8_t USBD_CDC_ECM_EP0_RxReady(USBD_HandleTypeDef *pdev) { USBD_CDC_ECM_HandleTypeDef *hcdc = (USBD_CDC_ECM_HandleTypeDef *)pdev->pClassData; + if (hcdc == NULL) + { + return (uint8_t)USBD_FAIL; + } + if ((pdev->pUserData != NULL) && (hcdc->CmdOpCode != 0xFFU)) { ((USBD_CDC_ECM_ItfTypeDef *)pdev->pUserData)->Control(hcdc->CmdOpCode, @@ -921,6 +949,11 @@ uint8_t USBD_CDC_ECM_SetTxBuffer(USBD_HandleTypeDef *pdev, uint8_t *pbuff, uint3 { USBD_CDC_ECM_HandleTypeDef *hcdc = (USBD_CDC_ECM_HandleTypeDef *)pdev->pClassData; + if (hcdc == NULL) + { + return (uint8_t)USBD_FAIL; + } + hcdc->TxBuffer = pbuff; hcdc->TxLength = length; @@ -938,6 +971,11 @@ uint8_t USBD_CDC_ECM_SetRxBuffer(USBD_HandleTypeDef *pdev, uint8_t *pbuff) { USBD_CDC_ECM_HandleTypeDef *hcdc = (USBD_CDC_ECM_HandleTypeDef *)pdev->pClassData; + if (hcdc == NULL) + { + return (uint8_t)USBD_FAIL; + } + hcdc->RxBuffer = pbuff; return (uint8_t)USBD_OK; @@ -970,7 +1008,7 @@ uint8_t USBD_CDC_ECM_TransmitPacket(USBD_HandleTypeDef *pdev) /* Transmit next packet */ (void)USBD_LL_Transmit(pdev, CDC_ECM_IN_EP, hcdc->TxBuffer, hcdc->TxLength); - ret = USBD_OK; + ret = USBD_OK; } return (uint8_t)ret; @@ -993,7 +1031,7 @@ uint8_t USBD_CDC_ECM_ReceivePacket(USBD_HandleTypeDef *pdev) } /* Prepare Out endpoint to receive next packet */ - (void)USBD_LL_PrepareReceive(pdev, CDC_ECM_OUT_EP,hcdc->RxBuffer, hcdc->MaxPcktLen); + (void)USBD_LL_PrepareReceive(pdev, CDC_ECM_OUT_EP, hcdc->RxBuffer, hcdc->MaxPcktLen); return (uint8_t)USBD_OK; } @@ -1016,11 +1054,16 @@ uint8_t USBD_CDC_ECM_SendNotification(USBD_HandleTypeDef *pdev, USBD_CDC_ECM_HandleTypeDef *hcdc = (USBD_CDC_ECM_HandleTypeDef *)pdev->pClassData; USBD_StatusTypeDef ret = USBD_OK; + if (hcdc == NULL) + { + return (uint8_t)USBD_FAIL; + } + /* Initialize the request fields */ (hcdc->Req).bmRequest = CDC_ECM_BMREQUEST_TYPE_ECM; (hcdc->Req).bRequest = (uint8_t)Notif; - switch (Notif) + switch ((hcdc->Req).bRequest) { case NETWORK_CONNECTION: (hcdc->Req).wValue = bVal; @@ -1069,7 +1112,7 @@ uint8_t USBD_CDC_ECM_SendNotification(USBD_HandleTypeDef *pdev, /* Transmit notification packet */ if (ReqSize != 0U) { - (void)USBD_LL_Transmit(pdev, CDC_ECM_CMD_EP, (uint8_t *)&(hcdc->Req), ReqSize); + (void)USBD_LL_Transmit(pdev, CDC_ECM_CMD_EP, (uint8_t *) &(hcdc->Req), ReqSize); } return (uint8_t)ret; diff --git a/system/Middlewares/ST/STM32_USB_Device_Library/Class/CDC_ECM/Src/usbd_cdc_ecm_if_template.c b/system/Middlewares/ST/STM32_USB_Device_Library/Class/CDC_ECM/Src/usbd_cdc_ecm_if_template.c index 9b96de8b4e..cab0056584 100644 --- a/system/Middlewares/ST/STM32_USB_Device_Library/Class/CDC_ECM/Src/usbd_cdc_ecm_if_template.c +++ b/system/Middlewares/ST/STM32_USB_Device_Library/Class/CDC_ECM/Src/usbd_cdc_ecm_if_template.c @@ -32,12 +32,12 @@ /* Private variables ---------------------------------------------------------*/ #if defined ( __ICCARM__ ) /*!< IAR Compiler */ - #pragma data_alignment=4 +#pragma data_alignment=4 #endif __ALIGN_BEGIN static uint8_t UserRxBuffer[CDC_ECM_ETH_MAX_SEGSZE + 100]__ALIGN_END; /* Received Data over USB are stored in this buffer */ #if defined ( __ICCARM__ ) /*!< IAR Compiler */ - #pragma data_alignment=4 +#pragma data_alignment=4 #endif __ALIGN_BEGIN static uint8_t UserTxBuffer[CDC_ECM_ETH_MAX_SEGSZE + 100]__ALIGN_END; /* Received Data over CDC_ECM (CDC_ECM interface) are stored in this buffer */ @@ -133,15 +133,15 @@ static int8_t CDC_ECM_Itf_Control(uint8_t cmd, uint8_t *pbuf, uint16_t length) /* Add your code here */ break; - case CDC_ECM_SET_ETH_PWRM_PATTERN_FILTER: + case CDC_ECM_SET_ETH_PWRM_PATTERN_FILTER: /* Add your code here */ break; - case CDC_ECM_GET_ETH_PWRM_PATTERN_FILTER: + case CDC_ECM_GET_ETH_PWRM_PATTERN_FILTER: /* Add your code here */ break; - case CDC_ECM_SET_ETH_PACKET_FILTER: + case CDC_ECM_SET_ETH_PACKET_FILTER: /* Check if this is the first time we enter */ if (hcdc_cdc_ecm->LinkStatus == 0U) { @@ -164,7 +164,7 @@ static int8_t CDC_ECM_Itf_Control(uint8_t cmd, uint8_t *pbuf, uint16_t length) /* Add your code here */ break; - case CDC_ECM_GET_ETH_STATISTIC: + case CDC_ECM_GET_ETH_STATISTIC: /* Add your code here */ break; @@ -201,7 +201,7 @@ static int8_t CDC_ECM_Itf_Receive(uint8_t *Buf, uint32_t *Len) /** * @brief CDC_ECM_Itf_TransmitCplt - * Data transmited callback + * Data transmitted callback * * @note * This function is IN transfer complete callback used to inform user that diff --git a/system/Middlewares/ST/STM32_USB_Device_Library/Class/CDC_RNDIS/Inc/usbd_cdc_rndis.h b/system/Middlewares/ST/STM32_USB_Device_Library/Class/CDC_RNDIS/Inc/usbd_cdc_rndis.h index ef76894400..a2fb432357 100644 --- a/system/Middlewares/ST/STM32_USB_Device_Library/Class/CDC_RNDIS/Inc/usbd_cdc_rndis.h +++ b/system/Middlewares/ST/STM32_USB_Device_Library/Class/CDC_RNDIS/Inc/usbd_cdc_rndis.h @@ -243,7 +243,7 @@ typedef struct typedef struct { - uint32_t data[2000 / 4]; /* Force 32bits alignment */ + uint32_t data[CDC_RNDIS_MAX_DATA_SZE / 4U]; /* Force 32-bit alignment */ uint8_t CmdOpCode; uint8_t CmdLength; uint8_t ResponseRdy; /* Indicates if the Device Response to an CDC_RNDIS msg is ready */ diff --git a/system/Middlewares/ST/STM32_USB_Device_Library/Class/CDC_RNDIS/Src/usbd_cdc_rndis.c b/system/Middlewares/ST/STM32_USB_Device_Library/Class/CDC_RNDIS/Src/usbd_cdc_rndis.c index 946ed5018c..a7c2cbc7c6 100644 --- a/system/Middlewares/ST/STM32_USB_Device_Library/Class/CDC_RNDIS/Src/usbd_cdc_rndis.c +++ b/system/Middlewares/ST/STM32_USB_Device_Library/Class/CDC_RNDIS/Src/usbd_cdc_rndis.c @@ -144,10 +144,12 @@ __ALIGN_BEGIN static uint8_t USBD_CDC_RNDIS_DeviceQualifierDesc[USB_LEN_DEV_QUAL }; static uint8_t MAC_StrDesc[6] = {CDC_RNDIS_MAC_ADDR0, CDC_RNDIS_MAC_ADDR1, CDC_RNDIS_MAC_ADDR2, - CDC_RNDIS_MAC_ADDR3, CDC_RNDIS_MAC_ADDR4, CDC_RNDIS_MAC_ADDR5}; + CDC_RNDIS_MAC_ADDR3, CDC_RNDIS_MAC_ADDR4, CDC_RNDIS_MAC_ADDR5 + }; static uint32_t ConnSpeedTab[2] = {CDC_RNDIS_CONNECT_SPEED_UPSTREAM, - CDC_RNDIS_CONNECT_SPEED_DOWNSTREAM}; + CDC_RNDIS_CONNECT_SPEED_DOWNSTREAM + }; static uint8_t EmptyResponse = 0x00U; @@ -190,11 +192,15 @@ __ALIGN_BEGIN static uint8_t USBD_CDC_RNDIS_CfgHSDesc[] __ALIGN_END = USB_DESC_TYPE_CONFIGURATION, /* bDescriptorType: Configuration */ LOBYTE(CDC_RNDIS_CONFIG_DESC_SIZ), /* wTotalLength: Total size of the Config descriptor */ HIBYTE(CDC_RNDIS_CONFIG_DESC_SIZ), - 0x02, /* bNumInterfaces: 2 interface */ + 0x02, /* bNumInterfaces: 2 interfaces */ 0x01, /* bConfigurationValue: Configuration value */ 0x00, /* iConfiguration: Index of string descriptor describing the configuration */ - 0xC0, /* bmAttributes: self powered */ - 0x32, /* MaxPower 0 mA */ +#if (USBD_SELF_POWERED == 1U) + 0xC0, /* bmAttributes: Bus Powered according to user configuration */ +#else + 0x80, /* bmAttributes: Bus Powered according to user configuration */ +#endif + USBD_MAX_POWER, /* MaxPower (mA) */ /*---------------------------------------------------------------------------*/ /* IAD descriptor */ @@ -217,7 +223,7 @@ __ALIGN_BEGIN static uint8_t USBD_CDC_RNDIS_CfgHSDesc[] __ALIGN_END = 0x02, /* bInterfaceClass: Communication Interface Class */ 0x02, /* bInterfaceSubClass:Abstract Control Model */ 0xFF, /* bInterfaceProtocol: Common AT commands */ - 0x00, /* iInterface: */ + 0x00, /* iInterface */ /* Header Functional Descriptor */ 0x05, /* bLength: Endpoint Descriptor size */ @@ -251,7 +257,7 @@ __ALIGN_BEGIN static uint8_t USBD_CDC_RNDIS_CfgHSDesc[] __ALIGN_END = USB_DESC_TYPE_ENDPOINT, /* bDescriptorType: Endpoint */ CDC_RNDIS_CMD_EP, /* bEndpointAddress */ 0x03, /* bmAttributes: Interrupt */ - LOBYTE(CDC_RNDIS_CMD_PACKET_SIZE), /* wMaxPacketSize: */ + LOBYTE(CDC_RNDIS_CMD_PACKET_SIZE), /* wMaxPacketSize */ HIBYTE(CDC_RNDIS_CMD_PACKET_SIZE), CDC_RNDIS_HS_BINTERVAL, /* bInterval */ @@ -263,18 +269,18 @@ __ALIGN_BEGIN static uint8_t USBD_CDC_RNDIS_CfgHSDesc[] __ALIGN_END = 0x00, /* bAlternateSetting: Alternate setting */ 0x02, /* bNumEndpoints: Two endpoints used */ 0x0A, /* bInterfaceClass: CDC */ - 0x00, /* bInterfaceSubClass: */ - 0x00, /* bInterfaceProtocol: */ - 0x00, /* iInterface: */ + 0x00, /* bInterfaceSubClass */ + 0x00, /* bInterfaceProtocol */ + 0x00, /* iInterface */ /* Endpoint OUT Descriptor */ 0x07, /* bLength: Endpoint Descriptor size */ USB_DESC_TYPE_ENDPOINT, /* bDescriptorType: Endpoint */ CDC_RNDIS_OUT_EP, /* bEndpointAddress */ 0x02, /* bmAttributes: Bulk */ - LOBYTE(CDC_RNDIS_DATA_HS_MAX_PACKET_SIZE), /* wMaxPacketSize: */ + LOBYTE(CDC_RNDIS_DATA_HS_MAX_PACKET_SIZE), /* wMaxPacketSize */ HIBYTE(CDC_RNDIS_DATA_HS_MAX_PACKET_SIZE), - 0xFF, /* bInterval: ignore for Bulk transfer */ + 0x00, /* bInterval */ /* Endpoint IN Descriptor */ 0x07, /* bLength: Endpoint Descriptor size */ @@ -283,7 +289,7 @@ __ALIGN_BEGIN static uint8_t USBD_CDC_RNDIS_CfgHSDesc[] __ALIGN_END = 0x02, /* bmAttributes: Bulk */ LOBYTE(CDC_RNDIS_DATA_HS_MAX_PACKET_SIZE), /* wMaxPacketSize: */ HIBYTE(CDC_RNDIS_DATA_HS_MAX_PACKET_SIZE), - 0xFF /* bInterval: ignore for Bulk transfer */ + 0x00 /* bInterval */ }; @@ -295,11 +301,15 @@ __ALIGN_BEGIN static uint8_t USBD_CDC_RNDIS_CfgFSDesc[] __ALIGN_END = USB_DESC_TYPE_CONFIGURATION, /* bDescriptorType: Configuration */ LOBYTE(CDC_RNDIS_CONFIG_DESC_SIZ), /* wTotalLength: Total size of the Config descriptor */ HIBYTE(CDC_RNDIS_CONFIG_DESC_SIZ), - 0x02, /* bNumInterfaces: 2 interface */ + 0x02, /* bNumInterfaces: 2 interfaces */ 0x01, /* bConfigurationValue: Configuration value */ 0x00, /* iConfiguration: Index of string descriptor describing the configuration */ - 0xC0, /* bmAttributes: self powered */ - 0x32, /* MaxPower 0 mA */ +#if (USBD_SELF_POWERED == 1U) + 0xC0, /* bmAttributes: Bus Powered according to user configuration */ +#else + 0x80, /* bmAttributes: Bus Powered according to user configuration */ +#endif + USBD_MAX_POWER, /* MaxPower (mA) */ /*---------------------------------------------------------------------------*/ /* IAD descriptor */ @@ -322,7 +332,7 @@ __ALIGN_BEGIN static uint8_t USBD_CDC_RNDIS_CfgFSDesc[] __ALIGN_END = 0x02, /* bInterfaceClass: Communication Interface Class */ 0x02, /* bInterfaceSubClass:Abstract Control Model */ 0xFF, /* bInterfaceProtocol: Common AT commands */ - 0x00, /* iInterface: */ + 0x00, /* iInterface */ /* Header Functional Descriptor */ 0x05, /* bLength: Endpoint Descriptor size */ @@ -356,7 +366,7 @@ __ALIGN_BEGIN static uint8_t USBD_CDC_RNDIS_CfgFSDesc[] __ALIGN_END = USB_DESC_TYPE_ENDPOINT, /* bDescriptorType: Endpoint */ CDC_RNDIS_CMD_EP, /* bEndpointAddress */ 0x03, /* bmAttributes: Interrupt */ - LOBYTE(CDC_RNDIS_CMD_PACKET_SIZE), /* wMaxPacketSize: */ + LOBYTE(CDC_RNDIS_CMD_PACKET_SIZE), /* wMaxPacketSize */ HIBYTE(CDC_RNDIS_CMD_PACKET_SIZE), CDC_RNDIS_FS_BINTERVAL, /* bInterval */ @@ -368,9 +378,9 @@ __ALIGN_BEGIN static uint8_t USBD_CDC_RNDIS_CfgFSDesc[] __ALIGN_END = 0x00, /* bAlternateSetting: Alternate setting */ 0x02, /* bNumEndpoints: Two endpoints used */ 0x0A, /* bInterfaceClass: CDC */ - 0x00, /* bInterfaceSubClass: */ - 0x00, /* bInterfaceProtocol: */ - 0x00, /* iInterface: */ + 0x00, /* bInterfaceSubClass */ + 0x00, /* bInterfaceProtocol */ + 0x00, /* iInterface */ /* Endpoint OUT Descriptor */ 0x07, /* bLength: Endpoint Descriptor size */ @@ -379,16 +389,16 @@ __ALIGN_BEGIN static uint8_t USBD_CDC_RNDIS_CfgFSDesc[] __ALIGN_END = 0x02, /* bmAttributes: Bulk */ LOBYTE(CDC_RNDIS_DATA_FS_MAX_PACKET_SIZE), /* wMaxPacketSize: */ HIBYTE(CDC_RNDIS_DATA_FS_MAX_PACKET_SIZE), - 0xFF, /* bInterval: ignore for Bulk transfer */ + 0x00, /* bInterval */ /* Endpoint IN Descriptor */ 0x07, /* bLength: Endpoint Descriptor size */ USB_DESC_TYPE_ENDPOINT, /* bDescriptorType: Endpoint */ CDC_RNDIS_IN_EP, /* bEndpointAddress */ 0x02, /* bmAttributes: Bulk */ - LOBYTE(CDC_RNDIS_DATA_FS_MAX_PACKET_SIZE), /* wMaxPacketSize: */ + LOBYTE(CDC_RNDIS_DATA_FS_MAX_PACKET_SIZE), /* wMaxPacketSize */ HIBYTE(CDC_RNDIS_DATA_FS_MAX_PACKET_SIZE), - 0xFF /* bInterval: ignore for Bulk transfer */ + 0x00 /* bInterval */ } ; __ALIGN_BEGIN static uint8_t USBD_CDC_RNDIS_OtherSpeedCfgDesc[] __ALIGN_END = @@ -398,11 +408,15 @@ __ALIGN_BEGIN static uint8_t USBD_CDC_RNDIS_OtherSpeedCfgDesc[] __ALIGN_END = USB_DESC_TYPE_CONFIGURATION, /* bDescriptorType: Configuration */ LOBYTE(CDC_RNDIS_CONFIG_DESC_SIZ), /* wTotalLength:no of returned bytes */ HIBYTE(CDC_RNDIS_CONFIG_DESC_SIZ), - 0x02, /* bNumInterfaces: 2 interface */ + 0x02, /* bNumInterfaces: 2 interfaces */ 0x01, /* bConfigurationValue: Configuration value */ 0x04, /* iConfiguration: Index of string descriptor describing the configuration */ - 0xC0, /* bmAttributes: self powered */ - 0x32, /* MaxPower 0 mA */ +#if (USBD_SELF_POWERED == 1U) + 0xC0, /* bmAttributes: Bus Powered according to user configuration */ +#else + 0x80, /* bmAttributes: Bus Powered according to user configuration */ +#endif + USBD_MAX_POWER, /* MaxPower (mA) */ /*---------------------------------------------------------------------------*/ /* IAD descriptor */ @@ -425,7 +439,7 @@ __ALIGN_BEGIN static uint8_t USBD_CDC_RNDIS_OtherSpeedCfgDesc[] __ALIGN_END = 0x02, /* bInterfaceClass: Communication Interface Class */ 0x02, /* bInterfaceSubClass:Abstract Control Model */ 0xFF, /* bInterfaceProtocol: Common AT commands */ - 0x00, /* iInterface: */ + 0x00, /* iInterface */ /* Header Functional Descriptor */ 0x05, /* bLength: Endpoint Descriptor size */ @@ -459,7 +473,7 @@ __ALIGN_BEGIN static uint8_t USBD_CDC_RNDIS_OtherSpeedCfgDesc[] __ALIGN_END = USB_DESC_TYPE_ENDPOINT, /* bDescriptorType: Endpoint */ CDC_RNDIS_CMD_EP, /* bEndpointAddress */ 0x03, /* bmAttributes: Interrupt */ - LOBYTE(CDC_RNDIS_CMD_PACKET_SIZE), /* wMaxPacketSize: */ + LOBYTE(CDC_RNDIS_CMD_PACKET_SIZE), /* wMaxPacketSize */ HIBYTE(CDC_RNDIS_CMD_PACKET_SIZE), CDC_RNDIS_FS_BINTERVAL, /* bInterval */ @@ -471,27 +485,27 @@ __ALIGN_BEGIN static uint8_t USBD_CDC_RNDIS_OtherSpeedCfgDesc[] __ALIGN_END = 0x00, /* bAlternateSetting: Alternate setting */ 0x02, /* bNumEndpoints: Two endpoints used */ 0x0A, /* bInterfaceClass: CDC */ - 0x00, /* bInterfaceSubClass: */ - 0x00, /* bInterfaceProtocol: */ - 0x00, /* iInterface: */ + 0x00, /* bInterfaceSubClass */ + 0x00, /* bInterfaceProtocol */ + 0x00, /* iInterface */ /* Endpoint OUT Descriptor */ 0x07, /* bLength: Endpoint Descriptor size */ USB_DESC_TYPE_ENDPOINT, /* bDescriptorType: Endpoint */ CDC_RNDIS_OUT_EP, /* bEndpointAddress */ 0x02, /* bmAttributes: Bulk */ - 0x40, /* wMaxPacketSize: */ + 0x40, /* wMaxPacketSize */ 0x00, - 0xFF, /* bInterval: ignore for Bulk transfer */ + 0x00, /* bInterval */ /* Endpoint IN Descriptor */ 0x07, /* bLength: Endpoint Descriptor size */ USB_DESC_TYPE_ENDPOINT, /* bDescriptorType: Endpoint */ CDC_RNDIS_IN_EP, /* bEndpointAddress */ 0x02, /* bmAttributes: Bulk */ - 0x40, /* wMaxPacketSize: */ + 0x40, /* wMaxPacketSize */ 0x00, - 0xFF /* bInterval: ignore for Bulk transfer */ + 0x00 /* bInterval */ }; @@ -540,7 +554,7 @@ static uint8_t USBD_CDC_RNDIS_Init(USBD_HandleTypeDef *pdev, uint8_t cfgidx) UNUSED(cfgidx); USBD_CDC_RNDIS_HandleTypeDef *hcdc; - hcdc = USBD_malloc(sizeof(USBD_CDC_RNDIS_HandleTypeDef)); + hcdc = (USBD_CDC_RNDIS_HandleTypeDef *)USBD_malloc(sizeof(USBD_CDC_RNDIS_HandleTypeDef)); if (hcdc == NULL) { @@ -657,121 +671,127 @@ static uint8_t USBD_CDC_RNDIS_Setup(USBD_HandleTypeDef *pdev, USBD_SetupReqTypedef *req) { USBD_CDC_RNDIS_HandleTypeDef *hcdc = (USBD_CDC_RNDIS_HandleTypeDef *)pdev->pClassData; - USBD_CDC_RNDIS_CtrlMsgTypeDef *Msg = (USBD_CDC_RNDIS_CtrlMsgTypeDef *)hcdc->data; + USBD_CDC_RNDIS_CtrlMsgTypeDef *Msg = (USBD_CDC_RNDIS_CtrlMsgTypeDef *)(void *)hcdc->data; uint8_t ifalt = 0U; uint16_t status_info = 0U; USBD_StatusTypeDef ret = USBD_OK; + if (hcdc == NULL) + { + return (uint8_t)USBD_FAIL; + } + switch (req->bmRequest & USB_REQ_TYPE_MASK) { - case USB_REQ_TYPE_CLASS : - if (req->wLength != 0U) - { - /* Control Request Data from Device to Host, send data prepared by device */ - if ((req->bmRequest & 0x80U) != 0U) + case USB_REQ_TYPE_CLASS : + if (req->wLength != 0U) { - /* Update opcode and length */ - hcdc->CmdOpCode = req->bRequest; - hcdc->CmdLength = (uint8_t)req->wLength; - - if (hcdc->CmdOpCode == CDC_RNDIS_GET_ENCAPSULATED_RESPONSE) + /* Control Request Data from Device to Host, send data prepared by device */ + if ((req->bmRequest & 0x80U) != 0U) { - /* Data of Response Message has already been prepared by USBD_CDC_RNDIS_MsgParsing. - Just check that length is corresponding to right expected value */ - if (req->wLength != Msg->MsgLength) + /* Update opcode and length */ + hcdc->CmdOpCode = req->bRequest; + hcdc->CmdLength = (uint8_t)req->wLength; + + if (hcdc->CmdOpCode == CDC_RNDIS_GET_ENCAPSULATED_RESPONSE) { + /* Data of Response Message has already been prepared by USBD_CDC_RNDIS_MsgParsing. + Just check that length is corresponding to right expected value */ + if (req->wLength != Msg->MsgLength) + { + } } - } - /* Allow application layer to pre-process data or add own processing before sending response */ - ((USBD_CDC_RNDIS_ItfTypeDef *)pdev->pUserData)->Control(req->bRequest, - (uint8_t *)hcdc->data, - req->wLength); - /* Check if Response is ready */ - if (hcdc->ResponseRdy != 0U) - { - /* Clear Response Ready flag */ - hcdc->ResponseRdy = 0U; + /* Allow application layer to pre-process data or add own processing before sending response */ + ((USBD_CDC_RNDIS_ItfTypeDef *)pdev->pUserData)->Control(req->bRequest, + (uint8_t *)hcdc->data, + req->wLength); + /* Check if Response is ready */ + if (hcdc->ResponseRdy != 0U) + { + /* Clear Response Ready flag */ + hcdc->ResponseRdy = 0U; - /* Send data on control endpoint */ - (void)USBD_CtlSendData(pdev, (uint8_t *)hcdc->data, Msg->MsgLength); + /* Send data on control endpoint */ + (void)USBD_CtlSendData(pdev, (uint8_t *)hcdc->data, + MIN(CDC_RNDIS_MAX_DATA_SZE, Msg->MsgLength)); + } + else + { + /* CDC_RNDIS Specification says: If for some reason the device receives a GET ENCAPSULATED RESPONSE + and is unable to respond with a valid data on the Control endpoint, + then it should return a one-byte packet set to 0x00, rather than + stalling the Control endpoint */ + (void)USBD_CtlSendData(pdev, &EmptyResponse, 1U); + } } + /* Control Request Data from Host to Device: Prepare reception of control data stage */ else { - /* CDC_RNDIS Specification says: If for some reason the device receives a GET ENCAPSULATED RESPONSE - and is unable to respond with a valid data on the Control endpoint, - then it should return a one-byte packet set to 0x00, rather than - stalling the Control endpoint */ - (void)USBD_CtlSendData(pdev, &EmptyResponse, 1U); - } - } - /* Control Request Data from Host to Device: Prepare reception of control data stage */ - else - { - hcdc->CmdOpCode = req->bRequest; - hcdc->CmdLength = (uint8_t)req->wLength; - - (void)USBD_CtlPrepareRx(pdev, (uint8_t *)hcdc->data, req->wLength); - } - } - /* No Data control request: there is no such request for CDC_RNDIS protocol, - so let application layer manage this case */ - else - { - ((USBD_CDC_RNDIS_ItfTypeDef *)pdev->pUserData)->Control(req->bRequest, - (uint8_t *)req, 0U); - } - break; + hcdc->CmdOpCode = req->bRequest; + hcdc->CmdLength = (uint8_t)MIN(CDC_RNDIS_CMD_PACKET_SIZE, req->wLength); - case USB_REQ_TYPE_STANDARD: - switch (req->bRequest) - { - case USB_REQ_GET_STATUS: - if (pdev->dev_state == USBD_STATE_CONFIGURED) - { - (void)USBD_CtlSendData(pdev, (uint8_t *)&status_info, 2U); + (void)USBD_CtlPrepareRx(pdev, (uint8_t *)hcdc->data, hcdc->CmdLength); + } } + /* No Data control request: there is no such request for CDC_RNDIS protocol, + so let application layer manage this case */ else { - USBD_CtlError(pdev, req); - ret = USBD_FAIL; + ((USBD_CDC_RNDIS_ItfTypeDef *)pdev->pUserData)->Control(req->bRequest, + (uint8_t *)req, 0U); } break; - case USB_REQ_GET_INTERFACE: - if (pdev->dev_state == USBD_STATE_CONFIGURED) + case USB_REQ_TYPE_STANDARD: + switch (req->bRequest) { - (void)USBD_CtlSendData(pdev, &ifalt, 1U); - } - else - { - USBD_CtlError(pdev, req); - ret = USBD_FAIL; - } - break; + case USB_REQ_GET_STATUS: + if (pdev->dev_state == USBD_STATE_CONFIGURED) + { + (void)USBD_CtlSendData(pdev, (uint8_t *)&status_info, 2U); + } + 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_INTERFACE: + if (pdev->dev_state == USBD_STATE_CONFIGURED) + { + (void)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_CLEAR_FEATURE: + break; - case USB_REQ_CLEAR_FEATURE: + default: + USBD_CtlError(pdev, req); + ret = USBD_FAIL; + break; + } break; default: USBD_CtlError(pdev, req); ret = USBD_FAIL; break; - } - break; - - default: - USBD_CtlError(pdev, req); - ret = USBD_FAIL; - break; } return (uint8_t)ret; @@ -810,7 +830,11 @@ static uint8_t USBD_CDC_RNDIS_DataIn(USBD_HandleTypeDef *pdev, uint8_t epnum) else { hcdc->TxState = 0U; - ((USBD_CDC_RNDIS_ItfTypeDef *)pdev->pUserData)->TransmitCplt(hcdc->TxBuffer, &hcdc->TxLength, epnum); + + if (((USBD_CDC_RNDIS_ItfTypeDef *)pdev->pUserData)->TransmitCplt != NULL) + { + ((USBD_CDC_RNDIS_ItfTypeDef *)pdev->pUserData)->TransmitCplt(hcdc->TxBuffer, &hcdc->TxLength, epnum); + } } } else if (epnum == (CDC_RNDIS_CMD_EP & 0x7FU)) @@ -818,7 +842,7 @@ static uint8_t USBD_CDC_RNDIS_DataIn(USBD_HandleTypeDef *pdev, uint8_t epnum) if (hcdc->NotificationStatus != 0U) { (void)USBD_CDC_RNDIS_SendNotification(pdev, CONNECTION_SPEED_CHANGE, - 0U, (uint8_t *)ConnSpeedTab); + 0U, (uint8_t *)ConnSpeedTab); hcdc->NotificationStatus = 0U; } @@ -863,10 +887,10 @@ static uint8_t USBD_CDC_RNDIS_DataOut(USBD_HandleTypeDef *pdev, uint8_t epnum) (hcdc->RxLength >= (CDC_RNDIS_ETH_MAX_SEGSZE + sizeof(USBD_CDC_RNDIS_PacketMsgTypeDef)))) { /* USB data will be immediately processed, this allow next USB traffic being - NACKed till the end of the application Xfer */ + NAKed till the end of the application Xfer */ /* Call data packet message parsing and processing function */ - (void)USBD_CDC_RNDIS_ProcessPacketMsg(pdev, (USBD_CDC_RNDIS_PacketMsgTypeDef *)hcdc->RxBuffer); + (void)USBD_CDC_RNDIS_ProcessPacketMsg(pdev, (USBD_CDC_RNDIS_PacketMsgTypeDef *)(void *)hcdc->RxBuffer); } else { @@ -894,6 +918,11 @@ static uint8_t USBD_CDC_RNDIS_EP0_RxReady(USBD_HandleTypeDef *pdev) { USBD_CDC_RNDIS_HandleTypeDef *hcdc = (USBD_CDC_RNDIS_HandleTypeDef *)pdev->pClassData; + if (hcdc == NULL) + { + return (uint8_t)USBD_FAIL; + } + if ((pdev->pUserData != NULL) && (hcdc->CmdOpCode != 0xFFU)) { /* Check if the received command is SendEncapsulated command */ @@ -1030,6 +1059,11 @@ uint8_t USBD_CDC_RNDIS_SetTxBuffer(USBD_HandleTypeDef *pdev, uint8_t *pbuff, uin { USBD_CDC_RNDIS_HandleTypeDef *hcdc = (USBD_CDC_RNDIS_HandleTypeDef *)pdev->pClassData; + if (hcdc == NULL) + { + return (uint8_t)USBD_FAIL; + } + hcdc->TxBuffer = pbuff; hcdc->TxLength = length; @@ -1047,6 +1081,11 @@ uint8_t USBD_CDC_RNDIS_SetRxBuffer(USBD_HandleTypeDef *pdev, uint8_t *pbuff) { USBD_CDC_RNDIS_HandleTypeDef *hcdc = (USBD_CDC_RNDIS_HandleTypeDef *)pdev->pClassData; + if (hcdc == NULL) + { + return (uint8_t)USBD_FAIL; + } + hcdc->RxBuffer = pbuff; return (uint8_t)USBD_OK; @@ -1071,7 +1110,7 @@ uint8_t USBD_CDC_RNDIS_TransmitPacket(USBD_HandleTypeDef *pdev) } hcdc = (USBD_CDC_RNDIS_HandleTypeDef *)pdev->pClassData; - PacketMsg = (USBD_CDC_RNDIS_PacketMsgTypeDef *)hcdc->TxBuffer; + PacketMsg = (USBD_CDC_RNDIS_PacketMsgTypeDef *)(void *)hcdc->TxBuffer; if (hcdc->TxState == 0U) { @@ -1097,7 +1136,7 @@ uint8_t USBD_CDC_RNDIS_TransmitPacket(USBD_HandleTypeDef *pdev) /* Transmit next packet */ (void)USBD_LL_Transmit(pdev, CDC_RNDIS_IN_EP, hcdc->TxBuffer, hcdc->TxLength); - ret = USBD_OK; + ret = USBD_OK; } return (uint8_t)ret; @@ -1150,32 +1189,39 @@ uint8_t USBD_CDC_RNDIS_SendNotification(USBD_HandleTypeDef *pdev, UNUSED(bVal); UNUSED(pData); + if (hcdc == NULL) + { + return (uint8_t)USBD_FAIL; + } + /* Initialize the request fields */ (hcdc->Req).bmRequest = CDC_RNDIS_BMREQUEST_TYPE_RNDIS; (hcdc->Req).bRequest = (uint8_t)Notif; switch (Notif) { - case RESPONSE_AVAILABLE: - (hcdc->Req).wValue = 0U; - (hcdc->Req).wIndex = CDC_RNDIS_CMD_ITF_NBR; - (hcdc->Req).wLength = 0U; - for (Idx = 0U; Idx < 8U; Idx++) - { - (hcdc->Req).data[Idx] = 0U; - } - ReqSize = 8U; - break; + case RESPONSE_AVAILABLE: + (hcdc->Req).wValue = 0U; + (hcdc->Req).wIndex = CDC_RNDIS_CMD_ITF_NBR; + (hcdc->Req).wLength = 0U; + + for (Idx = 0U; Idx < 8U; Idx++) + { + (hcdc->Req).data[Idx] = 0U; + } - default: - ret = USBD_FAIL; - break; + ReqSize = 8U; + break; + + default: + ret = USBD_FAIL; + break; } /* Transmit notification packet */ if (ReqSize != 0U) { - (void)USBD_LL_Transmit(pdev, CDC_RNDIS_CMD_EP, (uint8_t *)&(hcdc->Req), ReqSize); + (void)USBD_LL_Transmit(pdev, CDC_RNDIS_CMD_EP, (uint8_t *) &(hcdc->Req), ReqSize); } return (uint8_t)ret; @@ -1192,46 +1238,46 @@ uint8_t USBD_CDC_RNDIS_SendNotification(USBD_HandleTypeDef *pdev, */ static uint8_t USBD_CDC_RNDIS_MsgParsing(USBD_HandleTypeDef *pdev, uint8_t *RxBuff) { - USBD_CDC_RNDIS_CtrlMsgTypeDef *Msg = (USBD_CDC_RNDIS_CtrlMsgTypeDef *)RxBuff; + USBD_CDC_RNDIS_CtrlMsgTypeDef *Msg = (USBD_CDC_RNDIS_CtrlMsgTypeDef *)(void *)RxBuff; static uint8_t ret = (uint8_t)USBD_OK; /* Check message type */ switch (Msg->MsgType) { /* CDC_RNDIS Initialize message */ - case CDC_RNDIS_INITIALIZE_MSG_ID: - ret = USBD_CDC_RNDIS_ProcessInitMsg(pdev, (USBD_CDC_RNDIS_InitMsgTypeDef *)Msg); - break; + case CDC_RNDIS_INITIALIZE_MSG_ID: + ret = USBD_CDC_RNDIS_ProcessInitMsg(pdev, (USBD_CDC_RNDIS_InitMsgTypeDef *)(void *)Msg); + break; /* CDC_RNDIS Halt message */ - case CDC_RNDIS_HALT_MSG_ID: - ret = USBD_CDC_RNDIS_ProcessHaltMsg(pdev, (USBD_CDC_RNDIS_HaltMsgTypeDef *)Msg); - break; + case CDC_RNDIS_HALT_MSG_ID: + ret = USBD_CDC_RNDIS_ProcessHaltMsg(pdev, (USBD_CDC_RNDIS_HaltMsgTypeDef *)(void *)Msg); + break; /* CDC_RNDIS Query message */ - case CDC_RNDIS_QUERY_MSG_ID: - ret = USBD_CDC_RNDIS_ProcessQueryMsg(pdev, (USBD_CDC_RNDIS_QueryMsgTypeDef *)Msg); - break; + case CDC_RNDIS_QUERY_MSG_ID: + ret = USBD_CDC_RNDIS_ProcessQueryMsg(pdev, (USBD_CDC_RNDIS_QueryMsgTypeDef *)(void *)Msg); + break; /* CDC_RNDIS Set message */ - case CDC_RNDIS_SET_MSG_ID: - ret = USBD_CDC_RNDIS_ProcessSetMsg(pdev, (USBD_CDC_RNDIS_SetMsgTypeDef *)Msg); - break; + case CDC_RNDIS_SET_MSG_ID: + ret = USBD_CDC_RNDIS_ProcessSetMsg(pdev, (USBD_CDC_RNDIS_SetMsgTypeDef *)(void *)Msg); + break; /* CDC_RNDIS Reset message */ - case CDC_RNDIS_RESET_MSG_ID: - ret = USBD_CDC_RNDIS_ProcessResetMsg(pdev, (USBD_CDC_RNDIS_ResetMsgTypeDef *)Msg); - break; + case CDC_RNDIS_RESET_MSG_ID: + ret = USBD_CDC_RNDIS_ProcessResetMsg(pdev, (USBD_CDC_RNDIS_ResetMsgTypeDef *)(void *)Msg); + break; /* CDC_RNDIS Keep-Alive message */ - case CDC_RNDIS_KEEPALIVE_MSG_ID: - ret = USBD_CDC_RNDIS_ProcessKeepAliveMsg(pdev, (USBD_CDC_RNDIS_KpAliveMsgTypeDef *)Msg); - break; + case CDC_RNDIS_KEEPALIVE_MSG_ID: + ret = USBD_CDC_RNDIS_ProcessKeepAliveMsg(pdev, (USBD_CDC_RNDIS_KpAliveMsgTypeDef *)(void *)Msg); + break; /* CDC_RNDIS unsupported message */ - default: - ret = USBD_CDC_RNDIS_ProcessUnsupportedMsg(pdev, (USBD_CDC_RNDIS_CtrlMsgTypeDef *)Msg); - break; + default: + ret = USBD_CDC_RNDIS_ProcessUnsupportedMsg(pdev, (USBD_CDC_RNDIS_CtrlMsgTypeDef *)(void *)Msg); + break; } return ret; @@ -1255,11 +1301,16 @@ static uint8_t USBD_CDC_RNDIS_ProcessInitMsg(USBD_HandleTypeDef *pdev, USBD_CDC_RNDIS_InitMsgTypeDef *InitMessage = (USBD_CDC_RNDIS_InitMsgTypeDef *)Msg; /* Use same Msg input buffer as response buffer */ - USBD_CDC_RNDIS_InitCpltMsgTypeDef *InitResponse = (USBD_CDC_RNDIS_InitCpltMsgTypeDef *)Msg; + USBD_CDC_RNDIS_InitCpltMsgTypeDef *InitResponse = (USBD_CDC_RNDIS_InitCpltMsgTypeDef *)(void *)Msg; /* Store the Message Request ID */ uint32_t ReqId = InitMessage->ReqId; + if (hcdc == NULL) + { + return (uint8_t)USBD_FAIL; + } + /* Check correctness of the message (MsgType already checked by entry to this function) */ if ((InitMessage->MsgLength != sizeof(USBD_CDC_RNDIS_InitMsgTypeDef)) || \ (InitMessage->MajorVersion < CDC_RNDIS_VERSION_MAJOR)) @@ -1311,10 +1362,15 @@ static uint8_t USBD_CDC_RNDIS_ProcessHaltMsg(USBD_HandleTypeDef *pdev, /* Get the CDC_RNDIS handle pointer */ USBD_CDC_RNDIS_HandleTypeDef *hcdc = (USBD_CDC_RNDIS_HandleTypeDef *)pdev->pClassData; + if (hcdc == NULL) + { + return (uint8_t)USBD_FAIL; + } + /* Set CDC_RNDIS state to INITIALIZED */ hcdc->State = CDC_RNDIS_STATE_UNINITIALIZED; - /* No response required for this message, so no notification (RESPNSE_AVAILABLE) is sent */ + /* No response required for this message, so no notification (RESPONSE_AVAILABLE) is sent */ UNUSED(Msg); @@ -1336,11 +1392,16 @@ static uint8_t USBD_CDC_RNDIS_ProcessKeepAliveMsg(USBD_HandleTypeDef *pdev, USBD_CDC_RNDIS_HandleTypeDef *hcdc = (USBD_CDC_RNDIS_HandleTypeDef *)pdev->pClassData; /* Use same Msg input buffer as response buffer */ - USBD_CDC_RNDIS_KpAliveCpltMsgTypeDef *InitResponse = (USBD_CDC_RNDIS_KpAliveCpltMsgTypeDef *)Msg; + USBD_CDC_RNDIS_KpAliveCpltMsgTypeDef *InitResponse = (USBD_CDC_RNDIS_KpAliveCpltMsgTypeDef *)(void *)Msg; /* Store the Message Request ID */ uint32_t ReqId = Msg->ReqId; + if (hcdc == NULL) + { + return (uint8_t)USBD_FAIL; + } + /* Check correctness of the message (MsgType already checked by entry to this function) */ if (Msg->MsgLength != sizeof(USBD_CDC_RNDIS_KpAliveMsgTypeDef)) { @@ -1381,114 +1442,119 @@ static uint8_t USBD_CDC_RNDIS_ProcessQueryMsg(USBD_HandleTypeDef *pdev, USBD_CDC_RNDIS_HandleTypeDef *hcdc = (USBD_CDC_RNDIS_HandleTypeDef *)pdev->pClassData; /* Use same Msg input buffer as response buffer */ - USBD_CDC_RNDIS_QueryCpltMsgTypeDef *QueryResponse = (USBD_CDC_RNDIS_QueryCpltMsgTypeDef *)Msg; + USBD_CDC_RNDIS_QueryCpltMsgTypeDef *QueryResponse = (USBD_CDC_RNDIS_QueryCpltMsgTypeDef *)(void *)Msg; /* Store the Message Request ID */ uint32_t ReqId = Msg->RequestId; + if (hcdc == NULL) + { + return (uint8_t)USBD_FAIL; + } + /* Process the OID depending on its code */ switch (Msg->Oid) { - case OID_GEN_SUPPORTED_LIST: - QueryResponse->InfoBufLength = sizeof(CDC_RNDIS_SupportedOIDs); - (void)USBD_memcpy(QueryResponse->InfoBuf, CDC_RNDIS_SupportedOIDs, - sizeof(CDC_RNDIS_SupportedOIDs)); - - QueryResponse->Status = CDC_RNDIS_STATUS_SUCCESS; - break; - - case OID_GEN_HARDWARE_STATUS: - QueryResponse->InfoBufLength = sizeof(uint32_t); - QueryResponse->InfoBuf[0] = CDC_RNDIS_HW_STS_READY; - QueryResponse->Status = CDC_RNDIS_STATUS_SUCCESS; - break; - - case OID_GEN_MEDIA_SUPPORTED: - case OID_GEN_MEDIA_IN_USE: - QueryResponse->InfoBufLength = sizeof(uint32_t); - QueryResponse->InfoBuf[0] = CDC_RNDIS_MEDIUM_802_3; - QueryResponse->Status = CDC_RNDIS_STATUS_SUCCESS; - break; - - case OID_GEN_VENDOR_ID: - QueryResponse->InfoBufLength = sizeof(uint32_t); - QueryResponse->InfoBuf[0] = USBD_CDC_RNDIS_VID; - QueryResponse->Status = CDC_RNDIS_STATUS_SUCCESS; - break; - - case OID_GEN_MAXIMUM_FRAME_SIZE: - case OID_GEN_TRANSMIT_BLOCK_SIZE: - case OID_GEN_RECEIVE_BLOCK_SIZE: - QueryResponse->InfoBufLength = sizeof(uint32_t); - QueryResponse->InfoBuf[0] = CDC_RNDIS_ETH_FRAME_SIZE_MAX; - QueryResponse->Status = CDC_RNDIS_STATUS_SUCCESS; - break; - - case OID_GEN_VENDOR_DESCRIPTION: - QueryResponse->InfoBufLength = (strlen(USBD_CDC_RNDIS_VENDOR_DESC) + 1U); - (void)USBD_memcpy(QueryResponse->InfoBuf, USBD_CDC_RNDIS_VENDOR_DESC, - strlen(USBD_CDC_RNDIS_VENDOR_DESC)); - - QueryResponse->Status = CDC_RNDIS_STATUS_SUCCESS; - break; - - case OID_GEN_MEDIA_CONNECT_STATUS: - QueryResponse->InfoBufLength = sizeof(uint32_t); - QueryResponse->InfoBuf[0] = CDC_RNDIS_MEDIA_STATE_CONNECTED; - QueryResponse->Status = CDC_RNDIS_STATUS_SUCCESS; - break; - - case OID_GEN_MAXIMUM_SEND_PACKETS: - QueryResponse->InfoBufLength = sizeof(uint32_t); - QueryResponse->InfoBuf[0] = 1U; - QueryResponse->Status = CDC_RNDIS_STATUS_SUCCESS; - break; - - case OID_GEN_LINK_SPEED: - QueryResponse->InfoBufLength = sizeof(uint32_t); - QueryResponse->InfoBuf[0] = USBD_CDC_RNDIS_LINK_SPEED; - QueryResponse->Status = CDC_RNDIS_STATUS_SUCCESS; - break; - - case OID_802_3_PERMANENT_ADDRESS: - case OID_802_3_CURRENT_ADDRESS: - QueryResponse->InfoBufLength = 6U; - (void)USBD_memcpy(QueryResponse->InfoBuf, MAC_StrDesc, 6); - QueryResponse->Status = CDC_RNDIS_STATUS_SUCCESS; - break; - - case OID_802_3_MAXIMUM_LIST_SIZE: - QueryResponse->InfoBufLength = sizeof(uint32_t); - QueryResponse->InfoBuf[0] = 1U; /* Only one multicast address supported */ - QueryResponse->Status = CDC_RNDIS_STATUS_SUCCESS; - break; - - case OID_GEN_CURRENT_PACKET_FILTER: - QueryResponse->InfoBufLength = sizeof(uint32_t); - QueryResponse->InfoBuf[0] = 0xFFFFFFU; /* USBD_CDC_RNDIS_DEVICE.packetFilter; */ - QueryResponse->Status = CDC_RNDIS_STATUS_SUCCESS; - break; - - case OID_802_3_RCV_ERROR_ALIGNMENT: - case OID_802_3_XMIT_ONE_COLLISION: - case OID_802_3_XMIT_MORE_COLLISIONS: - QueryResponse->InfoBufLength = sizeof(uint32_t); - QueryResponse->InfoBuf[0] = 0U; /* Unused OIDs, return zero */ - QueryResponse->Status = CDC_RNDIS_STATUS_SUCCESS; - break; - - case OID_GEN_MAXIMUM_TOTAL_SIZE: - QueryResponse->InfoBufLength = sizeof(uint32_t); - /* Indicate maximum overall buffer (Ethernet frame and CDC_RNDIS header) the adapter can handle */ - QueryResponse->InfoBuf[0] = (CDC_RNDIS_MESSAGE_BUFFER_SIZE + CDC_RNDIS_ETH_FRAME_SIZE_MAX); - QueryResponse->Status = CDC_RNDIS_STATUS_SUCCESS; - break; - - default: - /* Unknown or unsupported OID */ - QueryResponse->InfoBufLength = 0U; - QueryResponse->Status = CDC_RNDIS_STATUS_FAILURE; - break; + case OID_GEN_SUPPORTED_LIST: + QueryResponse->InfoBufLength = sizeof(CDC_RNDIS_SupportedOIDs); + (void)USBD_memcpy(QueryResponse->InfoBuf, CDC_RNDIS_SupportedOIDs, + sizeof(CDC_RNDIS_SupportedOIDs)); + + QueryResponse->Status = CDC_RNDIS_STATUS_SUCCESS; + break; + + case OID_GEN_HARDWARE_STATUS: + QueryResponse->InfoBufLength = sizeof(uint32_t); + QueryResponse->InfoBuf[0] = CDC_RNDIS_HW_STS_READY; + QueryResponse->Status = CDC_RNDIS_STATUS_SUCCESS; + break; + + case OID_GEN_MEDIA_SUPPORTED: + case OID_GEN_MEDIA_IN_USE: + QueryResponse->InfoBufLength = sizeof(uint32_t); + QueryResponse->InfoBuf[0] = CDC_RNDIS_MEDIUM_802_3; + QueryResponse->Status = CDC_RNDIS_STATUS_SUCCESS; + break; + + case OID_GEN_VENDOR_ID: + QueryResponse->InfoBufLength = sizeof(uint32_t); + QueryResponse->InfoBuf[0] = USBD_CDC_RNDIS_VID; + QueryResponse->Status = CDC_RNDIS_STATUS_SUCCESS; + break; + + case OID_GEN_MAXIMUM_FRAME_SIZE: + case OID_GEN_TRANSMIT_BLOCK_SIZE: + case OID_GEN_RECEIVE_BLOCK_SIZE: + QueryResponse->InfoBufLength = sizeof(uint32_t); + QueryResponse->InfoBuf[0] = CDC_RNDIS_ETH_FRAME_SIZE_MAX; + QueryResponse->Status = CDC_RNDIS_STATUS_SUCCESS; + break; + + case OID_GEN_VENDOR_DESCRIPTION: + QueryResponse->InfoBufLength = (strlen(USBD_CDC_RNDIS_VENDOR_DESC) + 1U); + (void)USBD_memcpy(QueryResponse->InfoBuf, USBD_CDC_RNDIS_VENDOR_DESC, + strlen(USBD_CDC_RNDIS_VENDOR_DESC)); + + QueryResponse->Status = CDC_RNDIS_STATUS_SUCCESS; + break; + + case OID_GEN_MEDIA_CONNECT_STATUS: + QueryResponse->InfoBufLength = sizeof(uint32_t); + QueryResponse->InfoBuf[0] = CDC_RNDIS_MEDIA_STATE_CONNECTED; + QueryResponse->Status = CDC_RNDIS_STATUS_SUCCESS; + break; + + case OID_GEN_MAXIMUM_SEND_PACKETS: + QueryResponse->InfoBufLength = sizeof(uint32_t); + QueryResponse->InfoBuf[0] = 1U; + QueryResponse->Status = CDC_RNDIS_STATUS_SUCCESS; + break; + + case OID_GEN_LINK_SPEED: + QueryResponse->InfoBufLength = sizeof(uint32_t); + QueryResponse->InfoBuf[0] = USBD_CDC_RNDIS_LINK_SPEED; + QueryResponse->Status = CDC_RNDIS_STATUS_SUCCESS; + break; + + case OID_802_3_PERMANENT_ADDRESS: + case OID_802_3_CURRENT_ADDRESS: + QueryResponse->InfoBufLength = 6U; + (void)USBD_memcpy(QueryResponse->InfoBuf, MAC_StrDesc, 6); + QueryResponse->Status = CDC_RNDIS_STATUS_SUCCESS; + break; + + case OID_802_3_MAXIMUM_LIST_SIZE: + QueryResponse->InfoBufLength = sizeof(uint32_t); + QueryResponse->InfoBuf[0] = 1U; /* Only one multicast address supported */ + QueryResponse->Status = CDC_RNDIS_STATUS_SUCCESS; + break; + + case OID_GEN_CURRENT_PACKET_FILTER: + QueryResponse->InfoBufLength = sizeof(uint32_t); + QueryResponse->InfoBuf[0] = 0xFFFFFFU; /* USBD_CDC_RNDIS_DEVICE.packetFilter; */ + QueryResponse->Status = CDC_RNDIS_STATUS_SUCCESS; + break; + + case OID_802_3_RCV_ERROR_ALIGNMENT: + case OID_802_3_XMIT_ONE_COLLISION: + case OID_802_3_XMIT_MORE_COLLISIONS: + QueryResponse->InfoBufLength = sizeof(uint32_t); + QueryResponse->InfoBuf[0] = 0U; /* Unused OIDs, return zero */ + QueryResponse->Status = CDC_RNDIS_STATUS_SUCCESS; + break; + + case OID_GEN_MAXIMUM_TOTAL_SIZE: + QueryResponse->InfoBufLength = sizeof(uint32_t); + /* Indicate maximum overall buffer (Ethernet frame and CDC_RNDIS header) the adapter can handle */ + QueryResponse->InfoBuf[0] = (CDC_RNDIS_MESSAGE_BUFFER_SIZE + CDC_RNDIS_ETH_FRAME_SIZE_MAX); + QueryResponse->Status = CDC_RNDIS_STATUS_SUCCESS; + break; + + default: + /* Unknown or unsupported OID */ + QueryResponse->InfoBufLength = 0U; + QueryResponse->Status = CDC_RNDIS_STATUS_FAILURE; + break; } /* Setup the response buffer content */ @@ -1503,7 +1569,7 @@ static uint8_t USBD_CDC_RNDIS_ProcessQueryMsg(USBD_HandleTypeDef *pdev, /* Send Notification on Interrupt EP to inform Host that response is ready */ (void)USBD_CDC_RNDIS_SendNotification(pdev, RESPONSE_AVAILABLE, 0U, NULL); - return(uint8_t)USBD_OK; + return (uint8_t)USBD_OK; } @@ -1524,28 +1590,33 @@ static uint8_t USBD_CDC_RNDIS_ProcessSetMsg(USBD_HandleTypeDef *pdev, USBD_CDC_RNDIS_SetMsgTypeDef *SetMessage = (USBD_CDC_RNDIS_SetMsgTypeDef *)Msg; /* Use same Msg input buffer as response buffer */ - USBD_CDC_RNDIS_SetCpltMsgTypeDef *SetResponse = (USBD_CDC_RNDIS_SetCpltMsgTypeDef *)Msg; + USBD_CDC_RNDIS_SetCpltMsgTypeDef *SetResponse = (USBD_CDC_RNDIS_SetCpltMsgTypeDef *)(void *)Msg; /* Store the Message Request ID */ uint32_t ReqId = SetMessage->ReqId; + if (hcdc == NULL) + { + return (uint8_t)USBD_FAIL; + } + switch (SetMessage->Oid) { - case OID_GEN_CURRENT_PACKET_FILTER: - /* Setup the packet filter value */ - hcdc->PacketFilter = SetMessage->InfoBuf[0]; - SetResponse->Status = CDC_RNDIS_STATUS_SUCCESS; - break; - - case OID_802_3_MULTICAST_LIST: - /* List of multicast addresses on a miniport adapter */ - SetResponse->Status = CDC_RNDIS_STATUS_SUCCESS; - break; - - default: - /* Report an error */ - SetResponse->Status = CDC_RNDIS_STATUS_FAILURE; - break; + case OID_GEN_CURRENT_PACKET_FILTER: + /* Setup the packet filter value */ + hcdc->PacketFilter = SetMessage->InfoBuf[0]; + SetResponse->Status = CDC_RNDIS_STATUS_SUCCESS; + break; + + case OID_802_3_MULTICAST_LIST: + /* List of multicast addresses on a miniport adapter */ + SetResponse->Status = CDC_RNDIS_STATUS_SUCCESS; + break; + + default: + /* Report an error */ + SetResponse->Status = CDC_RNDIS_STATUS_FAILURE; + break; } /* Prepare response buffer */ @@ -1578,7 +1649,12 @@ static uint8_t USBD_CDC_RNDIS_ProcessResetMsg(USBD_HandleTypeDef *pdev, /* Get the CDC_RNDIS handle pointer */ USBD_CDC_RNDIS_HandleTypeDef *hcdc = (USBD_CDC_RNDIS_HandleTypeDef *)pdev->pClassData; /* Use same Msg input buffer as response buffer */ - USBD_CDC_RNDIS_ResetCpltMsgTypeDef *ResetResponse = (USBD_CDC_RNDIS_ResetCpltMsgTypeDef *)Msg; + USBD_CDC_RNDIS_ResetCpltMsgTypeDef *ResetResponse = (USBD_CDC_RNDIS_ResetCpltMsgTypeDef *)(void *)Msg; + + if (hcdc == NULL) + { + return (uint8_t)USBD_FAIL; + } if ((ResetMessage->MsgLength != sizeof(USBD_CDC_RNDIS_ResetMsgTypeDef)) || \ (ResetMessage->Reserved != 0U)) @@ -1627,13 +1703,18 @@ static uint8_t USBD_CDC_RNDIS_ProcessPacketMsg(USBD_HandleTypeDef *pdev, /* Get and format the Msg input */ USBD_CDC_RNDIS_PacketMsgTypeDef *PacketMsg = (USBD_CDC_RNDIS_PacketMsgTypeDef *)Msg; + if (hcdc == NULL) + { + return (uint8_t)USBD_FAIL; + } + /* Check correctness of the message */ if ((PacketMsg->MsgType != CDC_RNDIS_PACKET_MSG_ID)) { return (uint8_t)USBD_FAIL; } - /* Point to the payload and udpate the message length */ + /* Point to the payload and update the message length */ /* Use temporary storage variables to comply with MISRA-C 2012 rule of (+) operand allowed types */ tmp1 = (uint32_t)PacketMsg; @@ -1649,12 +1730,12 @@ static uint8_t USBD_CDC_RNDIS_ProcessPacketMsg(USBD_HandleTypeDef *pdev, /** -* @brief USBD_CDC_RNDIS_ProcessUnsupportedMsg -* Parse, extract data and check correctness of CDC_RNDIS KeepAlive command. -* @param pdev: USB Device Handle pointer -* @param Msg: Pointer to the message data extracted from SendEncapsulated command -* @retval status -*/ + * @brief USBD_CDC_RNDIS_ProcessUnsupportedMsg + * Parse, extract data and check correctness of CDC_RNDIS KeepAlive command. + * @param pdev: USB Device Handle pointer + * @param Msg: Pointer to the message data extracted from SendEncapsulated command + * @retval status + */ static uint8_t USBD_CDC_RNDIS_ProcessUnsupportedMsg(USBD_HandleTypeDef *pdev, USBD_CDC_RNDIS_CtrlMsgTypeDef *Msg) { @@ -1662,7 +1743,12 @@ static uint8_t USBD_CDC_RNDIS_ProcessUnsupportedMsg(USBD_HandleTypeDef *pdev, USBD_CDC_RNDIS_HandleTypeDef *hcdc = (USBD_CDC_RNDIS_HandleTypeDef *)pdev->pClassData; /* Use same Msg input buffer as response buffer */ - USBD_CDC_RNDIS_StsChangeMsgTypeDef *Response = (USBD_CDC_RNDIS_StsChangeMsgTypeDef *)Msg; + USBD_CDC_RNDIS_StsChangeMsgTypeDef *Response = (USBD_CDC_RNDIS_StsChangeMsgTypeDef *)(void *)Msg; + + if (hcdc == NULL) + { + return (uint8_t)USBD_FAIL; + } /* Setup the response buffer content */ Response->MsgType = CDC_RNDIS_INDICATE_STATUS_MSG_ID; diff --git a/system/Middlewares/ST/STM32_USB_Device_Library/Class/CDC_RNDIS/Src/usbd_cdc_rndis_if_template.c b/system/Middlewares/ST/STM32_USB_Device_Library/Class/CDC_RNDIS/Src/usbd_cdc_rndis_if_template.c index 9408d43bb4..ad88c320a8 100644 --- a/system/Middlewares/ST/STM32_USB_Device_Library/Class/CDC_RNDIS/Src/usbd_cdc_rndis_if_template.c +++ b/system/Middlewares/ST/STM32_USB_Device_Library/Class/CDC_RNDIS/Src/usbd_cdc_rndis_if_template.c @@ -38,12 +38,12 @@ /* Private macro -------------------------------------------------------------*/ /* Private variables ---------------------------------------------------------*/ #if defined ( __ICCARM__ ) /*!< IAR Compiler */ - #pragma data_alignment=4 +#pragma data_alignment=4 #endif __ALIGN_BEGIN uint8_t UserRxBuffer[CDC_RNDIS_ETH_MAX_SEGSZE + 100] __ALIGN_END; /* Received Data over USB are stored in this buffer */ #if defined ( __ICCARM__ ) /*!< IAR Compiler */ - #pragma data_alignment=4 +#pragma data_alignment=4 #endif __ALIGN_BEGIN static uint8_t UserTxBuffer[CDC_RNDIS_ETH_MAX_SEGSZE + 100] __ALIGN_END; /* Received Data over CDC_RNDIS (CDC_RNDIS interface) are stored in this buffer */ @@ -179,14 +179,14 @@ static int8_t CDC_RNDIS_Itf_Receive(uint8_t *Buf, uint32_t *Len) hcdc_cdc_rndis->RxState = 1U; UNUSED(Buf); - UNUSED(Len); + UNUSED(Len); return (0); } /** * @brief CDC_RNDIS_Itf_TransmitCplt - * Data transmited callback + * Data transmitted callback * * @note * This function is IN transfer complete callback used to inform user that diff --git a/system/Middlewares/ST/STM32_USB_Device_Library/Class/CustomHID/Inc/usbd_customhid.h b/system/Middlewares/ST/STM32_USB_Device_Library/Class/CustomHID/Inc/usbd_customhid.h index a1dcd7ca7b..da01685017 100644 --- a/system/Middlewares/ST/STM32_USB_Device_Library/Class/CustomHID/Inc/usbd_customhid.h +++ b/system/Middlewares/ST/STM32_USB_Device_Library/Class/CustomHID/Inc/usbd_customhid.h @@ -42,10 +42,16 @@ extern "C" { * @{ */ #define CUSTOM_HID_EPIN_ADDR 0x81U + +#ifndef CUSTOM_HID_EPIN_SIZE #define CUSTOM_HID_EPIN_SIZE 0x02U +#endif #define CUSTOM_HID_EPOUT_ADDR 0x01U + +#ifndef CUSTOM_HID_EPOUT_SIZE #define CUSTOM_HID_EPOUT_SIZE 0x02U +#endif #define USB_CUSTOM_HID_CONFIG_DESC_SIZ 41U #define USB_CUSTOM_HID_DESC_SIZ 9U diff --git a/system/Middlewares/ST/STM32_USB_Device_Library/Class/CustomHID/Src/usbd_customhid.c b/system/Middlewares/ST/STM32_USB_Device_Library/Class/CustomHID/Src/usbd_customhid.c index 268027407f..2fbc0570ef 100644 --- a/system/Middlewares/ST/STM32_USB_Device_Library/Class/CustomHID/Src/usbd_customhid.c +++ b/system/Middlewares/ST/STM32_USB_Device_Library/Class/CustomHID/Src/usbd_customhid.c @@ -128,14 +128,17 @@ __ALIGN_BEGIN static uint8_t USBD_CUSTOM_HID_CfgFSDesc[USB_CUSTOM_HID_CONFIG_DES { 0x09, /* bLength: Configuration Descriptor size */ USB_DESC_TYPE_CONFIGURATION, /* bDescriptorType: Configuration */ - USB_CUSTOM_HID_CONFIG_DESC_SIZ, - /* wTotalLength: Bytes returned */ + USB_CUSTOM_HID_CONFIG_DESC_SIZ, /* wTotalLength: Bytes returned */ 0x00, 0x01, /* bNumInterfaces: 1 interface */ 0x01, /* bConfigurationValue: Configuration value */ 0x00, /* iConfiguration: Index of string descriptor describing the configuration */ - 0xC0, /* bmAttributes: bus powered */ - 0x32, /* MaxPower 100 mA: this current is used for detecting Vbus */ +#if (USBD_SELF_POWERED == 1U) + 0xC0, /* bmAttributes: Bus Powered according to user configuration */ +#else + 0x80, /* bmAttributes: Bus Powered according to user configuration */ +#endif + USBD_MAX_POWER, /* MaxPower (mA) */ /************** Descriptor of CUSTOM HID interface ****************/ /* 09 */ @@ -166,7 +169,7 @@ __ALIGN_BEGIN static uint8_t USBD_CUSTOM_HID_CfgFSDesc[USB_CUSTOM_HID_CONFIG_DES CUSTOM_HID_EPIN_ADDR, /* bEndpointAddress: Endpoint Address (IN) */ 0x03, /* bmAttributes: Interrupt endpoint */ - CUSTOM_HID_EPIN_SIZE, /* wMaxPacketSize: 2 Byte max */ + CUSTOM_HID_EPIN_SIZE, /* wMaxPacketSize: 2 Bytes max */ 0x00, CUSTOM_HID_FS_BINTERVAL, /* bInterval: Polling Interval */ /* 34 */ @@ -186,14 +189,17 @@ __ALIGN_BEGIN static uint8_t USBD_CUSTOM_HID_CfgHSDesc[USB_CUSTOM_HID_CONFIG_DES { 0x09, /* bLength: Configuration Descriptor size */ USB_DESC_TYPE_CONFIGURATION, /* bDescriptorType: Configuration */ - USB_CUSTOM_HID_CONFIG_DESC_SIZ, - /* wTotalLength: Bytes returned */ + USB_CUSTOM_HID_CONFIG_DESC_SIZ, /* wTotalLength: Bytes returned */ 0x00, 0x01, /* bNumInterfaces: 1 interface */ 0x01, /* bConfigurationValue: Configuration value */ 0x00, /* iConfiguration: Index of string descriptor describing the configuration */ - 0xC0, /* bmAttributes: bus powered */ - 0x32, /* MaxPower 100 mA: this current is used for detecting Vbus */ +#if (USBD_SELF_POWERED == 1U) + 0xC0, /* bmAttributes: Bus Powered according to user configuration */ +#else + 0x80, /* bmAttributes: Bus Powered according to user configuration */ +#endif + USBD_MAX_POWER, /* MaxPower (mA) */ /************** Descriptor of CUSTOM HID interface ****************/ /* 09 */ @@ -220,11 +226,11 @@ __ALIGN_BEGIN static uint8_t USBD_CUSTOM_HID_CfgHSDesc[USB_CUSTOM_HID_CONFIG_DES /******************** Descriptor of Custom HID endpoints ********************/ /* 27 */ 0x07, /* bLength: Endpoint Descriptor size */ - USB_DESC_TYPE_ENDPOINT, /* bDescriptorType: */ + USB_DESC_TYPE_ENDPOINT, /* bDescriptorType */ CUSTOM_HID_EPIN_ADDR, /* bEndpointAddress: Endpoint Address (IN) */ 0x03, /* bmAttributes: Interrupt endpoint */ - CUSTOM_HID_EPIN_SIZE, /* wMaxPacketSize: 2 Byte max */ + CUSTOM_HID_EPIN_SIZE, /* wMaxPacketSize: 2 Bytes max */ 0x00, CUSTOM_HID_HS_BINTERVAL, /* bInterval: Polling Interval */ /* 34 */ @@ -244,14 +250,17 @@ __ALIGN_BEGIN static uint8_t USBD_CUSTOM_HID_OtherSpeedCfgDesc[USB_CUSTOM_HID_CO { 0x09, /* bLength: Configuration Descriptor size */ USB_DESC_TYPE_CONFIGURATION, /* bDescriptorType: Configuration */ - USB_CUSTOM_HID_CONFIG_DESC_SIZ, - /* wTotalLength: Bytes returned */ + USB_CUSTOM_HID_CONFIG_DESC_SIZ, /* wTotalLength: Bytes returned */ 0x00, 0x01, /* bNumInterfaces: 1 interface */ 0x01, /* bConfigurationValue: Configuration value */ 0x00, /* iConfiguration: Index of string descriptor describing the configuration */ - 0xC0, /* bmAttributes: bus powered */ - 0x32, /* MaxPower 100 mA: this current is used for detecting Vbus */ +#if (USBD_SELF_POWERED == 1U) + 0xC0, /* bmAttributes: Bus Powered according to user configuration */ +#else + 0x80, /* bmAttributes: Bus Powered according to user configuration */ +#endif + USBD_MAX_POWER, /* MaxPower (mA) */ /************** Descriptor of CUSTOM HID interface ****************/ /* 09 */ @@ -282,7 +291,7 @@ __ALIGN_BEGIN static uint8_t USBD_CUSTOM_HID_OtherSpeedCfgDesc[USB_CUSTOM_HID_CO CUSTOM_HID_EPIN_ADDR, /* bEndpointAddress: Endpoint Address (IN) */ 0x03, /* bmAttributes: Interrupt endpoint */ - CUSTOM_HID_EPIN_SIZE, /* wMaxPacketSize: 2 Byte max */ + CUSTOM_HID_EPIN_SIZE, /* wMaxPacketSize: 2 Bytes max */ 0x00, CUSTOM_HID_FS_BINTERVAL, /* bInterval: Polling Interval */ /* 34 */ @@ -347,7 +356,7 @@ static uint8_t USBD_CUSTOM_HID_Init(USBD_HandleTypeDef *pdev, uint8_t cfgidx) UNUSED(cfgidx); USBD_CUSTOM_HID_HandleTypeDef *hhid; - hhid = USBD_malloc(sizeof(USBD_CUSTOM_HID_HandleTypeDef)); + hhid = (USBD_CUSTOM_HID_HandleTypeDef *)USBD_malloc(sizeof(USBD_CUSTOM_HID_HandleTypeDef)); if (hhid == NULL) { @@ -412,7 +421,7 @@ static uint8_t USBD_CUSTOM_HID_DeInit(USBD_HandleTypeDef *pdev, uint8_t cfgidx) pdev->ep_out[CUSTOM_HID_EPOUT_ADDR & 0xFU].is_used = 0U; pdev->ep_out[CUSTOM_HID_EPOUT_ADDR & 0xFU].bInterval = 0U; - /* FRee allocated memory */ + /* Free allocated memory */ if (pdev->pClassData != NULL) { ((USBD_CUSTOM_HID_ItfTypeDef *)pdev->pUserData)->DeInit(); @@ -439,110 +448,116 @@ static uint8_t USBD_CUSTOM_HID_Setup(USBD_HandleTypeDef *pdev, uint16_t status_info = 0U; USBD_StatusTypeDef ret = USBD_OK; - switch (req->bmRequest & USB_REQ_TYPE_MASK) + if (hhid == NULL) { - case USB_REQ_TYPE_CLASS: - switch (req->bRequest) - { - case CUSTOM_HID_REQ_SET_PROTOCOL: - hhid->Protocol = (uint8_t)(req->wValue); - break; - - case CUSTOM_HID_REQ_GET_PROTOCOL: - (void)USBD_CtlSendData(pdev, (uint8_t *)&hhid->Protocol, 1U); - break; - - case CUSTOM_HID_REQ_SET_IDLE: - hhid->IdleState = (uint8_t)(req->wValue >> 8); - break; - - case CUSTOM_HID_REQ_GET_IDLE: - (void)USBD_CtlSendData(pdev, (uint8_t *)&hhid->IdleState, 1U); - break; - - case CUSTOM_HID_REQ_SET_REPORT: - hhid->IsReportAvailable = 1U; - (void)USBD_CtlPrepareRx(pdev, hhid->Report_buf, req->wLength); - break; - - default: - USBD_CtlError(pdev, req); - ret = USBD_FAIL; - break; - } - break; - - case USB_REQ_TYPE_STANDARD: - switch (req->bRequest) - { - case USB_REQ_GET_STATUS: - if (pdev->dev_state == USBD_STATE_CONFIGURED) - { - (void)USBD_CtlSendData(pdev, (uint8_t *)&status_info, 2U); - } - else - { - USBD_CtlError(pdev, req); - ret = USBD_FAIL; - } - break; - - case USB_REQ_GET_DESCRIPTOR: - if ((req->wValue >> 8) == CUSTOM_HID_REPORT_DESC) - { - len = MIN(USBD_CUSTOM_HID_REPORT_DESC_SIZE, req->wLength); - pbuf = ((USBD_CUSTOM_HID_ItfTypeDef *)pdev->pUserData)->pReport; - } - else - { - if ((req->wValue >> 8) == CUSTOM_HID_DESCRIPTOR_TYPE) - { - pbuf = USBD_CUSTOM_HID_Desc; - len = MIN(USB_CUSTOM_HID_DESC_SIZ, req->wLength); - } - } - - (void)USBD_CtlSendData(pdev, pbuf, len); - break; + return (uint8_t)USBD_FAIL; + } - case USB_REQ_GET_INTERFACE: - if (pdev->dev_state == USBD_STATE_CONFIGURED) - { - (void)USBD_CtlSendData(pdev, (uint8_t *)&hhid->AltSetting, 1U); - } - else + switch (req->bmRequest & USB_REQ_TYPE_MASK) + { + case USB_REQ_TYPE_CLASS: + switch (req->bRequest) { - USBD_CtlError(pdev, req); - ret = USBD_FAIL; + case CUSTOM_HID_REQ_SET_PROTOCOL: + hhid->Protocol = (uint8_t)(req->wValue); + break; + + case CUSTOM_HID_REQ_GET_PROTOCOL: + (void)USBD_CtlSendData(pdev, (uint8_t *)&hhid->Protocol, 1U); + break; + + case CUSTOM_HID_REQ_SET_IDLE: + hhid->IdleState = (uint8_t)(req->wValue >> 8); + break; + + case CUSTOM_HID_REQ_GET_IDLE: + (void)USBD_CtlSendData(pdev, (uint8_t *)&hhid->IdleState, 1U); + break; + + case CUSTOM_HID_REQ_SET_REPORT: + hhid->IsReportAvailable = 1U; + (void)USBD_CtlPrepareRx(pdev, hhid->Report_buf, + MIN(req->wLength, USBD_CUSTOMHID_OUTREPORT_BUF_SIZE)); + break; + + default: + USBD_CtlError(pdev, req); + ret = USBD_FAIL; + break; } break; - case USB_REQ_SET_INTERFACE: - if (pdev->dev_state == USBD_STATE_CONFIGURED) - { - hhid->AltSetting = (uint8_t)(req->wValue); - } - else + case USB_REQ_TYPE_STANDARD: + switch (req->bRequest) { - USBD_CtlError(pdev, req); - ret = USBD_FAIL; + case USB_REQ_GET_STATUS: + if (pdev->dev_state == USBD_STATE_CONFIGURED) + { + (void)USBD_CtlSendData(pdev, (uint8_t *)&status_info, 2U); + } + else + { + USBD_CtlError(pdev, req); + ret = USBD_FAIL; + } + break; + + case USB_REQ_GET_DESCRIPTOR: + if ((req->wValue >> 8) == CUSTOM_HID_REPORT_DESC) + { + len = MIN(USBD_CUSTOM_HID_REPORT_DESC_SIZE, req->wLength); + pbuf = ((USBD_CUSTOM_HID_ItfTypeDef *)pdev->pUserData)->pReport; + } + else + { + if ((req->wValue >> 8) == CUSTOM_HID_DESCRIPTOR_TYPE) + { + pbuf = USBD_CUSTOM_HID_Desc; + len = MIN(USB_CUSTOM_HID_DESC_SIZ, req->wLength); + } + } + + (void)USBD_CtlSendData(pdev, pbuf, len); + break; + + case USB_REQ_GET_INTERFACE: + if (pdev->dev_state == USBD_STATE_CONFIGURED) + { + (void)USBD_CtlSendData(pdev, (uint8_t *)&hhid->AltSetting, 1U); + } + else + { + USBD_CtlError(pdev, req); + ret = USBD_FAIL; + } + break; + + case USB_REQ_SET_INTERFACE: + if (pdev->dev_state == USBD_STATE_CONFIGURED) + { + hhid->AltSetting = (uint8_t)(req->wValue); + } + else + { + USBD_CtlError(pdev, req); + ret = USBD_FAIL; + } + break; + + case USB_REQ_CLEAR_FEATURE: + break; + + default: + USBD_CtlError(pdev, req); + ret = USBD_FAIL; + break; } break; - case USB_REQ_CLEAR_FEATURE: - break; - default: USBD_CtlError(pdev, req); ret = USBD_FAIL; break; - } - break; - - default: - USBD_CtlError(pdev, req); - ret = USBD_FAIL; - break; } return (uint8_t)ret; } @@ -564,7 +579,7 @@ uint8_t USBD_CUSTOM_HID_SendReport(USBD_HandleTypeDef *pdev, return (uint8_t)USBD_FAIL; } - hhid = (USBD_CUSTOM_HID_HandleTypeDef*)pdev->pClassData; + hhid = (USBD_CUSTOM_HID_HandleTypeDef *)pdev->pClassData; if (pdev->dev_state == USBD_STATE_CONFIGURED) { @@ -658,7 +673,7 @@ static uint8_t USBD_CUSTOM_HID_DataOut(USBD_HandleTypeDef *pdev, uint8_t epnum) return (uint8_t)USBD_FAIL; } - hhid = (USBD_CUSTOM_HID_HandleTypeDef*)pdev->pClassData; + hhid = (USBD_CUSTOM_HID_HandleTypeDef *)pdev->pClassData; /* USB data will be immediately processed, this allow next USB traffic being NAKed till the end of the application processing */ @@ -684,7 +699,7 @@ uint8_t USBD_CUSTOM_HID_ReceivePacket(USBD_HandleTypeDef *pdev) return (uint8_t)USBD_FAIL; } - hhid = (USBD_CUSTOM_HID_HandleTypeDef*)pdev->pClassData; + hhid = (USBD_CUSTOM_HID_HandleTypeDef *)pdev->pClassData; /* Resume USB Out process */ (void)USBD_LL_PrepareReceive(pdev, CUSTOM_HID_EPOUT_ADDR, hhid->Report_buf, @@ -704,6 +719,11 @@ static uint8_t USBD_CUSTOM_HID_EP0_RxReady(USBD_HandleTypeDef *pdev) { USBD_CUSTOM_HID_HandleTypeDef *hhid = (USBD_CUSTOM_HID_HandleTypeDef *)pdev->pClassData; + if (hhid == NULL) + { + return (uint8_t)USBD_FAIL; + } + if (hhid->IsReportAvailable == 1U) { ((USBD_CUSTOM_HID_ItfTypeDef *)pdev->pUserData)->OutEvent(hhid->Report_buf[0], @@ -715,11 +735,11 @@ static uint8_t USBD_CUSTOM_HID_EP0_RxReady(USBD_HandleTypeDef *pdev) } /** -* @brief DeviceQualifierDescriptor -* return Device Qualifier descriptor -* @param length : pointer data length -* @retval pointer to descriptor buffer -*/ + * @brief DeviceQualifierDescriptor + * return Device Qualifier descriptor + * @param length : pointer data length + * @retval pointer to descriptor buffer + */ static uint8_t *USBD_CUSTOM_HID_GetDeviceQualifierDesc(uint16_t *length) { *length = (uint16_t)sizeof(USBD_CUSTOM_HID_DeviceQualifierDesc); @@ -728,7 +748,7 @@ static uint8_t *USBD_CUSTOM_HID_GetDeviceQualifierDesc(uint16_t *length) } /** -* @brief USBD_CUSTOM_HID_RegisterInterface + * @brief USBD_CUSTOM_HID_RegisterInterface * @param pdev: device instance * @param fops: CUSTOMHID Interface callback * @retval status diff --git a/system/Middlewares/ST/STM32_USB_Device_Library/Class/CustomHID/Src/usbd_customhid_if_template.c b/system/Middlewares/ST/STM32_USB_Device_Library/Class/CustomHID/Src/usbd_customhid_if_template.c index 1fb6edd16d..97e4337987 100644 --- a/system/Middlewares/ST/STM32_USB_Device_Library/Class/CustomHID/Src/usbd_customhid_if_template.c +++ b/system/Middlewares/ST/STM32_USB_Device_Library/Class/CustomHID/Src/usbd_customhid_if_template.c @@ -83,7 +83,7 @@ static int8_t TEMPLATE_CUSTOM_HID_OutEvent(uint8_t event_idx, uint8_t state) UNUSED(event_idx); UNUSED(state); - /* Start next USB packet transfer once data processing is completed */ + /* Start next USB packet transfer once data processing is completed */ USBD_CUSTOM_HID_ReceivePacket(&USBD_Device); return (0); diff --git a/system/Middlewares/ST/STM32_USB_Device_Library/Class/DFU/Inc/usbd_dfu_media_template.h b/system/Middlewares/ST/STM32_USB_Device_Library/Class/DFU/Inc/usbd_dfu_media_template.h index 1ba14227c9..25efe526aa 100644 --- a/system/Middlewares/ST/STM32_USB_Device_Library/Class/DFU/Inc/usbd_dfu_media_template.h +++ b/system/Middlewares/ST/STM32_USB_Device_Library/Class/DFU/Inc/usbd_dfu_media_template.h @@ -92,6 +92,6 @@ extern USBD_DFU_MediaTypeDef USBD_DFU_MEDIA_Template_fops; */ /** -* @} -*/ + * @} + */ /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ diff --git a/system/Middlewares/ST/STM32_USB_Device_Library/Class/DFU/Src/usbd_dfu.c b/system/Middlewares/ST/STM32_USB_Device_Library/Class/DFU/Src/usbd_dfu.c index d179650b1a..fc942a76d0 100644 --- a/system/Middlewares/ST/STM32_USB_Device_Library/Class/DFU/Src/usbd_dfu.c +++ b/system/Middlewares/ST/STM32_USB_Device_Library/Class/DFU/Src/usbd_dfu.c @@ -153,16 +153,19 @@ USBD_ClassTypeDef USBD_DFU = /* USB DFU device Configuration Descriptor */ __ALIGN_BEGIN static uint8_t USBD_DFU_CfgDesc[USB_DFU_CONFIG_DESC_SIZ] __ALIGN_END = { - 0x09, /* bLength: Configuation Descriptor size */ + 0x09, /* bLength: Configuration Descriptor size */ USB_DESC_TYPE_CONFIGURATION, /* bDescriptorType: Configuration */ - USB_DFU_CONFIG_DESC_SIZ, - /* wTotalLength: Bytes returned */ + USB_DFU_CONFIG_DESC_SIZ, /* wTotalLength: Bytes returned */ 0x00, 0x01, /* bNumInterfaces: 1 interface */ 0x01, /* bConfigurationValue: Configuration value */ 0x02, /* iConfiguration: Index of string descriptor describing the configuration */ - 0xC0, /* bmAttributes: bus powered and Supprts Remote Wakeup */ - 0x32, /* MaxPower 100 mA: this current is used for detecting Vbus */ +#if (USBD_SELF_POWERED == 1U) + 0xC0, /* bmAttributes: Bus Powered according to user configuration */ +#else + 0x80, /* bmAttributes: Bus Powered according to user configuration */ +#endif + USBD_MAX_POWER, /* MaxPower (mA) */ /* 09 */ /********** Descriptor of DFU interface 0 Alternate setting 0 **************/ @@ -255,7 +258,7 @@ static uint8_t USBD_DFU_Init(USBD_HandleTypeDef *pdev, uint8_t cfgidx) USBD_DFU_HandleTypeDef *hdfu; /* Allocate Audio structure */ - hdfu = USBD_malloc(sizeof(USBD_DFU_HandleTypeDef)); + hdfu = (USBD_DFU_HandleTypeDef *)USBD_malloc(sizeof(USBD_DFU_HandleTypeDef)); if (hdfu == NULL) { @@ -337,118 +340,123 @@ static uint8_t USBD_DFU_Setup(USBD_HandleTypeDef *pdev, USBD_SetupReqTypedef *re uint16_t len = 0U; uint16_t status_info = 0U; - switch (req->bmRequest & USB_REQ_TYPE_MASK) + if (hdfu == NULL) { - case USB_REQ_TYPE_CLASS: - switch (req->bRequest) - { - case DFU_DNLOAD: - DFU_Download(pdev, req); - break; + return (uint8_t)USBD_FAIL; + } - case DFU_UPLOAD: - DFU_Upload(pdev, req); - break; + switch (req->bmRequest & USB_REQ_TYPE_MASK) + { + case USB_REQ_TYPE_CLASS: + switch (req->bRequest) + { + case DFU_DNLOAD: + DFU_Download(pdev, req); + break; - case DFU_GETSTATUS: - DFU_GetStatus(pdev); - break; + case DFU_UPLOAD: + DFU_Upload(pdev, req); + break; - case DFU_CLRSTATUS: - DFU_ClearStatus(pdev); - break; + case DFU_GETSTATUS: + DFU_GetStatus(pdev); + break; - case DFU_GETSTATE: - DFU_GetState(pdev); - break; + case DFU_CLRSTATUS: + DFU_ClearStatus(pdev); + break; - case DFU_ABORT: - DFU_Abort(pdev); - break; + case DFU_GETSTATE: + DFU_GetState(pdev); + break; - case DFU_DETACH: - DFU_Detach(pdev, req); - break; + case DFU_ABORT: + DFU_Abort(pdev); + break; - default: - USBD_CtlError(pdev, req); - ret = USBD_FAIL; - break; - } - break; + case DFU_DETACH: + DFU_Detach(pdev, req); + break; - case USB_REQ_TYPE_STANDARD: - switch (req->bRequest) - { - case USB_REQ_GET_STATUS: - if (pdev->dev_state == USBD_STATE_CONFIGURED) - { - (void)USBD_CtlSendData(pdev, (uint8_t *)&status_info, 2U); - } - else - { - USBD_CtlError(pdev, req); - ret = USBD_FAIL; + default: + USBD_CtlError(pdev, req); + ret = USBD_FAIL; + break; } break; - case USB_REQ_GET_DESCRIPTOR: - if ((req->wValue >> 8) == DFU_DESCRIPTOR_TYPE) + case USB_REQ_TYPE_STANDARD: + switch (req->bRequest) { - pbuf = USBD_DFU_CfgDesc + (9U * (USBD_DFU_MAX_ITF_NUM + 1U)); - len = MIN(USB_DFU_DESC_SIZ, req->wLength); - } + case USB_REQ_GET_STATUS: + if (pdev->dev_state == USBD_STATE_CONFIGURED) + { + (void)USBD_CtlSendData(pdev, (uint8_t *)&status_info, 2U); + } + else + { + USBD_CtlError(pdev, req); + ret = USBD_FAIL; + } + break; - (void)USBD_CtlSendData(pdev, pbuf, len); - break; + case USB_REQ_GET_DESCRIPTOR: + if ((req->wValue >> 8) == DFU_DESCRIPTOR_TYPE) + { + pbuf = USBD_DFU_CfgDesc + (9U * (USBD_DFU_MAX_ITF_NUM + 1U)); + len = MIN(USB_DFU_DESC_SIZ, req->wLength); + } - case USB_REQ_GET_INTERFACE: - if (pdev->dev_state == USBD_STATE_CONFIGURED) - { - (void)USBD_CtlSendData(pdev, (uint8_t *)hdfu->alt_setting, 1U); - } - else - { - USBD_CtlError(pdev, req); - ret = USBD_FAIL; - } - break; + (void)USBD_CtlSendData(pdev, pbuf, len); + break; - case USB_REQ_SET_INTERFACE: - if ((uint8_t)(req->wValue) < USBD_DFU_MAX_ITF_NUM) - { - if (pdev->dev_state == USBD_STATE_CONFIGURED) - { - hdfu->alt_setting = (uint8_t)(req->wValue); - } - else - { + case USB_REQ_GET_INTERFACE: + if (pdev->dev_state == USBD_STATE_CONFIGURED) + { + (void)USBD_CtlSendData(pdev, (uint8_t *)&hdfu->alt_setting, 1U); + } + else + { + USBD_CtlError(pdev, req); + ret = USBD_FAIL; + } + break; + + case USB_REQ_SET_INTERFACE: + if ((uint8_t)(req->wValue) < USBD_DFU_MAX_ITF_NUM) + { + if (pdev->dev_state == USBD_STATE_CONFIGURED) + { + hdfu->alt_setting = (uint8_t)(req->wValue); + } + else + { + USBD_CtlError(pdev, req); + ret = USBD_FAIL; + } + } + else + { + /* Call the error management function (command will be NAKed */ + USBD_CtlError(pdev, req); + ret = USBD_FAIL; + } + break; + + case USB_REQ_CLEAR_FEATURE: + break; + + default: USBD_CtlError(pdev, req); ret = USBD_FAIL; - } + break; } - else - { - /* Call the error management function (command will be nacked */ - USBD_CtlError(pdev, req); - ret = USBD_FAIL; - } - break; - - case USB_REQ_CLEAR_FEATURE: break; default: USBD_CtlError(pdev, req); ret = USBD_FAIL; break; - } - break; - - default: - USBD_CtlError(pdev, req); - ret = USBD_FAIL; - break; } return (uint8_t)ret; @@ -495,16 +503,21 @@ static uint8_t USBD_DFU_EP0_TxReady(USBD_HandleTypeDef *pdev) USBD_DFU_HandleTypeDef *hdfu = (USBD_DFU_HandleTypeDef *)pdev->pClassData; USBD_DFU_MediaTypeDef *DfuInterface = (USBD_DFU_MediaTypeDef *)pdev->pUserData; + if (hdfu == NULL) + { + return (uint8_t)USBD_FAIL; + } + if (hdfu->dev_state == DFU_STATE_DNLOAD_BUSY) { - /* Decode the Special Command*/ + /* Decode the Special Command */ if (hdfu->wblock_num == 0U) { - if(hdfu->wlength == 1U) + if (hdfu->wlength == 1U) { if (hdfu->buffer.d8[0] == DFU_CMD_GETCOMMANDS) { - /* nothink to do */ + /* Nothing to do */ } } else if (hdfu->wlength == 5U) @@ -530,7 +543,7 @@ static uint8_t USBD_DFU_EP0_TxReady(USBD_HandleTypeDef *pdev) } else { - /* .. */ + return (uint8_t)USBD_FAIL; } } else @@ -538,7 +551,7 @@ static uint8_t USBD_DFU_EP0_TxReady(USBD_HandleTypeDef *pdev) /* Reset the global length and block number */ hdfu->wlength = 0U; hdfu->wblock_num = 0U; - /* Call the error management function (command will be nacked) */ + /* Call the error management function (command will be NAKed) */ req.bmRequest = 0U; req.wLength = 1U; USBD_CtlError(pdev, &req); @@ -552,7 +565,7 @@ static uint8_t USBD_DFU_EP0_TxReady(USBD_HandleTypeDef *pdev) /* Decode the required address */ addr = ((hdfu->wblock_num - 2U) * USBD_DFU_XFER_SIZE) + hdfu->data_ptr; - /* Preform the write operation */ + /* Perform the write operation */ if (DfuInterface->Write(hdfu->buffer.d8, (uint8_t *)addr, hdfu->wlength) != USBD_OK) { return (uint8_t)USBD_FAIL; @@ -579,7 +592,7 @@ static uint8_t USBD_DFU_EP0_TxReady(USBD_HandleTypeDef *pdev) } else { - /* .. */ + return (uint8_t)USBD_FAIL; } return (uint8_t)USBD_OK; @@ -599,11 +612,11 @@ static uint8_t USBD_DFU_SOF(USBD_HandleTypeDef *pdev) /** -* @brief DeviceQualifierDescriptor -* return Device Qualifier descriptor -* @param length : pointer data length -* @retval pointer to descriptor buffer -*/ + * @brief DeviceQualifierDescriptor + * return Device Qualifier descriptor + * @param length : pointer data length + * @retval pointer to descriptor buffer + */ static uint8_t *USBD_DFU_GetDeviceQualifierDesc(uint16_t *length) { *length = (uint16_t)sizeof(USBD_DFU_DeviceQualifierDesc); @@ -615,7 +628,7 @@ static uint8_t *USBD_DFU_GetDeviceQualifierDesc(uint16_t *length) * @brief USBD_DFU_GetUsrStringDesc * Manages the transfer of memory interfaces string descriptors. * @param speed : current device speed - * @param index: desciptor index + * @param index: descriptor index * @param length : pointer data length * @retval pointer to the descriptor table or NULL if the descriptor is not supported. */ @@ -640,10 +653,10 @@ static uint8_t *USBD_DFU_GetUsrStringDesc(USBD_HandleTypeDef *pdev, uint8_t inde #endif /** -* @brief USBD_MSC_RegisterStorage -* @param fops: storage callback -* @retval status -*/ + * @brief USBD_MSC_RegisterStorage + * @param fops: storage callback + * @retval status + */ uint8_t USBD_DFU_RegisterMedia(USBD_HandleTypeDef *pdev, USBD_DFU_MediaTypeDef *fops) { @@ -659,7 +672,7 @@ uint8_t USBD_DFU_RegisterMedia(USBD_HandleTypeDef *pdev, /****************************************************************************** DFU Class requests management -******************************************************************************/ + ******************************************************************************/ /** * @brief DFU_Detach * Handles the DFU DETACH request. @@ -671,6 +684,11 @@ static void DFU_Detach(USBD_HandleTypeDef *pdev, USBD_SetupReqTypedef *req) { USBD_DFU_HandleTypeDef *hdfu = (USBD_DFU_HandleTypeDef *)pdev->pClassData; + if (hdfu == NULL) + { + return; + } + if ((hdfu->dev_state == DFU_STATE_IDLE) || (hdfu->dev_state == DFU_STATE_DNLOAD_SYNC) || (hdfu->dev_state == DFU_STATE_DNLOAD_IDLE) || @@ -714,6 +732,11 @@ static void DFU_Download(USBD_HandleTypeDef *pdev, USBD_SetupReqTypedef *req) { USBD_DFU_HandleTypeDef *hdfu = (USBD_DFU_HandleTypeDef *)pdev->pClassData; + if (hdfu == NULL) + { + return; + } + /* Data setup request */ if (req->wLength > 0U) { @@ -721,7 +744,7 @@ static void DFU_Download(USBD_HandleTypeDef *pdev, USBD_SetupReqTypedef *req) { /* Update the global length and block number */ hdfu->wblock_num = req->wValue; - hdfu->wlength = req->wLength; + hdfu->wlength = MIN(req->wLength, USBD_DFU_XFER_SIZE); /* Update the state machine */ hdfu->dev_state = DFU_STATE_DNLOAD_SYNC; @@ -733,7 +756,7 @@ static void DFU_Download(USBD_HandleTypeDef *pdev, USBD_SetupReqTypedef *req) /* Unsupported state */ else { - /* Call the error management function (command will be nacked */ + /* Call the error management function (command will be NAKed */ USBD_CtlError(pdev, req); } } @@ -752,7 +775,7 @@ static void DFU_Download(USBD_HandleTypeDef *pdev, USBD_SetupReqTypedef *req) } else { - /* Call the error management function (command will be nacked */ + /* Call the error management function (command will be NAKed */ USBD_CtlError(pdev, req); } } @@ -772,6 +795,11 @@ static void DFU_Upload(USBD_HandleTypeDef *pdev, USBD_SetupReqTypedef *req) uint8_t *phaddr; uint32_t addr; + if (hdfu == NULL) + { + return; + } + /* Data setup request */ if (req->wLength > 0U) { @@ -779,7 +807,7 @@ static void DFU_Upload(USBD_HandleTypeDef *pdev, USBD_SetupReqTypedef *req) { /* Update the global length and block number */ hdfu->wblock_num = req->wValue; - hdfu->wlength = req->wLength; + hdfu->wlength = MIN(req->wLength, USBD_DFU_XFER_SIZE); /* DFU Get Command */ if (hdfu->wblock_num == 0U) @@ -826,7 +854,7 @@ static void DFU_Upload(USBD_HandleTypeDef *pdev, USBD_SetupReqTypedef *req) hdfu->dev_status[3] = 0U; hdfu->dev_status[4] = hdfu->dev_state; - /* Call the error management function (command will be nacked */ + /* Call the error management function (command will be NAKed */ USBD_CtlError(pdev, req); } } @@ -836,7 +864,7 @@ static void DFU_Upload(USBD_HandleTypeDef *pdev, USBD_SetupReqTypedef *req) hdfu->wlength = 0U; hdfu->wblock_num = 0U; - /* Call the error management function (command will be nacked */ + /* Call the error management function (command will be NAKed */ USBD_CtlError(pdev, req); } } @@ -863,65 +891,70 @@ static void DFU_GetStatus(USBD_HandleTypeDef *pdev) USBD_DFU_HandleTypeDef *hdfu = (USBD_DFU_HandleTypeDef *)pdev->pClassData; USBD_DFU_MediaTypeDef *DfuInterface = (USBD_DFU_MediaTypeDef *)pdev->pUserData; + if (hdfu == NULL) + { + return; + } + switch (hdfu->dev_state) { - case DFU_STATE_DNLOAD_SYNC: - if (hdfu->wlength != 0U) - { - hdfu->dev_state = DFU_STATE_DNLOAD_BUSY; + case DFU_STATE_DNLOAD_SYNC: + if (hdfu->wlength != 0U) + { + hdfu->dev_state = DFU_STATE_DNLOAD_BUSY; - hdfu->dev_status[1] = 0U; - hdfu->dev_status[2] = 0U; - hdfu->dev_status[3] = 0U; - hdfu->dev_status[4] = hdfu->dev_state; + hdfu->dev_status[1] = 0U; + hdfu->dev_status[2] = 0U; + hdfu->dev_status[3] = 0U; + hdfu->dev_status[4] = hdfu->dev_state; - if ((hdfu->wblock_num == 0U) && (hdfu->buffer.d8[0] == DFU_CMD_ERASE)) - { - DfuInterface->GetStatus(hdfu->data_ptr, DFU_MEDIA_ERASE, hdfu->dev_status); + if ((hdfu->wblock_num == 0U) && (hdfu->buffer.d8[0] == DFU_CMD_ERASE)) + { + DfuInterface->GetStatus(hdfu->data_ptr, DFU_MEDIA_ERASE, hdfu->dev_status); + } + else + { + DfuInterface->GetStatus(hdfu->data_ptr, DFU_MEDIA_PROGRAM, hdfu->dev_status); + } } - else + else /* (hdfu->wlength==0)*/ { - DfuInterface->GetStatus(hdfu->data_ptr, DFU_MEDIA_PROGRAM, hdfu->dev_status); - } - } - else /* (hdfu->wlength==0)*/ - { - hdfu->dev_state = DFU_STATE_DNLOAD_IDLE; + hdfu->dev_state = DFU_STATE_DNLOAD_IDLE; - hdfu->dev_status[1] = 0U; - hdfu->dev_status[2] = 0U; - hdfu->dev_status[3] = 0U; - hdfu->dev_status[4] = hdfu->dev_state; - } - break; - - case DFU_STATE_MANIFEST_SYNC: - if (hdfu->manif_state == DFU_MANIFEST_IN_PROGRESS) - { - hdfu->dev_state = DFU_STATE_MANIFEST; + hdfu->dev_status[1] = 0U; + hdfu->dev_status[2] = 0U; + hdfu->dev_status[3] = 0U; + hdfu->dev_status[4] = hdfu->dev_state; + } + break; - hdfu->dev_status[1] = 1U; /*bwPollTimeout = 1ms*/ - hdfu->dev_status[2] = 0U; - hdfu->dev_status[3] = 0U; - hdfu->dev_status[4] = hdfu->dev_state; - } - else - { - if ((hdfu->manif_state == DFU_MANIFEST_COMPLETE) && - (((USBD_DFU_CfgDesc[(11U + (9U * USBD_DFU_MAX_ITF_NUM))]) & 0x04U) != 0U)) + case DFU_STATE_MANIFEST_SYNC: + if (hdfu->manif_state == DFU_MANIFEST_IN_PROGRESS) { - hdfu->dev_state = DFU_STATE_IDLE; + hdfu->dev_state = DFU_STATE_MANIFEST; - hdfu->dev_status[1] = 0U; + hdfu->dev_status[1] = 1U; /*bwPollTimeout = 1ms*/ hdfu->dev_status[2] = 0U; hdfu->dev_status[3] = 0U; hdfu->dev_status[4] = hdfu->dev_state; } - } - break; + else + { + if ((hdfu->manif_state == DFU_MANIFEST_COMPLETE) && + (((USBD_DFU_CfgDesc[(11U + (9U * USBD_DFU_MAX_ITF_NUM))]) & 0x04U) != 0U)) + { + hdfu->dev_state = DFU_STATE_IDLE; + + hdfu->dev_status[1] = 0U; + hdfu->dev_status[2] = 0U; + hdfu->dev_status[3] = 0U; + hdfu->dev_status[4] = hdfu->dev_state; + } + } + break; - default: - break; + default: + break; } /* Send the status data over EP0 */ @@ -938,26 +971,31 @@ static void DFU_ClearStatus(USBD_HandleTypeDef *pdev) { USBD_DFU_HandleTypeDef *hdfu = (USBD_DFU_HandleTypeDef *)pdev->pClassData; + if (hdfu == NULL) + { + return; + } + if (hdfu->dev_state == DFU_STATE_ERROR) { hdfu->dev_state = DFU_STATE_IDLE; - hdfu->dev_status[0] = DFU_ERROR_NONE; /*bStatus*/ + hdfu->dev_status[0] = DFU_ERROR_NONE; /* bStatus */ hdfu->dev_status[1] = 0U; hdfu->dev_status[2] = 0U; - hdfu->dev_status[3] = 0U; /*bwPollTimeout=0ms*/ - hdfu->dev_status[4] = hdfu->dev_state; /*bState*/ - hdfu->dev_status[5] = 0U; /*iString*/ + hdfu->dev_status[3] = 0U; /* bwPollTimeout=0ms */ + hdfu->dev_status[4] = hdfu->dev_state; /* bState */ + hdfu->dev_status[5] = 0U; /* iString */ } else { - /*State Error*/ + /* State Error */ hdfu->dev_state = DFU_STATE_ERROR; - hdfu->dev_status[0] = DFU_ERROR_UNKNOWN; /*bStatus*/ + hdfu->dev_status[0] = DFU_ERROR_UNKNOWN; /* bStatus */ hdfu->dev_status[1] = 0U; hdfu->dev_status[2] = 0U; - hdfu->dev_status[3] = 0U; /*bwPollTimeout=0ms*/ - hdfu->dev_status[4] = hdfu->dev_state; /*bState*/ - hdfu->dev_status[5] = 0U; /*iString*/ + hdfu->dev_status[3] = 0U; /* bwPollTimeout=0ms */ + hdfu->dev_status[4] = hdfu->dev_state; /* bState */ + hdfu->dev_status[5] = 0U; /* iString */ } } @@ -971,6 +1009,11 @@ static void DFU_GetState(USBD_HandleTypeDef *pdev) { USBD_DFU_HandleTypeDef *hdfu = (USBD_DFU_HandleTypeDef *)pdev->pClassData; + if (hdfu == NULL) + { + return; + } + /* Return the current state of the DFU interface */ (void)USBD_CtlSendData(pdev, &hdfu->dev_state, 1U); } @@ -985,6 +1028,10 @@ static void DFU_Abort(USBD_HandleTypeDef *pdev) { USBD_DFU_HandleTypeDef *hdfu = (USBD_DFU_HandleTypeDef *)pdev->pClassData; + if (hdfu == NULL) + { + return; + } if ((hdfu->dev_state == DFU_STATE_IDLE) || (hdfu->dev_state == DFU_STATE_DNLOAD_SYNC) || @@ -996,9 +1043,9 @@ static void DFU_Abort(USBD_HandleTypeDef *pdev) hdfu->dev_status[0] = DFU_ERROR_NONE; hdfu->dev_status[1] = 0U; hdfu->dev_status[2] = 0U; - hdfu->dev_status[3] = 0U; /*bwPollTimeout=0ms*/ + hdfu->dev_status[3] = 0U; /* bwPollTimeout=0ms */ hdfu->dev_status[4] = hdfu->dev_state; - hdfu->dev_status[5] = 0U; /*iString*/ + hdfu->dev_status[5] = 0U; /* iString */ hdfu->wblock_num = 0U; hdfu->wlength = 0U; } @@ -1015,6 +1062,11 @@ static void DFU_Leave(USBD_HandleTypeDef *pdev) { USBD_DFU_HandleTypeDef *hdfu = (USBD_DFU_HandleTypeDef *)pdev->pClassData; + if (hdfu == NULL) + { + return; + } + hdfu->manif_state = DFU_MANIFEST_COMPLETE; if (((USBD_DFU_CfgDesc[(11U + (9U * USBD_DFU_MAX_ITF_NUM))]) & 0x04U) != 0U) diff --git a/system/Middlewares/ST/STM32_USB_Device_Library/Class/HID/Inc/usbd_hid.h b/system/Middlewares/ST/STM32_USB_Device_Library/Class/HID/Inc/usbd_hid.h index 40ed7291af..76fcdc7c68 100644 --- a/system/Middlewares/ST/STM32_USB_Device_Library/Class/HID/Inc/usbd_hid.h +++ b/system/Middlewares/ST/STM32_USB_Device_Library/Class/HID/Inc/usbd_hid.h @@ -116,7 +116,7 @@ extern USBD_ClassTypeDef USBD_HID; /** @defgroup USB_CORE_Exported_Functions * @{ */ -uint8_t USBD_HID_SendReport(USBD_HandleTypeDef *pdev, uint8_t *report,uint16_t len); +uint8_t USBD_HID_SendReport(USBD_HandleTypeDef *pdev, uint8_t *report, uint16_t len); uint32_t USBD_HID_GetPollingInterval(USBD_HandleTypeDef *pdev); /** diff --git a/system/Middlewares/ST/STM32_USB_Device_Library/Class/HID/Src/usbd_hid.c b/system/Middlewares/ST/STM32_USB_Device_Library/Class/HID/Src/usbd_hid.c index c73dacebe9..75256d20fa 100644 --- a/system/Middlewares/ST/STM32_USB_Device_Library/Class/HID/Src/usbd_hid.c +++ b/system/Middlewares/ST/STM32_USB_Device_Library/Class/HID/Src/usbd_hid.c @@ -105,7 +105,8 @@ static uint8_t *USBD_HID_GetDeviceQualifierDesc(uint16_t *length); * @{ */ -USBD_ClassTypeDef USBD_HID = { +USBD_ClassTypeDef USBD_HID = +{ USBD_HID_Init, USBD_HID_DeInit, USBD_HID_Setup, @@ -123,17 +124,21 @@ USBD_ClassTypeDef USBD_HID = { }; /* USB HID device FS Configuration Descriptor */ -__ALIGN_BEGIN static uint8_t USBD_HID_CfgFSDesc[USB_HID_CONFIG_DESC_SIZ] __ALIGN_END = { +__ALIGN_BEGIN static uint8_t USBD_HID_CfgFSDesc[USB_HID_CONFIG_DESC_SIZ] __ALIGN_END = +{ 0x09, /* bLength: Configuration Descriptor size */ USB_DESC_TYPE_CONFIGURATION, /* bDescriptorType: Configuration */ - USB_HID_CONFIG_DESC_SIZ, - /* wTotalLength: Bytes returned */ + USB_HID_CONFIG_DESC_SIZ, /* wTotalLength: Bytes returned */ 0x00, 0x01, /* bNumInterfaces: 1 interface */ 0x01, /* bConfigurationValue: Configuration value */ 0x00, /* iConfiguration: Index of string descriptor describing the configuration */ - 0xE0, /* bmAttributes: bus powered and Support Remote Wake-up */ - 0x32, /* MaxPower 100 mA: this current is used for detecting Vbus */ +#if (USBD_SELF_POWERED == 1U) + 0xE0, /* bmAttributes: Bus Powered according to user configuration */ +#else + 0xA0, /* bmAttributes: Bus Powered according to user configuration */ +#endif + USBD_MAX_POWER, /* MaxPower (mA) */ /************** Descriptor of Joystick Mouse interface ****************/ /* 09 */ @@ -164,24 +169,28 @@ __ALIGN_BEGIN static uint8_t USBD_HID_CfgFSDesc[USB_HID_CONFIG_DESC_SIZ] __ALIGN HID_EPIN_ADDR, /* bEndpointAddress: Endpoint Address (IN) */ 0x03, /* bmAttributes: Interrupt endpoint */ - HID_EPIN_SIZE, /* wMaxPacketSize: 4 Byte max */ + HID_EPIN_SIZE, /* wMaxPacketSize: 4 Bytes max */ 0x00, HID_FS_BINTERVAL, /* bInterval: Polling Interval */ /* 34 */ }; /* USB HID device HS Configuration Descriptor */ -__ALIGN_BEGIN static uint8_t USBD_HID_CfgHSDesc[USB_HID_CONFIG_DESC_SIZ] __ALIGN_END = { +__ALIGN_BEGIN static uint8_t USBD_HID_CfgHSDesc[USB_HID_CONFIG_DESC_SIZ] __ALIGN_END = +{ 0x09, /* bLength: Configuration Descriptor size */ USB_DESC_TYPE_CONFIGURATION, /* bDescriptorType: Configuration */ - USB_HID_CONFIG_DESC_SIZ, - /* wTotalLength: Bytes returned */ + USB_HID_CONFIG_DESC_SIZ, /* wTotalLength: Bytes returned */ 0x00, 0x01, /* bNumInterfaces: 1 interface */ 0x01, /* bConfigurationValue: Configuration value */ 0x00, /* iConfiguration: Index of string descriptor describing the configuration */ - 0xE0, /* bmAttributes: bus powered and Support Remote Wake-up */ - 0x32, /* MaxPower 100 mA: this current is used for detecting Vbus */ +#if (USBD_SELF_POWERED == 1U) + 0xE0, /* bmAttributes: Bus Powered according to user configuration */ +#else + 0xA0, /* bmAttributes: Bus Powered according to user configuration */ +#endif + USBD_MAX_POWER, /* MaxPower (mA) */ /************** Descriptor of Joystick Mouse interface ****************/ /* 09 */ @@ -212,24 +221,28 @@ __ALIGN_BEGIN static uint8_t USBD_HID_CfgHSDesc[USB_HID_CONFIG_DESC_SIZ] __ALIGN HID_EPIN_ADDR, /* bEndpointAddress: Endpoint Address (IN) */ 0x03, /* bmAttributes: Interrupt endpoint */ - HID_EPIN_SIZE, /* wMaxPacketSize: 4 Byte max */ + HID_EPIN_SIZE, /* wMaxPacketSize: 4 Bytes max */ 0x00, HID_HS_BINTERVAL, /* bInterval: Polling Interval */ /* 34 */ }; /* USB HID device Other Speed Configuration Descriptor */ -__ALIGN_BEGIN static uint8_t USBD_HID_OtherSpeedCfgDesc[USB_HID_CONFIG_DESC_SIZ] __ALIGN_END = { +__ALIGN_BEGIN static uint8_t USBD_HID_OtherSpeedCfgDesc[USB_HID_CONFIG_DESC_SIZ] __ALIGN_END = +{ 0x09, /* bLength: Configuration Descriptor size */ USB_DESC_TYPE_CONFIGURATION, /* bDescriptorType: Configuration */ - USB_HID_CONFIG_DESC_SIZ, - /* wTotalLength: Bytes returned */ + USB_HID_CONFIG_DESC_SIZ, /* wTotalLength: Bytes returned */ 0x00, 0x01, /* bNumInterfaces: 1 interface */ 0x01, /* bConfigurationValue: Configuration value */ 0x00, /* iConfiguration: Index of string descriptor describing the configuration */ - 0xE0, /* bmAttributes: bus powered and Support Remote Wake-up */ - 0x32, /* MaxPower 100 mA: this current is used for detecting Vbus */ +#if (USBD_SELF_POWERED == 1U) + 0xE0, /* bmAttributes: Bus Powered according to user configuration */ +#else + 0xA0, /* bmAttributes: Bus Powered according to user configuration */ +#endif + USBD_MAX_POWER, /* MaxPower (mA) */ /************** Descriptor of Joystick Mouse interface ****************/ /* 09 */ @@ -260,7 +273,7 @@ __ALIGN_BEGIN static uint8_t USBD_HID_OtherSpeedCfgDesc[USB_HID_CONFIG_DESC_SIZ] HID_EPIN_ADDR, /* bEndpointAddress: Endpoint Address (IN) */ 0x03, /* bmAttributes: Interrupt endpoint */ - HID_EPIN_SIZE, /* wMaxPacketSize: 4 Byte max */ + HID_EPIN_SIZE, /* wMaxPacketSize: 4 Bytes max */ 0x00, HID_FS_BINTERVAL, /* bInterval: Polling Interval */ /* 34 */ @@ -268,7 +281,8 @@ __ALIGN_BEGIN static uint8_t USBD_HID_OtherSpeedCfgDesc[USB_HID_CONFIG_DESC_SIZ] /* USB HID device Configuration Descriptor */ -__ALIGN_BEGIN static uint8_t USBD_HID_Desc[USB_HID_DESC_SIZ] __ALIGN_END = { +__ALIGN_BEGIN static uint8_t USBD_HID_Desc[USB_HID_DESC_SIZ] __ALIGN_END = +{ /* 18 */ 0x09, /* bLength: HID Descriptor size */ HID_DESCRIPTOR_TYPE, /* bDescriptorType: HID */ @@ -282,7 +296,8 @@ __ALIGN_BEGIN static uint8_t USBD_HID_Desc[USB_HID_DESC_SIZ] __ALIGN_END = { }; /* USB Standard Device Descriptor */ -__ALIGN_BEGIN static uint8_t USBD_HID_DeviceQualifierDesc[USB_LEN_DEV_QUALIFIER_DESC] __ALIGN_END = { +__ALIGN_BEGIN static uint8_t USBD_HID_DeviceQualifierDesc[USB_LEN_DEV_QUALIFIER_DESC] __ALIGN_END = +{ USB_LEN_DEV_QUALIFIER_DESC, USB_DESC_TYPE_DEVICE_QUALIFIER, 0x00, @@ -295,53 +310,46 @@ __ALIGN_BEGIN static uint8_t USBD_HID_DeviceQualifierDesc[USB_LEN_DEV_QUALIFIER_ 0x00, }; -__ALIGN_BEGIN static uint8_t HID_MOUSE_ReportDesc[HID_MOUSE_REPORT_DESC_SIZE] __ALIGN_END = { - 0x05, 0x01, - 0x09, 0x02, - 0xA1, 0x01, - 0x09, 0x01, - - 0xA1, 0x00, - 0x05, 0x09, - 0x19, 0x01, - 0x29, 0x03, - - 0x15, 0x00, - 0x25, 0x01, - 0x95, 0x03, - 0x75, 0x01, - - 0x81, 0x02, - 0x95, 0x01, - 0x75, 0x05, - 0x81, 0x01, - - 0x05, 0x01, - 0x09, 0x30, - 0x09, 0x31, - 0x09, 0x38, - - 0x15, 0x81, - 0x25, 0x7F, - 0x75, 0x08, - 0x95, 0x03, - - 0x81, 0x06, - 0xC0, 0x09, - 0x3c, 0x05, - 0xff, 0x09, - - 0x01, 0x15, - 0x00, 0x25, - 0x01, 0x75, - 0x01, 0x95, - - 0x02, 0xb1, - 0x22, 0x75, - 0x06, 0x95, - 0x01, 0xb1, - - 0x01, 0xc0 +__ALIGN_BEGIN static uint8_t HID_MOUSE_ReportDesc[HID_MOUSE_REPORT_DESC_SIZE] __ALIGN_END = +{ + 0x05, 0x01, /* Usage Page (Generic Desktop Ctrls) */ + 0x09, 0x02, /* Usage (Mouse) */ + 0xA1, 0x01, /* Collection (Application) */ + 0x09, 0x01, /* Usage (Pointer) */ + 0xA1, 0x00, /* Collection (Physical) */ + 0x05, 0x09, /* Usage Page (Button) */ + 0x19, 0x01, /* Usage Minimum (0x01) */ + 0x29, 0x03, /* Usage Maximum (0x03) */ + 0x15, 0x00, /* Logical Minimum (0) */ + 0x25, 0x01, /* Logical Maximum (1) */ + 0x95, 0x03, /* Report Count (3) */ + 0x75, 0x01, /* Report Size (1) */ + 0x81, 0x02, /* Input (Data,Var,Abs) */ + 0x95, 0x01, /* Report Count (1) */ + 0x75, 0x05, /* Report Size (5) */ + 0x81, 0x01, /* Input (Const,Array,Abs) */ + 0x05, 0x01, /* Usage Page (Generic Desktop Ctrls) */ + 0x09, 0x30, /* Usage (X) */ + 0x09, 0x31, /* Usage (Y) */ + 0x09, 0x38, /* Usage (Wheel) */ + 0x15, 0x81, /* Logical Minimum (-127) */ + 0x25, 0x7F, /* Logical Maximum (127) */ + 0x75, 0x08, /* Report Size (8) */ + 0x95, 0x03, /* Report Count (3) */ + 0x81, 0x06, /* Input (Data,Var,Rel) */ + 0xC0, /* End Collection */ + 0x09, 0x3C, /* Usage (Motion Wakeup) */ + 0x05, 0xFF, /* Usage Page (Reserved 0xFF) */ + 0x09, 0x01, /* Usage (0x01) */ + 0x15, 0x00, /* Logical Minimum (0) */ + 0x25, 0x01, /* Logical Maximum (1) */ + 0x75, 0x01, /* Report Size (1) */ + 0x95, 0x02, /* Report Count (2) */ + 0xB1, 0x22, /* Feature (Data,Var,Abs,NoWrp) */ + 0x75, 0x06, /* Report Size (6) */ + 0x95, 0x01, /* Report Count (1) */ + 0xB1, 0x01, /* Feature (Const,Array,Abs,NoWrp) */ + 0xC0 /* End Collection */ }; /** @@ -365,7 +373,7 @@ static uint8_t USBD_HID_Init(USBD_HandleTypeDef *pdev, uint8_t cfgidx) USBD_HID_HandleTypeDef *hhid; - hhid = USBD_malloc(sizeof(USBD_HID_HandleTypeDef)); + hhid = (USBD_HID_HandleTypeDef *)USBD_malloc(sizeof(USBD_HID_HandleTypeDef)); if (hhid == NULL) { @@ -384,7 +392,7 @@ static uint8_t USBD_HID_Init(USBD_HandleTypeDef *pdev, uint8_t cfgidx) pdev->ep_in[HID_EPIN_ADDR & 0xFU].bInterval = HID_FS_BINTERVAL; } - /* Open EP IN */ + /* Open EP IN */ (void)USBD_LL_OpenEP(pdev, HID_EPIN_ADDR, USBD_EP_TYPE_INTR, HID_EPIN_SIZE); pdev->ep_in[HID_EPIN_ADDR & 0xFU].is_used = 1U; @@ -409,7 +417,7 @@ static uint8_t USBD_HID_DeInit(USBD_HandleTypeDef *pdev, uint8_t cfgidx) pdev->ep_in[HID_EPIN_ADDR & 0xFU].is_used = 0U; pdev->ep_in[HID_EPIN_ADDR & 0xFU].bInterval = 0U; - /* FRee allocated memory */ + /* Free allocated memory */ if (pdev->pClassData != NULL) { (void)USBD_free(pdev->pClassData); @@ -434,106 +442,111 @@ static uint8_t USBD_HID_Setup(USBD_HandleTypeDef *pdev, USBD_SetupReqTypedef *re uint8_t *pbuf; uint16_t status_info = 0U; - switch (req->bmRequest & USB_REQ_TYPE_MASK) + if (hhid == NULL) { - case USB_REQ_TYPE_CLASS : - switch (req->bRequest) - { - case HID_REQ_SET_PROTOCOL: - hhid->Protocol = (uint8_t)(req->wValue); - break; - - case HID_REQ_GET_PROTOCOL: - (void)USBD_CtlSendData(pdev, (uint8_t *)&hhid->Protocol, 1U); - break; - - case HID_REQ_SET_IDLE: - hhid->IdleState = (uint8_t)(req->wValue >> 8); - break; - - case HID_REQ_GET_IDLE: - (void)USBD_CtlSendData(pdev, (uint8_t *)&hhid->IdleState, 1U); - break; - - default: - USBD_CtlError(pdev, req); - ret = USBD_FAIL; - break; - } - break; - case USB_REQ_TYPE_STANDARD: - switch (req->bRequest) - { - case USB_REQ_GET_STATUS: - if (pdev->dev_state == USBD_STATE_CONFIGURED) - { - (void)USBD_CtlSendData(pdev, (uint8_t *)&status_info, 2U); - } - else - { - USBD_CtlError(pdev, req); - ret = USBD_FAIL; - } - break; - - case USB_REQ_GET_DESCRIPTOR: - if ((req->wValue >> 8) == HID_REPORT_DESC) - { - len = MIN(HID_MOUSE_REPORT_DESC_SIZE, req->wLength); - pbuf = HID_MOUSE_ReportDesc; - } - else if ((req->wValue >> 8) == HID_DESCRIPTOR_TYPE) - { - pbuf = USBD_HID_Desc; - len = MIN(USB_HID_DESC_SIZ, req->wLength); - } - else - { - USBD_CtlError(pdev, req); - ret = USBD_FAIL; - break; - } - (void)USBD_CtlSendData(pdev, pbuf, len); - break; + return (uint8_t)USBD_FAIL; + } - case USB_REQ_GET_INTERFACE : - if (pdev->dev_state == USBD_STATE_CONFIGURED) - { - (void)USBD_CtlSendData(pdev, (uint8_t *)&hhid->AltSetting, 1U); - } - else + switch (req->bmRequest & USB_REQ_TYPE_MASK) + { + case USB_REQ_TYPE_CLASS : + switch (req->bRequest) { - USBD_CtlError(pdev, req); - ret = USBD_FAIL; + case HID_REQ_SET_PROTOCOL: + hhid->Protocol = (uint8_t)(req->wValue); + break; + + case HID_REQ_GET_PROTOCOL: + (void)USBD_CtlSendData(pdev, (uint8_t *)&hhid->Protocol, 1U); + break; + + case HID_REQ_SET_IDLE: + hhid->IdleState = (uint8_t)(req->wValue >> 8); + break; + + case HID_REQ_GET_IDLE: + (void)USBD_CtlSendData(pdev, (uint8_t *)&hhid->IdleState, 1U); + break; + + default: + USBD_CtlError(pdev, req); + ret = USBD_FAIL; + break; } break; - - case USB_REQ_SET_INTERFACE: - if (pdev->dev_state == USBD_STATE_CONFIGURED) - { - hhid->AltSetting = (uint8_t)(req->wValue); - } - else + case USB_REQ_TYPE_STANDARD: + switch (req->bRequest) { - USBD_CtlError(pdev, req); - ret = USBD_FAIL; + case USB_REQ_GET_STATUS: + if (pdev->dev_state == USBD_STATE_CONFIGURED) + { + (void)USBD_CtlSendData(pdev, (uint8_t *)&status_info, 2U); + } + else + { + USBD_CtlError(pdev, req); + ret = USBD_FAIL; + } + break; + + case USB_REQ_GET_DESCRIPTOR: + if ((req->wValue >> 8) == HID_REPORT_DESC) + { + len = MIN(HID_MOUSE_REPORT_DESC_SIZE, req->wLength); + pbuf = HID_MOUSE_ReportDesc; + } + else if ((req->wValue >> 8) == HID_DESCRIPTOR_TYPE) + { + pbuf = USBD_HID_Desc; + len = MIN(USB_HID_DESC_SIZ, req->wLength); + } + else + { + USBD_CtlError(pdev, req); + ret = USBD_FAIL; + break; + } + (void)USBD_CtlSendData(pdev, pbuf, len); + break; + + case USB_REQ_GET_INTERFACE : + if (pdev->dev_state == USBD_STATE_CONFIGURED) + { + (void)USBD_CtlSendData(pdev, (uint8_t *)&hhid->AltSetting, 1U); + } + else + { + USBD_CtlError(pdev, req); + ret = USBD_FAIL; + } + break; + + case USB_REQ_SET_INTERFACE: + if (pdev->dev_state == USBD_STATE_CONFIGURED) + { + hhid->AltSetting = (uint8_t)(req->wValue); + } + else + { + USBD_CtlError(pdev, req); + ret = USBD_FAIL; + } + break; + + case USB_REQ_CLEAR_FEATURE: + break; + + default: + USBD_CtlError(pdev, req); + ret = USBD_FAIL; + break; } break; - case USB_REQ_CLEAR_FEATURE: - break; - default: USBD_CtlError(pdev, req); ret = USBD_FAIL; break; - } - break; - - default: - USBD_CtlError(pdev, req); - ret = USBD_FAIL; - break; } return (uint8_t)ret; @@ -550,6 +563,11 @@ uint8_t USBD_HID_SendReport(USBD_HandleTypeDef *pdev, uint8_t *report, uint16_t { USBD_HID_HandleTypeDef *hhid = (USBD_HID_HandleTypeDef *)pdev->pClassData; + if (hhid == NULL) + { + return (uint8_t)USBD_FAIL; + } + if (pdev->dev_state == USBD_STATE_CONFIGURED) { if (hhid->state == HID_IDLE) @@ -651,11 +669,11 @@ static uint8_t USBD_HID_DataIn(USBD_HandleTypeDef *pdev, uint8_t epnum) /** -* @brief DeviceQualifierDescriptor -* return Device Qualifier descriptor -* @param length : pointer data length -* @retval pointer to descriptor buffer -*/ + * @brief DeviceQualifierDescriptor + * return Device Qualifier descriptor + * @param length : pointer data length + * @retval pointer to descriptor buffer + */ static uint8_t *USBD_HID_GetDeviceQualifierDesc(uint16_t *length) { *length = (uint16_t)sizeof(USBD_HID_DeviceQualifierDesc); diff --git a/system/Middlewares/ST/STM32_USB_Device_Library/Class/MSC/Inc/usbd_msc_bot.h b/system/Middlewares/ST/STM32_USB_Device_Library/Class/MSC/Inc/usbd_msc_bot.h index f5b1b6d42e..fb99095cd8 100644 --- a/system/Middlewares/ST/STM32_USB_Device_Library/Class/MSC/Inc/usbd_msc_bot.h +++ b/system/Middlewares/ST/STM32_USB_Device_Library/Class/MSC/Inc/usbd_msc_bot.h @@ -144,7 +144,7 @@ void MSC_BOT_CplClrFeature(USBD_HandleTypeDef *pdev, */ /** -* @} -*/ + * @} + */ /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ diff --git a/system/Middlewares/ST/STM32_USB_Device_Library/Class/MSC/Inc/usbd_msc_data.h b/system/Middlewares/ST/STM32_USB_Device_Library/Class/MSC/Inc/usbd_msc_data.h index 26838de02e..3aacf04a4c 100644 --- a/system/Middlewares/ST/STM32_USB_Device_Library/Class/MSC/Inc/usbd_msc_data.h +++ b/system/Middlewares/ST/STM32_USB_Device_Library/Class/MSC/Inc/usbd_msc_data.h @@ -99,7 +99,7 @@ extern uint8_t MSC_Mode_Sense10_data[MODE_SENSE10_LEN]; */ /** -* @} -*/ + * @} + */ /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ diff --git a/system/Middlewares/ST/STM32_USB_Device_Library/Class/MSC/Inc/usbd_msc_scsi.h b/system/Middlewares/ST/STM32_USB_Device_Library/Class/MSC/Inc/usbd_msc_scsi.h index b32ded0f6c..9bf10a9e6b 100644 --- a/system/Middlewares/ST/STM32_USB_Device_Library/Class/MSC/Inc/usbd_msc_scsi.h +++ b/system/Middlewares/ST/STM32_USB_Device_Library/Class/MSC/Inc/usbd_msc_scsi.h @@ -178,8 +178,8 @@ void SCSI_SenseCode(USBD_HandleTypeDef *pdev, uint8_t lun, uint8_t sKey, */ /** -* @} -*/ + * @} + */ /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ diff --git a/system/Middlewares/ST/STM32_USB_Device_Library/Class/MSC/Inc/usbd_msc_storage_template.h b/system/Middlewares/ST/STM32_USB_Device_Library/Class/MSC/Inc/usbd_msc_storage_template.h index 0288c308fc..9591a3ba9d 100644 --- a/system/Middlewares/ST/STM32_USB_Device_Library/Class/MSC/Inc/usbd_msc_storage_template.h +++ b/system/Middlewares/ST/STM32_USB_Device_Library/Class/MSC/Inc/usbd_msc_storage_template.h @@ -92,6 +92,6 @@ extern USBD_StorageTypeDef USBD_MSC_Template_fops; */ /** -* @} -*/ + * @} + */ /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ diff --git a/system/Middlewares/ST/STM32_USB_Device_Library/Class/MSC/Src/usbd_msc.c b/system/Middlewares/ST/STM32_USB_Device_Library/Class/MSC/Src/usbd_msc.c index fe6e1c6a24..09a61a6d36 100644 --- a/system/Middlewares/ST/STM32_USB_Device_Library/Class/MSC/Src/usbd_msc.c +++ b/system/Middlewares/ST/STM32_USB_Device_Library/Class/MSC/Src/usbd_msc.c @@ -123,16 +123,20 @@ USBD_ClassTypeDef USBD_MSC = /* All Descriptors (Configuration, Interface, Endpoint, Class, Vendor */ __ALIGN_BEGIN static uint8_t USBD_MSC_CfgHSDesc[USB_MSC_CONFIG_DESC_SIZ] __ALIGN_END = { - 0x09, /* bLength: Configuation Descriptor size */ + 0x09, /* bLength: Configuration 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 */ + 0x01, /* bConfigurationValue */ + 0x04, /* iConfiguration */ +#if (USBD_SELF_POWERED == 1U) + 0xC0, /* bmAttributes: Bus Powered according to user configuration */ +#else + 0x80, /* bmAttributes: Bus Powered according to user configuration */ +#endif + USBD_MAX_POWER, /* MaxPower (mA) */ /******************** Mass Storage interface ********************/ 0x09, /* bLength: Interface Descriptor size */ @@ -143,7 +147,7 @@ __ALIGN_BEGIN static uint8_t USBD_MSC_CfgHSDesc[USB_MSC_CONFIG_DESC_SIZ] __ALIG 0x08, /* bInterfaceClass: MSC Class */ 0x06, /* bInterfaceSubClass : SCSI transparent */ 0x50, /* nInterfaceProtocol */ - 0x05, /* iInterface: */ + 0x05, /* iInterface */ /******************** Mass Storage Endpoints ********************/ 0x07, /* Endpoint descriptor length = 7 */ 0x05, /* Endpoint descriptor type */ @@ -166,23 +170,27 @@ __ALIGN_BEGIN static uint8_t USBD_MSC_CfgHSDesc[USB_MSC_CONFIG_DESC_SIZ] __ALIG /* All Descriptors (Configuration, Interface, Endpoint, Class, Vendor */ __ALIGN_BEGIN static uint8_t USBD_MSC_CfgFSDesc[USB_MSC_CONFIG_DESC_SIZ] __ALIGN_END = { - 0x09, /* bLength: Configuation Descriptor size */ + 0x09, /* bLength: Configuration 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 */ + 0x01, /* bConfigurationValue */ + 0x04, /* iConfiguration */ +#if (USBD_SELF_POWERED == 1U) + 0xC0, /* bmAttributes: Bus Powered according to user configuration */ +#else + 0x80, /* bmAttributes: Bus Powered according to user configuration */ +#endif + USBD_MAX_POWER, /* MaxPower (mA) */ /******************** Mass Storage interface ********************/ 0x09, /* bLength: Interface Descriptor size */ 0x04, /* bDescriptorType: */ 0x00, /* bInterfaceNumber: Number of Interface */ 0x00, /* bAlternateSetting: Alternate setting */ - 0x02, /* bNumEndpoints*/ + 0x02, /* bNumEndpoints */ 0x08, /* bInterfaceClass: MSC Class */ 0x06, /* bInterfaceSubClass : SCSI transparent*/ 0x50, /* nInterfaceProtocol */ @@ -207,27 +215,31 @@ __ALIGN_BEGIN static uint8_t USBD_MSC_CfgFSDesc[USB_MSC_CONFIG_DESC_SIZ] __ALIG __ALIGN_BEGIN static uint8_t USBD_MSC_OtherSpeedCfgDesc[USB_MSC_CONFIG_DESC_SIZ] __ALIGN_END = { - 0x09, /* bLength: Configuation Descriptor size */ + 0x09, /* bLength: Configuration Descriptor size */ USB_DESC_TYPE_OTHER_SPEED_CONFIGURATION, USB_MSC_CONFIG_DESC_SIZ, 0x00, 0x01, /* bNumInterfaces: 1 interface */ - 0x01, /* bConfigurationValue: */ - 0x04, /* iConfiguration: */ - 0xC0, /* bmAttributes: */ - 0x32, /* MaxPower 100 mA */ + 0x01, /* bConfigurationValue */ + 0x04, /* iConfiguration */ +#if (USBD_SELF_POWERED == 1U) + 0xC0, /* bmAttributes: Bus Powered according to user configuration */ +#else + 0x80, /* bmAttributes: Bus Powered according to user configuration */ +#endif + USBD_MAX_POWER, /* MaxPower (mA) */ /******************** Mass Storage interface ********************/ 0x09, /* bLength: Interface Descriptor size */ - 0x04, /* bDescriptorType: */ + 0x04, /* bDescriptorType */ 0x00, /* bInterfaceNumber: Number of Interface */ 0x00, /* bAlternateSetting: Alternate setting */ 0x02, /* bNumEndpoints */ 0x08, /* bInterfaceClass: MSC Class */ 0x06, /* bInterfaceSubClass : SCSI transparent command set */ 0x50, /* nInterfaceProtocol */ - 0x05, /* iInterface: */ + 0x05, /* iInterface */ /******************** Mass Storage Endpoints ********************/ 0x07, /* Endpoint descriptor length = 7 */ 0x05, /* Endpoint descriptor type */ @@ -281,7 +293,7 @@ uint8_t USBD_MSC_Init(USBD_HandleTypeDef *pdev, uint8_t cfgidx) UNUSED(cfgidx); USBD_MSC_BOT_HandleTypeDef *hmsc; - hmsc = USBD_malloc(sizeof(USBD_MSC_BOT_HandleTypeDef)); + hmsc = (USBD_MSC_BOT_HandleTypeDef *)USBD_malloc(sizeof(USBD_MSC_BOT_HandleTypeDef)); if (hmsc == NULL) { @@ -320,7 +332,7 @@ uint8_t USBD_MSC_Init(USBD_HandleTypeDef *pdev, uint8_t cfgidx) /** * @brief USBD_MSC_DeInit - * DeInitilaize the mass storage configuration + * DeInitialize the mass storage configuration * @param pdev: device instance * @param cfgidx: configuration index * @retval status @@ -337,12 +349,12 @@ uint8_t USBD_MSC_DeInit(USBD_HandleTypeDef *pdev, uint8_t cfgidx) (void)USBD_LL_CloseEP(pdev, MSC_EPIN_ADDR); pdev->ep_in[MSC_EPIN_ADDR & 0xFU].is_used = 0U; - /* De-Init the BOT layer */ - MSC_BOT_DeInit(pdev); - /* Free MSC Class Resources */ if (pdev->pClassData != NULL) { + /* De-Init the BOT layer */ + MSC_BOT_DeInit(pdev); + (void)USBD_free(pdev->pClassData); pdev->pClassData = NULL; } @@ -350,108 +362,120 @@ uint8_t USBD_MSC_DeInit(USBD_HandleTypeDef *pdev, uint8_t cfgidx) return (uint8_t)USBD_OK; } /** -* @brief USBD_MSC_Setup -* Handle the MSC specific requests -* @param pdev: device instance -* @param req: USB request -* @retval status -*/ + * @brief USBD_MSC_Setup + * Handle the MSC specific requests + * @param pdev: device instance + * @param req: USB request + * @retval status + */ uint8_t USBD_MSC_Setup(USBD_HandleTypeDef *pdev, USBD_SetupReqTypedef *req) { USBD_MSC_BOT_HandleTypeDef *hmsc = (USBD_MSC_BOT_HandleTypeDef *)pdev->pClassData; USBD_StatusTypeDef ret = USBD_OK; uint16_t status_info = 0U; + if (hmsc == NULL) + { + return (uint8_t)USBD_FAIL; + } + switch (req->bmRequest & USB_REQ_TYPE_MASK) { /* Class request */ - case USB_REQ_TYPE_CLASS: - switch (req->bRequest) - { - case BOT_GET_MAX_LUN: - if ((req->wValue == 0U) && (req->wLength == 1U) && - ((req->bmRequest & 0x80U) == 0x80U)) - { - hmsc->max_lun = (uint32_t)((USBD_StorageTypeDef *)pdev->pUserData)->GetMaxLun(); - (void)USBD_CtlSendData(pdev, (uint8_t *)&hmsc->max_lun, 1U); - } - else + case USB_REQ_TYPE_CLASS: + switch (req->bRequest) { - USBD_CtlError(pdev, req); - ret = USBD_FAIL; + case BOT_GET_MAX_LUN: + if ((req->wValue == 0U) && (req->wLength == 1U) && + ((req->bmRequest & 0x80U) == 0x80U)) + { + hmsc->max_lun = (uint32_t)((USBD_StorageTypeDef *)pdev->pUserData)->GetMaxLun(); + (void)USBD_CtlSendData(pdev, (uint8_t *)&hmsc->max_lun, 1U); + } + else + { + USBD_CtlError(pdev, req); + ret = USBD_FAIL; + } + break; + + case BOT_RESET : + if ((req->wValue == 0U) && (req->wLength == 0U) && + ((req->bmRequest & 0x80U) != 0x80U)) + { + MSC_BOT_Reset(pdev); + } + else + { + USBD_CtlError(pdev, req); + ret = USBD_FAIL; + } + break; + + default: + USBD_CtlError(pdev, req); + ret = USBD_FAIL; + break; } break; - - case BOT_RESET : - if ((req->wValue == 0U) && (req->wLength == 0U) && - ((req->bmRequest & 0x80U) != 0x80U)) - { - MSC_BOT_Reset(pdev); - } - else - { - USBD_CtlError(pdev, req); - ret = USBD_FAIL; - } - break; - - default: - USBD_CtlError(pdev, req); - ret = USBD_FAIL; - break; - } - break; /* Interface & Endpoint request */ - case USB_REQ_TYPE_STANDARD: - switch (req->bRequest) - { - case USB_REQ_GET_STATUS: - if (pdev->dev_state == USBD_STATE_CONFIGURED) - { - (void)USBD_CtlSendData(pdev, (uint8_t *)&status_info, 2U); - } - else - { - USBD_CtlError(pdev, req); - ret = USBD_FAIL; - } - break; - - case USB_REQ_GET_INTERFACE: - if (pdev->dev_state == USBD_STATE_CONFIGURED) - { - (void)USBD_CtlSendData(pdev, (uint8_t *)&hmsc->interface, 1U); - } - else - { - USBD_CtlError(pdev, req); - ret = USBD_FAIL; - } - break; - - case USB_REQ_SET_INTERFACE: - if (pdev->dev_state == USBD_STATE_CONFIGURED) - { - hmsc->interface = (uint8_t)(req->wValue); - } - else - { - USBD_CtlError(pdev, req); - ret = USBD_FAIL; - } - break; - - case USB_REQ_CLEAR_FEATURE: - if (pdev->dev_state == USBD_STATE_CONFIGURED) + case USB_REQ_TYPE_STANDARD: + switch (req->bRequest) { - if (req->wValue == USB_FEATURE_EP_HALT) - { - /* Flush the FIFO */ - (void)USBD_LL_FlushEP(pdev, (uint8_t)req->wIndex); - - /* Handle BOT error */ - MSC_BOT_CplClrFeature(pdev, (uint8_t)req->wIndex); - } + case USB_REQ_GET_STATUS: + if (pdev->dev_state == USBD_STATE_CONFIGURED) + { + (void)USBD_CtlSendData(pdev, (uint8_t *)&status_info, 2U); + } + else + { + USBD_CtlError(pdev, req); + ret = USBD_FAIL; + } + break; + + case USB_REQ_GET_INTERFACE: + if (pdev->dev_state == USBD_STATE_CONFIGURED) + { + (void)USBD_CtlSendData(pdev, (uint8_t *)&hmsc->interface, 1U); + } + else + { + USBD_CtlError(pdev, req); + ret = USBD_FAIL; + } + break; + + case USB_REQ_SET_INTERFACE: + if (pdev->dev_state == USBD_STATE_CONFIGURED) + { + hmsc->interface = (uint8_t)(req->wValue); + } + else + { + USBD_CtlError(pdev, req); + ret = USBD_FAIL; + } + break; + + case USB_REQ_CLEAR_FEATURE: + if (pdev->dev_state == USBD_STATE_CONFIGURED) + { + if (req->wValue == USB_FEATURE_EP_HALT) + { + /* Flush the FIFO */ + (void)USBD_LL_FlushEP(pdev, (uint8_t)req->wIndex); + + /* Handle BOT error */ + MSC_BOT_CplClrFeature(pdev, (uint8_t)req->wIndex); + } + } + break; + + default: + USBD_CtlError(pdev, req); + ret = USBD_FAIL; + break; } break; @@ -459,25 +483,18 @@ uint8_t USBD_MSC_Setup(USBD_HandleTypeDef *pdev, USBD_SetupReqTypedef *req) USBD_CtlError(pdev, req); ret = USBD_FAIL; break; - } - break; - - default: - USBD_CtlError(pdev, req); - ret = USBD_FAIL; - break; } return (uint8_t)ret; } /** -* @brief USBD_MSC_DataIn -* handle data IN Stage -* @param pdev: device instance -* @param epnum: endpoint index -* @retval status -*/ + * @brief USBD_MSC_DataIn + * handle data IN Stage + * @param pdev: device instance + * @param epnum: endpoint index + * @retval status + */ uint8_t USBD_MSC_DataIn(USBD_HandleTypeDef *pdev, uint8_t epnum) { MSC_BOT_DataIn(pdev, epnum); @@ -486,12 +503,12 @@ uint8_t USBD_MSC_DataIn(USBD_HandleTypeDef *pdev, uint8_t epnum) } /** -* @brief USBD_MSC_DataOut -* handle data OUT Stage -* @param pdev: device instance -* @param epnum: endpoint index -* @retval status -*/ + * @brief USBD_MSC_DataOut + * handle data OUT Stage + * @param pdev: device instance + * @param epnum: endpoint index + * @retval status + */ uint8_t USBD_MSC_DataOut(USBD_HandleTypeDef *pdev, uint8_t epnum) { MSC_BOT_DataOut(pdev, epnum); @@ -500,11 +517,11 @@ uint8_t USBD_MSC_DataOut(USBD_HandleTypeDef *pdev, uint8_t epnum) } /** -* @brief USBD_MSC_GetHSCfgDesc -* return configuration descriptor -* @param length : pointer data length -* @retval pointer to descriptor buffer -*/ + * @brief USBD_MSC_GetHSCfgDesc + * return configuration descriptor + * @param length : pointer data length + * @retval pointer to descriptor buffer + */ uint8_t *USBD_MSC_GetHSCfgDesc(uint16_t *length) { *length = (uint16_t)sizeof(USBD_MSC_CfgHSDesc); @@ -513,11 +530,11 @@ uint8_t *USBD_MSC_GetHSCfgDesc(uint16_t *length) } /** -* @brief USBD_MSC_GetFSCfgDesc -* return configuration descriptor -* @param length : pointer data length -* @retval pointer to descriptor buffer -*/ + * @brief USBD_MSC_GetFSCfgDesc + * return configuration descriptor + * @param length : pointer data length + * @retval pointer to descriptor buffer + */ uint8_t *USBD_MSC_GetFSCfgDesc(uint16_t *length) { *length = (uint16_t)sizeof(USBD_MSC_CfgFSDesc); @@ -526,11 +543,11 @@ uint8_t *USBD_MSC_GetFSCfgDesc(uint16_t *length) } /** -* @brief USBD_MSC_GetOtherSpeedCfgDesc -* return other speed configuration descriptor -* @param length : pointer data length -* @retval pointer to descriptor buffer -*/ + * @brief USBD_MSC_GetOtherSpeedCfgDesc + * return other speed configuration descriptor + * @param length : pointer data length + * @retval pointer to descriptor buffer + */ uint8_t *USBD_MSC_GetOtherSpeedCfgDesc(uint16_t *length) { *length = (uint16_t)sizeof(USBD_MSC_OtherSpeedCfgDesc); @@ -538,11 +555,11 @@ uint8_t *USBD_MSC_GetOtherSpeedCfgDesc(uint16_t *length) return USBD_MSC_OtherSpeedCfgDesc; } /** -* @brief DeviceQualifierDescriptor -* return Device Qualifier descriptor -* @param length : pointer data length -* @retval pointer to descriptor buffer -*/ + * @brief DeviceQualifierDescriptor + * return Device Qualifier descriptor + * @param length : pointer data length + * @retval pointer to descriptor buffer + */ uint8_t *USBD_MSC_GetDeviceQualifierDescriptor(uint16_t *length) { *length = (uint16_t)sizeof(USBD_MSC_DeviceQualifierDesc); @@ -551,10 +568,10 @@ uint8_t *USBD_MSC_GetDeviceQualifierDescriptor(uint16_t *length) } /** -* @brief USBD_MSC_RegisterStorage -* @param fops: storage callback -* @retval status -*/ + * @brief USBD_MSC_RegisterStorage + * @param fops: storage callback + * @retval status + */ uint8_t USBD_MSC_RegisterStorage(USBD_HandleTypeDef *pdev, USBD_StorageTypeDef *fops) { if (fops == NULL) diff --git a/system/Middlewares/ST/STM32_USB_Device_Library/Class/MSC/Src/usbd_msc_bot.c b/system/Middlewares/ST/STM32_USB_Device_Library/Class/MSC/Src/usbd_msc_bot.c index ae68ac055c..bbe94303e6 100644 --- a/system/Middlewares/ST/STM32_USB_Device_Library/Class/MSC/Src/usbd_msc_bot.c +++ b/system/Middlewares/ST/STM32_USB_Device_Library/Class/MSC/Src/usbd_msc_bot.c @@ -90,15 +90,20 @@ static void MSC_BOT_Abort(USBD_HandleTypeDef *pdev); /** -* @brief MSC_BOT_Init -* Initialize the BOT Process -* @param pdev: device instance -* @retval None -*/ + * @brief MSC_BOT_Init + * Initialize the BOT Process + * @param pdev: device instance + * @retval None + */ void MSC_BOT_Init(USBD_HandleTypeDef *pdev) { USBD_MSC_BOT_HandleTypeDef *hmsc = (USBD_MSC_BOT_HandleTypeDef *)pdev->pClassData; + if (hmsc == NULL) + { + return; + } + hmsc->bot_state = USBD_BOT_IDLE; hmsc->bot_status = USBD_BOT_STATUS_NORMAL; @@ -111,88 +116,107 @@ void MSC_BOT_Init(USBD_HandleTypeDef *pdev) (void)USBD_LL_FlushEP(pdev, MSC_EPOUT_ADDR); (void)USBD_LL_FlushEP(pdev, MSC_EPIN_ADDR); - /* Prapare EP to Receive First BOT Cmd */ + /* Prepare EP to Receive First BOT Cmd */ (void)USBD_LL_PrepareReceive(pdev, MSC_EPOUT_ADDR, (uint8_t *)&hmsc->cbw, USBD_BOT_CBW_LENGTH); } /** -* @brief MSC_BOT_Reset -* Reset the BOT Machine -* @param pdev: device instance -* @retval None -*/ + * @brief MSC_BOT_Reset + * Reset the BOT Machine + * @param pdev: device instance + * @retval None + */ void MSC_BOT_Reset(USBD_HandleTypeDef *pdev) { USBD_MSC_BOT_HandleTypeDef *hmsc = (USBD_MSC_BOT_HandleTypeDef *)pdev->pClassData; + if (hmsc == NULL) + { + return; + } + hmsc->bot_state = USBD_BOT_IDLE; hmsc->bot_status = USBD_BOT_STATUS_RECOVERY; (void)USBD_LL_ClearStallEP(pdev, MSC_EPIN_ADDR); (void)USBD_LL_ClearStallEP(pdev, MSC_EPOUT_ADDR); - /* Prapare EP to Receive First BOT Cmd */ + /* Prepare EP to Receive First BOT Cmd */ (void)USBD_LL_PrepareReceive(pdev, MSC_EPOUT_ADDR, (uint8_t *)&hmsc->cbw, USBD_BOT_CBW_LENGTH); } /** -* @brief MSC_BOT_DeInit -* Deinitialize the BOT Machine -* @param pdev: device instance -* @retval None -*/ + * @brief MSC_BOT_DeInit + * DeInitialize the BOT Machine + * @param pdev: device instance + * @retval None + */ void MSC_BOT_DeInit(USBD_HandleTypeDef *pdev) { USBD_MSC_BOT_HandleTypeDef *hmsc = (USBD_MSC_BOT_HandleTypeDef *)pdev->pClassData; - hmsc->bot_state = USBD_BOT_IDLE; + + if (hmsc != NULL) + { + hmsc->bot_state = USBD_BOT_IDLE; + } } /** -* @brief MSC_BOT_DataIn -* Handle BOT IN data stage -* @param pdev: device instance -* @param epnum: endpoint index -* @retval None -*/ + * @brief MSC_BOT_DataIn + * Handle BOT IN data stage + * @param pdev: device instance + * @param epnum: endpoint index + * @retval None + */ void MSC_BOT_DataIn(USBD_HandleTypeDef *pdev, uint8_t epnum) { UNUSED(epnum); USBD_MSC_BOT_HandleTypeDef *hmsc = (USBD_MSC_BOT_HandleTypeDef *)pdev->pClassData; + if (hmsc == NULL) + { + return; + } + switch (hmsc->bot_state) { - case USBD_BOT_DATA_IN: - if (SCSI_ProcessCmd(pdev, hmsc->cbw.bLUN, &hmsc->cbw.CB[0]) < 0) - { - MSC_BOT_SendCSW(pdev, USBD_CSW_CMD_FAILED); - } - break; + case USBD_BOT_DATA_IN: + if (SCSI_ProcessCmd(pdev, hmsc->cbw.bLUN, &hmsc->cbw.CB[0]) < 0) + { + MSC_BOT_SendCSW(pdev, USBD_CSW_CMD_FAILED); + } + break; - case USBD_BOT_SEND_DATA: - case USBD_BOT_LAST_DATA_IN: - MSC_BOT_SendCSW(pdev, USBD_CSW_CMD_PASSED); - break; + case USBD_BOT_SEND_DATA: + case USBD_BOT_LAST_DATA_IN: + MSC_BOT_SendCSW(pdev, USBD_CSW_CMD_PASSED); + break; - default: - break; + default: + break; } } /** -* @brief MSC_BOT_DataOut -* Process MSC OUT data -* @param pdev: device instance -* @param epnum: endpoint index -* @retval None -*/ + * @brief MSC_BOT_DataOut + * Process MSC OUT data + * @param pdev: device instance + * @param epnum: endpoint index + * @retval None + */ void MSC_BOT_DataOut(USBD_HandleTypeDef *pdev, uint8_t epnum) { UNUSED(epnum); USBD_MSC_BOT_HandleTypeDef *hmsc = (USBD_MSC_BOT_HandleTypeDef *)pdev->pClassData; + if (hmsc == NULL) + { + return; + } + switch (hmsc->bot_state) { case USBD_BOT_IDLE: @@ -212,15 +236,20 @@ void MSC_BOT_DataOut(USBD_HandleTypeDef *pdev, uint8_t epnum) } /** -* @brief MSC_BOT_CBW_Decode -* Decode the CBW command and set the BOT state machine accordingly -* @param pdev: device instance -* @retval None -*/ + * @brief MSC_BOT_CBW_Decode + * Decode the CBW command and set the BOT state machine accordingly + * @param pdev: device instance + * @retval None + */ static void MSC_BOT_CBW_Decode(USBD_HandleTypeDef *pdev) { USBD_MSC_BOT_HandleTypeDef *hmsc = (USBD_MSC_BOT_HandleTypeDef *)pdev->pClassData; + if (hmsc == NULL) + { + return; + } + hmsc->csw.dTag = hmsc->cbw.dTag; hmsc->csw.dDataResidue = hmsc->cbw.dDataLength; @@ -273,19 +302,24 @@ static void MSC_BOT_CBW_Decode(USBD_HandleTypeDef *pdev) } /** -* @brief MSC_BOT_SendData -* Send the requested data -* @param pdev: device instance -* @param buf: pointer to data buffer -* @param len: Data Length -* @retval None -*/ + * @brief MSC_BOT_SendData + * Send the requested data + * @param pdev: device instance + * @param buf: pointer to data buffer + * @param len: Data Length + * @retval None + */ static void MSC_BOT_SendData(USBD_HandleTypeDef *pdev, uint8_t *pbuf, uint32_t len) { USBD_MSC_BOT_HandleTypeDef *hmsc = (USBD_MSC_BOT_HandleTypeDef *)pdev->pClassData; uint32_t length = MIN(hmsc->cbw.dDataLength, len); + if (hmsc == NULL) + { + return; + } + hmsc->csw.dDataResidue -= len; hmsc->csw.bStatus = USBD_CSW_CMD_PASSED; hmsc->bot_state = USBD_BOT_SEND_DATA; @@ -294,16 +328,21 @@ static void MSC_BOT_SendData(USBD_HandleTypeDef *pdev, uint8_t *pbuf, uint32_t } /** -* @brief MSC_BOT_SendCSW -* Send the Command Status Wrapper -* @param pdev: device instance -* @param status : CSW status -* @retval None -*/ + * @brief MSC_BOT_SendCSW + * Send the Command Status Wrapper + * @param pdev: device instance + * @param status : CSW status + * @retval None + */ void MSC_BOT_SendCSW(USBD_HandleTypeDef *pdev, uint8_t CSW_Status) { USBD_MSC_BOT_HandleTypeDef *hmsc = (USBD_MSC_BOT_HandleTypeDef *)pdev->pClassData; + if (hmsc == NULL) + { + return; + } + hmsc->csw.dSignature = USBD_BOT_CSW_SIGNATURE; hmsc->csw.bStatus = CSW_Status; hmsc->bot_state = USBD_BOT_IDLE; @@ -317,16 +356,21 @@ void MSC_BOT_SendCSW(USBD_HandleTypeDef *pdev, uint8_t CSW_Status) } /** -* @brief MSC_BOT_Abort -* Abort the current transfer -* @param pdev: device instance -* @retval status -*/ + * @brief MSC_BOT_Abort + * Abort the current transfer + * @param pdev: device instance + * @retval status + */ static void MSC_BOT_Abort(USBD_HandleTypeDef *pdev) { USBD_MSC_BOT_HandleTypeDef *hmsc = (USBD_MSC_BOT_HandleTypeDef *)pdev->pClassData; + if (hmsc == NULL) + { + return; + } + if ((hmsc->cbw.bmFlags == 0U) && (hmsc->cbw.dDataLength != 0U) && (hmsc->bot_status == USBD_BOT_STATUS_NORMAL)) @@ -344,17 +388,22 @@ static void MSC_BOT_Abort(USBD_HandleTypeDef *pdev) } /** -* @brief MSC_BOT_CplClrFeature -* Complete the clear feature request -* @param pdev: device instance -* @param epnum: endpoint index -* @retval None -*/ + * @brief MSC_BOT_CplClrFeature + * Complete the clear feature request + * @param pdev: device instance + * @param epnum: endpoint index + * @retval None + */ void MSC_BOT_CplClrFeature(USBD_HandleTypeDef *pdev, uint8_t epnum) { USBD_MSC_BOT_HandleTypeDef *hmsc = (USBD_MSC_BOT_HandleTypeDef *)pdev->pClassData; + if (hmsc == NULL) + { + return; + } + if (hmsc->bot_status == USBD_BOT_STATUS_ERROR) /* Bad CBW Signature */ { (void)USBD_LL_StallEP(pdev, MSC_EPIN_ADDR); diff --git a/system/Middlewares/ST/STM32_USB_Device_Library/Class/MSC/Src/usbd_msc_data.c b/system/Middlewares/ST/STM32_USB_Device_Library/Class/MSC/Src/usbd_msc_data.c index d1c3a9772d..34ef4438df 100644 --- a/system/Middlewares/ST/STM32_USB_Device_Library/Class/MSC/Src/usbd_msc_data.c +++ b/system/Middlewares/ST/STM32_USB_Device_Library/Class/MSC/Src/usbd_msc_data.c @@ -87,7 +87,7 @@ uint8_t MSC_Page80_Inquiry_Data[LENGTH_INQUIRY_PAGE80] = 0x20, 0x20, 0x20 - }; +}; /* USB Mass storage sense 6 Data */ uint8_t MSC_Mode_Sense6_data[MODE_SENSE6_LEN] = diff --git a/system/Middlewares/ST/STM32_USB_Device_Library/Class/MSC/Src/usbd_msc_scsi.c b/system/Middlewares/ST/STM32_USB_Device_Library/Class/MSC/Src/usbd_msc_scsi.c index 5c36a6e8c8..02fdc833a3 100644 --- a/system/Middlewares/ST/STM32_USB_Device_Library/Class/MSC/Src/usbd_msc_scsi.c +++ b/system/Middlewares/ST/STM32_USB_Device_Library/Class/MSC/Src/usbd_msc_scsi.c @@ -111,85 +111,90 @@ static int8_t SCSI_UpdateBotData(USBD_MSC_BOT_HandleTypeDef *hmsc, /** -* @brief SCSI_ProcessCmd -* Process SCSI commands -* @param pdev: device instance -* @param lun: Logical unit number -* @param params: Command parameters -* @retval status -*/ + * @brief SCSI_ProcessCmd + * Process SCSI commands + * @param pdev: device instance + * @param lun: Logical unit number + * @param params: Command parameters + * @retval status + */ int8_t SCSI_ProcessCmd(USBD_HandleTypeDef *pdev, uint8_t lun, uint8_t *cmd) { int8_t ret; USBD_MSC_BOT_HandleTypeDef *hmsc = (USBD_MSC_BOT_HandleTypeDef *)pdev->pClassData; + if (hmsc == NULL) + { + return -1; + } + switch (cmd[0]) { - case SCSI_TEST_UNIT_READY: - ret = SCSI_TestUnitReady(pdev, lun, cmd); - break; - - case SCSI_REQUEST_SENSE: - ret = SCSI_RequestSense(pdev, lun, cmd); - break; - - case SCSI_INQUIRY: - ret = SCSI_Inquiry(pdev, lun, cmd); - break; - - case SCSI_START_STOP_UNIT: - ret = SCSI_StartStopUnit(pdev, lun, cmd); - break; - - case SCSI_ALLOW_MEDIUM_REMOVAL: - ret = SCSI_AllowPreventRemovable(pdev, lun, cmd); - break; - - case SCSI_MODE_SENSE6: - ret = SCSI_ModeSense6(pdev, lun, cmd); - break; - - case SCSI_MODE_SENSE10: - ret = SCSI_ModeSense10(pdev, lun, cmd); - break; - - case SCSI_READ_FORMAT_CAPACITIES: - ret = SCSI_ReadFormatCapacity(pdev, lun, cmd); - break; - - case SCSI_READ_CAPACITY10: - ret = SCSI_ReadCapacity10(pdev, lun, cmd); - break; - - case SCSI_READ_CAPACITY16: - ret = SCSI_ReadCapacity16(pdev, lun, cmd); - break; - - case SCSI_READ10: - ret = SCSI_Read10(pdev, lun, cmd); - break; - - case SCSI_READ12: - ret = SCSI_Read12(pdev, lun, cmd); - break; - - case SCSI_WRITE10: - ret = SCSI_Write10(pdev, lun, cmd); - break; - - case SCSI_WRITE12: - ret = SCSI_Write12(pdev, lun, cmd); - break; - - case SCSI_VERIFY10: - ret = SCSI_Verify10(pdev, lun, cmd); - break; - - default: - SCSI_SenseCode(pdev, lun, ILLEGAL_REQUEST, INVALID_CDB); - hmsc->bot_status = USBD_BOT_STATUS_ERROR; - ret = -1; - break; + case SCSI_TEST_UNIT_READY: + ret = SCSI_TestUnitReady(pdev, lun, cmd); + break; + + case SCSI_REQUEST_SENSE: + ret = SCSI_RequestSense(pdev, lun, cmd); + break; + + case SCSI_INQUIRY: + ret = SCSI_Inquiry(pdev, lun, cmd); + break; + + case SCSI_START_STOP_UNIT: + ret = SCSI_StartStopUnit(pdev, lun, cmd); + break; + + case SCSI_ALLOW_MEDIUM_REMOVAL: + ret = SCSI_AllowPreventRemovable(pdev, lun, cmd); + break; + + case SCSI_MODE_SENSE6: + ret = SCSI_ModeSense6(pdev, lun, cmd); + break; + + case SCSI_MODE_SENSE10: + ret = SCSI_ModeSense10(pdev, lun, cmd); + break; + + case SCSI_READ_FORMAT_CAPACITIES: + ret = SCSI_ReadFormatCapacity(pdev, lun, cmd); + break; + + case SCSI_READ_CAPACITY10: + ret = SCSI_ReadCapacity10(pdev, lun, cmd); + break; + + case SCSI_READ_CAPACITY16: + ret = SCSI_ReadCapacity16(pdev, lun, cmd); + break; + + case SCSI_READ10: + ret = SCSI_Read10(pdev, lun, cmd); + break; + + case SCSI_READ12: + ret = SCSI_Read12(pdev, lun, cmd); + break; + + case SCSI_WRITE10: + ret = SCSI_Write10(pdev, lun, cmd); + break; + + case SCSI_WRITE12: + ret = SCSI_Write12(pdev, lun, cmd); + break; + + case SCSI_VERIFY10: + ret = SCSI_Verify10(pdev, lun, cmd); + break; + + default: + SCSI_SenseCode(pdev, lun, ILLEGAL_REQUEST, INVALID_CDB); + hmsc->bot_status = USBD_BOT_STATUS_ERROR; + ret = -1; + break; } return ret; @@ -197,17 +202,22 @@ int8_t SCSI_ProcessCmd(USBD_HandleTypeDef *pdev, uint8_t lun, uint8_t *cmd) /** -* @brief SCSI_TestUnitReady -* Process SCSI Test Unit Ready Command -* @param lun: Logical unit number -* @param params: Command parameters -* @retval status -*/ + * @brief SCSI_TestUnitReady + * Process SCSI Test Unit Ready Command + * @param lun: Logical unit number + * @param params: Command parameters + * @retval status + */ static int8_t SCSI_TestUnitReady(USBD_HandleTypeDef *pdev, uint8_t lun, uint8_t *params) { UNUSED(params); USBD_MSC_BOT_HandleTypeDef *hmsc = (USBD_MSC_BOT_HandleTypeDef *)pdev->pClassData; + if (hmsc == NULL) + { + return -1; + } + /* case 9 : Hi > D0 */ if (hmsc->cbw.dDataLength != 0U) { @@ -237,18 +247,23 @@ static int8_t SCSI_TestUnitReady(USBD_HandleTypeDef *pdev, uint8_t lun, uint8_t /** -* @brief SCSI_Inquiry -* Process Inquiry command -* @param lun: Logical unit number -* @param params: Command parameters -* @retval status -*/ + * @brief SCSI_Inquiry + * Process Inquiry command + * @param lun: Logical unit number + * @param params: Command parameters + * @retval status + */ static int8_t SCSI_Inquiry(USBD_HandleTypeDef *pdev, uint8_t lun, uint8_t *params) { uint8_t *pPage; uint16_t len; USBD_MSC_BOT_HandleTypeDef *hmsc = (USBD_MSC_BOT_HandleTypeDef *)pdev->pClassData; + if (hmsc == NULL) + { + return -1; + } + if (hmsc->cbw.dDataLength == 0U) { SCSI_SenseCode(pdev, hmsc->cbw.bLUN, ILLEGAL_REQUEST, INVALID_CDB); @@ -275,7 +290,7 @@ static int8_t SCSI_Inquiry(USBD_HandleTypeDef *pdev, uint8_t lun, uint8_t *param } else { - pPage = (uint8_t *)&((USBD_StorageTypeDef *)pdev->pUserData)->pInquiry[lun * STANDARD_INQUIRY_DATA_LEN]; + pPage = (uint8_t *) &((USBD_StorageTypeDef *)pdev->pUserData)->pInquiry[lun * STANDARD_INQUIRY_DATA_LEN]; len = (uint16_t)pPage[4] + 5U; if (params[4] <= len) @@ -291,18 +306,23 @@ static int8_t SCSI_Inquiry(USBD_HandleTypeDef *pdev, uint8_t lun, uint8_t *param /** -* @brief SCSI_ReadCapacity10 -* Process Read Capacity 10 command -* @param lun: Logical unit number -* @param params: Command parameters -* @retval status -*/ + * @brief SCSI_ReadCapacity10 + * Process Read Capacity 10 command + * @param lun: Logical unit number + * @param params: Command parameters + * @retval status + */ static int8_t SCSI_ReadCapacity10(USBD_HandleTypeDef *pdev, uint8_t lun, uint8_t *params) { UNUSED(params); int8_t ret; USBD_MSC_BOT_HandleTypeDef *hmsc = (USBD_MSC_BOT_HandleTypeDef *)pdev->pClassData; + if (hmsc == NULL) + { + return -1; + } + ret = ((USBD_StorageTypeDef *)pdev->pUserData)->GetCapacity(lun, &hmsc->scsi_blk_nbr, &hmsc->scsi_blk_size); if ((ret != 0) || (hmsc->scsi_medium_state == SCSI_MEDIUM_EJECTED)) @@ -329,12 +349,12 @@ static int8_t SCSI_ReadCapacity10(USBD_HandleTypeDef *pdev, uint8_t lun, uint8_t /** -* @brief SCSI_ReadCapacity16 -* Process Read Capacity 16 command -* @param lun: Logical unit number -* @param params: Command parameters -* @retval status -*/ + * @brief SCSI_ReadCapacity16 + * Process Read Capacity 16 command + * @param lun: Logical unit number + * @param params: Command parameters + * @retval status + */ static int8_t SCSI_ReadCapacity16(USBD_HandleTypeDef *pdev, uint8_t lun, uint8_t *params) { UNUSED(params); @@ -342,6 +362,11 @@ static int8_t SCSI_ReadCapacity16(USBD_HandleTypeDef *pdev, uint8_t lun, uint8_t int8_t ret; USBD_MSC_BOT_HandleTypeDef *hmsc = (USBD_MSC_BOT_HandleTypeDef *)pdev->pClassData; + if (hmsc == NULL) + { + return -1; + } + ret = ((USBD_StorageTypeDef *)pdev->pUserData)->GetCapacity(lun, &hmsc->scsi_blk_nbr, &hmsc->scsi_blk_size); if ((ret != 0) || (hmsc->scsi_medium_state == SCSI_MEDIUM_EJECTED)) @@ -353,7 +378,7 @@ static int8_t SCSI_ReadCapacity16(USBD_HandleTypeDef *pdev, uint8_t lun, uint8_t hmsc->bot_data_length = ((uint32_t)params[10] << 24) | ((uint32_t)params[11] << 16) | ((uint32_t)params[12] << 8) | - (uint32_t)params[13]; + (uint32_t)params[13]; for (idx = 0U; idx < hmsc->bot_data_length; idx++) { @@ -373,19 +398,19 @@ static int8_t SCSI_ReadCapacity16(USBD_HandleTypeDef *pdev, uint8_t lun, uint8_t hmsc->bot_data_length = ((uint32_t)params[10] << 24) | ((uint32_t)params[11] << 16) | ((uint32_t)params[12] << 8) | - (uint32_t)params[13]; + (uint32_t)params[13]; return 0; } /** -* @brief SCSI_ReadFormatCapacity -* Process Read Format Capacity command -* @param lun: Logical unit number -* @param params: Command parameters -* @retval status -*/ + * @brief SCSI_ReadFormatCapacity + * Process Read Format Capacity command + * @param lun: Logical unit number + * @param params: Command parameters + * @retval status + */ static int8_t SCSI_ReadFormatCapacity(USBD_HandleTypeDef *pdev, uint8_t lun, uint8_t *params) { UNUSED(params); @@ -395,6 +420,11 @@ static int8_t SCSI_ReadFormatCapacity(USBD_HandleTypeDef *pdev, uint8_t lun, uin int8_t ret; USBD_MSC_BOT_HandleTypeDef *hmsc = (USBD_MSC_BOT_HandleTypeDef *)pdev->pClassData; + if (hmsc == NULL) + { + return -1; + } + ret = ((USBD_StorageTypeDef *)pdev->pUserData)->GetCapacity(lun, &blk_nbr, &blk_size); if ((ret != 0) || (hmsc->scsi_medium_state == SCSI_MEDIUM_EJECTED)) @@ -426,18 +456,23 @@ static int8_t SCSI_ReadFormatCapacity(USBD_HandleTypeDef *pdev, uint8_t lun, uin /** -* @brief SCSI_ModeSense6 -* Process Mode Sense6 command -* @param lun: Logical unit number -* @param params: Command parameters -* @retval status -*/ + * @brief SCSI_ModeSense6 + * Process Mode Sense6 command + * @param lun: Logical unit number + * @param params: Command parameters + * @retval status + */ static int8_t SCSI_ModeSense6(USBD_HandleTypeDef *pdev, uint8_t lun, uint8_t *params) { UNUSED(lun); USBD_MSC_BOT_HandleTypeDef *hmsc = (USBD_MSC_BOT_HandleTypeDef *)pdev->pClassData; uint16_t len = MODE_SENSE6_LEN; + if (hmsc == NULL) + { + return -1; + } + if (params[4] <= len) { len = params[4]; @@ -450,18 +485,23 @@ static int8_t SCSI_ModeSense6(USBD_HandleTypeDef *pdev, uint8_t lun, uint8_t *pa /** -* @brief SCSI_ModeSense10 -* Process Mode Sense10 command -* @param lun: Logical unit number -* @param params: Command parameters -* @retval status -*/ + * @brief SCSI_ModeSense10 + * Process Mode Sense10 command + * @param lun: Logical unit number + * @param params: Command parameters + * @retval status + */ static int8_t SCSI_ModeSense10(USBD_HandleTypeDef *pdev, uint8_t lun, uint8_t *params) { UNUSED(lun); USBD_MSC_BOT_HandleTypeDef *hmsc = (USBD_MSC_BOT_HandleTypeDef *)pdev->pClassData; uint16_t len = MODE_SENSE10_LEN; + if (hmsc == NULL) + { + return -1; + } + if (params[8] <= len) { len = params[8]; @@ -474,18 +514,23 @@ static int8_t SCSI_ModeSense10(USBD_HandleTypeDef *pdev, uint8_t lun, uint8_t *p /** -* @brief SCSI_RequestSense -* Process Request Sense command -* @param lun: Logical unit number -* @param params: Command parameters -* @retval status -*/ + * @brief SCSI_RequestSense + * Process Request Sense command + * @param lun: Logical unit number + * @param params: Command parameters + * @retval status + */ static int8_t SCSI_RequestSense(USBD_HandleTypeDef *pdev, uint8_t lun, uint8_t *params) { UNUSED(lun); uint8_t i; USBD_MSC_BOT_HandleTypeDef *hmsc = (USBD_MSC_BOT_HandleTypeDef *)pdev->pClassData; + if (hmsc == NULL) + { + return -1; + } + if (hmsc->cbw.dDataLength == 0U) { SCSI_SenseCode(pdev, hmsc->cbw.bLUN, ILLEGAL_REQUEST, INVALID_CDB); @@ -525,19 +570,24 @@ static int8_t SCSI_RequestSense(USBD_HandleTypeDef *pdev, uint8_t lun, uint8_t * /** -* @brief SCSI_SenseCode -* Load the last error code in the error list -* @param lun: Logical unit number -* @param sKey: Sense Key -* @param ASC: Additional Sense Code -* @retval none - -*/ + * @brief SCSI_SenseCode + * Load the last error code in the error list + * @param lun: Logical unit number + * @param sKey: Sense Key + * @param ASC: Additional Sense Code + * @retval none + + */ void SCSI_SenseCode(USBD_HandleTypeDef *pdev, uint8_t lun, uint8_t sKey, uint8_t ASC) { UNUSED(lun); USBD_MSC_BOT_HandleTypeDef *hmsc = (USBD_MSC_BOT_HandleTypeDef *)pdev->pClassData; + if (hmsc == NULL) + { + return; + } + hmsc->scsi_sense[hmsc->scsi_sense_tail].Skey = sKey; hmsc->scsi_sense[hmsc->scsi_sense_tail].w.b.ASC = ASC; hmsc->scsi_sense[hmsc->scsi_sense_tail].w.b.ASCQ = 0U; @@ -551,17 +601,22 @@ void SCSI_SenseCode(USBD_HandleTypeDef *pdev, uint8_t lun, uint8_t sKey, uint8_t /** -* @brief SCSI_StartStopUnit -* Process Start Stop Unit command -* @param lun: Logical unit number -* @param params: Command parameters -* @retval status -*/ + * @brief SCSI_StartStopUnit + * Process Start Stop Unit command + * @param lun: Logical unit number + * @param params: Command parameters + * @retval status + */ static int8_t SCSI_StartStopUnit(USBD_HandleTypeDef *pdev, uint8_t lun, uint8_t *params) { UNUSED(lun); USBD_MSC_BOT_HandleTypeDef *hmsc = (USBD_MSC_BOT_HandleTypeDef *)pdev->pClassData; + if (hmsc == NULL) + { + return -1; + } + if ((hmsc->scsi_medium_state == SCSI_MEDIUM_LOCKED) && ((params[4] & 0x3U) == 2U)) { SCSI_SenseCode(pdev, lun, ILLEGAL_REQUEST, INVALID_FIELED_IN_COMMAND); @@ -592,17 +647,22 @@ static int8_t SCSI_StartStopUnit(USBD_HandleTypeDef *pdev, uint8_t lun, uint8_t /** -* @brief SCSI_AllowPreventRemovable -* Process Allow Prevent Removable medium command -* @param lun: Logical unit number -* @param params: Command parameters -* @retval status -*/ + * @brief SCSI_AllowPreventRemovable + * Process Allow Prevent Removable medium command + * @param lun: Logical unit number + * @param params: Command parameters + * @retval status + */ static int8_t SCSI_AllowPreventRemovable(USBD_HandleTypeDef *pdev, uint8_t lun, uint8_t *params) { UNUSED(lun); USBD_MSC_BOT_HandleTypeDef *hmsc = (USBD_MSC_BOT_HandleTypeDef *)pdev->pClassData; + if (hmsc == NULL) + { + return -1; + } + if (params[4] == 0U) { hmsc->scsi_medium_state = SCSI_MEDIUM_UNLOCKED; @@ -619,16 +679,21 @@ static int8_t SCSI_AllowPreventRemovable(USBD_HandleTypeDef *pdev, uint8_t lun, /** -* @brief SCSI_Read10 -* Process Read10 command -* @param lun: Logical unit number -* @param params: Command parameters -* @retval status -*/ + * @brief SCSI_Read10 + * Process Read10 command + * @param lun: Logical unit number + * @param params: Command parameters + * @retval status + */ static int8_t SCSI_Read10(USBD_HandleTypeDef *pdev, uint8_t lun, uint8_t *params) { USBD_MSC_BOT_HandleTypeDef *hmsc = (USBD_MSC_BOT_HandleTypeDef *)pdev->pClassData; + if (hmsc == NULL) + { + return -1; + } + if (hmsc->bot_state == USBD_BOT_IDLE) /* Idle */ { /* case 10 : Ho <> Di */ @@ -680,16 +745,21 @@ static int8_t SCSI_Read10(USBD_HandleTypeDef *pdev, uint8_t lun, uint8_t *params /** -* @brief SCSI_Read12 -* Process Read12 command -* @param lun: Logical unit number -* @param params: Command parameters -* @retval status -*/ + * @brief SCSI_Read12 + * Process Read12 command + * @param lun: Logical unit number + * @param params: Command parameters + * @retval status + */ static int8_t SCSI_Read12(USBD_HandleTypeDef *pdev, uint8_t lun, uint8_t *params) { USBD_MSC_BOT_HandleTypeDef *hmsc = (USBD_MSC_BOT_HandleTypeDef *)pdev->pClassData; + if (hmsc == NULL) + { + return -1; + } + if (hmsc->bot_state == USBD_BOT_IDLE) /* Idle */ { /* case 10 : Ho <> Di */ @@ -743,17 +813,22 @@ static int8_t SCSI_Read12(USBD_HandleTypeDef *pdev, uint8_t lun, uint8_t *params /** -* @brief SCSI_Write10 -* Process Write10 command -* @param lun: Logical unit number -* @param params: Command parameters -* @retval status -*/ + * @brief SCSI_Write10 + * Process Write10 command + * @param lun: Logical unit number + * @param params: Command parameters + * @retval status + */ static int8_t SCSI_Write10(USBD_HandleTypeDef *pdev, uint8_t lun, uint8_t *params) { USBD_MSC_BOT_HandleTypeDef *hmsc = (USBD_MSC_BOT_HandleTypeDef *)pdev->pClassData; uint32_t len; + if (hmsc == NULL) + { + return -1; + } + if (hmsc->bot_state == USBD_BOT_IDLE) /* Idle */ { if (hmsc->cbw.dDataLength == 0U) @@ -823,17 +898,22 @@ static int8_t SCSI_Write10(USBD_HandleTypeDef *pdev, uint8_t lun, uint8_t *param /** -* @brief SCSI_Write12 -* Process Write12 command -* @param lun: Logical unit number -* @param params: Command parameters -* @retval status -*/ + * @brief SCSI_Write12 + * Process Write12 command + * @param lun: Logical unit number + * @param params: Command parameters + * @retval status + */ static int8_t SCSI_Write12(USBD_HandleTypeDef *pdev, uint8_t lun, uint8_t *params) { USBD_MSC_BOT_HandleTypeDef *hmsc = (USBD_MSC_BOT_HandleTypeDef *)pdev->pClassData; uint32_t len; + if (hmsc == NULL) + { + return -1; + } + if (hmsc->bot_state == USBD_BOT_IDLE) /* Idle */ { if (hmsc->cbw.dDataLength == 0U) @@ -907,16 +987,21 @@ static int8_t SCSI_Write12(USBD_HandleTypeDef *pdev, uint8_t lun, uint8_t *param /** -* @brief SCSI_Verify10 -* Process Verify10 command -* @param lun: Logical unit number -* @param params: Command parameters -* @retval status -*/ + * @brief SCSI_Verify10 + * Process Verify10 command + * @param lun: Logical unit number + * @param params: Command parameters + * @retval status + */ static int8_t SCSI_Verify10(USBD_HandleTypeDef *pdev, uint8_t lun, uint8_t *params) { USBD_MSC_BOT_HandleTypeDef *hmsc = (USBD_MSC_BOT_HandleTypeDef *)pdev->pClassData; + if (hmsc == NULL) + { + return -1; + } + if ((params[1] & 0x02U) == 0x02U) { SCSI_SenseCode(pdev, lun, ILLEGAL_REQUEST, INVALID_FIELED_IN_COMMAND); @@ -934,18 +1019,23 @@ static int8_t SCSI_Verify10(USBD_HandleTypeDef *pdev, uint8_t lun, uint8_t *para } /** -* @brief SCSI_CheckAddressRange -* Check address range -* @param lun: Logical unit number -* @param blk_offset: first block address -* @param blk_nbr: number of block to be processed -* @retval status -*/ + * @brief SCSI_CheckAddressRange + * Check address range + * @param lun: Logical unit number + * @param blk_offset: first block address + * @param blk_nbr: number of block to be processed + * @retval status + */ static int8_t SCSI_CheckAddressRange(USBD_HandleTypeDef *pdev, uint8_t lun, uint32_t blk_offset, uint32_t blk_nbr) { USBD_MSC_BOT_HandleTypeDef *hmsc = (USBD_MSC_BOT_HandleTypeDef *)pdev->pClassData; + if (hmsc == NULL) + { + return -1; + } + if ((blk_offset + blk_nbr) > hmsc->scsi_blk_nbr) { SCSI_SenseCode(pdev, lun, ILLEGAL_REQUEST, ADDRESS_OUT_OF_RANGE); @@ -956,16 +1046,21 @@ static int8_t SCSI_CheckAddressRange(USBD_HandleTypeDef *pdev, uint8_t lun, } /** -* @brief SCSI_ProcessRead -* Handle Read Process -* @param lun: Logical unit number -* @retval status -*/ + * @brief SCSI_ProcessRead + * Handle Read Process + * @param lun: Logical unit number + * @retval status + */ static int8_t SCSI_ProcessRead(USBD_HandleTypeDef *pdev, uint8_t lun) { USBD_MSC_BOT_HandleTypeDef *hmsc = (USBD_MSC_BOT_HandleTypeDef *)pdev->pClassData; uint32_t len = hmsc->scsi_blk_len * hmsc->scsi_blk_size; + if (hmsc == NULL) + { + return -1; + } + len = MIN(len, MSC_MEDIA_PACKET); if (((USBD_StorageTypeDef *)pdev->pUserData)->Read(lun, hmsc->bot_data, @@ -993,16 +1088,21 @@ static int8_t SCSI_ProcessRead(USBD_HandleTypeDef *pdev, uint8_t lun) } /** -* @brief SCSI_ProcessWrite -* Handle Write Process -* @param lun: Logical unit number -* @retval status -*/ + * @brief SCSI_ProcessWrite + * Handle Write Process + * @param lun: Logical unit number + * @retval status + */ static int8_t SCSI_ProcessWrite(USBD_HandleTypeDef *pdev, uint8_t lun) { USBD_MSC_BOT_HandleTypeDef *hmsc = (USBD_MSC_BOT_HandleTypeDef *)pdev->pClassData; uint32_t len = hmsc->scsi_blk_len * hmsc->scsi_blk_size; + if (hmsc == NULL) + { + return -1; + } + len = MIN(len, MSC_MEDIA_PACKET); if (((USBD_StorageTypeDef *)pdev->pUserData)->Write(lun, hmsc->bot_data, @@ -1036,18 +1136,23 @@ static int8_t SCSI_ProcessWrite(USBD_HandleTypeDef *pdev, uint8_t lun) /** -* @brief SCSI_UpdateBotData -* fill the requested Data to transmit buffer -* @param hmsc handler -* @param params: Data buffer -* @param length: Data length -* @retval status -*/ + * @brief SCSI_UpdateBotData + * fill the requested Data to transmit buffer + * @param hmsc handler + * @param pBuff: Data buffer + * @param length: Data length + * @retval status + */ static int8_t SCSI_UpdateBotData(USBD_MSC_BOT_HandleTypeDef *hmsc, uint8_t *pBuff, uint16_t length) { uint16_t len = length; + if (hmsc == NULL) + { + return -1; + } + hmsc->bot_data_length = len; while (len != 0U) diff --git a/system/Middlewares/ST/STM32_USB_Device_Library/Class/MSC/Src/usbd_msc_storage_template.c b/system/Middlewares/ST/STM32_USB_Device_Library/Class/MSC/Src/usbd_msc_storage_template.c index dc6cc3dead..875c1f9d63 100644 --- a/system/Middlewares/ST/STM32_USB_Device_Library/Class/MSC/Src/usbd_msc_storage_template.c +++ b/system/Middlewares/ST/STM32_USB_Device_Library/Class/MSC/Src/usbd_msc_storage_template.c @@ -88,24 +88,24 @@ USBD_StorageTypeDef USBD_MSC_Template_fops = }; /******************************************************************************* -* Function Name : Read_Memory -* Description : Handle the Read operation from the microSD card. -* Input : None. -* Output : None. -* Return : None. -*******************************************************************************/ + * Function Name : Read_Memory + * Description : Handle the Read operation from the microSD card. + * Input : None. + * Output : None. + * Return : None. + *******************************************************************************/ int8_t STORAGE_Init(uint8_t lun) { return (0); } /******************************************************************************* -* Function Name : Read_Memory -* Description : Handle the Read operation from the STORAGE card. -* Input : None. -* Output : None. -* Return : None. -*******************************************************************************/ + * Function Name : Read_Memory + * Description : Handle the Read operation from the STORAGE card. + * Input : None. + * Output : None. + * Return : None. + *******************************************************************************/ int8_t STORAGE_GetCapacity(uint8_t lun, uint32_t *block_num, uint16_t *block_size) { *block_num = STORAGE_BLK_NBR; @@ -114,60 +114,60 @@ int8_t STORAGE_GetCapacity(uint8_t lun, uint32_t *block_num, uint16_t *block_siz } /******************************************************************************* -* Function Name : Read_Memory -* Description : Handle the Read operation from the STORAGE card. -* Input : None. -* Output : None. -* Return : None. -*******************************************************************************/ + * Function Name : Read_Memory + * Description : Handle the Read operation from the STORAGE card. + * Input : None. + * Output : None. + * Return : None. + *******************************************************************************/ int8_t STORAGE_IsReady(uint8_t lun) { return (0); } /******************************************************************************* -* Function Name : Read_Memory -* Description : Handle the Read operation from the STORAGE card. -* Input : None. -* Output : None. -* Return : None. -*******************************************************************************/ + * Function Name : Read_Memory + * Description : Handle the Read operation from the STORAGE card. + * Input : None. + * Output : None. + * Return : None. + *******************************************************************************/ int8_t STORAGE_IsWriteProtected(uint8_t lun) { return 0; } /******************************************************************************* -* Function Name : Read_Memory -* Description : Handle the Read operation from the STORAGE card. -* Input : None. -* Output : None. -* Return : None. -*******************************************************************************/ + * Function Name : Read_Memory + * Description : Handle the Read operation from the STORAGE card. + * Input : None. + * Output : None. + * Return : None. + *******************************************************************************/ int8_t STORAGE_Read(uint8_t lun, uint8_t *buf, uint32_t blk_addr, uint16_t blk_len) { return 0; } /******************************************************************************* -* Function Name : Write_Memory -* Description : Handle the Write operation to the STORAGE card. -* Input : None. -* Output : None. -* Return : None. -*******************************************************************************/ + * Function Name : Write_Memory + * Description : Handle the Write operation to the STORAGE card. + * Input : None. + * Output : None. + * Return : None. + *******************************************************************************/ int8_t STORAGE_Write(uint8_t lun, uint8_t *buf, uint32_t blk_addr, uint16_t blk_len) { return (0); } /******************************************************************************* -* Function Name : Write_Memory -* Description : Handle the Write operation to the STORAGE card. -* Input : None. -* Output : None. -* Return : None. -*******************************************************************************/ + * Function Name : Write_Memory + * Description : Handle the Write operation to the STORAGE card. + * Input : None. + * Output : None. + * Return : None. + *******************************************************************************/ int8_t STORAGE_GetMaxLun(void) { return (STORAGE_LUN_NBR - 1); diff --git a/system/Middlewares/ST/STM32_USB_Device_Library/Class/Printer/Inc/usbd_printer.h b/system/Middlewares/ST/STM32_USB_Device_Library/Class/Printer/Inc/usbd_printer.h new file mode 100644 index 0000000000..ec73edcaef --- /dev/null +++ b/system/Middlewares/ST/STM32_USB_Device_Library/Class/Printer/Inc/usbd_printer.h @@ -0,0 +1,164 @@ +/** + ****************************************************************************** + * @file usbd_printer.h + * @author MCD Application Team + * @brief header file for the usbd_printer.c file. + ****************************************************************************** + * @attention + * + *

© Copyright (c) 2021 STMicroelectronics. + * All rights reserved.

+ * + * This software component is licensed by ST under Ultimate Liberty license + * SLA0044, the "License"; You may not use this file except in compliance with + * the License. You may obtain a copy of the License at: + * www.st.com/SLA0044 + * + ****************************************************************************** + */ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef __USB_PRNT_H +#define __USB_PRNT_H + +#ifdef __cplusplus +extern "C" { +#endif + +/* Includes ------------------------------------------------------------------*/ +#include "usbd_ioreq.h" + +/** @addtogroup STM32_USB_DEVICE_LIBRARY + * @{ + */ + +/** @defgroup usbd_PRNT + * @brief This file is the Header file for usbd_PRNT.c + * @{ + */ + + +/** @defgroup usbd_PRNT_Exported_Defines + * @{ + */ +#ifndef PRNT_IN_EP +#define PRNT_IN_EP 0x81U /* Default: EP1 for data IN */ +#endif /* PRNT_IN_EP */ + +#ifndef PRNT_OUT_EP +#define PRNT_OUT_EP 0x01U /* Default: EP1 for data OUT */ +#endif /* PRNT_OUT_EP */ + +#ifndef PRNT_DATA_HS_MAX_PACKET_SIZE +#define PRNT_DATA_HS_MAX_PACKET_SIZE 512U /* Endpoint IN & OUT Packet size */ +#endif /* PRNT_DATA_HS_MAX_PACKET_SIZE */ + +#ifndef PRNT_DATA_FS_MAX_PACKET_SIZE +#define PRNT_DATA_FS_MAX_PACKET_SIZE 64U /* Endpoint IN & OUT Packet size */ +#endif /* PRNT_DATA_FS_MAX_PACKET_SIZE */ + +#define USB_PRNT_CONFIG_DESC_SIZ 32U +#define PRNT_DATA_HS_IN_PACKET_SIZE PRNT_DATA_HS_MAX_PACKET_SIZE +#define PRNT_DATA_HS_OUT_PACKET_SIZE PRNT_DATA_HS_MAX_PACKET_SIZE + +#define PRNT_DATA_FS_IN_PACKET_SIZE PRNT_DATA_FS_MAX_PACKET_SIZE +#define PRNT_DATA_FS_OUT_PACKET_SIZE PRNT_DATA_FS_MAX_PACKET_SIZE + +/*---------------------------------------------------------------------*/ +/* PRNT definitions */ +/*---------------------------------------------------------------------*/ +#define PRNT_STATUS_PAPER_EMPTY 0x10U +#define PRNT_STATUS_SELECTED 0x08U +#define PRNT_STATUS_NO_ERROR 0x00U + +#define USB_PRNT_SUBCLASS 0x01U + +#define USB_PRNT_UNIDIRECTIONAL 0x01U +#define USB_PRNT_BIDIRECTIONAL 0x02U + +/* USB PRNT Request types */ +#define PRNT_GET_DEVICE_ID 0x00U +#define PRNT_GET_PORT_STATUS 0x01U +#define PRNT_SOFT_RESET 0x02U +/** + * @} + */ + + +/** @defgroup USBD_CORE_Exported_TypesDefinitions + * @{ + */ + +/** + * @} + */ + +typedef struct _USBD_PRNT_Itf +{ + int8_t (* Init)(void); + int8_t (* DeInit)(void); + int8_t (* Control_req)(uint8_t req, uint8_t *pbuf, uint16_t *length); + int8_t (* Receive)(uint8_t *Buf, uint32_t *Len); + +} USBD_PRNT_ItfTypeDef; + +typedef struct +{ + uint32_t data[PRNT_DATA_HS_MAX_PACKET_SIZE / 4U]; /* Force 32-bit alignment */ + 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_PRNT_HandleTypeDef; + + + +/** @defgroup USBD_CORE_Exported_Macros + * @{ + */ + +/** + * @} + */ + +/** @defgroup USBD_CORE_Exported_Variables + * @{ + */ + +extern USBD_ClassTypeDef USBD_PRNT; +#define USBD_PRNT_CLASS &USBD_PRNT +/** + * @} + */ + +/** @defgroup USB_CORE_Exported_Functions + * @{ + */ +uint8_t USBD_PRNT_RegisterInterface(USBD_HandleTypeDef *pdev, USBD_PRNT_ItfTypeDef *fops); +uint8_t USBD_PRNT_SetRxBuffer(USBD_HandleTypeDef *pdev, uint8_t *pbuff); +uint8_t USBD_PRNT_ReceivePacket(USBD_HandleTypeDef *pdev); + +/** + * @} + */ + +#ifdef __cplusplus +} +#endif + +#endif /* __USB_PRNT_H */ +/** + * @} + */ + +/** + * @} + */ + +/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ diff --git a/system/Middlewares/ST/STM32_USB_Device_Library/Class/Printer/Inc/usbd_printer_if_template.h b/system/Middlewares/ST/STM32_USB_Device_Library/Class/Printer/Inc/usbd_printer_if_template.h new file mode 100644 index 0000000000..7037afad58 --- /dev/null +++ b/system/Middlewares/ST/STM32_USB_Device_Library/Class/Printer/Inc/usbd_printer_if_template.h @@ -0,0 +1,45 @@ +/** + ****************************************************************************** + * @file usbd_printer_if_template.h + * @author MCD Application Team + * @brief Header for usbd_PRNT_if_template.c file. + ****************************************************************************** + * @attention + * + *

© Copyright (c) 2021 STMicroelectronics. + * All rights reserved.

+ * + * This software component is licensed by ST under Ultimate Liberty license + * SLA0044, the "License"; You may not use this file except in compliance with + * the License. You may obtain a copy of the License at: + * http://www.st.com/SLA0044 + * + ****************************************************************************** + */ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef __USBD_PRNT_IF_TEMPLATE_H +#define __USBD_PRNT_IF_TEMPLATE_H + +#ifdef __cplusplus +extern "C" { +#endif + +/* Includes ------------------------------------------------------------------*/ +#include "usbd_printer.h" + +/* Exported types ------------------------------------------------------------*/ +/* Exported constants --------------------------------------------------------*/ + +extern USBD_PRNT_ItfTypeDef USBD_PRNT_Template_fops; + +/* Exported macro ------------------------------------------------------------*/ +/* Exported functions ------------------------------------------------------- */ + +#ifdef __cplusplus +} +#endif + +#endif /* __USBD_PRNT_IF_TEMPLATE_H */ + +/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ diff --git a/system/Middlewares/ST/STM32_USB_Device_Library/Class/Printer/Src/usbd_printer.c b/system/Middlewares/ST/STM32_USB_Device_Library/Class/Printer/Src/usbd_printer.c new file mode 100644 index 0000000000..246674f7f9 --- /dev/null +++ b/system/Middlewares/ST/STM32_USB_Device_Library/Class/Printer/Src/usbd_printer.c @@ -0,0 +1,673 @@ +/** + ****************************************************************************** + * @file usbd_printer.c + * @author MCD Application Team + * @brief This file provides the high layer firmware functions to manage the + * following functionalities of the USB printer Class: + * - Initialization and Configuration of high and low layer + * - Enumeration as printer Device (and enumeration for each implemented memory interface) + * - OUT data transfer + * - Command OUT transfer (class requests management) + * - Error management + * + * @verbatim + * + * =================================================================== + * PRINTER Class Driver Description + * =================================================================== + * This driver manages the "Universal Serial Bus Class Definitions for Communications Devices + * Revision 1.2 November 16, 2007" and the sub-protocol specification of "Universal Serial Bus + * printer Class Subclass Specification for PSTN Devices Revision 1.2 February 9, 2007" + * This driver implements the following aspects of the specification: + * - Device descriptor management + * - Configuration descriptor management + * - Enumeration as printer device with 2 data endpoints (IN and OUT) + * - Control Requests management (PRNT_GET_DEVICE_ID,PRNT_GET_PORT_STATUS,PRNT_SOFT_RESET) + * - protocol USB_PRNT_BIDIRECTIONAL + * + * + * + * These aspects may be enriched or modified for a specific user application. + * + * This driver doesn't implement the following aspects of the specification + * (but it is possible to manage these features with some modifications on this driver): + * - Any class-specific aspect relative to communication classes should be managed by user application. + * - All communication classes other than PSTN are not managed + * + * @endverbatim + * + ****************************************************************************** + * @attention + * + *

© Copyright (c) 2021 STMicroelectronics. + * All rights reserved.

+ * + * This software component is licensed by ST under Ultimate Liberty license + * SLA0044, the "License"; You may not use this file except in compliance with + * the License. You may obtain a copy of the License at: + * www.st.com/SLA0044 + * + ****************************************************************************** + */ + +/* BSPDependencies +- "stm32xxxxx_{eval}{discovery}{nucleo_144}.c" +- "stm32xxxxx_{eval}{discovery}_io.c" +EndBSPDependencies */ + +/* Includes ------------------------------------------------------------------*/ +#include "usbd_printer.h" +#include "usbd_ctlreq.h" + + +/** @addtogroup STM32_USB_DEVICE_LIBRARY + * @{ + */ + + +/** @defgroup USBD_PRNT + * @brief usbd core module + * @{ + */ + +/** @defgroup USBD_PRNT_Private_TypesDefinitions + * @{ + */ +/** + * @} + */ +static uint32_t usbd_PRNT_altset = 0U; + +/** @defgroup USBD_PRNT_Private_Defines + * @{ + */ +/** + * @} + */ + +/** @defgroup USBD_PRNT_Private_Macros + * @{ + */ +/** + * @} + */ + + +/** @defgroup USBD_PRNT_Private_FunctionPrototypes + * @{ + */ +static uint8_t USBD_PRNT_Init(USBD_HandleTypeDef *pdev, uint8_t cfgidx); +static uint8_t USBD_PRNT_DeInit(USBD_HandleTypeDef *pdev, uint8_t cfgidx); +static uint8_t USBD_PRNT_Setup(USBD_HandleTypeDef *pdev, USBD_SetupReqTypedef *req); +static uint8_t USBD_PRNT_DataIn(USBD_HandleTypeDef *pdev, uint8_t epnum); +static uint8_t USBD_PRNT_DataOut(USBD_HandleTypeDef *pdev, uint8_t epnum); + +static uint8_t *USBD_PRNT_GetFSCfgDesc(uint16_t *length); +static uint8_t *USBD_PRNT_GetHSCfgDesc(uint16_t *length); +static uint8_t *USBD_PRNT_GetOtherSpeedCfgDesc(uint16_t *length); +static uint8_t *USBD_PRNT_GetOtherSpeedCfgDesc(uint16_t *length); +uint8_t *USBD_PRNT_GetDeviceQualifierDescriptor(uint16_t *length); + +/* USB Standard Device Descriptor */ +__ALIGN_BEGIN static uint8_t USBD_PRNT_DeviceQualifierDesc[USB_LEN_DEV_QUALIFIER_DESC] __ALIGN_END = +{ + USB_LEN_DEV_QUALIFIER_DESC, + USB_DESC_TYPE_DEVICE_QUALIFIER, + 0x00, + 0x02, + 0x00, + 0x00, + 0x00, + 0x40, + 0x01, + 0x00, +}; + +/** + * @} + */ + +/** @defgroup USBD_PRNT_Private_Variables + * @{ + */ + +/* PRNT interface class callbacks structure */ +USBD_ClassTypeDef USBD_PRNT = +{ + USBD_PRNT_Init, + USBD_PRNT_DeInit, + USBD_PRNT_Setup, + NULL, + NULL, + USBD_PRNT_DataIn, + USBD_PRNT_DataOut, + NULL, + NULL, + NULL, + USBD_PRNT_GetHSCfgDesc, + USBD_PRNT_GetFSCfgDesc, + USBD_PRNT_GetOtherSpeedCfgDesc, + USBD_PRNT_GetDeviceQualifierDescriptor, +}; + +/* USB PRNT device Configuration Descriptor */ +__ALIGN_BEGIN static uint8_t USBD_PRNT_CfgHSDesc[] __ALIGN_END = +{ + /*Configuration Descriptor*/ + 0x09, /* bLength: Configuration Descriptor size */ + USB_DESC_TYPE_CONFIGURATION, /* bDescriptorType: Configuration */ + USB_PRNT_CONFIG_DESC_SIZ, /* wTotalLength:no of returned bytes */ + 0x00, + 0x01, /* bNumInterfaces: 1 interface */ + 0x01, /* bConfigurationValue: Configuration value */ + 0x00, /* iConfiguration: Index of string descriptor describing the configuration */ +#if (USBD_SELF_POWERED == 1U) + 0xC0, /* bmAttributes: Self Powered according to user configuration */ +#else + 0x80, /* bmAttributes: Bus Powered according to user configuration */ +#endif + USBD_MAX_POWER, /* MaxPower in mA */ + + /* Interface Descriptor */ + 0x09, /* bLength: Interface Descriptor size */ + USB_DESC_TYPE_INTERFACE, /* bDescriptorType: Interface */ + 0x00, /* bInterfaceNumber: Number of Interface */ + 0x00, /* bAlternateSetting: Alternate setting */ + 0x02, /* bNumEndpoints: 2 endpoints used */ + 0x07, /* bInterfaceClass: Communication Interface Class */ + 0x01, /* bInterfaceSubClass: Abstract Control Model */ + USB_PRNT_BIDIRECTIONAL, /* bDeviceProtocol */ + 0x00, /* iInterface */ + + /* Endpoint IN Descriptor */ + 0x07, /* bLength: Endpoint Descriptor size */ + USB_DESC_TYPE_ENDPOINT, /* bDescriptorType: Endpoint */ + PRNT_IN_EP, /* bEndpointAddress */ + 0x02, /* bmAttributes: Bulk */ + LOBYTE(PRNT_DATA_HS_IN_PACKET_SIZE), /* wMaxPacketSize */ + HIBYTE(PRNT_DATA_HS_IN_PACKET_SIZE), + 0x00, /* bInterval */ + + /* Endpoint OUT Descriptor */ + 0x07, /* bLength: Endpoint Descriptor size */ + USB_DESC_TYPE_ENDPOINT, /* bDescriptorType: Endpoint */ + PRNT_OUT_EP, /* bEndpointAddress */ + 0x02, /* bmAttributes: Bulk */ + LOBYTE(PRNT_DATA_HS_OUT_PACKET_SIZE),/* wMaxPacketSize */ + HIBYTE(PRNT_DATA_HS_OUT_PACKET_SIZE), + 0x00 /* bInterval */ +}; + + +/* USB PRNT device Configuration Descriptor */ +__ALIGN_BEGIN static uint8_t USBD_PRNT_CfgFSDesc[] __ALIGN_END = +{ + /*Configuration Descriptor*/ + 0x09, /* bLength: Configuration Descriptor size */ + USB_DESC_TYPE_CONFIGURATION, /* bDescriptorType: Configuration */ + USB_PRNT_CONFIG_DESC_SIZ, /* wTotalLength:no of returned bytes */ + 0x00, + 0x01, /* bNumInterfaces: 1 interface */ + 0x01, /* bConfigurationValue: Configuration value */ + 0x00, /* iConfiguration: Index of string descriptor describing the configuration */ +#if (USBD_SELF_POWERED == 1U) + 0xC0, /* bmAttributes: Self Powered according to user configuration */ +#else + 0x80, /* bmAttributes: Bus Powered according to user configuration */ +#endif + USBD_MAX_POWER, /* MaxPower in mA */ + + /*Interface Descriptor */ + 0x09, /* bLength: Interface Descriptor size */ + USB_DESC_TYPE_INTERFACE, /* bDescriptorType: Interface */ + 0x00, /* bInterfaceNumber: Number of Interface */ + 0x00, /* bAlternateSetting: Alternate setting */ + 0x02, /* bNumEndpoints: 2 endpoints used */ + 0x07, /* bInterfaceClass: Communication Interface Class */ + 0x01, /* bInterfaceSubClass: Abstract Control Model */ + USB_PRNT_BIDIRECTIONAL, /* bDeviceProtocol */ + 0x00, /* iInterface */ + + /*Endpoint IN Descriptor*/ + 0x07, /* bLength: Endpoint Descriptor size */ + USB_DESC_TYPE_ENDPOINT, /* bDescriptorType: Endpoint */ + PRNT_IN_EP, /* bEndpointAddress */ + 0x02, /* bmAttributes: Bulk */ + LOBYTE(PRNT_DATA_FS_IN_PACKET_SIZE), /* wMaxPacketSize */ + HIBYTE(PRNT_DATA_FS_IN_PACKET_SIZE), + 0x00, /* bInterval */ + + /*Endpoint OUT Descriptor*/ + 0x07, /* bLength: Endpoint Descriptor size */ + USB_DESC_TYPE_ENDPOINT, /* bDescriptorType: Endpoint */ + PRNT_OUT_EP, /* bEndpointAddress */ + 0x02, /* bmAttributes: Bulk */ + LOBYTE(PRNT_DATA_FS_OUT_PACKET_SIZE),/* wMaxPacketSize */ + HIBYTE(PRNT_DATA_FS_OUT_PACKET_SIZE), + 0x00 /* bInterval */ +}; + +__ALIGN_BEGIN static uint8_t USBD_PRNT_OtherSpeedCfgDesc[] __ALIGN_END = +{ + /*Configuration Descriptor*/ + 0x09, /* bLength: Configuration Descriptor size */ + USB_DESC_TYPE_CONFIGURATION, /* bDescriptorType: Configuration */ + USB_PRNT_CONFIG_DESC_SIZ, /* wTotalLength:no of returned bytes */ + 0x00, + 0x01, /* bNumInterfaces: 1 interface */ + 0x01, /* bConfigurationValue: Configuration value */ + 0x00, /* iConfiguration: Index of string descriptor describing the configuration */ +#if (USBD_SELF_POWERED == 1U) + 0xC0, /* bmAttributes: Self Powered according to user configuration */ +#else + 0x80, /* bmAttributes: Bus Powered according to user configuration */ +#endif + USBD_MAX_POWER, /* MaxPower in mA */ + + /*Interface Descriptor */ + 0x09, /* bLength: Interface Descriptor size */ + USB_DESC_TYPE_INTERFACE, /* bDescriptorType: Interface */ + 0x00, /* bInterfaceNumber: Number of Interface */ + 0x00, /* bAlternateSetting: Alternate setting */ + 0x02, /* bNumEndpoints: 2 endpoints used */ + 0x07, /* bInterfaceClass: Communication Interface Class */ + 0x01, /* bInterfaceSubClass: Abstract Control Model */ + USB_PRNT_BIDIRECTIONAL, /* bDeviceProtocol */ + 0x00, /* iInterface */ + + /*Endpoint IN Descriptor*/ + 0x07, /* bLength: Endpoint Descriptor size */ + USB_DESC_TYPE_ENDPOINT, /* bDescriptorType: Endpoint */ + PRNT_IN_EP, /* bEndpointAddress */ + 0x02, /* bmAttributes: Bulk */ + LOBYTE(PRNT_DATA_FS_IN_PACKET_SIZE), /* wMaxPacketSize */ + HIBYTE(PRNT_DATA_FS_IN_PACKET_SIZE), + 0x00, /* bInterval */ + + /*Endpoint OUT Descriptor*/ + 0x07, /* bLength: Endpoint Descriptor size */ + USB_DESC_TYPE_ENDPOINT, /* bDescriptorType: Endpoint */ + PRNT_OUT_EP, /* bEndpointAddress */ + 0x02, /* bmAttributes: Bulk */ + LOBYTE(PRNT_DATA_FS_OUT_PACKET_SIZE),/* wMaxPacketSize */ + HIBYTE(PRNT_DATA_FS_OUT_PACKET_SIZE), + 0x00 /* bInterval */ +}; + +/** + * @} + */ + +/** @defgroup USBD_PRNT_Private_Functions + * @{ + */ + +/** + * @brief USBD_PRNT_Init + * Initialize the PRNT interface + * @param pdev: device instance + * @param cfgidx: Configuration index + * @retval status + */ +static uint8_t USBD_PRNT_Init(USBD_HandleTypeDef *pdev, uint8_t cfgidx) +{ + UNUSED(cfgidx); + + USBD_PRNT_HandleTypeDef *hPRNT; + uint16_t mps; + hPRNT = (USBD_PRNT_HandleTypeDef *)USBD_malloc(sizeof(USBD_PRNT_HandleTypeDef)); + + if (hPRNT == NULL) + { + pdev->pClassData = NULL; + return (uint8_t)USBD_EMEM; + } + + /* Setup the pClassData pointer */ + pdev->pClassData = (void *)hPRNT; + + /* Setup the max packet size according to selected speed */ + if (pdev->dev_speed == USBD_SPEED_HIGH) + { + mps = PRNT_DATA_HS_IN_PACKET_SIZE; + } + else + { + mps = PRNT_DATA_FS_IN_PACKET_SIZE; + } + + /* Open EP IN */ + (void)USBD_LL_OpenEP(pdev, PRNT_IN_EP, USBD_EP_TYPE_BULK, mps); + + /* Set endpoint as used */ + pdev->ep_in[PRNT_IN_EP & 0xFU].is_used = 1U; + + /* Open EP OUT */ + (void)USBD_LL_OpenEP(pdev, PRNT_OUT_EP, USBD_EP_TYPE_BULK, mps); + + /* Set endpoint as used */ + pdev->ep_out[PRNT_OUT_EP & 0xFU].is_used = 1U; + + /* Init physical Interface components */ + ((USBD_PRNT_ItfTypeDef *)pdev->pUserData)->Init(); + + /* Prepare Out endpoint to receive next packet */ + (void)USBD_LL_PrepareReceive(pdev, PRNT_OUT_EP, hPRNT->RxBuffer, mps); + + /* End of initialization phase */ + return (uint8_t)USBD_OK; +} + +/** + * @brief USBD_PRNT_DeInit + * DeInitialize the PRNT layer + * @param pdev: device instance + * @param cfgidx: Configuration index + * @retval status + */ +static uint8_t USBD_PRNT_DeInit(USBD_HandleTypeDef *pdev, uint8_t cfgidx) +{ + UNUSED(cfgidx); + + /* Close EP IN */ + (void)USBD_LL_CloseEP(pdev, PRNT_IN_EP); + pdev->ep_in[PRNT_IN_EP & 0xFU].is_used = 0U; + + /* Close EP OUT */ + (void)USBD_LL_CloseEP(pdev, PRNT_OUT_EP); + pdev->ep_out[PRNT_OUT_EP & 0xFU].is_used = 0U; + + /* DeInit physical Interface components */ + if (pdev->pClassData != NULL) + { + ((USBD_PRNT_ItfTypeDef *)pdev->pUserData)->DeInit(); + (void)USBD_free(pdev->pClassData); + pdev->pClassData = NULL; + } + + return 0U; +} + +/** + * @brief USBD_PRNT_Setup + * Handle the PRNT specific requests + * @param pdev: instance + * @param req: usb requests + * @retval status + */ +static uint8_t USBD_PRNT_Setup(USBD_HandleTypeDef *pdev, USBD_SetupReqTypedef *req) +{ + USBD_PRNT_HandleTypeDef *hPRNT = (USBD_PRNT_HandleTypeDef *)pdev->pClassData; + USBD_PRNT_ItfTypeDef *hPRNTitf = (USBD_PRNT_ItfTypeDef *)pdev->pUserData; + + USBD_StatusTypeDef ret = USBD_OK; + uint16_t status_info = 0U; + uint16_t data_length; + + switch (req->bmRequest & USB_REQ_TYPE_MASK) + { + case USB_REQ_TYPE_CLASS : + if (req->wLength != 0U) + { + data_length = MIN(req->wLength, PRNT_DATA_HS_MAX_PACKET_SIZE); + + if ((req->bmRequest & 0x80U) != 0U) + { + /* Call the User class interface function to process the command */ + hPRNTitf->Control_req(req->bRequest, (uint8_t *)hPRNT->data, &data_length); + + /* Return the answer to host */ + (void) USBD_CtlSendData(pdev, (uint8_t *)hPRNT->data, data_length); + } + else + { + /* Prepare for control data reception */ + (void) USBD_CtlPrepareRx(pdev, (uint8_t *)hPRNT->data, data_length); + } + } + else + { + data_length = 0U; + hPRNTitf->Control_req(req->bRequest, (uint8_t *)req, &data_length); + } + break; + + case USB_REQ_TYPE_STANDARD: + switch (req->bRequest) + { + case USB_REQ_GET_STATUS: + if (pdev->dev_state == USBD_STATE_CONFIGURED) + { + (void)USBD_CtlSendData(pdev, (uint8_t *)&status_info, 2U); + } + else + { + USBD_CtlError(pdev, req); + ret = USBD_FAIL; + } + break; + + case USB_REQ_GET_INTERFACE: + if (pdev->dev_state == USBD_STATE_CONFIGURED) + { + (void)USBD_CtlSendData(pdev, (uint8_t *)&usbd_PRNT_altset, 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_CLEAR_FEATURE: + break; + + default: + USBD_CtlError(pdev, req); + ret = USBD_FAIL; + break; + } + break; + + default: + USBD_CtlError(pdev, req); + ret = USBD_FAIL; + break; + } + + return (uint8_t)ret; +} + +/** + * @brief USBD_PRNT_DataIn + * Data sent on non-control IN endpoint + * @param pdev: device instance + * @param epnum: endpoint number + * @retval status + */ +static uint8_t USBD_PRNT_DataIn(USBD_HandleTypeDef *pdev, uint8_t epnum) +{ + USBD_PRNT_HandleTypeDef *hPRNT = (USBD_PRNT_HandleTypeDef *)pdev->pClassData; + PCD_HandleTypeDef *hpcd = pdev->pData; + + if (hPRNT == NULL) + { + return (uint8_t)USBD_FAIL; + } + + 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 */ + (void) USBD_LL_Transmit(pdev, epnum, NULL, 0U); + } + else + { + hPRNT->TxState = 0U; + } + + return (uint8_t)USBD_OK; +} +/** + * @brief USBD_PRNT_DataOut + * Data received on non-control Out endpoint + * @param pdev: device instance + * @param epnum: endpoint number + * @retval status + */ +static uint8_t USBD_PRNT_DataOut(USBD_HandleTypeDef *pdev, uint8_t epnum) +{ + USBD_PRNT_HandleTypeDef *hPRNT = (USBD_PRNT_HandleTypeDef *)pdev->pClassData; + + if (hPRNT == NULL) + { + return (uint8_t)USBD_FAIL; + } + + /* Get the received data length */ + hPRNT->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 */ + ((USBD_PRNT_ItfTypeDef *)pdev->pUserData)->Receive(hPRNT->RxBuffer, &hPRNT->RxLength); + + return (uint8_t)USBD_OK; +} + +/** + * @brief USBD_PRNT_GetFSCfgDesc + * Return configuration descriptor + * @param length : pointer data length + * @retval pointer to descriptor buffer + */ +static uint8_t *USBD_PRNT_GetFSCfgDesc(uint16_t *length) +{ + *length = (uint16_t) sizeof(USBD_PRNT_CfgFSDesc); + return USBD_PRNT_CfgFSDesc; +} + +/** + * @brief USBD_PRNT_GetHSCfgDesc + * Return configuration descriptor + * @param length : pointer data length + * @retval pointer to descriptor buffer + */ +static uint8_t *USBD_PRNT_GetHSCfgDesc(uint16_t *length) +{ + *length = (uint16_t) sizeof(USBD_PRNT_CfgHSDesc); + return USBD_PRNT_CfgHSDesc; +} + +/** + * @brief USBD_PRNT_GetOtherSpeedCfgDesc + * Return configuration descriptor + * @param length : pointer data length + * @retval pointer to descriptor buffer + */ +static uint8_t *USBD_PRNT_GetOtherSpeedCfgDesc(uint16_t *length) +{ + *length = (uint16_t) sizeof(USBD_PRNT_OtherSpeedCfgDesc); + return USBD_PRNT_OtherSpeedCfgDesc; +} + +/** + * @brief USBD_PRNT_GetDeviceQualifierDescriptor + * return Device Qualifier descriptor + * @param length : pointer data length + * @retval pointer to descriptor buffer + */ +uint8_t *USBD_PRNT_GetDeviceQualifierDescriptor(uint16_t *length) +{ + *length = (uint16_t)sizeof(USBD_PRNT_DeviceQualifierDesc); + return USBD_PRNT_DeviceQualifierDesc; +} + +/** + * @brief USBD_PRNT_RegisterInterface + * @param pdev: device instance + * @param fops: Interface callbacks + * @retval status + */ +uint8_t USBD_PRNT_RegisterInterface(USBD_HandleTypeDef *pdev, USBD_PRNT_ItfTypeDef *fops) +{ + /* Check if the fops pointer is valid */ + if (fops == NULL) + { + return (uint8_t)USBD_FAIL; + } + + /* Setup the fops pointer */ + pdev->pUserData = fops; + + return (uint8_t)USBD_OK; +} + +/** + * @brief USBD_PRNT_SetRxBuffer + * @param pdev: device instance + * @param pbuff: Rx Buffer + * @retval status + */ +uint8_t USBD_PRNT_SetRxBuffer(USBD_HandleTypeDef *pdev, uint8_t *pbuff) +{ + USBD_PRNT_HandleTypeDef *hPRNT = (USBD_PRNT_HandleTypeDef *) pdev->pClassData; + + hPRNT->RxBuffer = pbuff; + + return (uint8_t)USBD_OK; +} + +/** + * @brief USBD_PRNT_ReceivePacket + * prepare OUT Endpoint for reception + * @param pdev: device instance + * @retval status + */ +uint8_t USBD_PRNT_ReceivePacket(USBD_HandleTypeDef *pdev) +{ + USBD_PRNT_HandleTypeDef *hPRNT = (USBD_PRNT_HandleTypeDef *)pdev->pClassData; + + if (hPRNT == NULL) + { + return (uint8_t)USBD_FAIL; + } + + if (pdev->dev_speed == USBD_SPEED_HIGH) + { + /* Prepare Out endpoint to receive next packet */ + (void)USBD_LL_PrepareReceive(pdev, PRNT_OUT_EP, hPRNT->RxBuffer, + PRNT_DATA_HS_OUT_PACKET_SIZE); + } + else + { + /* Prepare Out endpoint to receive next packet */ + (void)USBD_LL_PrepareReceive(pdev, PRNT_OUT_EP, hPRNT->RxBuffer, + PRNT_DATA_FS_OUT_PACKET_SIZE); + } + + return (uint8_t)USBD_OK; +} +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ diff --git a/system/Middlewares/ST/STM32_USB_Device_Library/Class/Printer/Src/usbd_printer_if_template.c b/system/Middlewares/ST/STM32_USB_Device_Library/Class/Printer/Src/usbd_printer_if_template.c new file mode 100644 index 0000000000..064c41e81f --- /dev/null +++ b/system/Middlewares/ST/STM32_USB_Device_Library/Class/Printer/Src/usbd_printer_if_template.c @@ -0,0 +1,218 @@ +/** + ****************************************************************************** + * @file usbd_printer_if_template.c + * @author MCD Application Team + * @brief Generic media access Layer. + ****************************************************************************** + * @attention + * + *

© Copyright (c) 2021 STMicroelectronics. + * All rights reserved.

+ * + * This software component is licensed by ST under Ultimate Liberty license + * SLA0044, the "License"; You may not use this file except in compliance with + * the License. You may obtain a copy of the License at: + * http://www.st.com/SLA0044 + * + ****************************************************************************** + */ + +/* Includes ------------------------------------------------------------------*/ +#include "usbd_printer_if_template.h" + +/** @addtogroup STM32_USB_DEVICE_LIBRARY + * @{ + */ + + +/** @defgroup USBD_PRNT + * @brief usbd core module + * @{ + */ + +/** @defgroup USBD_PRNT_Private_TypesDefinitions + * @{ + */ +/** + * @} + */ + + +/** @defgroup USBD_PRNT_Private_Defines + * @{ + */ +/** + * @} + */ + + +/** @defgroup USBD_PRNT_Private_Macros + * @{ + */ + +/** + * @} + */ + + +/** @defgroup USBD_PRNT_Private_FunctionPrototypes + * @{ + */ + +static int8_t TEMPLATE_Init(void); +static int8_t TEMPLATE_DeInit(void); +static int8_t TEMPLATE_Control_req(uint8_t req, uint8_t *pbuf, uint16_t *length); +static int8_t TEMPLATE_Receive(uint8_t *pbuf, uint32_t *Len); + +/*printer Private function prototypes*/ +void TEMPLATE_PRNT_PageEndManager(uint8_t *Buf, uint32_t Len); + +USBD_PRNT_ItfTypeDef USBD_PRNT_Template_fops = +{ + TEMPLATE_Init, + TEMPLATE_DeInit, + TEMPLATE_Control_req + TEMPLATE_Receive +}; + +static uint8_t PRNT_DEVICE_ID[DEVICE_ID_LEN] = +{ + 0x00, 0x6D, + 'M', 'A', 'N', 'U', 'F', 'A', 'C', 'T', 'U', 'R', 'E', 'R', ':', + 'S', 'T', 'M', 'i', 'c', 'r', 'o', 'e', 'l', 'e', 'c', 't', 'r', 'o', 'n', 'i', 'c', 's', ';', + 'C', 'O', 'M', 'M', 'A', 'N', 'D', ' ', 'S', 'E', 'T', ':', + 'P', 'D', 'L', ',', 'P', 'C', 'P', ';', + 'M', 'O', 'D', 'E', 'L', ':', + 'U', 'S', 'B', 'P', 'r', 'i', 'n', 't', 'e', 'r', ';', + 'C', 'O', 'M', 'M', 'E', 'N', 'T', ':', + 'G', 'o', 'o', 'd', ' ', '!', ';', + 'A', 'C', 'T', 'I', 'V', 'E', ' ', 'C', 'O', 'M', 'M', 'A', 'N', 'D', ' ', 'S', 'E', 'T', ':', + 'P', 'C', 'P', ';' +}; + +/* Private functions ---------------------------------------------------------*/ + +/** + * @brief TEMPLATE_Init + * Initializes the PRNT media low layer + * @param None + * @retval Result of the operation: USBD_OK if all operations are OK else USBD_FAIL + */ +static int8_t TEMPLATE_Init(void) +{ + /* + Add your initialization code here + */ + return (0); +} + +/** + * @brief TEMPLATE_DeInit + * DeInitializes the PRNT media low layer + * @param None + * @retval Result of the operation: USBD_OK if all operations are OK else USBD_FAIL + */ +static int8_t TEMPLATE_DeInit(void) +{ + /* + Add your deinitialization code here + */ + return (0); +} + + +/** + * @brief TEMPLATE_Receive + * Data received over USB OUT endpoint are sent over PRNT interface + * through this function. + * + * @note + * This function will issue a NAK packet on any OUT packet received on + * USB endpoint untill exiting this function. If you exit this function + * before transfer is complete on PRNT 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 TEMPLATE_Receive(uint8_t *Buf, uint32_t *Len) +{ + UNUSED(Buf); + UNUSED(Len); + + return (0); +} + + +/** + * @brief TEMPLATE_PRNT_Itf_Control_req + * Manage the PRNT class requests + * @param req: Command code + * @param pbuf: Buffer containing command data (request parameters) + * @param length: Number of data to be sent (in bytes) + * @retval Result of the operation: USBD_OK if all operations are OK else USBD_FAIL + */ +static int8_t TEMPLATE_PRNT_Itf_Control_req(uint8_t req, uint8_t *pbuf, uint16_t *length) +{ + uint32_t i = 0; + + /* Check on the setup request value */ + switch (req) + { + /* Get Printer Device ID request */ + case PRNT_GET_DEVICE_ID: + /* Not using for loop here due to MISRA-C2012-Rule-16.1 */ + while (i < sizeof(PRNT_DEVICE_ID)) + { + pbuf[i] = PRNT_DEVICE_ID[i]; + i++; + } + *length = i; + break; + + /* Get Printer current status */ + case PRNT_GET_PORT_STATUS: + pbuf[0] = PRNT_STATUS_PAPER_EMPTY | + PRNT_STATUS_SELECTED | + PRNT_STATUS_NO_ERROR; + + *length = 1U; + break; + + /* Printer SOFT RESET request: cleanup pending tasks */ + case PRNT_SOFT_RESET: + (void)f_close(&hSD.MyFile); + break; + + default: + /* Unkown commands are not managed */ + break; +} + +/** +* @brief TEMPLATE_PRNT_PageEndManager, defined by user +* Call this function frequently to check if data is received. +* @param Buf: Buffer of data to be received +* @param Len: Number of data received (in bytes) +*/ +void TEMPLATE_PRNT_PageEndManager(uint8_t *Buf, uint32_t Len) +{ + UNUSED(Buf); + UNUSED(Len); +} +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ + diff --git a/system/Middlewares/ST/STM32_USB_Device_Library/Class/Template/Src/usbd_template.c b/system/Middlewares/ST/STM32_USB_Device_Library/Class/Template/Src/usbd_template.c index 1c8ea725e5..10ced3fc05 100644 --- a/system/Middlewares/ST/STM32_USB_Device_Library/Class/Template/Src/usbd_template.c +++ b/system/Middlewares/ST/STM32_USB_Device_Library/Class/Template/Src/usbd_template.c @@ -128,7 +128,7 @@ USBD_ClassTypeDef USBD_TEMPLATE_ClassDriver = /* USB TEMPLATE device Configuration Descriptor */ __ALIGN_BEGIN static uint8_t USBD_TEMPLATE_CfgDesc[USB_TEMPLATE_CONFIG_DESC_SIZ] __ALIGN_END = { - 0x09, /* bLength: Configuation Descriptor size */ + 0x09, /* bLength: Configuration Descriptor size */ USB_DESC_TYPE_OTHER_SPEED_CONFIGURATION, /* bDescriptorType: Configuration */ USB_TEMPLATE_CONFIG_DESC_SIZ, /* wTotalLength: Bytes returned */ @@ -210,36 +210,35 @@ static uint8_t USBD_TEMPLATE_Setup(USBD_HandleTypeDef *pdev, switch (req->bmRequest & USB_REQ_TYPE_MASK) { - case USB_REQ_TYPE_CLASS : - switch (req->bRequest) - { - default: - USBD_CtlError(pdev, req); - ret = USBD_FAIL; + case USB_REQ_TYPE_CLASS : + switch (req->bRequest) + { + default: + USBD_CtlError(pdev, req); + ret = USBD_FAIL; + break; + } + break; + + case USB_REQ_TYPE_STANDARD: + switch (req->bRequest) + { + default: + USBD_CtlError(pdev, req); + ret = USBD_FAIL; + break; + } break; - } - break; - case USB_REQ_TYPE_STANDARD: - switch (req->bRequest) - { default: USBD_CtlError(pdev, req); ret = USBD_FAIL; break; - } - break; - - default: - USBD_CtlError(pdev, req); - ret = USBD_FAIL; - break; } return (uint8_t)ret; } - /** * @brief USBD_TEMPLATE_GetCfgDesc * return configuration descriptor @@ -253,18 +252,17 @@ static uint8_t *USBD_TEMPLATE_GetCfgDesc(uint16_t *length) } /** -* @brief DeviceQualifierDescriptor -* return Device Qualifier descriptor -* @param length : pointer data length -* @retval pointer to descriptor buffer -*/ + * @brief DeviceQualifierDescriptor + * return Device Qualifier descriptor + * @param length : pointer data length + * @retval pointer to descriptor buffer + */ uint8_t *USBD_TEMPLATE_DeviceQualifierDescriptor(uint16_t *length) { *length = (uint16_t)sizeof(USBD_TEMPLATE_DeviceQualifierDesc); return USBD_TEMPLATE_DeviceQualifierDesc; } - /** * @brief USBD_TEMPLATE_DataIn * handle data IN Stage @@ -289,6 +287,7 @@ static uint8_t USBD_TEMPLATE_EP0_RxReady(USBD_HandleTypeDef *pdev) return (uint8_t)USBD_OK; } + /** * @brief USBD_TEMPLATE_EP0_TxReady * handle EP0 TRx Ready event @@ -300,6 +299,7 @@ static uint8_t USBD_TEMPLATE_EP0_TxReady(USBD_HandleTypeDef *pdev) return (uint8_t)USBD_OK; } + /** * @brief USBD_TEMPLATE_SOF * handle SOF event @@ -311,6 +311,7 @@ static uint8_t USBD_TEMPLATE_SOF(USBD_HandleTypeDef *pdev) return (uint8_t)USBD_OK; } + /** * @brief USBD_TEMPLATE_IsoINIncomplete * handle data ISO IN Incomplete event @@ -323,6 +324,7 @@ static uint8_t USBD_TEMPLATE_IsoINIncomplete(USBD_HandleTypeDef *pdev, uint8_t e return (uint8_t)USBD_OK; } + /** * @brief USBD_TEMPLATE_IsoOutIncomplete * handle data ISO OUT Incomplete event @@ -349,11 +351,11 @@ static uint8_t USBD_TEMPLATE_DataOut(USBD_HandleTypeDef *pdev, uint8_t epnum) } /** -* @brief DeviceQualifierDescriptor -* return Device Qualifier descriptor -* @param length : pointer data length -* @retval pointer to descriptor buffer -*/ + * @brief DeviceQualifierDescriptor + * return Device Qualifier descriptor + * @param length : pointer data length + * @retval pointer to descriptor buffer + */ uint8_t *USBD_TEMPLATE_GetDeviceQualifierDesc(uint16_t *length) { *length = (uint16_t)sizeof(USBD_TEMPLATE_DeviceQualifierDesc); diff --git a/system/Middlewares/ST/STM32_USB_Device_Library/Class/VIDEO/Inc/usbd_video.h b/system/Middlewares/ST/STM32_USB_Device_Library/Class/VIDEO/Inc/usbd_video.h new file mode 100644 index 0000000000..c92ff76110 --- /dev/null +++ b/system/Middlewares/ST/STM32_USB_Device_Library/Class/VIDEO/Inc/usbd_video.h @@ -0,0 +1,460 @@ +/** + ****************************************************************************** + * @file usbd_video.h + * @author MCD Application Team + * @brief header file for the usbd_video.c file. + ****************************************************************************** + * @attention + * + *

© Copyright (c) 2020 STMicroelectronics. + * All rights reserved.

+ * + * This software component is licensed by ST under Ultimate Liberty license + * SLA0044, the "License"; You may not use this file except in compliance with + * the License. You may obtain a copy of the License at: + * www.st.com/SLA0044 + * + ****************************************************************************** + */ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef __USBD_VIDEO_H +#define __USBD_VIDEO_H + +#ifdef __cplusplus +extern "C" { +#endif + +/* Includes ------------------------------------------------------------------*/ +#include "usbd_ioreq.h" + +/** @addtogroup STM32_USB_DEVICE_LIBRARY + * @{ + */ + +/** @defgroup USBD_VIDEO + * @brief This file is the Header file for usbd_video.c + * @{ + */ + + +/** @defgroup usbd_VIDEO_Exported_Defines + * @{ + */ + +/* USB Video device class specification version 1.10 */ +#ifdef UVC_1_0 +#define UVC_VERSION 0x0100U /* UVC 1.0 */ +#else +#define UVC_VERSION 0x0110U /* UVC 1.1 */ +#endif + +/* bEndpointAddress in Endpoint Descriptor */ +#ifndef UVC_IN_EP +#define UVC_IN_EP 0x81U +#endif /* VIDEO_IN_EP */ + +/* These defines shall be updated in the usbd_conf.h file */ +#ifndef UVC_WIDTH +#define UVC_WIDTH 400U +#endif /* UVC_WIDTH */ + +#ifndef UVC_HEIGHT +#define UVC_HEIGHT 240U +#endif /* UVC_HEIGHT */ + +#ifndef UVC_CAM_FPS_FS +#define UVC_CAM_FPS_FS 10U +#endif /* UVC_CAM_FPS_FS */ + +#ifndef UVC_CAM_FPS_HS +#define UVC_CAM_FPS_HS 5U +#endif /* UVC_CAM_FPS_HS */ + +#ifndef UVC_PACKET_SIZE +#define UVC_PACKET_SIZE 512U +#endif /* UVC_PACKET_SIZE */ + +#ifndef UVC_MAX_FRAME_SIZE +#define UVC_MAX_FRAME_SIZE (UVC_WIDTH * UVC_HEIGHT * 16U / 2U) +#endif /* UVC_MAX_FRAME_SIZE */ + +#ifndef UVC_COLOR_PRIMARIE +#define UVC_COLOR_PRIMARIE 0x01U +#endif /* UVC_COLOR_PRIMARIE */ + +#ifndef UVC_TFR_CHARACTERISTICS +#define UVC_TFR_CHARACTERISTICS 0x01U +#endif /* UVC_TFR_CHARACTERISTICS */ + +#ifndef UVC_MATRIX_COEFFICIENTS +#define UVC_MATRIX_COEFFICIENTS 0x04U +#endif /* UVC_MATRIX_COEFFICIENTS */ + +#ifndef UVC_BITS_PER_PIXEL +#define UVC_BITS_PER_PIXEL 12U +#endif /* UVC_BITS_PER_PIXEL */ + +#define UVC_GUID_YUY2 0x32595559U +#define UVC_GUID_NV12 0x3231564EU + +#ifndef UVC_UNCOMPRESSED_GUID +#define UVC_UNCOMPRESSED_GUID UVC_GUID_NV12 +#endif /* UVC_UNCOMPRESSED_GUID */ + +#define UVC_INTERVAL(n) (10000000U/(n)) + +#define UVC_MIN_BIT_RATE(n) (UVC_WIDTH * UVC_HEIGHT * 16U * (n)) /* 16 bit */ +#define UVC_MAX_BIT_RATE(n) (UVC_WIDTH * UVC_HEIGHT * 16U * (n)) /* 16 bit */ + +#define UVC_PACKETS_IN_FRAME(n) (UVC_MAX_FRAME_SIZE / (n)) + +#ifndef UVC_ISO_FS_MPS +#define UVC_ISO_FS_MPS 256U +#endif + +#ifndef UVC_ISO_HS_MPS +#define UVC_ISO_HS_MPS 512U +#endif + +#ifndef UVC_HEADER_PACKET_CNT +#define UVC_HEADER_PACKET_CNT 0x01U +#endif + + +#define UVC_REQ_READ_MASK 0x80U +#define UVC_VC_IF_NUM 0x00U +#define UVC_VS_IF_NUM 0x01U +#define UVC_TOTAL_IF_NUM 0x02U + +#ifdef USBD_UVC_FORMAT_UNCOMPRESSED +#define UVC_CONFIG_DESC_SIZ (0x88U + 0x16U) +#else +#define UVC_CONFIG_DESC_SIZ 0x88U +#endif + +#define UVC_TOTAL_BUF_SIZE 0x04U + +#define UVC_VC_EP_DESC_SIZE 0x05U +#define UVC_STREAMING_EP_DESC_SIZE 0x07U +#define UVC_EP_DESC_TYPE 0x25U + +/* Video Interface Class Codes*/ +#define UVC_CC_VIDEO 0x0EU + +#define UVC_PLAY_STATUS_STOP 0x00U +#define UVC_PLAY_STATUS_READY 0x01U +#define UVC_PLAY_STATUS_STREAMING 0x02U + +#ifndef WBVAL +#define WBVAL(x) ((x) & 0xFFU),(((x) >> 8) & 0xFFU) +#endif +#ifndef DBVAL +#define DBVAL(x) ((x)& 0xFFU),(((x) >> 8) & 0xFFU),(((x)>> 16) & 0xFFU),(((x) >> 24) & 0xFFU) +#endif + +/* Video Interface Protocol Codes */ +#define PC_PROTOCOL_UNDEFINED 0x00U + +#define VIDEO_VC_IF_HEADER_DESC_SIZE 0x0DU +#define VIDEO_IN_TERMINAL_DESC_SIZE 0x08U +#define VIDEO_OUT_TERMINAL_DESC_SIZE 0x09U +#define VIDEO_VS_IF_IN_HEADER_DESC_SIZE 0x0EU + +#define VS_FORMAT_UNCOMPRESSED_DESC_SIZE 0x1BU +#define VS_FORMAT_MJPEG_DESC_SIZE 0x0BU +#define VS_FRAME_DESC_SIZE 0x1EU +#define VS_COLOR_MATCHING_DESC_SIZE 0x06U + +#ifdef USBD_UVC_FORMAT_UNCOMPRESSED +#define VS_FORMAT_DESC_SIZE VS_FORMAT_UNCOMPRESSED_DESC_SIZE +#define VS_FORMAT_SUBTYPE VS_FORMAT_UNCOMPRESSED +#define VS_FRAME_SUBTYPE VS_FRAME_UNCOMPRESSED + +#define VC_HEADER_SIZE (VIDEO_VS_IF_IN_HEADER_DESC_SIZE + \ + VS_FORMAT_UNCOMPRESSED_DESC_SIZE + \ + VS_FRAME_DESC_SIZE + \ + VS_COLOR_MATCHING_DESC_SIZE) +#else +#define VS_FORMAT_DESC_SIZE VS_FORMAT_MJPEG_DESC_SIZE +#define VS_FORMAT_SUBTYPE VS_FORMAT_MJPEG +#define VS_FRAME_SUBTYPE VS_FRAME_MJPEG + +#define VC_HEADER_SIZE (VIDEO_VS_IF_IN_HEADER_DESC_SIZE + \ + VS_FORMAT_DESC_SIZE + \ + VS_FRAME_DESC_SIZE) +#endif + +/* + * Video Class specification release 1.1 + * Appendix A. Video Device Class Codes defines + */ + +/* Video Interface Subclass values */ +#define SC_UNDEFINED 0x00U +#define SC_VIDEOCONTROL 0x01U +#define SC_VIDEOSTREAMING 0x02U +#define SC_VIDEO_INTERFACE_COLLECTION 0x03U + +/* Video Class-Specific Descriptor Types */ +#define CS_UNDEFINED 0x20U +#define CS_DEVICE 0x21U +#define CS_CONFIGURATION 0x22U +#define CS_STRING 0x23U +#define CS_INTERFACE 0x24U +#define CS_ENDPOINT 0x25U + +/* Video Class-Specific VideoControl Interface Descriptor Subtypes */ +#define VC_DESCRIPTOR_UNDEFINED 0x00U +#define VC_HEADER 0x01U +#define VC_INPUT_TERMINAL 0x02U +#define VC_OUTPUT_TERMINAL 0x03U +#define VC_SELECTOR_UNIT 0x04U +#define VC_PROCESSING_UNIT 0x05U +#define VC_EXTENSION_UNIT 0x06U + +/* Video Class-Specific VideoStreaming Interface Descriptor Subtypes */ +#define VS_UNDEFINED 0x00U +#define VS_INPUT_HEADER 0x01U +#define VS_OUTPUT_HEADER 0x02U +#define VS_STILL_IMAGE_FRAME 0x03U +#define VS_FORMAT_UNCOMPRESSED 0x04U +#define VS_FRAME_UNCOMPRESSED 0x05U +#define VS_FORMAT_MJPEG 0x06U +#define VS_FRAME_MJPEG 0x07U +#define VS_FORMAT_MPEG2TS 0x0AU +#define VS_FORMAT_DV 0x0CU +#define VS_COLORFORMAT 0x0DU +#define VS_FORMAT_FRAME_BASED 0x10U +#define VS_FRAME_FRAME_BASED 0x11U +#define VS_FORMAT_STREAM_BASED 0x12U + +/* Video Class-Specific Request values */ +#define UVC_RQ_UNDEFINED 0x00U +#define UVC_SET_CUR 0x01U +#define UVC_GET_CUR 0x81U +#define UVC_GET_MIN 0x82U +#define UVC_GET_MAX 0x83U +#define UVC_GET_RES 0x84U +#define UVC_GET_LEN 0x85U +#define UVC_GET_INFO 0x86U +#define UVC_GET_DEF 0x87U + +/* VideoControl Interface Control Selectors */ +#define VC_CONTROL_UNDEFINED 0x00U +#define VC_VIDEO_POWER_MODE_CONTROL 0x01U +#define VC_REQUEST_ERROR_CODE_CONTROL 0x02U + +/* Request Error Code Control */ +#define UVC_NO_ERROR_ERR 0x00U +#define UVC_NOT_READY_ERR 0x01U +#define UVC_WRONG_STATE_ERR 0x02U +#define UVC_POWER_ERR 0x03U +#define UVC_OUT_OF_RANGE_ERR 0x04U +#define UVC_INVALID_UNIT_ERR 0x05U +#define UVC_INVALID_CONTROL_ERR 0x06U +#define UVC_INVALID_REQUEST_ERR 0x07U +#define UVC_UNKNOWN_ERR 0xFFU + +/*Terminal Control Selectors*/ +#define TE_CONTROL_UNDEFINED 0x00U + +/* Selector Unit Control Selectors */ +#define SU_CONTROL_UNDEFINED 0x00U +#define SU_INPUT_SELECT_CONTROL 0x01U + +/* Camera Terminal Control Selectors */ +#define CT_CONTROL_UNDEFINED 0x00U +#define CT_SCANNING_MODE_CONTROL 0x01U +#define CT_AE_MODE_CONTROL 0x02U +#define CT_AE_PRIORITY_CONTROL 0x03U +#define CT_EXPOSURE_TIME_ABSOLUTE_CONTROL 0x04U +#define CT_EXPOSURE_TIME_RELATIVE_CONTROL 0x05U +#define CT_FOCUS_ABSOLUTE_CONTROL 0x06U +#define CT_FOCUS_RELATIVE_CONTROL 0x07U +#define CT_FOCUS_AUTO_CONTROL 0x08U +#define CT_IRIS_ABSOLUTE_CONTROL 0x09U +#define CT_IRIS_RELATIVE_CONTROL 0x0AU +#define CT_ZOOM_ABSOLUTE_CONTROL 0x0BU +#define CT_ZOOM_RELATIVE_CONTROL 0x0CU +#define CT_PANTILT_ABSOLUTE_CONTROL 0x0DU +#define CT_PANTILT_RELATIVE_CONTROL 0x0EU +#define CT_ROLL_ABSOLUTE_CONTROL 0x0FU +#define CT_ROLL_RELATIVE_CONTROL 0x10U +#define CT_PRIVACY_CONTROL 0x11U + +/* Processing Unit Control Selectors */ +#define PU_CONTROL_UNDEFINED 0x00U +#define PU_BACKLIGHT_COMPENSATION_CONTROL 0x01U +#define PU_BRIGHTNESS_CONTROL 0x02U +#define PU_CONTRAST_CONTROL 0x03U +#define PU_GAIN_CONTROL 0x04U +#define PU_POWER_LINE_FREQUENCY_CONTROL 0x05U +#define PU_HUE_CONTROL 0x06U +#define PU_SATURATION_CONTROL 0x07U +#define PU_SHARPNESS_CONTROL 0x08U +#define PU_GAMMA_CONTROL 0x09U +#define PU_WHITE_BALANCE_TEMPERATURE_CONTROL 0x0AU +#define PU_WHITE_BALANCE_TEMPERATURE_AUTO_CONTROL 0x0BU +#define PU_WHITE_BALANCE_COMPONENT_CONTROL 0x0CU +#define PU_WHITE_BALANCE_COMPONENT_AUTO_CONTROL 0x0DU +#define PU_DIGITAL_MULTIPLIER_CONTROL 0x0EU +#define PU_DIGITAL_MULTIPLIER_LIMIT_CONTROL 0x0FU +#define PU_HUE_AUTO_CONTROL 0x10U +#define PU_ANALOG_VIDEO_STANDARD_CONTROL 0x11U +#define PU_ANALOG_LOCK_STATUS_CONTROL 0x12U + +/*Extension Unit Control Selectors */ +#define XU_CONTROL_UNDEFINED 0x00U + +/* VideoStreaming Interface Control Selectors */ +#define VS_CONTROL_UNDEFINED 0x00U +#define VS_PROBE_CONTROL 0x100U +#define VS_COMMIT_CONTROL 0x200U +#define VS_STILL_PROBE_CONTROL 0x03U +#define VS_STILL_COMMIT_CONTROL 0x04U +#define VS_STILL_IMAGE_TRIGGER_CONTROL 0x05U +#define VS_STREAM_ERROR_CODE_CONTROL 0x06U +#define VS_GENERATE_KEY_FRAME_CONTROL 0x07U +#define VS_UPDATE_FRAME_SEGMENT_CONTROL 0x08U +#define VS_SYNC_DELAY_CONTROL 0x09U + + +/* Control Capabilities */ +#define UVC_SUPPORTS_GET 0x01U +#define UVC_SUPPORTS_SET 0x02U +#define UVC_STATE_DISABLED 0x04U +#define UVC_AUTOUPDATE_CONTROL 0x08U +#define UVC_ASYNCHRONOUS_CONTROL 0x10U + +/* USB Terminal Types */ +#define TT_VENDOR_SPECIFIC 0x0100U +#define TT_STREAMING 0x0101U + +/* Input Terminal Types */ +#define ITT_VENDOR_SPECIFIC 0x0200U +#define ITT_CAMERA 0x0201U +#define ITT_MEDIA_TRANSPORT_INPUT 0x0202U + +/*Output Terminal Types */ +#define OTT_VENDOR_SPECIFIC 0x0300U +#define OTT_DISPLAY 0x0301U +#define OTT_MEDIA_TRANSPORT_OUTPUT 0x0302U + +/* External Terminal Types */ +#define EXTERNAL_VENDOR_SPECIFIC 0x0400U +#define COMPOSITE_CONNECTOR 0x0401U +#define SVIDEO_CONNECTOR 0x0402U +#define COMPONENT_CONNECTOR 0x0403U + + +/* VIDEO Commands enumeration */ +typedef enum +{ + VIDEO_CMD_START = 1U, + VIDEO_CMD_PLAY, + VIDEO_CMD_STOP, +} VIDEO_CMD_TypeDef; + +typedef enum +{ + VIDEO_OFFSET_NONE = 0U, + VIDEO_OFFSET_HALF, + VIDEO_OFFSET_FULL, + VIDEO_OFFSET_UNKNOWN, +} VIDEO_OffsetTypeDef; + +typedef struct _VIDEO_DescHeader +{ + uint8_t bLength; + uint8_t bDescriptorType; + uint8_t bDescriptorSubType; +} USBD_VIDEO_DescHeader_t; + +typedef struct +{ + uint8_t bLength; + uint8_t bDescriptorType; + uint8_t bDescriptorSubType; + uint8_t bFrameIndex; + uint8_t bmCapabilities; + uint16_t wWidth; + uint16_t wHeight; + uint32_t dwMinBitRate; + uint32_t dwMaxBitRate; + uint32_t dwMaxVideoFrameBufSize; + uint32_t dwDefaultFrameInterval; + uint8_t bFrameIntervalType; + uint32_t dwMinFrameInterval; + uint32_t dwMaxFrameInterval; + uint32_t dwFrameIntervalStep; +} __PACKED USBD_VIDEO_VSFrameDescTypeDef; + +typedef struct +{ + uint8_t cmd; + uint8_t data[USB_MAX_EP0_SIZE]; + uint8_t len; + uint8_t unit; +} USBD_VIDEO_ControlTypeDef; + +typedef struct +{ + uint32_t interface; + uint32_t uvc_state; + uint8_t buffer[UVC_TOTAL_BUF_SIZE]; + VIDEO_OffsetTypeDef offset; + USBD_VIDEO_ControlTypeDef control; +} USBD_VIDEO_HandleTypeDef; + +typedef struct +{ + int8_t (* Init)(void); + int8_t (* DeInit)(void); + int8_t (* Control)(uint8_t, uint8_t *, uint16_t); + int8_t (* Data)(uint8_t **, uint16_t *, uint16_t *); + uint8_t *pStrDesc; +} USBD_VIDEO_ItfTypeDef; + +/* UVC uses only 26 first bytes */ +typedef struct +{ + uint16_t bmHint; + uint8_t bFormatIndex; + uint8_t bFrameIndex; + uint32_t dwFrameInterval; + uint16_t wKeyFrameRate; + uint16_t wPFrameRate; + uint16_t wCompQuality; + uint16_t wCompWindowSize; + uint16_t wDelay; + uint32_t dwMaxVideoFrameSize; + uint32_t dwMaxPayloadTransferSize; + uint32_t dwClockFrequency; + uint8_t bmFramingInfo; + uint8_t bPreferedVersion; + uint8_t bMinVersion; + uint8_t bMaxVersion; +} __PACKED USBD_VideoControlTypeDef; + +extern USBD_ClassTypeDef USBD_VIDEO; +#define USBD_VIDEO_CLASS &USBD_VIDEO +/** + * @} + */ + +/** @defgroup USB_CORE_Exported_Functions + * @{ + */ + +uint8_t USBD_VIDEO_RegisterInterface(USBD_HandleTypeDef *pdev, USBD_VIDEO_ItfTypeDef *fops); + +/** + * @} + */ + +#ifdef __cplusplus +} +#endif + +#endif /* _USBD_VIDEO_H_ */ diff --git a/system/Middlewares/ST/STM32_USB_Device_Library/Class/VIDEO/Inc/usbd_video_if_template.h b/system/Middlewares/ST/STM32_USB_Device_Library/Class/VIDEO/Inc/usbd_video_if_template.h new file mode 100644 index 0000000000..036c7aade2 --- /dev/null +++ b/system/Middlewares/ST/STM32_USB_Device_Library/Class/VIDEO/Inc/usbd_video_if_template.h @@ -0,0 +1,142 @@ +/** + ****************************************************************************** + * @file usbd_video_if_template.h + * @author MCD Application Team + * @brief Template Header file for the video Interface application layer functions + ****************************************************************************** + * @attention + * + *

© Copyright (c) 2020 STMicroelectronics. + * All rights reserved.

+ * + * This software component is licensed by ST under Ultimate Liberty license + * SLA0044, the "License"; You may not use this file except in compliance with + * the License. You may obtain a copy of the License at: + * www.st.com/SLA0044 + * + ****************************************************************************** + */ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef __USBD_VIDEO_IF_H__ +#define __USBD_VIDEO_IF_H__ + +#ifdef __cplusplus +extern "C" { +#endif + +/* Includes ------------------------------------------------------------------*/ +#include "usbd_video.h" + +/* USER CODE BEGIN INCLUDE */ + +/* USER CODE END INCLUDE */ + +/** @addtogroup STM32_USB_OTG_DEVICE_LIBRARY + * @brief For Usb device. + * @{ + */ + +/** @defgroup USBD_VIDEO_IF + * @brief Usb VIDEO interface device module. + * @{ + */ + +/** @defgroup USBD_VIDEO_IF_Exported_Defines + * @brief Defines. + * @{ + */ + +/* USER CODE BEGIN EXPORTED_DEFINES */ + +/* USER CODE END EXPORTED_DEFINES */ + +/** + * @} + */ + +/** @defgroup USBD_VIDEO_IF_Exported_Types + * @brief Types. + * @{ + */ + +/* USER CODE BEGIN EXPORTED_TYPES */ + +/* USER CODE END EXPORTED_TYPES */ + +/** + * @} + */ + +/** @defgroup USBD_VIDEO_IF_Exported_Macros + * @brief Aliases. + * @{ + */ + +/* USER CODE BEGIN EXPORTED_MACRO */ + +/* USER CODE END EXPORTED_MACRO */ + +/** + * @} + */ + +/** @defgroup USBD_VIDEO_IF_Exported_Variables + * @brief Public variables. + * @{ + */ + +/** VIDEO_IF Interface callback. */ +extern USBD_VIDEO_ItfTypeDef USBD_VIDEO_fops_FS; + +/* USER CODE BEGIN EXPORTED_VARIABLES */ + +/* USER CODE END EXPORTED_VARIABLES */ + +/** + * @} + */ + +/** @defgroup USBD_VIDEO_IF_Exported_FunctionsPrototype + * @brief Public functions declaration. + * @{ + */ + +/** + * @brief Manages the DMA full transfer complete event. + * @retval None + */ +void TransferComplete_CallBack_FS(void); + +/** + * @brief Manages the DMA half transfer complete event. + * @retval None + */ +void HalfTransfer_CallBack_FS(void); + +/* USER CODE BEGIN EXPORTED_FUNCTIONS */ + +/* USER CODE END EXPORTED_FUNCTIONS */ + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +#ifdef __cplusplus +} +#endif + +#endif /* USBD_VIDEO_IF_H_ */ + +/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ + + + diff --git a/system/Middlewares/ST/STM32_USB_Device_Library/Class/VIDEO/Src/usbd_video.c b/system/Middlewares/ST/STM32_USB_Device_Library/Class/VIDEO/Src/usbd_video.c new file mode 100644 index 0000000000..a414ed6ff6 --- /dev/null +++ b/system/Middlewares/ST/STM32_USB_Device_Library/Class/VIDEO/Src/usbd_video.c @@ -0,0 +1,1051 @@ +/** + ****************************************************************************** + * @file usbd_video.c + * @author MCD Application Team + * @brief This file provides the Video core functions. + * + * @verbatim + * + * =================================================================== + * VIDEO Class Description + * =================================================================== + * This driver manages the Video Class 1.1 following the "USB Device Class Definition for + * Video Devices V1.0 Mar 18, 98". + * This driver implements the following aspects of the specification: + * - Device descriptor management + * - Configuration descriptor management + * - Interface Association Descriptor + * -Standard VC Interface Descriptor = interface 0 + * -Standard Vs Interface Descriptor = interface 1 + * - 1 Video Streaming Interface + * - 1 Video Streaming Endpoint + * - 1 Video Terminal Input (camera) + * - Video Class-Specific AC Interfaces + * - Video Class-Specific AS Interfaces + * - VideoControl Requests + * - Video Synchronization type: Asynchronous + * The current Video class version supports the following Video features: + * - image JPEG format + * - Asynchronous Endpoints + * + * @note In HS mode and when the USB DMA is used, all variables and data structures + * dealing with the DMA during the transaction process should be 32-bit aligned. + * + * + * @endverbatim + * + ****************************************************************************** + * @attention + * + *

© Copyright (c) 2020 STMicroelectronics. + * All rights reserved.

+ * + * This software component is licensed by ST under Ultimate Liberty license + * SLA0044, the "License"; You may not use this file except in compliance with + * the License. You may obtain a copy of the License at: + * www.st.com/SLA0044 + * + ****************************************************************************** + */ + +/* Includes ------------------------------------------------------------------*/ +#include "usbd_video.h" +#include "usbd_ctlreq.h" +#include "usbd_core.h" +/** @addtogroup STM32_USB_DEVICE_LIBRARY + * @{ + */ + + +/** @defgroup USBD_VIDEO + * @brief USB Device Video Class core module + * @{ + */ + +/** @defgroup USBD_VIDEO_Private_TypesDefinitions + * @{ + */ + +/** + * @} + */ + +/** @defgroup USBD_VIDEO_Private_Defines + * @{ + */ + +/** + * @} + */ + + +/** @defgroup USBD_VIDEO_Private_Macros + * @{ + */ + +/* VIDEO Device library callbacks */ +static uint8_t USBD_VIDEO_Init(USBD_HandleTypeDef *pdev, uint8_t cfgidx); +static uint8_t USBD_VIDEO_DeInit(USBD_HandleTypeDef *pdev, uint8_t cfgidx); +static uint8_t USBD_VIDEO_Setup(USBD_HandleTypeDef *pdev, USBD_SetupReqTypedef *req); +static uint8_t *USBD_VIDEO_GetFSCfgDesc(uint16_t *length); +static uint8_t *USBD_VIDEO_GetHSCfgDesc(uint16_t *length); +static uint8_t *USBD_VIDEO_GetOtherSpeedCfgDesc(uint16_t *length); +static uint8_t *USBD_VIDEO_GetDeviceQualifierDesc(uint16_t *length); +static uint8_t USBD_VIDEO_DataIn(USBD_HandleTypeDef *pdev, uint8_t epnum); +static uint8_t USBD_VIDEO_SOF(USBD_HandleTypeDef *pdev); +static uint8_t USBD_VIDEO_IsoINIncomplete(USBD_HandleTypeDef *pdev, uint8_t epnum); + +/* VIDEO Requests management functions */ +static void VIDEO_REQ_GetCurrent(USBD_HandleTypeDef *pdev, USBD_SetupReqTypedef *req); +static void VIDEO_REQ_SetCurrent(USBD_HandleTypeDef *pdev, USBD_SetupReqTypedef *req); + +static USBD_VIDEO_DescHeader_t *USBD_VIDEO_GetNextDesc(uint8_t *pbuf, uint16_t *ptr); +static void *USBD_VIDEO_GetEpDesc(uint8_t *pConfDesc, uint8_t EpAddr); +static void *USBD_VIDEO_GetVSFrameDesc(uint8_t *pConfDesc); + + +/** + * @} + */ + +/** @defgroup USBD_VIDEO_Private_Variables + * @{ + */ + +USBD_ClassTypeDef USBD_VIDEO = +{ + USBD_VIDEO_Init, + USBD_VIDEO_DeInit, + USBD_VIDEO_Setup, + NULL, + NULL, + USBD_VIDEO_DataIn, + NULL, + USBD_VIDEO_SOF, + USBD_VIDEO_IsoINIncomplete, + NULL, + USBD_VIDEO_GetHSCfgDesc, + USBD_VIDEO_GetFSCfgDesc, + USBD_VIDEO_GetOtherSpeedCfgDesc, + USBD_VIDEO_GetDeviceQualifierDesc, +}; + +/* USB VIDEO device Configuration Descriptor (same for all speeds thanks to user defines) */ +__ALIGN_BEGIN static uint8_t USBD_VIDEO_CfgDesc[] __ALIGN_END = +{ + /* Configuration 1 */ + USB_CONF_DESC_SIZE, /* bLength: Configuration Descriptor size */ + USB_DESC_TYPE_CONFIGURATION, /* bDescriptorType: Configuration */ + LOBYTE(UVC_CONFIG_DESC_SIZ), /* wTotalLength: no of returned bytes */ + HIBYTE(UVC_CONFIG_DESC_SIZ), + 0x02, /* bNumInterfaces: 2 interfaces */ + 0x01, /* bConfigurationValue: Configuration value */ + 0x00, /* iConfiguration: Index of string descriptor describing the configuration */ +#if (USBD_SELF_POWERED == 1U) + 0xC0, /* bmAttributes: Bus Powered according to user configuration */ +#else + 0x80, /* bmAttributes: Bus Powered according to user configuration */ +#endif + USBD_MAX_POWER, /* bMaxPower in mA according to user configuration */ + + /* Interface Association Descriptor */ + USB_IAD_DESC_SIZE, /* bLength: Interface Association Descriptor size */ + USB_DESC_TYPE_IAD, /* bDescriptorType: interface association */ + 0x00, /* bFirstInterface */ + 0x02, /* bInterfaceCount */ + UVC_CC_VIDEO, /* bFunctionClass: Video class */ + SC_VIDEO_INTERFACE_COLLECTION, /* bFunctionSubClass: Video Interface Collection */ + PC_PROTOCOL_UNDEFINED, /* bInterfaceProtocol: protocol undefined */ + 0x00, /* iFunction */ + + /* Standard VC (Video Control) Interface Descriptor = interface 0 */ + USB_IF_DESC_SIZE, /* bLength: interface descriptor size */ + USB_DESC_TYPE_INTERFACE, /* bDescriptorType: interface */ + UVC_VC_IF_NUM, /* bInterfaceNumber: interface number */ + 0x00, /* bAlternateSetting: index of this alternate setting */ + 0x00, /* bNumEndpoints: No endpoints used for this interface */ + UVC_CC_VIDEO, /* bInterfaceClass: Video Class */ + SC_VIDEOCONTROL, /* bInterfaceSubClass: Video Control */ + PC_PROTOCOL_UNDEFINED, /* bInterfaceProtocol: protocol is undefined */ + 0x00, /* iFunction: index of string descriptor relative to this item */ + + /* Class-specific VC Interface Descriptor */ + VIDEO_VC_IF_HEADER_DESC_SIZE, /* bLength */ + CS_INTERFACE, /* bDescriptorType */ + VC_HEADER, /* bDescriptorSubtype */ + LOBYTE(UVC_VERSION), + HIBYTE(UVC_VERSION), /* bcdUVC: UVC1.0 or UVC1.1 revision */ + VS_FRAME_DESC_SIZE, /* wTotalLength: total size of class-specific descriptors */ + 0x00, + 0x00, /* dwClockFrequency: not used. 48 Mhz value is set, but not used */ + 0x6C, + 0xDC, + 0x02, + 0x01, /* bInCollection: number of streaming interfaces */ + 0x01, /* baInterfaceNr(1): VideoStreaming interface 1 is part of VC interface */ + + /* Input Terminal Descriptor */ + VIDEO_IN_TERMINAL_DESC_SIZE, /* bLength: Input terminal descriptor size */ + CS_INTERFACE, /* bDescriptorType: INTERFACE */ + VC_INPUT_TERMINAL, /* bDescriptorSubtype: INPUT_TERMINAL */ + 0x01, /* bTerminalID: ID of this Terminal */ + LOBYTE(ITT_VENDOR_SPECIFIC), /* wTerminalType: 0x0200 ITT_VENDOR_SPECIFIC */ + HIBYTE(ITT_VENDOR_SPECIFIC), + 0x00, /* bAssocTerminal: no Terminal is associated */ + 0x00, /* iTerminal: index of string descriptor relative to this item */ + + /* Output Terminal Descriptor */ + VIDEO_OUT_TERMINAL_DESC_SIZE, /* bLength: output terminal descriptor size */ + CS_INTERFACE, /* bDescriptorType */ + VC_OUTPUT_TERMINAL, /* bDescriptorSubtype */ + 0x02, /* bTerminalID */ + LOBYTE(TT_STREAMING), /* wTerminalType: USB streaming terminal */ + HIBYTE(TT_STREAMING), + 0x00, /* bAssocTerminal: no Terminal is associated */ + 0x01, /* bSourceID: input is connected to output unit ID 1 */ + 0x00, /* iTerminal: index of string descriptor relative to this item */ + + /* Standard VS (Video Streaming) Interface Descriptor = interface 1, alternate setting 0 = Zero Bandwidth + (when no data are sent from the device) */ + USB_IF_DESC_SIZE, /* bLength: interface descriptor size */ + USB_DESC_TYPE_INTERFACE, /* bDescriptorType */ + UVC_VS_IF_NUM, /* bInterfaceNumber */ + 0x00, /* bAlternateSetting */ + 0x00, /* bNumEndpoints: no endpoints used for alternate setting 0 */ + UVC_CC_VIDEO, /* bInterfaceClass */ + SC_VIDEOSTREAMING, /* bInterfaceSubClass */ + PC_PROTOCOL_UNDEFINED, /* bInterfaceProtocol */ + 0x00, /* iInterface: index of string descriptor relative to this item */ + + /* Class-specific VS Header Descriptor (Input) */ + VIDEO_VS_IF_IN_HEADER_DESC_SIZE, /* bLength */ + CS_INTERFACE, /* bDescriptorType */ + VS_INPUT_HEADER, /* bDescriptorSubtype */ + 0x01, /* bNumFormats: 1 format descriptor is used */ + VC_HEADER_SIZE, + 0x00, /* Total size of Video Control Specific Descriptors */ + UVC_IN_EP, /* bEndPointAddress: In endpoint is used for the alternate setting */ + 0x00, /* bmInfo: dynamic format change not supported */ + 0x02, /* bTerminalLink: output to terminal ID 2 */ + 0x00, /* bStillCaptureMethod: not supported */ + 0x00, /* bTriggerSupport: not supported */ + 0x00, /* bTriggerUsage: not supported */ + 0x01, /* bControlSize: 1 byte field size */ + 0x00, /* bmaControls: No specific controls used */ + + /* Payload Format Descriptor */ + VS_FORMAT_DESC_SIZE, /* blength */ + CS_INTERFACE, /* bDescriptorType */ + VS_FORMAT_SUBTYPE, /* bDescriptorSubType */ + 0x01, /* bFormatIndex */ + 0x01, /* bNumFrameDescriptor */ +#ifdef USBD_UVC_FORMAT_UNCOMPRESSED + DBVAL(UVC_UNCOMPRESSED_GUID), /* Giud Format: YUY2 {32595559-0000-0010-8000-00AA00389B71} */ + 0x00, 0x00, + 0x10, 0x00, + 0x80, 0x00, + 0x00, 0xAA, 0x00, 0x38, 0x9B, 0x71, + UVC_BITS_PER_PIXEL, /* bBitsPerPixel : Number of bits per pixel */ +#else + 0x01, /* bmFlags: FixedSizeSamples */ +#endif + 0x01, /* bDefaultFrameIndex: default frame used is frame 1 (only one frame used) */ + 0x00, /* bAspectRatioX: not required by specification */ + 0x00, /* bAspectRatioY: not required by specification */ + 0x00, /* bInterlaceFlags: non interlaced stream */ + 0x00, /* bCopyProtect: no protection restrictions */ + + /* Class-specific VS (Video Streaming) Frame Descriptor */ + VS_FRAME_DESC_SIZE, /* bLength */ + CS_INTERFACE, /* bDescriptorType */ + VS_FRAME_SUBTYPE, /* bDescriptorSubType */ + 0x01, /* bFrameIndex */ +#ifdef USBD_UVC_FORMAT_UNCOMPRESSED + 0x00, /* bmCapabilities: no till image capture */ +#else + 0x02, /* bmCapabilities: fixed frame rate supported */ +#endif + WBVAL(UVC_WIDTH), /* wWidth: Image Frame Width */ + WBVAL(UVC_HEIGHT), /* wHeight: Image Frame Height */ + DBVAL(UVC_MIN_BIT_RATE(UVC_CAM_FPS_FS)), /* dwMinBitRate: Minimum supported bit rate in bits/s */ + DBVAL(UVC_MAX_BIT_RATE(UVC_CAM_FPS_FS)), /* dwMaxBitRate: Maximum supported bit rate in bits/s */ + DBVAL(UVC_MAX_FRAME_SIZE), /* dwMaxVideoFrameBufSize: Maximum video frame size, in bytes */ + DBVAL(UVC_INTERVAL(UVC_CAM_FPS_FS)), /* dwDefaultFrameInterval: following number of FPS */ + 0x01, /* bFrameIntervalType: Discrete frame interval type */ + DBVAL(UVC_INTERVAL(UVC_CAM_FPS_FS)), /* dwMinFrameInterval: One supported value of interval (FPS) */ + +#ifdef USBD_UVC_FORMAT_UNCOMPRESSED + /* Color Matching Descriptor */ + VS_COLOR_MATCHING_DESC_SIZE, /* bLength */ + CS_INTERFACE, /* bDescriptorType: CS_INTERFACE */ + VS_COLORFORMAT, /* bDescriptorSubType: VS_COLORFORMAT */ + UVC_COLOR_PRIMARIE, /* bColorPrimarie: 1: BT.709, sRGB (default) */ + UVC_TFR_CHARACTERISTICS, /* bTransferCharacteristics: 1: BT.709 (default) */ + UVC_MATRIX_COEFFICIENTS, /* bMatrixCoefficients: 4: BT.601, (default) */ +#endif + + /* Standard VS Interface Descriptor = interface 1, alternate setting 1 = data transfer mode */ + USB_IF_DESC_SIZE, /* bLength */ + USB_DESC_TYPE_INTERFACE, /* bDescriptorType */ + UVC_VS_IF_NUM, /* bInterfaceNumber */ + 0x01, /* bAlternateSetting */ + 0x01, /* bNumEndpoints: one endpoint is used */ + UVC_CC_VIDEO, /* bInterfaceClass */ + SC_VIDEOSTREAMING, /* bInterfaceSubClass */ + PC_PROTOCOL_UNDEFINED, /* bInterfaceProtocol */ + 0x00, /* iInterface: index of string descriptor relative to this item */ + + /* Standard VS (Video Streaming) data Endpoint */ + USB_EP_DESC_SIZE, /* bLength */ + USB_DESC_TYPE_ENDPOINT, /* bDescriptorType */ + UVC_IN_EP, /* bEndpointAddress */ + 0x05, /* bmAttributes: ISO transfer */ + LOBYTE(UVC_ISO_FS_MPS), /* wMaxPacketSize */ + LOBYTE(UVC_ISO_FS_MPS), + 0x01, /* bInterval: 1 frame interval */ +}; + +/* USB Standard Device Descriptor */ +__ALIGN_BEGIN static uint8_t USBD_VIDEO_DeviceQualifierDesc[USB_LEN_DEV_QUALIFIER_DESC] __ALIGN_END = +{ + USB_LEN_DEV_QUALIFIER_DESC, + USB_DESC_TYPE_DEVICE_QUALIFIER, + 0x00, + 0x02, + 0xEF, + 0x02, + 0x01, + 0x40, + 0x01, + 0x00, +}; + +/* Video Commit data structure */ +static USBD_VideoControlTypeDef video_Commit_Control = +{ + .bmHint = 0x0000U, + .bFormatIndex = 0x01U, + .bFrameIndex = 0x01U, + .dwFrameInterval = UVC_INTERVAL(UVC_CAM_FPS_FS), + .wKeyFrameRate = 0x0000U, + .wPFrameRate = 0x0000U, + .wCompQuality = 0x0000U, + .wCompWindowSize = 0x0000U, + .wDelay = 0x0000U, + .dwMaxVideoFrameSize = 0x0000U, + .dwMaxPayloadTransferSize = 0x00000000U, + .dwClockFrequency = 0x00000000U, + .bmFramingInfo = 0x00U, + .bPreferedVersion = 0x00U, + .bMinVersion = 0x00U, + .bMaxVersion = 0x00U, +}; + +/* Video Probe data structure */ +static USBD_VideoControlTypeDef video_Probe_Control = +{ + .bmHint = 0x0000U, + .bFormatIndex = 0x01U, + .bFrameIndex = 0x01U, + .dwFrameInterval = UVC_INTERVAL(UVC_CAM_FPS_FS), + .wKeyFrameRate = 0x0000U, + .wPFrameRate = 0x0000U, + .wCompQuality = 0x0000U, + .wCompWindowSize = 0x0000U, + .wDelay = 0x0000U, + .dwMaxVideoFrameSize = 0x0000U, + .dwMaxPayloadTransferSize = 0x00000000U, + .dwClockFrequency = 0x00000000U, + .bmFramingInfo = 0x00U, + .bPreferedVersion = 0x00U, + .bMinVersion = 0x00U, + .bMaxVersion = 0x00U, +}; + +/** + * @} + */ + +/** @defgroup USBD_VIDEO_Private_Functions + * @{ + */ + +/** + * @brief USBD_VIDEO_Init + * Initialize the VIDEO interface + * @param pdev: device instance + * @param cfgidx: Configuration index + * @retval status + */ +static uint8_t USBD_VIDEO_Init(USBD_HandleTypeDef *pdev, uint8_t cfgidx) +{ + USBD_VIDEO_HandleTypeDef *hVIDEO; + + /* Allocate memory for the video control structure */ + hVIDEO = (USBD_VIDEO_HandleTypeDef *)USBD_malloc(sizeof(USBD_VIDEO_HandleTypeDef)); + + /* Check if allocated point is NULL, then exit with error code */ + if (hVIDEO == NULL) + { + return (uint8_t)USBD_FAIL; + } + + /* Assign the pClassData pointer to the allocated structure */ + pdev->pClassData = (void *)hVIDEO; + + /* Open EP IN */ + if (pdev->dev_speed == USBD_SPEED_HIGH) + { + (void)USBD_LL_OpenEP(pdev, UVC_IN_EP, USBD_EP_TYPE_ISOC, UVC_ISO_HS_MPS); + + pdev->ep_in[UVC_IN_EP & 0xFU].is_used = 1U; + pdev->ep_in[UVC_IN_EP & 0xFU].maxpacket = UVC_ISO_HS_MPS; + } + else + { + (void)USBD_LL_OpenEP(pdev, UVC_IN_EP, USBD_EP_TYPE_ISOC, UVC_ISO_FS_MPS); + + pdev->ep_in[UVC_IN_EP & 0xFU].is_used = 1U; + pdev->ep_in[UVC_IN_EP & 0xFU].maxpacket = UVC_ISO_FS_MPS; + } + + /* Init physical Interface components */ + ((USBD_VIDEO_ItfTypeDef *)pdev->pUserData)->Init(); + + /* Init Xfer states */ + hVIDEO->interface = 0U; + + /* Some calls to unused variables, to comply with MISRA-C 2012 rules */ + UNUSED(USBD_VIDEO_CfgDesc); + UNUSED(cfgidx); + + /* Exit with no error code */ + return (uint8_t)USBD_OK; +} + +/** + * @brief USBD_VIDEO_DeInit + * DeInitialize the VIDEO layer + * @param pdev: device instance + * @param cfgidx: Configuration index + * @retval status + */ +static uint8_t USBD_VIDEO_DeInit(USBD_HandleTypeDef *pdev, uint8_t cfgidx) +{ + UNUSED(cfgidx); + + /* Check if the video structure pointer is valid */ + if (pdev->pClassData == NULL) + { + return (uint8_t)USBD_FAIL; + } + + /* Close EP IN */ + (void)USBD_LL_CloseEP(pdev, UVC_IN_EP); + pdev->ep_in[UVC_IN_EP & 0xFU].is_used = 0U; + + /* DeInit physical Interface components */ + ((USBD_VIDEO_ItfTypeDef *)pdev->pUserData)->DeInit(); + USBD_free(pdev->pClassData); + pdev->pClassData = NULL; + + /* Exit with no error code */ + return (uint8_t)USBD_OK; +} + +/** + * @brief USBD_VIDEO_Setup + * Handle the VIDEO specific requests + * @param pdev: instance + * @param req: usb requests + * @retval status + */ +static uint8_t USBD_VIDEO_Setup(USBD_HandleTypeDef *pdev, USBD_SetupReqTypedef *req) +{ + USBD_VIDEO_HandleTypeDef *hVIDEO = (USBD_VIDEO_HandleTypeDef *) pdev->pClassData; + uint8_t ret = (uint8_t)USBD_OK; + uint16_t len = 0U; + uint8_t *pbuf = NULL; + uint16_t status_info = 0U; + + switch (req->bmRequest & USB_REQ_TYPE_MASK) + { + /* Class Requests -------------------------------*/ + case USB_REQ_TYPE_CLASS: + switch (req->bRequest) + { + case UVC_GET_CUR: + case UVC_GET_DEF: + case UVC_GET_MIN: + case UVC_GET_MAX: + VIDEO_REQ_GetCurrent(pdev, req); + break; + case UVC_GET_RES: + case UVC_GET_LEN: + case UVC_GET_INFO: + break; + case UVC_SET_CUR: + VIDEO_REQ_SetCurrent(pdev, req); + break; + default: + (void) USBD_CtlError(pdev, req); + ret = (uint8_t)USBD_FAIL; + break; + } + break; + + /* Standard Requests -------------------------------*/ + case USB_REQ_TYPE_STANDARD: + switch (req->bRequest) + { + case USB_REQ_GET_STATUS: + if (pdev->dev_state == USBD_STATE_CONFIGURED) + { + (void) USBD_CtlSendData(pdev, (uint8_t *)&status_info, 2U); + } + else + { + USBD_CtlError(pdev, req); + ret = (uint8_t)USBD_FAIL; + } + break; + + case USB_REQ_GET_DESCRIPTOR: + if ((req->wValue >> 8) == CS_DEVICE) + { + pbuf = USBD_VIDEO_CfgDesc + 18; + len = MIN((uint16_t)USB_CONF_DESC_SIZE, (uint16_t)req->wLength); + } + (void)USBD_CtlSendData(pdev, pbuf, len); + break; + + case USB_REQ_GET_INTERFACE : + if (pdev->dev_state == USBD_STATE_CONFIGURED) + { + (void)USBD_CtlSendData(pdev, (uint8_t *)&hVIDEO->interface, 1U); + } + else + { + USBD_CtlError(pdev, req); + ret = (uint8_t)USBD_FAIL; + } + break; + + case USB_REQ_SET_INTERFACE : + if (pdev->dev_state == USBD_STATE_CONFIGURED) + { + if (req->wValue <= USBD_MAX_NUM_INTERFACES) + { + hVIDEO->interface = LOBYTE(req->wValue); + if (hVIDEO->interface == 1U) + { + /* Start Streaming (First endpoint writing will be done on next SOF) */ + (void)USBD_LL_FlushEP(pdev, UVC_IN_EP); + hVIDEO->uvc_state = UVC_PLAY_STATUS_READY; + } + else + { + /* Stop Streaming */ + hVIDEO->uvc_state = UVC_PLAY_STATUS_STOP; + (void)USBD_LL_FlushEP(pdev, UVC_IN_EP); + } + } + else + { + /* Call the error management function (command will be NAKed) */ + USBD_CtlError(pdev, req); + ret = (uint8_t)USBD_FAIL; + } + } + else + { + USBD_CtlError(pdev, req); + ret = (uint8_t)USBD_FAIL; + } + break; + + case USB_REQ_CLEAR_FEATURE: + break; + + default: + USBD_CtlError(pdev, req); + ret = (uint8_t)USBD_FAIL; + break; + } + break; + + default: + USBD_CtlError(pdev, req); + ret = (uint8_t)USBD_FAIL; + break; + } + + return ret; +} + +/** + * @brief USBD_VIDEO_DataIn + * handle data IN Stage + * @param pdev: device instance + * @param epnum: endpoint index + * @retval status + */ +static uint8_t USBD_VIDEO_DataIn(USBD_HandleTypeDef *pdev, uint8_t epnum) +{ + USBD_VIDEO_HandleTypeDef *hVIDEO = (USBD_VIDEO_HandleTypeDef *) pdev->pClassData; + static uint8_t packet[UVC_PACKET_SIZE + (UVC_HEADER_PACKET_CNT * 2U)] = {0x00U}; + static uint8_t *Pcktdata = packet; + static uint16_t PcktIdx = 0U; + static uint16_t PcktSze = UVC_PACKET_SIZE; + static uint8_t payload_header[2] = {0x02U, 0x00U}; + uint8_t i = 0U; + uint32_t RemainData, DataOffset = 0U; + + /* Check if the Streaming has already been started */ + if (hVIDEO->uvc_state == UVC_PLAY_STATUS_STREAMING) + { + /* Get the current packet buffer, index and size from the application layer */ + ((USBD_VIDEO_ItfTypeDef *)pdev->pUserData)->Data(&Pcktdata, &PcktSze, &PcktIdx); + + /* Check if end of current image has been reached */ + if (PcktSze > 2U) + { + /* Check if this is the first packet in current image */ + if (PcktIdx == 0U) + { + /* Set the packet start index */ + payload_header[1] ^= 0x01U; + } + + RemainData = PcktSze; + + /* fill the Transmit buffer */ + while (RemainData > 0U) + { + packet[((DataOffset + 0U) * i)] = payload_header[0]; + packet[((DataOffset + 0U) * i) + 1U] = payload_header[1]; + if (RemainData > pdev->ep_in[UVC_IN_EP & 0xFU].maxpacket) + { + DataOffset = pdev->ep_in[UVC_IN_EP & 0xFU].maxpacket; + (void)USBD_memcpy((packet + ((DataOffset + 0U) * i) + 2U), + Pcktdata + ((DataOffset - 2U) * i), (DataOffset - 2U)); + + RemainData -= DataOffset; + i++; + } + else + { + (void)USBD_memcpy((packet + ((DataOffset + 0U) * i) + 2U), + Pcktdata + ((DataOffset - 2U) * i), (RemainData - 2U)); + + RemainData = 0U; + } + } + } + else + { + /* Add the packet header */ + packet[0] = payload_header[0]; + packet[1] = payload_header[1]; + } + + /* Transmit the packet on Endpoint */ + (void)USBD_LL_Transmit(pdev, (uint8_t)(epnum | 0x80U), + (uint8_t *)&packet, (uint32_t)PcktSze); + } + + /* Exit with no error code */ + return (uint8_t) USBD_OK; +} + +/** + * @brief USBD_VIDEO_SOF + * handle SOF event + * @param pdev: device instance + * @retval status + */ +static uint8_t USBD_VIDEO_SOF(USBD_HandleTypeDef *pdev) +{ + USBD_VIDEO_HandleTypeDef *hVIDEO = (USBD_VIDEO_HandleTypeDef *) pdev->pClassData; + uint8_t payload[2] = {0x02U, 0x00U}; + + /* Check if the Streaming has already been started by SetInterface AltSetting 1 */ + if (hVIDEO->uvc_state == UVC_PLAY_STATUS_READY) + { + /* Transmit the first packet indicating that Streaming is starting */ + (void)USBD_LL_Transmit(pdev, UVC_IN_EP, (uint8_t *)payload, 2U); + + /* Enable Streaming state */ + hVIDEO->uvc_state = UVC_PLAY_STATUS_STREAMING; + } + + /* Exit with no error code */ + return (uint8_t)USBD_OK; +} + +/** + * @brief USBD_VIDEO_IsoINIncomplete + * handle data ISO IN Incomplete event + * @param pdev: device instance + * @param epnum: endpoint index + * @retval status + */ +static uint8_t USBD_VIDEO_IsoINIncomplete(USBD_HandleTypeDef *pdev, uint8_t epnum) +{ + UNUSED(pdev); + UNUSED(epnum); + + return (uint8_t)USBD_OK; +} + +/** + * @brief VIDEO_Req_GetCurrent + * Handles the GET_CUR VIDEO control request. + * @param pdev: instance + * @param req: setup class request + * @retval status + */ +static void VIDEO_REQ_GetCurrent(USBD_HandleTypeDef *pdev, USBD_SetupReqTypedef *req) +{ + USBD_VIDEO_HandleTypeDef *hVIDEO; + hVIDEO = (USBD_VIDEO_HandleTypeDef *)(pdev->pClassData); + static __IO uint8_t EntityStatus[8] = {0}; + + /* Reset buffer to zeros */ + (void) USBD_memset(hVIDEO->control.data, 0, USB_MAX_EP0_SIZE); + + /* Manage Video Control interface requests */ + if (LOBYTE(req->wIndex) == 0x00U) + { + if (HIBYTE(req->wValue) == 0x02U) + { + /* Get the status of the current requested Entity */ + EntityStatus[0] = 0x06U; + + /* Send current status */ + (void) USBD_CtlSendData(pdev, (uint8_t *)&EntityStatus, 1U); + } + else + { + /* Unknown request */ + USBD_CtlError(pdev, req); + } + } + /* Manage Video Streaming interface requests */ + else + { + if (LOBYTE(req->wValue) == (uint8_t)VS_PROBE_CONTROL) + { + /* Update bPreferedVersion, bMinVersion and bMaxVersion which must be set only by Device */ + video_Probe_Control.bPreferedVersion = 0x00U; + video_Probe_Control.bMinVersion = 0x00U; + video_Probe_Control.bMaxVersion = 0x00U; + video_Probe_Control.dwMaxVideoFrameSize = UVC_MAX_FRAME_SIZE; + + video_Probe_Control.dwClockFrequency = 0x02DC6C00U; + + if (pdev->dev_speed == USBD_SPEED_HIGH) + { + video_Probe_Control.dwFrameInterval = (UVC_INTERVAL(UVC_CAM_FPS_HS)); + video_Probe_Control.dwMaxPayloadTransferSize = UVC_ISO_HS_MPS; + } + else + { + video_Probe_Control.dwFrameInterval = (UVC_INTERVAL(UVC_CAM_FPS_FS)); + video_Probe_Control.dwMaxPayloadTransferSize = UVC_ISO_FS_MPS; + } + + /* Probe Request */ + (void)USBD_CtlSendData(pdev, (uint8_t *)&video_Probe_Control, + MIN(req->wLength, sizeof(USBD_VideoControlTypeDef))); + } + else if (LOBYTE(req->wValue) == (uint8_t)VS_COMMIT_CONTROL) + { + if (pdev->dev_speed == USBD_SPEED_HIGH) + { + video_Commit_Control.dwFrameInterval = (UVC_INTERVAL(UVC_CAM_FPS_HS)); + video_Commit_Control.dwMaxPayloadTransferSize = UVC_ISO_HS_MPS; + } + else + { + video_Commit_Control.dwFrameInterval = (UVC_INTERVAL(UVC_CAM_FPS_FS)); + video_Commit_Control.dwMaxPayloadTransferSize = UVC_ISO_FS_MPS; + } + + /* Commit Request */ + (void)USBD_CtlSendData(pdev, (uint8_t *)&video_Commit_Control, + MIN(req->wLength, sizeof(USBD_VideoControlTypeDef))); + } + else + { + /* Send the current state */ + (void) USBD_CtlSendData(pdev, hVIDEO->control.data, + MIN(req->wLength, USB_MAX_EP0_SIZE)); + } + } +} + +/** + * @brief VIDEO_Req_SetCurrent + * Handles the SET_CUR VIDEO control request. + * @param pdev: instance + * @param req: setup class request + * @retval status + */ +static void VIDEO_REQ_SetCurrent(USBD_HandleTypeDef *pdev, USBD_SetupReqTypedef *req) +{ + USBD_VIDEO_HandleTypeDef *hVIDEO = (USBD_VIDEO_HandleTypeDef *)(pdev->pClassData); + + /* Check that the request has control data */ + if (req->wLength > 0U) + { + /* Prepare the reception of the buffer over EP0 */ + if (LOBYTE(req->wValue) == (uint8_t)VS_PROBE_CONTROL) + { + /* Probe Request */ + (void) USBD_CtlPrepareRx(pdev, (uint8_t *)&video_Probe_Control, + MIN(req->wLength, sizeof(USBD_VideoControlTypeDef))); + } + else if (LOBYTE(req->wValue) == (uint8_t)VS_COMMIT_CONTROL) + { + /* Commit Request */ + (void) USBD_CtlPrepareRx(pdev, (uint8_t *)&video_Commit_Control, + MIN(req->wLength, sizeof(USBD_VideoControlTypeDef))); + } + else + { + /* Prepare the reception of the buffer over EP0 */ + (void) USBD_CtlPrepareRx(pdev, hVIDEO->control.data, + MIN(req->wLength, USB_MAX_EP0_SIZE)); + } + } +} + +/** + * @brief USBD_VIDEO_GetFSCfgDesc + * return configuration descriptor + * @param length : pointer data length + * @retval pointer to descriptor buffer + */ +static uint8_t *USBD_VIDEO_GetFSCfgDesc(uint16_t *length) +{ + USBD_EpDescTypedef *pEpDesc = USBD_VIDEO_GetEpDesc(USBD_VIDEO_CfgDesc, UVC_IN_EP); + USBD_VIDEO_VSFrameDescTypeDef *pVSFrameDesc = USBD_VIDEO_GetVSFrameDesc(USBD_VIDEO_CfgDesc); + + if (pEpDesc != NULL) + { + pEpDesc->wMaxPacketSize = UVC_ISO_FS_MPS; + } + + if (pVSFrameDesc != NULL) + { + pVSFrameDesc->dwMinBitRate = UVC_MIN_BIT_RATE(UVC_CAM_FPS_FS); + pVSFrameDesc->dwMaxBitRate = UVC_MAX_BIT_RATE(UVC_CAM_FPS_FS); + pVSFrameDesc->dwDefaultFrameInterval = UVC_INTERVAL(UVC_CAM_FPS_FS); + pVSFrameDesc->dwMinFrameInterval = UVC_INTERVAL(UVC_CAM_FPS_FS); + } + + *length = (uint16_t)(sizeof(USBD_VIDEO_CfgDesc)); + return USBD_VIDEO_CfgDesc; +} + +/** + * @brief USBD_VIDEO_GetHSCfgDesc + * return configuration descriptor + * @param length : pointer data length + * @retval pointer to descriptor buffer + */ +static uint8_t *USBD_VIDEO_GetHSCfgDesc(uint16_t *length) +{ + USBD_EpDescTypedef *pEpDesc = USBD_VIDEO_GetEpDesc(USBD_VIDEO_CfgDesc, UVC_IN_EP); + USBD_VIDEO_VSFrameDescTypeDef *pVSFrameDesc = USBD_VIDEO_GetVSFrameDesc(USBD_VIDEO_CfgDesc); + + if (pEpDesc != NULL) + { + pEpDesc->wMaxPacketSize = UVC_ISO_HS_MPS; + } + + if (pVSFrameDesc != NULL) + { + pVSFrameDesc->dwMinBitRate = UVC_MIN_BIT_RATE(UVC_CAM_FPS_HS); + pVSFrameDesc->dwMaxBitRate = UVC_MAX_BIT_RATE(UVC_CAM_FPS_HS); + pVSFrameDesc->dwDefaultFrameInterval = UVC_INTERVAL(UVC_CAM_FPS_HS); + pVSFrameDesc->dwMinFrameInterval = UVC_INTERVAL(UVC_CAM_FPS_HS); + } + + *length = (uint16_t)(sizeof(USBD_VIDEO_CfgDesc)); + return USBD_VIDEO_CfgDesc; +} + +/** + * @brief USBD_VIDEO_GetOtherSpeedCfgDesc + * return configuration descriptor + * @param length : pointer data length + * @retval pointer to descriptor buffer + */ +static uint8_t *USBD_VIDEO_GetOtherSpeedCfgDesc(uint16_t *length) +{ + USBD_EpDescTypedef *pEpDesc = USBD_VIDEO_GetEpDesc(USBD_VIDEO_CfgDesc, UVC_IN_EP); + USBD_VIDEO_VSFrameDescTypeDef *pVSFrameDesc = USBD_VIDEO_GetVSFrameDesc(USBD_VIDEO_CfgDesc); + + if (pEpDesc != NULL) + { + pEpDesc->wMaxPacketSize = UVC_ISO_FS_MPS; + } + + if (pVSFrameDesc != NULL) + { + pVSFrameDesc->dwMinBitRate = UVC_MIN_BIT_RATE(UVC_CAM_FPS_FS); + pVSFrameDesc->dwMaxBitRate = UVC_MAX_BIT_RATE(UVC_CAM_FPS_FS); + pVSFrameDesc->dwDefaultFrameInterval = UVC_INTERVAL(UVC_CAM_FPS_FS); + pVSFrameDesc->dwMinFrameInterval = UVC_INTERVAL(UVC_CAM_FPS_FS); + } + + *length = (uint16_t)(sizeof(USBD_VIDEO_CfgDesc)); + return USBD_VIDEO_CfgDesc; +} + +/** + * @brief DeviceQualifierDescriptor + * return Device Qualifier descriptor + * @param length : pointer data length + * @retval pointer to descriptor buffer + */ +static uint8_t *USBD_VIDEO_GetDeviceQualifierDesc(uint16_t *length) +{ + *length = (uint16_t)(sizeof(USBD_VIDEO_DeviceQualifierDesc)); + return USBD_VIDEO_DeviceQualifierDesc; +} + +/** + * @brief USBD_VIDEO_GetNextDesc + * This function return the next descriptor header + * @param buf: Buffer where the descriptor is available + * @param ptr: data pointer inside the descriptor + * @retval next header + */ +static USBD_VIDEO_DescHeader_t *USBD_VIDEO_GetNextDesc(uint8_t *pbuf, uint16_t *ptr) +{ + USBD_VIDEO_DescHeader_t *pnext = (USBD_VIDEO_DescHeader_t *)(void *)pbuf; + + *ptr += pnext->bLength; + pnext = (USBD_VIDEO_DescHeader_t *)(void *)(pbuf + pnext->bLength); + + return (pnext); +} + +/** + * @brief USBD_VIDEO_GetVSFrameDesc + * This function return the Video Endpoint descriptor + * @param pdev: device instance + * @param pConfDesc: pointer to Bos descriptor + * @retval pointer to video endpoint descriptor + */ +static void *USBD_VIDEO_GetVSFrameDesc(uint8_t *pConfDesc) +{ + USBD_VIDEO_DescHeader_t *pdesc = (USBD_VIDEO_DescHeader_t *)(void *)pConfDesc; + USBD_ConfigDescTypedef *desc = (USBD_ConfigDescTypedef *)(void *)pConfDesc; + USBD_VIDEO_VSFrameDescTypeDef *pVSFrameDesc = NULL; + uint16_t ptr; + + if (desc->wTotalLength > desc->bLength) + { + ptr = desc->bLength; + + while (ptr < desc->wTotalLength) + { + pdesc = USBD_VIDEO_GetNextDesc((uint8_t *)pdesc, &ptr); + + if (((pdesc->bDescriptorSubType == VS_FRAME_MJPEG) || + (pdesc->bDescriptorSubType == VS_FRAME_UNCOMPRESSED)) && + (pdesc->bLength == VS_FRAME_DESC_SIZE)) + { + pVSFrameDesc = (USBD_VIDEO_VSFrameDescTypeDef *)(void *)pdesc; + break; + } + } + } + + return (void *)pVSFrameDesc; +} + +/** + * @brief USBD_VIDEO_GetEpDesc + * This function return the Video Endpoint descriptor + * @param pdev: device instance + * @param pConfDesc: pointer to Bos descriptor + * @param EpAddr: endpoint address + * @retval pointer to video endpoint descriptor + */ +static void *USBD_VIDEO_GetEpDesc(uint8_t *pConfDesc, uint8_t EpAddr) +{ + USBD_VIDEO_DescHeader_t *pdesc = (USBD_VIDEO_DescHeader_t *)(void *)pConfDesc; + USBD_ConfigDescTypedef *desc = (USBD_ConfigDescTypedef *)(void *)pConfDesc; + USBD_EpDescTypedef *pEpDesc = NULL; + uint16_t ptr; + + if (desc->wTotalLength > desc->bLength) + { + ptr = desc->bLength; + + while (ptr < desc->wTotalLength) + { + pdesc = USBD_VIDEO_GetNextDesc((uint8_t *)pdesc, &ptr); + + if (pdesc->bDescriptorType == USB_DESC_TYPE_ENDPOINT) + { + pEpDesc = (USBD_EpDescTypedef *)(void *)pdesc; + + if (pEpDesc->bEndpointAddress == EpAddr) + { + break; + } + else + { + pEpDesc = NULL; + } + } + } + } + + return (void *)pEpDesc; +} + +/** + * @brief USBD_VIDEO_RegisterInterface + * @param pdev: instance + * @param fops: VIDEO interface callback + * @retval status + */ +uint8_t USBD_VIDEO_RegisterInterface(USBD_HandleTypeDef *pdev, USBD_VIDEO_ItfTypeDef *fops) +{ + /* Check if the FOPS pointer is valid */ + if (fops == NULL) + { + return (uint8_t)USBD_FAIL; + } + + /* Assign the FOPS pointer */ + pdev->pUserData = fops; + + /* Exit with no error code */ + return (uint8_t)USBD_OK; +} + +/** + * @} + */ + + +/** + * @} + */ + + +/** + * @} + */ + +/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ + + diff --git a/system/Middlewares/ST/STM32_USB_Device_Library/Class/VIDEO/Src/usbd_video_if_template.c b/system/Middlewares/ST/STM32_USB_Device_Library/Class/VIDEO/Src/usbd_video_if_template.c new file mode 100644 index 0000000000..70b8d3aacb --- /dev/null +++ b/system/Middlewares/ST/STM32_USB_Device_Library/Class/VIDEO/Src/usbd_video_if_template.c @@ -0,0 +1,296 @@ +/** + ****************************************************************************** + * @file usbd_video_if_template.c + * @author MCD Application Team + * @brief Template file for Video Interface application layer functions + ****************************************************************************** + * @attention + * + *

© Copyright (c) 2020 STMicroelectronics. + * All rights reserved.

+ * + * This software component is licensed by ST under Ultimate Liberty license + * SLA0044, the "License"; You may not use this file except in compliance with + * the License. You may obtain a copy of the License at: + * www.st.com/SLA0044 + * + ****************************************************************************** + */ + +/* Includes ------------------------------------------------------------------*/ +#include "usbd_video_if.h" + +/* Include you image binary file here + Binary image template shall provide: + - tImagesList: table containing pointers to all images + - tImagesSizes: table containing sizes of each image respectively + - img_count: global image counter variable + - IMG_NBR: Total image number + + To generate such file, it is possible to use tools converting video to MJPEG then to JPEG images. + */ +/* #include "img_bin.h" */ + +/* USER CODE BEGIN INCLUDE */ + +/* USER CODE END INCLUDE */ + +/* Private typedef -----------------------------------------------------------*/ +/* Private define ------------------------------------------------------------*/ +/* Private macro -------------------------------------------------------------*/ + +/* USER CODE BEGIN PV */ +/* Private variables ---------------------------------------------------------*/ + +/* USER CODE END PV */ + +/** @addtogroup STM32_USB_OTG_DEVICE_LIBRARY + * @brief Usb device library. + * @{ + */ + +/** @addtogroup USBD_VIDEO_IF + * @{ + */ + +/** @defgroup USBD_VIDEO_IF_Private_TypesDefinitions + * @brief Private types. + * @{ + */ + +/* USER CODE BEGIN PRIVATE_TYPES */ + +/* USER CODE END PRIVATE_TYPES */ + +/** + * @} + */ + +/** @defgroup USBD_VIDEO_IF_Private_Defines + * @brief Private defines. + * @{ + */ + +/* USER CODE BEGIN PRIVATE_DEFINES */ + +/* USER CODE END PRIVATE_DEFINES */ + +/** + * @} + */ + +/** @defgroup USBD_VIDEO_IF_Private_Macros + * @brief Private macros. + * @{ + */ + +/* USER CODE BEGIN PRIVATE_MACRO */ + +/* USER CODE END PRIVATE_MACRO */ + +/** + * @} + */ + +/** @defgroup USBD_VIDEO_IF_Private_Variables + * @brief Private variables. + * @{ + */ + +/* USER CODE BEGIN PRIVATE_VARIABLES */ + +/* USER CODE END PRIVATE_VARIABLES */ + +/** + * @} + */ + +/** @defgroup USBD_VIDEO_IF_Exported_Variables + * @brief Public variables. + * @{ + */ + + + +/* USER CODE BEGIN EXPORTED_VARIABLES */ + +/* USER CODE END EXPORTED_VARIABLES */ + +/** + * @} + */ + +/** @defgroup USBD_VIDEO_IF_Private_FunctionPrototypes + * @brief Private functions declaration. + * @{ + */ + +static int8_t VIDEO_Itf_Init(void); +static int8_t VIDEO_Itf_DeInit(void); +static int8_t VIDEO_Itf_Control(uint8_t cmd, uint8_t *pbuf, uint16_t length); +static int8_t VIDEO_Itf_Data(uint8_t **pbuf, uint16_t *psize, uint16_t *pcktidx); + + +/* USER CODE BEGIN PRIVATE_FUNCTIONS_DECLARATION */ + +/* USER CODE END PRIVATE_FUNCTIONS_DECLARATION */ + +/** + * @} + */ + +USBD_VIDEO_ItfTypeDef USBD_VIDEO_fops_FS = +{ + VIDEO_Itf_Init, + VIDEO_Itf_DeInit, + VIDEO_Itf_Control, + VIDEO_Itf_Data, +}; + +/* Private functions ---------------------------------------------------------*/ +/** + * @brief Initializes the VIDEO media low layer over USB FS IP + * @param VIDEOFreq: VIDEO frequency used to play the VIDEO stream. + * @param Volume: Initial volume level (from 0 (Mute) to 100 (Max)) + * @param options: Reserved for future use + * @retval USBD_OK if all operations are OK else USBD_FAIL + */ +static int8_t VIDEO_Itf_Init(void) +{ + /* + Add your initialization code here + */ + + return (0); +} + +/** + * @brief TEMPLATE_DeInit + * DeInitializes the UVC media low layer + * @param None + * @retval Result of the operation: USBD_OK if all operations are OK else USBD_FAIL + */ +static int8_t VIDEO_Itf_DeInit(void) +{ + /* + Add your deinitialization code here + */ + return (0); +} + + +/** + * @brief TEMPLATE_Control + * Manage the UVC class requests + * @param Cmd: Command code + * @param Buf: Buffer containing command data (request parameters) + * @param Len: Number of data to be sent (in bytes) + * @retval Result of the operation: USBD_OK if all operations are OK else USBD_FAIL + */ +static int8_t VIDEO_Itf_Control(uint8_t cmd, uint8_t *pbuf, uint16_t length) +{ + + return (0); +} + +/** + * @brief TEMPLATE_Data + * Manage the UVC data packets + * @param pbuf: pointer to the buffer data to be filled + * @param psize: pointer tot he current packet size to be filled + * @param pcktidx: pointer to the current packet index in the current image + * @retval Result of the operation: USBD_OK if all operations are OK else USBD_FAIL + */ +static int8_t VIDEO_Itf_Data(uint8_t **pbuf, uint16_t *psize, uint16_t *pcktidx) +{ + /* + Implementation of this function is mandatory to provide the video data to the USB video class + This function shall parse the MJPEG images and provide each time the buffer packet relative to + current packet index and its size. + If the packet is the first packet in the current MJPEG image, then packet size shall be zero and + the pbuf is ignored and pcktidx shall be zero. + Below is typical implementation of this function based on a binary image template. + + Binary image template shall provide: + - tImagesList: table containing pointers to all images + - tImagesSizes: table containing sizes of each image respectively + - img_count: global image counter variable + - IMG_NBR: Total image number + + To generate such file, it is possible to use tools converting video to MJPEG then to JPEG images. + + */ + const uint8_t *(*ImagePtr) = tImagesList; + uint32_t packet_count = (tImagesSizes[img_count]) / ((uint16_t)(UVC_PACKET_SIZE - (UVC_HEADER_PACKET_CNT * 2U))); + uint32_t packet_remainder = (tImagesSizes[img_count]) % ((uint16_t)(UVC_PACKET_SIZE - (UVC_HEADER_PACKET_CNT * 2U))); + static uint8_t packet_index = 0; + + /* Check if end of current image has been reached */ + if (packet_index < packet_count) + { + /* Set the current packet size */ + *psize = (uint16_t)UVC_PACKET_SIZE; + + /* Get the pointer to the next packet to be transmitted */ + *pbuf = (uint8_t *)(*(ImagePtr + img_count) + packet_index * ((uint16_t)(UVC_PACKET_SIZE - (UVC_HEADER_PACKET_CNT * 2U)))); + } + else if ((packet_index == packet_count)) + { + if (packet_remainder != 0U) + { + /* Get the pointer to the next packet to be transmitted */ + *pbuf = (uint8_t *)(*(ImagePtr + img_count) + packet_index * ((uint16_t)(UVC_PACKET_SIZE - (UVC_HEADER_PACKET_CNT * 2U)))); + + /* Set the current packet size */ + *psize = packet_remainder + (UVC_HEADER_PACKET_CNT * 2U); + } + else + { + packet_index++; + + /* New image to be started, send only the packet header */ + *psize = 2; + } + } + else + { + /* New image to be started, send only the packet header */ + *psize = 2; + } + + /* Update the packet index */ + *pcktidx = packet_index; + + /* Increment the packet count and check if it reached the end of current image buffer */ + if (packet_index++ >= (packet_count + 1)) + { + /* Reset the packet count to zero */ + packet_index = 0U; + + /* Move to the next image in the images table */ + + img_count++; + HAL_Delay(USBD_VIDEO_IMAGE_LAPS); + /* Check if images count has been reached, then reset to zero (go back to first image in circular loop) */ + if (img_count == IMG_NBR) + { + img_count = 0U; + } + } + + return (0); +} + +/* USER CODE BEGIN PRIVATE_FUNCTIONS_IMPLEMENTATION */ + +/* USER CODE END PRIVATE_FUNCTIONS_IMPLEMENTATION */ + +/** + * @} + */ + +/** + * @} + */ + +/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ diff --git a/system/Middlewares/ST/STM32_USB_Device_Library/Core/Inc/usbd_conf_template.h b/system/Middlewares/ST/STM32_USB_Device_Library/Core/Inc/usbd_conf_template.h index 85e18ab781..0527cf2758 100644 --- a/system/Middlewares/ST/STM32_USB_Device_Library/Core/Inc/usbd_conf_template.h +++ b/system/Middlewares/ST/STM32_USB_Device_Library/Core/Inc/usbd_conf_template.h @@ -44,50 +44,101 @@ extern "C" { * @{ */ -#define USBD_MAX_NUM_INTERFACES 1U -#define USBD_MAX_NUM_CONFIGURATION 1U -#define USBD_MAX_STR_DESC_SIZ 0x100U -#define USBD_SELF_POWERED 1U -#define USBD_DEBUG_LEVEL 2U +#define USBD_MAX_NUM_INTERFACES 1U +#define USBD_MAX_NUM_CONFIGURATION 1U +#define USBD_MAX_STR_DESC_SIZ 0x100U +#define USBD_SELF_POWERED 1U +#define USBD_DEBUG_LEVEL 2U /* ECM, RNDIS, DFU Class Config */ -#define USBD_SUPPORT_USER_STRING_DESC 1U +#define USBD_SUPPORT_USER_STRING_DESC 1U /* BillBoard Class Config */ -#define USBD_CLASS_USER_STRING_DESC 1U -#define USBD_CLASS_BOS_ENABLED 1U -#define USB_BB_MAX_NUM_ALT_MODE 0x2U +#define USBD_CLASS_USER_STRING_DESC 1U +#define USBD_CLASS_BOS_ENABLED 1U +#define USB_BB_MAX_NUM_ALT_MODE 0x2U /* MSC Class Config */ -#define MSC_MEDIA_PACKET 8192U +#define MSC_MEDIA_PACKET 8192U /* CDC Class Config */ -#define USBD_CDC_INTERVAL 2000U +#define USBD_CDC_INTERVAL 2000U /* DFU Class Config */ -#define USBD_DFU_MAX_ITF_NUM 1U -#define USBD_DFU_XFERS_IZE 1024U +#define USBD_DFU_MAX_ITF_NUM 1U +#define USBD_DFU_XFERS_IZE 1024U /* AUDIO Class Config */ -#define USBD_AUDIO_FREQ 22100U +#define USBD_AUDIO_FREQ 22100U + +/* CustomHID Class Config */ +#define CUSTOM_HID_HS_BINTERVAL 0x05U +#define CUSTOM_HID_FS_BINTERVAL 0x05U +#define USBD_CUSTOMHID_OUTREPORT_BUF_SIZE 0x02U +#define USBD_CUSTOM_HID_REPORT_DESC_SIZE 163U + +/* VIDEO Class Config */ +#define UVC_1_1 /* #define UVC_1_0 */ + +/* To be used only with YUY2 and NV12 Video format, shouldn't be defined for MJPEG format */ +#define USBD_UVC_FORMAT_UNCOMPRESSED + +#ifdef USBD_UVC_FORMAT_UNCOMPRESSED +#define UVC_BITS_PER_PIXEL 12U +#define UVC_UNCOMPRESSED_GUID UVC_GUID_NV12 /* UVC_GUID_YUY2 */ + +/* refer to Table 3-18 Color Matching Descriptor video class v1.1 */ +#define UVC_COLOR_PRIMARIE 0x01U +#define UVC_TFR_CHARACTERISTICS 0x01U +#define UVC_MATRIX_COEFFICIENTS 0x04U +#endif + +/* Video Stream frame width and height */ +#define UVC_WIDTH 176U +#define UVC_HEIGHT 144U + +/* bEndpointAddress in Endpoint Descriptor */ +#define UVC_IN_EP 0x81U + +#define UVC_CAM_FPS_FS 10U +#define UVC_CAM_FPS_HS 5U + +#define UVC_ISO_FS_MPS 512U +#define UVC_ISO_HS_MPS 512U + +#define UVC_PACKET_SIZE UVC_ISO_FS_MPS +/* To be used with Device Only IP supporting double buffer mode */ +/* #define UVC_HEADER_PACKET_CNT 0x02U */ +/* #define UVC_PACKET_SIZE (UVC_ISO_FS_MPS * UVC_HEADER_PACKET_CNT) */ + +#define UVC_MAX_FRAME_SIZE (UVC_WIDTH * UVC_HEIGHT * 16U / 8U) /** @defgroup USBD_Exported_Macros * @{ */ -/* Memory management macros */ -#define USBD_malloc malloc -#define USBD_free free -#define USBD_memset memset -#define USBD_memcpy memcpy -#define USBD_Delay HAL_Delay +/* Memory management macros make sure to use static memory allocation */ +/** Alias for memory allocation. */ +#define USBD_malloc (void *)USBD_static_malloc + +/** Alias for memory release. */ +#define USBD_free USBD_static_free + +/** Alias for memory set. */ +#define USBD_memset memset + +/** Alias for memory copy. */ +#define USBD_memcpy memcpy + +/** Alias for delay. */ +#define USBD_Delay HAL_Delay /* DEBUG macros */ #if (USBD_DEBUG_LEVEL > 0U) #define USBD_UsrLog(...) do { \ - printf(__VA_ARGS__); \ - printf("\n"); \ -} while (0) + printf(__VA_ARGS__); \ + printf("\n"); \ + } while (0) #else #define USBD_UsrLog(...) do {} while (0) #endif @@ -95,20 +146,20 @@ extern "C" { #if (USBD_DEBUG_LEVEL > 1U) #define USBD_ErrLog(...) do { \ - printf("ERROR: ") ; \ - printf(__VA_ARGS__); \ - printf("\n"); \ -} while (0) + printf("ERROR: ") ; \ + printf(__VA_ARGS__); \ + printf("\n"); \ + } while (0) #else #define USBD_ErrLog(...) do {} while (0) #endif #if (USBD_DEBUG_LEVEL > 2U) #define USBD_DbgLog(...) do { \ - printf("DEBUG : ") ; \ - printf(__VA_ARGS__); \ - printf("\n"); \ -} while (0) + printf("DEBUG : ") ; \ + printf(__VA_ARGS__); \ + printf("\n"); \ + } while (0) #else #define USBD_DbgLog(...) do {} while (0) #endif @@ -149,6 +200,9 @@ extern "C" { /** @defgroup USBD_CONF_Exported_FunctionsPrototype * @{ */ +/* Exported functions -------------------------------------------------------*/ +void *USBD_static_malloc(uint32_t size); +void USBD_static_free(void *p); /** * @} */ diff --git a/system/Middlewares/ST/STM32_USB_Device_Library/Core/Inc/usbd_core.h b/system/Middlewares/ST/STM32_USB_Device_Library/Core/Inc/usbd_core.h index c7d2ba39e5..92f72705fd 100644 --- a/system/Middlewares/ST/STM32_USB_Device_Library/Core/Inc/usbd_core.h +++ b/system/Middlewares/ST/STM32_USB_Device_Library/Core/Inc/usbd_core.h @@ -149,8 +149,8 @@ void USBD_LL_Delay(uint32_t Delay); */ /** -* @} -*/ + * @} + */ /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ diff --git a/system/Middlewares/ST/STM32_USB_Device_Library/Core/Inc/usbd_ctlreq.h b/system/Middlewares/ST/STM32_USB_Device_Library/Core/Inc/usbd_ctlreq.h index f973a8b1b2..3495a97870 100644 --- a/system/Middlewares/ST/STM32_USB_Device_Library/Core/Inc/usbd_ctlreq.h +++ b/system/Middlewares/ST/STM32_USB_Device_Library/Core/Inc/usbd_ctlreq.h @@ -96,8 +96,8 @@ void USBD_GetString(uint8_t *desc, uint8_t *unicode, uint16_t *len); */ /** -* @} -*/ + * @} + */ /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ diff --git a/system/Middlewares/ST/STM32_USB_Device_Library/Core/Inc/usbd_def.h b/system/Middlewares/ST/STM32_USB_Device_Library/Core/Inc/usbd_def.h index 0463e2f31f..4c4de6899a 100644 --- a/system/Middlewares/ST/STM32_USB_Device_Library/Core/Inc/usbd_def.h +++ b/system/Middlewares/ST/STM32_USB_Device_Library/Core/Inc/usbd_def.h @@ -61,6 +61,10 @@ extern "C" { #define USBD_SELF_POWERED 1U #endif /*USBD_SELF_POWERED */ +#ifndef USBD_MAX_POWER +#define USBD_MAX_POWER 0x32U /* 100 mA */ +#endif /* USBD_MAX_POWER */ + #ifndef USBD_SUPPORT_USER_STRING_DESC #define USBD_SUPPORT_USER_STRING_DESC 0U #endif /* USBD_SUPPORT_USER_STRING_DESC */ @@ -114,6 +118,7 @@ extern "C" { #define USB_DESC_TYPE_ENDPOINT 0x05U #define USB_DESC_TYPE_DEVICE_QUALIFIER 0x06U #define USB_DESC_TYPE_OTHER_SPEED_CONFIGURATION 0x07U +#define USB_DESC_TYPE_IAD 0x0BU #define USB_DESC_TYPE_BOS 0x0FU #define USB_CONFIG_REMOTE_WAKEUP 0x02U @@ -125,6 +130,11 @@ extern "C" { #define USB_DEVICE_CAPABITY_TYPE 0x10U +#define USB_CONF_DESC_SIZE 0x09U +#define USB_IF_DESC_SIZE 0x09U +#define USB_EP_DESC_SIZE 0x07U +#define USB_IAD_DESC_SIZE 0x08U + #define USB_HS_MAX_PACKET_SIZE 512U #define USB_FS_MAX_PACKET_SIZE 64U #define USB_MAX_EP0_SIZE 64U @@ -150,7 +160,6 @@ extern "C" { #define USBD_EP_TYPE_BULK 0x02U #define USBD_EP_TYPE_INTR 0x03U - /** * @} */ @@ -173,8 +182,7 @@ typedef struct { uint8_t bLength; uint8_t bDescriptorType; - uint8_t wDescriptorLengthLow; - uint8_t wDescriptorLengthHigh; + uint16_t wTotalLength; uint8_t bNumInterfaces; uint8_t bConfigurationValue; uint8_t iConfiguration; @@ -190,6 +198,15 @@ typedef struct uint8_t bNumDeviceCaps; } USBD_BosDescTypedef; +typedef struct +{ + uint8_t bLength; + uint8_t bDescriptorType; + uint8_t bEndpointAddress; + uint8_t bmAttributes; + uint16_t wMaxPacketSize; + uint8_t bInterval; +} USBD_EpDescTypedef; struct _USBD_HandleTypeDef; @@ -274,10 +291,10 @@ typedef struct _USBD_HandleTypeDef USBD_SpeedTypeDef dev_speed; USBD_EndpointTypeDef ep_in[16]; USBD_EndpointTypeDef ep_out[16]; - uint32_t ep0_state; + __IO uint32_t ep0_state; uint32_t ep0_data_len; - uint8_t dev_state; - uint8_t dev_old_state; + __IO uint8_t dev_state; + __IO uint8_t dev_old_state; uint8_t dev_address; uint8_t dev_connection_status; uint8_t dev_test_mode; @@ -317,11 +334,21 @@ __STATIC_INLINE uint16_t SWAPBYTE(uint8_t *addr) return _SwapVal; } +#ifndef LOBYTE #define LOBYTE(x) ((uint8_t)((x) & 0x00FFU)) +#endif + +#ifndef HIBYTE #define HIBYTE(x) ((uint8_t)(((x) & 0xFF00U) >> 8U)) +#endif + +#ifndef MIN #define MIN(a, b) (((a) < (b)) ? (a) : (b)) -#define MAX(a, b) (((a) > (b)) ? (a) : (b)) +#endif +#ifndef MAX +#define MAX(a, b) (((a) > (b)) ? (a) : (b)) +#endif #if defined ( __GNUC__ ) #ifndef __weak @@ -388,6 +415,6 @@ __STATIC_INLINE uint16_t SWAPBYTE(uint8_t *addr) */ /** -* @} -*/ + * @} + */ /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ diff --git a/system/Middlewares/ST/STM32_USB_Device_Library/Core/Inc/usbd_ioreq.h b/system/Middlewares/ST/STM32_USB_Device_Library/Core/Inc/usbd_ioreq.h index b7159d53b6..c896b5ae33 100644 --- a/system/Middlewares/ST/STM32_USB_Device_Library/Core/Inc/usbd_ioreq.h +++ b/system/Middlewares/ST/STM32_USB_Device_Library/Core/Inc/usbd_ioreq.h @@ -109,6 +109,6 @@ uint32_t USBD_GetRxCount(USBD_HandleTypeDef *pdev, uint8_t ep_addr); */ /** -* @} -*/ + * @} + */ /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ diff --git a/system/Middlewares/ST/STM32_USB_Device_Library/Core/Src/usbd_conf_template.c b/system/Middlewares/ST/STM32_USB_Device_Library/Core/Src/usbd_conf_template.c index 67b70aa0e3..381988b4fe 100644 --- a/system/Middlewares/ST/STM32_USB_Device_Library/Core/Src/usbd_conf_template.c +++ b/system/Middlewares/ST/STM32_USB_Device_Library/Core/Src/usbd_conf_template.c @@ -21,6 +21,7 @@ /* Includes ------------------------------------------------------------------*/ #include "usbd_core.h" +#include "usbd_hid.h" /* Include class header file */ /* Private typedef -----------------------------------------------------------*/ /* Private define ------------------------------------------------------------*/ /* Private macro -------------------------------------------------------------*/ @@ -168,14 +169,14 @@ uint8_t USBD_LL_IsStallEP(USBD_HandleTypeDef *pdev, uint8_t ep_addr) /** * @brief Assigns a USB address to the device. * @param pdev: Device handle - * @param ep_addr: Endpoint Number + * @param dev_addr: Endpoint Number * @retval USBD Status */ USBD_StatusTypeDef USBD_LL_SetUSBAddress(USBD_HandleTypeDef *pdev, uint8_t dev_addr) { UNUSED(pdev); - UNUSED(ep_addr); + UNUSED(dev_addr); return USBD_OK; } @@ -223,7 +224,7 @@ USBD_StatusTypeDef USBD_LL_PrepareReceive(USBD_HandleTypeDef *pdev, * @brief Returns the last transferred packet size. * @param pdev: Device handle * @param ep_addr: Endpoint Number - * @retval Recived Data Size + * @retval Received Data Size */ uint32_t USBD_LL_GetRxDataSize(USBD_HandleTypeDef *pdev, uint8_t ep_addr) { @@ -233,6 +234,27 @@ uint32_t USBD_LL_GetRxDataSize(USBD_HandleTypeDef *pdev, uint8_t ep_addr) return 0U; } +/** + * @brief Static single allocation. + * @param size: Size of allocated memory + * @retval None + */ +void *USBD_static_malloc(uint32_t size) +{ + static uint32_t mem[(sizeof(USBD_HID_HandleTypeDef) / 4) + 1]; /* On 32-bit boundary */ + return mem; +} + +/** + * @brief Dummy memory free + * @param p: Pointer to allocated memory address + * @retval None + */ +void USBD_static_free(void *p) +{ + +} + /** * @brief Delays routine for the USB Device Library. * @param Delay: Delay in ms diff --git a/system/Middlewares/ST/STM32_USB_Device_Library/Core/Src/usbd_core.c b/system/Middlewares/ST/STM32_USB_Device_Library/Core/Src/usbd_core.c index 6021cc0784..a6154ea839 100644 --- a/system/Middlewares/ST/STM32_USB_Device_Library/Core/Src/usbd_core.c +++ b/system/Middlewares/ST/STM32_USB_Device_Library/Core/Src/usbd_core.c @@ -21,71 +21,71 @@ #include "usbd_core.h" /** @addtogroup STM32_USBD_DEVICE_LIBRARY -* @{ -*/ + * @{ + */ /** @defgroup USBD_CORE -* @brief usbd core module -* @{ -*/ + * @brief usbd core module + * @{ + */ /** @defgroup USBD_CORE_Private_TypesDefinitions -* @{ -*/ + * @{ + */ /** -* @} -*/ + * @} + */ /** @defgroup USBD_CORE_Private_Defines -* @{ -*/ + * @{ + */ /** -* @} -*/ + * @} + */ /** @defgroup USBD_CORE_Private_Macros -* @{ -*/ + * @{ + */ /** -* @} -*/ + * @} + */ /** @defgroup USBD_CORE_Private_FunctionPrototypes -* @{ -*/ + * @{ + */ /** -* @} -*/ + * @} + */ /** @defgroup USBD_CORE_Private_Variables -* @{ -*/ + * @{ + */ /** -* @} -*/ + * @} + */ /** @defgroup USBD_CORE_Private_Functions -* @{ -*/ + * @{ + */ /** -* @brief USBD_Init -* Initializes the device stack and load the class driver -* @param pdev: device instance -* @param pdesc: Descriptor structure address -* @param id: Low level core index -* @retval None -*/ + * @brief USBD_Init + * Initializes the device stack and load the class driver + * @param pdev: device instance + * @param pdesc: Descriptor structure address + * @param id: Low level core index + * @retval None + */ USBD_StatusTypeDef USBD_Init(USBD_HandleTypeDef *pdev, USBD_DescriptorsTypeDef *pdesc, uint8_t id) { @@ -100,16 +100,10 @@ USBD_StatusTypeDef USBD_Init(USBD_HandleTypeDef *pdev, return USBD_FAIL; } - /* Unlink previous class */ - if (pdev->pClass != NULL) - { - pdev->pClass = NULL; - } - - if (pdev->pConfDesc != NULL) - { - pdev->pConfDesc = NULL; - } + /* Unlink previous class resources */ + pdev->pClass = NULL; + pdev->pUserData = NULL; + pdev->pConfDesc = NULL; /* Assign USBD Descriptors */ if (pdesc != NULL) @@ -128,15 +122,18 @@ USBD_StatusTypeDef USBD_Init(USBD_HandleTypeDef *pdev, } /** -* @brief USBD_DeInit -* Re-Initialize th device library -* @param pdev: device instance -* @retval status: status -*/ + * @brief USBD_DeInit + * Re-Initialize the device library + * @param pdev: device instance + * @retval status: status + */ USBD_StatusTypeDef USBD_DeInit(USBD_HandleTypeDef *pdev) { USBD_StatusTypeDef ret; + /* Disconnect the USB Device */ + (void)USBD_LL_Stop(pdev); + /* Set Default State */ pdev->dev_state = USBD_STATE_DEFAULT; @@ -144,22 +141,15 @@ USBD_StatusTypeDef USBD_DeInit(USBD_HandleTypeDef *pdev) if (pdev->pClass != NULL) { pdev->pClass->DeInit(pdev, (uint8_t)pdev->dev_config); + pdev->pClass = NULL; + pdev->pUserData = NULL; } - if (pdev->pConfDesc != NULL) - { - pdev->pConfDesc = NULL; - } - - /* Stop the low level driver */ - ret = USBD_LL_Stop(pdev); - - if (ret != USBD_OK) - { - return ret; - } + /* Free Device descriptors resources */ + pdev->pDesc = NULL; + pdev->pConfDesc = NULL; - /* Initialize low level driver */ + /* DeInitialize low level driver */ ret = USBD_LL_DeInit(pdev); return ret; @@ -188,13 +178,18 @@ USBD_StatusTypeDef USBD_RegisterClass(USBD_HandleTypeDef *pdev, USBD_ClassTypeDe pdev->pClass = pclass; /* Get Device Configuration Descriptor */ -#ifdef USE_USB_FS - pdev->pConfDesc = (void *)pdev->pClass->GetFSConfigDescriptor(&len); -#else /* USE_USB_HS */ - pdev->pConfDesc = (void *)pdev->pClass->GetHSConfigDescriptor(&len); +#ifdef USE_USB_HS + if (pdev->pClass->GetHSConfigDescriptor != NULL) + { + pdev->pConfDesc = (void *)pdev->pClass->GetHSConfigDescriptor(&len); + } +#else /* Default USE_USB_FS */ + if (pdev->pClass->GetFSConfigDescriptor != NULL) + { + pdev->pConfDesc = (void *)pdev->pClass->GetFSConfigDescriptor(&len); + } #endif /* USE_USB_FS */ - return USBD_OK; } @@ -218,31 +213,24 @@ USBD_StatusTypeDef USBD_Start(USBD_HandleTypeDef *pdev) */ USBD_StatusTypeDef USBD_Stop(USBD_HandleTypeDef *pdev) { - USBD_StatusTypeDef ret; + /* Disconnect USB Device */ + (void)USBD_LL_Stop(pdev); /* Free Class Resources */ if (pdev->pClass != NULL) { - pdev->pClass->DeInit(pdev, (uint8_t)pdev->dev_config); + (void)pdev->pClass->DeInit(pdev, (uint8_t)pdev->dev_config); } - if (pdev->pConfDesc != NULL) - { - pdev->pConfDesc = NULL; - } - - /* Stop the low level driver */ - ret = USBD_LL_Stop(pdev); - - return ret; + return USBD_OK; } /** -* @brief USBD_RunTestMode -* Launch test mode process -* @param pdev: device instance -* @retval status -*/ + * @brief USBD_RunTestMode + * Launch test mode process + * @param pdev: device instance + * @retval status + */ USBD_StatusTypeDef USBD_RunTestMode(USBD_HandleTypeDef *pdev) { /* Prevent unused argument compilation warning */ @@ -252,12 +240,12 @@ USBD_StatusTypeDef USBD_RunTestMode(USBD_HandleTypeDef *pdev) } /** -* @brief USBD_SetClassConfig -* Configure device and start the interface -* @param pdev: device instance -* @param cfgidx: configuration index -* @retval status -*/ + * @brief USBD_SetClassConfig + * Configure device and start the interface + * @param pdev: device instance + * @param cfgidx: configuration index + * @retval status + */ USBD_StatusTypeDef USBD_SetClassConfig(USBD_HandleTypeDef *pdev, uint8_t cfgidx) { @@ -273,12 +261,12 @@ USBD_StatusTypeDef USBD_SetClassConfig(USBD_HandleTypeDef *pdev, uint8_t cfgidx) } /** -* @brief USBD_ClrClassConfig -* Clear current configuration -* @param pdev: device instance -* @param cfgidx: configuration index -* @retval status: USBD_StatusTypeDef -*/ + * @brief USBD_ClrClassConfig + * Clear current configuration + * @param pdev: device instance + * @param cfgidx: configuration index + * @retval status: USBD_StatusTypeDef + */ USBD_StatusTypeDef USBD_ClrClassConfig(USBD_HandleTypeDef *pdev, uint8_t cfgidx) { /* Clear configuration and De-initialize the Class process */ @@ -292,11 +280,11 @@ USBD_StatusTypeDef USBD_ClrClassConfig(USBD_HandleTypeDef *pdev, uint8_t cfgidx) /** -* @brief USBD_SetupStage -* Handle the setup stage -* @param pdev: device instance -* @retval status -*/ + * @brief USBD_LL_SetupStage + * Handle the setup stage + * @param pdev: device instance + * @retval status + */ USBD_StatusTypeDef USBD_LL_SetupStage(USBD_HandleTypeDef *pdev, uint8_t *psetup) { USBD_StatusTypeDef ret; @@ -330,12 +318,13 @@ USBD_StatusTypeDef USBD_LL_SetupStage(USBD_HandleTypeDef *pdev, uint8_t *psetup) } /** -* @brief USBD_DataOutStage -* Handle data OUT stage -* @param pdev: device instance -* @param epnum: endpoint index -* @retval status -*/ + * @brief USBD_LL_DataOutStage + * Handle data OUT stage + * @param pdev: device instance + * @param epnum: endpoint index + * @param pdata: data pointer + * @retval status + */ USBD_StatusTypeDef USBD_LL_DataOutStage(USBD_HandleTypeDef *pdev, uint8_t epnum, uint8_t *pdata) { @@ -356,11 +345,14 @@ USBD_StatusTypeDef USBD_LL_DataOutStage(USBD_HandleTypeDef *pdev, } else { - if ((pdev->pClass->EP0_RxReady != NULL) && - (pdev->dev_state == USBD_STATE_CONFIGURED)) + if (pdev->dev_state == USBD_STATE_CONFIGURED) { - pdev->pClass->EP0_RxReady(pdev); + if (pdev->pClass->EP0_RxReady != NULL) + { + pdev->pClass->EP0_RxReady(pdev); + } } + (void)USBD_CtlSendStatus(pdev); } } @@ -370,40 +362,40 @@ USBD_StatusTypeDef USBD_LL_DataOutStage(USBD_HandleTypeDef *pdev, if (pdev->ep0_state == USBD_EP0_STATUS_OUT) { /* - * STATUS PHASE completed, update ep0_state to idle - */ + * STATUS PHASE completed, update ep0_state to idle + */ pdev->ep0_state = USBD_EP0_IDLE; (void)USBD_LL_StallEP(pdev, 0U); } #endif } } - else if ((pdev->pClass->DataOut != NULL) && - (pdev->dev_state == USBD_STATE_CONFIGURED)) + else { - ret = (USBD_StatusTypeDef)pdev->pClass->DataOut(pdev, epnum); - - if (ret != USBD_OK) + if (pdev->dev_state == USBD_STATE_CONFIGURED) { - return ret; + if (pdev->pClass->DataOut != NULL) + { + ret = (USBD_StatusTypeDef)pdev->pClass->DataOut(pdev, epnum); + + if (ret != USBD_OK) + { + return ret; + } + } } } - else - { - /* should never be in this condition */ - return USBD_FAIL; - } return USBD_OK; } /** -* @brief USBD_DataInStage -* Handle data in stage -* @param pdev: device instance -* @param epnum: endpoint index -* @retval status -*/ + * @brief USBD_LL_DataInStage + * Handle data in stage + * @param pdev: device instance + * @param epnum: endpoint index + * @retval status + */ USBD_StatusTypeDef USBD_LL_DataInStage(USBD_HandleTypeDef *pdev, uint8_t epnum, uint8_t *pdata) { @@ -423,7 +415,7 @@ USBD_StatusTypeDef USBD_LL_DataInStage(USBD_HandleTypeDef *pdev, (void)USBD_CtlContinueSendData(pdev, pdata, pep->rem_length); /* Prepare endpoint for premature end of transfer */ - (void)USBD_LL_PrepareReceive(pdev, 0U, NULL, 0U); + (void)USBD_LL_PrepareReceive(pdev, 0U, NULL, 0U); } else { @@ -440,12 +432,19 @@ USBD_StatusTypeDef USBD_LL_DataInStage(USBD_HandleTypeDef *pdev, } else { - if ((pdev->pClass->EP0_TxSent != NULL) && - (pdev->dev_state == USBD_STATE_CONFIGURED)) + if (pdev->dev_state == USBD_STATE_CONFIGURED) { - pdev->pClass->EP0_TxSent(pdev); - (void)USBD_LL_StallEP(pdev, 0x80U); + if (pdev->pClass->EP0_TxSent != NULL) + { + pdev->pClass->EP0_TxSent(pdev); + } } + /* + * Fix EPO STALL issue in STM32 USB Device library 2.5.1 + * Issue raised by @makarenya, see #388 + * USB Specification EP0 should never STALL. + */ + /* (void)USBD_LL_StallEP(pdev, 0x80U); */ (void)USBD_CtlReceiveStatus(pdev); } } @@ -467,31 +466,31 @@ USBD_StatusTypeDef USBD_LL_DataInStage(USBD_HandleTypeDef *pdev, pdev->dev_test_mode = 0U; } } - else if ((pdev->pClass->DataIn != NULL) && - (pdev->dev_state == USBD_STATE_CONFIGURED)) + else { - ret = (USBD_StatusTypeDef)pdev->pClass->DataIn(pdev, epnum); - - if (ret != USBD_OK) + if (pdev->dev_state == USBD_STATE_CONFIGURED) { - return ret; + if (pdev->pClass->DataIn != NULL) + { + ret = (USBD_StatusTypeDef)pdev->pClass->DataIn(pdev, epnum); + + if (ret != USBD_OK) + { + return ret; + } + } } } - else - { - /* should never be in this condition */ - return USBD_FAIL; - } return USBD_OK; } /** -* @brief USBD_LL_Reset -* Handle Reset event -* @param pdev: device instance -* @retval status -*/ + * @brief USBD_LL_Reset + * Handle Reset event + * @param pdev: device instance + * @retval status + */ USBD_StatusTypeDef USBD_LL_Reset(USBD_HandleTypeDef *pdev) { @@ -501,12 +500,20 @@ USBD_StatusTypeDef USBD_LL_Reset(USBD_HandleTypeDef *pdev) pdev->dev_config = 0U; pdev->dev_remote_wakeup = 0U; + if (pdev->pClass == NULL) + { + return USBD_FAIL; + } + if (pdev->pClassData != NULL) { - pdev->pClass->DeInit(pdev, (uint8_t)pdev->dev_config); + if (pdev->pClass->DeInit != NULL) + { + (void)pdev->pClass->DeInit(pdev, (uint8_t)pdev->dev_config); + } } - /* Open EP0 OUT */ + /* Open EP0 OUT */ (void)USBD_LL_OpenEP(pdev, 0x00U, USBD_EP_TYPE_CTRL, USB_MAX_EP0_SIZE); pdev->ep_out[0x00U & 0xFU].is_used = 1U; @@ -522,11 +529,11 @@ USBD_StatusTypeDef USBD_LL_Reset(USBD_HandleTypeDef *pdev) } /** -* @brief USBD_LL_Reset -* Handle Reset event -* @param pdev: device instance -* @retval status -*/ + * @brief USBD_LL_SetSpeed + * Handle Reset event + * @param pdev: device instance + * @retval status + */ USBD_StatusTypeDef USBD_LL_SetSpeed(USBD_HandleTypeDef *pdev, USBD_SpeedTypeDef speed) { @@ -536,11 +543,11 @@ USBD_StatusTypeDef USBD_LL_SetSpeed(USBD_HandleTypeDef *pdev, } /** -* @brief USBD_Suspend -* Handle Suspend event -* @param pdev: device instance -* @retval status -*/ + * @brief USBD_LL_Suspend + * Handle Suspend event + * @param pdev: device instance + * @retval status + */ USBD_StatusTypeDef USBD_LL_Suspend(USBD_HandleTypeDef *pdev) { @@ -551,11 +558,11 @@ USBD_StatusTypeDef USBD_LL_Suspend(USBD_HandleTypeDef *pdev) } /** -* @brief USBD_Resume -* Handle Resume event -* @param pdev: device instance -* @retval status -*/ + * @brief USBD_LL_Resume + * Handle Resume event + * @param pdev: device instance + * @retval status + */ USBD_StatusTypeDef USBD_LL_Resume(USBD_HandleTypeDef *pdev) { @@ -568,19 +575,24 @@ USBD_StatusTypeDef USBD_LL_Resume(USBD_HandleTypeDef *pdev) } /** -* @brief USBD_SOF -* Handle SOF event -* @param pdev: device instance -* @retval status -*/ + * @brief USBD_LL_SOF + * Handle SOF event + * @param pdev: device instance + * @retval status + */ USBD_StatusTypeDef USBD_LL_SOF(USBD_HandleTypeDef *pdev) { + if (pdev->pClass == NULL) + { + return USBD_FAIL; + } + if (pdev->dev_state == USBD_STATE_CONFIGURED) { if (pdev->pClass->SOF != NULL) { - pdev->pClass->SOF(pdev); + (void)pdev->pClass->SOF(pdev); } } @@ -588,43 +600,61 @@ USBD_StatusTypeDef USBD_LL_SOF(USBD_HandleTypeDef *pdev) } /** -* @brief USBD_IsoINIncomplete -* Handle iso in incomplete event -* @param pdev: device instance -* @retval status -*/ + * @brief USBD_LL_IsoINIncomplete + * Handle iso in incomplete event + * @param pdev: device instance + * @retval status + */ USBD_StatusTypeDef USBD_LL_IsoINIncomplete(USBD_HandleTypeDef *pdev, uint8_t epnum) { - /* Prevent unused arguments compilation warning */ - UNUSED(pdev); - UNUSED(epnum); + if (pdev->pClass == NULL) + { + return USBD_FAIL; + } + + if (pdev->dev_state == USBD_STATE_CONFIGURED) + { + if (pdev->pClass->IsoINIncomplete != NULL) + { + (void)pdev->pClass->IsoINIncomplete(pdev, epnum); + } + } return USBD_OK; } /** -* @brief USBD_IsoOUTIncomplete -* Handle iso out incomplete event -* @param pdev: device instance -* @retval status -*/ + * @brief USBD_LL_IsoOUTIncomplete + * Handle iso out incomplete event + * @param pdev: device instance + * @retval status + */ USBD_StatusTypeDef USBD_LL_IsoOUTIncomplete(USBD_HandleTypeDef *pdev, uint8_t epnum) { - /* Prevent unused arguments compilation warning */ - UNUSED(pdev); - UNUSED(epnum); + if (pdev->pClass == NULL) + { + return USBD_FAIL; + } + + if (pdev->dev_state == USBD_STATE_CONFIGURED) + { + if (pdev->pClass->IsoOUTIncomplete != NULL) + { + (void)pdev->pClass->IsoOUTIncomplete(pdev, epnum); + } + } return USBD_OK; } /** -* @brief USBD_DevConnected -* Handle device connection event -* @param pdev: device instance -* @retval status -*/ + * @brief USBD_LL_DevConnected + * Handle device connection event + * @param pdev: device instance + * @retval status + */ USBD_StatusTypeDef USBD_LL_DevConnected(USBD_HandleTypeDef *pdev) { /* Prevent unused argument compilation warning */ @@ -634,11 +664,11 @@ USBD_StatusTypeDef USBD_LL_DevConnected(USBD_HandleTypeDef *pdev) } /** -* @brief USBD_DevDisconnected -* Handle device disconnection event -* @param pdev: device instance -* @retval status -*/ + * @brief USBD_LL_DevDisconnected + * Handle device disconnection event + * @param pdev: device instance + * @retval status + */ USBD_StatusTypeDef USBD_LL_DevDisconnected(USBD_HandleTypeDef *pdev) { /* Free Class Resources */ @@ -646,24 +676,24 @@ USBD_StatusTypeDef USBD_LL_DevDisconnected(USBD_HandleTypeDef *pdev) if (pdev->pClass != NULL) { - pdev->pClass->DeInit(pdev, (uint8_t)pdev->dev_config); + (void)pdev->pClass->DeInit(pdev, (uint8_t)pdev->dev_config); } return USBD_OK; } /** -* @} -*/ + * @} + */ /** -* @} -*/ + * @} + */ /** -* @} -*/ + * @} + */ /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ diff --git a/system/Middlewares/ST/STM32_USB_Device_Library/Core/Src/usbd_ctlreq.c b/system/Middlewares/ST/STM32_USB_Device_Library/Core/Src/usbd_ctlreq.c index c31d40e0a0..b7098546c1 100644 --- a/system/Middlewares/ST/STM32_USB_Device_Library/Core/Src/usbd_ctlreq.c +++ b/system/Middlewares/ST/STM32_USB_Device_Library/Core/Src/usbd_ctlreq.c @@ -91,126 +91,126 @@ static uint8_t USBD_GetLen(uint8_t *buf); /** -* @brief USBD_StdDevReq -* Handle standard usb device requests -* @param pdev: device instance -* @param req: usb request -* @retval status -*/ + * @brief USBD_StdDevReq + * Handle standard usb device requests + * @param pdev: device instance + * @param req: usb request + * @retval status + */ USBD_StatusTypeDef USBD_StdDevReq(USBD_HandleTypeDef *pdev, USBD_SetupReqTypedef *req) { USBD_StatusTypeDef ret = USBD_OK; switch (req->bmRequest & USB_REQ_TYPE_MASK) { - case USB_REQ_TYPE_CLASS: - case USB_REQ_TYPE_VENDOR: - ret = (USBD_StatusTypeDef)pdev->pClass->Setup(pdev, req); - break; - - case USB_REQ_TYPE_STANDARD: - switch (req->bRequest) - { - case USB_REQ_GET_DESCRIPTOR: - USBD_GetDescriptor(pdev, req); + case USB_REQ_TYPE_CLASS: + case USB_REQ_TYPE_VENDOR: + ret = (USBD_StatusTypeDef)pdev->pClass->Setup(pdev, req); break; - case USB_REQ_SET_ADDRESS: - USBD_SetAddress(pdev, req); - break; + case USB_REQ_TYPE_STANDARD: + switch (req->bRequest) + { + case USB_REQ_GET_DESCRIPTOR: + USBD_GetDescriptor(pdev, req); + break; - case USB_REQ_SET_CONFIGURATION: - ret = USBD_SetConfig(pdev, req); - break; + case USB_REQ_SET_ADDRESS: + USBD_SetAddress(pdev, req); + break; - case USB_REQ_GET_CONFIGURATION: - USBD_GetConfig(pdev, req); - break; + case USB_REQ_SET_CONFIGURATION: + ret = USBD_SetConfig(pdev, req); + break; - case USB_REQ_GET_STATUS: - USBD_GetStatus(pdev, req); - break; + case USB_REQ_GET_CONFIGURATION: + USBD_GetConfig(pdev, req); + break; - case USB_REQ_SET_FEATURE: - USBD_SetFeature(pdev, req); - break; + case USB_REQ_GET_STATUS: + USBD_GetStatus(pdev, req); + break; + + case USB_REQ_SET_FEATURE: + USBD_SetFeature(pdev, req); + break; - case USB_REQ_CLEAR_FEATURE: - USBD_ClrFeature(pdev, req); + case USB_REQ_CLEAR_FEATURE: + USBD_ClrFeature(pdev, req); + break; + + default: + USBD_CtlError(pdev, req); + break; + } break; default: USBD_CtlError(pdev, req); break; - } - break; - - default: - USBD_CtlError(pdev, req); - break; } return ret; } /** -* @brief USBD_StdItfReq -* Handle standard usb interface requests -* @param pdev: device instance -* @param req: usb request -* @retval status -*/ + * @brief USBD_StdItfReq + * Handle standard usb interface requests + * @param pdev: device instance + * @param req: usb request + * @retval status + */ USBD_StatusTypeDef USBD_StdItfReq(USBD_HandleTypeDef *pdev, USBD_SetupReqTypedef *req) { USBD_StatusTypeDef ret = USBD_OK; switch (req->bmRequest & USB_REQ_TYPE_MASK) { - case USB_REQ_TYPE_CLASS: - case USB_REQ_TYPE_VENDOR: - case USB_REQ_TYPE_STANDARD: - switch (pdev->dev_state) - { - case USBD_STATE_DEFAULT: - case USBD_STATE_ADDRESSED: - case USBD_STATE_CONFIGURED: - - if (LOBYTE(req->wIndex) <= USBD_MAX_NUM_INTERFACES) + case USB_REQ_TYPE_CLASS: + case USB_REQ_TYPE_VENDOR: + case USB_REQ_TYPE_STANDARD: + switch (pdev->dev_state) { - ret = (USBD_StatusTypeDef)pdev->pClass->Setup(pdev, req); + case USBD_STATE_DEFAULT: + case USBD_STATE_ADDRESSED: + case USBD_STATE_CONFIGURED: - if ((req->wLength == 0U) && (ret == USBD_OK)) - { - (void)USBD_CtlSendStatus(pdev); - } - } - else - { - USBD_CtlError(pdev, req); + if (LOBYTE(req->wIndex) <= USBD_MAX_NUM_INTERFACES) + { + ret = (USBD_StatusTypeDef)pdev->pClass->Setup(pdev, req); + + if ((req->wLength == 0U) && (ret == USBD_OK)) + { + (void)USBD_CtlSendStatus(pdev); + } + } + else + { + USBD_CtlError(pdev, req); + } + break; + + default: + USBD_CtlError(pdev, req); + break; } break; default: USBD_CtlError(pdev, req); break; - } - break; - - default: - USBD_CtlError(pdev, req); - break; } return ret; } /** -* @brief USBD_StdEPReq -* Handle standard usb endpoint requests -* @param pdev: device instance -* @param req: usb request -* @retval status -*/ + * @brief USBD_StdEPReq + * Handle standard usb endpoint requests + * @param pdev: device instance + * @param req: usb request + * @retval status + */ USBD_StatusTypeDef USBD_StdEPReq(USBD_HandleTypeDef *pdev, USBD_SetupReqTypedef *req) { USBD_EndpointTypeDef *pep; @@ -220,150 +220,150 @@ USBD_StatusTypeDef USBD_StdEPReq(USBD_HandleTypeDef *pdev, USBD_SetupReqTypedef switch (req->bmRequest & USB_REQ_TYPE_MASK) { - case USB_REQ_TYPE_CLASS: - case USB_REQ_TYPE_VENDOR: - ret = (USBD_StatusTypeDef)pdev->pClass->Setup(pdev, req); - break; - - case USB_REQ_TYPE_STANDARD: - switch (req->bRequest) - { - case USB_REQ_SET_FEATURE: - switch (pdev->dev_state) - { - case USBD_STATE_ADDRESSED: - if ((ep_addr != 0x00U) && (ep_addr != 0x80U)) - { - (void)USBD_LL_StallEP(pdev, ep_addr); - (void)USBD_LL_StallEP(pdev, 0x80U); - } - else - { - USBD_CtlError(pdev, req); - } - break; - - case USBD_STATE_CONFIGURED: - if (req->wValue == USB_FEATURE_EP_HALT) - { - if ((ep_addr != 0x00U) && (ep_addr != 0x80U) && (req->wLength == 0x00U)) - { - (void)USBD_LL_StallEP(pdev, ep_addr); - } - } - (void)USBD_CtlSendStatus(pdev); - - break; - - default: - USBD_CtlError(pdev, req); - break; - } + case USB_REQ_TYPE_CLASS: + case USB_REQ_TYPE_VENDOR: + ret = (USBD_StatusTypeDef)pdev->pClass->Setup(pdev, req); break; - case USB_REQ_CLEAR_FEATURE: - - switch (pdev->dev_state) + case USB_REQ_TYPE_STANDARD: + switch (req->bRequest) { - case USBD_STATE_ADDRESSED: - if ((ep_addr != 0x00U) && (ep_addr != 0x80U)) - { - (void)USBD_LL_StallEP(pdev, ep_addr); - (void)USBD_LL_StallEP(pdev, 0x80U); - } - else - { - USBD_CtlError(pdev, req); - } - break; - - case USBD_STATE_CONFIGURED: - if (req->wValue == USB_FEATURE_EP_HALT) - { - if ((ep_addr & 0x7FU) != 0x00U) + case USB_REQ_SET_FEATURE: + switch (pdev->dev_state) { - (void)USBD_LL_ClearStallEP(pdev, ep_addr); + case USBD_STATE_ADDRESSED: + if ((ep_addr != 0x00U) && (ep_addr != 0x80U)) + { + (void)USBD_LL_StallEP(pdev, ep_addr); + (void)USBD_LL_StallEP(pdev, 0x80U); + } + else + { + USBD_CtlError(pdev, req); + } + break; + + case USBD_STATE_CONFIGURED: + if (req->wValue == USB_FEATURE_EP_HALT) + { + if ((ep_addr != 0x00U) && (ep_addr != 0x80U) && (req->wLength == 0x00U)) + { + (void)USBD_LL_StallEP(pdev, ep_addr); + } + } + (void)USBD_CtlSendStatus(pdev); + + break; + + default: + USBD_CtlError(pdev, req); + break; } - (void)USBD_CtlSendStatus(pdev); - (USBD_StatusTypeDef)pdev->pClass->Setup(pdev, req); - } - break; - - default: - USBD_CtlError(pdev, req); - break; - } - break; - - case USB_REQ_GET_STATUS: - switch (pdev->dev_state) - { - case USBD_STATE_ADDRESSED: - if ((ep_addr != 0x00U) && (ep_addr != 0x80U)) - { - USBD_CtlError(pdev, req); break; - } - pep = ((ep_addr & 0x80U) == 0x80U) ? &pdev->ep_in[ep_addr & 0x7FU] : \ - &pdev->ep_out[ep_addr & 0x7FU]; - - pep->status = 0x0000U; - (void)USBD_CtlSendData(pdev, (uint8_t *)&pep->status, 2U); - break; + case USB_REQ_CLEAR_FEATURE: - case USBD_STATE_CONFIGURED: - if ((ep_addr & 0x80U) == 0x80U) - { - if (pdev->ep_in[ep_addr & 0xFU].is_used == 0U) - { - USBD_CtlError(pdev, req); - break; - } - } - else - { - if (pdev->ep_out[ep_addr & 0xFU].is_used == 0U) + switch (pdev->dev_state) { - USBD_CtlError(pdev, req); - break; + case USBD_STATE_ADDRESSED: + if ((ep_addr != 0x00U) && (ep_addr != 0x80U)) + { + (void)USBD_LL_StallEP(pdev, ep_addr); + (void)USBD_LL_StallEP(pdev, 0x80U); + } + else + { + USBD_CtlError(pdev, req); + } + break; + + case USBD_STATE_CONFIGURED: + if (req->wValue == USB_FEATURE_EP_HALT) + { + if ((ep_addr & 0x7FU) != 0x00U) + { + (void)USBD_LL_ClearStallEP(pdev, ep_addr); + } + (void)USBD_CtlSendStatus(pdev); + ret = (USBD_StatusTypeDef)pdev->pClass->Setup(pdev, req); + } + break; + + default: + USBD_CtlError(pdev, req); + break; } - } - - pep = ((ep_addr & 0x80U) == 0x80U) ? &pdev->ep_in[ep_addr & 0x7FU] : \ - &pdev->ep_out[ep_addr & 0x7FU]; + break; - if ((ep_addr == 0x00U) || (ep_addr == 0x80U)) + case USB_REQ_GET_STATUS: + switch (pdev->dev_state) { - pep->status = 0x0000U; + case USBD_STATE_ADDRESSED: + if ((ep_addr != 0x00U) && (ep_addr != 0x80U)) + { + USBD_CtlError(pdev, req); + break; + } + pep = ((ep_addr & 0x80U) == 0x80U) ? &pdev->ep_in[ep_addr & 0x7FU] : \ + &pdev->ep_out[ep_addr & 0x7FU]; + + pep->status = 0x0000U; + + (void)USBD_CtlSendData(pdev, (uint8_t *)&pep->status, 2U); + break; + + case USBD_STATE_CONFIGURED: + if ((ep_addr & 0x80U) == 0x80U) + { + if (pdev->ep_in[ep_addr & 0xFU].is_used == 0U) + { + USBD_CtlError(pdev, req); + break; + } + } + else + { + if (pdev->ep_out[ep_addr & 0xFU].is_used == 0U) + { + USBD_CtlError(pdev, req); + break; + } + } + + pep = ((ep_addr & 0x80U) == 0x80U) ? &pdev->ep_in[ep_addr & 0x7FU] : \ + &pdev->ep_out[ep_addr & 0x7FU]; + + if ((ep_addr == 0x00U) || (ep_addr == 0x80U)) + { + pep->status = 0x0000U; + } + else if (USBD_LL_IsStallEP(pdev, ep_addr) != 0U) + { + pep->status = 0x0001U; + } + else + { + pep->status = 0x0000U; + } + + (void)USBD_CtlSendData(pdev, (uint8_t *)&pep->status, 2U); + break; + + default: + USBD_CtlError(pdev, req); + break; } - else if (USBD_LL_IsStallEP(pdev, ep_addr) != 0U) - { - pep->status = 0x0001U; - } - else - { - pep->status = 0x0000U; - } - - (void)USBD_CtlSendData(pdev, (uint8_t *)&pep->status, 2U); break; - default: - USBD_CtlError(pdev, req); - break; + default: + USBD_CtlError(pdev, req); + break; } break; default: USBD_CtlError(pdev, req); break; - } - break; - - default: - USBD_CtlError(pdev, req); - break; } return ret; @@ -371,12 +371,12 @@ USBD_StatusTypeDef USBD_StdEPReq(USBD_HandleTypeDef *pdev, USBD_SetupReqTypedef /** -* @brief USBD_GetDescriptor -* Handle Get Descriptor requests -* @param pdev: device instance -* @param req: usb request -* @retval status -*/ + * @brief USBD_GetDescriptor + * Handle Get Descriptor requests + * @param pdev: device instance + * @param req: usb request + * @retval status + */ static void USBD_GetDescriptor(USBD_HandleTypeDef *pdev, USBD_SetupReqTypedef *req) { uint16_t len = 0U; @@ -386,42 +386,10 @@ static void USBD_GetDescriptor(USBD_HandleTypeDef *pdev, USBD_SetupReqTypedef *r switch (req->wValue >> 8) { #if ((USBD_LPM_ENABLED == 1U) || (USBD_CLASS_BOS_ENABLED == 1U)) - case USB_DESC_TYPE_BOS: - if (pdev->pDesc->GetBOSDescriptor != NULL) - { - pbuf = pdev->pDesc->GetBOSDescriptor(pdev->dev_speed, &len); - } - else - { - USBD_CtlError(pdev, req); - err++; - } - break; -#endif - case USB_DESC_TYPE_DEVICE: - pbuf = pdev->pDesc->GetDeviceDescriptor(pdev->dev_speed, &len); - break; - - case USB_DESC_TYPE_CONFIGURATION: - if (pdev->dev_speed == USBD_SPEED_HIGH) - { - pbuf = pdev->pClass->GetHSConfigDescriptor(&len); - pbuf[1] = USB_DESC_TYPE_CONFIGURATION; - } - else - { - pbuf = pdev->pClass->GetFSConfigDescriptor(&len); - pbuf[1] = USB_DESC_TYPE_CONFIGURATION; - } - break; - - case USB_DESC_TYPE_STRING: - switch ((uint8_t)(req->wValue)) - { - case USBD_IDX_LANGID_STR: - if (pdev->pDesc->GetLangIDStrDescriptor != NULL) + case USB_DESC_TYPE_BOS: + if (pdev->pDesc->GetBOSDescriptor != NULL) { - pbuf = pdev->pDesc->GetLangIDStrDescriptor(pdev->dev_speed, &len); + pbuf = pdev->pDesc->GetBOSDescriptor(pdev->dev_speed, &len); } else { @@ -429,47 +397,136 @@ static void USBD_GetDescriptor(USBD_HandleTypeDef *pdev, USBD_SetupReqTypedef *r err++; } break; - - case USBD_IDX_MFC_STR: - if (pdev->pDesc->GetManufacturerStrDescriptor != NULL) - { - pbuf = pdev->pDesc->GetManufacturerStrDescriptor(pdev->dev_speed, &len); - } - else - { - USBD_CtlError(pdev, req); - err++; - } +#endif + case USB_DESC_TYPE_DEVICE: + pbuf = pdev->pDesc->GetDeviceDescriptor(pdev->dev_speed, &len); break; - case USBD_IDX_PRODUCT_STR: - if (pdev->pDesc->GetProductStrDescriptor != NULL) + case USB_DESC_TYPE_CONFIGURATION: + if (pdev->dev_speed == USBD_SPEED_HIGH) { - pbuf = pdev->pDesc->GetProductStrDescriptor(pdev->dev_speed, &len); + pbuf = pdev->pClass->GetHSConfigDescriptor(&len); + pbuf[1] = USB_DESC_TYPE_CONFIGURATION; } else { - USBD_CtlError(pdev, req); - err++; + pbuf = pdev->pClass->GetFSConfigDescriptor(&len); + pbuf[1] = USB_DESC_TYPE_CONFIGURATION; } break; - case USBD_IDX_SERIAL_STR: - if (pdev->pDesc->GetSerialStrDescriptor != NULL) - { - pbuf = pdev->pDesc->GetSerialStrDescriptor(pdev->dev_speed, &len); - } - else + case USB_DESC_TYPE_STRING: + switch ((uint8_t)(req->wValue)) { - USBD_CtlError(pdev, req); - err++; + case USBD_IDX_LANGID_STR: + if (pdev->pDesc->GetLangIDStrDescriptor != NULL) + { + pbuf = pdev->pDesc->GetLangIDStrDescriptor(pdev->dev_speed, &len); + } + else + { + USBD_CtlError(pdev, req); + err++; + } + break; + + case USBD_IDX_MFC_STR: + if (pdev->pDesc->GetManufacturerStrDescriptor != NULL) + { + pbuf = pdev->pDesc->GetManufacturerStrDescriptor(pdev->dev_speed, &len); + } + else + { + USBD_CtlError(pdev, req); + err++; + } + break; + + case USBD_IDX_PRODUCT_STR: + if (pdev->pDesc->GetProductStrDescriptor != NULL) + { + pbuf = pdev->pDesc->GetProductStrDescriptor(pdev->dev_speed, &len); + } + else + { + USBD_CtlError(pdev, req); + err++; + } + break; + + case USBD_IDX_SERIAL_STR: + if (pdev->pDesc->GetSerialStrDescriptor != NULL) + { + pbuf = pdev->pDesc->GetSerialStrDescriptor(pdev->dev_speed, &len); + } + else + { + USBD_CtlError(pdev, req); + err++; + } + break; + + case USBD_IDX_CONFIG_STR: + if (pdev->pDesc->GetConfigurationStrDescriptor != NULL) + { + pbuf = pdev->pDesc->GetConfigurationStrDescriptor(pdev->dev_speed, &len); + } + else + { + USBD_CtlError(pdev, req); + err++; + } + break; + + case USBD_IDX_INTERFACE_STR: + if (pdev->pDesc->GetInterfaceStrDescriptor != NULL) + { + pbuf = pdev->pDesc->GetInterfaceStrDescriptor(pdev->dev_speed, &len); + } + else + { + USBD_CtlError(pdev, req); + err++; + } + break; + + default: +#if (USBD_SUPPORT_USER_STRING_DESC == 1U) + if (pdev->pClass->GetUsrStrDescriptor != NULL) + { + pbuf = pdev->pClass->GetUsrStrDescriptor(pdev, (req->wValue), &len); + } + else + { + USBD_CtlError(pdev, req); + err++; + } +#endif + +#if (USBD_CLASS_USER_STRING_DESC == 1U) + if (pdev->pDesc->GetUserStrDescriptor != NULL) + { + pbuf = pdev->pDesc->GetUserStrDescriptor(pdev->dev_speed, (req->wValue), &len); + } + else + { + USBD_CtlError(pdev, req); + err++; + } +#endif + +#if ((USBD_CLASS_USER_STRING_DESC == 0U) && (USBD_SUPPORT_USER_STRING_DESC == 0U)) + USBD_CtlError(pdev, req); + err++; +#endif + break; } break; - case USBD_IDX_CONFIG_STR: - if (pdev->pDesc->GetConfigurationStrDescriptor != NULL) + case USB_DESC_TYPE_DEVICE_QUALIFIER: + if (pdev->dev_speed == USBD_SPEED_HIGH) { - pbuf = pdev->pDesc->GetConfigurationStrDescriptor(pdev->dev_speed, &len); + pbuf = pdev->pClass->GetDeviceQualifierDescriptor(&len); } else { @@ -478,10 +535,11 @@ static void USBD_GetDescriptor(USBD_HandleTypeDef *pdev, USBD_SetupReqTypedef *r } break; - case USBD_IDX_INTERFACE_STR: - if (pdev->pDesc->GetInterfaceStrDescriptor != NULL) + case USB_DESC_TYPE_OTHER_SPEED_CONFIGURATION: + if (pdev->dev_speed == USBD_SPEED_HIGH) { - pbuf = pdev->pDesc->GetInterfaceStrDescriptor(pdev->dev_speed, &len); + pbuf = pdev->pClass->GetOtherSpeedConfigDescriptor(&len); + pbuf[1] = USB_DESC_TYPE_OTHER_SPEED_CONFIGURATION; } else { @@ -491,97 +549,42 @@ static void USBD_GetDescriptor(USBD_HandleTypeDef *pdev, USBD_SetupReqTypedef *r break; default: -#if (USBD_SUPPORT_USER_STRING_DESC == 1U) - if (pdev->pClass->GetUsrStrDescriptor != NULL) - { - pbuf = pdev->pClass->GetUsrStrDescriptor(pdev, (req->wValue), &len); - } - else - { - USBD_CtlError(pdev, req); - err++; - } -#elif (USBD_CLASS_USER_STRING_DESC == 1U) - if (pdev->pDesc->GetUserStrDescriptor != NULL) - { - pbuf = pdev->pDesc->GetUserStrDescriptor(pdev->dev_speed, (req->wValue), &len); - } - else - { - USBD_CtlError(pdev, req); - err++; - } -#else USBD_CtlError(pdev, req); err++; -#endif break; - } - break; - - case USB_DESC_TYPE_DEVICE_QUALIFIER: - if (pdev->dev_speed == USBD_SPEED_HIGH) - { - pbuf = pdev->pClass->GetDeviceQualifierDescriptor(&len); - } - else - { - USBD_CtlError(pdev, req); - err++; - } - break; - - case USB_DESC_TYPE_OTHER_SPEED_CONFIGURATION: - if (pdev->dev_speed == USBD_SPEED_HIGH) - { - pbuf = pdev->pClass->GetOtherSpeedConfigDescriptor(&len); - pbuf[1] = USB_DESC_TYPE_OTHER_SPEED_CONFIGURATION; - } - else - { - USBD_CtlError(pdev, req); - err++; - } - break; - - default: - USBD_CtlError(pdev, req); - err++; - break; } if (err != 0U) { return; } - else + + if (req->wLength != 0U) { - if (req->wLength != 0U) + if (len != 0U) { - if (len != 0U) - { - len = MIN(len, req->wLength); - (void)USBD_CtlSendData(pdev, pbuf, len); - } - else - { - USBD_CtlError(pdev, req); - } + len = MIN(len, req->wLength); + (void)USBD_CtlSendData(pdev, pbuf, len); } else { - (void)USBD_CtlSendStatus(pdev); + USBD_CtlError(pdev, req); } } + else + { + (void)USBD_CtlSendStatus(pdev); + } } + /** -* @brief USBD_SetAddress -* Set device address -* @param pdev: device instance -* @param req: usb request -* @retval status -*/ + * @brief USBD_SetAddress + * Set device address + * @param pdev: device instance + * @param req: usb request + * @retval status + */ static void USBD_SetAddress(USBD_HandleTypeDef *pdev, USBD_SetupReqTypedef *req) { uint8_t dev_addr; @@ -617,12 +620,12 @@ static void USBD_SetAddress(USBD_HandleTypeDef *pdev, USBD_SetupReqTypedef *req) } /** -* @brief USBD_SetConfig -* Handle Set device configuration request -* @param pdev: device instance -* @param req: usb request -* @retval status -*/ + * @brief USBD_SetConfig + * Handle Set device configuration request + * @param pdev: device instance + * @param req: usb request + * @retval status + */ static USBD_StatusTypeDef USBD_SetConfig(USBD_HandleTypeDef *pdev, USBD_SetupReqTypedef *req) { USBD_StatusTypeDef ret = USBD_OK; @@ -638,81 +641,81 @@ static USBD_StatusTypeDef USBD_SetConfig(USBD_HandleTypeDef *pdev, USBD_SetupReq switch (pdev->dev_state) { - case USBD_STATE_ADDRESSED: - if (cfgidx != 0U) - { - pdev->dev_config = cfgidx; + case USBD_STATE_ADDRESSED: + if (cfgidx != 0U) + { + pdev->dev_config = cfgidx; - ret = USBD_SetClassConfig(pdev, cfgidx); + ret = USBD_SetClassConfig(pdev, cfgidx); - if (ret != USBD_OK) - { - USBD_CtlError(pdev, req); + if (ret != USBD_OK) + { + USBD_CtlError(pdev, req); + } + else + { + (void)USBD_CtlSendStatus(pdev); + pdev->dev_state = USBD_STATE_CONFIGURED; + } } else { (void)USBD_CtlSendStatus(pdev); - pdev->dev_state = USBD_STATE_CONFIGURED; } - } - else - { - (void)USBD_CtlSendStatus(pdev); - } - break; + break; - case USBD_STATE_CONFIGURED: - if (cfgidx == 0U) - { - pdev->dev_state = USBD_STATE_ADDRESSED; - pdev->dev_config = cfgidx; - (void)USBD_ClrClassConfig(pdev, cfgidx); - (void)USBD_CtlSendStatus(pdev); - } - else if (cfgidx != pdev->dev_config) - { - /* Clear old configuration */ - (void)USBD_ClrClassConfig(pdev, (uint8_t)pdev->dev_config); + case USBD_STATE_CONFIGURED: + if (cfgidx == 0U) + { + pdev->dev_state = USBD_STATE_ADDRESSED; + pdev->dev_config = cfgidx; + (void)USBD_ClrClassConfig(pdev, cfgidx); + (void)USBD_CtlSendStatus(pdev); + } + else if (cfgidx != pdev->dev_config) + { + /* Clear old configuration */ + (void)USBD_ClrClassConfig(pdev, (uint8_t)pdev->dev_config); - /* set new configuration */ - pdev->dev_config = cfgidx; + /* set new configuration */ + pdev->dev_config = cfgidx; - ret = USBD_SetClassConfig(pdev, cfgidx); + ret = USBD_SetClassConfig(pdev, cfgidx); - if (ret != USBD_OK) - { - USBD_CtlError(pdev, req); - (void)USBD_ClrClassConfig(pdev, (uint8_t)pdev->dev_config); - pdev->dev_state = USBD_STATE_ADDRESSED; + if (ret != USBD_OK) + { + USBD_CtlError(pdev, req); + (void)USBD_ClrClassConfig(pdev, (uint8_t)pdev->dev_config); + pdev->dev_state = USBD_STATE_ADDRESSED; + } + else + { + (void)USBD_CtlSendStatus(pdev); + } } else { (void)USBD_CtlSendStatus(pdev); } - } - else - { - (void)USBD_CtlSendStatus(pdev); - } - break; + break; - default: - USBD_CtlError(pdev, req); - (void)USBD_ClrClassConfig(pdev, cfgidx); - ret = USBD_FAIL; - break; + default: + USBD_CtlError(pdev, req); + (void)USBD_ClrClassConfig(pdev, cfgidx); + ret = USBD_FAIL; + break; } return ret; } /** -* @brief USBD_GetConfig -* Handle Get device configuration request -* @param pdev: device instance -* @param req: usb request -* @retval status -*/ + * @brief USBD_GetConfig + * Handle Get device configuration request + * @param pdev: device instance + * @param req: usb request + * @retval status + */ static void USBD_GetConfig(USBD_HandleTypeDef *pdev, USBD_SetupReqTypedef *req) { if (req->wLength != 1U) @@ -723,71 +726,71 @@ static void USBD_GetConfig(USBD_HandleTypeDef *pdev, USBD_SetupReqTypedef *req) { switch (pdev->dev_state) { - case USBD_STATE_DEFAULT: - case USBD_STATE_ADDRESSED: - pdev->dev_default_config = 0U; - (void)USBD_CtlSendData(pdev, (uint8_t *)&pdev->dev_default_config, 1U); - break; + case USBD_STATE_DEFAULT: + case USBD_STATE_ADDRESSED: + pdev->dev_default_config = 0U; + (void)USBD_CtlSendData(pdev, (uint8_t *)&pdev->dev_default_config, 1U); + break; - case USBD_STATE_CONFIGURED: - (void)USBD_CtlSendData(pdev, (uint8_t *)&pdev->dev_config, 1U); - break; + case USBD_STATE_CONFIGURED: + (void)USBD_CtlSendData(pdev, (uint8_t *)&pdev->dev_config, 1U); + break; - default: - USBD_CtlError(pdev, req); - break; + default: + USBD_CtlError(pdev, req); + break; } } } /** -* @brief USBD_GetStatus -* Handle Get Status request -* @param pdev: device instance -* @param req: usb request -* @retval status -*/ + * @brief USBD_GetStatus + * Handle Get Status request + * @param pdev: device instance + * @param req: usb request + * @retval status + */ static void USBD_GetStatus(USBD_HandleTypeDef *pdev, USBD_SetupReqTypedef *req) { switch (pdev->dev_state) { - case USBD_STATE_DEFAULT: - case USBD_STATE_ADDRESSED: - case USBD_STATE_CONFIGURED: - if (req->wLength != 0x2U) - { - USBD_CtlError(pdev, req); - break; - } + case USBD_STATE_DEFAULT: + case USBD_STATE_ADDRESSED: + case USBD_STATE_CONFIGURED: + if (req->wLength != 0x2U) + { + USBD_CtlError(pdev, req); + break; + } #if (USBD_SELF_POWERED == 1U) - pdev->dev_config_status = USB_CONFIG_SELF_POWERED; + pdev->dev_config_status = USB_CONFIG_SELF_POWERED; #else - pdev->dev_config_status = 0U; + pdev->dev_config_status = 0U; #endif - if (pdev->dev_remote_wakeup != 0U) - { - pdev->dev_config_status |= USB_CONFIG_REMOTE_WAKEUP; - } + if (pdev->dev_remote_wakeup != 0U) + { + pdev->dev_config_status |= USB_CONFIG_REMOTE_WAKEUP; + } - (void)USBD_CtlSendData(pdev, (uint8_t *)&pdev->dev_config_status, 2U); - break; + (void)USBD_CtlSendData(pdev, (uint8_t *)&pdev->dev_config_status, 2U); + break; - default: - USBD_CtlError(pdev, req); - break; + default: + USBD_CtlError(pdev, req); + break; } } /** -* @brief USBD_SetFeature -* Handle Set device feature request -* @param pdev: device instance -* @param req: usb request -* @retval status -*/ + * @brief USBD_SetFeature + * Handle Set device feature request + * @param pdev: device instance + * @param req: usb request + * @retval status + */ static void USBD_SetFeature(USBD_HandleTypeDef *pdev, USBD_SetupReqTypedef *req) { if (req->wValue == USB_FEATURE_REMOTE_WAKEUP) @@ -799,12 +802,12 @@ static void USBD_SetFeature(USBD_HandleTypeDef *pdev, USBD_SetupReqTypedef *req) /** -* @brief USBD_ClrFeature -* Handle clear device feature request -* @param pdev: device instance -* @param req: usb request -* @retval status -*/ + * @brief USBD_ClrFeature + * Handle clear device feature request + * @param pdev: device instance + * @param req: usb request + * @retval status + */ static void USBD_ClrFeature(USBD_HandleTypeDef *pdev, USBD_SetupReqTypedef *req) { switch (pdev->dev_state) @@ -825,14 +828,14 @@ static void USBD_ClrFeature(USBD_HandleTypeDef *pdev, USBD_SetupReqTypedef *req) } } -/** -* @brief USBD_ParseSetupRequest -* Copy buffer into setup structure -* @param pdev: device instance -* @param req: usb request -* @retval None -*/ +/** + * @brief USBD_ParseSetupRequest + * Copy buffer into setup structure + * @param pdev: device instance + * @param req: usb request + * @retval None + */ void USBD_ParseSetupRequest(USBD_SetupReqTypedef *req, uint8_t *pdata) { uint8_t *pbuff = pdata; @@ -854,14 +857,14 @@ void USBD_ParseSetupRequest(USBD_SetupReqTypedef *req, uint8_t *pdata) req->wLength = SWAPBYTE(pbuff); } -/** -* @brief USBD_CtlError -* Handle USB low level Error -* @param pdev: device instance -* @param req: usb request -* @retval None -*/ +/** + * @brief USBD_CtlError + * Handle USB low level Error + * @param pdev: device instance + * @param req: usb request + * @retval None + */ void USBD_CtlError(USBD_HandleTypeDef *pdev, USBD_SetupReqTypedef *req) { UNUSED(req); @@ -908,6 +911,7 @@ void USBD_GetString(uint8_t *desc, uint8_t *unicode, uint16_t *len) } } + /** * @brief USBD_GetLen * return the string length diff --git a/system/Middlewares/ST/STM32_USB_Device_Library/Core/Src/usbd_desc_template.c b/system/Middlewares/ST/STM32_USB_Device_Library/Core/Src/usbd_desc_template.c index 403936ddb0..8558ebd7d6 100644 --- a/system/Middlewares/ST/STM32_USB_Device_Library/Core/Src/usbd_desc_template.c +++ b/system/Middlewares/ST/STM32_USB_Device_Library/Core/Src/usbd_desc_template.c @@ -52,7 +52,7 @@ uint8_t *USBD_Class_UserStrDescriptor(USBD_SpeedTypeDef speed, uint8_t idx, uint #endif /* USB_CLASS_USER_STRING_DESC */ #if ((USBD_LPM_ENABLED == 1) || (USBD_CLASS_BOS_ENABLED == 1)) -uint8_t *USBD_USR_BOSDescriptor(USBD_SpeedTypeDef speed , uint16_t *length); +uint8_t *USBD_USR_BOSDescriptor(USBD_SpeedTypeDef speed, uint16_t *length); #endif /* Private variables ---------------------------------------------------------*/ @@ -109,7 +109,7 @@ __ALIGN_BEGIN uint8_t USBD_DeviceDesc[USB_LEN_DEV_DESC] __ALIGN_END = /* USB Device LPM BOS descriptor */ #if (USBD_LPM_ENABLED == 1) #if defined ( __ICCARM__ ) /*!< IAR Compiler */ - #pragma data_alignment=4 +#pragma data_alignment=4 #endif __ALIGN_BEGIN uint8_t USBD_BOSDesc[USB_SIZ_BOS_DESC] __ALIGN_END = { @@ -132,87 +132,87 @@ __ALIGN_BEGIN uint8_t USBD_BOSDesc[USB_SIZ_BOS_DESC] __ALIGN_END = /* USB Device Billboard BOS descriptor Template */ #if (USBD_CLASS_BOS_ENABLED == 1) #if defined ( __ICCARM__ ) /*!< IAR Compiler */ - #pragma data_alignment=4 +#pragma data_alignment=4 #endif __ALIGN_BEGIN uint8_t USBD_BOSDesc[USB_SIZ_BOS_DESC] __ALIGN_END = { -0x05, /* bLength */ -USB_DESC_TYPE_BOS, /* Device Descriptor Type */ -USB_SIZ_BOS_DESC, /* Total length of BOS descriptor and all of its sub descs */ -0x00, -0x04, /* The number of separate device capability descriptors in the BOS */ - - /* ----------- Device Capability Descriptor: CONTAINER_ID ---------- */ -0x14, /* bLength */ -0x10, /* bDescriptorType: DEVICE CAPABILITY Type */ -0x04, /* bDevCapabilityType: CONTAINER_ID */ -0x00, /* bReserved */ -0xa7, 0xd6, 0x1b, 0xfa, /* ContainerID: This is a Unique 128-bit number GUID */ -0x91, 0xa6, 0xa8, 0x4e, -0xa8, 0x21, 0x9f, 0x2b, -0xaf, 0xf7, 0x94, 0xd4, - - /* ----------- Device Capability Descriptor: BillBoard ---------- */ -0x34, /* bLength */ -0x10, /* bDescriptorType: DEVICE CAPABILITY Type */ -0x0D, /* bDevCapabilityType: BILLBOARD_CAPABILITY */ -USBD_BB_URL_STRING_INDEX, /* iAddtionalInfoURL: Index of string descriptor providing a URL where the user can go to get more + 0x05, /* bLength */ + USB_DESC_TYPE_BOS, /* Device Descriptor Type */ + USB_SIZ_BOS_DESC, /* Total length of BOS descriptor and all of its sub descs */ + 0x00, + 0x04, /* The number of separate device capability descriptors in the BOS */ + + /* ----------- Device Capability Descriptor: CONTAINER_ID ---------- */ + 0x14, /* bLength */ + 0x10, /* bDescriptorType: DEVICE CAPABILITY Type */ + 0x04, /* bDevCapabilityType: CONTAINER_ID */ + 0x00, /* bReserved */ + 0xa7, 0xd6, 0x1b, 0xfa, /* ContainerID: This is a Unique 128-bit number GUID */ + 0x91, 0xa6, 0xa8, 0x4e, + 0xa8, 0x21, 0x9f, 0x2b, + 0xaf, 0xf7, 0x94, 0xd4, + + /* ----------- Device Capability Descriptor: BillBoard ---------- */ + 0x34, /* bLength */ + 0x10, /* bDescriptorType: DEVICE CAPABILITY Type */ + 0x0D, /* bDevCapabilityType: BILLBOARD_CAPABILITY */ + USBD_BB_URL_STRING_INDEX, /* iAddtionalInfoURL: Index of string descriptor providing a URL where the user can go to get more detailed information about the product and the various Alternate Modes it supports */ -0x02, /* bNumberOfAlternateModes: Number of Alternate modes supported. The + 0x02, /* bNumberOfAlternateModes: Number of Alternate modes supported. The maximum value that this field can be set to is MAX_NUM_ALT_MODE. */ -0x00, /* bPreferredAlternateMode: Index of the preferred Alternate Mode. System + 0x00, /* bPreferredAlternateMode: Index of the preferred Alternate Mode. System software may use this information to provide the user with a better user experience. */ -0x00, 0x00, /* VCONN Power needed by the adapter for full functionality 000b = 1W */ - -0x01,0x00,0x00,0x00, /* bmConfigured. 01b: Alternate Mode configuration not attempted or exited */ -0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00, -0x21, 0x01, /* bcdVersion = 0x0121 */ -0x00, /* bAdditionalFailureInfo */ -0x00, /* bReserved */ -LOBYTE(USBD_VID), -HIBYTE(USBD_VID), /* wSVID[0]: Standard or Vendor ID. This shall match one of the SVIDs + 0x00, 0x00, /* VCONN Power needed by the adapter for full functionality 000b = 1W */ + + 0x01, 0x00, 0x00, 0x00, /* bmConfigured. 01b: Alternate Mode configuration not attempted or exited */ + 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x21, 0x01, /* bcdVersion = 0x0121 */ + 0x00, /* bAdditionalFailureInfo */ + 0x00, /* bReserved */ + LOBYTE(USBD_VID), + HIBYTE(USBD_VID), /* wSVID[0]: Standard or Vendor ID. This shall match one of the SVIDs returned in response to a USB PD Discover SVIDs command */ -0x00, /* bAlternateMode[0] Index of the Alternate Mode within the SVID as + 0x00, /* bAlternateMode[0] Index of the Alternate Mode within the SVID as returned in response to a Discover Modes command. Example: 0 � first Mode entry 1 � second mode entry */ -USBD_BB_ALTMODE0_STRING_INDEX, /* iAlternateModeString[0]: Index of string descriptor describing protocol. + USBD_BB_ALTMODE0_STRING_INDEX, /* iAlternateModeString[0]: Index of string descriptor describing protocol. It is optional to support this string. */ -LOBYTE(USBD_VID), -HIBYTE(USBD_VID), /* wSVID[1]: Standard or Vendor ID. This shall match one of the SVIDs + LOBYTE(USBD_VID), + HIBYTE(USBD_VID), /* wSVID[1]: Standard or Vendor ID. This shall match one of the SVIDs returned in response to a USB PD Discover SVIDs command */ -0x01, /* bAlternateMode[1] Index of the Alternate Mode within the SVID as + 0x01, /* bAlternateMode[1] Index of the Alternate Mode within the SVID as returned in response to a Discover Modes command. Example: 0 � first Mode entry 1 � second Mode entry */ -USBD_BB_ALTMODE1_STRING_INDEX, /* iAlternateModeString[1]: Index of string descriptor describing protocol. + USBD_BB_ALTMODE1_STRING_INDEX, /* iAlternateModeString[1]: Index of string descriptor describing protocol. It is optional to support this string. */ - /* Alternate Mode Desc */ - /* ----------- Device Capability Descriptor: BillBoard Alternate Mode Desc ---------- */ -0x08, /* bLength */ -0x10, /* bDescriptorType: Device Descriptor Type */ -0x0F, /* bDevCapabilityType: BILLBOARD ALTERNATE MODE CAPABILITY */ -0x00, /* bIndex: Index of Alternate Mode described in the Billboard Capability Desc */ -0x10, 0x00, 0x00, 0x00, /* dwAlternateModeVdo: contents of the Mode VDO for the alternate mode identified by bIndex */ - -0x08, /* bLength */ -0x10, /* bDescriptorType: Device Descriptor Type */ -0x0F, /* bDevCapabilityType: BILLBOARD ALTERNATE MODE CAPABILITY */ -0x01, /* bIndex: Index of Alternate Mode described in the Billboard Capability Desc */ -0x20, 0x00, 0x00, 0x00, /* dwAlternateModeVdo: contents of the Mode VDO for the alternate mode identified by bIndex */ + /* Alternate Mode Desc */ + /* ----------- Device Capability Descriptor: BillBoard Alternate Mode Desc ---------- */ + 0x08, /* bLength */ + 0x10, /* bDescriptorType: Device Descriptor Type */ + 0x0F, /* bDevCapabilityType: BILLBOARD ALTERNATE MODE CAPABILITY */ + 0x00, /* bIndex: Index of Alternate Mode described in the Billboard Capability Desc */ + 0x10, 0x00, 0x00, 0x00, /* dwAlternateModeVdo: contents of the Mode VDO for the alternate mode identified by bIndex */ + + 0x08, /* bLength */ + 0x10, /* bDescriptorType: Device Descriptor Type */ + 0x0F, /* bDevCapabilityType: BILLBOARD ALTERNATE MODE CAPABILITY */ + 0x01, /* bIndex: Index of Alternate Mode described in the Billboard Capability Desc */ + 0x20, 0x00, 0x00, 0x00, /* dwAlternateModeVdo: contents of the Mode VDO for the alternate mode identified by bIndex */ }; #endif @@ -395,10 +395,10 @@ static void Get_SerialNum(void) * @param length : pointer to data length variable * @retval pointer to descriptor buffer */ -uint8_t *USBD_USR_BOSDescriptor(USBD_SpeedTypeDef speed , uint16_t *length) +uint8_t *USBD_USR_BOSDescriptor(USBD_SpeedTypeDef speed, uint16_t *length) { *length = sizeof(USBD_BOSDesc); - return (uint8_t*)USBD_BOSDesc; + return (uint8_t *)USBD_BOSDesc; } #endif diff --git a/system/Middlewares/ST/STM32_USB_Device_Library/Core/Src/usbd_ioreq.c b/system/Middlewares/ST/STM32_USB_Device_Library/Core/Src/usbd_ioreq.c index 8ac5491ffe..1e7e62d451 100644 --- a/system/Middlewares/ST/STM32_USB_Device_Library/Core/Src/usbd_ioreq.c +++ b/system/Middlewares/ST/STM32_USB_Device_Library/Core/Src/usbd_ioreq.c @@ -77,20 +77,25 @@ */ /** -* @brief USBD_CtlSendData -* send data on the ctl pipe -* @param pdev: device instance -* @param buff: pointer to data buffer -* @param len: length of data to be sent -* @retval status -*/ + * @brief USBD_CtlSendData + * send data on the ctl pipe + * @param pdev: device instance + * @param buff: pointer to data buffer + * @param len: length of data to be sent + * @retval status + */ USBD_StatusTypeDef USBD_CtlSendData(USBD_HandleTypeDef *pdev, uint8_t *pbuf, uint32_t len) { /* Set EP0 State */ pdev->ep0_state = USBD_EP0_DATA_IN; pdev->ep_in[0].total_length = len; + +#ifdef USBD_AVOID_PACKET_SPLIT_MPS + pdev->ep_in[0].rem_length = 0U; +#else pdev->ep_in[0].rem_length = len; +#endif /* Start the transfer */ (void)USBD_LL_Transmit(pdev, 0x00U, pbuf, len); @@ -99,13 +104,13 @@ USBD_StatusTypeDef USBD_CtlSendData(USBD_HandleTypeDef *pdev, } /** -* @brief USBD_CtlContinueSendData -* continue sending data on the ctl pipe -* @param pdev: device instance -* @param buff: pointer to data buffer -* @param len: length of data to be sent -* @retval status -*/ + * @brief USBD_CtlContinueSendData + * continue sending data on the ctl pipe + * @param pdev: device instance + * @param buff: pointer to data buffer + * @param len: length of data to be sent + * @retval status + */ USBD_StatusTypeDef USBD_CtlContinueSendData(USBD_HandleTypeDef *pdev, uint8_t *pbuf, uint32_t len) { @@ -116,20 +121,25 @@ USBD_StatusTypeDef USBD_CtlContinueSendData(USBD_HandleTypeDef *pdev, } /** -* @brief USBD_CtlPrepareRx -* receive data on the ctl pipe -* @param pdev: device instance -* @param buff: pointer to data buffer -* @param len: length of data to be received -* @retval status -*/ + * @brief USBD_CtlPrepareRx + * receive data on the ctl pipe + * @param pdev: device instance + * @param buff: pointer to data buffer + * @param len: length of data to be received + * @retval status + */ USBD_StatusTypeDef USBD_CtlPrepareRx(USBD_HandleTypeDef *pdev, uint8_t *pbuf, uint32_t len) { /* Set EP0 State */ pdev->ep0_state = USBD_EP0_DATA_OUT; pdev->ep_out[0].total_length = len; + +#ifdef USBD_AVOID_PACKET_SPLIT_MPS + pdev->ep_out[0].rem_length = 0U; +#else pdev->ep_out[0].rem_length = len; +#endif /* Start the transfer */ (void)USBD_LL_PrepareReceive(pdev, 0U, pbuf, len); @@ -138,13 +148,13 @@ USBD_StatusTypeDef USBD_CtlPrepareRx(USBD_HandleTypeDef *pdev, } /** -* @brief USBD_CtlContinueRx -* continue receive data on the ctl pipe -* @param pdev: device instance -* @param buff: pointer to data buffer -* @param len: length of data to be received -* @retval status -*/ + * @brief USBD_CtlContinueRx + * continue receive data on the ctl pipe + * @param pdev: device instance + * @param buff: pointer to data buffer + * @param len: length of data to be received + * @retval status + */ USBD_StatusTypeDef USBD_CtlContinueRx(USBD_HandleTypeDef *pdev, uint8_t *pbuf, uint32_t len) { @@ -154,11 +164,11 @@ USBD_StatusTypeDef USBD_CtlContinueRx(USBD_HandleTypeDef *pdev, } /** -* @brief USBD_CtlSendStatus -* send zero lzngth packet on the ctl pipe -* @param pdev: device instance -* @retval status -*/ + * @brief USBD_CtlSendStatus + * send zero lzngth packet on the ctl pipe + * @param pdev: device instance + * @retval status + */ USBD_StatusTypeDef USBD_CtlSendStatus(USBD_HandleTypeDef *pdev) { /* Set EP0 State */ @@ -171,11 +181,11 @@ USBD_StatusTypeDef USBD_CtlSendStatus(USBD_HandleTypeDef *pdev) } /** -* @brief USBD_CtlReceiveStatus -* receive zero lzngth packet on the ctl pipe -* @param pdev: device instance -* @retval status -*/ + * @brief USBD_CtlReceiveStatus + * receive zero lzngth packet on the ctl pipe + * @param pdev: device instance + * @retval status + */ USBD_StatusTypeDef USBD_CtlReceiveStatus(USBD_HandleTypeDef *pdev) { /* Set EP0 State */ @@ -188,12 +198,12 @@ USBD_StatusTypeDef USBD_CtlReceiveStatus(USBD_HandleTypeDef *pdev) } /** -* @brief USBD_GetRxCount -* returns the received data length -* @param pdev: device instance -* @param ep_addr: endpoint address -* @retval Rx Data blength -*/ + * @brief USBD_GetRxCount + * returns the received data length + * @param pdev: device instance + * @param ep_addr: endpoint address + * @retval Rx Data blength + */ uint32_t USBD_GetRxCount(USBD_HandleTypeDef *pdev, uint8_t ep_addr) { return USBD_LL_GetRxDataSize(pdev, ep_addr); diff --git a/system/Middlewares/ST/STM32_USB_Device_Library/Release_Notes.html b/system/Middlewares/ST/STM32_USB_Device_Library/Release_Notes.html index c1432a6b65..cf3544b244 100644 --- a/system/Middlewares/ST/STM32_USB_Device_Library/Release_Notes.html +++ b/system/Middlewares/ST/STM32_USB_Device_Library/Release_Notes.html @@ -14,6 +14,8 @@ + +