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.

pull/1469/head
Dean Camera 15 years ago
parent 7e5966c1a8
commit 66201a05e9

@ -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 */ /* Enable access to the XPROG NVM bus by sending the documented NVM access key to the device */
PDITarget_SendByte(PDI_CMD_KEY); PDITarget_SendByte(PDI_CMD_KEY);
for (uint8_t i = 0; i < sizeof(PDI_NVMENABLE_KEY); i++) for (uint8_t i = sizeof(PDI_NVMENABLE_KEY); i > 0; i--)
PDITarget_SendByte(PDI_NVMENABLE_KEY[i]); PDITarget_SendByte(PDI_NVMENABLE_KEY[i - 1]);
/* Poll the STATUS register to check to see if NVM access has been enabled */ /* Poll the STATUS register to check to see if NVM access has been enabled */
uint8_t NVMAttemptsRemaining = 200; uint8_t NVMAttemptsRemaining = 150;
while (NVMAttemptsRemaining--) while (NVMAttemptsRemaining)
{ {
_delay_ms(1); _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) if (PDITarget_ReceiveByte() & PDI_STATUS_NVM)
break; break;
NVMAttemptsRemaining--;
} }
Endpoint_Write_Byte(CMD_XPROG); Endpoint_Write_Byte(CMD_XPROG);

@ -38,8 +38,9 @@
#define INCLUDE_FROM_PDITARGET_C #define INCLUDE_FROM_PDITARGET_C
#include "PDITarget.h" #include "PDITarget.h"
#if !defined(PDI_VIA_HARDWARE_USART)
volatile bool IsSending; volatile bool IsSending;
#if !defined(PDI_VIA_HARDWARE_USART)
volatile uint16_t DataBits; volatile uint16_t DataBits;
volatile uint8_t BitCount; volatile uint8_t BitCount;
@ -192,31 +193,60 @@ void PDITarget_DisableTargetPDI(void)
void PDITarget_SendByte(uint8_t Byte) void PDITarget_SendByte(uint8_t Byte)
{ {
UCSR1B &= ~(1 << RXEN1); /* Switch to Tx mode if currently in Rx mode */
UCSR1B |= (1 << TXEN1); 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; UDR1 = Byte;
while (!(UCSR1A & (1 << TXC1)));
UCSR1A |= (1 << TXC1);
} }
uint8_t PDITarget_ReceiveByte(void) uint8_t PDITarget_ReceiveByte(void)
{ {
UCSR1B &= ~(1 << TXEN1); /* Switch to Rx mode if currently in Tx mode */
UCSR1B |= (1 << RXEN1); 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))); while (!(UCSR1A & (1 << RXC1)));
UCSR1A |= (1 << RXC1);
return UDR1; return UDR1;
} }
void PDITarget_SendBreak(void) void PDITarget_SendBreak(void)
{ {
UCSR1B &= ~(1 << RXEN1); /* Switch to Tx mode if currently in Rx mode */
UCSR1B |= (1 << TXEN1); 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++) for (uint8_t i = 0; i <= BITS_IN_FRAME; i++)
{ {
/* Wait for rising edge of clock */ /* Wait for rising edge of clock */

@ -66,7 +66,7 @@ MCU = at90usb1287
# Target board (see library "Board Types" documentation, USER or blank for projects not requiring # 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 # LUFA board drivers). If USER is selected, put custom board drivers in a directory called
# "Board" inside the application directory. # "Board" inside the application directory.
BOARD = XPLAIN BOARD = XPLAIN
# Processor frequency. # Processor frequency.

Loading…
Cancel
Save