From 666c0fa4c31b2c9f7f02f6d0e09551e24dc4680c Mon Sep 17 00:00:00 2001
From: Dean Camera <dean@fourwalledcubicle.com>
Date: Tue, 13 Jul 2010 11:26:03 +0000
Subject: [PATCH] Remove the timeout period extension code from the AVRISP
 project, as no single command should ever exceed the maximum timeout period.
 Extend timeout period to 1 second per command, so that an accidental timeout
 will never occur.

---
 LUFA/ManPages/ChangeLog.txt                   |  2 ++
 Projects/AVRISP-MKII/Lib/ISP/ISPProtocol.c    | 11 +++-------
 Projects/AVRISP-MKII/Lib/ISP/ISPTarget.c      | 19 ++++--------------
 Projects/AVRISP-MKII/Lib/V2Protocol.c         | 12 +++++------
 Projects/AVRISP-MKII/Lib/V2Protocol.h         |  6 +++---
 Projects/AVRISP-MKII/Lib/XPROG/TINYNVM.c      | 18 ++++++-----------
 Projects/AVRISP-MKII/Lib/XPROG/XMEGANVM.c     | 20 +++++++------------
 .../AVRISP-MKII/Lib/XPROG/XPROGProtocol.c     |  2 +-
 Projects/AVRISP-MKII/Lib/XPROG/XPROGTarget.c  | 17 +---------------
 9 files changed, 33 insertions(+), 74 deletions(-)

diff --git a/LUFA/ManPages/ChangeLog.txt b/LUFA/ManPages/ChangeLog.txt
index 6f1bc3ae6..b75798d68 100644
--- a/LUFA/ManPages/ChangeLog.txt
+++ b/LUFA/ManPages/ChangeLog.txt
@@ -44,6 +44,8 @@
   *  - 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
   *  - Fixed USB_Device_SendRemoteWakeup() not working when the USB clock was frozen during USB bus suspend (thanks to Brian Dickman)
+  *  - Fixed occasional lockup of the AVRISP project due to the timeout extension code incorrectly extending the timeout in
+  *    PDI and TPI programming modes infinitely
   *
   *  \section Sec_ChangeLog100513 Version 100513
   *  <b>New:</b>
diff --git a/Projects/AVRISP-MKII/Lib/ISP/ISPProtocol.c b/Projects/AVRISP-MKII/Lib/ISP/ISPProtocol.c
index 2ce11a8ee..d6e02fa2b 100644
--- a/Projects/AVRISP-MKII/Lib/ISP/ISPProtocol.c
+++ b/Projects/AVRISP-MKII/Lib/ISP/ISPProtocol.c
@@ -76,7 +76,7 @@ void ISPProtocol_EnterISPMode(void)
 
 	/* Continuously attempt to synchronize with the target until either the number of attempts specified
 	 * by the host has exceeded, or the the device sends back the expected response values */
-	while (Enter_ISP_Params.SynchLoops-- && (ResponseStatus == STATUS_CMD_FAILED) && TimeoutMSRemaining)
+	while (Enter_ISP_Params.SynchLoops-- && (ResponseStatus == STATUS_CMD_FAILED) && TimeoutTicksRemaining)
 	{
 		uint8_t ResponseBytes[4];
 
@@ -552,13 +552,8 @@ void ISPProtocol_SPIMulti(void)
  */
 void ISPProtocol_DelayMS(uint8_t DelayMS)
 {
-	while (DelayMS-- && TimeoutMSRemaining)
-	{
-		if (TimeoutMSRemaining)
-		  TimeoutMSRemaining--;
-		  
-		_delay_ms(1);
-	}
+	while (DelayMS-- && TimeoutTicksRemaining)
+	  _delay_ms(1);
 }
 
 #endif
\ No newline at end of file
diff --git a/Projects/AVRISP-MKII/Lib/ISP/ISPTarget.c b/Projects/AVRISP-MKII/Lib/ISP/ISPTarget.c
index 9a74aabb2..430c9158a 100644
--- a/Projects/AVRISP-MKII/Lib/ISP/ISPTarget.c
+++ b/Projects/AVRISP-MKII/Lib/ISP/ISPTarget.c
@@ -129,9 +129,9 @@ uint8_t ISPTarget_WaitForProgComplete(const uint8_t ProgrammingMode, const uint1
 				SPI_SendByte(PollAddress >> 8);
 				SPI_SendByte(PollAddress & 0xFF);
 			}
-			while ((SPI_TransferByte(0x00) == PollValue) && TimeoutMSRemaining);
+			while ((SPI_TransferByte(0x00) == PollValue) && TimeoutTicksRemaining);
 
-			if (!(TimeoutMSRemaining))
+			if (!(TimeoutTicksRemaining))
 			 ProgrammingStatus = STATUS_CMD_TOUT;
 			
 			break;		
@@ -141,9 +141,6 @@ uint8_t ISPTarget_WaitForProgComplete(const uint8_t ProgrammingMode, const uint1
 			break;
 	}
 
-	if (ProgrammingStatus == STATUS_CMD_OK)
-	  TimeoutMSRemaining = COMMAND_TIMEOUT_MS;
-
 	return ProgrammingStatus;
 }
 
@@ -160,17 +157,9 @@ uint8_t ISPTarget_WaitWhileTargetBusy(void)
 		SPI_SendByte(0x00);
 		SPI_SendByte(0x00);
 	}
-	while ((SPI_ReceiveByte() & 0x01) && TimeoutMSRemaining);
+	while ((SPI_ReceiveByte() & 0x01) && TimeoutTicksRemaining);
 
-	if (TimeoutMSRemaining)
-	{
-		TimeoutMSRemaining = COMMAND_TIMEOUT_MS;
-		return STATUS_CMD_OK;
-	}
-	else
-	{
-		return STATUS_RDY_BSY_TOUT;
-	}
+	return TimeoutTicksRemaining ? STATUS_CMD_OK : STATUS_RDY_BSY_TOUT;
 }
 
 /** Sends a low-level LOAD EXTENDED ADDRESS command to the target, for addressing of memory beyond the
diff --git a/Projects/AVRISP-MKII/Lib/V2Protocol.c b/Projects/AVRISP-MKII/Lib/V2Protocol.c
index d6bb32a14..9e210c26a 100644
--- a/Projects/AVRISP-MKII/Lib/V2Protocol.c
+++ b/Projects/AVRISP-MKII/Lib/V2Protocol.c
@@ -46,8 +46,8 @@ bool MustLoadExtendedAddress;
 /** ISR to manage timeouts whilst processing a V2Protocol command */
 ISR(TIMER0_COMPA_vect, ISR_NOBLOCK)
 {
-	if (TimeoutMSRemaining)
-	  TimeoutMSRemaining--;
+	if (TimeoutTicksRemaining)
+	  TimeoutTicksRemaining--;
 }
 
 /** Initializes the hardware and software associated with the V2 protocol command handling. */
@@ -60,8 +60,8 @@ void V2Protocol_Init(void)
 	ADC_StartReading(VTARGET_ADC_CHANNEL_MASK | ADC_RIGHT_ADJUSTED | ADC_REFERENCE_AVCC);
 	#endif
 	
-	/* Millisecond timer initialization for managing the command timeout counter */
-	OCR0A  = ((F_CPU / 64) / 1000);
+	/* Timeout timer initialization (10ms period) */
+	OCR0A  = ((F_CPU / 1024) / 100);
 	TCCR0A = (1 << WGM01);
 	TIMSK0 = (1 << OCIE0A);
 	
@@ -77,8 +77,8 @@ void V2Protocol_ProcessCommand(void)
 	uint8_t V2Command = Endpoint_Read_Byte();
 	
 	/* Start the timeout management timer */
-	TimeoutMSRemaining = COMMAND_TIMEOUT_MS;
-	TCCR0B = ((1 << CS01) | (1 << CS00));
+	TimeoutTicksRemaining = COMMAND_TIMEOUT_TICKS;
+	TCCR0B = ((1 << CS02) | (1 << CS00));
 	
 	switch (V2Command)
 	{
diff --git a/Projects/AVRISP-MKII/Lib/V2Protocol.h b/Projects/AVRISP-MKII/Lib/V2Protocol.h
index 5b8589294..12ab5992d 100644
--- a/Projects/AVRISP-MKII/Lib/V2Protocol.h
+++ b/Projects/AVRISP-MKII/Lib/V2Protocol.h
@@ -66,11 +66,11 @@
 		/** Programmer ID string, returned to the host during the CMD_SIGN_ON command processing. */
 		#define PROGRAMMER_ID              "AVRISP_MK2"
 		
-		/** Timeout period for each issued command from the host before it is aborted. */
-		#define COMMAND_TIMEOUT_MS         200
+		/** Timeout period for each issued command from the host before it is aborted (in 10ms ticks). */
+		#define COMMAND_TIMEOUT_TICKS      100
 		
 		/** Command timeout counter register, GPIOR for speed. */
-		#define TimeoutMSRemaining         GPIOR0
+		#define TimeoutTicksRemaining      GPIOR0
 
 		/** MUX mask for the VTARGET ADC channel number. */
 		#define VTARGET_ADC_CHANNEL_MASK   _GETADCMUXMASK(ADC_CHANNEL, VTARGET_ADC_CHANNEL)
diff --git a/Projects/AVRISP-MKII/Lib/XPROG/TINYNVM.c b/Projects/AVRISP-MKII/Lib/XPROG/TINYNVM.c
index e0e2479ea..150f64244 100644
--- a/Projects/AVRISP-MKII/Lib/XPROG/TINYNVM.c
+++ b/Projects/AVRISP-MKII/Lib/XPROG/TINYNVM.c
@@ -85,15 +85,12 @@ bool TINYNVM_WaitWhileNVMBusBusy(void)
 		uint8_t StatusRegister = XPROGTarget_ReceiveByte();
 
 		/* We might have timed out waiting for the status register read response, check here */
-		if (!(TimeoutMSRemaining))
+		if (!(TimeoutTicksRemaining))
 		  return false;
 
 		/* Check the status register read response to see if the NVM bus is enabled */
 		if (StatusRegister & TPI_STATUS_NVM)
-		{
-			TimeoutMSRemaining = COMMAND_TIMEOUT_MS;
-			return true;
-		}
+		  return true;
 	}
 }
 
@@ -113,15 +110,12 @@ bool TINYNVM_WaitWhileNVMControllerBusy(void)
 		uint8_t StatusRegister = XPROGTarget_ReceiveByte();
 
 		/* We might have timed out waiting for the status register read response, check here */
-		if (!(TimeoutMSRemaining))
+		if (!(TimeoutTicksRemaining))
 		  return false;
 
 		/* Check to see if the BUSY flag is still set */
 		if (!(StatusRegister & (1 << 7)))
-		{
-			TimeoutMSRemaining = COMMAND_TIMEOUT_MS;
-			return true;
-		}
+		  return true;
 	}
 }
 
@@ -146,14 +140,14 @@ bool TINYNVM_ReadMemory(const uint16_t ReadAddress, uint8_t* ReadBuffer, uint16_
 	/* Send the address of the location to read from */
 	TINYNVM_SendPointerAddress(ReadAddress);
 	
-	while (ReadSize-- && TimeoutMSRemaining)
+	while (ReadSize-- && TimeoutTicksRemaining)
 	{
 		/* Read the byte of data from the target */
 		XPROGTarget_SendByte(TPI_CMD_SLD | TPI_POINTER_INDIRECT_PI);
 		*(ReadBuffer++) = XPROGTarget_ReceiveByte();
 	}
 	
-	return (TimeoutMSRemaining != 0);
+	return (TimeoutTicksRemaining != 0);
 }
 
 /** Writes word addressed memory to the target's memory spaces.
diff --git a/Projects/AVRISP-MKII/Lib/XPROG/XMEGANVM.c b/Projects/AVRISP-MKII/Lib/XPROG/XMEGANVM.c
index 2caee6a87..93419d00d 100644
--- a/Projects/AVRISP-MKII/Lib/XPROG/XMEGANVM.c
+++ b/Projects/AVRISP-MKII/Lib/XPROG/XMEGANVM.c
@@ -80,15 +80,12 @@ bool XMEGANVM_WaitWhileNVMBusBusy(void)
 		uint8_t StatusRegister = XPROGTarget_ReceiveByte();
 		
 		/* We might have timed out waiting for the status register read response, check here */
-		if (!(TimeoutMSRemaining))
+		if (!(TimeoutTicksRemaining))
 		  return false;
 		
 		/* Check the status register read response to see if the NVM bus is enabled */
 		if (StatusRegister & PDI_STATUS_NVM)
-		{
-			TimeoutMSRemaining = COMMAND_TIMEOUT_MS;
-			return true;
-		}
+		  return true;
 	}
 }
 
@@ -109,15 +106,12 @@ bool XMEGANVM_WaitWhileNVMControllerBusy(void)
 		uint8_t StatusRegister = XPROGTarget_ReceiveByte();
 
 		/* We might have timed out waiting for the status register read response, check here */
-		if (!(TimeoutMSRemaining))
+		if (!(TimeoutTicksRemaining))
 		  return false;
 
 		/* Check to see if the BUSY flag is still set */
 		if (!(StatusRegister & (1 << 7)))
-		{
-			TimeoutMSRemaining = COMMAND_TIMEOUT_MS;
-			return true;
-		}
+		  return true;
 	}
 }
 
@@ -165,7 +159,7 @@ bool XMEGANVM_GetMemoryCRC(const uint8_t CRCCommand, uint32_t* const CRCDest)
 	for (uint8_t i = 0; i < XMEGA_CRC_LENGTH; i++)
 	  ((uint8_t*)CRCDest)[i] = XPROGTarget_ReceiveByte();
 	
-	return (TimeoutMSRemaining != 0);
+	return (TimeoutTicksRemaining != 0);
 }
 
 /** Reads memory from the target's memory spaces.
@@ -197,10 +191,10 @@ bool XMEGANVM_ReadMemory(const uint32_t ReadAddress, uint8_t* ReadBuffer, uint16
 		
 	/* Send a LD command with indirect access and post-increment to read out the bytes */
 	XPROGTarget_SendByte(PDI_CMD_LD | (PDI_POINTER_INDIRECT_PI << 2) | PDI_DATSIZE_1BYTE);
-	while (ReadSize-- && TimeoutMSRemaining)
+	while (ReadSize-- && TimeoutTicksRemaining)
 	  *(ReadBuffer++) = XPROGTarget_ReceiveByte();
 	
-	return (TimeoutMSRemaining != 0);
+	return (TimeoutTicksRemaining != 0);
 }
 
 /** Writes byte addressed memory to the target's memory spaces.
diff --git a/Projects/AVRISP-MKII/Lib/XPROG/XPROGProtocol.c b/Projects/AVRISP-MKII/Lib/XPROG/XPROGProtocol.c
index f2c2674eb..84d82bc5f 100644
--- a/Projects/AVRISP-MKII/Lib/XPROG/XPROGProtocol.c
+++ b/Projects/AVRISP-MKII/Lib/XPROG/XPROGProtocol.c
@@ -131,7 +131,7 @@ static void XPROGProtocol_EnterXPROGMode(void)
 		XPROGTarget_SendByte(0x07);
 
 		/* Enable access to the XPROG NVM bus by sending the documented NVM access key to the device */
-		XPROGTarget_SendByte(PDI_CMD_KEY);	
+		XPROGTarget_SendByte(PDI_CMD_KEY);
 		for (uint8_t i = sizeof(PDI_NVMENABLE_KEY); i > 0; i--)
 		  XPROGTarget_SendByte(PDI_NVMENABLE_KEY[i - 1]);
 
diff --git a/Projects/AVRISP-MKII/Lib/XPROG/XPROGTarget.c b/Projects/AVRISP-MKII/Lib/XPROG/XPROGTarget.c
index 07efbb1da..2e5200561 100644
--- a/Projects/AVRISP-MKII/Lib/XPROG/XPROGTarget.c
+++ b/Projects/AVRISP-MKII/Lib/XPROG/XPROGTarget.c
@@ -138,9 +138,6 @@ void XPROGTarget_SendByte(const uint8_t Byte)
 	while (!(UCSR1A & (1 << UDRE1)));
 	UCSR1A |= (1 << TXC1);
 	UDR1    = Byte;
-
-    if (TimeoutMSRemaining)
-	  TimeoutMSRemaining = COMMAND_TIMEOUT_MS;
 }
 
 /** Receives a byte via the software USART, blocking until data is received.
@@ -154,10 +151,7 @@ uint8_t XPROGTarget_ReceiveByte(void)
 	  XPROGTarget_SetRxMode();
 
 	/* Wait until a byte has been received before reading */
-	while (!(UCSR1A & (1 << RXC1)) && TimeoutMSRemaining);
-	
-	if (TimeoutMSRemaining)
-	  TimeoutMSRemaining = COMMAND_TIMEOUT_MS;
+	while (!(UCSR1A & (1 << RXC1)) && TimeoutTicksRemaining);
 
 	return UDR1;
 }
@@ -176,9 +170,6 @@ void XPROGTarget_SendBreak(void)
 		while (PIND & (1 << 5));
 		while (!(PIND & (1 << 5)));
 	}
-
-    if (TimeoutMSRemaining)
-	  TimeoutMSRemaining = COMMAND_TIMEOUT_MS;
 }
 
 static void XPROGTarget_SetTxMode(void)
@@ -193,9 +184,6 @@ static void XPROGTarget_SetTxMode(void)
 	UCSR1B &= ~(1 << RXEN1);
 	UCSR1B |=  (1 << TXEN1);
 
-    if (TimeoutMSRemaining)
-	  TimeoutMSRemaining = COMMAND_TIMEOUT_MS;
-
 	IsSending = true;
 }
 
@@ -210,9 +198,6 @@ static void XPROGTarget_SetRxMode(void)
 	DDRD   &= ~(1 << 3);
 	PORTD  &= ~(1 << 3);
 
-    if (TimeoutMSRemaining)
-	  TimeoutMSRemaining = COMMAND_TIMEOUT_MS;
-
 	IsSending = false;
 }
 
-- 
GitLab