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.

Dean Camera 15 years ago
parent 40db485c79
commit 3bf760ad7d

@ -65,6 +65,7 @@
* - All LowLevel demos changed to use the constants and types defined in the USB class drivers
* - Changed AudioInput and AudioOutput demos to reload the next sample via an interrupt rather than polling the sample timer
* - The MIDI class drivers now automatically flushes the MIDI interface when the MIDI class driver's USBTask() function is called
* - Rescue clock of the AVRISP-MKII moved to the AVR's OCR1A pin, so that the clock can be generated at all times
*
* <b>Fixed:</b>
* - Fixed USB_GetHIDReportItemInfo() function modifying the given report item's data when the report item does not exist

@ -105,9 +105,9 @@
* </tr>
* </table>
*
* 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).
*
* <b><sup>1</sup></b> <i>Optional, see \ref SSec_Options section - for USB AVRs with ADC modules only</i> \n
* <b><sup>2</sup></b> <i>See AUX line related tokens in the \ref SSec_Options section</i>

@ -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();

@ -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

@ -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);

@ -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.

@ -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);

Loading…
Cancel
Save