Added DataflashManager_WriteBlocks_RAM() and DataflashManager_ReadBlocks_RAM() functi...
authorDean Camera <dean@fourwalledcubicle.com>
Tue, 17 Mar 2009 10:45:32 +0000 (10:45 +0000)
committerDean Camera <dean@fourwalledcubicle.com>
Tue, 17 Mar 2009 10:45:32 +0000 (10:45 +0000)
Demos/MassStorage/DataflashManager.c
Demos/MassStorage/DataflashManager.h
LUFA/ChangeLog.txt

index b2dbdda..7b02ed6 100644 (file)
@@ -266,6 +266,175 @@ void DataflashManager_ReadBlocks(const uint32_t BlockAddress, uint16_t TotalBloc
        Dataflash_DeselectChip();\r
 }\r
 \r
+/** Writes blocks (OS blocks, not Dataflash pages) to the storage medium, the board dataflash IC(s), from\r
+ *  the a given RAM buffer. This routine reads in OS sized blocks from the buffer and writes them to the\r
+ *  dataflash in Dataflash page sized blocks. This can be linked to FAT libraries to write files to the\r
+ *  dataflash.\r
+ *\r
+ *  \param BlockAddress  Data block starting address for the write sequence\r
+ *  \param TotalBlocks   Number of blocks of data to write\r
+ *  \param BufferPtr     Pointer to the data source RAM buffer\r
+ */\r
+void DataflashManager_WriteBlocks_RAM(const uint32_t BlockAddress, uint16_t TotalBlocks, uint8_t* BufferPtr)\r
+{\r
+       uint16_t CurrDFPage          = ((BlockAddress * VIRTUAL_MEMORY_BLOCK_SIZE) / DATAFLASH_PAGE_SIZE);\r
+       uint16_t CurrDFPageByte      = ((BlockAddress * VIRTUAL_MEMORY_BLOCK_SIZE) % DATAFLASH_PAGE_SIZE);\r
+       uint8_t  CurrDFPageByteDiv16 = (CurrDFPageByte >> 4);\r
+\r
+       /* Copy selected dataflash's current page contents to the dataflash buffer */\r
+       Dataflash_SelectChipFromPage(CurrDFPage);\r
+       Dataflash_SendByte(DF_CMD_MAINMEMTOBUFF1);\r
+       Dataflash_SendAddressBytes(CurrDFPage, 0);\r
+       Dataflash_WaitWhileBusy();\r
+\r
+       /* Send the dataflash buffer write command */\r
+       Dataflash_ToggleSelectedChipCS();\r
+       Dataflash_SendByte(DF_CMD_BUFF1WRITE);\r
+       Dataflash_SendAddressBytes(0, CurrDFPageByte);\r
+\r
+       while (TotalBlocks)\r
+       {\r
+               uint8_t BytesInBlockDiv16 = 0;\r
+               \r
+               /* Write an endpoint packet sized data block to the dataflash */\r
+               while (BytesInBlockDiv16 < (VIRTUAL_MEMORY_BLOCK_SIZE >> 4))\r
+               {\r
+                       /* Check if end of dataflash page reached */\r
+                       if (CurrDFPageByteDiv16 == (DATAFLASH_PAGE_SIZE >> 4))\r
+                       {\r
+                               /* Write the dataflash buffer contents back to the dataflash page */\r
+                               Dataflash_ToggleSelectedChipCS();\r
+                               Dataflash_SendByte(DF_CMD_BUFF1TOMAINMEMWITHERASE);\r
+                               Dataflash_SendAddressBytes(CurrDFPage, 0);\r
+\r
+                               /* Reset the dataflash buffer counter, increment the page counter */\r
+                               CurrDFPageByteDiv16 = 0;\r
+                               CurrDFPage++;\r
+\r
+                               /* Select the next dataflash chip based on the new dataflash page index */\r
+                               Dataflash_SelectChipFromPage(CurrDFPage);\r
+                               Dataflash_WaitWhileBusy();\r
+\r
+#if (DATAFLASH_PAGE_SIZE > VIRTUAL_MEMORY_BLOCK_SIZE)\r
+                               /* If less than one dataflash page remaining, copy over the existing page to preserve trailing data */\r
+                               if ((TotalBlocks * (VIRTUAL_MEMORY_BLOCK_SIZE >> 4)) < (DATAFLASH_PAGE_SIZE >> 4))\r
+                               {\r
+                                       /* Copy selected dataflash's current page contents to the dataflash buffer */\r
+                                       Dataflash_ToggleSelectedChipCS();\r
+                                       Dataflash_SendByte(DF_CMD_MAINMEMTOBUFF1);\r
+                                       Dataflash_SendAddressBytes(CurrDFPage, 0);\r
+                                       Dataflash_WaitWhileBusy();\r
+                               }\r
+#endif\r
+\r
+                               /* Send the dataflash buffer write command */\r
+                               Dataflash_ToggleSelectedChipCS();\r
+                               Dataflash_SendByte(DF_CMD_BUFF1WRITE);\r
+                               Dataflash_SendAddressBytes(0, 0);\r
+                       }\r
+                       \r
+                       /* Write one 16-byte chunk of data to the dataflash */\r
+                       for (uint8_t ByteNum = 0; ByteNum < 16; ByteNum++)\r
+                         Dataflash_SendByte(*(BufferPtr++));\r
+                       \r
+                       /* Increment the dataflash page 16 byte block counter */\r
+                       CurrDFPageByteDiv16++;\r
+\r
+                       /* Increment the block 16 byte block counter */\r
+                       BytesInBlockDiv16++;\r
+\r
+                       /* Check if the current command is being aborted by the host */\r
+                       if (IsMassStoreReset)\r
+                         return;                       \r
+               }\r
+                       \r
+               /* Decrement the blocks remaining counter and reset the sub block counter */\r
+               TotalBlocks--;\r
+       }\r
+\r
+       /* Write the dataflash buffer contents back to the dataflash page */\r
+       Dataflash_ToggleSelectedChipCS();\r
+       Dataflash_SendByte(DF_CMD_BUFF1TOMAINMEMWITHERASE);\r
+       Dataflash_SendAddressBytes(CurrDFPage, 0x00);\r
+       Dataflash_WaitWhileBusy();\r
+\r
+       /* Deselect all dataflash chips */\r
+       Dataflash_DeselectChip();\r
+}\r
+\r
+/** Reads blocks (OS blocks, not Dataflash pages) from the storage medium, the board dataflash IC(s), into\r
+ *  the a preallocated RAM buffer. This routine reads in Dataflash page sized blocks from the Dataflash\r
+ *  and writes them in OS sized blocks to the given buffer. This can be linked to FAT libraries to read\r
+ *  the files stored on the dataflash.\r
+ *\r
+ *  \param BlockAddress  Data block starting address for the read sequence\r
+ *  \param TotalBlocks   Number of blocks of data to read\r
+ *  \param BufferPtr     Pointer to the data destination RAM buffer\r
+ */\r
+void DataflashManager_ReadBlocks_RAM(const uint32_t BlockAddress, uint16_t TotalBlocks, uint8_t* BufferPtr)\r
+{\r
+       uint16_t CurrDFPage          = ((BlockAddress * VIRTUAL_MEMORY_BLOCK_SIZE) / DATAFLASH_PAGE_SIZE);\r
+       uint16_t CurrDFPageByte      = ((BlockAddress * VIRTUAL_MEMORY_BLOCK_SIZE) % DATAFLASH_PAGE_SIZE);\r
+       uint8_t  CurrDFPageByteDiv16 = (CurrDFPageByte >> 4);\r
+\r
+       /* Send the dataflash main memory page read command */\r
+       Dataflash_SelectChipFromPage(CurrDFPage);\r
+       Dataflash_SendByte(DF_CMD_MAINMEMPAGEREAD);\r
+       Dataflash_SendAddressBytes(CurrDFPage, CurrDFPageByte);\r
+       Dataflash_SendByte(0x00);\r
+       Dataflash_SendByte(0x00);\r
+       Dataflash_SendByte(0x00);\r
+       Dataflash_SendByte(0x00);\r
+\r
+       while (TotalBlocks)\r
+       {\r
+               uint8_t BytesInBlockDiv16 = 0;\r
+               \r
+               /* Write an endpoint packet sized data block to the dataflash */\r
+               while (BytesInBlockDiv16 < (VIRTUAL_MEMORY_BLOCK_SIZE >> 4))\r
+               {\r
+                       /* Check if end of dataflash page reached */\r
+                       if (CurrDFPageByteDiv16 == (DATAFLASH_PAGE_SIZE >> 4))\r
+                       {\r
+                               /* Reset the dataflash buffer counter, increment the page counter */\r
+                               CurrDFPageByteDiv16 = 0;\r
+                               CurrDFPage++;\r
+\r
+                               /* Select the next dataflash chip based on the new dataflash page index */\r
+                               Dataflash_SelectChipFromPage(CurrDFPage);\r
+                               \r
+                               /* Send the dataflash main memory page read command */\r
+                               Dataflash_SendByte(DF_CMD_MAINMEMPAGEREAD);\r
+                               Dataflash_SendAddressBytes(CurrDFPage, 0);\r
+                               Dataflash_SendByte(0x00);\r
+                               Dataflash_SendByte(0x00);\r
+                               Dataflash_SendByte(0x00);\r
+                               Dataflash_SendByte(0x00);\r
+                       }       \r
+\r
+                       /* Read one 16-byte chunk of data from the dataflash */\r
+                       for (uint8_t ByteNum = 0; ByteNum < 16; ByteNum++)\r
+                         *(BufferPtr++) = Dataflash_ReceiveByte();\r
+                       \r
+                       /* Increment the dataflash page 16 byte block counter */\r
+                       CurrDFPageByteDiv16++;\r
+                       \r
+                       /* Increment the block 16 byte block counter */\r
+                       BytesInBlockDiv16++;\r
+\r
+                       /* Check if the current command is being aborted by the host */\r
+                       if (IsMassStoreReset)\r
+                         return;\r
+               }\r
+               \r
+               /* Decrement the blocks remaining counter */\r
+               TotalBlocks--;\r
+       }\r
+\r
+       /* Deselect all dataflash chips */\r
+       Dataflash_DeselectChip();\r
+}\r
+\r
 /** Disables the dataflash memory write protection bits on the board Dataflash ICs, if enabled. */\r
 void DataflashManager_ResetDataflashProtections(void)\r
 {\r
index a0c43c3..1332fd3 100644 (file)
        /* Function Prototypes: */\r
                void DataflashManager_WriteBlocks(const uint32_t BlockAddress, uint16_t TotalBlocks);\r
                void DataflashManager_ReadBlocks(const uint32_t BlockAddress, uint16_t TotalBlocks);\r
+               void DataflashManager_WriteBlocks_RAM(const uint32_t BlockAddress, uint16_t TotalBlocks,\r
+                                                     uint8_t* BufferPtr) ATTR_NON_NULL_PTR_ARG(3);\r
+               void DataflashManager_ReadBlocks_RAM(const uint32_t BlockAddress, uint16_t TotalBlocks,\r
+                                                    uint8_t* BufferPtr) ATTR_NON_NULL_PTR_ARG(3);\r
                void DataflashManager_ResetDataflashProtections(void);\r
                \r
 #endif\r
index 27cbca8..325cef1 100644 (file)
@@ -35,6 +35,8 @@
   *  - Makefile updated to include output giving the currently selected BOARD parameter value\r
   *  - Board Dataflash driver now allows for dataflash ICs which use different shifts for setting the current page/byte address (thanks\r
   *    to Kenneth Clubb)\r
+  *  - Added DataflashManager_WriteBlocks_RAM() and DataflashManager_ReadBlocks_RAM() functions to the MassStorage demo, to allow for easy\r
+  *    interfacing with a FAT library for dataflash file level access\r
   *\r
   *  \section Sec_ChangeLog090209 Version 090209\r
   *\r