X-Git-Url: http://git.linex4red.de/pub/USBasp.git/blobdiff_plain/b9b03aadb219d06fbad9d110e508db93e45461af..2a0c28e6e47c8a173f32fc99cd8666a2633c5c12:/Demos/Device/LowLevel/MassStorage/Lib/DataflashManager.c?ds=inline diff --git a/Demos/Device/LowLevel/MassStorage/Lib/DataflashManager.c b/Demos/Device/LowLevel/MassStorage/Lib/DataflashManager.c index 4b624190f..2bd03c98d 100644 --- a/Demos/Device/LowLevel/MassStorage/Lib/DataflashManager.c +++ b/Demos/Device/LowLevel/MassStorage/Lib/DataflashManager.c @@ -43,29 +43,37 @@ * the pre-selected data OUT endpoint. This routine reads in OS sized blocks from the endpoint and writes * them to the dataflash in Dataflash page sized blocks. * - * \param BlockAddress Data block starting address for the write sequence - * \param TotalBlocks Number of blocks of data to write + * \param[in] BlockAddress Data block starting address for the write sequence + * \param[in] TotalBlocks Number of blocks of data to write */ void DataflashManager_WriteBlocks(const uint32_t BlockAddress, uint16_t TotalBlocks) { uint16_t CurrDFPage = ((BlockAddress * VIRTUAL_MEMORY_BLOCK_SIZE) / DATAFLASH_PAGE_SIZE); uint16_t CurrDFPageByte = ((BlockAddress * VIRTUAL_MEMORY_BLOCK_SIZE) % DATAFLASH_PAGE_SIZE); uint8_t CurrDFPageByteDiv16 = (CurrDFPageByte >> 4); + bool UsingSecondBuffer = false; - /* Copy selected dataflash's current page contents to the dataflash buffer */ + /* Select the correct starting Dataflash IC for the block requested */ Dataflash_SelectChipFromPage(CurrDFPage); + +#if (DATAFLASH_PAGE_SIZE > VIRTUAL_MEMORY_BLOCK_SIZE) + /* Copy selected dataflash's current page contents to the dataflash buffer */ Dataflash_SendByte(DF_CMD_MAINMEMTOBUFF1); Dataflash_SendAddressBytes(CurrDFPage, 0); Dataflash_WaitWhileBusy(); +#endif /* Send the dataflash buffer write command */ - Dataflash_ToggleSelectedChipCS(); Dataflash_SendByte(DF_CMD_BUFF1WRITE); Dataflash_SendAddressBytes(0, CurrDFPageByte); /* Wait until endpoint is ready before continuing */ - while (!(Endpoint_IsReadWriteAllowed())); - + while (!(Endpoint_IsReadWriteAllowed())) + { + if (USB_DeviceState == DEVICE_STATE_Unattached) + return; + } + while (TotalBlocks) { uint8_t BytesInBlockDiv16 = 0; @@ -80,41 +88,47 @@ void DataflashManager_WriteBlocks(const uint32_t BlockAddress, uint16_t TotalBlo Endpoint_ClearOUT(); /* Wait until the host has sent another packet */ - while (!(Endpoint_IsReadWriteAllowed())); + while (!(Endpoint_IsReadWriteAllowed())) + { + if (USB_DeviceState == DEVICE_STATE_Unattached) + return; + } } /* Check if end of dataflash page reached */ if (CurrDFPageByteDiv16 == (DATAFLASH_PAGE_SIZE >> 4)) { /* Write the dataflash buffer contents back to the dataflash page */ - Dataflash_ToggleSelectedChipCS(); - Dataflash_SendByte(DF_CMD_BUFF1TOMAINMEMWITHERASE); + Dataflash_WaitWhileBusy(); + Dataflash_SendByte(UsingSecondBuffer ? DF_CMD_BUFF2TOMAINMEMWITHERASE : DF_CMD_BUFF1TOMAINMEMWITHERASE); Dataflash_SendAddressBytes(CurrDFPage, 0); /* Reset the dataflash buffer counter, increment the page counter */ CurrDFPageByteDiv16 = 0; CurrDFPage++; + /* Once all the dataflash ICs have had their first buffers filled, switch buffers to maintain throughput */ + if (Dataflash_GetSelectedChip() == DATAFLASH_CHIP_MASK(DATAFLASH_TOTALCHIPS)) + UsingSecondBuffer = !(UsingSecondBuffer); + /* Select the next dataflash chip based on the new dataflash page index */ Dataflash_SelectChipFromPage(CurrDFPage); - Dataflash_WaitWhileBusy(); #if (DATAFLASH_PAGE_SIZE > VIRTUAL_MEMORY_BLOCK_SIZE) /* If less than one dataflash page remaining, copy over the existing page to preserve trailing data */ if ((TotalBlocks * (VIRTUAL_MEMORY_BLOCK_SIZE >> 4)) < (DATAFLASH_PAGE_SIZE >> 4)) { /* Copy selected dataflash's current page contents to the dataflash buffer */ - Dataflash_ToggleSelectedChipCS(); - Dataflash_SendByte(DF_CMD_MAINMEMTOBUFF1); + Dataflash_WaitWhileBusy(); + Dataflash_SendByte(UsingSecondBuffer ? DF_CMD_MAINMEMTOBUFF2 : DF_CMD_MAINMEMTOBUFF1); Dataflash_SendAddressBytes(CurrDFPage, 0); Dataflash_WaitWhileBusy(); } #endif /* Send the dataflash buffer write command */ - Dataflash_ToggleSelectedChipCS(); - Dataflash_SendByte(DF_CMD_BUFF1WRITE); - Dataflash_SendAddressBytes(0, 0); + Dataflash_SendByte(UsingSecondBuffer ? DF_CMD_BUFF2WRITE : DF_CMD_BUFF1WRITE); + Dataflash_SendAddressBytes(0, 0); } /* Write one 16-byte chunk of data to the dataflash */ @@ -151,8 +165,8 @@ void DataflashManager_WriteBlocks(const uint32_t BlockAddress, uint16_t TotalBlo } /* Write the dataflash buffer contents back to the dataflash page */ - Dataflash_ToggleSelectedChipCS(); - Dataflash_SendByte(DF_CMD_BUFF1TOMAINMEMWITHERASE); + Dataflash_WaitWhileBusy(); + Dataflash_SendByte(UsingSecondBuffer ? DF_CMD_BUFF2TOMAINMEMWITHERASE : DF_CMD_BUFF1TOMAINMEMWITHERASE); Dataflash_SendAddressBytes(CurrDFPage, 0x00); Dataflash_WaitWhileBusy(); @@ -168,8 +182,8 @@ void DataflashManager_WriteBlocks(const uint32_t BlockAddress, uint16_t TotalBlo * the pre-selected data IN endpoint. This routine reads in Dataflash page sized blocks from the Dataflash * and writes them in OS sized blocks to the endpoint. * - * \param BlockAddress Data block starting address for the read sequence - * \param TotalBlocks Number of blocks of data to read + * \param[in] BlockAddress Data block starting address for the read sequence + * \param[in] TotalBlocks Number of blocks of data to read */ void DataflashManager_ReadBlocks(const uint32_t BlockAddress, uint16_t TotalBlocks) { @@ -177,8 +191,10 @@ void DataflashManager_ReadBlocks(const uint32_t BlockAddress, uint16_t TotalBloc uint16_t CurrDFPageByte = ((BlockAddress * VIRTUAL_MEMORY_BLOCK_SIZE) % DATAFLASH_PAGE_SIZE); uint8_t CurrDFPageByteDiv16 = (CurrDFPageByte >> 4); - /* Send the dataflash main memory page read command */ + /* Select the correct starting Dataflash IC for the block requested */ Dataflash_SelectChipFromPage(CurrDFPage); + + /* Send the dataflash main memory page read command */ Dataflash_SendByte(DF_CMD_MAINMEMPAGEREAD); Dataflash_SendAddressBytes(CurrDFPage, CurrDFPageByte); Dataflash_SendByte(0x00); @@ -187,7 +203,11 @@ void DataflashManager_ReadBlocks(const uint32_t BlockAddress, uint16_t TotalBloc Dataflash_SendByte(0x00); /* Wait until endpoint is ready before continuing */ - while (!(Endpoint_IsReadWriteAllowed())); + while (!(Endpoint_IsReadWriteAllowed())) + { + if (USB_DeviceState == DEVICE_STATE_Unattached) + return; + } while (TotalBlocks) { @@ -203,7 +223,11 @@ void DataflashManager_ReadBlocks(const uint32_t BlockAddress, uint16_t TotalBloc Endpoint_ClearIN(); /* Wait until the endpoint is ready for more data */ - while (!(Endpoint_IsReadWriteAllowed())); + while (!(Endpoint_IsReadWriteAllowed())) + { + if (USB_DeviceState == DEVICE_STATE_Unattached) + return; + } } /* Check if end of dataflash page reached */ @@ -271,24 +295,28 @@ void DataflashManager_ReadBlocks(const uint32_t BlockAddress, uint16_t TotalBloc * dataflash in Dataflash page sized blocks. This can be linked to FAT libraries to write files to the * dataflash. * - * \param BlockAddress Data block starting address for the write sequence - * \param TotalBlocks Number of blocks of data to write - * \param BufferPtr Pointer to the data source RAM buffer + * \param[in] BlockAddress Data block starting address for the write sequence + * \param[in] TotalBlocks Number of blocks of data to write + * \param[in] BufferPtr Pointer to the data source RAM buffer */ void DataflashManager_WriteBlocks_RAM(const uint32_t BlockAddress, uint16_t TotalBlocks, uint8_t* BufferPtr) { uint16_t CurrDFPage = ((BlockAddress * VIRTUAL_MEMORY_BLOCK_SIZE) / DATAFLASH_PAGE_SIZE); uint16_t CurrDFPageByte = ((BlockAddress * VIRTUAL_MEMORY_BLOCK_SIZE) % DATAFLASH_PAGE_SIZE); uint8_t CurrDFPageByteDiv16 = (CurrDFPageByte >> 4); + bool UsingSecondBuffer = false; - /* Copy selected dataflash's current page contents to the dataflash buffer */ + /* Select the correct starting Dataflash IC for the block requested */ Dataflash_SelectChipFromPage(CurrDFPage); + +#if (DATAFLASH_PAGE_SIZE > VIRTUAL_MEMORY_BLOCK_SIZE) + /* Copy selected dataflash's current page contents to the dataflash buffer */ Dataflash_SendByte(DF_CMD_MAINMEMTOBUFF1); Dataflash_SendAddressBytes(CurrDFPage, 0); Dataflash_WaitWhileBusy(); +#endif /* Send the dataflash buffer write command */ - Dataflash_ToggleSelectedChipCS(); Dataflash_SendByte(DF_CMD_BUFF1WRITE); Dataflash_SendAddressBytes(0, CurrDFPageByte); @@ -303,25 +331,28 @@ void DataflashManager_WriteBlocks_RAM(const uint32_t BlockAddress, uint16_t Tota if (CurrDFPageByteDiv16 == (DATAFLASH_PAGE_SIZE >> 4)) { /* Write the dataflash buffer contents back to the dataflash page */ - Dataflash_ToggleSelectedChipCS(); - Dataflash_SendByte(DF_CMD_BUFF1TOMAINMEMWITHERASE); + Dataflash_WaitWhileBusy(); + Dataflash_SendByte(UsingSecondBuffer ? DF_CMD_BUFF2TOMAINMEMWITHERASE : DF_CMD_BUFF1TOMAINMEMWITHERASE); Dataflash_SendAddressBytes(CurrDFPage, 0); /* Reset the dataflash buffer counter, increment the page counter */ CurrDFPageByteDiv16 = 0; CurrDFPage++; + /* Once all the dataflash ICs have had their first buffers filled, switch buffers to maintain throughput */ + if (Dataflash_GetSelectedChip() == DATAFLASH_CHIP_MASK(DATAFLASH_TOTALCHIPS)) + UsingSecondBuffer = !(UsingSecondBuffer); + /* Select the next dataflash chip based on the new dataflash page index */ Dataflash_SelectChipFromPage(CurrDFPage); - Dataflash_WaitWhileBusy(); #if (DATAFLASH_PAGE_SIZE > VIRTUAL_MEMORY_BLOCK_SIZE) /* If less than one dataflash page remaining, copy over the existing page to preserve trailing data */ if ((TotalBlocks * (VIRTUAL_MEMORY_BLOCK_SIZE >> 4)) < (DATAFLASH_PAGE_SIZE >> 4)) { /* Copy selected dataflash's current page contents to the dataflash buffer */ - Dataflash_ToggleSelectedChipCS(); - Dataflash_SendByte(DF_CMD_MAINMEMTOBUFF1); + Dataflash_WaitWhileBusy(); + Dataflash_SendByte(UsingSecondBuffer ? DF_CMD_MAINMEMTOBUFF2 : DF_CMD_MAINMEMTOBUFF1); Dataflash_SendAddressBytes(CurrDFPage, 0); Dataflash_WaitWhileBusy(); } @@ -341,11 +372,7 @@ void DataflashManager_WriteBlocks_RAM(const uint32_t BlockAddress, uint16_t Tota CurrDFPageByteDiv16++; /* Increment the block 16 byte block counter */ - BytesInBlockDiv16++; - - /* Check if the current command is being aborted by the host */ - if (IsMassStoreReset) - return; + BytesInBlockDiv16++; } /* Decrement the blocks remaining counter and reset the sub block counter */ @@ -353,8 +380,8 @@ void DataflashManager_WriteBlocks_RAM(const uint32_t BlockAddress, uint16_t Tota } /* Write the dataflash buffer contents back to the dataflash page */ - Dataflash_ToggleSelectedChipCS(); - Dataflash_SendByte(DF_CMD_BUFF1TOMAINMEMWITHERASE); + Dataflash_WaitWhileBusy(); + Dataflash_SendByte(UsingSecondBuffer ? DF_CMD_BUFF2TOMAINMEMWITHERASE : DF_CMD_BUFF1TOMAINMEMWITHERASE); Dataflash_SendAddressBytes(CurrDFPage, 0x00); Dataflash_WaitWhileBusy(); @@ -367,9 +394,9 @@ void DataflashManager_WriteBlocks_RAM(const uint32_t BlockAddress, uint16_t Tota * and writes them in OS sized blocks to the given buffer. This can be linked to FAT libraries to read * the files stored on the dataflash. * - * \param BlockAddress Data block starting address for the read sequence - * \param TotalBlocks Number of blocks of data to read - * \param BufferPtr Pointer to the data destination RAM buffer + * \param[in] BlockAddress Data block starting address for the read sequence + * \param[in] TotalBlocks Number of blocks of data to read + * \param[out] BufferPtr Pointer to the data destination RAM buffer */ void DataflashManager_ReadBlocks_RAM(const uint32_t BlockAddress, uint16_t TotalBlocks, uint8_t* BufferPtr) { @@ -377,8 +404,10 @@ void DataflashManager_ReadBlocks_RAM(const uint32_t BlockAddress, uint16_t Total uint16_t CurrDFPageByte = ((BlockAddress * VIRTUAL_MEMORY_BLOCK_SIZE) % DATAFLASH_PAGE_SIZE); uint8_t CurrDFPageByteDiv16 = (CurrDFPageByte >> 4); - /* Send the dataflash main memory page read command */ + /* Select the correct starting Dataflash IC for the block requested */ Dataflash_SelectChipFromPage(CurrDFPage); + + /* Send the dataflash main memory page read command */ Dataflash_SendByte(DF_CMD_MAINMEMPAGEREAD); Dataflash_SendAddressBytes(CurrDFPage, CurrDFPageByte); Dataflash_SendByte(0x00); @@ -421,10 +450,6 @@ void DataflashManager_ReadBlocks_RAM(const uint32_t BlockAddress, uint16_t Total /* Increment the block 16 byte block counter */ BytesInBlockDiv16++; - - /* Check if the current command is being aborted by the host */ - if (IsMassStoreReset) - return; } /* Decrement the blocks remaining counter */