8000 Feature hvsp ppi by psagi · Pull Request #1445 · avrdudes/avrdude · GitHub
[go: up one dir, main page]
More Web Proxy on the site http://driver.im/
Skip to content

Feature hvsp ppi #1445

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 33 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
33 commits
Select commit Hold shift + click to select a range
ca06d03
dapa_hvsp added to config
psagi Apr 2, 2023
12cb796
show SII pin when in HVSP is supported
psagi Apr 7, 2023
8870346
invert the RESET pin for dapa_hvsp, so it drives 0V to MCU when adapt…
psagi Apr 7, 2023
0b341b4
latch to HVSP mode implemented
psagi Apr 7, 2023
9015eab
fix: operator precedence in bitbang_initialize()
psagi Apr 7, 2023
0899f9b
debug bitbang_initialize_hvsp()
psagi Apr 7, 2023
4ef9466
number of retries for HVSP latching increased
psagi Apr 7, 2023
847808f
signature reading in HVSP mode added to config
psagi Apr 7, 2023
291145e
fix: signature read HVSP data format for ATtiny85
psagi Apr 8, 2023
9e0c037
signature reading in HVSP mode
psagi Apr 8, 2023
223f259
debug bitbang_txrx_hvsp() pin reading
psagi Apr 8, 2023
11d78e4
debug written and read HVSP bits
psagi Apr 9, 2023
ad70b2a
fix: debug HVSP pins
psagi Apr 9, 2023
1a01b6a
New dapa_hvsp hardware, SCI is inverted.
psagi Apr 16, 2023
94941eb
Fix: read data waw shifted 1bit right.
psagi Apr 16, 2023
2793be0
FIX: properly initialize SCI in HVSP mode
psagi May 21, 2023
f1cd8e7
Fuse read commands added for HVSP mode
psagi May 21, 2023
626e466
FIX: include higher bits of efuse in the result when reading ATTiny85…
psagi May 22, 2023
499d980
Write fuse commands implemented for ATTiny85 HVSP
psagi May 24, 2023
fa43ce5
vcc_detect pin added to avrdude.conf
psagi Jun 5, 2023
136efa2
FIX: vcc_detect pin handling in pgm_fill_old_pins()
psagi Jun 5, 2023
563afde
PPI: VCC_DETECT pin handling when HVSP is supported
psagi Jun 5, 2023
d446c39
VCC detection in HVSP latching
psagi Jun 10, 2023
2d723f7
dapa_hvsp: prevent VCC leaking from PPI to MCU, adjust delay before c…
psagi Jun 10, 2023
9664b1f
dapa_hvsp: revert to simple driving of SCI
psagi Jun 24, 2023
6992452
FIX: clock polarity (dapa_hvsp)
psagi Jun 24, 2023
78628ed
HVSP: wait for AVR ready instead of static delay when latching
psagi Jun 25, 2023
fbcaad9
FIX: bitbang_wait_for_signal_hvsp(): timeout calculation
psagi Jun 25, 2023
0c4b6c5
dapa_hvsp documentation link added
psagi Jun 26, 2023
7b8ea37
Revert to default build options.
psagi Jun 26, 2023
30c0437
Description for HVSP commands added.
psagi Jul 1, 2023
205d06d
term.c is used by libavrdude
psagi Jul 1, 2023
d862c82
fix merge conflict of src/CMakeLists.txt
psagi Jul 1, 2023
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 6 additions & 4 deletions src/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -145,6 +145,8 @@ add_library(libavrdude
avrftdi_private.h
avrftdi_tpi.c
avrftdi_tpi.h
avrintel.c
avrintel.h
avrpart.c
bitbang.c
bitbang.h
Expand All @@ -167,6 +169,8 @@ add_library(libavrdude
freebsd_ppi.h
ft245r.c
ft245r.h
hvsp.c
hvsp.h
jtagmkI.c
jtagmkI.h
jtagmkI_private.h
Expand Down Expand Up @@ -214,6 +218,8 @@ add_library(libavrdude
stk500generic.h
teensy.c
teensy.h
term.c
term.h
tpi.h
updi_constants.h
updi_link.c
Expand Down Expand Up @@ -277,10 +283,6 @@ target_link_libraries(libavrdude

add_executable(avrdude
main.c
term.c
term.h
avrintel.c
avrintel.h
developer_opts.c
developer_opts.h
developer_opts_private.h
Expand Down
134 changes: 86 additions & 48 deletions src/avr.c
Original file line number Diff line number Diff line change
Expand Up @@ -27,9 +27,11 @@
#include <string.h>
#include <sys/time.h>
#include <time.h>
#include <stdbool.h>

#include "avrdude.h"
#include "libavrdude.h"
#include "hvsp.h"

#include "tpi.h"

Expand Down Expand Up @@ -173,16 +175,64 @@ static int avr_tpi_setup_rw(const PROGRAMMER *pgm, const AVRMEM *mem,
return 0;
}

bool avr_is_there_proper_cmd(const PROGRAMMER *pgm, const AVRPART *p) {
return (
(hvsp_is_hvsp_mode(pgm, p) && pgm->cmd_hvsp != NULL) || (pgm->cmd != NULL)
);
}

void avr_get_opcode(
const PROGRAMMER *pgm, const AVRPART *p, const AVRMEM *mem, bool is_read,
unsigned long addr, OPCODE **op_instr, OPCODE **op, unsigned long *caddr
) {
if (hvsp_is_hvsp_mode(pgm, p)) {
*op_instr = mem->op[is_read ? AVR_OP_READ_HVSP_CMD : AVR_OP_WRITE_HVSP_CMD];
*op = mem->op[is_read ? AVR_OP_READ_HVSP_DATA : AVR_OP_WRITE_HVSP_DATA];
*caddr = addr;
} else {
if (mem->op[is_read ? AVR_OP_READ_LO : AVR_OP_WRITE_LO]) {
if (addr & 0x00000001)
*op = mem->op[is_read ? AVR_OP_READ_HI : AVR_OP_WRITE_HI];
else
*op = mem->op[is_read ? AVR_OP_READ_LO : AVR_OP_WRITE_LO];
*caddr = addr / 2;
} else if ((!is_read) && (mem->paged && mem->op[AVR_OP_LOADPAGE_LO])) {
if (addr & 0x00000001)
*op = mem->op[AVR_OP_LOADPAGE_HI];
else
*op = mem->op[AVR_OP_LOADPAGE_LO];
*caddr = addr / 2;
} else {
*op = mem->op[is_read ? AVR_OP_READ : AVR_OP_WRITE];
*caddr = addr;
}
}
}

void avr_prepare_cmd(
const OPCODE * op, const OPCODE * op_instr, unsigned long addr, bool is_read,
unsigned char data, unsigned char *cmd, size_t cmd_size,
unsigned char *cmd_instr, size_t cmd_instr_size
) {
memset(cmd, 0, cmd_size);
memset(cmd_instr, 0, cmd_instr_size);

avr_set_bits(op, cmd);
if (op_instr) avr_set_bits(op_instr, cmd_instr);
avr_set_addr(op, cmd, addr);
if (!is_read) avr_set_input(op, cmd, data);
}

int avr_read_byte_default(const PROGRAMMER *pgm, const AVRPART *p, const AVRMEM *mem,
unsigned long addr, unsigned char * value)
{
unsigned char cmd[4];
unsigned char cmd[4], cmd_instr[4];
unsigned char res[4];
unsigned char data;
int r;
OPCODE * readop, * lext;
OPCODE * readop, * readop_cmd = NULL, 8000 * lext;

if (pgm->cmd == NULL) {
if (!avr_is_there_proper_cmd(pgm, p)) {
pmsg_error("%s programmer uses avr_read_byte_default() but does not\n", pgm->type);
imsg_error("provide a cmd() method\n");
return -1;
Expand Down Expand Up @@ -214,17 +264,7 @@ int avr_read_byte_default(const PROGRAMMER *pgm, const AVRPART *p, const AVRMEM
/*
* figure out what opcode to use
*/
if (mem->op[AVR_OP_READ_LO]) {
if (addr & 0x00000001)
readop = mem->op[AVR_OP_READ_HI];
else
readop = mem->op[AVR_OP_READ_LO];
addr = addr / 2;
}
else {
readop = mem->op[AVR_OP_READ];
}

avr_get_opcode(pgm, p, mem, true, addr, &readop_cmd, &readop, &addr);
if (readop == NULL) {
#if DEBUG
pmsg_error("operation not supported on memory type %s\n", mem->desc);
Expand All @@ -246,11 +286,12 @@ int avr_read_byte_default(const PROGRAMMER *pgm, const AVRPART *p, const AVRMEM
return r;
}

memset(cmd, 0, sizeof(cmd));

avr_set_bits(readop, cmd);
avr_set_addr(readop, cmd, addr);
r = pgm->cmd(pgm, cmd, res);
avr_prepare_cmd(
readop, readop_cmd, addr, true, 0, cmd, sizeof(cmd), cmd_instr,
sizeof(cmd_instr)
);
if (hvsp_is_hvsp_mode(pgm, p)) r = pgm->cmd_hvsp(pgm, cmd_instr, cmd, res);
else r = pgm->cmd(pgm, cmd, res);
if (r < 0)
return r;
data = 0;
Expand Down Expand Up @@ -560,24 +601,32 @@ double avr_timestamp() {
return avr_ustimestamp()/1e6;
}

bool avr_wait_for_avr_rdy(
const PROGRAMMER *pgm, const AVRPART *p, int timeout_us
) {
return (
(!pgm->wait_for_avr_ready) ||
pgm->wait_for_avr_ready(pgm, p, timeout_us, timeout_us / 4)
);
}

int avr_write_byte_default(const PROGRAMMER *pgm, const AVRPART *p, const AVRMEM *mem,
unsigned long addr, unsigned char data)
{
unsigned char cmd[4];
unsigned char cmd[4], cmd_instr[4];
unsigned char res[4];
unsigned char r;
int ready;
int tries;
unsigned long start_time;
unsigned long prog_time;
unsigned char b;
unsigned short caddr;
OPCODE * writeop;
unsigned long caddr;
OPCODE * writeop, * writeop_cmd = NULL;
int rc;
int readok=0;

if (pgm->cmd == NULL) {
if (!avr_is_there_proper_cmd(pgm, p)) {
pmsg_error("%s programmer uses avr_write_byte_default() but does not\n", pgm->type);
imsg_error("provide a cmd() method\n");
return -1;
Expand Down Expand Up @@ -659,25 +708,7 @@ int avr_write_byte_default(const PROGRAMMER *pgm, const AVRPART *p, const AVRMEM
/*
* determine which memory opcode to use
*/
if (mem->op[AVR_OP_WRITE_LO]) {
if (addr & 0x01)
writeop = mem->op[AVR_OP_WRITE_HI];
else
writeop = mem->op[AVR_OP_WRITE_LO];
caddr = addr / 2;
}
else if (mem->paged && mem->op[AVR_OP_LOADPAGE_LO]) {
if (addr & 0x01)
writeop = mem->op[AVR_OP_LOADPAGE_HI];
else
writeop = mem->op[AVR_OP_LOADPAGE_LO];
caddr = addr / 2;
}
else {
writeop = mem->op[AVR_OP_WRITE];
caddr = addr;
}

avr_get_opcode(pgm, p, mem, false, addr, &writeop_cmd, &writeop, &caddr);
if (writeop == NULL) {
#if DEBUG
pmsg_error("write not supported for memory type %s\n", mem->desc);
Expand All @@ -689,12 +720,12 @@ int avr_write_byte_default(const PROGRAMMER *pgm, const AVRPART *p, const AVRMEM
pgm->pgm_led(pgm, ON);
pgm->err_led(pgm, OFF);

memset(cmd, 0, sizeof(cmd));

avr_set_bits(writeop, cmd);
avr_set_addr(writeop, cmd, caddr);
avr_set_input(writeop, cmd, data);
pgm->cmd(pgm, cmd, res);
avr_prepare_cmd(
writeop, writeop_cmd, caddr, false, data, cmd, sizeof(cmd), cmd_instr,
sizeof(cmd_instr)
);
if (hvsp_is_hvsp_mode(pgm, p)) pgm->cmd_hvsp(pgm, cmd_instr, cmd, res);
else pgm->cmd(pgm, cmd, res);

if (mem->paged) {
/*
Expand All @@ -706,6 +737,13 @@ int avr_write_byte_default(const PROGRAMMER *pgm, const AVRPART *p, const AVRMEM
return 0;
}

if (!avr_wait_for_avr_rdy(pgm, p, mem->max_write_delay)) {
pmsg_error(
"AVR stuck busy after writing. Reset it and check what happened!"
);
return -7;
}

if (readok == 0) {
/*
* read operation not supported for this memory type, just wait
Expand Down
53 changes: 53 additions & 0 deletions src/avrdude.conf.in
Original file line number Diff line number Diff line change
Expand Up @@ -27,10 +27,12 @@
# connection_type = parallel | serial | usb | spi
# baudrate = <num> ; # baudrate for avr910-programmer
# vcc = <pin1> [, <pin2> ... ] ; # pin number(s)
# vcc_detect = <pin> ; # pin number
# buff = <pin1> [, <pin2> ... ] ; # pin number(s)
# reset = <pin> ; # pin number
# sck = <pin> ; # pin number
# sdo = <pin> ; # pin number
# sii = <pin> ; # pin number (HVSP mode)
# sdi = <pin> ; # pin number
# errled = <pin> ; # pin number
# rdyled = <pin> ; # pin number
Expand Down Expand Up @@ -183,6 +185,10 @@
# loadpage_lo = <instruction format> ;
# loadpage_hi = <instruction format> ;
# writepage = <instruction format> ;
# read_hvsp_data = <instruction format> ;
# read_hvsp_cmd = <instruction format> ;
# write_hvsp_data = <instruction format> ;
# write_hvsp_cmd = <instruction format> ;
# ;
# ;
#
Expand Down Expand Up @@ -279,6 +285,15 @@
#
# loadpage_lo = "0100.0000", "000x.xxxx", "xxaa.aaaa", "iiii.iiii";
#
# HVSP COMMANDS
#
# In High-Voltage Serial Programming mode two input pins of the MCU are used:
# one for inputting the 'instruction' (SII) and one that respects output bits# besides constant, address and data bits (SDI) - just like in case of the
# SPI instuctions. The corresponding bit-strings are specified using the
# [read|write]_hvsp_cmd and the [read|write]_hvsp_data configuration elements
# respectively.
# More information on HVSP is in section 20.6-7 of
# https://ww1.microchip.com/downloads/en/DeviceDoc/Atmel-2586-AVR-8-bit-Microcontroller-ATtiny25-ATtiny45-ATtiny85_Datasheet.pdf
#
# The following are STK500 part device codes to use for the
# "devicecode" field of the part. These came from Atmel's software
Expand Down Expand Up @@ -610,6 +625,23 @@ programmer
sdi = 11;
;

#------------------------------------------------------------
# dapa_hvsp
#------------------------------------------------------------

programmer
id = "dapa_hvsp";
desc = "Direct AVR Parallel Access cable for HVSP mode <https://pety.dynu.net/dapa_hvsp/>";
type = "par";
prog_modes = PM_HVSP;
reset = ~16; /* RESET (0V) on HIGH and 12V on LOW */
sck = 1; /* SCI in HVSP */
sdo = 2; /* SDI in HVSP */
sii = 3;
sdi = 11; /* SDO in HVSP */
vcc_detect = 10;
;

#------------------------------------------------------------
# atisp
#------------------------------------------------------------
Expand Down Expand Up @@ -9244,6 +9276,12 @@ part
max_write_delay = 9000;
read = "0101.0000--0000.0000--xxxx.xxxx--oooo.oooo";
write = "1010.1100--1010.0000--xxxx.xxxx--iiii.iiii";
read_hvsp_cmd = "0100.1100--0110.1000--0110.1100--0100.1100";
read_hvsp_data = "0000.0100--0000.0000--oooo.oooo--0000.0000";
# HVSP fuse read command is padded w/ "No Operation" command to
# preserve the 4bytes command length
write_hvsp_cmd = "0100.1100--0010.1100--0110.0100--0110.1100";
write_hvsp_data = "0100.0000--iiii.iiii--0000.0000--0000.0000";
;

memory "hfuse"
Expand All @@ -9252,6 +9290,12 @@ part
max_write_delay = 9000;
read = "0101.1000--0000.1000--xxxx.xxxx--oooo.oooo";
write = "1010.1100--1010.1000--xxxx.xxxx--iiii.iiii";
read_hvsp_cmd = "0100.1100--0111.1010--0111.1110--0100.1100";
read_hvsp_data = "0000.0100--0000.0000--oooo.oooo--0000.0000";
# HVSP fuse read command is padded w/ "No Operation" command to
# preserve the 4bytes command length
write_hvsp_cmd = "0100.1100--0010.1100--0111.0100--0111.1100";
write_hvsp_data = "0100.0000--iiii.iiii--0000.0000--0000.0000";
;

memory "efuse"
Expand All @@ -9260,6 +9304,12 @@ part
max_write_delay = 9000;
read = "0101.0000--0000.1000--xxxx.xxxx--oooo.oooo";
write = "1010.1100--1010.0100--xxxx.xxxx--xxxx.xxxi";
read_hvsp_cmd = "0100.1100--0110.1010--0110.1110--0100.1100";
read_hvsp_data = "0000.0100--0000.0000--oooo.oooo--0000.0000";
# HVSP fuse read command is padded w/ "No Operation" command to
# preserve the 4bytes command length
write_hvsp_cmd = "0100.1100--0010.1100--0110.0110--0110.1110";
write_hvsp_data = "0100.1100--0000.000i--0000.0000--0000.0000";
;

memory "lock"
Expand All @@ -9273,6 +9323,9 @@ part
memory "signature"
size = 3;
read = "0011.0000--000x.xxxx--xxxx.xxaa--oooo.oooo";
read_hvsp_cmd = "0100.1100--0000.1100--0110.1000--0110.1100";
read_hvsp_data = "0000.1000", "0 0 0 0 0 0 a1 a0",
"0000.0000", "oooo.oooo";
;

memory "calibration"
Expand Down
14 changes: 14 additions & 0 deletions src/avrpart.c
Original file line number Diff line number Diff line change
Expand Up @@ -148,6 +148,8 @@ int avr_set_addr_mem(const AVRMEM *mem, int opnum, unsigned char *cmd, unsigned
case AVR_OP_READ_HI:
case AVR_OP_WRITE_LO:
case AVR_OP_WRITE_HI:
case AVR_OP_READ_HVSP_DATA:
case AVR_OP_WRITE_HVSP_DATA:
lo = 0;
hi = intlog2(memsize-1); // memsize = 1 implies no addr bit is needed
break;
Expand Down Expand Up @@ -304,6 +306,10 @@ static char * avr_op_str(int op)
case AVR_OP_WRITEPAGE : return "WRITEPAGE"; break;
case AVR_OP_CHIP_ERASE : return "CHIP_ERASE"; break;
case AVR_OP_PGM_ENABLE : return "PGM_ENABLE"; break;
case AVR_OP_READ_HVSP_CMD : return "READ_HVSP_CMD"; break;
case AVR_OP_READ_HVSP_DATA : return "READ_HVSP_DATA"; break;
case AVR_OP_WRITE_HVSP_CMD : return "WRITE_HVSP_CMD"; break;
case AVR_OP_WRITE_HVSP_DATA : return "WRITE_HVSP_DATA"; break;
default : return "<unknown opcode>"; break;
}
}
Expand Down Expand Up @@ -843,6 +849,14 @@ const char *opcodename(int opnum) {
return "chip_erase";
case AVR_OP_PGM_ENABLE:
return "pgm_enable";
case AVR_OP_READ_HVSP_CMD:
return "read_hvsp_cmd";
case AVR_OP_READ_HVSP_DATA:
return "read_hvsp_data";
case AVR_OP_WRITE_HVSP_CMD:
return "write_hvsp_cmd";
case AVR_OP_WRITE_HVSP_DATA:
return "write_hvsp_data";
default:
return "???";
}
Expand Down
Loading
0