Submitted by Alex Sverdlin:

patch #10027: linuxspi: Add reset pulse, according to AVR programming algorithm
* linuxspi.c (linuxspi_open, linuxspi_program_enable):
movw out reset code into linuxspi_reset_mcu()



git-svn-id: svn://svn.savannah.nongnu.org/avrdude/trunk/avrdude@1490 81a1dc3b-b13d-400b-aceb-764788c761c2
This commit is contained in:
Joerg Wunsch 2021-11-27 15:40:12 +00:00
parent 6887f4f373
commit 711323e7cc
3 changed files with 57 additions and 11 deletions

View File

@ -1,3 +1,10 @@
2021-11-27 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
Submitted by Alex Sverdlin:
patch #10027: linuxspi: Add reset pulse, according to AVR programming algorithm
* linuxspi.c (linuxspi_open, linuxspi_program_enable):
movw out reset code into linuxspi_reset_mcu()
2021-11-25 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
Submitted by David Mosberger-Tang:

1
NEWS
View File

@ -117,6 +117,7 @@ Current:
patch #9757: Fix ATtiny817 Xplained Mini programmer
patch #9327: ft245r.c: add TPI support (patches 1-4)
patch #9328: ft245r.c: add TPI support (patches 5-7)
patch #10027: linuxspi: Add reset pulse, according to AVR programming algorithm
* Internals:
- New avrdude.conf keyword "family_id", used to verify SIB attributes

View File

@ -98,12 +98,32 @@ static void linuxspi_teardown(PROGRAMMER* pgm)
{
}
static int linuxspi_reset_mcu(PROGRAMMER *pgm, bool active)
{
struct gpiohandle_data data;
int ret;
/*
* Set the reset state and keep it. The pin will be released and set back to
* its initial value, once the fd_gpiochip is closed.
*/
data.values[0] = active ^ !(pgm->pinno[PIN_AVR_RESET] & PIN_INVERSE);
ret = ioctl(fd_linehandle, GPIOHANDLE_SET_LINE_VALUES_IOCTL, &data);
if (ret == -1) {
ret = -errno;
avrdude_message(MSG_INFO, "%s error: Unable to set GPIO line %d value\n",
progname, pgm->pinno[PIN_AVR_RESET] & ~PIN_INVERSE);
return ret;
}
return 0;
}
static int linuxspi_open(PROGRAMMER *pgm, char *port)
{
const char *port_error = "%s: error: Unknown port specification. Please use the format /dev/spidev:/dev/gpiochip[:resetno]\n";
char *spidev, *gpiochip, *reset_pin;
struct gpiohandle_request req;
struct gpiohandle_data data;
int ret;
if (!port || !strcmp(port, "unknown")) {
@ -156,16 +176,9 @@ static int linuxspi_open(PROGRAMMER *pgm, char *port)
fd_linehandle = req.fd;
/*
* Set the reset state and keep it. The pin will be released and set back to
* its initial value, once the fd_gpiochip is closed.
*/
data.values[0] = !!(pgm->pinno[PIN_AVR_RESET] & PIN_INVERSE);
ret = ioctl(fd_linehandle, GPIOHANDLE_SET_LINE_VALUES_IOCTL, &data);
if (ret == -1) {
ret = -errno;
ret = linuxspi_reset_mcu(pgm, true);
if (ret)
goto close_out;
}
return 0;
@ -239,8 +252,33 @@ static int linuxspi_program_enable(PROGRAMMER *pgm, AVRPART *p)
avr_set_bits(p->op[AVR_OP_PGM_ENABLE], cmd); //set the cmd
pgm->cmd(pgm, cmd, res);
if (res[2] != cmd[1])
if (res[2] != cmd[1]) {
/*
* From ATtiny441 datasheet:
*
* In some systems, the programmer can not guarantee that SCK is held low
* during power-up. In this case, RESET must be given a positive pulse after
* SCK has been set to '0'. The duration of the pulse must be at least t RST
* plus two CPU clock cycles. See Table 25-5 on page 240 for definition of
* minimum pulse width on RESET pin, t RST
* 2. Wait for at least 20 ms and then enable serial programming by sending
* the Programming Enable serial instruction to the MOSI pin
* 3. The serial programming instructions will not work if the communication
* is out of synchronization. When in sync, the second byte (0x53) will echo
* back when issuing the third byte of the Programming Enable instruction
* ...
* If the 0x53 did not echo back, give RESET a positive pulse and issue a
* new Programming Enable command
*/
if (linuxspi_reset_mcu(pgm, false))
return -1;
usleep(3 + (pgm->baudrate ? 500000 / pgm->baudrate : 1));
if (linuxspi_reset_mcu(pgm, true))
return -1;
usleep(20000);
return -2;
}
return 0;
}