From b1dbd92c32022c2ec1601f6a6e51c5714a69c56c Mon Sep 17 00:00:00 2001 From: Dean Camera Date: Tue, 29 Dec 2009 14:43:03 +0000 Subject: [PATCH] Fixed AVRISP PDI race condition where the guard time between direction changes could be interpreted as a start bit. Fixed TPI interface lines not being changed correctly when in bit-banged TPI mode. --- LUFA/ManPages/ChangeLog.txt | 3 + Projects/AVRISP-MKII/Lib/XPROG/XMEGANVM.h | 2 +- .../AVRISP-MKII/Lib/XPROG/XPROGProtocol.h | 1 + Projects/AVRISP-MKII/Lib/XPROG/XPROGTarget.c | 137 ++++++++++-------- Projects/AVRISP-MKII/Lib/XPROG/XPROGTarget.h | 6 + 5 files changed, 86 insertions(+), 63 deletions(-) diff --git a/LUFA/ManPages/ChangeLog.txt b/LUFA/ManPages/ChangeLog.txt index 52c78f0015..c206ad04d4 100644 --- a/LUFA/ManPages/ChangeLog.txt +++ b/LUFA/ManPages/ChangeLog.txt @@ -16,9 +16,12 @@ * Changed: * - Slowed down bit-banged PDI programming in the AVRISP project slightly to prevent transmission errors * - Renamed the AVRISP project folder to AVRISP-MKII to reduce confusion + * - Renamed the RESET_LINE_* makefile tokens in the AVRISP MKII Project to AUX_LINE_*, as they are not always used for target + * reset * * Fixed: * - Fixed AVRISP project not able to enter programming mode when ISP protocol is used + * - Fixed AVRISP PDI race condition where the guard time between direction changes could be interpreted as a start bit * * \section Sec_ChangeLog091223 Version 091223 * diff --git a/Projects/AVRISP-MKII/Lib/XPROG/XMEGANVM.h b/Projects/AVRISP-MKII/Lib/XPROG/XMEGANVM.h index 608f5ab794..d2e2a25169 100644 --- a/Projects/AVRISP-MKII/Lib/XPROG/XMEGANVM.h +++ b/Projects/AVRISP-MKII/Lib/XPROG/XMEGANVM.h @@ -33,7 +33,7 @@ * Header file for XMEGANVM.c. */ -#ifndef _XMEGA_NVM__ +#ifndef _XMEGA_NVM_ #define _XMEGA_NVM_ /* Includes: */ diff --git a/Projects/AVRISP-MKII/Lib/XPROG/XPROGProtocol.h b/Projects/AVRISP-MKII/Lib/XPROG/XPROGProtocol.h index 4bb600910f..7dc6af5385 100644 --- a/Projects/AVRISP-MKII/Lib/XPROG/XPROGProtocol.h +++ b/Projects/AVRISP-MKII/Lib/XPROG/XPROGProtocol.h @@ -113,6 +113,7 @@ extern uint16_t XPROG_Param_EEPageSize; extern uint8_t XPROG_Param_NVMCSRRegAddr; extern uint8_t XPROG_Param_NVMCMDRegAddr; + extern uint8_t XPROG_SelectedProtocol; /* Function Prototypes: */ void XPROGProtocol_SetMode(void); diff --git a/Projects/AVRISP-MKII/Lib/XPROG/XPROGTarget.c b/Projects/AVRISP-MKII/Lib/XPROG/XPROGTarget.c index 856b489039..c1f1a63161 100644 --- a/Projects/AVRISP-MKII/Lib/XPROG/XPROGTarget.c +++ b/Projects/AVRISP-MKII/Lib/XPROG/XPROGTarget.c @@ -279,33 +279,16 @@ void XPROGTarget_DisableTargetTPI(void) */ void XPROGTarget_SendByte(const uint8_t Byte) { -#if defined(XPROG_VIA_HARDWARE_USART) /* Switch to Tx mode if currently in Rx mode */ if (!(IsSending)) - { - PORTD |= (1 << 3); - DDRD |= (1 << 3); - - UCSR1B |= (1 << TXEN1); - UCSR1B &= ~(1 << RXEN1); - - IsSending = true; - } - + XPROGTarget_SetTxMode(); + +#if defined(XPROG_VIA_HARDWARE_USART) /* Wait until there is space in the hardware Tx buffer before writing */ while (!(UCSR1A & (1 << UDRE1))); UCSR1A |= (1 << TXC1); UDR1 = Byte; #else - /* Switch to Tx mode if currently in Rx mode */ - if (!(IsSending)) - { - BITBANG_PDIDATA_PORT |= BITBANG_PDIDATA_MASK; - BITBANG_PDIDATA_DDR |= BITBANG_PDIDATA_MASK; - - IsSending = true; - } - /* Calculate the new USART frame data here while while we wait for a previous byte (if any) to finish sending */ uint16_t NewUSARTData = ((1 << 11) | (1 << 10) | (0 << 9) | ((uint16_t)Byte << 1) | (0 << 0)); @@ -332,37 +315,15 @@ void XPROGTarget_SendByte(const uint8_t Byte) */ uint8_t XPROGTarget_ReceiveByte(void) { -#if defined(XPROG_VIA_HARDWARE_USART) /* Switch to Rx mode if currently in Tx mode */ if (IsSending) - { - while (!(UCSR1A & (1 << TXC1))); - UCSR1A |= (1 << TXC1); - - UCSR1B &= ~(1 << TXEN1); - UCSR1B |= (1 << RXEN1); - - DDRD &= ~(1 << 3); - PORTD &= ~(1 << 3); - - IsSending = false; - } + XPROGTarget_SetRxMode(); +#if defined(XPROG_VIA_HARDWARE_USART) /* Wait until a byte has been received before reading */ while (!(UCSR1A & (1 << RXC1)) && TimeoutMSRemaining); return UDR1; #else - /* Switch to Rx mode if currently in Tx mode */ - if (IsSending) - { - while (SoftUSART_BitCount); - - BITBANG_PDIDATA_DDR &= ~BITBANG_PDIDATA_MASK; - BITBANG_PDIDATA_PORT &= ~BITBANG_PDIDATA_MASK; - - IsSending = false; - } - /* Wait until a byte has been received before reading */ SoftUSART_BitCount = BITS_IN_USART_FRAME; while (SoftUSART_BitCount && TimeoutMSRemaining); @@ -375,19 +336,11 @@ uint8_t XPROGTarget_ReceiveByte(void) /** Sends a BREAK via the USART to the attached target, consisting of a full frame of idle bits. */ void XPROGTarget_SendBreak(void) { -#if defined(XPROG_VIA_HARDWARE_USART) /* Switch to Tx mode if currently in Rx mode */ if (!(IsSending)) - { - PORTD |= (1 << 3); - DDRD |= (1 << 3); - - UCSR1B &= ~(1 << RXEN1); - UCSR1B |= (1 << TXEN1); - - IsSending = true; - } + XPROGTarget_SetTxMode(); +#if defined(XPROG_VIA_HARDWARE_USART) /* Need to do nothing for a full frame to send a BREAK */ for (uint8_t i = 0; i < BITS_IN_USART_FRAME; i++) { @@ -396,21 +349,81 @@ void XPROGTarget_SendBreak(void) while (!(PIND & (1 << 5))); } #else - /* Switch to Tx mode if currently in Rx mode */ - if (!(IsSending)) + while (SoftUSART_BitCount); + + /* Need to do nothing for a full frame to send a BREAK */ + SoftUSART_Data = 0x0FFF; + SoftUSART_BitCount = BITS_IN_USART_FRAME; +#endif +} + +static void XPROGTarget_SetTxMode(void) +{ +#if defined(XPROG_VIA_HARDWARE_USART) + /* Wait for a full cycle of the clock */ + while (PIND & (1 << 5)); + while (!(PIND & (1 << 5))); + + PORTD |= (1 << 3); + DDRD |= (1 << 3); + + UCSR1B &= ~(1 << RXEN1); + UCSR1B |= (1 << TXEN1); + + IsSending = true; +#else + while (SoftUSART_BitCount); + + /* Wait for a full cycle of the clock */ + SoftUSART_Data = 0x0001; + SoftUSART_BitCount = 1; + while (SoftUSART_BitCount); + + if (XPROG_SelectedProtocol == XPRG_PROTOCOL_PDI) { BITBANG_PDIDATA_PORT |= BITBANG_PDIDATA_MASK; BITBANG_PDIDATA_DDR |= BITBANG_PDIDATA_MASK; - - IsSending = true; } - + else + { + BITBANG_TPIDATA_PORT |= BITBANG_TPIDATA_MASK; + BITBANG_TPIDATA_DDR |= BITBANG_TPIDATA_MASK; + } +#endif + + IsSending = true; +} + +static void XPROGTarget_SetRxMode(void) +{ +#if defined(XPROG_VIA_HARDWARE_USART) + while (!(UCSR1A & (1 << TXC1))); + UCSR1A |= (1 << TXC1); + + UCSR1B &= ~(1 << TXEN1); + UCSR1B |= (1 << RXEN1); + + DDRD &= ~(1 << 3); + PORTD &= ~(1 << 3); +#else while (SoftUSART_BitCount); - /* Need to do nothing for a full frame to send a BREAK */ - SoftUSART_Data = 0x0FFF; - SoftUSART_BitCount = BITS_IN_USART_FRAME; + if (XPROG_SelectedProtocol == XPRG_PROTOCOL_PDI) + { + BITBANG_PDIDATA_DDR &= ~BITBANG_PDIDATA_MASK; + BITBANG_PDIDATA_PORT &= ~BITBANG_PDIDATA_MASK; + } + else + { + BITBANG_TPIDATA_DDR &= ~BITBANG_TPIDATA_MASK; + BITBANG_TPIDATA_PORT &= ~BITBANG_TPIDATA_MASK; + } + + /* Wait until DATA line has been pulled up to idle by the target */ + while (!(BITBANG_PDIDATA_PIN & BITBANG_PDIDATA_MASK)); #endif + + IsSending = false; } #endif diff --git a/Projects/AVRISP-MKII/Lib/XPROG/XPROGTarget.h b/Projects/AVRISP-MKII/Lib/XPROG/XPROGTarget.h index 3bbf454bef..dab41f316c 100644 --- a/Projects/AVRISP-MKII/Lib/XPROG/XPROGTarget.h +++ b/Projects/AVRISP-MKII/Lib/XPROG/XPROGTarget.h @@ -44,6 +44,7 @@ #include #include "../V2Protocol.h" + #include "XPROGProtocol.h" /* Preprocessor Checks: */ #if ((BOARD == BOARD_XPLAIN) || (BOARD == BOARD_XPLAIN_REV1)) @@ -141,5 +142,10 @@ uint8_t XPROGTarget_ReceiveByte(void); void XPROGTarget_SendBreak(void); bool XPROGTarget_WaitWhileNVMBusBusy(void); + + #if defined(INCLUDE_FROM_XPROGTARGET_C) + static void XPROGTarget_SetTxMode(void); + static void XPROGTarget_SetRxMode(void); + #endif #endif