From 9296d466940e898c165e5860778fcc51491b18ef Mon Sep 17 00:00:00 2001 From: Michael McMaster Date: Sun, 6 Feb 2022 14:36:24 +1000 Subject: [PATCH] Improve SD hotswap detection --- src/firmware/disk.c | 2 +- src/firmware/main.c | 5 +- src/firmware/sd.c | 422 +++++++++++----------- src/firmware/usb_device/usbd_composite.c | 430 +++++++++++------------ 4 files changed, 435 insertions(+), 424 deletions(-) diff --git a/src/firmware/disk.c b/src/firmware/disk.c index 6069eeb1..a9d91693 100755 --- a/src/firmware/disk.c +++ b/src/firmware/disk.c @@ -301,7 +301,7 @@ static void doSeek(uint32_t lba) } else { - s2s_delay_ms(1); + s2s_delay_us(10); } } } diff --git a/src/firmware/main.c b/src/firmware/main.c index f79ebd6e..4873334b 100755 --- a/src/firmware/main.c +++ b/src/firmware/main.c @@ -154,10 +154,9 @@ void mainLoop() sdPoll(); #endif - // TODO test if USB transfer is in progress if (unlikely(scsiDev.phase == BUS_FREE) && !usbBusy) { - if (unlikely(s2s_elapsedTime_ms(lastSDPoll) > 200)) + if (unlikely(s2s_elapsedTime_ms(lastSDPoll) > 377)) { lastSDPoll = s2s_getTime_ms(); if (sdInit()) @@ -181,7 +180,7 @@ void mainLoop() } } } - else if (lastSDKeepAlive > 10000) // 10 seconds + else if (s2s_elapsedTime_ms(lastSDKeepAlive) > 10000) // 10 seconds { // 2021 boards fail if there's no commands sent in a while sdKeepAlive(); diff --git a/src/firmware/sd.c b/src/firmware/sd.c index 7985b3ef..d717fb25 100755 --- a/src/firmware/sd.c +++ b/src/firmware/sd.c @@ -1,19 +1,19 @@ -// Copyright (C) 2013 Michael McMaster +// Copyright (C) 2013 Michael McMaster // -// This file is part of SCSI2SD. +// This file is part of SCSI2SD. // -// SCSI2SD is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. +// SCSI2SD is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. // -// SCSI2SD is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. +// SCSI2SD is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. // -// You should have received a copy of the GNU General Public License -// along with SCSI2SD. If not, see . +// You should have received a copy of the GNU General Public License +// along with SCSI2SD. If not, see . #ifdef STM32F2xx #include "stm32f2xx.h" @@ -46,243 +46,252 @@ static int sdCmdActive = 0; int sdReadDMAPoll(uint32_t remainingSectors) { - // TODO DMA byte counting disabled for now as it's not - // working. - // We can ask the SDIO controller how many bytes have been - // processed (SDIO_GetDataCounter()) but I'm not sure if that - // means the data has been transfered via dma to memory yet. -// uint32_t dmaBytesRemaining = __HAL_DMA_GET_COUNTER(hsd.hdmarx) * 4; - - if (HAL_SD_GetState(&hsd) != HAL_SD_STATE_BUSY) - { - // DMA transfer is complete - sdCmdActive = 0; - return remainingSectors; - } -/* else - { - return remainingSectors - ((dmaBytesRemaining + (SD_SECTOR_SIZE - 1)) / SD_SECTOR_SIZE); - }*/ - return 0; + // TODO DMA byte counting disabled for now as it's not + // working. + // We can ask the SDIO controller how many bytes have been + // processed (SDIO_GetDataCounter()) but I'm not sure if that + // means the data has been transfered via dma to memory yet. +// uint32_t dmaBytesRemaining = __HAL_DMA_GET_COUNTER(hsd.hdmarx) * 4; + + if (HAL_SD_GetState(&hsd) != HAL_SD_STATE_BUSY) + { + // DMA transfer is complete + sdCmdActive = 0; + return remainingSectors; + } +/* else + { + return remainingSectors - ((dmaBytesRemaining + (SD_SECTOR_SIZE - 1)) / SD_SECTOR_SIZE); + }*/ + return 0; } void sdReadDMA(uint32_t lba, uint32_t sectors, uint8_t* outputBuffer) { - if (HAL_SD_ReadBlocks_DMA(&hsd, outputBuffer, lba, sectors) != HAL_OK) - { - scsiDiskReset(); - - scsiDev.status = CHECK_CONDITION; - scsiDev.target->sense.code = HARDWARE_ERROR; - scsiDev.target->sense.asc = LOGICAL_UNIT_COMMUNICATION_FAILURE; - scsiDev.phase = STATUS; - } - else - { - sdCmdActive = 1; - } + if (HAL_SD_ReadBlocks_DMA(&hsd, outputBuffer, lba, sectors) != HAL_OK) + { + scsiDiskReset(); + + scsiDev.status = CHECK_CONDITION; + scsiDev.target->sense.code = HARDWARE_ERROR; + scsiDev.target->sense.asc = LOGICAL_UNIT_COMMUNICATION_FAILURE; + scsiDev.phase = STATUS; + } + else + { + sdCmdActive = 1; + } } void sdReadCmd(uint32_t lba, uint32_t sectors) { - uint32_t errorstate; - hsd.ErrorCode = HAL_SD_ERROR_NONE; - hsd.State = HAL_SD_STATE_BUSY; + uint32_t errorstate; + hsd.ErrorCode = HAL_SD_ERROR_NONE; + hsd.State = HAL_SD_STATE_BUSY; - /* Initialize data control register */ - hsd.Instance->DCTRL = 0U; + /* Initialize data control register */ + hsd.Instance->DCTRL = 0U; - // The IRQ handler clears flags which we need to read the fifo data + // The IRQ handler clears flags which we need to read the fifo data #if defined(SDIO_STA_STBITERR) __HAL_SD_DISABLE_IT(&hsd, (SDIO_IT_DCRCFAIL | SDIO_IT_DTIMEOUT | SDIO_IT_RXOVERR | SDIO_IT_DATAEND | SDIO_FLAG_RXFIFOHF | SDIO_IT_STBITERR)); #else __HAL_SD_DISABLE_IT(&hsd, (SDIO_IT_DCRCFAIL | SDIO_IT_DTIMEOUT | SDIO_IT_RXOVERR | SDIO_IT_DATAEND | SDIO_FLAG_RXFIFOHF)); #endif - if(hsd.SdCard.CardType != CARD_SDHC_SDXC) - { - lba *= 512U; - - errorstate = SDMMC_CmdBlockLength(hsd.Instance, 512u); - if(errorstate != HAL_SD_ERROR_NONE) - { - __HAL_SD_CLEAR_FLAG(&hsd, SDIO_STATIC_FLAGS); - scsiDiskReset(); - - scsiDev.status = CHECK_CONDITION; - scsiDev.target->sense.code = HARDWARE_ERROR; - scsiDev.target->sense.asc = LOGICAL_UNIT_COMMUNICATION_FAILURE; - scsiDev.phase = STATUS; - return; - } - } - - if(sectors > 1U) - { - hsd.Context = SD_CONTEXT_READ_MULTIPLE_BLOCK; - errorstate = SDMMC_CmdReadMultiBlock(hsd.Instance, lba); - } - else - { - hsd.Context = SD_CONTEXT_READ_SINGLE_BLOCK; - errorstate = SDMMC_CmdReadSingleBlock(hsd.Instance, lba); - } - - if(errorstate != HAL_SD_ERROR_NONE) - { - __HAL_SD_CLEAR_FLAG(&hsd, SDIO_STATIC_FLAGS); - - scsiDiskReset(); - - scsiDev.status = CHECK_CONDITION; - scsiDev.target->sense.code = HARDWARE_ERROR; - scsiDev.target->sense.asc = LOGICAL_UNIT_COMMUNICATION_FAILURE; - scsiDev.phase = STATUS; - } - else - { - sdCmdActive = 1; - } + if(hsd.SdCard.CardType != CARD_SDHC_SDXC) + { + lba *= 512U; + + errorstate = SDMMC_CmdBlockLength(hsd.Instance, 512u); + if(errorstate != HAL_SD_ERROR_NONE) + { + __HAL_SD_CLEAR_FLAG(&hsd, SDIO_STATIC_FLAGS); + scsiDiskReset(); + + scsiDev.status = CHECK_CONDITION; + scsiDev.target->sense.code = HARDWARE_ERROR; + scsiDev.target->sense.asc = LOGICAL_UNIT_COMMUNICATION_FAILURE; + scsiDev.phase = STATUS; + return; + } + } + + if(sectors > 1U) + { + hsd.Context = SD_CONTEXT_READ_MULTIPLE_BLOCK; + errorstate = SDMMC_CmdReadMultiBlock(hsd.Instance, lba); + } + else + { + hsd.Context = SD_CONTEXT_READ_SINGLE_BLOCK; + errorstate = SDMMC_CmdReadSingleBlock(hsd.Instance, lba); + } + + if(errorstate != HAL_SD_ERROR_NONE) + { + __HAL_SD_CLEAR_FLAG(&hsd, SDIO_STATIC_FLAGS); + + scsiDiskReset(); + + scsiDev.status = CHECK_CONDITION; + scsiDev.target->sense.code = HARDWARE_ERROR; + scsiDev.target->sense.asc = LOGICAL_UNIT_COMMUNICATION_FAILURE; + scsiDev.phase = STATUS; + } + else + { + sdCmdActive = 1; + } } void sdReadPIOData(uint32_t sectors) { - /* Initialize data control register */ - hsd.Instance->DCTRL = 0U; - - SDIO_DataInitTypeDef config; - config.DataTimeOut = SDMMC_DATATIMEOUT; - config.DataLength = sectors * 512u; - config.DataBlockSize = SDIO_DATABLOCK_SIZE_512B; - config.TransferDir = SDIO_TRANSFER_DIR_TO_SDIO; - config.TransferMode = SDIO_TRANSFER_MODE_BLOCK; - config.DPSM = SDIO_DPSM_ENABLE; - SDIO_ConfigData(hsd.Instance, &config); + /* Initialize data control register */ + hsd.Instance->DCTRL = 0U; + + SDIO_DataInitTypeDef config; + config.DataTimeOut = SDMMC_DATATIMEOUT; + config.DataLength = sectors * 512u; + config.DataBlockSize = SDIO_DATABLOCK_SIZE_512B; + config.TransferDir = SDIO_TRANSFER_DIR_TO_SDIO; + config.TransferMode = SDIO_TRANSFER_MODE_BLOCK; + config.DPSM = SDIO_DPSM_ENABLE; + SDIO_ConfigData(hsd.Instance, &config); } void sdCompleteTransfer() { - if (sdCmdActive) - { - HAL_SD_Abort(&hsd); - sdCmdActive = 0; - } + if (sdCmdActive) + { + HAL_SD_Abort(&hsd); + sdCmdActive = 0; + } } static void sdClear() { - sdDev.version = 0; - sdDev.capacity = 0; - memset(sdDev.csd, 0, sizeof(sdDev.csd)); - memset(sdDev.cid, 0, sizeof(sdDev.cid)); + sdDev.version = 0; + sdDev.capacity = 0; + memset(sdDev.csd, 0, sizeof(sdDev.csd)); + memset(sdDev.cid, 0, sizeof(sdDev.cid)); } static int sdDoInit() { - int result = 0; + int result = 0; - sdClear(); + sdClear(); - int8_t error = BSP_SD_Init(); - if (error == MSD_OK) - { - HAL_SD_CardInfoTypeDef cardInfo; - HAL_SD_GetCardInfo(&hsd, &cardInfo); - memcpy(sdDev.csd, hsd.CSD, sizeof(sdDev.csd)); - memcpy(sdDev.cid, hsd.CID, sizeof(sdDev.cid)); - sdDev.capacity = cardInfo.LogBlockNbr; - blockDev.state |= DISK_PRESENT | DISK_INITIALISED; - result = 1; + int8_t error = BSP_SD_Init(); + if (error == MSD_OK) + { + HAL_SD_CardInfoTypeDef cardInfo; + HAL_SD_GetCardInfo(&hsd, &cardInfo); + memcpy(sdDev.csd, hsd.CSD, sizeof(sdDev.csd)); + memcpy(sdDev.cid, hsd.CID, sizeof(sdDev.cid)); + sdDev.capacity = cardInfo.LogBlockNbr; + blockDev.state |= DISK_PRESENT | DISK_INITIALISED; + result = 1; - goto out; - } + goto out; + } //bad: - blockDev.state &= ~(DISK_PRESENT | DISK_INITIALISED); + blockDev.state &= ~(DISK_PRESENT | DISK_INITIALISED); - sdDev.capacity = 0; + sdDev.capacity = 0; out: - s2s_ledOff(); - return result; + s2s_ledOff(); + return result; } int sdInit() { - // Check if there's an SD card present. - int result = 0; - - static int firstInit = 1; - - if (firstInit) - { - blockDev.state &= ~(DISK_PRESENT | DISK_INITIALISED); - sdClear(); - } - - if (firstInit || (scsiDev.phase == BUS_FREE)) - { - uint8_t cs = HAL_GPIO_ReadPin(nSD_CD_GPIO_Port, nSD_CD_Pin) ? 0 : 1; - uint8_t wp = HAL_GPIO_ReadPin(nSD_WP_GPIO_Port, nSD_WP_Pin) ? 0 : 1; - - if (cs && !(blockDev.state & DISK_PRESENT)) - { - s2s_ledOn(); - - // Debounce - if (!firstInit) - { - s2s_delay_ms(250); - } - - if (sdDoInit()) - { - blockDev.state |= DISK_PRESENT | DISK_INITIALISED; - - if (wp) - { - blockDev.state |= DISK_WP; - } - else - { - blockDev.state &= ~DISK_WP; - } - - result = 1; - - s2s_ledOff(); - } - else - { - for (int i = 0; i < 10; ++i) - { - // visual indicator of SD error - s2s_ledOff(); - s2s_delay_ms(50); - s2s_ledOn(); - s2s_delay_ms(50); - } - s2s_ledOff(); - } - } - else if (!cs && (blockDev.state & DISK_PRESENT)) - { - sdDev.capacity = 0; - blockDev.state &= ~DISK_PRESENT; - blockDev.state &= ~DISK_INITIALISED; - int i; - for (i = 0; i < S2S_MAX_TARGETS; ++i) - { - scsiDev.targets[i].unitAttention = PARAMETERS_CHANGED; - } - - HAL_SD_DeInit(&hsd); - } - } - firstInit = 0; - - return result; + // Check if there's an SD card present. + int result = 0; + + static int firstInit = 1; + + if (firstInit) + { + blockDev.state &= ~(DISK_PRESENT | DISK_INITIALISED); + sdClear(); + } + + if (firstInit || (scsiDev.phase == BUS_FREE)) + { + uint8_t cs = HAL_GPIO_ReadPin(nSD_CD_GPIO_Port, nSD_CD_Pin) ? 0 : 1; + + if (cs && !(blockDev.state & DISK_PRESENT)) + { + s2s_ledOn(); + + // Debounce. Quicker if the card is present at + // power on + if (!firstInit) + { + for (int i = 0; cs && i < 50; ++i) + { + cs = HAL_GPIO_ReadPin(nSD_CD_GPIO_Port, nSD_CD_Pin) ? 0 : 1; + s2s_delay_ms(5); + } + } + + if (cs && sdDoInit()) + { + blockDev.state |= DISK_PRESENT | DISK_INITIALISED; + + uint8_t wp = HAL_GPIO_ReadPin(nSD_WP_GPIO_Port, nSD_WP_Pin) ? 0 : 1; + if (wp) + { + blockDev.state |= DISK_WP; + } + else + { + blockDev.state &= ~DISK_WP; + } + + result = 1; + + s2s_ledOff(); + } + else if (cs) + { + for (int i = 0; i < 10; ++i) + { + // visual indicator of SD error + s2s_ledOff(); + s2s_delay_ms(50); + s2s_ledOn(); + s2s_delay_ms(50); + } + s2s_ledOff(); + } + else + { + s2s_ledOff(); + } + } + else if (!cs && (blockDev.state & DISK_PRESENT)) + { + sdDev.capacity = 0; + blockDev.state &= ~DISK_PRESENT; + blockDev.state &= ~DISK_INITIALISED; + int i; + for (i = 0; i < S2S_MAX_TARGETS; ++i) + { + scsiDev.targets[i].unitAttention = PARAMETERS_CHANGED; + } + + HAL_SD_DeInit(&hsd); + } + } + firstInit = 0; + + return result; } // Return 1 if the SD card has no buffer space left for writes and/or is @@ -295,5 +304,8 @@ int sdIsBusy() void sdKeepAlive() { - /*HAL_SD_CardStateTypeDef cardState = */HAL_SD_GetCardState(&hsd); + if (blockDev.state & DISK_PRESENT) + { + /*HAL_SD_CardStateTypeDef cardState = */HAL_SD_GetCardState(&hsd); + } } diff --git a/src/firmware/usb_device/usbd_composite.c b/src/firmware/usb_device/usbd_composite.c index a545b8ba..8d724d96 100755 --- a/src/firmware/usb_device/usbd_composite.c +++ b/src/firmware/usb_device/usbd_composite.c @@ -55,20 +55,20 @@ static uint8_t USBD_Composite_DataOut (USBD_HandleTypeDef *pdev, uint8_t epnum) USBD_ClassTypeDef USBD_Composite = { - USBD_Composite_Init, - USBD_Composite_DeInit, - USBD_Composite_Setup, - NULL, /*EP0_TxSent*/ - NULL, /*EP0_RxReady*/ - USBD_Composite_DataIn, /*DataIn*/ - USBD_Composite_DataOut, /*DataOut*/ - NULL, /*SOF */ - NULL, - NULL, - USBD_Composite_GetHSCfgDesc, - USBD_Composite_GetFSCfgDesc, - USBD_Composite_GetFSCfgDesc, // "Other" speed - USBD_Composite_GetDeviceQualifierDesc, + USBD_Composite_Init, + USBD_Composite_DeInit, + USBD_Composite_Setup, + NULL, /*EP0_TxSent*/ + NULL, /*EP0_RxReady*/ + USBD_Composite_DataIn, /*DataIn*/ + USBD_Composite_DataOut, /*DataOut*/ + NULL, /*SOF */ + NULL, + NULL, + USBD_Composite_GetHSCfgDesc, + USBD_Composite_GetFSCfgDesc, + USBD_Composite_GetFSCfgDesc, // "Other" speed + USBD_Composite_GetDeviceQualifierDesc, }; __ALIGN_BEGIN static uint8_t USBD_Composite_CfgHSDesc[USB_COMPOSITE_CONFIG_DESC_SIZ] __ALIGN_END = @@ -267,263 +267,263 @@ __ALIGN_BEGIN static uint8_t USBD_Composite_DeviceQualifierDesc[USB_LEN_DEV_QUAL static uint8_t USBD_Composite_Init(USBD_HandleTypeDef *pdev, uint8_t cfgidx) { - uint8_t ret = 0; + uint8_t ret = 0; - // HID Endpoints - USBD_LL_OpenEP(pdev, HID_EPIN_ADDR, USBD_EP_TYPE_INTR, HID_EPIN_SIZE); - USBD_LL_OpenEP(pdev, HID_EPOUT_ADDR, USBD_EP_TYPE_INTR, HID_EPOUT_SIZE); + // HID Endpoints + USBD_LL_OpenEP(pdev, HID_EPIN_ADDR, USBD_EP_TYPE_INTR, HID_EPIN_SIZE); + USBD_LL_OpenEP(pdev, HID_EPOUT_ADDR, USBD_EP_TYPE_INTR, HID_EPOUT_SIZE); - USBD_CompositeClassData* classData; + USBD_CompositeClassData* classData; #ifdef S2S_USB_HS if(pdev->dev_speed == USBD_SPEED_HIGH) - { - classData = &hsClassData; + { + classData = &hsClassData; - // MSC Endpoints - USBD_LL_OpenEP(pdev, MSC_EPOUT_ADDR, USBD_EP_TYPE_BULK, MSC_MAX_HS_PACKET); - USBD_LL_OpenEP(pdev, MSC_EPIN_ADDR, USBD_EP_TYPE_BULK, MSC_MAX_HS_PACKET); - } + // MSC Endpoints + USBD_LL_OpenEP(pdev, MSC_EPOUT_ADDR, USBD_EP_TYPE_BULK, MSC_MAX_HS_PACKET); + USBD_LL_OpenEP(pdev, MSC_EPIN_ADDR, USBD_EP_TYPE_BULK, MSC_MAX_HS_PACKET); + } #endif #ifdef S2S_USB_FS if(pdev->dev_speed != USBD_SPEED_HIGH) - { - classData = &fsClassData; + { + classData = &fsClassData; - // MSC Endpoints - USBD_LL_OpenEP(pdev, MSC_EPOUT_ADDR, USBD_EP_TYPE_BULK, MSC_MAX_FS_PACKET); - USBD_LL_OpenEP(pdev, MSC_EPIN_ADDR, USBD_EP_TYPE_BULK, MSC_MAX_FS_PACKET); - } + // MSC Endpoints + USBD_LL_OpenEP(pdev, MSC_EPOUT_ADDR, USBD_EP_TYPE_BULK, MSC_MAX_FS_PACKET); + USBD_LL_OpenEP(pdev, MSC_EPIN_ADDR, USBD_EP_TYPE_BULK, MSC_MAX_FS_PACKET); + } #endif - classData->hid.state = HID_IDLE; - classData->hid.reportReady = 0; - classData->DataInReady = 0; - classData->DataOutReady = 0; - pdev->pClassData = classData; + classData->hid.state = HID_IDLE; + classData->hid.reportReady = 0; + classData->DataInReady = 0; + classData->DataOutReady = 0; + pdev->pClassData = classData; - MSC_BOT_Init(pdev); + MSC_BOT_Init(pdev); - // Prepare Out endpoint to receive next HID packet - USBD_LL_PrepareReceive( - pdev, - HID_EPOUT_ADDR, - classData->hid.rxBuffer, - sizeof(classData->hid.rxBuffer)); + // Prepare Out endpoint to receive next HID packet + USBD_LL_PrepareReceive( + pdev, + HID_EPOUT_ADDR, + classData->hid.rxBuffer, + sizeof(classData->hid.rxBuffer)); - return ret; + return ret; } static uint8_t USBD_Composite_DeInit (USBD_HandleTypeDef *pdev, uint8_t cfgidx) { - USBD_LL_CloseEP(pdev, HID_EPIN_ADDR); - USBD_LL_CloseEP(pdev, HID_EPOUT_ADDR); - USBD_LL_CloseEP(pdev, MSC_EPOUT_ADDR); - USBD_LL_CloseEP(pdev, MSC_EPIN_ADDR); + USBD_LL_CloseEP(pdev, HID_EPIN_ADDR); + USBD_LL_CloseEP(pdev, HID_EPOUT_ADDR); + USBD_LL_CloseEP(pdev, MSC_EPOUT_ADDR); + USBD_LL_CloseEP(pdev, MSC_EPIN_ADDR); - MSC_BOT_DeInit(pdev); + MSC_BOT_DeInit(pdev); - pdev->pClassData = NULL; - return USBD_OK; + pdev->pClassData = NULL; + return USBD_OK; } static uint8_t USBD_Composite_Setup( - USBD_HandleTypeDef *pdev, - USBD_SetupReqTypedef *req) + USBD_HandleTypeDef *pdev, + USBD_SetupReqTypedef *req) { - uint16_t len = 0; - uint8_t *pbuf = NULL; - - USBD_CompositeClassData *classData = (USBD_CompositeClassData*) pdev->pClassData; - USBD_HID_HandleTypeDef *hhid = &(classData->hid); - USBD_MSC_BOT_HandleTypeDef *hmsc = &(classData->msc); - - switch (req->bmRequest & USB_REQ_TYPE_MASK) - { - 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: - USBD_CtlSendData (pdev, (uint8_t *)&hhid->Protocol, 1); - break; - case HID_REQ_SET_IDLE: - hhid->IdleState = (uint8_t)(req->wValue >> 8); - break; - case HID_REQ_GET_IDLE: - USBD_CtlSendData (pdev, (uint8_t *)&hhid->IdleState, 1); - break; - - case BOT_GET_MAX_LUN : - if((req->wValue == 0) && - (req->wLength == 1) && - ((req->bmRequest & 0x80) == 0x80)) - { - hmsc->max_lun = ((USBD_StorageTypeDef *)pdev->pUserData)->GetMaxLun(); - USBD_CtlSendData (pdev, (uint8_t *)&hmsc->max_lun, 1); - } - else - { - USBD_CtlError(pdev , req); - return USBD_FAIL; - } - break; - - case BOT_RESET : - if((req->wValue == 0) && - (req->wLength == 0) && - ((req->bmRequest & 0x80) != 0x80)) - { - MSC_BOT_Reset(pdev); - } - else - { - USBD_CtlError(pdev , req); - return USBD_FAIL; - } - break; - - - default: - USBD_CtlError (pdev, req); - return USBD_FAIL; - } break; - - - case USB_REQ_TYPE_STANDARD: - switch (req->bRequest) - { - case USB_REQ_GET_DESCRIPTOR: - if( req->wValue >> 8 == HID_REPORT_DESC) - { - len = MIN(HID_GENERIC_REPORT_DESC_SIZE , req->wLength); - pbuf = (uint8_t*) USBD_HID_GetReportDesc(); - } - else if( req->wValue >> 8 == HID_DESCRIPTOR_TYPE) - { - pbuf = (uint8_t*) USBD_HID_GetDesc(); - len = MIN(USB_HID_DESC_SIZ , req->wLength); - } - USBD_CtlSendData (pdev, pbuf, len); - break; - - case USB_REQ_GET_INTERFACE : - if (req->wIndex == 0) - { - USBD_CtlSendData (pdev, (uint8_t *)&hhid->AltSetting, 1); - } - else - { - USBD_CtlSendData (pdev, (uint8_t *)&hmsc->interface, 1); - } - break; - case USB_REQ_SET_INTERFACE : - if (req->wIndex == 0) - { - hhid->AltSetting = (uint8_t)(req->wValue); - } - else - { - hmsc->interface = (uint8_t)(req->wValue); - } - break; - - case USB_REQ_CLEAR_FEATURE: - /* Flush the FIFO and Clear the stall status */ - USBD_LL_FlushEP(pdev, (uint8_t)req->wIndex); - - /* Reactivate the EP */ - USBD_LL_CloseEP (pdev , (uint8_t)req->wIndex); - switch ((uint8_t)req->wIndex) - { - case MSC_EPIN_ADDR: - USBD_LL_OpenEP( + uint16_t len = 0; + uint8_t *pbuf = NULL; + + USBD_CompositeClassData *classData = (USBD_CompositeClassData*) pdev->pClassData; + USBD_HID_HandleTypeDef *hhid = &(classData->hid); + USBD_MSC_BOT_HandleTypeDef *hmsc = &(classData->msc); + + switch (req->bmRequest & USB_REQ_TYPE_MASK) + { + 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: + USBD_CtlSendData (pdev, (uint8_t *)&hhid->Protocol, 1); + break; + case HID_REQ_SET_IDLE: + hhid->IdleState = (uint8_t)(req->wValue >> 8); + break; + case HID_REQ_GET_IDLE: + USBD_CtlSendData (pdev, (uint8_t *)&hhid->IdleState, 1); + break; + + case BOT_GET_MAX_LUN : + if((req->wValue == 0) && + (req->wLength == 1) && + ((req->bmRequest & 0x80) == 0x80)) + { + hmsc->max_lun = ((USBD_StorageTypeDef *)pdev->pUserData)->GetMaxLun(); + USBD_CtlSendData (pdev, (uint8_t *)&hmsc->max_lun, 1); + } + else + { + USBD_CtlError(pdev , req); + return USBD_FAIL; + } + break; + + case BOT_RESET : + if((req->wValue == 0) && + (req->wLength == 0) && + ((req->bmRequest & 0x80) != 0x80)) + { + MSC_BOT_Reset(pdev); + } + else + { + USBD_CtlError(pdev , req); + return USBD_FAIL; + } + break; + + + default: + USBD_CtlError (pdev, req); + return USBD_FAIL; + } break; + + + case USB_REQ_TYPE_STANDARD: + switch (req->bRequest) + { + case USB_REQ_GET_DESCRIPTOR: + if( req->wValue >> 8 == HID_REPORT_DESC) + { + len = MIN(HID_GENERIC_REPORT_DESC_SIZE , req->wLength); + pbuf = (uint8_t*) USBD_HID_GetReportDesc(); + } + else if( req->wValue >> 8 == HID_DESCRIPTOR_TYPE) + { + pbuf = (uint8_t*) USBD_HID_GetDesc(); + len = MIN(USB_HID_DESC_SIZ , req->wLength); + } + USBD_CtlSendData (pdev, pbuf, len); + break; + + case USB_REQ_GET_INTERFACE : + if (req->wIndex == 0) + { + USBD_CtlSendData (pdev, (uint8_t *)&hhid->AltSetting, 1); + } + else + { + USBD_CtlSendData (pdev, (uint8_t *)&hmsc->interface, 1); + } + break; + case USB_REQ_SET_INTERFACE : + if (req->wIndex == 0) + { + hhid->AltSetting = (uint8_t)(req->wValue); + } + else + { + hmsc->interface = (uint8_t)(req->wValue); + } + break; + + case USB_REQ_CLEAR_FEATURE: + /* Flush the FIFO and Clear the stall status */ + USBD_LL_FlushEP(pdev, (uint8_t)req->wIndex); + + /* Reactivate the EP */ + USBD_LL_CloseEP (pdev , (uint8_t)req->wIndex); + switch ((uint8_t)req->wIndex) + { + case MSC_EPIN_ADDR: + USBD_LL_OpenEP( pdev, MSC_EPIN_ADDR, USBD_EP_TYPE_BULK, pdev->dev_speed == USBD_SPEED_HIGH ? MSC_MAX_HS_PACKET : MSC_MAX_FS_PACKET); - break; + break; - case MSC_EPOUT_ADDR: - USBD_LL_OpenEP( + case MSC_EPOUT_ADDR: + USBD_LL_OpenEP( pdev, MSC_EPOUT_ADDR, USBD_EP_TYPE_BULK, pdev->dev_speed == USBD_SPEED_HIGH ? MSC_MAX_HS_PACKET : MSC_MAX_FS_PACKET); - break; + break; - case HID_EPIN_ADDR: - USBD_LL_OpenEP(pdev, HID_EPIN_ADDR, USBD_EP_TYPE_INTR, HID_EPIN_SIZE); - break; + case HID_EPIN_ADDR: + USBD_LL_OpenEP(pdev, HID_EPIN_ADDR, USBD_EP_TYPE_INTR, HID_EPIN_SIZE); + break; - case HID_EPOUT_ADDR: - USBD_LL_OpenEP(pdev, HID_EPOUT_ADDR, USBD_EP_TYPE_INTR, HID_EPOUT_SIZE); - break; - } + case HID_EPOUT_ADDR: + USBD_LL_OpenEP(pdev, HID_EPOUT_ADDR, USBD_EP_TYPE_INTR, HID_EPOUT_SIZE); + break; + } - /* Handle BOT error */ - MSC_BOT_CplClrFeature(pdev, (uint8_t)req->wIndex); - break; + /* Handle BOT error */ + MSC_BOT_CplClrFeature(pdev, (uint8_t)req->wIndex); + break; - } break; - } + } break; + } - return USBD_OK; + return USBD_OK; } static uint8_t USBD_Composite_DataIn(USBD_HandleTypeDef *pdev, uint8_t epnum) { - USBD_CompositeClassData *classData = (USBD_CompositeClassData*) pdev->pClassData; - if (epnum == (HID_EPIN_ADDR & 0x7F)) - { - USBD_HID_HandleTypeDef *hhid = &(classData->hid); - /* Ensure that the FIFO is empty before a new transfer, this condition could - be caused by a new transfer before the end of the previous transfer */ - hhid->state = HID_IDLE; - } - else if (epnum == (MSC_EPIN_ADDR & 0x7F)) - { - classData->DataInReady = epnum; - } - return USBD_OK; + USBD_CompositeClassData *classData = (USBD_CompositeClassData*) pdev->pClassData; + if (epnum == (HID_EPIN_ADDR & 0x7F)) + { + USBD_HID_HandleTypeDef *hhid = &(classData->hid); + /* Ensure that the FIFO is empty before a new transfer, this condition could + be caused by a new transfer before the end of the previous transfer */ + hhid->state = HID_IDLE; + } + else if (epnum == (MSC_EPIN_ADDR & 0x7F)) + { + classData->DataInReady = epnum; + } + return USBD_OK; } static uint8_t USBD_Composite_DataOut(USBD_HandleTypeDef *pdev, uint8_t epnum) { - USBD_CompositeClassData *classData = (USBD_CompositeClassData*) pdev->pClassData; - if (epnum == (HID_EPOUT_ADDR & 0x7F)) - { - USBD_HID_HandleTypeDef *hhid = &(classData->hid); - hhid->reportReady = 1; - } - else if (epnum == (MSC_EPOUT_ADDR & 0x7F)) - { - classData->DataOutReady = epnum; - } - return USBD_OK; + USBD_CompositeClassData *classData = (USBD_CompositeClassData*) pdev->pClassData; + if (epnum == (HID_EPOUT_ADDR & 0x7F)) + { + USBD_HID_HandleTypeDef *hhid = &(classData->hid); + hhid->reportReady = 1; + } + else if (epnum == (MSC_EPOUT_ADDR & 0x7F)) + { + classData->DataOutReady = epnum; + } + return USBD_OK; } int s2s_usbDevicePoll(USBD_HandleTypeDef *pdev) { - USBD_CompositeClassData *classData = (USBD_CompositeClassData*) pdev->pClassData; + USBD_CompositeClassData *classData = (USBD_CompositeClassData*) pdev->pClassData; int busy = 0; - if (classData->DataInReady) - { - classData->DataInReady = 0; - MSC_BOT_DataIn(pdev); + if (classData->DataInReady) + { + classData->DataInReady = 0; + MSC_BOT_DataIn(pdev); busy = busy || 1; - } + } - if (classData->DataOutReady) + if (classData->DataOutReady) { - classData->DataOutReady = 0; - MSC_BOT_DataOut(pdev); + classData->DataOutReady = 0; + MSC_BOT_DataOut(pdev); busy = busy || 1; - } + } return busy; } @@ -531,8 +531,8 @@ int s2s_usbDevicePoll(USBD_HandleTypeDef *pdev) { static uint8_t *USBD_Composite_GetDeviceQualifierDesc (uint16_t *length) { - *length = sizeof (USBD_Composite_DeviceQualifierDesc); - return USBD_Composite_DeviceQualifierDesc; + *length = sizeof (USBD_Composite_DeviceQualifierDesc); + return USBD_Composite_DeviceQualifierDesc; } uint8_t *USBD_Composite_GetHSCfgDesc (uint16_t *length) -- 2.38.5