diff --git a/Projects/AVRISP/Lib/PDIProtocol.c b/Projects/AVRISP/Lib/PDIProtocol.c index c1e7bf2ee6..28bd540716 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 9511bc8781..ea26e4ba60 100644 --- a/Projects/AVRISP/Lib/PDIProtocol.h +++ b/Projects/AVRISP/Lib/PDIProtocol.h @@ -38,6 +38,7 @@ /* Includes: */ #include + #include #include #include "V2Protocol.h" diff --git a/Projects/AVRISP/Lib/PDITarget.c b/Projects/AVRISP/Lib/PDITarget.c index 9a94e9a4e7..d012a1beb2 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 6eebb2b338..37c0e722b4 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.