From 37c9ba7fa980472406625973f0ee32719b5a8997 Mon Sep 17 00:00:00 2001
From: Dean Camera <dean@fourwalledcubicle.com>
Date: Sun, 20 Dec 2009 22:33:48 +0000
Subject: [PATCH] Fixed AVRISP project timeouts not checking for the correct
 timeout period (thanks to Carl Ott).

---
 LUFA/ManPages/ChangeLog.txt      |  1 +
 Projects/AVRISP/Lib/ISPTarget.c  | 28 +++++++++++++++++++++++-----
 Projects/AVRISP/Lib/NVMTarget.c  | 13 +++++++++++--
 Projects/AVRISP/Lib/PDITarget.c  | 13 +++++++++++--
 Projects/AVRISP/Lib/V2Protocol.h | 11 ++++++++++-
 Projects/AVRISP/makefile         |  2 +-
 6 files changed, 57 insertions(+), 11 deletions(-)

diff --git a/LUFA/ManPages/ChangeLog.txt b/LUFA/ManPages/ChangeLog.txt
index f28ed4772..f046a1f50 100644
--- a/LUFA/ManPages/ChangeLog.txt
+++ b/LUFA/ManPages/ChangeLog.txt
@@ -68,6 +68,7 @@
   *  - Fixed USB_CurrentMode not being reset to USB_MODE_NONE when the USB interface is shut down and both Host and Device modes can be
   *    used (thanks to Daniel Levy)
   *  - Fixed TeensyHID bootloader not enumerating to the host correctly
+  *  - Fixed AVRISP project timeouts not checking for the correct timeout period (thanks to Carl Ott)
   *
   *  \section Sec_ChangeLog091122 Version 091122
   *
diff --git a/Projects/AVRISP/Lib/ISPTarget.c b/Projects/AVRISP/Lib/ISPTarget.c
index fbe8ad31c..ce364c6cc 100644
--- a/Projects/AVRISP/Lib/ISPTarget.c
+++ b/Projects/AVRISP/Lib/ISPTarget.c
@@ -123,16 +123,25 @@ uint8_t ISPTarget_WaitForProgComplete(const uint8_t ProgrammingMode, const uint1
 		case PROG_MODE_WORD_VALUE_MASK:
 		case PROG_MODE_PAGED_VALUE_MASK:
 			TCNT0 = 0;
+			TIFR0 = (1 << OCF1A);
+			
+			uint8_t TimeoutMS = TARGET_BUSY_TIMEOUT_MS;
 
 			do
 			{
 				SPI_SendByte(ReadMemCommand);
 				SPI_SendByte(PollAddress >> 8);
-				SPI_SendByte(PollAddress & 0xFF);				
+				SPI_SendByte(PollAddress & 0xFF);
+
+				if (TIFR0 & (1 << OCF1A))
+				{
+					TIFR0 = (1 << OCF1A);
+					TimeoutMS--;
+				}
 			}
-			while ((SPI_TransferByte(0x00) != PollValue) && (TCNT0 < TARGET_BUSY_TIMEOUT_MS));
+			while ((SPI_TransferByte(0x00) != PollValue) && TimeoutMS);
 
-			if (TCNT0 >= TARGET_BUSY_TIMEOUT_MS)
+			if (!(TimeoutMS))
 			 ProgrammingStatus = STATUS_CMD_TOUT;
 			
 			break;		
@@ -153,6 +162,9 @@ uint8_t ISPTarget_WaitForProgComplete(const uint8_t ProgrammingMode, const uint1
 uint8_t ISPTarget_WaitWhileTargetBusy(void)
 {
 	TCNT0 = 0;
+	TIFR0 = (1 << OCF1A);
+			
+	uint8_t TimeoutMS = TARGET_BUSY_TIMEOUT_MS;
 	
 	do
 	{
@@ -160,10 +172,16 @@ uint8_t ISPTarget_WaitWhileTargetBusy(void)
 		SPI_SendByte(0x00);
 
 		SPI_SendByte(0x00);
+
+		if (TIFR0 & (1 << OCF1A))
+		{
+			TIFR0 = (1 << OCF1A);
+			TimeoutMS--;
+		}
 	}
-	while ((SPI_ReceiveByte() & 0x01) && (TCNT0 < TARGET_BUSY_TIMEOUT_MS));
+	while ((SPI_ReceiveByte() & 0x01) && TimeoutMS);
 
-	if (TCNT0 >= TARGET_BUSY_TIMEOUT_MS)
+	if (!(TimeoutMS))
 	  return STATUS_RDY_BSY_TOUT;
 	else
 	  return STATUS_CMD_OK;
diff --git a/Projects/AVRISP/Lib/NVMTarget.c b/Projects/AVRISP/Lib/NVMTarget.c
index 00312d513..adf213bb4 100644
--- a/Projects/AVRISP/Lib/NVMTarget.c
+++ b/Projects/AVRISP/Lib/NVMTarget.c
@@ -72,9 +72,12 @@ void NVMTarget_SendAddress(const uint32_t AbsoluteAddress)
 bool NVMTarget_WaitWhileNVMControllerBusy(void)
 {
 	TCNT0 = 0;
-
+	TIFR0 = (1 << OCF1A);
+			
+	uint8_t TimeoutMS = PDI_NVM_TIMEOUT_MS;
+	
 	/* Poll the NVM STATUS register while the NVM controller is busy */
-	while (TCNT0 < NVM_BUSY_TIMEOUT_MS)
+	while (TimeoutMS)
 	{
 		/* Send a LDS command to read the NVM STATUS register to check the BUSY flag */
 		PDITarget_SendByte(PDI_CMD_LDS | (PDI_DATSIZE_4BYTES << 2));
@@ -83,6 +86,12 @@ bool NVMTarget_WaitWhileNVMControllerBusy(void)
 		/* Check to see if the BUSY flag is still set */
 		if (!(PDITarget_ReceiveByte() & (1 << 7)))
 		  return true;
+
+		if (TIFR0 & (1 << OCF1A))
+		{
+			TIFR0 = (1 << OCF1A);
+			TimeoutMS--;
+		}
 	}
 	
 	return false;
diff --git a/Projects/AVRISP/Lib/PDITarget.c b/Projects/AVRISP/Lib/PDITarget.c
index df01497f6..29bb33985 100644
--- a/Projects/AVRISP/Lib/PDITarget.c
+++ b/Projects/AVRISP/Lib/PDITarget.c
@@ -311,14 +311,23 @@ void PDITarget_SendBreak(void)
 bool PDITarget_WaitWhileNVMBusBusy(void)
 {
 	TCNT0 = 0;
-
+	TIFR0 = (1 << OCF1A);
+			
+	uint8_t TimeoutMS = PDI_NVM_TIMEOUT_MS;
+	
 	/* Poll the STATUS register to check to see if NVM access has been enabled */
-	while (TCNT0 < PDI_NVM_TIMEOUT_MS)
+	while (TimeoutMS)
 	{
 		/* Send the LDCS command to read the PDI STATUS register to see the NVM bus is active */
 		PDITarget_SendByte(PDI_CMD_LDCS | PDI_STATUS_REG);
 		if (PDITarget_ReceiveByte() & PDI_STATUS_NVM)
 		  return true;
+
+		if (TIFR0 & (1 << OCF1A))
+		{
+			TIFR0 = (1 << OCF1A);
+			TimeoutMS--;
+		}
 	}
 	
 	return false;
diff --git a/Projects/AVRISP/Lib/V2Protocol.h b/Projects/AVRISP/Lib/V2Protocol.h
index 5f996eadd..1777e0fe1 100644
--- a/Projects/AVRISP/Lib/V2Protocol.h
+++ b/Projects/AVRISP/Lib/V2Protocol.h
@@ -70,7 +70,16 @@
 		static inline void V2Protocol_DelayMS(uint8_t DelayMS)
 		{
 			TCNT0 = 0;
-			while (TCNT0 < DelayMS);
+			TIFR0 = (1 << OCF1A);
+
+			while (DelayMS)
+			{
+				if (TIFR0 & (1 << OCF1A))
+				{
+					TIFR0 = (1 << OCF1A);
+					DelayMS--;
+				}
+			}
 		}
 
 	/* External Variables: */
diff --git a/Projects/AVRISP/makefile b/Projects/AVRISP/makefile
index 23e27c52d..2b6a1e858 100644
--- a/Projects/AVRISP/makefile
+++ b/Projects/AVRISP/makefile
@@ -66,7 +66,7 @@ MCU = at90usb1287
 # Target board (see library "Board Types" documentation, USER or blank for projects not requiring
 # LUFA board drivers). If USER is selected, put custom board drivers in a directory called 
 # "Board" inside the application directory.
-BOARD = XPLAIN
+BOARD = USBKEY
 
 
 # Processor frequency.
-- 
GitLab