Update UC3 platform driver support to use the bitmasks defined in the header files...
[pub/USBasp.git] / Projects / AVRISP-MKII / Lib / ISP / ISPTarget.c
index f4e9e3d..9e7260a 100644 (file)
@@ -1,13 +1,13 @@
 /*
              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
@@ -108,15 +108,16 @@ static uint16_t TimerCompareFromSCKDuration[] PROGMEM =
 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))
@@ -139,10 +140,10 @@ ISR(TIMER1_COMPA_vect, ISR_BLOCK)
        PINB |= (1 << 1);
 }
 
-/** Initialises the appropriate SPI driver (hardware or software, depending on the selected ISP speed) ready for
+/** Initializes the appropriate SPI driver (hardware or software, depending on the selected ISP speed) ready for
  *  communication with the attached target.
  */
-void ISPTarget_Init(void)
+void ISPTarget_EnableTargetISP(void)
 {
        uint8_t SCKDuration = V2Params_GetParameterValue(PARAM_SCK_DURATION);
 
@@ -160,58 +161,70 @@ void ISPTarget_Init(void)
                DDRB  |= ((1 << 1) | (1 << 2));
                PORTB |= ((1 << 0) | (1 << 3));
 
-               ISPTarget_ConfigureSoftwareISP(SCKDuration);
+               ISPTarget_ConfigureSoftwareSPI(SCKDuration);
        }
 }
 
 /** Shuts down the current selected SPI driver (hardware or software, depending on the selected ISP speed) so that no
  *  further communications can occur until the driver is re-initialized.
  */
-void ISPTarget_ShutDown(void)
+void ISPTarget_DisableTargetISP(void)
 {
        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();
        }
 }
 
-/** 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
+/** Configures the AVR to produce a 4MHz 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 mis-configured 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);
+       #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 / 4000000UL) - 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
+/** Configures the AVR's timer ready to produce software SPI 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)
+void ISPTarget_ConfigureSoftwareSPI(const uint8_t SCKDuration)
 {
-       /* Configure Timer 1 for software ISP using the specified SCK duration */
+       /* Configure Timer 1 for software SPI using the specified SCK duration */
        TIMSK1 = (1 << OCIE1A);
        TCNT1  = 0;
        OCR1A  = pgm_read_word(&TimerCompareFromSCKDuration[SCKDuration - sizeof(SPIMaskFromSCKDuration)]);
@@ -237,7 +250,7 @@ uint8_t ISPTarget_TransferSoftSPIByte(const uint8_t Byte)
 
        TCNT1  = 0;
        TCCR1B = ((1 << WGM12) | (1 << CS11));
-       while (SoftSPI_BitsRemaining && TimeoutTicksRemaining);
+       while (SoftSPI_BitsRemaining && !(TimeoutExpired));
        TCCR1B = 0;
 
        return SoftSPI_Data;
@@ -279,9 +292,9 @@ uint8_t ISPTarget_WaitWhileTargetBusy(void)
                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
@@ -331,9 +344,9 @@ uint8_t ISPTarget_WaitForProgComplete(const uint8_t ProgrammingMode,
                                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;