X-Git-Url: http://git.linex4red.de/pub/USBasp.git/blobdiff_plain/60fd0ff418566d85224f9841037ba01b77acc0d8..28f1ac81176bbcd9fd13d94e61323522a5279d27:/Projects/AVRISP-MKII/Lib/ISP/ISPProtocol.c diff --git a/Projects/AVRISP-MKII/Lib/ISP/ISPProtocol.c b/Projects/AVRISP-MKII/Lib/ISP/ISPProtocol.c index 59a77e575..9d0a26c33 100644 --- a/Projects/AVRISP-MKII/Lib/ISP/ISPProtocol.c +++ b/Projects/AVRISP-MKII/Lib/ISP/ISPProtocol.c @@ -57,18 +57,26 @@ void ISPProtocol_EnterISPMode(void) Endpoint_Read_Stream_LE(&Enter_ISP_Params, sizeof(Enter_ISP_Params), NO_STREAM_CALLBACK); Endpoint_ClearOUT(); + Endpoint_SelectEndpoint(AVRISP_DATA_IN_EPNUM); Endpoint_SetEndpointDirection(ENDPOINT_DIR_IN); uint8_t ResponseStatus = STATUS_CMD_FAILED; CurrentAddress = 0; + + /* Set up the synchronous USART to generate the recovery clock on XCK pin */ + UBRR1 = (F_CPU / 500000UL); + UCSR1B = (1 << TXEN1); + UCSR1C = (1 << UMSEL10) | (1 << UPM11) | (1 << USBS1) | (1 << UCSZ11) | (1 << UCSZ10) | (1 << UCPOL1); + DDRD |= (1 << 5); + /* Perform execution delay, initialize SPI bus */ ISPProtocol_DelayMS(Enter_ISP_Params.ExecutionDelayMS); SPI_Init(ISPTarget_GetSPIPrescalerMask() | SPI_SCK_LEAD_RISING | SPI_SAMPLE_LEADING | SPI_MODE_MASTER); /* Continuously attempt to synchronize with the target until either the number of attempts specified * by the host has exceeded, or the the device sends back the expected response values */ - while (Enter_ISP_Params.SynchLoops-- && (ResponseStatus == STATUS_CMD_FAILED)) + while (Enter_ISP_Params.SynchLoops-- && (ResponseStatus == STATUS_CMD_FAILED) && TimeoutMSRemaining) { uint8_t ResponseBytes[4]; @@ -110,6 +118,7 @@ void ISPProtocol_LeaveISPMode(void) Endpoint_Read_Stream_LE(&Leave_ISP_Params, sizeof(Leave_ISP_Params), NO_STREAM_CALLBACK); Endpoint_ClearOUT(); + Endpoint_SelectEndpoint(AVRISP_DATA_IN_EPNUM); Endpoint_SetEndpointDirection(ENDPOINT_DIR_IN); /* Perform pre-exit delay, release the target /RESET, disable the SPI bus and perform the post-exit delay */ @@ -118,6 +127,12 @@ void ISPProtocol_LeaveISPMode(void) SPI_ShutDown(); ISPProtocol_DelayMS(Leave_ISP_Params.PostDelayMS); + /* Turn off the synchronous USART to terminate the recovery clock on XCK pin */ + UBRR1 = (F_CPU / 500000UL); + UCSR1B = (1 << TXEN1); + UCSR1C = (1 << UMSEL10) | (1 << UPM11) | (1 << USBS1) | (1 << UCSZ11) | (1 << UCSZ10) | (1 << UCPOL1); + DDRD &= ~(1 << 5); + Endpoint_Write_Byte(CMD_LEAVE_PROGMODE_ISP); Endpoint_Write_Byte(STATUS_CMD_OK); Endpoint_ClearIN(); @@ -150,6 +165,7 @@ void ISPProtocol_ProgramMemory(uint8_t V2Command) if (Write_Memory_Params.BytesToWrite > sizeof(Write_Memory_Params.ProgData)) { Endpoint_ClearOUT(); + Endpoint_SelectEndpoint(AVRISP_DATA_IN_EPNUM); Endpoint_SetEndpointDirection(ENDPOINT_DIR_IN); Endpoint_Write_Byte(V2Command); @@ -161,6 +177,7 @@ void ISPProtocol_ProgramMemory(uint8_t V2Command) Endpoint_Read_Stream_LE(&Write_Memory_Params.ProgData, Write_Memory_Params.BytesToWrite, NO_STREAM_CALLBACK); Endpoint_ClearOUT(); + Endpoint_SelectEndpoint(AVRISP_DATA_IN_EPNUM); Endpoint_SetEndpointDirection(ENDPOINT_DIR_IN); uint8_t ProgrammingStatus = STATUS_CMD_OK; @@ -198,14 +215,15 @@ void ISPProtocol_ProgramMemory(uint8_t V2Command) /* AVR FLASH addressing requires us to modify the write command based on if we are writing a high * or low byte at the current word address */ - Write_Memory_Params.ProgrammingCommands[0] ^= READ_WRITE_HIGH_BYTE_MASK; + if (V2Command == CMD_PROGRAM_FLASH_ISP) + Write_Memory_Params.ProgrammingCommands[0] ^= READ_WRITE_HIGH_BYTE_MASK; /* Check to see the write completion method, to see if we have a valid polling address */ if (!(PollAddress) && (ByteToWrite != PollValue)) { if (IsOddByte && (V2Command == CMD_PROGRAM_FLASH_ISP)) Write_Memory_Params.ProgrammingCommands[2] |= READ_WRITE_HIGH_BYTE_MASK; - + PollAddress = (CurrentAddress & 0xFFFF); } @@ -239,17 +257,17 @@ void ISPProtocol_ProgramMemory(uint8_t V2Command) { bool IsOddByte = (CurrentByte & 0x01); uint8_t ByteToWrite = *(NextWriteByte++); - - if (IsOddByte && (V2Command == CMD_READ_FLASH_ISP)) - Write_Memory_Params.ProgrammingCommands[0] |= READ_WRITE_HIGH_BYTE_MASK; - else - Write_Memory_Params.ProgrammingCommands[0] &= ~READ_WRITE_HIGH_BYTE_MASK; SPI_SendByte(Write_Memory_Params.ProgrammingCommands[0]); SPI_SendByte(CurrentAddress >> 8); SPI_SendByte(CurrentAddress & 0xFF); SPI_SendByte(ByteToWrite); + /* AVR FLASH addressing requires us to modify the write command based on if we are writing a high + * or low byte at the current word address */ + if (V2Command == CMD_PROGRAM_FLASH_ISP) + Write_Memory_Params.ProgrammingCommands[0] ^= READ_WRITE_HIGH_BYTE_MASK; + if (ByteToWrite != PollValue) { if (IsOddByte && (V2Command == CMD_PROGRAM_FLASH_ISP)) @@ -291,6 +309,7 @@ void ISPProtocol_ReadMemory(uint8_t V2Command) Read_Memory_Params.BytesToRead = SwapEndian_16(Read_Memory_Params.BytesToRead); Endpoint_ClearOUT(); + Endpoint_SelectEndpoint(AVRISP_DATA_IN_EPNUM); Endpoint_SetEndpointDirection(ENDPOINT_DIR_IN); Endpoint_Write_Byte(V2Command); @@ -361,6 +380,7 @@ void ISPProtocol_ChipErase(void) Endpoint_Read_Stream_LE(&Erase_Chip_Params, sizeof(Erase_Chip_Params), NO_STREAM_CALLBACK); Endpoint_ClearOUT(); + Endpoint_SelectEndpoint(AVRISP_DATA_IN_EPNUM); Endpoint_SetEndpointDirection(ENDPOINT_DIR_IN); uint8_t ResponseStatus = STATUS_CMD_OK; @@ -396,6 +416,7 @@ void ISPProtocol_ReadFuseLockSigOSCCAL(uint8_t V2Command) Endpoint_Read_Stream_LE(&Read_FuseLockSigOSCCAL_Params, sizeof(Read_FuseLockSigOSCCAL_Params), NO_STREAM_CALLBACK); Endpoint_ClearOUT(); + Endpoint_SelectEndpoint(AVRISP_DATA_IN_EPNUM); Endpoint_SetEndpointDirection(ENDPOINT_DIR_IN); uint8_t ResponseBytes[4]; @@ -426,6 +447,7 @@ void ISPProtocol_WriteFuseLock(uint8_t V2Command) Endpoint_Read_Stream_LE(&Write_FuseLockSig_Params, sizeof(Write_FuseLockSig_Params), NO_STREAM_CALLBACK); Endpoint_ClearOUT(); + Endpoint_SelectEndpoint(AVRISP_DATA_IN_EPNUM); Endpoint_SetEndpointDirection(ENDPOINT_DIR_IN); /* Send the Fuse or Lock byte program commands as given by the host to the device */ @@ -453,6 +475,7 @@ void ISPProtocol_SPIMulti(void) Endpoint_Read_Stream_LE(&SPI_Multi_Params.TxData, SPI_Multi_Params.TxBytes, NO_STREAM_CALLBACK); Endpoint_ClearOUT(); + Endpoint_SelectEndpoint(AVRISP_DATA_IN_EPNUM); Endpoint_SetEndpointDirection(ENDPOINT_DIR_IN); Endpoint_Write_Byte(CMD_SPI_MULTI); @@ -504,4 +527,19 @@ void ISPProtocol_SPIMulti(void) } } +/** Blocking delay for a given number of milliseconds. + * + * \param[in] DelayMS Number of milliseconds to delay for + */ +void ISPProtocol_DelayMS(uint8_t DelayMS) +{ + while (DelayMS-- && TimeoutMSRemaining) + { + if (TimeoutMSRemaining) + TimeoutMSRemaining--; + + _delay_ms(1); + } +} + #endif \ No newline at end of file