#define INCLUDE_FROM_V2PROTOCOL_C\r
#include "V2Protocol.h"\r
\r
-ParameterItem_t ParameterTable[] EEMEM = \r
- {\r
- { .ParameterID = PARAM_BUILD_NUMBER_LOW,\r
- .ParameterValue = 0x00 },\r
- { .ParameterID = PARAM_BUILD_NUMBER_HIGH,\r
- .ParameterValue = 0x00 },\r
- { .ParameterID = PARAM_HW_VER,\r
- .ParameterValue = 0x01 },\r
- { .ParameterID = PARAM_SW_MAJOR,\r
- .ParameterValue = 0x01 },\r
- { .ParameterID = PARAM_SW_MINOR,\r
- .ParameterValue = 0x00 },\r
- { .ParameterID = PARAM_VTARGET,\r
- .ParameterValue = 0x00 },\r
- { .ParameterID = PARAM_SCK_DURATION,\r
- .ParameterValue = 0x00 },\r
- { .ParameterID = PARAM_RESET_POLARITY,\r
- .ParameterValue = 0x00 },\r
- { .ParameterID = PARAM_STATUS_TGT_CONN,\r
- .ParameterValue = 0x00 },\r
- { .ParameterID = PARAM_DISCHARGEDELAY,\r
- .ParameterValue = 0x00 },\r
- };\r
-
-void V2Protocol_ProcessCommand(void)
-{
- uint8_t V2Command = Endpoint_Read_Byte();\r
- \r
- printf("COMMAND %d\r\n", V2Command);\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
- V2Protocol_ProcessCmdSignOn();\r
+ V2Protocol_SignOn();\r
break;\r
case CMD_SET_PARAMETER:\r
- V2Protocol_ProcessCmdSetParam();\r
- break;\r
case CMD_GET_PARAMETER:\r
- V2Protocol_ProcessCmdGetParam();\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
- Endpoint_ClearOUT();\r
- Endpoint_SetEndpointDirection(ENDPOINT_DIR_IN);\r
- Endpoint_Write_Byte(STATUS_CMD_UNKNOWN);\r
- Endpoint_ClearIN();\r
+ V2Protocol_UnknownCommand(V2Command);\r
break;\r
}\r
\r
- /* Reset Endpoint direction to OUT ready for next command */\r
- Endpoint_SetEndpointDirection(ENDPOINT_DIR_OUT);
+ Endpoint_WaitUntilReady();\r
+ Endpoint_SetEndpointDirection(ENDPOINT_DIR_OUT);\r
}\r
\r
-static ParameterItem_t* V2Protocol_GetParameterItem(uint8_t ParamID)\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
- for (uint8_t TableIndex = 0; TableIndex < (sizeof(ParameterTable) / sizeof(ParameterTable[0])); TableIndex++)\r
+ /* Discard all incoming data */\r
+ while (Endpoint_BytesInEndpoint() == AVRISP_DATA_EPSIZE)\r
{\r
- if (ParamID == eeprom_read_byte(&ParameterTable[TableIndex].ParameterID))\r
- return &ParameterTable[TableIndex];\r
+ Endpoint_ClearOUT();\r
+ Endpoint_WaitUntilReady();\r
}\r
- \r
- return NULL;\r
-}
-
-static void V2Protocol_ProcessCmdSignOn(void)\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
+\r
Endpoint_Write_Byte(CMD_SIGN_ON);\r
Endpoint_Write_Byte(STATUS_CMD_OK);\r
- Endpoint_Write_Byte(PROGRAMMER_ID_LEN);\r
- Endpoint_Write_Stream_LE(PROGRAMMER_ID, PROGRAMMER_ID_LEN);\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
-static void V2Protocol_ProcessCmdSetParam(void)\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
- uint8_t ParamID = Endpoint_Read_Byte();\r
- uint8_t ParamValue = Endpoint_Read_Byte();\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
- ParameterItem_t* ParameterItem = V2Protocol_GetParameterItem(ParamID);\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
- if (ParameterItem != NULL)\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
- eeprom_write_byte(&ParameterItem->ParameterValue, ParamValue);\r
-\r
- Endpoint_Write_Byte(CMD_SET_PARAMETER);\r
- Endpoint_Write_Byte(STATUS_CMD_OK); \r
+ Endpoint_Write_Byte(STATUS_CMD_OK);\r
+ V2Params_SetParameterValue(ParamID, ParamValue);\r
}\r
- else\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
-static void V2Protocol_ProcessCmdGetParam(void)\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
- uint8_t ParamID = Endpoint_Read_Byte();\r
+ Endpoint_Read_Stream_BE(&CurrentAddress, sizeof(CurrentAddress));\r
\r
- ParameterItem_t* ParameterItem = V2Protocol_GetParameterItem(ParamID);\r
- \r
Endpoint_ClearOUT();\r
Endpoint_SetEndpointDirection(ENDPOINT_DIR_IN);\r
+ \r
+ MustSetAddress = true;\r
\r
- if (ParameterItem != NULL)\r
- {\r
- Endpoint_Write_Byte(CMD_GET_PARAMETER);\r
- Endpoint_Write_Byte(STATUS_CMD_OK);\r
- Endpoint_Write_Byte(eeprom_read_byte(&ParameterItem->ParameterValue)); \r
- }\r
- else\r
- {\r
- Endpoint_Write_Byte(STATUS_CMD_FAILED);\r
- }\r
-\r
- Endpoint_ClearIN(); \r
+ Endpoint_Write_Byte(CMD_LOAD_ADDRESS);\r
+ Endpoint_Write_Byte(STATUS_CMD_OK);\r
+ Endpoint_ClearIN();\r
}\r