Fix NVM commands so that memory reads and CRC generations now work correctly using...
authorDean Camera <dean@fourwalledcubicle.com>
Mon, 14 Dec 2009 04:39:16 +0000 (04:39 +0000)
committerDean Camera <dean@fourwalledcubicle.com>
Mon, 14 Dec 2009 04:39:16 +0000 (04:39 +0000)
Projects/AVRISP/Lib/NVMTarget.c
Projects/AVRISP/Lib/NVMTarget.h
Projects/AVRISP/Lib/PDIProtocol.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
index 5afb4c0..0f2dad5 100644 (file)
                #endif\r
 \r
        /* Defines: */\r
-               #define FLASH_BASE           0x00800000\r
-               #define EPPROM_BASE          0x008C0000\r
-               #define FUSE_BASE            0x008F0020\r
-               #define DATAMEM_BASE         0x01000000\r
-               #define PROD_SIGNATURE_BASE  0x008E0200\r
-               #define USER_SIGNATURE_BASE  0x008E0400\r
+               #define FLASH_BASE                     0x00800000\r
+               #define EPPROM_BASE                    0x008C0000\r
+               #define FUSE_BASE                      0x008F0020\r
+               #define DATAMEM_BASE                   0x01000000\r
+               #define PROD_SIGNATURE_BASE            0x008E0200\r
+               #define USER_SIGNATURE_BASE            0x008E0400\r
                \r
-               #define NVM_REG_ADDR0        0x00\r
-               #define NVM_REG_ADDR1        0x01\r
-               #define NVM_REG_ADDR2        0x02\r
-               #define NVM_REG_DAT0         0x04\r
-               #define NVM_REG_DAT1         0x05\r
-               #define NVM_REG_DAT2         0x06\r
-               #define NVM_REG_CMD          0x0A\r
-               #define NVM_REG_CTRLA        0x0B\r
-               #define NVM_REG_CTRLB        0x0C\r
-               #define NVM_REG_INTCTRL      0x0D\r
-               #define NVM_REG_STATUS       0x0F\r
-               #define NVM_REG_LOCKBITS     0x10\r
+               #define NVM_REG_ADDR0                  0x00\r
+               #define NVM_REG_ADDR1                  0x01\r
+               #define NVM_REG_ADDR2                  0x02\r
+               #define NVM_REG_DAT0                   0x04\r
+               #define NVM_REG_DAT1                   0x05\r
+               #define NVM_REG_DAT2                   0x06\r
+               #define NVM_REG_CMD                    0x0A\r
+               #define NVM_REG_CTRLA                  0x0B\r
+               #define NVM_REG_CTRLB                  0x0C\r
+               #define NVM_REG_INTCTRL                0x0D\r
+               #define NVM_REG_STATUS                 0x0F\r
+               #define NVM_REG_LOCKBITS               0x10\r
                \r
-               #define NVM_CMD_APPCRC       0x38\r
-               #define NVM_CMD_BOOTCRC      0x39\r
-               #define NVM_CMD_FLASHCRC     0x78\r
-               #define NVM_CMD_READUSERSIG  0x03\r
-                               \r
+               #define NVM_CMD_NOOP                   0x00\r
+               #define NVM_CMD_CHIPERASE              0x40\r
+               #define NVM_CMD_READNVM                0x43\r
+               #define NVM_CMD_LOADFLASHBUFF          0x23\r
+               #define NVM_CMD_ERASEFLASHBUFF         0x26\r
+               #define NVM_CMD_ERASEFLASHPAGE         0x2B\r
+               #define NVM_CMD_FLASHPAGEWRITE         0x2E\r
+               #define NVM_CMD_ERASEWRITEFLASH        0x2F\r
+               #define NVM_CMD_FLASHCRC               0x78\r
+               #define NVM_CMD_ERASEAPPSEC            0x20\r
+               #define NVM_CMD_ERASEAPPSECPAGE        0x22\r
+               #define NVM_CMD_WRITEAPPSECPAGE        0x24\r
+               #define NVM_CMD_ERASEWRITEAPPSECPAGE   0x25\r
+               #define NVM_CMD_APPCRC                 0x38\r
+               #define NVM_CMD_ERASEBOOTSEC           0x68\r
+               #define NVM_CMD_ERASEBOOTSECPAGE       0x2A\r
+               #define NVM_CMD_WRITEBOOTSECPAGE       0x2C\r
+               #define NVM_CMD_ERASEWRITEBOOTSECPAGE  0x2D\r
+               #define NVM_CMD_BOOTCRC                0x39\r
+               #define NVM_CMD_READUSERSIG            0x03\r
+               #define NVM_CMD_ERASEUSERSIG           0x18\r
+               #define NVM_CMD_WRITEUSERSIG           0x1A\r
+               #define NVM_CMD_READCALIBRATION        0x02\r
+               #define NVM_CMD_READFUSE               0x07\r
+               #define NVM_CMD_WRITEFUSE              0x4C\r
+               #define NVM_CMD_WRITELOCK              0x08\r
+               #define NVM_CMD_LOADEEPROMPAGEBUFF     0x33\r
+               #define NVM_CMD_ERASEEEPROMPAGEBUFF    0x36\r
+               #define NVM_CMD_ERASEEEPROM            0x30\r
+               #define NVM_CMD_ERASEEEPROMPAGE        0x32\r
+               #define NVM_CMD_WRITEEEPROMPAGE        0x34\r
+               #define NVM_CMD_ERASEWRITEEEPROMPAGE   0x35\r
+               #define NVM_CMD_READEEPROM             0x06\r
+\r
        /* Function Prototypes: */\r
-               void NVMTarget_SendNVMRegAddress(uint8_t Register);\r
+               void     NVMTarget_SendNVMRegAddress(uint8_t Register);\r
+               void     NVMTarget_SendAddress(uint32_t AbsoluteAddress);\r
                bool     NVMTarget_WaitWhileNVMBusBusy(void);\r
                void     NVMTarget_WaitWhileNVMControllerBusy(void);\r
                uint32_t NVMTarget_GetMemoryCRC(uint8_t MemoryCommand);\r
+               void     NVMTarget_ReadMemory(uint32_t ReadAddress, uint8_t* ReadBuffer, uint16_t ReadSize);\r
 \r
 #endif\r
index a7b1155..e3255a0 100644 (file)
@@ -216,20 +216,17 @@ static void PDIProtocol_ReadMemory(void)
 \r
        Endpoint_ClearOUT();\r
        Endpoint_SetEndpointDirection(ENDPOINT_DIR_IN);\r
-       \r
-       if (ReadMemory_XPROG_Params.MemoryType == XPRG_MEM_TYPE_USERSIG)\r
-       {\r
-               PDITarget_SendByte(PDI_CMD_STS | (PDI_DATSIZE_1BYTE << 2));\r
-               NVMTarget_SendNVMRegAddress(NVM_REG_CMD);\r
-               PDITarget_SendByte(NVM_CMD_READUSERSIG);\r
 \r
-               // TODO\r
-       }\r
-       \r
+       uint8_t ReadBuffer[ReadMemory_XPROG_Params.Length];\r
+       NVMTarget_ReadMemory(ReadMemory_XPROG_Params.Address, ReadBuffer, ReadMemory_XPROG_Params.Length);\r
+\r
        Endpoint_Write_Byte(CMD_XPROG);\r
        Endpoint_Write_Byte(XPRG_CMD_READ_MEM);\r
        Endpoint_Write_Byte(ReturnStatus);\r
        \r
+       if (ReturnStatus == XPRG_ERR_OK)\r
+         Endpoint_Write_Stream_LE(ReadBuffer, ReadMemory_XPROG_Params.Length);\r
+       \r
        Endpoint_ClearIN();\r
 }\r
 \r
@@ -250,13 +247,16 @@ static void PDIProtocol_ReadCRC(void)
        Endpoint_SetEndpointDirection(ENDPOINT_DIR_IN);\r
        \r
        uint32_t MemoryCRC;\r
+       uint8_t  CRCCommand;\r
 \r
        if (ReadCRC_XPROG_Params.CRCType == XPRG_CRC_APP)\r
-         MemoryCRC = NVMTarget_GetMemoryCRC(NVM_CMD_APPCRC);\r
+         CRCCommand = NVM_CMD_APPCRC;\r
        else if (ReadCRC_XPROG_Params.CRCType == XPRG_CRC_BOOT)\r
-         MemoryCRC = NVMTarget_GetMemoryCRC(NVM_CMD_BOOTCRC);\r
+         CRCCommand = NVM_CMD_BOOTCRC;\r
        else\r
-         MemoryCRC = NVMTarget_GetMemoryCRC(NVM_CMD_FLASHCRC);\r
+         CRCCommand = NVM_CMD_FLASHCRC;\r
+       \r
+       MemoryCRC = NVMTarget_GetMemoryCRC(CRCCommand);\r
        \r
        Endpoint_Write_Byte(CMD_XPROG);\r
        Endpoint_Write_Byte(XPRG_CMD_CRC);\r