Cleanups to the MassStorage Device demos, and the MassStorage Device Class driver.
[pub/USBasp.git] / Demos / Device / ClassDriver / MassStorage / Lib / DataflashManager.c
index 2335a5e..6646278 100644 (file)
@@ -43,6 +43,7 @@
  *  the pre-selected data OUT endpoint. This routine reads in OS sized blocks from the endpoint and writes\r
  *  them to the dataflash in Dataflash page sized blocks.\r
  *\r
  *  the pre-selected data OUT endpoint. This routine reads in OS sized blocks from the endpoint and writes\r
  *  them to the dataflash in Dataflash page sized blocks.\r
  *\r
+ *  \param[in] MSInterfaceInfo  Pointer to a structure containing a Mass Storage Class configuration and state\r
  *  \param[in] BlockAddress  Data block starting address for the write sequence\r
  *  \param[in] TotalBlocks   Number of blocks of data to write\r
  */\r
  *  \param[in] BlockAddress  Data block starting address for the write sequence\r
  *  \param[in] TotalBlocks   Number of blocks of data to write\r
  */\r
@@ -53,21 +54,23 @@ void DataflashManager_WriteBlocks(USB_ClassInfo_MS_Device_t* MSInterfaceInfo, co
        uint8_t  CurrDFPageByteDiv16 = (CurrDFPageByte >> 4);\r
        bool     UsingSecondBuffer   = false;\r
 \r
        uint8_t  CurrDFPageByteDiv16 = (CurrDFPageByte >> 4);\r
        bool     UsingSecondBuffer   = false;\r
 \r
-       /* Copy selected dataflash's current page contents to the dataflash buffer */\r
+       /* Select the correct starting Dataflash IC for the block requested */\r
        Dataflash_SelectChipFromPage(CurrDFPage);\r
        Dataflash_SelectChipFromPage(CurrDFPage);\r
+\r
 #if (DATAFLASH_PAGE_SIZE > VIRTUAL_MEMORY_BLOCK_SIZE)\r
 #if (DATAFLASH_PAGE_SIZE > VIRTUAL_MEMORY_BLOCK_SIZE)\r
+       /* Copy selected dataflash's current page contents to the dataflash buffer */\r
        Dataflash_SendByte(DF_CMD_MAINMEMTOBUFF1);\r
        Dataflash_SendAddressBytes(CurrDFPage, 0);\r
        Dataflash_SendByte(DF_CMD_MAINMEMTOBUFF1);\r
        Dataflash_SendAddressBytes(CurrDFPage, 0);\r
-#endif\r
        Dataflash_WaitWhileBusy();\r
        Dataflash_WaitWhileBusy();\r
+#endif\r
 \r
        /* Send the dataflash buffer write command */\r
 \r
        /* Send the dataflash buffer write command */\r
-       Dataflash_ToggleSelectedChipCS();\r
        Dataflash_SendByte(DF_CMD_BUFF1WRITE);\r
        Dataflash_SendAddressBytes(0, CurrDFPageByte);\r
 \r
        /* Wait until endpoint is ready before continuing */\r
        Dataflash_SendByte(DF_CMD_BUFF1WRITE);\r
        Dataflash_SendAddressBytes(0, CurrDFPageByte);\r
 \r
        /* Wait until endpoint is ready before continuing */\r
-       while (!(Endpoint_IsReadWriteAllowed()));\r
+       if (Endpoint_WaitUntilReady())\r
+         return;\r
 \r
        while (TotalBlocks)\r
        {\r
 \r
        while (TotalBlocks)\r
        {\r
@@ -83,7 +86,8 @@ void DataflashManager_WriteBlocks(USB_ClassInfo_MS_Device_t* MSInterfaceInfo, co
                                Endpoint_ClearOUT();\r
                                \r
                                /* Wait until the host has sent another packet */\r
                                Endpoint_ClearOUT();\r
                                \r
                                /* Wait until the host has sent another packet */\r
-                               while (!(Endpoint_IsReadWriteAllowed()));\r
+                               if (Endpoint_WaitUntilReady())\r
+                                 return;\r
                        }\r
 \r
                        /* Check if end of dataflash page reached */\r
                        }\r
 \r
                        /* Check if end of dataflash page reached */\r
@@ -173,6 +177,7 @@ 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\r
  *  and writes them in OS sized blocks to the endpoint.\r
  *\r
  *  the pre-selected data IN endpoint. This routine reads in Dataflash page sized blocks from the Dataflash\r
  *  and writes them in OS sized blocks to the endpoint.\r
  *\r
+ *  \param[in] MSInterfaceInfo  Pointer to a structure containing a Mass Storage Class configuration and state\r
  *  \param[in] BlockAddress  Data block starting address for the read sequence\r
  *  \param[in] TotalBlocks   Number of blocks of data to read\r
  */\r
  *  \param[in] BlockAddress  Data block starting address for the read sequence\r
  *  \param[in] TotalBlocks   Number of blocks of data to read\r
  */\r
@@ -182,8 +187,10 @@ void DataflashManager_ReadBlocks(USB_ClassInfo_MS_Device_t* MSInterfaceInfo, con
        uint16_t CurrDFPageByte      = ((BlockAddress * VIRTUAL_MEMORY_BLOCK_SIZE) % DATAFLASH_PAGE_SIZE);\r
        uint8_t  CurrDFPageByteDiv16 = (CurrDFPageByte >> 4);\r
 \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
+       /* Select the correct starting Dataflash IC for the block requested */\r
        Dataflash_SelectChipFromPage(CurrDFPage);\r
        Dataflash_SelectChipFromPage(CurrDFPage);\r
+\r
+       /* Send the dataflash main memory page read command */\r
        Dataflash_SendByte(DF_CMD_MAINMEMPAGEREAD);\r
        Dataflash_SendAddressBytes(CurrDFPage, CurrDFPageByte);\r
        Dataflash_SendByte(0x00);\r
        Dataflash_SendByte(DF_CMD_MAINMEMPAGEREAD);\r
        Dataflash_SendAddressBytes(CurrDFPage, CurrDFPageByte);\r
        Dataflash_SendByte(0x00);\r
@@ -192,7 +199,8 @@ void DataflashManager_ReadBlocks(USB_ClassInfo_MS_Device_t* MSInterfaceInfo, con
        Dataflash_SendByte(0x00);\r
        \r
        /* Wait until endpoint is ready before continuing */\r
        Dataflash_SendByte(0x00);\r
        \r
        /* Wait until endpoint is ready before continuing */\r
-       while (!(Endpoint_IsReadWriteAllowed()));\r
+       if (Endpoint_WaitUntilReady())\r
+         return;\r
        \r
        while (TotalBlocks)\r
        {\r
        \r
        while (TotalBlocks)\r
        {\r
@@ -208,7 +216,8 @@ void DataflashManager_ReadBlocks(USB_ClassInfo_MS_Device_t* MSInterfaceInfo, con
                                Endpoint_ClearIN();\r
                                \r
                                /* Wait until the endpoint is ready for more data */\r
                                Endpoint_ClearIN();\r
                                \r
                                /* Wait until the endpoint is ready for more data */\r
-                               while (!(Endpoint_IsReadWriteAllowed()));\r
+                               if (Endpoint_WaitUntilReady())\r
+                                 return;\r
                        }\r
                        \r
                        /* Check if end of dataflash page reached */\r
                        }\r
                        \r
                        /* Check if end of dataflash page reached */\r
@@ -287,19 +296,20 @@ void DataflashManager_WriteBlocks_RAM(const uint32_t BlockAddress, uint16_t Tota
        uint8_t  CurrDFPageByteDiv16 = (CurrDFPageByte >> 4);\r
        bool     UsingSecondBuffer   = false;\r
 \r
        uint8_t  CurrDFPageByteDiv16 = (CurrDFPageByte >> 4);\r
        bool     UsingSecondBuffer   = false;\r
 \r
-       /* Copy selected dataflash's current page contents to the dataflash buffer */\r
+       /* Select the correct starting Dataflash IC for the block requested */\r
        Dataflash_SelectChipFromPage(CurrDFPage);\r
        Dataflash_SelectChipFromPage(CurrDFPage);\r
+\r
 #if (DATAFLASH_PAGE_SIZE > VIRTUAL_MEMORY_BLOCK_SIZE)\r
 #if (DATAFLASH_PAGE_SIZE > VIRTUAL_MEMORY_BLOCK_SIZE)\r
+       /* Copy selected dataflash's current page contents to the dataflash buffer */\r
        Dataflash_SendByte(DF_CMD_MAINMEMTOBUFF1);\r
        Dataflash_SendAddressBytes(CurrDFPage, 0);\r
        Dataflash_SendByte(DF_CMD_MAINMEMTOBUFF1);\r
        Dataflash_SendAddressBytes(CurrDFPage, 0);\r
-#endif\r
        Dataflash_WaitWhileBusy();\r
        Dataflash_WaitWhileBusy();\r
+#endif\r
 \r
        /* Send the dataflash buffer write command */\r
 \r
        /* Send the dataflash buffer write command */\r
-       Dataflash_ToggleSelectedChipCS();\r
        Dataflash_SendByte(DF_CMD_BUFF1WRITE);\r
        Dataflash_SendAddressBytes(0, CurrDFPageByte);\r
        Dataflash_SendByte(DF_CMD_BUFF1WRITE);\r
        Dataflash_SendAddressBytes(0, CurrDFPageByte);\r
-\r
+       \r
        while (TotalBlocks)\r
        {\r
                uint8_t BytesInBlockDiv16 = 0;\r
        while (TotalBlocks)\r
        {\r
                uint8_t BytesInBlockDiv16 = 0;\r
@@ -384,8 +394,10 @@ void DataflashManager_ReadBlocks_RAM(const uint32_t BlockAddress, uint16_t Total
        uint16_t CurrDFPageByte      = ((BlockAddress * VIRTUAL_MEMORY_BLOCK_SIZE) % DATAFLASH_PAGE_SIZE);\r
        uint8_t  CurrDFPageByteDiv16 = (CurrDFPageByte >> 4);\r
 \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
+       /* Select the correct starting Dataflash IC for the block requested */\r
        Dataflash_SelectChipFromPage(CurrDFPage);\r
        Dataflash_SelectChipFromPage(CurrDFPage);\r
+\r
+       /* Send the dataflash main memory page read command */\r
        Dataflash_SendByte(DF_CMD_MAINMEMPAGEREAD);\r
        Dataflash_SendAddressBytes(CurrDFPage, CurrDFPageByte);\r
        Dataflash_SendByte(0x00);\r
        Dataflash_SendByte(DF_CMD_MAINMEMPAGEREAD);\r
        Dataflash_SendAddressBytes(CurrDFPage, CurrDFPageByte);\r
        Dataflash_SendByte(0x00);\r
@@ -478,3 +490,36 @@ void DataflashManager_ResetDataflashProtections(void)
        /* Deselect current dataflash chip */\r
        Dataflash_DeselectChip();\r
 }\r
        /* Deselect current dataflash chip */\r
        Dataflash_DeselectChip();\r
 }\r
+\r
+/** Performs a simple test on the attached Dataflash IC(s) to ensure that they are working.\r
+ *\r
+ *  \return Boolean true if all media chips are working, false otherwise\r
+ */\r
+bool DataflashManager_CheckDataflashOperation(void)\r
+{\r
+       uint8_t ReturnByte;\r
+\r
+       /* Test first Dataflash IC is present and responding to commands */\r
+       Dataflash_SelectChip(DATAFLASH_CHIP1);\r
+       Dataflash_SendByte(DF_CMD_READMANUFACTURERDEVICEINFO);\r
+       ReturnByte = Dataflash_ReceiveByte();\r
+       Dataflash_DeselectChip();\r
+\r
+       /* If returned data is invalid, fail the command */\r
+       if (ReturnByte != DF_MANUFACTURER_ATMEL)\r
+         return false;\r
+\r
+       #if (DATAFLASH_TOTALCHIPS == 2)\r
+       /* Test second Dataflash IC is present and responding to commands */\r
+       Dataflash_SelectChip(DATAFLASH_CHIP2);\r
+       Dataflash_SendByte(DF_CMD_READMANUFACTURERDEVICEINFO);\r
+       ReturnByte = Dataflash_ReceiveByte();\r
+       Dataflash_DeselectChip();\r
+\r
+       /* If returned data is invalid, fail the command */\r
+       if (ReturnByte != DF_MANUFACTURER_ATMEL)\r
+         return false;\r
+       #endif\r
+       \r
+       return true;\r
+}\r