Fixed broken PDI EEPROM Section Erase functionality in the AVRISP-MKII project.
authorDean Camera <dean@fourwalledcubicle.com>
Thu, 17 Jun 2010 09:17:09 +0000 (09:17 +0000)
committerDean Camera <dean@fourwalledcubicle.com>
Thu, 17 Jun 2010 09:17:09 +0000 (09:17 +0000)
LUFA/ManPages/ChangeLog.txt
LUFA/ManPages/FutureChanges.txt
Projects/AVRISP-MKII/Lib/XPROG/XMEGANVM.c
Projects/AVRISP-MKII/Lib/XPROG/XPROGProtocol.c

index 01e219e..9d800a6 100644 (file)
@@ -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
   *  <b>New:</b>
index 9c8891f..e7e1f90 100644 (file)
@@ -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
index 7921b03..150ad3e 100644 (file)
@@ -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);
index 47e2b4d..f2c2674 100644 (file)
 
 #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.