From 8cb8f1cfddf0d9a76442f8fdafe207ac7e6fe340 Mon Sep 17 00:00:00 2001 From: Dean Camera Date: Mon, 24 Aug 2009 12:49:19 +0000 Subject: Switch to hardware delays and timeouts via a hardware timer in the V2 Protocol handler. More additions to the PROGRAM_FLASH_ISP and PROGRAM_EEPROM_ISP commands, although neither work correctly yet. Added dummy RESET_PROTECTIONS handler to prevent the Atmel driver from crashing when the command returns an UNKNOWN_COMMAND error code. --- Projects/Incomplete/AVRISP/AVRISP.c | 6 +++ Projects/Incomplete/AVRISP/Lib/V2Protocol.c | 58 ++++++++++++++++++----- Projects/Incomplete/AVRISP/Lib/V2Protocol.h | 2 +- Projects/Incomplete/AVRISP/Lib/V2ProtocolParams.c | 2 +- Projects/Incomplete/AVRISP/Lib/V2ProtocolTarget.c | 56 +++++++++++++++++----- Projects/Incomplete/AVRISP/Lib/V2ProtocolTarget.h | 5 +- 6 files changed, 101 insertions(+), 28 deletions(-) (limited to 'Projects/Incomplete') diff --git a/Projects/Incomplete/AVRISP/AVRISP.c b/Projects/Incomplete/AVRISP/AVRISP.c index f3634fd70..32919ef8e 100644 --- a/Projects/Incomplete/AVRISP/AVRISP.c +++ b/Projects/Incomplete/AVRISP/AVRISP.c @@ -37,6 +37,7 @@ // TODO: Add reversed target connector checks // TODO: Add in software SPI for lower programming speeds below 125KHz // TODO: Add in VTARGET detection +// TODO: Add in software SPI for lower programming speeds #include "AVRISP.h" @@ -72,6 +73,11 @@ void SetupHardware(void) /* Hardware Initialization */ LEDs_Init(); USB_Init(); + + /* Millisecond timer initialization for timeout checking */ + OCR0A = ((F_CPU / 64) / 1000); + TCCR0A = (1 << WGM01); + TCCR0B = ((1 << CS01) | (1 << CS00)); } /** Event handler for the library USB Connection event. */ diff --git a/Projects/Incomplete/AVRISP/Lib/V2Protocol.c b/Projects/Incomplete/AVRISP/Lib/V2Protocol.c index 16a1a0708..2c2966906 100644 --- a/Projects/Incomplete/AVRISP/Lib/V2Protocol.c +++ b/Projects/Incomplete/AVRISP/Lib/V2Protocol.c @@ -52,6 +52,9 @@ void V2Protocol_ProcessCommand(void) case CMD_LOAD_ADDRESS: V2Protocol_Command_LoadAddress(); break; + case CMD_RESET_PROTECTION: + V2Protocol_Command_ResetProtection(); + break; case CMD_ENTER_PROGMODE_ISP: V2Protocol_Command_EnterISPMode(); break; @@ -168,6 +171,16 @@ static void V2Protocol_Command_LoadAddress(void) Endpoint_ClearIN(); } +static void V2Protocol_Command_ResetProtection(void) +{ + Endpoint_ClearOUT(); + Endpoint_SetEndpointDirection(ENDPOINT_DIR_IN); + + Endpoint_Write_Byte(CMD_RESET_PROTECTION); + Endpoint_Write_Byte(STATUS_CMD_OK); + Endpoint_ClearIN(); +} + static void V2Protocol_Command_EnterISPMode(void) { struct @@ -208,7 +221,7 @@ static void V2Protocol_Command_EnterISPMode(void) } /* Check if polling disabled, or if the polled value matches the expected value */ - if (!Enter_ISP_Params.PollIndex || (ResponseBytes[Enter_ISP_Params.PollIndex - 1] == Enter_ISP_Params.PollValue)) + if (!(Enter_ISP_Params.PollIndex) || (ResponseBytes[Enter_ISP_Params.PollIndex - 1] == Enter_ISP_Params.PollValue)) { ResponseStatus = STATUS_CMD_OK; } @@ -264,6 +277,8 @@ static void V2Protocol_Command_ProgramMemory(uint8_t V2Command) uint8_t ProgrammingStatus = STATUS_CMD_OK; uint16_t PollAddress = 0; + uint8_t PollValue = (V2Command == CMD_PROGRAM_FLASH_ISP) ? Write_Memory_Params.PollValue1 : + Write_Memory_Params.PollValue2; if (Write_Memory_Params.ProgrammingMode & PROG_MODE_PAGED_WRITES_MASK) { @@ -281,11 +296,11 @@ static void V2Protocol_Command_ProgramMemory(uint8_t V2Command) SPI_SendByte(CurrentAddress & 0xFF); SPI_SendByte(ByteToWrite); - if (!(PollAddress)) + if (!(PollAddress) && (ByteToWrite != PollValue)) { - if ((ByteToWrite != Write_Memory_Params.PollValue1) && (V2Command == CMD_PROGRAM_FLASH_ISP)) + if (V2Command == CMD_PROGRAM_FLASH_ISP) PollAddress = (((CurrentAddress & 0xFFFF) << 1) | IsOddByte); - else if ((ByteToWrite != Write_Memory_Params.PollValue2) && (V2Command == CMD_PROGRAM_EEPROM_ISP)) + else PollAddress = (CurrentAddress & 0xFFFF); } @@ -309,7 +324,9 @@ static void V2Protocol_Command_ProgramMemory(uint8_t V2Command) } } - ProgrammingStatus = V2Protocol_WaitForProgrammingComplete(PollAddress, Write_Memory_Params.ProgrammingMode); + ProgrammingStatus = V2Protocol_WaitForProgComplete(Write_Memory_Params.ProgrammingMode, PollAddress, PollValue, + Write_Memory_Params.DelayMS, (V2Command == CMD_READ_FLASH_ISP), + Write_Memory_Params.ProgrammingCommands[2]); } else { @@ -327,15 +344,20 @@ static void V2Protocol_Command_ProgramMemory(uint8_t V2Command) SPI_SendByte(CurrentAddress & 0xFF); SPI_SendByte(ByteToWrite); - if ((ByteToWrite != Write_Memory_Params.PollValue1) && (V2Command == CMD_PROGRAM_FLASH_ISP)) - PollAddress = (((CurrentAddress & 0xFFFF) << 1) | IsOddByte); - else if ((ByteToWrite != Write_Memory_Params.PollValue2) && (V2Command == CMD_PROGRAM_EEPROM_ISP)) - PollAddress = (CurrentAddress & 0xFFFF); - - ProgrammingStatus = V2Protocol_WaitForProgrammingComplete(PollAddress, Write_Memory_Params.ProgrammingMode); - + if (ByteToWrite != PollValue) + { + if (V2Command == CMD_PROGRAM_FLASH_ISP) + PollAddress = (((CurrentAddress & 0xFFFF) << 1) | IsOddByte); + else + PollAddress = (CurrentAddress & 0xFFFF); + } + if (IsOddByte || (V2Command == CMD_PROGRAM_EEPROM_ISP)) CurrentAddress++; + + ProgrammingStatus = V2Protocol_WaitForProgComplete(Write_Memory_Params.ProgrammingMode, PollAddress, PollValue, + Write_Memory_Params.DelayMS, (V2Command == CMD_READ_FLASH_ISP), + Write_Memory_Params.ProgrammingCommands[2]); if (ProgrammingStatus != STATUS_CMD_OK) break; @@ -390,7 +412,17 @@ static void V2Protocol_Command_ReadMemory(uint8_t V2Command) } Endpoint_Write_Byte(STATUS_CMD_OK); + + bool IsEndpointFull = !(Endpoint_IsReadWriteAllowed()); Endpoint_ClearIN(); + + /* Ensure last packet is a short packet to terminate the transfer */ + if (IsEndpointFull) + { + Endpoint_WaitUntilReady(); + Endpoint_ClearIN(); + Endpoint_WaitUntilReady(); + } } static void V2Protocol_Command_ChipErase(void) @@ -412,7 +444,7 @@ static void V2Protocol_Command_ChipErase(void) for (uint8_t SByte = 0; SByte < sizeof(Erase_Chip_Params.EraseCommandBytes); SByte++) SPI_SendByte(Erase_Chip_Params.EraseCommandBytes[SByte]); - if (Erase_Chip_Params.PollMethod == 0) + if (!(Erase_Chip_Params.PollMethod)) V2Protocol_DelayMS(Erase_Chip_Params.EraseDelayMS); else ResponseStatus = V2Protocol_WaitWhileTargetBusy(); diff --git a/Projects/Incomplete/AVRISP/Lib/V2Protocol.h b/Projects/Incomplete/AVRISP/Lib/V2Protocol.h index cd9648253..55c1c78c2 100644 --- a/Projects/Incomplete/AVRISP/Lib/V2Protocol.h +++ b/Projects/Incomplete/AVRISP/Lib/V2Protocol.h @@ -56,7 +56,6 @@ #define PROG_MODE_PAGED_TIMEDELAY_MASK (1 << 4) #define PROG_MODE_PAGED_VALUE_MASK (1 << 5) #define PROG_MODE_PAGED_READYBUSY_MASK (1 << 6) - #define PROG_MODE_COMMIT_PAGE_MASK (1 << 7) /* Function Prototypes: */ @@ -67,6 +66,7 @@ static void V2Protocol_Command_SignOn(void); static void V2Protocol_Command_GetSetParam(uint8_t V2Command); static void V2Protocol_Command_LoadAddress(void); + static void V2Protocol_Command_ResetProtection(void); static void V2Protocol_Command_EnterISPMode(void); static void V2Protocol_Command_LeaveISPMode(void); static void V2Protocol_Command_ProgramMemory(uint8_t V2Command); diff --git a/Projects/Incomplete/AVRISP/Lib/V2ProtocolParams.c b/Projects/Incomplete/AVRISP/Lib/V2ProtocolParams.c index 74c8f2024..a95e8757e 100644 --- a/Projects/Incomplete/AVRISP/Lib/V2ProtocolParams.c +++ b/Projects/Incomplete/AVRISP/Lib/V2ProtocolParams.c @@ -63,7 +63,7 @@ static ParameterItem_t ParameterTable[] = .ParamPrivellages = PARAM_PRIV_READ }, { .ParamID = PARAM_VTARGET, - .ParamValue = 0x00, + .ParamValue = 0x32, .ParamPrivellages = PARAM_PRIV_READ }, { .ParamID = PARAM_SCK_DURATION, diff --git a/Projects/Incomplete/AVRISP/Lib/V2ProtocolTarget.c b/Projects/Incomplete/AVRISP/Lib/V2ProtocolTarget.c index b2064fc26..f9b4427ce 100644 --- a/Projects/Incomplete/AVRISP/Lib/V2ProtocolTarget.c +++ b/Projects/Incomplete/AVRISP/Lib/V2ProtocolTarget.c @@ -78,22 +78,58 @@ void V2Protocol_ChangeTargetResetLine(bool ResetTarget) void V2Protocol_DelayMS(uint8_t MS) { - while (MS--) - _delay_ms(1); + TCNT0 = 0; + while (TCNT0 < MS); } -uint8_t V2Protocol_WaitForProgrammingComplete(uint16_t PollAddress, uint8_t ProgrammingMode) +uint8_t V2Protocol_WaitForProgComplete(uint8_t ProgrammingMode, uint16_t PollAddress, uint8_t PollValue, + uint8_t DelayMS, bool IsFlashMemory, uint8_t ReadMemCommand) { - // TODO + uint8_t ProgrammingStatus = STATUS_CMD_OK; - return STATUS_CMD_OK; + /* Determine method of Programming Complete check */ + switch (ProgrammingMode & ~(PROG_MODE_PAGED_WRITES_MASK | PROG_MODE_COMMIT_PAGE_MASK)) + { + case PROG_MODE_WORD_TIMEDELAY_MASK: + case PROG_MODE_PAGED_TIMEDELAY_MASK: + V2Protocol_DelayMS(DelayMS); + break; + case PROG_MODE_WORD_VALUE_MASK: + case PROG_MODE_PAGED_VALUE_MASK: + if (IsFlashMemory && (PollAddress & 0x01)) + { + ReadMemCommand |= READ_WRITE_ODD_BYTE_MASK; + PollAddress >>= 1; + } + + TCNT0 = 0; + + do + { + SPI_SendByte(ReadMemCommand); + SPI_SendByte(PollAddress >> 8); + SPI_SendByte(PollAddress & 0xFF); + } + while ((SPI_TransferByte(0x00) != PollValue) && (TCNT0 < TARGET_BUSY_TIMEOUT_MS)); + + if (TCNT0 >= TARGET_BUSY_TIMEOUT_MS) + ProgrammingStatus = STATUS_RDY_BSY_TOUT; + + break; + case PROG_MODE_WORD_READYBUSY_MASK: + case PROG_MODE_PAGED_READYBUSY_MASK: + ProgrammingStatus = V2Protocol_WaitWhileTargetBusy(); + } + + return ProgrammingStatus; } uint8_t V2Protocol_WaitWhileTargetBusy(void) { - uint8_t TimeoutMS = TARGET_BUSY_TIMEOUT_MS; uint8_t ResponseByte; + TCNT0 = 0; + do { SPI_SendByte(0xF0); @@ -101,13 +137,11 @@ uint8_t V2Protocol_WaitWhileTargetBusy(void) SPI_SendByte(0x00); ResponseByte = SPI_ReceiveByte(); - - V2Protocol_DelayMS(1); } - while ((ResponseByte & 0x01) && (TimeoutMS--)); + while ((ResponseByte & 0x01) && (TCNT0 < TARGET_BUSY_TIMEOUT_MS)); - if (!(TimeoutMS)) - return STATUS_CMD_TOUT; + if (TCNT0 >= TARGET_BUSY_TIMEOUT_MS) + return STATUS_RDY_BSY_TOUT; else return STATUS_CMD_OK; } diff --git a/Projects/Incomplete/AVRISP/Lib/V2ProtocolTarget.h b/Projects/Incomplete/AVRISP/Lib/V2ProtocolTarget.h index 847770c7b..d67f84708 100644 --- a/Projects/Incomplete/AVRISP/Lib/V2ProtocolTarget.h +++ b/Projects/Incomplete/AVRISP/Lib/V2ProtocolTarget.h @@ -48,7 +48,7 @@ #include "V2ProtocolParams.h" /* Macros: */ - #define TARGET_BUSY_TIMEOUT_MS 100 + #define TARGET_BUSY_TIMEOUT_MS 200 /* External Variables: */ extern uint32_t CurrentAddress; @@ -57,7 +57,8 @@ uint8_t V2Protocol_GetSPIPrescalerMask(void); void V2Protocol_ChangeTargetResetLine(bool ResetTarget); void V2Protocol_DelayMS(uint8_t MS); - uint8_t V2Protocol_WaitForProgrammingComplete(uint16_t PollAddress, uint8_t ProgrammingMode); + uint8_t V2Protocol_WaitForProgComplete(uint8_t ProgrammingMode, uint16_t PollAddress, uint8_t PollValue, + uint8_t DelayMS, bool IsFlashMemory, uint8_t ReadMemCommand); uint8_t V2Protocol_WaitWhileTargetBusy(void); void V2Protocol_LoadExtendedAddress(void); -- cgit v1.2.3