From db73b11244c2c5dc444f3c459d6823be8d1fe655 Mon Sep 17 00:00:00 2001
From: Dean Camera <dean@fourwalledcubicle.com>
Date: Fri, 7 Oct 2011 04:40:56 +0000
Subject: [PATCH] Added reliability patches to the AVRISP-MKII Clone project's
 ISP and PDI/TPI protocols (thanks to Justin Mattair).

---
 LUFA/ManPages/ChangeLog.txt                  |  1 +
 Projects/AVRISP-MKII/Lib/ISP/ISPProtocol.c   |  5 ++++-
 Projects/AVRISP-MKII/Lib/XPROG/XPROGTarget.c | 11 ++++++++---
 3 files changed, 13 insertions(+), 4 deletions(-)

diff --git a/LUFA/ManPages/ChangeLog.txt b/LUFA/ManPages/ChangeLog.txt
index d3ff6858e..c07f10a90 100644
--- a/LUFA/ManPages/ChangeLog.txt
+++ b/LUFA/ManPages/ChangeLog.txt
@@ -68,6 +68,7 @@
   *   - Updated all host mode demos and projects to use the EVENT_USB_Host_DeviceEnumerationComplete() event callback for device configuration
   *     instead of manual host state machine manipulations in the main application task
   *   - Changed the reports in the GenericHID device demos to control the board LEDs, to reduce user confusion over the callback routines
+  *   - Added reliability patches to the AVRISP-MKII Clone project's ISP and PDI/TPI protocols (thanks to Justin Mattair)
   *
   *  <b>Fixed:</b>
   *  - Core:
diff --git a/Projects/AVRISP-MKII/Lib/ISP/ISPProtocol.c b/Projects/AVRISP-MKII/Lib/ISP/ISPProtocol.c
index e9e92f99a..797fa3655 100644
--- a/Projects/AVRISP-MKII/Lib/ISP/ISPProtocol.c
+++ b/Projects/AVRISP-MKII/Lib/ISP/ISPProtocol.c
@@ -69,10 +69,11 @@ void ISPProtocol_EnterISPMode(void)
 	ISPTarget_EnableTargetISP();
 
 	ISPTarget_ChangeTargetResetLine(true);
+	ISPProtocol_DelayMS(Enter_ISP_Params.PinStabDelayMS);
 
 	/* 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_OK) && !(TimeoutExpired))
+	while (Enter_ISP_Params.SynchLoops-- && !(TimeoutExpired))
 	{
 		uint8_t ResponseBytes[4];
 
@@ -86,12 +87,14 @@ void ISPProtocol_EnterISPMode(void)
 		if (!(Enter_ISP_Params.PollIndex) || (ResponseBytes[Enter_ISP_Params.PollIndex - 1] == Enter_ISP_Params.PollValue))
 		{
 			ResponseStatus = STATUS_CMD_OK;
+			break;
 		}
 		else
 		{
 			ISPTarget_ChangeTargetResetLine(false);
 			ISPProtocol_DelayMS(Enter_ISP_Params.PinStabDelayMS);
 			ISPTarget_ChangeTargetResetLine(true);
+			ISPProtocol_DelayMS(Enter_ISP_Params.PinStabDelayMS);
 		}
 	}
 
diff --git a/Projects/AVRISP-MKII/Lib/XPROG/XPROGTarget.c b/Projects/AVRISP-MKII/Lib/XPROG/XPROGTarget.c
index af0cc0106..065cd0965 100644
--- a/Projects/AVRISP-MKII/Lib/XPROG/XPROGTarget.c
+++ b/Projects/AVRISP-MKII/Lib/XPROG/XPROGTarget.c
@@ -174,9 +174,14 @@ void XPROGTarget_SendIdle(void)
 
 static void XPROGTarget_SetTxMode(void)
 {
-	/* Wait for a full cycle of the clock */
-	while (PIND & (1 << 5));
-	while (!(PIND & (1 << 5)));
+    /* Need to do nothing for a full frame to send a BREAK - only one cycle should be needed, however
+	 * there are reports that sometimes the interface will get stuck in some environments. */
+    for (uint8_t i = 0; i < BITS_IN_USART_FRAME; i++)
+    {
+        /* Wait for a full cycle of the clock */
+        while (PIND & (1 << 5));
+        while (!(PIND & (1 << 5)));
+    }
 
 	PORTD  |=  (1 << 3);
 	DDRD   |=  (1 << 3);
-- 
GitLab