Clean up and add more comments to the AVRISP-MKII project. Make sure the SPI_MULTI...
authorDean Camera <dean@fourwalledcubicle.com>
Sun, 17 Jan 2010 04:39:33 +0000 (04:39 +0000)
committerDean Camera <dean@fourwalledcubicle.com>
Sun, 17 Jan 2010 04:39:33 +0000 (04:39 +0000)
LUFA/Drivers/USB/HighLevel/Events.h
Projects/AVRISP-MKII/Descriptors.c
Projects/AVRISP-MKII/Lib/ISP/ISPProtocol.c
Projects/AVRISP-MKII/Lib/V2Protocol.c
Projects/AVRISP-MKII/Lib/V2ProtocolParams.c
Projects/AVRISP-MKII/Lib/V2ProtocolParams.h
Projects/AVRISP-MKII/Lib/XPROG/XMEGANVM.c
Projects/AVRISP-MKII/Lib/XPROG/XMEGANVM.h
Projects/AVRISP-MKII/Lib/XPROG/XPROGProtocol.c
Projects/AVRISP-MKII/Lib/XPROG/XPROGProtocol.h

index 84b951e..08727d7 100644 (file)
@@ -40,8 +40,8 @@
  *  listed here. If an event with no user-associated handler is fired within the library, it by default maps to an\r
  *  internal empty stub function.\r
  *\r
- *  Each event must only have one associated event handler, but can be raised by multiple sources by calling the event\r
- *  name just like any regular C function (with any required event parameters).\r
+ *  Each event must only have one associated event handler, but can be raised by multiple sources by calling the\r
+ *  event handler function (with any required event parameters).\r
  *\r
  *  @{\r
  */\r
                         *  \note This event does not exist if the USB_HOST_ONLY token is supplied to the compiler (see\r
                         *        \ref Group_USBManagement documentation).\r
                         *\r
+                        *  \note This event does not exist on the series 2 USB AVRs when the NO_LIMITED_CONTROLLER_CONNECT\r
+                        *        compile time token is not set - see \ref EVENT_USB_Device_Disconnect.\r
+                        *\r
                         *  \see \ref EVENT_USB_Device_WakeUp() event for accompanying Wake Up event.\r
                         */\r
                        void EVENT_USB_Device_Suspend(void);\r
 \r
                        /** Event for USB wake up. This event fires when a the USB interface is suspended while in device\r
                         *  mode, and the host wakes up the device by supplying Start Of Frame pulses. This is generally\r
-                        *  hooked to pull the user application out of a lowe power state and back into normal operating\r
+                        *  hooked to pull the user application out of a low power state and back into normal operating\r
                         *  mode. If the USB interface is enumerated with the \ref USB_OPT_AUTO_PLL option set, the library\r
                         *  will automatically restart the USB PLL before the event is fired.\r
                         *\r
                         *  \note This event does not exist if the USB_HOST_ONLY token is supplied to the compiler (see\r
                         *        \ref Group_USBManagement documentation).\r
                         *\r
+                        *  \note This event does not exist on the series 2 USB AVRs when the NO_LIMITED_CONTROLLER_CONNECT\r
+                        *        compile time token is not set - see \ref EVENT_USB_Device_Connect.\r
+                        *\r
                         *  \see \ref EVENT_USB_Device_Suspend() event for accompanying Suspend event.\r
                         */\r
                        void EVENT_USB_Device_WakeUp(void);\r
index f89cfae..6b4264f 100644 (file)
@@ -151,9 +151,9 @@ USB_Descriptor_String_t PROGMEM ManufacturerString =
  */\r
 USB_Descriptor_String_t PROGMEM ProductString =\r
 {\r
-       .Header                 = {.Size = USB_STRING_LEN(33), .Type = DTYPE_String},\r
+       .Header                 = {.Size = USB_STRING_LEN(22), .Type = DTYPE_String},\r
                \r
-       .UnicodeString          = L"LUFA AVRISP MkII Clone Programmer"\r
+       .UnicodeString          = L"LUFA AVRISP MkII Clone"\r
 };\r
 \r
 USB_Descriptor_String_t PROGMEM SerialString =\r
index 3a7e640..936c9ab 100644 (file)
@@ -65,7 +65,9 @@ void ISPProtocol_EnterISPMode(void)
 \r
        ISPProtocol_DelayMS(Enter_ISP_Params.ExecutionDelayMS); \r
        SPI_Init(ISPTarget_GetSPIPrescalerMask() | SPI_SCK_LEAD_RISING | SPI_SAMPLE_LEADING | SPI_MODE_MASTER);\r
-               \r
+\r
+       /* Continuously attempt to synchronize with the target until either the number of attempts specified\r
+        * by the host has exceeded, or the the device sends back the expected response values */\r
        while (Enter_ISP_Params.SynchLoops-- && (ResponseStatus == STATUS_CMD_FAILED))\r
        {\r
                uint8_t ResponseBytes[4];\r
@@ -110,6 +112,7 @@ void ISPProtocol_LeaveISPMode(void)
        Endpoint_ClearOUT();\r
        Endpoint_SetEndpointDirection(ENDPOINT_DIR_IN);\r
 \r
+       /* Perform pre-exit delay, release the target /RESET, disable the SPI bus and perform the post-exit delay */\r
        ISPProtocol_DelayMS(Leave_ISP_Params.PreDelayMS);\r
        ISPTarget_ChangeTargetResetLine(false);\r
        SPI_ShutDown();\r
@@ -166,6 +169,9 @@ void ISPProtocol_ProgramMemory(uint8_t V2Command)
                                                                            Write_Memory_Params.PollValue2;\r
        uint8_t* NextWriteByte = Write_Memory_Params.ProgData;\r
 \r
+       /* Check to see if the host has issued a SET ADDRESS command and we haven't sent a\r
+        * LOAD EXTENDED ADDRESS command (if needed, used when operating beyond the 128KB\r
+        * FLASH barrier) */\r
        if (MustSetAddress)\r
        {\r
                if (CurrentAddress & (1UL << 31))\r
@@ -174,6 +180,7 @@ void ISPProtocol_ProgramMemory(uint8_t V2Command)
                MustSetAddress = false;\r
        }\r
 \r
+       /* Check the programming mode desired by the host, either Paged or Word memory writes */\r
        if (Write_Memory_Params.ProgrammingMode & PROG_MODE_PAGED_WRITES_MASK)\r
        {\r
                uint16_t StartAddress = (CurrentAddress & 0xFFFF);\r
@@ -184,16 +191,16 @@ void ISPProtocol_ProgramMemory(uint8_t V2Command)
                        bool    IsOddByte   = (CurrentByte & 0x01);\r
                        uint8_t ByteToWrite = *(NextWriteByte++);\r
                \r
-                       if (IsOddByte && (V2Command == CMD_PROGRAM_FLASH_ISP))\r
-                         Write_Memory_Params.ProgrammingCommands[0] |=  READ_WRITE_HIGH_BYTE_MASK;\r
-                       else\r
-                         Write_Memory_Params.ProgrammingCommands[0] &= ~READ_WRITE_HIGH_BYTE_MASK;\r
-                         \r
                        SPI_SendByte(Write_Memory_Params.ProgrammingCommands[0]);\r
                        SPI_SendByte(CurrentAddress >> 8);\r
                        SPI_SendByte(CurrentAddress & 0xFF);\r
                        SPI_SendByte(ByteToWrite);\r
                        \r
+                       /* AVR FLASH addressing requires us to modify the write command based on if we are writing a high\r
+                        * or low byte at the current word address */\r
+                       Write_Memory_Params.ProgrammingCommands[0] ^= READ_WRITE_HIGH_BYTE_MASK;\r
+\r
+                       /* Check to see the write completion method, to see if we have a valid polling address */\r
                        if (!(PollAddress) && (ByteToWrite != PollValue))\r
                        {\r
                                if (IsOddByte && (V2Command == CMD_PROGRAM_FLASH_ISP))\r
@@ -289,6 +296,9 @@ void ISPProtocol_ReadMemory(uint8_t V2Command)
        Endpoint_Write_Byte(V2Command);\r
        Endpoint_Write_Byte(STATUS_CMD_OK);\r
        \r
+       /* Check to see if the host has issued a SET ADDRESS command and we haven't sent a\r
+        * LOAD EXTENDED ADDRESS command (if needed, used when operating beyond the 128KB\r
+        * FLASH barrier) */\r
        if (MustSetAddress)\r
        {\r
                if (CurrentAddress & (1UL << 31))\r
@@ -297,28 +307,30 @@ void ISPProtocol_ReadMemory(uint8_t V2Command)
                MustSetAddress = false;\r
        }\r
 \r
+       /* Read each byte from the device and write them to the packet for the host */\r
        for (uint16_t CurrentByte = 0; CurrentByte < Read_Memory_Params.BytesToRead; CurrentByte++)\r
        {\r
-               bool IsOddByte = (CurrentByte & 0x01);\r
-\r
-               if (IsOddByte && (V2Command == CMD_READ_FLASH_ISP))\r
-                 Read_Memory_Params.ReadMemoryCommand |=  READ_WRITE_HIGH_BYTE_MASK;\r
-               else\r
-                 Read_Memory_Params.ReadMemoryCommand &= ~READ_WRITE_HIGH_BYTE_MASK;\r
-\r
+               /* Read the next byte from the desired memory space in the device */\r
                SPI_SendByte(Read_Memory_Params.ReadMemoryCommand);\r
                SPI_SendByte(CurrentAddress >> 8);\r
                SPI_SendByte(CurrentAddress & 0xFF);\r
                Endpoint_Write_Byte(SPI_ReceiveByte());\r
                \r
-               /* Check if the endpoint bank is currently full */\r
+               /* Check if the endpoint bank is currently full, if so send the packet */\r
                if (!(Endpoint_IsReadWriteAllowed()))\r
                {\r
                        Endpoint_ClearIN();\r
                        Endpoint_WaitUntilReady();\r
                }\r
                \r
-               if ((IsOddByte && (V2Command == CMD_READ_FLASH_ISP)) || (V2Command == CMD_READ_EEPROM_ISP))\r
+               /* AVR FLASH addressing requires us to modify the read command based on if we are reading a high\r
+                * or low byte at the current word address */\r
+               if (V2Command == CMD_READ_FLASH_ISP)\r
+                 Read_Memory_Params.ReadMemoryCommand ^= READ_WRITE_HIGH_BYTE_MASK;\r
+\r
+               /* Only increment the current address if we have read both bytes in the current word when in FLASH\r
+                * read mode, or for each byte when in EEPROM read mode */               \r
+               if (((CurrentByte & 0x01) && (V2Command == CMD_READ_FLASH_ISP)) || (V2Command == CMD_READ_EEPROM_ISP))\r
                  CurrentAddress++;\r
        }\r
 \r
@@ -353,9 +365,11 @@ void ISPProtocol_ChipErase(void)
        \r
        uint8_t ResponseStatus = STATUS_CMD_OK;\r
        \r
+       /* Send the chip erase commands as given by the host to the device */\r
        for (uint8_t SByte = 0; SByte < sizeof(Erase_Chip_Params.EraseCommandBytes); SByte++)\r
          SPI_SendByte(Erase_Chip_Params.EraseCommandBytes[SByte]);\r
 \r
+       /* Use appropriate command completion check as given by the host (delay or busy polling) */\r
        if (!(Erase_Chip_Params.PollMethod))\r
          ISPProtocol_DelayMS(Erase_Chip_Params.EraseDelayMS);\r
        else\r
@@ -385,7 +399,8 @@ void ISPProtocol_ReadFuseLockSigOSCCAL(uint8_t V2Command)
        Endpoint_SetEndpointDirection(ENDPOINT_DIR_IN);\r
 \r
        uint8_t ResponseBytes[4];\r
-               \r
+\r
+       /* Send the Fuse or Lock byte read commands as given by the host to the device, store response */\r
        for (uint8_t RByte = 0; RByte < sizeof(ResponseBytes); RByte++)\r
          ResponseBytes[RByte] = SPI_TransferByte(Read_FuseLockSigOSCCAL_Params.ReadCommandBytes[RByte]);\r
                \r
@@ -413,6 +428,7 @@ void ISPProtocol_WriteFuseLock(uint8_t V2Command)
        Endpoint_ClearOUT();\r
        Endpoint_SetEndpointDirection(ENDPOINT_DIR_IN);\r
 \r
+       /* Send the Fuse or Lock byte program commands as given by the host to the device */\r
        for (uint8_t SByte = 0; SByte < sizeof(Write_FuseLockSig_Params.WriteCommandBytes); SByte++)\r
          SPI_SendByte(Write_FuseLockSig_Params.WriteCommandBytes[SByte]);\r
                \r
@@ -463,12 +479,29 @@ void ISPProtocol_SPIMulti(void)
                  Endpoint_Write_Byte(SPI_TransferByte(SPI_Multi_Params.TxData[CurrTxPos++]));\r
                else\r
                  Endpoint_Write_Byte(SPI_ReceiveByte());\r
+                 \r
+               /* Check to see if we have filled the endpoint bank and need to send the packet */\r
+               if (!(Endpoint_IsReadWriteAllowed()))\r
+               {\r
+                       Endpoint_ClearIN();\r
+                       Endpoint_WaitUntilReady();\r
+               }\r
                \r
                CurrRxPos++;\r
        }       \r
        \r
        Endpoint_Write_Byte(STATUS_CMD_OK);\r
+\r
+       bool IsEndpointFull = !(Endpoint_IsReadWriteAllowed());\r
        Endpoint_ClearIN();\r
+       \r
+       /* Ensure last packet is a short packet to terminate the transfer */\r
+       if (IsEndpointFull)\r
+       {\r
+               Endpoint_WaitUntilReady();      \r
+               Endpoint_ClearIN();\r
+               Endpoint_WaitUntilReady();      \r
+       }\r
 }\r
 \r
 #endif
\ No newline at end of file
index 093c078..976f24b 100644 (file)
@@ -58,6 +58,7 @@ void V2Protocol_ProcessCommand(void)
 {\r
        uint8_t V2Command = Endpoint_Read_Byte();\r
        \r
+       /* Set total command processing timeout value, enable timeout management interrupt */\r
        TimeoutMSRemaining = COMMAND_TIMEOUT_MS;\r
        TIMSK0 |= (1 << OCIE0A);\r
 \r
@@ -121,6 +122,7 @@ void V2Protocol_ProcessCommand(void)
                        break;\r
        }\r
                \r
+       /* Disable timeout management interrupt once processing has completed */\r
        TIMSK0 &= ~(1 << OCIE0A);\r
 \r
        Endpoint_WaitUntilReady();\r
@@ -162,8 +164,8 @@ static void V2Protocol_SignOn(void)
        Endpoint_ClearIN();\r
 }\r
 \r
-/** Handler for the CMD_RESET_PROTECTION command, currently implemented as a dummy ACK function\r
- *  as no ISP short-circuit protection is currently implemented.\r
+/** Handler for the CMD_RESET_PROTECTION command, implemented as a dummy ACK function as\r
+ *  no target short-circuit protection is currently implemented.\r
  */\r
 static void V2Protocol_ResetProtection(void)\r
 {\r
index c2595e7..0078851 100644 (file)
@@ -170,7 +170,7 @@ static ParameterItem_t* V2Params_GetParamFromTable(const uint8_t ParamID)
        ParameterItem_t* CurrTableItem = ParameterTable;\r
 \r
        /* Find the parameter in the parameter table if present */\r
-       for (uint8_t TableIndex = 0; TableIndex < (sizeof(ParameterTable) / sizeof(ParameterTable[0])); TableIndex++)\r
+       for (uint8_t TableIndex = 0; TableIndex < TABLE_PARAM_COUNT; TableIndex++)\r
        {\r
                if (ParamID == CurrTableItem->ParamID)\r
                  return CurrTableItem;\r
index 04e32fe..995468a 100644 (file)
 \r
        /* Macros: */\r
                /** Parameter privilege mask to allow the host PC to read the parameter's value */\r
-               #define PARAM_PRIV_READ   (1 << 0)\r
+               #define PARAM_PRIV_READ     (1 << 0)\r
 \r
                /** Parameter privilege mask to allow the host PC to change the parameter's value */\r
-               #define PARAM_PRIV_WRITE  (1 << 1)\r
+               #define PARAM_PRIV_WRITE    (1 << 1)\r
+               \r
+               /** Total number of parameters in the parameter table */\r
+               #define TABLE_PARAM_COUNT   (sizeof(ParameterTable) / sizeof(ParameterTable[0]))\r
 \r
        /* Type Defines: */\r
                /** Type define for a parameter table entry indicating a PC readable or writable device parameter. */\r
index c23b9d7..573f8fd 100644 (file)
@@ -136,24 +136,18 @@ bool XMEGANVM_GetMemoryCRC(const uint8_t CRCCommand, uint32_t* const CRCDest)
        if (!(XMEGANVM_WaitWhileNVMControllerBusy()))\r
          return false;\r
        \r
-       uint32_t MemoryCRC = 0;\r
-       \r
-       /* Read the first generated CRC byte value */\r
-       XPROGTarget_SendByte(PDI_CMD_LDS | (PDI_DATSIZE_4BYTES << 2));\r
+       /* Load the PDI pointer register with the DAT0 register start address */\r
+       XPROGTarget_SendByte(PDI_CMD_ST | (PDI_POINTER_DIRECT << 2) | PDI_DATSIZE_4BYTES);\r
        XMEGANVM_SendNVMRegAddress(XMEGA_NVM_REG_DAT0);\r
-       MemoryCRC  = XPROGTarget_ReceiveByte();\r
-\r
-       /* Read the second generated CRC byte value */\r
-       XPROGTarget_SendByte(PDI_CMD_LDS | (PDI_DATSIZE_4BYTES << 2));\r
-       XMEGANVM_SendNVMRegAddress(XMEGA_NVM_REG_DAT1);\r
-       MemoryCRC |= ((uint16_t)XPROGTarget_ReceiveByte() << 8);\r
 \r
-       /* Read the third generated CRC byte value */\r
-       XPROGTarget_SendByte(PDI_CMD_LDS | (PDI_DATSIZE_4BYTES << 2));\r
-       XMEGANVM_SendNVMRegAddress(XMEGA_NVM_REG_DAT2);\r
-       MemoryCRC |= ((uint32_t)XPROGTarget_ReceiveByte() << 16);\r
+       /* Send the REPEAT command to grab the CRC bytes */\r
+       XPROGTarget_SendByte(PDI_CMD_REPEAT | PDI_DATSIZE_1BYTE);\r
+       XPROGTarget_SendByte(XMEGA_CRC_LENGTH - 1);\r
        \r
-       *CRCDest = MemoryCRC;\r
+       /* Read in the CRC bytes from the target */\r
+       XPROGTarget_SendByte(PDI_CMD_LD | (PDI_POINTER_INDIRECT_PI << 2) | PDI_DATSIZE_1BYTE);\r
+       for (uint8_t i = 0; i < XMEGA_CRC_LENGTH; i++)\r
+         ((uint8_t*)CRCDest)[i] = XPROGTarget_ReceiveByte();\r
        \r
        return true;\r
 }\r
index 63fe05c..cbd9e26 100644 (file)
@@ -56,6 +56,8 @@
                #endif\r
 \r
        /* Defines: */\r
+               #define XMEGA_CRC_LENGTH                     3\r
+       \r
                #define XMEGA_NVM_REG_ADDR0                  0x00\r
                #define XMEGA_NVM_REG_ADDR1                  0x01\r
                #define XMEGA_NVM_REG_ADDR2                  0x02\r
index 9c6ee7e..1be159c 100644 (file)
@@ -38,7 +38,7 @@
 \r
 #if defined(ENABLE_XPROG_PROTOCOL) || defined(__DOXYGEN__)\r
 /** Base absolute address for the target's NVM controller for PDI programming */\r
-uint32_t XPROG_Param_NVMBase    = 0x010001C0;\r
+uint32_t XPROG_Param_NVMBase = 0x010001C0;\r
 \r
 /** Size in bytes of the target's EEPROM page */\r
 uint16_t XPROG_Param_EEPageSize;\r
@@ -455,10 +455,10 @@ static void XPROGProtocol_SetParam(void)
                case XPRG_PARAM_EEPPAGESIZE:\r
                        XPROG_Param_EEPageSize = Endpoint_Read_Word_BE();\r
                        break;\r
-               case XPRG_PARAM_NVMCMD:\r
+               case XPRG_PARAM_NVMCMD_REG:\r
                        XPROG_Param_NVMCMDRegAddr = Endpoint_Read_Byte();\r
                        break;\r
-               case XPRG_PARAM_NVMCSR:\r
+               case XPRG_PARAM_NVMCSR_REG:\r
                        XPROG_Param_NVMCSRRegAddr = Endpoint_Read_Byte();\r
                        break;\r
                default:\r
index 2bc7d8a..8e5d1b0 100644 (file)
 \r
                #define XPRG_PARAM_NVMBASE                  0x01\r
                #define XPRG_PARAM_EEPPAGESIZE              0x02\r
-               #define XPRG_PARAM_NVMCMD                   0x03\r
-               #define XPRG_PARAM_NVMCSR                   0x04\r
+               #define XPRG_PARAM_NVMCMD_REG               0x03 /* Undocumented, Reverse-engineered */\r
+               #define XPRG_PARAM_NVMCSR_REG               0x04 /* Undocumented, Reverse-engineered */\r
                \r
                #define XPRG_PROTOCOL_PDI                   0x00\r
                #define XPRG_PROTOCOL_JTAG                  0x01\r
-               #define XPRG_PROTOCOL_TPI                   0x02\r
+               #define XPRG_PROTOCOL_TPI                   0x02 /* Undocumented, Reverse-engineered */\r
                \r
                #define XPRG_PAGEMODE_WRITE                 (1 << 1)\r
                #define XPRG_PAGEMODE_ERASE                 (1 << 0)\r