aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDean Camera <dean@fourwalledcubicle.com>2009-12-11 00:19:25 +0000
committerDean Camera <dean@fourwalledcubicle.com>2009-12-11 00:19:25 +0000
commit7e5966c1a88bf670c2f4962e8a52fcfc3528e82a (patch)
tree306b0ada4c354cfff19a9e502cd93e5a70a56399
parent42cfd157936571c70b6ba0be48fbda1ab7b450a1 (diff)
downloadlufa-7e5966c1a88bf670c2f4962e8a52fcfc3528e82a.tar.gz
lufa-7e5966c1a88bf670c2f4962e8a52fcfc3528e82a.tar.bz2
lufa-7e5966c1a88bf670c2f4962e8a52fcfc3528e82a.zip
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.
-rw-r--r--Projects/AVRISP/Lib/PDIProtocol.c24
-rw-r--r--Projects/AVRISP/Lib/PDIProtocol.h1
-rw-r--r--Projects/AVRISP/Lib/PDITarget.c11
-rw-r--r--Projects/AVRISP/makefile2
4 files changed, 25 insertions, 13 deletions
diff --git a/Projects/AVRISP/Lib/PDIProtocol.c b/Projects/AVRISP/Lib/PDIProtocol.c
index c1e7bf2ee..28bd54071 100644
--- a/Projects/AVRISP/Lib/PDIProtocol.c
+++ b/Projects/AVRISP/Lib/PDIProtocol.c
@@ -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);
diff --git a/Projects/AVRISP/Lib/PDIProtocol.h b/Projects/AVRISP/Lib/PDIProtocol.h
index 9511bc878..ea26e4ba6 100644
--- a/Projects/AVRISP/Lib/PDIProtocol.h
+++ b/Projects/AVRISP/Lib/PDIProtocol.h
@@ -38,6 +38,7 @@
/* Includes: */
#include <avr/io.h>
+ #include <util/delay.h>
#include <stdio.h>
#include "V2Protocol.h"
diff --git a/Projects/AVRISP/Lib/PDITarget.c b/Projects/AVRISP/Lib/PDITarget.c
index 9a94e9a4e..d012a1beb 100644
--- a/Projects/AVRISP/Lib/PDITarget.c
+++ b/Projects/AVRISP/Lib/PDITarget.c
@@ -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)));
}
}
diff --git a/Projects/AVRISP/makefile b/Projects/AVRISP/makefile
index 6eebb2b33..37c0e722b 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 = USBKEY
+BOARD = XPLAIN
# Processor frequency.