diff --git a/src/avrftdi.c b/src/avrftdi.c index 47b71e6f..9283321e 100644 --- a/src/avrftdi.c +++ b/src/avrftdi.c @@ -17,9 +17,7 @@ * along with this program. If not, see . */ -/* - * Interface to the MPSSE Engine of FTDI Chips using libftdi. - */ +// Interface to the MPSSE Engine of FTDI Chips using libftdi #include #include @@ -42,28 +40,28 @@ #include "usbdevs.h" #ifndef MAX -#define MAX(a,b) ((a)>(b)?(a):(b)) +#define MAX(a, b) ((a)>(b)?(a):(b)) #endif + #ifndef MIN -#define MIN(a,b) ((a)<(b)?(a):(b)) +#define MIN(a, b) ((a)<(b)?(a):(b)) #endif #ifdef DO_NOT_BUILD_AVRFTDI - static int avrftdi_noftdi_open(PROGRAMMER *pgm, const char *name) { - pmsg_error("no libftdi or libusb support; install\n"); - imsg_error("libftdi1/libusb-1.0 or libftdi/libusb and run configure/make again\n"); - return -1; + pmsg_error("no libftdi or libusb support; install\n"); + imsg_error("libftdi1/libusb-1.0 or libftdi/libusb and run configure/make again\n"); + return -1; } void avrftdi_initpgm(PROGRAMMER *pgm) { - strcpy(pgm->type, "avrftdi"); - pgm->open = avrftdi_noftdi_open; + strcpy(pgm->type, "avrftdi"); + pgm->open = avrftdi_noftdi_open; } void avrftdi_jtag_initpgm(PROGRAMMER *pgm) { - strcpy(pgm->type, "avrftdi_jtag"); - pgm->open = avrftdi_noftdi_open; + strcpy(pgm->type, "avrftdi_jtag"); + pgm->open = avrftdi_noftdi_open; } #else @@ -75,309 +73,294 @@ void avrftdi_jtag_initpgm(PROGRAMMER *pgm) { #define PGM_FL_IS_UPDI (0x0010) #define PGM_FL_IS_TPI (0x0020) -/* MPSSE pins */ +// MPSSE pins enum { - FTDI_TCK_SCK = 0, - FTDI_TDI_SDO, - FTDI_TDO_SDI, - FTDI_TMS_CS, + FTDI_TCK_SCK = 0, + FTDI_TDI_SDO, + FTDI_TDO_SDI, + FTDI_TMS_CS, }; static int write_flush(Avrftdi_data *); -/* - * returns a human-readable name for a pin number. The name should match with - * the pin names used in FTDI datasheets. - */ +// Returns a human-readable name for a pin number; the name should match with the FTDI datasheets static char *ftdi_pin_name(Avrftdi_data *pdata, struct pindef pin) { - char *str = pdata->name_str; - size_t strsiz = sizeof pdata->name_str; + char *str = pdata->name_str; + size_t strsiz = sizeof pdata->name_str; - /* - * INTERFACE_ANY is zero: print @ - * INTERFACE_A is one, use '@' + 1 = 'A' and so forth ... - * Be aware, there is an interface member in ftdi_context, - * however, we really want the index member here. - */ - char interface = '@' + pdata->ftdic->index; + /* + * INTERFACE_ANY is zero: print @ + * INTERFACE_A is one, use '@' + 1 = 'A' and so forth ... + * Be aware, there is an interface member in ftdi_context, however, we really + * want the index member here. + */ + char interface = '@' + pdata->ftdic->index; - size_t n = 0; - int mask = pin.mask[0]; + size_t n = 0; + int mask = pin.mask[0]; - str[0] = 0; + str[0] = 0; - for(int pinno = 0; mask && n < strsiz-1; mask >>= 1, pinno++) { - if(!(mask & 1)) - continue; + for(int pinno = 0; mask && n < strsiz - 1; mask >>= 1, pinno++) { + if(!(mask & 1)) + continue; - // FTDI port: probably 'D' for data and 'C' for control - n += snprintf(&str[n], strsiz - n, "%s%c%cBUS%d", n? ", ": "", - interface, pinno < 8? 'D': 'C', pinno); - } + // FTDI port: probably 'D' for data and 'C' for control + n += snprintf(&str[n], strsiz - n, "%s%c%cBUS%d", n? ", ": "", interface, pinno < 8? 'D': 'C', pinno); + } - return str; + return str; } /* - * helper function to print a binary buffer *buf of size len. Begin and end of + * Helper function to print a binary buffer *buf of size len. Begin and end of * the dump are enclosed in the string contained in *desc. Offset denotes the * number of bytes which are printed on the first line (may be 0). After that * width bytes are printed on each line */ -static void buf_dump(const unsigned char *buf, int len, char *desc, - int offset, int width) -{ - int i; - msg_trace2("%s begin:\n", desc); - for (i = 0; i < offset; i++) - msg_trace2("%02x ", buf[i]); - msg_trace2("\n"); - for (i++; i <= len; i++) { - msg_trace2("%02x ", buf[i-1]); - if((i-offset) != 0 && (i-offset)%width == 0) - msg_trace2("\n"); - } - msg_trace2("%s end\n", desc); +static void buf_dump(const unsigned char *buf, int len, char *desc, int offset, int width) { + int i; + + msg_trace2("%s begin:\n", desc); + for(i = 0; i < offset; i++) + msg_trace2("%02x ", buf[i]); + msg_trace2("\n"); + for(i++; i <= len; i++) { + msg_trace2("%02x ", buf[i - 1]); + if((i - offset) != 0 && (i - offset)%width == 0) + msg_trace2("\n"); + } + msg_trace2("%s end\n", desc); } -/* - * calculates the so-called 'divisor'-value from a given frequency. - * the divisor is sent to the chip. - */ +// Calculate the divisor value from a given frequency; the divisor is sent to the chip static int set_frequency(Avrftdi_data *ftdi, uint32_t freq) { - int32_t clock, divisor; - float hs_error, ls_error; - uint8_t buf[4], *ptr = buf; + int32_t clock, divisor; + float hs_error, ls_error; + uint8_t buf[4], *ptr = buf; - if (ftdi->ftdic->type == TYPE_232H || - ftdi->ftdic->type == TYPE_2232H || - ftdi->ftdic->type == TYPE_4232H) { + if(ftdi->ftdic->type == TYPE_232H || ftdi->ftdic->type == TYPE_2232H || ftdi->ftdic->type == TYPE_4232H) { - clock = 60000000; - divisor = ((clock / 2) / freq) - 1; - hs_error = (float)(clock / 2) / (divisor + 1) / freq; + clock = 60000000; + divisor = ((clock/2)/freq) - 1; + hs_error = (float) (clock/2)/(divisor + 1)/freq; - clock = 12000000; - divisor = ((clock / 2) / freq) - 1; - ls_error = (float)(clock / 2) / (divisor + 1) / freq; + clock = 12000000; + divisor = ((clock/2)/freq) - 1; + ls_error = (float) (clock/2)/(divisor + 1)/freq; - if (ls_error <= hs_error) { - *ptr++ = EN_DIV_5; - } else { - clock = 60000000; - divisor = ((clock / 2) / freq) - 1; - *ptr++ = DIS_DIV_5; - } - } else { - clock = 12000000; - divisor = ((clock / 2) / freq) - 1; - } + if(ls_error <= hs_error) { + *ptr++ = EN_DIV_5; + } else { + clock = 60000000; + divisor = ((clock/2)/freq) - 1; + *ptr++ = DIS_DIV_5; + } + } else { + clock = 12000000; + divisor = ((clock/2)/freq) - 1; + } - if (divisor < 0) { - pmsg_warning("frequency %s too high, resetting to %s\n", - str_ccfrq(freq, 6), str_ccfrq(clock/2.0, 6)); - divisor = 0; - } + if(divisor < 0) { + pmsg_warning("frequency %s too high, resetting to %s\n", + str_ccfrq(freq, 6), str_ccfrq(clock/2.0, 6)); + divisor = 0; + } - if (divisor > 65535) { - pmsg_warning("frequency %s too low, resetting to %s\n", - str_ccfrq(freq, 6), str_ccfrq(clock/2.0 / 65536, 6)); - divisor = 65535; - } + if(divisor > 65535) { + pmsg_warning("frequency %s too low, resetting to %s\n", + str_ccfrq(freq, 6), str_ccfrq(clock/2.0/65536, 6)); + divisor = 65535; + } - imsg_notice(" - frequency %s (clock divisor %d = 0x%04x)\n", - str_ccfrq(clock/2.0 / (divisor + 1), 6), divisor, divisor); + imsg_notice(" - frequency %s (clock divisor %d = 0x%04x)\n", + str_ccfrq(clock/2.0/(divisor + 1), 6), divisor, divisor); - *ptr++ = TCK_DIVISOR; - *ptr++ = (uint8_t)(divisor & 0xff); - *ptr++ = (uint8_t)(divisor >> 8) & 0xff; + *ptr++ = TCK_DIVISOR; + *ptr++ = (uint8_t) (divisor & 0xff); + *ptr++ = (uint8_t) (divisor >> 8) & 0xff; - E(ftdi_write_data(ftdi->ftdic, buf, ptr - buf) < 0, ftdi->ftdic); + E(ftdi_write_data(ftdi->ftdic, buf, ptr - buf) < 0, ftdi->ftdic); - return 0; + return 0; } /* - * This function sets or clears any pin, except mandatory pins. Depending - * on the pin configuration, a non-zero value sets the pin in the 'active' - * state (high active, low active) and a zero value sets the pin in the - * inactive state. - * Because we configured the pin direction mask earlier, nothing bad can happen - * here. + * This function sets or clears any pin, except mandatory pins. Depending on + * the pin configuration, a non-zero value sets the pin in the 'active' state + * (high active, low active) and a zero value sets the pin in the inactive + * state. Because we configured the pin direction mask earlier, nothing bad can + * happen here. */ static int set_pin(const PROGRAMMER *pgm, int pinfunc, int value) { - if(pinfunc < 0 || pinfunc >= N_PINS) - return -1; + if(pinfunc < 0 || pinfunc >= N_PINS) + return -1; - Avrftdi_data *pdata = to_pdata(pgm); - struct pindef pin = pgm->pin[pinfunc]; - - if (pin.mask[0] == 0) { - // ignore not defined pins (might be the led or vcc or buff if not needed) - return 0; - } + Avrftdi_data *pdata = to_pdata(pgm); + struct pindef pin = pgm->pin[pinfunc]; - pmsg_debug("setting pin %s (%s) as %s: %s (%s active)\n", - pinmask_to_str(pin.mask), ftdi_pin_name(pdata, pin), avr_pin_name(pinfunc), - (value) ? "high" : "low", (pin.inverse[0]) ? "low" : "high"); + if(pin.mask[0] == 0) // Ignore not defined pins (might be the led or Vcc or buff) + return 0; - pdata->pin_value = SET_BITS_0(pdata->pin_value, pgm, pinfunc, value); + pmsg_debug("setting pin %s (%s) as %s: %s (%s active)\n", + pinmask_to_str(pin.mask), ftdi_pin_name(pdata, pin), avr_pin_name(pinfunc), + (value)? "high": "low", (pin.inverse[0])? "low": "high"); - return write_flush(pdata); + pdata->pin_value = SET_BITS_0(pdata->pin_value, pgm, pinfunc, value); + + return write_flush(pdata); } -/* - * Mandatory callbacks which boil down to GPIO. - */ +// Mandatory callbacks which boil down to GPIO static int avrftdi_rdy_led(const PROGRAMMER *pgm, int value) { - return set_pin(pgm, PIN_LED_RDY, value); + return set_pin(pgm, PIN_LED_RDY, value); } static int avrftdi_err_led(const PROGRAMMER *pgm, int value) { - return set_pin(pgm, PIN_LED_ERR, value); + return set_pin(pgm, PIN_LED_ERR, value); } static int avrftdi_pgm_led(const PROGRAMMER *pgm, int value) { - return set_pin(pgm, PIN_LED_PGM, value); + return set_pin(pgm, PIN_LED_PGM, value); } static int avrftdi_vfy_led(const PROGRAMMER *pgm, int value) { - return set_pin(pgm, PIN_LED_VFY, value); + return set_pin(pgm, PIN_LED_VFY, value); } static void avrftdi_enable(PROGRAMMER *pgm, const AVRPART *p) { - set_pin(pgm, PPI_AVR_BUFF, ON); + set_pin(pgm, PPI_AVR_BUFF, ON); - // Switch to TPI initialisation in avrftdi_tpi.c - if(p->prog_modes & PM_TPI) - avrftdi_tpi_initpgm(pgm); + // Switch to TPI initialisation in avrftdi_tpi.c + if(p->prog_modes & PM_TPI) + avrftdi_tpi_initpgm(pgm); } static void avrftdi_disable(const PROGRAMMER *pgm) { - set_pin(pgm, PPI_AVR_BUFF, OFF); + set_pin(pgm, PPI_AVR_BUFF, OFF); } static void avrftdi_powerup(const PROGRAMMER *pgm) { - set_pin(pgm, PPI_AVR_VCC, ON); + set_pin(pgm, PPI_AVR_VCC, ON); } static void avrftdi_powerdown(const PROGRAMMER *pgm) { - set_pin(pgm, PPI_AVR_VCC, OFF); + set_pin(pgm, PPI_AVR_VCC, OFF); } static inline int set_data(const PROGRAMMER *pgm, unsigned char *buf, unsigned char data, bool read_data) { - int j; - int buf_pos = 0; - unsigned char bit = 0x80; - Avrftdi_data *pdata = to_pdata(pgm); + int j; + int buf_pos = 0; + unsigned char bit = 0x80; + Avrftdi_data *pdata = to_pdata(pgm); - for (j=0; j<8; j++) { - pdata->pin_value = SET_BITS_0(pdata->pin_value,pgm,PIN_AVR_SDO,data & bit); - pdata->pin_value = SET_BITS_0(pdata->pin_value,pgm,PIN_AVR_SCK,0); - buf[buf_pos++] = SET_BITS_LOW; - buf[buf_pos++] = (pdata->pin_value) & 0xff; - buf[buf_pos++] = (pdata->pin_direction) & 0xff; - buf[buf_pos++] = SET_BITS_HIGH; - buf[buf_pos++] = ((pdata->pin_value) >> 8) & 0xff; - buf[buf_pos++] = ((pdata->pin_direction) >> 8) & 0xff; + for(j = 0; j < 8; j++) { + pdata->pin_value = SET_BITS_0(pdata->pin_value, pgm, PIN_AVR_SDO, data & bit); + pdata->pin_value = SET_BITS_0(pdata->pin_value, pgm, PIN_AVR_SCK, 0); + buf[buf_pos++] = SET_BITS_LOW; + buf[buf_pos++] = (pdata->pin_value) & 0xff; + buf[buf_pos++] = (pdata->pin_direction) & 0xff; + buf[buf_pos++] = SET_BITS_HIGH; + buf[buf_pos++] = ((pdata->pin_value) >> 8) & 0xff; + buf[buf_pos++] = ((pdata->pin_direction) >> 8) & 0xff; - pdata->pin_value = SET_BITS_0(pdata->pin_value,pgm,PIN_AVR_SCK,1); - buf[buf_pos++] = SET_BITS_LOW; - buf[buf_pos++] = (pdata->pin_value) & 0xff; - buf[buf_pos++] = (pdata->pin_direction) & 0xff; - buf[buf_pos++] = SET_BITS_HIGH; - buf[buf_pos++] = ((pdata->pin_value) >> 8) & 0xff; - buf[buf_pos++] = ((pdata->pin_direction) >> 8) & 0xff; + pdata->pin_value = SET_BITS_0(pdata->pin_value, pgm, PIN_AVR_SCK, 1); + buf[buf_pos++] = SET_BITS_LOW; + buf[buf_pos++] = (pdata->pin_value) & 0xff; + buf[buf_pos++] = (pdata->pin_direction) & 0xff; + buf[buf_pos++] = SET_BITS_HIGH; + buf[buf_pos++] = ((pdata->pin_value) >> 8) & 0xff; + buf[buf_pos++] = ((pdata->pin_direction) >> 8) & 0xff; - if (read_data) { - buf[buf_pos++] = GET_BITS_LOW; - buf[buf_pos++] = GET_BITS_HIGH; - } + if(read_data) { + buf[buf_pos++] = GET_BITS_LOW; + buf[buf_pos++] = GET_BITS_HIGH; + } - bit >>= 1; - } - return buf_pos; + bit >>= 1; + } + return buf_pos; } static inline unsigned char extract_data(const PROGRAMMER *pgm, unsigned char *buf, int offset) { - int j; - unsigned char bit = 0x80; - unsigned char r = 0; + int j; + unsigned char bit = 0x80; + unsigned char r = 0; - buf += offset * 16; // 2 bytes per bit, 8 bits - for (j=0; j<8; j++) { - uint16_t in = buf[0] | (buf[1] << 8); - if (GET_BITS_0(in,pgm,PIN_AVR_SDI)) { - r |= bit; - } - buf += 2; // 2 bytes per input - bit >>= 1; - } - return r; + buf += offset*16; // 2 bytes per bit, 8 bits + for(j = 0; j < 8; j++) { + uint16_t in = buf[0] | (buf[1] << 8); + + if(GET_BITS_0(in, pgm, PIN_AVR_SDI)) { + r |= bit; + } + buf += 2; // 2 bytes per input + bit >>= 1; + } + return r; } - static int avrftdi_transmit_bb(const PROGRAMMER *pgm, unsigned char mode, const unsigned char *buf, - unsigned char *data, int buf_size) -{ - size_t remaining = buf_size; - size_t written = 0; - Avrftdi_data *pdata = to_pdata(pgm); - size_t blocksize = pdata->rx_buffer_size/2; // we are reading 2 bytes per data byte + unsigned char *data, int buf_size) { + size_t remaining = buf_size; + size_t written = 0; + Avrftdi_data *pdata = to_pdata(pgm); + size_t blocksize = pdata->rx_buffer_size/2; // Reading 2 bytes per data byte - // determine a maximum size of data block - size_t max_size = MIN(pdata->ftdic->max_packet_size, (unsigned int) pdata->tx_buffer_size); - // select block size so that resulting commands does not exceed max_size if possible - blocksize = MAX(1,(max_size-7)/((8*2*6)+(8*1*2))); - // msg_notice("blocksize %d \n", blocksize); + // Determine a maximum size of data block + size_t max_size = MIN(pdata->ftdic->max_packet_size, (unsigned int) pdata->tx_buffer_size); - unsigned char* send_buffer = alloca((8 * 2 * 6) * blocksize + (8 * 1 * 2) * blocksize + 7); - unsigned char* recv_buffer = alloca(2 * 16 * blocksize); + // Select block size so that resulting commands does not exceed max_size if possible + blocksize = MAX(1, (max_size - 7)/((8*2*6) + (8*1*2))); + // msg_notice("blocksize %d \n", blocksize); - while(remaining) - { + unsigned char *send_buffer = alloca(8*2*6*blocksize + 8*1*2*blocksize + 7); + unsigned char *recv_buffer = alloca(2*16*blocksize); - size_t transfer_size = (remaining > blocksize) ? blocksize : remaining; + while(remaining) { - // (8*2) outputs per data byte, 6 transmit bytes per output (SET_BITS_LOW/HIGH), - // (8*1) inputs per data byte, 2 transmit bytes per input (GET_BITS_LOW/HIGH), - // 1x SEND_IMMEDIATE - int len = 0; - - for(size_t i = 0 ; i < transfer_size; i++) { - len += set_data(pgm, send_buffer + len, buf[written+i], (mode & MPSSE_DO_READ) != 0); - } + size_t transfer_size = (remaining > blocksize)? blocksize: remaining; - pdata->pin_value = SET_BITS_0(pdata->pin_value,pgm,PIN_AVR_SCK,0); - send_buffer[len++] = SET_BITS_LOW; - send_buffer[len++] = (pdata->pin_value) & 0xff; - send_buffer[len++] = (pdata->pin_direction) & 0xff; - send_buffer[len++] = SET_BITS_HIGH; - send_buffer[len++] = ((pdata->pin_value) >> 8) & 0xff; - send_buffer[len++] = ((pdata->pin_direction) >> 8) & 0xff; + // (8*2) outputs per data byte, 6 transmit bytes per output (SET_BITS_LOW/HIGH), + // (8*1) inputs per data byte, 2 transmit bytes per input (GET_BITS_LOW/HIGH), + // 1x SEND_IMMEDIATE + int len = 0; - send_buffer[len++] = SEND_IMMEDIATE; + for(size_t i = 0; i < transfer_size; i++) { + len += set_data(pgm, send_buffer + len, buf[written + i], (mode & MPSSE_DO_READ) != 0); + } - E(ftdi_write_data(pdata->ftdic, send_buffer, len) != len, pdata->ftdic); - if (mode & MPSSE_DO_READ) { - int n; - size_t k = 0; - do { - n = ftdi_read_data(pdata->ftdic, &recv_buffer[k], 2*16*transfer_size - k); - E(n < 0, pdata->ftdic); - k += n; - } while (k < transfer_size); + pdata->pin_value = SET_BITS_0(pdata->pin_value, pgm, PIN_AVR_SCK, 0); + send_buffer[len++] = SET_BITS_LOW; + send_buffer[len++] = (pdata->pin_value) & 0xff; + send_buffer[len++] = (pdata->pin_direction) & 0xff; + send_buffer[len++] = SET_BITS_HIGH; + send_buffer[len++] = ((pdata->pin_value) >> 8) & 0xff; + send_buffer[len++] = ((pdata->pin_direction) >> 8) & 0xff; - for(size_t i = 0 ; i< transfer_size; i++) { - data[written + i] = extract_data(pgm, recv_buffer, i); - } - } - - written += transfer_size; - remaining -= transfer_size; - } - - return written; + send_buffer[len++] = SEND_IMMEDIATE; + + E(ftdi_write_data(pdata->ftdic, send_buffer, len) != len, pdata->ftdic); + if(mode & MPSSE_DO_READ) { + int n; + size_t k = 0; + + do { + n = ftdi_read_data(pdata->ftdic, &recv_buffer[k], 2*16*transfer_size - k); + E(n < 0, pdata->ftdic); + k += n; + } while(k < transfer_size); + + for(size_t i = 0; i < transfer_size; i++) { + data[written + i] = extract_data(pgm, recv_buffer, i); + } + } + + written += transfer_size; + remaining -= transfer_size; + } + + return written; } /* Send 'buf_size' bytes from 'cmd' to device and return data from device in @@ -386,1436 +369,1375 @@ static int avrftdi_transmit_bb(const PROGRAMMER *pgm, unsigned char mode, const * Read is only performed when mode contains MPSSE_DO_WRITE and MPSSE_DO_READ. */ static int avrftdi_transmit_mpsse(Avrftdi_data *pdata, unsigned char mode, const unsigned char *buf, - unsigned char *data, int buf_size) -{ - size_t blocksize; - size_t remaining = buf_size; - size_t written = 0; - - unsigned char cmd[3]; -// unsigned char si = SEND_IMMEDIATE; + unsigned char *data, int buf_size) { + size_t blocksize; + size_t remaining = buf_size; + size_t written = 0; - cmd[0] = mode | MPSSE_WRITE_NEG; - cmd[1] = ((buf_size - 1) & 0xff); - cmd[2] = (((buf_size - 1) >> 8) & 0xff); + unsigned char cmd[3]; - //if we are not reading back, we can just write the data out - if(!(mode & MPSSE_DO_READ)) - blocksize = buf_size; - else - blocksize = pdata->rx_buffer_size; +// unsigned char si = SEND_IMMEDIATE; - E(ftdi_write_data(pdata->ftdic, cmd, sizeof(cmd)) != sizeof(cmd), pdata->ftdic); + cmd[0] = mode | MPSSE_WRITE_NEG; + cmd[1] = ((buf_size - 1) & 0xff); + cmd[2] = (((buf_size - 1) >> 8) & 0xff); - while(remaining) - { - size_t transfer_size = (remaining > blocksize) ? blocksize : remaining; + // If we are not reading back, we can just write the data out + if(!(mode & MPSSE_DO_READ)) + blocksize = buf_size; + else + blocksize = pdata->rx_buffer_size; + + E(ftdi_write_data(pdata->ftdic, cmd, sizeof(cmd)) != sizeof(cmd), pdata->ftdic); + + while(remaining) { + size_t transfer_size = (remaining > blocksize)? blocksize: remaining; + + E((size_t) ftdi_write_data(pdata->ftdic, (unsigned char *) &buf[written], + transfer_size) != transfer_size, pdata->ftdic); - E((size_t) ftdi_write_data(pdata->ftdic, (unsigned char*)&buf[written], transfer_size) != transfer_size, pdata->ftdic); #if 0 - if(remaining < blocksize) - E(ftdi_write_data(pdata->ftdic, &si, sizeof(si)) != sizeof(si), pdata->ftdic); + if(remaining < blocksize) + E(ftdi_write_data(pdata->ftdic, &si, sizeof(si)) != sizeof(si), pdata->ftdic); #endif - if (mode & MPSSE_DO_READ) { - int n; - size_t k = 0; - do { - n = ftdi_read_data(pdata->ftdic, &data[written + k], transfer_size - k); - E(n < 0, pdata->ftdic); - k += n; - } while (k < transfer_size); + if(mode & MPSSE_DO_READ) { + int n; + size_t k = 0; - } - - written += transfer_size; - remaining -= transfer_size; - } - - return written; + do { + n = ftdi_read_data(pdata->ftdic, &data[written + k], transfer_size - k); + E(n < 0, pdata->ftdic); + k += n; + } while(k < transfer_size); + + } + + written += transfer_size; + remaining -= transfer_size; + } + + return written; } static inline int avrftdi_transmit(const PROGRAMMER *pgm, unsigned char mode, const unsigned char *buf, - unsigned char *data, int buf_size) -{ - Avrftdi_data *pdata = to_pdata(pgm); - if (pdata->use_bitbanging) - return avrftdi_transmit_bb(pgm, mode, buf, data, buf_size); - else - return avrftdi_transmit_mpsse(pdata, mode, buf, data, buf_size); + unsigned char *data, int buf_size) { + Avrftdi_data *pdata = to_pdata(pgm); + + if(pdata->use_bitbanging) + return avrftdi_transmit_bb(pgm, mode, buf, data, buf_size); + else + return avrftdi_transmit_mpsse(pdata, mode, buf, data, buf_size); } -static int write_flush(Avrftdi_data *pdata) -{ - unsigned char buf[6]; +static int write_flush(Avrftdi_data *pdata) { + unsigned char buf[6]; - pmsg_debug("setting pin direction (0x%04x) and value (0x%04x)\n", - pdata->pin_direction, pdata->pin_value); + pmsg_debug("setting pin direction (0x%04x) and value (0x%04x)\n", pdata->pin_direction, pdata->pin_value); - buf[0] = SET_BITS_LOW; - buf[1] = (pdata->pin_value) & 0xff; - buf[2] = (pdata->pin_direction) & 0xff; - buf[3] = SET_BITS_HIGH; - buf[4] = ((pdata->pin_value) >> 8) & 0xff; - buf[5] = ((pdata->pin_direction) >> 8) & 0xff; + buf[0] = SET_BITS_LOW; + buf[1] = (pdata->pin_value) & 0xff; + buf[2] = (pdata->pin_direction) & 0xff; + buf[3] = SET_BITS_HIGH; + buf[4] = ((pdata->pin_value) >> 8) & 0xff; + buf[5] = ((pdata->pin_direction) >> 8) & 0xff; - E(ftdi_write_data(pdata->ftdic, buf, 6) != 6, pdata->ftdic); + E(ftdi_write_data(pdata->ftdic, buf, 6) != 6, pdata->ftdic); - msg_trace("set pins command: %02x %02x %02x %02x %02x %02x\n", - buf[0], buf[1], buf[2], buf[3], buf[4], buf[5]); + msg_trace("set pins command: %02x %02x %02x %02x %02x %02x\n", buf[0], buf[1], buf[2], buf[3], buf[4], buf[5]); - /* we need to flush here, because set_pin is used as reset. - * if we want to sleep reset periods, we must be certain the - * avr has got the reset signal when we start sleeping. - * (it may be stuck in the USB stack or some USB hub) - * - * Add.: purge does NOT flush. It clears. Also, it is unknown, when the purge - * command actually arrives at the chip. - * Use read pin status command as sync. - */ - //E(ftdi_usb_purge_buffers(pdata->ftdic), pdata->ftdic); + /* we need to flush here, because set_pin is used as reset. + * if we want to sleep reset periods, we must be certain the + * avr has got the reset signal when we start sleeping. + * (it may be stuck in the USB stack or some USB hub) + * + * Add.: purge does NOT flush. It clears. Also, it is unknown, when the purge + * command actually arrives at the chip. + * Use read pin status command as sync. + */ + // E(ftdi_usb_purge_buffers(pdata->ftdic), pdata->ftdic); - unsigned char cmd[] = { GET_BITS_LOW, SEND_IMMEDIATE }; - E(ftdi_write_data(pdata->ftdic, cmd, sizeof(cmd)) != sizeof(cmd), pdata->ftdic); - - int num = 0; - do - { - int n = ftdi_read_data(pdata->ftdic, buf, sizeof(buf)); - if(n > 0) - num += n; - E(n < 0, pdata->ftdic); - } while(num < 1); - - if(num > 1) - pmsg_warning("read %d extra bytes\n", num-1); + unsigned char cmd[] = { GET_BITS_LOW, SEND_IMMEDIATE }; + E(ftdi_write_data(pdata->ftdic, cmd, sizeof(cmd)) != sizeof(cmd), pdata->ftdic); - return 0; + int num = 0; + + do { + int n = ftdi_read_data(pdata->ftdic, buf, sizeof(buf)); + + if(n > 0) + num += n; + E(n < 0, pdata->ftdic); + } while(num < 1); + + if(num > 1) + pmsg_warning("read %d extra bytes\n", num - 1); + + return 0; } static int avrftdi_check_pins_bb(const PROGRAMMER *pgm, bool output) { - int pin; + int pin; - /* pin checklist. */ - Pin_checklist pin_checklist[N_PINS]; + // Pin checklist + Pin_checklist pin_checklist[N_PINS]; - Avrftdi_data *pdata = to_pdata(pgm); + Avrftdi_data *pdata = to_pdata(pgm); - /* value for 8/12/16 bit wide interface */ - int valid_mask = ((1 << pdata->pin_limit) - 1); + // Value for 8/12/16 bit wide interface + int valid_mask = ((1 << pdata->pin_limit) - 1); - pmsg_debug("using valid mask bitbanging: 0x%08x\n", valid_mask); - struct pindef *valid_pins_p = &pdata->valid_pins; - valid_pins_p->mask[0] = valid_mask; - valid_pins_p->inverse[0] = valid_mask ; + pmsg_debug("using valid mask bitbanging: 0x%08x\n", valid_mask); + struct pindef *valid_pins_p = &pdata->valid_pins; - /* build pin checklist */ - for(pin = 0; pin < N_PINS; ++pin) { - pin_checklist[pin].pinname = pin; - pin_checklist[pin].mandatory = 0; - pin_checklist[pin].valid_pins = valid_pins_p; - } + valid_pins_p->mask[0] = valid_mask; + valid_pins_p->inverse[0] = valid_mask; - /* assumes all checklists above have same number of entries */ - return pins_check(pgm, pin_checklist, N_PINS, output); + // Build pin checklist + for(pin = 0; pin < N_PINS; ++pin) { + pin_checklist[pin].pinname = pin; + pin_checklist[pin].mandatory = 0; + pin_checklist[pin].valid_pins = valid_pins_p; + } + + // Assumes all checklists above have same number of entries + return pins_check(pgm, pin_checklist, N_PINS, output); } static int avrftdi_check_pins_mpsse(const PROGRAMMER *pgm, bool output) { - int pin; + int pin; - /* pin checklist. */ - Pin_checklist pin_checklist[N_PINS]; + // Pin checklist + Pin_checklist pin_checklist[N_PINS]; - Avrftdi_data *pdata = to_pdata(pgm); + Avrftdi_data *pdata = to_pdata(pgm); - struct pindef *valid_pins = pdata->mpsse_pins; + struct pindef *valid_pins = pdata->mpsse_pins; - /* value for 8/12/16 bit wide interface for other pins */ - int valid_mask = ((1 << pdata->pin_limit) - 1); + // Value for 8/12/16 bit wide interface for other pins + int valid_mask = ((1 << pdata->pin_limit) - 1); - /* mask MPSSE pins */ - valid_mask &= ~((1 << FTDI_TCK_SCK) | (1 << FTDI_TDI_SDO) | (1 << FTDI_TDO_SDI)); - if (pgm->flag == PGM_FL_IS_JTAG) { - valid_mask &= ~(1 << FTDI_TMS_CS); - } + // Mask MPSSE pins + valid_mask &= ~((1 << FTDI_TCK_SCK) | (1 << FTDI_TDI_SDO) | (1 << FTDI_TDO_SDI)); + if(pgm->flag == PGM_FL_IS_JTAG) { + valid_mask &= ~(1 << FTDI_TMS_CS); + } - pmsg_debug("using valid mask mpsse: 0x%08x\n", valid_mask); - struct pindef *valid_pins_others_p = &pdata->other_pins; - valid_pins_others_p->mask[0] = valid_mask; - valid_pins_others_p->inverse[0] = valid_mask ; + pmsg_debug("using valid mask mpsse: 0x%08x\n", valid_mask); + struct pindef *valid_pins_others_p = &pdata->other_pins; - /* build pin checklist */ - for(pin = 0; pin < N_PINS; ++pin) { - pin_checklist[pin].pinname = pin; - pin_checklist[pin].mandatory = 0; - pin_checklist[pin].valid_pins = valid_pins_others_p; - } + valid_pins_others_p->mask[0] = valid_mask; + valid_pins_others_p->inverse[0] = valid_mask; - /* now set mpsse specific pins */ - if (pgm->flag == PGM_FL_IS_JTAG) { - pin_checklist[PIN_JTAG_TCK].mandatory = 1; - pin_checklist[PIN_JTAG_TCK].valid_pins = &valid_pins[FTDI_TCK_SCK]; - pin_checklist[PIN_JTAG_TDI].mandatory = 1; - pin_checklist[PIN_JTAG_TDI].valid_pins = &valid_pins[FTDI_TDI_SDO]; - pin_checklist[PIN_JTAG_TDO].mandatory = 1; - pin_checklist[PIN_JTAG_TDO].valid_pins = &valid_pins[FTDI_TDO_SDI]; - pin_checklist[PIN_JTAG_TMS].mandatory = 1; - pin_checklist[PIN_JTAG_TMS].valid_pins = &valid_pins[FTDI_TMS_CS]; - } else { - pin_checklist[PIN_AVR_SCK].mandatory = 1; - pin_checklist[PIN_AVR_SCK].valid_pins = &valid_pins[FTDI_TCK_SCK]; - pin_checklist[PIN_AVR_SDO].mandatory = 1; - pin_checklist[PIN_AVR_SDO].valid_pins = &valid_pins[FTDI_TDI_SDO]; - pin_checklist[PIN_AVR_SDI].mandatory = 1; - pin_checklist[PIN_AVR_SDI].valid_pins = &valid_pins[FTDI_TDO_SDI]; - pin_checklist[PIN_AVR_RESET].mandatory = 1; - } + // Build pin checklist + for(pin = 0; pin < N_PINS; ++pin) { + pin_checklist[pin].pinname = pin; + pin_checklist[pin].mandatory = 0; + pin_checklist[pin].valid_pins = valid_pins_others_p; + } - /* assumes all checklists above have same number of entries */ - return pins_check(pgm, pin_checklist, N_PINS, output); + // Now set mpsse specific pins + if(pgm->flag == PGM_FL_IS_JTAG) { + pin_checklist[PIN_JTAG_TCK].mandatory = 1; + pin_checklist[PIN_JTAG_TCK].valid_pins = &valid_pins[FTDI_TCK_SCK]; + pin_checklist[PIN_JTAG_TDI].mandatory = 1; + pin_checklist[PIN_JTAG_TDI].valid_pins = &valid_pins[FTDI_TDI_SDO]; + pin_checklist[PIN_JTAG_TDO].mandatory = 1; + pin_checklist[PIN_JTAG_TDO].valid_pins = &valid_pins[FTDI_TDO_SDI]; + pin_checklist[PIN_JTAG_TMS].mandatory = 1; + pin_checklist[PIN_JTAG_TMS].valid_pins = &valid_pins[FTDI_TMS_CS]; + } else { + pin_checklist[PIN_AVR_SCK].mandatory = 1; + pin_checklist[PIN_AVR_SCK].valid_pins = &valid_pins[FTDI_TCK_SCK]; + pin_checklist[PIN_AVR_SDO].mandatory = 1; + pin_checklist[PIN_AVR_SDO].valid_pins = &valid_pins[FTDI_TDI_SDO]; + pin_checklist[PIN_AVR_SDI].mandatory = 1; + pin_checklist[PIN_AVR_SDI].valid_pins = &valid_pins[FTDI_TDO_SDI]; + pin_checklist[PIN_AVR_RESET].mandatory = 1; + } + + // Assumes all checklists above have same number of entries + return pins_check(pgm, pin_checklist, N_PINS, output); } static int avrftdi_pin_setup(const PROGRAMMER *pgm) { - int pin; + int pin; - /************* - * pin setup * - *************/ + // Pin setup - Avrftdi_data *pdata = to_pdata(pgm); + Avrftdi_data *pdata = to_pdata(pgm); + bool pin_check_mpsse = (0 == avrftdi_check_pins_mpsse(pgm, verbose >= MSG_TRACE)); - bool pin_check_mpsse = (0 == avrftdi_check_pins_mpsse(pgm, verbose >= MSG_TRACE)); + bool pin_check_bitbanging = (0 == avrftdi_check_pins_bb(pgm, verbose >= MSG_TRACE)); - bool pin_check_bitbanging = (0 == avrftdi_check_pins_bb(pgm, verbose >= MSG_TRACE)); + if(!pin_check_mpsse && !pin_check_bitbanging) { + pmsg_error("no valid pin configuration found\n"); + avrftdi_check_pins_bb(pgm, true); + pmsg_error("pin configuration for FTDI MPSSE must be:\n"); + if(pgm->flag == PGM_FL_IS_JTAG) { + imsg_error(" %s: 0; %s: 1; %s: 2; %s: 3 (is: %s; %s; %s; %s)\n", + avr_pin_name(PIN_JTAG_TCK), avr_pin_name(PIN_JTAG_TDI), + avr_pin_name(PIN_JTAG_TDO), avr_pin_name(PIN_JTAG_TMS), + pins_to_str(&pgm->pin[PIN_JTAG_TCK]), + pins_to_str(&pgm->pin[PIN_JTAG_TDI]), + pins_to_str(&pgm->pin[PIN_JTAG_TDO]), + pins_to_str(&pgm->pin[PIN_JTAG_TMS])); + } else { + imsg_error(" %s: 0; %s: 1; %s: 2 (is: %s; %s; %s)\n", + avr_pin_name(PIN_AVR_SCK), + avr_pin_name(PIN_AVR_SDO), + avr_pin_name(PIN_AVR_SDI), + pins_to_str(&pgm->pin[PIN_AVR_SCK]), pins_to_str(&pgm->pin[PIN_AVR_SDO]), pins_to_str(&pgm->pin[PIN_AVR_SDI])); + } + pmsg_error("if other pin configuration is used, fallback to slower bitbanging mode is used\n"); - if (!pin_check_mpsse && !pin_check_bitbanging) { - pmsg_error("no valid pin configuration found\n"); - avrftdi_check_pins_bb(pgm, true); - pmsg_error("pin configuration for FTDI MPSSE must be:\n"); - if (pgm->flag == PGM_FL_IS_JTAG) { - imsg_error(" %s: 0; %s: 1; %s: 2; %s: 3 (is: %s; %s; %s; %s)\n", - avr_pin_name(PIN_JTAG_TCK), avr_pin_name(PIN_JTAG_TDI), - avr_pin_name(PIN_JTAG_TDO), avr_pin_name(PIN_JTAG_TMS), - pins_to_str(&pgm->pin[PIN_JTAG_TCK]), - pins_to_str(&pgm->pin[PIN_JTAG_TDI]), - pins_to_str(&pgm->pin[PIN_JTAG_TDO]), - pins_to_str(&pgm->pin[PIN_JTAG_TMS])); - } else { - imsg_error(" %s: 0; %s: 1; %s: 2 (is: %s; %s; %s)\n", - avr_pin_name(PIN_AVR_SCK), - avr_pin_name(PIN_AVR_SDO), - avr_pin_name(PIN_AVR_SDI), - pins_to_str(&pgm->pin[PIN_AVR_SCK]), - pins_to_str(&pgm->pin[PIN_AVR_SDO]), - pins_to_str(&pgm->pin[PIN_AVR_SDI])); - } - pmsg_error("if other pin configuration is used, fallback to slower bitbanging mode is used\n"); + return -1; + } - return -1; - } + pdata->use_bitbanging = !pin_check_mpsse; + if(pdata->use_bitbanging) + pmsg_notice("fallback to bitbanging mode because of pin configuration\n"); - pdata->use_bitbanging = !pin_check_mpsse; - if (pdata->use_bitbanging) - pmsg_notice("fallback to bitbanging mode because of pin configuration\n"); + /* + * TODO: No need to fail for a wrongly configured led or something. Maybe we + * should only fail for SCK; SDI, SDO, RST (and probably VCC and BUFF). + */ - /* - * TODO: No need to fail for a wrongly configured led or something. - * Maybe we should only fail for SCK; SDI, SDO, RST (and probably - * VCC and BUFF). - */ + // Everything is an output, except SDI + for(pin = 0; pin < N_PINS; ++pin) { + pdata->pin_direction |= pgm->pin[pin].mask[0]; + pdata->pin_value = SET_BITS_0(pdata->pin_value, pgm, pin, OFF); + } + pdata->pin_direction &= ~pgm->pin[PIN_AVR_SDI].mask[0]; - /* everything is an output, except SDI */ - for(pin = 0; pin < N_PINS; ++pin) { - pdata->pin_direction |= pgm->pin[pin].mask[0]; - pdata->pin_value = SET_BITS_0(pdata->pin_value, pgm, pin, OFF); - } - pdata->pin_direction &= ~pgm->pin[PIN_AVR_SDI].mask[0]; + if(pgm->flag & PGM_FL_IS_JTAG) { + if(!pdata->use_bitbanging) { + pdata->pin_value &= ~pgm->pin[PIN_JTAG_TCK].mask[0]; + pdata->pin_value |= pgm->pin[PIN_JTAG_TCK].inverse[0]; + } + pdata->pin_direction &= ~pgm->pin[PIN_JTAG_TDO].mask[0]; + } else { + if(!pdata->use_bitbanging) { + pdata->pin_value &= ~pgm->pin[PIN_AVR_SCK].mask[0]; + pdata->pin_value |= pgm->pin[PIN_AVR_SCK].inverse[0]; + } + pdata->pin_direction &= ~pgm->pin[PIN_AVR_SDI].mask[0]; + } - if (pgm->flag & PGM_FL_IS_JTAG) { - if (!pdata->use_bitbanging) { - pdata->pin_value &= ~pgm->pin[PIN_JTAG_TCK].mask[0]; - pdata->pin_value |= pgm->pin[PIN_JTAG_TCK].inverse[0]; - } - pdata->pin_direction &= ~pgm->pin[PIN_JTAG_TDO].mask[0]; - } else { - if (!pdata->use_bitbanging) { - pdata->pin_value &= ~pgm->pin[PIN_AVR_SCK].mask[0]; - pdata->pin_value |= pgm->pin[PIN_AVR_SCK].inverse[0]; - } - pdata->pin_direction &= ~pgm->pin[PIN_AVR_SDI].mask[0]; - } + for(pin = PIN_LED_ERR; pin < N_PINS; ++pin) { + pdata->led_mask |= pgm->pin[pin].mask[0]; + } - for(pin = PIN_LED_ERR; pin < N_PINS; ++pin) { - pdata->led_mask |= pgm->pin[pin].mask[0]; - } + imsg_notice(" - pin direction mask %04x\n", pdata->pin_direction); + imsg_notice(" - pin value mask %04x\n", pdata->pin_value); - - imsg_notice(" - pin direction mask %04x\n", pdata->pin_direction); - imsg_notice(" - pin value mask %04x\n", pdata->pin_value); - - return 0; + return 0; } static int avrftdi_open(PROGRAMMER *pgm, const char *port) { - int vid, pid, interface, err; - - Avrftdi_data *pdata = to_pdata(pgm); + int vid, pid, interface, err; - /************************ - * parameter validation * - ************************/ + Avrftdi_data *pdata = to_pdata(pgm); - /* use vid/pid in following priority: config, - * defaults. cmd-line is currently not supported */ - - if (pgm->usbvid) - vid = pgm->usbvid; - else - vid = USB_VENDOR_FTDI; + // Parameter validation - LNODEID usbpid = lfirst(pgm->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 = USB_DEVICE_FT2232; + // Use vid/pid in following priority: config, defaults cmd-line is currently not supported - if (pgm->usbdev[0] == 'a' || pgm->usbdev[0] == 'A') - interface = INTERFACE_A; - else if (pgm->usbdev[0] == 'b' || pgm->usbdev[0] == 'B') - interface = INTERFACE_B; - else { - pmsg_warning("invalid interface %s; setting to Interface A\n", pgm->usbdev); - interface = INTERFACE_A; - } + if(pgm->usbvid) + vid = pgm->usbvid; + else + vid = USB_VENDOR_FTDI; - /**************** - * Device setup * - ****************/ + LNODEID usbpid = lfirst(pgm->usbpid); - E(ftdi_set_interface(pdata->ftdic, interface) < 0, pdata->ftdic); - - const char *serial = *pgm->usbsn? pgm->usbsn: NULL; // no SN means use first available - // Todo: use desc and index argument, currently set to NULL and 0 - err = ftdi_usb_open_desc_index(pdata->ftdic, vid, pid, NULL, serial, 0); - if(err) { - pmsg_error("%s (%d)\n", ftdi_get_error_string(pdata->ftdic), err); - // usb_dev is initialized to the last usb device from probing - pdata->ftdic->usb_dev = NULL; - return err; - } else { - pmsg_notice("using device VID:PID %04x:%04x and SN %s on interface %c\n", - vid, pid, serial? serial: "(none)", INTERFACE_A == interface? 'A': 'B'); - } - - ftdi_set_latency_timer(pdata->ftdic, 1); - //ftdi_write_data_set_chunksize(pdata->ftdic, 16); - //ftdi_read_data_set_chunksize(pdata->ftdic, 16); + if(usbpid) { + pid = *(int *) (ldata(usbpid)); + if(lnext(usbpid)) + pmsg_warning("using PID 0x%04x, ignoring remaining PIDs in list\n", pid); + } else + pid = USB_DEVICE_FT2232; + + if(pgm->usbdev[0] == 'a' || pgm->usbdev[0] == 'A') + interface = INTERFACE_A; + else if(pgm->usbdev[0] == 'b' || pgm->usbdev[0] == 'B') + interface = INTERFACE_B; + else { + pmsg_warning("invalid interface %s; setting to Interface A\n", pgm->usbdev); + interface = INTERFACE_A; + } + + // Device setup + + E(ftdi_set_interface(pdata->ftdic, interface) < 0, pdata->ftdic); + + const char *serial = *pgm->usbsn? pgm->usbsn: NULL; // No SN means use first available + + // Todo: use desc and index argument, currently set to NULL and 0 + err = ftdi_usb_open_desc_index(pdata->ftdic, vid, pid, NULL, serial, 0); + if(err) { + pmsg_error("%s (%d)\n", ftdi_get_error_string(pdata->ftdic), err); + // usb_dev is initialized to the last usb device from probing + pdata->ftdic->usb_dev = NULL; + return err; + } else { + pmsg_notice("using device VID:PID %04x:%04x and SN %s on interface %c\n", + vid, pid, serial? serial: "(none)", INTERFACE_A == interface? 'A': 'B'); + } + + ftdi_set_latency_timer(pdata->ftdic, 1); + // ftdi_write_data_set_chunksize(pdata->ftdic, 16); + // ftdi_read_data_set_chunksize(pdata->ftdic, 16); + + // Set SPI mode + E(ftdi_set_bitmode(pdata->ftdic, 0, BITMODE_RESET) < 0, pdata->ftdic); + E(ftdi_set_bitmode(pdata->ftdic, pdata->pin_direction & 0xff, BITMODE_MPSSE) < 0, pdata->ftdic); - /* set SPI mode */ - E(ftdi_set_bitmode(pdata->ftdic, 0, BITMODE_RESET) < 0, pdata->ftdic); - E(ftdi_set_bitmode(pdata->ftdic, pdata->pin_direction & 0xff, BITMODE_MPSSE) < 0, pdata->ftdic); #ifdef HAVE_FTDI_TCIOFLUSH - E(ftdi_tcioflush(pdata->ftdic), pdata->ftdic); + E(ftdi_tcioflush(pdata->ftdic), pdata->ftdic); #else - E(ftdi_usb_purge_buffers(pdata->ftdic), pdata->ftdic); + E(ftdi_usb_purge_buffers(pdata->ftdic), pdata->ftdic); #endif - write_flush(pdata); + write_flush(pdata); - if (pgm->baudrate) { - set_frequency(pdata, pgm->baudrate); - } else if(pgm->bitclock) { - set_frequency(pdata, (uint32_t)(1.0f/pgm->bitclock)); - } else { - set_frequency(pdata, pgm->baudrate ? pgm->baudrate : 150000); - } + if(pgm->baudrate) { + set_frequency(pdata, pgm->baudrate); + } else if(pgm->bitclock) { + set_frequency(pdata, (uint32_t) (1.0f/pgm->bitclock)); + } else { + set_frequency(pdata, pgm->baudrate? pgm->baudrate: 150000); + } + + // Set pin limit depending on chip type + switch (pdata->ftdic->type) { + case TYPE_AM: + case TYPE_BM: + case TYPE_R: + pmsg_error("found unsupported device type AM, BM or R\n"); + imsg_error("avrftdi cannot work with your chip; try the synbb programmer type\n"); + return -1; + case TYPE_2232C: + pdata->pin_limit = 12; + pdata->rx_buffer_size = 384; + pdata->tx_buffer_size = 128; + break; + case TYPE_2232H: + pdata->pin_limit = 16; + pdata->rx_buffer_size = 4096; + pdata->tx_buffer_size = 4096; + break; - /* set pin limit depending on chip type */ - switch(pdata->ftdic->type) { - case TYPE_AM: - case TYPE_BM: - case TYPE_R: - pmsg_error("found unsupported device type AM, BM or R\n"); - imsg_error("avrftdi cannot work with your chip; try the synbb programmer type\n"); - return -1; - case TYPE_2232C: - pdata->pin_limit = 12; - pdata->rx_buffer_size = 384; - pdata->tx_buffer_size = 128; - break; - case TYPE_2232H: - pdata->pin_limit = 16; - pdata->rx_buffer_size = 4096; - pdata->tx_buffer_size = 4096; - break; #ifdef HAVE_LIBFTDI_TYPE_232H - case TYPE_232H: - pdata->pin_limit = 16; - pdata->rx_buffer_size = 1024; - pdata->tx_buffer_size = 1024; - break; + case TYPE_232H: + pdata->pin_limit = 16; + pdata->rx_buffer_size = 1024; + pdata->tx_buffer_size = 1024; + break; #else + #ifdef _MSC_VER #pragma message("No support for 232H, use a newer libftdi, version >= 0.20") #else #warning No support for 232H, use a newer libftdi, version >= 0.20 #endif #endif - case TYPE_4232H: - pdata->pin_limit = 8; - pdata->rx_buffer_size = 2048; - pdata->tx_buffer_size = 2048; - break; - default: - pmsg_warning("unknown device type 0x%02x, continuing but no guarantees...\n", pdata->ftdic->type); - pdata->pin_limit = 8; - pdata->rx_buffer_size = pdata->ftdic->max_packet_size; - pdata->tx_buffer_size = pdata->ftdic->max_packet_size; - break; - } - return avrftdi_pin_setup(pgm)? -1: 0; + case TYPE_4232H: + pdata->pin_limit = 8; + pdata->rx_buffer_size = 2048; + pdata->tx_buffer_size = 2048; + break; + default: + pmsg_warning("unknown device type 0x%02x, continuing but no guarantees...\n", pdata->ftdic->type); + pdata->pin_limit = 8; + pdata->rx_buffer_size = pdata->ftdic->max_packet_size; + pdata->tx_buffer_size = pdata->ftdic->max_packet_size; + break; + } + + return avrftdi_pin_setup(pgm)? -1: 0; } static void avrftdi_close(PROGRAMMER *pgm) { - Avrftdi_data *pdata = to_pdata(pgm); + Avrftdi_data *pdata = to_pdata(pgm); - if(pdata->ftdic->usb_dev) { - set_pin(pgm, PIN_AVR_RESET, ON); + if(pdata->ftdic->usb_dev) { + set_pin(pgm, PIN_AVR_RESET, ON); - /* Stop driving the pins - except for the LEDs */ - pmsg_debug("LED Mask 0x%04x, pin value 0x%04x, anded 0x%04x\n", - pdata->led_mask, pdata->pin_value, pdata->led_mask & pdata->pin_value); + // Stop driving the pins - except for the LEDs + pmsg_debug("LED Mask 0x%04x, pin value 0x%04x, anded 0x%04x\n", + pdata->led_mask, pdata->pin_value, pdata->led_mask & pdata->pin_value); - pdata->pin_direction = pdata->led_mask; - pdata->pin_value &= pdata->led_mask; - write_flush(pdata); - /* reset state recommended by FTDI */ - ftdi_set_bitmode(pdata->ftdic, 0, BITMODE_RESET); - E_VOID(ftdi_usb_close(pdata->ftdic), pdata->ftdic); - } + pdata->pin_direction = pdata->led_mask; + pdata->pin_value &= pdata->led_mask; + write_flush(pdata); + // Reset state recommended by FTDI + ftdi_set_bitmode(pdata->ftdic, 0, BITMODE_RESET); + E_VOID(ftdi_usb_close(pdata->ftdic), pdata->ftdic); + } - return; + return; } static int avrftdi_initialize(const PROGRAMMER *pgm, const AVRPART *p) { - avrftdi_powerup(pgm); + avrftdi_powerup(pgm); - if(p->prog_modes & PM_TPI) - { - /* see avrftdi_tpi.c */ - avrftdi_tpi_initialize(pgm, p); - } - else - { - set_pin(pgm, PIN_AVR_RESET, OFF); - set_pin(pgm, PIN_AVR_SCK, OFF); - /*use speed optimization with CAUTION*/ - usleep(20 * 1000); + if(p->prog_modes & PM_TPI) { + // See avrftdi_tpi.c + avrftdi_tpi_initialize(pgm, p); + } else { + set_pin(pgm, PIN_AVR_RESET, OFF); + set_pin(pgm, PIN_AVR_SCK, OFF); + // Use speed optimization with CAUTION + usleep(20*1000); - /* giving rst-pulse of at least 2 avr-clock-cycles, for - * security (2us @ 1MHz) */ - set_pin(pgm, PIN_AVR_RESET, ON); - usleep(20 * 1000); + // Giving rst-pulse of at least 2 avr-clock-cycles, for security (2us @ 1MHz) + set_pin(pgm, PIN_AVR_RESET, ON); + usleep(20*1000); - /*setting rst back to 0 */ - set_pin(pgm, PIN_AVR_RESET, OFF); - /*wait at least 20ms before issuing spi commands to avr */ - usleep(20 * 1000); - } + // Setting rst back to 0 + set_pin(pgm, PIN_AVR_RESET, OFF); + // Wait at least 20ms before issuing spi commands to avr + usleep(20*1000); + } - return pgm->program_enable(pgm, p); + return pgm->program_enable(pgm, p); } -static void avrftdi_display(const PROGRAMMER *pgm, const char *p) -{ - msg_info("%spin assignment : 0..7 = DBUS0..7, 8..15 = CBUS0..7\n", p); - if (pgm->flag & PGM_FL_IS_JTAG) { - pgm_display_generic_mask(pgm, p, SHOW_ALL_PINS & ~SHOW_AVR_PINS); - } else { - pgm_display_generic_mask(pgm, p, SHOW_ALL_PINS & ~SHOW_JTAG_PINS); - } +static void avrftdi_display(const PROGRAMMER *pgm, const char *p) { + msg_info("%spin assignment : 0..7 = DBUS0..7, 8..15 = CBUS0..7\n", p); + if(pgm->flag & PGM_FL_IS_JTAG) { + pgm_display_generic_mask(pgm, p, SHOW_ALL_PINS & ~SHOW_AVR_PINS); + } else { + pgm_display_generic_mask(pgm, p, SHOW_ALL_PINS & ~SHOW_JTAG_PINS); + } } - static int avrftdi_cmd(const PROGRAMMER *pgm, const unsigned char *cmd, unsigned char *res) { - return avrftdi_transmit(pgm, MPSSE_DO_READ | MPSSE_DO_WRITE, cmd, res, 4); + return avrftdi_transmit(pgm, MPSSE_DO_READ | MPSSE_DO_WRITE, cmd, res, 4); } - static int avrftdi_program_enable(const PROGRAMMER *pgm, const AVRPART *p) { - int i; - unsigned char buf[4]; - int polli = p->pollindex - 1, pollok = polli >= 0 && polli < (int) sizeof buf; + int i; + unsigned char buf[4]; + int polli = p->pollindex - 1, pollok = polli >= 0 && polli < (int) sizeof buf; - memset(buf, 0, sizeof(buf)); + memset(buf, 0, sizeof(buf)); - if (p->op[AVR_OP_PGM_ENABLE] == NULL) { - pmsg_error("AVR_OP_PGM_ENABLE command not defined for %s\n", p->desc); - return -1; - } + if(p->op[AVR_OP_PGM_ENABLE] == NULL) { + pmsg_error("AVR_OP_PGM_ENABLE command not defined for %s\n", p->desc); + return -1; + } - avr_set_bits(p->op[AVR_OP_PGM_ENABLE], buf); + avr_set_bits(p->op[AVR_OP_PGM_ENABLE], buf); - for(i = 0; i < 4; i++) { - pgm->cmd(pgm, buf, buf); - if (pollok && buf[polli] != p->pollvalue) { - pmsg_warning("program enable command not successful%s\n", i < 3? "; retrying": ""); - set_pin(pgm, PIN_AVR_RESET, ON); - usleep(20); - set_pin(pgm, PIN_AVR_RESET, OFF); - avr_set_bits(p->op[AVR_OP_PGM_ENABLE], buf); - } else - return 0; - } + for(i = 0; i < 4; i++) { + pgm->cmd(pgm, buf, buf); + if(pollok && buf[polli] != p->pollvalue) { + pmsg_warning("program enable command not successful%s\n", i < 3? "; retrying": ""); + set_pin(pgm, PIN_AVR_RESET, ON); + usleep(20); + set_pin(pgm, PIN_AVR_RESET, OFF); + avr_set_bits(p->op[AVR_OP_PGM_ENABLE], buf); + } else + return 0; + } - pmsg_error("device is not responding to program enable. Check connection.\n"); + pmsg_error("device is not responding to program enable. Check connection.\n"); - return -1; + return -1; } - static int avrftdi_chip_erase(const PROGRAMMER *pgm, const AVRPART *p) { - unsigned char cmd[4]; - unsigned char res[4]; + unsigned char cmd[4]; + unsigned char res[4]; - if (p->op[AVR_OP_CHIP_ERASE] == NULL) { - pmsg_error("AVR_OP_CHIP_ERASE command not defined for %s\n", p->desc); - return -1; - } + if(p->op[AVR_OP_CHIP_ERASE] == NULL) { + pmsg_error("AVR_OP_CHIP_ERASE command not defined for %s\n", p->desc); + return -1; + } - memset(cmd, 0, sizeof(cmd)); + memset(cmd, 0, sizeof(cmd)); - avr_set_bits(p->op[AVR_OP_CHIP_ERASE], cmd); - pgm->cmd(pgm, cmd, res); - usleep(p->chip_erase_delay); - pgm->initialize(pgm, p); + avr_set_bits(p->op[AVR_OP_CHIP_ERASE], cmd); + pgm->cmd(pgm, cmd, res); + usleep(p->chip_erase_delay); + pgm->initialize(pgm, p); - return 0; + return 0; } - -/* Load extended address byte command */ +// Load extended address byte command static int avrftdi_lext(const PROGRAMMER *pgm, const AVRPART *p, const AVRMEM *m, unsigned int address) { - /* nothing to do if load extended address command unavailable */ - if(m->op[AVR_OP_LOAD_EXT_ADDR] == NULL) - return 0; + // Nothing to do if load extended address command unavailable + if(m->op[AVR_OP_LOAD_EXT_ADDR] == NULL) + return 0; - Avrftdi_data *pdata = to_pdata(pgm); - unsigned char buf[] = { 0x00, 0x00, 0x00, 0x00 }; + Avrftdi_data *pdata = to_pdata(pgm); + unsigned char buf[] = { 0x00, 0x00, 0x00, 0x00 }; - /* only send load extended address command if high byte changed */ - if(pdata->lext_byte == (uint8_t) (address>>16)) - return 0; + // Only send load extended address command if high byte changed + if(pdata->lext_byte == (uint8_t) (address >> 16)) + return 0; - pdata->lext_byte = (uint8_t) (address>>16); + pdata->lext_byte = (uint8_t) (address >> 16); - avr_set_bits(m->op[AVR_OP_LOAD_EXT_ADDR], buf); - avr_set_addr(m->op[AVR_OP_LOAD_EXT_ADDR], buf, address); + avr_set_bits(m->op[AVR_OP_LOAD_EXT_ADDR], buf); + avr_set_addr(m->op[AVR_OP_LOAD_EXT_ADDR], buf, address); - if(verbose >= MSG_TRACE2) - buf_dump(buf, sizeof(buf), - "load extended address command", 0, 16 * 3); + if(verbose >= MSG_TRACE2) + buf_dump(buf, sizeof(buf), "load extended address command", 0, 16*3); - if (0 > avrftdi_transmit(pgm, MPSSE_DO_WRITE, buf, buf, 4)) - return -1; - - return 0; + if(0 > avrftdi_transmit(pgm, MPSSE_DO_WRITE, buf, buf, 4)) + return -1; + + return 0; } static int avrftdi_eeprom_write(const PROGRAMMER *pgm, const AVRPART *p, const AVRMEM *m, - unsigned int page_size, unsigned int addr, unsigned int len) -{ - unsigned char cmd[] = { 0x00, 0x00, 0x00, 0x00 }; - unsigned char *data = &m->buf[addr]; - unsigned int add; + unsigned int page_size, unsigned int addr, unsigned int len) { + unsigned char cmd[] = { 0x00, 0x00, 0x00, 0x00 }; + unsigned char *data = &m->buf[addr]; + unsigned int add; - avr_set_bits(m->op[AVR_OP_WRITE], cmd); + avr_set_bits(m->op[AVR_OP_WRITE], cmd); - for (add = addr; add < addr + len; add++) - { - avr_set_addr(m->op[AVR_OP_WRITE], cmd, add); - avr_set_input(m->op[AVR_OP_WRITE], cmd, *data++); + for(add = addr; add < addr + len; add++) { + avr_set_addr(m->op[AVR_OP_WRITE], cmd, add); + avr_set_input(m->op[AVR_OP_WRITE], cmd, *data++); - if (0 > avrftdi_transmit(pgm, MPSSE_DO_WRITE, cmd, cmd, 4)) - return -1; - usleep((m->max_write_delay)); + if(0 > avrftdi_transmit(pgm, MPSSE_DO_WRITE, cmd, cmd, 4)) + return -1; + usleep((m->max_write_delay)); - } - return len; + } + return len; } static int avrftdi_eeprom_read(const PROGRAMMER *pgm, const AVRPART *p, const AVRMEM *m, - unsigned int page_size, unsigned int addr, unsigned int len) -{ - unsigned char cmd[4]; - unsigned int add; - unsigned char* buffer = alloca(len); - unsigned char* bufptr = buffer; + unsigned int page_size, unsigned int addr, unsigned int len) { + unsigned char cmd[4]; + unsigned int add; + unsigned char *buffer = alloca(len); + unsigned char *bufptr = buffer; - memset(buffer, 0, len); + memset(buffer, 0, len); - for (add = addr; add < addr + len; add++) - { - memset(cmd, 0, sizeof(cmd)); - avr_set_bits(m->op[AVR_OP_READ], cmd); - avr_set_addr(m->op[AVR_OP_READ], cmd, add); + for(add = addr; add < addr + len; add++) { + memset(cmd, 0, sizeof(cmd)); + avr_set_bits(m->op[AVR_OP_READ], cmd); + avr_set_addr(m->op[AVR_OP_READ], cmd, add); - if (0 > avrftdi_transmit(pgm, MPSSE_DO_READ | MPSSE_DO_WRITE, cmd, cmd, 4)) - return -1; + if(0 > avrftdi_transmit(pgm, MPSSE_DO_READ | MPSSE_DO_WRITE, cmd, cmd, 4)) + return -1; - avr_get_output(m->op[AVR_OP_READ], cmd, bufptr++); - } + avr_get_output(m->op[AVR_OP_READ], cmd, bufptr++); + } - memcpy(m->buf + addr, buffer, len); - return len; + memcpy(m->buf + addr, buffer, len); + return len; } static int avrftdi_flash_write(const PROGRAMMER *pgm, const AVRPART *p, const AVRMEM *m, - unsigned int page_size, unsigned int addr, unsigned int len) -{ - unsigned int word; - unsigned int poll_index; + unsigned int page_size, unsigned int addr, unsigned int len) { + unsigned int word; + unsigned int poll_index; - unsigned char poll_byte; - unsigned char *buffer = &m->buf[addr]; - unsigned int buf_size = 4 * len + 4; - unsigned char* buf = alloca(buf_size); - unsigned char* bufptr = buf; + unsigned char poll_byte; + unsigned char *buffer = &m->buf[addr]; + unsigned int buf_size = 4*len + 4; + unsigned char *buf = alloca(buf_size); + unsigned char *bufptr = buf; - memset(buf, 0, buf_size); + memset(buf, 0, buf_size); - /* pre-check opcodes */ - if (m->op[AVR_OP_LOADPAGE_LO] == NULL) { - pmsg_error("AVR_OP_LOADPAGE_LO command not defined for %s\n", p->desc); - return -1; - } - if (m->op[AVR_OP_LOADPAGE_HI] == NULL) { - pmsg_error("AVR_OP_LOADPAGE_HI command not defined for %s\n", p->desc); - return -1; - } + // Pre-check opcodes + if(m->op[AVR_OP_LOADPAGE_LO] == NULL) { + pmsg_error("AVR_OP_LOADPAGE_LO command not defined for %s\n", p->desc); + return -1; + } + if(m->op[AVR_OP_LOADPAGE_HI] == NULL) { + pmsg_error("AVR_OP_LOADPAGE_HI command not defined for %s\n", p->desc); + return -1; + } - if(page_size != (unsigned int) m->page_size) { - pmsg_warning("parameter page_size is %d ", page_size); - msg_warning("but m->page_size is %d; using the latter\n", m->page_size); - } + if(page_size != (unsigned int) m->page_size) { + pmsg_warning("parameter page_size is %d ", page_size); + msg_warning("but m->page_size is %d; using the latter\n", m->page_size); + } - page_size = m->page_size; + page_size = m->page_size; - /* on large-flash devices > 128k issue extended address command when needed */ - if(avrftdi_lext(pgm, p, m, addr/2) < 0) - return -1; - - /* prepare the command stream for the whole page */ - /* addr is in bytes, but we program in words. */ - for(word = addr/2; word < (len + addr)/2; word++) - { - pmsg_debug("-< bytes = %d of %d\n", word * 2, len + addr); + // On large-flash devices > 128k issue extended address command when needed + if(avrftdi_lext(pgm, p, m, addr/2) < 0) + return -1; - /*setting word*/ - avr_set_bits(m->op[AVR_OP_LOADPAGE_LO], bufptr); - /* here is the second byte increment, just if you're wondering */ - avr_set_addr(m->op[AVR_OP_LOADPAGE_LO], bufptr, word); - avr_set_input(m->op[AVR_OP_LOADPAGE_LO], bufptr, *buffer++); - bufptr += 4; - avr_set_bits(m->op[AVR_OP_LOADPAGE_HI], bufptr); - avr_set_addr(m->op[AVR_OP_LOADPAGE_HI], bufptr, word); - avr_set_input(m->op[AVR_OP_LOADPAGE_HI], bufptr, *buffer++); - bufptr += 4; - } + // Prepare the command stream for the whole page - /* issue write page command, if available */ - if (m->op[AVR_OP_WRITEPAGE] == NULL) { - pmsg_error("AVR_OP_WRITEPAGE command not defined for %s\n", p->desc); - return -1; - } else { - avr_set_bits(m->op[AVR_OP_WRITEPAGE], bufptr); - /* setting page address highbyte */ - avr_set_addr(m->op[AVR_OP_WRITEPAGE], - bufptr, addr/2); - bufptr += 4; - } + // Addr is in bytes, but we program in words. + for(word = addr/2; word < (len + addr)/2; word++) { + pmsg_debug("-< bytes = %d of %d\n", word*2, len + addr); - /* find a poll byte. We cannot poll a value of 0xff, so look - * for a value != 0xff - */ - for(poll_index = addr+len-1; poll_index+1 > addr; poll_index--) - if(m->buf[poll_index] != 0xff) - break; + // Setting word + avr_set_bits(m->op[AVR_OP_LOADPAGE_LO], bufptr); + // Here is the second byte increment, just if you're wondering + avr_set_addr(m->op[AVR_OP_LOADPAGE_LO], bufptr, word); + avr_set_input(m->op[AVR_OP_LOADPAGE_LO], bufptr, *buffer++); + bufptr += 4; + avr_set_bits(m->op[AVR_OP_LOADPAGE_HI], bufptr); + avr_set_addr(m->op[AVR_OP_LOADPAGE_HI], bufptr, word); + avr_set_input(m->op[AVR_OP_LOADPAGE_HI], bufptr, *buffer++); + bufptr += 4; + } - if(poll_index+1 > addr) { - buf_size = bufptr - buf; + // Issue write page command, if available + if(m->op[AVR_OP_WRITEPAGE] == NULL) { + pmsg_error("AVR_OP_WRITEPAGE command not defined for %s\n", p->desc); + return -1; + } else { + avr_set_bits(m->op[AVR_OP_WRITEPAGE], bufptr); + // Setting page address highbyte + avr_set_addr(m->op[AVR_OP_WRITEPAGE], bufptr, addr/2); + bufptr += 4; + } - if(verbose >= MSG_TRACE2) - buf_dump(buf, buf_size, "command buffer", 0, 16*2); + // Find a poll byte; we cannot poll a value of 0xff, so look for a value != 0xff + for(poll_index = addr + len - 1; poll_index + 1 > addr; poll_index--) + if(m->buf[poll_index] != 0xff) + break; - pmsg_notice("transmitting buffer of size: %d\n", buf_size); - if (0 > avrftdi_transmit(pgm, MPSSE_DO_WRITE, buf, buf, buf_size)) - return -1; + if(poll_index + 1 > addr) { + buf_size = bufptr - buf; - bufptr = buf; + if(verbose >= MSG_TRACE2) + buf_dump(buf, buf_size, "command buffer", 0, 16*2); - pmsg_notice("using m->buf[%d] = 0x%02x as polling value ", poll_index, - m->buf[poll_index]); - /* poll page write ready */ - do { - msg_notice("."); + pmsg_notice("transmitting buffer of size: %d\n", buf_size); + if(0 > avrftdi_transmit(pgm, MPSSE_DO_WRITE, buf, buf, buf_size)) + return -1; - pgm->read_byte(pgm, p, m, poll_index, &poll_byte); - } while (m->buf[poll_index] != poll_byte); + bufptr = buf; - msg_notice("\n"); - } - else - { - pmsg_warning("skipping empty page (containing only 0xff bytes)\n"); - /* TODO sync write */ - /* sleep */ - usleep((m->max_write_delay)); - } + pmsg_notice("using m->buf[%d] = 0x%02x as polling value ", poll_index, m->buf[poll_index]); + // Poll page write ready + do { + msg_notice("."); - return len; + pgm->read_byte(pgm, p, m, poll_index, &poll_byte); + } while(m->buf[poll_index] != poll_byte); + + msg_notice("\n"); + } else { + pmsg_warning("skipping empty page (containing only 0xff bytes)\n"); + // TODO sync write + usleep((m->max_write_delay)); + } + + return len; } -/* - *Reading from flash - */ +// Reading from flash static int avrftdi_flash_read(const PROGRAMMER *pgm, const AVRPART *p, const AVRMEM *m, - unsigned int page_size, unsigned int addr, unsigned int len) -{ - OPCODE *readop; + unsigned int page_size, unsigned int addr, unsigned int len) { + OPCODE *readop; - unsigned int buf_size = 4 * len + 4; - unsigned char* o_buf = alloca(buf_size); - unsigned char* i_buf = alloca(buf_size); + unsigned int buf_size = 4*len + 4; + unsigned char *o_buf = alloca(buf_size); + unsigned char *i_buf = alloca(buf_size); + memset(o_buf, 0, buf_size); + memset(i_buf, 0, buf_size); - memset(o_buf, 0, buf_size); - memset(i_buf, 0, buf_size); + // Pre-check opcodes + if(m->op[AVR_OP_READ_LO] == NULL) { + pmsg_error("AVR_OP_READ_LO command not defined for %s\n", p->desc); + return -1; + } + if(m->op[AVR_OP_READ_HI] == NULL) { + pmsg_error("AVR_OP_READ_HI command not defined for %s\n", p->desc); + return -1; + } - /* pre-check opcodes */ - if (m->op[AVR_OP_READ_LO] == NULL) { - pmsg_error("AVR_OP_READ_LO command not defined for %s\n", p->desc); - return -1; - } - if (m->op[AVR_OP_READ_HI] == NULL) { - pmsg_error("AVR_OP_READ_HI command not defined for %s\n", p->desc); - return -1; - } - - if(avrftdi_lext(pgm, p, m, addr/2) < 0) - return -1; - - /* word addressing! */ - for(unsigned int word = addr/2, index = 0; word < (addr + len)/2; word++) - { - /* one byte is transferred via a 4-byte opcode. - * TODO: reduce magic numbers - */ - avr_set_bits(m->op[AVR_OP_READ_LO], &o_buf[index*4]); - avr_set_addr(m->op[AVR_OP_READ_LO], &o_buf[index*4], word); - index++; - avr_set_bits(m->op[AVR_OP_READ_HI], &o_buf[index*4]); - avr_set_addr(m->op[AVR_OP_READ_HI], &o_buf[index*4], word); - index++; - } + if(avrftdi_lext(pgm, p, m, addr/2) < 0) + return -1; - /* transmit, - * if there was an error, we did not see, memory validation will - * subsequently fail. - */ - if(verbose >= MSG_TRACE2) { - buf_dump(o_buf, sizeof(o_buf), "o_buf", 0, 32); - } + // Word addressing! + for(unsigned int word = addr/2, index = 0; word < (addr + len)/2; word++) { + /* one byte is transferred via a 4-byte opcode. + * TODO: reduce magic numbers + */ + avr_set_bits(m->op[AVR_OP_READ_LO], &o_buf[index*4]); + avr_set_addr(m->op[AVR_OP_READ_LO], &o_buf[index*4], word); + index++; + avr_set_bits(m->op[AVR_OP_READ_HI], &o_buf[index*4]); + avr_set_addr(m->op[AVR_OP_READ_HI], &o_buf[index*4], word); + index++; + } - if (0 > avrftdi_transmit(pgm, MPSSE_DO_READ | MPSSE_DO_WRITE, o_buf, i_buf, len * 4)) - return -1; + /* transmit, + * if there was an error, we did not see, memory validation will + * subsequently fail. + */ + if(verbose >= MSG_TRACE2) { + buf_dump(o_buf, sizeof(o_buf), "o_buf", 0, 32); + } - if(verbose >= MSG_TRACE2) { - buf_dump(i_buf, sizeof(i_buf), "i_buf", 0, 32); - } + if(0 > avrftdi_transmit(pgm, MPSSE_DO_READ | MPSSE_DO_WRITE, o_buf, i_buf, len*4)) + return -1; - memset(&m->buf[addr], 0, page_size); + if(verbose >= MSG_TRACE2) { + buf_dump(i_buf, sizeof(i_buf), "i_buf", 0, 32); + } - /* every (read) op is 4 bytes in size and yields one byte of memory data */ - for(unsigned int byte = 0; byte < page_size; byte++) { - if(byte & 1) - readop = m->op[AVR_OP_READ_HI]; - else - readop = m->op[AVR_OP_READ_LO]; + memset(&m->buf[addr], 0, page_size); - /* take 4 bytes and put the memory byte in the buffer at - * offset addr + offset of the current byte - */ - avr_get_output(readop, &i_buf[byte*4], &m->buf[addr+byte]); - } + // Every (read) op is 4 bytes in size and yields one byte of memory data + for(unsigned int byte = 0; byte < page_size; byte++) { + if(byte & 1) + readop = m->op[AVR_OP_READ_HI]; + else + readop = m->op[AVR_OP_READ_LO]; - if(verbose >= MSG_TRACE2) - buf_dump(&m->buf[addr], page_size, "page:", 0, 32); + /* take 4 bytes and put the memory byte in the buffer at + * offset addr + offset of the current byte + */ + avr_get_output(readop, &i_buf[byte*4], &m->buf[addr + byte]); + } - return len; + if(verbose >= MSG_TRACE2) + buf_dump(&m->buf[addr], page_size, "page:", 0, 32); + + return len; } static int avrftdi_paged_write(const PROGRAMMER *pgm, const AVRPART *p, const AVRMEM *m, - unsigned int page_size, unsigned int addr, unsigned int n_bytes) -{ - if (mem_is_flash(m)) - return avrftdi_flash_write(pgm, p, m, page_size, addr, n_bytes); - else if (mem_is_eeprom(m)) - return avrftdi_eeprom_write(pgm, p, m, page_size, addr, n_bytes); - else - return -2; + unsigned int page_size, unsigned int addr, unsigned int n_bytes) { + if(mem_is_flash(m)) + return avrftdi_flash_write(pgm, p, m, page_size, addr, n_bytes); + else if(mem_is_eeprom(m)) + return avrftdi_eeprom_write(pgm, p, m, page_size, addr, n_bytes); + else + return -2; } static int avrftdi_paged_load(const PROGRAMMER *pgm, const AVRPART *p, const AVRMEM *m, - unsigned int page_size, unsigned int addr, unsigned int n_bytes) -{ - if (mem_is_flash(m)) - return avrftdi_flash_read(pgm, p, m, page_size, addr, n_bytes); - else if(mem_is_eeprom(m)) - return avrftdi_eeprom_read(pgm, p, m, page_size, addr, n_bytes); - else - return -2; + unsigned int page_size, unsigned int addr, unsigned int n_bytes) { + if(mem_is_flash(m)) + return avrftdi_flash_read(pgm, p, m, page_size, addr, n_bytes); + else if(mem_is_eeprom(m)) + return avrftdi_eeprom_read(pgm, p, m, page_size, addr, n_bytes); + else + return -2; } static void avrftdi_setup(PROGRAMMER *pgm) { - Avrftdi_data *pdata; + Avrftdi_data *pdata; - pgm->cookie = mmt_malloc(sizeof(Avrftdi_data)); - pdata = to_pdata(pgm); + pgm->cookie = mmt_malloc(sizeof(Avrftdi_data)); + pdata = to_pdata(pgm); - /* SCK/SDO/SDI are fixed and not invertible? */ - /* TODO: inverted SCK/SDI/SDO */ - const struct pindef valid_mpsse_pins[4] = { - {{0x01}, {0x00}}, - {{0x02}, {0x00}}, - {{0x04}, {0x00}}, - {{0x08}, {0x00}}, - }; - for(int i=0; i<4; i++) - pdata->mpsse_pins[i] = valid_mpsse_pins[i]; + // SCK/SDO/SDI are fixed and not invertible? TODO: inverted SCK/SDI/SDO + const struct pindef valid_mpsse_pins[4] = { + {{0x01}, {0x00}}, + {{0x02}, {0x00}}, + {{0x04}, {0x00}}, + {{0x08}, {0x00}}, + }; + for(int i = 0; i < 4; i++) + pdata->mpsse_pins[i] = valid_mpsse_pins[i]; - pdata->ftdic = ftdi_new(); - if(!pdata->ftdic) { - pmsg_ext_error("ftdi_new() failed to allocate memory\n"); - exit(1); // pgm->setup() should return an int, but it doesn't - } - E_VOID(ftdi_init(pdata->ftdic), pdata->ftdic); + pdata->ftdic = ftdi_new(); + if(!pdata->ftdic) { + pmsg_ext_error("ftdi_new() failed to allocate memory\n"); + exit(1); // pgm->setup() should return an int, but it doesn't + } + E_VOID(ftdi_init(pdata->ftdic), pdata->ftdic); - pdata->pin_value = 0; - pdata->pin_direction = 0; - pdata->led_mask = 0; - pdata->lext_byte = 0xff; + pdata->pin_value = 0; + pdata->pin_direction = 0; + pdata->led_mask = 0; + pdata->lext_byte = 0xff; } static void avrftdi_teardown(PROGRAMMER *pgm) { - if(pgm->cookie) { - Avrftdi_data *pdata = to_pdata(pgm); - ftdi_deinit(pdata->ftdic); - ftdi_free(pdata->ftdic); - mmt_free(pdata); - pgm->cookie = NULL; - } + if(pgm->cookie) { + Avrftdi_data *pdata = to_pdata(pgm); + + ftdi_deinit(pdata->ftdic); + ftdi_free(pdata->ftdic); + mmt_free(pdata); + pgm->cookie = NULL; + } } -/******************/ -/* JTAG functions */ -/******************/ + +// JTAG functions static int avrftdi_jtag_reset(const PROGRAMMER *pgm) { - Avrftdi_data *pdata = to_pdata(pgm); - unsigned char buf[3], *ptr = buf; + Avrftdi_data *pdata = to_pdata(pgm); + unsigned char buf[3], *ptr = buf; - /* Unknown -> Reset -> Run-Test/Idle */ - *ptr++ = MPSSE_WRITE_TMS | MPSSE_LSB | MPSSE_BITMODE | MPSSE_WRITE_NEG; - *ptr++ = 5; - *ptr++ = 0x1f; + // Unknown -> Reset -> Run-Test/Idle + *ptr++ = MPSSE_WRITE_TMS | MPSSE_LSB | MPSSE_BITMODE | MPSSE_WRITE_NEG; + *ptr++ = 5; + *ptr++ = 0x1f; - E(ftdi_write_data(pdata->ftdic, buf, ptr - buf) != ptr - buf, pdata->ftdic); + E(ftdi_write_data(pdata->ftdic, buf, ptr - buf) != ptr - buf, pdata->ftdic); - return 0; + return 0; } static int avrftdi_jtag_ir_out(const PROGRAMMER *pgm, unsigned char ir) { - Avrftdi_data *pdata = to_pdata(pgm); - unsigned char buf[9], *ptr = buf; + Avrftdi_data *pdata = to_pdata(pgm); + unsigned char buf[9], *ptr = buf; - /* Idle -> Select-DR -> Select-IR -> Capture-IR -> Shift-IR */ - *ptr++ = MPSSE_WRITE_TMS | MPSSE_LSB | MPSSE_BITMODE | MPSSE_WRITE_NEG; - *ptr++ = 3; - *ptr++ = 0x03; + // Idle -> Select-DR -> Select-IR -> Capture-IR -> Shift-IR + *ptr++ = MPSSE_WRITE_TMS | MPSSE_LSB | MPSSE_BITMODE | MPSSE_WRITE_NEG; + *ptr++ = 3; + *ptr++ = 0x03; - /* Clock out first 3 bits */ - *ptr++ = MPSSE_DO_WRITE | MPSSE_LSB | MPSSE_BITMODE | MPSSE_WRITE_NEG; - *ptr++ = 2; - *ptr++ = ir & 0x7; + // Clock out first 3 bits + *ptr++ = MPSSE_DO_WRITE | MPSSE_LSB | MPSSE_BITMODE | MPSSE_WRITE_NEG; + *ptr++ = 2; + *ptr++ = ir & 0x7; - /* Clock out 4th bit and Shift-IR -> Exit1-IR -> Update-IR -> Idle */ - *ptr++ = MPSSE_WRITE_TMS | MPSSE_LSB | MPSSE_BITMODE | MPSSE_WRITE_NEG; - *ptr++ = 2; - *ptr++ = (ir & 0x8) << 4 | 0x03; + // Clock out 4th bit and Shift-IR -> Exit1-IR -> Update-IR -> Idle + *ptr++ = MPSSE_WRITE_TMS | MPSSE_LSB | MPSSE_BITMODE | MPSSE_WRITE_NEG; + *ptr++ = 2; + *ptr++ = (ir & 0x8) << 4 | 0x03; - E(ftdi_write_data(pdata->ftdic, buf, ptr - buf) != ptr - buf, pdata->ftdic); + E(ftdi_write_data(pdata->ftdic, buf, ptr - buf) != ptr - buf, pdata->ftdic); - return 0; + return 0; } static int avrftdi_jtag_dr_out(const PROGRAMMER *pgm, unsigned int dr, int bits) { - Avrftdi_data *pdata = to_pdata(pgm); - unsigned char buf[18], *ptr = buf; + Avrftdi_data *pdata = to_pdata(pgm); + unsigned char buf[18], *ptr = buf; - if (bits <= 0 || bits > 31) { - return -1; - } + if(bits <= 0 || bits > 31) { + return -1; + } - /* Idle -> Select-DR -> Capture-DR -> Shift-DR */ - *ptr++ = MPSSE_WRITE_TMS | MPSSE_LSB | MPSSE_BITMODE | MPSSE_WRITE_NEG; - *ptr++ = 2; - *ptr++ = 0x01; + // Idle -> Select-DR -> Capture-DR -> Shift-DR + *ptr++ = MPSSE_WRITE_TMS | MPSSE_LSB | MPSSE_BITMODE | MPSSE_WRITE_NEG; + *ptr++ = 2; + *ptr++ = 0x01; - while (bits > 8) { - /* Write bits */ - *ptr++ = MPSSE_DO_WRITE | MPSSE_LSB | MPSSE_BITMODE | MPSSE_WRITE_NEG; - *ptr++ = 7; - *ptr++ = dr & 0xff; - bits -= 8; - dr >>= 8; - } + while(bits > 8) { + // Write bits + *ptr++ = MPSSE_DO_WRITE | MPSSE_LSB | MPSSE_BITMODE | MPSSE_WRITE_NEG; + *ptr++ = 7; + *ptr++ = dr & 0xff; + bits -= 8; + dr >>= 8; + } - if (bits > 1) { - /* Write */ - *ptr++ = MPSSE_DO_WRITE | MPSSE_LSB | MPSSE_BITMODE | MPSSE_WRITE_NEG; - *ptr++ = bits - 2; - *ptr++ = dr & ((1 << (bits - 1)) - 1); - } - dr <<= 8 - bits; + if(bits > 1) { + // Write + *ptr++ = MPSSE_DO_WRITE | MPSSE_LSB | MPSSE_BITMODE | MPSSE_WRITE_NEG; + *ptr++ = bits - 2; + *ptr++ = dr & ((1 << (bits - 1)) - 1); + } + dr <<= 8 - bits; - /* Write MSB and Shift-DR -> Exit1-DR -> Update-DR -> Idle */ - *ptr++ = MPSSE_WRITE_TMS | MPSSE_LSB | MPSSE_BITMODE | MPSSE_WRITE_NEG; - *ptr++ = 2; - *ptr++ = (dr & 0x80) | 0x03; + // Write MSB and Shift-DR -> Exit1-DR -> Update-DR -> Idle + *ptr++ = MPSSE_WRITE_TMS | MPSSE_LSB | MPSSE_BITMODE | MPSSE_WRITE_NEG; + *ptr++ = 2; + *ptr++ = (dr & 0x80) | 0x03; - E(ftdi_write_data(pdata->ftdic, buf, ptr - buf) != ptr - buf, pdata->ftdic); + E(ftdi_write_data(pdata->ftdic, buf, ptr - buf) != ptr - buf, pdata->ftdic); - return 0; + return 0; } -static int avrftdi_jtag_dr_inout(const PROGRAMMER *pgm, unsigned int dr, - int bits) -{ - Avrftdi_data *pdata = to_pdata(pgm); - unsigned char buf[19], *ptr = buf; - unsigned char bytes = 1, pos; - unsigned int dr_in; +static int avrftdi_jtag_dr_inout(const PROGRAMMER *pgm, unsigned int dr, int bits) { + Avrftdi_data *pdata = to_pdata(pgm); + unsigned char buf[19], *ptr = buf; + unsigned char bytes = 1, pos; + unsigned int dr_in; - if (bits <= 0 || bits > 31) { - return -1; - } + if(bits <= 0 || bits > 31) { + return -1; + } - /* Run-Test/Idle -> Select-DR -> Capture-DR -> Shift-DR */ - *ptr++ = MPSSE_WRITE_TMS | MPSSE_LSB | MPSSE_BITMODE | MPSSE_WRITE_NEG; - *ptr++ = 2; - *ptr++ = 0x01; + // Run-Test/Idle -> Select-DR -> Capture-DR -> Shift-DR + *ptr++ = MPSSE_WRITE_TMS | MPSSE_LSB | MPSSE_BITMODE | MPSSE_WRITE_NEG; + *ptr++ = 2; + *ptr++ = 0x01; - while (bits > 8) { - /* Read/write bits */ - *ptr++ = MPSSE_DO_READ | MPSSE_DO_WRITE | MPSSE_LSB | MPSSE_BITMODE | MPSSE_WRITE_NEG; - *ptr++ = 7; - *ptr++ = dr & 0xff; - bits -= 8; - bytes++; - dr >>= 8; - } + while(bits > 8) { + // Read/write bits + *ptr++ = MPSSE_DO_READ | MPSSE_DO_WRITE | MPSSE_LSB | MPSSE_BITMODE | MPSSE_WRITE_NEG; + *ptr++ = 7; + *ptr++ = dr & 0xff; + bits -= 8; + bytes++; + dr >>= 8; + } - if (bits > 1) { - /* Read/write */ - *ptr++ = MPSSE_DO_READ | MPSSE_DO_WRITE | MPSSE_LSB | MPSSE_BITMODE | MPSSE_WRITE_NEG; - *ptr++ = bits - 2; - *ptr++ = dr & ((1 << (bits - 1)) - 1); - bytes++; - } - dr <<= 8 - bits; + if(bits > 1) { + // Read/write + *ptr++ = MPSSE_DO_READ | MPSSE_DO_WRITE | MPSSE_LSB | MPSSE_BITMODE | MPSSE_WRITE_NEG; + *ptr++ = bits - 2; + *ptr++ = dr & ((1 << (bits - 1)) - 1); + bytes++; + } + dr <<= 8 - bits; - /* Read/write MSB and Shift-DR -> Exit1-DR -> Update-DR -> Run-Test/Idle */ - *ptr++ = MPSSE_WRITE_TMS | MPSSE_DO_READ | MPSSE_LSB | MPSSE_BITMODE | MPSSE_WRITE_NEG; - *ptr++ = 2; - *ptr++ = (dr & 0x80) | 0x03; - *ptr++ = SEND_IMMEDIATE; + // Read/write MSB and Shift-DR -> Exit1-DR -> Update-DR -> Run-Test/Idle + *ptr++ = MPSSE_WRITE_TMS | MPSSE_DO_READ | MPSSE_LSB | MPSSE_BITMODE | MPSSE_WRITE_NEG; + *ptr++ = 2; + *ptr++ = (dr & 0x80) | 0x03; + *ptr++ = SEND_IMMEDIATE; - E(ftdi_write_data(pdata->ftdic, buf, ptr - buf) != ptr - buf, pdata->ftdic); + E(ftdi_write_data(pdata->ftdic, buf, ptr - buf) != ptr - buf, pdata->ftdic); - pos = 0; - do { - int n = ftdi_read_data(pdata->ftdic, &buf[pos], bytes - pos); - E(n < 0, pdata->ftdic); - pos += n; - } while (pos < bytes); + pos = 0; + do { + int n = ftdi_read_data(pdata->ftdic, &buf[pos], bytes - pos); - dr_in = 0; - ptr = buf; - pos = 0; - while (bytes - (ptr - buf) > 2) { - dr_in |= *ptr++ << pos; - pos += 8; - } - if (bytes >= 1) { - dr_in |= *ptr++ << (pos - 8 + bits - 1); - pos += bits - 1; - } - dr_in |= (*ptr++ & 0x20) << (pos - 5); + E(n < 0, pdata->ftdic); + pos += n; + } while(pos < bytes); - return dr_in; + dr_in = 0; + ptr = buf; + pos = 0; + while(bytes - (ptr - buf) > 2) { + dr_in |= *ptr++ << pos; + pos += 8; + } + if(bytes >= 1) { + dr_in |= *ptr++ << (pos - 8 + bits - 1); + pos += bits - 1; + } + dr_in |= (*ptr++ & 0x20) << (pos - 5); + + return dr_in; } -static void avrftdi_jtag_enable(PROGRAMMER *pgm, const AVRPART *p) -{ - pgm->powerup(pgm); +static void avrftdi_jtag_enable(PROGRAMMER *pgm, const AVRPART *p) { + pgm->powerup(pgm); - set_pin(pgm, PIN_AVR_RESET, OFF); - set_pin(pgm, PIN_JTAG_TCK, OFF); - usleep(20 * 1000); + set_pin(pgm, PIN_AVR_RESET, OFF); + set_pin(pgm, PIN_JTAG_TCK, OFF); + usleep(20*1000); - set_pin(pgm, PIN_AVR_RESET, ON); - usleep(20 * 1000); + set_pin(pgm, PIN_AVR_RESET, ON); + usleep(20*1000); } -static int avrftdi_jtag_initialize(const PROGRAMMER *pgm, const AVRPART *p) -{ - if(!ovsigck) { - if(str_eq(p->id, "m128a") || str_eq(p->id, "m128") || - str_eq(p->id, "m64a") || str_eq(p->id, "m64") || - str_eq(p->id, "m32a") || str_eq(p->id, "m32") || - str_eq(p->id, "m16a") || str_eq(p->id, "m16") || - str_eq(p->id, "m162")) { - pmsg_error("programmer type %s is known not to work for %s\n", pgm->type, p->desc); - pmsg_error("exiting, use -F to carry on regardless\n"); - return LIBAVRDUDE_EXIT; - } - } +static int avrftdi_jtag_initialize(const PROGRAMMER *pgm, const AVRPART *p) { + if(!ovsigck) { + if(str_eq(p->id, "m128a") || str_eq(p->id, "m128") || + str_eq(p->id, "m64a") || str_eq(p->id, "m64") || + str_eq(p->id, "m32a") || str_eq(p->id, "m32") || + str_eq(p->id, "m16a") || str_eq(p->id, "m16") || str_eq(p->id, "m162")) { - set_pin(pgm, PPI_AVR_BUFF, ON); + pmsg_error("programmer type %s is known not to work for %s\n", pgm->type, p->desc); + pmsg_error("exiting, use -F to carry on regardless\n"); + return LIBAVRDUDE_EXIT; + } + } - avrftdi_jtag_reset(pgm); + set_pin(pgm, PPI_AVR_BUFF, ON); - /* Set RESET */ - avrftdi_jtag_ir_out(pgm, JTAG_IR_AVR_RESET); - avrftdi_jtag_dr_out(pgm, 1, 1); + avrftdi_jtag_reset(pgm); - /* Write program enable magic */ - avrftdi_jtag_ir_out(pgm, JTAG_IR_PROG_ENABLE); - avrftdi_jtag_dr_out(pgm, 0xa370, 16); + // Set RESET + avrftdi_jtag_ir_out(pgm, JTAG_IR_AVR_RESET); + avrftdi_jtag_dr_out(pgm, 1, 1); - return 0; + // Write program enable magic + avrftdi_jtag_ir_out(pgm, JTAG_IR_PROG_ENABLE); + avrftdi_jtag_dr_out(pgm, 0xa370, 16); + + return 0; } static void avrftdi_jtag_disable(const PROGRAMMER *pgm) { - Avrftdi_data *pdata = to_pdata(pgm); + Avrftdi_data *pdata = to_pdata(pgm); - /* NOP command */ - avrftdi_jtag_ir_out(pgm, JTAG_IR_PROG_COMMANDS); - avrftdi_jtag_dr_out(pgm, 0x2300, 15); - avrftdi_jtag_dr_out(pgm, 0x3300, 15); + // Nop command + avrftdi_jtag_ir_out(pgm, JTAG_IR_PROG_COMMANDS); + avrftdi_jtag_dr_out(pgm, 0x2300, 15); + avrftdi_jtag_dr_out(pgm, 0x3300, 15); - /* Clear program enable */ - avrftdi_jtag_ir_out(pgm, JTAG_IR_PROG_ENABLE); - avrftdi_jtag_dr_out(pgm, 0x0000, 16); + // Clear program enable + avrftdi_jtag_ir_out(pgm, JTAG_IR_PROG_ENABLE); + avrftdi_jtag_dr_out(pgm, 0x0000, 16); - /* Disable RESET */ - avrftdi_jtag_ir_out(pgm, JTAG_IR_AVR_RESET); - avrftdi_jtag_dr_out(pgm, 0, 1); + // Disable RESET + avrftdi_jtag_ir_out(pgm, JTAG_IR_AVR_RESET); + avrftdi_jtag_dr_out(pgm, 0, 1); - write_flush(pdata); + write_flush(pdata); - set_pin(pgm, PPI_AVR_BUFF, OFF); + set_pin(pgm, PPI_AVR_BUFF, OFF); } -static int avrftdi_jtag_chip_erase(const PROGRAMMER *pgm, const AVRPART *p) -{ - avrftdi_jtag_ir_out(pgm, JTAG_IR_PROG_COMMANDS); - avrftdi_jtag_dr_out(pgm, 0x2380, 15); - avrftdi_jtag_dr_out(pgm, 0x3180, 15); - avrftdi_jtag_dr_out(pgm, 0x3380, 15); - avrftdi_jtag_dr_out(pgm, 0x3380, 15); - while (!(avrftdi_jtag_dr_inout(pgm, 0x3380, 15) & 0x0200)) - ; +static int avrftdi_jtag_chip_erase(const PROGRAMMER *pgm, const AVRPART *p) { + avrftdi_jtag_ir_out(pgm, JTAG_IR_PROG_COMMANDS); + avrftdi_jtag_dr_out(pgm, 0x2380, 15); + avrftdi_jtag_dr_out(pgm, 0x3180, 15); + avrftdi_jtag_dr_out(pgm, 0x3380, 15); + avrftdi_jtag_dr_out(pgm, 0x3380, 15); + while(!(avrftdi_jtag_dr_inout(pgm, 0x3380, 15) & 0x0200)); - return 0; + return 0; } static int avrftdi_jtag_read_byte(const PROGRAMMER *pgm, const AVRPART *p, - const AVRMEM *m, unsigned long addr, unsigned char *value) -{ - if (mem_is_lfuse(m)) { - avrftdi_jtag_ir_out(pgm, JTAG_IR_PROG_COMMANDS); - avrftdi_jtag_dr_out(pgm, 0x2300 | JTAG_DR_PROG_FUSE_READ, 15); + const AVRMEM *m, unsigned long addr, unsigned char *value) { + if(mem_is_lfuse(m)) { + avrftdi_jtag_ir_out(pgm, JTAG_IR_PROG_COMMANDS); + avrftdi_jtag_dr_out(pgm, 0x2300 | JTAG_DR_PROG_FUSE_READ, 15); - /* Read fuse low byte */ - avrftdi_jtag_dr_out(pgm, 0x3200, 15); - *value = avrftdi_jtag_dr_inout(pgm, 0x3300, 15) & 0xff; + // Read fuse low byte + avrftdi_jtag_dr_out(pgm, 0x3200, 15); + *value = avrftdi_jtag_dr_inout(pgm, 0x3300, 15) & 0xff; - } else if (mem_is_hfuse(m)) { - avrftdi_jtag_ir_out(pgm, JTAG_IR_PROG_COMMANDS); - avrftdi_jtag_dr_out(pgm, 0x2300 | JTAG_DR_PROG_FUSE_READ, 15); + } else if(mem_is_hfuse(m)) { + avrftdi_jtag_ir_out(pgm, JTAG_IR_PROG_COMMANDS); + avrftdi_jtag_dr_out(pgm, 0x2300 | JTAG_DR_PROG_FUSE_READ, 15); - /* Read fuse high byte */ - avrftdi_jtag_dr_out(pgm, 0x3e00, 15); - *value = avrftdi_jtag_dr_inout(pgm, 0x3f00, 15) & 0xff; + // Read fuse high byte + avrftdi_jtag_dr_out(pgm, 0x3e00, 15); + *value = avrftdi_jtag_dr_inout(pgm, 0x3f00, 15) & 0xff; - } else if (mem_is_efuse(m)) { - avrftdi_jtag_ir_out(pgm, JTAG_IR_PROG_COMMANDS); - avrftdi_jtag_dr_out(pgm, 0x2300 | JTAG_DR_PROG_FUSE_READ, 15); + } else if(mem_is_efuse(m)) { + avrftdi_jtag_ir_out(pgm, JTAG_IR_PROG_COMMANDS); + avrftdi_jtag_dr_out(pgm, 0x2300 | JTAG_DR_PROG_FUSE_READ, 15); - /* Read fuse extended byte */ - avrftdi_jtag_dr_out(pgm, 0x3a00, 15); - *value = avrftdi_jtag_dr_inout(pgm, 0x3b00, 15) & 0xff; + // Read fuse extended byte + avrftdi_jtag_dr_out(pgm, 0x3a00, 15); + *value = avrftdi_jtag_dr_inout(pgm, 0x3b00, 15) & 0xff; - } else if (mem_is_lock(m)) { - avrftdi_jtag_ir_out(pgm, JTAG_IR_PROG_COMMANDS); - avrftdi_jtag_dr_out(pgm, 0x2300 | JTAG_DR_PROG_FUSE_READ, 15); + } else if(mem_is_lock(m)) { + avrftdi_jtag_ir_out(pgm, JTAG_IR_PROG_COMMANDS); + avrftdi_jtag_dr_out(pgm, 0x2300 | JTAG_DR_PROG_FUSE_READ, 15); - /* Read lock bits byte */ - avrftdi_jtag_dr_out(pgm, 0x3600, 15); - *value = avrftdi_jtag_dr_inout(pgm, 0x3700, 15) & 0xff; + // Read lock bits byte + avrftdi_jtag_dr_out(pgm, 0x3600, 15); + *value = avrftdi_jtag_dr_inout(pgm, 0x3700, 15) & 0xff; - } else if (mem_is_signature(m)) { - avrftdi_jtag_ir_out(pgm, JTAG_IR_PROG_COMMANDS); - avrftdi_jtag_dr_out(pgm, 0x2300 | JTAG_DR_PROG_SIGCAL_READ, 15); - avrftdi_jtag_dr_out(pgm, 0x0300 | (addr & 0xff), 15); + } else if(mem_is_signature(m)) { + avrftdi_jtag_ir_out(pgm, JTAG_IR_PROG_COMMANDS); + avrftdi_jtag_dr_out(pgm, 0x2300 | JTAG_DR_PROG_SIGCAL_READ, 15); + avrftdi_jtag_dr_out(pgm, 0x0300 | (addr & 0xff), 15); - /* Read signature byte */ - avrftdi_jtag_dr_out(pgm, 0x3200, 15); - *value = avrftdi_jtag_dr_inout(pgm, 0x3300, 15) & 0xff; + // Read signature byte + avrftdi_jtag_dr_out(pgm, 0x3200, 15); + *value = avrftdi_jtag_dr_inout(pgm, 0x3300, 15) & 0xff; - } else if (mem_is_calibration(m)) { - avrftdi_jtag_ir_out(pgm, JTAG_IR_PROG_COMMANDS); - avrftdi_jtag_dr_out(pgm, 0x2300 | JTAG_DR_PROG_SIGCAL_READ, 15); - avrftdi_jtag_dr_out(pgm, 0x0300 | (addr & 0xff), 15); + } else if(mem_is_calibration(m)) { + avrftdi_jtag_ir_out(pgm, JTAG_IR_PROG_COMMANDS); + avrftdi_jtag_dr_out(pgm, 0x2300 | JTAG_DR_PROG_SIGCAL_READ, 15); + avrftdi_jtag_dr_out(pgm, 0x0300 | (addr & 0xff), 15); - /* Read calibration byte */ - avrftdi_jtag_dr_out(pgm, 0x3600, 15); - *value = avrftdi_jtag_dr_inout(pgm, 0x3700, 15) & 0xff; + // Read calibration byte + avrftdi_jtag_dr_out(pgm, 0x3600, 15); + *value = avrftdi_jtag_dr_inout(pgm, 0x3700, 15) & 0xff; - } else if (mem_is_in_sigrow(m)) { - addr += avr_sigrow_offset(p, m, addr); - avrftdi_jtag_ir_out(pgm, JTAG_IR_PROG_COMMANDS); - avrftdi_jtag_dr_out(pgm, 0x2300 | JTAG_DR_PROG_SIGCAL_READ, 15); - avrftdi_jtag_dr_out(pgm, 0x0300 | (addr/2 & 0xff), 15); + } else if(mem_is_in_sigrow(m)) { + addr += avr_sigrow_offset(p, m, addr); + avrftdi_jtag_ir_out(pgm, JTAG_IR_PROG_COMMANDS); + avrftdi_jtag_dr_out(pgm, 0x2300 | JTAG_DR_PROG_SIGCAL_READ, 15); + avrftdi_jtag_dr_out(pgm, 0x0300 | (addr/2 & 0xff), 15); - /* Read prodsig byte either through signature (even addr) or calibration (odd) */ - avrftdi_jtag_dr_out(pgm, addr&1? 0x3600: 0x3200, 15); - *value = avrftdi_jtag_dr_inout(pgm, addr&1? 0x3700: 0x3300, 15) & 0xff; + // Read prodsig byte either through signature (even addr) or calibration (odd) + avrftdi_jtag_dr_out(pgm, addr & 1? 0x3600: 0x3200, 15); + *value = avrftdi_jtag_dr_inout(pgm, addr & 1? 0x3700: 0x3300, 15) & 0xff; - } else { - return -1; - } + } else { + return -1; + } - return 0; + return 0; } static int avrftdi_jtag_write_byte(const PROGRAMMER *pgm, const AVRPART *p, - const AVRMEM *m, unsigned long addr, unsigned char value) -{ - if (mem_is_lfuse(m)) { - avrftdi_jtag_ir_out(pgm, JTAG_IR_PROG_COMMANDS); - avrftdi_jtag_dr_out(pgm, 0x2300 | JTAG_DR_PROG_FUSE_WRITE, 15); + const AVRMEM *m, unsigned long addr, unsigned char value) { + if(mem_is_lfuse(m)) { + avrftdi_jtag_ir_out(pgm, JTAG_IR_PROG_COMMANDS); + avrftdi_jtag_dr_out(pgm, 0x2300 | JTAG_DR_PROG_FUSE_WRITE, 15); - /* Load data low byte */ - avrftdi_jtag_dr_out(pgm, 0x1300 | value, 15); + // Load data low byte + avrftdi_jtag_dr_out(pgm, 0x1300 | value, 15); - /* Write fuse low byte */ - avrftdi_jtag_dr_out(pgm, 0x3300, 15); - avrftdi_jtag_dr_out(pgm, 0x3100, 15); - avrftdi_jtag_dr_out(pgm, 0x3300, 15); - avrftdi_jtag_dr_out(pgm, 0x3300, 15); + // Write fuse low byte + avrftdi_jtag_dr_out(pgm, 0x3300, 15); + avrftdi_jtag_dr_out(pgm, 0x3100, 15); + avrftdi_jtag_dr_out(pgm, 0x3300, 15); + avrftdi_jtag_dr_out(pgm, 0x3300, 15); - /* Poll for fuse write complete */ - while (!(avrftdi_jtag_dr_inout(pgm, 0x3300, 15) & 0x0200)) - ; + // Poll for fuse write complete + while(!(avrftdi_jtag_dr_inout(pgm, 0x3300, 15) & 0x0200)); - } else if (mem_is_hfuse(m)) { - avrftdi_jtag_ir_out(pgm, JTAG_IR_PROG_COMMANDS); - avrftdi_jtag_dr_out(pgm, 0x2300 | JTAG_DR_PROG_FUSE_WRITE, 15); + } else if(mem_is_hfuse(m)) { + avrftdi_jtag_ir_out(pgm, JTAG_IR_PROG_COMMANDS); + avrftdi_jtag_dr_out(pgm, 0x2300 | JTAG_DR_PROG_FUSE_WRITE, 15); - /* Load data low byte */ - avrftdi_jtag_dr_out(pgm, 0x1300 | value, 15); + // Load data low byte + avrftdi_jtag_dr_out(pgm, 0x1300 | value, 15); - /* Write fuse low byte */ - avrftdi_jtag_dr_out(pgm, 0x3700, 15); - avrftdi_jtag_dr_out(pgm, 0x3500, 15); - avrftdi_jtag_dr_out(pgm, 0x3700, 15); - avrftdi_jtag_dr_out(pgm, 0x3700, 15); + // Write fuse low byte + avrftdi_jtag_dr_out(pgm, 0x3700, 15); + avrftdi_jtag_dr_out(pgm, 0x3500, 15); + avrftdi_jtag_dr_out(pgm, 0x3700, 15); + avrftdi_jtag_dr_out(pgm, 0x3700, 15); - /* Poll for fuse write complete */ - while (!(avrftdi_jtag_dr_inout(pgm, 0x3700, 15) & 0x0200)) - ; + // Poll for fuse write complete + while(!(avrftdi_jtag_dr_inout(pgm, 0x3700, 15) & 0x0200)); - } else if (mem_is_efuse(m)) { - avrftdi_jtag_ir_out(pgm, JTAG_IR_PROG_COMMANDS); - avrftdi_jtag_dr_out(pgm, 0x2300 | JTAG_DR_PROG_FUSE_WRITE, 15); + } else if(mem_is_efuse(m)) { + avrftdi_jtag_ir_out(pgm, JTAG_IR_PROG_COMMANDS); + avrftdi_jtag_dr_out(pgm, 0x2300 | JTAG_DR_PROG_FUSE_WRITE, 15); - /* Load data low byte */ - avrftdi_jtag_dr_out(pgm, 0x1300 | value, 15); + // Load data low byte + avrftdi_jtag_dr_out(pgm, 0x1300 | value, 15); - /* Write fuse low byte */ - avrftdi_jtag_dr_out(pgm, 0x3b00, 15); - avrftdi_jtag_dr_out(pgm, 0x3900, 15); - avrftdi_jtag_dr_out(pgm, 0x3b00, 15); - avrftdi_jtag_dr_out(pgm, 0x3b00, 15); + // Write fuse low byte + avrftdi_jtag_dr_out(pgm, 0x3b00, 15); + avrftdi_jtag_dr_out(pgm, 0x3900, 15); + avrftdi_jtag_dr_out(pgm, 0x3b00, 15); + avrftdi_jtag_dr_out(pgm, 0x3b00, 15); - /* Poll for fuse write complete */ - while (!(avrftdi_jtag_dr_inout(pgm, 0x3b00, 15) & 0x0200)) - ; + // Poll for fuse write complete + while(!(avrftdi_jtag_dr_inout(pgm, 0x3b00, 15) & 0x0200)); - } else if (mem_is_lock(m)) { - avrftdi_jtag_ir_out(pgm, JTAG_IR_PROG_COMMANDS); - avrftdi_jtag_dr_out(pgm, 0x2300 | JTAG_DR_PROG_LOCK_WRITE, 15); + } else if(mem_is_lock(m)) { + avrftdi_jtag_ir_out(pgm, JTAG_IR_PROG_COMMANDS); + avrftdi_jtag_dr_out(pgm, 0x2300 | JTAG_DR_PROG_LOCK_WRITE, 15); - /* Load data low byte */ - avrftdi_jtag_dr_out(pgm, 0x1300 | value | 0xc0, 15); + // Load data low byte + avrftdi_jtag_dr_out(pgm, 0x1300 | value | 0xc0, 15); - /* Write fuse low byte */ - avrftdi_jtag_dr_out(pgm, 0x3300, 15); - avrftdi_jtag_dr_out(pgm, 0x3100, 15); - avrftdi_jtag_dr_out(pgm, 0x3300, 15); - avrftdi_jtag_dr_out(pgm, 0x3300, 15); + // Write fuse low byte + avrftdi_jtag_dr_out(pgm, 0x3300, 15); + avrftdi_jtag_dr_out(pgm, 0x3100, 15); + avrftdi_jtag_dr_out(pgm, 0x3300, 15); + avrftdi_jtag_dr_out(pgm, 0x3300, 15); - /* Poll for fuse write complete */ - while (!(avrftdi_jtag_dr_inout(pgm, 0x3300, 15) & 0x0200)) - ; + // Poll for fuse write complete + while(!(avrftdi_jtag_dr_inout(pgm, 0x3300, 15) & 0x0200)); - } else if(mem_is_readonly(m)) { - unsigned char is; - if(pgm->read_byte(pgm, p, m, addr, &is) >= 0 && is == value) - return 0; + } else if(mem_is_readonly(m)) { + unsigned char is; - pmsg_error("cannot write to read-only memory %s of %s\n", m->desc, p->desc); - return -1; - } else { - return -1; - } + if(pgm->read_byte(pgm, p, m, addr, &is) >= 0 && is == value) + return 0; - return 0; + pmsg_error("cannot write to read-only memory %s of %s\n", m->desc, p->desc); + return -1; + } else { + return -1; + } + + return 0; } static int avrftdi_jtag_paged_write(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; - unsigned char byte; + const AVRMEM *m, unsigned int page_size, unsigned int addr, unsigned int n_bytes) { + unsigned int maxaddr = addr + n_bytes; + unsigned char byte; - if (mem_is_flash(m)) { - avrftdi_jtag_ir_out(pgm, JTAG_IR_PROG_COMMANDS); - avrftdi_jtag_dr_out(pgm, 0x2300 | JTAG_DR_PROG_FLASH_WRITE, 15); + if(mem_is_flash(m)) { + avrftdi_jtag_ir_out(pgm, JTAG_IR_PROG_COMMANDS); + avrftdi_jtag_dr_out(pgm, 0x2300 | JTAG_DR_PROG_FLASH_WRITE, 15); - /* Load address */ - avrftdi_jtag_dr_out(pgm, 0x0b00 | ((addr >> 17) & 0xff), 15); - avrftdi_jtag_dr_out(pgm, 0x0700 | ((addr >> 9) & 0xff), 15); - avrftdi_jtag_dr_out(pgm, 0x0300 | ((addr >> 1) & 0xff), 15); + // Load address + avrftdi_jtag_dr_out(pgm, 0x0b00 | ((addr >> 17) & 0xff), 15); + avrftdi_jtag_dr_out(pgm, 0x0700 | ((addr >> 9) & 0xff), 15); + avrftdi_jtag_dr_out(pgm, 0x0300 | ((addr >> 1) & 0xff), 15); - /* Load page data */ - avrftdi_jtag_ir_out(pgm, JTAG_IR_PROG_PAGELOAD); - for (unsigned int i = 0; i < page_size; i++) { - byte = i < (maxaddr - addr) ? m->buf[addr + i] : 0xff; - avrftdi_jtag_dr_out(pgm, byte, 8); - } + // Load page data + avrftdi_jtag_ir_out(pgm, JTAG_IR_PROG_PAGELOAD); + for(unsigned int i = 0; i < page_size; i++) { + byte = i < (maxaddr - addr)? m->buf[addr + i]: 0xff; + avrftdi_jtag_dr_out(pgm, byte, 8); + } - /* Write Flash page */ - avrftdi_jtag_ir_out(pgm, JTAG_IR_PROG_COMMANDS); - avrftdi_jtag_dr_out(pgm, 0x3700, 15); - avrftdi_jtag_dr_out(pgm, 0x3500, 15); - avrftdi_jtag_dr_out(pgm, 0x3700, 15); - avrftdi_jtag_dr_out(pgm, 0x3700, 15); + // Write Flash page + avrftdi_jtag_ir_out(pgm, JTAG_IR_PROG_COMMANDS); + avrftdi_jtag_dr_out(pgm, 0x3700, 15); + avrftdi_jtag_dr_out(pgm, 0x3500, 15); + avrftdi_jtag_dr_out(pgm, 0x3700, 15); + avrftdi_jtag_dr_out(pgm, 0x3700, 15); - /* Wait for completion */ - while (!(avrftdi_jtag_dr_inout(pgm, 0x3700, 15) & 0x0200)) - ; + // Wait for completion + while(!(avrftdi_jtag_dr_inout(pgm, 0x3700, 15) & 0x0200)); - } else if (mem_is_eeprom(m)) { - avrftdi_jtag_ir_out(pgm, JTAG_IR_PROG_COMMANDS); - avrftdi_jtag_dr_out(pgm, 0x2300 | JTAG_DR_PROG_EEPROM_WRITE, 15); + } else if(mem_is_eeprom(m)) { + avrftdi_jtag_ir_out(pgm, JTAG_IR_PROG_COMMANDS); + avrftdi_jtag_dr_out(pgm, 0x2300 | JTAG_DR_PROG_EEPROM_WRITE, 15); - for (; addr < maxaddr; addr += page_size) { - for (unsigned int i = 0; i < page_size; i++) { - /* Load address */ - avrftdi_jtag_dr_out(pgm, 0x0700 | ((addr >> 8) & 0xff), 15); - avrftdi_jtag_dr_out(pgm, 0x0300 | ((addr + i) & 0xff), 15); + for(; addr < maxaddr; addr += page_size) { + for(unsigned int i = 0; i < page_size; i++) { + // Load address + avrftdi_jtag_dr_out(pgm, 0x0700 | ((addr >> 8) & 0xff), 15); + avrftdi_jtag_dr_out(pgm, 0x0300 | ((addr + i) & 0xff), 15); - /* Load data byte */ - avrftdi_jtag_dr_out(pgm, 0x1300 | m->buf[addr + i], 15); + // Load data byte + avrftdi_jtag_dr_out(pgm, 0x1300 | m->buf[addr + i], 15); - /* Latch data */ - avrftdi_jtag_dr_out(pgm, 0x3700, 15); - avrftdi_jtag_dr_out(pgm, 0x7700, 15); - avrftdi_jtag_dr_out(pgm, 0x3700, 15); - } + // Latch data + avrftdi_jtag_dr_out(pgm, 0x3700, 15); + avrftdi_jtag_dr_out(pgm, 0x7700, 15); + avrftdi_jtag_dr_out(pgm, 0x3700, 15); + } - /* Write EEPROM page */ - avrftdi_jtag_dr_out(pgm, 0x3300, 15); - avrftdi_jtag_dr_out(pgm, 0x3100, 15); - avrftdi_jtag_dr_out(pgm, 0x3300, 15); - avrftdi_jtag_dr_out(pgm, 0x3300, 15); + // Write EEPROM page + avrftdi_jtag_dr_out(pgm, 0x3300, 15); + avrftdi_jtag_dr_out(pgm, 0x3100, 15); + avrftdi_jtag_dr_out(pgm, 0x3300, 15); + avrftdi_jtag_dr_out(pgm, 0x3300, 15); - /* Wait for completion */ - while (!(avrftdi_jtag_dr_inout(pgm, 0x3300, 15) & 0x0200)) - ; - } - } else { - return -1; - } + // Wait for completion + while(!(avrftdi_jtag_dr_inout(pgm, 0x3300, 15) & 0x0200)); + } + } else { + return -1; + } - return n_bytes; + return n_bytes; } static int avrftdi_jtag_paged_read(const PROGRAMMER *pgm, const AVRPART *p, - const AVRMEM *m, unsigned int page_size, unsigned int addr, - unsigned int n_bytes) -{ - Avrftdi_data *pdata = to_pdata(pgm); - unsigned int maxaddr = addr + n_bytes; - unsigned char *buf, *ptr; - unsigned int bytes; + const AVRMEM *m, unsigned int page_size, unsigned int addr, unsigned int n_bytes) { + Avrftdi_data *pdata = to_pdata(pgm); + unsigned int maxaddr = addr + n_bytes; + unsigned char *buf, *ptr; + unsigned int bytes; - buf = alloca(n_bytes * 8 + 1); - ptr = buf; + buf = alloca(n_bytes*8 + 1); + ptr = buf; - if (mem_is_flash(m)) { - avrftdi_jtag_ir_out(pgm, JTAG_IR_PROG_COMMANDS); - avrftdi_jtag_dr_out(pgm, 0x2300 | JTAG_DR_PROG_FLASH_READ, 15); + if(mem_is_flash(m)) { + avrftdi_jtag_ir_out(pgm, JTAG_IR_PROG_COMMANDS); + avrftdi_jtag_dr_out(pgm, 0x2300 | JTAG_DR_PROG_FLASH_READ, 15); - /* Load address */ - avrftdi_jtag_dr_out(pgm, 0x0b00 | ((addr >> 17) & 0xff), 15); - avrftdi_jtag_dr_out(pgm, 0x0700 | ((addr >> 9) & 0xff), 15); - avrftdi_jtag_dr_out(pgm, 0x0300 | ((addr >> 1) & 0xff), 15); - avrftdi_jtag_ir_out(pgm, JTAG_IR_PROG_PAGEREAD); + // Load address + avrftdi_jtag_dr_out(pgm, 0x0b00 | ((addr >> 17) & 0xff), 15); + avrftdi_jtag_dr_out(pgm, 0x0700 | ((addr >> 9) & 0xff), 15); + avrftdi_jtag_dr_out(pgm, 0x0300 | ((addr >> 1) & 0xff), 15); + avrftdi_jtag_ir_out(pgm, JTAG_IR_PROG_PAGEREAD); - for (unsigned int i = addr; i < maxaddr; i++) { - /* Run-Test/Idle -> Select-DR -> Capture-DR -> Shift-DR */ - *ptr++ = MPSSE_WRITE_TMS | MPSSE_LSB | MPSSE_BITMODE | MPSSE_WRITE_NEG; - *ptr++ = 2; - *ptr++ = 0x01; + for(unsigned int i = addr; i < maxaddr; i++) { + // Run-Test/Idle -> Select-DR -> Capture-DR -> Shift-DR + *ptr++ = MPSSE_WRITE_TMS | MPSSE_LSB | MPSSE_BITMODE | MPSSE_WRITE_NEG; + *ptr++ = 2; + *ptr++ = 0x01; - /* Read byte */ - *ptr++ = MPSSE_DO_READ | MPSSE_LSB | MPSSE_BITMODE; - *ptr++ = 6; + // Read byte + *ptr++ = MPSSE_DO_READ | MPSSE_LSB | MPSSE_BITMODE; + *ptr++ = 6; - /* Shift-DR -> Exit1-DR -> Update-DR -> Run-Test/Idle */ - *ptr++ = MPSSE_WRITE_TMS | MPSSE_DO_READ | MPSSE_LSB | MPSSE_BITMODE | MPSSE_WRITE_NEG; - *ptr++ = 2; - *ptr++ = 0x03; - } + // Shift-DR -> Exit1-DR -> Update-DR -> Run-Test/Idle + *ptr++ = MPSSE_WRITE_TMS | MPSSE_DO_READ | MPSSE_LSB | MPSSE_BITMODE | MPSSE_WRITE_NEG; + *ptr++ = 2; + *ptr++ = 0x03; + } - *ptr++ = SEND_IMMEDIATE; - E(ftdi_write_data(pdata->ftdic, buf, ptr - buf) != ptr - buf, pdata->ftdic); + *ptr++ = SEND_IMMEDIATE; + E(ftdi_write_data(pdata->ftdic, buf, ptr - buf) != ptr - buf, pdata->ftdic); - bytes = 0; - do { - int n = ftdi_read_data(pdata->ftdic, &buf[bytes], n_bytes * 2 - bytes); - E(n < 0, pdata->ftdic); - bytes += n; - } while (bytes < n_bytes * 2); + bytes = 0; + do { + int n = ftdi_read_data(pdata->ftdic, &buf[bytes], n_bytes*2 - bytes); - for (unsigned int i = 0; i < n_bytes; i++) { - m->buf[addr + i] = (buf[i * 2] >> 1) | (buf[(i * 2) + 1] << 2); - } + E(n < 0, pdata->ftdic); + bytes += n; + } while(bytes < n_bytes*2); - } else if (mem_is_eeprom(m)) { - avrftdi_jtag_ir_out(pgm, JTAG_IR_PROG_COMMANDS); - avrftdi_jtag_dr_out(pgm, 0x2300 | JTAG_DR_PROG_EEPROM_READ, 15); + for(unsigned int i = 0; i < n_bytes; i++) { + m->buf[addr + i] = (buf[i*2] >> 1) | (buf[(i*2) + 1] << 2); + } - for (; addr < maxaddr; addr++) { - /* Load address */ - avrftdi_jtag_dr_out(pgm, 0x0700 | ((addr >> 8) & 0xff), 15); - avrftdi_jtag_dr_out(pgm, 0x0300 | (addr & 0xff), 15); + } else if(mem_is_eeprom(m)) { + avrftdi_jtag_ir_out(pgm, JTAG_IR_PROG_COMMANDS); + avrftdi_jtag_dr_out(pgm, 0x2300 | JTAG_DR_PROG_EEPROM_READ, 15); - /* Read data byte */ - avrftdi_jtag_dr_out(pgm, 0x3300 | (addr & 0xff), 15); - avrftdi_jtag_dr_out(pgm, 0x3200, 15); - m->buf[addr] = avrftdi_jtag_dr_inout(pgm, 0x3300, 15) & 0xff; - } + for(; addr < maxaddr; addr++) { + // Load address + avrftdi_jtag_dr_out(pgm, 0x0700 | ((addr >> 8) & 0xff), 15); + avrftdi_jtag_dr_out(pgm, 0x0300 | (addr & 0xff), 15); - } else { - return -1; - } + // Read data byte + avrftdi_jtag_dr_out(pgm, 0x3300 | (addr & 0xff), 15); + avrftdi_jtag_dr_out(pgm, 0x3200, 15); + m->buf[addr] = avrftdi_jtag_dr_inout(pgm, 0x3300, 15) & 0xff; + } - return n_bytes; + } else { + return -1; + } + + return n_bytes; } -void avrftdi_initpgm(PROGRAMMER *pgm) -{ - strcpy(pgm->type, "avrftdi"); +void avrftdi_initpgm(PROGRAMMER *pgm) { + strcpy(pgm->type, "avrftdi"); - /* - * mandatory functions - */ - pgm->initialize = avrftdi_initialize; - pgm->display = avrftdi_display; - pgm->enable = avrftdi_enable; - pgm->disable = avrftdi_disable; - pgm->powerup = avrftdi_powerup; - pgm->powerdown = avrftdi_powerdown; - pgm->program_enable = avrftdi_program_enable; - pgm->chip_erase = avrftdi_chip_erase; - pgm->cmd = avrftdi_cmd; - pgm->open = avrftdi_open; - pgm->close = avrftdi_close; - pgm->read_byte = avr_read_byte_default; - pgm->write_byte = avr_write_byte_default; + // Mandatory functions + pgm->initialize = avrftdi_initialize; + pgm->display = avrftdi_display; + pgm->enable = avrftdi_enable; + pgm->disable = avrftdi_disable; + pgm->powerup = avrftdi_powerup; + pgm->powerdown = avrftdi_powerdown; + pgm->program_enable = avrftdi_program_enable; + pgm->chip_erase = avrftdi_chip_erase; + pgm->cmd = avrftdi_cmd; + pgm->open = avrftdi_open; + pgm->close = avrftdi_close; + pgm->read_byte = avr_read_byte_default; + pgm->write_byte = avr_write_byte_default; - /* - * optional functions - */ - pgm->paged_write = avrftdi_paged_write; - pgm->paged_load = avrftdi_paged_load; - pgm->setpin = set_pin; - pgm->setup = avrftdi_setup; - pgm->teardown = avrftdi_teardown; - pgm->rdy_led = avrftdi_rdy_led; - pgm->err_led = avrftdi_err_led; - pgm->pgm_led = avrftdi_pgm_led; - pgm->vfy_led = avrftdi_vfy_led; + // Optional functions + pgm->paged_write = avrftdi_paged_write; + pgm->paged_load = avrftdi_paged_load; + pgm->setpin = set_pin; + pgm->setup = avrftdi_setup; + pgm->teardown = avrftdi_teardown; + pgm->rdy_led = avrftdi_rdy_led; + pgm->err_led = avrftdi_err_led; + pgm->pgm_led = avrftdi_pgm_led; + pgm->vfy_led = avrftdi_vfy_led; } -void avrftdi_jtag_initpgm(PROGRAMMER *pgm) -{ - strcpy(pgm->type, "avrftdi_jtag"); +void avrftdi_jtag_initpgm(PROGRAMMER *pgm) { + strcpy(pgm->type, "avrftdi_jtag"); - /* - * mandatory functions - */ - pgm->initialize = avrftdi_jtag_initialize; - pgm->display = avrftdi_display; - pgm->enable = avrftdi_jtag_enable; - pgm->disable = avrftdi_jtag_disable; - pgm->powerup = avrftdi_powerup; - pgm->powerdown = avrftdi_powerdown; - pgm->chip_erase = avrftdi_jtag_chip_erase; - pgm->open = avrftdi_open; - pgm->close = avrftdi_close; - pgm->read_byte = avrftdi_jtag_read_byte; - pgm->write_byte = avrftdi_jtag_write_byte; + // Mandatory functions + pgm->initialize = avrftdi_jtag_initialize; + pgm->display = avrftdi_display; + pgm->enable = avrftdi_jtag_enable; + pgm->disable = avrftdi_jtag_disable; + pgm->powerup = avrftdi_powerup; + pgm->powerdown = avrftdi_powerdown; + pgm->chip_erase = avrftdi_jtag_chip_erase; + pgm->open = avrftdi_open; + pgm->close = avrftdi_close; + pgm->read_byte = avrftdi_jtag_read_byte; + pgm->write_byte = avrftdi_jtag_write_byte; - /* - * optional functions - */ - pgm->paged_write = avrftdi_jtag_paged_write; - pgm->paged_load = avrftdi_jtag_paged_read; - pgm->setup = avrftdi_setup; - pgm->teardown = avrftdi_teardown; - pgm->rdy_led = avrftdi_rdy_led; - pgm->err_led = avrftdi_err_led; - pgm->pgm_led = avrftdi_pgm_led; - pgm->vfy_led = avrftdi_vfy_led; - pgm->page_size = 256; - pgm->flag = PGM_FL_IS_JTAG; + // Optional functions + pgm->paged_write = avrftdi_jtag_paged_write; + pgm->paged_load = avrftdi_jtag_paged_read; + pgm->setup = avrftdi_setup; + pgm->teardown = avrftdi_teardown; + pgm->rdy_led = avrftdi_rdy_led; + pgm->err_led = avrftdi_err_led; + pgm->pgm_led = avrftdi_pgm_led; + pgm->vfy_led = avrftdi_vfy_led; + pgm->page_size = 256; + pgm->flag = PGM_FL_IS_JTAG; } - -#endif /* DO_NOT_BUILD_AVRFTDI */ +#endif // DO_NOT_BUILD_AVRFTDI const char avrftdi_desc[] = "Interface to the MPSSE Engine of FTDI Chips using libftdi."; const char avrftdi_jtag_desc[] = "libftdi JTAG interface"; -