Commit 7e5966c1 authored by Dean Camera's avatar Dean Camera
Browse files

Fix AVRISP PDI protocol - make sure inverted masks have the appropriate...

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.
parent 42cfd157
......@@ -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 */
/* 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))
ReturnStatus = XPRG_ERR_FAILED;
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));
}
......@@ -217,9 +217,12 @@ void PDITarget_SendBreak(void)
UCSR1B &= ~(1 << RXEN1);
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.
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment