mirror of
https://github.com/qmk/qmk_firmware.git
synced 2025-07-17 21:22:05 +00:00
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.
This commit is contained in:
parent
40db485c79
commit
3bf760ad7d
@ -65,6 +65,7 @@
|
|||||||
* - All LowLevel demos changed to use the constants and types defined in the USB class drivers
|
* - 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
|
* - 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
|
* - 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>
|
* <b>Fixed:</b>
|
||||||
* - Fixed USB_GetHIDReportItemInfo() function modifying the given report item's data when the report item does not exist
|
* - Fixed USB_GetHIDReportItemInfo() function modifying the given report item's data when the report item does not exist
|
||||||
|
@ -105,9 +105,9 @@
|
|||||||
* </tr>
|
* </tr>
|
||||||
* </table>
|
* </table>
|
||||||
*
|
*
|
||||||
* In addition, the AVR's XCK pin will generate a .5MHz clock when SPI programming is used, to act as an external
|
* In addition, the AVR's OCR1A pin will generate a .5MHz clock, to act as an external rescue device clock
|
||||||
* device clock if the fuses have been mis-set. To use the recovery clock, connect XCK to the target AVR's XTAL1
|
* if the fuses have been mis-set. To use the recovery clock, connect the OCR1A pin of the USB AVR to the target
|
||||||
* pin, and set the ISP programming speed to 125KHz or below.
|
* 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>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>
|
* <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;
|
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 */
|
/* Perform execution delay, initialize SPI bus */
|
||||||
ISPProtocol_DelayMS(Enter_ISP_Params.ExecutionDelayMS);
|
ISPProtocol_DelayMS(Enter_ISP_Params.ExecutionDelayMS);
|
||||||
ISPTarget_Init();
|
ISPTarget_Init();
|
||||||
@ -127,12 +121,6 @@ void ISPProtocol_LeaveISPMode(void)
|
|||||||
ISPTarget_ShutDown();
|
ISPTarget_ShutDown();
|
||||||
ISPProtocol_DelayMS(Leave_ISP_Params.PostDelayMS);
|
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(CMD_LEAVE_PROGMODE_ISP);
|
||||||
Endpoint_Write_Byte(STATUS_CMD_OK);
|
Endpoint_Write_Byte(STATUS_CMD_OK);
|
||||||
Endpoint_ClearIN();
|
Endpoint_ClearIN();
|
||||||
|
@ -119,7 +119,7 @@ ISR(TIMER1_COMPA_vect, ISR_BLOCK)
|
|||||||
{
|
{
|
||||||
if (!(PINB & (1 << 1)))
|
if (!(PINB & (1 << 1)))
|
||||||
{
|
{
|
||||||
if (SoftSPI_Data & 0x80)
|
if (SoftSPI_Data & (1 << 7))
|
||||||
PORTB |= (1 << 2);
|
PORTB |= (1 << 2);
|
||||||
else
|
else
|
||||||
PORTB &= ~(1 << 2);
|
PORTB &= ~(1 << 2);
|
||||||
@ -132,10 +132,11 @@ ISR(TIMER1_COMPA_vect, ISR_BLOCK)
|
|||||||
TCCR1B = 0;
|
TCCR1B = 0;
|
||||||
|
|
||||||
if (PINB & (1 << 3))
|
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
|
/** 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));
|
DDRB |= ((1 << 1) | (1 << 2));
|
||||||
PORTB |= ((1 << 0) | (1 << 3));
|
PORTB |= ((1 << 0) | (1 << 3));
|
||||||
|
|
||||||
TIMSK1 = (1 << OCIE1A);
|
ISPTarget_ConfigureSoftwareISP(SCKDuration);
|
||||||
OCR1A = pgm_read_word(&TimerCompareFromSCKDuration[SCKDuration - sizeof(SPIMaskFromSCKDuration)]);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -177,9 +177,48 @@ void ISPTarget_ShutDown(void)
|
|||||||
{
|
{
|
||||||
DDRB &= ~((1 << 1) | (1 << 2));
|
DDRB &= ~((1 << 1) | (1 << 2));
|
||||||
PORTB &= ~((1 << 0) | (1 << 3));
|
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.
|
/** 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
|
* \param[in] Byte Byte of data to send to the attached target
|
||||||
|
@ -68,6 +68,8 @@
|
|||||||
/* Function Prototypes: */
|
/* Function Prototypes: */
|
||||||
void ISPTarget_Init(void);
|
void ISPTarget_Init(void);
|
||||||
void ISPTarget_ShutDown(void);
|
void ISPTarget_ShutDown(void);
|
||||||
|
void ISPTarget_ConfigureRescueClock(void);
|
||||||
|
void ISPTarget_ConfigureSoftwareISP(const uint8_t SCKDuration);
|
||||||
uint8_t ISPTarget_TransferSoftSPIByte(const uint8_t Byte);
|
uint8_t ISPTarget_TransferSoftSPIByte(const uint8_t Byte);
|
||||||
void ISPTarget_ChangeTargetResetLine(const bool ResetTarget);
|
void ISPTarget_ChangeTargetResetLine(const bool ResetTarget);
|
||||||
uint8_t ISPTarget_WaitWhileTargetBusy(void);
|
uint8_t ISPTarget_WaitWhileTargetBusy(void);
|
||||||
|
@ -66,6 +66,7 @@ void V2Protocol_Init(void)
|
|||||||
TIMSK0 = (1 << OCIE0A);
|
TIMSK0 = (1 << OCIE0A);
|
||||||
|
|
||||||
V2Params_LoadNonVolatileParamValues();
|
V2Params_LoadNonVolatileParamValues();
|
||||||
|
ISPTarget_ConfigureRescueClock();
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Master V2 Protocol packet handler, for received V2 Protocol packets from a connected host.
|
/** 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);
|
SoftUART_SetBaud(9600);
|
||||||
|
|
||||||
/* Setup reception timer compare ISR */
|
/* Setup reception timer compare ISR */
|
||||||
TIMSK1 = (1 << ICIE1);
|
TIMSK2 = (1 << ICIE2);
|
||||||
|
|
||||||
/* Setup transmission timer compare ISR and start the timer */
|
/* Setup transmission timer compare ISR and start the timer */
|
||||||
TIMSK3 = (1 << ICIE3);
|
TIMSK3 = (1 << ICIE3);
|
||||||
@ -81,7 +81,7 @@ ISR(INT0_vect, ISR_BLOCK)
|
|||||||
RX_BitsRemaining = 8;
|
RX_BitsRemaining = 8;
|
||||||
|
|
||||||
/* Reset the bit reception timer */
|
/* 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) */
|
/* Check to see that the pin is still low (prevents glitches from starting a frame reception) */
|
||||||
if (!(SRXPIN & (1 << SRX)))
|
if (!(SRXPIN & (1 << SRX)))
|
||||||
@ -90,12 +90,12 @@ ISR(INT0_vect, ISR_BLOCK)
|
|||||||
EIMSK = 0;
|
EIMSK = 0;
|
||||||
|
|
||||||
/* Start the reception timer */
|
/* 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 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 */
|
/* Cache the current RX pin value for later checking */
|
||||||
uint8_t SRX_Cached = (SRXPIN & (1 << SRX));
|
uint8_t SRX_Cached = (SRXPIN & (1 << SRX));
|
||||||
@ -114,7 +114,7 @@ ISR(TIMER1_CAPT_vect, ISR_BLOCK)
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
/* Disable the reception timer as all data has now been received, re-enable start bit detection ISR */
|
/* Disable the reception timer as all data has now been received, re-enable start bit detection ISR */
|
||||||
TCCR1B = 0;
|
TCCR2B = 0;
|
||||||
EIFR = (1 << INTF0);
|
EIFR = (1 << INTF0);
|
||||||
EIMSK = (1 << INT0);
|
EIMSK = (1 << INT0);
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user