From 48e50b6b578fa7a74b4f33f067aa684e3469850e Mon Sep 17 00:00:00 2001
From: Dean Camera <dean@fourwalledcubicle.com>
Date: Mon, 14 Dec 2009 05:15:42 +0000
Subject: [PATCH] Added memory erase handling to the PDI protocol in the AVRISP
 project.

---
 Projects/AVRISP/Lib/NVMTarget.c   | 27 +++++++++++++++++++++++++++
 Projects/AVRISP/Lib/NVMTarget.h   |  1 +
 Projects/AVRISP/Lib/PDIProtocol.c | 22 +++++++++++++++++++++-
 3 files changed, 49 insertions(+), 1 deletion(-)

diff --git a/Projects/AVRISP/Lib/NVMTarget.c b/Projects/AVRISP/Lib/NVMTarget.c
index fee432cfb..a23ccf292 100644
--- a/Projects/AVRISP/Lib/NVMTarget.c
+++ b/Projects/AVRISP/Lib/NVMTarget.c
@@ -137,4 +137,31 @@ void NVMTarget_ReadMemory(uint32_t ReadAddress, uint8_t* ReadBuffer, uint16_t Re
 	}
 }
 
+void NVMTarget_EraseMemory(uint8_t EraseCommand, uint32_t Address)
+{
+	NVMTarget_WaitWhileNVMControllerBusy();
+
+	PDITarget_SendByte(PDI_CMD_STS | (PDI_DATSIZE_4BYTES << 2));
+	NVMTarget_SendNVMRegAddress(NVM_REG_CMD);
+	PDITarget_SendByte(EraseCommand);
+	
+	if (EraseCommand == NVM_CMD_CHIPERASE)
+	{
+		/* Set CMDEX bit in NVM CTRLA register to start the chip erase */
+		PDITarget_SendByte(PDI_CMD_STS | (PDI_DATSIZE_4BYTES << 2));
+		NVMTarget_SendNVMRegAddress(NVM_REG_CTRLA);
+		PDITarget_SendByte(1 << 0);		
+	}
+	else
+	{
+		/* Other erase modes just need us to address a byte within the target memory space */
+		PDITarget_SendByte(PDI_CMD_STS | (PDI_DATSIZE_4BYTES << 2));
+		NVMTarget_SendAddress(Address);	
+		PDITarget_SendByte(0x00);
+	}
+	
+	NVMTarget_WaitWhileNVMBusBusy();
+	NVMTarget_WaitWhileNVMControllerBusy();
+}
+
 #endif
diff --git a/Projects/AVRISP/Lib/NVMTarget.h b/Projects/AVRISP/Lib/NVMTarget.h
index 0f2dad504..bd9296f74 100644
--- a/Projects/AVRISP/Lib/NVMTarget.h
+++ b/Projects/AVRISP/Lib/NVMTarget.h
@@ -117,5 +117,6 @@
 		void     NVMTarget_WaitWhileNVMControllerBusy(void);
 		uint32_t NVMTarget_GetMemoryCRC(uint8_t MemoryCommand);
 		void     NVMTarget_ReadMemory(uint32_t ReadAddress, uint8_t* ReadBuffer, uint16_t ReadSize);
+		void     NVMTarget_EraseMemory(uint8_t EraseCommand, uint32_t Address);
 
 #endif
diff --git a/Projects/AVRISP/Lib/PDIProtocol.c b/Projects/AVRISP/Lib/PDIProtocol.c
index e3255a0c6..39f33cf49 100644
--- a/Projects/AVRISP/Lib/PDIProtocol.c
+++ b/Projects/AVRISP/Lib/PDIProtocol.c
@@ -154,11 +154,31 @@ static void PDIProtocol_Erase(void)
 	} Erase_XPROG_Params;
 
 	Endpoint_Read_Stream_LE(&Erase_XPROG_Params, sizeof(Erase_XPROG_Params));
+	Erase_XPROG_Params.Address = SwapEndian_32(Erase_XPROG_Params.Address);
 
 	Endpoint_ClearOUT();
 	Endpoint_SetEndpointDirection(ENDPOINT_DIR_IN);
 	
-	// TODO: Send erase command here via PDI protocol
+	uint8_t EraseCommand;
+	
+	if (Erase_XPROG_Params.MemoryType == XPRG_ERASE_CHIP)
+	  EraseCommand = NVM_CMD_CHIPERASE;
+	else if (Erase_XPROG_Params.MemoryType == XPRG_ERASE_APP)
+	  EraseCommand = NVM_CMD_ERASEAPPSEC;
+	else if (Erase_XPROG_Params.MemoryType == XPRG_ERASE_BOOT)
+	  EraseCommand = NVM_CMD_ERASEBOOTSEC;
+	else if (Erase_XPROG_Params.MemoryType == XPRG_ERASE_EEPROM)
+	  EraseCommand = NVM_CMD_ERASEEEPROM;
+	else if (Erase_XPROG_Params.MemoryType == XPRG_ERASE_APP_PAGE)
+	  EraseCommand = NVM_CMD_ERASEAPPSECPAGE;
+	else if (Erase_XPROG_Params.MemoryType == XPRG_ERASE_BOOT_PAGE)
+	  EraseCommand = NVM_CMD_ERASEBOOTSECPAGE;
+	else if (Erase_XPROG_Params.MemoryType == XPRG_ERASE_EEPROM_PAGE)
+	  EraseCommand = NVM_CMD_ERASEEEPROMPAGE;
+	else if (Erase_XPROG_Params.MemoryType == XPRG_ERASE_USERSIG)
+	  EraseCommand = NVM_CMD_ERASEUSERSIG;
+	
+	NVMTarget_EraseMemory(EraseCommand, Erase_XPROG_Params.Address);
 	
 	Endpoint_Write_Byte(CMD_XPROG);
 	Endpoint_Write_Byte(XPRG_CMD_ERASE);
-- 
GitLab