From c6d6bdae0a6fa5604174428787ff3c415ca73fad Mon Sep 17 00:00:00 2001 From: Dean Camera Date: Wed, 12 Oct 2011 05:31:35 +0000 Subject: [PATCH] Added reliability patches to the AVRISP-MKII Clone project's PDI/TPI protocols (thanks to Justin Mattair). --- LUFA/ManPages/ChangeLog.txt | 2 +- Projects/AVRISP-MKII/Lib/XPROG/XMEGANVM.c | 19 ++++++++++++------- Projects/AVRISP-MKII/Lib/XPROG/XPROGTarget.c | 19 +++++++++---------- 3 files changed, 22 insertions(+), 18 deletions(-) diff --git a/LUFA/ManPages/ChangeLog.txt b/LUFA/ManPages/ChangeLog.txt index b3bda78c93..1b3003f80a 100644 --- a/LUFA/ManPages/ChangeLog.txt +++ b/LUFA/ManPages/ChangeLog.txt @@ -24,7 +24,7 @@ * - Core: * - None * - Library Applications: - * - None + * - Added reliability patches to the AVRISP-MKII Clone project's PDI/TPI protocols (thanks to Justin Mattair) * * \section Sec_ChangeLog111009 Version 111009 * New: diff --git a/Projects/AVRISP-MKII/Lib/XPROG/XMEGANVM.c b/Projects/AVRISP-MKII/Lib/XPROG/XMEGANVM.c index e4f1186b05..71fa782220 100644 --- a/Projects/AVRISP-MKII/Lib/XPROG/XMEGANVM.c +++ b/Projects/AVRISP-MKII/Lib/XPROG/XMEGANVM.c @@ -149,13 +149,18 @@ void XMEGANVM_DisablePDI(void) { XMEGANVM_WaitWhileNVMBusBusy(); - /* Clear the RESET key in the RESET PDI register to allow the XMEGA to run */ - XPROGTarget_SendByte(PDI_CMD_STCS | PDI_RESET_REG); - XPROGTarget_SendByte(0x00); - - /* Do it twice to make sure it takes effect (silicon bug?) */ - XPROGTarget_SendByte(PDI_CMD_STCS | PDI_RESET_REG); - XPROGTarget_SendByte(0x00); + /* Clear the RESET key in the RESET PDI register to allow the XMEGA to run - must perform this until the + * change takes effect, as in some cases it takes multiple writes (silicon bug?). + */ + do + { + /* Clear reset register */ + XPROGTarget_SendByte(PDI_CMD_STCS | PDI_RESET_REG); + XPROGTarget_SendByte(0x00); + + /* Read back the reset register, check to see if it took effect */ + XPROGTarget_SendByte(PDI_CMD_LDCS | PDI_RESET_REG); + } while (XPROGTarget_ReceiveByte() != 0x00); XPROGTarget_DisableTargetPDI(); } diff --git a/Projects/AVRISP-MKII/Lib/XPROG/XPROGTarget.c b/Projects/AVRISP-MKII/Lib/XPROG/XPROGTarget.c index 065cd09658..58df785596 100644 --- a/Projects/AVRISP-MKII/Lib/XPROG/XPROGTarget.c +++ b/Projects/AVRISP-MKII/Lib/XPROG/XPROGTarget.c @@ -92,7 +92,8 @@ void XPROGTarget_EnableTargetTPI(void) void XPROGTarget_DisableTargetPDI(void) { /* Switch to Rx mode to ensure that all pending transmissions are complete */ - XPROGTarget_SetRxMode(); + if (IsSending) + XPROGTarget_SetRxMode(); /* Turn off receiver and transmitter of the USART, clear settings */ UCSR1A = ((1 << TXC1) | (1 << RXC1)); @@ -108,7 +109,8 @@ void XPROGTarget_DisableTargetPDI(void) void XPROGTarget_DisableTargetTPI(void) { /* Switch to Rx mode to ensure that all pending transmissions are complete */ - XPROGTarget_SetRxMode(); + if (IsSending) + XPROGTarget_SetRxMode(); /* Turn off receiver and transmitter of the USART, clear settings */ UCSR1A |= (1 << TXC1) | (1 << RXC1); @@ -169,19 +171,16 @@ void XPROGTarget_SendIdle(void) /* Wait for a full cycle of the clock */ while (PIND & (1 << 5)); while (!(PIND & (1 << 5))); + while (PIND & (1 << 5)); } } static void XPROGTarget_SetTxMode(void) { - /* 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))); - } + /* Wait for a full cycle of the clock */ + while (PIND & (1 << 5)); + while (!(PIND & (1 << 5))); + while (PIND & (1 << 5)); PORTD |= (1 << 3); DDRD |= (1 << 3);