Browse Source

Improve SD hotswap detection

Michael McMaster 3 years ago
parent
commit
ed43f0dff0

+ 1 - 1
lib/SCSI2SD/src/firmware/disk.c

@@ -301,7 +301,7 @@ static void doSeek(uint32_t lba)
         }
         else
         {
-            s2s_delay_ms(1);
+            s2s_delay_us(10);
         }
     }
 }

+ 2 - 3
lib/SCSI2SD/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();

+ 217 - 205
lib/SCSI2SD/src/firmware/sd.c

@@ -1,19 +1,19 @@
-//	Copyright (C) 2013 Michael McMaster <michael@codesrc.com>
+//    Copyright (C) 2013 Michael McMaster <michael@codesrc.com>
 //
-//	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 <http://www.gnu.org/licenses/>.
+//    You should have received a copy of the GNU General Public License
+//    along with SCSI2SD.  If not, see <http://www.gnu.org/licenses/>.
 
 #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);
+    }
 }

+ 215 - 215
lib/SCSI2SD/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)