From 3bf760ad7d8bcc06c9145121786f3644995fae87 Mon Sep 17 00:00:00 2001 From: Dean Camera Date: Tue, 2 Nov 2010 07:57:23 +0000 Subject: Rescue clock of the AVRISP-MKII moved to the AVR's OCR1A pin, so that the clock can be generated at all times when 125KHz ISP programming mode is selected. --- Projects/AVRISP-MKII/AVRISP-MKII.txt | 6 ++-- Projects/AVRISP-MKII/Lib/ISP/ISPProtocol.c | 12 -------- Projects/AVRISP-MKII/Lib/ISP/ISPTarget.c | 49 +++++++++++++++++++++++++++--- Projects/AVRISP-MKII/Lib/ISP/ISPTarget.h | 2 ++ Projects/AVRISP-MKII/Lib/V2Protocol.c | 1 + Projects/XPLAINBridge/Lib/SoftUART.c | 10 +++--- 6 files changed, 55 insertions(+), 25 deletions(-) (limited to 'Projects') diff --git a/Projects/AVRISP-MKII/AVRISP-MKII.txt b/Projects/AVRISP-MKII/AVRISP-MKII.txt index e36ffe231..534af5639 100644 --- a/Projects/AVRISP-MKII/AVRISP-MKII.txt +++ b/Projects/AVRISP-MKII/AVRISP-MKII.txt @@ -105,9 +105,9 @@ * * * - * In addition, the AVR's XCK pin will generate a .5MHz clock when SPI programming is used, to act as an external - * device clock if the fuses have been mis-set. To use the recovery clock, connect XCK to the target AVR's XTAL1 - * pin, and set the ISP programming speed to 125KHz or below. + * In addition, the AVR's OCR1A pin will generate a .5MHz clock, to act as an external rescue device clock + * if the fuses have been mis-set. To use the recovery clock, connect the OCR1A pin of the USB AVR to the target + * AVR's XTAL1 pin, and set the ISP programming speed to 125KHz (note: other ISP speeds will not work correctly). * * 1 Optional, see \ref SSec_Options section - for USB AVRs with ADC modules only \n * 2 See AUX line related tokens in the \ref SSec_Options section diff --git a/Projects/AVRISP-MKII/Lib/ISP/ISPProtocol.c b/Projects/AVRISP-MKII/Lib/ISP/ISPProtocol.c index 30d45c916..9056942d2 100644 --- a/Projects/AVRISP-MKII/Lib/ISP/ISPProtocol.c +++ b/Projects/AVRISP-MKII/Lib/ISP/ISPProtocol.c @@ -64,12 +64,6 @@ void ISPProtocol_EnterISPMode(void) CurrentAddress = 0; - /* Set up the synchronous USART to generate the .5MHz 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); ISPTarget_Init(); @@ -127,12 +121,6 @@ void ISPProtocol_LeaveISPMode(void) ISPTarget_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(); diff --git a/Projects/AVRISP-MKII/Lib/ISP/ISPTarget.c b/Projects/AVRISP-MKII/Lib/ISP/ISPTarget.c index e596cfe28..fe2f50d07 100644 --- a/Projects/AVRISP-MKII/Lib/ISP/ISPTarget.c +++ b/Projects/AVRISP-MKII/Lib/ISP/ISPTarget.c @@ -119,7 +119,7 @@ ISR(TIMER1_COMPA_vect, ISR_BLOCK) { if (!(PINB & (1 << 1))) { - if (SoftSPI_Data & 0x80) + if (SoftSPI_Data & (1 << 7)) PORTB |= (1 << 2); else PORTB &= ~(1 << 2); @@ -132,10 +132,11 @@ ISR(TIMER1_COMPA_vect, ISR_BLOCK) TCCR1B = 0; if (PINB & (1 << 3)) - SoftSPI_Data |= 0x01; + SoftSPI_Data |= (1 << 0); } - PORTB ^= (1 << 1); + /* Fast toggle of PORTB.1 via the PIN register (see datasheet) */ + PINB |= (1 << 1); } /** Initialises the appropriate SPI driver (hardware or software, depending on the selected ISP speed) ready for @@ -159,8 +160,7 @@ void ISPTarget_Init(void) DDRB |= ((1 << 1) | (1 << 2)); PORTB |= ((1 << 0) | (1 << 3)); - TIMSK1 = (1 << OCIE1A); - OCR1A = pgm_read_word(&TimerCompareFromSCKDuration[SCKDuration - sizeof(SPIMaskFromSCKDuration)]); + ISPTarget_ConfigureSoftwareISP(SCKDuration); } } @@ -177,9 +177,48 @@ void ISPTarget_ShutDown(void) { DDRB &= ~((1 << 1) | (1 << 2)); PORTB &= ~((1 << 0) | (1 << 3)); + + ISPTarget_ConfigureRescueClock(); } } +/** Configures the AVR to produce a .5MHz rescue clock out of the OCR1A pin of the AVR, so + * that it can be fed into the XTAL1 pin of an AVR whose fuses have been misconfigured for + * an external clock rather than a crystal. When used, the ISP speed must be 125KHz for this + * functionality to work correctly. + */ +void ISPTarget_ConfigureRescueClock(void) +{ + /* Configure OCR1A as an output for the specified AVR model */ + #if defined(USB_SERIES_2_AVR) + DDRC |= (1 << 6); + #else + DDRB |= (1 << 5); + #endif + + /* Start Timer 1 to generate a .5MHz clock on the OCR1A pin */ + TIMSK1 = 0; + TCNT1 = 0; + OCR1A = (F_CPU / 2 / 500000UL); + TCCR1A = (1 << COM1A0); + TCCR1B = ((1 << WGM12) | (1 << CS10)); +} + +/** Configures the AVR's timer ready to produce software ISP for the slower ISP speeds that + * cannot be obtained when using the AVR's hardware SPI module. + * + * \param[in] SCKDuration Duration of the desired software ISP SCK clock + */ +void ISPTarget_ConfigureSoftwareISP(const uint8_t SCKDuration) +{ + /* Configure Timer 1 for software ISP using the specified SCK duration */ + TIMSK1 = (1 << OCIE1A); + TCNT1 = 0; + OCR1A = pgm_read_word(&TimerCompareFromSCKDuration[SCKDuration - sizeof(SPIMaskFromSCKDuration)]); + TCCR1A = 0; + TCCR1B = 0; +} + /** Sends and receives a single byte of data to and from the attached target via software SPI. * * \param[in] Byte Byte of data to send to the attached target diff --git a/Projects/AVRISP-MKII/Lib/ISP/ISPTarget.h b/Projects/AVRISP-MKII/Lib/ISP/ISPTarget.h index e6ee42d4e..c467298c6 100644 --- a/Projects/AVRISP-MKII/Lib/ISP/ISPTarget.h +++ b/Projects/AVRISP-MKII/Lib/ISP/ISPTarget.h @@ -68,6 +68,8 @@ /* Function Prototypes: */ void ISPTarget_Init(void); void ISPTarget_ShutDown(void); + void ISPTarget_ConfigureRescueClock(void); + void ISPTarget_ConfigureSoftwareISP(const uint8_t SCKDuration); uint8_t ISPTarget_TransferSoftSPIByte(const uint8_t Byte); void ISPTarget_ChangeTargetResetLine(const bool ResetTarget); uint8_t ISPTarget_WaitWhileTargetBusy(void); diff --git a/Projects/AVRISP-MKII/Lib/V2Protocol.c b/Projects/AVRISP-MKII/Lib/V2Protocol.c index 673a0941c..208d7b77e 100644 --- a/Projects/AVRISP-MKII/Lib/V2Protocol.c +++ b/Projects/AVRISP-MKII/Lib/V2Protocol.c @@ -66,6 +66,7 @@ void V2Protocol_Init(void) TIMSK0 = (1 << OCIE0A); V2Params_LoadNonVolatileParamValues(); + ISPTarget_ConfigureRescueClock(); } /** Master V2 Protocol packet handler, for received V2 Protocol packets from a connected host. diff --git a/Projects/XPLAINBridge/Lib/SoftUART.c b/Projects/XPLAINBridge/Lib/SoftUART.c index 4b38a0bd2..5de365930 100644 --- a/Projects/XPLAINBridge/Lib/SoftUART.c +++ b/Projects/XPLAINBridge/Lib/SoftUART.c @@ -67,7 +67,7 @@ void SoftUART_Init(void) SoftUART_SetBaud(9600); /* Setup reception timer compare ISR */ - TIMSK1 = (1 << ICIE1); + TIMSK2 = (1 << ICIE2); /* Setup transmission timer compare ISR and start the timer */ TIMSK3 = (1 << ICIE3); @@ -81,7 +81,7 @@ ISR(INT0_vect, ISR_BLOCK) RX_BitsRemaining = 8; /* Reset the bit reception timer */ - TCNT1 = 0; + TCNT2 = 0; /* Check to see that the pin is still low (prevents glitches from starting a frame reception) */ if (!(SRXPIN & (1 << SRX))) @@ -90,12 +90,12 @@ ISR(INT0_vect, ISR_BLOCK) EIMSK = 0; /* Start the reception timer */ - TCCR1B = ((1 << CS10) | (1 << WGM13) | (1 << WGM12)); + TCCR2B = ((1 << CS20) | (1 << WGM23) | (1 << WGM22)); } } /** ISR to manage the reception of bits to the software UART. */ -ISR(TIMER1_CAPT_vect, ISR_BLOCK) +ISR(TIMER2_CAPT_vect, ISR_BLOCK) { /* Cache the current RX pin value for later checking */ uint8_t SRX_Cached = (SRXPIN & (1 << SRX)); @@ -114,7 +114,7 @@ ISR(TIMER1_CAPT_vect, ISR_BLOCK) else { /* Disable the reception timer as all data has now been received, re-enable start bit detection ISR */ - TCCR1B = 0; + TCCR2B = 0; EIFR = (1 << INTF0); EIMSK = (1 << INT0); -- cgit v1.2.3