Fix AVRISP PDI protocol - make sure inverted masks have the appropriate parenthesis...
authorDean Camera <dean@fourwalledcubicle.com>
Fri, 11 Dec 2009 00:19:25 +0000 (00:19 +0000)
committerDean Camera <dean@fourwalledcubicle.com>
Fri, 11 Dec 2009 00:19:25 +0000 (00:19 +0000)
Projects/AVRISP/Lib/PDIProtocol.c
Projects/AVRISP/Lib/PDIProtocol.h
Projects/AVRISP/Lib/PDITarget.c
Projects/AVRISP/makefile

index c1e7bf2..28bd540 100644 (file)
@@ -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. */\r
 static void PDIProtocol_EnterXPROGMode(void)\r
 {\r
-       uint8_t ReturnStatus = XPRG_ERR_OK;\r
-\r
        Endpoint_ClearOUT();\r
        Endpoint_SetEndpointDirection(ENDPOINT_DIR_IN);\r
        \r
        /* Enable PDI programming mode with the attached target */\r
        PDITarget_EnableTargetPDI();\r
        \r
-       /* Store the RESET ket into the RESET PDI register to complete the handshake */\r
+       /* Store the RESET key into the RESET PDI register to keep the XMEGA in reset */\r
        PDITarget_SendByte(PDI_CMD_STCS | PD_RESET_REG);        \r
        PDITarget_SendByte(PDI_RESET_KEY);\r
 \r
@@ -116,14 +114,20 @@ static void PDIProtocol_EnterXPROGMode(void)
        for (uint8_t i = 0; i < sizeof(PDI_NVMENABLE_KEY); i++)\r
          PDITarget_SendByte(PDI_NVMENABLE_KEY[i]);\r
 \r
-       /* Read out the STATUS register to check that NVM access was successfully enabled */\r
-       PDITarget_SendByte(PDI_CMD_LDCS | PD_STATUS_REG);       \r
-       if (!(PDITarget_ReceiveByte() & PDI_STATUS_NVM))\r
-         ReturnStatus = XPRG_ERR_FAILED;\r
+       /* Poll the STATUS register to check to see if NVM access has been enabled */\r
+       uint8_t NVMAttemptsRemaining = 200;\r
+       while (NVMAttemptsRemaining--)\r
+       {\r
+               _delay_ms(1);\r
+               PDITarget_SendByte(PDI_CMD_LDCS | PD_STATUS_REG);\r
+\r
+               if (PDITarget_ReceiveByte() & PDI_STATUS_NVM)\r
+                 break;\r
+       }\r
        \r
        Endpoint_Write_Byte(CMD_XPROG);\r
        Endpoint_Write_Byte(XPRG_CMD_ENTER_PROGMODE);\r
-       Endpoint_Write_Byte(ReturnStatus);\r
+       Endpoint_Write_Byte(NVMAttemptsRemaining ? XPRG_ERR_OK : XPRG_ERR_FAILED);\r
        Endpoint_ClearIN();\r
 }\r
 \r
@@ -135,6 +139,10 @@ static void PDIProtocol_LeaveXPROGMode(void)
        Endpoint_ClearOUT();\r
        Endpoint_SetEndpointDirection(ENDPOINT_DIR_IN);\r
        \r
+       /* Clear the RESET key into the RESET PDI register to allow the XMEGA to run */\r
+       PDITarget_SendByte(PDI_CMD_STCS | PD_RESET_REG);        \r
+       PDITarget_SendByte(0x00);\r
+\r
        PDITarget_DisableTargetPDI();\r
 \r
        Endpoint_Write_Byte(CMD_XPROG);\r
index 9511bc8..ea26e4b 100644 (file)
@@ -38,6 +38,7 @@
 \r
        /* Includes: */\r
                #include <avr/io.h>\r
+               #include <util/delay.h>\r
                #include <stdio.h>\r
        \r
                #include "V2Protocol.h"\r
index 9a94e9a..d012a1b 100644 (file)
@@ -172,9 +172,9 @@ void PDITarget_EnableTargetPDI(void)
        /* Set up the synchronous USART for XMEGA communications - \r
           8 data bits, even parity, 2 stop bits */\r
        UBRR1  = 10;\r
-       UCSR1B = (1 << TXEN1);\r
        UCSR1C = (1 << UMSEL10) | (1 << UPM11) | (1 << USBS1) | (1 << UCSZ11) | (1 << UCSZ10) | (1 << UCPOL1);\r
 \r
+       /* Send two BREAKs of 12 bits each to enable PDI interface (need at least 16 idle bits) */\r
        PDITarget_SendBreak();\r
        PDITarget_SendBreak();\r
 }\r
@@ -186,7 +186,7 @@ void PDITarget_DisableTargetPDI(void)
        UCSR1C = 0;\r
 \r
        /* Set all USART lines as input, tristate */\r
-       DDRD  &= ~(1 << 5) | (1 << 3);\r
+       DDRD  &= ~((1 << 5) | (1 << 3));\r
        PORTD &= ~((1 << 5) | (1 << 3) | (1 << 2));\r
 }\r
 \r
@@ -215,11 +215,14 @@ uint8_t PDITarget_ReceiveByte(void)
 void PDITarget_SendBreak(void)\r
 {\r
        UCSR1B &= ~(1 << RXEN1);\r
-       UCSR1B |= (1 << TXEN1);\r
+       UCSR1B |=  (1 << TXEN1);\r
 \r
-       for (uint8_t i = 0; i < BITS_IN_FRAME; i++)\r
+       for (uint8_t i = 0; i <= BITS_IN_FRAME; i++)\r
        {\r
+               /* Wait for rising edge of clock */\r
                while (PIND & (1 << 5));\r
+               \r
+               /* Wait for falling edge of clock */\r
                while (!(PIND & (1 << 5)));\r
        }\r
 }\r
index 6eebb2b..37c0e72 100644 (file)
@@ -66,7 +66,7 @@ MCU = at90usb1287
 # Target board (see library "Board Types" documentation, USER or blank for projects not requiring\r
 # LUFA board drivers). If USER is selected, put custom board drivers in a directory called \r
 # "Board" inside the application directory.\r
-BOARD  = USBKEY\r
+BOARD  = XPLAIN\r
 \r
 \r
 # Processor frequency.\r