From acf742ef36a87703365a4662e71a898873f69dac Mon Sep 17 00:00:00 2001 From: Nicolas Schodet Date: Sat, 25 Apr 2009 13:24:53 +0200 Subject: * digital/avr/modules/isp: - added many isp_proto commands. --- digital/avr/modules/isp/avrconfig.h | 8 ++ digital/avr/modules/isp/isp_proto.c | 213 +++++++++++++++++++++++++++++-- digital/avr/modules/isp/isp_proto.h | 3 + digital/avr/modules/isp/test/avrconfig.h | 8 ++ 4 files changed, 221 insertions(+), 11 deletions(-) diff --git a/digital/avr/modules/isp/avrconfig.h b/digital/avr/modules/isp/avrconfig.h index 92f5742a..daabef56 100644 --- a/digital/avr/modules/isp/avrconfig.h +++ b/digital/avr/modules/isp/avrconfig.h @@ -34,5 +34,13 @@ #define AC_ISP_FRAME_ACCEPT_FRAME isp_proto_accept /** Should be implemeted by the user to send a frame. */ #define AC_ISP_PROTO_SEND isp_frame_send_frame +/** Programmer signature. */ +#define AC_ISP_PROTO_SIGNATURE "APBisp_2" +/** Programmer build number. */ +#define AC_ISP_PROTO_BUILD_NUMBER 0x0100 +/** Programmer hardware version. */ +#define AC_ISP_PROTO_HW_VERSION 0x02 +/** Programmer software version. */ +#define AC_ISP_PROTO_SW_VERSION 0x0204 #endif /* avrconfig_h */ diff --git a/digital/avr/modules/isp/isp_proto.c b/digital/avr/modules/isp/isp_proto.c index 8192017f..ef1f321e 100644 --- a/digital/avr/modules/isp/isp_proto.c +++ b/digital/avr/modules/isp/isp_proto.c @@ -24,36 +24,227 @@ * }}} */ #include "common.h" +#include "modules/utils/byte.h" + #include "isp_proto.h" +#include "isp.h" #include #define ISP_PROTO_CMD_SIGN_ON 0x01 +#define ISP_PROTO_CMD_SET_PARAMETER 0x02 +#define ISP_PROTO_CMD_GET_PARAMETER 0x03 +#define ISP_PROTO_CMD_SET_DEVICE_PARAMETERS 0x04 +#define ISP_PROTO_CMD_OSCCAL 0x05 +#define ISP_PROTO_CMD_LOAD_ADDRESS 0x06 +#define ISP_PROTO_CMD_FIRMWARE_UPGRADE 0x07 + +#define ISP_PROTO_CMD_ENTER_PROGMODE_ISP 0x10 +#define ISP_PROTO_CMD_LEAVE_PROGMODE_ISP 0x11 +#define ISP_PROTO_CMD_CHIP_ERASE_ISP 0x12 +#define ISP_PROTO_CMD_PROGRAM_FLASH_ISP 0x13 +#define ISP_PROTO_CMD_READ_FLASH_ISP 0x14 +#define ISP_PROTO_CMD_PROGRAM_EEPROM_ISP 0x15 +#define ISP_PROTO_CMD_READ_EEPROM_ISP 0x16 +#define ISP_PROTO_CMD_PROGRAM_FUSE_ISP 0x17 +#define ISP_PROTO_CMD_READ_FUSE_ISP 0x18 +#define ISP_PROTO_CMD_PROGRAM_LOCK_ISP 0x19 +#define ISP_PROTO_CMD_READ_LOCK_ISP 0x1a +#define ISP_PROTO_CMD_READ_SIGNATURE_ISP 0x1b +#define ISP_PROTO_CMD_READ_OSCCAL_ISP 0x1c +#define ISP_PROTO_CMD_SPI_MULTI 0x1d #define ISP_PROTO_STATUS_CMD_OK 0x00 + +#define ISP_PROTO_STATUS_CMD_TOUT 0x80 +#define ISP_PROTO_STATUS_RDY_BSY_TOUT 0x81 +#define ISP_PROTO_STATUS_SET_PARAM_MISSING 0x82 + +#define ISP_PROTO_STATUS_CMD_FAILED 0xc0 +#define ISP_PROTO_STATUS_CKSUM_ERROR 0xc1 #define ISP_PROTO_STATUS_CMD_UNKNOWN 0xc9 -#define ISP_PROTO_SIGNATURE "APBdev_2" +#define ISP_PROTO_ISP_STATUS(status) \ + ((status) == ISP_OK ? ISP_PROTO_STATUS_CMD_OK \ + : ISP_PROTO_STATUS_CMD_FAILED) + +#define ISP_PROTO_ISP_STATUS_TOUT(status) \ + ((status) == ISP_OK ? ISP_PROTO_STATUS_CMD_OK \ + : (status) == ISP_TIMEOUT ? ISP_PROTO_STATUS_CMD_TOUT \ + : ISP_PROTO_STATUS_CMD_FAILED) + +#define ISP_PROTO_PARAM_BUILD_NUMBER_LOW 0x80 +#define ISP_PROTO_PARAM_BUILD_NUMBER_HIGH 0x81 +#define ISP_PROTO_PARAM_HW_VER 0x90 +#define ISP_PROTO_PARAM_SW_MAJOR 0x91 +#define ISP_PROTO_PARAM_SW_MINOR 0x92 +#define ISP_PROTO_PARAM_VTARGET 0x94 +#define ISP_PROTO_PARAM_VADJUST 0x95 +#define ISP_PROTO_PARAM_OSC_PSCALE 0x96 +#define ISP_PROTO_PARAM_OSC_CMATCH 0x97 +#define ISP_PROTO_PARAM_SCK_DURATION 0x98 +#define ISP_PROTO_PARAM_TOPCARD_DETECT 0x9a +#define ISP_PROTO_PARAM_STATUS 0x9c +#define ISP_PROTO_PARAM_DATA 0x9d +#define ISP_PROTO_PARAM_RESET_POLARITY 0x9e +#define ISP_PROTO_PARAM_CONTROLLER_INIT 0x9f + +uint8_t isp_proto_sck_duration; + +static void +isp_proto_simple_answer (uint8_t *data, uint8_t status) +{ + data[1] = status; + AC_ISP_PROTO_SEND (data, 2); +} void isp_proto_accept (uint8_t *data, uint16_t len) { + uint8_t status; + uint16_t size; /* Decode command. */ - switch (data [0]) + switch (data[0]) { case ISP_PROTO_CMD_SIGN_ON: - /* Return programmer signature. */ + if (len != 1) break; + data[1] = ISP_PROTO_STATUS_CMD_OK; + data[2] = sizeof (AC_ISP_PROTO_SIGNATURE); + memcpy_P (&data[3], PSTR (AC_ISP_PROTO_SIGNATURE), + sizeof (AC_ISP_PROTO_SIGNATURE)); + AC_ISP_PROTO_SEND (data, 3 + sizeof (AC_ISP_PROTO_SIGNATURE)); + return; + case ISP_PROTO_CMD_SET_PARAMETER: + if (len != 3) break; + status = ISP_PROTO_STATUS_CMD_OK; + switch (data[1]) + { + case ISP_PROTO_PARAM_SCK_DURATION: + isp_proto_sck_duration = data[2]; + break; + default: + status = ISP_PROTO_STATUS_CMD_FAILED; + break; + } + isp_proto_simple_answer (data, status); + return; + case ISP_PROTO_CMD_GET_PARAMETER: + if (len != 2) break; + status = ISP_PROTO_STATUS_CMD_OK; + switch (data[1]) + { + case ISP_PROTO_PARAM_SCK_DURATION: + data[2] = isp_proto_sck_duration; + break; + case ISP_PROTO_PARAM_BUILD_NUMBER_LOW: + data[2] = v16_to_v8 (AC_ISP_PROTO_BUILD_NUMBER, 0); + break; + case ISP_PROTO_PARAM_BUILD_NUMBER_HIGH: + data[2] = v16_to_v8 (AC_ISP_PROTO_BUILD_NUMBER, 1); + break; + case ISP_PROTO_PARAM_HW_VER: + data[2] = AC_ISP_PROTO_HW_VERSION; + break; + case ISP_PROTO_PARAM_SW_MAJOR: + data[2] = v16_to_v8 (AC_ISP_PROTO_SW_VERSION, 1); + break; + case ISP_PROTO_PARAM_SW_MINOR: + data[2] = v16_to_v8 (AC_ISP_PROTO_SW_VERSION, 0); + break; + default: + status = ISP_PROTO_STATUS_CMD_FAILED; + break; + } + data[1] = status; + AC_ISP_PROTO_SEND (data, status == ISP_PROTO_STATUS_CMD_OK ? 3 : 2); + return; + case ISP_PROTO_CMD_LOAD_ADDRESS: + if (len != 5) break; + isp_load_address (v8_to_v32 (data[1], data[2], data[3], data[4])); + isp_proto_simple_answer (data, ISP_PROTO_STATUS_CMD_OK); + return; + case ISP_PROTO_CMD_ENTER_PROGMODE_ISP: + if (len != 12) break; + status = isp_enter_progmode (data[1], data[2], data[3], data[4], + data[5], data[6], data[7], &data[8]); + isp_proto_simple_answer (data, ISP_PROTO_ISP_STATUS (status)); + return; + case ISP_PROTO_CMD_LEAVE_PROGMODE_ISP: + if (len != 3) break; + isp_leave_progmode (data[1], data[2]); + isp_proto_simple_answer (data, ISP_PROTO_STATUS_CMD_OK); + return; + case ISP_PROTO_CMD_CHIP_ERASE_ISP: + if (len != 7) break; + status = isp_chip_erase (data[1], data[2], &data[3]); + isp_proto_simple_answer (data, ISP_PROTO_ISP_STATUS_TOUT (status)); + return; + case ISP_PROTO_CMD_PROGRAM_FLASH_ISP: + case ISP_PROTO_CMD_PROGRAM_EEPROM_ISP: + if (len < 10) break; + size = v8_to_v16 (data[1], data[2]); + if (len != 10 + size) break; + status = isp_program_begin (size, data[3], data[4], data[5], data[6], + data[7], &data[8], data[0] == + ISP_PROTO_CMD_PROGRAM_FLASH_ISP); + if (status == ISP_OK) + status = isp_program_continue (&data[10], size); + if (status == ISP_OK) + status = isp_program_end (); + isp_proto_simple_answer (data, ISP_PROTO_ISP_STATUS_TOUT (status)); + return; + case ISP_PROTO_CMD_READ_FLASH_ISP: + case ISP_PROTO_CMD_READ_EEPROM_ISP: + if (len != 4) break; + size = v8_to_v16 (data[1], data[2]); + status = isp_read_begin (size, data[3], data[0] == + ISP_PROTO_CMD_PROGRAM_FLASH_ISP); + if (status == ISP_OK) + status = isp_read_continue (&data[2], size); + if (status == ISP_OK) + status = isp_read_end (); + if (status == ISP_OK) + { + data[1] = ISP_PROTO_STATUS_CMD_OK; + data[2 + size] = ISP_PROTO_STATUS_CMD_OK; + AC_ISP_PROTO_SEND (data, 2 + size + 1); + } + else + isp_proto_simple_answer (data, ISP_PROTO_STATUS_CMD_FAILED); + return; + case ISP_PROTO_CMD_PROGRAM_FUSE_ISP: + case ISP_PROTO_CMD_PROGRAM_LOCK_ISP: + if (len != 5) break; + isp_program_misc (&data[1]); + data[1] = ISP_PROTO_STATUS_CMD_OK; + data[2] = ISP_PROTO_STATUS_CMD_OK; + AC_ISP_PROTO_SEND (data, 3); + return; + case ISP_PROTO_CMD_READ_FUSE_ISP: + case ISP_PROTO_CMD_READ_LOCK_ISP: + case ISP_PROTO_CMD_READ_SIGNATURE_ISP: + case ISP_PROTO_CMD_READ_OSCCAL_ISP: + if (len != 6) break; + status = isp_read_misc (data[1], &data[2]); + data[1] = ISP_PROTO_STATUS_CMD_OK; + data[2] = status; + data[3] = ISP_PROTO_STATUS_CMD_OK; + AC_ISP_PROTO_SEND (data, 4); + return; + case ISP_PROTO_CMD_SPI_MULTI: + if (len < 4) break; + size = data[2]; + if (len != 4 + size) break; + isp_multi (data[1], data[2], data[3], &data[4], &data[2]); data[1] = ISP_PROTO_STATUS_CMD_OK; - data[2] = sizeof (ISP_PROTO_SIGNATURE); - memcpy_P (&data[3], PSTR (ISP_PROTO_SIGNATURE), - sizeof (ISP_PROTO_SIGNATURE)); - AC_ISP_PROTO_SEND (data, 3 + sizeof (ISP_PROTO_SIGNATURE)); - break; + data[2 + size] = ISP_PROTO_STATUS_CMD_OK; + AC_ISP_PROTO_SEND (data, 2 + size + 1); + return; default: /* Unknown. */ - data[1] = ISP_PROTO_STATUS_CMD_UNKNOWN; - AC_ISP_PROTO_SEND (data, 2); - break; + isp_proto_simple_answer (data, ISP_PROTO_STATUS_CMD_UNKNOWN); + return; } + isp_proto_simple_answer (data, ISP_PROTO_STATUS_CMD_FAILED); } diff --git a/digital/avr/modules/isp/isp_proto.h b/digital/avr/modules/isp/isp_proto.h index 983f6f0f..460ec889 100644 --- a/digital/avr/modules/isp/isp_proto.h +++ b/digital/avr/modules/isp/isp_proto.h @@ -28,6 +28,9 @@ /** The isp_proto sub module interprets commands in the AVR068 and AVR069 * format. Framing is needed for AVR068 and provided by isp_frame. */ +/** Requested SCK duration, in the AVR06[89] format. */ +uint8_t isp_proto_sck_duration; + /** Should be implemeted by the user to send a frame. */ void AC_ISP_PROTO_SEND (uint8_t *data, uint16_t len); diff --git a/digital/avr/modules/isp/test/avrconfig.h b/digital/avr/modules/isp/test/avrconfig.h index 92f5742a..daabef56 100644 --- a/digital/avr/modules/isp/test/avrconfig.h +++ b/digital/avr/modules/isp/test/avrconfig.h @@ -34,5 +34,13 @@ #define AC_ISP_FRAME_ACCEPT_FRAME isp_proto_accept /** Should be implemeted by the user to send a frame. */ #define AC_ISP_PROTO_SEND isp_frame_send_frame +/** Programmer signature. */ +#define AC_ISP_PROTO_SIGNATURE "APBisp_2" +/** Programmer build number. */ +#define AC_ISP_PROTO_BUILD_NUMBER 0x0100 +/** Programmer hardware version. */ +#define AC_ISP_PROTO_HW_VERSION 0x02 +/** Programmer software version. */ +#define AC_ISP_PROTO_SW_VERSION 0x0204 #endif /* avrconfig_h */ -- cgit v1.2.3