From 89f2b620164c72f522613997a15d7427f693409b Mon Sep 17 00:00:00 2001 From: Pavol Rusnak Date: Mon, 16 Jan 2017 16:43:09 +0100 Subject: stmhal: Fix USB HID receive not receiving the first packet. --- stmhal/usbdev/class/inc/usbd_cdc_msc_hid.h | 1 + stmhal/usbdev/class/src/usbd_cdc_msc_hid.c | 2 ++ 2 files changed, 3 insertions(+) (limited to 'stmhal/usbdev/class') diff --git a/stmhal/usbdev/class/inc/usbd_cdc_msc_hid.h b/stmhal/usbdev/class/inc/usbd_cdc_msc_hid.h index 76a767892..7cb64fd84 100644 --- a/stmhal/usbdev/class/inc/usbd_cdc_msc_hid.h +++ b/stmhal/usbdev/class/inc/usbd_cdc_msc_hid.h @@ -48,6 +48,7 @@ typedef struct { } USBD_CDC_HandleTypeDef; typedef struct _USBD_HID_Itf { + int8_t (* Init) (void); int8_t (* Receive)(uint8_t *, uint32_t); } USBD_HID_ItfTypeDef; diff --git a/stmhal/usbdev/class/src/usbd_cdc_msc_hid.c b/stmhal/usbdev/class/src/usbd_cdc_msc_hid.c index d13657023..3ebc7d828 100644 --- a/stmhal/usbdev/class/src/usbd_cdc_msc_hid.c +++ b/stmhal/usbdev/class/src/usbd_cdc_msc_hid.c @@ -724,6 +724,8 @@ static uint8_t USBD_CDC_MSC_HID_Init(USBD_HandleTypeDef *pdev, uint8_t cfgidx) { USBD_EP_TYPE_INTR, mps_out); + HID_fops->Init(); + // Prepare Out endpoint to receive next packet USBD_LL_PrepareReceive(pdev, hid_out_ep, HID_ClassData.RxBuffer, mps_out); -- cgit v1.2.3 From 0883a7e72f7122b307798205441c96120446bf75 Mon Sep 17 00:00:00 2001 From: Pavol Rusnak Date: Tue, 17 Jan 2017 20:17:15 +0100 Subject: stmhal: Implement SNAK/CNAK mechanism for USB HID receive. This implements flow control in case user does not call recv method often enough (it tells host side to stop sending more data). --- stmhal/usbd_hid_interface.c | 6 +++++- stmhal/usbdev/class/inc/usbd_cdc_msc_hid.h | 2 ++ stmhal/usbdev/class/src/usbd_cdc_msc_hid.c | 18 ++++++++++++++++++ 3 files changed, 25 insertions(+), 1 deletion(-) (limited to 'stmhal/usbdev/class') diff --git a/stmhal/usbd_hid_interface.c b/stmhal/usbd_hid_interface.c index 4987314bd..7a420c330 100644 --- a/stmhal/usbd_hid_interface.c +++ b/stmhal/usbd_hid_interface.c @@ -89,7 +89,8 @@ static int8_t HID_Itf_Receive(uint8_t* Buf, uint32_t Len) { // initiate next USB packet transfer, to append to existing data in buffer USBD_HID_SetRxBuffer(&hUSBDDevice, buffer[current_write_buffer]); USBD_HID_ReceivePacket(&hUSBDDevice); - + // Set NAK to indicate we need to process read buffer + USBD_HID_SetNAK(&hUSBDDevice); return USBD_OK; } @@ -125,6 +126,9 @@ int USBD_HID_Rx(uint8_t *buf, uint32_t len, uint32_t timeout) { memcpy(buf, buffer[current_read_buffer], last_read_len); current_read_buffer = !current_read_buffer; + // Clear NAK to indicate we are ready to read more data + USBD_HID_ClearNAK(&hUSBDDevice); + // Success, return number of bytes read return last_read_len; } diff --git a/stmhal/usbdev/class/inc/usbd_cdc_msc_hid.h b/stmhal/usbdev/class/inc/usbd_cdc_msc_hid.h index 7cb64fd84..5f0502766 100644 --- a/stmhal/usbdev/class/inc/usbd_cdc_msc_hid.h +++ b/stmhal/usbdev/class/inc/usbd_cdc_msc_hid.h @@ -116,5 +116,7 @@ uint8_t USBD_HID_SetRxBuffer(USBD_HandleTypeDef *pdev, uint8_t *pbuff); uint8_t USBD_HID_ReceivePacket(USBD_HandleTypeDef *pdev); int USBD_HID_CanSendReport(USBD_HandleTypeDef *pdev); uint8_t USBD_HID_SendReport(USBD_HandleTypeDef *pdev, uint8_t *report, uint16_t len); +uint8_t USBD_HID_SetNAK(USBD_HandleTypeDef *pdev); +uint8_t USBD_HID_ClearNAK(USBD_HandleTypeDef *pdev); #endif // _USB_CDC_MSC_CORE_H_ diff --git a/stmhal/usbdev/class/src/usbd_cdc_msc_hid.c b/stmhal/usbdev/class/src/usbd_cdc_msc_hid.c index 3ebc7d828..cfae7224d 100644 --- a/stmhal/usbdev/class/src/usbd_cdc_msc_hid.c +++ b/stmhal/usbdev/class/src/usbd_cdc_msc_hid.c @@ -1093,6 +1093,24 @@ uint8_t USBD_HID_SendReport(USBD_HandleTypeDef *pdev, uint8_t *report, uint16_t return USBD_OK; } +uint8_t USBD_HID_SetNAK(USBD_HandleTypeDef *pdev) { + // get USBx object from pdev (needed for USBx_OUTEP macro below) + PCD_HandleTypeDef *hpcd = pdev->pData; + USB_OTG_GlobalTypeDef *USBx = hpcd->Instance; + // set NAK on HID OUT endpoint + USBx_OUTEP(HID_OUT_EP_WITH_CDC)->DOEPCTL |= USB_OTG_DOEPCTL_SNAK; + return USBD_OK; +} + +uint8_t USBD_HID_ClearNAK(USBD_HandleTypeDef *pdev) { + // get USBx object from pdev (needed for USBx_OUTEP macro below) + PCD_HandleTypeDef *hpcd = pdev->pData; + USB_OTG_GlobalTypeDef *USBx = hpcd->Instance; + // clear NAK on HID OUT endpoint + USBx_OUTEP(HID_OUT_EP_WITH_CDC)->DOEPCTL |= USB_OTG_DOEPCTL_CNAK; + return USBD_OK; +} + // CDC/MSC/HID interface class callback structure USBD_ClassTypeDef USBD_CDC_MSC_HID = { USBD_CDC_MSC_HID_Init, -- cgit v1.2.3 From 6adcf7bb8288fb6fd0e131f081735dd5cff16b86 Mon Sep 17 00:00:00 2001 From: Sylvain Pelissier Date: Wed, 3 May 2017 10:55:02 +0200 Subject: stmhal: Pass USB handler as parameter to allow more than one USB handler --- stmhal/usbd_cdc_interface.c | 16 ++++++++-------- stmhal/usbd_hid_interface.c | 16 ++++++++-------- stmhal/usbdev/class/inc/usbd_cdc_msc_hid.h | 8 ++++---- stmhal/usbdev/class/src/usbd_cdc_msc_hid.c | 8 ++++---- 4 files changed, 24 insertions(+), 24 deletions(-) (limited to 'stmhal/usbdev/class') diff --git a/stmhal/usbd_cdc_interface.c b/stmhal/usbd_cdc_interface.c index 941025515..942e51e98 100644 --- a/stmhal/usbd_cdc_interface.c +++ b/stmhal/usbd_cdc_interface.c @@ -82,10 +82,10 @@ static uint8_t UserTxBufPtrWaitCount = 0; // used to implement a timeout waiting static uint8_t UserTxNeedEmptyPacket = 0; // used to flush the USB IN endpoint if the last packet was exactly the endpoint packet size /* Private function prototypes -----------------------------------------------*/ -static int8_t CDC_Itf_Init (void); +static int8_t CDC_Itf_Init (USBD_HandleTypeDef *pdev); static int8_t CDC_Itf_DeInit (void); static int8_t CDC_Itf_Control (uint8_t cmd, uint8_t* pbuf, uint16_t length); -static int8_t CDC_Itf_Receive (uint8_t* pbuf, uint32_t *Len); +static int8_t CDC_Itf_Receive (USBD_HandleTypeDef *pdev, uint8_t* pbuf, uint32_t *Len); const USBD_CDC_ItfTypeDef USBD_CDC_fops = { CDC_Itf_Init, @@ -102,7 +102,7 @@ const USBD_CDC_ItfTypeDef USBD_CDC_fops = { * @param None * @retval Result of the opeartion: USBD_OK if all operations are OK else USBD_FAIL */ -static int8_t CDC_Itf_Init(void) +static int8_t CDC_Itf_Init(USBD_HandleTypeDef *pdev) { #if 0 /*##-1- Configure the UART peripheral ######################################*/ @@ -141,8 +141,8 @@ static int8_t CDC_Itf_Init(void) #endif /*##-5- Set Application Buffers ############################################*/ - USBD_CDC_SetTxBuffer(&hUSBDDevice, UserTxBuffer, 0); - USBD_CDC_SetRxBuffer(&hUSBDDevice, cdc_rx_packet_buf); + USBD_CDC_SetTxBuffer(pdev, UserTxBuffer, 0); + USBD_CDC_SetRxBuffer(pdev, cdc_rx_packet_buf); cdc_rx_buf_put = 0; cdc_rx_buf_get = 0; @@ -317,7 +317,7 @@ void HAL_PCD_SOFCallback(PCD_HandleTypeDef *hpcd) { * @note The buffer we are passed here is just cdc_rx_packet_buf, so we are * free to modify it. */ -static int8_t CDC_Itf_Receive(uint8_t* Buf, uint32_t *Len) { +static int8_t CDC_Itf_Receive(USBD_HandleTypeDef *pdev, uint8_t* Buf, uint32_t *Len) { #if 0 // this sends the data over the UART using DMA HAL_UART_Transmit_DMA(&UartHandle, Buf, *Len); @@ -339,8 +339,8 @@ static int8_t CDC_Itf_Receive(uint8_t* Buf, uint32_t *Len) { } // initiate next USB packet transfer - USBD_CDC_SetRxBuffer(&hUSBDDevice, cdc_rx_packet_buf); - USBD_CDC_ReceivePacket(&hUSBDDevice); + USBD_CDC_SetRxBuffer(pdev, cdc_rx_packet_buf); + USBD_CDC_ReceivePacket(pdev); return USBD_OK; } diff --git a/stmhal/usbd_hid_interface.c b/stmhal/usbd_hid_interface.c index 7a420c330..9eee451f3 100644 --- a/stmhal/usbd_hid_interface.c +++ b/stmhal/usbd_hid_interface.c @@ -51,8 +51,8 @@ static uint32_t last_read_len = 0; // length of last read static int8_t current_write_buffer = 0; // which buffer to write to /* Private function prototypes -----------------------------------------------*/ -static int8_t HID_Itf_Init (void); -static int8_t HID_Itf_Receive (uint8_t* pbuf, uint32_t Len); +static int8_t HID_Itf_Init (USBD_HandleTypeDef *pdev); +static int8_t HID_Itf_Receive (USBD_HandleTypeDef *pdev, uint8_t* pbuf, uint32_t Len); const USBD_HID_ItfTypeDef USBD_HID_fops = { HID_Itf_Init, @@ -65,12 +65,12 @@ const USBD_HID_ItfTypeDef USBD_HID_fops = { * @param None * @retval Result of the opeartion: USBD_OK if all operations are OK else USBD_FAIL */ -static int8_t HID_Itf_Init(void) +static int8_t HID_Itf_Init(USBD_HandleTypeDef *pdev) { current_read_buffer = 0; last_read_len = 0; current_write_buffer = 0; - USBD_HID_SetRxBuffer(&hUSBDDevice, buffer[current_write_buffer]); + USBD_HID_SetRxBuffer(pdev, buffer[current_write_buffer]); return USBD_OK; } @@ -83,14 +83,14 @@ static int8_t HID_Itf_Init(void) * @note The buffer we are passed here is just UserRxBuffer, so we are * free to modify it. */ -static int8_t HID_Itf_Receive(uint8_t* Buf, uint32_t Len) { +static int8_t HID_Itf_Receive(USBD_HandleTypeDef *pdev, uint8_t* Buf, uint32_t Len) { current_write_buffer = !current_write_buffer; last_read_len = Len; // initiate next USB packet transfer, to append to existing data in buffer - USBD_HID_SetRxBuffer(&hUSBDDevice, buffer[current_write_buffer]); - USBD_HID_ReceivePacket(&hUSBDDevice); + USBD_HID_SetRxBuffer(pdev, buffer[current_write_buffer]); + USBD_HID_ReceivePacket(pdev); // Set NAK to indicate we need to process read buffer - USBD_HID_SetNAK(&hUSBDDevice); + USBD_HID_SetNAK(pdev); return USBD_OK; } diff --git a/stmhal/usbdev/class/inc/usbd_cdc_msc_hid.h b/stmhal/usbdev/class/inc/usbd_cdc_msc_hid.h index 5f0502766..96617b107 100644 --- a/stmhal/usbdev/class/inc/usbd_cdc_msc_hid.h +++ b/stmhal/usbdev/class/inc/usbd_cdc_msc_hid.h @@ -28,10 +28,10 @@ typedef struct { } USBD_CDC_LineCodingTypeDef; typedef struct _USBD_CDC_Itf { - int8_t (* Init) (void); + int8_t (* Init) (USBD_HandleTypeDef *pdev); int8_t (* DeInit) (void); int8_t (* Control) (uint8_t, uint8_t * , uint16_t); - int8_t (* Receive) (uint8_t *, uint32_t *); + int8_t (* Receive) (USBD_HandleTypeDef *pdev, uint8_t *, uint32_t *); } USBD_CDC_ItfTypeDef; typedef struct { @@ -48,8 +48,8 @@ typedef struct { } USBD_CDC_HandleTypeDef; typedef struct _USBD_HID_Itf { - int8_t (* Init) (void); - int8_t (* Receive)(uint8_t *, uint32_t); + int8_t (* Init) (USBD_HandleTypeDef *pdev); + int8_t (* Receive)(USBD_HandleTypeDef *pdev, uint8_t *, uint32_t); } USBD_HID_ItfTypeDef; typedef struct _USBD_STORAGE { diff --git a/stmhal/usbdev/class/src/usbd_cdc_msc_hid.c b/stmhal/usbdev/class/src/usbd_cdc_msc_hid.c index cfae7224d..e0edf1370 100644 --- a/stmhal/usbdev/class/src/usbd_cdc_msc_hid.c +++ b/stmhal/usbdev/class/src/usbd_cdc_msc_hid.c @@ -669,7 +669,7 @@ static uint8_t USBD_CDC_MSC_HID_Init(USBD_HandleTypeDef *pdev, uint8_t cfgidx) { CDC_CMD_PACKET_SIZE); // Init physical Interface components - CDC_fops->Init(); + CDC_fops->Init(pdev); // Init Xfer states CDC_ClassData.TxState =0; @@ -724,7 +724,7 @@ static uint8_t USBD_CDC_MSC_HID_Init(USBD_HandleTypeDef *pdev, uint8_t cfgidx) { USBD_EP_TYPE_INTR, mps_out); - HID_fops->Init(); + HID_fops->Init(pdev); // Prepare Out endpoint to receive next packet USBD_LL_PrepareReceive(pdev, hid_out_ep, HID_ClassData.RxBuffer, mps_out); @@ -963,7 +963,7 @@ static uint8_t USBD_CDC_MSC_HID_DataOut(USBD_HandleTypeDef *pdev, uint8_t epnum) /* USB data will be immediately processed, this allow next USB traffic being NAKed till the end of the application Xfer */ - CDC_fops->Receive(CDC_ClassData.RxBuffer, &CDC_ClassData.RxLength); + CDC_fops->Receive(pdev, CDC_ClassData.RxBuffer, &CDC_ClassData.RxLength); return USBD_OK; } else if ((usbd_mode & USBD_MODE_MSC) && epnum == (MSC_OUT_EP & 0x7f)) { @@ -971,7 +971,7 @@ static uint8_t USBD_CDC_MSC_HID_DataOut(USBD_HandleTypeDef *pdev, uint8_t epnum) return USBD_OK; } else if ((usbd_mode & USBD_MODE_HID) && epnum == (hid_out_ep & 0x7f)) { HID_ClassData.RxLength = USBD_LL_GetRxDataSize(pdev, epnum); - HID_fops->Receive(HID_ClassData.RxBuffer, HID_ClassData.RxLength); + HID_fops->Receive(pdev, HID_ClassData.RxBuffer, HID_ClassData.RxLength); } return USBD_OK; -- cgit v1.2.3 From 22cedef95f671a4f769954ab7d0b30823bf446e8 Mon Sep 17 00:00:00 2001 From: Damien George Date: Sat, 3 Jun 2017 18:36:17 +1000 Subject: stmhal/usbdev: For MSC implement SCSI SYNCHRONIZE_CACHE command. Currently just a dummy command that returns "success", but it's needed for some O/S's to correctly talk with the SCSI layer. --- stmhal/usbdev/class/inc/usbd_msc_scsi.h | 2 ++ stmhal/usbdev/class/src/usbd_msc_scsi.c | 12 ++++++++++++ 2 files changed, 14 insertions(+) (limited to 'stmhal/usbdev/class') diff --git a/stmhal/usbdev/class/inc/usbd_msc_scsi.h b/stmhal/usbdev/class/inc/usbd_msc_scsi.h index dea247bca..34f059ee5 100644 --- a/stmhal/usbdev/class/inc/usbd_msc_scsi.h +++ b/stmhal/usbdev/class/inc/usbd_msc_scsi.h @@ -55,6 +55,8 @@ #define SCSI_MODE_SENSE6 0x1A #define SCSI_MODE_SENSE10 0x5A #define SCSI_ALLOW_MEDIUM_REMOVAL 0x1E +#define SCSI_SYNCHRONIZE_CACHE10 0x35 +#define SCSI_SYNCHRONIZE_CACHE16 0x91 #define SCSI_READ6 0x08 #define SCSI_READ10 0x28 #define SCSI_READ12 0xA8 diff --git a/stmhal/usbdev/class/src/usbd_msc_scsi.c b/stmhal/usbdev/class/src/usbd_msc_scsi.c index 366f1f00e..b2931b745 100644 --- a/stmhal/usbdev/class/src/usbd_msc_scsi.c +++ b/stmhal/usbdev/class/src/usbd_msc_scsi.c @@ -89,6 +89,7 @@ static int8_t SCSI_StartStopUnit(USBD_HandleTypeDef *pdev, uint8_t lun, uint8_t static int8_t SCSI_AllowMediumRemoval(USBD_HandleTypeDef *pdev, uint8_t lun, uint8_t *params); static int8_t SCSI_ModeSense6 (USBD_HandleTypeDef *pdev, uint8_t lun, uint8_t *params); static int8_t SCSI_ModeSense10 (USBD_HandleTypeDef *pdev, uint8_t lun, uint8_t *params); +static int8_t SCSI_SynchronizeCache(USBD_HandleTypeDef *pdev, uint8_t lun, uint8_t *params); static int8_t SCSI_Write10(USBD_HandleTypeDef *pdev, uint8_t lun , uint8_t *params); static int8_t SCSI_Read10(USBD_HandleTypeDef *pdev, uint8_t lun , uint8_t *params); static int8_t SCSI_Verify10(USBD_HandleTypeDef *pdev, uint8_t lun, uint8_t *params); @@ -151,6 +152,10 @@ int8_t SCSI_ProcessCmd(USBD_HandleTypeDef *pdev, case SCSI_MODE_SENSE10: return SCSI_ModeSense10 (pdev, lun, params); + case SCSI_SYNCHRONIZE_CACHE10: + case SCSI_SYNCHRONIZE_CACHE16: + return SCSI_SynchronizeCache(pdev, lun, params); + case SCSI_READ_FORMAT_CAPACITIES: return SCSI_ReadFormatCapacity(pdev, lun, params); @@ -374,6 +379,13 @@ static int8_t SCSI_ModeSense10 (USBD_HandleTypeDef *pdev, uint8_t lun, uint8_t return 0; } +static int8_t SCSI_SynchronizeCache(USBD_HandleTypeDef *pdev, uint8_t lun, uint8_t *params) { + // nothing to synchronize, so just return "success" + USBD_MSC_BOT_HandleTypeDef *hmsc = pdev->pClassData; + hmsc->bot_data_length = 0; + return 0; +} + /** * @brief SCSI_RequestSense * Process Request Sense command -- cgit v1.2.3