diff --git a/src/usbasp.c b/src/usbasp.c index e6de2d81..7a23efa7 100644 --- a/src/usbasp.c +++ b/src/usbasp.c @@ -18,7 +18,7 @@ */ /* - * Interface to the USBasp programmer. + * Interface to the USBasp programmer * * See http://www.fischl.de/usbasp/ */ @@ -42,34 +42,38 @@ #if defined(HAVE_LIBUSB) || defined(HAVE_LIBUSB_1_0) #ifdef HAVE_LIBUSB_1_0 -# define USE_LIBUSB_1_0 +#define USE_LIBUSB_1_0 #endif #if defined(USE_LIBUSB_1_0) -# if defined(HAVE_LIBUSB_1_0_LIBUSB_H) -# include -# else -# include -# endif + +#if defined(HAVE_LIBUSB_1_0_LIBUSB_H) +#include #else -# if defined(HAVE_USB_H) -# include -# elif defined(HAVE_LUSB0_USB_H) -# include -# else -# error "libusb needs either or " -# endif +#include +#endif +#else + +#if defined(HAVE_USB_H) +#include +#elif defined(HAVE_LUSB0_USB_H) +#include +#else +#error "libusb needs either or " +#endif #endif #include // Private data for this programmer struct pdata { + #ifdef USE_LIBUSB_1_0 libusb_device_handle *usbhandle; #else usb_dev_handle *usbhandle; #endif + int sckfreq_hz; unsigned int capabilities; int use_tpi; @@ -80,145 +84,143 @@ struct pdata { libusb_context *ctx; char msg[30]; // Used in errstr() #endif + int USB_init; // Used in both usbOpenDevice() variants }; #define PDATA(pgm) ((struct pdata *)(pgm->cookie)) #ifdef USE_LIBUSB_1_0 - static const char *errstr(const PROGRAMMER *pgm, int result) { - char *msg = PDATA(pgm)->msg; - size_t msgsiz = sizeof(PDATA(pgm)->msg); - int n = 0; + char *msg = PDATA(pgm)->msg; + size_t msgsiz = sizeof(PDATA(pgm)->msg); + int n = 0; + + switch (result) { + case LIBUSB_SUCCESS: + return "No error"; + case LIBUSB_ERROR_IO: + n = EIO; + break; + case LIBUSB_ERROR_INVALID_PARAM: + n = EINVAL; + break; + case LIBUSB_ERROR_ACCESS: + n = EACCES; + break; + case LIBUSB_ERROR_NO_DEVICE: + n = ENXIO; + break; + case LIBUSB_ERROR_NOT_FOUND: + n = ENOENT; + break; + case LIBUSB_ERROR_BUSY: + n = EBUSY; + break; + case LIBUSB_ERROR_TIMEOUT: - switch (result) { - case LIBUSB_SUCCESS: - return "No error"; - case LIBUSB_ERROR_IO: - n = EIO; - break; - case LIBUSB_ERROR_INVALID_PARAM: - n = EINVAL; - break; - case LIBUSB_ERROR_ACCESS: - n = EACCES; - break; - case LIBUSB_ERROR_NO_DEVICE: - n = ENXIO; - break; - case LIBUSB_ERROR_NOT_FOUND: - n = ENOENT; - break; - case LIBUSB_ERROR_BUSY: - n = EBUSY; - break; - case LIBUSB_ERROR_TIMEOUT: #ifdef ETIMEDOUT - n = ETIMEDOUT; - break; + n = ETIMEDOUT; + break; #else - return "Operation timed out" + return "Operation timed out" #endif - case LIBUSB_ERROR_OVERFLOW: + + case LIBUSB_ERROR_OVERFLOW: + #ifdef EOVERFLOW - n = EOVERFLOW; - break; + n = EOVERFLOW; + break; #else - return "Value too large to be stored in data type" + return "Value too large to be stored in data type" #endif - case LIBUSB_ERROR_PIPE: - n = EPIPE; - break; - case LIBUSB_ERROR_INTERRUPTED: - n = EINTR; - break; - case LIBUSB_ERROR_NO_MEM: - n = ENOMEM; - break; - case LIBUSB_ERROR_NOT_SUPPORTED: - n = ENOSYS; - break; - default: - snprintf(msg, msgsiz, "Unknown libusb error code %d", result); - return msg; - } - return strerror(n); + + case LIBUSB_ERROR_PIPE: + n = EPIPE; + break; + case LIBUSB_ERROR_INTERRUPTED: + n = EINTR; + break; + case LIBUSB_ERROR_NO_MEM: + n = ENOMEM; + break; + case LIBUSB_ERROR_NOT_SUPPORTED: + n = ENOSYS; + break; + default: + snprintf(msg, msgsiz, "Unknown libusb error code %d", result); + return msg; + } + return strerror(n); } - #endif - -/* Prototypes */ -// interface - management +// Interface management static void usbasp_setup(PROGRAMMER *pgm); static void usbasp_teardown(PROGRAMMER *pgm); static int usbasp_parseextparms(const PROGRAMMER *pgm, const LISTID extparms); -// internal functions + +// Internal functions static int usbasp_transmit(const PROGRAMMER *pgm, unsigned char receive, - unsigned char functionid, const unsigned char *send, - unsigned char *buffer, int buffersize); + unsigned char functionid, const unsigned char *send, unsigned char *buffer, int buffersize); + #ifdef USE_LIBUSB_1_0 -static int usbOpenDevice(const PROGRAMMER *pgm, libusb_device_handle **device, int vendor, +static int usbOpenDevice(const PROGRAMMER *pgm, libusb_device_handle ** device, int vendor, const char *vendorName, int product, const char *productName, const char *port); #else -static int usbOpenDevice(const PROGRAMMER *pgm, usb_dev_handle **device, int vendor, +static int usbOpenDevice(const PROGRAMMER *pgm, usb_dev_handle ** device, int vendor, const char *vendorName, int product, const char *productName, const char *port); #endif -// interface - prog. + +// Interface prog static int usbasp_open(PROGRAMMER *pgm, const char *port); static void usbasp_close(PROGRAMMER *pgm); -// dummy functions + +// Dummy functions static void usbasp_disable(const PROGRAMMER *pgm); static void usbasp_enable(PROGRAMMER *pgm, const AVRPART *p); static void usbasp_display(const PROGRAMMER *pgm, const char *p); -// universal functions + +// Universal functions static int usbasp_initialize(const PROGRAMMER *pgm, const AVRPART *p); + // SPI specific functions static int usbasp_spi_cmd(const PROGRAMMER *pgm, const unsigned char *cmd, unsigned char *res); static int usbasp_spi_program_enable(const PROGRAMMER *pgm, const AVRPART *p); static int usbasp_spi_chip_erase(const PROGRAMMER *pgm, const AVRPART *p); static int usbasp_spi_paged_load(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); static int usbasp_spi_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); static int usbasp_spi_set_sck_period(const PROGRAMMER *pgm, double sckperiod); + // TPI specific functions static void usbasp_tpi_send_byte(const PROGRAMMER *pgm, uint8_t b); static int usbasp_tpi_cmd(const PROGRAMMER *pgm, const unsigned char *cmd, unsigned char *res); static int usbasp_tpi_program_enable(const PROGRAMMER *pgm, const AVRPART *p); static int usbasp_tpi_chip_erase(const PROGRAMMER *pgm, const AVRPART *p); static int usbasp_tpi_paged_load(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); static int usbasp_tpi_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); static int usbasp_tpi_set_sck_period(const PROGRAMMER *pgm, double sckperiod); -static int usbasp_tpi_read_byte(const PROGRAMMER * pgm, const AVRPART *p, const AVRMEM *m, unsigned long addr, unsigned char *value); -static int usbasp_tpi_write_byte(const PROGRAMMER *pgm, const AVRPART *p, const AVRMEM *m, unsigned long addr, unsigned char data); - +static int usbasp_tpi_read_byte(const PROGRAMMER *pgm, const AVRPART *p, const AVRMEM *m, unsigned long addr, + unsigned char *value); +static int usbasp_tpi_write_byte(const PROGRAMMER *pgm, const AVRPART *p, const AVRMEM *m, unsigned long addr, + unsigned char data); // Dispatching wrappers static int usbasp_cmd(const PROGRAMMER *pgm, const unsigned char *cmd, unsigned char *res) { - return PDATA(pgm)->use_tpi? - usbasp_tpi_cmd(pgm, cmd, res): - usbasp_spi_cmd(pgm, cmd, res); + return PDATA(pgm)->use_tpi? usbasp_tpi_cmd(pgm, cmd, res): usbasp_spi_cmd(pgm, cmd, res); } static int usbasp_program_enable(const PROGRAMMER *pgm, const AVRPART *p) { - return PDATA(pgm)->use_tpi? - usbasp_tpi_program_enable(pgm, p): - usbasp_spi_program_enable(pgm, p); + return PDATA(pgm)->use_tpi? usbasp_tpi_program_enable(pgm, p): usbasp_spi_program_enable(pgm, p); } static int usbasp_chip_erase(const PROGRAMMER *pgm, const AVRPART *p) { - return PDATA(pgm)->use_tpi? - usbasp_tpi_chip_erase(pgm, p): - usbasp_spi_chip_erase(pgm, p); + return PDATA(pgm)->use_tpi? usbasp_tpi_chip_erase(pgm, p): usbasp_spi_chip_erase(pgm, p); } static int usbasp_paged_load(const PROGRAMMER *pgm, const AVRPART *p, const AVRMEM *m, @@ -238,13 +240,11 @@ static int usbasp_paged_write(const PROGRAMMER *pgm, const AVRPART *p, const AVR } static int usbasp_set_sck_period(const PROGRAMMER *pgm, double sckperiod) { - return PDATA(pgm)->use_tpi? - usbasp_tpi_set_sck_period(pgm, sckperiod): - usbasp_spi_set_sck_period(pgm, sckperiod); + return PDATA(pgm)->use_tpi? usbasp_tpi_set_sck_period(pgm, sckperiod): usbasp_spi_set_sck_period(pgm, sckperiod); } static int usbasp_read_byte(const PROGRAMMER *pgm, const AVRPART *p, const AVRMEM *m, - unsigned long addr, unsigned char * value) { + unsigned long addr, unsigned char *value) { return PDATA(pgm)->use_tpi? usbasp_tpi_read_byte(pgm, p, m, addr, value): @@ -256,6 +256,7 @@ static int usbasp_write_byte(const PROGRAMMER *pgm, const AVRPART *p, const AVRM if(mem_is_readonly(m)) { unsigned char is; + if(pgm->read_byte(pgm, p, m, addr, &is) >= 0 && is == data) return 0; @@ -268,8 +269,7 @@ static int usbasp_write_byte(const PROGRAMMER *pgm, const AVRPART *p, const AVRM avr_write_byte_default(pgm, p, m, addr, data); } - -/* Interface - management */ +// Interface management static void usbasp_setup(PROGRAMMER *pgm) { pgm->cookie = mmt_malloc(sizeof(struct pdata)); } @@ -283,21 +283,21 @@ static int usbasp_parseextparms(const PROGRAMMER *pgm, const LISTID extparms) { int rv = 0; bool help = false; - for (LNODEID ln = lfirst(extparms); ln; ln = lnext(ln)) { + for(LNODEID ln = lfirst(extparms); ln; ln = lnext(ln)) { const char *extended_param = ldata(ln); - if (str_eq(extended_param, "section_config")) { + if(str_eq(extended_param, "section_config")) { pmsg_notice2("%s(): set section_e to 1 (config section)\n", __func__); PDATA(pgm)->section_e = 1; continue; } - if (str_eq(extended_param, "help")) { + if(str_eq(extended_param, "help")) { help = true; rv = LIBAVRDUDE_EXIT; } - if (!help) { + if(!help) { pmsg_error("invalid extended parameter -x %s\n", extended_param); rv = -1; } @@ -310,86 +310,107 @@ static int usbasp_parseextparms(const PROGRAMMER *pgm, const LISTID extparms) { return rv; } - -/* Internal functions */ - -static const char *usbasp_get_funcname(unsigned char functionid) -{ +static const char *usbasp_get_funcname(unsigned char functionid) { switch (functionid) { - case USBASP_FUNC_CONNECT: return "USBASP_FUNC_CONNECT"; break; - case USBASP_FUNC_DISCONNECT: return "USBASP_FUNC_DISCONNECT"; break; - case USBASP_FUNC_TRANSMIT: return "USBASP_FUNC_TRANSMIT"; break; - case USBASP_FUNC_READFLASH: return "USBASP_FUNC_READFLASH"; break; - case USBASP_FUNC_ENABLEPROG: return "USBASP_FUNC_ENABLEPROG"; break; - case USBASP_FUNC_WRITEFLASH: return "USBASP_FUNC_WRITEFLASH"; break; - case USBASP_FUNC_READEEPROM: return "USBASP_FUNC_READEEPROM"; break; - case USBASP_FUNC_WRITEEEPROM: return "USBASP_FUNC_WRITEEEPROM"; break; - case USBASP_FUNC_SETLONGADDRESS: return "USBASP_FUNC_SETLONGADDRESS"; break; - case USBASP_FUNC_SETISPSCK: return "USBASP_FUNC_SETISPSCK"; break; - case USBASP_FUNC_TPI_CONNECT: return "USBASP_FUNC_TPI_CONNECT"; break; - case USBASP_FUNC_TPI_DISCONNECT: return "USBASP_FUNC_TPI_DISCONNECT"; break; - case USBASP_FUNC_TPI_RAWREAD: return "USBASP_FUNC_TPI_RAWREAD"; break; - case USBASP_FUNC_TPI_RAWWRITE: return "USBASP_FUNC_TPI_RAWWRITE"; break; - case USBASP_FUNC_TPI_READBLOCK: return "USBASP_FUNC_TPI_READBLOCK"; break; - case USBASP_FUNC_TPI_WRITEBLOCK: return "USBASP_FUNC_TPI_WRITEBLOCK"; break; - case USBASP_FUNC_GETCAPABILITIES: return "USBASP_FUNC_GETCAPABILITIES"; break; - default: return "Unknown USBASP function"; break; + case USBASP_FUNC_CONNECT: + return "USBASP_FUNC_CONNECT"; + break; + case USBASP_FUNC_DISCONNECT: + return "USBASP_FUNC_DISCONNECT"; + break; + case USBASP_FUNC_TRANSMIT: + return "USBASP_FUNC_TRANSMIT"; + break; + case USBASP_FUNC_READFLASH: + return "USBASP_FUNC_READFLASH"; + break; + case USBASP_FUNC_ENABLEPROG: + return "USBASP_FUNC_ENABLEPROG"; + break; + case USBASP_FUNC_WRITEFLASH: + return "USBASP_FUNC_WRITEFLASH"; + break; + case USBASP_FUNC_READEEPROM: + return "USBASP_FUNC_READEEPROM"; + break; + case USBASP_FUNC_WRITEEEPROM: + return "USBASP_FUNC_WRITEEEPROM"; + break; + case USBASP_FUNC_SETLONGADDRESS: + return "USBASP_FUNC_SETLONGADDRESS"; + break; + case USBASP_FUNC_SETISPSCK: + return "USBASP_FUNC_SETISPSCK"; + break; + case USBASP_FUNC_TPI_CONNECT: + return "USBASP_FUNC_TPI_CONNECT"; + break; + case USBASP_FUNC_TPI_DISCONNECT: + return "USBASP_FUNC_TPI_DISCONNECT"; + break; + case USBASP_FUNC_TPI_RAWREAD: + return "USBASP_FUNC_TPI_RAWREAD"; + break; + case USBASP_FUNC_TPI_RAWWRITE: + return "USBASP_FUNC_TPI_RAWWRITE"; + break; + case USBASP_FUNC_TPI_READBLOCK: + return "USBASP_FUNC_TPI_READBLOCK"; + break; + case USBASP_FUNC_TPI_WRITEBLOCK: + return "USBASP_FUNC_TPI_WRITEBLOCK"; + break; + case USBASP_FUNC_GETCAPABILITIES: + return "USBASP_FUNC_GETCAPABILITIES"; + break; + default: + return "Unknown USBASP function"; + break; } } -/* - * wrapper for usb_control_msg call - */ +// Wrapper for usb_control_msg call static int usbasp_transmit(const PROGRAMMER *pgm, - unsigned char receive, unsigned char functionid, - const unsigned char *send, - unsigned char *buffer, int buffersize) -{ + unsigned char receive, unsigned char functionid, const unsigned char *send, unsigned char *buffer, int buffersize) { int nbytes; - if (verbose >= MSG_TRACE) { + if(verbose >= MSG_TRACE) { pmsg_trace("usbasp_transmit(\"%s\", 0x%02x, 0x%02x, 0x%02x, 0x%02x)\n", usbasp_get_funcname(functionid), send[0], send[1], send[2], send[3]); - if (!receive && buffersize > 0) { + if(!receive && buffersize > 0) { int i; + imsg_trace(" => "); - for (i = 0; i < buffersize; i++) - msg_trace("[%02x] ", buffer[i]); + for(i = 0; i < buffersize; i++) + msg_trace("[%02x] ", buffer[i]); msg_trace("\n"); } } #ifdef USE_LIBUSB_1_0 nbytes = libusb_control_transfer(PDATA(pgm)->usbhandle, - (LIBUSB_REQUEST_TYPE_VENDOR | LIBUSB_RECIPIENT_DEVICE | (receive << 7)) & 0xff, - functionid & 0xff, - ((send[1] << 8) | send[0]) & 0xffff, - ((send[3] << 8) | send[2]) & 0xffff, - buffer, - buffersize & 0xffff, - 5000); - if(nbytes < 0){ + (LIBUSB_REQUEST_TYPE_VENDOR | LIBUSB_RECIPIENT_DEVICE | (receive << 7)) & 0xff, + functionid & 0xff, + ((send[1] << 8) | send[0]) & 0xffff, ((send[3] << 8) | send[2]) & 0xffff, buffer, buffersize & 0xffff, 5000); + if(nbytes < 0) { pmsg_ext_error("%s\n", errstr(pgm, nbytes)); return -1; } #else nbytes = usb_control_msg(PDATA(pgm)->usbhandle, - USB_TYPE_VENDOR | USB_RECIP_DEVICE | (receive << 7), - functionid, - (send[1] << 8) | send[0], - (send[3] << 8) | send[2], - (char *)buffer, buffersize, - 5000); - if(nbytes < 0){ + USB_TYPE_VENDOR | USB_RECIP_DEVICE | (receive << 7), + functionid, (send[1] << 8) | send[0], (send[3] << 8) | send[2], (char *) buffer, buffersize, 5000); + if(nbytes < 0) { pmsg_error("%s\n", usb_strerror()); return -1; } #endif - if (verbose >= MSG_TRACE && receive && nbytes > 0) { + if(verbose >= MSG_TRACE && receive && nbytes > 0) { int i; + imsg_trace("<= "); - for (i = 0; i < nbytes; i++) + for(i = 0; i < nbytes; i++) msg_trace("[%02x] ", buffer[i]); msg_trace("\n"); } @@ -401,209 +422,213 @@ static int check_for_port_argument_match(const char *port, char *bus, char *devi pmsg_debug("%s(): found USBasp, bus:device: %s:%s, serial_number: %s\n", __func__, bus, device, serial_num); const size_t usb_len = strlen("usb"); + if(str_starts(port, "usb") && ':' == port[usb_len]) { port += usb_len + 1; char *colon_pointer = strchr(port, ':'); - if (colon_pointer) { + + if(colon_pointer) { // Value contains ':' character. Compare with bus/device. - if (strncmp(port, bus, colon_pointer - port)) + if(strncmp(port, bus, colon_pointer - port)) return 0; port = colon_pointer + 1; return str_eq(port, device); } - // serial number case + // Serial number case return *port && str_ends(serial_num, port); } // Invalid -P option. - return 0; + return 0; } /* - * Try to open USB device with given VID, PID, vendor and product name - * Parts of this function were taken from an example code by OBJECTIVE - * DEVELOPMENT Software GmbH (www.obdev.at) to meet conditions for - * shared VID/PID + * Try to open USB device with given VID, PID, vendor and product name Parts of + * this function were taken from an example code by OBJECTIVE DEVELOPMENT + * Software GmbH (www.obdev.at) to meet conditions for shared VID/PID */ + #ifdef USE_LIBUSB_1_0 -static int usbOpenDevice(const PROGRAMMER *pgm, libusb_device_handle **device, int vendor, +static int usbOpenDevice(const PROGRAMMER *pgm, libusb_device_handle ** device, int vendor, const char *vendorName, int product, const char *productName, const char *port) { - libusb_device_handle *handle = NULL; - int errorCode = USB_ERROR_NOTFOUND; - int j; - int r; + libusb_device_handle *handle = NULL; + int errorCode = USB_ERROR_NOTFOUND; + int j; + int r; - if(!PDATA(pgm)->USB_init){ - PDATA(pgm)->USB_init = 1; - libusb_init(&PDATA(pgm)->ctx); - } - - libusb_device **dev_list; - int dev_list_len = libusb_get_device_list(PDATA(pgm)->ctx, &dev_list); + if(!PDATA(pgm)->USB_init) { + PDATA(pgm)->USB_init = 1; + libusb_init(&PDATA(pgm)->ctx); + } - for (j=0; jusb_access_error = 1; - errorCode = USB_ERROR_ACCESS; - pmsg_warning("cannot open USB device: %s\n", errstr(pgm, r)); - continue; - } - errorCode = 0; - /* now check whether the names match: */ - /* if vendorName not given ignore it (any vendor matches) */ - r = libusb_get_string_descriptor_ascii(handle, descriptor.iManufacturer & 0xff, (unsigned char*)string, sizeof(string)); - if (r < 0) { - cx->usb_access_error = 1; - if ((vendorName != NULL) && (vendorName[0] != 0)) { - errorCode = USB_ERROR_IO; - pmsg_warning("cannot query manufacturer for device: %s\n", errstr(pgm, r)); - } - } else { - pmsg_notice2("seen device from vendor >%s<\n", string); - if ((vendorName != NULL) && (vendorName[0] != 0) && !str_eq(string, vendorName)) - errorCode = USB_ERROR_NOTFOUND; - } - /* if productName not given ignore it (any product matches) */ - r = libusb_get_string_descriptor_ascii(handle, descriptor.iProduct & 0xff, (unsigned char*)string, sizeof(string)); - if (r < 0) { - cx->usb_access_error = 1; - if ((productName != NULL) && (productName[0] != 0)) { - errorCode = USB_ERROR_IO; - pmsg_warning("cannot query product for device: %s\n", errstr(pgm, r)); - } - } else { - pmsg_notice2("seen product >%s<\n", string); - if((productName != NULL) && (productName[0] != 0) && !str_eq(string, productName)) - errorCode = USB_ERROR_NOTFOUND; - } - if (errorCode == 0) { - if(!str_eq(port, "usb")) { - // -P option given - libusb_get_string_descriptor_ascii(handle, descriptor.iSerialNumber, (unsigned char*)string, sizeof(string)); - char bus_num[21]; - sprintf(bus_num, "%d", libusb_get_bus_number(dev)); - char dev_addr[21]; - sprintf(dev_addr, "%d", libusb_get_device_address(dev)); - if (!check_for_port_argument_match(port, bus_num, dev_addr, string)) - errorCode = USB_ERROR_NOTFOUND; - } - } - if (errorCode == 0) - break; - libusb_close(handle); - handle = NULL; + libusb_device **dev_list; + int dev_list_len = libusb_get_device_list(PDATA(pgm)->ctx, &dev_list); + + for(j = 0; j < dev_list_len; ++j) { + libusb_device *dev = dev_list[j]; + struct libusb_device_descriptor descriptor; + + libusb_get_device_descriptor(dev, &descriptor); + if(descriptor.idVendor == vendor && descriptor.idProduct == product) { + char string[256]; + + // We need to open the device in order to query strings + r = libusb_open(dev, &handle); + if(!handle) { + cx->usb_access_error = 1; + errorCode = USB_ERROR_ACCESS; + pmsg_warning("cannot open USB device: %s\n", errstr(pgm, r)); + continue; + } + errorCode = 0; + // Do the names match? if vendorName not given ignore it (any vendor matches) + r = libusb_get_string_descriptor_ascii(handle, descriptor.iManufacturer & 0xff, + (unsigned char *) string, sizeof(string)); + if(r < 0) { + cx->usb_access_error = 1; + if((vendorName != NULL) && (vendorName[0] != 0)) { + errorCode = USB_ERROR_IO; + pmsg_warning("cannot query manufacturer for device: %s\n", errstr(pgm, r)); } + } else { + pmsg_notice2("seen device from vendor >%s<\n", string); + if((vendorName != NULL) && (vendorName[0] != 0) && !str_eq(string, vendorName)) + errorCode = USB_ERROR_NOTFOUND; + } + // If productName not given ignore it (any product matches) + r = libusb_get_string_descriptor_ascii(handle, descriptor.iProduct & 0xff, + (unsigned char *) string, sizeof(string)); + if(r < 0) { + cx->usb_access_error = 1; + if((productName != NULL) && (productName[0] != 0)) { + errorCode = USB_ERROR_IO; + pmsg_warning("cannot query product for device: %s\n", errstr(pgm, r)); + } + } else { + pmsg_notice2("seen product >%s<\n", string); + if((productName != NULL) && (productName[0] != 0) && !str_eq(string, productName)) + errorCode = USB_ERROR_NOTFOUND; + } + if(errorCode == 0) { + if(!str_eq(port, "usb")) { + // -P option given + libusb_get_string_descriptor_ascii(handle, descriptor.iSerialNumber, + (unsigned char *) string, sizeof(string)); + char bus_num[21]; + + sprintf(bus_num, "%d", libusb_get_bus_number(dev)); + char dev_addr[21]; + + sprintf(dev_addr, "%d", libusb_get_device_address(dev)); + if(!check_for_port_argument_match(port, bus_num, dev_addr, string)) + errorCode = USB_ERROR_NOTFOUND; + } + } + if(errorCode == 0) + break; + libusb_close(handle); + handle = NULL; } - libusb_free_device_list(dev_list,1); - if (handle != NULL){ - errorCode = 0; - *device = handle; - } - return errorCode; + } + libusb_free_device_list(dev_list, 1); + if(handle != NULL) { + errorCode = 0; + *device = handle; + } + return errorCode; } #else -static int usbOpenDevice(const PROGRAMMER *pgm, usb_dev_handle **device, int vendor, +static int usbOpenDevice(const PROGRAMMER *pgm, usb_dev_handle ** device, int vendor, const char *vendorName, int product, const char *productName, const char *port) { - struct usb_bus * bus; - struct usb_device * dev; - usb_dev_handle * handle = NULL; - int errorCode = USB_ERROR_NOTFOUND; + struct usb_bus *bus; + struct usb_device *dev; + usb_dev_handle *handle = NULL; + int errorCode = USB_ERROR_NOTFOUND; - if(!PDATA(pgm)->USB_init) { - PDATA(pgm)->USB_init = 1; - usb_init(); - } - usb_find_busses(); - usb_find_devices(); - for(bus=usb_get_busses(); bus; bus=bus->next){ - for(dev=bus->devices; dev; dev=dev->next){ - if(dev->descriptor.idVendor == vendor && - dev->descriptor.idProduct == product){ - char string[256]; - int len; - /* we need to open the device in order to query strings */ - handle = usb_open(dev); - if(!handle){ - cx->usb_access_error = 1; - errorCode = USB_ERROR_ACCESS; - pmsg_warning("cannot open USB device: %s\n", usb_strerror()); - continue; - } - errorCode = 0; - /* now check whether the names match: */ - /* if vendorName not given ignore it (any vendor matches) */ - len = usb_get_string_simple(handle, dev->descriptor.iManufacturer, - string, sizeof(string)); - if(len < 0){ - cx->usb_access_error = 1; - if ((vendorName != NULL) && (vendorName[0] != 0)) { - errorCode = USB_ERROR_IO; - pmsg_warning("cannot query manufacturer for device: %s\n", usb_strerror()); - } - } else { - pmsg_notice2("seen device from vendor >%s<\n", string); - if((vendorName != NULL) && (vendorName[0] != 0) && !str_eq(string, vendorName)) - errorCode = USB_ERROR_NOTFOUND; - } - /* if productName not given ignore it (any product matches) */ - len = usb_get_string_simple(handle, dev->descriptor.iProduct, - string, sizeof(string)); - if(len < 0){ - cx->usb_access_error = 1; - if ((productName != NULL) && (productName[0] != 0)) { - errorCode = USB_ERROR_IO; - pmsg_warning("cannot query product for device: %s\n", usb_strerror()); - } - } else { - pmsg_notice2("seen product >%s<\n", string); - if((productName != NULL) && (productName[0] != 0) && !str_eq(string, productName)) - errorCode = USB_ERROR_NOTFOUND; - } - if (errorCode == 0) { - if(!str_eq(port, "usb")) { - // -P option given - usb_get_string_simple(handle, dev->descriptor.iSerialNumber, - string, sizeof(string)); - if (!check_for_port_argument_match(port, bus->dirname, dev->filename, string)) - errorCode = USB_ERROR_NOTFOUND; - } - } - if (errorCode == 0) - break; - usb_close(handle); - handle = NULL; - } + if(!PDATA(pgm)->USB_init) { + PDATA(pgm)->USB_init = 1; + usb_init(); + } + usb_find_busses(); + usb_find_devices(); + for(bus = usb_get_busses(); bus; bus = bus->next) { + for(dev = bus->devices; dev; dev = dev->next) { + if(dev->descriptor.idVendor == vendor && dev->descriptor.idProduct == product) { + char string[256]; + int len; + + // We need to open the device in order to query strings + handle = usb_open(dev); + if(!handle) { + cx->usb_access_error = 1; + errorCode = USB_ERROR_ACCESS; + pmsg_warning("cannot open USB device: %s\n", usb_strerror()); + continue; } - if(handle) - break; - } - if(handle != NULL){ errorCode = 0; - *device = handle; + // Do the names match? If vendorName not given ignore it (any vendor matches) + len = usb_get_string_simple(handle, dev->descriptor.iManufacturer, string, sizeof(string)); + if(len < 0) { + cx->usb_access_error = 1; + if((vendorName != NULL) && (vendorName[0] != 0)) { + errorCode = USB_ERROR_IO; + pmsg_warning("cannot query manufacturer for device: %s\n", usb_strerror()); + } + } else { + pmsg_notice2("seen device from vendor >%s<\n", string); + if((vendorName != NULL) && (vendorName[0] != 0) && !str_eq(string, vendorName)) + errorCode = USB_ERROR_NOTFOUND; + } + // If productName not given ignore it (any product matches) + len = usb_get_string_simple(handle, dev->descriptor.iProduct, string, sizeof(string)); + if(len < 0) { + cx->usb_access_error = 1; + if((productName != NULL) && (productName[0] != 0)) { + errorCode = USB_ERROR_IO; + pmsg_warning("cannot query product for device: %s\n", usb_strerror()); + } + } else { + pmsg_notice2("seen product >%s<\n", string); + if((productName != NULL) && (productName[0] != 0) && !str_eq(string, productName)) + errorCode = USB_ERROR_NOTFOUND; + } + if(errorCode == 0) { + if(!str_eq(port, "usb")) { + // -P option given + usb_get_string_simple(handle, dev->descriptor.iSerialNumber, string, sizeof(string)); + if(!check_for_port_argument_match(port, bus->dirname, dev->filename, string)) + errorCode = USB_ERROR_NOTFOUND; + } + } + if(errorCode == 0) + break; + usb_close(handle); + handle = NULL; + } } - return errorCode; + if(handle) + break; + } + if(handle != NULL) { + errorCode = 0; + *device = handle; + } + return errorCode; } #endif - -/* Interface - prog. */ +// Interface prog static int usbasp_open(PROGRAMMER *pgm, const char *port) { pmsg_debug("usbasp_open(\"%s\")\n", port); - /* usb_init will be done in usbOpenDevice */ + // usb_init will be done in usbOpenDevice LNODEID usbpid = lfirst(pgm->usbpid); int pid, vid; - 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 = USBASP_SHARED_PID; @@ -611,24 +636,28 @@ static int usbasp_open(PROGRAMMER *pgm, const char *port) { vid = pgm->usbvid? pgm->usbvid: USBASP_SHARED_VID; if(usbOpenDevice(pgm, &PDATA(pgm)->usbhandle, vid, pgm->usbvendor, pid, pgm->usbproduct, port) != 0) { if(str_eq(pgmid, "usbasp")) { - /* check if device with old VID/PID is available */ + // Check if device with old VID/PID is available if(usbOpenDevice(pgm, &PDATA(pgm)->usbhandle, USBASP_OLD_VID, "www.fischl.de", - USBASP_OLD_PID, "USBasp", port) == 0) { + USBASP_OLD_PID, "USBasp", port) == 0) { + cx->usb_access_error = 0; - /* found USBasp with old IDs */ + // Found USBasp with old IDs pmsg_error("found USB device USBasp with old VID/PID; please update firmware of USBasp\n"); - return 0; + return 0; } - /* original USBasp is specified in config file, so no need to check it again here */ - /* no alternative found => fall through to generic error message */ + /* + * original USBasp is specified in config file, so no need to check it + * again here; no alternative found => fall through to generic error + * message + */ } pmsg_error("cannot find USB device with vid=0x%x pid=0x%x", vid, pid); - if (pgm->usbvendor[0] != 0) { - msg_error(" vendor='%s'", pgm->usbvendor); + if(pgm->usbvendor[0] != 0) { + msg_error(" vendor='%s'", pgm->usbvendor); } - if (pgm->usbproduct[0] != 0) { - msg_error(" product='%s'", pgm->usbproduct); + if(pgm->usbproduct[0] != 0) { + msg_error(" product='%s'", pgm->usbproduct); } msg_error("\n"); return -1; @@ -637,18 +666,18 @@ static int usbasp_open(PROGRAMMER *pgm, const char *port) { return 0; } -static void usbasp_close(PROGRAMMER * pgm) -{ +static void usbasp_close(PROGRAMMER *pgm) { pmsg_debug("usbasp_close()\n"); - if (PDATA(pgm)->usbhandle!=NULL) { + if(PDATA(pgm)->usbhandle != NULL) { unsigned char temp[4]; + memset(temp, 0, sizeof(temp)); - if (PDATA(pgm)->use_tpi) { - usbasp_transmit(pgm, 1, USBASP_FUNC_TPI_DISCONNECT, temp, temp, sizeof(temp)); + if(PDATA(pgm)->use_tpi) { + usbasp_transmit(pgm, 1, USBASP_FUNC_TPI_DISCONNECT, temp, temp, sizeof(temp)); } else { - usbasp_transmit(pgm, 1, USBASP_FUNC_DISCONNECT, temp, temp, sizeof(temp)); + usbasp_transmit(pgm, 1, USBASP_FUNC_DISCONNECT, temp, temp, sizeof(temp)); } #ifdef USE_LIBUSB_1_0 @@ -657,15 +686,14 @@ static void usbasp_close(PROGRAMMER * pgm) usb_close(PDATA(pgm)->usbhandle); #endif } + #ifdef USE_LIBUSB_1_0 libusb_exit(PDATA(pgm)->ctx); #else - /* nothing for usb 0.1 ? */ + // Nothing for usb 0.1? #endif } - -/* Dummy functions */ static void usbasp_disable(const PROGRAMMER *pgm) { return; } @@ -678,11 +706,7 @@ static void usbasp_display(const PROGRAMMER *pgm, const char *p) { return; } - - -// @@@ - -/* Universal functions: for both SPI and TPI */ +// Universal functions: for both SPI and TPI static int usbasp_initialize(const PROGRAMMER *pgm, const AVRPART *p) { unsigned char temp[4]; unsigned char res[4]; @@ -690,66 +714,57 @@ static int usbasp_initialize(const PROGRAMMER *pgm, const AVRPART *p) { pmsg_debug("usbasp_initialize()\n"); - /* get capabilities */ + // Get capabilities memset(temp, 0, sizeof(temp)); - if(usbasp_transmit(pgm, 1, USBASP_FUNC_GETCAPABILITIES, temp, res, sizeof(res)) == 4) - pdata->capabilities = res[0] | ((unsigned int)res[1] << 8) | ((unsigned int)res[2] << 16) | ((unsigned int)res[3] << 24); - else - pdata->capabilities = 0; + pdata->capabilities = usbasp_transmit(pgm, 1, USBASP_FUNC_GETCAPABILITIES, temp, res, sizeof(res)) == 4? + res[0] | ((unsigned int) res[1] << 8) | ((unsigned int) res[2] << 16) | ((unsigned int) res[3] << 24): 0; pdata->use_tpi = (pdata->capabilities & USBASP_CAP_TPI) && (p->prog_modes & PM_TPI); - // query support for 3 MHz SCK in UsbAsp-flash firmware - // https://github.com/nofeletru/UsbAsp-flash - pdata->sck_3mhz = ((pdata->capabilities & USBASP_CAP_3MHZ) != 0) ? 1 :0; + // Query support for 3 MHz SCK in UsbAsp-flash firmware https://github.com/nofeletru/UsbAsp-flash + pdata->sck_3mhz = ((pdata->capabilities & USBASP_CAP_3MHZ) != 0)? 1: 0; + + if(pdata->use_tpi) { + // Calc tpiclk delay + int dly = 1500000.0*pgm->bitclock; - if(pdata->use_tpi) - { - /* calc tpiclk delay */ - int dly = 1500000.0 * pgm->bitclock; if(dly < 1) - dly = 1; + dly = 1; else if(dly > 2047) - dly = 2047; + dly = 2047; temp[0] = dly; temp[1] = dly >> 8; - /* connect */ + // Connect usbasp_transmit(pgm, 1, USBASP_FUNC_TPI_CONNECT, temp, res, sizeof(res)); - } - else - { - /* set sck period */ + } else { + // Set sck period pgm->set_sck_period(pgm, pgm->bitclock); - /* connect to target device */ + // Connect to target device usbasp_transmit(pgm, 1, USBASP_FUNC_CONNECT, temp, res, sizeof(res)); } - /* wait, so device is ready to receive commands */ + // Wait, so device is ready to receive commands usleep(100000); return pgm->program_enable(pgm, p); } -/* SPI specific functions */ -static int usbasp_spi_cmd(const PROGRAMMER *pgm, const unsigned char *cmd, - unsigned char *res) -{ +// SPI specific functions +static int usbasp_spi_cmd(const PROGRAMMER *pgm, const unsigned char *cmd, unsigned char *res) { pmsg_debug("usbasp_spi_cmd(0x%02x, 0x%02x, 0x%02x, 0x%02x)%s", cmd[0], cmd[1], cmd[2], cmd[3], verbose >= MSG_TRACE? " ...\n": ""); - int nbytes = - usbasp_transmit(pgm, 1, USBASP_FUNC_TRANSMIT, cmd, res, 4); + int nbytes = usbasp_transmit(pgm, 1, USBASP_FUNC_TRANSMIT, cmd, res, 4); - if(nbytes != 4){ + if(nbytes != 4) { msg_debug("\n"); pmsg_error("wrong response size\n"); return -1; } pmsg_trace("usbasp_spi_cmd()"); - msg_debug(" => 0x%02x, 0x%02x, 0x%02x, 0x%02x\n", - res[0], res[1], res[2], res[3]); + msg_debug(" => 0x%02x, 0x%02x, 0x%02x, 0x%02x\n", res[0], res[1], res[2], res[3]); return 0; } @@ -757,6 +772,7 @@ static int usbasp_spi_cmd(const PROGRAMMER *pgm, const unsigned char *cmd, static int usbasp_spi_program_enable(const PROGRAMMER *pgm, const AVRPART *p) { unsigned char res[4]; unsigned char cmd[4]; + memset(cmd, 0, sizeof(cmd)); memset(res, 0, sizeof(res)); @@ -764,10 +780,9 @@ static int usbasp_spi_program_enable(const PROGRAMMER *pgm, const AVRPART *p) { pmsg_debug("usbasp_program_enable()\n"); - int nbytes = - usbasp_transmit(pgm, 1, USBASP_FUNC_ENABLEPROG, cmd, res, sizeof(res)); + int nbytes = usbasp_transmit(pgm, 1, USBASP_FUNC_ENABLEPROG, cmd, res, sizeof(res)); - if ((nbytes != 1) | (res[0] != 0)) { + if((nbytes != 1) | (res[0] != 0)) { pmsg_error("program enable: target does not answer (0x%02x)\n", res[0]); return -1; } @@ -781,7 +796,7 @@ static int usbasp_spi_chip_erase(const PROGRAMMER *pgm, const AVRPART *p) { pmsg_debug("usbasp_chip_erase()\n"); - 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; } @@ -808,29 +823,30 @@ static int usbasp_spi_paged_load(const PROGRAMMER *pgm, const AVRPART *p, const pmsg_debug("usbasp_program_paged_load(\"%s\", 0x%x, %d)\n", m->desc, address, n_bytes); - if (mem_is_flash(m)) { + if(mem_is_flash(m)) { function = USBASP_FUNC_READFLASH; - } else if (mem_is_eeprom(m)) { + } else if(mem_is_eeprom(m)) { function = USBASP_FUNC_READEEPROM; } else { return -2; } - /* set blocksize depending on sck frequency */ - if ((PDATA(pgm)->sckfreq_hz > 0) && (PDATA(pgm)->sckfreq_hz < 10000)) { - blocksize = USBASP_READBLOCKSIZE / 10; + // Set blocksize depending on sck frequency + if((PDATA(pgm)->sckfreq_hz > 0) && (PDATA(pgm)->sckfreq_hz < 10000)) { + blocksize = USBASP_READBLOCKSIZE/10; } else { - blocksize = USBASP_READBLOCKSIZE; + blocksize = USBASP_READBLOCKSIZE; } - while (wbytes) { - if (wbytes <= blocksize) { + while(wbytes) { + if(wbytes <= blocksize) { blocksize = wbytes; } wbytes -= blocksize; - /* set address (new mode) - if firmware on usbasp support newmode, then they use address from this command */ + // Set address (new mode) - if firmware on usbasp support newmode, then they use address from this command unsigned char temp[4]; + memset(temp, 0, sizeof(temp)); cmd[0] = address & 0xFF; cmd[1] = address >> 8; @@ -839,16 +855,16 @@ static int usbasp_spi_paged_load(const PROGRAMMER *pgm, const AVRPART *p, const usbasp_transmit(pgm, 1, USBASP_FUNC_SETLONGADDRESS, cmd, temp, sizeof(temp)); /* send command with address (compatibility mode) - if firmware on - usbasp doesn't support newmode, then they use address from this */ + usbasp doesn't support newmode, then they use address from this */ cmd[0] = address & 0xFF; cmd[1] = address >> 8; - // for compatibility - previous version of usbasp.c doesn't initialize this fields (firmware ignore it) + // For compatibility: previous version of usbasp.c has not initializes these fields (as FW ignored them) cmd[2] = 0; cmd[3] = 0; n = usbasp_transmit(pgm, 1, function, cmd, buffer, blocksize); - if (n != blocksize) { + if(n != blocksize) { pmsg_error("wrong reading bytes %x\n", n); return -3; } @@ -873,32 +889,32 @@ static int usbasp_spi_paged_write(const PROGRAMMER *pgm, const AVRPART *p, const pmsg_debug("usbasp_program_paged_write(\"%s\", 0x%x, %d)\n", m->desc, address, n_bytes); - if (mem_is_flash(m)) { + if(mem_is_flash(m)) { function = USBASP_FUNC_WRITEFLASH; - } else if (mem_is_eeprom(m)) { + } else if(mem_is_eeprom(m)) { function = USBASP_FUNC_WRITEEEPROM; } else { return -2; } - /* set blocksize depending on sck frequency */ - if ((PDATA(pgm)->sckfreq_hz > 0) && (PDATA(pgm)->sckfreq_hz < 10000)) { - blocksize = USBASP_WRITEBLOCKSIZE / 10; + // Set blocksize depending on sck frequency + if((PDATA(pgm)->sckfreq_hz > 0) && (PDATA(pgm)->sckfreq_hz < 10000)) { + blocksize = USBASP_WRITEBLOCKSIZE/10; } else { - blocksize = USBASP_WRITEBLOCKSIZE; + blocksize = USBASP_WRITEBLOCKSIZE; } - while (wbytes) { + while(wbytes) { - if (wbytes <= blocksize) { + if(wbytes <= blocksize) { blocksize = wbytes; } wbytes -= blocksize; - /* set address (new mode) - if firmware on usbasp support newmode, then - they use address from this command */ + they use address from this command */ unsigned char temp[4]; + memset(temp, 0, sizeof(temp)); cmd[0] = address & 0xFF; cmd[1] = address >> 8; @@ -907,22 +923,21 @@ static int usbasp_spi_paged_write(const PROGRAMMER *pgm, const AVRPART *p, const usbasp_transmit(pgm, 1, USBASP_FUNC_SETLONGADDRESS, cmd, temp, sizeof(temp)); /* normal command - firmware what support newmode - use address from previous command, - firmware what doesn't support newmode - ignore previous command and use address from this command */ + firmware what doesn't support newmode - ignore previous command and use address from this command */ cmd[0] = address & 0xFF; cmd[1] = address >> 8; cmd[2] = page_size & 0xFF; - cmd[3] = (blockflags & 0x0F) + ((page_size & 0xF00) >> 4); //TP: Mega128 fix + cmd[3] = (blockflags & 0x0F) + ((page_size & 0xF00) >> 4); // TP: Mega128 fix blockflags = 0; n = usbasp_transmit(pgm, 0, function, cmd, buffer, blocksize); - if (n != blocksize) { + if(n != blocksize) { pmsg_error("wrong count at writing %x\n", n); - return -3; + return -3; } - buffer += blocksize; address += blocksize; } @@ -930,26 +945,26 @@ static int usbasp_spi_paged_write(const PROGRAMMER *pgm, const AVRPART *p, const return n_bytes; } -/* The list of SCK frequencies in Hz supported by USBasp */ +// The list of SCK frequencies in Hz supported by USBasp static const struct sckoptions usbaspSCKoptions[] = { - { USBASP_ISP_SCK_3000, 3000000 }, - { USBASP_ISP_SCK_1500, 1500000 }, - { USBASP_ISP_SCK_750, 750000 }, - { USBASP_ISP_SCK_375, 375000 }, - { USBASP_ISP_SCK_187_5, 187500 }, - { USBASP_ISP_SCK_93_75, 93750 }, - { USBASP_ISP_SCK_32, 32000 }, - { USBASP_ISP_SCK_16, 16000 }, - { USBASP_ISP_SCK_8, 8000 }, - { USBASP_ISP_SCK_4, 4000 }, - { USBASP_ISP_SCK_2, 2000 }, - { USBASP_ISP_SCK_1, 1000 }, - { USBASP_ISP_SCK_0_5, 500 } + {USBASP_ISP_SCK_3000, 3000000}, + {USBASP_ISP_SCK_1500, 1500000}, + {USBASP_ISP_SCK_750, 750000}, + {USBASP_ISP_SCK_375, 375000}, + {USBASP_ISP_SCK_187_5, 187500}, + {USBASP_ISP_SCK_93_75, 93750}, + {USBASP_ISP_SCK_32, 32000}, + {USBASP_ISP_SCK_16, 16000}, + {USBASP_ISP_SCK_8, 8000}, + {USBASP_ISP_SCK_4, 4000}, + {USBASP_ISP_SCK_2, 2000}, + {USBASP_ISP_SCK_1, 1000}, + {USBASP_ISP_SCK_0_5, 500} }; /* * Set sck period (in seconds) - * Find next possible sck period and write it to the programmer. + * Find next possible sck period and write it to the programmer */ static int usbasp_spi_set_sck_period(const PROGRAMMER *pgm, double sckperiod) { char clockoption = USBASP_ISP_SCK_AUTO; @@ -961,39 +976,39 @@ static int usbasp_spi_set_sck_period(const PROGRAMMER *pgm, double sckperiod) { memset(cmd, 0, sizeof(cmd)); memset(res, 0, sizeof(res)); - /* reset global sck frequency to auto */ + // Reset global sck frequency to auto PDATA(pgm)->sckfreq_hz = 0; - if (sckperiod == 0) { - /* auto sck set */ - + if(sckperiod == 0) { + // Auto sck set pmsg_notice2("auto set sck period\n"); } else { - int sckfreq = 1 / sckperiod; /* sck in Hz */ + int sckfreq = 1/sckperiod; // sck in Hz int usefreq = 0; pmsg_notice2("try to set SCK period to %g s (= %i Hz)\n", sckperiod, sckfreq); - /* Check if programmer is capable of 3 MHz SCK, if not then ommit 3 MHz setting */ + // Check if programmer is capable of 3 MHz SCK, if not then ommit 3 MHz setting size_t i; - if (PDATA(pgm)->sck_3mhz) { + + if(PDATA(pgm)->sck_3mhz) { pmsg_notice2("connected USBasp is capable of 3 MHz SCK\n"); i = 0; } else { pmsg_notice2("connected USBasp is not cabable of 3 MHz SCK\n"); i = 1; } - if (sckfreq >= usbaspSCKoptions[i].frequency) { + if(sckfreq >= usbaspSCKoptions[i].frequency) { clockoption = usbaspSCKoptions[i].id; usefreq = usbaspSCKoptions[i].frequency; } else { - /* find clock option next to given clock */ + // Find clock option next to given clock - for (; i < sizeof(usbaspSCKoptions) / sizeof(usbaspSCKoptions[0]); i++) { - if (sckfreq >= usbaspSCKoptions[i].frequency - 1) { /* subtract 1 to compensate round errors */ + for(; i < sizeof(usbaspSCKoptions)/sizeof(usbaspSCKoptions[0]); i++) { + if(sckfreq >= usbaspSCKoptions[i].frequency - 1) { // Subtract 1 to compensate rounding errors clockoption = usbaspSCKoptions[i].id; usefreq = usbaspSCKoptions[i].frequency; break; @@ -1001,7 +1016,7 @@ static int usbasp_spi_set_sck_period(const PROGRAMMER *pgm, double sckperiod) { } } - /* save used sck frequency */ + // Save used sck frequency PDATA(pgm)->sckfreq_hz = usefreq; pmsg_info("set SCK frequency to %i Hz\n", usefreq); @@ -1009,10 +1024,9 @@ static int usbasp_spi_set_sck_period(const PROGRAMMER *pgm, double sckperiod) { cmd[0] = clockoption; - int nbytes = - usbasp_transmit(pgm, 1, USBASP_FUNC_SETISPSCK, cmd, res, sizeof(res)); + int nbytes = usbasp_transmit(pgm, 1, USBASP_FUNC_SETISPSCK, cmd, res, sizeof(res)); - if ((nbytes != 1) | (res[0] != 0)) { + if((nbytes != 1) | (res[0] != 0)) { pmsg_error("cannot set sck period; please check for usbasp firmware update\n"); return -1; } @@ -1020,9 +1034,10 @@ static int usbasp_spi_set_sck_period(const PROGRAMMER *pgm, double sckperiod) { return 0; } -/* TPI specific functions */ +// TPI specific functions static void usbasp_tpi_send_byte(const PROGRAMMER *pgm, uint8_t b) { unsigned char temp[4]; + memset(temp, 0, sizeof(temp)); temp[0] = b; @@ -1030,13 +1045,12 @@ static void usbasp_tpi_send_byte(const PROGRAMMER *pgm, uint8_t b) { usbasp_transmit(pgm, 1, USBASP_FUNC_TPI_RAWWRITE, temp, temp, sizeof(temp)); } - static int usbasp_tpi_recv_byte(const PROGRAMMER *pgm) { unsigned char temp[4]; + memset(temp, 0, sizeof(temp)); - if(usbasp_transmit(pgm, 1, USBASP_FUNC_TPI_RAWREAD, temp, temp, sizeof(temp)) != 1) - { + if(usbasp_transmit(pgm, 1, USBASP_FUNC_TPI_RAWREAD, temp, temp, sizeof(temp)) != 1) { pmsg_error("wrong response size\n"); return -1; } @@ -1044,14 +1058,12 @@ static int usbasp_tpi_recv_byte(const PROGRAMMER *pgm) { return temp[0]; } - static int usbasp_tpi_nvm_waitbusy(const PROGRAMMER *pgm) { int retry; pmsg_debug("usbasp_tpi_nvm_waitbusy() ..."); - for(retry=50; retry>0; retry--) - { + for(retry = 50; retry > 0; retry--) { usbasp_tpi_send_byte(pgm, TPI_OP_SIN(NVMCSR)); if(usbasp_tpi_recv_byte(pgm) & NVMCSR_BSY) continue; @@ -1076,11 +1088,11 @@ static int usbasp_tpi_program_enable(const PROGRAMMER *pgm, const AVRPART *p) { pmsg_debug("usbasp_tpi_program_enable()\n"); - /* change guard time */ + // Change guard time usbasp_tpi_send_byte(pgm, TPI_OP_SSTCS(TPIPCR)); usbasp_tpi_send_byte(pgm, TPIPCR_GT_2b); - /* send SKEY */ + // Send SKEY usbasp_tpi_send_byte(pgm, 0xE0); usbasp_tpi_send_byte(pgm, 0xFF); usbasp_tpi_send_byte(pgm, 0x88); @@ -1091,9 +1103,8 @@ static int usbasp_tpi_program_enable(const PROGRAMMER *pgm, const AVRPART *p) { usbasp_tpi_send_byte(pgm, 0x89); usbasp_tpi_send_byte(pgm, 0x12); - /* check if device is ready */ - for(retry=0; retry<10; retry++) - { + // Check if device is ready + for(retry = 0; retry < 10; retry++) { usbasp_tpi_send_byte(pgm, TPI_OP_SLDCS(TPIIR)); if(usbasp_tpi_recv_byte(pgm) != 0x80) continue; @@ -1102,8 +1113,7 @@ static int usbasp_tpi_program_enable(const PROGRAMMER *pgm, const AVRPART *p) { continue; break; } - if(retry >= 10) - { + if(retry >= 10) { pmsg_error("program enable, target does not answer\n"); return -1; } @@ -1117,14 +1127,14 @@ static int usbasp_tpi_chip_erase(const PROGRAMMER *pgm, const AVRPART *p) { int nvm_cmd; switch (PDATA(pgm)->section_e) { - /* Config bits section erase */ + // Config bits section erase case 1: pr_0 = 0x41; pr_1 = 0x3F; nvm_cmd = NVMCMD_SECTION_ERASE; pmsg_debug("usbasp_tpi_chip_erase() - section erase\n"); break; - /* Chip erase (flash only) */ + // Chip erase (flash only) default: pr_0 = 0x01; pr_1 = 0x40; @@ -1133,15 +1143,15 @@ static int usbasp_tpi_chip_erase(const PROGRAMMER *pgm, const AVRPART *p) { break; } - /* Set PR */ + // Set PR usbasp_tpi_send_byte(pgm, TPI_OP_SSTPR(0)); usbasp_tpi_send_byte(pgm, pr_0); usbasp_tpi_send_byte(pgm, TPI_OP_SSTPR(1)); usbasp_tpi_send_byte(pgm, pr_1); - /* select what been erase */ + // Select what been erase usbasp_tpi_send_byte(pgm, TPI_OP_SOUT(NVMCMD)); usbasp_tpi_send_byte(pgm, nvm_cmd); - /* dummy write */ + // Dummy write usbasp_tpi_send_byte(pgm, TPI_OP_SST_INC); usbasp_tpi_send_byte(pgm, 0x00); usbasp_tpi_nvm_waitbusy(pgm); @@ -1156,35 +1166,32 @@ static int usbasp_tpi_paged_load(const PROGRAMMER *pgm, const AVRPART *p, const unsigned int page_size, unsigned int addr, unsigned int n_bytes) { unsigned char cmd[4]; - unsigned char* dptr; + unsigned char *dptr; int read, clen, n; uint16_t pr; - pmsg_debug("usbasp_tpi_paged_load(\"%s\", 0x%0x, %d)\n", m->desc, addr, n_bytes); dptr = addr + m->buf; pr = addr + m->offset; read = 0; - while(read < (int) n_bytes) - { + while(read < (int) n_bytes) { clen = n_bytes - read; if(clen > 32) clen = 32; - /* prepare READBLOCK cmd */ + // Prepare READBLOCK cmd cmd[0] = pr & 0xFF; cmd[1] = pr >> 8; cmd[2] = 0; cmd[3] = 0; n = usbasp_transmit(pgm, 1, USBASP_FUNC_TPI_READBLOCK, cmd, dptr, clen); - if(n != clen) - { + if(n != clen) { pmsg_error("wrong reading bytes %x\n", n); return -3; } - + read += clen; pr += clen; dptr += clen; @@ -1197,58 +1204,55 @@ int usbasp_tpi_paged_write(const PROGRAMMER *pgm, const AVRPART *p, const AVRMEM unsigned int page_size, unsigned int addr, unsigned int n_bytes) { unsigned char cmd[4]; - unsigned char* sptr; + unsigned char *sptr; int written, clen, n; uint16_t pr; - pmsg_debug("usbasp_tpi_paged_write(\"%s\", 0x%0x, %d)\n", m->desc, addr, n_bytes); sptr = addr + m->buf; pr = addr + m->offset; written = 0; - /* must erase fuse first, TPI parts only have one fuse */ + // Must erase fuse first, TPI parts only have one fuse if(mem_is_a_fuse(m)) { // Keep fuse writing ability for backward compatibility - /* Set PR */ + // Set PR usbasp_tpi_send_byte(pgm, TPI_OP_SSTPR(0)); - usbasp_tpi_send_byte(pgm, (pr & 0xFF) | 1 ); + usbasp_tpi_send_byte(pgm, (pr & 0xFF) | 1); usbasp_tpi_send_byte(pgm, TPI_OP_SSTPR(1)); - usbasp_tpi_send_byte(pgm, (pr >> 8) ); - /* select SECTION_ERASE */ + usbasp_tpi_send_byte(pgm, (pr >> 8)); + // Select SECTION_ERASE usbasp_tpi_send_byte(pgm, TPI_OP_SOUT(NVMCMD)); usbasp_tpi_send_byte(pgm, NVMCMD_SECTION_ERASE); - /* dummy write */ + // Dummy write usbasp_tpi_send_byte(pgm, TPI_OP_SST_INC); usbasp_tpi_send_byte(pgm, 0x00); usbasp_tpi_nvm_waitbusy(pgm); } - /* Set PR to flash */ + // Set PR to flash usbasp_tpi_send_byte(pgm, TPI_OP_SSTPR(0)); - usbasp_tpi_send_byte(pgm, (pr & 0xFF) | 1 ); + usbasp_tpi_send_byte(pgm, (pr & 0xFF) | 1); usbasp_tpi_send_byte(pgm, TPI_OP_SSTPR(1)); - usbasp_tpi_send_byte(pgm, (pr >> 8) ); + usbasp_tpi_send_byte(pgm, (pr >> 8)); - while(written < (int) n_bytes) - { + while(written < (int) n_bytes) { clen = n_bytes - written; if(clen > 32) clen = 32; - /* prepare WRITEBLOCK cmd */ + // Prepare WRITEBLOCK cmd cmd[0] = pr & 0xFF; cmd[1] = pr >> 8; cmd[2] = 0; cmd[3] = 0; n = usbasp_transmit(pgm, 0, USBASP_FUNC_TPI_WRITEBLOCK, cmd, sptr, clen); - if(n != clen) - { + if(n != clen) { pmsg_error("wrong count at writing %x\n", n); return -3; } - + written += clen; pr += clen; sptr += clen; @@ -1261,7 +1265,8 @@ static int usbasp_tpi_set_sck_period(const PROGRAMMER *pgm, double sckperiod) { return 0; } -static int usbasp_tpi_read_byte(const PROGRAMMER * pgm, const AVRPART *p, const AVRMEM *m, unsigned long addr, unsigned char *value) { +static int usbasp_tpi_read_byte(const PROGRAMMER *pgm, const AVRPART *p, const AVRMEM *m, unsigned long addr, + unsigned char *value) { unsigned char cmd[4]; int n; uint16_t pr; @@ -1270,7 +1275,7 @@ static int usbasp_tpi_read_byte(const PROGRAMMER * pgm, const AVRPART *p, const pr = m->offset + addr; - /* READBLOCK */ + // READBLOCK cmd[0] = pr & 0xFF; cmd[1] = pr >> 8; cmd[2] = 0; @@ -1292,24 +1297,23 @@ static int usbasp_tpi_write_byte(const PROGRAMMER *pgm, const AVRPART *p, const pmsg_error("cannot write_byte() to %s; use paged_write()\n", m->desc); return -1; } - // Memories left: fuse and lockbits if(addr != 0) { pmsg_error("unexpected address 0x%04lx of %s memory\n", addr, m->desc); return -1; - } + } uint16_t pr = addr + m->offset; usbasp_tpi_nvm_waitbusy(pgm); // Must erase fuse first, TPI parts only have one fuse - if(mem_is_a_fuse(m)) { // Lockbits are reset during chip erase + if(mem_is_a_fuse(m)) { // Lockbits are reset during chip erase // Set pointer register to pr + 1 usbasp_tpi_send_byte(pgm, TPI_OP_SSTPR(0)); - usbasp_tpi_send_byte(pgm, (pr & 0xFF) | 1 ); + usbasp_tpi_send_byte(pgm, (pr & 0xFF) | 1); usbasp_tpi_send_byte(pgm, TPI_OP_SSTPR(1)); - usbasp_tpi_send_byte(pgm, (pr >> 8) ); + usbasp_tpi_send_byte(pgm, (pr >> 8)); // Select SECTION_ERASE usbasp_tpi_send_byte(pgm, TPI_OP_SOUT(NVMCMD)); usbasp_tpi_send_byte(pgm, NVMCMD_SECTION_ERASE); @@ -1319,12 +1323,11 @@ static int usbasp_tpi_write_byte(const PROGRAMMER *pgm, const AVRPART *p, const usbasp_tpi_nvm_waitbusy(pgm); } - // Reset pointer register to pr usbasp_tpi_send_byte(pgm, TPI_OP_SSTPR(0)); usbasp_tpi_send_byte(pgm, pr & 0xFF); usbasp_tpi_send_byte(pgm, TPI_OP_SSTPR(1)); - usbasp_tpi_send_byte(pgm, (pr >> 8) ); + usbasp_tpi_send_byte(pgm, (pr >> 8)); // Select word write usbasp_tpi_send_byte(pgm, TPI_OP_SOUT(NVMCMD)); usbasp_tpi_send_byte(pgm, NVMCMD_WORD_WRITE); @@ -1340,41 +1343,33 @@ static int usbasp_tpi_write_byte(const PROGRAMMER *pgm, const AVRPART *p, const return 0; } - void usbasp_initpgm(PROGRAMMER *pgm) { strcpy(pgm->type, "usbasp"); - /* - * mandatory functions - */ - - pgm->initialize = usbasp_initialize; - pgm->display = usbasp_display; - pgm->enable = usbasp_enable; - pgm->disable = usbasp_disable; + // Mandatory functions + pgm->initialize = usbasp_initialize; + pgm->display = usbasp_display; + pgm->enable = usbasp_enable; + pgm->disable = usbasp_disable; pgm->program_enable = usbasp_program_enable; - pgm->chip_erase = usbasp_chip_erase; - pgm->cmd = usbasp_cmd; - pgm->open = usbasp_open; - pgm->close = usbasp_close; - pgm->read_byte = usbasp_read_byte; - pgm->write_byte = usbasp_write_byte; + pgm->chip_erase = usbasp_chip_erase; + pgm->cmd = usbasp_cmd; + pgm->open = usbasp_open; + pgm->close = usbasp_close; + pgm->read_byte = usbasp_read_byte; + pgm->write_byte = usbasp_write_byte; - /* - * optional functions - */ - - pgm->paged_write = usbasp_paged_write; - pgm->paged_load = usbasp_paged_load; - pgm->setup = usbasp_setup; - pgm->teardown = usbasp_teardown; + // Optional functions + pgm->paged_write = usbasp_paged_write; + pgm->paged_load = usbasp_paged_load; + pgm->setup = usbasp_setup; + pgm->teardown = usbasp_teardown; pgm->set_sck_period = usbasp_set_sck_period; pgm->parseextparams = usbasp_parseextparms; } - -#else /* HAVE_LIBUSB */ +#else // HAVE_LIBUSB static int usbasp_nousb_open(PROGRAMMER *pgm, const char *name) { pmsg_error("no usb support; please compile again with libusb installed\n"); @@ -1385,9 +1380,8 @@ static int usbasp_nousb_open(PROGRAMMER *pgm, const char *name) { void usbasp_initpgm(PROGRAMMER *pgm) { strcpy(pgm->type, "usbasp"); - pgm->open = usbasp_nousb_open; + pgm->open = usbasp_nousb_open; } - -#endif /* HAVE_LIBUSB */ +#endif // HAVE_LIBUSB const char usbasp_desc[] = "USBasp programmer, see http://www.fischl.de/usbasp/";