Fix NVM commands so that memory reads and CRC generations now work correctly using...
[pub/USBasp.git] / Projects / AVRISP / Lib / NVMTarget.c
index 104d0a8..fee432c 100644 (file)
@@ -42,10 +42,18 @@ void NVMTarget_SendNVMRegAddress(uint8_t Register)
 {\r
        uint32_t Address = XPROG_Param_NVMBase | Register;\r
 \r
-       PDITarget_SendByte(Address >> 24);\r
-       PDITarget_SendByte(Address >> 26);\r
-       PDITarget_SendByte(Address >> 8);\r
        PDITarget_SendByte(Address &  0xFF);\r
+       PDITarget_SendByte(Address >> 8);\r
+       PDITarget_SendByte(Address >> 16);\r
+       PDITarget_SendByte(Address >> 24);\r
+}\r
+\r
+void NVMTarget_SendAddress(uint32_t AbsoluteAddress)\r
+{\r
+       PDITarget_SendByte(AbsoluteAddress &  0xFF);\r
+       PDITarget_SendByte(AbsoluteAddress >> 8);\r
+       PDITarget_SendByte(AbsoluteAddress >> 16);\r
+       PDITarget_SendByte(AbsoluteAddress >> 24);\r
 }\r
 \r
 bool NVMTarget_WaitWhileNVMBusBusy(void)\r
@@ -68,7 +76,7 @@ void NVMTarget_WaitWhileNVMControllerBusy(void)
        /* Poll the NVM STATUS register while the NVM controller is busy */\r
        for (;;)\r
        {\r
-               PDITarget_SendByte(PDI_CMD_LDS | (PDI_DATSIZE_1BYTE << 2));\r
+               PDITarget_SendByte(PDI_CMD_LDS | (PDI_DATSIZE_4BYTES << 2));\r
                NVMTarget_SendNVMRegAddress(NVM_REG_STATUS);\r
                \r
                if (!(PDITarget_ReceiveByte() & (1 << 7)))\r
@@ -80,13 +88,15 @@ uint32_t NVMTarget_GetMemoryCRC(uint8_t MemoryCommand)
 {\r
        uint32_t MemoryCRC;\r
 \r
+       NVMTarget_WaitWhileNVMControllerBusy();\r
+\r
        /* Set the NVM command to the correct CRC read command */\r
-       PDITarget_SendByte(PDI_CMD_STS | (PDI_DATSIZE_1BYTE << 2));\r
+       PDITarget_SendByte(PDI_CMD_STS | (PDI_DATSIZE_4BYTES << 2));\r
        NVMTarget_SendNVMRegAddress(NVM_REG_CMD);\r
        PDITarget_SendByte(MemoryCommand);\r
 \r
        /* Set CMDEX bit in NVM CTRLA register to start the CRC generation */\r
-       PDITarget_SendByte(PDI_CMD_STS | (PDI_DATSIZE_1BYTE << 2));\r
+       PDITarget_SendByte(PDI_CMD_STS | (PDI_DATSIZE_4BYTES << 2));\r
        NVMTarget_SendNVMRegAddress(NVM_REG_CTRLA);\r
        PDITarget_SendByte(1 << 0);\r
 \r
@@ -94,14 +104,37 @@ uint32_t NVMTarget_GetMemoryCRC(uint8_t MemoryCommand)
        NVMTarget_WaitWhileNVMBusBusy();\r
        NVMTarget_WaitWhileNVMControllerBusy();\r
        \r
-       /* Read the three byte generated CRC value */\r
-       PDITarget_SendByte(PDI_CMD_LDS | (PDI_DATSIZE_3BYTES << 2));\r
+       /* Read the three bytes generated CRC value */\r
+       PDITarget_SendByte(PDI_CMD_LDS | (PDI_DATSIZE_4BYTES << 2));\r
        NVMTarget_SendNVMRegAddress(NVM_REG_DAT0);\r
        MemoryCRC  = PDITarget_ReceiveByte();\r
+\r
+       PDITarget_SendByte(PDI_CMD_LDS | (PDI_DATSIZE_4BYTES << 2));\r
+       NVMTarget_SendNVMRegAddress(NVM_REG_DAT1);\r
        MemoryCRC |= ((uint16_t)PDITarget_ReceiveByte() << 8);\r
+\r
+       PDITarget_SendByte(PDI_CMD_LDS | (PDI_DATSIZE_4BYTES << 2));\r
+       NVMTarget_SendNVMRegAddress(NVM_REG_DAT2);\r
        MemoryCRC |= ((uint32_t)PDITarget_ReceiveByte() << 16);\r
        \r
        return MemoryCRC;\r
 }\r
 \r
+void NVMTarget_ReadMemory(uint32_t ReadAddress, uint8_t* ReadBuffer, uint16_t ReadSize)\r
+{\r
+       NVMTarget_WaitWhileNVMControllerBusy();\r
+\r
+       PDITarget_SendByte(PDI_CMD_STS | (PDI_DATSIZE_4BYTES << 2));\r
+       NVMTarget_SendNVMRegAddress(NVM_REG_CMD);\r
+       PDITarget_SendByte(NVM_CMD_READNVM);\r
+\r
+       /* TODO: Optimize via REPEAT and buffer orientated commands */\r
+       for (uint16_t i = 0; i < ReadSize; i++)\r
+       {\r
+               PDITarget_SendByte(PDI_CMD_LDS | (PDI_DATSIZE_4BYTES << 2));\r
+               NVMTarget_SendAddress(ReadAddress++);\r
+               *(ReadBuffer++) = PDITarget_ReceiveByte();\r
+       }\r
+}\r
+\r
 #endif\r