mirror of
https://github.com/avrdudes/avrdude.git
synced 2026-09-21 08:36:29 +03:00
Reformat spacing/comments in src/usbtiny.c
This commit is contained in:
583
src/usbtiny.c
583
src/usbtiny.c
@@ -38,34 +38,32 @@
|
||||
#include "usbtiny.h"
|
||||
#include "usbdevs.h"
|
||||
|
||||
#if defined(HAVE_LIBUSB) // we use LIBUSB to talk to the board
|
||||
#if defined(HAVE_LIBUSB) // We use LIBUSB to talk to the board
|
||||
|
||||
#if defined(HAVE_USB_H)
|
||||
# include <usb.h>
|
||||
#include <usb.h>
|
||||
#elif defined(HAVE_LUSB0_USB_H)
|
||||
# include <lusb0_usb.h>
|
||||
#include <lusb0_usb.h>
|
||||
#else
|
||||
# error "libusb needs either <usb.h> or <lusb0_usb.h>"
|
||||
#error "libusb needs either <usb.h> or <lusb0_usb.h>"
|
||||
#endif
|
||||
|
||||
#include "tpi.h"
|
||||
|
||||
#define TPIPCR_GT_0b 0x07
|
||||
#define TPI_STOP_BITS 0x03
|
||||
#define TPIPCR_GT_0b 0x07
|
||||
#define TPI_STOP_BITS 0x03
|
||||
|
||||
#define LITTLE_TO_BIG_16(x) ((((x) << 8) & 0xFF00) | (((x) >> 8) & 0x00FF))
|
||||
|
||||
#ifndef HAVE_UINT_T
|
||||
typedef unsigned int uint_t;
|
||||
#endif
|
||||
#ifndef HAVE_ULONG_T
|
||||
typedef unsigned long ulong_t;
|
||||
typedef unsigned int uint_t;
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Private data for this programmer.
|
||||
*/
|
||||
struct pdata
|
||||
{
|
||||
#ifndef HAVE_ULONG_T
|
||||
typedef unsigned long ulong_t;
|
||||
#endif
|
||||
|
||||
struct pdata {
|
||||
usb_dev_handle *usb_handle;
|
||||
int sck_period;
|
||||
int chunk_size;
|
||||
@@ -86,17 +84,17 @@ static void usbtiny_teardown(PROGRAMMER *pgm) {
|
||||
}
|
||||
|
||||
// Wrapper for simple usb_control_msg messages
|
||||
static int usb_control(const PROGRAMMER *pgm,
|
||||
unsigned int requestid, unsigned int val, unsigned int index, int silent) {
|
||||
static int usb_control(const PROGRAMMER *pgm, unsigned int requestid,
|
||||
unsigned int val, unsigned int index, int silent) {
|
||||
|
||||
int nbytes;
|
||||
nbytes = usb_control_msg( PDATA(pgm)->usb_handle,
|
||||
USB_ENDPOINT_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
|
||||
requestid,
|
||||
val, index, // 2 bytes each of data
|
||||
NULL, 0, // no data buffer in control message
|
||||
USB_TIMEOUT ); // default timeout
|
||||
if(nbytes < 0){
|
||||
|
||||
nbytes = usb_control_msg(PDATA(pgm)->usb_handle,
|
||||
USB_ENDPOINT_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE, requestid,
|
||||
val, index, // 2 bytes each of data
|
||||
NULL, 0, // No data buffer in control message
|
||||
USB_TIMEOUT); // Default timeout
|
||||
if(nbytes < 0) {
|
||||
cx->usb_access_error = 1;
|
||||
if(!silent) {
|
||||
msg_error("\n");
|
||||
@@ -109,26 +107,22 @@ static int usb_control(const PROGRAMMER *pgm,
|
||||
}
|
||||
|
||||
// Wrapper for simple usb_control_msg messages to receive data from programmer
|
||||
static int usb_in (const PROGRAMMER *pgm,
|
||||
unsigned int requestid, unsigned int val, unsigned int index,
|
||||
unsigned char* buffer, int buflen, int bitclk )
|
||||
{
|
||||
static int usb_in(const PROGRAMMER *pgm,
|
||||
unsigned int requestid, unsigned int val, unsigned int index, unsigned char *buffer, int buflen, int bitclk) {
|
||||
int nbytes;
|
||||
int timeout;
|
||||
int i;
|
||||
|
||||
// calculate the amount of time we expect the process to take by
|
||||
// figuring the bit-clock time and buffer size and adding to the standard USB timeout.
|
||||
timeout = USB_TIMEOUT + (buflen * bitclk) / 1000;
|
||||
/*
|
||||
* Calculate the amount of time we expect the process to take by figuring the
|
||||
* bit-clock time and buffer size and adding to the standard USB timeout.
|
||||
*/
|
||||
timeout = USB_TIMEOUT + (buflen*bitclk)/1000;
|
||||
|
||||
for (i = 0; i < 10; i++) {
|
||||
nbytes = usb_control_msg( PDATA(pgm)->usb_handle,
|
||||
USB_ENDPOINT_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
|
||||
requestid,
|
||||
val, index,
|
||||
(char *)buffer, buflen,
|
||||
timeout);
|
||||
if (nbytes == buflen) {
|
||||
for(i = 0; i < 10; i++) {
|
||||
nbytes = usb_control_msg(PDATA(pgm)->usb_handle,
|
||||
USB_ENDPOINT_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE, requestid, val, index, (char *) buffer, buflen, timeout);
|
||||
if(nbytes == buflen) {
|
||||
return nbytes;
|
||||
}
|
||||
PDATA(pgm)->retries++;
|
||||
@@ -139,31 +133,27 @@ static int usb_in (const PROGRAMMER *pgm,
|
||||
}
|
||||
|
||||
// Report the number of retries, and reset the counter.
|
||||
static void check_retries (const PROGRAMMER *pgm, const char *operation) {
|
||||
if (PDATA(pgm)->retries > 0)
|
||||
static void check_retries(const PROGRAMMER *pgm, const char *operation) {
|
||||
if(PDATA(pgm)->retries > 0)
|
||||
pmsg_info("%d retries during %s\n", PDATA(pgm)->retries, operation);
|
||||
PDATA(pgm)->retries = 0;
|
||||
}
|
||||
|
||||
// Wrapper for simple usb_control_msg messages to send data to programmer
|
||||
static int usb_out (const PROGRAMMER *pgm,
|
||||
unsigned int requestid, unsigned int val, unsigned int index,
|
||||
unsigned char* buffer, int buflen, int bitclk )
|
||||
{
|
||||
static int usb_out(const PROGRAMMER *pgm,
|
||||
unsigned int requestid, unsigned int val, unsigned int index, unsigned char *buffer, int buflen, int bitclk) {
|
||||
int nbytes;
|
||||
int timeout;
|
||||
|
||||
// calculate the amount of time we expect the process to take by
|
||||
// figuring the bit-clock time and buffer size and adding to the standard USB timeout.
|
||||
timeout = USB_TIMEOUT + (buflen * bitclk) / 1000;
|
||||
/*
|
||||
* Calculate the amount of time we expect the process to take by figuring the
|
||||
* bit-clock time and buffer size and adding to the standard USB timeout.
|
||||
*/
|
||||
timeout = USB_TIMEOUT + (buflen*bitclk)/1000;
|
||||
|
||||
nbytes = usb_control_msg( PDATA(pgm)->usb_handle,
|
||||
USB_ENDPOINT_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
|
||||
requestid,
|
||||
val, index,
|
||||
(char *)buffer, buflen,
|
||||
timeout);
|
||||
if (nbytes != buflen) {
|
||||
nbytes = usb_control_msg(PDATA(pgm)->usb_handle,
|
||||
USB_ENDPOINT_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE, requestid, val, index, (char *) buffer, buflen, timeout);
|
||||
if(nbytes != buflen) {
|
||||
msg_error("\n");
|
||||
pmsg_error("%s (expected %d, got %d)\n", usb_strerror(), buflen, nbytes);
|
||||
return -1;
|
||||
@@ -175,8 +165,7 @@ static int usb_out (const PROGRAMMER *pgm,
|
||||
/* Reverse the bits in a byte. Needed since TPI uses little-endian
|
||||
bit order (LSB first) whereas SPI uses big-endian (MSB first).*/
|
||||
static unsigned char reverse(unsigned char b) {
|
||||
return
|
||||
( (b & 0x01) << 7)
|
||||
return ((b & 0x01) << 7)
|
||||
| ((b & 0x02) << 5)
|
||||
| ((b & 0x04) << 3)
|
||||
| ((b & 0x08) << 1)
|
||||
@@ -186,82 +175,79 @@ static unsigned char reverse(unsigned char b) {
|
||||
| ((b & 0x80) >> 7);
|
||||
}
|
||||
|
||||
/* Calculate even parity. */
|
||||
static unsigned char tpi_parity(unsigned char b)
|
||||
{
|
||||
// Calculate even parity
|
||||
static unsigned char tpi_parity(unsigned char b) {
|
||||
unsigned char parity = 0;
|
||||
int i;
|
||||
|
||||
for (i = 0; i < 8; ++i) {
|
||||
if (b & 1)
|
||||
for(i = 0; i < 8; ++i) {
|
||||
if(b & 1)
|
||||
parity ^= 1;
|
||||
b >>= 1;
|
||||
}
|
||||
return parity;
|
||||
}
|
||||
|
||||
/* Encode 1 start bit (0), 8 data bits, 1 parity, 2 stop bits (1)
|
||||
inside 16 bits. The data is padded to 16 bits by 4 leading 1s
|
||||
(which will be ignored since they're not start bits). This layout
|
||||
enables a write to be followed by a read. */
|
||||
/*
|
||||
* Encode 1 start bit (0), 8 data bits, 1 parity, 2 stop bits (1) inside 16
|
||||
* bits. The data is padded to 16 bits by 4 leading 1s (which will be ignored
|
||||
* since they're not start bits). This layout enables a write to be followed by
|
||||
* a read
|
||||
*/
|
||||
static unsigned short tpi_frame(unsigned char b) {
|
||||
return LITTLE_TO_BIG_16(0xf000 |
|
||||
(reverse(b) << 3) |
|
||||
tpi_parity(b) << 2 |
|
||||
TPI_STOP_BITS);
|
||||
return LITTLE_TO_BIG_16(0xf000 | (reverse(b) << 3) | tpi_parity(b) << 2 | TPI_STOP_BITS);
|
||||
}
|
||||
|
||||
/* Transmit a single byte encapsulated in a 32-bit transfer. Unused
|
||||
bits are padded with 1s. */
|
||||
// Transmit a single byte encapsulated in a 32-bit transfer; unused bits are padded with 1s
|
||||
static int usbtiny_tpi_tx(const PROGRAMMER *pgm, unsigned char b0) {
|
||||
unsigned char res[4];
|
||||
|
||||
if (usb_in(pgm, USBTINY_SPI, tpi_frame(b0), 0xffff,
|
||||
res, sizeof(res), 8 * sizeof(res) * PDATA(pgm)->sck_period) < 0)
|
||||
if(usb_in(pgm, USBTINY_SPI, tpi_frame(b0), 0xffff, res, sizeof(res), 8*sizeof(res)*PDATA(pgm)->sck_period) < 0)
|
||||
return -1;
|
||||
msg_debug("CMD_TPI_TX: [0x%02x]\n", b0);
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* Transmit a two bytes encapsulated in a 32-bit transfer. Unused
|
||||
bits are padded with 1s. */
|
||||
static int usbtiny_tpi_txtx(const PROGRAMMER *pgm,
|
||||
unsigned char b0, unsigned char b1)
|
||||
{
|
||||
// Transmit a two bytes encapsulated in a 32-bit transfer; unused bits are padded with 1s
|
||||
static int usbtiny_tpi_txtx(const PROGRAMMER *pgm, unsigned char b0, unsigned char b1) {
|
||||
unsigned char res[4];
|
||||
|
||||
if (usb_in(pgm, USBTINY_SPI, tpi_frame(b0), tpi_frame(b1),
|
||||
res, sizeof(res), 8 * sizeof(res) * PDATA(pgm)->sck_period) < 0)
|
||||
if(usb_in(pgm, USBTINY_SPI, tpi_frame(b0), tpi_frame(b1), res, sizeof(res),
|
||||
8*sizeof(res)*PDATA(pgm)->sck_period) < 0) {
|
||||
|
||||
return -1;
|
||||
}
|
||||
msg_debug("CMD_TPI_TX_TX: [0x%02x 0x%02x]\n", b0, b1);
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* Transmit a byte then receive a byte, all encapsulated in a 32-bit
|
||||
transfer. Unused bits are padded with 1s. This code assumes that
|
||||
the start bit of the byte being received arrives within at most 2
|
||||
TPICLKs. We ensure this by calling avr_tpi_program_enable() with
|
||||
delay==TPIPCR_GT_0b. */
|
||||
/*
|
||||
* Transmit a byte then receive a byte, all encapsulated in a 32-bit transfer.
|
||||
* Unused bits are padded with 1s. This code assumes that the start bit of the
|
||||
* byte being received arrives within at most 2 TPICLKs. We ensure this by
|
||||
* calling avr_tpi_program_enable() with delay==TPIPCR_GT_0b.
|
||||
*/
|
||||
static int usbtiny_tpi_txrx(const PROGRAMMER *pgm, unsigned char b0) {
|
||||
unsigned char res[4], r;
|
||||
short w;
|
||||
|
||||
if (usb_in(pgm, USBTINY_SPI, tpi_frame(b0), 0xffff,
|
||||
res, sizeof(res), 8 * sizeof(res) * PDATA(pgm)->sck_period) < 0)
|
||||
if(usb_in(pgm, USBTINY_SPI, tpi_frame(b0), 0xffff, res, sizeof(res), 8*sizeof(res)*PDATA(pgm)->sck_period) < 0)
|
||||
return -1;
|
||||
|
||||
w = (res[2] << 8) | res[3];
|
||||
/* Look for start bit (there should be no more than two 1 bits): */
|
||||
while (w < 0)
|
||||
// Look for start bit (there should be no more than two 1 bits)
|
||||
while(w < 0)
|
||||
w <<= 1;
|
||||
/* Now that we found the start bit, the top 9 bits contain the start
|
||||
bit and the 8 data bits, but the latter in reverse order. */
|
||||
/*
|
||||
* Now that we found the start bit, the top 9 bits contain the start bit and
|
||||
* the 8 data bits, but the latter in reverse order
|
||||
*/
|
||||
r = reverse(w >> 7);
|
||||
if (tpi_parity(r) != ((w >> 6) & 1)) {
|
||||
if(tpi_parity(r) != ((w >> 6) & 1)) {
|
||||
pmsg_error("parity bit is wrong\n");
|
||||
return -1;
|
||||
}
|
||||
if (((w >> 4) & 0x3) != TPI_STOP_BITS) {
|
||||
if(((w >> 4) & 0x3) != TPI_STOP_BITS) {
|
||||
pmsg_error("stop bits not received correctly\n");
|
||||
return -1;
|
||||
}
|
||||
@@ -270,17 +256,16 @@ static int usbtiny_tpi_txrx(const PROGRAMMER *pgm, unsigned char b0) {
|
||||
return r;
|
||||
}
|
||||
|
||||
// Sometimes we just need to know the SPI command for the part to perform
|
||||
// a function. Here we wrap this request for an operation so that we
|
||||
// can just specify the part and operation and it'll do the right stuff
|
||||
// to get the information from AvrDude and send to the USBtiny
|
||||
static int usbtiny_avr_op (const PROGRAMMER *pgm, const AVRPART *p,
|
||||
int op,
|
||||
unsigned char *res)
|
||||
{
|
||||
unsigned char cmd[4];
|
||||
/*
|
||||
* Sometimes we just need to know the SPI command for the part to perform a
|
||||
* function. Here we wrap this request for an operation so that we can just
|
||||
* specify the part and operation and it'll do the right stuff to get the
|
||||
* information from AvrDude and send to the USBtiny.
|
||||
*/
|
||||
static int usbtiny_avr_op(const PROGRAMMER *pgm, const AVRPART *p, int op, unsigned char *res) {
|
||||
unsigned char cmd[4];
|
||||
|
||||
if (p->op[op] == NULL) {
|
||||
if(p->op[op] == NULL) {
|
||||
pmsg_error("operation %d not defined for this chip\n", op);
|
||||
return -1;
|
||||
}
|
||||
@@ -292,69 +277,66 @@ static int usbtiny_avr_op (const PROGRAMMER *pgm, const AVRPART *p,
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
|
||||
/* Find a device with the correct VID/PID match for USBtiny */
|
||||
// Find a device with the correct VID/PID match for USBtiny
|
||||
|
||||
static int usbtiny_open(PROGRAMMER *pgm, const char *name) {
|
||||
struct usb_bus *bus;
|
||||
struct usb_device *dev = 0;
|
||||
struct usb_bus *bus;
|
||||
struct usb_device *dev = 0;
|
||||
const char *bus_name = NULL;
|
||||
char *dev_name = NULL;
|
||||
int vid, pid;
|
||||
|
||||
// if no -P was given or '-P usb' was given
|
||||
// If no -P was given or '-P usb' was given
|
||||
if(str_eq(name, "usb"))
|
||||
name = NULL;
|
||||
else {
|
||||
// calculate bus and device names from -P option
|
||||
// Calculate bus and device names from -P option
|
||||
const size_t usb_len = strlen("usb");
|
||||
|
||||
if(str_starts(name, "usb") && ':' == name[usb_len]) {
|
||||
bus_name = name + usb_len + 1;
|
||||
dev_name = strchr(bus_name, ':');
|
||||
if(NULL != dev_name)
|
||||
*dev_name++ = '\0';
|
||||
bus_name = name + usb_len + 1;
|
||||
dev_name = strchr(bus_name, ':');
|
||||
if(NULL != dev_name)
|
||||
*dev_name++ = '\0';
|
||||
}
|
||||
}
|
||||
|
||||
usb_init(); // initialize the libusb system
|
||||
usb_find_busses(); // have libusb scan all the usb buses available
|
||||
usb_find_devices(); // have libusb scan all the usb devices available
|
||||
usb_init(); // Initialize the libusb system
|
||||
usb_find_busses(); // Have libusb scan all the usb buses available
|
||||
usb_find_devices(); // Have libusb scan all the usb devices available
|
||||
|
||||
PDATA(pgm)->usb_handle = NULL;
|
||||
|
||||
if (pgm->usbvid)
|
||||
if(pgm->usbvid)
|
||||
vid = pgm->usbvid;
|
||||
else
|
||||
vid = USBTINY_VENDOR_DEFAULT;
|
||||
|
||||
LNODEID usbpid = lfirst(pgm->usbpid);
|
||||
if (usbpid) {
|
||||
pid = *(int *)(ldata(usbpid));
|
||||
if (lnext(usbpid))
|
||||
|
||||
if(usbpid) {
|
||||
pid = *(int *) (ldata(usbpid));
|
||||
if(lnext(usbpid))
|
||||
pmsg_warning("using PID 0x%04x, ignoring remaining PIDs in list\n", pid);
|
||||
} else {
|
||||
pid = USBTINY_PRODUCT_DEFAULT;
|
||||
}
|
||||
|
||||
|
||||
// now we iterate through all the buses and devices
|
||||
for ( bus = usb_busses; bus; bus = bus->next ) {
|
||||
for ( dev = bus->devices; dev; dev = dev->next ) {
|
||||
if (dev->descriptor.idVendor == vid
|
||||
&& dev->descriptor.idProduct == pid ) { // found match?
|
||||
pmsg_debug("%s(): found USBtinyISP, bus:device: %s:%s\n", __func__, bus->dirname, dev->filename);
|
||||
// if -P was given, match device by device name and bus name
|
||||
if(name != NULL &&
|
||||
(NULL == dev_name ||
|
||||
!str_eq(bus->dirname, bus_name) ||
|
||||
!str_eq(dev->filename, dev_name)))
|
||||
continue;
|
||||
PDATA(pgm)->usb_handle = usb_open(dev); // attempt to connect to device
|
||||
// Now we iterate through all the buses and devices
|
||||
for(bus = usb_busses; bus; bus = bus->next) {
|
||||
for(dev = bus->devices; dev; dev = dev->next) {
|
||||
if(dev->descriptor.idVendor == vid && dev->descriptor.idProduct == pid) { // Found match?
|
||||
pmsg_debug("%s(): found USBtinyISP, bus:device: %s:%s\n", __func__, bus->dirname, dev->filename);
|
||||
// If -P was given, match device by device name and bus name
|
||||
if(name != NULL && (NULL == dev_name || !str_eq(bus->dirname, bus_name) || !str_eq(dev->filename, dev_name)))
|
||||
continue;
|
||||
PDATA(pgm)->usb_handle = usb_open(dev); // Attempt to connect to device
|
||||
|
||||
// wrong permissions or something?
|
||||
if (!PDATA(pgm)->usb_handle) {
|
||||
pmsg_warning("cannot open USB device: %s\n", usb_strerror());
|
||||
continue;
|
||||
}
|
||||
// Wrong permissions or something?
|
||||
if(!PDATA(pgm)->usb_handle) {
|
||||
pmsg_warning("cannot open USB device: %s\n", usb_strerror());
|
||||
continue;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -363,31 +345,28 @@ static int usbtiny_open(PROGRAMMER *pgm, const char *name) {
|
||||
pmsg_error("invalid -P %s; use -P usb:bus:device\n", name);
|
||||
return -1;
|
||||
}
|
||||
if (!PDATA(pgm)->usb_handle) {
|
||||
pmsg_error("cannot find USBtiny device (0x%x/0x%x)\n", vid, pid );
|
||||
if(!PDATA(pgm)->usb_handle) {
|
||||
pmsg_error("cannot find USBtiny device (0x%x/0x%x)\n", vid, pid);
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0; // If we got here, we must have found a good USB device
|
||||
return 0; // If we got here, we must have found a good USB device
|
||||
}
|
||||
|
||||
/* Clean up the handle for the usbtiny */
|
||||
static void usbtiny_close ( PROGRAMMER* pgm )
|
||||
{
|
||||
if (! PDATA(pgm)->usb_handle) {
|
||||
return; // not a valid handle, bail!
|
||||
}
|
||||
usb_close(PDATA(pgm)->usb_handle); // ask libusb to clean up
|
||||
// Clean up the handle for the usbtiny
|
||||
static void usbtiny_close(PROGRAMMER *pgm) {
|
||||
if(!PDATA(pgm)->usb_handle) // Not a valid handle, bail!
|
||||
return;
|
||||
usb_close(PDATA(pgm)->usb_handle); // Ask libusb to clean up
|
||||
PDATA(pgm)->usb_handle = NULL;
|
||||
}
|
||||
|
||||
/* A simple calculator function determines the maximum size of data we can
|
||||
shove through a USB connection without getting errors */
|
||||
static void usbtiny_set_chunk_size (const PROGRAMMER *pgm, int period) {
|
||||
PDATA(pgm)->chunk_size = CHUNK_SIZE; // start with the maximum (default)
|
||||
while (PDATA(pgm)->chunk_size > 8 && period > 16) {
|
||||
// Reduce the chunk size for a slow SCK to reduce
|
||||
// the maximum time of a single USB transfer.
|
||||
static void usbtiny_set_chunk_size(const PROGRAMMER *pgm, int period) {
|
||||
PDATA(pgm)->chunk_size = CHUNK_SIZE; // Start with the maximum (default)
|
||||
while(PDATA(pgm)->chunk_size > 8 && period > 16) {
|
||||
// Reduce the chunk size for a slow SCK to reduce the maximum time of a single USB transfer
|
||||
PDATA(pgm)->chunk_size >>= 1;
|
||||
period >>= 1;
|
||||
}
|
||||
@@ -395,45 +374,41 @@ static void usbtiny_set_chunk_size (const PROGRAMMER *pgm, int period) {
|
||||
|
||||
/* Given a SCK bit-clock speed (in useconds) we verify its an OK speed and tell the
|
||||
USBtiny to update itself to the new frequency */
|
||||
static int usbtiny_set_sck_period (const PROGRAMMER *pgm, double v) {
|
||||
PDATA(pgm)->sck_period = (int)(v * 1e6 + 0.5); // convert from us to 'int', the 0.5 is for rounding up
|
||||
static int usbtiny_set_sck_period(const PROGRAMMER *pgm, double v) {
|
||||
PDATA(pgm)->sck_period = (int) (v*1e6 + 0.5); // Convert from us to int, the 0.5 is for rounding up
|
||||
|
||||
// Make sure its not 0, as that will confuse the usbtiny
|
||||
if (PDATA(pgm)->sck_period < SCK_MIN)
|
||||
if(PDATA(pgm)->sck_period < SCK_MIN)
|
||||
PDATA(pgm)->sck_period = SCK_MIN;
|
||||
|
||||
// We can't go slower, due to the byte-size of the clock variable
|
||||
if (PDATA(pgm)->sck_period > SCK_MAX)
|
||||
if(PDATA(pgm)->sck_period > SCK_MAX)
|
||||
PDATA(pgm)->sck_period = SCK_MAX;
|
||||
|
||||
pmsg_notice("setting SCK period to %d usec\n",
|
||||
PDATA(pgm)->sck_period );
|
||||
pmsg_notice("setting SCK period to %d usec\n", PDATA(pgm)->sck_period);
|
||||
|
||||
// send the command to the usbtiny device.
|
||||
// MEME: for at90's fix resetstate?
|
||||
if (usb_control(pgm, USBTINY_POWERUP, PDATA(pgm)->sck_period, RESET_LOW, 0) < 0)
|
||||
// Send the command to the usbtiny device; MEME: for at90's fix resetstate?
|
||||
if(usb_control(pgm, USBTINY_POWERUP, PDATA(pgm)->sck_period, RESET_LOW, 0) < 0)
|
||||
return -1;
|
||||
|
||||
// with the new speed, we'll have to update how much data we send per usb transfer
|
||||
// With the new speed, we'll have to update how much data we send per usb transfer
|
||||
usbtiny_set_chunk_size(pgm, PDATA(pgm)->sck_period);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static int usbtiny_initialize (const PROGRAMMER *pgm, const AVRPART *p ) {
|
||||
unsigned char res[4]; // store the response from usbtinyisp
|
||||
static int usbtiny_initialize(const PROGRAMMER *pgm, const AVRPART *p) {
|
||||
unsigned char res[4]; // Store the response from usbtinyisp
|
||||
int tries;
|
||||
|
||||
// Check for bit-clock and tell the usbtiny to adjust itself
|
||||
if (pgm->bitclock > 0.0) {
|
||||
if(pgm->bitclock > 0.0) {
|
||||
// -B option specified: convert to valid range for sck_period
|
||||
usbtiny_set_sck_period(pgm, pgm->bitclock);
|
||||
} else {
|
||||
// -B option not specified: use default
|
||||
PDATA(pgm)->sck_period = SCK_DEFAULT;
|
||||
pmsg_notice("using SCK period of %d usec\n", PDATA(pgm)->sck_period );
|
||||
if (usb_control(pgm, USBTINY_POWERUP,
|
||||
PDATA(pgm)->sck_period, RESET_LOW, 0) < 0)
|
||||
pmsg_notice("using SCK period of %d usec\n", PDATA(pgm)->sck_period);
|
||||
if(usb_control(pgm, USBTINY_POWERUP, PDATA(pgm)->sck_period, RESET_LOW, 0) < 0)
|
||||
return -1;
|
||||
usbtiny_set_chunk_size(pgm, PDATA(pgm)->sck_period);
|
||||
}
|
||||
@@ -441,51 +416,51 @@ static int usbtiny_initialize (const PROGRAMMER *pgm, const AVRPART *p ) {
|
||||
// Let the device wake up.
|
||||
usleep(50000);
|
||||
|
||||
if (p->prog_modes & PM_TPI) {
|
||||
/* Since there is a single TPIDATA line, SDO and SDI must be
|
||||
linked together through a 1kOhm resistor. Verify that
|
||||
everything we send on SDO gets mirrored back on SDI. */
|
||||
if(p->prog_modes & PM_TPI) {
|
||||
/*
|
||||
* Since there is a single TPIDATA line, SDO and SDI must be linked
|
||||
* together through a 1kOhm resistor. Verify that everything we send on
|
||||
* SDO gets mirrored back on SDI.
|
||||
*/
|
||||
msg_debug("doing SDO-SDI link check\n");
|
||||
|
||||
memset(res, 0xaa, sizeof(res));
|
||||
if (usb_in(pgm, USBTINY_SPI, LITTLE_TO_BIG_16(0x1234), LITTLE_TO_BIG_16(0x5678),
|
||||
res, 4, 32 * PDATA(pgm)->sck_period) < 0) {
|
||||
if(usb_in(pgm, USBTINY_SPI, LITTLE_TO_BIG_16(0x1234), LITTLE_TO_BIG_16(0x5678),
|
||||
res, 4, 32*PDATA(pgm)->sck_period) < 0) {
|
||||
|
||||
pmsg_error("usb_in() failed\n");
|
||||
return -1;
|
||||
}
|
||||
if (res[0] != 0x12 || res[1] != 0x34 || res[2] != 0x56 || res[3] != 0x78) {
|
||||
if(res[0] != 0x12 || res[1] != 0x34 || res[2] != 0x56 || res[3] != 0x78) {
|
||||
pmsg_error("SDO->SDI check failed (got 0x%02x 0x%02x 0x%02x 0x%02x)\n"
|
||||
"\tplease verify that SDI is connected directly to TPIDATA and\n"
|
||||
"\tSDO is connected to TPIDATA through a 1kOhm resistor\n",
|
||||
res[0], res[1], res[2], res[3]);
|
||||
"\tSDO is connected to TPIDATA through a 1kOhm resistor\n", res[0], res[1], res[2], res[3]);
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* keep TPIDATA high for >= 16 clock cycles: */
|
||||
if (usb_in(pgm, USBTINY_SPI, 0xffff, 0xffff, res, 4,
|
||||
32 * PDATA(pgm)->sck_period) < 0)
|
||||
{
|
||||
// Keep TPIDATA high for >= 16 clock cycles:
|
||||
if(usb_in(pgm, USBTINY_SPI, 0xffff, 0xffff, res, 4, 32*PDATA(pgm)->sck_period) < 0) {
|
||||
pmsg_error("unable to switch chip into TPI mode\n");
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
for (tries = 0; tries < 4; ++tries) {
|
||||
if (pgm->program_enable(pgm, p) >= 0)
|
||||
for(tries = 0; tries < 4; ++tries) {
|
||||
if(pgm->program_enable(pgm, p) >= 0)
|
||||
break;
|
||||
// no response, RESET and try again
|
||||
// No response, RESET and try again
|
||||
if(usb_control(pgm, USBTINY_POWERUP, PDATA(pgm)->sck_period, RESET_HIGH, 0) < 0 ||
|
||||
usb_control(pgm, USBTINY_POWERUP, PDATA(pgm)->sck_period, RESET_LOW, 0) < 0)
|
||||
usb_control(pgm, USBTINY_POWERUP, PDATA(pgm)->sck_period, RESET_LOW, 0) < 0)
|
||||
return -1;
|
||||
usleep(50000);
|
||||
}
|
||||
if (tries >= 4)
|
||||
if(tries >= 4)
|
||||
return -1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int usbtiny_setpin(const PROGRAMMER *pgm, int pinfunc, int value) {
|
||||
/* USBtiny is not a bit bang device, but it can set RESET */
|
||||
// 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) < 0)
|
||||
return -1;
|
||||
@@ -495,10 +470,10 @@ static int usbtiny_setpin(const PROGRAMMER *pgm, int pinfunc, int value) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Tell the USBtiny to release the output pins, etc */
|
||||
// Tell the USBtiny to release the output pins, etc
|
||||
static void usbtiny_powerdown(const PROGRAMMER *pgm) {
|
||||
if (!PDATA(pgm)->usb_handle)
|
||||
return; // wasn't connected in the first place
|
||||
if(!PDATA(pgm)->usb_handle)
|
||||
return; // Wasn't connected in the first place
|
||||
usb_control(pgm, USBTINY_POWERDOWN, 0, 0, 1);
|
||||
}
|
||||
|
||||
@@ -508,52 +483,50 @@ static int usbtiny_cmd(const PROGRAMMER *pgm, const unsigned char *cmd, unsigned
|
||||
int nbytes;
|
||||
|
||||
// Make sure its empty so we don't read previous calls if it fails
|
||||
memset(res, '\0', 4 );
|
||||
memset(res, '\0', 4);
|
||||
|
||||
nbytes = usb_in( pgm, USBTINY_SPI,
|
||||
(cmd[1] << 8) | cmd[0], // convert to 16-bit words
|
||||
(cmd[3] << 8) | cmd[2], // "
|
||||
res, 4, 8 * PDATA(pgm)->sck_period );
|
||||
if (nbytes < 0)
|
||||
nbytes = usb_in(pgm, USBTINY_SPI, (cmd[1] << 8) | cmd[0], // Convert to 16-bit words
|
||||
(cmd[3] << 8) | cmd[2], // "
|
||||
res, 4, 8*PDATA(pgm)->sck_period);
|
||||
if(nbytes < 0)
|
||||
return -1;
|
||||
check_retries(pgm, "SPI command");
|
||||
// print out the data we sent and received
|
||||
// Print out the data we sent and received
|
||||
msg_debug("CMD: [%02x %02x %02x %02x] [%02x %02x %02x %02x]\n",
|
||||
cmd[0], cmd[1], cmd[2], cmd[3],
|
||||
res[0], res[1], res[2], res[3] );
|
||||
cmd[0], cmd[1], cmd[2], cmd[3], res[0], res[1], res[2], res[3]);
|
||||
|
||||
return nbytes == 4 && res[2] == cmd[1]? LIBAVRDUDE_SUCCESS: LIBAVRDUDE_GENERAL_FAILURE;
|
||||
}
|
||||
|
||||
int usbtiny_cmd_tpi(const PROGRAMMER *pgm, const unsigned char *cmd,
|
||||
int cmd_len, unsigned char *res, int res_len)
|
||||
{
|
||||
int usbtiny_cmd_tpi(const PROGRAMMER *pgm, const unsigned char *cmd, int cmd_len, unsigned char *res, int res_len) {
|
||||
unsigned char b0, b1;
|
||||
int tx, rx, r;
|
||||
|
||||
/* Transmits command two bytes at the time until we're down to 0 or
|
||||
1 command byte. Then we're either done or we transmit the final
|
||||
byte optionally followed by reading 1 byte. With the current TPI
|
||||
protocol, we never receive more than one byte. */
|
||||
for (tx = rx = 0; tx < cmd_len; ) {
|
||||
/*
|
||||
* Transmits command two bytes at the time until we're down to 0 or
|
||||
* 1 command byte. Then we're either done or we transmit the final
|
||||
* byte optionally followed by reading 1 byte. With the current TPI
|
||||
* protocol, we never receive more than one byte.
|
||||
*/
|
||||
for(tx = rx = 0; tx < cmd_len;) {
|
||||
b0 = cmd[tx++];
|
||||
if (tx < cmd_len) {
|
||||
if(tx < cmd_len) {
|
||||
b1 = cmd[tx++];
|
||||
if (usbtiny_tpi_txtx(pgm, b0, b1) < 0)
|
||||
return -1;
|
||||
if(usbtiny_tpi_txtx(pgm, b0, b1) < 0)
|
||||
return -1;
|
||||
} else {
|
||||
if (res_len > 0) {
|
||||
if ((r = usbtiny_tpi_txrx(pgm, b0)) < 0)
|
||||
return -1;
|
||||
res[rx++] = r;
|
||||
if(res_len > 0) {
|
||||
if((r = usbtiny_tpi_txrx(pgm, b0)) < 0)
|
||||
return -1;
|
||||
res[rx++] = r;
|
||||
} else {
|
||||
if (usbtiny_tpi_tx(pgm, b0) < 0)
|
||||
return -1;
|
||||
if(usbtiny_tpi_tx(pgm, b0) < 0)
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (rx < res_len) {
|
||||
if(rx < res_len) {
|
||||
pmsg_error("unexpected cmd_len=%d/res_len=%d\n", cmd_len, res_len);
|
||||
return -1;
|
||||
}
|
||||
@@ -566,43 +539,44 @@ static int usbtiny_spi(const PROGRAMMER *pgm, const unsigned char *cmd, unsigned
|
||||
// Clear the receive buffer so we don't read old data in case of failure
|
||||
memset(res, 0, count);
|
||||
|
||||
if (count % 4) {
|
||||
if(count%4) {
|
||||
pmsg_error("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) {
|
||||
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(const PROGRAMMER *pgm, const AVRPART *p) {
|
||||
unsigned char res[4];
|
||||
|
||||
if (p->prog_modes & PM_TPI)
|
||||
if(p->prog_modes & PM_TPI)
|
||||
return avr_tpi_chip_erase(pgm, p);
|
||||
|
||||
if (p->op[AVR_OP_CHIP_ERASE] == NULL) {
|
||||
if(p->op[AVR_OP_CHIP_ERASE] == NULL) {
|
||||
pmsg_error("chip erase instruction not defined for part %s\n", p->desc);
|
||||
return -1;
|
||||
}
|
||||
|
||||
// get the command for erasing this chip and transmit to avrdude
|
||||
if (usbtiny_avr_op(pgm, p, AVR_OP_CHIP_ERASE, res) < 0)
|
||||
// Get the command for erasing this chip and transmit to avrdude
|
||||
if(usbtiny_avr_op(pgm, p, AVR_OP_CHIP_ERASE, res) < 0)
|
||||
return -1;
|
||||
|
||||
if(pgm->prog_modes & PM_SPM) { // Talking to bootloader directly
|
||||
if(pgm->prog_modes & PM_SPM) { // Talking to bootloader directly
|
||||
AVRMEM *fl = avr_locate_flash(p);
|
||||
|
||||
// Estimated time it takes to erase all pages in bootloader
|
||||
usleep(p->chip_erase_delay * (fl? fl->num_pages: 999));
|
||||
usleep(p->chip_erase_delay*(fl? fl->num_pages: 999));
|
||||
} else
|
||||
usleep(p->chip_erase_delay);
|
||||
|
||||
// prepare for further instruction
|
||||
// Prepare for further instruction
|
||||
pgm->initialize(pgm, p);
|
||||
|
||||
return 0;
|
||||
@@ -615,20 +589,16 @@ static void usbtiny_enable(PROGRAMMER *pgm, const AVRPART *p) {
|
||||
static void usbtiny_disable(const PROGRAMMER *pgm) {
|
||||
}
|
||||
|
||||
|
||||
static void usbtiny_display(const PROGRAMMER *pgm, const char *p) {
|
||||
}
|
||||
|
||||
|
||||
/* To speed up programming and reading, we do a 'chunked' read.
|
||||
* We request just the data itself and the USBtiny uses the SPI function
|
||||
* given to read in the data. Much faster than sending a 4-byte SPI request
|
||||
* per byte
|
||||
*/
|
||||
static int usbtiny_paged_load (const PROGRAMMER *pgm, const AVRPART *p, const AVRMEM *m,
|
||||
unsigned int page_size,
|
||||
unsigned int addr, unsigned int n_bytes)
|
||||
{
|
||||
static int usbtiny_paged_load(const PROGRAMMER *pgm, const AVRPART *p, const AVRMEM *m,
|
||||
unsigned int page_size, unsigned int addr, unsigned int n_bytes) {
|
||||
unsigned int maxaddr = addr + n_bytes;
|
||||
int chunk, function;
|
||||
OPCODE *lext, *readop;
|
||||
@@ -642,45 +612,41 @@ static int usbtiny_paged_load (const PROGRAMMER *pgm, const AVRPART *p, const AV
|
||||
memset(cmd, 0, sizeof(cmd));
|
||||
avr_set_bits(lext, cmd);
|
||||
avr_set_addr(lext, cmd, addr/2);
|
||||
if(pgm->cmd(pgm, cmd, cmd+4) < 0)
|
||||
if(pgm->cmd(pgm, cmd, cmd + 4) < 0)
|
||||
return -1;
|
||||
}
|
||||
|
||||
// Byte acces as work around to correctly read flash above 64 kiB
|
||||
if(function == USBTINY_FLASH_READ && addr >= 0x10000) {
|
||||
for(unsigned int i=0; i<n_bytes; i++, addr++) {
|
||||
if(!(readop = m->op[addr&1? AVR_OP_READ_HI: AVR_OP_READ_LO]))
|
||||
for(unsigned int i = 0; i < n_bytes; i++, addr++) {
|
||||
if(!(readop = m->op[addr & 1? AVR_OP_READ_HI: AVR_OP_READ_LO]))
|
||||
return -1;
|
||||
|
||||
memset(cmd, 0, sizeof(cmd));
|
||||
avr_set_bits(readop, cmd);
|
||||
avr_set_addr(readop, cmd, addr/2);
|
||||
if(pgm->cmd(pgm, cmd, cmd+4) < 0)
|
||||
if(pgm->cmd(pgm, cmd, cmd + 4) < 0)
|
||||
return -1;
|
||||
m->buf[addr] = 0;
|
||||
avr_get_output(readop, cmd+4, m->buf + addr);
|
||||
avr_get_output(readop, cmd + 4, m->buf + addr);
|
||||
}
|
||||
|
||||
return n_bytes;
|
||||
}
|
||||
|
||||
for (; addr < maxaddr; addr += chunk) {
|
||||
chunk = PDATA(pgm)->chunk_size; // start with the maximum chunk size possible
|
||||
if (addr + chunk > maxaddr) {
|
||||
chunk = maxaddr - addr;
|
||||
}
|
||||
for(; addr < maxaddr; addr += chunk) {
|
||||
chunk = PDATA(pgm)->chunk_size; // Start with the maximum chunk size possible
|
||||
if(addr + chunk > maxaddr)
|
||||
chunk = maxaddr - addr;
|
||||
|
||||
// Send the chunk of data to the USBtiny with the function we want
|
||||
// to perform
|
||||
if (usb_in(pgm,
|
||||
function, // EEPROM or flash
|
||||
0, // delay between SPI commands
|
||||
addr, // address in memory
|
||||
m->buf + addr, // pointer to where we store data
|
||||
chunk, // number of bytes
|
||||
32 * PDATA(pgm)->sck_period) // each byte gets turned into a 4-byte SPI cmd
|
||||
< 0) {
|
||||
// usb_in() multiplies this per byte.
|
||||
// Send the chunk of data to the USBtiny with the function we want to perform
|
||||
if(usb_in(pgm, function, // EEPROM or flash
|
||||
0, // Delay between SPI commands
|
||||
addr, // Address in memory
|
||||
m->buf + addr, // Pointer to where we store data
|
||||
chunk, // Number of bytes
|
||||
32*PDATA(pgm)->sck_period) < 0) { // Each byte gets turned into a 4-byte SPI cmd
|
||||
// usb_in() multiplies this per byte
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
@@ -695,25 +661,24 @@ static int usbtiny_paged_load (const PROGRAMMER *pgm, const AVRPART *p, const AV
|
||||
* per byte.
|
||||
*/
|
||||
static int usbtiny_paged_write(const PROGRAMMER *pgm, const AVRPART *p, const AVRMEM *m,
|
||||
unsigned int page_size,
|
||||
unsigned int addr, unsigned int n_bytes)
|
||||
{
|
||||
unsigned int page_size, unsigned int addr, unsigned int n_bytes) {
|
||||
unsigned int maxaddr = addr + n_bytes;
|
||||
int chunk; // Size of data to write at once
|
||||
int chunk; // Size of data to write at once
|
||||
int next;
|
||||
int function; // which SPI command to use
|
||||
int delay; // delay required between SPI commands
|
||||
int function; // Which SPI command to use
|
||||
int delay; // Delay required between SPI commands
|
||||
|
||||
// First determine what we're doing
|
||||
if (mem_is_flash(m)) {
|
||||
if(mem_is_flash(m)) {
|
||||
function = USBTINY_FLASH_WRITE;
|
||||
} else {
|
||||
function = USBTINY_EEPROM_WRITE;
|
||||
}
|
||||
|
||||
delay = 0;
|
||||
if (! m->paged) {
|
||||
if(!m->paged) {
|
||||
unsigned int poll_value = (m->readback[1] << 8) | m->readback[0];
|
||||
|
||||
if(!poll_value)
|
||||
poll_value = 0xffff;
|
||||
if(usb_control(pgm, USBTINY_POLL_BYTES, poll_value, 0, 0) < 0)
|
||||
@@ -721,32 +686,29 @@ static int usbtiny_paged_write(const PROGRAMMER *pgm, const AVRPART *p, const AV
|
||||
delay = m->max_write_delay;
|
||||
}
|
||||
|
||||
for (; addr < maxaddr; addr += chunk) {
|
||||
// start with the max chunk size
|
||||
for(; addr < maxaddr; addr += chunk) {
|
||||
// Start with the max chunk size
|
||||
chunk = PDATA(pgm)->chunk_size;
|
||||
if (addr + chunk > maxaddr) {
|
||||
chunk = maxaddr - addr;
|
||||
if(addr + chunk > maxaddr) {
|
||||
chunk = maxaddr - addr;
|
||||
}
|
||||
|
||||
// we can only write a page at a time anyways
|
||||
if (m->paged && chunk > (int) page_size)
|
||||
// We can only write a page at a time anyways
|
||||
if(m->paged && chunk > (int) page_size)
|
||||
chunk = page_size;
|
||||
|
||||
if (usb_out(pgm,
|
||||
function, // Flash or EEPROM
|
||||
delay, // How much to wait between each byte
|
||||
addr, // Address in memory
|
||||
m->buf + addr, // Pointer to data
|
||||
chunk, // Number of bytes to write
|
||||
32 * PDATA(pgm)->sck_period + delay // each byte gets turned into a
|
||||
// 4-byte SPI cmd usb_out() multiplies
|
||||
// this per byte. Then add the cmd-delay
|
||||
) < 0) {
|
||||
if(usb_out(pgm, function, // Flash or EEPROM
|
||||
delay, // How much to wait between each byte
|
||||
addr, // Address in memory
|
||||
m->buf + addr, // Pointer to data
|
||||
chunk, // Number of bytes to write
|
||||
// Each byte gets turned into a 4-byte SPI cmd; usb_out() multiplies this per byte; then add the cmd-delay
|
||||
32*PDATA(pgm)->sck_period + delay) < 0) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
next = addr + chunk; // Calculate what address we're at now
|
||||
if (m->paged && (next % page_size == 0 || next == (int) maxaddr) ) {
|
||||
next = addr + chunk; // Calculate what address we're at now
|
||||
if(m->paged && (next%page_size == 0 || next == (int) maxaddr)) {
|
||||
// If we're at a page boundary, send the SPI command to flush it.
|
||||
avr_write_page(pgm, p, m, (unsigned long) addr);
|
||||
}
|
||||
@@ -757,7 +719,7 @@ static int usbtiny_paged_write(const PROGRAMMER *pgm, const AVRPART *p, const AV
|
||||
static int usbtiny_program_enable(const PROGRAMMER *pgm, const AVRPART *p) {
|
||||
unsigned char buf[4];
|
||||
|
||||
if (p->prog_modes & PM_TPI)
|
||||
if(p->prog_modes & PM_TPI)
|
||||
return avr_tpi_program_enable(pgm, p, TPIPCR_GT_0b);
|
||||
else
|
||||
return usbtiny_avr_op(pgm, p, AVR_OP_PGM_ENABLE, buf);
|
||||
@@ -766,33 +728,33 @@ static int usbtiny_program_enable(const PROGRAMMER *pgm, const AVRPART *p) {
|
||||
void usbtiny_initpgm(PROGRAMMER *pgm) {
|
||||
strcpy(pgm->type, "USBtiny");
|
||||
|
||||
/* Mandatory Functions */
|
||||
pgm->initialize = usbtiny_initialize;
|
||||
pgm->display = usbtiny_display;
|
||||
pgm->enable = usbtiny_enable;
|
||||
pgm->disable = usbtiny_disable;
|
||||
pgm->program_enable = usbtiny_program_enable;
|
||||
pgm->chip_erase = usbtiny_chip_erase;
|
||||
pgm->cmd = usbtiny_cmd;
|
||||
pgm->cmd_tpi = usbtiny_cmd_tpi;
|
||||
pgm->open = usbtiny_open;
|
||||
pgm->close = usbtiny_close;
|
||||
pgm->read_byte = avr_read_byte_default;
|
||||
pgm->write_byte = avr_write_byte_default;
|
||||
// Mandatory Functions
|
||||
pgm->initialize = usbtiny_initialize;
|
||||
pgm->display = usbtiny_display;
|
||||
pgm->enable = usbtiny_enable;
|
||||
pgm->disable = usbtiny_disable;
|
||||
pgm->program_enable = usbtiny_program_enable;
|
||||
pgm->chip_erase = usbtiny_chip_erase;
|
||||
pgm->cmd = usbtiny_cmd;
|
||||
pgm->cmd_tpi = usbtiny_cmd_tpi;
|
||||
pgm->open = usbtiny_open;
|
||||
pgm->close = usbtiny_close;
|
||||
pgm->read_byte = avr_read_byte_default;
|
||||
pgm->write_byte = avr_write_byte_default;
|
||||
|
||||
/* Optional Functions */
|
||||
pgm->powerup = NULL;
|
||||
pgm->powerdown = usbtiny_powerdown;
|
||||
pgm->paged_load = usbtiny_paged_load;
|
||||
pgm->paged_write = usbtiny_paged_write;
|
||||
pgm->set_sck_period = usbtiny_set_sck_period;
|
||||
pgm->setup = usbtiny_setup;
|
||||
pgm->teardown = usbtiny_teardown;
|
||||
pgm->setpin = usbtiny_setpin;
|
||||
pgm->spi = usbtiny_spi;
|
||||
// Optional Functions
|
||||
pgm->powerup = NULL;
|
||||
pgm->powerdown = usbtiny_powerdown;
|
||||
pgm->paged_load = usbtiny_paged_load;
|
||||
pgm->paged_write = usbtiny_paged_write;
|
||||
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 */
|
||||
#else // ! HAVE_LIBUSB
|
||||
|
||||
// Give a proper error if we were not compiled with libusb
|
||||
|
||||
@@ -807,7 +769,6 @@ void usbtiny_initpgm(PROGRAMMER *pgm) {
|
||||
|
||||
pgm->open = usbtiny_nousb_open;
|
||||
}
|
||||
|
||||
#endif /* HAVE_LIBUSB */
|
||||
#endif // HAVE_LIBUSB
|
||||
|
||||
const char usbtiny_desc[] = "Usbtiny-type programmers incl arduinoisp, arduino_gemma and adafruit_gemma";
|
||||
|
||||
Reference in New Issue
Block a user