Rename PDIProtocol.c/.h to XPROGProtocol.c/.h as it will now handle both TPI and...
[pub/USBasp.git] / Projects / AVRISP / Lib / V2Protocol.c
index 3532c5e..eae2e83 100644 (file)
  *  V2Protocol handler, to process V2 Protocol commands used in Atmel programmer devices.\r
  */\r
 \r
-char ProgrammerID[] = "AVRISP_MK2";\r
-\r
+#define  INCLUDE_FROM_V2PROTOCOL_C\r
 #include "V2Protocol.h"\r
-
-void V2Protocol_ProcessCommand(void)
-{
+\r
+/** Current memory address for FLASH/EEPROM memory read/write commands */\r
+uint32_t CurrentAddress;\r
+\r
+/** Flag to indicate that the next read/write operation must update the device's current address */\r
+bool MustSetAddress;\r
+\r
+\r
+/** Master V2 Protocol packet handler, for received V2 Protocol packets from a connected host.\r
+ *  This routine decodes the issued command and passes off the handling of the command to the\r
+ *  appropriate function.\r
+ */\r
+void V2Protocol_ProcessCommand(void)\r
+{\r
        uint8_t V2Command = Endpoint_Read_Byte();\r
        \r
+       Serial_TxByte(V2Command);\r
+       \r
        switch (V2Command)\r
        {\r
                case CMD_SIGN_ON:\r
-                       Endpoint_ClearOUT();\r
-                       Endpoint_SetEndpointDirection(ENDPOINT_DIR_IN);\r
-                       \r
-                       Endpoint_Write_Byte(CMD_SIGN_ON);\r
-                       Endpoint_Write_Byte(STATUS_CMD_OK);\r
-                       Endpoint_Write_Byte((sizeof(ProgrammerID) - 1));\r
-                       Endpoint_Write_Stream_LE(ProgrammerID, (sizeof(ProgrammerID) - 1));                     \r
-                       Endpoint_ClearIN();\r
-                       break;\r
-       }
-}
-
+                       V2Protocol_SignOn();\r
+                       break;\r
+               case CMD_SET_PARAMETER:\r
+               case CMD_GET_PARAMETER:\r
+                       V2Protocol_GetSetParam(V2Command);\r
+                       break;\r
+               case CMD_LOAD_ADDRESS:\r
+                       V2Protocol_LoadAddress();\r
+                       break;\r
+               case CMD_RESET_PROTECTION:\r
+                       V2Protocol_ResetProtection();\r
+                       break;\r
+#if defined(ENABLE_ISP_PROTOCOL)\r
+               case CMD_ENTER_PROGMODE_ISP:\r
+                       ISPProtocol_EnterISPMode();\r
+                       break;\r
+               case CMD_LEAVE_PROGMODE_ISP:\r
+                       ISPProtocol_LeaveISPMode();\r
+                       break;\r
+               case CMD_PROGRAM_FLASH_ISP:\r
+               case CMD_PROGRAM_EEPROM_ISP:\r
+                       ISPProtocol_ProgramMemory(V2Command);                   \r
+                       break;\r
+               case CMD_READ_FLASH_ISP:\r
+               case CMD_READ_EEPROM_ISP:\r
+                       ISPProtocol_ReadMemory(V2Command);\r
+                       break;\r
+               case CMD_CHIP_ERASE_ISP:\r
+                       ISPProtocol_ChipErase();\r
+                       break;\r
+               case CMD_READ_FUSE_ISP:\r
+               case CMD_READ_LOCK_ISP:\r
+               case CMD_READ_SIGNATURE_ISP:\r
+               case CMD_READ_OSCCAL_ISP:\r
+                       ISPProtocol_ReadFuseLockSigOSCCAL(V2Command);\r
+                       break;\r
+               case CMD_PROGRAM_FUSE_ISP:\r
+               case CMD_PROGRAM_LOCK_ISP:\r
+                       ISPProtocol_WriteFuseLock(V2Command);\r
+                       break;\r
+               case CMD_SPI_MULTI:\r
+                       ISPProtocol_SPIMulti();\r
+                       break;\r
+#endif\r
+#if defined(ENABLE_PDI_PROTOCOL)\r
+               case CMD_XPROG_SETMODE:\r
+                       PDIProtocol_XPROG_SetMode();\r
+                       break;\r
+               case CMD_XPROG:\r
+                       PDIProtocol_XPROG_Command();\r
+                       break;\r
+#endif\r
+#if defined(ENABLE_TPI_PROTOCOL)\r
+               // TODO\r
+#endif\r
+               default:\r
+                       V2Protocol_UnknownCommand(V2Command);\r
+                       break;\r
+       }\r
+       \r
+       Endpoint_WaitUntilReady();\r
+       Endpoint_SetEndpointDirection(ENDPOINT_DIR_OUT);\r
+}\r
+\r
+/** Handler for unknown V2 protocol commands. This discards all sent data and returns a\r
+ *  STATUS_CMD_UNKNOWN status back to the host.\r
+ *\r
+ *  \param[in] V2Command  Issued V2 Protocol command byte from the host\r
+ */\r
+static void V2Protocol_UnknownCommand(const uint8_t V2Command)\r
+{\r
+       /* Discard all incoming data */\r
+       while (Endpoint_BytesInEndpoint() == AVRISP_DATA_EPSIZE)\r
+       {\r
+               Endpoint_ClearOUT();\r
+               Endpoint_WaitUntilReady();\r
+       }\r
+\r
+       Endpoint_ClearOUT();\r
+       Endpoint_SetEndpointDirection(ENDPOINT_DIR_IN);\r
+\r
+       Endpoint_Write_Byte(V2Command);\r
+       Endpoint_Write_Byte(STATUS_CMD_UNKNOWN);\r
+       Endpoint_ClearIN();\r
+}\r
+\r
+/** Handler for the CMD_SIGN_ON command, returning the programmer ID string to the host. */\r
+static void V2Protocol_SignOn(void)\r
+{\r
+       Endpoint_ClearOUT();\r
+       Endpoint_SetEndpointDirection(ENDPOINT_DIR_IN);\r
+\r
+       Endpoint_Write_Byte(CMD_SIGN_ON);\r
+       Endpoint_Write_Byte(STATUS_CMD_OK);\r
+       Endpoint_Write_Byte(sizeof(PROGRAMMER_ID) - 1);\r
+       Endpoint_Write_Stream_LE(PROGRAMMER_ID, (sizeof(PROGRAMMER_ID) - 1));\r
+       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
+ */\r
+static void V2Protocol_ResetProtection(void)\r
+{\r
+       Endpoint_ClearOUT();\r
+       Endpoint_SetEndpointDirection(ENDPOINT_DIR_IN);\r
+       \r
+       Endpoint_Write_Byte(CMD_RESET_PROTECTION);\r
+       Endpoint_Write_Byte(STATUS_CMD_OK);\r
+       Endpoint_ClearIN();     \r
+}\r
+\r
+\r
+/** Handler for the CMD_SET_PARAMETER and CMD_GET_PARAMETER commands from the host, setting or\r
+ *  getting a device parameter's value from the parameter table.\r
+ *\r
+ *  \param[in] V2Command  Issued V2 Protocol command byte from the host\r
+ */\r
+static void V2Protocol_GetSetParam(const uint8_t V2Command)\r
+{\r
+       uint8_t ParamID = Endpoint_Read_Byte();\r
+       uint8_t ParamValue;\r
+       \r
+       if (V2Command == CMD_SET_PARAMETER)\r
+         ParamValue = Endpoint_Read_Byte();\r
+\r
+       Endpoint_ClearOUT();\r
+       Endpoint_SetEndpointDirection(ENDPOINT_DIR_IN);\r
+       \r
+       Endpoint_Write_Byte(V2Command);\r
+       \r
+       uint8_t ParamPrivs = V2Params_GetParameterPrivileges(ParamID);\r
+       \r
+       if ((V2Command == CMD_SET_PARAMETER) && (ParamPrivs & PARAM_PRIV_WRITE))\r
+       {\r
+               Endpoint_Write_Byte(STATUS_CMD_OK);\r
+               V2Params_SetParameterValue(ParamID, ParamValue);\r
+       }\r
+       else if ((V2Command == CMD_GET_PARAMETER) && (ParamPrivs & PARAM_PRIV_READ))\r
+       {\r
+               Endpoint_Write_Byte(STATUS_CMD_OK);\r
+               Endpoint_Write_Byte(V2Params_GetParameterValue(ParamID));\r
+       }\r
+       else\r
+       {       \r
+               Endpoint_Write_Byte(STATUS_CMD_FAILED);\r
+       }\r
+\r
+       Endpoint_ClearIN();\r
+}\r
+\r
+/** Handler for the CMD_LOAD_ADDRESS command, loading the given device address into a\r
+ *  global storage variable for later use, and issuing LOAD EXTENDED ADDRESS commands\r
+ *  to the attached device as required.\r
+ */\r
+static void V2Protocol_LoadAddress(void)\r
+{\r
+       Endpoint_Read_Stream_BE(&CurrentAddress, sizeof(CurrentAddress));\r
+\r
+       Endpoint_ClearOUT();\r
+       Endpoint_SetEndpointDirection(ENDPOINT_DIR_IN);\r
+       \r
+       MustSetAddress = true;\r
+\r
+       Endpoint_Write_Byte(CMD_LOAD_ADDRESS);\r
+       Endpoint_Write_Byte(STATUS_CMD_OK);\r
+       Endpoint_ClearIN();\r
+}\r