Fix AVRISP PDI protocol - make sure inverted masks have the appropriate parenthesis around them, make sure the BREAK command for the hardware USART has 12 clock cycles exactly. Poll NVM Enable bit in the target's STATUS PDI register with a timeout, as it is not set immediately.

pull/1469/head
Dean Camera 15 years ago
parent 42cfd15793
commit 7e5966c1a8

@ -99,15 +99,13 @@ void PDIProtocol_XPROG_Command(void)
/** Handler for the XPROG ENTER_PROGMODE command to establish a PDI connection with the attached device. */
static void PDIProtocol_EnterXPROGMode(void)
{
uint8_t ReturnStatus = XPRG_ERR_OK;
Endpoint_ClearOUT();
Endpoint_SetEndpointDirection(ENDPOINT_DIR_IN);
/* Enable PDI programming mode with the attached target */
PDITarget_EnableTargetPDI();
/* Store the RESET ket into the RESET PDI register to complete the handshake */
/* Store the RESET key into the RESET PDI register to keep the XMEGA in reset */
PDITarget_SendByte(PDI_CMD_STCS | PD_RESET_REG);
PDITarget_SendByte(PDI_RESET_KEY);
@ -116,14 +114,20 @@ static void PDIProtocol_EnterXPROGMode(void)
for (uint8_t i = 0; i < sizeof(PDI_NVMENABLE_KEY); i++)
PDITarget_SendByte(PDI_NVMENABLE_KEY[i]);
/* Read out the STATUS register to check that NVM access was successfully enabled */
PDITarget_SendByte(PDI_CMD_LDCS | PD_STATUS_REG);
if (!(PDITarget_ReceiveByte() & PDI_STATUS_NVM))
ReturnStatus = XPRG_ERR_FAILED;
/* Poll the STATUS register to check to see if NVM access has been enabled */
uint8_t NVMAttemptsRemaining = 200;
while (NVMAttemptsRemaining--)
{
_delay_ms(1);
PDITarget_SendByte(PDI_CMD_LDCS | PD_STATUS_REG);
if (PDITarget_ReceiveByte() & PDI_STATUS_NVM)
break;
}
Endpoint_Write_Byte(CMD_XPROG);
Endpoint_Write_Byte(XPRG_CMD_ENTER_PROGMODE);
Endpoint_Write_Byte(ReturnStatus);
Endpoint_Write_Byte(NVMAttemptsRemaining ? XPRG_ERR_OK : XPRG_ERR_FAILED);
Endpoint_ClearIN();
}
@ -135,6 +139,10 @@ static void PDIProtocol_LeaveXPROGMode(void)
Endpoint_ClearOUT();
Endpoint_SetEndpointDirection(ENDPOINT_DIR_IN);
/* Clear the RESET key into the RESET PDI register to allow the XMEGA to run */
PDITarget_SendByte(PDI_CMD_STCS | PD_RESET_REG);
PDITarget_SendByte(0x00);
PDITarget_DisableTargetPDI();
Endpoint_Write_Byte(CMD_XPROG);

@ -38,6 +38,7 @@
/* Includes: */
#include <avr/io.h>
#include <util/delay.h>
#include <stdio.h>
#include "V2Protocol.h"

@ -172,9 +172,9 @@ void PDITarget_EnableTargetPDI(void)
/* Set up the synchronous USART for XMEGA communications -
8 data bits, even parity, 2 stop bits */
UBRR1 = 10;
UCSR1B = (1 << TXEN1);
UCSR1C = (1 << UMSEL10) | (1 << UPM11) | (1 << USBS1) | (1 << UCSZ11) | (1 << UCSZ10) | (1 << UCPOL1);
/* Send two BREAKs of 12 bits each to enable PDI interface (need at least 16 idle bits) */
PDITarget_SendBreak();
PDITarget_SendBreak();
}
@ -186,7 +186,7 @@ void PDITarget_DisableTargetPDI(void)
UCSR1C = 0;
/* Set all USART lines as input, tristate */
DDRD &= ~(1 << 5) | (1 << 3);
DDRD &= ~((1 << 5) | (1 << 3));
PORTD &= ~((1 << 5) | (1 << 3) | (1 << 2));
}
@ -215,11 +215,14 @@ uint8_t PDITarget_ReceiveByte(void)
void PDITarget_SendBreak(void)
{
UCSR1B &= ~(1 << RXEN1);
UCSR1B |= (1 << TXEN1);
UCSR1B |= (1 << TXEN1);
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 */
while (PIND & (1 << 5));
/* Wait for falling edge of clock */
while (!(PIND & (1 << 5)));
}
}

@ -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 = USBKEY
BOARD = XPLAIN
# Processor frequency.

Loading…
Cancel
Save