Merge pull request #816 from andrewshadura/usbtiny-spi

Add SPI support to USBtiny
This commit is contained in:
Jörg Wunsch 2022-01-21 21:40:00 +01:00 committed by GitHub
commit 490558049e
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 44 additions and 2 deletions

View File

@ -838,7 +838,7 @@ Display the device signature bytes.
Enter direct SPI mode. The
.Em pgmled
pin acts as slave select.
.Em Only supported on parallel bitbang programmers.
.Em Only supported on parallel bitbang programmers, and partially by USBtiny.
.It Ar part
Display the current part settings and parameters. Includes chip
specific information including all memory types supported by the
@ -1282,7 +1282,8 @@ This also applies to the STK500 and STK600 in parallel programming mode.
.Pp
The USBasp and USBtinyISP drivers do not offer any option to distinguish multiple
devices connected simultaneously, so effectively only a single device
is supported.
is supported. Slave Select must be externally held low for direct SPI when
using USBtinyISP, and send must be a multiple of four bytes.
.Pp
The avrftdi driver allows one to select specific devices using any combination of vid,pid
serial number (usbsn) vendor description (usbvendoror part description (usbproduct)

View File

@ -541,6 +541,10 @@ static int cmd_sig(PROGRAMMER * pgm, struct avrpart * p,
static int cmd_quit(PROGRAMMER * pgm, struct avrpart * p,
int argc, char * argv[])
{
/* FUSE bit verify will fail if left in SPI mode */
if (spi_mode) {
cmd_pgm(pgm, p, 0, NULL);
}
return 1;
}

View File

@ -511,6 +511,20 @@ static int usbtiny_initialize (PROGRAMMER *pgm, AVRPART *p )
return 0;
}
static int usbtiny_setpin(struct programmer_t * pgm, int pinfunc, int value)
{
/* USBtiny is not a bit bang device, but it can set RESET */
if(pinfunc == PIN_AVR_RESET) {
if (usb_control(pgm, USBTINY_POWERUP,
PDATA(pgm)->sck_period, value ? RESET_HIGH : RESET_LOW) < 0) {
return -1;
}
usleep(50000);
return 0;
}
return -1;
}
/* Tell the USBtiny to release the output pins, etc */
static void usbtiny_powerdown(PROGRAMMER * pgm)
{
@ -580,6 +594,27 @@ int usbtiny_cmd_tpi(PROGRAMMER * pgm, const unsigned char *cmd,
return 0;
}
static int usbtiny_spi(struct programmer_t * pgm, const unsigned char *cmd, unsigned char *res, int count)
{
int i;
// Clear the receive buffer so we don't read old data in case of failure
memset(res, 0, count);
if (count % 4) {
avrdude_message(MSG_INFO, "Direct SPI write must be a multiple of 4 bytes for %s\n",
pgm->type);
return -1;
}
for (i = 0; i < count; i += 4) {
if (usbtiny_cmd(pgm, cmd + i, res + i) < 0) {
return -1;
}
}
return 0;
}
/* Send the chip-erase command */
static int usbtiny_chip_erase(PROGRAMMER * pgm, AVRPART * p)
{
@ -759,6 +794,8 @@ void usbtiny_initpgm ( PROGRAMMER* pgm )
pgm->set_sck_period = usbtiny_set_sck_period;
pgm->setup = usbtiny_setup;
pgm->teardown = usbtiny_teardown;
pgm->setpin = usbtiny_setpin;
pgm->spi = usbtiny_spi;
}
#else /* !HAVE_LIBUSB */