AVRISP programmer project now has a more robust timeout system, allowing for a doubli...
[pub/USBasp.git] / Projects / AVRISP-MKII / Lib / ISP / ISPProtocol.c
index 59a77e5..e0eb441 100644 (file)
@@ -62,7 +62,14 @@ void ISPProtocol_EnterISPMode(void)
        uint8_t ResponseStatus = STATUS_CMD_FAILED;\r
        \r
        CurrentAddress = 0;\r
        uint8_t ResponseStatus = STATUS_CMD_FAILED;\r
        \r
        CurrentAddress = 0;\r
+       \r
+       /* Set up the synchronous USART to generate the recovery clock on XCK pin */\r
+       UBRR1  = (F_CPU / 500000UL);\r
+       UCSR1B = (1 << TXEN1);\r
+       UCSR1C = (1 << UMSEL10) | (1 << UPM11) | (1 << USBS1) | (1 << UCSZ11) | (1 << UCSZ10) | (1 << UCPOL1);\r
+       DDRD  |= (1 << 5);\r
 \r
 \r
+       /* Perform execution delay, initialize SPI bus */\r
        ISPProtocol_DelayMS(Enter_ISP_Params.ExecutionDelayMS); \r
        SPI_Init(ISPTarget_GetSPIPrescalerMask() | SPI_SCK_LEAD_RISING | SPI_SAMPLE_LEADING | SPI_MODE_MASTER);\r
 \r
        ISPProtocol_DelayMS(Enter_ISP_Params.ExecutionDelayMS); \r
        SPI_Init(ISPTarget_GetSPIPrescalerMask() | SPI_SCK_LEAD_RISING | SPI_SAMPLE_LEADING | SPI_MODE_MASTER);\r
 \r
@@ -118,6 +125,12 @@ void ISPProtocol_LeaveISPMode(void)
        SPI_ShutDown();\r
        ISPProtocol_DelayMS(Leave_ISP_Params.PostDelayMS);\r
 \r
        SPI_ShutDown();\r
        ISPProtocol_DelayMS(Leave_ISP_Params.PostDelayMS);\r
 \r
+       /* Turn off the synchronous USART to terminate the recovery clock on XCK pin */\r
+       UBRR1  = (F_CPU / 500000UL);\r
+       UCSR1B = (1 << TXEN1);\r
+       UCSR1C = (1 << UMSEL10) | (1 << UPM11) | (1 << USBS1) | (1 << UCSZ11) | (1 << UCSZ10) | (1 << UCPOL1);\r
+       DDRD  &= ~(1 << 5);\r
+\r
        Endpoint_Write_Byte(CMD_LEAVE_PROGMODE_ISP);\r
        Endpoint_Write_Byte(STATUS_CMD_OK);\r
        Endpoint_ClearIN();\r
        Endpoint_Write_Byte(CMD_LEAVE_PROGMODE_ISP);\r
        Endpoint_Write_Byte(STATUS_CMD_OK);\r
        Endpoint_ClearIN();\r
@@ -198,14 +211,15 @@ void ISPProtocol_ProgramMemory(uint8_t V2Command)
                        \r
                        /* AVR FLASH addressing requires us to modify the write command based on if we are writing a high\r
                         * or low byte at the current word address */\r
                        \r
                        /* AVR FLASH addressing requires us to modify the write command based on if we are writing a high\r
                         * or low byte at the current word address */\r
-                       Write_Memory_Params.ProgrammingCommands[0] ^= READ_WRITE_HIGH_BYTE_MASK;\r
+                       if (V2Command == CMD_PROGRAM_FLASH_ISP)\r
+                         Write_Memory_Params.ProgrammingCommands[0] ^= READ_WRITE_HIGH_BYTE_MASK;\r
 \r
                        /* Check to see the write completion method, to see if we have a valid polling address */\r
                        if (!(PollAddress) && (ByteToWrite != PollValue))\r
                        {\r
                                if (IsOddByte && (V2Command == CMD_PROGRAM_FLASH_ISP))\r
                                  Write_Memory_Params.ProgrammingCommands[2] |= READ_WRITE_HIGH_BYTE_MASK;\r
 \r
                        /* Check to see the write completion method, to see if we have a valid polling address */\r
                        if (!(PollAddress) && (ByteToWrite != PollValue))\r
                        {\r
                                if (IsOddByte && (V2Command == CMD_PROGRAM_FLASH_ISP))\r
                                  Write_Memory_Params.ProgrammingCommands[2] |= READ_WRITE_HIGH_BYTE_MASK;\r
-                                 \r
+\r
                                PollAddress = (CurrentAddress & 0xFFFF);                                \r
                        }               \r
 \r
                                PollAddress = (CurrentAddress & 0xFFFF);                                \r
                        }               \r
 \r
@@ -239,17 +253,17 @@ void ISPProtocol_ProgramMemory(uint8_t V2Command)
                {\r
                        bool    IsOddByte   = (CurrentByte & 0x01);\r
                        uint8_t ByteToWrite = *(NextWriteByte++);\r
                {\r
                        bool    IsOddByte   = (CurrentByte & 0x01);\r
                        uint8_t ByteToWrite = *(NextWriteByte++);\r
-               \r
-                       if (IsOddByte && (V2Command == CMD_READ_FLASH_ISP))\r
-                         Write_Memory_Params.ProgrammingCommands[0] |=  READ_WRITE_HIGH_BYTE_MASK;\r
-                       else\r
-                         Write_Memory_Params.ProgrammingCommands[0] &= ~READ_WRITE_HIGH_BYTE_MASK;                     \r
                          \r
                        SPI_SendByte(Write_Memory_Params.ProgrammingCommands[0]);\r
                        SPI_SendByte(CurrentAddress >> 8);\r
                        SPI_SendByte(CurrentAddress & 0xFF);\r
                        SPI_SendByte(ByteToWrite);\r
                        \r
                          \r
                        SPI_SendByte(Write_Memory_Params.ProgrammingCommands[0]);\r
                        SPI_SendByte(CurrentAddress >> 8);\r
                        SPI_SendByte(CurrentAddress & 0xFF);\r
                        SPI_SendByte(ByteToWrite);\r
                        \r
+                       /* AVR FLASH addressing requires us to modify the write command based on if we are writing a high\r
+                        * or low byte at the current word address */\r
+                       if (V2Command == CMD_PROGRAM_FLASH_ISP)\r
+                         Write_Memory_Params.ProgrammingCommands[0] ^= READ_WRITE_HIGH_BYTE_MASK;\r
+\r
                        if (ByteToWrite != PollValue)\r
                        {\r
                                if (IsOddByte && (V2Command == CMD_PROGRAM_FLASH_ISP))\r
                        if (ByteToWrite != PollValue)\r
                        {\r
                                if (IsOddByte && (V2Command == CMD_PROGRAM_FLASH_ISP))\r