mirror of
https://github.com/avrdudes/avrdude.git
synced 2026-09-22 00:56:21 +03:00
fixing prodsig on isp and jtag and other improvements
This commit is contained in:
293
src/pickit5.c
293
src/pickit5.c
@@ -74,6 +74,7 @@
|
||||
#define ERROR_USB_RECV -11
|
||||
#define ERROR_SCRIPT_PARAM_SIZE -12
|
||||
#define ERROR_BAD_RESPONSE -13
|
||||
#define ERROR_SCRIPT_EXECUTION -14
|
||||
|
||||
// Private data for this programmer
|
||||
struct pdata {
|
||||
@@ -97,7 +98,7 @@ struct pdata {
|
||||
unsigned char sernum_string[20]; // Buffer for display() sent by get_fw()
|
||||
char sib_string[32];
|
||||
unsigned char txBuf[2048]; // Buffer for transfers
|
||||
unsigned char rxBuf[2048];
|
||||
unsigned char rxBuf[2048]; // 2048 because of WriteEEmem_dw with 1728 bytes length
|
||||
SCRIPT scripts;
|
||||
};
|
||||
|
||||
@@ -147,7 +148,7 @@ static int pickit5_updi_read_cs_reg(const PROGRAMMER *pgm, unsigned int addr, un
|
||||
|
||||
// ISP-specific
|
||||
static int pickit5_isp_write_fuse(const PROGRAMMER *pgm, const AVRMEM *mem, unsigned char value);
|
||||
static int pickit5_isp_read_fuse(const PROGRAMMER *pgm, const AVRMEM *mem, unsigned char *value);
|
||||
static int pickit5_isp_read_fuse(const PROGRAMMER *pgm, const AVRMEM *mem, unsigned long addr, unsigned char *value);
|
||||
|
||||
// debugWire-specific
|
||||
static int pickit5_dw_write_fuse(const PROGRAMMER *pgm, const AVRPART *p, const AVRMEM *mem, unsigned char value);
|
||||
@@ -164,7 +165,7 @@ static int pickit5_tpi_write(const PROGRAMMER *pgm, const AVRPART *p,
|
||||
// JTAG-Specific
|
||||
static int pickit5_jtag_write_fuse(const PROGRAMMER *pgm, const AVRPART *p, const AVRMEM *mem, unsigned char value);
|
||||
static int pickit5_jtag_read_fuse(const PROGRAMMER *pgm, const AVRPART *p, const AVRMEM *mem, unsigned char *value);
|
||||
|
||||
static int pickit5_jtag_read_configmem(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);
|
||||
@@ -324,7 +325,7 @@ static int pickit5_send_script(const PROGRAMMER *pgm, unsigned int script_type,
|
||||
memcpy(&buf[preamble_len], script, script_len);
|
||||
|
||||
int ret_val = serial_send(&pgm->fd, buf, message_len);
|
||||
if (ret_val < 0) {
|
||||
if(ret_val < 0) {
|
||||
pmsg_error("Sending script failed");
|
||||
}
|
||||
return ret_val;
|
||||
@@ -338,12 +339,18 @@ static int pickit5_read_response(const PROGRAMMER *pgm) {
|
||||
return ERROR_USB_RECV;
|
||||
}
|
||||
unsigned int status = pickit5_array_to_uint32(&buf[0]);
|
||||
unsigned int error_code = pickit5_array_to_uint32(&buf[16]);
|
||||
|
||||
if(status != 0x0D) {
|
||||
pmsg_error("unexpected response");
|
||||
pmsg_error("unexpected read response: 0x%2X\n", status);
|
||||
return ERROR_BAD_RESPONSE;
|
||||
}
|
||||
|
||||
if(error_code != 0x00) {
|
||||
pmsg_error("Script Error returned: 0x%2X\n", error_code);
|
||||
return ERROR_SCRIPT_EXECUTION;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -488,18 +495,46 @@ static void pickit5_enable(PROGRAMMER *pgm, const AVRPART *p) {
|
||||
// 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;
|
||||
if(is_updi(pgm)){
|
||||
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;
|
||||
}
|
||||
}
|
||||
if(is_debugwire(pgm)) {
|
||||
if((mem = avr_locate_flash(p))) {
|
||||
mem->page_size = 1024; // The Flash Write function needs 1600 bytes
|
||||
mem->readsize = 1024; // this reduces overhead and speeds things up
|
||||
mem->page_size = mem->size < 1024? mem->size : 1024; // The Flash Write function needs 1600 bytes
|
||||
mem->readsize = mem->size < 1024? mem->size : 1024; // this reduces overhead and speeds things up
|
||||
}
|
||||
}
|
||||
if(is_isp(pgm)){
|
||||
if((mem = avr_locate_flash(p))) {
|
||||
mem->page_size = mem->size < 1024? mem->size : 1024;
|
||||
mem->readsize = mem->size < 1024? mem->size : 1024;
|
||||
}
|
||||
}
|
||||
if(both_xmegajtag(pgm, p) || both_pdi(pgm, p)) {
|
||||
if((mem = avr_locate_flash(p))) {
|
||||
mem->page_size = mem->size < 1024? mem->size : 1024;
|
||||
mem->readsize = mem->size < 1024? mem->size : 1024;
|
||||
}
|
||||
if((mem = avr_locate_application(p))) {
|
||||
mem->page_size = mem->size < 1024? mem->size : 1024;
|
||||
mem->readsize = mem->size < 1024? mem->size : 1024;
|
||||
}
|
||||
if((mem = avr_locate_apptable(p))) {
|
||||
mem->page_size = mem->size < 1024? mem->size : 1024;
|
||||
mem->readsize = mem->size < 1024? mem->size : 1024;
|
||||
}
|
||||
if((mem = avr_locate_boot(p))) {
|
||||
mem->page_size = mem->size < 1024? mem->size : 1024;
|
||||
mem->readsize = mem->size < 1024? mem->size : 1024;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -683,7 +718,7 @@ static int pickit5_initialize(const PROGRAMMER *pgm, const AVRPART *p) {
|
||||
my.dW_switched_isp = 0;
|
||||
|
||||
if(is_updi(pgm)) { // UPDI got it's own init as it is well enough documented to select the
|
||||
if (pickit5_updi_init(pgm, p, v_target) < 0) { // CLKDIV based on the voltage and requested baud
|
||||
if(pickit5_updi_init(pgm, p, v_target) < 0) { // CLKDIV based on the voltage and requested baud
|
||||
return -1;
|
||||
}
|
||||
} else {
|
||||
@@ -764,7 +799,7 @@ static int pickit5_chip_erase(const PROGRAMMER *pgm, const AVRPART *p) {
|
||||
pmsg_debug("%s()\n", __func__);
|
||||
|
||||
pickit5_program_enable(pgm, p);
|
||||
if (is_debugwire(pgm)) { // dW Chip erase doesn't seem to be working, use ISP
|
||||
if(is_debugwire(pgm)) { // dW Chip erase doesn't seem to be working, use ISP
|
||||
pickit5_dw_switch_to_isp(pgm, p);
|
||||
}
|
||||
const unsigned char *chip_erase = my.scripts.EraseChip;
|
||||
@@ -804,7 +839,7 @@ static int pickit5_set_sck_period(const PROGRAMMER *pgm, double sckperiod) {
|
||||
const unsigned char *set_speed = my.scripts.SetSpeed;
|
||||
unsigned int set_speed_len = my.scripts.SetSpeed_len;
|
||||
unsigned char buf[4];
|
||||
if (set_speed == NULL) { // debugWire is fun . . .
|
||||
if(set_speed == NULL) { // debugWire is fun . . .
|
||||
return 0; // No script, to execute, return success
|
||||
}
|
||||
|
||||
@@ -830,7 +865,7 @@ static int pickit5_write_byte(const PROGRAMMER *pgm, const AVRPART *p,
|
||||
rc = pickit5_jtag_write_fuse(pgm, p, mem, value);
|
||||
}
|
||||
}
|
||||
if (rc == 0) {
|
||||
if(rc == 0) {
|
||||
rc = pickit5_write_array(pgm, p, mem, addr, 1, &value);
|
||||
}
|
||||
|
||||
@@ -843,13 +878,19 @@ static int pickit5_read_byte(const PROGRAMMER *pgm, const AVRPART *p,
|
||||
const AVRMEM *mem, unsigned long addr, unsigned char *value) {
|
||||
int rc = 0;
|
||||
if(mem_is_in_fuses(mem)) {
|
||||
if(is_isp(pgm)){
|
||||
rc = pickit5_isp_read_fuse(pgm, mem, value);
|
||||
} else if(is_debugwire(pgm)){
|
||||
if(is_isp(pgm)) {
|
||||
rc = pickit5_isp_read_fuse(pgm, mem, addr, value);
|
||||
} else if(is_debugwire(pgm)) {
|
||||
rc = pickit5_dw_read_fuse(pgm, p, mem, value);
|
||||
} else if(both_jtag(pgm, p)){
|
||||
} else if(both_jtag(pgm, p)) {
|
||||
rc = pickit5_jtag_read_fuse(pgm, p, mem, value);
|
||||
}
|
||||
} else if(mem_is_in_sigrow(mem)) {
|
||||
if(is_isp(pgm)){
|
||||
rc = pickit5_isp_read_fuse(pgm, mem, addr, value); // this works by chance
|
||||
} else if(both_jtag(pgm, p)) {
|
||||
rc = pickit5_jtag_read_configmem(pgm, p, mem, addr, value);
|
||||
}
|
||||
}
|
||||
if(rc == 0) {
|
||||
rc = pickit5_read_array(pgm, p, mem, addr, 1, value);
|
||||
@@ -993,7 +1034,7 @@ static int pickit5_write_array(const PROGRAMMER *pgm, const AVRPART *p,
|
||||
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_io(mem) && my.scripts.WriteMemIO != NULL) {
|
||||
} else if(mem_is_io(mem) && my.scripts.WriteMemIO != NULL) {
|
||||
write_bytes = my.scripts.WriteMemIO;
|
||||
write_bytes_len = my.scripts.WriteMemIO_len;
|
||||
} else if(mem_is_eeprom(mem) && my.scripts.WriteDataEEmem != NULL) {
|
||||
@@ -1002,7 +1043,7 @@ static int pickit5_write_array(const PROGRAMMER *pgm, const AVRPART *p,
|
||||
} else if(mem_is_in_fuses(mem) && my.scripts.WriteConfigmemFuse != NULL) {
|
||||
write_bytes = my.scripts.WriteConfigmemFuse;
|
||||
write_bytes_len = my.scripts.WriteConfigmemFuse_len;
|
||||
} else if (mem_is_lock(mem) && my.scripts.WriteConfigmemLock != NULL) {
|
||||
} else if(mem_is_lock(mem) && my.scripts.WriteConfigmemLock != NULL) {
|
||||
write_bytes = my.scripts.WriteConfigmemLock;
|
||||
write_bytes_len = my.scripts.WriteConfigmemLock_len;
|
||||
} else if(mem_is_user_type(mem) && my.scripts.WriteIDmem != NULL) {
|
||||
@@ -1028,21 +1069,6 @@ static int pickit5_write_array(const PROGRAMMER *pgm, const AVRPART *p,
|
||||
pickit5_uint32_to_array(&buf[4], len);
|
||||
|
||||
int rc = pickit5_download_data(pgm, write_bytes, write_bytes_len, buf, 8, value, len);
|
||||
if(rc == -1) {
|
||||
pmsg_error("sending script failed\n");
|
||||
}
|
||||
if(rc == -2) {
|
||||
pmsg_error("reading script response failed\n");
|
||||
}
|
||||
if(rc == -3) {
|
||||
pmsg_error("failed when sending data\n");
|
||||
}
|
||||
if(rc == -4) {
|
||||
pmsg_error("error check failed\n");
|
||||
}
|
||||
if(rc == -5) {
|
||||
pmsg_error("sending script done message failed\n");
|
||||
}
|
||||
if(rc < 0) {
|
||||
return -1;
|
||||
} else {
|
||||
@@ -1087,10 +1113,10 @@ static int pickit5_read_array(const PROGRAMMER *pgm, const AVRPART *p,
|
||||
if(mem_is_in_flash(mem)) {
|
||||
read_bytes = my.scripts.ReadProgmem;
|
||||
read_bytes_len = my.scripts.ReadProgmem_len;
|
||||
} else if (mem_is_calibration(mem) && my.scripts.ReadCalibrationByte != NULL) {
|
||||
} else if(mem_is_calibration(mem) && my.scripts.ReadCalibrationByte != NULL) {
|
||||
read_bytes = my.scripts.ReadCalibrationByte;
|
||||
read_bytes_len = my.scripts.ReadCalibrationByte_len;
|
||||
} else if (mem_is_io(mem) && my.scripts.ReadMemIO != NULL) {
|
||||
} else if(mem_is_io(mem) && my.scripts.ReadMemIO != NULL) {
|
||||
read_bytes = my.scripts.ReadMemIO;
|
||||
read_bytes_len = my.scripts.ReadMemIO_len;
|
||||
} else if(mem_is_eeprom(mem) && my.scripts.ReadDataEEmem != NULL) {
|
||||
@@ -1099,7 +1125,7 @@ static int pickit5_read_array(const PROGRAMMER *pgm, const AVRPART *p,
|
||||
} else if(mem_is_in_fuses(mem) && my.scripts.ReadConfigmemFuse != NULL) {
|
||||
read_bytes = my.scripts.ReadConfigmemFuse;
|
||||
read_bytes_len = my.scripts.ReadConfigmemFuse_len;
|
||||
} else if (mem_is_lock(mem) && my.scripts.ReadConfigmemLock != NULL) {
|
||||
} else if(mem_is_lock(mem) && my.scripts.ReadConfigmemLock != NULL) {
|
||||
read_bytes = my.scripts.ReadConfigmemLock;
|
||||
read_bytes_len = my.scripts.ReadConfigmemLock_len;
|
||||
} else if(mem_is_user_type(mem) && my.scripts.ReadIDmem != NULL) {
|
||||
@@ -1136,16 +1162,6 @@ static int pickit5_read_array(const PROGRAMMER *pgm, const AVRPART *p,
|
||||
pickit5_uint32_to_array(&buf[4], len);
|
||||
|
||||
int rc = pickit5_upload_data(pgm, read_bytes, read_bytes_len, buf, 8, value, len);
|
||||
|
||||
if(rc == -1) {
|
||||
pmsg_error("sending script failed\n");
|
||||
} else if (rc == -2) {
|
||||
pmsg_error("unexpected read response\n");
|
||||
} else if (rc == -3) {
|
||||
pmsg_error("reading data memory failed\n");
|
||||
} else if (rc == -4) {
|
||||
pmsg_error("sending script done message failed\n");
|
||||
}
|
||||
|
||||
if(rc < 0) {
|
||||
return -1;
|
||||
@@ -1164,12 +1180,12 @@ static int pickit5_read_dev_id(const PROGRAMMER *pgm, const AVRPART *p) {
|
||||
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
|
||||
}
|
||||
} else if (is_debugwire(pgm)) {
|
||||
} else if(is_debugwire(pgm)) {
|
||||
unsigned char scr [] = {0x7D, 0x00, 0x00, 0x00}; // Not sure what this does
|
||||
unsigned int scr_len = sizeof(scr);
|
||||
pickit5_send_script_cmd(pgm, scr, scr_len, NULL, 0);
|
||||
pickit5_program_enable(pgm, p);
|
||||
if (my.rxBuf[17] == 0x0E) { // Errors figured out during 6 hours of failing to get it to work
|
||||
if(my.rxBuf[17] == 0x0E) { // Errors figured out during 6 hours of failing to get it to work
|
||||
if(my.rxBuf[16] == 0x10) { // with the serial/bootloader auto-reset circuit.
|
||||
pmsg_error("Debug Wire transmission error, Aborting. (Is the Pullup >=10 kOhms?)");
|
||||
} else if(my.rxBuf[16] == 58) {
|
||||
@@ -1258,7 +1274,7 @@ static int pickit5_updi_write_cs_reg(const PROGRAMMER *pgm, unsigned int addr, u
|
||||
buf[0] = addr;
|
||||
buf[1] = value;
|
||||
|
||||
if (pickit5_send_script_cmd(pgm, write_cs, write_cs_len, buf, 2) < 0) {
|
||||
if(pickit5_send_script_cmd(pgm, write_cs, write_cs_len, buf, 2) < 0) {
|
||||
pmsg_error("CS Reg write failed\n");
|
||||
return -1;
|
||||
}
|
||||
@@ -1337,6 +1353,9 @@ static void pickit5_isp_switch_to_dw(const PROGRAMMER *pgm, const AVRPART *p) {
|
||||
}
|
||||
|
||||
|
||||
// Original Script only supports doing all three at once,
|
||||
// doing a custom script felt easier to integrate into avrdude,
|
||||
// especially as we already have all the programming commands
|
||||
static int pickit5_isp_write_fuse(const PROGRAMMER *pgm, const AVRMEM *mem, unsigned char value) {
|
||||
unsigned char write_fuse_isp [] = {
|
||||
0x90, 0x00, 0x32, 0x00, 0x00, 0x00, // load 0x32 to r00
|
||||
@@ -1362,14 +1381,11 @@ static int pickit5_isp_write_fuse(const PROGRAMMER *pgm, const AVRMEM *mem, unsi
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int pickit5_isp_read_fuse(const PROGRAMMER *pgm, const AVRMEM *mem, unsigned char *value) {
|
||||
// Original Script only supports doing all three at once,
|
||||
// doing a custom script felt easier to integrate into avrdude,
|
||||
// especially as we already have all the programming commands
|
||||
unsigned char read_fuse_isp [] = {
|
||||
static int pickit5_isp_read_fuse(const PROGRAMMER *pgm, const AVRMEM *mem, unsigned long addr, unsigned char *value) {
|
||||
unsigned char read_fuse_isp [] = { // as we pull the command from avrdude's conf file, this isn't limited to fuses
|
||||
0x90, 0x00, 0x32, 0x00, 0x00, 0x00, // load 0x32 to r00
|
||||
0x1E, 0x37, 0x00, // Enable Programming?
|
||||
0x90, 0x01, 0x00, 0x00, 0x00, 0x00, // load programming command to r01 (set later)
|
||||
0x90, 0x01, 0x00, 0x00, 0x00, 0x00, // load programming command to r01 (set below)
|
||||
0x9B, 0x02, 0x03, // load 0x03 to r02
|
||||
0x9B, 0x03, 0x00, // load 0x00 to r03
|
||||
0x1E, 0x35, 0x01, 0x02, 0x03, // Execute Command placed in r01
|
||||
@@ -1378,7 +1394,7 @@ static int pickit5_isp_read_fuse(const PROGRAMMER *pgm, const AVRMEM *mem, unsig
|
||||
unsigned int read_fuse_isp_len = sizeof(read_fuse_isp);
|
||||
unsigned int cmd;
|
||||
avr_set_bits(mem->op[AVR_OP_READ], (unsigned char*)&cmd);
|
||||
avr_set_addr(mem->op[AVR_OP_READ], (unsigned char*)&cmd, mem_fuse_offset(mem));
|
||||
avr_set_addr(mem->op[AVR_OP_READ], (unsigned char*)&cmd, addr + mem->offset);
|
||||
|
||||
read_fuse_isp[14] = (uint8_t) cmd; // swap bitorder and fill array
|
||||
read_fuse_isp[13] = (uint8_t) (cmd >> 8);
|
||||
@@ -1389,13 +1405,14 @@ static int pickit5_isp_read_fuse(const PROGRAMMER *pgm, const AVRMEM *mem, unsig
|
||||
pmsg_error("Read Fuse Script failed");
|
||||
return -1;
|
||||
}
|
||||
if (0x01 != my.rxBuf[20]) { // length
|
||||
if(0x01 != my.rxBuf[20]) { // length
|
||||
return -1;
|
||||
}
|
||||
*value = my.rxBuf[24]; // return value
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
// debugWire cannot write nor read fuses, have to change to ISP for that.
|
||||
// Luckily, there is a custom script doing fuse access on ISP anyway,
|
||||
// so no need to switch between script sets
|
||||
@@ -1406,46 +1423,47 @@ static int pickit5_dw_write_fuse(const PROGRAMMER *pgm, const AVRPART *p, const
|
||||
|
||||
static int pickit5_dw_read_fuse(const PROGRAMMER *pgm, const AVRPART *p, const AVRMEM *mem, unsigned char *value) {
|
||||
pickit5_dw_switch_to_isp(pgm, p);
|
||||
return pickit5_isp_read_fuse(pgm, mem, value);
|
||||
return pickit5_isp_read_fuse(pgm, mem, 0, value);
|
||||
}
|
||||
|
||||
|
||||
// gave JTAG also a custom script to make integration into avrdude
|
||||
// easier. Also encodes all data in script itself instead of using paramters
|
||||
static int pickit5_jtag_write_fuse(const PROGRAMMER *pgm, const AVRPART *p, const AVRMEM *mem, unsigned char value) {
|
||||
unsigned char fuse_cmd = 0x33; // value for lfuse
|
||||
unsigned char fuse_poll = 0x33; // value for lfuse
|
||||
if(mem_is_hfuse(mem)) {
|
||||
fuse_cmd = 0x37;
|
||||
fuse_poll = 0x37;
|
||||
} else if(mem_is_efuse(mem)) {
|
||||
fuse_cmd = 0x3B;
|
||||
fuse_poll = 0x37;
|
||||
}
|
||||
|
||||
unsigned char write_fuse_jtag [] = {
|
||||
0x9b, 0x00, 0x33, // Parameter address to r04
|
||||
0x9b, 0x0B, 0xFF, // Parameter value to r11
|
||||
0x9b, 0x0a, 0x0f, // Set r10 to 0x0F
|
||||
0x9b, 0x02, 0x05, // Set r02 to 0x05 (PROG_COMMANDS)
|
||||
0x1e, 0x66, 0x02, // JTAG Write to Instruction Reg the value in r02
|
||||
0x90, 0x02, 0x40, 0x23, 0x00, 0x00, // set r02 to 0x2340 (Enter Fuse Write)
|
||||
0x1e, 0x67, 0x02, 0x0a, // JTAG: Write to Data Reg the value in r02 with a length in r0A(16)
|
||||
0x90, 0x03, 0x00, 0x13, 0x00, 0x00, // set r03 to 0x1300 (Load Data Low Byte)
|
||||
0x6e, 0x03, 0x0b, // r03 += r11 (Set low byte)
|
||||
0x1e, 0x67, 0x03, 0x0a, // JTAG: Write to Data Reg the value in r03 with a length in r0A(16)
|
||||
0x9C, 0x00, 0x00, fuse_cmd, // Write fuse write command A to r00
|
||||
0x9C, 0x06, 0x00, (fuse_cmd & 0xFD), // Write fuse write command B to r06
|
||||
0x9C, 0x07, 0x00, fuse_poll, // Write fuse poll command to r07
|
||||
0x9C, 0x01, value, 0x13, // Write new fuse value plus load command (0x13) into r01
|
||||
0x9b, 0x02, 0x0F, // Set r02 to 0x0F
|
||||
0x9b, 0x03, 0x05, // Set r03 to 0x05 (PROG_COMMANDS)
|
||||
0x1e, 0x66, 0x03, // JTAG Write to Instruction Reg the value in r03
|
||||
0x90, 0x04, 0x40, 0x23, 0x00, 0x00, // set r04 to 0x2340 (Enter Fuse Write)
|
||||
0x1e, 0x67, 0x04, 0x02, // JTAG: Write to Data Reg the value in r04 with a length in r02(16)
|
||||
0x1e, 0x67, 0x01, 0x02, // JTAG: Write to Data Reg the value in r01 with a length in r02(16)
|
||||
|
||||
0x60, 0x01, 0x00, // Copy r00 to r01 (Write fuse command)
|
||||
0x68, 0x01, 0x08, // Left Shift r01 by 8
|
||||
0x69, 0x00, 0x02, 0x00, 0x00, 0x00, // r00 -= 2
|
||||
0x68, 0x00, 0x08, // Left Shift r00 by 8
|
||||
0x1e, 0x67, 0x00, 0x02, // JTAG: Write to Data Reg the value in r00 with a length in r02(16)
|
||||
0x1e, 0x67, 0x06, 0x02, // JTAG: Write to Data Reg the value in r06 with a length in r02(16)
|
||||
0x1e, 0x67, 0x00, 0x02, // JTAG: Write to Data Reg the value in r00 with a length in r02(16)
|
||||
0x1e, 0x67, 0x00, 0x02, // JTAG: Write to Data Reg the value in r00 with a length in r02(16)
|
||||
|
||||
0x1e, 0x67, 0x01, 0x0a, // JTAG: Write to D../build_linux/src/avrdude -qq -c pickit5_jtag -xvtarg=4.5 -p m32u4 -Ueeprom:w:0x55:m -Ueeprom:w:0xaa:mata Reg the value in r01 with a length in r0A(16)
|
||||
0x1e, 0x67, 0x00, 0x0a, // JTAG: Write to Data Reg the value in r00 with a length in r0A(16)
|
||||
0x1e, 0x67, 0x01, 0x0a, // JTAG: Write to Data Reg the value in r01 with a length in r0A(16)
|
||||
0x1e, 0x67, 0x01, 0x0a, // JTAG: Write to Data Reg the value in r01 with a length in r0A(16)
|
||||
0xa2, // do
|
||||
0x1e, 0x6b, 0x01, 0x0a, // JTAG: Write/read Data Reg the value in r01 with a length in r0A(16)
|
||||
0xa5, 0x00, 0x02, 0x00, 0x00, // while ((temp_reg & 0x200) != 0x200)
|
||||
0x00, 0x02, 0x00, 0x00, 0x0a, 0x00, //
|
||||
0xa2, // do
|
||||
0x1e, 0x6b, 0x07, 0x02, // JTAG: Write/read Data Reg the value in r07 with a length in r02(16)
|
||||
0xa5, 0x00, 0x02, 0x00, 0x00, // while ((temp_reg & 0x200) != 0x200)
|
||||
0x00, 0x02, 0x00, 0x00, 0x0a, 0x00, //
|
||||
};
|
||||
unsigned int write_fuse_isp_len = sizeof(write_fuse_jtag);
|
||||
if(mem_is_hfuse(mem)) {
|
||||
write_fuse_jtag[2] = 0x3B;
|
||||
} else if (mem_is_efuse(mem)) {
|
||||
write_fuse_jtag[2] = 0x37;
|
||||
}
|
||||
write_fuse_jtag[5] = value;
|
||||
|
||||
if(pickit5_send_script_cmd(pgm, write_fuse_jtag, write_fuse_isp_len, NULL, 0) < 0) {
|
||||
pmsg_error("Write Fuse Script failed");
|
||||
return -1;
|
||||
@@ -1454,34 +1472,62 @@ static int pickit5_jtag_write_fuse(const PROGRAMMER *pgm, const AVRPART *p, cons
|
||||
}
|
||||
|
||||
static int pickit5_jtag_read_fuse(const PROGRAMMER *pgm, const AVRPART *p, const AVRMEM *mem, unsigned char *value) {
|
||||
unsigned char fuse_cmd = 0x33; // value for lfuse
|
||||
if(mem_is_hfuse(mem)) {
|
||||
fuse_cmd = 0x3F;
|
||||
} else if(mem_is_efuse(mem)) {
|
||||
fuse_cmd = 0x3B;
|
||||
}
|
||||
|
||||
unsigned char read_fuse_jtag [] = {
|
||||
0x9b, 0x06, 0x32, // load lfuse address to r06 (replaced fo hfuse/efuse)
|
||||
0x9b, 0x07, 0x0f, // set r07 to 0x07
|
||||
0x9b, 0x09, 0x05, // set r09 to 0x05 (PROG COMMANDS)
|
||||
0x1e, 0x66, 0x09, // Write JTAG Instruction in r09
|
||||
0x90, 0x09, 0x04, 0x23, 0x00, 0x00, // set r09 to 0x2304 (Enter Fuse Bit Read)
|
||||
0x1e, 0x67, 0x09, 0x07, // Write JTAG instruction in r09 with length in r07 (7 bits)
|
||||
0x60, 0x09, 0x06, // copy r06 to r09 (0x32)
|
||||
0x68, 0x09, 0x08, // left-shift r09 by 8
|
||||
0x1e, 0x67, 0x09, 0x07, // Write JTAG instruction in r09 with length in r07 (7 bits)
|
||||
0x60, 0x09, 0x06, // copy r06 to r09
|
||||
0x6e, 0x09, 0x02, // r09 += 2 (set LSB or so (writing only 7 bits))
|
||||
0x68, 0x09, 0x08, // left-shift r09 by 8
|
||||
0x1E, 0x6B, 0x09, 0x07, // Write JTAG instruction in r09 with length in r07 (7 bits) and shift data in
|
||||
0x9C, 0x00, 0x00, fuse_cmd, // load fuse read command A in r00
|
||||
0x9C, 0x01, 0x00, (fuse_cmd & 0xFE), // load fuse read command B in r01
|
||||
0x9b, 0x02, 0x0f, // set r02 to 0x07
|
||||
0x9b, 0x03, 0x05, // set r03 to 0x05 (PROG COMMANDS)
|
||||
0x1e, 0x66, 0x03, // Write JTAG Instruction in r03
|
||||
0x9C, 0x04, 0x04, 0x23, // set r04 to 0x2304 (Enter Fuse Bit Read)
|
||||
0x1e, 0x67, 0x04, 0x02, // Write JTAG instruction in r04 with length in r02 (7 bits)
|
||||
0x1e, 0x67, 0x01, 0x02, // Write JTAG instruction in r01 with length in r02 (7 bits)
|
||||
0x1E, 0x6B, 0x00, 0x02, // Write JTAG instruction in r00 with length in r02 (7 bits) and shift data in
|
||||
0x9F, // Send temp-reg to return status
|
||||
};
|
||||
|
||||
unsigned int read_fuse_jtag_len = sizeof(read_fuse_jtag);
|
||||
if(mem_is_hfuse(mem)) {
|
||||
read_fuse_jtag[2] = 0x3E;
|
||||
} else if (mem_is_efuse(mem)) {
|
||||
read_fuse_jtag[2] = 0x3A;
|
||||
}
|
||||
|
||||
if(pickit5_send_script_cmd(pgm, read_fuse_jtag, read_fuse_jtag_len, NULL, 0) < 0) {
|
||||
pmsg_error("Read Fuse Script failed");
|
||||
return -1;
|
||||
}
|
||||
if (0x01 != my.rxBuf[20]) { // length
|
||||
if(0x01 != my.rxBuf[20]) { // length
|
||||
return -1;
|
||||
}
|
||||
*value = my.rxBuf[24]; // return value
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int pickit5_jtag_read_configmem(const PROGRAMMER *pgm, const AVRPART *p, const AVRMEM *mem, unsigned long addr, unsigned char *value) {
|
||||
unsigned char read_configmem_jtag [] = {
|
||||
0x90, 0x00, 0x00, 0x03, 0x00, 0x00, // set r00 to 0x03xx (Load Address byte with xx=addr)
|
||||
0x9b, 0x02, 0x0f, // set r02 to 0x0F
|
||||
0x9b, 0x03, 0x05, // set r03 to 0x05 (PROG COMMANDS)
|
||||
0x1e, 0x66, 0x03, // Write JTAG Instruction in r03
|
||||
0x90, 0x04, 0x08, 0x23, 0x00, 0x00, // set r04 to 0x2308 (Enter Signature Read)
|
||||
0x1e, 0x67, 0x04, 0x02, // Write JTAG instruction in r04 with length in r02 (15 bits)
|
||||
0x1e, 0x67, 0x00, 0x02, // Write JTAG instruction in r00 with length in r02 (15 bits)
|
||||
0x90, 0x05, 0x00, 0x32, 0x00, 0x00, // set r05 to 0x3200 (Read Signature byte I)
|
||||
0x1e, 0x67, 0x05, 0x02, // Write JTAG instruction in r05 with length in r02 (15 bits)
|
||||
0x90, 0x06, 0x00, 0x33, 0x00, 0x00, // set r06 to 0x3300 (Read Signature byte II)
|
||||
0x1E, 0x6B, 0x06, 0x02, // Write JTAG instruction in r06 with length in r02 (15 bits) and shift data in
|
||||
0x9F, // Send temp-reg to return status
|
||||
};
|
||||
unsigned int read_configmem_jtag_len = sizeof(read_configmem_jtag);
|
||||
read_configmem_jtag[2] = (unsigned char)mem->offset + (unsigned char)addr;
|
||||
|
||||
if(pickit5_send_script_cmd(pgm, read_configmem_jtag, read_configmem_jtag_len, NULL, 0) < 0) {
|
||||
pmsg_error("Read Fuse Script failed");
|
||||
return -1;
|
||||
}
|
||||
if(0x01 != my.rxBuf[20]) { // length
|
||||
return -1;
|
||||
}
|
||||
*value = my.rxBuf[24]; // return value
|
||||
@@ -1543,11 +1589,11 @@ static int pickit5_tpi_read(const PROGRAMMER *pgm, const AVRPART *p,
|
||||
|
||||
if(rc == -1) {
|
||||
pmsg_error("sending script failed\n");
|
||||
} else if (rc == -2) {
|
||||
} else if(rc == -2) {
|
||||
pmsg_error("unexpected read response\n");
|
||||
} else if (rc == -3) {
|
||||
} else if(rc == -3) {
|
||||
pmsg_error("reading data memory failed\n");
|
||||
} else if (rc == -4) {
|
||||
} else if(rc == -4) {
|
||||
pmsg_error("sending script done message failed\n");
|
||||
}
|
||||
if(rc < 0) {
|
||||
@@ -1577,18 +1623,22 @@ static int pickit5_download_data(const PROGRAMMER *pgm, const unsigned char *scr
|
||||
const unsigned char *param, unsigned int param_len, unsigned char *send_buf, unsigned int send_len) {
|
||||
|
||||
if(pickit5_send_script(pgm, SCR_DOWNLOAD, scr, scr_len, param, param_len, send_len) < 0) {
|
||||
pmsg_error("sending script with download failed\n");
|
||||
return -1;
|
||||
}
|
||||
if(pickit5_read_response(pgm) < 0) {
|
||||
return -2;
|
||||
}
|
||||
if(usbdev_data_send(&pgm->fd, send_buf, send_len) < 0) {
|
||||
pmsg_error("Transmission failed on the data channel\n");
|
||||
return -3;
|
||||
}
|
||||
if(pickit5_get_status(pgm, CHECK_ERROR) < 0) {
|
||||
pmsg_error("error check not 'NONE'\n");
|
||||
return -4;
|
||||
}
|
||||
if(pickit5_send_script_done(pgm) < 0) {
|
||||
pmsg_error("sending script done message failed\n");
|
||||
return -5;
|
||||
}
|
||||
return 0;
|
||||
@@ -1598,15 +1648,18 @@ static int pickit5_upload_data(const PROGRAMMER *pgm, const unsigned char *scr,
|
||||
const unsigned char *param, unsigned int param_len, unsigned char *recv_buf, unsigned int recv_len) {
|
||||
|
||||
if(pickit5_send_script(pgm, SCR_UPLOAD, scr, scr_len, param, param_len, recv_len) < 0) {
|
||||
pmsg_error("sending script with upload failed\n");
|
||||
return -1;
|
||||
}
|
||||
if(pickit5_read_response(pgm) < 0) {
|
||||
return -2;
|
||||
}
|
||||
if(usbdev_data_recv(&pgm->fd, recv_buf, recv_len) < 0) {
|
||||
pmsg_error("reading data memory failed\n");
|
||||
return -3;
|
||||
}
|
||||
if(pickit5_send_script_done(pgm) < 0) {
|
||||
pmsg_error("sending script done message failed\n");
|
||||
return -4;
|
||||
}
|
||||
return 0;
|
||||
@@ -1660,16 +1713,16 @@ static int pickit5_set_vtarget(const PROGRAMMER *pgm, double v) {
|
||||
|
||||
if(v < 1.0) { // Anything below 1 V equals disabling Power
|
||||
pmsg_debug("%s(disable)\n", __func__);
|
||||
if (pickit5_send_script_cmd(pgm, power_source, 5, NULL, 0) < 0)
|
||||
if(pickit5_send_script_cmd(pgm, power_source, 5, NULL, 0) < 0)
|
||||
return -1;
|
||||
|
||||
if (pickit5_send_script_cmd(pgm, disable_power, 1, NULL, 0) < 0)
|
||||
if(pickit5_send_script_cmd(pgm, disable_power, 1, NULL, 0) < 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_cmd(pgm, power_source, 5, NULL, 0) < 0)
|
||||
if(pickit5_send_script_cmd(pgm, power_source, 5, NULL, 0) < 0)
|
||||
return -1;
|
||||
|
||||
int vtarg = (int) (v * 1000.0);
|
||||
@@ -1678,7 +1731,7 @@ static int pickit5_set_vtarget(const PROGRAMMER *pgm, double v) {
|
||||
pickit5_uint32_to_array(&set_vtarget[5], vtarg);
|
||||
pickit5_uint32_to_array(&set_vtarget[9], vtarg);
|
||||
|
||||
if (pickit5_send_script_cmd(pgm, set_vtarget, 15, NULL, 0) < 0)
|
||||
if(pickit5_send_script_cmd(pgm, set_vtarget, 15, NULL, 0) < 0)
|
||||
return -1;
|
||||
}
|
||||
return 0;
|
||||
@@ -1690,7 +1743,7 @@ static int pickit5_get_vtarget(const PROGRAMMER *pgm, double *v) {
|
||||
|
||||
pmsg_debug("%s()\n", __func__);
|
||||
|
||||
if (pickit5_send_script_cmd(pgm, get_vtarget, 1, NULL, 0) < 0)
|
||||
if(pickit5_send_script_cmd(pgm, get_vtarget, 1, NULL, 0) < 0)
|
||||
return -1;
|
||||
|
||||
// 24 - internal Vdd [mV]
|
||||
@@ -1717,7 +1770,7 @@ static int pickit5_set_ptg_mode(const PROGRAMMER *pgm) {
|
||||
|
||||
pmsg_debug("%s()\n", __func__);
|
||||
|
||||
if (pickit5_upload_data(pgm, ptg_mode, 5, NULL, 0, buf, 4)) {
|
||||
if(pickit5_upload_data(pgm, ptg_mode, 5, NULL, 0, buf, 4)) {
|
||||
return -1;
|
||||
}
|
||||
return 0;
|
||||
|
||||
Reference in New Issue
Block a user