Dataflash_WaitWhileBusy() now always ensures that the dataflash is ready for the next command immediately after returning, no need to call Dataflash_ToggleSelectedChipCS() afterwards.

Added new DATAFLASH_CHIP_MASK() macro to the Dataflash driver, which returns the Dataflash select mask for the given chip index.

Updated MassStorage device block write routines to use ping-pong Dataflash buffering to increase throughput by around 30%.
pull/1469/head
Dean Camera 15 years ago
parent f1076ac4d6
commit 86e6ed7f31

@ -43,7 +43,6 @@
* the pre-selected data OUT endpoint. This routine reads in OS sized blocks from the endpoint and writes * 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. * them to the dataflash in Dataflash page sized blocks.
* *
* \param[in] MSInterfaceInfo Pointer to a Mass Storage class state structure for the Mass Storage interface being used
* \param[in] BlockAddress Data block starting address for the write sequence * \param[in] BlockAddress Data block starting address for the write sequence
* \param[in] TotalBlocks Number of blocks of data to write * \param[in] TotalBlocks Number of blocks of data to write
*/ */
@ -52,11 +51,14 @@ void DataflashManager_WriteBlocks(USB_ClassInfo_MS_Device_t* MSInterfaceInfo, co
uint16_t CurrDFPage = ((BlockAddress * VIRTUAL_MEMORY_BLOCK_SIZE) / DATAFLASH_PAGE_SIZE); uint16_t CurrDFPage = ((BlockAddress * VIRTUAL_MEMORY_BLOCK_SIZE) / DATAFLASH_PAGE_SIZE);
uint16_t CurrDFPageByte = ((BlockAddress * VIRTUAL_MEMORY_BLOCK_SIZE) % DATAFLASH_PAGE_SIZE); uint16_t CurrDFPageByte = ((BlockAddress * VIRTUAL_MEMORY_BLOCK_SIZE) % DATAFLASH_PAGE_SIZE);
uint8_t CurrDFPageByteDiv16 = (CurrDFPageByte >> 4); uint8_t CurrDFPageByteDiv16 = (CurrDFPageByte >> 4);
bool UsingSecondBuffer = false;
/* Copy selected dataflash's current page contents to the dataflash buffer */ /* Copy selected dataflash's current page contents to the dataflash buffer */
Dataflash_SelectChipFromPage(CurrDFPage); Dataflash_SelectChipFromPage(CurrDFPage);
#if (DATAFLASH_PAGE_SIZE > VIRTUAL_MEMORY_BLOCK_SIZE)
Dataflash_SendByte(DF_CMD_MAINMEMTOBUFF1); Dataflash_SendByte(DF_CMD_MAINMEMTOBUFF1);
Dataflash_SendAddressBytes(CurrDFPage, 0); Dataflash_SendAddressBytes(CurrDFPage, 0);
#endif
Dataflash_WaitWhileBusy(); Dataflash_WaitWhileBusy();
/* Send the dataflash buffer write command */ /* Send the dataflash buffer write command */
@ -88,34 +90,36 @@ void DataflashManager_WriteBlocks(USB_ClassInfo_MS_Device_t* MSInterfaceInfo, co
if (CurrDFPageByteDiv16 == (DATAFLASH_PAGE_SIZE >> 4)) if (CurrDFPageByteDiv16 == (DATAFLASH_PAGE_SIZE >> 4))
{ {
/* Write the dataflash buffer contents back to the dataflash page */ /* Write the dataflash buffer contents back to the dataflash page */
Dataflash_ToggleSelectedChipCS(); Dataflash_WaitWhileBusy();
Dataflash_SendByte(DF_CMD_BUFF1TOMAINMEMWITHERASE); Dataflash_SendByte(UsingSecondBuffer ? DF_CMD_BUFF2TOMAINMEMWITHERASE : DF_CMD_BUFF1TOMAINMEMWITHERASE);
Dataflash_SendAddressBytes(CurrDFPage, 0); Dataflash_SendAddressBytes(CurrDFPage, 0);
/* Reset the dataflash buffer counter, increment the page counter */ /* Reset the dataflash buffer counter, increment the page counter */
CurrDFPageByteDiv16 = 0; CurrDFPageByteDiv16 = 0;
CurrDFPage++; 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 */ /* Select the next dataflash chip based on the new dataflash page index */
Dataflash_SelectChipFromPage(CurrDFPage); Dataflash_SelectChipFromPage(CurrDFPage);
Dataflash_WaitWhileBusy();
#if (DATAFLASH_PAGE_SIZE > VIRTUAL_MEMORY_BLOCK_SIZE) #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 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)) if ((TotalBlocks * (VIRTUAL_MEMORY_BLOCK_SIZE >> 4)) < (DATAFLASH_PAGE_SIZE >> 4))
{ {
/* Copy selected dataflash's current page contents to the dataflash buffer */ /* Copy selected dataflash's current page contents to the dataflash buffer */
Dataflash_ToggleSelectedChipCS(); Dataflash_WaitWhileBusy();
Dataflash_SendByte(DF_CMD_MAINMEMTOBUFF1); Dataflash_SendByte(UsingSecondBuffer ? DF_CMD_MAINMEMTOBUFF2 : DF_CMD_MAINMEMTOBUFF1);
Dataflash_SendAddressBytes(CurrDFPage, 0); Dataflash_SendAddressBytes(CurrDFPage, 0);
Dataflash_WaitWhileBusy(); Dataflash_WaitWhileBusy();
} }
#endif #endif
/* Send the dataflash buffer write command */ /* Send the dataflash buffer write command */
Dataflash_ToggleSelectedChipCS(); Dataflash_SendByte(UsingSecondBuffer ? DF_CMD_BUFF2WRITE : DF_CMD_BUFF1WRITE);
Dataflash_SendByte(DF_CMD_BUFF1WRITE); Dataflash_SendAddressBytes(0, 0);
Dataflash_SendAddressBytes(0, 0);
} }
/* Write one 16-byte chunk of data to the dataflash */ /* Write one 16-byte chunk of data to the dataflash */
@ -152,8 +156,8 @@ void DataflashManager_WriteBlocks(USB_ClassInfo_MS_Device_t* MSInterfaceInfo, co
} }
/* Write the dataflash buffer contents back to the dataflash page */ /* Write the dataflash buffer contents back to the dataflash page */
Dataflash_ToggleSelectedChipCS(); Dataflash_WaitWhileBusy();
Dataflash_SendByte(DF_CMD_BUFF1TOMAINMEMWITHERASE); Dataflash_SendByte(UsingSecondBuffer ? DF_CMD_BUFF2TOMAINMEMWITHERASE : DF_CMD_BUFF1TOMAINMEMWITHERASE);
Dataflash_SendAddressBytes(CurrDFPage, 0x00); Dataflash_SendAddressBytes(CurrDFPage, 0x00);
Dataflash_WaitWhileBusy(); Dataflash_WaitWhileBusy();
@ -169,7 +173,6 @@ void DataflashManager_WriteBlocks(USB_ClassInfo_MS_Device_t* MSInterfaceInfo, co
* the pre-selected data IN endpoint. This routine reads in Dataflash page sized blocks from the Dataflash * 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. * and writes them in OS sized blocks to the endpoint.
* *
* \param[in] MSInterfaceInfo Pointer to a Mass Storage class state structure for the Mass Storage interface being used
* \param[in] BlockAddress Data block starting address for the read sequence * \param[in] BlockAddress Data block starting address for the read sequence
* \param[in] TotalBlocks Number of blocks of data to read * \param[in] TotalBlocks Number of blocks of data to read
*/ */
@ -282,11 +285,14 @@ void DataflashManager_WriteBlocks_RAM(const uint32_t BlockAddress, uint16_t Tota
uint16_t CurrDFPage = ((BlockAddress * VIRTUAL_MEMORY_BLOCK_SIZE) / DATAFLASH_PAGE_SIZE); uint16_t CurrDFPage = ((BlockAddress * VIRTUAL_MEMORY_BLOCK_SIZE) / DATAFLASH_PAGE_SIZE);
uint16_t CurrDFPageByte = ((BlockAddress * VIRTUAL_MEMORY_BLOCK_SIZE) % DATAFLASH_PAGE_SIZE); uint16_t CurrDFPageByte = ((BlockAddress * VIRTUAL_MEMORY_BLOCK_SIZE) % DATAFLASH_PAGE_SIZE);
uint8_t CurrDFPageByteDiv16 = (CurrDFPageByte >> 4); uint8_t CurrDFPageByteDiv16 = (CurrDFPageByte >> 4);
bool UsingSecondBuffer = false;
/* Copy selected dataflash's current page contents to the dataflash buffer */ /* Copy selected dataflash's current page contents to the dataflash buffer */
Dataflash_SelectChipFromPage(CurrDFPage); Dataflash_SelectChipFromPage(CurrDFPage);
#if (DATAFLASH_PAGE_SIZE > VIRTUAL_MEMORY_BLOCK_SIZE)
Dataflash_SendByte(DF_CMD_MAINMEMTOBUFF1); Dataflash_SendByte(DF_CMD_MAINMEMTOBUFF1);
Dataflash_SendAddressBytes(CurrDFPage, 0); Dataflash_SendAddressBytes(CurrDFPage, 0);
#endif
Dataflash_WaitWhileBusy(); Dataflash_WaitWhileBusy();
/* Send the dataflash buffer write command */ /* Send the dataflash buffer write command */
@ -305,25 +311,28 @@ void DataflashManager_WriteBlocks_RAM(const uint32_t BlockAddress, uint16_t Tota
if (CurrDFPageByteDiv16 == (DATAFLASH_PAGE_SIZE >> 4)) if (CurrDFPageByteDiv16 == (DATAFLASH_PAGE_SIZE >> 4))
{ {
/* Write the dataflash buffer contents back to the dataflash page */ /* Write the dataflash buffer contents back to the dataflash page */
Dataflash_ToggleSelectedChipCS(); Dataflash_WaitWhileBusy();
Dataflash_SendByte(DF_CMD_BUFF1TOMAINMEMWITHERASE); Dataflash_SendByte(UsingSecondBuffer ? DF_CMD_BUFF2TOMAINMEMWITHERASE : DF_CMD_BUFF1TOMAINMEMWITHERASE);
Dataflash_SendAddressBytes(CurrDFPage, 0); Dataflash_SendAddressBytes(CurrDFPage, 0);
/* Reset the dataflash buffer counter, increment the page counter */ /* Reset the dataflash buffer counter, increment the page counter */
CurrDFPageByteDiv16 = 0; CurrDFPageByteDiv16 = 0;
CurrDFPage++; 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 */ /* Select the next dataflash chip based on the new dataflash page index */
Dataflash_SelectChipFromPage(CurrDFPage); Dataflash_SelectChipFromPage(CurrDFPage);
Dataflash_WaitWhileBusy();
#if (DATAFLASH_PAGE_SIZE > VIRTUAL_MEMORY_BLOCK_SIZE) #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 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)) if ((TotalBlocks * (VIRTUAL_MEMORY_BLOCK_SIZE >> 4)) < (DATAFLASH_PAGE_SIZE >> 4))
{ {
/* Copy selected dataflash's current page contents to the dataflash buffer */ /* Copy selected dataflash's current page contents to the dataflash buffer */
Dataflash_ToggleSelectedChipCS(); Dataflash_WaitWhileBusy();
Dataflash_SendByte(DF_CMD_MAINMEMTOBUFF1); Dataflash_SendByte(UsingSecondBuffer ? DF_CMD_MAINMEMTOBUFF2 : DF_CMD_MAINMEMTOBUFF1);
Dataflash_SendAddressBytes(CurrDFPage, 0); Dataflash_SendAddressBytes(CurrDFPage, 0);
Dataflash_WaitWhileBusy(); Dataflash_WaitWhileBusy();
} }
@ -351,8 +360,8 @@ void DataflashManager_WriteBlocks_RAM(const uint32_t BlockAddress, uint16_t Tota
} }
/* Write the dataflash buffer contents back to the dataflash page */ /* Write the dataflash buffer contents back to the dataflash page */
Dataflash_ToggleSelectedChipCS(); Dataflash_WaitWhileBusy();
Dataflash_SendByte(DF_CMD_BUFF1TOMAINMEMWITHERASE); Dataflash_SendByte(UsingSecondBuffer ? DF_CMD_BUFF2TOMAINMEMWITHERASE : DF_CMD_BUFF1TOMAINMEMWITHERASE);
Dataflash_SendAddressBytes(CurrDFPage, 0x00); Dataflash_SendAddressBytes(CurrDFPage, 0x00);
Dataflash_WaitWhileBusy(); Dataflash_WaitWhileBusy();
@ -367,7 +376,7 @@ void DataflashManager_WriteBlocks_RAM(const uint32_t BlockAddress, uint16_t Tota
* *
* \param[in] BlockAddress Data block starting address for the read sequence * \param[in] BlockAddress Data block starting address for the read sequence
* \param[in] TotalBlocks Number of blocks of data to read * \param[in] TotalBlocks Number of blocks of data to read
* \param[out] BufferPtr Pointer to the data destination RAM buffer * \param[out] BufferPtr Pointer to the data destination RAM buffer
*/ */
void DataflashManager_ReadBlocks_RAM(const uint32_t BlockAddress, uint16_t TotalBlocks, uint8_t* BufferPtr) void DataflashManager_ReadBlocks_RAM(const uint32_t BlockAddress, uint16_t TotalBlocks, uint8_t* BufferPtr)
{ {

@ -51,11 +51,14 @@ void DataflashManager_WriteBlocks(const uint32_t BlockAddress, uint16_t TotalBlo
uint16_t CurrDFPage = ((BlockAddress * VIRTUAL_MEMORY_BLOCK_SIZE) / DATAFLASH_PAGE_SIZE); uint16_t CurrDFPage = ((BlockAddress * VIRTUAL_MEMORY_BLOCK_SIZE) / DATAFLASH_PAGE_SIZE);
uint16_t CurrDFPageByte = ((BlockAddress * VIRTUAL_MEMORY_BLOCK_SIZE) % DATAFLASH_PAGE_SIZE); uint16_t CurrDFPageByte = ((BlockAddress * VIRTUAL_MEMORY_BLOCK_SIZE) % DATAFLASH_PAGE_SIZE);
uint8_t CurrDFPageByteDiv16 = (CurrDFPageByte >> 4); uint8_t CurrDFPageByteDiv16 = (CurrDFPageByte >> 4);
bool UsingSecondBuffer = false;
/* Copy selected dataflash's current page contents to the dataflash buffer */ /* Copy selected dataflash's current page contents to the dataflash buffer */
Dataflash_SelectChipFromPage(CurrDFPage); Dataflash_SelectChipFromPage(CurrDFPage);
#if (DATAFLASH_PAGE_SIZE > VIRTUAL_MEMORY_BLOCK_SIZE)
Dataflash_SendByte(DF_CMD_MAINMEMTOBUFF1); Dataflash_SendByte(DF_CMD_MAINMEMTOBUFF1);
Dataflash_SendAddressBytes(CurrDFPage, 0); Dataflash_SendAddressBytes(CurrDFPage, 0);
#endif
Dataflash_WaitWhileBusy(); Dataflash_WaitWhileBusy();
/* Send the dataflash buffer write command */ /* Send the dataflash buffer write command */
@ -87,34 +90,36 @@ void DataflashManager_WriteBlocks(const uint32_t BlockAddress, uint16_t TotalBlo
if (CurrDFPageByteDiv16 == (DATAFLASH_PAGE_SIZE >> 4)) if (CurrDFPageByteDiv16 == (DATAFLASH_PAGE_SIZE >> 4))
{ {
/* Write the dataflash buffer contents back to the dataflash page */ /* Write the dataflash buffer contents back to the dataflash page */
Dataflash_ToggleSelectedChipCS(); Dataflash_WaitWhileBusy();
Dataflash_SendByte(DF_CMD_BUFF1TOMAINMEMWITHERASE); Dataflash_SendByte(UsingSecondBuffer ? DF_CMD_BUFF2TOMAINMEMWITHERASE : DF_CMD_BUFF1TOMAINMEMWITHERASE);
Dataflash_SendAddressBytes(CurrDFPage, 0); Dataflash_SendAddressBytes(CurrDFPage, 0);
/* Reset the dataflash buffer counter, increment the page counter */ /* Reset the dataflash buffer counter, increment the page counter */
CurrDFPageByteDiv16 = 0; CurrDFPageByteDiv16 = 0;
CurrDFPage++; 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 */ /* Select the next dataflash chip based on the new dataflash page index */
Dataflash_SelectChipFromPage(CurrDFPage); Dataflash_SelectChipFromPage(CurrDFPage);
Dataflash_WaitWhileBusy();
#if (DATAFLASH_PAGE_SIZE > VIRTUAL_MEMORY_BLOCK_SIZE) #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 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)) if ((TotalBlocks * (VIRTUAL_MEMORY_BLOCK_SIZE >> 4)) < (DATAFLASH_PAGE_SIZE >> 4))
{ {
/* Copy selected dataflash's current page contents to the dataflash buffer */ /* Copy selected dataflash's current page contents to the dataflash buffer */
Dataflash_ToggleSelectedChipCS(); Dataflash_WaitWhileBusy();
Dataflash_SendByte(DF_CMD_MAINMEMTOBUFF1); Dataflash_SendByte(UsingSecondBuffer ? DF_CMD_MAINMEMTOBUFF2 : DF_CMD_MAINMEMTOBUFF1);
Dataflash_SendAddressBytes(CurrDFPage, 0); Dataflash_SendAddressBytes(CurrDFPage, 0);
Dataflash_WaitWhileBusy(); Dataflash_WaitWhileBusy();
} }
#endif #endif
/* Send the dataflash buffer write command */ /* Send the dataflash buffer write command */
Dataflash_ToggleSelectedChipCS(); Dataflash_SendByte(UsingSecondBuffer ? DF_CMD_BUFF2WRITE : DF_CMD_BUFF1WRITE);
Dataflash_SendByte(DF_CMD_BUFF1WRITE); Dataflash_SendAddressBytes(0, 0);
Dataflash_SendAddressBytes(0, 0);
} }
/* Write one 16-byte chunk of data to the dataflash */ /* Write one 16-byte chunk of data to the dataflash */
@ -151,8 +156,8 @@ void DataflashManager_WriteBlocks(const uint32_t BlockAddress, uint16_t TotalBlo
} }
/* Write the dataflash buffer contents back to the dataflash page */ /* Write the dataflash buffer contents back to the dataflash page */
Dataflash_ToggleSelectedChipCS(); Dataflash_WaitWhileBusy();
Dataflash_SendByte(DF_CMD_BUFF1TOMAINMEMWITHERASE); Dataflash_SendByte(UsingSecondBuffer ? DF_CMD_BUFF2TOMAINMEMWITHERASE : DF_CMD_BUFF1TOMAINMEMWITHERASE);
Dataflash_SendAddressBytes(CurrDFPage, 0x00); Dataflash_SendAddressBytes(CurrDFPage, 0x00);
Dataflash_WaitWhileBusy(); Dataflash_WaitWhileBusy();
@ -280,11 +285,14 @@ void DataflashManager_WriteBlocks_RAM(const uint32_t BlockAddress, uint16_t Tota
uint16_t CurrDFPage = ((BlockAddress * VIRTUAL_MEMORY_BLOCK_SIZE) / DATAFLASH_PAGE_SIZE); uint16_t CurrDFPage = ((BlockAddress * VIRTUAL_MEMORY_BLOCK_SIZE) / DATAFLASH_PAGE_SIZE);
uint16_t CurrDFPageByte = ((BlockAddress * VIRTUAL_MEMORY_BLOCK_SIZE) % DATAFLASH_PAGE_SIZE); uint16_t CurrDFPageByte = ((BlockAddress * VIRTUAL_MEMORY_BLOCK_SIZE) % DATAFLASH_PAGE_SIZE);
uint8_t CurrDFPageByteDiv16 = (CurrDFPageByte >> 4); uint8_t CurrDFPageByteDiv16 = (CurrDFPageByte >> 4);
bool UsingSecondBuffer = false;
/* Copy selected dataflash's current page contents to the dataflash buffer */ /* Copy selected dataflash's current page contents to the dataflash buffer */
Dataflash_SelectChipFromPage(CurrDFPage); Dataflash_SelectChipFromPage(CurrDFPage);
#if (DATAFLASH_PAGE_SIZE > VIRTUAL_MEMORY_BLOCK_SIZE)
Dataflash_SendByte(DF_CMD_MAINMEMTOBUFF1); Dataflash_SendByte(DF_CMD_MAINMEMTOBUFF1);
Dataflash_SendAddressBytes(CurrDFPage, 0); Dataflash_SendAddressBytes(CurrDFPage, 0);
#endif
Dataflash_WaitWhileBusy(); Dataflash_WaitWhileBusy();
/* Send the dataflash buffer write command */ /* Send the dataflash buffer write command */
@ -303,25 +311,28 @@ void DataflashManager_WriteBlocks_RAM(const uint32_t BlockAddress, uint16_t Tota
if (CurrDFPageByteDiv16 == (DATAFLASH_PAGE_SIZE >> 4)) if (CurrDFPageByteDiv16 == (DATAFLASH_PAGE_SIZE >> 4))
{ {
/* Write the dataflash buffer contents back to the dataflash page */ /* Write the dataflash buffer contents back to the dataflash page */
Dataflash_ToggleSelectedChipCS(); Dataflash_WaitWhileBusy();
Dataflash_SendByte(DF_CMD_BUFF1TOMAINMEMWITHERASE); Dataflash_SendByte(UsingSecondBuffer ? DF_CMD_BUFF2TOMAINMEMWITHERASE : DF_CMD_BUFF1TOMAINMEMWITHERASE);
Dataflash_SendAddressBytes(CurrDFPage, 0); Dataflash_SendAddressBytes(CurrDFPage, 0);
/* Reset the dataflash buffer counter, increment the page counter */ /* Reset the dataflash buffer counter, increment the page counter */
CurrDFPageByteDiv16 = 0; CurrDFPageByteDiv16 = 0;
CurrDFPage++; 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 */ /* Select the next dataflash chip based on the new dataflash page index */
Dataflash_SelectChipFromPage(CurrDFPage); Dataflash_SelectChipFromPage(CurrDFPage);
Dataflash_WaitWhileBusy();
#if (DATAFLASH_PAGE_SIZE > VIRTUAL_MEMORY_BLOCK_SIZE) #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 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)) if ((TotalBlocks * (VIRTUAL_MEMORY_BLOCK_SIZE >> 4)) < (DATAFLASH_PAGE_SIZE >> 4))
{ {
/* Copy selected dataflash's current page contents to the dataflash buffer */ /* Copy selected dataflash's current page contents to the dataflash buffer */
Dataflash_ToggleSelectedChipCS(); Dataflash_WaitWhileBusy();
Dataflash_SendByte(DF_CMD_MAINMEMTOBUFF1); Dataflash_SendByte(UsingSecondBuffer ? DF_CMD_MAINMEMTOBUFF2 : DF_CMD_MAINMEMTOBUFF1);
Dataflash_SendAddressBytes(CurrDFPage, 0); Dataflash_SendAddressBytes(CurrDFPage, 0);
Dataflash_WaitWhileBusy(); Dataflash_WaitWhileBusy();
} }
@ -341,11 +352,7 @@ void DataflashManager_WriteBlocks_RAM(const uint32_t BlockAddress, uint16_t Tota
CurrDFPageByteDiv16++; CurrDFPageByteDiv16++;
/* Increment the block 16 byte block counter */ /* Increment the block 16 byte block counter */
BytesInBlockDiv16++; BytesInBlockDiv16++;
/* Check if the current command is being aborted by the host */
if (IsMassStoreReset)
return;
} }
/* Decrement the blocks remaining counter and reset the sub block counter */ /* Decrement the blocks remaining counter and reset the sub block counter */
@ -353,8 +360,8 @@ void DataflashManager_WriteBlocks_RAM(const uint32_t BlockAddress, uint16_t Tota
} }
/* Write the dataflash buffer contents back to the dataflash page */ /* Write the dataflash buffer contents back to the dataflash page */
Dataflash_ToggleSelectedChipCS(); Dataflash_WaitWhileBusy();
Dataflash_SendByte(DF_CMD_BUFF1TOMAINMEMWITHERASE); Dataflash_SendByte(UsingSecondBuffer ? DF_CMD_BUFF2TOMAINMEMWITHERASE : DF_CMD_BUFF1TOMAINMEMWITHERASE);
Dataflash_SendAddressBytes(CurrDFPage, 0x00); Dataflash_SendAddressBytes(CurrDFPage, 0x00);
Dataflash_WaitWhileBusy(); Dataflash_WaitWhileBusy();
@ -421,10 +428,6 @@ void DataflashManager_ReadBlocks_RAM(const uint32_t BlockAddress, uint16_t Total
/* Increment the block 16 byte block counter */ /* Increment the block 16 byte block counter */
BytesInBlockDiv16++; BytesInBlockDiv16++;
/* Check if the current command is being aborted by the host */
if (IsMassStoreReset)
return;
} }
/* Decrement the blocks remaining counter */ /* Decrement the blocks remaining counter */

@ -75,6 +75,18 @@
#endif #endif
/* Public Interface - May be used in end-application: */ /* Public Interface - May be used in end-application: */
/* Macros: */
#if !defined(__DOXYGEN__)
#define __GET_DATAFLASH_MASK2(x, y) x ## y
#define __GET_DATAFLASH_MASK(x) __GET_DATAFLASH_MASK2(DATAFLASH_CHIP,x)
#endif
/* Retrieves the Dataflash chip select mask for the given Dataflash chip index.
*
* \param index Index of the dataflash chip mask to retrieve
*/
#define DATAFLASH_CHIP_MASK(index) __GET_DATAFLASH_MASK(index)
/* Pseudo-Function Macros: */ /* Pseudo-Function Macros: */
#if defined(__DOXYGEN__) #if defined(__DOXYGEN__)
/** Determines the currently selected dataflash chip. /** Determines the currently selected dataflash chip.
@ -149,7 +161,7 @@
#else #else
#error The selected board does not contain a dataflash IC. #error The selected board does not contain a dataflash IC.
#endif #endif
/* Inline Functions: */ /* Inline Functions: */
/** Initializes the dataflash driver (including the SPI driver) so that commands and data may be /** Initializes the dataflash driver (including the SPI driver) so that commands and data may be
* sent to an attached dataflash IC. * sent to an attached dataflash IC.
@ -183,6 +195,7 @@
Dataflash_ToggleSelectedChipCS(); Dataflash_ToggleSelectedChipCS();
Dataflash_SendByte(DF_CMD_GETSTATUS); Dataflash_SendByte(DF_CMD_GETSTATUS);
while (!(Dataflash_ReceiveByte() & DF_STATUS_READY)); while (!(Dataflash_ReceiveByte() & DF_STATUS_READY));
Dataflash_ToggleSelectedChipCS();
} }
/** Selects a dataflash IC from the given page number, which should range from 0 to /** Selects a dataflash IC from the given page number, which should range from 0 to

@ -38,6 +38,10 @@
* - Fixed MassStorage demo not clearing the reset flag when a Mass Storage Reset is issued while not processing a command * - Fixed MassStorage demo not clearing the reset flag when a Mass Storage Reset is issued while not processing a command
* - Fixed USB_Host_SendControlRequest() not re-suspending the USB bus when initial device ready-wait fails * - Fixed USB_Host_SendControlRequest() not re-suspending the USB bus when initial device ready-wait fails
* - Fixed USB Pad regulator not being disabled on some AVR models when the USB_OPT_REG_DISABLED option is used * - Fixed USB Pad regulator not being disabled on some AVR models when the USB_OPT_REG_DISABLED option is used
* - Dataflash_WaitWhileBusy() now always ensures that the dataflash is ready for the next command immediately after returning,
* no need to call Dataflash_ToggleSelectedChipCS() afterwards
* - Added new DATAFLASH_CHIP_MASK() macro to the Dataflash driver, which returns the Dataflash select mask for the given chip index
* - Updated MassStorage device block write routines to use ping-pong Dataflash buffering to increase throughput by around 30%
* *
* *
* \section Sec_ChangeLog090605 Version 090605 * \section Sec_ChangeLog090605 Version 090605

@ -12,23 +12,25 @@
* or post your suggestion as an enhancement request to the project bug tracker. * or post your suggestion as an enhancement request to the project bug tracker.
* *
* <b>Targeted for This Release:</b> * <b>Targeted for This Release:</b>
* - Make new host class drivers * - Host Mode Class Drivers
* - Document new host class drivers * -# Make new host class drivers
* - Convert Host mode demos to class drivers * -# Document new host class drivers
* - Re-enable Host mode Class driver builds after completion * -# Convert Host mode demos to class drivers
* - Add standardized descriptor names to class driver structures, controlled by USE_NONSTANDARD_DESCRIPTOR_NAMES * -# Re-enable Host mode Class driver builds after completion
* - Update Host mode Class Driver demo .txt files * -# Update Host mode Class Driver demo .txt files
* - Add standardized descriptor names to device and host class driver structures, controlled by USE_NONSTANDARD_DESCRIPTOR_NAMES
* - Debug mode for pipe/endpoint calls * - Debug mode for pipe/endpoint calls
* - Test and document new FAST_STREAM_TRANSFERS compile time option * - Test and document new FAST_STREAM_TRANSFERS compile time option
* *
* <b>Targeted for Future Releases:</b> * <b>Targeted for Future Releases:</b>
* - Remake AVRStudio project files * - Remake AVRStudio project files
* - Detailed overviews of how each demo works * - Add detailed overviews of how each demo works
* - Master LUFA include file * - Master LUFA include file rather than per-module includes
* - Stream reads - return number of bytes not read? * - Stream reads - return number of bytes not read?
* - Add multiple-report HID demo to the library * - Add multiple-report HID demo to the library
* - Add dual role Mouse Host/Keyboard Device demo to the library * - Add dual role Mouse Host/Keyboard Device demo to the library
* - Add hub support to match Atmel's stack * - Add hub support to match Atmel's stack
* - Port LUFA to the AVR32 UC3B series microcontrollers * - Port LUFA to other architectures
* - Port LUFA to the Atmel ARM7 series microcontrollers * -# AVR32 UC3B series microcontrollers
* -# Atmel ARM7 series microcontrollers
*/ */

@ -259,7 +259,7 @@
Scheduler_TotalTasks = TotalTasks; Scheduler_TotalTasks = TotalTasks;
} }
static inline void Scheduler_GoSchedule(const uint8_t TotalTasks) ATTR_NO_RETURN ATTR_ALWAYS_INLINE; static inline void Scheduler_GoSchedule(const uint8_t TotalTasks) ATTR_NO_RETURN ATTR_ALWAYS_INLINE ATTR_DEPRECATED;
static inline void Scheduler_GoSchedule(const uint8_t TotalTasks) static inline void Scheduler_GoSchedule(const uint8_t TotalTasks)
{ {
Scheduler_InitScheduler(TotalTasks); Scheduler_InitScheduler(TotalTasks);

Loading…
Cancel
Save