Add structure padding to the appropriate descriptor structures to maintain correct...
[pub/USBasp.git] / Projects / AVRISP-MKII / Lib / XPROG / XPROGProtocol.c
index edd362b..ffc07ad 100644 (file)
@@ -1,13 +1,13 @@
 /*
              LUFA Library
-     Copyright (C) Dean Camera, 2010.
+     Copyright (C) Dean Camera, 2011.
 
   dean [at] fourwalledcubicle [dot] com
-      www.fourwalledcubicle.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
@@ -62,7 +62,7 @@ void XPROGProtocol_SetMode(void)
                uint8_t Protocol;
        } SetMode_XPROG_Params;
 
-       Endpoint_Read_Stream_LE(&SetMode_XPROG_Params, sizeof(SetMode_XPROG_Params), NO_STREAM_CALLBACK);
+       Endpoint_Read_Stream_LE(&SetMode_XPROG_Params, sizeof(SetMode_XPROG_Params), NULL);
 
        Endpoint_ClearOUT();
        Endpoint_SelectEndpoint(AVRISP_DATA_IN_EPNUM);
@@ -118,43 +118,9 @@ static void XPROGProtocol_EnterXPROGMode(void)
        bool NVMBusEnabled = false;
 
        if (XPROG_SelectedProtocol == XPRG_PROTOCOL_PDI)
-       {
-               /* 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 */
-               NVMBusEnabled = XMEGANVM_WaitWhileNVMBusBusy();
-       }
+         NVMBusEnabled = XMEGANVM_EnablePDI();
        else if (XPROG_SelectedProtocol == XPRG_PROTOCOL_TPI)
-       {
-               /* Enable TPI programming mode with the attached target */
-               XPROGTarget_EnableTargetTPI();
-
-               /* Lower direction change guard time to 0 USART bits */
-               XPROGTarget_SendByte(TPI_CMD_SSTCS | TPI_CTRL_REG);
-               XPROGTarget_SendByte(0x07);
-
-               /* Enable access to the XPROG NVM bus by sending the documented NVM access key to the device */
-               XPROGTarget_SendByte(TPI_CMD_SKEY);
-               for (uint8_t i = sizeof(TPI_NVMENABLE_KEY); i > 0; i--)
-                 XPROGTarget_SendByte(TPI_NVMENABLE_KEY[i - 1]);
-
-               /* Wait until the NVM bus becomes active */
-               NVMBusEnabled = TINYNVM_WaitWhileNVMBusBusy();
-       }
+         NVMBusEnabled = TINYNVM_EnableTPI();
 
        Endpoint_Write_Byte(CMD_XPROG);
        Endpoint_Write_Byte(XPRG_CMD_ENTER_PROGMODE);
@@ -172,29 +138,15 @@ static void XPROGProtocol_LeaveXPROGMode(void)
        Endpoint_SetEndpointDirection(ENDPOINT_DIR_IN);
 
        if (XPROG_SelectedProtocol == XPRG_PROTOCOL_PDI)
-       {
-               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 affect (silicon bug?) */
-               XPROGTarget_SendByte(PDI_CMD_STCS | PDI_RESET_REG);
-               XPROGTarget_SendByte(0x00);
-
-               XPROGTarget_DisableTargetPDI();
-       }
+         XMEGANVM_DisablePDI();
        else
-       {
-               TINYNVM_WaitWhileNVMBusBusy();
-
-               /* Clear the NVMEN bit in the TPI CONTROL register to disable TPI mode */
-               XPROGTarget_SendByte(TPI_CMD_SSTCS | TPI_CTRL_REG);
-               XPROGTarget_SendByte(0x00);
+         TINYNVM_DisableTPI();
 
-               XPROGTarget_DisableTargetTPI();
-       }
+       #if defined(XCK_RESCUE_CLOCK_ENABLE) && defined(ENABLE_ISP_PROTOCOL)
+       /* If the XCK rescue clock option is enabled, we need to restart it once the 
+        * XPROG mode has been exited, since the XPROG protocol stops it after use. */
+       ISPTarget_ConfigureRescueClock();
+       #endif
 
        Endpoint_Write_Byte(CMD_XPROG);
        Endpoint_Write_Byte(XPRG_CMD_LEAVE_PROGMODE);
@@ -213,7 +165,7 @@ static void XPROGProtocol_Erase(void)
                uint32_t Address;
        } Erase_XPROG_Params;
 
-       Endpoint_Read_Stream_LE(&Erase_XPROG_Params, sizeof(Erase_XPROG_Params), NO_STREAM_CALLBACK);
+       Endpoint_Read_Stream_LE(&Erase_XPROG_Params, sizeof(Erase_XPROG_Params), NULL);
        Erase_XPROG_Params.Address = SwapEndian_32(Erase_XPROG_Params.Address);
 
        Endpoint_ClearOUT();
@@ -293,11 +245,20 @@ static void XPROGProtocol_WriteMemory(void)
        } WriteMemory_XPROG_Params;
 
        Endpoint_Read_Stream_LE(&WriteMemory_XPROG_Params, (sizeof(WriteMemory_XPROG_Params) -
-                                                           sizeof(WriteMemory_XPROG_Params).ProgData), NO_STREAM_CALLBACK);
+                                                           sizeof(WriteMemory_XPROG_Params).ProgData), NULL);
        WriteMemory_XPROG_Params.Address = SwapEndian_32(WriteMemory_XPROG_Params.Address);
        WriteMemory_XPROG_Params.Length  = SwapEndian_16(WriteMemory_XPROG_Params.Length);
-       Endpoint_Read_Stream_LE(&WriteMemory_XPROG_Params.ProgData, WriteMemory_XPROG_Params.Length, NO_STREAM_CALLBACK);
+       Endpoint_Read_Stream_LE(&WriteMemory_XPROG_Params.ProgData, WriteMemory_XPROG_Params.Length, NULL);
 
+       // The driver will terminate transfers that are a round multiple of the endpoint bank in size with a ZLP, need
+       // to catch this and discard it before continuing on with packet processing to prevent communication issues
+       if (((sizeof(uint8_t) + sizeof(WriteMemory_XPROG_Params) - sizeof(WriteMemory_XPROG_Params.ProgData)) +
+           WriteMemory_XPROG_Params.Length) % AVRISP_DATA_EPSIZE == 0)
+       {
+               Endpoint_ClearOUT();
+               Endpoint_WaitUntilReady();
+       }
+       
        Endpoint_ClearOUT();
        Endpoint_SelectEndpoint(AVRISP_DATA_IN_EPNUM);
        Endpoint_SetEndpointDirection(ENDPOINT_DIR_IN);
@@ -376,7 +337,7 @@ static void XPROGProtocol_ReadMemory(void)
                uint16_t Length;
        } ReadMemory_XPROG_Params;
 
-       Endpoint_Read_Stream_LE(&ReadMemory_XPROG_Params, sizeof(ReadMemory_XPROG_Params), NO_STREAM_CALLBACK);
+       Endpoint_Read_Stream_LE(&ReadMemory_XPROG_Params, sizeof(ReadMemory_XPROG_Params), NULL);
        ReadMemory_XPROG_Params.Address = SwapEndian_32(ReadMemory_XPROG_Params.Address);
        ReadMemory_XPROG_Params.Length  = SwapEndian_16(ReadMemory_XPROG_Params.Length);
 
@@ -404,7 +365,7 @@ static void XPROGProtocol_ReadMemory(void)
        Endpoint_Write_Byte(ReturnStatus);
 
        if (ReturnStatus == XPRG_ERR_OK)
-         Endpoint_Write_Stream_LE(ReadBuffer, ReadMemory_XPROG_Params.Length, NO_STREAM_CALLBACK);
+         Endpoint_Write_Stream_LE(ReadBuffer, ReadMemory_XPROG_Params.Length, NULL);
 
        Endpoint_ClearIN();
 }
@@ -421,7 +382,7 @@ static void XPROGProtocol_ReadCRC(void)
                uint8_t CRCType;
        } ReadCRC_XPROG_Params;
 
-       Endpoint_Read_Stream_LE(&ReadCRC_XPROG_Params, sizeof(ReadCRC_XPROG_Params), NO_STREAM_CALLBACK);
+       Endpoint_Read_Stream_LE(&ReadCRC_XPROG_Params, sizeof(ReadCRC_XPROG_Params), NULL);
 
        Endpoint_ClearOUT();
        Endpoint_SelectEndpoint(AVRISP_DATA_IN_EPNUM);