X-Git-Url: http://git.linex4red.de/pub/USBasp.git/blobdiff_plain/711542ee8986482a12796ffdbc4a32912b267e44..55d7e1e65bccd6b4c44802cf971f39eb05e6e57a:/Projects/AVRISP-MKII/Lib/XPROG/XMEGANVM.c 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);