diff options
author | Dean Camera <dean@fourwalledcubicle.com> | 2010-11-02 07:57:23 +0000 |
---|---|---|
committer | Dean Camera <dean@fourwalledcubicle.com> | 2010-11-02 07:57:23 +0000 |
commit | 3bf760ad7d8bcc06c9145121786f3644995fae87 (patch) | |
tree | 96583e3a1c8aae9fd768710e2590badd5b4bd524 /Projects/AVRISP-MKII/Lib/ISP | |
parent | 40db485c7967c584eb9fe855e744ed0dc6fe8bae (diff) | |
download | lufa-3bf760ad7d8bcc06c9145121786f3644995fae87.tar.gz lufa-3bf760ad7d8bcc06c9145121786f3644995fae87.tar.bz2 lufa-3bf760ad7d8bcc06c9145121786f3644995fae87.zip |
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.
Diffstat (limited to 'Projects/AVRISP-MKII/Lib/ISP')
-rw-r--r-- | Projects/AVRISP-MKII/Lib/ISP/ISPProtocol.c | 12 | ||||
-rw-r--r-- | Projects/AVRISP-MKII/Lib/ISP/ISPTarget.c | 49 | ||||
-rw-r--r-- | Projects/AVRISP-MKII/Lib/ISP/ISPTarget.h | 2 |
3 files changed, 46 insertions, 17 deletions
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); |