From 8a55d80e7e1214b8625b413fa0123a8b6ce9c825 Mon Sep 17 00:00:00 2001 From: Dean Camera Date: Mon, 14 Dec 2009 04:39:16 +0000 Subject: [PATCH] Fix NVM commands so that memory reads and CRC generations now work correctly using unoptimized PDI commands. --- Projects/AVRISP/Lib/NVMTarget.c | 49 +++++++++++++++---- Projects/AVRISP/Lib/NVMTarget.h | 79 +++++++++++++++++++++---------- Projects/AVRISP/Lib/PDIProtocol.c | 24 +++++----- 3 files changed, 108 insertions(+), 44 deletions(-) diff --git a/Projects/AVRISP/Lib/NVMTarget.c b/Projects/AVRISP/Lib/NVMTarget.c index 104d0a8b09..fee432cfb2 100644 --- a/Projects/AVRISP/Lib/NVMTarget.c +++ b/Projects/AVRISP/Lib/NVMTarget.c @@ -42,10 +42,18 @@ void NVMTarget_SendNVMRegAddress(uint8_t Register) { uint32_t Address = XPROG_Param_NVMBase | Register; - PDITarget_SendByte(Address >> 24); - PDITarget_SendByte(Address >> 26); - PDITarget_SendByte(Address >> 8); PDITarget_SendByte(Address & 0xFF); + PDITarget_SendByte(Address >> 8); + PDITarget_SendByte(Address >> 16); + PDITarget_SendByte(Address >> 24); +} + +void NVMTarget_SendAddress(uint32_t AbsoluteAddress) +{ + PDITarget_SendByte(AbsoluteAddress & 0xFF); + PDITarget_SendByte(AbsoluteAddress >> 8); + PDITarget_SendByte(AbsoluteAddress >> 16); + PDITarget_SendByte(AbsoluteAddress >> 24); } bool NVMTarget_WaitWhileNVMBusBusy(void) @@ -68,7 +76,7 @@ void NVMTarget_WaitWhileNVMControllerBusy(void) /* Poll the NVM STATUS register while the NVM controller is busy */ for (;;) { - PDITarget_SendByte(PDI_CMD_LDS | (PDI_DATSIZE_1BYTE << 2)); + PDITarget_SendByte(PDI_CMD_LDS | (PDI_DATSIZE_4BYTES << 2)); NVMTarget_SendNVMRegAddress(NVM_REG_STATUS); if (!(PDITarget_ReceiveByte() & (1 << 7))) @@ -80,13 +88,15 @@ uint32_t NVMTarget_GetMemoryCRC(uint8_t MemoryCommand) { uint32_t MemoryCRC; + NVMTarget_WaitWhileNVMControllerBusy(); + /* Set the NVM command to the correct CRC read command */ - PDITarget_SendByte(PDI_CMD_STS | (PDI_DATSIZE_1BYTE << 2)); + PDITarget_SendByte(PDI_CMD_STS | (PDI_DATSIZE_4BYTES << 2)); NVMTarget_SendNVMRegAddress(NVM_REG_CMD); PDITarget_SendByte(MemoryCommand); /* Set CMDEX bit in NVM CTRLA register to start the CRC generation */ - PDITarget_SendByte(PDI_CMD_STS | (PDI_DATSIZE_1BYTE << 2)); + PDITarget_SendByte(PDI_CMD_STS | (PDI_DATSIZE_4BYTES << 2)); NVMTarget_SendNVMRegAddress(NVM_REG_CTRLA); PDITarget_SendByte(1 << 0); @@ -94,14 +104,37 @@ uint32_t NVMTarget_GetMemoryCRC(uint8_t MemoryCommand) NVMTarget_WaitWhileNVMBusBusy(); NVMTarget_WaitWhileNVMControllerBusy(); - /* Read the three byte generated CRC value */ - PDITarget_SendByte(PDI_CMD_LDS | (PDI_DATSIZE_3BYTES << 2)); + /* Read the three bytes generated CRC value */ + PDITarget_SendByte(PDI_CMD_LDS | (PDI_DATSIZE_4BYTES << 2)); NVMTarget_SendNVMRegAddress(NVM_REG_DAT0); MemoryCRC = PDITarget_ReceiveByte(); + + PDITarget_SendByte(PDI_CMD_LDS | (PDI_DATSIZE_4BYTES << 2)); + NVMTarget_SendNVMRegAddress(NVM_REG_DAT1); MemoryCRC |= ((uint16_t)PDITarget_ReceiveByte() << 8); + + PDITarget_SendByte(PDI_CMD_LDS | (PDI_DATSIZE_4BYTES << 2)); + NVMTarget_SendNVMRegAddress(NVM_REG_DAT2); MemoryCRC |= ((uint32_t)PDITarget_ReceiveByte() << 16); return MemoryCRC; } +void NVMTarget_ReadMemory(uint32_t ReadAddress, uint8_t* ReadBuffer, uint16_t ReadSize) +{ + NVMTarget_WaitWhileNVMControllerBusy(); + + PDITarget_SendByte(PDI_CMD_STS | (PDI_DATSIZE_4BYTES << 2)); + NVMTarget_SendNVMRegAddress(NVM_REG_CMD); + PDITarget_SendByte(NVM_CMD_READNVM); + + /* TODO: Optimize via REPEAT and buffer orientated commands */ + for (uint16_t i = 0; i < ReadSize; i++) + { + PDITarget_SendByte(PDI_CMD_LDS | (PDI_DATSIZE_4BYTES << 2)); + NVMTarget_SendAddress(ReadAddress++); + *(ReadBuffer++) = PDITarget_ReceiveByte(); + } +} + #endif diff --git a/Projects/AVRISP/Lib/NVMTarget.h b/Projects/AVRISP/Lib/NVMTarget.h index 5afb4c013c..0f2dad5044 100644 --- a/Projects/AVRISP/Lib/NVMTarget.h +++ b/Projects/AVRISP/Lib/NVMTarget.h @@ -56,35 +56,66 @@ #endif /* Defines: */ - #define FLASH_BASE 0x00800000 - #define EPPROM_BASE 0x008C0000 - #define FUSE_BASE 0x008F0020 - #define DATAMEM_BASE 0x01000000 - #define PROD_SIGNATURE_BASE 0x008E0200 - #define USER_SIGNATURE_BASE 0x008E0400 + #define FLASH_BASE 0x00800000 + #define EPPROM_BASE 0x008C0000 + #define FUSE_BASE 0x008F0020 + #define DATAMEM_BASE 0x01000000 + #define PROD_SIGNATURE_BASE 0x008E0200 + #define USER_SIGNATURE_BASE 0x008E0400 - #define NVM_REG_ADDR0 0x00 - #define NVM_REG_ADDR1 0x01 - #define NVM_REG_ADDR2 0x02 - #define NVM_REG_DAT0 0x04 - #define NVM_REG_DAT1 0x05 - #define NVM_REG_DAT2 0x06 - #define NVM_REG_CMD 0x0A - #define NVM_REG_CTRLA 0x0B - #define NVM_REG_CTRLB 0x0C - #define NVM_REG_INTCTRL 0x0D - #define NVM_REG_STATUS 0x0F - #define NVM_REG_LOCKBITS 0x10 + #define NVM_REG_ADDR0 0x00 + #define NVM_REG_ADDR1 0x01 + #define NVM_REG_ADDR2 0x02 + #define NVM_REG_DAT0 0x04 + #define NVM_REG_DAT1 0x05 + #define NVM_REG_DAT2 0x06 + #define NVM_REG_CMD 0x0A + #define NVM_REG_CTRLA 0x0B + #define NVM_REG_CTRLB 0x0C + #define NVM_REG_INTCTRL 0x0D + #define NVM_REG_STATUS 0x0F + #define NVM_REG_LOCKBITS 0x10 - #define NVM_CMD_APPCRC 0x38 - #define NVM_CMD_BOOTCRC 0x39 - #define NVM_CMD_FLASHCRC 0x78 - #define NVM_CMD_READUSERSIG 0x03 - + #define NVM_CMD_NOOP 0x00 + #define NVM_CMD_CHIPERASE 0x40 + #define NVM_CMD_READNVM 0x43 + #define NVM_CMD_LOADFLASHBUFF 0x23 + #define NVM_CMD_ERASEFLASHBUFF 0x26 + #define NVM_CMD_ERASEFLASHPAGE 0x2B + #define NVM_CMD_FLASHPAGEWRITE 0x2E + #define NVM_CMD_ERASEWRITEFLASH 0x2F + #define NVM_CMD_FLASHCRC 0x78 + #define NVM_CMD_ERASEAPPSEC 0x20 + #define NVM_CMD_ERASEAPPSECPAGE 0x22 + #define NVM_CMD_WRITEAPPSECPAGE 0x24 + #define NVM_CMD_ERASEWRITEAPPSECPAGE 0x25 + #define NVM_CMD_APPCRC 0x38 + #define NVM_CMD_ERASEBOOTSEC 0x68 + #define NVM_CMD_ERASEBOOTSECPAGE 0x2A + #define NVM_CMD_WRITEBOOTSECPAGE 0x2C + #define NVM_CMD_ERASEWRITEBOOTSECPAGE 0x2D + #define NVM_CMD_BOOTCRC 0x39 + #define NVM_CMD_READUSERSIG 0x03 + #define NVM_CMD_ERASEUSERSIG 0x18 + #define NVM_CMD_WRITEUSERSIG 0x1A + #define NVM_CMD_READCALIBRATION 0x02 + #define NVM_CMD_READFUSE 0x07 + #define NVM_CMD_WRITEFUSE 0x4C + #define NVM_CMD_WRITELOCK 0x08 + #define NVM_CMD_LOADEEPROMPAGEBUFF 0x33 + #define NVM_CMD_ERASEEEPROMPAGEBUFF 0x36 + #define NVM_CMD_ERASEEEPROM 0x30 + #define NVM_CMD_ERASEEEPROMPAGE 0x32 + #define NVM_CMD_WRITEEEPROMPAGE 0x34 + #define NVM_CMD_ERASEWRITEEEPROMPAGE 0x35 + #define NVM_CMD_READEEPROM 0x06 + /* Function Prototypes: */ - void NVMTarget_SendNVMRegAddress(uint8_t Register); + void NVMTarget_SendNVMRegAddress(uint8_t Register); + void NVMTarget_SendAddress(uint32_t AbsoluteAddress); bool NVMTarget_WaitWhileNVMBusBusy(void); void NVMTarget_WaitWhileNVMControllerBusy(void); uint32_t NVMTarget_GetMemoryCRC(uint8_t MemoryCommand); + void NVMTarget_ReadMemory(uint32_t ReadAddress, uint8_t* ReadBuffer, uint16_t ReadSize); #endif diff --git a/Projects/AVRISP/Lib/PDIProtocol.c b/Projects/AVRISP/Lib/PDIProtocol.c index a7b11557c9..e3255a0c64 100644 --- a/Projects/AVRISP/Lib/PDIProtocol.c +++ b/Projects/AVRISP/Lib/PDIProtocol.c @@ -216,20 +216,17 @@ static void PDIProtocol_ReadMemory(void) Endpoint_ClearOUT(); Endpoint_SetEndpointDirection(ENDPOINT_DIR_IN); - - if (ReadMemory_XPROG_Params.MemoryType == XPRG_MEM_TYPE_USERSIG) - { - PDITarget_SendByte(PDI_CMD_STS | (PDI_DATSIZE_1BYTE << 2)); - NVMTarget_SendNVMRegAddress(NVM_REG_CMD); - PDITarget_SendByte(NVM_CMD_READUSERSIG); - // TODO - } - + uint8_t ReadBuffer[ReadMemory_XPROG_Params.Length]; + NVMTarget_ReadMemory(ReadMemory_XPROG_Params.Address, ReadBuffer, ReadMemory_XPROG_Params.Length); + Endpoint_Write_Byte(CMD_XPROG); Endpoint_Write_Byte(XPRG_CMD_READ_MEM); Endpoint_Write_Byte(ReturnStatus); + if (ReturnStatus == XPRG_ERR_OK) + Endpoint_Write_Stream_LE(ReadBuffer, ReadMemory_XPROG_Params.Length); + Endpoint_ClearIN(); } @@ -250,13 +247,16 @@ static void PDIProtocol_ReadCRC(void) Endpoint_SetEndpointDirection(ENDPOINT_DIR_IN); uint32_t MemoryCRC; + uint8_t CRCCommand; if (ReadCRC_XPROG_Params.CRCType == XPRG_CRC_APP) - MemoryCRC = NVMTarget_GetMemoryCRC(NVM_CMD_APPCRC); + CRCCommand = NVM_CMD_APPCRC; else if (ReadCRC_XPROG_Params.CRCType == XPRG_CRC_BOOT) - MemoryCRC = NVMTarget_GetMemoryCRC(NVM_CMD_BOOTCRC); + CRCCommand = NVM_CMD_BOOTCRC; else - MemoryCRC = NVMTarget_GetMemoryCRC(NVM_CMD_FLASHCRC); + CRCCommand = NVM_CMD_FLASHCRC; + + MemoryCRC = NVMTarget_GetMemoryCRC(CRCCommand); Endpoint_Write_Byte(CMD_XPROG); Endpoint_Write_Byte(XPRG_CMD_CRC);