From 51c2dcf3b09960a5a50f57f8395a1e2655550db4 Mon Sep 17 00:00:00 2001 From: Dean Camera Date: Thu, 17 Jun 2010 09:17:09 +0000 Subject: Fixed broken PDI EEPROM Section Erase functionality in the AVRISP-MKII project. --- LUFA/ManPages/ChangeLog.txt | 1 + LUFA/ManPages/FutureChanges.txt | 1 - Projects/AVRISP-MKII/Lib/XPROG/XMEGANVM.c | 67 ++++++++++++++++++++++---- Projects/AVRISP-MKII/Lib/XPROG/XPROGProtocol.c | 10 ++-- 4 files changed, 64 insertions(+), 15 deletions(-) diff --git a/LUFA/ManPages/ChangeLog.txt b/LUFA/ManPages/ChangeLog.txt index 01e219e57..9d800a613 100644 --- a/LUFA/ManPages/ChangeLog.txt +++ b/LUFA/ManPages/ChangeLog.txt @@ -33,6 +33,7 @@ * - Fixed incorrect signature for the ATMEGA32U2 in the DFU bootloader (thanks to Axel Rohde) * - Fixed internal device serial not being accessible on the ATMEGAXXU2 AVRs (thanks to Axel Rohde) * - Fixed void pointer arithmetic in ConfigDescriptor.h breaking C++ compatibility (thanks to Michael Hennebry) + * - Fixed broken PDI EEPROM Section Erase functionality in the AVRISP-MKII project * * \section Sec_ChangeLog100513 Version 100513 * New: diff --git a/LUFA/ManPages/FutureChanges.txt b/LUFA/ManPages/FutureChanges.txt index 9c8891f2f..e7e1f900c 100644 --- a/LUFA/ManPages/FutureChanges.txt +++ b/LUFA/ManPages/FutureChanges.txt @@ -33,7 +33,6 @@ * -# Finish StandaloneProgrammer project * -# Finish MIDIToneGenerator project * -# Correct mishandling of error cases in Mass Storage demos - * -# Fix AVRISP-MKII clone project's XMEGA EEPROM section erase command * - Ports * -# AVR32 UC3B series microcontrollers * -# Atmel ARM7 series microcontrollers diff --git a/Projects/AVRISP-MKII/Lib/XPROG/XMEGANVM.c b/Projects/AVRISP-MKII/Lib/XPROG/XMEGANVM.c index 7921b03bc..150ad3ebf 100644 --- a/Projects/AVRISP-MKII/Lib/XPROG/XMEGANVM.c +++ b/Projects/AVRISP-MKII/Lib/XPROG/XMEGANVM.c @@ -315,7 +315,7 @@ bool XMEGANVM_WritePageMemory(const uint8_t WriteBuffCommand, const uint8_t Eras /** Erases a specific memory space of the target. * * \param[in] EraseCommand NVM erase command to send to the device - * \param[in] Address Address inside the memory space to erase + * \param[in] Address Address inside the memory space to erase * * \return Boolean true if the command sequence complete successfully */ @@ -324,22 +324,71 @@ bool XMEGANVM_EraseMemory(const uint8_t EraseCommand, const uint32_t Address) /* Wait until the NVM controller is no longer busy */ if (!(XMEGANVM_WaitWhileNVMControllerBusy())) return false; - - /* Send the memory erase command to the target */ - XPROGTarget_SendByte(PDI_CMD_STS | (PDI_DATSIZE_4BYTES << 2)); - XMEGANVM_SendNVMRegAddress(XMEGA_NVM_REG_CMD); - XPROGTarget_SendByte(EraseCommand); - - /* Chip erase is handled separately, since it's procedure is different to other erase types */ + + /* EEPROM and Chip erasures are triggered differently to FLASH section erasures */ if (EraseCommand == XMEGA_NVM_CMD_CHIPERASE) { - /* Set CMDEX bit in NVM CTRLA register to start the chip erase */ + /* Send the memory erase command to the target */ + XPROGTarget_SendByte(PDI_CMD_STS | (PDI_DATSIZE_4BYTES << 2)); + XMEGANVM_SendNVMRegAddress(XMEGA_NVM_REG_CMD); + XPROGTarget_SendByte(EraseCommand); + + /* Set CMDEX bit in NVM CTRLA register to start the erase sequence */ + XPROGTarget_SendByte(PDI_CMD_STS | (PDI_DATSIZE_4BYTES << 2)); + XMEGANVM_SendNVMRegAddress(XMEGA_NVM_REG_CTRLA); + XPROGTarget_SendByte(1 << 0); + } + else if (EraseCommand == XMEGA_NVM_CMD_ERASEEEPROM) + { + /* Send the EEPROM page buffer erase command to the target */ + XPROGTarget_SendByte(PDI_CMD_STS | (PDI_DATSIZE_4BYTES << 2)); + XMEGANVM_SendNVMRegAddress(XMEGA_NVM_REG_CMD); + XPROGTarget_SendByte(XMEGA_NVM_CMD_ERASEEEPROMPAGEBUFF); + + /* Set CMDEX bit in NVM CTRLA register to start the buffer erase */ + XPROGTarget_SendByte(PDI_CMD_STS | (PDI_DATSIZE_4BYTES << 2)); + XMEGANVM_SendNVMRegAddress(XMEGA_NVM_REG_CTRLA); + XPROGTarget_SendByte(1 << 0); + + /* Wait until the NVM controller is no longer busy */ + if (!(XMEGANVM_WaitWhileNVMControllerBusy())) + return false; + + /* Send the EEPROM memory buffer write command to the target */ + XPROGTarget_SendByte(PDI_CMD_STS | (PDI_DATSIZE_4BYTES << 2)); + XMEGANVM_SendNVMRegAddress(XMEGA_NVM_REG_CMD); + XPROGTarget_SendByte(XMEGA_NVM_CMD_LOADEEPROMPAGEBUFF); + + /* Load the PDI pointer register with the EEPROM page start address */ + XPROGTarget_SendByte(PDI_CMD_ST | (PDI_POINTER_DIRECT << 2) | PDI_DATSIZE_4BYTES); + XMEGANVM_SendAddress(Address); + + /* Send the REPEAT command with the specified number of bytes to write */ + XPROGTarget_SendByte(PDI_CMD_REPEAT | PDI_DATSIZE_1BYTE); + XPROGTarget_SendByte(XPROG_Param_EEPageSize - 1); + + /* Send a ST command with indirect access and post-increment to tag each byte in the EEPROM page buffer */ + XPROGTarget_SendByte(PDI_CMD_ST | (PDI_POINTER_INDIRECT_PI << 2) | PDI_DATSIZE_1BYTE); + for (uint8_t PageByte = 0; PageByte < XPROG_Param_EEPageSize; PageByte++) + XPROGTarget_SendByte(0x00); + + /* Send the memory erase command to the target */ + XPROGTarget_SendByte(PDI_CMD_STS | (PDI_DATSIZE_4BYTES << 2)); + XMEGANVM_SendNVMRegAddress(XMEGA_NVM_REG_CMD); + XPROGTarget_SendByte(EraseCommand); + + /* Set CMDEX bit in NVM CTRLA register to start the EEPROM erase sequence */ XPROGTarget_SendByte(PDI_CMD_STS | (PDI_DATSIZE_4BYTES << 2)); XMEGANVM_SendNVMRegAddress(XMEGA_NVM_REG_CTRLA); XPROGTarget_SendByte(1 << 0); } else { + /* Send the memory erase command to the target */ + XPROGTarget_SendByte(PDI_CMD_STS | (PDI_DATSIZE_4BYTES << 2)); + XMEGANVM_SendNVMRegAddress(XMEGA_NVM_REG_CMD); + XPROGTarget_SendByte(EraseCommand); + /* Other erase modes just need us to address a byte within the target memory space */ XPROGTarget_SendByte(PDI_CMD_STS | (PDI_DATSIZE_4BYTES << 2)); XMEGANVM_SendAddress(Address); diff --git a/Projects/AVRISP-MKII/Lib/XPROG/XPROGProtocol.c b/Projects/AVRISP-MKII/Lib/XPROG/XPROGProtocol.c index 47e2b4dff..f2c2674eb 100644 --- a/Projects/AVRISP-MKII/Lib/XPROG/XPROGProtocol.c +++ b/Projects/AVRISP-MKII/Lib/XPROG/XPROGProtocol.c @@ -38,19 +38,19 @@ #if defined(ENABLE_XPROG_PROTOCOL) || defined(__DOXYGEN__) /** Base absolute address for the target's NVM controller for PDI programming */ -uint32_t XPROG_Param_NVMBase = 0x010001C0; +uint32_t XPROG_Param_NVMBase = 0x010001C0; /** Size in bytes of the target's EEPROM page */ -uint16_t XPROG_Param_EEPageSize; +uint16_t XPROG_Param_EEPageSize = 32; /** Address of the TPI device's NVMCMD register for TPI programming */ -uint8_t XPROG_Param_NVMCMDRegAddr; +uint8_t XPROG_Param_NVMCMDRegAddr = 0x33; /** Address of the TPI device's NVMCSR register for TPI programming */ -uint8_t XPROG_Param_NVMCSRRegAddr; +uint8_t XPROG_Param_NVMCSRRegAddr = 0x32; /** Currently selected XPROG programming protocol */ -uint8_t XPROG_SelectedProtocol = XPRG_PROTOCOL_PDI; +uint8_t XPROG_SelectedProtocol = XPRG_PROTOCOL_PDI; /** Handler for the CMD_XPROG_SETMODE command, which sets the programmer-to-target protocol used for PDI/TPI * programming. -- cgit v1.2.3