Update UC3 platform driver support to use the bitmasks defined in the header files...
[pub/USBasp.git] / Projects / AVRISP-MKII / Lib / XPROG / XMEGANVM.c
index 60e7552..e4f1186 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
 static void XMEGANVM_SendAddress(const uint32_t AbsoluteAddress)
 {
        /* Send the given 32-bit address to the target, LSB first */
-       XPROGTarget_SendByte(((uint8_t*)&AbsoluteAddress)[0]);
-       XPROGTarget_SendByte(((uint8_t*)&AbsoluteAddress)[1]);
-       XPROGTarget_SendByte(((uint8_t*)&AbsoluteAddress)[2]);
-       XPROGTarget_SendByte(((uint8_t*)&AbsoluteAddress)[3]);
+       XPROGTarget_SendByte(AbsoluteAddress &  0xFF);
+       XPROGTarget_SendByte(AbsoluteAddress >> 8);
+       XPROGTarget_SendByte(AbsoluteAddress >> 16);
+       XPROGTarget_SendByte(AbsoluteAddress >> 24);
 }
 
 /** Sends the given NVM register address to the target.
@@ -80,7 +80,7 @@ bool XMEGANVM_WaitWhileNVMBusBusy(void)
                uint8_t StatusRegister = XPROGTarget_ReceiveByte();
 
                /* We might have timed out waiting for the status register read response, check here */
-               if (!(TimeoutTicksRemaining))
+               if (TimeoutExpired)
                  return false;
 
                /* Check the status register read response to see if the NVM bus is enabled */
@@ -105,10 +105,11 @@ bool XMEGANVM_WaitWhileNVMControllerBusy(void)
        {
                /* Fetch the current status value via the pointer register (without auto-increment afterwards) */
                XPROGTarget_SendByte(PDI_CMD_LD | (PDI_POINTER_INDIRECT << 2) | PDI_DATSIZE_1BYTE);
+
                uint8_t StatusRegister = XPROGTarget_ReceiveByte();
 
                /* We might have timed out waiting for the status register read response, check here */
-               if (!(TimeoutTicksRemaining))
+               if (TimeoutExpired)
                  return false;
 
                /* Check to see if the BUSY flag is still set */
@@ -117,6 +118,48 @@ bool XMEGANVM_WaitWhileNVMControllerBusy(void)
        }
 }
 
+/** Enables the physical PDI interface on the target and enables access to the internal NVM controller.
+ *
+ *  \return Boolean true if the PDI interface was enabled successfully, false otherwise
+ */
+bool XMEGANVM_EnablePDI(void)
+{
+       /* Enable PDI programming mode with the attached target */
+       XPROGTarget_EnableTargetPDI();
+
+       /* Store the RESET key into the RESET PDI register to keep the XMEGA in reset */
+       XPROGTarget_SendByte(PDI_CMD_STCS | PDI_RESET_REG);
+       XPROGTarget_SendByte(PDI_RESET_KEY);
+
+       /* Lower direction change guard time to 0 USART bits */
+       XPROGTarget_SendByte(PDI_CMD_STCS | PDI_CTRL_REG);
+       XPROGTarget_SendByte(0x07);
+
+       /* Enable access to the XPROG NVM bus by sending the documented NVM access key to the device */
+       XPROGTarget_SendByte(PDI_CMD_KEY);
+       for (uint8_t i = sizeof(PDI_NVMENABLE_KEY); i > 0; i--)
+         XPROGTarget_SendByte(PDI_NVMENABLE_KEY[i - 1]);
+
+       /* Wait until the NVM bus becomes active */
+       return XMEGANVM_WaitWhileNVMBusBusy();
+}
+
+/** Removes access to the target's NVM controller and physically disables the target's physical PDI interface. */
+void XMEGANVM_DisablePDI(void)
+{
+       XMEGANVM_WaitWhileNVMBusBusy();
+
+       /* Clear the RESET key in the RESET PDI register to allow the XMEGA to run */
+       XPROGTarget_SendByte(PDI_CMD_STCS | PDI_RESET_REG);
+       XPROGTarget_SendByte(0x00);
+
+       /* Do it twice to make sure it takes effect (silicon bug?) */
+       XPROGTarget_SendByte(PDI_CMD_STCS | PDI_RESET_REG);
+       XPROGTarget_SendByte(0x00);
+
+       XPROGTarget_DisableTargetPDI();
+}
+
 /** Retrieves the CRC value of the given memory space.
  *
  *  \param[in]  CRCCommand  NVM CRC command to issue to the target
@@ -161,7 +204,7 @@ bool XMEGANVM_GetMemoryCRC(const uint8_t CRCCommand, uint32_t* const CRCDest)
        for (uint8_t i = 0; i < XMEGA_CRC_LENGTH; i++)
          ((uint8_t*)CRCDest)[i] = XPROGTarget_ReceiveByte();
 
-       return (TimeoutTicksRemaining != 0);
+       return (TimeoutExpired == false);
 }
 
 /** Reads memory from the target's memory spaces.
@@ -193,10 +236,10 @@ bool XMEGANVM_ReadMemory(const uint32_t ReadAddress, uint8_t* ReadBuffer, uint16
 
        /* Send a LD command with indirect access and post-increment to read out the bytes */
        XPROGTarget_SendByte(PDI_CMD_LD | (PDI_POINTER_INDIRECT_PI << 2) | PDI_DATSIZE_1BYTE);
-       while (ReadSize-- && TimeoutTicksRemaining)
+       while (ReadSize-- && !(TimeoutExpired))
          *(ReadBuffer++) = XPROGTarget_ReceiveByte();
 
-       return (TimeoutTicksRemaining != 0);
+       return (TimeoutExpired == false);
 }
 
 /** Writes byte addressed memory to the target's memory spaces.