Add direct SPI mode to USBtiny

It is limited to exactly sending (and receiving) multiples of 4 bytes,
and unlike programming mode where slave select isn't required, SS must
be held low for SPI to work. USBtiny programmers don't usually have
a wire for SS.
This commit is contained in:
David Fries 2015-01-01 19:16:47 -06:00 committed by Andrej Shadura
parent 112b6edd1c
commit cffa6c7ca0
No known key found for this signature in database
GPG Key ID: 2526E9EB828A8F35
1 changed files with 37 additions and 0 deletions

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 */