From 66201a05e9d5793880b27519affff7132f6630ea Mon Sep 17 00:00:00 2001 From: Dean Camera Date: Fri, 11 Dec 2009 04:04:34 +0000 Subject: Fix PDI code - must send NVM enable key least significant byte first, need to make sure Tx and Rx is switched correctly including disabling the output on the Tx line when receiving. --- Projects/AVRISP/Lib/PDIProtocol.c | 12 +++++---- Projects/AVRISP/Lib/PDITarget.c | 54 ++++++++++++++++++++++++++++++--------- Projects/AVRISP/makefile | 2 +- 3 files changed, 50 insertions(+), 18 deletions(-) (limited to 'Projects') diff --git a/Projects/AVRISP/Lib/PDIProtocol.c b/Projects/AVRISP/Lib/PDIProtocol.c index 28bd54071..32a74c586 100644 --- a/Projects/AVRISP/Lib/PDIProtocol.c +++ b/Projects/AVRISP/Lib/PDIProtocol.c @@ -111,18 +111,20 @@ static void PDIProtocol_EnterXPROGMode(void) /* Enable access to the XPROG NVM bus by sending the documented NVM access key to the device */ PDITarget_SendByte(PDI_CMD_KEY); - for (uint8_t i = 0; i < sizeof(PDI_NVMENABLE_KEY); i++) - PDITarget_SendByte(PDI_NVMENABLE_KEY[i]); + for (uint8_t i = sizeof(PDI_NVMENABLE_KEY); i > 0; i--) + PDITarget_SendByte(PDI_NVMENABLE_KEY[i - 1]); /* Poll the STATUS register to check to see if NVM access has been enabled */ - uint8_t NVMAttemptsRemaining = 200; - while (NVMAttemptsRemaining--) + uint8_t NVMAttemptsRemaining = 150; + while (NVMAttemptsRemaining) { _delay_ms(1); - PDITarget_SendByte(PDI_CMD_LDCS | PD_STATUS_REG); + PDITarget_SendByte(PDI_CMD_LDCS | PD_STATUS_REG); if (PDITarget_ReceiveByte() & PDI_STATUS_NVM) break; + + NVMAttemptsRemaining--; } Endpoint_Write_Byte(CMD_XPROG); diff --git a/Projects/AVRISP/Lib/PDITarget.c b/Projects/AVRISP/Lib/PDITarget.c index d012a1beb..22a4d019a 100644 --- a/Projects/AVRISP/Lib/PDITarget.c +++ b/Projects/AVRISP/Lib/PDITarget.c @@ -38,8 +38,9 @@ #define INCLUDE_FROM_PDITARGET_C #include "PDITarget.h" -#if !defined(PDI_VIA_HARDWARE_USART) volatile bool IsSending; + +#if !defined(PDI_VIA_HARDWARE_USART) volatile uint16_t DataBits; volatile uint8_t BitCount; @@ -192,31 +193,60 @@ void PDITarget_DisableTargetPDI(void) void PDITarget_SendByte(uint8_t Byte) { - UCSR1B &= ~(1 << RXEN1); - UCSR1B |= (1 << TXEN1); + /* 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; + } + + /* Wait until there is space in the hardware Tx buffer before writing */ + while (!(UCSR1A & (1 << UDRE1))); UDR1 = Byte; - - while (!(UCSR1A & (1 << TXC1))); - UCSR1A |= (1 << TXC1); } uint8_t PDITarget_ReceiveByte(void) { - UCSR1B &= ~(1 << TXEN1); - UCSR1B |= (1 << RXEN1); + /* 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; + } + + /* Wait until a byte has been received before reading */ while (!(UCSR1A & (1 << RXC1))); - UCSR1A |= (1 << RXC1); - return UDR1; } void PDITarget_SendBreak(void) { - UCSR1B &= ~(1 << RXEN1); - UCSR1B |= (1 << TXEN1); + /* 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; + } + /* Need to do nothing for a full frame to send a BREAK */ for (uint8_t i = 0; i <= BITS_IN_FRAME; i++) { /* Wait for rising edge of clock */ diff --git a/Projects/AVRISP/makefile b/Projects/AVRISP/makefile index 37c0e722b..003eaa57a 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 = XPLAIN # Processor frequency. -- cgit v1.2.3