From 8ea051de637f09f0fd2895f5a18ee9f337b9b1f1 Mon Sep 17 00:00:00 2001 From: Dean Camera Date: Tue, 15 Dec 2009 00:58:22 +0000 Subject: [PATCH] Add Lock/Fuse byte programming support to the AVRISP PDI programming protocol code. --- Projects/AVRISP/Lib/NVMTarget.c | 35 +++++++++++++++++++++ Projects/AVRISP/Lib/NVMTarget.h | 2 ++ Projects/AVRISP/Lib/PDIProtocol.c | 52 ++++++++++++++++++++++++++++--- 3 files changed, 84 insertions(+), 5 deletions(-) diff --git a/Projects/AVRISP/Lib/NVMTarget.c b/Projects/AVRISP/Lib/NVMTarget.c index c2ed92d2e2..d84ae6b858 100644 --- a/Projects/AVRISP/Lib/NVMTarget.c +++ b/Projects/AVRISP/Lib/NVMTarget.c @@ -114,6 +114,10 @@ bool NVMTarget_GetMemoryCRC(uint8_t CRCCommand, uint32_t* CRCDest) NVMTarget_SendNVMRegAddress(NVM_REG_CTRLA); PDITarget_SendByte(1 << 0); + /* Wait until the NVM bus is ready again */ + if (!(PDITarget_WaitWhileNVMBusBusy())) + return false; + /* Wait until the NVM controller is no longer busy */ if (!(NVMTarget_WaitWhileNVMControllerBusy())) return false; @@ -180,6 +184,37 @@ bool NVMTarget_ReadMemory(uint32_t ReadAddress, uint8_t* ReadBuffer, uint16_t Re return true; } +/** Writes byte addressed memory to the target's memory spaces. + * + * \param[in] WriteCommand Command to send to the device to write each memory page + * \param[in] WriteAddress Start address to write to within the target's address space + * \param[in] WriteBuffer Buffer to source data from + * \param[in] WriteSize Number of bytes to write + * + * \return Boolean true if the command sequence complete sucessfully + */ +bool NVMTarget_WriteByteMemory(uint8_t WriteCommand, uint32_t WriteAddress, uint8_t* WriteBuffer, uint16_t WriteSize) +{ + for (uint8_t i = 0; i < WriteSize; i++) + { + /* Wait until the NVM controller is no longer busy */ + if (!(NVMTarget_WaitWhileNVMControllerBusy())) + return false; + + /* Send the memory write command to the target */ + PDITarget_SendByte(PDI_CMD_STS | (PDI_DATSIZE_4BYTES << 2)); + NVMTarget_SendNVMRegAddress(NVM_REG_CMD); + PDITarget_SendByte(WriteCommand); + + /* Send each new memory byte to the memory to the target */ + PDITarget_SendByte(PDI_CMD_STS | (PDI_DATSIZE_4BYTES << 2)); + NVMTarget_SendAddress(WriteAddress++); + PDITarget_SendByte(*(WriteBuffer++)); + } + + return true; +} + /** Erases a specific memory space of the target. * * \param[in] EraseCommand NVM erase command to send to the device diff --git a/Projects/AVRISP/Lib/NVMTarget.h b/Projects/AVRISP/Lib/NVMTarget.h index dae55ed121..dea9ff3dec 100644 --- a/Projects/AVRISP/Lib/NVMTarget.h +++ b/Projects/AVRISP/Lib/NVMTarget.h @@ -111,6 +111,8 @@ bool NVMTarget_WaitWhileNVMControllerBusy(void); bool NVMTarget_GetMemoryCRC(uint8_t CRCCommand, uint32_t* CRCDest); bool NVMTarget_ReadMemory(uint32_t ReadAddress, uint8_t* ReadBuffer, uint16_t ReadSize); + bool NVMTarget_WriteByteMemory(uint8_t WriteCommand, uint32_t WriteAddress, uint8_t* WriteBuffer, + uint16_t WriteSize); bool NVMTarget_EraseMemory(uint8_t EraseCommand, uint32_t Address); #endif diff --git a/Projects/AVRISP/Lib/PDIProtocol.c b/Projects/AVRISP/Lib/PDIProtocol.c index 46d6dd417e..36aa3b4c5c 100644 --- a/Projects/AVRISP/Lib/PDIProtocol.c +++ b/Projects/AVRISP/Lib/PDIProtocol.c @@ -162,7 +162,7 @@ static void PDIProtocol_Erase(void) Endpoint_ClearOUT(); Endpoint_SetEndpointDirection(ENDPOINT_DIR_IN); - uint8_t EraseCommand; + uint8_t EraseCommand = NVM_CMD_NOOP; if (Erase_XPROG_Params.MemoryType == XPRG_ERASE_CHIP) EraseCommand = NVM_CMD_CHIPERASE; @@ -198,9 +198,10 @@ static void PDIProtocol_WriteMemory(void) struct { uint8_t MemoryType; + uint8_t PageMode; uint32_t Address; uint16_t Length; - uint8_t ProgData[256]; + uint8_t ProgData[512]; } WriteMemory_XPROG_Params; Endpoint_Read_Stream_LE(&WriteMemory_XPROG_Params, (sizeof(WriteMemory_XPROG_Params) - @@ -211,11 +212,52 @@ static void PDIProtocol_WriteMemory(void) Endpoint_ClearOUT(); Endpoint_SetEndpointDirection(ENDPOINT_DIR_IN); + + + uint8_t WriteCommand = NVM_CMD_NOOP; + uint8_t WritePageCommand = NVM_CMD_NOOP; + bool PagedMemory = false; + + if (WriteMemory_XPROG_Params.MemoryType == XPRG_MEM_TYPE_APPL) + { + PagedMemory = true; + } + else if (WriteMemory_XPROG_Params.MemoryType == XPRG_MEM_TYPE_BOOT) + { + PagedMemory = true; + } + else if (WriteMemory_XPROG_Params.MemoryType == XPRG_MEM_TYPE_EEPROM) + { + PagedMemory = true; + } + else if (WriteMemory_XPROG_Params.MemoryType == XPRG_MEM_TYPE_USERSIG) + { + PagedMemory = true; + } + else if (WriteMemory_XPROG_Params.MemoryType == XPRG_MEM_TYPE_FUSE) + { + WriteCommand = NVM_CMD_WRITEFUSE; + } + else if (WriteMemory_XPROG_Params.MemoryType == XPRG_MEM_TYPE_LOCKBITS) + { + WriteCommand = NVM_CMD_WRITELOCK; + } - // TODO: Send program command here via PDI protocol + if (PagedMemory) + { + + } + else + { + if (!(NVMTarget_WriteByteMemory(WriteCommand, WriteMemory_XPROG_Params.Address, WriteMemory_XPROG_Params.ProgData, + WriteMemory_XPROG_Params.Length))) + { + ReturnStatus = XPRG_ERR_TIMEOUT; + } + } Endpoint_Write_Byte(CMD_XPROG); - Endpoint_Write_Byte(XPRG_CMD_READ_MEM); + Endpoint_Write_Byte(XPRG_CMD_WRITE_MEM); Endpoint_Write_Byte(ReturnStatus); Endpoint_ClearIN(); } @@ -272,8 +314,8 @@ static void PDIProtocol_ReadCRC(void) Endpoint_ClearOUT(); Endpoint_SetEndpointDirection(ENDPOINT_DIR_IN); + uint8_t CRCCommand = NVM_CMD_NOOP; uint32_t MemoryCRC; - uint8_t CRCCommand; if (ReadCRC_XPROG_Params.CRCType == XPRG_CRC_APP) CRCCommand = NVM_CMD_APPCRC;