From beaebd989cab968cab8c9af24f4d376e89ca71b5 Mon Sep 17 00:00:00 2001
From: MX682X <58419867+MX682X@users.noreply.github.com>
Date: Wed, 14 Aug 2024 19:01:04 +0200
Subject: [PATCH] PICkit 5 support (#1863)
---
src/CMakeLists.txt | 4 +
src/Makefile.am | 4 +
src/avrdude.conf.in | 41 +-
src/doc/avrdude.texi | 23 +
src/main.c | 3 +
src/pgm_type.c | 2 +
src/pickit5.c | 1410 ++++++++++++++++++++++++++++++++++++++
src/pickit5.h | 32 +
src/pickit5_lut.h | 83 +++
src/pickit5_updi_lut.c | 1110 ++++++++++++++++++++++++++++++
src/usbdevs.h | 1 +
tools/scripts_decoder.py | 675 ++++++++++++++++++
12 files changed, 3386 insertions(+), 2 deletions(-)
create mode 100644 src/pickit5.c
create mode 100644 src/pickit5.h
create mode 100644 src/pickit5_lut.h
create mode 100644 src/pickit5_updi_lut.c
create mode 100644 tools/scripts_decoder.py
diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt
index 5c02978e4..f7b1700b8 100644
--- a/src/CMakeLists.txt
+++ b/src/CMakeLists.txt
@@ -229,6 +229,10 @@ set(SOURCES
pgm_type.c
pickit2.c
pickit2.h
+ pickit5_updi_lut.c
+ pickit5_lut.h
+ pickit5.c
+ pickit5.h
pindefs.c
ppi.c
ppi.h
diff --git a/src/Makefile.am b/src/Makefile.am
index 5b9957564..b075ea869 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -156,6 +156,10 @@ libavrdude_la_SOURCES = \
pgm_type.c \
pickit2.c \
pickit2.h \
+ pickit5_updi_lut.c \
+ pickit5_lut.h \
+ pickit5.c \
+ pickit5.h \
pindefs.c \
ppi.c \
ppi.h \
diff --git a/src/avrdude.conf.in b/src/avrdude.conf.in
index 9d64a83ab..1dc05cb0b 100644
--- a/src/avrdude.conf.in
+++ b/src/avrdude.conf.in
@@ -2948,9 +2948,8 @@ programmer # powerdebugger_tpi
# pickit4 / pickit4_jtag
#------------------------------------------------------------
-# Microchip PICkit 4. See
+# Microchip PICkit 4. For details see
# https://www.microchip.com/en-us/development-tool/pg164140
-# for details.
#
# The PICkit 4 supports the following programming modes
# using different programmer names:
@@ -3055,6 +3054,44 @@ programmer # pickit4_tpi
usbpid = 0x2177, 0x2178, 0x2179;
;
+
+# Microchip PICkit 5. For details, see
+# https://www.microchip.com/en-us/development-tool/PG164150
+#
+# Currently -c pickit5 only supports UPDI programming
+#
+# PIN UPDI
+# > 1 !RST(*)
+# 2 VCC
+# 3 GND
+# 4 UPDI(*)
+# 5
+# 6
+# 7
+# 8
+#
+# (*): The PICkit5 can generate a High-Voltage (12V) Pulse on this pins
+# to restore the UPDI Pin functionality, if it was changed through fuses.
+# AVRDUDE automatically selects the correct pin, if the HV pulse is
+# enabled through the '-x hvupdi' flag.
+
+#------------------------------------------------------------
+# pickit5 /pickit5_updi
+#------------------------------------------------------------
+
+programmer # pickit5_updi
+ id = "pickit5_updi";
+ desc = "MPLAB(R) PICkit 5, PICkit 4 and SNAP (PIC mode)";
+ type = "pickit5_updi";
+ prog_modes = PM_UPDI;
+ extra_features = HAS_VTARG_READ;
+ connection_type = usb;
+ baudrate = 200000; # UPDI default clock
+ usbvid = 0x04d8;
+ usbpid = 0x9036, 0x9012, 0x9018; # PK5, PK4 (pic mode), snap (pic mode)
+ hvupdi_support = 0, 1, 2;
+;
+
#------------------------------------------------------------
# snap /snap_jtag
#------------------------------------------------------------
diff --git a/src/doc/avrdude.texi b/src/doc/avrdude.texi
index eb97eda84..5e1bfd8c5 100644
--- a/src/doc/avrdude.texi
+++ b/src/doc/avrdude.texi
@@ -325,6 +325,7 @@ See below for some hints about FLIP version 1 protocol behaviour.
The MPLAB(R) PICkit 4 and MPLAB(R) SNAP are supported in JTAG, TPI, ISP, PDI and UPDI mode.
The Curiosity Nano board is supported in UPDI mode. It is dubbed ``PICkit on
Board'', thus the name @code{pkobn_updi}.
+The MPLAB(R) PICkit 5 is currently only supported in UPDI mode.
SerialUPDI programmer implementation is based on Microchip's
@emph{pymcuprog} (@url{https://github.com/microchip-pic-avr-tools/pymcuprog})
@@ -1305,6 +1306,27 @@ for switching to PIC mode.
Show help menu and exit.
@end table
+@cindex Option @code{-x} PICkit 5
+@item PICkit 5
+@item PICkit 4 (PIC Mode)
+
+The PICkit 5 and PICkit 4 (PIC Mode) programmer can accept following extended parameters
+@table @code
+@item @samp{vtarg=VALUE}
+Specify a voltage between 1.8 and 5.5@w{ }V that the programmer should supply
+to the target. If there is already a valid voltage applied to the VTG Pin,
+this setting will be ignored. When AVRDUDE detects an external voltage outside
+of this range, it will terminate the operation. You can disable this by
+setting the voltage to 0@w{ }V.
+@item @samp{hvupdi}
+High-voltage UPDI programming is used to enable a UPDI pin that has previously
+been set to RESET or GPIO mode. Use @samp{-x hvupdi} to enable high-voltage UPDI
+initialization for supported targets. Depending on the target, the HV pulse will
+be applied either on the RST pin, or the UPDI pin.
+@item @samp{help}
+Show help menu and exit.
+@end table
+
@cindex Option @code{-x} Xplained Mini
@item Xplained Mini
@@ -2220,6 +2242,7 @@ Valid programmers for part AVR32EA32 are:
jtag2updi = JTAGv2 to UPDI bridge via UPDI
jtag3updi = Atmel AVR JTAGICE3 via UPDI
pickit4_updi = MPLAB(R) PICkit 4 via UPDI
+ pickit5_updi = MPLAB(R) PICkit 5, PICkit 4 and SNAP (PIC mode) via UPDI
pkobn_updi = Curiosity nano (nEDBG) via UPDI
powerdebugger_updi = Atmel PowerDebugger (ARM/AVR) via UPDI
serialupdi = SerialUPDI via UPDI
diff --git a/src/main.c b/src/main.c
index 427788942..ce2be3b53 100644
--- a/src/main.c
+++ b/src/main.c
@@ -1545,6 +1545,9 @@ int main(int argc, char * argv [])
else
imsg_error(" - use -B to set lower the bit clock frequency, e.g. -B 125kHz\n");
+ if (str_starts(pgm->type, "pickit5"))
+ imsg_error(" - reset the programmer by unplugging it");
+
if (!ovsigck) {
imsg_error(" - use -F to override this check\n");
exitrc = 1;
diff --git a/src/pgm_type.c b/src/pgm_type.c
index e439e8568..d80097ee1 100644
--- a/src/pgm_type.c
+++ b/src/pgm_type.c
@@ -46,6 +46,7 @@
#include "micronucleus.h"
#include "par.h"
#include "pickit2.h"
+#include "pickit5.h"
#include "ppi.h"
#include "serbb.h"
#include "serialupdi.h"
@@ -99,6 +100,7 @@ const PROGRAMMER_TYPE programmers_types[] = { // Name(s) the programmers call th
{"micronucleus", micronucleus_initpgm, micronucleus_desc}, // "micronucleus" or "Micronucleus V2.0"
{"par", par_initpgm, par_desc}, // "PPI"
{"pickit2", pickit2_initpgm, pickit2_desc}, // "pickit2"
+ {"pickit5_updi", pickit5_initpgm, pickit5_desc}, // "pickit5"
{"serbb", serbb_initpgm, serbb_desc}, // "SERBB"
{"serialupdi", serialupdi_initpgm, serialupdi_desc}, // "serialupdi"
{"serprog", serprog_initpgm, serprog_desc}, // "serprog"
diff --git a/src/pickit5.c b/src/pickit5.c
new file mode 100644
index 000000000..13bdc66bb
--- /dev/null
+++ b/src/pickit5.c
@@ -0,0 +1,1410 @@
+/*
+ * avrdude - A Downloader/Uploader for AVR device programmers
+ * Copyright (C) 2024 MX682X
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ *
+ * This code is not affiliated in any way with Microchip®
+ */
+
+#include
+
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+
+#include "avrdude.h"
+#include "libavrdude.h"
+
+#include "pickit5.h"
+#include "pickit5_lut.h"
+#include "updi_constants.h"
+#include "usbdevs.h"
+
+#if defined(HAVE_USB_H)
+#include // Linux/Mac
+#elif defined(HAVE_LUSB0_USB_H)
+#include // Windows
+#endif
+
+// A USB driver is needed to talk with MacOS USB; it's unclear where to find it
+// so remove the support under MacOS for the time being
+
+#if defined(HAVE_USB_H) || defined(HAVE_LUSB0_USB_H)
+#define USB_PK5_CMD_READ_EP 0x81
+#define USB_PK5_CMD_WRITE_EP 0x02
+#define USB_PK5_DATA_READ_EP 0x83
+#define USB_PK5_DATA_WRITE_EP 0x04
+
+#define USB_PK5_MAX_XFER 512
+
+#define CHECK_ERROR 0x01
+#define BIST_TEST 0x02
+#define BIST_RESULT 0x03
+
+#define PGM_TYPE_PK5 0x00 // Default
+#define PGM_TYPE_PK4 0x01 // PICkit4
+#define PGM_TYPE_SNAP 0x02 // SNAP
+
+#define PK_OP_NONE 0x00 // Init
+#define PK_OP_FOUND 0x01 // PK is connected to USB
+#define PK_OP_RESPONDS 0x02 // Responds to get_fw() requests
+#define PK_OP_READY 0x03 // Voltage Set, Clock Set
+
+#define POWER_SOURCE_EXT 0x00
+#define POWER_SOURCE_INT 0x01
+#define POWER_SOURCE_NONE 0x02
+
+// Private data for this programmer
+struct pdata {
+ unsigned char pgm_type; // Used to skip unsupported functions
+ unsigned char pk_op_mode; // See PK_OP_ defines
+ unsigned char power_source; // 0: external / 1: from PICkit / 2: ignore check
+ unsigned char hvupdi_enabled; // 0: no HV / 1: HV generation enabled
+ double target_voltage; // Voltage to supply to target
+
+ double measured_vcc; // This and below for print_params()
+ unsigned int measured_current;
+ unsigned int actual_updi_clk;
+
+ unsigned char nvm_version; // Used to determine the offset for SIGROW/DevID
+
+ unsigned char devID[4]; // Last byte has the Chip Revision of the target
+ unsigned char app_version[3]; // Buffer for display() sent by get_fw()
+ unsigned char fw_info[16]; // Buffer for display() sent by get_fw()
+ unsigned char sernum_string[20]; // Buffer for display() sent by get_fw()
+ char sib_string[32];
+ unsigned char txBuf[512];
+ unsigned char rxBuf[512];
+ SCRIPT scripts;
+};
+
+#define my (*(struct pdata *)(pgm->cookie))
+
+
+static void pickit5_setup(PROGRAMMER *pgm);
+static void pickit5_teardown(PROGRAMMER *pgm);
+static int pickit5_parseextparms(const PROGRAMMER *pgm, const LISTID extparms);
+
+static int pickit5_open(PROGRAMMER *pgm, const char *port);
+static void pickit5_close(PROGRAMMER *pgm);
+
+static void pickit5_disable(const PROGRAMMER *pgm);
+static void pickit5_enable(PROGRAMMER *pgm, const AVRPART *p);
+static void pickit5_display(const PROGRAMMER *pgm, const char *p);
+static int pickit5_initialize(const PROGRAMMER *pgm, const AVRPART *p);
+
+static int pickit5_cmd(const PROGRAMMER *pgm, const unsigned char *cmd, unsigned char *res);
+static int pickit5_program_enable(const PROGRAMMER *pgm, const AVRPART *p);
+static int pickit5_program_disable(const PROGRAMMER *pgm, const AVRPART *p);
+static int pickit5_chip_erase(const PROGRAMMER *pgm, const AVRPART *p);
+static int pickit5_paged_load(const PROGRAMMER *pgm, const AVRPART *p, const AVRMEM *mem,
+ unsigned int page_size, unsigned int addr, unsigned int n_bytes);
+static int pickit5_paged_write(const PROGRAMMER *pgm, const AVRPART *p, const AVRMEM *mem,
+ unsigned int page_size, unsigned int addr, unsigned int n_bytes);
+static int pickit5_write_byte(const PROGRAMMER *pgm, const AVRPART *p, const AVRMEM *mem,
+ unsigned long addr, unsigned char value);
+static int pickit5_read_byte(const PROGRAMMER *pgm, const AVRPART *p, const AVRMEM *mem,
+ unsigned long addr, unsigned char *value);
+static int pickit5_read_dev_id(const PROGRAMMER *pgm, const AVRPART *p);
+static int pickit5_read_sib(const PROGRAMMER *pgm, const AVRPART *p, char *sib);
+static int pickit5_read_chip_rev(const PROGRAMMER *pgm, const AVRPART *p, unsigned char *chip_rev);
+static int pickit5_read_array(const PROGRAMMER *pgm, const AVRPART *p,
+ const AVRMEM *mem, unsigned long addr, int len, unsigned char *value);
+static int pickit5_write_array(const PROGRAMMER *pgm, const AVRPART *p,
+ const AVRMEM *mem, unsigned long addr, int len, unsigned char *value);
+
+// UPDI-specific functions
+static int pickit5_updi_write_byte(const PROGRAMMER *pgm, const AVRPART *p,
+ const AVRMEM *mem, unsigned long addr, unsigned char value);
+static int pickit5_updi_read_byte(const PROGRAMMER *pgm, const AVRPART *p,
+ const AVRMEM *mem, unsigned long addr, unsigned char *value);
+
+// Extra functions
+static int pickit5_get_fw_info(const PROGRAMMER *pgm);
+static int pickit5_set_vtarget(const PROGRAMMER *pgm, double v);
+static int pickit5_get_vtarget(const PROGRAMMER *pgm, double *v);
+static int pickit5_set_ptg_mode(const PROGRAMMER *pgm);
+static int pickit5_set_sck_period(const PROGRAMMER *pgm, double sckperiod);
+static int pickit5_write_cs_reg(const PROGRAMMER *pgm, unsigned int addr, unsigned char value);
+static int pickit5_read_cs_reg(const PROGRAMMER *pgm, unsigned int addr, unsigned char *value);
+
+// Internal functions
+inline static void pickit5_uint32_to_array(unsigned char *buf, uint32_t num);
+inline static unsigned int pickit5_array_to_uint32(unsigned char *buf);
+inline static void pickit5_create_payload_header(unsigned char *buf, unsigned int type,
+ unsigned int msg_len, unsigned int trans_len);
+inline static void pickit5_create_script_header(unsigned char *buf, unsigned int arg_len, unsigned int script_len);
+inline static int pickit5_check_ret_status(const PROGRAMMER *pgm);
+
+static int pickit5_get_status(const PROGRAMMER *pgm, unsigned char status);
+static int pickit5_send_script(const PROGRAMMER *pgm, unsigned int script_type,
+ const unsigned char *script, unsigned int script_len,
+ const unsigned char *param, unsigned int param_len, unsigned int payload_len);
+static int pickit5_send_script_done(const PROGRAMMER *pgm, char *func);
+static int pickit5_read_response(const PROGRAMMER *pgm, char *fn_name);
+
+// Extra-USB related functions, because we need more then 2 endpoints
+static int usbdev_data_recv(const union filedescriptor *fd, unsigned char *buf, size_t nbytes);
+static int usbdev_data_send(const union filedescriptor *fd, const unsigned char *bp, size_t mlen);
+
+inline static void pickit5_uint32_to_array(unsigned char *buf, uint32_t num) {
+ *(buf++) = (uint8_t) num;
+ *(buf++) = (uint8_t) (num >> 8);
+ *(buf++) = (uint8_t) (num >> 16);
+ *(buf) = (uint8_t) (num >> 24);
+}
+
+inline static unsigned int pickit5_array_to_uint32(unsigned char *buf) {
+ unsigned int retval = 0;
+
+ retval |= *(buf++);
+ retval |= *(buf++) << 8;
+ retval |= *(buf++) << 16;
+ retval |= *(buf++) << 24;
+ return retval;
+}
+
+inline static void pickit5_create_payload_header(unsigned char *buf, unsigned int type,
+ unsigned int msg_len, unsigned int trans_len) {
+ pickit5_uint32_to_array(&buf[0], type);
+ pickit5_uint32_to_array(&buf[4], 0);
+ pickit5_uint32_to_array(&buf[8], msg_len);
+ pickit5_uint32_to_array(&buf[12], trans_len);
+}
+
+inline static void pickit5_create_script_header(unsigned char *buf, unsigned int arg_len, unsigned int script_len) {
+ pickit5_uint32_to_array(&buf[0], arg_len);
+ pickit5_uint32_to_array(&buf[4], script_len);
+}
+
+static void pickit5_setup(PROGRAMMER *pgm) {
+ pgm->cookie = mmt_malloc(sizeof(struct pdata));
+}
+
+static void pickit5_teardown(PROGRAMMER *pgm) {
+ mmt_free(pgm->cookie);
+ pgm->cookie = NULL;
+}
+
+static int pickit5_parseextparms(const PROGRAMMER *pgm, const LISTID extparms) {
+ LNODEID ln;
+ const char *extended_param;
+ int rv = 0;
+
+ for(ln = lfirst(extparms); ln; ln = lnext(ln)) {
+ extended_param = ldata(ln);
+
+ if(str_starts(extended_param, "vtarg=")) {
+ double voltage = -1.0;
+
+ if(sscanf(extended_param, "vtarg=%lf", &voltage) != 1) {
+
+ pmsg_error("invalid voltage parameter %s\n", extended_param);
+ rv = -1;
+ continue;
+ }
+ if(voltage < 0.1 && voltage > -1.0) {
+ my.power_source = POWER_SOURCE_NONE; // Voltage check disabled
+ continue;
+ } else if(voltage < 1.8 || voltage > 5.5) {
+ pmsg_error("voltage %1.1lf V outside valid range [1.8 V, 5.5 V]\n", voltage);
+ rv = -1;
+ continue;
+ } else {
+ my.power_source = POWER_SOURCE_INT; // PK supplies power
+ my.target_voltage = voltage;
+ continue;
+ }
+ }
+ if(str_starts(extended_param, "hvupdi")) {
+ my.hvupdi_enabled = 1;
+ continue;
+ }
+
+ if(str_eq(extended_param, "help")) {
+ msg_error("%s -c %s extended options:\n", progname, pgmid);
+ msg_error(" -x vtarg= Enable power output; must be in [1.8, 5.5] V\n");
+ msg_error(" -x hvupdi Enable high-voltage UPDI initialization\n");
+ msg_error(" -x help Show this help menu and exit\n");
+ return LIBAVRDUDE_EXIT;
+ }
+
+ pmsg_error("invalid extended parameter %s\n", extended_param);
+ rv = -1;
+ }
+ return rv;
+}
+
+// Internal functions
+
+// Type can be CMD, UPLOAD or DOWNLOAD
+#define SCR_CMD 0x0100
+#define SCR_UPLOAD 0x80000102
+#define SCR_DOWNLOAD 0x0C0000101
+
+static int pickit5_send_script(const PROGRAMMER *pgm, unsigned int script_type,
+ const unsigned char *script, unsigned int script_len,
+ const unsigned char *param, unsigned int param_len, unsigned int payload_len) {
+
+ if(script == NULL)
+ return -1;
+
+ unsigned int header_len = 16 + 8; // Header info + script header
+ unsigned int preamble_len = header_len + param_len;
+ unsigned int message_len = preamble_len + script_len;
+
+ if(message_len > 1023) // Required memory will exceed buffer size, abort
+ return -1; // 1 kB should be enough for everything
+
+ unsigned char *buf = my.txBuf;
+
+ pickit5_create_payload_header(&buf[0], script_type, message_len, payload_len);
+ pickit5_create_script_header(&buf[16], param_len, script_len);
+
+ if(param != NULL)
+ memcpy(&buf[24], param, param_len);
+
+ memcpy(&buf[preamble_len], script, script_len);
+
+ return serial_send(&pgm->fd, buf, message_len);
+}
+
+static int pickit5_read_response(const PROGRAMMER *pgm, char *fn_name) {
+ unsigned char *buf = my.rxBuf;
+
+ if(serial_recv(&pgm->fd, buf, 512) < 0) {
+ pmsg_error("reading from PICkit failed");
+ return -1;
+ }
+ unsigned int status = pickit5_array_to_uint32(&buf[0]);
+
+ if(status != 0x0D) {
+ pmsg_error("unexpected response in function %s", fn_name);
+ return -1;
+ }
+
+ return 0;
+}
+
+static int pickit5_send_script_done(const PROGRAMMER *pgm, char *func) {
+ unsigned char script_done[16];
+ unsigned int script_done_type = 0x0103;
+
+ pickit5_create_payload_header(script_done, script_done_type, 16, 0);
+ if(serial_send(&pgm->fd, script_done, 16) >= 0)
+ return pickit5_read_response(pgm, func);
+ pmsg_error("failed sending script done message");
+ return -1;
+}
+
+static int pickit5_open(PROGRAMMER *pgm, const char *port) {
+ if(!pgm->cookie) // Sanity
+ return -1;
+ pmsg_debug("%s(\"%s\")\n", __func__, port);
+ union pinfo pinfo;
+ LNODEID usbpid;
+ int rv = -1;
+
+#if !defined(HAVE_LIBUSB)
+ pmsg_error("need to be compiled with USB or HIDAPI support\n");
+ return -1;
+#endif
+
+ if(!str_starts(port, "usb")) {
+ pmsg_error("port names must start with usb\n");
+ return -1;
+ }
+ unsigned int new_vid = 0, new_pid = 0;
+ char *vidp, *pidp;
+
+ /*
+ * The syntax for usb devices is defined as:
+ *
+ * -P usb:vid:pid
+ * -P usb::pid
+ * -P usb:serialnumber
+ * -P usb
+ *
+ * First we check if we have two colons.
+ * Then check the filed between the two colons is empty
+ * Parse VID as hex number
+ * If it is empty, assume Microchip VID
+ * The PID is handled similary but can not be empty
+ *
+ * If there are fewer than two colons nothing is changed
+ */
+
+ vidp = strchr(port, ':');
+ if(vidp != NULL) {
+ vidp += 1;
+ pidp = strchr(vidp, ':');
+ if(pidp != NULL) {
+ if(vidp != pidp) { // User specified an VID
+ // First: Handle VID input
+ if(sscanf(vidp, "%x", &new_vid) != 1) {
+ pmsg_error("failed to parse -P VID input %s: unexpected format", vidp);
+ return -1;
+ }
+ } else { // VID space empty: default to Microchip
+ new_vid = USB_VENDOR_MICROCHIP;
+ }
+
+ // Now handle PID input
+ if(sscanf(pidp + 1, "%x", &new_pid) != 1) {
+ pmsg_error("failed to parse -P PID input %s: unexpected format", pidp+1);
+ return -1;
+ }
+
+ if((new_vid != 0) && (new_pid != 0)) {
+ pmsg_notice("overwriting VID:PID to %04x:%04x\n", new_vid, new_pid);
+ port = "usb"; // Overwrite the string to avoid confusing the libusb
+ }
+ } // pidp == NULL means vidp could point to serial number
+ } // vidp == NULL means just 'usb'
+
+ // If the config entry did not specify a USB PID, insert the default one
+ if(lfirst(pgm->usbpid) == NULL)
+ ladd(pgm->usbpid, (void *) USB_DEVICE_PICKIT5);
+
+ pinfo.usbinfo.vid = pgm->usbvid? pgm->usbvid: USB_VENDOR_MICROCHIP;
+
+ // PICkit 5 does not have support for HID, so no need to support it
+ serdev = &usb_serdev;
+ if(new_pid != 0 && new_vid != 0) { // In case a specific VID/PID was specified
+ pinfo.usbinfo.vid = new_vid;
+ pinfo.usbinfo.pid = new_pid;
+ pinfo.usbinfo.flags = PINFO_FL_SILENT;
+ pgm->fd.usb.max_xfer = USB_PK5_MAX_XFER;
+ pgm->fd.usb.rep = USB_PK5_CMD_READ_EP; // Command read
+ pgm->fd.usb.wep = USB_PK5_CMD_WRITE_EP; // Command write
+ pgm->fd.usb.eep = 0x00;
+ pgm->port = port;
+ rv = serial_open(port, pinfo, &pgm->fd);
+ } else { // Otherwise walk the list of config file PIDs
+ for(usbpid = lfirst(pgm->usbpid); rv < 0 && usbpid != NULL; usbpid = lnext(usbpid)) {
+ pinfo.usbinfo.flags = PINFO_FL_SILENT;
+ pinfo.usbinfo.pid = *(int *) (ldata(usbpid));
+ pgm->fd.usb.max_xfer = USB_PK5_MAX_XFER;
+ pgm->fd.usb.rep = USB_PK5_CMD_READ_EP; // Command read
+ pgm->fd.usb.wep = USB_PK5_CMD_WRITE_EP; // Command write
+ pgm->fd.usb.eep = 0x00;
+
+ pgm->port = port;
+ rv = serial_open(port, pinfo, &pgm->fd);
+ }
+ }
+
+ // Make USB serial number available to programmer
+ if(serdev && serdev->usbsn) {
+ pgm->usbsn = serdev->usbsn;
+ my.pk_op_mode = PK_OP_FOUND;
+
+ if(pinfo.usbinfo.pid == USB_DEVICE_PICKIT5)
+ my.pgm_type = PGM_TYPE_PK5;
+ else if(pinfo.usbinfo.pid == USB_DEVICE_PICKIT4_PIC_MODE)
+ my.pgm_type = PGM_TYPE_PK4;
+ else if(pinfo.usbinfo.pid == USB_DEVICE_SNAP_PIC_MODE)
+ my.pgm_type = PGM_TYPE_SNAP;
+ }
+
+ return rv;
+}
+
+static void pickit5_close(PROGRAMMER *pgm) {
+ pmsg_debug("%s()\n", __func__);
+ pickit5_set_vtarget(pgm, 0.0); // Switches off PICkit voltage regulator if enabled
+
+ serial_close(&pgm->fd);
+}
+
+static void pickit5_disable(const PROGRAMMER *pgm) {
+ return;
+}
+
+static void pickit5_enable(PROGRAMMER *pgm, const AVRPART *p) {
+ // Overwrite page sizes so that avrdude uses pages read/writes
+ // This will reduce overhead and increase speed
+ AVRMEM *mem;
+
+ if((mem = avr_locate_sram(p)))
+ mem->page_size = mem->size < 256? mem->size: 256;
+ if((mem = avr_locate_eeprom(p)))
+ mem->page_size = mem->size < 32? mem->size: 32;
+ if((mem = avr_locate_sib(p))) { // This is mandatory as PICkit is reading all 32 bytes at once
+ mem->page_size = 32;
+ mem->readsize = 32;
+ }
+}
+
+static void pickit5_display(const PROGRAMMER *pgm, const char *p) {
+ unsigned char *app = my.app_version;
+ unsigned char *sn = my.sernum_string;
+
+ if(pickit5_get_fw_info(pgm) < 0) {
+ msg_error("failed to get firmware info\n");
+ return;
+ }
+
+ msg_info("Application version : %02x.%02x.%02x\n", app[0], app[1], app[2]);
+ msg_info("Serial number : %s\n", sn);
+ my.pk_op_mode = PK_OP_RESPONDS;
+}
+
+static void pickit5_print_parms(const PROGRAMMER *pgm, FILE *fp) {
+ pickit5_get_vtarget(pgm, NULL);
+ fmsg_out(fp, "UPDI clock : %u kHz\n", my.actual_updi_clk / 1000);
+ fmsg_out(fp, "Target Vcc : %1.2f V\n", my.measured_vcc);
+ fmsg_out(fp, "Target current : %3u mA\n", my.measured_current);
+}
+
+static int pickit5_initialize(const PROGRAMMER *pgm, const AVRPART *p) {
+ pmsg_debug("%s()\n", __func__);
+ if(!pgm->cookie)
+ return -1;
+
+ if(my.pk_op_mode < PK_OP_FOUND) {
+ pmsg_error("failed to find a connected PICkit\n");
+ return -1;
+ }
+
+ int rc = -1;
+
+ if(pgm->prog_modes == PM_UPDI)
+ rc = get_pickit_updi_script(&(my.scripts), p->desc);
+
+ if(rc == -1)
+ return -1;
+ if(rc == -2) {
+ pmsg_error("failed to match scripts to %s, aborting\n", p->desc);
+ return -1;
+ }
+
+ if(my.hvupdi_enabled > 0) {
+ if(p->hvupdi_variant == 0)
+ pmsg_notice("high-voltage SYSCFG0 override on UPDI Pin enabled\n");
+ if(p->hvupdi_variant == 2)
+ pmsg_notice("high-voltage SYSCFG0 override on RST Pin enabled\n");
+ }
+
+ if(my.pk_op_mode < PK_OP_RESPONDS) {
+ if(pickit5_get_fw_info(pgm) < 0) // PK responds: we can try to enable voltage
+ return -1;
+ my.pk_op_mode = PK_OP_RESPONDS;
+ }
+
+ pickit5_set_ptg_mode(pgm);
+ pickit5_set_vtarget(pgm, 0.0); // Avoid the edge case when avrdude was CTRL+C'd but still provides power
+
+ // Now we try to figure out if we have to supply power from PICkit
+ double v_target;
+
+ pickit5_get_vtarget(pgm, &v_target);
+ if(v_target < 1.8) {
+ if(my.power_source == POWER_SOURCE_NONE) {
+ pmsg_warning("no external voltage detected but continuing anyway\n");
+ } else if(my.power_source == POWER_SOURCE_INT) {
+ pmsg_notice("no extenal Voltage detected; trying to supply from PICkit\n");
+
+ if(pickit5_set_vtarget(pgm, my.target_voltage) < 0)
+ return -1; // Set requested voltage
+
+ if(pickit5_get_vtarget(pgm, &v_target) < 0)
+ return -1; // Verify voltage
+
+ if(v_target < my.target_voltage - 0.25 // Voltage supply is not accurate: allow some room
+ || v_target > my.target_voltage + 0.15) {
+ pmsg_error("target voltage out of range, aborting\n");
+ return -1;
+ }
+ } else {
+ pmsg_error("no external voltage detected, aborting; overwrite this check with -x vtarg=0\n");
+ return -1;
+ }
+ } else {
+ my.power_source = POWER_SOURCE_EXT; // Overwrite user input
+ pmsg_notice("external Voltage detected: will not supply power\n");
+ }
+
+ my.pk_op_mode = PK_OP_READY;
+
+ // Target is powered, set the UPDI baudrate; adjust UPDICLKSEL if possible and neccessary
+ if(pickit5_program_enable(pgm, p) < 0)
+ return -1;
+
+ // Get SIB so we can get the NVM Version
+ if(pickit5_read_sib(pgm, p, my.sib_string) < 0) {
+ pmsg_error("failed to obtain System Info Block\n");
+ return -1;
+ }
+
+ if(pickit5_read_dev_id(pgm, p) < 0) {
+ pmsg_error("failed to obtain device ID\n");
+ return -1;
+ }
+
+ double bitclock = pgm->bitclock;
+ unsigned int baud = pgm->baudrate;
+
+ if(baud == 200000) { // If baud unchanged
+ if(bitclock > 0.0) {
+ baud = (unsigned int) (1.0 / pgm->bitclock); // Bitclock in us
+ }
+ } else {
+ if(bitclock > 0.0) {
+ pmsg_error("both -b baudrate and -B bitclock given; please use only one, aborting\n");
+ return -1;
+ }
+ }
+
+ if(baud < 300) { // Better be safe than sorry
+ pmsg_warning("UPDI needs a higher clock for operation, increasing UPDI to 300 Hz\n");
+ baud = 300;
+ }
+ if(baud > 225000) {
+ if(v_target < 2.9) {
+ pmsg_warning("UPDI needs a voltage of more than 2.9 V for a faster baudrate, limiting UPDI to 225 kHz\n");
+ baud = 225000;
+ } else {
+ if(baud > 900000) {
+ pmsg_warning("requested clock %u Hz too high, limiting UPDI to 900 kHz\n", baud);
+ baud = 900000;
+ }
+ pickit5_set_sck_period(pgm, 1.0 / 100000); // Start with 200 kHz
+ pickit5_write_cs_reg(pgm, UPDI_ASI_CTRLA, 0x01); // Change UPDI clock to 16 MHz
+ unsigned char ret_val = 0;
+
+ pickit5_read_cs_reg(pgm, UPDI_ASI_CTRLA, &ret_val);
+ if(ret_val != 0x01) {
+ pmsg_warning("failed to change UPDI clock, falling back to 225 kHz\n");
+ baud = 225000;
+ }
+ }
+ }
+ if(pickit5_set_sck_period(pgm, 1.0 / baud) >= 0) {
+ pmsg_notice("UPDI speed set to %i kHz\n", baud / 1000);
+ my.actual_updi_clk = baud;
+ } else {
+ pmsg_warning("failed to set UPDI speed, continuing\n");
+ my.actual_updi_clk = 100000; // Default clock?
+ }
+
+ pickit5_program_enable(pgm, p);
+ return 0;
+}
+
+static int pickit5_cmd(const PROGRAMMER *pgm, const unsigned char *cmd, unsigned char *res) {
+ return -2;
+}
+
+static int pickit5_program_enable(const PROGRAMMER *pgm, const AVRPART *p) {
+ pmsg_debug("%s()\n", __func__);
+ const unsigned char *enter_prog = my.scripts.EnterProgMode;
+ unsigned int enter_prog_len = my.scripts.EnterProgMode_len;
+
+ if(my.hvupdi_enabled && (my.pgm_type != PGM_TYPE_SNAP)) { // SNAP has no HV generation
+ if(p->hvupdi_variant == HV_UPDI_VARIANT_0) { // High voltage generation on UPDI line
+ enter_prog = my.scripts.EnterProgModeHvSp;
+ enter_prog_len = my.scripts.EnterProgModeHvSp_len;
+ } else if(p->hvupdi_variant == HV_UPDI_VARIANT_2) { // High voltage generation on RST line
+ enter_prog = my.scripts.EnterProgModeHvSpRst;
+ enter_prog_len = my.scripts.EnterProgModeHvSpRst_len;
+ }
+ }
+ if(my.pk_op_mode == PK_OP_READY) {
+ if(pickit5_send_script(pgm, SCR_CMD, enter_prog, enter_prog_len, NULL, 0, 0) < 0)
+ return -1;
+
+ if(pickit5_read_response(pgm, "Enter Programming Mode") < 0)
+ return -1;
+ }
+ return 0;
+}
+
+static int pickit5_program_disable(const PROGRAMMER *pgm, const AVRPART *p) {
+ pmsg_debug("%s()\n", __func__);
+ const unsigned char *enter_prog = my.scripts.ExitProgMode;
+ unsigned int enter_prog_len = my.scripts.ExitProgMode_len;
+
+ if(my.pk_op_mode == PK_OP_READY) {
+ if(pickit5_send_script(pgm, SCR_CMD, enter_prog, enter_prog_len, NULL, 0, 0) < 0)
+ return -1;
+
+ if(pickit5_read_response(pgm, "Exit Programming Mode") < 0)
+ return -1;
+ }
+ return 0;
+}
+
+static int pickit5_chip_erase(const PROGRAMMER *pgm, const AVRPART *p) {
+ pmsg_debug("%s()\n", __func__);
+
+ pickit5_program_enable(pgm, p);
+ const unsigned char *chip_erase = my.scripts.EraseChip;
+ unsigned int chip_erase_len = my.scripts.EraseChip_len;
+
+ if(pickit5_send_script(pgm, SCR_CMD, chip_erase, chip_erase_len, NULL, 0, 0) >= 0) {
+ if(pickit5_read_response(pgm, "Erase Chip") >= 0) {
+ if(pickit5_array_to_uint32(&(my.rxBuf[16])) == 0x00) {
+ pmsg_info("target successfully erased\n");
+ my.pk_op_mode = PK_OP_READY;
+ pickit5_program_enable(pgm, p);
+ return 0;
+ }
+ }
+ }
+
+ pmsg_error("chip erase failed\n");
+ return -1;
+}
+
+static int pickit5_paged_load(const PROGRAMMER *pgm, const AVRPART *p, const AVRMEM *mem,
+ unsigned int page_size, unsigned int address, unsigned int n_bytes) {
+
+ return pickit5_read_array(pgm, p, mem, address, n_bytes, &mem->buf[address]);
+}
+
+static int pickit5_paged_write(const PROGRAMMER *pgm, const AVRPART *p, const AVRMEM *mem,
+ unsigned int page_size, unsigned int address, unsigned int n_bytes) {
+
+ return pickit5_write_array(pgm, p, mem, address, n_bytes, &mem->buf[address]);
+}
+
+// Sets UPDI Frequency in kHz
+static int pickit5_set_sck_period(const PROGRAMMER *pgm, double sckperiod) {
+ pmsg_debug("%s()\n", __func__);
+ double frq = (0.001 / sckperiod) + 0.5; // 1ms/period = kHz; round up
+ const unsigned char *set_speed = my.scripts.SetSpeed;
+ int set_speed_len = my.scripts.SetSpeed_len;
+ unsigned char buf[4];
+
+ pickit5_uint32_to_array(buf, frq);
+ if(pickit5_send_script(pgm, SCR_CMD, set_speed, set_speed_len, buf, 4, 0) < 0)
+ return -1;
+ if(pickit5_read_response(pgm, "Set UPDI Speed") < 0)
+ return -1;
+ return 0;
+}
+
+static int pickit5_write_byte(const PROGRAMMER *pgm, const AVRPART *p,
+ const AVRMEM *mem, unsigned long addr, unsigned char value) {
+ int rc = pickit5_write_array(pgm, p, mem, addr, 1, &value);
+
+ if(rc < 0)
+ return rc;
+ return 0;
+}
+
+static int pickit5_read_byte(const PROGRAMMER *pgm, const AVRPART *p,
+ const AVRMEM *mem, unsigned long addr, unsigned char *value) {
+ int rc = pickit5_read_array(pgm, p, mem, addr, 1, value);
+
+ if(rc < 0)
+ return rc;
+ return 0;
+}
+
+// UPDI Specific function providing a reduced overhead when writing a single byte
+static int pickit5_updi_write_byte(const PROGRAMMER *pgm, const AVRPART *p,
+ const AVRMEM *mem, unsigned long addr, unsigned char value) {
+
+ if(mem->size < 1 || addr > (unsigned long) mem->size) {
+ pmsg_error("address %i out of range for %s [0, %i]\n", (unsigned) addr, mem->desc, mem->size);
+ return -1;
+ }
+ addr += mem->offset;
+ pmsg_debug("%s(0x%4X, %i)\n", __func__, (unsigned) addr, value);
+ // This script is based on WriteCSreg; reduces overhead by avoiding writing data EP
+ const unsigned char h_len = 24; // 16 + 8
+ const unsigned char p_len = 8;
+ const unsigned char s_len = 8;
+ const unsigned char m_len = h_len + p_len + s_len;
+
+ unsigned char write8_fast[] = {
+ 0x00, 0x01, 0x00, 0x00, // [0] SCR_CMD
+ 0x00, 0x00, 0x00, 0x00, // [4] always 0
+ m_len, 0x00, 0x00, 0x00, // [8] message length = 16 + 8 + param (8) + script (8) = 40
+ 0x00, 0x00, 0x00, 0x00, // [12] keep at 0 to receive the data in the "response"
+
+ p_len, 0x00, 0x00, 0x00, // [16] param length: 8 bytes
+ s_len, 0x00, 0x00, 0x00, // [20] length of script: 8 bytes
+
+ 0x00, 0x00, 0x00, 0x00, // [24] param: address to write to, will be overwritten
+ 0x00, 0x00, 0x00, 0x00, // [28] param: byte to write, will be overwritten
+
+ // Script itself:
+ 0x91, 0x00, // Copy first 4 bytes of param to reg 0
+ 0x91, 0x01, // Copy second 4 bytes of param to reg 1
+ 0x1E, 0x06, 0x00, 0x01, // Store to address in reg 0 the byte in reg 1
+ };
+ write8_fast[24] = (((unsigned char *) &addr)[0]);
+ write8_fast[25] = (((unsigned char *) &addr)[1]);
+ write8_fast[28] = value;
+
+ serial_send(&pgm->fd, write8_fast, m_len);
+ unsigned char *buf = my.rxBuf;
+
+ if(serial_recv(&pgm->fd, buf, 512) >= 0) { // Read response
+ if(buf[0] == 0x0D) {
+ return 0;
+ }
+ }
+ return -1;
+}
+
+// UPDI-specific function providing a reduced overhead when reading a single byte
+static int pickit5_updi_read_byte(const PROGRAMMER *pgm, const AVRPART *p,
+ const AVRMEM *mem, unsigned long addr, unsigned char *value) {
+ if(mem_is_sram(mem) || mem_is_io(mem)
+ || mem_is_lock(mem) || mem_is_in_fuses(mem)) {
+ if(mem->size < 1 || addr > (unsigned long) mem->size) {
+ pmsg_error("address %i out of range for %s [0, %i]\n", (unsigned) addr, mem->desc, mem->size);
+ return -1;
+ }
+ addr += mem->offset;
+ pmsg_debug("%s(0x%4X)\n", __func__, (unsigned int) addr);
+ // This script is based on ReadSIB; reduces overhead by avoiding readind data EP
+ const unsigned char h_len = 24; // 16 + 8
+ const unsigned char p_len = 4;
+ const unsigned char s_len = 6;
+ const unsigned char m_len = h_len + p_len + s_len;
+
+ unsigned char read8_fast[] = {
+ 0x00, 0x01, 0x00, 0x00, // [0] SCR_CMD
+ 0x00, 0x00, 0x00, 0x00, // [4] always 0
+ m_len, 0x00, 0x00, 0x00, // [8] message length = 16 + 8 + param (4) + script (6) = 34
+ 0x00, 0x00, 0x00, 0x00, // [12] keep at 0 to receive the data in the "response"
+
+ p_len, 0x00, 0x00, 0x00, // [16] param length: 4 bytes
+ s_len, 0x00, 0x00, 0x00, // [20] length of script: 6 bytes
+
+ 0x00, 0x00, 0x00, 0x00, // [24] param: address to read from, will be overwritten
+
+ // Script itself:
+ 0x91, 0x00, // Copy first 4 bytes of param to reg 0
+ 0x1E, 0x03, 0x00, // Load byte from address in reg 0
+ 0x9F // Send data from 0x1E to "response"
+ };
+ read8_fast[24] = (((unsigned char *) &addr)[0]);
+ read8_fast[25] = (((unsigned char *) &addr)[1]);
+
+ serial_send(&pgm->fd, read8_fast, m_len);
+ unsigned char *buf = my.rxBuf;
+
+ if(serial_recv(&pgm->fd, buf, 512) >= 0) { // Read response
+ if(buf[0] == 0x0D) {
+ if(buf[20] == 0x01) {
+ *value = buf[24];
+ return 0;
+ }
+ }
+ }
+ return -1;
+ } else { // Fall back to standard function
+ int rc = pickit5_read_array(pgm, p, mem, addr, 1, value);
+
+ if(rc < 0)
+ return rc;
+ return 0;
+ }
+}
+
+// Return numbers of byte written
+static int pickit5_write_array(const PROGRAMMER *pgm, const AVRPART *p,
+ const AVRMEM *mem, unsigned long addr, int len, unsigned char *value) {
+ pmsg_debug("%s(%s, 0x%04x, %i)", __func__, mem->desc, (unsigned int) addr, len);
+
+ if(len > mem->size || mem->size < 1) {
+ pmsg_error("cannot write to %s %s owing to its size %d\n", p->desc, mem->desc, mem->size);
+ return -1;
+ }
+ if(addr >= (unsigned long) mem->size) {
+ pmsg_error("cannot write to %s %s as address 0x%04lx outside range [0, 0x%04x]\n",
+ p->desc, mem->desc, addr, mem->size - 1);
+ return -1;
+ }
+
+ const unsigned char *write_bytes = NULL;
+ unsigned int write_bytes_len = 0;
+
+ if((mem_is_in_flash(mem) && (len == mem->page_size))) {
+ write_bytes = my.scripts.WriteProgmem;
+ write_bytes_len = my.scripts.WriteProgmem_len;
+ } else if(mem_is_eeprom(mem)) {
+ write_bytes = my.scripts.WriteDataEEmem;
+ write_bytes_len = my.scripts.WriteDataEEmem_len;
+ } else if(mem_is_user_type(mem)) {
+ write_bytes = my.scripts.WriteIDmem;
+ write_bytes_len = my.scripts.WriteIDmem_len;
+ } else if(mem_is_in_fuses(mem)) {
+ write_bytes = my.scripts.WriteConfigmem;
+ write_bytes_len = my.scripts.WriteConfigmem_len;
+ } else if(!mem_is_readonly(mem)) { // SRAM, IO, LOCK
+ if((len == 1) && (pgm->prog_modes == PM_UPDI)) {
+ return pickit5_updi_write_byte(pgm, p, mem, addr, value[0]);
+ }
+ write_bytes = my.scripts.WriteMem8;
+ write_bytes_len = my.scripts.WriteMem8_len;
+ } else {
+ pmsg_error("unsupported memory %s\n", mem->desc);
+ return -2;
+ }
+ addr += mem->offset;
+
+ unsigned char buf[8];
+
+ pickit5_uint32_to_array(&buf[0], addr);
+ pickit5_uint32_to_array(&buf[4], len);
+
+ if(pickit5_send_script(pgm, SCR_DOWNLOAD, write_bytes, write_bytes_len, buf, 8, len) < 0) {
+ pmsg_error("sending script failed\n");
+ return -1;
+ }
+
+ if(pickit5_read_response(pgm, "Write Bytes") < 0) {
+ pmsg_error("reading script response failed\n");
+ return -1;
+ }
+ if(usbdev_data_send(&pgm->fd, value, len) < 0) {
+ pmsg_error("failed when sending data\n");
+ return -1;
+ }
+ if(pickit5_get_status(pgm, CHECK_ERROR) < 0) {
+ pmsg_error("error check failed\n");
+ return -1;
+ }
+ if(pickit5_send_script_done(pgm, "Write Bytes") < 0) {
+ pmsg_error("sending script done message failed\n");
+ return -1;
+ }
+ return len;
+}
+
+// Return numbers of byte read
+static int pickit5_read_array(const PROGRAMMER *pgm, const AVRPART *p,
+ const AVRMEM *mem, unsigned long addr, int len, unsigned char *value) {
+ pmsg_debug("%s(%u, %u)\n", __func__, (unsigned) addr, len);
+
+ if(len > mem->size || mem->size < 1) {
+ pmsg_error("cannot read from %s %s owing to its size %d\n", p->desc, mem->desc, mem->size);
+ return -1;
+ }
+ if(addr >= (unsigned long) mem->size) {
+ pmsg_error("cannot read from %s %s as address 0x%04lx outside range [0, 0x%04x]\n",
+ p->desc, mem->desc, addr, mem->size - 1);
+ return -1;
+ }
+
+ const unsigned char *read_bytes = NULL;
+ unsigned int read_bytes_len = 0;
+
+ if(mem_is_in_flash(mem)) {
+ read_bytes = my.scripts.ReadProgmem;
+ read_bytes_len = my.scripts.ReadProgmem_len;
+ } else if(mem_is_eeprom(mem)) {
+ read_bytes = my.scripts.ReadDataEEmem;
+ read_bytes_len = my.scripts.ReadDataEEmem_len;
+ } else if(mem_is_user_type(mem)) {
+ read_bytes = my.scripts.ReadIDmem;
+ read_bytes_len = my.scripts.ReadIDmem_len;
+ } else if(mem_is_sib(mem)) {
+ if(len == 1) {
+ *value = my.sib_string[addr];
+ return 0;
+ } else if(len == 32) {
+ memcpy(value, my.sib_string, 32);
+ return 32;
+ }
+ return -1;
+ } else if(mem_is_signature(mem)) {
+ if(len == 1) {
+ *value = my.devID[addr];
+ return 0;
+ }
+ return -1;
+ } else if(mem_is_in_sigrow(mem) || mem_is_user_type(mem) || mem_is_a_fuse(mem)) {
+ read_bytes = my.scripts.ReadConfigmem;
+ read_bytes_len = my.scripts.ReadConfigmem_len;
+ } else if(!mem_is_readonly(mem)) { // SRAM, IO, LOCK, USERROW
+ if((len == 1) && (pgm->prog_modes == PM_UPDI)) {
+ return pickit5_updi_read_byte(pgm, p, mem, addr, value);
+ }
+ read_bytes = my.scripts.ReadMem8;
+ read_bytes_len = my.scripts.ReadMem8_len;
+ } else {
+ pmsg_error("unsupported memory %s\n", mem->desc);
+ return -2;
+ }
+
+ addr += mem->offset;
+ unsigned char buf[8];
+
+ pickit5_uint32_to_array(&buf[0], addr);
+ pickit5_uint32_to_array(&buf[4], len);
+
+ if(pickit5_send_script(pgm, SCR_UPLOAD, read_bytes, read_bytes_len, buf, 8, len) < 0) {
+ pmsg_error("sending script failed\n");
+ return -1;
+ }
+ if(pickit5_read_response(pgm, "Read Bytes") < 0) {
+ pmsg_error("unexpected read response\n");
+ return -1;
+ }
+ if(usbdev_data_recv(&pgm->fd, value, len) < 0) {
+ pmsg_error("reading data memory failed\n");
+ return -1;
+ }
+ if(pickit5_send_script_done(pgm, "Read Bytes") < 0) {
+ pmsg_error("sending script done message failed\n");
+ return -1;
+ }
+ return len;
+}
+
+static int pickit5_read_dev_id(const PROGRAMMER *pgm, const AVRPART *p) {
+ pmsg_debug("%s()\n", __func__);
+ const unsigned char *read_id = my.scripts.GetDeviceID; // Defaults
+ unsigned int read_id_len = my.scripts.GetDeviceID_len;
+
+ if(my.nvm_version >= '0' && my.nvm_version <= '9') {
+ read_id = get_devid_script_by_nvm_ver(my.nvm_version); // Only address changes, not length
+ }
+
+ if(pickit5_send_script(pgm, SCR_CMD, read_id, read_id_len, NULL, 0, 0) < 0)
+ return -1;
+ if(pickit5_read_response(pgm, "Read Device ID") >= 0) {
+ if(my.rxBuf[0] == 0x0D) {
+ if(my.rxBuf[20] == 0x04) {
+ memcpy(my.devID, &my.rxBuf[24], 4);
+ return 0;
+ } else {
+ if(my.hvupdi_enabled && p->hvupdi_variant == HV_UPDI_VARIANT_2) {
+ pmsg_info("failed to get DeviceID with activated HV Pulse on RST\n");
+ pmsg_info("if the wiring is correct, try connecting a 16 V, 1 uF cap between RST and GND\n");
+ }
+ }
+ }
+ }
+ return -1;
+}
+
+static int pickit5_read_sib(const PROGRAMMER *pgm, const AVRPART *p, char *sib) {
+ pmsg_debug("%s()\n", __func__);
+ const unsigned char *read_sib = my.scripts.ReadSIB;
+ unsigned int read_sib_len = my.scripts.ReadSIB_len;
+
+ if(pickit5_send_script(pgm, SCR_CMD, read_sib, read_sib_len, NULL, 0, 0) < 0)
+ return -1;
+ if(pickit5_read_response(pgm, "Read SIB") < 0)
+ return -1;
+ unsigned int ret_len = pickit5_array_to_uint32(&(my.rxBuf[20]));
+
+ if(ret_len == 32) {
+ memcpy(sib, &my.rxBuf[24], 32);
+ sib[31] = 0x00; // Known zero-terminator
+ my.nvm_version = sib[10];
+ return 0;
+ }
+ my.nvm_version = 0xFF;
+ return -1;
+}
+
+static int pickit5_read_chip_rev(const PROGRAMMER *pgm, const AVRPART *p, unsigned char *chip_rev) {
+ pmsg_debug("%s()\n", __func__);
+ *chip_rev = my.devID[3];
+ return 0;
+}
+
+static int pickit5_write_cs_reg(const PROGRAMMER *pgm, unsigned int addr, unsigned char value) {
+ pmsg_debug("%s(%u, %i)", __func__, addr, value);
+ const unsigned char *write_cs = my.scripts.WriteCSreg;
+ unsigned int write_cs_len = my.scripts.WriteCSreg_len;
+
+ if(addr > 0x0C) {
+ pmsg_error("CS reg %i out of range [0x00, 0x0C], addr\n", addr);
+ return -1;
+ }
+
+ unsigned char buf[2];
+
+ buf[0] = addr;
+ buf[1] = value;
+
+ if(pickit5_send_script(pgm, SCR_CMD, write_cs, write_cs_len, buf, 2, 0) < 0) {
+ pmsg_error("sending script failed\n");
+ return -1;
+ }
+
+ if(pickit5_read_response(pgm, "Write CS reg") < 0) {
+ pmsg_error("reading script response failed\n");
+ return -1;
+ }
+ return 1;
+}
+
+static int pickit5_read_cs_reg(const PROGRAMMER *pgm, unsigned int addr, unsigned char *value) {
+ pmsg_debug("%s(%i)\n", __func__, addr);
+ const unsigned char *read_cs = my.scripts.ReadCSreg;
+ unsigned int read_cs_len = my.scripts.ReadCSreg_len;
+
+ if(addr > 0x0C) {
+ pmsg_error("CS reg %i out of range [0x00, 0x0C], addr\n", addr);
+ return -1;
+ }
+
+ unsigned char buf[1];
+
+ buf[0] = addr;
+
+ if(pickit5_send_script(pgm, SCR_UPLOAD, read_cs, read_cs_len, buf, 1, 1) < 0) {
+ pmsg_error("sending script failed\n");
+ return -1;
+ }
+ if(pickit5_read_response(pgm, "Read CS") < 0) {
+ pmsg_error("unexpected read response\n");
+ return -1;
+ }
+ if(usbdev_data_recv(&pgm->fd, value, 1) < 0) {
+ pmsg_error("reading CS memory failed\n");
+ return -1;
+ }
+ if(pickit5_send_script_done(pgm, "Read CS") < 0) {
+ pmsg_error("sending script done message failed\n");
+ return -1;
+ }
+ return 0;
+}
+
+static int pickit5_get_fw_info(const PROGRAMMER *pgm) {
+ pmsg_debug("%s()\n", __func__);
+ unsigned char *buf = my.rxBuf;
+ const unsigned char get_fw[] = { 0xE1 };
+
+ if(serial_send(&pgm->fd, get_fw, 1) < 0) {
+ pmsg_error("sending command via serial_send() failed\n");
+ return -1;
+ }
+
+ if(serial_recv(&pgm->fd, buf, 512) < 0) {
+ pmsg_error("receiving FW response failed\n");
+ return -1;
+ }
+
+ if(buf[0] != 0xE1) {
+ pmsg_error("unexpected device response for get firmware info command\n");
+ return -1;
+ }
+
+ memcpy(my.app_version, &(my.rxBuf[3]), 3);
+ memcpy(my.fw_info, &(my.rxBuf[7]), 16);
+ memcpy(my.sernum_string, &(my.rxBuf[32]), 20);
+ my.sernum_string[19] = 0; // Known zero-terminator
+ return 0;
+}
+
+static int pickit5_set_vtarget(const PROGRAMMER *pgm, double v) {
+ if(my.pgm_type >= PGM_TYPE_SNAP) // SNAP can't supply power, ignore
+ return 0;
+
+ unsigned char set_vtarget[] = {
+ 0x40,
+ 0x00, 0x00, 0x00, 0x00, // Vdd
+ 0x00, 0x00, 0x00, 0x00, // Vpp
+ 0x00, 0x00, 0x00, 0x00, // Vpp_op
+ 0x42, 0x43,
+ };
+ unsigned char power_source[] = {
+ 0x46, 0x00, 0x00, 0x00, 0x00,
+ };
+ unsigned char disable_power[] = {
+ 0x44
+ };
+
+ if(v < 1.0) { // Anything below 1 V equals disabling Power
+ pmsg_debug("%s(disable)\n", __func__);
+ if(pickit5_send_script(pgm, SCR_CMD, power_source, 5, NULL, 0, 0) < 0)
+ return -1;
+ if(pickit5_read_response(pgm, "Select external power source") < 0)
+ return -1;
+
+ if(pickit5_send_script(pgm, SCR_CMD, disable_power, 1, NULL, 0, 0) < 0)
+ return -1;
+ if(pickit5_read_response(pgm, "Disabling Power") < 0)
+ return -1;
+ usleep(50000); // There might be some caps, let them discharge
+ } else {
+ pmsg_debug("%s(%1.2f V)\n", __func__, v);
+ power_source[1] = 0x01;
+ if(pickit5_send_script(pgm, SCR_CMD, power_source, 5, NULL, 0, 0) < 0)
+ return -1;
+ if(pickit5_read_response(pgm, "Select internal power source") < 0)
+ return -1;
+
+ int vtarg = (int) (v * 1000.0);
+
+ pickit5_uint32_to_array(&set_vtarget[1], vtarg);
+ pickit5_uint32_to_array(&set_vtarget[5], vtarg);
+ pickit5_uint32_to_array(&set_vtarget[9], vtarg);
+
+ if(pickit5_send_script(pgm, SCR_CMD, set_vtarget, 15, NULL, 0, 0) < 0)
+ return -1;
+
+ if(pickit5_read_response(pgm, "set_vtarget") < 0)
+ return -1;
+ }
+ return 0;
+}
+
+static int pickit5_get_vtarget(const PROGRAMMER *pgm, double *v) {
+ const unsigned char get_vtarget[] = { 0x47, };
+ unsigned char *buf = my.rxBuf;
+
+ pmsg_debug("%s()\n", __func__);
+
+ if(pickit5_send_script(pgm, SCR_CMD, get_vtarget, 1, NULL, 0, 0) < 0)
+ return -1;
+
+ if(pickit5_read_response(pgm, "get_vtarget") < 0)
+ return -1;
+
+ // 24 - internal Vdd [mV]
+ // 28 - target Vdd [mV]
+ // 48 - Vdd Current Sense [mA]
+ my.measured_vcc = pickit5_array_to_uint32(&buf[28]) / 1000.0;
+ my.measured_current = pickit5_array_to_uint32(&buf[48]);
+
+ pmsg_notice("target Vdd: %1.2f V, target current: %u mA\n", my.measured_vcc, my.measured_current);
+
+ if(v != NULL)
+ *v = my.measured_vcc;
+ return 0;
+}
+
+static int pickit5_set_ptg_mode(const PROGRAMMER *pgm) {
+ if(my.pgm_type >= PGM_TYPE_SNAP) // Don't bother if Programmer doesn't support PTG
+ return 0; // Side note: Bitmask would be probably better in the future
+
+ unsigned char ptg_mode[] = {
+ 0x5E, 0x00, 0x00, 0x00, 0x00,
+ };
+ unsigned char buf[8];
+
+ pmsg_debug("%s()\n", __func__);
+
+ if(pickit5_send_script(pgm, SCR_UPLOAD, ptg_mode, 5, NULL, 0, 4) < 0)
+ return -1;
+ if(pickit5_read_response(pgm, "Set PTG mode") < 0)
+ return -1;
+
+ if(usbdev_data_recv(&pgm->fd, buf, 4) < 0)
+ return -1;
+ if(pickit5_send_script_done(pgm, "Set PTG Mode") < 0)
+ return -1;
+ return 0;
+}
+
+static int pickit5_get_status(const PROGRAMMER *pgm, unsigned char status) {
+ unsigned char *buf = my.txBuf;
+ const unsigned int type = 0x0105;
+ unsigned int key_len = 0;
+
+ if(CHECK_ERROR == status) {
+ key_len = strlen("ERROR_STATUS_KEY") + 1;
+ memcpy(&buf[16], "ERROR_STATUS_KEY", key_len);
+ } else if(BIST_TEST == status) {
+ key_len = strlen("BIST Tested") + 1;
+ memcpy(&buf[16], "BIST Tested", key_len);
+ } else if(BIST_RESULT == status) {
+ key_len = strlen("BIST Results") + 1;
+ memcpy(&buf[16], "BIST Results", key_len);
+ }
+ if(0 == key_len) {
+ pmsg_error("unknown key type %d passed to %s()", status, __func__);
+ return -1;
+ }
+ unsigned int msg_len = 16 + key_len;
+
+ pickit5_create_payload_header(buf, type, msg_len, 0);
+ serial_send(&pgm->fd, buf, msg_len);
+ serial_recv(&pgm->fd, my.rxBuf, 512);
+ if(pickit5_check_ret_status(pgm) < 0) {
+ return -1;
+ }
+ unsigned int status_len = pickit5_array_to_uint32(&(my.rxBuf[8]));
+
+ if(status_len > 64)
+ status_len = 64;
+ my.rxBuf[16 + status_len] = 0x00; // Known zero-terminator
+ if(str_starts((const char *) &(my.rxBuf[16]), "NONE") == 0) {
+ pmsg_error("PICkit error status report: %s", buf);
+ return -1;
+ }
+ return 0;
+}
+
+inline static int pickit5_check_ret_status(const PROGRAMMER *pgm) {
+ unsigned char ret = my.rxBuf[0];
+
+ if(0x0D != ret) {
+ pmsg_error("PICkit5 bad response %i", ret);
+ return -1;
+ }
+ return 0;
+}
+
+void pickit5_initpgm(PROGRAMMER *pgm) {
+ strcpy(pgm->type, "pickit5");
+
+ // Mandatory functions
+ pgm->initialize = pickit5_initialize;
+ pgm->parseextparams = pickit5_parseextparms;
+ pgm->display = pickit5_display;
+ pgm->enable = pickit5_enable;
+ pgm->disable = pickit5_disable;
+ pgm->program_enable = pickit5_program_enable;
+ pgm->chip_erase = pickit5_chip_erase;
+ pgm->cmd = pickit5_cmd;
+ pgm->open = pickit5_open;
+ pgm->close = pickit5_close;
+ pgm->write_byte = pickit5_write_byte;
+ pgm->read_byte = pickit5_read_byte;
+
+ // Optional functions
+ pgm->paged_write = pickit5_paged_write;
+ pgm->paged_load = pickit5_paged_load;
+ pgm->setup = pickit5_setup;
+ pgm->teardown = pickit5_teardown;
+ pgm->set_sck_period = pickit5_set_sck_period;
+ pgm->end_programming = pickit5_program_disable;
+ pgm->read_sib = pickit5_read_sib;
+ pgm->read_chip_rev = pickit5_read_chip_rev;
+ pgm->set_vtarget = pickit5_set_vtarget;
+ pgm->get_vtarget = pickit5_get_vtarget;
+ pgm->print_parms = pickit5_print_parms;
+
+}
+
+#if defined(HAVE_USB_H)
+static int usb_fill_buf(const union filedescriptor *fd, int maxsize, int ep, int use_interrupt_xfer) {
+ int rv = (use_interrupt_xfer? usb_interrupt_read: usb_bulk_read)(fd->usb.handle, ep, cx->usb_buf,
+ maxsize, 10000);
+
+ if(rv < 0) {
+ pmsg_notice2("%s(): usb_%s_read() error: %s\n", __func__,
+ use_interrupt_xfer? "interrupt": "bulk", usb_strerror());
+ return -1;
+ }
+
+ cx->usb_buflen = rv;
+ cx->usb_bufptr = 0;
+
+ return 0;
+}
+
+static int usbdev_data_recv(const union filedescriptor *fd, unsigned char *buf, size_t nbytes) {
+ int i, amnt;
+ unsigned char *p = buf;
+
+ if(fd->usb.handle == NULL)
+ return -1;
+
+ for(i = 0; nbytes > 0;) {
+ if(cx->usb_buflen <= cx->usb_bufptr) {
+ if(usb_fill_buf(fd, fd->usb.max_xfer, USB_PK5_DATA_READ_EP, fd->usb.use_interrupt_xfer) < 0)
+ return -1;
+ }
+ amnt = cx->usb_buflen - cx->usb_bufptr > (int) nbytes? (int) nbytes: cx->usb_buflen - cx->usb_bufptr;
+ memcpy(buf + i, cx->usb_buf + cx->usb_bufptr, amnt);
+ cx->usb_bufptr += amnt;
+ nbytes -= amnt;
+ i += amnt;
+ }
+
+ if(verbose > 4)
+ trace_buffer(__func__, p, i);
+
+ return 0;
+}
+
+static int usbdev_data_send(const union filedescriptor *fd, const unsigned char *bp, size_t mlen) {
+ int rv;
+ int i = mlen;
+ const unsigned char *p = bp;
+ int tx_size;
+
+ if(fd->usb.handle == NULL)
+ return -1;
+
+ /*
+ * Split the frame into multiple packets. It's important to make sure we
+ * finish with a short packet, or else the device won't know the frame is
+ * finished. For example, if we need to send 64 bytes, we must send a packet
+ * of length 64 followed by a packet of length 0.
+ */
+ do {
+ tx_size = ((int) mlen < fd->usb.max_xfer)? (int) mlen: fd->usb.max_xfer;
+ if(fd->usb.use_interrupt_xfer)
+ rv = usb_interrupt_write(fd->usb.handle, USB_PK5_DATA_WRITE_EP, (char *) bp, tx_size, 10000);
+ else
+ rv = usb_bulk_write(fd->usb.handle, USB_PK5_DATA_WRITE_EP, (char *) bp, tx_size, 10000);
+ if(rv != tx_size) {
+ pmsg_error("wrote %d out of %d bytes, err = %s\n", rv, tx_size, usb_strerror());
+ return -1;
+ }
+ bp += tx_size;
+ mlen -= tx_size;
+ } while(mlen > 0);
+
+ if(verbose > 3)
+ trace_buffer(__func__, p, i);
+ return 0;
+}
+#else
+
+/*
+ * Allow compiling without throwing dozen errors
+ * We need libusb so we can access specific Endpoints
+ * This does not seem to be possible with usbhid
+ */
+
+static int usbdev_data_recv(const union filedescriptor *fd, unsigned char *buf, size_t nbytes) {
+ return -1;
+}
+
+static int usbdev_data_send(const union filedescriptor *fd, const unsigned char *bp, size_t mlen) {
+ return -1;
+}
+#endif
+
+#else // defined(HAVE_LIBUSB) || defined(HAVE_LIBUSB_1_0)
+static int pickit5_nousb_open(PROGRAMMER *pgm, const char *name);
+
+static int pickit5_nousb_open(PROGRAMMER *pgm, const char *name) {
+ pmsg_error("no usb support; please compile again with libusb installed\n");
+
+ return -1;
+}
+
+void pickit5_initpgm(PROGRAMMER *pgm) {
+ strcpy(pgm->type, "pickit5");
+
+ pgm->open = pickit5_nousb_open;
+}
+#endif // defined(HAVE_USB_H) || defined(HAVE_LUSB0_USB_H)
+
+const char pickit5_desc[] = "Microchip's PICkit 5 Programmer/Debugger";
diff --git a/src/pickit5.h b/src/pickit5.h
new file mode 100644
index 000000000..c6597073f
--- /dev/null
+++ b/src/pickit5.h
@@ -0,0 +1,32 @@
+/*
+ * avrdude - A Downloader/Uploader for AVR device programmers
+ * Copyright (C) 2024 MX682X
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
+
+#ifndef pickit5_h
+#define pickit5_h
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+extern const char pickit5_desc[];
+void pickit5_initpgm(PROGRAMMER *pgm);
+
+#ifdef __cplusplus
+}
+#endif
+#endif
diff --git a/src/pickit5_lut.h b/src/pickit5_lut.h
new file mode 100644
index 000000000..27b4c3327
--- /dev/null
+++ b/src/pickit5_lut.h
@@ -0,0 +1,83 @@
+/* This file was auto-generated by scripts_decoder.py, any changes will be overwritten */
+
+/*
+ * avrdude - A Downloader/Uploader for AVR device programmers
+ * Copyright (C) 2024 MX682X
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
+
+
+#ifndef pickit5_lut_h
+#define pickit5_lut_h
+
+#ifdef __cplusplus
+ extern "C" {
+#endif
+
+struct avr_script_lut {
+ const unsigned char *EnterProgMode;
+ unsigned int EnterProgMode_len;
+ const unsigned char *EnterProgModeHvSp;
+ unsigned int EnterProgModeHvSp_len;
+ const unsigned char *EnterProgModeHvSpRst;
+ unsigned int EnterProgModeHvSpRst_len;
+ const unsigned char *EnterProgModeHvUpt;
+ unsigned int EnterProgModeHvUpt_len;
+ const unsigned char *ExitProgMode;
+ unsigned int ExitProgMode_len;
+ const unsigned char *SetSpeed;
+ unsigned int SetSpeed_len;
+ const unsigned char *GetDeviceID;
+ unsigned int GetDeviceID_len;
+ const unsigned char *EraseChip;
+ unsigned int EraseChip_len;
+ const unsigned char *WriteProgmem;
+ unsigned int WriteProgmem_len;
+ const unsigned char *ReadProgmem;
+ unsigned int ReadProgmem_len;
+ const unsigned char *WriteDataEEmem;
+ unsigned int WriteDataEEmem_len;
+ const unsigned char *ReadDataEEmem;
+ unsigned int ReadDataEEmem_len;
+ const unsigned char *WriteCSreg;
+ unsigned int WriteCSreg_len;
+ const unsigned char *ReadCSreg;
+ unsigned int ReadCSreg_len;
+ const unsigned char *WriteMem8;
+ unsigned int WriteMem8_len;
+ const unsigned char *ReadMem8;
+ unsigned int ReadMem8_len;
+ const unsigned char *WriteConfigmem;
+ unsigned int WriteConfigmem_len;
+ const unsigned char *ReadConfigmem;
+ unsigned int ReadConfigmem_len;
+ const unsigned char *WriteIDmem;
+ unsigned int WriteIDmem_len;
+ const unsigned char *ReadIDmem;
+ unsigned int ReadIDmem_len;
+ const unsigned char *ReadSIB;
+ unsigned int ReadSIB_len;
+
+};
+
+typedef struct avr_script_lut SCRIPT;
+const unsigned char * get_devid_script_by_nvm_ver(unsigned char version);
+int get_pickit_updi_script(SCRIPT *scr, const char *partdesc);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // pickit5_lut_h
diff --git a/src/pickit5_updi_lut.c b/src/pickit5_updi_lut.c
new file mode 100644
index 000000000..d279f576f
--- /dev/null
+++ b/src/pickit5_updi_lut.c
@@ -0,0 +1,1110 @@
+/* This file was auto-generated by scripts_decoder.py, any changes will be overwritten */
+
+/*
+ * avrdude - A Downloader/Uploader for AVR device programmers
+ * Copyright (C) 2024 MX682X
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
+
+#include
+#include
+#include
+#include "pickit5_lut.h"
+
+
+const unsigned char EnterProgMode_0[294] = {
+ 0x9b, 0x00, 0x08, 0x9b, 0x01, 0x00, 0x1e, 0x01, 0x00, 0x01, 0xfd, 0x19, 0x00, 0x00, 0x00, 0x08,
+ 0x01, 0x94, 0x32, 0x00, 0x94, 0x40, 0x00, 0x9b, 0x00, 0x0b, 0x1e, 0x0e, 0x00, 0x6c, 0x01, 0x66,
+ 0x01, 0x08, 0x00, 0x00, 0x00, 0xfe, 0x01, 0x08, 0x00, 0x00, 0x00, 0x26, 0x01, 0x9b, 0x00, 0x08,
+ 0x9b, 0x01, 0x59, 0x1e, 0x0f, 0x00, 0x01, 0x9b, 0x01, 0x00, 0x65, 0x20, 0x67, 0x6f, 0x72, 0x04,
+ 0x65, 0x50, 0x4d, 0x56, 0x4e, 0x04, 0x1e, 0x11, 0x01, 0x9b, 0x02, 0x07, 0x1e, 0x0e, 0x02, 0x6c,
+ 0x03, 0x66, 0x03, 0x10, 0x00, 0x00, 0x00, 0x9b, 0x04, 0x10, 0xfc, 0x03, 0x04, 0x1e, 0x01, 0x9b,
+ 0x00, 0x08, 0x9b, 0x01, 0x59, 0x1e, 0x0f, 0x00, 0x01, 0x9b, 0x01, 0x0b, 0xa2, 0x1e, 0x0e, 0x01,
+ 0xa5, 0x20, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x0a, 0x00, 0x9b, 0x00, 0x08, 0x9b, 0x01,
+ 0x00, 0x1e, 0x0f, 0x00, 0x01, 0x9b, 0x01, 0x0b, 0xa2, 0x1e, 0x0e, 0x01, 0xa5, 0x20, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x0a, 0x00, 0x94, 0x48, 0x00, 0x9b, 0x00, 0x0b, 0x1e, 0x0e, 0x00,
+ 0x6c, 0x01, 0x66, 0x01, 0x08, 0x00, 0x00, 0x00, 0xfe, 0x01, 0x08, 0x00, 0x00, 0x00, 0x26, 0x01,
+ 0x9b, 0x00, 0x0b, 0x1e, 0x0e, 0x00, 0x6c, 0x01, 0x66, 0x01, 0x01, 0x00, 0x00, 0x00, 0xfe, 0x01,
+ 0x01, 0x00, 0x00, 0x00, 0x13, 0x01, 0x6c, 0x01, 0x66, 0x01, 0x02, 0x00, 0x00, 0x00, 0xfe, 0x01,
+ 0x02, 0x00, 0x00, 0x00, 0x13, 0x01, 0x9b, 0x01, 0x0c, 0x1e, 0x0e, 0x01, 0x6c, 0x02, 0x66, 0x02,
+ 0x04, 0x00, 0x00, 0x00, 0xfe, 0x02, 0x04, 0x00, 0x00, 0x00, 0x13, 0x01, 0x94, 0xf4, 0x01, 0x9b,
+ 0x01, 0x0c, 0x1e, 0x0e, 0x01, 0x6c, 0x02, 0x66, 0x02, 0x04, 0x00, 0x00, 0x00, 0xfe, 0x02, 0x04,
+ 0x00, 0x00, 0x00, 0x13, 0x01, 0xfb, 0x1e, 0x01, 0x90, 0x01, 0x51, 0x00, 0x00, 0x00, 0x7f, 0x01,
+ 0xfb, 0x26, 0x01, 0x90, 0x01, 0x44, 0x00, 0x00, 0x00, 0x7f, 0x01, 0xfb, 0x26, 0x01, 0x90, 0x01,
+ 0x00, 0x01, 0x00, 0x00, 0x7f, 0x01,
+};
+
+const unsigned char EnterProgModeHvSp_0[339] = {
+ 0x9b, 0x00, 0x08, 0x9b, 0x01, 0x01, 0x1e, 0x01, 0x00, 0x01, 0xfd, 0x54, 0x00, 0x00, 0x00, 0x3a,
+ 0x01, 0xfd, 0x08, 0x03, 0x00, 0x00, 0x45, 0x01, 0xfd, 0x09, 0x03, 0x00, 0x00, 0x48, 0x01, 0xfd,
+ 0x19, 0x00, 0x00, 0x00, 0x24, 0x01, 0xfd, 0x1b, 0x00, 0x00, 0x00, 0x24, 0x01, 0x94, 0x32, 0x00,
+ 0x94, 0x40, 0x00, 0x9b, 0x00, 0x0b, 0x1e, 0x0e, 0x00, 0x6c, 0x01, 0x66, 0x01, 0x08, 0x00, 0x00,
+ 0x00, 0xfe, 0x01, 0x08, 0x00, 0x00, 0x00, 0x53, 0x01, 0x9b, 0x00, 0x08, 0x9b, 0x01, 0x59, 0x1e,
+ 0x0f, 0x00, 0x01, 0x9b, 0x01, 0x00, 0x65, 0x20, 0x67, 0x6f, 0x72, 0x04, 0x65, 0x50, 0x4d, 0x56,
+ 0x4e, 0x04, 0x1e, 0x11, 0x01, 0x9b, 0x02, 0x07, 0x1e, 0x0e, 0x02, 0x6c, 0x03, 0x66, 0x03, 0x10,
+ 0x00, 0x00, 0x00, 0x9b, 0x04, 0x10, 0xfc, 0x03, 0x04, 0x4b, 0x01, 0x9b, 0x00, 0x08, 0x9b, 0x01,
+ 0x59, 0x1e, 0x0f, 0x00, 0x01, 0x9b, 0x01, 0x0b, 0xa2, 0x1e, 0x0e, 0x01, 0xa5, 0x20, 0x00, 0x00,
+ 0x00, 0x20, 0x00, 0x00, 0x00, 0x0a, 0x00, 0x9b, 0x00, 0x08, 0x9b, 0x01, 0x00, 0x1e, 0x0f, 0x00,
+ 0x01, 0x9b, 0x01, 0x0b, 0xa2, 0x1e, 0x0e, 0x01, 0xa5, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x0a, 0x00, 0x94, 0x48, 0x00, 0x9b, 0x00, 0x0b, 0x1e, 0x0e, 0x00, 0x6c, 0x01, 0x66, 0x01,
+ 0x08, 0x00, 0x00, 0x00, 0xfe, 0x01, 0x08, 0x00, 0x00, 0x00, 0x53, 0x01, 0x9b, 0x00, 0x0b, 0x1e,
+ 0x0e, 0x00, 0x6c, 0x01, 0x66, 0x01, 0x01, 0x00, 0x00, 0x00, 0xfe, 0x01, 0x01, 0x00, 0x00, 0x00,
+ 0x2f, 0x01, 0x6c, 0x01, 0x66, 0x01, 0x02, 0x00, 0x00, 0x00, 0xfe, 0x01, 0x02, 0x00, 0x00, 0x00,
+ 0x2f, 0x01, 0x9b, 0x01, 0x0c, 0x1e, 0x0e, 0x01, 0x6c, 0x02, 0x66, 0x02, 0x04, 0x00, 0x00, 0x00,
+ 0xfe, 0x02, 0x04, 0x00, 0x00, 0x00, 0x2f, 0x01, 0x94, 0xf4, 0x01, 0x9b, 0x01, 0x0c, 0x1e, 0x0e,
+ 0x01, 0x6c, 0x02, 0x66, 0x02, 0x04, 0x00, 0x00, 0x00, 0xfe, 0x02, 0x04, 0x00, 0x00, 0x00, 0x2f,
+ 0x01, 0xfb, 0x4b, 0x01, 0x90, 0x01, 0x51, 0x00, 0x00, 0x00, 0x7f, 0x01, 0xfb, 0x53, 0x01, 0x90,
+ 0x01, 0x44, 0x00, 0x00, 0x00, 0x7f, 0x01, 0xfb, 0x53, 0x01, 0x90, 0x01, 0x54, 0x00, 0x00, 0x00,
+ 0x7f, 0x01, 0xfb, 0x53, 0x01, 0xfb, 0x53, 0x01, 0xfb, 0x53, 0x01, 0x90, 0x01, 0x00, 0x01, 0x00,
+ 0x00, 0x7f, 0x01,
+};
+
+const unsigned char EnterProgModeHvSpRst_0[325] = {
+ 0x9b, 0x00, 0x08, 0x9b, 0x01, 0x05, 0x1e, 0x01, 0x00, 0x01, 0xfd, 0x54, 0x00, 0x00, 0x00, 0x2c,
+ 0x01, 0xfd, 0x08, 0x03, 0x00, 0x00, 0x37, 0x01, 0xfd, 0x09, 0x03, 0x00, 0x00, 0x3a, 0x01, 0x94,
+ 0x32, 0x00, 0x94, 0x40, 0x00, 0x9b, 0x00, 0x0b, 0x1e, 0x0e, 0x00, 0x6c, 0x01, 0x66, 0x01, 0x08,
+ 0x00, 0x00, 0x00, 0xfe, 0x01, 0x08, 0x00, 0x00, 0x00, 0x45, 0x01, 0x9b, 0x00, 0x08, 0x9b, 0x01,
+ 0x59, 0x1e, 0x0f, 0x00, 0x01, 0x9b, 0x01, 0x00, 0x65, 0x20, 0x67, 0x6f, 0x72, 0x04, 0x65, 0x50,
+ 0x4d, 0x56, 0x4e, 0x04, 0x1e, 0x11, 0x01, 0x9b, 0x02, 0x07, 0x1e, 0x0e, 0x02, 0x6c, 0x03, 0x66,
+ 0x03, 0x10, 0x00, 0x00, 0x00, 0x9b, 0x04, 0x10, 0xfc, 0x03, 0x04, 0x3d, 0x01, 0x9b, 0x00, 0x08,
+ 0x9b, 0x01, 0x59, 0x1e, 0x0f, 0x00, 0x01, 0x9b, 0x01, 0x0b, 0xa2, 0x1e, 0x0e, 0x01, 0xa5, 0x20,
+ 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x0a, 0x00, 0x9b, 0x00, 0x08, 0x9b, 0x01, 0x00, 0x1e,
+ 0x0f, 0x00, 0x01, 0x9b, 0x01, 0x0b, 0xa2, 0x1e, 0x0e, 0x01, 0xa5, 0x20, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x0a, 0x00, 0x94, 0x48, 0x00, 0x9b, 0x00, 0x0b, 0x1e, 0x0e, 0x00, 0x6c, 0x01,
+ 0x66, 0x01, 0x08, 0x00, 0x00, 0x00, 0xfe, 0x01, 0x08, 0x00, 0x00, 0x00, 0x45, 0x01, 0x9b, 0x00,
+ 0x0b, 0x1e, 0x0e, 0x00, 0x6c, 0x01, 0x66, 0x01, 0x01, 0x00, 0x00, 0x00, 0xfe, 0x01, 0x01, 0x00,
+ 0x00, 0x00, 0x21, 0x01, 0x6c, 0x01, 0x66, 0x01, 0x02, 0x00, 0x00, 0x00, 0xfe, 0x01, 0x02, 0x00,
+ 0x00, 0x00, 0x21, 0x01, 0x9b, 0x01, 0x0c, 0x1e, 0x0e, 0x01, 0x6c, 0x02, 0x66, 0x02, 0x04, 0x00,
+ 0x00, 0x00, 0xfe, 0x02, 0x04, 0x00, 0x00, 0x00, 0x21, 0x01, 0x94, 0xf4, 0x01, 0x9b, 0x01, 0x0c,
+ 0x1e, 0x0e, 0x01, 0x6c, 0x02, 0x66, 0x02, 0x04, 0x00, 0x00, 0x00, 0xfe, 0x02, 0x04, 0x00, 0x00,
+ 0x00, 0x21, 0x01, 0xfb, 0x3d, 0x01, 0x90, 0x01, 0x51, 0x00, 0x00, 0x00, 0x7f, 0x01, 0xfb, 0x45,
+ 0x01, 0x90, 0x01, 0x44, 0x00, 0x00, 0x00, 0x7f, 0x01, 0xfb, 0x45, 0x01, 0x90, 0x01, 0x54, 0x00,
+ 0x00, 0x00, 0x7f, 0x01, 0xfb, 0x45, 0x01, 0xfb, 0x45, 0x01, 0xfb, 0x45, 0x01, 0x90, 0x01, 0x00,
+ 0x01, 0x00, 0x00, 0x7f, 0x01,
+};
+
+const unsigned char EnterProgModeHvUpt_0[339] = {
+ 0x9b, 0x00, 0x08, 0x9b, 0x01, 0x03, 0x1e, 0x01, 0x00, 0x01, 0xfd, 0x54, 0x00, 0x00, 0x00, 0x3a,
+ 0x01, 0xfd, 0x08, 0x03, 0x00, 0x00, 0x45, 0x01, 0xfd, 0x09, 0x03, 0x00, 0x00, 0x48, 0x01, 0xfd,
+ 0x19, 0x00, 0x00, 0x00, 0x24, 0x01, 0xfd, 0x1b, 0x00, 0x00, 0x00, 0x24, 0x01, 0x94, 0x32, 0x00,
+ 0x94, 0x40, 0x00, 0x9b, 0x00, 0x0b, 0x1e, 0x0e, 0x00, 0x6c, 0x01, 0x66, 0x01, 0x08, 0x00, 0x00,
+ 0x00, 0xfe, 0x01, 0x08, 0x00, 0x00, 0x00, 0x53, 0x01, 0x9b, 0x00, 0x08, 0x9b, 0x01, 0x59, 0x1e,
+ 0x0f, 0x00, 0x01, 0x9b, 0x01, 0x00, 0x65, 0x20, 0x67, 0x6f, 0x72, 0x04, 0x65, 0x50, 0x4d, 0x56,
+ 0x4e, 0x04, 0x1e, 0x11, 0x01, 0x9b, 0x02, 0x07, 0x1e, 0x0e, 0x02, 0x6c, 0x03, 0x66, 0x03, 0x10,
+ 0x00, 0x00, 0x00, 0x9b, 0x04, 0x10, 0xfc, 0x03, 0x04, 0x4b, 0x01, 0x9b, 0x00, 0x08, 0x9b, 0x01,
+ 0x59, 0x1e, 0x0f, 0x00, 0x01, 0x9b, 0x01, 0x0b, 0xa2, 0x1e, 0x0e, 0x01, 0xa5, 0x20, 0x00, 0x00,
+ 0x00, 0x20, 0x00, 0x00, 0x00, 0x0a, 0x00, 0x9b, 0x00, 0x08, 0x9b, 0x01, 0x00, 0x1e, 0x0f, 0x00,
+ 0x01, 0x9b, 0x01, 0x0b, 0xa2, 0x1e, 0x0e, 0x01, 0xa5, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x0a, 0x00, 0x94, 0x48, 0x00, 0x9b, 0x00, 0x0b, 0x1e, 0x0e, 0x00, 0x6c, 0x01, 0x66, 0x01,
+ 0x08, 0x00, 0x00, 0x00, 0xfe, 0x01, 0x08, 0x00, 0x00, 0x00, 0x53, 0x01, 0x9b, 0x00, 0x0b, 0x1e,
+ 0x0e, 0x00, 0x6c, 0x01, 0x66, 0x01, 0x01, 0x00, 0x00, 0x00, 0xfe, 0x01, 0x01, 0x00, 0x00, 0x00,
+ 0x2f, 0x01, 0x6c, 0x01, 0x66, 0x01, 0x02, 0x00, 0x00, 0x00, 0xfe, 0x01, 0x02, 0x00, 0x00, 0x00,
+ 0x2f, 0x01, 0x9b, 0x01, 0x0c, 0x1e, 0x0e, 0x01, 0x6c, 0x02, 0x66, 0x02, 0x04, 0x00, 0x00, 0x00,
+ 0xfe, 0x02, 0x04, 0x00, 0x00, 0x00, 0x2f, 0x01, 0x94, 0xf4, 0x01, 0x9b, 0x01, 0x0c, 0x1e, 0x0e,
+ 0x01, 0x6c, 0x02, 0x66, 0x02, 0x04, 0x00, 0x00, 0x00, 0xfe, 0x02, 0x04, 0x00, 0x00, 0x00, 0x2f,
+ 0x01, 0xfb, 0x4b, 0x01, 0x90, 0x01, 0x51, 0x00, 0x00, 0x00, 0x7f, 0x01, 0xfb, 0x53, 0x01, 0x90,
+ 0x01, 0x44, 0x00, 0x00, 0x00, 0x7f, 0x01, 0xfb, 0x53, 0x01, 0x90, 0x01, 0x54, 0x00, 0x00, 0x00,
+ 0x7f, 0x01, 0xfb, 0x53, 0x01, 0xfb, 0x53, 0x01, 0xfb, 0x53, 0x01, 0x90, 0x01, 0x00, 0x01, 0x00,
+ 0x00, 0x7f, 0x01,
+};
+
+const unsigned char ExitProgMode_0[22] = {
+ 0x9b, 0x00, 0x08, 0x9b, 0x01, 0x59, 0x1e, 0x0f, 0x00, 0x01, 0x9b, 0x00, 0x08, 0x9b, 0x01, 0x00,
+ 0x1e, 0x0f, 0x00, 0x01, 0x1e, 0x02,
+};
+
+const unsigned char SetSpeed_0[5] = {
+ 0x91, 0x00, 0x1e, 0x14, 0x00,
+};
+
+const unsigned char GetDeviceID_0[33] = {
+ 0x95, 0x90, 0x00, 0x00, 0x11, 0x00, 0x00, 0x1e, 0x09, 0x00, 0x9c, 0x01, 0x03, 0x00, 0x1e, 0x10,
+ 0x01, 0x9b, 0x02, 0x03, 0x1e, 0x0c, 0x02, 0x90, 0x02, 0x01, 0x0f, 0x00, 0x00, 0x1e, 0x03, 0x02,
+ 0x9f,
+};
+
+const unsigned char GetDeviceID_1[33] = {
+ 0x95, 0x90, 0x00, 0x80, 0x10, 0x00, 0x00, 0x1e, 0x09, 0x00, 0x9c, 0x01, 0x03, 0x00, 0x1e, 0x10,
+ 0x01, 0x9b, 0x02, 0x03, 0x1e, 0x0c, 0x02, 0x90, 0x02, 0x01, 0x0f, 0x00, 0x00, 0x1e, 0x03, 0x02,
+ 0x9f,
+};
+
+const unsigned char EraseChip_0[184] = {
+ 0x94, 0x32, 0x00, 0x94, 0x40, 0x00, 0x90, 0x01, 0x00, 0x00, 0x00, 0x00, 0x65, 0x65, 0x73, 0x61,
+ 0x72, 0x04, 0x65, 0x45, 0x4d, 0x56, 0x4e, 0x04, 0x1e, 0x11, 0x01, 0x90, 0x02, 0x07, 0x00, 0x00,
+ 0x00, 0x1e, 0x0e, 0x02, 0x6c, 0x03, 0x66, 0x03, 0x08, 0x00, 0x00, 0x00, 0x90, 0x04, 0x08, 0x00,
+ 0x00, 0x00, 0xfc, 0x03, 0x04, 0xaf, 0x00, 0x90, 0x00, 0x08, 0x00, 0x00, 0x00, 0x90, 0x01, 0x59,
+ 0x00, 0x00, 0x00, 0x1e, 0x0f, 0x00, 0x01, 0x90, 0x01, 0x0b, 0x00, 0x00, 0x00, 0xa2, 0x1e, 0x0e,
+ 0x01, 0xa5, 0x20, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x0a, 0x00, 0x90, 0x00, 0x08, 0x00,
+ 0x00, 0x00, 0x90, 0x01, 0x00, 0x00, 0x00, 0x00, 0x1e, 0x0f, 0x00, 0x01, 0x90, 0x01, 0x0b, 0x00,
+ 0x00, 0x00, 0xa2, 0x1e, 0x0e, 0x01, 0xa5, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0a,
+ 0x00, 0x90, 0x01, 0x0b, 0x00, 0x00, 0x00, 0xa2, 0x94, 0x02, 0x00, 0x1e, 0x0e, 0x01, 0xa5, 0x01,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf4, 0x01, 0x1e, 0x0e, 0x01, 0x6c, 0x03, 0x66, 0x03,
+ 0x40, 0x00, 0x00, 0x00, 0xfe, 0x03, 0x40, 0x00, 0x00, 0x00, 0xaf, 0x00, 0xfb, 0xb7, 0x00, 0x90,
+ 0x01, 0x00, 0x01, 0x00, 0x00, 0x7f, 0x01, 0x5a,
+};
+
+const unsigned char WriteProgmem_0[231] = {
+ 0x91, 0x00, 0x91, 0x01, 0x90, 0x02, 0x08, 0x10, 0x00, 0x00, 0x1e, 0x03, 0x02, 0x6c, 0x0a, 0x90,
+ 0x02, 0x09, 0x10, 0x00, 0x00, 0x1e, 0x03, 0x02, 0x6c, 0x0b, 0x90, 0x11, 0x00, 0x00, 0x00, 0x00,
+ 0x90, 0x0f, 0x40, 0x00, 0x00, 0x00, 0xfa, 0x01, 0x0f, 0x2e, 0x00, 0x60, 0x0f, 0x01, 0x90, 0x02,
+ 0x02, 0x10, 0x00, 0x00, 0xa2, 0x1e, 0x03, 0x02, 0x94, 0x02, 0x00, 0xa5, 0x03, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x14, 0x00, 0x90, 0x02, 0x00, 0x10, 0x00, 0x00, 0x90, 0x03, 0x04, 0x00,
+ 0x00, 0x00, 0x1e, 0x06, 0x02, 0x03, 0x90, 0x02, 0x02, 0x10, 0x00, 0x00, 0xa2, 0x1e, 0x03, 0x02,
+ 0x94, 0x02, 0x00, 0xa5, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14, 0x00, 0x90, 0x10,
+ 0x00, 0x01, 0x00, 0x00, 0xfa, 0x0f, 0x10, 0x7c, 0x00, 0x60, 0x10, 0x0f, 0x1e, 0x09, 0x00, 0x60,
+ 0x04, 0x10, 0x67, 0x04, 0x01, 0x1e, 0x10, 0x04, 0x1e, 0x0b, 0x04, 0x6a, 0x0f, 0x10, 0x6e, 0x00,
+ 0x10, 0x6a, 0x01, 0x10, 0xfc, 0x0f, 0x11, 0x6e, 0x00, 0x90, 0x06, 0x00, 0x10, 0x00, 0x00, 0x90,
+ 0x07, 0x03, 0x00, 0x00, 0x00, 0x1e, 0x06, 0x06, 0x07, 0x6c, 0x0c, 0x90, 0x0d, 0x00, 0x00, 0x00,
+ 0x00, 0xfc, 0x0c, 0x0d, 0xd3, 0x00, 0x90, 0x02, 0x02, 0x10, 0x00, 0x00, 0xa2, 0x1e, 0x03, 0x02,
+ 0x94, 0x02, 0x00, 0xa5, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14, 0x00, 0xfc, 0x01,
+ 0x11, 0x20, 0x00, 0x90, 0x02, 0x08, 0x10, 0x00, 0x00, 0x1e, 0x06, 0x02, 0x0a, 0x90, 0x02, 0x09,
+ 0x10, 0x00, 0x00, 0x1e, 0x06, 0x02, 0x0b,
+};
+
+const unsigned char WriteProgmem_1[231] = {
+ 0x91, 0x00, 0x91, 0x01, 0x90, 0x02, 0x08, 0x10, 0x00, 0x00, 0x1e, 0x03, 0x02, 0x6c, 0x0a, 0x90,
+ 0x02, 0x09, 0x10, 0x00, 0x00, 0x1e, 0x03, 0x02, 0x6c, 0x0b, 0x90, 0x11, 0x00, 0x00, 0x00, 0x00,
+ 0x90, 0x0f, 0x80, 0x00, 0x00, 0x00, 0xfa, 0x01, 0x0f, 0x2e, 0x00, 0x60, 0x0f, 0x01, 0x90, 0x02,
+ 0x02, 0x10, 0x00, 0x00, 0xa2, 0x1e, 0x03, 0x02, 0x94, 0x02, 0x00, 0xa5, 0x03, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x14, 0x00, 0x90, 0x02, 0x00, 0x10, 0x00, 0x00, 0x90, 0x03, 0x04, 0x00,
+ 0x00, 0x00, 0x1e, 0x06, 0x02, 0x03, 0x90, 0x02, 0x02, 0x10, 0x00, 0x00, 0xa2, 0x1e, 0x03, 0x02,
+ 0x94, 0x02, 0x00, 0xa5, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14, 0x00, 0x90, 0x10,
+ 0x00, 0x01, 0x00, 0x00, 0xfa, 0x0f, 0x10, 0x7c, 0x00, 0x60, 0x10, 0x0f, 0x1e, 0x09, 0x00, 0x60,
+ 0x04, 0x10, 0x67, 0x04, 0x01, 0x1e, 0x10, 0x04, 0x1e, 0x0b, 0x04, 0x6a, 0x0f, 0x10, 0x6e, 0x00,
+ 0x10, 0x6a, 0x01, 0x10, 0xfc, 0x0f, 0x11, 0x6e, 0x00, 0x90, 0x06, 0x00, 0x10, 0x00, 0x00, 0x90,
+ 0x07, 0x03, 0x00, 0x00, 0x00, 0x1e, 0x06, 0x06, 0x07, 0x6c, 0x0c, 0x90, 0x0d, 0x00, 0x00, 0x00,
+ 0x00, 0xfc, 0x0c, 0x0d, 0xd3, 0x00, 0x90, 0x02, 0x02, 0x10, 0x00, 0x00, 0xa2, 0x1e, 0x03, 0x02,
+ 0x94, 0x02, 0x00, 0xa5, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14, 0x00, 0xfc, 0x01,
+ 0x11, 0x20, 0x00, 0x90, 0x02, 0x08, 0x10, 0x00, 0x00, 0x1e, 0x06, 0x02, 0x0a, 0x90, 0x02, 0x09,
+ 0x10, 0x00, 0x00, 0x1e, 0x06, 0x02, 0x0b,
+};
+
+const unsigned char WriteProgmem_2[272] = {
+ 0x91, 0x00, 0x91, 0x01, 0x90, 0x02, 0x02, 0x10, 0x00, 0x00, 0xa2, 0x1e, 0x03, 0x02, 0x94, 0x02,
+ 0x00, 0xa5, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14, 0x00, 0x90, 0x11, 0x00, 0x00,
+ 0x00, 0x00, 0x90, 0x0f, 0x00, 0x02, 0x00, 0x00, 0xfa, 0x01, 0x0f, 0x30, 0x00, 0x60, 0x0f, 0x01,
+ 0x90, 0x06, 0x00, 0x10, 0x00, 0x00, 0x90, 0x07, 0x08, 0x00, 0x00, 0x00, 0x1e, 0x06, 0x06, 0x07,
+ 0x90, 0x06, 0xff, 0x00, 0x00, 0x00, 0x1e, 0x06, 0x00, 0x06, 0x90, 0x02, 0x02, 0x10, 0x00, 0x00,
+ 0xa2, 0x1e, 0x03, 0x02, 0x94, 0x02, 0x00, 0xa5, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x14, 0x00, 0x90, 0x06, 0x00, 0x10, 0x00, 0x00, 0x90, 0x07, 0x00, 0x00, 0x00, 0x00, 0x1e, 0x06,
+ 0x06, 0x07, 0x90, 0x02, 0x02, 0x10, 0x00, 0x00, 0xa2, 0x1e, 0x03, 0x02, 0x94, 0x02, 0x00, 0xa5,
+ 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14, 0x00, 0x90, 0x06, 0x00, 0x10, 0x00, 0x00,
+ 0x90, 0x07, 0x02, 0x00, 0x00, 0x00, 0x1e, 0x06, 0x06, 0x07, 0x90, 0x10, 0x00, 0x01, 0x00, 0x00,
+ 0xfa, 0x0f, 0x10, 0xa8, 0x00, 0x60, 0x10, 0x0f, 0x1e, 0x09, 0x00, 0x60, 0x04, 0x10, 0x67, 0x04,
+ 0x01, 0x1e, 0x10, 0x04, 0x1e, 0x0b, 0x04, 0x6a, 0x0f, 0x10, 0x6e, 0x00, 0x10, 0x6a, 0x01, 0x10,
+ 0xfc, 0x0f, 0x11, 0x9a, 0x00, 0x6c, 0x0c, 0x90, 0x0d, 0x00, 0x00, 0x00, 0x00, 0xfc, 0x0c, 0x0d,
+ 0x00, 0x01, 0x90, 0x02, 0x02, 0x10, 0x00, 0x00, 0xa2, 0x1e, 0x03, 0x02, 0x94, 0x02, 0x00, 0xa5,
+ 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14, 0x00, 0x90, 0x06, 0x00, 0x10, 0x00, 0x00,
+ 0x90, 0x07, 0x00, 0x00, 0x00, 0x00, 0x1e, 0x06, 0x06, 0x07, 0xfc, 0x01, 0x11, 0x22, 0x00, 0x5a,
+ 0x90, 0x06, 0x00, 0x10, 0x00, 0x00, 0x90, 0x07, 0x00, 0x00, 0x00, 0x00, 0x1e, 0x06, 0x06, 0x07,
+};
+
+const unsigned char WriteProgmem_3[231] = {
+ 0x91, 0x00, 0x91, 0x01, 0x90, 0x02, 0x0c, 0x10, 0x00, 0x00, 0x1e, 0x03, 0x02, 0x6c, 0x0a, 0x90,
+ 0x02, 0x0d, 0x10, 0x00, 0x00, 0x1e, 0x03, 0x02, 0x6c, 0x0b, 0x90, 0x11, 0x00, 0x00, 0x00, 0x00,
+ 0x90, 0x0f, 0x80, 0x00, 0x00, 0x00, 0xfa, 0x01, 0x0f, 0x2e, 0x00, 0x60, 0x0f, 0x01, 0x90, 0x02,
+ 0x06, 0x10, 0x00, 0x00, 0xa2, 0x1e, 0x03, 0x02, 0x94, 0x02, 0x00, 0xa5, 0x03, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x14, 0x00, 0x90, 0x02, 0x00, 0x10, 0x00, 0x00, 0x90, 0x03, 0x0f, 0x00,
+ 0x00, 0x00, 0x1e, 0x06, 0x02, 0x03, 0x90, 0x02, 0x06, 0x10, 0x00, 0x00, 0xa2, 0x1e, 0x03, 0x02,
+ 0x94, 0x02, 0x00, 0xa5, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14, 0x00, 0x90, 0x10,
+ 0x00, 0x01, 0x00, 0x00, 0xfa, 0x0f, 0x10, 0x7c, 0x00, 0x60, 0x10, 0x0f, 0x1e, 0x09, 0x00, 0x60,
+ 0x04, 0x10, 0x67, 0x04, 0x01, 0x1e, 0x10, 0x04, 0x1e, 0x0b, 0x04, 0x6a, 0x0f, 0x10, 0x6e, 0x00,
+ 0x10, 0x6a, 0x01, 0x10, 0xfc, 0x0f, 0x11, 0x6e, 0x00, 0x90, 0x06, 0x00, 0x10, 0x00, 0x00, 0x90,
+ 0x07, 0x05, 0x00, 0x00, 0x00, 0x1e, 0x06, 0x06, 0x07, 0x6c, 0x0c, 0x90, 0x0d, 0x00, 0x00, 0x00,
+ 0x00, 0xfc, 0x0c, 0x0d, 0xd3, 0x00, 0x90, 0x02, 0x06, 0x10, 0x00, 0x00, 0xa2, 0x1e, 0x03, 0x02,
+ 0x94, 0x02, 0x00, 0xa5, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14, 0x00, 0xfc, 0x01,
+ 0x11, 0x20, 0x00, 0x90, 0x02, 0x0c, 0x10, 0x00, 0x00, 0x1e, 0x06, 0x02, 0x0a, 0x90, 0x02, 0x0d,
+ 0x10, 0x00, 0x00, 0x1e, 0x06, 0x02, 0x0b,
+};
+
+const unsigned char WriteProgmem_4[272] = {
+ 0x91, 0x00, 0x91, 0x01, 0x90, 0x02, 0x06, 0x10, 0x00, 0x00, 0xa2, 0x1e, 0x03, 0x02, 0x94, 0x02,
+ 0x00, 0xa5, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14, 0x00, 0x90, 0x11, 0x00, 0x00,
+ 0x00, 0x00, 0x90, 0x0f, 0x00, 0x02, 0x00, 0x00, 0xfa, 0x01, 0x0f, 0x30, 0x00, 0x60, 0x0f, 0x01,
+ 0x90, 0x06, 0x00, 0x10, 0x00, 0x00, 0x90, 0x07, 0x08, 0x00, 0x00, 0x00, 0x1e, 0x06, 0x06, 0x07,
+ 0x90, 0x06, 0xff, 0x00, 0x00, 0x00, 0x1e, 0x06, 0x00, 0x06, 0x90, 0x02, 0x06, 0x10, 0x00, 0x00,
+ 0xa2, 0x1e, 0x03, 0x02, 0x94, 0x02, 0x00, 0xa5, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x14, 0x00, 0x90, 0x06, 0x00, 0x10, 0x00, 0x00, 0x90, 0x07, 0x00, 0x00, 0x00, 0x00, 0x1e, 0x06,
+ 0x06, 0x07, 0x90, 0x02, 0x06, 0x10, 0x00, 0x00, 0xa2, 0x1e, 0x03, 0x02, 0x94, 0x02, 0x00, 0xa5,
+ 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14, 0x00, 0x90, 0x06, 0x00, 0x10, 0x00, 0x00,
+ 0x90, 0x07, 0x02, 0x00, 0x00, 0x00, 0x1e, 0x06, 0x06, 0x07, 0x90, 0x10, 0x00, 0x01, 0x00, 0x00,
+ 0xfa, 0x0f, 0x10, 0xa8, 0x00, 0x60, 0x10, 0x0f, 0x1e, 0x09, 0x00, 0x60, 0x04, 0x10, 0x67, 0x04,
+ 0x01, 0x1e, 0x10, 0x04, 0x1e, 0x0b, 0x04, 0x6a, 0x0f, 0x10, 0x6e, 0x00, 0x10, 0x6a, 0x01, 0x10,
+ 0xfc, 0x0f, 0x11, 0x9a, 0x00, 0x6c, 0x0c, 0x90, 0x0d, 0x00, 0x00, 0x00, 0x00, 0xfc, 0x0c, 0x0d,
+ 0x00, 0x01, 0x90, 0x02, 0x06, 0x10, 0x00, 0x00, 0xa2, 0x1e, 0x03, 0x02, 0x94, 0x02, 0x00, 0xa5,
+ 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14, 0x00, 0x90, 0x06, 0x00, 0x10, 0x00, 0x00,
+ 0x90, 0x07, 0x00, 0x00, 0x00, 0x00, 0x1e, 0x06, 0x06, 0x07, 0xfc, 0x01, 0x11, 0x22, 0x00, 0x5a,
+ 0x90, 0x06, 0x00, 0x10, 0x00, 0x00, 0x90, 0x07, 0x00, 0x00, 0x00, 0x00, 0x1e, 0x06, 0x06, 0x07,
+};
+
+const unsigned char WriteProgmem_5[231] = {
+ 0x91, 0x00, 0x91, 0x01, 0x90, 0x02, 0x0c, 0x10, 0x00, 0x00, 0x1e, 0x03, 0x02, 0x6c, 0x0a, 0x90,
+ 0x02, 0x0d, 0x10, 0x00, 0x00, 0x1e, 0x03, 0x02, 0x6c, 0x0b, 0x90, 0x11, 0x00, 0x00, 0x00, 0x00,
+ 0x90, 0x0f, 0x40, 0x00, 0x00, 0x00, 0xfa, 0x01, 0x0f, 0x2e, 0x00, 0x60, 0x0f, 0x01, 0x90, 0x02,
+ 0x06, 0x10, 0x00, 0x00, 0xa2, 0x1e, 0x03, 0x02, 0x94, 0x02, 0x00, 0xa5, 0x03, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x14, 0x00, 0x90, 0x02, 0x00, 0x10, 0x00, 0x00, 0x90, 0x03, 0x0f, 0x00,
+ 0x00, 0x00, 0x1e, 0x06, 0x02, 0x03, 0x90, 0x02, 0x06, 0x10, 0x00, 0x00, 0xa2, 0x1e, 0x03, 0x02,
+ 0x94, 0x02, 0x00, 0xa5, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14, 0x00, 0x90, 0x10,
+ 0x00, 0x01, 0x00, 0x00, 0xfa, 0x0f, 0x10, 0x7c, 0x00, 0x60, 0x10, 0x0f, 0x1e, 0x09, 0x00, 0x60,
+ 0x04, 0x10, 0x67, 0x04, 0x01, 0x1e, 0x10, 0x04, 0x1e, 0x0b, 0x04, 0x6a, 0x0f, 0x10, 0x6e, 0x00,
+ 0x10, 0x6a, 0x01, 0x10, 0xfc, 0x0f, 0x11, 0x6e, 0x00, 0x90, 0x06, 0x00, 0x10, 0x00, 0x00, 0x90,
+ 0x07, 0x05, 0x00, 0x00, 0x00, 0x1e, 0x06, 0x06, 0x07, 0x6c, 0x0c, 0x90, 0x0d, 0x00, 0x00, 0x00,
+ 0x00, 0xfc, 0x0c, 0x0d, 0xd3, 0x00, 0x90, 0x02, 0x06, 0x10, 0x00, 0x00, 0xa2, 0x1e, 0x03, 0x02,
+ 0x94, 0x02, 0x00, 0xa5, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14, 0x00, 0xfc, 0x01,
+ 0x11, 0x20, 0x00, 0x90, 0x02, 0x0c, 0x10, 0x00, 0x00, 0x1e, 0x06, 0x02, 0x0a, 0x90, 0x02, 0x0d,
+ 0x10, 0x00, 0x00, 0x1e, 0x06, 0x02, 0x0b,
+};
+
+const unsigned char WriteProgmem_6[272] = {
+ 0x91, 0x00, 0x91, 0x01, 0x90, 0x02, 0x07, 0x10, 0x00, 0x00, 0xa2, 0x1e, 0x03, 0x02, 0x94, 0x02,
+ 0x00, 0xa5, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14, 0x00, 0x90, 0x11, 0x00, 0x00,
+ 0x00, 0x00, 0x90, 0x0f, 0x00, 0x02, 0x00, 0x00, 0xfa, 0x01, 0x0f, 0x30, 0x00, 0x60, 0x0f, 0x01,
+ 0x90, 0x06, 0x00, 0x10, 0x00, 0x00, 0x90, 0x07, 0x08, 0x00, 0x00, 0x00, 0x1e, 0x06, 0x06, 0x07,
+ 0x90, 0x06, 0xff, 0x00, 0x00, 0x00, 0x1e, 0x06, 0x00, 0x06, 0x90, 0x02, 0x07, 0x10, 0x00, 0x00,
+ 0xa2, 0x1e, 0x03, 0x02, 0x94, 0x02, 0x00, 0xa5, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x14, 0x00, 0x90, 0x06, 0x00, 0x10, 0x00, 0x00, 0x90, 0x07, 0x00, 0x00, 0x00, 0x00, 0x1e, 0x06,
+ 0x06, 0x07, 0x90, 0x02, 0x07, 0x10, 0x00, 0x00, 0xa2, 0x1e, 0x03, 0x02, 0x94, 0x02, 0x00, 0xa5,
+ 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14, 0x00, 0x90, 0x06, 0x00, 0x10, 0x00, 0x00,
+ 0x90, 0x07, 0x02, 0x00, 0x00, 0x00, 0x1e, 0x06, 0x06, 0x07, 0x90, 0x10, 0x00, 0x01, 0x00, 0x00,
+ 0xfa, 0x0f, 0x10, 0xa8, 0x00, 0x60, 0x10, 0x0f, 0x1e, 0x09, 0x00, 0x60, 0x04, 0x10, 0x67, 0x04,
+ 0x01, 0x1e, 0x10, 0x04, 0x1e, 0x0b, 0x04, 0x6a, 0x0f, 0x10, 0x6e, 0x00, 0x10, 0x6a, 0x01, 0x10,
+ 0xfc, 0x0f, 0x11, 0x9a, 0x00, 0x6c, 0x0c, 0x90, 0x0d, 0x00, 0x00, 0x00, 0x00, 0xfc, 0x0c, 0x0d,
+ 0x00, 0x01, 0x90, 0x02, 0x07, 0x10, 0x00, 0x00, 0xa2, 0x1e, 0x03, 0x02, 0x94, 0x02, 0x00, 0xa5,
+ 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14, 0x00, 0x90, 0x06, 0x00, 0x10, 0x00, 0x00,
+ 0x90, 0x07, 0x00, 0x00, 0x00, 0x00, 0x1e, 0x06, 0x06, 0x07, 0xfc, 0x01, 0x11, 0x22, 0x00, 0x5a,
+ 0x90, 0x06, 0x00, 0x10, 0x00, 0x00, 0x90, 0x07, 0x00, 0x00, 0x00, 0x00, 0x1e, 0x06, 0x06, 0x07,
+};
+
+const unsigned char ReadProgmem_0[73] = {
+ 0x91, 0x00, 0x91, 0x01, 0x95, 0x90, 0x11, 0x00, 0x00, 0x00, 0x00, 0x90, 0x0f, 0x40, 0x00, 0x00,
+ 0x00, 0xfa, 0x01, 0x0f, 0x19, 0x00, 0x60, 0x0f, 0x01, 0x90, 0x10, 0x00, 0x01, 0x00, 0x00, 0xfa,
+ 0x0f, 0x10, 0x27, 0x00, 0x60, 0x10, 0x0f, 0x1e, 0x09, 0x00, 0x60, 0x04, 0x10, 0x67, 0x04, 0x01,
+ 0x1e, 0x10, 0x04, 0x1e, 0x0d, 0x04, 0x6a, 0x0f, 0x10, 0x6e, 0x00, 0x10, 0x6a, 0x01, 0x10, 0xfc,
+ 0x0f, 0x11, 0x19, 0x00, 0xfc, 0x01, 0x11, 0x0b, 0x00,
+};
+
+const unsigned char ReadProgmem_1[73] = {
+ 0x91, 0x00, 0x91, 0x01, 0x95, 0x90, 0x11, 0x00, 0x00, 0x00, 0x00, 0x90, 0x0f, 0x80, 0x00, 0x00,
+ 0x00, 0xfa, 0x01, 0x0f, 0x19, 0x00, 0x60, 0x0f, 0x01, 0x90, 0x10, 0x00, 0x01, 0x00, 0x00, 0xfa,
+ 0x0f, 0x10, 0x27, 0x00, 0x60, 0x10, 0x0f, 0x1e, 0x09, 0x00, 0x60, 0x04, 0x10, 0x67, 0x04, 0x01,
+ 0x1e, 0x10, 0x04, 0x1e, 0x0d, 0x04, 0x6a, 0x0f, 0x10, 0x6e, 0x00, 0x10, 0x6a, 0x01, 0x10, 0xfc,
+ 0x0f, 0x11, 0x19, 0x00, 0xfc, 0x01, 0x11, 0x0b, 0x00,
+};
+
+const unsigned char ReadProgmem_2[73] = {
+ 0x91, 0x00, 0x91, 0x01, 0x95, 0x90, 0x11, 0x00, 0x00, 0x00, 0x00, 0x90, 0x0f, 0x00, 0x02, 0x00,
+ 0x00, 0xfa, 0x01, 0x0f, 0x19, 0x00, 0x60, 0x0f, 0x01, 0x90, 0x10, 0x00, 0x01, 0x00, 0x00, 0xfa,
+ 0x0f, 0x10, 0x27, 0x00, 0x60, 0x10, 0x0f, 0x1e, 0x09, 0x00, 0x60, 0x04, 0x10, 0x67, 0x04, 0x01,
+ 0x1e, 0x10, 0x04, 0x1e, 0x0d, 0x04, 0x6a, 0x0f, 0x10, 0x6e, 0x00, 0x10, 0x6a, 0x01, 0x10, 0xfc,
+ 0x0f, 0x11, 0x19, 0x00, 0xfc, 0x01, 0x11, 0x0b, 0x00,
+};
+
+const unsigned char WriteDataEEmem_0[208] = {
+ 0x91, 0x00, 0x91, 0x01, 0x90, 0x11, 0x00, 0x00, 0x00, 0x00, 0x90, 0x0f, 0x20, 0x00, 0x00, 0x00,
+ 0xfa, 0x01, 0x0f, 0x18, 0x00, 0x60, 0x0f, 0x01, 0x90, 0x03, 0x00, 0x00, 0x00, 0x00, 0xfe, 0x03,
+ 0x00, 0x00, 0x00, 0x00, 0x30, 0x00, 0x90, 0x02, 0x00, 0x10, 0x00, 0x00, 0x1e, 0x06, 0x02, 0x03,
+ 0x90, 0x02, 0x02, 0x10, 0x00, 0x00, 0xa2, 0x1e, 0x03, 0x02, 0x94, 0x02, 0x00, 0xa5, 0x03, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14, 0x00, 0x90, 0x02, 0x00, 0x10, 0x00, 0x00, 0x90, 0x03,
+ 0x04, 0x00, 0x00, 0x00, 0x1e, 0x06, 0x02, 0x03, 0x90, 0x02, 0x02, 0x10, 0x00, 0x00, 0xa2, 0x1e,
+ 0x03, 0x02, 0x94, 0x02, 0x00, 0xa5, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14, 0x00,
+ 0x90, 0x10, 0x00, 0x01, 0x00, 0x00, 0xfa, 0x0f, 0x10, 0x7e, 0x00, 0x60, 0x10, 0x0f, 0x1e, 0x09,
+ 0x00, 0x1e, 0x10, 0x10, 0x1e, 0x0a, 0x10, 0x6a, 0x0f, 0x10, 0x6e, 0x00, 0x10, 0x6a, 0x01, 0x10,
+ 0xfc, 0x0f, 0x11, 0x70, 0x00, 0x90, 0x06, 0x00, 0x10, 0x00, 0x00, 0x90, 0x07, 0x03, 0x00, 0x00,
+ 0x00, 0x1e, 0x06, 0x06, 0x07, 0x6c, 0x0c, 0x90, 0x0d, 0x00, 0x00, 0x00, 0x00, 0xfc, 0x0c, 0x0d,
+ 0xcf, 0x00, 0x90, 0x02, 0x02, 0x10, 0x00, 0x00, 0xa2, 0x1e, 0x03, 0x02, 0x94, 0x02, 0x00, 0xa5,
+ 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14, 0x00, 0xfc, 0x01, 0x11, 0x0a, 0x00, 0xaf,
+};
+
+const unsigned char WriteDataEEmem_1[208] = {
+ 0x91, 0x00, 0x91, 0x01, 0x90, 0x11, 0x00, 0x00, 0x00, 0x00, 0x90, 0x0f, 0x40, 0x00, 0x00, 0x00,
+ 0xfa, 0x01, 0x0f, 0x18, 0x00, 0x60, 0x0f, 0x01, 0x90, 0x03, 0x00, 0x00, 0x00, 0x00, 0xfe, 0x03,
+ 0x00, 0x00, 0x00, 0x00, 0x30, 0x00, 0x90, 0x02, 0x00, 0x10, 0x00, 0x00, 0x1e, 0x06, 0x02, 0x03,
+ 0x90, 0x02, 0x02, 0x10, 0x00, 0x00, 0xa2, 0x1e, 0x03, 0x02, 0x94, 0x02, 0x00, 0xa5, 0x03, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14, 0x00, 0x90, 0x02, 0x00, 0x10, 0x00, 0x00, 0x90, 0x03,
+ 0x04, 0x00, 0x00, 0x00, 0x1e, 0x06, 0x02, 0x03, 0x90, 0x02, 0x02, 0x10, 0x00, 0x00, 0xa2, 0x1e,
+ 0x03, 0x02, 0x94, 0x02, 0x00, 0xa5, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14, 0x00,
+ 0x90, 0x10, 0x00, 0x01, 0x00, 0x00, 0xfa, 0x0f, 0x10, 0x7e, 0x00, 0x60, 0x10, 0x0f, 0x1e, 0x09,
+ 0x00, 0x1e, 0x10, 0x10, 0x1e, 0x0a, 0x10, 0x6a, 0x0f, 0x10, 0x6e, 0x00, 0x10, 0x6a, 0x01, 0x10,
+ 0xfc, 0x0f, 0x11, 0x70, 0x00, 0x90, 0x06, 0x00, 0x10, 0x00, 0x00, 0x90, 0x07, 0x03, 0x00, 0x00,
+ 0x00, 0x1e, 0x06, 0x06, 0x07, 0x6c, 0x0c, 0x90, 0x0d, 0x00, 0x00, 0x00, 0x00, 0xfc, 0x0c, 0x0d,
+ 0xcf, 0x00, 0x90, 0x02, 0x02, 0x10, 0x00, 0x00, 0xa2, 0x1e, 0x03, 0x02, 0x94, 0x02, 0x00, 0xa5,
+ 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14, 0x00, 0xfc, 0x01, 0x11, 0x0a, 0x00, 0xaf,
+};
+
+const unsigned char WriteDataEEmem_2[176] = {
+ 0x91, 0x00, 0x91, 0x01, 0x90, 0x11, 0x00, 0x00, 0x00, 0x00, 0x90, 0x0f, 0x01, 0x00, 0x00, 0x00,
+ 0xfa, 0x01, 0x0f, 0x18, 0x00, 0x60, 0x0f, 0x01, 0x90, 0x02, 0x02, 0x10, 0x00, 0x00, 0xa2, 0x1e,
+ 0x03, 0x02, 0x94, 0x02, 0x00, 0xa5, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14, 0x00,
+ 0x90, 0x06, 0x00, 0x10, 0x00, 0x00, 0x90, 0x07, 0x13, 0x00, 0x00, 0x00, 0x1e, 0x06, 0x06, 0x07,
+ 0x90, 0x10, 0x00, 0x01, 0x00, 0x00, 0xfa, 0x0f, 0x10, 0x4e, 0x00, 0x60, 0x10, 0x0f, 0x1e, 0x09,
+ 0x00, 0x1e, 0x10, 0x10, 0x1e, 0x0a, 0x10, 0x6a, 0x0f, 0x10, 0x6e, 0x00, 0x10, 0x6a, 0x01, 0x10,
+ 0xfc, 0x0f, 0x11, 0x40, 0x00, 0x6c, 0x0c, 0x90, 0x0d, 0x00, 0x00, 0x00, 0x00, 0xfc, 0x0c, 0x0d,
+ 0xa0, 0x00, 0x90, 0x02, 0x02, 0x10, 0x00, 0x00, 0xa2, 0x1e, 0x03, 0x02, 0x94, 0x02, 0x00, 0xa5,
+ 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14, 0x00, 0x90, 0x06, 0x00, 0x10, 0x00, 0x00,
+ 0x90, 0x07, 0x00, 0x00, 0x00, 0x00, 0x1e, 0x06, 0x06, 0x07, 0xfc, 0x01, 0x11, 0x0a, 0x00, 0x5a,
+ 0x90, 0x06, 0x00, 0x10, 0x00, 0x00, 0x90, 0x07, 0x00, 0x00, 0x00, 0x00, 0x1e, 0x06, 0x06, 0x07,
+};
+
+const unsigned char WriteDataEEmem_3[208] = {
+ 0x91, 0x00, 0x91, 0x01, 0x90, 0x11, 0x00, 0x00, 0x00, 0x00, 0x90, 0x0f, 0x08, 0x00, 0x00, 0x00,
+ 0xfa, 0x01, 0x0f, 0x18, 0x00, 0x60, 0x0f, 0x01, 0x90, 0x03, 0x1f, 0x00, 0x00, 0x00, 0xfe, 0x03,
+ 0x00, 0x00, 0x00, 0x00, 0x30, 0x00, 0x90, 0x02, 0x00, 0x10, 0x00, 0x00, 0x1e, 0x06, 0x02, 0x03,
+ 0x90, 0x02, 0x06, 0x10, 0x00, 0x00, 0xa2, 0x1e, 0x03, 0x02, 0x94, 0x02, 0x00, 0xa5, 0x03, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14, 0x00, 0x90, 0x02, 0x00, 0x10, 0x00, 0x00, 0x90, 0x03,
+ 0x0f, 0x00, 0x00, 0x00, 0x1e, 0x06, 0x02, 0x03, 0x90, 0x02, 0x06, 0x10, 0x00, 0x00, 0xa2, 0x1e,
+ 0x03, 0x02, 0x94, 0x02, 0x00, 0xa5, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14, 0x00,
+ 0x90, 0x10, 0x00, 0x01, 0x00, 0x00, 0xfa, 0x0f, 0x10, 0x7e, 0x00, 0x60, 0x10, 0x0f, 0x1e, 0x09,
+ 0x00, 0x1e, 0x10, 0x10, 0x1e, 0x0a, 0x10, 0x6a, 0x0f, 0x10, 0x6e, 0x00, 0x10, 0x6a, 0x01, 0x10,
+ 0xfc, 0x0f, 0x11, 0x70, 0x00, 0x90, 0x06, 0x00, 0x10, 0x00, 0x00, 0x90, 0x07, 0x15, 0x00, 0x00,
+ 0x00, 0x1e, 0x06, 0x06, 0x07, 0x6c, 0x0c, 0x90, 0x0d, 0x00, 0x00, 0x00, 0x00, 0xfc, 0x0c, 0x0d,
+ 0xcf, 0x00, 0x90, 0x02, 0x06, 0x10, 0x00, 0x00, 0xa2, 0x1e, 0x03, 0x02, 0x94, 0x02, 0x00, 0xa5,
+ 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14, 0x00, 0xfc, 0x01, 0x11, 0x0a, 0x00, 0xaf,
+};
+
+const unsigned char WriteDataEEmem_4[176] = {
+ 0x91, 0x00, 0x91, 0x01, 0x90, 0x11, 0x00, 0x00, 0x00, 0x00, 0x90, 0x0f, 0x01, 0x00, 0x00, 0x00,
+ 0xfa, 0x01, 0x0f, 0x18, 0x00, 0x60, 0x0f, 0x01, 0x90, 0x02, 0x06, 0x10, 0x00, 0x00, 0xa2, 0x1e,
+ 0x03, 0x02, 0x94, 0x02, 0x00, 0xa5, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14, 0x00,
+ 0x90, 0x06, 0x00, 0x10, 0x00, 0x00, 0x90, 0x07, 0x13, 0x00, 0x00, 0x00, 0x1e, 0x06, 0x06, 0x07,
+ 0x90, 0x10, 0x00, 0x01, 0x00, 0x00, 0xfa, 0x0f, 0x10, 0x4e, 0x00, 0x60, 0x10, 0x0f, 0x1e, 0x09,
+ 0x00, 0x1e, 0x10, 0x10, 0x1e, 0x0a, 0x10, 0x6a, 0x0f, 0x10, 0x6e, 0x00, 0x10, 0x6a, 0x01, 0x10,
+ 0xfc, 0x0f, 0x11, 0x40, 0x00, 0x6c, 0x0c, 0x90, 0x0d, 0x00, 0x00, 0x00, 0x00, 0xfc, 0x0c, 0x0d,
+ 0xa0, 0x00, 0x90, 0x02, 0x06, 0x10, 0x00, 0x00, 0xa2, 0x1e, 0x03, 0x02, 0x94, 0x02, 0x00, 0xa5,
+ 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14, 0x00, 0x90, 0x06, 0x00, 0x10, 0x00, 0x00,
+ 0x90, 0x07, 0x00, 0x00, 0x00, 0x00, 0x1e, 0x06, 0x06, 0x07, 0xfc, 0x01, 0x11, 0x0a, 0x00, 0x5a,
+ 0x90, 0x06, 0x00, 0x10, 0x00, 0x00, 0x90, 0x07, 0x00, 0x00, 0x00, 0x00, 0x1e, 0x06, 0x06, 0x07,
+};
+
+const unsigned char WriteDataEEmem_5[176] = {
+ 0x91, 0x00, 0x91, 0x01, 0x90, 0x11, 0x00, 0x00, 0x00, 0x00, 0x90, 0x0f, 0x01, 0x00, 0x00, 0x00,
+ 0xfa, 0x01, 0x0f, 0x18, 0x00, 0x60, 0x0f, 0x01, 0x90, 0x02, 0x07, 0x10, 0x00, 0x00, 0xa2, 0x1e,
+ 0x03, 0x02, 0x94, 0x02, 0x00, 0xa5, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14, 0x00,
+ 0x90, 0x06, 0x00, 0x10, 0x00, 0x00, 0x90, 0x07, 0x13, 0x00, 0x00, 0x00, 0x1e, 0x06, 0x06, 0x07,
+ 0x90, 0x10, 0x00, 0x01, 0x00, 0x00, 0xfa, 0x0f, 0x10, 0x4e, 0x00, 0x60, 0x10, 0x0f, 0x1e, 0x09,
+ 0x00, 0x1e, 0x10, 0x10, 0x1e, 0x0a, 0x10, 0x6a, 0x0f, 0x10, 0x6e, 0x00, 0x10, 0x6a, 0x01, 0x10,
+ 0xfc, 0x0f, 0x11, 0x40, 0x00, 0x6c, 0x0c, 0x90, 0x0d, 0x00, 0x00, 0x00, 0x00, 0xfc, 0x0c, 0x0d,
+ 0xa0, 0x00, 0x90, 0x02, 0x07, 0x10, 0x00, 0x00, 0xa2, 0x1e, 0x03, 0x02, 0x94, 0x02, 0x00, 0xa5,
+ 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14, 0x00, 0x90, 0x06, 0x00, 0x10, 0x00, 0x00,
+ 0x90, 0x07, 0x00, 0x00, 0x00, 0x00, 0x1e, 0x06, 0x06, 0x07, 0xfc, 0x01, 0x11, 0x0a, 0x00, 0x5a,
+ 0x90, 0x06, 0x00, 0x10, 0x00, 0x00, 0x90, 0x07, 0x00, 0x00, 0x00, 0x00, 0x1e, 0x06, 0x06, 0x07,
+};
+
+const unsigned char ReadDataEEmem_0[67] = {
+ 0x91, 0x00, 0x91, 0x01, 0x95, 0x90, 0x11, 0x00, 0x00, 0x00, 0x00, 0x90, 0x0f, 0x20, 0x00, 0x00,
+ 0x00, 0xfa, 0x01, 0x0f, 0x19, 0x00, 0x60, 0x0f, 0x01, 0x90, 0x10, 0x00, 0x01, 0x00, 0x00, 0xfa,
+ 0x0f, 0x10, 0x27, 0x00, 0x60, 0x10, 0x0f, 0x1e, 0x09, 0x00, 0x1e, 0x10, 0x10, 0x1e, 0x0c, 0x10,
+ 0x6a, 0x0f, 0x10, 0x6e, 0x00, 0x10, 0x6a, 0x01, 0x10, 0xfc, 0x0f, 0x11, 0x19, 0x00, 0xfc, 0x01,
+ 0x11, 0x0b, 0x00,
+};
+
+const unsigned char ReadDataEEmem_1[67] = {
+ 0x91, 0x00, 0x91, 0x01, 0x95, 0x90, 0x11, 0x00, 0x00, 0x00, 0x00, 0x90, 0x0f, 0x40, 0x00, 0x00,
+ 0x00, 0xfa, 0x01, 0x0f, 0x19, 0x00, 0x60, 0x0f, 0x01, 0x90, 0x10, 0x00, 0x01, 0x00, 0x00, 0xfa,
+ 0x0f, 0x10, 0x27, 0x00, 0x60, 0x10, 0x0f, 0x1e, 0x09, 0x00, 0x1e, 0x10, 0x10, 0x1e, 0x0c, 0x10,
+ 0x6a, 0x0f, 0x10, 0x6e, 0x00, 0x10, 0x6a, 0x01, 0x10, 0xfc, 0x0f, 0x11, 0x19, 0x00, 0xfc, 0x01,
+ 0x11, 0x0b, 0x00,
+};
+
+const unsigned char ReadDataEEmem_2[67] = {
+ 0x91, 0x00, 0x91, 0x01, 0x95, 0x90, 0x11, 0x00, 0x00, 0x00, 0x00, 0x90, 0x0f, 0x01, 0x00, 0x00,
+ 0x00, 0xfa, 0x01, 0x0f, 0x19, 0x00, 0x60, 0x0f, 0x01, 0x90, 0x10, 0x00, 0x01, 0x00, 0x00, 0xfa,
+ 0x0f, 0x10, 0x27, 0x00, 0x60, 0x10, 0x0f, 0x1e, 0x09, 0x00, 0x1e, 0x10, 0x10, 0x1e, 0x0c, 0x10,
+ 0x6a, 0x0f, 0x10, 0x6e, 0x00, 0x10, 0x6a, 0x01, 0x10, 0xfc, 0x0f, 0x11, 0x19, 0x00, 0xfc, 0x01,
+ 0x11, 0x0b, 0x00,
+};
+
+const unsigned char ReadDataEEmem_3[67] = {
+ 0x91, 0x00, 0x91, 0x01, 0x95, 0x90, 0x11, 0x00, 0x00, 0x00, 0x00, 0x90, 0x0f, 0x08, 0x00, 0x00,
+ 0x00, 0xfa, 0x01, 0x0f, 0x19, 0x00, 0x60, 0x0f, 0x01, 0x90, 0x10, 0x00, 0x01, 0x00, 0x00, 0xfa,
+ 0x0f, 0x10, 0x27, 0x00, 0x60, 0x10, 0x0f, 0x1e, 0x09, 0x00, 0x1e, 0x10, 0x10, 0x1e, 0x0c, 0x10,
+ 0x6a, 0x0f, 0x10, 0x6e, 0x00, 0x10, 0x6a, 0x01, 0x10, 0xfc, 0x0f, 0x11, 0x19, 0x00, 0xfc, 0x01,
+ 0x11, 0x0b, 0x00,
+};
+
+const unsigned char WriteConfigmem_0[369] = {
+ 0x91, 0x00, 0x91, 0x01, 0x90, 0x03, 0x00, 0x00, 0x00, 0x00, 0xfe, 0x03, 0x01, 0x00, 0x00, 0x00,
+ 0x93, 0x00, 0xad, 0x01, 0x90, 0x02, 0x02, 0x10, 0x00, 0x00, 0xa2, 0x1e, 0x03, 0x02, 0x94, 0x02,
+ 0x00, 0xa5, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14, 0x00, 0x60, 0x03, 0x00, 0x60,
+ 0x04, 0x00, 0x66, 0x03, 0xff, 0x00, 0x00, 0x00, 0x67, 0x04, 0x08, 0x66, 0x04, 0xff, 0x00, 0x00,
+ 0x00, 0x90, 0x06, 0x08, 0x10, 0x00, 0x00, 0x1e, 0x06, 0x06, 0x03, 0x90, 0x06, 0x09, 0x10, 0x00,
+ 0x00, 0x1e, 0x06, 0x06, 0x04, 0x90, 0x06, 0x06, 0x10, 0x00, 0x00, 0x99, 0x07, 0x1e, 0x06, 0x06,
+ 0x07, 0x90, 0x06, 0x00, 0x10, 0x00, 0x00, 0x90, 0x07, 0x07, 0x00, 0x00, 0x00, 0x1e, 0x06, 0x06,
+ 0x07, 0x90, 0x02, 0x02, 0x10, 0x00, 0x00, 0xa2, 0x1e, 0x03, 0x02, 0x94, 0x02, 0x00, 0xa5, 0x03,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14, 0x00, 0x92, 0x00, 0x01, 0x00, 0x00, 0x00, 0xae,
+ 0xfb, 0x70, 0x01, 0xad, 0x01, 0x90, 0x02, 0x02, 0x10, 0x00, 0x00, 0xa2, 0x1e, 0x03, 0x02, 0x94,
+ 0x02, 0x00, 0xa5, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14, 0x00, 0x60, 0x03, 0x00,
+ 0x60, 0x04, 0x00, 0x66, 0x03, 0xff, 0x00, 0x00, 0x00, 0x67, 0x04, 0x08, 0x66, 0x04, 0xff, 0x00,
+ 0x00, 0x00, 0x90, 0x06, 0x08, 0x10, 0x00, 0x00, 0x1e, 0x06, 0x06, 0x03, 0x90, 0x06, 0x09, 0x10,
+ 0x00, 0x00, 0x1e, 0x06, 0x06, 0x04, 0x90, 0x03, 0x00, 0x00, 0x00, 0x00, 0xfe, 0x03, 0x00, 0x00,
+ 0x00, 0x00, 0xee, 0x00, 0x90, 0x02, 0x00, 0x10, 0x00, 0x00, 0x1e, 0x06, 0x02, 0x03, 0x90, 0x02,
+ 0x02, 0x10, 0x00, 0x00, 0xa2, 0x1e, 0x03, 0x02, 0x94, 0x02, 0x00, 0xa5, 0x03, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x14, 0x00, 0x90, 0x02, 0x00, 0x10, 0x00, 0x00, 0x90, 0x03, 0x04, 0x00,
+ 0x00, 0x00, 0x1e, 0x06, 0x02, 0x03, 0x90, 0x02, 0x02, 0x10, 0x00, 0x00, 0xa2, 0x1e, 0x03, 0x02,
+ 0x94, 0x02, 0x00, 0xa5, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14, 0x00, 0x99, 0x07,
+ 0x1e, 0x06, 0x00, 0x07, 0x90, 0x06, 0x00, 0x10, 0x00, 0x00, 0x90, 0x07, 0x03, 0x00, 0x00, 0x00,
+ 0x1e, 0x06, 0x06, 0x07, 0x6c, 0x0c, 0x90, 0x0d, 0x00, 0x00, 0x00, 0x00, 0xfc, 0x0c, 0x0d, 0x70,
+ 0x01, 0x90, 0x02, 0x02, 0x10, 0x00, 0x00, 0xa2, 0x1e, 0x03, 0x02, 0x94, 0x02, 0x00, 0xa5, 0x03,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14, 0x00, 0x92, 0x00, 0x01, 0x00, 0x00, 0x00, 0xae,
+ 0xaf,
+};
+
+const unsigned char WriteConfigmem_1[128] = {
+ 0x91, 0x00, 0x91, 0x01, 0xad, 0x01, 0x90, 0x02, 0x02, 0x10, 0x00, 0x00, 0xa2, 0x1e, 0x03, 0x02,
+ 0x94, 0x02, 0x00, 0xa5, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14, 0x00, 0x90, 0x06,
+ 0x00, 0x10, 0x00, 0x00, 0x90, 0x07, 0x13, 0x00, 0x00, 0x00, 0x1e, 0x06, 0x06, 0x07, 0x99, 0x03,
+ 0x1e, 0x06, 0x00, 0x03, 0x6c, 0x0c, 0x90, 0x0d, 0x00, 0x00, 0x00, 0x00, 0xfc, 0x0c, 0x0d, 0x70,
+ 0x00, 0x90, 0x02, 0x02, 0x10, 0x00, 0x00, 0xa2, 0x1e, 0x03, 0x02, 0x94, 0x02, 0x00, 0xa5, 0x03,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14, 0x00, 0x90, 0x06, 0x00, 0x10, 0x00, 0x00, 0x90,
+ 0x07, 0x00, 0x00, 0x00, 0x00, 0x1e, 0x06, 0x06, 0x07, 0x92, 0x00, 0x01, 0x00, 0x00, 0x00, 0xae,
+ 0x90, 0x06, 0x00, 0x10, 0x00, 0x00, 0x90, 0x07, 0x00, 0x00, 0x00, 0x00, 0x1e, 0x06, 0x06, 0x07,
+};
+
+const unsigned char WriteConfigmem_2[369] = {
+ 0x91, 0x00, 0x91, 0x01, 0x90, 0x03, 0x01, 0x00, 0x00, 0x00, 0xfe, 0x03, 0x01, 0x00, 0x00, 0x00,
+ 0x93, 0x00, 0xad, 0x01, 0x90, 0x02, 0x06, 0x10, 0x00, 0x00, 0xa2, 0x1e, 0x03, 0x02, 0x94, 0x02,
+ 0x00, 0xa5, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14, 0x00, 0x60, 0x03, 0x00, 0x60,
+ 0x04, 0x00, 0x66, 0x03, 0xff, 0x00, 0x00, 0x00, 0x67, 0x04, 0x08, 0x66, 0x04, 0xff, 0x00, 0x00,
+ 0x00, 0x90, 0x06, 0x0c, 0x10, 0x00, 0x00, 0x1e, 0x06, 0x06, 0x03, 0x90, 0x06, 0x0d, 0x10, 0x00,
+ 0x00, 0x1e, 0x06, 0x06, 0x04, 0x90, 0x06, 0x08, 0x10, 0x00, 0x00, 0x99, 0x07, 0x1e, 0x06, 0x06,
+ 0x07, 0x90, 0x06, 0x00, 0x10, 0x00, 0x00, 0x90, 0x07, 0x00, 0x00, 0x00, 0x00, 0x1e, 0x06, 0x06,
+ 0x07, 0x90, 0x02, 0x06, 0x10, 0x00, 0x00, 0xa2, 0x1e, 0x03, 0x02, 0x94, 0x02, 0x00, 0xa5, 0x03,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14, 0x00, 0x92, 0x00, 0x01, 0x00, 0x00, 0x00, 0xae,
+ 0xfb, 0x70, 0x01, 0xad, 0x01, 0x90, 0x02, 0x06, 0x10, 0x00, 0x00, 0xa2, 0x1e, 0x03, 0x02, 0x94,
+ 0x02, 0x00, 0xa5, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14, 0x00, 0x60, 0x03, 0x00,
+ 0x60, 0x04, 0x00, 0x66, 0x03, 0xff, 0x00, 0x00, 0x00, 0x67, 0x04, 0x08, 0x66, 0x04, 0xff, 0x00,
+ 0x00, 0x00, 0x90, 0x06, 0x0c, 0x10, 0x00, 0x00, 0x1e, 0x06, 0x06, 0x03, 0x90, 0x06, 0x0d, 0x10,
+ 0x00, 0x00, 0x1e, 0x06, 0x06, 0x04, 0x90, 0x03, 0x1f, 0x00, 0x00, 0x00, 0xfe, 0x03, 0x00, 0x00,
+ 0x00, 0x00, 0xee, 0x00, 0x90, 0x02, 0x00, 0x10, 0x00, 0x00, 0x1e, 0x06, 0x02, 0x03, 0x90, 0x02,
+ 0x06, 0x10, 0x00, 0x00, 0xa2, 0x1e, 0x03, 0x02, 0x94, 0x02, 0x00, 0xa5, 0x03, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x14, 0x00, 0x90, 0x02, 0x00, 0x10, 0x00, 0x00, 0x90, 0x03, 0x0f, 0x00,
+ 0x00, 0x00, 0x1e, 0x06, 0x02, 0x03, 0x90, 0x02, 0x06, 0x10, 0x00, 0x00, 0xa2, 0x1e, 0x03, 0x02,
+ 0x94, 0x02, 0x00, 0xa5, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14, 0x00, 0x99, 0x07,
+ 0x1e, 0x06, 0x00, 0x07, 0x90, 0x06, 0x00, 0x10, 0x00, 0x00, 0x90, 0x07, 0x15, 0x00, 0x00, 0x00,
+ 0x1e, 0x06, 0x06, 0x07, 0x6c, 0x0c, 0x90, 0x0d, 0x00, 0x00, 0x00, 0x00, 0xfc, 0x0c, 0x0d, 0x70,
+ 0x01, 0x90, 0x02, 0x06, 0x10, 0x00, 0x00, 0xa2, 0x1e, 0x03, 0x02, 0x94, 0x02, 0x00, 0xa5, 0x03,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14, 0x00, 0x92, 0x00, 0x01, 0x00, 0x00, 0x00, 0xae,
+ 0xaf,
+};
+
+const unsigned char WriteConfigmem_3[128] = {
+ 0x91, 0x00, 0x91, 0x01, 0xad, 0x01, 0x90, 0x02, 0x06, 0x10, 0x00, 0x00, 0xa2, 0x1e, 0x03, 0x02,
+ 0x94, 0x02, 0x00, 0xa5, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14, 0x00, 0x90, 0x06,
+ 0x00, 0x10, 0x00, 0x00, 0x90, 0x07, 0x13, 0x00, 0x00, 0x00, 0x1e, 0x06, 0x06, 0x07, 0x99, 0x03,
+ 0x1e, 0x06, 0x00, 0x03, 0x6c, 0x0c, 0x90, 0x0d, 0x00, 0x00, 0x00, 0x00, 0xfc, 0x0c, 0x0d, 0x70,
+ 0x00, 0x90, 0x02, 0x06, 0x10, 0x00, 0x00, 0xa2, 0x1e, 0x03, 0x02, 0x94, 0x02, 0x00, 0xa5, 0x03,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14, 0x00, 0x90, 0x06, 0x00, 0x10, 0x00, 0x00, 0x90,
+ 0x07, 0x00, 0x00, 0x00, 0x00, 0x1e, 0x06, 0x06, 0x07, 0x92, 0x00, 0x01, 0x00, 0x00, 0x00, 0xae,
+ 0x90, 0x06, 0x00, 0x10, 0x00, 0x00, 0x90, 0x07, 0x00, 0x00, 0x00, 0x00, 0x1e, 0x06, 0x06, 0x07,
+};
+
+const unsigned char WriteConfigmem_4[128] = {
+ 0x91, 0x00, 0x91, 0x01, 0xad, 0x01, 0x90, 0x02, 0x07, 0x10, 0x00, 0x00, 0xa2, 0x1e, 0x03, 0x02,
+ 0x94, 0x02, 0x00, 0xa5, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14, 0x00, 0x90, 0x06,
+ 0x00, 0x10, 0x00, 0x00, 0x90, 0x07, 0x13, 0x00, 0x00, 0x00, 0x1e, 0x06, 0x06, 0x07, 0x99, 0x03,
+ 0x1e, 0x06, 0x00, 0x03, 0x6c, 0x0c, 0x90, 0x0d, 0x00, 0x00, 0x00, 0x00, 0xfc, 0x0c, 0x0d, 0x70,
+ 0x00, 0x90, 0x02, 0x07, 0x10, 0x00, 0x00, 0xa2, 0x1e, 0x03, 0x02, 0x94, 0x02, 0x00, 0xa5, 0x03,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14, 0x00, 0x90, 0x06, 0x00, 0x10, 0x00, 0x00, 0x90,
+ 0x07, 0x00, 0x00, 0x00, 0x00, 0x1e, 0x06, 0x06, 0x07, 0x92, 0x00, 0x01, 0x00, 0x00, 0x00, 0xae,
+ 0x90, 0x06, 0x00, 0x10, 0x00, 0x00, 0x90, 0x07, 0x00, 0x00, 0x00, 0x00, 0x1e, 0x06, 0x06, 0x07,
+};
+
+const unsigned char ReadConfigmem_0[19] = {
+ 0x91, 0x00, 0x91, 0x01, 0x95, 0xad, 0x01, 0x1e, 0x03, 0x00, 0x9f, 0x92, 0x00, 0x01, 0x00, 0x00,
+ 0x00, 0xae, 0x5a,
+};
+
+const unsigned char WriteIDmem_0[421] = {
+ 0x91, 0x00, 0x91, 0x01, 0x90, 0x03, 0x01, 0x00, 0x00, 0x00, 0xfe, 0x03, 0x02, 0x00, 0x00, 0x00,
+ 0x1d, 0x00, 0xfe, 0x03, 0x01, 0x00, 0x00, 0x00, 0xd9, 0x00, 0xfb, 0xa4, 0x01, 0x90, 0x11, 0x00,
+ 0x00, 0x00, 0x00, 0x90, 0x0f, 0x20, 0x00, 0x00, 0x00, 0xfa, 0x01, 0x0f, 0xed, 0x00, 0x60, 0x0f,
+ 0x01, 0x90, 0x02, 0x02, 0x10, 0x00, 0x00, 0xa2, 0x1e, 0x03, 0x02, 0x94, 0x02, 0x00, 0xa5, 0x03,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14, 0x00, 0x90, 0x02, 0x00, 0x10, 0x00, 0x00, 0x90,
+ 0x03, 0x04, 0x00, 0x00, 0x00, 0x1e, 0x06, 0x02, 0x03, 0x90, 0x02, 0x02, 0x10, 0x00, 0x00, 0xa2,
+ 0x1e, 0x03, 0x02, 0x94, 0x02, 0x00, 0xa5, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14,
+ 0x00, 0x90, 0x10, 0x00, 0x01, 0x00, 0x00, 0xfa, 0x0f, 0x10, 0x53, 0x01, 0x60, 0x10, 0x0f, 0x1e,
+ 0x09, 0x00, 0x60, 0x04, 0x10, 0x67, 0x04, 0x01, 0x1e, 0x10, 0x04, 0x1e, 0x0b, 0x04, 0x6a, 0x0f,
+ 0x10, 0x6e, 0x00, 0x10, 0x6a, 0x01, 0x10, 0xfc, 0x0f, 0x11, 0x45, 0x01, 0x90, 0x06, 0x00, 0x10,
+ 0x00, 0x00, 0x90, 0x07, 0x03, 0x00, 0x00, 0x00, 0x1e, 0x06, 0x06, 0x07, 0x6c, 0x0c, 0x90, 0x0d,
+ 0x00, 0x00, 0x00, 0x00, 0xfc, 0x0c, 0x0d, 0xa4, 0x01, 0x90, 0x02, 0x02, 0x10, 0x00, 0x00, 0xa2,
+ 0x1e, 0x03, 0x02, 0x94, 0x02, 0x00, 0xa5, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14,
+ 0x00, 0xfc, 0x01, 0x11, 0xdf, 0x00, 0xfb, 0xa4, 0x01, 0x90, 0x11, 0x00, 0x00, 0x00, 0x00, 0x90,
+ 0x0f, 0x20, 0x00, 0x00, 0x00, 0xfa, 0x01, 0x0f, 0xed, 0x00, 0x60, 0x0f, 0x01, 0x90, 0x03, 0x00,
+ 0x00, 0x00, 0x00, 0xfe, 0x03, 0x00, 0x00, 0x00, 0x00, 0x05, 0x01, 0x90, 0x02, 0x00, 0x10, 0x00,
+ 0x00, 0x1e, 0x06, 0x02, 0x03, 0x90, 0x02, 0x02, 0x10, 0x00, 0x00, 0xa2, 0x1e, 0x03, 0x02, 0x94,
+ 0x02, 0x00, 0xa5, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14, 0x00, 0x90, 0x02, 0x00,
+ 0x10, 0x00, 0x00, 0x90, 0x03, 0x04, 0x00, 0x00, 0x00, 0x1e, 0x06, 0x02, 0x03, 0x90, 0x02, 0x02,
+ 0x10, 0x00, 0x00, 0xa2, 0x1e, 0x03, 0x02, 0x94, 0x02, 0x00, 0xa5, 0x03, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x14, 0x00, 0x90, 0x10, 0x00, 0x01, 0x00, 0x00, 0xfa, 0x0f, 0x10, 0x53, 0x01,
+ 0x60, 0x10, 0x0f, 0x1e, 0x09, 0x00, 0x1e, 0x10, 0x10, 0x1e, 0x0a, 0x10, 0x6a, 0x0f, 0x10, 0x6e,
+ 0x00, 0x10, 0x6a, 0x01, 0x10, 0xfc, 0x0f, 0x11, 0x45, 0x01, 0x90, 0x06, 0x00, 0x10, 0x00, 0x00,
+ 0x90, 0x07, 0x03, 0x00, 0x00, 0x00, 0x1e, 0x06, 0x06, 0x07, 0x6c, 0x0c, 0x90, 0x0d, 0x00, 0x00,
+ 0x00, 0x00, 0xfc, 0x0c, 0x0d, 0xa4, 0x01, 0x90, 0x02, 0x02, 0x10, 0x00, 0x00, 0xa2, 0x1e, 0x03,
+ 0x02, 0x94, 0x02, 0x00, 0xa5, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14, 0x00, 0xfc,
+ 0x01, 0x11, 0xdf, 0x00, 0xaf,
+};
+
+const unsigned char WriteIDmem_1[421] = {
+ 0x91, 0x00, 0x91, 0x01, 0x90, 0x03, 0x01, 0x00, 0x00, 0x00, 0xfe, 0x03, 0x02, 0x00, 0x00, 0x00,
+ 0x1d, 0x00, 0xfe, 0x03, 0x01, 0x00, 0x00, 0x00, 0xd9, 0x00, 0xfb, 0xa4, 0x01, 0x90, 0x11, 0x00,
+ 0x00, 0x00, 0x00, 0x90, 0x0f, 0x40, 0x00, 0x00, 0x00, 0xfa, 0x01, 0x0f, 0xed, 0x00, 0x60, 0x0f,
+ 0x01, 0x90, 0x02, 0x02, 0x10, 0x00, 0x00, 0xa2, 0x1e, 0x03, 0x02, 0x94, 0x02, 0x00, 0xa5, 0x03,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14, 0x00, 0x90, 0x02, 0x00, 0x10, 0x00, 0x00, 0x90,
+ 0x03, 0x04, 0x00, 0x00, 0x00, 0x1e, 0x06, 0x02, 0x03, 0x90, 0x02, 0x02, 0x10, 0x00, 0x00, 0xa2,
+ 0x1e, 0x03, 0x02, 0x94, 0x02, 0x00, 0xa5, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14,
+ 0x00, 0x90, 0x10, 0x00, 0x01, 0x00, 0x00, 0xfa, 0x0f, 0x10, 0x53, 0x01, 0x60, 0x10, 0x0f, 0x1e,
+ 0x09, 0x00, 0x60, 0x04, 0x10, 0x67, 0x04, 0x01, 0x1e, 0x10, 0x04, 0x1e, 0x0b, 0x04, 0x6a, 0x0f,
+ 0x10, 0x6e, 0x00, 0x10, 0x6a, 0x01, 0x10, 0xfc, 0x0f, 0x11, 0x45, 0x01, 0x90, 0x06, 0x00, 0x10,
+ 0x00, 0x00, 0x90, 0x07, 0x03, 0x00, 0x00, 0x00, 0x1e, 0x06, 0x06, 0x07, 0x6c, 0x0c, 0x90, 0x0d,
+ 0x00, 0x00, 0x00, 0x00, 0xfc, 0x0c, 0x0d, 0xa4, 0x01, 0x90, 0x02, 0x02, 0x10, 0x00, 0x00, 0xa2,
+ 0x1e, 0x03, 0x02, 0x94, 0x02, 0x00, 0xa5, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14,
+ 0x00, 0xfc, 0x01, 0x11, 0xdf, 0x00, 0xfb, 0xa4, 0x01, 0x90, 0x11, 0x00, 0x00, 0x00, 0x00, 0x90,
+ 0x0f, 0x40, 0x00, 0x00, 0x00, 0xfa, 0x01, 0x0f, 0xed, 0x00, 0x60, 0x0f, 0x01, 0x90, 0x03, 0x00,
+ 0x00, 0x00, 0x00, 0xfe, 0x03, 0x00, 0x00, 0x00, 0x00, 0x05, 0x01, 0x90, 0x02, 0x00, 0x10, 0x00,
+ 0x00, 0x1e, 0x06, 0x02, 0x03, 0x90, 0x02, 0x02, 0x10, 0x00, 0x00, 0xa2, 0x1e, 0x03, 0x02, 0x94,
+ 0x02, 0x00, 0xa5, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14, 0x00, 0x90, 0x02, 0x00,
+ 0x10, 0x00, 0x00, 0x90, 0x03, 0x04, 0x00, 0x00, 0x00, 0x1e, 0x06, 0x02, 0x03, 0x90, 0x02, 0x02,
+ 0x10, 0x00, 0x00, 0xa2, 0x1e, 0x03, 0x02, 0x94, 0x02, 0x00, 0xa5, 0x03, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x14, 0x00, 0x90, 0x10, 0x00, 0x01, 0x00, 0x00, 0xfa, 0x0f, 0x10, 0x53, 0x01,
+ 0x60, 0x10, 0x0f, 0x1e, 0x09, 0x00, 0x1e, 0x10, 0x10, 0x1e, 0x0a, 0x10, 0x6a, 0x0f, 0x10, 0x6e,
+ 0x00, 0x10, 0x6a, 0x01, 0x10, 0xfc, 0x0f, 0x11, 0x45, 0x01, 0x90, 0x06, 0x00, 0x10, 0x00, 0x00,
+ 0x90, 0x07, 0x03, 0x00, 0x00, 0x00, 0x1e, 0x06, 0x06, 0x07, 0x6c, 0x0c, 0x90, 0x0d, 0x00, 0x00,
+ 0x00, 0x00, 0xfc, 0x0c, 0x0d, 0xa4, 0x01, 0x90, 0x02, 0x02, 0x10, 0x00, 0x00, 0xa2, 0x1e, 0x03,
+ 0x02, 0x94, 0x02, 0x00, 0xa5, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14, 0x00, 0xfc,
+ 0x01, 0x11, 0xdf, 0x00, 0xaf,
+};
+
+const unsigned char WriteIDmem_2[266] = {
+ 0x91, 0x00, 0x91, 0x01, 0x90, 0x11, 0x00, 0x00, 0x00, 0x00, 0x90, 0x0f, 0x20, 0x00, 0x00, 0x00,
+ 0xfa, 0x01, 0x0f, 0x18, 0x00, 0x60, 0x0f, 0x01, 0x90, 0x02, 0x02, 0x10, 0x00, 0x00, 0xa2, 0x1e,
+ 0x03, 0x02, 0x94, 0x02, 0x00, 0xa5, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14, 0x00,
+ 0x90, 0x06, 0x00, 0x10, 0x00, 0x00, 0x90, 0x07, 0x08, 0x00, 0x00, 0x00, 0x1e, 0x06, 0x06, 0x07,
+ 0x90, 0x06, 0xff, 0x00, 0x00, 0x00, 0x1e, 0x06, 0x00, 0x06, 0x90, 0x02, 0x02, 0x10, 0x00, 0x00,
+ 0xa2, 0x1e, 0x03, 0x02, 0x94, 0x02, 0x00, 0xa5, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x14, 0x00, 0x90, 0x06, 0x00, 0x10, 0x00, 0x00, 0x90, 0x07, 0x00, 0x00, 0x00, 0x00, 0x1e, 0x06,
+ 0x06, 0x07, 0x90, 0x02, 0x02, 0x10, 0x00, 0x00, 0xa2, 0x1e, 0x03, 0x02, 0x94, 0x02, 0x00, 0xa5,
+ 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14, 0x00, 0x90, 0x06, 0x00, 0x10, 0x00, 0x00,
+ 0x90, 0x07, 0x02, 0x00, 0x00, 0x00, 0x1e, 0x06, 0x06, 0x07, 0x90, 0x10, 0x00, 0x01, 0x00, 0x00,
+ 0xfa, 0x0f, 0x10, 0xa8, 0x00, 0x60, 0x10, 0x0f, 0x1e, 0x09, 0x00, 0x1e, 0x10, 0x10, 0x1e, 0x0a,
+ 0x10, 0x6a, 0x0f, 0x10, 0x6e, 0x00, 0x10, 0x6a, 0x01, 0x10, 0xfc, 0x0f, 0x11, 0x9a, 0x00, 0x6c,
+ 0x0c, 0x90, 0x0d, 0x00, 0x00, 0x00, 0x00, 0xfc, 0x0c, 0x0d, 0xfa, 0x00, 0x90, 0x02, 0x02, 0x10,
+ 0x00, 0x00, 0xa2, 0x1e, 0x03, 0x02, 0x94, 0x02, 0x00, 0xa5, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x14, 0x00, 0x90, 0x06, 0x00, 0x10, 0x00, 0x00, 0x90, 0x07, 0x00, 0x00, 0x00, 0x00,
+ 0x1e, 0x06, 0x06, 0x07, 0xfc, 0x01, 0x11, 0x0a, 0x00, 0x5a, 0x90, 0x06, 0x00, 0x10, 0x00, 0x00,
+ 0x90, 0x07, 0x00, 0x00, 0x00, 0x00, 0x1e, 0x06, 0x06, 0x07,
+};
+
+const unsigned char WriteIDmem_3[421] = {
+ 0x91, 0x00, 0x91, 0x01, 0x90, 0x03, 0x02, 0x00, 0x00, 0x00, 0xfe, 0x03, 0x02, 0x00, 0x00, 0x00,
+ 0x1d, 0x00, 0xfe, 0x03, 0x01, 0x00, 0x00, 0x00, 0xd9, 0x00, 0xfb, 0xa4, 0x01, 0x90, 0x11, 0x00,
+ 0x00, 0x00, 0x00, 0x90, 0x0f, 0x40, 0x00, 0x00, 0x00, 0xfa, 0x01, 0x0f, 0xed, 0x00, 0x60, 0x0f,
+ 0x01, 0x90, 0x02, 0x06, 0x10, 0x00, 0x00, 0xa2, 0x1e, 0x03, 0x02, 0x94, 0x02, 0x00, 0xa5, 0x03,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14, 0x00, 0x90, 0x02, 0x00, 0x10, 0x00, 0x00, 0x90,
+ 0x03, 0x0f, 0x00, 0x00, 0x00, 0x1e, 0x06, 0x02, 0x03, 0x90, 0x02, 0x06, 0x10, 0x00, 0x00, 0xa2,
+ 0x1e, 0x03, 0x02, 0x94, 0x02, 0x00, 0xa5, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14,
+ 0x00, 0x90, 0x10, 0x00, 0x01, 0x00, 0x00, 0xfa, 0x0f, 0x10, 0x53, 0x01, 0x60, 0x10, 0x0f, 0x1e,
+ 0x09, 0x00, 0x60, 0x04, 0x10, 0x67, 0x04, 0x01, 0x1e, 0x10, 0x04, 0x1e, 0x0b, 0x04, 0x6a, 0x0f,
+ 0x10, 0x6e, 0x00, 0x10, 0x6a, 0x01, 0x10, 0xfc, 0x0f, 0x11, 0x45, 0x01, 0x90, 0x06, 0x00, 0x10,
+ 0x00, 0x00, 0x90, 0x07, 0x05, 0x00, 0x00, 0x00, 0x1e, 0x06, 0x06, 0x07, 0x6c, 0x0c, 0x90, 0x0d,
+ 0x00, 0x00, 0x00, 0x00, 0xfc, 0x0c, 0x0d, 0xa4, 0x01, 0x90, 0x02, 0x06, 0x10, 0x00, 0x00, 0xa2,
+ 0x1e, 0x03, 0x02, 0x94, 0x02, 0x00, 0xa5, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14,
+ 0x00, 0xfc, 0x01, 0x11, 0xdf, 0x00, 0xfb, 0xa4, 0x01, 0x90, 0x11, 0x00, 0x00, 0x00, 0x00, 0x90,
+ 0x0f, 0x40, 0x00, 0x00, 0x00, 0xfa, 0x01, 0x0f, 0xed, 0x00, 0x60, 0x0f, 0x01, 0x90, 0x03, 0x1f,
+ 0x00, 0x00, 0x00, 0xfe, 0x03, 0x00, 0x00, 0x00, 0x00, 0x05, 0x01, 0x90, 0x02, 0x00, 0x10, 0x00,
+ 0x00, 0x1e, 0x06, 0x02, 0x03, 0x90, 0x02, 0x06, 0x10, 0x00, 0x00, 0xa2, 0x1e, 0x03, 0x02, 0x94,
+ 0x02, 0x00, 0xa5, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14, 0x00, 0x90, 0x02, 0x00,
+ 0x10, 0x00, 0x00, 0x90, 0x03, 0x0f, 0x00, 0x00, 0x00, 0x1e, 0x06, 0x02, 0x03, 0x90, 0x02, 0x06,
+ 0x10, 0x00, 0x00, 0xa2, 0x1e, 0x03, 0x02, 0x94, 0x02, 0x00, 0xa5, 0x03, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x14, 0x00, 0x90, 0x10, 0x00, 0x01, 0x00, 0x00, 0xfa, 0x0f, 0x10, 0x53, 0x01,
+ 0x60, 0x10, 0x0f, 0x1e, 0x09, 0x00, 0x1e, 0x10, 0x10, 0x1e, 0x0a, 0x10, 0x6a, 0x0f, 0x10, 0x6e,
+ 0x00, 0x10, 0x6a, 0x01, 0x10, 0xfc, 0x0f, 0x11, 0x45, 0x01, 0x90, 0x06, 0x00, 0x10, 0x00, 0x00,
+ 0x90, 0x07, 0x15, 0x00, 0x00, 0x00, 0x1e, 0x06, 0x06, 0x07, 0x6c, 0x0c, 0x90, 0x0d, 0x00, 0x00,
+ 0x00, 0x00, 0xfc, 0x0c, 0x0d, 0xa4, 0x01, 0x90, 0x02, 0x06, 0x10, 0x00, 0x00, 0xa2, 0x1e, 0x03,
+ 0x02, 0x94, 0x02, 0x00, 0xa5, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14, 0x00, 0xfc,
+ 0x01, 0x11, 0xdf, 0x00, 0xaf,
+};
+
+const unsigned char WriteIDmem_4[266] = {
+ 0x91, 0x00, 0x91, 0x01, 0x90, 0x11, 0x00, 0x00, 0x00, 0x00, 0x90, 0x0f, 0x00, 0x02, 0x00, 0x00,
+ 0xfa, 0x01, 0x0f, 0x18, 0x00, 0x60, 0x0f, 0x01, 0x90, 0x02, 0x06, 0x10, 0x00, 0x00, 0xa2, 0x1e,
+ 0x03, 0x02, 0x94, 0x02, 0x00, 0xa5, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14, 0x00,
+ 0x90, 0x06, 0x00, 0x10, 0x00, 0x00, 0x90, 0x07, 0x08, 0x00, 0x00, 0x00, 0x1e, 0x06, 0x06, 0x07,
+ 0x90, 0x06, 0xff, 0x00, 0x00, 0x00, 0x1e, 0x06, 0x00, 0x06, 0x90, 0x02, 0x06, 0x10, 0x00, 0x00,
+ 0xa2, 0x1e, 0x03, 0x02, 0x94, 0x02, 0x00, 0xa5, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x14, 0x00, 0x90, 0x06, 0x00, 0x10, 0x00, 0x00, 0x90, 0x07, 0x00, 0x00, 0x00, 0x00, 0x1e, 0x06,
+ 0x06, 0x07, 0x90, 0x02, 0x06, 0x10, 0x00, 0x00, 0xa2, 0x1e, 0x03, 0x02, 0x94, 0x02, 0x00, 0xa5,
+ 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14, 0x00, 0x90, 0x06, 0x00, 0x10, 0x00, 0x00,
+ 0x90, 0x07, 0x02, 0x00, 0x00, 0x00, 0x1e, 0x06, 0x06, 0x07, 0x90, 0x10, 0x00, 0x01, 0x00, 0x00,
+ 0xfa, 0x0f, 0x10, 0xa8, 0x00, 0x60, 0x10, 0x0f, 0x1e, 0x09, 0x00, 0x1e, 0x10, 0x10, 0x1e, 0x0a,
+ 0x10, 0x6a, 0x0f, 0x10, 0x6e, 0x00, 0x10, 0x6a, 0x01, 0x10, 0xfc, 0x0f, 0x11, 0x9a, 0x00, 0x6c,
+ 0x0c, 0x90, 0x0d, 0x00, 0x00, 0x00, 0x00, 0xfc, 0x0c, 0x0d, 0xfa, 0x00, 0x90, 0x02, 0x06, 0x10,
+ 0x00, 0x00, 0xa2, 0x1e, 0x03, 0x02, 0x94, 0x02, 0x00, 0xa5, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x14, 0x00, 0x90, 0x06, 0x00, 0x10, 0x00, 0x00, 0x90, 0x07, 0x00, 0x00, 0x00, 0x00,
+ 0x1e, 0x06, 0x06, 0x07, 0xfc, 0x01, 0x11, 0x0a, 0x00, 0x5a, 0x90, 0x06, 0x00, 0x10, 0x00, 0x00,
+ 0x90, 0x07, 0x00, 0x00, 0x00, 0x00, 0x1e, 0x06, 0x06, 0x07,
+};
+
+const unsigned char WriteIDmem_5[266] = {
+ 0x91, 0x00, 0x91, 0x01, 0x90, 0x11, 0x00, 0x00, 0x00, 0x00, 0x90, 0x0f, 0x20, 0x00, 0x00, 0x00,
+ 0xfa, 0x01, 0x0f, 0x18, 0x00, 0x60, 0x0f, 0x01, 0x90, 0x02, 0x07, 0x10, 0x00, 0x00, 0xa2, 0x1e,
+ 0x03, 0x02, 0x94, 0x02, 0x00, 0xa5, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14, 0x00,
+ 0x90, 0x06, 0x00, 0x10, 0x00, 0x00, 0x90, 0x07, 0x08, 0x00, 0x00, 0x00, 0x1e, 0x06, 0x06, 0x07,
+ 0x90, 0x06, 0xff, 0x00, 0x00, 0x00, 0x1e, 0x06, 0x00, 0x06, 0x90, 0x02, 0x07, 0x10, 0x00, 0x00,
+ 0xa2, 0x1e, 0x03, 0x02, 0x94, 0x02, 0x00, 0xa5, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x14, 0x00, 0x90, 0x06, 0x00, 0x10, 0x00, 0x00, 0x90, 0x07, 0x00, 0x00, 0x00, 0x00, 0x1e, 0x06,
+ 0x06, 0x07, 0x90, 0x02, 0x07, 0x10, 0x00, 0x00, 0xa2, 0x1e, 0x03, 0x02, 0x94, 0x02, 0x00, 0xa5,
+ 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14, 0x00, 0x90, 0x06, 0x00, 0x10, 0x00, 0x00,
+ 0x90, 0x07, 0x02, 0x00, 0x00, 0x00, 0x1e, 0x06, 0x06, 0x07, 0x90, 0x10, 0x00, 0x01, 0x00, 0x00,
+ 0xfa, 0x0f, 0x10, 0xa8, 0x00, 0x60, 0x10, 0x0f, 0x1e, 0x09, 0x00, 0x1e, 0x10, 0x10, 0x1e, 0x0a,
+ 0x10, 0x6a, 0x0f, 0x10, 0x6e, 0x00, 0x10, 0x6a, 0x01, 0x10, 0xfc, 0x0f, 0x11, 0x9a, 0x00, 0x6c,
+ 0x0c, 0x90, 0x0d, 0x00, 0x00, 0x00, 0x00, 0xfc, 0x0c, 0x0d, 0xfa, 0x00, 0x90, 0x02, 0x07, 0x10,
+ 0x00, 0x00, 0xa2, 0x1e, 0x03, 0x02, 0x94, 0x02, 0x00, 0xa5, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x14, 0x00, 0x90, 0x06, 0x00, 0x10, 0x00, 0x00, 0x90, 0x07, 0x00, 0x00, 0x00, 0x00,
+ 0x1e, 0x06, 0x06, 0x07, 0xfc, 0x01, 0x11, 0x0a, 0x00, 0x5a, 0x90, 0x06, 0x00, 0x10, 0x00, 0x00,
+ 0x90, 0x07, 0x00, 0x00, 0x00, 0x00, 0x1e, 0x06, 0x06, 0x07,
+};
+
+const unsigned char ReadIDmem_0[67] = {
+ 0x91, 0x00, 0x91, 0x01, 0x95, 0x90, 0x11, 0x00, 0x00, 0x00, 0x00, 0x90, 0x0f, 0x20, 0x00, 0x00,
+ 0x00, 0xfa, 0x01, 0x0f, 0x19, 0x00, 0x60, 0x0f, 0x01, 0x90, 0x10, 0x00, 0x01, 0x00, 0x00, 0xfa,
+ 0x0f, 0x10, 0x27, 0x00, 0x60, 0x10, 0x0f, 0x1e, 0x09, 0x00, 0x1e, 0x10, 0x10, 0x1e, 0x0c, 0x10,
+ 0x6a, 0x0f, 0x10, 0x6e, 0x00, 0x10, 0x6a, 0x01, 0x10, 0xfc, 0x0f, 0x11, 0x19, 0x00, 0xfc, 0x01,
+ 0x11, 0x0b, 0x00,
+};
+
+const unsigned char ReadIDmem_1[67] = {
+ 0x91, 0x00, 0x91, 0x01, 0x95, 0x90, 0x11, 0x00, 0x00, 0x00, 0x00, 0x90, 0x0f, 0x40, 0x00, 0x00,
+ 0x00, 0xfa, 0x01, 0x0f, 0x19, 0x00, 0x60, 0x0f, 0x01, 0x90, 0x10, 0x00, 0x01, 0x00, 0x00, 0xfa,
+ 0x0f, 0x10, 0x27, 0x00, 0x60, 0x10, 0x0f, 0x1e, 0x09, 0x00, 0x1e, 0x10, 0x10, 0x1e, 0x0c, 0x10,
+ 0x6a, 0x0f, 0x10, 0x6e, 0x00, 0x10, 0x6a, 0x01, 0x10, 0xfc, 0x0f, 0x11, 0x19, 0x00, 0xfc, 0x01,
+ 0x11, 0x0b, 0x00,
+};
+
+const unsigned char ReadIDmem_2[67] = {
+ 0x91, 0x00, 0x91, 0x01, 0x95, 0x90, 0x11, 0x00, 0x00, 0x00, 0x00, 0x90, 0x0f, 0x00, 0x02, 0x00,
+ 0x00, 0xfa, 0x01, 0x0f, 0x19, 0x00, 0x60, 0x0f, 0x01, 0x90, 0x10, 0x00, 0x01, 0x00, 0x00, 0xfa,
+ 0x0f, 0x10, 0x27, 0x00, 0x60, 0x10, 0x0f, 0x1e, 0x09, 0x00, 0x1e, 0x10, 0x10, 0x1e, 0x0c, 0x10,
+ 0x6a, 0x0f, 0x10, 0x6e, 0x00, 0x10, 0x6a, 0x01, 0x10, 0xfc, 0x0f, 0x11, 0x19, 0x00, 0xfc, 0x01,
+ 0x11, 0x0b, 0x00,
+};
+
+const unsigned char WriteCSreg_0[8] = {
+ 0x99, 0x00, 0x99, 0x01, 0x1e, 0x0f, 0x00, 0x01,
+};
+
+const unsigned char ReadCSreg_0[6] = {
+ 0x99, 0x00, 0x1e, 0x0e, 0x00, 0x9f,
+};
+
+const unsigned char WriteMem8_0[20] = {
+ 0x91, 0x00, 0x91, 0x01, 0xad, 0x01, 0x99, 0x03, 0x1e, 0x06, 0x00, 0x03, 0x92, 0x00, 0x01, 0x00,
+ 0x00, 0x00, 0xae, 0x5a,
+};
+
+const unsigned char ReadMem8_0[19] = {
+ 0x91, 0x00, 0x91, 0x01, 0x95, 0xad, 0x01, 0x1e, 0x03, 0x00, 0x9f, 0x92, 0x00, 0x01, 0x00, 0x00,
+ 0x00, 0xae, 0x5a,
+};
+
+const unsigned char ReadSIB_0[7] = {
+ 0x95, 0x9b, 0x00, 0x02, 0x1e, 0x12, 0x00,
+};
+
+
+
+
+static void pickit_updi_script_init(SCRIPT *scr);
+static void pickit_updi_script_init(SCRIPT *scr) {
+ scr->EnterProgMode = EnterProgMode_0;
+ scr->EnterProgModeHvSp = EnterProgModeHvSp_0;
+ scr->EnterProgModeHvSpRst = EnterProgModeHvSpRst_0;
+ scr->EnterProgModeHvUpt = EnterProgModeHvUpt_0;
+ scr->ExitProgMode = ExitProgMode_0;
+ scr->SetSpeed = SetSpeed_0;
+ scr->GetDeviceID = NULL;
+ scr->EraseChip = EraseChip_0;
+ scr->WriteProgmem = NULL;
+ scr->ReadProgmem = NULL;
+ scr->WriteDataEEmem = NULL;
+ scr->ReadDataEEmem = NULL;
+ scr->WriteConfigmem = NULL;
+ scr->ReadConfigmem = ReadConfigmem_0;
+ scr->WriteIDmem = NULL;
+ scr->ReadIDmem = NULL;
+ scr->WriteCSreg = WriteCSreg_0;
+ scr->ReadCSreg = ReadCSreg_0;
+ scr->WriteMem8 = WriteMem8_0;
+ scr->ReadMem8 = ReadMem8_0;
+ scr->ReadSIB = ReadSIB_0;
+
+ scr->EnterProgMode_len = sizeof(EnterProgMode_0);
+ scr->EnterProgModeHvSp_len = sizeof(EnterProgModeHvSp_0);
+ scr->EnterProgModeHvSpRst_len = sizeof(EnterProgModeHvSpRst_0);
+ scr->EnterProgModeHvUpt_len = sizeof(EnterProgModeHvUpt_0);
+ scr->ExitProgMode_len = sizeof(ExitProgMode_0);
+ scr->SetSpeed_len = sizeof(SetSpeed_0);
+ scr->GetDeviceID_len = 0;
+ scr->EraseChip_len = sizeof(EraseChip_0);
+ scr->WriteProgmem_len = 0;
+ scr->ReadProgmem_len = 0;
+ scr->WriteDataEEmem_len = 0;
+ scr->ReadDataEEmem_len = 0;
+ scr->WriteConfigmem_len = 0;
+ scr->ReadConfigmem_len = sizeof(ReadConfigmem_0);
+ scr->WriteIDmem_len = 0;
+ scr->ReadIDmem_len = 0;
+ scr->WriteCSreg_len = sizeof(WriteCSreg_0);
+ scr->ReadCSreg_len = sizeof(ReadCSreg_0);
+ scr->WriteMem8_len = sizeof(WriteMem8_0);
+ scr->ReadMem8_len = sizeof(ReadMem8_0);
+ scr->ReadSIB_len = sizeof(ReadSIB_0);
+}
+
+
+const char * const pickit5_updi_chip_lut[] = {
+ "ATtiny416auto", "ATmega1608", "ATmega1609", "ATmega3208", "ATmega3209", "ATmega4808", "ATmega4809", "ATmega808",
+ "ATmega809", "ATtiny1604", "ATtiny1606", "ATtiny1607", "ATtiny1614", "ATtiny1616", "ATtiny1617", "ATtiny1624",
+ "ATtiny1626", "ATtiny1627", "ATtiny202", "ATtiny204", "ATtiny212", "ATtiny214", "ATtiny3216", "ATtiny3217",
+ "ATtiny3224", "ATtiny3226", "ATtiny3227", "ATtiny402", "ATtiny404", "ATtiny406", "ATtiny412", "ATtiny414",
+ "ATtiny416", "ATtiny417", "ATtiny424", "ATtiny426", "ATtiny427", "ATtiny804", "ATtiny806", "ATtiny807",
+ "ATtiny814", "ATtiny816", "ATtiny817", "ATtiny824", "ATtiny826", "ATtiny827", "AVR128DA28", "AVR128DA32",
+ "AVR128DA48", "AVR128DA64", "AVR128DB28", "AVR128DB32", "AVR128DB48", "AVR128DB64", "AVR16DD14", "AVR16DD20",
+ "AVR16DD28", "AVR16DD32", "AVR32DA28", "AVR32DA32", "AVR32DA48", "AVR32DB28", "AVR32DB32", "AVR32DB48",
+ "AVR32DD14", "AVR32DD20", "AVR32DD28", "AVR32DD32", "AVR64DA28", "AVR64DA32", "AVR64DA48", "AVR64DA64",
+ "AVR64DB28", "AVR64DB32", "AVR64DB48", "AVR64DB64", "AVR64DD14", "AVR64DD20", "AVR64DD28", "AVR64DD32",
+ "AVR64EA28", "AVR64EA32", "AVR64EA48", "AVR16DA28", "AVR16DA32", "AVR16DA48", "AVR16DB28", "AVR16DB32",
+ "AVR16DB48", "AVR16DU14", "AVR16DU20", "AVR16DU28", "AVR16DU32", "AVR32DU14", "AVR32DU20", "AVR32DU28",
+ "AVR32DU32", "AVR64DU28", "AVR64DU32", "AVR16EA28", "AVR16EA32", "AVR16EA48", "AVR32EA28", "AVR32EA32",
+ "AVR32EA48", "AVR8EA28", "AVR8EA32", "AVR16EB14", "AVR16EB20", "AVR16EB28", "AVR16EB32", "AVR32EB28",
+ "AVR32EB32", "AVR64EC48", "AVR32SD32", "AVR64SD48",
+};
+
+
+const unsigned char * get_devid_script_by_nvm_ver(unsigned char version) {
+ if (version >= '0') version -= '0'; // allow chars
+ if (version > 9) return NULL; // Not a valid number
+ if (version <= 3) // tiny, mega, DA, DB, DD, EA
+ return GetDeviceID_0;
+ else // DU, EB
+ return GetDeviceID_1;
+}
+
+int get_pickit_updi_script(SCRIPT *scr, const char* partdesc) {
+ if ((scr == NULL) || (partdesc == NULL))
+ return -1;
+
+ int namepos = -1;
+ for (int i = 0; i < 116; i++) {
+ if (strncmp(pickit5_updi_chip_lut[i], partdesc, 10) == 0) {
+ namepos = i;
+ break;
+ }
+ }
+ if (namepos == -1) {
+ return -2;
+ }
+
+ pickit_updi_script_init(scr); // load common functions
+
+ switch (namepos) {
+ case 0: /* ATtiny416auto */
+ case 1: /* ATmega1608 */
+ case 2: /* ATmega1609 */
+ case 7: /* ATmega808 */
+ case 8: /* ATmega809 */
+ case 9: /* ATtiny1604 */
+ case 10: /* ATtiny1606 */
+ case 11: /* ATtiny1607 */
+ case 12: /* ATtiny1614 */
+ case 13: /* ATtiny1616 */
+ case 14: /* ATtiny1617 */
+ case 15: /* ATtiny1624 */
+ case 16: /* ATtiny1626 */
+ case 17: /* ATtiny1627 */
+ case 18: /* ATtiny202 */
+ case 19: /* ATtiny204 */
+ case 20: /* ATtiny212 */
+ case 21: /* ATtiny214 */
+ case 27: /* ATtiny402 */
+ case 28: /* ATtiny404 */
+ case 29: /* ATtiny406 */
+ case 30: /* ATtiny412 */
+ case 31: /* ATtiny414 */
+ case 32: /* ATtiny416 */
+ case 33: /* ATtiny417 */
+ case 34: /* ATtiny424 */
+ case 35: /* ATtiny426 */
+ case 36: /* ATtiny427 */
+ case 37: /* ATtiny804 */
+ case 38: /* ATtiny806 */
+ case 39: /* ATtiny807 */
+ case 40: /* ATtiny814 */
+ case 41: /* ATtiny816 */
+ case 42: /* ATtiny817 */
+ case 43: /* ATtiny824 */
+ case 44: /* ATtiny826 */
+ case 45: /* ATtiny827 */
+ scr->GetDeviceID = GetDeviceID_0;
+ scr->GetDeviceID_len = sizeof(GetDeviceID_0);
+ scr->WriteProgmem = WriteProgmem_0;
+ scr->WriteProgmem_len = sizeof(WriteProgmem_0);
+ scr->ReadProgmem = ReadProgmem_0;
+ scr->ReadProgmem_len = sizeof(ReadProgmem_0);
+ scr->WriteDataEEmem = WriteDataEEmem_0;
+ scr->WriteDataEEmem_len = sizeof(WriteDataEEmem_0);
+ scr->ReadDataEEmem = ReadDataEEmem_0;
+ scr->ReadDataEEmem_len = sizeof(ReadDataEEmem_0);
+ scr->WriteConfigmem = WriteConfigmem_0;
+ scr->WriteConfigmem_len = sizeof(WriteConfigmem_0);
+ scr->WriteIDmem = WriteIDmem_0;
+ scr->WriteIDmem_len = sizeof(WriteIDmem_0);
+ scr->ReadIDmem = ReadIDmem_0;
+ scr->ReadIDmem_len = sizeof(ReadIDmem_0);
+ break;
+ case 3: /* ATmega3208 */
+ case 4: /* ATmega3209 */
+ case 5: /* ATmega4808 */
+ case 6: /* ATmega4809 */
+ case 22: /* ATtiny3216 */
+ case 23: /* ATtiny3217 */
+ scr->GetDeviceID = GetDeviceID_0;
+ scr->GetDeviceID_len = sizeof(GetDeviceID_0);
+ scr->WriteProgmem = WriteProgmem_1;
+ scr->WriteProgmem_len = sizeof(WriteProgmem_1);
+ scr->ReadProgmem = ReadProgmem_1;
+ scr->ReadProgmem_len = sizeof(ReadProgmem_1);
+ scr->WriteDataEEmem = WriteDataEEmem_1;
+ scr->WriteDataEEmem_len = sizeof(WriteDataEEmem_1);
+ scr->ReadDataEEmem = ReadDataEEmem_1;
+ scr->ReadDataEEmem_len = sizeof(ReadDataEEmem_1);
+ scr->WriteConfigmem = WriteConfigmem_0;
+ scr->WriteConfigmem_len = sizeof(WriteConfigmem_0);
+ scr->WriteIDmem = WriteIDmem_1;
+ scr->WriteIDmem_len = sizeof(WriteIDmem_1);
+ scr->ReadIDmem = ReadIDmem_1;
+ scr->ReadIDmem_len = sizeof(ReadIDmem_1);
+ break;
+ case 24: /* ATtiny3224 */
+ case 25: /* ATtiny3226 */
+ case 26: /* ATtiny3227 */
+ scr->GetDeviceID = GetDeviceID_0;
+ scr->GetDeviceID_len = sizeof(GetDeviceID_0);
+ scr->WriteProgmem = WriteProgmem_1;
+ scr->WriteProgmem_len = sizeof(WriteProgmem_1);
+ scr->ReadProgmem = ReadProgmem_1;
+ scr->ReadProgmem_len = sizeof(ReadProgmem_1);
+ scr->WriteDataEEmem = WriteDataEEmem_1;
+ scr->WriteDataEEmem_len = sizeof(WriteDataEEmem_1);
+ scr->ReadDataEEmem = ReadDataEEmem_1;
+ scr->ReadDataEEmem_len = sizeof(ReadDataEEmem_1);
+ scr->WriteConfigmem = WriteConfigmem_0;
+ scr->WriteConfigmem_len = sizeof(WriteConfigmem_0);
+ scr->WriteIDmem = WriteIDmem_0;
+ scr->WriteIDmem_len = sizeof(WriteIDmem_0);
+ scr->ReadIDmem = ReadIDmem_0;
+ scr->ReadIDmem_len = sizeof(ReadIDmem_0);
+ break;
+ case 46: /* AVR128DA28 */
+ case 47: /* AVR128DA32 */
+ case 48: /* AVR128DA48 */
+ case 49: /* AVR128DA64 */
+ case 50: /* AVR128DB28 */
+ case 51: /* AVR128DB32 */
+ case 52: /* AVR128DB48 */
+ case 53: /* AVR128DB64 */
+ case 54: /* AVR16DD14 */
+ case 55: /* AVR16DD20 */
+ case 56: /* AVR16DD28 */
+ case 57: /* AVR16DD32 */
+ case 58: /* AVR32DA28 */
+ case 59: /* AVR32DA32 */
+ case 60: /* AVR32DA48 */
+ case 61: /* AVR32DB28 */
+ case 62: /* AVR32DB32 */
+ case 63: /* AVR32DB48 */
+ case 64: /* AVR32DD14 */
+ case 65: /* AVR32DD20 */
+ case 66: /* AVR32DD28 */
+ case 67: /* AVR32DD32 */
+ case 68: /* AVR64DA28 */
+ case 69: /* AVR64DA32 */
+ case 70: /* AVR64DA48 */
+ case 71: /* AVR64DA64 */
+ case 72: /* AVR64DB28 */
+ case 73: /* AVR64DB32 */
+ case 74: /* AVR64DB48 */
+ case 75: /* AVR64DB64 */
+ case 76: /* AVR64DD14 */
+ case 77: /* AVR64DD20 */
+ case 78: /* AVR64DD28 */
+ case 79: /* AVR64DD32 */
+ case 83: /* AVR16DA28 */
+ case 84: /* AVR16DA32 */
+ case 85: /* AVR16DA48 */
+ case 86: /* AVR16DB28 */
+ case 87: /* AVR16DB32 */
+ case 88: /* AVR16DB48 */
+ scr->GetDeviceID = GetDeviceID_0;
+ scr->GetDeviceID_len = sizeof(GetDeviceID_0);
+ scr->WriteProgmem = WriteProgmem_2;
+ scr->WriteProgmem_len = sizeof(WriteProgmem_2);
+ scr->ReadProgmem = ReadProgmem_2;
+ scr->ReadProgmem_len = sizeof(ReadProgmem_2);
+ scr->WriteDataEEmem = WriteDataEEmem_2;
+ scr->WriteDataEEmem_len = sizeof(WriteDataEEmem_2);
+ scr->ReadDataEEmem = ReadDataEEmem_2;
+ scr->ReadDataEEmem_len = sizeof(ReadDataEEmem_2);
+ scr->WriteConfigmem = WriteConfigmem_1;
+ scr->WriteConfigmem_len = sizeof(WriteConfigmem_1);
+ scr->WriteIDmem = WriteIDmem_2;
+ scr->WriteIDmem_len = sizeof(WriteIDmem_2);
+ scr->ReadIDmem = ReadIDmem_0;
+ scr->ReadIDmem_len = sizeof(ReadIDmem_0);
+ break;
+ case 80: /* AVR64EA28 */
+ case 81: /* AVR64EA32 */
+ case 82: /* AVR64EA48 */
+ scr->GetDeviceID = GetDeviceID_0;
+ scr->GetDeviceID_len = sizeof(GetDeviceID_0);
+ scr->WriteProgmem = WriteProgmem_3;
+ scr->WriteProgmem_len = sizeof(WriteProgmem_3);
+ scr->ReadProgmem = ReadProgmem_1;
+ scr->ReadProgmem_len = sizeof(ReadProgmem_1);
+ scr->WriteDataEEmem = WriteDataEEmem_3;
+ scr->WriteDataEEmem_len = sizeof(WriteDataEEmem_3);
+ scr->ReadDataEEmem = ReadDataEEmem_3;
+ scr->ReadDataEEmem_len = sizeof(ReadDataEEmem_3);
+ scr->WriteConfigmem = WriteConfigmem_2;
+ scr->WriteConfigmem_len = sizeof(WriteConfigmem_2);
+ scr->WriteIDmem = WriteIDmem_3;
+ scr->WriteIDmem_len = sizeof(WriteIDmem_3);
+ scr->ReadIDmem = ReadIDmem_1;
+ scr->ReadIDmem_len = sizeof(ReadIDmem_1);
+ break;
+ case 89: /* AVR16DU14 */
+ case 90: /* AVR16DU20 */
+ case 91: /* AVR16DU28 */
+ case 92: /* AVR16DU32 */
+ case 93: /* AVR32DU14 */
+ case 94: /* AVR32DU20 */
+ case 95: /* AVR32DU28 */
+ case 96: /* AVR32DU32 */
+ case 97: /* AVR64DU28 */
+ case 98: /* AVR64DU32 */
+ scr->GetDeviceID = GetDeviceID_1;
+ scr->GetDeviceID_len = sizeof(GetDeviceID_1);
+ scr->WriteProgmem = WriteProgmem_4;
+ scr->WriteProgmem_len = sizeof(WriteProgmem_4);
+ scr->ReadProgmem = ReadProgmem_2;
+ scr->ReadProgmem_len = sizeof(ReadProgmem_2);
+ scr->WriteDataEEmem = WriteDataEEmem_4;
+ scr->WriteDataEEmem_len = sizeof(WriteDataEEmem_4);
+ scr->ReadDataEEmem = ReadDataEEmem_2;
+ scr->ReadDataEEmem_len = sizeof(ReadDataEEmem_2);
+ scr->WriteConfigmem = WriteConfigmem_3;
+ scr->WriteConfigmem_len = sizeof(WriteConfigmem_3);
+ scr->WriteIDmem = WriteIDmem_4;
+ scr->WriteIDmem_len = sizeof(WriteIDmem_4);
+ scr->ReadIDmem = ReadIDmem_2;
+ scr->ReadIDmem_len = sizeof(ReadIDmem_2);
+ break;
+ case 99: /* AVR16EA28 */
+ case 100: /* AVR16EA32 */
+ case 101: /* AVR16EA48 */
+ case 102: /* AVR32EA28 */
+ case 103: /* AVR32EA32 */
+ case 104: /* AVR32EA48 */
+ case 105: /* AVR8EA28 */
+ case 106: /* AVR8EA32 */
+ scr->GetDeviceID = GetDeviceID_0;
+ scr->GetDeviceID_len = sizeof(GetDeviceID_0);
+ scr->WriteProgmem = WriteProgmem_5;
+ scr->WriteProgmem_len = sizeof(WriteProgmem_5);
+ scr->ReadProgmem = ReadProgmem_0;
+ scr->ReadProgmem_len = sizeof(ReadProgmem_0);
+ scr->WriteDataEEmem = WriteDataEEmem_3;
+ scr->WriteDataEEmem_len = sizeof(WriteDataEEmem_3);
+ scr->ReadDataEEmem = ReadDataEEmem_3;
+ scr->ReadDataEEmem_len = sizeof(ReadDataEEmem_3);
+ scr->WriteConfigmem = WriteConfigmem_2;
+ scr->WriteConfigmem_len = sizeof(WriteConfigmem_2);
+ scr->WriteIDmem = WriteIDmem_3;
+ scr->WriteIDmem_len = sizeof(WriteIDmem_3);
+ scr->ReadIDmem = ReadIDmem_1;
+ scr->ReadIDmem_len = sizeof(ReadIDmem_1);
+ break;
+ case 107: /* AVR16EB14 */
+ case 108: /* AVR16EB20 */
+ case 109: /* AVR16EB28 */
+ case 110: /* AVR16EB32 */
+ case 111: /* AVR32EB28 */
+ case 112: /* AVR32EB32 */
+ scr->GetDeviceID = GetDeviceID_1;
+ scr->GetDeviceID_len = sizeof(GetDeviceID_1);
+ scr->WriteProgmem = WriteProgmem_5;
+ scr->WriteProgmem_len = sizeof(WriteProgmem_5);
+ scr->ReadProgmem = ReadProgmem_0;
+ scr->ReadProgmem_len = sizeof(ReadProgmem_0);
+ scr->WriteDataEEmem = WriteDataEEmem_3;
+ scr->WriteDataEEmem_len = sizeof(WriteDataEEmem_3);
+ scr->ReadDataEEmem = ReadDataEEmem_3;
+ scr->ReadDataEEmem_len = sizeof(ReadDataEEmem_3);
+ scr->WriteConfigmem = WriteConfigmem_2;
+ scr->WriteConfigmem_len = sizeof(WriteConfigmem_2);
+ scr->WriteIDmem = WriteIDmem_3;
+ scr->WriteIDmem_len = sizeof(WriteIDmem_3);
+ scr->ReadIDmem = ReadIDmem_1;
+ scr->ReadIDmem_len = sizeof(ReadIDmem_1);
+ break;
+ case 113: /* AVR64EC48 */
+ scr->GetDeviceID = GetDeviceID_1;
+ scr->GetDeviceID_len = sizeof(GetDeviceID_1);
+ scr->WriteProgmem = WriteProgmem_3;
+ scr->WriteProgmem_len = sizeof(WriteProgmem_3);
+ scr->ReadProgmem = ReadProgmem_1;
+ scr->ReadProgmem_len = sizeof(ReadProgmem_1);
+ scr->WriteDataEEmem = WriteDataEEmem_3;
+ scr->WriteDataEEmem_len = sizeof(WriteDataEEmem_3);
+ scr->ReadDataEEmem = ReadDataEEmem_3;
+ scr->ReadDataEEmem_len = sizeof(ReadDataEEmem_3);
+ scr->WriteConfigmem = WriteConfigmem_2;
+ scr->WriteConfigmem_len = sizeof(WriteConfigmem_2);
+ scr->WriteIDmem = WriteIDmem_3;
+ scr->WriteIDmem_len = sizeof(WriteIDmem_3);
+ scr->ReadIDmem = ReadIDmem_1;
+ scr->ReadIDmem_len = sizeof(ReadIDmem_1);
+ break;
+ case 114: /* AVR32SD32 */
+ case 115: /* AVR64SD48 */
+ scr->GetDeviceID = GetDeviceID_1;
+ scr->GetDeviceID_len = sizeof(GetDeviceID_1);
+ scr->WriteProgmem = WriteProgmem_6;
+ scr->WriteProgmem_len = sizeof(WriteProgmem_6);
+ scr->ReadProgmem = ReadProgmem_2;
+ scr->ReadProgmem_len = sizeof(ReadProgmem_2);
+ scr->WriteDataEEmem = WriteDataEEmem_5;
+ scr->WriteDataEEmem_len = sizeof(WriteDataEEmem_5);
+ scr->ReadDataEEmem = ReadDataEEmem_2;
+ scr->ReadDataEEmem_len = sizeof(ReadDataEEmem_2);
+ scr->WriteConfigmem = WriteConfigmem_4;
+ scr->WriteConfigmem_len = sizeof(WriteConfigmem_4);
+ scr->WriteIDmem = WriteIDmem_5;
+ scr->WriteIDmem_len = sizeof(WriteIDmem_5);
+ scr->ReadIDmem = ReadIDmem_0;
+ scr->ReadIDmem_len = sizeof(ReadIDmem_0);
+ break;
+ }
+ return 0;
+}
\ No newline at end of file
diff --git a/src/usbdevs.h b/src/usbdevs.h
index 6fc6b773d..7213badd0 100644
--- a/src/usbdevs.h
+++ b/src/usbdevs.h
@@ -40,6 +40,7 @@
#define USB_DEVICE_PICKIT4_AVR_MODE 0x2177
#define USB_DEVICE_PICKIT4_PIC_MODE 0x9012
#define USB_DEVICE_PICKIT4_PIC_MODE_BL 0x9017 // PICkit4 in bootloader mode
+#define USB_DEVICE_PICKIT5 0x9036
#define USB_DEVICE_SNAP_AVR_MODE 0x2180
#define USB_DEVICE_SNAP_PIC_MODE 0x9018
#define USB_DEVICE_SNAP_PIC_MODE_BL 0x9019 // SNAP in bootloader mode
diff --git a/tools/scripts_decoder.py b/tools/scripts_decoder.py
new file mode 100644
index 000000000..83c357465
--- /dev/null
+++ b/tools/scripts_decoder.py
@@ -0,0 +1,675 @@
+#!/usr/bin/env python3
+# -*- coding: utf-8 -*-
+
+#
+# avrdude - A Downloader/Uploader for AVR device programmers
+# Copyright (C) 2024 MX682X
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see .
+#
+
+# this is a small python sketch that tries to find the PICkit5_TP folder
+# created by MPLAB X that contains the scripts.xml file.
+# Works on Windows and Linux (MacOS untested), as long as the default installation
+# folder was not changed. If it was changed, and the program is unable to locate
+# the scripts.xml file, you should be promted to enter a path. You can
+# either provide the path to the file, or to the directory providing the file.
+#
+# This file contains some functions that were used in initial develeopment
+# but are not needed anymore. However, they might provide useful, thus they
+# can be enabled by setting "user_input" to 1.
+#
+# The idea behind this program is to extract the sub-programs defined in the
+# script.xml. The original file has a size of about 300MB, containing a lot of
+# redundand information as well as sub-programs for chips avrdude doesn't
+# support, like ARM MCUs.
+# This python scripts iterates through all functions, removing identical ones,
+# and indexes those. The index is then used to connect the MCUs with those functions
+# so that the correct array pointers can be loaded.
+# Warning: If you run this python program, the previously generated files will be
+# overwritten without warning.
+#
+# As the XML file is fairly large, a machine with at least 16GB RAM is recommended
+
+import os, fnmatch, mmap
+from pathlib import Path
+from xml.etree import ElementTree as ET
+
+user_input = 0
+
+# The list of functions, as a Python Dictionary, that will be used by avr-dude
+# The complete list of available functions can be found below
+c_dict = {
+ "EnterProgMode" : [],
+ "EnterProgModeHvSp" : [], # High Voltage Pulse on UPDI line
+ "EnterProgModeHvSpRst" : [], # High Voltage Pulse on Reset Pin
+ "EnterProgModeHvUpt" : [],
+ "ExitProgMode" : [],
+ "SetSpeed" : [],
+ "GetDeviceID" : [],
+ "EraseChip" : [],
+ "WriteProgmem" : [],
+ "ReadProgmem" : [],
+ "WriteDataEEmem" : [],
+ "ReadDataEEmem" : [],
+ "WriteCSreg" : [],
+ "ReadCSreg" : [],
+ "WriteMem8" : [],
+ "ReadMem8" : [],
+ "WriteConfigmem" : [],
+ "ReadConfigmem" : [],
+ "WriteIDmem" : [],
+ "ReadIDmem" : [],
+ "ReadSIB" : [],
+}
+
+# List of MCUs that should not end up in the lookup-table,
+# preferably only those that are known not be released in the future
+mcu_blacklist = [
+ "AVR16DV14", "AVR16DV20"
+]
+
+# A complete list of Functions defined in the scripts.xml
+# This string was used to generate an intermediate python file
+dict_header = \
+'''
+func_dict = {
+ "EnterProgMode" : [],
+ "EnterProgModeHvSp" : [],
+ "EnterProgModeHvSpRst" : [],
+ "EnterProgModeHvUpt" : [],
+ "ExitProgMode" : [],
+ "SetSpeed" : [],
+ "GetDeviceID" : [],
+ "EraseChip" : [],
+ "WriteProgmem" : [],
+ "ReadProgmem" : [],
+ "WriteDataEEmem" : [],
+ "ReadDataEEmem" : [],
+ "WriteConfigmem" : [],
+ "WriteConfigmemFuse" : [],
+ "WriteConfigmemLock" : [],
+ "ReadConfigmem" : [],
+ "ReadConfigmemFuse" : [],
+ "ReadConfigmemLock" : [],
+ "WriteIDmem" : [],
+ "ReadIDmem" : [],
+ "WriteCSreg" : [],
+ "ReadCSreg" : [],
+ "WriteMem8" : [],
+ "WriteMem16" : [],
+ "ReadMem8" : [],
+ "ReadMem16" : [],
+ "ReadSIB" : [],
+ "HoldInReset" : [],
+ "ReleaseFromReset" : [],
+ "EnterDebugMode" : [],
+ "EnterDebugModeHvSp" : [],
+ "EnterDebugModeHvSpRst" : [],
+ "EnterDebugModeHvUpt" : [],
+ "ExitDebugMode" : [],
+ "SetPC" : [],
+ "GetPC" : [],
+ "Run" : [],
+ "Halt" : [],
+ "DebugReset" : [],
+ "GetHaltStatus" : [],
+ "SingleStep" : [],
+ "SetHWBP" : [],
+ "ClearHWBP" : [],
+}\n
+'''
+
+
+import platform
+
+work_dir = os.path.abspath(os.getcwd())
+cache_dir = os.path.join(work_dir, "scripts_cache")
+
+print(work_dir)
+print(cache_dir)
+
+
+# Tries to locate the xml file in a known location
+def find_xml():
+ home_dir = str(Path.home())
+ print("Home Path: {0}".format(home_dir))
+ if home_dir == None:
+ return
+ home_dir = os.path.join(home_dir, ".mchp_packs", "Microchip")
+ home_dir_A = os.path.join(home_dir, "PICkit5_TP")
+ result = []
+ for root, dirs, files in os.walk(home_dir_A):
+ for name in files:
+ if fnmatch.fnmatch(name, "scripts.xml"):
+ result.append(os.path.join(root, name))
+
+ print("List of scripts.xml files:")
+ print(result)
+ return result[-1]
+ # EOF
+
+# extracts only the functions from the scripts.xml that end with "UPDI"
+def cache_xml(file):
+ if file == None:
+ return
+ print("Opening file {0}".format(file))
+ global cache_dir
+ origin_tree = ET.parse(file)
+ origin_root = origin_tree.getroot()
+ work_root = ET.Element("scripts")
+ old_chip_name = ""
+ print("List of UPDI MCUs:")
+ for script in origin_root.findall('script'):
+ function_name = script[0].text # the function name is always on the first place
+ if (function_name.endswith("UPDI")):
+ chip_name = script[1].text
+ if (old_chip_name != chip_name):
+ print(chip_name)
+ old_chip_name = chip_name
+ work_root.append(script) # copy UPDI entries to our working element
+
+
+ work_tree = ET.ElementTree(work_root)
+ work_tree.write(os.path.join(cache_dir, "scripts_updi.xml"))
+ # EOF
+
+
+# generates a python file out of the reduced scripts.xml file
+def decode_xml_cache(xml_path):
+ global cache_dir
+ dict_path = os.path.join(cache_dir, "scripts_dict.py")
+
+ xml_tree = ET.parse(xml_path)
+ xml_root = xml_tree.getroot()
+
+ if (os.path.exists(dict_path)):
+ os.remove(dict_path)
+
+ with open(dict_path, 'w') as dict_file:
+ dict_list = []
+ dict_iterator = -1
+ old_chip_name = ""
+ old_function_name = ""
+ for script in xml_root:
+ function_string = ""
+ function_name = script[0].text
+ chip_name = script[1].text
+ if (old_chip_name != chip_name):
+ if (dict_iterator >= 0):
+ dict_list[dict_iterator] += " },\n" # trailing bracket
+ print("{0} generated".format(old_chip_name))
+
+ dict_iterator += 1
+ dict_list.append("")
+ dict_list[dict_iterator] = " \"{0}\" : ".format(chip_name) # thisdict : {
+ dict_list[dict_iterator] += "{\n"
+ old_chip_name = chip_name
+
+ if (old_function_name != function_name):
+ dict_list[dict_iterator] += " \"{0}\" : ".format(function_name[0:-5]) # "function_name" :
+ old_function_name = function_name
+
+ scrbytes = script[3]
+ for bytes in scrbytes:
+ function_string += bytes.text
+ function_string += ", "
+
+ dict_list[dict_iterator] += "[{0}],\n".format(function_string[0:-2]) # "function string",
+
+ dict_file.write(dict_header)
+ dict_file.write("scripts = {\n")
+ for x in range (dict_iterator):
+ dict_file.write(dict_list[x]) # store decoded dictionary
+ dict_file.write("}")
+
+
+
+
+# tries to reduce file size, reuires the previous function to be executed
+# in order to provide the python file
+def optimize_dict():
+ import scripts_cache.scripts_dict as dict
+ global cache_dir
+ for chip_name in dict.scripts: # Go through every chip
+ for func_name in dict.scripts[chip_name]: # Go through every function for each chip
+ if func_name in dict.func_dict: # Only handle the function if we care
+ func_array = dict.func_dict[func_name] # Use the array
+ position = -1
+ for x in range (len(func_array)): # go through
+ if func_array[x] == dict.scripts[chip_name][func_name]:
+ position = x
+ break
+ if position >= 0:
+ dict.scripts[chip_name][func_name] = position
+ else:
+ func_array.append(dict.scripts[chip_name][func_name])
+ dict.scripts[chip_name][func_name] = position + 1
+
+ lut_path = os.path.join(cache_dir, "scripts_lut.py")
+ if (os.path.exists(lut_path)):
+ os.remove(lut_path)
+
+ with open(lut_path, 'w') as lut_file: # Create file
+ lut_file.write("func_dict = {\n") # start with function look-up Table
+ for func in dict.func_dict:
+ lut_file.write(" \"{0}\" : [\n".format(func)) # function start
+ func_array = dict.func_dict[func]
+
+ for array_elem in func_array: # function list start
+ func_string = " ["
+ for i in array_elem: # iterate through the sub-function elements
+ func_string += "0x{0:02X}, ".format(i) # format for readability
+ func_string += "],\n" # end of sub-function
+ lut_file.write(func_string) # write to file
+ lut_file.write(" ],\n") # end of function
+ lut_file.write("}\n\n\n") # end of lut
+
+ lut_file.write("scripts = {\n")
+ for chip_name in dict.scripts: # Go through every chip
+ lut_file.write(" \""+ chip_name + "\" : {\n")
+ for func_name in dict.scripts[chip_name]: # Go through every function for each chip
+ lut_file.write(" \"{0}\" : {1},\n".format(func_name, dict.scripts[chip_name][func_name]))
+ lut_file.write(" },\n")
+ lut_file.write("}") # close dict
+ print("done")
+ #EOF
+
+
+# Beginning of C and H Files
+common_header = \
+'''/* This file was auto-generated by scripts_decoder.py, any changes will be overwritten */
+
+/*
+ * avrdude - A Downloader/Uploader for AVR device programmers
+ * Copyright (C) 2024 MX682X
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
+
+'''
+
+# generates the h-file. generates the struct definition
+def generate_h_file(c_dict, file_dir):
+ h_header = \
+'''
+#ifndef pickit5_lut_h
+#define pickit5_lut_h
+
+#ifdef __cplusplus
+ extern "C" {
+#endif
+
+struct avr_script_lut {
+'''
+
+ h_trailer = \
+'''
+};
+
+typedef struct avr_script_lut SCRIPT;
+const unsigned char * get_devid_script_by_nvm_ver(unsigned char version);
+int get_pickit_updi_script(SCRIPT *scr, const char *partdesc);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // pickit5_lut_h
+'''
+ global common_header
+ if file_dir is None:
+ return
+
+ h_lut_path = os.path.join(file_dir, "pickit5_lut.h") # first - handle defining the structure
+ if (os.path.exists(h_lut_path)):
+ os.remove(h_lut_path)
+ with open(h_lut_path, 'w') as h_file:
+ h_file.write(common_header)
+ h_file.write(h_header)
+ for func_name in c_dict:
+ h_file.write(" const unsigned char *{0};\n unsigned int {0}_len;\n".format(func_name))
+ h_file.write(h_trailer)
+ print("h-File generated")
+ #EOF
+
+
+
+# generates the c-file out of a previously generated python file
+def generate_c_file(c_dict, file_dir):
+ import scripts_cache.scripts_lut as lut
+
+ if file_dir is None:
+ return
+
+ c_lut_path = os.path.join(file_dir, "pickit5_lut.c")
+ if (os.path.exists(c_lut_path)):
+ os.remove(c_lut_path)
+ with open(c_lut_path, 'w') as c_file:
+ non_unique_func = []
+ c_file.write("/* this file was auto-generated */\n")
+ c_file.write("#include \n")
+ c_file.write("#include \n")
+ c_file.write("#include \n")
+ c_file.write("#include \"pickit5_lut.h\"\n\n\n")
+ struct_init_func = ""
+ struct_init_len = ""
+ for func_name in lut.func_dict: # for each function in our database
+ if func_name in c_dict: # if the function exists in our c-list
+ function = lut.func_dict[func_name] # load data associated with the function
+ array_iterator = 0
+ for array in function: # for each array in function
+ array_str = "const unsigned char {0}_{1}[{2}]".format(func_name, array_iterator, len(array))
+ array_str += " = {\n " # begin array
+ for i in range (len(array)): # go through every byte
+ array_str += "0x{0:02x}, ".format(array[i]) # and generate String
+ array_str += "\n};\n" # complete array
+ array_iterator += 1
+ c_file.write(array_str)
+
+ if array_iterator == 1:
+ struct_init_func += " .{0} = {0}_0,\n".format(func_name)
+ struct_init_len += " .{0}_len = sizeof({0}_0),\n".format(func_name)
+ else:
+ struct_init_func += " .{0} = NULL,\n".format(func_name)
+ struct_init_len += " .{0}_len = 0,\n".format(func_name)
+ non_unique_func.append(func_name)
+
+
+ c_file.write("\n\n\nstruct avr_script_lut avr_scripts = {\n")
+ c_file.write(struct_init_func)
+ c_file.write(struct_init_len)
+ c_file.write("};\n\n\n")
+
+ chip_lut_str = "const char *chip_lut[] = {\n "
+ chip_name_iterator = 0
+ for chip_name in lut.scripts:
+ chip_lut_str += "\""
+ chip_lut_str += chip_name
+ chip_lut_str += "\", "
+ chip_name_iterator += 1
+ if chip_name_iterator % 8 == 0:
+ chip_lut_str += "\n "
+ chip_lut_str += "\n};\n\n\n"
+ c_file.write(chip_lut_str)
+
+ c_func_str = "struct avr_script_lut* get_pickit_script(const char* partdesc) { \n"
+ c_func_str += " int namepos = -1;\n"
+ c_func_str += " for (int i = 0; i < {0}; i++)".format(chip_name_iterator)
+ c_func_str += " {\n"
+ c_func_str += " if (strncmp(chip_lut[i], partdesc, 10) == 0) {\n"
+ c_func_str += " namepos = i;\n break;\n }\n }\n"
+ c_func_str += " if (namepos == -1) {\n return NULL;\n }\n"
+ c_file.write(c_func_str)
+
+ switch_iterator = 0
+ c_file.write(" switch (namepos) {\n")
+ for chip_name in lut.scripts:
+ case_str = " case {0}:\n".format(switch_iterator)
+ chip_func = lut.scripts[chip_name]
+ for func_lut in chip_func:
+ if func_lut in non_unique_func:
+ case_str += " avr_scripts.{0} = {0}_{1};\n".format(func_lut, chip_func[func_lut])
+ case_str += " avr_scripts.{0}_len = sizeof({0}_{1});\n".format(func_lut, chip_func[func_lut])
+ case_str += " break;\n"
+ switch_iterator += 1
+ c_file.write(case_str)
+ c_file.write(" }\n return &avr_scripts;\n }")
+ print("c-File generated")
+ #EOF
+
+
+def convert_to_c(c_dict, file_dir):
+
+ generate_h_file(c_dict, file_dir)
+ generate_c_file(c_dict, file_dir)
+ #EOF
+
+
+
+# A sum of the previous functions, generating the c/h files
+# without needing any intermediate files
+def convert_xml(xml_path, c_dict):
+ if xml_path == None:
+ print("No Path to XML file provided")
+ return
+
+ mcu_dict = dict()
+
+ # Prepare directories
+ parent_dir = os.getcwd()
+ src_dir = os.path.join(parent_dir, "src")
+ print("Opening file {0}".format(xml_path))
+ print("Parent Dir: {0}".format(parent_dir))
+ print("Src directory: {0}".format(src_dir))
+
+ # open XML file
+ origin_tree = ET.parse(xml_path)
+ origin_root = origin_tree.getroot()
+ work_root = ET.Element("scripts")
+ print ("XML File loaded")
+
+ # scan scripts file
+ for script in origin_root.findall('script'):
+ function_name = script[0].text # the function name is always on the first place
+ if (function_name.endswith("UPDI")): # We're only intrested in UPDI functions
+ function_name = function_name[0:-5] # remove "_UPDI" from function name
+ if (function_name in c_dict): # filter out unneded functions
+ chip_name = script[1].text # get chip name
+ if (chip_name in mcu_blacklist): # filter out chips in blacklist
+ continue
+ if (chip_name not in mcu_dict):
+ mcu_dict[chip_name] = dict()
+ if (function_name not in mcu_dict[chip_name]):
+ mcu_dict[chip_name][function_name] = []
+ scrbytes = script[3]
+ for bytes in scrbytes:
+ mcu_dict[chip_name][function_name].append(int(bytes.text, 16))
+ # the mcu dict has following layout "mcu_name" : "function1" : [], "function2" : []
+ print("XML File processed")
+
+ # reorder mcu_dict to a func_dict
+ func_dict = dict()
+ for mcu_name in mcu_dict: # Go through every MCU
+ for function_name in mcu_dict[mcu_name]: # Go through every Function for every CPU
+ if (function_name not in func_dict):
+ func_dict[function_name] = []
+
+ funct_bytes = mcu_dict[mcu_name][function_name] # get Function bytes
+ entries = len(func_dict[function_name])
+ for x in range (entries + 1): # try to find an existing entry
+ if x == entries: # if we reached the end
+ func_dict[function_name].append(funct_bytes) # add an entry to our dict
+ mcu_dict[mcu_name][function_name] = x # remember the postion in dict
+ break
+ if func_dict[function_name][x] == funct_bytes: # if match found
+ mcu_dict[mcu_name][function_name] = x # remember the postion
+ break
+ # the funct dict has following layout: "function1" : [[], []], "function2" : [[], []],
+ # the mcu dict has following layout "mcu_name" : "function1" : 1, "function2" : 0
+
+ # create h-File
+ generate_h_file(c_dict, src_dir)
+
+ # create c-File
+ global common_header
+ c_lut_path = os.path.join(src_dir, "pickit5_updi_lut.c")
+ if (os.path.exists(c_lut_path)):
+ os.remove(c_lut_path)
+ with open(c_lut_path, 'w') as c_file:
+ non_unique_func = []
+ c_file.write(common_header)
+ c_file.write("#include \n")
+ c_file.write("#include \n")
+ c_file.write("#include \n")
+ c_file.write("#include \"pickit5_lut.h\"\n\n\n")
+
+ # Generate the arrays for the functions
+ struct_init_func = ""
+ struct_init_len = ""
+ for func_name in func_dict: # for each function in our database
+ function = func_dict[func_name] # load data associated with the function
+ array_iterator = 0
+ for array in function: # for each array in function
+ array_str = "const unsigned char {0}_{1}[{2}]".format(func_name, array_iterator, len(array))
+ array_str += " = {" # begin array
+ for i in range (len(array)): # go through every byte
+ if (i % 16 == 0):
+ array_str += "\n " # new line after 16 bytes
+ array_str += "0x{0:02x}, ".format(array[i]) # and generate String
+ array_str += "\n};\n\n" # complete array
+ array_iterator += 1
+ c_file.write(array_str)
+
+ if array_iterator == 1:
+ struct_init_func += " scr->{0} = {0}_0;\n".format(func_name)
+ struct_init_len += " scr->{0}_len = sizeof({0}_0);\n".format(func_name)
+ else:
+ struct_init_func += " scr->{0} = NULL;\n".format(func_name)
+ struct_init_len += " scr->{0}_len = 0;\n".format(func_name)
+ non_unique_func.append(func_name)
+
+
+ c_file.write("\n\n\nstatic void pickit_updi_script_init(SCRIPT *scr);\n") # declaration
+ c_file.write("static void pickit_updi_script_init(SCRIPT *scr) {\n") # definition
+ c_file.write(struct_init_func)
+ c_file.write("\n") # improve readability
+ c_file.write(struct_init_len)
+ c_file.write("}\n\n\n")
+
+ # Lookup Table for Chip Names
+ chip_lut_str = "const char * const pickit5_updi_chip_lut[] = {\n "
+ chip_name_iterator = 0
+ for chip_name in mcu_dict:
+ chip_lut_str += "\""
+ chip_lut_str += chip_name
+ chip_lut_str += "\", "
+ chip_name_iterator += 1
+ if chip_name_iterator % 8 == 0:
+ chip_lut_str += "\n "
+ chip_lut_str += "\n};\n\n\n"
+ c_file.write(chip_lut_str)
+
+ # Provide a way to get the DevID Script by NVM Version stored in SIB
+ devid_str = "const unsigned char * get_devid_script_by_nvm_ver(unsigned char version) {\n"
+ devid_str += " if (version >= '0') version -= '0'; // allow chars\n"
+ devid_str += " if (version > 9) return NULL; // Not a valid number\n"
+ devid_str += " if (version <= 3) // tiny, mega, DA, DB, DD, EA\n"
+ devid_str += " return GetDeviceID_0;\n"
+ devid_str += " else // DU, EB\n"
+ devid_str += " return GetDeviceID_1;\n}\n\n"
+ c_file.write(devid_str)
+
+ # Main Function to load the data into the structure
+ c_func_str = "int get_pickit_updi_script(SCRIPT *scr, const char* partdesc) { \n"
+ c_func_str += " if ((scr == NULL) || (partdesc == NULL))\n return -1;\n\n"
+ c_func_str += " int namepos = -1;\n"
+ c_func_str += " for (int i = 0; i < {0}; i++)".format(chip_name_iterator)
+ c_func_str += " {\n"
+ c_func_str += " if (strncmp(pickit5_updi_chip_lut[i], partdesc, 10) == 0) {\n"
+ c_func_str += " namepos = i;\n break;\n }\n }\n"
+ c_func_str += " if (namepos == -1) {\n return -2;\n }\n\n"
+ c_func_str += " pickit_updi_script_init(scr); // load common functions\n\n"
+ c_file.write(c_func_str)
+
+
+ switch_iterator = 0
+ c_file.write(" switch (namepos) {\n")
+ case_str_list = []
+ break_str_list = []
+ for chip_name in mcu_dict:
+ case_str_list.append("")
+ break_str_list.append("")
+ case_str_list[switch_iterator] = " case {0}: /* {1} */\n".format(switch_iterator, chip_name)
+ chip_func = mcu_dict[chip_name]
+ for func_lut in chip_func:
+ if func_lut in non_unique_func:
+ break_str_list[switch_iterator] += " scr->{0} = {0}_{1};\n".format(func_lut, chip_func[func_lut])
+ break_str_list[switch_iterator] += " scr->{0}_len = sizeof({0}_{1});\n".format(func_lut, chip_func[func_lut])
+ break_str_list[switch_iterator] += " break;\n"
+ switch_iterator += 1
+
+
+ for x in range (0, switch_iterator):
+ if (case_str_list[x] != ""): # ignore already "filtered" out cases
+ file_str = case_str_list[x] # start with a case
+ temp_str = break_str_list[x] # buffer the content of the case
+ for y in range(x + 1, switch_iterator): # go through all future entries
+ if temp_str == break_str_list[y]: # if we find one that is identical
+ file_str += case_str_list[y] # add it to the case at the beginning
+ case_str_list[y] = "" # clear case entry
+ break_str_list[y] = "" # clear content entry to speed up filtering
+ file_str += temp_str # add the content of the case
+ c_file.write(file_str)
+
+
+ c_file.write(" }\n return 0;\n}")
+ print("c-File generated")
+ pass
+
+
+
+if not user_input:
+ xml_path = find_xml()
+ if xml_path == None:
+ print("Unable to find scripts.xml in the default location.")
+ print("Please Enter a Path to the File or Directory:")
+ xml_path = input(">")
+ if (os.path.isdir(xml_path)):
+ os.path.join(xml_path, "scripts.xml")
+ if (os.path.exists(xml_path) == False):
+ print("File not found, exiting")
+ quit()
+ convert_xml(xml_path, c_dict)
+ quit()
+
+
+while user_input:
+ user_in = input(">")
+
+ if (user_in == "cache"):
+ xml_path = find_xml()
+ cache_xml(xml_path)
+ elif (user_in == "decode"):
+ xml_path = os.path.join(cache_dir, "scripts_updi.xml")
+ decode_xml_cache(xml_path)
+ elif (user_in == "optimize"):
+ optimize_dict()
+ elif (user_in == "cfy"):
+ convert_to_c(c_dict, cache_dir)
+ elif (user_in == "dude"):
+ xml_path = find_xml()
+ if xml_path == None:
+ print("Unable to find scripts.xml in the default location.")
+ print("Please Enter a Path to the File or Directory:")
+ xml_path = input(">")
+ if (os.path.isdir(xml_path)):
+ os.path.join(xml_path, "scripts.xml")
+ if (os.path.exists(xml_path) == False):
+ print("File not found, exiting")
+ quit()
+ convert_xml(xml_path, c_dict)
+ quit()
+ pass