summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-rw-r--r--digital/avr/modules/isp/avrconfig.h8
-rw-r--r--digital/avr/modules/isp/isp_proto.c213
-rw-r--r--digital/avr/modules/isp/isp_proto.h3
-rw-r--r--digital/avr/modules/isp/test/avrconfig.h8
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 <avr/pgmspace.h>
#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 */