From 48a6c2e2a40cc601d41a1e633533b3586b27dd9a Mon Sep 17 00:00:00 2001 From: Robert Fisk Date: Tue, 25 Aug 2015 01:44:51 +1200 Subject: [PATCH] Bugfixes for Downstream, including one in the USB host stack! Downstream now enumerates and accepts attached USB storage devices. --- .../Downstream Debug.launch | 13 +- Downstream/Inc/downstream_statemachine.h | 1 + .../Class/MSC/Inc/usbh_msc_bot.h | 1 + .../Class/MSC/Src/usbh_msc.c | 2 +- .../Class/MSC/Src/usbh_msc_bot.c | 192 +++++++++++------- .../Class/MSC/Src/usbh_msc_scsi.c | 2 + .../Core/Inc/usbh_def.h | 3 + Downstream/Src/downstream_msc.c | 5 + 8 files changed, 140 insertions(+), 79 deletions(-) rename Upstream/Upstream Release.launch => Downstream/Downstream Debug.launch (90%) diff --git a/Upstream/Upstream Release.launch b/Downstream/Downstream Debug.launch similarity index 90% rename from Upstream/Upstream Release.launch rename to Downstream/Downstream Debug.launch index 50a5790..5f7fe32 100644 --- a/Upstream/Upstream Release.launch +++ b/Downstream/Downstream Debug.launch @@ -1,5 +1,6 @@ + @@ -15,7 +16,7 @@ - + @@ -47,12 +48,12 @@ - - + + - + - + @@ -60,6 +61,6 @@ - + diff --git a/Downstream/Inc/downstream_statemachine.h b/Downstream/Inc/downstream_statemachine.h index 8519826..84384b8 100644 --- a/Downstream/Inc/downstream_statemachine.h +++ b/Downstream/Inc/downstream_statemachine.h @@ -28,6 +28,7 @@ typedef enum do { \ LED_Fault_SetBlinkRate(LED_FAST_BLINK_RATE); \ DownstreamState = STATE_ERROR; \ + while (1); \ } while (0); diff --git a/Downstream/Middlewares/ST/STM32_USB_Host_Library/Class/MSC/Inc/usbh_msc_bot.h b/Downstream/Middlewares/ST/STM32_USB_Host_Library/Class/MSC/Inc/usbh_msc_bot.h index fba8501..6164a86 100644 --- a/Downstream/Middlewares/ST/STM32_USB_Host_Library/Class/MSC/Inc/usbh_msc_bot.h +++ b/Downstream/Middlewares/ST/STM32_USB_Host_Library/Class/MSC/Inc/usbh_msc_bot.h @@ -142,6 +142,7 @@ typedef struct uint8_t Reserved2[3]; uint8_t* pbuf; DownstreamPacketTypeDef* bot_packet; + uint8_t* bot_packet_pbuf; uint16_t bot_packet_bytes_remaining; uint16_t this_URB_size; } diff --git a/Downstream/Middlewares/ST/STM32_USB_Host_Library/Class/MSC/Src/usbh_msc.c b/Downstream/Middlewares/ST/STM32_USB_Host_Library/Class/MSC/Src/usbh_msc.c index d91988b..e805fbd 100644 --- a/Downstream/Middlewares/ST/STM32_USB_Host_Library/Class/MSC/Src/usbh_msc.c +++ b/Downstream/Middlewares/ST/STM32_USB_Host_Library/Class/MSC/Src/usbh_msc.c @@ -445,7 +445,7 @@ static USBH_StatusTypeDef USBH_MSC_Process(USBH_HandleTypeDef *phost) (MSC_Handle->unit[MSC_Handle->current_lun].sense.key == SCSI_SENSE_KEY_NOT_READY) ) { - if((phost->Timer - MSC_Handle->timeout) > 10000) + if((phost->Timer - MSC_Handle->timeout) < 10000) { MSC_Handle->unit[MSC_Handle->current_lun].state = MSC_TEST_UNIT_READY; break; diff --git a/Downstream/Middlewares/ST/STM32_USB_Host_Library/Class/MSC/Src/usbh_msc_bot.c b/Downstream/Middlewares/ST/STM32_USB_Host_Library/Class/MSC/Src/usbh_msc_bot.c index 3f8638f..29576f8 100644 --- a/Downstream/Middlewares/ST/STM32_USB_Host_Library/Class/MSC/Src/usbh_msc_bot.c +++ b/Downstream/Middlewares/ST/STM32_USB_Host_Library/Class/MSC/Src/usbh_msc_bot.c @@ -36,11 +36,12 @@ static USBH_StatusTypeDef USBH_MSC_BOT_Abort(USBH_HandleTypeDef *phost, uint8_t lun, uint8_t dir); static BOT_CSWStatusTypeDef USBH_MSC_DecodeCSW(USBH_HandleTypeDef *phost); -void USBH_MSC_BOT_Read_FreePacketCallback(DownstreamPacketTypeDef* freePacket); -void USBH_MSC_BOT_Read_PrepareURB(USBH_HandleTypeDef *phost); -void USBH_MSC_BOT_Write_ReceivePacketCallback(DownstreamPacketTypeDef* receivedPacket, +void USBH_MSC_BOT_Read_Multipacket_FreePacketCallback(DownstreamPacketTypeDef* freePacket); +void USBH_MSC_BOT_Read_Multipacket_PrepareURB(USBH_HandleTypeDef *phost); +void USBH_MSC_BOT_Write_Multipacket_ReceivePacketCallback(DownstreamPacketTypeDef* receivedPacket, uint16_t dataLength); -void USBH_MSC_BOT_Write_PrepareURB(USBH_HandleTypeDef *phost); +void USBH_MSC_BOT_Write_Multipacket_PrepareURB(USBH_HandleTypeDef *phost); + USBH_HandleTypeDef *Callback_MSC_phost; @@ -175,13 +176,26 @@ USBH_StatusTypeDef USBH_MSC_BOT_Process (USBH_HandleTypeDef *phost, uint8_t lun) } break; - case BOT_DATA_IN: - /* Get first packet */ - Callback_MSC_phost = phost; + case BOT_DATA_IN: MSC_Handle->hbot.state = BOT_DATA_IN_WAIT; - if (Downstream_GetFreePacket(USBH_MSC_BOT_Read_FreePacketCallback) != HAL_OK) + if (MSC_Handle->hbot.pbuf != NULL) + { + //Simple single-buffer operation + MSC_Handle->hbot.this_URB_size = MIN(MSC_Handle->hbot.cbw.field.DataTransferLength, + MSC_Handle->InEpSize); + USBH_BulkReceiveData (phost, + MSC_Handle->hbot.pbuf, + MSC_Handle->hbot.this_URB_size, + MSC_Handle->InPipe); + } + else { - MSC_Handle->hbot.state = BOT_ERROR_IN; + //Asynchronous multi-packet operation: get first packet + Callback_MSC_phost = phost; + if (Downstream_GetFreePacket(USBH_MSC_BOT_Read_Multipacket_FreePacketCallback) != HAL_OK) + { + MSC_Handle->hbot.state = BOT_ERROR_IN; + } } break; @@ -191,39 +205,49 @@ USBH_StatusTypeDef USBH_MSC_BOT_Process (USBH_HandleTypeDef *phost, uint8_t lun) if (URB_Status == USBH_URB_DONE) { MSC_Handle->hbot.cbw.field.DataTransferLength -= MSC_Handle->hbot.this_URB_size; - MSC_Handle->hbot.bot_packet_bytes_remaining -= MSC_Handle->hbot.this_URB_size; - MSC_Handle->hbot.pbuf += MSC_Handle->hbot.this_URB_size; - if (MSC_Handle->hbot.cbw.field.DataTransferLength == 0) + if (MSC_Handle->hbot.pbuf != NULL) { - //End of reception: dispatch last packet - MSC_Handle->hbot.state = BOT_RECEIVE_CSW; - Downstream_MSC_PutStreamDataPacket(MSC_Handle->hbot.bot_packet, - (BOT_PAGE_LENGTH - MSC_Handle->hbot.bot_packet_bytes_remaining)); + //Simple single-buffer operation: everything must fit in one URB + MSC_Handle->hbot.state = BOT_RECEIVE_CSW; } else { - //Still more data to receive - if (MSC_Handle->hbot.bot_packet_bytes_remaining == 0) - { - //Dispatch current bot_packet, then get a new one - if (Downstream_MSC_PutStreamDataPacket(MSC_Handle->hbot.bot_packet, - (BOT_PAGE_LENGTH - MSC_Handle->hbot.bot_packet_bytes_remaining)) != HAL_OK) - { - MSC_Handle->hbot.state = BOT_ERROR_IN; - break; - } - if (Downstream_GetFreePacket(USBH_MSC_BOT_Read_FreePacketCallback) != HAL_OK) - { - MSC_Handle->hbot.state = BOT_ERROR_IN; - break; - } - } - else - { - //Continue filling the current bot_packet - USBH_MSC_BOT_Read_PrepareURB(phost); - } + //Asynchronous multi-packet operation + MSC_Handle->hbot.bot_packet_bytes_remaining -= MSC_Handle->hbot.this_URB_size; + MSC_Handle->hbot.bot_packet_pbuf += MSC_Handle->hbot.this_URB_size; + + if (MSC_Handle->hbot.cbw.field.DataTransferLength == 0) + { + //End of reception: dispatch last packet + MSC_Handle->hbot.state = BOT_RECEIVE_CSW; + Downstream_MSC_PutStreamDataPacket(MSC_Handle->hbot.bot_packet, + (BOT_PAGE_LENGTH - MSC_Handle->hbot.bot_packet_bytes_remaining)); + } + else + { + //Still more data to receive + if (MSC_Handle->hbot.bot_packet_bytes_remaining == 0) + { + //Dispatch current bot_packet, then get a new one + if (Downstream_MSC_PutStreamDataPacket(MSC_Handle->hbot.bot_packet, + (BOT_PAGE_LENGTH - MSC_Handle->hbot.bot_packet_bytes_remaining)) != HAL_OK) + { + MSC_Handle->hbot.state = BOT_ERROR_IN; + break; + } + if (Downstream_GetFreePacket(USBH_MSC_BOT_Read_Multipacket_FreePacketCallback) != HAL_OK) + { + MSC_Handle->hbot.state = BOT_ERROR_IN; + break; + } + } + else + { + //Continue filling the current bot_packet + USBH_MSC_BOT_Read_Multipacket_PrepareURB(phost); + } + } } } @@ -242,11 +266,26 @@ USBH_StatusTypeDef USBH_MSC_BOT_Process (USBH_HandleTypeDef *phost, uint8_t lun) break; case BOT_DATA_OUT: - Callback_MSC_phost = phost; MSC_Handle->hbot.state = BOT_DATA_OUT_WAIT; - if (Downstream_MSC_GetStreamDataPacket(USBH_MSC_BOT_Write_ReceivePacketCallback) != HAL_OK) + if (MSC_Handle->hbot.pbuf != NULL) { - MSC_Handle->hbot.state = BOT_ERROR_OUT; + //Simple single-buffer operation + MSC_Handle->hbot.this_URB_size = MIN(MSC_Handle->hbot.cbw.field.DataTransferLength, + MSC_Handle->OutEpSize); + USBH_BulkSendData (phost, + MSC_Handle->hbot.pbuf, + MSC_Handle->hbot.this_URB_size, + MSC_Handle->OutPipe, + 1); + } + else + { + //Asynchronous multi-packet operation: get first packet + Callback_MSC_phost = phost; + if (Downstream_MSC_GetStreamDataPacket(USBH_MSC_BOT_Write_Multipacket_ReceivePacketCallback) != HAL_OK) + { + MSC_Handle->hbot.state = BOT_ERROR_OUT; + } } break; @@ -256,30 +295,39 @@ USBH_StatusTypeDef USBH_MSC_BOT_Process (USBH_HandleTypeDef *phost, uint8_t lun) if(URB_Status == USBH_URB_DONE) { MSC_Handle->hbot.cbw.field.DataTransferLength -= MSC_Handle->hbot.this_URB_size; - MSC_Handle->hbot.bot_packet_bytes_remaining -= MSC_Handle->hbot.this_URB_size; - MSC_Handle->hbot.pbuf += MSC_Handle->hbot.this_URB_size; - if (MSC_Handle->hbot.cbw.field.DataTransferLength == 0) - { - //End of reception - MSC_Handle->hbot.state = BOT_RECEIVE_CSW; - } + if (MSC_Handle->hbot.pbuf != NULL) + { + //Simple single-buffer operation: everything must fit in one URB + MSC_Handle->hbot.state = BOT_RECEIVE_CSW; + } else { - //Still more data to receive - if (MSC_Handle->hbot.bot_packet_bytes_remaining == 0) - { - //Get next bot_packet - if (Downstream_MSC_GetStreamDataPacket(USBH_MSC_BOT_Write_ReceivePacketCallback) != HAL_OK) - { - MSC_Handle->hbot.state = BOT_ERROR_OUT; - } - } - else - { - //Continue reading the current bot_packet - USBH_MSC_BOT_Write_PrepareURB(phost); - } + //Asynchronous multi-packet operation + MSC_Handle->hbot.bot_packet_bytes_remaining -= MSC_Handle->hbot.this_URB_size; + MSC_Handle->hbot.bot_packet_pbuf += MSC_Handle->hbot.this_URB_size; + if (MSC_Handle->hbot.cbw.field.DataTransferLength == 0) + { + //End of transmission + MSC_Handle->hbot.state = BOT_RECEIVE_CSW; + } + else + { + //Still more data to send + if (MSC_Handle->hbot.bot_packet_bytes_remaining == 0) + { + //Get next bot_packet + if (Downstream_MSC_GetStreamDataPacket(USBH_MSC_BOT_Write_Multipacket_ReceivePacketCallback) != HAL_OK) + { + MSC_Handle->hbot.state = BOT_ERROR_OUT; + } + } + else + { + //Continue writing the current bot_packet + USBH_MSC_BOT_Write_Multipacket_PrepareURB(phost); + } + } } } @@ -385,7 +433,7 @@ USBH_StatusTypeDef USBH_MSC_BOT_Process (USBH_HandleTypeDef *phost, uint8_t lun) } -void USBH_MSC_BOT_Read_FreePacketCallback(DownstreamPacketTypeDef* freePacket) +void USBH_MSC_BOT_Read_Multipacket_FreePacketCallback(DownstreamPacketTypeDef* freePacket) { MSC_HandleTypeDef *MSC_Handle = (MSC_HandleTypeDef *) Callback_MSC_phost->pActiveClass->pData; @@ -396,13 +444,13 @@ void USBH_MSC_BOT_Read_FreePacketCallback(DownstreamPacketTypeDef* freePacket) } MSC_Handle->hbot.bot_packet = freePacket; - MSC_Handle->hbot.pbuf = freePacket->Data; + MSC_Handle->hbot.bot_packet_pbuf = freePacket->Data; MSC_Handle->hbot.bot_packet_bytes_remaining = BOT_PAGE_LENGTH; - USBH_MSC_BOT_Read_PrepareURB(Callback_MSC_phost); + USBH_MSC_BOT_Read_Multipacket_PrepareURB(Callback_MSC_phost); } -void USBH_MSC_BOT_Read_PrepareURB(USBH_HandleTypeDef *phost) +void USBH_MSC_BOT_Read_Multipacket_PrepareURB(USBH_HandleTypeDef *phost) { MSC_HandleTypeDef *MSC_Handle = (MSC_HandleTypeDef *) phost->pActiveClass->pData; @@ -417,14 +465,14 @@ void USBH_MSC_BOT_Read_PrepareURB(USBH_HandleTypeDef *phost) } USBH_BulkReceiveData(phost, - MSC_Handle->hbot.pbuf, + MSC_Handle->hbot.bot_packet_pbuf, MSC_Handle->hbot.this_URB_size, MSC_Handle->InPipe); } -void USBH_MSC_BOT_Write_ReceivePacketCallback(DownstreamPacketTypeDef* receivedPacket, - uint16_t dataLength) +void USBH_MSC_BOT_Write_Multipacket_ReceivePacketCallback(DownstreamPacketTypeDef* receivedPacket, + uint16_t dataLength) { MSC_HandleTypeDef *MSC_Handle = (MSC_HandleTypeDef *) Callback_MSC_phost->pActiveClass->pData; @@ -435,13 +483,13 @@ void USBH_MSC_BOT_Write_ReceivePacketCallback(DownstreamPacketTypeDef* receivedP } MSC_Handle->hbot.bot_packet = receivedPacket; - MSC_Handle->hbot.pbuf = receivedPacket->Data; + MSC_Handle->hbot.bot_packet_pbuf = receivedPacket->Data; MSC_Handle->hbot.bot_packet_bytes_remaining = dataLength; - USBH_MSC_BOT_Write_PrepareURB(Callback_MSC_phost); + USBH_MSC_BOT_Write_Multipacket_PrepareURB(Callback_MSC_phost); } -void USBH_MSC_BOT_Write_PrepareURB(USBH_HandleTypeDef *phost) +void USBH_MSC_BOT_Write_Multipacket_PrepareURB(USBH_HandleTypeDef *phost) { MSC_HandleTypeDef *MSC_Handle = (MSC_HandleTypeDef *) phost->pActiveClass->pData; @@ -455,7 +503,7 @@ void USBH_MSC_BOT_Write_PrepareURB(USBH_HandleTypeDef *phost) MSC_Handle->hbot.this_URB_size = MSC_Handle->OutEpSize; } USBH_BulkSendData (phost, - MSC_Handle->hbot.pbuf, + MSC_Handle->hbot.bot_packet_pbuf, MSC_Handle->hbot.this_URB_size, MSC_Handle->OutPipe, 1); diff --git a/Downstream/Middlewares/ST/STM32_USB_Host_Library/Class/MSC/Src/usbh_msc_scsi.c b/Downstream/Middlewares/ST/STM32_USB_Host_Library/Class/MSC/Src/usbh_msc_scsi.c index d4122fa..ac7ed08 100644 --- a/Downstream/Middlewares/ST/STM32_USB_Host_Library/Class/MSC/Src/usbh_msc_scsi.c +++ b/Downstream/Middlewares/ST/STM32_USB_Host_Library/Class/MSC/Src/usbh_msc_scsi.c @@ -352,6 +352,7 @@ USBH_StatusTypeDef USBH_MSC_SCSI_Write(USBH_HandleTypeDef *phost, MSC_Handle->hbot.state = BOT_SEND_CBW; MSC_Handle->hbot.cmd_state = BOT_CMD_WAIT; + MSC_Handle->hbot.pbuf = NULL; error = USBH_BUSY; break; @@ -408,6 +409,7 @@ USBH_StatusTypeDef USBH_MSC_SCSI_Read(USBH_HandleTypeDef *phost, MSC_Handle->hbot.state = BOT_SEND_CBW; MSC_Handle->hbot.cmd_state = BOT_CMD_WAIT; + MSC_Handle->hbot.pbuf = NULL; error = USBH_BUSY; break; diff --git a/Downstream/Middlewares/ST/STM32_USB_Host_Library/Core/Inc/usbh_def.h b/Downstream/Middlewares/ST/STM32_USB_Host_Library/Core/Inc/usbh_def.h index 69db4f9..4dfaa59 100644 --- a/Downstream/Middlewares/ST/STM32_USB_Host_Library/Core/Inc/usbh_def.h +++ b/Downstream/Middlewares/ST/STM32_USB_Host_Library/Core/Inc/usbh_def.h @@ -94,6 +94,9 @@ #define LE32S(addr) (int32_t)(LE32((addr))) +#define MIN(a, b) (((a) < (b)) ? (a) : (b)) +#define MAX(a, b) (((a) > (b)) ? (a) : (b)) + #define USB_LEN_DESC_HDR 0x02 #define USB_LEN_DEV_DESC 0x12 diff --git a/Downstream/Src/downstream_msc.c b/Downstream/Src/downstream_msc.c index 3c89941..a73671d 100644 --- a/Downstream/Src/downstream_msc.c +++ b/Downstream/Src/downstream_msc.c @@ -37,6 +37,11 @@ HAL_StatusTypeDef Downstream_MSC_ApproveConnectedDevice(void) { MSC_HandleTypeDef* MSC_Handle = (MSC_HandleTypeDef*)hUsbHostFS.pActiveClass->pData; + if (MSC_Handle->unit[MSC_FIXED_LUN].error != MSC_OK) + { + return HAL_ERROR; + } + if ((MSC_Handle->unit[MSC_FIXED_LUN].capacity.block_nbr == 0) || (MSC_Handle->unit[MSC_FIXED_LUN].capacity.block_nbr == UINT32_MAX)) {