From 3d28d53c3e2ae529933283e63a8b05f2ab1ce2be Mon Sep 17 00:00:00 2001 From: Dean Camera Date: Sun, 2 May 2010 05:16:34 +0000 Subject: [PATCH] Change AVRISP project's timeout to be interrupt based again, but make the interrupt itself interruptable and use a seperate assembly file to hand-optimize the ISR code. Removed the cast to uint16_t on the set baud rate in the USBtoSerial project, so that the higher >1M baud rates can be selected (thanks to Steffan). --- LUFA.pnproj | 2 +- LUFA/ManPages/ChangeLog.txt | 2 + Projects/AVRISP-MKII/Lib/ISP/ISPTarget.c | 14 ----- Projects/AVRISP-MKII/Lib/Timeout.S | 23 ++++++++ Projects/AVRISP-MKII/Lib/V2Protocol.c | 8 ++- Projects/AVRISP-MKII/Lib/V2Protocol.h | 44 ++++++++------- Projects/AVRISP-MKII/Lib/XPROG/TINYNVM.c | 14 ----- Projects/AVRISP-MKII/Lib/XPROG/XMEGANVM.c | 14 ----- Projects/AVRISP-MKII/Lib/XPROG/XPROGTarget.c | 58 ++------------------ Projects/AVRISP-MKII/makefile | 2 +- Projects/USBtoSerial/USBtoSerial.c | 2 +- 11 files changed, 66 insertions(+), 117 deletions(-) create mode 100644 Projects/AVRISP-MKII/Lib/Timeout.S diff --git a/LUFA.pnproj b/LUFA.pnproj index a3cb469e28..dc9ab7db23 100644 --- a/LUFA.pnproj +++ b/LUFA.pnproj @@ -1 +1 @@ - \ No newline at end of file + \ No newline at end of file diff --git a/LUFA/ManPages/ChangeLog.txt b/LUFA/ManPages/ChangeLog.txt index 6eec642a36..81e7189658 100644 --- a/LUFA/ManPages/ChangeLog.txt +++ b/LUFA/ManPages/ChangeLog.txt @@ -31,6 +31,8 @@ * - The USB_Init() function no longer calls sei() - the user is now responsible for enabling interrupts when they are ready * for them to be enabled (thanks to Andrei Krainev) * - The Audio_Device_IsSampleReceived() and Audio_Device_IsReadyForNextSample() functions are now inline, to reduce overhead + * - Removed the cast to uint16_t on the set baud rate in the USBtoSerial project, so that the higher >1M baud rates can be + * selected (thanks to Steffan) * * Fixed: * - Fixed software PDI/TPI programming mode in the AVRISP project not correctly toggling just the clock pin diff --git a/Projects/AVRISP-MKII/Lib/ISP/ISPTarget.c b/Projects/AVRISP-MKII/Lib/ISP/ISPTarget.c index 94f1c3d74b..1c53765794 100644 --- a/Projects/AVRISP-MKII/Lib/ISP/ISPTarget.c +++ b/Projects/AVRISP-MKII/Lib/ISP/ISPTarget.c @@ -124,13 +124,6 @@ uint8_t ISPTarget_WaitForProgComplete(const uint8_t ProgrammingMode, const uint1 case PROG_MODE_PAGED_VALUE_MASK: do { - /* Manage software timeout */ - if (TIFR0 & (1 << OCF0A)) - { - TIFR0 |= (1 << OCF0A); - TimeoutMSRemaining--; - } - SPI_SendByte(ReadMemCommand); SPI_SendByte(PollAddress >> 8); SPI_SendByte(PollAddress & 0xFF); @@ -162,13 +155,6 @@ uint8_t ISPTarget_WaitWhileTargetBusy(void) { do { - /* Manage software timeout */ - if (TIFR0 & (1 << OCF0A)) - { - TIFR0 |= (1 << OCF0A); - TimeoutMSRemaining--; - } - SPI_SendByte(0xF0); SPI_SendByte(0x00); SPI_SendByte(0x00); diff --git a/Projects/AVRISP-MKII/Lib/Timeout.S b/Projects/AVRISP-MKII/Lib/Timeout.S new file mode 100644 index 0000000000..ad56d1d215 --- /dev/null +++ b/Projects/AVRISP-MKII/Lib/Timeout.S @@ -0,0 +1,23 @@ +#include +#include "V2Protocol.h" + +.global TIMER0_COMPA_vect +TIMER0_COMPA_vect: + sei + push r24 + in r24, 0x3f + push r24 + + in r24, TimeoutMSRemaining + and r24, r24 + breq Epilogue + subi r24, 0x01 + out TimeoutMSRemaining, r24 + +Epilogue: + pop r24 + out 0x3f, r24 + pop r24 + reti + + \ No newline at end of file diff --git a/Projects/AVRISP-MKII/Lib/V2Protocol.c b/Projects/AVRISP-MKII/Lib/V2Protocol.c index 431f9c2d52..63b7294c0a 100644 --- a/Projects/AVRISP-MKII/Lib/V2Protocol.c +++ b/Projects/AVRISP-MKII/Lib/V2Protocol.c @@ -42,6 +42,7 @@ uint32_t CurrentAddress; /** Flag to indicate that the next read/write operation must update the device's current address */ bool MustSetAddress; + /** Initializes the hardware and software associated with the V2 protocol command handling. */ void V2Protocol_Init(void) { @@ -55,7 +56,7 @@ void V2Protocol_Init(void) /* Millisecond timer initialization for managing the command timeout counter */ OCR0A = ((F_CPU / 64) / 1000); TCCR0A = (1 << WGM01); - TCCR0B = ((1 << CS01) | (1 << CS00)); + TIMSK0 = (1 << OCIE0A); V2Params_LoadNonVolatileParamValues(); } @@ -68,7 +69,9 @@ void V2Protocol_ProcessCommand(void) { uint8_t V2Command = Endpoint_Read_Byte(); + /* Start the timeout management timer */ TimeoutMSRemaining = COMMAND_TIMEOUT_MS; + TCCR0B = ((1 << CS01) | (1 << CS00)); switch (V2Command) { @@ -129,6 +132,9 @@ void V2Protocol_ProcessCommand(void) V2Protocol_UnknownCommand(V2Command); break; } + + /* Disable the timeout management timer */ + TCCR0B = 0; Endpoint_WaitUntilReady(); Endpoint_SelectEndpoint(AVRISP_DATA_OUT_EPNUM); diff --git a/Projects/AVRISP-MKII/Lib/V2Protocol.h b/Projects/AVRISP-MKII/Lib/V2Protocol.h index 43dee1e77c..7ad896da8a 100644 --- a/Projects/AVRISP-MKII/Lib/V2Protocol.h +++ b/Projects/AVRISP-MKII/Lib/V2Protocol.h @@ -37,14 +37,16 @@ #define _V2_PROTOCOL_ /* Includes: */ - #include - #include - - #include "../Descriptors.h" - #include "V2ProtocolConstants.h" - #include "V2ProtocolParams.h" - #include "ISP/ISPProtocol.h" - #include "XPROG/XPROGProtocol.h" + #if !defined(__ASSEMBLER__) + #include + #include + + #include "../Descriptors.h" + #include "V2ProtocolConstants.h" + #include "V2ProtocolParams.h" + #include "ISP/ISPProtocol.h" + #include "XPROG/XPROGProtocol.h" + #endif /* Preprocessor Checks: */ #if ((BOARD == BOARD_XPLAIN) || (BOARD == BOARD_XPLAIN_REV1)) @@ -80,19 +82,23 @@ #endif /* External Variables: */ - extern uint32_t CurrentAddress; - extern bool MustSetAddress; + #if !defined(__ASSEMBLER__) + extern uint32_t CurrentAddress; + extern bool MustSetAddress; + #endif /* Function Prototypes: */ - void V2Protocol_Init(void); - void V2Protocol_ProcessCommand(void); - - #if defined(INCLUDE_FROM_V2PROTOCOL_C) - static void V2Protocol_UnknownCommand(const uint8_t V2Command); - static void V2Protocol_SignOn(void); - static void V2Protocol_GetSetParam(const uint8_t V2Command); - static void V2Protocol_ResetProtection(void); - static void V2Protocol_LoadAddress(void); + #if !defined(__ASSEMBLER__) + void V2Protocol_Init(void); + void V2Protocol_ProcessCommand(void); + + #if defined(INCLUDE_FROM_V2PROTOCOL_C) + static void V2Protocol_UnknownCommand(const uint8_t V2Command); + static void V2Protocol_SignOn(void); + static void V2Protocol_GetSetParam(const uint8_t V2Command); + static void V2Protocol_ResetProtection(void); + static void V2Protocol_LoadAddress(void); + #endif #endif #endif diff --git a/Projects/AVRISP-MKII/Lib/XPROG/TINYNVM.c b/Projects/AVRISP-MKII/Lib/XPROG/TINYNVM.c index acd6b651cc..817f22347f 100644 --- a/Projects/AVRISP-MKII/Lib/XPROG/TINYNVM.c +++ b/Projects/AVRISP-MKII/Lib/XPROG/TINYNVM.c @@ -94,13 +94,6 @@ bool TINYNVM_WaitWhileNVMBusBusy(void) TimeoutMSRemaining = COMMAND_TIMEOUT_MS; return true; } - - /* Manage software timeout */ - if (TIFR0 & (1 << OCF0A)) - { - TIFR0 |= (1 << OCF0A); - TimeoutMSRemaining--; - } } return false; @@ -131,13 +124,6 @@ bool TINYNVM_WaitWhileNVMControllerBusy(void) TimeoutMSRemaining = COMMAND_TIMEOUT_MS; return true; } - - /* Manage software timeout */ - if (TIFR0 & (1 << OCF0A)) - { - TIFR0 |= (1 << OCF0A); - TimeoutMSRemaining--; - } } return false; diff --git a/Projects/AVRISP-MKII/Lib/XPROG/XMEGANVM.c b/Projects/AVRISP-MKII/Lib/XPROG/XMEGANVM.c index b6b039aa80..1671d29bac 100644 --- a/Projects/AVRISP-MKII/Lib/XPROG/XMEGANVM.c +++ b/Projects/AVRISP-MKII/Lib/XPROG/XMEGANVM.c @@ -89,13 +89,6 @@ bool XMEGANVM_WaitWhileNVMBusBusy(void) TimeoutMSRemaining = COMMAND_TIMEOUT_MS; return true; } - - /* Manage software timeout */ - if (TIFR0 & (1 << OCF0A)) - { - TIFR0 |= (1 << OCF0A); - TimeoutMSRemaining--; - } } return false; @@ -127,13 +120,6 @@ bool XMEGANVM_WaitWhileNVMControllerBusy(void) TimeoutMSRemaining = COMMAND_TIMEOUT_MS; return true; } - - /* Manage software timeout */ - if (TIFR0 & (1 << OCF0A)) - { - TIFR0 |= (1 << OCF0A); - TimeoutMSRemaining--; - } } return false; diff --git a/Projects/AVRISP-MKII/Lib/XPROG/XPROGTarget.c b/Projects/AVRISP-MKII/Lib/XPROG/XPROGTarget.c index e75adbe101..228a895468 100644 --- a/Projects/AVRISP-MKII/Lib/XPROG/XPROGTarget.c +++ b/Projects/AVRISP-MKII/Lib/XPROG/XPROGTarget.c @@ -328,15 +328,7 @@ uint8_t XPROGTarget_ReceiveByte(void) #if defined(XPROG_VIA_HARDWARE_USART) /* Wait until a byte has been received before reading */ - while (!(UCSR1A & (1 << RXC1)) && TimeoutMSRemaining) - { - /* Manage software timeout */ - if (TIFR0 & (1 << OCF0A)) - { - TIFR0 |= (1 << OCF0A); - TimeoutMSRemaining--; - } - } + while (!(UCSR1A & (1 << RXC1)) && TimeoutMSRemaining); if (TimeoutMSRemaining) TimeoutMSRemaining = COMMAND_TIMEOUT_MS; @@ -345,15 +337,7 @@ uint8_t XPROGTarget_ReceiveByte(void) #else /* Wait until a byte has been received before reading */ SoftUSART_BitCount = BITS_IN_USART_FRAME; - while (SoftUSART_BitCount && TimeoutMSRemaining) - { - /* Manage software timeout */ - if (TIFR0 & (1 << OCF0A)) - { - TIFR0 |= (1 << OCF0A); - TimeoutMSRemaining--; - } - } + while (SoftUSART_BitCount && TimeoutMSRemaining); if (TimeoutMSRemaining) TimeoutMSRemaining = COMMAND_TIMEOUT_MS; @@ -402,14 +386,7 @@ static void XPROGTarget_SetTxMode(void) IsSending = true; #else - while (SoftUSART_BitCount && TimeoutMSRemaining) - { - if (TIFR0 & (1 << OCF0A)) - { - TIFR0 |= (1 << OCF0A); - TimeoutMSRemaining--; - } - } + while (SoftUSART_BitCount && TimeoutMSRemaining); /* Wait for a full cycle of the clock */ SoftUSART_Data = 0x0001; @@ -443,14 +420,7 @@ static void XPROGTarget_SetRxMode(void) DDRD &= ~(1 << 3); PORTD &= ~(1 << 3); #else - while (SoftUSART_BitCount && TimeoutMSRemaining) - { - if (TIFR0 & (1 << OCF0A)) - { - TIFR0 |= (1 << OCF0A); - TimeoutMSRemaining--; - } - } + while (SoftUSART_BitCount && TimeoutMSRemaining); if (XPROG_SelectedProtocol == XPRG_PROTOCOL_PDI) { @@ -458,15 +428,7 @@ static void XPROGTarget_SetRxMode(void) BITBANG_PDIDATA_PORT &= ~BITBANG_PDIDATA_MASK; /* Wait until DATA line has been pulled up to idle by the target */ - while (!(BITBANG_PDIDATA_PIN & BITBANG_PDIDATA_MASK) && TimeoutMSRemaining) - { - /* Manage software timeout */ - if (TIFR0 & (1 << OCF0A)) - { - TIFR0 |= (1 << OCF0A); - TimeoutMSRemaining--; - } - } + while (!(BITBANG_PDIDATA_PIN & BITBANG_PDIDATA_MASK) && TimeoutMSRemaining); } else { @@ -474,15 +436,7 @@ static void XPROGTarget_SetRxMode(void) BITBANG_TPIDATA_PORT &= ~BITBANG_TPIDATA_MASK; /* Wait until DATA line has been pulled up to idle by the target */ - while (!(BITBANG_TPIDATA_PIN & BITBANG_TPIDATA_MASK) && TimeoutMSRemaining) - { - /* Manage software timeout */ - if (TIFR0 & (1 << OCF0A)) - { - TIFR0 |= (1 << OCF0A); - TimeoutMSRemaining--; - } - } + while (!(BITBANG_TPIDATA_PIN & BITBANG_TPIDATA_MASK) && TimeoutMSRemaining); } #endif diff --git a/Projects/AVRISP-MKII/makefile b/Projects/AVRISP-MKII/makefile index 004a108379..cbc46ce50c 100644 --- a/Projects/AVRISP-MKII/makefile +++ b/Projects/AVRISP-MKII/makefile @@ -157,7 +157,7 @@ CPPSRC = # Even though the DOS/Win* filesystem matches both .s and .S the same, # it will preserve the spelling of the filenames, and gcc itself does # care about how the name is spelled on its command-line. -ASRC = +ASRC = Lib/Timeout.S # Optimization level, can be [0, 1, 2, 3, s]. diff --git a/Projects/USBtoSerial/USBtoSerial.c b/Projects/USBtoSerial/USBtoSerial.c index c9bc717341..1b4cab2890 100644 --- a/Projects/USBtoSerial/USBtoSerial.c +++ b/Projects/USBtoSerial/USBtoSerial.c @@ -194,5 +194,5 @@ void EVENT_CDC_Device_LineEncodingChanged(USB_ClassInfo_CDC_Device_t* const CDCI UCSR1A = (1 << U2X1); UCSR1B = ((1 << RXCIE1) | (1 << TXEN1) | (1 << RXEN1)); UCSR1C = ConfigMask; - UBRR1 = SERIAL_2X_UBBRVAL((uint16_t)CDCInterfaceInfo->State.LineEncoding.BaudRateBPS); + UBRR1 = SERIAL_2X_UBBRVAL(CDCInterfaceInfo->State.LineEncoding.BaudRateBPS); }