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
+ /* 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
/* Continuously attempt to synchronize with the target until either the number of attempts specified\r
* by the host has exceeded, or the the device sends back the expected response values */\r
- while (Enter_ISP_Params.SynchLoops-- && (ResponseStatus == STATUS_CMD_FAILED))\r
+ while (Enter_ISP_Params.SynchLoops-- && (ResponseStatus == STATUS_CMD_FAILED) && TimeoutMSRemaining)\r
{\r
uint8_t ResponseBytes[4];\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
\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
+\r
PollAddress = (CurrentAddress & 0xFFFF); \r
} \r
\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
+ /* 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
}\r
}\r
\r
+/** Blocking delay for a given number of milliseconds.\r
+ *\r
+ * \param[in] DelayMS Number of milliseconds to delay for\r
+ */\r
+void ISPProtocol_DelayMS(uint8_t DelayMS)\r
+{\r
+ while (DelayMS-- && TimeoutMSRemaining)\r
+ {\r
+ if (TimeoutMSRemaining)\r
+ TimeoutMSRemaining--;\r
+ \r
+ _delay_ms(1);\r
+ }\r
+}\r
+\r
#endif
\ No newline at end of file