/*
LUFA Library
- Copyright (C) Dean Camera, 2010.
+ Copyright (C) Dean Camera, 2011.
dean [at] fourwalledcubicle [dot] com
www.lufa-lib.org
*/
/*
- Copyright 2010 Dean Camera (dean [at] fourwalledcubicle [dot] com)
+ Copyright 2011 Dean Camera (dean [at] fourwalledcubicle [dot] com)
Permission to use, copy, modify, distribute, and sell this
software and its documentation for any purpose is hereby granted
bool HardwareSPIMode = true;
/** Software SPI data register for sending and receiving */
-volatile uint8_t SoftSPI_Data;
+static volatile uint8_t SoftSPI_Data;
/** Number of bits left to transfer in the software SPI driver */
-volatile uint8_t SoftSPI_BitsRemaining;
+static volatile uint8_t SoftSPI_BitsRemaining;
/** ISR to handle software SPI transmission and reception */
ISR(TIMER1_COMPA_vect, ISR_BLOCK)
{
+ /* Check if rising edge (output next bit) or falling edge (read in next bit) */
if (!(PINB & (1 << 1)))
{
if (SoftSPI_Data & (1 << 7))
{
if (HardwareSPIMode)
{
- SPI_ShutDown();
+ SPI_Disable();
}
else
{
DDRB &= ~((1 << 1) | (1 << 2));
PORTB &= ~((1 << 0) | (1 << 3));
+ /* Must re-enable rescue clock once software ISP has exited, as the timer for the rescue clock is
+ * re-purposed for software SPI */
ISPTarget_ConfigureRescueClock();
}
}
*/
void ISPTarget_ConfigureRescueClock(void)
{
- /* Configure OCR1A as an output for the specified AVR model */
- #if defined(USB_SERIES_2_AVR)
- DDRC |= (1 << 6);
+ #if defined(XCK_RESCUE_CLOCK_ENABLE)
+ /* Configure XCK as an output for the specified AVR model */
+ DDRD |= (1 << 5);
+
+ /* Start USART to generate a 4MHz clock on the XCK pin */
+ UBRR1 = ((F_CPU / 2 / ISP_RESCUE_CLOCK_SPEED) - 1);
+ UCSR1B = (1 << TXEN1);
+ UCSR1C = (1 << UMSEL10) | (1 << UPM11) | (1 << USBS1) | (1 << UCSZ11) | (1 << UCSZ10) | (1 << UCPOL1);
#else
- DDRB |= (1 << 5);
+ /* 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 4MHz clock on the OCR1A pin */
+ TIMSK1 = 0;
+ TCNT1 = 0;
+ OCR1A = ((F_CPU / 2 / ISP_RESCUE_CLOCK_SPEED) - 1);
+ TCCR1A = (1 << COM1A0);
+ TCCR1B = ((1 << WGM12) | (1 << CS10));
#endif
-
- /* Start Timer 1 to generate a 4MHz clock on the OCR1A pin */
- TIMSK1 = 0;
- TCNT1 = 0;
- OCR1A = ((F_CPU / 2 / ISP_RESCUE_CLOCK_SPEED) - 1);
- TCCR1A = (1 << COM1A0);
- TCCR1B = ((1 << WGM12) | (1 << CS10));
}
/** Configures the AVR's timer ready to produce software ISP for the slower ISP speeds that
TCNT1 = 0;
TCCR1B = ((1 << WGM12) | (1 << CS11));
- while (SoftSPI_BitsRemaining && TimeoutTicksRemaining);
+ while (SoftSPI_BitsRemaining && !(TimeoutExpired));
TCCR1B = 0;
return SoftSPI_Data;
ISPTarget_SendByte(0x00);
ISPTarget_SendByte(0x00);
}
- while ((ISPTarget_ReceiveByte() & 0x01) && TimeoutTicksRemaining);
+ while ((ISPTarget_ReceiveByte() & 0x01) && !(TimeoutExpired));
- return TimeoutTicksRemaining ? STATUS_CMD_OK : STATUS_RDY_BSY_TOUT;
+ return (TimeoutExpired) ? STATUS_RDY_BSY_TOUT : STATUS_CMD_OK;
}
/** Sends a low-level LOAD EXTENDED ADDRESS command to the target, for addressing of memory beyond the
ISPTarget_SendByte(PollAddress >> 8);
ISPTarget_SendByte(PollAddress & 0xFF);
}
- while ((ISPTarget_TransferByte(0x00) == PollValue) && TimeoutTicksRemaining);
+ while ((ISPTarget_TransferByte(0x00) == PollValue) && !(TimeoutExpired));
- if (!(TimeoutTicksRemaining))
+ if (TimeoutExpired)
ProgrammingStatus = STATUS_CMD_TOUT;
break;