Merge pull request #816 from andrewshadura/usbtiny-spi
Add SPI support to USBtiny
This commit is contained in:
commit
490558049e
|
@ -838,7 +838,7 @@ Display the device signature bytes.
|
||||||
Enter direct SPI mode. The
|
Enter direct SPI mode. The
|
||||||
.Em pgmled
|
.Em pgmled
|
||||||
pin acts as slave select.
|
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
|
.It Ar part
|
||||||
Display the current part settings and parameters. Includes chip
|
Display the current part settings and parameters. Includes chip
|
||||||
specific information including all memory types supported by the
|
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
|
.Pp
|
||||||
The USBasp and USBtinyISP drivers do not offer any option to distinguish multiple
|
The USBasp and USBtinyISP drivers do not offer any option to distinguish multiple
|
||||||
devices connected simultaneously, so effectively only a single device
|
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
|
.Pp
|
||||||
The avrftdi driver allows one to select specific devices using any combination of vid,pid
|
The avrftdi driver allows one to select specific devices using any combination of vid,pid
|
||||||
serial number (usbsn) vendor description (usbvendoror part description (usbproduct)
|
serial number (usbsn) vendor description (usbvendoror part description (usbproduct)
|
||||||
|
|
|
@ -541,6 +541,10 @@ static int cmd_sig(PROGRAMMER * pgm, struct avrpart * p,
|
||||||
static int cmd_quit(PROGRAMMER * pgm, struct avrpart * p,
|
static int cmd_quit(PROGRAMMER * pgm, struct avrpart * p,
|
||||||
int argc, char * argv[])
|
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;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -511,6 +511,20 @@ static int usbtiny_initialize (PROGRAMMER *pgm, AVRPART *p )
|
||||||
return 0;
|
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 */
|
/* Tell the USBtiny to release the output pins, etc */
|
||||||
static void usbtiny_powerdown(PROGRAMMER * pgm)
|
static void usbtiny_powerdown(PROGRAMMER * pgm)
|
||||||
{
|
{
|
||||||
|
@ -580,6 +594,27 @@ int usbtiny_cmd_tpi(PROGRAMMER * pgm, const unsigned char *cmd,
|
||||||
return 0;
|
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 */
|
/* Send the chip-erase command */
|
||||||
static int usbtiny_chip_erase(PROGRAMMER * pgm, AVRPART * p)
|
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->set_sck_period = usbtiny_set_sck_period;
|
||||||
pgm->setup = usbtiny_setup;
|
pgm->setup = usbtiny_setup;
|
||||||
pgm->teardown = usbtiny_teardown;
|
pgm->teardown = usbtiny_teardown;
|
||||||
|
pgm->setpin = usbtiny_setpin;
|
||||||
|
pgm->spi = usbtiny_spi;
|
||||||
}
|
}
|
||||||
|
|
||||||
#else /* !HAVE_LIBUSB */
|
#else /* !HAVE_LIBUSB */
|
||||||
|
|
Loading…
Reference in New Issue