diff --git a/NEWS b/NEWS index 14945c4c4..db5f91eba 100644 --- a/NEWS +++ b/NEWS @@ -1520,11 +1520,11 @@ Version 5.7: - ATXMEGA64A1 - ATXMEGA192A1 - - ATXMEGA256A1 + - ATXMEGA256A1 - ATXMEGA64A3 - ATXMEGA128A3 - ATXMEGA192A3 - - ATXMEGA256A3 + - ATXMEGA256A3 - ATXMEGA256A3B - ATXMEGA16A4 - ATXMEGA32A4 @@ -1794,7 +1794,7 @@ Version 4.1.0 * Add support for avr910 type programmers (mcu00100, pavr avr910, etc). * Support new devices: ATmega8535, ATtiny26 - + Version 4.0.0 diff --git a/src/arduino.c b/src/arduino.c index 56157dbf8..5bbff7769 100644 --- a/src/arduino.c +++ b/src/arduino.c @@ -40,26 +40,26 @@ static int arduino_parseextparms(const PROGRAMMER *pgm, const LISTID extparms) { int rv = 0; bool help = 0; - for (LNODEID ln = lfirst(extparms); ln; ln = lnext(ln)) { + for(LNODEID ln = lfirst(extparms); ln; ln = lnext(ln)) { const char *extended_param = ldata(ln); - if (sscanf(extended_param, "attempts=%i", &attempts) == 1) { - PDATA(pgm)->retry_attempts = attempts; + if(sscanf(extended_param, "attempts=%i", &attempts) == 1) { + my.retry_attempts = attempts; pmsg_info("setting number of retry attempts to %d\n", attempts); continue; } if(str_eq(extended_param, "noautoreset")) { - PDATA(pgm)->autoreset = false; + my.autoreset = false; continue; } - if (str_eq(extended_param, "help")) { + if(str_eq(extended_param, "help")) { help = true; rv = LIBAVRDUDE_EXIT; } - if (!help) { + if(!help) { pmsg_error("invalid extended parameter -x %s\n", extended_param); rv = -1; } @@ -72,13 +72,13 @@ static int arduino_parseextparms(const PROGRAMMER *pgm, const LISTID extparms) { return rv; } -/* read signature bytes - arduino version */ +// Read signature bytes - arduino version static int arduino_read_sig_bytes(const PROGRAMMER *pgm, const AVRPART *p, const AVRMEM *m) { unsigned char buf[32]; - /* Signature byte reads are always 3 bytes. */ + // Signature byte reads are always 3 bytes - if (m->size < 3) { + if(m->size < 3) { pmsg_error("memsize too small for sig byte read"); return -1; } @@ -88,17 +88,17 @@ static int arduino_read_sig_bytes(const PROGRAMMER *pgm, const AVRPART *p, const serial_send(&pgm->fd, buf, 2); - if (serial_recv(&pgm->fd, buf, 5) < 0) + if(serial_recv(&pgm->fd, buf, 5) < 0) return -1; - if (buf[0] == Resp_STK_NOSYNC) { + if(buf[0] == Resp_STK_NOSYNC) { pmsg_error("programmer is out of sync\n"); - return -1; - } else if (buf[0] != Resp_STK_INSYNC) { + return -1; + } else if(buf[0] != Resp_STK_INSYNC) { msg_error("\n"); pmsg_error("protocol expects sync byte 0x%02x but got 0x%02x\n", Resp_STK_INSYNC, buf[0]); return -2; } - if (buf[4] != Resp_STK_OK) { + if(buf[4] != Resp_STK_OK) { msg_error("\n"); pmsg_error("protocol expects OK byte 0x%02x but got 0x%02x\n", Resp_STK_OK, buf[4]); return -3; @@ -113,24 +113,25 @@ static int arduino_read_sig_bytes(const PROGRAMMER *pgm, const AVRPART *p, const static int arduino_open(PROGRAMMER *pgm, const char *port) { union pinfo pinfo; + pgm->port = port; pinfo.serialinfo.baud = pgm->baudrate? pgm->baudrate: 115200; pinfo.serialinfo.cflags = SERIAL_8N1; - if (serial_open(port, pinfo, &pgm->fd)==-1) { + if(serial_open(port, pinfo, &pgm->fd) == -1) { return -1; } - if(PDATA(pgm)->autoreset) { + if(my.autoreset) { // This code assumes a negative-logic USB to TTL serial adapter // Set RTS/DTR high to discharge the series-capacitor, if present serial_set_dtr_rts(&pgm->fd, 0); /* - * Long wait needed for optiboot: otherwise the second of two bootloader - * calls in quick succession fails: - * - * avrdude -c arduino -qqp m328p -U x.hex; avrdude -c arduino -qqp m328p -U x.hex - */ - usleep(250 * 1000); + * Long wait needed for optiboot: otherwise the second of two bootloader + * calls in quick succession fails: + * + * avrdude -c arduino -qqp m328p -U x.hex; avrdude -c arduino -qqp m328p -U x.hex + */ + usleep(250*1000); // Pull the RTS/DTR line low to reset AVR serial_set_dtr_rts(&pgm->fd, 1); // Max 100 us: charging a cap longer creates a high reset spike above Vcc @@ -138,13 +139,12 @@ static int arduino_open(PROGRAMMER *pgm, const char *port) { // Set the RTS/DTR line back to high, so direct connection to reset works serial_set_dtr_rts(&pgm->fd, 0); - usleep(100 * 1000); + usleep(100*1000); } - // Drain any extraneous input stk500_drain(pgm, 0); - if (stk500_getsync(pgm) < 0) + if(stk500_getsync(pgm) < 0) return -1; return 0; @@ -159,7 +159,7 @@ const char arduino_desc[] = "Arduino programmer"; void arduino_initpgm(PROGRAMMER *pgm) { /* This is mostly a STK500; just the signature is read - differently than on real STK500v1 + differently than on real STK500v1 and the DTR signal is set when opening the serial port for the Auto-Reset feature */ stk500_initpgm(pgm); diff --git a/src/arduino.h b/src/arduino.h index eed3343d2..9708f003d 100644 --- a/src/arduino.h +++ b/src/arduino.h @@ -21,7 +21,4 @@ extern const char arduino_desc[]; void arduino_initpgm(PROGRAMMER *pgm); - #endif - - diff --git a/src/avr.c b/src/avr.c index 8c42647e2..b6337c760 100644 --- a/src/avr.c +++ b/src/avr.c @@ -37,28 +37,28 @@ FP_UpdateProgress update_progress; #define DEBUG 0 -/* TPI: returns nonzero if NVM controller busy, 0 if free */ +// TPI: returns nonzero if NVM controller busy, 0 if free int avr_tpi_poll_nvmbsy(const PROGRAMMER *pgm) { unsigned char cmd; unsigned char res; cmd = TPI_CMD_SIN | TPI_SIO_ADDR(TPI_IOREG_NVMCSR); - (void)pgm->cmd_tpi(pgm, &cmd, 1, &res, 1); + (void) pgm->cmd_tpi(pgm, &cmd, 1, &res, 1); return (res & TPI_IOREG_NVMCSR_NVMBSY); } -/* TPI chip erase sequence */ +// TPI chip erase sequence int avr_tpi_chip_erase(const PROGRAMMER *pgm, const AVRPART *p) { int err; AVRMEM *mem; - if (p->prog_modes & PM_TPI) { + if(is_tpi(p)) { led_clr(pgm, LED_ERR); led_set(pgm, LED_PGM); - /* Set Pointer Register */ + // Set pointer register mem = avr_locate_flash(p); - if (mem == NULL) { + if(mem == NULL) { pmsg_error("no flash memory to erase for part %s\n", p->desc); led_set(pgm, LED_ERR); led_clr(pgm, LED_PGM); @@ -66,21 +66,21 @@ int avr_tpi_chip_erase(const PROGRAMMER *pgm, const AVRPART *p) { } unsigned char cmd[] = { - /* write pointer register high byte */ + // Write pointer register high byte (TPI_CMD_SSTPR | 0), ((mem->offset & 0xFF) | 1), - /* and low byte */ + // and low byte (TPI_CMD_SSTPR | 1), ((mem->offset >> 8) & 0xFF), - /* write CHIP_ERASE command to NVMCMD register */ + // Write CHIP_ERASE command to NVMCMD register (TPI_CMD_SOUT | TPI_SIO_ADDR(TPI_IOREG_NVMCMD)), TPI_NVMCMD_CHIP_ERASE, - /* write dummy value to start erase */ + // Write dummy value to start erase TPI_CMD_SST, 0xFF }; - while (avr_tpi_poll_nvmbsy(pgm)) + while(avr_tpi_poll_nvmbsy(pgm)) continue; err = pgm->cmd_tpi(pgm, cmd, sizeof(cmd), NULL, 0); @@ -90,7 +90,7 @@ int avr_tpi_chip_erase(const PROGRAMMER *pgm, const AVRPART *p) { return err; } - while (avr_tpi_poll_nvmbsy(pgm)) + while(avr_tpi_poll_nvmbsy(pgm)) continue; led_clr(pgm, LED_PGM); @@ -101,14 +101,14 @@ int avr_tpi_chip_erase(const PROGRAMMER *pgm, const AVRPART *p) { } } -/* TPI program enable sequence */ +// TPI program enable sequence int avr_tpi_program_enable(const PROGRAMMER *pgm, const AVRPART *p, unsigned char guard_time) { int err, retry; unsigned char cmd[2]; unsigned char response; - if(p->prog_modes & PM_TPI) { - /* set guard time */ + if(is_tpi(p)) { + // Set guard time cmd[0] = (TPI_CMD_SSTCS | TPI_REG_TPIPCR); cmd[1] = guard_time; @@ -116,23 +116,22 @@ int avr_tpi_program_enable(const PROGRAMMER *pgm, const AVRPART *p, unsigned cha if(err) return err; - /* read TPI ident reg */ + // Read TPI ident reg cmd[0] = (TPI_CMD_SLDCS | TPI_REG_TPIIR); err = pgm->cmd_tpi(pgm, cmd, 1, &response, sizeof(response)); - if (err || response != TPI_IDENT_CODE) { + if(err || response != TPI_IDENT_CODE) { pmsg_error("TPIIR not correct\n"); return -1; } - /* send SKEY command + SKEY */ + // Send SKEY command + SKEY err = pgm->cmd_tpi(pgm, tpi_skey_cmd, sizeof(tpi_skey_cmd), NULL, 0); if(err) return err; - /* check if device is ready */ - for(retry = 0; retry < 10; retry++) - { - cmd[0] = (TPI_CMD_SLDCS | TPI_REG_TPISR); + // Check if device is ready + for(retry = 0; retry < 10; retry++) { + cmd[0] = (TPI_CMD_SLDCS | TPI_REG_TPISR); err = pgm->cmd_tpi(pgm, cmd, 1, &response, sizeof(response)); if(err || !(response & TPI_REG_TPISR_NVMEN)) continue; @@ -149,31 +148,30 @@ int avr_tpi_program_enable(const PROGRAMMER *pgm, const AVRPART *p, unsigned cha } } -/* TPI: setup NVMCMD register and pointer register (PR) for read/write/erase */ -static int avr_tpi_setup_rw(const PROGRAMMER *pgm, const AVRMEM *mem, - unsigned long addr, unsigned char nvmcmd) { +// TPI: setup NVMCMD register and pointer register (PR) for read/write/erase +static int avr_tpi_setup_rw(const PROGRAMMER *pgm, const AVRMEM *mem, unsigned long addr, unsigned char nvmcmd) { unsigned char cmd[4]; int rc; - /* set NVMCMD register */ + // Set NVMCMD register cmd[0] = TPI_CMD_SOUT | TPI_SIO_ADDR(TPI_IOREG_NVMCMD); cmd[1] = nvmcmd; rc = pgm->cmd_tpi(pgm, cmd, 2, NULL, 0); - if (rc == -1) + if(rc == -1) return -1; - /* set Pointer Register (PR) */ + // Set Pointer Register (PR) cmd[0] = TPI_CMD_SSTPR | 0; cmd[1] = (mem->offset + addr) & 0xFF; rc = pgm->cmd_tpi(pgm, cmd, 2, NULL, 0); - if (rc == -1) + if(rc == -1) return -1; cmd[0] = TPI_CMD_SSTPR | 1; cmd[1] = ((mem->offset + addr) >> 8) & 0xFF; rc = pgm->cmd_tpi(pgm, cmd, 2, NULL, 0); - if (rc == -1) + if(rc == -1) return -1; return 0; @@ -185,8 +183,10 @@ int avr_sigrow_offset(const AVRPART *p, const AVRMEM *mem, int addr) { if(mem_is_in_sigrow(mem)) { AVRMEM *m = avr_locate_sigrow(p); + if(m) { int off = mem->offset - m->offset; + if(off >= 0 && off + addr < m->size) offset = off; } @@ -201,8 +201,10 @@ int avr_flash_offset(const AVRPART *p, const AVRMEM *mem, int addr) { if(mem_is_in_flash(mem)) { AVRMEM *m = avr_locate_flash(p); + if(m) { int off = mem->offset - m->offset; + if(off >= 0 && off + addr < m->size) offset = off; } @@ -212,15 +214,15 @@ int avr_flash_offset(const AVRPART *p, const AVRMEM *mem, int addr) { } int avr_read_byte_default(const PROGRAMMER *pgm, const AVRPART *p, const AVRMEM *mem, - unsigned long addr, unsigned char * value) -{ + unsigned long addr, unsigned char *value) { + unsigned char cmd[4]; unsigned char res[4]; unsigned char data; int rc; - OPCODE * readop, * lext; + OPCODE *readop, *lext; - if (pgm->cmd == NULL) { + if(pgm->cmd == NULL) { pmsg_error("%s programmer uses %s() without providing a cmd() method\n", pgm->type, __func__); return -1; } @@ -228,53 +230,50 @@ int avr_read_byte_default(const PROGRAMMER *pgm, const AVRPART *p, const AVRMEM led_clr(pgm, LED_ERR); led_set(pgm, LED_PGM); - if (p->prog_modes & PM_TPI) { - if (pgm->cmd_tpi == NULL) { + if(is_tpi(p)) { + if(pgm->cmd_tpi == NULL) { pmsg_error("%s programmer does not support TPI\n", pgm->type); goto error; } - while (avr_tpi_poll_nvmbsy(pgm)) + while(avr_tpi_poll_nvmbsy(pgm)) continue; - /* setup for read */ + // Setup for read avr_tpi_setup_rw(pgm, mem, addr, TPI_NVMCMD_NO_OPERATION); - /* load byte */ + // Load byte cmd[0] = TPI_CMD_SLD; rc = pgm->cmd_tpi(pgm, cmd, 1, value, 1); - if (rc == -1) + if(rc == -1) goto error; goto success; } - /* - * figure out what opcode to use - */ - if (mem->op[AVR_OP_READ_LO]) { - if (addr & 0x00000001) + // Figure out what opcode to use + if(mem->op[AVR_OP_READ_LO]) { + if(addr & 0x00000001) readop = mem->op[AVR_OP_READ_HI]; else readop = mem->op[AVR_OP_READ_LO]; - addr = addr / 2; - } - else { + addr = addr/2; + } else { readop = mem->op[AVR_OP_READ]; } - if (readop == NULL) { + if(readop == NULL) { + #if DEBUG pmsg_error("operation not supported on memory %s\n", mem->desc); #endif + goto error; } - /* - * If this device has a "load extended address" command, issue it. - */ + // If this device has a "load extended address" command, issue it lext = mem->op[AVR_OP_LOAD_EXT_ADDR]; - if (lext != NULL) { + if(lext != NULL) { memset(cmd, 0, sizeof(cmd)); avr_set_bits(lext, cmd); @@ -309,33 +308,30 @@ int avr_read_byte_default(const PROGRAMMER *pgm, const AVRPART *p, const AVRMEM return rc; } - /* - * Return the number of "interesting" bytes in a memory buffer, - * "interesting" being defined as up to the last non-0xff data - * value. This is useful for determining where to stop when dealing - * with "flash" memory, since writing 0xff to flash is typically a - * no-op. Always return an even number since flash is word addressed. - * Only apply this optimisation on flash-type memory. + * Return the number of "interesting" bytes in a memory buffer, "interesting" + * being defined as up to the last non-0xff data value. This is useful for + * determining where to stop when dealing with "flash" memory, since writing + * 0xff to flash is typically a no-op. Always return an even number since flash + * is word addressed. Only apply this optimisation on flash-type memory. */ -int avr_mem_hiaddr(const AVRMEM * mem) -{ +int avr_mem_hiaddr(const AVRMEM *mem) { int i, n; if(cx->avr_disableffopt) return mem->size; - /* if the memory is not a flash-type memory do not remove trailing 0xff */ + // If the memory is not a flash-type memory do not remove trailing 0xff if(!mem_is_in_flash(mem)) return mem->size; /* return the highest non-0xff address regardless of how much memory was read */ - for (i = mem->size-1; i >= 0; i--) { - if (mem->buf[i] != 0xff) { - n = i+1; - if (n & 0x01) - return n+1; + for(i = mem->size - 1; i >= 0; i--) { + if(mem->buf[i] != 0xff) { + n = i + 1; + if(n & 0x01) + return n + 1; else return n; } @@ -344,7 +340,6 @@ int avr_mem_hiaddr(const AVRMEM * mem) return 0; } - /* * Read the entirety of the specified memory into the corresponding buffer of * the avrpart pointed to by p. If v is non-NULL, verify against v's memory @@ -354,7 +349,8 @@ int avr_mem_hiaddr(const AVRMEM * mem) */ int avr_read(const PROGRAMMER *pgm, const AVRPART *p, const char *memstr, const AVRPART *v) { AVRMEM *mem = avr_locate_mem(p, memstr); - if (mem == NULL) { + + if(mem == NULL) { pmsg_error("no %s memory for part %s\n", memstr, p->desc); return LIBAVRDUDE_GENERAL_FAILURE; } @@ -368,8 +364,8 @@ int avr_read_mem(const PROGRAMMER *pgm, const AVRPART *p, const AVRMEM *mem, con AVRMEM *vmem = NULL; int rc; - if (v != NULL) - vmem = avr_locate_mem(v, mem->desc); + if(v != NULL) + vmem = avr_locate_mem(v, mem->desc); if(mem->size < 0) // Sanity check return -1; @@ -377,35 +373,30 @@ int avr_read_mem(const PROGRAMMER *pgm, const AVRPART *p, const AVRMEM *mem, con led_clr(pgm, LED_ERR); led_set(pgm, LED_PGM); - /* - * start with all 0xff - */ + // Start with all 0xff memset(mem->buf, 0xff, mem->size); - /* supports "paged load" thru post-increment */ - if ((p->prog_modes & PM_TPI) && mem->page_size > 1 && - mem->size % mem->page_size == 0 && pgm->cmd_tpi != NULL) { + // Supports paged load thru post-increment + if(is_tpi(p) && mem->page_size > 1 && mem->size%mem->page_size == 0 && pgm->cmd_tpi != NULL) { - while (avr_tpi_poll_nvmbsy(pgm)) + while(avr_tpi_poll_nvmbsy(pgm)) continue; - /* setup for read (NOOP) */ + // Setup for read (NOOP) avr_tpi_setup_rw(pgm, mem, 0, TPI_NVMCMD_NO_OPERATION); - /* load bytes */ - for (lastaddr = i = 0; i < (unsigned long) mem->size; i++) { - if (vmem == NULL || - (vmem->tags[i] & TAG_ALLOCATED) != 0) - { - if (lastaddr != i) { - /* need to setup new address */ + // Load bytes + for(lastaddr = i = 0; i < (unsigned long) mem->size; i++) { + if(vmem == NULL || (vmem->tags[i] & TAG_ALLOCATED) != 0) { + if(lastaddr != i) { + // Need to setup new address avr_tpi_setup_rw(pgm, mem, i, TPI_NVMCMD_NO_OPERATION); lastaddr = i; } cmd[0] = TPI_CMD_SLD_PI; rc = pgm->cmd_tpi(pgm, cmd, 1, mem->buf + i, 1); lastaddr++; - if (rc == -1) { + if(rc == -1) { pmsg_error("unable to read address 0x%04lx\n", i); report_progress(1, -1, NULL); led_set(pgm, LED_ERR); @@ -419,85 +410,72 @@ int avr_read_mem(const PROGRAMMER *pgm, const AVRPART *p, const AVRMEM *mem, con led_clr(pgm, LED_PGM); return avr_mem_hiaddr(mem); } - // HW programmers need a page size > 1, bootloader typ only offer paged r/w - if ((pgm->paged_load && mem->page_size > 1 && mem->size % mem->page_size == 0) || - ((pgm->prog_modes & PM_SPM) && avr_has_paged_access(pgm, p, mem))) { - /* - * the programmer supports a paged mode read - */ + if((pgm->paged_load && mem->page_size > 1 && mem->size%mem->page_size == 0) || + (is_spm(pgm) && avr_has_paged_access(pgm, p, mem))) { + // The programmer supports a paged mode read int need_read, failure; unsigned int pageaddr; unsigned int npages, nread; - /* quickly scan number of pages to be written to first */ - for (pageaddr = 0, npages = 0; - pageaddr < (unsigned int) mem->size; - pageaddr += mem->page_size) { - /* check whether this page must be read */ - for (i = pageaddr; - i < pageaddr + mem->page_size; - i++) - if (vmem == NULL /* no verify, read everything */ || - (mem->tags[i] & TAG_ALLOCATED) != 0 /* verify, do only - read pages that - are needed in - input file */) { + // Quickly scan number of pages to be written to first + for(pageaddr = 0, npages = 0; pageaddr < (unsigned int) mem->size; pageaddr += mem->page_size) { + // Check whether this page must be read + for(i = pageaddr; i < pageaddr + mem->page_size; i++) { + // No verify: read everything; verify: only read needed pages in input file + if(vmem == NULL || (mem->tags[i] & TAG_ALLOCATED) != 0) { npages++; break; } + } } - for (pageaddr = 0, failure = 0, nread = 0; - !failure && pageaddr < (unsigned int) mem->size; - pageaddr += mem->page_size) { - /* check whether this page must be read */ - for (i = pageaddr, need_read = 0; - i < pageaddr + mem->page_size; - i++) - if (vmem == NULL /* no verify, read everything */ || - (vmem->tags[i] & TAG_ALLOCATED) != 0 /* verify, do only - read pages that - are needed in - input file */) { + for(pageaddr = 0, failure = 0, nread = 0; + !failure && pageaddr < (unsigned int) mem->size; pageaddr += mem->page_size) { + + // Check whether this page must be read + for(i = pageaddr, need_read = 0; i < pageaddr + mem->page_size; i++) { + // No verify: read everything; verify: only read needed pages in input file + if(vmem == NULL || (vmem->tags[i] & TAG_ALLOCATED) != 0) { need_read = 1; break; } - if (need_read) { - rc = pgm->paged_load(pgm, p, mem, mem->page_size, - pageaddr, mem->page_size); - if (rc < 0) - /* paged load failed, fall back to byte-at-a-time read below */ + } + if(need_read) { + rc = pgm->paged_load(pgm, p, mem, mem->page_size, pageaddr, mem->page_size); + if(rc < 0) + // Paged load failed, fall back to byte-at-a-time read below failure = 1; nread++; report_progress(nread, npages, NULL); } else { - pmsg_debug("%s(): skipping page %u: no interesting data\n", __func__, pageaddr / mem->page_size); + pmsg_debug("%s(): skipping page %u: no interesting data\n", __func__, pageaddr/mem->page_size); } } - if (!failure) { + if(!failure) { led_clr(pgm, LED_PGM); return avr_mem_hiaddr(mem); } - /* else: fall back to byte-at-a-time read, for historical reasons */ + // Else: fall back to byte-at-a-time read, for historical reasons } - if (mem_is_signature(mem)) { - if (pgm->read_sig_bytes) { + if(mem_is_signature(mem)) { + if(pgm->read_sig_bytes) { int rc = pgm->read_sig_bytes(pgm, p, mem); - if (rc < 0 && rc != LIBAVRDUDE_EXIT) + + if(rc < 0 && rc != LIBAVRDUDE_EXIT) led_set(pgm, LED_ERR); led_clr(pgm, LED_PGM); return rc; } } - for (i=0; i < (unsigned long) mem->size; i++) { - if (vmem == NULL || (vmem->tags[i] & TAG_ALLOCATED) != 0) { + for(i = 0; i < (unsigned long) mem->size; i++) { + if(vmem == NULL || (vmem->tags[i] & TAG_ALLOCATED) != 0) { rc = pgm->read_byte(pgm, p, mem, i, mem->buf + i); - if (rc != LIBAVRDUDE_SUCCESS) { + if(rc != LIBAVRDUDE_SUCCESS) { pmsg_error("unable to read byte at address 0x%04lx\n", i); - if (rc == LIBAVRDUDE_GENERAL_FAILURE) { + if(rc == LIBAVRDUDE_GENERAL_FAILURE) { // pmsg_error("read operation not supported for memory %s\n", mem->desc); report_progress(1, -1, NULL); led_set(pgm, LED_ERR); @@ -518,43 +496,34 @@ int avr_read_mem(const PROGRAMMER *pgm, const AVRPART *p, const AVRMEM *mem, con return avr_mem_hiaddr(mem); } - -/* - * write a page data at the specified address - */ -int avr_write_page(const PROGRAMMER *pgm, const AVRPART *p_unused, const AVRMEM *mem, - unsigned long addr) { +// Write a page data at the specified address +int avr_write_page(const PROGRAMMER *pgm, const AVRPART *p_unused, const AVRMEM *mem, unsigned long addr) { unsigned char cmd[4]; unsigned char res[4]; - OPCODE * wp, * lext; + OPCODE *wp, *lext; led_clr(pgm, LED_ERR); led_set(pgm, LED_PGM); - if (pgm->cmd == NULL) { + if(pgm->cmd == NULL) { pmsg_error("%s programmer uses %s() without providing a cmd() method\n", pgm->type, __func__); goto error; } wp = mem->op[AVR_OP_WRITEPAGE]; - if (wp == NULL) { + if(wp == NULL) { pmsg_error("memory %s not configured for page writes\n", mem->desc); goto error; } - /* - * if this memory is word-addressable, adjust the address - * accordingly - */ - if ((mem->op[AVR_OP_LOADPAGE_LO]) || (mem->op[AVR_OP_READ_LO])) - addr = addr / 2; + // If this memory is word-addressable, adjust the address accordingly + if((mem->op[AVR_OP_LOADPAGE_LO]) || (mem->op[AVR_OP_READ_LO])) + addr = addr/2; - /* - * If this device has a "load extended address" command, issue it. - */ + // If this device has a "load extended address" command, issue it lext = mem->op[AVR_OP_LOAD_EXT_ADDR]; - if (lext != NULL) { + if(lext != NULL) { memset(cmd, 0, sizeof(cmd)); avr_set_bits(lext, cmd); @@ -570,7 +539,7 @@ int avr_write_page(const PROGRAMMER *pgm, const AVRPART *p_unused, const AVRMEM goto error; /* - * since we don't know what voltage the target AVR is powered by, be + * Since we don't know what voltage the target AVR is powered by, be * conservative and delay the max amount the spec says to wait */ usleep(mem->max_write_delay); @@ -584,7 +553,6 @@ int avr_write_page(const PROGRAMMER *pgm, const AVRPART *p_unused, const AVRMEM return -1; } - // Return us since first call uint64_t avr_ustimestamp() { struct timeval tv; @@ -615,14 +583,14 @@ double avr_timestamp() { } /* - * Initialize the global context pointer cx. + * Initialize the global context pointer cx * - * This must be called once at program startup (with a NULL argument), - * and at each (re-)initialization of a programmer (with the - * respective programmer as argument). + * This must be called once at program startup with a NULL argument, and at + * each re-initialization of a programmer with the respective programmer as + * argument. */ void init_cx(PROGRAMMER *pgm) { - if (pgm) + if(pgm) pgm->flag = 0; // Clear out remnants of previous session(s) mmt_free(cx); cx = mmt_malloc(sizeof *cx); // Allocate and initialise context structure @@ -633,8 +601,10 @@ int avr_read_byte_silent(const PROGRAMMER *pgm, const AVRPART *p, const AVRMEM * unsigned long addr, unsigned char *datap) { int bakverb = verbose; + verbose = -123; int ret = pgm->read_byte(pgm, p, mem, addr, datap); + verbose = bakverb; return ret; @@ -645,8 +615,10 @@ int avr_bitmask_data(const PROGRAMMER *pgm, const AVRPART *p, const AVRMEM *mem, unsigned long addr, unsigned char data) { int bitmask = avr_mem_bitmask(p, mem, addr); - if(bitmask && bitmask != 0xff) { // Modify data + + if(bitmask && bitmask != 0xff) { // Modify data unsigned char was = mem->initval; + if(mem->initval == -1) // -1 stands for unknown/not set in avrdude.conf if(avr_read_byte_silent(pgm, p, mem, addr, &was) < 0) was = 0xff; @@ -657,8 +629,8 @@ int avr_bitmask_data(const PROGRAMMER *pgm, const AVRPART *p, const AVRMEM *mem, } int avr_write_byte_default(const PROGRAMMER *pgm, const AVRPART *p, const AVRMEM *mem, - unsigned long addr, unsigned char data) -{ + unsigned long addr, unsigned char data) { + unsigned char cmd[4]; unsigned char res[4]; unsigned char r; @@ -668,20 +640,21 @@ int avr_write_byte_default(const PROGRAMMER *pgm, const AVRPART *p, const AVRMEM unsigned long prog_time; unsigned char b; unsigned short caddr; - OPCODE * writeop; + OPCODE *writeop; int rc; - int readok=0; + int readok = 0; led_clr(pgm, LED_ERR); led_set(pgm, LED_PGM); - if (pgm->cmd == NULL) { + if(pgm->cmd == NULL) { pmsg_error("%s programmer uses %s() without providing a cmd() method\n", pgm->type, __func__); goto error; } if(mem_is_readonly(mem)) { unsigned char is; + if(pgm->read_byte(pgm, p, mem, addr, &is) >= 0 && is == data) return 0; @@ -691,113 +664,109 @@ int avr_write_byte_default(const PROGRAMMER *pgm, const AVRPART *p, const AVRMEM data = avr_bitmask_data(pgm, p, mem, addr, data); - if (p->prog_modes & PM_TPI) { - if (pgm->cmd_tpi == NULL) { + if(is_tpi(p)) { + if(pgm->cmd_tpi == NULL) { pmsg_error("%s programmer does not support TPI\n", pgm->type); goto error; } - if (mem_is_flash(mem)) { + if(mem_is_flash(mem)) { pmsg_error("writing a byte to flash is not supported for %s\n", p->desc); goto error; - } else if ((mem->offset + addr) & 1) { + } else if((mem->offset + addr) & 1) { pmsg_error("writing a byte to an odd location is not supported for %s\n", p->desc); goto error; } - while (avr_tpi_poll_nvmbsy(pgm)) + while(avr_tpi_poll_nvmbsy(pgm)) continue; - /* must erase fuse first */ - if (mem_is_a_fuse(mem)) { // TPI parts only have one fuse - /* setup for SECTION_ERASE (high byte) */ + // Must erase fuse first + if(mem_is_a_fuse(mem)) { // TPI parts only have one fuse + // Setup for SECTION_ERASE (high byte) avr_tpi_setup_rw(pgm, mem, addr | 1, TPI_NVMCMD_SECTION_ERASE); - /* write dummy byte */ + // Write dummy byte cmd[0] = TPI_CMD_SST; cmd[1] = 0xFF; if((rc = pgm->cmd_tpi(pgm, cmd, 2, NULL, 0)) < 0) goto error; - while (avr_tpi_poll_nvmbsy(pgm)) + while(avr_tpi_poll_nvmbsy(pgm)) continue; } - /* setup for WORD_WRITE */ + // Setup for WORD_WRITE avr_tpi_setup_rw(pgm, mem, addr, TPI_NVMCMD_WORD_WRITE); cmd[0] = TPI_CMD_SST_PI; cmd[1] = data; if((rc = pgm->cmd_tpi(pgm, cmd, 2, NULL, 0)) < 0) goto error; - /* dummy high byte to start WORD_WRITE */ + // Dummy high byte to start WORD_WRITE cmd[0] = TPI_CMD_SST_PI; cmd[1] = data; if((rc = pgm->cmd_tpi(pgm, cmd, 2, NULL, 0)) < 0) goto error; - while (avr_tpi_poll_nvmbsy(pgm)) + while(avr_tpi_poll_nvmbsy(pgm)) continue; goto success; } - if (!mem->paged && (p->flags & AVRPART_IS_AT90S1200) == 0) { - /* - * check to see if the write is necessary by reading the existing - * value and only write if we are changing the value; we can't - * use this optimization for paged addressing. + if(!mem->paged && (p->flags & AVRPART_IS_AT90S1200) == 0) { + /* + * Check to see if the write is necessary by reading the existing value and + * only write if we are changing the value; we can't use this optimization + * for paged addressing. * - * For mysterious reasons, on the AT90S1200, this read operation - * sometimes causes the high byte of the same word to be - * programmed to the value of the low byte that has just been - * programmed before. Avoid that optimization on this device. + * For mysterious reasons, on the AT90S1200, this read operation sometimes + * causes the high byte of the same word to be programmed to the value of + * the low byte that has just been programmed before. Avoid that + * optimization on this device. */ rc = pgm->read_byte(pgm, p, mem, addr, &b); - if (rc != 0) { - if (rc != -1) { + if(rc != 0) { + if(rc != -1) { rc = -2; goto rcerror; } // Read operation is not support on this memory - } - else { + } else { readok = 1; - if (b == data) + if(b == data) goto success; } } - /* - * determine which memory opcode to use - */ - if (mem->op[AVR_OP_WRITE_LO]) { - if (addr & 0x01) + // Determine which memory opcode to use + if(mem->op[AVR_OP_WRITE_LO]) { + if(addr & 0x01) writeop = mem->op[AVR_OP_WRITE_HI]; else writeop = mem->op[AVR_OP_WRITE_LO]; - caddr = addr / 2; - } - else if (mem->paged && mem->op[AVR_OP_LOADPAGE_LO]) { - if (addr & 0x01) + caddr = addr/2; + } else if(mem->paged && mem->op[AVR_OP_LOADPAGE_LO]) { + if(addr & 0x01) writeop = mem->op[AVR_OP_LOADPAGE_HI]; else writeop = mem->op[AVR_OP_LOADPAGE_LO]; - caddr = addr / 2; - } - else { + caddr = addr/2; + } else { writeop = mem->op[AVR_OP_WRITE]; caddr = addr; } - if (writeop == NULL) { + if(writeop == NULL) { + #if DEBUG pmsg_error("write not supported for memory %s\n", mem->desc); #endif + goto error; } - memset(cmd, 0, sizeof(cmd)); avr_set_bits(writeop, cmd); avr_set_addr(writeop, cmd, caddr); @@ -805,99 +774,88 @@ int avr_write_byte_default(const PROGRAMMER *pgm, const AVRPART *p, const AVRMEM if(pgm->cmd(pgm, cmd, res) < 0) goto error; - if (mem->paged) { + if(mem->paged) { /* - * in paged addressing, single bytes to be written to the memory - * page complete immediately, we only need to delay when we commit - * the whole page via the avr_write_page() routine. + * In paged addressing, single bytes to be written to the memory page + * complete immediately, we only need to delay when we commit the whole + * page via the avr_write_page() routine. */ goto success; } - if (readok == 0) { - /* - * read operation not supported for this memory, just wait - * the max programming time and then return - */ - usleep(mem->max_write_delay); /* maximum write delay */ + if(readok == 0) { + // Read operation not supported for this memory, just wait the max programming time + usleep(mem->max_write_delay); // Maximum write delay goto success; } tries = 0; ready = 0; - while (!ready) { - - if ((data == mem->readback[0]) || - (data == mem->readback[1])) { - /* - * use an extra long delay when we happen to be writing values - * used for polled data read-back. In this case, polling - * doesn't work, and we need to delay the worst case write time - * specified for the chip. + while(!ready) { + + if((data == mem->readback[0]) || (data == mem->readback[1])) { + /* + * Use an extra long delay when we happen to be writing values used for + * polled data read-back. In this case, polling doesn't work, and we + * need to delay the worst case write time specified for the chip. */ usleep(mem->max_write_delay); rc = pgm->read_byte(pgm, p, mem, addr, &r); - if (rc != 0) { + if(rc != 0) { rc = -5; goto rcerror; } - } - else { + } else { start_time = avr_ustimestamp(); do { // Do polling, but timeout after max_write_delay rc = pgm->read_byte(pgm, p, mem, addr, &r); - if (rc != 0) { + if(rc != 0) { rc = -4; goto rcerror; } prog_time = avr_ustimestamp(); - } while (r != data && mem->max_write_delay >= 0 && - prog_time - start_time < (unsigned long) mem->max_write_delay); + } while(r != data && mem->max_write_delay >= 0 && prog_time - start_time < (unsigned long) mem->max_write_delay); } - /* - * At this point we either have a valid readback or the - * max_write_delay is expired. - */ - - if (r == data) { + // At this point we either have a valid readback or the max_write_delay is expired + + if(r == data) { ready = 1; - } - else if (mem->pwroff_after_write) { + } else if(mem->pwroff_after_write) { /* - * The device has been flagged as power-off after write to this - * memory. The reason we don't just blindly follow the - * flag is that the power-off advice may only apply to some - * memory bits but not all. We only actually power-off the - * device if the data read back does not match what we wrote. + * The device has been flagged as power-off after write to this memory. + * The reason we don't just blindly follow the flag is that the power-off + * advice may only apply to some memory bits but not all. We only + * actually power-off the device if the data read back does not match + * what we wrote. */ pmsg_info("this device must be powered off and back on to continue\n"); - if ((pgm->pinno[PPI_AVR_VCC] & PIN_MASK) <= PIN_MAX) { + if((pgm->pinno[PPI_AVR_VCC] & PIN_MASK) <= PIN_MAX) { pmsg_info("attempting to do this now ...\n"); pgm->powerdown(pgm); usleep(250000); rc = pgm->initialize(pgm, p); - if (rc < 0) { + if(rc < 0) { pmsg_error("initialization failed (rc = %d):\n", rc); imsg_error("cannot re-initialize device after programming the %s bits;\n", mem->desc); imsg_error("manually power-down the device and restart %s to continue\n", progname); rc = -3; goto rcerror; } - + pmsg_info("device was successfully re-initialized\n"); goto success; } } tries++; - if (!ready && tries > 5) { + if(!ready && tries > 5) { /* - * we wrote the data, but after waiting for what should have - * been plenty of time, the memory cell still doesn't match what - * we wrote. Indicate a write error. + * We wrote the data, but after waiting for what should have been plenty + * of time, the memory cell still doesn't match what we wrote. Indicate + * a write error. */ rc = -6; goto rcerror; @@ -917,16 +875,13 @@ int avr_write_byte_default(const PROGRAMMER *pgm, const AVRPART *p, const AVRMEM return rc; } - -/* - * write a byte of data at the specified address - */ +// Write a byte of data at the specified address int avr_write_byte(const PROGRAMMER *pgm, const AVRPART *p, const AVRMEM *mem, - unsigned long addr, unsigned char data) -{ + unsigned long addr, unsigned char data) { if(mem_is_readonly(mem)) { unsigned char is; + if(pgm->read_byte(pgm, p, mem, addr, &is) >= 0 && is == data) return 0; @@ -941,18 +896,18 @@ int avr_write_byte(const PROGRAMMER *pgm, const AVRPART *p, const AVRMEM *mem, return pgm->write_byte(pgm, p, mem, addr, data); } - /* - * Write the whole memory region of the specified memory from its buffer of - * the avrpart pointed to by p to the device. Write up to size bytes from - * the buffer. Data is only written if the corresponding tags byte is set. - * Data beyond size bytes are not affected. + * Write the whole memory region of the specified memory from its buffer of the + * avrpart pointed to by p to the device. Write up to size bytes from the + * buffer. Data is only written if the corresponding tags byte is set. Data + * beyond size bytes are not affected. * * Return the number of bytes written, or LIBAVRDUDE_GENERAL_FAILURE on error. */ int avr_write(const PROGRAMMER *pgm, const AVRPART *p, const char *memstr, int size, int auto_erase) { AVRMEM *m = avr_locate_mem(p, memstr); - if (m == NULL) { + + if(m == NULL) { pmsg_error("no %s memory for part %s\n", memstr, p->desc); return LIBAVRDUDE_GENERAL_FAILURE; } @@ -961,18 +916,18 @@ int avr_write(const PROGRAMMER *pgm, const AVRPART *p, const char *memstr, int s } int avr_write_mem(const PROGRAMMER *pgm, const AVRPART *p, const AVRMEM *m, int size, int auto_erase) { - int wsize; - unsigned int i, lastaddr; - unsigned char data; - unsigned char cmd[4]; + int wsize; + unsigned int i, lastaddr; + unsigned char data; + unsigned char cmd[4]; led_clr(pgm, LED_ERR); led_set(pgm, LED_PGM); wsize = m->size; - if (size < wsize) { + if(size < wsize) { wsize = size; - } else if (size > wsize) { + } else if(size > wsize) { pmsg_warning("%d bytes requested, but memory region is only %d bytes;\n", size, wsize); imsg_warning("only %d bytes will actually be written\n", wsize); } @@ -984,11 +939,11 @@ int avr_write_mem(const PROGRAMMER *pgm, const AVRPART *p, const AVRMEM *m, int return wsize; } - if ((p->prog_modes & PM_TPI) && m->page_size > 1 && pgm->cmd_tpi) { - unsigned int chunk; /* number of words for each write command */ - unsigned int j, writeable_chunk; + if(is_tpi(p) && m->page_size > 1 && pgm->cmd_tpi) { + unsigned int chunk; // Number of words for each write command + unsigned int j, writeable_chunk; - if (wsize == 1) { + if(wsize == 1) { // Fuse (configuration) memory: only single byte to write if(avr_write_byte(pgm, p, m, 0, m->buf[0])) { led_set(pgm, LED_ERR); @@ -1000,10 +955,10 @@ int avr_write_mem(const PROGRAMMER *pgm, const AVRPART *p, const AVRMEM *m, int } } - while (avr_tpi_poll_nvmbsy(pgm)) + while(avr_tpi_poll_nvmbsy(pgm)) continue; - /* setup for WORD_WRITE */ + // Setup for WORD_WRITE avr_tpi_setup_rw(pgm, m, 0, TPI_NVMCMD_WORD_WRITE); /* @@ -1011,36 +966,33 @@ int avr_write_mem(const PROGRAMMER *pgm, const AVRPART *p, const AVRMEM *m, int * This is set by the n_word_writes option of the AVRMEM config section. * Ensure that we align our write size to this boundary. */ - if (m->n_word_writes < 0 || m->n_word_writes > 4 || m->n_word_writes == 3) { + if(m->n_word_writes < 0 || m->n_word_writes > 4 || m->n_word_writes == 3) { msg_error("\n"); - pmsg_error("unsupported n_word_writes value of %d for %s memory\n", - m->n_word_writes, m->desc); + pmsg_error("unsupported n_word_writes value of %d for %s memory\n", m->n_word_writes, m->desc); led_set(pgm, LED_ERR); led_clr(pgm, LED_PGM); return LIBAVRDUDE_GENERAL_FAILURE; } - chunk = m->n_word_writes > 0 ? 2*m->n_word_writes : 2; - wsize = (wsize+chunk-1) / chunk * chunk; - - /* write words in chunks, low byte first */ - for (lastaddr = i = 0; i < (unsigned int) wsize; i += chunk) { - /* check that at least one byte in this chunk is allocated */ - for (writeable_chunk = j = 0; !writeable_chunk && j < chunk; j++) { - writeable_chunk = m->tags[i+j] & TAG_ALLOCATED; + chunk = m->n_word_writes > 0? 2*m->n_word_writes: 2; + wsize = (wsize + chunk - 1)/chunk*chunk; + + // Write words in chunks, low byte first + for(lastaddr = i = 0; i < (unsigned int) wsize; i += chunk) { + // Check that at least one byte in this chunk is allocated + for(writeable_chunk = j = 0; !writeable_chunk && j < chunk; j++) { + writeable_chunk = m->tags[i + j] & TAG_ALLOCATED; } - if (writeable_chunk) { - if (lastaddr != i) { - /* need to setup new address */ + if(writeable_chunk) { + if(lastaddr != i) { + // Need to setup new address avr_tpi_setup_rw(pgm, m, i, TPI_NVMCMD_WORD_WRITE); lastaddr = i; } - - // Write each byte of the chunk. Unallocated bytes should read - // as 0xFF, which should no-op. + // Write each byte of the chunk; unallocated bytes should read as 0xFF cmd[0] = TPI_CMD_SST_PI; - for (j = 0; j < chunk; j++) { - cmd[1] = m->buf[i+j]; + for(j = 0; j < chunk; j++) { + cmd[1] = m->buf[i + j]; if(pgm->cmd_tpi(pgm, cmd, 2, NULL, 0) < 0) { report_progress(1, -1, NULL); led_set(pgm, LED_ERR); @@ -1051,7 +1003,7 @@ int avr_write_mem(const PROGRAMMER *pgm, const AVRPART *p, const AVRMEM *m, int lastaddr += chunk; - while (avr_tpi_poll_nvmbsy(pgm)); + while(avr_tpi_poll_nvmbsy(pgm)); } report_progress(i, wsize, NULL); } @@ -1059,13 +1011,11 @@ int avr_write_mem(const PROGRAMMER *pgm, const AVRPART *p, const AVRMEM *m, int led_clr(pgm, LED_PGM); return i; } - // HW programmers need a page size > 1, bootloader typ only offer paged r/w - if ((pgm->paged_load && m->page_size > 1 && m->size % m->page_size == 0) || - ((pgm->prog_modes & PM_SPM) && avr_has_paged_access(pgm, p, m))) { - /* - * the programmer supports a paged mode write - */ + if((pgm->paged_load && m->page_size > 1 && m->size%m->page_size == 0) || + (is_spm(pgm) && avr_has_paged_access(pgm, p, m))) { + + // The programmer supports a paged mode write int need_write, failure, nset; unsigned int pageaddr; unsigned int npages, nwritten; @@ -1089,9 +1039,9 @@ int avr_write_mem(const PROGRAMMER *pgm, const AVRPART *p, const AVRMEM *m, int AVRMEM *cm = avr_dup_mem(m); // Establish and sanity check effective page size - int pgsize = (pgm->prog_modes & PM_SPM) && p->n_page_erase > 0? - p->n_page_erase*cm->page_size: cm->page_size; - if((pgsize & (pgsize-1)) || pgsize < 1) { + int pgsize = is_spm(pgm) && p->n_page_erase > 0? p->n_page_erase*cm->page_size: cm->page_size; + + if((pgsize & (pgsize - 1)) || pgsize < 1) { pmsg_error("effective page size %d implausible\n", pgsize); avr_free_mem(cm); led_set(pgm, LED_ERR); @@ -1102,15 +1052,15 @@ int avr_write_mem(const PROGRAMMER *pgm, const AVRPART *p, const AVRMEM *m, int uint8_t *spc = mmt_malloc(cm->page_size); // Set cwsize as rounded-up wsize - int cwsize = (wsize + pgsize-1)/pgsize*pgsize; + int cwsize = (wsize + pgsize - 1)/pgsize*pgsize; for(pageaddr = 0; pageaddr < (unsigned int) cwsize; pageaddr += pgsize) { for(i = pageaddr, nset = 0; i < pageaddr + pgsize; i++) if(cm->tags[i] & TAG_ALLOCATED) nset++; - if(nset && nset != pgsize) { // Effective page has holes - for(int np=0; np < pgsize/cm->page_size; np++) { // page by page + if(nset && nset != pgsize) { // Effective page has holes + for(int np = 0; np < pgsize/cm->page_size; np++) { // Page by page unsigned int beg = pageaddr + np*cm->page_size; unsigned int end = beg + cm->page_size; @@ -1119,19 +1069,18 @@ int avr_write_mem(const PROGRAMMER *pgm, const AVRPART *p, const AVRMEM *m, int break; if(i >= end) // Memory page has no holes - continue; + continue; // Read flash contents to separate memory spc and fill in holes if(avr_read_page_default(pgm, p, cm, beg, spc) >= 0) { - pmsg_debug("padding %s [0x%04x, 0x%04x]\n", cm->desc, beg, end-1); + pmsg_debug("padding %s [0x%04x, 0x%04x]\n", cm->desc, beg, end - 1); for(i = beg; i < end; i++) if(!(cm->tags[i] & TAG_ALLOCATED)) { cm->tags[i] |= TAG_ALLOCATED; - cm->buf[i] = spc[i-beg]; + cm->buf[i] = spc[i - beg]; } } else { - pmsg_debug("cannot read %s [0x%04x, 0x%04x] to pad page\n", - cm->desc, beg, end-1); + pmsg_debug("cannot read %s [0x%04x, 0x%04x] to pad page\n", cm->desc, beg, end - 1); } } } @@ -1146,45 +1095,43 @@ int avr_write_mem(const PROGRAMMER *pgm, const AVRPART *p, const AVRMEM *m, int } } - for (pageaddr = 0, failure = 0, nwritten = 0; - !failure && pageaddr < (unsigned int) cwsize; - pageaddr += cm->page_size) { + for(pageaddr = 0, failure = 0, nwritten = 0; + !failure && pageaddr < (unsigned int) cwsize; pageaddr += cm->page_size) { // Check whether this page must be written to - for (i = pageaddr, need_write = 0; i < pageaddr + cm->page_size; i++) - if ((cm->tags[i] & TAG_ALLOCATED) != 0) { + for(i = pageaddr, need_write = 0; i < pageaddr + cm->page_size; i++) + if((cm->tags[i] & TAG_ALLOCATED) != 0) { need_write = 1; break; } - if (need_write) { + if(need_write) { int rc = 0; - if (auto_erase && pgm->page_erase) + + if(auto_erase && pgm->page_erase) rc = pgm->page_erase(pgm, p, cm, pageaddr); - if (rc >= 0) + if(rc >= 0) rc = pgm->paged_write(pgm, p, cm, cm->page_size, pageaddr, cm->page_size); - if (rc < 0) - /* paged write failed, fall back to byte-at-a-time write below */ - failure = 1; + if(rc < 0) + failure = 1; // Paged write failed, fall back to byte-at-a-time write below nwritten++; report_progress(nwritten, npages, NULL); } else { - pmsg_debug("%s(): skipping page %u: no interesting data\n", __func__, pageaddr / cm->page_size); + pmsg_debug("%s(): skipping page %u: no interesting data\n", __func__, pageaddr/cm->page_size); } } avr_free_mem(cm); mmt_free(spc); - if (!failure) { + if(!failure) { led_clr(pgm, LED_PGM); return wsize; } - /* else: fall back to byte-at-a-time write, for historical reasons */ + // Else: fall back to byte-at-a-time write, for historical reasons } - // ISP programming from now on; flash will look like NOR-memory - if (pgm->write_setup) + if(pgm->write_setup) pgm->write_setup(pgm, p, m); int page_tainted = 0; @@ -1192,8 +1139,8 @@ int avr_write_mem(const PROGRAMMER *pgm, const AVRPART *p, const AVRMEM *m, int int paged = mem_is_in_flash(m) && m->paged; if(paged) - wsize = (wsize+1)/2*2; // Round up write size for word boundary - for (i = 0; i < (unsigned int) wsize; i++) { + wsize = (wsize + 1)/2*2; // Round up write size for word boundary + for(i = 0; i < (unsigned int) wsize; i++) { data = m->buf[i]; report_progress(i, wsize, NULL); @@ -1208,19 +1155,20 @@ int avr_write_mem(const PROGRAMMER *pgm, const AVRPART *p, const AVRMEM *m, int * the last byte of each tainted page, the write operation must also be * invoked in order to actually write the page buffer to device memory. */ - int do_write = (paged? m->tags[i&~1] | m->tags[i|1]: m->tags[i]) & TAG_ALLOCATED; - if (paged) { + int do_write = (paged? m->tags[i & ~1] | m->tags[i | 1]: m->tags[i]) & TAG_ALLOCATED; + + if(paged) { page_tainted |= do_write; - if ((int) i % m->page_size == m->page_size - 1 || (int) i == wsize - 1) { + if((int) i%m->page_size == m->page_size - 1 || (int) i == wsize - 1) { flush_page = page_tainted; page_tainted = 0; } } - if (!do_write && !flush_page) + if(!do_write && !flush_page) continue; - if (do_write) { + if(do_write) { if(avr_write_byte(pgm, p, m, i, data)) { msg_error(" *** failed\n"); led_set(pgm, LED_ERR); @@ -1228,12 +1176,11 @@ int avr_write_mem(const PROGRAMMER *pgm, const AVRPART *p, const AVRMEM *m, int } } - if (flush_page) { // Time to flush the page with a page write + if(flush_page) { // Time to flush the page with a page write flush_page = 0; if(avr_write_page(pgm, p, m, i)) { - msg_error(" *** failed to write page %d [0x%04x, 0x%04x]\n", - i / m->page_size, i - m->page_size + 1, i); + msg_error(" *** failed to write page %d [0x%04x, 0x%04x]\n", i/m->page_size, i - m->page_size + 1, i); led_set(pgm, LED_ERR); goto error; } @@ -1248,17 +1195,14 @@ int avr_write_mem(const PROGRAMMER *pgm, const AVRPART *p, const AVRMEM *m, int return -1; } - -/* - * read the AVR device's signature bytes - */ +// Read the AVR device's signature bytes int avr_signature(const PROGRAMMER *pgm, const AVRPART *p) { int rc; if(verbose > 1) report_progress(0, 1, "Reading"); rc = avr_read(pgm, p, "signature", 0); - if (rc < LIBAVRDUDE_SUCCESS && rc != LIBAVRDUDE_EXIT) { + if(rc < LIBAVRDUDE_SUCCESS && rc != LIBAVRDUDE_EXIT) { pmsg_error("unable to read signature data for part %s (rc = %d)\n", p->desc, rc); return rc; } @@ -1267,17 +1211,17 @@ int avr_signature(const PROGRAMMER *pgm, const AVRPART *p) { return rc < LIBAVRDUDE_SUCCESS? LIBAVRDUDE_EXIT: LIBAVRDUDE_SUCCESS; } - // Obtain bitmask for byte in memory (classic, TPI, PDI and UPDI parts) int avr_mem_bitmask(const AVRPART *p, const AVRMEM *mem, int addr) { int bitmask = mem->bitmask; // Collective memory fuses will have a different bitmask for each address (ie, fuse) - if(mem_is_fuses(mem) && addr >=0 && addr < 16) { // Get right fuse in fuses memory + if(mem_is_fuses(mem) && addr >= 0 && addr < 16) { // Get right fuse in fuses memory AVRMEM *dfuse = avr_locate_fuse_by_offset(p, addr); + if(dfuse) { bitmask = dfuse->bitmask; - if(dfuse->size == 2 && addr == (int) mem_fuse_offset(dfuse)+1) // High byte of 2-byte fuse + if(dfuse->size == 2 && addr == (int) mem_fuse_offset(dfuse) + 1) // High byte of 2-byte fuse bitmask >>= 8; } } else if(mem_is_a_fuse(mem) && mem->size == 2 && addr == 1) { @@ -1295,29 +1239,27 @@ static uint8_t get_fuse_bitmask(const AVRMEM *m) { uint8_t bitmask_w = 0; int i; - if (!m || m->size > 1) { - // not a fuse, compare bytes directly + if(!m || m->size > 1) // Not a fuse, compare bytes directly return 0xFF; - } - if (m->op[AVR_OP_WRITE] == NULL || - m->op[AVR_OP_READ] == NULL) - // no memory operations provided by configuration, compare directly + // No memory operations provided by configuration, compare directly + if(m->op[AVR_OP_WRITE] == NULL || m->op[AVR_OP_READ] == NULL) return 0xFF; - // For fuses, only compare bytes that are actually written *and* read. - for (i = 0; i < 32; i++) { - if (m->op[AVR_OP_WRITE]->bit[i].type == AVR_CMDBIT_INPUT) + // For fuses, only compare bytes that are actually written *and* read + for(i = 0; i < 32; i++) { + if(m->op[AVR_OP_WRITE]->bit[i].type == AVR_CMDBIT_INPUT) bitmask_w |= (1 << m->op[AVR_OP_WRITE]->bit[i].bitno); - if (m->op[AVR_OP_READ]->bit[i].type == AVR_CMDBIT_OUTPUT) + if(m->op[AVR_OP_READ]->bit[i].type == AVR_CMDBIT_OUTPUT) bitmask_r |= (1 << m->op[AVR_OP_READ]->bit[i].bitno); } return bitmask_r & bitmask_w; } // Unused in AVRDUDE, beware this is only valid for ISP parts -int compare_memory_masked(AVRMEM * m, uint8_t b1, uint8_t b2) { +int compare_memory_masked(AVRMEM *m, uint8_t b1, uint8_t b2) { uint8_t bitmask = get_fuse_bitmask(m); + return (b1 & bitmask) != (b2 & bitmask); } @@ -1348,30 +1290,32 @@ int avr_verify_mem(const PROGRAMMER *pgm, const AVRPART *p, const AVRPART *v, co return -1; } - buf1 = a->buf; - buf2 = b->buf; + buf1 = a->buf; + buf2 = b->buf; vsize = a->size; - if (vsize < size) { + if(vsize < size) { pmsg_warning("requested verification for %d bytes but\n", size); imsg_warning("%s memory region only contains %d bytes;\n", a->desc, vsize); imsg_warning("only %d bytes will be verified\n", vsize); size = vsize; } - int verror = 0, vroerror = 0, maxerrs = verbose >= MSG_DEBUG? size+1: 10; - int ro = mem_is_readonly(a); // Other memories can have known protected zones such as bootloaders - for (i=0; itags[i] & TAG_ALLOCATED) != 0 && buf1[i] != buf2[i]) { - uint8_t bitmask = p->prog_modes & PM_ISP? get_fuse_bitmask(a): avr_mem_bitmask(p, a, i); + int verror = 0, vroerror = 0, maxerrs = verbose >= MSG_DEBUG? size + 1: 10; + int ro = mem_is_readonly(a); // Other memories can have known protected zones such as bootloaders + + for(i = 0; i < size; i++) { + if((b->tags[i] & TAG_ALLOCATED) != 0 && buf1[i] != buf2[i]) { + uint8_t bitmask = is_isp(p)? get_fuse_bitmask(a): avr_mem_bitmask(p, a, i); + if(ro || (pgm->readonly && pgm->readonly(pgm, p, a, i))) { if(quell_progress < 2) { if(vroerror < 10) { if(!(verror + vroerror)) pmsg_warning("%s verification mismatch%s\n", a->desc, mem_is_in_flash(a)? " in r/o areas, expected for vectors and/or bootloader": ""); - imsg_warning(" device 0x%02x != input 0x%02x at addr 0x%04x (read only location: ignored)\n", - buf1[i], buf2[i], i); + imsg_warning(" device 0x%02x != input 0x%02x at addr 0x%04x " + "(read only location: ignored)\n", buf1[i], buf2[i], i); } else if(vroerror == 10) imsg_warning(" suppressing further mismatches in read-only areas\n"); } @@ -1390,7 +1334,7 @@ int avr_verify_mem(const PROGRAMMER *pgm, const AVRPART *p, const AVRPART *v, co return -1; } else { // Mismatch is only in unused bits - if ((buf1[i] | bitmask) != 0xff) { + if((buf1[i] | bitmask) != 0xff) { // Programmer returned unused bits as 0, must be the part/programmer pmsg_debug("ignoring mismatch in unused bits of %s\n", a->desc); imsg_debug("(device 0x%02x != input 0x%02x); to prevent this warning fix\n", buf1[i], buf2[i]); @@ -1408,34 +1352,32 @@ int avr_verify_mem(const PROGRAMMER *pgm, const AVRPART *p, const AVRPART *v, co return verror? -1: size; } - int avr_get_cycle_count(const PROGRAMMER *pgm, const AVRPART *p, int *cycles) { - AVRMEM * a; + AVRMEM *a; unsigned int cycle_count = 0; unsigned char v1; int rc; int i; a = avr_locate_eeprom(p); - if (a == NULL) + if(a == NULL) return -1; - for (i=4; i>0; i--) { - rc = pgm->read_byte(pgm, p, a, a->size-i, &v1); - if (rc < 0) { + for(i = 4; i > 0; i--) { + rc = pgm->read_byte(pgm, p, a, a->size - i, &v1); + if(rc < 0) { pmsg_warning("cannot read memory for cycle count (rc = %d)\n", rc); return -1; } cycle_count = (cycle_count << 8) | v1; } - /* - * If the EEPROM is erased, the cycle count reads 0xffffffff. - * In this case we return a cycle_count of zero. - * So, the calling function don't have to care about whether or not - * the cycle count was initialized. + /* + * If the EEPROM is erased, the cycle count reads 0xffffffff. In this case we + * return a cycle_count of zero. So, the calling function don't have to care + * about whether or not the cycle count was initialized. */ - if (cycle_count == 0xffffffff) { + if(cycle_count == 0xffffffff) { cycle_count = 0; } @@ -1444,23 +1386,22 @@ int avr_get_cycle_count(const PROGRAMMER *pgm, const AVRPART *p, int *cycles) { return 0; } - int avr_put_cycle_count(const PROGRAMMER *pgm, const AVRPART *p, int cycles) { - AVRMEM * a; + AVRMEM *a; unsigned char v1; int rc; int i; a = avr_locate_eeprom(p); - if (a == NULL) + if(a == NULL) return -1; - for (i=1; i<=4; i++) { + for(i = 1; i <= 4; i++) { v1 = cycles & 0xff; cycles = cycles >> 8; - rc = avr_write_byte(pgm, p, a, a->size-i, v1); - if (rc < 0) { + rc = avr_write_byte(pgm, p, a, a->size - i, v1); + if(rc < 0) { pmsg_warning("cannot write memory for cycle count (rc = %d)\n", rc); return -1; } @@ -1469,10 +1410,10 @@ int avr_put_cycle_count(const PROGRAMMER *pgm, const AVRPART *p, int cycles) { return 0; } - // Return temporary string buffer with n bytes from a closed-circuit space char *avr_cc_buffer(size_t n) { size_t avail = sizeof cx->avr_space - AVR_SAFETY_MARGIN; + if(!is_memset(cx->avr_space + avail, 0, AVR_SAFETY_MARGIN)) { pmsg_warning("avr_cc_buffer(n) overran; n chosen too small in previous calls? Change and recompile\n"); memset(cx->avr_space + avail, 0, AVR_SAFETY_MARGIN); @@ -1486,7 +1427,7 @@ char *avr_cc_buffer(size_t n) { } else if(!cx->avr_s) cx->avr_s = cx->avr_space; - cx->avr_s += strlen(cx->avr_s) + 1; // Move behind string from last call + cx->avr_s += strlen(cx->avr_s) + 1; // Move behind string from last call // Rewind if too little space left if((size_t) (cx->avr_s - cx->avr_space) > avail - n) @@ -1497,15 +1438,15 @@ char *avr_cc_buffer(size_t n) { } /* - * Returns a string in closed-circuit space with a list of programming - * modes encoded in pm; variant creates the list in subtly different ways: + * Returns a string in closed-circuit space with a list of programming modes + * encoded in pm; variant creates the list in subtly different ways: * - variants == 0: PM_SPM prints bootloader * - variants == 1: PM_SPM prints SPM * - variants == 2: rather than a comma-separated list it's | PM_... separated * If pm is 0 (no programming modes) returns "0" */ static char *prog_modes_string(int pm, int variant) { - char *type = avr_cc_buffer(256); // Longest returned string has 142 chars + char *type = avr_cc_buffer(256); // Longest returned string has 142 chars const char *spm = variant? "SPM": "bootloader"; const char *sep = variant == 2? " | PM_": ", "; @@ -1554,57 +1495,56 @@ char *dev_prog_modes(int pm) { // Symbolic C code of prog_modes return prog_modes_string(pm, 2); } - // Typical order in which memories show in avrdude.conf, runtime adds unknown ones (if any) Memtable avr_mem_order[100] = { - {"eeprom", MEM_EEPROM}, - {"flash", MEM_FLASH | MEM_IN_FLASH}, + {"eeprom", MEM_EEPROM}, + {"flash", MEM_FLASH | MEM_IN_FLASH}, {"application", MEM_APPLICATION | MEM_IN_FLASH}, - {"apptable", MEM_APPTABLE | MEM_IN_FLASH}, - {"boot", MEM_BOOT | MEM_IN_FLASH}, - {"fuses", MEM_FUSES}, - {"fuse", MEM_FUSE0 | MEM_IS_A_FUSE}, - {"lfuse", MEM_FUSE0 | MEM_IS_A_FUSE}, - {"hfuse", MEM_FUSE1 | MEM_IS_A_FUSE}, - {"efuse", MEM_FUSE2 | MEM_IS_A_FUSE}, - {"fuse0", MEM_FUSE0 | MEM_IS_A_FUSE}, - {"wdtcfg", MEM_FUSE0 | MEM_IS_A_FUSE}, - {"fuse1", MEM_FUSE1 | MEM_IS_A_FUSE}, - {"bodcfg", MEM_FUSE1 | MEM_IS_A_FUSE}, - {"fuse2", MEM_FUSE2 | MEM_IS_A_FUSE}, - {"osccfg", MEM_FUSE2 | MEM_IS_A_FUSE}, - {"fuse4", MEM_FUSE4 | MEM_IS_A_FUSE}, - {"tcd0cfg", MEM_FUSE4 | MEM_IS_A_FUSE}, - {"fuse5", MEM_FUSE5 | MEM_IS_A_FUSE}, - {"syscfg0", MEM_FUSE5 | MEM_IS_A_FUSE}, - {"fuse6", MEM_FUSE6 | MEM_IS_A_FUSE}, - {"syscfg1", MEM_FUSE6 | MEM_IS_A_FUSE}, - {"fuse7", MEM_FUSE7 | MEM_IS_A_FUSE}, - {"append", MEM_FUSE7 | MEM_IS_A_FUSE}, - {"codesize", MEM_FUSE7 | MEM_IS_A_FUSE}, - {"fuse8", MEM_FUSE8 | MEM_IS_A_FUSE}, - {"bootend", MEM_FUSE8 | MEM_IS_A_FUSE}, - {"bootsize", MEM_FUSE8 | MEM_IS_A_FUSE}, - {"fusea", MEM_FUSEA | MEM_IS_A_FUSE}, - {"pdicfg", MEM_FUSEA | MEM_IS_A_FUSE}, - {"lock", MEM_LOCK}, - {"lockbits", MEM_LOCK}, - {"prodsig", MEM_SIGROW | MEM_IN_SIGROW | MEM_READONLY}, - {"sigrow", MEM_SIGROW | MEM_IN_SIGROW | MEM_READONLY}, - {"signature", MEM_SIGNATURE | MEM_IN_SIGROW | MEM_READONLY}, // Not in SIGROW in Classic/XMEGA parts - {"calibration", MEM_CALIBRATION | MEM_IN_SIGROW | MEM_READONLY}, // Not in SIGROW in Classic parts - {"tempsense", MEM_TEMPSENSE | MEM_IN_SIGROW | MEM_READONLY}, - {"sernum", MEM_SERNUM | MEM_IN_SIGROW | MEM_READONLY}, - {"osccal16", MEM_OSCCAL16 | MEM_IN_SIGROW | MEM_READONLY}, - {"osccal20", MEM_OSCCAL20 | MEM_IN_SIGROW | MEM_READONLY}, - {"osc16err", MEM_OSC16ERR | MEM_IN_SIGROW | MEM_READONLY}, - {"osc20err", MEM_OSC20ERR | MEM_IN_SIGROW | MEM_READONLY}, - {"bootrow", MEM_BOOTROW | MEM_USER_TYPE}, - {"usersig", MEM_USERROW | MEM_USER_TYPE}, - {"userrow", MEM_USERROW | MEM_USER_TYPE}, - {"io", MEM_IO}, - {"sram", MEM_SRAM}, - {"sib", MEM_SIB | MEM_READONLY}, + {"apptable", MEM_APPTABLE | MEM_IN_FLASH}, + {"boot", MEM_BOOT | MEM_IN_FLASH}, + {"fuses", MEM_FUSES}, + {"fuse", MEM_FUSE0 | MEM_IS_A_FUSE}, + {"lfuse", MEM_FUSE0 | MEM_IS_A_FUSE}, + {"hfuse", MEM_FUSE1 | MEM_IS_A_FUSE}, + {"efuse", MEM_FUSE2 | MEM_IS_A_FUSE}, + {"fuse0", MEM_FUSE0 | MEM_IS_A_FUSE}, + {"wdtcfg", MEM_FUSE0 | MEM_IS_A_FUSE}, + {"fuse1", MEM_FUSE1 | MEM_IS_A_FUSE}, + {"bodcfg", MEM_FUSE1 | MEM_IS_A_FUSE}, + {"fuse2", MEM_FUSE2 | MEM_IS_A_FUSE}, + {"osccfg", MEM_FUSE2 | MEM_IS_A_FUSE}, + {"fuse4", MEM_FUSE4 | MEM_IS_A_FUSE}, + {"tcd0cfg", MEM_FUSE4 | MEM_IS_A_FUSE}, + {"fuse5", MEM_FUSE5 | MEM_IS_A_FUSE}, + {"syscfg0", MEM_FUSE5 | MEM_IS_A_FUSE}, + {"fuse6", MEM_FUSE6 | MEM_IS_A_FUSE}, + {"syscfg1", MEM_FUSE6 | MEM_IS_A_FUSE}, + {"fuse7", MEM_FUSE7 | MEM_IS_A_FUSE}, + {"append", MEM_FUSE7 | MEM_IS_A_FUSE}, + {"codesize", MEM_FUSE7 | MEM_IS_A_FUSE}, + {"fuse8", MEM_FUSE8 | MEM_IS_A_FUSE}, + {"bootend", MEM_FUSE8 | MEM_IS_A_FUSE}, + {"bootsize", MEM_FUSE8 | MEM_IS_A_FUSE}, + {"fusea", MEM_FUSEA | MEM_IS_A_FUSE}, + {"pdicfg", MEM_FUSEA | MEM_IS_A_FUSE}, + {"lock", MEM_LOCK}, + {"lockbits", MEM_LOCK}, + {"prodsig", MEM_SIGROW | MEM_IN_SIGROW | MEM_READONLY}, + {"sigrow", MEM_SIGROW | MEM_IN_SIGROW | MEM_READONLY}, + {"signature", MEM_SIGNATURE | MEM_IN_SIGROW | MEM_READONLY}, // Not in SIGROW in Classic/XMEGA parts + {"calibration", MEM_CALIBRATION | MEM_IN_SIGROW | MEM_READONLY}, // Not in SIGROW in Classic parts + {"tempsense", MEM_TEMPSENSE | MEM_IN_SIGROW | MEM_READONLY}, + {"sernum", MEM_SERNUM | MEM_IN_SIGROW | MEM_READONLY}, + {"osccal16", MEM_OSCCAL16 | MEM_IN_SIGROW | MEM_READONLY}, + {"osccal20", MEM_OSCCAL20 | MEM_IN_SIGROW | MEM_READONLY}, + {"osc16err", MEM_OSC16ERR | MEM_IN_SIGROW | MEM_READONLY}, + {"osc20err", MEM_OSC20ERR | MEM_IN_SIGROW | MEM_READONLY}, + {"bootrow", MEM_BOOTROW | MEM_USER_TYPE}, + {"usersig", MEM_USERROW | MEM_USER_TYPE}, + {"userrow", MEM_USERROW | MEM_USER_TYPE}, + {"io", MEM_IO}, + {"sram", MEM_SRAM}, + {"sib", MEM_SIB | MEM_READONLY}, }; #include "dryrun.h" @@ -1615,27 +1555,21 @@ Memtable avr_mem_order[100] = { // Whether a memory is an exception that shouldn't be there for this particular i/face int avr_mem_exclude(const PROGRAMMER *pgm, const AVRPART *p, const AVRMEM *m) { - return - is_type(pgm, dryrun)? 0: // Never exclude dryrun memories - + return is_type(pgm, dryrun)? 0: // Never exclude dryrun memories // debugWIRE only allows eeprom/flash/signature (both_debugwire(pgm, p) && !(mem_is_in_flash(m) || mem_is_eeprom(m) || mem_is_signature(m))) || - // urclock type only allows eeprom/flash/signature (both_spm(pgm, p) && is_type(pgm, urclock) && !(mem_is_in_flash(m) || mem_is_eeprom(m) || mem_is_signature(m))) || - // jtag2updi cannot deal with sib (mem_is_sib(m) && is_type(pgm, jtagmkII_updi)) || - // jtag3 JTAG i/fce cannot read beyond addr 6 on classic prodsig, so exclude this (is_type(pgm, jtag3) && mem_is_in_sigrow(m) && is_classic(p) && both_jtag(pgm, p)) || - // Classic part usersig memories cannot be read/written using ISP (mem_is_usersig(m) && is_classic(p) && both_isp(pgm, p)); } int avr_get_mem_type(const char *str) { - for(size_t i=0; i < sizeof avr_mem_order/sizeof *avr_mem_order; i++) { + for(size_t i = 0; i < sizeof avr_mem_order/sizeof *avr_mem_order; i++) { if(avr_mem_order[i].str && str_eq(avr_mem_order[i].str, str)) return avr_mem_order[i].type; if(!avr_mem_order[i].str) { @@ -1667,18 +1601,15 @@ static int mem_group(AVRMEM *mem) { mem_is_in_flash(mem)? 1: mem_is_in_fuses(mem)? 2: mem_is_lock(mem)? 3: - mem_is_in_sigrow(mem)? 4: - mem_is_user_type(mem)? 5: - mem_is_io(mem)? 6: - mem_is_sram(mem)? 7: - mem_is_sib(mem)? 8: 9; + mem_is_in_sigrow(mem)? 4: mem_is_user_type(mem)? 5: mem_is_io(mem)? 6: mem_is_sram(mem)? 7: mem_is_sib(mem)? 8: 9; } // Return sort order of memories int avr_mem_cmp(void *mem1, void *mem2) { AVRMEM *m1 = mem1, *m2 = mem2; - int diff = mem_group(m1) - mem_group(m2); // First sort by group + int diff = mem_group(m1) - mem_group(m2); // First sort by group + if(diff) return diff; if(!m1) // Sanity, if called with NULL pointers @@ -1688,7 +1619,7 @@ int avr_mem_cmp(void *mem1, void *mem2) { if(diff) return diff; } - diff = m1->offset - m2->offset; // Sort by offset within each group + diff = m1->offset - m2->offset; // Sort by offset within each group if(diff) return diff; diff = m2->size - m1->size; // Sic: larger size is listed first, eg, fuses before fuse0 @@ -1697,10 +1628,9 @@ int avr_mem_cmp(void *mem1, void *mem2) { return strcmp(m1->desc, m2->desc); } - int avr_mem_is_known(const char *str) { if(str && *str) - for(size_t i=0; i < sizeof avr_mem_order/sizeof *avr_mem_order; i++) + for(size_t i = 0; i < sizeof avr_mem_order/sizeof *avr_mem_order; i++) if(avr_mem_order[i].str && str_eq(avr_mem_order[i].str, str)) return 1; return 0; @@ -1708,13 +1638,12 @@ int avr_mem_is_known(const char *str) { int avr_mem_might_be_known(const char *str) { if(str && *str) - for(size_t i=0; i < sizeof avr_mem_order/sizeof *avr_mem_order; i++) + for(size_t i = 0; i < sizeof avr_mem_order/sizeof *avr_mem_order; i++) if(avr_mem_order[i].str && str_starts(avr_mem_order[i].str, str)) return 1; return 0; } - int avr_chip_erase(const PROGRAMMER *pgm, const AVRPART *p) { return led_chip_erase(pgm, p); } @@ -1722,7 +1651,7 @@ int avr_chip_erase(const PROGRAMMER *pgm, const AVRPART *p) { int avr_unlock(const PROGRAMMER *pgm, const AVRPART *p) { int rc = -1; - if (pgm->unlock) + if(pgm->unlock) rc = pgm->unlock(pgm, p); return rc; @@ -1819,13 +1748,12 @@ void report_progress(int completed, int total, const char *hdr) { int percent; double t; - if (update_progress == NULL) + if(update_progress == NULL) return; percent = completed >= total || total <= 0? 100: - completed < 0? 0: - completed < INT_MAX/100? 100*completed/total: completed/(total/100); + completed < 0? 0: completed < INT_MAX/100? 100*completed/total: completed/(total/100); t = avr_timestamp(); @@ -1838,12 +1766,12 @@ void report_progress(int completed, int total, const char *hdr) { } } - // Output comms buffer void trace_buffer(const char *funstr, const unsigned char *buf, size_t buflen) { pmsg_trace("%s: ", funstr); while(buflen--) { unsigned char c = *buf++; + msg_trace("%c [%02x]%s", isascii(c) && isprint(c)? c: '.', c, buflen? " ": ""); } msg_trace("\n"); diff --git a/src/avr910.c b/src/avr910.c index ae5c94845..a7a19ed27 100644 --- a/src/avr910.c +++ b/src/avr910.c @@ -38,11 +38,7 @@ #include "avr910.h" -/* - * Private data for this programmer. - */ -struct pdata -{ +struct pdata { char has_auto_incr_addr; unsigned char devcode; unsigned int buffersize; @@ -54,7 +50,7 @@ struct pdata unsigned long caddr; }; -#define PDATA(pgm) ((struct pdata *)(pgm->cookie)) +#define my (*(struct pdata *) (pgm->cookie)) // Print error and return when command failed #define EI(x) do { \ @@ -73,38 +69,33 @@ struct pdata } \ } while(0) - -static void avr910_setup(PROGRAMMER * pgm) { +static void avr910_setup(PROGRAMMER *pgm) { pgm->cookie = mmt_malloc(sizeof(struct pdata)); - PDATA(pgm)->test_blockmode = 1; + my.test_blockmode = 1; } -static void avr910_teardown(PROGRAMMER * pgm) { +static void avr910_teardown(PROGRAMMER *pgm) { mmt_free(pgm->cookie); pgm->cookie = NULL; } - static int avr910_send(const PROGRAMMER *pgm, char *buf, size_t len) { - return serial_send(&pgm->fd, (unsigned char *)buf, len); + return serial_send(&pgm->fd, (unsigned char *) buf, len); } - static int avr910_recv(const PROGRAMMER *pgm, char *buf, size_t len) { return serial_recv(&pgm->fd, (unsigned char *) buf, len); } - static int avr910_drain(const PROGRAMMER *pgm, int display) { return serial_drain(&pgm->fd, display); } - static int avr910_vfy_cmd_sent(const PROGRAMMER *pgm, char *errmsg) { char c; EI(avr910_recv(pgm, &c, 1)); - if (c != '\r') { + if(c != '\r') { pmsg_error("protocol error for command: %s\n", errmsg); return -1; } @@ -112,44 +103,33 @@ static int avr910_vfy_cmd_sent(const PROGRAMMER *pgm, char *errmsg) { return 0; } - -/* - * issue the 'chip erase' command to the AVR device - */ +// Issue the 'chip erase' command to the AVR device static int avr910_chip_erase(const PROGRAMMER *pgm, const AVRPART *p) { EI(avr910_send(pgm, "e", 1)); - if (avr910_vfy_cmd_sent(pgm, "chip erase") < 0) + if(avr910_vfy_cmd_sent(pgm, "chip erase") < 0) return -1; - /* - * avr910 firmware may not delay long enough - */ - usleep (p->chip_erase_delay); + // Avr910 firmware may not delay long enough + usleep(p->chip_erase_delay); return 0; } - static int avr910_enter_prog_mode(const PROGRAMMER *pgm) { EI(avr910_send(pgm, "P", 1)); return avr910_vfy_cmd_sent(pgm, "enter prog mode"); } - static int avr910_leave_prog_mode(const PROGRAMMER *pgm) { EI(avr910_send(pgm, "L", 1)); return avr910_vfy_cmd_sent(pgm, "leave prog mode"); } - static int avr910_program_enable(const PROGRAMMER *pgm, const AVRPART *p) { return avr910_enter_prog_mode(pgm); } - -/* - * initialize the AVR device and prepare it to accept commands - */ +// Initialize the AVR device and prepare it to accept commands static int avr910_initialize(const PROGRAMMER *pgm, const AVRPART *p) { char id[8]; char sw[2]; @@ -157,16 +137,15 @@ static int avr910_initialize(const PROGRAMMER *pgm, const AVRPART *p) { char buf[10]; char type; char c; - AVRPART * part; + AVRPART *part; - /* Get the programmer identifier. Programmer returns exactly 7 chars - _without_ the null.*/ + // Get the programmer identifier; Programmer returns exactly 7 chars without nul EI(avr910_send(pgm, "S", 1)); - memset (id, 0, sizeof(id)); - EI(avr910_recv(pgm, id, sizeof(id)-1)); + memset(id, 0, sizeof(id)); + EI(avr910_recv(pgm, id, sizeof(id) - 1)); - /* Get the HW and SW versions to see if the programmer is present. */ + // Get the HW and SW versions to see if the programmer is present EI(avr910_send(pgm, "V", 1)); EI(avr910_recv(pgm, sw, sizeof(sw))); @@ -174,7 +153,7 @@ static int avr910_initialize(const PROGRAMMER *pgm, const AVRPART *p) { EI(avr910_send(pgm, "v", 1)); EI(avr910_recv(pgm, hw, sizeof(hw))); - /* Get the programmer type (serial or parallel). Expect serial. */ + // Get the programmer type (serial or parallel); expect serial EI(avr910_send(pgm, "p", 1)); EI(avr910_recv(pgm, &type, 1)); @@ -183,79 +162,76 @@ static int avr910_initialize(const PROGRAMMER *pgm, const AVRPART *p) { msg_notice("Software version = %c.%c; ", sw[0], sw[1]); msg_notice("Hardware version = %c.%c\n", hw[0], hw[1]); - /* See if programmer supports autoincrement of address. */ + // See if programmer supports autoincrement of address EI(avr910_send(pgm, "a", 1)); - EI(avr910_recv(pgm, &PDATA(pgm)->has_auto_incr_addr, 1)); - if (PDATA(pgm)->has_auto_incr_addr == 'Y') - msg_notice("programmer supports auto addr increment\n"); + EI(avr910_recv(pgm, &my.has_auto_incr_addr, 1)); + if(my.has_auto_incr_addr == 'Y') + msg_notice("programmer supports auto addr increment\n"); - /* Check support for buffered memory access, ignore if not available */ + // Check support for buffered memory access, ignore if not available - if (PDATA(pgm)->test_blockmode == 1) { + if(my.test_blockmode == 1) { EI(avr910_send(pgm, "b", 1)); EI(avr910_recv(pgm, &c, 1)); - if (c == 'Y') { + if(c == 'Y') { EI(avr910_recv(pgm, &c, 1)); - PDATA(pgm)->buffersize = (unsigned int)(unsigned char)c<<8; + my.buffersize = (unsigned int) (unsigned char) c << 8; EI(avr910_recv(pgm, &c, 1)); - PDATA(pgm)->buffersize += (unsigned int)(unsigned char)c; - msg_notice("programmer supports buffered memory access with " - "buffersize = %u bytes\n", - PDATA(pgm)->buffersize); - PDATA(pgm)->use_blockmode = 1; + my.buffersize += (unsigned int) (unsigned char) c; + msg_notice("programmer supports buffered memory access with " "buffersize = %u bytes\n", my.buffersize); + my.use_blockmode = 1; } else { - PDATA(pgm)->use_blockmode = 0; + my.use_blockmode = 0; } } else { - PDATA(pgm)->use_blockmode = 0; + my.use_blockmode = 0; } - if (PDATA(pgm)->devcode == 0) { + if(my.devcode == 0) { char devtype_1st; int dev_supported = 0; - /* Get list of devices that the programmer supports. */ + // Get list of devices that the programmer supports EI(avr910_send(pgm, "t", 1)); msg_notice2("\nProgrammer supports the following devices:\n"); devtype_1st = 0; while(1) { EI(avr910_recv(pgm, &c, 1)); - if (devtype_1st == 0) - devtype_1st = c; - if (c == 0) - break; + if(devtype_1st == 0) + devtype_1st = c; + if(c == 0) + break; part = locate_part_by_avr910_devcode(part_list, c); msg_notice2(" Device code: 0x%02x = %s\n", c & 0xff, part? part->desc: "(unknown)"); - /* FIXME: Need to lookup devcode and report the device. */ + // Fixme: Need to lookup devcode and report the device - if (p->avr910_devcode == c) - dev_supported = 1; + if(p->avr910_devcode == c) + dev_supported = 1; }; msg_notice2("\n"); - if (!dev_supported) { + if(!dev_supported) { if(ovsigck) pmsg_warning("selected device %s is not supported by programmer %s\n", p->desc, pgmid); else { pmsg_error("selected device %s is not supported by programmer %s\n", p->desc, pgmid); - return -1; + return -1; } } - /* If the user forced the selection, use the first device - type that is supported by the programmer. */ + // If the user forced the selection, use the first device type that is supported by the programmer buf[1] = ovsigck? devtype_1st: p->avr910_devcode; } else { - /* devcode overridden by -x devcode= option */ - buf[1] = (char)(PDATA(pgm)->devcode); + // Devcode overridden by -x devcode= option + buf[1] = (char) (my.devcode); } - /* Tell the programmer which part we selected. */ + // Tell the programmer which part we selected buf[0] = 'T'; - /* buf[1] has been set up above */ + // buf[1] has been set up above EI(avr910_send(pgm, buf, 2)); if(avr910_vfy_cmd_sent(pgm, "select device") < 0) @@ -266,28 +242,23 @@ static int avr910_initialize(const PROGRAMMER *pgm, const AVRPART *p) { return pgm->program_enable(pgm, p); } - static void avr910_disable(const PROGRAMMER *pgm) { avr910_leave_prog_mode(pgm); } - static void avr910_enable(PROGRAMMER *pgm, const AVRPART *p) { } - /* - * transmit an AVR device command and return the results; 'cmd' and + * Transmit an AVR device command and return the results; 'cmd' and * 'res' must point to at least a 4 byte data buffer */ -static int avr910_cmd(const PROGRAMMER *pgm, const unsigned char *cmd, - unsigned char *res) -{ +static int avr910_cmd(const PROGRAMMER *pgm, const unsigned char *cmd, unsigned char *res) { char buf[5]; - /* FIXME: Insert version check here */ + // FIXME: Insert version check here - buf[0] = '.'; /* New Universal Command */ + buf[0] = '.'; // New Universal Command buf[1] = cmd[0]; buf[2] = cmd[1]; buf[3] = cmd[2]; @@ -296,7 +267,7 @@ static int avr910_cmd(const PROGRAMMER *pgm, const unsigned char *cmd, EI(avr910_send(pgm, buf, 5)); EI(avr910_recv(pgm, buf, 2)); - res[0] = 0x00; /* Dummy value */ + res[0] = 0x00; // Dummy value res[1] = cmd[0]; res[2] = cmd[1]; res[3] = buf[0]; @@ -304,39 +275,38 @@ static int avr910_cmd(const PROGRAMMER *pgm, const unsigned char *cmd, return 0; } - static int avr910_parseextparms(const PROGRAMMER *pgm, const LISTID extparms) { int rv = 0; bool help = false; - for (LNODEID ln = lfirst(extparms); ln; ln = lnext(ln)) { + for(LNODEID ln = lfirst(extparms); ln; ln = lnext(ln)) { const char *extended_param = ldata(ln); - if (str_starts(extended_param, "devcode=")) { + if(str_starts(extended_param, "devcode=")) { int devcode; - if (sscanf(extended_param, "devcode=%i", &devcode) != 1 || - devcode <= 0 || devcode > 255) { + + if(sscanf(extended_param, "devcode=%i", &devcode) != 1 || devcode <= 0 || devcode > 255) { pmsg_error("invalid device code in -x %s\n", extended_param); rv = -1; break; } pmsg_notice2("%s(): devcode overwritten as 0x%02x\n", __func__, devcode); - PDATA(pgm)->devcode = devcode; + my.devcode = devcode; continue; } - if (str_eq(extended_param, "no_blockmode")) { + if(str_eq(extended_param, "no_blockmode")) { pmsg_notice2("avr910_parseextparms(-x): no testing for Blockmode\n"); - PDATA(pgm)->test_blockmode = 0; + my.test_blockmode = 0; continue; } - if (str_eq(extended_param, "help")) { + if(str_eq(extended_param, "help")) { help = true; rv = LIBAVRDUDE_EXIT; } - if (!help) { + if(!help) { pmsg_error("invalid extended parameter -x %s\n", extended_param); rv = -1; } @@ -350,7 +320,6 @@ static int avr910_parseextparms(const PROGRAMMER *pgm, const LISTID extparms) { return rv; } - static int avr910_open(PROGRAMMER *pgm, const char *port) { union pinfo pinfo; @@ -363,8 +332,8 @@ static int avr910_open(PROGRAMMER *pgm, const char *port) { if(serial_open(port, pinfo, &pgm->fd) < 0) return -1; - (void) avr910_drain (pgm, 0); - + (void) avr910_drain(pgm, 0); + return 0; } @@ -373,39 +342,36 @@ static void avr910_close(PROGRAMMER *pgm) { pgm->fd.ifd = -1; } - static void avr910_display(const PROGRAMMER *pgm, const char *p) { return; } - static void avr910_set_addr(const PROGRAMMER *pgm, unsigned long addr) { char cmd[3]; cmd[0] = 'A'; cmd[1] = (addr >> 8) & 0xff; cmd[2] = addr & 0xff; - + EV(avr910_send(pgm, cmd, sizeof(cmd))); avr910_vfy_cmd_sent(pgm, "set addr"); } - static int avr910_write_byte(const PROGRAMMER *pgm, const AVRPART *p, const AVRMEM *m, - unsigned long addr, unsigned char value) -{ + unsigned long addr, unsigned char value) { + char cmd[2]; - if (mem_is_flash(m)) { - if (addr & 0x01) { - cmd[0] = 'C'; // Write program mem high byte + if(mem_is_flash(m)) { + if(addr & 0x01) { + cmd[0] = 'C'; // Write program mem high byte } else { cmd[0] = 'c'; } addr >>= 1; - PDATA(pgm)->ctype = 0; // Invalidate read cache - } else if (mem_is_eeprom(m)) { + my.ctype = 0; // Invalidate read cache + } else if(mem_is_eeprom(m)) { cmd[0] = 'D'; } else { return avr_write_byte_default(pgm, p, m, addr, value); @@ -419,14 +385,12 @@ static int avr910_write_byte(const PROGRAMMER *pgm, const AVRPART *p, const AVRM return avr910_vfy_cmd_sent(pgm, "write byte"); } - static int avr910_read_byte_flash(const PROGRAMMER *pgm, const AVRPART *p, const AVRMEM *m, - unsigned long addr, unsigned char * value) -{ + unsigned long addr, unsigned char *value) { char buf[2]; - if(PDATA(pgm)->ctype == 'F' && PDATA(pgm)->caddr == addr) { - *value = PDATA(pgm)->cvalue; + if(my.ctype == 'F' && my.caddr == addr) { + *value = my.cvalue; return 0; } @@ -436,17 +400,15 @@ static int avr910_read_byte_flash(const PROGRAMMER *pgm, const AVRPART *p, const EI(avr910_recv(pgm, buf, sizeof(buf))); *value = buf[(addr & 1) ^ 1]; // MSB in buffer first - PDATA(pgm)->ctype = 'F'; - PDATA(pgm)->cvalue = buf[addr & 1]; - PDATA(pgm)->caddr = addr ^ 1; + my.ctype = 'F'; + my.cvalue = buf[addr & 1]; + my.caddr = addr ^ 1; return 0; } - static int avr910_read_byte_eeprom(const PROGRAMMER *pgm, const AVRPART *p, const AVRMEM *m, - unsigned long addr, unsigned char * value) -{ + unsigned long addr, unsigned char *value) { avr910_set_addr(pgm, addr); EI(avr910_send(pgm, "d", 1)); EI(avr910_recv(pgm, (char *) value, 1)); @@ -454,39 +416,35 @@ static int avr910_read_byte_eeprom(const PROGRAMMER *pgm, const AVRPART *p, cons return 0; } - static int avr910_read_byte(const PROGRAMMER *pgm, const AVRPART *p, const AVRMEM *m, - unsigned long addr, unsigned char * value) -{ - if (mem_is_flash(m)) { + unsigned long addr, unsigned char *value) { + + if(mem_is_flash(m)) { return avr910_read_byte_flash(pgm, p, m, addr, value); } - if (mem_is_eeprom(m)) { + if(mem_is_eeprom(m)) { return avr910_read_byte_eeprom(pgm, p, m, addr, value); } return avr_read_byte_default(pgm, p, m, addr, value); } - static int avr910_paged_write_flash(const PROGRAMMER *pgm, const AVRPART *p, const AVRMEM *m, - unsigned int page_size, - unsigned int addr, unsigned int n_bytes) -{ - unsigned char cmd[] = {'c', 'C'}; + unsigned int page_size, unsigned int addr, unsigned int n_bytes) { + unsigned char cmd[] = { 'c', 'C' }; char buf[2]; unsigned int max_addr = addr + n_bytes; unsigned int page_addr; int page_bytes = page_size; int page_wr_cmd_pending = 0; - PDATA(pgm)->ctype = 0; // Invalidate read cache + my.ctype = 0; // Invalidate read cache page_addr = addr; - avr910_set_addr(pgm, addr>>1); + avr910_set_addr(pgm, addr >> 1); - while (addr < max_addr) { + while(addr < max_addr) { page_wr_cmd_pending = 1; buf[0] = cmd[addr & 0x01]; buf[1] = m->buf[addr]; @@ -497,33 +455,30 @@ static int avr910_paged_write_flash(const PROGRAMMER *pgm, const AVRPART *p, con addr++; page_bytes--; - if (m->paged && (page_bytes == 0)) { - /* Send the "Issue Page Write" if we have sent a whole page. */ + if(m->paged && (page_bytes == 0)) { + // Send the "Issue Page Write" if we have sent a whole page - avr910_set_addr(pgm, page_addr>>1); + avr910_set_addr(pgm, page_addr >> 1); EI(avr910_send(pgm, "m", 1)); if(avr910_vfy_cmd_sent(pgm, "flush page") < 0) return -1; page_wr_cmd_pending = 0; usleep(m->max_write_delay); - avr910_set_addr(pgm, addr>>1); + avr910_set_addr(pgm, addr >> 1); - /* Set page address for next page. */ + // Set page address for next page page_addr = addr; page_bytes = page_size; - } - else if ((PDATA(pgm)->has_auto_incr_addr != 'Y') && ((addr & 0x01) == 0)) { - avr910_set_addr(pgm, addr>>1); + } else if((my.has_auto_incr_addr != 'Y') && ((addr & 0x01) == 0)) { + avr910_set_addr(pgm, addr >> 1); } } - /* If we didn't send the page wr cmd after the last byte written in the - loop, send it now. */ - - if (page_wr_cmd_pending) { - avr910_set_addr(pgm, page_addr>>1); + // If we didn't send the page wr cmd after the last byte written in the loop, send it now + if(page_wr_cmd_pending) { + avr910_set_addr(pgm, page_addr >> 1); EI(avr910_send(pgm, "m", 1)); if(avr910_vfy_cmd_sent(pgm, "flush final page") < 0) return -1; @@ -533,12 +488,8 @@ static int avr910_paged_write_flash(const PROGRAMMER *pgm, const AVRPART *p, con return n_bytes; } - static int avr910_paged_write_eeprom(const PROGRAMMER *pgm, const AVRPART *p, - const AVRMEM * m, - unsigned int page_size, - unsigned int addr, unsigned int n_bytes) -{ + const AVRMEM *m, unsigned int page_size, unsigned int addr, unsigned int n_bytes) { char cmd[2]; unsigned int max_addr = addr + n_bytes; @@ -546,7 +497,7 @@ static int avr910_paged_write_eeprom(const PROGRAMMER *pgm, const AVRPART *p, cmd[0] = 'D'; - while (addr < max_addr) { + while(addr < max_addr) { cmd[1] = m->buf[addr]; EI(avr910_send(pgm, cmd, sizeof(cmd))); if(avr910_vfy_cmd_sent(pgm, "write byte") < 0) @@ -555,21 +506,18 @@ static int avr910_paged_write_eeprom(const PROGRAMMER *pgm, const AVRPART *p, addr++; - if (PDATA(pgm)->has_auto_incr_addr != 'Y') + if(my.has_auto_incr_addr != 'Y') avr910_set_addr(pgm, addr); } return n_bytes; } - static int avr910_paged_write(const PROGRAMMER *pgm, const AVRPART *p, const AVRMEM *m, - unsigned int page_size, - unsigned int addr, unsigned int n_bytes) -{ + unsigned int page_size, unsigned int addr, unsigned int n_bytes) { int isee = mem_is_eeprom(m); - if (PDATA(pgm)->use_blockmode == 0) { + if(my.use_blockmode == 0) { if(mem_is_flash(m)) return avr910_paged_write_flash(pgm, p, m, page_size, addr, n_bytes); if(isee) @@ -577,10 +525,10 @@ static int avr910_paged_write(const PROGRAMMER *pgm, const AVRPART *p, const AVR return -2; } - if (PDATA(pgm)->use_blockmode == 1) { + if(my.use_blockmode == 1) { unsigned int max_addr = addr + n_bytes; char *cmd; - unsigned int blocksize = PDATA(pgm)->buffersize; + unsigned int blocksize = my.buffersize; if(!mem_is_flash(m) && !isee) return -2; @@ -588,25 +536,24 @@ static int avr910_paged_write(const PROGRAMMER *pgm, const AVRPART *p, const AVR if(isee) blocksize = 1; // Write single bytes only to EEPROM else - PDATA(pgm)->ctype = 0; // Invalidate read cache + my.ctype = 0; // Invalidate read cache - avr910_set_addr(pgm, isee? addr: addr>>1); + avr910_set_addr(pgm, isee? addr: addr >> 1); cmd = mmt_malloc(4 + blocksize); cmd[0] = 'B'; cmd[3] = isee? 'E': 'F'; - while (addr < max_addr) { - if ((max_addr - addr) < blocksize) + while(addr < max_addr) { + if((max_addr - addr) < blocksize) blocksize = max_addr - addr; memcpy(&cmd[4], &m->buf[addr], blocksize); cmd[1] = (blocksize >> 8) & 0xff; cmd[2] = blocksize & 0xff; - if(avr910_send(pgm, cmd, 4 + blocksize) < 0 || - avr910_vfy_cmd_sent(pgm, "write block") < 0) { + if(avr910_send(pgm, cmd, 4 + blocksize) < 0 || avr910_vfy_cmd_sent(pgm, "write block") < 0) { mmt_free(cmd); return -1; } @@ -619,11 +566,8 @@ static int avr910_paged_write(const PROGRAMMER *pgm, const AVRPART *p, const AVR return n_bytes; } - static int avr910_paged_load(const PROGRAMMER *pgm, const AVRPART *p, const AVRMEM *m, - unsigned int page_size, - unsigned int addr, unsigned int n_bytes) -{ + unsigned int page_size, unsigned int addr, unsigned int n_bytes) { char cmd[4]; unsigned int max_addr; char buf[2]; @@ -638,17 +582,17 @@ static int avr910_paged_load(const PROGRAMMER *pgm, const AVRPART *p, const AVRM else return -2; - avr910_set_addr(pgm, isee? addr: addr>>1); + avr910_set_addr(pgm, isee? addr: addr >> 1); - if (PDATA(pgm)->use_blockmode) { - /* use buffered mode */ - int blocksize = PDATA(pgm)->buffersize; + if(my.use_blockmode) { + // Use buffered mode + int blocksize = my.buffersize; cmd[0] = 'g'; cmd[3] = isee? 'E': 'F'; - while (addr < max_addr) { - if (max_addr - addr < (unsigned int) blocksize) + while(addr < max_addr) { + if(max_addr - addr < (unsigned int) blocksize) blocksize = max_addr - addr; cmd[1] = (blocksize >> 8) & 0xff; @@ -660,39 +604,39 @@ static int avr910_paged_load(const PROGRAMMER *pgm, const AVRPART *p, const AVRM addr += blocksize; } } else { - while (addr < max_addr) { + while(addr < max_addr) { EI(avr910_send(pgm, cmd, 1)); if(!isee) { // The 'R' command returns two bytes, MSB first, ie, reverse data EI(avr910_recv(pgm, buf, 2)); - m->buf[addr] = buf[1]; // LSB - m->buf[addr+1] = buf[0]; // MSB + m->buf[addr] = buf[1]; // LSB + m->buf[addr + 1] = buf[0]; // MSB } else EI(avr910_recv(pgm, (char *) &m->buf[addr], 1)); addr += isee? 1: 2; - if (PDATA(pgm)->has_auto_incr_addr != 'Y') - avr910_set_addr(pgm, isee? addr: addr>>1); + if(my.has_auto_incr_addr != 'Y') + avr910_set_addr(pgm, isee? addr: addr >> 1); } } return n_bytes; } -/* Signature byte reads are always 3 bytes. */ +// Signature byte reads are always 3 bytes static int avr910_read_sig_bytes(const PROGRAMMER *pgm, const AVRPART *p, const AVRMEM *m) { unsigned char tmp; - if (m->size < 3) { + if(m->size < 3) { pmsg_error("memsize too small for sig byte read"); return -1; } EI(avr910_send(pgm, "s", 1)); EI(avr910_recv(pgm, (char *) m->buf, 3)); - /* Returned signature has wrong order. */ + // Returned signature has wrong order tmp = m->buf[2]; m->buf[2] = m->buf[0]; m->buf[0] = tmp; @@ -705,22 +649,18 @@ const char avr910_desc[] = "Serial programmers using protocol described in appli void avr910_initpgm(PROGRAMMER *pgm) { strcpy(pgm->type, "avr910"); - /* - * mandatory functions - */ - pgm->initialize = avr910_initialize; - pgm->display = avr910_display; - pgm->enable = avr910_enable; - pgm->disable = avr910_disable; + // Mandatory functions + pgm->initialize = avr910_initialize; + pgm->display = avr910_display; + pgm->enable = avr910_enable; + pgm->disable = avr910_disable; pgm->program_enable = avr910_program_enable; - pgm->chip_erase = avr910_chip_erase; - pgm->cmd = avr910_cmd; - pgm->open = avr910_open; - pgm->close = avr910_close; + pgm->chip_erase = avr910_chip_erase; + pgm->cmd = avr910_cmd; + pgm->open = avr910_open; + pgm->close = avr910_close; - /* - * optional functions - */ + // Optional functions pgm->write_byte = avr910_write_byte; pgm->read_byte = avr910_read_byte; @@ -731,6 +671,6 @@ void avr910_initpgm(PROGRAMMER *pgm) { pgm->read_sig_bytes = avr910_read_sig_bytes; pgm->parseextparams = avr910_parseextparms; - pgm->setup = avr910_setup; - pgm->teardown = avr910_teardown; + pgm->setup = avr910_setup; + pgm->teardown = avr910_teardown; } diff --git a/src/avr910.h b/src/avr910.h index 4a32d218c..9be9c8a4b 100644 --- a/src/avr910.h +++ b/src/avr910.h @@ -23,11 +23,11 @@ extern "C" { #endif -extern const char avr910_desc[]; -void avr910_initpgm(PROGRAMMER *pgm); + extern const char avr910_desc[]; + void avr910_initpgm(PROGRAMMER *pgm); #ifdef __cplusplus } #endif -#endif /* avr910_h */ +#endif diff --git a/src/avr_opcodes.c b/src/avr_opcodes.c index e6c1e07c8..bf11d9446 100644 --- a/src/avr_opcodes.c +++ b/src/avr_opcodes.c @@ -1,5 +1,5 @@ /* - * AVRDUDE - A Downloader/Uploader for AVR device programmers + * avrdude - A Downloader/Uploader for AVR device programmers * Copyright (C) 2024 Stefan Rueger * * This program is free software; you can redistribute it and/or modify @@ -81,512 +81,513 @@ const AVR_opcode avr_opcodes[MNEMO_N] = { #define OP_ID(nam) MNEMO_##nam, #nam // Arithmetic and Logic Instructions - {OP_ID(lsl), 0xfc00, 0x0c00, 1, OP_AVR1, "0000 11d= dddd ====", OTY_ALBI|OTY_RALL|OTY_CONSTRAINT, - "lsl", "Rd", "logical shift left", "C <-- Rd(7) <-- Rd(6) ... Rd(1) <-- Rd(0) <-- 0", "--H-VNZC", + {OP_ID(lsl), 0xfc00, 0x0c00, 1, OP_AVR1, "0000 11d= dddd ====", OTY_ALBI | OTY_RALL | OTY_CONSTRAINT, + "lsl", "Rd", "logical shift left", "C <-- Rd(7) <-- Rd(6) ... Rd(1) <-- Rd(0) <-- 0", "--H-VNZC", {"1", "1", "1", "1"}, "alias for add Rd, Rd"}, - {OP_ID(add), 0xfc00, 0x0c00, 1, OP_AVR1, "0000 11rd dddd rrrr", OTY_ALBI|OTY_RALL, - "add", "Rd, Rr", "add without carry", "Rd <-- Rd + Rr", "--HSVNZC", + {OP_ID(add), 0xfc00, 0x0c00, 1, OP_AVR1, "0000 11rd dddd rrrr", OTY_ALBI | OTY_RALL, + "add", "Rd, Rr", "add without carry", "Rd <-- Rd + Rr", "--HSVNZC", {"1", "1", "1", "1"}, ""}, - {OP_ID(rol), 0xfc00, 0x1c00, 1, OP_AVR1, "0001 11d= dddd ====", OTY_ALBI|OTY_RALL|OTY_CONSTRAINT, - "rol", "Rd", "rotate left through carry", "C <-- Rd(7) <-- Rd(6) ... Rd(1) <-- Rd(0) <-- C", "--H-VNZC", + {OP_ID(rol), 0xfc00, 0x1c00, 1, OP_AVR1, "0001 11d= dddd ====", OTY_ALBI | OTY_RALL | OTY_CONSTRAINT, + "rol", "Rd", "rotate left through carry", "C <-- Rd(7) <-- Rd(6) ... Rd(1) <-- Rd(0) <-- C", "--H-VNZC", {"1", "1", "1", "1"}, "alias for adc Rd, Rd"}, - {OP_ID(adc), 0xfc00, 0x1c00, 1, OP_AVR1, "0001 11rd dddd rrrr", OTY_ALBI|OTY_RALL, - "adc", "Rd, Rr", "add with carry", "Rd <-- Rd + Rr + C", "--HSVNZC", + {OP_ID(adc), 0xfc00, 0x1c00, 1, OP_AVR1, "0001 11rd dddd rrrr", OTY_ALBI | OTY_RALL, + "adc", "Rd, Rr", "add with carry", "Rd <-- Rd + Rr + C", "--HSVNZC", {"1", "1", "1", "1"}, ""}, - {OP_ID(ror), 0xfe0f, 0x9407, 1, OP_AVR1, "1001 010d dddd 0111", OTY_ALBI|OTY_RALL, - "ror", "Rd", "rotate right through carry", "C --> Rd(7) --> Rd(6) ... Rd(1) --> Rd(0) --> C", "----VNZC", + {OP_ID(ror), 0xfe0f, 0x9407, 1, OP_AVR1, "1001 010d dddd 0111", OTY_ALBI | OTY_RALL, + "ror", "Rd", "rotate right through carry", "C --> Rd(7) --> Rd(6) ... Rd(1) --> Rd(0) --> C", "----VNZC", {"1", "1", "1", "1"}, ""}, - {OP_ID(asr), 0xfe0f, 0x9405, 1, OP_AVR1, "1001 010d dddd 0101", OTY_ALBI|OTY_RALL, - "asr", "Rd", "arithmetic shift right", "Rd(7) --> Rd(7) --> Rd(6) ... Rd(1) --> Rd(0) --> C", "----VNZC", + {OP_ID(asr), 0xfe0f, 0x9405, 1, OP_AVR1, "1001 010d dddd 0101", OTY_ALBI | OTY_RALL, + "asr", "Rd", "arithmetic shift right", "Rd(7) --> Rd(7) --> Rd(6) ... Rd(1) --> Rd(0) --> C", "----VNZC", {"1", "1", "1", "1"}, ""}, - {OP_ID(adiw), 0xff00, 0x9600, 1, OP_AVR2nRC, "1001 0110 KKdd KKKK", OTY_ALBI|OTY_RW24, - "adiw", "Rd, K", "add immediate to word", "Rd+1:Rd <-- Rd+1:Rd + K", "---SVNZC", + {OP_ID(adiw), 0xff00, 0x9600, 1, OP_AVR2nRC, "1001 0110 KKdd KKKK", OTY_ALBI | OTY_RW24, + "adiw", "Rd, K", "add immediate to word", "Rd+1:Rd <-- Rd+1:Rd + K", "---SVNZC", {"2", "2", "2", "n/a"}, "d in {24, 26, 28, 30}"}, - {OP_ID(sub), 0xfc00, 0x1800, 1, OP_AVR1, "0001 10rd dddd rrrr", OTY_ALBI|OTY_RALL, - "sub", "Rd, Rr", "subtract without carry", "Rd <-- Rd - Rr", "--HSVNZC", + {OP_ID(sub), 0xfc00, 0x1800, 1, OP_AVR1, "0001 10rd dddd rrrr", OTY_ALBI | OTY_RALL, + "sub", "Rd, Rr", "subtract without carry", "Rd <-- Rd - Rr", "--HSVNZC", {"1", "1", "1", "1"}, ""}, - {OP_ID(subi), 0xf000, 0x5000, 1, OP_AVR1, "0101 KKKK dddd KKKK", OTY_ALBI|OTY_RUPP, - "subi", "Rd, K", "subtract immediate", "Rd <-- Rd - K", "--HSVNZC", + {OP_ID(subi), 0xf000, 0x5000, 1, OP_AVR1, "0101 KKKK dddd KKKK", OTY_ALBI | OTY_RUPP, + "subi", "Rd, K", "subtract immediate", "Rd <-- Rd - K", "--HSVNZC", {"1", "1", "1", "1"}, "d = 16..31"}, - {OP_ID(sbc), 0xfc00, 0x0800, 1, OP_AVR1, "0000 10rd dddd rrrr", OTY_ALBI|OTY_RALL, - "sbc", "Rd, Rr", "subtract with carry", "Rd <-- Rd - Rr - C", "--HSVNZC", + {OP_ID(sbc), 0xfc00, 0x0800, 1, OP_AVR1, "0000 10rd dddd rrrr", OTY_ALBI | OTY_RALL, + "sbc", "Rd, Rr", "subtract with carry", "Rd <-- Rd - Rr - C", "--HSVNZC", {"1", "1", "1", "1"}, ""}, - {OP_ID(sbci), 0xf000, 0x4000, 1, OP_AVR1, "0100 KKKK dddd KKKK", OTY_ALBI|OTY_RUPP, - "sbci", "Rd, K", "subtract immediate with carry", "Rd <-- Rd - K - C", "--HSVNZC", + {OP_ID(sbci), 0xf000, 0x4000, 1, OP_AVR1, "0100 KKKK dddd KKKK", OTY_ALBI | OTY_RUPP, + "sbci", "Rd, K", "subtract immediate with carry", "Rd <-- Rd - K - C", "--HSVNZC", {"1", "1", "1", "1"}, "d = 16..31"}, - {OP_ID(sbiw), 0xff00, 0x9700, 1, OP_AVR2nRC, "1001 0111 KKdd KKKK", OTY_ALBI|OTY_RW24, - "sbiw", "Rd, K", "subtract immediate from word", "Rd+1:Rd <-- Rd+1:Rd - K", "---SVNZC", + {OP_ID(sbiw), 0xff00, 0x9700, 1, OP_AVR2nRC, "1001 0111 KKdd KKKK", OTY_ALBI | OTY_RW24, + "sbiw", "Rd, K", "subtract immediate from word", "Rd+1:Rd <-- Rd+1:Rd - K", "---SVNZC", {"2", "2", "2", "n/a"}, "d in {24, 26, 28, 30}"}, - {OP_ID(tst), 0xfc00, 0x2000, 1, OP_AVR1, "0010 00r= rrrr ====", OTY_ALBI|OTY_RALL|OTY_CONSTRAINT, - "tst", "Rr", "test for zero or minus", "Rr <-- Rr & Rr", "---SVNZ-", + {OP_ID(tst), 0xfc00, 0x2000, 1, OP_AVR1, "0010 00r= rrrr ====", OTY_ALBI | OTY_RALL | OTY_CONSTRAINT, + "tst", "Rr", "test for zero or minus", "Rr <-- Rr & Rr", "---SVNZ-", {"1", "1", "1", "1"}, "alias for and Rd, Rd"}, - {OP_ID(and), 0xfc00, 0x2000, 1, OP_AVR1, "0010 00rd dddd rrrr", OTY_ALBI|OTY_RALL, - "and", "Rd, Rr", "logical and", "Rd <-- Rd & Rr", "---SVNZ-", + {OP_ID(and), 0xfc00, 0x2000, 1, OP_AVR1, "0010 00rd dddd rrrr", OTY_ALBI | OTY_RALL, + "and", "Rd, Rr", "logical and", "Rd <-- Rd & Rr", "---SVNZ-", {"1", "1", "1", "1"}, ""}, - {OP_ID(andi), 0xf000, 0x7000, 1, OP_AVR1, "0111 KKKK dddd KKKK", OTY_ALBI|OTY_RUPP, - "andi", "Rd, K", "logical and with immediate", "Rd <-- Rd & K", "---SVNZ-", + {OP_ID(andi), 0xf000, 0x7000, 1, OP_AVR1, "0111 KKKK dddd KKKK", OTY_ALBI | OTY_RUPP, + "andi", "Rd, K", "logical and with immediate", "Rd <-- Rd & K", "---SVNZ-", {"1", "1", "1", "1"}, "d = 16..31"}, - {OP_ID(cbr), 0xf000, 0x7000, 1, OP_AVR1, "0111 KKKK dddd KKKK", OTY_ALBI|OTY_RUPP|OTY_ALIAS, - "cbr", "Rd, K", "clear bit(s) in register", "Rd <-- Rd & (0xff - K)", "---SVNZ-", + {OP_ID(cbr), 0xf000, 0x7000, 1, OP_AVR1, "0111 KKKK dddd KKKK", OTY_ALBI | OTY_RUPP | OTY_ALIAS, + "cbr", "Rd, K", "clear bit(s) in register", "Rd <-- Rd & (0xff - K)", "---SVNZ-", {"1", "1", "1", "1"}, "alias for andi Rd, (0xff - K); d = 16..31"}, - {OP_ID(or), 0xfc00, 0x2800, 1, OP_AVR1, "0010 10rd dddd rrrr", OTY_ALBI|OTY_RALL, - "or", "Rd, Rr", "logical or", "Rd <-- Rd | Rr", "---SVNZ-", + {OP_ID(or), 0xfc00, 0x2800, 1, OP_AVR1, "0010 10rd dddd rrrr", OTY_ALBI | OTY_RALL, + "or", "Rd, Rr", "logical or", "Rd <-- Rd | Rr", "---SVNZ-", {"1", "1", "1", "1"}, ""}, - {OP_ID(ori), 0xf000, 0x6000, 1, OP_AVR1, "0110 KKKK dddd KKKK", OTY_ALBI|OTY_RUPP, - "ori", "Rd, K", "logical or with immediate", "Rd <-- Rd | K", "---SVNZ-", + {OP_ID(ori), 0xf000, 0x6000, 1, OP_AVR1, "0110 KKKK dddd KKKK", OTY_ALBI | OTY_RUPP, + "ori", "Rd, K", "logical or with immediate", "Rd <-- Rd | K", "---SVNZ-", {"1", "1", "1", "1"}, "d = 16..31"}, - {OP_ID(sbr), 0xf000, 0x6000, 1, OP_AVR1, "0110 KKKK dddd KKKK", OTY_ALBI|OTY_RUPP|OTY_ALIAS, - "sbr", "Rd, K", "set bit(s) in register", "Rd <-- Rd | K", "---SVNZ-", + {OP_ID(sbr), 0xf000, 0x6000, 1, OP_AVR1, "0110 KKKK dddd KKKK", OTY_ALBI | OTY_RUPP | OTY_ALIAS, + "sbr", "Rd, K", "set bit(s) in register", "Rd <-- Rd | K", "---SVNZ-", {"1", "1", "1", "1"}, "alias for ori Rd, K; d = 16..31"}, - {OP_ID(clr), 0xfc00, 0x2400, 1, OP_AVR1, "0010 01d= dddd ====", OTY_ALBI|OTY_RALL|OTY_CONSTRAINT, - "clr", "Rd", "clear register", "Rd <-- Rd ^ Rd", "---SVNZ-", + {OP_ID(clr), 0xfc00, 0x2400, 1, OP_AVR1, "0010 01d= dddd ====", OTY_ALBI | OTY_RALL | OTY_CONSTRAINT, + "clr", "Rd", "clear register", "Rd <-- Rd ^ Rd", "---SVNZ-", {"1", "1", "1", "1"}, "alias for eor Rd, Rd"}, - {OP_ID(eor), 0xfc00, 0x2400, 1, OP_AVR1, "0010 01rd dddd rrrr", OTY_ALBI|OTY_RALL, - "eor", "Rd, Rr", "exclusive or", "Rd <-- Rd ^ Rr", "---SVNZ-", + {OP_ID(eor), 0xfc00, 0x2400, 1, OP_AVR1, "0010 01rd dddd rrrr", OTY_ALBI | OTY_RALL, + "eor", "Rd, Rr", "exclusive or", "Rd <-- Rd ^ Rr", "---SVNZ-", {"1", "1", "1", "1"}, ""}, - {OP_ID(com), 0xfe0f, 0x9400, 1, OP_AVR1, "1001 010d dddd 0000", OTY_ALBI|OTY_RALL, - "com", "Rd", "one's complement", "Rd <-- 0xff - Rd", "---SVNZC", + {OP_ID(com), 0xfe0f, 0x9400, 1, OP_AVR1, "1001 010d dddd 0000", OTY_ALBI | OTY_RALL, + "com", "Rd", "one's complement", "Rd <-- 0xff - Rd", "---SVNZC", {"1", "1", "1", "1"}, ""}, - {OP_ID(neg), 0xfe0f, 0x9401, 1, OP_AVR1, "1001 010d dddd 0001", OTY_ALBI|OTY_RALL, - "neg", "Rd", "two's complement", "Rd <-- 0x00 - Rd", "--HSVNZC", + {OP_ID(neg), 0xfe0f, 0x9401, 1, OP_AVR1, "1001 010d dddd 0001", OTY_ALBI | OTY_RALL, + "neg", "Rd", "two's complement", "Rd <-- 0x00 - Rd", "--HSVNZC", {"1", "1", "1", "1"}, ""}, - {OP_ID(inc), 0xfe0f, 0x9403, 1, OP_AVR1, "1001 010d dddd 0011", OTY_ALBI|OTY_RALL, - "inc", "Rd", "increment", "Rd <-- Rd + 1", "---SVNZ-", + {OP_ID(inc), 0xfe0f, 0x9403, 1, OP_AVR1, "1001 010d dddd 0011", OTY_ALBI | OTY_RALL, + "inc", "Rd", "increment", "Rd <-- Rd + 1", "---SVNZ-", {"1", "1", "1", "1"}, ""}, - {OP_ID(dec), 0xfe0f, 0x940a, 1, OP_AVR1, "1001 010d dddd 1010", OTY_ALBI|OTY_RALL, - "dec", "Rd", "decrement", "Rd <-- Rd - 1", "---SVNZ-", + {OP_ID(dec), 0xfe0f, 0x940a, 1, OP_AVR1, "1001 010d dddd 1010", OTY_ALBI | OTY_RALL, + "dec", "Rd", "decrement", "Rd <-- Rd - 1", "---SVNZ-", {"1", "1", "1", "1"}, ""}, - {OP_ID(mul), 0xfc00, 0x9c00, 1, OP_AVR4, "1001 11rd dddd rrrr", OTY_ALBI|OTY_RALL, - "mul", "Rd, Rr", "multiply unsigned", "R1:R0 <-- Rd x Rr (UU)", "------ZC", + {OP_ID(mul), 0xfc00, 0x9c00, 1, OP_AVR4, "1001 11rd dddd rrrr", OTY_ALBI | OTY_RALL, + "mul", "Rd, Rr", "multiply unsigned", "R1:R0 <-- Rd x Rr (UU)", "------ZC", {"2", "2", "2", "n/a"}, ""}, - {OP_ID(muls), 0xff00, 0x0200, 1, OP_AVR4, "0000 0010 dddd rrrr", OTY_ALBI|OTY_RUPP, - "muls", "Rd, Rr", "multiply signed", "R1:R0 <-- Rd x Rr (SS)", "------ZC", + {OP_ID(muls), 0xff00, 0x0200, 1, OP_AVR4, "0000 0010 dddd rrrr", OTY_ALBI | OTY_RUPP, + "muls", "Rd, Rr", "multiply signed", "R1:R0 <-- Rd x Rr (SS)", "------ZC", {"2", "2", "2", "n/a"}, "d, r = 16..31"}, - {OP_ID(mulsu), 0xff88, 0x0300, 1, OP_AVR4, "0000 0011 0ddd 0rrr", OTY_ALBI|OTY_RUPP, - "mulsu", "Rd, Rr", "multiply signed with unsigned", "R1:R0 <-- Rd x Rr (SU)", "------ZC", + {OP_ID(mulsu), 0xff88, 0x0300, 1, OP_AVR4, "0000 0011 0ddd 0rrr", OTY_ALBI | OTY_RUPP, + "mulsu", "Rd, Rr", "multiply signed with unsigned", "R1:R0 <-- Rd x Rr (SU)", "------ZC", {"2", "2", "2", "n/a"}, "d, r = 16..23"}, - {OP_ID(fmul), 0xff88, 0x0308, 1, OP_AVR4, "0000 0011 0ddd 1rrr", OTY_ALBI|OTY_RUPP, - "fmul", "Rd, Rr", "fractional multiply unsigned", "R1:R0 <-- Rd x Rr << 1 (UU)", "------ZC", + {OP_ID(fmul), 0xff88, 0x0308, 1, OP_AVR4, "0000 0011 0ddd 1rrr", OTY_ALBI | OTY_RUPP, + "fmul", "Rd, Rr", "fractional multiply unsigned", "R1:R0 <-- Rd x Rr << 1 (UU)", "------ZC", {"2", "2", "2", "n/a"}, "d, r = 16..23"}, - {OP_ID(fmuls), 0xff88, 0x0380, 1, OP_AVR4, "0000 0011 1ddd 0rrr", OTY_ALBI|OTY_RUPP, - "fmuls", "Rd, Rr", "fractional multiply signed", "R1:R0 <-- Rd x Rr << 1 (SS)", "------ZC", + {OP_ID(fmuls), 0xff88, 0x0380, 1, OP_AVR4, "0000 0011 1ddd 0rrr", OTY_ALBI | OTY_RUPP, + "fmuls", "Rd, Rr", "fractional multiply signed", "R1:R0 <-- Rd x Rr << 1 (SS)", "------ZC", {"2", "2", "2", "n/a"}, "d, r = 16..23"}, - {OP_ID(fmulsu), 0xff88, 0x0388, 1, OP_AVR4, "0000 0011 1ddd 1rrr", OTY_ALBI|OTY_RUPP, - "fmulsu", "Rd, Rr", "fractional multiply signed with unsigned", "R1:R0 <-- Rd x Rr << 1 (SU)", "------ZC", + {OP_ID(fmulsu), 0xff88, 0x0388, 1, OP_AVR4, "0000 0011 1ddd 1rrr", OTY_ALBI | OTY_RUPP, + "fmulsu", "Rd, Rr", "fractional multiply signed with unsigned", "R1:R0 <-- Rd x Rr << 1 (SU)", "------ZC", {"2", "2", "2", "n/a"}, "d, r = 16..23"}, - {OP_ID(des), 0xff0f, 0x940b, 1, OP_AVR_XM, "1001 0100 KKKK 1011", OTY_ALBI, - "des", "K", "data encryption round", "if (H = 0) then R15:R0 <-- Encrypt(R15:R0, K) if (H = 1) then R15:R0 <-- Decrypt(R15:R0, K)", "--------", + {OP_ID(des), 0xff0f, 0x940b, 1, OP_AVR_XM, "1001 0100 KKKK 1011", OTY_ALBI, + "des", "K", "data encryption round", + "if (H = 0) then R15:R0 <-- Encrypt(R15:R0, K) if (H = 1) then R15:R0 <-- Decrypt(R15:R0, K)", "--------", {"n/a", "1/2", "n/a", "n/a"}, ""}, // Branch Instructions (and compare) - {OP_ID(rjmp), 0xf000, 0xc000, 1, OP_AVR1, "1100 kkkk kkkk kkkk", OTY_RJMI, - "rjmp", "k", "relative jump", "PC <-- PC + k + 1", "--------", + {OP_ID(rjmp), 0xf000, 0xc000, 1, OP_AVR1, "1100 kkkk kkkk kkkk", OTY_RJMI, + "rjmp", "k", "relative jump", "PC <-- PC + k + 1", "--------", {"2", "2", "2", "2"}, ""}, - {OP_ID(ijmp), 0xffff, 0x9409, 1, OP_AVR2, "1001 0100 0000 1001", OTY_JMPI|OTY_ZWORD, - "ijmp", "", "indirect jump to (Z)", "PC(15:0) <-- Z, PC(21:16) <-- 0", "--------", + {OP_ID(ijmp), 0xffff, 0x9409, 1, OP_AVR2, "1001 0100 0000 1001", OTY_JMPI | OTY_ZWORD, + "ijmp", "", "indirect jump to (Z)", "PC(15:0) <-- Z, PC(21:16) <-- 0", "--------", {"2", "2", "2", "2"}, ""}, - {OP_ID(eijmp), 0xffff, 0x9419, 1, OP_AVR_XL, "1001 0100 0001 1001", OTY_JMPX|OTY_ZWORD, - "eijmp", "", "extended indirect jump to (Z)", "PC(15:0) <-- Z, PC(21:16) <-- EIND", "--------", + {OP_ID(eijmp), 0xffff, 0x9419, 1, OP_AVR_XL, "1001 0100 0001 1001", OTY_JMPX | OTY_ZWORD, + "eijmp", "", "extended indirect jump to (Z)", "PC(15:0) <-- Z, PC(21:16) <-- EIND", "--------", {"2", "2", "2", "n/a"}, ""}, - {OP_ID(jmp), 0xfe0e, 0x940c, 2, OP_AVR_M, "1001 010k kkkk 110k kkkk kkkk kkkk kkkk", OTY_JMPI, - "jmp", "k", "jump", "PC <-- k", "--------", + {OP_ID(jmp), 0xfe0e, 0x940c, 2, OP_AVR_M, "1001 010k kkkk 110k kkkk kkkk kkkk kkkk", OTY_JMPI, + "jmp", "k", "jump", "PC <-- k", "--------", {"3", "3", "3", "n/a"}, ""}, - {OP_ID(rcall), 0xf000, 0xd000, 1, OP_AVR1, "1101 kkkk kkkk kkkk", OTY_RJMX, - "rcall", "k", "relative call subroutine", "PC <-- PC + k + 1", "--------", + {OP_ID(rcall), 0xf000, 0xd000, 1, OP_AVR1, "1101 kkkk kkkk kkkk", OTY_RJMX, + "rcall", "k", "relative call subroutine", "PC <-- PC + k + 1", "--------", {"3+", "2+", "2+", "3"}, ""}, - {OP_ID(icall), 0xffff, 0x9509, 1, OP_AVR2, "1001 0101 0000 1001", OTY_JMPX|OTY_ZWORD, - "icall", "", "indirect call to (Z)", "PC(15:0) <-- Z, PC(21:16) <-- 0", "--------", + {OP_ID(icall), 0xffff, 0x9509, 1, OP_AVR2, "1001 0101 0000 1001", OTY_JMPX | OTY_ZWORD, + "icall", "", "indirect call to (Z)", "PC(15:0) <-- Z, PC(21:16) <-- 0", "--------", {"3+", "2+", "2+", "3"}, ""}, - {OP_ID(eicall), 0xffff, 0x9519, 1, OP_AVR_XL, "1001 0101 0001 1001", OTY_JMPX|OTY_ZWORD, - "eicall", "", "extended indirect call to (Z)", "PC(15:0) <-- Z, PC(21:16) <-- EIND", "--------", + {OP_ID(eicall), 0xffff, 0x9519, 1, OP_AVR_XL, "1001 0101 0001 1001", OTY_JMPX | OTY_ZWORD, + "eicall", "", "extended indirect call to (Z)", "PC(15:0) <-- Z, PC(21:16) <-- EIND", "--------", {"4", "3", "3", "n/a"}, ""}, - {OP_ID(call), 0xfe0e, 0x940e, 2, OP_AVR_M, "1001 010k kkkk 111k kkkk kkkk kkkk kkkk", OTY_JMPX, - "call", "k", "call subroutine", "PC <-- k, STACK <-- PC, SP <-- SP - 2", "--------", + {OP_ID(call), 0xfe0e, 0x940e, 2, OP_AVR_M, "1001 010k kkkk 111k kkkk kkkk kkkk kkkk", OTY_JMPX, + "call", "k", "call subroutine", "PC <-- k, STACK <-- PC, SP <-- SP - 2", "--------", {"4+", "3+", "3+", "n/a"}, ""}, - {OP_ID(ret), 0xffff, 0x9508, 1, OP_AVR1, "1001 0101 0000 1000", OTY_JMPX, - "ret", "", "subroutine return", "SP <-- SP + 2, PC <-- STACK", "--------", + {OP_ID(ret), 0xffff, 0x9508, 1, OP_AVR1, "1001 0101 0000 1000", OTY_JMPX, + "ret", "", "subroutine return", "SP <-- SP + 2, PC <-- STACK", "--------", {"4+", "4+", "4+", "6"}, ""}, - {OP_ID(reti), 0xffff, 0x9518, 1, OP_AVR1, "1001 0101 0001 1000", OTY_JMPX, - "reti", "", "interrupt return", "SP <-- SP + 2, PC <-- STACK", "I-------", + {OP_ID(reti), 0xffff, 0x9518, 1, OP_AVR1, "1001 0101 0001 1000", OTY_JMPX, + "reti", "", "interrupt return", "SP <-- SP + 2, PC <-- STACK", "I-------", {"4+", "4+", "4+", "6"}, ""}, - {OP_ID(cpse), 0xfc00, 0x1000, 1, OP_AVR1, "0001 00rd dddd rrrr", OTY_SKPI|OTY_RALL, - "cpse", "Rd, Rr", "compare and skip if equal", "if(Rd=Rr) PC <-- PC + 2/3", "--------", + {OP_ID(cpse), 0xfc00, 0x1000, 1, OP_AVR1, "0001 00rd dddd rrrr", OTY_SKPI | OTY_RALL, + "cpse", "Rd, Rr", "compare and skip if equal", "if(Rd=Rr) PC <-- PC + 2/3", "--------", {"1-3", "1-3", "1-3", "1/2"}, ""}, - {OP_ID(cp), 0xfc00, 0x1400, 1, OP_AVR1, "0001 01rd dddd rrrr", OTY_ALBI|OTY_RALL, - "cp", "Rd, Rr", "compare", "Rd - Rr", "--HSVNZC", + {OP_ID(cp), 0xfc00, 0x1400, 1, OP_AVR1, "0001 01rd dddd rrrr", OTY_ALBI | OTY_RALL, + "cp", "Rd, Rr", "compare", "Rd - Rr", "--HSVNZC", {"1", "1", "1", "1"}, ""}, - {OP_ID(cpc), 0xfc00, 0x0400, 1, OP_AVR1, "0000 01rd dddd rrrr", OTY_ALBI|OTY_RALL, - "cpc", "Rd, Rr", "compare with carry", "Rd - Rr - C", "--HSVNZC", + {OP_ID(cpc), 0xfc00, 0x0400, 1, OP_AVR1, "0000 01rd dddd rrrr", OTY_ALBI | OTY_RALL, + "cpc", "Rd, Rr", "compare with carry", "Rd - Rr - C", "--HSVNZC", {"1", "1", "1", "1"}, ""}, - {OP_ID(cpi), 0xf000, 0x3000, 1, OP_AVR1, "0011 KKKK dddd KKKK", OTY_ALBI|OTY_RUPP, - "cpi", "Rd, K", "compare with immediate", "Rd - K", "--HSVNZC", + {OP_ID(cpi), 0xf000, 0x3000, 1, OP_AVR1, "0011 KKKK dddd KKKK", OTY_ALBI | OTY_RUPP, + "cpi", "Rd, K", "compare with immediate", "Rd - K", "--HSVNZC", {"1", "1", "1", "1"}, "d = 16..31"}, - {OP_ID(sbrc), 0xfe08, 0xfc00, 1, OP_AVR1, "1111 110r rrrr 0bbb", OTY_SKPI|OTY_RALL, - "sbrc", "Rr, b", "skip if bit in register cleared", "if(Rr(b)=0) PC <-- PC + 2/3", "--------", + {OP_ID(sbrc), 0xfe08, 0xfc00, 1, OP_AVR1, "1111 110r rrrr 0bbb", OTY_SKPI | OTY_RALL, + "sbrc", "Rr, b", "skip if bit in register cleared", "if(Rr(b)=0) PC <-- PC + 2/3", "--------", {"1-3", "1-3", "1-3", "1/2"}, ""}, - {OP_ID(sbrs), 0xfe08, 0xfe00, 1, OP_AVR1, "1111 111r rrrr 0bbb", OTY_SKPI|OTY_RALL, - "sbrs", "Rr, b", "skip if bit in register set", "if(Rr(b)=1) PC <-- PC + 2/3", "--------", + {OP_ID(sbrs), 0xfe08, 0xfe00, 1, OP_AVR1, "1111 111r rrrr 0bbb", OTY_SKPI | OTY_RALL, + "sbrs", "Rr, b", "skip if bit in register set", "if(Rr(b)=1) PC <-- PC + 2/3", "--------", {"1-3", "1-3", "1-3", "1/2"}, ""}, - {OP_ID(sbic), 0xff00, 0x9900, 1, OP_AVR1, "1001 1001 AAAA Abbb", OTY_SKPX, - "sbic", "A, b", "skip if bit in I/O register cleared", "if(I/O(A,b)=0) PC <-- PC + 2/3", "--------", + {OP_ID(sbic), 0xff00, 0x9900, 1, OP_AVR1, "1001 1001 AAAA Abbb", OTY_SKPX, + "sbic", "A, b", "skip if bit in I/O register cleared", "if(I/O(A,b)=0) PC <-- PC + 2/3", "--------", {"1-3", "2-4", "1-3", "1/2"}, ""}, - {OP_ID(sbis), 0xff00, 0x9b00, 1, OP_AVR1, "1001 1011 AAAA Abbb", OTY_SKPX, - "sbis", "A, b", "skip if bit in I/O register set", "If(I/O(A,b)=1) PC <-- PC + 2/3", "--------", + {OP_ID(sbis), 0xff00, 0x9b00, 1, OP_AVR1, "1001 1011 AAAA Abbb", OTY_SKPX, + "sbis", "A, b", "skip if bit in I/O register set", "If(I/O(A,b)=1) PC <-- PC + 2/3", "--------", {"1-3", "2-4", "1-3", "1/2"}, ""}, - {OP_ID(brcs), 0xfc07, 0xf000, 1, OP_AVR1, "1111 00kk kkkk k000", OTY_BRAI, - "brcs", "k", "branch if carry set", "if(C=1) then PC <-- PC + k + 1", "--------", + {OP_ID(brcs), 0xfc07, 0xf000, 1, OP_AVR1, "1111 00kk kkkk k000", OTY_BRAI, + "brcs", "k", "branch if carry set", "if(C=1) then PC <-- PC + k + 1", "--------", {"1/2", "1/2", "1/2", "1/2"}, "alias for brbs 0, k (C Carry)"}, - {OP_ID(brlo), 0xfc07, 0xf000, 1, OP_AVR1, "1111 00kk kkkk k000", OTY_BRAI|OTY_ALIAS, - "brlo", "k", "branch if lower", "if(C=1) then PC <-- PC + k + 1", "--------", + {OP_ID(brlo), 0xfc07, 0xf000, 1, OP_AVR1, "1111 00kk kkkk k000", OTY_BRAI | OTY_ALIAS, + "brlo", "k", "branch if lower", "if(C=1) then PC <-- PC + k + 1", "--------", {"1/2", "1/2", "1/2", "1/2"}, "alias for brbs 0, k (C Carry)"}, - {OP_ID(breq), 0xfc07, 0xf001, 1, OP_AVR1, "1111 00kk kkkk k001", OTY_BRAI, - "breq", "k", "branch if equal", "if(Z=1) then PC <-- PC + k + 1", "--------", + {OP_ID(breq), 0xfc07, 0xf001, 1, OP_AVR1, "1111 00kk kkkk k001", OTY_BRAI, + "breq", "k", "branch if equal", "if(Z=1) then PC <-- PC + k + 1", "--------", {"1/2", "1/2", "1/2", "1/2"}, "alias for brbs 1, k (Z Zero)"}, - {OP_ID(brmi), 0xfc07, 0xf002, 1, OP_AVR1, "1111 00kk kkkk k010", OTY_BRAI, - "brmi", "k", "branch if minus", "if(N=1) then PC <-- PC + k + 1", "--------", + {OP_ID(brmi), 0xfc07, 0xf002, 1, OP_AVR1, "1111 00kk kkkk k010", OTY_BRAI, + "brmi", "k", "branch if minus", "if(N=1) then PC <-- PC + k + 1", "--------", {"1/2", "1/2", "1/2", "1/2"}, "alias for brbs 2, k (N Negative)"}, - {OP_ID(brvs), 0xfc07, 0xf003, 1, OP_AVR1, "1111 00kk kkkk k011", OTY_BRAI, - "brvs", "k", "branch if overflow flag is set", "if(V=1) then PC <-- PC + k + 1", "--------", + {OP_ID(brvs), 0xfc07, 0xf003, 1, OP_AVR1, "1111 00kk kkkk k011", OTY_BRAI, + "brvs", "k", "branch if overflow flag is set", "if(V=1) then PC <-- PC + k + 1", "--------", {"1/2", "1/2", "1/2", "1/2"}, "alias for brbs 3, k (V Overflow in two's complement)"}, - {OP_ID(brlt), 0xfc07, 0xf004, 1, OP_AVR1, "1111 00kk kkkk k100", OTY_BRAI, - "brlt", "k", "branch if less than (signed)", "if(N^V=1) then PC <-- PC + k + 1", "--------", + {OP_ID(brlt), 0xfc07, 0xf004, 1, OP_AVR1, "1111 00kk kkkk k100", OTY_BRAI, + "brlt", "k", "branch if less than (signed)", "if(N^V=1) then PC <-- PC + k + 1", "--------", {"1/2", "1/2", "1/2", "1/2"}, "alias for brbs 4, k (S Sign)"}, - {OP_ID(brhs), 0xfc07, 0xf005, 1, OP_AVR1, "1111 00kk kkkk k101", OTY_BRAI, - "brhs", "k", "branch if half-carry flag set", "if(H=1) then PC <-- PC + k + 1", "--------", + {OP_ID(brhs), 0xfc07, 0xf005, 1, OP_AVR1, "1111 00kk kkkk k101", OTY_BRAI, + "brhs", "k", "branch if half-carry flag set", "if(H=1) then PC <-- PC + k + 1", "--------", {"1/2", "1/2", "1/2", "1/2"}, "alias for brbs 5, k (H Half carry)"}, - {OP_ID(brts), 0xfc07, 0xf006, 1, OP_AVR1, "1111 00kk kkkk k110", OTY_BRAI, - "brts", "k", "branch if T flag set", "if(T=1) then PC <-- PC + k + 1", "--------", + {OP_ID(brts), 0xfc07, 0xf006, 1, OP_AVR1, "1111 00kk kkkk k110", OTY_BRAI, + "brts", "k", "branch if T flag set", "if(T=1) then PC <-- PC + k + 1", "--------", {"1/2", "1/2", "1/2", "1/2"}, "alias for brbs 6, k (T Transfer bit)"}, - {OP_ID(brie), 0xfc07, 0xf007, 1, OP_AVR1, "1111 00kk kkkk k111", OTY_BRAI, - "brie", "k", "branch if interrupt enabled", "if(I=1) then PC <-- PC + k + 1", "--------", + {OP_ID(brie), 0xfc07, 0xf007, 1, OP_AVR1, "1111 00kk kkkk k111", OTY_BRAI, + "brie", "k", "branch if interrupt enabled", "if(I=1) then PC <-- PC + k + 1", "--------", {"1/2", "1/2", "1/2", "1/2"}, "alias for brbs 7, k (I Interrupt enable)"}, - {OP_ID(brbs), 0xfc00, 0xf000, 1, OP_AVR1, "1111 00kk kkkk ksss", OTY_BRAI, - "brbs", "s, k", "branch if status flag set", "if(SREG(s)=1) then PC <-- PC + k + 1", "--------", + {OP_ID(brbs), 0xfc00, 0xf000, 1, OP_AVR1, "1111 00kk kkkk ksss", OTY_BRAI, + "brbs", "s, k", "branch if status flag set", "if(SREG(s)=1) then PC <-- PC + k + 1", "--------", {"1/2", "1/2", "1/2", "1/2"}, ""}, - {OP_ID(brcc), 0xfc07, 0xf400, 1, OP_AVR1, "1111 01kk kkkk k000", OTY_BRAI, - "brcc", "k", "branch if carry cleared", "if(C=0) then PC <-- PC + k + 1", "--------", + {OP_ID(brcc), 0xfc07, 0xf400, 1, OP_AVR1, "1111 01kk kkkk k000", OTY_BRAI, + "brcc", "k", "branch if carry cleared", "if(C=0) then PC <-- PC + k + 1", "--------", {"1/2", "1/2", "1/2", "1/2"}, "alias for brbc 0, k (C Carry)"}, - {OP_ID(brsh), 0xfc07, 0xf400, 1, OP_AVR1, "1111 01kk kkkk k000", OTY_BRAI|OTY_ALIAS, - "brsh", "k", "branch if same or higher", "if(C=0) then PC <-- PC + k + 1", "--------", + {OP_ID(brsh), 0xfc07, 0xf400, 1, OP_AVR1, "1111 01kk kkkk k000", OTY_BRAI | OTY_ALIAS, + "brsh", "k", "branch if same or higher", "if(C=0) then PC <-- PC + k + 1", "--------", {"1/2", "1/2", "1/2", "1/2"}, "alias for brbc 0, k (C Carry)"}, - {OP_ID(brne), 0xfc07, 0xf401, 1, OP_AVR1, "1111 01kk kkkk k001", OTY_BRAI, - "brne", "k", "branch if not equal", "if(Z=0) then PC <-- PC + k + 1", "--------", + {OP_ID(brne), 0xfc07, 0xf401, 1, OP_AVR1, "1111 01kk kkkk k001", OTY_BRAI, + "brne", "k", "branch if not equal", "if(Z=0) then PC <-- PC + k + 1", "--------", {"1/2", "1/2", "1/2", "1/2"}, "alias for brbc 1, k (Z Zero)"}, - {OP_ID(brpl), 0xfc07, 0xf402, 1, OP_AVR1, "1111 01kk kkkk k010", OTY_BRAI, - "brpl", "k", "branch if plus", "if(N=0) then PC <-- PC + k + 1", "--------", + {OP_ID(brpl), 0xfc07, 0xf402, 1, OP_AVR1, "1111 01kk kkkk k010", OTY_BRAI, + "brpl", "k", "branch if plus", "if(N=0) then PC <-- PC + k + 1", "--------", {"1/2", "1/2", "1/2", "1/2"}, "alias for brbc 2, k (N Negative)"}, - {OP_ID(brvc), 0xfc07, 0xf403, 1, OP_AVR1, "1111 01kk kkkk k011", OTY_BRAI, - "brvc", "k", "branch if overflow flag is cleared", "if(V=0) then PC <-- PC + k + 1", "--------", + {OP_ID(brvc), 0xfc07, 0xf403, 1, OP_AVR1, "1111 01kk kkkk k011", OTY_BRAI, + "brvc", "k", "branch if overflow flag is cleared", "if(V=0) then PC <-- PC + k + 1", "--------", {"1/2", "1/2", "1/2", "1/2"}, "alias for brbc 3, k (V Overflow in two's complement)"}, - {OP_ID(brge), 0xfc07, 0xf404, 1, OP_AVR1, "1111 01kk kkkk k100", OTY_BRAI, - "brge", "k", "branch if greater or equal (signed)", "if(N^V=0) then PC <-- PC + k + 1", "--------", + {OP_ID(brge), 0xfc07, 0xf404, 1, OP_AVR1, "1111 01kk kkkk k100", OTY_BRAI, + "brge", "k", "branch if greater or equal (signed)", "if(N^V=0) then PC <-- PC + k + 1", "--------", {"1/2", "1/2", "1/2", "1/2"}, "alias for brbc 4, k (S Sign)"}, - {OP_ID(brhc), 0xfc07, 0xf405, 1, OP_AVR1, "1111 01kk kkkk k101", OTY_BRAI, - "brhc", "k", "branch if half-carry flag cleared", "if(H=0) then PC <-- PC + k + 1", "--------", + {OP_ID(brhc), 0xfc07, 0xf405, 1, OP_AVR1, "1111 01kk kkkk k101", OTY_BRAI, + "brhc", "k", "branch if half-carry flag cleared", "if(H=0) then PC <-- PC + k + 1", "--------", {"1/2", "1/2", "1/2", "1/2"}, "alias for brbc 5, k (H Half carry)"}, - {OP_ID(brtc), 0xfc07, 0xf406, 1, OP_AVR1, "1111 01kk kkkk k110", OTY_BRAI, - "brtc", "k", "branch if T flag cleared", "if(T=0) then PC <-- PC + k + 1", "--------", + {OP_ID(brtc), 0xfc07, 0xf406, 1, OP_AVR1, "1111 01kk kkkk k110", OTY_BRAI, + "brtc", "k", "branch if T flag cleared", "if(T=0) then PC <-- PC + k + 1", "--------", {"1/2", "1/2", "1/2", "1/2"}, "alias for brbc 6, k (T Transfer bit)"}, - {OP_ID(brid), 0xfc07, 0xf407, 1, OP_AVR1, "1111 01kk kkkk k111", OTY_BRAI, - "brid", "k", "branch if interrupt disabled", "if(I=0) then PC <-- PC + k + 1", "--------", + {OP_ID(brid), 0xfc07, 0xf407, 1, OP_AVR1, "1111 01kk kkkk k111", OTY_BRAI, + "brid", "k", "branch if interrupt disabled", "if(I=0) then PC <-- PC + k + 1", "--------", {"1/2", "1/2", "1/2", "1/2"}, "alias for brbc 7, k (I Interrupt enable)"}, - {OP_ID(brbc), 0xfc00, 0xf400, 1, OP_AVR1, "1111 01kk kkkk ksss", OTY_BRAI, - "brbc", "s, k", "branch if status flag cleared", "if(SREG(s)=0) then PC <-- PC + k + 1", "--------", + {OP_ID(brbc), 0xfc00, 0xf400, 1, OP_AVR1, "1111 01kk kkkk ksss", OTY_BRAI, + "brbc", "s, k", "branch if status flag cleared", "if(SREG(s)=0) then PC <-- PC + k + 1", "--------", {"1/2", "1/2", "1/2", "1/2"}, ""}, // Data Transfer Instructions - {OP_ID(mov), 0xfc00, 0x2c00, 1, OP_AVR1, "0010 11rd dddd rrrr", OTY_XFRI|OTY_RALL, - "mov", "Rd, Rr", "copy register", "Rd <-- Rr", "--------", + {OP_ID(mov), 0xfc00, 0x2c00, 1, OP_AVR1, "0010 11rd dddd rrrr", OTY_XFRI | OTY_RALL, + "mov", "Rd, Rr", "copy register", "Rd <-- Rr", "--------", {"1", "1", "1", "1"}, ""}, - {OP_ID(movw), 0xff00, 0x0100, 1, OP_AVR25, "0000 0001 dddd rrrr", OTY_XFRI|OTY_REVN, - "movw", "Rd, Rr", "copy register pair", "Rd+1:Rd <-- Rr+1:Rr", "--------", + {OP_ID(movw), 0xff00, 0x0100, 1, OP_AVR25, "0000 0001 dddd rrrr", OTY_XFRI | OTY_REVN, + "movw", "Rd, Rr", "copy register pair", "Rd+1:Rd <-- Rr+1:Rr", "--------", {"1", "1", "1", "n/a"}, "d, r in {0, 2, ..., 30}"}, - {OP_ID(ser), 0xff0f, 0xef0f, 1, OP_AVR1, "1110 1111 dddd 1111", OTY_ALBI|OTY_RUPP, - "ser", "Rd", "set register", "Rd <-- 0xff", "--------", + {OP_ID(ser), 0xff0f, 0xef0f, 1, OP_AVR1, "1110 1111 dddd 1111", OTY_ALBI | OTY_RUPP, + "ser", "Rd", "set register", "Rd <-- 0xff", "--------", {"1", "1", "1", "1"}, "alias for ldi Rd, 0xff; d = 16..31"}, - {OP_ID(ldi), 0xf000, 0xe000, 1, OP_AVR1, "1110 KKKK dddd KKKK", OTY_XFRI|OTY_RUPP, - "ldi", "Rd, K", "load immediate", "Rd <-- K", "--------", + {OP_ID(ldi), 0xf000, 0xe000, 1, OP_AVR1, "1110 KKKK dddd KKKK", OTY_XFRI | OTY_RUPP, + "ldi", "Rd, K", "load immediate", "Rd <-- K", "--------", {"1", "1", "1", "1"}, "d = 16..31"}, - {OP_ID(lds), 0xfe0f, 0x9000, 2, OP_AVR2nRC, "1001 000d dddd 0000 kkkk kkkk kkkk kkkk", OTY_XFRX|OTY_RALL, - "lds", "Rd, k", "load direct from data space", "Rd <-- (k)", "--------", + {OP_ID(lds), 0xfe0f, 0x9000, 2, OP_AVR2nRC, "1001 000d dddd 0000 kkkk kkkk kkkk kkkk", OTY_XFRX | OTY_RALL, + "lds", "Rd, k", "load direct from data space", "Rd <-- (k)", "--------", {"2", "3", "3", "2"}, ""}, - {OP_ID(ld_x), 0xfe0f, 0x900c, 1, OP_AVR2, "1001 000d dddd 1100", OTY_XFRX|OTY_RALL, - "ld", "Rd, X", "load indirect", "Rd <-- (X)", "--------", + {OP_ID(ld_x), 0xfe0f, 0x900c, 1, OP_AVR2, "1001 000d dddd 1100", OTY_XFRX | OTY_RALL, + "ld", "Rd, X", "load indirect", "Rd <-- (X)", "--------", {"2", "2", "2", "1/2"}, ""}, - {OP_ID(ld_xp), 0xfe0f, 0x900d, 1, OP_AVR2, "1001 000d dddd 1101", OTY_XFRX|OTY_RALL|OTY_XWRN, - "ld", "Rd, X+", "load indirect and post-increment", "Rd <-- (X), X <-- X + 1", "--------", + {OP_ID(ld_xp), 0xfe0f, 0x900d, 1, OP_AVR2, "1001 000d dddd 1101", OTY_XFRX | OTY_RALL | OTY_XWRN, + "ld", "Rd, X+", "load indirect and post-increment", "Rd <-- (X), X <-- X + 1", "--------", {"2", "2", "2", "2/3"}, ""}, - {OP_ID(ld_mx), 0xfe0f, 0x900e, 1, OP_AVR2, "1001 000d dddd 1110", OTY_XFRX|OTY_RALL|OTY_XWRN, - "ld", "Rd, -X", "load indirect and pre-decrement", "X <-- X - 1, Rd <-- (X)", "--------", + {OP_ID(ld_mx), 0xfe0f, 0x900e, 1, OP_AVR2, "1001 000d dddd 1110", OTY_XFRX | OTY_RALL | OTY_XWRN, + "ld", "Rd, -X", "load indirect and pre-decrement", "X <-- X - 1, Rd <-- (X)", "--------", {"2", "3", "2", "2/3"}, ""}, - {OP_ID(ld_y), 0xfe0f, 0x8008, 1, OP_AVR2, "1000 000d dddd 1000", OTY_XFRX|OTY_RALL, - "ld", "Rd, Y", "load indirect", "Rd <-- (Y) <-- (Y)", "--------", + {OP_ID(ld_y), 0xfe0f, 0x8008, 1, OP_AVR2, "1000 000d dddd 1000", OTY_XFRX | OTY_RALL, + "ld", "Rd, Y", "load indirect", "Rd <-- (Y) <-- (Y)", "--------", {"2", "2", "2", "1/2"}, "alias for ldd Rd, Y+0"}, - {OP_ID(ld_yp), 0xfe0f, 0x9009, 1, OP_AVR2, "1001 000d dddd 1001", OTY_XFRX|OTY_RALL|OTY_YWRN, - "ld", "Rd, Y+", "load indirect and post-increment", "Rd <-- (Y), Y <-- Y + 1", "--------", + {OP_ID(ld_yp), 0xfe0f, 0x9009, 1, OP_AVR2, "1001 000d dddd 1001", OTY_XFRX | OTY_RALL | OTY_YWRN, + "ld", "Rd, Y+", "load indirect and post-increment", "Rd <-- (Y), Y <-- Y + 1", "--------", {"2", "2", "2", "2/3"}, ""}, - {OP_ID(ld_my), 0xfe0f, 0x900a, 1, OP_AVR2, "1001 000d dddd 1010", OTY_XFRX|OTY_RALL|OTY_YWRN, - "ld", "Rd, -Y", "load indirect and pre-decrement", "Y <-- Y - 1 Rd <-- (Y)", "--------", + {OP_ID(ld_my), 0xfe0f, 0x900a, 1, OP_AVR2, "1001 000d dddd 1010", OTY_XFRX | OTY_RALL | OTY_YWRN, + "ld", "Rd, -Y", "load indirect and pre-decrement", "Y <-- Y - 1 Rd <-- (Y)", "--------", {"2", "3", "2", "2/3"}, ""}, - {OP_ID(ldd_y), 0xd208, 0x8008, 1, OP_AVR2nRC, "10q0 qq0d dddd 1qqq", OTY_XFRX|OTY_RALL, - "ldd", "Rd, Y+q", "load indirect with displacement", "Rd <-- (Y+q)", "--------", + {OP_ID(ldd_y), 0xd208, 0x8008, 1, OP_AVR2nRC, "10q0 qq0d dddd 1qqq", OTY_XFRX | OTY_RALL, + "ldd", "Rd, Y+q", "load indirect with displacement", "Rd <-- (Y+q)", "--------", {"2", "3", "2", "n/a"}, ""}, - {OP_ID(ld_z), 0xfe0f, 0x8000, 1, OP_AVR1, "1000 000d dddd 0000", OTY_XFRX|OTY_RALL, - "ld", "Rd, Z", "load indirect", "Rd <-- (Z)", "--------", + {OP_ID(ld_z), 0xfe0f, 0x8000, 1, OP_AVR1, "1000 000d dddd 0000", OTY_XFRX | OTY_RALL, + "ld", "Rd, Z", "load indirect", "Rd <-- (Z)", "--------", {"2", "2", "2", "1/2"}, "alias for ldd Rd, Z+0"}, - {OP_ID(ld_zp), 0xfe0f, 0x9001, 1, OP_AVR1, "1001 000d dddd 0001", OTY_XFRX|OTY_RALL|OTY_ZWRN, - "ld", "Rd, Z+", "load indirect and post-increment", "Rd <-- (Z), Z <-- Z + 1", "--------", + {OP_ID(ld_zp), 0xfe0f, 0x9001, 1, OP_AVR1, "1001 000d dddd 0001", OTY_XFRX | OTY_RALL | OTY_ZWRN, + "ld", "Rd, Z+", "load indirect and post-increment", "Rd <-- (Z), Z <-- Z + 1", "--------", {"2", "2", "2", "2/3"}, ""}, - {OP_ID(ld_mz), 0xfe0f, 0x9002, 1, OP_AVR1, "1001 000d dddd 0010", OTY_XFRX|OTY_RALL|OTY_ZWRN, - "ld", "Rd, -Z", "load indirect and pre-decrement", "Z <-- Z - 1, Rd <-- (Z)", "--------", + {OP_ID(ld_mz), 0xfe0f, 0x9002, 1, OP_AVR1, "1001 000d dddd 0010", OTY_XFRX | OTY_RALL | OTY_ZWRN, + "ld", "Rd, -Z", "load indirect and pre-decrement", "Z <-- Z - 1, Rd <-- (Z)", "--------", {"2", "3", "2", "2/3"}, ""}, - {OP_ID(ldd_z), 0xd208, 0x8000, 1, OP_AVR2nRC, "10q0 qq0d dddd 0qqq", OTY_XFRX|OTY_RALL, - "ldd", "Rd, Z+q", "load indirect with displacement", "Rd <-- (Z+q)", "--------", + {OP_ID(ldd_z), 0xd208, 0x8000, 1, OP_AVR2nRC, "10q0 qq0d dddd 0qqq", OTY_XFRX | OTY_RALL, + "ldd", "Rd, Z+q", "load indirect with displacement", "Rd <-- (Z+q)", "--------", {"2", "3", "2", "n/a"}, ""}, - {OP_ID(sts), 0xfe0f, 0x9200, 2, OP_AVR2nRC, "1001 001r rrrr 0000 kkkk kkkk kkkk kkkk", OTY_XFRX|OTY_RALL, - "sts", "k, Rr", "store direct to data space", "(k) <-- Rr", "--------", + {OP_ID(sts), 0xfe0f, 0x9200, 2, OP_AVR2nRC, "1001 001r rrrr 0000 kkkk kkkk kkkk kkkk", OTY_XFRX | OTY_RALL, + "sts", "k, Rr", "store direct to data space", "(k) <-- Rr", "--------", {"2", "2", "2", "1"}, ""}, - {OP_ID(st_x), 0xfe0f, 0x920c, 1, OP_AVR2, "1001 001r rrrr 1100", OTY_XFRX|OTY_RALL, - "st", "X, Rr", "store indirect", "(X) <-- Rr", "--------", + {OP_ID(st_x), 0xfe0f, 0x920c, 1, OP_AVR2, "1001 001r rrrr 1100", OTY_XFRX | OTY_RALL, + "st", "X, Rr", "store indirect", "(X) <-- Rr", "--------", {"2", "1", "1", "1"}, ""}, - {OP_ID(st_xp), 0xfe0f, 0x920d, 1, OP_AVR2, "1001 001r rrrr 1101", OTY_XFRX|OTY_RALL|OTY_XWRN, - "st", "X+, Rr", "store indirect and post-increment", "(X) <-- Rr, X <-- X + 1", "--------", + {OP_ID(st_xp), 0xfe0f, 0x920d, 1, OP_AVR2, "1001 001r rrrr 1101", OTY_XFRX | OTY_RALL | OTY_XWRN, + "st", "X+, Rr", "store indirect and post-increment", "(X) <-- Rr, X <-- X + 1", "--------", {"2", "1", "1", "1"}, ""}, - {OP_ID(st_mx), 0xfe0f, 0x920e, 1, OP_AVR2, "1001 001r rrrr 1110", OTY_XFRX|OTY_RALL|OTY_XWRN, - "st", "-X, Rr", "store indirect and pre-decrement", "X <-- X - 1, (X) <-- Rr", "--------", + {OP_ID(st_mx), 0xfe0f, 0x920e, 1, OP_AVR2, "1001 001r rrrr 1110", OTY_XFRX | OTY_RALL | OTY_XWRN, + "st", "-X, Rr", "store indirect and pre-decrement", "X <-- X - 1, (X) <-- Rr", "--------", {"2", "2", "1", "1"}, ""}, - {OP_ID(st_y), 0xfe0f, 0x8208, 1, OP_AVR2, "1000 001r rrrr 1000", OTY_XFRX|OTY_RALL, - "st", "Y, Rr", "store indirect", "(Y) <-- Rr", "--------", + {OP_ID(st_y), 0xfe0f, 0x8208, 1, OP_AVR2, "1000 001r rrrr 1000", OTY_XFRX | OTY_RALL, + "st", "Y, Rr", "store indirect", "(Y) <-- Rr", "--------", {"2", "1", "1", "1"}, "alias for std Y+0, Rr"}, - {OP_ID(st_yp), 0xfe0f, 0x9209, 1, OP_AVR2, "1001 001r rrrr 1001", OTY_XFRX|OTY_RALL|OTY_YWRN, - "st", "Y+, Rr", "store indirect and post-increment", "(Y) <-- Rr, Y <-- Y + 1", "--------", + {OP_ID(st_yp), 0xfe0f, 0x9209, 1, OP_AVR2, "1001 001r rrrr 1001", OTY_XFRX | OTY_RALL | OTY_YWRN, + "st", "Y+, Rr", "store indirect and post-increment", "(Y) <-- Rr, Y <-- Y + 1", "--------", {"2", "1", "1", "1"}, ""}, - {OP_ID(st_my), 0xfe0f, 0x920a, 1, OP_AVR2, "1001 001r rrrr 1010", OTY_XFRX|OTY_RALL|OTY_YWRN, - "st", "-Y, Rr", "store indirect and pre-decrement", "Y <-- Y - 1, (Y) <-- Rr", "--------", + {OP_ID(st_my), 0xfe0f, 0x920a, 1, OP_AVR2, "1001 001r rrrr 1010", OTY_XFRX | OTY_RALL | OTY_YWRN, + "st", "-Y, Rr", "store indirect and pre-decrement", "Y <-- Y - 1, (Y) <-- Rr", "--------", {"2", "2", "1", "1"}, ""}, - {OP_ID(std_y), 0xd208, 0x8208, 1, OP_AVR2nRC, "10q0 qq1r rrrr 1qqq", OTY_XFRX|OTY_RALL, - "std", "Y+q, Rr", "store indirect with displacement", "(Y+q) <-- Rr", "--------", + {OP_ID(std_y), 0xd208, 0x8208, 1, OP_AVR2nRC, "10q0 qq1r rrrr 1qqq", OTY_XFRX | OTY_RALL, + "std", "Y+q, Rr", "store indirect with displacement", "(Y+q) <-- Rr", "--------", {"2", "2", "1", "n/a"}, ""}, - {OP_ID(st_z), 0xfe0f, 0x8200, 1, OP_AVR1, "1000 001r rrrr 0000", OTY_XFRX|OTY_RALL, - "st", "Z, Rr", "store indirect", "(Z) <-- Rr", "--------", + {OP_ID(st_z), 0xfe0f, 0x8200, 1, OP_AVR1, "1000 001r rrrr 0000", OTY_XFRX | OTY_RALL, + "st", "Z, Rr", "store indirect", "(Z) <-- Rr", "--------", {"2", "1", "1", "1"}, "alias for std Z+0, Rr"}, - {OP_ID(st_zp), 0xfe0f, 0x9201, 1, OP_AVR1, "1001 001r rrrr 0001", OTY_XFRX|OTY_RALL|OTY_ZWRN, - "st", "Z+, Rr", "store indirect and post-increment", "(Z) <-- Rr, Z <-- Z + 1", "--------", + {OP_ID(st_zp), 0xfe0f, 0x9201, 1, OP_AVR1, "1001 001r rrrr 0001", OTY_XFRX | OTY_RALL | OTY_ZWRN, + "st", "Z+, Rr", "store indirect and post-increment", "(Z) <-- Rr, Z <-- Z + 1", "--------", {"2", "1", "1", "1"}, ""}, - {OP_ID(st_mz), 0xfe0f, 0x9202, 1, OP_AVR1, "1001 001r rrrr 0010", OTY_XFRX|OTY_RALL|OTY_ZWRN, - "st", "-Z, Rr", "store indirect and pre-decrement", "Z <-- Z - 1, (Z) <-- Rr", "--------", + {OP_ID(st_mz), 0xfe0f, 0x9202, 1, OP_AVR1, "1001 001r rrrr 0010", OTY_XFRX | OTY_RALL | OTY_ZWRN, + "st", "-Z, Rr", "store indirect and pre-decrement", "Z <-- Z - 1, (Z) <-- Rr", "--------", {"2", "2", "1", "1"}, ""}, - {OP_ID(std_z), 0xd208, 0x8200, 1, OP_AVR2nRC, "10q0 qq1r rrrr 0qqq", OTY_XFRX|OTY_RALL, - "std", "Z+q, Rr", "store indirect with displacement", "(Z+q) <-- Rr", "--------", + {OP_ID(std_z), 0xd208, 0x8200, 1, OP_AVR2nRC, "10q0 qq1r rrrr 0qqq", OTY_XFRX | OTY_RALL, + "std", "Z+q, Rr", "store indirect with displacement", "(Z+q) <-- Rr", "--------", {"2", "2", "1", "n/a"}, ""}, - {OP_ID(lpm_0), 0xffff, 0x95c8, 1, OP_AVR1nRC, "1001 0101 1100 1000", OTY_XFRX, - "lpm", "", "load program memory", "R0 <-- (Z)", "--------", + {OP_ID(lpm_0), 0xffff, 0x95c8, 1, OP_AVR1nRC, "1001 0101 1100 1000", OTY_XFRX, + "lpm", "", "load program memory", "R0 <-- (Z)", "--------", {"3", "3", "3", "n/a"}, ""}, - {OP_ID(lpm_z), 0xfe0f, 0x9004, 1, OP_AVR25, "1001 000d dddd 0100", OTY_XFRX|OTY_RALL, - "lpm", "Rd, Z", "load program memory", "Rd <-- (Z)", "--------", + {OP_ID(lpm_z), 0xfe0f, 0x9004, 1, OP_AVR25, "1001 000d dddd 0100", OTY_XFRX | OTY_RALL, + "lpm", "Rd, Z", "load program memory", "Rd <-- (Z)", "--------", {"3", "3", "3", "n/a"}, ""}, - {OP_ID(lpm_zp), 0xfe0f, 0x9005, 1, OP_AVR25, "1001 000d dddd 0101", OTY_XFRX|OTY_RALL|OTY_ZWRN, - "lpm", "Rd, Z+", "load program memory and post-increment", "Rd <-- (Z), Z <-- Z + 1", "--------", + {OP_ID(lpm_zp), 0xfe0f, 0x9005, 1, OP_AVR25, "1001 000d dddd 0101", OTY_XFRX | OTY_RALL | OTY_ZWRN, + "lpm", "Rd, Z+", "load program memory and post-increment", "Rd <-- (Z), Z <-- Z + 1", "--------", {"3", "3", "3", "n/a"}, ""}, - {OP_ID(elpm_0), 0xffff, 0x95d8, 1, OP_AVR_L, "1001 0101 1101 1000", OTY_XFRX, - "elpm", "", "extended load program memory", "R0 <-- (RAMPZ:Z)", "--------", + {OP_ID(elpm_0), 0xffff, 0x95d8, 1, OP_AVR_L, "1001 0101 1101 1000", OTY_XFRX, + "elpm", "", "extended load program memory", "R0 <-- (RAMPZ:Z)", "--------", {"3", "3", "3", "n/a"}, ""}, - {OP_ID(elpm_z), 0xfe0f, 0x9006, 1, OP_AVR_L, "1001 000d dddd 0110", OTY_XFRX|OTY_RALL, - "elpm", "Rd, Z", "extended load program memory", "Rd <-- (RAMPZ:Z)", "--------", + {OP_ID(elpm_z), 0xfe0f, 0x9006, 1, OP_AVR_L, "1001 000d dddd 0110", OTY_XFRX | OTY_RALL, + "elpm", "Rd, Z", "extended load program memory", "Rd <-- (RAMPZ:Z)", "--------", {"3", "3", "3", "n/a"}, ""}, - {OP_ID(elpm_zp), 0xfe0f, 0x9007, 1, OP_AVR_L, "1001 000d dddd 0111", OTY_XFRX|OTY_RALL|OTY_ZWRN, - "elpm", "Rd, Z+", "extended load program memory and post-increment", "Rd <-- (RAMPZ:Z), Z <-- Z + 1", "--------", + {OP_ID(elpm_zp), 0xfe0f, 0x9007, 1, OP_AVR_L, "1001 000d dddd 0111", OTY_XFRX | OTY_RALL | OTY_ZWRN, + "elpm", "Rd, Z+", "extended load program memory and post-increment", "Rd <-- (RAMPZ:Z), Z <-- Z + 1", "--------", {"3", "3", "3", "n/a"}, ""}, - {OP_ID(spm), 0xffff, 0x95e8, 1, OP_AVR25, "1001 0101 1110 1000", OTY_XFRX, - "spm", "", "store program memory", "(RAMPZ:Z) <-- R1:R0", "--------", + {OP_ID(spm), 0xffff, 0x95e8, 1, OP_AVR25, "1001 0101 1110 1000", OTY_XFRX, + "spm", "", "store program memory", "(RAMPZ:Z) <-- R1:R0", "--------", {"-", "-", "-", "-"}, ""}, - {OP_ID(spm_zp), 0xffff, 0x95f8, 1, OP_AVR_XTM, "1001 0101 1111 1000", OTY_XFRX, - "spm", "Z+", "store program memory and post-increment by 2", "(RAMPZ:Z) <-- R1:R0, Z <-- Z + 2", "--------", + {OP_ID(spm_zp), 0xffff, 0x95f8, 1, OP_AVR_XTM, "1001 0101 1111 1000", OTY_XFRX, + "spm", "Z+", "store program memory and post-increment by 2", "(RAMPZ:Z) <-- R1:R0, Z <-- Z + 2", "--------", {"n/a", "-", "-", "n/a"}, ""}, - {OP_ID(in), 0xf800, 0xb000, 1, OP_AVR1, "1011 0AAd dddd AAAA", OTY_XFRX|OTY_RALL, - "in", "Rd, A", "in from I/O location", "Rd <-- I/O(A)", "--------", + {OP_ID(in), 0xf800, 0xb000, 1, OP_AVR1, "1011 0AAd dddd AAAA", OTY_XFRX | OTY_RALL, + "in", "Rd, A", "in from I/O location", "Rd <-- I/O(A)", "--------", {"1", "1", "1", "1"}, ""}, - {OP_ID(out), 0xf800, 0xb800, 1, OP_AVR1, "1011 1AAr rrrr AAAA", OTY_XFRX|OTY_RALL, - "out", "A, Rr", "out to I/O location", "I/O(A) <-- Rr", "--------", + {OP_ID(out), 0xf800, 0xb800, 1, OP_AVR1, "1011 1AAr rrrr AAAA", OTY_XFRX | OTY_RALL, + "out", "A, Rr", "out to I/O location", "I/O(A) <-- Rr", "--------", {"1", "1", "1", "1"}, ""}, - {OP_ID(push), 0xfe0f, 0x920f, 1, OP_AVR2, "1001 001r rrrr 1111", OTY_XFRX|OTY_RALL, - "push", "Rr", "push register on stack", "STACK <-- Rr, SP <-- SP - 2", "--------", + {OP_ID(push), 0xfe0f, 0x920f, 1, OP_AVR2, "1001 001r rrrr 1111", OTY_XFRX | OTY_RALL, + "push", "Rr", "push register on stack", "STACK <-- Rr, SP <-- SP - 2", "--------", {"2", "1", "1", "1"}, ""}, - {OP_ID(pop), 0xfe0f, 0x900f, 1, OP_AVR2, "1001 000d dddd 1111", OTY_XFRX|OTY_RALL, - "pop", "Rd", "pop register from stack", "SP <-- SP + 2, Rd <-- STACK", "--------", + {OP_ID(pop), 0xfe0f, 0x900f, 1, OP_AVR2, "1001 000d dddd 1111", OTY_XFRX | OTY_RALL, + "pop", "Rd", "pop register from stack", "SP <-- SP + 2, Rd <-- STACK", "--------", {"2", "2", "2", "3"}, ""}, - {OP_ID(xch), 0xfe0f, 0x9204, 1, OP_AVR_XM, "1001 001d dddd 0100", OTY_XFRX|OTY_RALL, - "xch", "Z, Rd", "exchange", "(Z) <-- Rd, Rd <-- (Z)", "--------", + {OP_ID(xch), 0xfe0f, 0x9204, 1, OP_AVR_XM, "1001 001d dddd 0100", OTY_XFRX | OTY_RALL, + "xch", "Z, Rd", "exchange", "(Z) <-- Rd, Rd <-- (Z)", "--------", {"n/a", "1", "n/a", "n/a"}, ""}, - {OP_ID(las), 0xfe0f, 0x9205, 1, OP_AVR_XM, "1001 001d dddd 0101", OTY_ALBX|OTY_RALL, - "las", "Z, Rd", "load and set", "(Z) <-- Rd | (Z), Rd <-- (Z)", "--------", + {OP_ID(las), 0xfe0f, 0x9205, 1, OP_AVR_XM, "1001 001d dddd 0101", OTY_ALBX | OTY_RALL, + "las", "Z, Rd", "load and set", "(Z) <-- Rd | (Z), Rd <-- (Z)", "--------", {"n/a", "1", "n/a", "n/a"}, ""}, - {OP_ID(lac), 0xfe0f, 0x9206, 1, OP_AVR_XM, "1001 001d dddd 0110", OTY_ALBX|OTY_RALL, - "lac", "Z, Rd", "load and clear", "(Z) <-- (0xff - Rd) & (Z), Rd <-- (Z)", "--------", + {OP_ID(lac), 0xfe0f, 0x9206, 1, OP_AVR_XM, "1001 001d dddd 0110", OTY_ALBX | OTY_RALL, + "lac", "Z, Rd", "load and clear", "(Z) <-- (0xff - Rd) & (Z), Rd <-- (Z)", "--------", {"n/a", "1", "n/a", "n/a"}, ""}, - {OP_ID(lat), 0xfe0f, 0x9207, 1, OP_AVR_XM, "1001 001d dddd 0111", OTY_ALBX|OTY_RALL, - "lat", "Z, Rd", "load and toggle", "(Z) <-- Rd ^ (Z), Rd <-- (Z)", "--------", + {OP_ID(lat), 0xfe0f, 0x9207, 1, OP_AVR_XM, "1001 001d dddd 0111", OTY_ALBX | OTY_RALL, + "lat", "Z, Rd", "load and toggle", "(Z) <-- Rd ^ (Z), Rd <-- (Z)", "--------", {"n/a", "1", "n/a", "n/a"}, ""}, // Bit and Bit-test Instructions - {OP_ID(lsr), 0xfe0f, 0x9406, 1, OP_AVR1, "1001 010d dddd 0110", OTY_ALBI|OTY_RALL, - "lsr", "Rd", "logical shift right", "0 --> Rd(7) --> Rd(6) ... Rd(1) --> Rd(0) --> C", "----VNZC", + {OP_ID(lsr), 0xfe0f, 0x9406, 1, OP_AVR1, "1001 010d dddd 0110", OTY_ALBI | OTY_RALL, + "lsr", "Rd", "logical shift right", "0 --> Rd(7) --> Rd(6) ... Rd(1) --> Rd(0) --> C", "----VNZC", {"1", "1", "1", "1"}, ""}, - {OP_ID(swap), 0xfe0f, 0x9402, 1, OP_AVR1, "1001 010d dddd 0010", OTY_ALBI|OTY_RALL, - "swap", "Rd", "swap nibbles", "Rd(3..0) <--> Rd(7..4)", "--------", + {OP_ID(swap), 0xfe0f, 0x9402, 1, OP_AVR1, "1001 010d dddd 0010", OTY_ALBI | OTY_RALL, + "swap", "Rd", "swap nibbles", "Rd(3..0) <--> Rd(7..4)", "--------", {"1", "1", "1", "1"}, ""}, - {OP_ID(sbi), 0xff00, 0x9a00, 1, OP_AVR1, "1001 1010 AAAA Abbb", OTY_ALBX, - "sbi", "A, b", "set bit in I/O register", "I/O(A,b) <-- 1", "--------", + {OP_ID(sbi), 0xff00, 0x9a00, 1, OP_AVR1, "1001 1010 AAAA Abbb", OTY_ALBX, + "sbi", "A, b", "set bit in I/O register", "I/O(A,b) <-- 1", "--------", {"2", "1", "1", "1"}, ""}, - {OP_ID(cbi), 0xff00, 0x9800, 1, OP_AVR1, "1001 1000 AAAA Abbb", OTY_ALBX, - "cbi", "A, b", "clear bit in I/O register", "I/O(A,b) <-- 0", "--------", + {OP_ID(cbi), 0xff00, 0x9800, 1, OP_AVR1, "1001 1000 AAAA Abbb", OTY_ALBX, + "cbi", "A, b", "clear bit in I/O register", "I/O(A,b) <-- 0", "--------", {"2", "1", "1", "1"}, ""}, - {OP_ID(bst), 0xfe08, 0xfa00, 1, OP_AVR1, "1111 101r rrrr 0bbb", OTY_ALBI|OTY_RALL, - "bst", "Rr, b", "bit store from register to T", "T <-- Rr(b)", "-T------", + {OP_ID(bst), 0xfe08, 0xfa00, 1, OP_AVR1, "1111 101r rrrr 0bbb", OTY_ALBI | OTY_RALL, + "bst", "Rr, b", "bit store from register to T", "T <-- Rr(b)", "-T------", {"1", "1", "1", "1"}, ""}, - {OP_ID(bld), 0xfe08, 0xf800, 1, OP_AVR1, "1111 100d dddd 0bbb", OTY_ALBI|OTY_RALL, - "bld", "Rd, b", "bit load from T to register", "Rd(b) <-- T", "--------", + {OP_ID(bld), 0xfe08, 0xf800, 1, OP_AVR1, "1111 100d dddd 0bbb", OTY_ALBI | OTY_RALL, + "bld", "Rd, b", "bit load from T to register", "Rd(b) <-- T", "--------", {"1", "1", "1", "1"}, ""}, - {OP_ID(sec), 0xffff, 0x9408, 1, OP_AVR1, "1001 0100 0000 1000", OTY_ALBI, - "sec", "", "set carry", "C <-- 1", "-------C", + {OP_ID(sec), 0xffff, 0x9408, 1, OP_AVR1, "1001 0100 0000 1000", OTY_ALBI, + "sec", "", "set carry", "C <-- 1", "-------C", {"1", "1", "1", "1"}, "alias for bset 0"}, - {OP_ID(clc), 0xffff, 0x9488, 1, OP_AVR1, "1001 0100 1000 1000", OTY_ALBI, - "clc", "", "clear carry", "C <-- 0", "-------C", + {OP_ID(clc), 0xffff, 0x9488, 1, OP_AVR1, "1001 0100 1000 1000", OTY_ALBI, + "clc", "", "clear carry", "C <-- 0", "-------C", {"1", "1", "1", "1"}, "alias for bclr 0"}, - {OP_ID(sen), 0xffff, 0x9428, 1, OP_AVR1, "1001 0100 0010 1000", OTY_ALBI, - "sen", "", "set negative flag", "N <-- 1", "-----N--", + {OP_ID(sen), 0xffff, 0x9428, 1, OP_AVR1, "1001 0100 0010 1000", OTY_ALBI, + "sen", "", "set negative flag", "N <-- 1", "-----N--", {"1", "1", "1", "1"}, "alias for bset 2"}, - {OP_ID(cln), 0xffff, 0x94a8, 1, OP_AVR1, "1001 0100 1010 1000", OTY_ALBI, - "cln", "", "clear negative flag", "N <-- 0", "-----N--", + {OP_ID(cln), 0xffff, 0x94a8, 1, OP_AVR1, "1001 0100 1010 1000", OTY_ALBI, + "cln", "", "clear negative flag", "N <-- 0", "-----N--", {"1", "1", "1", "1"}, "alias for bclr 2"}, - {OP_ID(sez), 0xffff, 0x9418, 1, OP_AVR1, "1001 0100 0001 1000", OTY_ALBI, - "sez", "", "set zero flag", "Z <-- 1", "------Z-", + {OP_ID(sez), 0xffff, 0x9418, 1, OP_AVR1, "1001 0100 0001 1000", OTY_ALBI, + "sez", "", "set zero flag", "Z <-- 1", "------Z-", {"1", "1", "1", "1"}, "alias for bset 1"}, - {OP_ID(clz), 0xffff, 0x9498, 1, OP_AVR1, "1001 0100 1001 1000", OTY_ALBI, - "clz", "", "clear zero flag", "Z <-- 0", "------Z-", + {OP_ID(clz), 0xffff, 0x9498, 1, OP_AVR1, "1001 0100 1001 1000", OTY_ALBI, + "clz", "", "clear zero flag", "Z <-- 0", "------Z-", {"1", "1", "1", "1"}, "alias for bclr 1"}, - {OP_ID(sei), 0xffff, 0x9478, 1, OP_AVR1, "1001 0100 0111 1000", OTY_ALBX, - "sei", "", "global interrupt enable", "I <-- 1", "I-------", + {OP_ID(sei), 0xffff, 0x9478, 1, OP_AVR1, "1001 0100 0111 1000", OTY_ALBX, + "sei", "", "global interrupt enable", "I <-- 1", "I-------", {"1", "1", "1", "1"}, "alias for bset 7"}, - {OP_ID(cli), 0xffff, 0x94f8, 1, OP_AVR1, "1001 0100 1111 1000", OTY_ALBI, - "cli", "", "global interrupt disable", "I <-- 0", "I-------", + {OP_ID(cli), 0xffff, 0x94f8, 1, OP_AVR1, "1001 0100 1111 1000", OTY_ALBI, + "cli", "", "global interrupt disable", "I <-- 0", "I-------", {"1", "1", "1", "1"}, "alias for bclr 7"}, - {OP_ID(ses), 0xffff, 0x9448, 1, OP_AVR1, "1001 0100 0100 1000", OTY_ALBI, - "ses", "", "set signed test flag", "S <-- 1", "---S----", + {OP_ID(ses), 0xffff, 0x9448, 1, OP_AVR1, "1001 0100 0100 1000", OTY_ALBI, + "ses", "", "set signed test flag", "S <-- 1", "---S----", {"1", "1", "1", "1"}, "alias for bset 4"}, - {OP_ID(cls), 0xffff, 0x94c8, 1, OP_AVR1, "1001 0100 1100 1000", OTY_ALBI, - "cls", "", "clear signed test flag", "S <-- 0", "---S----", + {OP_ID(cls), 0xffff, 0x94c8, 1, OP_AVR1, "1001 0100 1100 1000", OTY_ALBI, + "cls", "", "clear signed test flag", "S <-- 0", "---S----", {"1", "1", "1", "1"}, "alias for bclr 4"}, - {OP_ID(sev), 0xffff, 0x9438, 1, OP_AVR1, "1001 0100 0011 1000", OTY_ALBI, - "sev", "", "set two's complement overflow", "V <-- 1", "----V---", + {OP_ID(sev), 0xffff, 0x9438, 1, OP_AVR1, "1001 0100 0011 1000", OTY_ALBI, + "sev", "", "set two's complement overflow", "V <-- 1", "----V---", {"1", "1", "1", "1"}, "alias for bset 3"}, - {OP_ID(clv), 0xffff, 0x94b8, 1, OP_AVR1, "1001 0100 1011 1000", OTY_ALBI, - "clv", "", "clear two's complement overflow", "V <-- 0", "----V---", + {OP_ID(clv), 0xffff, 0x94b8, 1, OP_AVR1, "1001 0100 1011 1000", OTY_ALBI, + "clv", "", "clear two's complement overflow", "V <-- 0", "----V---", {"1", "1", "1", "1"}, "alias for bclr 3"}, - {OP_ID(set), 0xffff, 0x9468, 1, OP_AVR1, "1001 0100 0110 1000", OTY_ALBI, - "set", "", "set T in sreg", "T <-- 1", "-T------", + {OP_ID(set), 0xffff, 0x9468, 1, OP_AVR1, "1001 0100 0110 1000", OTY_ALBI, + "set", "", "set T in sreg", "T <-- 1", "-T------", {"1", "1", "1", "1"}, "alias for bset 6"}, - {OP_ID(clt), 0xffff, 0x94e8, 1, OP_AVR1, "1001 0100 1110 1000", OTY_ALBI, - "clt", "", "clear T in sreg", "T <-- 0", "-T------", + {OP_ID(clt), 0xffff, 0x94e8, 1, OP_AVR1, "1001 0100 1110 1000", OTY_ALBI, + "clt", "", "clear T in sreg", "T <-- 0", "-T------", {"1", "1", "1", "1"}, "alias for bclr 6"}, - {OP_ID(seh), 0xffff, 0x9458, 1, OP_AVR1, "1001 0100 0101 1000", OTY_ALBI, - "seh", "", "set half-carry flag in sreg", "H <-- 1", "--H-----", + {OP_ID(seh), 0xffff, 0x9458, 1, OP_AVR1, "1001 0100 0101 1000", OTY_ALBI, + "seh", "", "set half-carry flag in sreg", "H <-- 1", "--H-----", {"1", "1", "1", "1"}, "alias for bset 5"}, - {OP_ID(clh), 0xffff, 0x94d8, 1, OP_AVR1, "1001 0100 1101 1000", OTY_ALBI, - "clh", "", "clear half-carry flag in sreg", "H <-- 0", "--H-----", + {OP_ID(clh), 0xffff, 0x94d8, 1, OP_AVR1, "1001 0100 1101 1000", OTY_ALBI, + "clh", "", "clear half-carry flag in sreg", "H <-- 0", "--H-----", {"1", "1", "1", "1"}, "alias for bclr 5"}, - {OP_ID(bset), 0xff8f, 0x9408, 1, OP_AVR1, "1001 0100 0sss 1000", OTY_ALBX, - "bset", "s", "flag set", "SREG(s) <-- 1", "SREG-bit", + {OP_ID(bset), 0xff8f, 0x9408, 1, OP_AVR1, "1001 0100 0sss 1000", OTY_ALBX, + "bset", "s", "flag set", "SREG(s) <-- 1", "SREG-bit", {"1", "1", "1", "1"}, "s = 0-7 = C,Z,N,V,S,H,T,I"}, - {OP_ID(bclr), 0xff8f, 0x9488, 1, OP_AVR1, "1001 0100 1sss 1000", OTY_ALBI, - "bclr", "s", "flag clear", "SREG(s) <-- 0", "SREG-bit", + {OP_ID(bclr), 0xff8f, 0x9488, 1, OP_AVR1, "1001 0100 1sss 1000", OTY_ALBI, + "bclr", "s", "flag clear", "SREG(s) <-- 0", "SREG-bit", {"1", "1", "1", "1"}, "s = 0-7 = C,Z,N,V,S,H,T,I"}, // MCU Control Instructions - {OP_ID(break), 0xffff, 0x9598, 1, OP_AVR1, "1001 0101 1001 1000", OTY_MCUX, - "break", "", "break", "on-chip debug system breakpoint", "--------", + {OP_ID(break), 0xffff, 0x9598, 1, OP_AVR1, "1001 0101 1001 1000", OTY_MCUX, + "break", "", "break", "on-chip debug system breakpoint", "--------", {"-", "-", "-", "-"}, "not available on all parts"}, - {OP_ID(nop), 0xffff, 0x0000, 1, OP_AVR1, "0000 0000 0000 0000", OTY_MCUI, - "nop", "", "no operation", "-", "--------", + {OP_ID(nop), 0xffff, 0x0000, 1, OP_AVR1, "0000 0000 0000 0000", OTY_MCUI, + "nop", "", "no operation", "-", "--------", {"1", "1", "1", "1"}, ""}, - {OP_ID(sleep), 0xffff, 0x9588, 1, OP_AVR1, "1001 0101 1000 1000", OTY_MCUX, - "sleep", "", "sleep", "sleep mode defined by the MCU control register", "--------", + {OP_ID(sleep), 0xffff, 0x9588, 1, OP_AVR1, "1001 0101 1000 1000", OTY_MCUX, + "sleep", "", "sleep", "sleep mode defined by the MCU control register", "--------", {"-", "-", "-", "-"}, ""}, - {OP_ID(wdr), 0xffff, 0x95a8, 1, OP_AVR1, "1001 0101 1010 1000", OTY_MCUI, - "wdr", "", "watchdog reset", "reset the watchdog timer", "--------", + {OP_ID(wdr), 0xffff, 0x95a8, 1, OP_AVR1, "1001 0101 1010 1000", OTY_MCUI, + "wdr", "", "watchdog reset", "reset the watchdog timer", "--------", {"1", "1", "1", "1"}, ""}, /* * Special 16-bit lds/sts opcodes for reduced-core ATtinys only; they conflict with * regular ldd Rd, Y+q; ldd Rd, Z+q; std Y+q, Rr; std Z+q, Rr opcodes */ - {OP_ID(lds_rc), 0xf800, 0xa000, 1, OP_AVR_RC, "1010 0aaa dddd aaaa", OTY_XFRX|OTY_RUPP, - "lds", "Rd, a", "load direct from data space", "Rd <-- (a)", "--------", + {OP_ID(lds_rc), 0xf800, 0xa000, 1, OP_AVR_RC, "1010 0aaa dddd aaaa", OTY_XFRX | OTY_RUPP, + "lds", "Rd, a", "load direct from data space", "Rd <-- (a)", "--------", {"n/a", "n/a", "n/a", "2"}, "AVRrc only (TPI parts); a = 0x40..0xbf"}, - {OP_ID(sts_rc), 0xf800, 0xa800, 1, OP_AVR_RC, "1010 1aaa rrrr aaaa", OTY_XFRX|OTY_RUPP, - "sts", "a, Rr", "store direct to data space", "(a) <-- Rr", "--------", + {OP_ID(sts_rc), 0xf800, 0xa800, 1, OP_AVR_RC, "1010 1aaa rrrr aaaa", OTY_XFRX | OTY_RUPP, + "sts", "a, Rr", "store direct to data space", "(a) <-- Rr", "--------", {"n/a", "n/a", "n/a", "1"}, "AVRrc only (TPI parts); a = 0x40..0xbf"}, // Undocumented opcodes: they are said(!) to do the following - {OP_ID(u_nop_1), 0xff00, 0x0000, 1, OP_AVR_ILL, "0000 0000 xxxx xxxx", OTY_MCUI, - "u/nop", "", "no operation", "-", "--------", + {OP_ID(u_nop_1), 0xff00, 0x0000, 1, OP_AVR_ILL, "0000 0000 xxxx xxxx", OTY_MCUI, + "u/nop", "", "no operation", "-", "--------", {"1", "1", "1", "1"}, "xxxx xxxx != 0000 0000"}, - {OP_ID(u_nop_2), 0xfe0f, 0x9003, 1, OP_AVR_ILL, "1001 000x xxxx 0011", OTY_MCUI, - "u/nop", "", "no operation", "-", "--------", + {OP_ID(u_nop_2), 0xfe0f, 0x9003, 1, OP_AVR_ILL, "1001 000x xxxx 0011", OTY_MCUI, + "u/nop", "", "no operation", "-", "--------", {"1", "1", "1", "1"}, ""}, - {OP_ID(u_nop_3), 0xfe0f, 0x9008, 1, OP_AVR_ILL, "1001 000x xxxx 1000", OTY_MCUI, - "u/nop", "", "no operation", "-", "--------", + {OP_ID(u_nop_3), 0xfe0f, 0x9008, 1, OP_AVR_ILL, "1001 000x xxxx 1000", OTY_MCUI, + "u/nop", "", "no operation", "-", "--------", {"1", "1", "1", "1"}, ""}, - {OP_ID(u_nop_4), 0xfe0f, 0x900b, 1, OP_AVR_ILL, "1001 000x xxxx 1011", OTY_MCUI, - "u/nop", "", "no operation", "-", "--------", + {OP_ID(u_nop_4), 0xfe0f, 0x900b, 1, OP_AVR_ILL, "1001 000x xxxx 1011", OTY_MCUI, + "u/nop", "", "no operation", "-", "--------", {"1", "1", "1", "1"}, ""}, - {OP_ID(u_nop_5), 0xfe0f, 0x9203, 1, OP_AVR_ILL, "1001 001x xxxx 0011", OTY_MCUI, - "u/nop", "", "no operation", "-", "--------", + {OP_ID(u_nop_5), 0xfe0f, 0x9203, 1, OP_AVR_ILL, "1001 001x xxxx 0011", OTY_MCUI, + "u/nop", "", "no operation", "-", "--------", {"1", "1", "1", "1"}, ""}, - {OP_ID(u_nop_6), 0xfe0f, 0x9208, 1, OP_AVR_ILL, "1001 001x xxxx 1000", OTY_MCUI, - "u/nop", "", "no operation", "-", "--------", + {OP_ID(u_nop_6), 0xfe0f, 0x9208, 1, OP_AVR_ILL, "1001 001x xxxx 1000", OTY_MCUI, + "u/nop", "", "no operation", "-", "--------", {"1", "1", "1", "1"}, ""}, - {OP_ID(u_nop_7), 0xfe0f, 0x920b, 1, OP_AVR_ILL, "1001 001x xxxx 1011", OTY_MCUI, - "u/nop", "", "no operation", "-", "--------", + {OP_ID(u_nop_7), 0xfe0f, 0x920b, 1, OP_AVR_ILL, "1001 001x xxxx 1011", OTY_MCUI, + "u/nop", "", "no operation", "-", "--------", {"1", "1", "1", "1"}, ""}, - {OP_ID(u_icall), 0xff1f, 0x9509, 1, OP_AVR_ILL, "1001 0101 xxx0 1001", OTY_JMPX|OTY_ZWORD, - "u/icall", "", "indirect call to (Z)", "PC(15:0) <-- Z, PC(21:16) <-- 0", "--------", + {OP_ID(u_icall), 0xff1f, 0x9509, 1, OP_AVR_ILL, "1001 0101 xxx0 1001", OTY_JMPX | OTY_ZWORD, + "u/icall", "", "indirect call to (Z)", "PC(15:0) <-- Z, PC(21:16) <-- 0", "--------", {"3+", "2+", "2+", "3"}, "xxx != 000"}, - {OP_ID(u_eicall), 0xff1f, 0x9519, 1, OP_AVR_ILL, "1001 0101 xxx1 1001", OTY_JMPX|OTY_ZWORD, - "u/eicall", "", "extended indirect call to (Z)", "PC(15:0) <-- Z, PC(21:16) <-- EIND", "--------", + {OP_ID(u_eicall), 0xff1f, 0x9519, 1, OP_AVR_ILL, "1001 0101 xxx1 1001", OTY_JMPX | OTY_ZWORD, + "u/eicall", "", "extended indirect call to (Z)", "PC(15:0) <-- Z, PC(21:16) <-- EIND", "--------", {"4", "3", "3", "n/a"}, "xxx != 000"}, - {OP_ID(u_ret), 0xff9f, 0x9508, 1, OP_AVR_ILL, "1001 0101 0xx0 1000", OTY_JMPX, - "u/ret", "", "subroutine return", "SP --> SP + 2, PC <-- STACK", "--------", + {OP_ID(u_ret), 0xff9f, 0x9508, 1, OP_AVR_ILL, "1001 0101 0xx0 1000", OTY_JMPX, + "u/ret", "", "subroutine return", "SP --> SP + 2, PC <-- STACK", "--------", {"4+", "4+", "4+", "6"}, "xx != 00"}, - {OP_ID(u_reti), 0xff9f, 0x9518, 1, OP_AVR_ILL, "1001 0101 0xx1 1000", OTY_JMPX, - "u/reti", "", "interrupt return", "SP -> SP + 2, PC <-- STACK", "I-------", + {OP_ID(u_reti), 0xff9f, 0x9518, 1, OP_AVR_ILL, "1001 0101 0xx1 1000", OTY_JMPX, + "u/reti", "", "interrupt return", "SP -> SP + 2, PC <-- STACK", "I-------", {"4+", "4+", "4+", "6"}, "xx != 00"}, - {OP_ID(u_nop_8), 0xffff, 0x95b8, 1, OP_AVR_ILL, "1001 0101 1011 1000", OTY_MCUI, - "u/nop", "", "no operation", "-", "--------", + {OP_ID(u_nop_8), 0xffff, 0x95b8, 1, OP_AVR_ILL, "1001 0101 1011 1000", OTY_MCUI, + "u/nop", "", "no operation", "-", "--------", {"1", "1", "1", "1"}, ""}, - {OP_ID(u_nop_9), 0xfe0f, 0x9404, 1, OP_AVR_ILL, "1001 010x xxxx 0100", OTY_MCUI, - "u/nop", "", "no operation", "-", "--------", + {OP_ID(u_nop_9), 0xfe0f, 0x9404, 1, OP_AVR_ILL, "1001 010x xxxx 0100", OTY_MCUI, + "u/nop", "", "no operation", "-", "--------", {"1", "1", "1", "1"}, ""}, - {OP_ID(u_nop_a), 0xff0f, 0x950b, 1, OP_AVR_ILL, "1001 0101 xxxx 1011", OTY_MCUI, - "u/nop", "", "no operation", "-", "--------", + {OP_ID(u_nop_a), 0xff0f, 0x950b, 1, OP_AVR_ILL, "1001 0101 xxxx 1011", OTY_MCUI, + "u/nop", "", "no operation", "-", "--------", {"1", "1", "1", "1"}, ""}, - {OP_ID(u_ijmp), 0xff1f, 0x9409, 1, OP_AVR_ILL, "1001 0100 xxx0 1001", OTY_JMPI|OTY_ZWORD, - "u/ijmp", "", "indirect jump to (Z)", "PC(15:0) <-- Z, PC(21:16) <-- 0", "--------", + {OP_ID(u_ijmp), 0xff1f, 0x9409, 1, OP_AVR_ILL, "1001 0100 xxx0 1001", OTY_JMPI | OTY_ZWORD, + "u/ijmp", "", "indirect jump to (Z)", "PC(15:0) <-- Z, PC(21:16) <-- 0", "--------", {"2", "2", "2", "2"}, "xxx != 000"}, - {OP_ID(u_eijmp), 0xff1f, 0x9419, 1, OP_AVR_ILL, "1001 0100 xxx1 1001", OTY_JMPX|OTY_ZWORD, - "u/eijmp", "", "extended indirect jump to (Z)", "PC(15:0) <-- Z, PC(21:16) <-- EIND", "--------", + {OP_ID(u_eijmp), 0xff1f, 0x9419, 1, OP_AVR_ILL, "1001 0100 xxx1 1001", OTY_JMPX | OTY_ZWORD, + "u/eijmp", "", "extended indirect jump to (Z)", "PC(15:0) <-- Z, PC(21:16) <-- EIND", "--------", {"2", "2", "2", "n/a"}, "xxx != 000"}, - {OP_ID(u_bld), 0xfe08, 0xf808, 1, OP_AVR_ILL, "1111 100d dddd 1bbb", OTY_ALBI|OTY_RALL, - "u/bld", "Rd, b", "bit load from T to register", "Rd(b) <-- T", "--------", + {OP_ID(u_bld), 0xfe08, 0xf808, 1, OP_AVR_ILL, "1111 100d dddd 1bbb", OTY_ALBI | OTY_RALL, + "u/bld", "Rd, b", "bit load from T to register", "Rd(b) <-- T", "--------", {"1", "1", "1", "1"}, ""}, - {OP_ID(u_bst), 0xfe08, 0xfa08, 1, OP_AVR_ILL, "1111 101r rrrr 1bbb", OTY_ALBI|OTY_RALL, - "u/bst", "Rr, b", "bit store from register to T", "T <-- Rr(b)", "-T------", + {OP_ID(u_bst), 0xfe08, 0xfa08, 1, OP_AVR_ILL, "1111 101r rrrr 1bbb", OTY_ALBI | OTY_RALL, + "u/bst", "Rr, b", "bit store from register to T", "T <-- Rr(b)", "-T------", {"1", "1", "1", "1"}, ""}, - {OP_ID(u_sbrc), 0xfe08, 0xfc08, 1, OP_AVR_ILL, "1111 110r rrrr 1bbb", OTY_SKPI|OTY_RALL, - "u/sbrc", "Rr, b", "skip if bit in register cleared", "if(Rr(b)=0) PC <-- PC + 2/3", "--------", + {OP_ID(u_sbrc), 0xfe08, 0xfc08, 1, OP_AVR_ILL, "1111 110r rrrr 1bbb", OTY_SKPI | OTY_RALL, + "u/sbrc", "Rr, b", "skip if bit in register cleared", "if(Rr(b)=0) PC <-- PC + 2/3", "--------", {"1-3", "1-3", "1-3", "1/2"}, ""}, - {OP_ID(u_sbrs), 0xfe08, 0xfe08, 1, OP_AVR_ILL, "1111 111r rrrr 1bbb", OTY_SKPI|OTY_RALL, - "u/sbrs", "Rr, b", "skip if bit in register set", "if(Rr(b)=1) PC <-- PC + 2/3", "--------", + {OP_ID(u_sbrs), 0xfe08, 0xfe08, 1, OP_AVR_ILL, "1111 111r rrrr 1bbb", OTY_SKPI | OTY_RALL, + "u/sbrs", "Rr, b", "skip if bit in register set", "if(Rr(b)=1) PC <-- PC + 2/3", "--------", {"1-3", "1-3", "1-3", "1/2"}, ""}, }; @@ -595,7 +596,7 @@ int op16_is_mnemo(int op, AVR_mnemo mnemo) { return mnemo < 0 || mnemo >= MNEMO_N? 0: (op & avr_opcodes[mnemo].mask) != avr_opcodes[mnemo].value? 0: !(avr_opcodes[mnemo].type & OTY_CONSTRAINT)? 1: - (op>>0 & 15) == (op>>4 & 15) && (op>>9 & 1) == (op>>8 & 1); // Constraint Rd == Rr + (op >> 0 & 15) == (op >> 4 & 15) && (op >> 9 & 1) == (op >> 8 & 1); // Constraint Rd == Rr } // Return whether or not the given 16-bit opcode has a 16-bit address argument @@ -623,6 +624,7 @@ int ldi_K(int op) { // Returns bitmask of first character chr in bits static int bitmask_first_chr(const char *bits, int chr) { int ret = 0x8000; + for(const char *c = bits; *c && *c != chr && ret; c++) if(*c != ' ') ret >>= 1; @@ -637,6 +639,7 @@ AVR_mnemo opcode_mnemo(int op, int avrlevel) { if(avrlevel == PART_AVR_RC && (avr_opcodes[i].type & OTY_REG_MASK) == OTY_RALL) { // Reduced-core ATtiny does not have registers r0, ..., r15 int bmask; // Assert highest bit in 5-bit r/d is set + if((bmask = bitmask_first_chr(avr_opcodes[i].bits, 'r')) && !(op & bmask)) return MNEMO_NONE; if((bmask = bitmask_first_chr(avr_opcodes[i].bits, 'd')) && !(op & bmask)) @@ -650,35 +653,37 @@ AVR_mnemo opcode_mnemo(int op, int avrlevel) { // Is 16-bit opcode valid for AVR part with avrlevel architecture? int op16_is_valid(int op16, int avrlevel) { int mnemo = opcode_mnemo(op16, avrlevel); - return mnemo >= 0 && mnemo <= MNEMO_N; + + return mnemo >= 0 && mnemo <= MNEMO_N; } // Is 16-bit opcode valid and benign for AVR part with avrlevel architecture? -int op16_is_benign(int op16, int avrlevel) { // Benign means no I/O or SRAM is being read/written +int op16_is_benign(int op16, int avrlevel) { // Benign means no I/O or SRAM is being read/written int mnemo = opcode_mnemo(op16, avrlevel); - return mnemo >= 0 && mnemo <= MNEMO_N && !(avr_opcodes[mnemo].type & OTY_EXTERNAL); + + return mnemo >= 0 && mnemo <= MNEMO_N && !(avr_opcodes[mnemo].type & OTY_EXTERNAL); } // Opcodes in avr_opcodes[] that a part ought to be able to run int avr_get_archlevel(const AVRPART *p) { int ret = - p->prog_modes & PM_UPDI? PART_AVR_XT: - p->prog_modes & PM_PDI? PART_AVR_XM: - p->prog_modes & PM_TPI? PART_AVR_RC: 0; + is_updi(p)? PART_AVR_XT: is_pdi(p)? PART_AVR_XM: is_tpi(p)? PART_AVR_RC: 0; if(!ret) { // Non-TPI classic part switch(p->archnum) { case 1: ret = PART_AVR1; break; - default: // If AVRDUE doesn't know, it's probably rare & old + default: // If AVRDUE doesn't know, it's probably rare & old case 2: ret = PART_AVR2; break; case 25: ret = PART_AVR25; break; - case 3: case 31: case 35: // Sic + case 3: + case 31: + case 35: // Sic ret = PART_AVR3; break; break; @@ -691,12 +696,13 @@ int avr_get_archlevel(const AVRPART *p) { case 51: ret = PART_AVR51; break; - case 6: + case 6: ret = PART_AVR6; } } AVRMEM *mem = avr_locate_flash(p); + if(mem) { // Add opcodes needed for large parts in any case if(mem->size > 8192) ret |= OP_AVR_M; // JMP, CALL @@ -711,15 +717,13 @@ int avr_get_archlevel(const AVRPART *p) { // Index in the avr_opcodes[].clock[] array for timings of an opcode AVR_cycle_index avr_get_cycle_index(const AVRPART *p) { - return - p->prog_modes & PM_UPDI? OP_AVRxt: - p->prog_modes & PM_PDI? OP_AVRxm: - p->prog_modes & PM_TPI? OP_AVRrc: OP_AVRe; + return is_updi(p)? OP_AVRxt: is_pdi(p)? OP_AVRxm: is_tpi(p)? OP_AVRrc: OP_AVRe; } // Return the mnemonic string of an opcode const char *mnemo_str(int op) { AVR_mnemo mnemo = opcode_mnemo(op, PART_ALL | OP_AVR_ILL); + if(mnemo < 0 || mnemo >= MNEMO_N) return "illegal"; return avr_opcodes[mnemo].opcode; @@ -740,7 +744,7 @@ int z_width(int op16, AVR_mnemo *mnemop) { MNEMO_xch, MNEMO_las, MNEMO_lac, MNEMO_lat, }; - for(AVR_mnemo m=0; m < (AVR_mnemo) (sizeof mlist/sizeof*mlist); m++) + for(AVR_mnemo m = 0; m < (AVR_mnemo) (sizeof mlist/sizeof *mlist); m++) if(op16_is_mnemo(op16, mlist[m])) { if(mnemop) *mnemop = mlist[m]; @@ -756,19 +760,19 @@ int op16_target(int here, int op16) { if(mnemo >= 0 && mnemo < MNEMO_N) { switch(avr_opcodes[mnemo].type & OTY_TYPE_MASK) { - case OTY_RJMX: // Relative call rcall, range [.-4096, .+4094] bytes - case OTY_RJMI: // Relative jump rjmp, range [.-4096, .+4094] bytes - return here + 2 + ((int16_t) (op16<<4) >> 3); + case OTY_RJMX: // Relative call rcall, range [.-4096, .+4094] bytes + case OTY_RJMI: // Relative jump rjmp, range [.-4096, .+4094] bytes + return here + 2 + ((int16_t) (op16 << 4) >> 3); - case OTY_JMPI: // Jump to potentially anywhere in flash (jmp, ijmp, eijmp) - case OTY_JMPX: // Jump to potentially anywhere in flash (calls and ret/i) + case OTY_JMPI: // Jump to potentially anywhere in flash (jmp, ijmp, eijmp) + case OTY_JMPX: // Jump to potentially anywhere in flash (calls and ret/i) return INT_MIN; - case OTY_BRAI: // Conditional branch, range [.-128, .+126] bytes - return here + 2 + (int8_t) ((op16 & 0x3f8)>>2); + case OTY_BRAI: // Conditional branch, range [.-128, .+126] bytes + return here + 2 + (int8_t) ((op16 & 0x3f8) >> 2); - case OTY_SKPI: // Conditional skip, range [.+0, .+4] (cpse, sbrc, sbrs) - case OTY_SKPX: // Conditional skip, range [.+0, .+4] (sbic, sbis) + case OTY_SKPI: // Conditional skip, range [.+0, .+4] (cpse, sbrc, sbrs) + case OTY_SKPX: // Conditional skip, range [.+0, .+4] (sbic, sbis) return here + 2 + 4; } } diff --git a/src/avrcache.c b/src/avrcache.c index 590cec54b..960933de0 100644 --- a/src/avrcache.c +++ b/src/avrcache.c @@ -76,7 +76,7 @@ * avr_chip_erase_cached() erases the chip and discards pending writes() to * flash or EEPROM. It presets the flash cache to all 0xff alleviating the * need to read from the device flash. However, if the programmer serves - * bootloaders (pgm->prog_modes & PM_SPM) then the flash cache is reset + * bootloaders is_spm(pgm) then the flash cache is reset * instead, necessitating flash memory be fetched from the device on first * read; the reason for this is that bootloaders emulate chip erase and they * won't overwrite themselves (some bootloaders, eg, optiboot ignore chip @@ -112,7 +112,6 @@ * */ - /* * Paged access? * - Programmer must have paged routines @@ -125,13 +124,10 @@ int avr_has_paged_access(const PROGRAMMER *pgm, const AVRPART *p, const AVRMEM *mem) { return pgm->paged_load && pgm->paged_write && - mem->page_size > 0 && (mem->page_size & (mem->page_size-1)) == 0 && - mem->size > 0 && mem->size % mem->page_size == 0 && - mem_is_paged_type(mem) && - !(p && avr_mem_exclude(pgm, p, mem)); + mem->page_size > 0 && (mem->page_size & (mem->page_size - 1)) == 0 && + mem->size > 0 && mem->size%mem->page_size == 0 && mem_is_paged_type(mem) && !(p && avr_mem_exclude(pgm, p, mem)); } - #define fallback_read_byte (pgm->read_byte != avr_read_byte_cached? led_read_byte: avr_read_byte_default) #define fallback_write_byte (pgm->write_byte != avr_write_byte_cached? led_write_byte: avr_write_byte_default) @@ -149,7 +145,7 @@ int avr_read_page_default(const PROGRAMMER *pgm, const AVRPART *p, const AVRMEM if(!avr_has_paged_access(pgm, p, mem) || addr < 0 || addr >= mem->size) return LIBAVRDUDE_GENERAL_FAILURE; - int rc, pgsize = mem->page_size, base = addr & ~(pgsize-1); + int rc, pgsize = mem->page_size, base = addr & ~(pgsize - 1); if(pgsize == 1) return fallback_read_byte(pgm, p, mem, addr, buf); @@ -158,6 +154,7 @@ int avr_read_page_default(const PROGRAMMER *pgm, const AVRPART *p, const AVRMEM led_set(pgm, LED_PGM); unsigned char *pagecopy = mmt_malloc(pgsize); + memcpy(pagecopy, mem->buf + base, pgsize); if((rc = pgm->paged_load(pgm, p, mem, pgsize, base, pgsize)) >= 0) memcpy(buf, mem->buf + base, pgsize); @@ -165,8 +162,8 @@ int avr_read_page_default(const PROGRAMMER *pgm, const AVRPART *p, const AVRMEM if(rc < 0 && pgm->read_byte != avr_read_byte_cached) { rc = LIBAVRDUDE_SUCCESS; - for(int i=0; iread_byte(pgm, p, mem, base+i, pagecopy+i) < 0) { + for(int i = 0; i < pgsize; i++) { + if(pgm->read_byte(pgm, p, mem, base + i, pagecopy + i) < 0) { rc = LIBAVRDUDE_GENERAL_FAILURE; break; } @@ -183,7 +180,6 @@ int avr_read_page_default(const PROGRAMMER *pgm, const AVRPART *p, const AVRMEM return rc; } - /* * Write the data page to the device into the page containing addr * - Caller to provide all mem->page_size bytes incl padding if any @@ -194,12 +190,13 @@ int avr_write_page_default(const PROGRAMMER *pgm, const AVRPART *p, const AVRMEM if(!avr_has_paged_access(pgm, p, mem) || addr < 0 || addr >= mem->size) return LIBAVRDUDE_GENERAL_FAILURE; - int rc, pgsize = mem->page_size, base = addr & ~(pgsize-1); + int rc, pgsize = mem->page_size, base = addr & ~(pgsize - 1); if(pgsize == 1) return fallback_write_byte(pgm, p, mem, addr, *data); unsigned char *pagecopy = mmt_malloc(pgsize); + memcpy(pagecopy, mem->buf + base, pgsize); memcpy(mem->buf + base, data, pgsize); rc = pgm->paged_write(pgm, p, mem, pgsize, base, pgsize); @@ -209,7 +206,6 @@ int avr_write_page_default(const PROGRAMMER *pgm, const AVRPART *p, const AVRMEM return rc; } - // Could memory region s1 be the result of a NOR-memory copy of s3 onto s2? int avr_is_and(const unsigned char *s1, const unsigned char *s2, const unsigned char *s3, size_t n) { while(n--) @@ -219,12 +215,11 @@ int avr_is_and(const unsigned char *s1, const unsigned char *s2, const unsigned return 1; } - static int cacheAddress(int addr, const AVR_Cache *cp, const AVRMEM *mem) { int cacheaddr = addr + (int) (mem->offset - cp->offset); - if(cacheaddr < 0 || cacheaddr >= cp->size) { // Should never happen (unless offsets wrong in avrdude.conf) - pmsg_error("%s cache address 0x%04x out of range [0, 0x%04x]\n", mem->desc, cacheaddr, cp->size-1); + if(cacheaddr < 0 || cacheaddr >= cp->size) { // Should never happen (unless offsets wrong in avrdude.conf) + pmsg_error("%s cache address 0x%04x out of range [0, 0x%04x]\n", mem->desc, cacheaddr, cp->size - 1); return LIBAVRDUDE_GENERAL_FAILURE; } @@ -236,21 +231,22 @@ static int cacheAddress(int addr, const AVR_Cache *cp, const AVRMEM *mem) { return cacheaddr; } +static int loadCachePage(AVR_Cache *cp, const PROGRAMMER *pgm, const AVRPART *p, const AVRMEM *mem, + int addr, int cacheaddr, int nlOnErr) { -static int loadCachePage(AVR_Cache *cp, const PROGRAMMER *pgm, const AVRPART *p, const AVRMEM *mem, int addr, int cacheaddr, int nlOnErr) { int pgno = cacheaddr/cp->page_size; if(!cp->iscached[pgno]) { // Read cached section from device - int cachebase = cacheaddr & ~(cp->page_size-1); - if(avr_read_page_default(pgm, p, mem, addr & ~(cp->page_size-1), cp->cont + cachebase) < 0) { + int cachebase = cacheaddr & ~(cp->page_size - 1); + + if(avr_read_page_default(pgm, p, mem, addr & ~(cp->page_size - 1), cp->cont + cachebase) < 0) { report_progress(1, -1, NULL); if(nlOnErr && quell_progress) msg_info("\n"); pmsg_error("unable to read %s page at addr 0x%04x\n", mem->desc, addr); return LIBAVRDUDE_GENERAL_FAILURE; } - // Copy last read device page, so we can later check for changes memcpy(cp->copy + cachebase, cp->cont + cachebase, cp->page_size); cp->iscached[pgno] = 1; @@ -259,7 +255,6 @@ static int loadCachePage(AVR_Cache *cp, const PROGRAMMER *pgm, const AVRPART *p, return LIBAVRDUDE_SUCCESS; } - static int initCache(AVR_Cache *cp, const PROGRAMMER *pgm, const AVRPART *p) { AVRMEM *basemem = cp == pgm->cp_flash? avr_locate_flash(p): cp == pgm->cp_eeprom? avr_locate_eeprom(p): cp == pgm->cp_bootrow? avr_locate_bootrow(p): avr_locate_usersig(p); @@ -271,10 +266,10 @@ static int initCache(AVR_Cache *cp, const PROGRAMMER *pgm, const AVRPART *p) { cp->page_size = basemem->page_size; cp->offset = basemem->offset; cp->cont = mmt_malloc(cp->size); - cp->copy = mmt_malloc( cp->size); + cp->copy = mmt_malloc(cp->size); cp->iscached = mmt_malloc(cp->size/cp->page_size); - if((pgm->prog_modes & PM_SPM) && mem_is_in_flash(basemem)) { // Could be vector bootloader + if(is_spm(pgm) && mem_is_in_flash(basemem)) { // Could be vector bootloader // Caching the vector page hands over to the progammer that then can patch the reset vector if(loadCachePage(cp, pgm, p, basemem, 0, 0, 0) < 0) return LIBAVRDUDE_GENERAL_FAILURE; @@ -283,21 +278,22 @@ static int initCache(AVR_Cache *cp, const PROGRAMMER *pgm, const AVRPART *p) { return LIBAVRDUDE_SUCCESS; } +static int writeCachePage(AVR_Cache *cp, const PROGRAMMER *pgm, const AVRPART *p, + const AVRMEM *mem, int base, int nlOnErr) { -static int writeCachePage(AVR_Cache *cp, const PROGRAMMER *pgm, const AVRPART *p, const AVRMEM *mem, int base, int nlOnErr) { led_clr(pgm, LED_ERR); led_set(pgm, LED_PGM); // Write modified page cont to device; if unsuccessful try bytewise access if(avr_write_page_default(pgm, p, mem, base, cp->cont + base) < 0) { if(pgm->read_byte != avr_read_byte_cached && pgm->write_byte != avr_write_byte_cached) { - for(int i=0; i < cp->page_size; i++) - if(cp->cont[base+i] != cp->copy[base+i]) - if(pgm->write_byte(pgm, p, mem, base+i, cp->cont[base+i]) < 0 || - pgm->read_byte(pgm, p, mem, base+i, cp->copy+base+i) < 0) { + for(int i = 0; i < cp->page_size; i++) + if(cp->cont[base + i] != cp->copy[base + i]) + if(pgm->write_byte(pgm, p, mem, base + i, cp->cont[base + i]) < 0 || + pgm->read_byte(pgm, p, mem, base + i, cp->copy + base + i) < 0) { report_progress(1, -1, NULL); if(nlOnErr && quell_progress) msg_info("\n"); - pmsg_error("%s access error at addr 0x%04x\n", mem->desc, base+i); + pmsg_error("%s access error at addr 0x%04x\n", mem->desc, base + i); goto error; } @@ -328,61 +324,61 @@ static int writeCachePage(AVR_Cache *cp, const PROGRAMMER *pgm, const AVRPART *p return LIBAVRDUDE_GENERAL_FAILURE; } - // A coarse guess where any bootloader might start (prob underestimates the start) static int guessBootStart(const PROGRAMMER *pgm, const AVRPART *p) { int bootstart = 0; const AVR_Cache *cp = pgm->cp_flash; - if(p->prog_modes & PM_UPDI) // Modern AVRs put the bootloader at 0 + if(is_updi(p)) // Modern AVRs put the bootloader at 0 return 0; if(p->n_boot_sections > 0 && p->boot_section_size > 0) - bootstart = cp->size - (p->boot_section_size<<(p->n_boot_sections-1)); + bootstart = cp->size - (p->boot_section_size << (p->n_boot_sections - 1)); if(bootstart <= cp->size/2 || bootstart >= cp->size) bootstart = cp->size > 32768? cp->size - 16384: cp->size*3/4; - return bootstart & ~(cp->page_size-1); + return bootstart & ~(cp->page_size - 1); } - // Page erase but without error messages if it does not work static int silent_page_erase(const PROGRAMMER *pgm, const AVRPART *p, const AVRMEM *m, unsigned int a) { int bakverb = verbose; + verbose = -123; int ret = pgm->page_erase? pgm->page_erase(pgm, p, m, a): -1; + verbose = bakverb; return ret; } - typedef struct { AVRMEM *mem; AVR_Cache *cp; int isflash, iseeprom, zopaddr, pgerase; } Cache_desc; - // Write flash, EEPROM, bootrow and usersig caches to device and free them int avr_flush_cache(const PROGRAMMER *pgm, const AVRPART *p) { Cache_desc mems[] = { - { avr_locate_flash(p), pgm->cp_flash, 1, 0, -1, 0 }, - { avr_locate_eeprom(p), pgm->cp_eeprom, 0, 1, -1, 0 }, - { avr_locate_bootrow(p), pgm->cp_bootrow, 0, 0, -1, 0 }, - { avr_locate_usersig(p), pgm->cp_usersig, 0, 0, -1, 0 }, + {avr_locate_flash(p), pgm->cp_flash, 1, 0, -1, 0}, + {avr_locate_eeprom(p), pgm->cp_eeprom, 0, 1, -1, 0}, + {avr_locate_bootrow(p), pgm->cp_bootrow, 0, 0, -1, 0}, + {avr_locate_usersig(p), pgm->cp_usersig, 0, 0, -1, 0}, }; int chpages = 0; bool chiperase = 0; + // Count page changes and find a page that needs a clear bit set - for(size_t i = 0; i < sizeof mems/sizeof*mems; i++) { - if(mems[i].mem && avr_mem_exclude(pgm, p, mems[i].mem)) // Zap mem if excluded combo - memset(mems+i, 0, sizeof *mems); + for(size_t i = 0; i < sizeof mems/sizeof *mems; i++) { + if(mems[i].mem && avr_mem_exclude(pgm, p, mems[i].mem)) // Zap mem if excluded combo + memset(mems + i, 0, sizeof *mems); AVRMEM *mem = mems[i].mem; AVR_Cache *cp = mems[i].cp; + if(!mem || !cp->cont) continue; @@ -403,14 +399,14 @@ int avr_flush_cache(const PROGRAMMER *pgm, const AVRPART *p) { fflush(stderr); // Check whether page erase needed and working and whether chip erase needed - for(size_t i = 0; i < sizeof mems/sizeof*mems; i++) { + for(size_t i = 0; i < sizeof mems/sizeof *mems; i++) { AVRMEM *mem = mems[i].mem; AVR_Cache *cp = mems[i].cp; if(!mem) continue; - if(!cp->cont) // Ensure cache is initialised from now on + if(!cp->cont) // Ensure cache is initialised from now on if(initCache(cp, pgm, p) < 0) { if(quell_progress) msg_info("\n"); @@ -421,7 +417,7 @@ int avr_flush_cache(const PROGRAMMER *pgm, const AVRPART *p) { if(chiperase || mems[i].zopaddr < 0) continue; - int n=mems[i].zopaddr; + int n = mems[i].zopaddr; if(writeCachePage(cp, pgm, p, mem, n, 1) < 0) return LIBAVRDUDE_GENERAL_FAILURE; @@ -430,7 +426,6 @@ int avr_flush_cache(const PROGRAMMER *pgm, const AVRPART *p) { chpages--; continue; } - // Probably NOR memory, check out page erase if(silent_page_erase(pgm, p, mem, n) >= 0) { if(writeCachePage(cp, pgm, p, mem, n, 1) < 0) @@ -443,7 +438,7 @@ int avr_flush_cache(const PROGRAMMER *pgm, const AVRPART *p) { } } - if(!mem_is_usersig(mems[i].mem)) // CE does not erase usersig + if(!mem_is_usersig(mems[i].mem)) // CE does not erase usersig chiperase = 1; } @@ -459,13 +454,15 @@ int avr_flush_cache(const PROGRAMMER *pgm, const AVRPART *p) { } int nrd = 0; + // Count read operations needed - for(size_t i = 0; i < sizeof mems/sizeof*mems; i++) { + for(size_t i = 0; i < sizeof mems/sizeof *mems; i++) { AVRMEM *mem = mems[i].mem; AVR_Cache *cp = mems[i].cp; + if(!mem) continue; - if(mem_is_usersig(mem)) // CE does not affect usersig/userrow + if(mem_is_usersig(mem)) // CE does not affect usersig/userrow continue; for(int pgno = 0, n = 0; n < cp->size; pgno++, n += cp->page_size) @@ -476,9 +473,10 @@ int avr_flush_cache(const PROGRAMMER *pgm, const AVRPART *p) { report_progress(0, 1, "Reading"); if(nrd) { // Read full flash and EEPROM - for(size_t i = 0; i < sizeof mems/sizeof*mems; i++) { + for(size_t i = 0; i < sizeof mems/sizeof *mems; i++) { AVRMEM *mem = mems[i].mem; AVR_Cache *cp = mems[i].cp; + if(!mem) continue; if(mem_is_usersig(mem)) // CE does not affect usersig/userrow @@ -503,25 +501,25 @@ int avr_flush_cache(const PROGRAMMER *pgm, const AVRPART *p) { pmsg_error("chip erase failed\n"); return LIBAVRDUDE_GENERAL_FAILURE; } - // Update cache copies after chip erase so that writing back is efficient - for(size_t i = 0; i < sizeof mems/sizeof*mems; i++) { + for(size_t i = 0; i < sizeof mems/sizeof *mems; i++) { AVRMEM *mem = mems[i].mem; AVR_Cache *cp = mems[i].cp; + if(!mem) continue; if(mem_is_usersig(mem)) // CE does not affect usersig/userrow continue; if(mems[i].isflash) { - memset(cp->copy, 0xff, cp->size); // record device memory as erased - if(pgm->prog_modes & PM_SPM) { // Bootloaders will not overwrite themselves + memset(cp->copy, 0xff, cp->size); // Record device memory as erased + if(is_spm(pgm)) { // Bootloaders will not overwrite themselves // Read back generously estimated bootloader section to avoid verification errors int bootstart = guessBootStart(pgm, p); int nbo = (cp->size - bootstart)/cp->page_size; for(int ibo = 0, n = bootstart; n < cp->size; n += cp->page_size) { - report_progress(1+ibo++, nbo+2, NULL); + report_progress(1 + ibo++, nbo + 2, NULL); if(avr_read_page_default(pgm, p, mem, n, cp->copy + n) < 0) { report_progress(1, -1, NULL); if(quell_progress) @@ -554,10 +552,12 @@ int avr_flush_cache(const PROGRAMMER *pgm, const AVRPART *p) { } int nwr = 0; + // Count number of writes - for(size_t i = 0; i < sizeof mems/sizeof*mems; i++) { + for(size_t i = 0; i < sizeof mems/sizeof *mems; i++) { AVRMEM *mem = mems[i].mem; AVR_Cache *cp = mems[i].cp; + if(!mem) continue; @@ -569,9 +569,10 @@ int avr_flush_cache(const PROGRAMMER *pgm, const AVRPART *p) { report_progress(0, 1, "Writing"); if(nwr) { // Write all modified pages to the device - for(size_t i = 0; i < sizeof mems/sizeof*mems; i++) { + for(size_t i = 0; i < sizeof mems/sizeof *mems; i++) { AVRMEM *mem = mems[i].mem; AVR_Cache *cp = mems[i].cp; + if(!mem || !cp->cont) continue; @@ -599,7 +600,6 @@ int avr_flush_cache(const PROGRAMMER *pgm, const AVRPART *p) { return LIBAVRDUDE_SUCCESS; } - /* * Read byte via a read/write cache * - Used if paged routines available and if memory is flash, EEPROM, bootrow or usersig @@ -630,6 +630,7 @@ int avr_read_byte_cached(const PROGRAMMER *pgm, const AVRPART *p, const AVRMEM * return LIBAVRDUDE_GENERAL_FAILURE; int cacheaddr = cacheAddress((int) addr, cp, mem); + if(cacheaddr < 0) return LIBAVRDUDE_GENERAL_FAILURE; @@ -642,7 +643,6 @@ int avr_read_byte_cached(const PROGRAMMER *pgm, const AVRPART *p, const AVRMEM * return LIBAVRDUDE_SUCCESS; } - /* * Write byte via a read/write cache * - Used if paged routines available and if memory is flash, EEPROM, bootrow or usersig @@ -670,6 +670,7 @@ int avr_write_byte_cached(const PROGRAMMER *pgm, const AVRPART *p, const AVRMEM return LIBAVRDUDE_GENERAL_FAILURE; int cacheaddr = cacheAddress((int) addr, cp, mem); + if(cacheaddr < 0) return LIBAVRDUDE_GENERAL_FAILURE; @@ -688,13 +689,12 @@ int avr_write_byte_cached(const PROGRAMMER *pgm, const AVRPART *p, const AVRMEM return LIBAVRDUDE_SUCCESS; } - // Erase the chip and set the cache accordingly int avr_chip_erase_cached(const PROGRAMMER *pgm, const AVRPART *p) { Cache_desc mems[] = { - { avr_locate_flash(p), pgm->cp_flash, 1, 0, -1, 0 }, - { avr_locate_eeprom(p), pgm->cp_eeprom, 0, 1, -1, 0 }, - { avr_locate_bootrow(p), pgm->cp_bootrow, 0, 0, -1, 0 }, + {avr_locate_flash(p), pgm->cp_flash, 1, 0, -1, 0}, + {avr_locate_eeprom(p), pgm->cp_eeprom, 0, 1, -1, 0}, + {avr_locate_bootrow(p), pgm->cp_bootrow, 0, 0, -1, 0}, // usersig is unaffected by CE }; int rc; @@ -702,7 +702,7 @@ int avr_chip_erase_cached(const PROGRAMMER *pgm, const AVRPART *p) { if((rc = led_chip_erase(pgm, p)) < 0) return rc; - for(size_t i = 0; i < sizeof mems/sizeof*mems; i++) { + for(size_t i = 0; i < sizeof mems/sizeof *mems; i++) { AVRMEM *mem = mems[i].mem; AVR_Cache *cp = mems[i].cp; @@ -714,15 +714,16 @@ int avr_chip_erase_cached(const PROGRAMMER *pgm, const AVRPART *p) { return LIBAVRDUDE_GENERAL_FAILURE; if(mems[i].isflash) { - if(pgm->prog_modes & PM_SPM) { // Reset cache to unknown + if(is_spm(pgm)) { // Reset cache to unknown memset(cp->iscached, 0, cp->size/cp->page_size); - } else { // preset all pages as erased + } else { // Preset all pages as erased memset(cp->copy, 0xff, cp->size); memset(cp->cont, 0xff, cp->size); memset(cp->iscached, 1, cp->size/cp->page_size); } } else { // Test whether cached EEPROM/bootrow pages were zapped bool erased = 0; + for(int pgno = 0, n = 0; n < cp->size; pgno++, n += cp->page_size) { if(cp->iscached[pgno]) { if(!is_memset(cp->copy + n, 0xff, cp->page_size)) { // Page has data? @@ -748,10 +749,8 @@ int avr_chip_erase_cached(const PROGRAMMER *pgm, const AVRPART *p) { return LIBAVRDUDE_SUCCESS; } - // Erase a page and synchronise it with the cache -int avr_page_erase_cached(const PROGRAMMER *pgm, const AVRPART *p, const AVRMEM *mem, - unsigned int uaddr) { +int avr_page_erase_cached(const PROGRAMMER *pgm, const AVRPART *p, const AVRMEM *mem, unsigned int uaddr) { int addr = uaddr; @@ -774,6 +773,7 @@ int avr_page_erase_cached(const PROGRAMMER *pgm, const AVRPART *p, const AVRMEM return LIBAVRDUDE_GENERAL_FAILURE; int cacheaddr = cacheAddress(addr, cp, mem); + if(cacheaddr < 0) return LIBAVRDUDE_GENERAL_FAILURE; @@ -784,26 +784,26 @@ int avr_page_erase_cached(const PROGRAMMER *pgm, const AVRPART *p, const AVRMEM if(loadCachePage(cp, pgm, p, mem, (int) addr, cacheaddr, 0) < 0) return LIBAVRDUDE_GENERAL_FAILURE; - if(!is_memset(cp->cont + (cacheaddr & ~(cp->page_size-1)), 0xff, cp->page_size)) + if(!is_memset(cp->cont + (cacheaddr & ~(cp->page_size - 1)), 0xff, cp->page_size)) return LIBAVRDUDE_GENERAL_FAILURE; return LIBAVRDUDE_SUCCESS; } - // Free cache(s) discarding any pending writes int avr_reset_cache(const PROGRAMMER *pgm, const AVRPART *p_unused) { AVR_Cache *mems[] = { pgm->cp_flash, pgm->cp_eeprom, pgm->cp_bootrow, pgm->cp_usersig }; - for(size_t i = 0; i < sizeof mems/sizeof*mems; i++) { + for(size_t i = 0; i < sizeof mems/sizeof *mems; i++) { AVR_Cache *cp = mems[i]; + if(cp->cont) mmt_free(cp->cont); if(cp->copy) mmt_free(cp->copy); if(cp->iscached) mmt_free(cp->iscached); - memset(cp, 0, sizeof*cp); + memset(cp, 0, sizeof *cp); } return LIBAVRDUDE_SUCCESS; diff --git a/src/avrdude.1 b/src/avrdude.1 index 8e53e6b1f..65b62e59f 100644 --- a/src/avrdude.1 +++ b/src/avrdude.1 @@ -101,13 +101,13 @@ port. Connecting to a serial port emulated on top of USB is likely to not work at all, or to work abysmally slow. .Pp -If you happen to have a Linux system with at least 4 hardware GPIOs -available (like almost all embedded Linux boards) you can do without +If you happen to have a Linux system with at least 4 hardware GPIOs +available (like almost all embedded Linux boards) you can do without any additional hardware - just connect them to the SDO, SDI, RESET and SCK pins on the AVR and use the linuxgpio programmer type. It bitbangs the lines using the Linux sysfs GPIO interface. Of course, care should be taken about voltage level compatibility. Also, although not strictly -required, it is strongly advisable to protect the GPIO pins from +required, it is strongly advisable to protect the GPIO pins from overcurrent situations in some way. The simplest would be to just put some resistors in series or better yet use a 3-state buffer driver like the 74HC244. Have a look at https://kolev.info/blog/2013/01/06/avrdude-linuxgpio/ for a more @@ -231,8 +231,8 @@ frequency of 6.8 MHz or more: factory-set AVR parts, which typically run on an internal oscillator between 1 MHz and 1.6 MHz, cannot be programmed using -c ch341a. If libftdi has has been compiled in .Nm avrdude , -the avrftdi device adds support for many programmers using FTDI's 2232C/D/H -and 4232H parts running in MPSSE mode, which hard-codes (in the chip) +the avrftdi device adds support for many programmers using FTDI's 2232C/D/H +and 4232H parts running in MPSSE mode, which hard-codes (in the chip) SCK to bit 1, SDO to bit 2, and SDI to bit 3. Reset is usually bit 4. .Pp The Atmel DFU bootloader is supported in both, FLIP protocol version 1 @@ -420,7 +420,7 @@ or .Pa ${HOME}/.avrduderc file to assign a default programmer to keep from having to specify this option on every invocation. -A full list of all supported programmers is output to the terminal +A full list of all supported programmers is output to the terminal by using ? as programmer-id. If -c ? is specified with a specific part, see -p above, then only those programmers are output that expect @@ -441,7 +441,7 @@ See the config file, located at .Pa ${PREFIX}/etc/avrdude.conf , which contains a description of the format. .Pp -If +If .Ar config-file is written as .Pa +filename @@ -1145,7 +1145,7 @@ hexadecimal and ASCII form. .It Ar dump memory addr Read from .Ar memory addr -as many bytes as the most recent +as many bytes as the most recent .Ar dump memory addr len command with this very memory had specified (default 256 bytes), and display them. .It Ar dump memory @@ -1880,7 +1880,7 @@ C programming language. .Bl -tag -offset indent -width indent .It Ar no_blockmode Disables the default checking for block transfer capability. -Use +Use .Ar no_blockmode only if your .Ar AVR910 @@ -2024,7 +2024,7 @@ Show help menu and exit. .It Ar buspirate .Bl -tag -offset indent -width indent .It Ar reset=cs,aux,aux2 -The default setup assumes the BusPirate's CS output pin connected to +The default setup assumes the BusPirate's CS output pin connected to the RESET pin on AVR side. It is however possible to have multiple AVRs connected to the same BP with SDI, SDO and SCK lines common for all of them. In such a case one AVR should have its RESET connected to BusPirate's @@ -2036,9 +2036,9 @@ pin and if your BusPirate has an pin (only available on BusPirate version v1a with firmware 3.0 or newer) use that to activate RESET on the third AVR. .Pp -It may be a good idea to decouple the BusPirate and the AVR's SPI buses from +It may be a good idea to decouple the BusPirate and the AVR's SPI buses from each other using a 3-state bus buffer. For example 74HC125 or 74HC244 are some -good candidates with the latches driven by the appropriate reset pin (cs, +good candidates with the latches driven by the appropriate reset pin (cs, aux or aux2). Otherwise the SPI traffic in one active circuit may interfere with programming the AVR in the other design. .It Ar spifreq=<0..7> @@ -2066,12 +2066,12 @@ The only advantage of the "raw-wire" mode is the different SPI frequencies available. Paged writing is not implemented in this mode. .It Ar ascii Attempt to use ASCII mode even when the firmware supports BinMode (binary -mode). +mode). BinMode is supported in firmware 2.7 and newer, older FW's either don't -have BinMode or their BinMode is buggy. ASCII mode is slower and makes +have BinMode or their BinMode is buggy. ASCII mode is slower and makes the above .Ar reset= , spifreq= -and +and .Ar rawfreq= parameters unavailable. Be aware that ASCII mode is not guaranteed to work with newer firmware versions, and is retained only to maintain compatibility @@ -2082,22 +2082,22 @@ whole pages to be written to AVR flash memory at once, resulting in a significant write speed increase. If use of this mode is not desirable for some reason, this option disables it. .It Ar nopagedread -Newer firmware versions support in binary mode SPI command some AVR Extended +Newer firmware versions support in binary mode SPI command some AVR Extended Commands. Using the "Bulk Memory Read from Flash" results in a significant read speed increase. If use of this mode is not desirable for some reason, this option disables it. .It Ar cpufreq=<125..4000> -This sets the AUX pin to output a frequency of +This sets the AUX pin to output a frequency of .Ar n kHz. Connecting -the AUX pin to the XTAL1 pin of your MCU, you can provide it a clock, +the AUX pin to the XTAL1 pin of your MCU, you can provide it a clock, for example when it needs an external clock because of wrong fuses settings. -Make sure the CPU frequency is at least four times the SPI frequency. +Make sure the CPU frequency is at least four times the SPI frequency. .It Ar serial_recv_timeout=<1...> -This sets the serial receive timeout to the given value. -The timeout happens every time avrdude waits for the BusPirate prompt. -Especially in ascii mode this happens very often, so setting a smaller value -can speed up programming a lot. +This sets the serial receive timeout to the given value. +The timeout happens every time avrdude waits for the BusPirate prompt. +Especially in ascii mode this happens very often, so setting a smaller value +can speed up programming a lot. The default value is 100ms. Using 10ms might work in most cases. .It Ar help Show help menu and exit. @@ -2151,11 +2151,11 @@ Show help menu and exit. Connection to the PICkit2 programmer: .Bd -literal (AVR) (PICkit2) -RST - VPP/MCLR (1) -VDD - VDD Target (2) -- possibly optional if AVR self powered -GND - GND (3) +RST - VPP/MCLR (1) +VDD - VDD Target (2) -- possibly optional if AVR self powered +GND - GND (3) SDI - PGD (4) -SCLK - PDC (5) +SCLK - PDC (5) SDO - AUX (6) .Ed .Bl -tag -offset indent -width indent @@ -2381,6 +2381,6 @@ using USBtinyISP, and send must be a multiple of four bytes. .Pp The avrftdi driver allows one to select specific devices using any combination of vid,pid serial number (usbsn) vendor description (usbvendoror part description (usbproduct) -as seen with lsusb or whatever tool used to view USB device information. Multiple +as seen with lsusb or whatever tool used to view USB device information. Multiple devices can be on the bus at the same time. For the H parts, which have multiple MPSSE interfaces, the interface can also be selected. It defaults to interface 'A'. diff --git a/src/avrdude.h b/src/avrdude.h index 095f56b78..bcb9b696f 100644 --- a/src/avrdude.h +++ b/src/avrdude.h @@ -22,6 +22,7 @@ #include #define SYSTEM_CONF_FILE "avrdude.conf" + #if defined(WIN32) #define USER_CONF_FILE "avrdude.rc" #else @@ -29,13 +30,13 @@ #define XDG_USER_CONF_FILE "avrdude/avrdude.rc" #endif -extern char *progname; // Name of program, for messages -#define progbuf "" // Used to be for indenting continuation below "avrdude: msg" -extern int ovsigck; // Override signature check (-F) -extern int verbose; // Verbosity level (-v, -vv, ...) -extern int quell_progress; // Quell progress report -q, reduce effective verbosity level (-qq, -qqq) -extern const char *partdesc; // Part -p string -extern const char *pgmid; // Programmer -c string +#define progbuf "" // Used to be for indenting continuation below "avrdude: msg" +extern char *progname; // Name of program, for messages +extern int ovsigck; // Override signature check (-F) +extern int verbose; // Verbosity level (-v, -vv, ...) +extern int quell_progress; // Quell progress report -q, reduce effective verbosity level (-qq, -qqq) +extern const char *partdesc; // Part -p string +extern const char *pgmid; // Programmer -c string // Magic memory tree: these functions succeed or exit() #define mmt_strdup(s) cfg_strdup(__func__, s) @@ -46,9 +47,9 @@ extern const char *pgmid; // Programmer -c string int avrdude_message2(FILE *fp, int lno, const char *file, const char *func, int msgmode, int msglvl, const char *format, ...) #if defined(__GNUC__) // Ask gcc to check whether format and parameters match - __attribute__ ((format (printf, 7, 8))) + __attribute__((format(printf, 7, 8))) #endif -; + ; // Shortcuts #define msg_ext_error(...) avrdude_message2(stderr, __LINE__, __FILE__, __func__, 0, MSG_EXT_ERROR, __VA_ARGS__) @@ -95,5 +96,4 @@ int avrdude_message2(FILE *fp, int lno, const char *file, const char *func, int #define lterm_out(...) avrdude_message2(stdout, __LINE__, __FILE__, __func__, MSG2_FLUSH|MSG2_LEFT_MARGIN, MSG_INFO, __VA_ARGS__) #define fmsg_out(fp, ...) avrdude_message2(fp, __LINE__, __FILE__, __func__, MSG2_FLUSH, MSG_INFO, __VA_ARGS__) - #endif diff --git a/src/avrftdi.c b/src/avrftdi.c index 47b71e6f8..4a1062600 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; - - 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 = 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 (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; - } - - 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; - - E(ftdi_write_data(ftdi->ftdic, buf, ptr - buf) < 0, ftdi->ftdic); - - return 0; + 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) { + + 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; + + 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 > 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); + + *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); + + 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]; - 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; - } + if(pin.mask[0] == 0) // Ignore not defined pins (might be the led or Vcc or buff) + return 0; - 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"); + 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"); - pdata->pin_value = SET_BITS_0(pdata->pin_value, pgm, pinfunc, value); + pdata->pin_value = SET_BITS_0(pdata->pin_value, pgm, pinfunc, value); - return write_flush(pdata); + 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(is_tpi(p)) + 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); - - 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; - - if (read_data) { - buf[buf_pos++] = GET_BITS_LOW; - buf[buf_pos++] = GET_BITS_HIGH; - } - - bit >>= 1; - } - return buf_pos; + 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; + + 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; + } + + 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; - - 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; + 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; } - 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 - - // 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); - - unsigned char* send_buffer = alloca((8 * 2 * 6) * blocksize + (8 * 1 * 2) * blocksize + 7); - unsigned char* recv_buffer = alloca(2 * 16 * blocksize); - - while(remaining) - { - - size_t transfer_size = (remaining > blocksize) ? blocksize : 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); - } - - 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; - - 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; + 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); + + unsigned char *send_buffer = alloca(8*2*6*blocksize + 8*1*2*blocksize + 7); + unsigned char *recv_buffer = alloca(2*16*blocksize); + + while(remaining) { + + size_t transfer_size = (remaining > blocksize)? blocksize: 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); + } + + 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; + + 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; - - cmd[0] = mode | MPSSE_WRITE_NEG; - cmd[1] = ((buf_size - 1) & 0xff); - cmd[2] = (((buf_size - 1) >> 8) & 0xff); - - //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); + 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; + + cmd[0] = mode | MPSSE_WRITE_NEG; + cmd[1] = ((buf_size - 1) & 0xff); + cmd[2] = (((buf_size - 1) >> 8) & 0xff); + + // 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); + #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); - - } - - written += transfer_size; - remaining -= transfer_size; - } - - return written; + 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); + + } + + 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]; - - 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; - - 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]); - - /* 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); - - return 0; +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); + + 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); + + 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); + + 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); + + 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; - 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 ; + valid_pins_p->mask[0] = valid_mask; + valid_pins_p->inverse[0] = valid_mask; - /* 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; - } + // 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); + // 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; - - /* pin checklist. */ - Pin_checklist pin_checklist[N_PINS]; - - Avrftdi_data *pdata = to_pdata(pgm); - - 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); - - /* 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 ; - - /* 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; - } - - /* 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); + int pin; + + // Pin checklist + Pin_checklist pin_checklist[N_PINS]; + + Avrftdi_data *pdata = to_pdata(pgm); + + 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); + + // 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; + + // 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; + } + + // 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; - - /************* - * pin setup * - *************/ - - Avrftdi_data *pdata = to_pdata(pgm); - - - 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)); - - 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; - } - - 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). - */ - - /* 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]; - } - - 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); - - return 0; + int pin; + + // Pin setup + + Avrftdi_data *pdata = to_pdata(pgm); + + 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)); + + 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; + } + + 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). + */ + + // 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]; + } + + 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); + + return 0; } static int avrftdi_open(PROGRAMMER *pgm, const char *port) { - int vid, pid, interface, err; - - Avrftdi_data *pdata = to_pdata(pgm); - - /************************ - * parameter validation * - ************************/ - - /* 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; - - 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; - - 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); + int vid, pid, interface, err; + + Avrftdi_data *pdata = to_pdata(pgm); + + // Parameter validation + + // 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; + + 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; + + 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); + #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); - - 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; + 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); + } + + // 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); - - 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); - - /*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); + avrftdi_powerup(pgm); + + if(is_tpi(p)) { + // 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); + + // 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); } -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; - - 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; - } - - 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; - } - - pmsg_error("device is not responding to program enable. Check connection.\n"); - - return -1; + int i; + unsigned char buf[4]; + int polli = p->pollindex - 1, pollok = polli >= 0 && polli < (int) 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; + } + + 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; + } + + pmsg_error("device is not responding to program enable. Check connection.\n"); + + 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 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); - - /* 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); - } - - 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); - - /*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; - } - - /* 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; - } - - /* 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; - - if(poll_index+1 > addr) { - buf_size = bufptr - buf; - - if(verbose >= MSG_TRACE2) - buf_dump(buf, buf_size, "command buffer", 0, 16*2); - - pmsg_notice("transmitting buffer of size: %d\n", buf_size); - if (0 > avrftdi_transmit(pgm, MPSSE_DO_WRITE, buf, buf, buf_size)) - return -1; - - bufptr = buf; - - pmsg_notice("using m->buf[%d] = 0x%02x as polling value ", poll_index, - m->buf[poll_index]); - /* poll page write ready */ - do { - msg_notice("."); - - 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 */ - /* sleep */ - usleep((m->max_write_delay)); - } - - return len; + 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; + + 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; + } + + 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; + + // 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); + + // 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; + } + + // 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; + } + + // 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; + + if(poll_index + 1 > addr) { + buf_size = bufptr - buf; + + if(verbose >= MSG_TRACE2) + buf_dump(buf, buf_size, "command buffer", 0, 16*2); + + pmsg_notice("transmitting buffer of size: %d\n", buf_size); + if(0 > avrftdi_transmit(pgm, MPSSE_DO_WRITE, buf, buf, buf_size)) + return -1; + + bufptr = buf; + + pmsg_notice("using m->buf[%d] = 0x%02x as polling value ", poll_index, m->buf[poll_index]); + // Poll page write ready + do { + msg_notice("."); + + 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 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); - - /* 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++; - } - - /* 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 (0 > avrftdi_transmit(pgm, MPSSE_DO_READ | MPSSE_DO_WRITE, o_buf, i_buf, len * 4)) - return -1; - - if(verbose >= MSG_TRACE2) { - buf_dump(i_buf, sizeof(i_buf), "i_buf", 0, 32); - } - - memset(&m->buf[addr], 0, page_size); - - /* 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]; - - /* 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]); - } - - if(verbose >= MSG_TRACE2) - buf_dump(&m->buf[addr], page_size, "page:", 0, 32); - - return len; + 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); + + 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; + } + + 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++; + } + + /* 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(0 > avrftdi_transmit(pgm, MPSSE_DO_READ | MPSSE_DO_WRITE, o_buf, i_buf, len*4)) + return -1; + + if(verbose >= MSG_TRACE2) { + buf_dump(i_buf, sizeof(i_buf), "i_buf", 0, 32); + } + + memset(&m->buf[addr], 0, page_size); + + // 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]; + + /* 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]); + } + + 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; - - 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]; - - 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; + Avrftdi_data *pdata; + + 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]; + + 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; } 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; - - 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; - - 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; - - /* 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); - - return 0; + Avrftdi_data *pdata = to_pdata(pgm); + unsigned char buf[18], *ptr = buf; + + 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; + + 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; + + // 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); + + 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; - - 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; - - 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; - - /* 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); - - pos = 0; - do { - int n = ftdi_read_data(pdata->ftdic, &buf[pos], bytes - pos); - E(n < 0, pdata->ftdic); - pos += n; - } while (pos < bytes); - - 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 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; + } + + // 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; + } + + 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; + + 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); + + 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; - } - } - - set_pin(pgm, PPI_AVR_BUFF, ON); - - avrftdi_jtag_reset(pgm); - - /* Set RESET */ - avrftdi_jtag_ir_out(pgm, JTAG_IR_AVR_RESET); - avrftdi_jtag_dr_out(pgm, 1, 1); - - /* Write program enable magic */ - avrftdi_jtag_ir_out(pgm, JTAG_IR_PROG_ENABLE); - avrftdi_jtag_dr_out(pgm, 0xa370, 16); - - return 0; +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; + } + } + + set_pin(pgm, PPI_AVR_BUFF, ON); + + avrftdi_jtag_reset(pgm); + + // Set RESET + avrftdi_jtag_ir_out(pgm, JTAG_IR_AVR_RESET); + avrftdi_jtag_dr_out(pgm, 1, 1); + + // 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)) - ; - - return 0; +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; } 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); - - /* 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); - - /* 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); - - /* 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); - - /* 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); - - /* 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); - - /* 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); - - /* 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; - } - - return 0; + 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; + + } 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; + + } 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; + + } 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; + + } 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; + + } 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; + + } 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; + + } else { + return -1; + } + + 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); - - /* 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); - - /* 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); - - /* 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); - - /* 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); - - /* 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); - - /* 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); - - /* 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); - - /* 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; - - pmsg_error("cannot write to read-only memory %s of %s\n", m->desc, p->desc); - return -1; - } else { - return -1; - } - - return 0; + 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); + + // 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)); + + } 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); + + // 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)); + + } 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); + + // 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)); + + } 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); + + // 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)); + + } else if(mem_is_readonly(m)) { + unsigned char is; + + if(pgm->read_byte(pgm, p, m, addr, &is) >= 0 && is == value) + 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; - - 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 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); - - /* 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); - - 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); - - /* 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); - - /* Wait for completion */ - while (!(avrftdi_jtag_dr_inout(pgm, 0x3300, 15) & 0x0200)) - ; - } - } else { - return -1; - } - - return n_bytes; + 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); + + // 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); + } + + // 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)); + + } 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); + + // 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); + } + + // 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; + } + + 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; - - 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); - - /* 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; - - /* 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; - } - - *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); - - for (unsigned int i = 0; i < n_bytes; i++) { - m->buf[addr + i] = (buf[i * 2] >> 1) | (buf[(i * 2) + 1] << 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 (; addr < maxaddr; addr++) { - /* Load address */ - avrftdi_jtag_dr_out(pgm, 0x0700 | ((addr >> 8) & 0xff), 15); - avrftdi_jtag_dr_out(pgm, 0x0300 | (addr & 0xff), 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; - } - - } else { - return -1; - } - - return n_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; + + 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); + + 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; + + // 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); + + 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); + + for(unsigned int i = 0; i < n_bytes; i++) { + m->buf[addr + i] = (buf[i*2] >> 1) | (buf[(i*2) + 1] << 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(; addr < maxaddr; addr++) { + // Load address + avrftdi_jtag_dr_out(pgm, 0x0700 | ((addr >> 8) & 0xff), 15); + avrftdi_jtag_dr_out(pgm, 0x0300 | (addr & 0xff), 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; + } + + } else { + return -1; + } + + return n_bytes; } -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; - - /* - * 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_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; + + // 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"); - - /* - * 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; +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; + + // 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"; - diff --git a/src/avrftdi.h b/src/avrftdi.h index 4e1a7a94a..2810b3412 100644 --- a/src/avrftdi.h +++ b/src/avrftdi.h @@ -25,16 +25,12 @@ extern "C" { #endif - -extern const char avrftdi_desc[]; -extern const char avrftdi_jtag_desc[]; -void avrftdi_initpgm(PROGRAMMER *pgm); -void avrftdi_jtag_initpgm(PROGRAMMER *pgm); + extern const char avrftdi_desc[]; + extern const char avrftdi_jtag_desc[]; + void avrftdi_initpgm(PROGRAMMER *pgm); + void avrftdi_jtag_initpgm(PROGRAMMER *pgm); #ifdef __cplusplus } #endif - #endif - - diff --git a/src/avrftdi_private.h b/src/avrftdi_private.h index 0a23908d3..c959c71af 100644 --- a/src/avrftdi_private.h +++ b/src/avrftdi_private.h @@ -4,14 +4,16 @@ #include #if defined(HAVE_LIBFTDI1) && defined(HAVE_LIBUSB_1_0) -# if defined(HAVE_LIBUSB_1_0_LIBUSB_H) -# include -# else -# include -# endif -# include -# undef HAVE_LIBFTDI_TYPE_232H -# define HAVE_LIBFTDI_TYPE_232H 1 + +#if defined(HAVE_LIBUSB_1_0_LIBUSB_H) +#include +#else +#include +#endif + +#include +#undef HAVE_LIBFTDI_TYPE_232H +#define HAVE_LIBFTDI_TYPE_232H 1 #elif defined(HAVE_LIBFTDI) #include #else @@ -21,11 +23,11 @@ #else #warning No libftdi or libusb support. Install libftdi1/libusb-1.0 or libftdi/libusb and run configure/make again. #endif + #define DO_NOT_BUILD_AVRFTDI #endif #ifndef DO_NOT_BUILD_AVRFTDI - #define E(x, ftdi) \ do { \ if((x)) { \ @@ -44,54 +46,53 @@ } while(0) enum { - JTAG_IR_EXTEST = 0, - JTAG_IR_IDCODE = 1, - JTAG_IR_SAMPLE_PRELOAD = 2, - JTAG_IR_PROG_ENABLE = 4, - JTAG_IR_PROG_COMMANDS = 5, - JTAG_IR_PROG_PAGELOAD = 6, - JTAG_IR_PROG_PAGEREAD = 7, - JTAG_IR_PRIVATE0 = 8, - JTAG_IR_PRIVATE1 = 9, - JTAG_IR_PRIVATE2 = 10, - JTAG_IR_PRIVATE3 = 11, - JTAG_IR_AVR_RESET = 12, - JTAG_IR_BYPASS = 15, + JTAG_IR_EXTEST = 0, + JTAG_IR_IDCODE = 1, + JTAG_IR_SAMPLE_PRELOAD = 2, + JTAG_IR_PROG_ENABLE = 4, + JTAG_IR_PROG_COMMANDS = 5, + JTAG_IR_PROG_PAGELOAD = 6, + JTAG_IR_PROG_PAGEREAD = 7, + JTAG_IR_PRIVATE0 = 8, + JTAG_IR_PRIVATE1 = 9, + JTAG_IR_PRIVATE2 = 10, + JTAG_IR_PRIVATE3 = 11, + JTAG_IR_AVR_RESET = 12, + JTAG_IR_BYPASS = 15, }; enum jtag_cmd { - JTAG_DR_PROG_NONE = 0x00, - JTAG_DR_PROG_FLASH_READ = 0x02, - JTAG_DR_PROG_EEPROM_READ = 0x03, - JTAG_DR_PROG_FUSE_READ = 0x04, - JTAG_DR_PROG_SIGCAL_READ = 0x08, - JTAG_DR_PROG_FLASH_WRITE = 0x10, - JTAG_DR_PROG_EEPROM_WRITE = 0x11, - JTAG_DR_PROG_LOCK_WRITE = 0x20, - JTAG_DR_PROG_FUSE_WRITE = 0x40, + JTAG_DR_PROG_NONE = 0x00, + JTAG_DR_PROG_FLASH_READ = 0x02, + JTAG_DR_PROG_EEPROM_READ = 0x03, + JTAG_DR_PROG_FUSE_READ = 0x04, + JTAG_DR_PROG_SIGCAL_READ = 0x08, + JTAG_DR_PROG_FLASH_WRITE = 0x10, + JTAG_DR_PROG_EEPROM_WRITE = 0x11, + JTAG_DR_PROG_LOCK_WRITE = 0x20, + JTAG_DR_PROG_FUSE_WRITE = 0x40, }; #define to_pdata(pgm) \ ((Avrftdi_data *)((pgm)->cookie)) typedef struct avrftdi_s { - /* pointer to struct maintained by libftdi to identify the device */ - struct ftdi_context* ftdic; - /* bitmask of values for pins. bit 0 represents pin 0 ([A|B]DBUS0) */ + // Pointer to struct maintained by libftdi to identify the device + struct ftdi_context *ftdic; + // Bitmask of values for pins; bit 0 represents pin 0 ([A|B]DBUS0) uint16_t pin_value; - /* bitmask of pin direction. a '1' make a pin an output. - * bit 0 corresponds to pin 0. */ + // Bitmask of pin direction; 1 makes a pin an output; bit 0 corresponds to pin 0 uint16_t pin_direction; - /* don't know. not useful. someone put it in. */ + // Don't know; not useful? Someone put it in uint16_t led_mask; - /* total number of pins supported by a programmer. varies with FTDI chips */ + // Total number of pins supported by a programmerl varies with FTDI chips int pin_limit; - /* internal RX buffer of the device. needed for INOUT transfers */ + // Internal RX buffer of the device; needed for INOUT transfers int rx_buffer_size; int tx_buffer_size; - /* use bitbanging instead of mpsse spi */ + // Use bitbanging instead of MPSSE SPI bool use_bitbanging; - /* bits 16-23 of extended 24-bit word flash address for parts with flash > 128k */ + // Bits 16-23 of extended 24-bit word flash address for parts with flash > 128k uint8_t lext_byte; char name_str[128]; // Used in ftdi_pin_name() @@ -99,6 +100,4 @@ typedef struct avrftdi_s { struct pindef mpsse_pins[4]; // Used in avrftdi_check_pins_mpsse() struct pindef other_pins; // Used in avrftdi_check_pins_mpsse() } Avrftdi_data; - -#endif /* DO_NOT_BUILD_AVRFDTI */ - +#endif // Do_not_build_avrfdti diff --git a/src/avrftdi_tpi.c b/src/avrftdi_tpi.c index 4e0f16d34..3dbd5a94c 100644 --- a/src/avrftdi_tpi.c +++ b/src/avrftdi_tpi.c @@ -14,244 +14,226 @@ #include "avrftdi_private.h" #ifndef DO_NOT_BUILD_AVRFTDI - static void avrftdi_tpi_disable(const PROGRAMMER *); static int avrftdi_tpi_program_enable(const PROGRAMMER *pgm, const AVRPART *p); #ifdef notyet static void avrftdi_debug_frame(uint16_t frame) { - static const char bit_name[] = "IDLES01234567PSS"; - //static char bit_name[] = "SSP76543210SELDI"; - char line0[34], line1[34], line2[34]; - int bit, pos; - - for(bit = 0; bit < 16; bit++) - { - pos = 16 - bit - 1; - if(frame & (1 << pos)) - { - line0[2*pos] = '_'; - line0[2*pos+1] = ' '; - - line2[2*pos] = ' '; - line2[2*pos+1] = ' '; - } - else - { - line0[2*pos] = ' '; - line0[2*pos+1] = ' '; - - line2[2*pos] = '-'; - line2[2*pos+1] = ' '; - } - - line1[2*pos] = bit_name[pos]; - line1[2*pos+1] = ' '; - - } - - line0[32] = 0; - line1[32] = 0; - line2[32] = 0; - - msg_debug("%s\n", line0); - msg_debug("%s\n", line1); - // msg_debug("%s\n", line2); -} -#endif /* notyet */ - -int -avrftdi_tpi_initialize(const PROGRAMMER *pgm, const AVRPART *p) { - int ret; - - Avrftdi_data *pdata = to_pdata(pgm); - unsigned char buf[] = { MPSSE_DO_WRITE | MPSSE_WRITE_NEG | MPSSE_LSB, 0x01, 0x00, 0xff, 0xff }; - - pmsg_info("setting /Reset pin low\n"); - pgm->setpin(pgm, PIN_AVR_RESET, OFF); - pgm->setpin(pgm, PIN_AVR_SCK, OFF); - pgm->setpin(pgm, PIN_AVR_SDO, ON); - usleep(20 * 1000); - - pgm->setpin(pgm, PIN_AVR_RESET, ON); - /* worst case 128ms */ - usleep(2 * 128 * 1000); - - /*setting rst back to 0 */ - pgm->setpin(pgm, PIN_AVR_RESET, OFF); - /*wait at least 20ms bevor issuing spi commands to avr */ - usleep(20 * 1000); - - pmsg_info("sending 16 init clock cycles ...\n"); - ret = ftdi_write_data(pdata->ftdic, buf, sizeof(buf)); - - return ret; + static const char bit_name[] = "IDLES01234567PSS"; + + char line0[34], line1[34], line2[34]; + int bit, pos; + + for(bit = 0; bit < 16; bit++) { + pos = 16 - bit - 1; + if(frame & (1 << pos)) { + line0[2*pos] = '_'; + line0[2*pos + 1] = ' '; + + line2[2*pos] = ' '; + line2[2*pos + 1] = ' '; + } else { + line0[2*pos] = ' '; + line0[2*pos + 1] = ' '; + + line2[2*pos] = '-'; + line2[2*pos + 1] = ' '; + } + + line1[2*pos] = bit_name[pos]; + line1[2*pos + 1] = ' '; + + } + + line0[32] = 0; + line1[32] = 0; + line2[32] = 0; + + msg_debug("%s\n", line0); + msg_debug("%s\n", line1); + // msg_debug("%s\n", line2); } +#endif // Notyet +int avrftdi_tpi_initialize(const PROGRAMMER *pgm, const AVRPART *p) { + int ret; -void avrftdi_tpi_initpgm(PROGRAMMER *pgm) { - pmsg_info("using TPI interface\n"); + Avrftdi_data *pdata = to_pdata(pgm); + unsigned char buf[] = { MPSSE_DO_WRITE | MPSSE_WRITE_NEG | MPSSE_LSB, 0x01, 0x00, 0xff, 0xff }; + + pmsg_info("setting /Reset pin low\n"); + pgm->setpin(pgm, PIN_AVR_RESET, OFF); + pgm->setpin(pgm, PIN_AVR_SCK, OFF); + pgm->setpin(pgm, PIN_AVR_SDO, ON); + usleep(20*1000); - pgm->program_enable = avrftdi_tpi_program_enable; - pgm->cmd_tpi = avrftdi_cmd_tpi; - pgm->chip_erase = avr_tpi_chip_erase; - pgm->disable = avrftdi_tpi_disable; + pgm->setpin(pgm, PIN_AVR_RESET, ON); + // Worst case 128ms + usleep(2*128*1000); - pgm->paged_load = NULL; - pgm->paged_write = NULL; + // Setting rst back to 0 + pgm->setpin(pgm, PIN_AVR_RESET, OFF); + // Wait at least 20ms bevor issuing spi commands to avr + usleep(20*1000); + + pmsg_info("sending 16 init clock cycles ...\n"); + ret = ftdi_write_data(pdata->ftdic, buf, sizeof(buf)); + + return ret; } +void avrftdi_tpi_initpgm(PROGRAMMER *pgm) { + pmsg_info("using TPI interface\n"); + + pgm->program_enable = avrftdi_tpi_program_enable; + pgm->cmd_tpi = avrftdi_cmd_tpi; + pgm->chip_erase = avr_tpi_chip_erase; + pgm->disable = avrftdi_tpi_disable; + + pgm->paged_load = NULL; + pgm->paged_write = NULL; +} #define TPI_PARITY_MASK 0x2000 static inline int count1s(unsigned int x) { + #if defined(__GNUC__) - return __builtin_popcount(x); + return __builtin_popcount(x); #else - int count = 0; + int count = 0; - while (x) - { - count += x & 1; - x >>= 1; - } + while(x) { + count += x & 1; + x >>= 1; + } - return count; + return count; #endif } static uint16_t tpi_byte2frame(uint8_t byte) { - uint16_t frame = 0xc00f; - int parity = count1s(byte) & 1; + uint16_t frame = 0xc00f; + int parity = count1s(byte) & 1; + + frame |= ((byte << 5) & 0x1fe0); - frame |= ((byte << 5) & 0x1fe0); + if(parity) + frame |= TPI_PARITY_MASK; - if(parity) - frame |= TPI_PARITY_MASK; - - return frame; + return frame; } static int tpi_frame2byte(uint16_t frame, uint8_t *byte) { - /* drop idle and start bit(s) */ - *byte = (frame >> 5) & 0xff; + // Drop idle and start bit(s) + *byte = (frame >> 5) & 0xff; - int parity = count1s(*byte) & 1; - int parity_rcvd = (frame & TPI_PARITY_MASK) ? 1 : 0; + int parity = count1s(*byte) & 1; + int parity_rcvd = (frame & TPI_PARITY_MASK)? 1: 0; - return parity != parity_rcvd; + return parity != parity_rcvd; } #ifdef notyet static int avrftdi_tpi_break(const PROGRAMMER *pgm) { - unsigned char buffer[] = { MPSSE_DO_WRITE | MPSSE_WRITE_NEG | MPSSE_LSB, 1, 0, 0, 0 }; - E(ftdi_write_data(to_pdata(pgm)->ftdic, buffer, sizeof(buffer)) != sizeof(buffer), to_pdata(pgm)->ftdic); + unsigned char buffer[] = { MPSSE_DO_WRITE | MPSSE_WRITE_NEG | MPSSE_LSB, 1, 0, 0, 0 }; + E(ftdi_write_data(to_pdata(pgm)->ftdic, buffer, sizeof(buffer)) != sizeof(buffer), to_pdata(pgm)->ftdic); - return 0; + return 0; } -#endif /* notyet */ +#endif // Notyet static int avrftdi_tpi_write_byte(const PROGRAMMER *pgm, unsigned char byte) { - uint16_t frame; + uint16_t frame; - struct ftdi_context* ftdic = to_pdata(pgm)->ftdic; + struct ftdi_context *ftdic = to_pdata(pgm)->ftdic; - unsigned char buffer[] = { MPSSE_DO_WRITE | MPSSE_WRITE_NEG | MPSSE_LSB, 1, 0, 0, 0 }; + unsigned char buffer[] = { MPSSE_DO_WRITE | MPSSE_WRITE_NEG | MPSSE_LSB, 1, 0, 0, 0 }; - frame = tpi_byte2frame(byte); - - buffer[3] = frame & 0xff; - buffer[4] = frame >> 8; - - msg_trace("Byte %02x, frame: %04x, MPSSE: 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x\n", - byte, frame, buffer[0], buffer[1], buffer[2], buffer[3], buffer[4]); + frame = tpi_byte2frame(byte); - //avrftdi_debug_frame(frame); - - E(ftdi_write_data(ftdic, buffer, sizeof(buffer)) != sizeof(buffer), ftdic); + buffer[3] = frame & 0xff; + buffer[4] = frame >> 8; - return 0; + msg_trace("Byte %02x, frame: %04x, MPSSE: 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x\n", + byte, frame, buffer[0], buffer[1], buffer[2], buffer[3], buffer[4]); + + // avrftdi_debug_frame(frame); + + E(ftdi_write_data(ftdic, buffer, sizeof(buffer)) != sizeof(buffer), ftdic); + + return 0; } #define TPI_FRAME_SIZE 12 #define TPI_IDLE_BITS 2 static int avrftdi_tpi_read_byte(const PROGRAMMER *pgm, unsigned char *byte) { - uint16_t frame; - - /* use 2 guard bits, 2 default idle bits + 12 frame bits = 16 bits total */ - const int bytes = 3; - int err, i = 0; - - unsigned char buffer[4]; + uint16_t frame; + + // Use 2 guard bits, 2 default idle bits + 12 frame bits = 16 bits total + const int bytes = 3; + int err, i = 0; - buffer[0] = MPSSE_DO_READ | MPSSE_LSB; - buffer[1] = (bytes-1) & 0xff; - buffer[2] = ((bytes-1) >> 8) & 0xff; - buffer[3] = SEND_IMMEDIATE; + unsigned char buffer[4]; - msg_trace("MPSSE: 0x%02x 0x%02x 0x%02x 0x%02x (Read frame)\n", - buffer[0], buffer[1], buffer[2], buffer[3]); + buffer[0] = MPSSE_DO_READ | MPSSE_LSB; + buffer[1] = (bytes - 1) & 0xff; + buffer[2] = ((bytes - 1) >> 8) & 0xff; + buffer[3] = SEND_IMMEDIATE; - ftdi_write_data(to_pdata(pgm)->ftdic, buffer, 4); + msg_trace("MPSSE: 0x%02x 0x%02x 0x%02x 0x%02x (Read frame)\n", buffer[0], buffer[1], buffer[2], buffer[3]); - memset(buffer, 0, sizeof(buffer)); + ftdi_write_data(to_pdata(pgm)->ftdic, buffer, 4); - i = 0; - do { - int err = ftdi_read_data(to_pdata(pgm)->ftdic, &buffer[i], bytes - i); - E(err < 0, to_pdata(pgm)->ftdic); - i += err; - } while(i < bytes); + memset(buffer, 0, sizeof(buffer)); + i = 0; + do { + int err = ftdi_read_data(to_pdata(pgm)->ftdic, &buffer[i], bytes - i); - msg_trace("MPSSE: 0x%02x 0x%02x 0x%02x 0x%02x (Read frame)\n", - buffer[0], buffer[1], buffer[2], buffer[3]); + E(err < 0, to_pdata(pgm)->ftdic); + i += err; + } while(i < bytes); + msg_trace("MPSSE: 0x%02x 0x%02x 0x%02x 0x%02x (Read frame)\n", buffer[0], buffer[1], buffer[2], buffer[3]); - frame = buffer[0] | (buffer[1] << 8); - - err = tpi_frame2byte(frame, byte); - pmsg_trace("frame: 0x%04x, byte: 0x%02x\n", frame, *byte); - - //avrftdi_debug_frame(frame); + frame = buffer[0] | (buffer[1] << 8); - return err; + err = tpi_frame2byte(frame, byte); + pmsg_trace("frame: 0x%04x, byte: 0x%02x\n", frame, *byte); + + // avrftdi_debug_frame(frame); + + return err; } static int avrftdi_tpi_program_enable(const PROGRAMMER *pgm, const AVRPART *p) { - return avr_tpi_program_enable(pgm, p, TPIPCR_GT_2b); + return avr_tpi_program_enable(pgm, p, TPIPCR_GT_2b); } -int -avrftdi_cmd_tpi(const PROGRAMMER *pgm, const unsigned char *cmd, int cmd_len, - unsigned char *res, int res_len) -{ - int i, err = 0; - - for(i = 0; i < cmd_len; i++) - { - err = avrftdi_tpi_write_byte(pgm, cmd[i]); - if(err) - return err; - } - - for(i = 0; i < res_len; i++) - { - err = avrftdi_tpi_read_byte(pgm, &res[i]); - if(err) - return err; - } - - return 0; -} +int avrftdi_cmd_tpi(const PROGRAMMER *pgm, const unsigned char *cmd, int cmd_len, unsigned char *res, int res_len) { + int i, err = 0; -static void avrftdi_tpi_disable(const PROGRAMMER *pgm) { - unsigned char cmd[] = {TPI_OP_SSTCS(TPIPCR), 0}; - pgm->cmd_tpi(pgm, cmd, sizeof(cmd), NULL, 0); + for(i = 0; i < cmd_len; i++) { + err = avrftdi_tpi_write_byte(pgm, cmd[i]); + if(err) + return err; + } - pmsg_info("leaving Programming mode\n"); + for(i = 0; i < res_len; i++) { + err = avrftdi_tpi_read_byte(pgm, &res[i]); + if(err) + return err; + } + + return 0; } -#endif /* DO_NOT_BUILD_AVRFTDI */ +static void avrftdi_tpi_disable(const PROGRAMMER *pgm) { + unsigned char cmd[] = { TPI_OP_SSTCS(TPIPCR), 0 }; + pgm->cmd_tpi(pgm, cmd, sizeof(cmd), NULL, 0); + pmsg_info("leaving Programming mode\n"); +} +#endif // Do_not_build_avrftdi diff --git a/src/avrftdi_tpi.h b/src/avrftdi_tpi.h index f9a075154..c47d4ece9 100644 --- a/src/avrftdi_tpi.h +++ b/src/avrftdi_tpi.h @@ -1,10 +1,7 @@ #pragma once -//int avrftdi_tpi_write_byte(PROGRAMMER *pgm, unsigned char byte); -//int avrftdi_tpi_read_byte(PROGRAMMER *pgm, unsigned char * byte); -int avrftdi_cmd_tpi(const PROGRAMMER *pgm, const unsigned char *cmd, int cmd_len, - unsigned char *res, int res_len); +// int avrftdi_tpi_write_byte(PROGRAMMER *pgm, unsigned char byte); +// int avrftdi_tpi_read_byte(PROGRAMMER *pgm, unsigned char *byte); +int avrftdi_cmd_tpi(const PROGRAMMER *pgm, const unsigned char *cmd, int cmd_len, unsigned char *res, int res_len); int avrftdi_tpi_initialize(const PROGRAMMER *pgm, const AVRPART *p); void avrftdi_tpi_initpgm(PROGRAMMER *pgm); - - diff --git a/src/avrpart.c b/src/avrpart.c index dea8c8880..71ab88db7 100644 --- a/src/avrpart.c +++ b/src/avrpart.c @@ -28,9 +28,7 @@ #include "avrdude.h" #include "libavrdude.h" -/*** - *** Elementary functions dealing with OPCODE structures - ***/ +// Elementary functions dealing with OPCODE structures OPCODE *avr_new_opcode(void) { return (OPCODE *) mmt_malloc(sizeof(OPCODE)); @@ -41,6 +39,7 @@ static OPCODE *avr_dup_opcode(const OPCODE *op) { return NULL; OPCODE *m = (OPCODE *) mmt_malloc(sizeof(*m)); + memcpy(m, op, sizeof(*m)); return m; @@ -50,8 +49,7 @@ void avr_free_opcode(OPCODE *op) { mmt_free(op); } - -// returns position 0..31 of highest bit set or INT_MIN if no bit is set +// Returns position 0..31 of highest bit set or INT_MIN if no bit is set int intlog2(unsigned int n) { int ret; @@ -64,7 +62,6 @@ int intlog2(unsigned int n) { return ret; } - /* * avr_set_bits() * @@ -74,12 +71,12 @@ int avr_set_bits(const OPCODE *op, unsigned char *cmd) { int i, j, bit; unsigned char mask; - for (i=0; i<32; i++) { - if (op->bit[i].type == AVR_CMDBIT_VALUE || op->bit[i].type == AVR_CMDBIT_IGNORE) { - j = 3 - i / 8; - bit = i % 8; + for(i = 0; i < 32; i++) { + if(op->bit[i].type == AVR_CMDBIT_VALUE || op->bit[i].type == AVR_CMDBIT_IGNORE) { + j = 3 - i/8; + bit = i%8; mask = 1 << bit; - if (op->bit[i].value && op->bit[i].type == AVR_CMDBIT_VALUE) + if(op->bit[i].value && op->bit[i].type == AVR_CMDBIT_VALUE) cmd[j] = cmd[j] | mask; else cmd[j] = cmd[j] & ~mask; @@ -89,7 +86,6 @@ int avr_set_bits(const OPCODE *op, unsigned char *cmd) { return 0; } - /* * avr_set_addr() * @@ -101,13 +97,13 @@ int avr_set_addr(const OPCODE *op, unsigned char *cmd, unsigned long addr) { unsigned long value; unsigned char mask; - for (i=0; i<32; i++) { - if (op->bit[i].type == AVR_CMDBIT_ADDRESS) { - j = 3 - i / 8; - bit = i % 8; + for(i = 0; i < 32; i++) { + if(op->bit[i].type == AVR_CMDBIT_ADDRESS) { + j = 3 - i/8; + bit = i%8; mask = 1 << bit; value = addr >> op->bit[i].bitno & 0x01; - if (value) + if(value) cmd[j] = cmd[j] | mask; else cmd[j] = cmd[j] & ~mask; @@ -117,15 +113,14 @@ int avr_set_addr(const OPCODE *op, unsigned char *cmd, unsigned long addr) { return 0; } - /* * avr_set_addr_mem() * * Set address bits in the specified command based on the memory, opcode and - * address; addr must be a word address for flash or, for all other memories, - * a byte address; returns 0 on success and -1 on error (no memory or no - * opcode) or, if positive, bn+1 where bn is bit number of the highest - * necessary bit that the opcode does not provide. + * address; addr must be a word address for flash or, for all other memories, a + * byte address; returns 0 on success and -1 on error (no memory or no opcode) + * or, if positive, bn+1 where bn is bit number of the highest necessary bit + * that the opcode does not provide. */ int avr_set_addr_mem(const AVRMEM *mem, int opnum, unsigned char *cmd, unsigned long addr) { int ret, isflash, lo, hi, memsize, pagesize; @@ -138,10 +133,10 @@ int avr_set_addr_mem(const AVRMEM *mem, int opnum, unsigned char *cmd, unsigned return -1; isflash = mem_is_in_flash(mem); - memsize = mem->size >> isflash; // word addresses for flash + memsize = mem->size >> isflash; // Word addresses for flash pagesize = mem->page_size >> isflash; - // compute range lo..hi of needed address bits + // Compute range lo..hi of needed address bits switch(opnum) { case AVR_OP_READ: case AVR_OP_WRITE: @@ -150,23 +145,23 @@ int avr_set_addr_mem(const AVRMEM *mem, int opnum, unsigned char *cmd, unsigned case AVR_OP_WRITE_LO: case AVR_OP_WRITE_HI: lo = 0; - hi = intlog2(memsize-1); // memsize = 1 implies no addr bit is needed + hi = intlog2(memsize - 1); // memsize = 1 implies no addr bit is needed break; case AVR_OP_LOADPAGE_LO: case AVR_OP_LOADPAGE_HI: lo = 0; - hi = intlog2(pagesize-1); + hi = intlog2(pagesize - 1); break; case AVR_OP_LOAD_EXT_ADDR: lo = 16; - hi = intlog2(memsize-1); + hi = intlog2(memsize - 1); break; case AVR_OP_WRITEPAGE: lo = intlog2(pagesize); - hi = intlog2(memsize-1); + hi = intlog2(memsize - 1); break; case AVR_OP_CHIP_ERASE: @@ -182,21 +177,22 @@ int avr_set_addr_mem(const AVRMEM *mem, int opnum, unsigned char *cmd, unsigned hi = 15; unsigned char avail[32]; + memset(avail, 0, sizeof avail); - for(int i=0; i<32; i++) { + for(int i = 0; i < 32; i++) { if(op->bit[i].type == AVR_CMDBIT_ADDRESS) { int bitno, j, bit; unsigned char mask; bitno = op->bit[i].bitno & 31; - j = 3 - i / 8; - bit = i % 8; + j = 3 - i/8; + bit = i%8; mask = 1 << bit; avail[bitno] = 1; // 'a' bit with number outside bit range [lo, hi] is set to 0 - if (bitno >= lo && bitno <= hi? (addr >> bitno) & 1: 0) + if(bitno >= lo && bitno <= hi? (addr >> bitno) & 1: 0) cmd[j] = cmd[j] | mask; else cmd[j] = cmd[j] & ~mask; @@ -205,32 +201,31 @@ int avr_set_addr_mem(const AVRMEM *mem, int opnum, unsigned char *cmd, unsigned ret = 0; if(lo >= 0 && hi < 32 && lo <= hi) - for(int bn=lo; bn <= hi; bn++) - if(!avail[bn]) // necessary bit bn misses in opcode - ret = bn+1; + for(int bn = lo; bn <= hi; bn++) + if(!avail[bn]) // Necessary bit bn misses in opcode + ret = bn + 1; return ret; } - /* * avr_set_input() * - * Set input data bits in the specified command based on the opcode, - * and the data byte. + * Set input data bits in the specified command based on the opcode, and the + * data byte. */ int avr_set_input(const OPCODE *op, unsigned char *cmd, unsigned char data) { int i, j, bit; unsigned char value; unsigned char mask; - for (i=0; i<32; i++) { - if (op->bit[i].type == AVR_CMDBIT_INPUT) { - j = 3 - i / 8; - bit = i % 8; + for(i = 0; i < 32; i++) { + if(op->bit[i].type == AVR_CMDBIT_INPUT) { + j = 3 - i/8; + bit = i%8; mask = 1 << bit; value = data >> op->bit[i].bitno & 0x01; - if (value) + if(value) cmd[j] = cmd[j] | mask; else cmd[j] = cmd[j] & ~mask; @@ -240,26 +235,24 @@ int avr_set_input(const OPCODE *op, unsigned char *cmd, unsigned char data) { return 0; } - /* * avr_get_output() * - * Retrieve output data bits from the command results based on the - * opcode data. + * Retrieve output data bits from the command results based on the opcode data. */ int avr_get_output(const OPCODE *op, const unsigned char *res, unsigned char *data) { int i, j, bit; unsigned char value; unsigned char mask; - for (i=0; i<32; i++) { - if (op->bit[i].type == AVR_CMDBIT_OUTPUT) { - j = 3 - i / 8; - bit = i % 8; + for(i = 0; i < 32; i++) { + if(op->bit[i].type == AVR_CMDBIT_OUTPUT) { + j = 3 - i/8; + bit = i%8; mask = 1 << bit; value = ((res[j] & mask) >> bit) & 0x01; value = value << op->bit[i].bitno; - if (value) + if(value) *data = *data | value; else *data = *data & ~value; @@ -269,19 +262,17 @@ int avr_get_output(const OPCODE *op, const unsigned char *res, unsigned char *da return 0; } - /* * avr_get_output_index() * - * Calculate the byte number of the output data based on the - * opcode data. + * Calculate the byte number of the output data based on the opcode data. */ int avr_get_output_index(const OPCODE *op) { int i, j; - for (i=0; i<32; i++) { - if (op->bit[i].type == AVR_CMDBIT_OUTPUT) { - j = 3 - i / 8; + for(i = 0; i < 32; i++) { + if(op->bit[i].type == AVR_CMDBIT_OUTPUT) { + j = 3 - i/8; return j; } } @@ -289,13 +280,11 @@ int avr_get_output_index(const OPCODE *op) { return -1; } - -/*** - *** Elementary functions dealing with AVRMEM structures - ***/ +// Elementary functions dealing with AVRMEM structures AVRMEM *avr_new_mem(void) { AVRMEM *m = (AVRMEM *) mmt_malloc(sizeof(*m)); + m->desc = cache_string(""); m->page_size = 1; // Ensure not 0 m->initval = -1; // Unknown value represented as -1 @@ -307,6 +296,7 @@ AVRMEM *avr_new_mem(void) { // Create memory from name and size AVRMEM *avr_new_memory(const char *name, int size) { AVRMEM *m = (AVRMEM *) mmt_malloc(sizeof(*m)); + m->desc = cache_string(name); m->page_size = 1; // Ensure not 0 m->size = size; @@ -320,6 +310,7 @@ AVRMEM *avr_new_memory(const char *name, int size) { AVRMEM_ALIAS *avr_new_memalias(void) { AVRMEM_ALIAS *m = (AVRMEM_ALIAS *) mmt_malloc(sizeof *m); + m->desc = cache_string(""); return m; } @@ -333,33 +324,32 @@ const char *avr_mem_name(const AVRPART *p, const AVRMEM *mem) { ret[n/2] = 0; AVRMEM_ALIAS *alias = avr_find_memalias(p, mem); + if(alias && alias->desc && *alias->desc) { int l = strlen(ret); + ret[l] = '/'; - strncpy(ret+l+1, alias->desc, n-l-1); + strncpy(ret + l + 1, alias->desc, n - l - 1); ret[n] = 0; } return cache_string(ret); } -/* - * Allocate and initialize memory buffers for each of the device's - * defined memory regions. - */ +// Allocate and initialize memory buffers for each of the device's defined memory regions int avr_initmem(const AVRPART *p) { if(p == NULL || p->mem == NULL) return -1; - for (LNODEID ln=lfirst(p->mem); ln; ln=lnext(ln)) { + for(LNODEID ln = lfirst(p->mem); ln; ln = lnext(ln)) { AVRMEM *m = ldata(ln); - m->buf = mmt_malloc(m->size); + + m->buf = mmt_malloc(m->size); m->tags = mmt_malloc(m->size); } return 0; } - AVRMEM *avr_dup_mem(const AVRMEM *m) { AVRMEM *n = avr_new_mem(); @@ -392,7 +382,7 @@ AVRMEM_ALIAS *avr_dup_memalias(const AVRMEM_ALIAS *m) { return n; } -void avr_free_mem(AVRMEM * m) { +void avr_free_mem(AVRMEM *m) { if(m == NULL) return; @@ -404,7 +394,7 @@ void avr_free_mem(AVRMEM * m) { mmt_free(m->tags); m->tags = NULL; } - for(size_t i=0; iop)/sizeof(m->op[0]); i++) { + for(size_t i = 0; i < sizeof(m->op)/sizeof(m->op[0]); i++) { if(m->op[i]) { avr_free_opcode(m->op[i]); m->op[i] = NULL; @@ -429,9 +419,9 @@ AVRMEM_ALIAS *avr_locate_memalias(const AVRPART *p, const char *desc) { l = strlen(desc); matches = 0; match = NULL; - for(ln=lfirst(p->mem_alias); ln; ln=lnext(ln)) { + for(ln = lfirst(p->mem_alias); ln; ln = lnext(ln)) { m = ldata(ln); - if(d1 == *m->desc && !strncmp(m->desc, desc, l)) { // Partial initial match + if(d1 == *m->desc && !strncmp(m->desc, desc, l)) { // Partial initial match match = m; matches++; if(m->desc[l] == 0) // Exact match; return straight away @@ -454,9 +444,9 @@ AVRMEM *avr_locate_mem_noalias(const AVRPART *p, const char *desc) { l = strlen(desc); matches = 0; match = NULL; - for(ln=lfirst(p->mem); ln; ln=lnext(ln)) { + for(ln = lfirst(p->mem); ln; ln = lnext(ln)) { m = ldata(ln); - if(d1 == *m->desc && !strncmp(m->desc, desc, l)) { // Partial initial match + if(d1 == *m->desc && !strncmp(m->desc, desc, l)) { // Partial initial match match = m; matches++; if(m->desc[l] == 0) // Exact match; return straight away @@ -467,7 +457,6 @@ AVRMEM *avr_locate_mem_noalias(const AVRPART *p, const char *desc) { return matches == 1? match: NULL; } - AVRMEM *avr_locate_mem(const AVRPART *p, const char *desc) { AVRMEM *m = avr_locate_mem_noalias(p, desc); @@ -476,6 +465,7 @@ AVRMEM *avr_locate_mem(const AVRPART *p, const char *desc) { // Not yet found: look for matching alias name AVRMEM_ALIAS *a = avr_locate_memalias(p, desc); + return a? a->aliased_mem: NULL; } @@ -484,9 +474,9 @@ AVRMEM *avr_locate_fuse_by_offset(const AVRPART *p, unsigned int off) { AVRMEM *m; if(p && p->mem) - for(LNODEID ln=lfirst(p->mem); ln; ln=lnext(ln)) + for(LNODEID ln = lfirst(p->mem); ln; ln = lnext(ln)) if(mem_is_a_fuse(m = ldata(ln))) - if(off == mem_fuse_offset(m) || (m->size == 2 && off-1 == mem_fuse_offset(m))) + if(off == mem_fuse_offset(m) || (m->size == 2 && off - 1 == mem_fuse_offset(m))) return m; return NULL; @@ -496,10 +486,11 @@ AVRMEM *avr_locate_fuse_by_offset(const AVRPART *p, unsigned int off) { AVRMEM *avr_locate_mem_by_type(const AVRPART *p, Memtype type) { AVRMEM *m; Memtype off = type & MEM_FUSEOFF_MASK; + type &= ~(Memtype) MEM_FUSEOFF_MASK; if(p && p->mem) - for(LNODEID ln=lfirst(p->mem); ln; ln=lnext(ln)) + for(LNODEID ln = lfirst(p->mem); ln; ln = lnext(ln)) if((m = ldata(ln))->type & type) if(type != MEM_IS_A_FUSE || off == mem_fuse_offset(m)) return m; @@ -514,8 +505,9 @@ unsigned int avr_data_offset(const AVRPART *p) { AVRMEM_ALIAS *avr_find_memalias(const AVRPART *p, const AVRMEM *m_orig) { if(p && p->mem_alias && m_orig) - for(LNODEID ln=lfirst(p->mem_alias); ln; ln=lnext(ln)) { + for(LNODEID ln = lfirst(p->mem_alias); ln; ln = lnext(ln)) { AVRMEM_ALIAS *m = ldata(ln); + if(m->aliased_mem == m_orig) return m; } @@ -535,8 +527,7 @@ int avr_locate_upidx(const AVRPART *p) { idx = upidxname(p->desc); if(idx < 0) - pmsg_error("uP_table neither knows mcuid %d nor part %s\n", - p->mcuid, p->desc && *p->desc? p->desc: "???"); + pmsg_error("uP_table neither knows mcuid %d nor part %s\n", p->mcuid, p->desc && *p->desc? p->desc: "???"); return idx; } @@ -548,10 +539,10 @@ const Avrintel *avr_locate_uP(const AVRPART *p) { return idx < 0? NULL: uP_table + idx; } - // Return pointer to config table for the part and set number of config bitfields const Configitem *avr_locate_configitems(const AVRPART *p, int *ncp) { int idx = avr_locate_upidx(p); + if(idx < 0) return NULL; @@ -560,8 +551,9 @@ const Configitem *avr_locate_configitems(const AVRPART *p, int *ncp) { } // Return pointer to ISR table for the part and set number of interrupts -const char * const *avr_locate_isrtable(const AVRPART *p, int *nip) { +const char *const *avr_locate_isrtable(const AVRPART *p, int *nip) { int idx = avr_locate_upidx(p); + if(idx < 0) return NULL; @@ -572,6 +564,7 @@ const char * const *avr_locate_isrtable(const AVRPART *p, int *nip) { // Return pointer to register file for the part and set number of registers const Register_file *avr_locate_register_file(const AVRPART *p, int *nrp) { int idx = avr_locate_upidx(p); + if(idx < 0) return NULL; @@ -580,23 +573,23 @@ const Register_file *avr_locate_register_file(const AVRPART *p, int *nrp) { } /* - * Return pointer to a register that uniquely matches the argument reg or - * NULL if no or more than one register matches the reg argument. + * Return pointer to a register that uniquely matches the argument reg or NULL + * if no or more than one register matches the reg argument. * - * Register names have the form module.name or module.instance.name. The - * caller provides a matching function which can be str_eq, str_starts, - * str_matched_by etc. If reg is a full, existing register name, eg, - * porta.out then a pointer to that register entry is returned irrespective - * of the matching function. avr_locate_register() also tries to match the - * last colon-separated segments (instance.name or name) using the provided - * matching function. If reg is the same as instance.name or name then the - * matching function switches to str_eq(). This allows the only ADC register - * adc.adc to be addressed by adc under a lax str_begins() matching even - * though there are other registers that start with adc, eg, adc.adcsra. + * Register names have the form module.name or module.instance.name. The caller + * provides a matching function which can be str_eq, str_starts, str_matched_by + * etc. If reg is a full, existing register name, eg, porta.out then a pointer + * to that register entry is returned irrespective of the matching function. + * avr_locate_register() also tries to match the last colon-separated segments + * (instance.name or name) using the provided matching function. If reg is the + * same as instance.name or name then the matching function switches to + * str_eq(). This allows the only ADC register adc.adc to be addressed by adc + * under a lax str_begins() matching even though there are other registers that + * start with adc, eg, adc.adcsra. */ const Register_file *avr_locate_register(const Register_file *rgf, int nr, const char *reg, - int (*match)(const char *, const char*)) { + int (*match)(const char *, const char *)) { if(!rgf || nr < 1 || !reg || !match) return NULL; @@ -606,15 +599,16 @@ const Register_file *avr_locate_register(const Register_file *rgf, int nr, const for(int i = 0; i < nr; i++) { int reg_matched = 0; + // Match against module.instance.name, instance.name or name - for(const char *p = rgf[i].reg; p; p = strchr(p, '.'), p = p? p+1: p) + for(const char *p = rgf[i].reg; p; p = strchr(p, '.'), p = p? p + 1: p) if(match(p, reg)) { - if(p == rgf[i].reg && (eqmatch || str_eq(p, reg))) // Reg is full name: return straight away - return rgf+i; - if(!eqmatch && str_eq(p, reg)) // reg same as segment: switch to str_eq() matching + if(p == rgf[i].reg && (eqmatch || str_eq(p, reg))) // reg is full name: return straight away + return rgf + i; + if(!eqmatch && str_eq(p, reg)) // reg same as segment: switch to str_eq() matching return avr_locate_register(rgf, nr, reg, str_eq); if(!reg_matched++) // Record a matching register only once - nmatches++, ret = rgf+i; + nmatches++, ret = rgf + i; } } @@ -624,32 +618,33 @@ const Register_file *avr_locate_register(const Register_file *rgf, int nr, const /* * Return a NULL terminated malloc'd list of pointers to matching registers * - * Register names have the form module.name or module.instance.name. The - * caller provides a matching function which can be str_eq, str_starts, - * str_matched_by etc. If reg is a full, existing register name, eg, - * porta.out then the returned list is confined to this specific entry - * irrespective of the matching function. avr_locate_registerlist() also - * tries to match the last colon-separated segments (instance.name or name) - * using the provided matching function. If the argument reg is the same as - * instance.name or name then the matching function switches to str_eq() - * reducing the returned list to those that match that full segment. This - * behaviour can be suppressed by specifying a pattern for reg, eg, adc* - * together with the matching function str_matched_by. + * Register names have the form module.name or module.instance.name. The caller + * provides a matching function which can be str_eq, str_starts, str_matched_by + * etc. If reg is a full, existing register name, eg, porta.out then the + * returned list is confined to this specific entry irrespective of the + * matching function. avr_locate_registerlist() also tries to match the last + * colon-separated segments (instance.name or name) using the provided matching + * function. If the argument reg is the same as instance.name or name then the + * matching function switches to str_eq() reducing the returned list to those + * that match that full segment. This behaviour can be suppressed by specifying + * a pattern for reg, eg, adc* together with the matching function + * str_matched_by. */ const Register_file **avr_locate_registerlist(const Register_file *rgf, int nr, const char *reg, - int (*match)(const char *, const char*)) { + int (*match)(const char *, const char *)) { - const Register_file **ret = mmt_malloc(sizeof rgf*(nr>0? nr+1: 1)), **r = ret; + const Register_file **ret = mmt_malloc(sizeof rgf*(nr > 0? nr + 1: 1)), **r = ret; int eqmatch = match == str_eq; if(rgf && reg && match) for(int i = 0; i < nr; i++) { int reg_matched = 0; + // Match against module.instance.name, instance.name or name - for(const char *p = rgf[i].reg; p; p = strchr(p, '.'), p = p? p+1: p) + for(const char *p = rgf[i].reg; p; p = strchr(p, '.'), p = p? p + 1: p) if(match(p, reg)) { - if(p == rgf[i].reg && (eqmatch || str_eq(p, reg))) { // Reg is full name: return only that - ret[0] = rgf+i; + if(p == rgf[i].reg && (eqmatch || str_eq(p, reg))) { // Reg is full name: return only that + ret[0] = rgf + i; ret[1] = NULL; return ret; } @@ -657,8 +652,8 @@ const Register_file **avr_locate_registerlist(const Register_file *rgf, int nr, mmt_free(ret); return avr_locate_registerlist(rgf, nr, reg, str_eq); } - if(!reg_matched++) // Record a matching register only once - *r++ = rgf+i; + if(!reg_matched++) // Record a matching register only once + *r++ = rgf + i; } } *r = NULL; @@ -675,7 +670,7 @@ const Register_file **avr_locate_registerlist(const Register_file *rgf, int nr, * then a pointer to that is returned irrespective of the matching function. */ const Configitem *avr_locate_config(const Configitem *cfg, int nc, const char *name, - int (*match)(const char *, const char*)) { + int (*match)(const char *, const char *)) { if(!cfg || nc < 1 || !name || !match) return NULL; @@ -685,9 +680,9 @@ const Configitem *avr_locate_config(const Configitem *cfg, int nc, const char *n for(int i = 0; i < nc; i++) { if(match(cfg[i].name, name)) { - if(match == str_eq || str_eq(cfg[i].name, name)) // Full name specified: return straight away - return cfg+i; - nmatches++, ret = cfg+i; + if(match == str_eq || str_eq(cfg[i].name, name)) // Full name specified: return straight away + return cfg + i; + nmatches++, ret = cfg + i; } } @@ -703,19 +698,19 @@ const Configitem *avr_locate_config(const Configitem *cfg, int nc, const char *n * matching function. */ const Configitem **avr_locate_configlist(const Configitem *cfg, int nc, const char *name, - int (*match)(const char *, const char*)) { + int (*match)(const char *, const char *)) { - const Configitem **ret = mmt_malloc(sizeof cfg*(nc>0? nc+1: 1)), **r = ret; + const Configitem **ret = mmt_malloc(sizeof cfg*(nc > 0? nc + 1: 1)), **r = ret; if(cfg && name && match) { for(int i = 0; i < nc; i++) if(match(cfg[i].name, name)) { - if(match == str_eq || str_eq(cfg[i].name, name)) { // Full name specified: return straight away - ret[0] = cfg+i; + if(match == str_eq || str_eq(cfg[i].name, name)) { // Full name specified: return straight away + ret[0] = cfg + i; ret[1] = NULL; return ret; } - *r++ = cfg+i; + *r++ = cfg + i; } } *r = NULL; @@ -736,12 +731,14 @@ static AVRMEM *avr_locate_config_mem_c_value(const PROGRAMMER *pgm, const AVRPAR } const Configitem *c = avr_locate_config(cfg, nc, cname, str_contains); + if(!c) { pmsg_error("%s does not have a unique config item matched by %s\n", p->desc, cname); return NULL; } AVRMEM *mem = str_starts(c->memstr, "lock")? avr_locate_lock(p): avr_locate_fuse_by_offset(p, c->memoffset); + if(!mem) mem = avr_locate_mem(p, c->memstr); if(!mem) { @@ -755,6 +752,7 @@ static AVRMEM *avr_locate_config_mem_c_value(const PROGRAMMER *pgm, const AVRPAR } int fusel = 0; + for(int i = 0; i < mem->size; i++) if(led_read_byte(pgm, p, mem, i, (unsigned char *) &fusel + i) < 0) { pmsg_error("cannot read from %s's %s memory\n", p->desc, mem->desc); @@ -785,7 +783,7 @@ int avr_set_config_value(const PROGRAMMER *pgm, const AVRPART *p, const char *cn const Configitem *c; int fusel; - if(!(mem=avr_locate_config_mem_c_value(pgm, p, cname, &c, &fusel))) + if(!(mem = avr_locate_config_mem_c_value(pgm, p, cname, &c, &fusel))) return -1; if((value << c->lsh) & ~c->mask) @@ -804,9 +802,8 @@ int avr_set_config_value(const PROGRAMMER *pgm, const AVRPART *p, const char *cn return 0; } - static const char *print_num(const char *fmt, int n) { - return str_ccprintf(n<10? "%d": fmt, n); + return str_ccprintf(n < 10? "%d": fmt, n); } static int num_len(const char *fmt, int n) { @@ -814,7 +811,7 @@ static int num_len(const char *fmt, int n) { } void avr_mem_display(FILE *f, const PROGRAMMER *pgm, const AVRPART *p, const char *prefix) { - const char *table_colum[] = {"Memory", "Size", "Pg size", "Offset"}; + const char *table_colum[] = { "Memory", "Size", "Pg size", "Offset" }; const char *table_padding = "-------------------------------"; const int memory_col = 0, offset_col = 3; int m_char_max[4]; @@ -823,16 +820,18 @@ void avr_mem_display(FILE *f, const PROGRAMMER *pgm, const AVRPART *p, const cha for(int i = 0; i < 4; i++) m_char_max[i] = strlen(table_colum[i]); - for (LNODEID ln=lfirst(p->mem); ln; ln=lnext(ln)) { + for(LNODEID ln = lfirst(p->mem); ln; ln = lnext(ln)) { if(avr_mem_exclude(pgm, p, (m = ldata(ln)))) continue; - int m_size[] = {0, m->size, m->page_size, m->offset}; + int m_size[] = { 0, m->size, m->page_size, m->offset }; // Max column widths for(int i = 0; i < 4; i++) { - int len = i == memory_col? (int) strlen(avr_mem_name(p, m)): + int len = + i == memory_col? (int) strlen(avr_mem_name(p, m)): num_len(i == offset_col? "0x%04x": "%d", m_size[i]); // size/pgsize/offset + if(m_char_max[i] < len) m_char_max[i] = len; } @@ -849,10 +848,8 @@ void avr_mem_display(FILE *f, const PROGRAMMER *pgm, const AVRPART *p, const cha m_char_max[2], table_colum[2], m_char_max[3], table_colum[3], prefix, - m_char_max[0], table_padding, - m_char_max[1], table_padding, - m_char_max[2], table_padding, - m_char_max[3], table_padding); + m_char_max[0], table_padding, m_char_max[1], table_padding, m_char_max[2], + table_padding, m_char_max[3], table_padding); } else { fprintf(f, "\n%s%-*s %*s %-*s\n" @@ -861,13 +858,11 @@ void avr_mem_display(FILE *f, const PROGRAMMER *pgm, const AVRPART *p, const cha m_char_max[0], table_colum[0], m_char_max[1], table_colum[1], m_char_max[2], table_colum[2], - prefix, - m_char_max[0], table_padding, - m_char_max[1], table_padding, + prefix, m_char_max[0], table_padding, m_char_max[1], table_padding, m_char_max[2], table_padding); } - for (LNODEID ln=lfirst(p->mem); ln; ln=lnext(ln)) { + for(LNODEID ln = lfirst(p->mem); ln; ln = lnext(ln)) { if(avr_mem_exclude(pgm, p, (m = ldata(ln)))) continue; @@ -876,22 +871,19 @@ void avr_mem_display(FILE *f, const PROGRAMMER *pgm, const AVRPART *p, const cha fprintf(f, "%s%-*s %*d %*d %*s \n", prefix, m_char_max[0], avr_mem_name(p, m), - m_char_max[1], m->size, - m_char_max[2], m->page_size, + m_char_max[1], m->size, m_char_max[2], m->page_size, m_char_max[3], print_num("0x%04x", m->offset)); } else { fprintf(f, "%s%-*s %*d %*d\n", - prefix, - m_char_max[0], avr_mem_name(p, m), - m_char_max[1], m->size, - m_char_max[2], m->page_size); + prefix, m_char_max[0], avr_mem_name(p, m), m_char_max[1], + m->size, m_char_max[2], m->page_size); } } } int avr_variants_display(FILE *f, const AVRPART *p, const char *prefix) { const char *table_padding = "-------------------------------"; - const char *var_table_column[] = {"Variants", "Package", "F max", "T range", "V range"}; + const char *var_table_column[] = { "Variants", "Package", "F max", "T range", "V range" }; char var_tok[5][50]; int var_tok_len[5]; @@ -900,17 +892,17 @@ int avr_variants_display(FILE *f, const AVRPART *p, const char *prefix) { if(lsize(p->variants)) { // Split, eg, "ATtiny841-SSU: SOIC14, Fmax=16 MHz, T=[-40 C, 85 C], Vcc=[1.7 V, 5.5 V]" - for(LNODEID ln=lfirst(p->variants); ln; ln=lnext(ln)) + for(LNODEID ln = lfirst(p->variants); ln; ln = lnext(ln)) if(5 == sscanf(ldata(ln), "%49[^:]: %49[^,], Fmax=%49[^,], T=%48[^]]], Vcc=%48[^]]]", - var_tok[0], var_tok[1], var_tok[2], var_tok[3], var_tok[4])) + var_tok[0], var_tok[1], var_tok[2], var_tok[3], var_tok[4])) for(int i = 0; i < 5; i++) if(var_tok_len[i] < (int) strlen(var_tok[i])) - var_tok_len[i] = strlen(var_tok[i]) + (i>2); // Add 1 for closing interval bracket + var_tok_len[i] = strlen(var_tok[i]) + (i > 2); // Add 1 for closing interval bracket // Print variants table header fprintf(f, "\n%s%-*s %-*s %-*s %-*s %-*s\n" - "%s%.*s--%.*s--%.*s--%.*s--%.*s\n", + "%s%.*s--%.*s--%.*s--%.*s--%.*s\n", prefix, var_tok_len[0], var_table_column[0], var_tok_len[1], var_table_column[1], @@ -919,25 +911,21 @@ int avr_variants_display(FILE *f, const AVRPART *p, const char *prefix) { var_tok_len[4], var_table_column[4], prefix, var_tok_len[0], table_padding, - var_tok_len[1], table_padding, - var_tok_len[2], table_padding, - var_tok_len[3], table_padding, - var_tok_len[4], table_padding); + var_tok_len[1], table_padding, var_tok_len[2], table_padding, + var_tok_len[3], table_padding, var_tok_len[4], table_padding); // Print variants table content - for(LNODEID ln=lfirst(p->variants); ln; ln=lnext(ln)) + for(LNODEID ln = lfirst(p->variants); ln; ln = lnext(ln)) if(5 == sscanf(ldata(ln), "%49[^:]: %49[^,], Fmax=%49[^,], T=%48[^]]], Vcc=%48[^]]]", - var_tok[0], var_tok[1], var_tok[2], var_tok[3], var_tok[4])) { + var_tok[0], var_tok[1], var_tok[2], var_tok[3], var_tok[4])) { strcat(var_tok[3], "]"); strcat(var_tok[4], "]"); fprintf(f, "%s%-*s %-*s %-*s %-*s %-*s\n", prefix, var_tok_len[0], var_tok[0], - var_tok_len[1], var_tok[1], - var_tok_len[2], var_tok[2], - var_tok_len[3], var_tok[3], - var_tok_len[4], var_tok[4]); + var_tok_len[1], var_tok[1], var_tok_len[2], var_tok[2], var_tok_len[3], + var_tok[3], var_tok_len[4], var_tok[4]); } return 0; @@ -945,10 +933,7 @@ int avr_variants_display(FILE *f, const AVRPART *p, const char *prefix) { return -1; } - -/* - * Elementary functions dealing with AVRPART structures - */ +// Elementary functions dealing with AVRPART structures AVRPART *avr_new_part(void) { AVRPART *p = (AVRPART *) mmt_malloc(sizeof(AVRPART)); @@ -969,7 +954,7 @@ AVRPART *avr_new_part(void) { // Default values p->mcuid = -1; p->hvupdi_variant = -1; - p->autobaud_sync = 0x30; // STK_GET_SYNC + p->autobaud_sync = 0x30; // STK_GET_SYNC memset(p->signature, 0xFF, 3); p->reset_disposition = RESET_DEDICATED; p->retry_pulse = PIN_AVR_SCK; @@ -981,7 +966,6 @@ AVRPART *avr_new_part(void) { return p; } - AVRPART *avr_dup_part(const AVRPART *d) { AVRPART *p = avr_new_part(); @@ -992,16 +976,19 @@ AVRPART *avr_dup_part(const AVRPART *d) { p->variants = lcreat(NULL, 0); p->mem = lcreat(NULL, 0); p->mem_alias = lcreat(NULL, 0); - for(LNODEID ln=lfirst(d->mem); ln; ln=lnext(ln)) { + for(LNODEID ln = lfirst(d->mem); ln; ln = lnext(ln)) { AVRMEM *m = ldata(ln); AVRMEM *m2 = avr_dup_mem(m); + ladd(p->mem, m2); // See if there is any alias for it - for(LNODEID ln2=lfirst(d->mem_alias); ln2; ln2=lnext(ln2)) { + for(LNODEID ln2 = lfirst(d->mem_alias); ln2; ln2 = lnext(ln2)) { AVRMEM_ALIAS *a = ldata(ln2); - if (a->aliased_mem == m) { + + if(a->aliased_mem == m) { // Yes, duplicate it, adjust the pointer and add to new list AVRMEM_ALIAS *a2 = avr_dup_memalias(a); + a2->aliased_mem = m2; ladd(p->mem_alias, a2); } @@ -1015,17 +1002,17 @@ AVRPART *avr_dup_part(const AVRPART *d) { return p; } -void avr_free_part(AVRPART * d) { - ldestroy_cb(d->mem, (void(*)(void *)) avr_free_mem); +void avr_free_part(AVRPART *d) { + ldestroy_cb(d->mem, (void (*)(void *)) avr_free_mem); d->mem = NULL; - ldestroy_cb(d->mem_alias, (void(*)(void *)) avr_free_memalias); + ldestroy_cb(d->mem_alias, (void (*)(void *)) avr_free_memalias); d->mem_alias = NULL; ldestroy_cb(d->variants, mmt_f_free); d->variants = NULL; - /* do not free d->parent_id and d->config_file */ - for(size_t i=0; iop)/sizeof(d->op[0]); i++) { - if (d->op[i] != NULL) { + // Do not free d->parent_id and d->config_file + for(size_t i = 0; i < sizeof(d->op)/sizeof(d->op[0]); i++) { + if(d->op[i] != NULL) { avr_free_opcode(d->op[i]); d->op[i] = NULL; } @@ -1034,13 +1021,13 @@ void avr_free_part(AVRPART * d) { } AVRPART *locate_part(const LISTID parts, const char *partdesc) { - AVRPART * p = NULL; + AVRPART *p = NULL; int found = 0; if(!parts || !partdesc) return NULL; - for (LNODEID ln1=lfirst(parts); ln1 && !found; ln1=lnext(ln1)) { + for(LNODEID ln1 = lfirst(parts); ln1 && !found; ln1 = lnext(ln1)) { p = ldata(ln1); if(part_eq(p, partdesc, str_caseeq)) found = 1; @@ -1051,9 +1038,10 @@ AVRPART *locate_part(const LISTID parts, const char *partdesc) { AVRPART *locate_part_by_avr910_devcode(const LISTID parts, int devcode) { if(parts) - for (LNODEID ln1=lfirst(parts); ln1; ln1=lnext(ln1)) { - AVRPART * p = ldata(ln1); - if (p->avr910_devcode == devcode) + for(LNODEID ln1 = lfirst(parts); ln1; ln1 = lnext(ln1)) { + AVRPART *p = ldata(ln1); + + if(p->avr910_devcode == devcode) return p; } @@ -1063,9 +1051,10 @@ AVRPART *locate_part_by_avr910_devcode(const LISTID parts, int devcode) { // Return pointer to first part that has signature sig (unless all 0xff or all 0x00); NULL if no match AVRPART *locate_part_by_signature_pm(const LISTID parts, unsigned char *sig, int sigsize, int prog_modes) { if(parts && sigsize == 3) { - for(LNODEID ln=lfirst(parts); ln; ln=lnext(ln)) { + for(LNODEID ln = lfirst(parts); ln; ln = lnext(ln)) { AVRPART *p = ldata(ln); - if(!*p->id || *p->id == '.') // Skip stump entries + + if(!*p->id || *p->id == '.') // Skip stump entries continue; if(!is_memset(p->signature, 0xff, 3) && !is_memset(p->signature, 0, 3)) if(!memcmp(p->signature, sig, 3) && p->prog_modes & prog_modes) @@ -1082,30 +1071,32 @@ AVRPART *locate_part_by_signature(const LISTID parts, unsigned char *sig, int si // Return whether two signatures represent SW-compatible parts int avr_sig_compatible(const unsigned char *sig1, const unsigned char *sig2) { // SW-compatible parts (same memories, interrupts and regfiles) despite different signatures - static const struct { unsigned char sig[3], equ[3]; } compat[] = { - {{0x1e, 0x97, 0x06}, {0x1e, 0x97, 0x05}}, // ATmega1284 vs ATmega1284P - {{0x1e, 0xa7, 0x03}, {0x1e, 0xa7, 0x02}}, // ATmega1284RFR2 vs ATmega128RFR2 - {{0x1e, 0x94, 0x0f}, {0x1e, 0x94, 0x0a}}, // ATmega164A vs ATmega164P=ATmega164PA - {{0x1e, 0x94, 0x10}, {0x1e, 0x94, 0x07}}, // ATmega165A vs ATmega165=ATmega165=ATmega165PA - {{0x1e, 0x94, 0x06}, {0x1e, 0x94, 0x0b}}, // ATmega168=ATmega168A vs ATmega168P=ATmega168PA - {{0x1e, 0x94, 0x11}, {0x1e, 0x94, 0x05}}, // ATmega169A vs ATmega169=ATmega169P=ATmega169PA - {{0x1e, 0xa8, 0x03}, {0x1e, 0xa8, 0x02}}, // ATmega2564RFR2 vs ATmega256RFR2 - {{0x1e, 0x95, 0x15}, {0x1e, 0x95, 0x08}}, // ATmega324A vs ATmega324P - {{0x1e, 0x95, 0x15}, {0x1e, 0x95, 0x11}}, // ATmega324A vs ATmega324PA - {{0x1e, 0x95, 0x08}, {0x1e, 0x95, 0x11}}, // ATmega324P vs ATmega324PA - {{0x1e, 0x95, 0x06}, {0x1e, 0x95, 0x0e}}, // ATmega3250=ATmega3250A vs ATmega3250P=ATmega3250PA - {{0x1e, 0x95, 0x05}, {0x1e, 0x95, 0x0d}}, // ATmega325=ATmega325A vs ATmega325P=ATmega325PA - {{0x1e, 0x95, 0x04}, {0x1e, 0x95, 0x0c}}, // ATmega3290=ATmega3290A vs ATmega3290P=ATmega3290PA - {{0x1e, 0x95, 0x03}, {0x1e, 0x95, 0x0b}}, // ATmega329=ATmega329A vs ATmega329P=ATmega329PA - {{0x1e, 0x92, 0x05}, {0x1e, 0x92, 0x0a}}, // ATmega48=ATmega48A vs ATmega48P=ATmega48PA - {{0x1e, 0x92, 0x05}, {0x1e, 0x92, 0x0a}}, // ATmega48=ATmega48A vs ATmega48P=ATmega48PA - {{0x1e, 0x96, 0x09}, {0x1e, 0x96, 0x0a}}, // ATmega644=ATmega644A vs ATmega644P=ATmega644PA - {{0x1e, 0xa6, 0x03}, {0x1e, 0xa6, 0x02}}, // ATmega644RFR2 vs ATmega64RFR2 - {{0x1e, 0x96, 0x06}, {0x1e, 0x96, 0x0e}}, // ATmega6450=ATmega6450A vs ATmega6450P - {{0x1e, 0x96, 0x05}, {0x1e, 0x96, 0x0d}}, // ATmega645=ATmega645A vs ATmega645P - {{0x1e, 0x96, 0x04}, {0x1e, 0x96, 0x0c}}, // ATmega6490=ATmega6490A vs ATmega6490P - {{0x1e, 0x96, 0x03}, {0x1e, 0x96, 0x0b}}, // ATmega649=ATmega649A vs ATmega649P - {{0x1e, 0x93, 0x0a}, {0x1e, 0x93, 0x0f}}, // ATmega88=ATmega88A=ATA6612C vs ATmega88P=ATmega88PA + static const struct { + unsigned char sig[3], equ[3]; + } compat[] = { + {{0x1e, 0x97, 0x06}, {0x1e, 0x97, 0x05}}, // ATmega1284 vs ATmega1284P + {{0x1e, 0xa7, 0x03}, {0x1e, 0xa7, 0x02}}, // ATmega1284RFR2 vs ATmega128RFR2 + {{0x1e, 0x94, 0x0f}, {0x1e, 0x94, 0x0a}}, // ATmega164A vs ATmega164P=ATmega164PA + {{0x1e, 0x94, 0x10}, {0x1e, 0x94, 0x07}}, // ATmega165A vs ATmega165=ATmega165=ATmega165PA + {{0x1e, 0x94, 0x06}, {0x1e, 0x94, 0x0b}}, // ATmega168=ATmega168A vs ATmega168P=ATmega168PA + {{0x1e, 0x94, 0x11}, {0x1e, 0x94, 0x05}}, // ATmega169A vs ATmega169=ATmega169P=ATmega169PA + {{0x1e, 0xa8, 0x03}, {0x1e, 0xa8, 0x02}}, // ATmega2564RFR2 vs ATmega256RFR2 + {{0x1e, 0x95, 0x15}, {0x1e, 0x95, 0x08}}, // ATmega324A vs ATmega324P + {{0x1e, 0x95, 0x15}, {0x1e, 0x95, 0x11}}, // ATmega324A vs ATmega324PA + {{0x1e, 0x95, 0x08}, {0x1e, 0x95, 0x11}}, // ATmega324P vs ATmega324PA + {{0x1e, 0x95, 0x06}, {0x1e, 0x95, 0x0e}}, // ATmega3250=ATmega3250A vs ATmega3250P=ATmega3250PA + {{0x1e, 0x95, 0x05}, {0x1e, 0x95, 0x0d}}, // ATmega325=ATmega325A vs ATmega325P=ATmega325PA + {{0x1e, 0x95, 0x04}, {0x1e, 0x95, 0x0c}}, // ATmega3290=ATmega3290A vs ATmega3290P=ATmega3290PA + {{0x1e, 0x95, 0x03}, {0x1e, 0x95, 0x0b}}, // ATmega329=ATmega329A vs ATmega329P=ATmega329PA + {{0x1e, 0x92, 0x05}, {0x1e, 0x92, 0x0a}}, // ATmega48=ATmega48A vs ATmega48P=ATmega48PA + {{0x1e, 0x92, 0x05}, {0x1e, 0x92, 0x0a}}, // ATmega48=ATmega48A vs ATmega48P=ATmega48PA + {{0x1e, 0x96, 0x09}, {0x1e, 0x96, 0x0a}}, // ATmega644=ATmega644A vs ATmega644P=ATmega644PA + {{0x1e, 0xa6, 0x03}, {0x1e, 0xa6, 0x02}}, // ATmega644RFR2 vs ATmega64RFR2 + {{0x1e, 0x96, 0x06}, {0x1e, 0x96, 0x0e}}, // ATmega6450=ATmega6450A vs ATmega6450P + {{0x1e, 0x96, 0x05}, {0x1e, 0x96, 0x0d}}, // ATmega645=ATmega645A vs ATmega645P + {{0x1e, 0x96, 0x04}, {0x1e, 0x96, 0x0c}}, // ATmega6490=ATmega6490A vs ATmega6490P + {{0x1e, 0x96, 0x03}, {0x1e, 0x96, 0x0b}}, // ATmega649=ATmega649A vs ATmega649P + {{0x1e, 0x93, 0x0a}, {0x1e, 0x93, 0x0f}}, // ATmega88=ATmega88A=ATA6612C vs ATmega88P=ATmega88PA }; if(!memcmp(sig1, sig2, 3)) @@ -1122,29 +1113,25 @@ int avr_sig_compatible(const unsigned char *sig1, const unsigned char *sig2) { } /* - * Iterate over the list of avrparts given as "avrparts", and - * call the callback function cb for each entry found. cb is being - * passed the following arguments: - * . the name of the avrpart (for -p) - * . the descriptive text given in the config file - * . the name of the config file this avrpart has been defined in - * . the line number of the config file this avrpart has been defined at - * . the "cookie" passed into walk_avrparts() (opaque client data) + * Iterate over the list of avrparts given as "avrparts", and call the callback + * function cb for each entry found. cb is being passed the following arguments: + * - Name of the avrpart (for -p) + * - Descriptive text given in the config file + * - Name of the config file this avrpart has been defined in + * - Line number of the config file this avrpart has been defined at + * - Cookie passed into walk_avrparts() (opaque client data) */ -void walk_avrparts(LISTID avrparts, walk_avrparts_cb cb, void *cookie) -{ +void walk_avrparts(LISTID avrparts, walk_avrparts_cb cb, void *cookie) { LNODEID ln1; - AVRPART * p; + AVRPART *p; - for (ln1 = lfirst(avrparts); ln1; ln1 = lnext(ln1)) { + for(ln1 = lfirst(avrparts); ln1; ln1 = lnext(ln1)) { p = ldata(ln1); cb(p->id, p->desc, p->config_file, p->lineno, cookie); } } -/* - * Compare function to sort a list of parts - */ +// Compare function to sort a list of parts static int sort_avrparts_compare(const AVRPART *p1, const AVRPART *p2) { if(p1 == NULL || p1->desc == NULL || p2 == NULL || p2->desc == NULL) return 0; @@ -1152,15 +1139,11 @@ static int sort_avrparts_compare(const AVRPART *p1, const AVRPART *p2) { return strcasecmp(p1->desc, p2->desc); } -/* - * Sort the list avrparts of parts - */ -void sort_avrparts(LISTID avrparts) -{ - lsort(avrparts,(int (*)(void*, void*)) sort_avrparts_compare); +// Sort the list avrparts of parts +void sort_avrparts(LISTID avrparts) { + lsort(avrparts, (int (*)(void *, void *)) sort_avrparts_compare); } - void avr_display(FILE *f, const PROGRAMMER *pgm, const AVRPART *p, const char *prefix, int verbose) { fprintf(f, "%sAVR part : %s\n", prefix, p->desc); fprintf(f, "%sProgramming modes : %s\n", prefix, str_prog_modes(p->prog_modes)); @@ -1171,7 +1154,6 @@ void avr_display(FILE *f, const PROGRAMMER *pgm, const AVRPART *p, const char *p } } - char cmdbitchar(CMDBIT cb) { switch(cb.type) { case AVR_CMDBIT_IGNORE: @@ -1189,20 +1171,18 @@ char cmdbitchar(CMDBIT cb) { } } - char *cmdbitstr(CMDBIT cb) { char space[32]; *space = cmdbitchar(cb); if(*space == 'a') - sprintf(space+1, "%d", cb.bitno); + sprintf(space + 1, "%d", cb.bitno); else space[1] = 0; return mmt_strdup(space); } - const char *opcodename(int opnum) { switch(opnum) { case AVR_OP_READ: @@ -1234,7 +1214,6 @@ const char *opcodename(int opnum) { } } - // Unique string representation of an opcode char *opcode2str(const OPCODE *op, int opnum, int detailed) { char cb, space[1024], *sp = space; @@ -1244,10 +1223,10 @@ char *opcode2str(const OPCODE *op, int opnum, int detailed) { return mmt_strdup("NULL"); // Can the opcode be printed in a compact way? Only if i, o and a bits are systematic. - for(int i=31; i >= 0; i--) + for(int i = 31; i >= 0; i--) switch(op->bit[i].type) { case AVR_CMDBIT_ADDRESS: - if(i<8 || i>23 || op->bit[i].bitno != (opnum == AVR_OP_LOAD_EXT_ADDR? i+8: i-8)) + if(i < 8 || i > 23 || op->bit[i].bitno != (opnum == AVR_OP_LOAD_EXT_ADDR? i + 8: i - 8)) compact = 0; break; case AVR_CMDBIT_INPUT: @@ -1259,10 +1238,10 @@ char *opcode2str(const OPCODE *op, int opnum, int detailed) { if(detailed) *sp++ = '"'; - for(int i=31; i >= 0; i--) { + for(int i = 31; i >= 0; i--) { cb = cmdbitchar(op->bit[i]); printbit = cb == 'a' || ((strchr("io", cb) && op->bit[i].bitno != i%8)); - *sp++ = !detailed && !compact && printbit? toupper(cb): cb; // Disambiguate tsv output + *sp++ = !detailed && !compact && printbit? toupper(cb): cb; // Disambiguate tsv output if(!compact && printbit) { sprintf(sp, "%d", op->bit[i].bitno); sp += strlen(sp); @@ -1288,7 +1267,6 @@ char *opcode2str(const OPCODE *op, int opnum, int detailed) { return mmt_strdup(space); } - // Returns 1 if the part pointed to by p matches the string or pattern s under the function cmp(s, ...) int part_eq(AVRPART *p, const char *s, int (*cmp)(const char *, const char *)) { // Matching id or desc? OK @@ -1298,14 +1276,17 @@ int part_eq(AVRPART *p, const char *s, int (*cmp)(const char *, const char *)) { // Check against all variants, either up to colon or up to dash size_t desclen = strlen(p->desc), variantlen, dashlen; char query[1024]; + for(LNODEID ln = lfirst(p->variants); ln; ln = lnext(ln)) { const char *q = (const char *) ldata(ln), *qdash = strchr(q, '-'), *qcolon = strchr(q, ':'); - variantlen = qcolon? (size_t) (qcolon-q): strlen(q); - dashlen = qdash? (size_t) (qdash-q): variantlen; - if(variantlen < sizeof query) { // Sanity: should not expect such long strings + + variantlen = qcolon? (size_t) (qcolon - q): strlen(q); + dashlen = qdash? (size_t) (qdash - q): variantlen; + if(variantlen < sizeof query) { // Sanity: should not expect such long strings // Variant names should be unique order numbers, but don't check (again) if it's the same as p->desc if(variantlen != desclen || memcmp(q, p->desc, desclen)) { - memcpy(query, q, variantlen); query[variantlen] = 0; + memcpy(query, q, variantlen); + query[variantlen] = 0; if(cmp(s, query)) return 1; // The name before dash should normally be p->desc and the dash is meant to come before the colon diff --git a/src/bitbang.c b/src/bitbang.c index 59e506d26..76f245a43 100644 --- a/src/bitbang.c +++ b/src/bitbang.c @@ -47,114 +47,102 @@ #define freq (*(LARGE_INTEGER *)&cx->bb_freq) #else static void alarmhandler(int signo) { - *(volatile int *)&cx->bb_done = 1; + *(volatile int *) &cx->bb_done = 1; signal(SIGALRM, cx->bb_saved_alarmf); } -#endif /* WIN32 */ +#endif // WIN32 + +// Calibrate the microsecond delay loop below +static void bitbang_calibrate_delay(void) { -/* - * Calibrate the microsecond delay loop below. - */ -static void bitbang_calibrate_delay(void) -{ #if defined(WIN32) /* - * If the hardware supports a high-resolution performance counter, - * we ultimately prefer that one, as it gives quite accurate delays - * on modern high-speed CPUs. + * If the hardware supports a high-resolution performance counter, we + * ultimately prefer that one, as it gives quite accurate delays on modern + * high-speed CPUs. */ - if (QueryPerformanceFrequency(&freq)) - { + if(QueryPerformanceFrequency(&freq)) { cx->bb_has_perfcount = 1; pmsg_notice2("using performance counter for bitbang delays\n"); - } - else - { + } else { /* - * If a high-resolution performance counter is not available, we - * don't have any Win32 implementation for setting up the - * per-microsecond delay count, so we can only run on a - * preconfigured delay stepping there. The figure below should at - * least be correct within an order of magnitude, judging from the - * auto-calibration figures seen on various Unix systems on + * If a high-resolution performance counter is not available, we don't have + * any Win32 implementation for setting up the per-microsecond delay count, + * so we can only run on a preconfigured delay stepping there. The figure + * below should at least be correct within an order of magnitude, judging + * from the auto-calibration figures seen on various Unix systems on * comparable hardware. */ pmsg_notice2("using guessed per-microsecond delay count for bitbang delays\n"); cx->bb_delay_decrement = 100; } -#else /* !WIN32 */ +#else // !WIN32 struct itimerval itv; volatile int i; pmsg_notice2("calibrating delay loop ..."); i = 0; - *(volatile int *)&cx->bb_done = 0; + *(volatile int *) &cx->bb_done = 0; cx->bb_saved_alarmf = signal(SIGALRM, alarmhandler); /* - * Set ITIMER_REAL to 100 ms. All known systems have a timer - * granularity of 10 ms or better, so counting the delay cycles - * accumulating over 100 ms should give us a rather realistic - * picture, without annoying the user by a lengthy startup time (as - * an alarm(1) would do). Of course, if heavy system activity - * happens just during calibration but stops before the remaining - * part of AVRDUDE runs, this will yield wrong values. There's not + * Set ITIMER_REAL to 100 ms. All known systems have a timer granularity of + * 10 ms or better, so counting the delay cycles accumulating over 100 ms + * should give us a rather realistic picture, without annoying the user by a + * lengthy startup time (as an alarm(1) would do). Of course, if heavy + * system activity happens just during calibration but stops before the + * remaining part of AVRDUDE runs, this will yield wrong values. There's not * much we can do about this. */ itv.it_value.tv_sec = 0; itv.it_value.tv_usec = 100000; itv.it_interval.tv_sec = itv.it_interval.tv_usec = 0; setitimer(ITIMER_REAL, &itv, 0); - while (!*(volatile int *)&cx->bb_done) + while(!*(volatile int *) &cx->bb_done) i--; itv.it_value.tv_sec = itv.it_value.tv_usec = 0; setitimer(ITIMER_REAL, &itv, 0); - /* - * Calculate back from 100 ms to 1 us. - */ - cx->bb_delay_decrement = -i / 100000; + // Calculate back from 100 ms to 1 us + cx->bb_delay_decrement = -i/100000; msg_notice2(" calibrated to %d cycles per us\n", cx->bb_delay_decrement); -#endif /* WIN32 */ +#endif // WIN32 } /* - * Delay for approximately the number of microseconds specified. - * usleep()'s granularity is usually like 1 ms or 10 ms, so it's not - * really suitable for short delays in bit-bang algorithms. + * Delay for approximately the number of microseconds specified. usleep()'s + * granularity is usually like 1 ms or 10 ms, so it's not really suitable for + * short delays in bit-bang algorithms. */ -void bitbang_delay(unsigned int us) -{ +void bitbang_delay(unsigned int us) { + #if defined(WIN32) LARGE_INTEGER countNow, countEnd; - if (cx->bb_has_perfcount) - { + if(cx->bb_has_perfcount) { QueryPerformanceCounter(&countNow); - countEnd.QuadPart = countNow.QuadPart + freq.QuadPart * us / 1000000ll; + countEnd.QuadPart = countNow.QuadPart + freq.QuadPart*us/1000000ll; - while (countNow.QuadPart < countEnd.QuadPart) + while(countNow.QuadPart < countEnd.QuadPart) QueryPerformanceCounter(&countNow); - } - else /* no performance counters -- run normal uncalibrated delay */ - { -#endif /* WIN32 */ - volatile unsigned int del = us * cx->bb_delay_decrement; + } else { // No performance counters -- run normal uncalibrated delay +#endif + + volatile unsigned int del = us*cx->bb_delay_decrement; + + while(del > 0) + del--; - while (del > 0) - del--; #if defined(WIN32) } -#endif /* WIN32 */ +#endif } -/* - * transmit and receive a byte of data to/from the AVR device - */ +// Transmit and receive a byte of data to/from the AVR device static unsigned char bitbang_txrx(const PROGRAMMER *pgm, unsigned char byte) { int i; unsigned char r, b, rbyte; rbyte = 0; - for (i=7; i>=0; i--) { + for(i = 7; i >= 0; i--) { /* * Write and read one bit on SPI. * Some notes on timing: Let T be the time it takes to do @@ -167,22 +155,19 @@ static unsigned char bitbang_txrx(const PROGRAMMER *pgm, unsigned char byte) { * So we are within programming specs (expect for AT90S1200), * if and only if T>t_CLCL (t_CLCL=clock period of target system). * - * Due to the delay introduced by "IN" and "OUT"-commands, - * T is greater than 1us (more like 2us) on x86-architectures. - * So programming works safely down to 1MHz target clock. - */ + * Due to the delay introduced by "IN" and "OUT"-commands, T is greater + * than 1us (more like 2us) on x86-architectures. So programming works + * safely down to 1MHz target clock. + */ b = (byte >> i) & 0x01; - /* set the data input line as desired */ + // Set the data input line as desired pgm->setpin(pgm, PIN_AVR_SDO, b); pgm->setpin(pgm, PIN_AVR_SCK, 1); - /* - * read the result bit (it is either valid from a previous falling - * edge or it is ignored in the current context) - */ + // The result bit is either valid from a previous falling edge or ignored in current context r = pgm->getpin(pgm, PIN_AVR_SDI); pgm->setpin(pgm, PIN_AVR_SCK, 0); @@ -193,8 +178,9 @@ static unsigned char bitbang_txrx(const PROGRAMMER *pgm, unsigned char byte) { return rbyte; } -static int bitbang_tpi_clk(const PROGRAMMER *pgm) { +static int bitbang_tpi_clk(const PROGRAMMER *pgm) { unsigned char r = 0; + pgm->setpin(pgm, PIN_AVR_SCK, 1); r = pgm->getpin(pgm, PIN_AVR_SDI); @@ -204,77 +190,77 @@ static int bitbang_tpi_clk(const PROGRAMMER *pgm) { return r; } -void bitbang_tpi_tx(const PROGRAMMER *pgm, unsigned char byte) { +void bitbang_tpi_tx(const PROGRAMMER *pgm, unsigned char byte) { int i; unsigned char b, parity; - /* start bit */ + // Start bit pgm->setpin(pgm, PIN_AVR_SDO, 0); bitbang_tpi_clk(pgm); parity = 0; - for (i = 0; i <= 7; i++) { + for(i = 0; i <= 7; i++) { b = (byte >> i) & 0x01; parity ^= b; - /* set the data input line as desired */ + // Set the data input line as desired pgm->setpin(pgm, PIN_AVR_SDO, b); bitbang_tpi_clk(pgm); } - - /* parity bit */ + + // Parity bit pgm->setpin(pgm, PIN_AVR_SDO, parity); bitbang_tpi_clk(pgm); - /* 2 stop bits */ + // 2 stop bits pgm->setpin(pgm, PIN_AVR_SDO, 1); bitbang_tpi_clk(pgm); bitbang_tpi_clk(pgm); } -int bitbang_tpi_rx(const PROGRAMMER *pgm) { +int bitbang_tpi_rx(const PROGRAMMER *pgm) { int i; unsigned char b, rbyte, parity; - /* make sure pin is on for "pullup" */ + // Make sure pin is on for pullup pgm->setpin(pgm, PIN_AVR_SDO, 1); - /* wait for start bit (up to 10 bits) */ + // Wait for start bit (up to 10 bits) b = 1; - for (i = 0; i < 10; i++) { + for(i = 0; i < 10; i++) { b = bitbang_tpi_clk(pgm); - if (b == 0) + if(b == 0) break; } - if (b != 0) { + if(b != 0) { pmsg_error("start bit not received correctly\n"); return -1; } rbyte = 0; parity = 0; - for (i=0; i<=7; i++) { + for(i = 0; i <= 7; i++) { b = bitbang_tpi_clk(pgm); parity ^= b; rbyte |= b << i; } - /* parity bit */ - if (bitbang_tpi_clk(pgm) != parity) { + // Parity bit + if(bitbang_tpi_clk(pgm) != parity) { pmsg_error("parity bit is wrong\n"); return -1; } - /* 2 stop bits */ + // 2 stop bits b = 1; b &= bitbang_tpi_clk(pgm); b &= bitbang_tpi_clk(pgm); - if (b != 1) { + if(b != 1) { pmsg_error("stop bits not received correctly\n"); return -1; } - + return rbyte; } @@ -298,142 +284,123 @@ int bitbang_vfy_led(const PROGRAMMER *pgm, int value) { return 0; } - /* - * transmit an AVR device command and return the results; 'cmd' and - * 'res' must point to at least a 4 byte data buffer + * Transmit an AVR device command and return the results; 'cmd' and 'res' must + * point to at least a 4 byte data buffer */ -int bitbang_cmd(const PROGRAMMER *pgm, const unsigned char *cmd, - unsigned char *res) -{ +int bitbang_cmd(const PROGRAMMER *pgm, const unsigned char *cmd, unsigned char *res) { int i; - for (i=0; i<4; i++) { + for(i = 0; i < 4; i++) { res[i] = bitbang_txrx(pgm, cmd[i]); } - if(verbose >= MSG_DEBUG) - { - msg_debug("%s(): [ ", __func__); - for(i = 0; i < 4; i++) - msg_debug("%02X ", cmd[i]); - msg_debug("] [ "); - for(i = 0; i < 4; i++) - { - msg_debug("%02X ", res[i]); - } - msg_debug("]\n"); - } + if(verbose >= MSG_DEBUG) { + msg_debug("%s(): [ ", __func__); + for(i = 0; i < 4; i++) + msg_debug("%02X ", cmd[i]); + msg_debug("] [ "); + for(i = 0; i < 4; i++) { + msg_debug("%02X ", res[i]); + } + msg_debug("]\n"); + } return 0; } -int bitbang_cmd_tpi(const PROGRAMMER *pgm, const unsigned char *cmd, - int cmd_len, unsigned char *res, int res_len) -{ +int bitbang_cmd_tpi(const PROGRAMMER *pgm, const unsigned char *cmd, int cmd_len, unsigned char *res, int res_len) { int i, r; - for (i=0; i= MSG_DEBUG) - { + if(verbose >= MSG_DEBUG) { msg_debug("%s(): [ ", __func__); for(i = 0; i < cmd_len; i++) msg_debug("%02X ", cmd[i]); msg_debug("] [ "); - for(i = 0; i < res_len; i++) - { + for(i = 0; i < res_len; i++) { msg_debug("%02X ", res[i]); } msg_debug("]\n"); } - if (r == -1) + if(r == -1) return -1; return 0; } -/* - * transmit bytes via SPI and return the results; 'cmd' and - * 'res' must point to data buffers - */ -int bitbang_spi(const PROGRAMMER *pgm, const unsigned char *cmd, - unsigned char *res, int count) -{ +// Transmit bytes via SPI and return the results; 'cmd' and 'res' must point to data buffers +int bitbang_spi(const PROGRAMMER *pgm, const unsigned char *cmd, unsigned char *res, int count) { int i; pgm->setpin(pgm, PIN_LED_PGM, 0); - for (i=0; isetpin(pgm, PIN_LED_PGM, 1); - if(verbose >= MSG_DEBUG) - { - msg_debug("%s(): [ ", __func__); - for(i = 0; i < count; i++) - msg_debug("%02X ", cmd[i]); - msg_debug("] [ "); - for(i = 0; i < count; i++) - { - msg_debug("%02X ", res[i]); - } - msg_debug("]\n"); - } + if(verbose >= MSG_DEBUG) { + msg_debug("%s(): [ ", __func__); + for(i = 0; i < count; i++) + msg_debug("%02X ", cmd[i]); + msg_debug("] [ "); + for(i = 0; i < count; i++) { + msg_debug("%02X ", res[i]); + } + msg_debug("]\n"); + } return 0; } - -/* - * issue the 'chip erase' command to the AVR device - */ +// Issue the 'chip erase' command to the AVR device int bitbang_chip_erase(const PROGRAMMER *pgm, const AVRPART *p) { unsigned char cmd[4]; unsigned char res[4]; AVRMEM *mem; - if (p->prog_modes & PM_TPI) { + if(is_tpi(p)) { - while (avr_tpi_poll_nvmbsy(pgm)); + while(avr_tpi_poll_nvmbsy(pgm)); - /* NVMCMD <- CHIP_ERASE */ + // NVMCMD <- CHIP_ERASE bitbang_tpi_tx(pgm, TPI_CMD_SOUT | TPI_SIO_ADDR(TPI_IOREG_NVMCMD)); - bitbang_tpi_tx(pgm, TPI_NVMCMD_CHIP_ERASE); /* CHIP_ERASE */ + bitbang_tpi_tx(pgm, TPI_NVMCMD_CHIP_ERASE); // CHIP_ERASE - /* Set Pointer Register */ + // Set Pointer Register mem = avr_locate_flash(p); - if (mem == NULL) { + if(mem == NULL) { pmsg_error("no flash memory to erase for part %s\n", p->desc); return -1; } bitbang_tpi_tx(pgm, TPI_CMD_SSTPR | 0); - bitbang_tpi_tx(pgm, (mem->offset & 0xFF) | 1); /* high byte */ + bitbang_tpi_tx(pgm, (mem->offset & 0xFF) | 1); // High byte bitbang_tpi_tx(pgm, TPI_CMD_SSTPR | 1); bitbang_tpi_tx(pgm, (mem->offset >> 8) & 0xFF); - /* write dummy value to start erase */ + // Write dummy value to start erase bitbang_tpi_tx(pgm, TPI_CMD_SST); bitbang_tpi_tx(pgm, 0xFF); - while (avr_tpi_poll_nvmbsy(pgm)); + while(avr_tpi_poll_nvmbsy(pgm)); return 0; } - if (p->op[AVR_OP_CHIP_ERASE] == NULL) { + if(p->op[AVR_OP_CHIP_ERASE] == NULL) { pmsg_error("chip erase instruction not defined for part %s\n", p->desc); return -1; } @@ -448,27 +415,25 @@ int bitbang_chip_erase(const PROGRAMMER *pgm, const AVRPART *p) { return 0; } -/* - * issue the 'program enable' command to the AVR device - */ +// Issue the 'program enable' command to the AVR device int bitbang_program_enable(const PROGRAMMER *pgm, const AVRPART *p) { unsigned char cmd[4]; unsigned char res[4]; int i; - if (p->prog_modes & PM_TPI) { - /* enable NVM programming */ + if(is_tpi(p)) { + // Enable NVM programming bitbang_tpi_tx(pgm, TPI_CMD_SKEY); - for (i = sizeof(tpi_skey) - 1; i >= 0; i--) + for(i = sizeof(tpi_skey) - 1; i >= 0; i--) bitbang_tpi_tx(pgm, tpi_skey[i]); - /* check NVMEN bit */ + // Check NVMEN bit bitbang_tpi_tx(pgm, TPI_CMD_SLDCS | TPI_REG_TPISR); i = bitbang_tpi_rx(pgm); - return (i != -1 && (i & TPI_REG_TPISR_NVMEN)) ? 0 : -2; + return (i != -1 && (i & TPI_REG_TPISR_NVMEN))? 0: -2; } - if (p->op[AVR_OP_PGM_ENABLE] == NULL) { + if(p->op[AVR_OP_PGM_ENABLE] == NULL) { pmsg_error("program enable instruction not defined for part %s\n", p->desc); return -1; } @@ -477,15 +442,13 @@ int bitbang_program_enable(const PROGRAMMER *pgm, const AVRPART *p) { avr_set_bits(p->op[AVR_OP_PGM_ENABLE], cmd); pgm->cmd(pgm, cmd, res); - if (res[2] != cmd[1]) + if(res[2] != cmd[1]) return -2; return 0; } -/* - * initialize the AVR device and prepare it to accept commands - */ +// Initialize the AVR device and prepare it to accept commands int bitbang_initialize(const PROGRAMMER *pgm, const AVRPART *p) { int rc; int tries; @@ -496,30 +459,30 @@ int bitbang_initialize(const PROGRAMMER *pgm, const AVRPART *p) { pgm->powerup(pgm); usleep(20000); - /* TPIDATA is a single line, so SDI & SDO should be connected */ - if (p->prog_modes & PM_TPI) { - /* make sure cmd_tpi() is defined */ - if (pgm->cmd_tpi == NULL) { + // TPIDATA is a single line, so SDI & SDO should be connected + if(is_tpi(p)) { + // Make sure cmd_tpi() is defined + if(pgm->cmd_tpi == NULL) { pmsg_error("%s programmer does not support TPI\n", pgm->type); return -1; } - /* bring RESET high first */ + // Bring RESET high first pgm->setpin(pgm, PIN_AVR_RESET, 1); - usleep(128000); /* wait t_TOUT (32-128ms) */ + usleep(128000); // Wait t_TOUT (32-128ms) - /* RESET must be LOW in case the existing code is driving the TPI pins: */ + // RESET must be LOW in case the existing code is driving the TPI pins pgm->setpin(pgm, PIN_AVR_RESET, 0); msg_notice2("doing SDO-SDI link check\n"); pgm->setpin(pgm, PIN_AVR_SDO, 0); - if (pgm->getpin(pgm, PIN_AVR_SDI) != 0) { + if(pgm->getpin(pgm, PIN_AVR_SDI) != 0) { pmsg_error("SDO->SDI 0 failed\n"); return -1; } pgm->setpin(pgm, PIN_AVR_SDO, 1); - if (pgm->getpin(pgm, PIN_AVR_SDI) != 1) { + if(pgm->getpin(pgm, PIN_AVR_SDI) != 1) { pmsg_error("SDO->SDI 1 failed\n"); return -1; } @@ -531,20 +494,20 @@ int bitbang_initialize(const PROGRAMMER *pgm, const AVRPART *p) { pgm->setpin(pgm, PIN_AVR_RESET, 0); usleep(20000); - if (p->prog_modes & PM_TPI) { - /* keep TPIDATA high for 16 clock cycles */ + if(is_tpi(p)) { + // Keep TPIDATA high for 16 clock cycles pgm->setpin(pgm, PIN_AVR_SDO, 1); - for (i = 0; i < 16; i++) + for(i = 0; i < 16; i++) pgm->highpulsepin(pgm, PIN_AVR_SCK); - /* remove extra guard timing bits */ + // Remove extra guard timing bits bitbang_tpi_tx(pgm, TPI_CMD_SSTCS | TPI_REG_TPIPCR); bitbang_tpi_tx(pgm, 0x7); - /* read TPI ident reg */ + // Read TPI ident reg bitbang_tpi_tx(pgm, TPI_CMD_SLDCS | TPI_REG_TPIIR); rc = bitbang_tpi_rx(pgm); - if (rc != 0x80) { + if(rc != 0x80) { pmsg_error("TPIIR not correct\n"); return -1; } @@ -552,33 +515,29 @@ int bitbang_initialize(const PROGRAMMER *pgm, const AVRPART *p) { pgm->highpulsepin(pgm, PIN_AVR_RESET); } - usleep(20000); /* 20 ms XXX should be a per-chip parameter */ + usleep(20000); // 20 ms XXX should be a per-chip parameter /* - * Enable programming mode. If we are programming an AT90S1200, we - * can only issue the command and hope it worked. If we are using - * one of the other chips, the chip will echo 0x53 when issuing the - * third byte of the command. In this case, try up to 32 times in - * order to possibly get back into sync with the chip if we are out - * of sync. + * Enable programming mode. If we are programming an AT90S1200, we can only + * issue the command and hope it worked. If we are using one of the other + * chips, the chip will echo 0x53 when issuing the third byte of the command. + * In this case, try up to 32 times in order to possibly get back into sync + * with the chip if we are out of sync. */ - if (p->flags & AVRPART_IS_AT90S1200) { + if(p->flags & AVRPART_IS_AT90S1200) { pgm->program_enable(pgm, p); - } - else { + } else { tries = 0; do { rc = pgm->program_enable(pgm, p); - if ((rc == 0)||(rc == -1)) + if((rc == 0) || (rc == -1)) break; - pgm->highpulsepin(pgm, p->retry_pulse/*PIN_AVR_SCK*/); + pgm->highpulsepin(pgm, p->retry_pulse); // PIN_AVR_SCK tries++; - } while (tries < 65); + } while(tries < 65); - /* - * can't sync with the device, maybe it's not attached? - */ - if (rc) { + // Can't sync with the device, maybe it's not attached? + if(rc) { pmsg_error("AVR device not responding\n"); return -1; } @@ -593,29 +552,26 @@ static int verify_pin_assigned(const PROGRAMMER *pgm, int pinfunc, char *desc) { return -1; } - if ((pgm->pinno[pinfunc] & PIN_MASK) > PIN_MAX) { + if((pgm->pinno[pinfunc] & PIN_MASK) > PIN_MAX) { pmsg_error("no pin has been assigned for %s\n", desc); return -1; } return 0; } - -/* - * Verify all prerequisites for a bit-bang programmer are present. - */ +// Verify all prerequisites for a bit-bang programmer are present int bitbang_check_prerequisites(const PROGRAMMER *pgm) { - if (verify_pin_assigned(pgm, PIN_AVR_RESET, "AVR RESET") < 0) + if(verify_pin_assigned(pgm, PIN_AVR_RESET, "AVR RESET") < 0) return -1; - if (verify_pin_assigned(pgm, PIN_AVR_SCK, "AVR SCK") < 0) + if(verify_pin_assigned(pgm, PIN_AVR_SCK, "AVR SCK") < 0) return -1; - if (verify_pin_assigned(pgm, PIN_AVR_SDI, "AVR SDI") < 0) + if(verify_pin_assigned(pgm, PIN_AVR_SDI, "AVR SDI") < 0) return -1; - if (verify_pin_assigned(pgm, PIN_AVR_SDO, "AVR SDO") < 0) + if(verify_pin_assigned(pgm, PIN_AVR_SDO, "AVR SDO") < 0) return -1; - if (pgm->cmd == NULL) { + if(pgm->cmd == NULL) { pmsg_error("no cmd() method defined for bitbang programmer\n"); return -1; } diff --git a/src/bitbang.h b/src/bitbang.h index 93a401e7f..6b48eac26 100644 --- a/src/bitbang.h +++ b/src/bitbang.h @@ -25,33 +25,29 @@ extern "C" { #endif -int bitbang_setpin(int fd, int pin, int value); -int bitbang_getpin(int fd, int pin); -int bitbang_highpulsepin(int fd, int pin); -void bitbang_delay(unsigned int us); + int bitbang_setpin(int fd, int pin, int value); + int bitbang_getpin(int fd, int pin); + int bitbang_highpulsepin(int fd, int pin); + void bitbang_delay(unsigned int us); -int bitbang_check_prerequisites(const PROGRAMMER *pgm); + int bitbang_check_prerequisites(const PROGRAMMER *pgm); -int bitbang_rdy_led (const PROGRAMMER *pgm, int value); -int bitbang_err_led (const PROGRAMMER *pgm, int value); -int bitbang_pgm_led (const PROGRAMMER *pgm, int value); -int bitbang_vfy_led (const PROGRAMMER *pgm, int value); -int bitbang_cmd (const PROGRAMMER *pgm, const unsigned char *cmd, - unsigned char *res); -int bitbang_cmd_tpi (const PROGRAMMER *pgm, const unsigned char *cmd, - int cmd_len, unsigned char *res, int res_len); -int bitbang_spi (const PROGRAMMER *pgm, const unsigned char *cmd, - unsigned char *res, int count); -int bitbang_chip_erase (const PROGRAMMER *pgm, const AVRPART *p); -int bitbang_program_enable (const PROGRAMMER *pgm, const AVRPART *p); -void bitbang_powerup (const PROGRAMMER *pgm); -void bitbang_powerdown (const PROGRAMMER *pgm); -int bitbang_initialize (const PROGRAMMER *pgm, const AVRPART *p); -void bitbang_disable (const PROGRAMMER *pgm); -void bitbang_enable (PROGRAMMER *pgm, const AVRPART *p); + int bitbang_rdy_led(const PROGRAMMER *pgm, int value); + int bitbang_err_led(const PROGRAMMER *pgm, int value); + int bitbang_pgm_led(const PROGRAMMER *pgm, int value); + int bitbang_vfy_led(const PROGRAMMER *pgm, int value); + int bitbang_cmd(const PROGRAMMER *pgm, const unsigned char *cmd, unsigned char *res); + int bitbang_cmd_tpi(const PROGRAMMER *pgm, const unsigned char *cmd, int cmd_len, unsigned char *res, int res_len); + int bitbang_spi(const PROGRAMMER *pgm, const unsigned char *cmd, unsigned char *res, int count); + int bitbang_chip_erase(const PROGRAMMER *pgm, const AVRPART *p); + int bitbang_program_enable(const PROGRAMMER *pgm, const AVRPART *p); + void bitbang_powerup(const PROGRAMMER *pgm); + void bitbang_powerdown(const PROGRAMMER *pgm); + int bitbang_initialize(const PROGRAMMER *pgm, const AVRPART *p); + void bitbang_disable(const PROGRAMMER *pgm); + void bitbang_enable(PROGRAMMER *pgm, const AVRPART *p); #ifdef __cplusplus } #endif - #endif diff --git a/src/buspirate.c b/src/buspirate.c index eab3bc80e..225c9b862 100644 --- a/src/buspirate.c +++ b/src/buspirate.c @@ -46,7 +46,8 @@ #include "bitbang.h" #include "buspirate.h" -/* ====== Private data structure ====== */ +// ====== Private data structure ====== + /* CS and AUX pin bitmasks in * 0100wxyz - Configure peripherals command */ #define BP_RESET_CS 0x01 @@ -64,1291 +65,1279 @@ #define BP_FLAG_PULLUPS (1<<8) #define BP_FLAG_HIZ (1<<9) -struct pdata -{ - int binmode_version; - int submode_version; - int current_peripherals_config; - int spifreq; /* For "set speed" commands */ - int cpufreq; /* (125)..4000 kHz - see buspirate manual */ - int serial_recv_timeout; /* timeout in ms, default 100 */ - int reset; /* See BP_RESET_* above */ - unsigned char pin_dir; /* Last written pin direction for bitbang mode */ - unsigned char pin_val; /* Last written pin values for bitbang mode */ - int unread_bytes; /* How many bytes we expected, but ignored */ - int flag; - char buf_local[100]; /* Local buffer for buspirate_readline_noexit() */ +struct pdata { + int binmode_version; + int submode_version; + int current_peripherals_config; + int spifreq; // For "set speed" commands + int cpufreq; // (125)..4000 kHz - see buspirate manual + int serial_recv_timeout; // Timeout in ms, default 100 + int reset; // See BP_RESET_* above + unsigned char pin_dir; // Last written pin direction for bitbang mode + unsigned char pin_val; // Last written pin values for bitbang mode + int unread_bytes; // How many bytes we expected, but ignored + int flag; + char buf_local[100]; // Local buffer for buspirate_readline_noexit() }; -#define PDATA(pgm) ((struct pdata *)(pgm->cookie)) -/* ====== Feature checks ====== */ +#define my (*(struct pdata *) (pgm->cookie)) + +// ====== Feature checks ====== static inline int buspirate_uses_ascii(const PROGRAMMER *pgm) { - return (PDATA(pgm)->flag & BP_FLAG_XPARM_FORCE_ASCII); + return (my.flag & BP_FLAG_XPARM_FORCE_ASCII); } static inline int buspirate_uses_pullups(const PROGRAMMER *pgm) { - return (PDATA(pgm)->flag & BP_FLAG_PULLUPS); + return (my.flag & BP_FLAG_PULLUPS); } static inline int buspirate_uses_hiz(const PROGRAMMER *pgm) { - return (PDATA(pgm)->flag & BP_FLAG_HIZ); + return (my.flag & BP_FLAG_HIZ); } -/* ====== Serial talker functions - binmode ====== */ - -static void dump_mem(const unsigned char *buf, size_t len) -{ - size_t i; - - for (i = 0; ifd, data, len); + rc = serial_send(&pgm->fd, data, len); - return rc; + return rc; } static int buspirate_recv_bin(const PROGRAMMER *pgm, unsigned char *buf, size_t len) { - int rc; + int rc; - rc = serial_recv(&pgm->fd, buf, len); - if (rc < 0) - return EOF; + rc = serial_recv(&pgm->fd, buf, len); + if(rc < 0) + return EOF; - pmsg_debug("buspirate_recv_bin():\n"); - dump_mem(buf, len); + pmsg_debug("buspirate_recv_bin():\n"); + dump_mem(buf, len); - return len; + return len; } static int buspirate_expect_bin(const PROGRAMMER *pgm, - unsigned char *send_data, size_t send_len, - unsigned char *expect_data, size_t expect_len) -{ - unsigned char *recv_buf = alloca(expect_len); - if ((PDATA(pgm)->flag & BP_FLAG_IN_BINMODE) == 0) { - pmsg_error("called from ascii mode\n"); - return -1; - } - - buspirate_send_bin(pgm, send_data, send_len); - buspirate_recv_bin(pgm, recv_buf, expect_len); - if (memcmp(expect_data, recv_buf, expect_len) != 0) - return 0; - return 1; + unsigned char *send_data, size_t send_len, unsigned char *expect_data, size_t expect_len) { + unsigned char *recv_buf = alloca(expect_len); + + if((my.flag & BP_FLAG_IN_BINMODE) == 0) { + pmsg_error("called from ascii mode\n"); + return -1; + } + + buspirate_send_bin(pgm, send_data, send_len); + buspirate_recv_bin(pgm, recv_buf, expect_len); + if(memcmp(expect_data, recv_buf, expect_len) != 0) + return 0; + return 1; } -static int buspirate_expect_bin_byte(const PROGRAMMER *pgm, - unsigned char send_byte, unsigned char expect_byte) -{ - return buspirate_expect_bin(pgm, &send_byte, 1, &expect_byte, 1); +static int buspirate_expect_bin_byte(const PROGRAMMER *pgm, unsigned char send_byte, unsigned char expect_byte) { + return buspirate_expect_bin(pgm, &send_byte, 1, &expect_byte, 1); } -/* ====== Serial talker functions - ascii mode ====== */ +// ====== Serial talker functions - ASCII mode ====== static int buspirate_getc(const PROGRAMMER *pgm) { - int rc; - unsigned char ch = 0; - - if (PDATA(pgm)->flag & BP_FLAG_IN_BINMODE) { - pmsg_error("called from binmode\n"); - return EOF; - } - - rc = serial_recv(&pgm->fd, &ch, 1); - if (rc < 0) - return EOF; - return ch; + int rc; + unsigned char ch = 0; + + if(my.flag & BP_FLAG_IN_BINMODE) { + pmsg_error("called from binmode\n"); + return EOF; + } + + rc = serial_recv(&pgm->fd, &ch, 1); + if(rc < 0) + return EOF; + return ch; } static char *buspirate_readline_noexit(const PROGRAMMER *pgm, char *buf, size_t len) { - char *buf_p; - int c; - long orig_serial_recv_timeout = serial_recv_timeout; - - if (buf == NULL) { - buf = PDATA(pgm)->buf_local; - len = sizeof(PDATA(pgm)->buf_local); - } - buf_p = buf; - memset(buf, 0, len); - while (buf_p < (buf + len - 1)) { /* keep the very last byte == 0 */ - *buf_p = c = buspirate_getc(pgm); - if (c == '\r') - continue; - if (c == '\n') - break; - if (c == EOF) { - *buf_p = '\0'; - break; - } - buf_p++; - serial_recv_timeout = PDATA(pgm)->serial_recv_timeout; - } - serial_recv_timeout = orig_serial_recv_timeout; - pmsg_debug("%s(): %s%s", __func__, buf, *buf && buf[strlen(buf)-1] == '\n'? "": "\n"); - if (! buf[0]) - return NULL; - - return buf; + char *buf_p; + int c; + long orig_serial_recv_timeout = serial_recv_timeout; + + if(buf == NULL) { + buf = my.buf_local; + len = sizeof(my.buf_local); + } + buf_p = buf; + memset(buf, 0, len); + while(buf_p < (buf + len - 1)) { // Keep the very last byte == 0 + *buf_p = c = buspirate_getc(pgm); + if(c == '\r') + continue; + if(c == '\n') + break; + if(c == EOF) { + *buf_p = '\0'; + break; + } + buf_p++; + serial_recv_timeout = my.serial_recv_timeout; + } + serial_recv_timeout = orig_serial_recv_timeout; + pmsg_debug("%s(): %s%s", __func__, buf, *buf && buf[strlen(buf) - 1] == '\n'? "": "\n"); + if(!buf[0]) + return NULL; + + return buf; } static char *buspirate_readline(const PROGRAMMER *pgm, char *buf, size_t len) { - char *ret; - - ret = buspirate_readline_noexit(pgm, buf, len); - if (! ret) { - pmsg_error("programmer is not responding\n"); - return NULL; - } - return ret; + char *ret; + + ret = buspirate_readline_noexit(pgm, buf, len); + if(!ret) { + pmsg_error("programmer is not responding\n"); + return NULL; + } + return ret; } static int buspirate_send(const PROGRAMMER *pgm, const char *str) { - int rc; - const char * readline; - - pmsg_debug("%s(): %s", __func__, str); - - if (PDATA(pgm)->flag & BP_FLAG_IN_BINMODE) { - pmsg_error("called from binmode\n"); - return -1; - } - - rc = serial_send(&pgm->fd, (const unsigned char*)str, strlen(str)); - if (rc) - return rc; - do { - readline = buspirate_readline(pgm, NULL, 0); - if (readline == NULL) - return -1; - /* keep reading until we get what we sent there */ - } while (!str_eq(readline, str)); - - /* by now we should be in sync */ - return 0; + int rc; + const char *readline; + + pmsg_debug("%s(): %s", __func__, str); + + if(my.flag & BP_FLAG_IN_BINMODE) { + pmsg_error("called from binmode\n"); + return -1; + } + + rc = serial_send(&pgm->fd, (const unsigned char *) str, strlen(str)); + if(rc) + return rc; + do { + readline = buspirate_readline(pgm, NULL, 0); + if(readline == NULL) + return -1; + // Keep reading until we get what we sent there + } while(!str_eq(readline, str)); + + // By now we should be in sync + return 0; } -static int buspirate_is_prompt(const char *str) -{ - int strlen_str = strlen(str); - /* Prompt ends with '>' or '> ' - * all other input probably ends with '\n' */ - return (str[strlen_str - 1] == '>' || str[strlen_str - 2] == '>'); +static int buspirate_is_prompt(const char *str) { + int strlen_str = strlen(str); + + /* Prompt ends with '>' or '> ' + * all other input probably ends with '\n' */ + return (str[strlen_str - 1] == '>' || str[strlen_str - 2] == '>'); } -static int buspirate_expect(const PROGRAMMER *pgm, char *send, - char *expect, int wait_for_prompt) -{ - int got_it = 0; - char *rcvd; - - buspirate_send(pgm, send); - while (1) { - rcvd = buspirate_readline(pgm, NULL, 0); - if (rcvd == NULL) { - return -1; - } - if (str_starts(rcvd, expect)) { - if (! wait_for_prompt) { - serial_drain(&pgm->fd, 0); - return 1; - } else { - got_it = 1; - } - } - - if (buspirate_is_prompt(rcvd)) - break; - } - return got_it; +static int buspirate_expect(const PROGRAMMER *pgm, char *send, char *expect, int wait_for_prompt) { + int got_it = 0; + char *rcvd; + + buspirate_send(pgm, send); + while(1) { + rcvd = buspirate_readline(pgm, NULL, 0); + if(rcvd == NULL) { + return -1; + } + if(str_starts(rcvd, expect)) { + if(!wait_for_prompt) { + serial_drain(&pgm->fd, 0); + return 1; + } else { + got_it = 1; + } + } + + if(buspirate_is_prompt(rcvd)) + break; + } + return got_it; } -/* ====== Do-nothing functions ====== */ +// ====== Do-nothing functions ====== static void buspirate_dummy_6(const PROGRAMMER *pgm, const char *p) { } -/* ====== Config / parameters handling functions ====== */ +// ====== Config/parameters handling functions ====== static int buspirate_parseextparms(const PROGRAMMER *pgm, const LISTID extparms) { - int rv = 0; - char reset[10]; - char *preset = reset; /* for strtok() */ - unsigned int spifreq; - unsigned int rawfreq; - unsigned int cpufreq; - int serial_recv_timeout; - bool help = false; - - for (LNODEID ln = lfirst(extparms); ln; ln = lnext(ln)) { - const char *extended_param = ldata(ln); - - if (str_eq(extended_param, "ascii")) { - PDATA(pgm)->flag |= BP_FLAG_XPARM_FORCE_ASCII; - continue; - } - - if (str_eq(extended_param, "pullups")) { - PDATA(pgm)->flag |= BP_FLAG_PULLUPS; - continue; - } - - if (str_eq(extended_param, "hiz")) { - PDATA(pgm)->flag |= BP_FLAG_HIZ; - continue; - } - - if (sscanf(extended_param, "spifreq=%u", &spifreq) == 1) { - if (spifreq & (~0x07)) { - pmsg_error("spifreq must be between 0 and 7; see BusPirate manual for details\n"); - rv = -1; - break; - } - if (PDATA(pgm)->flag & BP_FLAG_XPARM_RAWFREQ) { - pmsg_error("set either spifreq or rawfreq\n"); - rv = -1; - break; - } - PDATA(pgm)->flag |= BP_FLAG_XPARM_SPIFREQ; - PDATA(pgm)->spifreq = spifreq; - continue; - } - - if (sscanf(extended_param, "rawfreq=%u", &rawfreq) == 1) { - if (rawfreq >= 4) { - pmsg_error("rawfreq must be between 0 and 3\n"); - rv = -1; - break; - } - if (PDATA(pgm)->flag & BP_FLAG_XPARM_SPIFREQ) { - pmsg_error("set either spifreq or rawfreq\n"); - rv = -1; - break; - } - PDATA(pgm)->flag |= BP_FLAG_XPARM_RAWFREQ; - PDATA(pgm)->spifreq = rawfreq; - continue; - } - - if (sscanf(extended_param, "cpufreq=%u", &cpufreq) == 1) { - /* lower limit comes from 'cpufreq > 4 * spifreq', spifreq in ascii mode is 30kHz. */ - if (cpufreq < 125 || cpufreq > 4000) { - pmsg_error("cpufreq must be between 125 and 4000 kHz; see BusPirate manual for details\n"); - rv = -1; - break; - } - PDATA(pgm)->cpufreq = cpufreq; - PDATA(pgm)->flag |= BP_FLAG_XPARM_CPUFREQ; - continue; - } - - if (sscanf(extended_param, "reset=%9s", reset) == 1) { - char *resetpin; - while ((resetpin = strtok(preset, ","))) { - preset = NULL; /* for subsequent strtok() calls */ - if (str_caseeq(resetpin, "cs")) - PDATA(pgm)->reset |= BP_RESET_CS; - else if (str_caseeq(resetpin, "aux") || str_caseeq(reset, "aux1")) - PDATA(pgm)->reset |= BP_RESET_AUX; - else if (str_caseeq(resetpin, "aux2")) - PDATA(pgm)->reset |= BP_RESET_AUX2; - else { - pmsg_error("-x reset= value must be either CS, AUX or AUX2\n"); - rv = -1; - break; - } - } - PDATA(pgm)->flag |= BP_FLAG_XPARM_RESET; - continue; - } - - if (str_eq(extended_param, "nopagedwrite")) { - PDATA(pgm)->flag |= BP_FLAG_NOPAGEDWRITE; - continue; - } - - if (str_eq(extended_param, "nopagedread")) { - PDATA(pgm)->flag |= BP_FLAG_NOPAGEDREAD; - continue; - } - - if (sscanf(extended_param, "serial_recv_timeout=%d", &serial_recv_timeout) == 1) { - if (serial_recv_timeout < 1) { - pmsg_error("serial_recv_timeout must be greater 0\n"); - rv = -1; - break; - } - PDATA(pgm)->serial_recv_timeout = serial_recv_timeout; - continue; - } - - if (str_eq(extended_param, "help")) { - help = true; - rv = LIBAVRDUDE_EXIT; - } - - if (!help) { - pmsg_error("invalid extended parameter -x %s\n", extended_param); - rv = -1; - } - msg_error("%s -c %s extended options:\n", progname, pgmid); - msg_error(" -x reset=[cs|aux|aux2] Override default reset pin\n"); - msg_error(" -x spifreq=<0..7> Set binary SPI mode speed\n"); - msg_error(" -x rawfreq=<0..3> Set \"raw-wire\" SPI mode speed\n"); - msg_error(" -x ascii Use ASCII protocol between BP and Avrdude\n"); - msg_error(" -x nopagedwrite Disable page write functionality\n"); - msg_error(" -x nopagedread Disable page read functionality\n"); - msg_error(" -x cpufreq=<125..4000> Set the AUX pin to output a frequency to kHz\n"); - msg_error(" -x serial_recv_timeout= Set serial receive timeout to ms\n"); - msg_error(" -x pullups Enable internal pull-ups\n"); - msg_error(" -x hiz SPI HiZ mode (open collector)\n"); - msg_error(" -x help Show this help menu and exit\n"); - return rv; - } - - return rv; + int rv = 0; + char reset[10]; + char *preset = reset; // For strtok() + unsigned int spifreq; + unsigned int rawfreq; + unsigned int cpufreq; + int serial_recv_timeout; + bool help = false; + + for(LNODEID ln = lfirst(extparms); ln; ln = lnext(ln)) { + const char *extended_param = ldata(ln); + + if(str_eq(extended_param, "ascii")) { + my.flag |= BP_FLAG_XPARM_FORCE_ASCII; + continue; + } + + if(str_eq(extended_param, "pullups")) { + my.flag |= BP_FLAG_PULLUPS; + continue; + } + + if(str_eq(extended_param, "hiz")) { + my.flag |= BP_FLAG_HIZ; + continue; + } + + if(sscanf(extended_param, "spifreq=%u", &spifreq) == 1) { + if(spifreq & (~0x07)) { + pmsg_error("spifreq must be between 0 and 7; see BusPirate manual for details\n"); + rv = -1; + break; + } + if(my.flag & BP_FLAG_XPARM_RAWFREQ) { + pmsg_error("set either spifreq or rawfreq\n"); + rv = -1; + break; + } + my.flag |= BP_FLAG_XPARM_SPIFREQ; + my.spifreq = spifreq; + continue; + } + + if(sscanf(extended_param, "rawfreq=%u", &rawfreq) == 1) { + if(rawfreq >= 4) { + pmsg_error("rawfreq must be between 0 and 3\n"); + rv = -1; + break; + } + if(my.flag & BP_FLAG_XPARM_SPIFREQ) { + pmsg_error("set either spifreq or rawfreq\n"); + rv = -1; + break; + } + my.flag |= BP_FLAG_XPARM_RAWFREQ; + my.spifreq = rawfreq; + continue; + } + + if(sscanf(extended_param, "cpufreq=%u", &cpufreq) == 1) { + // Lower limit comes from cpufreq > 4*spifreq, spifreq in ASCII mode is 30kHz + if(cpufreq < 125 || cpufreq > 4000) { + pmsg_error("cpufreq must be between 125 and 4000 kHz; see BusPirate manual for details\n"); + rv = -1; + break; + } + my.cpufreq = cpufreq; + my.flag |= BP_FLAG_XPARM_CPUFREQ; + continue; + } + + if(sscanf(extended_param, "reset=%9s", reset) == 1) { + char *resetpin; + + while((resetpin = strtok(preset, ","))) { + preset = NULL; // For subsequent strtok() calls + if(str_caseeq(resetpin, "cs")) + my.reset |= BP_RESET_CS; + else if(str_caseeq(resetpin, "aux") || str_caseeq(reset, "aux1")) + my.reset |= BP_RESET_AUX; + else if(str_caseeq(resetpin, "aux2")) + my.reset |= BP_RESET_AUX2; + else { + pmsg_error("-x reset= value must be either CS, AUX or AUX2\n"); + rv = -1; + break; + } + } + my.flag |= BP_FLAG_XPARM_RESET; + continue; + } + + if(str_eq(extended_param, "nopagedwrite")) { + my.flag |= BP_FLAG_NOPAGEDWRITE; + continue; + } + + if(str_eq(extended_param, "nopagedread")) { + my.flag |= BP_FLAG_NOPAGEDREAD; + continue; + } + + if(sscanf(extended_param, "serial_recv_timeout=%d", &serial_recv_timeout) == 1) { + if(serial_recv_timeout < 1) { + pmsg_error("serial_recv_timeout must be greater 0\n"); + rv = -1; + break; + } + my.serial_recv_timeout = serial_recv_timeout; + continue; + } + + if(str_eq(extended_param, "help")) { + help = true; + rv = LIBAVRDUDE_EXIT; + } + + if(!help) { + pmsg_error("invalid extended parameter -x %s\n", extended_param); + rv = -1; + } + msg_error("%s -c %s extended options:\n", progname, pgmid); + msg_error(" -x reset=[cs|aux|aux2] Override default reset pin\n"); + msg_error(" -x spifreq=<0..7> Set binary SPI mode speed\n"); + msg_error(" -x rawfreq=<0..3> Set \"raw-wire\" SPI mode speed\n"); + msg_error(" -x ascii Use ASCII protocol between BP and Avrdude\n"); + msg_error(" -x nopagedwrite Disable page write functionality\n"); + msg_error(" -x nopagedread Disable page read functionality\n"); + msg_error(" -x cpufreq=<125..4000> Set the AUX pin to output a frequency to kHz\n"); + msg_error(" -x serial_recv_timeout= Set serial receive timeout to ms\n"); + msg_error(" -x pullups Enable internal pull-ups\n"); + msg_error(" -x hiz SPI HiZ mode (open collector)\n"); + msg_error(" -x help Show this help menu and exit\n"); + return rv; + } + + return rv; } static int buspirate_verifyconfig(const PROGRAMMER *pgm) { - /* Default reset pin is CS */ - if (PDATA(pgm)->reset == 0x00) - PDATA(pgm)->reset |= BP_RESET_CS; - - if ((PDATA(pgm)->reset != BP_RESET_CS) && buspirate_uses_ascii(pgm)) { - pmsg_error("RESET pin other than CS is not supported in ASCII mode\n"); - return -1; - } - - if ( ((PDATA(pgm)->flag & BP_FLAG_XPARM_SPIFREQ) || (PDATA(pgm)->flag & BP_FLAG_XPARM_RAWFREQ)) - && buspirate_uses_ascii(pgm)) { - pmsg_error("SPI speed selection is not supported in ASCII mode\n"); - return -1; - } - - return 0; + // Default reset pin is CS + if(my.reset == 0x00) + my.reset |= BP_RESET_CS; + + if((my.reset != BP_RESET_CS) && buspirate_uses_ascii(pgm)) { + pmsg_error("RESET pin other than CS is not supported in ASCII mode\n"); + return -1; + } + + if(((my.flag & BP_FLAG_XPARM_SPIFREQ) || (my.flag & BP_FLAG_XPARM_RAWFREQ)) + && buspirate_uses_ascii(pgm)) { + pmsg_error("SPI speed selection is not supported in ASCII mode\n"); + return -1; + } + + return 0; } -/* ====== Programmer methods ======= */ +// ====== Programmer methods ======= static int buspirate_open(PROGRAMMER *pgm, const char *port) { - union pinfo pinfo; - /* BusPirate runs at 115200 by default */ - if(pgm->baudrate == 0) - pgm->baudrate = 115200; - - pinfo.serialinfo.baud = pgm->baudrate; - pinfo.serialinfo.cflags = SERIAL_8N1; - pgm->port = port; - if (serial_open(port, pinfo, &pgm->fd)==-1) { - return -1; - } - - /* drain any extraneous input */ - serial_drain(&pgm->fd, 0); - - return 0; + union pinfo pinfo; + + // BusPirate runs at 115200 by default + if(pgm->baudrate == 0) + pgm->baudrate = 115200; + + pinfo.serialinfo.baud = pgm->baudrate; + pinfo.serialinfo.cflags = SERIAL_8N1; + pgm->port = port; + if(serial_open(port, pinfo, &pgm->fd) == -1) { + return -1; + } + + // Drain any extraneous input + serial_drain(&pgm->fd, 0); + + return 0; } -static void buspirate_close(PROGRAMMER *pgm) -{ - serial_close(&pgm->fd); - pgm->fd.ifd = -1; +static void buspirate_close(PROGRAMMER *pgm) { + serial_close(&pgm->fd); + pgm->fd.ifd = -1; } static void buspirate_reset_from_binmode(const PROGRAMMER *pgm) { - unsigned char buf[10]; - - buf[0] = 0x00; /* BinMode: revert to raw bitbang mode */ - buspirate_send_bin(pgm, buf, 1); - buspirate_recv_bin(pgm, buf, 5); - - if (PDATA(pgm)->flag & BP_FLAG_XPARM_CPUFREQ) { - /* disable pwm */ - if (buspirate_expect_bin_byte(pgm, 0x13, 0x01) != 1) { - pmsg_error("did not get a response to stop PWM command\n"); - } - } - /* 0b0100wxyz - Configure peripherals w=power, x=pull-ups, y=AUX, z=CS - * we want everything off -- 0b01000000 = 0x40 */ - if (buspirate_expect_bin_byte(pgm, 0x40, 0x00) == 1) { - pmsg_error("did not get a response to power off command\n"); - } - - buf[0] = 0x0F; /* BinMode: reset */ - buspirate_send_bin(pgm, buf, 1); - - /* read back all output */ - memset(buf, '\0', sizeof(buf)); - for (;;) { - int rc; - rc = buspirate_recv_bin(pgm, buf, sizeof(buf) - 1); - - if (buspirate_is_prompt((const char*)buf)) { - PDATA(pgm)->flag &= ~BP_FLAG_IN_BINMODE; - break; - } - if (rc == EOF) - break; - memset(buf, '\0', sizeof(buf)); - } - - if (PDATA(pgm)->flag & BP_FLAG_IN_BINMODE) { - pmsg_error("reset failed; you may need to powercycle it\n"); - return; - } - - msg_notice2("BusPirate is back in text mode\n"); + unsigned char buf[10]; + + buf[0] = 0x00; // BinMode: revert to raw bitbang mode + buspirate_send_bin(pgm, buf, 1); + buspirate_recv_bin(pgm, buf, 5); + + if(my.flag & BP_FLAG_XPARM_CPUFREQ) { + // Disable PWM + if(buspirate_expect_bin_byte(pgm, 0x13, 0x01) != 1) { + pmsg_error("did not get a response to stop PWM command\n"); + } + } + /* 0b0100wxyz - Configure peripherals w=power, x=pull-ups, y=AUX, z=CS + * we want everything off -- 0b01000000 = 0x40 */ + if(buspirate_expect_bin_byte(pgm, 0x40, 0x00) == 1) { + pmsg_error("did not get a response to power off command\n"); + } + + buf[0] = 0x0F; // BinMode: reset + buspirate_send_bin(pgm, buf, 1); + + // Read back all output + memset(buf, '\0', sizeof(buf)); + for(;;) { + int rc; + + rc = buspirate_recv_bin(pgm, buf, sizeof(buf) - 1); + + if(buspirate_is_prompt((const char *) buf)) { + my.flag &= ~BP_FLAG_IN_BINMODE; + break; + } + if(rc == EOF) + break; + memset(buf, '\0', sizeof(buf)); + } + + if(my.flag & BP_FLAG_IN_BINMODE) { + pmsg_error("reset failed; you may need to powercycle it\n"); + return; + } + + msg_notice2("BusPirate is back in text mode\n"); } -static int buspirate_start_mode_bin(PROGRAMMER *pgm) -{ - struct submode { - const char *name; /* Name of mode for user messages */ - char enter; /* Command to enter from base binary mode */ - const char *entered_format; /* Response, for "scanf" */ - char config; /* Command to setup submode parameters */ - } submode; - - if (PDATA(pgm)->flag & BP_FLAG_XPARM_RAWFREQ) { - submode.name = "Raw-wire"; - submode.enter = 0x05; - submode.entered_format = "RAW%1d"; - submode.config = 0x8C; - PDATA(pgm)->flag |= BP_FLAG_NOPAGEDWRITE; - PDATA(pgm)->flag |= BP_FLAG_NOPAGEDREAD; - } else { - submode.name = "SPI"; - submode.enter = 0x01; - submode.entered_format = "SPI%1d"; - - /* 1000wxyz - SPI config, w=HiZ(0)/3.3v(1), x=CLK idle, y=CLK edge, z=SMP sample - * we want: 3.3V(1), idle low(0), data change on - * trailing edge (1), sample in the middle - * of the pulse (0) - * => 0b10001010 = 0x8a */ - submode.config = 0x8A; - if (buspirate_uses_hiz(pgm)) { - submode.config &= ~(1<<3); - pmsg_info("spi hi-z mode (open-collector)\n"); - } - } - - unsigned char buf[20] = { '\0' }; - - /* == Switch to binmode - send 20x '\0' == */ - buspirate_send_bin(pgm, buf, sizeof(buf)); - - /* Expecting 'BBIOx' reply */ - memset(buf, 0, sizeof(buf)); - buspirate_recv_bin(pgm, buf, 5); - if (sscanf((const char*)buf, "BBIO%1d", &PDATA(pgm)->binmode_version) != 1) { - pmsg_error("binary mode not confirmed: %s\n", buf); - buspirate_reset_from_binmode(pgm); - return -1; - } - msg_notice2("BusPirate binmode version: %d\n", - PDATA(pgm)->binmode_version); - - PDATA(pgm)->flag |= BP_FLAG_IN_BINMODE; - - if (PDATA(pgm)->flag & BP_FLAG_XPARM_CPUFREQ) { - unsigned short pwm_duty; - unsigned short pwm_period; - - pwm_period = 16000/(PDATA(pgm)->cpufreq) - 1; // oscillator runs at 32MHz, we don't use a prescaler - pwm_duty = pwm_period/2; // 50% duty cycle - - msg_notice2("setting up PWM for cpufreq\n"); - msg_debug("PWM settings: Prescaler=1, Duty Cycle=%hd, Period=%hd\n", pwm_duty, pwm_period); - - buf[0] = 0x12; // pwm setup - buf[1] = 0; // prescaler 1 - buf[2] = (char) ((pwm_duty >> 8) & 0xff); // duty cycle register, high byte - buf[3] = (char) pwm_duty & 0xff; // duty cycle register, low byte - buf[4] = (char) ((pwm_period >> 8) & 0xff); // period register, high byte - buf[5] = (char) pwm_period & 0xff; // period register, low byte - buspirate_send_bin(pgm, buf, 6); - - buspirate_recv_bin(pgm, buf, 1); - if (buf[0] != 0x01) - pmsg_error("cpufreq (PWM) setup failed\n"); - } - - /* == Set protocol sub-mode of binary mode == */ - buf[0] = submode.enter; - buspirate_send_bin(pgm, buf, 1); - memset(buf, 0, sizeof(buf)); - buspirate_recv_bin(pgm, buf, 4); - if (sscanf((const char*)buf, submode.entered_format, &PDATA(pgm)->submode_version) != 1) { - pmsg_error("%s mode not confirmed: %s\n", submode.name, buf); - buspirate_reset_from_binmode(pgm); - return -1; - } - msg_notice2("BusPirate %s version: %d\n", - submode.name, PDATA(pgm)->submode_version); - if (PDATA(pgm)->flag & BP_FLAG_NOPAGEDWRITE) { - pmsg_notice2("paged flash write disabled\n"); - pgm->paged_write = NULL; - } else { - /* Check for write-then-read without !CS/CS and disable paged_write if absent: */ - const unsigned char buf2[] = {5, 0, 0, 0, 0}; - buspirate_send_bin(pgm, buf2, sizeof(buf2)); - buspirate_recv_bin(pgm, buf, 1); - if (buf[0] != 0x01) { - /* Disable paged write: */ - PDATA(pgm)->flag |= BP_FLAG_NOPAGEDWRITE; - pgm->paged_write = NULL; - - /* Return to SPI mode (0x00s have landed us back in binary bitbang mode): */ - buf[0] = 0x1; - buspirate_send_bin(pgm, buf, 1); - - pmsg_notice2("disabling paged flash write (need BusPirate firmware >= v5.10)\n"); - - /* Flush serial buffer: */ - serial_drain(&pgm->fd, 0); - } else { - pmsg_info("paged flash write enabled\n"); - } - } - - /* 0b0100wxyz - Configure peripherals w=power, x=pull-ups/aux2, y=AUX, z=CS - * we want power (0x48) and all reset pins high. */ - PDATA(pgm)->current_peripherals_config = 0x48 | PDATA(pgm)->reset; - if (buspirate_uses_pullups(pgm)) { - PDATA(pgm)->current_peripherals_config |= 1<<2; - submode.config &= ~(1<<3); - pmsg_info("enabling pull-ups (open-collector)\n"); +static int buspirate_start_mode_bin(PROGRAMMER *pgm) { + struct submode { + const char *name; // Name of mode for user messages + char enter; // Command to enter from base binary mode + const char *entered_format; // Response, for scanf + char config; // Command to setup submode parameters + } submode; + + if(my.flag & BP_FLAG_XPARM_RAWFREQ) { + submode.name = "Raw-wire"; + submode.enter = 0x05; + submode.entered_format = "RAW%1d"; + submode.config = 0x8C; + my.flag |= BP_FLAG_NOPAGEDWRITE; + my.flag |= BP_FLAG_NOPAGEDREAD; + } else { + submode.name = "SPI"; + submode.enter = 0x01; + submode.entered_format = "SPI%1d"; + + /* 1000wxyz - SPI config, w=HiZ(0)/3.3v(1), x=CLK idle, y=CLK edge, z=SMP sample + * we want: 3.3V(1), idle low(0), data change on + * trailing edge (1), sample in the middle + * of the pulse (0) + * => 0b10001010 = 0x8a */ + submode.config = 0x8A; + if(buspirate_uses_hiz(pgm)) { + submode.config &= ~(1 << 3); + pmsg_info("spi hi-z mode (open-collector)\n"); + } + } + + unsigned char buf[20] = { '\0' }; + + // == Switch to binmode - send 20x '\0' == + buspirate_send_bin(pgm, buf, sizeof(buf)); + + // Expecting 'BBIOx' reply + memset(buf, 0, sizeof(buf)); + buspirate_recv_bin(pgm, buf, 5); + if(sscanf((const char *) buf, "BBIO%1d", &my.binmode_version) != 1) { + pmsg_error("binary mode not confirmed: %s\n", buf); + buspirate_reset_from_binmode(pgm); + return -1; + } + msg_notice2("BusPirate binmode version: %d\n", my.binmode_version); + + my.flag |= BP_FLAG_IN_BINMODE; + + if(my.flag & BP_FLAG_XPARM_CPUFREQ) { + unsigned short pwm_duty; + unsigned short pwm_period; + + pwm_period = 16000/(my.cpufreq) - 1; // Oscillator runs at 32MHz, we don't use a prescaler + pwm_duty = pwm_period/2; // 50% duty cycle + + msg_notice2("setting up PWM for cpufreq\n"); + msg_debug("PWM settings: Prescaler=1, Duty Cycle=%hd, Period=%hd\n", pwm_duty, pwm_period); + + buf[0] = 0x12; // PWM setup + buf[1] = 0; // Prescaler 1 + buf[2] = (char) ((pwm_duty >> 8) & 0xff); // Duty cycle register, high byte + buf[3] = (char) pwm_duty & 0xff; // Duty cycle register, low byte + buf[4] = (char) ((pwm_period >> 8) & 0xff); // Period register, high byte + buf[5] = (char) pwm_period & 0xff; // Period register, low byte + buspirate_send_bin(pgm, buf, 6); + + buspirate_recv_bin(pgm, buf, 1); + if(buf[0] != 0x01) + pmsg_error("cpufreq (PWM) setup failed\n"); + } + + // == Set protocol sub-mode of binary mode == + buf[0] = submode.enter; + buspirate_send_bin(pgm, buf, 1); + memset(buf, 0, sizeof(buf)); + buspirate_recv_bin(pgm, buf, 4); + if(sscanf((const char *) buf, submode.entered_format, &my.submode_version) != 1) { + pmsg_error("%s mode not confirmed: %s\n", submode.name, buf); + buspirate_reset_from_binmode(pgm); + return -1; + } + msg_notice2("BusPirate %s version: %d\n", submode.name, my.submode_version); + if(my.flag & BP_FLAG_NOPAGEDWRITE) { + pmsg_notice2("paged flash write disabled\n"); + pgm->paged_write = NULL; + } else { + // Check for write-then-read without !CS/CS and disable paged_write if absent + const unsigned char buf2[] = { 5, 0, 0, 0, 0 }; + buspirate_send_bin(pgm, buf2, sizeof(buf2)); + buspirate_recv_bin(pgm, buf, 1); + if(buf[0] != 0x01) { + // Disable paged write + my.flag |= BP_FLAG_NOPAGEDWRITE; + pgm->paged_write = NULL; + + // Return to SPI mode (0x00s have landed us back in binary bitbang mode) + buf[0] = 0x1; + buspirate_send_bin(pgm, buf, 1); + + pmsg_notice2("disabling paged flash write (need BusPirate firmware >= v5.10)\n"); + + // Flush serial buffer + serial_drain(&pgm->fd, 0); + } else { + pmsg_info("paged flash write enabled\n"); + } + } + + /* + * 0b0100wxyz - Configure peripherals w=power, x=pull-ups/aux2, y=AUX, z=CS + * we want power (0x48) and all reset pins high + */ + my.current_peripherals_config = 0x48 | my.reset; + if(buspirate_uses_pullups(pgm)) { + my.current_peripherals_config |= 1 << 2; + submode.config &= ~(1 << 3); + pmsg_info("enabling pull-ups (open-collector)\n"); + } + if(buspirate_expect_bin_byte(pgm, my.current_peripherals_config, 0x01) < 0) + return -1; + usleep(50000); // Sleep for 50 ms after power up + + // 01100xxx - Set speed + if(buspirate_expect_bin_byte(pgm, 0x60 | my.spifreq, 0x01) < 0) + return -1; + + // Submode config + if(buspirate_expect_bin_byte(pgm, submode.config, 0x01) < 0) + return -1; + + // AVR Extended Commands - test for existence + if(my.flag & BP_FLAG_NOPAGEDREAD) { + pmsg_notice2("paged flash read disabled\n"); + pgm->paged_load = NULL; + } else { + int rv = buspirate_expect_bin_byte(pgm, 0x06, 0x01); + + if(rv < 0) + return -1; + if(rv) { + unsigned int ver = 0; + const unsigned char buf2[] = { 1 }; + buspirate_send_bin(pgm, buf2, sizeof(buf2)); + buspirate_recv_bin(pgm, buf, 3); + ver = buf[1] << 8 | buf[2]; + msg_notice2("AVR Extended Commands version %d\n", ver); + } else { + msg_notice2("AVR Extended Commands not found\n"); + my.flag |= BP_FLAG_NOPAGEDREAD; + pgm->paged_load = NULL; } - if (buspirate_expect_bin_byte(pgm, PDATA(pgm)->current_peripherals_config, 0x01) < 0) - return -1; - usleep(50000); // sleep for 50ms after power up - - /* 01100xxx - Set speed */ - if (buspirate_expect_bin_byte(pgm, 0x60 | PDATA(pgm)->spifreq, 0x01) < 0) - return -1; - - /* Submode config */ - if (buspirate_expect_bin_byte(pgm, submode.config, 0x01) < 0) - return -1; - - /* AVR Extended Commands - test for existence */ - if (PDATA(pgm)->flag & BP_FLAG_NOPAGEDREAD) { - pmsg_notice2("paged flash read disabled\n"); - pgm->paged_load = NULL; - } else { - int rv = buspirate_expect_bin_byte(pgm, 0x06, 0x01); - if (rv < 0) - return -1; - if (rv) { - unsigned int ver = 0; - const unsigned char buf2[] = {1}; - buspirate_send_bin(pgm, buf2, sizeof(buf2)); - buspirate_recv_bin(pgm, buf, 3); - ver = buf[1] << 8 | buf[2]; - msg_notice2("AVR Extended Commands version %d\n", ver); - } else { - msg_notice2("AVR Extended Commands not found\n"); - PDATA(pgm)->flag |= BP_FLAG_NOPAGEDREAD; - pgm->paged_load = NULL; - } - } - - return 0; + } + + return 0; } static int buspirate_start_spi_mode_ascii(const PROGRAMMER *pgm) { - int spi_cmd = -1; - int cmd; - char *rcvd; - char buf[5]; - char mode[11]; - - buspirate_send(pgm, "m\n"); - while(1) { - rcvd = buspirate_readline(pgm, NULL, 0); - if (rcvd == NULL) { - return -1; - } - if (spi_cmd == -1 && sscanf(rcvd, "%2d. %10s", &cmd, mode)) { - if (str_eq(mode, "SPI")) - spi_cmd = cmd; - } - if (buspirate_is_prompt(rcvd)) - break; - } - if (spi_cmd == -1) { - pmsg_error("SPI mode number not found; does your BusPirate support SPI?\n"); - pmsg_error("try powercycling your BusPirate and try again\n"); - return -1; - } - snprintf(buf, sizeof(buf), "%d\n", spi_cmd); - buspirate_send(pgm, buf); - buf[0] = '\0'; - while (1) { - rcvd = buspirate_readline(pgm, NULL, 0); - if (rcvd == NULL) { - return -1; - } - if (str_contains(rcvd, "Normal (H=3.3V, L=GND)")) { - /* BP firmware 2.1 defaults to Open-drain output. - * That doesn't work on my board, even with pull-up - * resistors. Select 3.3V output mode instead. */ - sscanf(rcvd, " %2d.", &cmd); - snprintf(buf, sizeof(buf), "%d\n", cmd); - } - if (buspirate_is_prompt(rcvd)) { - if (str_starts(rcvd, "SPI>")) { - msg_info("BusPirate is now configured for SPI\n"); - break; - } - /* Not yet 'SPI>' prompt */ - if (buf[0]) { - buspirate_send(pgm, buf); - buf[0] = '\0'; - } else - buspirate_send(pgm, "\n"); - } - } - return 0; + int spi_cmd = -1; + int cmd; + char *rcvd; + char buf[5]; + char mode[11]; + + buspirate_send(pgm, "m\n"); + while(1) { + rcvd = buspirate_readline(pgm, NULL, 0); + if(rcvd == NULL) { + return -1; + } + if(spi_cmd == -1 && sscanf(rcvd, "%2d. %10s", &cmd, mode)) { + if(str_eq(mode, "SPI")) + spi_cmd = cmd; + } + if(buspirate_is_prompt(rcvd)) + break; + } + if(spi_cmd == -1) { + pmsg_error("SPI mode number not found; does your BusPirate support SPI?\n"); + pmsg_error("try powercycling your BusPirate and try again\n"); + return -1; + } + snprintf(buf, sizeof(buf), "%d\n", spi_cmd); + buspirate_send(pgm, buf); + buf[0] = '\0'; + while(1) { + rcvd = buspirate_readline(pgm, NULL, 0); + if(rcvd == NULL) { + return -1; + } + if(str_contains(rcvd, "Normal (H=3.3V, L=GND)")) { + /* + * BP firmware 2.1 defaults to Open-drain output. That doesn't work on my + * board, even with pull-up resistors. Select 3.3V output mode instead. + */ + sscanf(rcvd, " %2d.", &cmd); + snprintf(buf, sizeof(buf), "%d\n", cmd); + } + if(buspirate_is_prompt(rcvd)) { + if(str_starts(rcvd, "SPI>")) { + msg_info("BusPirate is now configured for SPI\n"); + break; + } + // Not yet 'SPI>' prompt + if(buf[0]) { + buspirate_send(pgm, buf); + buf[0] = '\0'; + } else + buspirate_send(pgm, "\n"); + } + } + return 0; } static void buspirate_enable(PROGRAMMER *pgm, const AVRPART *p) { - const char * const reset_str = "#\n"; - const char * const accept_str = "y\n"; - char *rcvd; - int rc, print_banner = 0; - - /* Ensure configuration is self-consistant: */ - if (buspirate_verifyconfig(pgm)<0) - return; /* XXX should handle error */ - - /* Attempt to start binary SPI mode unless explicitly told otherwise: */ - if (!buspirate_uses_ascii(pgm)) { - msg_info("attempting to initiate BusPirate binary mode ...\n"); - - /* Send two CRs to ensure we're not in a sub-menu of the UI if we're in ASCII mode: */ - buspirate_send_bin(pgm, (const unsigned char*)"\n\n", 2); - - /* Clear input buffer: */ - serial_drain(&pgm->fd, 0); - - /* Attempt to enter binary mode: */ - if (buspirate_start_mode_bin(pgm) >= 0) - return; - else - pmsg_info("unable to start binary mode, falling back to ASCII ...\n"); - } - - msg_info("attempting to initiate BusPirate ASCII mode ...\n"); - - /* Call buspirate_send_bin() instead of buspirate_send() - * because we don't know if BP is in text or bin mode */ - rc = buspirate_send_bin(pgm, (const unsigned char*)reset_str, strlen(reset_str)); - if (rc) { - pmsg_error("BusPirate is not responding; serial port error code %d\n", rc); - return; - } - - while(1) { - rcvd = buspirate_readline_noexit(pgm, NULL, 0); - if (! rcvd) { - pmsg_error("programmer is not responding\n"); - return; - } - if (str_starts(rcvd, "Are you sure?")) { - buspirate_send_bin(pgm, (const unsigned char*)accept_str, strlen(accept_str)); - } - if (str_starts(rcvd, "RESET")) { - print_banner = 1; - continue; - } - if (buspirate_is_prompt(rcvd)) { - msg_debug("**\n"); - break; - } - if (print_banner) - msg_debug("** %s", rcvd); - } - - if (!(PDATA(pgm)->flag & BP_FLAG_IN_BINMODE)) { - msg_info("using ASCII mode\n"); - if (buspirate_start_spi_mode_ascii(pgm) < 0) { - pmsg_error("unable to start ascii SPI mode\n"); - return; - } - } + const char *const reset_str = "#\n"; + const char *const accept_str = "y\n"; + char *rcvd; + int rc, print_banner = 0; + + // Ensure configuration is self-consistent + if(buspirate_verifyconfig(pgm) < 0) + return; // XXX should handle error + + // Attempt to start binary SPI mode unless explicitly told otherwise + if(!buspirate_uses_ascii(pgm)) { + msg_info("attempting to initiate BusPirate binary mode ...\n"); + + // Send two CRs to ensure we're not in a sub-menu of the UI if we're in ASCII mode + buspirate_send_bin(pgm, (const unsigned char *) "\n\n", 2); + + // Clear input buffer + serial_drain(&pgm->fd, 0); + + // Attempt to enter binary mode + if(buspirate_start_mode_bin(pgm) >= 0) + return; + else + pmsg_info("unable to start binary mode, falling back to ASCII ...\n"); + } + + msg_info("attempting to initiate BusPirate ASCII mode ...\n"); + + /* Call buspirate_send_bin() instead of buspirate_send() + * because we don't know if BP is in text or bin mode */ + rc = buspirate_send_bin(pgm, (const unsigned char *) reset_str, strlen(reset_str)); + if(rc) { + pmsg_error("BusPirate is not responding; serial port error code %d\n", rc); + return; + } + + while(1) { + rcvd = buspirate_readline_noexit(pgm, NULL, 0); + if(!rcvd) { + pmsg_error("programmer is not responding\n"); + return; + } + if(str_starts(rcvd, "Are you sure?")) { + buspirate_send_bin(pgm, (const unsigned char *) accept_str, strlen(accept_str)); + } + if(str_starts(rcvd, "RESET")) { + print_banner = 1; + continue; + } + if(buspirate_is_prompt(rcvd)) { + msg_debug("**\n"); + break; + } + if(print_banner) + msg_debug("** %s", rcvd); + } + + if(!(my.flag & BP_FLAG_IN_BINMODE)) { + msg_info("using ASCII mode\n"); + if(buspirate_start_spi_mode_ascii(pgm) < 0) { + pmsg_error("unable to start ascii SPI mode\n"); + return; + } + } } static void buspirate_disable(const PROGRAMMER *pgm) { - if (PDATA(pgm)->flag & BP_FLAG_IN_BINMODE) { - serial_recv_timeout = 100; - buspirate_reset_from_binmode(pgm); - } else { - buspirate_expect(pgm, "#\n", "RESET", 1); - } + if(my.flag & BP_FLAG_IN_BINMODE) { + serial_recv_timeout = 100; + buspirate_reset_from_binmode(pgm); + } else { + buspirate_expect(pgm, "#\n", "RESET", 1); + } } static int buspirate_initialize(const PROGRAMMER *pgm, const AVRPART *p) { - pgm->powerup(pgm); + pgm->powerup(pgm); - return pgm->program_enable(pgm, p); + return pgm->program_enable(pgm, p); } static void buspirate_powerup(const PROGRAMMER *pgm) { - if (PDATA(pgm)->flag & BP_FLAG_IN_BINMODE) { - /* Powerup in BinMode is handled in binary mode init */ - return; - } else { - if (buspirate_expect(pgm, "W\n", "POWER SUPPLIES ON", 1)) { - if (PDATA(pgm)->flag & BP_FLAG_XPARM_CPUFREQ) { - char buf[25]; - int ok = 0; - snprintf(buf, sizeof(buf), "%d\n", PDATA(pgm)->cpufreq); - if (buspirate_expect(pgm, "g\n", "Frequency in kHz", 1)) { - if (buspirate_expect(pgm, buf, "Duty cycle in %", 1)) { - if (buspirate_expect(pgm, "50\n", "PWM active", 1)) { - ok = 1; - } - } - } - if(!ok) { - pmsg_error("did not get a response to start PWM command\n"); - } - } - return; - } - } - - pmsg_warning("did not get a response to PowerUp command; trying to continue anyway ...\n"); + if(my.flag & BP_FLAG_IN_BINMODE) { + // Powerup in BinMode is handled in binary mode init + return; + } else { + if(buspirate_expect(pgm, "W\n", "POWER SUPPLIES ON", 1)) { + if(my.flag & BP_FLAG_XPARM_CPUFREQ) { + char buf[25]; + int ok = 0; + + snprintf(buf, sizeof(buf), "%d\n", my.cpufreq); + if(buspirate_expect(pgm, "g\n", "Frequency in kHz", 1)) { + if(buspirate_expect(pgm, buf, "Duty cycle in %", 1)) { + if(buspirate_expect(pgm, "50\n", "PWM active", 1)) { + ok = 1; + } + } + } + if(!ok) { + pmsg_error("did not get a response to start PWM command\n"); + } + } + return; + } + } + + pmsg_warning("did not get a response to PowerUp command; trying to continue anyway ...\n"); } static void buspirate_powerdown(const PROGRAMMER *pgm) { - if (PDATA(pgm)->flag & BP_FLAG_IN_BINMODE) { - /* Powerdown in BinMode is handled in binary mode init */ - return; - } else { - if (PDATA(pgm)->flag & BP_FLAG_XPARM_CPUFREQ) { - if (!buspirate_expect(pgm, "g\n", "PWM disabled", 1)) { - pmsg_error("did not get a response to stop PWM command\n"); - } - } - if (buspirate_expect(pgm, "w\n", "POWER SUPPLIES OFF", 1)) - return; - } - - pmsg_error("did not get a response to PowerDown command\n"); + if(my.flag & BP_FLAG_IN_BINMODE) { + // Powerdown in BinMode is handled in binary mode init + return; + } else { + if(my.flag & BP_FLAG_XPARM_CPUFREQ) { + if(!buspirate_expect(pgm, "g\n", "PWM disabled", 1)) { + pmsg_error("did not get a response to stop PWM command\n"); + } + } + if(buspirate_expect(pgm, "w\n", "POWER SUPPLIES OFF", 1)) + return; + } + + pmsg_error("did not get a response to PowerDown command\n"); } -static int buspirate_cmd_bin(const PROGRAMMER *pgm, - const unsigned char *cmd, - unsigned char *res) -{ - /* 0001xxxx - Bulk transfer, send/read 1-16 bytes (0=1byte!) - * we are sending 4 bytes -> 0x13 */ - int rv = buspirate_expect_bin_byte(pgm, 0x13, 0x01); - if (rv < 0) - return -1; - if (rv == 0) - return -1; - - buspirate_send_bin(pgm, cmd, 4); - buspirate_recv_bin(pgm, res, 4); - - return 0; +static int buspirate_cmd_bin(const PROGRAMMER *pgm, const unsigned char *cmd, unsigned char *res) { + /* 0001xxxx - Bulk transfer, send/read 1-16 bytes (0=1byte!) + * we are sending 4 bytes -> 0x13 */ + int rv = buspirate_expect_bin_byte(pgm, 0x13, 0x01); + + if(rv < 0) + return -1; + if(rv == 0) + return -1; + + buspirate_send_bin(pgm, cmd, 4); + buspirate_recv_bin(pgm, res, 4); + + return 0; } -static int buspirate_cmd_ascii(const PROGRAMMER *pgm, - const unsigned char *cmd, - unsigned char *res) -{ - char buf[25]; - char *rcvd; - int i = 0; - unsigned int spi_write, spi_read; - - snprintf(buf, sizeof(buf), "0x%02x 0x%02x 0x%02x 0x%02x\n", - cmd[0], cmd[1], cmd[2], cmd[3]); - buspirate_send(pgm, buf); - while (i < 4) { - rcvd = buspirate_readline(pgm, NULL, 0); - if (rcvd == NULL) { - return -1; - } - /* WRITE: 0xAC READ: 0x04 */ - if (sscanf(rcvd, "WRITE: 0x%2x READ: 0x%2x", &spi_write, &spi_read) == 2) { - res[i++] = spi_read; - } - if (buspirate_is_prompt(rcvd)) - break; - } - - if (i != 4) { - pmsg_error("SPI has not read 4 bytes back\n"); - return -1; - } - - /* wait for prompt */ - while (buspirate_getc(pgm) != '>') - /* do nothing */; - - return 0; +static int buspirate_cmd_ascii(const PROGRAMMER *pgm, const unsigned char *cmd, unsigned char *res) { + char buf[25]; + char *rcvd; + int i = 0; + unsigned int spi_write, spi_read; + + snprintf(buf, sizeof(buf), "0x%02x 0x%02x 0x%02x 0x%02x\n", cmd[0], cmd[1], cmd[2], cmd[3]); + buspirate_send(pgm, buf); + while(i < 4) { + rcvd = buspirate_readline(pgm, NULL, 0); + if(rcvd == NULL) { + return -1; + } + // WRITE: 0xAC READ: 0x04 + if(sscanf(rcvd, "WRITE: 0x%2x READ: 0x%2x", &spi_write, &spi_read) == 2) { + res[i++] = spi_read; + } + if(buspirate_is_prompt(rcvd)) + break; + } + + if(i != 4) { + pmsg_error("SPI has not read 4 bytes back\n"); + return -1; + } + + // Wait for prompt + while(buspirate_getc(pgm) != '>') + ; + + return 0; } -static int buspirate_cmd(const PROGRAMMER *pgm, - const unsigned char *cmd, - unsigned char *res) -{ - if (PDATA(pgm)->flag & BP_FLAG_IN_BINMODE) - return buspirate_cmd_bin(pgm, cmd, res); - else - return buspirate_cmd_ascii(pgm, cmd, res); +static int buspirate_cmd(const PROGRAMMER *pgm, const unsigned char *cmd, unsigned char *res) { + if(my.flag & BP_FLAG_IN_BINMODE) + return buspirate_cmd_bin(pgm, cmd, res); + else + return buspirate_cmd_ascii(pgm, cmd, res); } -/* Paged load function which utilizes the AVR Extended Commands set */ +// Paged load function which utilizes the AVR Extended Commands set static int buspirate_paged_load(const PROGRAMMER *pgm, const AVRPART *p, const AVRMEM *m, unsigned int page_size, unsigned int address, unsigned int n_bytes) { - unsigned char commandbuf[10]; - unsigned char buf[275]; - unsigned int addr = 0; - - msg_debug("buspirate_paged_load(..,%s,%d,%d,%d)\n",m->desc,m->page_size,address,n_bytes); - - // This should never happen, but still ... - if (PDATA(pgm)->flag & BP_FLAG_NOPAGEDREAD) { - pmsg_error("called while in nopagedread mode\n"); - return -1; - } - - // determine what type of memory to read, only flash is supported - if (!mem_is_flash(m)) { - return -1; - } - - // send command to read data - commandbuf[0] = 6; - commandbuf[1] = 2; - - // send start address (in WORDS, not bytes!) - commandbuf[2] = (address >> 1 >> 24) & 0xff; - commandbuf[3] = (address >> 1>> 16) & 0xff; - commandbuf[4] = (address >> 1 >> 8) & 0xff; - commandbuf[5] = (address >> 1) & 0xff; - - // send number of bytes to fetch (in BYTES) - commandbuf[6] = (n_bytes >> 24) & 0xff; - commandbuf[7] = (n_bytes >> 16) & 0xff; - commandbuf[8] = (n_bytes >> 8) & 0xff; - commandbuf[9] = (n_bytes) & 0xff; - - buspirate_send_bin(pgm, commandbuf, 10); - buspirate_recv_bin(pgm, buf, 1); - buspirate_recv_bin(pgm, buf, 1); - - if (buf[0] != 0x01) { - pmsg_error("paged read command returned zero\n"); - return -1; - } - - for (addr = 0; addr < n_bytes; addr++) { - buspirate_recv_bin(pgm, &m->buf[addr+address], 1); - } - - return n_bytes; + unsigned char commandbuf[10]; + unsigned char buf[275]; + unsigned int addr = 0; + + msg_debug("buspirate_paged_load(..,%s,%d,%d,%d)\n", m->desc, m->page_size, address, n_bytes); + + // This should never happen, but still ... + if(my.flag & BP_FLAG_NOPAGEDREAD) { + pmsg_error("called while in nopagedread mode\n"); + return -1; + } + // Determine what type of memory to read, only flash is supported + if(!mem_is_flash(m)) { + return -1; + } + // Send command to read data + commandbuf[0] = 6; + commandbuf[1] = 2; + + // Send start address (in WORDS, not bytes!) + commandbuf[2] = (address >> 1 >> 24) & 0xff; + commandbuf[3] = (address >> 1 >> 16) & 0xff; + commandbuf[4] = (address >> 1 >> 8) & 0xff; + commandbuf[5] = (address >> 1) & 0xff; + + // Send number of bytes to fetch (in BYTES) + commandbuf[6] = (n_bytes >> 24) & 0xff; + commandbuf[7] = (n_bytes >> 16) & 0xff; + commandbuf[8] = (n_bytes >> 8) & 0xff; + commandbuf[9] = (n_bytes) & 0xff; + + buspirate_send_bin(pgm, commandbuf, 10); + buspirate_recv_bin(pgm, buf, 1); + buspirate_recv_bin(pgm, buf, 1); + + if(buf[0] != 0x01) { + pmsg_error("paged read command returned zero\n"); + return -1; + } + + for(addr = 0; addr < n_bytes; addr++) { + buspirate_recv_bin(pgm, &m->buf[addr + address], 1); + } + + return n_bytes; } -/* Paged write function which utilizes the Bus Pirate's "Write then Read" binary SPI instruction */ +// Paged write function which utilizes the Bus Pirate's "Write then Read" binary SPI instruction static int buspirate_paged_write(const PROGRAMMER *pgm, const AVRPART *p, const AVRMEM *m, unsigned int page_size, unsigned int base_addr, unsigned int n_data_bytes) { - int page, i; - int addr = base_addr; - int n_page_writes; - int this_page_size; - unsigned char cmd_buf[4096] = {'\0'}; - unsigned char send_byte, recv_byte; - - if (!(PDATA(pgm)->flag & BP_FLAG_IN_BINMODE)) { - /* Return if we are not in binary mode. */ - return -1; - } - - if (PDATA(pgm)->flag & BP_FLAG_NOPAGEDWRITE) { - /* Return if we've nominated not to use paged writes. */ - return -1; - } - - if (page_size>1024) { - /* Page sizes greater than 1kB not yet supported. */ - return -1; - } - - if (!str_eq(m->desc,"flash")) { - /* Only flash memory currently supported. */ - 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; - } - - /* Calculate total number of page writes needed: */ - n_page_writes = n_data_bytes/page_size; - if (n_data_bytes%page_size >0) - n_page_writes++; - - /* Loop over pages: */ - for (page=0; pageop[AVR_OP_LOADPAGE_LO], &(cmd_buf[4*i])); - avr_set_addr(m->op[AVR_OP_LOADPAGE_LO], &(cmd_buf[4*i]), addr/2); - avr_set_input(m->op[AVR_OP_LOADPAGE_LO], &(cmd_buf[4*i]), m->buf[addr]); - } else { - avr_set_bits(m->op[AVR_OP_LOADPAGE_HI], &(cmd_buf[4*i])); - avr_set_addr(m->op[AVR_OP_LOADPAGE_HI], &(cmd_buf[4*i]), addr/2); - avr_set_input(m->op[AVR_OP_LOADPAGE_HI], &(cmd_buf[4*i]), m->buf[addr]); - } - } - - /* 00000100 - Write then read */ - send_byte = 0x05; - buspirate_send_bin(pgm, &send_byte, 1); - - /* Number of bytes to write: */ - send_byte = (4*this_page_size)/0x100; - buspirate_send_bin(pgm, &send_byte, 1); /* High byte */ - send_byte = (4*this_page_size)%0x100; - buspirate_send_bin(pgm, &send_byte, 1); /* Low byte */ - - /* Number of bytes to read: */ - send_byte = 0x0; - buspirate_send_bin(pgm, &send_byte, 1); /* High byte */ - buspirate_send_bin(pgm, &send_byte, 1); /* Low byte */ - - /* Send command buffer: */ - buspirate_send_bin(pgm, cmd_buf, 4*this_page_size); - - /* Check for write failure: */ - if ((buspirate_recv_bin(pgm, &recv_byte, 1) == EOF) || (recv_byte != 0x01)) { - pmsg_error("write then read did not succeed\n"); - return -1; - } - - /* Write loaded page to flash: */ - avr_write_page(pgm, p, m, addr); - } - - return n_data_bytes; + int page, i; + int addr = base_addr; + int n_page_writes; + int this_page_size; + unsigned char cmd_buf[4096] = { '\0' }; + unsigned char send_byte, recv_byte; + + if(!(my.flag & BP_FLAG_IN_BINMODE)) { + // Return if we are not in binary mode + return -1; + } + + if(my.flag & BP_FLAG_NOPAGEDWRITE) { + // Return if we've nominated not to use paged writes + return -1; + } + + if(page_size > 1024) { + // Page sizes greater than 1kB not yet supported + return -1; + } + + if(!str_eq(m->desc, "flash")) { + // Only flash memory currently supported + 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; + } + + // Calculate total number of page writes needed + n_page_writes = n_data_bytes/page_size; + if(n_data_bytes%page_size > 0) + n_page_writes++; + + // Loop over pages + for(page = 0; page < n_page_writes; page++) { + + // Determine bytes to write in this page + this_page_size = page_size; + if(page == n_page_writes - 1) + this_page_size = n_data_bytes - page_size*page; + + // Set up command buffer + memset(cmd_buf, 0, 4*this_page_size); + for(i = 0; i < this_page_size; i++) { + + addr = base_addr + page*page_size + i; + + if(i%2 == 0) { + avr_set_bits(m->op[AVR_OP_LOADPAGE_LO], &(cmd_buf[4*i])); + avr_set_addr(m->op[AVR_OP_LOADPAGE_LO], &(cmd_buf[4*i]), addr/2); + avr_set_input(m->op[AVR_OP_LOADPAGE_LO], &(cmd_buf[4*i]), m->buf[addr]); + } else { + avr_set_bits(m->op[AVR_OP_LOADPAGE_HI], &(cmd_buf[4*i])); + avr_set_addr(m->op[AVR_OP_LOADPAGE_HI], &(cmd_buf[4*i]), addr/2); + avr_set_input(m->op[AVR_OP_LOADPAGE_HI], &(cmd_buf[4*i]), m->buf[addr]); + } + } + + // 00000100 - Write then read + send_byte = 0x05; + buspirate_send_bin(pgm, &send_byte, 1); + + // Number of bytes to write + send_byte = (4*this_page_size)/0x100; + buspirate_send_bin(pgm, &send_byte, 1); // High byte + send_byte = (4*this_page_size)%0x100; + buspirate_send_bin(pgm, &send_byte, 1); // Low byte + + // Number of bytes to read + send_byte = 0x0; + buspirate_send_bin(pgm, &send_byte, 1); // High byte + buspirate_send_bin(pgm, &send_byte, 1); // Low byte + + // Send command buffer + buspirate_send_bin(pgm, cmd_buf, 4*this_page_size); + + // Check for write failure + if((buspirate_recv_bin(pgm, &recv_byte, 1) == EOF) || (recv_byte != 0x01)) { + pmsg_error("write then read did not succeed\n"); + return -1; + } + + // Write loaded page to flash + avr_write_page(pgm, p, m, addr); + } + + return n_data_bytes; } static int buspirate_program_enable(const PROGRAMMER *pgm, const AVRPART *p) { - unsigned char cmd[4]; - unsigned char res[4]; - - if (PDATA(pgm)->flag & BP_FLAG_IN_BINMODE) { - /* Clear configured reset pin(s): CS and/or AUX and/or AUX2 */ - PDATA(pgm)->current_peripherals_config &= ~PDATA(pgm)->reset; - if (buspirate_expect_bin_byte(pgm, PDATA(pgm)->current_peripherals_config, 0x01) < 0) - return -1; - } - else - buspirate_expect(pgm, "{\n", "CS ENABLED", 1); - - if (p->op[AVR_OP_PGM_ENABLE] == NULL) { - pmsg_error("program enable instruction not defined for part %s\n", p->desc); - return -1; - } - - memset(cmd, 0, sizeof(cmd)); - avr_set_bits(p->op[AVR_OP_PGM_ENABLE], cmd); - pgm->cmd(pgm, cmd, res); - - if (res[2] != cmd[1]) - return -2; - - return 0; + unsigned char cmd[4]; + unsigned char res[4]; + + if(my.flag & BP_FLAG_IN_BINMODE) { + // Clear configured reset pin(s): CS and/or AUX and/or AUX2 + my.current_peripherals_config &= ~my.reset; + if(buspirate_expect_bin_byte(pgm, my.current_peripherals_config, 0x01) < 0) + return -1; + } else + buspirate_expect(pgm, "{\n", "CS ENABLED", 1); + + if(p->op[AVR_OP_PGM_ENABLE] == NULL) { + pmsg_error("program enable instruction not defined for part %s\n", p->desc); + return -1; + } + + memset(cmd, 0, sizeof(cmd)); + avr_set_bits(p->op[AVR_OP_PGM_ENABLE], cmd); + pgm->cmd(pgm, cmd, res); + + if(res[2] != cmd[1]) + return -2; + + return 0; } static int buspirate_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("chip erase instruction not defined for part %s\n", p->desc); - return -1; - } + if(p->op[AVR_OP_CHIP_ERASE] == NULL) { + pmsg_error("chip erase instruction not defined for part %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; } -/* Interface - management */ +// Interface - management static void buspirate_setup(PROGRAMMER *pgm) { - pgm->cookie = mmt_malloc(sizeof(struct pdata)); - PDATA(pgm)->serial_recv_timeout = 100; + pgm->cookie = mmt_malloc(sizeof(struct pdata)); + my.serial_recv_timeout = 100; } static void buspirate_teardown(PROGRAMMER *pgm) { - mmt_free(pgm->cookie); - pgm->cookie = NULL; + mmt_free(pgm->cookie); + pgm->cookie = NULL; } const char buspirate_desc[] = "Using the Bus Pirate's SPI interface for programming"; void buspirate_initpgm(PROGRAMMER *pgm) { - strcpy(pgm->type, "BusPirate"); - - pgm->display = buspirate_dummy_6; - - /* BusPirate itself related methods */ - pgm->open = buspirate_open; - pgm->close = buspirate_close; - pgm->enable = buspirate_enable; - pgm->disable = buspirate_disable; - pgm->initialize = buspirate_initialize; - - /* Chip related methods */ - pgm->powerup = buspirate_powerup; - pgm->powerdown = buspirate_powerdown; - pgm->program_enable = buspirate_program_enable; - pgm->chip_erase = buspirate_chip_erase; - pgm->cmd = buspirate_cmd; - pgm->read_byte = avr_read_byte_default; - pgm->write_byte = avr_write_byte_default; - - pgm->paged_write = buspirate_paged_write; - pgm->paged_load = buspirate_paged_load; - - /* Support functions */ - pgm->parseextparams = buspirate_parseextparms; - - pgm->setup = buspirate_setup; - pgm->teardown = buspirate_teardown; + strcpy(pgm->type, "BusPirate"); + + pgm->display = buspirate_dummy_6; + + // Buspirate itself related methods + pgm->open = buspirate_open; + pgm->close = buspirate_close; + pgm->enable = buspirate_enable; + pgm->disable = buspirate_disable; + pgm->initialize = buspirate_initialize; + + // Chip related methods + pgm->powerup = buspirate_powerup; + pgm->powerdown = buspirate_powerdown; + pgm->program_enable = buspirate_program_enable; + pgm->chip_erase = buspirate_chip_erase; + pgm->cmd = buspirate_cmd; + pgm->read_byte = avr_read_byte_default; + pgm->write_byte = avr_write_byte_default; + + pgm->paged_write = buspirate_paged_write; + pgm->paged_load = buspirate_paged_load; + + // Support functions + pgm->parseextparams = buspirate_parseextparms; + + pgm->setup = buspirate_setup; + pgm->teardown = buspirate_teardown; } -/* Bitbang support */ +// Bitbang support static void buspirate_bb_enable(PROGRAMMER *pgm, const AVRPART *p) { - unsigned char buf[20] = { '\0' }; + unsigned char buf[20] = { '\0' }; - if (bitbang_check_prerequisites(pgm) < 0) - return; /* XXX should treat as error */ + if(bitbang_check_prerequisites(pgm) < 0) + return; // XXX should treat as error - pmsg_error("attempting to initiate BusPirate bitbang binary mode ...\n"); + pmsg_error("attempting to initiate BusPirate bitbang binary mode ...\n"); - /* Send two CRs to ensure we're not in a sub-menu of the UI if we're in ASCII mode: */ - buspirate_send_bin(pgm, (const unsigned char*)"\n\n", 2); + // Send two CRs to ensure we're not in a sub-menu of the UI if we're in ASCII mode + buspirate_send_bin(pgm, (const unsigned char *) "\n\n", 2); - /* Clear input buffer: */ - serial_drain(&pgm->fd, 0); + // Clear input buffer + serial_drain(&pgm->fd, 0); - /* == Switch to binmode - send 20x '\0' == */ - buspirate_send_bin(pgm, buf, sizeof(buf)); + // == Switch to binmode - send 20x '\0' == + buspirate_send_bin(pgm, buf, sizeof(buf)); - /* Expecting 'BBIOx' reply */ - memset(buf, 0, sizeof(buf)); - buspirate_recv_bin(pgm, buf, 5); - if (sscanf((char*)buf, "BBIO%1d", &PDATA(pgm)->binmode_version) != 1) { - pmsg_error("binary mode not confirmed: %s\n", buf); - buspirate_reset_from_binmode(pgm); - return; - } - msg_info("BusPirate binmode version: %d\n", PDATA(pgm)->binmode_version); + // Expecting 'BBIOx' reply + memset(buf, 0, sizeof(buf)); + buspirate_recv_bin(pgm, buf, 5); + if(sscanf((char *) buf, "BBIO%1d", &my.binmode_version) != 1) { + pmsg_error("binary mode not confirmed: %s\n", buf); + buspirate_reset_from_binmode(pgm); + return; + } + msg_info("BusPirate binmode version: %d\n", my.binmode_version); - PDATA(pgm)->flag |= BP_FLAG_IN_BINMODE; + my.flag |= BP_FLAG_IN_BINMODE; - /* Set pin directions and an initial pin status (all high) */ - PDATA(pgm)->pin_dir = 0x12; /* AUX, SDI input; everything else output */ - buf[0] = PDATA(pgm)->pin_dir | 0x40; - buspirate_send_bin(pgm, buf, 1); - buspirate_recv_bin(pgm, buf, 1); + // Set pin directions and an initial pin status (all high) + my.pin_dir = 0x12; // AUX, SDI input; everything else output + buf[0] = my.pin_dir | 0x40; + buspirate_send_bin(pgm, buf, 1); + buspirate_recv_bin(pgm, buf, 1); - PDATA(pgm)->pin_val = 0x3f; /* PULLUP, AUX, SDO, CLK, SDI, CS high */ - buf[0] = PDATA(pgm)->pin_val | 0x80; - buspirate_send_bin(pgm, buf, 1); - buspirate_recv_bin(pgm, buf, 1); + my.pin_val = 0x3f; // PULLUP, AUX, SDO, CLK, SDI, CS high + buf[0] = my.pin_val | 0x80; + buspirate_send_bin(pgm, buf, 1); + buspirate_recv_bin(pgm, buf, 1); - /* Done */ - return; + // Done + return; } /* - Direction: - 010xxxxx - Input (1) or output (0): - AUX|SDO|CLK|SDI|CS - - Output value: - 1xxxxxxx - High (1) or low(0): - 1|POWER|PULLUP|AUX|SDO|CLK|SDI|CS - - Both respond with a byte with current status: - 0|POWER|PULLUP|AUX|SDO|CLK|SDI|CS -*/ + * Direction: + * 010xxxxx + * Input (1) or output (0): + * AUX|SDO|CLK|SDI|CS + * + * Output value: + * 1xxxxxxx + * High (1) or low(0): + * 1|POWER|PULLUP|AUX|SDO|CLK|SDI|CS + * + * Both respond with a byte with current status: + * 0|POWER|PULLUP|AUX|SDO|CLK|SDI|CS + */ static int buspirate_bb_getpin(const PROGRAMMER *pgm, int pinfunc) { - unsigned char buf[10]; - int pin, value = 0; + unsigned char buf[10]; + int pin, value = 0; - if(pinfunc < 0 || pinfunc >= N_PINS) - return -1; + if(pinfunc < 0 || pinfunc >= N_PINS) + return -1; - pin = pgm->pinno[pinfunc]; + pin = pgm->pinno[pinfunc]; - if (pin & PIN_INVERSE) { - pin &= PIN_MASK; - value = 1; - } + if(pin & PIN_INVERSE) { + pin &= PIN_MASK; + value = 1; + } - if (pin < 1 || pin > 5) - return -1; + if(pin < 1 || pin > 5) + return -1; - buf[0] = PDATA(pgm)->pin_dir | 0x40; - if (buspirate_send_bin(pgm, buf, 1) < 0) - return -1; - /* Read all of the previously-expected-but-unread bytes */ - while (PDATA(pgm)->unread_bytes > 0) { - if (buspirate_recv_bin(pgm, buf, 1) < 0) - return -1; - PDATA(pgm)->unread_bytes--; - } + buf[0] = my.pin_dir | 0x40; + if(buspirate_send_bin(pgm, buf, 1) < 0) + return -1; + // Read all of the previously-expected-but-unread bytes + while(my.unread_bytes > 0) { + if(buspirate_recv_bin(pgm, buf, 1) < 0) + return -1; + my.unread_bytes--; + } - /* Now read the actual response */ - if (buspirate_recv_bin(pgm, buf, 1) < 0) - return -1; + // Now read the actual response + if(buspirate_recv_bin(pgm, buf, 1) < 0) + return -1; - if (buf[0] & (1 << (pin - 1))) - value ^= 1; + if(buf[0] & (1 << (pin - 1))) + value ^= 1; - msg_debug("get pin %d = %d\n", pin, value); + msg_debug("get pin %d = %d\n", pin, value); - return value; + return value; } static int buspirate_bb_setpin_internal(const PROGRAMMER *pgm, int pin, int value) { - unsigned char buf[10]; - - if (pin & PIN_INVERSE) { - value = !value; - pin &= PIN_MASK; - } - - if ((pin < 1 || pin > 5) && (pin != 7)) // 7 is POWER - return -1; - - msg_debug("set pin %d = %d\n", pin, value); - - if (value) - PDATA(pgm)->pin_val |= (1 << (pin - 1)); - else - PDATA(pgm)->pin_val &= ~(1 << (pin - 1)); - - buf[0] = PDATA(pgm)->pin_val | 0x80; - if (buspirate_send_bin(pgm, buf, 1) < 0) - return -1; - /* We'll get a byte back, but we don't need to read it now. - This is just a quick optimization that saves some USB - round trips, improving read times by a factor of 3. */ - PDATA(pgm)->unread_bytes++; - - return 0; + unsigned char buf[10]; + + if(pin & PIN_INVERSE) { + value = !value; + pin &= PIN_MASK; + } + + if((pin < 1 || pin > 5) && (pin != 7)) // 7 is POWER + return -1; + + msg_debug("set pin %d = %d\n", pin, value); + + if(value) + my.pin_val |= (1 << (pin - 1)); + else + my.pin_val &= ~(1 << (pin - 1)); + + buf[0] = my.pin_val | 0x80; + if(buspirate_send_bin(pgm, buf, 1) < 0) + return -1; + /* + * We'll get a byte back, but we don't need to read it now. This is just a + * quick optimization that saves some USB round trips, improving read times + * by a factor of 3. + */ + my.unread_bytes++; + + return 0; } static int buspirate_bb_setpin(const PROGRAMMER *pgm, int pinfunc, int value) { - if(pinfunc < 0 || pinfunc >= N_PINS) - return -1; + if(pinfunc < 0 || pinfunc >= N_PINS) + return -1; - return buspirate_bb_setpin_internal(pgm, pgm->pinno[pinfunc], value); + return buspirate_bb_setpin_internal(pgm, pgm->pinno[pinfunc], value); } - static int buspirate_bb_highpulsepin(const PROGRAMMER *pgm, int pinfunc) { - int ret; - ret = buspirate_bb_setpin(pgm, pinfunc, 1); - if (ret < 0) - return ret; - return buspirate_bb_setpin(pgm, pinfunc, 0); + int ret; + + ret = buspirate_bb_setpin(pgm, pinfunc, 1); + if(ret < 0) + return ret; + return buspirate_bb_setpin(pgm, pinfunc, 0); } static void buspirate_bb_powerup(const PROGRAMMER *pgm) { - buspirate_bb_setpin_internal(pgm, 7, 1); + buspirate_bb_setpin_internal(pgm, 7, 1); } static void buspirate_bb_powerdown(const PROGRAMMER *pgm) { - buspirate_bb_setpin_internal(pgm, 7, 0); + buspirate_bb_setpin_internal(pgm, 7, 0); } const char buspirate_bb_desc[] = "Using the Bus Pirate's bitbang interface for programming"; void buspirate_bb_initpgm(PROGRAMMER *pgm) { - strcpy(pgm->type, "BusPirate_BB"); - - pgm_fill_old_pins(pgm); // TODO to be removed if old pin data no longer needed - - pgm->display = buspirate_dummy_6; - - /* BusPirate itself related methods */ - pgm->setup = buspirate_setup; - pgm->teardown = buspirate_teardown; - pgm->open = buspirate_open; - pgm->close = buspirate_close; - pgm->enable = buspirate_bb_enable; - pgm->disable = buspirate_disable; - - /* Chip related methods */ - pgm->initialize = bitbang_initialize; - pgm->rdy_led = bitbang_rdy_led; - pgm->err_led = bitbang_err_led; - pgm->pgm_led = bitbang_pgm_led; - pgm->vfy_led = bitbang_vfy_led; - pgm->program_enable = bitbang_program_enable; - pgm->chip_erase = bitbang_chip_erase; - pgm->cmd = bitbang_cmd; - pgm->cmd_tpi = bitbang_cmd_tpi; - pgm->powerup = buspirate_bb_powerup; - pgm->powerdown = buspirate_bb_powerdown; - pgm->setpin = buspirate_bb_setpin; - pgm->getpin = buspirate_bb_getpin; - pgm->highpulsepin = buspirate_bb_highpulsepin; - pgm->read_byte = avr_read_byte_default; - pgm->write_byte = avr_write_byte_default; + strcpy(pgm->type, "BusPirate_BB"); + + pgm_fill_old_pins(pgm); // TODO to be removed if old pin data no longer needed + + pgm->display = buspirate_dummy_6; + + // Buspirate itself related methods + pgm->setup = buspirate_setup; + pgm->teardown = buspirate_teardown; + pgm->open = buspirate_open; + pgm->close = buspirate_close; + pgm->enable = buspirate_bb_enable; + pgm->disable = buspirate_disable; + + // Chip related methods + pgm->initialize = bitbang_initialize; + pgm->rdy_led = bitbang_rdy_led; + pgm->err_led = bitbang_err_led; + pgm->pgm_led = bitbang_pgm_led; + pgm->vfy_led = bitbang_vfy_led; + pgm->program_enable = bitbang_program_enable; + pgm->chip_erase = bitbang_chip_erase; + pgm->cmd = bitbang_cmd; + pgm->cmd_tpi = bitbang_cmd_tpi; + pgm->powerup = buspirate_bb_powerup; + pgm->powerdown = buspirate_bb_powerdown; + pgm->setpin = buspirate_bb_setpin; + pgm->getpin = buspirate_bb_getpin; + pgm->highpulsepin = buspirate_bb_highpulsepin; + pgm->read_byte = avr_read_byte_default; + pgm->write_byte = avr_write_byte_default; } diff --git a/src/buspirate.h b/src/buspirate.h index 3713a4724..ead3cbf28 100644 --- a/src/buspirate.h +++ b/src/buspirate.h @@ -26,5 +26,4 @@ extern const char buspirate_desc[]; extern const char buspirate_bb_desc[]; void buspirate_initpgm(PROGRAMMER *pgm); void buspirate_bb_initpgm(PROGRAMMER *pgm); - #endif diff --git a/src/butterfly.c b/src/butterfly.c index c3859a477..fc0d299bd 100644 --- a/src/butterfly.c +++ b/src/butterfly.c @@ -32,7 +32,6 @@ * avrdude.conf so users could call it by these name as well. */ - #include #include @@ -47,11 +46,7 @@ #include "butterfly.h" -/* - * Private data for this programmer. - */ -struct pdata -{ +struct pdata { char has_auto_incr_addr; unsigned int buffersize; @@ -61,7 +56,7 @@ struct pdata bool autoreset; }; -#define PDATA(pgm) ((struct pdata *)(pgm->cookie)) +#define my (*(struct pdata *) (pgm->cookie)) // Print error and return when command failed #define EI(x) do { \ @@ -80,7 +75,6 @@ struct pdata } \ } while(0) - static void butterfly_setup(PROGRAMMER *pgm) { pgm->cookie = mmt_malloc(sizeof(struct pdata)); } @@ -91,25 +85,22 @@ static void butterfly_teardown(PROGRAMMER *pgm) { } static int butterfly_send(const PROGRAMMER *pgm, char *buf, size_t len) { - return serial_send(&pgm->fd, (unsigned char *)buf, len); + return serial_send(&pgm->fd, (unsigned char *) buf, len); } - static int butterfly_recv(const PROGRAMMER *pgm, char *buf, size_t len) { return serial_recv(&pgm->fd, (unsigned char *) buf, len); } - static int butterfly_drain(const PROGRAMMER *pgm, int display) { return serial_drain(&pgm->fd, display); } - static int butterfly_vfy_cmd_sent(const PROGRAMMER *pgm, char *errmsg) { char c; EI(butterfly_recv(pgm, &c, 1)); - if (c != '\r') { + if(c != '\r') { pmsg_error("protocol error for command: %s\n", errmsg); return -1; } @@ -117,23 +108,20 @@ static int butterfly_vfy_cmd_sent(const PROGRAMMER *pgm, char *errmsg) { return 0; } - static int butterfly_default_led(const PROGRAMMER *pgm, int value) { // No LED: do nothing return 0; } - -/* - * issue the 'chip erase' command to the butterfly board - */ +// Issue the 'chip erase' command to the butterfly board static int butterfly_chip_erase(const PROGRAMMER *pgm, const AVRPART *p) { long bak_timeout = serial_recv_timeout; AVRMEM *fl = avr_locate_flash(p); int ret = 0; // Estimated time it takes to erase all pages in bootloader - long new_timeout = p->chip_erase_delay * (fl? fl->num_pages: 999); + long new_timeout = p->chip_erase_delay*(fl? fl->num_pages: 999); + if(serial_recv_timeout < new_timeout) serial_recv_timeout = new_timeout; @@ -145,48 +133,33 @@ static int butterfly_chip_erase(const PROGRAMMER *pgm, const AVRPART *p) { return ret; } - static int butterfly_enter_prog_mode(const PROGRAMMER *pgm) { EI(butterfly_send(pgm, "P", 1)); return butterfly_vfy_cmd_sent(pgm, "enter prog mode"); } - static void butterfly_leave_prog_mode(const PROGRAMMER *pgm) { EV(butterfly_send(pgm, "L", 1)); butterfly_vfy_cmd_sent(pgm, "leave prog mode"); } - static int butterfly_program_enable(const PROGRAMMER *pgm, const AVRPART *p) { return butterfly_enter_prog_mode(pgm); } - -/* - * apply power to the AVR processor - */ +// Apply power to the AVR processor static void butterfly_powerup(const PROGRAMMER *pgm) { - /* Do nothing. */ - return; } - -/* - * remove power from the AVR processor - */ +// Remove power from the AVR processor static void butterfly_powerdown(const PROGRAMMER *pgm) { - /* Do nothing. */ - return; } #define IS_BUTTERFLY_MK 0x0001 -/* - * initialize the AVR device and prepare it to accept commands - */ +// Initialize the AVR device and prepare it to accept commands static int butterfly_initialize(const PROGRAMMER *pgm, const AVRPART *p) { char id[8]; char sw[2]; @@ -196,143 +169,137 @@ static int butterfly_initialize(const PROGRAMMER *pgm, const AVRPART *p) { char c, devtype_1st; /* - * Send some ESC to activate butterfly bootloader. This is not needed - * for plain avr109 bootloaders but does not harm there either. + * Send some ESC to activate butterfly bootloader. This is not needed for + * plain avr109 bootloaders but does not harm there either. */ msg_notice("connecting to programmer: "); - if (pgm->flag & IS_BUTTERFLY_MK) - { - char mk_reset_cmd[6] = {"#aR@S\r"}; - unsigned char mk_timeout = 0; + if(pgm->flag & IS_BUTTERFLY_MK) { + char mk_reset_cmd[6] = { "#aR@S\r" }; + unsigned char mk_timeout = 0; + + msg_notice("."); + EI(butterfly_send(pgm, mk_reset_cmd, sizeof(mk_reset_cmd))); + usleep(20000); + + do { + c = 27; + EI(butterfly_send(pgm, &c, 1)); + usleep(20000); + c = 0xaa; + usleep(80000); + EI(butterfly_send(pgm, &c, 1)); + if(mk_timeout%10 == 0) + msg_notice("."); + } while(mk_timeout++ < 10); + EI(butterfly_recv(pgm, &c, 1)); + if(c != 'M' && c != '?') { + msg_error("\n"); + pmsg_error("connection failed"); + return -1; + } else { + id[0] = 'M'; + id[1] = 'K'; + id[2] = '2'; + id[3] = 0; + } + } else { + do { msg_notice("."); - EI(butterfly_send(pgm, mk_reset_cmd, sizeof(mk_reset_cmd))); - usleep(20000); - - do - { - c = 27; - EI(butterfly_send(pgm, &c, 1)); - usleep(20000); - c = 0xaa; - usleep(80000); - EI(butterfly_send(pgm, &c, 1)); - if (mk_timeout % 10 == 0) - msg_notice("."); - } while (mk_timeout++ < 10); - + EI(butterfly_send(pgm, "\033", 1)); + (void) butterfly_drain(pgm, 0); + EI(butterfly_send(pgm, "S", 1)); EI(butterfly_recv(pgm, &c, 1)); - if ( c != 'M' && c != '?') - { - msg_error("\n"); - pmsg_error("connection failed"); - return -1; - } - else - { - id[0] = 'M'; id[1] = 'K'; id[2] = '2'; id[3] = 0; - } - } - else - { - do { - msg_notice("."); - EI(butterfly_send(pgm, "\033", 1)); - (void) butterfly_drain(pgm, 0); - EI(butterfly_send(pgm, "S", 1)); - EI(butterfly_recv(pgm, &c, 1)); - if (c != '?') { - msg_notice("\n"); - /* - * Got a useful response, continue getting the programmer - * identifier. Programmer returns exactly 7 chars _without_ - * the null. - */ - id[0] = c; - EI(butterfly_recv(pgm, &id[1], sizeof(id)-2)); - id[sizeof(id)-1] = '\0'; - } - } while (c == '?'); - } + if(c != '?') { + msg_notice("\n"); + /* + * Got a useful response, continue getting the programmer identifier. + * Programmer returns exactly 7 chars _without_ the null. + */ + id[0] = c; + EI(butterfly_recv(pgm, &id[1], sizeof(id) - 2)); + id[sizeof(id) - 1] = '\0'; + } + } while(c == '?'); + } - /* Get the HW and SW versions to see if the programmer is present. */ + // Get the HW and SW versions to see if the programmer is present (void) butterfly_drain(pgm, 0); EI(butterfly_send(pgm, "V", 1)); EI(butterfly_recv(pgm, sw, sizeof(sw))); EI(butterfly_send(pgm, "v", 1)); - EI(butterfly_recv(pgm, hw, 1)); // First, read only _one_ byte - if (hw[0]!='?') { + EI(butterfly_recv(pgm, hw, 1)); // First, read only _one_ byte + if(hw[0] != '?') { EI(butterfly_recv(pgm, &hw[1], 1)); // Now, read second byte }; - /* Get the programmer type (serial or parallel). Expect serial. */ + // Get the programmer type (serial or parallel); Expect serial EI(butterfly_send(pgm, "p", 1)); EI(butterfly_recv(pgm, &type, 1)); msg_notice("Programmer id = %s; type = %c\n", id, type); msg_notice("Software version = %c.%c; ", sw[0], sw[1]); - if (hw[0]=='?') { + if(hw[0] == '?') { msg_notice("no hardware version given\n"); } else { msg_notice("Hardware version = %c.%c\n", hw[0], hw[1]); }; - /* See if programmer supports autoincrement of address. */ + // See if programmer supports autoincrement of address EI(butterfly_send(pgm, "a", 1)); - EI(butterfly_recv(pgm, &PDATA(pgm)->has_auto_incr_addr, 1)); - if (PDATA(pgm)->has_auto_incr_addr == 'Y') - msg_notice("programmer supports auto addr increment\n"); + EI(butterfly_recv(pgm, &my.has_auto_incr_addr, 1)); + if(my.has_auto_incr_addr == 'Y') + msg_notice("programmer supports auto addr increment\n"); - /* Check support for buffered memory access, abort if not available */ + // Check support for buffered memory access, abort if not available EI(butterfly_send(pgm, "b", 1)); EI(butterfly_recv(pgm, &c, 1)); - if (c != 'Y') { - pmsg_notice("buffered memory access not supported; maybe it isn't\n"\ - "a butterfly/AVR109 but a AVR910 device?\n"); + if(c != 'Y') { + pmsg_notice("buffered memory access not supported; maybe it isn't\n" "a butterfly/AVR109 but a AVR910 device?\n"); return -1; }; EI(butterfly_recv(pgm, &c, 1)); - PDATA(pgm)->buffersize = (unsigned int)(unsigned char)c<<8; + my.buffersize = (unsigned int) (unsigned char) c << 8; EI(butterfly_recv(pgm, &c, 1)); - PDATA(pgm)->buffersize += (unsigned int)(unsigned char)c; - msg_notice("programmer supports buffered memory access with buffersize=%i bytes\n", - PDATA(pgm)->buffersize); + my.buffersize += (unsigned int) (unsigned char) c; + msg_notice("programmer supports buffered memory access with buffersize=%i bytes\n", my.buffersize); - /* Get list of devices that the programmer supports. */ + // Get list of devices that the programmer supports EI(butterfly_send(pgm, "t", 1)); msg_notice2("\nProgrammer supports the following devices:\n"); devtype_1st = 0; - while (1) { + while(1) { EI(butterfly_recv(pgm, &c, 1)); - if (devtype_1st == 0) + if(devtype_1st == 0) devtype_1st = c; - if (c == 0) + if(c == 0) break; msg_notice2(" Device code: 0x%02x\n", (unsigned char) c); }; msg_notice2("\n"); - /* Tell the programmer which part we selected. - According to the AVR109 code, this is ignored by the bootloader. As - some early versions might not properly ignore it, rather pick up the - first device type as reported above than anything out of avrdude.conf, - so to avoid a potential conflict. There appears to be no general - agreement on AVR910 device IDs beyond the ones from the original - appnote 910. */ + /* + * Tell the programmer which part we selected. According to the AVR109 code, + * this is ignored by the bootloader. As some early versions might not + * properly ignore it, rather pick up the first device type as reported above + * than anything out of avrdude.conf, so to avoid a potential conflict. + * There appears to be no general agreement on AVR910 device IDs beyond the + * ones from the original appnote 910. + */ buf[0] = 'T'; buf[1] = devtype_1st; EI(butterfly_send(pgm, buf, 2)); - if (butterfly_vfy_cmd_sent(pgm, "select device") < 0) - return -1; + if(butterfly_vfy_cmd_sent(pgm, "select device") < 0) + return -1; pmsg_notice("devcode selected: 0x%02x\n", (unsigned) buf[1]); @@ -343,22 +310,19 @@ static int butterfly_initialize(const PROGRAMMER *pgm, const AVRPART *p) { return 0; } - - static void butterfly_disable(const PROGRAMMER *pgm) { butterfly_leave_prog_mode(pgm); return; } - static void butterfly_enable(PROGRAMMER *pgm, const AVRPART *p) { return; } - static int butterfly_open(PROGRAMMER *pgm, const char *port) { union pinfo pinfo; + pgm->port = port; // If baudrate was not specified use 19200 Baud @@ -367,35 +331,32 @@ static int butterfly_open(PROGRAMMER *pgm, const char *port) { } pinfo.serialinfo.baud = pgm->baudrate; pinfo.serialinfo.cflags = SERIAL_8N1; - if (serial_open(port, pinfo, &pgm->fd)==-1) { + if(serial_open(port, pinfo, &pgm->fd) == -1) { return -1; } - if(PDATA(pgm)->autoreset) { + if(my.autoreset) { // This code assumes a negative-logic USB to TTL serial adapter // Set RTS/DTR high to discharge the series-capacitor, if present pmsg_notice2("toggling the DTR/RTS lines to trigger a hardware reset\n"); serial_set_dtr_rts(&pgm->fd, 0); - usleep(250 * 1000); + usleep(250*1000); // Pull the RTS/DTR line low to reset AVR serial_set_dtr_rts(&pgm->fd, 1); // Max 100 us: charging a cap longer creates a high reset spike above Vcc usleep(100); // Set the RTS/DTR line back to high, so direct connection to reset works serial_set_dtr_rts(&pgm->fd, 0); - usleep(100 * 1000); + usleep(100*1000); } - // Drain any extraneous input (void) butterfly_drain(pgm, 0); return 0; } - -static void butterfly_close(PROGRAMMER * pgm) -{ - /* "exit programmer" */ +static void butterfly_close(PROGRAMMER *pgm) { + // Exit programmer EV(butterfly_send(pgm, "E", 1)); butterfly_vfy_cmd_sent(pgm, "exit bootloader"); @@ -403,20 +364,18 @@ static void butterfly_close(PROGRAMMER * pgm) pgm->fd.ifd = -1; } - static void butterfly_display(const PROGRAMMER *pgm, const char *p) { return; } - static void butterfly_set_addr(const PROGRAMMER *pgm, unsigned long addr) { - if( addr < 0x10000 ) { + if(addr < 0x10000) { char cmd[3]; cmd[0] = 'A'; cmd[1] = (addr >> 8) & 0xff; cmd[2] = addr & 0xff; - + EV(butterfly_send(pgm, cmd, sizeof(cmd))); butterfly_vfy_cmd_sent(pgm, "set addr"); } else { @@ -432,7 +391,6 @@ static void butterfly_set_addr(const PROGRAMMER *pgm, unsigned long addr) { } } - static void butterfly_set_extaddr(const PROGRAMMER *pgm, unsigned long addr) { char cmd[4]; @@ -445,24 +403,21 @@ static void butterfly_set_extaddr(const PROGRAMMER *pgm, unsigned long addr) { butterfly_vfy_cmd_sent(pgm, "set extaddr"); } - - static int butterfly_write_byte(const PROGRAMMER *pgm, const AVRPART *p, const AVRMEM *m, - unsigned long addr, unsigned char value) -{ + unsigned long addr, unsigned char value) { char cmd[6]; int size; if(mem_is_flash(m)) { int ext_addr = m->op[AVR_OP_LOAD_EXT_ADDR] != NULL; - PDATA(pgm)->ctype = 0; // Invalidate read cache + my.ctype = 0; // Invalidate read cache cmd[0] = 'B'; cmd[1] = 0; cmd[2] = 2; cmd[3] = 'F'; size = 6; - (ext_addr? butterfly_set_extaddr: butterfly_set_addr)(pgm, addr >> 1); + (ext_addr? butterfly_set_extaddr: butterfly_set_addr) (pgm, addr >> 1); return -1; // @@@ not yet implemented (and what about usersig?) } @@ -481,26 +436,24 @@ static int butterfly_write_byte(const PROGRAMMER *pgm, const AVRPART *p, const A size = 2; } else if(mem_is_readonly(m)) { unsigned char is; + if(pgm->read_byte(pgm, p, m, addr, &is) >= 0 && is == value) return 0; pmsg_error("cannot write to read-only memory %s of %s\n", m->desc, p->desc); return -1; - } - else + } else return -1; EI(butterfly_send(pgm, cmd, size)); - if (butterfly_vfy_cmd_sent(pgm, "write byte") < 0) - return -1; + if(butterfly_vfy_cmd_sent(pgm, "write byte") < 0) + return -1; return 0; } - static int butterfly_read_byte_flash(const PROGRAMMER *pgm, const AVRPART *p, const AVRMEM *m, - unsigned long addr, unsigned char * value) -{ + unsigned long addr, unsigned char *value) { int ext_addr = m->op[AVR_OP_LOAD_EXT_ADDR] != NULL; char mtype = mem_is_flash(m)? 'F': mem_is_in_sigrow(m)? 'P': mem_is_userrow(m)? 'U': '?'; @@ -511,30 +464,28 @@ static int butterfly_read_byte_flash(const PROGRAMMER *pgm, const AVRPART *p, co return -1; } - if(PDATA(pgm)->ctype == mtype && PDATA(pgm)->caddr == addr) { - *value = PDATA(pgm)->cvalue; + if(my.ctype == mtype && my.caddr == addr) { + *value = my.cvalue; return 0; } - char buf[2]; // Read word and cache the other byte - char msg[4] = {'g', 0x00, 0x02, mtype}; + char buf[2]; // Read word and cache the other byte + char msg[4] = { 'g', 0x00, 0x02, mtype }; - (ext_addr? butterfly_set_extaddr: butterfly_set_addr)(pgm, addr >> 1); + (ext_addr? butterfly_set_extaddr: butterfly_set_addr) (pgm, addr >> 1); EI(butterfly_send(pgm, msg, 4)); EI(butterfly_recv(pgm, buf, sizeof(buf))); - PDATA(pgm)->ctype = mtype; + my.ctype = mtype; *value = buf[addr & 1]; - PDATA(pgm)->cvalue = buf[1 - (addr & 1)]; - PDATA(pgm)->caddr = addr ^ 1; + my.cvalue = buf[1 - (addr & 1)]; + my.caddr = addr ^ 1; return 0; } - static int butterfly_read_byte_eeprom(const PROGRAMMER *pgm, const AVRPART *p, const AVRMEM *m, - unsigned long addr, unsigned char * value) -{ + unsigned long addr, unsigned char *value) { butterfly_set_addr(pgm, addr); EI(butterfly_send(pgm, "g\000\001E", 4)); EI(butterfly_recv(pgm, (char *) value, 1)); @@ -542,31 +493,26 @@ static int butterfly_read_byte_eeprom(const PROGRAMMER *pgm, const AVRPART *p, c } static int butterfly_read_byte(const PROGRAMMER *pgm, const AVRPART *p, const AVRMEM *m, - unsigned long addr, unsigned char * value) -{ + unsigned long addr, unsigned char *value) { char cmd; - if (mem_is_flash(m) || mem_is_in_sigrow(m) || mem_is_userrow(m)) { + if(mem_is_flash(m) || mem_is_in_sigrow(m) || mem_is_userrow(m)) { return butterfly_read_byte_flash(pgm, p, m, addr, value); } - if (mem_is_eeprom(m)) { + if(mem_is_eeprom(m)) { return butterfly_read_byte_eeprom(pgm, p, m, addr, value); } - if (mem_is_lfuse(m)) { + if(mem_is_lfuse(m)) { cmd = 'F'; - } - else if (mem_is_hfuse(m)) { + } else if(mem_is_hfuse(m)) { cmd = 'N'; - } - else if (mem_is_efuse(m)) { + } else if(mem_is_efuse(m)) { cmd = 'Q'; - } - else if (mem_is_lock(m)) { + } else if(mem_is_lock(m)) { cmd = 'r'; - } - else + } else return -1; EI(butterfly_send(pgm, &cmd, 1)); @@ -575,50 +521,45 @@ static int butterfly_read_byte(const PROGRAMMER *pgm, const AVRPART *p, const AV return *value == '?'? -1: 0; } - - static int butterfly_paged_write(const PROGRAMMER *pgm, const AVRPART *p, const AVRMEM *m, - unsigned int page_size, - unsigned int addr, unsigned int n_bytes) -{ + unsigned int page_size, unsigned int addr, unsigned int n_bytes) { unsigned int max_addr = addr + n_bytes; char *cmd; - unsigned int blocksize = PDATA(pgm)->buffersize; + unsigned int blocksize = my.buffersize; int ext_addr = m->op[AVR_OP_LOAD_EXT_ADDR] != NULL; int isee = mem_is_eeprom(m); - if (!mem_is_flash(m) && !isee && !mem_is_userrow(m)) + if(!mem_is_flash(m) && !isee && !mem_is_userrow(m)) return -2; if(isee) // Write single bytes to EEPROM blocksize = 1; else - PDATA(pgm)->ctype = 0; // Invalidate flash byte read cache + my.ctype = 0; // Invalidate flash byte read cache - (ext_addr? butterfly_set_extaddr: butterfly_set_addr)(pgm, isee? addr: addr>>1); + (ext_addr? butterfly_set_extaddr: butterfly_set_addr) (pgm, isee? addr: addr >> 1); #if 0 usleep(1000000); EI(butterfly_send(pgm, "y", 1)); - if (butterfly_vfy_cmd_sent(pgm, "clear LED") < 0) + if(butterfly_vfy_cmd_sent(pgm, "clear LED") < 0) return -1; #endif - cmd = mmt_malloc(4+blocksize); + cmd = mmt_malloc(4 + blocksize); cmd[0] = 'B'; cmd[3] = isee? 'E': mem_is_flash(m)? 'F': 'U'; - while (addr < max_addr) { - if ((max_addr - addr) < blocksize) + while(addr < max_addr) { + if((max_addr - addr) < blocksize) blocksize = max_addr - addr; memcpy(&cmd[4], &m->buf[addr], blocksize); cmd[1] = (blocksize >> 8) & 0xff; cmd[2] = blocksize & 0xff; - if(butterfly_send(pgm, cmd, 4+blocksize) < 0 || - butterfly_vfy_cmd_sent(pgm, "write block") < 0) { + if(butterfly_send(pgm, cmd, 4 + blocksize) < 0 || butterfly_vfy_cmd_sent(pgm, "write block") < 0) { mmt_free(cmd); return -1; @@ -631,19 +572,15 @@ static int butterfly_paged_write(const PROGRAMMER *pgm, const AVRPART *p, const return n_bytes; } - - static int butterfly_paged_load(const PROGRAMMER *pgm, const AVRPART *p, const AVRMEM *m, - unsigned int page_size, - unsigned int addr, unsigned int n_bytes) -{ + unsigned int page_size, unsigned int addr, unsigned int n_bytes) { unsigned int max_addr = addr + n_bytes; - int blocksize = PDATA(pgm)->buffersize; + int blocksize = my.buffersize; int ext_addr = m->op[AVR_OP_LOAD_EXT_ADDR] != NULL; int isee = mem_is_eeprom(m); // Only flash, EEPROM or usersig/userrow is allowed - if (!mem_is_flash(m) && !isee && !mem_is_userrow(m)) + if(!mem_is_flash(m) && !isee && !mem_is_userrow(m)) return -2; if(isee) // Read single bytes from EEPROM @@ -654,10 +591,10 @@ static int butterfly_paged_load(const PROGRAMMER *pgm, const AVRPART *p, const A cmd[0] = 'g'; cmd[3] = isee? 'E': mem_is_flash(m)? 'F': 'U'; - (ext_addr? butterfly_set_extaddr: butterfly_set_addr)(pgm, isee? addr: addr>>1); + (ext_addr? butterfly_set_extaddr: butterfly_set_addr) (pgm, isee? addr: addr >> 1); - while (addr < max_addr) { - if ((max_addr - addr) < (unsigned int) blocksize) + while(addr < max_addr) { + if((max_addr - addr) < (unsigned int) blocksize) blocksize = max_addr - addr; cmd[1] = (blocksize >> 8) & 0xff; @@ -672,19 +609,18 @@ static int butterfly_paged_load(const PROGRAMMER *pgm, const AVRPART *p, const A return n_bytes; } - -/* Signature byte reads are always 3 bytes. */ +// Signature byte reads are always 3 bytes static int butterfly_read_sig_bytes(const PROGRAMMER *pgm, const AVRPART *p, const AVRMEM *m) { unsigned char tmp; - if (m->size < 3) { + if(m->size < 3) { pmsg_error("memsize too small for sig byte read"); return -1; } EI(butterfly_send(pgm, "s", 1)); EI(butterfly_recv(pgm, (char *) m->buf, 3)); - /* Returned signature has wrong order. */ + // Returned signature has wrong order tmp = m->buf[2]; m->buf[2] = m->buf[0]; m->buf[0] = tmp; @@ -697,20 +633,20 @@ static int butterfly_parseextparms(const PROGRAMMER *pgm, const LISTID extparms) int rv = 0; bool help = 0; - for (LNODEID ln = lfirst(extparms); ln; ln = lnext(ln)) { + for(LNODEID ln = lfirst(extparms); ln; ln = lnext(ln)) { extended_param = ldata(ln); if(str_eq(extended_param, "autoreset")) { - PDATA(pgm)->autoreset = true; + my.autoreset = true; continue; } - if (str_eq(extended_param, "help")) { + if(str_eq(extended_param, "help")) { help = true; rv = LIBAVRDUDE_EXIT; } - if (!help) { + if(!help) { pmsg_error("invalid extended parameter -x %s\n", extended_param); rv = -1; } @@ -728,37 +664,32 @@ const char butterfly_desc[] = "Atmel Butterfly evaluation board; Atmel AppNotes void butterfly_initpgm(PROGRAMMER *pgm) { strcpy(pgm->type, "butterfly"); - /* - * mandatory functions - */ - pgm->rdy_led = butterfly_default_led; - pgm->err_led = butterfly_default_led; - pgm->pgm_led = butterfly_default_led; - pgm->vfy_led = butterfly_default_led; - pgm->initialize = butterfly_initialize; - pgm->display = butterfly_display; - pgm->enable = butterfly_enable; - pgm->disable = butterfly_disable; - pgm->powerup = butterfly_powerup; - pgm->powerdown = butterfly_powerdown; + // Mandatory functions + pgm->rdy_led = butterfly_default_led; + pgm->err_led = butterfly_default_led; + pgm->pgm_led = butterfly_default_led; + pgm->vfy_led = butterfly_default_led; + pgm->initialize = butterfly_initialize; + pgm->display = butterfly_display; + pgm->enable = butterfly_enable; + pgm->disable = butterfly_disable; + pgm->powerup = butterfly_powerup; + pgm->powerdown = butterfly_powerdown; pgm->program_enable = butterfly_program_enable; - pgm->chip_erase = butterfly_chip_erase; - pgm->open = butterfly_open; - pgm->close = butterfly_close; - pgm->read_byte = butterfly_read_byte; - pgm->write_byte = butterfly_write_byte; - - /* - * optional functions - */ + pgm->chip_erase = butterfly_chip_erase; + pgm->open = butterfly_open; + pgm->close = butterfly_close; + pgm->read_byte = butterfly_read_byte; + pgm->write_byte = butterfly_write_byte; + // Optional functions pgm->paged_write = butterfly_paged_write; pgm->paged_load = butterfly_paged_load; pgm->read_sig_bytes = butterfly_read_sig_bytes; pgm->parseextparams = butterfly_parseextparms; - pgm->setup = butterfly_setup; - pgm->teardown = butterfly_teardown; + pgm->setup = butterfly_setup; + pgm->teardown = butterfly_teardown; pgm->flag = 0; } diff --git a/src/butterfly.h b/src/butterfly.h index 3ba48dfee..9bfc30bc3 100644 --- a/src/butterfly.h +++ b/src/butterfly.h @@ -23,13 +23,13 @@ extern "C" { #endif -extern const char butterfly_desc[]; -extern const char butterfly_mk_desc[]; -void butterfly_initpgm(PROGRAMMER *pgm); -void butterfly_mk_initpgm(PROGRAMMER *pgm); + extern const char butterfly_desc[]; + extern const char butterfly_mk_desc[]; + void butterfly_initpgm(PROGRAMMER *pgm); + void butterfly_mk_initpgm(PROGRAMMER *pgm); #ifdef __cplusplus } #endif -#endif /* butterfly_h */ +#endif diff --git a/src/ch341a.c b/src/ch341a.c index ba2276c05..5202182be 100644 --- a/src/ch341a.c +++ b/src/ch341a.c @@ -18,10 +18,8 @@ * along with this program. If not, see . */ -/* - * Interface to the CH341A programmer - * - */ +// Interface to the CH341A programmer + #include #include @@ -37,7 +35,6 @@ #include "usbdevs.h" #if defined(HAVE_LIBUSB_1_0) - #define USE_LIBUSB_1_0 #if defined(HAVE_LIBUSB_1_0_LIBUSB_H) @@ -50,7 +47,7 @@ #ifdef USE_LIBUSB_1_0 static int libusb_to_errno(int result) { - switch (result) { + switch(result) { case LIBUSB_SUCCESS: return 0; case LIBUSB_ERROR_IO: @@ -99,7 +96,7 @@ struct pdata { int USB_init; // Used in ch341a_open() }; -#define PDATA(pgm) ((struct pdata *)(pgm->cookie)) +#define my (*(struct pdata *) (pgm->cookie)) // ---------------------------------------------------------------------- @@ -117,7 +114,6 @@ static void ch341a_disable(const PROGRAMMER *pgm); static void ch341a_enable(PROGRAMMER *pgm, const AVRPART *p); static void ch341a_display(const PROGRAMMER *pgm, const char *p); - // ch341 requires LSB first: invert the bit order before sending and after receiving static unsigned char swap_byte(unsigned char byte) { byte = ((byte >> 1) & 0x55) | ((byte << 1) & 0xaa); @@ -132,11 +128,11 @@ static int CH341USBTransferPart(const PROGRAMMER *pgm, enum libusb_endpoint_dire int ret, bytestransferred; - if(!PDATA(pgm)->usbhandle) + if(!my.usbhandle) return 0; - if((ret = libusb_bulk_transfer(PDATA(pgm)->usbhandle, CH341A_USB_BULK_ENDPOINT | dir, - buff, size, &bytestransferred, CH341A_USB_TIMEOUT))) { + if((ret = libusb_bulk_transfer(my.usbhandle, CH341A_USB_BULK_ENDPOINT | dir, + buff, size, &bytestransferred, CH341A_USB_TIMEOUT))) { pmsg_error("libusb_bulk_transfer for IN_EP failed, return value %d (%s)\n", ret, libusb_error_name(ret)); return -1; @@ -162,9 +158,9 @@ static bool CH341USBTransfer(const PROGRAMMER *pgm, enum libusb_endpoint_directi } /* - * Below the assumed map between UIO command bits, pins on CH341A chip and - * pins on SPI chip. The UIO stream commands only have 6 bits of output, - * D6/D7 are SPI inputs. + * Below the assumed map between UIO command bits, pins on CH341A chip and pins + * on SPI chip. The UIO stream commands only have 6 bits of output, D6/D7 are + * SPI inputs. * * UIO CH341A pin/name AVR target * ------------------------------------------- @@ -199,7 +195,6 @@ bool CH341ChipSelect(const PROGRAMMER *pgm, unsigned int cs, bool enable) { return CH341USBTransferPart(pgm, LIBUSB_ENDPOINT_OUT, cmd, 4) > 0; } - static int ch341a_open(PROGRAMMER *pgm, const char *port) { LNODEID usbpid = lfirst(pgm->usbpid); int pid, vid, j, r; @@ -208,9 +203,9 @@ static int ch341a_open(PROGRAMMER *pgm, const char *port) { pmsg_trace("ch341a_open(\"%s\")\n", port); - if(!PDATA(pgm)->USB_init) { - PDATA(pgm)->USB_init = 1; - libusb_init(&PDATA(pgm)->ctx); + if(!my.USB_init) { + my.USB_init = 1; + libusb_init(&my.ctx); } if(usbpid) { @@ -223,7 +218,7 @@ static int ch341a_open(PROGRAMMER *pgm, const char *port) { vid = pgm->usbvid? pgm->usbvid: CH341A_VID; libusb_device **dev_list; - int dev_list_len = libusb_get_device_list(PDATA(pgm)->ctx, &dev_list); + int dev_list_len = libusb_get_device_list(my.ctx, &dev_list); for(j = 0; j < dev_list_len; ++j) { libusb_device *dev = dev_list[j]; @@ -242,17 +237,17 @@ static int ch341a_open(PROGRAMMER *pgm, const char *port) { libusb_free_device_list(dev_list, 1); if(handle != NULL) { errorCode = 0; - PDATA(pgm)->usbhandle = handle; + my.usbhandle = handle; } if(errorCode != 0) { pmsg_error("could not find USB device with vid=0x%x pid=0x%x\n", vid, pid); return -1; } - if((r = libusb_claim_interface(PDATA(pgm)->usbhandle, 0))) { + if((r = libusb_claim_interface(my.usbhandle, 0))) { pmsg_error("libusb_claim_interface failed, return value %d (%s)\n", r, libusb_error_name(r)); - libusb_close(PDATA(pgm)->usbhandle); - libusb_exit(PDATA(pgm)->ctx); + libusb_close(my.usbhandle); + libusb_exit(my.ctx); return -1; } return 0; @@ -268,14 +263,13 @@ static void ch341a_close(PROGRAMMER *pgm) { CH341ChipSelect(pgm, cs, false); - if(PDATA(pgm)->usbhandle != NULL) { - libusb_release_interface(PDATA(pgm)->usbhandle, 0); - libusb_close(PDATA(pgm)->usbhandle); + if(my.usbhandle != NULL) { + libusb_release_interface(my.usbhandle, 0); + libusb_close(my.usbhandle); } - libusb_exit(PDATA(pgm)->ctx); + libusb_exit(my.ctx); } - static int ch341a_initialize(const PROGRAMMER *pgm, const AVRPART *p) { pmsg_trace("ch341a_initialize()\n"); @@ -288,7 +282,7 @@ static int ch341a_initialize(const PROGRAMMER *pgm, const AVRPART *p) { pmsg_error("CH341ChipSelect(..., false) failed\n"); return -1; } - usleep(20 * 1000); + usleep(20*1000); if(!CH341ChipSelect(pgm, cs, true)) { pmsg_error("CH341ChipSelect(..., true) failed\n"); return -1; @@ -297,7 +291,6 @@ static int ch341a_initialize(const PROGRAMMER *pgm, const AVRPART *p) { return pgm->program_enable(pgm, p); } - static int ch341a_spi(const PROGRAMMER *pgm, const unsigned char *in, unsigned char *out, int size) { unsigned char pkt[CH341A_PACKET_LENGTH]; @@ -310,7 +303,7 @@ static int ch341a_spi(const PROGRAMMER *pgm, const unsigned char *in, unsigned c pkt[0] = CH341A_CMD_SPI_STREAM; for(int i = 0; i < size; i++) - pkt[i+1] = swap_byte(in[i]); + pkt[i + 1] = swap_byte(in[i]); if(!CH341USBTransfer(pgm, LIBUSB_ENDPOINT_OUT, pkt, size + 1)) { pmsg_error("failed to transfer data to CH341\n"); @@ -332,7 +325,6 @@ static int ch341a_spi_cmd(const PROGRAMMER *pgm, const unsigned char *cmd, unsig return pgm->spi(pgm, cmd, res, 4); } - static int ch341a_spi_chip_erase(const PROGRAMMER *pgm, const AVRPART *p) { unsigned char cmd[4]; unsigned char res[4]; @@ -349,7 +341,6 @@ static int ch341a_spi_chip_erase(const PROGRAMMER *pgm, const AVRPART *p) { return 0; } - // Fall back on bytewise write (followed by write page if flash) static int ch341a_spi_paged_write(const PROGRAMMER *pgm, const AVRPART *p, const AVRMEM *m, unsigned int page_size, unsigned int addr, unsigned int n_bytes) { @@ -388,7 +379,7 @@ static int ch341a_spi_paged_load(const PROGRAMMER *pgm, const AVRPART *p, const memset(cmd, 0, sizeof cmd); avr_set_bits(m->op[AVR_OP_LOAD_EXT_ADDR], cmd); - avr_set_addr(m->op[AVR_OP_LOAD_EXT_ADDR], cmd, addr / 2); + avr_set_addr(m->op[AVR_OP_LOAD_EXT_ADDR], cmd, addr/2); if(pgm->cmd(pgm, cmd, res) < 0) return -1; } @@ -401,7 +392,6 @@ static int ch341a_spi_paged_load(const PROGRAMMER *pgm, const AVRPART *p, const return n_bytes; } - static int ch341a_spi_program_enable(const PROGRAMMER *pgm, const AVRPART *p) { unsigned char res[4]; unsigned char cmd[4]; @@ -426,7 +416,6 @@ static int ch341a_spi_program_enable(const PROGRAMMER *pgm, const AVRPART *p) { return 0; } - // Interface management static void ch341a_setup(PROGRAMMER *pgm) { pgm->cookie = mmt_malloc(sizeof(struct pdata)); @@ -475,7 +464,7 @@ void ch341a_initpgm(PROGRAMMER *pgm) { } // ---------------------------------------------------------------------- -#else // !defined(HAVE_LIBUSB_1_0) +#else // !defined(HAVE_LIBUSB_1_0) static int ch341a_nousb_open(PROGRAMMER *pgm, const char *name) { pmsg_error("no usb support, please compile again with libusb installed\n"); @@ -486,6 +475,6 @@ void ch341a_initpgm(PROGRAMMER *pgm) { strcpy(pgm->type, "ch341a"); pgm->open = ch341a_nousb_open; } -#endif // !defined(HAVE_LIBUSB_1_0) +#endif // !defined(HAVE_LIBUSB_1_0) const char ch341a_desc[] = "Programmer chip CH341A (AVR must have minimum F_CPU of 6.8 MHz)"; diff --git a/src/ch341a.h b/src/ch341a.h index 1d9b04bc6..1aad27741 100644 --- a/src/ch341a.h +++ b/src/ch341a.h @@ -18,7 +18,6 @@ * along with this program. If not, see . */ - #ifndef ch341a_h #define ch341a_h @@ -32,34 +31,31 @@ #define CH341A_USB_TIMEOUT 15000 -#define CH341A_CMD_SPI_STREAM 0xA8 // SPI command -#define CH341A_CMD_UIO_STREAM 0xAB // UIO command +#define CH341A_CMD_SPI_STREAM 0xA8 // SPI command +#define CH341A_CMD_UIO_STREAM 0xAB // UIO command -#define CH341A_CMD_UIO_STM_IN 0x00 // UIO Interface In (D0~D7) -#define CH341A_CMD_UIO_STM_DIR 0x40 // UIO interface Dir (set dir of D0~D5) -#define CH341A_CMD_UIO_STM_OUT 0x80 // UIO Interface Output (D0~D5) -#define CH341A_CMD_UIO_STM_END 0x20 // UIO Interface End Command +#define CH341A_CMD_UIO_STM_IN 0x00 // UIO Interface In (D0~D7) +#define CH341A_CMD_UIO_STM_DIR 0x40 // UIO interface Dir (set dir of D0~D5) +#define CH341A_CMD_UIO_STM_OUT 0x80 // UIO Interface Output (D0~D5) +#define CH341A_CMD_UIO_STM_END 0x20 // UIO Interface End Command #define CH341A_CMD_I2C_STREAM 0xAA -#define CH341A_CMD_I2C_STM_SET 0x60 // Bit 2: SPI with two data pairs D5,D4=out, D7,D6=in +#define CH341A_CMD_I2C_STM_SET 0x60 // Bit 2: SPI with two data pairs (D5, D4)=out, (D7, D6)=in #define CH341A_CMD_I2C_STM_END 0x00 - // USB error identifiers #define USB_ERROR_NOTFOUND 1 #define USB_ERROR_ACCESS 2 #define USB_ERROR_IO 3 - #ifdef __cplusplus extern "C" { #endif -extern const char ch341a_desc[]; -void ch341a_initpgm (PROGRAMMER * pgm); + extern const char ch341a_desc[]; + void ch341a_initpgm(PROGRAMMER *pgm); #ifdef __cplusplus } #endif - -#endif // ch341a_h +#endif // ch341a_h diff --git a/src/config.c b/src/config.c index 12937618b..6d04fdf4b 100644 --- a/src/config.c +++ b/src/config.c @@ -45,17 +45,17 @@ double default_bitclock; char const *default_linuxgpio; int allow_subshells; -LISTID string_list; -LISTID number_list; +LISTID string_list; +LISTID number_list; PROGRAMMER *current_prog; -AVRPART *current_part; -AVRMEM *current_mem; -int current_strct; -LISTID part_list; -LISTID programmers; -bool is_alias; - -int cfg_lineno; +AVRPART *current_part; +AVRMEM *current_mem; +int current_strct; +LISTID part_list; +LISTID programmers; +bool is_alias; + +int cfg_lineno; char *cfg_infile; extern char *yytext; @@ -106,7 +106,7 @@ Component avr_comp[] = { part_comp_desc(postdelay, COMP_INT), part_comp_desc(pollmethod, COMP_INT), - part_comp_desc(hventerstabdelay, COMP_INT), // STK500 v2 hv mode parameters + part_comp_desc(hventerstabdelay, COMP_INT), // STK500 v2 hv mode parameters part_comp_desc(progmodedelay, COMP_INT), part_comp_desc(latchcycles, COMP_INT), part_comp_desc(togglevtg, COMP_INT), @@ -149,8 +149,8 @@ Component avr_comp[] = { mem_comp_desc(min_write_delay, COMP_INT), mem_comp_desc(max_write_delay, COMP_INT), mem_comp_desc(pwroff_after_write, COMP_INT), - {"readback_p1", COMP_AVRMEM, offsetof(AVRMEM, readback)+0, 1, COMP_CHAR }, - {"readback_p2", COMP_AVRMEM, offsetof(AVRMEM, readback)+1, 1, COMP_CHAR }, + {"readback_p1", COMP_AVRMEM, offsetof(AVRMEM, readback) + 0, 1, COMP_CHAR}, + {"readback_p2", COMP_AVRMEM, offsetof(AVRMEM, readback) + 1, 1, COMP_CHAR}, mem_comp_desc(mode, COMP_INT), mem_comp_desc(delay, COMP_INT), mem_comp_desc(pollindex, COMP_INT), @@ -160,36 +160,34 @@ Component avr_comp[] = { #define DEBUG 0 -void cleanup_config(void) -{ - ldestroy_cb(part_list, (void(*)(void*)) avr_free_part); - ldestroy_cb(programmers, (void(*)(void*)) pgm_free); - ldestroy_cb(string_list, (void(*)(void*)) free_token); - ldestroy_cb(number_list, (void(*)(void*)) free_token); +void cleanup_config(void) { + ldestroy_cb(part_list, (void (*)(void *)) avr_free_part); + ldestroy_cb(programmers, (void (*)(void *)) pgm_free); + ldestroy_cb(string_list, (void (*)(void *)) free_token); + ldestroy_cb(number_list, (void (*)(void *)) free_token); } -int init_config(void) -{ - string_list = lcreat(NULL, 0); - number_list = lcreat(NULL, 0); +int init_config(void) { + string_list = lcreat(NULL, 0); + number_list = lcreat(NULL, 0); current_prog = NULL; current_part = NULL; - current_mem = NULL; - part_list = lcreat(NULL, 0); - programmers = lcreat(NULL, 0); - is_alias = false; + current_mem = NULL; + part_list = lcreat(NULL, 0); + programmers = lcreat(NULL, 0); + is_alias = false; - cfg_lineno = 1; - cfg_infile = NULL; + cfg_lineno = 1; + cfg_infile = NULL; return 0; } void *cfg_malloc(const char *funcname, size_t n) { void *ret = malloc(n); + if(!ret) { - pmsg_error("out of memory in %s() for malloc(); needed %lu bytes\n", - funcname, (unsigned long) n); + pmsg_error("out of memory in %s() for malloc(); needed %lu bytes\n", funcname, (unsigned long) n); exit(1); } memset(ret, 0, n); @@ -198,17 +196,17 @@ void *cfg_malloc(const char *funcname, size_t n) { void *cfg_realloc(const char *funcname, void *p, size_t n) { void *ret; + if(!(ret = p? realloc(p, n): calloc(1, n))) { - pmsg_error("out of memory in %s() for %salloc(); needed %lu bytes\n", - funcname, p? "re": "c", (unsigned long) n); + pmsg_error("out of memory in %s() for %salloc(); needed %lu bytes\n", funcname, p? "re": "c", (unsigned long) n); exit(1); } return ret; } - char *cfg_strdup(const char *funcname, const char *s) { char *ret = strdup(s); + if(!ret) { pmsg_error("out of memory in %s() for strdup()\n", funcname); exit(1); @@ -216,18 +214,14 @@ char *cfg_strdup(const char *funcname, const char *s) { return ret; } - void mmt_f_free(void *ptr) { mmt_free(ptr); } - -int yywrap() -{ +int yywrap() { return 1; } - int yyerror(char *errmsg, ...) { va_list args; @@ -243,7 +237,6 @@ int yyerror(char *errmsg, ...) { return 0; } - int yywarning(char *errmsg, ...) { va_list args; @@ -259,47 +252,44 @@ int yywarning(char *errmsg, ...) { return 0; } - TOKEN *new_token(int primary) { TOKEN *tkn = (TOKEN *) mmt_malloc(sizeof(TOKEN)); + tkn->primary = primary; return tkn; } - void free_token(TOKEN *tkn) { - if (tkn) { - switch (tkn->value.type) { - case V_STR: - if (tkn->value.string) - mmt_free(tkn->value.string); - tkn->value.string = NULL; - break; + if(tkn) { + switch(tkn->value.type) { + case V_STR: + if(tkn->value.string) + mmt_free(tkn->value.string); + tkn->value.string = NULL; + break; } mmt_free(tkn); } } - -void free_tokens(int n, ...) -{ +void free_tokens(int n, ...) { TOKEN *t; va_list ap; va_start(ap, n); - while (n--) { + while(n--) { t = va_arg(ap, TOKEN *); free_token(t); } va_end(ap); } - TOKEN *new_number(const char *text) { const char *errstr; TOKEN *tkn = new_token(TKN_NUMBER); - tkn->value.type = V_NUM; + + tkn->value.type = V_NUM; tkn->value.number = str_int(text, STR_INT32, &errstr); if(errstr) { yyerror("integer %s in config file: %s", text, errstr); @@ -317,7 +307,8 @@ TOKEN *new_number(const char *text) { TOKEN *new_number_real(const char *text) { char *endptr; TOKEN *tkn = new_token(TKN_NUMBER); - tkn->value.type = V_NUM_REAL; + + tkn->value.type = V_NUM_REAL; tkn->value.number_real = strtod(text, &endptr); if(endptr == text || *endptr) { yyerror("real number in config file %s: parsing error", text); @@ -358,9 +349,7 @@ TOKEN *new_constant(const char *con) { str_eq(con, "HAS_FOSC_ADJ")? HAS_FOSC_ADJ: str_eq(con, "HAS_VAREF_ADJ")? HAS_VAREF_ADJ: str_eq(con, "pseudo")? 2: - str_eq(con, "yes") || str_eq(con, "true")? 1: - str_eq(con, "no") || str_eq(con, "false")? 0: - (assigned = 0); + str_eq(con, "yes") || str_eq(con, "true")? 1: str_eq(con, "no") || str_eq(con, "false")? 0: (assigned = 0); if(!assigned) { yyerror("can't identify constant %s", con); @@ -377,7 +366,8 @@ TOKEN *new_constant(const char *con) { TOKEN *new_string(const char *text) { TOKEN *tkn = new_token(TKN_STRING); - tkn->value.type = V_STR; + + tkn->value.type = V_STR; tkn->value.string = mmt_strdup(text); #if DEBUG @@ -387,49 +377,46 @@ TOKEN *new_string(const char *text) { return tkn; } - TOKEN *new_keyword(int primary) { return new_token(primary); } - void print_token(TOKEN *tkn) { - if (!tkn) + if(!tkn) return; msg_info("token = %d = ", tkn->primary); - switch (tkn->value.type) { - case V_NUM: - msg_info("NUMBER, value=%d", tkn->value.number); - break; + switch(tkn->value.type) { + case V_NUM: + msg_info("NUMBER, value=%d", tkn->value.number); + break; - case V_NUM_REAL: - msg_info("NUMBER, value=%g", tkn->value.number_real); - break; + case V_NUM_REAL: + msg_info("NUMBER, value=%g", tkn->value.number_real); + break; - case V_STR: - msg_info("STRING, value=%s", tkn->value.string); - break; + case V_STR: + msg_info("STRING, value=%s", tkn->value.string); + break; - default: - msg_info(""); - break; + default: + msg_info(""); + break; } msg_info("\n"); } +void pyytext(void) { -void pyytext(void) -{ #if DEBUG msg_notice("TOKEN: %s\n", yytext); #endif } - #ifdef HAVE_YYLEX_DESTROY -/* reset lexer and free any allocated memory */ + +// Reset lexer and free any allocated memory extern int yylex_destroy(void); #endif @@ -443,7 +430,7 @@ int read_config(const char *file) { } f = fopen(cfg_infile, "r"); - if (f == NULL) { + if(f == NULL) { pmsg_ext_error("cannot open config file %s: %s\n", cfg_infile, strerror(errno)); mmt_free(cfg_infile); cfg_infile = NULL; @@ -451,12 +438,12 @@ int read_config(const char *file) { } cfg_lineno = 1; - yyin = f; + yyin = f; r = yyparse(); #ifdef HAVE_YYLEX_DESTROY - /* reset lexer and free any allocated memory */ + // Reset lexer and free any allocated memory yylex_destroy(); #endif @@ -470,7 +457,6 @@ int read_config(const char *file) { return r; } - // Adapted version of a neat empirical hash function from comp.lang.c by Daniel Bernstein unsigned strhash(const char *str) { unsigned c, hash = 5381, n = 0; @@ -481,7 +467,6 @@ unsigned strhash(const char *str) { return hash; } - // Return a copy of the argument as hashed string const char *cache_string(const char *p) { int h, k; @@ -490,27 +475,27 @@ const char *cache_string(const char *p) { if(!p) p = "(NULL)"; - h = strhash(p) % (sizeof cx->cfg_hstrings/sizeof*cx->cfg_hstrings); - if(!(hs=cx->cfg_hstrings[h])) - hs = cx->cfg_hstrings[h] = (char **) mmt_realloc(NULL, (16+1)*sizeof**cx->cfg_hstrings); + h = strhash(p)%(sizeof cx->cfg_hstrings/sizeof *cx->cfg_hstrings); + if(!(hs = cx->cfg_hstrings[h])) + hs = cx->cfg_hstrings[h] = (char **) mmt_realloc(NULL, (16 + 1)*sizeof **cx->cfg_hstrings); - for(k=0; hs[k]; k++) + for(k = 0; hs[k]; k++) if(*p == *hs[k] && str_eq(p, hs[k])) return hs[k]; if(k && k%16 == 0) - cx->cfg_hstrings[h] = (char **) mmt_realloc(cx->cfg_hstrings[h], (k+16+1)*sizeof**cx->cfg_hstrings); + cx->cfg_hstrings[h] = (char **) mmt_realloc(cx->cfg_hstrings[h], (k + 16 + 1)*sizeof **cx->cfg_hstrings); - cx->cfg_hstrings[h][k+1] = NULL; + cx->cfg_hstrings[h][k + 1] = NULL; return cx->cfg_hstrings[h][k] = mmt_strdup(p); } - COMMENT *locate_comment(const LISTID comments, const char *where, int rhs) { if(comments) - for(LNODEID ln=lfirst(comments); ln; ln=lnext(ln)) { + for(LNODEID ln = lfirst(comments); ln; ln = lnext(ln)) { COMMENT *n = ldata(ln); + if(n && rhs == n->rhs && n->kw && str_eq(where, n->kw)) return n; } @@ -521,6 +506,7 @@ COMMENT *locate_comment(const LISTID comments, const char *where, int rhs) { static void addcomment(int rhs) { if(cx->cfg_lkw) { COMMENT *node = mmt_malloc(sizeof(*node)); + node->rhs = rhs; node->kw = mmt_strdup(cx->cfg_lkw); node->comms = cx->cfg_comms; @@ -578,6 +564,7 @@ LISTID cfg_move_comments(void) { capture_lvalue_kw(";", -1); LISTID ret = cx->cfg_strctcomms; + cx->cfg_strctcomms = NULL; return ret; } @@ -606,8 +593,8 @@ static unsigned int tohex(const unsigned char *s, unsigned int n) { /* * Create a utf-8 character sequence from a single unicode character. - * Permissive for some invalid unicode sequences but not for those with - * high bit set). Returns numbers of characters written (0-6). + * Permissive for some invalid unicode sequences but not for those with high + * bit set). Returns numbers of characters written (0-6). */ static int wc_to_utf8str(unsigned int wc, unsigned char *str) { if(!(wc & ~0x7fu)) { @@ -658,13 +645,15 @@ unsigned char *cfg_unescapeu(unsigned char *d, const unsigned char *s) { int n, k; while(*s) { - switch (*s) { + switch(*s) { case '\\': - switch (*++s) { - case '\n': // String continuation over new line + switch(*++s) { + case '\n': // String continuation over new line + #if '\n' != '\r' case '\r': #endif + --d; break; case 'n': @@ -679,7 +668,7 @@ unsigned char *cfg_unescapeu(unsigned char *d, const unsigned char *s) { case 'b': *d = '\b'; break; - case 'e': // Non-standard ESC + case 'e': // Non-standard ESC *d = 27; break; case 'f': @@ -713,13 +702,13 @@ unsigned char *cfg_unescapeu(unsigned char *d, const unsigned char *s) { case '4': case '5': case '6': - case '7': // 1-3 octal digits + case '7': // 1-3 octal digits n = *s - '0'; - for(k = 0; k < 2 && s[1] >= '0' && s[1] <= '7'; k++) // Max 2 more octal characters + for(k = 0; k < 2 && s[1] >= '0' && s[1] <= '7'; k++) // Max 2 more octal characters n *= 8, n += s[1] - '0', s++; *d = n; break; - case 'x': // Unlimited hex digits + case 'x': // Unlimited hex digits for(k = 0; isxdigit(s[k + 1]); k++) continue; if(k > 0) { @@ -730,9 +719,10 @@ unsigned char *cfg_unescapeu(unsigned char *d, const unsigned char *s) { *d = 'x'; } break; - case 'u': // Exactly 4 hex digits and valid unicode + case 'u': // Exactly 4 hex digits and valid unicode if(isxdigit(s[1]) && isxdigit(s[2]) && isxdigit(s[3]) && isxdigit(s[4]) && - (n = wc_to_utf8str(tohex(s+1, 4), d))) { + (n = wc_to_utf8str(tohex(s + 1, 4), d))) { + d += n - 1; s += 4; } else { // Invalid \u sequence? copy \u @@ -740,9 +730,9 @@ unsigned char *cfg_unescapeu(unsigned char *d, const unsigned char *s) { *d = 'u'; } break; - case 'U': // Exactly 6 hex digits and valid unicode + case 'U': // Exactly 6 hex digits and valid unicode if(isxdigit(s[1]) && isxdigit(s[2]) && isxdigit(s[3]) && isxdigit(s[4]) && isxdigit(s[5]) && isxdigit(s[6]) && - (n = wc_to_utf8str(tohex(s+1, 6), d))) { + (n = wc_to_utf8str(tohex(s + 1, 6), d))) { d += n - 1; s += 6; } else { // Invalid \U sequence? copy \U @@ -750,13 +740,13 @@ unsigned char *cfg_unescapeu(unsigned char *d, const unsigned char *s) { *d = 'U'; } break; - default: // Keep the escape sequence (C would warn and remove \) + default: // Keep the escape sequence (C would warn and remove \) *d++ = '\\'; *d = *s; } break; - default: // Not an escape sequence: just copy the character + default: // Not an escape sequence: just copy the character *d = *s; } d++; @@ -789,7 +779,6 @@ static int utf8width(wint_t wc) { return 0; } - // Given the first byte c of a character sequence, how long is the sequence going to be? static int utf8headlen(int c) { return (c & 0xe0) == 0xc0? 2: @@ -798,9 +787,9 @@ static int utf8headlen(int c) { } /* - * Return the next unicode character from a utf-8 string str with at least - * n characters and record the length of the utf-8 string eaten in *lenp - * Returns U+FFFD (illegal char) if parsing does not go well + * Return the next unicode character from a utf-8 string str with at least n + * characters and record the length of the utf-8 string eaten in *lenp. Returns + * U+FFFD (illegal char) if parsing does not go well */ static wint_t nextutf8char(const char *str, int n, int *lenp) { @@ -817,7 +806,7 @@ static wint_t nextutf8char(const char *str, int n, int *lenp) { utf8 = 0; // Possible UTF-8 character, convert to wint_t len = utf8headlen((int) c); if(len > 1 && len <= n) { - switch (len) { + switch(len) { case 2: wc = c & 0x1f; break; @@ -842,7 +831,7 @@ static wint_t nextutf8char(const char *str, int n, int *lenp) { wc = (wc << 6) + (str[j] & 0x3f); } } - if(utf8 && utf8width(wc) != len) // Sequence code was longer than needed be, make invalid + if(utf8 && utf8width(wc) != len) // Sequence code was longer than needed be, make invalid utf8 = 0; if(!utf8) @@ -859,38 +848,49 @@ char *cfg_escape(const char *s) { char buf[50*1024], *d = buf; *d++ = '"'; - for(; *s && d-buf < (long) sizeof buf - 10; s++) { + for(; *s && d - buf < (long) sizeof buf - 10; s++) { switch(*s) { case '\n': - *d++ = '\\'; *d++ = 'n'; + *d++ = '\\'; + *d++ = 'n'; break; case '\t': - *d++ = '\\'; *d++ = 't'; + *d++ = '\\'; + *d++ = 't'; break; case '\a': - *d++ = '\\'; *d++ = 'a'; + *d++ = '\\'; + *d++ = 'a'; break; case '\b': - *d++ = '\\'; *d++ = 'b'; + *d++ = '\\'; + *d++ = 'b'; break; case '\f': - *d++ = '\\'; *d++ = 'f'; + *d++ = '\\'; + *d++ = 'f'; break; + #if '\r' != '\n' case '\r': - *d++ = '\\'; *d++ = 'r'; + *d++ = '\\'; + *d++ = 'r'; break; #endif + case '\v': - *d++ = '\\'; *d++ = 'v'; + *d++ = '\\'; + *d++ = 'v'; break; case '\"': - *d++ = '\\'; *d++ = '\"'; + *d++ = '\\'; + *d++ = '\"'; break; default: if(*s & 0x80) { // Check for utf8-sequences int chrlen; - if(0xFFFD == nextutf8char(s, strlen(s), &chrlen)) { // Invalid UTF-8 + + if(0xFFFD == nextutf8char(s, strlen(s), &chrlen)) { // Invalid UTF-8 sprintf(d, "\\%03o", *s & 0xff); d += strlen(d); } else { // Copy over valid UTF-8 character @@ -911,7 +911,6 @@ char *cfg_escape(const char *s) { return mmt_strdup(buf); } - static int cmp_comp(const void *v1, const void *v2) { const Component *c1 = v1, *c2 = v2; int ret = strcmp(c1->name, c2->name); @@ -923,53 +922,71 @@ Component *cfg_comp_search(const char *name, int strct) { Component key; if(!cx->cfg_init_search++) - qsort(avr_comp, sizeof avr_comp/sizeof*avr_comp, sizeof(Component), cmp_comp); + qsort(avr_comp, sizeof avr_comp/sizeof *avr_comp, sizeof(Component), cmp_comp); key.name = name; key.strct = strct; - return bsearch(&key, avr_comp, sizeof avr_comp/sizeof*avr_comp, sizeof(Component), cmp_comp); + return bsearch(&key, avr_comp, sizeof avr_comp/sizeof *avr_comp, sizeof(Component), cmp_comp); } - const char *cfg_strct_name(int strct) { switch(strct) { - case COMP_CONFIG_MAIN: return "avrdude.conf main"; - case COMP_AVRPART: return "AVRPART"; - case COMP_AVRMEM: return "AVRMEM"; - case COMP_PROGRAMMER: return "PROGRAMMER"; + case COMP_CONFIG_MAIN: + return "avrdude.conf main"; + case COMP_AVRPART: + return "AVRPART"; + case COMP_AVRMEM: + return "AVRMEM"; + case COMP_PROGRAMMER: + return "PROGRAMMER"; } return "unknown struct"; } const char *cfg_v_type(int type) { switch(type) { - case V_NONE: return "void"; - case V_NUM: return "number"; - case V_NUM_REAL: return "real"; - case V_STR: return "string"; - case V_COMPONENT: return "component"; + case V_NONE: + return "void"; + case V_NUM: + return "number"; + case V_NUM_REAL: + return "real"; + case V_STR: + return "string"; + case V_COMPONENT: + return "component"; } return "unknown v type"; } const char *cfg_comp_type(int type) { switch(type) { - case COMP_INT: return "number"; - case COMP_SHORT: return "short"; - case COMP_CHAR: return "char"; - case COMP_BOOL: return "bool"; - case COMP_STRING: return "string"; - case COMP_CHAR_ARRAY: return "byte array"; - case COMP_INT_LISTID: return "number list"; - case COMP_STRING_LISTID: return "string list"; - case COMP_OPCODE: return "opcode"; - case COMP_PIN: return "pin"; - case COMP_PIN_LIST: return "pin list"; + case COMP_INT: + return "number"; + case COMP_SHORT: + return "short"; + case COMP_CHAR: + return "char"; + case COMP_BOOL: + return "bool"; + case COMP_STRING: + return "string"; + case COMP_CHAR_ARRAY: + return "byte array"; + case COMP_INT_LISTID: + return "number list"; + case COMP_STRING_LISTID: + return "string list"; + case COMP_OPCODE: + return "opcode"; + case COMP_PIN: + return "pin"; + case COMP_PIN_LIST: + return "pin list"; } return "unknown comp type"; } - // Used by config_gram.y to assign a component in one of the relevant structures with a value void cfg_assign(char *sp, int strct, Component *cp, VALUE *v) { const char *str; @@ -987,7 +1004,7 @@ void cfg_assign(char *sp, int strct, Component *cp, VALUE *v) { } // TODO: consider endianness (code currently assumes little endian) num = v->number; - memcpy(sp+cp->offset, &num, cp->size); + memcpy(sp + cp->offset, &num, cp->size); break; case COMP_STRING: if(v->type != V_STR) { @@ -996,9 +1013,9 @@ void cfg_assign(char *sp, int strct, Component *cp, VALUE *v) { return; } str = cache_string(v->string); - memcpy(sp+cp->offset, &str, cp->size); + memcpy(sp + cp->offset, &str, cp->size); break; - // TODO: implement COMP_CHAR_ARRAY, COMP_INT_LISTID, COMP_STRING_LISTID, ... + // TODO: implement COMP_CHAR_ARRAY, COMP_INT_LISTID, COMP_STRING_LISTID, ... default: yywarning("%s in %s expects a %s but that is not implemented", cp->name, cfg_strct_name(strct), cfg_comp_type(cp->type)); @@ -1016,11 +1033,11 @@ void cfg_update_mcuid(AVRPART *part) { return; // Don't assign an mcuid for 32-bit AVR parts - if(part->prog_modes & PM_aWire) + if(is_awire(part)) return; // Find an entry that shares the same name, overwrite mcuid with known, existing mcuid - for(size_t i=0; i < sizeof uP_table/sizeof *uP_table; i++) { + for(size_t i = 0; i < sizeof uP_table/sizeof *uP_table; i++) { if(str_caseeq(part->desc, uP_table[i].name)) { if(part->mcuid != (int) uP_table[i].mcuid) { if(part->mcuid >= 0 && verbose >= MSG_DEBUG) @@ -1032,24 +1049,24 @@ void cfg_update_mcuid(AVRPART *part) { } // None have the same name: an entry with part->mcuid might be an error - for(size_t i=0; i < sizeof uP_table/sizeof *uP_table; i++) + for(size_t i = 0; i < sizeof uP_table/sizeof *uP_table; i++) if(part->mcuid == (int) uP_table[i].mcuid) { // Complain unless it can be considered a variant, eg, ATmega32L and ATmega32 AVRMEM *flash = avr_locate_flash(part); + if(flash) { size_t l1 = strlen(part->desc), l2 = strlen(uP_table[i].name); + if(strncasecmp(part->desc, uP_table[i].name, l1 < l2? l1: l2) || - flash->size != uP_table[i].flashsize || - flash->page_size != uP_table[i].pagesize || - part->n_interrupts != (int8_t) uP_table[i].ninterrupts) + flash->size != uP_table[i].flashsize || + flash->page_size != uP_table[i].pagesize || part->n_interrupts != (int8_t) uP_table[i].ninterrupts) yywarning("mcuid %d is reserved for %s, use a free number >= %d", part->mcuid, uP_table[i].name, sizeof uP_table/sizeof *uP_table); } return; } - // Range check if(part->mcuid < 0 || part->mcuid >= UB_N_MCU) yywarning("mcuid %d for %s is out of range [0..%d], use a free number >= %d", - part->mcuid, part->desc, UB_N_MCU-1, sizeof uP_table/sizeof *uP_table); + part->mcuid, part->desc, UB_N_MCU - 1, sizeof uP_table/sizeof *uP_table); } diff --git a/src/config.h b/src/config.h index e91ca5bc1..80ae37d1f 100644 --- a/src/config.h +++ b/src/config.h @@ -16,7 +16,7 @@ * along with this program. If not, see . */ -/* These are the internal definitions needed for config parsing */ +// These are the internal definitions needed for config parsing #ifndef config_h #define config_h @@ -24,17 +24,15 @@ #include "libavrdude.h" #if defined(WIN32) || defined(_MSC_VER) || defined(__MINGW32__) -#define realpath(N,R) _fullpath((R), (N), PATH_MAX) +#define realpath(N, R) _fullpath((R), (N), PATH_MAX) #endif - typedef struct { char *kw; // Keyword near the comments LISTID comms; // Chained list of comments int rhs; // Comments to print rhs of keyword line } COMMENT; - enum { // Which structures a component can occur in COMP_CONFIG_MAIN, COMP_PROGRAMMER, @@ -62,7 +60,6 @@ typedef struct { // Description of a component in a structure int offset, size, type; // Location, size and type within structure } Component; - enum { // Value types for VALUE struct V_NONE, V_NUM, @@ -74,94 +71,91 @@ enum { // Value types for VALUE struct typedef struct { int type; union { - int number; - double number_real; - char *string; + int number; + double number_real; + char *string; Component *comp; }; } VALUE; - typedef struct token { int primary; VALUE value; } TOKEN; typedef struct token *token_p; - -extern FILE *yyin; +extern FILE *yyin; extern PROGRAMMER *current_prog; -extern AVRPART *current_part; -extern AVRMEM *current_mem; -extern int current_strct; -extern int cfg_lineno; -extern char *cfg_infile; -extern LISTID string_list; -extern LISTID number_list; -extern bool is_alias; // current entry is alias - +extern AVRPART *current_part; +extern AVRMEM *current_mem; +extern int current_strct; +extern int cfg_lineno; +extern char *cfg_infile; +extern LISTID string_list; +extern LISTID number_list; +extern bool is_alias; // Current entry is alias #if !defined(HAS_YYSTYPE) #define YYSTYPE token_p #endif + extern YYSTYPE yylval; #ifdef __cplusplus extern "C" { #endif -int yyparse(void); + int yyparse(void); -int yyerror(char *errmsg, ...); + int yyerror(char *errmsg, ...); -int yywarning(char *errmsg, ...); + int yywarning(char *errmsg, ...); -TOKEN *new_token(int primary); + TOKEN *new_token(int primary); -void free_token(TOKEN *tkn); + void free_token(TOKEN *tkn); -void free_tokens(int n, ...); + void free_tokens(int n, ...); -TOKEN *new_number(const char *text); + TOKEN *new_number(const char *text); -TOKEN *new_number_real(const char *text); + TOKEN *new_number_real(const char *text); -TOKEN *new_constant(const char *text); + TOKEN *new_constant(const char *text); -TOKEN *new_string(const char *text); + TOKEN *new_string(const char *text); -TOKEN *new_keyword(int primary); + TOKEN *new_keyword(int primary); -void print_token(TOKEN *tkn); + void print_token(TOKEN *tkn); -void pyytext(void); + void pyytext(void); -COMMENT *locate_comment(const LISTID comments, const char *where, int rhs); + COMMENT *locate_comment(const LISTID comments, const char *where, int rhs); -void cfg_capture_prologue(void); + void cfg_capture_prologue(void); -LISTID cfg_get_prologue(void); + LISTID cfg_get_prologue(void); -void capture_comment_str(const char *com, int lineno); + void capture_comment_str(const char *com, int lineno); -void capture_lvalue_kw(const char *kw, int lineno); + void capture_lvalue_kw(const char *kw, int lineno); -LISTID cfg_move_comments(void); + LISTID cfg_move_comments(void); -void cfg_pop_comms(void); + void cfg_pop_comms(void); -Component *cfg_comp_search(const char *name, int strct); + Component *cfg_comp_search(const char *name, int strct); -const char *cfg_v_type(int type); + const char *cfg_v_type(int type); -const char *cfg_strct_name(int strct); + const char *cfg_strct_name(int strct); -void cfg_assign(char *sp, int strct, Component *cp, VALUE *v); + void cfg_assign(char *sp, int strct, Component *cp, VALUE *v); -void cfg_update_mcuid(AVRPART *part); + void cfg_update_mcuid(AVRPART *part); #ifdef __cplusplus } #endif - #endif diff --git a/src/config_gram.y b/src/config_gram.y index d266516f6..797796b23 100644 --- a/src/config_gram.y +++ b/src/config_gram.y @@ -33,22 +33,21 @@ #include "developer_opts.h" #if defined(WIN32) -#define strtok_r( _s, _sep, _lasts ) \ - ( *(_lasts) = strtok( (_s), (_sep) ) ) +#define strtok_r( _s, _sep, _lasts ) ( *(_lasts) = strtok( (_s), (_sep) ) ) #endif #define STRINGIFY(x) #x #define TOSTRING(x) STRINGIFY(x) int yylex(void); -int yyerror(char * errmsg, ...); -int yywarning(char * errmsg, ...); +int yyerror(char *errmsg, ...); +int yywarning(char *errmsg, ...); static int clear_pin(int pinfunc); static int assign_pin(int pinfunc, TOKEN *v, int invert); static int assign_pin_list(int invert); -static int which_opcode(TOKEN * opcode); -static int parse_cmdbits(OPCODE * op, int opnum); +static int which_opcode(TOKEN *opcode); +static int parse_cmdbits(OPCODE *op, int opnum); #define pin_name (cx->cfgy_pin_name) %} @@ -128,17 +127,17 @@ static int parse_cmdbits(OPCODE * op, int opnum); %token K_HVSP_CONTROLSTACK /* JTAG ICE mkII specific parameters */ -%token K_ALLOWFULLPAGEBITSTREAM /* - * Internal parameter for the JTAG - * ICE; describes the internal JTAG - * streaming behaviour inside the MCU. - * 1 for all older chips, 0 for newer - * MCUs. - */ -%token K_ENABLEPAGEPROGRAMMING /* ? yes for mega256*, mega406 */ -%token K_IS_AT90S1200 /* chip is an AT90S1200 (needs special treatment) */ -%token K_FLASH_INSTR /* flash instructions */ -%token K_EEPROM_INSTR /* EEPROM instructions */ + + /* + * Internal parameter for the JTAG ICE; describes the internal JTAG streaming + * behaviour inside the MCU. 1 for all older chips, 0 for newer MCUs. + */ +%token K_ALLOWFULLPAGEBITSTREAM + +%token K_ENABLEPAGEPROGRAMMING /* True for mega256*, mega406 */ +%token K_IS_AT90S1200 /* Chip is an AT90S1200 (needs special treatment) */ +%token K_FLASH_INSTR /* Flash instructions */ +%token K_EEPROM_INSTR /* EEPROM instructions */ %token TKN_COMMA %token TKN_EQUAL @@ -150,7 +149,7 @@ static int parse_cmdbits(OPCODE * op, int opnum); %token TKN_STRING %token TKN_COMPONENT -%left OP_OR /* calculator operations */ +%left OP_OR /* Calculator operations */ %left OP_XOR %left OP_AND %left OP_PLUS OP_MINUS @@ -258,12 +257,12 @@ def : prog_def : prog_decl prog_parms { - PROGRAMMER * existing_prog; - if (lsize(current_prog->id) == 0) { + PROGRAMMER *existing_prog; + if(lsize(current_prog->id) == 0) { yyerror("required parameter id not specified"); YYABORT; } - if (current_prog->initpgm == NULL && current_prog->prog_modes) { + if(current_prog->initpgm == NULL && current_prog->prog_modes) { yyerror("programmer type not specified"); YYABORT; } @@ -301,8 +300,8 @@ prog_decl : | K_PROGRAMMER K_PARENT TKN_STRING { - PROGRAMMER * pgm = locate_programmer(programmers, $3->value.string); - if (pgm == NULL) { + PROGRAMMER *pgm = locate_programmer(programmers, $3->value.string); + if(pgm == NULL) { yyerror("parent programmer %s not found", $3->value.string); free_token($3); YYABORT; @@ -321,10 +320,10 @@ part_def : part_decl part_parms { LNODEID ln; - AVRMEM * m; - AVRPART * existing_part; + AVRMEM *m; + AVRPART *existing_part; - if (current_part->id[0] == 0) { + if(current_part->id[0] == 0) { yyerror("required parameter id not specified"); YYABORT; } @@ -336,29 +335,29 @@ part_def : (!avr_locate_sigrow(current_part)? MEM_IN_SIGROW: 0)); // Sanity checks for memory sizes and compute/override num_pages entry - for (ln=lfirst(current_part->mem); ln; ln=lnext(ln)) { + for(ln=lfirst(current_part->mem); ln; ln=lnext(ln)) { m = ldata(ln); - if (m->paged) { - if (m->size <= 0) { + if(m->paged) { + if(m->size <= 0) { yyerror("must specify a positive size for paged memory %s", m->desc); YYABORT; } - if (m->page_size <= 0) { + if(m->page_size <= 0) { yyerror("must specify a positive page size for paged memory %s", m->desc); YYABORT; } // Code base relies on page_size being a power of 2 in some places - if (m->page_size & (m->page_size - 1)) { + if(m->page_size & (m->page_size - 1)) { yyerror("page size must be a power of 2 for paged memory %s", m->desc); YYABORT; } // Code base relies on size being a multiple of page_size - if (m->size % m->page_size) { + if(m->size % m->page_size) { yyerror("size must be a multiple of page size for paged memory %s", m->desc); YYABORT; } // Warn if num_pages was specified but is inconsistent with size and page size - if (m->num_pages && m->num_pages != m->size / m->page_size) + if(m->num_pages && m->num_pages != m->size / m->page_size) yywarning("overriding num_page to be %d for memory %s", m->size/m->page_size, m->desc); m->num_pages = m->size / m->page_size; @@ -380,7 +379,7 @@ part_def : } existing_part = locate_part(part_list, current_part->id); - if (existing_part) { + if(existing_part) { { /* temporarily set lineno to lineno of part start */ int temp = cfg_lineno; cfg_lineno = current_part->lineno; yywarning("part %s overwrites previous definition %s:%d.", @@ -408,8 +407,8 @@ part_decl : } | K_PART K_PARENT TKN_STRING { - AVRPART * parent_part = locate_part(part_list, $3->value.string); - if (parent_part == NULL) { + AVRPART *parent_part = locate_part(part_list, $3->value.string); + if(parent_part == NULL) { yyerror("can't find parent part"); free_token($3); YYABORT; @@ -448,7 +447,7 @@ prog_parm : } | K_ID TKN_EQUAL string_list { { - while (lsize(string_list)) { + while(lsize(string_list)) { TOKEN *t = lrmv_n(string_list, 1); ladd(current_prog->id, mmt_strdup(t->value.string)); free_token(t); @@ -473,7 +472,7 @@ prog_parm_type: prog_parm_type_id: TKN_STRING { const PROGRAMMER_TYPE *pgm_type = locate_programmer_type($1->value.string); - if (pgm_type == NULL) { + if(pgm_type == NULL) { yyerror("programmer type %s not found", $1->value.string); free_token($1); YYABORT; @@ -658,7 +657,7 @@ part_parm : K_VARIANTS TKN_EQUAL string_list { { - while (lsize(string_list)) { + while(lsize(string_list)) { TOKEN *t = lrmv_n(string_list, 1); int found = 0; for(LNODEID ln = lfirst(current_part->variants); ln; ln = lnext(ln)) { @@ -694,7 +693,7 @@ part_parm : K_PP_CONTROLSTACK TKN_EQUAL num_list { { - TOKEN * t; + TOKEN *t; unsigned nbytes; int ok; @@ -703,23 +702,18 @@ part_parm : ok = 1; memset(current_part->controlstack, 0, CTL_STACK_SIZE); - while (lsize(number_list)) { + while(lsize(number_list)) { t = lrmv_n(number_list, 1); - if (nbytes < CTL_STACK_SIZE) - { - current_part->controlstack[nbytes] = t->value.number; - nbytes++; - } - else - { - ok = 0; - } + if(nbytes < CTL_STACK_SIZE) { + current_part->controlstack[nbytes] = t->value.number; + nbytes++; + } else { + ok = 0; + } free_token(t); } - if (!ok) - { - yywarning("too many bytes in control stack"); - } + if(!ok) + yywarning("too many bytes in control stack"); } } | @@ -732,7 +726,7 @@ part_parm : K_HVSP_CONTROLSTACK TKN_EQUAL num_list { { - TOKEN * t; + TOKEN *t; unsigned nbytes; int ok; @@ -741,23 +735,18 @@ part_parm : ok = 1; memset(current_part->controlstack, 0, CTL_STACK_SIZE); - while (lsize(number_list)) { + while(lsize(number_list)) { t = lrmv_n(number_list, 1); - if (nbytes < CTL_STACK_SIZE) - { - current_part->controlstack[nbytes] = t->value.number; - nbytes++; - } - else - { - ok = 0; - } + if(nbytes < CTL_STACK_SIZE) { + current_part->controlstack[nbytes] = t->value.number; + nbytes++; + } else { + ok = 0; + } free_token(t); } - if (!ok) - { - yywarning("too many bytes in control stack"); - } + if(!ok) + yywarning("too many bytes in control stack"); } } | @@ -770,7 +759,7 @@ part_parm : K_FLASH_INSTR TKN_EQUAL num_list { { - TOKEN * t; + TOKEN *t; unsigned nbytes; int ok; @@ -778,23 +767,18 @@ part_parm : ok = 1; memset(current_part->flash_instr, 0, FLASH_INSTR_SIZE); - while (lsize(number_list)) { + while(lsize(number_list)) { t = lrmv_n(number_list, 1); - if (nbytes < FLASH_INSTR_SIZE) - { - current_part->flash_instr[nbytes] = t->value.number; - nbytes++; - } - else - { - ok = 0; - } + if(nbytes < FLASH_INSTR_SIZE) { + current_part->flash_instr[nbytes] = t->value.number; + nbytes++; + } else { + ok = 0; + } free_token(t); } - if (!ok) - { - yywarning("too many bytes in flash instructions"); - } + if(!ok) + yywarning("too many bytes in flash instructions"); } } | @@ -806,7 +790,7 @@ part_parm : K_EEPROM_INSTR TKN_EQUAL num_list { { - TOKEN * t; + TOKEN *t; unsigned nbytes; int ok; @@ -814,23 +798,18 @@ part_parm : ok = 1; memset(current_part->eeprom_instr, 0, EEPROM_INSTR_SIZE); - while (lsize(number_list)) { + while(lsize(number_list)) { t = lrmv_n(number_list, 1); - if (nbytes < EEPROM_INSTR_SIZE) - { - current_part->eeprom_instr[nbytes] = t->value.number; - nbytes++; - } - else - { - ok = 0; - } + if(nbytes < EEPROM_INSTR_SIZE) { + current_part->eeprom_instr[nbytes] = t->value.number; + nbytes++; + } else { + ok = 0; + } free_token(t); } - if (!ok) - { - yywarning("too many bytes in EEPROM instructions"); - } + if(!ok) + yywarning("too many bytes in EEPROM instructions"); } } | @@ -842,9 +821,9 @@ part_parm : K_RESET TKN_EQUAL reset_disposition { - if ($3->primary == K_DEDICATED) + if($3->primary == K_DEDICATED) current_part->reset_disposition = RESET_DEDICATED; - else if ($3->primary == K_IO) + else if($3->primary == K_IO) current_part->reset_disposition = RESET_IO; free_tokens(2, $1, $3); @@ -852,9 +831,9 @@ part_parm : K_IS_AT90S1200 TKN_EQUAL numexpr { - if ($3->value.number == 1) + if($3->value.number == 1) current_part->flags |= AVRPART_IS_AT90S1200; - else if ($3->value.number == 0) + else if($3->value.number == 0) current_part->flags &= ~AVRPART_IS_AT90S1200; else { yyerror("is_at90s1200 not a Boolean value"); @@ -867,9 +846,9 @@ part_parm : K_ALLOWFULLPAGEBITSTREAM TKN_EQUAL numexpr { - if ($3->value.number == 1) + if($3->value.number == 1) current_part->flags |= AVRPART_ALLOWFULLPAGEBITSTREAM; - else if ($3->value.number == 0) + else if($3->value.number == 0) current_part->flags &= ~AVRPART_ALLOWFULLPAGEBITSTREAM; else { yyerror("allowfullpagebitstream not a Boolean value"); @@ -882,9 +861,9 @@ part_parm : K_ENABLEPAGEPROGRAMMING TKN_EQUAL numexpr { - if ($3->value.number == 1) + if($3->value.number == 1) current_part->flags |= AVRPART_ENABLEPAGEPROGRAMMING; - else if ($3->value.number == 0) + else if($3->value.number == 0) current_part->flags &= ~AVRPART_ENABLEPAGEPROGRAMMING; else { yyerror("enablepageprogramming not a Boolean value"); @@ -897,9 +876,9 @@ part_parm : K_SERIAL TKN_EQUAL numexpr { - if ($3->value.number == 1) + if($3->value.number == 1) current_part->flags |= AVRPART_SERIALOK; - else if ($3->value.number == 0) + else if($3->value.number == 0) current_part->flags &= ~AVRPART_SERIALOK; else { yyerror("serial not a Boolean value"); @@ -912,15 +891,15 @@ part_parm : K_PARALLEL TKN_EQUAL numexpr { - if ($3->value.number == 1) { + if($3->value.number == 1) { current_part->flags |= AVRPART_PARALLELOK; current_part->flags &= ~AVRPART_PSEUDOPARALLEL; } - else if ($3->value.number == 0) { + else if($3->value.number == 0) { current_part->flags &= ~AVRPART_PARALLELOK; current_part->flags &= ~AVRPART_PSEUDOPARALLEL; } - else if ($3->value.number == 2) { + else if($3->value.number == 2) { current_part->flags |= AVRPART_PARALLELOK; current_part->flags |= AVRPART_PSEUDOPARALLEL; } @@ -936,13 +915,13 @@ part_parm : K_RETRY_PULSE TKN_EQUAL retry_lines { - switch ($3->primary) { - case K_RESET : - current_part->retry_pulse = PIN_AVR_RESET; - break; - case K_SCK : - current_part->retry_pulse = PIN_AVR_SCK; - break; + switch($3->primary) { + case K_RESET : + current_part->retry_pulse = PIN_AVR_RESET; + break; + case K_SCK : + current_part->retry_pulse = PIN_AVR_SCK; + break; } free_token($1); @@ -963,7 +942,7 @@ part_parm : } mem_specs { - if (is_alias) { // alias mem has been already entered + if(is_alias) { // alias mem has been already entered lrmv_d(current_part->mem, current_mem); avr_free_mem(current_mem); is_alias = false; @@ -986,7 +965,7 @@ part_parm : K_MEMORY TKN_STRING TKN_EQUAL K_NULL { AVRMEM *existing_mem = avr_locate_mem_noalias(current_part, $2->value.string); - if (existing_mem != NULL) { + if(existing_mem != NULL) { lrmv_d(current_part->mem, existing_mem); avr_free_mem(existing_mem); } @@ -998,14 +977,15 @@ part_parm : opcode TKN_EQUAL string_list { { int opnum; - OPCODE * op; + OPCODE *op; opnum = which_opcode($1); - if (opnum < 0) YYABORT; + if(opnum < 0) + YYABORT; op = avr_new_opcode(); if(0 != parse_cmdbits(op, opnum)) YYABORT; - if (current_part->op[opnum] != NULL) { + if(current_part->op[opnum] != NULL) { /*yywarning("operation redefined");*/ avr_free_opcode(current_part->op[opnum]); } @@ -1043,17 +1023,17 @@ mem_spec : free_token($1); } | - K_PAGE_SIZE TKN_EQUAL numexpr + K_PAGE_SIZE TKN_EQUAL numexpr { int ps = $3->value.number; - if (ps <= 0) + if(ps <= 0) pmsg_warning("invalid page size %d, ignored [%s:%d]\n", ps, cfg_infile, cfg_lineno); else current_mem->page_size = ps; free_token($3); } | - K_READBACK TKN_EQUAL TKN_NUMBER TKN_NUMBER + K_READBACK TKN_EQUAL TKN_NUMBER TKN_NUMBER { current_mem->readback[0] = $3->value.number; current_mem->readback[1] = $4->value.number; @@ -1064,14 +1044,14 @@ mem_spec : opcode TKN_EQUAL string_list { { int opnum; - OPCODE * op; + OPCODE *op; opnum = which_opcode($1); - if (opnum < 0) YYABORT; + if(opnum < 0) YYABORT; op = avr_new_opcode(); if(0 != parse_cmdbits(op, opnum)) YYABORT; - if (current_mem->op[opnum] != NULL) { + if(current_mem->op[opnum] != NULL) { /*yywarning("operation redefined");*/ avr_free_opcode(current_mem->op[opnum]); } @@ -1098,19 +1078,18 @@ mem_spec : mem_alias : K_ALIAS TKN_STRING { - AVRMEM * existing_mem; + AVRMEM *existing_mem; existing_mem = avr_locate_mem(current_part, $2->value.string); - if (existing_mem == NULL) { - yyerror("%s alias to non-existent memory %s", - current_mem->desc, $2->value.string); + if(existing_mem == NULL) { + yyerror("%s alias to non-existent memory %s", current_mem->desc, $2->value.string); free_token($2); YYABORT; } // if this alias does already exist, drop the old one - AVRMEM_ALIAS * alias = avr_locate_memalias(current_part, current_mem->desc); - if (alias) { + AVRMEM_ALIAS *alias = avr_locate_memalias(current_part, current_mem->desc); + if(alias) { lrmv_d(current_part->mem_alias, alias); avr_free_memalias(alias); } @@ -1128,14 +1107,13 @@ mem_alias : %% #if 0 -static char * vtypestr(int type) -{ - switch (type) { - case V_NUM : return "INTEGER"; - case V_NUM_REAL: return "REAL"; - case V_STR : return "STRING"; - default: - return ""; +static char *vtypestr(int type) { + switch(type) { + case V_NUM : return "INTEGER"; + case V_NUM_REAL: return "REAL"; + case V_STR : return "STRING"; + default: + return ""; } } #endif @@ -1161,7 +1139,7 @@ static int assign_pin(int pinfunc, TOKEN *v, int invert) { int value = v->value.number; free_token(v); - if ((value < PIN_MIN) || (value > PIN_MAX)) { + if((value < PIN_MIN) || (value > PIN_MAX)) { yyerror("pin must be in the range " TOSTRING(PIN_MIN) "-" TOSTRING(PIN_MAX)); return -1; } @@ -1171,9 +1149,8 @@ static int assign_pin(int pinfunc, TOKEN *v, int invert) { return 0; } -static int assign_pin_list(int invert) -{ - TOKEN * t; +static int assign_pin_list(int invert) { + TOKEN *t; int pin; int rv = 0; @@ -1183,14 +1160,14 @@ static int assign_pin_list(int invert) } current_prog->pinno[pin_name] = NO_PIN; - while (lsize(number_list)) { + while(lsize(number_list)) { t = lrmv_n(number_list, 1); if (rv == 0) { pin = t->value.number; if ((pin < PIN_MIN) || (pin > PIN_MAX)) { yyerror("pin must be in the range " TOSTRING(PIN_MIN) "-" TOSTRING(PIN_MAX)); rv = -1; - /* loop clears list and frees tokens */ + /* loop clears list and frees tokens */ } pin_set_value(&(current_prog->pin[pin_name]), pin, invert); } @@ -1199,31 +1176,28 @@ static int assign_pin_list(int invert) return rv; } -static int which_opcode(TOKEN * opcode) -{ - switch (opcode->primary) { - case K_READ : return AVR_OP_READ; break; - case K_WRITE : return AVR_OP_WRITE; break; - case K_READ_LO : return AVR_OP_READ_LO; break; - case K_READ_HI : return AVR_OP_READ_HI; break; - case K_WRITE_LO : return AVR_OP_WRITE_LO; break; - case K_WRITE_HI : return AVR_OP_WRITE_HI; break; - case K_LOADPAGE_LO : return AVR_OP_LOADPAGE_LO; break; - case K_LOADPAGE_HI : return AVR_OP_LOADPAGE_HI; break; - case K_LOAD_EXT_ADDR : return AVR_OP_LOAD_EXT_ADDR; break; - case K_WRITEPAGE : return AVR_OP_WRITEPAGE; break; - case K_CHIP_ERASE : return AVR_OP_CHIP_ERASE; break; - case K_PGM_ENABLE : return AVR_OP_PGM_ENABLE; break; - default : - yyerror("invalid opcode"); - return -1; - break; +static int which_opcode(TOKEN *opcode) { + switch(opcode->primary) { + case K_READ: return AVR_OP_READ; + case K_WRITE: return AVR_OP_WRITE; + case K_READ_LO: return AVR_OP_READ_LO; + case K_READ_HI: return AVR_OP_READ_HI; + case K_WRITE_LO: return AVR_OP_WRITE_LO; + case K_WRITE_HI: return AVR_OP_WRITE_HI; + case K_LOADPAGE_LO: return AVR_OP_LOADPAGE_LO; + case K_LOADPAGE_HI: return AVR_OP_LOADPAGE_HI; + case K_LOAD_EXT_ADDR: return AVR_OP_LOAD_EXT_ADDR; + case K_WRITEPAGE: return AVR_OP_WRITEPAGE; + case K_CHIP_ERASE: return AVR_OP_CHIP_ERASE; + case K_PGM_ENABLE: return AVR_OP_PGM_ENABLE; + default: + yyerror("invalid opcode"); + return -1; } } -static int parse_cmdbits(OPCODE * op, int opnum) -{ +static int parse_cmdbits(OPCODE *op, int opnum) { TOKEN *t; int bitno; int len; @@ -1231,7 +1205,7 @@ static int parse_cmdbits(OPCODE * op, int opnum) int rv = 0; bitno = 32; - while (lsize(string_list)) { + while(lsize(string_list)) { t = lrmv_n(string_list, 1); @@ -1242,12 +1216,12 @@ static int parse_cmdbits(OPCODE * op, int opnum) bit[0] = *cc++; s = !compact? strtok_r(str, " ", &brkt): *bit? bit: NULL; - while (rv == 0 && s != NULL) { + while(rv == 0 && s != NULL) { // Ignore visual grouping characters in compact mode if(*s != '.' && *s != '-' && *s != '_' && *s !='/') bitno--; - if (bitno < 0) { + if(bitno < 0) { yyerror("too many opcode bits for instruction"); rv = -1; break; @@ -1255,56 +1229,56 @@ static int parse_cmdbits(OPCODE * op, int opnum) len = strlen(s); - if (len == 0) { + if(len == 0) { yyerror("invalid bit specifier \"\""); rv = -1; break; } - if (len == 1) { - switch (*s) { - case '1': - op->bit[bitno].type = AVR_CMDBIT_VALUE; - op->bit[bitno].value = 1; - op->bit[bitno].bitno = bitno % 8; - break; - case '0': - op->bit[bitno].type = AVR_CMDBIT_VALUE; - op->bit[bitno].value = 0; - op->bit[bitno].bitno = bitno % 8; - break; - case 'x': - op->bit[bitno].type = AVR_CMDBIT_IGNORE; - op->bit[bitno].value = 0; - op->bit[bitno].bitno = bitno % 8; - break; - case 'a': - op->bit[bitno].type = AVR_CMDBIT_ADDRESS; - op->bit[bitno].value = 0; - op->bit[bitno].bitno = bitno < 8 || bitno > 23? 0: - opnum == AVR_OP_LOAD_EXT_ADDR? bitno+8: bitno-8; /* correct bit number for lone 'a' */ - if(bitno < 8 || bitno > 23) - yywarning("address bits don't normally appear in Bytes 0 or 3 of SPI commands"); - break; - case 'i': - op->bit[bitno].type = AVR_CMDBIT_INPUT; - op->bit[bitno].value = 0; - op->bit[bitno].bitno = bitno % 8; - break; - case 'o': - op->bit[bitno].type = AVR_CMDBIT_OUTPUT; - op->bit[bitno].value = 0; - op->bit[bitno].bitno = bitno % 8; - break; - case '.': - case '-': - case '_': - case '/': - break; - default : - yyerror("invalid bit specifier '%c'", *s); - rv = -1; - break; + if(len == 1) { + switch(*s) { + case '1': + op->bit[bitno].type = AVR_CMDBIT_VALUE; + op->bit[bitno].value = 1; + op->bit[bitno].bitno = bitno % 8; + break; + case '0': + op->bit[bitno].type = AVR_CMDBIT_VALUE; + op->bit[bitno].value = 0; + op->bit[bitno].bitno = bitno % 8; + break; + case 'x': + op->bit[bitno].type = AVR_CMDBIT_IGNORE; + op->bit[bitno].value = 0; + op->bit[bitno].bitno = bitno % 8; + break; + case 'a': + op->bit[bitno].type = AVR_CMDBIT_ADDRESS; + op->bit[bitno].value = 0; + op->bit[bitno].bitno = bitno < 8 || bitno > 23? 0: + opnum == AVR_OP_LOAD_EXT_ADDR? bitno+8: bitno-8; /* correct bit number for lone 'a' */ + if(bitno < 8 || bitno > 23) + yywarning("address bits don't normally appear in Bytes 0 or 3 of SPI commands"); + break; + case 'i': + op->bit[bitno].type = AVR_CMDBIT_INPUT; + op->bit[bitno].value = 0; + op->bit[bitno].bitno = bitno % 8; + break; + case 'o': + op->bit[bitno].type = AVR_CMDBIT_OUTPUT; + op->bit[bitno].value = 0; + op->bit[bitno].bitno = bitno % 8; + break; + case '.': + case '-': + case '_': + case '/': + break; + default : + yyerror("invalid bit specifier '%c'", *s); + rv = -1; + break; } } else { const char *errstr; diff --git a/src/confwin.c b/src/confwin.c index c5322cea3..ca5574628 100644 --- a/src/confwin.c +++ b/src/confwin.c @@ -16,14 +16,12 @@ * along with this program. If not, see . */ - #include #include "avrdude.h" #include "libavrdude.h" #if defined(WIN32) - #define WIN32_LEAN_AND_MEAN #include @@ -32,5 +30,4 @@ int win_set_path(char *path, int n, const char *file) { *path = 0; return SearchPath(NULL, file, NULL, n, path, NULL); } - #endif diff --git a/src/crc16.c b/src/crc16.c index 0177c9dab..cee047fac 100644 --- a/src/crc16.c +++ b/src/crc16.c @@ -1,10 +1,10 @@ /* - * Derived from CRC algorithm for JTAG ICE mkII, published in Atmel - * Appnote AVR067. Converted from C++ to C. + * Derived from CRC algorithm for JTAG ICE mkII, published in Atmel Appnote + * AVR067. Converted from C++ to C. */ #include "crc16.h" -/* CRC16 Definitions */ +// CRC16 Definitions static const unsigned short crc_table[256] = { 0x0000, 0x1189, 0x2312, 0x329b, 0x4624, 0x57ad, 0x6536, 0x74bf, 0x8c48, 0x9dc1, 0xaf5a, 0xbed3, 0xca6c, 0xdbe5, 0xe97e, 0xf8f7, @@ -40,44 +40,31 @@ static const unsigned short crc_table[256] = { 0x7bc7, 0x6a4e, 0x58d5, 0x495c, 0x3de3, 0x2c6a, 0x1ef1, 0x0f78 }; -/* CRC calculation macros */ +// CRC calculation macros #define CRC_INIT 0xFFFF -#define CRC(crcval,newchar) crcval = (crcval >> 8) ^ \ - crc_table[(crcval ^ newchar) & 0x00ff] +#define CRC(crcval, newchar) ((crcval) = (crcval>>8) ^ crc_table[((crcval) ^ (newchar)) & 0x00ff]) -unsigned short -crcsum(const unsigned char* message, unsigned long length, - unsigned short crc) -{ +unsigned short crcsum(const unsigned char *message, unsigned long length, unsigned short crc) { unsigned long i; - for(i = 0; i < length; i++) - { - CRC(crc, message[i]); - } + for(i = 0; i < length; i++) { + CRC(crc, message[i]); + } return crc; } -int -crcverify(const unsigned char* message, unsigned long length) -{ - /* - * Returns true if the last two bytes in a message is the crc of the - * preceding bytes. - */ +// Returns true if the last two bytes in a message is the crc of the preceding bytes +int crcverify(const unsigned char *message, unsigned long length) { unsigned short expected; expected = crcsum(message, length - 2, CRC_INIT); - return (expected & 0xff) == message[length - 2] && - ((expected >> 8) & 0xff) == message[length - 1]; + return (expected & 0xff) == message[length - 2] && ((expected >> 8) & 0xff) == message[length - 1]; } -void -crcappend(unsigned char* message, unsigned long length) -{ +void crcappend(unsigned char *message, unsigned long length) { unsigned long crc; crc = crcsum(message, length, CRC_INIT); - message[length] = (unsigned char)(crc & 0xff); - message[length+1] = (unsigned char)((crc >> 8) & 0xff); + message[length] = (unsigned char) (crc & 0xff); + message[length + 1] = (unsigned char) ((crc >> 8) & 0xff); } diff --git a/src/crc16.h b/src/crc16.h index db10131de..32fa7ff32 100644 --- a/src/crc16.h +++ b/src/crc16.h @@ -5,30 +5,19 @@ extern "C" { #endif -/* - * Derived from CRC algorithm for JTAG ICE mkII, published in Atmel - * Appnote AVR067. Converted from C++ to C. - */ + // Derived from CRC algorithm for JTAG ICE mkII, published in Atmel Appnote AVR067 + extern unsigned short crcsum(const unsigned char *message, unsigned long length, unsigned short crc); -extern unsigned short crcsum(const unsigned char* message, - unsigned long length, - unsigned short crc); -/* - * Verify that the last two bytes is a (LSB first) valid CRC of the - * message. - */ -extern int crcverify(const unsigned char* message, - unsigned long length); -/* - * Append a two byte CRC (LSB first) to message. length is size of - * message excluding crc. Space for the CRC bytes must be allocated - * in advance! - */ -extern void crcappend(unsigned char* message, - unsigned long length); + // Verify that the last two bytes is a (LSB first) valid CRC of the message + extern int crcverify(const unsigned char *message, unsigned long length); + + /* + * Append a two byte CRC (LSB first) to message. length is size of message + * excluding crc. Space for the CRC bytes must be allocated in advance! + */ + extern void crcappend(unsigned char *message, unsigned long length); #ifdef __cplusplus } #endif - #endif diff --git a/src/developer_opts.c b/src/developer_opts.c index 707be90e8..4f8ea8ffa 100644 --- a/src/developer_opts.c +++ b/src/developer_opts.c @@ -78,7 +78,6 @@ static struct { {NULL, NULL, NULL, NULL}, }; - // Return 0 if op code would encode (essentially) the same SPI command static int opcodecmp(const OPCODE *op1, const OPCODE *op2, int opnum) { char *opstr1, *opstr2, *p; @@ -93,10 +92,10 @@ static int opcodecmp(const OPCODE *op1, const OPCODE *op2, int opnum) { opstr2 = opcode2str(op2, opnum, 1); // Don't care x and 0 are functionally equivalent - for(p=opstr1; *p; p++) + for(p = opstr1; *p; p++) if(*p == 'x') *p = '0'; - for(p=opstr2; *p; p++) + for(p = opstr2; *p; p++) if(*p == 'x') *p = '0'; @@ -107,7 +106,6 @@ static int opcodecmp(const OPCODE *op1, const OPCODE *op2, int opnum) { return cmp; } - static void printopcode(const AVRPART *p, const char *d, const OPCODE *op, int opnum) { unsigned char cmd[4]; int i; @@ -117,7 +115,7 @@ static void printopcode(const AVRPART *p, const char *d, const OPCODE *op, int o avr_set_bits(op, cmd); dev_info(".op\t%s\t%s\t%s\t0x%02x%02x%02x%02x\t", p->desc, d, opcodename(opnum), cmd[0], cmd[1], cmd[2], cmd[3]); - for(i=31; i >= 0; i--) { + for(i = 31; i >= 0; i--) { dev_info("%c", cmdbitchar(op->bit[i])); if(i%8 == 0) dev_info("%c", i? '\t': '\n'); @@ -125,12 +123,11 @@ static void printopcode(const AVRPART *p, const char *d, const OPCODE *op, int o } } -static void printallopcodes(const AVRPART *p, const char *d, OPCODE * const *opa) { - for(int i=0; i hi) { - if(op->bit[i+8].type != AVR_CMDBIT_IGNORE && !(op->bit[i+8].type == AVR_CMDBIT_VALUE && op->bit[i+8].value == 0)) { - char *cbs = cmdbitstr(op->bit[i+8]); + if(op->bit[i + 8].type != AVR_CMDBIT_IGNORE && + !(op->bit[i + 8].type == AVR_CMDBIT_VALUE && op->bit[i + 8].value == 0)) { + + char *cbs = cmdbitstr(op->bit[i + 8]); + dev_info(".cmderr\t%s\t%s-%s\tbit %d outside addressable space should be x or 0 but is %s\n", - p->desc, m->desc, opstr, i+8, cbs? cbs: "NULL"); + p->desc, m->desc, opstr, i + 8, cbs? cbs: "NULL"); if(cbs) mmt_free(cbs); } } else { - if(op->bit[i+8].type != AVR_CMDBIT_ADDRESS) - dev_info(".cmderr\t%s\t%s-%s\tbit %d is %c but should be a\n", p->desc, m->desc, opstr, i+8, cmdbitchar(op->bit[i+8])); - else if(op->bit[i+8].bitno != i) - dev_info(".cmderr\t%s\t%s-%s\tbit %d inconsistent: a%d specified as a%d\n", p->desc, m->desc, opstr, i+8, i, op->bit[i+8].bitno); + if(op->bit[i + 8].type != AVR_CMDBIT_ADDRESS) + dev_info(".cmderr\t%s\t%s-%s\tbit %d is %c but should be a\n", p->desc, m->desc, opstr, i + 8, + cmdbitchar(op->bit[i + 8])); + else if(op->bit[i + 8].bitno != i) + dev_info(".cmderr\t%s\t%s-%s\tbit %d inconsistent: a%d specified as a%d\n", + p->desc, m->desc, opstr, i + 8, i, op->bit[i + 8].bitno); } } - for(i=0; i<32; i++) // Command bits 8..23 should not contain address bits - if((i<8 || i>23) && op->bit[i].type == AVR_CMDBIT_ADDRESS) - dev_info(".cmderr\t%s\t%s-%s\tbit %d contains a%d which it shouldn't\n", p->desc, m->desc, opstr, i, op->bit[i].bitno); + for(i = 0; i < 32; i++) // Command bits 8..23 should not contain address bits + if((i < 8 || i > 23) && op->bit[i].type == AVR_CMDBIT_ADDRESS) + dev_info(".cmderr\t%s\t%s-%s\tbit %d contains a%d which it shouldn't\n", + p->desc, m->desc, opstr, i, op->bit[i].bitno); } - - static char *dev_sprintf(const char *fmt, ...) { int size = 0; char *p = NULL; @@ -209,11 +210,10 @@ static char *dev_sprintf(const char *fmt, ...) { return p; } - static int dev_nprinted; #if defined(__GNUC__) - __attribute__ ((format (printf, 2, 3))) +__attribute__((format(printf, 2, 3))) #endif int dev_message(int msglvl, const char *fmt, ...) { va_list ap; @@ -230,21 +230,20 @@ int dev_message(int msglvl, const char *fmt, ...) { return rc; } - // Any of the strings in the list contains subs as substring? int dev_has_subsstr_comms(const LISTID comms, const char *subs) { if(comms) - for(LNODEID ln=lfirst(comms); ln; ln=lnext(ln)) - if(str_contains((char *) ldata(ln), subs)) - return 1; + for(LNODEID ln = lfirst(comms); ln; ln = lnext(ln)) + if(str_contains((char *) ldata(ln), subs)) + return 1; return 0; } // Print a chained list of strings void dev_print_comment(const LISTID comms) { if(comms) - for(LNODEID ln=lfirst(comms); ln; ln=lnext(ln)) - dev_info("%s", (char *) ldata(ln)); + for(LNODEID ln = lfirst(comms); ln; ln = lnext(ln)) + dev_info("%s", (char *) ldata(ln)); } // Conditional output of part, memory or programmer's comments field @@ -262,8 +261,9 @@ static void dev_cout(const LISTID comms, const char *name, int rhs, int elself) // Print part->comments, mem->comments or pgm->comments (for debugging) void dev_print_kw_comments(const LISTID comms) { if(comms) - for(LNODEID ln=lfirst(comms); ln; ln=lnext(ln)) { + for(LNODEID ln = lfirst(comms); ln; ln = lnext(ln)) { COMMENT *n = ldata(ln); + if(n && n->comms) { dev_info(">>> %s %c\n", n->kw, n->rhs? '>': '<'); dev_print_comment(n->comms); @@ -272,7 +272,7 @@ void dev_print_kw_comments(const LISTID comms) { } // Ideally all assignment outputs run via this function -static int dev_part_strct_entry(bool tsv, // Print as spreadsheet? +static int dev_part_strct_entry(bool tsv, // Print as spreadsheet? const char *col0, const char *col1, const char *col2, // Descriptors of item const char *name, char *cont, const LISTID comms) { // Name, contents and comments @@ -292,6 +292,7 @@ static int dev_part_strct_entry(bool tsv, // Print as spreadsheet? dev_info("%s\t%s\n", n, c); } else { // Grammar conform int indent = col2 && !str_eq(col2, "part"); + dev_cout(comms, n, 0, 0); // Print comments before the line dev_info("%*s%-*s = %s;", indent? 8: 4, "", indent? 18: 22, n, c); dev_cout(comms, n, 1, 1); // Print comments on rhs @@ -302,16 +303,13 @@ static int dev_part_strct_entry(bool tsv, // Print as spreadsheet? return 1; } - static const char *dev_controlstack_name(const AVRPART *p) { return p->ctl_stack_type == CTL_STACK_PP? "pp_controlstack": p->ctl_stack_type == CTL_STACK_HVSP? "hvsp_controlstack": - p->ctl_stack_type == CTL_STACK_NONE? "NULL": - "unknown_controlstack"; + p->ctl_stack_type == CTL_STACK_NONE? "NULL": "unknown_controlstack"; } - static void dev_stack_out(bool tsv, const AVRPART *p, const char *name, const unsigned char *stack, int ns) { if(str_eq(name, "NULL")) { name = "pp_controlstack"; @@ -322,28 +320,26 @@ static void dev_stack_out(bool tsv, const AVRPART *p, const char *name, const un dev_info(".pt\t%s\t%s\t", p->desc, name); else { dev_cout(p->comments, name, 0, 0); - dev_info(" %-22s =%s", name, ns <=8? " ": ""); + dev_info(" %-22s =%s", name, ns <= 8? " ": ""); } if(ns <= 0) dev_info(tsv? "NULL\n": "NULL;"); else - for(int i=0; i 8 && i%8 == 0? "\n ": " ", stack[i], i+1 8 && i%8 == 0? "\n ": " ", stack[i], i + 1 < ns? ",": tsv? "\n": ";"); dev_cout(p->comments, name, 1, 1); } - static int intcmp(int a, int b) { - return a-b; + return a - b; } static int boolcmp(int a, int b) { - return !!a-!!b; + return !!a - !!b; } - // Deep copies for comparison and raw output typedef struct { @@ -357,22 +353,22 @@ static int avrmem_deep_copy(AVRMEMdeep *d, const AVRMEM *m) { // Note memory desc (name, really) is limited to 31 char here memset(d->descbuf, 0, sizeof d->descbuf); - strncpy(d->descbuf, m->desc, sizeof d->descbuf-1); + strncpy(d->descbuf, m->desc, sizeof d->descbuf - 1); // Zap address values d->base.comments = NULL; d->base.buf = NULL; d->base.tags = NULL; d->base.desc = NULL; - for(int i=0; ibase.op[i] = NULL; // Copy over the SPI operations themselves memset(d->ops, 0, sizeof d->ops); - for(size_t i=0; iop[i]) { d->ops[i] = *m->op[i]; - for(int b=0; b<32; b++) { // Replace x with 0 as they are treated the same + for(int b = 0; b < 32; b++) { // Replace x with 0 as they are treated the same if(d->ops[i].bit[b].type == AVR_CMDBIT_IGNORE) { d->ops[i].bit[b].type = AVR_CMDBIT_VALUE; d->ops[i].bit[b].value = 0; @@ -398,21 +394,20 @@ static int memorycmp(const AVRMEM *m1, const AVRMEM *m2) { return memcmp(&dm1, &dm2, sizeof dm1); } - typedef struct { char descbuf[64]; char idbuf[32]; char family_idbuf[16]; - char variants[4096-16-32-64]; + char variants[4096 - 16 - 32 - 64]; AVRPART base; OPCODE ops[AVR_OP_MAX]; AVRMEMdeep mems[40]; } AVRPARTdeep; - // Return memory iff its desc matches str exactly static AVRMEM *dev_locate_mem(const AVRPART *p, const char *str) { AVRMEM *m = p->mem? avr_locate_mem_noalias(p, str): NULL; + return m && str_eq(m->desc, str)? m: NULL; } @@ -430,14 +425,15 @@ static int avrpart_deep_copy(AVRPARTdeep *d, const AVRPART *p) { d->base.lineno = 0; // Copy over desc, id, and family_id - strncpy(d->descbuf, p->desc, sizeof d->descbuf-1); - strncpy(d->idbuf, p->id, sizeof d->idbuf-1); - strncpy(d->family_idbuf, p->family_id, sizeof d->family_idbuf-1); + strncpy(d->descbuf, p->desc, sizeof d->descbuf - 1); + strncpy(d->idbuf, p->id, sizeof d->idbuf - 1); + strncpy(d->family_idbuf, p->family_id, sizeof d->family_idbuf - 1); char *vp = d->variants; - for(LNODEID ln=lfirst(p->variants); ln; ln=lnext(ln)) { - if(vp < d->variants+sizeof d->variants-2) { - strncpy(vp, (char *)ldata(ln), d->variants+sizeof d->variants-vp-1); - vp += strlen(vp)+1; + + for(LNODEID ln = lfirst(p->variants); ln; ln = lnext(ln)) { + if(vp < d->variants + sizeof d->variants - 2) { + strncpy(vp, (char *) ldata(ln), d->variants + sizeof d->variants - vp - 1); + vp += strlen(vp) + 1; } } @@ -448,24 +444,24 @@ static int avrpart_deep_copy(AVRPARTdeep *d, const AVRPART *p) { d->base.mem = NULL; d->base.mem_alias = NULL; d->base.variants = NULL; - for(int i=0; ibase.op[i] = NULL; // Copy over all used SPI operations - for(int i=0; iop[i]) d->ops[i] = *p->op[i]; // Fill in all memories we got in defined order di = 0; - for(size_t mi=0; mi < sizeof avr_mem_order/sizeof *avr_mem_order && avr_mem_order[mi].str; mi++) { + for(size_t mi = 0; mi < sizeof avr_mem_order/sizeof *avr_mem_order && avr_mem_order[mi].str; mi++) { m = dev_locate_mem(p, avr_mem_order[mi].str); if(m) { if(di >= sizeof d->mems/sizeof *d->mems) { pmsg_error("ran out of mems[] space, increase size in AVRMEMdeep of developer_opts.c and recompile\n"); exit(1); } - avrmem_deep_copy(d->mems+di, m); + avrmem_deep_copy(d->mems + di, m); di++; } } @@ -473,7 +469,6 @@ static int avrpart_deep_copy(AVRPARTdeep *d, const AVRPART *p) { return di; } - static char txtchar(unsigned char in) { in &= 0x7f; return in == 0? '.': in > ' ' && in < 0x7f? in: '_'; @@ -483,9 +478,9 @@ static void dev_raw_dump(const void *v, int nbytes, const char *name, const char const unsigned char *p = v; int n = (nbytes + 31)/32; - for(int i=0; idesc, "part.intro", 0); + dev_raw_dump(&dp, (char *) &dp.base - (char *) &dp, part->desc, "part.intro", 0); dev_raw_dump(&dp.base, sizeof dp.base, part->desc, "part", 0); - for(int i=0; idesc, opsnm("part", i), 1); + for(int i = 0; i < AVR_OP_MAX; i++) + if(!is_memset(dp.ops + i, 0, sizeof *dp.ops)) + dev_raw_dump(dp.ops + i, sizeof *dp.ops, part->desc, opsnm("part", i), 1); - for(int i=0; idesc, nm, i+2); - dev_raw_dump(&dp.mems[i].base, sizeof dp.mems[i].base, part->desc, nm, i+2); - for(int j=0; jdesc, opsnm(nm, j), i+2); + dev_raw_dump(nm, sizeof dp.mems[i].descbuf, part->desc, nm, i + 2); + dev_raw_dump(&dp.mems[i].base, sizeof dp.mems[i].base, part->desc, nm, i + 2); + for(int j = 0; j < AVR_OP_MAX; j++) + if(!is_memset(dp.mems[i].ops + j, 0, sizeof(OPCODE))) + dev_raw_dump(dp.mems[i].ops + j, sizeof(OPCODE), part->desc, opsnm(nm, j), i + 2); } } - static void dev_part_strct(const AVRPART *p, bool tsv, const AVRPART *base, bool injct) { char *descstr = cfg_escape(p->desc); COMMENT *cp; if(!tsv) { const char *del = "#------------------------------------------------------------"; + cp = locate_comment(p->comments, "*", 0); if(!cp || !dev_has_subsstr_comms(cp->comms, del)) { dev_info("%s\n", del); - dev_info("# %.*s\n", (int) strlen(descstr)-2, descstr+1); // Remove double quotes + dev_info("# %.*s\n", (int) strlen(descstr) - 2, descstr + 1); // Remove double quotes dev_info("%s\n\n", del); } if(cp) @@ -555,17 +551,19 @@ static void dev_part_strct(const AVRPART *p, bool tsv, const AVRPART *base, bool if(lsize(p->variants)) { // Variants are never inherited, so print if they exist int firstid = 1; + if(tsv) dev_info(".pt\t%s\tvariants\t", p->desc); else { dev_cout(p->comments, "variants", 0, 0); dev_info(" %-22s =\n", "variants"); } - for(LNODEID ln=lfirst(p->variants); ln; ln=lnext(ln)) { + for(LNODEID ln = lfirst(p->variants); ln; ln = lnext(ln)) { if(!firstid) dev_info(tsv? ", ": ",\n"); firstid = 0; char *str = cfg_escape(ldata(ln)); + dev_info("%*s%s", tsv? 0: 8, "", str); mmt_free(str); } @@ -603,16 +601,16 @@ static void dev_part_strct(const AVRPART *p, bool tsv, const AVRPART *base, bool _if_partout(intcmp, "%d", chip_erase_delay); _if_partout(intcmp, "0x%02x", pagel); _if_partout(intcmp, "0x%02x", bs2); - _if_n_partout_str(memcmp, sizeof p->signature, dev_sprintf("0x%02x 0x%02x 0x%02x", p->signature[0], p->signature[1], p->signature[2]), signature); + _if_n_partout_str(memcmp, sizeof p->signature, dev_sprintf("0x%02x 0x%02x 0x%02x", p->signature[0], p->signature[1], + p->signature[2]), signature); _if_partout(intcmp, "0x%04x", usbpid); if(!base || base->reset_disposition != p->reset_disposition) _partout_str(mmt_strdup(p->reset_disposition == RESET_DEDICATED? - "dedicated": p->reset_disposition == RESET_IO? "io": "unknown"), - reset); + "dedicated": p->reset_disposition == RESET_IO? "io": "unknown"), reset); _if_partout_str(intcmp, mmt_strdup(p->retry_pulse == PIN_AVR_RESET? - "reset": p->retry_pulse == PIN_AVR_SCK? "sck": "unknown"), retry_pulse); + "reset": p->retry_pulse == PIN_AVR_SCK? "sck": "unknown"), retry_pulse); if(!base || base->flags != p->flags) { if(tsv) { @@ -623,10 +621,13 @@ static void dev_part_strct(const AVRPART *p, bool tsv, const AVRPART *base, bool _if_flagout(AVRPART_ENABLEPAGEPROGRAMMING, enablepageprogramming); _if_flagout(AVRPART_SERIALOK, serial); - if(!base || (base->flags & (AVRPART_PARALLELOK | AVRPART_PSEUDOPARALLEL)) != (p->flags & (AVRPART_PARALLELOK | AVRPART_PSEUDOPARALLEL))) { + if(!base + || (base->flags & (AVRPART_PARALLELOK | AVRPART_PSEUDOPARALLEL)) != + (p->flags & (AVRPART_PARALLELOK | AVRPART_PSEUDOPARALLEL))) { int par = p->flags & (AVRPART_PARALLELOK | AVRPART_PSEUDOPARALLEL); + _partout_str(mmt_strdup(par == 0? "no": - par == AVRPART_PSEUDOPARALLEL? "unknown": AVRPART_PARALLELOK? "yes": "pseudo"), parallel); + par == AVRPART_PSEUDOPARALLEL? "unknown": AVRPART_PARALLELOK? "yes": "pseudo"), parallel); } } } @@ -642,11 +643,12 @@ static void dev_part_strct(const AVRPART *p, bool tsv, const AVRPART *base, bool _if_partout(intcmp, "%d", postdelay); _if_partout(intcmp, "%d", pollmethod); - if(!base && p->ctl_stack_type != CTL_STACK_NONE) + if(!base && p->ctl_stack_type != CTL_STACK_NONE) dev_stack_out(tsv, p, dev_controlstack_name(p), p->controlstack, CTL_STACK_SIZE); // @@@ may need to remove controlstack and set p->ctl_stack_type to CTL_STACK_NONE if base has controlstack? - if(base && (p->ctl_stack_type != base->ctl_stack_type || memcmp(base->controlstack, p->controlstack, sizeof base->controlstack))) + if(base && (p->ctl_stack_type != base->ctl_stack_type + || memcmp(base->controlstack, p->controlstack, sizeof base->controlstack))) dev_stack_out(tsv, p, dev_controlstack_name(p), p->controlstack, CTL_STACK_SIZE); if(!base || memcmp(base->flash_instr, p->flash_instr, sizeof base->flash_instr)) @@ -687,18 +689,19 @@ static void dev_part_strct(const AVRPART *p, bool tsv, const AVRPART *base, bool _if_partout(intcmp, "0x%02x", autobaud_sync); _if_partout(intcmp, "%d", factory_fcpu); - for(int i=0; i < AVR_OP_MAX; i++) + for(int i = 0; i < AVR_OP_MAX; i++) if(!base || opcodecmp(p->op[i], base->op[i], i)) dev_part_strct_entry(tsv, ".ptop", p->desc, "part", opcodename(i), opcode2str(p->op[i], i, !tsv), p->comments); - for(size_t mi=0; mi < sizeof avr_mem_order/sizeof *avr_mem_order && avr_mem_order[mi].str; mi++) { + for(size_t mi = 0; mi < sizeof avr_mem_order/sizeof *avr_mem_order && avr_mem_order[mi].str; mi++) { AVRMEM *m, *bm; m = dev_locate_mem(p, avr_mem_order[mi].str); bm = base? dev_locate_mem(base, avr_mem_order[mi].str): NULL; if(!m && bm && !tsv) - dev_info("\n memory \"%s\" %*s= NULL;\n", bm->desc, 13 > strlen(bm->desc)? 13 - (int) strlen(bm->desc): 0, ""); + dev_info("\n memory \"%s\" %*s= NULL;\n", + bm->desc, 13 > strlen(bm->desc)? 13 - (int) strlen(bm->desc): 0, ""); if(!m) continue; @@ -709,8 +712,9 @@ static void dev_part_strct(const AVRPART *p, bool tsv, const AVRPART *base, bool if(!tsv) { if(!memorycmp(bm, m)) { // Same memory bit for bit, only instantiate on injected parameters int haveinjct = 0; + if(injct) - for(size_t i=0; idesc) && str_match(meminj[i].mem, m->desc)) haveinjct = 1; if(!haveinjct) @@ -739,16 +743,16 @@ static void dev_part_strct(const AVRPART *p, bool tsv, const AVRPART *base, bool _if_memout(intcmp, "%d", readsize); _if_memout(intcmp, "%d", pollindex); - for(int i=0; i < AVR_OP_MAX; i++) + for(int i = 0; i < AVR_OP_MAX; i++) if(!bm || opcodecmp(bm->op[i], m->op[i], i)) - dev_part_strct_entry(tsv, ".ptmmop", p->desc, m->desc, opcodename(i), opcode2str(m->op[i], i, !tsv), m->comments); + dev_part_strct_entry(tsv, ".ptmmop", p->desc, m->desc, opcodename(i), + opcode2str(m->op[i], i, !tsv), m->comments); if(injct) - for(size_t i=0; idesc)) if(str_match(meminj[i].mem, m->desc)) { - dev_part_strct_entry(tsv, ".ptmm", p->desc, m->desc, - meminj[i].var, mmt_strdup(meminj[i].value), NULL); + dev_part_strct_entry(tsv, ".ptmm", p->desc, m->desc, meminj[i].var, mmt_strdup(meminj[i].value), NULL); meminj[i].mcu = NULL; } @@ -757,14 +761,17 @@ static void dev_part_strct(const AVRPART *p, bool tsv, const AVRPART *base, bool dev_info(" ;\n"); } - for(LNODEID lnm=lfirst(p->mem_alias); lnm; lnm=lnext(lnm)) { + for(LNODEID lnm = lfirst(p->mem_alias); lnm; lnm = lnext(lnm)) { AVRMEM_ALIAS *ma = ldata(lnm); + if(ma->aliased_mem && str_eq(ma->aliased_mem->desc, m->desc)) { // There is a memory that's aliased to the current memory: is it inherited? if(base) { int basehasalias = 0; - for(LNODEID lnb=lfirst(base->mem_alias); lnb; lnb=lnext(lnb)) { + + for(LNODEID lnb = lfirst(base->mem_alias); lnb; lnb = lnext(lnb)) { AVRMEM_ALIAS *mab = ldata(lnb); + if(str_eq(mab->desc, ma->desc) && mab->aliased_mem && str_eq(mab->aliased_mem->desc, m->desc)) basehasalias = 1; } @@ -780,18 +787,16 @@ static void dev_part_strct(const AVRPART *p, bool tsv, const AVRPART *base, bool } if(injct) { - for(size_t i=0; idesc)) - dev_part_strct_entry(tsv, ".pt", p->desc, NULL, - ptinj[i].var, mmt_strdup(ptinj[i].value), NULL); + dev_part_strct_entry(tsv, ".pt", p->desc, NULL, ptinj[i].var, mmt_strdup(ptinj[i].value), NULL); - for(size_t i=0; idesc)) { if(!tsv) dev_info(" memory \"%s\"\n", meminj[i].mem); - dev_part_strct_entry(tsv, ".ptmm", p->desc, meminj[i].mem, - meminj[i].var, mmt_strdup(meminj[i].value), NULL); + dev_part_strct_entry(tsv, ".ptmm", p->desc, meminj[i].mem, meminj[i].var, mmt_strdup(meminj[i].value), NULL); meminj[i].mcu = NULL; if(!tsv) dev_info(" ;\n"); @@ -804,20 +809,25 @@ static void dev_part_strct(const AVRPART *p, bool tsv, const AVRPART *base, bool } } - void dev_output_pgm_part(int dev_opt_c, const char *programmer, int dev_opt_p, const char *partdesc) { if(dev_opt_c == 2 && dev_opt_p == 2) { char *p; dev_print_comment(cfg_get_prologue()); - dev_info("avrdude_conf_version = %s;\n\n", p = cfg_escape(avrdude_conf_version)); mmt_free(p); - dev_info("default_programmer = %s;\n", p = cfg_escape(default_programmer)); mmt_free(p); - dev_info("default_parallel = %s;\n", p = cfg_escape(default_parallel)); mmt_free(p); - dev_info("default_serial = %s;\n", p = cfg_escape(default_serial)); mmt_free(p); - dev_info("default_spi = %s;\n", p = cfg_escape(default_spi)); mmt_free(p); + dev_info("avrdude_conf_version = %s;\n\n", p = cfg_escape(avrdude_conf_version)); + mmt_free(p); + dev_info("default_programmer = %s;\n", p = cfg_escape(default_programmer)); + mmt_free(p); + dev_info("default_parallel = %s;\n", p = cfg_escape(default_parallel)); + mmt_free(p); + dev_info("default_serial = %s;\n", p = cfg_escape(default_serial)); + mmt_free(p); + dev_info("default_spi = %s;\n", p = cfg_escape(default_spi)); + mmt_free(p); dev_info("default_baudrate = %d;\n", default_baudrate); dev_info("default_bitclock = %7.5f;\n", default_bitclock); - dev_info("default_linuxgpio = %s;\n", p = cfg_escape(default_linuxgpio)); mmt_free(p); + dev_info("default_linuxgpio = %s;\n", p = cfg_escape(default_linuxgpio)); + mmt_free(p); dev_info("allow_subshells = %s;\n", allow_subshells? "yes": "no"); dev_info("\n#\n# PROGRAMMER DEFINITIONS\n#\n\n"); @@ -835,25 +845,43 @@ void dev_output_pgm_part(int dev_opt_c, const char *programmer, int dev_opt_p, c dev_output_part_defs(mmt_strdup(partdesc)); } - // Which programming modes should be considered, given the flags? static int prog_modes_in_flags(int prog_modes, const char *flags) { - int pm = 0, quirky = 0; + int pm = 0, quirky = 0; for(const char *p = flags; *p; p++) switch(*p) { - case 'B': pm |= PM_SPM; break; - case 'C': pm |= PM_TPI | PM_ISP | PM_HVSP | PM_HVPP | PM_debugWIRE | PM_JTAG | PM_JTAGmkI; break; - case 'U': pm |= PM_UPDI; break; - case 'P': pm |= PM_PDI; break; - case 'T': pm |= PM_TPI; break; - case 'I': pm |= PM_ISP; break; - case 'J': pm |= PM_JTAG | PM_JTAGmkI | PM_XMEGAJTAG; break; - case 'W': pm |= PM_debugWIRE; break; - case 'H': pm |= PM_HVPP | PM_HVSP; break; - case 'Q': pm |= PM_ALL & ~(PM_SPM | PM_UPDI | PM_PDI | PM_TPI | PM_ISP | PM_JTAG | PM_JTAGmkI | - PM_XMEGAJTAG | PM_debugWIRE | PM_HVPP | PM_HVSP); - quirky = 1; + case 'B': + pm |= PM_SPM; + break; + case 'C': + pm |= PM_TPI | PM_ISP | PM_HVSP | PM_HVPP | PM_debugWIRE | PM_JTAG | PM_JTAGmkI; + break; + case 'U': + pm |= PM_UPDI; + break; + case 'P': + pm |= PM_PDI; + break; + case 'T': + pm |= PM_TPI; + break; + case 'I': + pm |= PM_ISP; + break; + case 'J': + pm |= PM_JTAG | PM_JTAGmkI | PM_XMEGAJTAG; + break; + case 'W': + pm |= PM_debugWIRE; + break; + case 'H': + pm |= PM_HVPP | PM_HVSP; + break; + case 'Q': + pm |= PM_ALL & ~(PM_SPM | PM_UPDI | PM_PDI | PM_TPI | PM_ISP | PM_JTAG | PM_JTAGmkI | + PM_XMEGAJTAG | PM_debugWIRE | PM_HVPP | PM_HVSP); + quirky = 1; } return (prog_modes == 0 && quirky) || !pm || (prog_modes & pm); @@ -862,6 +890,7 @@ static int prog_modes_in_flags(int prog_modes, const char *flags) { // Return pointer to uP_table entry for part p static const Avrintel *silent_locate_uP(const AVRPART *p) { int bakverb = verbose, idx; + verbose = -123; idx = avr_locate_upidx(p); verbose = bakverb; @@ -879,13 +908,12 @@ void dev_output_part_defs(char *partdesc) { if((flags = strchr(partdesc, '/'))) *flags++ = 0; - if(!flags && str_eq(partdesc, "*")) // Treat -p * as if it was -p */s + if(!flags && str_eq(partdesc, "*")) // Treat -p * as if it was -p */s flags = "s"; if(!*flags || !strchr("dsASRvcreow*tiBCUPTIJWHQ", *flags)) { dev_info("Error: flags for developer option -p / not recognised\n"); - dev_info( - "Wildcard examples (these need protecting in the shell through quoting):\n" + dev_info("Wildcard examples (these need protecting in the shell through quoting):\n" " * all known parts\n" " ATtiny10 just this part\n" " *32[0-9] matches ATmega329, ATmega325 and ATmega328\n" @@ -918,8 +946,7 @@ void dev_output_part_defs(char *partdesc) { " /s, /S and /A outputs are designed to be used as input in avrdude.conf\n" " Sorted /r output should stay invariant when rearranging avrdude.conf\n" " The /e, /o and /w flags are less generic and may be removed sometime\n" - " These options are just to help development, so not further documented\n" - ); + " These options are just to help development, so not further documented\n"); return; } @@ -932,22 +959,23 @@ void dev_output_part_defs(char *partdesc) { opspi = all || !!strchr(flags, 'o'); waits = all || !!strchr(flags, 'w'); astrc = all || !!strchr(flags, 'A'); - raw = all || !!strchr(flags, 'R'); + raw = all || !!strchr(flags, 'R'); strct = !!strchr(flags, 'S'); cmpst = !!strchr(flags, 's'); - tsv = !!strchr(flags, 't'); + tsv = !!strchr(flags, 't'); injct = !!strchr(flags, 'i'); // Go through all memories and add them to the memory order list for(LNODEID ln1 = lfirst(part_list); ln1; ln1 = lnext(ln1)) { AVRPART *p = ldata(ln1); + if(p->mem) - for(LNODEID lnm=lfirst(p->mem); lnm; lnm=lnext(lnm)) + for(LNODEID lnm = lfirst(p->mem); lnm; lnm = lnext(lnm)) avr_get_mem_type(((AVRMEM *) ldata(lnm))->desc); // Same for aliased memories (though probably not needed) if(p->mem_alias) - for(LNODEID lnm=lfirst(p->mem_alias); lnm; lnm=lnext(lnm)) + for(LNODEID lnm = lfirst(p->mem_alias); lnm; lnm = lnext(lnm)) avr_get_mem_type(((AVRMEM_ALIAS *) ldata(lnm))->desc); } @@ -957,7 +985,7 @@ void dev_output_part_defs(char *partdesc) { } for(LNODEID ln1 = lfirst(part_list); ln1; ln1 = lnext(ln1)) { AVRPART *p = ldata(ln1); - int flashsize, flashoffset, flashpagesize, eepromsize , eepromoffset, eeprompagesize; + int flashsize, flashoffset, flashpagesize, eepromsize, eepromoffset, eeprompagesize; if(!descs || tsv) if(dev_nprinted > nprinted) { @@ -972,8 +1000,7 @@ void dev_output_part_defs(char *partdesc) { if(astrc || strct || cmpst) dev_part_strct(p, tsv, - astrc? NULL: - strct? nullpart: + astrc? NULL: strct? nullpart: p->parent_id && *p->parent_id? locate_part(part_list, p->parent_id): nullpart, injct); @@ -984,8 +1011,9 @@ void dev_output_part_defs(char *partdesc) { flashsize = flashoffset = flashpagesize = eepromsize = eepromoffset = eeprompagesize = 0; if(p->mem) { - for(LNODEID lnm=lfirst(p->mem); lnm; lnm=lnext(lnm)) { + for(LNODEID lnm = lfirst(p->mem); lnm; lnm = lnext(lnm)) { AVRMEM *m = ldata(lnm); + if(!flashsize && mem_is_flash(m)) { flashsize = m->size; flashpagesize = m->page_size; @@ -998,7 +1026,6 @@ void dev_output_part_defs(char *partdesc) { } } } - // "Real" entries don't seem to have a space in their desc (a bit hackey) if(flashsize && !strchr(p->desc, ' ')) { int ok, nfuses; @@ -1019,47 +1046,47 @@ void dev_output_part_defs(char *partdesc) { if((oc = m->op[AVR_OP_LOAD_EXT_ADDR])) { // @@@ to do: check whether address is put at lsb of third byte } else - ok &= ~DEV_SPI_LOAD_EXT_ADDR; + ok &= ~DEV_SPI_LOAD_EXT_ADDR; if((oc = m->op[AVR_OP_READ_HI])) { if(cmdok) - checkaddr(m->size>>1, 1, AVR_OP_READ_HI, oc, p, m); + checkaddr(m->size >> 1, 1, AVR_OP_READ_HI, oc, p, m); } else ok &= ~DEV_SPI_PROGMEM; if((oc = m->op[AVR_OP_READ_LO])) { if(cmdok) - checkaddr(m->size>>1, 1, AVR_OP_READ_LO, oc, p, m); + checkaddr(m->size >> 1, 1, AVR_OP_READ_LO, oc, p, m); } else ok &= ~DEV_SPI_PROGMEM; if((oc = m->op[AVR_OP_WRITE_HI])) { if(cmdok) - checkaddr(m->size>>1, 1, AVR_OP_WRITE_HI, oc, p, m); + checkaddr(m->size >> 1, 1, AVR_OP_WRITE_HI, oc, p, m); } else ok &= ~DEV_SPI_PROGMEM; if((oc = m->op[AVR_OP_WRITE_LO])) { if(cmdok) - checkaddr(m->size>>1, 1, AVR_OP_WRITE_LO, oc, p, m); + checkaddr(m->size >> 1, 1, AVR_OP_WRITE_LO, oc, p, m); } else ok &= ~DEV_SPI_PROGMEM; if((oc = m->op[AVR_OP_LOADPAGE_HI])) { if(cmdok) - checkaddr(m->page_size>>1, 1, AVR_OP_LOADPAGE_HI, oc, p, m); + checkaddr(m->page_size >> 1, 1, AVR_OP_LOADPAGE_HI, oc, p, m); } else ok &= ~DEV_SPI_PROGMEM_PAGED; if((oc = m->op[AVR_OP_LOADPAGE_LO])) { if(cmdok) - checkaddr(m->page_size>>1, 1, AVR_OP_LOADPAGE_LO, oc, p, m); + checkaddr(m->page_size >> 1, 1, AVR_OP_LOADPAGE_LO, oc, p, m); } else ok &= ~DEV_SPI_PROGMEM_PAGED; if((oc = m->op[AVR_OP_WRITEPAGE])) { if(cmdok) - checkaddr(m->size>>1, m->page_size>>1, AVR_OP_WRITEPAGE, oc, p, m); + checkaddr(m->size >> 1, m->page_size >> 1, AVR_OP_WRITEPAGE, oc, p, m); } else ok &= ~DEV_SPI_PROGMEM_PAGED; } else @@ -1105,7 +1132,7 @@ void dev_output_part_defs(char *partdesc) { ok &= ~DEV_SPI_CALIBRATION; // Actually, some AT90S... parts cannot read, only write lock bits :-0 - if( !((m = avr_locate_lock(p)) && m->op[AVR_OP_WRITE])) + if(!((m = avr_locate_lock(p)) && m->op[AVR_OP_WRITE])) ok &= ~DEV_SPI_LOCK; if((m = avr_locate_fuse(p)) && m->op[AVR_OP_READ] && m->op[AVR_OP_WRITE]) @@ -1124,71 +1151,70 @@ void dev_output_part_defs(char *partdesc) { ok &= ~DEV_SPI_EFUSE; if(descs) { - int len = 16-strlen(p->desc); - dev_info("%s '%s' =>%*s [0x%02X, 0x%02X, 0x%02X, 0x%08x, 0x%05x, 0x%03x, 0x%06x, 0x%04x, 0x%03x, %d, 0x%03x, 0x%04x, '%s'], # %s %d\n", + int len = 16 - strlen(p->desc); + + dev_info + ("%s '%s' =>%*s [0x%02X, 0x%02X, 0x%02X, 0x%08x, 0x%05x, 0x%03x, " + "0x%06x, 0x%04x, 0x%03x, %d, 0x%03x, 0x%04x, '%s'], # %s %d\n", tsv || all? ".desc": " ", p->desc, len > 0? len: 0, "", p->signature[0], p->signature[1], p->signature[2], - flashoffset, flashsize, flashpagesize, - eepromoffset, eepromsize, eeprompagesize, - nfuses, - ok, - p->flags, - dev_prog_modes(p->prog_modes), - p->config_file, p->lineno - ); + flashoffset, flashsize, flashpagesize, eepromoffset, eepromsize, eeprompagesize, nfuses, ok, p->flags, + dev_prog_modes(p->prog_modes), p->config_file, p->lineno); } if(vtabs && (up = silent_locate_uP(p)) && up->isrtable) - for(int i=0; i < up->ninterrupts; i++) + for(int i = 0; i < up->ninterrupts; i++) dev_info(".vtab\t%s\t%d\t%s\n", p->desc, i, up->isrtable[i]); if(confs && (up = silent_locate_uP(p)) && up->cfgtable) - for(int i=0; i < up->nconfigs; i++) { - const Configitem *cp = up->cfgtable+i; + for(int i = 0; i < up->nconfigs; i++) { + const Configitem *cp = up->cfgtable + i; unsigned c, n = cp->nvalues; - if(!n || !cp->vlist) { // Count bits set in mask - for(n = cp->mask, c=0; n; c++) - n &= n-1; - n = 1<vlist) { // Count bits set in mask + for(n = cp->mask, c = 0; n; c++) + n &= n - 1; + n = 1 << c; } dev_info(".cfgt\t%s\t%d\t%s\n", p->desc, n, cp->name); if(cp->vlist && verbose) - for(int k=0; k < cp->nvalues; k++) + for(int k = 0; k < cp->nvalues; k++) dev_info(".cfgv\t%s\t\tvalue\t%d\t%s\n", p->desc, cp->vlist[k].value, cp->vlist[k].label); } if(regis && (up = silent_locate_uP(p)) && up->regf) - for(int i=0; i < up->nregisters; i++) + for(int i = 0; i < up->nregisters; i++) dev_info(".regf\t%s\t0x%02x\t%d\t%s\n", p->desc, up->regf[i].addr, up->regf[i].size, up->regf[i].reg); } if(opspi) { printallopcodes(p, "part", p->op); if(p->mem) { - for(LNODEID lnm=lfirst(p->mem); lnm; lnm=lnext(lnm)) { + for(LNODEID lnm = lfirst(p->mem); lnm; lnm = lnext(lnm)) { AVRMEM *m = ldata(lnm); + if(m) printallopcodes(p, m->desc, m->op); } } } - // Print wait delays for AVR family parts if(waits) { - if(p->prog_modes & PM_ISP) + if(is_isp(p)) dev_info(".wd_chip_erase %.3f ms %s\n", p->chip_erase_delay/1000.0, p->desc); if(p->mem) { - for(LNODEID lnm=lfirst(p->mem); lnm; lnm=lnext(lnm)) { + for(LNODEID lnm = lfirst(p->mem); lnm; lnm = lnext(lnm)) { AVRMEM *m = ldata(lnm); + // Write delays not needed for read-only calibration and signature memories if(!mem_is_readonly(m)) { - if(p->prog_modes & PM_ISP) { + if(is_isp(p)) { if(m->min_write_delay == m->max_write_delay) - dev_info(".wd_%s %.3f ms %s\n", m->desc, m->min_write_delay/1000.0, p->desc); + dev_info(".wd_%s %.3f ms %s\n", m->desc, m->min_write_delay/1000.0, p->desc); else { - dev_info(".wd_min_%s %.3f ms %s\n", m->desc, m->min_write_delay/1000.0, p->desc); - dev_info(".wd_max_%s %.3f ms %s\n", m->desc, m->max_write_delay/1000.0, p->desc); + dev_info(".wd_min_%s %.3f ms %s\n", m->desc, m->min_write_delay/1000.0, p->desc); + dev_info(".wd_max_%s %.3f ms %s\n", m->desc, m->max_write_delay/1000.0, p->desc); } } } @@ -1198,7 +1224,6 @@ void dev_output_part_defs(char *partdesc) { } } - static void dev_pgm_raw(const PROGRAMMER *pgm) { PROGRAMMER dp; int len, idx; @@ -1208,27 +1233,27 @@ static void dev_pgm_raw(const PROGRAMMER *pgm) { memcpy(&dp, pgm, sizeof dp); // Dump id, usbpid and hvupdi_support lists - for(idx=0, ln=lfirst(dp.id); ln; ln=lnext(ln)) - dev_raw_dump(ldata(ln), strlen(ldata(ln))+1, id, "id", idx++); - for(idx=0, ln=lfirst(dp.usbpid); ln; ln=lnext(ln)) + for(idx = 0, ln = lfirst(dp.id); ln; ln = lnext(ln)) + dev_raw_dump(ldata(ln), strlen(ldata(ln)) + 1, id, "id", idx++); + for(idx = 0, ln = lfirst(dp.usbpid); ln; ln = lnext(ln)) dev_raw_dump(ldata(ln), sizeof(int), id, "usbpid", idx++); - for(idx=0, ln=lfirst(dp.hvupdi_support); ln; ln=lnext(ln)) + for(idx = 0, ln = lfirst(dp.hvupdi_support); ln; ln = lnext(ln)) dev_raw_dump(ldata(ln), sizeof(int), id, "hvupdi_", idx++); if(dp.desc) - dev_raw_dump(dp.desc, strlen(dp.desc)+1, id, "desc", 0); + dev_raw_dump(dp.desc, strlen(dp.desc) + 1, id, "desc", 0); // Dump cache_string values if(dp.usbdev && *dp.usbdev) - dev_raw_dump(dp.usbdev, strlen(dp.usbdev)+1, id, "usbdev", 0); + dev_raw_dump(dp.usbdev, strlen(dp.usbdev) + 1, id, "usbdev", 0); if(dp.usbsn && *dp.usbsn) - dev_raw_dump(dp.usbsn, strlen(dp.usbsn)+1, id, "usbsn", 0); + dev_raw_dump(dp.usbsn, strlen(dp.usbsn) + 1, id, "usbsn", 0); if(dp.usbvendor && *dp.usbvendor) - dev_raw_dump(dp.usbvendor, strlen(dp.usbvendor)+1, id, "usbvend", 0); + dev_raw_dump(dp.usbvendor, strlen(dp.usbvendor) + 1, id, "usbvend", 0); if(dp.usbproduct && *dp.usbproduct) - dev_raw_dump(dp.usbproduct, strlen(dp.usbproduct)+1, id, "usbprod", 0); + dev_raw_dump(dp.usbproduct, strlen(dp.usbproduct) + 1, id, "usbprod", 0); // Zap all bytes beyond terminating nul of type array - if((len = (int) strlen(dp.type)+1) < (int) sizeof dp.type) + if((len = (int) strlen(dp.type) + 1) < (int) sizeof dp.type) memset(dp.type + len, 0, sizeof dp.type - len); // Zap address values @@ -1249,25 +1274,30 @@ static void dev_pgm_raw(const PROGRAMMER *pgm) { dev_raw_dump((char *) &dp, offsetof(PROGRAMMER, fd), id, "pgm", 0); } - static const char *connstr(Conntype conntype) { switch(conntype) { - case CONNTYPE_LINUXGPIO: return "linuxgpio"; - case CONNTYPE_PARALLEL: return "parallel"; - case CONNTYPE_SERIAL: return "serial"; - case CONNTYPE_USB: return "usb"; - case CONNTYPE_SPI: return "spi"; - default: return ""; + case CONNTYPE_LINUXGPIO: + return "linuxgpio"; + case CONNTYPE_PARALLEL: + return "parallel"; + case CONNTYPE_SERIAL: + return "serial"; + case CONNTYPE_USB: + return "usb"; + case CONNTYPE_SPI: + return "spi"; + default: + return ""; } } - static char *dev_usbpid_liststr(const PROGRAMMER *pgm) { - char spc[1024]; int firstid = 1; + char spc[1024]; + int firstid = 1; spc[0] = 0; if(pgm->usbpid) - for(LNODEID ln=lfirst(pgm->usbpid); ln; ln=lnext(ln)) { + for(LNODEID ln = lfirst(pgm->usbpid); ln; ln = lnext(ln)) { if(strlen(spc) > sizeof spc - 20) break; if(!firstid) @@ -1280,11 +1310,12 @@ static char *dev_usbpid_liststr(const PROGRAMMER *pgm) { } static char *dev_hvupdi_support_liststr(const PROGRAMMER *pgm) { - char spc[1024]; int firstid = 1; + char spc[1024]; + int firstid = 1; spc[0] = 0; if(pgm->hvupdi_support) - for(LNODEID ln=lfirst(pgm->hvupdi_support); ln; ln=lnext(ln)) { + for(LNODEID ln = lfirst(pgm->hvupdi_support); ln; ln = lnext(ln)) { if(strlen(spc) > sizeof spc - 20) break; if(!firstid) @@ -1296,7 +1327,6 @@ static char *dev_hvupdi_support_liststr(const PROGRAMMER *pgm) { return mmt_strdup(*spc? spc: "NULL"); } - static void dev_pgm_strct(const PROGRAMMER *pgm, bool tsv, const PROGRAMMER *base, bool injct) { char *id = ldata(lfirst(pgm->id)); LNODEID ln; @@ -1305,11 +1335,12 @@ static void dev_pgm_strct(const PROGRAMMER *pgm, bool tsv, const PROGRAMMER *bas if(!tsv) { const char *del = "#------------------------------------------------------------"; + cp = locate_comment(pgm->comments, "*", 0); if(!cp || !dev_has_subsstr_comms(cp->comms, del)) { dev_info("%s\n# ", del); - for(firstid=1, ln=lfirst(pgm->id); ln; ln=lnext(ln)) { + for(firstid = 1, ln = lfirst(pgm->id); ln; ln = lnext(ln)) { if(!firstid) dev_info("/"); firstid = 0; @@ -1321,6 +1352,7 @@ static void dev_pgm_strct(const PROGRAMMER *pgm, bool tsv, const PROGRAMMER *bas dev_print_comment(cp->comms); const char *prog_sea = is_programmer(pgm)? "programmer": is_serialadapter(pgm)? "serialadapter": "programmer"; + if(pgm->parent_id && *pgm->parent_id) dev_info("%s parent \"%s\" # %s\n", prog_sea, pgm->parent_id, (char *) ldata(lfirst(pgm->id))); else @@ -1333,11 +1365,12 @@ static void dev_pgm_strct(const PROGRAMMER *pgm, bool tsv, const PROGRAMMER *bas dev_cout(pgm->comments, "id", 0, 0); dev_info(" %-22s = ", "id"); } - for(firstid=1, ln=lfirst(pgm->id); ln; ln=lnext(ln)) { + for(firstid = 1, ln = lfirst(pgm->id); ln; ln = lnext(ln)) { if(!firstid) dev_info(", "); firstid = 0; char *str = cfg_escape(ldata(ln)); + dev_info("%s", str); mmt_free(str); } @@ -1365,6 +1398,7 @@ static void dev_pgm_strct(const PROGRAMMER *pgm, bool tsv, const PROGRAMMER *bas if(base) { char *basestr = dev_usbpid_liststr(base); + show = !str_eq(basestr, pgmstr); mmt_free(basestr); } @@ -1378,10 +1412,11 @@ static void dev_pgm_strct(const PROGRAMMER *pgm, bool tsv, const PROGRAMMER *bas _if_pgmout_str(strcmp, cfg_escape(pgm->usbvendor), usbvendor); _if_pgmout_str(strcmp, cfg_escape(pgm->usbproduct), usbproduct); - for(int i=0; ipin+i); - const char *bstr = base? pins_to_str(base->pin+i): NULL; + for(int i = 0; i < N_PINS; i++) { + const char *str = pins_to_str(pgm->pin + i); + const char *bstr = base? pins_to_str(base->pin + i): NULL; const char *pinname = avr_pin_lcname(i); + if((!base || !str_eq(bstr, str)) && !str_eq(pinname, "")) _pgmout_fmt(pinname, "%s", str); } @@ -1391,6 +1426,7 @@ static void dev_pgm_strct(const PROGRAMMER *pgm, bool tsv, const PROGRAMMER *bas if(base) { char *basestr = dev_hvupdi_support_liststr(base); + show = !str_eq(basestr, pgmstr); mmt_free(basestr); } @@ -1400,12 +1436,11 @@ static void dev_pgm_strct(const PROGRAMMER *pgm, bool tsv, const PROGRAMMER *bas mmt_free(pgmstr); if(injct) - for(size_t i=0; iid); ln; ln=lnext(ln)) + for(LNODEID *ln = lfirst(pgm->id); ln; ln = lnext(ln)) if(str_casematch(pgminj[i].pgmid, ldata(ln))) - dev_part_strct_entry(tsv, ".prog", ldata(ln), NULL, - pgminj[i].var, mmt_strdup(pgminj[i].value), NULL); + dev_part_strct_entry(tsv, ".prog", ldata(ln), NULL, pgminj[i].var, mmt_strdup(pgminj[i].value), NULL); if(!tsv) { dev_cout(pgm->comments, ";", 0, 0); @@ -1413,19 +1448,17 @@ static void dev_pgm_strct(const PROGRAMMER *pgm, bool tsv, const PROGRAMMER *bas } } - typedef struct { int vid, pid, ishid; const char *ids; } Dev_udev; - static Dev_udev *add_udev(Dev_udev *ud, int *uip, int vid, int pid, int ishid, const char *ids) { - for(int i = 0; i < *uip; i++) // Already entered? + for(int i = 0; i < *uip; i++) // Already entered? if(ud[i].vid == vid && ud[i].pid == pid && ud[i].ishid == ishid && ud[i].ids == ids) return ud; - if(*uip % 128 == 0) - ud = (Dev_udev *) mmt_realloc(ud, sizeof*ud*(*uip+128)); + if(*uip%128 == 0) + ud = (Dev_udev *) mmt_realloc(ud, sizeof *ud*(*uip + 128)); ud[*uip].vid = vid; ud[*uip].pid = pid; @@ -1438,6 +1471,7 @@ static Dev_udev *add_udev(Dev_udev *ud, int *uip, int vid, int pid, int ishid, c static int udev_cmp_wout_ids(const Dev_udev *p1, const Dev_udev *p2) { int diff; + if((diff = p1->vid - p2->vid)) return diff; if((diff = p1->pid - p2->pid)) @@ -1469,13 +1503,12 @@ void dev_output_pgm_defs(char *pgmidcp) { if((flags = strchr(pgmidcp, '/'))) *flags++ = 0; - if(!flags && str_eq(pgmidcp, "*")) // Treat -c * as if it was -c */s + if(!flags && str_eq(pgmidcp, "*")) // Treat -c * as if it was -c */s flags = "s"; if(!*flags || !strchr("duASsrtiBUPTIJWHQ", *flags)) { dev_info("Error: flags for developer option -c / not recognised\n"); - dev_info( - "Wildcard examples (these need protecting in the shell through quoting):\n" + dev_info("Wildcard examples (these need protecting in the shell through quoting):\n" " * all known programmers\n" " avrftdi just this programmer\n" " jtag*pdi matches jtag2pdi, jtag3pdi, jtag3updi and jtag2updi\n" @@ -1500,8 +1533,7 @@ void dev_output_pgm_defs(char *pgmidcp) { " Leaving no space after -c can be an OK substitute for quoting in shells\n" " /s, /S and /A outputs are designed to be used as input in avrdude.conf\n" " Sorted /r output should stay invariant when rearranging avrdude.conf\n" - " These options are just to help development, so not further documented\n" - ); + " These options are just to help development, so not further documented\n"); return; } @@ -1509,10 +1541,10 @@ void dev_output_pgm_defs(char *pgmidcp) { strct = !!strchr(flags, 'S'); cmpst = !!strchr(flags, 's'); descs = !!strchr(flags, 'd'); - raw = !!strchr(flags, 'r'); - tsv = !!strchr(flags, 't'); + raw = !!strchr(flags, 'r'); + tsv = !!strchr(flags, 't'); injct = !!strchr(flags, 'i'); - udev = !!strchr(flags, 'u'); + udev = !!strchr(flags, 'u'); nprinted = dev_nprinted; @@ -1520,10 +1552,12 @@ void dev_output_pgm_defs(char *pgmidcp) { Dev_udev *udr = NULL; LNODEID ln1, ln2; - for(ln1=lfirst(programmers); ln1; ln1=lnext(ln1)) { + + for(ln1 = lfirst(programmers); ln1; ln1 = lnext(ln1)) { PROGRAMMER *pgm = ldata(ln1); int matched = 0; - for(ln2=lfirst(pgm->id); ln2; ln2=lnext(ln2)) { + + for(ln2 = lfirst(pgm->id); ln2; ln2 = lnext(ln2)) { if(str_casematch(pgmidcp, ldata(ln2))) { matched = 1; break; @@ -1542,44 +1576,43 @@ void dev_output_pgm_defs(char *pgmidcp) { if(astrc || strct || cmpst) dev_pgm_strct(pgm, tsv, - astrc? NULL: - strct? nullpgm: + astrc? NULL: strct? nullpgm: pgm->parent_id && *pgm->parent_id? locate_programmer(programmers, pgm->parent_id): nullpgm, injct); if(descs) - for(LNODEID idn=lfirst(pgm->id); idn; idn=lnext(idn)) { + for(LNODEID idn = lfirst(pgm->id); idn; idn = lnext(idn)) { char *id = ldata(idn); - int len = 19-strlen(id); + int len = 19 - strlen(id); + dev_info("%s '%s' =>%*s ['%s', '%s', '%s'], # %s %d\n", tsv? ".desc": " ", id, len > 0? len: 0, "", - locate_programmer_type_id(pgm->initpgm), - dev_prog_modes(pgm->prog_modes), - pgm->desc, - pgm->config_file, pgm->lineno - ); + locate_programmer_type_id(pgm->initpgm), dev_prog_modes(pgm->prog_modes), + pgm->desc, pgm->config_file, pgm->lineno); } if(udev && pgm->usbpid && (pgm->conntype == CONNTYPE_USB || is_serialadapter(pgm))) { - void (* pi)(PROGRAMMER *) = pgm->initpgm; + void (*pi)(PROGRAMMER *) = pgm->initpgm; const char *ids = cache_string(str_ccpgmids(pgm->id)); int usbvid = pgm->usbvid, ishid = pi == jtag3_initpgm || pi == jtag3_pdi_initpgm || pi == jtag3_updi_initpgm || pi == jtag3_dw_initpgm || pi == stk500v2_jtag3_initpgm || pi == jtag3_tpi_initpgm; if(!lfirst(pgm->usbpid)) { - if(pi == flip1_initpgm || pi == flip2_initpgm) { // Bootloaders, add possible part pids + if(pi == flip1_initpgm || pi == flip2_initpgm) { // Bootloaders, add possible part pids for(LNODEID lp = lfirst(part_list); lp; lp = lnext(lp)) { AVRPART *pt = ldata(lp); + if(pt->usbpid) udr = add_udev(udr, &ui, usbvid, pt->usbpid, 0, ids); } } } - for(LNODEID pidn=lfirst(pgm->usbpid); pidn; pidn=lnext(pidn)) { + for(LNODEID pidn = lfirst(pgm->usbpid); pidn; pidn = lnext(pidn)) { int pid = *(int *) ldata(pidn); + udr = add_udev(udr, &ui, usbvid, pid, ishid, ids); // Piggy back PIC Snap devices that can be switched to AVR mode @@ -1603,12 +1636,14 @@ void dev_output_pgm_defs(char *pgmidcp) { } int reboot = 0; - for(Dev_udev *u = udr; !reboot && u-udr < ui; u++) + + for(Dev_udev *u = udr; !reboot && u - udr < ui; u++) reboot |= u->ishid; if(udev && ui) { int all = str_eq(pgmidcp, "*"); const char *var = all? "": str_asciiname((char *) str_ccprintf("-%s", pgmidcp)); + dev_info("1. Examine the suggested udev rule%s below; to install run:\n\n", str_plural(ui + udr[0].ishid)); dev_info("%s -c \"%s/u\" | tail -n +%d | sudo tee /etc/udev/rules.d/55-%s%s.rules\n", progname, pgmidcp, all? 9: 11, progname, var); @@ -1616,20 +1651,20 @@ void dev_output_pgm_defs(char *pgmidcp) { dev_info("2. %s\n", reboot? "Reboot your computer": "Unplug any AVRDUDE USB programmers and plug them in again"); dev_info("3. Enjoy user access to the USB programmer(s)\n\n"); if(!all) - dev_info("Note: To install all udev rules known to AVRDUDE follow: %s -c \"*/u\" | more\n\n", - progname); + dev_info("Note: To install all udev rules known to AVRDUDE follow: %s -c \"*/u\" | more\n\n", progname); dev_info("# Generated from avrdude -c \"%s/u\"\n", pgmidcp); if(ui > 3) dev_info("\nACTION!=\"add|change\", GOTO=\"avrdude_end\"\n"); qsort(udr, ui, sizeof *udr, udev_cmp); char *prev_head = mmt_strdup(""); - for(Dev_udev *u = udr; u-udr < ui; u++) { - char head[1024] = {0}, *h = head; + + for(Dev_udev *u = udr; u - udr < ui; u++) { + char head[1024] = { 0 }, *h = head; strncpy(h, u->ids, sizeof head - 1), h += strlen(h); - for(Dev_udev *v = u+1; v-udr < ui; v++) { + for(Dev_udev *v = u + 1; v - udr < ui; v++) { if(udev_cmp_wout_ids(u, v)) break; - if((int) (strlen(v->ids) + 3 + h-head) <= (int) sizeof head) { + if((int) (strlen(v->ids) + 3 + h - head) <= (int) sizeof head) { strcpy(h, ", "), h += 2; strcpy(h, v->ids), h += strlen(v->ids); } diff --git a/src/developer_opts.h b/src/developer_opts.h index 66909b2a7..bf982f058 100644 --- a/src/developer_opts.h +++ b/src/developer_opts.h @@ -22,5 +22,4 @@ void dev_output_pgm_part(int dev_opt_c, const char *programmer, int dev_opt_p, const char *partdesc); void dev_output_part_defs(char *partdesc); void dev_output_pgm_defs(char *programmer); - #endif diff --git a/src/developer_opts_private.h b/src/developer_opts_private.h index 5e66e38da..b3973fe7f 100644 --- a/src/developer_opts_private.h +++ b/src/developer_opts_private.h @@ -31,10 +31,8 @@ #define DEV_SPI_HFUSE 512 #define DEV_SPI_EFUSE 1024 - static int dev_message(int msglvl, const char *fmt, ...); - #ifndef DEV_INFO #define DEV_INFO MSG_INFO #endif @@ -64,7 +62,8 @@ static int dev_message(int msglvl, const char *fmt, ...); #define _if_pgmout_bool(component) do { \ if(!base || !!base->component != !!pgm->component) \ - dev_part_strct_entry(tsv, ".prog", id, NULL, #component, dev_sprintf("%s", pgm->component? "true": "false"), pgm->comments); \ + dev_part_strct_entry(tsv, ".prog", id, NULL, #component, \ + dev_sprintf("%s", pgm->component? "true": "false"), pgm->comments); \ } while(0) // Result must be an mmt_malloc'd string @@ -73,7 +72,6 @@ static int dev_message(int msglvl, const char *fmt, ...); dev_part_strct_entry(tsv, ".prog", id, NULL, #component, result, pgm->comments); \ } while(0) - #define _partout(fmt, component) \ dev_part_strct_entry(tsv, ".pt", p->desc, NULL, #component, dev_sprintf(fmt, p->component), p->comments) @@ -84,7 +82,8 @@ static int dev_message(int msglvl, const char *fmt, ...); #define _if_partout_bool(component) do { \ if(!base || !!base->component != !!p->component) \ - dev_part_strct_entry(tsv, ".pt", p->desc, NULL, #component, dev_sprintf("%s", p->component? "true": "false"), p->comments); \ + dev_part_strct_entry(tsv, ".pt", p->desc, NULL, #component, \ + dev_sprintf("%s", p->component? "true": "false"), p->comments); \ } while(0) #define _if_n_partout(cmp, n, fmt, component) do { \ @@ -108,7 +107,6 @@ static int dev_message(int msglvl, const char *fmt, ...); dev_part_strct_entry(tsv, ".pt", p->desc, NULL, #component, result, p->comments); \ } while(0) - #define _memout(fmt, component) \ dev_part_strct_entry(tsv, ".ptmm", p->desc, m->desc, #component, dev_sprintf(fmt, m->component), m->comments) @@ -132,12 +130,14 @@ static int dev_message(int msglvl, const char *fmt, ...); #define _if_memout_bool(component) do { \ if(!bm || !!bm->component != !!m->component) \ - dev_part_strct_entry(tsv, ".ptmm", p->desc, m->desc, #component, dev_sprintf("%s", m->component? "true": "false"), m->comments); \ + dev_part_strct_entry(tsv, ".ptmm", p->desc, m->desc, #component, \ + dev_sprintf("%s", m->component? "true": "false"), m->comments); \ } while(0) #define _if_memout_yn(component) do { \ if(!bm || bm->component != m->component) \ - dev_part_strct_entry(tsv, ".ptmm", p->desc, m->desc, #component, mmt_strdup(m->component? "yes": "no"), m->comments); \ + dev_part_strct_entry(tsv, ".ptmm", p->desc, m->desc, #component, \ + mmt_strdup(m->component? "yes": "no"), m->comments); \ } while(0) #define _flagout(mask, name) \ @@ -151,5 +151,4 @@ static int dev_message(int msglvl, const char *fmt, ...); // Result must be an mmt_malloc'd string #define _cmderr(result, component) \ dev_part_strct_entry(tsv, ".cmderr", p->desc, m->desc, #component, result, NULL) - #endif diff --git a/src/dfu.c b/src/dfu.c index 0aea930be..6bf51a567 100644 --- a/src/dfu.c +++ b/src/dfu.c @@ -30,12 +30,11 @@ #include "dfu.h" -#include "usbdevs.h" /* for USB_VENDOR_ATMEL */ +#include "usbdevs.h" // For USB_VENDOR_ATMEL -/* If we don't have LibUSB, define dummy functions that report an error. */ +// If we don't have LibUSB, define dummy functions that report an error #ifndef HAVE_LIBUSB - struct dfu_dev *dfu_open(const char *port_name) { pmsg_error("no USB support compiled for avrdude\n"); return NULL; @@ -46,11 +45,9 @@ int dfu_init(struct dfu_dev *dfu, unsigned short usb_vid, unsigned short usb_pid } void dfu_close(struct dfu_dev *dfu) { - /* nothing */ } -int dfu_getstatus(struct dfu_dev *dfu, struct dfu_status *status) -{ +int dfu_getstatus(struct dfu_dev *dfu, struct dfu_status *status) { return -1; } @@ -58,29 +55,28 @@ int dfu_clrstatus(struct dfu_dev *dfu) { return -1; } -int dfu_download(struct dfu_dev *dfu, void * ptr, int size) { +int dfu_download(struct dfu_dev *dfu, void *ptr, int size) { return -1; } -int dfu_upload(struct dfu_dev *dfu, void * ptr, int size) { +int dfu_upload(struct dfu_dev *dfu, void *ptr, int size) { return -1; } #else -/* If we DO have LibUSB, we can define the real functions. */ +// If we DO have LibUSB, we can define the real functions -/* DFU data structures and constants. - */ +// DFU data structures and constants -#define DFU_TIMEOUT 200 /* ms */ +#define DFU_TIMEOUT 200 // ms #define DFU_DNLOAD 1 #define DFU_UPLOAD 2 #define DFU_GETSTATUS 3 #define DFU_CLRSTATUS 4 -#define DFU_GETSTATE 5 /* FLIPv1 only; not used */ -#define DFU_ABORT 6 /* FLIPv1 only */ +#define DFU_GETSTATE 5 // FLIPv1 only; not used +#define DFU_ABORT 6 // FLIPv1 only /* Block counter global variable. Incremented each time a DFU_DNLOAD command * is sent to the device. @@ -89,7 +85,7 @@ int dfu_upload(struct dfu_dev *dfu, void * ptr, int size) { /* INTERNAL FUNCTION PROTOTYPES */ -static char * get_usb_string(usb_dev_handle * dev_handle, int index); +static char *get_usb_string(usb_dev_handle *dev_handle, int index); /* EXPORTED FUNCTION DEFINITIONS */ @@ -105,17 +101,17 @@ struct dfu_dev *dfu_open(const char *port_spec) { * function, where we actually open the device. */ - if (!str_starts(port_spec, "usb")) { + if(!str_starts(port_spec, "usb")) { pmsg_error("invalid port specification %s for USB device\n", port_spec); return NULL; } if(':' == port_spec[3]) { - bus_name = mmt_strdup(port_spec + 3 + 1); + bus_name = mmt_strdup(port_spec + 3 + 1); - dev_name = strchr(bus_name, ':'); - if(NULL != dev_name) - *dev_name++ = '\0'; + dev_name = strchr(bus_name, ':'); + if(NULL != dev_name) + *dev_name++ = '\0'; } /* Allocate the dfu_dev structure and save the bus_name and dev_name @@ -128,7 +124,7 @@ struct dfu_dev *dfu_open(const char *port_spec) { dfu->dev_name = dev_name; dfu->timeout = DFU_TIMEOUT; - /* LibUSB initialization. */ + // LibUSB initialization usb_init(); usb_find_busses(); @@ -137,8 +133,7 @@ struct dfu_dev *dfu_open(const char *port_spec) { return dfu; } -int dfu_init(struct dfu_dev *dfu, unsigned short vid, unsigned short pid) -{ +int dfu_init(struct dfu_dev *dfu, unsigned short vid, unsigned short pid) { struct usb_device *found = NULL; struct usb_device *dev; struct usb_bus *bus; @@ -152,7 +147,7 @@ int dfu_init(struct dfu_dev *dfu, unsigned short vid, unsigned short pid) * we use the default vendor and product id. */ - if (pid == 0 && dfu->dev_name == NULL) { + if(pid == 0 && dfu->dev_name == NULL) { pmsg_error("no DFU support for part; specify PID in config or USB address (via -P) to override\n"); return -1; } @@ -167,23 +162,23 @@ int dfu_init(struct dfu_dev *dfu, unsigned short vid, unsigned short pid) * id, the product id must match. */ - for (bus = usb_busses; !found && bus != NULL; bus = bus->next) { - for (dev = bus->devices; !found && dev != NULL; dev = dev->next) { - if (dfu->bus_name != NULL && !str_eq(bus->dirname, dfu->bus_name)) - continue; - if (dfu->dev_name != NULL) { - if (!str_eq(dev->filename, dfu->dev_name)) + for(bus = usb_busses; !found && bus != NULL; bus = bus->next) { + for(dev = bus->devices; !found && dev != NULL; dev = dev->next) { + if(dfu->bus_name != NULL && !str_eq(bus->dirname, dfu->bus_name)) + continue; + if(dfu->dev_name != NULL) { + if(!str_eq(dev->filename, dfu->dev_name)) continue; - } else if (vid != dev->descriptor.idVendor) + } else if(vid != dev->descriptor.idVendor) continue; - else if (pid != 0 && pid != dev->descriptor.idProduct) + else if(pid != 0 && pid != dev->descriptor.idProduct) continue; found = dev; } } - if (found == NULL) { + if(found == NULL) { /* We could try to be more informative here. For example, we could report * why the match failed, and if we came across another DFU-capable part. */ @@ -193,79 +188,71 @@ int dfu_init(struct dfu_dev *dfu, unsigned short vid, unsigned short pid) } pmsg_notice2("found VID=0x%04x PID=0x%04x at %s:%s\n", - found->descriptor.idVendor, found->descriptor.idProduct, - found->bus->dirname, found->filename); + found->descriptor.idVendor, found->descriptor.idProduct, found->bus->dirname, found->filename); dfu->dev_handle = usb_open(found); - if (dfu->dev_handle == NULL) { + if(dfu->dev_handle == NULL) { pmsg_error("USB device at %s:%s: %s\n", found->bus->dirname, found->filename, usb_strerror()); return -1; } - /* Save device, configuration, interface and endpoint descriptors. */ + // Save device, configuration, interface and endpoint descriptors memcpy(&dfu->dev_desc, &found->descriptor, sizeof(dfu->dev_desc)); memcpy(&dfu->conf_desc, found->config, sizeof(dfu->conf_desc)); dfu->conf_desc.interface = NULL; - memcpy(&dfu->intf_desc, found->config->interface->altsetting, - sizeof(dfu->intf_desc)); + memcpy(&dfu->intf_desc, found->config->interface->altsetting, sizeof(dfu->intf_desc)); dfu->intf_desc.endpoint = &dfu->endp_desc; - if (found->config->interface->altsetting->endpoint != 0) - memcpy(&dfu->endp_desc, found->config->interface->altsetting->endpoint, - sizeof(dfu->endp_desc)); + if(found->config->interface->altsetting->endpoint != 0) + memcpy(&dfu->endp_desc, found->config->interface->altsetting->endpoint, sizeof(dfu->endp_desc)); - /* Get strings. */ + // Get strings - dfu->manf_str = get_usb_string(dfu->dev_handle, - dfu->dev_desc.iManufacturer); + dfu->manf_str = get_usb_string(dfu->dev_handle, dfu->dev_desc.iManufacturer); - dfu->prod_str = get_usb_string(dfu->dev_handle, - dfu->dev_desc.iProduct); + dfu->prod_str = get_usb_string(dfu->dev_handle, dfu->dev_desc.iProduct); - dfu->serno_str = get_usb_string(dfu->dev_handle, - dfu->dev_desc.iSerialNumber); + dfu->serno_str = get_usb_string(dfu->dev_handle, dfu->dev_desc.iSerialNumber); return 0; } -void dfu_close(struct dfu_dev *dfu) -{ - if (dfu->dev_handle != NULL) +void dfu_close(struct dfu_dev *dfu) { + if(dfu->dev_handle != NULL) usb_close(dfu->dev_handle); - if (dfu->bus_name != NULL) + if(dfu->bus_name != NULL) mmt_free(dfu->bus_name); - if (dfu->manf_str != NULL) + if(dfu->manf_str != NULL) mmt_free(dfu->manf_str); - if (dfu->prod_str != NULL) + if(dfu->prod_str != NULL) mmt_free(dfu->prod_str); - if (dfu->serno_str != NULL) + if(dfu->serno_str != NULL) mmt_free(dfu->serno_str); } -int dfu_getstatus(struct dfu_dev *dfu, struct dfu_status *status) -{ +int dfu_getstatus(struct dfu_dev *dfu, struct dfu_status *status) { int result; pmsg_trace("%s(): issuing control IN message\n", __func__); result = usb_control_msg(dfu->dev_handle, 0x80 | USB_TYPE_CLASS | USB_RECIP_INTERFACE, DFU_GETSTATUS, 0, 0, - (char*) status, sizeof(struct dfu_status), dfu->timeout); + (char *) status, sizeof(struct dfu_status), dfu->timeout); - if (result < 0) { + if(result < 0) { pmsg_error("unable to get DFU status: %s\n", usb_strerror()); return -1; } - if (result < (int) sizeof(struct dfu_status)) { + if(result < (int) sizeof(struct dfu_status)) { pmsg_error("unable to get DFU status: %s\n", "short read"); return -1; } - if (result > (int) sizeof(struct dfu_status)) { + if(result > (int) sizeof(struct dfu_status)) { pmsg_error("oversize read (should not happen)\n"); return -1; } @@ -273,23 +260,20 @@ int dfu_getstatus(struct dfu_dev *dfu, struct dfu_status *status) pmsg_trace("%s(): bStatus 0x%02x, bwPollTimeout %d, bState 0x%02x, iString %d\n", __func__, status->bStatus, status->bwPollTimeout[0] | (status->bwPollTimeout[1] << 8) | (status->bwPollTimeout[2] << 16), - status->bState, - status->iString); + status->bState, status->iString); return 0; } -int dfu_clrstatus(struct dfu_dev *dfu) -{ +int dfu_clrstatus(struct dfu_dev *dfu) { int result; pmsg_trace("%s(): issuing control OUT message\n", __func__); - result = usb_control_msg(dfu->dev_handle, - USB_TYPE_CLASS | USB_RECIP_INTERFACE, DFU_CLRSTATUS, 0, 0, - NULL, 0, dfu->timeout); + result = usb_control_msg(dfu->dev_handle, USB_TYPE_CLASS | USB_RECIP_INTERFACE, + DFU_CLRSTATUS, 0, 0, NULL, 0, dfu->timeout); - if (result < 0) { + if(result < 0) { pmsg_error("unable to clear DFU status: %s\n", usb_strerror()); return -1; } @@ -297,17 +281,15 @@ int dfu_clrstatus(struct dfu_dev *dfu) return 0; } -int dfu_abort(struct dfu_dev *dfu) -{ +int dfu_abort(struct dfu_dev *dfu) { int result; pmsg_trace("%s(): issuing control OUT message\n", __func__); - result = usb_control_msg(dfu->dev_handle, - USB_TYPE_CLASS | USB_RECIP_INTERFACE, DFU_ABORT, 0, 0, - NULL, 0, dfu->timeout); + result = usb_control_msg(dfu->dev_handle, USB_TYPE_CLASS | USB_RECIP_INTERFACE, + DFU_ABORT, 0, 0, NULL, 0, dfu->timeout); - if (result < 0) { + if(result < 0) { pmsg_error("unable to reset DFU state: %s\n", usb_strerror()); return -1; } @@ -315,29 +297,26 @@ int dfu_abort(struct dfu_dev *dfu) return 0; } - -int dfu_dnload(struct dfu_dev *dfu, void *ptr, int size) -{ +int dfu_dnload(struct dfu_dev *dfu, void *ptr, int size) { int result; - pmsg_trace("%s(): issuing control OUT message, wIndex = %d, ptr = %p, size = %d\n", __func__, - cx->dfu_wIndex, ptr, size); + pmsg_trace("%s(): issuing control OUT message, wIndex = %d, ptr = %p, size = %d\n", + __func__, cx->dfu_wIndex, ptr, size); - result = usb_control_msg(dfu->dev_handle, - USB_TYPE_CLASS | USB_RECIP_INTERFACE, DFU_DNLOAD, cx->dfu_wIndex++, 0, - ptr, size, dfu->timeout); + result = usb_control_msg(dfu->dev_handle, USB_TYPE_CLASS | USB_RECIP_INTERFACE, + DFU_DNLOAD, cx->dfu_wIndex++, 0, ptr, size, dfu->timeout); - if (result < 0) { + if(result < 0) { pmsg_error("DFU_DNLOAD failed: %s\n", usb_strerror()); return -1; } - if (result < size) { + if(result < size) { pmsg_error("DFU_DNLOAD failed: short write\n"); return -1; } - if (result > size) { + if(result > size) { pmsg_error("DFU_DNLOAD failed: oversize write (should not happen)\n"); return -1; } @@ -345,28 +324,26 @@ int dfu_dnload(struct dfu_dev *dfu, void *ptr, int size) return 0; } -int dfu_upload(struct dfu_dev *dfu, void *ptr, int size) -{ +int dfu_upload(struct dfu_dev *dfu, void *ptr, int size) { int result; - pmsg_trace("%s(): issuing control IN message, wIndex = %d, ptr = %p, size = %d\n", __func__, - cx->dfu_wIndex, ptr, size); + pmsg_trace("%s(): issuing control IN message, wIndex = %d, ptr = %p, size = %d\n", + __func__, cx->dfu_wIndex, ptr, size); - result = usb_control_msg(dfu->dev_handle, - 0x80 | USB_TYPE_CLASS | USB_RECIP_INTERFACE, DFU_UPLOAD, cx->dfu_wIndex++, 0, - ptr, size, dfu->timeout); + result = usb_control_msg(dfu->dev_handle, 0x80 | USB_TYPE_CLASS | USB_RECIP_INTERFACE, + DFU_UPLOAD, cx->dfu_wIndex++, 0, ptr, size, dfu->timeout); - if (result < 0) { + if(result < 0) { pmsg_error("DFU_UPLOAD failed: %s\n", usb_strerror()); return -1; } - if (result < size) { + if(result < size) { pmsg_error("DFU_UPLOAD failed: %s\n", "short read"); return -1; } - if (result > size) { + if(result > size) { pmsg_error("oversize read (should not happen)\n"); return -1; } @@ -374,100 +351,118 @@ int dfu_upload(struct dfu_dev *dfu, void *ptr, int size) return 0; } -void dfu_show_info(struct dfu_dev *dfu) -{ - if (dfu->manf_str != NULL) - msg_info(" USB Vendor : %s (0x%04hX)\n", - dfu->manf_str, (unsigned short) dfu->dev_desc.idVendor); +void dfu_show_info(struct dfu_dev *dfu) { + if(dfu->manf_str != NULL) + msg_info(" USB Vendor : %s (0x%04hX)\n", dfu->manf_str, (unsigned short) dfu->dev_desc.idVendor); else - msg_info(" USB Vendor : 0x%04hX\n", - (unsigned short) dfu->dev_desc.idVendor); + msg_info(" USB Vendor : 0x%04hX\n", (unsigned short) dfu->dev_desc.idVendor); - if (dfu->prod_str != NULL) - msg_info(" USB Product : %s (0x%04hX)\n", - dfu->prod_str, (unsigned short) dfu->dev_desc.idProduct); + if(dfu->prod_str != NULL) + msg_info(" USB Product : %s (0x%04hX)\n", dfu->prod_str, (unsigned short) dfu->dev_desc.idProduct); else - msg_info(" USB Product : 0x%04hX\n", - (unsigned short) dfu->dev_desc.idProduct); + msg_info(" USB Product : 0x%04hX\n", (unsigned short) dfu->dev_desc.idProduct); msg_info(" USB Release : %u.%u.%u\n", - (dfu->dev_desc.bcdDevice >> 8) & 0xFF, - (dfu->dev_desc.bcdDevice >> 4) & 0xF, - (dfu->dev_desc.bcdDevice >> 0) & 0xF); + (dfu->dev_desc.bcdDevice >> 8) & 0xFF, (dfu->dev_desc.bcdDevice >> 4) & 0xF, (dfu->dev_desc.bcdDevice >> 0) & 0xF); - if (dfu->serno_str != NULL) + if(dfu->serno_str != NULL) msg_info(" USB Serial No : %s\n", dfu->serno_str); } /* INTERNAL FUNCTION DEFINITIONS */ -char * get_usb_string(usb_dev_handle * dev_handle, int index) { +char *get_usb_string(usb_dev_handle *dev_handle, int index) { char buffer[256]; - char * str; + char *str; int result; - if (index == 0) + if(index == 0) return NULL; - result = usb_get_string_simple(dev_handle, index, buffer, sizeof(buffer)-1); + result = usb_get_string_simple(dev_handle, index, buffer, sizeof(buffer) - 1); - if (result < 0) { + if(result < 0) { cx->usb_access_error = 1; pmsg_error("unable to read USB device string %d: %s\n", index, usb_strerror()); return NULL; } - str = mmt_malloc(result+1); + str = mmt_malloc(result + 1); memcpy(str, buffer, result); str[result] = '\0'; return str; } - -#endif /* defined(HAVE_LIBUSB) */ +#endif // defined(HAVE_LIBUSB) /* EXPORTED FUNCTIONS THAT DO NO REQUIRE LIBUSB */ -const char * dfu_status_str(int bStatus) -{ - switch (bStatus) { - case DFU_STATUS_OK: return "OK"; - case DFU_STATUS_ERR_TARGET: return "ERR_TARGET"; - case DFU_STATUS_ERR_FILE: return "ERR_FILE"; - case DFU_STATUS_ERR_WRITE: return "ERR_WRITE"; - case DFU_STATUS_ERR_ERASE: return "ERR_ERASE"; - case DFU_STATUS_ERR_CHECK_ERASED: return "ERR_CHECK_ERASED"; - case DFU_STATUS_ERR_PROG: return "ERR_PROG"; - case DFU_STATUS_ERR_VERIFY: return "ERR_VERIFY"; - case DFU_STATUS_ERR_ADDRESS: return "ERR_ADDRESS"; - case DFU_STATUS_ERR_NOTDONE: return "ERR_NOTDONE"; - case DFU_STATUS_ERR_FIRMWARE: return "ERR_FIRMWARE"; - case DFU_STATUS_ERR_VENDOR: return "ERR_VENDOR"; - case DFU_STATUS_ERR_USBR: return "ERR_USBR"; - case DFU_STATUS_ERR_POR: return "ERR_POR"; - case DFU_STATUS_ERR_UNKNOWN: return "ERR_UNKNOWN"; - case DFU_STATUS_ERR_STALLEDPKT: return "ERR_STALLEDPKT"; - default: return "Unknown"; +const char *dfu_status_str(int bStatus) { + switch(bStatus) { + case DFU_STATUS_OK: + return "OK"; + case DFU_STATUS_ERR_TARGET: + return "ERR_TARGET"; + case DFU_STATUS_ERR_FILE: + return "ERR_FILE"; + case DFU_STATUS_ERR_WRITE: + return "ERR_WRITE"; + case DFU_STATUS_ERR_ERASE: + return "ERR_ERASE"; + case DFU_STATUS_ERR_CHECK_ERASED: + return "ERR_CHECK_ERASED"; + case DFU_STATUS_ERR_PROG: + return "ERR_PROG"; + case DFU_STATUS_ERR_VERIFY: + return "ERR_VERIFY"; + case DFU_STATUS_ERR_ADDRESS: + return "ERR_ADDRESS"; + case DFU_STATUS_ERR_NOTDONE: + return "ERR_NOTDONE"; + case DFU_STATUS_ERR_FIRMWARE: + return "ERR_FIRMWARE"; + case DFU_STATUS_ERR_VENDOR: + return "ERR_VENDOR"; + case DFU_STATUS_ERR_USBR: + return "ERR_USBR"; + case DFU_STATUS_ERR_POR: + return "ERR_POR"; + case DFU_STATUS_ERR_UNKNOWN: + return "ERR_UNKNOWN"; + case DFU_STATUS_ERR_STALLEDPKT: + return "ERR_STALLEDPKT"; + default: + return "Unknown"; } } -const char * dfu_state_str(int bState) -{ - switch (bState) { - case DFU_STATE_APP_IDLE: return "APP_IDLE"; - case DFU_STATE_APP_DETACH: return "APP_DETACH"; - case DFU_STATE_DFU_IDLE: return "DFU_IDLE"; - case DFU_STATE_DFU_DLOAD_SYNC: return "DFU_DLOAD_SYNC"; - case DFU_STATE_DFU_DNBUSY: return "DFU_DNBUSY"; - case DFU_STATE_DFU_DNLOAD_IDLE: return "DFU_DNLOAD_IDLE"; - case DFU_STATE_DFU_MANIFEST_SYNC: return "DFU_MANIFEST_SYNC"; - case DFU_STATE_DFU_MANIFEST: return "DFU_MANIFEST"; - case DFU_STATE_DFU_MANIFEST_WAIT_RESET: return "DFU_MANIFEST_WAIT_RESET"; - case DFU_STATE_DFU_UPLOAD_IDLE: return "DFU_UPLOAD_IDLE"; - case DFU_STATE_DFU_ERROR: return "DFU_ERROR"; - default: return "Unknown"; +const char *dfu_state_str(int bState) { + switch(bState) { + case DFU_STATE_APP_IDLE: + return "APP_IDLE"; + case DFU_STATE_APP_DETACH: + return "APP_DETACH"; + case DFU_STATE_DFU_IDLE: + return "DFU_IDLE"; + case DFU_STATE_DFU_DLOAD_SYNC: + return "DFU_DLOAD_SYNC"; + case DFU_STATE_DFU_DNBUSY: + return "DFU_DNBUSY"; + case DFU_STATE_DFU_DNLOAD_IDLE: + return "DFU_DNLOAD_IDLE"; + case DFU_STATE_DFU_MANIFEST_SYNC: + return "DFU_MANIFEST_SYNC"; + case DFU_STATE_DFU_MANIFEST: + return "DFU_MANIFEST"; + case DFU_STATE_DFU_MANIFEST_WAIT_RESET: + return "DFU_MANIFEST_WAIT_RESET"; + case DFU_STATE_DFU_UPLOAD_IDLE: + return "DFU_UPLOAD_IDLE"; + case DFU_STATE_DFU_ERROR: + return "DFU_ERROR"; + default: + return "Unknown"; } } - diff --git a/src/dfu.h b/src/dfu.h index 03d2fc46a..3e26f010a 100644 --- a/src/dfu.h +++ b/src/dfu.h @@ -22,12 +22,13 @@ #include #ifdef HAVE_LIBUSB + #if defined(HAVE_USB_H) -# include +#include #elif defined(HAVE_LUSB0_USB_H) -# include +#include #else -# error "libusb needs either or " +#error "libusb needs either or " #endif #endif @@ -37,45 +38,41 @@ extern "C" { #endif -/* If we have LIBUSB, define the dfu_dev struct normally. Otherwise, declare - * it as an empty struct so that code compiles, but we generate an error at - * run time. +/* + * If we have LIBUSB, define the dfu_dev struct normally. Otherwise, declare it + * as an empty struct so that code compiles and we generate an error at run + * time. */ #ifdef HAVE_LIBUSB - -struct dfu_dev -{ - char *bus_name, *dev_name; - usb_dev_handle *dev_handle; - struct usb_device_descriptor dev_desc; - struct usb_config_descriptor conf_desc; - struct usb_interface_descriptor intf_desc; - struct usb_endpoint_descriptor endp_desc; - char *manf_str, *prod_str, *serno_str; - unsigned int timeout; -}; + struct dfu_dev { + char *bus_name, *dev_name; + usb_dev_handle *dev_handle; + struct usb_device_descriptor dev_desc; + struct usb_config_descriptor conf_desc; + struct usb_interface_descriptor intf_desc; + struct usb_endpoint_descriptor endp_desc; + char *manf_str, *prod_str, *serno_str; + unsigned int timeout; + }; #else -struct dfu_dev { - int dummy; -}; - + struct dfu_dev { + int dummy; + }; #endif -/* We assume unsigned char is 1 byte. */ - #if UCHAR_MAX != 255 #error UCHAR_MAX != 255 #endif -struct dfu_status { - unsigned char bStatus; - unsigned char bwPollTimeout[3]; - unsigned char bState; - unsigned char iString; -}; + struct dfu_status { + unsigned char bStatus; + unsigned char bwPollTimeout[3]; + unsigned char bState; + unsigned char iString; + }; // Values of bStatus field. @@ -112,24 +109,23 @@ struct dfu_status { // FUNCTIONS -extern struct dfu_dev *dfu_open(const char *port_spec); -extern int dfu_init(struct dfu_dev *dfu, - unsigned short vid, unsigned short pid); -extern void dfu_close(struct dfu_dev *dfu); + extern struct dfu_dev *dfu_open(const char *port_spec); + extern int dfu_init(struct dfu_dev *dfu, unsigned short vid, unsigned short pid); + extern void dfu_close(struct dfu_dev *dfu); -extern int dfu_getstatus(struct dfu_dev *dfu, struct dfu_status *status); -extern int dfu_clrstatus(struct dfu_dev *dfu); -extern int dfu_dnload(struct dfu_dev *dfu, void *ptr, int size); -extern int dfu_upload(struct dfu_dev *dfu, void *ptr, int size); -extern int dfu_abort(struct dfu_dev *dfu); + extern int dfu_getstatus(struct dfu_dev *dfu, struct dfu_status *status); + extern int dfu_clrstatus(struct dfu_dev *dfu); + extern int dfu_dnload(struct dfu_dev *dfu, void *ptr, int size); + extern int dfu_upload(struct dfu_dev *dfu, void *ptr, int size); + extern int dfu_abort(struct dfu_dev *dfu); -extern void dfu_show_info(struct dfu_dev *dfu); + extern void dfu_show_info(struct dfu_dev *dfu); -extern const char * dfu_status_str(int bStatus); -extern const char * dfu_state_str(int bState); + extern const char *dfu_status_str(int bStatus); + extern const char *dfu_state_str(int bState); #ifdef __cplusplus } #endif -#endif /* dfu_h */ +#endif diff --git a/src/disasm.c b/src/disasm.c index cb6a657fb..33cc70db2 100644 --- a/src/disasm.c +++ b/src/disasm.c @@ -1,5 +1,5 @@ /* - * AVRDUDE - A Downloader/Uploader for AVR device programmers + * avrdude - A Downloader/Uploader for AVR device programmers * Copyright (C) 2007 Johannes Bauer * Copyright (C) 2024 by Stefan Rueger * @@ -17,15 +17,13 @@ * along with this program. If not, see . */ -/* $Id$ */ - /* * This disassembly code originates from the avrdisas disassembler written in * 2007 by Johannes Bauer. It has been rewritten by Stefan Rueger to - * - Enable disassembly of small memory chunks in AVRDUDE's terminal - * - Drive disassembly from the avr_opcodes[] table alone - * - Generate a compilable source - * - Find symbolic values for ldi constants that initialise register pais + * - Enable disassembly of small memory chunks in AVRDUDE's terminal + * - Drive disassembly from the avr_opcodes[] table alone + * - Generate a compilable source + * - Find symbolic values for ldi constants that initialise register pais * * Like the ship of Theseus there is little of the avrdisas orginal code that * has remained, but it is fair to say that without it the AVRDUDE disasm @@ -51,7 +49,6 @@ #define buf2op16(i) ((buf[i] & 0xff) | (buf[(i)+1] & 0xff)<<8) - static void zap_symbols() { if(cx->dis_symbols) { for(int i = 0; i < cx->dis_symbolN; i++) { @@ -66,17 +63,23 @@ static void zap_symbols() { static int type_order(int type) { switch(type) { - case 'I': return '1'; - case 'M': return '2'; - case 'L': return '3'; - case 'P': return '4'; - default: return type; + case 'I': + return '1'; + case 'M': + return '2'; + case 'L': + return '3'; + case 'P': + return '4'; + default: + return type; } } static int symbol_sort(const void *v1, const void *v2) { const Dis_symbol *p1 = v1, *p2 = v2; int diff; + if((diff = type_order(p1->type) - type_order(p2->type))) return diff; return p1->address - p2->address; @@ -84,9 +87,10 @@ static int symbol_sort(const void *v1, const void *v2) { static int symbol_stable_qsort(const void *v1, const void *v2) { int diff = symbol_sort(v1, v2); + if(diff) return diff; - return (char *) v1 - (char *) v2; // Keep original order if same keys (stable sort) + return (char *) v1 - (char *) v2; // Keep original order if same keys (stable sort) } static char *cleanup(char *str) { @@ -97,7 +101,7 @@ static char *cleanup(char *str) { // Width of memory a symbol covers static int symbol_width(Dis_symbol *s) { - return s->count * (s->subtype == TYPE_WORD? 2: 1); + return s->count*(s->subtype == TYPE_WORD? 2: 1); } static Dis_symbol *find_symbol(int type, int address) { @@ -109,22 +113,23 @@ static Dis_symbol *find_symbol(int type, int address) { return NULL; // Determine m as first matching symbol that has smallest width - int k = found - s, m = k, w, width = symbol_width(s+k); + int k = found - s, m = k, w, width = symbol_width(s + k); - for(int i = k-1; i >= 0 && symbol_sort(s+i, s+k) == 0; i--) - if((w = symbol_width(s+i)) <= width) // Want first entry of those with same min width + for(int i = k - 1; i >= 0 && symbol_sort(s + i, s + k) == 0; i--) + if((w = symbol_width(s + i)) <= width) // Want first entry of those with same min width m = i, width = w; - for(int i = k+1; i < cx->dis_symbolN && symbol_sort(s+i, s+k) == 0; i++) - if((w = symbol_width(s+i)) < width) // < is deliberate, see above + for(int i = k + 1; i < cx->dis_symbolN && symbol_sort(s + i, s + k) == 0; i++) + if((w = symbol_width(s + i)) < width) // < is deliberate, see above m = i, width = w; - return s+m; + return s + m; } static void add_symbol(int addr, int type, int sub, int count, const char *name, const char *com) { int N = cx->dis_symbolN++; - if(N % 1024 == 0) - cx->dis_symbols = (Dis_symbol *) mmt_realloc(cx->dis_symbols, sizeof(Dis_symbol)*(N+1024)); + + if(N%1024 == 0) + cx->dis_symbols = (Dis_symbol *) mmt_realloc(cx->dis_symbols, sizeof(Dis_symbol)*(N + 1024)); cx->dis_symbols[N].address = addr; cx->dis_symbols[N].type = type; cx->dis_symbols[N].subtype = sub; @@ -137,9 +142,9 @@ static void add_symbol(int addr, int type, int sub, int count, const char *name, /* * Tokenising of a tagfile line returning (argc, argv); parsing ends when - * - A token starts with a comment character # - * - The comment field after the name of the symbol is encountered - * - The end of the string is encountered + * - A token starts with a comment character # + * - The comment field after the name of the symbol is encountered + * - The end of the string is encountered * * Argv is allocated once, so the caller only needs to mmt_free argv. * On error NULL is returned (when input line was too long). @@ -152,7 +157,7 @@ static int tagfile_tokenize(char *s, int *argcp, const char ***argvp) { char *buf, *q, *r; // Upper estimate of the number of arguments - for(nargs=0, q=s; *q; nargs++) { + for(nargs = 0, q = s; *q; nargs++) { while(*q && !isspace((unsigned char) *q)) q++; while(*q && isspace((unsigned char) *q)) @@ -161,26 +166,26 @@ static int tagfile_tokenize(char *s, int *argcp, const char ***argvp) { slen = q - s; // Limit input line to some 186 Megabytes as max nargs is (slen+1)/2 - if(slen > 2*((INT_MAX - 2*sizeof(char *))/(sizeof(char *)+3))) + if(slen > 2*((INT_MAX - 2*sizeof(char *))/(sizeof(char *) + 3))) return 0; // Allocate once for pointers and contents, so caller only needs to mmt_free(argv) - argv = mmt_malloc((nargs+2)*sizeof(char *) + slen + nargs); - buf = (char *) (argv+nargs+1); + argv = mmt_malloc((nargs + 2)*sizeof(char *) + slen + nargs); + buf = (char *) (argv + nargs + 1); - for(n=0, r=s; *r; ) { + for(n = 0, r = s; *r;) { q = str_nexttok(r, " \t\n\r\v\f", &r); size_t len = strlen(q); if(*q == '#') { // Inline comment: ignore rest of line - r = q+len; + r = q + len; break; } strcpy(buf, q); if(*buf) // Don't record empty arguments argv[n++] = buf; - if(n > 1 && n == (str_eq(argv[1], "L")? 3: 5)) { // Stop parsing after symbol name + if(n > 1 && n == (str_eq(argv[1], "L")? 3: 5)) { // Stop parsing after symbol name if(*r) argv[n] = r; // Comment, if any break; @@ -197,9 +202,9 @@ static int tagfile_tokenize(char *s, int *argcp, const char ***argvp) { #define Return(fmt, ...) do { \ pmsg_error("tagfile line %d " fmt, lineno, __VA_ARGS__); msg_error("\n"); \ return -1; \ -} while (0) +} while(0) -static int tagfile_readline(char *line, int lineno, const char * const *isrnames, int ni) { +static int tagfile_readline(char *line, int lineno, const char *const *isrnames, int ni) { int type, subtype, vn, address, count, argc = 0; const char *errptr, **argv = NULL; @@ -220,8 +225,9 @@ static int tagfile_readline(char *line, int lineno, const char * const *isrnames if(type == 'L') { const char *name = argv[2]; + if(str_starts(name, "__vector_") && looks_like_number(name + 9)) - if((vn = strtol(name+9, NULL, 0)) > 0 && vn < ni) // Don't replace __vectors_0 + if((vn = strtol(name + 9, NULL, 0)) > 0 && vn < ni) // Don't replace __vectors_0 name = str_lc((char *) str_ccprintf("__vector_%s", isrnames[vn])); add_symbol(address, 'L', TYPE_BYTE, 1, name, argv[3]); return 0; @@ -231,10 +237,17 @@ static int tagfile_readline(char *line, int lineno, const char * const *isrnames Return("needs to be
%c [%s] ", type, type == 'M'? "BW": "BWAS"); switch(*argv[2]) { - default: subtype = TYPE_BYTE; break; - case 'W': subtype = TYPE_WORD; break; - case 'A': subtype = TYPE_ASTRING; break; - case 'S': subtype = TYPE_STRING; + default: + subtype = TYPE_BYTE; + break; + case 'W': + subtype = TYPE_WORD; + break; + case 'A': + subtype = TYPE_ASTRING; + break; + case 'S': + subtype = TYPE_STRING; } if(type == 'M' && subtype != TYPE_BYTE && subtype != TYPE_WORD) { @@ -257,8 +270,7 @@ static int tagfile_readline(char *line, int lineno, const char * const *isrnames static char *regname(const char *pre, const char *reg, int suf) { char *ret = suf <= -1? mmt_sprintf("%s%s", pre, reg): - suf == 'h' || suf == 'l'? mmt_sprintf("%s%s%c", pre, reg, suf): - mmt_sprintf("%s%s%d", pre, reg, suf); + suf == 'h' || suf == 'l'? mmt_sprintf("%s%s%c", pre, reg, suf): mmt_sprintf("%s%s%d", pre, reg, suf); return cleanup(ret); } @@ -266,7 +278,8 @@ static char *regname(const char *pre, const char *reg, int suf) { // Return the basename of a register, ie, the part after the first . (if any) static const char *regbase(const char *reg) { const char *ret = strchr(reg, '.'); - return ret? ret+1: reg; + + return ret? ret + 1: reg; } // Return the basename of rf[i].reg if that's unique amongst the nr register entries @@ -274,7 +287,7 @@ static const char *shortrname(const Register_file *rf, int nr, int i) { const char *f = rf[i].reg, *s = regbase(f); if(f != s) - for(int k=0; ksize > 1 && mem->offset <= 0x200) { add_symbol(mem->offset, 'M', TYPE_BYTE, mem->size, "sram.start", NULL); - add_symbol(mem->offset+mem->size-1, 'M', TYPE_BYTE, 1, "sram.end", NULL); + add_symbol(mem->offset + mem->size - 1, 'M', TYPE_BYTE, 1, "sram.end", NULL); } if(rf) { for(int i = 0; i < nr; i++) { @@ -305,10 +318,10 @@ static void init_regfile(const AVRPART *p) { add_register(io_off, rf[i].addr, rname, -1); } else if(rf[i].size == 2) { add_register(io_off, rf[i].addr, rname, 'l'); - add_register(io_off, rf[i].addr+1, rname, 'h'); + add_register(io_off, rf[i].addr + 1, rname, 'h'); } else if(rf[i].size > 2) { for(int k = 0; k < rf[i].size; k++) - add_register(io_off, rf[i].addr+k, rname, k); + add_register(io_off, rf[i].addr + k, rname, k); } } qsort(cx->dis_symbols, cx->dis_symbolN, sizeof(Dis_symbol), symbol_stable_qsort); @@ -319,7 +332,7 @@ int disasm_init_tagfile(const AVRPART *p, const char *fname) { FILE *inf = fopen(fname, "r"); int ni = 0, lineno = 1; const char *errstr; - const char * const * isrnames = avr_locate_isrtable(p, &ni); + const char *const *isrnames = avr_locate_isrtable(p, &ni); if(!inf) { pmsg_ext_error("cannot open tagfile %s: %s\n", fname, strerror(errno)); @@ -365,13 +378,14 @@ static const char *cycles(int mnemo) { // A plus sign after the cycle number means add one for 3-byte PC if(*ret && ret[1] == '+') - return str_ccprintf("%c", cx->dis_flashsz > 128*1024? *ret+1: *ret); + return str_ccprintf("%c", cx->dis_flashsz > 128*1024? *ret + 1: *ret); return ret; } static const char *get_label_name(int destination, const char **commentp) { Dis_symbol *s = find_symbol('L', destination); + if(s && s->name) { if(commentp) *commentp = s->comment; @@ -381,8 +395,7 @@ static const char *get_label_name(int destination, const char **commentp) { for(int i = 0; i < cx->dis_jumpcallN; i++) if(cx->dis_jumpcalls[i].to == destination) - return str_ccprintf("%s%d", cx->dis_jumpcalls[i].is_func? "Subroutine": "Label", - cx->dis_jumpcalls[i].labelno); + return str_ccprintf("%s%d", cx->dis_jumpcalls[i].is_func? "Subroutine": "Label", cx->dis_jumpcalls[i].labelno); return NULL; } @@ -390,7 +403,7 @@ static const char *get_label_name(int destination, const char **commentp) { // Wrap around flash static int disasm_wrap(int addr) { if(cx->dis_flashsz2) - addr &= cx->dis_flashsz2-1; + addr &= cx->dis_flashsz2 - 1; return addr; } @@ -412,6 +425,7 @@ typedef struct { // Opcode starts in codecol() static int codecol() { int ret = 0; + if(cx->dis_opts.addresses) ret += 3 + cx->dis_addrwidth; if(cx->dis_opts.sreg_flags) @@ -421,7 +435,7 @@ static int codecol() { if(cx->dis_opts.opcode_bytes) ret += 12; - return (ret? ret+1: 2); + return (ret? ret + 1: 2); } // Comments start in commentcol() + 1 @@ -434,18 +448,26 @@ static int is_jumpable(int address) { return 0; int n = sizeof(int)*8, idx = (address - cx->dis_start)/2; - return cx->dis_jumpable[idx/n] & (1<<(idx%n)); + + return cx->dis_jumpable[idx/n] & (1 << (idx%n)); } // Format output for a label list r referenced by mnemonic m static void output_references(const char *m, char *r) { - disasm_out("; %c%s from ", toupper(*m), m+1); - for(char *s = r; ; ) { - char *c = strchr(s+1, ','); - if(c && c-r > 80 && s > r) { - *s = 0; disasm_out("%s\n; %*s ", r, (int) strlen(m), ""); r = (char *) str_ltrim(s+1); s = r; - } else if(c && c-r > 70) { - *c = 0; disasm_out("%s\n; %*s ", r, (int) strlen(m), ""); r = (char *) str_ltrim(c+1); s = r; + disasm_out("; %c%s from ", toupper(*m), m + 1); + for(char *s = r;;) { + char *c = strchr(s + 1, ','); + + if(c && c - r > 80 && s > r) { + *s = 0; + disasm_out("%s\n; %*s ", r, (int) strlen(m), ""); + r = (char *) str_ltrim(s + 1); + s = r; + } else if(c && c - r > 70) { + *c = 0; + disasm_out("%s\n; %*s ", r, (int) strlen(m), ""); + r = (char *) str_ltrim(c + 1); + s = r; } else if(c) { s = c; } else { @@ -472,23 +494,26 @@ static void lineout(const char *code, const char *comment, if(cx->dis_pass == 2 && match) { cx->dis_para++; - char *reflist = mmt_malloc(match*(3+64)), *r = reflist; // Worst case length + char *reflist = mmt_malloc(match*(3 + 64)), *r = reflist; // Worst case length int mne = jc[first].mnemo, one_mne = 1; + for(int i = first; i < cx->dis_jumpcallN && jc[i].to == here; i++) { - if(mne != jc[i].mnemo) { // More than one mnemonic reference this line + if(mne != jc[i].mnemo) { // More than one mnemonic reference this line one_mne = 0; output_references(avr_opcodes[mne].opcode, reflist); mne = jc[i].mnemo; - r = reflist; *r = 0; + r = reflist; + *r = 0; } - strcpy(r, str_ccprintf(&", L%0*x"[2*(r==reflist)], cx->dis_addrwidth, jc[i].from)); + strcpy(r, str_ccprintf(&", L%0*x"[2*(r == reflist)], cx->dis_addrwidth, jc[i].from)); r += strlen(r); } name = get_label_name(here, &comment); - if(!comment && strlen(reflist) + commentcol() < 70 && one_mne) { // Refs line with label + if(!comment && strlen(reflist) + commentcol() < 70 && one_mne) { // Refs line with label const char *mnestr = avr_opcodes[mne].opcode; + disasm_out("%-*s ; %s\n", commentcol(), str_ccprintf("%s:", name), - str_ccprintf("%c%s from %s", toupper(*mnestr), mnestr+1, reflist)); + str_ccprintf("%c%s from %s", toupper(*mnestr), mnestr + 1, reflist)); } else { output_references(avr_opcodes[mne].opcode, reflist); if(comment) @@ -525,13 +550,13 @@ static void lineout(const char *code, const char *comment, static int process_num(const char *buf, int buflen, int nbytes, int pos, int offset) { if(buflen - pos < nbytes) nbytes = buflen - pos; - while(nbytes & (nbytes-1)) // Round down to next power of 2 - nbytes &= nbytes-1; + while(nbytes & (nbytes - 1)) // Round down to next power of 2 + nbytes &= nbytes - 1; const char *str = nbytes == 1? str_ccprintf(".byte 0x%02x", buf[pos] & 0xff): nbytes == 2? str_ccprintf(".word 0x%04x", buf2op16(pos)): - nbytes == 4? str_ccprintf(".long 0x%04x%04x", buf2op16(pos+2), buf2op16(pos)): "nbytes?"; + nbytes == 4? str_ccprintf(".long 0x%04x%04x", buf2op16(pos + 2), buf2op16(pos)): "nbytes?"; lineout(str, NULL, -1, 1, buf, pos, offset, 0); return nbytes; @@ -539,7 +564,7 @@ static int process_num(const char *buf, int buflen, int nbytes, int pos, int off static int process_fill0xff(const char *buf, int buflen, int nbytes, int pos, int offset) { cx->dis_para++; - lineout(str_ccprintf(".fill %d, 2, 0xffff", nbytes/2), NULL, -1, 1, buf, pos, offset, 0); + lineout(str_ccprintf(".fill %d, 2, 0xffff", nbytes/2), NULL, -1, 1, buf, pos, offset, 0); return nbytes/2*2; } @@ -547,13 +572,15 @@ static int process_fill0xff(const char *buf, int buflen, int nbytes, int pos, in static int process_string(const char *buf, int buflen, int pos, int offset) { char *code, *out; int i = pos; + while(i < buflen && buf[i]) i++; if(i == buflen) { // Ran out of buffer: string not terminated - char *str = mmt_malloc(i-pos + 1); - memcpy(str, buf+pos, i-pos); - str[i-pos] = 0; + char *str = mmt_malloc(i - pos + 1); + + memcpy(str, buf + pos, i - pos); + str[i - pos] = 0; out = cfg_escape(str); mmt_free(str); code = mmt_sprintf(".ascii %s", out); @@ -563,29 +590,31 @@ static int process_string(const char *buf, int buflen, int pos, int offset) { i++; } - lineout(code, NULL, -1, i-pos, buf, pos, offset, 0); + lineout(code, NULL, -1, i - pos, buf, pos, offset, 0); mmt_free(out); mmt_free(code); - return i-pos; + return i - pos; } // Returns number of bytes of PGM data at this position, printing them in pass 2 static int process_data(const char *buf, int buflen, int pos, int offset) { int ret = 0; Dis_symbol *s = find_symbol('P', disasm_wrap(pos + offset)); + if(!s) { - if(pos+1 >= buflen) + if(pos + 1 >= buflen) return 0; - if(!(s = find_symbol('P', disasm_wrap(pos+offset+1)))) { // No PGM label, check for fill block + if(!(s = find_symbol('P', disasm_wrap(pos + offset + 1)))) { // No PGM label, check for fill block int k = 0; - if((buf[pos] &0xff) == 0xff && (buf[pos+1] & 0xff) == 0xff) - for(k=pos+2; kname); } - for(int i = 0; i < s->count && pos+ret < buflen; i++) { + for(int i = 0; i < s->count && pos + ret < buflen; i++) { switch(s->subtype) { case TYPE_BYTE: case TYPE_WORD: - ret += process_num(buf, buflen, s->subtype == TYPE_WORD? 2: 1, pos+ret, offset); + ret += process_num(buf, buflen, s->subtype == TYPE_WORD? 2: 1, pos + ret, offset); break; case TYPE_ASTRING: case TYPE_STRING: - ret += process_string(buf, buflen, pos+ret, offset); + ret += process_string(buf, buflen, pos + ret, offset); } } - if(s->subtype == TYPE_ASTRING) { // Autoaligned string + if(s->subtype == TYPE_ASTRING) { // Autoaligned string if(ret%2) { - if(buf[pos+ret]) - pmsg_warning("autoalignment expects 0x00 padding but got 0x%02x\n", buf[pos+ret] & 0xff); - lineout(str_ccprintf(".byte 0x%02x", buf[pos+ret] & 0xff), - "String autoalignment", -1, 1, buf, pos+ret, offset, 0); + if(buf[pos + ret]) + pmsg_warning("autoalignment expects 0x00 padding but got 0x%02x\n", buf[pos + ret] & 0xff); + lineout(str_ccprintf(".byte 0x%02x", buf[pos + ret] & 0xff), + "String autoalignment", -1, 1, buf, pos + ret, offset, 0); ret++; } } @@ -634,7 +663,8 @@ static void emit_used_symbols() { for(int i = 0; i < cx->dis_symbolN; i++) if(s[i].used && !s[i].printed && s[i].name) { const char *equ = str_ccprintf(".equ %s,%*s 0x%02x", s[i].name, - (int) (maxlen-strlen(s[i].name)), "", s[i].address); + (int) (maxlen - strlen(s[i].name)), "", s[i].address); + if(s[i].comment) disasm_out("%*s%-*s ; %s\n", codecol(), "", cx->dis_codewidth, equ, s[i].comment); else @@ -658,8 +688,8 @@ static void register_jumpcall(int from, int to, int mnemo, int is_func) { if(jc[i].from == from && jc[i].to == to && jc[i].mnemo == mnemo) return; - if(N % 1024 == 0) - jc = mmt_realloc(jc, sizeof(Dis_jumpcall) * (N+1024)); + if(N%1024 == 0) + jc = mmt_realloc(jc, sizeof(Dis_jumpcall)*(N + 1024)); jc[N].from = from; jc[N].to = to; jc[N].mnemo = mnemo; @@ -693,6 +723,7 @@ static void correct_is_funct(void) { static int jumpcall_sort(const void *v1, const void *v2) { const Dis_jumpcall *p1 = v1, *p2 = v2; int diff; + if((diff = p1->to - p2->to)) return diff; if((diff = p1->mnemo - p2->mnemo)) @@ -706,6 +737,7 @@ static void enumerate_labels(void) { correct_is_funct(); int dest = 987654321, cur_labelno = 0, cur_funcno = 0; + for(int i = 0; i < cx->dis_jumpcallN; i++) { if(!is_jumpable(cx->dis_jumpcalls[i].to)) continue; @@ -755,7 +787,7 @@ static char *add_comment(Dis_line *line, const char *comment) { static const char *regstyle(int n, int regword) { if(regword && !cx->dis_opts.avrgcc_style) - return str_ccprintf("%d:%d", n+1, n); + return str_ccprintf("%d:%d", n + 1, n); return str_ccprintf("%d", n); } @@ -765,7 +797,7 @@ static unsigned bitcount(unsigned n) { // A la Kernighan (and Richie): iteratively clear the least significant bit set for(ret = 0; n; ret++) - n &= n-1; + n &= n - 1; return ret; } @@ -779,12 +811,15 @@ static const char *get_ldi_name(int op1, int op2, Op_context *oxp) { char buf[2]; int ra = ldi_Rd(op1), rb = ldi_Rd(op2); - if((ra ^ rb) == 1) { // Two successive ldi opcodes initialise a register pair + + if((ra ^ rb) == 1) { // Two successive ldi opcodes initialise a register pair buf[ra & 1] = ldi_K(op1); buf[rb & 1] = ldi_K(op2); - int addr = buf2op16(0); // Address of register pair + int addr = buf2op16(0); // Address of register pair + // Assume address width is 2 if ldi acts on Z and is followed by e/icall within 5 opcodes int awidth = (ra | 1) == 31 && oxp->zwd == 2? 2: 1; + for(const char *c = awidth == 2 || oxp->is_lpm? "LP": "MLP"; *c; c++) if((s = find_symbol(*c, addr*awidth))) break; @@ -796,12 +831,14 @@ static const char *get_ldi_name(int op1, int op2, Op_context *oxp) { if(cx->dis_pass == 1) register_jumpcall(oxp->from, addr, MNEMO_ldi, 0); const char *name = get_label_name(addr, NULL); + if(name && cx->dis_opts.labels && is_jumpable(addr)) return str_ccprintf("%s(%s)", ra & 1? "hi8": "lo8", name); } else if(awidth == 2 && 2*addr >= cx->dis_start && 2*addr < cx->dis_end) { if(cx->dis_pass == 1) register_jumpcall(oxp->from, 2*addr, MNEMO_ldi, oxp->is_func); const char *name = get_label_name(2*addr, NULL); + if(name && cx->dis_opts.labels && is_jumpable(2*addr)) return str_ccprintf("pm_%s(%s)", ra & 1? "hi8": "lo8", name); } @@ -819,25 +856,26 @@ static const char *get_ldi_context(Op_context *oxp, int opcode) { return NULL; } -static void disassemble(const char *buf, int addr, int opcode, AVR_mnemo mnemo, - Op_context *oxp, Dis_line *line) { +static void disassemble(const char *buf, int addr, int opcode, AVR_mnemo mnemo, Op_context *oxp, Dis_line *line) { - memset(line, 0, sizeof*line); + memset(line, 0, sizeof *line); if(mnemo < 0) { add_comment(line, "Invalid opcode"); snprintf(line->code, LINE_N, ".word 0x%02x%02x", buf[1] & 0xff, buf[0] & 0xff); return; } - const AVR_opcode *oc = avr_opcodes+mnemo; + const AVR_opcode *oc = avr_opcodes + mnemo; const char *lsym = NULL; + if(op16_is_mnemo(opcode, MNEMO_ldi) && (lsym = get_ldi_context(oxp, opcode))) { mnemo = MNEMO_ldi; // Could have been ser - oc = avr_opcodes+mnemo; + oc = avr_opcodes + mnemo; } - int regs[128] = {0}, bits[128] = {0}; + int regs[128] = { 0 }, bits[128] = { 0 }; unsigned bmask = 0x8000; + for(const char *p = oc->bits; *p && bmask; p++) { if(*p == ' ') continue; @@ -878,11 +916,12 @@ static void disassemble(const char *buf, int addr, int opcode, AVR_mnemo mnemo, if(mnemo == MNEMO_andi && bitcount(RK) >= 4) { RK = ~RK & 0xff; mnemo = MNEMO_cbr; - oc = avr_opcodes+mnemo; + oc = avr_opcodes + mnemo; } // Apply register formula int regword = 0; + switch(oc->type & OTY_REG_MASK) { case OTY_REVN: // Even registers r0, r2, ..., r30 Rd *= 2, Rr *= 2; @@ -900,7 +939,7 @@ static void disassemble(const char *buf, int addr, int opcode, AVR_mnemo mnemo, int awd = cx->dis_addrwidth, swd = cx->dis_sramwidth; int target = 0, offset = 0, is_jumpcall = 0, is_relative = 0; - int is_function = !!(oc->type & OTY_EXTERNAL); // Call/rcall affects stack memory + int is_function = !!(oc->type & OTY_EXTERNAL); // Call/rcall affects stack memory const char *name, *ksym = NULL, *asym = NULL, *rsym = NA? resolve_address('I', RA): NULL; if(Na) { @@ -916,8 +955,8 @@ static void disassemble(const char *buf, int addr, int opcode, AVR_mnemo mnemo, switch(Nk) { case 0: break; - case 7: // Branches - offset = (int8_t) (Rk<<1); // Sign-extend and multiply by 2 + case 7: // Branches + offset = (int8_t) (Rk << 1); // Sign-extend and multiply by 2 target = disasm_wrap(addr + offset + 2); if(cx->dis_pass == 1 && offset) register_jumpcall(addr, target, mnemo, 0); @@ -925,21 +964,20 @@ static void disassemble(const char *buf, int addr, int opcode, AVR_mnemo mnemo, is_relative = 1; break; // rjmp/rcall case 12: - offset = (int16_t) (Rk<<4) >> 3; // Sign extend and multiply by 2 + offset = (int16_t) (Rk << 4) >> 3; // Sign extend and multiply by 2 target = disasm_wrap(addr + offset + 2); if(cx->dis_pass == 1 && offset) register_jumpcall(addr, target, mnemo, is_function); is_jumpcall = 1; is_relative = 1; break; - case 16: // lds/sts + case 16: // lds/sts ksym = resolve_address('M', Rk); break; case 22: if(cx->dis_flashsz && 2*Rk > cx->dis_flashsz) - add_comment(line, - str_ccprintf("Warning: destination outside flash [0, 0x%0*x]", awd, cx->dis_flashsz-1)); - target = 2*Rk; // disasm_wrap(2*Rk); + add_comment(line, str_ccprintf("Warning: destination outside flash [0, 0x%0*x]", awd, cx->dis_flashsz - 1)); + target = 2*Rk; // disasm_wrap(2*Rk); if(cx->dis_pass == 1) register_jumpcall(addr, target, mnemo, is_function); is_jumpcall = 1; @@ -948,6 +986,7 @@ static void disassemble(const char *buf, int addr, int opcode, AVR_mnemo mnemo, snprintf(line->code, LINE_N, "%-7s ", oc->opcode); char *lc = line->code + strlen(line->code); + #define add_operand(lc, ...) snprintf((lc), LINE_N - ((lc) - line->code), __VA_ARGS__) // Check for opcodes with undefined results @@ -966,7 +1005,7 @@ static void disassemble(const char *buf, int addr, int opcode, AVR_mnemo mnemo, break; } - for(const char *o = oc->operands; *o && lc-line->code < LINE_N - 1; o++) { + for(const char *o = oc->operands; *o && lc - line->code < LINE_N - 1; o++) { switch(*o) { case 'R': *lc++ = 'r', *lc = 0; @@ -989,7 +1028,7 @@ static void disassemble(const char *buf, int addr, int opcode, AVR_mnemo mnemo, case 'k': if(is_jumpcall) { name = get_label_name(target, NULL); - if(name && target != disasm_wrap(addr+2) && cx->dis_opts.labels && is_jumpable(target)) { + if(name && target != disasm_wrap(addr + 2) && cx->dis_opts.labels && is_jumpable(target)) { add_operand(lc, "%s", name); if(cx->dis_opts.addresses) add_comment(line, str_ccprintf("L%0*x", awd, target)); @@ -1053,6 +1092,7 @@ static void disassemble(const char *buf, int addr, int opcode, AVR_mnemo mnemo, static int have_own_main() { int mainaddr = -1; Dis_symbol *s = cx->dis_symbols; + for(int i = 0; i < cx->dis_symbolN; i++) if(s[i].type == 'L' && s[i].name && str_eq(s[i].name, "main")) mainaddr = s[i].address; @@ -1063,30 +1103,33 @@ static int have_own_main() { return 0; } -static void set_context(Op_context *oxp, const char *buf, int pos, int buflen, int addr, - int leadin, int leadout) { +static void set_context(Op_context *oxp, const char *buf, int pos, int buflen, int addr, int leadin, int leadout) { // Compute initial context structure: the opcode before and the following one - oxp->from = disasm_wrap(pos+addr); + oxp->from = disasm_wrap(pos + addr); oxp->is_func = 0; // Next Z-opcode ahead is an icall/eicall oxp->is_lpm = 0; // Next Z-opcode ahead is a lpm/elpm - oxp->preop = pos+leadin > 1? buf2op16(pos-2): -1; + oxp->preop = pos + leadin > 1? buf2op16(pos - 2): -1; oxp->postop = -1; oxp->zwd = 0; // 2: next Z-opcode ahead uses Z as word addr, 1: as byte addr int k = 0, op16, i = pos + op_width(buf2op16(pos)); - if(i < buflen+leadout-1) { + + if(i < buflen + leadout - 1) { AVR_mnemo z = 0; oxp->postop = op16 = buf2op16(i); // Check whether there is an opcode ahead that uses the Z register - for(k=0, i += op_width(op16); k < 6 && i < buflen+leadout-1; k++, i += op_width(op16)) + for(k = 0, i += op_width(op16); k < 6 && i < buflen + leadout - 1; k++, i += op_width(op16)) { if(op16_is_mnemo(op16, MNEMO_rjmp) || op16_is_mnemo(op16, MNEMO_jmp) || - op16_is_mnemo(op16, MNEMO_ret) || op16_is_mnemo(op16, MNEMO_reti) || - op16_is_mnemo(op16, MNEMO_u_ret) || op16_is_mnemo(op16, MNEMO_u_reti) || - (oxp->zwd = z_width((op16 = buf2op16(i)), &z))) + op16_is_mnemo(op16, MNEMO_ret) || op16_is_mnemo(op16, MNEMO_reti) || + op16_is_mnemo(op16, MNEMO_u_ret) || op16_is_mnemo(op16, MNEMO_u_reti) || + (oxp->zwd = z_width((op16 = buf2op16(i)), &z))) { + break; + } + } if(oxp->zwd == 2) - oxp->is_func = z==MNEMO_icall || z==MNEMO_eicall || z==MNEMO_u_icall || z==MNEMO_u_eicall; + oxp->is_func = z == MNEMO_icall || z == MNEMO_eicall || z == MNEMO_u_icall || z == MNEMO_u_eicall; else oxp->is_lpm = z >= MNEMO_lpm_0 && z <= MNEMO_elpm_zp; } @@ -1101,13 +1144,13 @@ static void set_context(Op_context *oxp, const char *buf, int pos, int buflen, i */ int disasm(const char *buf, int buflen, int addr, int leadin, int leadout) { int pos, opcode, mnemo, oplen; - Dis_line line = {0}; - Op_context ox = {0}; + Dis_line line = { 0 }; + Op_context ox = { 0 }; - for(int i = 0; i < cx->dis_symbolN; i++) // Clear used/printed state of symbols + for(int i = 0; i < cx->dis_symbolN; i++) // Clear used/printed state of symbols cx->dis_symbols[i].used = cx->dis_symbols[i].printed = 0; - cx->dis_jumpable = mmt_malloc((buflen+1)/2/8); // Allocate one bit per word address + cx->dis_jumpable = mmt_malloc((buflen + 1)/2/8); // Allocate one bit per word address cx->dis_start = addr, cx->dis_end = addr + buflen - 1; // Make two passes: the first gathers labels, the second outputs the assembler code @@ -1145,12 +1188,14 @@ int disasm(const char *buf, int buflen, int addr, int leadin, int leadout) { lineout(line.code, line.comment, mnemo, oplen, buf, pos, addr, 1); if(cx->dis_pass == 1) { // Mark this position as potential jump/call destination int n = sizeof(int)*8, idx = pos/2; - cx->dis_jumpable[idx/n] |= (1<<(idx%n)); + + cx->dis_jumpable[idx/n] |= (1 << (idx%n)); } } } - mmt_free(cx->dis_jumpable); cx->dis_jumpable = NULL; + mmt_free(cx->dis_jumpable); + cx->dis_jumpable = NULL; return 0; } @@ -1159,7 +1204,7 @@ int disasm_init(const AVRPART *p) { AVRMEM *mem; // Sanity check (problems only occur if avr_opcodes was changed) - for(size_t i = 0; i < sizeof avr_opcodes/sizeof*avr_opcodes; i++) + for(size_t i = 0; i < sizeof avr_opcodes/sizeof *avr_opcodes; i++) if(avr_opcodes[i].mnemo != (AVR_mnemo) i) { msg_error("avr_opcodes[] table broken (this should never happen)\n"); return -1; @@ -1173,13 +1218,15 @@ int disasm_init(const AVRPART *p) { if((mem = avr_locate_flash(p)) && mem->size > 1) { int nbits = intlog2(mem->size - 1) + 1; + cx->dis_flashsz = mem->size; cx->dis_flashsz2 = 1 << nbits; - cx->dis_addrwidth = (nbits+3)/4; + cx->dis_addrwidth = (nbits + 3)/4; } if((mem = avr_locate_sram(p)) && mem->size > 1) { int size = mem->size; + if(mem->offset > 0 && mem->offset <= 0x200) size += mem->offset; cx->dis_sramwidth = (intlog2(size - 1) + 1 + 3)/4; diff --git a/src/doc/avrdude.texi b/src/doc/avrdude.texi index ccdfc565e..739a881f9 100644 --- a/src/doc/avrdude.texi +++ b/src/doc/avrdude.texi @@ -103,7 +103,7 @@ Copyright @copyright{} Hans Eirik Bull, Brian S. Dean, Stefan R@"uger and J@"org @end ifinfo @menu -* Introduction:: +* Introduction:: * Command Line Options:: * Terminal Mode Operation:: * Configuration Files:: @@ -162,14 +162,14 @@ attached to a physical serial port. Connecting to a serial port emulated on top of USB is likely to not work at all, or to work abysmally slow. -If you happen to have a Linux system with at least 4 hardware GPIOs +If you happen to have a Linux system with at least 4 hardware GPIOs available (like almost all embedded Linux boards) you can do without any additional hardware - just connect them to the SDO, SDI, RESET and SCK pins of the AVR's SPI interface and use the linuxgpio programmer type. Older boards might use the labels MOSI for SDO and MISO for SDI. It bitbangs the lines using the Linux sysfs GPIO interface. Of course, care should -be taken about voltage level compatibility. Also, although not strictly -required, it is strongly advisable to protect the GPIO pins from +be taken about voltage level compatibility. Also, although not strictly +required, it is strongly advisable to protect the GPIO pins from overcurrent situations in some way. The simplest would be to just put some resistors in series or better yet use a 3-state buffer driver like the 74HC244. Have a look at @@ -223,7 +223,7 @@ The STK500, JTAG ICE, avr910, and avr109/butterfly use the serial port to commun The STK600, JTAG ICE mkII/3, AVRISP mkII, USBasp, avrftdi (and derivatives), and USBtinyISP programmers communicate through the USB, using @code{libusb} as a platform abstraction layer. -The avrftdi adds support for the FT2232C/D, FT2232H, and FT4232H devices. These all use +The avrftdi adds support for the FT2232C/D, FT2232H, and FT4232H devices. These all use the MPSSE mode, which has a specific pin mapping. Bit 0 (the lsb of the byte in the config file) is SCK. Bit 1 is SDO, and Bit 2 is SDI. Bit 3 usually reset. The 2232C/D parts are only supported on interface A, but the H parts can be either A or B (specified by the @@ -327,12 +327,12 @@ The Curiosity Nano board is supported in UPDI mode. It is dubbed ``PICkit on Board'', thus the name @code{pkobn_updi}. The MPLAB(R) PICkit 5 is currently only supported in UPDI mode. -SerialUPDI programmer implementation is based on Microchip's -@emph{pymcuprog} (@url{https://github.com/microchip-pic-avr-tools/pymcuprog}) +SerialUPDI programmer implementation is based on Microchip's +@emph{pymcuprog} (@url{https://github.com/microchip-pic-avr-tools/pymcuprog}) utility, but it also contains some performance improvements included in Spence Konde's @emph{DxCore} Arduino core (@url{https://github.com/SpenceKonde/DxCore}). -In a nutshell, this programmer consists of simple USB->UART adapter, diode -and couple of resistors. It uses serial connection to provide UPDI interface. +In a nutshell, this programmer consists of simple USB->UART adapter, diode +and couple of resistors. It uses serial connection to provide UPDI interface. @xref{SerialUPDI Programmer} for more details and known issues. The jtag2updi programmer is supported, @@ -354,7 +354,7 @@ See the section on @emph{extended parameters} below for Teensy specific options. @menu -* History:: +* History:: @end menu @c @@ -563,8 +563,8 @@ for the method of searching on Windows. If @var{config-file} is written as @var{+filename} then this file is read after the system wide and user configuration files. This can be used to add entries to the configuration -without patching your system wide configuration file. It can be used -several times, the files are read in same order as given on the command +without patching your system wide configuration file. It can be used +several times, the files are read in same order as given on the command line. @item -N @@ -1437,8 +1437,8 @@ is not verified but used directly within the C programming language. @item @samp{no_blockmode} Disables the default checking for block transfer capability. -Use -@samp{no_blockmode} only if your @samp{AVR910} +Use +@samp{no_blockmode} only if your @samp{AVR910} programmer creates errors during initial sequence. @item @samp{help} Show help menu and exit. @@ -1636,16 +1636,16 @@ The only advantage of the ``raw-wire'' mode is that different SPI frequencies are available. Paged writing is not implemented in this mode. @item @samp{pullups} -Enable the Bus Pirate's built-in pull-up resistors. These resistors are -useful when working with different voltage levels. VPU pin of the Bus Pirate -must be connected to an external voltage. -For example: connect VPU pin to the +5V pin or an external power supply. +Enable the Bus Pirate's built-in pull-up resistors. These resistors are +useful when working with different voltage levels. VPU pin of the Bus Pirate +must be connected to an external voltage. +For example: connect VPU pin to the +5V pin or an external power supply. @item @samp{hiz} -Enable the Bus Pirate's HiZ mode on SPI, allowing it to work as an -open-collector and interface with external pull-up circuits. -If the external target circuit does not have pull-ups, the Bus Pirate -will not be able to send data. +Enable the Bus Pirate's HiZ mode on SPI, allowing it to work as an +open-collector and interface with external pull-up circuits. +If the external target circuit does not have pull-ups, the Bus Pirate +will not be able to send data. @item @samp{ascii} Attempt to use ASCII mode even when the firmware supports BinMode (binary @@ -1667,22 +1667,22 @@ significant write speed increase. If use of this mode is not desirable for some reason, this option disables it. @item @samp{nopagedread} -Newer firmware versions support in binary mode SPI command some AVR Extended +Newer firmware versions support in binary mode SPI command some AVR Extended Commands. Using the ``Bulk Memory Read from Flash'' results in a significant read speed increase. If use of this mode is not desirable for some reason, this option disables it. @item @samp{cpufreq=@var{125..4000}} This sets the @emph{AUX} pin to output a frequency of @var{n} kHz. Connecting -the @emph{AUX} pin to the XTAL1 pin of your MCU, you can provide it a clock, +the @emph{AUX} pin to the XTAL1 pin of your MCU, you can provide it a clock, for example when it needs an external clock because of wrong fuses settings. -Make sure the CPU frequency is at least four times the SPI frequency. +Make sure the CPU frequency is at least four times the SPI frequency. @item @samp{serial_recv_timeout=@var{1...}} -This sets the serial receive timeout to the given value. -The timeout happens every time avrdude waits for the BusPirate prompt. -Especially in ascii mode this happens very often, so setting a smaller value -can speed up programming a lot. +This sets the serial receive timeout to the given value. +The timeout happens every time avrdude waits for the BusPirate prompt. +Especially in ascii mode this happens very often, so setting a smaller value +can speed up programming a lot. The default value is 100 ms. Using 10 ms might work in most cases. @item @samp{help} @@ -2346,8 +2346,8 @@ Terminal mode also supports a command history so that previously entered commands can be recalled and edited. @menu -* Terminal Mode Commands:: -* Terminal Mode Examples:: +* Terminal Mode Commands:: +* Terminal Mode Examples:: @end menu @node Terminal Mode Commands, Terminal Mode Examples, Terminal Mode Operation, Terminal Mode Operation @@ -3438,11 +3438,11 @@ this file is the @code{avrdude.rc} file located in the same directory as the executable. @menu -* AVRDUDE Defaults:: -* Programmer Definitions:: +* AVRDUDE Defaults:: +* Programmer Definitions:: * Serial Adapter Definitions:: -* Part Definitions:: -* Other Notes:: +* Part Definitions:: +* Other Notes:: @end menu @c @@ -3549,7 +3549,7 @@ programmer @end smallexample @noindent -If a parent is specified, all settings of it (except its ids) are used for the new +If a parent is specified, all settings of it (except its ids) are used for the new programmer. These values can be changed by new setting them for the new programmer. @noindent @@ -4029,7 +4029,7 @@ and socket card: @item @code{STK600-RC100M-11} @tab @code{STK600-TQFP100} @tab ATmega640 ATmega1280 ATmega2560 @item @code{} @tab @code{STK600-ATMEGA2560} @tab ATmega2560 @item @code{STK600-RC100M-18} @tab @code{STK600-TQFP100} @tab ATmega3250 ATmega3250P ATmega3290 ATmega3290P ATmega6450 ATmega6490 -@item @code{STK600-RC032U-20} @tab @code{STK600-TQFP32} @tab AT90USB82 AT90USB162 ATmega8U2 ATmega16U2 ATmega32U2 +@item @code{STK600-RC032U-20} @tab @code{STK600-TQFP32} @tab AT90USB82 AT90USB162 ATmega8U2 ATmega16U2 ATmega32U2 @item @code{STK600-RC044U-25} @tab @code{STK600-TQFP44} @tab ATmega16U4 ATmega32U4 @item @code{STK600-RC064U-17} @tab @code{STK600-TQFP64} @tab ATmega32U6 AT90USB646 AT90USB1286 AT90USB647 AT90USB1287 @item @code{STK600-RCPWM-22} @tab @code{STK600-TQFP32} @tab ATmega32C1 ATmega64C1 ATmega16M1 ATmega32M1 ATmega64M1 @@ -4124,7 +4124,7 @@ versions of the bootloader. SerialUPDI programmer can be used for programming UPDI-only devices using very simple serial connection. -You can read more about the details here +You can read more about the details here @url{https://github.com/SpenceKonde/AVR-Guidance/blob/master/UPDI/jtag2updi.md} SerialUPDI programmer has been tested using FT232RL USB->UART interface @@ -4147,23 +4147,23 @@ There are several limitations in current SerialUPDI/AVRDUDE integration, listed below. Currently available devices support only UPDI NVM programming model 0, 2 -3 and 5, but there is also experimental implementation of model 4 - it +3 and 5, but there is also experimental implementation of model 4 - it has been tested only on a single device, so issues with other devices are expected. Full NVM v4 mode support will be provided once the hardware is widely available. One of the core AVRDUDE features is verification of the connection by reading device signature prior to any operation, but this operation -is not possible on UPDI locked devices. Therefore, to be able to +is not possible on UPDI locked devices. Therefore, to be able to connect to such a device, you have to provide @option{-F} to override this check. -Please note: using @option{-F} during write operation to locked device +Please note: using @option{-F} during write operation to locked device will force chip erase. Use carefully. Another issue you might notice is slow performance of EEPROM writing using SerialUPDI for AVR Dx devices. This can be addressed by changing -@emph{avrdude.conf} section for this device - changing EEPROM page +@emph{avrdude.conf} section for this device - changing EEPROM page size to 0x20 (instead of default 1), like so: @example @@ -4266,11 +4266,11 @@ Other combinations should not show after exit. @cindex Unix @menu -* Unix Installation:: -* Unix Configuration Files:: -* Unix Port Names:: +* Unix Installation:: +* Unix Configuration Files:: +* Unix Port Names:: * Unix USB Permissions:: -* Unix Documentation:: +* Unix Documentation:: @end menu @c @@ -4301,8 +4301,8 @@ is searched for a file named @code{.avrduderc}, and if found, is used to augment the system default configuration file. @menu -* FreeBSD Configuration Files:: -* Linux Configuration Files:: +* FreeBSD Configuration Files:: +* Linux Configuration Files:: @end menu @c @@ -4338,7 +4338,7 @@ configuration file will be always be @code{/etc/avrdude.conf}. @noindent The parallel and serial port device file names are system specific. -MacOS has no default serial or parallel port names, but available +MacOS has no default serial or parallel port names, but available ports can be found under @code{/dev/cu.*}. The following table lists the default names for a given system. @@ -4534,9 +4534,9 @@ such as @option{--prefix}. @cindex Windows @menu -* Windows Installation:: -* Windows Configuration Files:: -* Windows Port Names:: +* Windows Installation:: +* Windows Configuration Files:: +* Windows Port Names:: @c * Documentation:: @end menu @@ -4559,7 +4559,7 @@ for the latest installation tips. @cindex Windows configuration files @menu -* Configuration file names:: +* Configuration file names:: * Windows Configuration File Location:: @end menu @@ -4581,7 +4581,7 @@ AVRDUDE on Windows looks for a system configuration file name of @node Windows Configuration File Location, , Configuration file names, Windows Configuration Files @subsubsection Windows Configuration File Location @cindex Windows configuration file location - + @noindent AVRDUDE on Windows has a different way of searching for the system and user configuration files. Below is the search method for locating the @@ -4624,8 +4624,8 @@ The directories that are listed in the PATH environment variable. @cindex Windows port names @menu -* Serial Ports:: -* Parallel Ports:: +* Serial Ports:: +* Parallel Ports:: @end menu @c @@ -4634,11 +4634,11 @@ The directories that are listed in the PATH environment variable. @node Serial Ports, Parallel Ports, Windows Port Names, Windows Port Names @subsubsection Windows Serial Ports @cindex Windows serial ports - + @noindent When you select a serial port (i.e. when using an STK500) use the Windows serial port device names such as: com1, com2, etc. - + @c @c Node @c @@ -4885,7 +4885,7 @@ Solution: Use the following pin mapping: @item Problem: I want to use my AVR Dragon to program an -Xmega device through PDI. +Xmega device through PDI. Solution: Use the 6 pin ISP header on the Dragon and the following pin mapping: @@ -4894,7 +4894,7 @@ Solution: Use the 6 pin ISP header on the Dragon and the following pin mapping: @item @strong{ISP Header} @tab @strong{pins} @item 1 (SDI) @tab PDI_DATA @item 2 (VCC) @tab VCC -@item 3 (SCK) @tab +@item 3 (SCK) @tab @item 4 (SDO) @tab @item 5 (RESET) @tab PDI_CLK / RST @item 6 (GND) @tab GND @@ -4918,26 +4918,26 @@ Solution: Use the following pin mapping: @end multitable @item -Problem: I want to program an ATtiny4/5/9/10 device using a serial/parallel +Problem: I want to program an ATtiny4/5/9/10 device using a serial/parallel bitbang programmer. How to connect the pins? -Solution: Since TPI has only 1 pin for bi-directional data transfer, both +Solution: Since TPI has only 1 pin for bi-directional data transfer, both @var{SDI} and @var{SDO} pins should be connected to the @var{TPIDATA} pin on the ATtiny device. However, a 1K resistor should be placed between the @var{SDO} and @var{TPIDATA}. The @var{SDI} pin connects to @var{TPIDATA} directly. The @var{SCK} pin is connected to @var{TPICLK}. -In addition, the @var{Vcc}, @var{/RESET} and @var{GND} pins should +In addition, the @var{Vcc}, @var{/RESET} and @var{GND} pins should be connected to their respective ports on the ATtiny device. @item Problem: How can I use a FTDI FT232R USB-to-Serial device for bitbang programming? -Solution: When connecting the FT232 directly to the pins of the target Atmel device, -the polarity of the pins defined in the @code{programmer} definition should be -inverted by prefixing a tilde. For example, the @var{dasa} programmer would -look like this when connected via a FT232R device (notice the tildes in +Solution: When connecting the FT232 directly to the pins of the target Atmel device, +the polarity of the pins defined in the @code{programmer} definition should be +inverted by prefixing a tilde. For example, the @var{dasa} programmer would +look like this when connected via a FT232R device (notice the tildes in front of pins 7, 4, 3 and 8): @example @@ -4952,7 +4952,7 @@ programmer ; @end example -Note that this uses the FT232 device as a normal serial port, not using the +Note that this uses the FT232 device as a normal serial port, not using the FTDI drivers in the special bitbang mode. @item diff --git a/src/dryrun.c b/src/dryrun.c index a593af66d..744572237 100644 --- a/src/dryrun.c +++ b/src/dryrun.c @@ -1,5 +1,5 @@ /* - * AVRDUDE - A Downloader/Uploader for AVR device programmers + * avrdude - A Downloader/Uploader for AVR device programmers * Copyright (C) 2022- Stefan Rueger * * This program is free software; you can redistribute it and/or modify @@ -66,12 +66,11 @@ typedef struct { // Use private programmer data as if they were a global structure dry #define dry (*(Dryrun_data *)(pgm->cookie)) -#define Return(...) do { pmsg_error(__VA_ARGS__); msg_error("\n"); return -1; } while (0) +#define Return(...) do { pmsg_error(__VA_ARGS__); msg_error("\n"); return -1; } while(0) #define Retwarning(...) do { pmsg_warning(__VA_ARGS__); \ - msg_warning("; not initialising %s memories\n", p->desc); return -1; } while (0) + msg_warning("; not initialising %s memories\n", p->desc); return -1; } while(0) -static int dryrun_readonly(const PROGRAMMER *pgm, const AVRPART *p, const AVRMEM *mem, - unsigned int addr); +static int dryrun_readonly(const PROGRAMMER *pgm, const AVRPART *p, const AVRMEM *mem, unsigned int addr); // Read expected signature bytes from part description static int dryrun_read_sig_bytes(const PROGRAMMER *pgm, const AVRPART *p, const AVRMEM *sigmem) { @@ -85,7 +84,6 @@ static int dryrun_read_sig_bytes(const PROGRAMMER *pgm, const AVRPART *p, const return 3; } - // Emulate chip erase static int dryrun_chip_erase(const PROGRAMMER *pgm, const AVRPART *punused) { AVRMEM *mem; @@ -99,75 +97,73 @@ static int dryrun_chip_erase(const PROGRAMMER *pgm, const AVRPART *punused) { Return("cannot erase %s flash memory owing to its size %d", dry.dp->desc, mem->size); if(dry.bl) { // Bootloaders won't overwrite themselves - memset(mem->buf + (dry.bl == DRY_TOP? 0: dry.bootsize), 0xff, mem->size-dry.bootsize); + memset(mem->buf + (dry.bl == DRY_TOP? 0: dry.bootsize), 0xff, mem->size - dry.bootsize); return 0; // Assume that's all a bootloader does } memset(mem->buf, 0xff, mem->size); int eesave, bakverb = verbose; + verbose = -123; if((mem = avr_locate_eeprom(dry.dp))) // Check whether EEPROM needs erasing - if(avr_get_config_value(pgm, dry.dp, "eesave", &eesave) == 0 && eesave == !(dry.dp->prog_modes & PM_UPDI)) + if(avr_get_config_value(pgm, dry.dp, "eesave", &eesave) == 0 && eesave == !is_updi(dry.dp)) if(mem->size > 0) memset(mem->buf, 0xff, mem->size); verbose = bakverb; - if((mem = avr_locate_bootrow(dry.dp))) // Also erase bootrow if it's there + if((mem = avr_locate_bootrow(dry.dp))) // Also erase bootrow if it's there if(mem->size > 0) memset(mem->buf, 0xff, mem->size); if((mem = avr_locate_lock(dry.dp))) if(mem->initval != -1 && mem->size > 0 && mem->size <= (int) sizeof(mem->initval)) - memcpy(mem->buf, &mem->initval, mem->size); // FIXME: relying on little endian here + memcpy(mem->buf, &mem->initval, mem->size); // FIXME: relying on little endian here return 0; } - // For now pretend all is hunky-dory static int dryrun_cmd(const PROGRAMMER *pgm, const unsigned char *cmd, unsigned char *res) { int ret = 0; pmsg_debug("%s(0x%02x 0x%02x 0x%02x 0x%02x)\n", __func__, cmd[0], cmd[1], cmd[2], cmd[3]); // FIXME: do we need to emulate some more commands? For now it's only the STK universal CE - if(cmd[0] == (Subc_STK_UNIVERSAL_LEXT>>24) || - (cmd[0] == (Subc_STK_UNIVERSAL_CE>>24) && cmd[1] == (uint8_t)(Subc_STK_UNIVERSAL_CE>>16))) { + if(cmd[0] == (Subc_STK_UNIVERSAL_LEXT >> 24) || + (cmd[0] == (Subc_STK_UNIVERSAL_CE >> 24) && cmd[1] == (uint8_t) (Subc_STK_UNIVERSAL_CE >> 16))) { ret = dryrun_chip_erase(pgm, NULL); } // Pretend call happened and all is good, returning 0xff each time - memcpy(res, cmd+1, 3); + memcpy(res, cmd + 1, 3); res[3] = 0xff; return ret; } - -static int dryrun_page_erase(const PROGRAMMER *pgm, const AVRPART *p, const AVRMEM *m, - unsigned int addr) { +static int dryrun_page_erase(const PROGRAMMER *pgm, const AVRPART *p, const AVRMEM *m, unsigned int addr) { pmsg_debug("%s(%s, 0x%04x)\n", __func__, m->desc, addr); if(!dry.dp) Return("no dryrun device?"); AVRMEM *dmem; + if(!(dmem = avr_locate_mem(dry.dp, m->desc))) Return("cannot locate %s %s memory for paged write", dry.dp->desc, m->desc); if(!avr_has_paged_access(pgm, dry.dp, dmem) || addr >= (unsigned) dmem->size) Return("%s does not support paged access", dmem->desc); - addr &= ~(dmem->page_size-1); + addr &= ~(dmem->page_size - 1); if(addr + dmem->page_size > (unsigned) dmem->size) Return("%s page erase of %s reaches outside %s?", dmem->desc, - str_ccinterval(addr, addr + dmem->page_size-1), str_ccinterval(0, dmem->size-1)); + str_ccinterval(addr, addr + dmem->page_size - 1), str_ccinterval(0, dmem->size - 1)); - memset(dmem->buf+addr, 0xff, dmem->page_size); + memset(dmem->buf + addr, 0xff, dmem->page_size); return 0; } - static int dryrun_program_enable(const PROGRAMMER *pgm, const AVRPART *p_unused) { pmsg_debug("%s()\n", __func__); @@ -175,22 +171,23 @@ static int dryrun_program_enable(const PROGRAMMER *pgm, const AVRPART *p_unused) } // Randomly set configuration values for bootloading, bootloader size and codesize, if any -static void randflashconfig(const PROGRAMMER *pgm, const AVRPART *p, - const Avrintel *up, const Configitem *cp, int nc) { +static void randflashconfig(const PROGRAMMER *pgm, const AVRPART *p, const Avrintel *up, + const Configitem *cp, int nc) { - if(up && p->prog_modes & PM_UPDI) { + if(up && is_updi(p)) { int sectorsize = up->bootsize > 0? up->bootsize: 256; int nsectors = up->flashsize/sectorsize; - int bootsize = random() % (nsectors > 4? nsectors/4: nsectors); + int bootsize = random()%(nsectors > 4? nsectors/4: nsectors); int codesize = !bootsize || random()%3? 0: bootsize + random()%(nsectors - bootsize); int size = !!avr_locate_config(cp, nc, "bootsize", str_eq); + avr_set_config_value(pgm, p, size? "bootsize": "bootend", bootsize); avr_set_config_value(pgm, p, size? "codesize": "append", codesize); - } else if(up && up->nboots >0 && (p->prog_modes & (PM_Classic | PM_PDI))) { - avr_set_config_value(pgm, p, "bootrst", random() % 2); + } else if(up && up->nboots > 0 && (p->prog_modes & (PM_Classic | PM_PDI))) { + avr_set_config_value(pgm, p, "bootrst", random()%2); if(up->nboots == 4) - avr_set_config_value(pgm, p, "bootsz", random() % 4); + avr_set_config_value(pgm, p, "bootsz", random()%4); } } @@ -200,36 +197,39 @@ static int flashlayout(const PROGRAMMER *pgm, const AVRPART *p, const AVRMEM *fl AVRMEM *m; - if(p->prog_modes & PM_UPDI) { + if(is_updi(p)) { int nbootsec = 0, ncodesec = 0; int size = !!avr_locate_config(cp, nc, "bootsize", str_eq); + avr_get_config_value(pgm, p, size? "bootsize": "bootend", &nbootsec); avr_get_config_value(pgm, p, size? "codesize": "append", &ncodesec); - if(nbootsec == 0 || (ncodesec && ncodesec <= nbootsec)) { // Treat boot section for code + if(nbootsec == 0 || (ncodesec && ncodesec <= nbootsec)) { // Treat boot section for code dry.bootstart = 0, dry.bootsize = 0; dry.appstart = 0, dry.appsize = nbootsec? nbootsec*up->bootsize: up->flashsize; - } else { // Distinct boot and application section + } else { // Distinct boot and application section dry.bootstart = 0, dry.bootsize = nbootsec*up->bootsize; dry.appstart = dry.bootsize; - dry.appsize = ncodesec? (ncodesec - nbootsec) * up->bootsize: up->flashsize - dry.appstart; + dry.appsize = ncodesec? (ncodesec - nbootsec)*up->bootsize: up->flashsize - dry.appstart; } - dry.datasize = up->flashsize - dry.bootsize - dry.appsize; // Remainder is apptable + dry.datasize = up->flashsize - dry.bootsize - dry.appsize; // Remainder is apptable dry.datastart = dry.datasize? dry.bootsize + dry.appsize: 0; } else if(p->prog_modes & (PM_Classic | PM_PDI)) { dry.bootstart = 0, dry.bootsize = 0; if(up->nboots) { int bootrst = 1; + avr_get_config_value(pgm, p, "bootrst", &bootrst); - if(bootrst == 0) { // Jump to bootloader on reset - if((p->prog_modes & PM_PDI) && (m = avr_locate_boot(p)) && m->size > 0) { + if(bootrst == 0) { // Jump to bootloader on reset + if(is_pdi(p) && (m = avr_locate_boot(p)) && m->size > 0) { dry.bootstart = m->offset - flm->offset; dry.bootsize = m->size; - } else if(p->prog_modes & PM_Classic) { - if(up->nboots == 4) { + } else if(is_classic(p)) { + if(up->nboots == 4) { int bootsz = 0; + avr_get_config_value(pgm, p, "bootsz", &bootsz); - dry.bootsize = (8>>bootsz) * up->bootsize; + dry.bootsize = (8 >> bootsz)*up->bootsize; } else dry.bootsize = up->bootsize; dry.bootstart = up->flashsize - dry.bootsize; @@ -237,7 +237,7 @@ static int flashlayout(const PROGRAMMER *pgm, const AVRPART *p, const AVRMEM *fl } } dry.datastart = 0, dry.datasize = 0; - if((p->prog_modes & PM_PDI) && (m = avr_locate_apptable(p)) && m->size > 0) { + if(is_pdi(p) && (m = avr_locate_apptable(p)) && m->size > 0) { dry.datastart = m->offset - flm->offset; dry.datasize = up->flashsize - dry.datastart - dry.bootsize; } @@ -247,21 +247,21 @@ static int flashlayout(const PROGRAMMER *pgm, const AVRPART *p, const AVRMEM *fl // Sanity checks if(dry.appsize < 0) Retwarning("negative application size"); - if(dry.appstart < 0 || dry.appstart+dry.appsize > up->flashsize) + if(dry.appstart < 0 || dry.appstart + dry.appsize > up->flashsize) Retwarning("application section %s outside flash [0, 0x%04x]", - str_ccinterval(dry.appstart, dry.appstart+dry.appsize-1), up->flashsize-1); + str_ccinterval(dry.appstart, dry.appstart + dry.appsize - 1), up->flashsize - 1); if(dry.datasize < 0) Retwarning("negative apptable size"); - if(dry.datastart < 0 || dry.datastart+dry.datasize > up->flashsize) + if(dry.datastart < 0 || dry.datastart + dry.datasize > up->flashsize) Retwarning("apptable section %s outside flash [0, 0x%04x]", - str_ccinterval(dry.datastart, dry.datastart+dry.datasize-1), up->flashsize-1); + str_ccinterval(dry.datastart, dry.datastart + dry.datasize - 1), up->flashsize - 1); if(dry.bootsize < 0) Retwarning("negative boot section size"); - if(dry.bootstart < 0 || dry.bootstart+dry.bootsize > up->flashsize) + if(dry.bootstart < 0 || dry.bootstart + dry.bootsize > up->flashsize) Retwarning("boot section %s outside flassh [0, 0x%04x]", - str_ccinterval(dry.bootstart, dry.bootstart+dry.bootsize-1), up->flashsize-1); + str_ccinterval(dry.bootstart, dry.bootstart + dry.bootsize - 1), up->flashsize - 1); if(dry.appsize + dry.datasize + dry.bootsize != up->flashsize) Retwarning("section sizes do not add up (0x%x) to flash size 0x%x", @@ -270,24 +270,24 @@ static int flashlayout(const PROGRAMMER *pgm, const AVRPART *p, const AVRMEM *fl if(!dry.appsize) Retwarning("no application section"); - if(p->prog_modes & PM_UPDI) { + if(is_updi(p)) { if(dry.bootsize && dry.appstart != dry.bootsize) Retwarning("application section %s does not touch boot section %s", - str_ccinterval(dry.appstart, dry.appstart+dry.appsize-1), - str_ccinterval(dry.bootstart, dry.bootstart+dry.bootsize-1)); + str_ccinterval(dry.appstart, dry.appstart + dry.appsize - 1), + str_ccinterval(dry.bootstart, dry.bootstart + dry.bootsize - 1)); if(dry.datasize && dry.datastart != dry.bootsize + dry.appsize) Retwarning("apptable section %s does not touch code section %s", - str_ccinterval(dry.datastart, dry.datastart+dry.appsize-1), - str_ccinterval(0, dry.bootsize+dry.appsize-1)); + str_ccinterval(dry.datastart, dry.datastart + dry.appsize - 1), + str_ccinterval(0, dry.bootsize + dry.appsize - 1)); } else { - if(dry.datasize && dry.datastart != dry.appsize && dry.appstart !=0) + if(dry.datasize && dry.datastart != dry.appsize && dry.appstart != 0) Retwarning("apptable section %s does not touch application section %s", - str_ccinterval(dry.datastart, dry.datastart+dry.appsize-1), - str_ccinterval(dry.appstart, dry.appstart+dry.appsize-1)); + str_ccinterval(dry.datastart, dry.datastart + dry.appsize - 1), + str_ccinterval(dry.appstart, dry.appstart + dry.appsize - 1)); if(dry.datasize && dry.bootsize && dry.bootstart != dry.appsize + dry.datasize) Retwarning("apptable section %s does not touch boot section %s", - str_ccinterval(dry.datastart, dry.datastart+dry.appsize-1), - str_ccinterval(dry.bootstart, dry.bootstart+dry.bootsize-1)); + str_ccinterval(dry.datastart, dry.datastart + dry.appsize - 1), + str_ccinterval(dry.bootstart, dry.bootstart + dry.bootsize - 1)); } return 0; @@ -295,21 +295,21 @@ static int flashlayout(const PROGRAMMER *pgm, const AVRPART *p, const AVRMEM *fl // Write a vector table to flash addr and return number of bytes written static int putvectortable(const AVRPART *p, const AVRMEM *flm, int addr, int round32) { - int vecsz = flm->size <= 8192? 2: 4, ret = p->n_interrupts * vecsz; - int app = (ret + vecsz - 2)/2; // Distance to application in words + int vecsz = flm->size <= 8192? 2: 4, ret = p->n_interrupts*vecsz; + int app = (ret + vecsz - 2)/2; // Distance to application in words for(int i = 0; i < ret; i += vecsz) { // First store rjmps to after table - flm->buf[addr + i] = app; - flm->buf[addr + i + 1] = 0xc0 + (app>>8); // rjmp app, rjmp app, ... + flm->buf[addr + i] = app; + flm->buf[addr + i + 1] = 0xc0 + (app >> 8); // rjmp app, rjmp app, ... if(vecsz == 4) // Put nop behind rjmp - flm->buf[addr+i+2] = 0, flm->buf[addr+i+3] = 0; + flm->buf[addr + i + 2] = 0, flm->buf[addr + i + 3] = 0; app -= vecsz/2; } - for(int i=0; i < vecsz; i++) // Leave one vector gap + for(int i = 0; i < vecsz; i++) // Leave one vector gap flm->buf[addr + ret++] = round32? ' ': 0; if(round32) { - flm->buf[addr + ret++] = 0xff; // Put endless loop rjmp .-2 as application + flm->buf[addr + ret++] = 0xff; // Put endless loop rjmp .-2 as application flm->buf[addr + ret++] = 0xcf; // Then round up to multiples of 32 @@ -325,17 +325,21 @@ static const int u384[] = { 0x00000800, 0x08000800, 0x1c4218ca, 0x08a5284a, 0x1842184e, 0x00000000, 0x00000000, 0x08010000, 0x08010000, 0x08c53086, 0x00430942, 0x08653082, }, u512[] = { + 0x20000800, 0x20000800, 0xf71c7b51, 0x28a288d1, 0x28a28851, 0x28a28859, 0xc71c7856, 0x00000000, 0x80020000, 0x80020000, 0x8f22f1cd, 0x80920a23, 0x870e0a21, 0x08120a21, 0x87a2f1c1, 0x00000000, }, bdata[] = { + 0x00000000, 0x00000001, 0x00000001, 0x08000001, 0x08000001, 0xfe381c1d, 0x08442223, 0x08824121, 0x08824121, 0x08824121, 0x08442223, 0xf0381c1d, 0x00000000, 0x00000000, 0x00400000, 0x00400000, 0x00400000, 0x00400000, 0x785c0e3c, 0x88621102, 0x84422081, 0xfc422081, 0x04422081, 0x04621102, 0xf85c0e3c, 0x00000000, 0x00000000, 0x00000000, }, adata[] = { + 0x00000020, 0x00000020, 0x00040020, 0x00040020, 0x3c7f1e2e, 0x40042031, 0x40042021, 0x7c043e21, 0x42042121, 0x42042131, 0xfc787e2e, 0x00000000, 0x00000000, 0x00000000, }, rocks[] = { + 0x00000004, 0x0000003c, 0x000000fc, 0x000007fc, 0x00001ffc, 0x0000ffe0, 0x0003ff00, 0x001ffc00, 0x007fc000, 0x03fe0000, 0x07f00000, 0x07800000, 0x07e00000, 0x07fc0000, 0x03ff0000, 0x007fe000, 0x001ffc00, 0x0003ff00, 0x0000ffe0, 0x00001ffc, 0x000007fc, 0x000000fc, 0x0000003c, 0x00000004, @@ -370,13 +374,15 @@ static const int u384[] = { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, }; -const struct { const int *bits, n32; } banner[] = { - {u384, sizeof u384/sizeof*u384}, - {u512, sizeof u512/sizeof*u512}, - {bdata, sizeof bdata/sizeof*bdata}, - {adata, sizeof adata/sizeof*adata}, - {rocks, sizeof rocks/sizeof*rocks}, - {rocks, sizeof rocks/sizeof*rocks}, // Sic, dummy entry for RND +const struct { + const int *bits, n32; +} banner[] = { + {u384, sizeof u384/sizeof *u384}, + {u512, sizeof u512/sizeof *u512}, + {bdata, sizeof bdata/sizeof *bdata}, + {adata, sizeof adata/sizeof *adata}, + {rocks, sizeof rocks/sizeof *rocks}, + {rocks, sizeof rocks/sizeof *rocks}, // Sic, dummy entry for RND }; enum { U384, U512, BDATA, ADATA, ROCKS, RND }; @@ -392,9 +398,10 @@ enum { U384, U512, BDATA, ADATA, ROCKS, RND }; static void putbanner(const AVRMEM *flm, int addr, int n, int bi) { const int *bp = banner[bi].bits, len = n/10 + random()%(9*n/10); - for(int i=0; ibuf[addr++] = scan & 1? '@': ' '; scan >>= 1; if(++i == n) @@ -410,7 +417,7 @@ static void putbanner(const AVRMEM *flm, int addr, int n, int bi) { // Put single 16-bit opcode into memory static void putop16(unsigned char *addr, int op) { - addr[0] = op, addr[1] = op>>8; + addr[0] = op, addr[1] = op >> 8; } // Put n/2 random benign opcodes compatible with part into memory at addr @@ -421,25 +428,27 @@ static void putcode(const AVRPART *p, const AVRMEM *flm, int addr, int n) { do { inrange = 0; // Last opcode is a long backward jump; the others are random - op = i == n/2-1? dist2rjmp(-2*(i<2048? i: 2047)): random() & 0xffff; + op = i == n/2 - 1? dist2rjmp(-2*(i < 2048? i: 2047)): random() & 0xffff; if(op16_is_benign(op, avrlevel)) - inrange = (pc = op16_target(addr+2*i, op)) >= addr && pc < end; + inrange = (pc = op16_target(addr + 2*i, op)) >= addr && pc < end; } while(!inrange); putop16(flm->buf + addr + 2*i, op); } } - // Write valid opcodes to flash (banners for -xinit, random code for -xrandom) static void putflash(const PROGRAMMER *pgm, const AVRPART *p, const AVRMEM *flm, int addr, int n, int bi) { - unsigned char *top = flm->buf+addr+n-4; + unsigned char *top = flm->buf + addr + n - 4; if(dry.random) { switch(bi) { - case U384: case U512: case BDATA: // Bootloader stuff, reduce code length a little + case U384: + case U512: + case BDATA: // Bootloader stuff, reduce code length a little n -= random()%(n/8); break; - case ADATA: case ROCKS: // Set random code length in [n/4, n] + case ADATA: + case ROCKS: // Set random code length in [n/4, n] n -= random()%(3*n/4); } if(bi != ADATA) { @@ -450,10 +459,10 @@ static void putflash(const PROGRAMMER *pgm, const AVRPART *p, const AVRMEM *flm, } putbanner(flm, addr, n, bi); -seal: // Put 1-2 endless loops in top memory section +seal: // Put 1-2 endless loops in top memory section if(*top == 0xff) putop16(top, 0xcfff); - putop16(top+2, 0xcfff); + putop16(top + 2, 0xcfff); } // Initialise a user writable memory other than flash or fuses @@ -477,19 +486,21 @@ static void putother(const PROGRAMMER *pgm, const AVRPART *p, const AVRMEM *m, c if((len = strlen(name)) > m->size) len = m->size; - memcpy(m->buf+m->size-len, name, len); + memcpy(m->buf + m->size - len, name, len); if(len < m->size) - m->buf[m->size-len-1] = ' '; + m->buf[m->size - len - 1] = ' '; } // Copy chunk in one flash memory to other overlapping flash memories (think XMEGA) static void sharedflash(const PROGRAMMER *pgm, const AVRMEM *fm, unsigned addr, int chunk) { - for(LNODEID ln=lfirst(dry.dp->mem); ln; ln=lnext(ln)) { + for(LNODEID ln = lfirst(dry.dp->mem); ln; ln = lnext(ln)) { AVRMEM *m = ldata(ln); + if(mem_is_in_flash(m) && fm != m) { // Overlapping region? unsigned int cpaddr = addr + fm->offset - m->offset; + if(cpaddr < (unsigned int) m->size && cpaddr + chunk <= (unsigned int) m->size) - memmove(m->buf+cpaddr, fm->buf+addr, chunk); + memmove(m->buf + cpaddr, fm->buf + addr, chunk); } } } @@ -502,13 +513,13 @@ static void dryrun_enable(PROGRAMMER *pgm, const AVRPART *p) { unsigned char inifuses[16]; // For fuses: made up from fuse0, fuse1, ... AVRMEM *m, *fusesm = NULL, *prodsigm = NULL, *calm; - AVRPART *q = dry.dp = avr_dup_part(p); // Allocate dryrun part and abbreviate with q + AVRPART *q = dry.dp = avr_dup_part(p); // Allocate dryrun part and abbreviate with q memset(inifuses, 0xff, sizeof inifuses); srandom(dry.seed? dry.seed: time(NULL)); // Initialise the device with factory setting and erase flash/EEPROM to 0xff - for (LNODEID ln=lfirst(q->mem); ln; ln=lnext(ln)) { + for(LNODEID ln = lfirst(q->mem); ln; ln = lnext(ln)) { m = ldata(ln); if(mem_is_in_flash(m) || mem_is_eeprom(m)) { memset(m->buf, 0xff, m->size); @@ -516,12 +527,13 @@ static void dryrun_enable(PROGRAMMER *pgm, const AVRPART *p) { fusesm = m; } else if(mem_is_a_fuse(m) || mem_is_lock(m)) { // Lock, eg, can have 4 bytes: still allow initialisation from initval - if(m->initval != -1 && m->size >=1 && m->size <= (int) sizeof(m->initval)) { - memcpy(m->buf, &m->initval, m->size); // FIXME: relying on little endian here + if(m->initval != -1 && m->size >= 1 && m->size <= (int) sizeof(m->initval)) { + memcpy(m->buf, &m->initval, m->size); // FIXME: relying on little endian here if(mem_is_a_fuse(m)) { int fno = mem_fuse_offset(m); - for(int i = 0; i < m->size && fno+i < (int) sizeof inifuses; i++) // pdicfg has 2 bytes - inifuses[fno+i] = m->initval >> 8*i; + + for(int i = 0; i < m->size && fno + i < (int) sizeof inifuses; i++) // pdicfg has 2 bytes + inifuses[fno + i] = m->initval >> 8*i; } } else { memset(m->buf, 0xff, m->size); @@ -529,7 +541,7 @@ static void dryrun_enable(PROGRAMMER *pgm, const AVRPART *p) { } else if(mem_is_signature(m) && (int) sizeof(q->signature) == m->size) { memcpy(m->buf, q->signature, m->size); } else if(mem_is_calibration(m)) { - memset(m->buf, 'U', m->size); // 'U' for uncalibrated or unknown :) + memset(m->buf, 'U', m->size); // 'U' for uncalibrated or unknown :) } else if(mem_is_osc16err(m)) { memset(m->buf, 'e', m->size); } else if(mem_is_osc20err(m)) { @@ -540,88 +552,95 @@ static void dryrun_enable(PROGRAMMER *pgm, const AVRPART *p) { memset(m->buf, 'O', m->size); } else if(mem_is_sib(m)) { memset(m->buf, 'S', m->size); - } else if( mem_is_tempsense(m)) { - memset(m->buf, 'T', m->size); // 'T' for temperature calibration values + } else if(mem_is_tempsense(m)) { + memset(m->buf, 'T', m->size); // 'T' for temperature calibration values } else if(mem_is_sernum(m)) { - for(int i = 0; i < m->size; i++) // Set serial number UTSRQPONM... - m->buf[i] = dry.random? 'A'+random()%26: 'U'-i >= 'A'? 'U'-i: 0xff; + for(int i = 0; i < m->size; i++) // Set serial number UTSRQPONM... + m->buf[i] = dry.random? 'A' + random()%26: 'U' - i >= 'A'? 'U' - i: 0xff; } else if(mem_is_sigrow(m) && m->size >= 6) { prodsigm = m; memset(m->buf, 0xff, m->size); // Classic parts: signature at even addresses - int n = q->prog_modes & PM_TPI? 1: 2; // ... unless it's the TPI parts t102/t104 - if(q->prog_modes & PM_Classic) - for(int i=0; i<3; i++) + int n = is_tpi(q)? 1: 2; // ... unless it's the TPI parts t102/t104 + + if(is_classic(q)) + for(int i = 0; i < 3; i++) m->buf[n*i] = q->signature[i]; - } else if(mem_is_io(m)) { // Initialise reset values (if known) + } else if(mem_is_io(m)) { // Initialise reset values (if known) int nr; const Register_file *rf = avr_locate_register_file(q, &nr); + if(rf) for(int i = 0; i < nr; i++) if(rf[i].initval != -1 && rf[i].size > 0 && rf[i].size < 5) - if(rf[i].addr >= 0 && rf[i].addr+rf[i].size <= m->size) - for(int k = 0; k < rf[i].size; k++) // FIXME: Assume little endian compiler - m->buf[rf[i].addr+k] = ((unsigned char *) &rf[i].initval)[k]; + if(rf[i].addr >= 0 && rf[i].addr + rf[i].size <= m->size) + for(int k = 0; k < rf[i].size; k++) // FIXME: Assume little endian compiler + m->buf[rf[i].addr + k] = ((unsigned char *) &rf[i].initval)[k]; } } if(prodsigm) { if(q->prog_modes & (PM_UPDI | PM_PDI)) { - for (LNODEID ln=lfirst(q->mem); ln; ln=lnext(ln)) { + for(LNODEID ln = lfirst(q->mem); ln; ln = lnext(ln)) { AVRMEM *m = ldata(ln); - if(m->buf == prodsigm->buf) // Skip prodsig memory + + if(m->buf == prodsigm->buf) // Skip prodsig memory continue; int off = m->offset - prodsigm->offset; int cpy = m->size; + // Submemory of prodsig, eg, signature and tempsense? Copy into prodsig - if(off >= 0 && off+cpy <= prodsigm->size) + if(off >= 0 && off + cpy <= prodsigm->size) memcpy(prodsigm->buf + off, m->buf, cpy); } } - if((q->prog_modes & PM_Classic) && (calm = avr_locate_calibration(q))) { + if(is_classic(q) && (calm = avr_locate_calibration(q))) { // Calibration bytes of classic parts are interspersed with signature - int n, tpi = !!(q->prog_modes & PM_TPI); // ... unless it's the TPI parts t102/t104 - for(int i=0; isize; i++) { - if((n = tpi? 3+i: 2*i+1) < prodsigm->size) + int n, tpi = is_tpi(q); // ... unless it's the TPI parts t102/t104 + + for(int i = 0; i < calm->size; i++) { + if((n = tpi? 3 + i: 2*i + 1) < prodsigm->size) prodsigm->buf[n] = 'U'; } } - if((q->prog_modes & PM_Classic) && (m = avr_locate_sernum(q))) { // m324pb/m328pb, t102/t104 + if(is_classic(q) && (m = avr_locate_sernum(q))) { // m324pb/m328pb, t102/t104 int off = m->offset - prodsigm->offset; int cpy = m->size; - if(off >= 0 && off+cpy <= prodsigm->size) + + if(off >= 0 && off + cpy <= prodsigm->size) memcpy(prodsigm->buf + off, m->buf, cpy); } } if(fusesm) { size_t fusz = fusesm->size; + memcpy(fusesm->buf, inifuses, fusz < sizeof inifuses? fusz: sizeof inifuses); } // Is the programmer a bootloader? - if((m = avr_locate_flash(q)) && m->size >= 1024 && (pgm->prog_modes & PM_SPM)) - dry.bl = (q->prog_modes & PM_UPDI)? DRY_BOTTOM: DRY_TOP; + if((m = avr_locate_flash(q)) && m->size >= 1024 && is_spm(pgm)) + dry.bl = is_updi(q)? DRY_BOTTOM: DRY_TOP; // So that dryrun can emulate AVRDUDE page erase - if(!(pgm->prog_modes & PM_SPM) && (q->prog_modes & (PM_PDI | PM_UPDI))) + if(!is_spm(pgm) && (q->prog_modes & (PM_PDI | PM_UPDI))) pgm->page_erase = dryrun_page_erase; - if(!dry.random && !dry.init) // OK, no further initialisation needed + if(!dry.random && !dry.init) // OK, no further initialisation needed return; int nc, bakverb = verbose; - verbose = -123; // Silently retrieve uP_table[] entry and config list + + verbose = -123; // Silently retrieve uP_table[] entry and config list const Avrintel *up = avr_locate_uP(q); const Configitem *cp = avr_locate_configitems(q, &nc); + verbose = bakverb; AVRMEM *flm = avr_locate_flash(q); AVRMEM *ee = avr_locate_eeprom(q); - int incons = flm && up && ( - up->flashsize != flm->size || flm->size <= 0 || + int incons = flm && up && (up->flashsize != flm->size || flm->size <= 0 || (ee && (up->eepromsize != ee->size || ee->size <= 0)) || up->nboots != q->n_boot_sections || up->nboots < 0 || - up->bootsize != q->boot_section_size || up->bootsize < 0 || - memcmp(up->sigs, q->signature, 3) - ); + up->bootsize != q->boot_section_size || up->bootsize < 0 || memcmp(up->sigs, q->signature, 3) + ); // Ensure can use up and cp with impunity if(!flm || !up || incons || !cp) { @@ -637,20 +656,23 @@ static void dryrun_enable(PROGRAMMER *pgm, const AVRPART *p) { int vtb = putvectortable(q, flm, dry.appstart, dry.init), urbtsz = 0; int urboot = random()%3 && dry.bootsize <= 512 && flm->size >= 1024 && - flm->size >= 4*dry.bootsize && (q->prog_modes & PM_Classic) && (q->prog_modes & PM_SPM); - if(urboot) { // Give some classic parts a small bootloader + flm->size >= 4*dry.bootsize && is_classic(q) && is_spm(q); + if(urboot) { // Give some classic parts a small bootloader int ps = flm->page_size; + urbtsz = dry.bootsize? dry.bootsize: flm->size > 32768? 512: flm->size < 16384? 256: 384; - urbtsz = (urbtsz + ps-1)/ps*ps; + urbtsz = (urbtsz + ps - 1)/ps*ps; if(!dry.bootsize && !dry.datasize) { dry.bootsize += urbtsz; dry.appsize -= urbtsz; dry.bootstart = dry.appsize; } int ubaddr = dry.bootstart; - putflash(pgm, dry.dp, flm, ubaddr, urbtsz, urbtsz==384? U384: U512); + + putflash(pgm, dry.dp, flm, ubaddr, urbtsz, urbtsz == 384? U384: U512); } else if(dry.bootsize) { int btb = 0; + if(dry.bootsize >= 2048) btb = putvectortable(q, flm, dry.bootstart, dry.init); putflash(pgm, dry.dp, flm, dry.bootstart + btb, dry.bootsize - btb, BDATA); @@ -659,7 +681,7 @@ static void dryrun_enable(PROGRAMMER *pgm, const AVRPART *p) { if(dry.datasize) putflash(pgm, dry.dp, flm, dry.datastart, dry.datasize, ADATA); - putflash(pgm, dry.dp, flm, dry.appstart+vtb, dry.appsize-vtb-urbtsz, ROCKS); + putflash(pgm, dry.dp, flm, dry.appstart + vtb, dry.appsize - vtb - urbtsz, ROCKS); for(int i = 0; i < flm->size; i += flm->page_size) sharedflash(pgm, flm, i, flm->page_size); @@ -674,14 +696,13 @@ static void dryrun_enable(PROGRAMMER *pgm, const AVRPART *p) { dry.initialised = 1; } - // Initialise the AVR device and prepare it to accept commands static int dryrun_initialize(const PROGRAMMER *pgm, const AVRPART *p) { pmsg_debug("%s()\n", __func__); /* - * Normally one would select appropriate programming mechanisms here, - * but for dryrun ignore discrepancies... + * Normally one would select appropriate programming mechanisms here, but for + * dryrun ignore discrepancies... int pm = pgm->prog_modes & p->prog_modes; @@ -696,7 +717,6 @@ static int dryrun_initialize(const PROGRAMMER *pgm, const AVRPART *p) { return pgm->program_enable(pgm, p); } - static void dryrun_disable(const PROGRAMMER *pgm) { pmsg_debug("%s()\n", __func__); if(dry.dp) { // Deallocate dryrun part @@ -707,23 +727,20 @@ static void dryrun_disable(const PROGRAMMER *pgm) { return; } - static int dryrun_open(PROGRAMMER *pgm, const char *port) { pmsg_debug("%s(%s)\n", __func__, port? port: "NULL"); return 0; } - static void dryrun_close(PROGRAMMER *pgm) { pmsg_debug("%s()\n", __func__); } - // Emulate flash NOR-memory static void *memand(void *dest, const void *src, size_t n) { - for(size_t i=0; i= (unsigned int) dmem->size || end > (unsigned int) dmem->size) Return("cannot write page [0x%04x, 0x%04x] to %s %s as it is incompatible with memory [0, 0x%04x]", - addr, end-1, dry.dp->desc, dmem->desc, dmem->size-1); + addr, end - 1, dry.dp->desc, dmem->desc, dmem->size - 1); for(; addr < end; addr += chunk) { - chunk = end-addr < page_size? end-addr: page_size; + chunk = end - addr < page_size? end - addr: page_size; // @@@ Check for bootloader write protection here // Unless it is a bootloader flash looks like NOR-memory - (mchr == 'F' && !dry.bl? memand: memcpy)(dmem->buf+addr, m->buf+addr, chunk); + (mchr == 'F' && !dry.bl? memand: memcpy) (dmem->buf + addr, m->buf + addr, chunk); // Copy chunk to overlapping XMEGA's apptable, application, boot and flash memories if(mchr == 'F') @@ -773,7 +790,6 @@ static int dryrun_paged_write(const PROGRAMMER *pgm, const AVRPART *p, const AVR return n_bytes; } - static int dryrun_paged_load(const PROGRAMMER *pgm, const AVRPART *p, const AVRMEM *m, unsigned int page_size, unsigned int addr, unsigned int n_bytes) { @@ -802,18 +818,17 @@ static int dryrun_paged_load(const PROGRAMMER *pgm, const AVRPART *p, const AVRM end = addr + n_bytes; if(addr >= (unsigned int) dmem->size || end > (unsigned int) dmem->size) Return("cannot read page [0x%04x, 0x%04x] from %s %s as it is incompatible with memory [0, 0x%04x]", - addr, end-1, dry.dp->desc, dmem->desc, dmem->size-1); + addr, end - 1, dry.dp->desc, dmem->desc, dmem->size - 1); for(; addr < end; addr += chunk) { - chunk = end-addr < page_size? end-addr: page_size; - memcpy(m->buf+addr, dmem->buf+addr, chunk); + chunk = end - addr < page_size? end - addr: page_size; + memcpy(m->buf + addr, dmem->buf + addr, chunk); } } return n_bytes; } - int dryrun_write_byte(const PROGRAMMER *pgm, const AVRPART *p, const AVRMEM *m, unsigned long addr, unsigned char data) { @@ -831,6 +846,7 @@ int dryrun_write_byte(const PROGRAMMER *pgm, const AVRPART *p, const AVRMEM *m, dry.dp->desc, dmem->desc, dmem->size, m->size); if(dryrun_readonly(pgm, p, dmem, addr)) { unsigned char is; + if(pgm->read_byte(pgm, p, m, addr, &is) >= 0 && is == data) return 0; @@ -839,10 +855,11 @@ int dryrun_write_byte(const PROGRAMMER *pgm, const AVRPART *p, const AVRMEM *m, if(addr >= (unsigned long) dmem->size) Return("cannot write byte to %s %s as address 0x%04lx outside range [0, 0x%04x]", - dry.dp->desc, dmem->desc, addr, dmem->size-1); + dry.dp->desc, dmem->desc, addr, dmem->size - 1); - if(p->prog_modes & (PM_Classic | PM_PDI)) { // Initialise unused bits in classic & XMEGA parts + if(p->prog_modes & (PM_Classic | PM_PDI)) { // Initialise unused bits in classic & XMEGA parts int bitmask = avr_mem_bitmask(dry.dp, dmem, addr); + // Read-modify-write for bitmasked memory data = (data & bitmask) | (dmem->buf[addr] & ~bitmask); } @@ -850,17 +867,18 @@ int dryrun_write_byte(const PROGRAMMER *pgm, const AVRPART *p, const AVRMEM *m, dmem->buf[addr] = data; if(mem_is_fuses(dmem) && addr < 16) { // Copy the byte to corresponding individual fuse - for(LNODEID ln=lfirst(dry.dp->mem); ln; ln=lnext(ln)) { + for(LNODEID ln = lfirst(dry.dp->mem); ln; ln = lnext(ln)) { if(mem_is_a_fuse(dfuse = ldata(ln))) { if(addr == mem_fuse_offset(dfuse)) dfuse->buf[0] = data; - else if(dfuse->size == 2 && addr-1 == mem_fuse_offset(dfuse)) // High byte of 2-byte fuse + else if(dfuse->size == 2 && addr - 1 == mem_fuse_offset(dfuse)) // High byte of 2-byte fuse dfuse->buf[1] = data; } } - } else if(mem_is_a_fuse(m) && (dfuse = avr_locate_fuses(dry.dp))) { // Copy fuse to fuses + } else if(mem_is_a_fuse(m) && (dfuse = avr_locate_fuses(dry.dp))) { // Copy fuse to fuses int fidx = addr + mem_fuse_offset(m); - if(fidx >=0 && fidx < dfuse->size) + + if(fidx >= 0 && fidx < dfuse->size) dfuse->buf[fidx] = data; } @@ -885,9 +903,9 @@ int dryrun_read_byte(const PROGRAMMER *pgm, const AVRPART *p, const AVRMEM *m, if(addr >= (unsigned long) dmem->size) Return("cannot read byte %s %s as address 0x%04lx outside range [0, 0x%04x]", - dry.dp->desc, dmem->desc, addr, dmem->size-1); + dry.dp->desc, dmem->desc, addr, dmem->size - 1); - if(!dry.bl && (mem_is_io(dmem) || mem_is_sram(dmem)) && (p->prog_modes & PM_Classic)) + if(!dry.bl && (mem_is_io(dmem) || mem_is_sram(dmem)) && is_classic(p)) Return("classic part io/sram memories cannot be read externally"); *value = dmem->buf[addr]; @@ -901,7 +919,6 @@ static int dryrun_term_keep_alive(const PROGRAMMER *pgm, const AVRPART *p_unused return 0; } - static int dryrun_rdy_led(const PROGRAMMER *pgm, int value) { pmsg_debug("%s(%d)\n", __func__, value); @@ -926,23 +943,20 @@ static int dryrun_vfy_led(const PROGRAMMER *pgm, int value) { return 0; } - static void dryrun_display(const PROGRAMMER *pgm, const char *p_unused) { // imsg_info("%c%s programmer for %s\n", toupper(*pgmid), pgmid+1, dry.dp? dry.dp->desc: partdesc? partdesc: "???"); return; } - // Return whether an address is write protected -static int dryrun_readonly(const PROGRAMMER *pgm, const AVRPART *p, const AVRMEM *mem, - unsigned int addr) { +static int dryrun_readonly(const PROGRAMMER *pgm, const AVRPART *p, const AVRMEM *mem, unsigned int addr) { if(mem_is_readonly(mem)) return 1; if(!dry.bl) { // io and sram may not be accessible by external programming if(mem_is_io(mem) || mem_is_sram(mem)) - return !(p->prog_modes & PM_UPDI); // Can not even read these externally in classic parts + return !is_updi(p); // Can not even read these externally in classic parts return 0; } @@ -954,21 +968,18 @@ static int dryrun_readonly(const PROGRAMMER *pgm, const AVRPART *p, const AVRMEM return 0; } - static void dryrun_setup(PROGRAMMER *pgm) { pmsg_debug("%s()\n", __func__); // Allocate dry pgm->cookie = mmt_malloc(sizeof(Dryrun_data)); } - static void dryrun_teardown(PROGRAMMER *pgm) { pmsg_debug("%s()\n", __func__); mmt_free(pgm->cookie); pgm->cookie = NULL; } - static int dryrun_parseextparams(const PROGRAMMER *pgm, const LISTID extparms) { int rc = 0; bool help = false; @@ -986,7 +997,8 @@ static int dryrun_parseextparams(const PROGRAMMER *pgm, const LISTID extparms) { } if(str_starts(xpara, "seed=") || str_starts(xpara, "init=") || str_starts(xpara, "random=")) { const char *errptr; - int seed = str_int(strchr(xpara, '=')+1, STR_INT32, &errptr); + int seed = str_int(strchr(xpara, '=') + 1, STR_INT32, &errptr); + if(errptr) { pmsg_error("cannot parse %s seed value: %s\n", xpara, errptr); rc = -1; diff --git a/src/dryrun.h b/src/dryrun.h index c6eefb9b7..7db49bcf6 100644 --- a/src/dryrun.h +++ b/src/dryrun.h @@ -20,8 +20,5 @@ #define dryrun_h__ extern const char dryrun_desc[]; -void dryrun_initpgm (PROGRAMMER *pgm); - +void dryrun_initpgm(PROGRAMMER *pgm); #endif - - diff --git a/src/dryrun_private.h b/src/dryrun_private.h index dd5eb736f..0515769d6 100644 --- a/src/dryrun_private.h +++ b/src/dryrun_private.h @@ -38,7 +38,6 @@ #define Cmnd_STK_READ_SIGN 0x75 // STK_UNIVERSAL commands -#define Subc_STK_UNIVERSAL_LEXT 0x4d000000u // Load extended address -#define Subc_STK_UNIVERSAL_CE 0xac800000u // Chip erase - +#define Subc_STK_UNIVERSAL_LEXT 0x4d000000u // Load extended address +#define Subc_STK_UNIVERSAL_CE 0xac800000u // Chip erase #endif diff --git a/src/fileio.c b/src/fileio.c index 63252b298..f5c2af9b0 100644 --- a/src/fileio.c +++ b/src/fileio.c @@ -28,35 +28,36 @@ #include #ifdef HAVE_LIBELF + #ifdef HAVE_LIBELF_H #include #elif defined(HAVE_LIBELF_LIBELF_H) #include #endif + #ifndef EM_AVR32 -# define EM_AVR32 0x18ad /* unofficial */ +#define EM_AVR32 0x18ad // Unofficial #endif + #ifndef EM_AVR -# define EM_AVR 83 /* OpenBSD lacks it */ +#define EM_AVR 83 // OpenBSD lacks it #endif #endif #include "avrdude.h" #include "libavrdude.h" - // Common internal record structure for ihex and srec files struct ihexsrec { - unsigned char reclen; - unsigned int loadofs; - unsigned char rectyp; - unsigned char data[256]; - unsigned char cksum; + unsigned char reclen; + unsigned int loadofs; + unsigned char rectyp; + unsigned char data[256]; + unsigned char cksum; }; - char *fileio_fmtstr(FILEFMT format) { - switch (format) { + switch(format) { case FMT_AUTO: return "auto-detect"; case FMT_SREC: @@ -87,7 +88,7 @@ char *fileio_fmtstr(FILEFMT format) { } int fileio_fmtchr(FILEFMT format) { - switch (format) { + switch(format) { case FMT_AUTO: return 'a'; case FMT_SREC: @@ -118,7 +119,7 @@ int fileio_fmtchr(FILEFMT format) { } FILEFMT fileio_format(char c) { - switch (c) { + switch(c) { case 'a': return FMT_AUTO; case 's': @@ -148,14 +149,14 @@ FILEFMT fileio_format(char c) { } } - // Same as fileio_format(ch) but show error message with originator who and list possible formats FILEFMT fileio_format_with_errmsg(char ch, const char *who) { FILEFMT format = fileio_format(ch); + if(format == FMT_ERROR) { pmsg_error("%sinvalid file format :%c; known formats are\n", who? who: "", ch); - for(int f, c, i=0; i<62; i++) { - c = i<10? '0'+i: (i&1? 'A': 'a') + (i-10)/2; + for(int f, c, i = 0; i < 62; i++) { + c = i < 10? '0' + i: (i & 1? 'A': 'a') + (i - 10)/2; f = fileio_format(c); if(f != FMT_ERROR) msg_error(" :%c %s\n", c, fileio_fmtstr(f)); @@ -165,7 +166,6 @@ FILEFMT fileio_format_with_errmsg(char ch, const char *who) { return format; } - // Multi-memory file flat address space layout (also used by avr-gcc's elf) enum { @@ -179,7 +179,7 @@ static const struct { unsigned base, size; const char *name; } mulmem[] = { - { 0, 0x800000, "flash"}, // rjmp/call can only address 8 MiB in AVR8 architectures + {0, 0x800000, "flash"}, // rjmp/call can only address 8 MiB in AVR8 architectures {0x800000, 0x10000, "data"}, // IO/SRAM {0x810000, 0x10000, "EEPROM"}, {0x820000, 0x10000, "fuses"}, @@ -217,34 +217,31 @@ unsigned fileio_mem_offset(const AVRPART *p, const AVRMEM *mem) { mem_is_in_flash(mem)? MBASE(FLASH) + mem->offset - boffset(p, flash): mem_is_io(mem) || mem_is_sram(mem)? MBASE(DATA) + mem->offset: mem_is_eeprom(mem)? MBASE(EEPROM): - mem_is_in_fuses(mem)? MBASE(FUSES) + mem_fuse_offset(mem): - mem_is_lock(mem)? MBASE(LOCK): + mem_is_in_fuses(mem)? MBASE(FUSES) + mem_fuse_offset(mem): mem_is_lock(mem)? MBASE(LOCK): // Classic parts intersperse signature and calibration bytes, this code places them together - (p->prog_modes & PM_Classic) && mem_is_signature(mem)? MBASE(SIGROW): - (p->prog_modes & PM_Classic) && mem_is_calibration(mem)? MBASE(SIGROW)+3: - (p->prog_modes & PM_Classic) && mem_is_in_sigrow(mem)? MBASE(SIGROW)+0x10+mem->offset-boffset(p, sigrow): + is_classic(p) && mem_is_signature(mem)? MBASE(SIGROW): + is_classic(p) && mem_is_calibration(mem)? MBASE(SIGROW) + 3: + is_classic(p) && mem_is_in_sigrow(mem)? MBASE(SIGROW) + 0x10 + mem->offset - boffset(p, sigrow): // XMEGA parts have signature separate from prodsig, place prodsig at +0x10 as above - (p->prog_modes & PM_PDI) && mem_is_signature(mem)? MBASE(SIGROW): - (p->prog_modes & PM_PDI) && mem_is_in_sigrow(mem)? MBASE(SIGROW)+0x10 + mem->offset - boffset(p, sigrow): - (p->prog_modes & PM_UPDI) && mem_is_in_sigrow(mem)? MBASE(SIGROW) + mem->offset - boffset(p, sigrow): - mem_is_sib(mem)? MBASE(SIGROW) + 0x1000: // Arbitrary 0x1000 offset in signature section for sib - mem_is_userrow(mem)? MBASE(USERROW): - mem_is_bootrow(mem)? MBASE(BOOTROW): - ~0U; + is_pdi(p) && mem_is_signature(mem)? MBASE(SIGROW): + is_pdi(p) && mem_is_in_sigrow(mem)? MBASE(SIGROW) + 0x10 + mem->offset - boffset(p, sigrow): + is_updi(p) && mem_is_in_sigrow(mem)? MBASE(SIGROW) + mem->offset - boffset(p, sigrow): + mem_is_sib(mem)? MBASE(SIGROW) + 0x1000: // Arbitrary 0x1000 offset in signature section for sib + mem_is_userrow(mem)? MBASE(USERROW): mem_is_bootrow(mem)? MBASE(BOOTROW): ~0U; if(location == ~0U) pmsg_error("unable to locate %s's %s in multi-memory address space\n", p->desc, mem->desc); - else if(location >= ANY_MEM_SIZE || location + mem->size > ANY_MEM_SIZE) { // Overflow + else if(location >= ANY_MEM_SIZE || location + mem->size > ANY_MEM_SIZE) { // Overflow pmsg_error("%s's %s location [0x%06x, 0x%06x] outside flat address space [0, 0x%06x]\n", - p->desc, mem->desc, location, location + mem->size-1, ANY_MEM_SIZE-1); + p->desc, mem->desc, location, location + mem->size - 1, ANY_MEM_SIZE - 1); location = ~0U; - } else if(location <= MEND(FLASH) && location + mem->size > MEND(FLASH)+1) { + } else if(location <= MEND(FLASH) && location + mem->size > MEND(FLASH) + 1) { pmsg_error("%s's %s location [0x%06x, 0x%06x] straddles flash section boundary 0x%06x\n", - p->desc, mem->desc, location, location + mem->size-1, MEND(FLASH)+1); + p->desc, mem->desc, location, location + mem->size - 1, MEND(FLASH) + 1); location = ~0U; - } else if(location > MEND(FLASH) && location/0x10000 != (location + mem->size-1)/0x10000) { + } else if(location > MEND(FLASH) && location/0x10000 != (location + mem->size - 1)/0x10000) { pmsg_error("%s's %s memory location [0x%06x, 0x%06x] straddles memory section boundary 0x%02x0000\n", - p->desc, mem->desc, location, location + mem->size-1, 1+location/0x10000); + p->desc, mem->desc, location, location + mem->size - 1, 1 + location/0x10000); location = ~0U; } @@ -252,7 +249,7 @@ unsigned fileio_mem_offset(const AVRPART *p, const AVRMEM *mem) { } static const char *memlabel(const AVRPART *p, const AVRMEM *m, unsigned addr, int n) { - if(m->size < (int) ANY_MEM_SIZE) // Ordinary (single) memory + if(m->size < (int) ANY_MEM_SIZE) // Ordinary (single) memory return addr? NULL: m->desc; // Inverse lookup of which memory could have been mapped to this address @@ -270,31 +267,28 @@ static const char *memlabel(const AVRPART *p, const AVRMEM *m, unsigned addr, in // Tells lower level .hex/.srec routines whether to write intros/outros typedef enum { FIRST_SEG = 1, - LAST_SEG = 2, + LAST_SEG = 2, } Segorder; - static void print_ihex_extended_addr(int n_64k, FILE *outf) { unsigned char hi = (n_64k >> 8); unsigned char lo = n_64k; unsigned char cksum = -(2 + 0 + 4 + hi + lo); + fprintf(outf, ":02000004%02X%02X%02X\n", hi, lo, cksum); } - - /* * Binary buffer to Intel Hex, see https://en.wikipedia.org/wiki/Intel_HEX * - * Given a buffer and a single segment, segp, an open file 'outf' to - * which to write Intel Hex formatted data, the desired record size - * recsize, an AVR32-specific memory offset startaddr and the name of - * the output file, write a valid Intel Hex file. Where indicates - * whether this is the first segment to be written to the file or - * the last segment (or both). + * Given a buffer and a single segment, segp, an open file 'outf' to which to + * write Intel Hex formatted data, the desired record size recsize, an + * AVR32-specific memory offset startaddr and the name of the output file, + * write a valid Intel Hex file. Where indicates whether this is the first + * segment to be written to the file or the last segment (or both). * - * Return the maximum memory address within mem->buf that was read from - * plus one. If an error occurs, return -1. + * Return the maximum memory address within mem->buf that was read from plus + * one. If an error occurs, return -1. */ static int b2ihex(const AVRPART *p, const AVRMEM *mem, const Segment *segp, Segorder where, int recsize, int startaddr, const char *outfile_unused, FILE *outf, FILEFMT ffmt) { @@ -309,40 +303,41 @@ static int b2ihex(const AVRPART *p, const AVRMEM *mem, const Segment *segp, Sego return -1; } - nextaddr = (unsigned) (startaddr + segp->addr) % 0x10000; - n_64k = (unsigned) (startaddr + segp->addr) / 0x10000; - hiaddr = segp->addr; - buf += segp->addr; + nextaddr = (unsigned) (startaddr + segp->addr)%0x10000; + n_64k = (unsigned) (startaddr + segp->addr)/0x10000; + hiaddr = segp->addr; + buf += segp->addr; // Give address unless it's the first segment and it would be the default 0 if(!((where & FIRST_SEG) && n_64k == 0)) print_ihex_extended_addr(n_64k, outf); - while (bufsize) { + while(bufsize) { n = recsize; - if (n > bufsize) + if(n > bufsize) n = bufsize; - if ((nextaddr + n) > 0x10000) + if((nextaddr + n) > 0x10000) n = 0x10000 - nextaddr; - if (n) { + if(n) { fprintf(outf, ":%02X%04X00", n, nextaddr); unsigned char c, cksum = n + ((nextaddr >> 8) & 0x0ff) + (nextaddr & 0x0ff); - for(int i=0; i ", n_64k*0x10000 + nextaddr); - for(int i=0; i= 0x10000 && bufsize > n) { - /* output an extended address record */ + // Output an extended address record n_64k++; print_ihex_extended_addr(n_64k, outf); nextaddr = 0; } - /* advance to next 'recsize' bytes */ + // Advance to next recsize bytes buf += n; bufsize -= n; } @@ -381,72 +377,70 @@ static int b2ihex(const AVRPART *p, const AVRMEM *mem, const Segment *segp, Sego return hiaddr; } - -static int ihex_readrec(struct ihexsrec *ihex, char * rec) { +static int ihex_readrec(struct ihexsrec *ihex, char *rec) { int i, j; char buf[8]; int offset, len; - char * e; + char *e; unsigned char cksum; - len = strlen(rec); + len = strlen(rec); offset = 1; - cksum = 0; + cksum = 0; - /* reclen */ - if (offset + 2 > len) + // Reclen + if(offset + 2 > len) return -1; - for (i=0; i<2; i++) + for(i = 0; i < 2; i++) buf[i] = rec[offset++]; buf[i] = 0; ihex->reclen = strtoul(buf, &e, 16); - if (e == buf || *e != 0) + if(e == buf || *e != 0) return -1; - /* load offset */ - if (offset + 4 > len) + // Load offset + if(offset + 4 > len) return -1; - for (i=0; i<4; i++) + for(i = 0; i < 4; i++) buf[i] = rec[offset++]; buf[i] = 0; ihex->loadofs = strtoul(buf, &e, 16); - if (e == buf || *e != 0) + if(e == buf || *e != 0) return -1; - /* record type */ - if (offset + 2 > len) + // Record type + if(offset + 2 > len) return -1; - for (i=0; i<2; i++) + for(i = 0; i < 2; i++) buf[i] = rec[offset++]; buf[i] = 0; ihex->rectyp = strtoul(buf, &e, 16); - if (e == buf || *e != 0) + if(e == buf || *e != 0) return -1; - cksum = ihex->reclen + ((ihex->loadofs >> 8) & 0x0ff) + - (ihex->loadofs & 0x0ff) + ihex->rectyp; + cksum = ihex->reclen + ((ihex->loadofs >> 8) & 0x0ff) + (ihex->loadofs & 0x0ff) + ihex->rectyp; - /* data */ - for (j=0; jreclen; j++) { - if (offset + 2 > len) + // Data + for(j = 0; j < ihex->reclen; j++) { + if(offset + 2 > len) return -1; - for (i=0; i<2; i++) + for(i = 0; i < 2; i++) buf[i] = rec[offset++]; buf[i] = 0; ihex->data[j] = strtoul(buf, &e, 16); - if (e == buf || *e != 0) + if(e == buf || *e != 0) return -1; cksum += ihex->data[j]; } - /* cksum */ - if (offset + 2 > len) + // Cksum + if(offset + 2 > len) return -1; - for (i=0; i<2; i++) + for(i = 0; i < 2; i++) buf[i] = rec[offset++]; buf[i] = 0; ihex->cksum = strtoul(buf, &e, 16); - if (e == buf || *e != 0) + if(e == buf || *e != 0) return -1; pmsg_debug("read ihex record type 0x%02x at 0x%04x with %2d bytes and chksum 0x%02x (0x%02x)\n", @@ -455,24 +449,23 @@ static int ihex_readrec(struct ihexsrec *ihex, char * rec) { return -cksum & 0xff; } - // Extract correct memory from large any memory assuming multi-memory model -static int any2mem(const AVRPART *p, const AVRMEM *mem, const Segment *segp, - const AVRMEM *any, unsigned maxsize) { +static int any2mem(const AVRPART *p, const AVRMEM *mem, const Segment *segp, const AVRMEM *any, unsigned maxsize) { // Compute location for multi-memory file input - unsigned location = maxsize > MEND(FLASH)+1? fileio_mem_offset(p, mem): 0; + unsigned location = maxsize > MEND(FLASH) + 1? fileio_mem_offset(p, mem): 0; if(location == ~0U) return -1; unsigned ret = 0; + // Copy over memory to right place and return highest written address plus one for(unsigned i = segp->addr, end = segp->addr + segp->len; i < end; i++) if(any->tags[location + i]) { mem->buf[i] = any->buf[location + i]; mem->tags[i] = any->tags[location + i]; - ret = i+1; + ret = i + 1; } return ret; @@ -481,14 +474,14 @@ static int any2mem(const AVRPART *p, const AVRMEM *mem, const Segment *segp, /* * Intel Hex to binary buffer * - * Given an open file 'inf' which contains Intel Hex formatted data, parse - * the file, which potentially contains many AVR memories, and lay it out - * in a temporary AVR "any memory". This also determines whether inf - * contains the AVR memory mem to write to. Only the segment within - * mem->buf, segp, is written to. + * Given an open file 'inf' which contains Intel Hex formatted data, parse the + * file, which potentially contains many AVR memories, and lay it out in a + * temporary AVR "any memory". This also determines whether inf contains the + * AVR memory mem to write to. Only the segment within mem->buf, segp, is + * written to. * - * Return 0 if nothing was written, otherwise the maximum memory address - * within mem->buf that was written plus one. On error, return -1. + * Return 0 if nothing was written, otherwise the maximum memory address within + * mem->buf that was written plus one. On error, return -1. */ static int ihex2b(const char *infile, FILE *inf, const AVRPART *p, const AVRMEM *mem, const Segment *segp, unsigned int fileoffset, FILEFMT ffmt) { @@ -498,9 +491,9 @@ static int ihex2b(const char *infile, FILE *inf, const AVRPART *p, const AVRMEM int lineno, rc; struct ihexsrec ihex; - lineno = 0; + lineno = 0; baseaddr = 0; - maxaddr = 0; + maxaddr = 0; nextaddr = 0; rewind(inf); @@ -509,7 +502,8 @@ static int ihex2b(const char *infile, FILE *inf, const AVRPART *p, const AVRMEM for(char *buffer; (buffer = str_fgets(inf, &errstr)); mmt_free(buffer)) { lineno++; int len = strlen(buffer); - if(len > 0 && buffer[len-1] == '\n') + + if(len > 0 && buffer[len - 1] == '\n') buffer[--len] = 0; if(len == 0 || buffer[0] != ':') continue; @@ -532,85 +526,86 @@ static int ihex2b(const char *infile, FILE *inf, const AVRPART *p, const AVRMEM } unsigned below = 0, anysize = any->size; - switch (ihex.rectyp) { - case 0: /* data record */ - if(ihex.loadofs + baseaddr < fileoffset) { - if(!ovsigck) { - pmsg_error("address 0x%06x below memory offset 0x%x at line %d of %s;\n", - ihex.loadofs + baseaddr, fileoffset, lineno, infile); - imsg_error("use -F to skip this check\n"); - mmt_free(buffer); - goto error; - } - pmsg_warning("address 0x%06x below memory offset 0x%x at line %d of %s: ", + + switch(ihex.rectyp) { + case 0: // Data record + if(ihex.loadofs + baseaddr < fileoffset) { + if(!ovsigck) { + pmsg_error("address 0x%06x below memory offset 0x%x at line %d of %s;\n", ihex.loadofs + baseaddr, fileoffset, lineno, infile); - below = fileoffset - baseaddr - ihex.loadofs; - if(below < ihex.reclen) { // Clip record - ihex.reclen -= below; - ihex.loadofs += below; - } else { // Nothing to write - ihex.reclen = 0; - } - msg_warning("%s record\n", ihex.reclen? "clipping": "ignoring"); + imsg_error("use -F to skip this check\n"); + mmt_free(buffer); + goto error; + } + pmsg_warning("address 0x%06x below memory offset 0x%x at line %d of %s: ", + ihex.loadofs + baseaddr, fileoffset, lineno, infile); + below = fileoffset - baseaddr - ihex.loadofs; + if(below < ihex.reclen) { // Clip record + ihex.reclen -= below; + ihex.loadofs += below; + } else { // Nothing to write + ihex.reclen = 0; + } + msg_warning("%s record\n", ihex.reclen? "clipping": "ignoring"); + } + nextaddr = ihex.loadofs + baseaddr - fileoffset; + if(ihex.reclen && nextaddr + ihex.reclen > anysize) { + if(!ovsigck) { + pmsg_error("Intel Hex record [0x%06x, 0x%06x] out of range [0, 0x%06x]\n", + nextaddr, nextaddr + ihex.reclen - 1, anysize - 1); + imsg_error("at line %d of %s; use -F to skip this check\n", lineno, infile); + mmt_free(buffer); + goto error; } - nextaddr = ihex.loadofs + baseaddr - fileoffset; + pmsg_warning("Intel Hex record [0x%06x, 0x%06x] out of range [0, 0x%06x]: ", + nextaddr, nextaddr + ihex.reclen - 1, anysize - 1); if(ihex.reclen && nextaddr + ihex.reclen > anysize) { - if(!ovsigck) { - pmsg_error("Intel Hex record [0x%06x, 0x%06x] out of range [0, 0x%06x]\n", - nextaddr, nextaddr+ihex.reclen-1, anysize-1); - imsg_error("at line %d of %s; use -F to skip this check\n", lineno, infile); - mmt_free(buffer); - goto error; - } - pmsg_warning("Intel Hex record [0x%06x, 0x%06x] out of range [0, 0x%06x]: ", - nextaddr, nextaddr+ihex.reclen-1, anysize-1); - if(ihex.reclen && nextaddr + ihex.reclen > anysize) { - unsigned above = nextaddr + ihex.reclen - anysize; - ihex.reclen = above < ihex.reclen? ihex.reclen - above: 0; // Clip or zap - } - msg_warning("%s it\n", ihex.reclen? "clipping": "ignoring"); + unsigned above = nextaddr + ihex.reclen - anysize; + + ihex.reclen = above < ihex.reclen? ihex.reclen - above: 0; // Clip or zap } - for(int i=0; ibuf[nextaddr+i] = ihex.data[below + i]; - any->tags[nextaddr+i] = TAG_ALLOCATED; + msg_warning("%s it\n", ihex.reclen? "clipping": "ignoring"); + } + for(int i = 0; i < ihex.reclen; i++) { + any->buf[nextaddr + i] = ihex.data[below + i]; + any->tags[nextaddr + i] = TAG_ALLOCATED; + } + if(!ovsigck && nextaddr == mulmem[MULTI_SIGROW].base && ihex.reclen >= 3) + if(!avr_sig_compatible(p->signature, any->buf + nextaddr)) { + pmsg_error("signature of %s incompatible with file's (%s);\n", p->desc, + str_ccmcunames_signature(any->buf + nextaddr, PM_ALL)); + imsg_error("use -F to override this check\n"); + mmt_free(buffer); + goto error; } - if(!ovsigck && nextaddr == mulmem[MULTI_SIGROW].base && ihex.reclen >= 3) - if(!avr_sig_compatible(p->signature, any->buf+nextaddr)) { - pmsg_error("signature of %s incompatible with file's (%s);\n", p->desc, - str_ccmcunames_signature(any->buf+nextaddr, PM_ALL)); - imsg_error("use -F to override this check\n"); - mmt_free(buffer); - goto error; - } - if(ihex.reclen && nextaddr+ihex.reclen > maxaddr) - maxaddr = nextaddr+ihex.reclen; - break; + if(ihex.reclen && nextaddr + ihex.reclen > maxaddr) + maxaddr = nextaddr + ihex.reclen; + break; - case 1: /* end of file record */ - mmt_free(buffer); - goto done; + case 1: // End of file record + mmt_free(buffer); + goto done; - case 2: /* extended segment address record */ - baseaddr = (ihex.data[0] << 8 | ihex.data[1]) << 4; - break; + case 2: // Extended segment address record + baseaddr = (ihex.data[0] << 8 | ihex.data[1]) << 4; + break; - case 3: /* Start segment address record */ - /* we don't do anything with the start address */ - break; + case 3: // Start segment address record + // We don't do anything with the start address + break; - case 4: /* extended linear address record */ - baseaddr = (ihex.data[0] << 8 | ihex.data[1]) << 16; - break; + case 4: // Extended linear address record + baseaddr = (ihex.data[0] << 8 | ihex.data[1]) << 16; + break; - case 5: /* start linear address record */ - /* we don't do anything with the start address */ - break; + case 5: // Start linear address record + // We don't do anything with the start address + break; - default: - pmsg_error("do not know how to deal with rectype=%d " - "at line %d of %s\n", ihex.rectyp, lineno, infile); - mmt_free(buffer); - goto error; + default: + pmsg_error("do not know how to deal with rectype=%d " "at line %d of %s\n", ihex.rectyp, lineno, infile); + mmt_free(buffer); + goto error; } } @@ -619,7 +614,7 @@ static int ihex2b(const char *infile, FILE *inf, const AVRPART *p, const AVRMEM goto error; } - if (maxaddr == 0) { + if(maxaddr == 0) { pmsg_error("no valid record found in Intel Hex file %s\n", infile); goto error; } @@ -641,16 +636,15 @@ static int ihex2b(const char *infile, FILE *inf, const AVRPART *p, const AVRMEM static unsigned int cksum_srec(const unsigned char *buf, int n, unsigned addr, int addr_width) { unsigned char cksum = n + addr_width + 1; - for(int i=0; i>= 8; - for(int i=0; iaddr; hiaddr = 0; - unsigned highest = startaddr + mem->size-1; + unsigned highest = startaddr + mem->size - 1; // Assume same address width throughout, even across different segments char datarec, endrec; + if(highest <= 0xffffu) { addr_width = 2; datarec = '1'; @@ -681,16 +676,16 @@ static int b2srec(const AVRMEM *mem, const Segment *segp, Segorder where, endrec = '7'; } - if(recsize < 1 || recsize > 255-1-addr_width) { - pmsg_error("recsize %d must be in [1, %d]\n", recsize, 255-1-addr_width); + if(recsize < 1 || recsize > 255 - 1 - addr_width) { + pmsg_error("recsize %d must be in [1, %d]\n", recsize, 255 - 1 - addr_width); return -1; } - + if(where & FIRST_SEG) { // Write header record const char *s = "https://github.com/avrdudes/avrdude"; unsigned char len = strlen(s); - fprintf(outf, "S0%02X0000", len+3); + fprintf(outf, "S0%02X0000", len + 3); for(int i = 0; i < len; i++) fprintf(outf, "%02X", s[i]); fprintf(outf, "%02X\n", cksum_srec((unsigned char *) s, len, 0, 2)); @@ -703,13 +698,13 @@ static int b2srec(const AVRMEM *mem, const Segment *segp, Segorder where, n = bufsize; fprintf(outf, "S%c%02X%0*X", datarec, n + addr_width + 1, 2*addr_width, nextaddr); - for(int i=0; ireccount++; } @@ -717,8 +712,9 @@ static int b2srec(const AVRMEM *mem, const Segment *segp, Segorder where, if(where & LAST_SEG) { if(cx->reccount >= 0 && cx->reccount <= 0xffffff) { int wd = cx->reccount <= 0xffff? 2: 3; - fprintf(outf, "S%c%02X%0*X%02X\n", '5' + (wd == 3), wd + 1, 2*wd, cx->reccount, - cksum_srec(NULL, 0, cx->reccount, wd)); + + fprintf(outf, "S%c%02X%0*X%02X\n", '5' + (wd == 3), wd + 1, 2*wd, + cx->reccount, cksum_srec(NULL, 0, cx->reccount, wd)); } fprintf(outf, "S%c%02X%0*X", endrec, addr_width + 1, 2*addr_width, startaddr); fprintf(outf, "%02X\n", cksum_srec(NULL, 0, startaddr, addr_width)); @@ -731,7 +727,7 @@ static int srec_readrec(struct ihexsrec *srec, char *rec) { int i, j; char buf[8]; int offset, len, addr_width; - char * e; + char *e; unsigned char cksum; int rc; @@ -740,61 +736,61 @@ static int srec_readrec(struct ihexsrec *srec, char *rec) { cksum = 0; addr_width = 2; - /* record type */ - if (offset + 1 > len) + // Record type + if(offset + 1 > len) return -1; srec->rectyp = rec[offset++]; - if (srec->rectyp == 0x32 || srec->rectyp == 0x38) - addr_width = 3; /* S2,S8-record */ - else if (srec->rectyp == 0x33 || srec->rectyp == 0x37) - addr_width = 4; /* S3,S7-record */ + if(srec->rectyp == 0x32 || srec->rectyp == 0x38) + addr_width = 3; // S2 or S8-record + else if(srec->rectyp == 0x33 || srec->rectyp == 0x37) + addr_width = 4; // S3 or S7-record - /* reclen */ - if (offset + 2 > len) + // Reclen + if(offset + 2 > len) return -1; - for (i=0; i<2; i++) + for(i = 0; i < 2; i++) buf[i] = rec[offset++]; buf[i] = 0; srec->reclen = strtoul(buf, &e, 16); cksum += srec->reclen; - srec->reclen -= (addr_width+1); - if (e == buf || *e != 0) + srec->reclen -= (addr_width + 1); + if(e == buf || *e != 0) return -1; - /* load offset */ - if (offset + addr_width > len) + // Load offset + if(offset + addr_width > len) return -1; - for (i=0; iloadofs = strtoull(buf, &e, 16); - if (e == buf || *e != 0) + if(e == buf || *e != 0) return -1; - for (i=addr_width; i>0; i--) - cksum += (srec->loadofs >> (i - 1) * 8) & 0xff; + for(i = addr_width; i > 0; i--) + cksum += (srec->loadofs >> (i - 1)*8) & 0xff; - /* data */ - for (j=0; jreclen; j++) { - if (offset+2 > len) + // Data + for(j = 0; j < srec->reclen; j++) { + if(offset + 2 > len) return -1; - for (i=0; i<2; i++) + for(i = 0; i < 2; i++) buf[i] = rec[offset++]; buf[i] = 0; srec->data[j] = strtoul(buf, &e, 16); - if (e == buf || *e != 0) + if(e == buf || *e != 0) return -1; cksum += srec->data[j]; } - /* cksum */ - if (offset + 2 > len) + // Cksum + if(offset + 2 > len) return -1; - for (i=0; i<2; i++) + for(i = 0; i < 2; i++) buf[i] = rec[offset++]; buf[i] = 0; srec->cksum = strtoul(buf, &e, 16); - if (e == buf || *e != 0) + if(e == buf || *e != 0) return -1; rc = 0xff - cksum; @@ -802,7 +798,7 @@ static int srec_readrec(struct ihexsrec *srec, char *rec) { } // Motorola S-Record to binary -static int srec2b(const char *infile, FILE * inf, const AVRPART *p, +static int srec2b(const char *infile, FILE *inf, const AVRPART *p, const AVRMEM *mem, const Segment *segp, unsigned int fileoffset) { const char *errstr; @@ -812,8 +808,8 @@ static int srec2b(const char *infile, FILE * inf, const AVRPART *p, unsigned int reccount; unsigned char datarec; - lineno = 0; - maxaddr = 0; + lineno = 0; + maxaddr = 0; reccount = 0; rewind(inf); @@ -822,7 +818,8 @@ static int srec2b(const char *infile, FILE * inf, const AVRPART *p, for(char *buffer; (buffer = str_fgets(inf, &errstr)); mmt_free(buffer)) { lineno++; int len = strlen(buffer); - if(len > 0 && buffer[len-1] == '\n') + + if(len > 0 && buffer[len - 1] == '\n') buffer[--len] = 0; if(len == 0 || buffer[0] != 'S') continue; @@ -839,57 +836,58 @@ static int srec2b(const char *infile, FILE * inf, const AVRPART *p, goto error; } - datarec=0; - hexdigs=4; - switch (srec.rectyp) { - case '0': // S0: header record, ignore - break; + datarec = 0; + hexdigs = 4; + switch(srec.rectyp) { + case '0': // S0: header record, ignore + break; - case '1': // S1: 16 bit address data record - datarec=1; - break; + case '1': // S1: 16 bit address data record + datarec = 1; + break; - case '2': // S2: 24 bit address data record - datarec=1; - hexdigs=6; - break; + case '2': // S2: 24 bit address data record + datarec = 1; + hexdigs = 6; + break; - case '3': // S3: 32 bit address data record - datarec=1; - hexdigs=8; - break; + case '3': // S3: 32 bit address data record + datarec = 1; + hexdigs = 8; + break; - case '4': // S4: symbol record (LSI extension) - pmsg_error("not supported record at line %d of %s\n", lineno, infile); + case '4': // S4: symbol record (LSI extension) + pmsg_error("not supported record at line %d of %s\n", lineno, infile); + mmt_free(buffer); + goto error; + + case '5': // S5: count of S1, S2 and S3 records previously tx'd + if(srec.loadofs != reccount) { + pmsg_error("count of transmitted data records mismatch at line %d of %s\n", lineno, infile); + imsg_error("transmitted data records= %d, expected value= %d\n", reccount, srec.loadofs); mmt_free(buffer); goto error; + } + break; - case '5': // S5: count of S1, S2 and S3 records previously tx'd - if (srec.loadofs != reccount){ - pmsg_error("count of transmitted data records mismatch at line %d of %s\n", lineno, infile); - imsg_error("transmitted data records= %d, expected value= %d\n", reccount, srec.loadofs); - mmt_free(buffer); - goto error; - } - break; - - case '7': // S7: end record for 32 bit addresses - case '8': // S8: end record for 24 bit addresses - case '9': // S9: end record for 16 bit addresses - mmt_free(buffer); - goto done; + case '7': // S7: end record for 32 bit addresses + case '8': // S8: end record for 24 bit addresses + case '9': // S9: end record for 16 bit addresses + mmt_free(buffer); + goto done; - default: - pmsg_error("do not know how to deal with rectype S%d at line %d of %s\n", - srec.rectyp, lineno, infile); - mmt_free(buffer); - goto error; + default: + pmsg_error("do not know how to deal with rectype S%d at line %d of %s\n", + srec.rectyp, lineno, infile); + mmt_free(buffer); + goto error; } - if (datarec == 1) { + if(datarec == 1) { nextaddr = srec.loadofs; unsigned below = 0, anysize = any->size; - if (nextaddr < fileoffset) { + + if(nextaddr < fileoffset) { if(!ovsigck) { pmsg_error("address 0x%0*x below memory offset 0x%x at line %d of %s\n", hexdigs, nextaddr, fileoffset, lineno, infile); @@ -900,7 +898,7 @@ static int srec2b(const char *infile, FILE * inf, const AVRPART *p, pmsg_warning("address 0x%0*x below memory offset 0x%x at line %d of %s: ", hexdigs, nextaddr, fileoffset, lineno, infile); below = fileoffset - nextaddr; - if(below < srec.reclen) { // Clip record + if(below < srec.reclen) { // Clip record nextaddr += below; srec.reclen -= below; } else { // Ignore record @@ -912,35 +910,36 @@ static int srec2b(const char *infile, FILE * inf, const AVRPART *p, if(srec.reclen && nextaddr + srec.reclen > anysize) { if(!ovsigck) { pmsg_error("Motorola S-Record [0x%06x, 0x%06x] out of range [0, 0x%06x]\n", - nextaddr, nextaddr+srec.reclen-1, anysize-1); + nextaddr, nextaddr + srec.reclen - 1, anysize - 1); imsg_error("at line %d of %s; use -F to skip this check\n", lineno, infile); mmt_free(buffer); goto error; } pmsg_warning("Motorola S-Record [0x%06x, 0x%06x] out of range [0, 0x%06x]: ", - nextaddr, nextaddr+srec.reclen-1, anysize-1); + nextaddr, nextaddr + srec.reclen - 1, anysize - 1); if(srec.reclen && nextaddr + srec.reclen > anysize) { unsigned above = nextaddr + srec.reclen - anysize; - srec.reclen = above < srec.reclen? srec.reclen - above: 0; // Clip or zap + + srec.reclen = above < srec.reclen? srec.reclen - above: 0; // Clip or zap } msg_warning("%s it\n", srec.reclen? "clipping": "ignoring"); } - for(int i=0; ibuf[nextaddr+i] = srec.data[below + i]; - any->tags[nextaddr+i] = TAG_ALLOCATED; + for(int i = 0; i < srec.reclen; i++) { + any->buf[nextaddr + i] = srec.data[below + i]; + any->tags[nextaddr + i] = TAG_ALLOCATED; } if(!ovsigck && nextaddr == mulmem[MULTI_SIGROW].base && srec.reclen >= 3) - if(!avr_sig_compatible(p->signature, any->buf+nextaddr)) { + if(!avr_sig_compatible(p->signature, any->buf + nextaddr)) { pmsg_error("signature of %s incompatible with file's (%s);\n", p->desc, - str_ccmcunames_signature(any->buf+nextaddr, PM_ALL)); + str_ccmcunames_signature(any->buf + nextaddr, PM_ALL)); imsg_error("use -F to override this check\n"); mmt_free(buffer); goto error; } - if(srec.reclen && nextaddr+srec.reclen > maxaddr) - maxaddr = nextaddr+srec.reclen; - reccount++; + if(srec.reclen && nextaddr + srec.reclen > maxaddr) + maxaddr = nextaddr + srec.reclen; + reccount++; } } @@ -962,39 +961,33 @@ static int srec2b(const char *infile, FILE * inf, const AVRPART *p, return -1; } - #ifdef HAVE_LIBELF + /* - * Determine whether the ELF file section pointed to by `sh' fits - * completely into the program header segment pointed to by `ph'. + * Determine whether the ELF file section pointed to by `sh' fits completely + * into the program header segment pointed to by `ph'. * - * Assumes the section has been checked already before to actually - * contain data (SHF_ALLOC, SHT_PROGBITS, sh_size > 0). + * Assumes the section has been checked already before to actually contain data + * (SHF_ALLOC, SHT_PROGBITS, sh_size > 0). * - * Sometimes, program header segments might be larger than the actual - * file sections. On VM architectures, this is used to allow mmapping - * the entire ELF file "as is" (including things like the program - * header table itself). + * Sometimes, program header segments might be larger than the actual file + * sections. On VM architectures, this is used to allow mmapping the entire + * ELF file "as is" (including things like the program header table itself). */ -static inline int is_section_in_segment(Elf32_Shdr *sh, Elf32_Phdr *ph) -{ - if (sh->sh_offset < ph->p_offset) - return 0; - if (sh->sh_offset + sh->sh_size > ph->p_offset + ph->p_filesz) - return 0; - return 1; +static inline int is_section_in_segment(Elf32_Shdr *sh, Elf32_Phdr *ph) { + if(sh->sh_offset < ph->p_offset) + return 0; + if(sh->sh_offset + sh->sh_size > ph->p_offset + ph->p_filesz) + return 0; + return 1; } - static int elf_mem_limits(const AVRMEM *mem, const AVRPART *p, - unsigned int *lowbound, - unsigned int *highbound, - unsigned int *fileoff) -{ + unsigned int *lowbound, unsigned int *highbound, unsigned int *fileoff) { int rv = 0; - if (p->prog_modes & PM_aWire) { // AVR32 - if (mem_is_flash(mem)) { + if(is_awire(p)) { // AVR32 + if(mem_is_flash(mem)) { *lowbound = 0x80000000; *highbound = 0xffffffff; *fileoff = 0; @@ -1002,35 +995,35 @@ static int elf_mem_limits(const AVRMEM *mem, const AVRPART *p, rv = -1; } } else { - if (mem_is_in_flash(mem)) { + if(mem_is_in_flash(mem)) { *lowbound = MBASE(FLASH); *highbound = MEND(FLASH); // Max 8 MiB *fileoff = 0; - } else if (mem_is_io(mem) || mem_is_sram(mem)) { // IO & SRAM in data space + } else if(mem_is_io(mem) || mem_is_sram(mem)) { // IO & SRAM in data space *lowbound = MBASE(DATA) + mem->offset; *highbound = MEND(DATA); *fileoff = 0; - } else if (mem_is_eeprom(mem)) { + } else if(mem_is_eeprom(mem)) { *lowbound = MBASE(EEPROM); - *highbound = MEND(EEPROM); // Max 64 KiB + *highbound = MEND(EEPROM); // Max 64 KiB *fileoff = 0; - } else if (mem_is_a_fuse(mem) || mem_is_fuses(mem)) { + } else if(mem_is_a_fuse(mem) || mem_is_fuses(mem)) { *lowbound = MBASE(FUSES); *highbound = MEND(FUSES); *fileoff = mem_is_a_fuse(mem)? mem_fuse_offset(mem): 0; - } else if (mem_is_lock(mem)) { // Lock or lockbits + } else if(mem_is_lock(mem)) { // Lock or lockbits *lowbound = MBASE(LOCK); *highbound = MEND(LOCK); *fileoff = 0; - } else if (mem_is_signature(mem)) { // Read only + } else if(mem_is_signature(mem)) { // Read only *lowbound = MBASE(SIGROW); *highbound = MEND(SIGROW); *fileoff = 0; - } else if (mem_is_userrow(mem)) { // usersig or userrow + } else if(mem_is_userrow(mem)) { // usersig or userrow *lowbound = MBASE(USERROW); *highbound = MEND(USERROW); *fileoff = 0; - } else if (mem_is_bootrow(mem)) { + } else if(mem_is_bootrow(mem)) { *lowbound = MBASE(BOOTROW); *highbound = MEND(BOOTROW); *fileoff = 0; @@ -1042,7 +1035,6 @@ static int elf_mem_limits(const AVRMEM *mem, const AVRPART *p, return rv; } - // ELF format to binary (the memory segment to read into is ignored) static int elf2b(const char *infile, FILE *inf, const AVRMEM *mem, const AVRPART *p, const Segment *segp_unused, unsigned int fileoffset_unused) { @@ -1051,38 +1043,38 @@ static int elf2b(const char *infile, FILE *inf, const AVRMEM *mem, int rv = 0, size = 0; unsigned int low, high, foff; - if (elf_mem_limits(mem, p, &low, &high, &foff) != 0) { + if(elf_mem_limits(mem, p, &low, &high, &foff) != 0) { pmsg_error("cannot handle %s memory region from ELF file\n", mem->desc); return -1; } /* - * The Xmega memory regions for "boot", "application", and - * "apptable" are actually sub-regions of "flash". Refine the - * applicable limits. This allows to select only the appropriate - * sections out of an ELF file that contains section data for more - * than one sub-segment. + * The Xmega memory regions for "boot", "application", and "apptable" are + * actually sub-regions of "flash". Refine the applicable limits. This + * allows to select only the appropriate sections out of an ELF file that + * contains section data for more than one sub-segment. */ - if ((p->prog_modes & PM_PDI) && mem_is_in_flash(mem) && !mem_is_flash(mem)) { + if(is_pdi(p) && mem_is_in_flash(mem) && !mem_is_flash(mem)) { AVRMEM *flashmem = avr_locate_flash(p); - if (flashmem == NULL) { + + if(flashmem == NULL) { pmsg_error("no flash memory region found, cannot compute bounds of %s sub-region\n", mem->desc); return -1; } - /* The config file offsets are PDI offsets, rebase to 0. */ + // The config file offsets are PDI offsets, rebase to 0 low = mem->offset - flashmem->offset; high = low + mem->size - 1; } - if (elf_version(EV_CURRENT) == EV_NONE) { + if(elf_version(EV_CURRENT) == EV_NONE) { pmsg_error("ELF library initialization failed: %s\n", elf_errmsg(-1)); return -1; } - if ((e = elf_begin(fileno(inf), ELF_C_READ, NULL)) == NULL) { + if((e = elf_begin(fileno(inf), ELF_C_READ, NULL)) == NULL) { pmsg_error("cannot open %s as an ELF file: %s\n", infile, elf_errmsg(-1)); return -1; } - if (elf_kind(e) != ELF_K_ELF) { + if(elf_kind(e) != ELF_K_ELF) { pmsg_error("cannot use %s as an ELF input file\n", infile); goto done; } @@ -1090,97 +1082,101 @@ static int elf2b(const char *infile, FILE *inf, const AVRMEM *mem, size_t i, isize; const char *id = elf_getident(e, &isize); - if (id == NULL) { + if(id == NULL) { pmsg_error("unable to read ident area of %s: %s\n", infile, elf_errmsg(-1)); goto done; } const char *endianname; unsigned char endianness; - if (p->prog_modes & PM_aWire) { // AVR32 + + if(is_awire(p)) { // AVR32 endianness = ELFDATA2MSB; endianname = "little"; } else { endianness = ELFDATA2LSB; endianname = "big"; } - if (id[EI_CLASS] != ELFCLASS32 || - id[EI_DATA] != endianness) { - pmsg_error("ELF file %s is not a 32-bit, %s-endian file that was expected\n", - infile, endianname); + if(id[EI_CLASS] != ELFCLASS32 || id[EI_DATA] != endianness) { + pmsg_error("ELF file %s is not a 32-bit, %s-endian file that was expected\n", infile, endianname); goto done; } Elf32_Ehdr *eh; - if ((eh = elf32_getehdr(e)) == NULL) { + + if((eh = elf32_getehdr(e)) == NULL) { pmsg_error("unable to read ehdr of %s: %s\n", infile, elf_errmsg(-1)); goto done; } - if (eh->e_type != ET_EXEC) { + if(eh->e_type != ET_EXEC) { pmsg_error("ELF file %s is not an executable file\n", infile); goto done; } const char *mname; uint16_t machine; - if (p->prog_modes & PM_aWire) { + + if(is_awire(p)) { machine = EM_AVR32; mname = "AVR32"; } else { machine = EM_AVR; mname = "AVR"; } - if (eh->e_machine != machine) { + if(eh->e_machine != machine) { pmsg_error("ELF file %s is not for machine %s\n", infile, mname); goto done; } - if (eh->e_phnum == 0xffff /* PN_XNUM */) { + if(eh->e_phnum == 0xffff /* PN_XNUM */) { pmsg_error("ELF file %s uses extended program header numbers which are not expected\n", infile); goto done; } Elf32_Phdr *ph; - if ((ph = elf32_getphdr(e)) == NULL) { + + if((ph = elf32_getphdr(e)) == NULL) { pmsg_error("unable to read program header table of %s: %s\n", infile, elf_errmsg(-1)); goto done; } size_t sndx; - if (elf_getshdrstrndx(e, &sndx) != 0) { + + if(elf_getshdrstrndx(e, &sndx) != 0) { pmsg_error("unable to obtain section name string table: %s\n", elf_errmsg(-1)); sndx = 0; } /* - * Walk the program header table, pick up entries that are of type - * PT_LOAD, and have a non-zero p_filesz. + * Walk the program header table, pick up entries that are of type PT_LOAD, + * and have a non-zero p_filesz. */ - for (i = 0; i < eh->e_phnum; i++) { - if (ph[i].p_type != PT_LOAD || ph[i].p_filesz == 0) + for(i = 0; i < eh->e_phnum; i++) { + if(ph[i].p_type != PT_LOAD || ph[i].p_filesz == 0) continue; pmsg_debug("considering PT_LOAD program header entry #%d\n", (int) i); imsg_debug("p_vaddr 0x%x, p_paddr 0x%x, p_filesz %d\n", ph[i].p_vaddr, ph[i].p_paddr, ph[i].p_filesz); Elf_Scn *scn = NULL; - while ((scn = elf_nextscn(e, scn)) != NULL) { + + while((scn = elf_nextscn(e, scn)) != NULL) { size_t ndx = elf_ndxscn(scn); Elf32_Shdr *sh = elf32_getshdr(scn); - if (sh == NULL) { + if(sh == NULL) { pmsg_error("unable to read section #%u header: %s\n", (unsigned int) ndx, elf_errmsg(-1)); rv = -1; continue; } // Only interested in PROGBITS, ALLOC sections - if ((sh->sh_flags & SHF_ALLOC) == 0 || sh->sh_type != SHT_PROGBITS) + if((sh->sh_flags & SHF_ALLOC) == 0 || sh->sh_type != SHT_PROGBITS) continue; // Not interested in empty sections - if (sh->sh_size == 0) + if(sh->sh_size == 0) continue; // Section must belong to this segment - if (!is_section_in_segment(sh, ph+i)) + if(!is_section_in_segment(sh, ph + i)) continue; const char *sname = sndx? elf_strptr(e, sndx, sh->sh_name): "*unknown*"; @@ -1193,14 +1189,14 @@ static int elf2b(const char *infile, FILE *inf, const AVRMEM *mem, continue; } /* - * 1-byte sized memory regions are special: they are used for fuse - * bits, where multiple regions (in the config file) map to a - * single, larger region in the ELF file (e.g. "lfuse", "hfuse", - * and "efuse" all map to ".fuse"). We silently accept a larger - * ELF file region for these, and extract the actual byte to write - * from it, using the "foff" offset obtained above. + * 1-byte sized memory regions are special: they are used for fuse bits, + * where multiple regions (in the config file) map to a single, larger + * region in the ELF file (e.g. "lfuse", "hfuse", and "efuse" all map to + * ".fuse"). We silently accept a larger ELF file region for these, and + * extract the actual byte to write from it, using the "foff" offset + * obtained above. */ - if (mem->size != 1 && sh->sh_size > (unsigned) mem->size) { + if(mem->size != 1 && sh->sh_size > (unsigned) mem->size) { pmsg_error("section %s of size %u does not fit into %s of size %d\n", sname, sh->sh_size, mem->desc, mem->size); rv = -1; @@ -1208,35 +1204,36 @@ static int elf2b(const char *infile, FILE *inf, const AVRMEM *mem, } Elf_Data *d = NULL; - while ((d = elf_getdata(scn, d)) != NULL) { + + while((d = elf_getdata(scn, d)) != NULL) { pmsg_debug("data block: d_buf %p, d_off 0x%x, d_size %ld\n", - d->d_buf, (unsigned int)d->d_off, (long) d->d_size); - if (mem->size == 1) { - if (d->d_off != 0) { + d->d_buf, (unsigned int) d->d_off, (long) d->d_size); + if(mem->size == 1) { + if(d->d_off != 0) { pmsg_error("unexpected data block at offset != 0\n"); rv = -1; - } else if (foff >= d->d_size) { + } else if(foff >= d->d_size) { pmsg_error("ELF file section does not contain byte at offset %d\n", foff); rv = -1; } else { pmsg_debug("extracting one byte from file offset %d\n", foff); - mem->buf[0] = ((unsigned char *)d->d_buf)[foff]; + mem->buf[0] = ((unsigned char *) d->d_buf)[foff]; mem->tags[0] = TAG_ALLOCATED; size = 1; } } else { - int idx = lma-low + d->d_off; + int idx = lma - low + d->d_off; int end = idx + d->d_size; - if(idx >= 0 && idx < mem->size && end >= 0 && end <= mem->size && end-idx >= 0) { - if (end > size) + if(idx >= 0 && idx < mem->size && end >= 0 && end <= mem->size && end - idx >= 0) { + if(end > size) size = end; - pmsg_debug("writing %d bytes to mem offset 0x%x\n", end-idx, idx); - memcpy(mem->buf + idx, d->d_buf, end-idx); - memset(mem->tags + idx, TAG_ALLOCATED, end-idx); + pmsg_debug("writing %d bytes to mem offset 0x%x\n", end - idx, idx); + memcpy(mem->buf + idx, d->d_buf, end - idx); + memset(mem->tags + idx, TAG_ALLOCATED, end - idx); } else { pmsg_error("section %s [0x%04x, 0x%04x] does not fit into %s [0, 0x%04x]\n", - sname, idx, (int) (idx + d->d_size-1), mem->desc, mem->size-1); + sname, idx, (int) (idx + d->d_size - 1), mem->desc, mem->size - 1); rv = -1; } } @@ -1244,32 +1241,31 @@ static int elf2b(const char *infile, FILE *inf, const AVRMEM *mem, } } done: - (void)elf_end(e); - return rv<0? rv: size; + (void) elf_end(e); + return rv < 0? rv: size; } -#endif /* HAVE_LIBELF */ - +#endif // HAVE_LIBELF // Read/write binary files and return highest memory addr set + 1 -static int fileio_rbin(struct fioparms *fio, const char *filename, FILE *f, - const AVRMEM *mem, const Segment *segp) { +static int fileio_rbin(struct fioparms *fio, const char *filename, FILE *f, const AVRMEM *mem, const Segment *segp) { int rc; - switch (fio->op) { - case FIO_READ: - rc = fread(mem->buf + segp->addr, 1, segp->len, f); - if (rc > 0) - memset(mem->tags + segp->addr, TAG_ALLOCATED, rc); - break; - case FIO_WRITE: - rc = fwrite(mem->buf + segp->addr, 1, segp->len, f); - break; - default: - pmsg_error("invalid fileio operation=%d\n", fio->op); - return -1; + + switch(fio->op) { + case FIO_READ: + rc = fread(mem->buf + segp->addr, 1, segp->len, f); + if(rc > 0) + memset(mem->tags + segp->addr, TAG_ALLOCATED, rc); + break; + case FIO_WRITE: + rc = fwrite(mem->buf + segp->addr, 1, segp->len, f); + break; + default: + pmsg_error("invalid fileio operation=%d\n", fio->op); + return -1; } - if (rc < 0 || (fio->op == FIO_WRITE && rc < segp->len)) { + if(rc < 0 || (fio->op == FIO_WRITE && rc < segp->len)) { pmsg_ext_error("%s error %s %s: %s; %s %d of the expected %d bytes\n", fio->iodesc, fio->dir, filename, strerror(errno), fio->rw, rc, segp->len); return -1; @@ -1278,9 +1274,8 @@ static int fileio_rbin(struct fioparms *fio, const char *filename, FILE *f, return segp->addr + rc; } - static int fileio_imm(struct fioparms *fio, const char *fname, FILE *f_unused, - const AVRMEM *mem, const Segment *segp) { + const AVRMEM *mem, const Segment *segp) { char *tok, *p, *line; const char *errstr; @@ -1288,138 +1283,134 @@ static int fileio_imm(struct fioparms *fio, const char *fname, FILE *f_unused, p = line = mmt_strdup(fname); - switch (fio->op) { - case FIO_READ: - while(*(tok = str_nexttok(p, ", \t\n\r\v\f", &p)) && n < end) { - int set = str_membuf(tok, STR_ANY, mem->buf+n, end-n, &errstr); - if(errstr || set < 0) { - pmsg_error("invalid data %s in immediate mode: %s\n", tok, errstr); - mmt_free(line); - return -1; - } - memset(mem->tags+n, TAG_ALLOCATED, set); - n += set; + switch(fio->op) { + case FIO_READ: + while(*(tok = str_nexttok(p, ", \t\n\r\v\f", &p)) && n < end) { + int set = str_membuf(tok, STR_ANY, mem->buf + n, end - n, &errstr); + + if(errstr || set < 0) { + pmsg_error("invalid data %s in immediate mode: %s\n", tok, errstr); + mmt_free(line); + return -1; } - break; + memset(mem->tags + n, TAG_ALLOCATED, set); + n += set; + } + break; - case FIO_WRITE: - pmsg_error("invalid file format 'immediate' for output\n"); - mmt_free(line); - return -1; + case FIO_WRITE: + pmsg_error("invalid file format 'immediate' for output\n"); + mmt_free(line); + return -1; - default: - pmsg_error("invalid operation=%d\n", fio->op); - mmt_free(line); - return -1; + default: + pmsg_error("invalid operation=%d\n", fio->op); + mmt_free(line); + return -1; } mmt_free(line); return n; } - static int fileio_ihex(struct fioparms *fio, const char *filename, FILE *f, const AVRPART *p, const AVRMEM *mem, const Segment *segp, FILEFMT ffmt, Segorder where) { int rc; - switch (fio->op) { - case FIO_WRITE: - rc = b2ihex(p, mem, segp, where, 32, fio->fileoffset, filename, f, ffmt); - break; + switch(fio->op) { + case FIO_WRITE: + rc = b2ihex(p, mem, segp, where, 32, fio->fileoffset, filename, f, ffmt); + break; - case FIO_READ: - rc = ihex2b(filename, f, p, mem, segp, fio->fileoffset, ffmt); - break; + case FIO_READ: + rc = ihex2b(filename, f, p, mem, segp, fio->fileoffset, ffmt); + break; - default: - rc = -1; - pmsg_error("invalid Intel Hex file I/O operation=%d\n", fio->op); + default: + rc = -1; + pmsg_error("invalid Intel Hex file I/O operation=%d\n", fio->op); } return rc < 0? -1: rc; } - static int fileio_srec(struct fioparms *fio, const char *filename, FILE *f, - const AVRPART* p, const AVRMEM *mem, const Segment *segp, Segorder where) { + const AVRPART *p, const AVRMEM *mem, const Segment *segp, Segorder where) { int rc; - switch (fio->op) { - case FIO_WRITE: - rc = b2srec(mem, segp, where, 32, fio->fileoffset, filename, f); - break; + switch(fio->op) { + case FIO_WRITE: + rc = b2srec(mem, segp, where, 32, fio->fileoffset, filename, f); + break; - case FIO_READ: - rc = srec2b(filename, f, p, mem, segp, fio->fileoffset); - break; + case FIO_READ: + rc = srec2b(filename, f, p, mem, segp, fio->fileoffset); + break; - default: - rc = -1; - pmsg_error("invalid Motorola S-Records file I/O operation=%d\n", fio->op); + default: + rc = -1; + pmsg_error("invalid Motorola S-Records file I/O operation=%d\n", fio->op); } return rc < 0? -1: rc; } - #ifdef HAVE_LIBELF static int fileio_elf(struct fioparms *fio, const char *filename, FILE *f, const AVRMEM *mem, const AVRPART *p, const Segment *segp) { int rc; - switch (fio->op) { - case FIO_WRITE: - pmsg_error("write operation not supported for ELF\n"); - return -1; - break; + switch(fio->op) { + case FIO_WRITE: + pmsg_error("write operation not supported for ELF\n"); + return -1; + break; - case FIO_READ: - rc = elf2b(filename, f, mem, p, segp, fio->fileoffset); - return rc; + case FIO_READ: + rc = elf2b(filename, f, mem, p, segp, fio->fileoffset); + return rc; - default: - pmsg_error("invalid ELF file I/O operation=%d\n", fio->op); - return -1; - break; + default: + pmsg_error("invalid ELF file I/O operation=%d\n", fio->op); + return -1; + break; } } - #endif - static int b2num(const char *filename, FILE *f, const AVRMEM *mem, const Segment *segp, FILEFMT fmt) { const char *prefix; int base; - switch (fmt) { - case FMT_HEX: - prefix = "0x"; - base = 16; - break; + switch(fmt) { + case FMT_HEX: + prefix = "0x"; + base = 16; + break; - default: - case FMT_DEC: - prefix = ""; - base = 10; - break; + default: + case FMT_DEC: + prefix = ""; + base = 10; + break; - case FMT_OCT: - prefix = "0"; - base = 8; - break; + case FMT_OCT: + prefix = "0"; + base = 8; + break; - case FMT_BIN: - prefix = "0b"; - base = 2; - break; + case FMT_BIN: + prefix = "0b"; + base = 2; + break; - case FMT_EEGG: - prefix = ""; - base = 'r'; - break; + case FMT_EEGG: + prefix = ""; + base = 'r'; + break; } for(int seen = 0, i = segp->addr; i < segp->addr + segp->len; i++) { @@ -1430,30 +1421,29 @@ static int b2num(const char *filename, FILE *f, const AVRMEM *mem, const Segment goto writeerr; unsigned num = mem->buf[i]; + /* - * For a base of 8 and a value < 8 to convert, don't write the - * prefix. The conversion will be indistinguishable from a - * decimal one then. + * For a base of 8 and a value < 8 to convert, don't write the prefix. The + * conversion will be indistinguishable from a decimal one then. */ - if (prefix[0] != '\0' && !(base == 8 && num < 8)) { - if (fputs(prefix, f) == EOF) + if(prefix[0] != '\0' && !(base == 8 && num < 8)) { + if(fputs(prefix, f) == EOF) goto writeerr; } str_utoa(num, cbuf, base); - if (fputs(cbuf, f) == EOF) + if(fputs(cbuf, f) == EOF) goto writeerr; } - if (putc('\n', f) == EOF) + if(putc('\n', f) == EOF) goto writeerr; return segp->addr + segp->len; - writeerr: +writeerr: pmsg_ext_error("unable to write to %s: %s\n", filename, strerror(errno)); return -1; } - static int num2b(const char *filename, FILE *f, const AVRMEM *mem, const Segment *segp) { const char *geterr = NULL; char *line; @@ -1461,20 +1451,23 @@ static int num2b(const char *filename, FILE *f, const AVRMEM *mem, const Segment while(n < end && (line = str_fgets(f, &geterr))) { char *p = line, *tok; - while(*p && isspace(*p & 0xff)) // Skip white space, comments and empty lines + + while(*p && isspace(*p & 0xff)) // Skip white space, comments and empty lines p++; if(*p && *p != '#') { while(*(tok = str_nexttok(p, ", \t\n\r\v\f", &p)) && n < end) { const char *errstr; - if(*tok == '#') // Ignore rest of line after # + + if(*tok == '#') // Ignore rest of line after # break; - int set = str_membuf(tok, STR_ANY, mem->buf+n, end-n, &errstr); + int set = str_membuf(tok, STR_ANY, mem->buf + n, end - n, &errstr); + if(errstr || set < 0) { pmsg_error("invalid data %s in immediate mode: %s\n", tok, errstr); mmt_free(line); return -1; } - memset(mem->tags+n, TAG_ALLOCATED, set); + memset(mem->tags + n, TAG_ALLOCATED, set); n += set; } } @@ -1488,59 +1481,57 @@ static int num2b(const char *filename, FILE *f, const AVRMEM *mem, const Segment return n; } - static int fileio_num(struct fioparms *fio, const char *filename, FILE *f, const AVRMEM *mem, const Segment *segp, FILEFMT fmt) { - switch (fio->op) { - case FIO_WRITE: - return b2num(filename, f, mem, segp, fmt); + switch(fio->op) { + case FIO_WRITE: + return b2num(filename, f, mem, segp, fmt); - case FIO_READ: - return num2b(filename, f, mem, segp); + case FIO_READ: + return num2b(filename, f, mem, segp); - default: - pmsg_error("invalid operation=%d\n", fio->op); - return -1; + default: + pmsg_error("invalid operation=%d\n", fio->op); + return -1; } } - static int fileio_setparms(int op, struct fioparms *fp, const AVRPART *p, const AVRMEM *m) { fp->op = op; - switch (op) { - case FIO_READ: - fp->mode = "r"; - fp->iodesc = "input"; - fp->dir = "from"; - fp->rw = "read"; - break; - - case FIO_WRITE: - fp->mode = "w"; - fp->iodesc = "output"; - fp->dir = "to"; - fp->rw = "wrote"; - break; + switch(op) { + case FIO_READ: + fp->mode = "r"; + fp->iodesc = "input"; + fp->dir = "from"; + fp->rw = "read"; + break; + + case FIO_WRITE: + fp->mode = "w"; + fp->iodesc = "output"; + fp->dir = "to"; + fp->rw = "wrote"; + break; - default: - pmsg_error("invalid I/O operation %d\n", op); - return -1; - break; + default: + pmsg_error("invalid I/O operation %d\n", op); + return -1; + break; } /* - * AVR32 devices maintain their load offset within the file itself, - * but AVRDUDE maintains all memory images 0-based. + * AVR32 devices maintain their load offset within the file itself, but + * AVRDUDE maintains all memory images 0-based. */ - fp->fileoffset = p->prog_modes & PM_aWire? m->offset: 0; + fp->fileoffset = is_awire(p)? m->offset: 0; return 0; } - FILE *fileio_fopenr(const char *fname) { + #if !defined(WIN32) return fopen(fname, "r"); #else @@ -1548,29 +1539,28 @@ FILE *fileio_fopenr(const char *fname) { #endif } - static FILEFMT couldbe(int first, unsigned char *line) { int found; unsigned long i, nxdigs, len; // Check for ELF file - if(first && line[0] == 0177 && str_starts((char *) line+1, "ELF")) + if(first && line[0] == 0177 && str_starts((char *) line + 1, "ELF")) return FMT_ELF; len = strlen((char *) line); - while(len > 0 && line[len-1] && isspace(line[len-1])) // cr/lf etc + while(len > 0 && line[len - 1] && isspace(line[len - 1])) // Cr/lf etc line[--len] = 0; // Check for binary data - for(i=0; i 127) return FMT_RBIN; // Check for lines that look like Intel HEX if(line[0] == ':' && len >= 11 && isxdigit(line[1]) && isxdigit(line[2])) { - nxdigs = sscanf((char *) line+1, "%2lx", &nxdigs) == 1? 2*nxdigs + 8: len; - for(found = 3+nxdigs <= len, i=0; found && i= 10 && isdigit(line[1]) && isxdigit(line[2]) && isxdigit(line[3])) { - nxdigs = sscanf((char *) line+2, "%2lx", &nxdigs) == 1? 2*nxdigs: len; - for(found = 4+nxdigs <= len, i=0; found && i 0) idx[str_casestarts(tok, "0x")? 0: str_casestarts(tok, "0b")? 1: - *tok=='0' && tok[1] && strchr("01234567", tok[1])? 2: 3]++; + *tok == '0' && tok[1] && strchr("01234567", tok[1])? 2: 3]++; } - if(!failed && idx[0]+idx[1]+idx[2]+idx[3]) { + if(!failed && idx[0] + idx[1] + idx[2] + idx[3]) { // Doesn't matter which one: they all parse numbers universally int i0 = idx[0] >= idx[1]? 0: 1; - int i2 = idx[2] > idx[3]? 2: 3; - const int fmts[4] = {FMT_HEX, FMT_BIN, FMT_OCT, FMT_DEC }; + int i2 = idx[2] > idx[3]? 2: 3; + const int fmts[4] = { FMT_HEX, FMT_BIN, FMT_OCT, FMT_DEC }; return fmts[idx[i0] >= idx[i2]? i0: i2]; } @@ -1623,6 +1615,7 @@ int fileio_fmt_autodetect_fp(FILE *f) { if(f) { unsigned char *buf; + for(int first = 1; ret == FMT_ERROR && (buf = (unsigned char *) str_fgets(f, &err)); first = 0) { ret = couldbe(first, buf); mmt_free(buf); @@ -1637,33 +1630,31 @@ int fileio_fmt_autodetect_fp(FILE *f) { int fileio_fmt_autodetect(const char *fname) { FILE *f = fileio_fopenr(fname); - if (f == NULL) { + if(f == NULL) { pmsg_ext_error("unable to open %s: %s\n", fname, strerror(errno)); return -1; } int format = fileio_fmt_autodetect_fp(f); + fclose(f); return format; } - -int fileio_mem(int op, const char *filename, FILEFMT format, - const AVRPART *p, const AVRMEM *mem, int size) { +int fileio_mem(int op, const char *filename, FILEFMT format, const AVRPART *p, const AVRMEM *mem, int size) { if(size < 0 || op == FIO_READ || op == FIO_READ_FOR_VERIFY) size = mem->size; - const Segment seg = {0, size}; + const Segment seg = { 0, size }; return fileio_segments(op, filename, format, p, mem, 1, &seg); } - -int fileio(int op, const char *filename, FILEFMT format, - const AVRPART *p, const char *memstr, int size) { +int fileio(int op, const char *filename, FILEFMT format, const AVRPART *p, const char *memstr, int size) { AVRMEM *mem = avr_locate_mem(p, memstr); + if(mem == NULL) { pmsg_error("memory %s not configured for device %s\n", memstr, p->desc); return -1; @@ -1672,7 +1663,6 @@ int fileio(int op, const char *filename, FILEFMT format, return fileio_mem(op, filename, format, p, mem, size); } - // Normalise segment address and length to be non-negative int segment_normalise(const AVRMEM *mem, Segment *segp) { int addr = segp->addr, len = segp->len, maxsize = mem->size; @@ -1683,7 +1673,7 @@ int segment_normalise(const AVRMEM *mem, Segment *segp) { if(addr < 0 || addr >= maxsize) { pmsg_error("%s address 0x%0*x is out of range [-0x%0*x, 0x%0*x]\n", - mem->desc, digits, segp->addr, digits, maxsize, digits, maxsize-1); + mem->desc, digits, segp->addr, digits, maxsize, digits, maxsize - 1); return -1; } @@ -1691,8 +1681,7 @@ int segment_normalise(const AVRMEM *mem, Segment *segp) { len = maxsize + len - addr + 1; if(len < 0 || len > maxsize) { - pmsg_error("invalid segment length %d for %s address 0x%0*x\n", - segp->len, mem->desc, digits, addr); + pmsg_error("invalid segment length %d for %s address 0x%0*x\n", segp->len, mem->desc, digits, addr); return -1; } @@ -1702,23 +1691,22 @@ int segment_normalise(const AVRMEM *mem, Segment *segp) { return 0; } - static int fileio_segments_normalise(int oprwv, const char *filename, FILEFMT format, const AVRPART *p, const AVRMEM *mem, int n, Segment *seglist) { int op, rc; - FILE * f; + FILE *f; const char *fname; struct fioparms fio; int using_stdio; op = oprwv == FIO_READ_FOR_VERIFY? FIO_READ: oprwv; rc = fileio_setparms(op, &fio, p, mem); - if (rc < 0) + if(rc < 0) return -1; - for(int i=0; ibuf+addr, 0xff, len); - memset(mem->tags+addr, 0, len); + if(fio.op == FIO_READ) // Fill unspecified memory in segment + memset(mem->buf + addr, 0xff, len); + memset(mem->tags + addr, 0, len); Segorder where = i == 0? FIRST_SEG: 0; - if(i+1 == n) + + if(i + 1 == n) where |= LAST_SEG; int thisrc = 0; + switch(format) { case FMT_IHEX: case FMT_IHXC: - thisrc = fileio_ihex(&fio, fname, f, p, mem, seglist+i, format, where); + thisrc = fileio_ihex(&fio, fname, f, p, mem, seglist + i, format, where); break; case FMT_SREC: - thisrc = fileio_srec(&fio, fname, f, p, mem, seglist+i, where); + thisrc = fileio_srec(&fio, fname, f, p, mem, seglist + i, where); break; case FMT_RBIN: - thisrc = fileio_rbin(&fio, fname, f, mem, seglist+i); + thisrc = fileio_rbin(&fio, fname, f, mem, seglist + i); break; case FMT_ELF: + #ifdef HAVE_LIBELF - thisrc = fileio_elf(&fio, fname, f, mem, p, seglist+i); + thisrc = fileio_elf(&fio, fname, f, mem, p, seglist + i); break; #else pmsg_error("cannot handle ELF file %s, ELF file support was not compiled in\n", fname); @@ -1816,7 +1803,7 @@ static int fileio_segments_normalise(int oprwv, const char *filename, FILEFMT fo #endif case FMT_IMM: - thisrc = fileio_imm(&fio, fname, f, mem, seglist+i); + thisrc = fileio_imm(&fio, fname, f, mem, seglist + i); break; case FMT_HEX: @@ -1824,7 +1811,7 @@ static int fileio_segments_normalise(int oprwv, const char *filename, FILEFMT fo case FMT_OCT: case FMT_BIN: case FMT_EEGG: - thisrc = fileio_num(&fio, fname, f, mem, seglist+i, format); + thisrc = fileio_num(&fio, fname, f, mem, seglist + i, format); break; default: @@ -1837,15 +1824,15 @@ static int fileio_segments_normalise(int oprwv, const char *filename, FILEFMT fo rc = thisrc; } - /* on reading flash other than for verify set the size to location of highest non-0xff byte */ - if (rc > 0 && oprwv == FIO_READ) { - int hiaddr = avr_mem_hiaddr(mem); // @@@ Should check segments only, not all file + // On reading flash other than for verify set the size to location of highest non-0xff byte + if(rc > 0 && oprwv == FIO_READ) { + int hiaddr = avr_mem_hiaddr(mem); // @@@ Should check segments only, not all file - if(hiaddr < rc) /* if trailing-0xff not disabled */ + if(hiaddr < rc) // If trailing-0xff not disabled rc = hiaddr; } - if (format != FMT_IMM && !using_stdio) { + if(format != FMT_IMM && !using_stdio) { fclose(f); } @@ -1855,9 +1842,11 @@ static int fileio_segments_normalise(int oprwv, const char *filename, FILEFMT fo int fileio_segments(int oprwv, const char *filename, FILEFMT format, const AVRPART *p, const AVRMEM *mem, int n, const Segment *list) { - Segment *seglist = mmt_malloc(n*sizeof*seglist); - memcpy(seglist, list, n*sizeof*seglist); + Segment *seglist = mmt_malloc(n*sizeof *seglist); + + memcpy(seglist, list, n*sizeof *seglist); int ret = fileio_segments_normalise(oprwv, filename, format, p, mem, n, seglist); + mmt_free(seglist); return ret; diff --git a/src/flip1.c b/src/flip1.c index 00d76a166..39ab9e562 100644 --- a/src/flip1.c +++ b/src/flip1.c @@ -34,9 +34,10 @@ #include "flip1.h" #include "dfu.h" -#include "usbdevs.h" /* for USB_VENDOR_ATMEL */ +#include "usbdevs.h" // For USB_VENDOR_ATMEL -/* There are three versions of the FLIP protocol: +/* + * There are three versions of the FLIP protocol: * * Version 0: C51 parts * Version 1: megaAVR parts ("USB DFU Bootloader Datasheet" [doc7618]) @@ -60,35 +61,26 @@ * Quite cumbersome to the user. */ -/* EXPORTED CONSTANT STRINGS */ - const char flip1_desc[] = "FLIP USB DFU protocol version 1 (doc7618)"; -/* PRIVATE DATA STRUCTURES */ - -struct flip1 -{ +struct flip1 { struct dfu_dev *dfu; unsigned char part_sig[3]; unsigned char part_rev; unsigned char boot_ver; - unsigned char security_mode_flag; /* indicates the user has already - * been hinted about security - * mode */ + unsigned char security_mode_flag; // Indicates security mode was mentioned earlier }; #define FLIP1(pgm) ((struct flip1 *)(pgm->cookie)) -/* FLIP1 data structures and constants. */ +// FLIP1 data structures and constants -struct flip1_cmd -{ +struct flip1_cmd { unsigned char cmd; unsigned char args[5]; }; -struct flip1_cmd_header /* for memory read/write */ -{ +struct flip1_cmd_header { // For memory read/write unsigned char cmd; unsigned char memchr; unsigned char start_addr[2]; @@ -96,15 +88,14 @@ struct flip1_cmd_header /* for memory read/write */ unsigned char padding[26]; }; -struct flip1_prog_footer -{ - unsigned char crc[4]; /* not really used */ - unsigned char ftr_length; /* 0x10 */ - unsigned char signature[3]; /* "DFU" */ - unsigned char bcdversion[2]; /* 0x01, 0x10 */ - unsigned char vendor[2]; /* or 0xff, 0xff */ - unsigned char product[2]; /* or 0xff, 0xff */ - unsigned char device[2]; /* or 0xff, 0xff */ +struct flip1_prog_footer { + unsigned char crc[4]; // Not really used + unsigned char ftr_length; // 0x10 + unsigned char signature[3]; // DFU + unsigned char bcdversion[2]; // 0x01, 0x10 + unsigned char vendor[2]; // Or 0xff, 0xff + unsigned char product[2]; // Or 0xff, 0xff + unsigned char device[2]; // Or 0xff, 0xff }; #define FLIP1_CMD_PROG_START 0x01 @@ -113,7 +104,7 @@ struct flip1_prog_footer #define FLIP1_CMD_READ_COMMAND 0x05 #define FLIP1_CMD_CHANGE_BASE_ADDRESS 0x06 -/* args[1:0] for FLIP1_CMD_READ_COMMAND */ +// Args[1:0] for FLIP1_CMD_READ_COMMAND #define FLIP1_READ_BOOTLOADER_VERSION { 0x00, 0x00 } #define FLIP1_READ_DEVICE_BOOT_ID1 { 0x00, 0x01 } #define FLIP1_READ_DEVICE_BOOT_ID2 { 0x00, 0x02 } @@ -128,15 +119,13 @@ enum flip1_mem_unit { FLIP1_MEM_UNIT_UNKNOWN = -1 }; -#define STATE_dfuERROR 10 /* bState; requires a DFU_CLRSTATUS */ - -#define LONG_DFU_TIMEOUT 10000 /* 10 s for program and erase */ +#define STATE_dfuERROR 10 // bState; requires a DFU_CLRSTATUS -/* EXPORTED PROGRAMMER FUNCTION PROTOTYPES */ +#define LONG_DFU_TIMEOUT 10000 // 10 s for program and erase static int flip1_open(PROGRAMMER *pgm, const char *port_spec); static int flip1_initialize(const PROGRAMMER *pgm, const AVRPART *part); -static void flip1_close(PROGRAMMER* pgm); +static void flip1_close(PROGRAMMER *pgm); static void flip1_enable(PROGRAMMER *pgm, const AVRPART *p); static void flip1_disable(const PROGRAMMER *pgm); static void flip1_display(const PROGRAMMER *pgm, const char *prefix); @@ -154,53 +143,45 @@ static int flip1_read_sig_bytes(const PROGRAMMER *pgm, const AVRPART *part, cons static void flip1_setup(PROGRAMMER *pgm); static void flip1_teardown(PROGRAMMER *pgm); -/* INTERNAL PROGRAMMER FUNCTION PROTOTYPES */ #ifdef HAVE_LIBUSB // The internal ones are made conditional, as they're not defined further down #ifndef HAVE_LIBUSB - static void flip1_show_info(struct flip1 *flip1); - -static int flip1_read_memory(const PROGRAMMER *pgm, - enum flip1_mem_unit mem_unit, uint32_t addr, void *ptr, int size); -static int flip1_write_memory(struct dfu_dev *dfu, - enum flip1_mem_unit mem_unit, uint32_t addr, const void *ptr, int size); - -static const char * flip1_status_str(const struct dfu_status *status); -static const char * flip1_mem_unit_str(enum flip1_mem_unit mem_unit); +static int flip1_read_memory(const PROGRAMMER *pgm, enum flip1_mem_unit mem_unit, + uint32_t addr, void *ptr, int size); +static int flip1_write_memory(struct dfu_dev *dfu, enum flip1_mem_unit mem_unit, + uint32_t addr, const void *ptr, int size); +static const char *flip1_status_str(const struct dfu_status *status); +static const char *flip1_mem_unit_str(enum flip1_mem_unit mem_unit); static int flip1_set_mem_page(struct dfu_dev *dfu, unsigned short page_addr); static enum flip1_mem_unit flip1_mem_unit(const char *name); - -#endif /* HAVE_LIBUSB */ - -/* THE INITPGM FUNCTION DEFINITIONS */ +#endif // HAVE_LIBUSB void flip1_initpgm(PROGRAMMER *pgm) { strcpy(pgm->type, "flip1"); - /* Mandatory Functions */ - pgm->initialize = flip1_initialize; - pgm->enable = flip1_enable; - pgm->disable = flip1_disable; - pgm->display = flip1_display; - pgm->program_enable = flip1_program_enable; - pgm->chip_erase = flip1_chip_erase; - pgm->open = flip1_open; - pgm->close = flip1_close; - pgm->paged_load = flip1_paged_load; - pgm->paged_write = flip1_paged_write; - pgm->read_byte = flip1_read_byte; - pgm->write_byte = flip1_write_byte; - pgm->read_sig_bytes = flip1_read_sig_bytes; - pgm->setup = flip1_setup; - pgm->teardown = flip1_teardown; + // Mandatory functions + pgm->initialize = flip1_initialize; + pgm->enable = flip1_enable; + pgm->disable = flip1_disable; + pgm->display = flip1_display; + pgm->program_enable = flip1_program_enable; + pgm->chip_erase = flip1_chip_erase; + pgm->open = flip1_open; + pgm->close = flip1_close; + pgm->paged_load = flip1_paged_load; + pgm->paged_write = flip1_paged_write; + pgm->read_byte = flip1_read_byte; + pgm->write_byte = flip1_write_byte; + pgm->read_sig_bytes = flip1_read_sig_bytes; + pgm->setup = flip1_setup; + pgm->teardown = flip1_teardown; } #ifdef HAVE_LIBUSB -/* EXPORTED PROGRAMMER FUNCTION DEFINITIONS */ static int flip1_open(PROGRAMMER *pgm, const char *port_spec) { FLIP1(pgm)->dfu = dfu_open(port_spec); - return (FLIP1(pgm)->dfu != NULL) ? 0 : -1; + return (FLIP1(pgm)->dfu != NULL)? 0: -1; } static int flip1_initialize(const PROGRAMMER *pgm, const AVRPART *part) { @@ -227,16 +208,17 @@ static int flip1_initialize(const PROGRAMMER *pgm, const AVRPART *part) { * the PID when matching a target device. */ - vid = (pgm->usbvid != 0) ? pgm->usbvid : USB_VENDOR_ATMEL; + vid = (pgm->usbvid != 0)? pgm->usbvid: USB_VENDOR_ATMEL; LNODEID usbpid = lfirst(pgm->usbpid); - if (usbpid) { - pid = *(int *)(ldata(usbpid)); - if (lnext(usbpid)) + + if(usbpid) { + pid = *(int *) (ldata(usbpid)); + if(lnext(usbpid)) pmsg_warning("using PID 0x%04x, ignoring remaining PIDs in list\n", pid); } else { pid = part->usbpid; } - if (!ovsigck && (part->prog_modes & PM_PDI)) { + if(!ovsigck && is_pdi(part)) { pmsg_error("flip1 (FLIP protocol version 1) is for AT90USB* and ATmega*U* devices\n"); imsg_error("for Xmega devices, use flip2 or use -F to bypass this check\n"); return -1; @@ -244,53 +226,52 @@ static int flip1_initialize(const PROGRAMMER *pgm, const AVRPART *part) { result = dfu_init(FLIP1(pgm)->dfu, vid, pid); - if (result != 0) + if(result != 0) goto flip1_initialize_fail; - /* Check if descriptor values are what we expect. */ + // Check if descriptor values are what we expect - if (dfu->dev_desc.idVendor != vid) + if(dfu->dev_desc.idVendor != vid) pmsg_warning("USB idVendor = 0x%04X (expected 0x%04X)\n", dfu->dev_desc.idVendor, vid); - if (pid != 0 && dfu->dev_desc.idProduct != pid) + if(pid != 0 && dfu->dev_desc.idProduct != pid) pmsg_warning("USB idProduct = 0x%04X (expected 0x%04X)\n", dfu->dev_desc.idProduct, pid); - if (dfu->dev_desc.bNumConfigurations != 1) + if(dfu->dev_desc.bNumConfigurations != 1) pmsg_warning("USB bNumConfigurations = %d (expected 1)\n", (int) dfu->dev_desc.bNumConfigurations); - if (dfu->conf_desc.bNumInterfaces != 1) + if(dfu->conf_desc.bNumInterfaces != 1) pmsg_warning("USB bNumInterfaces = %d (expected 1)\n", (int) dfu->conf_desc.bNumInterfaces); - if (dfu->dev_desc.bDeviceClass != 254) + if(dfu->dev_desc.bDeviceClass != 254) pmsg_warning("USB bDeviceClass = %d (expected 254)\n", (int) dfu->dev_desc.bDeviceClass); - if (dfu->dev_desc.bDeviceSubClass != 1) + if(dfu->dev_desc.bDeviceSubClass != 1) pmsg_warning("USB bDeviceSubClass = %d (expected 1)\n", (int) dfu->dev_desc.bDeviceSubClass); - if (dfu->dev_desc.bDeviceProtocol != 0) + if(dfu->dev_desc.bDeviceProtocol != 0) pmsg_warning("USB bDeviceProtocol = %d (expected 0)\n", (int) dfu->dev_desc.bDeviceProtocol); /* - * doc7618 claims an interface class of FEh and a subclas 01h. - * However, as of today (2014-01-16), all values in the interface - * descriptor (except of bLength and bDescriptorType) are actually - * 0. So rather don't check these. + * Doc7618 claims an interface class of FEh and a subclas 01h. However, as of + * today (2014-01-16), all values in the interface descriptor (except of + * bLength and bDescriptorType) are actually 0. So rather don't check these. */ - if (0) { - if (dfu->intf_desc.bInterfaceClass != 254) - pmsg_warning("USB bInterfaceClass = %d (expected 254)\n", (int) dfu->intf_desc.bInterfaceClass); + if(0) { + if(dfu->intf_desc.bInterfaceClass != 254) + pmsg_warning("USB bInterfaceClass = %d (expected 254)\n", (int) dfu->intf_desc.bInterfaceClass); - if (dfu->intf_desc.bInterfaceSubClass != 1) - pmsg_warning("USB bInterfaceSubClass = %d (expected 1)\n", (int) dfu->intf_desc.bInterfaceSubClass); + if(dfu->intf_desc.bInterfaceSubClass != 1) + pmsg_warning("USB bInterfaceSubClass = %d (expected 1)\n", (int) dfu->intf_desc.bInterfaceSubClass); - if (dfu->intf_desc.bInterfaceProtocol != 0) - pmsg_warning("USB bInterfaceSubClass = %d (expected 0)\n", (int) dfu->intf_desc.bInterfaceProtocol); + if(dfu->intf_desc.bInterfaceProtocol != 0) + pmsg_warning("USB bInterfaceSubClass = %d (expected 0)\n", (int) dfu->intf_desc.bInterfaceProtocol); } - if (dfu->dev_desc.bMaxPacketSize0 != 32) + if(dfu->dev_desc.bMaxPacketSize0 != 32) pmsg_warning("bMaxPacketSize0 (%d) != 32, things might go wrong\n", dfu->dev_desc.bMaxPacketSize0); - if (verbose > 0) + if(verbose > 0) flip1_show_info(FLIP1(pgm)); dfu_abort(dfu); @@ -304,7 +285,7 @@ static int flip1_initialize(const PROGRAMMER *pgm, const AVRPART *part) { } static void flip1_close(PROGRAMMER *pgm) { - if (FLIP1(pgm)->dfu != NULL) { + if(FLIP1(pgm)->dfu != NULL) { dfu_close(FLIP1(pgm)->dfu); FLIP1(pgm)->dfu = NULL; } @@ -324,8 +305,7 @@ static int flip1_program_enable(const PROGRAMMER *pgm, const AVRPART *part) { * as "mandatory" in pgm.c. In case anyone does use it, we'll report an * error if we failed to initialize. */ - - return (FLIP1(pgm)->dfu != NULL) ? 0 : -1; + return (FLIP1(pgm)->dfu != NULL)? 0: -1; } static int flip1_chip_erase(const PROGRAMMER *pgm, const AVRPART *part) { @@ -337,7 +317,7 @@ static int flip1_chip_erase(const PROGRAMMER *pgm, const AVRPART *part) { pmsg_debug("flip_chip_erase()\n"); struct flip1_cmd cmd = { - FLIP1_CMD_WRITE_COMMAND, { 0, 0xff } + FLIP1_CMD_WRITE_COMMAND, {0, 0xff} }; FLIP1(pgm)->dfu->timeout = LONG_DFU_TIMEOUT; @@ -345,12 +325,12 @@ static int flip1_chip_erase(const PROGRAMMER *pgm, const AVRPART *part) { aux_result = dfu_getstatus(FLIP1(pgm)->dfu, &status); FLIP1(pgm)->dfu->timeout = default_timeout; - if (cmd_result < 0 || aux_result < 0) + if(cmd_result < 0 || aux_result < 0) return -1; - if (status.bStatus != DFU_STATUS_OK) { + if(status.bStatus != DFU_STATUS_OK) { pmsg_error("unable to send chip erase command: %s\n", flip1_status_str(&status)); - if (status.bState == STATE_dfuERROR) + if(status.bState == STATE_dfuERROR) dfu_clrstatus(FLIP1(pgm)->dfu); return -1; } @@ -359,18 +339,17 @@ static int flip1_chip_erase(const PROGRAMMER *pgm, const AVRPART *part) { } static int flip1_read_byte(const PROGRAMMER *pgm, const AVRPART *part, const AVRMEM *mem, - unsigned long addr, unsigned char *value) -{ + unsigned long addr, unsigned char *value) { enum flip1_mem_unit mem_unit; - if (FLIP1(pgm)->dfu == NULL) + if(FLIP1(pgm)->dfu == NULL) return -1; - if (mem_is_signature(mem)) { - if (flip1_read_sig_bytes(pgm, part, mem) < 0) + if(mem_is_signature(mem)) { + if(flip1_read_sig_bytes(pgm, part, mem) < 0) return -1; - if (addr >= (unsigned long) mem->size) { - pmsg_error("signature address %lu out of range [0, %d]\n", addr, mem->size-1); + if(addr >= (unsigned long) mem->size) { + pmsg_error("signature address %lu out of range [0, %d]\n", addr, mem->size - 1); return -1; } *value = mem->buf[addr]; @@ -379,25 +358,25 @@ static int flip1_read_byte(const PROGRAMMER *pgm, const AVRPART *part, const AVR mem_unit = flip1_mem_unit(mem->desc); - if (mem_unit == FLIP1_MEM_UNIT_UNKNOWN) { + if(mem_unit == FLIP1_MEM_UNIT_UNKNOWN) { pmsg_error("%s memory not accessible using FLIP\n", mem->desc); return -1; } - if (mem_unit == FLIP1_MEM_UNIT_EEPROM) - /* 0x01 is used for blank check when reading, 0x02 is EEPROM */ + if(mem_unit == FLIP1_MEM_UNIT_EEPROM) + // 0x01 is used for blank check when reading, 0x02 is EEPROM mem_unit = 2; return flip1_read_memory(pgm, mem_unit, addr, value, 1); } static int flip1_write_byte(const PROGRAMMER *pgm, const AVRPART *part, const AVRMEM *mem, - unsigned long addr, unsigned char value) -{ + unsigned long addr, unsigned char value) { enum flip1_mem_unit mem_unit; if(mem_is_readonly(mem)) { unsigned char is; + if(pgm->read_byte(pgm, part, mem, addr, &is) >= 0 && is == value) return 0; @@ -405,12 +384,12 @@ static int flip1_write_byte(const PROGRAMMER *pgm, const AVRPART *part, const AV return -1; } - if (FLIP1(pgm)->dfu == NULL) + if(FLIP1(pgm)->dfu == NULL) return -1; mem_unit = flip1_mem_unit(mem->desc); - if (mem_unit == FLIP1_MEM_UNIT_UNKNOWN) { + if(mem_unit == FLIP1_MEM_UNIT_UNKNOWN) { pmsg_error("%s memory not accessible using FLIP\n", mem->desc); return -1; } @@ -419,51 +398,48 @@ static int flip1_write_byte(const PROGRAMMER *pgm, const AVRPART *part, const AV } static int flip1_paged_load(const PROGRAMMER *pgm, const AVRPART *part, const AVRMEM *mem, - unsigned int page_size, unsigned int addr, unsigned int n_bytes) -{ + unsigned int page_size, unsigned int addr, unsigned int n_bytes) { enum flip1_mem_unit mem_unit; - if (FLIP1(pgm)->dfu == NULL) + if(FLIP1(pgm)->dfu == NULL) return -1; mem_unit = flip1_mem_unit(mem->desc); - if (mem_unit == FLIP1_MEM_UNIT_UNKNOWN) { + if(mem_unit == FLIP1_MEM_UNIT_UNKNOWN) { pmsg_error("%s memory not accessible using FLIP\n", mem->desc); return -1; } - if (mem_unit == FLIP1_MEM_UNIT_EEPROM) - /* 0x01 is used for blank check when reading, 0x02 is EEPROM */ + if(mem_unit == FLIP1_MEM_UNIT_EEPROM) + // 0x01 is used for blank check when reading, 0x02 is EEPROM mem_unit = 2; return flip1_read_memory(pgm, mem_unit, addr, mem->buf + addr, n_bytes); } static int flip1_paged_write(const PROGRAMMER *pgm, const AVRPART *part, const AVRMEM *mem, - unsigned int page_size, unsigned int addr, unsigned int n_bytes) -{ + unsigned int page_size, unsigned int addr, unsigned int n_bytes) { enum flip1_mem_unit mem_unit; int result; - if (FLIP1(pgm)->dfu == NULL) + if(FLIP1(pgm)->dfu == NULL) return -1; mem_unit = flip1_mem_unit(mem->desc); - if (mem_unit == FLIP1_MEM_UNIT_UNKNOWN) { + if(mem_unit == FLIP1_MEM_UNIT_UNKNOWN) { pmsg_error("%s memory not accessible using FLIP\n", mem->desc); return -1; } - if (n_bytes > INT_MAX) { - /* This should never happen, unless the int type is only 16 bits. */ + if(n_bytes > INT_MAX) { + // This should never happen, unless the int type is only 16 bits pmsg_error("attempting to read more than %d bytes\n", INT_MAX); return -1; } - result = flip1_write_memory(FLIP1(pgm)->dfu, mem_unit, addr, - mem->buf + addr, n_bytes); + result = flip1_write_memory(FLIP1(pgm)->dfu, mem_unit, addr, mem->buf + addr, n_bytes); return result == 0? (int) n_bytes: -1; } @@ -471,46 +447,42 @@ static int flip1_paged_write(const PROGRAMMER *pgm, const AVRPART *part, const A static int flip1_read_sig_bytes(const PROGRAMMER *pgm, const AVRPART *part, const AVRMEM *mem) { pmsg_debug("%s(): ", __func__); - if (FLIP1(pgm)->dfu == NULL) + if(FLIP1(pgm)->dfu == NULL) return -1; - if (mem->size < (int) sizeof(FLIP1(pgm)->part_sig)) { + if(mem->size < (int) sizeof(FLIP1(pgm)->part_sig)) { pmsg_error("signature read must be at least %u bytes\n", (unsigned int) sizeof(FLIP1(pgm)->part_sig)); return -1; } - if (FLIP1(pgm)->part_sig[0] == 0 && - FLIP1(pgm)->part_sig[1] == 0 && - FLIP1(pgm)->part_sig[2] == 0) - { - /* signature not yet cached */ + if(FLIP1(pgm)->part_sig[0] == 0 && FLIP1(pgm)->part_sig[1] == 0 && FLIP1(pgm)->part_sig[2] == 0) { + // Signature not yet cached struct dfu_status status; int cmd_result = 0; int aux_result; int i; + struct flip1_cmd cmd = { FLIP1_CMD_READ_COMMAND, FLIP1_READ_FAMILY_CODE }; msg_debug("from device\n"); - for (i = 0; i < 3; i++) - { - if (i == 1) - cmd.args[1] = 0x60; /* product name */ - else if (i == 2) - cmd.args[1] = 0x61; /* product revision */ + for(i = 0; i < 3; i++) { + if(i == 1) + cmd.args[1] = 0x60; // Product name + else if(i == 2) + cmd.args[1] = 0x61; // Product revision cmd_result = dfu_dnload(FLIP1(pgm)->dfu, &cmd, 3); aux_result = dfu_getstatus(FLIP1(pgm)->dfu, &status); - if (cmd_result < 0 || aux_result < 0) + if(cmd_result < 0 || aux_result < 0) return -1; - if (status.bStatus != DFU_STATUS_OK) - { + if(status.bStatus != DFU_STATUS_OK) { pmsg_error("unable to send cmd for signature byte %d: %s\n", i, flip1_status_str(&status)); - if (status.bState == STATE_dfuERROR) + if(status.bState == STATE_dfuERROR) dfu_clrstatus(FLIP1(pgm)->dfu); return -1; } @@ -518,20 +490,17 @@ static int flip1_read_sig_bytes(const PROGRAMMER *pgm, const AVRPART *part, cons cmd_result = dfu_upload(FLIP1(pgm)->dfu, &(FLIP1(pgm)->part_sig[i]), 1); aux_result = dfu_getstatus(FLIP1(pgm)->dfu, &status); - if (cmd_result < 0 || aux_result < 0) + if(cmd_result < 0 || aux_result < 0) return -1; - if (status.bStatus != DFU_STATUS_OK) - { + if(status.bStatus != DFU_STATUS_OK) { pmsg_error("unable to read signature byte %d: %s\n", i, flip1_status_str(&status)); - if (status.bState == STATE_dfuERROR) + if(status.bState == STATE_dfuERROR) dfu_clrstatus(FLIP1(pgm)->dfu); return -1; } } - } - else - { + } else { msg_debug("cached\n"); } @@ -557,32 +526,30 @@ static void flip1_show_info(struct flip1 *flip1) { msg_info(" USB max packet size : %hu\n", (unsigned short) flip1->dfu->dev_desc.bMaxPacketSize0); } -static int flip1_read_memory(const PROGRAMMER *pgm, - enum flip1_mem_unit mem_unit, uint32_t addr, void *ptr, int size) -{ +static int flip1_read_memory(const PROGRAMMER *pgm, enum flip1_mem_unit mem_unit, uint32_t addr, void *ptr, int size) { struct dfu_dev *dfu = FLIP1(pgm)->dfu; unsigned short page_addr; struct dfu_status status; int cmd_result = 0; int aux_result; + struct flip1_cmd cmd = { - FLIP1_CMD_DISPLAY_DATA, { mem_unit } + FLIP1_CMD_DISPLAY_DATA, {mem_unit} }; unsigned int default_timeout = dfu->timeout; - pmsg_debug("flip_read_memory(%s, 0x%04x, %d)\n", flip1_mem_unit_str(mem_unit), addr, size); /* - * As this function is called once per page, no need to handle 64 - * KiB border crossing below. + * As this function is called once per page, no need to handle 64 KiB border + * crossing below. * - * Also, on AVRs, no page size is larger than 1 KiB, so no need to - * split the request into multiple 1 KiB chunks. + * Also, on AVRs, no page size is larger than 1 KiB, so no need to split the + * request into multiple 1 KiB chunks. */ - if (mem_unit == FLIP1_MEM_UNIT_FLASH) { + if(mem_unit == FLIP1_MEM_UNIT_FLASH) { page_addr = addr >> 16; - if (flip1_set_mem_page(dfu, page_addr) < 0) + if(flip1_set_mem_page(dfu, page_addr) < 0) return -1; } @@ -596,36 +563,33 @@ static int flip1_read_memory(const PROGRAMMER *pgm, dfu->timeout = default_timeout; aux_result = dfu_getstatus(dfu, &status); - if (cmd_result < 0 || aux_result < 0) + if(cmd_result < 0 || aux_result < 0) return -1; - if (status.bStatus != DFU_STATUS_OK) - { + if(status.bStatus != DFU_STATUS_OK) { pmsg_error("unable to read %u bytes of %s memory @%u: %s\n", size, flip1_mem_unit_str(mem_unit), addr, flip1_status_str(&status)); - if (status.bState == STATE_dfuERROR) + if(status.bState == STATE_dfuERROR) dfu_clrstatus(dfu); return -1; } - cmd_result = dfu_upload(dfu, (char*) ptr, size); + cmd_result = dfu_upload(dfu, (char *) ptr, size); aux_result = dfu_getstatus(dfu, &status); - if (cmd_result < 0 && aux_result == 0 && - status.bStatus == DFU_STATUS_ERR_WRITE) { - if (FLIP1(pgm)->security_mode_flag == 0) + if(cmd_result < 0 && aux_result == 0 && status.bStatus == DFU_STATUS_ERR_WRITE) { + if(FLIP1(pgm)->security_mode_flag == 0) pmsg_error("maybe the device is in security mode and needs a chip erase first?\n"); FLIP1(pgm)->security_mode_flag = 1; } - if (cmd_result < 0 || aux_result < 0) + if(cmd_result < 0 || aux_result < 0) return -1; - if (status.bStatus != DFU_STATUS_OK) - { + if(status.bStatus != DFU_STATUS_OK) { pmsg_error("unable to read %u bytes of %s memory @%u: %s\n", size, flip1_mem_unit_str(mem_unit), addr, flip1_status_str(&status)); - if (status.bState == STATE_dfuERROR) + if(status.bState == STATE_dfuERROR) dfu_clrstatus(dfu); return -1; } @@ -633,37 +597,36 @@ static int flip1_read_memory(const PROGRAMMER *pgm, return 0; } -static int flip1_write_memory(struct dfu_dev *dfu, - enum flip1_mem_unit mem_unit, uint32_t addr, const void *ptr, int size) -{ +static int flip1_write_memory(struct dfu_dev *dfu, enum flip1_mem_unit mem_unit, + uint32_t addr, const void *ptr, int size) { + unsigned short page_addr; int write_size; struct dfu_status status; int cmd_result = 0; int aux_result; + struct flip1_cmd_header cmd_header = { FLIP1_CMD_PROG_START, mem_unit, {0}, {0}, {0}, }; struct flip1_prog_footer cmd_footer = { - { 0, 0, 0, 0 }, /* CRC */ - 0x10, /* footer length */ - { 'D', 'F', 'U' }, /* signature */ - { 0x01, 0x10 }, /* BCD version */ - { 0xff, 0xff }, /* vendor */ - { 0xff, 0xff }, /* product */ - { 0xff, 0xff } /* device */ + {0, 0, 0, 0}, // CRC + 0x10, // Footer length + {'D', 'F', 'U'}, // Signature + {0x01, 0x10}, // BCD version + {0xff, 0xff}, // Vendor + {0xff, 0xff}, // Product + {0xff, 0xff} // Device }; unsigned int default_timeout = dfu->timeout; unsigned char *buf; - pmsg_debug("flip_write_memory(%s, 0x%04x, %d)\n", - flip1_mem_unit_str(mem_unit), addr, size); + pmsg_debug("flip_write_memory(%s, 0x%04x, %d)\n", flip1_mem_unit_str(mem_unit), addr, size); - if (size < 32) { - /* presumably single-byte updates; must be padded to USB endpoint size */ - if ((addr + size - 1) / 32 != addr / 32) { - pmsg_error("begin 0x%x and end 0x%x not within same 32-byte block\n", - addr, addr + size - 1); + if(size < 32) { + // Presumably single-byte updates; must be padded to USB endpoint size + if((addr + size - 1)/32 != addr/32) { + pmsg_error("begin 0x%x and end 0x%x not within same 32-byte block\n", addr, addr + size - 1); return -1; } write_size = 32; @@ -674,15 +637,15 @@ static int flip1_write_memory(struct dfu_dev *dfu, buf = mmt_malloc(sizeof(struct flip1_cmd_header) + write_size + sizeof(struct flip1_prog_footer)); /* - * As this function is called once per page, no need to handle 64 - * KiB border crossing below. + * As this function is called once per page, no need to handle 64 KiB border + * crossing below. * - * Also, on AVRs, no page size is larger than 1 KiB, so no need to - * split the request into multiple 1 KiB chunks. + * Also, on AVRs, no page size is larger than 1 KiB, so no need to split the + * request into multiple 1 KiB chunks. */ - if (mem_unit == FLIP1_MEM_UNIT_FLASH) { + if(mem_unit == FLIP1_MEM_UNIT_FLASH) { page_addr = addr >> 16; - if (flip1_set_mem_page(dfu, page_addr) < 0) { + if(flip1_set_mem_page(dfu, page_addr) < 0) { mmt_free(buf); return -1; } @@ -694,33 +657,28 @@ static int flip1_write_memory(struct dfu_dev *dfu, cmd_header.end_addr[1] = (addr + size - 1) & 0xFF; memcpy(buf, &cmd_header, sizeof(struct flip1_cmd_header)); - if (size < 32) { + if(size < 32) { memset(buf + sizeof(struct flip1_cmd_header), 0xff, 32); - memcpy(buf + sizeof(struct flip1_cmd_header) + (addr % 32), ptr, size); + memcpy(buf + sizeof(struct flip1_cmd_header) + (addr%32), ptr, size); } else { memcpy(buf + sizeof(struct flip1_cmd_header), ptr, size); } - memcpy(buf + sizeof(struct flip1_cmd_header) + write_size, - &cmd_footer, sizeof(struct flip1_prog_footer)); + memcpy(buf + sizeof(struct flip1_cmd_header) + write_size, &cmd_footer, sizeof(struct flip1_prog_footer)); dfu->timeout = LONG_DFU_TIMEOUT; - cmd_result = dfu_dnload(dfu, buf, - sizeof(struct flip1_cmd_header) + - write_size + - sizeof(struct flip1_prog_footer)); + cmd_result = dfu_dnload(dfu, buf, sizeof(struct flip1_cmd_header) + write_size + sizeof(struct flip1_prog_footer)); aux_result = dfu_getstatus(dfu, &status); dfu->timeout = default_timeout; mmt_free(buf); - if (aux_result < 0 || cmd_result < 0) + if(aux_result < 0 || cmd_result < 0) return -1; - if (status.bStatus != DFU_STATUS_OK) - { + if(status.bStatus != DFU_STATUS_OK) { pmsg_error("unable to write %u bytes of %s memory @%u: %s\n", size, flip1_mem_unit_str(mem_unit), addr, flip1_status_str(&status)); - if (status.bState == STATE_dfuERROR) + if(status.bState == STATE_dfuERROR) dfu_clrstatus(dfu); return -1; } @@ -734,20 +692,19 @@ static int flip1_set_mem_page(struct dfu_dev *dfu, unsigned short page_addr) { int aux_result; struct flip1_cmd cmd = { - FLIP1_CMD_CHANGE_BASE_ADDRESS, { 0, page_addr } + FLIP1_CMD_CHANGE_BASE_ADDRESS, {0, page_addr} }; cmd_result = dfu_dnload(dfu, &cmd, 3); aux_result = dfu_getstatus(dfu, &status); - if (cmd_result < 0 || aux_result < 0) + if(cmd_result < 0 || aux_result < 0) return -1; - if (status.bStatus != DFU_STATUS_OK) - { + if(status.bStatus != DFU_STATUS_OK) { pmsg_error("unable to set memory page: %s\n", flip1_status_str(&status)); - if (status.bState == STATE_dfuERROR) + if(status.bState == STATE_dfuERROR) dfu_clrstatus(dfu); return -1; } @@ -756,7 +713,7 @@ static int flip1_set_mem_page(struct dfu_dev *dfu, unsigned short page_addr) { } static const char *flip1_status_str(const struct dfu_status *status) { - static const char * const msg[] = { + static const char *const msg[] = { "No error condition is present", "File is not targeted for use by this device", "File is for this device but fails some vendor-specific verification test", @@ -774,28 +731,31 @@ static const char *flip1_status_str(const struct dfu_status *status) { "Something went wrong, but the device does not know what it was", "Device stalled an unexpected request", }; - if (status->bStatus < sizeof msg / sizeof msg[0]) + if(status->bStatus < sizeof msg/sizeof msg[0]) return msg[status->bStatus]; return "Unknown status code"; } static const char *flip1_mem_unit_str(enum flip1_mem_unit mem_unit) { - switch (mem_unit) { - case FLIP1_MEM_UNIT_FLASH: return "Flash"; - case FLIP1_MEM_UNIT_EEPROM: return "EEPROM"; - default: return "unknown"; + switch(mem_unit) { + case FLIP1_MEM_UNIT_FLASH: + return "Flash"; + case FLIP1_MEM_UNIT_EEPROM: + return "EEPROM"; + default: + return "unknown"; } } static enum flip1_mem_unit flip1_mem_unit(const char *name) { - if (str_eq(name, "flash")) + if(str_eq(name, "flash")) return FLIP1_MEM_UNIT_FLASH; - if (str_eq(name, "eeprom")) + if(str_eq(name, "eeprom")) return FLIP1_MEM_UNIT_EEPROM; return FLIP1_MEM_UNIT_UNKNOWN; } -#else /* HAVE_LIBUSB */ +#else // HAVE_LIBUSB // Dummy functions static int flip1_open(PROGRAMMER *pgm, const char *port_spec) { @@ -833,14 +793,12 @@ static int flip1_read_byte(const PROGRAMMER *pgm, const AVRPART *part, const AVR } static int flip1_write_byte(const PROGRAMMER *pgm, const AVRPART *part, const AVRMEM *mem, - unsigned long addr, unsigned char value) -{ + unsigned long addr, unsigned char value) { return -1; } static int flip1_paged_load(const PROGRAMMER *pgm, const AVRPART *part, const AVRMEM *mem, - unsigned int page_size, unsigned int addr, unsigned int n_bytes) -{ + unsigned int page_size, unsigned int addr, unsigned int n_bytes) { return -1; } @@ -853,10 +811,9 @@ static int flip1_read_sig_bytes(const PROGRAMMER *pgm, const AVRPART *part, cons return -1; } -static void flip1_setup(PROGRAMMER * pgm) { +static void flip1_setup(PROGRAMMER *pgm) { } static void flip1_teardown(PROGRAMMER *pgm) { } - -#endif /* HAVE_LIBUSB */ +#endif // HAVE_LIBUSB diff --git a/src/flip1.h b/src/flip1.h index 18af3fabe..e26aba860 100644 --- a/src/flip1.h +++ b/src/flip1.h @@ -23,11 +23,11 @@ extern "C" { #endif -extern const char flip1_desc[]; -extern void flip1_initpgm(PROGRAMMER *pgm); + extern const char flip1_desc[]; + extern void flip1_initpgm(PROGRAMMER *pgm); #ifdef __cplusplus } #endif -#endif /* flip1_h */ +#endif diff --git a/src/flip2.c b/src/flip2.c index c3c8e543d..63ffbe1fb 100644 --- a/src/flip2.c +++ b/src/flip2.c @@ -31,9 +31,10 @@ #include "flip2.h" #include "dfu.h" -#include "usbdevs.h" /* for USB_VENDOR_ATMEL */ +#include "usbdevs.h" // For USB_VENDOR_ATMEL -/* There are three versions of the FLIP protocol: +/* + * There are three versions of the FLIP protocol: * * Version 0: C51 parts * Version 1: megaAVR parts ("USB DFU Bootloader Datasheet" [doc7618]) @@ -46,14 +47,9 @@ * udi_dfu_atmel.c from XMEGA bootloaders archive. */ -/* EXPORTED CONSTANT STRINGS */ - const char flip2_desc[] = "FLIP USB DFU protocol version 2 (AVR4023)"; -/* PRIVATE DATA STRUCTURES */ - -struct flip2 -{ +struct flip2 { struct dfu_dev *dfu; unsigned char part_sig[3]; unsigned char part_rev; @@ -76,7 +72,7 @@ struct flip2 #define FLIP2_STATUS_BLANK_FAIL 0x0500 #define FLIP2_STATUS_ERASE_ONGOING 0x0904 -/* FLIP2 data structures and constants. */ +// FLIP2 data structures and constants struct flip2_cmd { unsigned char group_id; @@ -121,11 +117,9 @@ enum flip2_mem_unit { #ifdef HAVE_LIBUSB -/* EXPORTED PROGRAMMER FUNCTION PROTOTYPES */ - static int flip2_open(PROGRAMMER *pgm, const char *port_spec); static int flip2_initialize(const PROGRAMMER *pgm, const AVRPART *part); -static void flip2_close(PROGRAMMER* pgm); +static void flip2_close(PROGRAMMER *pgm); static void flip2_enable(PROGRAMMER *pgm, const AVRPART *p); static void flip2_disable(const PROGRAMMER *pgm); static void flip2_display(const PROGRAMMER *pgm, const char *prefix); @@ -141,58 +135,51 @@ static int flip2_paged_load(const PROGRAMMER *pgm, const AVRPART *part, const AV static int flip2_paged_write(const PROGRAMMER *pgm, const AVRPART *part, const AVRMEM *mem, unsigned int page_size, unsigned int addr, unsigned int n_bytes); static int flip2_read_sig_bytes(const PROGRAMMER *pgm, const AVRPART *part, const AVRMEM *mem); -static int flip2_parseexitspecs(PROGRAMMER* pgm, const char *s); +static int flip2_parseexitspecs(PROGRAMMER *pgm, const char *s); static void flip2_setup(PROGRAMMER *pgm); static void flip2_teardown(PROGRAMMER *pgm); -/* INTERNAL PROGRAMMER FUNCTION PROTOTYPES */ - static void flip2_show_info(struct flip2 *flip2); - -static int flip2_read_memory(struct dfu_dev *dfu, - enum flip2_mem_unit mem_unit, uint32_t addr, void *ptr, int size); -static int flip2_write_memory(struct dfu_dev *dfu, - enum flip2_mem_unit mem_unit, uint32_t addr, const void *ptr, int size); - -static int flip2_set_mem_unit(struct dfu_dev *dfu, - enum flip2_mem_unit mem_unit); +static int flip2_read_memory(struct dfu_dev *dfu, enum flip2_mem_unit mem_unit, + uint32_t addr, void *ptr, int size); +static int flip2_write_memory(struct dfu_dev *dfu, enum flip2_mem_unit mem_unit, + uint32_t addr, const void *ptr, int size); +static int flip2_set_mem_unit(struct dfu_dev *dfu, enum flip2_mem_unit mem_unit); static int flip2_set_mem_page(struct dfu_dev *dfu, unsigned short page_addr); -static int flip2_read_max1k(struct dfu_dev *dfu, - unsigned short offset, void *ptr, unsigned short size); -static int flip2_write_max1k(struct dfu_dev *dfu, - unsigned short offset, const void *ptr, unsigned short size); +static int flip2_read_max1k(struct dfu_dev *dfu, unsigned short offset, + void *ptr, unsigned short size); +static int flip2_write_max1k(struct dfu_dev *dfu, unsigned short offset, + const void *ptr, unsigned short size); -static const char * flip2_status_str(const struct dfu_status *status); -static const char * flip2_mem_unit_str(enum flip2_mem_unit mem_unit); +static const char *flip2_status_str(const struct dfu_status *status); +static const char *flip2_mem_unit_str(enum flip2_mem_unit mem_unit); static enum flip2_mem_unit flip2_mem_unit(const char *name); void flip2_initpgm(PROGRAMMER *pgm) { strcpy(pgm->type, "flip2"); - /* Mandatory Functions */ - pgm->initialize = flip2_initialize; - pgm->enable = flip2_enable; - pgm->disable = flip2_disable; - pgm->display = flip2_display; - pgm->program_enable = flip2_program_enable; - pgm->chip_erase = flip2_chip_erase; - pgm->open = flip2_open; - pgm->close = flip2_close; - pgm->paged_load = flip2_paged_load; - pgm->paged_write = flip2_paged_write; - pgm->read_byte = flip2_read_byte; - pgm->write_byte = flip2_write_byte; - pgm->read_sig_bytes = flip2_read_sig_bytes; - pgm->parseexitspecs = flip2_parseexitspecs; - pgm->setup = flip2_setup; - pgm->teardown = flip2_teardown; + // Mandatory functions + pgm->initialize = flip2_initialize; + pgm->enable = flip2_enable; + pgm->disable = flip2_disable; + pgm->display = flip2_display; + pgm->program_enable = flip2_program_enable; + pgm->chip_erase = flip2_chip_erase; + pgm->open = flip2_open; + pgm->close = flip2_close; + pgm->paged_load = flip2_paged_load; + pgm->paged_write = flip2_paged_write; + pgm->read_byte = flip2_read_byte; + pgm->write_byte = flip2_write_byte; + pgm->read_sig_bytes = flip2_read_sig_bytes; + pgm->parseexitspecs = flip2_parseexitspecs; + pgm->setup = flip2_setup; + pgm->teardown = flip2_teardown; } -/* EXPORTED PROGRAMMER FUNCTION DEFINITIONS */ - static int flip2_open(PROGRAMMER *pgm, const char *port_spec) { FLIP2(pgm)->dfu = dfu_open(port_spec); - return (FLIP2(pgm)->dfu != NULL) ? 0 : -1; + return (FLIP2(pgm)->dfu != NULL)? 0: -1; } static int flip2_initialize(const PROGRAMMER *pgm, const AVRPART *part) { @@ -219,17 +206,18 @@ static int flip2_initialize(const PROGRAMMER *pgm, const AVRPART *part) { * the PID when matching a target device. */ - vid = (pgm->usbvid != 0) ? pgm->usbvid : USB_VENDOR_ATMEL; + vid = (pgm->usbvid != 0)? pgm->usbvid: USB_VENDOR_ATMEL; LNODEID usbpid = lfirst(pgm->usbpid); - if (usbpid) { - pid = *(int *)(ldata(usbpid)); - if (lnext(usbpid)) + + if(usbpid) { + pid = *(int *) (ldata(usbpid)); + if(lnext(usbpid)) pmsg_warning("using PID 0x%04x, ignoring remaining PIDs in list\n", pid); } else { pid = part->usbpid; } - if (!ovsigck && !(part->prog_modes & PM_PDI)) { + if(!ovsigck && !is_pdi(part)) { pmsg_error("flip2 (FLIP protocol version 2) is for Xmega devices;\n"); imsg_error("for AT90USB* or ATmega*U* devices use flip1 or use -F to bypass this check\n"); return -1; @@ -237,64 +225,52 @@ static int flip2_initialize(const PROGRAMMER *pgm, const AVRPART *part) { result = dfu_init(dfu, vid, pid); - if (result != 0) + if(result != 0) goto flip2_initialize_fail; - /* Check if descriptor values are what we expect. */ + // Check if descriptor values are what we expect - if (dfu->dev_desc.idVendor != vid) - pmsg_warning("USB idVendor = 0x%04X (expected 0x%04X)\n", - dfu->dev_desc.idVendor, vid); + if(dfu->dev_desc.idVendor != vid) + pmsg_warning("USB idVendor = 0x%04X (expected 0x%04X)\n", dfu->dev_desc.idVendor, vid); - if (pid != 0 && dfu->dev_desc.idProduct != pid) - pmsg_warning("USB idProduct = 0x%04X (expected 0x%04X)\n", - dfu->dev_desc.idProduct, pid); + if(pid != 0 && dfu->dev_desc.idProduct != pid) + pmsg_warning("USB idProduct = 0x%04X (expected 0x%04X)\n", dfu->dev_desc.idProduct, pid); - if (dfu->dev_desc.bNumConfigurations != 1) - pmsg_error("USB bNumConfigurations = %d (expected 1)\n", - (int) dfu->dev_desc.bNumConfigurations); + if(dfu->dev_desc.bNumConfigurations != 1) + pmsg_error("USB bNumConfigurations = %d (expected 1)\n", (int) dfu->dev_desc.bNumConfigurations); - if (dfu->conf_desc.bNumInterfaces != 1) - pmsg_error("USB bNumInterfaces = %d (expected 1)\n", - (int) dfu->conf_desc.bNumInterfaces); + if(dfu->conf_desc.bNumInterfaces != 1) + pmsg_error("USB bNumInterfaces = %d (expected 1)\n", (int) dfu->conf_desc.bNumInterfaces); - if (dfu->dev_desc.bDeviceClass != 0) - pmsg_error("USB bDeviceClass = %d (expected 0)\n", - (int) dfu->dev_desc.bDeviceClass); + if(dfu->dev_desc.bDeviceClass != 0) + pmsg_error("USB bDeviceClass = %d (expected 0)\n", (int) dfu->dev_desc.bDeviceClass); - if (dfu->dev_desc.bDeviceSubClass != 0) - pmsg_error("USB bDeviceSubClass = %d (expected 0)\n", - (int) dfu->dev_desc.bDeviceSubClass); + if(dfu->dev_desc.bDeviceSubClass != 0) + pmsg_error("USB bDeviceSubClass = %d (expected 0)\n", (int) dfu->dev_desc.bDeviceSubClass); - if (dfu->dev_desc.bDeviceProtocol != 0) - pmsg_error("USB bDeviceProtocol = %d (expected 0)\n", - (int) dfu->dev_desc.bDeviceProtocol); + if(dfu->dev_desc.bDeviceProtocol != 0) + pmsg_error("USB bDeviceProtocol = %d (expected 0)\n", (int) dfu->dev_desc.bDeviceProtocol); - if (dfu->intf_desc.bInterfaceClass != 0xFF) - pmsg_error("USB bInterfaceClass = %d (expected 255)\n", - (int) dfu->intf_desc.bInterfaceClass); + if(dfu->intf_desc.bInterfaceClass != 0xFF) + pmsg_error("USB bInterfaceClass = %d (expected 255)\n", (int) dfu->intf_desc.bInterfaceClass); - if (dfu->intf_desc.bInterfaceSubClass != 0) - pmsg_error("USB bInterfaceSubClass = %d (expected 0)\n", - (int) dfu->intf_desc.bInterfaceSubClass); + if(dfu->intf_desc.bInterfaceSubClass != 0) + pmsg_error("USB bInterfaceSubClass = %d (expected 0)\n", (int) dfu->intf_desc.bInterfaceSubClass); - if (dfu->intf_desc.bInterfaceProtocol != 0) - pmsg_error("USB bInterfaceSubClass = %d (expected 0)\n", - (int) dfu->intf_desc.bInterfaceProtocol); + if(dfu->intf_desc.bInterfaceProtocol != 0) + pmsg_error("USB bInterfaceSubClass = %d (expected 0)\n", (int) dfu->intf_desc.bInterfaceProtocol); - result = flip2_read_memory(FLIP2(pgm)->dfu, - FLIP2_MEM_UNIT_SIGNATURE, 0, FLIP2(pgm)->part_sig, 4); + result = flip2_read_memory(FLIP2(pgm)->dfu, FLIP2_MEM_UNIT_SIGNATURE, 0, FLIP2(pgm)->part_sig, 4); - if (result != 0) + if(result != 0) goto flip2_initialize_fail; - result = flip2_read_memory(FLIP2(pgm)->dfu, - FLIP2_MEM_UNIT_BOOTLOADER, 0, &FLIP2(pgm)->boot_ver, 1); + result = flip2_read_memory(FLIP2(pgm)->dfu, FLIP2_MEM_UNIT_BOOTLOADER, 0, &FLIP2(pgm)->boot_ver, 1); - if (result != 0) + if(result != 0) goto flip2_initialize_fail; - if (verbose > 0) + if(verbose > 0) flip2_show_info(FLIP2(pgm)); return 0; @@ -306,8 +282,8 @@ static int flip2_initialize(const PROGRAMMER *pgm, const AVRPART *part) { } static void flip2_close(PROGRAMMER *pgm) { - if (FLIP2(pgm)->dfu != NULL) { - if (pgm->exit_reset == EXIT_RESET_ENABLED) + if(FLIP2(pgm)->dfu != NULL) { + if(pgm->exit_reset == EXIT_RESET_ENABLED) flip2_start_app(pgm); dfu_close(FLIP2(pgm)->dfu); @@ -336,20 +312,19 @@ static int flip2_chip_erase(const PROGRAMMER *pgm, const AVRPART *part) { pmsg_debug("flip_chip_erase()\n"); struct flip2_cmd cmd = { - FLIP2_CMD_GROUP_EXEC, FLIP2_CMD_CHIP_ERASE, { 0xFF, 0, 0, 0 } + FLIP2_CMD_GROUP_EXEC, FLIP2_CMD_CHIP_ERASE, {0xFF, 0, 0, 0} }; - for (;;) { + for(;;) { cmd_result = dfu_dnload(FLIP2(pgm)->dfu, &cmd, sizeof(cmd)); aux_result = dfu_getstatus(FLIP2(pgm)->dfu, &status); - if (aux_result != 0) + if(aux_result != 0) return aux_result; - if (status.bStatus != DFU_STATUS_OK) { - if (status.bStatus == ((FLIP2_STATUS_ERASE_ONGOING >> 8) & 0xFF) && - status.bState == ((FLIP2_STATUS_ERASE_ONGOING >> 0) & 0xFF)) - { + if(status.bStatus != DFU_STATUS_OK) { + if(status.bStatus == ((FLIP2_STATUS_ERASE_ONGOING >> 8) & 0xFF) && + status.bState == ((FLIP2_STATUS_ERASE_ONGOING >> 0) & 0xFF)) { continue; } pmsg_error("DFU status %s\n", flip2_status_str(&status)); @@ -365,13 +340,13 @@ static int flip2_start_app(const PROGRAMMER *pgm) { pmsg_info("starting application\n"); struct flip2_cmd cmd = { - FLIP2_CMD_GROUP_EXEC, FLIP2_CMD_START_APP, { 0x00, 0, 0, 0 } + FLIP2_CMD_GROUP_EXEC, FLIP2_CMD_START_APP, {0x00, 0, 0, 0} }; - // queue command + // Queue command int cmd_result = dfu_dnload(FLIP2(pgm)->dfu, &cmd, sizeof(cmd)); - // repeat dnload to actually execute + // Repeat dnload to actually execute dfu_dnload(FLIP2(pgm)->dfu, &cmd, sizeof(cmd)); return cmd_result; @@ -381,14 +356,14 @@ static int flip2_read_byte(const PROGRAMMER *pgm, const AVRPART *part, const AVR unsigned long addr, unsigned char *value) { enum flip2_mem_unit mem_unit; - if (FLIP2(pgm)->dfu == NULL) + if(FLIP2(pgm)->dfu == NULL) return -1; mem_unit = flip2_mem_unit(mem->desc); - if (mem_unit == FLIP2_MEM_UNIT_UNKNOWN) { + if(mem_unit == FLIP2_MEM_UNIT_UNKNOWN) { pmsg_error("%s memory not accessible using FLIP", mem->desc); - if (mem_is_flash(mem)) + if(mem_is_flash(mem)) msg_error(" (did you mean \"application\"?)"); msg_error("\n"); return -1; @@ -403,6 +378,7 @@ static int flip2_write_byte(const PROGRAMMER *pgm, const AVRPART *part, const AV if(mem_is_readonly(mem)) { unsigned char is; + if(pgm->read_byte(pgm, part, mem, addr, &is) >= 0 && is == value) return 0; @@ -410,14 +386,14 @@ static int flip2_write_byte(const PROGRAMMER *pgm, const AVRPART *part, const AV return -1; } - if (FLIP2(pgm)->dfu == NULL) + if(FLIP2(pgm)->dfu == NULL) return -1; mem_unit = flip2_mem_unit(mem->desc); - if (mem_unit == FLIP2_MEM_UNIT_UNKNOWN) { + if(mem_unit == FLIP2_MEM_UNIT_UNKNOWN) { pmsg_error("%s memory not accessible using FLIP", mem->desc); - if (mem_is_flash(mem)) + if(mem_is_flash(mem)) msg_error(" (did you mean \"application\"?)"); msg_error("\n"); return -1; @@ -432,27 +408,26 @@ static int flip2_paged_load(const PROGRAMMER *pgm, const AVRPART *part, const AV enum flip2_mem_unit mem_unit; int result; - if (FLIP2(pgm)->dfu == NULL) + if(FLIP2(pgm)->dfu == NULL) return -1; mem_unit = flip2_mem_unit(mem->desc); - if (mem_unit == FLIP2_MEM_UNIT_UNKNOWN) { + if(mem_unit == FLIP2_MEM_UNIT_UNKNOWN) { pmsg_error("%s memory not accessible using FLIP", mem->desc); - if (mem_is_flash(mem)) + if(mem_is_flash(mem)) msg_error(" (did you mean \"application\"?)"); msg_error("\n"); return -1; } - if (n_bytes > INT_MAX) { - /* This should never happen, unless the int type is only 16 bits. */ + if(n_bytes > INT_MAX) { + // This should never happen, unless the int type is only 16 bits pmsg_error("attempting to read more than %d bytes\n", INT_MAX); return -1; } - result = flip2_read_memory(FLIP2(pgm)->dfu, mem_unit, addr, - mem->buf + addr, n_bytes); + result = flip2_read_memory(FLIP2(pgm)->dfu, mem_unit, addr, mem->buf + addr, n_bytes); return result == 0? (int) n_bytes: -1; } @@ -463,27 +438,26 @@ static int flip2_paged_write(const PROGRAMMER *pgm, const AVRPART *part, const A enum flip2_mem_unit mem_unit; int result; - if (FLIP2(pgm)->dfu == NULL) + if(FLIP2(pgm)->dfu == NULL) return -1; mem_unit = flip2_mem_unit(mem->desc); - if (mem_unit == FLIP2_MEM_UNIT_UNKNOWN) { + if(mem_unit == FLIP2_MEM_UNIT_UNKNOWN) { pmsg_error("%s memory not accessible using FLIP", mem->desc); - if (mem_is_flash(mem)) + if(mem_is_flash(mem)) msg_error(" (did you mean \"application\"?)"); msg_error("\n"); return -1; } - if (n_bytes > INT_MAX) { - /* This should never happen, unless the int type is only 16 bits. */ + if(n_bytes > INT_MAX) { + // This should never happen, unless the int type is only 16 bits pmsg_error("attempting to read more than %d bytes\n", INT_MAX); return -1; } - result = flip2_write_memory(FLIP2(pgm)->dfu, mem_unit, addr, - mem->buf + addr, n_bytes); + result = flip2_write_memory(FLIP2(pgm)->dfu, mem_unit, addr, mem->buf + addr, n_bytes); return result == 0? (int) n_bytes: -1; } @@ -495,22 +469,22 @@ static int flip2_parseexitspecs(PROGRAMMER *pgm, const char *sp) { bool help = false; s = str; - while ((cp = strtok(s, ","))) { + while((cp = strtok(s, ","))) { s = NULL; - if (str_eq(cp, "reset")) { + if(str_eq(cp, "reset")) { pgm->exit_reset = EXIT_RESET_ENABLED; continue; } - if (str_eq(cp, "noreset")) { + if(str_eq(cp, "noreset")) { pgm->exit_reset = EXIT_RESET_DISABLED; continue; } - if (str_eq(cp, "help")) { + if(str_eq(cp, "help")) { help = true; rv = LIBAVRDUDE_EXIT; } - if (!help) { + if(!help) { pmsg_error("invalid exitspec parameter -E %s\n", cp); rv = -1; } @@ -527,10 +501,10 @@ static int flip2_parseexitspecs(PROGRAMMER *pgm, const char *sp) { } static int flip2_read_sig_bytes(const PROGRAMMER *pgm, const AVRPART *part, const AVRMEM *mem) { - if (FLIP2(pgm)->dfu == NULL) + if(FLIP2(pgm)->dfu == NULL) return -1; - if (mem->size < (int) sizeof(FLIP2(pgm)->part_sig)) { + if(mem->size < (int) sizeof(FLIP2(pgm)->part_sig)) { pmsg_error("signature read must be at least %u bytes\n", (unsigned int) sizeof(FLIP2(pgm)->part_sig)); return -1; } @@ -555,32 +529,27 @@ static void flip2_show_info(struct flip2 *flip2) { dfu_show_info(flip2->dfu); msg_info(" Part signature : 0x%02X%02X%02X\n", - (int) flip2->part_sig[0], - (int) flip2->part_sig[1], - (int) flip2->part_sig[2]); + (int) flip2->part_sig[0], (int) flip2->part_sig[1], (int) flip2->part_sig[2]); - if (flip2->part_rev < 26) - msg_info(" Part revision : %c\n", - (char) (flip2->part_rev + 'A')); + if(flip2->part_rev < 26) + msg_info(" Part revision : %c\n", (char) (flip2->part_rev + 'A')); else msg_info(" Part revision : %c%c\n", - (char) (flip2->part_rev / 26 - 1 + 'A'), - (char) (flip2->part_rev % 26 + 'A')); + (char) (flip2->part_rev/26 - 1 + 'A'), (char) (flip2->part_rev%26 + 'A')); msg_info(" Bootloader version : 2.%u.%u\n", - (flip2->boot_ver >> 4) & 0xF, - (flip2->boot_ver >> 0) & 0xF); + (flip2->boot_ver >> 4) & 0xF, (flip2->boot_ver >> 0) & 0xF); msg_info(" USB max packet size : %hu\n", (unsigned short) flip2->dfu->dev_desc.bMaxPacketSize0); } -static int flip2_read_memory(struct dfu_dev *dfu, - enum flip2_mem_unit mem_unit, uint32_t addr, void *ptr, int size) { +static int flip2_read_memory(struct dfu_dev *dfu, enum flip2_mem_unit mem_unit, + uint32_t addr, void *ptr, int size) { unsigned short prev_page_addr; unsigned short page_addr; - const char * mem_name; + const char *mem_name; int read_size; int result; @@ -588,8 +557,8 @@ static int flip2_read_memory(struct dfu_dev *dfu, result = flip2_set_mem_unit(dfu, mem_unit); - if (result != 0) { - if ((mem_name = flip2_mem_unit_str(mem_unit)) != NULL) + if(result != 0) { + if((mem_name = flip2_mem_unit_str(mem_unit)) != NULL) pmsg_error("unable to set memory unit 0x%02X (%s)\n", (int) mem_unit, mem_name); else pmsg_error("unable to set memory unit 0x%02X\n", (int) mem_unit); @@ -599,32 +568,32 @@ static int flip2_read_memory(struct dfu_dev *dfu, page_addr = addr >> 16; result = flip2_set_mem_page(dfu, page_addr); - if (result != 0) { + if(result != 0) { pmsg_error("unable to set memory page 0x%04hX\n", page_addr); return -1; } - while (size > 0) { + while(size > 0) { prev_page_addr = page_addr; page_addr = addr >> 16; - if (page_addr != prev_page_addr) { + if(page_addr != prev_page_addr) { result = flip2_set_mem_page(dfu, page_addr); - if (result != 0) { + if(result != 0) { pmsg_error("unable to set memory page 0x%04hX\n", page_addr); return -1; } } - read_size = (size > 0x400) ? 0x400 : size; + read_size = (size > 0x400)? 0x400: size; result = flip2_read_max1k(dfu, addr & 0xFFFF, ptr, read_size); - if (result != 0) { + if(result != 0) { pmsg_error("unable to read 0x%04X bytes at 0x%04lX\n", read_size, (unsigned long) addr); return -1; } - ptr = (char*)ptr + read_size; + ptr = (char *) ptr + read_size; addr += read_size; size -= read_size; } @@ -632,12 +601,12 @@ static int flip2_read_memory(struct dfu_dev *dfu, return 0; } -static int flip2_write_memory(struct dfu_dev *dfu, - enum flip2_mem_unit mem_unit, uint32_t addr, const void *ptr, int size) { +static int flip2_write_memory(struct dfu_dev *dfu, enum flip2_mem_unit mem_unit, + uint32_t addr, const void *ptr, int size) { unsigned short prev_page_addr; unsigned short page_addr; - const char * mem_name; + const char *mem_name; int write_size; int result; @@ -645,8 +614,8 @@ static int flip2_write_memory(struct dfu_dev *dfu, result = flip2_set_mem_unit(dfu, mem_unit); - if (result != 0) { - if ((mem_name = flip2_mem_unit_str(mem_unit)) != NULL) + if(result != 0) { + if((mem_name = flip2_mem_unit_str(mem_unit)) != NULL) pmsg_error("unable to set memory unit 0x%02X (%s)\n", (int) mem_unit, mem_name); else pmsg_error("unable to set memory unit 0x%02X\n", (int) mem_unit); @@ -656,32 +625,32 @@ static int flip2_write_memory(struct dfu_dev *dfu, page_addr = addr >> 16; result = flip2_set_mem_page(dfu, page_addr); - if (result != 0) { + if(result != 0) { pmsg_error("unable to set memory page 0x%04hX\n", page_addr); return -1; } - while (size > 0) { + while(size > 0) { prev_page_addr = page_addr; page_addr = addr >> 16; - if (page_addr != prev_page_addr) { + if(page_addr != prev_page_addr) { result = flip2_set_mem_page(dfu, page_addr); - if (result != 0) { + if(result != 0) { pmsg_error("unable to set memory page 0x%04hX\n", page_addr); return -1; } } - write_size = (size > 0x800) ? 0x800 : size; + write_size = (size > 0x800)? 0x800: size; result = flip2_write_max1k(dfu, addr & 0xFFFF, ptr, write_size); - if (result != 0) { + if(result != 0) { pmsg_error("unable to write 0x%04X bytes at 0x%04lX\n", write_size, (unsigned long) addr); return -1; } - ptr = (const char*)ptr + write_size; + ptr = (const char *) ptr + write_size; addr += write_size; size -= write_size; } @@ -695,7 +664,7 @@ static int flip2_set_mem_unit(struct dfu_dev *dfu, enum flip2_mem_unit mem_unit) int aux_result; struct flip2_cmd cmd = { - FLIP2_CMD_GROUP_SELECT, FLIP2_CMD_SELECT_MEMORY, { 0, 0, 0, 0 } + FLIP2_CMD_GROUP_SELECT, FLIP2_CMD_SELECT_MEMORY, {0, 0, 0, 0} }; cmd.args[0] = FLIP2_SELECT_MEMORY_UNIT; @@ -705,13 +674,13 @@ static int flip2_set_mem_unit(struct dfu_dev *dfu, enum flip2_mem_unit mem_unit) aux_result = dfu_getstatus(dfu, &status); - if (aux_result != 0) + if(aux_result != 0) return aux_result; - if (status.bStatus != DFU_STATUS_OK) { - if (status.bStatus == ((FLIP2_STATUS_OUTOFRANGE >> 8) & 0xFF) && - status.bState == ((FLIP2_STATUS_OUTOFRANGE >> 0) & 0xFF)) - { + if(status.bStatus != DFU_STATUS_OK) { + if(status.bStatus == ((FLIP2_STATUS_OUTOFRANGE >> 8) & 0xFF) && + status.bState == ((FLIP2_STATUS_OUTOFRANGE >> 0) & 0xFF)) { + pmsg_error("unknown memory unit (0x%02x)\n", (unsigned int) mem_unit); } else pmsg_error("DFU status %s\n", flip2_status_str(&status)); @@ -721,15 +690,14 @@ static int flip2_set_mem_unit(struct dfu_dev *dfu, enum flip2_mem_unit mem_unit) return cmd_result; } -static int flip2_set_mem_page(struct dfu_dev *dfu, - unsigned short page_addr) { +static int flip2_set_mem_page(struct dfu_dev *dfu, unsigned short page_addr) { struct dfu_status status; int cmd_result = 0; int aux_result; struct flip2_cmd cmd = { - FLIP2_CMD_GROUP_SELECT, FLIP2_CMD_SELECT_MEMORY, { 0, 0, 0, 0 } + FLIP2_CMD_GROUP_SELECT, FLIP2_CMD_SELECT_MEMORY, {0, 0, 0, 0} }; cmd.args[0] = FLIP2_SELECT_MEMORY_PAGE; @@ -740,13 +708,13 @@ static int flip2_set_mem_page(struct dfu_dev *dfu, aux_result = dfu_getstatus(dfu, &status); - if (aux_result != 0) + if(aux_result != 0) return aux_result; - if (status.bStatus != DFU_STATUS_OK) { - if (status.bStatus == ((FLIP2_STATUS_OUTOFRANGE >> 8) & 0xFF) && - status.bState == ((FLIP2_STATUS_OUTOFRANGE >> 0) & 0xFF)) - { + if(status.bStatus != DFU_STATUS_OK) { + if(status.bStatus == ((FLIP2_STATUS_OUTOFRANGE >> 8) & 0xFF) && + status.bState == ((FLIP2_STATUS_OUTOFRANGE >> 0) & 0xFF)) { + pmsg_error("page address out of range (0x%04hx)\n", page_addr); } else pmsg_error("DFU status %s\n", flip2_status_str(&status)); @@ -756,41 +724,40 @@ static int flip2_set_mem_page(struct dfu_dev *dfu, return cmd_result; } -static int flip2_read_max1k(struct dfu_dev *dfu, - unsigned short offset, void *ptr, unsigned short size) { +static int flip2_read_max1k(struct dfu_dev *dfu, unsigned short offset, void *ptr, unsigned short size) { struct dfu_status status; int cmd_result = 0; int aux_result; struct flip2_cmd cmd = { - FLIP2_CMD_GROUP_UPLOAD, FLIP2_CMD_READ_MEMORY, { 0, 0, 0, 0 } + FLIP2_CMD_GROUP_UPLOAD, FLIP2_CMD_READ_MEMORY, {0, 0, 0, 0} }; cmd.args[0] = (offset >> 8) & 0xFF; cmd.args[1] = (offset >> 0) & 0xFF; - cmd.args[2] = ((offset+size-1) >> 8) & 0xFF; - cmd.args[3] = ((offset+size-1) >> 0) & 0xFF; + cmd.args[2] = ((offset + size - 1) >> 8) & 0xFF; + cmd.args[3] = ((offset + size - 1) >> 0) & 0xFF; cmd_result = dfu_dnload(dfu, &cmd, sizeof(cmd)); - if (cmd_result != 0) + if(cmd_result != 0) goto flip2_read_max1k_status; - cmd_result = dfu_upload(dfu, (char*) ptr, size); + cmd_result = dfu_upload(dfu, (char *) ptr, size); flip2_read_max1k_status: aux_result = dfu_getstatus(dfu, &status); - if (aux_result != 0) + if(aux_result != 0) return aux_result; - if (status.bStatus != DFU_STATUS_OK) { - if (status.bStatus == ((FLIP2_STATUS_OUTOFRANGE >> 8) & 0xFF) && - status.bState == ((FLIP2_STATUS_OUTOFRANGE >> 0) & 0xFF)) - { - pmsg_error("address out of range [0x%04X,0x%04X]\n", offset, (offset+size-1) & 0xffff); + if(status.bStatus != DFU_STATUS_OK) { + if(status.bStatus == ((FLIP2_STATUS_OUTOFRANGE >> 8) & 0xFF) && + status.bState == ((FLIP2_STATUS_OUTOFRANGE >> 0) & 0xFF)) { + + pmsg_error("address out of range [0x%04X,0x%04X]\n", offset, (offset + size - 1) & 0xffff); } else pmsg_error("DFU status %s\n", flip2_status_str(&status)); dfu_clrstatus(dfu); @@ -799,25 +766,24 @@ static int flip2_read_max1k(struct dfu_dev *dfu, return cmd_result; } -static int flip2_write_max1k(struct dfu_dev *dfu, - unsigned short offset, const void *ptr, unsigned short size) { +static int flip2_write_max1k(struct dfu_dev *dfu, unsigned short offset, const void *ptr, unsigned short size) { - char buffer[64+64+0x400]; + char buffer[64 + 64 + 0x400]; unsigned short data_offset; struct dfu_status status; int cmd_result = 0; int aux_result; struct flip2_cmd cmd = { - FLIP2_CMD_GROUP_DOWNLOAD, FLIP2_CMD_PROG_START, { 0, 0, 0, 0 } + FLIP2_CMD_GROUP_DOWNLOAD, FLIP2_CMD_PROG_START, {0, 0, 0, 0} }; cmd.args[0] = (offset >> 8) & 0xFF; cmd.args[1] = (offset >> 0) & 0xFF; - cmd.args[2] = ((offset+size-1) >> 8) & 0xFF; - cmd.args[3] = ((offset+size-1) >> 0) & 0xFF; + cmd.args[2] = ((offset + size - 1) >> 8) & 0xFF; + cmd.args[3] = ((offset + size - 1) >> 0) & 0xFF; - if (size > 0x400) { + if(size > 0x400) { pmsg_error("erite block too large (%hu > 1024)\n", size); return -1; } @@ -831,7 +797,7 @@ static int flip2_write_max1k(struct dfu_dev *dfu, */ data_offset = dfu->dev_desc.bMaxPacketSize0; - data_offset += offset % dfu->dev_desc.bMaxPacketSize0; + data_offset += offset%dfu->dev_desc.bMaxPacketSize0; memcpy(buffer, &cmd, sizeof(cmd)); memset(buffer + sizeof(cmd), 0, data_offset - sizeof(cmd)); @@ -841,14 +807,14 @@ static int flip2_write_max1k(struct dfu_dev *dfu, aux_result = dfu_getstatus(dfu, &status); - if (aux_result != 0) + if(aux_result != 0) return aux_result; - if (status.bStatus != DFU_STATUS_OK) { - if (status.bStatus == ((FLIP2_STATUS_OUTOFRANGE >> 8) & 0xFF) && - status.bState == ((FLIP2_STATUS_OUTOFRANGE >> 0) & 0xFF)) - { - pmsg_error("address out of range [0x%04X,0x%04X]\n", offset, (offset+size-1) & 0xffff); + if(status.bStatus != DFU_STATUS_OK) { + if(status.bStatus == ((FLIP2_STATUS_OUTOFRANGE >> 8) & 0xFF) && + status.bState == ((FLIP2_STATUS_OUTOFRANGE >> 0) & 0xFF)) { + + pmsg_error("address out of range [0x%04X,0x%04X]\n", offset, (offset + size - 1) & 0xffff); } else pmsg_error("DFU status %s\n", flip2_status_str(&status)); dfu_clrstatus(dfu); @@ -863,62 +829,87 @@ static const char *flip2_status_str(const struct dfu_status *status) { selector = (unsigned short) status->bStatus << 8; selector |= status->bState; - switch (selector) { - case FLIP2_STATUS_OK: return "OK"; - case FLIP2_STATUS_STALL: return "STALL"; - case FLIP2_STATUS_MEM_UKNOWN: return "MEM_UKNOWN"; - case FLIP2_STATUS_MEM_PROTECTED: return "MEM_PROTECTED"; - case FLIP2_STATUS_OUTOFRANGE: return "OUTOFRANGE"; - case FLIP2_STATUS_BLANK_FAIL: return "BLANK_FAIL"; - case FLIP2_STATUS_ERASE_ONGOING: return "ERASE_ONGOING"; - default: return dfu_status_str(status->bStatus); + switch(selector) { + case FLIP2_STATUS_OK: + return "OK"; + case FLIP2_STATUS_STALL: + return "STALL"; + case FLIP2_STATUS_MEM_UKNOWN: + return "MEM_UKNOWN"; + case FLIP2_STATUS_MEM_PROTECTED: + return "MEM_PROTECTED"; + case FLIP2_STATUS_OUTOFRANGE: + return "OUTOFRANGE"; + case FLIP2_STATUS_BLANK_FAIL: + return "BLANK_FAIL"; + case FLIP2_STATUS_ERASE_ONGOING: + return "ERASE_ONGOING"; + default: + return dfu_status_str(status->bStatus); } } -static const char * flip2_mem_unit_str(enum flip2_mem_unit mem_unit) { - switch (mem_unit) { - case FLIP2_MEM_UNIT_FLASH: return "Flash"; - case FLIP2_MEM_UNIT_EEPROM: return "EEPROM"; - case FLIP2_MEM_UNIT_SECURITY: return "security"; - case FLIP2_MEM_UNIT_CONFIGURATION: return "configuration"; - case FLIP2_MEM_UNIT_BOOTLOADER: return "bootloader version"; - case FLIP2_MEM_UNIT_SIGNATURE: return "signature"; - case FLIP2_MEM_UNIT_USER: return "user"; - case FLIP2_MEM_UNIT_INT_RAM: return "internal RAM"; - case FLIP2_MEM_UNIT_EXT_MEM_CS0: return "EXT_MEM_CS0"; - case FLIP2_MEM_UNIT_EXT_MEM_CS1: return "EXT_MEM_CS1"; - case FLIP2_MEM_UNIT_EXT_MEM_CS2: return "EXT_MEM_CS2"; - case FLIP2_MEM_UNIT_EXT_MEM_CS3: return "EXT_MEM_CS3"; - case FLIP2_MEM_UNIT_EXT_MEM_CS4: return "EXT_MEM_CS4"; - case FLIP2_MEM_UNIT_EXT_MEM_CS5: return "EXT_MEM_CS5"; - case FLIP2_MEM_UNIT_EXT_MEM_CS6: return "EXT_MEM_CS6"; - case FLIP2_MEM_UNIT_EXT_MEM_CS7: return "EXT_MEM_CS7"; - case FLIP2_MEM_UNIT_EXT_MEM_DF: return "EXT_MEM_DF"; - default: return "unknown"; +static const char *flip2_mem_unit_str(enum flip2_mem_unit mem_unit) { + switch(mem_unit) { + case FLIP2_MEM_UNIT_FLASH: + return "Flash"; + case FLIP2_MEM_UNIT_EEPROM: + return "EEPROM"; + case FLIP2_MEM_UNIT_SECURITY: + return "security"; + case FLIP2_MEM_UNIT_CONFIGURATION: + return "configuration"; + case FLIP2_MEM_UNIT_BOOTLOADER: + return "bootloader version"; + case FLIP2_MEM_UNIT_SIGNATURE: + return "signature"; + case FLIP2_MEM_UNIT_USER: + return "user"; + case FLIP2_MEM_UNIT_INT_RAM: + return "internal RAM"; + case FLIP2_MEM_UNIT_EXT_MEM_CS0: + return "EXT_MEM_CS0"; + case FLIP2_MEM_UNIT_EXT_MEM_CS1: + return "EXT_MEM_CS1"; + case FLIP2_MEM_UNIT_EXT_MEM_CS2: + return "EXT_MEM_CS2"; + case FLIP2_MEM_UNIT_EXT_MEM_CS3: + return "EXT_MEM_CS3"; + case FLIP2_MEM_UNIT_EXT_MEM_CS4: + return "EXT_MEM_CS4"; + case FLIP2_MEM_UNIT_EXT_MEM_CS5: + return "EXT_MEM_CS5"; + case FLIP2_MEM_UNIT_EXT_MEM_CS6: + return "EXT_MEM_CS6"; + case FLIP2_MEM_UNIT_EXT_MEM_CS7: + return "EXT_MEM_CS7"; + case FLIP2_MEM_UNIT_EXT_MEM_DF: + return "EXT_MEM_DF"; + default: + return "unknown"; } } static enum flip2_mem_unit flip2_mem_unit(const char *name) { - if (str_eq(name, "application")) + if(str_eq(name, "application")) return FLIP2_MEM_UNIT_FLASH; - if (str_eq(name, "eeprom")) + if(str_eq(name, "eeprom")) return FLIP2_MEM_UNIT_EEPROM; - if (str_eq(name, "signature")) + if(str_eq(name, "signature")) return FLIP2_MEM_UNIT_SIGNATURE; return FLIP2_MEM_UNIT_UNKNOWN; } -#else /* !HAVE_LIBUSB */ +#else // !HAVE_LIBUSB // Give a proper error if we were not compiled with libusb -static int flip2_nousb_open(PROGRAMMER* pgm, const char* name) { - pmsg_error("no USB support; please compile with libusb installed\n"); - return -1; +static int flip2_nousb_open(PROGRAMMER *pgm, const char *name) { + pmsg_error("no USB support; please compile with libusb installed\n"); + return -1; } void flip2_initpgm(PROGRAMMER *pgm) { - strcpy(pgm->type, "flip2"); - pgm->open = flip2_nousb_open; + strcpy(pgm->type, "flip2"); + pgm->open = flip2_nousb_open; } - -#endif /* HAVE_LIBUSB */ +#endif // HAVE_LIBUSB diff --git a/src/flip2.h b/src/flip2.h index eed0cfc1a..61ec616fd 100644 --- a/src/flip2.h +++ b/src/flip2.h @@ -23,11 +23,11 @@ extern "C" { #endif -extern const char flip2_desc[]; -extern void flip2_initpgm(PROGRAMMER *pgm); + extern const char flip2_desc[]; + extern void flip2_initpgm(PROGRAMMER *pgm); #ifdef __cplusplus } #endif -#endif /* flip2_h */ +#endif diff --git a/src/freebsd_ppi.h b/src/freebsd_ppi.h index 40cf60d5d..22f66cbfa 100644 --- a/src/freebsd_ppi.h +++ b/src/freebsd_ppi.h @@ -25,13 +25,12 @@ #define ppi_release(fd) {} -#define DO_PPI_READ(fd, reg, valp) \ - (void)ioctl(fd, \ - (reg) == PPIDATA? PPIGDATA: ((reg) == PPICTRL? PPIGCTRL: PPIGSTATUS), \ - valp) -#define DO_PPI_WRITE(fd, reg, valp) \ - (void)ioctl(fd, \ - (reg) == PPIDATA? PPISDATA: ((reg) == PPICTRL? PPISCTRL: PPISSTATUS), \ - valp) +#define DO_PPI_READ(fd, reg, valp) ((void) ioctl((fd), \ + (reg) == PPIDATA? PPIGDATA: (reg) == PPICTRL? PPIGCTRL: PPIGSTATUS, \ + (valp))) -#endif /* freebsd_ppi_h */ +#define DO_PPI_WRITE(fd, reg, valp) ((void) ioctl((fd), \ + (reg) == PPIDATA? PPISDATA: (reg) == PPICTRL? PPISCTRL: PPISSTATUS, \ + (valp))) + +#endif diff --git a/src/ft245r.c b/src/ft245r.c index 8b517b15a..d7e320778 100644 --- a/src/ft245r.c +++ b/src/ft245r.c @@ -1,5 +1,5 @@ /* - * AVRDUDE - A Downloader/Uploader for AVR device programmers + * avrdude - A Downloader/Uploader for AVR device programmers * Copyright (C) 2003-2004 Theodore A. Roth * some code: * Copyright (C) 2011-2012 Roger E. Wolff @@ -18,35 +18,33 @@ * along with this program. If not, see . */ - /* ft245r -- FT245R/FT232R Synchronous BitBangMode Programmer default pin assign - FT232R / FT245R - sdi = 1; # RxD / D1 - sck = 0; # RTS / D0 - sdo = 2; # TxD / D2 - reset = 4; # DTR / D4 + FT232R/FT245R + sdi = 1; # RxD /D1 + sck = 0; # RTS /D0 + sdo = 2; # TxD /D2 + reset = 4; # DTR /D4 */ /* - The ft232r is very similar, or even "identical" in the synchronous - bitbang mode that we use here. - - This allows boards that have an ft232r for communication and an avr - as the processor to function as their own "ICSP". Boards that fit - this description include the Arduino Duemilanove, Arduino Diecimila, - Arduino NG (http://arduino.cc/it/main/boards) and the BitWizard - ftdi_atmega board (http://www.bitwizard.nl/wiki/index.php/FTDI_ATmega) - - The Arduinos have to be patched to bring some of the control lines - to the ICSP header. The BitWizard board already has the neccessary - wiring on the PCB. - - How to add the wires to an arduino is documented here: - http://www.geocities.jp/arduino_diecimila/bootloader/index_en.html + * The ft232r is very similar, or even "identical" in the synchronous + * bitbang mode that we use here. + * + * This allows boards that have an ft232r for communication and an avr as the + * processor to function as their own "ICSP". Boards that fit this description + * include the Arduino Duemilanove, Arduino Diecimila, Arduino NG + * (http://arduino.cc/it/main/boards) and the BitWizard ftdi_atmega board + * (http://www.bitwizard.nl/wiki/index.php/FTDI_ATmega) + * + * The Arduinos have to be patched to bring some of the control lines to the + * ICSP header. The BitWizard board already has the neccessary wiring on the + * PCB. + * + * How to add the wires to an arduino is documented here: + * http://www.geocities.jp/arduino_diecimila/bootloader/index_en.html */ - #include #include @@ -67,88 +65,93 @@ #include "tpi.h" -#define TPIPCR_GT_0b 0x07 -#define TPI_STOP_BITS 0x03 +#define TPIPCR_GT_0b 0x07 +#define TPI_STOP_BITS 0x03 #if defined(HAVE_LIBFTDI1) && defined(HAVE_LIBUSB_1_0) -# if defined(HAVE_LIBUSB_1_0_LIBUSB_H) -# include -# else -# include -# endif -# include + +#if defined(HAVE_LIBUSB_1_0_LIBUSB_H) +#include +#else +#include +#endif + +#include #elif defined(HAVE_LIBFTDI) #include -#else +#else + #ifdef _MSC_VER #pragma message("No libftdi or libusb support. Install libftdi1/libusb-1.0 or libftdi/libusb and run configure/make again.") #else #warning No libftdi or libusb support. Install libftdi1/libusb-1.0 or libftdi/libusb and run configure/make again. #endif + #define DO_NOT_BUILD_FT245R #endif #if defined(DO_NOT_BUILD_FT245R) - static int ft245r_noftdi_open(PROGRAMMER *pgm, const char *name) { - pmsg_error("no libftdi or libusb support; install libftdi1/libusb-1.0 or libftdi/libusb and run configure/make\n"); + pmsg_error("no libftdi or libusb support; install libftdi1/libusb-1.0 or libftdi/libusb and run configure/make\n"); - return -1; + return -1; } void ft245r_initpgm(PROGRAMMER *pgm) { - strcpy(pgm->type, "ftdi_syncbb"); - pgm->open = ft245r_noftdi_open; + strcpy(pgm->type, "ftdi_syncbb"); + pgm->open = ft245r_noftdi_open; } #else -#define FT245R_CYCLES 2 -#define FT245R_CMD_SIZE (4 * 8*FT245R_CYCLES) -#define FT245R_FRAGMENT_SIZE (8 * FT245R_CMD_SIZE) -#define REQ_OUTSTANDINGS 10 - -#define FT245R_DEBUG 0 -/* - Some revisions of the FTDI chips mess up the timing in bitbang mode - unless the bitclock is set to the max (3MHz). For example, see: - - http://www.ftdichip.com/Support/Documents/TechnicalNotes/TN_120_FT232R%20Errata%20Technical%20Note.pdf +#define FT245R_CYCLES 2 +#define FT245R_CMD_SIZE (4*8*FT245R_CYCLES) +#define FT245R_FRAGMENT_SIZE (8*FT245R_CMD_SIZE) +#define REQ_OUTSTANDINGS 10 - To work around this problem, set the macro below to 1 to always set - the bitclock to 3MHz and then issue the same byte repeatedly to get - the desired timing. +#define FT245R_DEBUG 0 +/* + * Some revisions of the FTDI chips mess up the timing in bitbang mode unless + * the bitclock is set to the max (3MHz). For example, see: + * + * http://www.ftdichip.com/Support/Documents/TechnicalNotes/TN_120_FT232R%20Errata%20Technical%20Note.pdf + * + * To work around this problem, set the macro below to 1 to always set the + * bitclock to 3MHz and then issue the same byte repeatedly to get the desired + * timing. + * */ #define FT245R_BITBANG_VARIABLE_PULSE_WIDTH_WORKAROUND 0 - // Private data for this programmer -#define FT245R_BUFSIZE 0x2000 // receive buffer size -#define FT245R_MIN_FIFO_SIZE 128 // min of FTDI RX/TX FIFO size +#define FT245R_BUFSIZE 0x2000 // Receive buffer size +#define FT245R_MIN_FIFO_SIZE 128 // Min of FTDI RX/TX FIFO size struct pdata { struct ftdi_context *handle; + #if FT245R_BITBANG_VARIABLE_PULSE_WIDTH_WORKAROUND int baud_mult; -# define baud_multiplier my.baud_mult +#define baud_multiplier my.baud_mult #else -# define baud_multiplier 1 // Optimised by C compiler +#define baud_multiplier 1 // Optimised by C compiler #endif + unsigned char ft245r_ddr; unsigned char ft245r_out; struct { - int len; // # of bytes in transmit buffer - uint8_t buf[FT245R_MIN_FIFO_SIZE]; // Transmit buffer + int len; // # of bytes in transmit buffer + uint8_t buf[FT245R_MIN_FIFO_SIZE]; // Transmit buffer } tx; struct { - int discard; // # of bytes to discard during read - int pending; // # of bytes that have been written since last read - int len; // # of bytes in receive buffer - int wr; // Write pointer - int rd; // Read pointer - uint8_t buf[FT245R_BUFSIZE]; // Receive ring buffer + int discard; // # of bytes to discard during read + int pending; // # of bytes that have been written since last read + int len; // # of bytes in receive buffer + int wr; // Write pointer + int rd; // Read pointer + uint8_t buf[FT245R_BUFSIZE]; // Receive ring buffer } rx; struct ft245r_request { int addr; @@ -167,219 +170,217 @@ static int ft245r_tpi_rx(const PROGRAMMER *pgm, uint8_t *bytep); // Discard all data from the receive buffer. static void ft245r_rx_buf_purge(const PROGRAMMER *pgm) { - my.rx.len = 0; - my.rx.rd = my.rx.wr = 0; + my.rx.len = 0; + my.rx.rd = my.rx.wr = 0; } static void ft245r_rx_buf_put(const PROGRAMMER *pgm, uint8_t byte) { - my.rx.len++; - my.rx.buf[my.rx.wr++] = byte; - if (my.rx.wr >= (int) sizeof(my.rx.buf)) - my.rx.wr = 0; + my.rx.len++; + my.rx.buf[my.rx.wr++] = byte; + if(my.rx.wr >= (int) sizeof(my.rx.buf)) + my.rx.wr = 0; } static uint8_t ft245r_rx_buf_get(const PROGRAMMER *pgm) { - my.rx.len--; - uint8_t byte = my.rx.buf[my.rx.rd++]; - if (my.rx.rd >= (int) sizeof(my.rx.buf)) - my.rx.rd = 0; - return byte; + my.rx.len--; + uint8_t byte = my.rx.buf[my.rx.rd++]; + + if(my.rx.rd >= (int) sizeof(my.rx.buf)) + my.rx.rd = 0; + return byte; } -/* Fill receive buffer with data from the FTDI receive FIFO. */ +// Fill receive buffer with data from the FTDI receive FIFO static int ft245r_fill(const PROGRAMMER *pgm) { - uint8_t raw[FT245R_MIN_FIFO_SIZE]; - int i, nread; + uint8_t raw[FT245R_MIN_FIFO_SIZE]; + int i, nread; + + nread = ftdi_read_data(my.handle, raw, my.rx.pending); + if(nread < 0) + return -1; + my.rx.pending -= nread; - nread = ftdi_read_data(my.handle, raw, my.rx.pending); - if (nread < 0) - return -1; - my.rx.pending -= nread; #if FT245R_DEBUG - msg_info("%s: read %d bytes (pending=%d)\n", __func__, nread, my.rx.pending); + msg_info("%s: read %d bytes (pending=%d)\n", __func__, nread, my.rx.pending); #endif - for (i = 0; i < nread; ++i) - ft245r_rx_buf_put(pgm, raw[i]); - return nread; + + for(i = 0; i < nread; ++i) + ft245r_rx_buf_put(pgm, raw[i]); + return nread; } static int ft245r_rx_buf_fill_and_get(const PROGRAMMER *pgm) { - while(my.rx.len == 0) { - int result = ft245r_fill(pgm); - if(result < 0) - return result; - } + while(my.rx.len == 0) { + int result = ft245r_fill(pgm); + + if(result < 0) + return result; + } - return ft245r_rx_buf_get(pgm); + return ft245r_rx_buf_get(pgm); } -/* Flush pending TX data to the FTDI send FIFO. */ +// Flush pending TX data to the FTDI send FIFO static int ft245r_flush(const PROGRAMMER *pgm) { - int rv, len = my.tx.len, avail; - uint8_t *src = my.tx.buf; - - if (!len) - return 0; - - while (len > 0) { - avail = FT245R_MIN_FIFO_SIZE - my.rx.pending; - if (avail <= 0) { - avail = ft245r_fill(pgm); - if (avail < 0) { - pmsg_error("fill returned %d: %s\n", avail, ftdi_get_error_string(my.handle)); - return -1; - } - } - if (avail > len) - avail = len; + int rv, len = my.tx.len, avail; + uint8_t *src = my.tx.buf; + + if(!len) + return 0; + + while(len > 0) { + avail = FT245R_MIN_FIFO_SIZE - my.rx.pending; + if(avail <= 0) { + avail = ft245r_fill(pgm); + if(avail < 0) { + pmsg_error("fill returned %d: %s\n", avail, ftdi_get_error_string(my.handle)); + return -1; + } + } + if(avail > len) + avail = len; #if FT245R_DEBUG - msg_notice("%s: writing %d bytes\n", __func__, avail); + msg_notice("%s: writing %d bytes\n", __func__, avail); #endif - rv = ftdi_write_data(my.handle, src, avail); - if (rv != avail) { - msg_error("write returned %d (expected %d): %s\n", rv, avail, ftdi_get_error_string(my.handle)); - return -1; - } - src += avail; - len -= avail; - my.rx.pending += avail; + + rv = ftdi_write_data(my.handle, src, avail); + if(rv != avail) { + msg_error("write returned %d (expected %d): %s\n", rv, avail, ftdi_get_error_string(my.handle)); + return -1; } - my.tx.len = 0; - return 0; + src += avail; + len -= avail; + my.rx.pending += avail; + } + my.tx.len = 0; + return 0; } -static int ft245r_send2(const PROGRAMMER *pgm, unsigned char *buf, size_t len, - bool discard_rx_data) { - for (size_t i = 0; i < len; ++i) { - for (int j = 0; j < baud_multiplier; ++j) { - if (discard_rx_data) - ++my.rx.discard; - my.tx.buf[my.tx.len++] = buf[i]; - if (my.tx.len >= FT245R_MIN_FIFO_SIZE) - ft245r_flush(pgm); - } +static int ft245r_send2(const PROGRAMMER *pgm, unsigned char *buf, size_t len, bool discard_rx_data) { + for(size_t i = 0; i < len; ++i) { + for(int j = 0; j < baud_multiplier; ++j) { + if(discard_rx_data) + ++my.rx.discard; + my.tx.buf[my.tx.len++] = buf[i]; + if(my.tx.len >= FT245R_MIN_FIFO_SIZE) + ft245r_flush(pgm); } - return 0; + } + return 0; } static int ft245r_send(const PROGRAMMER *pgm, unsigned char *buf, size_t len) { - return ft245r_send2(pgm, buf, len, false); + return ft245r_send2(pgm, buf, len, false); } -static int ft245r_send_and_discard(const PROGRAMMER *pgm, unsigned char *buf, - size_t len) { - return ft245r_send2(pgm, buf, len, true); +static int ft245r_send_and_discard(const PROGRAMMER *pgm, unsigned char *buf, size_t len) { + return ft245r_send2(pgm, buf, len, true); } static int ft245r_recv(const PROGRAMMER *pgm, unsigned char *buf, size_t len) { - ft245r_flush(pgm); - ft245r_fill(pgm); + ft245r_flush(pgm); + ft245r_fill(pgm); #if FT245R_DEBUG - msg_notice("%s: discarding %d, consuming %lu bytes\n", __func__, my.rx.discard, (unsigned long) len); + msg_notice("%s: discarding %d, consuming %lu bytes\n", __func__, my.rx.discard, (unsigned long) len); #endif - while (my.rx.discard > 0) { - int result = ft245r_rx_buf_fill_and_get(pgm); - if (result < 0) - { - return result; - } - - --my.rx.discard; + + while(my.rx.discard > 0) { + int result = ft245r_rx_buf_fill_and_get(pgm); + + if(result < 0) { + return result; } - for (size_t i = 0; i < len; ++i) - { - int result = ft245r_rx_buf_fill_and_get(pgm); - if (result < 0) - { - return result; - } - - buf[i] = (uint8_t)result; - for (int j = 1; j < baud_multiplier; ++j) - { - result = ft245r_rx_buf_fill_and_get(pgm); - if (result < 0) - { - return result; - } - } + --my.rx.discard; + } + + for(size_t i = 0; i < len; ++i) { + int result = ft245r_rx_buf_fill_and_get(pgm); + + if(result < 0) { + return result; } - return 0; -} + buf[i] = (uint8_t) result; + for(int j = 1; j < baud_multiplier; ++j) { + result = ft245r_rx_buf_fill_and_get(pgm); + if(result < 0) { + return result; + } + } + } + return 0; +} static int ft245r_drain(const PROGRAMMER *pgm, int display) { - int r; + int r; - // flush the buffer in the chip by changing the mode ... - r = ftdi_set_bitmode(my.handle, 0, BITMODE_RESET); // reset - if (r) return -1; - r = ftdi_set_bitmode(my.handle, my.ft245r_ddr, BITMODE_SYNCBB); // set Synchronuse BitBang - if (r) return -1; + // Flush the buffer in the chip by changing the mode ... + r = ftdi_set_bitmode(my.handle, 0, BITMODE_RESET); // Reset + if(r) + return -1; + r = ftdi_set_bitmode(my.handle, my.ft245r_ddr, BITMODE_SYNCBB); // Set synchronous bitbang + if(r) + return -1; - // drain our buffer. - ft245r_rx_buf_purge(pgm); - return 0; + // Drain our buffer + ft245r_rx_buf_purge(pgm); + return 0; } - -/* Ensure any pending writes are sent to the FTDI chip before sleeping. */ +// Ensure any pending writes are sent to the FTDI chip before sleeping static void ft245r_usleep(const PROGRAMMER *pgm, useconds_t usec) { - ft245r_flush(pgm); - usleep(usec); + ft245r_flush(pgm); + usleep(usec); } - static int ft245r_chip_erase(const PROGRAMMER *pgm, const AVRPART *p) { - unsigned char cmd[4] = {0, 0, 0, 0}; - unsigned char res[4]; + unsigned char cmd[4] = { 0, 0, 0, 0 }; + unsigned char res[4]; - if (p->prog_modes & PM_TPI) - return avr_tpi_chip_erase(pgm, p); + if(is_tpi(p)) + return avr_tpi_chip_erase(pgm, p); - if (p->op[AVR_OP_CHIP_ERASE] == NULL) { - msg_error("chip erase instruction not defined for part %s\n", p->desc); - return -1; - } + if(p->op[AVR_OP_CHIP_ERASE] == NULL) { + msg_error("chip erase instruction not defined for part %s\n", p->desc); + return -1; + } - avr_set_bits(p->op[AVR_OP_CHIP_ERASE], cmd); - pgm->cmd(pgm, cmd, res); - ft245r_usleep(pgm, p->chip_erase_delay); - return pgm->initialize(pgm, p); + avr_set_bits(p->op[AVR_OP_CHIP_ERASE], cmd); + pgm->cmd(pgm, cmd, res); + ft245r_usleep(pgm, p->chip_erase_delay); + return pgm->initialize(pgm, p); } - static int ft245r_set_bitclock(const PROGRAMMER *pgm) { - // libftdi1 multiplies bitbang baudrate by 4: - int r, rate = 0, ftdi_rate = 3000000 / 4; - - /* bitclock is second. 1us = 0.000001. Max rate for ft232r 750000 */ - if(pgm->bitclock) { - rate = (uint32_t)(1.0/pgm->bitclock); - } else if (pgm->baudrate) { - rate = pgm->baudrate; - } else { - rate = 150000; /* should work for all ftdi chips and the avr default internal clock of 1MHz */ - } + // libftdi1 multiplies bitbang baudrate by 4: + int r, rate = 0, ftdi_rate = 3000000/4; + + // Bitclock is second; 1us = 0.000001; max rate for ft232r 750000 + if(pgm->bitclock) { + rate = (uint32_t) (1.0/pgm->bitclock); + } else if(pgm->baudrate) { + rate = pgm->baudrate; + } else { + rate = 150000; // Should work for all ftdi chips and the avr default internal clock of 1MHz + } #if FT245R_BITBANG_VARIABLE_PULSE_WIDTH_WORKAROUND - my.baud_mult = rate > 0 && rate < ftdi_rate? round((ftdi_rate + rate - 1) / rate): 1; + my.baud_mult = rate > 0 && rate < ftdi_rate? round((ftdi_rate + rate - 1)/rate): 1; #else - ftdi_rate = rate; + ftdi_rate = rate; #endif - msg_notice2("%s: bitclk %d -> FTDI rate %d, baud multiplier %d\n", - __func__, rate, ftdi_rate, baud_multiplier); + msg_notice2("%s: bitclk %d -> FTDI rate %d, baud multiplier %d\n", __func__, rate, ftdi_rate, baud_multiplier); - r = ftdi_set_baudrate(my.handle, ftdi_rate); - if (r) { - msg_error("setting baudrate %d failed with error %s\n", rate, ftdi_get_error_string (my.handle)); - return -1; - } - return 0; + r = ftdi_set_baudrate(my.handle, ftdi_rate); + if(r) { + msg_error("setting baudrate %d failed with error %s\n", rate, ftdi_get_error_string(my.handle)); + return -1; + } + return 0; } static int get_pin(const PROGRAMMER *pgm, int pinname) { @@ -387,811 +388,798 @@ static int get_pin(const PROGRAMMER *pgm, int pinname) { ft245r_flush(pgm); - if (ftdi_read_pins(my.handle, &byte) != 0) + if(ftdi_read_pins(my.handle, &byte) != 0) return -1; - if (FT245R_DEBUG) + if(FT245R_DEBUG) msg_notice("%s: in 0x%02x\n", __func__, byte); return GET_BITS_0(byte, pgm, pinname) != 0; } static int set_pin(const PROGRAMMER *pgm, int pinname, int val) { - unsigned char buf[1]; + unsigned char buf[1]; - if (pgm->pin[pinname].mask[0] == 0) { - // ignore not defined pins (might be the led or vcc or buff if not needed) - return 0; - } + if(pgm->pin[pinname].mask[0] == 0) { + // Ignore not defined pins (might be the led or vcc or buff if not needed) + return 0; + } - my.ft245r_out = SET_BITS_0(my.ft245r_out, pgm, pinname, val); - buf[0] = my.ft245r_out; + my.ft245r_out = SET_BITS_0(my.ft245r_out, pgm, pinname, val); + buf[0] = my.ft245r_out; - ft245r_send_and_discard(pgm, buf, 1); - return 0; + ft245r_send_and_discard(pgm, buf, 1); + return 0; } static int set_sck(const PROGRAMMER *pgm, int value) { - return set_pin(pgm, PIN_AVR_SCK, value); + return set_pin(pgm, PIN_AVR_SCK, value); } static int set_reset(const PROGRAMMER *pgm, int value) { - return set_pin(pgm, PIN_AVR_RESET, value); + return set_pin(pgm, PIN_AVR_RESET, value); } static int set_buff(const PROGRAMMER *pgm, int value) { - return set_pin(pgm, PPI_AVR_BUFF, value); + return set_pin(pgm, PPI_AVR_BUFF, value); } static int set_vcc(const PROGRAMMER *pgm, int value) { - return set_pin(pgm, PPI_AVR_VCC, value); + return set_pin(pgm, PPI_AVR_VCC, value); } /* these functions are callbacks, which go into the * PROGRAMMER data structure ("optional functions") */ static int ft245_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 ft245_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 ft245_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 ft245_vfy_led(const PROGRAMMER *pgm, int value) { - return set_pin(pgm, PIN_LED_VFY, value); + return set_pin(pgm, PIN_LED_VFY, value); } -/* - * apply power to the AVR processor - */ +// Apply power to the AVR processor static void ft245r_powerup(const PROGRAMMER *pgm) { - set_vcc(pgm, ON); /* power up */ - ft245r_usleep(pgm, 100); + set_vcc(pgm, ON); // Power up + ft245r_usleep(pgm, 100); } - -/* - * remove power from the AVR processor - */ +// Remove power from the AVR processor static void ft245r_powerdown(const PROGRAMMER *pgm) { - set_vcc(pgm, OFF); /* power down */ + set_vcc(pgm, OFF); // Power down } - static void ft245r_disable(const PROGRAMMER *pgm) { - set_buff(pgm, OFF); + set_buff(pgm, OFF); } - static void ft245r_enable(PROGRAMMER *pgm, const AVRPART *p) { /* - * Prepare to start talking to the connected device - pull reset low - * first, delay a few milliseconds, then enable the buffer. This - * sequence allows the AVR to be reset before the buffer is enabled - * to avoid a short period of time where the AVR may be driving the - * programming lines at the same time the programmer tries to. Of - * course, if a buffer is being used, then the /RESET line from the - * programmer needs to be directly connected to the AVR /RESET line - * and not via the buffer chip. + * Prepare to start talking to the connected device - pull reset low first, + * delay a few milliseconds, then enable the buffer. This sequence allows + * the AVR to be reset before the buffer is enabled to avoid a short period + * of time where the AVR may be driving the programming lines at the same + * time the programmer tries to. Of course, if a buffer is being used, then + * the /RESET line from the programmer needs to be directly connected to the + * AVR /RESET line and not via the buffer chip. */ - set_reset(pgm, OFF); - ft245r_usleep(pgm, 1); - set_buff(pgm, ON); + set_reset(pgm, OFF); + ft245r_usleep(pgm, 1); + set_buff(pgm, ON); } -/* - * issue the 'program enable' command to the AVR device - */ +// Issue the 'program enable' command to the AVR device static int ft245r_program_enable(const PROGRAMMER *pgm, const AVRPART *p) { - unsigned char cmd[4] = {0, 0, 0, 0}; - unsigned char res[4]; - int i; + unsigned char cmd[4] = { 0, 0, 0, 0 }; + unsigned char res[4]; + int i; - if (p->prog_modes & PM_TPI) - return avr_tpi_program_enable(pgm, p, TPIPCR_GT_0b); + if(is_tpi(p)) + return avr_tpi_program_enable(pgm, p, TPIPCR_GT_0b); - if (p->op[AVR_OP_PGM_ENABLE] == NULL) { - pmsg_error("AVR_OP_PGM_ENABLE command not defined for %s\n", p->desc); - fflush(stderr); - return -1; - } + if(p->op[AVR_OP_PGM_ENABLE] == NULL) { + pmsg_error("AVR_OP_PGM_ENABLE command not defined for %s\n", p->desc); + fflush(stderr); + return -1; + } - avr_set_bits(p->op[AVR_OP_PGM_ENABLE], cmd); + avr_set_bits(p->op[AVR_OP_PGM_ENABLE], cmd); - for(i = 0; i < 4; i++) { - ft245r_cmd(pgm, cmd, res); + for(i = 0; i < 4; i++) { + ft245r_cmd(pgm, cmd, res); - if (res[p->pollindex-1] == p->pollvalue) return 0; + if(res[p->pollindex - 1] == p->pollvalue) + return 0; - if (FT245R_DEBUG) { - pmsg_notice("program enable command not successful, retrying\n"); - fflush(stderr); - } - set_pin(pgm, PIN_AVR_RESET, ON); - ft245r_usleep(pgm, 20); - set_pin(pgm, PIN_AVR_RESET, OFF); + if(FT245R_DEBUG) { + pmsg_notice("program enable command not successful, retrying\n"); + fflush(stderr); + } + set_pin(pgm, PIN_AVR_RESET, ON); + ft245r_usleep(pgm, 20); + set_pin(pgm, PIN_AVR_RESET, OFF); - if (i == 3) { - ft245r_drain(pgm, 0); - ft245r_rx_buf_purge(pgm); - } + if(i == 3) { + ft245r_drain(pgm, 0); + ft245r_rx_buf_purge(pgm); } + } - pmsg_error("device is not responding to program enable; check connection\n"); - fflush(stderr); + pmsg_error("device is not responding to program enable; check connection\n"); + fflush(stderr); - return -1; + return -1; } -/* - * initialize the AVR device and prepare it to accept commands - */ +// Initialize the AVR device and prepare it to accept commands static int ft245r_initialize(const PROGRAMMER *pgm, const AVRPART *p) { - /* Apply power between VCC and GND while RESET and SCK are set to “0”. In some systems, - * the programmer can not guarantee that SCK is held low during power-up. In this - * case, RESET must be given a positive pulse of at least two CPU clock cycles duration - * after SCK has been set to “0”. - */ - set_sck(pgm, OFF); - ft245r_powerup(pgm); + /* Apply power between VCC and GND while RESET and SCK are set to “0”. In some systems, + * the programmer can not guarantee that SCK is held low during power-up. In this + * case, RESET must be given a positive pulse of at least two CPU clock cycles duration + * after SCK has been set to “0”. + */ + set_sck(pgm, OFF); + ft245r_powerup(pgm); + + set_reset(pgm, OFF); + ft245r_usleep(pgm, 5000); // 5ms + set_reset(pgm, ON); + ft245r_usleep(pgm, 5000); // 5ms + set_reset(pgm, OFF); + + /* Wait for at least 20 ms and enable serial programming by sending the Programming + * Enable serial instruction to pin SDO. + */ + ft245r_usleep(pgm, 20000); // 20ms - set_reset(pgm, OFF); - ft245r_usleep(pgm, 5000); // 5ms - set_reset(pgm, ON); - ft245r_usleep(pgm, 5000); // 5ms - set_reset(pgm, OFF); + if(is_tpi(p)) { + bool io_link_ok = true; + uint8_t byte; + int i; - /* Wait for at least 20 ms and enable serial programming by sending the Programming - * Enable serial instruction to pin SDO. + /* + * Since there is a single TPIDATA line, SDO and SDI must be linked + * together through a 1kOhm resistor. Verify that everything we send on + * SDO gets mirrored back on SDI. */ - ft245r_usleep(pgm, 20000); // 20ms - - if (p->prog_modes & PM_TPI) { - bool io_link_ok = true; - uint8_t byte; - int i; - - /* Since there is a single TPIDATA line, SDO and SDI must be - linked together through a 1kOhm resistor. Verify that - everything we send on SDO gets mirrored back on SDI. */ - set_pin(pgm, PIN_AVR_SDO, 0); - if (get_pin(pgm, PIN_AVR_SDI) != 0) { - io_link_ok = false; - if(ovsigck) { - pmsg_warning("SDO->SDI 0 failed\n"); - } else { - pmsg_error("SDO->SDI 0 failed\n"); - return -1; - } - } - set_pin(pgm, PIN_AVR_SDO, 1); - if (get_pin(pgm, PIN_AVR_SDI) != 1) { - io_link_ok = false; - if(ovsigck) { - pmsg_warning("SDO->SDI 1 failed\n"); - } else { - pmsg_error("SDO->SDI 1 failed\n"); - return -1; - } - } - - if (io_link_ok) - msg_notice2("SDO-SDI link present\n"); - - /* keep TPIDATA high for 16 clock cycles */ - set_pin(pgm, PIN_AVR_SDO, 1); - for (i = 0; i < 16; i++) { - set_sck(pgm, 1); - set_sck(pgm, 0); - } - - /* remove extra guard timing bits */ - ft245r_tpi_tx(pgm, TPI_CMD_SSTCS | TPI_REG_TPIPCR); - ft245r_tpi_tx(pgm, 0x7); - - /* read TPI ident reg */ - ft245r_tpi_tx(pgm, TPI_CMD_SLDCS | TPI_REG_TPIIR); - ft245r_tpi_rx(pgm, &byte); - if (byte != 0x80) { - msg_error("TPIIR 0x%02x not correct\n", byte); - return -1; - } + set_pin(pgm, PIN_AVR_SDO, 0); + if(get_pin(pgm, PIN_AVR_SDI) != 0) { + io_link_ok = false; + if(ovsigck) { + pmsg_warning("SDO->SDI 0 failed\n"); + } else { + pmsg_error("SDO->SDI 0 failed\n"); + return -1; + } + } + set_pin(pgm, PIN_AVR_SDO, 1); + if(get_pin(pgm, PIN_AVR_SDI) != 1) { + io_link_ok = false; + if(ovsigck) { + pmsg_warning("SDO->SDI 1 failed\n"); + } else { + pmsg_error("SDO->SDI 1 failed\n"); + return -1; + } + } + + if(io_link_ok) + msg_notice2("SDO-SDI link present\n"); + + // Keep TPIDATA high for 16 clock cycles + set_pin(pgm, PIN_AVR_SDO, 1); + for(i = 0; i < 16; i++) { + set_sck(pgm, 1); + set_sck(pgm, 0); + } + + // Remove extra guard timing bits + ft245r_tpi_tx(pgm, TPI_CMD_SSTCS | TPI_REG_TPIPCR); + ft245r_tpi_tx(pgm, 0x7); + + // Read TPI ident reg + ft245r_tpi_tx(pgm, TPI_CMD_SLDCS | TPI_REG_TPIIR); + ft245r_tpi_rx(pgm, &byte); + if(byte != 0x80) { + msg_error("TPIIR 0x%02x not correct\n", byte); + return -1; } - return ft245r_program_enable(pgm, p); + } + return ft245r_program_enable(pgm, p); } static inline void add_bit(const PROGRAMMER *pgm, unsigned char *buf, int *buf_pos, uint8_t bit) { - my.ft245r_out = SET_BITS_0(my.ft245r_out, pgm, PIN_AVR_SDO, bit); - my.ft245r_out = SET_BITS_0(my.ft245r_out, pgm, PIN_AVR_SCK, 0); - buf[*buf_pos] = my.ft245r_out; - (*buf_pos)++; - - my.ft245r_out = SET_BITS_0(my.ft245r_out, pgm, PIN_AVR_SCK, 1); - buf[*buf_pos] = my.ft245r_out; - (*buf_pos)++; + my.ft245r_out = SET_BITS_0(my.ft245r_out, pgm, PIN_AVR_SDO, bit); + my.ft245r_out = SET_BITS_0(my.ft245r_out, pgm, PIN_AVR_SCK, 0); + buf[*buf_pos] = my.ft245r_out; + (*buf_pos)++; + + my.ft245r_out = SET_BITS_0(my.ft245r_out, pgm, PIN_AVR_SCK, 1); + buf[*buf_pos] = my.ft245r_out; + (*buf_pos)++; } static inline int set_data(const PROGRAMMER *pgm, unsigned char *buf, unsigned char data) { - int j; - int buf_pos = 0; - unsigned char bit = 0x80; + int j; + int buf_pos = 0; + unsigned char bit = 0x80; - for (j=0; j<8; j++) { - add_bit(pgm, buf, &buf_pos, (data & bit) != 0); - bit >>= 1; - } - return buf_pos; + for(j = 0; j < 8; j++) { + add_bit(pgm, buf, &buf_pos, (data & bit) != 0); + bit >>= 1; + } + return buf_pos; } static inline unsigned char extract_data(const PROGRAMMER *pgm, unsigned char *buf, int offset) { - int j; - int buf_pos = FT245R_CYCLES; /* SDI data is valid AFTER rising SCK edge, - i.e. in next clock cycle */ - unsigned char bit = 0x80; - unsigned char r = 0; - - buf += offset * (8 * FT245R_CYCLES); - for (j=0; j<8; j++) { - if (GET_BITS_0(buf[buf_pos], pgm, PIN_AVR_SDI)) { - r |= bit; - } - buf_pos += FT245R_CYCLES; - bit >>= 1; + int j; + int buf_pos = FT245R_CYCLES; /* SDI data is valid AFTER rising SCK edge, + i.e. in next clock cycle */ + unsigned char bit = 0x80; + unsigned char r = 0; + + buf += offset*(8*FT245R_CYCLES); + for(j = 0; j < 8; j++) { + if(GET_BITS_0(buf[buf_pos], pgm, PIN_AVR_SDI)) { + r |= bit; } - return r; + buf_pos += FT245R_CYCLES; + bit >>= 1; + } + return r; } -/* to check data */ +// To check data + #if 0 static inline unsigned char extract_data_out(const PROGRAMMER *pgm, unsigned char *buf, int offset) { - int j; - int buf_pos = 1; - unsigned char bit = 0x80; - unsigned char r = 0; - - buf += offset * (8 * FT245R_CYCLES); - for (j=0; j<8; j++) { - if (GET_BITS_0(buf[buf_pos], pgm, PIN_AVR_SDO)) { - r |= bit; - } - buf_pos += FT245R_CYCLES; - bit >>= 1; + int j; + int buf_pos = 1; + unsigned char bit = 0x80; + unsigned char r = 0; + + buf += offset*(8*FT245R_CYCLES); + for(j = 0; j < 8; j++) { + if(GET_BITS_0(buf[buf_pos], pgm, PIN_AVR_SDO)) { + r |= bit; } - return r; + buf_pos += FT245R_CYCLES; + bit >>= 1; + } + return r; } #endif - /* - * transmit an AVR device command and return the results; 'cmd' and - * 'res' must point to at least a 4 byte data buffer + * Transmit an AVR device command and return the results; 'cmd' and 'res' must + * point to at least a 4 byte data buffer */ static int ft245r_cmd(const PROGRAMMER *pgm, const unsigned char *cmd, unsigned char *res) { - int i, buf_pos; - unsigned char buf[128]; + int i, buf_pos; + unsigned char buf[128]; - buf_pos = 0; - for (i=0; i<4; i++) { - buf_pos += set_data(pgm, buf+buf_pos, cmd[i]); - } - buf[buf_pos] = 0; - buf_pos++; + buf_pos = 0; + for(i = 0; i < 4; i++) { + buf_pos += set_data(pgm, buf + buf_pos, cmd[i]); + } + buf[buf_pos] = 0; + buf_pos++; - ft245r_send (pgm, buf, buf_pos); - ft245r_recv (pgm, buf, buf_pos); - res[0] = extract_data(pgm, buf, 0); - res[1] = extract_data(pgm, buf, 1); - res[2] = extract_data(pgm, buf, 2); - res[3] = extract_data(pgm, buf, 3); + ft245r_send(pgm, buf, buf_pos); + ft245r_recv(pgm, buf, buf_pos); + res[0] = extract_data(pgm, buf, 0); + res[1] = extract_data(pgm, buf, 1); + res[2] = extract_data(pgm, buf, 2); + res[3] = extract_data(pgm, buf, 3); - return 0; + return 0; } static inline uint8_t extract_tpi_data(const PROGRAMMER *pgm, unsigned char *buf, int *buf_pos) { - uint8_t bit = 0x1, byte = 0; - int j; - - for (j = 0; j < 8; j++) { - (*buf_pos)++; // skip over falling clock edge - if (GET_BITS_0(buf[(*buf_pos)++], pgm, PIN_AVR_SDI)) - byte |= bit; - bit <<= 1; - } - return byte; + uint8_t bit = 0x1, byte = 0; + int j; + + for(j = 0; j < 8; j++) { + (*buf_pos)++; // Skip over falling clock edge + if(GET_BITS_0(buf[(*buf_pos)++], pgm, PIN_AVR_SDI)) + byte |= bit; + bit <<= 1; + } + return byte; } static inline int set_tpi_data(const PROGRAMMER *pgm, unsigned char *buf, uint8_t byte) { - uint8_t bit = 0x1, parity = 0; - int j, buf_pos = 0; + uint8_t bit = 0x1, parity = 0; + int j, buf_pos = 0; - // start bit: - add_bit(pgm, buf, &buf_pos, 0); + // Start bit + add_bit(pgm, buf, &buf_pos, 0); - // 8 data bits: - for (j = 0; j < 8; j++) { - add_bit(pgm, buf, &buf_pos, (byte & bit) != 0); - parity ^= (byte & bit) != 0; - bit <<= 1; - } + // 8 data bits: + for(j = 0; j < 8; j++) { + add_bit(pgm, buf, &buf_pos, (byte & bit) != 0); + parity ^= (byte & bit) != 0; + bit <<= 1; + } - // parity bit: - add_bit(pgm, buf, &buf_pos, parity); - // stop bits: - add_bit(pgm, buf, &buf_pos, 1); - add_bit(pgm, buf, &buf_pos, 1); - return buf_pos; + // Parity bit + add_bit(pgm, buf, &buf_pos, parity); + // Stop bits + add_bit(pgm, buf, &buf_pos, 1); + add_bit(pgm, buf, &buf_pos, 1); + return buf_pos; } static int ft245r_tpi_tx(const PROGRAMMER *pgm, uint8_t byte) { - uint8_t buf[128]; - int len; + uint8_t buf[128]; + int len; - len = set_tpi_data(pgm, buf, byte); - ft245r_send_and_discard(pgm, buf, len); - return 0; + len = set_tpi_data(pgm, buf, byte); + ft245r_send_and_discard(pgm, buf, len); + return 0; } static int ft245r_tpi_rx(const PROGRAMMER *pgm, uint8_t *bytep) { - uint8_t buf[128], bit, parity; - int i, buf_pos = 0, len = 0; - uint32_t res, m, byte; - - /* Allow for up to 4 bits before we must see start bit; during - that time, we must keep the SDO line high. */ - for (i = 0; i < 2; ++i) - len += set_data(pgm, &buf[len], 0xff); - - ft245r_send(pgm, buf, len); - ft245r_recv(pgm, buf, len); - - res = (extract_tpi_data(pgm, buf, &buf_pos) - | ((uint32_t) extract_tpi_data(pgm, buf, &buf_pos) << 8)); - - /* Look for start bit: */ - m = 0x1; - while (m & res) - m <<= 1; - if (m >= 0x10) { - pmsg_error("start bit missing (res=0x%04x)\n", res); - return -1; - } - byte = parity = 0; - for (i = 0; i < 8; ++i) { - m <<= 1; - bit = (res & m) != 0; - parity ^= bit; - byte |= bit << i; - } + uint8_t buf[128], bit, parity; + int i, buf_pos = 0, len = 0; + uint32_t res, m, byte; + + // Allow for up to 4 bits before we must see start bit; during that time, we must keep the SDO line high + for(i = 0; i < 2; ++i) + len += set_data(pgm, &buf[len], 0xff); + + ft245r_send(pgm, buf, len); + ft245r_recv(pgm, buf, len); + + res = (extract_tpi_data(pgm, buf, &buf_pos) + | ((uint32_t) extract_tpi_data(pgm, buf, &buf_pos) << 8)); + + // Look for start bit + m = 0x1; + while(m & res) m <<= 1; - if (((res & m) != 0) != parity) { - pmsg_error("parity bit wrong\n"); - return -1; - } - if (((res & (m << 1)) == 0) || ((res & (m << 2))) == 0) { - pmsg_error("stop bits wrong\n"); - return -1; - } - *bytep = (uint8_t) byte; - return 0; + if(m >= 0x10) { + pmsg_error("start bit missing (res=0x%04x)\n", res); + return -1; + } + byte = parity = 0; + for(i = 0; i < 8; ++i) { + m <<= 1; + bit = (res & m) != 0; + parity ^= bit; + byte |= bit << i; + } + m <<= 1; + if(((res & m) != 0) != parity) { + pmsg_error("parity bit wrong\n"); + return -1; + } + if(((res & (m << 1)) == 0) || ((res & (m << 2))) == 0) { + pmsg_error("stop bits wrong\n"); + return -1; + } + *bytep = (uint8_t) byte; + return 0; } static int ft245r_cmd_tpi(const PROGRAMMER *pgm, const unsigned char *cmd, - int cmd_len, unsigned char *res, int res_len) { - int i, ret = 0; - - for (i = 0; i < cmd_len; ++i) - ft245r_tpi_tx(pgm, cmd[i]); - for (i = 0; i < res_len; ++i) - if ((ret = ft245r_tpi_rx(pgm, &res[i])) < 0) - break; - if (verbose >= MSG_DEBUG) { - msg_debug("%s: [ ", __func__); - for (i = 0; i < cmd_len; i++) - msg_debug("%02X ", cmd[i]); - msg_debug("] [ "); - for(i = 0; i < res_len; i++) - msg_debug("%02X ", res[i]); - msg_debug("]\n"); - } + int cmd_len, unsigned char *res, int res_len) { + + int i, ret = 0; + + for(i = 0; i < cmd_len; ++i) + ft245r_tpi_tx(pgm, cmd[i]); + for(i = 0; i < res_len; ++i) + if((ret = ft245r_tpi_rx(pgm, &res[i])) < 0) + break; + if(verbose >= MSG_DEBUG) { + msg_debug("%s: [ ", __func__); + for(i = 0; i < cmd_len; i++) + msg_debug("%02X ", cmd[i]); + msg_debug("] [ "); + for(i = 0; i < res_len; i++) + msg_debug("%02X ", res[i]); + msg_debug("]\n"); + } - return ret; + return ret; } -/* lower 8 pins are accepted, they might be also inverted */ -static const struct pindef valid_pins = {{0xff}, {0xff}}; +// Lower 8 pins are accepted, they might be also inverted +static const struct pindef valid_pins = { {0xff}, {0xff} }; static const Pin_checklist pin_checklist[] = { - { PIN_AVR_SCK, 1, &valid_pins}, - { PIN_AVR_SDO, 1, &valid_pins}, - { PIN_AVR_SDI, 1, &valid_pins}, - { PIN_AVR_RESET, 1, &valid_pins}, - { PPI_AVR_BUFF, 0, &valid_pins}, + {PIN_AVR_SCK, 1, &valid_pins}, + {PIN_AVR_SDO, 1, &valid_pins}, + {PIN_AVR_SDI, 1, &valid_pins}, + {PIN_AVR_RESET, 1, &valid_pins}, + {PPI_AVR_BUFF, 0, &valid_pins}, }; static int ft245r_open(PROGRAMMER *pgm, const char *port) { - int rv; - int devnum = -1; - char device[9] = ""; - - rv = pins_check(pgm, pin_checklist, sizeof(pin_checklist)/sizeof(pin_checklist[0]), true); + int rv; + int devnum = -1; + char device[9] = ""; - if(rv) { - pgm->display(pgm, progbuf); - return rv; - } + rv = pins_check(pgm, pin_checklist, sizeof(pin_checklist)/sizeof(pin_checklist[0]), true); - pgm->port = port; + if(rv) { + pgm->display(pgm, progbuf); + return rv; + } - // read device string cut after 8 chars (max. length of serial number) - if ((sscanf(port, "usb:%8s", device) != 1)) { - pmsg_notice("%s(): no device identifier in portname, using default\n", __func__); - pgm->usbsn = cache_string(""); + pgm->port = port; + + // Read device string cut after 8 chars (max. length of serial number) + if((sscanf(port, "usb:%8s", device) != 1)) { + pmsg_notice("%s(): no device identifier in portname, using default\n", __func__); + pgm->usbsn = cache_string(""); + devnum = 0; + } else { + if(strlen(device) == 8) { // Serial number + pmsg_notice2("%s(): serial number parsed as: %s\n", __func__, device); + // Copy serial number to pgm struct + pgm->usbsn = cache_string(device); + // and use first device with matching serial (should be unique) devnum = 0; - } else { - if (strlen(device) == 8 ){ // serial number - pmsg_notice2("%s(): serial number parsed as: %s\n", __func__, device); - // copy serial number to pgm struct - pgm->usbsn = cache_string(device); - // and use first device with matching serial (should be unique) - devnum = 0; - } - else if (strncmp("ft", device, 2) || strlen(device) <= 8) { // classic device number - char *startptr = device + 2; - char *endptr = NULL; - devnum = strtol(startptr, &endptr, 10); - if ((startptr==endptr) || (*endptr != '\0')) { - devnum = -1; - } - pmsg_notice2("%s(): device number parsed as: %d\n", __func__, devnum); + } else if(strncmp("ft", device, 2) || strlen(device) <= 8) { // Classic device number + char *startptr = device + 2; + char *endptr = NULL; + + devnum = strtol(startptr, &endptr, 10); + if((startptr == endptr) || (*endptr != '\0')) { + devnum = -1; } + pmsg_notice2("%s(): device number parsed as: %d\n", __func__, devnum); } + } - // if something went wrong before abort with helpful message - if (devnum < 0) { - pmsg_error("invalid port name %s: use ft[0-9]+ or serial number\n", port); - return -1; - } + // If something went wrong before abort with helpful message + if(devnum < 0) { + pmsg_error("invalid port name %s: use ft[0-9]+ or serial number\n", port); + return -1; + } - my.handle = mmt_malloc(sizeof (struct ftdi_context)); - ftdi_init(my.handle); - LNODEID usbpid = lfirst(pgm->usbpid); - int pid; - 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_FT245; - } - rv = ftdi_usb_open_desc_index(my.handle, - pgm->usbvid?pgm->usbvid:USB_VENDOR_FTDI, - pid, - pgm->usbproduct[0]?pgm->usbproduct:NULL, - pgm->usbsn[0]?pgm->usbsn:NULL, - devnum); - if (rv) { - pmsg_error("cannot open ftdi device: %s\n", ftdi_get_error_string(my.handle)); - goto cleanup_no_usb; - } + my.handle = mmt_malloc(sizeof(struct ftdi_context)); + ftdi_init(my.handle); + LNODEID usbpid = lfirst(pgm->usbpid); + int pid; + + 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_FT245; + } + rv = ftdi_usb_open_desc_index(my.handle, + pgm->usbvid? pgm->usbvid: USB_VENDOR_FTDI, + pid, pgm->usbproduct[0]? pgm->usbproduct: NULL, pgm->usbsn[0]? pgm->usbsn: NULL, devnum); + if(rv) { + pmsg_error("cannot open ftdi device: %s\n", ftdi_get_error_string(my.handle)); + goto cleanup_no_usb; + } - my.ft245r_ddr = - pgm->pin[PIN_AVR_SCK].mask[0] - | pgm->pin[PIN_AVR_SDO].mask[0] - | pgm->pin[PIN_AVR_RESET].mask[0] - | pgm->pin[PPI_AVR_BUFF].mask[0] - | pgm->pin[PPI_AVR_VCC].mask[0] - | pgm->pin[PIN_LED_ERR].mask[0] - | pgm->pin[PIN_LED_RDY].mask[0] - | pgm->pin[PIN_LED_PGM].mask[0] - | pgm->pin[PIN_LED_VFY].mask[0]; - - /* set initial values for outputs, no reset everything else is off */ - my.ft245r_out = 0; - my.ft245r_out = SET_BITS_0(my.ft245r_out, pgm, PIN_AVR_RESET, 1); - my.ft245r_out = SET_BITS_0(my.ft245r_out, pgm, PIN_AVR_SCK, 0); - my.ft245r_out = SET_BITS_0(my.ft245r_out, pgm, PIN_AVR_SDO, 0); - my.ft245r_out = SET_BITS_0(my.ft245r_out, pgm, PPI_AVR_BUFF, 0); - my.ft245r_out = SET_BITS_0(my.ft245r_out, pgm, PPI_AVR_VCC, 0); - my.ft245r_out = SET_BITS_0(my.ft245r_out, pgm, PIN_LED_ERR, 0); - my.ft245r_out = SET_BITS_0(my.ft245r_out, pgm, PIN_LED_RDY, 0); - my.ft245r_out = SET_BITS_0(my.ft245r_out, pgm, PIN_LED_PGM, 0); - my.ft245r_out = SET_BITS_0(my.ft245r_out, pgm, PIN_LED_VFY, 0); - - - rv = ftdi_set_latency_timer(my.handle, 1); - if (rv) { - pmsg_error("unable to set latency timer to 1 (%s)\n", ftdi_get_error_string(my.handle)); - goto cleanup; - } + my.ft245r_ddr = pgm->pin[PIN_AVR_SCK].mask[0] + | pgm->pin[PIN_AVR_SDO].mask[0] + | pgm->pin[PIN_AVR_RESET].mask[0] + | pgm->pin[PPI_AVR_BUFF].mask[0] + | pgm->pin[PPI_AVR_VCC].mask[0] + | pgm->pin[PIN_LED_ERR].mask[0] + | pgm->pin[PIN_LED_RDY].mask[0] + | pgm->pin[PIN_LED_PGM].mask[0] + | pgm->pin[PIN_LED_VFY].mask[0]; + + // Set initial values for outputs, no reset everything else is off + my.ft245r_out = 0; + my.ft245r_out = SET_BITS_0(my.ft245r_out, pgm, PIN_AVR_RESET, 1); + my.ft245r_out = SET_BITS_0(my.ft245r_out, pgm, PIN_AVR_SCK, 0); + my.ft245r_out = SET_BITS_0(my.ft245r_out, pgm, PIN_AVR_SDO, 0); + my.ft245r_out = SET_BITS_0(my.ft245r_out, pgm, PPI_AVR_BUFF, 0); + my.ft245r_out = SET_BITS_0(my.ft245r_out, pgm, PPI_AVR_VCC, 0); + my.ft245r_out = SET_BITS_0(my.ft245r_out, pgm, PIN_LED_ERR, 0); + my.ft245r_out = SET_BITS_0(my.ft245r_out, pgm, PIN_LED_RDY, 0); + my.ft245r_out = SET_BITS_0(my.ft245r_out, pgm, PIN_LED_PGM, 0); + my.ft245r_out = SET_BITS_0(my.ft245r_out, pgm, PIN_LED_VFY, 0); + + rv = ftdi_set_latency_timer(my.handle, 1); + if(rv) { + pmsg_error("unable to set latency timer to 1 (%s)\n", ftdi_get_error_string(my.handle)); + goto cleanup; + } - rv = ftdi_set_bitmode(my.handle, my.ft245r_ddr, BITMODE_SYNCBB); // set Synchronous BitBang - if (rv) { - pmsg_error("synchronous BitBangMode is not supported (%s)\n", ftdi_get_error_string(my.handle)); - goto cleanup; - } + rv = ftdi_set_bitmode(my.handle, my.ft245r_ddr, BITMODE_SYNCBB); // Set Synchronous bitbang + if(rv) { + pmsg_error("synchronous BitBangMode is not supported (%s)\n", ftdi_get_error_string(my.handle)); + goto cleanup; + } - rv = ft245r_set_bitclock(pgm); - if (rv) { - goto cleanup; - } + rv = ft245r_set_bitclock(pgm); + if(rv) { + goto cleanup; + } - /* - * drain any extraneous input - */ - ft245r_drain (pgm, 0); + // Drain any extraneous input + ft245r_drain(pgm, 0); - ft245r_send_and_discard(pgm, &my.ft245r_out, 1); + ft245r_send_and_discard(pgm, &my.ft245r_out, 1); - return 0; + return 0; cleanup: - ftdi_usb_close(my.handle); + ftdi_usb_close(my.handle); cleanup_no_usb: - ftdi_deinit (my.handle); - mmt_free(my.handle); - my.handle = NULL; - return -1; + ftdi_deinit(my.handle); + mmt_free(my.handle); + my.handle = NULL; + return -1; } - -static void ft245r_close(PROGRAMMER * pgm) { - if (my.handle) { - // I think the switch to BB mode and back flushes the buffer. - ftdi_set_bitmode(my.handle, 0, BITMODE_SYNCBB); // set Synchronous BitBang, all in puts - ftdi_set_bitmode(my.handle, 0, BITMODE_RESET); // disable Synchronous BitBang - ftdi_usb_close(my.handle); - ftdi_deinit (my.handle); - mmt_free(my.handle); - my.handle = NULL; - } +static void ft245r_close(PROGRAMMER *pgm) { + if(my.handle) { + // I think the switch to BB mode and back flushes the buffer. + ftdi_set_bitmode(my.handle, 0, BITMODE_SYNCBB); // Set Synchronous BitBang, all in puts + ftdi_set_bitmode(my.handle, 0, BITMODE_RESET); // Disable Synchronous BitBang + ftdi_usb_close(my.handle); + ftdi_deinit(my.handle); + mmt_free(my.handle); + my.handle = NULL; + } } static void ft245r_display(const PROGRAMMER *pgm, const char *p) { - msg_info("%sPin assignment : 0..7 = DBUS0..7\n", p); // , 8..11 = GPIO0..3\n", p); - pgm_display_generic_mask(pgm, p, SHOW_ALL_PINS); + msg_info("%sPin assignment : 0..7 = DBUS0..7\n", p); // , 8..11 = GPIO0..3\n", p); + pgm_display_generic_mask(pgm, p, SHOW_ALL_PINS); } - static int ft245r_paged_write_gen(const PROGRAMMER *pgm, const AVRPART *p, const AVRMEM *m, - unsigned int page_size, unsigned int addr, unsigned int n_bytes) { + unsigned int page_size, unsigned int addr, unsigned int n_bytes) { - for(int i=0; i < (int) n_bytes; i++, addr++) - if(avr_write_byte_default(pgm, p, m, addr, m->buf[addr]) != 0) - return -2; + for(int i = 0; i < (int) n_bytes; i++, addr++) + if(avr_write_byte_default(pgm, p, m, addr, m->buf[addr]) != 0) + return -2; - return n_bytes; + return n_bytes; } static void put_request(const PROGRAMMER *pgm, int addr, int bytes, int n) { - struct ft245r_request *p; - if (my.req_pool) { // Allocate struct ft245r_request from pool - p = my.req_pool; - my.req_pool = p->next; - } else { // ... or from memory - p = mmt_malloc(sizeof(struct ft245r_request)); - } - memset(p, 0, sizeof(struct ft245r_request)); - p->addr = addr; - p->bytes = bytes; - p->n = n; - if (my.req_tail) { - my.req_tail->next = p; - my.req_tail = p; - } else { - my.req_head = my.req_tail = p; - } + struct ft245r_request *p; + + if(my.req_pool) { // Allocate struct ft245r_request from pool + p = my.req_pool; + my.req_pool = p->next; + } else { // ... or from memory + p = mmt_malloc(sizeof(struct ft245r_request)); + } + memset(p, 0, sizeof(struct ft245r_request)); + p->addr = addr; + p->bytes = bytes; + p->n = n; + if(my.req_tail) { + my.req_tail->next = p; + my.req_tail = p; + } else { + my.req_head = my.req_tail = p; + } } static int do_request(const PROGRAMMER *pgm, const AVRMEM *m) { - struct ft245r_request *p; - int addr, bytes, j, n; - unsigned char buf[FT245R_FRAGMENT_SIZE+1+128]; + struct ft245r_request *p; + int addr, bytes, j, n; + unsigned char buf[FT245R_FRAGMENT_SIZE + 1 + 128]; - if (!my.req_head) - return 0; - p = my.req_head; - my.req_head = p->next; - if (!my.req_head) - my.req_tail = my.req_head; - - addr = p->addr; - bytes = p->bytes; - n = p->n; - // Insert p into request pool - memset(p, 0, sizeof(struct ft245r_request)); - p->next = my.req_pool; - my.req_pool = p; - - ft245r_recv(pgm, buf, bytes); - for (j=0; jbuf[addr++] = extract_data(pgm, buf , (j * 4 + 3)); - } - return 1; + if(!my.req_head) + return 0; + p = my.req_head; + my.req_head = p->next; + if(!my.req_head) + my.req_tail = my.req_head; + + addr = p->addr; + bytes = p->bytes; + n = p->n; + // Insert p into request pool + memset(p, 0, sizeof(struct ft245r_request)); + p->next = my.req_pool; + my.req_pool = p; + + ft245r_recv(pgm, buf, bytes); + for(j = 0; j < n; j++) { + m->buf[addr++] = extract_data(pgm, buf, (j*4 + 3)); + } + return 1; } - static int ft245r_paged_write_flash(const PROGRAMMER *pgm, const AVRPART *p, const AVRMEM *m, - unsigned int page_size, unsigned int addr, unsigned int n_bytes) { + unsigned int page_size, unsigned int addr, unsigned int n_bytes) { - int i, j, addr_save, buf_pos, req_count, do_page_write; - unsigned char buf[FT245R_FRAGMENT_SIZE+1]; - unsigned char cmd[4]; + int i, j, addr_save, buf_pos, req_count, do_page_write; + unsigned char buf[FT245R_FRAGMENT_SIZE + 1]; + unsigned char cmd[4]; - if(m->op[AVR_OP_LOADPAGE_LO] == NULL || m->op[AVR_OP_LOADPAGE_HI] == NULL) { - msg_error("AVR_OP_LOADPAGE_HI/LO command not defined for %s\n", p->desc); - return -1; - } + if(m->op[AVR_OP_LOADPAGE_LO] == NULL || m->op[AVR_OP_LOADPAGE_HI] == NULL) { + msg_error("AVR_OP_LOADPAGE_HI/LO command not defined for %s\n", p->desc); + return -1; + } + + do_page_write = req_count = i = j = buf_pos = 0; + addr_save = addr; + while(i < (int) n_bytes) { + int spi = addr & 1? AVR_OP_LOADPAGE_HI: AVR_OP_LOADPAGE_LO; + + // Put the SPI loadpage command as FT245R_CMD_SIZE bytes into buffer + memset(cmd, 0, sizeof cmd); + avr_set_bits(m->op[spi], cmd); + avr_set_addr(m->op[spi], cmd, addr/2); + avr_set_input(m->op[spi], cmd, m->buf[addr]); + for(size_t k = 0; k < sizeof cmd; k++) + buf_pos += set_data(pgm, buf + buf_pos, cmd[k]); + + i++; + j++; + addr++; + + if(m->paged && (i%m->page_size == 0 || i >= (int) n_bytes)) + do_page_write = 1; + + // Page boundary, finished or buffer exhausted? queue up requests + if(do_page_write || i >= (int) n_bytes || j >= FT245R_FRAGMENT_SIZE/FT245R_CMD_SIZE) { + if(i >= (int) n_bytes) { + my.ft245r_out = SET_BITS_0(my.ft245r_out, pgm, PIN_AVR_SCK, 0); // SCK down + buf[buf_pos++] = my.ft245r_out; + } else { + // Stretch sequence to allow correct readout, see extract_data() + buf[buf_pos] = buf[buf_pos - 1]; + buf_pos++; + } + ft245r_send(pgm, buf, buf_pos); + put_request(pgm, addr_save, buf_pos, 0); + + if(++req_count > REQ_OUTSTANDINGS) + do_request(pgm, m); + + if(do_page_write) { + while(do_request(pgm, m)) + continue; + if(avr_write_page(pgm, p, m, addr_save - (addr_save%m->page_size)) != 0) + return -2; + do_page_write = req_count = 0; + } - do_page_write = req_count = i = j = buf_pos = 0; - addr_save = addr; - while(i < (int) n_bytes) { - int spi = addr&1? AVR_OP_LOADPAGE_HI: AVR_OP_LOADPAGE_LO; - - // put the SPI loadpage command as FT245R_CMD_SIZE bytes into buffer - memset(cmd, 0, sizeof cmd); - avr_set_bits(m->op[spi], cmd); - avr_set_addr(m->op[spi], cmd, addr/2); - avr_set_input(m->op[spi], cmd, m->buf[addr]); - for(size_t k=0; kpaged && (i%m->page_size == 0 || i >= (int) n_bytes)) - do_page_write = 1; - - // page boundary, finished or buffer exhausted? queue up requests - if(do_page_write || i >= (int) n_bytes || j >= FT245R_FRAGMENT_SIZE/FT245R_CMD_SIZE) { - if(i >= (int) n_bytes) { - my.ft245r_out = SET_BITS_0(my.ft245r_out, pgm, PIN_AVR_SCK, 0); // SCK down - buf[buf_pos++] = my.ft245r_out; - } else { - // stretch sequence to allow correct readout, see extract_data() - buf[buf_pos] = buf[buf_pos - 1]; - buf_pos++; - } - ft245r_send(pgm, buf, buf_pos); - put_request(pgm, addr_save, buf_pos, 0); - - if(++req_count > REQ_OUTSTANDINGS) - do_request(pgm, m); - - if(do_page_write) { - while(do_request(pgm, m)) - continue; - if(avr_write_page(pgm, p, m, addr_save - (addr_save % m->page_size)) != 0) - return -2; - do_page_write = req_count = 0; - } - - // reset buffer variables - j = buf_pos = 0; - addr_save = addr; - } + // Reset buffer variables + j = buf_pos = 0; + addr_save = addr; } + } - while(do_request(pgm, m)) - continue; + while(do_request(pgm, m)) + continue; - return n_bytes; + return n_bytes; } - static int ft245r_paged_write(const PROGRAMMER *pgm, const AVRPART *p, const AVRMEM *m, - unsigned int page_size, unsigned int addr, unsigned int n_bytes) { + unsigned int page_size, unsigned int addr, unsigned int n_bytes) { - if(!n_bytes) - return 0; + if(!n_bytes) + return 0; - if(mem_is_flash(m)) - return ft245r_paged_write_flash(pgm, p, m, page_size, addr, n_bytes); + if(mem_is_flash(m)) + return ft245r_paged_write_flash(pgm, p, m, page_size, addr, n_bytes); - if(mem_is_eeprom(m)) - return ft245r_paged_write_gen(pgm, p, m, page_size, addr, n_bytes); + if(mem_is_eeprom(m)) + return ft245r_paged_write_gen(pgm, p, m, page_size, addr, n_bytes); - return -2; + return -2; } static int ft245r_paged_load_gen(const PROGRAMMER *pgm, const AVRPART *p, const AVRMEM *m, - unsigned int page_size, unsigned int addr, unsigned int n_bytes) { + unsigned int page_size, unsigned int addr, unsigned int n_bytes) { - for(int i=0; i < (int) n_bytes; i++) { - unsigned char rbyte; + for(int i = 0; i < (int) n_bytes; i++) { + unsigned char rbyte; - if(avr_read_byte_default(pgm, p, m, addr+i, &rbyte) != 0) - return -2; + if(avr_read_byte_default(pgm, p, m, addr + i, &rbyte) != 0) + return -2; - m->buf[addr+i] = rbyte; - } + m->buf[addr + i] = rbyte; + } - return 0; + return 0; } - static int ft245r_paged_load_flash(const PROGRAMMER *pgm, const AVRPART *p, const AVRMEM *m, - unsigned int page_size, unsigned int addr, unsigned int n_bytes) { + unsigned int page_size, unsigned int addr, unsigned int n_bytes) { - int i, j, addr_save, buf_pos, req_count; - unsigned char buf[FT245R_FRAGMENT_SIZE+1]; - unsigned char cmd[4]; + int i, j, addr_save, buf_pos, req_count; + unsigned char buf[FT245R_FRAGMENT_SIZE + 1]; + unsigned char cmd[4]; - if(m->op[AVR_OP_READ_LO] == NULL || m->op[AVR_OP_READ_HI] == NULL) { - msg_error("AVR_OP_READ_HI/LO command not defined for %s\n", p->desc); - return -1; - } + if(m->op[AVR_OP_READ_LO] == NULL || m->op[AVR_OP_READ_HI] == NULL) { + msg_error("AVR_OP_READ_HI/LO command not defined for %s\n", p->desc); + return -1; + } - // always called with addr at page boundary, and n_bytes == m->page_size; - // hence, OK to prepend load extended address command (at most) once - if(m->op[AVR_OP_LOAD_EXT_ADDR]) { - memset(cmd, 0, sizeof cmd); - avr_set_bits(m->op[AVR_OP_LOAD_EXT_ADDR], cmd); - avr_set_addr(m->op[AVR_OP_LOAD_EXT_ADDR], cmd, addr/2); - - buf_pos = 0; - for(size_t k=0; kpage_size; + * hence, OK to prepend load extended address command (at most) once + */ + if(m->op[AVR_OP_LOAD_EXT_ADDR]) { + memset(cmd, 0, sizeof cmd); + avr_set_bits(m->op[AVR_OP_LOAD_EXT_ADDR], cmd); + avr_set_addr(m->op[AVR_OP_LOAD_EXT_ADDR], cmd, addr/2); - req_count = i = j = buf_pos = 0; - addr_save = addr; - while(i < (int) n_bytes) { - int spi = addr&1? AVR_OP_READ_HI: AVR_OP_READ_LO; - - // put the SPI read command as FT245R_CMD_SIZE bytes into buffer - memset(cmd, 0, sizeof cmd); - avr_set_bits(m->op[spi], cmd); - avr_set_addr(m->op[spi], cmd, addr/2); - for(size_t k=0; k= (int) n_bytes || j >= FT245R_FRAGMENT_SIZE/FT245R_CMD_SIZE) { - if(i >= (int) n_bytes) { - my.ft245r_out = SET_BITS_0(my.ft245r_out, pgm, PIN_AVR_SCK, 0); // SCK down - buf[buf_pos++] = my.ft245r_out; - } else { - // stretch sequence to allow correct readout, see extract_data() - buf[buf_pos] = buf[buf_pos - 1]; - buf_pos++; - } - ft245r_send(pgm, buf, buf_pos); - put_request(pgm, addr_save, buf_pos, j); - - if(++req_count > REQ_OUTSTANDINGS) - do_request(pgm, m); - - // reset buffer variables - j = buf_pos = 0; - addr_save = addr; - } + buf_pos = 0; + for(size_t k = 0; k < sizeof cmd; k++) + buf_pos += set_data(pgm, buf + buf_pos, cmd[k]); + ft245r_send_and_discard(pgm, buf, buf_pos); + } + + req_count = i = j = buf_pos = 0; + addr_save = addr; + while(i < (int) n_bytes) { + int spi = addr & 1? AVR_OP_READ_HI: AVR_OP_READ_LO; + + // Put the SPI read command as FT245R_CMD_SIZE bytes into buffer + memset(cmd, 0, sizeof cmd); + avr_set_bits(m->op[spi], cmd); + avr_set_addr(m->op[spi], cmd, addr/2); + for(size_t k = 0; k < sizeof cmd; k++) + buf_pos += set_data(pgm, buf + buf_pos, cmd[k]); + + i++; + j++; + addr++; + + // Finished or buffer exhausted? Queue up requests + if(i >= (int) n_bytes || j >= FT245R_FRAGMENT_SIZE/FT245R_CMD_SIZE) { + if(i >= (int) n_bytes) { + my.ft245r_out = SET_BITS_0(my.ft245r_out, pgm, PIN_AVR_SCK, 0); // SCK down + buf[buf_pos++] = my.ft245r_out; + } else { + // Stretch sequence to allow correct readout, see extract_data() + buf[buf_pos] = buf[buf_pos - 1]; + buf_pos++; + } + ft245r_send(pgm, buf, buf_pos); + put_request(pgm, addr_save, buf_pos, j); + + if(++req_count > REQ_OUTSTANDINGS) + do_request(pgm, m); + + // Reset buffer variables + j = buf_pos = 0; + addr_save = addr; } + } - while(do_request(pgm, m)) - continue; + while(do_request(pgm, m)) + continue; - return 0; + return 0; } static int ft245r_paged_load(const PROGRAMMER *pgm, const AVRPART *p, const AVRMEM *m, - unsigned int page_size, unsigned int addr, unsigned int n_bytes) { + unsigned int page_size, unsigned int addr, unsigned int n_bytes) { - if(!n_bytes) - return 0; + if(!n_bytes) + return 0; - if(mem_is_flash(m)) - return ft245r_paged_load_flash(pgm, p, m, page_size, addr, n_bytes); + if(mem_is_flash(m)) + return ft245r_paged_load_flash(pgm, p, m, page_size, addr, n_bytes); - if(mem_is_eeprom(m)) - return ft245r_paged_load_gen(pgm, p, m, page_size, addr, n_bytes); + if(mem_is_eeprom(m)) + return ft245r_paged_load_gen(pgm, p, m, page_size, addr, n_bytes); - return -2; + return -2; } void ft245r_setup(PROGRAMMER *pgm) { @@ -1204,11 +1192,13 @@ void ft245r_teardown(PROGRAMMER *pgm) { while(my.req_pool) { // Free request pool struct ft245r_request *p = my.req_pool; + my.req_pool = p->next; mmt_free(p); } while(my.req_head) { // Free pending queue struct ft245r_request *p = my.req_head; + my.req_head = p->next; mmt_free(p); } @@ -1217,40 +1207,35 @@ void ft245r_teardown(PROGRAMMER *pgm) { } void ft245r_initpgm(PROGRAMMER *pgm) { - strcpy(pgm->type, "ftdi_syncbb"); - - /* - * mandatory functions - */ - pgm->initialize = ft245r_initialize; - pgm->display = ft245r_display; - pgm->enable = ft245r_enable; - pgm->disable = ft245r_disable; - pgm->program_enable = ft245r_program_enable; - pgm->chip_erase = ft245r_chip_erase; - pgm->cmd = ft245r_cmd; - pgm->cmd_tpi = ft245r_cmd_tpi; - pgm->open = ft245r_open; - pgm->close = ft245r_close; - pgm->read_byte = avr_read_byte_default; - pgm->write_byte = avr_write_byte_default; - - /* - * optional functions - */ - pgm->paged_write = ft245r_paged_write; - pgm->paged_load = ft245r_paged_load; - - pgm->rdy_led = ft245_rdy_led; - pgm->err_led = ft245_err_led; - pgm->pgm_led = ft245_pgm_led; - pgm->vfy_led = ft245_vfy_led; - pgm->powerup = ft245r_powerup; - pgm->powerdown = ft245r_powerdown; - pgm->setup = ft245r_setup; - pgm->teardown = ft245r_teardown; + strcpy(pgm->type, "ftdi_syncbb"); + + // Mandatory functions + pgm->initialize = ft245r_initialize; + pgm->display = ft245r_display; + pgm->enable = ft245r_enable; + pgm->disable = ft245r_disable; + pgm->program_enable = ft245r_program_enable; + pgm->chip_erase = ft245r_chip_erase; + pgm->cmd = ft245r_cmd; + pgm->cmd_tpi = ft245r_cmd_tpi; + pgm->open = ft245r_open; + pgm->close = ft245r_close; + pgm->read_byte = avr_read_byte_default; + pgm->write_byte = avr_write_byte_default; + + // Optional functions + pgm->paged_write = ft245r_paged_write; + pgm->paged_load = ft245r_paged_load; + + pgm->rdy_led = ft245_rdy_led; + pgm->err_led = ft245_err_led; + pgm->pgm_led = ft245_pgm_led; + pgm->vfy_led = ft245_vfy_led; + pgm->powerup = ft245r_powerup; + pgm->powerdown = ft245r_powerdown; + pgm->setup = ft245r_setup; + pgm->teardown = ft245r_teardown; } - #endif const char ft245r_desc[] = "FT245R/FT232R synchronous bit-bang programmer of type ftdi_syncbb"; diff --git a/src/ft245r.h b/src/ft245r.h index 2495dc87c..7c3df7df5 100644 --- a/src/ft245r.h +++ b/src/ft245r.h @@ -4,5 +4,4 @@ extern const char ft245r_desc[]; void ft245r_initpgm(PROGRAMMER *pgm); - -#endif /* ft245r_h */ +#endif diff --git a/src/jtag3.c b/src/jtag3.c index 2c595c5f2..bda8bd8e1 100644 --- a/src/jtag3.c +++ b/src/jtag3.c @@ -80,12 +80,8 @@ #include "jtag3_private.h" #include "usbdevs.h" -/* - * Private data for this programmer. - */ -struct pdata -{ - unsigned short command_sequence; /* Next cmd seqno to issue. */ +struct pdata { + unsigned short command_sequence; // Next cmd seqno to issue /* * See jtag3_read_byte() for an explanation of the flash and @@ -99,49 +95,49 @@ struct pdata unsigned long eeprom_pageaddr; unsigned int eeprom_pagesize; - int prog_enabled; /* Cached value of PROGRAMMING status. */ + int prog_enabled; // Cached value of PROGRAMMING status - /* JTAG chain stuff */ + // JTAG chain stuff unsigned char jtagchain[4]; - /* Start address of Xmega boot area */ + // Start address of Xmega boot area unsigned long boot_start; - /* Flag for triggering HV UPDI */ + // Flag for triggering HV UPDI bool use_hvupdi; - /* Get/set flags for SUFFER register */ + // Get/set flags for SUFFER register bool suffer_get; bool suffer_set; unsigned char suffer_data[2]; - /* Get/set flags for target power switch */ + // Get/set flags for target power switch bool vtarg_switch_get; bool vtarg_switch_set; unsigned char vtarg_switch_data[2]; - /* Get/set flags for adjustable target voltage */ + // Get/set flags for adjustable target voltage bool vtarg_get; bool vtarg_set; double vtarg_data; - /* Flag for PICkit4/SNAP mode switching */ + // Flag for PICkit4/SNAP mode switching int pk4_snap_mode; - /* SIB string cache */ + // SIB string cache char sib_string[AVR_SIBLEN]; - /* Function to set the appropriate clock parameter */ + // Function to set the appropriate clock parameter int (*set_sck)(const PROGRAMMER *, unsigned char *); - unsigned char signature_cache[2]; // Used in jtag3_read_byte() + unsigned char signature_cache[2]; // Used in jtag3_read_byte() }; -#define PDATA(pgm) ((struct pdata *)(pgm->cookie)) +#define my (*(struct pdata *) (pgm->cookie)) /* - * pgm->flag is marked as "for private use of the programmer". - * The following defines this programmer's use of that field. + * pgm->flag is marked as "for private use of the programmer". The following + * defines this programmer's use of that field. */ #define PGM_FL_IS_DW (0x0001) #define PGM_FL_IS_PDI (0x0002) @@ -159,19 +155,17 @@ static int jtag3_edbg_recv_frame(const PROGRAMMER *pgm, unsigned char **msg); static int jtag3_initialize(const PROGRAMMER *pgm, const AVRPART *p); static int jtag3_chip_erase(const PROGRAMMER *pgm, const AVRPART *p); static int jtag3_read_byte(const PROGRAMMER *pgm, const AVRPART *p, const AVRMEM *mem, - unsigned long addr, unsigned char * value); + unsigned long addr, unsigned char *value); static int jtag3_write_byte(const PROGRAMMER *pgm, const AVRPART *p, const AVRMEM *mem, - unsigned long addr, unsigned char data); + unsigned long addr, unsigned char data); static int jtag3_set_sck_period(const PROGRAMMER *pgm, double v); void jtag3_display(const PROGRAMMER *pgm, const char *p); void jtag3_print_parms1(const PROGRAMMER *pgm, const char *p, FILE *fp); static int jtag3_paged_write(const PROGRAMMER *pgm, const AVRPART *p, const AVRMEM *m, - unsigned int page_size, - unsigned int addr, unsigned int n_bytes); + unsigned int page_size, unsigned int addr, unsigned int n_bytes); static unsigned char jtag3_mtype(const PROGRAMMER *pgm, const AVRPART *p, const AVRMEM *m, unsigned long addr); static unsigned int jtag3_memaddr(const PROGRAMMER *pgm, const AVRPART *p, const AVRMEM *m, unsigned long addr); - void jtag3_setup(PROGRAMMER *pgm) { pgm->cookie = mmt_malloc(sizeof(struct pdata)); } @@ -181,13 +175,13 @@ void jtag3_teardown(PROGRAMMER *pgm) { pgm->cookie = NULL; } - static unsigned long b4_to_u32(unsigned char *b) { unsigned long l; + l = b[0]; - l += (unsigned)b[1] << 8; - l += (unsigned)b[2] << 16; - l += (unsigned)b[3] << 24; + l += (unsigned) b[1] << 8; + l += (unsigned) b[2] << 16; + l += (unsigned) b[3] << 24; return l; } @@ -201,8 +195,9 @@ static void u32_to_b4(unsigned char *b, unsigned long l) { static unsigned short b2_to_u16(unsigned char *b) { unsigned short l; + l = b[0]; - l += (unsigned)b[1] << 8; + l += (unsigned) b[1] << 8; return l; } @@ -227,234 +222,231 @@ static void u16_to_b2_big_endian(unsigned char *b, unsigned short l) { static void jtag3_print_data(unsigned char *b, size_t s) { size_t i; - if (s < 2) + if(s < 2) return; - for (i = 0; i < s; i++) { + for(i = 0; i < s; i++) { msg_debug("0x%02x", b[i]); - if (i % 16 == 15) + if(i%16 == 15) msg_debug("\n"); else msg_debug(" "); } - if (i % 16 != 0) + if(i%16 != 0) msg_debug("\n"); } static void jtag3_prmsg(const PROGRAMMER *pgm, unsigned char *data, size_t len) { - if (verbose >= MSG_TRACE) { + if(verbose >= MSG_TRACE) { size_t i; msg_trace("Raw message:\n"); - for (i = 0; i < len; i++) { + for(i = 0; i < len; i++) { msg_trace("%02x ", data[i]); - if (i % 16 == 15) + if(i%16 == 15) msg_trace("\n"); else msg_trace(" "); } - if (i % 16 != 0) + if(i%16 != 0) msg_trace("\n"); } - switch (data[0]) { - case SCOPE_INFO: - msg_debug("[info] "); - break; + switch(data[0]) { + case SCOPE_INFO: + msg_debug("[info] "); + break; - case SCOPE_GENERAL: - msg_debug("[general] "); - break; + case SCOPE_GENERAL: + msg_debug("[general] "); + break; - case SCOPE_AVR_ISP: - msg_debug("[AVRISP] "); - jtag3_print_data(data + 1, len - 1); - return; + case SCOPE_AVR_ISP: + msg_debug("[AVRISP] "); + jtag3_print_data(data + 1, len - 1); + return; - case SCOPE_AVR: - msg_debug("[AVR] "); - break; + case SCOPE_AVR: + msg_debug("[AVR] "); + break; - default: - msg_debug("[scope 0x%02x] ", data[0]); - break; + default: + msg_debug("[scope 0x%02x] ", data[0]); + break; } - switch (data[1]) { - case RSP3_OK: - msg_debug("OK\n"); - break; + switch(data[1]) { + case RSP3_OK: + msg_debug("OK\n"); + break; - case RSP3_FAILED: - msg_debug("FAILED"); - if (len > 3) - { - char reason[50]; - sprintf(reason, "0x%02x", data[3]); - switch (data[3]) { - case RSP3_FAIL_NO_ANSWER: - strcpy(reason, "target does not answer"); - break; + case RSP3_FAILED: + msg_debug("FAILED"); + if(len > 3) { + char reason[50]; - case RSP3_FAIL_NO_TARGET_POWER: - strcpy(reason, "no target power"); - break; + sprintf(reason, "0x%02x", data[3]); + switch(data[3]) { + case RSP3_FAIL_NO_ANSWER: + strcpy(reason, "target does not answer"); + break; - case RSP3_FAIL_NOT_UNDERSTOOD: - strcpy(reason, "command not understood"); - break; + case RSP3_FAIL_NO_TARGET_POWER: + strcpy(reason, "no target power"); + break; - case RSP3_FAIL_WRONG_MODE: - strcpy(reason, "wrong (programming) mode"); - break; + case RSP3_FAIL_NOT_UNDERSTOOD: + strcpy(reason, "command not understood"); + break; - case RSP3_FAIL_PDI: - strcpy(reason, "PDI failure"); - break; + case RSP3_FAIL_WRONG_MODE: + strcpy(reason, "wrong (programming) mode"); + break; - case RSP3_FAIL_UNSUPP_MEMORY: - strcpy(reason, "unsupported memory type"); - break; + case RSP3_FAIL_PDI: + strcpy(reason, "PDI failure"); + break; - case RSP3_FAIL_WRONG_LENGTH: - strcpy(reason, "wrong length in memory access"); - break; + case RSP3_FAIL_UNSUPP_MEMORY: + strcpy(reason, "unsupported memory type"); + break; - case RSP3_FAIL_DEBUGWIRE: - strcpy(reason, "debugWIRE communication failed"); - break; - } - msg_debug(", reason: %s\n", reason); - } - else { - msg_debug(", unspecified reason\n"); + case RSP3_FAIL_WRONG_LENGTH: + strcpy(reason, "wrong length in memory access"); + break; + + case RSP3_FAIL_DEBUGWIRE: + strcpy(reason, "debugWIRE communication failed"); + break; } - break; + msg_debug(", reason: %s\n", reason); + } else { + msg_debug(", unspecified reason\n"); + } + break; - case RSP3_DATA: - msg_debug("Data returned:\n"); - jtag3_print_data(data + 2, len - 2); - break; + case RSP3_DATA: + msg_debug("Data returned:\n"); + jtag3_print_data(data + 2, len - 2); + break; - case RSP3_INFO: - msg_debug("Info returned:\n"); - for (size_t i = 2; i < len; i++) { - if (isprint(data[i])) - msg_debug("%c", data[i]); - else - msg_debug("\\%03o", data[i]); - } - msg_debug("\n"); - break; + case RSP3_INFO: + msg_debug("Info returned:\n"); + for(size_t i = 2; i < len; i++) { + if(isprint(data[i])) + msg_debug("%c", data[i]); + else + msg_debug("\\%03o", data[i]); + } + msg_debug("\n"); + break; - case RSP3_PC: - if (len < 7) { - msg_debug("PC reply too short\n"); - } - else { - unsigned long pc = (data[6] << 24) | (data[5] << 16) - | (data[4] << 8) | data[3]; - msg_debug("PC 0x%0lx\n", pc); - } - break; + case RSP3_PC: + if(len < 7) { + msg_debug("PC reply too short\n"); + } else { + unsigned long pc = (data[6] << 24) | (data[5] << 16) + | (data[4] << 8) | data[3]; + + msg_debug("PC 0x%0lx\n", pc); + } + break; - default: - msg_debug("unknown message 0x%02x\n", data[1]); + default: + msg_debug("unknown message 0x%02x\n", data[1]); } } static int jtag3_errcode(int reason) { - if (reason == RSP3_FAIL_OCD_LOCKED || - reason == RSP3_FAIL_CRC_FAILURE) + if(reason == RSP3_FAIL_OCD_LOCKED || reason == RSP3_FAIL_CRC_FAILURE) return LIBAVRDUDE_SOFTFAIL; return LIBAVRDUDE_GENERAL_FAILURE; } static void jtag3_prevent(const PROGRAMMER *pgm, unsigned char *data, size_t len) { - if (verbose >= MSG_TRACE) { + if(verbose >= MSG_TRACE) { size_t i; msg_trace("Raw event:\n"); - for (i = 0; i < len; i++) { + for(i = 0; i < len; i++) { msg_trace("%02x ", data[i]); - if (i % 16 == 15) + if(i%16 == 15) msg_trace("\n"); else msg_trace(" "); } - if (i % 16 != 0) + if(i%16 != 0) msg_trace("\n"); } msg_debug("Event serial 0x%04x, ", (data[3] << 8) | data[2]); - switch (data[4]) { - case SCOPE_INFO: - msg_debug("[info] "); - break; + switch(data[4]) { + case SCOPE_INFO: + msg_debug("[info] "); + break; - case SCOPE_GENERAL: - msg_debug("[general] "); - break; + case SCOPE_GENERAL: + msg_debug("[general] "); + break; - case SCOPE_AVR: - msg_debug("[AVR] "); - break; + case SCOPE_AVR: + msg_debug("[AVR] "); + break; - default: - msg_debug("[scope 0x%02x] ", data[0]); - break; + default: + msg_debug("[scope 0x%02x] ", data[0]); + break; } - switch (data[5]) { - case EVT3_BREAK: - msg_debug("BREAK"); - if (len >= 11) { - msg_debug(", PC = 0x%lx, reason ", b4_to_u32(data + 6)); - switch (data[10]) { - case 0x00: - msg_debug("unspecified"); - break; - case 0x01: - msg_debug("program break"); - break; - case 0x02: - msg_debug("data break PDSB"); - break; - case 0x03: - msg_debug("data break PDMSB"); - break; - default: - msg_debug("unknown: 0x%02x", data[10]); - } - /* There are two more bytes of data which always appear to be - * 0x01, 0x00. Purpose unknown. */ + switch(data[5]) { + case EVT3_BREAK: + msg_debug("BREAK"); + if(len >= 11) { + msg_debug(", PC = 0x%lx, reason ", b4_to_u32(data + 6)); + switch(data[10]) { + case 0x00: + msg_debug("unspecified"); + break; + case 0x01: + msg_debug("program break"); + break; + case 0x02: + msg_debug("data break PDSB"); + break; + case 0x03: + msg_debug("data break PDMSB"); + break; + default: + msg_debug("unknown: 0x%02x", data[10]); } - break; - - case EVT3_SLEEP: - if (len >= 8 && data[7] == 0) - msg_debug("sleeping"); - else if (len >= 8 && data[7] == 1) - msg_debug("wakeup"); - else - msg_debug("unknown SLEEP event"); - break; + // There are two more bytes of data which always appear to be 0x01, 0x00; purpose unknown + } + break; - case EVT3_POWER: - if (len >= 8 && data[7] == 0) - msg_debug("power-down"); - else if (len >= 8 && data[7] == 1) - msg_debug("power-up"); - else - msg_debug("unknown POWER event"); - break; + case EVT3_SLEEP: + if(len >= 8 && data[7] == 0) + msg_debug("sleeping"); + else if(len >= 8 && data[7] == 1) + msg_debug("wakeup"); + else + msg_debug("unknown SLEEP event"); + break; + + case EVT3_POWER: + if(len >= 8 && data[7] == 0) + msg_debug("power-down"); + else if(len >= 8 && data[7] == 1) + msg_debug("power-up"); + else + msg_debug("unknown POWER event"); + break; - default: - msg_debug("UNKNOWN 0x%02x", data[5]); - break; + default: + msg_debug("UNKNOWN 0x%02x", data[5]); + break; } msg_debug("\n"); } @@ -462,7 +454,7 @@ static void jtag3_prevent(const PROGRAMMER *pgm, unsigned char *data, size_t len int jtag3_send(const PROGRAMMER *pgm, unsigned char *data, size_t len) { unsigned char *buf; - if (pgm->flag & PGM_FL_IS_EDBG) + if(pgm->flag & PGM_FL_IS_EDBG) return jtag3_edbg_send(pgm, data, len); msg_debug("\n"); @@ -470,11 +462,11 @@ int jtag3_send(const PROGRAMMER *pgm, unsigned char *data, size_t len) { buf = mmt_malloc(len + 4); buf[0] = TOKEN; - buf[1] = 0; /* dummy */ - u16_to_b2(buf + 2, PDATA(pgm)->command_sequence); + buf[1] = 0; // Dummy + u16_to_b2(buf + 2, my.command_sequence); memcpy(buf + 4, data, len); - if (serial_send(&pgm->fd, buf, len + 4) != 0) { + if(serial_send(&pgm->fd, buf, len + 4) != 0) { pmsg_error("unable to send command to serial port\n"); mmt_free(buf); return -1; @@ -490,7 +482,7 @@ static int jtag3_edbg_send(const PROGRAMMER *pgm, unsigned char *data, size_t le unsigned char status[USBDEV_MAX_XFER_3]; int rv; - if (verbose >= MSG_TRACE) { + if(verbose >= MSG_TRACE) { memset(buf, 0, USBDEV_MAX_XFER_3); memset(status, 0, USBDEV_MAX_XFER_3); } @@ -498,38 +490,37 @@ static int jtag3_edbg_send(const PROGRAMMER *pgm, unsigned char *data, size_t le msg_debug("\n"); pmsg_debug("%s(): sending %lu bytes\n", __func__, (unsigned long) len); - /* 4 bytes overhead for CMD, fragment #, and length info */ + // 4 bytes overhead for CMD, fragment #, and length info int max_xfer = pgm->fd.usb.max_xfer; - int nfragments = (len + max_xfer - 1) / max_xfer; - if (nfragments > 1) { + int nfragments = (len + max_xfer - 1)/max_xfer; + + if(nfragments > 1) { pmsg_debug("%s(): fragmenting into %d packets\n", __func__, nfragments); } int frag; - for (frag = 0; frag < nfragments; frag++) { + + for(frag = 0; frag < nfragments; frag++) { int this_len; - /* All fragments have the (CMSIS-DAP layer) CMD, the fragment - * identifier, and the length field. */ + // All fragments have the (CMSIS-DAP layer) CMD, the fragment identifier, and the length field buf[0] = EDBG_VENDOR_AVR_CMD; buf[1] = ((frag + 1) << 4) | nfragments; - if (frag == 0) { - /* Only first fragment has TOKEN and seq#, thus four bytes - * less payload than subsequent fragments. */ + if(frag == 0) { + // Only first fragment has TOKEN and seq# this_len = (int) len < max_xfer - 8? (int) len: max_xfer - 8; buf[2] = (this_len + 4) >> 8; buf[3] = (this_len + 4) & 0xff; buf[4] = TOKEN; - buf[5] = 0; /* dummy */ - u16_to_b2(buf + 6, PDATA(pgm)->command_sequence); + buf[5] = 0; // Dummy + u16_to_b2(buf + 6, my.command_sequence); if(this_len < 0) { pmsg_error("unexpected this_len = %d\n", this_len); return -1; } memcpy(buf + 8, data, this_len); - } - else { + } else { this_len = (int) len < max_xfer - 4? (int) len: max_xfer - 4; buf[2] = (this_len) >> 8; buf[3] = (this_len) & 0xff; @@ -540,20 +531,19 @@ static int jtag3_edbg_send(const PROGRAMMER *pgm, unsigned char *data, size_t le memcpy(buf + 4, data, this_len); } - if (serial_send(&pgm->fd, buf, max_xfer) != 0) { + if(serial_send(&pgm->fd, buf, max_xfer) != 0) { pmsg_notice("%s(): unable to send command to serial port\n", __func__); return -1; } rv = serial_recv(&pgm->fd, status, max_xfer); - if (rv < 0) { - /* timeout in receive */ + if(rv < 0) { + // Timeout in receive pmsg_notice2("%s(): timeout receiving packet\n", __func__); return -1; } - if (status[0] != EDBG_VENDOR_AVR_CMD || - (frag == nfragments - 1 && status[1] != 0x01)) { - /* what to do in this case? */ + if(status[0] != EDBG_VENDOR_AVR_CMD || (frag == nfragments - 1 && status[1] != 0x01)) { + // What to do in this case? pmsg_notice("%s(): unexpected response 0x%02x, 0x%02x\n", __func__, status[0], status[1]); } data += this_len; @@ -563,9 +553,7 @@ static int jtag3_edbg_send(const PROGRAMMER *pgm, unsigned char *data, size_t le return 0; } -/* - * Send out all the CMSIS-DAP stuff needed to prepare the ICE. - */ +// Send out all the CMSIS-DAP stuff needed to prepare the ICE static int jtag3_edbg_prepare(const PROGRAMMER *pgm) { unsigned char buf[USBDEV_MAX_XFER_3]; unsigned char status[USBDEV_MAX_XFER_3]; @@ -574,48 +562,43 @@ static int jtag3_edbg_prepare(const PROGRAMMER *pgm) { msg_debug("\n"); pmsg_debug("jtag3_edbg_prepare()\n"); - if (verbose >= MSG_TRACE) + if(verbose >= MSG_TRACE) memset(buf, 0, USBDEV_MAX_XFER_3); buf[0] = CMSISDAP_CMD_CONNECT; buf[1] = CMSISDAP_CONN_SWD; - if (serial_send(&pgm->fd, buf, pgm->fd.usb.max_xfer) != 0) { + if(serial_send(&pgm->fd, buf, pgm->fd.usb.max_xfer) != 0) { pmsg_error("unable to send command to serial port\n"); return -1; } rv = serial_recv(&pgm->fd, status, pgm->fd.usb.max_xfer); - if (rv != pgm->fd.usb.max_xfer) { + if(rv != pgm->fd.usb.max_xfer) { pmsg_error("unable to read from serial port (%d)\n", rv); return -1; } - if (status[0] != CMSISDAP_CMD_CONNECT || - status[1] == 0) + if(status[0] != CMSISDAP_CMD_CONNECT || status[1] == 0) pmsg_error("unexpected response 0x%02x, 0x%02x\n", status[0], status[1]); pmsg_notice2("%s(): connection status 0x%02x\n", __func__, status[1]); buf[0] = CMSISDAP_CMD_LED; buf[1] = CMSISDAP_LED_CONNECT; buf[2] = 1; - if (serial_send(&pgm->fd, buf, pgm->fd.usb.max_xfer) != 0) { + if(serial_send(&pgm->fd, buf, pgm->fd.usb.max_xfer) != 0) { pmsg_error("unable to send command to serial port\n"); return -1; } rv = serial_recv(&pgm->fd, status, pgm->fd.usb.max_xfer); - if (rv != pgm->fd.usb.max_xfer) { + if(rv != pgm->fd.usb.max_xfer) { pmsg_error("unable to read from serial port (%d)\n", rv); return -1; } - if (status[0] != CMSISDAP_CMD_LED || - status[1] != 0) + if(status[0] != CMSISDAP_CMD_LED || status[1] != 0) pmsg_error("unexpected response 0x%02x, 0x%02x\n", status[0], status[1]); return 0; } - -/* - * Send out all the CMSIS-DAP stuff when signing off. - */ +// Send out all the CMSIS-DAP stuff when signing off static int jtag3_edbg_signoff(const PROGRAMMER *pgm) { unsigned char buf[USBDEV_MAX_XFER_3]; unsigned char status[USBDEV_MAX_XFER_3]; @@ -624,53 +607,49 @@ static int jtag3_edbg_signoff(const PROGRAMMER *pgm) { msg_debug("\n"); pmsg_debug("jtag3_edbg_signoff()\n"); - if (verbose >= MSG_TRACE) + if(verbose >= MSG_TRACE) memset(buf, 0, USBDEV_MAX_XFER_3); buf[0] = CMSISDAP_CMD_LED; buf[1] = CMSISDAP_LED_CONNECT; buf[2] = 0; - if (serial_send(&pgm->fd, buf, pgm->fd.usb.max_xfer) != 0) { + if(serial_send(&pgm->fd, buf, pgm->fd.usb.max_xfer) != 0) { pmsg_notice("%s(): unable to send command to serial port\n", __func__); return -1; } rv = serial_recv(&pgm->fd, status, pgm->fd.usb.max_xfer); - if (rv != pgm->fd.usb.max_xfer) { + if(rv != pgm->fd.usb.max_xfer) { pmsg_notice("%s(): unable to read from serial port (%d)\n", __func__, rv); return -1; } - if (status[0] != CMSISDAP_CMD_LED || - status[1] != 0) + if(status[0] != CMSISDAP_CMD_LED || status[1] != 0) pmsg_notice("%s(): unexpected response 0x%02x, 0x%02x\n", __func__, status[0], status[1]); buf[0] = CMSISDAP_CMD_DISCONNECT; - if (serial_send(&pgm->fd, buf, pgm->fd.usb.max_xfer) != 0) { + if(serial_send(&pgm->fd, buf, pgm->fd.usb.max_xfer) != 0) { pmsg_notice("%s(): unable to send command to serial port\n", __func__); return -1; } rv = serial_recv(&pgm->fd, status, pgm->fd.usb.max_xfer); - if (rv != pgm->fd.usb.max_xfer) { + if(rv != pgm->fd.usb.max_xfer) { pmsg_notice("%s(): unable to read from serial port (%d)\n", __func__, rv); return -1; } - if (status[0] != CMSISDAP_CMD_DISCONNECT || - status[1] != 0) + if(status[0] != CMSISDAP_CMD_DISCONNECT || status[1] != 0) pmsg_notice("%s(): unexpected response 0x%02x, 0x%02x\n", __func__, status[0], status[1]); return 0; } - static int jtag3_drain(const PROGRAMMER *pgm, int display) { return serial_drain(&pgm->fd, display); } - /* - * Receive one frame, return it in *msg. Received sequence number is - * returned in seqno. Any valid frame will be returned, regardless - * whether it matches the expected sequence number, including event - * notification frames (seqno == 0xffff). + * Receive one frame, return it in *msg. Received sequence number is returned + * in seqno. Any valid frame will be returned, regardless whether it matches + * the expected sequence number, including event notification frames (seqno == + * 0xffff). * * Caller must eventually mmt_free() the buffer. */ @@ -678,7 +657,7 @@ static int jtag3_recv_frame(const PROGRAMMER *pgm, unsigned char **msg) { int rv; unsigned char *buf = NULL; - if (pgm->flag & PGM_FL_IS_EDBG) + if(pgm->flag & PGM_FL_IS_EDBG) return jtag3_edbg_recv_frame(pgm, msg); pmsg_trace("jtag3_recv_frame():\n"); @@ -686,7 +665,7 @@ static int jtag3_recv_frame(const PROGRAMMER *pgm, unsigned char **msg) { buf = mmt_malloc(pgm->fd.usb.max_xfer); rv = serial_recv(&pgm->fd, buf, pgm->fd.usb.max_xfer); - if (rv < 0) { + if(rv < 0) { pmsg_notice2("%s(): timeout receiving packet\n", __func__); mmt_free(buf); return -1; @@ -715,7 +694,7 @@ static int jtag3_edbg_recv_frame(const PROGRAMMER *pgm, unsigned char **msg) { do { request[0] = EDBG_VENDOR_AVR_RSP; - if (serial_send(&pgm->fd, request, pgm->fd.usb.max_xfer) != 0) { + if(serial_send(&pgm->fd, request, pgm->fd.usb.max_xfer) != 0) { pmsg_notice("%s(): unable to send CMSIS-DAP vendor command\n", __func__); mmt_free(request); mmt_free(*msg); @@ -724,25 +703,26 @@ static int jtag3_edbg_recv_frame(const PROGRAMMER *pgm, unsigned char **msg) { rv = serial_recv(&pgm->fd, buf, pgm->fd.usb.max_xfer); - if (rv < 0) { - /* timeout in receive */ + if(rv < 0) { + // Timeout in receive pmsg_notice2("%s(): timeout receiving packet\n", __func__); mmt_free(*msg); mmt_free(request); return -1; } - if (buf[0] != EDBG_VENDOR_AVR_RSP) { + if(buf[0] != EDBG_VENDOR_AVR_RSP) { pmsg_notice("%s(): unexpected response 0x%02x\n", __func__, buf[0]); mmt_free(*msg); mmt_free(request); return -1; } - if (buf[1] == 0) { - // Documentation says: - // "FragmentInfo 0x00 indicates that no response data is - // available, and the rest of the packet is ignored." + if(buf[1] == 0) { + /* + * Documentation says: "FragmentInfo 0x00 indicates that no response data + * is available, and the rest of the packet is ignored." + */ cx->usb_access_error = 1; // Also end up here on wrong USB permissions pmsg_notice("%s(): no response available\n", __func__); mmt_free(*msg); @@ -750,34 +730,34 @@ static int jtag3_edbg_recv_frame(const PROGRAMMER *pgm, unsigned char **msg) { return -1; } - /* calculate fragment information */ - if (thisfrag == 0) { - /* first fragment */ + // Calculate fragment information + if(thisfrag == 0) { + // First fragment nfrags = buf[1] & 0x0F; thisfrag = 1; } else { - if (nfrags != (buf[1] & 0x0F)) { - pmsg_notice("%s(): inconsistent # of fragments; had %d, now %d\n", __func__, - nfrags, (buf[1] & 0x0F)); + if(nfrags != (buf[1] & 0x0F)) { + pmsg_notice("%s(): inconsistent # of fragments; had %d, now %d\n", __func__, nfrags, (buf[1] & 0x0F)); mmt_free(*msg); mmt_free(request); return -1; } } - if (thisfrag != ((buf[1] >> 4) & 0x0F)) { - pmsg_notice("%s(): inconsistent fragment number; expect %d, got %d\n", __func__, - thisfrag, ((buf[1] >> 4) & 0x0F)); + if(thisfrag != ((buf[1] >> 4) & 0x0F)) { + pmsg_notice("%s(): inconsistent fragment number; expect %d, got %d\n", + __func__, thisfrag, ((buf[1] >> 4) & 0x0F)); mmt_free(*msg); mmt_free(request); return -1; } int thislen = (buf[2] << 8) | buf[3]; - if (thislen > rv + 4) { + + if(thislen > rv + 4) { pmsg_notice("%s(): unexpected length value (%d > %d)\n", __func__, thislen, rv + 4); thislen = rv + 4; } - if (len + thislen > USBDEV_MAX_XFER_3) { + if(len + thislen > USBDEV_MAX_XFER_3) { pmsg_notice("%s(): length exceeds max size (%d > %d)\n", __func__, len + thislen, USBDEV_MAX_XFER_3); thislen = USBDEV_MAX_XFER_3 - len; } @@ -785,7 +765,7 @@ static int jtag3_edbg_recv_frame(const PROGRAMMER *pgm, unsigned char **msg) { thisfrag++; len += thislen; buf += thislen; - } while (thisfrag <= nfrags); + } while(thisfrag <= nfrags); mmt_free(request); return len; @@ -795,12 +775,12 @@ int jtag3_recv(const PROGRAMMER *pgm, unsigned char **msg) { unsigned short r_seqno; int rv; - for (;;) { - if ((rv = jtag3_recv_frame(pgm, msg)) <= 0) + for(;;) { + if((rv = jtag3_recv_frame(pgm, msg)) <= 0) return rv; - if ((rv & USB_RECV_FLAG_EVENT) != 0) { - if (verbose >= MSG_DEBUG) + if((rv & USB_RECV_FLAG_EVENT) != 0) { + if(verbose >= MSG_DEBUG) jtag3_prevent(pgm, *msg, rv & USB_RECV_LENGTH_MASK); mmt_free(*msg); @@ -809,17 +789,18 @@ int jtag3_recv(const PROGRAMMER *pgm, unsigned char **msg) { rv &= USB_RECV_LENGTH_MASK; r_seqno = ((*msg)[2] << 8) | (*msg)[1]; - pmsg_debug("%s(): got message seqno %d (command_sequence == %d)\n", __func__, r_seqno, PDATA(pgm)->command_sequence); - if (r_seqno == PDATA(pgm)->command_sequence) { - if (++(PDATA(pgm)->command_sequence) == 0xffff) - PDATA(pgm)->command_sequence = 0; + pmsg_debug("%s(): got message seqno %d (command_sequence == %d)\n", + __func__, r_seqno, my.command_sequence); + if(r_seqno == my.command_sequence) { + if(++(my.command_sequence) == 0xffff) + my.command_sequence = 0; /* - * We move the payload to the beginning of the buffer, to make - * the job easier for the caller. We have to return the - * original pointer though, as the caller must mmt_free() it. + * We move the payload to the beginning of the buffer, to make the job + * easier for the caller. We have to return the original pointer though, + * as the caller must mmt_free() it. */ rv -= 3; - if (rv < 0) { + if(rv < 0) { pmsg_error("unexpected return value %d from jtag3_recv_frame()\n", rv); mmt_free(*msg); return -1; @@ -828,14 +809,15 @@ int jtag3_recv(const PROGRAMMER *pgm, unsigned char **msg) { return rv; } - pmsg_notice2("%s(): got wrong sequence number, %u != %u\n", __func__, r_seqno, PDATA(pgm)->command_sequence); + pmsg_notice2("%s(): got wrong sequence number, %u != %u\n", __func__, r_seqno, my.command_sequence); mmt_free(*msg); } } int jtag3_command(const PROGRAMMER *pgm, unsigned char *cmd, unsigned int cmdlen, - unsigned char **resp, const char *descr) { + unsigned char **resp, const char *descr) { + int status; unsigned char c; @@ -843,13 +825,13 @@ int jtag3_command(const PROGRAMMER *pgm, unsigned char *cmd, unsigned int cmdlen jtag3_send(pgm, cmd, cmdlen); status = jtag3_recv(pgm, resp); - if (status <= 0) { + if(status <= 0) { msg_notice2("\n"); pmsg_notice2("%s command: timeout/error communicating with programmer (status %d)\n", descr, status); - if (status == 0) + if(status == 0) mmt_free(*resp); return LIBAVRDUDE_GENERAL_FAILURE; - } else if (verbose >= MSG_DEBUG) { + } else if(verbose >= MSG_DEBUG) { msg_debug("\n"); jtag3_prmsg(pgm, *resp, status); } else { @@ -857,9 +839,8 @@ int jtag3_command(const PROGRAMMER *pgm, unsigned char *cmd, unsigned int cmdlen } c = (*resp)[1] & RSP3_STATUS_MASK; - if (c != RSP3_OK) { - if ((c == RSP3_FAILED) && - ((*resp)[3] == RSP3_FAIL_OCD_LOCKED || (*resp)[3] == RSP3_FAIL_CRC_FAILURE)) { + if(c != RSP3_OK) { + if((c == RSP3_FAILED) && ((*resp)[3] == RSP3_FAIL_OCD_LOCKED || (*resp)[3] == RSP3_FAIL_CRC_FAILURE)) { pmsg_error("device is locked; chip erase required to unlock\n"); } else { pmsg_notice("bad response to %s command: 0x%02x\n", descr, c); @@ -873,28 +854,25 @@ int jtag3_command(const PROGRAMMER *pgm, unsigned char *cmd, unsigned int cmdlen return status; } - int jtag3_getsync(const PROGRAMMER *pgm, int mode) { unsigned char buf[3], *resp; pmsg_debug("jtag3_getsync()\n"); - /* XplainedMini boards do not need this, and early revisions had a - * firmware bug where they complained about it. */ - if ((pgm->flag & PGM_FL_IS_EDBG) && - !str_starts(pgmid, "xplainedmini")) { - if (jtag3_edbg_prepare(pgm) < 0) { + // XplainedMini boards do not need this, and early revisions had a FW bug that complained about it + if((pgm->flag & PGM_FL_IS_EDBG) && !str_starts(pgmid, "xplainedmini")) { + if(jtag3_edbg_prepare(pgm) < 0) { return -1; } } - /* Get the sign-on information. */ + // Get the sign-on information buf[0] = SCOPE_GENERAL; buf[1] = CMD3_SIGN_ON; buf[2] = 0; - if (jtag3_command(pgm, buf, 3, &resp, "sign-on") < 0) + if(jtag3_command(pgm, buf, 3, &resp, "sign-on") < 0) return -1; mmt_free(resp); @@ -902,9 +880,7 @@ int jtag3_getsync(const PROGRAMMER *pgm, int mode) { return 0; } -/* - * issue the 'chip erase' command to the AVR device - */ +// Issue the 'chip erase' command to the AVR device static int jtag3_chip_erase(const PROGRAMMER *pgm, const AVRPART *p) { unsigned char buf[8], *resp; @@ -912,46 +888,41 @@ static int jtag3_chip_erase(const PROGRAMMER *pgm, const AVRPART *p) { buf[1] = CMD3_ERASE_MEMORY; buf[2] = 0; buf[3] = XMEGA_ERASE_CHIP; - buf[4] = buf[5] = buf[6] = buf[7] = 0; /* page address */ + buf[4] = buf[5] = buf[6] = buf[7] = 0; // Page address - if (jtag3_command(pgm, buf, 8, &resp, "chip erase") < 0) + if(jtag3_command(pgm, buf, 8, &resp, "chip erase") < 0) return -1; mmt_free(resp); return 0; } -/* - * UPDI 'unlock' -> 'enter progmode' with chip erase key - */ +// UPDI 'unlock' -> 'enter progmode' with chip erase key static int jtag3_unlock_erase_key(const PROGRAMMER *pgm, const AVRPART *p) { unsigned char buf[8], *resp; - buf[0] = 1; /* Enable */ - if (jtag3_setparm(pgm, SCOPE_AVR, SET_GET_CTXT_OPTIONS, PARM3_OPT_CHIP_ERASE_TO_ENTER, buf, 1) < 0) + buf[0] = 1; // Enable + if(jtag3_setparm(pgm, SCOPE_AVR, SET_GET_CTXT_OPTIONS, PARM3_OPT_CHIP_ERASE_TO_ENTER, buf, 1) < 0) return -1; buf[0] = SCOPE_AVR; buf[1] = CMD3_ENTER_PROGMODE; buf[2] = 0; - if (jtag3_command(pgm, buf, 3, &resp, "enter progmode") < 0) + if(jtag3_command(pgm, buf, 3, &resp, "enter progmode") < 0) return -1; mmt_free(resp); - PDATA(pgm)->prog_enabled = 1; + my.prog_enabled = 1; - buf[0] = 0; /* Disable */ - if (jtag3_setparm(pgm, SCOPE_AVR, SET_GET_CTXT_OPTIONS, PARM3_OPT_CHIP_ERASE_TO_ENTER, buf, 1) < 0) + buf[0] = 0; // Disable + if(jtag3_setparm(pgm, SCOPE_AVR, SET_GET_CTXT_OPTIONS, PARM3_OPT_CHIP_ERASE_TO_ENTER, buf, 1) < 0) return -1; return 0; } - -/* - * There is no chip erase functionality in debugWire mode. - */ +// There is no chip erase functionality in debugWire mode static int jtag3_chip_erase_dw(const PROGRAMMER *pgm, const AVRPART *p) { pmsg_error("chip erase not supported in debugWire mode\n"); return 0; @@ -965,16 +936,16 @@ static int jtag3_program_enable(const PROGRAMMER *pgm) { unsigned char buf[3], *resp; int status; - if (PDATA(pgm)->prog_enabled) + if(my.prog_enabled) return 0; buf[0] = SCOPE_AVR; buf[1] = CMD3_ENTER_PROGMODE; buf[2] = 0; - if ((status = jtag3_command(pgm, buf, 3, &resp, "enter progmode")) >= 0) { + if((status = jtag3_command(pgm, buf, 3, &resp, "enter progmode")) >= 0) { mmt_free(resp); - PDATA(pgm)->prog_enabled = 1; + my.prog_enabled = 1; return LIBAVRDUDE_SUCCESS; } @@ -985,19 +956,19 @@ static int jtag3_program_enable(const PROGRAMMER *pgm) { static int jtag3_program_disable(const PROGRAMMER *pgm) { unsigned char buf[3], *resp; - if (!PDATA(pgm)->prog_enabled) + if(!my.prog_enabled) return 0; buf[0] = SCOPE_AVR; buf[1] = CMD3_LEAVE_PROGMODE; buf[2] = 0; - if (jtag3_command(pgm, buf, 3, &resp, "leave progmode") < 0) + if(jtag3_command(pgm, buf, 3, &resp, "leave progmode") < 0) return -1; mmt_free(resp); - PDATA(pgm)->prog_enabled = 0; + my.prog_enabled = 0; return 0; } @@ -1014,10 +985,7 @@ static int jtag3_set_sck_mega_jtag(const PROGRAMMER *pgm, unsigned char *clk) { return jtag3_setparm(pgm, SCOPE_AVR, 1, PARM3_CLK_MEGA_PROG, clk, 2); } - -/* - * initialize the AVR device and prepare it to accept commands - */ +// Initialize the AVR device and prepare it to accept commands static int jtag3_initialize(const PROGRAMMER *pgm, const AVRPART *p) { unsigned char conn = 0, parm[4]; const char *ifname; @@ -1025,23 +993,22 @@ static int jtag3_initialize(const PROGRAMMER *pgm, const AVRPART *p) { int status; /* - * At least, as of firmware 2.12, the JTAGICE3 doesn't handle - * splitting packets correctly. On a large transfer, the first - * split packets are correct, but remaining packets contain just - * garbage. + * At least, as of firmware 2.12, the JTAGICE3 doesn't handle splitting + * packets correctly. On a large transfer, the first split packets are + * correct, but remaining packets contain just garbage. * - * We move the check here so in case future firmware versions fix - * this, the check below can be made dependended on the actual - * firmware level. Retrieving the firmware version can always be - * accomplished with USB 1.1 (64 byte max) packets. + * We move the check here so in case future firmware versions fix this, the + * check below can be made dependended on the actual firmware level. + * Retrieving the firmware version can always be accomplished with USB 1.1 + * (64 byte max) packets. * - * Allow to override the check by -F (so users could try on newer - * firmware), but warn loudly. + * Allow to override the check by -F (so users could try on newer firmware), + * but warn loudly. */ - if (jtag3_getparm(pgm, SCOPE_GENERAL, 0, PARM3_FW_MAJOR, parm, 2) < 0) + if(jtag3_getparm(pgm, SCOPE_GENERAL, 0, PARM3_FW_MAJOR, parm, 2) < 0) return -1; - if (pgm->fd.usb.max_xfer < USBDEV_MAX_XFER_3 && (pgm->flag & PGM_FL_IS_EDBG) == 0) { - if (ovsigck) { + if(pgm->fd.usb.max_xfer < USBDEV_MAX_XFER_3 && (pgm->flag & PGM_FL_IS_EDBG) == 0) { + if(ovsigck) { pmsg_warning("JTAGICE3's firmware %d.%d is broken on USB 1.1 connections\n", parm[0], parm[1]); imsg_warning("forced to continue by option -F; this puts the device's data integrity at risk!\n"); } else { @@ -1050,176 +1017,186 @@ static int jtag3_initialize(const PROGRAMMER *pgm, const AVRPART *p) { } } - if (pgm->flag & PGM_FL_IS_DW) { + if(pgm->flag & PGM_FL_IS_DW) { ifname = "debugWire"; - if (p->prog_modes & PM_debugWIRE) + if(is_debugwire(p)) conn = PARM3_CONN_DW; - } else if (pgm->flag & PGM_FL_IS_PDI) { + } else if(pgm->flag & PGM_FL_IS_PDI) { ifname = "PDI"; - if (p->prog_modes & PM_PDI) + if(is_pdi(p)) conn = PARM3_CONN_PDI; - } else if (pgm->flag & PGM_FL_IS_UPDI) { + } else if(pgm->flag & PGM_FL_IS_UPDI) { ifname = "UPDI"; - if (p->prog_modes & PM_UPDI) + if(is_updi(p)) conn = PARM3_CONN_UPDI; } else { ifname = "JTAG"; - if (p->prog_modes & (PM_JTAG | PM_JTAGmkI | PM_XMEGAJTAG | PM_AVR32JTAG)) + if(p->prog_modes & (PM_JTAG | PM_JTAGmkI | PM_XMEGAJTAG | PM_AVR32JTAG)) conn = PARM3_CONN_JTAG; } - if (conn == 0) { + if(conn == 0) { pmsg_error("part %s has no %s interface\n", p->desc, ifname); return -1; } - if (p->prog_modes & PM_PDI) + if(is_pdi(p)) parm[0] = PARM3_ARCH_XMEGA; - else if (p->prog_modes & PM_UPDI) + else if(is_updi(p)) parm[0] = PARM3_ARCH_UPDI; - else if (p->prog_modes & PM_debugWIRE) + else if(is_debugwire(p)) parm[0] = PARM3_ARCH_TINY; else parm[0] = PARM3_ARCH_MEGA; - if (jtag3_setparm(pgm, SCOPE_AVR, 0, PARM3_ARCH, parm, 1) < 0) + if(jtag3_setparm(pgm, SCOPE_AVR, 0, PARM3_ARCH, parm, 1) < 0) return -1; parm[0] = PARM3_SESS_PROGRAMMING; - if (jtag3_setparm(pgm, SCOPE_AVR, 0, PARM3_SESS_PURPOSE, parm, 1) < 0) + if(jtag3_setparm(pgm, SCOPE_AVR, 0, PARM3_SESS_PURPOSE, parm, 1) < 0) return -1; parm[0] = conn; - if (jtag3_setparm(pgm, SCOPE_AVR, 1, PARM3_CONNECTION, parm, 1) < 0) + if(jtag3_setparm(pgm, SCOPE_AVR, 1, PARM3_CONNECTION, parm, 1) < 0) return -1; - if (conn == PARM3_CONN_PDI || conn == PARM3_CONN_UPDI) - PDATA(pgm)->set_sck = jtag3_set_sck_xmega_pdi; - else if (conn == PARM3_CONN_JTAG) { - if (p->prog_modes & PM_PDI) - PDATA(pgm)->set_sck = jtag3_set_sck_xmega_jtag; + if(conn == PARM3_CONN_PDI || conn == PARM3_CONN_UPDI) + my.set_sck = jtag3_set_sck_xmega_pdi; + else if(conn == PARM3_CONN_JTAG) { + if(is_pdi(p)) + my.set_sck = jtag3_set_sck_xmega_jtag; else - PDATA(pgm)->set_sck = jtag3_set_sck_mega_jtag; + my.set_sck = jtag3_set_sck_mega_jtag; } - if (pgm->bitclock != 0.0 && PDATA(pgm)->set_sck != NULL) { - unsigned int clock = 1E-3 / pgm->bitclock; /* kHz */ + if(pgm->bitclock != 0.0 && my.set_sck != NULL) { + unsigned int clock = 1E-3/pgm->bitclock; // kHz + pmsg_notice2("%s(): trying to set JTAG clock to %u kHz\n", __func__, clock); parm[0] = clock & 0xff; parm[1] = (clock >> 8) & 0xff; - if (PDATA(pgm)->set_sck(pgm, parm) < 0) + if(my.set_sck(pgm, parm) < 0) return -1; } - if (conn == PARM3_CONN_JTAG) { + if(conn == PARM3_CONN_JTAG) { pmsg_notice2("%s(): trying to set JTAG daisy-chain info to %d,%d,%d,%d\n", __func__, - PDATA(pgm)->jtagchain[0], PDATA(pgm)->jtagchain[1], - PDATA(pgm)->jtagchain[2], PDATA(pgm)->jtagchain[3]); - if (jtag3_setparm(pgm, SCOPE_AVR, 1, PARM3_JTAGCHAIN, PDATA(pgm)->jtagchain, 4) < 0) + my.jtagchain[0], my.jtagchain[1], my.jtagchain[2], my.jtagchain[3]); + if(jtag3_setparm(pgm, SCOPE_AVR, 1, PARM3_JTAGCHAIN, my.jtagchain, 4) < 0) return -1; } - if (verbose > 0 && quell_progress < 2) + if(verbose > 0 && quell_progress < 2) jtag3_print_parms1(pgm, progbuf, stderr); // Read or write SUFFER register - if (PDATA(pgm)->suffer_get || PDATA(pgm)->suffer_set) { + if(my.suffer_get || my.suffer_set) { // Read existing SUFFER value - if (jtag3_getparm(pgm, SCOPE_EDBG, MEDBG_REG_SUFFER_BANK + 0x10, MEDBG_REG_SUFFER_OFFSET, PDATA(pgm)->suffer_data, 1) < 0) + if(jtag3_getparm(pgm, SCOPE_EDBG, MEDBG_REG_SUFFER_BANK + 0x10, + MEDBG_REG_SUFFER_OFFSET, my.suffer_data, 1) < 0) { return -1; - if (!PDATA(pgm)->suffer_set) - msg_info("SUFFER register value read as 0x%02x\n", PDATA(pgm)->suffer_data[0]); + } + if(!my.suffer_set) + msg_info("SUFFER register value read as 0x%02x\n", my.suffer_data[0]); // Write new SUFFER value else { - if (jtag3_setparm(pgm, SCOPE_EDBG, MEDBG_REG_SUFFER_BANK + 0x10, MEDBG_REG_SUFFER_OFFSET, PDATA(pgm)->suffer_data+1, 1) < 0) + if(jtag3_setparm(pgm, SCOPE_EDBG, MEDBG_REG_SUFFER_BANK + 0x10, + MEDBG_REG_SUFFER_OFFSET, my.suffer_data + 1, 1) < 0) { return -1; - msg_info("SUFFER register value changed from 0x%02x to 0x%02x\n", PDATA(pgm)->suffer_data[0], PDATA(pgm)->suffer_data[1]); + } + msg_info("SUFFER register value changed from 0x%02x to 0x%02x\n", + my.suffer_data[0], my.suffer_data[1]); } } - // Read or write Vtarg switch - if (PDATA(pgm)->vtarg_switch_get || PDATA(pgm)->vtarg_switch_set) { + if(my.vtarg_switch_get || my.vtarg_switch_set) { // Read existing Vtarg switch value - if (jtag3_getparm(pgm, SCOPE_EDBG, EDBG_CTXT_CONTROL, EDBG_CONTROL_TARGET_POWER, PDATA(pgm)->vtarg_switch_data, 1) < 0) + if(jtag3_getparm(pgm, SCOPE_EDBG, EDBG_CTXT_CONTROL, + EDBG_CONTROL_TARGET_POWER, my.vtarg_switch_data, 1) < 0) { return -1; - if (!PDATA(pgm)->vtarg_switch_set) - msg_info("Vtarg switch setting read as %u: target power is switched %s\n", PDATA(pgm)->vtarg_switch_data[0], PDATA(pgm)->vtarg_switch_data[0] ? "on" : "off"); + } + if(!my.vtarg_switch_set) + msg_info("Vtarg switch setting read as %u: target power is switched %s\n", my.vtarg_switch_data[0], + my.vtarg_switch_data[0]? "on": "off"); // Write Vtarg switch value else { - if (jtag3_setparm(pgm, SCOPE_EDBG, EDBG_CTXT_CONTROL, EDBG_CONTROL_TARGET_POWER, PDATA(pgm)->vtarg_switch_data+1, 1) < 0) + if(jtag3_setparm(pgm, SCOPE_EDBG, EDBG_CTXT_CONTROL, + EDBG_CONTROL_TARGET_POWER, my.vtarg_switch_data + 1, 1) < 0) { return -1; - imsg_info("Vtarg switch setting changed from %u to %u\n", PDATA(pgm)->vtarg_switch_data[0], PDATA(pgm)->vtarg_switch_data[1]); + } + imsg_info("Vtarg switch setting changed from %u to %u\n", my.vtarg_switch_data[0], + my.vtarg_switch_data[1]); // Exit early is the target power switch is off and print sensible info message - if (PDATA(pgm)->vtarg_switch_data[1] == 0) { + if(my.vtarg_switch_data[1] == 0) { pmsg_info("turn on the Vtarg switch to establish connection with the target\n\n"); return -1; } } } - // Read or write target voltage - if (PDATA(pgm)->vtarg_get || PDATA(pgm)->vtarg_set) { + if(my.vtarg_get || my.vtarg_set) { // Read current target voltage set value unsigned char buf[2]; - if (jtag3_getparm(pgm, SCOPE_GENERAL, 1, PARM3_VADJUST, buf, 2) < 0) + + if(jtag3_getparm(pgm, SCOPE_GENERAL, 1, PARM3_VADJUST, buf, 2) < 0) return -1; - double vtarg_read = b2_to_u16(buf) / 1000.0; - if (PDATA(pgm)->vtarg_get) + double vtarg_read = b2_to_u16(buf)/1000.0; + + if(my.vtarg_get) msg_info("Target voltage value read as %.2fV\n", vtarg_read); // Write target voltage value else { - u16_to_b2(buf, (unsigned)(PDATA(pgm)->vtarg_data * 1000)); - msg_info("Changing target voltage from %.2f to %.2fV\n", vtarg_read, PDATA(pgm)->vtarg_data); - if (jtag3_setparm(pgm, SCOPE_GENERAL, 1, PARM3_VADJUST, buf, sizeof(buf)) < 0) { - msg_warning("Cannot set target voltage %.2fV\n", PDATA(pgm)->vtarg_data); + u16_to_b2(buf, (unsigned) (my.vtarg_data*1000)); + msg_info("Changing target voltage from %.2f to %.2fV\n", vtarg_read, my.vtarg_data); + if(jtag3_setparm(pgm, SCOPE_GENERAL, 1, PARM3_VADJUST, buf, sizeof(buf)) < 0) { + msg_warning("Cannot set target voltage %.2fV\n", my.vtarg_data); return -1; } } } - /* set device descriptor data */ - if ((p->prog_modes & PM_PDI)) { + // Set device descriptor data + if(is_pdi(p)) { struct xmega_device_desc xd; LNODEID ln; - AVRMEM * m; + AVRMEM *m; int fuseinit = 0; u16_to_b2(xd.nvm_base_addr, p->nvm_base); u16_to_b2(xd.mcu_base_addr, p->mcu_base); - for (ln = lfirst(p->mem); ln; ln = lnext(ln)) { + for(ln = lfirst(p->mem); ln; ln = lnext(ln)) { m = ldata(ln); - if (mem_is_flash(m)) { - if (m->readsize != 0 && m->readsize < m->page_size) - PDATA(pgm)->flash_pagesize = m->readsize; + if(mem_is_flash(m)) { + if(m->readsize != 0 && m->readsize < m->page_size) + my.flash_pagesize = m->readsize; else - PDATA(pgm)->flash_pagesize = m->page_size; + my.flash_pagesize = m->page_size; u16_to_b2(xd.flash_page_size, m->page_size); - } else if (mem_is_eeprom(m)) { - PDATA(pgm)->eeprom_pagesize = m->page_size; + } else if(mem_is_eeprom(m)) { + my.eeprom_pagesize = m->page_size; xd.eeprom_page_size = m->page_size; u16_to_b2(xd.eeprom_size, m->size); u32_to_b4(xd.nvm_eeprom_offset, m->offset); - } else if (mem_is_application(m)) { + } else if(mem_is_application(m)) { u32_to_b4(xd.app_size, m->size); u32_to_b4(xd.nvm_app_offset, m->offset); - } else if (mem_is_boot(m)) { + } else if(mem_is_boot(m)) { u16_to_b2(xd.boot_size, m->size); u32_to_b4(xd.nvm_boot_offset, m->offset); - } else if (mem_is_a_fuse(m) && !fuseinit++) { // Any fuse is OK + } else if(mem_is_a_fuse(m) && !fuseinit++) { // Any fuse is OK u32_to_b4(xd.nvm_fuse_offset, m->offset & ~15); - } else if (mem_is_lock(m)) { + } else if(mem_is_lock(m)) { u32_to_b4(xd.nvm_lock_offset, m->offset); - } else if (mem_is_userrow(m)) { + } else if(mem_is_userrow(m)) { u32_to_b4(xd.nvm_user_sig_offset, m->offset); - } else if (mem_is_sigrow(m)) { + } else if(mem_is_sigrow(m)) { u32_to_b4(xd.nvm_prod_sig_offset, m->offset); } } u32_to_b4(xd.nvm_data_offset, DATA_OFFSET); - if (jtag3_setparm(pgm, SCOPE_AVR, 2, PARM3_DEVICEDESC, (unsigned char *)&xd, sizeof xd) < 0) + if(jtag3_setparm(pgm, SCOPE_AVR, 2, PARM3_DEVICEDESC, (unsigned char *) &xd, sizeof xd) < 0) return -1; - } - else if ((p->prog_modes & PM_UPDI)) { + } else if(is_updi(p)) { struct updi_device_desc xd; LNODEID ln; AVRMEM *m; @@ -1228,68 +1205,61 @@ static int jtag3_initialize(const PROGRAMMER *pgm, const AVRPART *p) { u16_to_b2(xd.ocd_base_addr, p->ocd_base); xd.hvupdi_variant = p->hvupdi_variant; - for (ln = lfirst(p->mem); ln; ln = lnext(ln)) { + for(ln = lfirst(p->mem); ln; ln = lnext(ln)) { m = ldata(ln); - if (mem_is_flash(m)) { - u16_to_b2(xd.prog_base, m->offset&0xFFFF); - xd.prog_base_msb = m->offset>>16; + if(mem_is_flash(m)) { + u16_to_b2(xd.prog_base, m->offset & 0xFFFF); + xd.prog_base_msb = m->offset >> 16; - if (m->readsize != 0 && m->readsize < m->page_size) - PDATA(pgm)->flash_pagesize = m->readsize; + if(m->readsize != 0 && m->readsize < m->page_size) + my.flash_pagesize = m->readsize; else - PDATA(pgm)->flash_pagesize = m->page_size; + my.flash_pagesize = m->page_size; xd.flash_page_size = m->page_size & 0xFF; - xd.flash_page_size_msb = (m->page_size)>>8; + xd.flash_page_size_msb = (m->page_size) >> 8; u32_to_b4(xd.flash_bytes, m->size); - if (m->offset > 0xFFFF) + if(m->offset > 0xFFFF) xd.address_mode = UPDI_ADDRESS_MODE_24BIT; else xd.address_mode = UPDI_ADDRESS_MODE_16BIT; - } - else if (mem_is_eeprom(m)) { - PDATA(pgm)->eeprom_pagesize = m->page_size; + } else if(mem_is_eeprom(m)) { + my.eeprom_pagesize = m->page_size; xd.eeprom_page_size = m->page_size; u16_to_b2(xd.eeprom_bytes, m->size); u16_to_b2(xd.eeprom_base, m->offset); - } - else if (mem_is_userrow(m)) { + } else if(mem_is_userrow(m)) { u16_to_b2(xd.user_sig_bytes, m->size); u16_to_b2(xd.user_sig_base, m->offset); - } - else if (mem_is_signature(m)) { + } else if(mem_is_signature(m)) { u16_to_b2(xd.signature_base, m->offset); xd.device_id[0] = p->signature[1]; xd.device_id[1] = p->signature[2]; - } - else if (mem_is_fuses(m)) { + } else if(mem_is_fuses(m)) { xd.fuses_bytes = m->size; u16_to_b2(xd.fuses_base, m->offset); - } - else if (mem_is_lock(m)) { + } else if(mem_is_lock(m)) { u16_to_b2(xd.lockbits_base, m->offset); } } // Generate UPDI high-voltage pulse if user asks for it and hardware supports it - if (PDATA(pgm)->use_hvupdi == true && - p->hvupdi_variant != HV_UPDI_VARIANT_1) { + if(my.use_hvupdi == true && p->hvupdi_variant != HV_UPDI_VARIANT_1) { parm[0] = PARM3_UPDI_HV_NONE; - for (LNODEID ln = lfirst(pgm->hvupdi_support); ln; ln = lnext(ln)) { + for(LNODEID ln = lfirst(pgm->hvupdi_support); ln; ln = lnext(ln)) { if(*(int *) ldata(ln) == p->hvupdi_variant) { - pmsg_notice("sending HV pulse to targets %s pin\n", - p->hvupdi_variant == HV_UPDI_VARIANT_0? "UPDI": "RESET"); + pmsg_notice("sending HV pulse to targets %s pin\n", p->hvupdi_variant == HV_UPDI_VARIANT_0? "UPDI": "RESET"); parm[0] = PARM3_UPDI_HV_SIMPLE_PULSE; break; } } - if (parm[0] == PARM3_UPDI_HV_NONE) { + if(parm[0] == PARM3_UPDI_HV_NONE) { pmsg_error("%s does not support sending HV pulse to target %s\n", pgm->desc, p->desc); return -1; } - if (jtag3_setparm(pgm, SCOPE_AVR, 3, PARM3_OPT_12V_UPDI_ENABLE, parm, 1) < 0) + if(jtag3_setparm(pgm, SCOPE_AVR, 3, PARM3_OPT_12V_UPDI_ENABLE, parm, 1) < 0) return -1; } @@ -1317,52 +1287,49 @@ static int jtag3_initialize(const PROGRAMMER *pgm, const AVRPART *p) { xd.prog_base[0], xd.prog_base[1], xd.flash_page_size_msb, xd.flash_page_size, - xd.eeprom_page_size, - xd.nvm_base_addr[0], xd.nvm_base_addr[1], - xd.ocd_base_addr[0], xd.ocd_base_addr[1], - xd.address_mode); + xd.eeprom_page_size, xd.nvm_base_addr[0], xd.nvm_base_addr[1], + xd.ocd_base_addr[0], xd.ocd_base_addr[1], xd.address_mode); - if (jtag3_setparm(pgm, SCOPE_AVR, 2, PARM3_DEVICEDESC, (unsigned char *)&xd, sizeof xd) < 0) + if(jtag3_setparm(pgm, SCOPE_AVR, 2, PARM3_DEVICEDESC, (unsigned char *) &xd, sizeof xd) < 0) return -1; - } - else { + } else { struct mega_device_desc md; LNODEID ln; - AVRMEM * m; + AVRMEM *m; unsigned int flashsize = 0; memset(&md, 0, sizeof md); - for (ln = lfirst(p->mem); ln; ln = lnext(ln)) { + for(ln = lfirst(p->mem); ln; ln = lnext(ln)) { m = ldata(ln); - if (mem_is_flash(m)) { - if (m->readsize != 0 && m->readsize < m->page_size) - PDATA(pgm)->flash_pagesize = m->readsize; + if(mem_is_flash(m)) { + if(m->readsize != 0 && m->readsize < m->page_size) + my.flash_pagesize = m->readsize; else - PDATA(pgm)->flash_pagesize = m->page_size; + my.flash_pagesize = m->page_size; u16_to_b2(md.flash_page_size, m->page_size); u32_to_b4(md.flash_size, (flashsize = m->size)); - // do we need it? just a wild guess - u32_to_b4(md.boot_address, (m->size - m->page_size * 4) / 2); - } else if (mem_is_eeprom(m)) { - PDATA(pgm)->eeprom_pagesize = m->page_size; + // Do we need it? Just a wild guess + u32_to_b4(md.boot_address, (m->size - m->page_size*4)/2); + } else if(mem_is_eeprom(m)) { + my.eeprom_pagesize = m->page_size; md.eeprom_page_size = m->page_size; u16_to_b2(md.eeprom_size, m->size); } } - u16_to_b2(md.sram_offset, 0x100); // do we need it? YES, but it won't be used + u16_to_b2(md.sram_offset, 0x100); // Do we need it? YES, but it won't be used - if (p->ocdrev == -1) { + if(p->ocdrev == -1) { int ocdrev; - /* lacking a proper definition, guess the OCD revision */ - if (p->prog_modes & PM_debugWIRE) - ocdrev = 1; /* exception: ATtiny13, 2313, 4313 */ - else if (flashsize > 128 * 1024) + // Lacking a proper definition, guess the OCD revision + if(is_debugwire(p)) + ocdrev = 1; // Exception: ATtiny13, 2313, 4313 + else if(flashsize > 128*1024) ocdrev = 4; else - ocdrev = 3; /* many exceptions from that, actually */ + ocdrev = 3; // Many exceptions from that, actually pmsg_warning("part definition for %s lacks ocdrev; guessing %d\n", p->desc, ocdrev); md.ocd_revision = ocdrev; } else { @@ -1372,115 +1339,111 @@ static int jtag3_initialize(const PROGRAMMER *pgm, const AVRPART *p) { md.allow_full_page_bitstream = (p->flags & AVRPART_ALLOWFULLPAGEBITSTREAM) != 0; md.idr_address = p->idr; - unsigned char eecr = p->eecr? p->eecr: 0x3f; // Use default 0x3f if not set + unsigned char eecr = p->eecr? p->eecr: 0x3f; // Use default 0x3f if not set + md.eearh_address = eecr - 0x20 + 3; md.eearl_address = eecr - 0x20 + 2; md.eecr_address = eecr - 0x20; md.eedr_address = eecr - 0x20 + 1; md.spmcr_address = p->spmcr; - //md.osccal_address = p->osccal; // do we need it at all? + // md.osccal_address = p->osccal; // Do we need it at all? - if (jtag3_setparm(pgm, SCOPE_AVR, 2, PARM3_DEVICEDESC, (unsigned char *)&md, sizeof md) < 0) + if(jtag3_setparm(pgm, SCOPE_AVR, 2, PARM3_DEVICEDESC, (unsigned char *) &md, sizeof md) < 0) return -1; } int use_ext_reset; - for (use_ext_reset = 0; use_ext_reset <= 1; use_ext_reset++) { + for(use_ext_reset = 0; use_ext_reset <= 1; use_ext_reset++) { cmd[0] = SCOPE_AVR; cmd[1] = CMD3_SIGN_ON; cmd[2] = 0; - cmd[3] = use_ext_reset; /* external reset */ + cmd[3] = use_ext_reset; // External reset - if ((status = jtag3_command(pgm, cmd, 4, &resp, "AVR sign-on")) >= 0) + if((status = jtag3_command(pgm, cmd, 4, &resp, "AVR sign-on")) >= 0) break; pmsg_notice("retrying with external reset applied\n"); } - if (use_ext_reset > 1) { + if(use_ext_reset > 1) { if(str_eq(pgm->type, "JTAGICE3") && (p->prog_modes & (PM_JTAG | PM_JTAGmkI | PM_XMEGAJTAG | PM_AVR32JTAG))) pmsg_error("JTAGEN fuse disabled?\n"); return -1; } /* - * Depending on the target connection, there are three different - * possible replies of the ICE. For a JTAG connection, the reply - * format is RSP3_DATA, followed by 4 bytes of the JTAG ID read from - * the device (followed by a trailing 0). - * For a UPDI connection the reply format is RSP3_DATA, followed by - * 4 bytes of the SIB Family_ID read from the device (followed by a - * trailing 0). - * For all other connections - * (except ISP which is handled completely differently, but that - * doesn't apply here anyway), the response is just RSP_OK. + * Depending on the target connection, there are three different possible + * replies of the ICE. For a JTAG connection, the reply format is RSP3_DATA, + * followed by 4 bytes of the JTAG ID read from the device (followed by a + * trailing 0). For a UPDI connection the reply format is RSP3_DATA, followed + * by 4 bytes of the SIB Family_ID read from the device (followed by a + * trailing 0). For all other connections (except ISP which is handled + * completely differently, but that doesn't apply here anyway), the response + * is just RSP_OK. */ - if (resp[1] == RSP3_DATA && status >= 7) { - if (p->prog_modes & PM_UPDI) { - /* Partial Family_ID has been returned */ - pmsg_notice("partial Family_ID returned: \"%c%c%c%c\"\n", - resp[3], resp[4], resp[5], resp[6]); - } - else - /* JTAG ID has been returned */ - pmsg_notice("JTAG ID returned: 0x%02x 0x%02x 0x%02x 0x%02x\n", - resp[3], resp[4], resp[5], resp[6]); + if(resp[1] == RSP3_DATA && status >= 7) { + if(is_updi(p)) { + // Partial Family_ID has been returned + pmsg_notice("partial Family_ID returned: \"%c%c%c%c\"\n", resp[3], resp[4], resp[5], resp[6]); + } else + // JTAG ID has been returned + pmsg_notice("JTAG ID returned: 0x%02x 0x%02x 0x%02x 0x%02x\n", resp[3], resp[4], resp[5], resp[6]); } mmt_free(resp); - if (pgm->read_sib) { - if (pgm->read_sib(pgm, p, PDATA(pgm)->sib_string) < 0) { + if(pgm->read_sib) { + if(pgm->read_sib(pgm, p, my.sib_string) < 0) { pmsg_warning("cannot read SIB string from target %s\n", p->desc); } } - // Read chip silicon revision if(pgm->read_chip_rev && p->prog_modes & (PM_PDI | PM_UPDI)) { unsigned char chip_rev[AVR_CHIP_REVLEN]; + pgm->read_chip_rev(pgm, p, chip_rev); pmsg_notice("silicon revision: %x.%x\n", chip_rev[0] >> 4, chip_rev[0] & 0x0f); } - PDATA(pgm)->boot_start = ULONG_MAX; - if (p->prog_modes & PM_PDI) { + my.boot_start = ULONG_MAX; + if(is_pdi(p)) { // Find the border between application and boot area AVRMEM *bootmem = avr_locate_boot(p); AVRMEM *flashmem = avr_locate_flash(p); - if (bootmem == NULL || flashmem == NULL) { + + if(bootmem == NULL || flashmem == NULL) { pmsg_error("cannot locate flash or boot memories in description\n"); } else { - PDATA(pgm)->boot_start = bootmem->offset - flashmem->offset; + my.boot_start = bootmem->offset - flashmem->offset; } } - mmt_free(PDATA(pgm)->flash_pagecache); - mmt_free(PDATA(pgm)->eeprom_pagecache); - PDATA(pgm)->flash_pagecache = mmt_malloc(PDATA(pgm)->flash_pagesize); - PDATA(pgm)->eeprom_pagecache = mmt_malloc(PDATA(pgm)->eeprom_pagesize); - PDATA(pgm)->flash_pageaddr = PDATA(pgm)->eeprom_pageaddr = ~0UL; + mmt_free(my.flash_pagecache); + mmt_free(my.eeprom_pagecache); + my.flash_pagecache = mmt_malloc(my.flash_pagesize); + my.eeprom_pagecache = mmt_malloc(my.eeprom_pagesize); + my.flash_pageaddr = my.eeprom_pageaddr = ~0UL; return 0; } static void jtag3_disable(const PROGRAMMER *pgm) { - mmt_free(PDATA(pgm)->flash_pagecache); - PDATA(pgm)->flash_pagecache = NULL; - mmt_free(PDATA(pgm)->eeprom_pagecache); - PDATA(pgm)->eeprom_pagecache = NULL; + mmt_free(my.flash_pagecache); + my.flash_pagecache = NULL; + mmt_free(my.eeprom_pagecache); + my.eeprom_pagecache = NULL; /* - * jtag3_program_disable() doesn't do anything if the - * device is currently not in programming mode, so just - * call it unconditionally here. + * jtag3_program_disable() doesn't do anything if the device is currently not + * in programming mode, so just call it unconditionally here. */ - (void)jtag3_program_disable(pgm); + (void) jtag3_program_disable(pgm); } static void jtag3_enable(PROGRAMMER *pgm, const AVRPART *p) { // Page erase only useful for classic parts with usersig mem or AVR8X/XMEGAs - if(p->prog_modes & PM_Classic) + if(is_classic(p)) if(!avr_locate_usersig(p)) pgm->page_erase = NULL; } @@ -1494,21 +1457,20 @@ static int jtag3_parseextparms(const PROGRAMMER *pgm, const LISTID extparms) { if(str_starts(extended_param, "jtagchain=") && (pgm->prog_modes & (PM_JTAG | PM_XMEGAJTAG | PM_AVR32JTAG))) { unsigned int ub, ua, bb, ba; + if(sscanf(extended_param, "jtagchain=%u,%u,%u,%u", &ub, &ua, &bb, &ba) != 4) { pmsg_error("invalid JTAG chain in -x %s\n", extended_param); rv = -1; break; } pmsg_notice2("%s(): JTAG chain parsed as:\n", __func__); - imsg_notice2("%u units before, %u units after, %u bits before, %u bits after\n", - ub, ua, bb, ba); - PDATA(pgm)->jtagchain[0] = ub; - PDATA(pgm)->jtagchain[1] = ua; - PDATA(pgm)->jtagchain[2] = bb; - PDATA(pgm)->jtagchain[3] = ba; + imsg_notice2("%u units before, %u units after, %u bits before, %u bits after\n", ub, ua, bb, ba); + my.jtagchain[0] = ub; + my.jtagchain[1] = ua; + my.jtagchain[2] = bb; + my.jtagchain[3] = ba; continue; } - // HVUPDI // All programmers that supports UPDI programming should have hvupdi_support=1 in avrdude.conf // Type 0: 12V pulse on UPDI pin @@ -1525,10 +1487,9 @@ static int jtag3_parseextparms(const PROGRAMMER *pgm, const LISTID extparms) { rv = -1; break; } - PDATA(pgm)->use_hvupdi = true; + my.use_hvupdi = true; continue; } - // SUFFER bits // Bit 7 ARDUINO: Adds control of extra LEDs when set to 0 // Bit 6..3: Reserved (must be set to 1) @@ -1539,22 +1500,21 @@ static int jtag3_parseextparms(const PROGRAMMER *pgm, const LISTID extparms) { if(pgm->extra_features & HAS_SUFFER) { // Set SUFFER value if(str_starts(extended_param, "suffer=")) { - if(sscanf(extended_param, "suffer=%hhi", PDATA(pgm)->suffer_data+1) < 1) { + if(sscanf(extended_param, "suffer=%hhi", my.suffer_data + 1) < 1) { pmsg_error("invalid value in -x %s\n", extended_param); rv = -1; break; } - if((PDATA(pgm)->suffer_data[1] & 0x78) != 0x78) { - PDATA(pgm)->suffer_data[1] |= 0x78; - pmsg_info("setting -x suffer=0x%02x so that reserved bits 3..6 are set\n", - PDATA(pgm)->suffer_data[1]); + if((my.suffer_data[1] & 0x78) != 0x78) { + my.suffer_data[1] |= 0x78; + pmsg_info("setting -x suffer=0x%02x so that reserved bits 3..6 are set\n", my.suffer_data[1]); } - PDATA(pgm)->suffer_set = true; + my.suffer_set = true; continue; } // Get SUFFER value if(str_eq(extended_param, "suffer")) { - PDATA(pgm)->suffer_get = true; + my.suffer_get = true; continue; } pmsg_error("invalid setting in -x %s; use -x suffer or -x suffer=\n", extended_param); @@ -1567,18 +1527,19 @@ static int jtag3_parseextparms(const PROGRAMMER *pgm, const LISTID extparms) { if(pgm->extra_features & HAS_VTARG_SWITCH) { // Set Vtarget switch value if(str_starts(extended_param, "vtarg_switch=")) { - int sscanf_success = sscanf(extended_param, "vtarg_switch=%hhi", PDATA(pgm)->vtarg_switch_data+1); - if(sscanf_success < 1 || PDATA(pgm)->vtarg_switch_data[1] > 1) { + int sscanf_success = sscanf(extended_param, "vtarg_switch=%hhi", my.vtarg_switch_data + 1); + + if(sscanf_success < 1 || my.vtarg_switch_data[1] > 1) { pmsg_error("invalid value in -x %s\n", extended_param); rv = -1; break; } - PDATA(pgm)->vtarg_switch_set = true; + my.vtarg_switch_set = true; continue; } // Get Vtarget switch value if(str_eq(extended_param, "vtarg_switch")) { - PDATA(pgm)->vtarg_switch_get = true; + my.vtarg_switch_get = true; continue; } pmsg_error("invalid setting in -x %s; use -x vtarg_switch or -x vtarg_switch=<0..1>\n", extended_param); @@ -1590,21 +1551,22 @@ static int jtag3_parseextparms(const PROGRAMMER *pgm, const LISTID extparms) { if(str_starts(extended_param, "vtarg")) { if(pgm->extra_features & HAS_VTARG_ADJ) { // Set target voltage - if(str_starts(extended_param, "vtarg=") ) { + if(str_starts(extended_param, "vtarg=")) { double vtarg_set_val = 0; int sscanf_success = sscanf(extended_param, "vtarg=%lf", &vtarg_set_val); - PDATA(pgm)->vtarg_data = (double)((int)(vtarg_set_val * 100 + .5)) / 100; + + my.vtarg_data = (double) ((int) (vtarg_set_val*100 + .5))/100; if(sscanf_success < 1 || vtarg_set_val < 0) { pmsg_error("invalid value in -x %s\n", extended_param); rv = -1; break; } - PDATA(pgm)->vtarg_set = true; + my.vtarg_set = true; continue; } // Get target voltage else if(str_eq(extended_param, "vtarg")) { - PDATA(pgm)->vtarg_get = true; + my.vtarg_get = true; continue; } pmsg_error("invalid setting in -x %s; use -x vtarg or -x vtarg=\n", extended_param); @@ -1613,16 +1575,15 @@ static int jtag3_parseextparms(const PROGRAMMER *pgm, const LISTID extparms) { } } - if(str_starts(extended_param, "mode") && - (str_starts(pgmid, "pickit4") || str_starts(pgmid, "snap"))) { + if(str_starts(extended_param, "mode") && (str_starts(pgmid, "pickit4") || str_starts(pgmid, "snap"))) { // Flag a switch to AVR mode if(str_caseeq(extended_param, "mode=avr")) { - PDATA(pgm)->pk4_snap_mode = PK4_SNAP_MODE_AVR; + my.pk4_snap_mode = PK4_SNAP_MODE_AVR; continue; } // Flag a switch to PIC mode if(str_caseeq(extended_param, "mode=pic")) { - PDATA(pgm)->pk4_snap_mode = PK4_SNAP_MODE_PIC; + my.pk4_snap_mode = PK4_SNAP_MODE_PIC; continue; } pmsg_error("invalid setting in -x %s; use -x mode=avr or -x mode=pic\n", extended_param); @@ -1635,7 +1596,7 @@ static int jtag3_parseextparms(const PROGRAMMER *pgm, const LISTID extparms) { rv = LIBAVRDUDE_EXIT; } - if (!help) { + if(!help) { pmsg_error("invalid extended parameter -x %s\n", extended_param); rv = -1; } @@ -1660,7 +1621,7 @@ static int jtag3_parseextparms(const PROGRAMMER *pgm, const LISTID extparms) { } if(str_starts(pgmid, "pickit4") || str_starts(pgmid, "snap")) msg_error(" -x mode=avr|pic Set programmer to AVR or PIC mode, then exit\n"); - msg_error (" -x help Show this help menu and exit\n"); + msg_error(" -x help Show this help menu and exit\n"); return rv; } @@ -1677,14 +1638,14 @@ int jtag3_open_common(PROGRAMMER *pgm, const char *port, int mode_switch) { return -1; #endif - if (!str_starts(port, "usb")) { + if(!str_starts(port, "usb")) { pmsg_error("JTAGICE3/EDBG port names must start with usb\n"); return -1; } - // If the config entry did not specify a USB PID, insert the default one. - if (lfirst(pgm->usbpid) == NULL) { - int *pidp = mmt_malloc(sizeof*pidp); + if(lfirst(pgm->usbpid) == NULL) { + int *pidp = mmt_malloc(sizeof *pidp); + *pidp = USB_DEVICE_JTAGICE3; ladd(pgm->usbpid, pidp); } @@ -1692,12 +1653,11 @@ int jtag3_open_common(PROGRAMMER *pgm, const char *port, int mode_switch) { pinfo.usbinfo.vid = pgm->usbvid? pgm->usbvid: USB_VENDOR_ATMEL; #if defined(HAVE_LIBHIDAPI) - // Try HIDAPI first. LibUSB is more generic, but might - // cause trouble for HID-class devices in some OSes + // Try HIDAPI first; LibUSB is more generic but might cause trouble for HID-class devices in some OSes serdev = &usbhid_serdev; - for (usbpid = lfirst(pgm->usbpid); rv < 0 && usbpid != NULL; usbpid = lnext(usbpid)) { + for(usbpid = lfirst(pgm->usbpid); rv < 0 && usbpid != NULL; usbpid = lnext(usbpid)) { pinfo.usbinfo.flags = PINFO_FL_SILENT; - pinfo.usbinfo.pid = *(int *)(ldata(usbpid)); + pinfo.usbinfo.pid = *(int *) (ldata(usbpid)); pgm->fd.usb.max_xfer = USBDEV_MAX_XFER_3; pgm->fd.usb.rep = USBDEV_BULK_EP_READ_3; pgm->fd.usb.wep = USBDEV_BULK_EP_WRITE_3; @@ -1706,13 +1666,14 @@ int jtag3_open_common(PROGRAMMER *pgm, const char *port, int mode_switch) { pgm->port = port; rv = serial_open(port, pinfo, &pgm->fd); } - if (rv < 0) { -#endif /* HAVE_LIBHIDAPI */ + if(rv < 0) { +#endif // HAVE_LIBHIDAPI + #if defined(HAVE_LIBUSB) serdev = &usb_serdev_frame; - for (usbpid = lfirst(pgm->usbpid); rv < 0 && usbpid != NULL; usbpid = lnext(usbpid)) { + for(usbpid = lfirst(pgm->usbpid); rv < 0 && usbpid != NULL; usbpid = lnext(usbpid)) { pinfo.usbinfo.flags = PINFO_FL_SILENT; - pinfo.usbinfo.pid = *(int *)(ldata(usbpid)); + pinfo.usbinfo.pid = *(int *) (ldata(usbpid)); pgm->fd.usb.max_xfer = USBDEV_MAX_XFER_3; pgm->fd.usb.rep = USBDEV_BULK_EP_READ_3; pgm->fd.usb.wep = USBDEV_BULK_EP_WRITE_3; @@ -1721,24 +1682,28 @@ int jtag3_open_common(PROGRAMMER *pgm, const char *port, int mode_switch) { pgm->port = port; rv = serial_open(port, pinfo, &pgm->fd); } -#endif /* HAVE_LIBUSB */ +#endif // HAVE_LIBUSB + #if defined(HAVE_LIBHIDAPI) } #endif - if (rv < 0) { + + if(rv < 0) { // Check if SNAP or PICkit4 are in PIC mode - for(LNODEID ln=lfirst(pgm->id); ln; ln=lnext(ln)) { - if (str_starts(ldata(ln), "snap") || str_starts(ldata(ln), "pickit4")) { + for(LNODEID ln = lfirst(pgm->id); ln; ln = lnext(ln)) { + if(str_starts(ldata(ln), "snap") || str_starts(ldata(ln), "pickit4")) { bool is_snap_pgm = str_starts(ldata(ln), "snap"); + pinfo.usbinfo.vid = USB_VENDOR_MICROCHIP; pinfo.usbinfo.pid = is_snap_pgm? USB_DEVICE_SNAP_PIC_MODE: USB_DEVICE_PICKIT4_PIC_MODE; const int bl_pid = is_snap_pgm? USB_DEVICE_SNAP_PIC_MODE_BL: USB_DEVICE_PICKIT4_PIC_MODE_BL; const char *pgmstr = is_snap_pgm? "MPLAB SNAP": "PICkit 4"; - const unsigned char exit_bl_cmd[] = {0xe6}; - const unsigned char enter_avr_mode_cmd[] = {0xf0, 0x01}; - const unsigned char reset_cmd[] = {0xed}; + const unsigned char exit_bl_cmd[] = { 0xe6 }; + const unsigned char enter_avr_mode_cmd[] = { 0xf0, 0x01 }; + const unsigned char reset_cmd[] = { 0xed }; int pic_mode = serial_open(port, pinfo, &pgm->fd); + if(pic_mode < 0) { // Retry with bootloader USB PID pinfo.usbinfo.pid = bl_pid; @@ -1747,8 +1712,7 @@ int jtag3_open_common(PROGRAMMER *pgm, const char *port, int mode_switch) { if(pic_mode >= 0) { msg_error("\n"); cx->usb_access_error = 0; - pmsg_error("%s in %s mode detected\n", - pgmstr, pinfo.usbinfo.pid == bl_pid? "bootloader": "PIC"); + pmsg_error("%s in %s mode detected\n", pgmstr, pinfo.usbinfo.pid == bl_pid? "bootloader": "PIC"); if(mode_switch == PK4_SNAP_MODE_AVR) { imsg_error("switching to AVR mode; "); if(pinfo.usbinfo.pid == bl_pid) @@ -1768,46 +1732,46 @@ int jtag3_open_common(PROGRAMMER *pgm, const char *port, int mode_switch) { } } } - pmsg_error("no device found matching VID 0x%04x and PID list: ", - (unsigned) pinfo.usbinfo.vid); + pmsg_error("no device found matching VID 0x%04x and PID list: ", (unsigned) pinfo.usbinfo.vid); int notfirst = 0; - for (usbpid = lfirst(pgm->usbpid); usbpid; usbpid = lnext(usbpid)) { - if (notfirst) + + for(usbpid = lfirst(pgm->usbpid); usbpid; usbpid = lnext(usbpid)) { + if(notfirst) msg_error(", "); - msg_error("0x%04x", (unsigned int)(*(int *)(ldata(usbpid)))); + msg_error("0x%04x", (unsigned int) (*(int *) (ldata(usbpid)))); notfirst = 1; } char *serno; - if ((serno = strchr(port, ':'))) + + if((serno = strchr(port, ':'))) msg_error(" with SN %s", ++serno); msg_error("\n"); return -1; } - if (mode_switch == PK4_SNAP_MODE_AVR) + if(mode_switch == PK4_SNAP_MODE_AVR) pmsg_warning("programmer is already in AVR mode, ignoring -x mode"); - // The event EP has been deleted by usb_open(), so we are - // running on a CMSIS-DAP device, using EDBG protocol - if (pgm->fd.usb.eep == 0) { + // The event EP has been deleted by usb_open(), so we are running on a CMSIS-DAP device, using EDBG protocol + if(pgm->fd.usb.eep == 0) { pgm->flag |= PGM_FL_IS_EDBG; pmsg_notice2("found CMSIS-DAP compliant device, using EDBG protocol\n"); } // Make USB serial number available to programmer - if (serdev && serdev->usbsn) + if(serdev && serdev->usbsn) pgm->usbsn = serdev->usbsn; // Drain any extraneous input jtag3_drain(pgm, 0); // Switch from AVR to PIC mode - if (mode_switch == PK4_SNAP_MODE_PIC) { + if(mode_switch == PK4_SNAP_MODE_PIC) { imsg_error("switching to PIC mode: "); - unsigned char *resp, buf[] = {SCOPE_GENERAL, CMD3_FW_UPGRADE, 0x00, 0x00, 0x70, 0x6d, 0x6a}; - if (jtag3_command(pgm, buf, sizeof(buf), &resp, "enter PIC mode") < 0) { + unsigned char *resp, buf[] = { SCOPE_GENERAL, CMD3_FW_UPGRADE, 0x00, 0x00, 0x70, 0x6d, 0x6a }; + if(jtag3_command(pgm, buf, sizeof(buf), &resp, "enter PIC mode") < 0) { msg_error("entering PIC mode failed\n"); return -1; } @@ -1819,13 +1783,12 @@ int jtag3_open_common(PROGRAMMER *pgm, const char *port, int mode_switch) { return 0; } - - static int jtag3_open(PROGRAMMER *pgm, const char *port) { pmsg_notice2("jtag3_open()\n"); - int rc = jtag3_open_common(pgm, port, PDATA(pgm)->pk4_snap_mode); - if (rc < 0) + int rc = jtag3_open_common(pgm, port, my.pk4_snap_mode); + + if(rc < 0) return rc; return jtag3_getsync(pgm, PARM3_CONN_JTAG) < 0? -1: 0; @@ -1834,11 +1797,12 @@ static int jtag3_open(PROGRAMMER *pgm, const char *port) { static int jtag3_open_dw(PROGRAMMER *pgm, const char *port) { pmsg_notice2("jtag3_open_dw()\n"); - int rc = jtag3_open_common(pgm, port, PDATA(pgm)->pk4_snap_mode); - if (rc < 0) + int rc = jtag3_open_common(pgm, port, my.pk4_snap_mode); + + if(rc < 0) return rc; - if (jtag3_getsync(pgm, PARM3_CONN_DW) < 0) + if(jtag3_getsync(pgm, PARM3_CONN_DW) < 0) return -1; return 0; @@ -1846,8 +1810,9 @@ static int jtag3_open_dw(PROGRAMMER *pgm, const char *port) { static int jtag3_open_pdi(PROGRAMMER *pgm, const char *port) { pmsg_notice2("jtag3_open_pdi()\n"); - int rc = jtag3_open_common(pgm, port, PDATA(pgm)->pk4_snap_mode); - if (rc < 0) + int rc = jtag3_open_common(pgm, port, my.pk4_snap_mode); + + if(rc < 0) return rc; return jtag3_getsync(pgm, PARM3_CONN_PDI) < 0? -1: 0; @@ -1857,19 +1822,21 @@ static int jtag3_open_updi(PROGRAMMER *pgm, const char *port) { pmsg_notice2("jtag3_open_updi()\n"); LNODEID ln; + pmsg_notice2("HV UPDI support:"); - for (ln = lfirst(pgm->hvupdi_support); ln; ln = lnext(ln)) + for(ln = lfirst(pgm->hvupdi_support); ln; ln = lnext(ln)) msg_notice2(" %d", *(int *) ldata(ln)); msg_notice2("\n"); - int rc = jtag3_open_common(pgm, port, PDATA(pgm)->pk4_snap_mode); - if (rc < 0) + int rc = jtag3_open_common(pgm, port, my.pk4_snap_mode); + + if(rc < 0) return rc; return jtag3_getsync(pgm, PARM3_CONN_UPDI) < 0? -1: 0; } -void jtag3_close(PROGRAMMER * pgm) { +void jtag3_close(PROGRAMMER *pgm) { unsigned char buf[4], *resp; pmsg_notice2("jtag3_close()\n"); @@ -1878,19 +1845,17 @@ void jtag3_close(PROGRAMMER * pgm) { buf[1] = CMD3_SIGN_OFF; buf[2] = buf[3] = 0; - if (jtag3_command(pgm, buf, 3, &resp, "AVR sign-off") >= 0) + if(jtag3_command(pgm, buf, 3, &resp, "AVR sign-off") >= 0) mmt_free(resp); buf[0] = SCOPE_GENERAL; buf[1] = CMD3_SIGN_OFF; - if (jtag3_command(pgm, buf, 4, &resp, "sign-off") >= 0) + if(jtag3_command(pgm, buf, 4, &resp, "sign-off") >= 0) mmt_free(resp); - /* XplainedMini boards do not need this, and early revisions had a - * firmware bug where they complained about it. */ - if ((pgm->flag & PGM_FL_IS_EDBG) && - !str_starts(pgmid, "xplainedmini")) { + // XplainedMini boards do not need this, and early revisions had a FW bug that complained about it + if((pgm->flag & PGM_FL_IS_EDBG) && !str_starts(pgmid, "xplainedmini")) { jtag3_edbg_signoff(pgm); } @@ -1898,45 +1863,43 @@ void jtag3_close(PROGRAMMER * pgm) { pgm->fd.ifd = -1; } -static int jtag3_page_erase(const PROGRAMMER *pgm, const AVRPART *p, const AVRMEM *m, - unsigned int addr) { +static int jtag3_page_erase(const PROGRAMMER *pgm, const AVRPART *p, const AVRMEM *m, unsigned int addr) { unsigned char cmd[8], *resp; pmsg_notice2("jtag3_page_erase(.., %s, 0x%x)\n", m->desc, addr); - if((p->prog_modes & PM_Classic) && !mem_is_userrow(m)) { + if(is_classic(p) && !mem_is_userrow(m)) { pmsg_error("page erase only available for AVR8X/XMEGAs or classic-part usersig mem\n"); return -1; } - if (jtag3_program_enable(pgm) < 0) + if(jtag3_program_enable(pgm) < 0) return -1; cmd[0] = SCOPE_AVR; cmd[1] = CMD3_ERASE_MEMORY; cmd[2] = 0; - if (mem_is_in_flash(m)) { - cmd[3] = is_updi(p) || jtag3_mtype(pgm, p, m, addr) == MTYPE_FLASH? - XMEGA_ERASE_APP_PAGE: XMEGA_ERASE_BOOT_PAGE; - PDATA(pgm)->flash_pageaddr = ~0UL; - } else if (mem_is_eeprom(m)) { + if(mem_is_in_flash(m)) { + cmd[3] = is_updi(p) || jtag3_mtype(pgm, p, m, addr) == MTYPE_FLASH? XMEGA_ERASE_APP_PAGE: XMEGA_ERASE_BOOT_PAGE; + my.flash_pageaddr = ~0UL; + } else if(mem_is_eeprom(m)) { cmd[3] = XMEGA_ERASE_EEPROM_PAGE; - PDATA(pgm)->eeprom_pageaddr = ~0UL; - } else if (mem_is_userrow(m)) { + my.eeprom_pageaddr = ~0UL; + } else if(mem_is_userrow(m)) { cmd[3] = XMEGA_ERASE_USERSIG; - } else if (mem_is_bootrow(m)) { + } else if(mem_is_bootrow(m)) { // Currently, AVR-DU BOOTROW cannot be erased with CMD3_ERASE_MEMORY // Note ATDF: - cmd[3] = XMEGA_ERASE_USERSIG; // Tentative for AVR-DU and AVR-EB series + cmd[3] = XMEGA_ERASE_USERSIG; // Tentative for AVR-DU and AVR-EB series } else { cmd[3] = XMEGA_ERASE_APP_PAGE; } addr = is_pdi(p) && !mem_is_in_flash(m)? addr + m->offset: jtag3_memaddr(pgm, p, m, addr); u32_to_b4(cmd + 4, addr); - if (jtag3_command(pgm, cmd, 8, &resp, "page erase") < 0) + if(jtag3_command(pgm, cmd, 8, &resp, "page erase") < 0) return -1; mmt_free(resp); @@ -1944,8 +1907,7 @@ static int jtag3_page_erase(const PROGRAMMER *pgm, const AVRPART *p, const AVRME } static int jtag3_paged_write(const PROGRAMMER *pgm, const AVRPART *p, const AVRMEM *m, - unsigned int page_size, - unsigned int addr, unsigned int n_bytes) { + unsigned int page_size, unsigned int addr, unsigned int n_bytes) { unsigned int block_size; unsigned int maxaddr = addr + n_bytes; unsigned char *cmd; @@ -1960,31 +1922,31 @@ static int jtag3_paged_write(const PROGRAMMER *pgm, const AVRPART *p, const AVRM imsg_notice2("mapped to address: 0x%04x\n", block_size); block_size = 0; - if (!(pgm->flag & PGM_FL_IS_DW) && jtag3_program_enable(pgm) < 0) + if(!(pgm->flag & PGM_FL_IS_DW) && jtag3_program_enable(pgm) < 0) return -1; - if (page_size == 0) + if(page_size == 0) page_size = 256; cmd = mmt_malloc(page_size + 13); cmd[0] = SCOPE_AVR; cmd[1] = CMD3_WRITE_MEMORY; cmd[2] = 0; - if (mem_is_flash(m)) { - PDATA(pgm)->flash_pageaddr = ~0UL; + if(mem_is_flash(m)) { + my.flash_pageaddr = ~0UL; cmd[3] = jtag3_mtype(pgm, p, m, addr); - if (p->prog_modes & PM_PDI) - /* dynamically decide between flash/boot mtype */ + if(is_pdi(p)) + // Dynamically decide between flash/boot mtype dynamic_mtype = 1; - } else if (mem_is_eeprom(m)) { - if (pgm->flag & PGM_FL_IS_DW) { + } else if(mem_is_eeprom(m)) { + if(pgm->flag & PGM_FL_IS_DW) { /* - * jtag3_paged_write() to EEPROM attempted while in - * DW mode. Use jtag3_write_byte() instead. + * jtag3_paged_write() to EEPROM attempted while in DW mode; use + * jtag3_write_byte() instead. */ - for (; addr < maxaddr; addr++) { + for(; addr < maxaddr; addr++) { status = jtag3_write_byte(pgm, p, m, addr, m->buf[addr]); - if (status < 0) { + if(status < 0) { mmt_free(cmd); return -1; } @@ -1993,25 +1955,25 @@ static int jtag3_paged_write(const PROGRAMMER *pgm, const AVRPART *p, const AVRM return n_bytes; } cmd[3] = p->prog_modes & (PM_PDI | PM_UPDI)? MTYPE_EEPROM_XMEGA: MTYPE_EEPROM_PAGE; - PDATA(pgm)->eeprom_pageaddr = ~0UL; - } else if (mem_is_userrow(m) || mem_is_bootrow(m)) { + my.eeprom_pageaddr = ~0UL; + } else if(mem_is_userrow(m) || mem_is_bootrow(m)) { cmd[3] = MTYPE_USERSIG; - } else if (mem_is_boot(m)) { + } else if(mem_is_boot(m)) { cmd[3] = MTYPE_BOOT_FLASH; - } else if (p->prog_modes & (PM_PDI | PM_UPDI)) { + } else if(p->prog_modes & (PM_PDI | PM_UPDI)) { cmd[3] = MTYPE_FLASH; } else { cmd[3] = MTYPE_SPM; } serial_recv_timeout = 100; - for (; addr < maxaddr; addr += page_size) { - if ((maxaddr - addr) < page_size) + for(; addr < maxaddr; addr += page_size) { + if((maxaddr - addr) < page_size) block_size = maxaddr - addr; else block_size = page_size; pmsg_debug("%s(): block_size at addr %d is %d\n", __func__, addr, block_size); - if (dynamic_mtype) + if(dynamic_mtype) cmd[3] = jtag3_mtype(pgm, p, m, addr); u32_to_b4(cmd + 8, page_size); @@ -2019,17 +1981,16 @@ static int jtag3_paged_write(const PROGRAMMER *pgm, const AVRPART *p, const AVRM cmd[12] = 0; /* - * The JTAG ICE will refuse to write anything but a full page, at - * least for the flash ROM. If a partial page has been requested, - * set the remainder to 0xff. (Maybe we should rather read back - * the existing contents instead before? Doesn't matter much, as - * bits cannot be written to 1 anyway.) + * The JTAG ICE will refuse to write anything but a full page, at least for + * the flash ROM. If a partial page has been requested, set the remainder + * to 0xff. (Maybe we should rather read back the existing contents + * instead before? Doesn't matter much, as bits cannot be written to 1 + * anyway.) */ memset(cmd + 13, 0xff, page_size); memcpy(cmd + 13, m->buf + addr, block_size); - if ((status = jtag3_command(pgm, cmd, page_size + 13, - &resp, "write memory")) < 0) { + if((status = jtag3_command(pgm, cmd, page_size + 13, &resp, "write memory")) < 0) { mmt_free(cmd); serial_recv_timeout = otimeout; return -1; @@ -2045,8 +2006,7 @@ static int jtag3_paged_write(const PROGRAMMER *pgm, const AVRPART *p, const AVRM } static int jtag3_paged_load(const PROGRAMMER *pgm, const AVRPART *p, const AVRMEM *m, - unsigned int page_size, - unsigned int addr, unsigned int n_bytes) { + unsigned int page_size, unsigned int addr, unsigned int n_bytes) { unsigned int block_size; unsigned int maxaddr = addr + n_bytes; unsigned char cmd[12]; @@ -2054,15 +2014,14 @@ static int jtag3_paged_load(const PROGRAMMER *pgm, const AVRPART *p, const AVRME int status, dynamic_mtype = 0; long otimeout = serial_recv_timeout; - pmsg_notice2("jtag3_paged_load(.., %s, %d, 0x%04x, %d)\n", - m->desc, page_size, addr, n_bytes); + pmsg_notice2("jtag3_paged_load(.., %s, %d, 0x%04x, %d)\n", m->desc, page_size, addr, n_bytes); block_size = jtag3_memaddr(pgm, p, m, addr); if(block_size != addr) imsg_notice2("mapped to address: 0x%04x\n", block_size); block_size = 0; - if (!(pgm->flag & PGM_FL_IS_DW) && jtag3_program_enable(pgm) < 0) + if(!(pgm->flag & PGM_FL_IS_DW) && jtag3_program_enable(pgm) < 0) return -1; page_size = m->readsize; @@ -2071,46 +2030,46 @@ static int jtag3_paged_load(const PROGRAMMER *pgm, const AVRPART *p, const AVRME cmd[1] = CMD3_READ_MEMORY; cmd[2] = 0; - if (mem_is_flash(m)) { + if(mem_is_flash(m)) { cmd[3] = jtag3_mtype(pgm, p, m, addr); - if (p->prog_modes & PM_PDI) - /* dynamically decide between flash/boot mtype */ + if(is_pdi(p)) + // Dynamically decide between flash/boot mtype dynamic_mtype = 1; - } else if (mem_is_eeprom(m)) { + } else if(mem_is_eeprom(m)) { cmd[3] = p->prog_modes & (PM_PDI | PM_UPDI)? MTYPE_EEPROM: MTYPE_EEPROM_PAGE; - if (pgm->flag & PGM_FL_IS_DW) + if(pgm->flag & PGM_FL_IS_DW) return -1; - } else if (mem_is_sigrow(m)) { + } else if(mem_is_sigrow(m)) { cmd[3] = MTYPE_PRODSIG; - } else if (mem_is_userrow(m) || mem_is_bootrow(m)) { + } else if(mem_is_userrow(m) || mem_is_bootrow(m)) { cmd[3] = MTYPE_USERSIG; - } else if (mem_is_boot(m)) { + } else if(mem_is_boot(m)) { cmd[3] = MTYPE_BOOT_FLASH; - } else if (p->prog_modes & PM_PDI) { + } else if(is_pdi(p)) { cmd[3] = MTYPE_FLASH; - } else if (p->prog_modes & PM_UPDI) { + } else if(is_updi(p)) { cmd[3] = MTYPE_SRAM; } else { cmd[3] = MTYPE_SPM; } serial_recv_timeout = 100; - for (; addr < maxaddr; addr += page_size) { - if ((maxaddr - addr) < page_size) + for(; addr < maxaddr; addr += page_size) { + if((maxaddr - addr) < page_size) block_size = maxaddr - addr; else block_size = page_size; pmsg_debug("%s(): block_size at addr %d is %d\n", __func__, addr, block_size); - if (dynamic_mtype) + if(dynamic_mtype) cmd[3] = jtag3_mtype(pgm, p, m, addr); u32_to_b4(cmd + 8, block_size); u32_to_b4(cmd + 4, jtag3_memaddr(pgm, p, m, addr)); - if ((status = jtag3_command(pgm, cmd, 12, &resp, "read memory")) < 0) + if((status = jtag3_command(pgm, cmd, 12, &resp, "read memory")) < 0) return -1; - if (resp[1] != RSP3_DATA || status < (int) block_size + 4) { + if(resp[1] != RSP3_DATA || status < (int) block_size + 4) { pmsg_error("wrong/short reply to read memory command\n"); serial_recv_timeout = otimeout; mmt_free(resp); @@ -2132,7 +2091,7 @@ static int jtag3_paged_load(const PROGRAMMER *pgm, const AVRPART *p, const AVRME } static int jtag3_read_byte(const PROGRAMMER *pgm, const AVRPART *p, const AVRMEM *mem, - unsigned long addr, unsigned char * value) { + unsigned long addr, unsigned char *value) { unsigned char cmd[12]; unsigned char *resp, *cache_ptr = NULL; int status, unsupp = 0; @@ -2142,22 +2101,22 @@ static int jtag3_read_byte(const PROGRAMMER *pgm, const AVRPART *p, const AVRMEM pmsg_notice2("jtag3_read_byte(.., %s, 0x%lx, ...)\n", mem->desc, addr); paddr = jtag3_memaddr(pgm, p, mem, addr); - if (paddr != addr) + if(paddr != addr) imsg_debug("addr 0x%lx mapped to address 0x%lx\n", addr, paddr); paddr = 0; - if (mem->size < 1) { + if(mem->size < 1) { pmsg_error("cannot read byte from %s %s owing to its size %d\n", p->desc, mem->desc, mem->size); return -1; } - if (addr >= (unsigned long) mem->size) { + if(addr >= (unsigned long) mem->size) { pmsg_error("cannot read byte from %s %s as address 0x%04lx outside range [0, 0x%04x]\n", - p->desc, mem->desc, addr, mem->size-1); + p->desc, mem->desc, addr, mem->size - 1); return -1; } - if (!(pgm->flag & PGM_FL_IS_DW)) - if ((status = jtag3_program_enable(pgm)) < 0) + if(!(pgm->flag & PGM_FL_IS_DW)) + if((status = jtag3_program_enable(pgm)) < 0) return status; cmd[0] = SCOPE_AVR; @@ -2165,97 +2124,97 @@ static int jtag3_read_byte(const PROGRAMMER *pgm, const AVRPART *p, const AVRMEM cmd[2] = 0; cmd[3] = p->prog_modes & (PM_PDI | PM_UPDI)? MTYPE_FLASH: MTYPE_FLASH_PAGE; - if (mem_is_in_flash(mem)) { - addr += mem->offset & (512 * 1024 - 1); /* max 512 KiB flash @@@ could be max 8M */ - pagesize = PDATA(pgm)->flash_pagesize; + if(mem_is_in_flash(mem)) { + addr += mem->offset & (512*1024 - 1); // Max 512 KiB flash @@@ could be max 8M + pagesize = my.flash_pagesize; paddr = addr & ~(pagesize - 1); - paddr_ptr = &PDATA(pgm)->flash_pageaddr; - cache_ptr = PDATA(pgm)->flash_pagecache; - } else if (mem_is_eeprom(mem)) { - if ((pgm->flag & PGM_FL_IS_DW) || (p->prog_modes & (PM_PDI | PM_UPDI))) { + paddr_ptr = &my.flash_pageaddr; + cache_ptr = my.flash_pagecache; + } else if(mem_is_eeprom(mem)) { + if((pgm->flag & PGM_FL_IS_DW) || (p->prog_modes & (PM_PDI | PM_UPDI))) { cmd[3] = MTYPE_EEPROM; } else { cmd[3] = MTYPE_EEPROM_PAGE; } pagesize = mem->page_size; paddr = addr & ~(pagesize - 1); - paddr_ptr = &PDATA(pgm)->eeprom_pageaddr; - cache_ptr = PDATA(pgm)->eeprom_pagecache; - } else if (mem_is_a_fuse(mem) || mem_is_fuses(mem)) { + paddr_ptr = &my.eeprom_pageaddr; + cache_ptr = my.eeprom_pagecache; + } else if(mem_is_a_fuse(mem) || mem_is_fuses(mem)) { cmd[3] = MTYPE_FUSE_BITS; - if(!(p->prog_modes & PM_UPDI) && mem_is_a_fuse(mem)) + if(!is_updi(p) && mem_is_a_fuse(mem)) addr = mem_fuse_offset(mem); - if (pgm->flag & PGM_FL_IS_DW) + if(pgm->flag & PGM_FL_IS_DW) unsupp = 1; - } else if (mem_is_lock(mem)) { + } else if(mem_is_lock(mem)) { cmd[3] = MTYPE_LOCK_BITS; - if (pgm->flag & PGM_FL_IS_DW) + if(pgm->flag & PGM_FL_IS_DW) unsupp = 1; - } else if (mem_is_userrow(mem) || mem_is_bootrow(mem)) { + } else if(mem_is_userrow(mem) || mem_is_bootrow(mem)) { cmd[3] = MTYPE_USERSIG; - } else if (mem_is_sigrow(mem)) { - if (p->prog_modes & (PM_PDI | PM_UPDI)) { + } else if(mem_is_sigrow(mem)) { + if(p->prog_modes & (PM_PDI | PM_UPDI)) { cmd[3] = MTYPE_PRODSIG; } else { - cmd[3] = addr&1? MTYPE_OSCCAL_BYTE: MTYPE_SIGN_JTAG; + cmd[3] = addr & 1? MTYPE_OSCCAL_BYTE: MTYPE_SIGN_JTAG; addr /= 2; - if (pgm->flag & PGM_FL_IS_DW) + if(pgm->flag & PGM_FL_IS_DW) unsupp = 1; } - } else if ((p->prog_modes & PM_Classic) && mem_is_calibration(mem)) { // Classic part calibration + } else if(is_classic(p) && mem_is_calibration(mem)) { // Classic part calibration cmd[3] = MTYPE_OSCCAL_BYTE; - if (pgm->flag & PGM_FL_IS_DW) + if(pgm->flag & PGM_FL_IS_DW) unsupp = 1; - } else if (mem_is_io(mem) || mem_is_sram(mem)) { + } else if(mem_is_io(mem) || mem_is_sram(mem)) { cmd[3] = MTYPE_SRAM; - } else if (mem_is_sib(mem)) { + } else if(mem_is_sib(mem)) { if(addr >= AVR_SIBLEN) { pmsg_error("cannot read byte from %s sib as address 0x%04lx outside range [0, 0x%04x]\n", - p->desc, addr, AVR_SIBLEN-1); + p->desc, addr, AVR_SIBLEN - 1); return -1; } - if(!*PDATA(pgm)->sib_string) { + if(!*my.sib_string) { pmsg_error("cannot read byte from %s sib as memory not initialised\n", p->desc); return -1; } - *value = PDATA(pgm)->sib_string[addr]; + *value = my.sib_string[addr]; return 0; - } else if (mem_is_signature(mem)) { + } else if(mem_is_signature(mem)) { cmd[3] = MTYPE_SIGN_JTAG; /* - * dW can read out the signature on JTAGICE3, but only allows - * for a full three-byte read. We cache them in a local - * variable to avoid multiple reads. This optimization does not - * harm for other connection types either. + * dW can read out the signature on JTAGICE3, but only allows for a full + * three-byte read. We cache them in a local variable to avoid multiple + * reads. This optimization does not harm for other connection types + * either. */ u32_to_b4(cmd + 8, 3); u32_to_b4(cmd + 4, jtag3_memaddr(pgm, p, mem, addr)); - if (addr == 0) { - if ((status = jtag3_command(pgm, cmd, 12, &resp, "read memory")) < 0) + if(addr == 0) { + if((status = jtag3_command(pgm, cmd, 12, &resp, "read memory")) < 0) return status; - PDATA(pgm)->signature_cache[0] = resp[4]; - PDATA(pgm)->signature_cache[1] = resp[5]; + my.signature_cache[0] = resp[4]; + my.signature_cache[1] = resp[5]; *value = resp[3]; mmt_free(resp); return 0; - } else if (addr <= 2) { - *value = PDATA(pgm)->signature_cache[addr - 1]; + } else if(addr <= 2) { + *value = my.signature_cache[addr - 1]; return 0; } else { - /* should not happen */ + // Should not happen msg_error("address out of range for signature memory: %lu\n", addr); return -1; } - } else if(mem_is_in_sigrow(mem)) { // sigrow sub-memories but not signature nor sigrow itself - if (p->prog_modes & (PM_PDI | PM_UPDI)) { + } else if(mem_is_in_sigrow(mem)) { // sigrow sub-memories but not signature nor sigrow itself + if(p->prog_modes & (PM_PDI | PM_UPDI)) { cmd[3] = MTYPE_PRODSIG; } else { - cmd[3] = addr&1? MTYPE_OSCCAL_BYTE: MTYPE_SIGN_JTAG; + cmd[3] = addr & 1? MTYPE_OSCCAL_BYTE: MTYPE_SIGN_JTAG; addr /= 2; - if (pgm->flag & PGM_FL_IS_DW) + if(pgm->flag & PGM_FL_IS_DW) unsupp = 1; } } else { @@ -2263,30 +2222,26 @@ static int jtag3_read_byte(const PROGRAMMER *pgm, const AVRPART *p, const AVRMEM return -1; } - /* - * If the respective memory area is not supported under debugWire, - * leave here. - */ - if (unsupp) { + // If the respective memory area is not supported under debugWire, leave here + if(unsupp) { *value = 42; return -1; } /* - * To improve the read speed, we used paged reads for flash and - * EEPROM, and cache the results in a page cache. + * To improve the read speed, we used paged reads for flash and EEPROM, and + * cache the results in a page cache. * - * Page cache validation is based on "{flash,eeprom}_pageaddr" - * (holding the base address of the most recent cache fill - * operation). This variable is set to ~0UL when the - * cache needs to be invalidated. + * Page cache validation is based on "{flash,eeprom}_pageaddr" (holding the + * base address of the most recent cache fill operation). This variable is + * set to ~0UL when the cache needs to be invalidated. */ - if (pagesize && paddr == *paddr_ptr) { + if(pagesize && paddr == *paddr_ptr) { *value = cache_ptr[addr & (pagesize - 1)]; return 0; } - if (pagesize) { + if(pagesize) { u32_to_b4(cmd + 8, pagesize); u32_to_b4(cmd + 4, jtag3_memaddr(pgm, p, mem, paddr)); @@ -2295,17 +2250,16 @@ static int jtag3_read_byte(const PROGRAMMER *pgm, const AVRPART *p, const AVRMEM u32_to_b4(cmd + 4, jtag3_memaddr(pgm, p, mem, addr)); } - if ((status = jtag3_command(pgm, cmd, 12, &resp, "read memory")) < 0) + if((status = jtag3_command(pgm, cmd, 12, &resp, "read memory")) < 0) return status; - if (resp[1] != RSP3_DATA || - status < (int) (pagesize? pagesize: 1) + 4) { + if(resp[1] != RSP3_DATA || status < (int) (pagesize? pagesize: 1) + 4) { pmsg_error("wrong/short reply to read memory command\n"); mmt_free(resp); return -1; } - if (pagesize) { + if(pagesize) { *paddr_ptr = paddr; memcpy(cache_ptr, resp + 3, pagesize); *value = cache_ptr[addr & (pagesize - 1)]; @@ -2317,7 +2271,8 @@ static int jtag3_read_byte(const PROGRAMMER *pgm, const AVRPART *p, const AVRMEM } static int jtag3_write_byte(const PROGRAMMER *pgm, const AVRPART *p, const AVRMEM *mem, - unsigned long addr, unsigned char data) { + unsigned long addr, unsigned char data) { + unsigned char cmd[14]; unsigned char *resp; unsigned char *cache_ptr = 0; @@ -2336,7 +2291,7 @@ static int jtag3_write_byte(const PROGRAMMER *pgm, const AVRPART *p, const AVRME return -1; } else if(addr >= (unsigned long) mem->size) { pmsg_error("cannot write byte to %s %s as address 0x%04lx outside range [0, 0x%04x]\n", - p->desc, mem->desc, addr, mem->size-1); + p->desc, mem->desc, addr, mem->size - 1); return -1; } @@ -2344,68 +2299,68 @@ static int jtag3_write_byte(const PROGRAMMER *pgm, const AVRPART *p, const AVRME cmd[1] = CMD3_WRITE_MEMORY; cmd[2] = 0; cmd[3] = p->prog_modes & (PM_PDI | PM_UPDI)? MTYPE_FLASH: MTYPE_SPM; - if (mem_is_flash(mem)) { - cache_ptr = PDATA(pgm)->flash_pagecache; - pagesize = PDATA(pgm)->flash_pagesize; - PDATA(pgm)->flash_pageaddr = ~0UL; - if (pgm->flag & PGM_FL_IS_DW) - unsupp = 1; - } else if (mem_is_eeprom(mem)) { - if (pgm->flag & PGM_FL_IS_DW) { + if(mem_is_flash(mem)) { + cache_ptr = my.flash_pagecache; + pagesize = my.flash_pagesize; + my.flash_pageaddr = ~0UL; + if(pgm->flag & PGM_FL_IS_DW) + unsupp = 1; + } else if(mem_is_eeprom(mem)) { + if(pgm->flag & PGM_FL_IS_DW) { cmd[3] = MTYPE_EEPROM; } else { - cache_ptr = PDATA(pgm)->eeprom_pagecache; - pagesize = PDATA(pgm)->eeprom_pagesize; + cache_ptr = my.eeprom_pagecache; + pagesize = my.eeprom_pagesize; } - PDATA(pgm)->eeprom_pageaddr = ~0UL; - } else if (mem_is_a_fuse(mem) || mem_is_fuses(mem)) { + my.eeprom_pageaddr = ~0UL; + } else if(mem_is_a_fuse(mem) || mem_is_fuses(mem)) { cmd[3] = MTYPE_FUSE_BITS; - if(!(p->prog_modes & PM_UPDI) && mem_is_a_fuse(mem)) + if(!is_updi(p) && mem_is_a_fuse(mem)) addr = mem_fuse_offset(mem); - if (pgm->flag & PGM_FL_IS_DW) + if(pgm->flag & PGM_FL_IS_DW) unsupp = 1; - } else if (mem_is_lock(mem)) { + } else if(mem_is_lock(mem)) { cmd[3] = MTYPE_LOCK_BITS; - if (pgm->flag & PGM_FL_IS_DW) + if(pgm->flag & PGM_FL_IS_DW) unsupp = 1; - } else if (mem_is_userrow(mem) || mem_is_bootrow(mem)) { + } else if(mem_is_userrow(mem) || mem_is_bootrow(mem)) { cmd[3] = MTYPE_USERSIG; - } else if (mem_is_io(mem) || mem_is_sram(mem)) + } else if(mem_is_io(mem) || mem_is_sram(mem)) cmd[3] = MTYPE_SRAM; // Read-only memories or unsupported by debugWire if(mem_is_readonly(mem) || unsupp) { - unsigned char is; - if(jtag3_read_byte(pgm, p, mem, addr, &is) >= 0 && is == data) - return 0; - if (unsupp && pgm->flag & PGM_FL_IS_DW) - pmsg_error("debugWire interface does not support writing to memory %s\n", mem->desc); - else - pmsg_error("cannot write to read-only memory %s of %s\n", mem->desc, p->desc); - return -1; - } + unsigned char is; - if (pagesize != 0) { - /* flash or EEPROM write: use paged algorithm */ + if(jtag3_read_byte(pgm, p, mem, addr, &is) >= 0 && is == data) + return 0; + if(unsupp && pgm->flag & PGM_FL_IS_DW) + pmsg_error("debugWire interface does not support writing to memory %s\n", mem->desc); + else + pmsg_error("cannot write to read-only memory %s of %s\n", mem->desc, p->desc); + return -1; + } + + if(pagesize != 0) { + // Flash or EEPROM write: use paged algorithm unsigned char dummy; int i; - /* step #1: ensure the page cache is up to date */ - if (jtag3_read_byte(pgm, p, mem, addr, &dummy) < 0) + // Step #1: ensure the page cache is up to date + if(jtag3_read_byte(pgm, p, mem, addr, &dummy) < 0) return -1; - /* step #2: update our value in page cache, and copy - * cache to mem->buf */ + // Step #2: update our value in page cache, and copy cache to mem->buf cache_ptr[addr & (pagesize - 1)] = data; - addr &= ~(pagesize - 1); /* page base address */ + addr &= ~(pagesize - 1); // Page base address memcpy(mem->buf + addr, cache_ptr, pagesize); - /* step #3: write back */ + // Step #3: write back i = jtag3_paged_write(pgm, p, mem, pagesize, addr, pagesize); return i < 0? -1: 0; } - /* non-paged writes go here */ - if (!(pgm->flag & PGM_FL_IS_DW) && jtag3_program_enable(pgm) < 0) + // Non-paged writes go here + if(!(pgm->flag & PGM_FL_IS_DW) && jtag3_program_enable(pgm) < 0) return -1; u32_to_b4(cmd + 8, 1); @@ -2413,7 +2368,7 @@ static int jtag3_write_byte(const PROGRAMMER *pgm, const AVRPART *p, const AVRME cmd[12] = 0; cmd[13] = data; - if ((status = jtag3_command(pgm, cmd, 14, &resp, "write memory")) < 0) + if((status = jtag3_command(pgm, cmd, 14, &resp, "write memory")) < 0) return status; mmt_free(resp); @@ -2421,66 +2376,65 @@ static int jtag3_write_byte(const PROGRAMMER *pgm, const AVRPART *p, const AVRME return 0; } - /* - * Set the JTAG clock. The actual frequency is quite a bit of - * guesswork, based on the values claimed by AVR Studio. Inside the - * JTAG ICE, the value is the delay count of a delay loop between the - * JTAG clock edges. A count of 0 bypasses the delay loop. + * Set the JTAG clock. The actual frequency is quite a bit of guesswork, based + * on the values claimed by AVR Studio. Inside the JTAG ICE, the value is the + * delay count of a delay loop between the JTAG clock edges. A count of 0 + * bypasses the delay loop. * - * As the STK500 expresses it as a period length (and we actualy do - * program a period length as well), we rather call it by that name. + * As the STK500 expresses it as a period length (and we actualy do program a + * period length as well), we rather call it by that name. */ static int jtag3_set_sck_period(const PROGRAMMER *pgm, double v) { unsigned char parm[2]; - unsigned int clock = 1E-3 / v; /* kHz */ + unsigned int clock = 1E-3/v; // kHz parm[0] = clock & 0xff; parm[1] = (clock >> 8) & 0xff; - if (PDATA(pgm)->set_sck == NULL) { + if(my.set_sck == NULL) { pmsg_error("no backend to set the SCK period for\n"); return -1; } - return (PDATA(pgm)->set_sck(pgm, parm) < 0)? -1: 0; + return (my.set_sck(pgm, parm) < 0)? -1: 0; } - static int jtag3_get_sck_period(const PROGRAMMER *pgm, double *v) { unsigned char conn, arch; unsigned char buf[2]; + *v = 0; - if (jtag3_getparm(pgm, SCOPE_AVR, 1, PARM3_CONNECTION, &conn, 1) < 0) { + if(jtag3_getparm(pgm, SCOPE_AVR, 1, PARM3_CONNECTION, &conn, 1) < 0) { pmsg_error("cannot obtain connection type\n"); return -1; } - if (jtag3_getparm(pgm, SCOPE_AVR, 0, PARM3_ARCH, &arch, 1) < 0) { + if(jtag3_getparm(pgm, SCOPE_AVR, 0, PARM3_ARCH, &arch, 1) < 0) { pmsg_error("cannot obtain target architecture\n"); return -1; } - if (conn == PARM3_CONN_JTAG) { - if (arch == PARM3_ARCH_XMEGA) { - if (jtag3_getparm(pgm, SCOPE_AVR, 1, PARM3_CLK_XMEGA_JTAG, buf, 2) < 0) { + if(conn == PARM3_CONN_JTAG) { + if(arch == PARM3_ARCH_XMEGA) { + if(jtag3_getparm(pgm, SCOPE_AVR, 1, PARM3_CLK_XMEGA_JTAG, buf, 2) < 0) { pmsg_error("cannot read Xmega JTAG clock speed\n"); return -1; } } else { - if (jtag3_getparm(pgm, SCOPE_AVR, 1, PARM3_CLK_MEGA_PROG, buf, 2) < 0) { + if(jtag3_getparm(pgm, SCOPE_AVR, 1, PARM3_CLK_MEGA_PROG, buf, 2) < 0) { pmsg_error("cannot read JTAG clock speed\n"); return -1; } } - } else if (conn & (PARM3_CONN_PDI | PARM3_CONN_UPDI)) { - if (jtag3_getparm(pgm, SCOPE_AVR, 1, PARM3_CLK_XMEGA_PDI, buf, 2) < 0) { + } else if(conn & (PARM3_CONN_PDI | PARM3_CONN_UPDI)) { + if(jtag3_getparm(pgm, SCOPE_AVR, 1, PARM3_CLK_XMEGA_PDI, buf, 2) < 0) { pmsg_error("cannot read PDI/UPDI clock speed\n"); return -1; } } - if (b2_to_u16(buf) <= 0) { + if(b2_to_u16(buf) <= 0) { pmsg_error("cannot calculate programmer clock speed\n"); return -1; } @@ -2489,13 +2443,9 @@ static int jtag3_get_sck_period(const PROGRAMMER *pgm, double *v) { return 0; } - -/* - * Read (an) emulator parameter(s). - */ +// Read (an) emulator parameter(s) int jtag3_getparm(const PROGRAMMER *pgm, unsigned char scope, - unsigned char section, unsigned char parm, - unsigned char *value, unsigned char length) { + unsigned char section, unsigned char parm, unsigned char *value, unsigned char length) { int status; unsigned char buf[6], *resp, c; char descr[60]; @@ -2509,21 +2459,20 @@ int jtag3_getparm(const PROGRAMMER *pgm, unsigned char scope, buf[4] = parm; buf[5] = length; - sprintf(descr, "get parameter (scope 0x%02x, section %d, parm %d)", - scope, section, parm); + sprintf(descr, "get parameter (scope 0x%02x, section %d, parm %d)", scope, section, parm); - if ((status = jtag3_command(pgm, buf, 6, &resp, descr)) < 0) + if((status = jtag3_command(pgm, buf, 6, &resp, descr)) < 0) return -1; c = resp[1]; - if (c != RSP3_DATA || status < 3) { + if(c != RSP3_DATA || status < 3) { pmsg_notice("%s(): bad response to %s\n", __func__, descr); mmt_free(resp); return -1; } status -= 3; - if (status < 0) { + if(status < 0) { pmsg_error("unexpected return value %d from jtag3_command()\n", status); mmt_free(resp); return -1; @@ -2534,20 +2483,16 @@ int jtag3_getparm(const PROGRAMMER *pgm, unsigned char scope, return 0; } -/* - * Write an emulator parameter. - */ +// Write an emulator parameter int jtag3_setparm(const PROGRAMMER *pgm, unsigned char scope, - unsigned char section, unsigned char parm, - unsigned char *value, unsigned char length) { + unsigned char section, unsigned char parm, unsigned char *value, unsigned char length) { int status; unsigned char *buf, *resp; char descr[60]; pmsg_notice2("jtag3_setparm()\n"); - sprintf(descr, "set parameter (scope 0x%02x, section %d, parm %d)", - scope, section, parm); + sprintf(descr, "set parameter (scope 0x%02x, section %d, parm %d)", scope, section, parm); buf = mmt_malloc(6 + length); buf[0] = scope; @@ -2561,7 +2506,7 @@ int jtag3_setparm(const PROGRAMMER *pgm, unsigned char scope, status = jtag3_command(pgm, buf, length + 6, &resp, descr); mmt_free(buf); - if (status >= 0) + if(status >= 0) mmt_free(resp); return status; @@ -2579,11 +2524,11 @@ int jtag3_read_sib(const PROGRAMMER *pgm, const AVRPART *p, char *sib) { u32_to_b4(cmd + 4, 0); u32_to_b4(cmd + 8, AVR_SIBLEN); - if ((status = jtag3_command(pgm, cmd, 12, &resp, "read SIB")) < 0) + if((status = jtag3_command(pgm, cmd, 12, &resp, "read SIB")) < 0) return status; - memcpy(sib, resp+3, AVR_SIBLEN); - sib[AVR_SIBLEN-1] = 0; // Zero terminate string + memcpy(sib, resp + 3, AVR_SIBLEN); + sib[AVR_SIBLEN - 1] = 0; // Zero terminate string pmsg_debug("%s(): received SIB: %s\n", __func__, sib); mmt_free(resp); return 0; @@ -2593,13 +2538,15 @@ int jtag3_read_chip_rev(const PROGRAMMER *pgm, const AVRPART *p, unsigned char * // XMEGA using JTAG or PDI, tinyAVR0/1/2, megaAVR0, AVR-Dx, AVR-Ex using UPDI if(p->prog_modes & (PM_PDI | PM_UPDI)) { AVRMEM *m = avr_locate_io(p); + if(!m) { pmsg_error("cannot locate io memory; is avrdude.conf up to date?\n"); return -1; } int status = pgm->read_byte(pgm, p, m, - p->prog_modes & PM_PDI? p->mcu_base+3 :p->syscfg_base+1, chip_rev); - if (status < 0) + is_pdi(p)? p->mcu_base + 3: p->syscfg_base + 1, chip_rev); + + if(status < 0) return status; } else { pmsg_error("target does not have a chip revision that can be read\n"); @@ -2614,18 +2561,18 @@ int jtag3_set_vtarget(const PROGRAMMER *pgm, double v) { unsigned uaref, utarg; unsigned char buf[2]; - utarg = (unsigned)(v * 1000); + utarg = (unsigned) (v*1000); - if (jtag3_getparm(pgm, SCOPE_GENERAL, 1, PARM3_VTARGET, buf, 2) < 0) { + if(jtag3_getparm(pgm, SCOPE_GENERAL, 1, PARM3_VTARGET, buf, 2) < 0) { pmsg_warning("cannot obtain V[target]\n"); } uaref = b2_to_u16(buf); u16_to_b2(buf, utarg); - pmsg_notice2("%s(): changing V[target] from %.1f to %.1f\n", __func__, uaref / 1000.0, v); + pmsg_notice2("%s(): changing V[target] from %.1f to %.1f\n", __func__, uaref/1000.0, v); - if (jtag3_setparm(pgm, SCOPE_GENERAL, 1, PARM3_VADJUST, buf, sizeof(buf)) < 0) { + if(jtag3_setparm(pgm, SCOPE_GENERAL, 1, PARM3_VADJUST, buf, sizeof(buf)) < 0) { pmsg_error("cannot confirm new V[target] value\n"); return -1; } @@ -2657,157 +2604,155 @@ void jtag3_display(const PROGRAMMER *pgm, const char *p) { * PARM3_FW_MINOR (1 byte) * PARM3_FW_RELEASE (2 bytes) */ - if (jtag3_getparm(pgm, SCOPE_GENERAL, 0, PARM3_HW_VER, parms, 5) < 0) + if(jtag3_getparm(pgm, SCOPE_GENERAL, 0, PARM3_HW_VER, parms, 5) < 0) return; // Use serial number pulled from the USB driver. If not present, query the programmer - if (pgm->usbsn && *pgm->usbsn) + if(pgm->usbsn && *pgm->usbsn) sn = pgm->usbsn; else { unsigned char cmd[4], c; int status; + cmd[0] = SCOPE_INFO; cmd[1] = CMD3_GET_INFO; cmd[2] = 0; cmd[3] = CMD3_INFO_SERIAL; - if ((status = jtag3_command(pgm, cmd, 4, &resp, "get info (serial number)")) < 0) { + if((status = jtag3_command(pgm, cmd, 4, &resp, "get info (serial number)")) < 0) { mmt_free(resp); return; } c = resp[1]; - if (c != RSP3_INFO) { + if(c != RSP3_INFO) { pmsg_error("response is not RSP3_INFO\n"); mmt_free(resp); return; } - if (status < 3) { + if(status < 3) { msg_error("unexpected response from CMD3_GET_INFO command\n"); mmt_free(resp); return; } memmove(resp, resp + 3, status - 3); resp[status - 3] = 0; - sn = (const char*)resp; + sn = (const char *) resp; } msg_info("%sICE HW version : %d\n", p, parms[0]); - msg_info("%sICE FW version : %d.%02d (rel. %d)\n", - p, parms[1], parms[2], (parms[3] | (parms[4] << 8))); + msg_info("%sICE FW version : %d.%02d (rel. %d)\n", p, parms[1], parms[2], (parms[3] | (parms[4] << 8))); msg_info("%sSerial number : %s\n", p, sn); mmt_free(resp); } - void jtag3_print_parms1(const PROGRAMMER *pgm, const char *p, FILE *fp) { unsigned char prog_mode[2]; unsigned char buf[3]; - if (pgm->extra_features & HAS_VTARG_READ) { - if (jtag3_getparm(pgm, SCOPE_GENERAL, 1, PARM3_VTARGET, buf, 2) < 0) + if(pgm->extra_features & HAS_VTARG_READ) { + if(jtag3_getparm(pgm, SCOPE_GENERAL, 1, PARM3_VTARGET, buf, 2) < 0) return; msg_info("%sVtarget : %.2f V\n", p, b2_to_u16(buf)/1000.0); } // Print clocks if programmer type is not TPI - if (!str_eq(pgm->type, "JTAGICE3_TPI")) { + if(!str_eq(pgm->type, "JTAGICE3_TPI")) { // Get current programming mode and target type from to determine what data to print - if (jtag3_getparm(pgm, SCOPE_AVR, 1, PARM3_CONNECTION, prog_mode, 1) < 0) + if(jtag3_getparm(pgm, SCOPE_AVR, 1, PARM3_CONNECTION, prog_mode, 1) < 0) return; - if (jtag3_getparm(pgm, SCOPE_AVR, 0, PARM3_ARCH, &prog_mode[1], 1) < 0) + if(jtag3_getparm(pgm, SCOPE_AVR, 0, PARM3_ARCH, &prog_mode[1], 1) < 0) return; - if (prog_mode[0] == PARM3_CONN_JTAG) { - if (prog_mode[1] == PARM3_ARCH_XMEGA) { - if (jtag3_getparm(pgm, SCOPE_AVR, 1, PARM3_CLK_XMEGA_JTAG, buf, 2) < 0) + if(prog_mode[0] == PARM3_CONN_JTAG) { + if(prog_mode[1] == PARM3_ARCH_XMEGA) { + if(jtag3_getparm(pgm, SCOPE_AVR, 1, PARM3_CLK_XMEGA_JTAG, buf, 2) < 0) return; - if (b2_to_u16(buf) > 0) + if(b2_to_u16(buf) > 0) fmsg_out(fp, "%sJTAG clk Xmega : %u kHz\n", p, b2_to_u16(buf)); } else { - if (jtag3_getparm(pgm, SCOPE_AVR, 1, PARM3_CLK_MEGA_PROG, buf, 2) < 0) + if(jtag3_getparm(pgm, SCOPE_AVR, 1, PARM3_CLK_MEGA_PROG, buf, 2) < 0) return; - if (b2_to_u16(buf) > 0) + if(b2_to_u16(buf) > 0) fmsg_out(fp, "%sJTAG clk prog. : %u kHz\n", p, b2_to_u16(buf)); - if (jtag3_getparm(pgm, SCOPE_AVR, 1, PARM3_CLK_MEGA_DEBUG, buf, 2) < 0) + if(jtag3_getparm(pgm, SCOPE_AVR, 1, PARM3_CLK_MEGA_DEBUG, buf, 2) < 0) return; - if (b2_to_u16(buf) > 0) + if(b2_to_u16(buf) > 0) fmsg_out(fp, "%sJTAG clk debug : %u kHz\n", p, b2_to_u16(buf)); } - } - else if (prog_mode[0] == PARM3_CONN_PDI || prog_mode[0] == PARM3_CONN_UPDI) { - if (jtag3_getparm(pgm, SCOPE_AVR, 1, PARM3_CLK_XMEGA_PDI, buf, 2) < 0) + } else if(prog_mode[0] == PARM3_CONN_PDI || prog_mode[0] == PARM3_CONN_UPDI) { + if(jtag3_getparm(pgm, SCOPE_AVR, 1, PARM3_CLK_XMEGA_PDI, buf, 2) < 0) return; - if (b2_to_u16(buf) > 0) + if(b2_to_u16(buf) > 0) fmsg_out(fp, "%sPDI/UPDI clk : %u kHz\n", p, b2_to_u16(buf)); } } // Print features unique to the Power Debugger - for(LNODEID ln=lfirst(pgm->id); ln; ln=lnext(ln)) { + for(LNODEID ln = lfirst(pgm->id); ln; ln = lnext(ln)) { if(str_starts(ldata(ln), "powerdebugger")) { short analog_raw_data; // Read generator set voltage value (VOUT) - if (jtag3_getparm(pgm, SCOPE_GENERAL, 1, PARM3_VADJUST, buf, 2) < 0) + if(jtag3_getparm(pgm, SCOPE_GENERAL, 1, PARM3_VADJUST, buf, 2) < 0) return; analog_raw_data = b2_to_u16(buf); - fmsg_out(fp, "%sVout set : %.2f V\n", p, analog_raw_data / 1000.0); + fmsg_out(fp, "%sVout set : %.2f V\n", p, analog_raw_data/1000.0); // Read measured generator voltage value (VOUT) - if (jtag3_getparm(pgm, SCOPE_GENERAL, 1, PARM3_TSUP_VOLTAGE_MEAS, buf, 2) < 0) + if(jtag3_getparm(pgm, SCOPE_GENERAL, 1, PARM3_TSUP_VOLTAGE_MEAS, buf, 2) < 0) return; analog_raw_data = ((buf[0] & 0x0F) << 8) + buf[1]; - if ((buf[0] & 0xF0) != 0x30) + if((buf[0] & 0xF0) != 0x30) pmsg_error("invalid PARM3_TSUP_VOLTAGE_MEAS data packet format\n"); else { - if (analog_raw_data & 0x0800) + if(analog_raw_data & 0x0800) analog_raw_data |= 0xF000; - fmsg_out(fp, "%sVout measured : %.02f V\n", p, analog_raw_data / -200.0); + fmsg_out(fp, "%sVout measured : %.02f V\n", p, analog_raw_data/-200.0); } // Read channel A voltage - if (jtag3_getparm(pgm, SCOPE_GENERAL, 1, PARM3_ANALOG_A_VOLTAGE, buf, 2) < 0) + if(jtag3_getparm(pgm, SCOPE_GENERAL, 1, PARM3_ANALOG_A_VOLTAGE, buf, 2) < 0) return; analog_raw_data = ((buf[0] & 0x0F) << 8) + buf[1]; - if ((buf[0] & 0xF0) != 0x20) + if((buf[0] & 0xF0) != 0x20) pmsg_error("invalid PARM3_ANALOG_A_VOLTAGE data packet format\n"); else { - if (analog_raw_data & 0x0800) + if(analog_raw_data & 0x0800) analog_raw_data |= 0xF000; - fmsg_out(fp, "%sCh A voltage : %.03f V\n", p, analog_raw_data / -200.0); + fmsg_out(fp, "%sCh A voltage : %.03f V\n", p, analog_raw_data/-200.0); } // Read channel A current - if (jtag3_getparm(pgm, SCOPE_GENERAL, 1, PARM3_ANALOG_A_CURRENT, buf, 3) < 0) + if(jtag3_getparm(pgm, SCOPE_GENERAL, 1, PARM3_ANALOG_A_CURRENT, buf, 3) < 0) return; analog_raw_data = (buf[1] << 8) + buf[2]; - if (buf[0] != 0x90) + if(buf[0] != 0x90) pmsg_error("invalid PARM3_ANALOG_A_CURRENT data packet format\n"); else - fmsg_out(fp, "%sCh A current : %.3f mA\n", p, analog_raw_data * 0.003472); + fmsg_out(fp, "%sCh A current : %.3f mA\n", p, analog_raw_data*0.003472); // Read channel B voltage - if (jtag3_getparm(pgm, SCOPE_GENERAL, 1, PARM3_ANALOG_B_VOLTAGE, buf, 2) < 0) + if(jtag3_getparm(pgm, SCOPE_GENERAL, 1, PARM3_ANALOG_B_VOLTAGE, buf, 2) < 0) return; analog_raw_data = ((buf[0] & 0x0F) << 8) + buf[1]; - if ((buf[0] & 0xF0) != 0x10) + if((buf[0] & 0xF0) != 0x10) pmsg_error("invalid PARM3_ANALOG_B_VOLTAGE data packet format\n"); else { - if (analog_raw_data & 0x0800) + if(analog_raw_data & 0x0800) analog_raw_data |= 0xF000; - fmsg_out(fp, "%sCh B voltage : %.03f V\n", p, analog_raw_data / -200.0); + fmsg_out(fp, "%sCh B voltage : %.03f V\n", p, analog_raw_data/-200.0); } // Read channel B current - if (jtag3_getparm(pgm, SCOPE_GENERAL, 1, PARM3_ANALOG_B_CURRENT, buf, 3) < 0) + if(jtag3_getparm(pgm, SCOPE_GENERAL, 1, PARM3_ANALOG_B_CURRENT, buf, 3) < 0) return; analog_raw_data = ((buf[0] & 0x0F) << 8) + buf[1]; - if ((buf[0] & 0xF0) != 0x00) + if((buf[0] & 0xF0) != 0x00) pmsg_error("invalid PARM3_ANALOG_B_CURRENT data packet format\n"); else { - if (analog_raw_data & 0x0800) + if(analog_raw_data & 0x0800) analog_raw_data |= 0xF000; - fmsg_out(fp, "%sCh B current : %.3f mA\n", p, analog_raw_data * 0.555556); + fmsg_out(fp, "%sCh B current : %.3f mA\n", p, analog_raw_data*0.555556); } break; } @@ -2819,24 +2764,23 @@ static void jtag3_print_parms(const PROGRAMMER *pgm, FILE *fp) { jtag3_print_parms1(pgm, "", fp); } -static unsigned char jtag3_mtype(const PROGRAMMER *pgm, const AVRPART *p, const AVRMEM *m, - unsigned long addr) { +static unsigned char jtag3_mtype(const PROGRAMMER *pgm, const AVRPART *p, const AVRMEM *m, unsigned long addr) { return !is_pdi(p)? MTYPE_FLASH_PAGE: mem_is_boot(m)? MTYPE_BOOT_FLASH: - mem_is_flash(m) && is_pdi(p) && addr >= PDATA(pgm)->boot_start? MTYPE_BOOT_FLASH: - MTYPE_FLASH; + mem_is_flash(m) && is_pdi(p) && addr >= my.boot_start? MTYPE_BOOT_FLASH: MTYPE_FLASH; } static unsigned int jtag3_memaddr(const PROGRAMMER *pgm, const AVRPART *p, const AVRMEM *m, unsigned long addr) { - if(is_pdi(p)) { // Xmega - if(mem_is_flash(m) && addr >= PDATA(pgm)->boot_start) // Boot is special and gets its own region - addr -= PDATA(pgm)->boot_start; - if(mem_is_in_flash(m) && !mem_is_boot(m)) // Apptable, application and flash + if(is_pdi(p)) { // Xmega + if(mem_is_flash(m) && addr >= my.boot_start) // Boot is special and gets its own region + addr -= my.boot_start; + if(mem_is_in_flash(m) && !mem_is_boot(m)) // Apptable, application and flash addr += avr_flash_offset(p, m, addr); if(mem_is_in_sigrow(m)) { AVRMEM *sigrow = avr_locate_sigrow(p); + if(sigrow) addr += m->offset - sigrow->offset; } @@ -2849,6 +2793,7 @@ static unsigned int jtag3_memaddr(const PROGRAMMER *pgm, const AVRPART *p, const addr += m->offset; else if(mem_is_in_sigrow(m)) { AVRMEM *sigrow = avr_locate_sigrow(p); + if(sigrow) addr += m->offset - sigrow->offset; } @@ -2866,16 +2811,14 @@ static unsigned char tpi_get_mtype(const AVRMEM *m) { XPRG_MEM_TYPE_APPL; // Sic, TPI parts do not have eeprom } -/* - * Send the data as a JTAGICE3 encapsulated TPI packet. - */ +// Send the data as a JTAGICE3 encapsulated TPI packet static int jtag3_send_tpi(const PROGRAMMER *pgm, unsigned char *data, size_t len) { unsigned char *cmdbuf; int rv; cmdbuf = mmt_malloc(len + 1); cmdbuf[0] = SCOPE_AVR_TPI; - if (len > INT_MAX) { + if(len > INT_MAX) { pmsg_error("invalid jtag3_send_tpi() packet length %lu\n", (unsigned long) len); mmt_free(cmdbuf); return -1; @@ -2883,7 +2826,7 @@ static int jtag3_send_tpi(const PROGRAMMER *pgm, unsigned char *data, size_t len memcpy(cmdbuf + 1, data, len); msg_trace("[TPI send] "); - for (size_t i=1; i<=len; i++) + for(size_t i = 1; i <= len; i++) msg_trace("0x%02x ", cmdbuf[i]); msg_trace("\n"); @@ -2898,7 +2841,7 @@ int jtag3_recv_tpi(const PROGRAMMER *pgm, unsigned char **msg) { rv = jtag3_recv(pgm, msg); - if (rv <= 0) { + if(rv <= 0) { pmsg_error("%s(): unable to receive\n", __func__); return -1; } @@ -2906,7 +2849,7 @@ int jtag3_recv_tpi(const PROGRAMMER *pgm, unsigned char **msg) { memcpy(*msg, *msg + 1, rv); msg_trace("[TPI recv] "); - for (int i=0; ivtarg_get || PDATA(pgm)->vtarg_set) { + if(my.vtarg_get || my.vtarg_set) { // Read current target voltage set value unsigned char buf[2]; - if (jtag3_getparm(pgm, SCOPE_GENERAL, 1, PARM3_VADJUST, buf, 2) < 0) + + if(jtag3_getparm(pgm, SCOPE_GENERAL, 1, PARM3_VADJUST, buf, 2) < 0) return -1; - double vtarg_read = b2_to_u16(buf) / 1000.0; - if (PDATA(pgm)->vtarg_get) + double vtarg_read = b2_to_u16(buf)/1000.0; + + if(my.vtarg_get) msg_info("Target voltage value read as %.2fV\n", vtarg_read); // Write target voltage value else { - u16_to_b2(buf, (unsigned)(PDATA(pgm)->vtarg_data * 1000)); - msg_info("Changing target voltage from %.2f to %.2fV\n", vtarg_read, PDATA(pgm)->vtarg_data); - if (jtag3_setparm(pgm, SCOPE_GENERAL, 1, PARM3_VADJUST, buf, sizeof(buf)) < 0) { - msg_warning("Cannot set target voltage %.2fV\n", PDATA(pgm)->vtarg_data); + u16_to_b2(buf, (unsigned) (my.vtarg_data*1000)); + msg_info("Changing target voltage from %.2f to %.2fV\n", vtarg_read, my.vtarg_data); + if(jtag3_setparm(pgm, SCOPE_GENERAL, 1, PARM3_VADJUST, buf, sizeof(buf)) < 0) { + msg_warning("Cannot set target voltage %.2fV\n", my.vtarg_data); return -1; } } } - if (verbose > 0 && quell_progress < 2) + if(verbose > 0 && quell_progress < 2) jtag3_print_parms1(pgm, progbuf, stderr); pmsg_notice2("jtag3_initialize_tpi() start\n"); cmd[0] = XPRG_CMD_ENTER_PROGMODE; - if ((status = jtag3_command_tpi(pgm, cmd, 1, &resp, "Enter Progmode")) < 0) + if((status = jtag3_command_tpi(pgm, cmd, 1, &resp, "Enter Progmode")) < 0) return -1; mmt_free(resp); @@ -2982,7 +2926,7 @@ static int jtag3_initialize_tpi(const PROGRAMMER *pgm, const AVRPART *p) { cmd[1] = XPRG_PARAM_NVMCMD_ADDR; cmd[2] = TPI_NVMCMD_ADDRESS; - if ((status = jtag3_command_tpi(pgm, cmd, 3, &resp, "Set NVMCMD")) < 0) + if((status = jtag3_command_tpi(pgm, cmd, 3, &resp, "Set NVMCMD")) < 0) return -1; mmt_free(resp); @@ -2990,7 +2934,7 @@ static int jtag3_initialize_tpi(const PROGRAMMER *pgm, const AVRPART *p) { cmd[1] = XPRG_PARAM_NVMCSR_ADDR; cmd[2] = TPI_NVMCSR_ADDRESS; - if ((status = jtag3_command_tpi(pgm, cmd, 3, &resp, "Set NVMCSR")) < 0) + if((status = jtag3_command_tpi(pgm, cmd, 3, &resp, "Set NVMCSR")) < 0) return -1; mmt_free(resp); @@ -3003,22 +2947,22 @@ static void jtag3_enable_tpi(PROGRAMMER *pgm, const AVRPART *p) { static void jtag3_disable_tpi(const PROGRAMMER *pgm) { unsigned char cmd[1]; - unsigned char* resp; + unsigned char *resp; int status; cmd[0] = XPRG_CMD_LEAVE_PROGMODE; - if ((status = jtag3_command_tpi(pgm, cmd, 1, &resp, "Leave Progmode")) < 0) + if((status = jtag3_command_tpi(pgm, cmd, 1, &resp, "Leave Progmode")) < 0) return; mmt_free(resp); } static int jtag3_read_byte_tpi(const PROGRAMMER *pgm, const AVRPART *p, const AVRMEM *mem, - unsigned long addr, unsigned char * value) { + unsigned long addr, unsigned char *value) { int status; const size_t len = 8; - unsigned char cmd[8]; // Using "len" as array length causes msvc build jobs to fail with error C2057: expected constant expression - unsigned char* resp; + unsigned char cmd[8]; + unsigned char *resp; unsigned long paddr = 0UL; msg_notice2("\n"); @@ -3028,53 +2972,53 @@ static int jtag3_read_byte_tpi(const PROGRAMMER *pgm, const AVRPART *p, const AV cmd[0] = XPRG_CMD_READ_MEM; cmd[1] = tpi_get_mtype(mem); - u32_to_b4_big_endian((cmd+2), paddr); // Address - u16_to_b2_big_endian((cmd+6), 1); // Size + u32_to_b4_big_endian((cmd + 2), paddr); // Address + u16_to_b2_big_endian((cmd + 6), 1); // Size - if ((status = jtag3_command_tpi(pgm, cmd, len, &resp, "Read Byte")) < 0) + if((status = jtag3_command_tpi(pgm, cmd, len, &resp, "Read Byte")) < 0) return -1; *value = resp[2]; mmt_free(resp); return 0; } -static int jtag3_erase_tpi(const PROGRAMMER *pgm, const AVRPART *p, const AVRMEM *mem, - unsigned long addr) { +static int jtag3_erase_tpi(const PROGRAMMER *pgm, const AVRPART *p, const AVRMEM *mem, unsigned long addr) { const size_t len = 6; - unsigned char cmd[6]; // Using "len" as array length causes msvc build jobs to fail with error C2057: expected constant expression - unsigned char* resp; + unsigned char cmd[6]; + unsigned char *resp; int status; unsigned long paddr = 0UL; cmd[0] = XPRG_CMD_ERASE; - if (mem_is_a_fuse(mem)) { + if(mem_is_a_fuse(mem)) { cmd[1] = XPRG_ERASE_CONFIG; - } else if (mem_is_flash(mem)) { + } else if(mem_is_flash(mem)) { cmd[1] = XPRG_ERASE_APP; } else { pmsg_error("jtag3_erase_tpi() unsupported memory: %s\n", mem->desc); return -1; } paddr = (mem->offset + addr) | 0x01; // An erase is triggered by an access to the hi-byte - u32_to_b4_big_endian((cmd+2), paddr); + u32_to_b4_big_endian((cmd + 2), paddr); - if ((status = jtag3_command_tpi(pgm, cmd, len, &resp, "Erase")) < 0) + if((status = jtag3_command_tpi(pgm, cmd, len, &resp, "Erase")) < 0) return -1; mmt_free(resp); return 0; } static int jtag3_write_byte_tpi(const PROGRAMMER *pgm, const AVRPART *p, const AVRMEM *mem, - unsigned long addr, unsigned char data) { + unsigned long addr, unsigned char data) { size_t len = 11; size_t data_size = 2; unsigned char cmd[17]; - unsigned char* resp; + unsigned char *resp; int status; unsigned long paddr = 0UL; if(mem_is_readonly(mem)) { unsigned char is; + if(pgm->read_byte(pgm, p, mem, addr, &is) >= 0 && is == data) return 0; @@ -3082,9 +3026,9 @@ static int jtag3_write_byte_tpi(const PROGRAMMER *pgm, const AVRPART *p, const A return -1; } - if (mem_is_a_fuse(mem) || mem_is_flash(mem)) { + if(mem_is_a_fuse(mem) || mem_is_flash(mem)) { status = jtag3_erase_tpi(pgm, p, mem, addr); - if (status < 0) { + if(status < 0) { pmsg_error("error in communication, received status 0x%02x\n", status); return -1; } @@ -3092,12 +3036,11 @@ static int jtag3_write_byte_tpi(const PROGRAMMER *pgm, const AVRPART *p, const A paddr = mem->offset + addr; - if (mem->n_word_writes != 0) { - if (mem->n_word_writes == 2) { + if(mem->n_word_writes != 0) { + if(mem->n_word_writes == 2) { len = 13; data_size = 4; - } - else if (mem->n_word_writes == 4) { + } else if(mem->n_word_writes == 4) { len = 17; data_size = 8; } @@ -3105,19 +3048,19 @@ static int jtag3_write_byte_tpi(const PROGRAMMER *pgm, const AVRPART *p, const A cmd[0] = XPRG_CMD_WRITE_MEM; cmd[1] = tpi_get_mtype(mem); - cmd[2] = 0; // Page Mode - Not used - u32_to_b4_big_endian((cmd+3), paddr); // Address - u16_to_b2_big_endian((cmd+7), data_size); // Size + cmd[2] = 0; // Page Mode - Not used + u32_to_b4_big_endian((cmd + 3), paddr); // Address + u16_to_b2_big_endian((cmd + 7), data_size); // Size cmd[9] = data; - cmd[10] = 0xFF; // len = 11 if no n_word_writes + cmd[10] = 0xFF; // len = 11 if no n_word_writes cmd[11] = 0xFF; - cmd[12] = 0xFF; // len = 13 if n_word_writes == 2 + cmd[12] = 0xFF; // len = 13 if n_word_writes == 2 cmd[13] = 0xFF; cmd[14] = 0xFF; cmd[15] = 0xFF; - cmd[16] = 0xFF; // len = 17 if n_word_writes == 4 + cmd[16] = 0xFF; // len = 17 if n_word_writes == 4 - if ((status = jtag3_command_tpi(pgm, cmd, len, &resp, "Write Byte")) < 0) + if((status = jtag3_command_tpi(pgm, cmd, len, &resp, "Write Byte")) < 0) return -1; mmt_free(resp); return 0; @@ -3125,13 +3068,14 @@ static int jtag3_write_byte_tpi(const PROGRAMMER *pgm, const AVRPART *p, const A static int jtag3_chip_erase_tpi(const PROGRAMMER *pgm, const AVRPART *p) { const size_t len = 6; - unsigned char cmd[6]; // Using "len" as array length causes msvc build jobs to fail with error C2057: expected constant expression - unsigned char* resp; + unsigned char cmd[6]; + unsigned char *resp; int status; unsigned long paddr = 0UL; AVRMEM *m = avr_locate_flash(p); - if (m == NULL) { + + if(m == NULL) { pmsg_error("no flash memory for part %s\n", p->desc); return LIBAVRDUDE_GENERAL_FAILURE; } @@ -3141,9 +3085,9 @@ static int jtag3_chip_erase_tpi(const PROGRAMMER *pgm, const AVRPART *p) { cmd[0] = XPRG_CMD_ERASE; cmd[1] = XPRG_ERASE_CHIP; - u32_to_b4_big_endian((cmd+2), paddr); + u32_to_b4_big_endian((cmd + 2), paddr); - if ((status = jtag3_command_tpi(pgm, cmd, len, &resp, "Chip Erase")) < 0) + if((status = jtag3_command_tpi(pgm, cmd, len, &resp, "Chip Erase")) < 0) return -1; mmt_free(resp); return 0; @@ -3152,7 +3096,7 @@ static int jtag3_chip_erase_tpi(const PROGRAMMER *pgm, const AVRPART *p) { static int jtag3_open_tpi(PROGRAMMER *pgm, const char *port) { pmsg_notice2("jtag3_open_tpi()\n"); - return jtag3_open_common(pgm, port, PDATA(pgm)->pk4_snap_mode); + return jtag3_open_common(pgm, port, my.pk4_snap_mode); } void jtag3_close_tpi(PROGRAMMER *pgm) { @@ -3160,8 +3104,7 @@ void jtag3_close_tpi(PROGRAMMER *pgm) { } static int jtag3_paged_load_tpi(const PROGRAMMER *pgm, const AVRPART *p, - const AVRMEM *m, unsigned int page_size, - unsigned int addr, unsigned int n_bytes) { + const AVRMEM *m, unsigned int page_size, unsigned int addr, unsigned int n_bytes) { unsigned int block_size = 0; unsigned int maxaddr = addr + n_bytes; unsigned char cmd[8]; @@ -3170,11 +3113,10 @@ static int jtag3_paged_load_tpi(const PROGRAMMER *pgm, const AVRPART *p, long otimeout = serial_recv_timeout; msg_notice2("\n"); - pmsg_notice2("jtag3_paged_load_tpi(.., %s, %d, 0x%04x, %d)\n", - m->desc, page_size, addr, n_bytes); + pmsg_notice2("jtag3_paged_load_tpi(.., %s, %d, 0x%04x, %d)\n", m->desc, page_size, addr, n_bytes); if(m->offset) - imsg_notice2("mapped to address: 0x%04x\n", (addr+m->offset)); + imsg_notice2("mapped to address: 0x%04x\n", (addr + m->offset)); cmd[0] = XPRG_CMD_READ_MEM; cmd[1] = tpi_get_mtype(m); @@ -3183,27 +3125,27 @@ static int jtag3_paged_load_tpi(const PROGRAMMER *pgm, const AVRPART *p, page_size = m->blocksize; serial_recv_timeout = 100; - for (; addr < maxaddr; addr += page_size) { - if ((maxaddr - addr) < page_size) + for(; addr < maxaddr; addr += page_size) { + if((maxaddr - addr) < page_size) block_size = maxaddr - addr; else block_size = page_size; pmsg_debug("%s(): block_size at addr 0x%x is %d\n", __func__, addr, block_size); - u32_to_b4_big_endian((cmd+2), addr + m->offset); // Address - u16_to_b2_big_endian((cmd+6), block_size); // Size + u32_to_b4_big_endian((cmd + 2), addr + m->offset); // Address + u16_to_b2_big_endian((cmd + 6), block_size); // Size - if ((status = jtag3_command_tpi(pgm, cmd, 8, &resp, "Read Memory")) < 0) + if((status = jtag3_command_tpi(pgm, cmd, 8, &resp, "Read Memory")) < 0) return -1; - if (resp[1] != XPRG_ERR_OK || status < (int) block_size + 2) { + if(resp[1] != XPRG_ERR_OK || status < (int) block_size + 2) { pmsg_error("wrong/short reply to read memory command\n"); serial_recv_timeout = otimeout; mmt_free(resp); return -1; } - if (status < 2) { + if(status < 2) { pmsg_error("unexpected return value %d from jtag3_paged_load_tpi()\n", status); mmt_free(resp); return -1; @@ -3218,8 +3160,7 @@ static int jtag3_paged_load_tpi(const PROGRAMMER *pgm, const AVRPART *p, } static int jtag3_paged_write_tpi(const PROGRAMMER *pgm, const AVRPART *p, - const AVRMEM *m, unsigned int page_size, - unsigned int addr, unsigned int n_bytes) { + const AVRMEM *m, unsigned int page_size, unsigned int addr, unsigned int n_bytes) { unsigned int block_size; unsigned int maxaddr = addr + n_bytes; unsigned char *cmd; @@ -3231,37 +3172,36 @@ static int jtag3_paged_write_tpi(const PROGRAMMER *pgm, const AVRPART *p, pmsg_notice2("jtag3_paged_write_tpi(.., %s, %d, 0x%04x, %d)\n", m->desc, page_size, addr, n_bytes); if(m->offset) - imsg_notice2("mapped to address: 0x%04x\n", (addr+m->offset)); + imsg_notice2("mapped to address: 0x%04x\n", (addr + m->offset)); - if (page_size == 0) + if(page_size == 0) page_size = m->page_size; cmd = mmt_malloc(page_size + 9); cmd[0] = XPRG_CMD_WRITE_MEM; cmd[1] = tpi_get_mtype(m); - cmd[2] = 0; // Page Mode; Not used - ignored + cmd[2] = 0; // Page Mode; Not used - ignored serial_recv_timeout = 100; - for (; addr < maxaddr; addr += page_size) { - if ((maxaddr - addr) < page_size) + for(; addr < maxaddr; addr += page_size) { + if((maxaddr - addr) < page_size) block_size = maxaddr - addr; else block_size = page_size; pmsg_debug("%s(): block_size at addr 0x%x is %d\n", __func__, addr, block_size); - u32_to_b4_big_endian((cmd+3), addr + m->offset); // Address - u16_to_b2_big_endian((cmd+7), page_size); // Size + u32_to_b4_big_endian((cmd + 3), addr + m->offset); // Address + u16_to_b2_big_endian((cmd + 7), page_size); // Size /* - * If a partial page has been requested, set the remainder to 0xff. - * (Maybe we should rather read back the existing contents instead - * before? Doesn't matter much, as bits cannot be written to 1 anyway.) + * If a partial page has been requested, set the remainder to 0xff. (Maybe + * we should rather read back the existing contents instead before? + * Doesn't matter much, as bits cannot be written to 1 anyway.) */ memset(cmd + 9, 0xff, page_size); memcpy(cmd + 9, m->buf + addr, block_size); - if ((status = jtag3_command_tpi(pgm, cmd, page_size + 9, - &resp, "Write Memory")) < 0) { + if((status = jtag3_command_tpi(pgm, cmd, page_size + 9, &resp, "Write Memory")) < 0) { mmt_free(cmd); serial_recv_timeout = otimeout; return -1; @@ -3276,49 +3216,42 @@ static int jtag3_paged_write_tpi(const PROGRAMMER *pgm, const AVRPART *p, return n_bytes; } - const char jtag3_desc[] = "Atmel JTAGICE3"; void jtag3_initpgm(PROGRAMMER *pgm) { strcpy(pgm->type, "JTAGICE3"); - /* - * mandatory functions - */ - pgm->initialize = jtag3_initialize; - pgm->display = jtag3_display; - pgm->enable = jtag3_enable; - pgm->disable = jtag3_disable; + // Mandatory functions + pgm->initialize = jtag3_initialize; + pgm->display = jtag3_display; + pgm->enable = jtag3_enable; + pgm->disable = jtag3_disable; pgm->program_enable = jtag3_program_enable_dummy; - pgm->chip_erase = jtag3_chip_erase; - pgm->open = jtag3_open; - pgm->close = jtag3_close; - pgm->read_byte = jtag3_read_byte; - pgm->write_byte = jtag3_write_byte; - - /* - * optional functions - */ - pgm->paged_write = jtag3_paged_write; - pgm->paged_load = jtag3_paged_load; - pgm->page_erase = jtag3_page_erase; - pgm->print_parms = jtag3_print_parms; + pgm->chip_erase = jtag3_chip_erase; + pgm->open = jtag3_open; + pgm->close = jtag3_close; + pgm->read_byte = jtag3_read_byte; + pgm->write_byte = jtag3_write_byte; + + // Optional functions + pgm->paged_write = jtag3_paged_write; + pgm->paged_load = jtag3_paged_load; + pgm->page_erase = jtag3_page_erase; + pgm->print_parms = jtag3_print_parms; pgm->set_sck_period = jtag3_set_sck_period; pgm->get_sck_period = jtag3_get_sck_period; pgm->parseextparams = jtag3_parseextparms; - pgm->setup = jtag3_setup; - pgm->teardown = jtag3_teardown; - pgm->page_size = 256; - pgm->flag = PGM_FL_IS_JTAG; - pgm->read_chip_rev = jtag3_read_chip_rev; + pgm->setup = jtag3_setup; + pgm->teardown = jtag3_teardown; + pgm->page_size = 256; + pgm->flag = PGM_FL_IS_JTAG; + pgm->read_chip_rev = jtag3_read_chip_rev; - /* - * hardware dependent functions - */ - if (pgm->extra_features & HAS_VTARG_READ) - pgm->get_vtarget = jtag3_get_vtarget; - if (pgm->extra_features & HAS_VTARG_ADJ) - pgm->set_vtarget = jtag3_set_vtarget; + // Hardware dependent functions + if(pgm->extra_features & HAS_VTARG_READ) + pgm->get_vtarget = jtag3_get_vtarget; + if(pgm->extra_features & HAS_VTARG_ADJ) + pgm->set_vtarget = jtag3_set_vtarget; } const char jtag3_dw_desc[] = "Atmel JTAGICE3 in debugWire mode"; @@ -3326,40 +3259,34 @@ const char jtag3_dw_desc[] = "Atmel JTAGICE3 in debugWire mode"; void jtag3_dw_initpgm(PROGRAMMER *pgm) { strcpy(pgm->type, "JTAGICE3_DW"); - /* - * mandatory functions - */ - pgm->initialize = jtag3_initialize; - pgm->display = jtag3_display; - pgm->enable = jtag3_enable; - pgm->disable = jtag3_disable; + // Mandatory functions + pgm->initialize = jtag3_initialize; + pgm->display = jtag3_display; + pgm->enable = jtag3_enable; + pgm->disable = jtag3_disable; pgm->program_enable = jtag3_program_enable_dummy; - pgm->chip_erase = jtag3_chip_erase_dw; - pgm->open = jtag3_open_dw; - pgm->close = jtag3_close; - pgm->read_byte = jtag3_read_byte; - pgm->write_byte = jtag3_write_byte; - - /* - * optional functions - */ - pgm->paged_write = jtag3_paged_write; - pgm->paged_load = jtag3_paged_load; - pgm->page_erase = NULL; - pgm->print_parms = jtag3_print_parms; + pgm->chip_erase = jtag3_chip_erase_dw; + pgm->open = jtag3_open_dw; + pgm->close = jtag3_close; + pgm->read_byte = jtag3_read_byte; + pgm->write_byte = jtag3_write_byte; + + // Optional functions + pgm->paged_write = jtag3_paged_write; + pgm->paged_load = jtag3_paged_load; + pgm->page_erase = NULL; + pgm->print_parms = jtag3_print_parms; pgm->parseextparams = jtag3_parseextparms; - pgm->setup = jtag3_setup; - pgm->teardown = jtag3_teardown; - pgm->page_size = 256; - pgm->flag = PGM_FL_IS_DW; + pgm->setup = jtag3_setup; + pgm->teardown = jtag3_teardown; + pgm->page_size = 256; + pgm->flag = PGM_FL_IS_DW; - /* - * hardware dependent functions - */ - if (pgm->extra_features & HAS_VTARG_READ) - pgm->get_vtarget = jtag3_get_vtarget; - if (pgm->extra_features & HAS_VTARG_ADJ) - pgm->set_vtarget = jtag3_set_vtarget; + // Hardware dependent functions + if(pgm->extra_features & HAS_VTARG_READ) + pgm->get_vtarget = jtag3_get_vtarget; + if(pgm->extra_features & HAS_VTARG_ADJ) + pgm->set_vtarget = jtag3_set_vtarget; } const char jtag3_pdi_desc[] = "Atmel JTAGICE3 in PDI mode"; @@ -3367,43 +3294,37 @@ const char jtag3_pdi_desc[] = "Atmel JTAGICE3 in PDI mode"; void jtag3_pdi_initpgm(PROGRAMMER *pgm) { strcpy(pgm->type, "JTAGICE3_PDI"); - /* - * mandatory functions - */ - pgm->initialize = jtag3_initialize; - pgm->display = jtag3_display; - pgm->enable = jtag3_enable; - pgm->disable = jtag3_disable; + // Mandatory functions + pgm->initialize = jtag3_initialize; + pgm->display = jtag3_display; + pgm->enable = jtag3_enable; + pgm->disable = jtag3_disable; pgm->program_enable = jtag3_program_enable_dummy; - pgm->chip_erase = jtag3_chip_erase; - pgm->open = jtag3_open_pdi; - pgm->close = jtag3_close; - pgm->read_byte = jtag3_read_byte; - pgm->write_byte = jtag3_write_byte; - - /* - * optional functions - */ - pgm->paged_write = jtag3_paged_write; - pgm->paged_load = jtag3_paged_load; - pgm->page_erase = jtag3_page_erase; - pgm->print_parms = jtag3_print_parms; + pgm->chip_erase = jtag3_chip_erase; + pgm->open = jtag3_open_pdi; + pgm->close = jtag3_close; + pgm->read_byte = jtag3_read_byte; + pgm->write_byte = jtag3_write_byte; + + // Optional functions + pgm->paged_write = jtag3_paged_write; + pgm->paged_load = jtag3_paged_load; + pgm->page_erase = jtag3_page_erase; + pgm->print_parms = jtag3_print_parms; pgm->set_sck_period = jtag3_set_sck_period; pgm->get_sck_period = jtag3_get_sck_period; pgm->parseextparams = jtag3_parseextparms; - pgm->setup = jtag3_setup; - pgm->teardown = jtag3_teardown; - pgm->page_size = 256; - pgm->flag = PGM_FL_IS_PDI; - pgm->read_chip_rev = jtag3_read_chip_rev; + pgm->setup = jtag3_setup; + pgm->teardown = jtag3_teardown; + pgm->page_size = 256; + pgm->flag = PGM_FL_IS_PDI; + pgm->read_chip_rev = jtag3_read_chip_rev; - /* - * hardware dependent functions - */ - if (pgm->extra_features & HAS_VTARG_READ) - pgm->get_vtarget = jtag3_get_vtarget; - if (pgm->extra_features & HAS_VTARG_ADJ) - pgm->set_vtarget = jtag3_set_vtarget; + // Hardware dependent functions + if(pgm->extra_features & HAS_VTARG_READ) + pgm->get_vtarget = jtag3_get_vtarget; + if(pgm->extra_features & HAS_VTARG_ADJ) + pgm->set_vtarget = jtag3_set_vtarget; } const char jtag3_updi_desc[] = "Atmel JTAGICE3 in UPDI mode"; @@ -3411,45 +3332,39 @@ const char jtag3_updi_desc[] = "Atmel JTAGICE3 in UPDI mode"; void jtag3_updi_initpgm(PROGRAMMER *pgm) { strcpy(pgm->type, "JTAGICE3_UPDI"); - /* - * mandatory functions - */ - pgm->initialize = jtag3_initialize; - pgm->display = jtag3_display; - pgm->enable = jtag3_enable; - pgm->disable = jtag3_disable; + // Mandatory functions + pgm->initialize = jtag3_initialize; + pgm->display = jtag3_display; + pgm->enable = jtag3_enable; + pgm->disable = jtag3_disable; pgm->program_enable = jtag3_program_enable_dummy; - pgm->chip_erase = jtag3_chip_erase; - pgm->open = jtag3_open_updi; - pgm->close = jtag3_close; - pgm->read_byte = jtag3_read_byte; - pgm->write_byte = jtag3_write_byte; - - /* - * optional functions - */ - pgm->paged_write = jtag3_paged_write; - pgm->paged_load = jtag3_paged_load; - pgm->page_erase = jtag3_page_erase; - pgm->print_parms = jtag3_print_parms; + pgm->chip_erase = jtag3_chip_erase; + pgm->open = jtag3_open_updi; + pgm->close = jtag3_close; + pgm->read_byte = jtag3_read_byte; + pgm->write_byte = jtag3_write_byte; + + // Optional functions + pgm->paged_write = jtag3_paged_write; + pgm->paged_load = jtag3_paged_load; + pgm->page_erase = jtag3_page_erase; + pgm->print_parms = jtag3_print_parms; pgm->set_sck_period = jtag3_set_sck_period; pgm->get_sck_period = jtag3_get_sck_period; pgm->parseextparams = jtag3_parseextparms; - pgm->setup = jtag3_setup; - pgm->teardown = jtag3_teardown; - pgm->page_size = 256; - pgm->flag = PGM_FL_IS_UPDI; - pgm->unlock = jtag3_unlock_erase_key; - pgm->read_sib = jtag3_read_sib; - pgm->read_chip_rev = jtag3_read_chip_rev; + pgm->setup = jtag3_setup; + pgm->teardown = jtag3_teardown; + pgm->page_size = 256; + pgm->flag = PGM_FL_IS_UPDI; + pgm->unlock = jtag3_unlock_erase_key; + pgm->read_sib = jtag3_read_sib; + pgm->read_chip_rev = jtag3_read_chip_rev; - /* - * hardware dependent functions - */ - if (pgm->extra_features & HAS_VTARG_READ) - pgm->get_vtarget = jtag3_get_vtarget; - if (pgm->extra_features & HAS_VTARG_ADJ) - pgm->set_vtarget = jtag3_set_vtarget; + // Hardware dependent functions + if(pgm->extra_features & HAS_VTARG_READ) + pgm->get_vtarget = jtag3_get_vtarget; + if(pgm->extra_features & HAS_VTARG_ADJ) + pgm->set_vtarget = jtag3_set_vtarget; } const char jtag3_tpi_desc[] = "Atmel JTAGICE3 in TPI mode"; @@ -3457,36 +3372,30 @@ const char jtag3_tpi_desc[] = "Atmel JTAGICE3 in TPI mode"; void jtag3_tpi_initpgm(PROGRAMMER *pgm) { strcpy(pgm->type, "JTAGICE3_TPI"); - /* - * mandatory functions - */ - pgm->initialize = jtag3_initialize_tpi; - pgm->display = jtag3_display; - pgm->enable = jtag3_enable_tpi; - pgm->disable = jtag3_disable_tpi; + // Mandatory functions + pgm->initialize = jtag3_initialize_tpi; + pgm->display = jtag3_display; + pgm->enable = jtag3_enable_tpi; + pgm->disable = jtag3_disable_tpi; pgm->program_enable = jtag3_program_enable_dummy; - pgm->chip_erase = jtag3_chip_erase_tpi; - pgm->open = jtag3_open_tpi; - pgm->close = jtag3_close_tpi; - pgm->read_byte = jtag3_read_byte_tpi; - pgm->write_byte = jtag3_write_byte_tpi; - - /* - * optional functions - */ - pgm->paged_write = jtag3_paged_write_tpi; - pgm->paged_load = jtag3_paged_load_tpi; - pgm->page_erase = NULL; - pgm->print_parms = jtag3_print_parms; + pgm->chip_erase = jtag3_chip_erase_tpi; + pgm->open = jtag3_open_tpi; + pgm->close = jtag3_close_tpi; + pgm->read_byte = jtag3_read_byte_tpi; + pgm->write_byte = jtag3_write_byte_tpi; + + // Optional functions + pgm->paged_write = jtag3_paged_write_tpi; + pgm->paged_load = jtag3_paged_load_tpi; + pgm->page_erase = NULL; + pgm->print_parms = jtag3_print_parms; pgm->parseextparams = jtag3_parseextparms; - pgm->setup = jtag3_setup; - pgm->teardown = jtag3_teardown; - pgm->page_size = 256; - pgm->flag = PGM_FL_IS_TPI; - - /* - * hardware dependent functions - */ - if (pgm->extra_features & HAS_VTARG_READ) - pgm->get_vtarget = jtag3_get_vtarget; + pgm->setup = jtag3_setup; + pgm->teardown = jtag3_teardown; + pgm->page_size = 256; + pgm->flag = PGM_FL_IS_TPI; + + // Hardware dependent functions + if(pgm->extra_features & HAS_VTARG_READ) + pgm->get_vtarget = jtag3_get_vtarget; } diff --git a/src/jtag3.h b/src/jtag3.h index c130cb275..18e810239 100644 --- a/src/jtag3.h +++ b/src/jtag3.h @@ -24,44 +24,37 @@ extern "C" { #endif -int jtag3_open_common(PROGRAMMER *pgm, const char *port, int mode_switch); -int jtag3_send(const PROGRAMMER *pgm, unsigned char *data, size_t len); -int jtag3_recv(const PROGRAMMER *pgm, unsigned char **msg); -void jtag3_close(PROGRAMMER * pgm); -int jtag3_getsync(const PROGRAMMER *pgm, int mode); -int jtag3_getparm(const PROGRAMMER *pgm, unsigned char scope, - unsigned char section, unsigned char parm, - unsigned char *value, unsigned char length); -int jtag3_setparm(const PROGRAMMER *pgm, unsigned char scope, - unsigned char section, unsigned char parm, - unsigned char *value, unsigned char length); -int jtag3_command(const PROGRAMMER *pgm, unsigned char *cmd, unsigned int cmdlen, - unsigned char **resp, const char *descr); -void jtag3_display(const PROGRAMMER *pgm, const char *p); -void jtag3_print_parms1(const PROGRAMMER *pgm, const char *p, FILE *fp); -int jtag3_set_vtarget(const PROGRAMMER *pgm, double voltage); -int jtag3_get_vtarget(const PROGRAMMER *pgm, double *voltage); -extern const char jtag3_desc[]; -extern const char jtag3_dw_desc[]; -extern const char jtag3_pdi_desc[]; -extern const char jtag3_updi_desc[]; -extern const char jtag3_tpi_desc[]; -void jtag3_initpgm(PROGRAMMER *pgm); -void jtag3_dw_initpgm(PROGRAMMER *pgm); -void jtag3_pdi_initpgm(PROGRAMMER *pgm); -void jtag3_updi_initpgm(PROGRAMMER *pgm); -void jtag3_tpi_initpgm(PROGRAMMER *pgm); + int jtag3_open_common(PROGRAMMER *pgm, const char *port, int mode_switch); + int jtag3_send(const PROGRAMMER *pgm, unsigned char *data, size_t len); + int jtag3_recv(const PROGRAMMER *pgm, unsigned char **msg); + void jtag3_close(PROGRAMMER *pgm); + int jtag3_getsync(const PROGRAMMER *pgm, int mode); + int jtag3_getparm(const PROGRAMMER *pgm, unsigned char scope, + unsigned char section, unsigned char parm, unsigned char *value, unsigned char length); + int jtag3_setparm(const PROGRAMMER *pgm, unsigned char scope, + unsigned char section, unsigned char parm, unsigned char *value, unsigned char length); + int jtag3_command(const PROGRAMMER *pgm, unsigned char *cmd, unsigned int cmdlen, + unsigned char **resp, const char *descr); + void jtag3_display(const PROGRAMMER *pgm, const char *p); + void jtag3_print_parms1(const PROGRAMMER *pgm, const char *p, FILE *fp); + int jtag3_set_vtarget(const PROGRAMMER *pgm, double voltage); + int jtag3_get_vtarget(const PROGRAMMER *pgm, double *voltage); + extern const char jtag3_desc[]; + extern const char jtag3_dw_desc[]; + extern const char jtag3_pdi_desc[]; + extern const char jtag3_updi_desc[]; + extern const char jtag3_tpi_desc[]; + void jtag3_initpgm(PROGRAMMER *pgm); + void jtag3_dw_initpgm(PROGRAMMER *pgm); + void jtag3_pdi_initpgm(PROGRAMMER *pgm); + void jtag3_updi_initpgm(PROGRAMMER *pgm); + void jtag3_tpi_initpgm(PROGRAMMER *pgm); -/* - * These functions are referenced from stk500v2.c for JTAGICE3 in - * one of the STK500v2 modi. - */ -void jtag3_setup(PROGRAMMER * pgm); -void jtag3_teardown(PROGRAMMER * pgm); + // These functions are referenced from stk500v2.c for JTAGICE3 in one of the STK500v2 modi + void jtag3_setup(PROGRAMMER *pgm); + void jtag3_teardown(PROGRAMMER *pgm); #ifdef __cplusplus } #endif - #endif - diff --git a/src/jtag3_private.h b/src/jtag3_private.h index 451e6a253..385f2b1cd 100644 --- a/src/jtag3_private.h +++ b/src/jtag3_private.h @@ -18,13 +18,13 @@ * along with this program. If not, see . */ - /* * JTAGICE3 definitions * Reverse-engineered from various USB traces. */ #if !defined(JTAG3_PRIVATE_EXPORTED) + /* * Communication with the JTAGICE3 uses three data endpoints: * @@ -88,8 +88,7 @@ * +---------------------------------------- */ #define TOKEN 0x0e - -#endif /* JTAG3_PRIVATE_EXPORTED */ +#endif // JTAG3_PRIVATE_EXPORTED #define SCOPE_INFO 0x00 #define SCOPE_GENERAL 0x01 @@ -99,30 +98,30 @@ #define SCOPE_AVR_TPI 0x14 #define SCOPE_EDBG 0x20 -/* Info scope */ +// Info scope #define CMD3_GET_INFO 0x00 -/* byte after GET_INFO is always 0, next is: */ -# define CMD3_INFO_NAME 0x80 /* JTAGICE3 */ -# define CMD3_INFO_SERIAL 0x81 /* J3xxxxxxxxxx */ +// Byte after GET_INFO is always 0, next is +#define CMD3_INFO_NAME 0x80 // JTAGICE3 +#define CMD3_INFO_SERIAL 0x81 // J3xxxxxxxxxx -/* Generic scope */ +// Generic scope #define CMD3_SET_PARAMETER 0x01 #define CMD3_GET_PARAMETER 0x02 #define CMD3_SIGN_ON 0x10 -#define CMD3_SIGN_OFF 0x11 /* takes one parameter? */ +#define CMD3_SIGN_OFF 0x11 // Takes one parameter? #define CMD3_GET_ID 0x12 #define CMD3_START_DW_DEBUG 0x13 #define CMD3_MONCON_DISABLE 0x17 #define CMD3_FW_UPGRADE 0x50 -/* AVR ISP scope: no commands of its own */ +// AVR ISP scope: no commands of its own -/* AVR scope */ -//#define CMD3_SET_PARAMETER 0x01 -//#define CMD3_GET_PARAMETER 0x02 -//#define CMD3_SIGN_ON 0x10 /* an additional signon/-off pair */ -//#define CMD3_SIGN_OFF 0x11 +// AVR scope +// #define CMD3_SET_PARAMETER 0x01 +// #define CMD3_GET_PARAMETER 0x02 +// #define CMD3_SIGN_ON 0x10 // An additional signon/-off pair +// #define CMD3_SIGN_OFF 0x11 #define CMD3_ENTER_PROGMODE 0x15 #define CMD3_LEAVE_PROGMODE 0x16 #define CMD3_ERASE_MEMORY 0x20 @@ -130,7 +129,7 @@ #define CMD3_WRITE_MEMORY 0x23 #define CMD3_READ_PC 0x35 -/* ICE responses */ +// ICE responses #define RSP3_OK 0x80 #define RSP3_INFO 0x81 #define RSP3_PC 0x83 @@ -139,128 +138,116 @@ #define RSP3_STATUS_MASK 0xE0 -/* possible failure codes that could be appended to RSP3_FAILED: */ -# define RSP3_FAIL_DEBUGWIRE 0x10 -# define RSP3_FAIL_PDI 0x1B -# define RSP3_FAIL_NO_ANSWER 0x20 -# define RSP3_FAIL_NO_TARGET_POWER 0x22 -# define RSP3_FAIL_WRONG_MODE 0x32 /* progmode vs. non-prog */ -# define RSP3_FAIL_UNSUPP_MEMORY 0x34 /* unsupported memory type */ -# define RSP3_FAIL_WRONG_LENGTH 0x35 /* wrong lenth for mem access */ -# define RSP3_FAIL_CRC_FAILURE 0x43 /* CRC failure in device */ -# define RSP3_FAIL_OCD_LOCKED 0x44 /* device is locked */ -# define RSP3_FAIL_NOT_UNDERSTOOD 0x91 - -/* ICE events */ -#define EVT3_BREAK 0x40 /* AVR scope */ -#define EVT3_SLEEP 0x11 /* General scope, also wakeup */ -#define EVT3_POWER 0x10 /* General scope */ - -/* memories */ -#define MTYPE_SRAM 0x20 /* target's SRAM or [ext.] IO registers */ -#define MTYPE_EEPROM 0x22 /* EEPROM, what way? */ -#define MTYPE_SPM 0xA0 /* flash through LPM/SPM */ -#define MTYPE_FLASH_PAGE 0xB0 /* flash in programming mode */ -#define MTYPE_EEPROM_PAGE 0xB1 /* EEPROM in programming mode */ -#define MTYPE_FUSE_BITS 0xB2 /* fuse bits in programming mode */ -#define MTYPE_LOCK_BITS 0xB3 /* lock bits in programming mode */ -#define MTYPE_SIGN_JTAG 0xB4 /* signature in programming mode */ -#define MTYPE_OSCCAL_BYTE 0xB5 /* osccal cells in programming mode */ -#define MTYPE_FLASH 0xc0 /* xmega (app.) flash - undocumented in AVR067 */ -#define MTYPE_BOOT_FLASH 0xc1 /* xmega boot flash - undocumented in AVR067 */ -#define MTYPE_EEPROM_XMEGA 0xc4 /* xmega EEPROM in debug mode - undocumented in AVR067 */ -#define MTYPE_USERSIG 0xc5 /* xmega user signature - undocumented in AVR067 */ -#define MTYPE_PRODSIG 0xc6 /* xmega production signature - undocumented in AVR067 */ -#define MTYPE_SIB 0xD3 /* AVR8X System Information Block */ - -/* - * SET and GET context definitions - */ -#define SET_GET_CTXT_CONFIG 0x00 /* Configuration */ -#define SET_GET_CTXT_PHYSICAL 0x01 /* Physical interface related */ -#define SET_GET_CTXT_DEVICE 0x02 /* Device specific settings */ -#define SET_GET_CTXT_OPTIONS 0x03 /* Option-related settings */ -#define SET_GET_CTXT_SESSION 0x04 /* Session-related settings */ +// Possible failure codes that could be appended to RSP3_FAILED +#define RSP3_FAIL_DEBUGWIRE 0x10 +#define RSP3_FAIL_PDI 0x1B +#define RSP3_FAIL_NO_ANSWER 0x20 +#define RSP3_FAIL_NO_TARGET_POWER 0x22 +#define RSP3_FAIL_WRONG_MODE 0x32 // Progmode vs non-prog +#define RSP3_FAIL_UNSUPP_MEMORY 0x34 // Unsupported memory type +#define RSP3_FAIL_WRONG_LENGTH 0x35 // Wrong lenth for mem access +#define RSP3_FAIL_CRC_FAILURE 0x43 // CRC failure in device +#define RSP3_FAIL_OCD_LOCKED 0x44 // Device is locked +#define RSP3_FAIL_NOT_UNDERSTOOD 0x91 + +// ICE events +#define EVT3_BREAK 0x40 // Avr scope */ +#define EVT3_SLEEP 0x11 // General scope, also wakeup +#define EVT3_POWER 0x10 // General scope + +// Memories +#define MTYPE_SRAM 0x20 // Target's SRAM or [ext.] IO registers +#define MTYPE_EEPROM 0x22 // EEPROM, what way? +#define MTYPE_SPM 0xA0 // Flash through LPM/SPM +#define MTYPE_FLASH_PAGE 0xB0 // Flash in programming mode +#define MTYPE_EEPROM_PAGE 0xB1 // EEPROM in programming mode +#define MTYPE_FUSE_BITS 0xB2 // Fuse bits in programming mode +#define MTYPE_LOCK_BITS 0xB3 // Lock bits in programming mode +#define MTYPE_SIGN_JTAG 0xB4 // Signature in programming mode +#define MTYPE_OSCCAL_BYTE 0xB5 // Osccal cells in programming mode +#define MTYPE_FLASH 0xc0 // Xmega (app.) flash - undocumented in AVR067 +#define MTYPE_BOOT_FLASH 0xc1 // Xmega boot flash - undocumented in AVR067 +#define MTYPE_EEPROM_XMEGA 0xc4 // Xmega EEPROM in debug mode - undocumented in AVR067 +#define MTYPE_USERSIG 0xc5 // Xmega user signature - undocumented in AVR067 +#define MTYPE_PRODSIG 0xc6 // Xmega production signature - undocumented in AVR067 +#define MTYPE_SIB 0xD3 // AVR8X System Information Block + +// SET and GET context definitions +#define SET_GET_CTXT_CONFIG 0x00 // Configuration +#define SET_GET_CTXT_PHYSICAL 0x01 // Physical interface related +#define SET_GET_CTXT_DEVICE 0x02 // Device specific settings +#define SET_GET_CTXT_OPTIONS 0x03 // Option-related settings +#define SET_GET_CTXT_SESSION 0x04 // Session-related settings /* * Parameters are divided into sections, where the section number * precedes each parameter address. There are distinct parameter * sets for generic and AVR scope. */ -#define PARM3_HW_VER 0x00 /* section 0, generic scope, 1 byte */ -#define PARM3_FW_MAJOR 0x01 /* section 0, generic scope, 1 byte */ -#define PARM3_FW_MINOR 0x02 /* section 0, generic scope, 1 byte */ -#define PARM3_FW_RELEASE 0x03 /* section 0, generic scope, 1 byte; - * always asked for by Atmel Studio, - * but never displayed there */ - -#define PARM3_VTARGET 0x00 /* section 1, generic scope, 2 bytes, in millivolts */ -#define PARM3_VBUF 0x01 /* section 1, generic scope, 2 bytes, bufferred target voltage reference */ -#define PARM3_VUSB 0x02 /* section 1, generic scope, 2 bytes, USB voltage */ -#define PARM3_ANALOG_A_CURRENT 0x10 /* section 1, generic scope, 2 bytes, Ch A current in milliamps, Powerdebugger only */ -#define PARM3_ANALOG_A_VOLTAGE 0x11 /* section 1, generic scope, 2 bytes, Ch A voltage in millivolts, Powerdebugger only */ -#define PARM3_ANALOG_B_CURRENT 0x12 /* section 1, generic scope, 2 bytes, Ch B current in milliamps, Powerdebugger only */ -#define PARM3_ANALOG_B_VOLTAGE 0x13 /* section 1, generic scope, 2 bytes, Ch V voltage in millivolts, Powerdebugger only */ -#define PARM3_TSUP_VOLTAGE_MEAS 0x14 /* section 1, generic scope, 2 bytes, target voltage measurement in millivolts */ -#define PARM3_USB_VOLTAGE_MEAS 0x15 /* section 1, generic scope, 2 bytes, USB voltage measurement in millivolts */ -#define PARM3_VADJUST 0x20 /* section 1, generic scope, 2 bytes, set voltage in millivolts */ -#define PARM3_ANALOG_STATUS 0x30 /* section 1, generic scope, 2 bytes, analog status */ - -/* mEDBG Xplained Mini / Nano constants */ +#define PARM3_HW_VER 0x00 // Section 0, generic scope, 1 byte +#define PARM3_FW_MAJOR 0x01 // Section 0, generic scope, 1 byte +#define PARM3_FW_MINOR 0x02 // Section 0, generic scope, 1 byte +#define PARM3_FW_RELEASE 0x03 // Section 0, generic scope, 1 byte; always asked for by Atmel Studio but never displayed there + +#define PARM3_VTARGET 0x00 // Section 1, generic scope, 2 bytes, in millivolts +#define PARM3_VBUF 0x01 // Section 1, generic scope, 2 bytes, bufferred target voltage reference +#define PARM3_VUSB 0x02 // Section 1, generic scope, 2 bytes, USB voltage +#define PARM3_ANALOG_A_CURRENT 0x10 // Section 1, generic scope, 2 bytes, Ch A current in milliamps, Powerdebugger only +#define PARM3_ANALOG_A_VOLTAGE 0x11 // Section 1, generic scope, 2 bytes, Ch A voltage in millivolts, Powerdebugger only +#define PARM3_ANALOG_B_CURRENT 0x12 // Section 1, generic scope, 2 bytes, Ch B current in milliamps, Powerdebugger only +#define PARM3_ANALOG_B_VOLTAGE 0x13 // Section 1, generic scope, 2 bytes, Ch V voltage in millivolts, Powerdebugger only +#define PARM3_TSUP_VOLTAGE_MEAS 0x14 // Section 1, generic scope, 2 bytes, target voltage measurement in millivolts +#define PARM3_USB_VOLTAGE_MEAS 0x15 // Section 1, generic scope, 2 bytes, USB voltage measurement in millivolts +#define PARM3_VADJUST 0x20 // Section 1, generic scope, 2 bytes, set voltage in millivolts +#define PARM3_ANALOG_STATUS 0x30 // Section 1, generic scope, 2 bytes, analog status + +// mEDBG Xplained Mini/Nano constants #define MEDBG_REG_SUFFER_BANK 0x01 -#define MEDBG_REG_SUFFER_OFFSET 0x20 /* section 17, EDBG scope, 1 byte, SUFFER register value */ - -#define PARM3_DEVICEDESC 0x00 /* section 2, memory etc. configuration, - * 31 bytes for tiny/mega AVR, 47 bytes - * for Xmega; is also used in command - * 0x36 in JTAGICEmkII, starting with - * firmware 7.x */ - -#define PARM3_ARCH 0x00 /* section 0, AVR scope, 1 byte */ -# define PARM3_ARCH_TINY 1 /* also small megaAVR with ISP/DW only */ -# define PARM3_ARCH_MEGA 2 -# define PARM3_ARCH_XMEGA 3 -# define PARM3_ARCH_UPDI 5 /* AVR devices with UPDI i/f */ - -#define PARM3_SESS_PURPOSE 0x01 /* section 0, AVR scope, 1 byte */ -# define PARM3_SESS_PROGRAMMING 1 -# define PARM3_SESS_DEBUGGING 2 - -#define PARM3_CONNECTION 0x00 /* section 1, AVR scope, 1 byte */ -# define PARM3_CONN_ISP 1 -# define PARM3_CONN_JTAG 4 -# define PARM3_CONN_DW 5 -# define PARM3_CONN_PDI 6 -# define PARM3_CONN_UPDI 8 - - -#define PARM3_JTAGCHAIN 0x01 /* JTAG chain info, AVR scope (units - * before/after, bits before/after), 4 - * bytes */ - -/* - * Physical context parameters - */ -#define PARM3_CLK_MEGA_PROG 0x20 /* section 1, AVR scope, 2 bytes (kHz) */ -#define PARM3_CLK_MEGA_DEBUG 0x21 /* section 1, AVR scope, 2 bytes (kHz) */ -#define PARM3_CLK_XMEGA_JTAG 0x30 /* section 1, AVR scope, 2 bytes (kHz) */ -#define PARM3_CLK_XMEGA_PDI 0x31 /* section 1, AVR scope, 2 bytes (kHz) */ - -/* - * Options context parameters - */ -#define PARM3_OPT_12V_UPDI_ENABLE 0x06 -#define PARM3_OPT_CHIP_ERASE_TO_ENTER 0x07 +#define MEDBG_REG_SUFFER_OFFSET 0x20 // Section 17, EDBG scope, 1 byte, SUFFER register value /* - * UPDI high-voltage enable modes + * Section 2, memory etc. configuration, 31 bytes for tiny/mega AVR, 47 bytes + * for Xmega; is also used in command 0x36 in JTAGICEmkII, starting with FW 7.x */ -#define PARM3_UPDI_HV_NONE 0x00 /* Do not use high-voltage */ -#define PARM3_UPDI_HV_SIMPLE_PULSE 0x01 /* Issue a single high-voltage pulse immediately*/ -#define PARM3_UPDI_HV_AUTO_POWER_TOGGLE 0x02 /* Toggle power automatically and then apply a high-voltage pulse */ -#define PARM3_UPDI_HV_USER_POWER_TOGGLE 0x03 /* The user toggles power, and the tool applies a high-voltage pulse on power-up */ - -/* Xmega erase memories for CMND_XMEGA_ERASE */ +#define PARM3_DEVICEDESC 0x00 + +#define PARM3_ARCH 0x00 // Section 0, AVR scope, 1 byte +#define PARM3_ARCH_TINY 1 // Also small megaAVR with ISP/DW only +#define PARM3_ARCH_MEGA 2 +#define PARM3_ARCH_XMEGA 3 +#define PARM3_ARCH_UPDI 5 // AVR devices with UPDI i/f + +#define PARM3_SESS_PURPOSE 0x01 // Section 0, AVR scope, 1 byte +#define PARM3_SESS_PROGRAMMING 1 +#define PARM3_SESS_DEBUGGING 2 + +#define PARM3_CONNECTION 0x00 // Section 1, AVR scope, 1 byte +#define PARM3_CONN_ISP 1 +#define PARM3_CONN_JTAG 4 +#define PARM3_CONN_DW 5 +#define PARM3_CONN_PDI 6 +#define PARM3_CONN_UPDI 8 + +// JTAG chain info, AVR scope (units before/after, bits before/after), 4 bytes +#define PARM3_JTAGCHAIN 0x01 + +// Physical context parameters +#define PARM3_CLK_MEGA_PROG 0x20 // Section 1, AVR scope, 2 bytes (kHz) +#define PARM3_CLK_MEGA_DEBUG 0x21 // Section 1, AVR scope, 2 bytes (kHz) +#define PARM3_CLK_XMEGA_JTAG 0x30 // Section 1, AVR scope, 2 bytes (kHz) +#define PARM3_CLK_XMEGA_PDI 0x31 // Section 1, AVR scope, 2 bytes (kHz) + +// Options context parameters +#define PARM3_OPT_12V_UPDI_ENABLE 0x06 +#define PARM3_OPT_CHIP_ERASE_TO_ENTER 0x07 + +// UPDI high-voltage enable modes +#define PARM3_UPDI_HV_NONE 0x00 // Do not use high-voltage +#define PARM3_UPDI_HV_SIMPLE_PULSE 0x01 // Issue a single high-voltage pulse immediately +#define PARM3_UPDI_HV_AUTO_POWER_TOGGLE 0x02 // Toggle power automatically and then apply a high-voltage pulse +#define PARM3_UPDI_HV_USER_POWER_TOGGLE 0x03 // The user toggles power, and the tool applies a high-voltage pulse on power-up + +// Xmega erase memories for CMND_XMEGA_ERASE #define XMEGA_ERASE_CHIP 0x00 #define XMEGA_ERASE_APP 0x01 #define XMEGA_ERASE_BOOT 0x02 @@ -270,7 +257,7 @@ #define XMEGA_ERASE_EEPROM_PAGE 0x06 #define XMEGA_ERASE_USERSIG 0x07 -/* EDBG vendor commands */ +// EDBG vendor commands #define EDBG_VENDOR_AVR_CMD 0x80 #define EDBG_VENDOR_AVR_RSP 0x81 #define EDBG_VENDOR_AVR_EVT 0x82 @@ -280,46 +267,45 @@ #define EDBG_CONTROL_EXT_PROG 0x01 #define EDBG_CONTROL_TARGET_POWER 0x10 -/* CMSIS-DAP commands */ -#define CMSISDAP_CMD_INFO 0x00 /* get info, followed by INFO byte */ -# define CMSISDAP_INFO_VID 0x01 /* vendor ID (string) */ -# define CMSISDAP_INFO_PID 0x02 /* product ID (string) */ -# define CMSISDAP_INFO_SERIAL 0x03 /* serial number (string) */ -# define CMSISDAP_INFO_FIRMWARE 0x04 /* firmware version (string) */ -# define CMSISDAP_INFO_TARGET_VENDOR 0x05 /* target device vendor (string) */ -# define CMSISDAP_INFO_TARGET_NAME 0x06 /* target device name (string) */ -# define CMSISDAP_INFO_CAPABILITIES 0xF0 /* debug unit capabilities (byte) */ -# define CMSISDAP_INFO_PACKET_COUNT 0xFE /* packet count (byte) (which packets, anyway?) */ -# define CMSISDAP_INFO_PACKET_SIZE 0xFF /* packet size (short) */ +// CMSIS-DAP commands +#define CMSISDAP_CMD_INFO 0x00 // Get info, followed by INFO byte +#define CMSISDAP_INFO_VID 0x01 // Vendor ID (string) +#define CMSISDAP_INFO_PID 0x02 // Product ID (string) +#define CMSISDAP_INFO_SERIAL 0x03 // Serial number (string) +#define CMSISDAP_INFO_FIRMWARE 0x04 // Firmware version (string) +#define CMSISDAP_INFO_TARGET_VENDOR 0x05 // Target device vendor (string) +#define CMSISDAP_INFO_TARGET_NAME 0x06 // Target device name (string) +#define CMSISDAP_INFO_CAPABILITIES 0xF0 // Debug unit capabilities (byte) +#define CMSISDAP_INFO_PACKET_COUNT 0xFE // Packet count (byte) (which packets, anyway?) +#define CMSISDAP_INFO_PACKET_SIZE 0xFF // Packet size (short) -#define CMSISDAP_CMD_LED 0x01 /* LED control, followed by LED number and on/off byte */ -# define CMSISDAP_LED_CONNECT 0x00 /* connect LED */ -# define CMSISDAP_LED_RUNNING 0x01 /* running LED */ +#define CMSISDAP_CMD_LED 0x01 // LED control, followed by LED number and on/off byte +#define CMSISDAP_LED_CONNECT 0x00 // Connect LED +#define CMSISDAP_LED_RUNNING 0x01 // Running LED -#define CMSISDAP_CMD_CONNECT 0x02 /* connect to target, followed by DAP mode */ -# define CMSISDAP_CONN_DEFAULT 0x00 -# define CMSISDAP_CONN_SWD 0x01 /* serial wire debug */ -# define CMSISDAP_CONN_JTAG 0x02 /* JTAG mode */ +#define CMSISDAP_CMD_CONNECT 0x02 // Connect to target, followed by DAP mode +#define CMSISDAP_CONN_DEFAULT 0x00 +#define CMSISDAP_CONN_SWD 0x01 // Serial wire debug +#define CMSISDAP_CONN_JTAG 0x02 // JTAG mode -#define CMSISDAP_CMD_DISCONNECT 0x03 /* disconnect from target */ +#define CMSISDAP_CMD_DISCONNECT 0x03 // Disconnect from target -#define CMSISDAP_XFR_CONFIGURE 0x04 /* configure transfers; idle cycles (byte); - wait retry (short); match retry (short) */ +#define CMSISDAP_XFR_CONFIGURE 0x04 // Configure transfers; idle cycles (byte); wait retry (short); match retry (short) -#define CMSISDAP_CMD_WRITEAPBORT 0x08 /* write to CoreSight ABORT register of target */ +#define CMSISDAP_CMD_WRITEAPBORT 0x08 // Write to CoreSight ABORT register of target -#define CMSISDAP_CMD_DELAY 0x09 /* delay for number of microseconds (short) */ +#define CMSISDAP_CMD_DELAY 0x09 // Delay for number of microseconds (short) -#define CMSISDAP_CMD_RESET 0x0A /* reset target */ +#define CMSISDAP_CMD_RESET 0x0A // Reset target -#define CMSISDAP_CMD_SWJ_CLOCK 0x11 /* SWD/JTAG clock, (word) */ +#define CMSISDAP_CMD_SWJ_CLOCK 0x11 // SWD/JTAG clock, (word) -#define CMSISDAP_CMD_SWD_CONFIGURE 0x13 /* configure SWD protocol; (byte) */ +#define CMSISDAP_CMD_SWD_CONFIGURE 0x13 // Configure SWD protocol; (byte) -#define DEFAULT_MINIMUM_CHARACTERISED_DIV1_VOLTAGE_MV 4500 // Default minimum voltage for 32M => 4.5V -#define DEFAULT_MINIMUM_CHARACTERISED_DIV2_VOLTAGE_MV 2700 // Default minimum voltage for 16M => 2.7V -#define DEFAULT_MINIMUM_CHARACTERISED_DIV4_VOLTAGE_MV 2200 // Default minimum voltage for 8M => 2.2V -#define DEFAULT_MINIMUM_CHARACTERISED_DIV8_VOLTAGE_MV 1500 // Default minimum voltage for 4M => 1.5V +#define DEFAULT_MINIMUM_CHARACTERISED_DIV1_VOLTAGE_MV 4500 // Default minimum voltage for 32M => 4.5V +#define DEFAULT_MINIMUM_CHARACTERISED_DIV2_VOLTAGE_MV 2700 // Default minimum voltage for 16M => 2.7V +#define DEFAULT_MINIMUM_CHARACTERISED_DIV4_VOLTAGE_MV 2200 // Default minimum voltage for 8M => 2.2V +#define DEFAULT_MINIMUM_CHARACTERISED_DIV8_VOLTAGE_MV 1500 // Default minimum voltage for 4M => 1.5V #define MAX_FREQUENCY_DEDICATED_UPDI_PIN 1500 #define MAX_FREQUENCY_SHARED_UPDI_PIN 750 #define UPDI_ADDRESS_MODE_16BIT 0 @@ -372,7 +358,7 @@ #define XPRG_PARAM_NVMBASE 0x01 // 2-byte page size #define XPRG_PARAM_EEPPAGESIZE 0x02 -// tiny TPI, 1-byte address +// Tiny TPI, 1-byte address #define XPRG_PARAM_NVMCMD_ADDR 0x03 #define XPRG_PARAM_NVMCSR_ADDR 0x04 @@ -387,101 +373,103 @@ #define PK4_SNAP_MODE_PIC 2 // Switch to PIC mode #if !defined(JTAG3_PRIVATE_EXPORTED) - struct mega_device_desc { - unsigned char flash_page_size[2]; // in bytes - unsigned char flash_size[4]; // in bytes - unsigned char dummy1[4]; // always 0 - unsigned char boot_address[4]; // maximal (BOOTSZ = 3) bootloader - // address, in 16-bit words (!) - unsigned char sram_offset[2]; // pointing behind IO registers - unsigned char eeprom_size[2]; - unsigned char eeprom_page_size; - unsigned char ocd_revision; // see XML; basically: - // t13*, t2313*, t4313: 0 - // all other DW devices: 1 - // ATmega128(A): 1 (!) - // ATmega16*,162,169*,32*,64*: 2 - // ATmega2560/2561: 4 - // all other megaAVR devices: 3 - unsigned char always_one; // always = 1 - unsigned char allow_full_page_bitstream; // old AVRs, see XML - unsigned char dummy2[2]; // always 0 - // all IO addresses below are given - // in IO number space (without - // offset 0x20), even though e.g. - // OSCCAL always resides outside - unsigned char idr_address; // IDR, aka. OCDR - unsigned char eearh_address; // EEPROM access - unsigned char eearl_address; - unsigned char eecr_address; - unsigned char eedr_address; - unsigned char spmcr_address; - unsigned char osccal_address; + unsigned char flash_page_size[2]; // In bytes + unsigned char flash_size[4]; // In bytes + unsigned char dummy1[4]; // Always 0 + unsigned char boot_address[4]; // At most (BOOTSZ = 3) bootloaders + // address, in 16-bit words (!) + unsigned char sram_offset[2]; // Pointing behind IO registers + unsigned char eeprom_size[2]; + unsigned char eeprom_page_size; + unsigned char ocd_revision; // See ATDF; basically as below + /* + * t13*, t2313*, t4313: 0 + * all other DW devices: 1 + * ATmega128(A): 1 (!) + * ATmega16*, 162, 169*, 32*, 64*: 2 + * ATmega2560/2561: 4 + * all other megaAVR devices: 3 + */ + unsigned char always_one; // Always = 1 + unsigned char allow_full_page_bitstream; // Old AVRs, see XML + unsigned char dummy2[2]; // Always 0 + /* + * All registers below are given in I/O space (without offset 0x20), even + * though e.g. OSCCAL always resides outside + */ + unsigned char idr_address; // IDR, aka. OCDR + unsigned char eearh_address; // EEPROM access + unsigned char eearl_address; + unsigned char eecr_address; + unsigned char eedr_address; + unsigned char spmcr_address; + unsigned char osccal_address; }; - -/* Xmega device descriptor */ +// Xmega device descriptor struct xmega_device_desc { - unsigned char nvm_app_offset[4]; // NVM offset for application flash - unsigned char nvm_boot_offset[4]; // NVM offset for boot flash - unsigned char nvm_eeprom_offset[4]; // NVM offset for EEPROM - unsigned char nvm_fuse_offset[4]; // NVM offset for fuses - unsigned char nvm_lock_offset[4]; // NVM offset for lock bits - unsigned char nvm_user_sig_offset[4]; // NVM offset for user signature row - unsigned char nvm_prod_sig_offset[4]; // NVM offset for production sign. row - unsigned char nvm_data_offset[4]; // NVM offset for data memory (SRAM + IO) - unsigned char app_size[4]; // size of application flash - unsigned char boot_size[2]; // size of boot flash - unsigned char flash_page_size[2]; // flash page size - unsigned char eeprom_size[2]; // size of EEPROM - unsigned char eeprom_page_size; // EEPROM page size - unsigned char nvm_base_addr[2]; // IO space base address of NVM controller - unsigned char mcu_base_addr[2]; // IO space base address of MCU control + unsigned char nvm_app_offset[4]; // NVM offset for application flash + unsigned char nvm_boot_offset[4]; // NVM offset for boot flash + unsigned char nvm_eeprom_offset[4]; // NVM offset for EEPROM + unsigned char nvm_fuse_offset[4]; // NVM offset for fuses + unsigned char nvm_lock_offset[4]; // NVM offset for lock bits + unsigned char nvm_user_sig_offset[4]; // NVM offset for user signature row + unsigned char nvm_prod_sig_offset[4]; // NVM offset for production sign. row + unsigned char nvm_data_offset[4]; // NVM offset for data memory (SRAM + IO) + unsigned char app_size[4]; // Size of application flash + unsigned char boot_size[2]; // Size of boot flash + unsigned char flash_page_size[2]; // Flash page size + unsigned char eeprom_size[2]; // Size of EEPROM + unsigned char eeprom_page_size; // EEPROM page size + unsigned char nvm_base_addr[2]; // IO space base address of NVM controller + unsigned char mcu_base_addr[2]; // IO space base address of MCU control }; -/* UPDI device descriptor */ +// UPDI device descriptor struct updi_device_desc { - unsigned char prog_base[2]; - unsigned char flash_page_size; - unsigned char eeprom_page_size; - unsigned char nvm_base_addr[2]; - unsigned char ocd_base_addr[2]; - - // Configuration below, except for "Extended memory support", is only used by kits with - // embedded debuggers (XPlained, Curiosity, ...). - unsigned char default_min_div1_voltage[2]; // Default minimum voltage for 32M => 4.5V -> 4500 - unsigned char default_min_div2_voltage[2]; // Default minimum voltage for 16M => 2.7V -> 2700 - unsigned char default_min_div4_voltage[2]; // Default minimum voltage for 8M => 2.2V -> 2200 - unsigned char default_min_div8_voltage[2]; // Default minimum voltage for 4M => 1.5V -> 1500 - - unsigned char pdi_pad_fmax[2]; // 750 - - unsigned char flash_bytes[4]; // Flash size in bytes - unsigned char eeprom_bytes[2]; // EEPROM size in bytes - unsigned char user_sig_bytes[2]; // UserSignture size in bytes - unsigned char fuses_bytes; // Fuses size in bytes - - unsigned char syscfg_offset; // Offset of SYSCFG0 within FUSE space - unsigned char syscfg_write_mask_and; // AND mask to apply to SYSCFG0 when writing - unsigned char syscfg_write_mask_or; // OR mask to apply to SYSCFG0 when writing - unsigned char syscfg_erase_mask_and; // AND mask to apply to SYSCFG0 after erase - unsigned char syscfg_erase_mask_or; // OR mask to apply to SYSCFG0 after erase - - unsigned char eeprom_base[2]; // Base address for EEPROM memory - unsigned char user_sig_base[2]; // Base address for UserSignature memory - unsigned char signature_base[2]; // Base address for Signature memory - unsigned char fuses_base[2]; // Base address for Fuses memory - unsigned char lockbits_base[2]; // Base address for Lockbits memory - - unsigned char device_id[2]; // Two last bytes of the device ID - - // Extended memory support. Needed for flash >= 64kb - unsigned char prog_base_msb; // Extends prog_base, used in 24-bit mode - unsigned char flash_page_size_msb; // Extends flash_page_size, used in 24-bit mode - - unsigned char address_mode; // 0x00 = 16-bit mode, 0x01 = 24-bit mode - - unsigned char hvupdi_variant; // Indicates the target UPDI HV implementation + unsigned char prog_base[2]; + unsigned char flash_page_size; + unsigned char eeprom_page_size; + unsigned char nvm_base_addr[2]; + unsigned char ocd_base_addr[2]; + + /* + * Configuration below, except for "Extended memory support", is only used by + * kits with embedded debuggers (XPlained, Curiosity, ...). + */ + unsigned char default_min_div1_voltage[2]; // Default minimum voltage for 32M => 4.5V -> 4500 + unsigned char default_min_div2_voltage[2]; // Default minimum voltage for 16M => 2.7V -> 2700 + unsigned char default_min_div4_voltage[2]; // Default minimum voltage for 8M => 2.2V -> 2200 + unsigned char default_min_div8_voltage[2]; // Default minimum voltage for 4M => 1.5V -> 1500 + + unsigned char pdi_pad_fmax[2]; // 750 + + unsigned char flash_bytes[4]; // Flash size in bytes + unsigned char eeprom_bytes[2]; // EEPROM size in bytes + unsigned char user_sig_bytes[2]; // UserSignture size in bytes + unsigned char fuses_bytes; // Fuses size in bytes + + unsigned char syscfg_offset; // Offset of SYSCFG0 within FUSE space + unsigned char syscfg_write_mask_and; // AND mask to apply to SYSCFG0 when writing + unsigned char syscfg_write_mask_or; // OR mask to apply to SYSCFG0 when writing + unsigned char syscfg_erase_mask_and; // AND mask to apply to SYSCFG0 after erase + unsigned char syscfg_erase_mask_or; // OR mask to apply to SYSCFG0 after erase + + unsigned char eeprom_base[2]; // Base address for EEPROM memory + unsigned char user_sig_base[2]; // Base address for UserSignature memory + unsigned char signature_base[2]; // Base address for Signature memory + unsigned char fuses_base[2]; // Base address for Fuses memory + unsigned char lockbits_base[2]; // Base address for Lockbits memory + + unsigned char device_id[2]; // Two last bytes of the device ID + + // Extended memory support. Needed for flash >= 64kb + unsigned char prog_base_msb; // Extends prog_base, used in 24-bit mode + unsigned char flash_page_size_msb; // Extends flash_page_size, used in 24-bit mode + + unsigned char address_mode; // 0x00 = 16-bit mode, 0x01 = 24-bit mode + + unsigned char hvupdi_variant; // Indicates the target UPDI HV implementation }; -#endif /* JTAG3_PRIVATE_EXPORTED */ +#endif // JTAG3_PRIVATE_EXPORTED diff --git a/src/jtagmkI.c b/src/jtagmkI.c index 28465675a..9bd3f10ec 100644 --- a/src/jtagmkI.c +++ b/src/jtagmkI.c @@ -16,9 +16,7 @@ * along with this program. If not, see . */ -/* - * avrdude interface for Atmel JTAG ICE (mkI) programmer - */ +// Avrdude interface for Atmel JTAG ICE (mkI) programmer #include @@ -37,17 +35,10 @@ #include "jtagmkI.h" #include "jtagmkI_private.h" -/* - * Private data for this programmer. - */ -struct pdata -{ +struct pdata { int initial_baudrate; - /* - * See jtagmkI_read_byte() for an explanation of the flash and - * EEPROM page caches. - */ + // See jtagmkI_read_byte() for an explanation of the flash and EEPROM page caches unsigned char *flash_pagecache; unsigned long flash_pageaddr; unsigned int flash_pagesize; @@ -56,41 +47,39 @@ struct pdata unsigned long eeprom_pageaddr; unsigned int eeprom_pagesize; - int prog_enabled; /* Cached value of PROGRAMMING status. */ + int prog_enabled; // Cached value of PROGRAMMING status }; -#define PDATA(pgm) ((struct pdata *)(pgm->cookie)) +#define my (*(struct pdata *) (pgm->cookie)) /* - * Table of baud rates supported by the mkI ICE, accompanied by their - * internal parameter value. + * Table of baud rates supported by the mkI ICE, accompanied by their internal + * parameter value. * - * 19200 is the initial value of the ICE after powerup, and virtually - * all connections then switch to 115200. As the table is also used - * to try connecting at startup, we keep these two entries on top to - * speedup the program start. + * 19200 is the initial value of the ICE after powerup, and virtually all + * connections then switch to 115200. As the table is also used to try + * connecting at startup, we keep these two entries on top to speedup the + * program start. */ static const struct { long baud; unsigned char val; } baudtab[] = { - { 19200L, 0xfa }, - { 115200L, 0xff }, - { 9600L, 0xf4 }, - { 38400L, 0xfd }, - { 57600L, 0xfe }, -/* { 14400L, 0xf8 }, */ /* not supported by serial driver */ + {19200L, 0xfa}, + {115200L, 0xff}, + {9600L, 0xf4}, + {38400L, 0xfd}, + {57600L, 0xfe}, + // { 14400L, 0xf8 }, // Not supported by serial driver }; static int jtagmkI_read_byte(const PROGRAMMER *pgm, const AVRPART *p, const AVRMEM *mem, - unsigned long addr, unsigned char * value); + unsigned long addr, unsigned char *value); static int jtagmkI_write_byte(const PROGRAMMER *pgm, const AVRPART *p, const AVRMEM *mem, - unsigned long addr, unsigned char data); + unsigned long addr, unsigned char data); static int jtagmkI_set_sck_period(const PROGRAMMER *pgm, double v); -static int jtagmkI_getparm(const PROGRAMMER *pgm, unsigned char parm, - unsigned char * value); -static int jtagmkI_setparm(const PROGRAMMER *pgm, unsigned char parm, - unsigned char value); +static int jtagmkI_getparm(const PROGRAMMER *pgm, unsigned char parm, unsigned char *value); +static int jtagmkI_setparm(const PROGRAMMER *pgm, unsigned char parm, unsigned char value); static void jtagmkI_print_parms1(const PROGRAMMER *pgm, const char *p, FILE *fp); static int jtagmkI_resync(const PROGRAMMER *pgm, int maxtries, int signon); @@ -104,7 +93,6 @@ static void jtagmkI_teardown(PROGRAMMER *pgm) { pgm->cookie = NULL; } - static void u32_to_b3(unsigned char *b, unsigned long l) { b[2] = l & 0xff; b[1] = (l >> 8) & 0xff; @@ -117,22 +105,23 @@ static void u16_to_b2(unsigned char *b, unsigned short l) { } static void jtagmkI_prmsg(const PROGRAMMER *pgm, unsigned char *data, size_t len) { - if (verbose >= MSG_TRACE) { + if(verbose >= MSG_TRACE) { msg_trace("Raw message:\n"); size_t i; - for (i = 0; i < len; i++) { + + for(i = 0; i < len; i++) { msg_trace("0x%02x ", data[i]); - if (i % 16 == 15) - msg_trace("\n"); + if(i%16 == 15) + msg_trace("\n"); else - msg_trace(" "); + msg_trace(" "); } - if (i % 16 != 0) + if(i%16 != 0) msg_trace("\n"); } - switch (data[0]) { + switch(data[0]) { case RESP_OK: msg_info("OK\n"); break; @@ -168,7 +157,6 @@ static void jtagmkI_prmsg(const PROGRAMMER *pgm, unsigned char *data, size_t len msg_info("\n"); } - static int jtagmkI_send(const PROGRAMMER *pgm, unsigned char *data, size_t len) { unsigned char *buf; @@ -177,10 +165,10 @@ static int jtagmkI_send(const PROGRAMMER *pgm, unsigned char *data, size_t len) buf = mmt_malloc(len + 2); memcpy(buf, data, len); - buf[len] = ' '; /* "CRC" */ - buf[len + 1] = ' '; /* EOP */ + buf[len] = ' '; // CRC + buf[len + 1] = ' '; // EOP - if (serial_send(&pgm->fd, buf, len + 2) != 0) { + if(serial_send(&pgm->fd, buf, len + 2) != 0) { pmsg_error("unable to send command to serial port\n"); mmt_free(buf); return -1; @@ -192,24 +180,22 @@ static int jtagmkI_send(const PROGRAMMER *pgm, unsigned char *data, size_t len) } static int jtagmkI_recv(const PROGRAMMER *pgm, unsigned char *buf, size_t len) { - if (serial_recv(&pgm->fd, buf, len) != 0) { + if(serial_recv(&pgm->fd, buf, len) != 0) { msg_error("\n"); pmsg_error("unable to send command to serial port\n"); return -1; } - if (verbose >= MSG_DEBUG) { + if(verbose >= MSG_DEBUG) { msg_debug("\n"); jtagmkI_prmsg(pgm, buf, len); } return 0; } - static int jtagmkI_drain(const PROGRAMMER *pgm, int display) { return serial_drain(&pgm->fd, display); } - static int jtagmkI_resync(const PROGRAMMER *pgm, int maxtries, int signon) { int tries; unsigned char buf[4], resp[9]; @@ -221,33 +207,31 @@ static int jtagmkI_resync(const PROGRAMMER *pgm, int maxtries, int signon) { jtagmkI_drain(pgm, 0); - for (tries = 0; tries < maxtries; tries++) { + for(tries = 0; tries < maxtries; tries++) { - /* Get the sign-on information. */ + // Get the sign-on information buf[0] = CMD_GET_SYNC; pmsg_notice2("%s(): sending sync command: ", __func__); - if (serial_send(&pgm->fd, buf, 1) != 0) { + if(serial_send(&pgm->fd, buf, 1) != 0) { msg_error("\n"); pmsg_error("unable to send command to serial port\n"); serial_recv_timeout = otimeout; return -1; } - if (serial_recv(&pgm->fd, resp, 1) == 0 && resp[0] == RESP_OK) { + if(serial_recv(&pgm->fd, resp, 1) == 0 && resp[0] == RESP_OK) { msg_notice2("got RESP_OK\n"); break; } - if (signon) { + if(signon) { /* - * The following is black magic, the idea has been taken from - * AVaRICE. + * The following is black magic, the idea has been taken from AVaRICE. * - * Apparently, the ICE behaves differently right after a - * power-up vs. when reconnecting to an ICE that has already - * been worked with. The undocumented 'E' command (or - * subcommand) occasionally helps in getting the connection into - * sync. + * Apparently, the ICE behaves differently right after a power-up vs. + * when reconnecting to an ICE that has already been worked with. The + * undocumented 'E' command (or subcommand) occasionally helps in getting + * the connection into sync. */ buf[0] = CMD_GET_SIGNON; buf[1] = 'E'; @@ -255,19 +239,19 @@ static int jtagmkI_resync(const PROGRAMMER *pgm, int maxtries, int signon) { buf[3] = ' '; pmsg_notice2("%s(): sending sign-on command: ", __func__); - if (serial_send(&pgm->fd, buf, 4) != 0) { - msg_error("\n"); - pmsg_error("unable to send command to serial port\n"); - serial_recv_timeout = otimeout; - return -1; + if(serial_send(&pgm->fd, buf, 4) != 0) { + msg_error("\n"); + pmsg_error("unable to send command to serial port\n"); + serial_recv_timeout = otimeout; + return -1; } - if (serial_recv(&pgm->fd, resp, 9) == 0 && resp[0] == RESP_OK) { + if(serial_recv(&pgm->fd, resp, 9) == 0 && resp[0] == RESP_OK) { msg_notice2("got RESP_OK\n"); - break; + break; } } } - if (tries >= maxtries) { + if(tries >= maxtries) { pmsg_notice2("%s(): timeout/error communicating with programmer\n", __func__); serial_recv_timeout = otimeout; return -1; @@ -280,7 +264,7 @@ static int jtagmkI_resync(const PROGRAMMER *pgm, int maxtries, int signon) { static int jtagmkI_getsync(const PROGRAMMER *pgm) { unsigned char buf[1], resp[9]; - if (jtagmkI_resync(pgm, 5, 1) < 0) { + if(jtagmkI_resync(pgm, 5, 1) < 0) { jtagmkI_drain(pgm, 0); return -1; } @@ -291,7 +275,7 @@ static int jtagmkI_getsync(const PROGRAMMER *pgm) { buf[0] = CMD_GET_SIGNON; jtagmkI_send(pgm, buf, 1); - if (jtagmkI_recv(pgm, resp, 9) < 0) + if(jtagmkI_recv(pgm, resp, 9) < 0) return -1; resp[8] = '\0'; msg_notice2("got %s\n", resp + 1); @@ -299,18 +283,16 @@ static int jtagmkI_getsync(const PROGRAMMER *pgm) { return 0; } -/* - * issue the 'chip erase' command to the AVR device - */ +// Issue the chip erase command to the AVR device static int jtagmkI_chip_erase(const PROGRAMMER *pgm, const AVRPART *p) { unsigned char buf[1], resp[2]; buf[0] = CMD_CHIP_ERASE; pmsg_notice2("%s(): sending chip erase command: ", __func__); jtagmkI_send(pgm, buf, 1); - if (jtagmkI_recv(pgm, resp, 2) < 0) + if(jtagmkI_recv(pgm, resp, 2) < 0) return -1; - if (resp[0] != RESP_OK) { + if(resp[0] != RESP_OK) { msg_notice2("\n"); pmsg_error("timeout/error communicating with programmer (resp %c)\n", resp[0]); return -1; @@ -326,7 +308,7 @@ static int jtagmkI_chip_erase(const PROGRAMMER *pgm, const AVRPART *p) { static void jtagmkI_set_devdescr(const PROGRAMMER *pgm, const AVRPART *p) { unsigned char resp[2]; LNODEID ln; - AVRMEM * m; + AVRMEM *m; struct { unsigned char cmd; struct device_descriptor dd; @@ -337,22 +319,22 @@ static void jtagmkI_set_devdescr(const PROGRAMMER *pgm, const AVRPART *p) { sendbuf.dd.ucSPMCRAddress = p->spmcr; sendbuf.dd.ucRAMPZAddress = p->rampz; sendbuf.dd.ucIDRAddress = p->idr; - for (ln = lfirst(p->mem); ln; ln = lnext(ln)) { + for(ln = lfirst(p->mem); ln; ln = lnext(ln)) { m = ldata(ln); - if (mem_is_flash(m)) { - PDATA(pgm)->flash_pagesize = m->page_size; - u16_to_b2(sendbuf.dd.uiFlashPageSize, PDATA(pgm)->flash_pagesize); - } else if (mem_is_eeprom(m)) { - sendbuf.dd.ucEepromPageSize = PDATA(pgm)->eeprom_pagesize = m->page_size; + if(mem_is_flash(m)) { + my.flash_pagesize = m->page_size; + u16_to_b2(sendbuf.dd.uiFlashPageSize, my.flash_pagesize); + } else if(mem_is_eeprom(m)) { + sendbuf.dd.ucEepromPageSize = my.eeprom_pagesize = m->page_size; } } pmsg_notice2("%s(): sending set device descriptor command: ", __func__); - jtagmkI_send(pgm, (unsigned char *)&sendbuf, sizeof(sendbuf)); + jtagmkI_send(pgm, (unsigned char *) &sendbuf, sizeof(sendbuf)); - if (jtagmkI_recv(pgm, resp, 2) < 0) + if(jtagmkI_recv(pgm, resp, 2) < 0) return; - if (resp[0] != RESP_OK) { + if(resp[0] != RESP_OK) { msg_notice2("\n"); pmsg_error("timeout/error communicating with programmer (resp %c)\n", resp[0]); } else { @@ -360,9 +342,7 @@ static void jtagmkI_set_devdescr(const PROGRAMMER *pgm, const AVRPART *p) { } } -/* - * Reset the target. - */ +// Reset the target static int jtagmkI_reset(const PROGRAMMER *pgm) { unsigned char buf[1], resp[2]; @@ -370,14 +350,14 @@ static int jtagmkI_reset(const PROGRAMMER *pgm) { pmsg_notice2("%s(): sending reset command: ", __func__); jtagmkI_send(pgm, buf, 1); - if (jtagmkI_recv(pgm, resp, 2) < 0) + if(jtagmkI_recv(pgm, resp, 2) < 0) return -1; - if (resp[0] != RESP_OK) { + if(resp[0] != RESP_OK) { msg_notice2("\n"); pmsg_error("timeout/error communicating with programmer (resp %c)\n", resp[0]); return -1; } else { - msg_notice2("OK\n"); + msg_notice2("OK\n"); } return 0; @@ -390,16 +370,16 @@ static int jtagmkI_program_enable_dummy(const PROGRAMMER *pgm, const AVRPART *p) static int jtagmkI_program_enable(const PROGRAMMER *pgm) { unsigned char buf[1], resp[2]; - if (PDATA(pgm)->prog_enabled) + if(my.prog_enabled) return 0; buf[0] = CMD_ENTER_PROGMODE; pmsg_notice2("%s(): sending enter progmode command: ", __func__); jtagmkI_send(pgm, buf, 1); - if (jtagmkI_recv(pgm, resp, 2) < 0) + if(jtagmkI_recv(pgm, resp, 2) < 0) return -1; - if (resp[0] != RESP_OK) { + if(resp[0] != RESP_OK) { msg_notice2("\n"); pmsg_error("timeout/error communicating with programmer (resp %c)\n", resp[0]); return -1; @@ -407,7 +387,7 @@ static int jtagmkI_program_enable(const PROGRAMMER *pgm) { msg_notice2("OK\n"); } - PDATA(pgm)->prog_enabled = 1; + my.prog_enabled = 1; return 0; } @@ -415,17 +395,17 @@ static int jtagmkI_program_enable(const PROGRAMMER *pgm) { static int jtagmkI_program_disable(const PROGRAMMER *pgm) { unsigned char buf[1], resp[2]; - if (!PDATA(pgm)->prog_enabled) + if(!my.prog_enabled) return 0; - if (pgm->fd.ifd != -1) { + if(pgm->fd.ifd != -1) { buf[0] = CMD_LEAVE_PROGMODE; pmsg_notice2("%s(): sending leave progmode command: ", __func__); jtagmkI_send(pgm, buf, 1); - if (jtagmkI_recv(pgm, resp, 2) < 0) + if(jtagmkI_recv(pgm, resp, 2) < 0) return -1; - if (resp[0] != RESP_OK) { + if(resp[0] != RESP_OK) { msg_notice2("\n"); pmsg_error("timeout/error communicating with programmer (resp %c)\n", resp[0]); return -1; @@ -433,128 +413,122 @@ static int jtagmkI_program_disable(const PROGRAMMER *pgm) { msg_notice2("OK\n"); } } - PDATA(pgm)->prog_enabled = 0; + my.prog_enabled = 0; return 0; } static unsigned char jtagmkI_get_baud(long baud) { - for (size_t i = 0; i < sizeof baudtab / sizeof baudtab[0]; i++) - if (baud == baudtab[i].baud) + for(size_t i = 0; i < sizeof baudtab/sizeof baudtab[0]; i++) + if(baud == baudtab[i].baud) return baudtab[i].val; return 0; } -/* - * initialize the AVR device and prepare it to accept commands - */ +// Initialize the AVR device and prepare it to accept commands static int jtagmkI_initialize(const PROGRAMMER *pgm, const AVRPART *p) { unsigned char cmd[1], resp[5]; unsigned char b; - if (!(p->prog_modes & (PM_JTAGmkI | PM_JTAG))) { + if(!(p->prog_modes & (PM_JTAGmkI | PM_JTAG))) { pmsg_error("part %s has no JTAG interface\n", p->desc); return -1; } - if (!(p->prog_modes & PM_JTAGmkI)) + if(!is_jtagmki(p)) pmsg_warning("part %s has JTAG interface, but may be too new\n", p->desc); jtagmkI_drain(pgm, 0); - if ((serdev->flags & SERDEV_FL_CANSETSPEED) && PDATA(pgm)->initial_baudrate != pgm->baudrate) { - if ((b = jtagmkI_get_baud(pgm->baudrate)) == 0) { + if((serdev->flags & SERDEV_FL_CANSETSPEED) && my.initial_baudrate != pgm->baudrate) { + if((b = jtagmkI_get_baud(pgm->baudrate)) == 0) { pmsg_error("unsupported baudrate %d\n", pgm->baudrate); } else { pmsg_notice2("%s(): trying to set baudrate to %d\n", __func__, pgm->baudrate); - if (jtagmkI_setparm(pgm, PARM_BITRATE, b) == 0) { - PDATA(pgm)->initial_baudrate = pgm->baudrate; /* don't adjust again later */ + if(jtagmkI_setparm(pgm, PARM_BITRATE, b) == 0) { + my.initial_baudrate = pgm->baudrate; // Don't adjust again later serial_setparams(&pgm->fd, pgm->baudrate, SERIAL_8N1); } } } - if (pgm->bitclock != 0.0) { + if(pgm->bitclock != 0.0) { pmsg_notice2("%s(): trying to set JTAG clock period to %.1f us\n", __func__, pgm->bitclock); - if (jtagmkI_set_sck_period(pgm, pgm->bitclock) != 0) + if(jtagmkI_set_sck_period(pgm, pgm->bitclock) != 0) return -1; } cmd[0] = CMD_STOP; jtagmkI_send(pgm, cmd, 1); - if (jtagmkI_recv(pgm, resp, 5) < 0) + if(jtagmkI_recv(pgm, resp, 5) < 0) return -1; - if (resp[0] != RESP_OK) { + if(resp[0] != RESP_OK) { msg_notice2("\n"); pmsg_warning("timeout/error communicating with programmer (resp %c)\n", resp[0]); } else { msg_notice2("OK\n"); } - /* - * Must set the device descriptor before entering programming mode. - */ + // Must set the device descriptor before entering programming mode jtagmkI_set_devdescr(pgm, p); - jtagmkI_setparm(pgm, PARM_FLASH_PAGESIZE_LOW, PDATA(pgm)->flash_pagesize & 0xff); - jtagmkI_setparm(pgm, PARM_FLASH_PAGESIZE_HIGH, PDATA(pgm)->flash_pagesize >> 8); - jtagmkI_setparm(pgm, PARM_EEPROM_PAGESIZE, PDATA(pgm)->eeprom_pagesize & 0xff); + jtagmkI_setparm(pgm, PARM_FLASH_PAGESIZE_LOW, my.flash_pagesize & 0xff); + jtagmkI_setparm(pgm, PARM_FLASH_PAGESIZE_HIGH, my.flash_pagesize >> 8); + jtagmkI_setparm(pgm, PARM_EEPROM_PAGESIZE, my.eeprom_pagesize & 0xff); - mmt_free(PDATA(pgm)->flash_pagecache); - mmt_free(PDATA(pgm)->eeprom_pagecache); - PDATA(pgm)->flash_pagecache = mmt_malloc(PDATA(pgm)->flash_pagesize); - PDATA(pgm)->eeprom_pagecache = mmt_malloc(PDATA(pgm)->eeprom_pagesize); - PDATA(pgm)->flash_pageaddr = PDATA(pgm)->eeprom_pageaddr = ~0UL; + mmt_free(my.flash_pagecache); + mmt_free(my.eeprom_pagecache); + my.flash_pagecache = mmt_malloc(my.flash_pagesize); + my.eeprom_pagecache = mmt_malloc(my.eeprom_pagesize); + my.flash_pageaddr = my.eeprom_pageaddr = ~0UL; - if (jtagmkI_reset(pgm) < 0) + if(jtagmkI_reset(pgm) < 0) return -1; int ocden = 0; + if(avr_get_config_value(pgm, p, "ocden", &ocden) == 0 && ocden) // ocden == 1 means disabled pmsg_warning("OCDEN fuse not programmed, single-byte EEPROM updates not possible\n"); return 0; } - static void jtagmkI_disable(const PROGRAMMER *pgm) { - mmt_free(PDATA(pgm)->flash_pagecache); - PDATA(pgm)->flash_pagecache = NULL; - mmt_free(PDATA(pgm)->eeprom_pagecache); - PDATA(pgm)->eeprom_pagecache = NULL; + mmt_free(my.flash_pagecache); + my.flash_pagecache = NULL; + mmt_free(my.eeprom_pagecache); + my.eeprom_pagecache = NULL; - (void)jtagmkI_program_disable(pgm); + (void) jtagmkI_program_disable(pgm); } static void jtagmkI_enable(PROGRAMMER *pgm, const AVRPART *p) { return; } - static int jtagmkI_open(PROGRAMMER *pgm, const char *port) { size_t i; pmsg_notice2("jtagmkI_open()\n"); pgm->port = port; - PDATA(pgm)->initial_baudrate = -1L; + my.initial_baudrate = -1L; - for (i = 0; i < sizeof(baudtab) / sizeof(baudtab[0]); i++) { + for(i = 0; i < sizeof(baudtab)/sizeof(baudtab[0]); i++) { union pinfo pinfo; + pinfo.serialinfo.baud = baudtab[i].baud; pinfo.serialinfo.cflags = SERIAL_8N1; pmsg_notice2("%s(): trying to sync at baud rate %ld:\n", __func__, pinfo.serialinfo.baud); - if (serial_open(port, pinfo, &pgm->fd)==-1) { + if(serial_open(port, pinfo, &pgm->fd) == -1) { return -1; } - /* - * drain any extraneous input - */ + // Drain any extraneous input jtagmkI_drain(pgm, 0); - if (jtagmkI_getsync(pgm) == 0) { - PDATA(pgm)->initial_baudrate = baudtab[i].baud; + if(jtagmkI_getsync(pgm) == 0) { + my.initial_baudrate = baudtab[i].baud; pmsg_notice2("%s(): succeeded\n", __func__); return 0; } @@ -568,97 +542,93 @@ static int jtagmkI_open(PROGRAMMER *pgm, const char *port) { return -1; } - static void jtagmkI_close(PROGRAMMER *pgm) { unsigned char b; pmsg_notice2("jtagmkI_close()\n"); /* - * Revert baud rate to what it used to be when we started. This - * appears to make AVR Studio happier when it is about to access the - * ICE later on. + * Revert baud rate to what it used to be when we started. This appears to + * make AVR Studio happier when it is about to access the ICE later on. */ - if ((serdev->flags & SERDEV_FL_CANSETSPEED) && PDATA(pgm)->initial_baudrate != pgm->baudrate) { - if ((b = jtagmkI_get_baud(PDATA(pgm)->initial_baudrate)) == 0) { - pmsg_error("unsupported baudrate %d\n", PDATA(pgm)->initial_baudrate); + if((serdev->flags & SERDEV_FL_CANSETSPEED) && my.initial_baudrate != pgm->baudrate) { + if((b = jtagmkI_get_baud(my.initial_baudrate)) == 0) { + pmsg_error("unsupported baudrate %d\n", my.initial_baudrate); } else { - pmsg_notice2("%s(): trying to set baudrate to %d\n", __func__, PDATA(pgm)->initial_baudrate); - if (jtagmkI_setparm(pgm, PARM_BITRATE, b) == 0) { + pmsg_notice2("%s(): trying to set baudrate to %d\n", __func__, my.initial_baudrate); + if(jtagmkI_setparm(pgm, PARM_BITRATE, b) == 0) { serial_setparams(&pgm->fd, pgm->baudrate, SERIAL_8N1); } } } - if (pgm->fd.ifd != -1) { + if(pgm->fd.ifd != -1) { serial_close(&pgm->fd); } pgm->fd.ifd = -1; } - static int jtagmkI_paged_write(const PROGRAMMER *pgm, const AVRPART *p, const AVRMEM *m, - unsigned int page_size, - unsigned int addr, unsigned int n_bytes) -{ + unsigned int page_size, unsigned int addr, unsigned int n_bytes) { int block_size, send_size, tries; unsigned int maxaddr = addr + n_bytes; unsigned char cmd[6], *datacmd = NULL; unsigned char resp[2]; int is_flash = 0; long otimeout = serial_recv_timeout; + #define MAXTRIES 3 pmsg_notice2("jtagmkI_paged_write(.., %s, %d, %d)\n", m->desc, page_size, n_bytes); - if (jtagmkI_program_enable(pgm) < 0) + if(jtagmkI_program_enable(pgm) < 0) return -1; - if (page_size == 0) + if(page_size == 0) page_size = 256; - if (page_size > 256) { + if(page_size > 256) { pmsg_error("page size %d too large\n", page_size); return -1; } datacmd = mmt_malloc(page_size + 1); cmd[0] = CMD_WRITE_MEM; - if (mem_is_flash(m)) { + if(mem_is_flash(m)) { cmd[1] = MTYPE_FLASH_PAGE; - PDATA(pgm)->flash_pageaddr = ~0UL; - page_size = PDATA(pgm)->flash_pagesize; + my.flash_pageaddr = ~0UL; + page_size = my.flash_pagesize; is_flash = 1; - } else if (mem_is_eeprom(m)) { + } else if(mem_is_eeprom(m)) { cmd[1] = MTYPE_EEPROM_PAGE; - PDATA(pgm)->eeprom_pageaddr = ~0UL; - page_size = PDATA(pgm)->eeprom_pagesize; + my.eeprom_pageaddr = ~0UL; + page_size = my.eeprom_pagesize; } datacmd[0] = CMD_DATA; serial_recv_timeout = 1000; - for (; addr < maxaddr; addr += page_size) { + for(; addr < maxaddr; addr += page_size) { tries = 0; - again: + again: - if (tries != 0 && jtagmkI_resync(pgm, 2000, 0) < 0) { + if(tries != 0 && jtagmkI_resync(pgm, 2000, 0) < 0) { pmsg_error("sync loss, retries exhausted\n"); mmt_free(datacmd); return -1; } - if (n_bytes < page_size) + if(n_bytes < page_size) block_size = n_bytes; else block_size = page_size; pmsg_debug("%s(): block_size at addr %d is %d\n", __func__, addr, block_size); - /* We always write full pages. */ + // We always write full pages send_size = page_size; - if (is_flash) { - cmd[2] = send_size / 2 - 1; - u32_to_b3(cmd + 3, addr / 2); + if(is_flash) { + cmd[2] = send_size/2 - 1; + u32_to_b3(cmd + 3, addr/2); } else { cmd[2] = send_size - 1; u32_to_b3(cmd + 3, addr); @@ -666,17 +636,17 @@ static int jtagmkI_paged_write(const PROGRAMMER *pgm, const AVRPART *p, const AV pmsg_notice2("%s(): sending write memory command: ", __func__); - /* First part, send the write command. */ + // First part, send the write command jtagmkI_send(pgm, cmd, 6); - if (jtagmkI_recv(pgm, resp, 1) < 0) { + if(jtagmkI_recv(pgm, resp, 1) < 0) { mmt_free(datacmd); return -1; } - if (resp[0] != RESP_OK) { + if(resp[0] != RESP_OK) { msg_notice2("\n"); pmsg_warning("timeout/error communicating with programmer (resp %c)\n", resp[0]); - if (tries++ < MAXTRIES) - goto again; + if(tries++ < MAXTRIES) + goto again; serial_recv_timeout = otimeout; mmt_free(datacmd); return -1; @@ -685,26 +655,26 @@ static int jtagmkI_paged_write(const PROGRAMMER *pgm, const AVRPART *p, const AV } /* - * The JTAG ICE will refuse to write anything but a full page, at - * least for the flash ROM. If a partial page has been requested, - * set the remainder to 0xff. (Maybe we should rather read back - * the existing contents instead before? Doesn't matter much, as - * bits cannot be written to 1 anyway.) + * The JTAG ICE will refuse to write anything but a full page, at least for + * the flash ROM. If a partial page has been requested, set the remainder + * to 0xff. (Maybe we should rather read back the existing contents + * instead before? Doesn't matter much, as bits cannot be written to 1 + * anyway.) */ memset(datacmd + 1, 0xff, page_size); memcpy(datacmd + 1, m->buf + addr, block_size); - /* Second, send the data command. */ + // Second, send the data command jtagmkI_send(pgm, datacmd, send_size + 1); - if (jtagmkI_recv(pgm, resp, 2) < 0) { + if(jtagmkI_recv(pgm, resp, 2) < 0) { mmt_free(datacmd); return -1; } - if (resp[1] != RESP_OK) { + if(resp[1] != RESP_OK) { msg_notice2("\n"); pmsg_warning("timeout/error communicating with programmer (resp %c)\n", resp[0]); - if (tries++ < MAXTRIES) - goto again; + if(tries++ < MAXTRIES) + goto again; serial_recv_timeout = otimeout; mmt_free(datacmd); return -1; @@ -721,54 +691,53 @@ static int jtagmkI_paged_write(const PROGRAMMER *pgm, const AVRPART *p, const AV } static int jtagmkI_paged_load(const PROGRAMMER *pgm, const AVRPART *p, const AVRMEM *m, - unsigned int page_size, - unsigned int addr, unsigned int n_bytes) -{ + unsigned int page_size, unsigned int addr, unsigned int n_bytes) { int block_size, read_size, is_flash = 0, tries; unsigned int maxaddr = addr + n_bytes; - unsigned char cmd[6], resp[256 * 2 + 3]; + unsigned char cmd[6], resp[256*2 + 3]; long otimeout = serial_recv_timeout; + #define MAXTRIES 3 pmsg_notice2("jtagmkI_paged_load(.., %s, %d, %d)\n", m->desc, page_size, n_bytes); - if (jtagmkI_program_enable(pgm) < 0) + if(jtagmkI_program_enable(pgm) < 0) return -1; page_size = m->readsize; cmd[0] = CMD_READ_MEM; - if (mem_is_flash(m)) { + if(mem_is_flash(m)) { cmd[1] = MTYPE_FLASH_PAGE; is_flash = 1; - } else if (mem_is_eeprom(m)) { + } else if(mem_is_eeprom(m)) { cmd[1] = MTYPE_EEPROM_PAGE; } - if (page_size > (is_flash? 512: 256)) { + if(page_size > (is_flash? 512: 256)) { pmsg_error("page size %d too large\n", page_size); return -1; } serial_recv_timeout = 1000; - for (; addr < maxaddr; addr += page_size) { + for(; addr < maxaddr; addr += page_size) { tries = 0; - again: - if (tries != 0 && jtagmkI_resync(pgm, 2000, 0) < 0) { + again: + if(tries != 0 && jtagmkI_resync(pgm, 2000, 0) < 0) { pmsg_error("sync loss, retries exhausted\n"); return -1; } - if (n_bytes < page_size) + if(n_bytes < page_size) block_size = n_bytes; else block_size = page_size; pmsg_debug("%s(): block_size at addr %d is %d\n", __func__, addr, block_size); - if (is_flash) { - read_size = 2 * ((block_size + 1) / 2); /* round up */ - cmd[2] = read_size / 2 - 1; - u32_to_b3(cmd + 3, addr / 2); + if(is_flash) { + read_size = 2*((block_size + 1)/2); // Round up + cmd[2] = read_size/2 - 1; + u32_to_b3(cmd + 3, addr/2); } else { read_size = page_size; cmd[2] = page_size - 1; @@ -778,14 +747,14 @@ static int jtagmkI_paged_load(const PROGRAMMER *pgm, const AVRPART *p, const AVR pmsg_notice2("%s(): sending read memory command: ", __func__); jtagmkI_send(pgm, cmd, 6); - if (jtagmkI_recv(pgm, resp, read_size + 3) < 0) + if(jtagmkI_recv(pgm, resp, read_size + 3) < 0) return -1; - if (resp[read_size + 3 - 1] != RESP_OK) { + if(resp[read_size + 3 - 1] != RESP_OK) { msg_notice2("\n"); pmsg_warning("timeout/error communicating with programmer (resp %c)\n", resp[read_size + 3 - 1]); - if (tries++ < MAXTRIES) - goto again; + if(tries++ < MAXTRIES) + goto again; serial_recv_timeout = otimeout; return -1; @@ -802,10 +771,9 @@ static int jtagmkI_paged_load(const PROGRAMMER *pgm, const AVRPART *p, const AVR } static int jtagmkI_read_byte(const PROGRAMMER *pgm, const AVRPART *p, const AVRMEM *mem, - unsigned long addr, unsigned char * value) -{ + unsigned long addr, unsigned char *value) { unsigned char cmd[6]; - unsigned char resp[256 * 2 + 3], *cache_ptr = NULL; + unsigned char resp[256*2 + 3], *cache_ptr = NULL; unsigned long paddr = 0UL, *paddr_ptr = NULL; unsigned int pagesize = 0; int respsize = 3 + 1; @@ -813,37 +781,37 @@ static int jtagmkI_read_byte(const PROGRAMMER *pgm, const AVRPART *p, const AVRM pmsg_notice2("jtagmkI_read_byte(.., %s, 0x%lx, ...)\n", mem->desc, addr); - if (jtagmkI_program_enable(pgm) < 0) + if(jtagmkI_program_enable(pgm) < 0) return -1; cmd[0] = CMD_READ_MEM; - if (mem_is_flash(mem)) { + if(mem_is_flash(mem)) { cmd[1] = MTYPE_FLASH_PAGE; pagesize = mem->page_size; paddr = addr & ~(pagesize - 1); - paddr_ptr = &PDATA(pgm)->flash_pageaddr; - cache_ptr = PDATA(pgm)->flash_pagecache; + paddr_ptr = &my.flash_pageaddr; + cache_ptr = my.flash_pagecache; is_flash = 1; - } else if (mem_is_eeprom(mem)) { + } else if(mem_is_eeprom(mem)) { cmd[1] = MTYPE_EEPROM_PAGE; pagesize = mem->page_size; paddr = addr & ~(pagesize - 1); - paddr_ptr = &PDATA(pgm)->eeprom_pageaddr; - cache_ptr = PDATA(pgm)->eeprom_pagecache; - } else if (mem_is_a_fuse(mem) || mem_is_fuses(mem)) { + paddr_ptr = &my.eeprom_pageaddr; + cache_ptr = my.eeprom_pagecache; + } else if(mem_is_a_fuse(mem) || mem_is_fuses(mem)) { cmd[1] = MTYPE_FUSE_BITS; if(mem_is_a_fuse(mem)) addr = mem_fuse_offset(mem); - } else if (mem_is_lock(mem)) { + } else if(mem_is_lock(mem)) { cmd[1] = MTYPE_LOCK_BITS; - } else if (mem_is_calibration(mem)) { + } else if(mem_is_calibration(mem)) { cmd[1] = MTYPE_OSCCAL_BYTE; - } else if (mem_is_signature(mem)) { + } else if(mem_is_signature(mem)) { cmd[1] = MTYPE_SIGN_JTAG; - } else if (mem_is_in_sigrow(mem)) { + } else if(mem_is_in_sigrow(mem)) { addr += avr_sigrow_offset(p, mem, addr); - cmd[1] = addr&1? MTYPE_OSCCAL_BYTE: MTYPE_SIGN_JTAG; + cmd[1] = addr & 1? MTYPE_OSCCAL_BYTE: MTYPE_SIGN_JTAG; addr /= 2; } else { pmsg_error("unknown memory %s\n", mem->desc); @@ -851,34 +819,33 @@ static int jtagmkI_read_byte(const PROGRAMMER *pgm, const AVRPART *p, const AVRM } /* - * To improve the read speed, we used paged reads for flash and - * EEPROM, and cache the results in a page cache. + * To improve the read speed, we used paged reads for flash and EEPROM, and + * cache the results in a page cache. * - * Page cache validation is based on "{flash,eeprom}_pageaddr" - * (holding the base address of the most recent cache fill - * operation). This variable is set to ~0UL when the - * cache needs to be invalidated. + * Page cache validation is based on "{flash,eeprom}_pageaddr" (holding the + * base address of the most recent cache fill operation). This variable is + * set to ~0UL when the cache needs to be invalidated. */ - if (pagesize && paddr == *paddr_ptr) { + if(pagesize && paddr == *paddr_ptr) { *value = cache_ptr[addr & (pagesize - 1)]; return 0; } - if (pagesize) { - if (is_flash) { - cmd[2] = pagesize / 2 - 1; - u32_to_b3(cmd + 3, paddr / 2); + if(pagesize) { + if(is_flash) { + cmd[2] = pagesize/2 - 1; + u32_to_b3(cmd + 3, paddr/2); } else { cmd[2] = pagesize - 1; u32_to_b3(cmd + 3, paddr); } respsize = 3 + pagesize; } else { - if (cmd[1] == MTYPE_FUSE_BITS) { + if(cmd[1] == MTYPE_FUSE_BITS) { /* - * The mkI ICE has a bug where it doesn't read efuse correctly - * when reading it as a single byte @offset 2, while reading all - * fuses at once does work. + * The mkI ICE has a bug where it doesn't read efuse correctly when + * reading it as a single byte @offset 2, while reading all fuses at once + * does work. */ cmd[2] = 3 - 1; u32_to_b3(cmd + 3, 0); @@ -890,10 +857,10 @@ static int jtagmkI_read_byte(const PROGRAMMER *pgm, const AVRPART *p, const AVRM } jtagmkI_send(pgm, cmd, 6); - if (jtagmkI_recv(pgm, resp, respsize) < 0) + if(jtagmkI_recv(pgm, resp, respsize) < 0) return -1; - if (resp[respsize - 1] != RESP_OK) { + if(resp[respsize - 1] != RESP_OK) { msg_notice2("\n"); pmsg_error("timeout/error communicating with programmer (resp %c)\n", resp[respsize - 1]); return -1; @@ -901,12 +868,12 @@ static int jtagmkI_read_byte(const PROGRAMMER *pgm, const AVRPART *p, const AVRM msg_notice2("OK\n"); } - if (pagesize) { + if(pagesize) { *paddr_ptr = paddr; memcpy(cache_ptr, resp + 1, pagesize); *value = cache_ptr[addr & (pagesize - 1)]; - } else if (cmd[1] == MTYPE_FUSE_BITS) { - /* extract the desired fuse */ + } else if(cmd[1] == MTYPE_FUSE_BITS) { + // Extract the desired fuse *value = resp[1 + addr]; } else *value = resp[1]; @@ -915,9 +882,8 @@ static int jtagmkI_read_byte(const PROGRAMMER *pgm, const AVRPART *p, const AVRM } static int jtagmkI_write_byte(const PROGRAMMER *pgm, const AVRPART *p, const AVRMEM *mem, - unsigned long addr, unsigned char data) -{ - unsigned char cmd[6], datacmd[1 * 2 + 1]; + unsigned long addr, unsigned char data) { + unsigned char cmd[6], datacmd[1*2 + 1]; unsigned char resp[1], writedata; int len, need_progmode = 1, need_dummy_read = 0; @@ -925,25 +891,26 @@ static int jtagmkI_write_byte(const PROGRAMMER *pgm, const AVRPART *p, const AVR writedata = data; cmd[0] = CMD_WRITE_MEM; - if (mem_is_flash(mem)) { + if(mem_is_flash(mem)) { cmd[1] = MTYPE_SPM; need_progmode = 0; - PDATA(pgm)->flash_pageaddr = ~0UL; - } else if (mem_is_eeprom(mem)) { + my.flash_pageaddr = ~0UL; + } else if(mem_is_eeprom(mem)) { cmd[1] = MTYPE_EEPROM; need_progmode = 0; need_dummy_read = 1; - PDATA(pgm)->eeprom_pageaddr = ~0UL; - } else if (mem_is_a_fuse(mem) || mem_is_fuses(mem)) { + my.eeprom_pageaddr = ~0UL; + } else if(mem_is_a_fuse(mem) || mem_is_fuses(mem)) { cmd[1] = MTYPE_FUSE_BITS; need_dummy_read = 1; if(mem_is_a_fuse(mem)) addr = mem_fuse_offset(mem); - } else if (mem_is_lock(mem)) { + } else if(mem_is_lock(mem)) { cmd[1] = MTYPE_LOCK_BITS; need_dummy_read = 1; } else if(mem_is_readonly(mem)) { unsigned char is; + if(pgm->read_byte(pgm, p, mem, addr, &is) >= 0 && is == data) return 0; @@ -954,29 +921,29 @@ static int jtagmkI_write_byte(const PROGRAMMER *pgm, const AVRPART *p, const AVR return -1; } - if (need_progmode) { - if (jtagmkI_program_enable(pgm) < 0) + if(need_progmode) { + if(jtagmkI_program_enable(pgm) < 0) return -1; } else { - if (jtagmkI_program_disable(pgm) < 0) + if(jtagmkI_program_disable(pgm) < 0) return -1; } cmd[2] = 1 - 1; - if (cmd[1] == MTYPE_SPM) { + if(cmd[1] == MTYPE_SPM) { /* - * Flash is word-addressed, but we cannot handle flash anyway - * here, as it needs to be written one page at a time ... + * Flash is word-addressed, but we cannot handle flash anyway here, as it + * needs to be written one page at a time ... */ - u32_to_b3(cmd + 3, addr / 2); + u32_to_b3(cmd + 3, addr/2); } else { u32_to_b3(cmd + 3, addr); } - /* First part, send the write command. */ + // First part, send the write command jtagmkI_send(pgm, cmd, 6); - if (jtagmkI_recv(pgm, resp, 1) < 0) + if(jtagmkI_recv(pgm, resp, 1) < 0) return -1; - if (resp[0] != RESP_OK) { + if(resp[0] != RESP_OK) { msg_notice2("\n"); pmsg_error("timeout/error communicating with programmer (resp %c)\n", resp[0]); return -1; @@ -984,11 +951,11 @@ static int jtagmkI_write_byte(const PROGRAMMER *pgm, const AVRPART *p, const AVR msg_notice2("OK\n"); } - /* Now, send the data buffer. */ + // Now, send the data buffer datacmd[0] = CMD_DATA; - if (cmd[1] == MTYPE_SPM) { + if(cmd[1] == MTYPE_SPM) { len = 3; - if ((addr & 1) != 0) { + if((addr & 1) != 0) { datacmd[1] = 0; datacmd[2] = writedata; } else { @@ -1000,9 +967,9 @@ static int jtagmkI_write_byte(const PROGRAMMER *pgm, const AVRPART *p, const AVR datacmd[1] = writedata; } jtagmkI_send(pgm, datacmd, len); - if (jtagmkI_recv(pgm, resp, 1) < 0) + if(jtagmkI_recv(pgm, resp, 1) < 0) return -1; - if (resp[0] != RESP_OK) { + if(resp[0] != RESP_OK) { msg_notice2("\n"); pmsg_error("timeout/error communicating with programmer (resp %c)\n", resp[0]); return -1; @@ -1015,25 +982,24 @@ static int jtagmkI_write_byte(const PROGRAMMER *pgm, const AVRPART *p, const AVR return 0; } - /* - * Set the JTAG clock. The actual frequency is quite a bit of - * guesswork, based on the values claimed by AVR Studio. Inside the - * JTAG ICE, the value is the delay count of a delay loop between the - * JTAG clock edges. A count of 0 bypasses the delay loop. + * Set the JTAG clock. The actual frequency is quite a bit of guesswork, based + * on the values claimed by AVR Studio. Inside the JTAG ICE, the value is the + * delay count of a delay loop between the JTAG clock edges. A count of 0 + * bypasses the delay loop. * - * As the STK500 expresses it as a period length (and we actualy do - * program a period length as well), we rather call it by that name. + * As the STK500 expresses it as a period length (and we actualy do program a + * period length as well), we rather call it by that name. */ static int jtagmkI_set_sck_period(const PROGRAMMER *pgm, double v) { unsigned char dur; - v = 1 / v; /* convert to frequency */ - if (v >= 1e6) + v = 1/v; // Convert to frequency + if(v >= 1e6) dur = JTAG_BITRATE_1_MHz; - else if (v >= 499e3) + else if(v >= 499e3) dur = JTAG_BITRATE_500_kHz; - else if (v >= 249e3) + else if(v >= 249e3) dur = JTAG_BITRATE_250_kHz; else dur = JTAG_BITRATE_125_kHz; @@ -1041,46 +1007,42 @@ static int jtagmkI_set_sck_period(const PROGRAMMER *pgm, double v) { return jtagmkI_setparm(pgm, PARM_CLOCK, dur); } - static int jtagmkI_get_sck_period(const PROGRAMMER *pgm, double *v) { unsigned char dur = 0; - if (jtagmkI_getparm(pgm, PARM_CLOCK, &dur) < 0) + + if(jtagmkI_getparm(pgm, PARM_CLOCK, &dur) < 0) return -1; - if (dur == JTAG_BITRATE_1_MHz) + if(dur == JTAG_BITRATE_1_MHz) *v = 1e6; - else if (dur == JTAG_BITRATE_500_kHz) + else if(dur == JTAG_BITRATE_500_kHz) *v = 500e3; - else if (dur == JTAG_BITRATE_250_kHz) + else if(dur == JTAG_BITRATE_250_kHz) *v = 250e3; - else if (dur == JTAG_BITRATE_125_kHz) + else if(dur == JTAG_BITRATE_125_kHz) *v = 125e3; - else { // something went wrong + else { // Something went wrong pmsg_error("wrong JTAG_BITRATE ID %02X\n", dur); return -1; } return 0; } - static int jtagmkI_get_vtarget(const PROGRAMMER *pgm, double *v) { unsigned char vtarget = 0; - if (jtagmkI_getparm(pgm, PARM_OCD_VTARGET, &vtarget) < 0) { + + if(jtagmkI_getparm(pgm, PARM_OCD_VTARGET, &vtarget) < 0) { pmsg_error("jtagmkI_getparm PARM_OCD_VTARGET failed\n"); return -1; } - *v = 6.25 * (unsigned)vtarget / 255.0; + *v = 6.25*(unsigned) vtarget/255.0; return 0; } - /* - * Read an emulator parameter. The result is exactly one byte, - * multi-byte parameters get two different parameter names for - * their components. + * Read an emulator parameter. The result is exactly one byte, multi-byte + * parameters get two different parameter names for their components. */ -static int jtagmkI_getparm(const PROGRAMMER *pgm, const unsigned char parm, - unsigned char * value) -{ +static int jtagmkI_getparm(const PROGRAMMER *pgm, const unsigned char parm, unsigned char *value) { unsigned char buf[2], resp[3]; pmsg_notice2("jtagmkI_getparm()\n"); @@ -1090,13 +1052,13 @@ static int jtagmkI_getparm(const PROGRAMMER *pgm, const unsigned char parm, pmsg_notice2("%s(): sending get parameter command (parm 0x%02x): ", __func__, parm); jtagmkI_send(pgm, buf, 2); - if (jtagmkI_recv(pgm, resp, 3) < 0) + if(jtagmkI_recv(pgm, resp, 3) < 0) return -1; - if (resp[0] != RESP_OK) { + if(resp[0] != RESP_OK) { msg_notice2("\n"); pmsg_error("timeout/error communicating with programmer (resp %c)\n", resp[0]); return -1; - } else if (resp[2] != RESP_OK) { + } else if(resp[2] != RESP_OK) { msg_notice2("\n"); pmsg_error("unknown parameter 0x%02x\n", parm); return -1; @@ -1109,12 +1071,8 @@ static int jtagmkI_getparm(const PROGRAMMER *pgm, const unsigned char parm, return 0; } -/* - * Write an emulator parameter. - */ -static int jtagmkI_setparm(const PROGRAMMER *pgm, unsigned char parm, - unsigned char value) -{ +// Write an emulator parameter +static int jtagmkI_setparm(const PROGRAMMER *pgm, unsigned char parm, unsigned char value) { unsigned char buf[3], resp[2]; pmsg_notice2("jtagmkI_setparm()\n"); @@ -1124,9 +1082,9 @@ static int jtagmkI_setparm(const PROGRAMMER *pgm, unsigned char parm, buf[2] = value; pmsg_notice2("%s(): sending set parameter command (parm 0x%02x): ", __func__, parm); jtagmkI_send(pgm, buf, 3); - if (jtagmkI_recv(pgm, resp, 2) < 0) + if(jtagmkI_recv(pgm, resp, 2) < 0) return -1; - if (resp[0] != RESP_OK) { + if(resp[0] != RESP_OK) { msg_notice2("\n"); pmsg_error("timeout/error communicating with programmer (resp %c)\n", resp[0]); return -1; @@ -1137,12 +1095,10 @@ static int jtagmkI_setparm(const PROGRAMMER *pgm, unsigned char parm, return 0; } - static void jtagmkI_display(const PROGRAMMER *pgm, const char *p) { unsigned char hw, fw; - if (jtagmkI_getparm(pgm, PARM_HW_VERSION, &hw) < 0 || - jtagmkI_getparm(pgm, PARM_SW_VERSION, &fw) < 0) + if(jtagmkI_getparm(pgm, PARM_HW_VERSION, &hw) < 0 || jtagmkI_getparm(pgm, PARM_SW_VERSION, &fw) < 0) return; msg_info("%sICE HW version : 0x%02x\n", p, hw); msg_info("%sICE FW version : 0x%02x\n", p, fw); @@ -1152,17 +1108,16 @@ static void jtagmkI_display(const PROGRAMMER *pgm, const char *p) { return; } - static void jtagmkI_print_parms1(const PROGRAMMER *pgm, const char *p, FILE *fp) { unsigned char jtag_clock = 0; double vtarget = 0; const char *clkstr; double clk; - if (jtagmkI_getparm(pgm, PARM_CLOCK, &jtag_clock) < 0) + if(jtagmkI_getparm(pgm, PARM_CLOCK, &jtag_clock) < 0) return; - switch ((unsigned)jtag_clock) { + switch((unsigned) jtag_clock) { case JTAG_BITRATE_1_MHz: clkstr = "1 MHz"; clk = 1e6; @@ -1188,17 +1143,16 @@ static void jtagmkI_print_parms1(const PROGRAMMER *pgm, const char *p, FILE *fp) clk = 1e6; } - if (pgm->extra_features & HAS_VTARG_READ) { - if (jtagmkI_get_vtarget(pgm, &vtarget) < 0) + if(pgm->extra_features & HAS_VTARG_READ) { + if(jtagmkI_get_vtarget(pgm, &vtarget) < 0) return; fmsg_out(fp, "%sVtarget : %.1f V\n", p, vtarget); } - fmsg_out(fp, "%sJTAG clock : %s (%.1f us)\n", p, clkstr, 1.0e6 / clk); + fmsg_out(fp, "%sJTAG clock : %s (%.1f us)\n", p, clkstr, 1.0e6/clk); return; } - static void jtagmkI_print_parms(const PROGRAMMER *pgm, FILE *fp) { jtagmkI_print_parms1(pgm, "", fp); } @@ -1208,32 +1162,28 @@ const char jtagmkI_desc[] = "Atmel JTAG ICE mkI"; void jtagmkI_initpgm(PROGRAMMER *pgm) { strcpy(pgm->type, "JTAGMKI"); - /* - * mandatory functions - */ - pgm->initialize = jtagmkI_initialize; - pgm->display = jtagmkI_display; - pgm->enable = jtagmkI_enable; - pgm->disable = jtagmkI_disable; + // Mandatory functions + pgm->initialize = jtagmkI_initialize; + pgm->display = jtagmkI_display; + pgm->enable = jtagmkI_enable; + pgm->disable = jtagmkI_disable; pgm->program_enable = jtagmkI_program_enable_dummy; - pgm->chip_erase = jtagmkI_chip_erase; - pgm->open = jtagmkI_open; - pgm->close = jtagmkI_close; - pgm->read_byte = jtagmkI_read_byte; - pgm->write_byte = jtagmkI_write_byte; - - /* - * optional functions - */ - pgm->paged_write = jtagmkI_paged_write; - pgm->paged_load = jtagmkI_paged_load; - pgm->print_parms = jtagmkI_print_parms; + pgm->chip_erase = jtagmkI_chip_erase; + pgm->open = jtagmkI_open; + pgm->close = jtagmkI_close; + pgm->read_byte = jtagmkI_read_byte; + pgm->write_byte = jtagmkI_write_byte; + + // Optional functions + pgm->paged_write = jtagmkI_paged_write; + pgm->paged_load = jtagmkI_paged_load; + pgm->print_parms = jtagmkI_print_parms; pgm->set_sck_period = jtagmkI_set_sck_period; pgm->get_sck_period = jtagmkI_get_sck_period; - pgm->setup = jtagmkI_setup; - pgm->teardown = jtagmkI_teardown; - pgm->page_size = 256; - if (pgm->extra_features & HAS_VTARG_READ) { - pgm->get_vtarget = jtagmkI_get_vtarget; + pgm->setup = jtagmkI_setup; + pgm->teardown = jtagmkI_teardown; + pgm->page_size = 256; + if(pgm->extra_features & HAS_VTARG_READ) { + pgm->get_vtarget = jtagmkI_get_vtarget; } } diff --git a/src/jtagmkI.h b/src/jtagmkI.h index 5d40c6b76..859c6f6a6 100644 --- a/src/jtagmkI.h +++ b/src/jtagmkI.h @@ -23,12 +23,10 @@ extern "C" { #endif -extern const char jtagmkI_desc[]; -void jtagmkI_initpgm(PROGRAMMER *pgm); + extern const char jtagmkI_desc[]; + void jtagmkI_initpgm(PROGRAMMER *pgm); #ifdef __cplusplus } #endif - #endif - diff --git a/src/jtagmkII.c b/src/jtagmkII.c index 46d0bec72..2b0eb7ea8 100644 --- a/src/jtagmkII.c +++ b/src/jtagmkII.c @@ -58,17 +58,12 @@ #include "jtagmkII_private.h" #include "usbdevs.h" -/* - * Private data for this programmer. - */ -struct pdata -{ - unsigned short command_sequence; /* Next cmd seqno to issue. */ +#define gotoerr {lineno = __LINE__; goto eRR;} - /* - * See jtagmkII_read_byte() for an explanation of the flash and - * EEPROM page caches. - */ +struct pdata { + unsigned short command_sequence; // Next cmd seqno to issue + + // See jtagmkII_read_byte() for an explanation of the flash and EEPROM page caches unsigned char *flash_pagecache; unsigned long flash_pageaddr; unsigned int flash_pagesize; @@ -77,25 +72,25 @@ struct pdata unsigned long eeprom_pageaddr; unsigned int eeprom_pagesize; - int prog_enabled; /* Cached value of PROGRAMMING status. */ - unsigned char serno[6]; /* JTAG ICE serial number. */ + int prog_enabled; // Cached value of PROGRAMMING status + unsigned char serno[6]; // JTAG ICE serial number - /* JTAG chain stuff */ + // JTAG chain stuff unsigned char jtagchain[4]; - /* Serial RTS/DTR setting */ + // Serial RTS/DTR setting int rts_mode; - /* The length of the device descriptor is firmware-dependent. */ + // The length of the device descriptor is firmware-dependent size_t device_descriptor_length; - /* Start address of Xmega boot area */ + // Start address of Xmega boot area unsigned long boot_start; - /* Major firmware version (needed for Xmega programming) */ + // Major firmware version (needed for Xmega programming) unsigned int fwver; - /* Most recent operation was a memory write or erase */ + // Most recent operation was a memory write or erase int recently_written; #define FLAGS32_INIT_SMC 1 // Part will undergo chip erase @@ -106,7 +101,7 @@ struct pdata char msg[64]; // Used in jtagmkII_get_rc() }; -#define PDATA(pgm) ((struct pdata *)(pgm->cookie)) +#define my (*(struct pdata *) (pgm->cookie)) #define RC(x) { x, #x }, static const struct { @@ -114,45 +109,43 @@ static const struct { const char *descr; } jtagresults[] = { RC(RSP_DEBUGWIRE_SYNC_FAILED) - RC(RSP_FAILED) - RC(RSP_ILLEGAL_BREAKPOINT) - RC(RSP_ILLEGAL_COMMAND) - RC(RSP_ILLEGAL_EMULATOR_MODE) - RC(RSP_ILLEGAL_JTAG_ID) - RC(RSP_ILLEGAL_MCU_STATE) - RC(RSP_ILLEGAL_MEMORY_TYPE) - RC(RSP_ILLEGAL_MEMORY_RANGE) - RC(RSP_ILLEGAL_PARAMETER) - RC(RSP_ILLEGAL_POWER_STATE) - RC(RSP_ILLEGAL_VALUE) - RC(RSP_NO_TARGET_POWER) - RC(RSP_SET_N_PARAMETERS) + RC(RSP_FAILED) + RC(RSP_ILLEGAL_BREAKPOINT) + RC(RSP_ILLEGAL_COMMAND) + RC(RSP_ILLEGAL_EMULATOR_MODE) + RC(RSP_ILLEGAL_JTAG_ID) + RC(RSP_ILLEGAL_MCU_STATE) + RC(RSP_ILLEGAL_MEMORY_TYPE) + RC(RSP_ILLEGAL_MEMORY_RANGE) + RC(RSP_ILLEGAL_PARAMETER) + RC(RSP_ILLEGAL_POWER_STATE) + RC(RSP_ILLEGAL_VALUE) + RC(RSP_NO_TARGET_POWER) + RC(RSP_SET_N_PARAMETERS) }; /* - * pgm->flag is marked as "for private use of the programmer". - * The following defines this programmer's use of that field. + * pgm->flag is marked as "for private use of the programmer". The following + * defines this programmer's use of that field. */ -#define PGM_FL_IS_DW (0x0001) -#define PGM_FL_IS_PDI (0x0002) -#define PGM_FL_IS_JTAG (0x0004) +#define PGM_FL_IS_DW 0x0001 +#define PGM_FL_IS_PDI 0x0002 +#define PGM_FL_IS_JTAG 0x0004 static int jtagmkII_open(PROGRAMMER *pgm, const char *port); static int jtagmkII_initialize(const PROGRAMMER *pgm, const AVRPART *p); static int jtagmkII_chip_erase(const PROGRAMMER *pgm, const AVRPART *p); static int jtagmkII_read_byte(const PROGRAMMER *pgm, const AVRPART *p, const AVRMEM *mem, - unsigned long addr, unsigned char * value); + unsigned long addr, unsigned char *value); static int jtagmkII_write_byte(const PROGRAMMER *pgm, const AVRPART *p, const AVRMEM *mem, - unsigned long addr, unsigned char data); + unsigned long addr, unsigned char data); static int jtagmkII_reset(const PROGRAMMER *pgm, unsigned char flags); static int jtagmkII_set_sck_period(const PROGRAMMER *pgm, double v); -static int jtagmkII_setparm(const PROGRAMMER *pgm, unsigned char parm, - unsigned char * value); +static int jtagmkII_setparm(const PROGRAMMER *pgm, unsigned char parm, unsigned char *value); static void jtagmkII_print_parms1(const PROGRAMMER *pgm, const char *p, FILE *fp); static int jtagmkII_paged_write(const PROGRAMMER *pgm, const AVRPART *p, const AVRMEM *m, - unsigned int page_size, - unsigned int addr, unsigned int n_bytes); + unsigned int page_size, unsigned int addr, unsigned int n_bytes); static unsigned char jtagmkII_mtype(const PROGRAMMER *pgm, const AVRPART *p, unsigned long addr); static unsigned int jtagmkII_memaddr(const PROGRAMMER *pgm, const AVRPART *p, const AVRMEM *m, unsigned long addr); @@ -160,32 +153,29 @@ static unsigned int jtagmkII_memaddr(const PROGRAMMER *pgm, const AVRPART *p, co #define ERROR_SAB 0xFFFFFFFF static int jtagmkII_open32(PROGRAMMER *pgm, const char *port); -static void jtagmkII_close32(PROGRAMMER * pgm); +static void jtagmkII_close32(PROGRAMMER *pgm); static int jtagmkII_reset32(const PROGRAMMER *pgm, unsigned short flags); static int jtagmkII_initialize32(const PROGRAMMER *pgm, const AVRPART *p); static int jtagmkII_chip_erase32(const PROGRAMMER *pgm, const AVRPART *p); static unsigned long jtagmkII_read_SABaddr(const PROGRAMMER *pgm, unsigned long addr, - unsigned int prefix); // ERROR_SAB illegal + unsigned int prefix); // ERROR_SAB illegal static int jtagmkII_write_SABaddr(const PROGRAMMER *pgm, unsigned long addr, - unsigned int prefix, unsigned long val); + unsigned int prefix, unsigned long val); static int jtagmkII_avr32_reset(const PROGRAMMER *pgm, unsigned char val, - unsigned char ret1, unsigned char ret2); + unsigned char ret1, unsigned char ret2); static int jtagmkII_smc_init32(const PROGRAMMER *pgm); static int jtagmkII_paged_write32(const PROGRAMMER *pgm, const AVRPART *p, const AVRMEM *m, - unsigned int page_size, - unsigned int addr, unsigned int n_bytes); -static int jtagmkII_flash_lock32(const PROGRAMMER *pgm, unsigned char lock, - unsigned int page); + unsigned int page_size, unsigned int addr, unsigned int n_bytes); +static int jtagmkII_flash_lock32(const PROGRAMMER *pgm, unsigned char lock, unsigned int page); static int jtagmkII_flash_erase32(const PROGRAMMER *pgm, unsigned int page); static int jtagmkII_flash_write_page32(const PROGRAMMER *pgm, unsigned int page); static int jtagmkII_flash_clear_pagebuffer32(const PROGRAMMER *pgm); static int jtagmkII_paged_load32(const PROGRAMMER *pgm, const AVRPART *p, const AVRMEM *m, - unsigned int page_size, - unsigned int addr, unsigned int n_bytes); + unsigned int page_size, unsigned int addr, unsigned int n_bytes); void jtagmkII_setup(PROGRAMMER *pgm) { pgm->cookie = mmt_malloc(sizeof(struct pdata)); - PDATA(pgm)->rts_mode = RTS_MODE_DEFAULT; + my.rts_mode = RTS_MODE_DEFAULT; } void jtagmkII_teardown(PROGRAMMER *pgm) { @@ -195,20 +185,22 @@ void jtagmkII_teardown(PROGRAMMER *pgm) { static unsigned long b4_to_u32(unsigned char *b) { unsigned long l; + l = b[0]; - l += (unsigned)b[1] << 8; - l += (unsigned)b[2] << 16; - l += (unsigned)b[3] << 24; + l += (unsigned) b[1] << 8; + l += (unsigned) b[2] << 16; + l += (unsigned) b[3] << 24; return l; } static unsigned long b4_to_u32r(unsigned char *b) { unsigned long l; + l = b[3]; - l += (unsigned)b[2] << 8; - l += (unsigned)b[1] << 16; - l += (unsigned)b[0] << 24; + l += (unsigned) b[2] << 8; + l += (unsigned) b[1] << 16; + l += (unsigned) b[0] << 24; return l; } @@ -229,8 +221,9 @@ static void u32_to_b4r(unsigned char *b, unsigned long l) { static unsigned short b2_to_u16(unsigned char *b) { unsigned short l; + l = b[0]; - l += (unsigned)b[1] << 8; + l += (unsigned) b[1] << 8; return l; } @@ -241,50 +234,49 @@ static void u16_to_b2(unsigned char *b, unsigned short l) { } static const char *jtagmkII_get_rc(const PROGRAMMER *pgm, unsigned int rc) { - for (size_t i = 0; i < sizeof jtagresults/sizeof*jtagresults; i++) - if (jtagresults[i].code == rc) + for(size_t i = 0; i < sizeof jtagresults/sizeof *jtagresults; i++) + if(jtagresults[i].code == rc) return jtagresults[i].descr; - sprintf(PDATA(pgm)->msg, "Unknown JTAG ICE mkII result code 0x%02x", rc); - return PDATA(pgm)->msg; + sprintf(my.msg, "Unknown JTAG ICE mkII result code 0x%02x", rc); + return my.msg; } - static void jtagmkII_print_memory(unsigned char *b, size_t s) { size_t i; - if (s < 2) + if(s < 2) return; - for (i = 0; i < s - 1; i++) { + for(i = 0; i < s - 1; i++) { msg_info("0x%02x ", b[i + 1]); - if (i % 16 == 15) + if(i%16 == 15) msg_info("\n"); else msg_info(" "); } - if (i % 16 != 0) + if(i%16 != 0) msg_info("\n"); } static void jtagmkII_prmsg(const PROGRAMMER *pgm_unused, unsigned char *data, size_t len) { size_t i; - if (verbose >= MSG_TRACE) { + if(verbose >= MSG_TRACE) { msg_trace("Raw message:\n"); - for (i = 0; i < len; i++) { + for(i = 0; i < len; i++) { msg_trace("0x%02x", data[i]); - if (i % 16 == 15) - msg_trace("\n"); + if(i%16 == 15) + msg_trace("\n"); else - msg_trace(" "); + msg_trace(" "); } - if (i % 16 != 0) + if(i%16 != 0) msg_trace("\n"); } - switch (data[0]) { + switch(data[0]) { case RSP_OK: msg_info("OK\n"); break; @@ -303,13 +295,23 @@ static void jtagmkII_prmsg(const PROGRAMMER *pgm_unused, unsigned char *data, si case RSP_ILLEGAL_EMULATOR_MODE: msg_info("Illegal emulator mode"); - if (len > 1) - switch (data[1]) { - case EMULATOR_MODE_DEBUGWIRE: msg_info(": DebugWire"); break; - case EMULATOR_MODE_JTAG: msg_info(": JTAG"); break; - case EMULATOR_MODE_HV: msg_info(": HVSP/PP"); break; - case EMULATOR_MODE_SPI: msg_info(": SPI"); break; - case EMULATOR_MODE_JTAG_XMEGA: msg_info(": JTAG/Xmega"); break; + if(len > 1) + switch(data[1]) { + case EMULATOR_MODE_DEBUGWIRE: + msg_info(": DebugWire"); + break; + case EMULATOR_MODE_JTAG: + msg_info(": JTAG"); + break; + case EMULATOR_MODE_HV: + msg_info(": HVSP/PP"); + break; + case EMULATOR_MODE_SPI: + msg_info(": SPI"); + break; + case EMULATOR_MODE_JTAG_XMEGA: + msg_info(": JTAG/Xmega"); + break; } msg_info("\n"); break; @@ -320,11 +322,17 @@ static void jtagmkII_prmsg(const PROGRAMMER *pgm_unused, unsigned char *data, si case RSP_ILLEGAL_MCU_STATE: msg_info("Illegal MCU state"); - if (len > 1) - switch (data[1]) { - case STOPPED: msg_info(": Stopped"); break; - case RUNNING: msg_info(": Running"); break; - case PROGRAMMING: msg_info(": Programming"); break; + if(len > 1) + switch(data[1]) { + case STOPPED: + msg_info(": Stopped"); + break; + case RUNNING: + msg_info(": Running"); + break; + case PROGRAMMING: + msg_info(": Programming"); + break; } msg_info("\n"); break; @@ -355,7 +363,7 @@ static void jtagmkII_prmsg(const PROGRAMMER *pgm_unused, unsigned char *data, si case RSP_SIGN_ON: msg_info("Sign-on succeeded\n"); - /* Sign-on data will be printed below anyway. */ + // Sign-on data will be printed below anyway break; case RSP_MEMORY: @@ -370,30 +378,30 @@ static void jtagmkII_prmsg(const PROGRAMMER *pgm_unused, unsigned char *data, si case RSP_SPI_DATA: msg_info("SPI data returned:\n"); - for (i = 1; i < len; i++) + for(i = 1; i < len; i++) msg_info("0x%02x ", data[i]); msg_info("\n"); break; case EVT_BREAK: msg_info("BREAK event"); - if (len >= 6) { + if(len >= 6) { msg_info(", PC = 0x%lx, reason ", b4_to_u32(data + 1)); - switch (data[5]) { + switch(data[5]) { case 0x00: - msg_info("unspecified"); - break; + msg_info("unspecified"); + break; case 0x01: - msg_info("program break"); - break; + msg_info("program break"); + break; case 0x02: - msg_info("data break PDSB"); - break; + msg_info("data break PDSB"); + break; case 0x03: - msg_info("data break PDMSB"); - break; + msg_info("data break PDMSB"); + break; default: - msg_info("unknown: 0x%02x", data[5]); + msg_info("unknown: 0x%02x", data[5]); } } msg_info("\n"); @@ -406,7 +414,6 @@ static void jtagmkII_prmsg(const PROGRAMMER *pgm_unused, unsigned char *data, si msg_info("\n"); } - int jtagmkII_send(const PROGRAMMER *pgm, unsigned char *data, size_t len) { unsigned char *buf; @@ -415,14 +422,14 @@ int jtagmkII_send(const PROGRAMMER *pgm, unsigned char *data, size_t len) { buf = mmt_malloc(len + 10); buf[0] = MESSAGE_START; - u16_to_b2(buf + 1, PDATA(pgm)->command_sequence); + u16_to_b2(buf + 1, my.command_sequence); u32_to_b4(buf + 3, len); buf[7] = TOKEN; memcpy(buf + 8, data, len); crcappend(buf, len + 8); - if (serial_send(&pgm->fd, buf, len + 10) != 0) { + if(serial_send(&pgm->fd, buf, len + 10) != 0) { pmsg_error("unable to send command to serial port\n"); mmt_free(buf); return -1; @@ -433,32 +440,29 @@ int jtagmkII_send(const PROGRAMMER *pgm, unsigned char *data, size_t len) { return 0; } - static int jtagmkII_drain(const PROGRAMMER *pgm, int display) { return serial_drain(&pgm->fd, display); } - /* - * Receive one frame, return it in *msg. Received sequence number is - * returned in seqno. Any valid frame will be returned, regardless - * whether it matches the expected sequence number, including event - * notification frames (seqno == 0xffff). + * Receive one frame, return it in *msg. Received sequence number is returned + * in seqno. Any valid frame will be returned, regardless whether it matches + * the expected sequence number, including event notification frames (seqno == + * 0xffff). * * Caller must eventually mmt_free() the buffer. */ -static int jtagmkII_recv_frame(const PROGRAMMER *pgm, unsigned char **msg, - unsigned short * seqno) { +static int jtagmkII_recv_frame(const PROGRAMMER *pgm, unsigned char **msg, unsigned short *seqno) { enum states { sSTART, - /* NB: do NOT change the sequence of the following: */ - sSEQNUM1, sSEQNUM2, - sSIZE1, sSIZE2, sSIZE3, sSIZE4, - sTOKEN, - sDATA, - sCSUM1, sCSUM2, - /* end NB */ - sDONE - } state = sSTART; + // NB: do NOT change the sequence of the following + sSEQNUM1, sSEQNUM2, + sSIZE1, sSIZE2, sSIZE3, sSIZE4, + sTOKEN, + sDATA, + sCSUM1, sCSUM2, + // End NB + sDONE + } state = sSTART; unsigned long msglen = 0, l = 0; int headeridx = 0; int timeout = 0; @@ -467,112 +471,111 @@ static int jtagmkII_recv_frame(const PROGRAMMER *pgm, unsigned char **msg, unsigned char c, *buf = NULL, header[8]; unsigned short r_seqno = 0; - double timeoutval = 100; /* seconds */ + double timeoutval = 100; // Seconds double tstart, tnow; pmsg_trace("jtagmkII_recv():\n"); tstart = avr_timestamp(); - while ( (state != sDONE ) && (!timeout) ) { - if (state == sDATA) { + while((state != sDONE) && (!timeout)) { + if(state == sDATA) { rv = 0; - if (ignorpkt) { - /* skip packet's contents */ - for(l = 0; l < msglen; l++) - rv += serial_recv(&pgm->fd, &c, 1); + if(ignorpkt) { + // Skip packet's contents + for(l = 0; l < msglen; l++) + rv += serial_recv(&pgm->fd, &c, 1); } else { if(buf) - rv += serial_recv(&pgm->fd, buf + 8, msglen); + rv += serial_recv(&pgm->fd, buf + 8, msglen); } - if (rv != 0) { - timedout: - /* timeout in receive */ + if(rv != 0) { + timedout: + // Timeout in receive pmsg_notice2("%s(): timeout receiving packet\n", __func__); - mmt_free(buf); - return -1; + mmt_free(buf); + return -1; } } else { - if (serial_recv(&pgm->fd, &c, 1) != 0) - goto timedout; + if(serial_recv(&pgm->fd, &c, 1) != 0) + goto timedout; } - if (state < sDATA) + if(state < sDATA) header[headeridx++] = c; - switch (state) { - case sSTART: - if (c == MESSAGE_START) { - state = sSEQNUM1; + switch(state) { + case sSTART: + if(c == MESSAGE_START) { + state = sSEQNUM1; + } else { + headeridx = 0; + } + break; + case sSEQNUM1: + case sSEQNUM2: + r_seqno >>= 8; + r_seqno |= ((unsigned) c << 8); + state++; + break; + case sSIZE1: + case sSIZE2: + case sSIZE3: + case sSIZE4: + msglen >>= 8; + msglen |= ((unsigned) c << 24); + state++; + break; + case sTOKEN: + if(c == TOKEN) { + state = sDATA; + if(msglen > MAX_MESSAGE) { + pmsg_warning("msglen %lu exceeds max message size %u, ignoring message\n", msglen, MAX_MESSAGE); + state = sSTART; + headeridx = 0; } else { - headeridx = 0; - } - break; - case sSEQNUM1: - case sSEQNUM2: - r_seqno >>= 8; - r_seqno |= ((unsigned)c << 8); - state++; - break; - case sSIZE1: - case sSIZE2: - case sSIZE3: - case sSIZE4: - msglen >>= 8; - msglen |= ((unsigned)c << 24); + buf = mmt_malloc(msglen + 10); + memcpy(buf, header, 8); + } + } else { + state = sSTART; + headeridx = 0; + } + break; + case sDATA: + // The entire payload has been read above + l = msglen + 8; + state = sCSUM1; + break; + case sCSUM1: + case sCSUM2: + if(buf) + buf[l++] = c; + if(state == sCSUM2 && buf) { + if(crcverify(buf, msglen + 10)) { + if(verbose >= 9) + pmsg_trace2("%s(): CRC OK", __func__); + state = sDONE; + } else { + pmsg_error("wrong checksum\n"); + mmt_free(buf); + return -4; + } + } else state++; - break; - case sTOKEN: - if (c == TOKEN) { - state = sDATA; - if (msglen > MAX_MESSAGE) { - pmsg_warning("msglen %lu exceeds max message size %u, ignoring message\n", - msglen, MAX_MESSAGE); - state = sSTART; - headeridx = 0; - } else { - buf = mmt_malloc(msglen + 10); - memcpy(buf, header, 8); - } - } else { - state = sSTART; - headeridx = 0; - } - break; - case sDATA: - /* The entire payload has been read above. */ - l = msglen + 8; - state = sCSUM1; - break; - case sCSUM1: - case sCSUM2: - if(buf) - buf[l++] = c; - if (state == sCSUM2 && buf) { - if (crcverify(buf, msglen + 10)) { - if (verbose >= 9) - pmsg_trace2("%s(): CRC OK", __func__); - state = sDONE; - } else { - pmsg_error("wrong checksum\n"); - mmt_free(buf); - return -4; - } - } else - state++; - break; - default: - pmsg_error("unknown state\n"); - mmt_free(buf); - return -5; - } + break; + default: + pmsg_error("unknown state\n"); + mmt_free(buf); + return -5; + } - tnow = avr_timestamp(); - if (tnow - tstart > timeoutval) { - pmsg_error("timeout\n"); - mmt_free(buf); - return -1; - } + tnow = avr_timestamp(); + if(tnow - tstart > timeoutval) { + pmsg_error("timeout\n"); + mmt_free(buf); + return -1; + } } msg_debug("\n"); @@ -587,18 +590,18 @@ int jtagmkII_recv(const PROGRAMMER *pgm, unsigned char **msg) { unsigned short r_seqno; int rv; - for (;;) { - if ((rv = jtagmkII_recv_frame(pgm, msg, &r_seqno)) <= 0) + for(;;) { + if((rv = jtagmkII_recv_frame(pgm, msg, &r_seqno)) <= 0) return rv; - pmsg_debug("%s(): got message seqno %d (command_sequence == %d)\n", __func__, - r_seqno, PDATA(pgm)->command_sequence); - if (r_seqno == PDATA(pgm)->command_sequence) { - if (++(PDATA(pgm)->command_sequence) == 0xffff) - PDATA(pgm)->command_sequence = 0; + pmsg_debug("%s(): got message seqno %d (command_sequence == %d)\n", + __func__, r_seqno, my.command_sequence); + if(r_seqno == my.command_sequence) { + if(++(my.command_sequence) == 0xffff) + my.command_sequence = 0; /* - * We move the payload to the beginning of the buffer, to make - * the job easier for the caller. We have to return the - * original pointer though, as the caller must mmt_free() it. + * We move the payload to the beginning of the buffer, to make the job + * easier for the caller. We have to return the original pointer though, + * as the caller must mmt_free() it. */ memmove(*msg, *msg + 8, rv); @@ -607,19 +610,18 @@ int jtagmkII_recv(const PROGRAMMER *pgm, unsigned char **msg) { return rv; } - if (r_seqno == 0xffff) { + if(r_seqno == 0xffff) { pmsg_debug("%s(): got asynchronous event\n", __func__); } else { - pmsg_notice2("%s(): got wrong sequence number, %u != %u\n", __func__, - r_seqno, PDATA(pgm)->command_sequence); + pmsg_notice2("%s(): got wrong sequence number, %u != %u\n", __func__, r_seqno, my.command_sequence); } mmt_free(*msg); } } - int jtagmkII_getsync(const PROGRAMMER *pgm, int mode) { int tries; + #define MAXTRIES 10 unsigned char buf[3], *resp, c = 0xff; int status; @@ -628,146 +630,134 @@ int jtagmkII_getsync(const PROGRAMMER *pgm, int mode) { pmsg_debug("jtagmkII_getsync()\n"); - if (str_starts(pgm->type, "JTAG")) { + if(str_starts(pgm->type, "JTAG")) { is_dragon = 0; - } else if (str_starts(pgm->type, "DRAGON")) { + } else if(str_starts(pgm->type, "DRAGON")) { is_dragon = 1; } else { pmsg_error("programmer is neither JTAG ICE mkII nor AVR Dragon\n"); return -1; } - for (tries = 0; tries < MAXTRIES; tries++) { + for(tries = 0; tries < MAXTRIES; tries++) { - /* Get the sign-on information. */ + // Get the sign-on information buf[0] = CMND_GET_SIGN_ON; - pmsg_notice2("jtagmkII_getsync() attempt %d of %d: sending sign-on command: ", - tries + 1, MAXTRIES); + pmsg_notice2("jtagmkII_getsync() attempt %d of %d: sending sign-on command: ", tries + 1, MAXTRIES); jtagmkII_send(pgm, buf, 1); status = jtagmkII_recv(pgm, &resp); - if (status <= 0) { - pmsg_warning("attempt %d of %d: sign-on command: status %d\n", - tries + 1, MAXTRIES, status); - } else if (verbose >= MSG_DEBUG) { + if(status <= 0) { + pmsg_warning("attempt %d of %d: sign-on command: status %d\n", tries + 1, MAXTRIES, status); + } else if(verbose >= MSG_DEBUG) { msg_debug("\n"); jtagmkII_prmsg(pgm, resp, status); } else msg_notice2("0x%02x (%d bytes msg)\n", resp[0], status); - if (status > 0) { - if ((c = resp[0]) == RSP_SIGN_ON) { - fwver = ((unsigned)resp[8] << 8) | (unsigned)resp[7]; - PDATA(pgm)->fwver = fwver; - hwver = (unsigned)resp[9]; - memcpy(PDATA(pgm)->serno, resp + 10, 6); - if (status > 17) { - imsg_notice2("JTAG ICE mkII sign-on message:\n"); - imsg_notice2("Communications protocol version: %u\n", - (unsigned)resp[1]); - imsg_notice2("M_MCU:\n"); - imsg_notice2(" boot-loader FW version: %u\n", - (unsigned)resp[2]); - imsg_notice2(" firmware version: %u.%02u\n", - (unsigned)resp[4], (unsigned)resp[3]); - imsg_notice2(" hardware version: %u\n", - (unsigned)resp[5]); - imsg_notice2("S_MCU:\n"); - imsg_notice2(" boot-loader FW version: %u\n", - (unsigned)resp[6]); - imsg_notice2(" firmware version: %u.%02u\n", - (unsigned)resp[8], (unsigned)resp[7]); - imsg_notice2(" hardware version: %u\n", - (unsigned)resp[9]); - imsg_notice2("Serial number: " - "%02x:%02x:%02x:%02x:%02x:%02x\n", - PDATA(pgm)->serno[0], PDATA(pgm)->serno[1], PDATA(pgm)->serno[2], PDATA(pgm)->serno[3], PDATA(pgm)->serno[4], PDATA(pgm)->serno[5]); - resp[status - 1] = '\0'; - imsg_notice2("Device ID: %s\n", - resp + 16); - } - mmt_free(resp); - break; + if(status > 0) { + if((c = resp[0]) == RSP_SIGN_ON) { + fwver = ((unsigned) resp[8] << 8) | (unsigned) resp[7]; + my.fwver = fwver; + hwver = (unsigned) resp[9]; + memcpy(my.serno, resp + 10, 6); + if(status > 17) { + imsg_notice2("JTAG ICE mkII sign-on message:\n"); + imsg_notice2("Communications protocol version: %u\n", (unsigned) resp[1]); + imsg_notice2("M_MCU:\n"); + imsg_notice2(" boot-loader FW version: %u\n", (unsigned) resp[2]); + imsg_notice2(" firmware version: %u.%02u\n", (unsigned) resp[4], (unsigned) resp[3]); + imsg_notice2(" hardware version: %u\n", (unsigned) resp[5]); + imsg_notice2("S_MCU:\n"); + imsg_notice2(" boot-loader FW version: %u\n", (unsigned) resp[6]); + imsg_notice2(" firmware version: %u.%02u\n", (unsigned) resp[8], (unsigned) resp[7]); + imsg_notice2(" hardware version: %u\n", (unsigned) resp[9]); + imsg_notice2("Serial number: %02x:%02x:%02x:%02x:%02x:%02x\n", + my.serno[0], my.serno[1], my.serno[2], + my.serno[3], my.serno[4], my.serno[5]); + resp[status - 1] = '\0'; + imsg_notice2("Device ID: %s\n", resp + 16); + } + mmt_free(resp); + break; } mmt_free(resp); } } - if (tries >= MAXTRIES) { - if (status <= 0) + if(tries >= MAXTRIES) { + if(status <= 0) pmsg_error("timeout/error communicating with programmer (status %d)\n", status); else pmsg_error("bad response to sign-on command: %s\n", jtagmkII_get_rc(pgm, c)); return -1; } - PDATA(pgm)->device_descriptor_length = sizeof(struct device_descriptor); + my.device_descriptor_length = sizeof(struct device_descriptor); /* - * There's no official documentation from Atmel about what firmware - * revision matches what device descriptor length. The algorithm - * below has been found empirically. + * There's no official documentation from Atmel about what firmware revision + * matches what device descriptor length. The algorithm below has been found + * empirically. */ #define FWVER(maj, min) ((maj << 8) | (min)) - if (!is_dragon && fwver < FWVER(3, 16)) { - PDATA(pgm)->device_descriptor_length -= 2; + if(!is_dragon && fwver < FWVER(3, 16)) { + my.device_descriptor_length -= 2; pmsg_warning("S_MCU firmware version might be too old to work correctly\n"); - } else if (!is_dragon && fwver < FWVER(4, 0)) { - PDATA(pgm)->device_descriptor_length -= 2; - } - if (mode != EMULATOR_MODE_SPI) - pmsg_notice2("%s(): using a %u-byte device descriptor\n", __func__, - (unsigned) PDATA(pgm)->device_descriptor_length); - if (mode == EMULATOR_MODE_SPI) { - PDATA(pgm)->device_descriptor_length = 0; - if (!is_dragon && fwver < FWVER(4, 14)) { + } else if(!is_dragon && fwver < FWVER(4, 0)) { + my.device_descriptor_length -= 2; + } + if(mode != EMULATOR_MODE_SPI) + pmsg_notice2("%s(): using a %u-byte device descriptor\n", + __func__, (unsigned) my.device_descriptor_length); + if(mode == EMULATOR_MODE_SPI) { + my.device_descriptor_length = 0; + if(!is_dragon && fwver < FWVER(4, 14)) { pmsg_error("ISP functionality requires firmware version >= 4.14\n"); return -1; } } - if (mode == EMULATOR_MODE_PDI || mode == EMULATOR_MODE_JTAG_XMEGA) { - if (!is_dragon && mode == EMULATOR_MODE_PDI && hwver < 1) { + if(mode == EMULATOR_MODE_PDI || mode == EMULATOR_MODE_JTAG_XMEGA) { + if(!is_dragon && mode == EMULATOR_MODE_PDI && hwver < 1) { pmsg_error("Xmega PDI support requires hardware revision >= 1\n"); return -1; } - if (!is_dragon && fwver < FWVER(5, 37)) { + if(!is_dragon && fwver < FWVER(5, 37)) { pmsg_error("Xmega support requires firmware version >= 5.37\n"); return -1; } - if (is_dragon && fwver < FWVER(6, 11)) { + if(is_dragon && fwver < FWVER(6, 11)) { pmsg_error("Xmega support requires firmware version >= 6.11\n"); return -1; } } #undef FWVER - if(mode < 0) return 0; // for AVR32 + if(mode < 0) + return 0; // For AVR32 tries = 0; retry: - /* Turn the ICE into JTAG or ISP mode as requested. */ + // Turn the ICE into JTAG or ISP mode as requested buf[0] = mode; - if (jtagmkII_setparm(pgm, PAR_EMULATOR_MODE, buf) < 0) { - if (mode == EMULATOR_MODE_SPI) { + if(jtagmkII_setparm(pgm, PAR_EMULATOR_MODE, buf) < 0) { + if(mode == EMULATOR_MODE_SPI) { pmsg_warning("ISP activation failed, trying debugWire\n"); buf[0] = EMULATOR_MODE_DEBUGWIRE; - if (jtagmkII_setparm(pgm, PAR_EMULATOR_MODE, buf) < 0) - return -1; + if(jtagmkII_setparm(pgm, PAR_EMULATOR_MODE, buf) < 0) + return -1; else { - /* - * We are supposed to send a CMND_RESET with the - * MONCOM_DISABLE flag set right now, and then - * restart from scratch. - * - * As this will make the ICE sign off from USB, so - * we risk losing our USB connection, it's easier - * to instruct the user to restart AVRDUDE rather - * than trying to cope with all this inside the - * program. - */ - (void)jtagmkII_reset(pgm, 0x04); - if (tries++ > 3) { - pmsg_error("unable to return from debugWIRE to ISP\n"); - return -1; - } - pmsg_warning("target prepared for ISP, signed off\n"); + /* + * We are supposed to send a CMND_RESET with the MONCOM_DISABLE flag + * set right now, and then restart from scratch. + * + * As this will make the ICE sign off from USB, so we risk losing our + * USB connection, it's easier to instruct the user to restart AVRDUDE + * rather than trying to cope with all this inside the program. + */ + (void) jtagmkII_reset(pgm, 0x04); + if(tries++ > 3) { + pmsg_error("unable to return from debugWIRE to ISP\n"); + return -1; + } + pmsg_warning("target prepared for ISP, signed off\n"); imsg_warning("now retrying without power-cycling the target\n"); goto retry; } @@ -776,25 +766,25 @@ int jtagmkII_getsync(const PROGRAMMER *pgm, int mode) { } } - /* GET SYNC forces the target into STOPPED mode */ + // GET_SYNC forces the target into STOPPED mode buf[0] = CMND_GET_SYNC; pmsg_notice2("%s(): sending get sync command: ", __func__); jtagmkII_send(pgm, buf, 1); status = jtagmkII_recv(pgm, &resp); - if (status <= 0) { + if(status <= 0) { msg_notice2("\n"); pmsg_error("timeout/error communicating with programmer (status %d)\n", status); return -1; } - if (verbose >= MSG_DEBUG) { + if(verbose >= MSG_DEBUG) { msg_debug("\n"); jtagmkII_prmsg(pgm, resp, status); } else msg_notice2("0x%02x (%d bytes msg)\n", resp[0], status); c = resp[0]; mmt_free(resp); - if (c != RSP_OK) { + if(c != RSP_OK) { pmsg_error("bad response to set parameter command: %s\n", jtagmkII_get_rc(pgm, c)); return -1; } @@ -802,54 +792,49 @@ int jtagmkII_getsync(const PROGRAMMER *pgm, int mode) { return 0; } -/* - * issue the 'chip erase' command to the AVR device - */ +// Issue the 'chip erase' command to the AVR device static int jtagmkII_chip_erase(const PROGRAMMER *pgm, const AVRPART *p) { int status, len; unsigned char buf[6], *resp, c; - if (p->prog_modes & (PM_PDI | PM_UPDI)) { + if(p->prog_modes & (PM_PDI | PM_UPDI)) { buf[0] = CMND_XMEGA_ERASE; buf[1] = XMEGA_ERASE_CHIP; - memset(buf + 2, 0, 4); /* address of area to be erased */ + memset(buf + 2, 0, 4); // Address of area to be erased len = 6; } else { buf[0] = CMND_CHIP_ERASE; len = 1; } - pmsg_notice2("%s(): sending %schip erase command: ", __func__, - p->prog_modes & (PM_PDI | PM_UPDI)? "Xmega ": ""); + pmsg_notice2("%s(): sending %schip erase command: ", __func__, p->prog_modes & (PM_PDI | PM_UPDI)? "Xmega ": ""); jtagmkII_send(pgm, buf, len); status = jtagmkII_recv(pgm, &resp); - if (status <= 0) { + if(status <= 0) { msg_notice2("\n"); pmsg_error("timeout/error communicating with programmer (status %d)\n", status); return -1; } - if (verbose >= MSG_DEBUG) { + if(verbose >= MSG_DEBUG) { msg_debug("\n"); jtagmkII_prmsg(pgm, resp, status); } else msg_notice2("0x%02x (%d bytes msg)\n", resp[0], status); c = resp[0]; mmt_free(resp); - if (c != RSP_OK) { + if(c != RSP_OK) { pmsg_error("bad response to chip erase command: %s\n", jtagmkII_get_rc(pgm, c)); return -1; } - if (p->prog_modes & PM_Classic) - pgm->initialize(pgm, p); + if(is_classic(p)) + pgm->initialize(pgm, p); - PDATA(pgm)->recently_written = 1; + my.recently_written = 1; return 0; } -/* - * There is no chip erase functionality in debugWire mode. - */ +// There is no chip erase functionality in debugWire mode static int jtagmkII_chip_erase_dw(const PROGRAMMER *pgm_unused, const AVRPART *p_unused) { pmsg_info("chip erase not supported in debugWire mode\n"); @@ -873,53 +858,51 @@ static void jtagmkII_set_devdescr(const PROGRAMMER *pgm, const AVRPART *p) { sendbuf.dd.ucIDRAddress = p->idr; if((flm = avr_locate_flash(p)) && p->boot_section_size > 0) { unsigned int sbls = (flm->size - p->boot_section_size)/2; // Words + sendbuf.dd.uiStartSmallestBootLoaderSection[0] = sbls; - sendbuf.dd.uiStartSmallestBootLoaderSection[1] = sbls>>8; - } - u16_to_b2(sendbuf.dd.EECRAddress, p->eecr? p->eecr: 0x3f); // Unset eecr means 0x3f - sendbuf.dd.ucAllowFullPageBitstream = - (p->flags & AVRPART_ALLOWFULLPAGEBITSTREAM) != 0; - sendbuf.dd.EnablePageProgramming = - (p->flags & AVRPART_ENABLEPAGEPROGRAMMING) != 0; - for (ln = lfirst(p->mem); ln; ln = lnext(ln)) { + sendbuf.dd.uiStartSmallestBootLoaderSection[1] = sbls >> 8; + } + u16_to_b2(sendbuf.dd.EECRAddress, p->eecr? p->eecr: 0x3f); // Unset eecr means 0x3f + sendbuf.dd.ucAllowFullPageBitstream = (p->flags & AVRPART_ALLOWFULLPAGEBITSTREAM) != 0; + sendbuf.dd.EnablePageProgramming = (p->flags & AVRPART_ENABLEPAGEPROGRAMMING) != 0; + for(ln = lfirst(p->mem); ln; ln = lnext(ln)) { AVRMEM *m = ldata(ln); - if (mem_is_flash(m)) { - if (m->page_size > 256) - PDATA(pgm)->flash_pagesize = 256; + + if(mem_is_flash(m)) { + if(m->page_size > 256) + my.flash_pagesize = 256; else - PDATA(pgm)->flash_pagesize = m->page_size; + my.flash_pagesize = m->page_size; u32_to_b4(sendbuf.dd.ulFlashSize, m->size); u16_to_b2(sendbuf.dd.uiFlashPageSize, m->page_size); - u16_to_b2(sendbuf.dd.uiFlashpages, m->size / m->page_size); - if (p->prog_modes & PM_debugWIRE) { - memcpy(sendbuf.dd.ucFlashInst, p->flash_instr, FLASH_INSTR_SIZE); - memcpy(sendbuf.dd.ucEepromInst, p->eeprom_instr, EEPROM_INSTR_SIZE); + u16_to_b2(sendbuf.dd.uiFlashpages, m->size/m->page_size); + if(is_debugwire(p)) { + memcpy(sendbuf.dd.ucFlashInst, p->flash_instr, FLASH_INSTR_SIZE); + memcpy(sendbuf.dd.ucEepromInst, p->eeprom_instr, EEPROM_INSTR_SIZE); } - } else if (mem_is_eeprom(m)) { - sendbuf.dd.ucEepromPageSize = PDATA(pgm)->eeprom_pagesize = m->page_size; + } else if(mem_is_eeprom(m)) { + sendbuf.dd.ucEepromPageSize = my.eeprom_pagesize = m->page_size; } } - sendbuf.dd.ucCacheType = - p->prog_modes & (PM_PDI | PM_UPDI)? 0x02: 0x00; + sendbuf.dd.ucCacheType = p->prog_modes & (PM_PDI | PM_UPDI)? 0x02: 0x00; pmsg_notice2("%s(): sending set device descriptor command: ", __func__); - jtagmkII_send(pgm, (unsigned char *)&sendbuf, - PDATA(pgm)->device_descriptor_length + sizeof(unsigned char)); + jtagmkII_send(pgm, (unsigned char *) &sendbuf, my.device_descriptor_length + sizeof(unsigned char)); status = jtagmkII_recv(pgm, &resp); - if (status <= 0) { + if(status <= 0) { msg_notice2("\n"); pmsg_error("timeout/error communicating with programmer (status %d)\n", status); return; } - if (verbose >= MSG_DEBUG) { + if(verbose >= MSG_DEBUG) { msg_debug("\n"); jtagmkII_prmsg(pgm, resp, status); } else msg_notice2("0x%02x (%d bytes msg)\n", resp[0], status); c = resp[0]; mmt_free(resp); - if (c != RSP_OK) { + if(c != RSP_OK) { pmsg_error("bad response to set device descriptor command: %s\n", jtagmkII_get_rc(pgm, c)); } } @@ -928,7 +911,7 @@ static void jtagmkII_set_xmega_params(const PROGRAMMER *pgm, const AVRPART *p) { int status, fuseinit = 0; unsigned char *resp, c; LNODEID ln; - AVRMEM * m; + AVRMEM *m; struct { unsigned char cmd; struct xmega_device_desc dd; @@ -941,31 +924,31 @@ static void jtagmkII_set_xmega_params(const PROGRAMMER *pgm, const AVRPART *p) { u16_to_b2(sendbuf.dd.nvm_base_addr, p->nvm_base); u16_to_b2(sendbuf.dd.mcu_base_addr, p->mcu_base); - for (ln = lfirst(p->mem); ln; ln = lnext(ln)) { + for(ln = lfirst(p->mem); ln; ln = lnext(ln)) { m = ldata(ln); - if (mem_is_flash(m)) { - if (m->page_size > 256) - PDATA(pgm)->flash_pagesize = 256; + if(mem_is_flash(m)) { + if(m->page_size > 256) + my.flash_pagesize = 256; else - PDATA(pgm)->flash_pagesize = m->page_size; + my.flash_pagesize = m->page_size; u16_to_b2(sendbuf.dd.flash_page_size, m->page_size); - } else if (mem_is_eeprom(m)) { + } else if(mem_is_eeprom(m)) { sendbuf.dd.eeprom_page_size = m->page_size; u16_to_b2(sendbuf.dd.eeprom_size, m->size); u32_to_b4(sendbuf.dd.nvm_eeprom_offset, m->offset); - } else if (mem_is_application(m)) { + } else if(mem_is_application(m)) { u32_to_b4(sendbuf.dd.app_size, m->size); u32_to_b4(sendbuf.dd.nvm_app_offset, m->offset); - } else if (mem_is_boot(m)) { + } else if(mem_is_boot(m)) { u16_to_b2(sendbuf.dd.boot_size, m->size); u32_to_b4(sendbuf.dd.nvm_boot_offset, m->offset); - } else if(mem_is_a_fuse(m) && !fuseinit++) { // Any fuse is OK + } else if(mem_is_a_fuse(m) && !fuseinit++) { // Any fuse is OK u32_to_b4(sendbuf.dd.nvm_fuse_offset, m->offset & ~15); - } else if (mem_is_lock(m)) { + } else if(mem_is_lock(m)) { u32_to_b4(sendbuf.dd.nvm_lock_offset, m->offset); - } else if (mem_is_userrow(m)) { + } else if(mem_is_userrow(m)) { u32_to_b4(sendbuf.dd.nvm_user_sig_offset, m->offset); - } else if (mem_is_sigrow(m)) { + } else if(mem_is_sigrow(m)) { u32_to_b4(sendbuf.dd.nvm_prod_sig_offset, m->offset); pmsg_notice2("prod_sig_offset addr 0x%05x\n", m->offset); } @@ -974,63 +957,60 @@ static void jtagmkII_set_xmega_params(const PROGRAMMER *pgm, const AVRPART *p) { u32_to_b4(sendbuf.dd.nvm_data_offset, DATA_OFFSET); pmsg_notice2("%s() sending set Xmega params command: ", __func__); - jtagmkII_send(pgm, (unsigned char *)&sendbuf, sizeof sendbuf); + jtagmkII_send(pgm, (unsigned char *) &sendbuf, sizeof sendbuf); status = jtagmkII_recv(pgm, &resp); - if (status <= 0) { + if(status <= 0) { msg_notice2("\n"); pmsg_error("timeout/error communicating with programmer (status %d)\n", status); return; } - if (verbose >= MSG_DEBUG) { + if(verbose >= MSG_DEBUG) { msg_debug("\n"); jtagmkII_prmsg(pgm, resp, status); } else msg_notice2("0x%02x (%d bytes msg)\n", resp[0], status); c = resp[0]; mmt_free(resp); - if (c != RSP_OK) { + if(c != RSP_OK) { pmsg_error("bad response to set device descriptor command: %s\n", jtagmkII_get_rc(pgm, c)); } } -/* - * Reset the target. - */ +// Reset the target static int jtagmkII_reset(const PROGRAMMER *pgm, unsigned char flags) { int status; unsigned char buf[2], *resp, c; /* - * In debugWire mode, don't reset. Do a forced stop, and tell the - * ICE to stop any timers, too. + * In debugWire mode, don't reset. Do a forced stop, and tell the ICE to + * stop any timers, too. */ - if (pgm->flag & PGM_FL_IS_DW) { + if(pgm->flag & PGM_FL_IS_DW) { unsigned char parm[] = { 0 }; - (void)jtagmkII_setparm(pgm, PAR_TIMERS_RUNNING, parm); + (void) jtagmkII_setparm(pgm, PAR_TIMERS_RUNNING, parm); } buf[0] = (pgm->flag & PGM_FL_IS_DW)? CMND_FORCED_STOP: CMND_RESET; buf[1] = (pgm->flag & PGM_FL_IS_DW)? 1: flags; - pmsg_notice2("%s(): sending %s command: ", __func__, - (pgm->flag & PGM_FL_IS_DW)? "stop": "reset"); + pmsg_notice2("%s(): sending %s command: ", __func__, (pgm->flag & PGM_FL_IS_DW)? "stop": "reset"); jtagmkII_send(pgm, buf, 2); status = jtagmkII_recv(pgm, &resp); - if (status <= 0) { + if(status <= 0) { msg_notice2("\n"); pmsg_error("timeout/error communicating with programmer (status %d)\n", status); return -1; } - if (verbose >= MSG_DEBUG) { + if(verbose >= MSG_DEBUG) { msg_debug("\n"); jtagmkII_prmsg(pgm, resp, status); } else msg_notice2("0x%02x (%d bytes msg)\n", resp[0], status); c = resp[0]; mmt_free(resp); - if (c != RSP_OK) { + if(c != RSP_OK) { pmsg_error("bad response to reset command: %s\n", jtagmkII_get_rc(pgm, c)); return -1; } @@ -1047,45 +1027,45 @@ static int jtagmkII_program_enable(const PROGRAMMER *pgm) { unsigned char buf[1], *resp, c; int use_ext_reset; - if (PDATA(pgm)->prog_enabled) + if(my.prog_enabled) return 0; - for (use_ext_reset = 0; use_ext_reset <= 1; use_ext_reset++) { + for(use_ext_reset = 0; use_ext_reset <= 1; use_ext_reset++) { buf[0] = CMND_ENTER_PROGMODE; pmsg_notice2("%s(): sending enter progmode command: ", __func__); jtagmkII_send(pgm, buf, 1); status = jtagmkII_recv(pgm, &resp); - if (status <= 0) { + if(status <= 0) { msg_notice2("\n"); pmsg_error("timeout/error communicating with programmer (status %d)\n", status); return -1; } - if (verbose >= MSG_DEBUG) { + if(verbose >= MSG_DEBUG) { msg_debug("\n"); jtagmkII_prmsg(pgm, resp, status); } else msg_notice2("0x%02x (%d bytes msg)\n", resp[0], status); c = resp[0]; mmt_free(resp); - if (c != RSP_OK) { + if(c != RSP_OK) { pmsg_warning("bad response to enter progmode command: %s\n", jtagmkII_get_rc(pgm, c)); - if (c == RSP_ILLEGAL_JTAG_ID) { - if (use_ext_reset == 0) { - unsigned char parm[] = { 1}; + if(c == RSP_ILLEGAL_JTAG_ID) { + if(use_ext_reset == 0) { + unsigned char parm[] = { 1 }; pmsg_warning("retrying with external reset applied\n"); - (void)jtagmkII_setparm(pgm, PAR_EXTERNAL_RESET, parm); - continue; - } + (void) jtagmkII_setparm(pgm, PAR_EXTERNAL_RESET, parm); + continue; + } - pmsg_error("JTAGEN fuse disabled?\n"); - return -1; + pmsg_error("JTAGEN fuse disabled?\n"); + return -1; } } } - PDATA(pgm)->prog_enabled = 1; + my.prog_enabled = 1; return 0; } @@ -1093,7 +1073,7 @@ static int jtagmkII_program_disable(const PROGRAMMER *pgm) { int status; unsigned char buf[1], *resp, c; - if (!PDATA(pgm)->prog_enabled) + if(!my.prog_enabled) return 0; buf[0] = CMND_LEAVE_PROGMODE; @@ -1101,26 +1081,26 @@ static int jtagmkII_program_disable(const PROGRAMMER *pgm) { jtagmkII_send(pgm, buf, 1); status = jtagmkII_recv(pgm, &resp); - if (status <= 0) { + if(status <= 0) { msg_notice2("\n"); pmsg_error("timeout/error communicating with programmer (status %d)\n", status); return -1; } - if (verbose >= MSG_DEBUG) { + if(verbose >= MSG_DEBUG) { msg_debug("\n"); jtagmkII_prmsg(pgm, resp, status); } else msg_notice2("0x%02x (%d bytes msg)\n", resp[0], status); c = resp[0]; mmt_free(resp); - if (c != RSP_OK) { + if(c != RSP_OK) { pmsg_error("bad response to leave progmode command: %s\n", jtagmkII_get_rc(pgm, c)); return -1; } - PDATA(pgm)->recently_written = 0; - PDATA(pgm)->prog_enabled = 0; - (void)jtagmkII_reset(pgm, 0x01); + my.recently_written = 0; + my.prog_enabled = 0; + (void) jtagmkII_reset(pgm, 0x01); return 0; } @@ -1164,102 +1144,96 @@ static unsigned char jtagmkII_get_baud(long baud) { BR(3000000), }; - for (size_t i = 0; i < sizeof baudtab/sizeof*baudtab; i++) - if (baud == baudtab[i].baud) + for(size_t i = 0; i < sizeof baudtab/sizeof *baudtab; i++) + if(baud == baudtab[i].baud) return baudtab[i].val; return 0; } -/* - * initialize the AVR device and prepare it to accept commands - */ +// Initialize the AVR device and prepare it to accept commands static int jtagmkII_initialize(const PROGRAMMER *pgm, const AVRPART *p) { unsigned char b; int ok; const char *ifname; - if (PDATA(pgm)->rts_mode != RTS_MODE_DEFAULT) { - pmsg_notice("forcing serial DTR/RTS handshake lines %s\n", - PDATA(pgm)->rts_mode == RTS_MODE_LOW ? "LOW" : "HIGH"); + if(my.rts_mode != RTS_MODE_DEFAULT) { + pmsg_notice("forcing serial DTR/RTS handshake lines %s\n", my.rts_mode == RTS_MODE_LOW? "LOW": "HIGH"); } - /* Abort and print error if programmer does not support the target microcontroller */ - if((str_starts(pgm->type, "JTAGMKII_UPDI") && !(p->prog_modes & PM_UPDI)) || - (str_starts(pgmid, "jtagmkII") && (p->prog_modes & PM_UPDI))) { + // Abort and print error if programmer does not support the target microcontroller + if((str_starts(pgm->type, "JTAGMKII_UPDI") && !is_updi(p)) || + (str_starts(pgmid, "jtagmkII") && is_updi(p))) { msg_error("programmer %s does not support target %s\n\n", pgmid, p->desc); return -1; } ok = 0; - if (pgm->flag & PGM_FL_IS_DW) { + if(pgm->flag & PGM_FL_IS_DW) { ifname = "debugWire"; - if (p->prog_modes & PM_debugWIRE) + if(is_debugwire(p)) ok = 1; - } else if (pgm->flag & PGM_FL_IS_PDI) { + } else if(pgm->flag & PGM_FL_IS_PDI) { ifname = "PDI"; - if (p->prog_modes & (PM_PDI | PM_UPDI)) + if(p->prog_modes & (PM_PDI | PM_UPDI)) ok = 1; } else { ifname = "JTAG"; - if (p->prog_modes & (PM_JTAG | PM_JTAGmkI | PM_XMEGAJTAG | PM_AVR32JTAG)) + if(p->prog_modes & (PM_JTAG | PM_JTAGmkI | PM_XMEGAJTAG | PM_AVR32JTAG)) ok = 1; } - if (!ok) { + if(!ok) { pmsg_error("part %s has no %s interface\n", p->desc, ifname); return -1; } - if ((serdev->flags & SERDEV_FL_CANSETSPEED) && pgm->baudrate && pgm->baudrate != 19200) { - if ((b = jtagmkII_get_baud(pgm->baudrate)) == 0) { + if((serdev->flags & SERDEV_FL_CANSETSPEED) && pgm->baudrate && pgm->baudrate != 19200) { + if((b = jtagmkII_get_baud(pgm->baudrate)) == 0) { pmsg_error("unsupported baudrate %d\n", pgm->baudrate); } else { pmsg_notice2("%s(): trying to set baudrate to %d\n", __func__, pgm->baudrate); - if (jtagmkII_setparm(pgm, PAR_BAUD_RATE, &b) == 0) - serial_setparams(&pgm->fd, pgm->baudrate, SERIAL_8N1); + if(jtagmkII_setparm(pgm, PAR_BAUD_RATE, &b) == 0) + serial_setparams(&pgm->fd, pgm->baudrate, SERIAL_8N1); } } - if ((pgm->flag & PGM_FL_IS_JTAG) && pgm->bitclock != 0.0) { + if((pgm->flag & PGM_FL_IS_JTAG) && pgm->bitclock != 0.0) { pmsg_notice2("%s(): trying to set JTAG clock period to %.1f us\n", __func__, pgm->bitclock); - if (jtagmkII_set_sck_period(pgm, pgm->bitclock) != 0) + if(jtagmkII_set_sck_period(pgm, pgm->bitclock) != 0) return -1; } - if ((pgm->flag & PGM_FL_IS_JTAG) && - jtagmkII_setparm(pgm, PAR_DAISY_CHAIN_INFO, PDATA(pgm)->jtagchain) < 0) { + if((pgm->flag & PGM_FL_IS_JTAG) && jtagmkII_setparm(pgm, PAR_DAISY_CHAIN_INFO, my.jtagchain) < 0) { pmsg_error("unable to setup JTAG chain\n"); return -1; } /* - * If this is an ATxmega device in JTAG mode, change the emulator - * mode from JTAG to JTAG_XMEGA. + * If this is an ATxmega device in JTAG mode, change the emulator mode from + * JTAG to JTAG_XMEGA. */ - if ((pgm->flag & PGM_FL_IS_JTAG) && - (p->prog_modes & (PM_PDI | PM_UPDI))) { - if (jtagmkII_getsync(pgm, EMULATOR_MODE_JTAG_XMEGA) < 0) + if((pgm->flag & PGM_FL_IS_JTAG) && (p->prog_modes & (PM_PDI | PM_UPDI))) { + if(jtagmkII_getsync(pgm, EMULATOR_MODE_JTAG_XMEGA) < 0) return -1; } - /* - * Must set the device descriptor before entering programming mode. - */ - if (PDATA(pgm)->fwver >= 0x700 && (p->prog_modes & (PM_PDI | PM_UPDI)) != 0) + // Must set the device descriptor before entering programming mode + if(my.fwver >= 0x700 && (p->prog_modes & (PM_PDI | PM_UPDI)) != 0) jtagmkII_set_xmega_params(pgm, p); else jtagmkII_set_devdescr(pgm, p); - PDATA(pgm)->boot_start = ULONG_MAX; - if ((p->prog_modes & (PM_PDI | PM_UPDI))) { + my.boot_start = ULONG_MAX; + if((p->prog_modes & (PM_PDI | PM_UPDI))) { // Find the border between application and boot area AVRMEM *bootmem = avr_locate_boot(p); AVRMEM *flashmem = avr_locate_flash(p); - if (bootmem == NULL || flashmem == NULL) { + + if(bootmem == NULL || flashmem == NULL) { if(str_starts(pgmid, "jtagmkII")) pmsg_error("cannot locate flash or boot memories in description\n"); } else { - if (PDATA(pgm)->fwver < 0x700) { - /* V7+ firmware does not need this anymore */ + if(my.fwver < 0x700) { + // V7+ firmware does not need this anymore unsigned char par[4]; u32_to_b4(par, flashmem->offset); @@ -1268,41 +1242,42 @@ static int jtagmkII_initialize(const PROGRAMMER *pgm, const AVRPART *p) { (void) jtagmkII_setparm(pgm, PAR_PDI_OFFSET_END, par); } - PDATA(pgm)->boot_start = bootmem->offset - flashmem->offset; + my.boot_start = bootmem->offset - flashmem->offset; } } - mmt_free(PDATA(pgm)->flash_pagecache); - mmt_free(PDATA(pgm)->eeprom_pagecache); - PDATA(pgm)->flash_pagecache = mmt_malloc(PDATA(pgm)->flash_pagesize); - PDATA(pgm)->eeprom_pagecache = mmt_malloc(PDATA(pgm)->eeprom_pagesize); - PDATA(pgm)->flash_pageaddr = PDATA(pgm)->eeprom_pageaddr = ~0UL; + mmt_free(my.flash_pagecache); + mmt_free(my.eeprom_pagecache); + my.flash_pagecache = mmt_malloc(my.flash_pagesize); + my.eeprom_pagecache = mmt_malloc(my.eeprom_pagesize); + my.flash_pageaddr = my.eeprom_pageaddr = ~0UL; - if (PDATA(pgm)->fwver >= 0x700 && (p->prog_modes & (PM_PDI | PM_UPDI))) { + if(my.fwver >= 0x700 && (p->prog_modes & (PM_PDI | PM_UPDI))) { /* * Work around for * https://savannah.nongnu.org/bugs/index.php?37942 * - * Firmware version 7.24 (at least) on the Dragon behaves very - * strange when it gets a RESET request here. All subsequent - * responses are completely off, so the emulator becomes unusable. - * This appears to be a firmware bug (earlier versions, at least - * 7.14, didn't experience this), but by omitting the RESET for - * Xmega devices, we can work around it. + * Firmware version 7.24 (at least) on the Dragon behaves very strange when + * it gets a RESET request here. All subsequent responses are completely + * off, so the emulator becomes unusable. This appears to be a firmware bug + * (earlier versions, at least 7.14, didn't experience this), but by + * omitting the RESET for Xmega devices, we can work around it. */ } else { - if (jtagmkII_reset(pgm, 0x01) < 0) + if(jtagmkII_reset(pgm, 0x01) < 0) return -1; } - if ((pgm->flag & PGM_FL_IS_JTAG) && (p->prog_modes & PM_Classic)) { + if((pgm->flag & PGM_FL_IS_JTAG) && is_classic(p)) { int ocden = 0; + if(avr_get_config_value(pgm, p, "ocden", &ocden) == 0 && ocden) // ocden == 1 means disabled pmsg_warning("OCDEN fuse not programmed, single-byte EEPROM updates not possible\n"); } - if (pgm->read_chip_rev && p->prog_modes & (PM_PDI | PM_UPDI)) { + if(pgm->read_chip_rev && p->prog_modes & (PM_PDI | PM_UPDI)) { unsigned char chip_rev[AVR_CHIP_REVLEN]; + pgm->read_chip_rev(pgm, p, chip_rev); pmsg_notice("silicon revision: %x.%x\n", chip_rev[0] >> 4, chip_rev[0] & 0x0f); } @@ -1311,22 +1286,21 @@ static int jtagmkII_initialize(const PROGRAMMER *pgm, const AVRPART *p) { } static void jtagmkII_disable(const PROGRAMMER *pgm) { - mmt_free(PDATA(pgm)->flash_pagecache); - PDATA(pgm)->flash_pagecache = NULL; - mmt_free(PDATA(pgm)->eeprom_pagecache); - PDATA(pgm)->eeprom_pagecache = NULL; + mmt_free(my.flash_pagecache); + my.flash_pagecache = NULL; + mmt_free(my.eeprom_pagecache); + my.eeprom_pagecache = NULL; /* - * jtagmkII_program_disable() doesn't do anything if the - * device is currently not in programming mode, so just - * call it unconditionally here. + * jtagmkII_program_disable() doesn't do anything if the device is currently + * not in programming mode, so just call it unconditionally here. */ - (void)jtagmkII_program_disable(pgm); + (void) jtagmkII_program_disable(pgm); } static void jtagmkII_enable(PROGRAMMER *pgm, const AVRPART *p) { // Page erase only useful for classic parts with usersig mem or AVR8X/XMEGAs - if(p->prog_modes & PM_Classic) + if(is_classic(p)) if(!avr_locate_usersig(p)) pgm->page_erase = NULL; @@ -1340,35 +1314,36 @@ static int jtagmkII_parseextparms(const PROGRAMMER *pgm, const LISTID extparms) int rv = 0; bool help = false; - for (LNODEID ln = lfirst(extparms); ln; ln = lnext(ln)) { + for(LNODEID ln = lfirst(extparms); ln; ln = lnext(ln)) { const char *extended_param = ldata(ln); - if (pgm->flag & PGM_FL_IS_JTAG) { - if (str_starts(extended_param, "jtagchain=")) { + if(pgm->flag & PGM_FL_IS_JTAG) { + if(str_starts(extended_param, "jtagchain=")) { unsigned int ub, ua, bb, ba; - if (sscanf(extended_param, "jtagchain=%u,%u,%u,%u", &ub, &ua, &bb, &ba) != 4) { + + if(sscanf(extended_param, "jtagchain=%u,%u,%u,%u", &ub, &ua, &bb, &ba) != 4) { pmsg_error("invalid JTAG chain in -x %s\n", extended_param); rv = -1; continue; } pmsg_notice2("%s(): JTAG chain parsed as:\n", __func__); - imsg_notice2("%u units before, %u units after, %u bits before, %u bits after\n", - ub, ua, bb, ba); - PDATA(pgm)->jtagchain[0] = ub; - PDATA(pgm)->jtagchain[1] = ua; - PDATA(pgm)->jtagchain[2] = bb; - PDATA(pgm)->jtagchain[3] = ba; + imsg_notice2("%u units before, %u units after, %u bits before, %u bits after\n", ub, ua, bb, ba); + my.jtagchain[0] = ub; + my.jtagchain[1] = ua; + my.jtagchain[2] = bb; + my.jtagchain[3] = ba; continue; } } - if (pgm->flag & PGM_FL_IS_PDI) { + if(pgm->flag & PGM_FL_IS_PDI) { char rts_mode[5]; - if (sscanf(extended_param, "rtsdtr=%4s", rts_mode) == 1) { - if (str_caseeq(rts_mode, "low")) { - PDATA(pgm)->rts_mode = RTS_MODE_LOW; - } else if (str_caseeq(rts_mode, "high")) { - PDATA(pgm)->rts_mode = RTS_MODE_HIGH; + + if(sscanf(extended_param, "rtsdtr=%4s", rts_mode) == 1) { + if(str_caseeq(rts_mode, "low")) { + my.rts_mode = RTS_MODE_LOW; + } else if(str_caseeq(rts_mode, "high")) { + my.rts_mode = RTS_MODE_HIGH; } else { pmsg_error("RTS/DTR mode must be LOW or HIGH\n"); rv = -1; @@ -1378,28 +1353,27 @@ static int jtagmkII_parseextparms(const PROGRAMMER *pgm, const LISTID extparms) } } - if (str_eq(extended_param, "help")) { + if(str_eq(extended_param, "help")) { help = true; rv = LIBAVRDUDE_EXIT; } - if (!help) { + if(!help) { pmsg_error("invalid extended parameter -x %s\n", extended_param); rv = -1; } msg_error("%s -c %s extended options:\n", progname, pgmid); - if (pgm->flag & PGM_FL_IS_JTAG) + if(pgm->flag & PGM_FL_IS_JTAG) msg_error(" -x jtagchain=UB,UA,BB,BA Setup the JTAG scan chain order\n"); - if (pgm->flag & PGM_FL_IS_PDI) + if(pgm->flag & PGM_FL_IS_PDI) msg_error(" -x rtsdtr=low,high Force RTS/DTR lines low or high state during programming\n"); - msg_error( " -x help Show this help menu and exit\n"); + msg_error(" -x help Show this help menu and exit\n"); return rv; } return rv; } - static int jtagmkII_open(PROGRAMMER *pgm, const char *port) { union pinfo pinfo; @@ -1407,20 +1381,20 @@ static int jtagmkII_open(PROGRAMMER *pgm, const char *port) { /* * The JTAG ICE mkII always starts with a baud rate of 19200 Bd upon - * attaching. If the config file or command-line parameters specify - * a higher baud rate, we switch to it later on, after establishing - * the connection with the ICE. + * attaching. If the config file or command-line parameters specify a higher + * baud rate, we switch to it later on, after establishing the connection + * with the ICE. */ pinfo.serialinfo.baud = 19200; pinfo.serialinfo.cflags = SERIAL_8N1; /* - * If the port name starts with "usb", divert the serial routines - * to the USB ones. The serial_open() function for USB overrides - * the meaning of the "baud" parameter to be the USB device ID to - * search for. + * If the port name starts with "usb", divert the serial routines to the USB + * ones. The serial_open() function for USB overrides the meaning of the + * "baud" parameter to be the USB device ID to search for. */ - if (str_starts(port, "usb")) { + if(str_starts(port, "usb")) { + #if defined(HAVE_LIBUSB) serdev = &usb_serdev; pinfo.usbinfo.vid = USB_VENDOR_ATMEL; @@ -1429,7 +1403,7 @@ static int jtagmkII_open(PROGRAMMER *pgm, const char *port) { pgm->fd.usb.max_xfer = USBDEV_MAX_XFER_MKII; pgm->fd.usb.rep = USBDEV_BULK_EP_READ_MKII; pgm->fd.usb.wep = USBDEV_BULK_EP_WRITE_MKII; - pgm->fd.usb.eep = 0; /* no seperate EP for events */ + pgm->fd.usb.eep = 0; // No seperate EP for events #else msg_error("avrdude was compiled without usb support\n"); return -1; @@ -1437,16 +1411,14 @@ static int jtagmkII_open(PROGRAMMER *pgm, const char *port) { } pgm->port = port; - if (serial_open(port, pinfo, &pgm->fd)==-1) { + if(serial_open(port, pinfo, &pgm->fd) == -1) { return -1; } - /* - * drain any extraneous input - */ + // Drain any extraneous input jtagmkII_drain(pgm, 0); - if (jtagmkII_getsync(pgm, EMULATOR_MODE_JTAG) < 0) + if(jtagmkII_getsync(pgm, EMULATOR_MODE_JTAG) < 0) return -1; return 0; @@ -1459,20 +1431,20 @@ static int jtagmkII_open_dw(PROGRAMMER *pgm, const char *port) { /* * The JTAG ICE mkII always starts with a baud rate of 19200 Bd upon - * attaching. If the config file or command-line parameters specify - * a higher baud rate, we switch to it later on, after establishing - * the connection with the ICE. + * attaching. If the config file or command-line parameters specify a higher + * baud rate, we switch to it later on, after establishing the connection + * with the ICE. */ pinfo.serialinfo.baud = 19200; pinfo.serialinfo.cflags = SERIAL_8N1; /* - * If the port name starts with "usb", divert the serial routines - * to the USB ones. The serial_open() function for USB overrides - * the meaning of the "baud" parameter to be the USB device ID to - * search for. + * If the port name starts with "usb", divert the serial routines to the USB + * ones. The serial_open() function for USB overrides the meaning of the + * "baud" parameter to be the USB device ID to search for. */ - if (str_starts(port, "usb")) { + if(str_starts(port, "usb")) { + #if defined(HAVE_LIBUSB) serdev = &usb_serdev; pinfo.usbinfo.vid = USB_VENDOR_ATMEL; @@ -1481,7 +1453,7 @@ static int jtagmkII_open_dw(PROGRAMMER *pgm, const char *port) { pgm->fd.usb.max_xfer = USBDEV_MAX_XFER_MKII; pgm->fd.usb.rep = USBDEV_BULK_EP_READ_MKII; pgm->fd.usb.wep = USBDEV_BULK_EP_WRITE_MKII; - pgm->fd.usb.eep = 0; /* no seperate EP for events */ + pgm->fd.usb.eep = 0; // No seperate EP for events #else msg_error("avrdude was compiled without usb support\n"); return -1; @@ -1489,16 +1461,14 @@ static int jtagmkII_open_dw(PROGRAMMER *pgm, const char *port) { } pgm->port = port; - if (serial_open(port, pinfo, &pgm->fd)==-1) { + if(serial_open(port, pinfo, &pgm->fd) == -1) { return -1; } - /* - * drain any extraneous input - */ + // Drain any extraneous input jtagmkII_drain(pgm, 0); - if (jtagmkII_getsync(pgm, EMULATOR_MODE_DEBUGWIRE) < 0) + if(jtagmkII_getsync(pgm, EMULATOR_MODE_DEBUGWIRE) < 0) return -1; return 0; @@ -1511,20 +1481,20 @@ static int jtagmkII_open_pdi(PROGRAMMER *pgm, const char *port) { /* * The JTAG ICE mkII always starts with a baud rate of 19200 Bd upon - * attaching. If the config file or command-line parameters specify - * a higher baud rate, we switch to it later on, after establishing - * the connection with the ICE. + * attaching. If the config file or command-line parameters specify a higher + * baud rate, we switch to it later on, after establishing the connection + * with the ICE. */ pinfo.serialinfo.baud = 19200; pinfo.serialinfo.cflags = SERIAL_8N1; /* - * If the port name starts with "usb", divert the serial routines - * to the USB ones. The serial_open() function for USB overrides - * the meaning of the "baud" parameter to be the USB device ID to - * search for. + * If the port name starts with "usb", divert the serial routines to the USB + * ones. The serial_open() function for USB overrides the meaning of the + * "baud" parameter to be the USB device ID to search for. */ - if (str_starts(port, "usb")) { + if(str_starts(port, "usb")) { + #if defined(HAVE_LIBUSB) serdev = &usb_serdev; pinfo.usbinfo.vid = USB_VENDOR_ATMEL; @@ -1533,7 +1503,7 @@ static int jtagmkII_open_pdi(PROGRAMMER *pgm, const char *port) { pgm->fd.usb.max_xfer = USBDEV_MAX_XFER_MKII; pgm->fd.usb.rep = USBDEV_BULK_EP_READ_MKII; pgm->fd.usb.wep = USBDEV_BULK_EP_WRITE_MKII; - pgm->fd.usb.eep = 0; /* no seperate EP for events */ + pgm->fd.usb.eep = 0; // No seperate EP for events #else msg_error("avrdude was compiled without usb support\n"); return -1; @@ -1541,28 +1511,25 @@ static int jtagmkII_open_pdi(PROGRAMMER *pgm, const char *port) { } pgm->port = port; - if (serial_open(port, pinfo, &pgm->fd)==-1) { + if(serial_open(port, pinfo, &pgm->fd) == -1) { return -1; } - /* - * drain any extraneous input - */ + // Drain any extraneous input jtagmkII_drain(pgm, 0); - /* Set RTS/DTR high or low based on the user specified rts_mode */ - if (PDATA(pgm)->rts_mode != RTS_MODE_DEFAULT) { + // Set RTS/DTR high or low based on the user specified rts_mode + if(my.rts_mode != RTS_MODE_DEFAULT) { serial_set_dtr_rts(&pgm->fd, 0); - serial_set_dtr_rts(&pgm->fd, PDATA(pgm)->rts_mode == RTS_MODE_LOW ? 1 : 0); + serial_set_dtr_rts(&pgm->fd, my.rts_mode == RTS_MODE_LOW? 1: 0); } - if (jtagmkII_getsync(pgm, EMULATOR_MODE_PDI) < 0) + if(jtagmkII_getsync(pgm, EMULATOR_MODE_PDI) < 0) return -1; return 0; } - static int jtagmkII_dragon_open(PROGRAMMER *pgm, const char *port) { union pinfo pinfo; @@ -1570,20 +1537,20 @@ static int jtagmkII_dragon_open(PROGRAMMER *pgm, const char *port) { /* * The JTAG ICE mkII always starts with a baud rate of 19200 Bd upon - * attaching. If the config file or command-line parameters specify - * a higher baud rate, we switch to it later on, after establishing - * the connection with the ICE. + * attaching. If the config file or command-line parameters specify a higher + * baud rate, we switch to it later on, after establishing the connection + * with the ICE. */ pinfo.serialinfo.baud = 19200; pinfo.serialinfo.cflags = SERIAL_8N1; /* - * If the port name starts with "usb", divert the serial routines - * to the USB ones. The serial_open() function for USB overrides - * the meaning of the "baud" parameter to be the USB device ID to - * search for. + * If the port name starts with "usb", divert the serial routines to the USB + * ones. The serial_open() function for USB overrides the meaning of the + * "baud" parameter to be the USB device ID to search for. */ - if (str_starts(port, "usb")) { + if(str_starts(port, "usb")) { + #if defined(HAVE_LIBUSB) serdev = &usb_serdev; pinfo.usbinfo.vid = USB_VENDOR_ATMEL; @@ -1592,7 +1559,7 @@ static int jtagmkII_dragon_open(PROGRAMMER *pgm, const char *port) { pgm->fd.usb.max_xfer = USBDEV_MAX_XFER_MKII; pgm->fd.usb.rep = USBDEV_BULK_EP_READ_MKII; pgm->fd.usb.wep = USBDEV_BULK_EP_WRITE_MKII; - pgm->fd.usb.eep = 0; /* no seperate EP for events */ + pgm->fd.usb.eep = 0; // No seperate EP for events #else msg_error("avrdude was compiled without usb support\n"); return -1; @@ -1600,22 +1567,19 @@ static int jtagmkII_dragon_open(PROGRAMMER *pgm, const char *port) { } pgm->port = port; - if (serial_open(port, pinfo, &pgm->fd)==-1) { + if(serial_open(port, pinfo, &pgm->fd) == -1) { return -1; } - /* - * drain any extraneous input - */ + // Drain any extraneous input jtagmkII_drain(pgm, 0); - if (jtagmkII_getsync(pgm, EMULATOR_MODE_JTAG) < 0) + if(jtagmkII_getsync(pgm, EMULATOR_MODE_JTAG) < 0) return -1; return 0; } - static int jtagmkII_dragon_open_dw(PROGRAMMER *pgm, const char *port) { union pinfo pinfo; @@ -1623,20 +1587,20 @@ static int jtagmkII_dragon_open_dw(PROGRAMMER *pgm, const char *port) { /* * The JTAG ICE mkII always starts with a baud rate of 19200 Bd upon - * attaching. If the config file or command-line parameters specify - * a higher baud rate, we switch to it later on, after establishing - * the connection with the ICE. + * attaching. If the config file or command-line parameters specify a higher + * baud rate, we switch to it later on, after establishing the connection + * with the ICE. */ pinfo.serialinfo.baud = 19200; pinfo.serialinfo.cflags = SERIAL_8N1; /* - * If the port name starts with "usb", divert the serial routines - * to the USB ones. The serial_open() function for USB overrides - * the meaning of the "baud" parameter to be the USB device ID to - * search for. + * If the port name starts with "usb", divert the serial routines to the USB + * ones. The serial_open() function for USB overrides the meaning of the + * "baud" parameter to be the USB device ID to search for. */ - if (str_starts(port, "usb")) { + if(str_starts(port, "usb")) { + #if defined(HAVE_LIBUSB) serdev = &usb_serdev; pinfo.usbinfo.vid = USB_VENDOR_ATMEL; @@ -1645,7 +1609,7 @@ static int jtagmkII_dragon_open_dw(PROGRAMMER *pgm, const char *port) { pgm->fd.usb.max_xfer = USBDEV_MAX_XFER_MKII; pgm->fd.usb.rep = USBDEV_BULK_EP_READ_MKII; pgm->fd.usb.wep = USBDEV_BULK_EP_WRITE_MKII; - pgm->fd.usb.eep = 0; /* no seperate EP for events */ + pgm->fd.usb.eep = 0; // No seperate EP for events #else msg_error("avrdude was compiled without usb support\n"); return -1; @@ -1653,22 +1617,19 @@ static int jtagmkII_dragon_open_dw(PROGRAMMER *pgm, const char *port) { } pgm->port = port; - if (serial_open(port, pinfo, &pgm->fd)==-1) { + if(serial_open(port, pinfo, &pgm->fd) == -1) { return -1; } - /* - * drain any extraneous input - */ + // Drain any extraneous input jtagmkII_drain(pgm, 0); - if (jtagmkII_getsync(pgm, EMULATOR_MODE_DEBUGWIRE) < 0) + if(jtagmkII_getsync(pgm, EMULATOR_MODE_DEBUGWIRE) < 0) return -1; return 0; } - static int jtagmkII_dragon_open_pdi(PROGRAMMER *pgm, const char *port) { union pinfo pinfo; @@ -1676,20 +1637,20 @@ static int jtagmkII_dragon_open_pdi(PROGRAMMER *pgm, const char *port) { /* * The JTAG ICE mkII always starts with a baud rate of 19200 Bd upon - * attaching. If the config file or command-line parameters specify - * a higher baud rate, we switch to it later on, after establishing - * the connection with the ICE. + * attaching. If the config file or command-line parameters specify a higher + * baud rate, we switch to it later on, after establishing the connection + * with the ICE. */ pinfo.serialinfo.baud = 19200; pinfo.serialinfo.cflags = SERIAL_8N1; /* - * If the port name starts with "usb", divert the serial routines - * to the USB ones. The serial_open() function for USB overrides - * the meaning of the "baud" parameter to be the USB device ID to - * search for. + * If the port name starts with "usb", divert the serial routines to the USB + * ones. The serial_open() function for USB overrides the meaning of the + * "baud" parameter to be the USB device ID to search for. */ - if (str_starts(port, "usb")) { + if(str_starts(port, "usb")) { + #if defined(HAVE_LIBUSB) serdev = &usb_serdev; pinfo.usbinfo.vid = USB_VENDOR_ATMEL; @@ -1698,7 +1659,7 @@ static int jtagmkII_dragon_open_pdi(PROGRAMMER *pgm, const char *port) { pgm->fd.usb.max_xfer = USBDEV_MAX_XFER_MKII; pgm->fd.usb.rep = USBDEV_BULK_EP_READ_MKII; pgm->fd.usb.wep = USBDEV_BULK_EP_WRITE_MKII; - pgm->fd.usb.eep = 0; /* no seperate EP for events */ + pgm->fd.usb.eep = 0; // No seperate EP for events #else msg_error("avrdude was compiled without usb support\n"); return -1; @@ -1706,49 +1667,45 @@ static int jtagmkII_dragon_open_pdi(PROGRAMMER *pgm, const char *port) { } pgm->port = port; - if (serial_open(port, pinfo, &pgm->fd)==-1) { + if(serial_open(port, pinfo, &pgm->fd) == -1) { return -1; } - /* - * drain any extraneous input - */ + // Drain any extraneous input jtagmkII_drain(pgm, 0); - if (jtagmkII_getsync(pgm, EMULATOR_MODE_PDI) < 0) + if(jtagmkII_getsync(pgm, EMULATOR_MODE_PDI) < 0) return -1; return 0; } - -void jtagmkII_close(PROGRAMMER * pgm) -{ +void jtagmkII_close(PROGRAMMER *pgm) { int status; unsigned char buf[1], *resp, c; pmsg_notice2("jtagmkII_close()\n"); - if (pgm->flag & (PGM_FL_IS_PDI | PGM_FL_IS_JTAG)) { - /* When in PDI or JTAG mode, restart target. */ + if(pgm->flag & (PGM_FL_IS_PDI | PGM_FL_IS_JTAG)) { + // When in PDI or JTAG mode, restart target. buf[0] = CMND_GO; pmsg_notice2("%s(): sending GO command: ", __func__); jtagmkII_send(pgm, buf, 1); status = jtagmkII_recv(pgm, &resp); - if (status <= 0) { + if(status <= 0) { msg_notice2("\n"); pmsg_error("timeout/error communicating with programmer (status %d)\n", status); } else { - if (verbose >= MSG_DEBUG) { - msg_debug("\n"); - jtagmkII_prmsg(pgm, resp, status); + if(verbose >= MSG_DEBUG) { + msg_debug("\n"); + jtagmkII_prmsg(pgm, resp, status); } else - msg_notice2("0x%02x (%d bytes msg)\n", resp[0], status); + msg_notice2("0x%02x (%d bytes msg)\n", resp[0], status); c = resp[0]; mmt_free(resp); - if (c != RSP_OK) { - pmsg_error("bad response to GO command: %s\n", jtagmkII_get_rc(pgm, c)); + if(c != RSP_OK) { + pmsg_error("bad response to GO command: %s\n", jtagmkII_get_rc(pgm, c)); } } } @@ -1758,23 +1715,23 @@ void jtagmkII_close(PROGRAMMER * pgm) jtagmkII_send(pgm, buf, 1); status = jtagmkII_recv(pgm, &resp); - if (status <= 0) { + if(status <= 0) { msg_notice2("\n"); pmsg_error("timeout/error communicating with programmer (status %d)\n", status); return; } - if (verbose >= MSG_DEBUG) { + if(verbose >= MSG_DEBUG) { msg_debug("\n"); jtagmkII_prmsg(pgm, resp, status); } else msg_notice2("0x%02x (%d bytes msg)\n", resp[0], status); c = resp[0]; mmt_free(resp); - if (c != RSP_OK) { + if(c != RSP_OK) { pmsg_error("bad response to sign-off command: %s\n", jtagmkII_get_rc(pgm, c)); } - if (PDATA(pgm)->rts_mode != RTS_MODE_DEFAULT) { + if(my.rts_mode != RTS_MODE_DEFAULT) { pmsg_notice("releasing DTR/RTS handshake lines\n"); serial_set_dtr_rts(&pgm->fd, 0); } @@ -1786,15 +1743,13 @@ void jtagmkII_close(PROGRAMMER * pgm) * after a programming session has ended before Avrdude can * communicate with the programmer again. */ - if (str_casestarts(pgmid, "dragon")) + if(str_casestarts(pgmid, "dragon")) usleep(1000*1000*1.5); - else if (str_caseeq(pgmid, "nanoevery")) + else if(str_caseeq(pgmid, "nanoevery")) usleep(1000*1000*0.5); } -static int jtagmkII_page_erase(const PROGRAMMER *pgm, const AVRPART *p, const AVRMEM *m, - unsigned int addr) -{ +static int jtagmkII_page_erase(const PROGRAMMER *pgm, const AVRPART *p, const AVRMEM *m, unsigned int addr) { unsigned char cmd[6]; unsigned char *resp; int status, tries; @@ -1802,29 +1757,29 @@ static int jtagmkII_page_erase(const PROGRAMMER *pgm, const AVRPART *p, const AV pmsg_notice2("jtagmkII_page_erase(.., %s, 0x%x)\n", m->desc, addr); - if ((p->prog_modes & PM_Classic) && !mem_is_userrow(m)) { + if(is_classic(p) && !mem_is_userrow(m)) { pmsg_error("page erase only available for AVR8X/XMEGAs or classic-part usersig mem\n"); return -1; } - if ((pgm->flag & PGM_FL_IS_DW)) { + if((pgm->flag & PGM_FL_IS_DW)) { pmsg_error("not applicable to debugWIRE\n"); return -1; } - if (jtagmkII_program_enable(pgm) < 0) + if(jtagmkII_program_enable(pgm) < 0) return -1; cmd[0] = CMND_XMEGA_ERASE; - if (mem_is_flash(m)) { - if (jtagmkII_mtype(pgm, p, addr) == MTYPE_FLASH) + if(mem_is_flash(m)) { + if(jtagmkII_mtype(pgm, p, addr) == MTYPE_FLASH) cmd[1] = XMEGA_ERASE_APP_PAGE; else cmd[1] = XMEGA_ERASE_BOOT_PAGE; - } else if (mem_is_eeprom(m)) { + } else if(mem_is_eeprom(m)) { cmd[1] = XMEGA_ERASE_EEPROM_PAGE; - } else if (mem_is_userrow(m) || mem_is_bootrow(m)) { + } else if(mem_is_userrow(m) || mem_is_bootrow(m)) { cmd[1] = XMEGA_ERASE_USERSIG; - } else if (mem_is_boot(m)) { + } else if(mem_is_boot(m)) { cmd[1] = XMEGA_ERASE_BOOT_PAGE; } else { cmd[1] = XMEGA_ERASE_APP_PAGE; @@ -1832,24 +1787,24 @@ static int jtagmkII_page_erase(const PROGRAMMER *pgm, const AVRPART *p, const AV serial_recv_timeout = 100; /* - * Don't use jtagmkII_memaddr() here. While with all other - * commands, firmware 7+ doesn't require the NVM offsets being - * applied, the erase page commands make an exception, and do - * require the NVM offsets as part of the (page) address. + * Don't use jtagmkII_memaddr() here. While with all other commands, + * firmware 7+ doesn't require the NVM offsets being applied, the erase page + * commands make an exception, and do require the NVM offsets as part of the + * (page) address. */ u32_to_b4(cmd + 2, addr + m->offset); tries = 0; - retry: - pmsg_notice2("%s(): sending Xmega erase command: ", __func__); +retry: + pmsg_notice2("%s(): sending Xmega erase command: ", __func__); jtagmkII_send(pgm, cmd, sizeof cmd); status = jtagmkII_recv(pgm, &resp); - if (status <= 0) { + if(status <= 0) { msg_notice2("\n"); pmsg_warning("timeout/error communicating with programmer (status %d)\n", status); - if (tries++ < 4) { + if(tries++ < 4) { serial_recv_timeout *= 2; goto retry; } @@ -1857,12 +1812,12 @@ static int jtagmkII_page_erase(const PROGRAMMER *pgm, const AVRPART *p, const AV serial_recv_timeout = otimeout; return -1; } - if (verbose >= MSG_DEBUG) { + if(verbose >= MSG_DEBUG) { msg_debug("\n"); jtagmkII_prmsg(pgm, resp, status); } else msg_notice2("0x%02x (%d bytes msg)\n", resp[0], status); - if (resp[0] != RSP_OK) { + if(resp[0] != RSP_OK) { pmsg_error("bad response to xmega erase command: %s\n", jtagmkII_get_rc(pgm, resp[0])); mmt_free(resp); serial_recv_timeout = otimeout; @@ -1876,9 +1831,7 @@ static int jtagmkII_page_erase(const PROGRAMMER *pgm, const AVRPART *p, const AV } static int jtagmkII_paged_write(const PROGRAMMER *pgm, const AVRPART *p, const AVRMEM *m, - unsigned int page_size, - unsigned int addr, unsigned int n_bytes) -{ + unsigned int page_size, unsigned int addr, unsigned int n_bytes) { unsigned int block_size; unsigned int maxaddr = addr + n_bytes; unsigned char *cmd; @@ -1888,95 +1841,97 @@ static int jtagmkII_paged_write(const PROGRAMMER *pgm, const AVRPART *p, const A pmsg_notice2("jtagmkII_paged_write(.., %s, %d, %d)\n", m->desc, page_size, n_bytes); - if (!(pgm->flag & PGM_FL_IS_DW) && jtagmkII_program_enable(pgm) < 0) + if(!(pgm->flag & PGM_FL_IS_DW) && jtagmkII_program_enable(pgm) < 0) return -1; - if (page_size == 0) page_size = 256; - else if (page_size > 256) page_size = 256; + if(page_size == 0) + page_size = 256; + else if(page_size > 256) + page_size = 256; cmd = mmt_malloc(page_size + 10); cmd[0] = CMND_WRITE_MEMORY; - if (mem_is_flash(m)) { - PDATA(pgm)->flash_pageaddr = ~0UL; + if(mem_is_flash(m)) { + my.flash_pageaddr = ~0UL; cmd[1] = jtagmkII_mtype(pgm, p, addr); - if (p->prog_modes & (PM_PDI | PM_UPDI)) // Dynamically decide between flash/boot mtype + if(p->prog_modes & (PM_PDI | PM_UPDI)) // Dynamically decide between flash/boot mtype dynamic_mtype = 1; - } else if (mem_is_eeprom(m)) { - if (pgm->flag & PGM_FL_IS_DW) { + } else if(mem_is_eeprom(m)) { + if(pgm->flag & PGM_FL_IS_DW) { /* - * jtagmkII_paged_write() to EEPROM attempted while in - * DW mode. Use jtagmkII_write_byte() instead. + * jtagmkII_paged_write() to EEPROM attempted while in DW mode. Use + * jtagmkII_write_byte() instead. */ - for (; addr < maxaddr; addr++) { - status = jtagmkII_write_byte(pgm, p, m, addr, m->buf[addr]); - if (status < 0) { - mmt_free(cmd); - return -1; - } + for(; addr < maxaddr; addr++) { + status = jtagmkII_write_byte(pgm, p, m, addr, m->buf[addr]); + if(status < 0) { + mmt_free(cmd); + return -1; + } } mmt_free(cmd); return n_bytes; } cmd[1] = p->prog_modes & (PM_PDI | PM_UPDI)? MTYPE_EEPROM_XMEGA: MTYPE_EEPROM_PAGE; - PDATA(pgm)->eeprom_pageaddr = ~0UL; - } else if (mem_is_userrow(m) || mem_is_bootrow(m)) { + my.eeprom_pageaddr = ~0UL; + } else if(mem_is_userrow(m) || mem_is_bootrow(m)) { cmd[1] = MTYPE_USERSIG; - } else if (mem_is_boot(m)) { + } else if(mem_is_boot(m)) { cmd[1] = MTYPE_BOOT_FLASH; - } else if (p->prog_modes & (PM_PDI | PM_UPDI)) { + } else if(p->prog_modes & (PM_PDI | PM_UPDI)) { cmd[1] = MTYPE_FLASH; } else { cmd[1] = MTYPE_SPM; } serial_recv_timeout = 200; - for (; addr < maxaddr; addr += page_size) { - if ((maxaddr - addr) < page_size) + for(; addr < maxaddr; addr += page_size) { + if((maxaddr - addr) < page_size) block_size = maxaddr - addr; else block_size = page_size; pmsg_debug("%s(): block_size at addr %d is %d\n", __func__, addr, block_size); - if (dynamic_mtype) + if(dynamic_mtype) cmd[1] = jtagmkII_mtype(pgm, p, addr); u32_to_b4(cmd + 2, page_size); u32_to_b4(cmd + 6, jtagmkII_memaddr(pgm, p, m, addr)); /* - * The JTAG ICE will refuse to write anything but a full page, at - * least for the flash ROM. If a partial page has been requested, - * set the remainder to 0xff. (Maybe we should rather read back - * the existing contents instead before? Doesn't matter much, as - * bits cannot be written to 1 anyway.) + * The JTAG ICE will refuse to write anything but a full page, at least for + * the flash ROM. If a partial page has been requested, set the remainder + * to 0xff. (Maybe we should rather read back the existing contents + * instead before? Doesn't matter much, as bits cannot be written to 1 + * anyway.) */ memset(cmd + 10, 0xff, page_size); memcpy(cmd + 10, m->buf + addr, block_size); tries = 0; - retry: - pmsg_notice2("%s(): sending write memory command: ", __func__); + retry: + pmsg_notice2("%s(): sending write memory command: ", __func__); jtagmkII_send(pgm, cmd, page_size + 10); status = jtagmkII_recv(pgm, &resp); - if (status <= 0) { + if(status <= 0) { msg_notice2("\n"); pmsg_warning("timeout/error communicating with programmer (status %d)\n", status); - if (tries++ < 4) { - serial_recv_timeout *= 2; - goto retry; + if(tries++ < 4) { + serial_recv_timeout *= 2; + goto retry; } pmsg_error("timeout/error communicating with programmer (status %d)\n", status); mmt_free(cmd); serial_recv_timeout = otimeout; return -1; } - if (verbose >= MSG_DEBUG) { + if(verbose >= MSG_DEBUG) { msg_debug("\n"); jtagmkII_prmsg(pgm, resp, status); } else msg_notice2("0x%02x (%d bytes msg)\n", resp[0], status); - if (resp[0] != RSP_OK) { + if(resp[0] != RSP_OK) { pmsg_error("bad response to write memory command: %s\n", jtagmkII_get_rc(pgm, resp[0])); mmt_free(resp); mmt_free(cmd); @@ -1989,14 +1944,12 @@ static int jtagmkII_paged_write(const PROGRAMMER *pgm, const AVRPART *p, const A mmt_free(cmd); serial_recv_timeout = otimeout; - PDATA(pgm)->recently_written = 1; + my.recently_written = 1; return n_bytes; } static int jtagmkII_paged_load(const PROGRAMMER *pgm, const AVRPART *p, const AVRMEM *m, - unsigned int page_size, - unsigned int addr, unsigned int n_bytes) -{ + unsigned int page_size, unsigned int addr, unsigned int n_bytes) { unsigned int block_size; unsigned int maxaddr = addr + n_bytes; unsigned char cmd[10]; @@ -2006,40 +1959,40 @@ static int jtagmkII_paged_load(const PROGRAMMER *pgm, const AVRPART *p, const AV pmsg_notice2("jtagmkII_paged_load(.., %s, %d, %d)\n", m->desc, page_size, n_bytes); - if (!(pgm->flag & PGM_FL_IS_DW) && jtagmkII_program_enable(pgm) < 0) + if(!(pgm->flag & PGM_FL_IS_DW) && jtagmkII_program_enable(pgm) < 0) return -1; page_size = m->readsize; cmd[0] = CMND_READ_MEMORY; - if (mem_is_flash(m)) { + if(mem_is_flash(m)) { cmd[1] = jtagmkII_mtype(pgm, p, addr); - if (p->prog_modes & (PM_PDI | PM_UPDI)) // Dynamically decide between flash/boot mtype + if(p->prog_modes & (PM_PDI | PM_UPDI)) // Dynamically decide between flash/boot mtype dynamic_mtype = 1; - } else if (mem_is_eeprom(m)) { + } else if(mem_is_eeprom(m)) { cmd[1] = p->prog_modes & (PM_PDI | PM_UPDI)? MTYPE_EEPROM: MTYPE_EEPROM_PAGE; - if (pgm->flag & PGM_FL_IS_DW) + if(pgm->flag & PGM_FL_IS_DW) return -1; - } else if (mem_is_sigrow(m)) { + } else if(mem_is_sigrow(m)) { cmd[1] = MTYPE_PRODSIG; - } else if (mem_is_userrow(m) || mem_is_bootrow(m)) { + } else if(mem_is_userrow(m) || mem_is_bootrow(m)) { cmd[1] = MTYPE_USERSIG; - } else if (mem_is_boot(m)) { + } else if(mem_is_boot(m)) { cmd[1] = MTYPE_BOOT_FLASH; - } else if (p->prog_modes & (PM_PDI | PM_UPDI)) { + } else if(p->prog_modes & (PM_PDI | PM_UPDI)) { cmd[1] = MTYPE_FLASH; } else { cmd[1] = MTYPE_SPM; } serial_recv_timeout = 100; - for (; addr < maxaddr; addr += page_size) { - if ((maxaddr - addr) < page_size) + for(; addr < maxaddr; addr += page_size) { + if((maxaddr - addr) < page_size) block_size = maxaddr - addr; else block_size = page_size; pmsg_debug("%s(): block_size at addr %d is %d\n", __func__, addr, block_size); - if (dynamic_mtype) + if(dynamic_mtype) cmd[1] = jtagmkII_mtype(pgm, p, addr); u32_to_b4(cmd + 2, block_size); @@ -2052,34 +2005,34 @@ static int jtagmkII_paged_load(const PROGRAMMER *pgm, const AVRPART *p, const AV jtagmkII_send(pgm, cmd, 10); status = jtagmkII_recv(pgm, &resp); - if (status <= 0) { + if(status <= 0) { msg_notice2("\n"); pmsg_warning("timeout/error communicating with programmer (status %d)\n", status); - if (tries++ < 4) { - serial_recv_timeout *= 2; - goto retry; + if(tries++ < 4) { + serial_recv_timeout *= 2; + goto retry; } pmsg_error("timeout/error communicating with programmer (status %d)\n", status); serial_recv_timeout = otimeout; return -1; } - if (verbose >= MSG_DEBUG) { + if(verbose >= MSG_DEBUG) { msg_debug("\n"); jtagmkII_prmsg(pgm, resp, status); } else msg_notice2("0x%02x (%d bytes msg)\n", resp[0], status); - if (resp[0] != RSP_MEMORY) { + if(resp[0] != RSP_MEMORY) { pmsg_error("bad response to read memory command: %s\n", jtagmkII_get_rc(pgm, resp[0])); mmt_free(resp); serial_recv_timeout = otimeout; return -1; } - memcpy(m->buf + addr, resp + 1, status-1); + memcpy(m->buf + addr, resp + 1, status - 1); mmt_free(resp); } serial_recv_timeout = otimeout; - PDATA(pgm)->recently_written = 0; + my.recently_written = 0; return n_bytes; } @@ -2087,13 +2040,15 @@ static int jtagmkII_read_chip_rev(const PROGRAMMER *pgm, const AVRPART *p, unsig // XMEGA using JTAG or PDI, tinyAVR0/1/2, megaAVR0, AVR-Dx, AVR-Ex using UPDI if(p->prog_modes & (PM_PDI | PM_UPDI)) { AVRMEM *m = avr_locate_io(p); + if(!m) { pmsg_error("cannot locate io memory; is avrdude.conf up to date?\n"); return -1; } int status = pgm->read_byte(pgm, p, m, - p->prog_modes & PM_PDI? p->mcu_base+3 :p->syscfg_base+1, chip_rev); - if (status < 0) + is_pdi(p)? p->mcu_base + 3: p->syscfg_base + 1, chip_rev); + + if(status < 0) return status; } else { pmsg_error("target does not have a chip revision that can be read\n"); @@ -2105,8 +2060,7 @@ static int jtagmkII_read_chip_rev(const PROGRAMMER *pgm, const AVRPART *p, unsig } static int jtagmkII_read_byte(const PROGRAMMER *pgm, const AVRPART *p, const AVRMEM *mem, - unsigned long addr, unsigned char * value) -{ + unsigned long addr, unsigned char *value) { unsigned char cmd[10]; unsigned char *resp = NULL, *cache_ptr = NULL; int status, tries, unsupp; @@ -2115,7 +2069,7 @@ static int jtagmkII_read_byte(const PROGRAMMER *pgm, const AVRPART *p, const AVR pmsg_notice2("jtagmkII_read_byte(.., %s, 0x%lx, ...)\n", mem->desc, addr); - if (!(pgm->flag & PGM_FL_IS_DW) && jtagmkII_program_enable(pgm) < 0) + if(!(pgm->flag & PGM_FL_IS_DW) && jtagmkII_program_enable(pgm) < 0) return -1; cmd[0] = CMND_READ_MEMORY; @@ -2123,88 +2077,88 @@ static int jtagmkII_read_byte(const PROGRAMMER *pgm, const AVRPART *p, const AVR addr += mem->offset; cmd[1] = p->prog_modes & (PM_PDI | PM_UPDI)? MTYPE_FLASH: MTYPE_FLASH_PAGE; - if (mem_is_in_flash(mem)) { - pagesize = PDATA(pgm)->flash_pagesize; + if(mem_is_in_flash(mem)) { + pagesize = my.flash_pagesize; paddr = addr & ~(pagesize - 1); - paddr_ptr = &PDATA(pgm)->flash_pageaddr; - cache_ptr = PDATA(pgm)->flash_pagecache; - } else if (mem_is_eeprom(mem)) { - if ( (pgm->flag & PGM_FL_IS_DW) || (p->prog_modes & (PM_PDI | PM_UPDI)) ) { - /* debugWire cannot use page access for EEPROM */ + paddr_ptr = &my.flash_pageaddr; + cache_ptr = my.flash_pagecache; + } else if(mem_is_eeprom(mem)) { + if((pgm->flag & PGM_FL_IS_DW) || (p->prog_modes & (PM_PDI | PM_UPDI))) { + // debugWire cannot use page access for EEPROM cmd[1] = MTYPE_EEPROM; } else { cmd[1] = MTYPE_EEPROM_PAGE; pagesize = mem->page_size; paddr = addr & ~(pagesize - 1); - paddr_ptr = &PDATA(pgm)->eeprom_pageaddr; - cache_ptr = PDATA(pgm)->eeprom_pagecache; + paddr_ptr = &my.eeprom_pageaddr; + cache_ptr = my.eeprom_pagecache; } } else if(mem_is_a_fuse(mem) || mem_is_fuses(mem)) { cmd[1] = MTYPE_FUSE_BITS; - if((p->prog_modes & PM_Classic) && mem_is_a_fuse(mem)) + if(is_classic(p) && mem_is_a_fuse(mem)) addr = mem_fuse_offset(mem); - if (pgm->flag & PGM_FL_IS_DW) + if(pgm->flag & PGM_FL_IS_DW) unsupp = 1; - } else if (mem_is_lock(mem)) { + } else if(mem_is_lock(mem)) { cmd[1] = MTYPE_LOCK_BITS; - if (pgm->flag & PGM_FL_IS_DW) + if(pgm->flag & PGM_FL_IS_DW) unsupp = 1; - } else if (mem_is_userrow(mem) || mem_is_bootrow(mem)) { + } else if(mem_is_userrow(mem) || mem_is_bootrow(mem)) { cmd[1] = MTYPE_USERSIG; - } else if (mem_is_sigrow(mem)) { - if (p->prog_modes & (PM_PDI | PM_UPDI)) { + } else if(mem_is_sigrow(mem)) { + if(p->prog_modes & (PM_PDI | PM_UPDI)) { cmd[1] = MTYPE_PRODSIG; pmsg_notice2("is_sigrow addr 0x%05lx\n", addr); } else { - cmd[1] = addr&1? MTYPE_OSCCAL_BYTE: MTYPE_SIGN_JTAG; + cmd[1] = addr & 1? MTYPE_OSCCAL_BYTE: MTYPE_SIGN_JTAG; addr /= 2; - if (pgm->flag & PGM_FL_IS_DW) + if(pgm->flag & PGM_FL_IS_DW) unsupp = 1; } } else if(is_classic(p) && mem_is_calibration(mem)) { cmd[1] = MTYPE_OSCCAL_BYTE; - if (pgm->flag & PGM_FL_IS_DW) + if(pgm->flag & PGM_FL_IS_DW) unsupp = 1; - } else if (mem_is_signature(mem)) { + } else if(mem_is_signature(mem)) { cmd[1] = MTYPE_SIGN_JTAG; - if (pgm->flag & PGM_FL_IS_DW) { + if(pgm->flag & PGM_FL_IS_DW) { /* - * In debugWire mode, there is no accessible memory area to read - * the signature from, but the essential two bytes can be read - * as a parameter from the ICE. + * In debugWire mode, there is no accessible memory area to read the + * signature from, but the essential two bytes can be read as a parameter + * from the ICE. */ unsigned char parm[4]; - switch (addr) { - case 0: - *value = 0x1E; /* Atmel vendor ID */ - break; - - case 1: - case 2: - if (jtagmkII_getparm(pgm, PAR_TARGET_SIGNATURE, parm) < 0) - return -1; - *value = parm[2 - addr]; - break; + switch(addr) { + case 0: + *value = 0x1E; // Atmel vendor ID + break; - default: - pmsg_error("illegal address %lu for signature memory\n", addr); + case 1: + case 2: + if(jtagmkII_getparm(pgm, PAR_TARGET_SIGNATURE, parm) < 0) return -1; - } + *value = parm[2 - addr]; + break; + + default: + pmsg_error("illegal address %lu for signature memory\n", addr); + return -1; + } return 0; } - } else if (mem_is_in_sigrow(mem)) { + } else if(mem_is_in_sigrow(mem)) { pmsg_notice2("in_sigrow addr 0x%05lx\n", addr); - if (p->prog_modes & (PM_PDI | PM_UPDI)) { + if(p->prog_modes & (PM_PDI | PM_UPDI)) { cmd[1] = MTYPE_PRODSIG; } else { - cmd[1] = addr&1? MTYPE_OSCCAL_BYTE: MTYPE_SIGN_JTAG; + cmd[1] = addr & 1? MTYPE_OSCCAL_BYTE: MTYPE_SIGN_JTAG; addr /= 2; - if (pgm->flag & PGM_FL_IS_DW) + if(pgm->flag & PGM_FL_IS_DW) unsupp = 1; } - } else if (mem_is_io(mem) || mem_is_sram(mem)) { + } else if(mem_is_io(mem) || mem_is_sram(mem)) { cmd[1] = MTYPE_FLASH; addr += avr_data_offset(p); } else { @@ -2212,30 +2166,26 @@ static int jtagmkII_read_byte(const PROGRAMMER *pgm, const AVRPART *p, const AVR return -1; } - /* - * If the respective memory area is not supported under debugWire, - * leave here. - */ - if (unsupp) { + // If the respective memory area is not supported under debugWire, leave here + if(unsupp) { *value = 42; return -1; } /* - * To improve the read speed, we used paged reads for flash and - * EEPROM, and cache the results in a page cache. + * To improve the read speed, we used paged reads for flash and EEPROM, and + * cache the results in a page cache. * - * Page cache validation is based on "{flash,eeprom}_pageaddr" - * (holding the base address of the most recent cache fill - * operation). This variable is set to ~0UL when the - * cache needs to be invalidated. + * Page cache validation is based on "{flash,eeprom}_pageaddr" (holding the + * base address of the most recent cache fill operation). This variable is + * set to ~0UL when the cache needs to be invalidated. */ - if (pagesize && paddr == *paddr_ptr) { + if(pagesize && paddr == *paddr_ptr) { *value = cache_ptr[addr & (pagesize - 1)]; return 0; } - if (pagesize) { + if(pagesize) { u32_to_b4(cmd + 2, pagesize); u32_to_b4(cmd + 6, paddr); } else { @@ -2249,27 +2199,27 @@ static int jtagmkII_read_byte(const PROGRAMMER *pgm, const AVRPART *p, const AVR jtagmkII_send(pgm, cmd, 10); status = jtagmkII_recv(pgm, &resp); - if (status <= 0) { + if(status <= 0) { msg_notice2("\n"); pmsg_warning("timeout/error communicating with programmer (status %d)\n", status); - if (tries++ < 3) + if(tries++ < 3) goto retry; pmsg_error("timeout/error communicating with programmer (status %d)\n", status); - if (status < 0) + if(status < 0) resp = 0; goto fail; } - if (verbose >= MSG_DEBUG) { + if(verbose >= MSG_DEBUG) { msg_debug("\n"); jtagmkII_prmsg(pgm, resp, status); } else msg_notice2("0x%02x (%d bytes msg)\n", resp[0], status); - if (resp[0] != RSP_MEMORY) { + if(resp[0] != RSP_MEMORY) { pmsg_error("bad response to read memory command: %s\n", jtagmkII_get_rc(pgm, resp[0])); goto fail; } - if (pagesize) { + if(pagesize) { *paddr_ptr = paddr; memcpy(cache_ptr, resp + 1, pagesize); *value = cache_ptr[addr & (pagesize - 1)]; @@ -2277,7 +2227,7 @@ static int jtagmkII_read_byte(const PROGRAMMER *pgm, const AVRPART *p, const AVR *value = resp[1]; mmt_free(resp); - PDATA(pgm)->recently_written = 0; + my.recently_written = 0; return 0; fail: @@ -2286,8 +2236,7 @@ static int jtagmkII_read_byte(const PROGRAMMER *pgm, const AVRPART *p, const AVR } static int jtagmkII_write_byte(const PROGRAMMER *pgm, const AVRPART *p, const AVRMEM *mem, - unsigned long addr, unsigned char data) -{ + unsigned long addr, unsigned char data) { unsigned char cmd[12]; unsigned char *resp = NULL, writedata, writedata2 = 0xFF; int status, tries, need_progmode = 1, unsupp = 0, writesize = 1; @@ -2299,41 +2248,42 @@ static int jtagmkII_write_byte(const PROGRAMMER *pgm, const AVRPART *p, const AV writedata = data; cmd[0] = CMND_WRITE_MEMORY; cmd[1] = p->prog_modes & (PM_PDI | PM_UPDI)? MTYPE_FLASH: MTYPE_SPM; - if (mem_is_flash(mem)) { - if ((addr & 1) == 1) { - /* odd address = high byte */ - writedata = 0xFF; /* don't modify the low byte */ - writedata2 = data; - addr &= ~1L; - } - writesize = 2; - if(str_eq(p->family_id, "megaAVR") || str_eq(p->family_id, "tinyAVR")) // AVRs with UPDI except AVR-Dx/Ex - need_progmode = 0; - PDATA(pgm)->flash_pageaddr = ~0UL; - if (pgm->flag & PGM_FL_IS_DW) - unsupp = 1; - } else if (mem_is_eeprom(mem)) { + if(mem_is_flash(mem)) { + if((addr & 1) == 1) { + // Odd address = high byte + writedata = 0xFF; // Don't modify the low byte + writedata2 = data; + addr &= ~1L; + } + writesize = 2; + if(str_eq(p->family_id, "megaAVR") || str_eq(p->family_id, "tinyAVR")) // AVRs with UPDI except AVR-Dx/Ex + need_progmode = 0; + my.flash_pageaddr = ~0UL; + if(pgm->flag & PGM_FL_IS_DW) + unsupp = 1; + } else if(mem_is_eeprom(mem)) { cmd[1] = p->prog_modes & (PM_PDI | PM_UPDI)? MTYPE_EEPROM_XMEGA: MTYPE_EEPROM; - if(str_eq(p->family_id, "megaAVR") || str_eq(p->family_id, "tinyAVR")) // AVRs with UPDI except AVR-Dx/Ex + if(str_eq(p->family_id, "megaAVR") || str_eq(p->family_id, "tinyAVR")) // AVRs with UPDI except AVR-Dx/Ex need_progmode = 0; - PDATA(pgm)->eeprom_pageaddr = ~0UL; - } else if (mem_is_a_fuse(mem) || mem_is_fuses(mem)) { + my.eeprom_pageaddr = ~0UL; + } else if(mem_is_a_fuse(mem) || mem_is_fuses(mem)) { cmd[1] = MTYPE_FUSE_BITS; - if((p->prog_modes & PM_Classic) && mem_is_a_fuse(mem)) + if(is_classic(p) && mem_is_a_fuse(mem)) addr = mem_fuse_offset(mem); - if (pgm->flag & PGM_FL_IS_DW) + if(pgm->flag & PGM_FL_IS_DW) unsupp = 1; - } else if (mem_is_userrow(mem) || mem_is_bootrow(mem)) { + } else if(mem_is_userrow(mem) || mem_is_bootrow(mem)) { cmd[1] = MTYPE_USERSIG; - } else if (mem_is_lock(mem)) { + } else if(mem_is_lock(mem)) { cmd[1] = MTYPE_LOCK_BITS; - if (pgm->flag & PGM_FL_IS_DW) + if(pgm->flag & PGM_FL_IS_DW) unsupp = 1; - } else if (mem_is_io(mem) || mem_is_sram(mem)) { - cmd[1] = MTYPE_FLASH; // Works with jtag2updi, does not work with any xmega + } else if(mem_is_io(mem) || mem_is_sram(mem)) { + cmd[1] = MTYPE_FLASH; // Works with jtag2updi, does not work with any xmega addr += avr_data_offset(p); } else if(mem_is_readonly(mem)) { unsigned char is; + if(pgm->read_byte(pgm, p, mem, addr, &is) >= 0 && is == data) return 0; @@ -2344,16 +2294,16 @@ static int jtagmkII_write_byte(const PROGRAMMER *pgm, const AVRPART *p, const AV return -1; } - if (unsupp) { + if(unsupp) { pmsg_error("unsupported memory %s in debugWIRE mode\n", mem->desc); return -1; } - if (need_progmode) { - if (jtagmkII_program_enable(pgm) < 0) + if(need_progmode) { + if(jtagmkII_program_enable(pgm) < 0) return -1; } else { - if (jtagmkII_program_disable(pgm) < 0) + if(jtagmkII_program_disable(pgm) < 0) return -1; } @@ -2368,26 +2318,26 @@ static int jtagmkII_write_byte(const PROGRAMMER *pgm, const AVRPART *p, const AV jtagmkII_send(pgm, cmd, 10 + writesize); status = jtagmkII_recv(pgm, &resp); - if (status <= 0) { + if(status <= 0) { msg_notice2("\n"); pmsg_notice2("%s(): timeout/error communicating with programmer (status %d)\n", __func__, status); - if (tries++ < 3) + if(tries++ < 3) goto retry; pmsg_error("timeout/error communicating with programmer (status %d)\n", status); goto fail; } - if (verbose >= MSG_DEBUG) { + if(verbose >= MSG_DEBUG) { msg_debug("\n"); jtagmkII_prmsg(pgm, resp, status); } else msg_notice2("0x%02x (%d bytes msg)\n", resp[0], status); - if (resp[0] != RSP_OK) { + if(resp[0] != RSP_OK) { pmsg_error("bad response to write memory command: %s\n", jtagmkII_get_rc(pgm, resp[0])); goto fail; } mmt_free(resp); - PDATA(pgm)->recently_written = 1; + my.recently_written = 1; return 0; fail: @@ -2395,26 +2345,25 @@ static int jtagmkII_write_byte(const PROGRAMMER *pgm, const AVRPART *p, const AV return -1; } - /* - * Set the JTAG clock. The actual frequency is quite a bit of - * guesswork, based on the values claimed by AVR Studio. Inside the - * JTAG ICE, the value is the delay count of a delay loop between the - * JTAG clock edges. A count of 0 bypasses the delay loop. + * Set the JTAG clock. The actual frequency is quite a bit of guesswork, based + * on the values claimed by AVR Studio. Inside the JTAG ICE, the value is the + * delay count of a delay loop between the JTAG clock edges. A count of 0 + * bypasses the delay loop. * - * As the STK500 expresses it as a period length (and we actualy do - * program a period length as well), we rather call it by that name. + * As the STK500 expresses it as a period length (and we actualy do program a + * period length as well), we rather call it by that name. */ static int jtagmkII_set_sck_period(const PROGRAMMER *pgm, double v) { unsigned char dur; - v = 1 / v; /* convert to frequency */ - if (v >= 6.4e6) + v = 1/v; // Convert to frequency + if(v >= 6.4e6) dur = 0; - else if (v >= 2.8e6) + else if(v >= 2.8e6) dur = 1; - else if (v >= 20.9e3) - dur = (unsigned char)(5.35e6 / v); + else if(v >= 20.9e3) + dur = (unsigned char) (5.35e6/v); else dur = 255; @@ -2424,30 +2373,29 @@ static int jtagmkII_set_sck_period(const PROGRAMMER *pgm, double v) { static int jtagmkII_get_sck_period(const PROGRAMMER *pgm, double *v) { unsigned char buf[4]; double clk; - if (jtagmkII_getparm(pgm, PAR_OCD_JTAG_CLK, buf) < 0) { + + if(jtagmkII_getparm(pgm, PAR_OCD_JTAG_CLK, buf) < 0) { pmsg_error("cannot read JTAG clock speed\n"); return -1; } - if (buf[0] == 0) + if(buf[0] == 0) clk = 6.4e6; - else if (buf[0] == 1) + else if(buf[0] == 1) clk = 2.8e6; else - clk = 5.35e6 / buf[0]; + clk = 5.35e6/buf[0]; - *v = 1 / clk; + *v = 1/clk; return 0; } /* - * Read an emulator parameter. As the maximal parameter length is 4 - * bytes by now, we always copy out 4 bytes to *value, so the caller - * must have allocated sufficient space. + * Read an emulator parameter. As the maximal parameter length is 4 bytes by + * now, we always copy out 4 bytes to *value, so the caller must have allocated + * sufficient space. */ -int jtagmkII_getparm(const PROGRAMMER *pgm, unsigned char parm, - unsigned char * value) -{ +int jtagmkII_getparm(const PROGRAMMER *pgm, unsigned char parm, unsigned char *value) { int status; unsigned char buf[2], *resp, c; @@ -2459,18 +2407,18 @@ int jtagmkII_getparm(const PROGRAMMER *pgm, unsigned char parm, jtagmkII_send(pgm, buf, 2); status = jtagmkII_recv(pgm, &resp); - if (status <= 0) { + if(status <= 0) { msg_notice2("\n"); pmsg_error("timeout/error communicating with programmer (status %d)\n", status); return -1; } - if (verbose >= MSG_DEBUG) { + if(verbose >= MSG_DEBUG) { msg_debug("\n"); jtagmkII_prmsg(pgm, resp, status); } else msg_notice2("0x%02x (%d bytes msg)\n", resp[0], status); c = resp[0]; - if (c != RSP_PARAMETER) { + if(c != RSP_PARAMETER) { pmsg_error("bad response to get parameter command: %s\n", jtagmkII_get_rc(pgm, c)); mmt_free(resp); return -1; @@ -2482,16 +2430,14 @@ int jtagmkII_getparm(const PROGRAMMER *pgm, unsigned char parm, return 0; } -/* - * Write an emulator parameter. - */ -static int jtagmkII_setparm(const PROGRAMMER *pgm, unsigned char parm, - unsigned char * value) -{ +// Write an emulator parameter +static int jtagmkII_setparm(const PROGRAMMER *pgm, unsigned char parm, unsigned char *value) { + int status; + /* - * As the maximal parameter length is 4 bytes, we use a fixed-length - * buffer, as opposed to malloc()ing it. + * As the maximal parameter length is 4 bytes, we use a fixed-length buffer, + * as opposed to malloc()ing it. */ unsigned char buf[2 + 4], *resp, c; size_t size; @@ -2499,18 +2445,51 @@ static int jtagmkII_setparm(const PROGRAMMER *pgm, unsigned char parm, pmsg_notice2("jtagmkII_setparm()\n"); - switch (parm) { - case PAR_HW_VERSION: size = 2; parstr ="hw_version"; break; - case PAR_FW_VERSION: size = 4; parstr ="fw_version"; break; - case PAR_EMULATOR_MODE: size = 1; parstr ="emulator_mode"; break; - case PAR_BAUD_RATE: size = 1; parstr ="baud_rate"; break; - case PAR_OCD_VTARGET: size = 2; parstr ="ocd_vtarget"; break; - case PAR_OCD_JTAG_CLK: size = 1; parstr ="ocd_jtag_clk"; break; - case PAR_TIMERS_RUNNING: size = 1; parstr ="timers_running"; break; - case PAR_EXTERNAL_RESET: size = 1; parstr ="external_reset"; break; - case PAR_DAISY_CHAIN_INFO: size = 4; parstr ="daisy_chain_info"; break; - case PAR_PDI_OFFSET_START: size = 4; parstr ="pdi_offset_start"; break; - case PAR_PDI_OFFSET_END: size = 4; parstr ="pdi_offset_end"; break; + switch(parm) { + case PAR_HW_VERSION: + size = 2; + parstr = "hw_version"; + break; + case PAR_FW_VERSION: + size = 4; + parstr = "fw_version"; + break; + case PAR_EMULATOR_MODE: + size = 1; + parstr = "emulator_mode"; + break; + case PAR_BAUD_RATE: + size = 1; + parstr = "baud_rate"; + break; + case PAR_OCD_VTARGET: + size = 2; + parstr = "ocd_vtarget"; + break; + case PAR_OCD_JTAG_CLK: + size = 1; + parstr = "ocd_jtag_clk"; + break; + case PAR_TIMERS_RUNNING: + size = 1; + parstr = "timers_running"; + break; + case PAR_EXTERNAL_RESET: + size = 1; + parstr = "external_reset"; + break; + case PAR_DAISY_CHAIN_INFO: + size = 4; + parstr = "daisy_chain_info"; + break; + case PAR_PDI_OFFSET_START: + size = 4; + parstr = "pdi_offset_start"; + break; + case PAR_PDI_OFFSET_END: + size = 4; + parstr = "pdi_offset_end"; + break; default: pmsg_error("unknown parameter 0x%02x\n", parm); return -1; @@ -2519,24 +2498,24 @@ static int jtagmkII_setparm(const PROGRAMMER *pgm, unsigned char parm, buf[0] = CMND_SET_PARAMETER; buf[1] = parm; memcpy(buf + 2, value, size); - pmsg_notice2("%s() sending set parameter command " - "(parm %s 0x%02x, %u bytes): ", __func__, parstr, parm, (unsigned) size); + pmsg_notice2("%s() sending set parameter command " "(parm %s 0x%02x, %u bytes): ", + __func__, parstr, parm, (unsigned) size); jtagmkII_send(pgm, buf, size + 2); status = jtagmkII_recv(pgm, &resp); - if (status <= 0) { + if(status <= 0) { msg_notice2("\n"); pmsg_error("timeout/error communicating with programmer (status %d)\n", status); return -1; } - if (verbose >= MSG_DEBUG) { + if(verbose >= MSG_DEBUG) { msg_debug("\n"); jtagmkII_prmsg(pgm, resp, status); } else msg_notice2("0x%02x (%d bytes msg)\n", resp[0], status); c = resp[0]; mmt_free(resp); - if (c != RSP_OK) { + if(c != RSP_OK) { pmsg_error("bad response to set parameter %s: %s\n", parstr, jtagmkII_get_rc(pgm, c)); return -1; } @@ -2544,55 +2523,52 @@ static int jtagmkII_setparm(const PROGRAMMER *pgm, unsigned char parm, return 0; } - static void jtagmkII_display(const PROGRAMMER *pgm, const char *p) { unsigned char hw[4], fw[4]; - if (jtagmkII_getparm(pgm, PAR_HW_VERSION, hw) < 0 || - jtagmkII_getparm(pgm, PAR_FW_VERSION, fw) < 0) + if(jtagmkII_getparm(pgm, PAR_HW_VERSION, hw) < 0 || jtagmkII_getparm(pgm, PAR_FW_VERSION, fw) < 0) return; msg_info("%sMain MCU HW version : %d\n", p, hw[0]); msg_info("%sMain MCU FW version : %d.%02d\n", p, fw[1], fw[0]); msg_info("%sSec. MCU HW version : %d\n", p, hw[1]); msg_info("%sSec. MCU FW version : %d.%02d\n", p, fw[3], fw[2]); msg_info("%sSerial number : %02x:%02x:%02x:%02x:%02x:%02x\n", p, - PDATA(pgm)->serno[0], PDATA(pgm)->serno[1], PDATA(pgm)->serno[2], - PDATA(pgm)->serno[3], PDATA(pgm)->serno[4], PDATA(pgm)->serno[5]); + my.serno[0], my.serno[1], my.serno[2], + my.serno[3], my.serno[4], my.serno[5]); jtagmkII_print_parms1(pgm, p, stderr); return; } - static void jtagmkII_print_parms1(const PROGRAMMER *pgm, const char *p, FILE *fp) { unsigned char vtarget[4], jtag_clock[4]; char clkbuf[20]; double clk; - if (pgm->extra_features & HAS_VTARG_READ) { - if (jtagmkII_getparm(pgm, PAR_OCD_VTARGET, vtarget) < 0) + if(pgm->extra_features & HAS_VTARG_READ) { + if(jtagmkII_getparm(pgm, PAR_OCD_VTARGET, vtarget) < 0) return; - fmsg_out(fp, "%sVtarget : %.1f V\n", p, b2_to_u16(vtarget) / 1000.0); + fmsg_out(fp, "%sVtarget : %.1f V\n", p, b2_to_u16(vtarget)/1000.0); } - if ((pgm->flag & PGM_FL_IS_JTAG)) { - if (jtagmkII_getparm(pgm, PAR_OCD_JTAG_CLK, jtag_clock) < 0) + if((pgm->flag & PGM_FL_IS_JTAG)) { + if(jtagmkII_getparm(pgm, PAR_OCD_JTAG_CLK, jtag_clock) < 0) return; - if (jtag_clock[0] == 0) { + if(jtag_clock[0] == 0) { strcpy(clkbuf, "6.4 MHz"); clk = 6.4e6; - } else if (jtag_clock[0] == 1) { + } else if(jtag_clock[0] == 1) { strcpy(clkbuf, "2.8 MHz"); clk = 2.8e6; - } else if (jtag_clock[0] <= 5) { - sprintf(clkbuf, "%.1f MHz", 5.35 / (double)jtag_clock[0]); - clk = 5.35e6 / (double)jtag_clock[0]; + } else if(jtag_clock[0] <= 5) { + sprintf(clkbuf, "%.1f MHz", 5.35/(double) jtag_clock[0]); + clk = 5.35e6/(double) jtag_clock[0]; } else { - sprintf(clkbuf, "%.1f kHz", 5.35e3 / (double)jtag_clock[0]); - clk = 5.35e6 / (double)jtag_clock[0]; - fmsg_out(fp, "%sJTAG clock : %s (%.1f us)\n", p, clkbuf, 1.0e6 / clk); + sprintf(clkbuf, "%.1f kHz", 5.35e3/(double) jtag_clock[0]); + clk = 5.35e6/(double) jtag_clock[0]; + fmsg_out(fp, "%sJTAG clock : %s (%.1f us)\n", p, clkbuf, 1.0e6/clk); } } @@ -2604,8 +2580,8 @@ static void jtagmkII_print_parms(const PROGRAMMER *pgm, FILE *fp) { } static unsigned char jtagmkII_mtype(const PROGRAMMER *pgm, const AVRPART *p, unsigned long addr) { - if (p->prog_modes & (PM_PDI | PM_UPDI)) { - if (addr >= PDATA(pgm)->boot_start) + if(p->prog_modes & (PM_PDI | PM_UPDI)) { + if(addr >= my.boot_start) return MTYPE_BOOT_FLASH; else return MTYPE_FLASH; @@ -2619,33 +2595,29 @@ static unsigned int jtagmkII_memaddr(const PROGRAMMER *pgm, const AVRPART *p, co * Xmega devices handled by V7+ firmware don't want to be told their * m->offset within the write memory command. */ - if (PDATA(pgm)->fwver >= 0x700 && (p->prog_modes & (PM_PDI | PM_UPDI))) { - if (addr >= PDATA(pgm)->boot_start) + if(my.fwver >= 0x700 && (p->prog_modes & (PM_PDI | PM_UPDI))) { + if(addr >= my.boot_start) /* - * all memories but "flash" are smaller than boot_start anyway, so - * no need for an extra check we are operating on "flash" + * All memories but "flash" are smaller than boot_start anyway, so no + * need for an extra check we are operating on "flash" */ - return addr - PDATA(pgm)->boot_start; + return addr - my.boot_start; else - /* normal flash, or anything else */ + // Normal flash, or anything else return addr; } /* - * Old firmware, or non-Xmega device. Non-Xmega (and non-AVR32) - * devices always have an m->offset of 0, so we don't have to - * distinguish them here. + * Old firmware, or non-Xmega device. Non-Xmega (and non-AVR32) devices + * always have an m->offset of 0, so we don't have to distinguish them here. */ return addr + m->offset; } - #ifdef __OBJC__ #pragma mark - #endif -static int jtagmkII_avr32_reset(const PROGRAMMER *pgm, unsigned char val, - unsigned char ret1, unsigned char ret2) -{ +static int jtagmkII_avr32_reset(const PROGRAMMER *pgm, unsigned char val, unsigned char ret1, unsigned char ret2) { int status; unsigned char buf[3], *resp; @@ -2654,25 +2626,26 @@ static int jtagmkII_avr32_reset(const PROGRAMMER *pgm, unsigned char val, buf[0] = CMND_GET_IR; buf[1] = 0x0C; status = jtagmkII_send(pgm, buf, 2); - if(status < 0) return -1; + if(status < 0) + return -1; status = jtagmkII_recv(pgm, &resp); - if (status != 2 || resp[0] != 0x87 || resp[1] != ret1) { + if(status != 2 || resp[0] != 0x87 || resp[1] != ret1) { pmsg_notice("%s(): Get_IR, expecting %2.2x but got %2.2x\n", __func__, ret1, resp[1]); - - //return -1; + // return -1; } buf[0] = CMND_GET_xxx; buf[1] = 5; buf[2] = val; status = jtagmkII_send(pgm, buf, 3); - if(status < 0) return -1; + if(status < 0) + return -1; status = jtagmkII_recv(pgm, &resp); - if (status != 2 || resp[0] != 0x87 || resp[1] != ret2) { + if(status != 2 || resp[0] != 0x87 || resp[1] != ret2) { pmsg_notice("%s(): Get_XXX, expecting %2.2x but got %2.2x\n", __func__, ret2, resp[1]); - //return -1; + // return -1; } return 0; @@ -2682,7 +2655,7 @@ static int jtagmkII_avr32_reset(const PROGRAMMER *pgm, unsigned char val, static int jtagmkII_reset32(const PROGRAMMER *pgm, unsigned short flags) { int status, j, lineno; unsigned char *resp, buf[3]; - unsigned long val=0; + unsigned long val = 0; pmsg_notice("jtagmkII_reset32(%2.2x)\n", flags); @@ -2693,176 +2666,223 @@ static int jtagmkII_reset32(const PROGRAMMER *pgm, unsigned short flags) { buf[0] = CMND_GET_IR; buf[1] = 0x11; status = jtagmkII_send(pgm, buf, 2); - if(status < 0) {lineno = __LINE__; goto eRR;} + if(status < 0) + gotoerr; status = jtagmkII_recv(pgm, &resp); - if (status != 2 || resp[0] != 0x87 || resp[1] != 01) - {lineno = __LINE__; goto eRR;}; + if(status != 2 || resp[0] != 0x87 || resp[1] != 01) + gotoerr;; } if(flags & (AVR32_RESET_WRITE | AVR32_SET4RUNNING)) { // AVR_RESET(0x1F) status = jtagmkII_avr32_reset(pgm, 0x1F, 0x01, 0x00); - if(status < 0) {lineno = __LINE__; goto eRR;} + if(status < 0) + gotoerr; // AVR_RESET(0x07) status = jtagmkII_avr32_reset(pgm, 0x07, 0x11, 0x1F); - if(status < 0) {lineno = __LINE__; goto eRR;} + if(status < 0) + gotoerr; } - //if(flags & AVR32_RESET_COMMON) + // if(flags & AVR32_RESET_COMMON) { val = jtagmkII_read_SABaddr(pgm, AVR32_DS, 0x01); - if(val != 0) {lineno = __LINE__; goto eRR;} + if(val != 0) + gotoerr; val = jtagmkII_read_SABaddr(pgm, AVR32_DC, 0x01); - if(val != 0) {lineno = __LINE__; goto eRR;} + if(val != 0) + gotoerr; } if(flags & (AVR32_RESET_READ | AVR32_RESET_CHIP_ERASE)) { - status = jtagmkII_write_SABaddr(pgm, AVR32_DC, 0x01, - AVR32_DC_DBE | AVR32_DC_DBR); - if(status < 0) return -1; + status = jtagmkII_write_SABaddr(pgm, AVR32_DC, 0x01, AVR32_DC_DBE | AVR32_DC_DBR); + if(status < 0) + return -1; } if(flags & (AVR32_RESET_WRITE | AVR32_SET4RUNNING)) { status = jtagmkII_write_SABaddr(pgm, AVR32_DC, 0x01, - AVR32_DC_ABORT | AVR32_DC_RESET | AVR32_DC_DBE | AVR32_DC_DBR); - if(status < 0) return -1; - for(j=0; j<21; ++j) { + AVR32_DC_ABORT | AVR32_DC_RESET | AVR32_DC_DBE | AVR32_DC_DBR); + if(status < 0) + return -1; + for(j = 0; j < 21; ++j) { val = jtagmkII_read_SABaddr(pgm, AVR32_DS, 0x01); } - if(val != 0x04000000) {lineno = __LINE__; goto eRR;} + if(val != 0x04000000) + gotoerr; // AVR_RESET(0x00) status = jtagmkII_avr32_reset(pgm, 0x00, 0x01, 0x07); - if(status < 0) {lineno = __LINE__; goto eRR;} + if(status < 0) + gotoerr; } // if(flags & (AVR32_RESET_READ | AVR32_RESET_WRITE)) { - for(j=0; j<2; ++j) { + for(j = 0; j < 2; ++j) { val = jtagmkII_read_SABaddr(pgm, AVR32_DS, 0x01); - if(val == ERROR_SAB) {lineno = __LINE__; goto eRR;} - if((val&0x05000020) != 0x05000020) {lineno = __LINE__; goto eRR;} + if(val == ERROR_SAB) + gotoerr; + if((val & 0x05000020) != 0x05000020) + gotoerr; } } - //if(flags & (AVR32_RESET_READ | AVR32_RESET_WRITE | AVR32_RESET_CHIP_ERASE)) + // if(flags & (AVR32_RESET_READ | AVR32_RESET_WRITE | AVR32_RESET_CHIP_ERASE)) { - status = jtagmkII_write_SABaddr(pgm, AVR32_DINST, 0x01, 0xe7b00044); // mtdr 272, R0 - if(status < 0) {lineno = __LINE__; goto eRR;} + status = jtagmkII_write_SABaddr(pgm, AVR32_DINST, 0x01, 0xe7b00044); // mtdr 272, R0 + if(status < 0) + gotoerr; val = jtagmkII_read_SABaddr(pgm, AVR32_DCSR, 0x01); - if(val != 0x00000001) {lineno = __LINE__; goto eRR;} + if(val != 0x00000001) + gotoerr; val = jtagmkII_read_SABaddr(pgm, AVR32_DCCPU, 0x01); - if(val != 0x00000000) {lineno = __LINE__; goto eRR;} + if(val != 0x00000000) + gotoerr; } // Read chip configuration - common for all if(flags & (AVR32_RESET_READ | AVR32_RESET_WRITE | AVR32_RESET_CHIP_ERASE)) { - for(j=0; j<2; ++j) { + for(j = 0; j < 2; ++j) { val = jtagmkII_read_SABaddr(pgm, AVR32_DS, 0x01); - if(val == ERROR_SAB) {lineno = __LINE__; goto eRR;} - if((val&0x05000020) != 0x05000020) {lineno = __LINE__; goto eRR;} + if(val == ERROR_SAB) + gotoerr; + if((val & 0x05000020) != 0x05000020) + gotoerr; } - status = jtagmkII_write_SABaddr(pgm, AVR32_DINST, 0x01, 0xe7b00044); // mtdr 272, R0 - if(status < 0) {lineno = __LINE__; goto eRR;} + status = jtagmkII_write_SABaddr(pgm, AVR32_DINST, 0x01, 0xe7b00044); // mtdr 272, R0 + if(status < 0) + gotoerr; val = jtagmkII_read_SABaddr(pgm, AVR32_DCSR, 0x01); - if(val != 0x00000001) {lineno = __LINE__; goto eRR;} + if(val != 0x00000001) + gotoerr; val = jtagmkII_read_SABaddr(pgm, AVR32_DCCPU, 0x01); - if(val != 0x00000000) {lineno = __LINE__; goto eRR;} + if(val != 0x00000000) + gotoerr; - status = jtagmkII_write_SABaddr(pgm, AVR32_DINST, 0x01, 0xe1b00040); // mfsr R0, 256 - if(status < 0) {lineno = __LINE__; goto eRR;} + status = jtagmkII_write_SABaddr(pgm, AVR32_DINST, 0x01, 0xe1b00040); // mfsr R0, 256 + if(status < 0) + gotoerr; - status = jtagmkII_write_SABaddr(pgm, AVR32_DINST, 0x01, 0xe7b00044); // mtdr 272, R0 - if(status < 0) {lineno = __LINE__; goto eRR;} + status = jtagmkII_write_SABaddr(pgm, AVR32_DINST, 0x01, 0xe7b00044); // mtdr 272, R0 + if(status < 0) + gotoerr; val = jtagmkII_read_SABaddr(pgm, AVR32_DCSR, 0x01); - if(val != 0x00000001) {lineno = __LINE__; goto eRR;} + if(val != 0x00000001) + gotoerr; val = jtagmkII_read_SABaddr(pgm, AVR32_DCCPU, 0x01); - if(val == ERROR_SAB) {lineno = __LINE__; goto eRR;} + if(val == ERROR_SAB) + gotoerr; status = jtagmkII_write_SABaddr(pgm, AVR32_DCEMU, 0x01, 0x00000000); - if(status < 0) {lineno = __LINE__; goto eRR;} + if(status < 0) + gotoerr; - status = jtagmkII_write_SABaddr(pgm, AVR32_DINST, 0x01, 0xe5b00045); // mtdr R0, 276 - if(status < 0) {lineno = __LINE__; goto eRR;} + status = jtagmkII_write_SABaddr(pgm, AVR32_DINST, 0x01, 0xe5b00045); // mtdr R0, 276 + if(status < 0) + gotoerr; val = jtagmkII_read_SABaddr(pgm, AVR32_DS, 0x01); - if(val == ERROR_SAB) {lineno = __LINE__; goto eRR;} - if((val&0x05000020) != 0x05000020) {lineno = __LINE__; goto eRR;} + if(val == ERROR_SAB) + gotoerr; + if((val & 0x05000020) != 0x05000020) + gotoerr; - status = jtagmkII_write_SABaddr(pgm, AVR32_DINST, 0x01, 0xe7b00044); // mtdr 272, R0 - if(status < 0) {lineno = __LINE__; goto eRR;} + status = jtagmkII_write_SABaddr(pgm, AVR32_DINST, 0x01, 0xe7b00044); // mtdr 272, R0 + if(status < 0) + gotoerr; val = jtagmkII_read_SABaddr(pgm, AVR32_DCSR, 0x01); - if(val != 0x00000001) {lineno = __LINE__; goto eRR;} + if(val != 0x00000001) + gotoerr; val = jtagmkII_read_SABaddr(pgm, AVR32_DCCPU, 0x01); - if(val != 0x00000000) {lineno = __LINE__; goto eRR;} + if(val != 0x00000000) + gotoerr; - status = jtagmkII_write_SABaddr(pgm, AVR32_DINST, 0x01, 0xe1b00041); // mfsr R0, 260 - if(status < 0) {lineno = __LINE__; goto eRR;} - status = jtagmkII_write_SABaddr(pgm, AVR32_DINST, 0x01, 0xe7b00044); // mtdr 272, R0 - if(status < 0) {lineno = __LINE__; goto eRR;} + status = jtagmkII_write_SABaddr(pgm, AVR32_DINST, 0x01, 0xe1b00041); // mfsr R0, 260 + if(status < 0) + gotoerr; + status = jtagmkII_write_SABaddr(pgm, AVR32_DINST, 0x01, 0xe7b00044); // mtdr 272, R0 + if(status < 0) + gotoerr; val = jtagmkII_read_SABaddr(pgm, AVR32_DCSR, 0x01); - if(val != 0x00000001) {lineno = __LINE__; goto eRR;} + if(val != 0x00000001) + gotoerr; val = jtagmkII_read_SABaddr(pgm, AVR32_DCCPU, 0x01); - if(val == ERROR_SAB) {lineno = __LINE__; goto eRR;} + if(val == ERROR_SAB) + gotoerr; status = jtagmkII_write_SABaddr(pgm, AVR32_DCEMU, 0x01, 0x00000000); - if(status < 0) {lineno = __LINE__; goto eRR;} - status = jtagmkII_write_SABaddr(pgm, AVR32_DINST, 0x01, 0xe5b00045); // mtdr R0, 276 - if(status < 0) {lineno = __LINE__; goto eRR;} + if(status < 0) + gotoerr; + status = jtagmkII_write_SABaddr(pgm, AVR32_DINST, 0x01, 0xe5b00045); // mtdr R0, 276 + if(status < 0) + gotoerr; - val = jtagmkII_read_SABaddr(pgm, 0x00000010, 0x06); // need to recheck who does this ... - if(val != 0x00000000) {lineno = __LINE__; goto eRR;} + val = jtagmkII_read_SABaddr(pgm, 0x00000010, 0x06); // Need to recheck who does this ... + if(val != 0x00000000) + gotoerr; } if(flags & AVR32_RESET_CHIP_ERASE) { status = jtagmkII_avr32_reset(pgm, 0x1f, 0x01, 0x00); - if(status < 0) {lineno = __LINE__; goto eRR;} + if(status < 0) + gotoerr; status = jtagmkII_avr32_reset(pgm, 0x01, 0x11, 0x1f); - if(status < 0) {lineno = __LINE__; goto eRR;} + if(status < 0) + gotoerr; } if(flags & AVR32_SET4RUNNING) { - status = jtagmkII_write_SABaddr(pgm, AVR32_DINST, 0x01, 0xe1b00014); // mfsr R0, 80 - if(status < 0) {lineno = __LINE__; goto eRR;} + status = jtagmkII_write_SABaddr(pgm, AVR32_DINST, 0x01, 0xe1b00014); // mfsr R0, 80 + if(status < 0) + gotoerr; - status = jtagmkII_write_SABaddr(pgm, AVR32_DINST, 0x01, 0xe7b00044); // mtdr 272, R0 - if(status < 0) {lineno = __LINE__; goto eRR;} + status = jtagmkII_write_SABaddr(pgm, AVR32_DINST, 0x01, 0xe7b00044); // mtdr 272, R0 + if(status < 0) + gotoerr; val = jtagmkII_read_SABaddr(pgm, AVR32_DCSR, 0x01); - if(val != 0x00000001) {lineno = __LINE__; goto eRR;} + if(val != 0x00000001) + gotoerr; val = jtagmkII_read_SABaddr(pgm, AVR32_DCCPU, 0x01); - if(val == ERROR_SAB) {lineno = __LINE__; goto eRR;} + if(val == ERROR_SAB) + gotoerr; status = jtagmkII_write_SABaddr(pgm, AVR32_DCEMU, 0x01, 0x00000000); - if(status < 0) {lineno = __LINE__; goto eRR;} + if(status < 0) + gotoerr; - status = jtagmkII_write_SABaddr(pgm, AVR32_DINST, 0x01, 0xe5b00045); // mfdr R0, 276 - if(status < 0) {lineno = __LINE__; goto eRR;} + status = jtagmkII_write_SABaddr(pgm, AVR32_DINST, 0x01, 0xe5b00045); // mfdr R0, 276 + if(status < 0) + gotoerr; val = jtagmkII_read_SABaddr(pgm, AVR32_DS, 0x01); - if(val == ERROR_SAB) {lineno = __LINE__; goto eRR;} - if((val&0x05000020) != 0x05000020) {lineno = __LINE__; goto eRR;} + if(val == ERROR_SAB) + gotoerr; + if((val & 0x05000020) != 0x05000020) + gotoerr; - status = jtagmkII_write_SABaddr(pgm, AVR32_DINST, 0x01, 0xd623d703); // retd - if(status < 0) {lineno = __LINE__; goto eRR;} + status = jtagmkII_write_SABaddr(pgm, AVR32_DINST, 0x01, 0xd623d703); // retd + if(status < 0) + gotoerr; } return 0; - eRR: - pmsg_error("reset failed at line %d (status=%x val=%lx)\n", lineno, status, val); - return -1; +eRR: + pmsg_error("reset failed at line %d (status=%x val=%lx)\n", lineno, status, val); + return -1; } static int jtagmkII_smc_init32(const PROGRAMMER *pgm) { @@ -2871,116 +2891,148 @@ static int jtagmkII_smc_init32(const PROGRAMMER *pgm) { // HMATRIX 0xFFFF1000 status = jtagmkII_write_SABaddr(pgm, 0xffff1018, 0x05, 0x04000000); - if (status < 0) {lineno = __LINE__; goto eRR;} + if(status < 0) + gotoerr; status = jtagmkII_write_SABaddr(pgm, 0xffff1024, 0x05, 0x04000000); - if (status < 0) {lineno = __LINE__; goto eRR;} + if(status < 0) + gotoerr; status = jtagmkII_write_SABaddr(pgm, 0xffff1008, 0x05, 0x04000000); - if (status < 0) {lineno = __LINE__; goto eRR;} + if(status < 0) + gotoerr; status = jtagmkII_write_SABaddr(pgm, 0xffff1078, 0x05, 0x04000000); - if (status < 0) {lineno = __LINE__; goto eRR;} + if(status < 0) + gotoerr; status = jtagmkII_write_SABaddr(pgm, 0xffff1088, 0x05, 0x04000000); - if (status < 0) {lineno = __LINE__; goto eRR;} + if(status < 0) + gotoerr; status = jtagmkII_write_SABaddr(pgm, 0xffff1018, 0x05, 0x08000000); - if (status < 0) {lineno = __LINE__; goto eRR;} + if(status < 0) + gotoerr; status = jtagmkII_write_SABaddr(pgm, 0xffff1024, 0x05, 0x08000000); - if (status < 0) {lineno = __LINE__; goto eRR;} + if(status < 0) + gotoerr; status = jtagmkII_write_SABaddr(pgm, 0xffff1008, 0x05, 0x08000000); - if (status < 0) {lineno = __LINE__; goto eRR;} + if(status < 0) + gotoerr; status = jtagmkII_write_SABaddr(pgm, 0xffff1078, 0x05, 0x08000000); - if (status < 0) {lineno = __LINE__; goto eRR;} + if(status < 0) + gotoerr; status = jtagmkII_write_SABaddr(pgm, 0xffff1088, 0x05, 0x08000000); - if (status < 0) {lineno = __LINE__; goto eRR;} + if(status < 0) + gotoerr; status = jtagmkII_write_SABaddr(pgm, 0xffff1018, 0x05, 0x10000000); - if (status < 0) {lineno = __LINE__; goto eRR;} + if(status < 0) + gotoerr; status = jtagmkII_write_SABaddr(pgm, 0xffff1024, 0x05, 0x10000000); - if (status < 0) {lineno = __LINE__; goto eRR;} + if(status < 0) + gotoerr; status = jtagmkII_write_SABaddr(pgm, 0xffff1008, 0x05, 0x10000000); - if (status < 0) {lineno = __LINE__; goto eRR;} + if(status < 0) + gotoerr; status = jtagmkII_write_SABaddr(pgm, 0xffff1078, 0x05, 0x10000000); - if (status < 0) {lineno = __LINE__; goto eRR;} + if(status < 0) + gotoerr; status = jtagmkII_write_SABaddr(pgm, 0xffff1088, 0x05, 0x10000000); - if (status < 0) {lineno = __LINE__; goto eRR;} + if(status < 0) + gotoerr; status = jtagmkII_write_SABaddr(pgm, 0xffff1018, 0x05, 0x00020000); - if (status < 0) {lineno = __LINE__; goto eRR;} + if(status < 0) + gotoerr; status = jtagmkII_write_SABaddr(pgm, 0xffff1024, 0x05, 0x00020000); - if (status < 0) {lineno = __LINE__; goto eRR;} + if(status < 0) + gotoerr; status = jtagmkII_write_SABaddr(pgm, 0xffff1008, 0x05, 0x00020000); - if (status < 0) {lineno = __LINE__; goto eRR;} + if(status < 0) + gotoerr; status = jtagmkII_write_SABaddr(pgm, 0xffff1078, 0x05, 0x00020000); - if (status < 0) {lineno = __LINE__; goto eRR;} + if(status < 0) + gotoerr; status = jtagmkII_write_SABaddr(pgm, 0xffff1088, 0x05, 0x00020000); - if (status < 0) {lineno = __LINE__; goto eRR;} + if(status < 0) + gotoerr; status = jtagmkII_write_SABaddr(pgm, 0xffff1018, 0x05, 0x02000000); - if (status < 0) {lineno = __LINE__; goto eRR;} + if(status < 0) + gotoerr; status = jtagmkII_write_SABaddr(pgm, 0xffff1024, 0x05, 0x02000000); - if (status < 0) {lineno = __LINE__; goto eRR;} + if(status < 0) + gotoerr; status = jtagmkII_write_SABaddr(pgm, 0xffff1008, 0x05, 0x02000000); - if (status < 0) {lineno = __LINE__; goto eRR;} + if(status < 0) + gotoerr; status = jtagmkII_write_SABaddr(pgm, 0xffff1078, 0x05, 0x02000000); - if (status < 0) {lineno = __LINE__; goto eRR;} + if(status < 0) + gotoerr; status = jtagmkII_write_SABaddr(pgm, 0xffff1088, 0x05, 0x02000000); - if (status < 0) {lineno = __LINE__; goto eRR;} + if(status < 0) + gotoerr; status = jtagmkII_write_SABaddr(pgm, 0xfffe1c00, 0x05, 0x00010001); - if (status < 0) {lineno = __LINE__; goto eRR;} + if(status < 0) + gotoerr; status = jtagmkII_write_SABaddr(pgm, 0xfffe1c04, 0x05, 0x05070a0b); - if (status < 0) {lineno = __LINE__; goto eRR;} + if(status < 0) + gotoerr; status = jtagmkII_write_SABaddr(pgm, 0xfffe1c08, 0x05, 0x000b000c); - if (status < 0) {lineno = __LINE__; goto eRR;} + if(status < 0) + gotoerr; status = jtagmkII_write_SABaddr(pgm, 0xfffe1c0c, 0x05, 0x00031103); - if (status < 0) {lineno = __LINE__; goto eRR;} + if(status < 0) + gotoerr; // switchToClockSource val = jtagmkII_read_SABaddr(pgm, 0xffff0c28, 0x05); - if (val != 0x00000000) {lineno = __LINE__; goto eRR;} // OSC 0 + if(val != 0x00000000) + gotoerr; // OSC 0 status = jtagmkII_write_SABaddr(pgm, 0xffff0c28, 0x05, 0x0000607); - if (status < 0) {lineno = __LINE__; goto eRR;} + if(status < 0) + gotoerr; val = jtagmkII_read_SABaddr(pgm, 0xffff0c00, 0x05); - if (val != 0x00000000) {lineno = __LINE__; goto eRR;} // PLL 0 + if(val != 0x00000000) + gotoerr; // PLL 0 status = jtagmkII_write_SABaddr(pgm, 0xffff0c00, 0x05, 0x0000004); - if (status < 0) {lineno = __LINE__; goto eRR;} // Power Manager + if(status < 0) + gotoerr; // Power Manager status = jtagmkII_write_SABaddr(pgm, 0xffff0c00, 0x05, 0x0000005); - if (status < 0) {lineno = __LINE__; goto eRR;} + if(status < 0) + gotoerr; usleep(1000000); val = jtagmkII_read_SABaddr(pgm, 0xfffe1408, 0x05); - if (val != 0x0000a001) {lineno = __LINE__; goto eRR;} // PLL 0 + if(val != 0x0000a001) + gotoerr; // PLL 0 - // need a small delay to let clock stabliize + // Need a small delay to let clock stabliize usleep(50*1000); return 0; - eRR: - pmsg_error("init failed at line %d\n", lineno); - return -1; +eRR: + pmsg_error("init failed at line %d\n", lineno); + return -1; } - -/* - * initialize the AVR device and prepare it to accept commands - */ +// Initialize the AVR device and prepare it to accept commands static int jtagmkII_initialize32(const PROGRAMMER *pgm, const AVRPART *p) { int status, j; unsigned char buf[6], *resp; - if (jtagmkII_setparm(pgm, PAR_DAISY_CHAIN_INFO, PDATA(pgm)->jtagchain) < 0) { + if(jtagmkII_setparm(pgm, PAR_DAISY_CHAIN_INFO, my.jtagchain) < 0) { pmsg_error("unable to setup JTAG chain\n"); return -1; } - mmt_free(PDATA(pgm)->flash_pagecache); - mmt_free(PDATA(pgm)->eeprom_pagecache); - PDATA(pgm)->flash_pagecache = mmt_malloc(PDATA(pgm)->flash_pagesize); - PDATA(pgm)->eeprom_pagecache = mmt_malloc(PDATA(pgm)->eeprom_pagesize); - PDATA(pgm)->flash_pageaddr = PDATA(pgm)->eeprom_pageaddr = ~0UL; + mmt_free(my.flash_pagecache); + mmt_free(my.eeprom_pagecache); + my.flash_pagecache = mmt_malloc(my.flash_pagesize); + my.eeprom_pagecache = mmt_malloc(my.eeprom_pagesize); + my.flash_pageaddr = my.eeprom_pageaddr = ~0UL; - for(j=0; j<2; ++j) { + for(j = 0; j < 2; ++j) { buf[0] = CMND_GET_IR; buf[1] = 0x1; if(jtagmkII_send(pgm, buf, 2) < 0) @@ -3005,11 +3057,8 @@ static int jtagmkII_initialize32(const PROGRAMMER *pgm, const AVRPART *p) { return -1; } - if (status != 5 || - resp[2] != p->signature[0] || - resp[3] != p->signature[1] || - resp[4] != p->signature[2]) { - if (ovsigck) { + if(status != 5 || resp[2] != p->signature[0] || resp[3] != p->signature[1] || resp[4] != p->signature[2]) { + if(ovsigck) { pmsg_warning("expected signature for %s is%s\n", p->desc, str_cchex(p->signature, 3, 1)); } else { pmsg_error("expected signature for %s is%s;\n", p->desc, str_cchex(p->signature, 3, 1)); @@ -3024,45 +3073,52 @@ static int jtagmkII_initialize32(const PROGRAMMER *pgm, const AVRPART *p) { } static int jtagmkII_chip_erase32(const PROGRAMMER *pgm, const AVRPART *p_unused) { - int status=0, loops; + int status = 0, loops; unsigned char *resp, buf[3], x, ret[4], *retP; - unsigned long val=0; + unsigned long val = 0; unsigned int lineno; pmsg_notice("jtagmkII_chip_erase32()\n"); status = jtagmkII_reset32(pgm, AVR32_RESET_CHIP_ERASE); - if(status != 0) {lineno = __LINE__; goto eRR;} + if(status != 0) + gotoerr; - // sequence of IR transitions + // Sequence of IR transitions ret[0] = 0x01; ret[1] = 0x05; ret[2] = 0x01; ret[3] = 0x00; retP = ret; - for(loops=0; loops<1000; ++loops) { + for(loops = 0; loops < 1000; ++loops) { buf[0] = CMND_GET_IR; buf[1] = 0x0F; status = jtagmkII_send(pgm, buf, 2); - if(status < 0) {lineno = __LINE__; goto eRR;} + if(status < 0) + gotoerr; status = jtagmkII_recv(pgm, &resp); - if (status != 2 || resp[0] != 0x87) { - {lineno = __LINE__; goto eRR;} + if(status != 2 || resp[0] != 0x87) { + gotoerr; } x = resp[1]; mmt_free(resp); - if(x == *retP) ++retP; - if(*retP == 0x00) break; + if(x == *retP) + ++retP; + if(*retP == 0x00) + break; } - if(loops == 1000) {lineno = __LINE__; goto eRR;} + if(loops == 1000) + gotoerr; status = jtagmkII_avr32_reset(pgm, 0x00, 0x01, 0x01); - if(status < 0) {lineno = __LINE__; goto eRR;} + if(status < 0) + gotoerr; val = jtagmkII_read_SABaddr(pgm, 0x00000010, 0x06); - if(val != 0x00000000) {lineno = __LINE__; goto eRR;} + if(val != 0x00000000) + gotoerr; // AVR32 "special" buf[0] = CMND_SET_PARAMETER; @@ -3070,19 +3126,18 @@ static int jtagmkII_chip_erase32(const PROGRAMMER *pgm, const AVRPART *p_unused) buf[2] = 0x02; jtagmkII_send(pgm, buf, 3); status = jtagmkII_recv(pgm, &resp); - if(status < 0 || resp[0] != RSP_OK) {lineno = __LINE__; goto eRR;} + if(status < 0 || resp[0] != RSP_OK) + gotoerr; mmt_free(resp); return 0; - eRR: - pmsg_error("chip erase failed at line %d (status=%x val=%lx)\n", lineno, status, val); - return -1; +eRR: + pmsg_error("chip erase failed at line %d (status=%x val=%lx)\n", lineno, status, val); + return -1; } -static unsigned long jtagmkII_read_SABaddr(const PROGRAMMER *pgm, unsigned long addr, - unsigned int prefix) -{ +static unsigned long jtagmkII_read_SABaddr(const PROGRAMMER *pgm, unsigned long addr, unsigned int prefix) { unsigned char buf[6], *resp; int status; unsigned long val; @@ -3105,12 +3160,13 @@ static unsigned long jtagmkII_read_SABaddr(const PROGRAMMER *pgm, unsigned long if(status > 0) { int i; + msg_error("cmd: "); - for(i=0; i<6; ++i) + for(i = 0; i < 6; ++i) msg_error("%2.2x ", buf[i]); msg_error("\n"); msg_error("Data: "); - for(i=0; ifd.usb.max_xfer = USBDEV_MAX_XFER_MKII; pgm->fd.usb.rep = USBDEV_BULK_EP_READ_MKII; pgm->fd.usb.wep = USBDEV_BULK_EP_WRITE_MKII; - pgm->fd.usb.eep = 0; /* no seperate EP for events */ + pgm->fd.usb.eep = 0; // No seperate EP for events #else msg_error("avrdude was compiled without usb support\n"); return -1; @@ -3199,17 +3253,16 @@ static int jtagmkII_open32(PROGRAMMER *pgm, const char *port) { } pgm->port = port; - if (serial_open(port, pinfo, &pgm->fd)==-1) { + if(serial_open(port, pinfo, &pgm->fd) == -1) { return -1; } - /* - * drain any extraneous input - */ + // Drain any extraneous input jtagmkII_drain(pgm, 0); status = jtagmkII_getsync(pgm, -1); - if(status < 0) return -1; + if(status < 0) + return -1; // AVR32 "special" buf[0] = CMND_SET_PARAMETER; @@ -3240,10 +3293,10 @@ static int jtagmkII_open32(PROGRAMMER *pgm, const char *port) { return 0; } -static void jtagmkII_close32(PROGRAMMER * pgm) { +static void jtagmkII_close32(PROGRAMMER *pgm) { int status, lineno; unsigned char *resp, buf[3], c; - unsigned long val=0; + unsigned long val = 0; pmsg_notice2("jtagmkII_close32()\n"); @@ -3253,7 +3306,8 @@ static void jtagmkII_close32(PROGRAMMER * pgm) { buf[2] = 0x02; jtagmkII_send(pgm, buf, 3); status = jtagmkII_recv(pgm, &resp); - if(status < 0 || resp[0] != RSP_OK) {lineno = __LINE__; goto eRR;} + if(status < 0 || resp[0] != RSP_OK) + gotoerr; mmt_free(resp); buf[0] = CMND_SIGN_OFF; @@ -3261,30 +3315,30 @@ static void jtagmkII_close32(PROGRAMMER * pgm) { jtagmkII_send(pgm, buf, 1); status = jtagmkII_recv(pgm, &resp); - if (status <= 0) { + if(status <= 0) { msg_notice2("\n"); pmsg_error("timeout/error communicating with programmer (status %d)\n", status); return; } - if (verbose >= MSG_DEBUG) { + if(verbose >= MSG_DEBUG) { msg_debug("\n"); jtagmkII_prmsg(pgm, resp, status); } else msg_notice2("0x%02x (%d bytes msg)\n", resp[0], status); c = resp[0]; mmt_free(resp); - if (c != RSP_OK) { + if(c != RSP_OK) { pmsg_error("bad response to sign-off command: %s\n", jtagmkII_get_rc(pgm, c)); } - ret: - serial_close(&pgm->fd); - pgm->fd.ifd = -1; - return; +ret: + serial_close(&pgm->fd); + pgm->fd.ifd = -1; + return; - eRR: - pmsg_error("close failed at line %d (status=%x val=%lx)\n", lineno, status, val); - goto ret; +eRR: + pmsg_error("close failed at line %d (status=%x val=%lx)\n", lineno, status, val); + goto ret; } static int jtagmkII_paged_load32(const PROGRAMMER *pgm, const AVRPART *p_unused, const AVRMEM *m, @@ -3295,50 +3349,53 @@ static int jtagmkII_paged_load32(const PROGRAMMER *pgm, const AVRPART *p_unused, unsigned char cmd[7]; unsigned char *resp; int lineno, status; - unsigned long val=0; + unsigned long val = 0; long otimeout = serial_recv_timeout; pmsg_notice2("jtagmkII_paged_load32(.., %s, %d, %d)\n", m->desc, page_size, n_bytes); serial_recv_timeout = 256; - if(!(PDATA(pgm)->flags32 & FLAGS32_WRITE)) { + if(!(my.flags32 & FLAGS32_WRITE)) { status = jtagmkII_reset32(pgm, AVR32_RESET_READ); - if(status != 0) {lineno = __LINE__; goto eRR;} + if(status != 0) + gotoerr; } // Init SMC and set clocks - if(!(PDATA(pgm)->flags32 & FLAGS32_INIT_SMC)) { + if(!(my.flags32 & FLAGS32_INIT_SMC)) { status = jtagmkII_smc_init32(pgm); - if(status != 0) {lineno = __LINE__; goto eRR;} // PLL 0 - PDATA(pgm)->flags32 |= FLAGS32_INIT_SMC; + if(status != 0) + gotoerr; // PLL 0 + my.flags32 |= FLAGS32_INIT_SMC; } - //msg_error("\n pageSize=%d bytes=%d pages=%d m->offset=0x%x pgm->page_size %d\n", - // page_size, n_bytes, pages, m->offset, pgm->page_size); + // msg_error("\n pageSize=%d bytes=%d pages=%d m->offset=0x%x pgm->page_size %d\n", + // page_size, n_bytes, pages, m->offset, pgm->page_size); cmd[0] = CMND_READ_MEMORY32; cmd[1] = 0x40; cmd[2] = 0x05; - for (; addr < maxaddr; addr += block_size) { - block_size = maxaddr - addr < (unsigned int) pgm->page_size? - maxaddr - addr: (unsigned int) pgm->page_size; + for(; addr < maxaddr; addr += block_size) { + block_size = maxaddr - addr < (unsigned int) pgm->page_size? maxaddr - addr: (unsigned int) pgm->page_size; pmsg_debug("%s(): block_size at addr %d is %d\n", __func__, addr, block_size); u32_to_b4r(cmd + 3, m->offset + addr); status = jtagmkII_send(pgm, cmd, 7); - if(status<0) {lineno = __LINE__; goto eRR;} + if(status < 0) + gotoerr; status = jtagmkII_recv(pgm, &resp); - if(status<0) {lineno = __LINE__; goto eRR;} + if(status < 0) + gotoerr; - if (verbose >= MSG_DEBUG) { + if(verbose >= MSG_DEBUG) { msg_debug("\n"); jtagmkII_prmsg(pgm, resp, status); } else msg_notice2("0x%02x (%d bytes msg)\n", resp[0], status); - if (resp[0] != 0x87) { + if(resp[0] != 0x87) { pmsg_error("bad response to write memory command: %s\n", jtagmkII_get_rc(pgm, resp[0])); mmt_free(resp); return -1; @@ -3351,73 +3408,79 @@ static int jtagmkII_paged_load32(const PROGRAMMER *pgm, const AVRPART *p_unused, serial_recv_timeout = otimeout; status = jtagmkII_reset32(pgm, AVR32_SET4RUNNING); - if(status < 0) {lineno = __LINE__; goto eRR;} + if(status < 0) + gotoerr; return addr; - eRR: - serial_recv_timeout = otimeout; - pmsg_error("paged load failed at line %d (status=%x val=%lx)\n", lineno, status, val); - return -1; +eRR: + serial_recv_timeout = otimeout; + pmsg_error("paged load failed at line %d (status=%x val=%lx)\n", lineno, status, val); + return -1; } -static int jtagmkII_paged_write32(const PROGRAMMER *pgm, const AVRPART *p_unused , const AVRMEM *m, +static int jtagmkII_paged_write32(const PROGRAMMER *pgm, const AVRPART *p_unused, const AVRMEM *m, unsigned int page_size, unsigned int addr, unsigned int n_bytes) { unsigned int block_size; - unsigned char *cmd=NULL; + unsigned char *cmd = NULL; unsigned char *resp; int lineno, status, pages, sPageNum, pageNum, blocks; - unsigned long val=0; + unsigned long val = 0; unsigned long otimeout = serial_recv_timeout; unsigned int maxaddr = addr + n_bytes; serial_recv_timeout = 256; - if(n_bytes == 0) return -1; + if(n_bytes == 0) + return -1; status = jtagmkII_reset32(pgm, AVR32_RESET_WRITE); - if(status != 0) {lineno = __LINE__; goto eRR;} - PDATA(pgm)->flags32 |= FLAGS32_WRITE; + if(status != 0) + gotoerr; + my.flags32 |= FLAGS32_WRITE; pages = (n_bytes - addr - 1)/page_size + 1; sPageNum = addr/page_size; - //msg_error("\n pageSize=%d bytes=%d pages=%d m->offset=0x%x pgm->page_size %d\n", - // page_size, n_bytes, pages, m->offset, pgm->page_size); + // msg_error("\n pageSize=%d bytes=%d pages=%d m->offset=0x%x pgm->page_size %d\n", + // page_size, n_bytes, pages, m->offset, pgm->page_size); // Before any errors can happen cmd = mmt_malloc(pgm->page_size + 10); // Init SMC and set clocks - if(!(PDATA(pgm)->flags32 & FLAGS32_INIT_SMC)) { + if(!(my.flags32 & FLAGS32_INIT_SMC)) { status = jtagmkII_smc_init32(pgm); - if(status != 0) {lineno = __LINE__; goto eRR;} // PLL 0 - PDATA(pgm)->flags32 |= FLAGS32_INIT_SMC; + if(status != 0) + gotoerr; // PLL 0 + my.flags32 |= FLAGS32_INIT_SMC; } // First unlock the pages - for(pageNum=sPageNum; pageNum < pages; ++pageNum) { - status =jtagmkII_flash_lock32(pgm, 0, pageNum); - if(status < 0) {lineno = __LINE__; goto eRR;} + for(pageNum = sPageNum; pageNum < pages; ++pageNum) { + status = jtagmkII_flash_lock32(pgm, 0, pageNum); + if(status < 0) + gotoerr; } // Then erase them (guess could do this in the same loop above?) - for(pageNum=sPageNum; pageNum < pages; ++pageNum) { - status =jtagmkII_flash_erase32(pgm, pageNum); - if(status < 0) {lineno = __LINE__; goto eRR;} + for(pageNum = sPageNum; pageNum < pages; ++pageNum) { + status = jtagmkII_flash_erase32(pgm, pageNum); + if(status < 0) + gotoerr; } cmd[0] = CMND_WRITE_MEMORY32; - u32_to_b4r(&cmd[1], 0x40000000); // who knows + u32_to_b4r(&cmd[1], 0x40000000); // Who knows cmd[5] = 0x5; - for(pageNum=sPageNum; pageNum < pages; ++pageNum) { + for(pageNum = sPageNum; pageNum < pages; ++pageNum) { status = jtagmkII_flash_clear_pagebuffer32(pgm); - if(status != 0) {lineno = __LINE__; goto eRR;} + if(status != 0) + gotoerr; - for(blocks=0; blocks<2; ++blocks) { - block_size = maxaddr - addr < (unsigned int) pgm->page_size? - maxaddr - addr: (unsigned int) pgm->page_size; + for(blocks = 0; blocks < 2; ++blocks) { + block_size = maxaddr - addr < (unsigned int) pgm->page_size? maxaddr - addr: (unsigned int) pgm->page_size; pmsg_debug("%s(): block_size at addr %d is %d\n", __func__, addr, block_size); u32_to_b4r(cmd + 6, m->offset + addr); @@ -3425,16 +3488,18 @@ static int jtagmkII_paged_write32(const PROGRAMMER *pgm, const AVRPART *p_unused memcpy(cmd + 10, m->buf + addr, block_size); status = jtagmkII_send(pgm, cmd, pgm->page_size + 10); - if(status<0) {lineno = __LINE__; goto eRR;} + if(status < 0) + gotoerr; status = jtagmkII_recv(pgm, &resp); - if (status<0) {lineno = __LINE__; goto eRR;} + if(status < 0) + gotoerr; - if (verbose >= MSG_DEBUG) { + if(verbose >= MSG_DEBUG) { msg_debug("\n"); jtagmkII_prmsg(pgm, resp, status); } else msg_notice2("0x%02x (%d bytes msg)\n", resp[0], status); - if (resp[0] != RSP_OK) { + if(resp[0] != RSP_OK) { pmsg_error("bad response to write memory command: %s\n", jtagmkII_get_rc(pgm, resp[0])); mmt_free(resp); mmt_free(cmd); @@ -3444,139 +3509,166 @@ static int jtagmkII_paged_write32(const PROGRAMMER *pgm, const AVRPART *p_unused addr += block_size; - } status = jtagmkII_flash_write_page32(pgm, pageNum); - if(status < 0) {lineno = __LINE__; goto eRR;} + if(status < 0) + gotoerr; } serial_recv_timeout = otimeout; - status = jtagmkII_reset32(pgm, AVR32_SET4RUNNING); // AVR32_SET4RUNNING | AVR32_RELEASE_JTAG - if(status < 0) {lineno = __LINE__; goto eRR;} + status = jtagmkII_reset32(pgm, AVR32_SET4RUNNING); // AVR32_SET4RUNNING | AVR32_RELEASE_JTAG + if(status < 0) + gotoerr; mmt_free(cmd); return addr; - eRR: - serial_recv_timeout = otimeout; - mmt_free(cmd); - pmsg_error("paged write failed at line %d (status=%x val=%lx)\n", lineno, status, val); - return -1; +eRR: + serial_recv_timeout = otimeout; + mmt_free(cmd); + pmsg_error("paged write failed at line %d (status=%x val=%lx)\n", lineno, status, val); + return -1; } - static int jtagmkII_flash_lock32(const PROGRAMMER *pgm, unsigned char lock, unsigned int page) { int status, lineno, i; - unsigned long val, cmd=0; + unsigned long val, cmd = 0; - for(i=0; i<256; ++i) { + for(i = 0; i < 256; ++i) { val = jtagmkII_read_SABaddr(pgm, AVR32_FLASHC_FSR, 0x05); - if(val == ERROR_SAB) continue; - if(val & AVR32_FLASHC_FSR_RDY) break; + if(val == ERROR_SAB) + continue; + if(val & AVR32_FLASHC_FSR_RDY) + break; } - if(val == ERROR_SAB) {lineno = __LINE__; goto eRR;} - if(!(val&AVR32_FLASHC_FSR_RDY)) {lineno = __LINE__; goto eRR;} // Flash better be ready + if(val == ERROR_SAB) + gotoerr; + if(!(val & AVR32_FLASHC_FSR_RDY)) + gotoerr; // Flash better be ready page <<= 8; - cmd = AVR32_FLASHC_FCMD_KEY | page | (lock ? AVR32_FLASHC_FCMD_LOCK : AVR32_FLASHC_FCMD_UNLOCK); + cmd = AVR32_FLASHC_FCMD_KEY | page | (lock? AVR32_FLASHC_FCMD_LOCK: AVR32_FLASHC_FCMD_UNLOCK); status = jtagmkII_write_SABaddr(pgm, AVR32_FLASHC_FCMD, 0x05, cmd); - if (status < 0) {lineno = __LINE__; goto eRR;} + if(status < 0) + gotoerr; return 0; - eRR: - pmsg_error("flash lock failed at line %d page %d cmd %8.8lx\n", lineno, page, cmd); +eRR: + pmsg_error("flash lock failed at line %d page %d cmd %8.8lx\n", lineno, page, cmd); return -1; } static int jtagmkII_flash_erase32(const PROGRAMMER *pgm, unsigned int page) { int status, lineno, i; - unsigned long val=0, cmd=0, err=0; + unsigned long val = 0, cmd = 0, err = 0; - for(i=0; i<256; ++i) { + for(i = 0; i < 256; ++i) { val = jtagmkII_read_SABaddr(pgm, AVR32_FLASHC_FSR, 0x05); - if(val == ERROR_SAB) continue; - if(val & AVR32_FLASHC_FSR_RDY) break; + if(val == ERROR_SAB) + continue; + if(val & AVR32_FLASHC_FSR_RDY) + break; } - if(val == ERROR_SAB) {lineno = __LINE__; goto eRR;} - if(!(val&AVR32_FLASHC_FSR_RDY)) {lineno = __LINE__; goto eRR;} // Flash better be ready + if(val == ERROR_SAB) + gotoerr; + if(!(val & AVR32_FLASHC_FSR_RDY)) + gotoerr; // Flash better be ready page <<= 8; cmd = AVR32_FLASHC_FCMD_KEY | page | AVR32_FLASHC_FCMD_ERASE_PAGE; status = jtagmkII_write_SABaddr(pgm, AVR32_FLASHC_FCMD, 0x05, cmd); - if (status < 0) {lineno = __LINE__; goto eRR;} + if(status < 0) + gotoerr; -//msg_error("ERASE %x -> %x\n", cmd, AVR32_FLASHC_FCMD); + // msg_error("ERASE %x -> %x\n", cmd, AVR32_FLASHC_FCMD); err = 0; - for(i=0; i<256; ++i) { + for(i = 0; i < 256; ++i) { val = jtagmkII_read_SABaddr(pgm, AVR32_FLASHC_FSR, 0x05); - if(val == ERROR_SAB) continue; + if(val == ERROR_SAB) + continue; err |= val; - if(val & AVR32_FLASHC_FSR_RDY) break; + if(val & AVR32_FLASHC_FSR_RDY) + break; } - if(val == ERROR_SAB) {lineno = __LINE__; goto eRR;} - if(!(val & AVR32_FLASHC_FSR_RDY)) {lineno = __LINE__; goto eRR;} - if(err & AVR32_FLASHC_FSR_ERR) {lineno = __LINE__; goto eRR;} + if(val == ERROR_SAB) + gotoerr; + if(!(val & AVR32_FLASHC_FSR_RDY)) + gotoerr; + if(err & AVR32_FLASHC_FSR_ERR) + gotoerr; return 0; - eRR: - pmsg_error("flash erase failed at line %d page %d cmd %8.8lx val %lx\n", lineno, page, cmd, val); - return -1; +eRR: + pmsg_error("flash erase failed at line %d page %d cmd %8.8lx val %lx\n", lineno, page, cmd, val); + return -1; } static int jtagmkII_flash_write_page32(const PROGRAMMER *pgm, unsigned int page) { int status, lineno, i; - unsigned long val=0, cmd, err; + unsigned long val = 0, cmd, err; page <<= 8; cmd = AVR32_FLASHC_FCMD_KEY | page | AVR32_FLASHC_FCMD_WRITE_PAGE; status = jtagmkII_write_SABaddr(pgm, AVR32_FLASHC_FCMD, 0x05, cmd); - if (status < 0) {lineno = __LINE__; goto eRR;} + if(status < 0) + gotoerr; err = 0; - for(i=0; i<256; ++i) { + for(i = 0; i < 256; ++i) { val = jtagmkII_read_SABaddr(pgm, AVR32_FLASHC_FSR, 0x05); - if(val == ERROR_SAB) continue; + if(val == ERROR_SAB) + continue; err |= val; - if(val & AVR32_FLASHC_FSR_RDY) break; + if(val & AVR32_FLASHC_FSR_RDY) + break; } - if(val == ERROR_SAB) {lineno = __LINE__; goto eRR;} - if(!(val & AVR32_FLASHC_FSR_RDY)) {lineno = __LINE__; goto eRR;} - if(err & AVR32_FLASHC_FSR_ERR) {lineno = __LINE__; goto eRR;} + if(val == ERROR_SAB) + gotoerr; + if(!(val & AVR32_FLASHC_FSR_RDY)) + gotoerr; + if(err & AVR32_FLASHC_FSR_ERR) + gotoerr; return 0; - eRR: - pmsg_error("flash write failed at line %d page %d cmd %8.8lx val %lx\n", lineno, page, cmd, val); - return -1; +eRR: + pmsg_error("flash write failed at line %d page %d cmd %8.8lx val %lx\n", lineno, page, cmd, val); + return -1; } static int jtagmkII_flash_clear_pagebuffer32(const PROGRAMMER *pgm) { int status, lineno, i; - unsigned long val=0, cmd, err; + unsigned long val = 0, cmd, err; cmd = AVR32_FLASHC_FCMD_KEY | AVR32_FLASHC_FCMD_CLEAR_PAGE_BUFFER; status = jtagmkII_write_SABaddr(pgm, AVR32_FLASHC_FCMD, 0x05, cmd); - if (status < 0) {lineno = __LINE__; goto eRR;} + if(status < 0) + gotoerr; err = 0; - for(i=0; i<256; ++i) { + for(i = 0; i < 256; ++i) { val = jtagmkII_read_SABaddr(pgm, AVR32_FLASHC_FSR, 0x05); - if(val == ERROR_SAB) continue; + if(val == ERROR_SAB) + continue; err |= val; - if(val & AVR32_FLASHC_FSR_RDY) break; + if(val & AVR32_FLASHC_FSR_RDY) + break; } - if(val == ERROR_SAB) {lineno = __LINE__; goto eRR;} - if(!(val & AVR32_FLASHC_FSR_RDY)) {lineno = __LINE__; goto eRR;} - if(err & AVR32_FLASHC_FSR_ERR) {lineno = __LINE__; goto eRR;} + if(val == ERROR_SAB) + gotoerr; + if(!(val & AVR32_FLASHC_FSR_RDY)) + gotoerr; + if(err & AVR32_FLASHC_FSR_ERR) + gotoerr; return 0; - eRR: - pmsg_error("clear page buffer failed at line %d cmd %8.8lx val %lx\n", lineno, cmd, val); - return -1; +eRR: + pmsg_error("clear page buffer failed at line %d cmd %8.8lx val %lx\n", lineno, cmd, val); + return -1; } // Periodic calls in terminal mode to keep the programmer jtagmkii_updi enabled @@ -3588,7 +3680,7 @@ static int jtagmkII_updi_term_keep_alive(const PROGRAMMER *pgm, const AVRPART *p jtagmkII_send(pgm, buf, 1); status = jtagmkII_recv(pgm, &resp); - if (status <= 0) { + if(status <= 0) { msg_notice2("\n"); pmsg_error("timeout/error communicating with programmer (status %d)\n", status); return -1; @@ -3596,7 +3688,7 @@ static int jtagmkII_updi_term_keep_alive(const PROGRAMMER *pgm, const AVRPART *p c = resp[0]; mmt_free(resp); - if (c != RSP_OK) { + if(c != RSP_OK) { pmsg_error("bad response to get_sync command: %s\n", jtagmkII_get_rc(pgm, c)); return -1; } @@ -3606,7 +3698,7 @@ static int jtagmkII_updi_term_keep_alive(const PROGRAMMER *pgm, const AVRPART *p // Read the signature if most recent operation was an erase or a write to ensure it finished static int jtagmkII_updi_end_programming(const PROGRAMMER *pgm, const AVRPART *p) { - return PDATA(pgm)->recently_written? avr_read(pgm, p, "signature", NULL): 0; + return my.recently_written? avr_read(pgm, p, "signature", NULL): 0; } #ifdef __OBJC__ @@ -3618,35 +3710,31 @@ const char jtagmkII_desc[] = "Atmel JTAG ICE mkII"; void jtagmkII_initpgm(PROGRAMMER *pgm) { strcpy(pgm->type, "JTAGMKII"); - /* - * mandatory functions - */ - pgm->initialize = jtagmkII_initialize; - pgm->display = jtagmkII_display; - pgm->enable = jtagmkII_enable; - pgm->disable = jtagmkII_disable; + // Mandatory functions + pgm->initialize = jtagmkII_initialize; + pgm->display = jtagmkII_display; + pgm->enable = jtagmkII_enable; + pgm->disable = jtagmkII_disable; pgm->program_enable = jtagmkII_program_enable_INFO; - pgm->chip_erase = jtagmkII_chip_erase; - pgm->open = jtagmkII_open; - pgm->close = jtagmkII_close; - pgm->read_byte = jtagmkII_read_byte; - pgm->write_byte = jtagmkII_write_byte; - - /* - * optional functions - */ - pgm->paged_write = jtagmkII_paged_write; - pgm->paged_load = jtagmkII_paged_load; - pgm->page_erase = jtagmkII_page_erase; - pgm->print_parms = jtagmkII_print_parms; + pgm->chip_erase = jtagmkII_chip_erase; + pgm->open = jtagmkII_open; + pgm->close = jtagmkII_close; + pgm->read_byte = jtagmkII_read_byte; + pgm->write_byte = jtagmkII_write_byte; + + // Optional functions + pgm->paged_write = jtagmkII_paged_write; + pgm->paged_load = jtagmkII_paged_load; + pgm->page_erase = jtagmkII_page_erase; + pgm->print_parms = jtagmkII_print_parms; pgm->set_sck_period = jtagmkII_set_sck_period; pgm->get_sck_period = jtagmkII_get_sck_period; pgm->parseextparams = jtagmkII_parseextparms; - pgm->setup = jtagmkII_setup; - pgm->teardown = jtagmkII_teardown; - pgm->read_chip_rev = jtagmkII_read_chip_rev; - pgm->page_size = 256; - pgm->flag = PGM_FL_IS_JTAG; + pgm->setup = jtagmkII_setup; + pgm->teardown = jtagmkII_teardown; + pgm->read_chip_rev = jtagmkII_read_chip_rev; + pgm->page_size = 256; + pgm->flag = PGM_FL_IS_JTAG; } const char jtagmkII_dw_desc[] = "Atmel JTAG ICE mkII in debugWire mode"; @@ -3654,30 +3742,26 @@ const char jtagmkII_dw_desc[] = "Atmel JTAG ICE mkII in debugWire mode"; void jtagmkII_dw_initpgm(PROGRAMMER *pgm) { strcpy(pgm->type, "JTAGMKII_DW"); - /* - * mandatory functions - */ - pgm->initialize = jtagmkII_initialize; - pgm->display = jtagmkII_display; - pgm->enable = jtagmkII_enable; - pgm->disable = jtagmkII_disable; + // Mandatory functions + pgm->initialize = jtagmkII_initialize; + pgm->display = jtagmkII_display; + pgm->enable = jtagmkII_enable; + pgm->disable = jtagmkII_disable; pgm->program_enable = jtagmkII_program_enable_INFO; - pgm->chip_erase = jtagmkII_chip_erase_dw; - pgm->open = jtagmkII_open_dw; - pgm->close = jtagmkII_close; - pgm->read_byte = jtagmkII_read_byte; - pgm->write_byte = jtagmkII_write_byte; - - /* - * optional functions - */ - pgm->paged_write = jtagmkII_paged_write; - pgm->paged_load = jtagmkII_paged_load; - pgm->print_parms = jtagmkII_print_parms; - pgm->setup = jtagmkII_setup; - pgm->teardown = jtagmkII_teardown; - pgm->page_size = 256; - pgm->flag = PGM_FL_IS_DW; + pgm->chip_erase = jtagmkII_chip_erase_dw; + pgm->open = jtagmkII_open_dw; + pgm->close = jtagmkII_close; + pgm->read_byte = jtagmkII_read_byte; + pgm->write_byte = jtagmkII_write_byte; + + // Optional functions + pgm->paged_write = jtagmkII_paged_write; + pgm->paged_load = jtagmkII_paged_load; + pgm->print_parms = jtagmkII_print_parms; + pgm->setup = jtagmkII_setup; + pgm->teardown = jtagmkII_teardown; + pgm->page_size = 256; + pgm->flag = PGM_FL_IS_DW; } const char jtagmkII_pdi_desc[] = "Atmel JTAG ICE mkII in PDI mode"; @@ -3685,32 +3769,28 @@ const char jtagmkII_pdi_desc[] = "Atmel JTAG ICE mkII in PDI mode"; void jtagmkII_pdi_initpgm(PROGRAMMER *pgm) { strcpy(pgm->type, "JTAGMKII_PDI"); - /* - * mandatory functions - */ - pgm->initialize = jtagmkII_initialize; - pgm->display = jtagmkII_display; - pgm->enable = jtagmkII_enable; - pgm->disable = jtagmkII_disable; + // Mandatory functions + pgm->initialize = jtagmkII_initialize; + pgm->display = jtagmkII_display; + pgm->enable = jtagmkII_enable; + pgm->disable = jtagmkII_disable; pgm->program_enable = jtagmkII_program_enable_INFO; - pgm->chip_erase = jtagmkII_chip_erase; - pgm->open = jtagmkII_open_pdi; - pgm->close = jtagmkII_close; - pgm->read_byte = jtagmkII_read_byte; - pgm->write_byte = jtagmkII_write_byte; - - /* - * optional functions - */ - pgm->paged_write = jtagmkII_paged_write; - pgm->paged_load = jtagmkII_paged_load; - pgm->page_erase = jtagmkII_page_erase; - pgm->print_parms = jtagmkII_print_parms; - pgm->setup = jtagmkII_setup; - pgm->teardown = jtagmkII_teardown; - pgm->read_chip_rev = jtagmkII_read_chip_rev; - pgm->page_size = 256; - pgm->flag = PGM_FL_IS_PDI; + pgm->chip_erase = jtagmkII_chip_erase; + pgm->open = jtagmkII_open_pdi; + pgm->close = jtagmkII_close; + pgm->read_byte = jtagmkII_read_byte; + pgm->write_byte = jtagmkII_write_byte; + + // Optional functions + pgm->paged_write = jtagmkII_paged_write; + pgm->paged_load = jtagmkII_paged_load; + pgm->page_erase = jtagmkII_page_erase; + pgm->print_parms = jtagmkII_print_parms; + pgm->setup = jtagmkII_setup; + pgm->teardown = jtagmkII_teardown; + pgm->read_chip_rev = jtagmkII_read_chip_rev; + pgm->page_size = 256; + pgm->flag = PGM_FL_IS_PDI; } const char jtagmkII_updi_desc[] = "Atmel JTAG ICE mkII in UPDI mode"; @@ -3718,35 +3798,31 @@ const char jtagmkII_updi_desc[] = "Atmel JTAG ICE mkII in UPDI mode"; void jtagmkII_updi_initpgm(PROGRAMMER *pgm) { strcpy(pgm->type, "JTAGMKII_UPDI"); - /* - * mandatory functions - */ - pgm->initialize = jtagmkII_initialize; - pgm->display = jtagmkII_display; - pgm->enable = jtagmkII_enable; - pgm->disable = jtagmkII_disable; + // Mandatory functions + pgm->initialize = jtagmkII_initialize; + pgm->display = jtagmkII_display; + pgm->enable = jtagmkII_enable; + pgm->disable = jtagmkII_disable; pgm->program_enable = jtagmkII_program_enable_INFO; - pgm->chip_erase = jtagmkII_chip_erase; - pgm->open = jtagmkII_open_pdi; - pgm->close = jtagmkII_close; - pgm->read_byte = jtagmkII_read_byte; - pgm->write_byte = jtagmkII_write_byte; - - /* - * optional functions - */ - pgm->paged_write = jtagmkII_paged_write; - pgm->paged_load = jtagmkII_paged_load; - pgm->page_erase = jtagmkII_page_erase; - pgm->print_parms = jtagmkII_print_parms; + pgm->chip_erase = jtagmkII_chip_erase; + pgm->open = jtagmkII_open_pdi; + pgm->close = jtagmkII_close; + pgm->read_byte = jtagmkII_read_byte; + pgm->write_byte = jtagmkII_write_byte; + + // Optional functions + pgm->paged_write = jtagmkII_paged_write; + pgm->paged_load = jtagmkII_paged_load; + pgm->page_erase = jtagmkII_page_erase; + pgm->print_parms = jtagmkII_print_parms; pgm->parseextparams = jtagmkII_parseextparms; - pgm->setup = jtagmkII_setup; - pgm->teardown = jtagmkII_teardown; - pgm->read_chip_rev = jtagmkII_read_chip_rev; - pgm->page_size = 256; - pgm->flag = PGM_FL_IS_PDI; - pgm->term_keep_alive= jtagmkII_updi_term_keep_alive; - pgm->end_programming= jtagmkII_updi_end_programming; + pgm->setup = jtagmkII_setup; + pgm->teardown = jtagmkII_teardown; + pgm->read_chip_rev = jtagmkII_read_chip_rev; + pgm->page_size = 256; + pgm->flag = PGM_FL_IS_PDI; + pgm->term_keep_alive = jtagmkII_updi_term_keep_alive; + pgm->end_programming = jtagmkII_updi_end_programming; } const char jtagmkII_dragon_desc[] = "Atmel AVR Dragon in JTAG mode"; @@ -3754,35 +3830,31 @@ const char jtagmkII_dragon_desc[] = "Atmel AVR Dragon in JTAG mode"; void jtagmkII_dragon_initpgm(PROGRAMMER *pgm) { strcpy(pgm->type, "DRAGON_JTAG"); - /* - * mandatory functions - */ - pgm->initialize = jtagmkII_initialize; - pgm->display = jtagmkII_display; - pgm->enable = jtagmkII_enable; - pgm->disable = jtagmkII_disable; + // Mandatory functions + pgm->initialize = jtagmkII_initialize; + pgm->display = jtagmkII_display; + pgm->enable = jtagmkII_enable; + pgm->disable = jtagmkII_disable; pgm->program_enable = jtagmkII_program_enable_INFO; - pgm->chip_erase = jtagmkII_chip_erase; - pgm->open = jtagmkII_dragon_open; - pgm->close = jtagmkII_close; - pgm->read_byte = jtagmkII_read_byte; - pgm->write_byte = jtagmkII_write_byte; - - /* - * optional functions - */ - pgm->paged_write = jtagmkII_paged_write; - pgm->paged_load = jtagmkII_paged_load; - pgm->page_erase = jtagmkII_page_erase; - pgm->print_parms = jtagmkII_print_parms; + pgm->chip_erase = jtagmkII_chip_erase; + pgm->open = jtagmkII_dragon_open; + pgm->close = jtagmkII_close; + pgm->read_byte = jtagmkII_read_byte; + pgm->write_byte = jtagmkII_write_byte; + + // Optional functions + pgm->paged_write = jtagmkII_paged_write; + pgm->paged_load = jtagmkII_paged_load; + pgm->page_erase = jtagmkII_page_erase; + pgm->print_parms = jtagmkII_print_parms; pgm->set_sck_period = jtagmkII_set_sck_period; pgm->get_sck_period = jtagmkII_get_sck_period; pgm->parseextparams = jtagmkII_parseextparms; - pgm->setup = jtagmkII_setup; - pgm->teardown = jtagmkII_teardown; - pgm->read_chip_rev = jtagmkII_read_chip_rev; - pgm->page_size = 256; - pgm->flag = PGM_FL_IS_JTAG; + pgm->setup = jtagmkII_setup; + pgm->teardown = jtagmkII_teardown; + pgm->read_chip_rev = jtagmkII_read_chip_rev; + pgm->page_size = 256; + pgm->flag = PGM_FL_IS_JTAG; } const char jtagmkII_dragon_dw_desc[] = "Atmel AVR Dragon in debugWire mode"; @@ -3790,30 +3862,26 @@ const char jtagmkII_dragon_dw_desc[] = "Atmel AVR Dragon in debugWire mode"; void jtagmkII_dragon_dw_initpgm(PROGRAMMER *pgm) { strcpy(pgm->type, "DRAGON_DW"); - /* - * mandatory functions - */ - pgm->initialize = jtagmkII_initialize; - pgm->display = jtagmkII_display; - pgm->enable = jtagmkII_enable; - pgm->disable = jtagmkII_disable; + // Mandatory functions + pgm->initialize = jtagmkII_initialize; + pgm->display = jtagmkII_display; + pgm->enable = jtagmkII_enable; + pgm->disable = jtagmkII_disable; pgm->program_enable = jtagmkII_program_enable_INFO; - pgm->chip_erase = jtagmkII_chip_erase_dw; - pgm->open = jtagmkII_dragon_open_dw; - pgm->close = jtagmkII_close; - pgm->read_byte = jtagmkII_read_byte; - pgm->write_byte = jtagmkII_write_byte; - - /* - * optional functions - */ - pgm->paged_write = jtagmkII_paged_write; - pgm->paged_load = jtagmkII_paged_load; - pgm->print_parms = jtagmkII_print_parms; - pgm->setup = jtagmkII_setup; - pgm->teardown = jtagmkII_teardown; - pgm->page_size = 256; - pgm->flag = PGM_FL_IS_DW; + pgm->chip_erase = jtagmkII_chip_erase_dw; + pgm->open = jtagmkII_dragon_open_dw; + pgm->close = jtagmkII_close; + pgm->read_byte = jtagmkII_read_byte; + pgm->write_byte = jtagmkII_write_byte; + + // Optional functions + pgm->paged_write = jtagmkII_paged_write; + pgm->paged_load = jtagmkII_paged_load; + pgm->print_parms = jtagmkII_print_parms; + pgm->setup = jtagmkII_setup; + pgm->teardown = jtagmkII_teardown; + pgm->page_size = 256; + pgm->flag = PGM_FL_IS_DW; } const char jtagmkII_avr32_desc[] = "Atmel JTAG ICE mkII in AVR32 mode"; @@ -3821,32 +3889,28 @@ const char jtagmkII_avr32_desc[] = "Atmel JTAG ICE mkII in AVR32 mode"; void jtagmkII_avr32_initpgm(PROGRAMMER *pgm) { strcpy(pgm->type, "JTAGMKII_AVR32"); - /* - * mandatory functions - */ - pgm->initialize = jtagmkII_initialize32; - pgm->display = jtagmkII_display; - pgm->enable = jtagmkII_enable; - pgm->disable = jtagmkII_disable; + // Mandatory functions + pgm->initialize = jtagmkII_initialize32; + pgm->display = jtagmkII_display; + pgm->enable = jtagmkII_enable; + pgm->disable = jtagmkII_disable; pgm->program_enable = jtagmkII_program_enable_INFO; - pgm->chip_erase = jtagmkII_chip_erase32; - pgm->open = jtagmkII_open32; - pgm->close = jtagmkII_close32; - pgm->read_byte = jtagmkII_read_byte; - pgm->write_byte = jtagmkII_write_byte; - - /* - * optional functions - */ - pgm->paged_write = jtagmkII_paged_write32; - pgm->paged_load = jtagmkII_paged_load32; - pgm->print_parms = jtagmkII_print_parms; - //pgm->set_sck_period = jtagmkII_set_sck_period; - //pgm->parseextparams = jtagmkII_parseextparms; - pgm->setup = jtagmkII_setup; - pgm->teardown = jtagmkII_teardown; - pgm->page_size = 256; - pgm->flag = PGM_FL_IS_JTAG; + pgm->chip_erase = jtagmkII_chip_erase32; + pgm->open = jtagmkII_open32; + pgm->close = jtagmkII_close32; + pgm->read_byte = jtagmkII_read_byte; + pgm->write_byte = jtagmkII_write_byte; + + // Optional functions + pgm->paged_write = jtagmkII_paged_write32; + pgm->paged_load = jtagmkII_paged_load32; + pgm->print_parms = jtagmkII_print_parms; + // pgm->set_sck_period = jtagmkII_set_sck_period; + // pgm->parseextparams = jtagmkII_parseextparms; + pgm->setup = jtagmkII_setup; + pgm->teardown = jtagmkII_teardown; + pgm->page_size = 256; + pgm->flag = PGM_FL_IS_JTAG; } const char jtagmkII_dragon_pdi_desc[] = "Atmel AVR Dragon in PDI mode"; @@ -3854,30 +3918,26 @@ const char jtagmkII_dragon_pdi_desc[] = "Atmel AVR Dragon in PDI mode"; void jtagmkII_dragon_pdi_initpgm(PROGRAMMER *pgm) { strcpy(pgm->type, "DRAGON_PDI"); - /* - * mandatory functions - */ - pgm->initialize = jtagmkII_initialize; - pgm->display = jtagmkII_display; - pgm->enable = jtagmkII_enable; - pgm->disable = jtagmkII_disable; + // Mandatory functions + pgm->initialize = jtagmkII_initialize; + pgm->display = jtagmkII_display; + pgm->enable = jtagmkII_enable; + pgm->disable = jtagmkII_disable; pgm->program_enable = jtagmkII_program_enable_INFO; - pgm->chip_erase = jtagmkII_chip_erase; - pgm->open = jtagmkII_dragon_open_pdi; - pgm->close = jtagmkII_close; - pgm->read_byte = jtagmkII_read_byte; - pgm->write_byte = jtagmkII_write_byte; - - /* - * optional functions - */ - pgm->paged_write = jtagmkII_paged_write; - pgm->paged_load = jtagmkII_paged_load; - pgm->page_erase = jtagmkII_page_erase; - pgm->print_parms = jtagmkII_print_parms; - pgm->setup = jtagmkII_setup; - pgm->teardown = jtagmkII_teardown; - pgm->read_chip_rev = jtagmkII_read_chip_rev; - pgm->page_size = 256; - pgm->flag = PGM_FL_IS_PDI; + pgm->chip_erase = jtagmkII_chip_erase; + pgm->open = jtagmkII_dragon_open_pdi; + pgm->close = jtagmkII_close; + pgm->read_byte = jtagmkII_read_byte; + pgm->write_byte = jtagmkII_write_byte; + + // Optional functions + pgm->paged_write = jtagmkII_paged_write; + pgm->paged_load = jtagmkII_paged_load; + pgm->page_erase = jtagmkII_page_erase; + pgm->print_parms = jtagmkII_print_parms; + pgm->setup = jtagmkII_setup; + pgm->teardown = jtagmkII_teardown; + pgm->read_chip_rev = jtagmkII_read_chip_rev; + pgm->page_size = 256; + pgm->flag = PGM_FL_IS_PDI; } diff --git a/src/jtagmkII.h b/src/jtagmkII.h index ec8d4bc9c..7608acc7f 100644 --- a/src/jtagmkII.h +++ b/src/jtagmkII.h @@ -23,41 +23,37 @@ extern "C" { #endif -int jtagmkII_send(const PROGRAMMER *pgm, unsigned char *data, size_t len); -int jtagmkII_recv(const PROGRAMMER *pgm, unsigned char **msg); -void jtagmkII_close(PROGRAMMER * pgm); -int jtagmkII_getsync(const PROGRAMMER *pgm, int mode); -int jtagmkII_getparm(const PROGRAMMER *pgm, unsigned char parm, - unsigned char * value); - -extern const char jtagmkII_desc[]; -extern const char jtagmkII_avr32_desc[]; -extern const char jtagmkII_dw_desc[]; -extern const char jtagmkII_pdi_desc[]; -extern const char jtagmkII_updi_desc[]; -extern const char jtagmkII_dragon_desc[]; -extern const char jtagmkII_dragon_dw_desc[]; -extern const char jtagmkII_dragon_pdi_desc[]; -void jtagmkII_initpgm(PROGRAMMER *pgm); -void jtagmkII_avr32_initpgm(PROGRAMMER *pgm); -void jtagmkII_dw_initpgm(PROGRAMMER *pgm); -void jtagmkII_pdi_initpgm(PROGRAMMER *pgm); -void jtagmkII_updi_initpgm(PROGRAMMER *pgm); -void jtagmkII_dragon_initpgm(PROGRAMMER *pgm); -void jtagmkII_dragon_dw_initpgm(PROGRAMMER *pgm); -void jtagmkII_dragon_pdi_initpgm(PROGRAMMER *pgm); - -/* - * These functions are referenced from stk500v2.c for JTAG ICE mkII - * and AVR Dragon programmers running in one of the STK500v2 - * modi. - */ -void jtagmkII_setup(PROGRAMMER * pgm); -void jtagmkII_teardown(PROGRAMMER * pgm); + int jtagmkII_send(const PROGRAMMER *pgm, unsigned char *data, size_t len); + int jtagmkII_recv(const PROGRAMMER *pgm, unsigned char **msg); + void jtagmkII_close(PROGRAMMER *pgm); + int jtagmkII_getsync(const PROGRAMMER *pgm, int mode); + int jtagmkII_getparm(const PROGRAMMER *pgm, unsigned char parm, unsigned char *value); + + extern const char jtagmkII_desc[]; + extern const char jtagmkII_avr32_desc[]; + extern const char jtagmkII_dw_desc[]; + extern const char jtagmkII_pdi_desc[]; + extern const char jtagmkII_updi_desc[]; + extern const char jtagmkII_dragon_desc[]; + extern const char jtagmkII_dragon_dw_desc[]; + extern const char jtagmkII_dragon_pdi_desc[]; + void jtagmkII_initpgm(PROGRAMMER *pgm); + void jtagmkII_avr32_initpgm(PROGRAMMER *pgm); + void jtagmkII_dw_initpgm(PROGRAMMER *pgm); + void jtagmkII_pdi_initpgm(PROGRAMMER *pgm); + void jtagmkII_updi_initpgm(PROGRAMMER *pgm); + void jtagmkII_dragon_initpgm(PROGRAMMER *pgm); + void jtagmkII_dragon_dw_initpgm(PROGRAMMER *pgm); + void jtagmkII_dragon_pdi_initpgm(PROGRAMMER *pgm); + + /* + * These functions are referenced from stk500v2.c for JTAG ICE mkII and AVR + * Dragon programmers running in one of the STK500v2 modi. + */ + void jtagmkII_setup(PROGRAMMER *pgm); + void jtagmkII_teardown(PROGRAMMER *pgm); #ifdef __cplusplus } #endif - #endif - diff --git a/src/jtagmkII_private.h b/src/jtagmkII_private.h index 3c581d8f6..9a01b86f7 100644 --- a/src/jtagmkII_private.h +++ b/src/jtagmkII_private.h @@ -17,17 +17,17 @@ * along with this program. If not, see . */ - /* * JTAG ICE mkII definitions * Taken from Appnote AVR067 */ #if !defined(JTAGMKII_PRIVATE_EXPORTED) + /* - * Communication with the JTAG ICE works in frames. The protocol - * somewhat resembles the STK500v2 protocol, yet it is sufficiently - * different to prevent a direct code reuse. :-( + * Communication with the JTAG ICE works in frames. The protocol somewhat + * resembles the STK500v2 protocol, yet it is sufficiently different to prevent + * a direct code reuse. :-( * * Frame format: * @@ -60,18 +60,16 @@ #define TOKEN 0x0e /* - * Max message size we are willing to accept. Prevents us from trying - * to allocate too much VM in case we received a nonsensical packet - * length. We have to allocate the buffer as soon as we've got the - * length information (and thus have to trust that information by that - * time at first), as the final CRC check can only be done once the - * entire packet came it. + * Max message size we are willing to accept. Prevents us from trying to + * allocate too much VM in case we received a nonsensical packet length. We + * have to allocate the buffer as soon as we've got the length information (and + * thus have to trust that information by that time at first), as the final CRC + * check can only be done once the entire packet came it. */ #define MAX_MESSAGE 100000 +#endif // JTAGMKII_PRIVATE_EXPORTED -#endif /* JTAGMKII_PRIVATE_EXPORTED */ - -/* ICE command codes */ +// ICE command codes #define CMND_SIGN_OFF 0x00 #define CMND_GET_SIGN_ON 0x01 #define CMND_SET_PARAMETER 0x02 @@ -108,10 +106,9 @@ #define CMND_WRITE_MEMORY32 0x2D #define CMND_ISP_PACKET 0x2F #define CMND_XMEGA_ERASE 0x34 -#define CMND_SET_XMEGA_PARAMS 0x36 // undocumented in AVR067 - +#define CMND_SET_XMEGA_PARAMS 0x36 // Undocumented in AVR067 -/* ICE responses */ +// ICE responses #define RSP_OK 0x80 #define RSP_PARAMETER 0x81 #define RSP_MEMORY 0x82 @@ -135,7 +132,7 @@ #define RSP_DEBUGWIRE_SYNC_FAILED 0xAC #define RSP_ILLEGAL_POWER_STATE 0xAD -/* ICE events */ +// ICE events #define EVT_BREAK 0xE0 #define EVT_RUN 0xE1 #define EVT_ERROR_PHY_FORCE_BREAK_TIMEOUT 0xE2 @@ -164,69 +161,72 @@ #define EVT_ERROR_PHY_OPT_RECEIVED_BREAK 0xFA #define EVT_RESULT_PHY_NO_ACTIVITY 0xFB -/* memories for CMND_{READ,WRITE}_MEMORY */ -#define MTYPE_IO_SHADOW 0x30 /* cached IO registers? */ -#define MTYPE_SRAM 0x20 /* target's SRAM or [ext.] IO registers */ -#define MTYPE_EEPROM 0x22 /* EEPROM, what way? */ -#define MTYPE_EVENT 0x60 /* ICE event memory */ -#define MTYPE_SPM 0xA0 /* flash through LPM/SPM */ -#define MTYPE_FLASH_PAGE 0xB0 /* flash in programming mode */ -#define MTYPE_EEPROM_PAGE 0xB1 /* EEPROM in programming mode */ -#define MTYPE_FUSE_BITS 0xB2 /* fuse bits in programming mode */ -#define MTYPE_LOCK_BITS 0xB3 /* lock bits in programming mode */ -#define MTYPE_SIGN_JTAG 0xB4 /* signature in programming mode */ -#define MTYPE_OSCCAL_BYTE 0xB5 /* osccal cells in programming mode */ -#define MTYPE_CAN 0xB6 /* CAN mailbox */ -#define MTYPE_FLASH 0xc0 /* xmega (app.) flash - undocumented in AVR067 */ -#define MTYPE_BOOT_FLASH 0xc1 /* xmega boot flash - undocumented in AVR067 */ -#define MTYPE_EEPROM_XMEGA 0xc4 /* xmega EEPROM in debug mode - undocumented in AVR067 */ -#define MTYPE_USERSIG 0xc5 /* xmega user signature - undocumented in AVR067 */ -#define MTYPE_PRODSIG 0xc6 /* xmega production signature - undocumented in AVR067 */ +// Memories for CMND_{READ,WRITE}_MEMORY +#define MTYPE_IO_SHADOW 0x30 // Cached IO registers? +#define MTYPE_SRAM 0x20 // Target's SRAM or [ext.] IO registers +#define MTYPE_EEPROM 0x22 // EEPROM, what way? +#define MTYPE_EVENT 0x60 // ICE event memory +#define MTYPE_SPM 0xA0 // Flash through LPM/SPM +#define MTYPE_FLASH_PAGE 0xB0 // Flash in programming mode +#define MTYPE_EEPROM_PAGE 0xB1 // EEPROM in programming mode +#define MTYPE_FUSE_BITS 0xB2 // Fuse bits in programming mode +#define MTYPE_LOCK_BITS 0xB3 // Lock bits in programming mode +#define MTYPE_SIGN_JTAG 0xB4 // Signature in programming mode +#define MTYPE_OSCCAL_BYTE 0xB5 // Osccal cells in programming mode +#define MTYPE_CAN 0xB6 // CAN mailbox +#define MTYPE_FLASH 0xc0 // Xmega (app.) flash - undocumented in AVR067 +#define MTYPE_BOOT_FLASH 0xc1 // Xmega boot flash - undocumented in AVR067 +#define MTYPE_EEPROM_XMEGA 0xc4 // Xmega EEPROM in debug mode - undocumented in AVR067 +#define MTYPE_USERSIG 0xc5 // Xmega user signature - undocumented in AVR067 +#define MTYPE_PRODSIG 0xc6 // Xmega production signature - undocumented in AVR067 -/* (some) ICE parameters, for CMND_{GET,SET}_PARAMETER */ +// (Some) ICE parameters, for CMND_{GET,SET}_PARAMETER #define PAR_HW_VERSION 0x01 #define PAR_FW_VERSION 0x02 #define PAR_EMULATOR_MODE 0x03 -# define EMULATOR_MODE_DEBUGWIRE 0x00 -# define EMULATOR_MODE_JTAG 0x01 -# define EMULATOR_MODE_HV 0x02 /* HVSP or PP mode of AVR Dragon */ -# define EMULATOR_MODE_SPI 0x03 -# define EMULATOR_MODE_JTAG_AVR32 0x04 -# define EMULATOR_MODE_JTAG_XMEGA 0x05 -# define EMULATOR_MODE_PDI 0x06 +#define EMULATOR_MODE_DEBUGWIRE 0x00 +#define EMULATOR_MODE_JTAG 0x01 +#define EMULATOR_MODE_HV 0x02 // HVSP or PP mode of AVR Dragon +#define EMULATOR_MODE_SPI 0x03 +#define EMULATOR_MODE_JTAG_AVR32 0x04 +#define EMULATOR_MODE_JTAG_XMEGA 0x05 +#define EMULATOR_MODE_PDI 0x06 #define PAR_IREG 0x04 #define PAR_BAUD_RATE 0x05 -# define PAR_BAUD_2400 0x01 -# define PAR_BAUD_4800 0x02 -# define PAR_BAUD_9600 0x03 -# define PAR_BAUD_19200 0x04 /* default */ -# define PAR_BAUD_38400 0x05 -# define PAR_BAUD_57600 0x06 -# define PAR_BAUD_115200 0x07 -# define PAR_BAUD_14400 0x08 -/* Extension to jtagmkII protocol: extra baud rates, standard series. */ -# define PAR_BAUD_153600 0x09 -# define PAR_BAUD_230400 0x0A -# define PAR_BAUD_460800 0x0B -# define PAR_BAUD_921600 0x0C -/* Extension to jtagmkII protocol: extra baud rates, binary series. */ -# define PAR_BAUD_128000 0x0D -# define PAR_BAUD_256000 0x0E -# define PAR_BAUD_512000 0x0F -# define PAR_BAUD_1024000 0x10 -/* Extension to jtagmkII protocol: extra baud rates, decimal series. */ -# define PAR_BAUD_150000 0x11 -# define PAR_BAUD_200000 0x12 -# define PAR_BAUD_250000 0x13 -# define PAR_BAUD_300000 0x14 -# define PAR_BAUD_400000 0x15 -# define PAR_BAUD_500000 0x16 -# define PAR_BAUD_600000 0x17 -# define PAR_BAUD_666666 0x18 -# define PAR_BAUD_1000000 0x19 -# define PAR_BAUD_1500000 0x1A -# define PAR_BAUD_2000000 0x1B -# define PAR_BAUD_3000000 0x1C +#define PAR_BAUD_2400 0x01 +#define PAR_BAUD_4800 0x02 +#define PAR_BAUD_9600 0x03 +#define PAR_BAUD_19200 0x04 // Default +#define PAR_BAUD_38400 0x05 +#define PAR_BAUD_57600 0x06 +#define PAR_BAUD_115200 0x07 +#define PAR_BAUD_14400 0x08 + +// Extension to jtagmkII protocol: extra baud rates, standard series +#define PAR_BAUD_153600 0x09 +#define PAR_BAUD_230400 0x0A +#define PAR_BAUD_460800 0x0B +#define PAR_BAUD_921600 0x0C + +// Extension to jtagmkII protocol: extra baud rates, binary series +#define PAR_BAUD_128000 0x0D +#define PAR_BAUD_256000 0x0E +#define PAR_BAUD_512000 0x0F +#define PAR_BAUD_1024000 0x10 + +// Extension to jtagmkII protocol: extra baud rates, decimal series +#define PAR_BAUD_150000 0x11 +#define PAR_BAUD_200000 0x12 +#define PAR_BAUD_250000 0x13 +#define PAR_BAUD_300000 0x14 +#define PAR_BAUD_400000 0x15 +#define PAR_BAUD_500000 0x16 +#define PAR_BAUD_600000 0x17 +#define PAR_BAUD_666666 0x18 +#define PAR_BAUD_1000000 0x19 +#define PAR_BAUD_1500000 0x1A +#define PAR_BAUD_2000000 0x1B +#define PAR_BAUD_3000000 0x1C #define PAR_OCD_VTARGET 0x06 #define PAR_OCD_JTAG_CLK 0x07 #define PAR_OCD_BREAK_CAUSE 0x08 @@ -248,9 +248,9 @@ #define PAR_PSB1 0x18 #define PAR_PROTOCOL_DEBUG_EVENT 0x19 #define PAR_MCU_STATE 0x1A -# define STOPPED 0x00 -# define RUNNING 0x01 -# define PROGRAMMING 0x02 +#define STOPPED 0x00 +#define RUNNING 0x01 +#define PROGRAMMING 0x02 #define PAR_DAISY_CHAIN_INFO 0x1B #define PAR_BOOT_ADDRESS 0x1C #define PAR_TARGET_SIGNATURE 0x1D @@ -264,19 +264,19 @@ #define PAR_INTERCOMMUNICATION_RX_FAILURES 0x43 #define PAR_CRC_ERRORS 0x44 #define PAR_POWER_SOURCE 0x45 -# define POWER_EXTERNAL 0x00 -# define POWER_USB 0x01 +#define POWER_EXTERNAL 0x00 +#define POWER_USB 0x01 #define PAR_CAN_FLAG 0x22 -# define DONT_READ_CAN_MAILBOX 0x00 -# define READ_CAN_MAILBOX 0x01 +#define DONT_READ_CAN_MAILBOX 0x00 +#define READ_CAN_MAILBOX 0x01 #define PAR_ENABLE_IDR_IN_RUN_MODE 0x23 -# define ACCESS_OSCCAL 0x00 -# define ACCESS_IDR 0x01 +#define ACCESS_OSCCAL 0x00 +#define ACCESS_IDR 0x01 #define PAR_ALLOW_PAGEPROGRAMMING_IN_SCANCHAIN 0x24 -# define PAGEPROG_NOT_ALLOWED 0x00 -# define PAGEPROG_ALLOWED 0x01 +#define PAGEPROG_NOT_ALLOWED 0x00 +#define PAGEPROG_ALLOWED 0x01 -/* Xmega erase memories for CMND_XMEGA_ERASE */ +// Xmega erase memories for CMND_XMEGA_ERASE #define XMEGA_ERASE_CHIP 0x00 #define XMEGA_ERASE_APP 0x01 #define XMEGA_ERASE_BOOT 0x02 @@ -286,127 +286,116 @@ #define XMEGA_ERASE_EEPROM_PAGE 0x06 #define XMEGA_ERASE_USERSIG 0x07 -/* AVR32 related definitions */ -#define AVR32_FLASHC_FCR 0xFFFE1400 -#define AVR32_FLASHC_FCMD 0xFFFE1404 -#define AVR32_FLASHC_FCMD_KEY 0xA5000000 -#define AVR32_FLASHC_FCMD_WRITE_PAGE 1 -#define AVR32_FLASHC_FCMD_ERASE_PAGE 2 -#define AVR32_FLASHC_FCMD_CLEAR_PAGE_BUFFER 3 -#define AVR32_FLASHC_FCMD_LOCK 4 -#define AVR32_FLASHC_FCMD_UNLOCK 5 -#define AVR32_FLASHC_FSR 0xFFFE1408 -#define AVR32_FLASHC_FSR_RDY 0x00000001 -#define AVR32_FLASHC_FSR_ERR 0x00000008 -#define AVR32_FLASHC_FGPFRHI 0xFFFE140C -#define AVR32_FLASHC_FGPFRLO 0xFFFE1410 +// AVR32 related definitions +#define AVR32_FLASHC_FCR 0xFFFE1400 +#define AVR32_FLASHC_FCMD 0xFFFE1404 +#define AVR32_FLASHC_FCMD_KEY 0xA5000000 +#define AVR32_FLASHC_FCMD_WRITE_PAGE 1 +#define AVR32_FLASHC_FCMD_ERASE_PAGE 2 +#define AVR32_FLASHC_FCMD_CLEAR_PAGE_BUFFER 3 +#define AVR32_FLASHC_FCMD_LOCK 4 +#define AVR32_FLASHC_FCMD_UNLOCK 5 +#define AVR32_FLASHC_FSR 0xFFFE1408 +#define AVR32_FLASHC_FSR_RDY 0x00000001 +#define AVR32_FLASHC_FSR_ERR 0x00000008 +#define AVR32_FLASHC_FGPFRHI 0xFFFE140C +#define AVR32_FLASHC_FGPFRLO 0xFFFE1410 -#define AVR32_DC 0x00000008 -#define AVR32_DS 0x00000010 -#define AVR32_DINST 0x00000104 -#define AVR32_DCCPU 0x00000110 -#define AVR32_DCEMU 0x00000114 -#define AVR32_DCSR 0x00000118 +#define AVR32_DC 0x00000008 +#define AVR32_DS 0x00000010 +#define AVR32_DINST 0x00000104 +#define AVR32_DCCPU 0x00000110 +#define AVR32_DCEMU 0x00000114 +#define AVR32_DCSR 0x00000118 -#define AVR32_DC_ABORT 0x80000000 -#define AVR32_DC_RESET 0x40000000 -#define AVR32_DC_DBE 0x00002000 -#define AVR32_DC_DBR 0x00001000 +#define AVR32_DC_ABORT 0x80000000 +#define AVR32_DC_RESET 0x40000000 +#define AVR32_DC_DBE 0x00002000 +#define AVR32_DC_DBR 0x00001000 #define AVR32_RESET_READ 0x0001 #define AVR32_RESET_WRITE 0x0002 #define AVR32_RESET_CHIP_ERASE 0x0004 #define AVR32_SET4RUNNING 0x0008 -//#define AVR32_RESET_COMMON (AVR32_RESET_READ | AVR32_RESET_WRITE | AVR32_RESET_CHIP_ERASE ) +// #define AVR32_RESET_COMMON (AVR32_RESET_READ | AVR32_RESET_WRITE | AVR32_RESET_CHIP_ERASE) #define DATA_OFFSET 0x1000000 -typedef enum -{ +typedef enum { RTS_MODE_DEFAULT, RTS_MODE_LOW, RTS_MODE_HIGH } jtagmkii_rts_mode; #if !defined(JTAGMKII_PRIVATE_EXPORTED) + /* - * In appnote AVR067, struct device_descriptor is written with - * int/long field types. We cannot use them directly, as they were - * neither properly aligned for portability, nor did they care for - * endianness issues. We thus use arrays of unsigned chars, plus - * conversion macros. + * In appnote AVR067, struct device_descriptor is written with int/long field + * types. We cannot use them directly, as they were neither properly aligned + * for portability, nor did they care for endianness issues. We thus use + * arrays of unsigned chars, plus conversion macros. */ -struct device_descriptor -{ - unsigned char ucReadIO[8]; /*LSB = IOloc 0, MSB = IOloc63 */ - unsigned char ucReadIOShadow[8]; /*LSB = IOloc 0, MSB = IOloc63 */ - unsigned char ucWriteIO[8]; /*LSB = IOloc 0, MSB = IOloc63 */ - unsigned char ucWriteIOShadow[8]; /*LSB = IOloc 0, MSB = IOloc63 */ - unsigned char ucReadExtIO[52]; /*LSB = IOloc 96, MSB = IOloc511 */ - unsigned char ucReadIOExtShadow[52]; /*LSB = IOloc 96, MSB = IOloc511 */ - unsigned char ucWriteExtIO[52]; /*LSB = IOloc 96, MSB = IOloc511 */ - unsigned char ucWriteIOExtShadow[52];/*LSB = IOloc 96, MSB = IOloc511 */ - unsigned char ucIDRAddress; /*IDR address */ - unsigned char ucSPMCRAddress; /*SPMCR Register address and dW BasePC */ - unsigned char ucRAMPZAddress; /*RAMPZ Register address in SRAM I/O */ - /*space */ - unsigned char uiFlashPageSize[2]; /*Device Flash Page Size, Size = */ - /*2 exp ucFlashPageSize */ - unsigned char ucEepromPageSize; /*Device Eeprom Page Size in bytes */ - unsigned char ulBootAddress[4]; /*Device Boot Loader Start Address */ - unsigned char uiUpperExtIOLoc[2]; /*Topmost (last) extended I/O */ - /*location, 0 if no external I/O */ - unsigned char ulFlashSize[4]; /*Device Flash Size */ - unsigned char ucEepromInst[20]; /*Instructions for W/R EEPROM */ - unsigned char ucFlashInst[3]; /*Instructions for W/R FLASH */ - unsigned char ucSPHaddr; /* stack pointer high */ - unsigned char ucSPLaddr; /* stack pointer low */ - /* new as of 16-02-2004 */ - unsigned char uiFlashpages[2]; /* number of pages in flash */ - unsigned char ucDWDRAddress; /* DWDR register address */ - unsigned char ucDWBasePC; /* base/mask value of the PC */ - /* new as of 30-04-2004 */ - unsigned char ucAllowFullPageBitstream; /* FALSE on ALL new */ - /*parts */ - unsigned char uiStartSmallestBootLoaderSection[2]; /* */ - /* new as of 18-10-2004 */ - unsigned char EnablePageProgramming; /* For JTAG parts only, */ - /* default TRUE */ - unsigned char ucCacheType; /* CacheType_Normal 0x00, */ - /* CacheType_CAN 0x01, */ - /* CacheType_HEIMDALL 0x02 */ - /* new as of 27-10-2004 */ - unsigned char uiSramStartAddr[2]; /* Start of SRAM */ - unsigned char ucResetType; /* Selects reset type. ResetNormal = 0x00 */ - /* ResetAT76CXXX = 0x01 */ - unsigned char ucPCMaskExtended; /* For parts with extended PC */ - unsigned char ucPCMaskHigh; /* PC high mask */ - unsigned char ucEindAddress; /* Selects reset type. [EIND address...] */ - /* new as of early 2005, firmware 4.x */ - unsigned char EECRAddress[2]; /* EECR memory-mapped IO address */ +struct device_descriptor { + unsigned char ucReadIO[8]; // LSB = IOloc 0, MSB = IOloc63 + unsigned char ucReadIOShadow[8]; // LSB = IOloc 0, MSB = IOloc63 + unsigned char ucWriteIO[8]; // LSB = IOloc 0, MSB = IOloc63 + unsigned char ucWriteIOShadow[8]; // LSB = IOloc 0, MSB = IOloc63 + unsigned char ucReadExtIO[52]; // LSB = IOloc 96, MSB = IOloc511 + unsigned char ucReadIOExtShadow[52]; // LSB = IOloc 96, MSB = IOloc511 + unsigned char ucWriteExtIO[52]; // LSB = IOloc 96, MSB = IOloc511 + unsigned char ucWriteIOExtShadow[52]; // LSB = IOloc 96, MSB = IOloc511 + unsigned char ucIDRAddress; // IDR address + unsigned char ucSPMCRAddress; // SPMCR Register address and dW BasePC + unsigned char ucRAMPZAddress; // Rampz Register address in SRAM I/O Space + unsigned char uiFlashPageSize[2]; // Device Flash Page Size, Size = 2 exp ucFlashPageSize + unsigned char ucEepromPageSize; // Device Eeprom Page Size in bytes + unsigned char ulBootAddress[4]; // Device Boot Loader Start Address + unsigned char uiUpperExtIOLoc[2]; // Topmost (last) extended I/O location, 0 if no external I/O + unsigned char ulFlashSize[4]; // Device Flash Size + unsigned char ucEepromInst[20]; // Instructions for W/R EEPROM + unsigned char ucFlashInst[3]; // Instructions for W/R FLASH + unsigned char ucSPHaddr; // Stack pointer high + unsigned char ucSPLaddr; // Stack pointer low; new as of 16-02-2004 + unsigned char uiFlashpages[2]; // Number of pages in flash + unsigned char ucDWDRAddress; // DWDR register address + unsigned char ucDWBasePC; // Base/mask value of the PC; new as of 30-04-2004 + unsigned char ucAllowFullPageBitstream; // False on ALL new parts + unsigned char uiStartSmallestBootLoaderSection[2]; + // New as of 18-10-2004 + unsigned char EnablePageProgramming; // For JTAG parts only + // Default TRUE + unsigned char ucCacheType; // CacheType_Normal 0x00, CacheType_CAN 0x01, CacheType_HEIMDALL 0x02 + // New as of 27-10-2004 + unsigned char uiSramStartAddr[2]; // Start of SRAM + unsigned char ucResetType; // Selects reset type, ResetNormal = 0x00, ResetAT76CXXX = 0x01 + unsigned char ucPCMaskExtended; // For parts with extended PC + unsigned char ucPCMaskHigh; // PC high mask + unsigned char ucEindAddress; // Selects reset type [EIND address...] + // New as of early 2005, firmware 4.x + unsigned char EECRAddress[2]; // EECR memory-mapped IO address }; -/* New Xmega device descriptor, for firmware version 7 and above */ +// New Xmega device descriptor, for firmware version 7 and above struct xmega_device_desc { - unsigned char whatever[2]; // cannot guess; must be 0x0002 - unsigned char datalen; // length of the following data, = 47 - unsigned char nvm_app_offset[4]; // NVM offset for application flash - unsigned char nvm_boot_offset[4]; // NVM offset for boot flash - unsigned char nvm_eeprom_offset[4]; // NVM offset for EEPROM - unsigned char nvm_fuse_offset[4]; // NVM offset for fuses - unsigned char nvm_lock_offset[4]; // NVM offset for lock bits - unsigned char nvm_user_sig_offset[4]; // NVM offset for user signature row - unsigned char nvm_prod_sig_offset[4]; // NVM offset for production sign. row - unsigned char nvm_data_offset[4]; // NVM offset for data memory (SRAM + IO) - unsigned char app_size[4]; // size of application flash - unsigned char boot_size[2]; // size of boot flash - unsigned char flash_page_size[2]; // flash page size - unsigned char eeprom_size[2]; // size of EEPROM - unsigned char eeprom_page_size; // EEPROM page size - unsigned char nvm_base_addr[2]; // IO space base address of NVM controller - unsigned char mcu_base_addr[2]; // IO space base address of MCU control + unsigned char whatever[2]; // Cannot guess; must be 0x0002 + unsigned char datalen; // Length of the following data, = 47 + unsigned char nvm_app_offset[4]; // NVM offset for application flash + unsigned char nvm_boot_offset[4]; // NVM offset for boot flash + unsigned char nvm_eeprom_offset[4]; // NVM offset for EEPROM + unsigned char nvm_fuse_offset[4]; // NVM offset for fuses + unsigned char nvm_lock_offset[4]; // NVM offset for lock bits + unsigned char nvm_user_sig_offset[4]; // NVM offset for user signature row + unsigned char nvm_prod_sig_offset[4]; // NVM offset for production sign. row + unsigned char nvm_data_offset[4]; // NVM offset for data memory (SRAM + IO) + unsigned char app_size[4]; // Size of application flash + unsigned char boot_size[2]; // Size of boot flash + unsigned char flash_page_size[2]; // Flash page size + unsigned char eeprom_size[2]; // Size of EEPROM + unsigned char eeprom_page_size; // EEPROM page size + unsigned char nvm_base_addr[2]; // IO space base address of NVM controller + unsigned char mcu_base_addr[2]; // IO space base address of MCU control }; -#endif /* JTAGMKII_PRIVATE_EXPORTED */ +#endif // JTAGMKII_PRIVATE_EXPORTED /* return code from jtagmkII_getsync() to indicate a "graceful" * failure, i.e. an attempt to enable ISP failed and should be diff --git a/src/jtagmkI_private.h b/src/jtagmkI_private.h index e21348231..bee84d959 100644 --- a/src/jtagmkI_private.h +++ b/src/jtagmkI_private.h @@ -17,73 +17,66 @@ * along with this program. If not, see . */ +// JTAG ICE mkI definitions -/* - * JTAG ICE mkI definitions - */ +// ICE command codes -/* ICE command codes */ -/* 0x20 Get Synch [Resp_OK] */ +// 0x20 Get Synch [Resp_OK] #define CMD_GET_SYNC ' ' -/* 0x31 Single Step [Sync_CRC/EOP] [Resp_OK] */ -/* 0x32 Read PC [Sync_CRC/EOP] [Resp_OK] [program counter] - * [Resp_OK] */ -/* 0x33 Write PC [program counter] [Sync_CRC/EOP] [Resp_OK] - * [Resp_OK] */ -/* 0xA2 Firmware Upgrade [upgrade string] [Sync_CRC/EOP] [Resp_OK] - * [Resp_OK] */ -/* 0xA0 Set Device Descriptor [device info] [Sync_CRC/EOP] [Resp_OK] - * [Resp_OK] */ +// 0x31 Single Step [Sync_CRC/EOP] [Resp_OK] + +// 0x32 Read PC [Sync_CRC/EOP] [Resp_OK] [program counter] [Resp_OK] + +// 0x33 Write PC [program counter] [Sync_CRC/EOP] [Resp_OK] [Resp_OK] + +// 0xA2 Firmware Upgrade [upgrade string] [Sync_CRC/EOP] [Resp_OK] [Resp_OK] + +// 0xA0 Set Device Descriptor [device info] [Sync_CRC/EOP] [Resp_OK] [Resp_OK] #define CMD_SET_DEVICE_DESCRIPTOR 0xA0 -/* 0x42 Set Parameter [parameter] [setting] [Sync_CRC/EOP] [Resp_OK] - * [Resp_OK] */ +// 0x42 Set Parameter [parameter] [setting] [Sync_CRC/EOP] [Resp_OK] [Resp_OK] #define CMD_SET_PARAM 'B' -/* 0x46 Forced Stop [Sync_CRC/EOP] [Resp_OK] [checksum][program - * counter] [Resp_OK] */ +// 0x46 Forced Stop [Sync_CRC/EOP] [Resp_OK] [checksum][program counter] [Resp_OK] #define CMD_STOP 'F' -/* 0x47 Go [Sync_CRC/EOP] [Resp_OK] */ +// 0x47 Go [Sync_CRC/EOP] [Resp_OK] #define CMD_GO 'G' -/* 0x52 Read Memory [memory type] [word count] [start address] - * [Sync_CRC/EOP] [Resp_OK] [word 0] ... [word n] [checksum] - * [Resp_OK] */ +// 0x52 Read Memory [memory type] [word count] [start address] [Sync_CRC/EOP] [Resp_OK] [word 0] ... [word n] [checksum] [Resp_OK] #define CMD_READ_MEM 'R' -/* 0x53 Get Sign On [Sync_CRC/EOP] [Resp_OK] ["AVRNOCD"] [Resp_OK] */ +// 0x53 Get Sign On [Sync_CRC/EOP] [Resp_OK] ["AVRNOCD"] [Resp_OK] #define CMD_GET_SIGNON 'S' -/* 0XA1 Erase Page spm [address] [Sync_CRC/EOP] [Resp_OK] [Resp_OK] */ +// 0xa1 Erase Page spm [address] [Sync_CRC/EOP] [Resp_OK] [Resp_OK] -/* 0x57 Write Memory [memory type] [word count] [start address] - * [Sync_CRC/EOP] [Resp_OK] [Cmd_DATA] [word 0] ... [word n] */ +// 0x57 Write Memory [memory type] [word count] [start address] [Sync_CRC/EOP] [Resp_OK] [Cmd_DATA] [word 0] ... [word n] #define CMD_WRITE_MEM 'W' -/* Second half of write memory: the data command. Undocumented. */ +// Second half of write memory: the data command; undocumented #define CMD_DATA 'h' -/* 0x64 Get Debug Info [Sync_CRC/EOP] [Resp_OK] [0x00] [Resp_OK] */ +// 0x64 Get Debug Info [Sync_CRC/EOP] [Resp_OK] [0x00] [Resp_OK] + /* 0x71 Get Parameter [parameter] [Sync_CRC/EOP] [Resp_OK] [setting] * [Resp_OK] */ #define CMD_GET_PARAM 'q' -/* 0x78 Reset [Sync_CRC/EOP] [Resp_OK] [Resp_OK] */ +// 0x78 Reset [Sync_CRC/EOP] [Resp_OK] [Resp_OK] #define CMD_RESET 'x' -/* 0xA3 Enter Progmode [Sync_CRC/EOP] [Resp_OK] [Resp_OK] */ +// 0xA3 Enter Progmode [Sync_CRC/EOP] [Resp_OK] [Resp_OK] #define CMD_ENTER_PROGMODE 0xa3 -/* 0xA4 Leave Progmode [Sync_CRC/EOP] [Resp_OK] [Resp_OK] */ +// 0xA4 Leave Progmode [Sync_CRC/EOP] [Resp_OK] [Resp_OK] #define CMD_LEAVE_PROGMODE 0xa4 -/* 0xA5 Chip Erase [Sync_CRC/EOP] [Resp_OK] [Resp_OK] */ +// 0xA5 Chip Erase [Sync_CRC/EOP] [Resp_OK] [Resp_OK] #define CMD_CHIP_ERASE 0xa5 - -/* ICE responses */ +// ICE responses #define RESP_OK 'A' #define RESP_BREAK 'B' #define RESP_INFO 'G' @@ -130,37 +123,33 @@ #define JTAG_BITRATE_250_kHz 0xfd #define JTAG_BITRATE_125_kHz 0xfb -/* memories for CMND_{READ,WRITE}_MEMORY */ -#define MTYPE_IO_SHADOW 0x30 /* cached IO registers? */ -#define MTYPE_SRAM 0x20 /* target's SRAM or [ext.] IO registers */ -#define MTYPE_EEPROM 0x22 /* EEPROM, what way? */ -#define MTYPE_EVENT 0x60 /* ICE event memory */ -#define MTYPE_SPM 0xA0 /* flash through LPM/SPM */ -#define MTYPE_FLASH_PAGE 0xB0 /* flash in programming mode */ -#define MTYPE_EEPROM_PAGE 0xB1 /* EEPROM in programming mode */ -#define MTYPE_FUSE_BITS 0xB2 /* fuse bits in programming mode */ -#define MTYPE_LOCK_BITS 0xB3 /* lock bits in programming mode */ -#define MTYPE_SIGN_JTAG 0xB4 /* signature in programming mode */ -#define MTYPE_OSCCAL_BYTE 0xB5 /* osccal cells in programming mode */ - -struct device_descriptor -{ - unsigned char ucReadIO[8]; /*LSB = IOloc 0, MSB = IOloc63 */ - unsigned char ucWriteIO[8]; /*LSB = IOloc 0, MSB = IOloc63 */ - unsigned char ucReadIOShadow[8]; /*LSB = IOloc 0, MSB = IOloc63 */ - unsigned char ucWriteIOShadow[8]; /*LSB = IOloc 0, MSB = IOloc63 */ - unsigned char ucReadExtIO[20]; /*LSB = IOloc 96, MSB = IOloc255 */ - unsigned char ucWriteExtIO[20]; /*LSB = IOloc 96, MSB = IOloc255 */ - unsigned char ucReadIOExtShadow[20]; /*LSB = IOloc 96, MSB = IOloc255 */ - unsigned char ucWriteIOExtShadow[20];/*LSB = IOloc 96, MSB = IOloc255 */ - unsigned char ucIDRAddress; /*IDR address */ - unsigned char ucSPMCRAddress; /*SPMCR Register address and dW BasePC */ - unsigned char ucRAMPZAddress; /*RAMPZ Register address in SRAM I/O */ - /*space */ - unsigned char uiFlashPageSize[2]; /*Device Flash Page Size, Size = */ - /*2 exp ucFlashPageSize */ - unsigned char ucEepromPageSize; /*Device Eeprom Page Size in bytes */ - unsigned char ulBootAddress[4]; /*Device Boot Loader Start Address */ - unsigned char uiUpperExtIOLoc; /*Topmost (last) extended I/O */ - /*location, 0 if no external I/O */ +// Memories for CMND_{READ,WRITE}_MEMORY +#define MTYPE_IO_SHADOW 0x30 // Cached IO registers? +#define MTYPE_SRAM 0x20 // Target's SRAM or [ext.] IO registers +#define MTYPE_EEPROM 0x22 // EEPROM, what way? +#define MTYPE_EVENT 0x60 // ICE event memory +#define MTYPE_SPM 0xA0 // Flash through LPM/SPM +#define MTYPE_FLASH_PAGE 0xB0 // Flash in programming mode +#define MTYPE_EEPROM_PAGE 0xB1 // EEPROM in programming mode +#define MTYPE_FUSE_BITS 0xB2 // Fuse bits in programming mode +#define MTYPE_LOCK_BITS 0xB3 // Lock bits in programming mode +#define MTYPE_SIGN_JTAG 0xB4 // Signature in programming mode +#define MTYPE_OSCCAL_BYTE 0xB5 // Osccal cells in programming mode + +struct device_descriptor { + unsigned char ucReadIO[8]; // LSB = IOloc 0, MSB = IOloc63 + unsigned char ucWriteIO[8]; // LSB = IOloc 0, MSB = IOloc63 + unsigned char ucReadIOShadow[8]; // LSB = IOloc 0, MSB = IOloc63 + unsigned char ucWriteIOShadow[8]; // LSB = IOloc 0, MSB = IOloc63 + unsigned char ucReadExtIO[20]; // LSB = IOloc 96, MSB = IOloc255 + unsigned char ucWriteExtIO[20]; // LSB = IOloc 96, MSB = IOloc255 + unsigned char ucReadIOExtShadow[20]; // LSB = IOloc 96, MSB = IOloc255 + unsigned char ucWriteIOExtShadow[20]; // LSB = IOloc 96, MSB = IOloc255 + unsigned char ucIDRAddress; // IDR address + unsigned char ucSPMCRAddress; // SPMCR Register address and dW BasePC + unsigned char ucRAMPZAddress; // RAMPZ Register address in SRAM I/O space + unsigned char uiFlashPageSize[2]; // Device Flash Page Size, Size = 2 exp ucFlashPageSize + unsigned char ucEepromPageSize; // Device Eeprom Page Size in bytes + unsigned char ulBootAddress[4]; // Device Boot Loader Start Address + unsigned char uiUpperExtIOLoc; // Topmost (last) extended I/O location, 0 if no external I/O }; diff --git a/src/leds.c b/src/leds.c index 2f006c967..f63da62de 100644 --- a/src/leds.c +++ b/src/leds.c @@ -1,5 +1,5 @@ /* - * AVRDUDE - A Downloader/Uploader for AVR device programmers + * avrdude - A Downloader/Uploader for AVR device programmers * Copyright (C) 2023 Stefan Rueger * * This program is free software; you can redistribute it and/or modify @@ -54,13 +54,13 @@ * */ -#define TOFF 2 // Toggle LED into off state -#define TON 3 // Toggle LED into on state -#define CHECK 15 // Check LED needs changing +#define TOFF 2 // Toggle LED into off state +#define TON 3 // Toggle LED into on state +#define CHECK 15 // Check LED needs changing // Keep track of LED status and set LED 0 .. LED_N-1 physically on or off static void led_direct(const PROGRAMMER *pgm, Leds *ls, int led, int what) { - if(what ^ !!(ls->phy & (1<phy & (1 << led))) { switch(led) { case LED_RDY: pgm->rdy_led(pgm, what); @@ -77,56 +77,57 @@ static void led_direct(const PROGRAMMER *pgm, Leds *ls, int led, int what) { default: pmsg_error("unknown LED %d in %s()\n", led, __func__); } - ls->phy ^= 1<phy ^= 1 << led; } } // Physical level of LED setting, deal with max blinking frequency LED_FMAX static void led_physical(const PROGRAMMER *pgm, Leds *ls, int led, int what) { - if(led < 0 || led >= LED_N) // Sanity + if(led < 0 || led >= LED_N) // Sanity return; unsigned long now = avr_mstimestamp(); if(what == ON || what == OFF) { if(what) // Force on or off - ls->phy &= ~(1<phy &= ~(1 << led); else - ls->phy |= 1<phy |= 1 << led; led_direct(pgm, ls, led, what); - ls->chg &= ~(1<chg &= ~(1 << led); ls->ms[led] = now; return; } - if(what == TON && !(ls->set & (1<set & (1 << led))) { // Never before set? Set immediately led_direct(pgm, ls, led, ON); - ls->set |= 1<chg &= ~(1<set |= 1 << led; + ls->chg &= ~(1 << led); ls->ms[led] = now; } else if(what == TON || what == TOFF) { // Toggle led into on or off state once enough time has gone by - ls->chg |= 1<chg |= 1 << led; } // Check all LEDs whether they need toggling or setting for(int l = 0; l < LED_N; l++) { unsigned long diff = now - ls->ms[l]; + if(diff && diff >= (unsigned long) (1000.0/LED_FMAX/2)) { - ls->ms[l] = now; // Toggle a fast signal or set to current value - what = ls->chg & (1<phy & (1<now & (1<ms[l] = now; // Toggle a fast signal or set to current value + what = ls->chg & (1 << l)? !(ls->phy & (1 << l)): !!(ls->now & (1 << l)); led_direct(pgm, ls, l, what); - ls->chg &= ~(1<chg &= ~(1 << l); } } } // Logical level of setting LEDs, passes on to physical level int led_set(const PROGRAMMER *pgm, int led) { - // leds should always be allocated, but if not use dummy - Leds sanity = { 0, 0, 0, 0, 0, {0, } }, *ls = pgm->leds? pgm->leds: &sanity; - int what = led >= 0 && led < LED_N && !(ls->now & (1<leds? pgm->leds: &sanity; + int what = led >= 0 && led < LED_N && !(ls->now & (1 << led))? TON: CHECK; switch(led) { case LED_BEG: @@ -138,24 +139,24 @@ int led_set(const PROGRAMMER *pgm, int led) { break; case LED_END: led_physical(pgm, ls, LED_RDY, OFF); - led_physical(pgm, ls, LED_ERR, ls->end & (1<end & (1<end & (1<end & (1 << LED_ERR)? ON: OFF); + led_physical(pgm, ls, LED_PGM, ls->end & (1 << LED_PGM)? ON: OFF); + led_physical(pgm, ls, LED_VFY, ls->end & (1 << LED_VFY)? ON: OFF); break; case LED_NOP: - led_physical(pgm, ls, LED_RDY, CHECK); // All others will be checked, too + led_physical(pgm, ls, LED_RDY, CHECK); // All others will be checked, too break; - case LED_ERR: // Record that error happened and in which mode - ls->end |= 1<now & (1<end |= 1<now & (1<end |= 1<end |= 1 << LED_ERR; + if(ls->now & (1 << LED_PGM)) + ls->end |= 1 << LED_PGM; + if(ls->now & (1 << LED_VFY)) + ls->end |= 1 << LED_VFY; + // Fall through case LED_RDY: case LED_PGM: case LED_VFY: - ls->now |= 1<now |= 1 << led; led_physical(pgm, ls, led, what); break; default: @@ -174,12 +175,14 @@ int led_clr(const PROGRAMMER *pgm, int led) { } // pgm->leds should always be allocated, but if not use dummy - Leds sanity = { 0, 0, 0, 0, 0, {0, } }, *ls = pgm->leds? pgm->leds: &sanity; - int what = ls->now & (1<leds? pgm->leds: &sanity; + int what = ls->now & (1 << led)? TOFF: CHECK; // Record logical level if(led >= 0 && led < LED_N) - ls->now &= ~(1<now &= ~(1 << led); led_physical(pgm, ls, led, what); @@ -194,8 +197,7 @@ int led_chip_erase(const PROGRAMMER *pgm, const AVRPART *p) { } // Programmer specific write byte function with ERR/PGM LED info -int led_write_byte(const PROGRAMMER *pgm, const AVRPART *p, const AVRMEM *m, - unsigned long addr, unsigned char value) { +int led_write_byte(const PROGRAMMER *pgm, const AVRPART *p, const AVRMEM *m, unsigned long addr, unsigned char value) { if(mem_is_readonly(m)) return pgm->write_byte(pgm, p, m, addr, value); @@ -221,7 +223,7 @@ int led_read_byte(const PROGRAMMER *pgm, const AVRPART *p, const AVRMEM *m, int rc = pgm->read_byte(pgm, p, m, addr, valuep); - if(rc<0) + if(rc < 0) led_set(pgm, LED_ERR); led_clr(pgm, LED_PGM); @@ -236,7 +238,7 @@ int led_paged_write(const PROGRAMMER *pgm, const AVRPART *p, const AVRMEM *m, int rc = pgm->paged_write? led_set(pgm, LED_PGM), pgm->paged_write(pgm, p, m, page_size, baseaddr, n_bytes): -1; - if(rc<0) + if(rc < 0) led_set(pgm, LED_ERR); led_clr(pgm, LED_PGM); @@ -251,7 +253,7 @@ int led_paged_load(const PROGRAMMER *pgm, const AVRPART *p, const AVRMEM *m, int rc = pgm->paged_load? led_set(pgm, LED_PGM), pgm->paged_load(pgm, p, m, page_size, baseaddr, n_bytes): -1; - if(rc<0) + if(rc < 0) led_set(pgm, LED_ERR); led_clr(pgm, LED_PGM); @@ -259,14 +261,13 @@ int led_paged_load(const PROGRAMMER *pgm, const AVRPART *p, const AVRMEM *m, } // Programmer-specific page erase function with ERR/PGM LED info -int led_page_erase(const PROGRAMMER *pgm, const AVRPART *p, const AVRMEM *m, - unsigned int baseaddr) { +int led_page_erase(const PROGRAMMER *pgm, const AVRPART *p, const AVRMEM *m, unsigned int baseaddr) { led_clr(pgm, LED_ERR); int rc = pgm->page_erase? led_set(pgm, LED_PGM), pgm->page_erase(pgm, p, m, baseaddr): -1; - if(rc<0) + if(rc < 0) led_set(pgm, LED_ERR); led_clr(pgm, LED_PGM); diff --git a/src/libavrdude.h b/src/libavrdude.h index bb2f49437..7abf74120 100644 --- a/src/libavrdude.h +++ b/src/libavrdude.h @@ -24,6 +24,7 @@ #include #include #include + #if !defined(WIN32) #include #endif @@ -37,35 +38,35 @@ #undef LIBAVRDUDE_INCLUDE_INTERNAL_HEADERS /* - * The libavrdude library contains useful functions for programming - * Microchip's 8-bit AVR microprocessors. The command line program avrdude - * was written using this library; its source code is a good example of how - * to use the library. Out of necessity libavrdude routinely changes - * PROGRAMMER, AVRPART and other structures to keep up with new programmers - * and with new parts and programming interfaces from Microchip. Any - * application that uses this library should ensure that it links to a - * libavrdude binary that is compatible with this header file, ideally the - * version that was shipped together with this header file or one that was - * compiled from source together with the application. + * The libavrdude library contains useful functions for programming Microchip's + * 8-bit AVR microprocessors. The command line program avrdude was written + * using this library; its source code is a good example of how to use the + * library. Out of necessity libavrdude routinely changes PROGRAMMER, AVRPART + * and other structures to keep up with new programmers and with new parts and + * programming interfaces from Microchip. Any application that uses this + * library should ensure that it links to a libavrdude binary that is + * compatible with this header file, ideally the version that was shipped + * together with this header file or one that was compiled from source together + * with the application. */ typedef uint32_t Pinmask; + /* - * Values returned by library functions. - * Some library functions also return a count, i.e. a positive - * number greater than 0. + * Values returned by library functions. Some library functions also return a + * count, i.e. a positive number greater than 0. */ #define LIBAVRDUDE_SUCCESS 0 #define LIBAVRDUDE_GENERAL_FAILURE (-1) -#define LIBAVRDUDE_NOTSUPPORTED (-2) // operation not supported -#define LIBAVRDUDE_SOFTFAIL (-3) // returned, eg, by avr_signature() if caller - // might proceed with chip erase -#define LIBAVRDUDE_EXIT (-4) // End all operations in this session +#define LIBAVRDUDE_NOTSUPPORTED (-2) // Operation not supported +#define LIBAVRDUDE_SOFTFAIL (-3) // Returned, eg, if caller might proceed with a plan B +#define LIBAVRDUDE_EXIT (-4) // End all operations in this session -/* Message system */ -/* This functions is supposed to be supplied by the application */ +// Message system -int avrdude_message2(FILE *fp, int lno, const char *file, const char *func, int msgmode, int msglvl, const char *format, ...); +// This functions is supposed to be supplied by the application +int avrdude_message2(FILE *fp, int lno, const char *file, const char *func, + int msgmode, int msglvl, const char *format, ...); enum msglvl { MSG_EXT_ERROR = (-3), // OS-type error, no -v option, can be suppressed with -qqqqq @@ -91,7 +92,7 @@ enum msgmode { MSG2_UCFIRST = 256 // Uppercase first character of output }; -/* formerly lists.h */ +// Formerly lists.h /*---------------------------------------------------------------------- General purpose linked list routines - header file declarations. @@ -100,9 +101,8 @@ enum msgmode { Date : 10 January, 1990 ----------------------------------------------------------------------*/ -typedef void * LISTID; -typedef void * LNODEID; - +typedef void *LISTID; +typedef void *LNODEID; /*---------------------------------------------------------------------- several defines to access the LIST structure as as stack or a queue @@ -113,79 +113,66 @@ typedef void * LNODEID; #define QUEUEID LISTID #define QNODEID LNODEID +#define PUSH(s,d) lins_n(s,d,1) // Push 'd' onto the stack +#define POP(s) lrmv_n(s,1) // Pop the stack +#define LOOKSTACK(s) lget_n(s,1) // Look at the top of the stack but don't pop -#define PUSH(s,d) lins_n(s,d,1) /* push 'd' onto the stack */ -#define POP(s) lrmv_n(s,1) /* pop the stack */ -#define LOOKSTACK(s) lget_n(s,1) /* look at the top of the stack, - but don't pop */ - - -#define ENQUEUE(q,d) lins_n(q,d,1) /* put 'd' on the end of the queue */ -#define DEQUEUE(q) lrmv(q) /* remove next item from the front of - the queue */ -#define REQUEUE(q,d) ladd(q,d) /* re-insert (push) item back on the - front of the queue */ -#define LOOKQUEUE(q) lget(q) /* return next item on the queue, - but don't dequeue */ -#define QUEUELEN(q) lsize(q) /* length of the queue */ - - -#define LISTADD(l,d) ladd(l,d) /* add to end of the list */ -#define LISTRMV(l,d) lrmv_d(l,d) /* remove from end of the list */ +#define ENQUEUE(q,d) lins_n(q,d,1) // Put 'd' on the end of the queue +#define DEQUEUE(q) lrmv(q) // Remove next item from the front of the queue +#define REQUEUE(q,d) ladd(q,d) // Re-insert (push) item back on the front of the queue +#define LOOKQUEUE(q) lget(q) // Return next item on the queue, but don't dequeue +#define QUEUELEN(q) lsize(q) // Length of the queue +#define LISTADD(l,d) ladd(l,d) // Add to end of the list +#define LISTRMV(l,d) lrmv_d(l,d) // Remove from end of the list #ifdef __cplusplus extern "C" { #endif -/* .................... Function Prototypes .................... */ +// .................... Function Prototypes .................... -LISTID lcreat ( void * liststruct, int poolsize ); -void ldestroy ( LISTID lid ); -void ldestroy_cb ( LISTID lid, void (*ucleanup)(void * data_ptr) ); + LISTID lcreat(void *liststruct, int poolsize); + void ldestroy(LISTID lid); + void ldestroy_cb(LISTID lid, void (*ucleanup)(void *data_ptr)); -LNODEID lfirst ( LISTID ); /* head of the list */ -LNODEID llast ( LISTID ); /* tail of the list */ -LNODEID lnext ( LNODEID ); /* next item in the list */ -LNODEID lprev ( LNODEID ); /* previous item in the list */ -void * ldata ( LNODEID ); /* data at the current position */ -int lsize ( LISTID ); /* number of elements in the list */ + LNODEID lfirst(LISTID); // Head of the list + LNODEID llast(LISTID); // Tail of the list + LNODEID lnext(LNODEID); // Next item in the list + LNODEID lprev(LNODEID); // Previous item in the list + void *ldata(LNODEID); // Data at the current position + int lsize(LISTID); // Number of elements in the list -int ladd ( LISTID lid, void * p ); -int laddo ( LISTID lid, void *p, - int (*compare)(const void *p1,const void *p2), - LNODEID * firstdup ); -int laddu ( LISTID lid, void * p, - int (*compare)(const void *p1,const void *p2)); -int lins_n ( LISTID lid, void * d, unsigned int n ); -int lins_ln ( LISTID lid, LNODEID lnid, void * data_ptr ); + int ladd(LISTID lid, void *p); + int laddo(LISTID lid, void *p, int (*compare)(const void *p1, const void *p2), LNODEID *firstdup); + int laddu(LISTID lid, void *p, int (*compare)(const void *p1, const void *p2)); + int lins_n(LISTID lid, void *d, unsigned int n); + int lins_ln(LISTID lid, LNODEID lnid, void *data_ptr); -void * lget ( LISTID lid ); -void * lget_n ( LISTID lid, unsigned int n ); -LNODEID lget_ln ( LISTID lid, unsigned int n ); + void *lget(LISTID lid); + void *lget_n(LISTID lid, unsigned int n); + LNODEID lget_ln(LISTID lid, unsigned int n); -void * lrmv ( LISTID lid ); -void * lrmv_n ( LISTID lid, unsigned int n ); -void * lrmv_ln ( LISTID lid, LNODEID lnid ); -void * lrmv_d ( LISTID lid, void * data_ptr ); + void *lrmv(LISTID lid); + void *lrmv_n(LISTID lid, unsigned int n); + void *lrmv_ln(LISTID lid, LNODEID lnid); + void *lrmv_d(LISTID lid, void *data_ptr); -LISTID lcat ( LISTID lid1, LISTID lid2 ); + LISTID lcat(LISTID lid1, LISTID lid2); -void lsort ( LISTID lid, int (*compare)(void * p1, void * p2)); + void lsort(LISTID lid, int (*compare)(void *p1, void *p2)); -void * lsrch ( LISTID lid, void * p, int (*compare)(void *p1,void *p2)); + void *lsrch(LISTID lid, void *p, int (*compare)(void *p1, void *p2)); -int lprint ( FILE * f, LISTID lid ); + int lprint(FILE *f, LISTID lid); #ifdef __cplusplus } #endif -/* formerly avrpart.h */ +// Formerly avrpart.h -/* - * AVR serial programming instructions - */ +// AVR serial programming instructions enum { AVR_OP_READ, AVR_OP_WRITE, @@ -202,48 +189,43 @@ enum { AVR_OP_MAX }; - enum { - AVR_CMDBIT_IGNORE, /* bit is ignored on input and output */ - AVR_CMDBIT_VALUE, /* bit is set to 0 or 1 for input or output */ - AVR_CMDBIT_ADDRESS, /* this bit represents an input address bit */ - AVR_CMDBIT_INPUT, /* this bit is an input bit */ - AVR_CMDBIT_OUTPUT /* this bit is an output bit */ + AVR_CMDBIT_IGNORE, // Bit is ignored on input and output + AVR_CMDBIT_VALUE, // Bit is set to 0 or 1 for input or output + AVR_CMDBIT_ADDRESS, // This bit represents an input address bit + AVR_CMDBIT_INPUT, // This bit is an input bit + AVR_CMDBIT_OUTPUT // This bit is an output bit }; -enum { /* these are assigned to reset_disposition of AVRPART */ - RESET_DEDICATED, /* reset pin is dedicated */ - RESET_IO /* reset pin might be configured as an I/O pin */ +enum { // These are assigned to reset_disposition of AVRPART + RESET_DEDICATED, // Reset pin is dedicated + RESET_IO // Reset pin might be configured as an I/O pin }; enum ctl_stack { - CTL_STACK_NONE, /* no control stack defined */ - CTL_STACK_PP, /* parallel programming control stack */ - CTL_STACK_HVSP /* high voltage serial programming control stack */ + CTL_STACK_NONE, // No control stack defined + CTL_STACK_PP, // Parallel programming control stack + CTL_STACK_HVSP // High voltage serial programming control stack }; - -/* - * serial programming instruction bit specifications - */ +// Serial programming instruction bit specifications typedef struct cmdbit { - int type; /* AVR_CMDBIT_* */ - int bitno; /* which input bit to use for this command bit */ - int value; /* bit value if type == AVR_CMDBIT_VALUE */ + int type; // AVR_CMDBIT_* + int bitno; // Which input bit to use for this command bit + int value; // Bit value if type == AVR_CMDBIT_VALUE } CMDBIT; typedef struct opcode { - CMDBIT bit[32]; /* opcode bit specs */ + CMDBIT bit[32]; // Opcode bit specs } OPCODE; - // Any changes here, please also reflect in dev_part_strct() of developer_opts.c -#define AVRPART_SERIALOK 1 // Part supports serial programming -#define AVRPART_PARALLELOK 2 // Part supports parallel programming -#define AVRPART_PSEUDOPARALLEL 4 // Part has pseudo parallel support -#define AVRPART_ALLOWFULLPAGEBITSTREAM 8 // JTAG ICE mkII param -#define AVRPART_ENABLEPAGEPROGRAMMING 16 // JTAG ICE mkII param -#define AVRPART_IS_AT90S1200 32 // Part is an AT90S1200, needs special treatment +#define AVRPART_SERIALOK 1 // Part supports serial programming +#define AVRPART_PARALLELOK 2 // Part supports parallel programming +#define AVRPART_PSEUDOPARALLEL 4 // Part has pseudo parallel support +#define AVRPART_ALLOWFULLPAGEBITSTREAM 8 // JTAG ICE mkII param +#define AVRPART_ENABLEPAGEPROGRAMMING 16 // JTAG ICE mkII param +#define AVRPART_IS_AT90S1200 32 // Part is an AT90S1200, needs special treatment // Programming modes for parts and programmers: reflect changes in lexer.l, developer_opts.c and config.c #define PM_SPM 1 // Bootloaders, self-programming with SPM opcodes or NVM Controllers @@ -298,26 +280,25 @@ typedef struct opcode { #define both_awire(pgm, p) (!!(joint_pm(pgm, p) & PM_aWire)) #define both_classic(pgm, p) (!!(joint_pm(pgm, p) & PM_Classic)) +#define HV_UPDI_VARIANT_0 0 // Shared UPDI/GPIO/RESET pin, HV on UPDI pin (tinyAVR0/1/2) +#define HV_UPDI_VARIANT_1 1 // Dedicated UPDI pin, no HV (megaAVR0/AVR-Dx) +#define HV_UPDI_VARIANT_2 2 // Shared UPDI pin, HV on _RESET (AVR-DD/AVR-Ex) -#define HV_UPDI_VARIANT_0 0 /* Shared UPDI/GPIO/RESET pin, HV on UPDI pin (tinyAVR0/1/2)*/ -#define HV_UPDI_VARIANT_1 1 /* Dedicated UPDI pin, no HV (megaAVR0/AVR-Dx) */ -#define HV_UPDI_VARIANT_2 2 /* Shared UPDI pin, HV on _RESET (AVR-DD/AVR-Ex) */ - -#define HAS_SUFFER 1 -#define HAS_VTARG_SWITCH 2 -#define HAS_VTARG_ADJ 4 -#define HAS_VTARG_READ 8 -#define HAS_FOSC_ADJ 16 -#define HAS_VAREF_ADJ 32 +#define HAS_SUFFER 1 +#define HAS_VTARG_SWITCH 2 +#define HAS_VTARG_ADJ 4 +#define HAS_VTARG_READ 8 +#define HAS_FOSC_ADJ 16 +#define HAS_VAREF_ADJ 32 -#define AVR_FAMILYIDLEN 7 -#define AVR_SIBLEN 32 -#define AVR_CHIP_REVLEN 1 -#define CTL_STACK_SIZE 32 -#define FLASH_INSTR_SIZE 3 -#define EEPROM_INSTR_SIZE 20 +#define AVR_FAMILYIDLEN 7 +#define AVR_SIBLEN 32 +#define AVR_CHIP_REVLEN 1 +#define CTL_STACK_SIZE 32 +#define FLASH_INSTR_SIZE 3 +#define EEPROM_INSTR_SIZE 20 -#define TAG_ALLOCATED 1 /* memory byte is allocated */ +#define TAG_ALLOCATED 1 // Memory byte is allocated /* * Any changes in AVRPART or AVRMEM, please also ensure changes are made in @@ -328,95 +309,92 @@ typedef struct opcode { * initialisation; note that all const char * must be initialised with "" */ typedef struct avrpart { - const char * desc; /* long part name */ - const char * id; /* short part name */ - LISTID comments; // Used by developer options -p*/[ASsr...] - LISTID variants; /* String with variant name and chip properties */ - const char * parent_id; /* Used by developer options */ - const char * family_id; /* family id in the SIB (avr8x) */ - int prog_modes; /* Programming interfaces, see #define PM_... */ - int mcuid; /* Unique id in 0..2039 for urclock programmer */ - int archnum; /* avr-gcc architecture number for the part */ - int n_interrupts; /* Number of interrupts, used for vector bootloaders */ - int n_page_erase; /* If set, number of pages erased during NVM erase */ - int n_boot_sections; /* Number of boot sections */ - int boot_section_size; /* Size of (smallest) boot section, if any */ - int hvupdi_variant; /* HV pulse on UPDI pin, no pin or RESET pin */ - int stk500_devcode; /* stk500 device code */ - int avr910_devcode; /* avr910 device code */ - int chip_erase_delay; /* microseconds */ - unsigned char pagel; /* for parallel programming */ - unsigned char bs2; /* for parallel programming */ - unsigned char signature[3]; /* expected value of signature bytes */ - unsigned short usbpid; /* USB DFU product ID (0 = none) */ - int reset_disposition; /* see RESET_ enums */ - int retry_pulse; /* retry program enable by pulsing - this pin (PIN_AVR_*) */ - unsigned flags; /* see AVRPART_ masks */ - - /* STK500 v2 parameters from ATDF files */ - int timeout; - int stabdelay; - int cmdexedelay; - int synchloops; - int bytedelay; - int pollindex; + const char *desc; // Long part name + const char *id; // Short part name + LISTID comments; // Used by developer options -p*/[ASsr...] + LISTID variants; // String with variant name and chip properties + const char *parent_id; // Used by developer options + const char *family_id; // Family id in the SIB (avr8x) + int prog_modes; // Programming interfaces, see #define PM_... + int mcuid; // Unique id in 0..2039 for urclock programmer + int archnum; // Avr-gcc architecture number for the part + int n_interrupts; // Number of interrupts, used for vector bootloaders + int n_page_erase; // If set, number of pages erased during NVM erase + int n_boot_sections; // Number of boot sections + int boot_section_size; // Size of (smallest) boot section, if any + int hvupdi_variant; // HV pulse on UPDI pin, no pin or RESET pin + int stk500_devcode; // Stk500 device code + int avr910_devcode; // Avr910 device code + int chip_erase_delay; // Microseconds + unsigned char pagel; // For parallel programming + unsigned char bs2; // For parallel programming + unsigned char signature[3]; // Expected value of signature bytes + unsigned short usbpid; // USB DFU product ID (0 = none) + int reset_disposition; // See RESET_ enums + int retry_pulse; // Retry program enable by pulsing this pin (PIN_AVR_*) + unsigned flags; // See AVRPART_ masks + + // STK500 v2 parameters from ATDF files + int timeout; + int stabdelay; + int cmdexedelay; + int synchloops; + int bytedelay; + int pollindex; unsigned char pollvalue; - int predelay; - int postdelay; - int pollmethod; - - enum ctl_stack ctl_stack_type; /* what to use the ctl stack for */ - unsigned char controlstack[CTL_STACK_SIZE]; /* stk500v2 PP/HVSP ctl stack */ - unsigned char flash_instr[FLASH_INSTR_SIZE]; /* flash instructions (debugWire, JTAG) */ - unsigned char eeprom_instr[EEPROM_INSTR_SIZE]; /* EEPROM instructions (debugWire, JTAG) */ - - /* STK500 v2 hv mode parameters */ - int hventerstabdelay; - int progmodedelay; - int latchcycles; - int togglevtg; - int poweroffdelay; - int resetdelayms; - int resetdelayus; - int hvleavestabdelay; - int resetdelay; - int chiperasepulsewidth; - int chiperasepolltimeout; - int chiperasetime; - int programfusepulsewidth; - int programfusepolltimeout; - int programlockpulsewidth; - int programlockpolltimeout; - int synchcycles; - int hvspcmdexedelay; - - - /* debugWIRE and/or JTAG ICE mkII XML file parameters */ - unsigned char idr; /* I/O address of IDR (OCD) reg */ - unsigned char rampz; /* I/O address of RAMPZ reg */ - unsigned char spmcr; /* memory address of SPMCR reg */ - unsigned char eecr; /* memory address of EECR reg */ - unsigned char eind; /* memory address of EIND reg */ - unsigned int mcu_base; /* Base address of MCU control block in ATxmega devices */ - unsigned int nvm_base; /* Base address of NVM controller in ATxmega devices */ - unsigned int ocd_base; /* Base address of OCD module in AVR8X/UPDI devices */ - unsigned int syscfg_base; /* Base address of revision ID in AVR8X/UPDI devices */ - int ocdrev; /* OCD revision (JTAGICE3 parameter, from AS6 XML files) */ - - /* Bootloader paramater */ - unsigned char autobaud_sync; /* Sync byte for bootloader autobaud, must be <= 0x30 */ - int factory_fcpu; /* Initial F_CPU after reset assuming factory settings */ - - OPCODE * op[AVR_OP_MAX]; /* opcodes */ - - LISTID mem; /* avr memory definitions */ - LISTID mem_alias; /* memory alias definitions */ - const char * config_file; /* config file where defined */ - int lineno; /* config file line number */ + int predelay; + int postdelay; + int pollmethod; + + enum ctl_stack ctl_stack_type; // What to use the ctl stack for + unsigned char controlstack[CTL_STACK_SIZE]; // Stk500v2 PP/HVSP ctl stack + unsigned char flash_instr[FLASH_INSTR_SIZE]; // Flash instructions (debugWire, JTAG) + unsigned char eeprom_instr[EEPROM_INSTR_SIZE]; // EEPROM instructions (debugWire, JTAG) + + // STK500 v2 hv mode parameters + int hventerstabdelay; + int progmodedelay; + int latchcycles; + int togglevtg; + int poweroffdelay; + int resetdelayms; + int resetdelayus; + int hvleavestabdelay; + int resetdelay; + int chiperasepulsewidth; + int chiperasepolltimeout; + int chiperasetime; + int programfusepulsewidth; + int programfusepolltimeout; + int programlockpulsewidth; + int programlockpolltimeout; + int synchcycles; + int hvspcmdexedelay; + + // debugWIRE and/or JTAG ICE mkII XML file parameters + unsigned char idr; // I/O address of IDR (OCD) reg + unsigned char rampz; // I/O address of RAMPZ reg + unsigned char spmcr; // Memory address of SPMCR reg + unsigned char eecr; // Memory address of EECR reg + unsigned char eind; // Memory address of EIND reg + unsigned int mcu_base; // Base address of MCU control block in ATxmega devices + unsigned int nvm_base; // Base address of NVM controller in ATxmega devices + unsigned int ocd_base; // Base address of OCD module in AVR8X/UPDI devices + unsigned int syscfg_base; // Base address of revision ID in AVR8X/UPDI devices + int ocdrev; // OCD revision (JTAGICE3 parameter, from AS6 XML files) + + // Bootloader parameter + unsigned char autobaud_sync; // Sync byte for bootloader autobaud, must be <= 0x30 + int factory_fcpu; // Initial F_CPU after reset assuming factory settings + + OPCODE *op[AVR_OP_MAX]; // Opcodes + + LISTID mem; // AVR memory definitions + LISTID mem_alias; // Memory alias definitions + const char *config_file; // Config file where defined + int lineno; // Config file line number } AVRPART; - typedef unsigned int Memtype; typedef struct { const char *str; @@ -563,115 +541,111 @@ typedef struct { #define mem_is_fuse8(m) (((m)->type&(MEM_IS_A_FUSE|MEM_FUSEOFF_MASK)) == (MEM_IS_A_FUSE|MEM_FUSE8)) #define mem_is_fusea(m) (((m)->type&(MEM_IS_A_FUSE|MEM_FUSEOFF_MASK)) == (MEM_IS_A_FUSE|MEM_FUSEA)) -#define mem_fuse_offset(mem) ((mem)->type & MEM_FUSEOFF_MASK) // Valid if mem_is_a_fuse(mem) +#define mem_fuse_offset(mem) ((mem)->type & MEM_FUSEOFF_MASK) // Valid if mem_is_a_fuse(mem) typedef struct avrmem { - const char *desc; /* memory description ("flash", "eeprom", etc) */ - Memtype type; /* Internally used type, cannot be set in conf files */ - LISTID comments; // Used by developer options -p*/[ASsr...] - int paged; /* 16-bit page addressed, e.g., ATmega flash but not EEPROM */ - int size; /* total memory size in bytes */ - int page_size; /* size of memory page (if page addressed) */ - int num_pages; /* number of pages (if page addressed) */ - int initval; /* factory setting of fuses and lock bits */ - int bitmask; /* bits used in fuses and lock bits */ - int n_word_writes; /* TPI only: number words to write at a time */ - unsigned int offset; /* offset in IO memory (ATxmega, UPDI, some classic memories) */ - int min_write_delay; /* microseconds */ - int max_write_delay; /* microseconds */ - int pwroff_after_write; /* after this memory is written to, - the device must be powered off and - back on, see errata - https://www.microchip.com/content/dam/mchp/documents/OTH/ProductDocuments/DataSheets/doc1042.pdf */ - unsigned char readback[2]; /* polled read-back values */ - - int mode; /* stk500 v2 xml file parameter */ - int delay; /* stk500 v2 xml file parameter */ - int blocksize; /* stk500 v2 xml file parameter */ - int readsize; /* stk500 v2 xml file parameter */ - int pollindex; /* stk500 v2 xml file parameter */ - - unsigned char * buf; /* pointer to memory buffer */ - unsigned char * tags; /* allocation tags */ - OPCODE * op[AVR_OP_MAX]; /* opcodes */ + const char *desc; // Memory description ("flash", "eeprom", etc) + Memtype type; // Internally used type, cannot be set in conf files + LISTID comments; // Used by developer options -p*/[ASsr...] + int paged; // 16-bit page addressed, e.g., ATmega flash but not EEPROM + int size; // Total memory size in bytes + int page_size; // Size of memory page (if page addressed) + int num_pages; // Number of pages (if page addressed) + int initval; // Factory setting of fuses and lock bits + int bitmask; // Bits used in fuses and lock bits + int n_word_writes; // TPI only: number words to write at a time + unsigned int offset; // Offset in IO memory (ATxmega, UPDI, some classic memories) + int min_write_delay; // Microseconds + int max_write_delay; // Microseconds + int pwroff_after_write; // After this memory is written to, the device must be powered off and back on, see errata + // https://www.microchip.com/content/dam/mchp/documents/OTH/ProductDocuments/DataSheets/doc1042.pdf + unsigned char readback[2]; // Polled read-back values + + int mode; // Stk500 v2 xml file parameter + int delay; // Stk500 v2 xml file parameter + int blocksize; // Stk500 v2 xml file parameter + int readsize; // Stk500 v2 xml file parameter + int pollindex; // Stk500 v2 xml file parameter + + unsigned char *buf; // Pointer to memory buffer + unsigned char *tags; // Allocation tags + OPCODE *op[AVR_OP_MAX]; // Opcodes } AVRMEM; typedef struct avrmem_alias { - const char *desc; /* alias name ("syscfg0" etc.) */ + const char *desc; // Alias name, eg, syscfg0 AVRMEM *aliased_mem; } AVRMEM_ALIAS; -typedef struct programmer PROGRAMMER; // Forward declaration +typedef struct programmer PROGRAMMER; // Forward declaration #ifdef __cplusplus extern "C" { #endif - -int intlog2(unsigned int n); - -/* Functions for OPCODE structures */ -OPCODE * avr_new_opcode(void); -void avr_free_opcode(OPCODE * op); -int avr_set_bits(const OPCODE *op, unsigned char *cmd); -int avr_set_addr(const OPCODE *op, unsigned char *cmd, unsigned long addr); -int avr_set_addr_mem(const AVRMEM *mem, int opnum, unsigned char *cmd, unsigned long addr); -int avr_set_input(const OPCODE *op, unsigned char *cmd, unsigned char data); -int avr_get_output(const OPCODE *op, const unsigned char *res, unsigned char *data); -int avr_get_output_index(const OPCODE *op); -char cmdbitchar(CMDBIT cb); -char *cmdbitstr(CMDBIT cb); -const char *opcodename(int opnum); -char *opcode2str(const OPCODE *op, int opnum, int detailed); - -/* Functions for AVRMEM structures */ -AVRMEM * avr_new_mem(void); -AVRMEM *avr_new_memory(const char *name, int size); -AVRMEM_ALIAS * avr_new_memalias(void); -const char *avr_mem_name(const AVRPART *p, const AVRMEM *mem); -int avr_initmem(const AVRPART *p); -AVRMEM * avr_dup_mem(const AVRMEM *m); -void avr_free_mem(AVRMEM * m); -void avr_free_memalias(AVRMEM_ALIAS * m); -AVRMEM * avr_locate_mem(const AVRPART *p, const char *desc); -AVRMEM * avr_locate_mem_noalias(const AVRPART *p, const char *desc); -AVRMEM * avr_locate_fuse_by_offset(const AVRPART *p, unsigned int off); -AVRMEM * avr_locate_mem_by_type(const AVRPART *p, Memtype type); -unsigned int avr_data_offset(const AVRPART *p); -AVRMEM_ALIAS * avr_locate_memalias(const AVRPART *p, const char *desc); -AVRMEM_ALIAS * avr_find_memalias(const AVRPART *p, const AVRMEM *m_orig); -void avr_mem_display(FILE *f, const PROGRAMMER *pgm, const AVRPART *p, const char *prefix); - -/* Functions for AVRPART structures */ -AVRPART * avr_new_part(void); -AVRPART * avr_dup_part(const AVRPART *d); -void avr_free_part(AVRPART * d); -AVRPART * locate_part(const LISTID parts, const char *partdesc); -AVRPART * locate_part_by_avr910_devcode(const LISTID parts, int devcode); -AVRPART * locate_part_by_signature(const LISTID parts, unsigned char *sig, int sigsize); -AVRPART * locate_part_by_signature_pm(const LISTID parts, unsigned char *sig, int sigsize, int prog_modes); -int avr_sig_compatible(const unsigned char *sig1, const unsigned char *sig2); - -char *avr_prog_modes(int pm), *str_prog_modes(int pm), *dev_prog_modes(int pm); -void avr_display(FILE *f, const PROGRAMMER *pgm, const AVRPART *p, const char *prefix, int verbose); -int avr_variants_display(FILE *f, const AVRPART *p, const char *prefix); - -typedef void (*walk_avrparts_cb)(const char *name, const char *desc, - const char *cfgname, int cfglineno, - void *cookie); -void walk_avrparts(LISTID avrparts, walk_avrparts_cb cb, void *cookie); -void sort_avrparts(LISTID avrparts); - -// cmp can be, eg, str_caseeq or str_casematch -int part_eq(AVRPART *p, const char *string, int (*cmp)(const char *, const char *)); - -int compare_memory_masked(AVRMEM * m, uint8_t buf1, uint8_t buf2); + int intlog2(unsigned int n); + + // Functions for OPCODE structures + OPCODE *avr_new_opcode(void); + void avr_free_opcode(OPCODE *op); + int avr_set_bits(const OPCODE *op, unsigned char *cmd); + int avr_set_addr(const OPCODE *op, unsigned char *cmd, unsigned long addr); + int avr_set_addr_mem(const AVRMEM *mem, int opnum, unsigned char *cmd, unsigned long addr); + int avr_set_input(const OPCODE *op, unsigned char *cmd, unsigned char data); + int avr_get_output(const OPCODE *op, const unsigned char *res, unsigned char *data); + int avr_get_output_index(const OPCODE *op); + char cmdbitchar(CMDBIT cb); + char *cmdbitstr(CMDBIT cb); + const char *opcodename(int opnum); + char *opcode2str(const OPCODE *op, int opnum, int detailed); + + // Functions for AVRMEM structures + AVRMEM *avr_new_mem(void); + AVRMEM *avr_new_memory(const char *name, int size); + AVRMEM_ALIAS *avr_new_memalias(void); + const char *avr_mem_name(const AVRPART *p, const AVRMEM *mem); + int avr_initmem(const AVRPART *p); + AVRMEM *avr_dup_mem(const AVRMEM *m); + void avr_free_mem(AVRMEM *m); + void avr_free_memalias(AVRMEM_ALIAS *m); + AVRMEM *avr_locate_mem(const AVRPART *p, const char *desc); + AVRMEM *avr_locate_mem_noalias(const AVRPART *p, const char *desc); + AVRMEM *avr_locate_fuse_by_offset(const AVRPART *p, unsigned int off); + AVRMEM *avr_locate_mem_by_type(const AVRPART *p, Memtype type); + unsigned int avr_data_offset(const AVRPART *p); + AVRMEM_ALIAS *avr_locate_memalias(const AVRPART *p, const char *desc); + AVRMEM_ALIAS *avr_find_memalias(const AVRPART *p, const AVRMEM *m_orig); + void avr_mem_display(FILE *f, const PROGRAMMER *pgm, const AVRPART *p, const char *prefix); + + // Functions for AVRPART structures + AVRPART *avr_new_part(void); + AVRPART *avr_dup_part(const AVRPART *d); + void avr_free_part(AVRPART *d); + AVRPART *locate_part(const LISTID parts, const char *partdesc); + AVRPART *locate_part_by_avr910_devcode(const LISTID parts, int devcode); + AVRPART *locate_part_by_signature(const LISTID parts, unsigned char *sig, int sigsize); + AVRPART *locate_part_by_signature_pm(const LISTID parts, unsigned char *sig, int sigsize, int prog_modes); + int avr_sig_compatible(const unsigned char *sig1, const unsigned char *sig2); + + char *avr_prog_modes(int pm), *str_prog_modes(int pm), *dev_prog_modes(int pm); + void avr_display(FILE *f, const PROGRAMMER *pgm, const AVRPART *p, const char *prefix, int verbose); + int avr_variants_display(FILE *f, const AVRPART *p, const char *prefix); + + typedef void (*walk_avrparts_cb)(const char *name, const char *desc, + const char *cfgname, int cfglineno, void *cookie); + void walk_avrparts(LISTID avrparts, walk_avrparts_cb cb, void *cookie); + void sort_avrparts(LISTID avrparts); + + // cmp can be, eg, str_caseeq or str_casematch + int part_eq(AVRPART *p, const char *string, int (*cmp)(const char *, const char *)); + + int compare_memory_masked(AVRMEM *m, uint8_t buf1, uint8_t buf2); #ifdef __cplusplus } #endif -/* formerly pindefs.h */ +// Formerly pindefs.h enum { PPI_AVR_VCC = 1, @@ -692,50 +666,47 @@ enum { }; #define PIN_MASK (UINT_MAX>>1) -#define PIN_INVERSE (~(PIN_MASK)) /* flag for inverted pin in serbb */ -#define PIN_MIN 0 /* smallest allowed pin number */ -#define PIN_MAX 31 /* largest allowed pin number */ +#define PIN_INVERSE (~(PIN_MASK)) // Flag for inverted pin in serbb +#define PIN_MIN 0 // Smallest allowed pin number +#define PIN_MAX 31 // Largest allowed pin number #ifdef HAVE_LINUXGPIO -/* Embedded systems might have a lot more gpio than only 0-31 */ + +// Embedded systems might have a lot more gpio than only 0-31 #undef PIN_MAX -#define PIN_MAX 1000 /* largest allowed pin number */ +#define PIN_MAX 1000 // Largest allowed pin number #endif -/** Number of pins in each element of the bitfield */ -#define PIN_FIELD_ELEMENT_SIZE (sizeof(Pinmask) * 8) -/** Numer of elements to store the complete bitfield of all pins */ +// Number of pins in each element of the bitfield +#define PIN_FIELD_ELEMENT_SIZE (sizeof(Pinmask)*8) + +// Numer of elements to store the complete bitfield of all pins #define PIN_FIELD_SIZE ((PIN_MAX+1 + PIN_FIELD_ELEMENT_SIZE-1)/PIN_FIELD_ELEMENT_SIZE) -/** - * This sets the corresponding bits to 1 or 0, the inverse mask is used to invert the value in necessary. - * It uses only the lowest element (index=0) of the bitfield, which should be enough for most - * programmers. +/* + * This sets the corresponding bits to 1 or 0, the inverse mask is used to + * invert the value in necessary. It uses only the lowest element (index=0) of + * the bitfield, which should be enough for most programmers. * * @param[in] x input value * @param[in] pgm the programmer whose pin definitions to use * @param[in] pinname the logical name of the pin (PIN_AVR_*, ...) * @param[in] level the logical level (level != 0 => 1, level == 0 => 0), - * if the pin is defined as inverted the resulting bit is also inverted + * if the pin is defined as inverted the resulting bit is + * also inverted * @returns the input value with the relevant bits modified */ -#define SET_BITS_0(x,pgm,pinname,level) (((x) & ~(pgm)->pin[pinname].mask[0]) \ - | (\ - (pgm)->pin[pinname].mask[0] & ( \ - (level) \ - ?~((pgm)->pin[pinname].inverse[0]) \ - : ((pgm)->pin[pinname].inverse[0]) \ - ) \ - ) \ +#define SET_BITS_0(x, pgm, pinname, level) ( ((x) & ~(pgm)->pin[pinname].mask[0]) | \ + ((pgm)->pin[pinname].mask[0] & ((level)? ~(pgm)->pin[pinname].inverse[0]: (pgm)->pin[pinname].inverse[0])) \ ) -/** - * Check if the corresponding bit is set (returns != 0) or cleared. - * The inverse mask is used, to invert the relevant bits. - * If the pin definition contains multiple pins, then a single set pin leads to return value != 0. - * Then you have to check the relevant bits of the returned value, if you need more information. - * It uses only the lowest element (index=0) of the bitfield, which should be enough for most - * programmers. +/* + * Check if the corresponding bit is set (returns != 0) or cleared. The inverse + * mask is used, to invert the relevant bits. If the pin definition contains + * multiple pins, then a single set pin leads to return value != 0. Then you + * have to check the relevant bits of the returned value, if you need more + * information. It uses only the lowest element (index=0) of the bitfield, + * which should be enough for most programmers. * * @param[in] x input value * @param[in] pgm the programmer whose pin definitions to use @@ -743,51 +714,47 @@ enum { * @returns the input value with only the relevant bits (which are already inverted, * so you get always the logical level) */ -#define GET_BITS_0(x,pgm,pinname) (((x) ^ (pgm)->pin[pinname].inverse[0]) & (pgm)->pin[pinname].mask[0]) +#define GET_BITS_0(x, pgm,pinname) (((x) ^ (pgm)->pin[pinname].inverse[0]) & (pgm)->pin[pinname].mask[0]) -/** - * Data structure to hold used pins by logical function (PIN_AVR_*, ...) - */ +// Data structure to hold used pins by logical function (PIN_AVR_*, ...) struct pindef { Pinmask mask[PIN_FIELD_SIZE]; ///< bitfield of used pins Pinmask inverse[PIN_FIELD_SIZE]; ///< bitfield of inverse/normal usage of used pins }; -/** - * Data structure to define a checklist of valid pins for each function. - */ +// Data structure to define a checklist of valid pins for each function typedef struct pin_checklist { - int pinname; ///< logical pinname eg. PIN_AVR_SCK - int mandatory; ///< is this a mandatory pin + int pinname; ///< logical pinname eg. PIN_AVR_SCK + int mandatory; ///< is this a mandatory pin const struct pindef *valid_pins; ///< mask defines allowed pins, inverse define is they might be used inverted } Pin_checklist; -/** +/* * Adds a pin in the pin definition as normal or inverse pin. * * @param[out] pindef pin definition to update * @param[in] pin number of pin [0..PIN_MAX] * @param[in] inverse inverse (true) or normal (false) pin */ -void pin_set_value(struct pindef * const pindef, const int pin, const bool inverse); +void pin_set_value(struct pindef *const pindef, const int pin, const bool inverse); -/** - * Clear all defined pins in pindef. +/* + * Clear all defined pins in pindef * * @param[out] pindef pin definition to clear */ -void pin_clear_all(struct pindef * const pindef); +void pin_clear_all(struct pindef *const pindef); -/** +/* * Convert for given programmer new pin definitions to old pin definitions. * * @param[inout] pgm programmer whose pins shall be converted. */ -int pgm_fill_old_pins(PROGRAMMER * const pgm); +int pgm_fill_old_pins(PROGRAMMER *const pgm); -/** +/* * This function checks all pin of pgm against the constraints given in the checklist. - * It checks if + * It checks if * @li any invalid pins are used * @li valid pins are used inverted when not allowed * @li any pins are used by more than one function @@ -803,117 +770,114 @@ int pgm_fill_old_pins(PROGRAMMER * const pgm); * @param[in] output false suppresses error messages to the user * @returns 0 if all pin definitions are valid, -1 otherwise */ -int pins_check(const PROGRAMMER * const pgm, const Pin_checklist * const checklist, const int size, const bool output); +int pins_check(const PROGRAMMER *const pgm, const Pin_checklist *const checklist, const int size, const bool output); -/** - * Returns the name of the pin as string. - * +/* + * Returns the name of the pin as string + * * @param pinname the pinname which we want as string. * @returns a string with the pinname, or if pinname is invalid. */ -const char * avr_pin_name(int pinname); +const char *avr_pin_name(int pinname); -/** - * Returns the name of the pin as lowercase string. +/* + * Returns the name of the pin as lowercase string * * @param pinname the pinname which we want as string. * @returns a lowercase string with the pinname, or if pinname is invalid. */ -const char * avr_pin_lcname(int pinname); +const char *avr_pin_lcname(int pinname); -/** +/* * This function returns a string of defined pins, eg, ~1, 2, ~4, ~5, 7 or "" * * @param[in] pindef the pin definition for which we want the string representation * @returns a temporary string that lives in closed-circuit space */ -const char *pins_to_str(const struct pindef * const pindef); +const char *pins_to_str(const struct pindef *const pindef); -/** +/* * This function returns a string representation of pins in the mask, eg, 1, 3, 5-7, 9, 12 * Consecutive pin numbers are represented as start-end. * * @param[in] pinmask the pin mask for which we want the string representation * @returns a temporary string that lives in closed-circuit space */ -const char *pinmask_to_str(const Pinmask * const pinmask); - -/* formerly serial.h */ +const char *pinmask_to_str(const Pinmask *const pinmask); -/* This is the API for the generic serial interface. The implementations are - actually provided by the target dependant files: +// Formerly serial.h - ser_posix.c : posix serial interface. - ser_win32.c : native win32 serial interface. - - The target file will be selected at configure time. */ +/* + * This is the API for the generic serial interface. The implementations are + * actually provided by the target dependant files: + * + * ser_posix.c : posix serial interface. + * ser_win32.c : native win32 serial interface. + * + * The target file will be selected at configure time. + */ -extern long serial_recv_timeout; /* ms */ -extern long serial_drain_timeout; /* ms */ +extern long serial_recv_timeout; // ms +extern long serial_drain_timeout; // ms -union filedescriptor -{ +union filedescriptor { int ifd; void *pfd; - struct - { + struct { void *handle; - int rep; /* bulk read endpoint */ - int wep; /* bulk write endpoint */ - int eep; /* event read endpoint */ - int max_xfer; /* max transfer size */ - int use_interrupt_xfer; /* device uses interrupt transfers */ + int rep; // Bulk read endpoint + int wep; // Bulk write endpoint + int eep; // Event read endpoint + int max_xfer; // Max transfer size + int use_interrupt_xfer; // Device uses interrupt transfers } usb; }; -#define SERIAL_CS5 0x0000 -#define SERIAL_CS6 0x0001 -#define SERIAL_CS7 0x0002 -#define SERIAL_CS8 0x0004 +#define SERIAL_CS5 0x0000 +#define SERIAL_CS6 0x0001 +#define SERIAL_CS7 0x0002 +#define SERIAL_CS8 0x0004 -#define SERIAL_NO_CSTOPB 0x0000 -#define SERIAL_CSTOPB 0x0008 +#define SERIAL_NO_CSTOPB 0x0000 +#define SERIAL_CSTOPB 0x0008 -#define SERIAL_NO_CREAD 0x0000 -#define SERIAL_CREAD 0x0010 +#define SERIAL_NO_CREAD 0x0000 +#define SERIAL_CREAD 0x0010 -#define SERIAL_NO_PARITY 0x0000 -#define SERIAL_PARENB 0x0020 -#define SERIAL_PARODD 0x0040 +#define SERIAL_NO_PARITY 0x0000 +#define SERIAL_PARENB 0x0020 +#define SERIAL_PARODD 0x0040 -#define SERIAL_NO_CLOCAL 0x0000 -#define SERIAL_CLOCAL 0x0080 +#define SERIAL_NO_CLOCAL 0x0000 +#define SERIAL_CLOCAL 0x0080 #define SERIAL_8N1 (SERIAL_CS8 | SERIAL_NO_CSTOPB | SERIAL_CREAD | SERIAL_NO_PARITY | SERIAL_CLOCAL) #define SERIAL_8E1 (SERIAL_CS8 | SERIAL_NO_CSTOPB | SERIAL_CREAD | SERIAL_PARENB | SERIAL_CLOCAL) #define SERIAL_8E2 (SERIAL_CS8 | SERIAL_CSTOPB | SERIAL_CREAD | SERIAL_PARENB | SERIAL_CLOCAL) -union pinfo -{ +union pinfo { struct { long baud; unsigned long cflags; } serialinfo; - struct - { + struct { unsigned short vid; unsigned short pid; unsigned short flags; -#define PINFO_FL_USEHID 0x0001 -#define PINFO_FL_SILENT 0x0002 /* don't complain if not found */ +#define PINFO_FL_USEHID 0x0001 +#define PINFO_FL_SILENT 0x0002 // Don't complain if not found } usbinfo; }; - struct serial_device { - // open should return -1 on error, other values on success + // Open should return -1 on error, other values on success int (*open)(const char *port, union pinfo pinfo, union filedescriptor *fd); int (*setparams)(const union filedescriptor *fd, long baud, unsigned long cflags); void (*close)(union filedescriptor *fd); - void (*rawclose)(union filedescriptor *fd); // Don't restore terminal attributes (Linux) + void (*rawclose)(union filedescriptor *fd); // Don't restore terminal attributes (Linux) - int (*send)(const union filedescriptor *fd, const unsigned char * buf, size_t buflen); - int (*recv)(const union filedescriptor *fd, unsigned char * buf, size_t buflen); + int (*send)(const union filedescriptor *fd, const unsigned char *buf, size_t buflen); + int (*recv)(const union filedescriptor *fd, unsigned char *buf, size_t buflen); int (*drain)(const union filedescriptor *fd, int display); int (*set_dtr_rts)(const union filedescriptor *fd, int is_on); @@ -921,8 +885,8 @@ struct serial_device { const char *usbsn; const char *usbproduct; int flags; -#define SERDEV_FL_NONE 0x0000 /* no flags */ -#define SERDEV_FL_CANSETSPEED 0x0001 /* device can change speed */ +#define SERDEV_FL_NONE 0 // No flags +#define SERDEV_FL_CANSETSPEED 1 // Device can change speed }; extern struct serial_device *serdev; @@ -945,14 +909,14 @@ extern struct serial_device usbhid_serdev; typedef struct { // Memory cache for a subset of cached pages int size, page_size; // Size of cache (flash or eeprom size) and page size unsigned int offset; // Offset of flash/eeprom memory - unsigned char *cont, *copy; // current memory contens and device copy of it + unsigned char *cont, *copy; // Current memory contens and device copy of it unsigned char *iscached; // iscached[i] set when page i has been loaded } AVR_Cache; -/* formerly pgm.h */ +// Formerly pgm.h -#define OFF 0 // Many contexts: reset, power, LEDs, ... -#define ON 1 // Many contexts +#define OFF 0 // Many contexts: reset, power, LEDs, ... +#define ON 1 // Many contexts #define PGM_TYPELEN 32 @@ -982,7 +946,6 @@ typedef enum { CONNTYPE_LINUXGPIO } Conntype; - #define LED_N 4 // Max number of LEDs driven by programmers #define LED_RDY 0 // led_set(pgm, LED_RDY) or led_clr(pgm, LED_RDY) #define LED_ERR 1 // led_set(pgm, LED_ERR) or led_clr(pgm, LED_ERR) @@ -1006,13 +969,12 @@ typedef struct { * - lexer.l * - Either Component avr_comp[] of config.c or config_gram.y * - dev_pgm_strct() in developer_opts.c - * - pgm_new() in pgm.c for initialisation; note that all const char * must - * be initialised with "" + * - pgm_new() in pgm.c for initialisation; note that all const char * must be initialised with "" */ typedef struct programmer { LISTID id; const char *desc; - void (*initpgm)(PROGRAMMER *pgm); // Sets up the AVRDUDE programmer + void (*initpgm)(PROGRAMMER *pgm); // Sets up the AVRDUDE programmer LISTID comments; // Used by developer options -c*/[ASsr...] const char *parent_id; // Used by developer options int prog_modes; // Programming interfaces, see #define PM_... @@ -1033,7 +995,7 @@ typedef struct programmer { union filedescriptor fd; char type[PGM_TYPELEN]; const char *port; - unsigned int pinno[N_PINS]; // TODO to be removed if old pin data no longer needed + unsigned int pinno[N_PINS]; // TODO: to be removed if old pin data no longer needed Exit_vcc exit_vcc; // Should these be set in avrdude.conf? Exit_reset exit_reset; Exit_datahigh exit_datahigh; @@ -1044,72 +1006,81 @@ typedef struct programmer { double bitclock; // JTAG ICE clock period in microseconds Leds *leds; // State of LEDs as tracked by led_...() functions in leds.c - int (*rdy_led) (const PROGRAMMER *pgm, int value); - int (*err_led) (const PROGRAMMER *pgm, int value); - int (*pgm_led) (const PROGRAMMER *pgm, int value); - int (*vfy_led) (const PROGRAMMER *pgm, int value); - int (*initialize) (const PROGRAMMER *pgm, const AVRPART *p); // Sets up the physical programmer - void (*display) (const PROGRAMMER *pgm, const char *p); - void (*enable) (PROGRAMMER *pgm, const AVRPART *p); - void (*disable) (const PROGRAMMER *pgm); - void (*powerup) (const PROGRAMMER *pgm); - void (*powerdown) (const PROGRAMMER *pgm); - int (*program_enable) (const PROGRAMMER *pgm, const AVRPART *p); - int (*chip_erase) (const PROGRAMMER *pgm, const AVRPART *p); - int (*unlock) (const PROGRAMMER *pgm, const AVRPART *p); - int (*cmd) (const PROGRAMMER *pgm, const unsigned char *cmd, unsigned char *res); - int (*cmd_tpi) (const PROGRAMMER *pgm, const unsigned char *cmd, int cmd_len, unsigned char *res, int res_len); - int (*spi) (const PROGRAMMER *pgm, const unsigned char *cmd, unsigned char *res, int count); - int (*open) (PROGRAMMER *pgm, const char *port); - void (*close) (PROGRAMMER *pgm); - int (*paged_write) (const PROGRAMMER *pgm, const AVRPART *p, const AVRMEM *m, unsigned int pg_size, unsigned int addr, unsigned int n); - int (*paged_load) (const PROGRAMMER *pgm, const AVRPART *p, const AVRMEM *m, unsigned int pg_size, unsigned int addr, unsigned int n); - int (*page_erase) (const PROGRAMMER *pgm, const AVRPART *p, const AVRMEM *m, unsigned int addr); - void (*write_setup) (const PROGRAMMER *pgm, const AVRPART *p, const AVRMEM *m); - int (*write_byte) (const PROGRAMMER *pgm, const AVRPART *p, const AVRMEM *m, unsigned long addr, unsigned char value); - int (*read_byte) (const PROGRAMMER *pgm, const AVRPART *p, const AVRMEM *m, unsigned long addr, unsigned char *value); - int (*read_sig_bytes) (const PROGRAMMER *pgm, const AVRPART *p, const AVRMEM *m); - int (*read_sib) (const PROGRAMMER *pgm, const AVRPART *p, char *sib); - int (*read_chip_rev) (const PROGRAMMER *pgm, const AVRPART *p, unsigned char *chip_rev); - int (*term_keep_alive)(const PROGRAMMER *pgm, const AVRPART *p); - int (*end_programming)(const PROGRAMMER *pgm, const AVRPART *p); - - void (*print_parms) (const PROGRAMMER *pgm, FILE *fp); - int (*set_vtarget) (const PROGRAMMER *pgm, double v); - int (*get_vtarget) (const PROGRAMMER *pgm, double *v); - int (*set_varef) (const PROGRAMMER *pgm, unsigned int chan, double v); - int (*get_varef) (const PROGRAMMER *pgm, unsigned int chan, double *v); - int (*set_fosc) (const PROGRAMMER *pgm, double v); - int (*get_fosc) (const PROGRAMMER *pgm, double *v); - int (*set_sck_period) (const PROGRAMMER *pgm, double v); - int (*get_sck_period) (const PROGRAMMER *pgm, double *v); - int (*setpin) (const PROGRAMMER *pgm, int pinfunc, int value); - int (*getpin) (const PROGRAMMER *pgm, int pinfunc); - int (*highpulsepin) (const PROGRAMMER *pgm, int pinfunc); - int (*parseexitspecs) (PROGRAMMER *pgm, const char *s); - int (*perform_osccal) (const PROGRAMMER *pgm); - int (*parseextparams) (const PROGRAMMER *pgm, const LISTID xparams); - void (*setup) (PROGRAMMER *pgm); - void (*teardown) (PROGRAMMER *pgm); - int (*flash_readhook) (const PROGRAMMER *pgm, const AVRPART *p, const AVRMEM *flm, const char *fname, int size); + int (*rdy_led)(const PROGRAMMER *pgm, int value); + int (*err_led)(const PROGRAMMER *pgm, int value); + int (*pgm_led)(const PROGRAMMER *pgm, int value); + int (*vfy_led)(const PROGRAMMER *pgm, int value); + int (*initialize)(const PROGRAMMER *pgm, const AVRPART *p); // Sets up the physical programmer + void (*display)(const PROGRAMMER *pgm, const char *p); + void (*enable)(PROGRAMMER *pgm, const AVRPART *p); + void (*disable)(const PROGRAMMER *pgm); + void (*powerup)(const PROGRAMMER *pgm); + void (*powerdown)(const PROGRAMMER *pgm); + int (*program_enable)(const PROGRAMMER *pgm, const AVRPART *p); + int (*chip_erase)(const PROGRAMMER *pgm, const AVRPART *p); + int (*unlock)(const PROGRAMMER *pgm, const AVRPART *p); + int (*cmd)(const PROGRAMMER *pgm, const unsigned char *cmd, unsigned char *res); + int (*cmd_tpi)(const PROGRAMMER *pgm, const unsigned char *cmd, int cmd_len, + unsigned char *res, int res_len); + int (*spi)(const PROGRAMMER *pgm, const unsigned char *cmd, unsigned char *res, int count); + int (*open)(PROGRAMMER *pgm, const char *port); + void (*close)(PROGRAMMER *pgm); + int (*paged_write)(const PROGRAMMER *pgm, const AVRPART *p, const AVRMEM *m, + unsigned int pg_size, unsigned int addr, unsigned int n); + int (*paged_load)(const PROGRAMMER *pgm, const AVRPART *p, const AVRMEM *m, + unsigned int pg_size, unsigned int addr, unsigned int n); + int (*page_erase)(const PROGRAMMER *pgm, const AVRPART *p, const AVRMEM *m, unsigned int addr); + void (*write_setup)(const PROGRAMMER *pgm, const AVRPART *p, const AVRMEM *m); + int (*write_byte)(const PROGRAMMER *pgm, const AVRPART *p, const AVRMEM *m, + unsigned long addr, unsigned char value); + int (*read_byte)(const PROGRAMMER *pgm, const AVRPART *p, const AVRMEM *m, + unsigned long addr, unsigned char *value); + int (*read_sig_bytes)(const PROGRAMMER *pgm, const AVRPART *p, const AVRMEM *m); + int (*read_sib)(const PROGRAMMER *pgm, const AVRPART *p, char *sib); + int (*read_chip_rev)(const PROGRAMMER *pgm, const AVRPART *p, unsigned char *chip_rev); + int (*term_keep_alive)(const PROGRAMMER *pgm, const AVRPART *p); + int (*end_programming)(const PROGRAMMER *pgm, const AVRPART *p); + + void (*print_parms)(const PROGRAMMER *pgm, FILE *fp); + int (*set_vtarget)(const PROGRAMMER *pgm, double v); + int (*get_vtarget)(const PROGRAMMER *pgm, double *v); + int (*set_varef)(const PROGRAMMER *pgm, unsigned int chan, double v); + int (*get_varef)(const PROGRAMMER *pgm, unsigned int chan, double *v); + int (*set_fosc)(const PROGRAMMER *pgm, double v); + int (*get_fosc)(const PROGRAMMER *pgm, double *v); + int (*set_sck_period)(const PROGRAMMER *pgm, double v); + int (*get_sck_period)(const PROGRAMMER *pgm, double *v); + int (*setpin)(const PROGRAMMER *pgm, int pinfunc, int value); + int (*getpin)(const PROGRAMMER *pgm, int pinfunc); + int (*highpulsepin)(const PROGRAMMER *pgm, int pinfunc); + int (*parseexitspecs)(PROGRAMMER *pgm, const char *s); + int (*perform_osccal)(const PROGRAMMER *pgm); + int (*parseextparams)(const PROGRAMMER *pgm, const LISTID xparams); + void (*setup)(PROGRAMMER *pgm); + void (*teardown)(PROGRAMMER *pgm); + int (*flash_readhook)(const PROGRAMMER *pgm, const AVRPART *p, const AVRMEM *flm, + const char *fname, int size); // Cached r/w API for terminal reads/writes - int (*write_byte_cached)(const PROGRAMMER *pgm, const AVRPART *p, const AVRMEM *m, unsigned long addr, unsigned char value); - int (*read_byte_cached)(const PROGRAMMER *pgm, const AVRPART *p, const AVRMEM *m, unsigned long addr, unsigned char *value); + int (*write_byte_cached)(const PROGRAMMER *pgm, const AVRPART *p, const AVRMEM *m, + unsigned long addr, unsigned char value); + int (*read_byte_cached)(const PROGRAMMER *pgm, const AVRPART *p, const AVRMEM *m, + unsigned long addr, unsigned char *value); int (*chip_erase_cached)(const PROGRAMMER *pgm, const AVRPART *p); - int (*page_erase_cached)(const PROGRAMMER *pgm, const AVRPART *p, const AVRMEM *m, unsigned int addr); - int (*readonly) (const PROGRAMMER *pgm, const AVRPART *p, const AVRMEM *m, unsigned int addr); - int (*flush_cache) (const PROGRAMMER *pgm, const AVRPART *p); - int (*reset_cache) (const PROGRAMMER *pgm, const AVRPART *p); + int (*page_erase_cached)(const PROGRAMMER *pgm, const AVRPART *p, const AVRMEM *m, + unsigned int addr); + int (*readonly)(const PROGRAMMER *pgm, const AVRPART *p, const AVRMEM *m, unsigned int addr); + int (*flush_cache)(const PROGRAMMER *pgm, const AVRPART *p); + int (*reset_cache)(const PROGRAMMER *pgm, const AVRPART *p); AVR_Cache *cp_flash, *cp_eeprom, *cp_bootrow, *cp_usersig; const char *config_file; // Config file where defined - int lineno; // Config file line number + int lineno; // Config file line number void *cookie; // For private use by the programmer char flag; // For use by pgm->initpgm() } PROGRAMMER; -typedef PROGRAMMER SERIALADAPTER; // Only a subset is needed for serial adapters +typedef PROGRAMMER SERIALADAPTER; // Only a subset is needed for serial adapters int is_programmer(const PROGRAMMER *p); int is_serialadapter(const SERIALADAPTER *p); void list_serialadapters(FILE *fp, const char *prefix, LISTID programmers); @@ -1121,38 +1092,38 @@ void serialadapter_not_found(const char *sea_id); extern "C" { #endif -void pgm_init_functions(PROGRAMMER *pgm); -PROGRAMMER * pgm_new(void); -PROGRAMMER * pgm_dup(const PROGRAMMER *src); -void pgm_free(PROGRAMMER *p); + void pgm_init_functions(PROGRAMMER *pgm); + PROGRAMMER *pgm_new(void); + PROGRAMMER *pgm_dup(const PROGRAMMER *src); + void pgm_free(PROGRAMMER *p); + void programmer_display(PROGRAMMER *pgm, const char *p); -void programmer_display(PROGRAMMER * pgm, const char * p); - -/* show is a mask like this (1<size-1] - lastaddr; // Highest address set by input file + nsections, // Number of consecutive sections in source excluding cut off, trailing 0xff + npages, // Number of memory pages needed excluding pages solely with trailing 0xff + nfill, // Number of fill bytes to make up full pages that are needed + ntrailing, // Number of trailing 0xff in source + firstaddr, // First address set in [0, mem->size-1] + lastaddr; // Highest address set by input file } Filestats; - #ifdef __cplusplus extern "C" { #endif -UPDATE *parse_op(const char *s); -UPDATE *dup_update(const UPDATE *upd); -UPDATE *new_update(int op, const char *memstr, int filefmt, const char *fname); -UPDATE *cmd_update(const char *cmd); -extern void free_update(UPDATE *upd); -char *update_str(const UPDATE *upd); -int do_op(const PROGRAMMER *pgm, const AVRPART *p, const UPDATE *upd, - enum updateflags flags); -int memstats(const AVRPART *p, const char *memstr, int size, Filestats *fsp); -int memstats_mem(const AVRPART *p, const AVRMEM *mem, int size, Filestats *fsp); + UPDATE *parse_op(const char *s); + UPDATE *dup_update(const UPDATE *upd); + UPDATE *new_update(int op, const char *memstr, int filefmt, const char *fname); + UPDATE *cmd_update(const char *cmd); + extern void free_update(UPDATE *upd); + char *update_str(const UPDATE *upd); + int do_op(const PROGRAMMER *pgm, const AVRPART *p, const UPDATE *upd, + enum updateflags flags); + int memstats(const AVRPART *p, const char *memstr, int size, Filestats *fsp); + int memstats_mem(const AVRPART *p, const AVRMEM *mem, int size, Filestats *fsp); -// Helper functions for dry run to determine file access -int update_is_okfile(const char *fn); -int update_is_writeable(const char *fn); -int update_is_readable(const char *fn); + // Helper functions for dry run to determine file access + int update_is_okfile(const char *fn); + int update_is_writeable(const char *fn); + int update_is_readable(const char *fn); -int update_dryrun(const AVRPART *p, UPDATE *upd); + int update_dryrun(const AVRPART *p, UPDATE *upd); -AVRMEM **memory_list(const char *mstr, const PROGRAMMER *pgm, const AVRPART *p, int *np, int *rwvsoftp, int *dry); -int memlist_contains_flash(const char *mstr, const AVRPART *p); + AVRMEM **memory_list(const char *mstr, const PROGRAMMER *pgm, const AVRPART *p, + int *np, int *rwvsoftp, int *dry); + int memlist_contains_flash(const char *mstr, const AVRPART *p); #ifdef __cplusplus } #endif - -/* formerly pgm_type.h */ - -/*LISTID programmer_types;*/ +// Formerly pgm_type.h typedef struct programmer_type { - const char * const id; + const char *const id; void (*initpgm)(PROGRAMMER *pgm); - const char * const desc; + const char *const desc; } PROGRAMMER_TYPE; #ifdef __cplusplus extern "C" { #endif -const PROGRAMMER_TYPE *locate_programmer_type(const char *id); - -const char *locate_programmer_type_id(void (*initpgm)(PROGRAMMER *pgm)); - -typedef void (*walk_programmer_types_cb)(const char *id, const char *desc, - void *cookie); -void walk_programmer_types(/*LISTID programmer_types,*/ walk_programmer_types_cb cb, void *cookie); + const PROGRAMMER_TYPE *locate_programmer_type(const char *id); + const char *locate_programmer_type_id(void (*initpgm)(PROGRAMMER *pgm)); + typedef void (*walk_programmer_types_cb)(const char *id, const char *desc, void *cookie); + void walk_programmer_types(walk_programmer_types_cb cb, void *cookie); #ifdef __cplusplus } #endif -/* formerly config.h */ +// Formerly config.h -extern LISTID part_list; -extern LISTID programmers; +extern LISTID part_list; +extern LISTID programmers; extern const char *avrdude_conf_version; extern const char *default_programmer; extern const char *default_parallel; extern const char *default_serial; extern const char *default_spi; -extern int default_baudrate; -extern double default_bitclock; +extern int default_baudrate; +extern double default_bitclock; extern char const *default_linuxgpio; -extern int allow_subshells; +extern int allow_subshells; -/* This name is fixed, it's only here for symmetry with - * default_parallel and default_serial. */ -#define DEFAULT_USB "usb" +// This name is fixed, it's only here for symmetry with default_parallel and default_serial +#define DEFAULT_USB "usb" #ifdef __cplusplus extern "C" { #endif -void *cfg_malloc(const char *funcname, size_t n); -void *cfg_realloc(const char *funcname, void *p, size_t n); -char *cfg_strdup(const char *funcname, const char *s); -void mmt_f_free(void *ptr); - -int init_config(void); - -void cleanup_config(void); - -int read_config(const char * file); - -const char *cache_string(const char *file); - -unsigned char *cfg_unescapeu(unsigned char *d, const unsigned char *s); - -char *cfg_unescape(char *d, const char *s); - -char *cfg_escape(const char *s); + void *cfg_malloc(const char *funcname, size_t n); + void *cfg_realloc(const char *funcname, void *p, size_t n); + char *cfg_strdup(const char *funcname, const char *s); + void mmt_f_free(void *ptr); + int init_config(void); + void cleanup_config(void); + int read_config(const char *file); + const char *cache_string(const char *file); + unsigned char *cfg_unescapeu(unsigned char *d, const unsigned char *s); + char *cfg_unescape(char *d, const char *s); + char *cfg_escape(const char *s); #ifdef __cplusplus } @@ -1503,19 +1419,21 @@ typedef struct { #define STR_ANY 1023 // Any of above // Abbreviations for specific types -#define STR_INT8 (STR_1 | STR_SIGNED) // Signed domain [-2^(n-1), 2^(n-1)-1] +#define STR_INT8 (STR_1 | STR_SIGNED) // Signed domain [-2^(n-1), 2^(n-1)-1] #define STR_INT16 (STR_2 | STR_SIGNED) #define STR_INT32 (STR_4 | STR_SIGNED) #define STR_INT64 (STR_8 | STR_SIGNED) #define STR_UINT8 (STR_1 | STR_UNSIGNED) // Unsigned domain [0, 2^n-1]; -u is same as 2^n-u #define STR_UINT16 (STR_2 | STR_UNSIGNED) // Unsigned number u is deemed out of range -#define STR_UINT32 (STR_4 | STR_UNSIGNED) // if both u and -u are outside unsigned domain +#define STR_UINT32 (STR_4 | STR_UNSIGNED) // If both u and -u are outside unsigned domain #define STR_UINT64 (STR_8 | STR_UNSIGNED) -#define STR_XINT8 STR_1 // Unspecified signedness: numbers can occupy the asymmetric union -#define STR_XINT16 STR_2 // of signed domain and unsigned domain: [-2^(n-1), 2^n-1] +#define STR_XINT8 STR_1 // Unspecified signedness: numbers can occupy the asymmetric union +#define STR_XINT16 STR_2 // of signed domain and unsigned domain: [-2^(n-1), 2^n-1] #define STR_XINT32 STR_4 #define STR_XINT64 STR_8 +// AVR opcodes and disassembly + typedef enum { OP_AVRe, OP_AVRxm, @@ -1541,7 +1459,7 @@ typedef struct { int address; int type; // I: I/O vars, M: mem vars, L: labels, P: PGM vars int subtype; // B: byte, W: word, A: autoterminated string, S: string - int count; // array length for tag file variables + int count; // Array length for tag file variables int used; // Whether symbol was referenced by disassembly process int printed; // Whether this L/P label will be printed in pass 2 } Dis_symbol; @@ -1594,19 +1512,19 @@ typedef enum { } AVR_mnemo; typedef enum { - OP_AVR_RC = 1, // Reduced-core Tiny only (128 byte STS/LDS) - OP_AVR1 = 2, // All AVR can run this OPCODE - OP_AVR1nRC = 4, // All except reduced-core Tiny (TPI) and AT90S1200 - OP_AVR2 = 8, // AVR with archnum 2 and above - OP_AVR2nRC = 16, // AVR with archnum 2+ but not reduced-core Tiny - OP_AVR25 = 32, // AVR with archnum 25 and above - OP_AVR_M = 64, // AVR with flash > 8 kB or archnum 3+ (JMP, CALL) - OP_AVR4 = 128, // AVR with archnum 4 and above - OP_AVR_L = 256, // AVR with flash > 64 kB (ELMP) - OP_AVR_XL = 512, // AVR with flash > 128 kB (EIJMP, EICALL) - OP_AVR_XM = 1024, // XMEGA only (DES, XCH, LAC, LAS, LAT) - OP_AVR_XTM = 2048, // XMEGA and UPDI only (SPM Z+) - OP_AVR_ILL = 4096, // Undocumented (illegal) opcodes + OP_AVR_RC = 1, // Reduced-core Tiny only (128 byte STS/LDS) + OP_AVR1 = 2, // All AVR can run this OPCODE + OP_AVR1nRC = 4, // All except reduced-core Tiny (TPI) and AT90S1200 + OP_AVR2 = 8, // AVR with archnum 2 and above + OP_AVR2nRC = 16, // AVR with archnum 2+ but not reduced-core Tiny + OP_AVR25 = 32, // AVR with archnum 25 and above + OP_AVR_M = 64, // AVR with flash > 8 kB or archnum 3+ (JMP, CALL) + OP_AVR4 = 128, // AVR with archnum 4 and above + OP_AVR_L = 256, // AVR with flash > 64 kB (ELMP) + OP_AVR_XL = 512, // AVR with flash > 128 kB (EIJMP, EICALL) + OP_AVR_XM = 1024, // XMEGA only (DES, XCH, LAC, LAS, LAT) + OP_AVR_XTM = 2048, // XMEGA and UPDI only (SPM Z+) + OP_AVR_ILL = 4096, // Undocumented (illegal) opcodes } AVR_archlevel; /* @@ -1627,7 +1545,7 @@ typedef enum { #define PART_AVR6 (OP_AVR1|OP_AVR1nRC|OP_AVR2|OP_AVR2nRC|OP_AVR25|OP_AVR4|OP_AVR_M|OP_AVR_L|OP_AVR_XL) #define PART_AVR_XT (OP_AVR1|OP_AVR1nRC|OP_AVR2|OP_AVR2nRC|OP_AVR25|OP_AVR4|OP_AVR_M|OP_AVR_XTM) #define PART_AVR_XM (OP_AVR1|OP_AVR1nRC|OP_AVR2|OP_AVR2nRC|OP_AVR25|OP_AVR4|OP_AVR_M|OP_AVR_XM|OP_AVR_XTM) -#define PART_ALL (PART_AVR_XM|OP_AVR_L|OP_AVR_XL) // All but RC (the latter conflicts) +#define PART_ALL (PART_AVR_XM|OP_AVR_L|OP_AVR_XL) // All but RC (the latter conflicts) // Opcode types #define OTY_REG_MASK 7 // Register formula mask @@ -1672,13 +1590,13 @@ typedef struct { const char *bits; // "0000 11rd dddd rrrr" int type; // OTY_ALBI|OTY_RALL const char - *opcode, // "add" - *operands, // "Rd, Rr" - *description, // "add without carry" - *operation, // "Rd <-- Rd + Rr" - *flags, // "--HSVNZC" - *clock[OP_AVR_cycle_N], // Timings for AVRe, AVRxm, AVRxt and AVRrc - *remarks; + *opcode, // "add" + *operands, // "Rd, Rr" + *description, // "add without carry" + *operation, // "Rd <-- Rd + Rr" + *flags, // "--HSVNZC" + *clock[OP_AVR_cycle_N], // Timings for AVRe, AVRxm, AVRxt and AVRrc + *remarks; } AVR_opcode; extern const AVR_opcode avr_opcodes[164]; @@ -1687,145 +1605,148 @@ extern const AVR_opcode avr_opcodes[164]; extern "C" { #endif -int avr_locate_upidx(const AVRPART *p); -const Avrintel *avr_locate_uP(const AVRPART *p); -const Configitem *avr_locate_configitems(const AVRPART *p, int *ncp); -const char * const *avr_locate_isrtable(const AVRPART *p, int *nip); -const Register_file *avr_locate_register_file(const AVRPART *p, int *nrp); -const Register_file *avr_locate_register(const Register_file *rgf, int nr, const char *reg, - int (*match)(const char *, const char*)); -const Register_file **avr_locate_registerlist(const Register_file *rgf, int nr, const char *reg, - int (*match)(const char *, const char*)); -const Configitem *avr_locate_config(const Configitem *cfg, int nc, const char *name, - int (*match)(const char *, const char*)); -const Configitem **avr_locate_configlist(const Configitem *cfg, int nc, const char *name, - int (*match)(const char *, const char*)); -int avr_get_config_value(const PROGRAMMER *pgm, const AVRPART *p, const char *cname, int *valuep); -int avr_set_config_value(const PROGRAMMER *pgm, const AVRPART *p, const char *cname, int value); - -int setport_from_serialadapter(char **portp, const SERIALADAPTER *ser, const char *sernum); -int setport_from_vid_pid(char **portp, int vid, int pid, const char *sernum); -int list_available_serialports(LISTID programmers); -int touch_serialport(char **portp, int baudrate, int nwaits); - -int str_starts(const char *str, const char *starts); -int str_eq(const char *str1, const char *str2); -int str_contains(const char *str, const char *substr); -int str_ends(const char *str, const char *ends); -int str_casestarts(const char *str, const char *starts); -int str_caseends(const char *str, const char *ends); -int str_caseeq(const char *str1, const char *str2); -int str_match(const char *pattern, const char *string); -int str_casematch(const char *pattern, const char *string); -int str_matched_by(const char *string, const char *pattern); -int str_casematched_by(const char *string, const char *pattern); -int str_is_pattern(const char *str); -int str_is_in_list(const char *s, const char **l, size_t nl, int (*f)(const char *, const char*)); -char *str_sprintf(const char *fmt, ...) + int avr_locate_upidx(const AVRPART *p); + const Avrintel *avr_locate_uP(const AVRPART *p); + const Configitem *avr_locate_configitems(const AVRPART *p, int *ncp); + const char *const *avr_locate_isrtable(const AVRPART *p, int *nip); + const Register_file *avr_locate_register_file(const AVRPART *p, int *nrp); + const Register_file *avr_locate_register(const Register_file *rgf, int nr, const char *reg, + int (*match)(const char *, const char *)); + const Register_file **avr_locate_registerlist(const Register_file *rgf, int nr, const char *reg, + int (*match)(const char *, const char *)); + const Configitem *avr_locate_config(const Configitem *cfg, int nc, const char *name, + int (*match)(const char *, const char *)); + const Configitem **avr_locate_configlist(const Configitem *cfg, int nc, const char *name, + int (*match)(const char *, const char *)); + int avr_get_config_value(const PROGRAMMER *pgm, const AVRPART *p, const char *cname, int *valuep); + int avr_set_config_value(const PROGRAMMER *pgm, const AVRPART *p, const char *cname, int value); + + int setport_from_serialadapter(char **portp, const SERIALADAPTER *ser, const char *sernum); + int setport_from_vid_pid(char **portp, int vid, int pid, const char *sernum); + int list_available_serialports(LISTID programmers); + int touch_serialport(char **portp, int baudrate, int nwaits); + + int str_starts(const char *str, const char *starts); + int str_eq(const char *str1, const char *str2); + int str_contains(const char *str, const char *substr); + int str_ends(const char *str, const char *ends); + int str_casestarts(const char *str, const char *starts); + int str_caseends(const char *str, const char *ends); + int str_caseeq(const char *str1, const char *str2); + int str_match(const char *pattern, const char *string); + int str_casematch(const char *pattern, const char *string); + int str_matched_by(const char *string, const char *pattern); + int str_casematched_by(const char *string, const char *pattern); + int str_is_pattern(const char *str); + int str_is_in_list(const char *s, const char **l, size_t nl, int (*f)(const char *, const char *)); + char *str_sprintf(const char *fmt, ...) #if defined(__GNUC__) // Ask gcc to check whether format and parameters match - __attribute__ ((format (printf, 1, 2))) + __attribute__((format(printf, 1, 2))) #endif -; -const char *str_ccprintf(const char *fmt, ...) + ; + const char *str_ccprintf(const char *fmt, ...) #if defined(__GNUC__) - __attribute__ ((format (printf, 1, 2))) + __attribute__((format(printf, 1, 2))) #endif -; -const char *str_ccstrdup(const char *str); -char *str_fgets(FILE *fp, const char **errpp); -size_t str_numc(const char *str, char c); -const char *str_ltrim(const char *s); -char *str_nrtrim(char *s, size_t n); -char *str_rtrim(char *s); -char *str_ntrim(char *s, size_t n); -char *str_trim(char *s); -char *str_lc(char *s); -char *str_uc(char *s); -char *str_lcfirst(char *s); -char *str_ucfirst(char *s); -char *str_asciiname(char *s); -char *str_utoa(unsigned n, char *buf, int base); -char *str_endnumber(const char *str); -const char *str_plural(int x); -const char *str_inname(const char *fn); -const char *str_infilename(const char *fn); -const char *str_outname(const char *fn); -const char *str_outfilename(const char *fn); -const char *str_ccinterval(int a, int b); -bool is_bigendian(void); -void change_endian(void *p, int size); -int is_memset(const void *p, char c, size_t n); -unsigned long long int str_ull(const char *str, char **endptr, int base); -int looks_like_number(const char *str); -Str2data *str_todata(const char *str, int type, const AVRPART *part, const char *memstr); -void str_freedata(Str2data *sd); -unsigned long long int str_int(const char *str, int type, const char **errpp); -int str_membuf(const char *str, int type, unsigned char *buf, int size, const char **errpp); -char *str_nexttok(char *buf, const char *delim, char **next); -const char *str_ccfrq(double f, int n); -const char *str_cchex(const void *buf, size_t len, int add_space); -int str_levenshtein(const char *str1, const char *str2, int swap, int subst, int add, int del); -size_t str_weighted_damerau_levenshtein(const char *str1, const char *str2); -int str_mcunames_signature(const unsigned char *sigs, int pm, char *p, size_t n); -const char *str_ccmcunames_signature(const unsigned char *sigs, int pm); -const char *str_ccpgmids(LISTID pgm_id); - -int led_set(const PROGRAMMER *pgm, int led); -int led_clr(const PROGRAMMER *pgm, int led); -int led_chip_erase(const PROGRAMMER *pgm, const AVRPART *p); -int led_write_byte(const PROGRAMMER *pgm, const AVRPART *p, const AVRMEM *m, unsigned long addr, unsigned char value); -int led_read_byte(const PROGRAMMER *pgm, const AVRPART *p, const AVRMEM *m, unsigned long addr, unsigned char *value); -int led_paged_write(const PROGRAMMER *pgm, const AVRPART *p, const AVRMEM *m, unsigned int page_size, unsigned int addr, unsigned int n); -int led_paged_load(const PROGRAMMER *pgm, const AVRPART *p, const AVRMEM *m, unsigned int page_size, unsigned int addr, unsigned int n); -int led_page_erase(const PROGRAMMER *pgm, const AVRPART *p, const AVRMEM *m, unsigned int addr); - -int terminal_mode(const PROGRAMMER *pgm, const AVRPART *p); -int terminal_mode_noninteractive(const PROGRAMMER *pgm, const AVRPART *p); -int terminal_line(const PROGRAMMER *pgm, const AVRPART *p, const char *line); -char *terminal_get_input(const char *prompt); -void terminal_setup_update_progress(void); - -char *avr_cc_buffer(size_t n); - -int op16_is_mnemo(int op16, AVR_mnemo mnemo); -int is_opcode32(int op16); -int op_width(int op16); -int ldi_Rd(int op16); -int ldi_K(int op16); -AVR_mnemo opcode_mnemo(int op16, int avrlevel); -int op16_is_valid(int op16, int avrlevel); -int op16_is_benign(int op16, int avrlevel); -int avr_get_archlevel(const AVRPART *p); -AVR_cycle_index avr_get_cycle_index(const AVRPART *p); -const char *mnemo_str(int op16); -int z_width(int op16, AVR_mnemo *mnenop); -int op16_target(int here, int op16); -int dist2rjmp(int dist); - -int disasm(const char *buf, int len, int addr, int leadin, int leadout); -int disasm_init(const AVRPART *p); -int disasm_init_tagfile(const AVRPART *p, const char *file); -void disasm_zap_jumpcalls(); + ; + const char *str_ccstrdup(const char *str); + char *str_fgets(FILE *fp, const char **errpp); + size_t str_numc(const char *str, char c); + const char *str_ltrim(const char *s); + char *str_nrtrim(char *s, size_t n); + char *str_rtrim(char *s); + char *str_ntrim(char *s, size_t n); + char *str_trim(char *s); + char *str_lc(char *s); + char *str_uc(char *s); + char *str_lcfirst(char *s); + char *str_ucfirst(char *s); + char *str_asciiname(char *s); + char *str_utoa(unsigned n, char *buf, int base); + char *str_endnumber(const char *str); + const char *str_plural(int x); + const char *str_inname(const char *fn); + const char *str_infilename(const char *fn); + const char *str_outname(const char *fn); + const char *str_outfilename(const char *fn); + const char *str_ccinterval(int a, int b); + bool is_bigendian(void); + void change_endian(void *p, int size); + int is_memset(const void *p, char c, size_t n); + unsigned long long int str_ull(const char *str, char **endptr, int base); + int looks_like_number(const char *str); + Str2data *str_todata(const char *str, int type, const AVRPART *part, const char *memstr); + void str_freedata(Str2data *sd); + unsigned long long int str_int(const char *str, int type, const char **errpp); + int str_membuf(const char *str, int type, unsigned char *buf, int size, const char **errpp); + char *str_nexttok(char *buf, const char *delim, char **next); + const char *str_ccfrq(double f, int n); + const char *str_cchex(const void *buf, size_t len, int add_space); + int str_levenshtein(const char *str1, const char *str2, int swap, int subst, int add, int del); + size_t str_weighted_damerau_levenshtein(const char *str1, const char *str2); + int str_mcunames_signature(const unsigned char *sigs, int pm, char *p, size_t n); + const char *str_ccmcunames_signature(const unsigned char *sigs, int pm); + const char *str_ccpgmids(LISTID pgm_id); + + int led_set(const PROGRAMMER *pgm, int led); + int led_clr(const PROGRAMMER *pgm, int led); + int led_chip_erase(const PROGRAMMER *pgm, const AVRPART *p); + int led_write_byte(const PROGRAMMER *pgm, const AVRPART *p, const AVRMEM *m, + unsigned long addr, unsigned char value); + int led_read_byte(const PROGRAMMER *pgm, const AVRPART *p, const AVRMEM *m, + unsigned long addr, unsigned char *value); + int led_paged_write(const PROGRAMMER *pgm, const AVRPART *p, const AVRMEM *m, + unsigned int page_size, unsigned int addr, unsigned int n); + int led_paged_load(const PROGRAMMER *pgm, const AVRPART *p, const AVRMEM *m, + unsigned int page_size, unsigned int addr, unsigned int n); + int led_page_erase(const PROGRAMMER *pgm, const AVRPART *p, const AVRMEM *m, unsigned int addr); + + int terminal_mode(const PROGRAMMER *pgm, const AVRPART *p); + int terminal_mode_noninteractive(const PROGRAMMER *pgm, const AVRPART *p); + int terminal_line(const PROGRAMMER *pgm, const AVRPART *p, const char *line); + char *terminal_get_input(const char *prompt); + void terminal_setup_update_progress(void); + + char *avr_cc_buffer(size_t n); + + int op16_is_mnemo(int op16, AVR_mnemo mnemo); + int is_opcode32(int op16); + int op_width(int op16); + int ldi_Rd(int op16); + int ldi_K(int op16); + AVR_mnemo opcode_mnemo(int op16, int avrlevel); + int op16_is_valid(int op16, int avrlevel); + int op16_is_benign(int op16, int avrlevel); + int avr_get_archlevel(const AVRPART *p); + AVR_cycle_index avr_get_cycle_index(const AVRPART *p); + const char *mnemo_str(int op16); + int z_width(int op16, AVR_mnemo *mnenop); + int op16_target(int here, int op16); + int dist2rjmp(int dist); + + int disasm(const char *buf, int len, int addr, int leadin, int leadout); + int disasm_init(const AVRPART *p); + int disasm_init_tagfile(const AVRPART *p, const char *file); + void disasm_zap_jumpcalls(); #ifdef __cplusplus } #endif - /* * Context structure * * Global and static variables should go here; the only remaining static * variables ought to be read-only tables. Access should be via a global * pointer libavrdude_context *cx; applications using libavrdude ought to - * allocate cx = mmt_malloc(sizeof *cx) for each instantiation (and set - * initial values if needed) and deallocate with mmt_free(cx). + * allocate cx = mmt_malloc(sizeof *cx) for each instantiation (and set initial + * values if needed) and deallocate with mmt_free(cx). */ typedef struct { // Closed-circuit space for returning strings in a persistent buffer #define AVR_SAFETY_MARGIN 1024 - char *avr_s, avr_space[32768+AVR_SAFETY_MARGIN]; + char *avr_s, avr_space[32768 + AVR_SAFETY_MARGIN]; // Static variables from avr.c int avr_disableffopt; // Disables trailing 0xff flash optimisation @@ -1836,6 +1757,7 @@ typedef struct { // Static variables from bitbang.c int bb_delay_decrement; + #if defined(WIN32) int bb_has_perfcount; uint64_t bb_freq; // Should be LARGE_INTEGER but what to include? @@ -1845,7 +1767,7 @@ typedef struct { #endif // Static variables from config.c - char **cfg_hstrings[1<<12]; // Hash lists for cache_string() + char **cfg_hstrings[1 << 12]; // Hash lists for cache_string() LISTID cfg_comms; // A chain of comment lines LISTID cfg_prologue; // Comment lines at start of avrdude.conf char *cfg_lkw; // Last seen keyword @@ -1853,7 +1775,7 @@ typedef struct { LISTID cfg_strctcomms; // Passed on to config_gram.y LISTID cfg_pushedcomms; // Temporarily pushed main comments int cfg_pushed; // ... for memory sections - int cfg_init_search; // used in cfg_comp_search() + int cfg_init_search; // Used in cfg_comp_search() // Static variable from dfu.c uint16_t dfu_wIndex; // A running number for USB messages @@ -1865,11 +1787,12 @@ typedef struct { unsigned char ppi_shadow[3]; // Static variables from ser_avrdoper.c - unsigned char sad_avrdoperRxBuffer[280]; // Buffer for receiving data + unsigned char sad_avrdoperRxBuffer[280]; // Buffer for receiving data int sad_avrdoperRxLength; // Amount of valid bytes in rx buffer int sad_avrdoperRxPosition; // Amount of bytes already consumed in rx buffer // Static variables from ser_win32.c/ser_posix.c + #if defined(WIN32) unsigned char ser_serial_over_ethernet; #else @@ -1909,7 +1832,7 @@ typedef struct { // Static variables from usb_libusb.c #include "usbdevs.h" char usb_buf[USBDEV_MAX_XFER_3]; - int usb_buflen, usb_bufptr; // @@@ Check whether usb_buflen needs initialising with -1 + int usb_buflen, usb_bufptr; // @@@ Check whether usb_buflen needs initialising with -1 int usb_interface; // Variable connecting lexer.l and config_gram.y @@ -1921,7 +1844,7 @@ typedef struct { extern libavrdude_context *cx; -/* formerly confwin.h */ +// Formerly confwin.h #if defined(WIN32) @@ -1929,13 +1852,12 @@ extern libavrdude_context *cx; extern "C" { #endif -int win_set_path(char *path, int n, const char *file); + int win_set_path(char *path, int n, const char *file); #ifdef __cplusplus } #endif - -#endif /* WIN32 */ +#endif // WIN32 #ifndef TO_BE_DEPRECATED_IN_2026 @@ -1973,9 +1895,7 @@ s/\bmemtype_t\b/Memtype/g s/\bSegment_t\b/Segment/g * - */ - -typedef Configvalue Valueitem_t; + */ typedef Configvalue Valueitem_t; typedef Configitem Configitem_t; typedef Register_file Register_file_t; typedef Avrintel uPcore_t; @@ -1990,7 +1910,6 @@ typedef Leds leds_t; typedef Memtable memtable_t; typedef Memtype memtype_t; typedef Segment Segment_t; - #endif -#endif /* libavrdude_h */ +#endif diff --git a/src/linux_ppdev.h b/src/linux_ppdev.h index ced79e580..e7fbb3256 100644 --- a/src/linux_ppdev.h +++ b/src/linux_ppdev.h @@ -22,6 +22,7 @@ #define OBSOLETE__IOW _IOW #include + #ifdef HAVE_PARPORT #include #include @@ -30,7 +31,7 @@ #include #define ppi_claim(fd) \ - if (ioctl(fd, PPCLAIM)) { \ + if(ioctl(fd, PPCLAIM)) { \ pmsg_ext_error("cannot claim port %s: %s\n\n", \ port, strerror(errno)); \ close(fd); \ @@ -38,18 +39,17 @@ } #define ppi_release(fd) \ - if (ioctl(fd, PPRELEASE)) { \ + if(ioctl(fd, PPRELEASE)) { \ pmsg_ext_error("cannot release device: %s\n\n", \ strerror(errno)); \ } -#define DO_PPI_READ(fd, reg, valp) \ - (void)ioctl(fd, \ - (reg) == PPIDATA? PPRDATA: ((reg) == PPICTRL? PPRCONTROL: PPRSTATUS), \ - valp) -#define DO_PPI_WRITE(fd, reg, valp) \ - (void)ioctl(fd, \ - (reg) == PPIDATA? PPWDATA: ((reg) == PPICTRL? PPWCONTROL: PPWSTATUS), \ - valp) +#define DO_PPI_READ(fd, reg, valp) ((void) ioctl((fd), \ + (reg) == PPIDATA? PPRDATA: (reg) == PPICTRL? PPRCONTROL: PPRSTATUS, \ + (valp))) + +#define DO_PPI_WRITE(fd, reg, valp) ((void) ioctl((fd), \ + (reg) == PPIDATA? PPWDATA: (reg) == PPICTRL? PPWCONTROL: PPWSTATUS, \ + (valp))) -#endif /* linux_ppdev_h */ +#endif diff --git a/src/linuxgpio.c b/src/linuxgpio.c index bc7d2ea1c..0a894de7c 100644 --- a/src/linuxgpio.c +++ b/src/linuxgpio.c @@ -59,23 +59,21 @@ struct pdata { // Use private programmer data as if they were a global structure my #define my (*(struct pdata *)(pgm->cookie)) - /* * Sysfs GPIO user space helpers - * The following functions are acting on an "unsigned gpio" argument, which corresponds to the - * gpio numbering scheme in the kernel (starting from 0). + * The following functions are acting on an "unsigned gpio" argument, which + * corresponds to the gpio numbering scheme in the kernel (starting from 0). */ -#define GPIO_DIR_IN 0 -#define GPIO_DIR_OUT 1 +#define GPIO_DIR_IN 0 +#define GPIO_DIR_OUT 1 -static int linuxgpio_sysfs_export(unsigned int gpio) -{ +static int linuxgpio_sysfs_export(unsigned int gpio) { int fd, len, r; char buf[11]; fd = open("/sys/class/gpio/export", O_WRONLY); - if (fd < 0) { + if(fd < 0) { pmsg_ext_error("cannot open /sys/class/gpio/export: %s\n", strerror(errno)); return fd; } @@ -87,13 +85,12 @@ static int linuxgpio_sysfs_export(unsigned int gpio) return r; } -static int linuxgpio_sysfs_unexport(unsigned int gpio) -{ +static int linuxgpio_sysfs_unexport(unsigned int gpio) { int fd, len, r; char buf[11]; fd = open("/sys/class/gpio/unexport", O_WRONLY); - if (fd < 0) { + if(fd < 0) { pmsg_ext_error("cannot open /sys/class/gpio/unexport: %s\n", strerror(errno)); return fd; } @@ -105,28 +102,26 @@ static int linuxgpio_sysfs_unexport(unsigned int gpio) return r; } -static int linuxgpio_sysfs_openfd(unsigned int gpio) -{ +static int linuxgpio_sysfs_openfd(unsigned int gpio) { char filepath[60]; snprintf(filepath, sizeof(filepath), "/sys/class/gpio/gpio%u/value", gpio); return (open(filepath, O_RDWR)); } -static int linuxgpio_sysfs_dir(unsigned int gpio, unsigned int dir) -{ +static int linuxgpio_sysfs_dir(unsigned int gpio, unsigned int dir) { int fd, r; char buf[60]; snprintf(buf, sizeof(buf), "/sys/class/gpio/gpio%u/direction", gpio); fd = open(buf, O_WRONLY); - if (fd < 0) { + if(fd < 0) { pmsg_ext_error("cannot open %s: %s\n", buf, strerror(errno)); return fd; } - if (dir == GPIO_DIR_OUT) + if(dir == GPIO_DIR_OUT) r = write(fd, "out", 4); else r = write(fd, "in", 3); @@ -136,23 +131,20 @@ static int linuxgpio_sysfs_dir(unsigned int gpio, unsigned int dir) return r; } -static int linuxgpio_sysfs_dir_out(unsigned int gpio) -{ +static int linuxgpio_sysfs_dir_out(unsigned int gpio) { return linuxgpio_sysfs_dir(gpio, GPIO_DIR_OUT); } -static int linuxgpio_sysfs_dir_in(unsigned int gpio) -{ +static int linuxgpio_sysfs_dir_in(unsigned int gpio) { return linuxgpio_sysfs_dir(gpio, GPIO_DIR_IN); } -/* - * End of Sysfs GPIO user space helpers - */ +// End of Sysfs GPIO user space helpers -/* Delay between checks for successful GPIO export (100ms) */ +// Delay between checks for successful GPIO export (100ms) #define GPIO_SYSFS_OPEN_DELAY 100000 -/* Number of retries to check for successful GPIO exports */ + +// Number of retries to check for successful GPIO exports #define GPIO_SYSFS_OPEN_RETRIES 10 static int linuxgpio_sysfs_setpin(const PROGRAMMER *pgm, int pinfunc, int value) { @@ -160,17 +152,18 @@ static int linuxgpio_sysfs_setpin(const PROGRAMMER *pgm, int pinfunc, int value) return -1; unsigned pin = pgm->pinno[pinfunc]; - if (pin & PIN_INVERSE) + + if(pin & PIN_INVERSE) value = !value; pin &= PIN_MASK; - if (pin > PIN_MAX || my.sysfs_fds[pin] < 0) + if(pin > PIN_MAX || my.sysfs_fds[pin] < 0) return -1; - if (write(my.sysfs_fds[pin], value? "1": "0", 1) != 1) + if(write(my.sysfs_fds[pin], value? "1": "0", 1) != 1) return -1; - if (pgm->ispdelay > 1) + if(pgm->ispdelay > 1) bitbang_delay(pgm->ispdelay); return 0; @@ -182,6 +175,7 @@ static int linuxgpio_sysfs_getpin(const PROGRAMMER *pgm, int pinfunc) { unsigned int pin = pgm->pinno[pinfunc]; int invert = !!(pin & PIN_INVERSE); + pin &= PIN_MASK; if(pin > PIN_MAX || my.sysfs_fds[pin] < 0) @@ -191,10 +185,11 @@ static int linuxgpio_sysfs_getpin(const PROGRAMMER *pgm, int pinfunc) { return -1; char c; + if(read(my.sysfs_fds[pin], &c, 1) != 1) return -1; - return c=='0'? 0+invert: c=='1'? 1-invert: -1; + return c == '0'? 0 + invert: c == '1'? 1 - invert: -1; } static int linuxgpio_sysfs_highpulsepin(const PROGRAMMER *pgm, int pinfunc) { @@ -203,7 +198,7 @@ static int linuxgpio_sysfs_highpulsepin(const PROGRAMMER *pgm, int pinfunc) { unsigned int pin = pgm->pinno[pinfunc] & PIN_MASK; - if (pin > PIN_MAX || my.sysfs_fds[pin] < 0 ) + if(pin > PIN_MAX || my.sysfs_fds[pin] < 0) return -1; linuxgpio_sysfs_setpin(pgm, pinfunc, 1); @@ -212,11 +207,9 @@ static int linuxgpio_sysfs_highpulsepin(const PROGRAMMER *pgm, int pinfunc) { return 0; } - - static void linuxgpio_sysfs_display(const PROGRAMMER *pgm, const char *p) { - msg_info("%sPin assignment : /sys/class/gpio/gpio{n}\n",p); - pgm_display_generic_mask(pgm, p, SHOW_AVR_PINS); + msg_info("%sPin assignment : /sys/class/gpio/gpio{n}\n", p); + pgm_display_generic_mask(pgm, p, SHOW_AVR_PINS); } static void linuxgpio_enable(PROGRAMMER *pgm, const AVRPART *p) { @@ -236,90 +229,88 @@ static int linuxgpio_sysfs_open(PROGRAMMER *pgm, const char *port) { char gpio_path[60]; struct stat stat_buf; - if (bitbang_check_prerequisites(pgm) < 0) + if(bitbang_check_prerequisites(pgm) < 0) return -1; - - for (i=0; ipinno[i] & PIN_MASK) <= PIN_MAX) { - pin = pgm->pinno[i] & PIN_MASK; - if ((r=linuxgpio_sysfs_export(pin)) < 0) { - pmsg_ext_error("cannot export GPIO %d, already exported/busy?: %s", - pin, strerror(errno)); - return r; - } + for(i = 1; i < N_PINS; i++) { // The pin enumeration in libavrdude.h starts with PPI_AVR_VCC = 1 + if((pgm->pinno[i] & PIN_MASK) <= PIN_MAX) { + pin = pgm->pinno[i] & PIN_MASK; + if((r = linuxgpio_sysfs_export(pin)) < 0) { + pmsg_ext_error("cannot export GPIO %d, already exported/busy?: %s", pin, strerror(errno)); + return r; + } - /* Wait until GPIO directory appears */ - snprintf(gpio_path, sizeof(gpio_path), "/sys/class/gpio/gpio%u", pin); - unsigned int retry_count; - for (retry_count = 0; retry_count < GPIO_SYSFS_OPEN_RETRIES; retry_count++) { - int ret = stat(gpio_path, &stat_buf); - if (ret == 0) { - break; - } else if (ret < 0 && errno != ENOENT) { - linuxgpio_sysfs_unexport(pin); - return ret; - } - - usleep(GPIO_SYSFS_OPEN_DELAY); - } + // Wait until GPIO directory appears + snprintf(gpio_path, sizeof(gpio_path), "/sys/class/gpio/gpio%u", pin); + unsigned int retry_count; + + for(retry_count = 0; retry_count < GPIO_SYSFS_OPEN_RETRIES; retry_count++) { + int ret = stat(gpio_path, &stat_buf); - /* Write direction, looping in case of EACCES errors due to delayed - * udev permission rule application after export */ - for (retry_count = 0; retry_count < GPIO_SYSFS_OPEN_RETRIES; retry_count++) { - usleep(GPIO_SYSFS_OPEN_DELAY); - if (i == PIN_AVR_SDI) - r=linuxgpio_sysfs_dir_in(pin); - else - r=linuxgpio_sysfs_dir_out(pin); - - if (r >= 0) - break; - - if (errno != EACCES) { - linuxgpio_sysfs_unexport(pin); - return r; - } + if(ret == 0) { + break; + } else if(ret < 0 && errno != ENOENT) { + linuxgpio_sysfs_unexport(pin); + return ret; } - if (retry_count) - pmsg_notice2("needed %d retr%s for linuxgpio_sysfs_dir_%s(%s)\n", - retry_count, retry_count > 1? "ies": "y", - i == PIN_AVR_SDI? "in": "out", avr_pin_name(pin)); + usleep(GPIO_SYSFS_OPEN_DELAY); + } - if (r < 0) { - linuxgpio_sysfs_unexport(pin); - return r; + /* Write direction, looping in case of EACCES errors due to delayed + * udev permission rule application after export */ + for(retry_count = 0; retry_count < GPIO_SYSFS_OPEN_RETRIES; retry_count++) { + usleep(GPIO_SYSFS_OPEN_DELAY); + if(i == PIN_AVR_SDI) + r = linuxgpio_sysfs_dir_in(pin); + else + r = linuxgpio_sysfs_dir_out(pin); + + if(r >= 0) + break; + + if(errno != EACCES) { + linuxgpio_sysfs_unexport(pin); + return r; } + } + + if(retry_count) + pmsg_notice2("needed %d retr%s for linuxgpio_sysfs_dir_%s(%s)\n", + retry_count, retry_count > 1? "ies": "y", i == PIN_AVR_SDI? "in": "out", avr_pin_name(pin)); - if ((my.sysfs_fds[pin]=linuxgpio_sysfs_openfd(pin)) < 0) - return my.sysfs_fds[pin]; + if(r < 0) { + linuxgpio_sysfs_unexport(pin); + return r; + } + + if((my.sysfs_fds[pin] = linuxgpio_sysfs_openfd(pin)) < 0) + return my.sysfs_fds[pin]; } } - return(0); + return (0); } -static void linuxgpio_sysfs_close(PROGRAMMER *pgm) -{ +static void linuxgpio_sysfs_close(PROGRAMMER *pgm) { int i, reset_pin; reset_pin = pgm->pinno[PIN_AVR_RESET] & PIN_MASK; - //first configure all pins as input, except RESET - //this should avoid possible conflicts when AVR firmware starts - for (i=0; i= 0 && i != reset_pin) { - close(my.sysfs_fds[i]); - my.sysfs_fds[i] = -1; - linuxgpio_sysfs_dir_in(i); - linuxgpio_sysfs_unexport(i); + // First configure all pins as input, except RESET + // This should avoid possible conflicts when AVR firmware starts + for(i = 0; i < N_GPIO; i++) { + if(my.sysfs_fds[i] >= 0 && i != reset_pin) { + close(my.sysfs_fds[i]); + my.sysfs_fds[i] = -1; + linuxgpio_sysfs_dir_in(i); + linuxgpio_sysfs_unexport(i); } } - //configure RESET as input, if there's external pull up it will go high + // Configure RESET as input, if there's external pull up it will go high if(reset_pin <= PIN_MAX && my.sysfs_fds[reset_pin] >= 0) { close(my.sysfs_fds[reset_pin]); my.sysfs_fds[reset_pin] = -1; @@ -337,31 +328,25 @@ void linuxgpio_teardown(PROGRAMMER *pgm) { pgm->cookie = NULL; } - -// -// libgpiod backend for the linuxgpio programmer. -// +// libgpiod backend for the linuxgpio programmer #ifdef HAVE_LIBGPIOD #if !HAVE_LIBGPIOD_V1_6 && !HAVE_LIBGPIOD_V2 - int gpiod_line_set_direction_input(struct gpiod_line **gpio_line) { struct gpiod_chip *chip = gpiod_line_get_chip(*gpio_line); unsigned int gpio_num = gpiod_line_offset(*gpio_line); - // release to pin first... + // Release pin first... gpiod_line_release(*gpio_line); - // so that we can re-acquire it as input + // ... so that we can re-acquire it as input *gpio_line = gpiod_chip_get_line(chip, gpio_num); return gpiod_line_request_input(*gpio_line, "avrdude"); } - #endif #if HAVE_LIBGPIOD_V2 - struct gpiod_line { struct gpiod_chip *chip; struct gpiod_line_request *line_request; @@ -372,14 +357,14 @@ struct gpiod_line *gpiod_line_get(const char *port, int gpio_num) { struct gpiod_line *rv; char abs_port[32]; - if (snprintf(abs_port, sizeof(abs_port), "/dev/%s", port) >= (int)sizeof(abs_port)) + if(snprintf(abs_port, sizeof(abs_port), "/dev/%s", port) >= (int) sizeof(abs_port)) return NULL; rv = mmt_malloc(sizeof(struct gpiod_line)); rv->gpio_num = gpio_num; rv->chip = gpiod_chip_open(abs_port); - if (!rv->chip) { + if(!rv->chip) { mmt_free(rv); return NULL; } @@ -397,21 +382,21 @@ int gpiod_line_request_input(struct gpiod_line *gpio_line, const char *consumer) line_config = gpiod_line_config_new(); req_cfg = gpiod_request_config_new(); - if (!line_settings || !line_config || !req_cfg) + if(!line_settings || !line_config || !req_cfg) goto err_out; retval = gpiod_line_settings_set_direction(line_settings, GPIOD_LINE_DIRECTION_INPUT); - if (retval != 0) + if(retval != 0) goto err_out; retval = gpiod_line_config_add_line_settings(line_config, &gpio_line->gpio_num, 1, line_settings); - if (retval != 0) + if(retval != 0) goto err_out; gpiod_request_config_set_consumer(req_cfg, consumer); gpio_line->line_request = gpiod_chip_request_lines(gpio_line->chip, req_cfg, line_config); - if (!gpio_line->line_request) + if(!gpio_line->line_request) goto err_out; retval = 0; @@ -433,25 +418,26 @@ int gpiod_line_request_output(struct gpiod_line *gpio_line, const char *consumer line_config = gpiod_line_config_new(); req_cfg = gpiod_request_config_new(); - if (!line_settings || !line_config || !req_cfg) + if(!line_settings || !line_config || !req_cfg) goto err_out; retval = gpiod_line_settings_set_direction(line_settings, GPIOD_LINE_DIRECTION_OUTPUT); - if (retval != 0) + if(retval != 0) goto err_out; - retval = gpiod_line_settings_set_output_value(line_settings, value ? GPIOD_LINE_VALUE_ACTIVE : GPIOD_LINE_VALUE_INACTIVE); - if (retval != 0) + retval = gpiod_line_settings_set_output_value(line_settings, + value? GPIOD_LINE_VALUE_ACTIVE: GPIOD_LINE_VALUE_INACTIVE); + if(retval != 0) goto err_out; retval = gpiod_line_config_add_line_settings(line_config, &gpio_line->gpio_num, 1, line_settings); - if (retval != 0) + if(retval != 0) goto err_out; gpiod_request_config_set_consumer(req_cfg, consumer); gpio_line->line_request = gpiod_chip_request_lines(gpio_line->chip, req_cfg, line_config); - if (!gpio_line->line_request) + if(!gpio_line->line_request) goto err_out; retval = 0; @@ -471,15 +457,15 @@ int gpiod_line_set_direction_input(struct gpiod_line *gpio_line) { line_settings = gpiod_line_settings_new(); line_config = gpiod_line_config_new(); - if (!line_settings || !line_config) + if(!line_settings || !line_config) goto err_out; retval = gpiod_line_settings_set_direction(line_settings, GPIOD_LINE_DIRECTION_INPUT); - if (retval != 0) + if(retval != 0) goto err_out; retval = gpiod_line_config_add_line_settings(line_config, &gpio_line->gpio_num, 1, line_settings); - if (retval != 0) + if(retval != 0) goto err_out; retval = gpiod_line_request_reconfigure_lines(gpio_line->line_request, line_config); @@ -503,10 +489,10 @@ static inline int gpiod_line_set_value(struct gpiod_line *gpio_line, int value) static inline int gpiod_line_get_value(struct gpiod_line *gpio_line) { return gpiod_line_request_get_value(gpio_line->line_request, gpio_line->gpio_num); } - #endif static inline unsigned int linuxgpio_get_gpio_num(struct gpiod_line *gpio_line) { + #if HAVE_LIBGPIOD_V2 return gpio_line->gpio_num; #else @@ -514,16 +500,17 @@ static inline unsigned int linuxgpio_get_gpio_num(struct gpiod_line *gpio_line) #endif } -struct gpiod_line * linuxgpio_libgpiod_lines[N_PINS]; +struct gpiod_line *linuxgpio_libgpiod_lines[N_PINS]; // Try to tell if libgpiod is going to work. // Returns True (non-zero) if it looks like libgpiod will work, False // (zero) if libgpiod will not work. static int libgpiod_is_working(void) { - char const * filename = "/dev/gpiochip0"; - struct gpiod_chip * gpiod_chip_ptr; + char const *filename = "/dev/gpiochip0"; + struct gpiod_chip *gpiod_chip_ptr; + gpiod_chip_ptr = gpiod_chip_open(filename); - if (gpiod_chip_ptr == NULL) { + if(gpiod_chip_ptr == NULL) { msg_info("failed to open gpiod chip %s: %s\n", filename, strerror(errno)); return 0; } @@ -531,86 +518,86 @@ static int libgpiod_is_working(void) { return 1; } - static void linuxgpio_libgpiod_display(const PROGRAMMER *pgm, const char *p) { msg_info("%sPin assignment : libgpiod\n", p); pgm_display_generic_mask(pgm, p, SHOW_AVR_PINS); } - static int linuxgpio_libgpiod_open(PROGRAMMER *pgm, const char *port) { int i; - if (bitbang_check_prerequisites(pgm) < 0) { + if(bitbang_check_prerequisites(pgm) < 0) { return -1; } - for (i = 0; i < N_PINS; ++i) { + for(i = 0; i < N_PINS; ++i) { linuxgpio_libgpiod_lines[i] = NULL; } // Avrdude assumes that if a pin number is invalid it means not used/available - for (i = 1; i < N_PINS; i++) { // The pin enumeration in libavrdude.h starts with PPI_AVR_VCC = 1 + for(i = 1; i < N_PINS; i++) { // The pin enumeration in libavrdude.h starts with PPI_AVR_VCC = 1 int r; int gpio_num; gpio_num = pgm->pinno[i] & PIN_MASK; - if (gpio_num > PIN_MAX) { + if(gpio_num > PIN_MAX) { continue; } linuxgpio_libgpiod_lines[i] = gpiod_line_get(port, gpio_num); - if (linuxgpio_libgpiod_lines[i] == NULL) { + if(linuxgpio_libgpiod_lines[i] == NULL) { msg_error("failed to open %s line %d: %s\n", port, gpio_num, strerror(errno)); return -1; } - // Request the pin, select direction. - if (i == PIN_AVR_SDI) { - r = gpiod_line_request_input(linuxgpio_libgpiod_lines[i], "avrdude"); + if(i == PIN_AVR_SDI) { + r = gpiod_line_request_input(linuxgpio_libgpiod_lines[i], "avrdude"); } else { - r = gpiod_line_request_output(linuxgpio_libgpiod_lines[i], "avrdude", 0); + r = gpiod_line_request_output(linuxgpio_libgpiod_lines[i], "avrdude", 0); } - if (r != 0) { + if(r != 0) { msg_error("failed to request %s line %d: %s\n", port, gpio_num, strerror(errno)); return -1; } } - return(0); + return (0); } - static void linuxgpio_libgpiod_close(PROGRAMMER *pgm) { int i; // First configure all pins as input, except RESET. // This should avoid possible conflicts when AVR firmware starts. - for (i = 0; i < N_PINS; ++i) { - if (linuxgpio_libgpiod_lines[i] != NULL && i != PIN_AVR_RESET) { + for(i = 0; i < N_PINS; ++i) { + if(linuxgpio_libgpiod_lines[i] != NULL && i != PIN_AVR_RESET) { + #if HAVE_LIBGPIOD_V1_6 || HAVE_LIBGPIOD_V2 int r = gpiod_line_set_direction_input(linuxgpio_libgpiod_lines[i]); #else int r = gpiod_line_set_direction_input(&linuxgpio_libgpiod_lines[i]); #endif - if (r != 0) { + + if(r != 0) msg_error("failed to set pin %u to input: %s\n", linuxgpio_get_gpio_num(linuxgpio_libgpiod_lines[i]), strerror(errno)); - } + gpiod_line_release(linuxgpio_libgpiod_lines[i]); linuxgpio_libgpiod_lines[i] = NULL; } } // Configure RESET as input. - if (linuxgpio_libgpiod_lines[PIN_AVR_RESET] != NULL) { + if(linuxgpio_libgpiod_lines[PIN_AVR_RESET] != NULL) { + #if HAVE_LIBGPIOD_V1_6 || HAVE_LIBGPIOD_V2 int r = gpiod_line_set_direction_input(linuxgpio_libgpiod_lines[PIN_AVR_RESET]); #else int r = gpiod_line_set_direction_input(&linuxgpio_libgpiod_lines[PIN_AVR_RESET]); #endif - if (r != 0) { + + if(r != 0) { msg_error("failed to set pin %u to input: %s\n", linuxgpio_get_gpio_num(linuxgpio_libgpiod_lines[PIN_AVR_RESET]), strerror(errno)); } @@ -619,30 +606,31 @@ static void linuxgpio_libgpiod_close(PROGRAMMER *pgm) { } } - static int linuxgpio_libgpiod_setpin(const PROGRAMMER *pgm, int pinfunc, int value) { - if (pinfunc < 0 || pinfunc >= N_PINS) { + if(pinfunc < 0 || pinfunc >= N_PINS) { return -1; } unsigned pin = pgm->pinno[pinfunc]; - if (pin & PIN_INVERSE) { + + if(pin & PIN_INVERSE) { value = !value; } pin &= PIN_MASK; - if (pin > PIN_MAX || linuxgpio_libgpiod_lines[pinfunc] == NULL) { + if(pin > PIN_MAX || linuxgpio_libgpiod_lines[pinfunc] == NULL) { return -1; } int r = gpiod_line_set_value(linuxgpio_libgpiod_lines[pinfunc], value); - if (r != 0) { + + if(r != 0) { msg_error("failed to set value of %s (%u) to %d: %s\n", avr_pin_name(pinfunc), linuxgpio_get_gpio_num(linuxgpio_libgpiod_lines[pinfunc]), value, strerror(errno)); return -1; } - if (pgm->ispdelay > 1) { + if(pgm->ispdelay > 1) { bitbang_delay(pgm->ispdelay); } @@ -650,20 +638,22 @@ static int linuxgpio_libgpiod_setpin(const PROGRAMMER *pgm, int pinfunc, int val } static int linuxgpio_libgpiod_getpin(const PROGRAMMER *pgm, int pinfunc) { - if (pinfunc < 0 || pinfunc >= N_PINS) { + if(pinfunc < 0 || pinfunc >= N_PINS) { return -1; } unsigned int pin = pgm->pinno[pinfunc]; int invert = !!(pin & PIN_INVERSE); + pin &= PIN_MASK; - if (pin > PIN_MAX || linuxgpio_libgpiod_lines[pinfunc] == NULL) { + if(pin > PIN_MAX || linuxgpio_libgpiod_lines[pinfunc] == NULL) { return -1; } int r = gpiod_line_get_value(linuxgpio_libgpiod_lines[pinfunc]); - if (r == -1) { + + if(r == -1) { msg_error("failed to read %u: %s\n", linuxgpio_get_gpio_num(linuxgpio_libgpiod_lines[pinfunc]), strerror(errno)); return -1; } @@ -671,7 +661,6 @@ static int linuxgpio_libgpiod_getpin(const PROGRAMMER *pgm, int pinfunc) { return r ^ invert; } - static int linuxgpio_libgpiod_highpulsepin(const PROGRAMMER *pgm, int pinfunc) { if(pinfunc < 0 || pinfunc >= N_PINS) { return -1; @@ -679,67 +668,65 @@ static int linuxgpio_libgpiod_highpulsepin(const PROGRAMMER *pgm, int pinfunc) { unsigned int pin = pgm->pinno[pinfunc] & PIN_MASK; - if (pin > PIN_MAX || linuxgpio_libgpiod_lines[pinfunc] == NULL ) { + if(pin > PIN_MAX || linuxgpio_libgpiod_lines[pinfunc] == NULL) { return -1; } int r = gpiod_line_set_value(linuxgpio_libgpiod_lines[pinfunc], 1); - if (r != 0) { + + if(r != 0) { msg_error("failed to set value\n"); return -1; } r = gpiod_line_set_value(linuxgpio_libgpiod_lines[pinfunc], 0); - if (r != 0) { + if(r != 0) { msg_error("failed to set value\n"); return -1; } return 0; } - - -#endif // HAVE_LIBGPIOD - +#endif // HAVE_LIBGPIOD void linuxgpio_initpgm(PROGRAMMER *pgm) { strcpy(pgm->type, "linuxgpio"); - pgm_fill_old_pins(pgm); // TODO to be removed if old pin data no longer needed - - pgm->rdy_led = bitbang_rdy_led; - pgm->err_led = bitbang_err_led; - pgm->pgm_led = bitbang_pgm_led; - pgm->vfy_led = bitbang_vfy_led; - pgm->initialize = bitbang_initialize; - pgm->display = linuxgpio_sysfs_display; - pgm->enable = linuxgpio_enable; - pgm->disable = linuxgpio_disable; - pgm->powerup = linuxgpio_powerup; - pgm->powerdown = linuxgpio_powerdown; + pgm_fill_old_pins(pgm); // TODO to be removed if old pin data no longer needed + + pgm->rdy_led = bitbang_rdy_led; + pgm->err_led = bitbang_err_led; + pgm->pgm_led = bitbang_pgm_led; + pgm->vfy_led = bitbang_vfy_led; + pgm->initialize = bitbang_initialize; + pgm->display = linuxgpio_sysfs_display; + pgm->enable = linuxgpio_enable; + pgm->disable = linuxgpio_disable; + pgm->powerup = linuxgpio_powerup; + pgm->powerdown = linuxgpio_powerdown; pgm->program_enable = bitbang_program_enable; - pgm->chip_erase = bitbang_chip_erase; - pgm->cmd = bitbang_cmd; - pgm->cmd_tpi = bitbang_cmd_tpi; - pgm->open = linuxgpio_sysfs_open; - pgm->close = linuxgpio_sysfs_close; - pgm->setpin = linuxgpio_sysfs_setpin; - pgm->getpin = linuxgpio_sysfs_getpin; - pgm->highpulsepin = linuxgpio_sysfs_highpulsepin; - pgm->read_byte = avr_read_byte_default; - pgm->write_byte = avr_write_byte_default; - pgm->setup = linuxgpio_setup; - pgm->teardown = linuxgpio_teardown; + pgm->chip_erase = bitbang_chip_erase; + pgm->cmd = bitbang_cmd; + pgm->cmd_tpi = bitbang_cmd_tpi; + pgm->open = linuxgpio_sysfs_open; + pgm->close = linuxgpio_sysfs_close; + pgm->setpin = linuxgpio_sysfs_setpin; + pgm->getpin = linuxgpio_sysfs_getpin; + pgm->highpulsepin = linuxgpio_sysfs_highpulsepin; + pgm->read_byte = avr_read_byte_default; + pgm->write_byte = avr_write_byte_default; + pgm->setup = linuxgpio_setup; + pgm->teardown = linuxgpio_teardown; #ifdef HAVE_LIBGPIOD - if (libgpiod_is_working()) { + if(libgpiod_is_working()) { msg_notice("using libgpiod for linuxgpio\n"); - pgm->display = linuxgpio_libgpiod_display; - pgm->open = linuxgpio_libgpiod_open; - pgm->close = linuxgpio_libgpiod_close; - pgm->setpin = linuxgpio_libgpiod_setpin; - pgm->getpin = linuxgpio_libgpiod_getpin; - pgm->highpulsepin = linuxgpio_libgpiod_highpulsepin; + pgm->display = linuxgpio_libgpiod_display; + pgm->open = linuxgpio_libgpiod_open; + pgm->close = linuxgpio_libgpiod_close; + pgm->setpin = linuxgpio_libgpiod_setpin; + pgm->getpin = linuxgpio_libgpiod_getpin; + pgm->highpulsepin = linuxgpio_libgpiod_highpulsepin; } else { msg_notice("falling back to sysfs for linuxgpio\n"); } @@ -748,12 +735,11 @@ void linuxgpio_initpgm(PROGRAMMER *pgm) { const char linuxgpio_desc[] = "GPIO bitbanging using the Linux libgpiod or sysfs interface"; -#else /* !HAVE_LINUXGPIO */ +#else // ! HAVE_LINUXGPIO void linuxgpio_initpgm(PROGRAMMER *pgm) { pmsg_error("Linux libgpiod/sysfs GPIO support not available in this configuration\n"); } const char linuxgpio_desc[] = "GPIO bitbanging using the Linux libgpiod or sysfs interface (not available)"; - -#endif /* HAVE_LINUXGPIO */ +#endif // HAVE_LINUXGPIO diff --git a/src/linuxgpio.h b/src/linuxgpio.h index 5c07d7c4e..ed7739002 100644 --- a/src/linuxgpio.h +++ b/src/linuxgpio.h @@ -17,8 +17,6 @@ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ -/* $Id: par.h 722 2007-01-24 22:43:46Z joerg_wunsch $ */ - #ifndef linuxgpio_h #define linuxgpio_h @@ -26,11 +24,10 @@ extern "C" { #endif -extern const char linuxgpio_desc[]; -void linuxgpio_initpgm(PROGRAMMER *pgm); + extern const char linuxgpio_desc[]; + void linuxgpio_initpgm(PROGRAMMER *pgm); #ifdef __cplusplus } #endif - #endif diff --git a/src/linuxspi.c b/src/linuxspi.c index 678aa222e..485736793 100644 --- a/src/linuxspi.c +++ b/src/linuxspi.c @@ -23,7 +23,6 @@ * Review code, rebase to latest trunk, add linux/gpio.h support, Ralf Ramsauer 2018-09-07 */ - #include #include "avrdude.h" @@ -33,7 +32,7 @@ #if HAVE_LINUXSPI -/** +/* * Linux Kernel SPI Drivers * * Copyright (C) 2006 SWAPP @@ -71,369 +70,372 @@ struct pdata { // Use private programmer data as if they were a global structure my #define my (*(struct pdata *)(pgm->cookie)) -/** +/* * @brief Sends/receives a message in full duplex mode * @return -1 on failure, otherwise number of bytes sent/received */ static int linuxspi_spi_duplex(const PROGRAMMER *pgm, const unsigned char *tx, unsigned char *rx, int len) { - struct spi_ioc_transfer tr; - int ret; - - tr = (struct spi_ioc_transfer) { - .tx_buf = (unsigned long)tx, - .rx_buf = (unsigned long)rx, - .len = len, - .delay_usecs = 1, - .speed_hz = 1.0 / pgm->bitclock, - .bits_per_word = 8, - }; - - errno = 0; - - ret = ioctl(my.fd_spidev, SPI_IOC_MESSAGE(1), &tr); - if (ret != len) { - int ioctl_errno = errno; - msg_error("\n"); - pmsg_error("unable to send SPI message"); - if (ioctl_errno) - msg_error("%s", strerror(ioctl_errno)); - msg_error("\n"); - } + struct spi_ioc_transfer tr; + int ret; + + tr = (struct spi_ioc_transfer) { + .tx_buf = (unsigned long) tx, + .rx_buf = (unsigned long) rx, + .len = len, + .delay_usecs = 1, + .speed_hz = 1.0/pgm->bitclock, + .bits_per_word = 8, + }; + + errno = 0; + + ret = ioctl(my.fd_spidev, SPI_IOC_MESSAGE(1), &tr); + if(ret != len) { + int ioctl_errno = errno; + + msg_error("\n"); + pmsg_error("unable to send SPI message"); + if(ioctl_errno) + msg_error("%s", strerror(ioctl_errno)); + msg_error("\n"); + } - return ret == -1? -1: 0; + return ret == -1? -1: 0; } static void linuxspi_setup(PROGRAMMER *pgm) { pgm->cookie = mmt_malloc(sizeof(struct pdata)); } -static void linuxspi_teardown(PROGRAMMER* pgm) { +static void linuxspi_teardown(PROGRAMMER *pgm) { mmt_free(pgm->cookie); pgm->cookie = NULL; } static int linuxspi_reset_mcu(const PROGRAMMER *pgm, bool active) { - struct gpiohandle_data data; - int ret; + struct gpiohandle_data data; + int ret; + + /* + * Set the reset state and keep it. The pin will be released and set back to + * its initial value, once the my.fd_gpiochip is closed. + */ + data.values[0] = active ^ !(pgm->pinno[PIN_AVR_RESET] & PIN_INVERSE); + ret = ioctl(my.fd_linehandle, GPIOHANDLE_SET_LINE_VALUES_IOCTL, &data); - /* - * Set the reset state and keep it. The pin will be released and set back to - * its initial value, once the my.fd_gpiochip is closed. - */ - data.values[0] = active ^ !(pgm->pinno[PIN_AVR_RESET] & PIN_INVERSE); - ret = ioctl(my.fd_linehandle, GPIOHANDLE_SET_LINE_VALUES_IOCTL, &data); #ifdef GPIO_V2_LINE_SET_VALUES_IOCTL - if (ret == -1) { - struct gpio_v2_line_values val; + if(ret == -1) { + struct gpio_v2_line_values val; - val.mask = 1; - val.bits = active ^ !(pgm->pinno[PIN_AVR_RESET] & PIN_INVERSE); + val.mask = 1; + val.bits = active ^ !(pgm->pinno[PIN_AVR_RESET] & PIN_INVERSE); - ret = ioctl(my.fd_linehandle, GPIO_V2_LINE_SET_VALUES_IOCTL, &val); - } + ret = ioctl(my.fd_linehandle, GPIO_V2_LINE_SET_VALUES_IOCTL, &val); + } #endif - if (ret == -1) { - ret = -errno; - pmsg_ext_error("unable to set GPIO line %d value: %s\n", pgm->pinno[PIN_AVR_RESET] & PIN_MASK, strerror(errno)); - return ret; - } - return 0; + if(ret == -1) { + ret = -errno; + pmsg_ext_error("unable to set GPIO line %d value: %s\n", pgm->pinno[PIN_AVR_RESET] & PIN_MASK, strerror(errno)); + return ret; + } + + return 0; } static int linuxspi_open(PROGRAMMER *pgm, const char *pt) { - const char *port_error = - "unknown port specification, " - "please use the format /dev/spidev:/dev/gpiochip[:resetno]\n"; - char port_default[] = "/dev/spidev0.0:/dev/gpiochip0"; - char *spidev, *gpiochip, *reset_pin; - char *port = mmt_strdup(pt); - struct gpiohandle_request req; - int ret; - - if (str_eq(port, "unknown")) { - port = port_default; - } + const char *port_error = "unknown port specification, " + "please use the format /dev/spidev:/dev/gpiochip[:resetno]\n"; + char port_default[] = "/dev/spidev0.0:/dev/gpiochip0"; + char *spidev, *gpiochip, *reset_pin; + char *port = mmt_strdup(pt); + struct gpiohandle_request req; + int ret; + + if(str_eq(port, "unknown")) { + port = port_default; + } - spidev = strtok(port, ":"); - if (!spidev) { - pmsg_error("%s", port_error); - return -1; - } + spidev = strtok(port, ":"); + if(!spidev) { + pmsg_error("%s", port_error); + return -1; + } - gpiochip = strtok(NULL, ":"); - if (!gpiochip) { - pmsg_error("%s", port_error); - return -1; - } + gpiochip = strtok(NULL, ":"); + if(!gpiochip) { + pmsg_error("%s", port_error); + return -1; + } - /* optional: override reset pin in configuration */ - reset_pin = strtok(NULL, ":"); - if (reset_pin) { - const char *errstr; - pgm->pinno[PIN_AVR_RESET] = str_int(reset_pin, STR_UINT32, &errstr); - if(errstr) { - pmsg_error("pin number %s: %s", reset_pin, errstr); - return -1; - } - } + // Optional: override reset pin in configuration + reset_pin = strtok(NULL, ":"); + if(reset_pin) { + const char *errstr; - pgm->port = port; - my.fd_spidev = open(pgm->port, O_RDWR); - if (my.fd_spidev < 0) { - pmsg_ext_error("unable to open the spidev device %s: %s\n", pgm->port, strerror(errno)); - return -1; + pgm->pinno[PIN_AVR_RESET] = str_int(reset_pin, STR_UINT32, &errstr); + if(errstr) { + pmsg_error("pin number %s: %s", reset_pin, errstr); + return -1; } + } - uint32_t mode = SPI_MODE_0; - if (!my.disable_no_cs) - mode |= SPI_NO_CS; - - ret = ioctl(my.fd_spidev, SPI_IOC_WR_MODE32, &mode); - if (ret == -1) { - int ioctl_errno = errno; - pmsg_ext_error("unable to set SPI mode %02X on %s: %s\n", mode, spidev, strerror(errno)); - if(ioctl_errno == EINVAL && !my.disable_no_cs) - pmsg_error("try -x disable_no_cs\n"); - goto close_spidev; - } - my.fd_gpiochip = open(gpiochip, 0); - if (my.fd_gpiochip < 0) { - pmsg_ext_error("unable to open the gpiochip %s: %s\n", gpiochip, strerror(errno)); - ret = -1; - goto close_spidev; - } + pgm->port = port; + my.fd_spidev = open(pgm->port, O_RDWR); + if(my.fd_spidev < 0) { + pmsg_ext_error("unable to open the spidev device %s: %s\n", pgm->port, strerror(errno)); + return -1; + } + + uint32_t mode = SPI_MODE_0; + + if(!my.disable_no_cs) + mode |= SPI_NO_CS; - strcpy(req.consumer_label, progname); - req.lines = 1; - req.lineoffsets[0] = pgm->pinno[PIN_AVR_RESET] & PIN_MASK; - req.default_values[0] = !!(pgm->pinno[PIN_AVR_RESET] & PIN_INVERSE); - req.flags = GPIOHANDLE_REQUEST_OUTPUT; + ret = ioctl(my.fd_spidev, SPI_IOC_WR_MODE32, &mode); + if(ret == -1) { + int ioctl_errno = errno; + + pmsg_ext_error("unable to set SPI mode %02X on %s: %s\n", mode, spidev, strerror(errno)); + if(ioctl_errno == EINVAL && !my.disable_no_cs) + pmsg_error("try -x disable_no_cs\n"); + goto close_spidev; + } + my.fd_gpiochip = open(gpiochip, 0); + if(my.fd_gpiochip < 0) { + pmsg_ext_error("unable to open the gpiochip %s: %s\n", gpiochip, strerror(errno)); + ret = -1; + goto close_spidev; + } + + strcpy(req.consumer_label, progname); + req.lines = 1; + req.lineoffsets[0] = pgm->pinno[PIN_AVR_RESET] & PIN_MASK; + req.default_values[0] = !!(pgm->pinno[PIN_AVR_RESET] & PIN_INVERSE); + req.flags = GPIOHANDLE_REQUEST_OUTPUT; + + ret = ioctl(my.fd_gpiochip, GPIO_GET_LINEHANDLE_IOCTL, &req); + if(ret != -1) + my.fd_linehandle = req.fd; - ret = ioctl(my.fd_gpiochip, GPIO_GET_LINEHANDLE_IOCTL, &req); - if (ret != -1) - my.fd_linehandle = req.fd; #ifdef GPIO_V2_GET_LINE_IOCTL - if (ret == -1) { - struct gpio_v2_line_request reqv2; - - memset(&reqv2, 0, sizeof(reqv2)); - reqv2.offsets[0] = pgm->pinno[PIN_AVR_RESET] & PIN_MASK; - strncpy(reqv2.consumer, progname, sizeof(reqv2.consumer) - 1); - reqv2.config.flags = GPIO_V2_LINE_FLAG_OUTPUT; - reqv2.config.num_attrs = 1; - reqv2.config.attrs[0].attr.id = GPIO_V2_LINE_ATTR_ID_OUTPUT_VALUES; - reqv2.config.attrs[0].attr.values = !!(pgm->pinno[PIN_AVR_RESET] & PIN_INVERSE); - reqv2.config.attrs[0].mask = 1; - reqv2.num_lines = 1; - - ret = ioctl(my.fd_gpiochip, GPIO_V2_GET_LINE_IOCTL, &reqv2); - if (ret != -1) - my.fd_linehandle = reqv2.fd; - } + if(ret == -1) { + struct gpio_v2_line_request reqv2; + + memset(&reqv2, 0, sizeof(reqv2)); + reqv2.offsets[0] = pgm->pinno[PIN_AVR_RESET] & PIN_MASK; + strncpy(reqv2.consumer, progname, sizeof(reqv2.consumer) - 1); + reqv2.config.flags = GPIO_V2_LINE_FLAG_OUTPUT; + reqv2.config.num_attrs = 1; + reqv2.config.attrs[0].attr.id = GPIO_V2_LINE_ATTR_ID_OUTPUT_VALUES; + reqv2.config.attrs[0].attr.values = !!(pgm->pinno[PIN_AVR_RESET] & PIN_INVERSE); + reqv2.config.attrs[0].mask = 1; + reqv2.num_lines = 1; + + ret = ioctl(my.fd_gpiochip, GPIO_V2_GET_LINE_IOCTL, &reqv2); + if(ret != -1) + my.fd_linehandle = reqv2.fd; + } #endif - if (ret == -1) { - ret = -errno; - pmsg_ext_error("unable to get GPIO line %d. %s\n", pgm->pinno[PIN_AVR_RESET] & PIN_MASK, strerror(errno)); - goto close_gpiochip; - } - ret = linuxspi_reset_mcu(pgm, true); - if (ret) - goto close_out; + if(ret == -1) { + ret = -errno; + pmsg_ext_error("unable to get GPIO line %d. %s\n", pgm->pinno[PIN_AVR_RESET] & PIN_MASK, strerror(errno)); + goto close_gpiochip; + } - if (pgm->baudrate != 0) { - pmsg_warning("obsolete use of -b option for bit clock; use -B \n"); - pgm->bitclock = 1.0 / pgm->baudrate; - } - if (pgm->bitclock == 0) { - pmsg_notice("defaulting bit clock to 200 kHz\n"); - pgm->bitclock = 5E-6; // 200 kHz - 5 µs - } + ret = linuxspi_reset_mcu(pgm, true); + if(ret) + goto close_out; - return 0; + if(pgm->baudrate != 0) { + pmsg_warning("obsolete use of -b option for bit clock; use -B \n"); + pgm->bitclock = 1.0/pgm->baudrate; + } + if(pgm->bitclock == 0) { + pmsg_notice("defaulting bit clock to 200 kHz\n"); + pgm->bitclock = 5E-6; // 200 kHz - 5 µs + } + + return 0; close_out: - close(my.fd_linehandle); + close(my.fd_linehandle); close_gpiochip: - close(my.fd_gpiochip); + close(my.fd_gpiochip); close_spidev: - close(my.fd_spidev); - return ret; + close(my.fd_spidev); + return ret; } static void linuxspi_close(PROGRAMMER *pgm) { - switch (pgm->exit_reset) { - case EXIT_RESET_ENABLED: - linuxspi_reset_mcu(pgm, true); - break; + switch(pgm->exit_reset) { + case EXIT_RESET_ENABLED: + linuxspi_reset_mcu(pgm, true); + break; - case EXIT_RESET_DISABLED: - linuxspi_reset_mcu(pgm, false); - break; + case EXIT_RESET_DISABLED: + linuxspi_reset_mcu(pgm, false); + break; - default: - break; - } + default: + break; + } - close(my.fd_linehandle); - close(my.fd_spidev); - close(my.fd_gpiochip); + close(my.fd_linehandle); + close(my.fd_spidev); + close(my.fd_gpiochip); } -static void linuxspi_disable(const PROGRAMMER* pgm) { +static void linuxspi_disable(const PROGRAMMER *pgm) { } static void linuxspi_enable(PROGRAMMER *pgm, const AVRPART *p) { } -static void linuxspi_display(const PROGRAMMER* pgm, const char* p) { +static void linuxspi_display(const PROGRAMMER *pgm, const char *p) { } static int linuxspi_initialize(const PROGRAMMER *pgm, const AVRPART *p) { - int tries, ret; + int tries, ret; - if (p->prog_modes & PM_TPI) { - /* We do not support TPI. This is a dedicated SPI thing */ - pmsg_error("programmer " LINUXSPI " does not support TPI\n"); - return -1; - } - - //enable programming on the part - tries = 0; - do - { - ret = pgm->program_enable(pgm, p); - if (ret == 0 || ret == -1) - break; - } while(tries++ < 65); - - if (ret) - pmsg_error("AVR device not responding\n"); - - return ret; + if(is_tpi(p)) { + // We do not support TPI; this is a dedicated SPI thing + pmsg_error("programmer " LINUXSPI " does not support TPI\n"); + return -1; + } + // Enable programming on the part + tries = 0; + do { + ret = pgm->program_enable(pgm, p); + if(ret == 0 || ret == -1) + break; + } while(tries++ < 65); + + if(ret) + pmsg_error("AVR device not responding\n"); + + return ret; } -static int linuxspi_cmd(const PROGRAMMER *pgm, const unsigned char *cmd, unsigned char *res) -{ - return linuxspi_spi_duplex(pgm, cmd, res, 4); +static int linuxspi_cmd(const PROGRAMMER *pgm, const unsigned char *cmd, unsigned char *res) { + return linuxspi_spi_duplex(pgm, cmd, res, 4); } static int linuxspi_program_enable(const PROGRAMMER *pgm, const AVRPART *p) { - unsigned char cmd[4], res[4]; + unsigned char cmd[4], res[4]; - if (!p->op[AVR_OP_PGM_ENABLE]) { - pmsg_error("program enable instruction not defined for part %s\n", p->desc); - return -1; - } + if(!p->op[AVR_OP_PGM_ENABLE]) { + pmsg_error("program enable instruction not defined for part %s\n", p->desc); + return -1; + } - memset(cmd, 0, sizeof(cmd)); - avr_set_bits(p->op[AVR_OP_PGM_ENABLE], cmd); //set the cmd - pgm->cmd(pgm, cmd, res); - - if (res[2] != cmd[1]) { - /* - * From ATtiny441 datasheet: - * - * In some systems, the programmer can not guarantee that SCK is held low - * during power-up. In this case, RESET must be given a positive pulse after - * SCK has been set to '0'. The duration of the pulse must be at least t RST - * plus two CPU clock cycles. See Table 25-5 on page 240 for definition of - * minimum pulse width on RESET pin, t RST - * 2. Wait for at least 20 ms and then enable serial programming by sending - * the Programming Enable serial instruction to the SDO pin - * 3. The serial programming instructions will not work if the communication - * is out of synchronization. When in sync, the second byte (0x53) will echo - * back when issuing the third byte of the Programming Enable instruction - * ... - * If the 0x53 did not echo back, give RESET a positive pulse and issue a - * new Programming Enable command - */ - if (linuxspi_reset_mcu(pgm, false)) - return -1; - usleep(5); - if (linuxspi_reset_mcu(pgm, true)) - return -1; - usleep(20000); - - return -2; - } + memset(cmd, 0, sizeof(cmd)); + avr_set_bits(p->op[AVR_OP_PGM_ENABLE], cmd); // Set the cmd + pgm->cmd(pgm, cmd, res); - return 0; + if(res[2] != cmd[1]) { + /* + * From ATtiny441 datasheet: + * + * In some systems, the programmer can not guarantee that SCK is held low + * during power-up. In this case, RESET must be given a positive pulse + * after SCK has been set to '0'. The duration of the pulse must be at + * least t RST plus two CPU clock cycles. See Table 25-5 on page 240 for + * definition of minimum pulse width on RESET pin, t RST 2. Wait for at + * least 20 ms and then enable serial programming by sending the + * Programming Enable serial instruction to the SDO pin 3. The serial + * programming instructions will not work if the communication is out of + * synchronization. When in sync, the second byte (0x53) will echo back + * when issuing the third byte of the Programming Enable instruction ... If + * the 0x53 did not echo back, give RESET a positive pulse and issue a new + * Programming Enable command + */ + if(linuxspi_reset_mcu(pgm, false)) + return -1; + usleep(5); + if(linuxspi_reset_mcu(pgm, true)) + return -1; + usleep(20000); + + return -2; + } + + return 0; } static int linuxspi_chip_erase(const PROGRAMMER *pgm, const AVRPART *p) { - unsigned char cmd[4], res[4]; + unsigned char cmd[4], res[4]; - if (!p->op[AVR_OP_CHIP_ERASE]) { - pmsg_error("chip erase instruction not defined for part %s\n", p->desc); - return -1; - } + if(!p->op[AVR_OP_CHIP_ERASE]) { + pmsg_error("chip erase instruction not defined for part %s\n", p->desc); + return -1; + } - 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); + 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); - return 0; + return 0; } static int linuxspi_parseexitspecs(PROGRAMMER *pgm, const char *sp) { - char *cp, *s, *str = mmt_strdup(sp); - int rv = 0; - bool help = false; - - s = str; - while ((cp = strtok(s, ","))) { - s = NULL; - if (str_eq(cp, "reset")) { - pgm->exit_reset = EXIT_RESET_ENABLED; - continue; - } - if (str_eq(cp, "noreset")) { - pgm->exit_reset = EXIT_RESET_DISABLED; - continue; - } - if (str_eq(cp, "help")) { - help = true; - rv = LIBAVRDUDE_EXIT; - } - - if (!help) { - pmsg_error("invalid exitspec parameter -E %s\n", cp); - rv = -1; - } - msg_error("%s -c %s exitspec parameter options:\n", progname, pgmid); - msg_error(" -E reset Programmer will keep the reset line low after programming session\n"); - msg_error(" -E noreset Programmer will not keep the reset line low after programming session\n"); - msg_error(" -E help Show this help menu and exit\n"); - mmt_free(str); - return rv; + char *cp, *s, *str = mmt_strdup(sp); + int rv = 0; + bool help = false; + + s = str; + while((cp = strtok(s, ","))) { + s = NULL; + if(str_eq(cp, "reset")) { + pgm->exit_reset = EXIT_RESET_ENABLED; + continue; + } + if(str_eq(cp, "noreset")) { + pgm->exit_reset = EXIT_RESET_DISABLED; + continue; + } + if(str_eq(cp, "help")) { + help = true; + rv = LIBAVRDUDE_EXIT; } + if(!help) { + pmsg_error("invalid exitspec parameter -E %s\n", cp); + rv = -1; + } + msg_error("%s -c %s exitspec parameter options:\n", progname, pgmid); + msg_error(" -E reset Programmer will keep the reset line low after programming session\n"); + msg_error(" -E noreset Programmer will not keep the reset line low after programming session\n"); + msg_error(" -E help Show this help menu and exit\n"); mmt_free(str); return rv; + } + + mmt_free(str); + return rv; } static int linuxspi_parseextparams(const PROGRAMMER *pgm, const LISTID extparms) { int rc = 0; bool help = false; - for (LNODEID ln = lfirst(extparms); ln; ln = lnext(ln)) { + for(LNODEID ln = lfirst(extparms); ln; ln = lnext(ln)) { const char *extended_param = ldata(ln); - if (str_eq(extended_param, "disable_no_cs")) { + if(str_eq(extended_param, "disable_no_cs")) { my.disable_no_cs = 1; continue; } - if (str_eq(extended_param, "help")) { + if(str_eq(extended_param, "help")) { help = true; rc = LIBAVRDUDE_EXIT; } - if (!help) { + if(!help) { pmsg_error("invalid extended parameter -x %s\n", extended_param); rc = -1; } @@ -447,38 +449,37 @@ static int linuxspi_parseextparams(const PROGRAMMER *pgm, const LISTID extparms) } void linuxspi_initpgm(PROGRAMMER *pgm) { - strcpy(pgm->type, LINUXSPI); - - pgm_fill_old_pins(pgm); // TODO to be removed if old pin data no longer needed - - /* mandatory functions */ - pgm->initialize = linuxspi_initialize; - pgm->display = linuxspi_display; - pgm->enable = linuxspi_enable; - pgm->disable = linuxspi_disable; - pgm->program_enable = linuxspi_program_enable; - pgm->chip_erase = linuxspi_chip_erase; - pgm->cmd = linuxspi_cmd; - pgm->open = linuxspi_open; - pgm->close = linuxspi_close; - pgm->read_byte = avr_read_byte_default; - pgm->write_byte = avr_write_byte_default; - - /* optional functions */ - pgm->setup = linuxspi_setup; - pgm->teardown = linuxspi_teardown; - pgm->parseexitspecs = linuxspi_parseexitspecs; - pgm->parseextparams = linuxspi_parseextparams; + strcpy(pgm->type, LINUXSPI); + + pgm_fill_old_pins(pgm); // TODO to be removed if old pin data no longer needed + + // Mandatory functions + pgm->initialize = linuxspi_initialize; + pgm->display = linuxspi_display; + pgm->enable = linuxspi_enable; + pgm->disable = linuxspi_disable; + pgm->program_enable = linuxspi_program_enable; + pgm->chip_erase = linuxspi_chip_erase; + pgm->cmd = linuxspi_cmd; + pgm->open = linuxspi_open; + pgm->close = linuxspi_close; + pgm->read_byte = avr_read_byte_default; + pgm->write_byte = avr_write_byte_default; + + // Optional functions + pgm->setup = linuxspi_setup; + pgm->teardown = linuxspi_teardown; + pgm->parseexitspecs = linuxspi_parseexitspecs; + pgm->parseextparams = linuxspi_parseextparams; } const char linuxspi_desc[] = "SPI using Linux spidev driver"; -#else /* !HAVE_LINUXSPI */ +#else // ! HAVE_LINUXSPI void linuxspi_initpgm(PROGRAMMER *pgm) { pmsg_error("Linux SPI driver not available in this configuration\n"); } const char linuxspi_desc[] = "SPI using Linux spidev driver (not available)"; - -#endif /* HAVE_LINUXSPI */ +#endif // HAVE_LINUXSPI diff --git a/src/linuxspi.h b/src/linuxspi.h index db2890951..8cd493234 100644 --- a/src/linuxspi.h +++ b/src/linuxspi.h @@ -24,12 +24,11 @@ extern "C" { #endif -extern const char linuxspi_desc[]; -void linuxspi_initpgm(PROGRAMMER *pgm); + extern const char linuxspi_desc[]; + void linuxspi_initpgm(PROGRAMMER *pgm); #ifdef __cplusplus } #endif -#endif //linuxspi_h - +#endif diff --git a/src/lists.c b/src/lists.c index 5c2f5afcd..922575127 100644 --- a/src/lists.c +++ b/src/lists.c @@ -16,11 +16,6 @@ * along with this program. If not, see . */ - - -/*---------------------------------------------------------------------- - Id: lists.c,v 1.4 2001/08/19 23:26:20 bsd Exp $ - ----------------------------------------------------------------------*/ /*------------------------------------------------------------------------ lists.c @@ -43,66 +38,70 @@ #define MAGIC 0xb05b05b0 -#define CHECK_MAGIC 0 /* set to 1 to enable memory overwrite detection */ - -#define MALLOC(size,x) mmt_malloc(size) -#define FREE mmt_free +#define CHECK_MAGIC 0 // Set to 1 to enable memory overwrite detection +#define MALLOC(size, x) mmt_malloc(size) +#define FREE mmt_free /*------------------------------------------------------------ | required private data structures ------------------------------------------------------------*/ typedef struct LISTNODE { + #if CHECK_MAGIC - unsigned int magic1; + unsigned int magic1; #endif - struct LISTNODE * next; /* chain to next item in the list */ - struct LISTNODE * prev; /* chain to previous item in the list */ - void * data; /* pointer to user data */ + + struct LISTNODE *next; // Chain to next item in the list + struct LISTNODE *prev; // Chain to previous item in the list + void *data; // Pointer to user data + #if CHECK_MAGIC - unsigned int magic2; + unsigned int magic2; #endif } LISTNODE; - typedef struct NODEPOOL { + #if CHECK_MAGIC - unsigned int magic1; + unsigned int magic1; #endif - struct NODEPOOL * chain_next; /* chain to next node pool */ - struct NODEPOOL * chain_prev; /* chain to previous node pool */ + + struct NODEPOOL *chain_next; // Chain to next node pool + struct NODEPOOL *chain_prev; // Chain to previous node pool + #if CHECK_MAGIC - unsigned int magic2; + unsigned int magic2; #endif } NODEPOOL; - typedef struct LIST { + #if CHECK_MAGIC unsigned int magic1; #endif - int num; /* number of elements in the list */ - short int free_on_close; /* free the LIST memory on close T/F */ - short int poolsize; /* list node allocation size */ - int n_ln_pool; /* number of listnodes in a pool */ - LISTNODE * top; /* top of the list */ - LISTNODE * bottom; /* bottom of the list */ - LISTNODE * next_ln; /* next available list node */ - NODEPOOL * np_top; /* top of the node pool chain */ - NODEPOOL * np_bottom; /* bottom of the node pool chain */ + + int num; // Number of elements in the list + short int free_on_close; // Free the LIST memory on close T/F + short int poolsize; // List node allocation size + int n_ln_pool; // Number of listnodes in a pool + LISTNODE *top; // Top of the list + LISTNODE *bottom; // Bottom of the list + LISTNODE *next_ln; // Next available list node + NODEPOOL *np_top; // Top of the node pool chain + NODEPOOL *np_bottom; // Bottom of the node pool chain + #if CHECK_MAGIC unsigned int magic2; #endif } LIST; - -/* allocate list nodes in 512 byte chunks, giving 42 elements */ +// Allocate list nodes in 512 byte chunks, giving 42 elements #define DEFAULT_POOLSIZE 512 - #if CHECK_MAGIC -#define CKMAGIC(p) { if (p->magic1 != MAGIC) breakpoint(); \ - if (p->magic2 != MAGIC) breakpoint(); } +#define CKMAGIC(p) { if(p->magic1 != MAGIC) breakpoint(); \ + if(p->magic2 != MAGIC) breakpoint(); } #define CKNPMAGIC(p) cknpmagic(p) @@ -119,18 +118,16 @@ typedef struct LIST { #define CKLMAGIC(p) #endif - -static int insert_ln ( LIST * l, LISTNODE * ln, void * data_ptr ); - +static int insert_ln(LIST *l, LISTNODE *ln, void *data_ptr); #if CHECK_MAGIC -static int cknpmagic ( LIST * l ) { - NODEPOOL * np; +static int cknpmagic(LIST *l) { + NODEPOOL *np; int i; i = 0; np = l->np_top; - while (np) { + while(np) { i++; CKMAGIC(np); np = np->chain_next; @@ -138,7 +135,7 @@ static int cknpmagic ( LIST * l ) { i = 0; np = l->np_bottom; - while (np) { + while(np) { i++; CKMAGIC(np); np = np->chain_prev; @@ -147,15 +144,13 @@ static int cknpmagic ( LIST * l ) { return 0; } - - -static int cklnmagic ( LIST * l ) { - LISTNODE * ln; +static int cklnmagic(LIST *l) { + LISTNODE *ln; int i; i = 0; ln = l->top; - while (ln) { + while(ln) { i++; CKMAGIC(ln); ln = ln->next; @@ -163,7 +158,7 @@ static int cklnmagic ( LIST * l ) { i = 0; ln = l->bottom; - while (ln) { + while(ln) { i++; CKMAGIC(ln); ln = ln->prev; @@ -172,8 +167,7 @@ static int cklnmagic ( LIST * l ) { return 0; } - -static int cklmagic ( LIST * l ) { +static int cklmagic(LIST *l) { CKMAGIC(l); CKNPMAGIC(l); CKLNMAGIC(l); @@ -182,7 +176,6 @@ static int cklmagic ( LIST * l ) { } #endif - /*------------------------------------------------------------ | new_node_pool | @@ -191,9 +184,9 @@ static int cklmagic ( LIST * l ) { | bytes reserved. The first available list node resides at | offset sizeof(NODEPOOL). ------------------------------------------------------------*/ -static NODEPOOL *new_nodepool ( LIST * l ) { - NODEPOOL * np; - LISTNODE * ln; +static NODEPOOL *new_nodepool(LIST *l) { + NODEPOOL *np; + LISTNODE *ln; int i; CKLMAGIC(l); @@ -201,8 +194,8 @@ static NODEPOOL *new_nodepool ( LIST * l ) { /*-------------------------------------------------- | get a block of memory for the new pool --------------------------------------------------*/ - np = (NODEPOOL *) MALLOC ( l->poolsize, "list node pool" ); - if (np == NULL) { + np = (NODEPOOL *) MALLOC(l->poolsize, "list node pool"); + if(np == NULL) { return NULL; } @@ -210,11 +203,14 @@ static NODEPOOL *new_nodepool ( LIST * l ) { | initialize the chaining information at the | beginning of the pool. --------------------------------------------------*/ + #if CHECK_MAGIC np->magic1 = MAGIC; #endif + np->chain_next = NULL; np->chain_prev = NULL; + #if CHECK_MAGIC np->magic2 = MAGIC; #endif @@ -229,33 +225,40 @@ static NODEPOOL *new_nodepool ( LIST * l ) { #if CHECK_MAGIC ln[0].magic1 = MAGIC; #endif + ln[0].data = NULL; ln[0].next = &ln[1]; ln[0].prev = NULL; + #if CHECK_MAGIC ln[0].magic2 = MAGIC; #endif - for (i=1; in_ln_pool-1; i++) { + for(i = 1; i < l->n_ln_pool - 1; i++) { + #if CHECK_MAGIC ln[i].magic1 = MAGIC; #endif + ln[i].data = NULL; - ln[i].next = &ln[i+1]; - ln[i].prev = &ln[i-1]; + ln[i].next = &ln[i + 1]; + ln[i].prev = &ln[i - 1]; + #if CHECK_MAGIC ln[i].magic2 = MAGIC; #endif } #if CHECK_MAGIC - ln[l->n_ln_pool-1].magic1 = MAGIC; + ln[l->n_ln_pool - 1].magic1 = MAGIC; #endif - ln[l->n_ln_pool-1].data = NULL; - ln[l->n_ln_pool-1].next = NULL; - ln[l->n_ln_pool-1].prev = &ln[l->n_ln_pool-2]; + + ln[l->n_ln_pool - 1].data = NULL; + ln[l->n_ln_pool - 1].next = NULL; + ln[l->n_ln_pool - 1].prev = &ln[l->n_ln_pool - 2]; + #if CHECK_MAGIC - ln[l->n_ln_pool-1].magic2 = MAGIC; + ln[l->n_ln_pool - 1].magic2 = MAGIC; #endif CKMAGIC(np); @@ -265,8 +268,6 @@ static NODEPOOL *new_nodepool ( LIST * l ) { return np; } - - /*------------------------------------------------------------ | get_listnode | @@ -274,23 +275,25 @@ static NODEPOOL *new_nodepool ( LIST * l ) { | list nodes, another pool of list nodes is allocated. If | that fails, NULL is returned. ------------------------------------------------------------*/ -static LISTNODE * get_listnode ( LIST * l ) { - LISTNODE * ln; - NODEPOOL * np; +static LISTNODE *get_listnode(LIST *l) { + LISTNODE *ln; + NODEPOOL *np; CKLMAGIC(l); - if (l->next_ln == NULL) { + if(l->next_ln == NULL) { + /*-------------------------------------------------- | allocate a new node pool and chain to the others --------------------------------------------------*/ np = new_nodepool(l); - if (np == NULL) { + if(np == NULL) { CKLMAGIC(l); return NULL; } - if (l->np_top == NULL) { + if(l->np_top == NULL) { + /*-------------------------------------------------- | this is the first node pool for this list, | directly assign to the top and bottom. @@ -299,8 +302,8 @@ static LISTNODE * get_listnode ( LIST * l ) { l->np_bottom = np; np->chain_next = NULL; np->chain_prev = NULL; - } - else { + } else { + /*-------------------------------------------------- | this is an additional node pool, add it to the | chain. @@ -316,7 +319,7 @@ static LISTNODE * get_listnode ( LIST * l ) { | list node to the first list node in this new | pool. --------------------------------------------------*/ - l->next_ln = (LISTNODE *)&np[1]; + l->next_ln = (LISTNODE *) & np[1]; CKMAGIC(np); } @@ -343,8 +346,6 @@ static LISTNODE * get_listnode ( LIST * l ) { return ln; } - - /*------------------------------------------------------------ | free_listnode | @@ -353,7 +354,7 @@ static LISTNODE * get_listnode ( LIST * l ) { | call to 'get_listnode', with return the most recently | freed one. ------------------------------------------------------------*/ -static int free_listnode ( LIST * l, LISTNODE * ln ) { +static int free_listnode(LIST *l, LISTNODE *ln) { CKLMAGIC(l); /*-------------------------------------------------- @@ -370,13 +371,11 @@ static int free_listnode ( LIST * l, LISTNODE * ln ) { return 0; } - - /*---------------------------------------------------------------------- lcreat - Create a new list data structure. - + Create a new list data structure. + If liststruct is not NULL, it is used to provide the memory space for the list structure instance, otherwise, the necessary memory is mmt_malloc'd. @@ -388,22 +387,21 @@ static int free_listnode ( LIST * l, LISTNODE * ln ) { The first node pool is not preallocated; instead it is mmt_malloc'd at the time of the first use. ----------------------------------------------------------------------*/ -LISTID -lcreat ( void * liststruct, int elements ) -{ - LIST * l; +LISTID lcreat(void *liststruct, int elements) { + LIST *l; + + if(liststruct == NULL) { - if (liststruct == NULL) { /*-------------------------------------------------- allocate memory for the list itself --------------------------------------------------*/ - l = (LIST *) MALLOC ( sizeof(LIST), "list struct" ); - if (l == NULL) { + l = (LIST *) MALLOC(sizeof(LIST), "list struct"); + if(l == NULL) { return NULL; } l->free_on_close = 1; - } - else { + } else { + /*----------------------------------------------------------------- use the memory given to us for the list structure -----------------------------------------------------------------*/ @@ -414,25 +412,26 @@ lcreat ( void * liststruct, int elements ) /*-------------------------------------------------- | initialize the list --------------------------------------------------*/ + #if CHECK_MAGIC l->magic1 = MAGIC; l->magic2 = MAGIC; #endif + l->top = NULL; l->bottom = NULL; l->num = 0; - if (elements == 0) { + if(elements == 0) { l->poolsize = DEFAULT_POOLSIZE; - } - else { - l->poolsize = elements*sizeof(LISTNODE)+sizeof(NODEPOOL); + } else { + l->poolsize = elements*sizeof(LISTNODE) + sizeof(NODEPOOL); } - l->n_ln_pool = (l->poolsize-sizeof(NODEPOOL))/sizeof(LISTNODE); + l->n_ln_pool = (l->poolsize - sizeof(NODEPOOL))/sizeof(LISTNODE); - if (l->n_ln_pool < 5) { - if (!liststruct) { + if(l->n_ln_pool < 5) { + if(!liststruct) { FREE(l); } return NULL; @@ -444,10 +443,9 @@ lcreat ( void * liststruct, int elements ) CKLMAGIC(l); - return (LISTID)l; + return (LISTID) l; } - /*-------------------------------------------------- | ldestroy_cb | @@ -458,27 +456,23 @@ lcreat ( void * liststruct, int elements ) | call their function to free up each list element | at the same time. --------------------------------------------------*/ -void -ldestroy_cb ( LISTID lid, void (*ucleanup)(void * data_ptr) ) -{ - LIST * l; - LISTNODE * ln; +void ldestroy_cb(LISTID lid, void (*ucleanup)(void *data_ptr)) { + LIST *l; + LISTNODE *ln; - l = (LIST *)lid; + l = (LIST *) lid; CKLMAGIC(l); ln = l->top; - while (ln != NULL) { - ucleanup ( ln->data ); + while(ln != NULL) { + ucleanup(ln->data); ln = ln->next; } - ldestroy ( l ); + ldestroy(l); } - - /*-------------------------------------------------- | ldestroy | @@ -487,13 +481,11 @@ ldestroy_cb ( LISTID lid, void (*ucleanup)(void * data_ptr) ) | assumes that each data element does not need to | be freed. --------------------------------------------------*/ -void -ldestroy ( LISTID lid ) -{ - LIST * l; - NODEPOOL * p1, * p2; +void ldestroy(LISTID lid) { + LIST *l; + NODEPOOL *p1, *p2; - l = (LIST *)lid; + l = (LIST *) lid; CKLMAGIC(l); @@ -503,7 +495,7 @@ ldestroy ( LISTID lid ) | no more. --------------------------------------------------*/ p1 = l->np_top; - while (p1 != NULL) { + while(p1 != NULL) { p2 = p1->chain_next; FREE(p1); p1 = p2; @@ -512,34 +504,31 @@ ldestroy ( LISTID lid ) /*-------------------------------------------------- | now free the memory occupied by the list itself --------------------------------------------------*/ - if (l->free_on_close) { - FREE ( l ); + if(l->free_on_close) { + FREE(l); } } - - - /*------------------------------------------------------------ | ladd | | add list - add item p to the list ------------------------------------------------------------*/ -int -ladd ( LISTID lid, void * p ) -{ - LIST * l; +int ladd(LISTID lid, void *p) { + LIST *l; LISTNODE *lnptr; - l = (LIST *)lid; + l = (LIST *) lid; CKLMAGIC(l); lnptr = get_listnode(l); - if (lnptr==NULL) { + if(lnptr == NULL) { + #ifdef BOS breakpoint(); #endif + return -1; } @@ -547,13 +536,12 @@ ladd ( LISTID lid, void * p ) lnptr->data = p; - if (l->top == NULL) { + if(l->top == NULL) { l->top = lnptr; l->bottom = lnptr; lnptr->next = NULL; lnptr->prev = NULL; - } - else { + } else { lnptr->prev = l->bottom; lnptr->next = NULL; l->bottom->next = lnptr; @@ -566,8 +554,6 @@ ladd ( LISTID lid, void * p ) return 0; } - - /*------------------------------------------------------------ | laddo | @@ -577,277 +563,227 @@ ladd ( LISTID lid, void * p ) | else return 1 indicating a duplicate entry, i.e., the | compare function returned 0 while inserting the element. ------------------------------------------------------------*/ -int -laddo ( LISTID lid, void * p, int (*compare)(const void *p1,const void *p2), - LNODEID * firstdup ) -{ - LIST * l; - LISTNODE * ln; +int laddo(LISTID lid, void *p, int (*compare)(const void *p1, const void *p2), LNODEID *firstdup) { + LIST *l; + LISTNODE *ln; int dup, cmp; - l = (LIST *)lid; + l = (LIST *) lid; CKLMAGIC(l); dup = 0; ln = l->top; - while (ln!=NULL) { + while(ln != NULL) { CKMAGIC(ln); - cmp = compare(p,ln->data); - if (cmp == 0) { + cmp = compare(p, ln->data); + if(cmp == 0) { dup = 1; - if (firstdup) - *firstdup = ln; + if(firstdup) + *firstdup = ln; } - if (cmp < 0) { - insert_ln(l,ln,p); + if(cmp < 0) { + insert_ln(l, ln, p); CKLMAGIC(l); return dup; - } - else { + } else { ln = ln->next; } } - ladd(l,p); + ladd(l, p); CKLMAGIC(l); return dup; } - /*--------------------------------------------------------------------------- | laddu | | add list, ordered, unique - add item p to the list, use 'compare' | function to place 'p' when the comparison 'p' is less than the next | item. Return 1 if the item was added, 0 if not. -| --------------------------------------------------------------------------*/ -int -laddu ( LISTID lid, void * p, int (*compare)(const void *p1,const void *p2) ) -{ - LIST * l; - LISTNODE * ln; +int laddu(LISTID lid, void *p, int (*compare)(const void *p1, const void *p2)) { + LIST *l; + LISTNODE *ln; int cmp; - l = (LIST *)lid; + l = (LIST *) lid; CKLMAGIC(l); ln = l->top; - while (ln!=NULL) { + while(ln != NULL) { CKMAGIC(ln); - cmp = compare(p,ln->data); - if (cmp == 0) { + cmp = compare(p, ln->data); + if(cmp == 0) { CKLMAGIC(l); return 0; } - if (cmp < 0) { - insert_ln(l,ln,p); + if(cmp < 0) { + insert_ln(l, ln, p); CKLMAGIC(l); return 1; - } - else { + } else { ln = ln->next; } } - ladd(l,p); + ladd(l, p); CKLMAGIC(l); return 1; } - - - -LNODEID -lfirst ( LISTID lid ) -{ - CKLMAGIC(((LIST *)lid)); - return ((LIST *)lid)->top; +LNODEID lfirst(LISTID lid) { + CKLMAGIC(((LIST *) lid)); + return ((LIST *) lid)->top; } - -LNODEID -llast ( LISTID lid ) -{ - CKLMAGIC(((LIST *)lid)); - return ((LIST *)lid)->bottom; +LNODEID llast(LISTID lid) { + CKLMAGIC(((LIST *) lid)); + return ((LIST *) lid)->bottom; } - -LNODEID -lnext ( LNODEID lnid ) -{ - CKMAGIC(((LISTNODE *)lnid)); - return ((LISTNODE *)lnid)->next; +LNODEID lnext(LNODEID lnid) { + CKMAGIC(((LISTNODE *) lnid)); + return ((LISTNODE *) lnid)->next; } - -LNODEID -lprev ( LNODEID lnid ) -{ - CKMAGIC(((LISTNODE *)lnid)); - return ((LISTNODE *)lnid)->prev; +LNODEID lprev(LNODEID lnid) { + CKMAGIC(((LISTNODE *) lnid)); + return ((LISTNODE *) lnid)->prev; } - -void * -ldata ( LNODEID lnid ) -{ - CKMAGIC(((LISTNODE *)lnid)); - return ((LISTNODE *)lnid)->data; +void *ldata(LNODEID lnid) { + CKMAGIC(((LISTNODE *) lnid)); + return ((LISTNODE *) lnid)->data; } - - -int -lsize ( LISTID lid ) -{ - CKLMAGIC(((LIST *)lid)); - return ((LIST *)lid)->num; +int lsize(LISTID lid) { + CKLMAGIC(((LIST *) lid)); + return ((LIST *) lid)->num; } - - /*------------------------------------------------------------ | lcat | | catenate - catenate l2 to l1, return pointer to l1. ------------------------------------------------------------*/ -LISTID -lcat ( LISTID lid1, LISTID lid2 ) -{ - CKLMAGIC(((LIST *)lid1)); - CKLMAGIC(((LIST *)lid2)); - while (lsize(lid2)) { - ladd ( lid1, lrmv_n(lid2,1) ); +LISTID lcat(LISTID lid1, LISTID lid2) { + CKLMAGIC(((LIST *) lid1)); + CKLMAGIC(((LIST *) lid2)); + while(lsize(lid2)) { + ladd(lid1, lrmv_n(lid2, 1)); } - CKLMAGIC(((LIST *)lid1)); - CKLMAGIC(((LIST *)lid2)); + CKLMAGIC(((LIST *) lid1)); + CKLMAGIC(((LIST *) lid2)); return lid1; } - - /*---------------------------------------------------------------------- | lget | | get from list, last item - return pointer to the data of the last | item in the list, non-destructive ----------------------------------------------------------------------*/ -void * -lget ( LISTID lid ) -{ - LIST * l; - LISTNODE * p; +void *lget(LISTID lid) { + LIST *l; + LISTNODE *p; - l = (LIST *)lid; + l = (LIST *) lid; CKLMAGIC(l); p = l->bottom; - if (p == NULL) { + if(p == NULL) { CKLMAGIC(l); return NULL; - } - else { + } else { CKLMAGIC(l); return p->data; } } - - /*--------------------------------------------------------------- | lget_n | -| get from list, index - return the nth list item, +| get from list, index - return the nth list item, | non-destructive ---------------------------------------------------------------*/ -void * -lget_n ( LISTID lid, unsigned int n ) -{ +void *lget_n(LISTID lid, unsigned int n) { unsigned int i; - LIST * l; - LISTNODE * ln; + LIST *l; + LISTNODE *ln; - l = (LIST *)lid; + l = (LIST *) lid; CKLMAGIC(l); - if (n < 1 || n > (unsigned int) lsize(l)) { + if(n < 1 || n > (unsigned int) lsize(l)) { return NULL; } ln = l->top; i = 1; - while (ln && (i!=n)) { + while(ln && (i != n)) { CKMAGIC(ln); ln = ln->next; i++; } - if (ln) { + if(ln) { CKLMAGIC(l); return ln->data; - } - else { + } else { CKLMAGIC(l); return NULL; } } - - /*--------------------------------------------------------------- | lget_ln | | get from list, listnode - return the nth list item, the | listnode is returned instead of the data, non-destructive ---------------------------------------------------------------*/ -LNODEID -lget_ln ( LISTID lid, unsigned int n ) -{ +LNODEID lget_ln(LISTID lid, unsigned int n) { unsigned int i; - LIST * l; - LISTNODE * ln; + LIST *l; + LISTNODE *ln; - l = (LIST *)lid; + l = (LIST *) lid; CKLMAGIC(l); - if (n < 1 || n > (unsigned int) lsize(l)) { + if(n < 1 || n > (unsigned int) lsize(l)) { return NULL; } ln = l->top; i = 1; - while (i!=n) { + while(i != n) { CKMAGIC(ln); ln = ln->next; i++; } CKLMAGIC(l); - return (LNODEID)ln; + return (LNODEID) ln; } - - /*---------------------------------------------------------------------- | insert_ln | -| insert data, listnode - insert data just before the list item +| insert data, listnode - insert data just before the list item | pointed to by 'ln'. | | This routine is not intended to be called directly by the user @@ -855,22 +791,24 @@ lget_ln ( LISTID lid, unsigned int n ) | by list manipulation routines within this module, in which ln is | known to point to a valid list node. ----------------------------------------------------------------------*/ -static int insert_ln ( LIST * l, LISTNODE * ln, void * data_ptr ) { - LISTNODE * lnptr; +static int insert_ln(LIST *l, LISTNODE *ln, void *data_ptr) { + LISTNODE *lnptr; CKLMAGIC(l); - if (ln==NULL) { - ladd ( l, data_ptr ); + if(ln == NULL) { + ladd(l, data_ptr); CKLMAGIC(l); return 0; } lnptr = get_listnode(l); - if (lnptr == NULL) { + if(lnptr == NULL) { + #ifdef BOS breakpoint(); #endif + return -1; } @@ -878,7 +816,8 @@ static int insert_ln ( LIST * l, LISTNODE * ln, void * data_ptr ) { lnptr->data = data_ptr; - if (ln==l->top) { + if(ln == l->top) { + /*------------------------------ | insert before the list head ------------------------------*/ @@ -886,8 +825,8 @@ static int insert_ln ( LIST * l, LISTNODE * ln, void * data_ptr ) { lnptr->prev = NULL; ln->prev = lnptr; l->top = lnptr; - } - else if (ln==NULL) { + } else if(ln == NULL) { + /*----------------- | list was empty -----------------*/ @@ -895,8 +834,8 @@ static int insert_ln ( LIST * l, LISTNODE * ln, void * data_ptr ) { lnptr->prev = l->bottom; l->bottom->next = lnptr; l->bottom = lnptr; - } - else { + } else { + /*----------------------------------- | insert in the middle of the list -----------------------------------*/ @@ -913,30 +852,26 @@ static int insert_ln ( LIST * l, LISTNODE * ln, void * data_ptr ) { return 0; } - - /*----------------------------------------------------------------- | lins_n | | Insert data before the nth item in the list. -----------------------------------------------------------------*/ -int -lins_n ( LISTID lid, void * data_ptr, unsigned int n ) -{ +int lins_n(LISTID lid, void *data_ptr, unsigned int n) { unsigned int i; - LIST * l; - LISTNODE * ln; + LIST *l; + LISTNODE *ln; - l = (LIST *)lid; + l = (LIST *) lid; CKLMAGIC(l); - if (n < 1 || n > (unsigned int) (l->num+1)) { + if(n < 1 || n > (unsigned int) (l->num + 1)) { return -1; } - if (l->num == 0) { - return ladd ( lid, data_ptr ); + if(l->num == 0) { + return ladd(lid, data_ptr); } /*---------------------------------- @@ -944,13 +879,13 @@ lins_n ( LISTID lid, void * data_ptr, unsigned int n ) ----------------------------------*/ ln = l->top; i = 1; - while (ln && (i!=n)) { + while(ln && (i != n)) { CKMAGIC(ln); ln = ln->next; i++; } - if (!ln) { + if(!ln) { CKLMAGIC(l); return -1; } @@ -960,24 +895,21 @@ lins_n ( LISTID lid, void * data_ptr, unsigned int n ) /*----------------------------------------- | insert before the nth item in the list -----------------------------------------*/ - return insert_ln ( l, ln, data_ptr ); + return insert_ln(l, ln, data_ptr); } - /*----------------------------------------------------------------- | lins_ln | | Insert data before the list node pointed to by ln. -----------------------------------------------------------------*/ -int -lins_ln ( LISTID lid, LNODEID lnid, void * data_ptr ) -{ - LIST * l; - LISTNODE * ln; - LISTNODE * ln_ptr; +int lins_ln(LISTID lid, LNODEID lnid, void *data_ptr) { + LIST *l; + LISTNODE *ln; + LISTNODE *ln_ptr; - l = (LIST *)lid; - ln = (LISTNODE *)lnid; + l = (LIST *) lid; + ln = (LISTNODE *) lnid; CKLMAGIC(l); @@ -987,12 +919,12 @@ lins_ln ( LISTID lid, LNODEID lnid, void * data_ptr ) | validate that ln is indeed in the list -----------------------------------------*/ ln_ptr = l->top; - while ((ln_ptr!=NULL)&&(ln_ptr!=ln)) { + while((ln_ptr != NULL) && (ln_ptr != ln)) { CKMAGIC(ln_ptr); ln_ptr = ln_ptr->next; } - if (ln_ptr == NULL) { + if(ln_ptr == NULL) { CKLMAGIC(l); return -1; } @@ -1002,11 +934,9 @@ lins_ln ( LISTID lid, LNODEID lnid, void * data_ptr ) /*-------------------------------- | insert the data into the list --------------------------------*/ - return insert_ln ( l, ln, data_ptr ); + return insert_ln(l, ln, data_ptr); } - - /*---------------------------------------------------------------------- | remove_ln | @@ -1016,38 +946,39 @@ lins_ln ( LISTID lid, LNODEID lnid, void * data_ptr ) | routines within this module, in which ln is known to point to a | valid list node. ----------------------------------------------------------------------*/ -static void * remove_ln ( LIST * l, LISTNODE * ln ) { - void * r; +static void *remove_ln(LIST *l, LISTNODE *ln) { + void *r; CKLMAGIC(l); CKMAGIC(ln); - if (ln==l->top) { + if(ln == l->top) { + /*------------------------------ | remove the head of the list ------------------------------*/ l->top = ln->next; - if (l->top != NULL) { + if(l->top != NULL) { l->top->prev = NULL; - } - else { + } else { + /*---------------------------------------- | this was the only item in the list ----------------------------------------*/ l->bottom = NULL; } - } - else if (ln==l->bottom) { + } else if(ln == l->bottom) { + /*------------------------------ | remove the tail of the list ------------------------------*/ l->bottom = ln->prev; - if (l->bottom != NULL) { + if(l->bottom != NULL) { l->bottom->next = NULL; } - } - else { + } else { + /*------------------------------------- | remove from the middle of the list -------------------------------------*/ @@ -1063,7 +994,7 @@ static void * remove_ln ( LIST * l, LISTNODE * ln ) { /*----------------------------------------------- | free the listnode for re-use -----------------------------------------------*/ - free_listnode(l,ln); + free_listnode(l, ln); /*------------------------------------ | adjust the item count of the list @@ -1075,175 +1006,151 @@ static void * remove_ln ( LIST * l, LISTNODE * ln ) { return r; } - - /*------------------------------------------------------------------------- | lrmv_d | | remove from list, data - removes the data element from the list, | destructive -------------------------------------------------------------------------*/ -void * -lrmv_d ( LISTID lid, void * data_ptr ) -{ - LIST * l; - LISTNODE * ln; +void *lrmv_d(LISTID lid, void *data_ptr) { + LIST *l; + LISTNODE *ln; - l = (LIST *)lid; + l = (LIST *) lid; CKLMAGIC(l); ln = l->top; - while (ln && (ln->data != data_ptr)) { + while(ln && (ln->data != data_ptr)) { CKMAGIC(ln); ln = ln->next; } - if (ln == NULL) { + if(ln == NULL) { CKLMAGIC(l); return NULL; - } - else { + } else { CKLMAGIC(l); - return remove_ln ( l, ln ); + return remove_ln(l, ln); } } - - /*------------------------------------------------------------------------- | lrmv_ln | | remove from list, by list node - remove the data element pointed to | by 'ln' from the list, destructive -------------------------------------------------------------------------*/ -void * -lrmv_ln ( LISTID lid, LNODEID lnid ) -{ - LIST * l; - LISTNODE * ln; - LISTNODE * p; +void *lrmv_ln(LISTID lid, LNODEID lnid) { + LIST *l; + LISTNODE *ln; + LISTNODE *p; - l = (LIST *)lid; - ln = (LISTNODE *)lnid; + l = (LIST *) lid; + ln = (LISTNODE *) lnid; CKLMAGIC(l); CKMAGIC(ln); p = l->top; - while ((p!=NULL)&&(p!=ln)) { + while((p != NULL) && (p != ln)) { CKMAGIC(p); p = p->next; } - - if (p==NULL) { + + if(p == NULL) { CKLMAGIC(l); return NULL; - } - else { + } else { CKLMAGIC(l); - return remove_ln ( l, p ); + return remove_ln(l, p); } } - - /*---------------------------------------------------------------------- | lrmv_n | | remove from list, by item number - remove the nth element from | the list. ----------------------------------------------------------------------*/ -void * -lrmv_n ( LISTID lid, unsigned int n ) -{ +void *lrmv_n(LISTID lid, unsigned int n) { unsigned int i; - LIST * l; - LISTNODE * ln; + LIST *l; + LISTNODE *ln; - l = (LIST *)lid; + l = (LIST *) lid; CKLMAGIC(l); - if (n < 1 || n > (unsigned int) l->num) { + if(n < 1 || n > (unsigned int) l->num) { return NULL; } ln = l->top; i = 1; - while (ln && (i!=n)) { + while(ln && (i != n)) { CKMAGIC(ln); ln = ln->next; i++; } - if (ln) { + if(ln) { CKLMAGIC(l); - return remove_ln ( l, ln ); - } - else { + return remove_ln(l, ln); + } else { CKLMAGIC(l); return NULL; } } - /*---------------------------------------------------------------------- | lrmv | | remove from list, last item - remove the last item from the list, | destructive ----------------------------------------------------------------------*/ -void * -lrmv ( LISTID lid ) -{ - LIST * l; - LISTNODE * p; +void *lrmv(LISTID lid) { + LIST *l; + LISTNODE *p; - l = (LIST *)lid; + l = (LIST *) lid; CKLMAGIC(l); p = l->bottom; - if (p == NULL) { + if(p == NULL) { CKLMAGIC(l); return NULL; - } - else { + } else { CKLMAGIC(l); - return remove_ln ( l, p ); + return remove_ln(l, p); } } - - /*---------------------------------------------------------------------- | lsrch | | search list - return data element pointed to by 'p', NULL if not | found ----------------------------------------------------------------------*/ -void * -lsrch ( LISTID lid, void * p, int (* compare)(void * p1, void * p2) ) -{ - LIST * l; - LISTNODE * ln; +void *lsrch(LISTID lid, void *p, int (*compare)(void *p1, void *p2)) { + LIST *l; + LISTNODE *ln; - l = (LIST *)lid; + l = (LIST *) lid; CKLMAGIC(l); ln = l->top; - while (ln!=NULL) { + while(ln != NULL) { CKMAGIC(ln); - if (compare(p,ln->data) == 0) { + if(compare(p, ln->data) == 0) { CKLMAGIC(l); return ln->data; - } - else { + } else { ln = ln->next; } } @@ -1258,26 +1165,25 @@ lsrch ( LISTID lid, void * p, int (* compare)(void * p1, void * p2) ) | sort list - sorts list inplace (using bubble sort) | ----------------------------------------------------------------------*/ -void -lsort ( LISTID lid, int (* compare)(void * p1, void * p2) ) -{ - LIST * l; - LISTNODE * lt; /* this */ - LISTNODE * ln; /* next */ +void lsort(LISTID lid, int (*compare)(void *p1, void *p2)) { + LIST *l; + LISTNODE *lt; // This + LISTNODE *ln; // Next int unsorted = 1; - l = (LIST *)lid; + l = (LIST *) lid; CKLMAGIC(l); - while(unsorted){ + while(unsorted) { lt = l->top; unsorted = 0; - while (lt!=NULL) { + while(lt != NULL) { CKMAGIC(lt); ln = lt->next; - if (ln!= NULL && compare(lt->data,ln->data) > 0) { - void * p = ln->data; + if(ln != NULL && compare(lt->data, ln->data) > 0) { + void *p = ln->data; + ln->data = lt->data; lt->data = p; unsorted = 1; @@ -1289,91 +1195,83 @@ lsort ( LISTID lid, int (* compare)(void * p1, void * p2) ) CKLMAGIC(l); } - -int lprint ( FILE * f, LISTID lid ) -{ - LIST * l; - LISTNODE * ln; - NODEPOOL * np; +int lprint(FILE *f, LISTID lid) { + LIST *l; + LISTNODE *ln; + NODEPOOL *np; int count; - l = (LIST *)lid; + l = (LIST *) lid; + + fprintf(f, "list id %p internal data structures:\n", lid); - fprintf ( f, "list id %p internal data structures:\n", - lid ); #if CHECK_MAGIC - if ((l->magic1 != MAGIC) || (l->magic2 != MAGIC)) { - fprintf ( f, " *** WARNING: LIST MAGIC IS CORRUPT ***\n" ); + if((l->magic1 != MAGIC) || (l->magic2 != MAGIC)) { + fprintf(f, " *** WARNING: LIST MAGIC IS CORRUPT ***\n"); } - fprintf ( f, - " magic1=0x%08x\n" - " magic2=0x%08x\n", - l->magic1, l->magic2 ); + fprintf(f, " magic1=0x%08x\n" " magic2=0x%08x\n", l->magic1, l->magic2); #endif - fprintf ( f, " num f pool n_ln top bottom next_ln np_top np_bottom\n" ); - fprintf ( f, " ---- - ---- ---- ---------- ---------- ---------- ---------- ----------\n" ); - fprintf ( f, " %4d %1d %4d %4d %10p %10p %10p %10p %10p\n", - l->num, l->free_on_close, l->poolsize, l->n_ln_pool, - l->top, l->bottom, - l->next_ln, l->np_top, l->np_bottom ); - - - fprintf ( f, - " node pools:\n" - " idx np magic1 next prev magic2\n" - " ---- ---------- ---------- ---------- ---------- ----------\n" ); + + fprintf(f, " num f pool n_ln top bottom next_ln np_top np_bottom\n"); + fprintf(f, " ---- - ---- ---- ---------- ---------- ---------- ---------- ----------\n"); + fprintf(f, " %4d %1d %4d %4d %10p %10p %10p %10p %10p\n", + l->num, l->free_on_close, l->poolsize, l->n_ln_pool, l->top, l->bottom, l->next_ln, l->np_top, l->np_bottom); + + fprintf(f, + " node pools:\n" + " idx np magic1 next prev magic2\n" + " ---- ---------- ---------- ---------- ---------- ----------\n"); count = 0; np = l->np_top; - while (np != NULL) { + while(np != NULL) { count++; - fprintf ( f, " %4d %10p 0x%08x %10p %10p 0x%08x\n", - count, np, + fprintf(f, " %4d %10p 0x%08x %10p %10p 0x%08x\n", count, np, + #if CHECK_MAGIC - np->magic1, + np->magic1, #else - 0, + 0, #endif - np->chain_next, np->chain_prev, + + np->chain_next, np->chain_prev, + #if CHECK_MAGIC - np->magic2 + np->magic2 #else - 0 + 0 #endif + ); np = np->chain_next; } - if (f) { - fprintf ( f, - " list elements:\n" - " n ln magic1 next prev data magic2\n" - " ---- ---------- ---------- ---------- ---------- ---------- ----------\n" ); + if(f) { + fprintf(f, + " list elements:\n" + " n ln magic1 next prev data magic2\n" + " ---- ---------- ---------- ---------- ---------- ---------- ----------\n"); count = 0; ln = l->top; - while (ln != NULL) { + while(ln != NULL) { count++; - fprintf ( f, " %4d %10p %10x %10p %10p %10p %10x\n", - count, ln, + fprintf(f, " %4d %10p %10x %10p %10p %10p %10x\n", count, ln, #if CHECK_MAGIC - ln->magic1, + ln->magic1, #else - 0, + 0, #endif - ln->next, ln->prev, ln->data, + ln->next, ln->prev, ln->data, #if CHECK_MAGIC - ln->magic2 + ln->magic2 #else - 0 + 0 #endif ); ln = lnext(ln); } - if (count != l->num) { - fprintf ( f, - " *** list count is not correct\n" - " *** list id indicates %d, counted items = %d\n", - l->num, count ); - } + if(count != l->num) + fprintf(f, " *** list count is not correct\n" " *** list id indicates %d, counted items = %d\n", + l->num, count); } return 0; diff --git a/src/main.c b/src/main.c index f6ddcf26e..ba0ca0a52 100644 --- a/src/main.c +++ b/src/main.c @@ -18,16 +18,15 @@ */ /* - * Code to program an Atmel AVR device through one of the supported - * programmers. + * Program an Atmel AVR device through one of the supported programmers * - * For parallel port connected programmers, the pin definitions can be - * changed via a config file. See the config file for instructions on - * how to add a programmer definition. + * For parallel port connected programmers, the pin definitions can be changed + * via a config file. See the config file for instructions on how to add a + * programmer definition. * */ -/* For AVRDUDE_FULL_VERSION and possibly others */ +// For AVRDUDE_FULL_VERSION and possibly others #include #include @@ -44,6 +43,7 @@ #include #include #include + #if !defined(WIN32) #include #endif @@ -53,152 +53,162 @@ #include "config.h" #include "developer_opts.h" -char * progname = "avrdude"; +char *progname = "avrdude"; static const char *avrdude_message_type(int msglvl) { switch(msglvl) { - case MSG_EXT_ERROR: return "OS error"; - case MSG_ERROR: return "error"; - case MSG_WARNING: return "warning"; - case MSG_INFO: return "info"; - case MSG_NOTICE: return "notice"; - case MSG_NOTICE2: return "notice2"; - case MSG_DEBUG: return "debug"; - case MSG_TRACE: return "trace"; - case MSG_TRACE2: return "trace2"; - default: return "unknown msglvl"; + case MSG_EXT_ERROR: + return "OS error"; + case MSG_ERROR: + return "error"; + case MSG_WARNING: + return "warning"; + case MSG_INFO: + return "info"; + case MSG_NOTICE: + return "notice"; + case MSG_NOTICE2: + return "notice2"; + case MSG_DEBUG: + return "debug"; + case MSG_TRACE: + return "trace"; + case MSG_TRACE2: + return "trace2"; + default: + return "unknown msglvl"; } } - /* * Core messaging routine for msg_xyz(), [pli]msg_xyz() and term_out() * See #define lines in avrdude.h of how it is normally called * * Named that way as there used to be a now gone different avrdude_message() */ -int avrdude_message2(FILE *fp, int lno, const char *file, const char *func, int msgmode, int msglvl, const char *format, ...) { - int rc = 0; - va_list ap; - - static struct { // Memorise whether last print ended at beginning of line - FILE *fp; - int bol; // Are we at the beginning of a line for this fp stream? - } bols[5+1]; // Cater for up to 5 different FILE pointers plus one catch-all - - size_t bi = 0; // bi is index to bols[] array - for(bi=0; bi < sizeof bols/sizeof*bols -1; bi++) { // Note the -1, so bi is valid after loop - if(!bols[bi].fp) { // First free space - bols[bi].fp = fp; // Insert fp in first free space - bols[bi].bol = 1; // Assume beginning of line on first use - } - if(bols[bi].fp == fp) - break; +int avrdude_message2(FILE *fp, int lno, const char *file, const char *func, + int msgmode, int msglvl, const char *format, ...) { + + int rc = 0; + va_list ap; + + static struct { // Memorise whether last print ended at beginning of line + FILE *fp; + int bol; // Are we at the beginning of a line for this fp stream? + } bols[5 + 1]; // Cater for up to 5 different FILE pointers plus one catch-all + + size_t bi = 0; // bi is index to bols[] array + + for(bi = 0; bi < sizeof bols/sizeof *bols - 1; bi++) { // Note the -1, so bi is valid after loop + if(!bols[bi].fp) { // First free space + bols[bi].fp = fp; // Insert fp in first free space + bols[bi].bol = 1; // Assume beginning of line on first use } + if(bols[bi].fp == fp) + break; + } - if(msglvl <= MSG_ERROR) // Serious error? Free progress bars (if any) - report_progress(1, -1, NULL); + if(msglvl <= MSG_ERROR) // Serious error? Free progress bars (if any) + report_progress(1, -1, NULL); - if(msgmode & MSG2_FLUSH) { - fflush(stdout); - fflush(stderr); + if(msgmode & MSG2_FLUSH) { + fflush(stdout); + fflush(stderr); + } + // Reduce effective verbosity level by number of -q above one when printing to stderr + if((quell_progress < 2 || fp != stderr? verbose: verbose + 1 - quell_progress) >= msglvl) { + if(msgmode & MSG2_LEFT_MARGIN && !bols[bi].bol) { + fprintf(fp, "\n"); + bols[bi].bol = 1; + } + // Keep vertical tab at start of format string as conditional new line + if(*format == '\v') { + format++; + if(!bols[bi].bol) { + fprintf(fp, "\n"); + bols[bi].bol = 1; + } } - // Reduce effective verbosity level by number of -q above one when printing to stderr - if ((quell_progress < 2 || fp != stderr? verbose: verbose+1-quell_progress) >= msglvl) { - if(msgmode & MSG2_LEFT_MARGIN && !bols[bi].bol) { - fprintf(fp, "\n"); - bols[bi].bol = 1; - } + if(msgmode & (MSG2_PROGNAME | MSG2_TYPE)) { + if(msgmode & MSG2_PROGNAME) { + fprintf(fp, "%s", progname); + bols[bi].bol = 0; + } + if(msgmode & MSG2_TYPE) { + const char *mt = avrdude_message_type(msglvl); - // Keep vertical tab at start of format string as conditional new line - if(*format == '\v') { - format++; - if(!bols[bi].bol) { - fprintf(fp, "\n"); - bols[bi].bol = 1; - } - } + if(bols[bi].bol) + fprintf(fp, "%c%s", msgmode & (MSG2_UCFIRST)? toupper(*mt & 0xff): *mt, mt + 1); + else + fprintf(fp, " %s", mt); + bols[bi].bol = 0; + } + if(verbose >= MSG_NOTICE2) { + const char *bfname = strrchr(file, '/'); // Only print basename - if(msgmode & (MSG2_PROGNAME | MSG2_TYPE)) { - if(msgmode & MSG2_PROGNAME) { - fprintf(fp, "%s", progname); - bols[bi].bol = 0; - } - if(msgmode & MSG2_TYPE) { - const char *mt = avrdude_message_type(msglvl); - if(bols[bi].bol) - fprintf(fp, "%c%s", msgmode & (MSG2_UCFIRST)? toupper(*mt & 0xff): *mt, mt+1); - else - fprintf(fp, " %s", mt); - bols[bi].bol = 0; - } - if(verbose >= MSG_NOTICE2) { - const char *bfname = strrchr(file, '/'); // Only print basename #if defined (WIN32) - if(!bfname) - bfname = strrchr(file, '\\'); + if(!bfname) + bfname = strrchr(file, '\\'); #endif - bfname = bfname? bfname+1: file; - if(msgmode & MSG2_FUNCTION) - fprintf(fp, " %s()", func); - if(msgmode & MSG2_FILELINE) - fprintf(fp, " %s %d", bfname, lno); - } - fprintf(fp, ": "); - } else if(msgmode & MSG2_INDENT1) { - fprintf(fp, "%*s", (int) strlen(progname)+1, ""); - bols[bi].bol = 0; - } else if(msgmode & MSG2_INDENT2) { - fprintf(fp, "%*s", (int) strlen(progname)+2, ""); - bols[bi].bol = 0; - } - // Figure out whether this print will leave us at beginning of line + bfname = bfname? bfname + 1: file; + if(msgmode & MSG2_FUNCTION) + fprintf(fp, " %s()", func); + if(msgmode & MSG2_FILELINE) + fprintf(fp, " %s %d", bfname, lno); + } + fprintf(fp, ": "); + } else if(msgmode & MSG2_INDENT1) { + fprintf(fp, "%*s", (int) strlen(progname) + 1, ""); + bols[bi].bol = 0; + } else if(msgmode & MSG2_INDENT2) { + fprintf(fp, "%*s", (int) strlen(progname) + 2, ""); + bols[bi].bol = 0; + } + // Figure out whether this print will leave us at beginning of line - // Determine required size first - va_start(ap, format); - rc = vsnprintf(NULL, 0, format, ap); - va_end(ap); + // Determine required size first + va_start(ap, format); + rc = vsnprintf(NULL, 0, format, ap); + va_end(ap); - if(rc < 0) // Some errror? - return 0; + if(rc < 0) // Some errror? + return 0; - rc++; // Accommodate terminating nul - char *p = mmt_malloc(rc); - va_start(ap, format); - rc = vsnprintf(p, rc, format, ap); - va_end(ap); + rc++; // Accommodate terminating nul + char *p = mmt_malloc(rc); - if(rc < 0) { - mmt_free(p); - return 0; - } + va_start(ap, format); + rc = vsnprintf(p, rc, format, ap); + va_end(ap); - if(*p) { // Finally: print! - if(bols[bi].bol && (msgmode & MSG2_UCFIRST)) - fprintf(fp, "%c%s", toupper(*p & 0xff), p+1); - else - fprintf(fp, "%s", p); - bols[bi].bol = p[strlen(p)-1] == '\n'; - } - mmt_free(p); + if(rc < 0) { + mmt_free(p); + return 0; } - if(msgmode & MSG2_FLUSH) - fflush(fp); + if(*p) { // Finally: print! + if(bols[bi].bol && (msgmode & MSG2_UCFIRST)) + fprintf(fp, "%c%s", toupper(*p & 0xff), p + 1); + else + fprintf(fp, "%s", p); + bols[bi].bol = p[strlen(p) - 1] == '\n'; + } + mmt_free(p); + } - return rc; -} + if(msgmode & MSG2_FLUSH) + fflush(fp); + return rc; +} -struct list_walk_cookie -{ - FILE *f; - const char *prefix; +struct list_walk_cookie { + FILE *f; + const char *prefix; }; - libavrdude_context *cx; // Context pointer, eventually the only global variable static LISTID updates = NULL; @@ -207,32 +217,25 @@ static LISTID extended_params = NULL; static LISTID additional_config_files = NULL; -static PROGRAMMER * pgm; +static PROGRAMMER *pgm; -/* - * global options - */ +// Global options int verbose; // Verbose output int quell_progress; // Quell progress report and un-verbose output int ovsigck; // 1 = override sig check, 0 = don't const char *partdesc; // Part -p string const char *pgmid; // Programmer -c string -static char usr_config[PATH_MAX]; // Per-user config file +static char usr_config[PATH_MAX]; // Per-user config file -/* - * usage message - */ -static void usage(void) -{ +// Usage message +static void usage(void) { char *home = getenv("HOME"); size_t l = home? strlen(home): 0; char *cfg = home && str_casestarts(usr_config, home)? - mmt_sprintf("~/%s", usr_config+l+(usr_config[l]=='/')): - mmt_sprintf("%s", usr_config); + mmt_sprintf("~/%s", usr_config + l + (usr_config[l] == '/')): mmt_sprintf("%s", usr_config); - msg_error( - "Usage: %s [options]\n" + msg_error("Usage: %s [options]\n" "Options:\n" " -p Specify AVR device; -p ? lists all known parts\n" " -p / Run developer options for matched AVR devices,\n" @@ -273,10 +276,11 @@ static void usage(void) mmt_free(cfg); } - // Potentially shorten copy of prog description if it's the suggested mode static void pmshorten(char *desc, const char *modes) { - struct { const char *end, *mode; } pairs[] = { + struct { + const char *end, *mode; + } pairs[] = { {" in parallel programming mode", "HVPP"}, {" in PP mode", "HVPP"}, {" in high-voltage serial programming mode", "HVSP"}, @@ -294,10 +298,11 @@ static void pmshorten(char *desc, const char *modes) { }; size_t len = strlen(desc); - for(size_t i=0; i elen && str_caseeq(desc+len-elen, pairs[i].end) && str_eq(modes, pairs[i].mode)) { - desc[len-elen] = 0; + + if(len > elen && str_caseeq(desc + len - elen, pairs[i].end) && str_eq(modes, pairs[i].mode)) { + desc[len - elen] = 0; break; } } @@ -307,7 +312,7 @@ static void list_programmers(FILE *f, const char *prefix, LISTID programmers, in LNODEID ln1; LNODEID ln2; PROGRAMMER *pgm; - int maxlen=0, len; + int maxlen = 0, len; sort_programmers(programmers); @@ -316,9 +321,10 @@ static void list_programmers(FILE *f, const char *prefix, LISTID programmers, in pgm = ldata(ln1); if(!is_programmer(pgm)) continue; - for(ln2=lfirst(pgm->id); ln2; ln2=lnext(ln2)) + for(ln2 = lfirst(pgm->id); ln2; ln2 = lnext(ln2)) if(!pm || !pgm->prog_modes || (pm & pgm->prog_modes)) { const char *id = ldata(ln2); + if(*id == 0 || *id == '.') continue; if((len = strlen(id)) > maxlen) @@ -330,7 +336,7 @@ static void list_programmers(FILE *f, const char *prefix, LISTID programmers, in pgm = ldata(ln1); if(!is_programmer(pgm)) continue; - for(ln2=lfirst(pgm->id); ln2; ln2=lnext(ln2)) { + for(ln2 = lfirst(pgm->id); ln2; ln2 = lnext(ln2)) { // List programmer if pm or prog_modes uninitialised or if they are compatible otherwise if(!pm || !pgm->prog_modes || (pm & pgm->prog_modes)) { const char *id = ldata(ln2); @@ -347,7 +353,7 @@ static void list_programmers(FILE *f, const char *prefix, LISTID programmers, in else fprintf(f, "%s%-*s = %-s", prefix, maxlen, id, desc); if(pm != ~0) - fprintf(f, " via %s", modes); + fprintf(f, " via %s", modes); fprintf(f, "\n"); mmt_free(desc); @@ -356,28 +362,25 @@ static void list_programmers(FILE *f, const char *prefix, LISTID programmers, in } } -static void list_programmer_types_callback(const char *name, const char *desc, - void *cookie) -{ - struct list_walk_cookie *c = (struct list_walk_cookie *)cookie; - fprintf(c->f, "%s%-16s = %-s\n", c->prefix, name, desc); +static void list_programmer_types_callback(const char *name, const char *desc, void *cookie) { + struct list_walk_cookie *c = (struct list_walk_cookie *) cookie; + + fprintf(c->f, "%s%-16s = %-s\n", c->prefix, name, desc); } -static void list_programmer_types(FILE * f, const char *prefix) -{ - struct list_walk_cookie c; +static void list_programmer_types(FILE *f, const char *prefix) { + struct list_walk_cookie c; - c.f = f; - c.prefix = prefix; + c.f = f; + c.prefix = prefix; - walk_programmer_types(list_programmer_types_callback, &c); + walk_programmer_types(list_programmer_types_callback, &c); } - static void list_parts(FILE *f, const char *prefix, LISTID avrparts, int pm) { LNODEID ln1; AVRPART *p; - int maxlen=0, len; + int maxlen = 0, len; sort_avrparts(avrparts); @@ -386,7 +389,7 @@ static void list_parts(FILE *f, const char *prefix, LISTID avrparts, int pm) { p = ldata(ln1); // List part if pm or prog_modes uninitialised or if they are compatible otherwise if(!pm || !p->prog_modes || (pm & p->prog_modes)) { - if(verbose < MSG_NOTICE2 && p->id[0] == '.') // hide ids starting with '.' + if(verbose < MSG_NOTICE2 && p->id[0] == '.') // Hide ids starting with '.' continue; if((len = strlen(p->id)) > maxlen) maxlen = len; @@ -397,7 +400,7 @@ static void list_parts(FILE *f, const char *prefix, LISTID avrparts, int pm) { p = ldata(ln1); // List part if pm or prog_modes uninitialised or if they are compatible otherwise if(!pm || !p->prog_modes || (pm & p->prog_modes)) { - if(verbose < MSG_NOTICE2 && p->id[0] == '.') // hide ids starting with '.' + if(verbose < MSG_NOTICE2 && p->id[0] == '.') // Hide ids starting with '.' continue; if(verbose > 0) fprintf(f, "%s%-*s = %-18s [%s:%d]", prefix, maxlen, p->id, p->desc, p->config_file, p->lineno); @@ -413,35 +416,32 @@ static void list_parts(FILE *f, const char *prefix, LISTID avrparts, int pm) { } } -static void exithook(void) -{ - if (pgm->teardown) - pgm->teardown(pgm); +static void exithook(void) { + if(pgm->teardown) + pgm->teardown(pgm); } -static void cleanup_main(void) -{ - if (updates) { - ldestroy_cb(updates, (void(*)(void*)) free_update); - updates = NULL; - } - if (extended_params) { - ldestroy(extended_params); - extended_params = NULL; - } - if (additional_config_files) { - ldestroy(additional_config_files); - additional_config_files = NULL; - } +static void cleanup_main(void) { + if(updates) { + ldestroy_cb(updates, (void (*)(void *)) free_update); + updates = NULL; + } + if(extended_params) { + ldestroy(extended_params); + extended_params = NULL; + } + if(additional_config_files) { + ldestroy(additional_config_files); + additional_config_files = NULL; + } - cleanup_config(); + cleanup_config(); } -static void replace_backslashes(char *s) -{ +static void replace_backslashes(char *s) { // Replace all backslashes with forward slashes - for (size_t i = 0; i < strlen(s); i++) { - if (s[i] == '\\') { + for(size_t i = 0; i < strlen(s); i++) { + if(s[i] == '\\') { s[i] = '/'; } } @@ -449,9 +449,7 @@ static void replace_backslashes(char *s) // Return whether a part/programmer string is a developer option and if so which type static int dev_opt(const char *str) { - return - !str? 0: - str_eq(str, "*") || str_starts(str, "*/s")? 2: // Print PART DEFINITIONS comment as well + return !str? 0: str_eq(str, "*") || str_starts(str, "*/s")? 2: // Print PART DEFINITIONS comment as well strchr(str, '/') && !locate_part(part_list, str); } @@ -463,32 +461,37 @@ typedef struct { } pgm_distance; static int cmp_pgmid(const void *a, const void *b) { - const pgm_distance *pa = a, *pb = b; + const pgm_distance *pa = a, *pb = b; + + int ret = pa->dist - pb->dist; - int ret = pa->dist - pb->dist; - if(ret) - return ret; - return strcmp(pa->pgmid, pb->pgmid); + if(ret) + return ret; + return strcmp(pa->pgmid, pb->pgmid); } static int suggest_programmers(const char *programmer, LISTID programmers) { - const size_t max_distance = 64; // Don't show suggestions if they are way far out + const size_t max_distance = 64; // Don't show suggestions if they are way far out int nid = 0; // Number of possible programmer ids + for(LNODEID ln1 = lfirst(programmers); ln1; ln1 = lnext(ln1)) { PROGRAMMER *pgm = ldata(ln1); + if(is_programmer(pgm)) for(LNODEID ln2 = lfirst(pgm->id); ln2; ln2 = lnext(ln2)) nid++; } - pgm_distance *d = mmt_malloc(nid*sizeof*d); + pgm_distance *d = mmt_malloc(nid*sizeof *d); // Fill d[] struct int idx = 0; AVRPART *p = locate_part(part_list, partdesc); + for(LNODEID ln1 = lfirst(programmers); ln1; ln1 = lnext(ln1)) { PROGRAMMER *pgm = ldata(ln1); + if(!is_programmer(pgm)) continue; for(LNODEID ln2 = lfirst(pgm->id); ln2; ln2 = lnext(ln2)) { @@ -503,9 +506,11 @@ static int suggest_programmers(const char *programmer, LISTID programmers) { } int n = 0, pgmid_maxlen = 0, comp = 0, len; + if(nid) { // Sort list so programmers according to string distance qsort(d, nid, sizeof(*d), cmp_pgmid); - size_t dst = d[nid > 2? 2: nid-1].dist; + size_t dst = d[nid > 2? 2: nid - 1].dist; + if(dst > max_distance) dst = max_distance; for(; n < nid && d[n].dist <= dst; n++) @@ -545,12 +550,15 @@ static void programmer_not_found(const char *programmer, const PROGRAMMER *pgm, // If there were partial matches then they were not unique: count and list them int pmatches = 0, maxlen = 0, len; - for(LNODEID ln1=lfirst(programmers); ln1; ln1=lnext(ln1)) { + + for(LNODEID ln1 = lfirst(programmers); ln1; ln1 = lnext(ln1)) { PROGRAMMER *pg = ldata(ln1); + if(is_programmer(pg) && (pg->prog_modes & pmode)) - for(LNODEID ln2=lfirst(pg->id); ln2; ln2=lnext(ln2)) { + for(LNODEID ln2 = lfirst(pg->id); ln2; ln2 = lnext(ln2)) { const char *id = (const char *) ldata(ln2); - if(str_casestarts(id, programmer)) { // Partial initial match + + if(str_casestarts(id, programmer)) { // Partial initial match pmatches++; if((len = strlen(id)) > maxlen) maxlen = len; @@ -559,17 +567,20 @@ static void programmer_not_found(const char *programmer, const PROGRAMMER *pgm, } if(pmatches) { pmsg_error("%s is not a unique start of a programmer name; consider:\n", programmer); - for(LNODEID ln1=lfirst(programmers); ln1; ln1=lnext(ln1)) { - PROGRAMMER *pg = ldata(ln1); + for(LNODEID ln1 = lfirst(programmers); ln1; ln1 = lnext(ln1)) { + PROGRAMMER *pg = ldata(ln1); + if(is_programmer(pg) && (pg->prog_modes & pmode)) - for(LNODEID ln2=lfirst(pg->id); ln2; ln2=lnext(ln2)) { + for(LNODEID ln2 = lfirst(pg->id); ln2; ln2 = lnext(ln2)) { const char *id = (const char *) ldata(ln2); + if(str_casestarts(id, programmer)) msg_error(" %-*s = %s\n", maxlen, id, pg->desc); - } + } } } else if(!pgm || !pgm->id || !lsize(pgm->id)) { PROGRAMMER *pg = locate_programmer(programmers, programmer); + if(!pgm && pt && pg && !(pg->prog_modes & pmode)) { pmsg_error("programmer %s and part %s have no programming modes in common\n", programmer, pt->desc); msg_info("use -c? -p %s to see all possible programmers for %s\n", pt->desc, pt->desc); @@ -595,7 +606,6 @@ static void part_not_found(const char *partdesc) { msg_error("\n"); } - #if !defined(WIN32) // Safely concatenate dir/file into dst that has size n static char *concatpath(char *dst, char *dir, char *file, size_t n) { @@ -606,13 +616,13 @@ static char *concatpath(char *dst, char *dir, char *file, size_t n) { size_t len = strlen(dir); // Insufficient space? - if(len + (dir[len-1] != '/') + strlen(file) > n-1) + if(len + (dir[len - 1] != '/') + strlen(file) > n - 1) return NULL; if(dst != dir) strcpy(dst, dir); - if(dst[len-1] != '/') + if(dst[len - 1] != '/') strcat(dst, "/"); strcat(dst, file); @@ -622,46 +632,42 @@ static char *concatpath(char *dst, char *dir, char *file, size_t n) { #endif -/* - * main routine - */ -int main(int argc, char * argv []) -{ - int rc; /* general return code checking */ - int exitrc; /* exit code for main() */ - int i; /* general loop counter */ - int ch; /* options flag */ - struct avrpart * p; /* which avr part we are programming */ - AVRMEM * sig; /* signature data */ - struct stat sb; - UPDATE * upd; - LNODEID * ln; - - /* options / operating mode variables */ - int erase; /* 1=erase chip, 0=don't */ - int flashread; /* 1=flash is going to be read, 0=no flash reads */ - int calibrate; /* 1=calibrate RC oscillator, 0=don't */ - int no_avrduderc; /* 1=don't load personal conf file */ - char * port; /* device port (/dev/xxx) */ - const char *exitspecs; /* exit specs string from command line */ - int explicit_c; /* 1=explicit -c on command line, 0=not specified there */ - int explicit_e; /* 1=explicit -e on command line, 0=not specified there */ - char sys_config[PATH_MAX]; /* system wide config file */ - char executable_abspath[PATH_MAX]; /* absolute path to avrdude executable */ - char executable_dirpath[PATH_MAX]; /* absolute path to folder with executable */ - bool executable_abspath_found = false; /* absolute path to executable found */ - bool sys_config_found = false; /* 'avrdude.conf' file found */ - char * e; /* for strtod() error checking */ - const char *errstr; /* for str_int() error checking */ - int baudrate; /* override default programmer baud rate */ - int touch_1200bps; /* "touch" serial port prior to programming */ - double bitclock; /* Specify programmer bit clock (JTAG ICE) */ - int ispdelay; /* Specify the delay for ISP clock */ - int init_ok; /* Device initialization worked well */ - int is_open; /* Device open succeeded */ - int ce_delayed; /* Chip erase delayed */ - char * logfile; /* Use logfile rather than stderr for diagnostics */ - enum updateflags uflags = UF_AUTO_ERASE | UF_VERIFY; /* Flags for do_op() */ +int main(int argc, char *argv[]) { + int rc; // General return code checking + int exitrc; // Exit code for main() + int i; // General loop counter + int ch; // Options flag + struct avrpart *p; // Which avr part we are programming + AVRMEM *sig; // Signature data + struct stat sb; + UPDATE *upd; + LNODEID *ln; + + // Options/operating mode variables + int erase; // 1=erase chip, 0=don't + int flashread; // 1=flash is going to be read, 0=no flash reads + int calibrate; // 1=calibrate RC oscillator, 0=don't + int no_avrduderc; // 1=don't load personal conf file + char *port; // Device port (/dev/xxx) + const char *exitspecs; // Exit specs string from command line + int explicit_c; // 1=explicit -c on command line, 0=not specified there + int explicit_e; // 1=explicit -e on command line, 0=not specified there + char sys_config[PATH_MAX]; // System wide config file + char executable_abspath[PATH_MAX]; // Absolute path to avrdude executable + char executable_dirpath[PATH_MAX]; // Absolute path to folder with executable + bool executable_abspath_found = false; // Absolute path to executable found + bool sys_config_found = false; // avrdude.conf file found + char *e; // For strtod() error checking + const char *errstr; // For str_int() error checking + int baudrate; // Override default programmer baud rate + int touch_1200bps; // Touch serial port prior to programming + double bitclock; // Specify programmer bit clock (JTAG ICE) + int ispdelay; // Specify the delay for ISP clock + int init_ok; // Device initialization worked well + int is_open; // Device open succeeded + int ce_delayed; // Chip erase delayed + char *logfile; // Use logfile rather than stderr for diagnostics + enum updateflags uflags = UF_AUTO_ERASE | UF_VERIFY; // Flags for do_op() init_cx(NULL); @@ -669,100 +675,98 @@ int main(int argc, char * argv []) _set_printf_count_output(1); #endif - /* - * Set line buffering for file descriptors so we see stdout and stderr - * properly interleaved. - */ - setvbuf(stdout, (char*)NULL, _IOLBF, 0); - setvbuf(stderr, (char*)NULL, _IOLBF, 0); + // Set line buffering for file descriptors so we see stdout and stderr properly interleaved + setvbuf(stdout, (char *) NULL, _IOLBF, 0); + setvbuf(stderr, (char *) NULL, _IOLBF, 0); sys_config[0] = '\0'; progname = strrchr(argv[0], '/'); #if defined (WIN32) - /* take care of backslash as dir sep in W32 */ - if (!progname) + // Take care of backslash as dir sep in W32 + if(!progname) progname = strrchr(argv[0], '\\'); -#endif /* WIN32 */ +#endif // WIN32 - if (progname) + if(progname) progname++; else progname = argv[0]; // Remove trailing .exe if(str_ends(progname, ".exe")) { - progname = mmt_strdup(progname); // Don't write to argv[0] - progname[strlen(progname)-4] = 0; + progname = mmt_strdup(progname); // Don't write to argv[0] + progname[strlen(progname) - 4] = 0; } avrdude_conf_version = ""; default_programmer = ""; - default_parallel = ""; - default_serial = ""; - default_spi = ""; - default_baudrate = 0; - default_bitclock = 0.0; - default_linuxgpio = ""; - allow_subshells = 0; + default_parallel = ""; + default_serial = ""; + default_spi = ""; + default_baudrate = 0; + default_bitclock = 0.0; + default_linuxgpio = ""; + allow_subshells = 0; init_config(); atexit(cleanup_main); msg_debug("$ "); // Record command line when debugging - for(int i=0; iavr_disableffopt = 1; - break; - - case 'e': /* perform a chip erase */ - erase = 1; - explicit_e = 1; - uflags &= ~UF_AUTO_ERASE; - break; - - case 'E': - exitspecs = optarg; - break; - - case 'F': /* override invalid signature check */ - ovsigck = 1; - break; - - case 'l': - logfile = optarg; - break; - - case 'n': - uflags |= UF_NOWRITE; - break; - - case 'N': - no_avrduderc = 1; - break; - - case 'O': /* perform RC oscillator calibration */ - calibrate = 1; - break; - - case 'p': /* specify AVR part */ - partdesc = optarg; - break; - - case 'P': - port = mmt_strdup(optarg); - break; - - case 'q': /* Quell progress output */ - quell_progress++ ; - break; - - case 'r' : - touch_1200bps++; - break; - - case 't': /* enter terminal mode */ - ladd(updates, cmd_update("interactive terminal")); - break; - - case 'T': - ladd(updates, cmd_update(optarg)); - break; - - case 'U': - upd = parse_op(optarg); - if (upd == NULL) { - pmsg_error("unable to parse update operation %s\n", optarg); - exit(1); - } - ladd(updates, upd); - break; + case 'C': // System wide configuration file + if(optarg[0] == '+') { + ladd(additional_config_files, optarg + 1); + } else { + strncpy(sys_config, optarg, PATH_MAX); + sys_config[PATH_MAX - 1] = 0; + } + break; - case 'v': - verbose++; - break; + case 'D': // Disable auto-erase + uflags &= ~UF_AUTO_ERASE; + // Fall through - case 'V': - uflags &= ~UF_VERIFY; - break; + case 'A': // Explicit disabling of trailing-0xff removal + cx->avr_disableffopt = 1; + break; - case 'x': - ladd(extended_params, optarg); - break; + case 'e': // Perform a chip erase + erase = 1; + explicit_e = 1; + uflags &= ~UF_AUTO_ERASE; + break; - case '?': /* help */ - usage(); - exit(0); - break; + case 'E': + exitspecs = optarg; + break; - default: - pmsg_error("invalid option -%c\n\n", ch); - usage(); + case 'F': // Override invalid signature check + ovsigck = 1; + break; + + case 'l': + logfile = optarg; + break; + + case 'n': + uflags |= UF_NOWRITE; + break; + + case 'N': + no_avrduderc = 1; + break; + + case 'O': // Perform RC oscillator calibration + calibrate = 1; + break; + + case 'p': // Specify AVR part + partdesc = optarg; + break; + + case 'P': + port = mmt_strdup(optarg); + break; + + case 'q': // Quell progress output + quell_progress++; + break; + + case 'r': + touch_1200bps++; + break; + + case 't': // Enter terminal mode + ladd(updates, cmd_update("interactive terminal")); + break; + + case 'T': + ladd(updates, cmd_update(optarg)); + break; + + case 'U': + upd = parse_op(optarg); + if(upd == NULL) { + pmsg_error("unable to parse update operation %s\n", optarg); exit(1); - break; - } + } + ladd(updates, upd); + break; - } + case 'v': + verbose++; + break; + + case 'V': + uflags &= ~UF_VERIFY; + break; + case 'x': + ladd(extended_params, optarg); + break; + case '?': // Help + usage(); + exit(0); + break; + + default: + pmsg_error("invalid option -%c\n\n", ch); + usage(); + exit(1); + break; + } + } - if (logfile != NULL) { + if(logfile != NULL) { FILE *newstderr = freopen(logfile, "w", stderr); - if (newstderr == NULL) { - /* Help! There's no stderr to complain to anymore now. */ + + if(newstderr == NULL) { + // Help! There's no stderr to complain to anymore now printf("Cannot create logfile %s: %s\n", logfile, strerror(errno)); return 1; } } size_t ztest; + if(1 != sscanf("42", "%zi", &ztest) || ztest != 42) pmsg_warning("linked C library does not conform to C99; %s may not work as expected\n", progname); - /* search for system configuration file unless -C conffile was given */ - if (strlen(sys_config) == 0) { + // Search for system configuration file unless -C conffile was given + if(strlen(sys_config) == 0) { /* - * EXECUTABLE ABSPATH - * ------------------ - * Determine the absolute path to avrdude executable. This will be used to - * locate the 'avrdude.conf' file later. + * Executable abspath: Determine the absolute path to avrdude executable. + * This will be used to locate the avrdude.conf file later. */ int executable_dirpath_len; - int executable_abspath_len = wai_getExecutablePath( - executable_abspath, + int executable_abspath_len = wai_getExecutablePath(executable_abspath, PATH_MAX, - &executable_dirpath_len - ); - if ( - (executable_abspath_len != -1) && - (executable_abspath_len != 0) && - (executable_dirpath_len != -1) && - (executable_dirpath_len != 0) - ) { + &executable_dirpath_len); + + if( + (executable_abspath_len != -1) && + (executable_abspath_len != 0) && (executable_dirpath_len != -1) && (executable_dirpath_len != 0) + ) { // All requirements satisfied, executable path was found executable_abspath_found = true; @@ -977,8 +972,7 @@ int main(int argc, char * argv []) replace_backslashes(executable_abspath); - // Define 'executable_dirpath' to be the path to the parent folder of the - // executable. + // Define executable_dirpath to be the path to the parent folder of the executable strcpy(executable_dirpath, executable_abspath); executable_dirpath[executable_dirpath_len] = '\0'; @@ -990,95 +984,95 @@ int main(int argc, char * argv []) } /* - * SYSTEM CONFIG + * System config * ------------- - * Determine the location of 'avrdude.conf'. Check in this order: + * Determine the location of avrdude.conf. Check in this order: * 1. /../etc/avrdude.conf * 2. /avrdude.conf * 3. CONFIG_DIR/avrdude.conf * * When found, write the result into the 'sys_config' variable. */ - if (executable_abspath_found) { + if(executable_abspath_found) { // 1. Check /../etc/avrdude.conf strcpy(sys_config, executable_dirpath); sys_config[PATH_MAX - 1] = '\0'; i = strlen(sys_config); - if (i && (sys_config[i - 1] != '/')) + if(i && (sys_config[i - 1] != '/')) strcat(sys_config, "/"); strcat(sys_config, "../etc/" SYSTEM_CONF_FILE); sys_config[PATH_MAX - 1] = '\0'; - if (access(sys_config, F_OK) == 0) { + if(access(sys_config, F_OK) == 0) { sys_config_found = true; - } - else { + } else { // 2. Check /avrdude.conf strcpy(sys_config, executable_dirpath); sys_config[PATH_MAX - 1] = '\0'; i = strlen(sys_config); - if (i && (sys_config[i - 1] != '/')) + if(i && (sys_config[i - 1] != '/')) strcat(sys_config, "/"); strcat(sys_config, SYSTEM_CONF_FILE); sys_config[PATH_MAX - 1] = '\0'; - if (access(sys_config, F_OK) == 0) { + if(access(sys_config, F_OK) == 0) { sys_config_found = true; } } } - if (!sys_config_found) { + if(!sys_config_found) { // 3. Check CONFIG_DIR/avrdude.conf + #if defined(WIN32) win_set_path(sys_config, sizeof sys_config, SYSTEM_CONF_FILE); #else strcpy(sys_config, CONFIG_DIR); i = strlen(sys_config); - if (i && (sys_config[i - 1] != '/')) + if(i && (sys_config[i - 1] != '/')) strcat(sys_config, "/"); strcat(sys_config, SYSTEM_CONF_FILE); #endif - if (access(sys_config, F_OK) == 0) { + + if(access(sys_config, F_OK) == 0) { sys_config_found = true; } } } // Debug output msg_trace2("sys_config = %s\n", sys_config); - msg_trace2("sys_config_found = %s\n", sys_config_found ? "true" : "false"); + msg_trace2("sys_config_found = %s\n", sys_config_found? "true": "false"); msg_trace2("\n"); - if (quell_progress == 0) + if(quell_progress == 0) terminal_setup_update_progress(); - /* - * Print out an identifying string so folks can tell what version - * they are running - */ + // Print out an identifying string so folks can tell what version they are running pmsg_notice("%s version %s\n", progname, AVRDUDE_FULL_VERSION); pmsg_notice("Copyright see https://github.com/avrdudes/avrdude/blob/main/AUTHORS\n\n"); if(*sys_config) { char *real_sys_config = realpath(sys_config, NULL); + if(real_sys_config) { - pmsg_notice("system wide configuration file is %s\n", real_sys_config); + pmsg_notice("system wide configuration file is %s\n", real_sys_config); } else pmsg_warning("cannot determine realpath() of config file %s: %s\n", sys_config, strerror(errno)); rc = read_config(real_sys_config); - if (rc) { + if(rc) { pmsg_error("unable to process system wide configuration file %s\n", real_sys_config); exit(1); } mmt_free(real_sys_config); } - if (usr_config[0] != 0 && !no_avrduderc) { + if(usr_config[0] != 0 && !no_avrduderc) { int ok = (rc = stat(usr_config, &sb)) >= 0 && (sb.st_mode & S_IFREG); + pmsg_notice("user configuration file %s%s%s\n", ok? "is ": "", usr_config, - rc<0? " does not exist": !(sb.st_mode & S_IFREG)? " is not a regular file, skipping": ""); + rc < 0? " does not exist": !(sb.st_mode & S_IFREG)? " is not a regular file, skipping": ""); if(ok) { rc = read_config(usr_config); - if (rc) { + if(rc) { pmsg_error("unable to process user configuration file %s\n", usr_config); exit(1); } @@ -1090,16 +1084,16 @@ int main(int argc, char * argv []) imsg_warning("does not match Avrdude build version (%s)\n", AVRDUDE_FULL_VERSION); } - if (lsize(additional_config_files) > 0) { + if(lsize(additional_config_files) > 0) { LNODEID ln1; - const char * p = NULL; + const char *p = NULL; - for (ln1=lfirst(additional_config_files); ln1; ln1=lnext(ln1)) { + for(ln1 = lfirst(additional_config_files); ln1; ln1 = lnext(ln1)) { p = ldata(ln1); pmsg_notice("additional configuration file is %s\n", p); rc = read_config(p); - if (rc) { + if(rc) { pmsg_error("unable to process additional configuration file %s\n", p); exit(1); } @@ -1111,8 +1105,8 @@ int main(int argc, char * argv []) if((p = ldata(ln1))->mem) lsort(p->mem, avr_mem_cmp); - // set bitclock from configuration files unless changed by command line - if (default_bitclock > 0 && bitclock == 0.0) { + // Set bitclock from configuration files unless changed by command line + if(default_bitclock > 0 && bitclock == 0.0) { bitclock = default_bitclock; } @@ -1120,8 +1114,8 @@ int main(int argc, char * argv []) pgmid = cache_string(default_programmer); // Developer options to print parts and/or programmer entries of avrdude.conf - int dev_opt_c = dev_opt(pgmid); // -c /[duASsrtiBUPTIJWHQ] - int dev_opt_p = dev_opt(partdesc); // -p /[cdoASsrw*tiBUPTIJWHQ] + int dev_opt_c = dev_opt(pgmid); // -c /[duASsrtiBUPTIJWHQ] + int dev_opt_p = dev_opt(partdesc); // -p /[cdoASsrw*tiBUPTIJWHQ] if(dev_opt_c || dev_opt_p) { // See -c/h and or -p/h dev_output_pgm_part(dev_opt_c, pgmid, dev_opt_p, partdesc); @@ -1129,15 +1123,19 @@ int main(int argc, char * argv []) } PROGRAMMER *dry = locate_programmer(programmers, "dryrun"); + for(LNODEID ln1 = lfirst(part_list); ln1; ln1 = lnext(ln1)) { AVRPART *p = ldata(ln1); + for(LNODEID ln2 = lfirst(programmers); ln2; ln2 = lnext(ln2)) { PROGRAMMER *pgm = ldata(ln2); + if(!is_programmer(pgm)) continue; const char *pnam = pgm->id? ldata(lfirst(pgm->id)): "???"; int pm = pgm->prog_modes & p->prog_modes; - if((pm & (pm-1)) && !str_eq(pnam, "dryrun") && !(dry && pgm->initpgm == dry->initpgm)) + + if((pm & (pm - 1)) && !str_eq(pnam, "dryrun") && !(dry && pgm->initpgm == dry->initpgm)) pmsg_warning("%s and %s share multiple modes (%s)\n", pnam, p->desc, avr_prog_modes(pm)); } } @@ -1157,6 +1155,7 @@ int main(int argc, char * argv []) if(str_eq(partdesc, "?")) { if(pgmid && *pgmid && explicit_c) { PROGRAMMER *pgm = locate_programmer_starts_set(programmers, pgmid, &pgmid, NULL); + if(!pgm || !is_programmer(pgm)) { programmer_not_found(pgmid, pgm, NULL); exit(1); @@ -1176,13 +1175,14 @@ int main(int argc, char * argv []) if(str_eq(pgmid, "?")) { if(partdesc && *partdesc) { AVRPART *p = locate_part(part_list, partdesc); + if(!p) { part_not_found(partdesc); exit(1); } msg_error("\nValid programmers for part %s are:\n", p->desc); list_programmers(stderr, " ", programmers, p->prog_modes); - } else { + } else { msg_error("\nValid programmers are:\n"); list_programmers(stderr, " ", programmers, ~0); } @@ -1205,9 +1205,9 @@ int main(int argc, char * argv []) exit(1); } - p = partdesc && *partdesc? locate_part(part_list, partdesc): NULL; + p = partdesc && *partdesc? locate_part(part_list, partdesc): NULL; pgm = locate_programmer_starts_set(programmers, pgmid, &pgmid, p); - if (pgm == NULL || !is_programmer(pgm)) { + if(pgm == NULL || !is_programmer(pgm)) { programmer_not_found(pgmid, pgm, p); exit(1); } @@ -1220,7 +1220,7 @@ int main(int argc, char * argv []) } } - if (pgm->initpgm) { + if(pgm->initpgm) { pgm->initpgm(pgm); } else { msg_error("\n"); @@ -1228,27 +1228,28 @@ int main(int argc, char * argv []) exit(1); } - if (pgm->setup) { + if(pgm->setup) { pgm->setup(pgm); } - if (pgm->teardown) { + if(pgm->teardown) { atexit(exithook); } - if (lsize(extended_params) > 0) { - if (pgm->parseextparams == NULL) { - for (LNODEID ln = lfirst(extended_params); ln; ln = lnext(ln)) { + if(lsize(extended_params) > 0) { + if(pgm->parseextparams == NULL) { + for(LNODEID ln = lfirst(extended_params); ln; ln = lnext(ln)) { const char *extended_param = ldata(ln); - if (str_eq(extended_param, "help")) { + + if(str_eq(extended_param, "help")) { msg_error("%s -c %s extended options:\n", progname, pgmid); msg_error(" -x help Show this help menu and exit\n"); exit(0); - } - else + } else pmsg_error("programmer does not support extended parameter -x %s, option ignored\n", extended_param); } } else { int rc = pgm->parseextparams(pgm, extended_params); + if(rc == LIBAVRDUDE_EXIT) exit(0); if(rc < 0) { @@ -1258,41 +1259,43 @@ int main(int argc, char * argv []) } } - if (port == NULL) { - switch (pgm->conntype) - { - case CONNTYPE_PARALLEL: - port = mmt_strdup(default_parallel); - break; + if(port == NULL) { + switch(pgm->conntype) { + case CONNTYPE_PARALLEL: + port = mmt_strdup(default_parallel); + break; + + case CONNTYPE_SERIAL: + port = mmt_strdup(default_serial); + break; - case CONNTYPE_SERIAL: - port = mmt_strdup(default_serial); - break; + case CONNTYPE_USB: + port = mmt_strdup(DEFAULT_USB); + break; - case CONNTYPE_USB: - port = mmt_strdup(DEFAULT_USB); - break; + case CONNTYPE_SPI: - case CONNTYPE_SPI: #ifdef HAVE_LINUXSPI - port = mmt_strdup(*default_spi? default_spi: "unknown"); + port = mmt_strdup(*default_spi? default_spi: "unknown"); #else - port = mmt_strdup("unknown"); + port = mmt_strdup("unknown"); #endif - break; - case CONNTYPE_LINUXGPIO: - port = mmt_strdup(default_linuxgpio); - break; + break; - default: - port = mmt_strdup("unknown"); - break; + case CONNTYPE_LINUXGPIO: + port = mmt_strdup(default_linuxgpio); + break; + + default: + port = mmt_strdup("unknown"); + break; } } int is_dryrun = str_eq(pgm->type, "dryrun") || (dry && pgm->initpgm == dry->initpgm); + if((port[0] == 0 || str_eq(port, "unknown")) && !is_dryrun) { msg_error("\n"); pmsg_error("no port has been specified on the command line or in the config file;\n"); @@ -1310,12 +1313,15 @@ int main(int argc, char * argv []) */ bool print_ports = true; SERIALADAPTER *ser = NULL; - if (pgm->conntype == CONNTYPE_SERIAL) { + + if(pgm->conntype == CONNTYPE_SERIAL) { char *portdup = mmt_strdup(port); char *port_tok[4], *tok = portdup; + for(int t = 0, maxt = str_starts(portdup, DEFAULT_USB ":")? 4: 2; t < 4; t++) { char *save = tok && t < maxt? tok: ""; - if(t < maxt-1 && tok && (tok = strchr(tok, ':'))) + + if(t < maxt - 1 && tok && (tok = strchr(tok, ':'))) *tok++ = 0; port_tok[t] = mmt_strdup(save); } @@ -1323,18 +1329,19 @@ int main(int argc, char * argv []) // Use libserialport to find the actual serial port ser = locate_programmer(programmers, port_tok[0]); - if (is_serialadapter(ser)) { + if(is_serialadapter(ser)) { + #ifdef HAVE_LIBSERIALPORT int rv = setport_from_serialadapter(&port, ser, port_tok[1]); - if (rv == -1) { + + if(rv == -1) { pmsg_warning("serial adapter %s", port_tok[0]); - if (port_tok[1][0]) + if(port_tok[1][0]) msg_warning(" with serial number %s", port_tok[1]); - else if (ser->usbsn && ser->usbsn[0]) + else if(ser->usbsn && ser->usbsn[0]) msg_warning(" with serial number %s", ser->usbsn); msg_warning(" not connected to host\n"); - } - else if (rv == -2) + } else if(rv == -2) print_ports = false; if(rv) ser = NULL; @@ -1342,72 +1349,70 @@ int main(int argc, char * argv []) } else if(str_eq(port_tok[0], DEFAULT_USB)) { // Port or usb:[vid]:[pid] int vid, pid; - if (sscanf(port_tok[1], "%x", &vid) > 0 && sscanf(port_tok[2], "%x", &pid) > 0) { + + if(sscanf(port_tok[1], "%x", &vid) > 0 && sscanf(port_tok[2], "%x", &pid) > 0) { int rv = setport_from_vid_pid(&port, vid, pid, port_tok[3]); - if (rv == -1) { - if (port_tok[3][0]) - pmsg_warning("serial adapter with USB VID %s and PID %s and serial number %s not connected\n", port_tok[1], port_tok[2], port_tok[3]); + + if(rv == -1) { + if(port_tok[3][0]) + pmsg_warning("serial adapter with USB VID %s and PID %s and serial number %s not connected\n", port_tok[1], + port_tok[2], port_tok[3]); else pmsg_warning("serial adapter with USB VID %s and PID %s not connected\n", port_tok[1], port_tok[2]); - } - else if (rv == -2) + } else if(rv == -2) print_ports = false; } } - for (int i = 0; i < 4; i++) + for(int i = 0; i < 4; i++) mmt_free(port_tok[i]); if(touch_1200bps && touch_serialport(&port, 1200, touch_1200bps) < 0) goto skipopen; } - // Open the programmer - if (verbose > 0) { + if(verbose > 0) { if(!is_dryrun) pmsg_notice("using port : %s\n", port); pmsg_notice("using programmer : %s\n", pgmid); } - if (baudrate && !pgm->baudrate && !default_baudrate) { // none set - pmsg_notice("setting baud rate : %d\n", baudrate); - pgm->baudrate = baudrate; - } - else if (baudrate && ((pgm->baudrate && pgm->baudrate != baudrate) - || (!pgm->baudrate && default_baudrate != baudrate))) { + if(baudrate && !pgm->baudrate && !default_baudrate) { // None set + pmsg_notice("setting baud rate : %d\n", baudrate); + pgm->baudrate = baudrate; + } else if(baudrate && ((pgm->baudrate && pgm->baudrate != baudrate) + || (!pgm->baudrate && default_baudrate != baudrate))) { pmsg_notice("overriding baud rate : %d\n", baudrate); pgm->baudrate = baudrate; - } - else if (!pgm->baudrate && default_baudrate) { + } else if(!pgm->baudrate && default_baudrate) { pmsg_notice("default baud rate : %d\n", default_baudrate); pgm->baudrate = default_baudrate; - } - else if (ser && ser->baudrate) { + } else if(ser && ser->baudrate) { pmsg_notice("serial baud rate : %d\n", ser->baudrate); pgm->baudrate = ser->baudrate; - } - else if (pgm->baudrate != 0) + } else if(pgm->baudrate != 0) pmsg_notice("programmer baud rate : %d\n", pgm->baudrate); - if (bitclock != 0.0) { + if(bitclock != 0.0) { pmsg_notice("setting bit clk period: %.1f us\n", bitclock); - pgm->bitclock = bitclock * 1e-6; + pgm->bitclock = bitclock*1e-6; } - if (ispdelay != 0) { + if(ispdelay != 0) { pmsg_notice("setting ISP clk delay : %3i us\n", ispdelay); pgm->ispdelay = ispdelay; } rc = pgm->open(pgm, port); - if (rc < 0) { + if(rc < 0) { if(rc == LIBAVRDUDE_EXIT) { exitrc = 0; goto main_exit; } pmsg_error("unable to open port %s for programmer %s\n", port, pgmid); -skipopen: - if (print_ports && pgm->conntype == CONNTYPE_SERIAL) { + skipopen: + if(print_ports && pgm->conntype == CONNTYPE_SERIAL) { + #ifdef HAVE_LIBSERIALPORT list_available_serialports(programmers); if(touch_1200bps == 1) @@ -1415,30 +1420,31 @@ int main(int argc, char * argv []) #endif } exitrc = 1; - pgm->ppidata = 0; /* clear all bits at exit */ + pgm->ppidata = 0; // Clear all bits at exit goto main_exit; } is_open = 1; - if (partdesc == NULL) { + if(partdesc == NULL) { part_not_found(NULL); exitrc = 1; goto main_exit; } p = locate_part(part_list, partdesc); - if (p == NULL) { + if(p == NULL) { part_not_found(partdesc); exitrc = 1; goto main_exit; } - if (exitspecs != NULL) { - if (pgm->parseexitspecs == NULL) { + if(exitspecs != NULL) { + if(pgm->parseexitspecs == NULL) { pmsg_warning("-E option not supported by this programmer type\n"); exitspecs = NULL; } else { int rc = pgm->parseexitspecs(pgm, exitspecs); + if(rc == LIBAVRDUDE_EXIT) exit(0); if(rc < 0) { @@ -1448,7 +1454,7 @@ int main(int argc, char * argv []) } } - if (avr_initmem(p) != 0) { + if(avr_initmem(p) != 0) { msg_error("\n"); pmsg_error("unable to initialize memories\n"); exitrc = 1; @@ -1466,24 +1472,25 @@ int main(int argc, char * argv []) } /* - * Now that we know which part we are going to program, locate any -U - * options using the default memory region, fill in the device-dependent - * default region name ("application" for Xmega parts or "flash" otherwise) - * and check for basic problems with memory names or file access with a - * view to exit before programming. + * Now that we know which part we are going to program, locate any -U options + * using the default memory region, fill in the device-dependent default + * region name ("application" for Xmega parts or "flash" otherwise) and check + * for basic problems with memory names or file access with a view to exit + * before programming. */ int doexit = 0; - for (ln=lfirst(updates); ln; ln=lnext(ln)) { + + for(ln = lfirst(updates); ln; ln = lnext(ln)) { upd = ldata(ln); - if (upd->memstr == NULL && upd->cmdline == NULL) { - const char *mtype = p->prog_modes & PM_PDI? "application": "flash"; + if(upd->memstr == NULL && upd->cmdline == NULL) { + const char *mtype = is_pdi(p)? "application": "flash"; + pmsg_notice2("defaulting memstr in -U %c:%s option to \"%s\"\n", - (upd->op == DEVICE_READ)? 'r': (upd->op == DEVICE_WRITE)? 'w': 'v', - upd->filename, mtype); + (upd->op == DEVICE_READ)? 'r': (upd->op == DEVICE_WRITE)? 'w': 'v', upd->filename, mtype); upd->memstr = mmt_strdup(mtype); } rc = update_dryrun(p, upd); - if (rc && rc != LIBAVRDUDE_SOFTFAIL) + if(rc && rc != LIBAVRDUDE_SOFTFAIL) doexit = 1; } if(doexit) { @@ -1491,19 +1498,16 @@ int main(int argc, char * argv []) goto main_exit; } - if (calibrate) { - /* - * perform an RC oscillator calibration - * as outlined in appnote AVR053 - */ - if (pgm->perform_osccal == 0) { + if(calibrate) { + // Perform an RC oscillator calibration as outlined in appnote AVR053 + if(pgm->perform_osccal == 0) { pmsg_error("programmer does not support RC oscillator calibration\n"); exitrc = 1; } else { pmsg_notice2("performing RC oscillator calibration\n"); exitrc = pgm->perform_osccal(pgm); } - if (exitrc) + if(exitrc) pmsg_error("RC calibration unsuccesful\n"); else pmsg_notice("calibration value is now stored in EEPROM at address 0\n"); @@ -1511,7 +1515,7 @@ int main(int argc, char * argv []) goto main_exit; } - if (verbose > 0 && quell_progress < 2) { + if(verbose > 0 && quell_progress < 2) { avr_display(stderr, pgm, p, progbuf, verbose); msg_notice2("\n"); programmer_display(pgm, progbuf); @@ -1521,25 +1525,21 @@ int main(int argc, char * argv []) exitrc = 0; - /* - * enable the programmer - */ + // Enable the programmer pgm->enable(pgm, p); // Turn off all the status LEDs and reset LED states led_set(pgm, LED_BEG); - /* - * initialize the chip in preparation for accepting commands - */ + // Initialize the chip in preparation for accepting commands init_ok = (rc = pgm->initialize(pgm, p)) >= 0; - if (!init_ok) { + if(!init_ok) { if(rc == LIBAVRDUDE_EXIT) { exitrc = 0; goto main_exit; } pmsg_error("initialization failed (rc = %d)\n", rc); - if (rc == -2) + if(rc == -2) imsg_error(" - the programmer ISP clock is too fast for the target\n"); else imsg_error(" - double check the connections and try again\n"); @@ -1549,10 +1549,10 @@ int main(int argc, char * argv []) else imsg_error(" - use -B to set lower the bit clock frequency, e.g. -B 125kHz\n"); - if (str_starts(pgm->type, "pickit5")) + if(str_starts(pgm->type, "pickit5")) imsg_error(" - reset the programmer by unplugging it"); - if (!ovsigck) { + if(!ovsigck) { imsg_error(" - use -F to override this check\n"); exitrc = 1; goto main_exit; @@ -1566,32 +1566,32 @@ int main(int argc, char * argv []) pmsg_notice("AVR device initialized and ready to accept instructions\n"); /* - * Let's read the signature bytes to make sure there is at least a - * chip on the other end that is responding correctly. A check - * against 0xffffff / 0x000000 should ensure that the signature bytes - * are valid. + * Let's read the signature bytes to make sure there is at least a chip on + * the other end that is responding correctly. A check against + * 0xffffff/0x000000 should ensure that the signature bytes are valid. */ - if(!(p->prog_modes & PM_aWire)) { // not AVR32 + if(!is_awire(p)) { // Not AVR32 int attempt = 0; - int waittime = 10000; /* 10 ms */ + int waittime = 10000; // 10 ms sig_again: usleep(waittime); - if (init_ok) { + if(init_ok) { rc = avr_signature(pgm, p); - if (rc == LIBAVRDUDE_EXIT) { + if(rc == LIBAVRDUDE_EXIT) { exitrc = 0; goto main_exit; } - if (rc != LIBAVRDUDE_SUCCESS) { - if (rc == LIBAVRDUDE_SOFTFAIL && (p->prog_modes & PM_UPDI) && attempt < 1) { + if(rc != LIBAVRDUDE_SUCCESS) { + if(rc == LIBAVRDUDE_SOFTFAIL && is_updi(p) && attempt < 1) { attempt++; - if (pgm->read_sib) { + if(pgm->read_sib) { // Read SIB and compare FamilyID char sib[AVR_SIBLEN + 1]; + pgm->read_sib(pgm, p, sib); pmsg_notice("System Information Block: %s\n", sib); - if (strncmp(p->family_id, sib, AVR_FAMILYIDLEN)) { + if(strncmp(p->family_id, sib, AVR_FAMILYIDLEN)) { pmsg_warning("received FamilyID: \"%.*s\"\n", AVR_FAMILYIDLEN, sib); imsg_warning("expected FamilyID: \"%s\"\n", p->family_id); } else @@ -1599,7 +1599,7 @@ int main(int argc, char * argv []) } if(erase) { erase = 0; - if (uflags & UF_NOWRITE) { + if(uflags & UF_NOWRITE) { pmsg_warning("conflicting -e and -n options specified, NOT erasing chip\n"); } else { pmsg_notice("trying to unlock the chip\n"); @@ -1609,7 +1609,7 @@ int main(int argc, char * argv []) goto sig_again; } } - if (!ovsigck) { + if(!ovsigck) { pmsg_error("double check chip or use -F to override this check\n"); exitrc = 1; goto main_exit; @@ -1625,26 +1625,29 @@ int main(int argc, char * argv []) } sig = avr_locate_signature(p); - if (sig == NULL) + if(sig == NULL) pmsg_warning("signature memory not defined for device %s\n", p->desc); else { const char *mculist = str_ccmcunames_signature(sig->buf, pgm->prog_modes); + if(!*mculist) { // No matching signatures? - if(p->prog_modes & PM_UPDI) { // UPDI parts have different(!) offsets for signature + if(is_updi(p)) { // UPDI parts have different(!) offsets for signature int k, n = 0; // Gather list of known different signature offsets unsigned myoff = sig->offset, offlist[10]; + for(LNODEID ln1 = lfirst(part_list); ln1; ln1 = lnext(ln1)) { AVRMEM *m = avr_locate_signature(ldata(ln1)); + if(m && m->offset != myoff) { - for(k=0; koffset == offlist[k]) break; - if(k == n && k < (int) (sizeof offlist/sizeof*offlist)) + if(k == n && k < (int) (sizeof offlist/sizeof *offlist)) offlist[n++] = m->offset; } } // Now go through the list of other(!) sig offsets and try these - for(k=0; koffset = offlist[k]; if(avr_signature(pgm, p) >= 0) if(*(mculist = str_ccmcunames_signature(sig->buf, pgm->prog_modes))) @@ -1655,28 +1658,30 @@ int main(int argc, char * argv []) } int ff = 1, zz = 1; - for (i=0; isize; i++) { - if (sig->buf[i] != 0xff) + + for(i = 0; i < sig->size; i++) { + if(sig->buf[i] != 0xff) ff = 0; - if (sig->buf[i] != 0x00) + if(sig->buf[i] != 0x00) zz = 0; } bool signature_matches = sig->size >= 3 && !memcmp(sig->buf, p->signature, 3); int showsig = !signature_matches || ff || zz || verbose > 0; + if(showsig) pmsg_info("device signature =%s", str_cchex(sig->buf, sig->size, 1)); if(*mculist && showsig) msg_info(" (%s)", is_dryrun? p->desc: mculist); - if (ff || zz) { // All three bytes are 0xff or all three bytes are 0x00 - if (++attempt < 3) { + if(ff || zz) { // All three bytes are 0xff or all three bytes are 0x00 + if(++attempt < 3) { waittime *= 5; msg_info(" (retrying)\n"); goto sig_again; } msg_info("\n"); pmsg_error("invalid device signature\n"); - if (!ovsigck) { + if(!ovsigck) { pmsg_error("expected signature for %s is%s\n", p->desc, str_cchex(p->signature, 3, 1)); imsg_error(" - double check connections and try again, or use -F to carry on regardless\n"); exitrc = 1; @@ -1686,8 +1691,8 @@ int main(int argc, char * argv []) msg_info("\n"); } - if (!signature_matches) { - if (ovsigck) { + if(!signature_matches) { + if(ovsigck) { pmsg_warning("expected signature for %s is%s\n", p->desc, str_cchex(p->signature, 3, 1)); } else { pmsg_error("expected signature for %s is%s\n", p->desc, str_cchex(p->signature, 3, 1)); @@ -1699,12 +1704,12 @@ int main(int argc, char * argv []) } } - if (uflags & UF_AUTO_ERASE) { + if(uflags & UF_AUTO_ERASE) { if((p->prog_modes & (PM_PDI | PM_UPDI)) && pgm->page_erase && lsize(updates) > 0) { - for(ln=lfirst(updates); ln; ln=lnext(ln)) { + for(ln = lfirst(updates); ln; ln = lnext(ln)) { upd = ldata(ln); if(upd->memstr && upd->op == DEVICE_WRITE && memlist_contains_flash(upd->memstr, p)) { - cx->avr_disableffopt = 1; // Must write full flash file including trailing 0xff + cx->avr_disableffopt = 1; // Must write full flash file including trailing 0xff pmsg_notice("NOT erasing chip as page erase will be used for new flash%s contents;\n", avr_locate_bootrow(p)? "/bootrow": ""); imsg_notice("unprogrammed flash contents remains: use -e for an explicit chip-erase\n"); @@ -1713,14 +1718,13 @@ int main(int argc, char * argv []) } } else { uflags &= ~UF_AUTO_ERASE; - for(ln=lfirst(updates); ln; ln=lnext(ln)) { + for(ln = lfirst(updates); ln; ln = lnext(ln)) { upd = ldata(ln); if(upd->cmdline && *str_ltrim(upd->cmdline) && str_starts("erase", str_ltrim(upd->cmdline))) break; // -T erase already erases the chip: no auto-erase needed - if(upd->cmdline || (upd->memstr && // Might be reading flash? - (upd->op == DEVICE_READ || upd->op == DEVICE_VERIFY) && - memlist_contains_flash(upd->memstr, p))) + if(upd->cmdline || (upd->memstr && // Might be reading flash? + (upd->op == DEVICE_READ || upd->op == DEVICE_VERIFY) && memlist_contains_flash(upd->memstr, p))) flashread = 1; if(upd->memstr && upd->op == DEVICE_WRITE && memlist_contains_flash(upd->memstr, p)) { @@ -1737,12 +1741,12 @@ int main(int argc, char * argv []) } } - if (init_ok && erase) { + if(init_ok && erase) { /* - * erase the chip's flash and eeprom memories, this is required - * before the chip can accept new programming + * Erase the chip's flash and eeprom memories, this is required before the + * chip can accept new programming */ - if (uflags & UF_NOWRITE) { + if(uflags & UF_NOWRITE) { if(explicit_e) pmsg_warning("conflicting -e and -n specified, NOT erasing chip\n"); else @@ -1766,12 +1770,13 @@ int main(int argc, char * argv []) goto main_exit; } - int wrmem = 0, terminal = 0; + if(lsize(updates) <= 1) - uflags |= UF_NOHEADING; - for (ln=lfirst(updates); ln; ln=lnext(ln)) { + uflags |= UF_NOHEADING; + for(ln = lfirst(updates); ln; ln = lnext(ln)) { const AVRMEM *m; + upd = ldata(ln); if(upd->cmdline && wrmem) { // Invalidate cache if device was written to wrmem = 0; @@ -1783,7 +1788,7 @@ int main(int argc, char * argv []) if((uflags & UF_NOWRITE) && upd->cmdline && !terminal++) pmsg_warning("the terminal ignores option -n, that is, it writes to the device\n"); rc = do_op(pgm, p, upd, uflags); - if (rc && rc != LIBAVRDUDE_SOFTFAIL) { + if(rc && rc != LIBAVRDUDE_SOFTFAIL) { exitrc = 1; break; } else if(rc == 0 && upd->op == DEVICE_WRITE && (m = avr_locate_mem(p, upd->memstr)) && mem_is_in_flash(m)) @@ -1798,7 +1803,7 @@ int main(int argc, char * argv []) main_exit: // Program complete - if (is_open) { + if(is_open) { // Clear rdy LED and summarise interaction in err, pgm and vfy LEDs led_set(pgm, LED_END); pgm->powerdown(pgm); @@ -1807,19 +1812,20 @@ int main(int argc, char * argv []) } if(cx->usb_access_error) { - pmsg_info( - "\nUSB access errors detected; this could have many reasons; if it is\n" + pmsg_info("\nUSB access errors detected; this could have many reasons; if it is\n" "USB permission problems, avrdude is likely to work when run as root\n" "but this is not good practice; instead you might want to\n"); + #if 0 && !defined(WIN32) DIR *dir; - if((dir = opendir("/etc/udev/rules.d"))) { // Linux udev land + + if((dir = opendir("/etc/udev/rules.d"))) { // Linux udev land closedir(dir); - imsg_info("run the command below to show udev rules recitifying USB access\n" - "$ %s -c %s/u\n", progname, pgmid); + imsg_info("run the command below to show udev rules recitifying USB access\n" "$ %s -c %s/u\n", progname, pgmid); } else #endif - imsg_info("check out USB port permissions on your OS and set them correctly\n"); + + imsg_info("check out USB port permissions on your OS and set them correctly\n"); } msg_info("\n"); diff --git a/src/micronucleus.c b/src/micronucleus.c index 8bbc596ae..813b3cd7e 100644 --- a/src/micronucleus.c +++ b/src/micronucleus.c @@ -18,23 +18,25 @@ * along with this program. If not, see . */ -// Notes: -// This file adds support for the Micronucleus bootloader V1 and V2, -// so you do no longer need the Micronucleus command-line utility. -// -// This bootloader is typically used on small ATtiny boards, -// such as Digispark (ATtiny85), Digispark Pro (ATtiny167), -// and the respective clones. -// By default, it bootloader uses the VID/PID 16d0:0753 (MCS Digistump). -// -// As the micronucleus bootloader is optimized for size, it implements -// writing to flash memory only. Since it does not support reading, -// use the -V option to prevent avrdude from verifing the flash memory. -// To have avrdude wait for the device to be connected, use the -// extended option '-x wait'. -// -// Example: -// avrdude -c micronucleus -p t85 -x wait -V -U flash:w:main.hex +/* + * Notes: + * This file adds support for the Micronucleus bootloader V1 and V2, + * so you do no longer need the Micronucleus command-line utility. + * + * This bootloader is typically used on small ATtiny boards, + * such as Digispark (ATtiny85), Digispark Pro (ATtiny167), + * and the respective clones. + * By default, it bootloader uses the VID/PID 16d0:0753 (MCS Digistump). + * + * As the micronucleus bootloader is optimized for size, it implements + * writing to flash memory only. Since it does not support reading, + * use the -V option to prevent avrdude from verifing the flash memory. + * To have avrdude wait for the device to be connected, use the + * extended option '-x wait'. + * + * Example: + * avrdude -c micronucleus -p t85 -x wait -V -U flash:w:main.hex + */ #include #include @@ -59,7 +61,7 @@ #error "libusb needs either or " #endif -//----------------------------------------------------------------------------- +// ----------------------------------------------------------------------------- #define MICRONUCLEUS_VID 0x16D0 #define MICRONUCLEUS_PID 0x0753 @@ -75,487 +77,436 @@ #define MICRONUCLEUS_DEFAULT_TIMEOUT 500 #define MICRONUCLEUS_MAX_MAJOR_VERSION 2 -#define PDATA(pgm) ((struct pdata *)(pgm->cookie)) +#define my (*(struct pdata *) (pgm->cookie)) -//----------------------------------------------------------------------------- +// ----------------------------------------------------------------------------- struct pdata { - usb_dev_handle* usb_handle; - // Extended parameters - bool wait_until_device_present; - int wait_timout; // in seconds - // Bootloader version - uint8_t major_version; - uint8_t minor_version; - // Bootloader info (via USB request) - uint16_t flash_size; // programmable size (in bytes) of flash - uint8_t page_size; // size (in bytes) of page - uint8_t write_sleep; // milliseconds - uint8_t signature1; // only used in protocol v2 - uint8_t signature2; // only used in protocol v2 - // Calculated bootloader info - uint16_t pages; // total number of pages to program - uint16_t bootloader_start; // start of the bootloader (at page boundary) - uint16_t erase_sleep; // milliseconds - // State - uint16_t user_reset_vector; // reset vector of user program - bool write_last_page; // last page already programmed - bool start_program; // require start after flash + usb_dev_handle *usb_handle; + // Extended parameters + bool wait_until_device_present; + int wait_timout; // In seconds + // Bootloader version + uint8_t major_version; + uint8_t minor_version; + // Bootloader info (via USB request) + uint16_t flash_size; // Programmable size (in bytes) of flash + uint8_t page_size; // Size (in bytes) of page + uint8_t write_sleep; // Milliseconds + uint8_t signature1; // Only used in protocol v2 + uint8_t signature2; // Only used in protocol v2 + // Calculated bootloader info + uint16_t pages; // Total number of pages to program + uint16_t bootloader_start; // Start of the bootloader (at page boundary) + uint16_t erase_sleep; // Milliseconds + // State + uint16_t user_reset_vector; // Reset vector of user program + bool write_last_page; // Last page already programmed + bool start_program; // Require start after flash }; -//----------------------------------------------------------------------------- +// ----------------------------------------------------------------------------- -static void delay_ms(uint32_t duration) -{ - usleep(duration * 1000); +static void delay_ms(uint32_t duration) { + usleep(duration*1000); } static int micronucleus_check_connection(struct pdata *pdata) { - if (pdata->major_version >= 2) - { - uint8_t buffer[6] = { 0 }; - int result = usb_control_msg( - pdata->usb_handle, - USB_ENDPOINT_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE, - MICRONUCLEUS_CMD_INFO, - 0, 0, - (char*)buffer, sizeof(buffer), - MICRONUCLEUS_DEFAULT_TIMEOUT); - if(result < 0) - cx->usb_access_error = 1; - return result == sizeof(buffer) ? 0 : -1; - } - else - { - uint8_t buffer[4] = { 0 }; - int result = usb_control_msg( - pdata->usb_handle, - USB_ENDPOINT_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE, - MICRONUCLEUS_CMD_INFO, - 0, 0, - (char*)buffer, sizeof(buffer), - MICRONUCLEUS_DEFAULT_TIMEOUT); - if(result < 0) - cx->usb_access_error = 1; - return result == sizeof(buffer) ? 0 : -1; - } + if(pdata->major_version >= 2) { + uint8_t buffer[6] = { 0 }; + int result = usb_control_msg(pdata->usb_handle, + USB_ENDPOINT_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE, + MICRONUCLEUS_CMD_INFO, + 0, 0, + (char *) buffer, sizeof(buffer), + MICRONUCLEUS_DEFAULT_TIMEOUT); + + if(result < 0) + cx->usb_access_error = 1; + return result == sizeof(buffer)? 0: -1; + } else { + uint8_t buffer[4] = { 0 }; + int result = usb_control_msg(pdata->usb_handle, + USB_ENDPOINT_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE, + MICRONUCLEUS_CMD_INFO, + 0, 0, + (char *) buffer, sizeof(buffer), + MICRONUCLEUS_DEFAULT_TIMEOUT); + + if(result < 0) + cx->usb_access_error = 1; + return result == sizeof(buffer)? 0: -1; + } } static bool micronucleus_is_device_responsive(struct pdata *pdata, struct usb_device *device) { - pdata->usb_handle = usb_open(device); - if (pdata->usb_handle == NULL) - { - return false; - } + pdata->usb_handle = usb_open(device); + if(pdata->usb_handle == NULL) { + return false; + } - int result = micronucleus_check_connection(pdata); + int result = micronucleus_check_connection(pdata); - usb_close(pdata->usb_handle); - pdata->usb_handle = NULL; + usb_close(pdata->usb_handle); + pdata->usb_handle = NULL; - return result >= 0; + return result >= 0; } static int micronucleus_reconnect(struct pdata *pdata) { - struct usb_device* device = usb_device(pdata->usb_handle); + struct usb_device *device = usb_device(pdata->usb_handle); - usb_close(pdata->usb_handle); - pdata->usb_handle = NULL; + usb_close(pdata->usb_handle); + pdata->usb_handle = NULL; - for (int i = 0; i < 25; i++) - { - pmsg_notice("trying to reconnect ...\n"); + for(int i = 0; i < 25; i++) { + pmsg_notice("trying to reconnect ...\n"); - pdata->usb_handle = usb_open(device); - if (pdata->usb_handle != NULL) - return 0; + pdata->usb_handle = usb_open(device); + if(pdata->usb_handle != NULL) + return 0; - delay_ms(MICRONUCLEUS_CONNECT_WAIT); - } + delay_ms(MICRONUCLEUS_CONNECT_WAIT); + } - return -1; + return -1; } static int micronucleus_get_bootloader_info_v1(struct pdata *pdata) { - uint8_t buffer[4] = { 0 }; - int result = usb_control_msg( - pdata->usb_handle, - USB_ENDPOINT_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE, - MICRONUCLEUS_CMD_INFO, - 0, 0, - (char*)buffer, sizeof(buffer), - MICRONUCLEUS_DEFAULT_TIMEOUT); - if (result < 0) - { - pmsg_warning("unable to get bootloader info block: %s\n", usb_strerror()); - return result; - } - else if ((size_t) result < sizeof(buffer)) - { - pmsg_warning("received invalid bootloader info block size: %d\n", result); - return -1; - } - - pdata->flash_size = (buffer[0] << 8) | buffer[1]; - pdata->page_size = buffer[2]; - pdata->write_sleep = buffer[3] & 127; - - // Take a wild guess on the part ID, so that we can supply it for device verification - if (pdata->page_size == 128) - { - // ATtiny167 - pdata->signature1 = 0x94; - pdata->signature2 = 0x87; - } - else if (pdata->page_size == 64) - { - if (pdata->flash_size > 4096) - { - // ATtiny85 - pdata->signature1 = 0x93; - pdata->signature2 = 0x0B; - } - else - { - // ATtiny45 - pdata->signature1 = 0x92; - pdata->signature2 = 0x06; - } - } - else if (pdata->page_size == 16) - { - // ATtiny841 - pdata->signature1 = 0x93; - pdata->signature2 = 0x15; - } - else - { - // Unknown device - pdata->signature1 = 0; - pdata->signature2 = 0; - } - - pdata->pages = (pdata->flash_size + pdata->page_size - 1) / pdata->page_size; - pdata->bootloader_start = pdata->pages * pdata->page_size; - pdata->erase_sleep = pdata->write_sleep * pdata->pages; - - return 0; + uint8_t buffer[4] = { 0 }; + int result = usb_control_msg(pdata->usb_handle, + USB_ENDPOINT_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE, + MICRONUCLEUS_CMD_INFO, + 0, 0, + (char *) buffer, sizeof(buffer), + MICRONUCLEUS_DEFAULT_TIMEOUT); + + if(result < 0) { + pmsg_warning("unable to get bootloader info block: %s\n", usb_strerror()); + return result; + } else if((size_t) result < sizeof(buffer)) { + pmsg_warning("received invalid bootloader info block size: %d\n", result); + return -1; + } + + pdata->flash_size = (buffer[0] << 8) | buffer[1]; + pdata->page_size = buffer[2]; + pdata->write_sleep = buffer[3] & 127; + + // Take a wild guess on the part ID, so that we can supply it for device verification + if(pdata->page_size == 128) { + // ATtiny167 + pdata->signature1 = 0x94; + pdata->signature2 = 0x87; + } else if(pdata->page_size == 64) { + if(pdata->flash_size > 4096) { + // ATtiny85 + pdata->signature1 = 0x93; + pdata->signature2 = 0x0B; + } else { + // ATtiny45 + pdata->signature1 = 0x92; + pdata->signature2 = 0x06; + } + } else if(pdata->page_size == 16) { + // ATtiny841 + pdata->signature1 = 0x93; + pdata->signature2 = 0x15; + } else { + // Unknown device + pdata->signature1 = 0; + pdata->signature2 = 0; + } + + pdata->pages = (pdata->flash_size + pdata->page_size - 1)/pdata->page_size; + pdata->bootloader_start = pdata->pages*pdata->page_size; + pdata->erase_sleep = pdata->write_sleep*pdata->pages; + + return 0; } static int micronucleus_get_bootloader_info_v2(struct pdata *pdata) { - uint8_t buffer[6] = { 0 }; - int result = usb_control_msg( - pdata->usb_handle, - USB_ENDPOINT_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE, - MICRONUCLEUS_CMD_INFO, - 0, 0, - (char*)buffer, sizeof(buffer), - MICRONUCLEUS_DEFAULT_TIMEOUT); - if (result < 0) - { - pmsg_warning("unable to get bootloader info block: %s\n", usb_strerror()); - return result; - } - else if ((size_t) result < sizeof(buffer)) - { - pmsg_warning("received invalid bootloader info block size: %d\n", result); - return -1; - } + uint8_t buffer[6] = { 0 }; + int result = usb_control_msg(pdata->usb_handle, + USB_ENDPOINT_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE, + MICRONUCLEUS_CMD_INFO, + 0, 0, + (char *) buffer, sizeof(buffer), + MICRONUCLEUS_DEFAULT_TIMEOUT); + + if(result < 0) { + pmsg_warning("unable to get bootloader info block: %s\n", usb_strerror()); + return result; + } else if((size_t) result < sizeof(buffer)) { + pmsg_warning("received invalid bootloader info block size: %d\n", result); + return -1; + } - pdata->flash_size = (buffer[0] << 8) + buffer[1]; - pdata->page_size = buffer[2]; - pdata->write_sleep = (buffer[3] & 127) + 2; - pdata->signature1 = buffer[4]; - pdata->signature2 = buffer[5]; - - pdata->pages = (pdata->flash_size + pdata->page_size - 1) / pdata->page_size; - pdata->bootloader_start = pdata->pages * pdata->page_size; - pdata->erase_sleep = pdata->write_sleep * pdata->pages; - - // if bit 7 of write sleep time is set, divide the erase time by four to - // accomodate to the 4*page erase of the ATtiny841/441 - if ((buffer[3] & 128) != 0) - { - pdata->erase_sleep /= 4; - } + pdata->flash_size = (buffer[0] << 8) + buffer[1]; + pdata->page_size = buffer[2]; + pdata->write_sleep = (buffer[3] & 127) + 2; + pdata->signature1 = buffer[4]; + pdata->signature2 = buffer[5]; - return 0; + pdata->pages = (pdata->flash_size + pdata->page_size - 1)/pdata->page_size; + pdata->bootloader_start = pdata->pages*pdata->page_size; + pdata->erase_sleep = pdata->write_sleep*pdata->pages; + + /* + * If bit 7 of write sleep time is set, divide the erase time by four to + * accomodate to the 4*page erase of the ATtiny841/441 + */ + if((buffer[3] & 128) != 0) { + pdata->erase_sleep /= 4; + } + + return 0; } static int micronucleus_get_bootloader_info(struct pdata *pdata) { - if (pdata->major_version >= 2) - { - return micronucleus_get_bootloader_info_v2(pdata); - } - else - { - return micronucleus_get_bootloader_info_v1(pdata); - } + if(pdata->major_version >= 2) { + return micronucleus_get_bootloader_info_v2(pdata); + } else { + return micronucleus_get_bootloader_info_v1(pdata); + } } static void micronucleus_dump_device_info(struct pdata *pdata) { - pmsg_notice("Bootloader version: %d.%d\n", pdata->major_version, pdata->minor_version); - imsg_notice("Available flash size: %u\n", pdata->flash_size); - imsg_notice("Page size: %u\n", pdata->page_size); - imsg_notice("Bootloader start: 0x%04X\n", pdata->bootloader_start); - imsg_notice("Write sleep: %ums\n", pdata->write_sleep); - imsg_notice("Erase sleep: %ums\n", pdata->erase_sleep); - imsg_notice("Signature1: 0x%02X\n", pdata->signature1); - imsg_notice("Signature2: 0x%02X\n", pdata->signature2); + pmsg_notice("Bootloader version: %d.%d\n", pdata->major_version, pdata->minor_version); + imsg_notice("Available flash size: %u\n", pdata->flash_size); + imsg_notice("Page size: %u\n", pdata->page_size); + imsg_notice("Bootloader start: 0x%04X\n", pdata->bootloader_start); + imsg_notice("Write sleep: %ums\n", pdata->write_sleep); + imsg_notice("Erase sleep: %ums\n", pdata->erase_sleep); + imsg_notice("Signature1: 0x%02X\n", pdata->signature1); + imsg_notice("Signature2: 0x%02X\n", pdata->signature2); } static int micronucleus_erase_device(struct pdata *pdata) { - pmsg_debug("micronucleus_erase_device()\n"); - - int result = usb_control_msg( - pdata->usb_handle, - USB_ENDPOINT_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE, - MICRONUCLEUS_CMD_ERASE, - 0, 0, - NULL, 0, - MICRONUCLEUS_DEFAULT_TIMEOUT); - if (result < 0) - { - switch (result) - { - case -EIO: - case -EPIPE: - pmsg_notice("ignoring last error of erase command: %s\n", usb_strerror()); - break; - default: - pmsg_warning("erase command failed, code %d: %s\n", result, usb_strerror()); - return result; - } + pmsg_debug("micronucleus_erase_device()\n"); + + int result = usb_control_msg(pdata->usb_handle, + USB_ENDPOINT_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE, + MICRONUCLEUS_CMD_ERASE, + 0, 0, + NULL, 0, + MICRONUCLEUS_DEFAULT_TIMEOUT); + + if(result < 0) { + switch(result) { + case -EIO: + case -EPIPE: + pmsg_notice("ignoring last error of erase command: %s\n", usb_strerror()); + break; + default: + pmsg_warning("erase command failed, code %d: %s\n", result, usb_strerror()); + return result; } + } - delay_ms(pdata->erase_sleep); + delay_ms(pdata->erase_sleep); - result = micronucleus_check_connection(pdata); - if (result < 0) - { - pmsg_notice("connection dropped, trying to reconnect ...\n"); + result = micronucleus_check_connection(pdata); + if(result < 0) { + pmsg_notice("connection dropped, trying to reconnect ...\n"); - result = micronucleus_reconnect(pdata); - if (result < 0) - { - pmsg_warning("unable to reconnect USB device: %s\n", usb_strerror()); - return result; - } + result = micronucleus_reconnect(pdata); + if(result < 0) { + pmsg_warning("unable to reconnect USB device: %s\n", usb_strerror()); + return result; } + } - return 0; + return 0; } static int micronucleus_patch_reset_vector(struct pdata *pdata, uint8_t *buffer) { - // Save user reset vector. - uint16_t word0 = (buffer[1] << 8) | buffer[0]; - uint16_t word1 = (buffer[3] << 8) | buffer[2]; - - if (word0 == 0x940C) - { - // long jump - pdata->user_reset_vector = word1; - } - else if ((word0 & 0xF000) == 0xC000) - { - // rjmp - pdata->user_reset_vector = (word0 & 0x0FFF) + 1; - } - else - { - pmsg_error("the reset vector of the user program does not contain a branch instruction\n"); - return -1; - } + // Save user reset vector. + uint16_t word0 = (buffer[1] << 8) | buffer[0]; + uint16_t word1 = (buffer[3] << 8) | buffer[2]; + + if(word0 == 0x940C) { + // Long jump + pdata->user_reset_vector = word1; + } else if((word0 & 0xF000) == 0xC000) { + // rjmp + pdata->user_reset_vector = (word0 & 0x0FFF) + 1; + } else { + pmsg_error("the reset vector of the user program does not contain a branch instruction\n"); + return -1; + } - // Patch in jmp to bootloader. - if (pdata->bootloader_start > 0x2000) - { - // jmp - uint16_t data = 0x940C; - buffer[0] = (uint8_t)(data >> 0); - buffer[1] = (uint8_t)(data >> 8); - buffer[2] = (uint8_t)(pdata->bootloader_start >> 0); - buffer[3] = (uint8_t)(pdata->bootloader_start >> 8); - } - else - { - // rjmp - uint16_t data = 0xC000 | ((pdata->bootloader_start / 2 - 1) & 0x0FFF); - buffer[0] = (uint8_t)(data >> 0); - buffer[1] = (uint8_t)(data >> 8); - } + // Patch in jmp to bootloader. + if(pdata->bootloader_start > 0x2000) { + // jmp + uint16_t data = 0x940C; - return 0; + buffer[0] = (uint8_t) (data >> 0); + buffer[1] = (uint8_t) (data >> 8); + buffer[2] = (uint8_t) (pdata->bootloader_start >> 0); + buffer[3] = (uint8_t) (pdata->bootloader_start >> 8); + } else { + // rjmp + uint16_t data = 0xC000 | ((pdata->bootloader_start/2 - 1) & 0x0FFF); + + buffer[0] = (uint8_t) (data >> 0); + buffer[1] = (uint8_t) (data >> 8); + } + + return 0; } static void micronucleus_patch_user_vector(struct pdata *pdata, uint8_t *buffer) { - uint16_t user_reset_addr = pdata->bootloader_start - 4; - uint16_t address = pdata->bootloader_start - pdata->page_size; - if (user_reset_addr > 0x2000) - { - // jmp - uint16_t data = 0x940C; - buffer[user_reset_addr - address + 0] = (uint8_t)(data >> 0); - buffer[user_reset_addr - address + 1] = (uint8_t)(data >> 8); - buffer[user_reset_addr - address + 2] = (uint8_t)(pdata->user_reset_vector >> 0); - buffer[user_reset_addr - address + 3] = (uint8_t)(pdata->user_reset_vector >> 8); - } - else - { - // rjmp - uint16_t data = 0xC000 | ((pdata->user_reset_vector - user_reset_addr / 2 - 1) & 0x0FFF); - buffer[user_reset_addr - address + 0] = (uint8_t)(data >> 0); - buffer[user_reset_addr - address + 1] = (uint8_t)(data >> 8); - } + uint16_t user_reset_addr = pdata->bootloader_start - 4; + uint16_t address = pdata->bootloader_start - pdata->page_size; + + if(user_reset_addr > 0x2000) { + // jmp + uint16_t data = 0x940C; + + buffer[user_reset_addr - address + 0] = (uint8_t) (data >> 0); + buffer[user_reset_addr - address + 1] = (uint8_t) (data >> 8); + buffer[user_reset_addr - address + 2] = (uint8_t) (pdata->user_reset_vector >> 0); + buffer[user_reset_addr - address + 3] = (uint8_t) (pdata->user_reset_vector >> 8); + } else { + // rjmp + uint16_t data = 0xC000 | ((pdata->user_reset_vector - user_reset_addr/2 - 1) & 0x0FFF); + + buffer[user_reset_addr - address + 0] = (uint8_t) (data >> 0); + buffer[user_reset_addr - address + 1] = (uint8_t) (data >> 8); + } } static int micronucleus_write_page_v1(struct pdata *pdata, uint32_t address, uint8_t *buffer, uint32_t size) { - int result = usb_control_msg( - pdata->usb_handle, - USB_ENDPOINT_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE, - MICRONUCLEUS_CMD_TRANSFER, - size, address, - (char*)buffer, size, - MICRONUCLEUS_DEFAULT_TIMEOUT); - if (result < 0) - { - pmsg_error("unable to transfer page: %s\n", usb_strerror()); - return result; - } + int result = usb_control_msg(pdata->usb_handle, + USB_ENDPOINT_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE, + MICRONUCLEUS_CMD_TRANSFER, + size, address, + (char *) buffer, size, + MICRONUCLEUS_DEFAULT_TIMEOUT); - return 0; + if(result < 0) { + pmsg_error("unable to transfer page: %s\n", usb_strerror()); + return result; + } + + return 0; } static int micronucleus_write_page_v2(struct pdata *pdata, uint32_t address, uint8_t *buffer, uint32_t size) { - int result = usb_control_msg( - pdata->usb_handle, - USB_ENDPOINT_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE, - MICRONUCLEUS_CMD_TRANSFER, - size, address, - NULL, 0, - MICRONUCLEUS_DEFAULT_TIMEOUT); - if (result < 0) - { - pmsg_error("unable to transfer page: %s\n", usb_strerror()); - return result; - } + int result = usb_control_msg(pdata->usb_handle, + USB_ENDPOINT_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE, + MICRONUCLEUS_CMD_TRANSFER, + size, address, + NULL, 0, + MICRONUCLEUS_DEFAULT_TIMEOUT); - for (uint32_t i = 0; i < size; i += 4) - { - int w1 = (buffer[i + 1] << 8) | (buffer[i + 0] << 0); - int w2 = (buffer[i + 3] << 8) | (buffer[i + 2] << 0); - result = usb_control_msg( - pdata->usb_handle, - USB_ENDPOINT_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE, - MICRONUCLEUS_CMD_PROGRAM, - w1, w2, - NULL, 0, - MICRONUCLEUS_DEFAULT_TIMEOUT); - if (result < 0) - { - pmsg_error("unable to transfer page: %s\n", usb_strerror()); - return result; - } + if(result < 0) { + pmsg_error("unable to transfer page: %s\n", usb_strerror()); + return result; + } + + for(uint32_t i = 0; i < size; i += 4) { + int w1 = (buffer[i + 1] << 8) | (buffer[i + 0] << 0); + int w2 = (buffer[i + 3] << 8) | (buffer[i + 2] << 0); + + result = usb_control_msg(pdata->usb_handle, + USB_ENDPOINT_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE, + MICRONUCLEUS_CMD_PROGRAM, w1, w2, NULL, 0, MICRONUCLEUS_DEFAULT_TIMEOUT); + if(result < 0) { + pmsg_error("unable to transfer page: %s\n", usb_strerror()); + return result; } + } - return 0; + return 0; } static int micronucleus_write_page(struct pdata *pdata, uint32_t address, uint8_t *buffer, uint32_t size) { - pmsg_debug("micronucleus_write_page(address=0x%04X, size=%d)\n", address, size); - - if (address == 0) - { - if (pdata->major_version >= 2) - { - int result = micronucleus_patch_reset_vector(pdata, buffer); - if (result < 0) - { - return result; - } - } + pmsg_debug("micronucleus_write_page(address=0x%04X, size=%d)\n", address, size); - // Require last page (with application reset vector) to be written. - pdata->write_last_page = true; + if(address == 0) { + if(pdata->major_version >= 2) { + int result = micronucleus_patch_reset_vector(pdata, buffer); - // Require software start. - pdata->start_program = true; + if(result < 0) { + return result; + } } - else if (address >= (uint32_t) (pdata->bootloader_start - pdata->page_size)) - { - if (pdata->major_version >= 2) - { - micronucleus_patch_user_vector(pdata, buffer); - } + // Require last page (with application reset vector) to be written. + pdata->write_last_page = true; - // Mark last page as written. - pdata->write_last_page = false; + // Require software start. + pdata->start_program = true; + } else if(address >= (uint32_t) (pdata->bootloader_start - pdata->page_size)) { + if(pdata->major_version >= 2) { + micronucleus_patch_user_vector(pdata, buffer); } + // Mark last page as written. + pdata->write_last_page = false; + } - int result; - if (pdata->major_version >= 2) - { - result = micronucleus_write_page_v2(pdata, address, buffer, size); - } - else - { - result = micronucleus_write_page_v1(pdata, address, buffer, size); - } + int result; - if (result < 0) - { - return result; - } + if(pdata->major_version >= 2) { + result = micronucleus_write_page_v2(pdata, address, buffer, size); + } else { + result = micronucleus_write_page_v1(pdata, address, buffer, size); + } - delay_ms(pdata->write_sleep); + if(result < 0) { + return result; + } - return 0; + delay_ms(pdata->write_sleep); + + return 0; } static int micronucleus_start(struct pdata *pdata) { - pmsg_debug("micronucleus_start()\n"); - - int result = usb_control_msg( - pdata->usb_handle, - USB_ENDPOINT_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE, - MICRONUCLEUS_CMD_START, - 0, 0, - NULL, 0, - MICRONUCLEUS_DEFAULT_TIMEOUT); - if (result < 0) - { - pmsg_warning("start command failed: %s\n", usb_strerror()); - return result; - } + pmsg_debug("micronucleus_start()\n"); - return 0; + int result = usb_control_msg(pdata->usb_handle, + USB_ENDPOINT_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE, + MICRONUCLEUS_CMD_START, + 0, 0, + NULL, 0, + MICRONUCLEUS_DEFAULT_TIMEOUT); + + if(result < 0) { + pmsg_warning("start command failed: %s\n", usb_strerror()); + return result; + } + + return 0; } -//----------------------------------------------------------------------------- +// ----------------------------------------------------------------------------- static void micronucleus_setup(PROGRAMMER *pgm) { - pmsg_debug("micronucleus_setup()\n"); - pgm->cookie = mmt_malloc(sizeof(struct pdata)); + pmsg_debug("micronucleus_setup()\n"); + pgm->cookie = mmt_malloc(sizeof(struct pdata)); } -static void micronucleus_teardown(PROGRAMMER* pgm) { - pmsg_debug("micronucleus_teardown()\n"); - mmt_free(pgm->cookie); - pgm->cookie = NULL; +static void micronucleus_teardown(PROGRAMMER *pgm) { + pmsg_debug("micronucleus_teardown()\n"); + mmt_free(pgm->cookie); + pgm->cookie = NULL; } static int micronucleus_initialize(const PROGRAMMER *pgm, const AVRPART *p) { - pmsg_debug("micronucleus_initialize()\n"); + pmsg_debug("micronucleus_initialize()\n"); - struct pdata *pdata = PDATA(pgm); + struct pdata *pdata = &my; - int result = micronucleus_get_bootloader_info(pdata); - if (result < 0) - return result; + int result = micronucleus_get_bootloader_info(pdata); - micronucleus_dump_device_info(pdata); + if(result < 0) + return result; - return 0; + micronucleus_dump_device_info(pdata); + + return 0; } static void micronucleus_display(const PROGRAMMER *pgm, const char *prefix) { @@ -563,396 +514,353 @@ static void micronucleus_display(const PROGRAMMER *pgm, const char *prefix) { } static void micronucleus_powerup(const PROGRAMMER *pgm) { - pmsg_debug("micronucleus_powerup()\n"); + pmsg_debug("micronucleus_powerup()\n"); } static void micronucleus_powerdown(const PROGRAMMER *pgm) { - pmsg_debug("micronucleus_powerdown()\n"); + pmsg_debug("micronucleus_powerdown()\n"); - struct pdata *pdata = PDATA(pgm); - if (pdata->write_last_page) - { - pdata->write_last_page = false; + struct pdata *pdata = &my; - uint8_t *buffer = (unsigned char *) mmt_malloc(pdata->page_size); - memset(buffer, 0xFF, pdata->page_size); - micronucleus_write_page(pdata, pdata->bootloader_start - pdata->page_size, buffer, pdata->page_size); - mmt_free(buffer); - } + if(pdata->write_last_page) { + pdata->write_last_page = false; - if (pdata->start_program) - { - pdata->start_program = false; + uint8_t *buffer = (unsigned char *) mmt_malloc(pdata->page_size); - micronucleus_start(pdata); - } + memset(buffer, 0xFF, pdata->page_size); + micronucleus_write_page(pdata, pdata->bootloader_start - pdata->page_size, buffer, pdata->page_size); + mmt_free(buffer); + } + + if(pdata->start_program) { + pdata->start_program = false; + + micronucleus_start(pdata); + } } static void micronucleus_enable(PROGRAMMER *pgm, const AVRPART *p) { - pmsg_debug("micronucleus_enable()\n"); + pmsg_debug("micronucleus_enable()\n"); } static void micronucleus_disable(const PROGRAMMER *pgm) { - pmsg_debug("micronucleus_disable()\n"); + pmsg_debug("micronucleus_disable()\n"); } static int micronucleus_program_enable(const PROGRAMMER *pgm, const AVRPART *p) { - pmsg_debug("micronucleus_program_enable()\n"); - return 0; + pmsg_debug("micronucleus_program_enable()\n"); + return 0; } static int micronucleus_read_sig_bytes(const PROGRAMMER *pgm, const AVRPART *p, const AVRMEM *mem) { - pmsg_debug("micronucleus_read_sig_bytes()\n"); + pmsg_debug("micronucleus_read_sig_bytes()\n"); - if (mem->size < 3) - { - pmsg_error("memory size %d < 3 too small for read_sig_bytes", mem->size); - return -1; - } + if(mem->size < 3) { + pmsg_error("memory size %d < 3 too small for read_sig_bytes", mem->size); + return -1; + } - struct pdata *pdata = PDATA(pgm); - mem->buf[0] = 0x1E; - mem->buf[1] = pdata->signature1; - mem->buf[2] = pdata->signature2; - return 0; + struct pdata *pdata = &my; + + mem->buf[0] = 0x1E; + mem->buf[1] = pdata->signature1; + mem->buf[2] = pdata->signature2; + return 0; } static int micronucleus_chip_erase(const PROGRAMMER *pgm, const AVRPART *p) { - pmsg_debug("micronucleus_chip_erase()\n"); + pmsg_debug("micronucleus_chip_erase()\n"); - struct pdata *pdata = PDATA(pgm); - return micronucleus_erase_device(pdata); + struct pdata *pdata = &my; + + return micronucleus_erase_device(pdata); } -static int micronucleus_open(PROGRAMMER* pgm, const char *port) { - pmsg_debug("micronucleus_open(\"%s\")\n", port); +static int micronucleus_open(PROGRAMMER *pgm, const char *port) { + pmsg_debug("micronucleus_open(\"%s\")\n", port); - struct pdata *pdata = PDATA(pgm); - const char *bus_name = NULL; - char* dev_name = NULL; + struct pdata *pdata = &my; + const char *bus_name = NULL; + char *dev_name = NULL; - // if no -P was given or '-P usb' was given - if (str_eq(port, "usb")) - { - port = NULL; - } - else - { - // calculate bus and device names from -P option - if (str_starts(port, "usb") && ':' == port[3]) - { - bus_name = port + 4; - dev_name = strchr(bus_name, ':'); - if (dev_name != NULL) - { - *dev_name = '\0'; - dev_name++; - } - } + // If no -P was given or '-P usb' was given + if(str_eq(port, "usb")) { + port = NULL; + } else { + // Calculate bus and device names from -P option + if(str_starts(port, "usb") && ':' == port[3]) { + bus_name = port + 4; + dev_name = strchr(bus_name, ':'); + if(dev_name != NULL) { + *dev_name = '\0'; + dev_name++; + } } + } - if (port != NULL && dev_name == NULL) - { - pmsg_error("invalid -P %s; use -P usb:bus:device\n", port); - return -1; - } + if(port != NULL && dev_name == NULL) { + pmsg_error("invalid -P %s; use -P usb:bus:device\n", port); + return -1; + } + // Determine VID/PID + int vid = pgm->usbvid? pgm->usbvid: MICRONUCLEUS_VID; + int pid = MICRONUCLEUS_PID; - // Determine VID/PID - int vid = pgm->usbvid ? pgm->usbvid : MICRONUCLEUS_VID; - int pid = MICRONUCLEUS_PID; - - LNODEID usbpid = lfirst(pgm->usbpid); - if (usbpid != NULL) - { - pid = *(int*)(ldata(usbpid)); - if (lnext(usbpid)) - { - pmsg_warning("using PID 0x%04x, ignoring remaining PIDs in list\n", pid); - } + LNODEID usbpid = lfirst(pgm->usbpid); + + if(usbpid != NULL) { + pid = *(int *) (ldata(usbpid)); + if(lnext(usbpid)) { + pmsg_warning("using PID 0x%04x, ignoring remaining PIDs in list\n", pid); } + } - usb_init(); - - bool show_retry_message = true; - bool show_unresponsive_device_message = true; - - time_t start_time = time(NULL); - for (;;) - { - usb_find_busses(); - usb_find_devices(); - - pdata->usb_handle = NULL; - - // Search for device - struct usb_bus* bus = NULL; - for (bus = usb_busses; bus != NULL && pdata->usb_handle == NULL; bus = bus->next) - { - struct usb_device* device = NULL; - for (device = bus->devices; device != NULL && pdata->usb_handle == NULL; device = device->next) - { - if (device->descriptor.idVendor == vid && device->descriptor.idProduct == pid) - { - pdata->major_version = (uint8_t)(device->descriptor.bcdDevice >> 8); - pdata->minor_version = (uint8_t)(device->descriptor.bcdDevice >> 0); - - if (!micronucleus_is_device_responsive(pdata, device)) - { - if (show_unresponsive_device_message) - { - pmsg_warning("unresponsive Micronucleus device detected, please reconnect ...\n"); - - show_unresponsive_device_message = false; - } - - continue; - } - - pmsg_notice("found device with Micronucleus V%d.%d, bus:device: %s:%s\n", - pdata->major_version, pdata->minor_version, - bus->dirname, device->filename); - - // if -P was given, match device by device name and bus name - if (port != NULL) - { - if (dev_name == NULL || !str_eq(bus->dirname, bus_name) || !str_eq(device->filename, dev_name)) - { - continue; - } - } - - if (pdata->major_version > MICRONUCLEUS_MAX_MAJOR_VERSION) - { - pmsg_warning("device with unsupported Micronucleus version V%d.%d\n", - pdata->major_version, pdata->minor_version); - continue; - } - - pdata->usb_handle = usb_open(device); - if (pdata->usb_handle == NULL) - { - pmsg_error("unable to open USB device: %s\n", usb_strerror()); - } - } - } - } + usb_init(); + + bool show_retry_message = true; + bool show_unresponsive_device_message = true; + + time_t start_time = time(NULL); + + for(;;) { + usb_find_busses(); + usb_find_devices(); + + pdata->usb_handle = NULL; + + // Search for device + struct usb_bus *bus = NULL; + + for(bus = usb_busses; bus != NULL && pdata->usb_handle == NULL; bus = bus->next) { + struct usb_device *device = NULL; + + for(device = bus->devices; device != NULL && pdata->usb_handle == NULL; device = device->next) { + if(device->descriptor.idVendor == vid && device->descriptor.idProduct == pid) { + pdata->major_version = (uint8_t) (device->descriptor.bcdDevice >> 8); + pdata->minor_version = (uint8_t) (device->descriptor.bcdDevice >> 0); + + if(!micronucleus_is_device_responsive(pdata, device)) { + if(show_unresponsive_device_message) { + pmsg_warning("unresponsive Micronucleus device detected, please reconnect ...\n"); - if (pdata->usb_handle == NULL && pdata->wait_until_device_present) - { - if (show_retry_message) - { - if (pdata->wait_timout < 0) - { - pmsg_error("no device found, waiting for device to be plugged in ...\n"); - } - else - { - pmsg_error("no device found, waiting %d seconds for device to be plugged in ...\n", - pdata->wait_timout); - } - - pmsg_error("press CTRL-C to terminate\n"); - show_retry_message = false; + show_unresponsive_device_message = false; } - if (pdata->wait_timout < 0 || (time(NULL) - start_time) < pdata->wait_timout) - { - delay_ms(MICRONUCLEUS_CONNECT_WAIT); - continue; + continue; + } + + pmsg_notice("found device with Micronucleus V%d.%d, bus:device: %s:%s\n", + pdata->major_version, pdata->minor_version, bus->dirname, device->filename); + + // If -P was given, match device by device name and bus name + if(port != NULL) { + if(dev_name == NULL || !str_eq(bus->dirname, bus_name) || !str_eq(device->filename, dev_name)) { + continue; } - } + } - break; + if(pdata->major_version > MICRONUCLEUS_MAX_MAJOR_VERSION) { + pmsg_warning("device with unsupported Micronucleus version V%d.%d\n", + pdata->major_version, pdata->minor_version); + continue; + } + + pdata->usb_handle = usb_open(device); + if(pdata->usb_handle == NULL) { + pmsg_error("unable to open USB device: %s\n", usb_strerror()); + } + } + } } - if (!pdata->usb_handle) - { - pmsg_error("cannot find device with Micronucleus bootloader (%04X:%04X)\n", vid, pid); - return -1; + if(pdata->usb_handle == NULL && pdata->wait_until_device_present) { + if(show_retry_message) { + if(pdata->wait_timout < 0) { + pmsg_error("no device found, waiting for device to be plugged in ...\n"); + } else { + pmsg_error("no device found, waiting %d seconds for device to be plugged in ...\n", pdata->wait_timout); + } + + pmsg_error("press CTRL-C to terminate\n"); + show_retry_message = false; + } + + if(pdata->wait_timout < 0 || (time(NULL) - start_time) < pdata->wait_timout) { + delay_ms(MICRONUCLEUS_CONNECT_WAIT); + continue; + } } - return 0; + break; + } + + if(!pdata->usb_handle) { + pmsg_error("cannot find device with Micronucleus bootloader (%04X:%04X)\n", vid, pid); + return -1; + } + + return 0; } -static void micronucleus_close(PROGRAMMER* pgm) -{ - pmsg_debug("micronucleus_close()\n"); +static void micronucleus_close(PROGRAMMER *pgm) { + pmsg_debug("micronucleus_close()\n"); - struct pdata *pdata = PDATA(pgm); - if (pdata->usb_handle != NULL) - { - usb_close(pdata->usb_handle); - pdata->usb_handle = NULL; - } + struct pdata *pdata = &my; + + if(pdata->usb_handle != NULL) { + usb_close(pdata->usb_handle); + pdata->usb_handle = NULL; + } } static int micronucleus_read_byte(const PROGRAMMER *pgm, const AVRPART *p, const AVRMEM *mem, - unsigned long addr, unsigned char* value) -{ - pmsg_debug("micronucleus_read_byte(desc=%s, addr=0x%04lX)\n", mem->desc, addr); - - if (mem_is_a_fuse(mem) || mem_is_lock(mem)) - { - *value = 0xFF; - return 0; - } - else - { - pmsg_notice("reading not supported for %s memory\n", mem->desc); - return -1; - } + unsigned long addr, unsigned char *value) { + pmsg_debug("micronucleus_read_byte(desc=%s, addr=0x%04lX)\n", mem->desc, addr); + + if(mem_is_a_fuse(mem) || mem_is_lock(mem)) { + *value = 0xFF; + return 0; + } else { + pmsg_notice("reading not supported for %s memory\n", mem->desc); + return -1; + } } static int micronucleus_write_byte(const PROGRAMMER *pgm, const AVRPART *p, const AVRMEM *mem, - unsigned long addr, unsigned char value) -{ - pmsg_debug("micronucleus_write_byte(desc=%s, addr=0x%04lX)\n", mem->desc, addr); - return -1; + unsigned long addr, unsigned char value) { + pmsg_debug("micronucleus_write_byte(desc=%s, addr=0x%04lX)\n", mem->desc, addr); + return -1; } static int micronucleus_paged_load(const PROGRAMMER *pgm, const AVRPART *p, const AVRMEM *mem, - unsigned int page_size, - unsigned int addr, unsigned int n_bytes) -{ - pmsg_debug("micronucleus_paged_load(page_size=0x%X, addr=0x%X, n_bytes=0x%X)\n", page_size, addr, n_bytes); - return -1; + unsigned int page_size, unsigned int addr, unsigned int n_bytes) { + pmsg_debug("micronucleus_paged_load(page_size=0x%X, addr=0x%X, n_bytes=0x%X)\n", page_size, addr, n_bytes); + return -1; } static int micronucleus_paged_write(const PROGRAMMER *pgm, const AVRPART *p, const AVRMEM *mem, - unsigned int page_size, - unsigned int addr, unsigned int n_bytes) -{ - pmsg_debug("micronucleus_paged_write(page_size=0x%X, addr=0x%X, n_bytes=0x%X)\n", page_size, addr, n_bytes); - - if (mem_is_flash(mem)) - { - struct pdata *pdata = PDATA(pgm); - - if (n_bytes > page_size) - { - pmsg_error("buffer size %u exceeds page size %u\n", n_bytes, page_size); - return -1; - } + unsigned int page_size, unsigned int addr, unsigned int n_bytes) { + pmsg_debug("micronucleus_paged_write(page_size=0x%X, addr=0x%X, n_bytes=0x%X)\n", page_size, addr, n_bytes); - if (addr + n_bytes > pdata->flash_size) - { - pmsg_error("program size %u exceeds flash size %u\n", addr + n_bytes, pdata->flash_size); - return -1; - } + if(mem_is_flash(mem)) { + struct pdata *pdata = &my; - uint8_t *page_buffer = (uint8_t *) mmt_malloc(pdata->page_size); + if(n_bytes > page_size) { + pmsg_error("buffer size %u exceeds page size %u\n", n_bytes, page_size); + return -1; + } - // Note: Page size reported by the bootloader may be smaller than device page size as configured in avrdude.conf. - int result = 0; - while (n_bytes > 0) - { - size_t chunk_size = n_bytes < pdata->page_size ? n_bytes : pdata->page_size; + if(addr + n_bytes > pdata->flash_size) { + pmsg_error("program size %u exceeds flash size %u\n", addr + n_bytes, pdata->flash_size); + return -1; + } - memcpy(page_buffer, mem->buf + addr, chunk_size); - memset(page_buffer + chunk_size, 0xFF, pdata->page_size - chunk_size); + uint8_t *page_buffer = (uint8_t *) mmt_malloc(pdata->page_size); - result = micronucleus_write_page(pdata, addr, page_buffer, pdata->page_size); - if (result < 0) - { - break; - } + // Note: Page size reported by the bootloader may be smaller than device page size as configured in avrdude.conf. + int result = 0; - addr += chunk_size; - n_bytes -= chunk_size; - } + while(n_bytes > 0) { + size_t chunk_size = n_bytes < pdata->page_size? n_bytes: pdata->page_size; - mmt_free(page_buffer); - return result; - } - else - { - pmsg_error("unsupported memory %s\n", mem->desc); - return -1; + memcpy(page_buffer, mem->buf + addr, chunk_size); + memset(page_buffer + chunk_size, 0xFF, pdata->page_size - chunk_size); + + result = micronucleus_write_page(pdata, addr, page_buffer, pdata->page_size); + if(result < 0) { + break; + } + + addr += chunk_size; + n_bytes -= chunk_size; } + + mmt_free(page_buffer); + return result; + } else { + pmsg_error("unsupported memory %s\n", mem->desc); + return -1; + } } static int micronucleus_parseextparams(const PROGRAMMER *pgm, const LISTID xparams) { - int rv = 0; - bool help = false; - pmsg_debug("micronucleus_parseextparams()\n"); - - struct pdata *pdata = PDATA(pgm); - for (LNODEID node = lfirst(xparams); node; node = lnext(node)) - { - const char* extended_param = ldata(node); - - if (str_eq(extended_param, "wait")) - { - pdata->wait_until_device_present = true; - pdata->wait_timout = -1; - continue; - } + int rv = 0; + bool help = false; - if (str_starts(extended_param, "wait=")) - { - pdata->wait_until_device_present = true; - pdata->wait_timout = atoi(extended_param + 5); - continue; - } + pmsg_debug("micronucleus_parseextparams()\n"); - if (str_eq(extended_param, "help")) - { - help = true; - rv = LIBAVRDUDE_EXIT; - } + struct pdata *pdata = &my; - if (!help) - { - pmsg_error("invalid extended parameter -x %s\n", extended_param); - rv = -1; - } - msg_error("%s -c %s extended options:\n", progname, pgmid); - msg_error(" -x wait Wait for the device to be plugged in if not connected\n"); - msg_error(" -x wait= Wait s for the device to be plugged in if not connected\n"); - msg_error(" -x help Show this help menu and exit\n"); - return rv; + for(LNODEID node = lfirst(xparams); node; node = lnext(node)) { + const char *extended_param = ldata(node); + + if(str_eq(extended_param, "wait")) { + pdata->wait_until_device_present = true; + pdata->wait_timout = -1; + continue; } + if(str_starts(extended_param, "wait=")) { + pdata->wait_until_device_present = true; + pdata->wait_timout = atoi(extended_param + 5); + continue; + } + + if(str_eq(extended_param, "help")) { + help = true; + rv = LIBAVRDUDE_EXIT; + } + + if(!help) { + pmsg_error("invalid extended parameter -x %s\n", extended_param); + rv = -1; + } + msg_error("%s -c %s extended options:\n", progname, pgmid); + msg_error(" -x wait Wait for the device to be plugged in if not connected\n"); + msg_error(" -x wait= Wait s for the device to be plugged in if not connected\n"); + msg_error(" -x help Show this help menu and exit\n"); return rv; + } + + return rv; } void micronucleus_initpgm(PROGRAMMER *pgm) { - strcpy(pgm->type, "Micronucleus V2.0"); - - pgm->setup = micronucleus_setup; - pgm->teardown = micronucleus_teardown; - pgm->initialize = micronucleus_initialize; - pgm->display = micronucleus_display; - pgm->powerup = micronucleus_powerup; - pgm->powerdown = micronucleus_powerdown; - pgm->enable = micronucleus_enable; - pgm->disable = micronucleus_disable; - pgm->program_enable = micronucleus_program_enable; - pgm->read_sig_bytes = micronucleus_read_sig_bytes; - pgm->chip_erase = micronucleus_chip_erase; - pgm->cmd = NULL; - pgm->open = micronucleus_open; - pgm->close = micronucleus_close; - pgm->read_byte = micronucleus_read_byte; - pgm->write_byte = micronucleus_write_byte; - pgm->paged_load = micronucleus_paged_load; - pgm->paged_write = micronucleus_paged_write; - pgm->parseextparams = micronucleus_parseextparams; -} - -#else /* !HAVE_LIBUSB */ + strcpy(pgm->type, "Micronucleus V2.0"); + + pgm->setup = micronucleus_setup; + pgm->teardown = micronucleus_teardown; + pgm->initialize = micronucleus_initialize; + pgm->display = micronucleus_display; + pgm->powerup = micronucleus_powerup; + pgm->powerdown = micronucleus_powerdown; + pgm->enable = micronucleus_enable; + pgm->disable = micronucleus_disable; + pgm->program_enable = micronucleus_program_enable; + pgm->read_sig_bytes = micronucleus_read_sig_bytes; + pgm->chip_erase = micronucleus_chip_erase; + pgm->cmd = NULL; + pgm->open = micronucleus_open; + pgm->close = micronucleus_close; + pgm->read_byte = micronucleus_read_byte; + pgm->write_byte = micronucleus_write_byte; + pgm->paged_load = micronucleus_paged_load; + pgm->paged_write = micronucleus_paged_write; + pgm->parseextparams = micronucleus_parseextparams; +} + +#else // ! HAVE_LIBUSB // Give a proper error if we were not compiled with libusb -static int micronucleus_nousb_open(PROGRAMMER* pgm, const char* name) { - pmsg_error("no usb support; please compile again with libusb installed\n"); - return -1; +static int micronucleus_nousb_open(PROGRAMMER *pgm, const char *name) { + pmsg_error("no usb support; please compile again with libusb installed\n"); + return -1; } void micronucleus_initpgm(PROGRAMMER *pgm) { - strcpy(pgm->type, "micronucleus"); - pgm->open = micronucleus_nousb_open; + strcpy(pgm->type, "micronucleus"); + pgm->open = micronucleus_nousb_open; } - -#endif /* HAVE_LIBUSB */ +#endif // HAVE_LIBUSB const char micronucleus_desc[] = "Micronucleus Bootloader"; diff --git a/src/micronucleus.h b/src/micronucleus.h index 729fa1261..841247ad8 100644 --- a/src/micronucleus.h +++ b/src/micronucleus.h @@ -25,11 +25,11 @@ extern "C" { #endif -extern const char micronucleus_desc[]; -void micronucleus_initpgm(PROGRAMMER *pgm); + extern const char micronucleus_desc[]; + void micronucleus_initpgm(PROGRAMMER *pgm); #ifdef __cplusplus } #endif -#endif /* micronucleus_h */ +#endif diff --git a/src/par.c b/src/par.c index 29865dd1e..5aab54c2d 100644 --- a/src/par.c +++ b/src/par.c @@ -26,11 +26,11 @@ #include #if defined(__FreeBSD__) || defined(__FreeBSD_kernel__) -# include "freebsd_ppi.h" +#include "freebsd_ppi.h" #elif defined(__linux__) -# include "linux_ppdev.h" -#elif defined(__sun__) || defined(__sun) /* Solaris */ -# include "solaris_ecpp.h" +#include "linux_ppdev.h" +#elif defined(__sun__) || defined(__sun) // Solaris +#include "solaris_ecpp.h" #endif #include "avrdude.h" @@ -41,7 +41,6 @@ #include "par.h" #if HAVE_PARPORT - struct ppipins { int pin; int reg; @@ -50,23 +49,23 @@ struct ppipins { }; static const struct ppipins ppipins[] = { - { 1, PPICTRL, 0x01, 1 }, - { 2, PPIDATA, 0x01, 0 }, - { 3, PPIDATA, 0x02, 0 }, - { 4, PPIDATA, 0x04, 0 }, - { 5, PPIDATA, 0x08, 0 }, - { 6, PPIDATA, 0x10, 0 }, - { 7, PPIDATA, 0x20, 0 }, - { 8, PPIDATA, 0x40, 0 }, - { 9, PPIDATA, 0x80, 0 }, - { 10, PPISTATUS, 0x40, 0 }, - { 11, PPISTATUS, 0x80, 1 }, - { 12, PPISTATUS, 0x20, 0 }, - { 13, PPISTATUS, 0x10, 0 }, - { 14, PPICTRL, 0x02, 1 }, - { 15, PPISTATUS, 0x08, 0 }, - { 16, PPICTRL, 0x04, 0 }, - { 17, PPICTRL, 0x08, 1 } + {1, PPICTRL, 0x01, 1}, + {2, PPIDATA, 0x01, 0}, + {3, PPIDATA, 0x02, 0}, + {4, PPIDATA, 0x04, 0}, + {5, PPIDATA, 0x08, 0}, + {6, PPIDATA, 0x10, 0}, + {7, PPIDATA, 0x20, 0}, + {8, PPIDATA, 0x40, 0}, + {9, PPIDATA, 0x80, 0}, + {10, PPISTATUS, 0x40, 0}, + {11, PPISTATUS, 0x80, 1}, + {12, PPISTATUS, 0x20, 0}, + {13, PPISTATUS, 0x10, 0}, + {14, PPICTRL, 0x02, 1}, + {15, PPISTATUS, 0x08, 0}, + {16, PPICTRL, 0x04, 0}, + {17, PPICTRL, 0x08, 1} }; #define NPINS (sizeof(ppipins)/sizeof(struct ppipins)) @@ -77,29 +76,29 @@ static int par_setpin_internal(const PROGRAMMER *pgm, int pin, int value) { inverted = pin & PIN_INVERSE; pin &= PIN_MASK; - if (pin < 1 || pin > 17) + if(pin < 1 || pin > 17) return -1; pin--; - if (ppipins[pin].inverted) + if(ppipins[pin].inverted) inverted = !inverted; - if (inverted) + if(inverted) value = !value; - if (value) + if(value) ppi_set(&pgm->fd, ppipins[pin].reg, ppipins[pin].bit); else ppi_clr(&pgm->fd, ppipins[pin].reg, ppipins[pin].bit); - if (pgm->ispdelay > 1) + if(pgm->ispdelay > 1) bitbang_delay(pgm->ispdelay); return 0; } -static int par_setpin(const PROGRAMMER * pgm, int pinfunc, int value) { +static int par_setpin(const PROGRAMMER *pgm, int pinfunc, int value) { if(pinfunc < 0 || pinfunc >= N_PINS) return -1; @@ -114,16 +113,16 @@ static void par_setmany(const PROGRAMMER *pgm, int pinfunc, int value) { pinset = pgm->pinno[pinfunc]; - /* mask is anything non-pin - needs to be applied to each par_setpin to preserve inversion */ + // Mask is anything non-pin - needs to be applied to each par_setpin to preserve inversion mask = pinset & (~PIN_MASK); - for (pin = 1; pin <= 17; pin++) { - if (pinset & (1 << pin)) + for(pin = 1; pin <= 17; pin++) { + if(pinset & (1 << pin)) par_setpin_internal(pgm, pin | mask, value); } } -static int par_getpin(const PROGRAMMER * pgm, int pinfunc) { +static int par_getpin(const PROGRAMMER *pgm, int pinfunc) { int value, inverted, pin; if(pinfunc < 0 || pinfunc >= N_PINS) @@ -134,26 +133,25 @@ static int par_getpin(const PROGRAMMER * pgm, int pinfunc) { inverted = pin & PIN_INVERSE; pin &= PIN_MASK; - if (pin < 1 || pin > 17) + if(pin < 1 || pin > 17) return -1; pin--; value = ppi_get(&pgm->fd, ppipins[pin].reg, ppipins[pin].bit); - if (value) + if(value) value = 1; - - if (ppipins[pin].inverted) + + if(ppipins[pin].inverted) inverted = !inverted; - if (inverted) + if(inverted) value = !value; return value; } - static int par_highpulsepin(const PROGRAMMER *pgm, int pinfunc) { int inverted, pin; @@ -165,100 +163,90 @@ static int par_highpulsepin(const PROGRAMMER *pgm, int pinfunc) { inverted = pin & PIN_INVERSE; pin &= PIN_MASK; - if (pin < 1 || pin > 17) + if(pin < 1 || pin > 17) return -1; pin--; - if (ppipins[pin].inverted) + if(ppipins[pin].inverted) inverted = !inverted; - if (inverted) { + if(inverted) { ppi_clr(&pgm->fd, ppipins[pin].reg, ppipins[pin].bit); - if (pgm->ispdelay > 1) + if(pgm->ispdelay > 1) bitbang_delay(pgm->ispdelay); ppi_set(&pgm->fd, ppipins[pin].reg, ppipins[pin].bit); - if (pgm->ispdelay > 1) + if(pgm->ispdelay > 1) bitbang_delay(pgm->ispdelay); } else { ppi_set(&pgm->fd, ppipins[pin].reg, ppipins[pin].bit); - if (pgm->ispdelay > 1) + if(pgm->ispdelay > 1) bitbang_delay(pgm->ispdelay); ppi_clr(&pgm->fd, ppipins[pin].reg, ppipins[pin].bit); - if (pgm->ispdelay > 1) + if(pgm->ispdelay > 1) bitbang_delay(pgm->ispdelay); } return 0; } -/* - * apply power to the AVR processor - */ +// Apply power to the AVR processor static void par_powerup(const PROGRAMMER *pgm) { - par_setmany(pgm, PPI_AVR_VCC, 1); /* power up */ + par_setmany(pgm, PPI_AVR_VCC, 1); // Power up usleep(100000); } - -/* - * remove power from the AVR processor - */ +// Remove power from the AVR processor static void par_powerdown(const PROGRAMMER *pgm) { - par_setmany(pgm, PPI_AVR_VCC, 0); /* power down */ + par_setmany(pgm, PPI_AVR_VCC, 0); // Power down } static void par_disable(const PROGRAMMER *pgm) { - par_setmany(pgm, PPI_AVR_BUFF, 1); /* turn off */ + par_setmany(pgm, PPI_AVR_BUFF, 1); // Turn off } static void par_enable(PROGRAMMER *pgm, const AVRPART *p) { /* - * Prepare to start talking to the connected device - pull reset low - * first, delay a few milliseconds, then enable the buffer. This - * sequence allows the AVR to be reset before the buffer is enabled - * to avoid a short period of time where the AVR may be driving the - * programming lines at the same time the programmer tries to. Of - * course, if a buffer is being used, then the /RESET line from the - * programmer needs to be directly connected to the AVR /RESET line - * and not via the buffer chip. + * Prepare to start talking to the connected device - pull reset low first, + * delay a few milliseconds, then enable the buffer. This sequence allows + * the AVR to be reset before the buffer is enabled to avoid a short period + * of time where the AVR may be driving the programming lines at the same + * time the programmer tries to. Of course, if a buffer is being used, then + * the /RESET line from the programmer needs to be directly connected to the + * AVR /RESET line and not via the buffer chip. */ par_setpin(pgm, PIN_AVR_RESET, 0); usleep(1); - /* - * enable the 74367 buffer, if connected; this signal is active low - */ + // Enable the 74367 buffer, if connected; this signal is active low par_setmany(pgm, PPI_AVR_BUFF, 0); } static int par_open(PROGRAMMER *pgm, const char *port) { int rc; - if (bitbang_check_prerequisites(pgm) < 0) + if(bitbang_check_prerequisites(pgm) < 0) return -1; ppi_open(port, &pgm->fd); - if (pgm->fd.ifd < 0) { + if(pgm->fd.ifd < 0) { pmsg_error("unable to open parallel port %s\n\n", port); return -1; } - /* - * save pin values, so they can be restored when device is closed - */ + // Save pin values, so they can be restored when device is closed rc = ppi_getall(&pgm->fd, PPIDATA); - if (rc < 0) { + if(rc < 0) { pmsg_error("unable to read status of ppi data port\n"); return -1; } pgm->ppidata = rc; rc = ppi_getall(&pgm->fd, PPICTRL); - if (rc < 0) { + if(rc < 0) { pmsg_error("unable to read status of ppi ctrl port\n"); return -1; } @@ -267,22 +255,16 @@ static int par_open(PROGRAMMER *pgm, const char *port) { return 0; } - static void par_close(PROGRAMMER *pgm) { - /* - * Restore pin values before closing, - * but ensure that buffers are turned off. - */ + // Restore pin values before closing, but ensure that buffers are turned off ppi_setall(&pgm->fd, PPIDATA, pgm->ppidata); ppi_setall(&pgm->fd, PPICTRL, pgm->ppictrl); par_setmany(pgm, PPI_AVR_BUFF, 1); - /* - * Handle exit specs. - */ - switch (pgm->exit_reset) { + // Handle exit specs + switch(pgm->exit_reset) { case EXIT_RESET_ENABLED: par_setpin(pgm, PIN_AVR_RESET, 0); break; @@ -292,11 +274,11 @@ static void par_close(PROGRAMMER *pgm) { break; case EXIT_RESET_UNSPEC: - /* Leave it alone. */ + // Leave it alone break; } - switch (pgm->exit_datahigh) { + switch(pgm->exit_datahigh) { case EXIT_DATAHIGH_ENABLED: ppi_setall(&pgm->fd, PPIDATA, 0xff); break; @@ -306,11 +288,11 @@ static void par_close(PROGRAMMER *pgm) { break; case EXIT_DATAHIGH_UNSPEC: - /* Leave it alone. */ + // Leave it alone break; } - switch (pgm->exit_vcc) { + switch(pgm->exit_vcc) { case EXIT_VCC_ENABLED: par_setmany(pgm, PPI_AVR_VCC, 1); break; @@ -320,7 +302,7 @@ static void par_close(PROGRAMMER *pgm) { break; case EXIT_VCC_UNSPEC: - /* Leave it alone. */ + // Leave it alone break; } @@ -328,9 +310,7 @@ static void par_close(PROGRAMMER *pgm) { pgm->fd.ifd = -1; } -/* - * parse the -E string - */ +// Parse the -E string static int par_parseexitspecs(PROGRAMMER *pgm, const char *sp) { char *cp, *s, *str = mmt_strdup(sp); int rv = 0; @@ -363,12 +343,12 @@ static int par_parseexitspecs(PROGRAMMER *pgm, const char *sp) { pgm->exit_datahigh = EXIT_DATAHIGH_DISABLED; continue; } - if (str_eq(cp, "help")) { + if(str_eq(cp, "help")) { help = true; rv = LIBAVRDUDE_EXIT; } - if (!help) { + if(!help) { pmsg_error("invalid exitspec parameter -E %s\n", cp); rv = -1; } @@ -391,43 +371,42 @@ static int par_parseexitspecs(PROGRAMMER *pgm, const char *sp) { void par_initpgm(PROGRAMMER *pgm) { strcpy(pgm->type, "PPI"); - pgm_fill_old_pins(pgm); // TODO to be removed if old pin data no longer needed + pgm_fill_old_pins(pgm); // TODO to be removed if old pin data no longer needed pgm->exit_vcc = EXIT_VCC_UNSPEC; pgm->exit_reset = EXIT_RESET_UNSPEC; pgm->exit_datahigh = EXIT_DATAHIGH_UNSPEC; - pgm->rdy_led = bitbang_rdy_led; - pgm->err_led = bitbang_err_led; - pgm->pgm_led = bitbang_pgm_led; - pgm->vfy_led = bitbang_vfy_led; - pgm->initialize = bitbang_initialize; - pgm->display = pgm_display_generic; - pgm->enable = par_enable; - pgm->disable = par_disable; - pgm->powerup = par_powerup; - pgm->powerdown = par_powerdown; + pgm->rdy_led = bitbang_rdy_led; + pgm->err_led = bitbang_err_led; + pgm->pgm_led = bitbang_pgm_led; + pgm->vfy_led = bitbang_vfy_led; + pgm->initialize = bitbang_initialize; + pgm->display = pgm_display_generic; + pgm->enable = par_enable; + pgm->disable = par_disable; + pgm->powerup = par_powerup; + pgm->powerdown = par_powerdown; pgm->program_enable = bitbang_program_enable; - pgm->chip_erase = bitbang_chip_erase; - pgm->cmd = bitbang_cmd; - pgm->cmd_tpi = bitbang_cmd_tpi; - pgm->spi = bitbang_spi; - pgm->open = par_open; - pgm->close = par_close; - pgm->setpin = par_setpin; - pgm->getpin = par_getpin; - pgm->highpulsepin = par_highpulsepin; + pgm->chip_erase = bitbang_chip_erase; + pgm->cmd = bitbang_cmd; + pgm->cmd_tpi = bitbang_cmd_tpi; + pgm->spi = bitbang_spi; + pgm->open = par_open; + pgm->close = par_close; + pgm->setpin = par_setpin; + pgm->getpin = par_getpin; + pgm->highpulsepin = par_highpulsepin; pgm->parseexitspecs = par_parseexitspecs; - pgm->read_byte = avr_read_byte_default; - pgm->write_byte = avr_write_byte_default; + pgm->read_byte = avr_read_byte_default; + pgm->write_byte = avr_write_byte_default; } -#else /* !HAVE_PARPORT */ +#else // ! HAVE_PARPORT void par_initpgm(PROGRAMMER *pgm) { pmsg_error("parallel port access not available in this configuration\n"); } - -#endif /* HAVE_PARPORT */ +#endif // HAVE_PARPORT const char par_desc[] = "Parallel port bitbanging"; diff --git a/src/par.h b/src/par.h index adcca7d0b..3941c8f36 100644 --- a/src/par.h +++ b/src/par.h @@ -23,11 +23,10 @@ extern "C" { #endif -extern const char par_desc[]; -void par_initpgm(PROGRAMMER *pgm); + extern const char par_desc[]; + void par_initpgm(PROGRAMMER *pgm); #ifdef __cplusplus } #endif - #endif diff --git a/src/pgm.c b/src/pgm.c index 4f34c5cba..72c5413e1 100644 --- a/src/pgm.c +++ b/src/pgm.c @@ -28,11 +28,11 @@ #include "libavrdude.h" static void pgm_default(void); -static int pgm_default_2(const PROGRAMMER *, const AVRPART *); -static int pgm_default_3(const PROGRAMMER *pgm, const AVRPART *p, const AVRMEM *mem, - unsigned long addr, unsigned char * value); +static int pgm_default_2(const PROGRAMMER *, const AVRPART *); +static int pgm_default_3(const PROGRAMMER *pgm, const AVRPART *p, const AVRMEM *mem, + unsigned long addr, unsigned char *value); static void pgm_default_4(const PROGRAMMER *); -static int pgm_default_5(const PROGRAMMER *pgm, const AVRPART *p, const AVRMEM *mem, +static int pgm_default_5(const PROGRAMMER *pgm, const AVRPART *p, const AVRMEM *mem, unsigned long addr, unsigned char data); static void pgm_default_6(const PROGRAMMER *, const char *); static void pgm_default_setup_teardown(PROGRAMMER *pgm); @@ -51,89 +51,76 @@ static void pgm_default_enable(PROGRAMMER *pgm, const AVRPART *p) { } static int pgm_default_led(const PROGRAMMER *pgm, int value) { - // If programmer has no LEDs, just do nothing + // If programmer has no LEDs, just do nothing return 0; } - static void pgm_default_powerup_powerdown(const PROGRAMMER *pgm) { - // If programmer does not support powerup/down, just do nothing + // If programmer does not support powerup/down, just do nothing } - void pgm_init_functions(PROGRAMMER *pgm) { - /* - * mandatory functions - these are called without checking to see - * whether they are assigned or not - */ - pgm->initialize = pgm_default_2; - pgm->display = pgm_default_6; - pgm->enable = pgm_default_enable; - pgm->disable = pgm_default_4; - pgm->powerup = pgm_default_powerup_powerdown; - pgm->powerdown = pgm_default_powerup_powerdown; + // Mandatory functions - these are called without checking whether they are assigned + pgm->initialize = pgm_default_2; + pgm->display = pgm_default_6; + pgm->enable = pgm_default_enable; + pgm->disable = pgm_default_4; + pgm->powerup = pgm_default_powerup_powerdown; + pgm->powerdown = pgm_default_powerup_powerdown; pgm->program_enable = pgm_default_2; - pgm->chip_erase = pgm_default_2; - pgm->open = pgm_default_open; - pgm->close = pgm_default_close; - pgm->read_byte = pgm_default_3; - pgm->write_byte = pgm_default_5; - - /* - * predefined functions - these functions have a valid default - * implementation. Hence, they don't need to be defined in - * the programmer. - */ - pgm->rdy_led = pgm_default_led; - pgm->err_led = pgm_default_led; - pgm->pgm_led = pgm_default_led; - pgm->vfy_led = pgm_default_led; - pgm->read_byte_cached = avr_read_byte_cached; + pgm->chip_erase = pgm_default_2; + pgm->open = pgm_default_open; + pgm->close = pgm_default_close; + pgm->read_byte = pgm_default_3; + pgm->write_byte = pgm_default_5; + + // Predefined functions - these functions have a valid default implementation + pgm->rdy_led = pgm_default_led; + pgm->err_led = pgm_default_led; + pgm->pgm_led = pgm_default_led; + pgm->vfy_led = pgm_default_led; + pgm->read_byte_cached = avr_read_byte_cached; pgm->write_byte_cached = avr_write_byte_cached; pgm->chip_erase_cached = avr_chip_erase_cached; pgm->page_erase_cached = avr_page_erase_cached; - pgm->flush_cache = avr_flush_cache; - pgm->reset_cache = avr_reset_cache; - pgm->setup = pgm_default_setup_teardown; - pgm->teardown = pgm_default_setup_teardown; - - /* - * optional functions - these are checked to make sure they are - * assigned before they are called - */ - pgm->unlock = NULL; - pgm->cmd = NULL; - pgm->cmd_tpi = NULL; - pgm->spi = NULL; - pgm->paged_write = NULL; - pgm->paged_load = NULL; - pgm->page_erase = NULL; - pgm->write_setup = NULL; + pgm->flush_cache = avr_flush_cache; + pgm->reset_cache = avr_reset_cache; + pgm->setup = pgm_default_setup_teardown; + pgm->teardown = pgm_default_setup_teardown; + + // Optional functions - these are checked to make sure they are assigned before they are called + pgm->unlock = NULL; + pgm->cmd = NULL; + pgm->cmd_tpi = NULL; + pgm->spi = NULL; + pgm->paged_write = NULL; + pgm->paged_load = NULL; + pgm->page_erase = NULL; + pgm->write_setup = NULL; pgm->read_sig_bytes = NULL; - pgm->read_sib = NULL; - pgm->read_chip_rev = NULL; - pgm->term_keep_alive= NULL; - pgm->end_programming= NULL; - pgm->print_parms = NULL; - pgm->set_vtarget = NULL; - pgm->get_vtarget = NULL; - pgm->set_varef = NULL; - pgm->get_varef = NULL; - pgm->set_fosc = NULL; - pgm->get_fosc = NULL; + pgm->read_sib = NULL; + pgm->read_chip_rev = NULL; + pgm->term_keep_alive = NULL; + pgm->end_programming = NULL; + pgm->print_parms = NULL; + pgm->set_vtarget = NULL; + pgm->get_vtarget = NULL; + pgm->set_varef = NULL; + pgm->get_varef = NULL; + pgm->set_fosc = NULL; + pgm->get_fosc = NULL; pgm->set_sck_period = NULL; pgm->get_sck_period = NULL; - pgm->setpin = NULL; - pgm->getpin = NULL; - pgm->highpulsepin = NULL; + pgm->setpin = NULL; + pgm->getpin = NULL; + pgm->highpulsepin = NULL; pgm->parseexitspecs = NULL; pgm->perform_osccal = NULL; pgm->parseextparams = NULL; - pgm->readonly = NULL; + pgm->readonly = NULL; pgm->flash_readhook = NULL; } - PROGRAMMER *pgm_new(void) { PROGRAMMER *pgm = (PROGRAMMER *) mmt_malloc(sizeof(*pgm)); const char *nulp = cache_string(""); @@ -162,7 +149,7 @@ PROGRAMMER *pgm_new(void) { pgm->baudrate = 0; // Clear pin array - for(int i=0; ipinno[i] = NO_PIN; pin_clear_all(&(pgm->pin[i])); } @@ -172,7 +159,7 @@ PROGRAMMER *pgm_new(void) { pgm_init_functions(pgm); // For allocating static programmer memory - pgm->cookie = NULL; + pgm->cookie = NULL; return pgm; } @@ -191,7 +178,8 @@ void pgm_free(PROGRAMMER *p) { ldestroy_cb(p->hvupdi_support, mmt_f_free); p->hvupdi_support = NULL; } - mmt_free(p->leds); p->leds = NULL; + mmt_free(p->leds); + p->leds = NULL; // Never free const char *, eg, p->desc, which are set by cache_string() // p->cookie was freed by pgm_teardown // Never free cp_flash, cp_eeprom, cp_bootrow or cp_usersig cache structures @@ -217,6 +205,7 @@ PROGRAMMER *pgm_dup(const PROGRAMMER *src) { mmt_free(pgm->cp_usersig); Leds *ls = pgm->leds; + memcpy(pgm, src, sizeof(*pgm)); if(ls && src->leds) memcpy(ls, src->leds, sizeof *ls); @@ -230,12 +219,14 @@ PROGRAMMER *pgm_dup(const PROGRAMMER *src) { if(src->hvupdi_support) for(LNODEID ln = lfirst(src->hvupdi_support); ln; ln = lnext(ln)) { int *ip = mmt_malloc(sizeof(int)); + *ip = *(int *) ldata(ln); ladd(pgm->hvupdi_support, ip); } if(src->usbpid) for(LNODEID ln = lfirst(src->usbpid); ln; ln = lnext(ln)) { int *ip = mmt_malloc(sizeof(int)); + *ip = *(int *) ldata(ln); ladd(pgm->usbpid, ip); } @@ -244,55 +235,52 @@ PROGRAMMER *pgm_dup(const PROGRAMMER *src) { return pgm; } - static void pgm_default(void) { pmsg_error("programmer operation not supported\n"); } - -static int pgm_default_2 (const PROGRAMMER *pgm, const AVRPART *p) { +static int pgm_default_2(const PROGRAMMER *pgm, const AVRPART *p) { pgm_default(); return -1; } -static int pgm_default_3 (const PROGRAMMER *pgm, const AVRPART *p, const AVRMEM *mem, - unsigned long addr, unsigned char * value) { +static int pgm_default_3(const PROGRAMMER *pgm, const AVRPART *p, const AVRMEM *mem, + unsigned long addr, unsigned char *value) { + pgm_default(); return -1; } -static void pgm_default_4 (const PROGRAMMER *pgm) { +static void pgm_default_4(const PROGRAMMER *pgm) { pgm_default(); } -static int pgm_default_5 (const PROGRAMMER *pgm, const AVRPART *p, const AVRMEM *mem, - unsigned long addr, unsigned char data) { +static int pgm_default_5(const PROGRAMMER *pgm, const AVRPART *p, const AVRMEM *mem, + unsigned long addr, unsigned char data) { + pgm_default(); return -1; } -static void pgm_default_6 (const PROGRAMMER *pgm, const char *p) { +static void pgm_default_6(const PROGRAMMER *pgm, const char *p) { pgm_default(); } static void pgm_default_setup_teardown(PROGRAMMER *pgm) { - // ignore - (void)pgm; } - -void programmer_display(PROGRAMMER *pgm, const char * p) { +void programmer_display(PROGRAMMER *pgm, const char *p) { msg_info("%sProgrammer type : %s\n", p, pgm->type); msg_info("%sDescription : %s\n", p, pgm->desc); pgm->display(pgm, p); } - void pgm_display_generic_mask(const PROGRAMMER *pgm, const char *p, unsigned int show) { for(int pbit = 1; pbit < N_PINS; pbit++) - if(show & (1<pin + pbit); + msg_info("%s %-6s = %s\n", p, avr_pin_name(pbit), *pinstr? pinstr: "(not used)"); } } @@ -302,7 +290,9 @@ void pgm_display_generic(const PROGRAMMER *pgm, const char *p) { } // Locate a real programmer entry by partial initial id and set the matching id -PROGRAMMER *locate_programmer_starts_set(const LISTID programmers, const char *pgid, const char **setid, AVRPART *prt) { +PROGRAMMER *locate_programmer_starts_set(const LISTID programmers, const char *pgid, + const char **setid, AVRPART *prt) { + PROGRAMMER *pgm, *matchp; int matches, p1, pmode = prt? prt->prog_modes: -1; const char *matchid; @@ -314,13 +304,15 @@ PROGRAMMER *locate_programmer_starts_set(const LISTID programmers, const char *p l = strlen(pgid); matches = 0; matchp = NULL; - for(LNODEID ln1=lfirst(programmers); ln1; ln1=lnext(ln1)) { + for(LNODEID ln1 = lfirst(programmers); ln1; ln1 = lnext(ln1)) { pgm = ldata(ln1); if(is_programmer(pgm) && (pgm->prog_modes & pmode)) { int thispgmmatch = 0; - for(LNODEID ln2=lfirst(pgm->id); ln2; ln2=lnext(ln2)) { + + for(LNODEID ln2 = lfirst(pgm->id); ln2; ln2 = lnext(ln2)) { const char *id = (const char *) ldata(ln2); - if(p1 == tolower((unsigned char) *id) && !strncasecmp(id, pgid, l)) { // Partial initial match + + if(p1 == tolower((unsigned char) *id) && !strncasecmp(id, pgid, l)) { // Partial initial match if(!thispgmmatch) { // Only count match once for a programmer thispgmmatch++; matchp = pgm; @@ -348,10 +340,12 @@ PROGRAMMER *locate_programmer_starts_set(const LISTID programmers, const char *p // Locate a programmer (or serial adapter) by full name and set the matching id PROGRAMMER *locate_programmer_set(const LISTID programmers, const char *configid, const char **setid) { - for(LNODEID ln1=lfirst(programmers); ln1; ln1=lnext(ln1)) { + for(LNODEID ln1 = lfirst(programmers); ln1; ln1 = lnext(ln1)) { PROGRAMMER *p = ldata(ln1); - for(LNODEID ln2=lfirst(p->id); ln2; ln2=lnext(ln2)) { + + for(LNODEID ln2 = lfirst(p->id); ln2; ln2 = lnext(ln2)) { const char *id = (const char *) ldata(ln2); + if(str_caseeq(configid, id)) { if(setid) *setid = id; @@ -377,23 +371,20 @@ PROGRAMMER *locate_programmer(const LISTID programmers, const char *configid) { * . the line number of the config file this programmer has been defined at * . the "cookie" passed into walk_programmers() (opaque client data) */ -void walk_programmers(LISTID programmers, walk_programmers_cb cb, void *cookie) -{ +void walk_programmers(LISTID programmers, walk_programmers_cb cb, void *cookie) { LNODEID ln1; LNODEID ln2; - PROGRAMMER * p; + PROGRAMMER *p; - for (ln1 = lfirst(programmers); ln1; ln1 = lnext(ln1)) { + for(ln1 = lfirst(programmers); ln1; ln1 = lnext(ln1)) { p = ldata(ln1); - for (ln2=lfirst(p->id); ln2; ln2=lnext(ln2)) { + for(ln2 = lfirst(p->id); ln2; ln2 = lnext(ln2)) { cb(ldata(ln2), p->desc, p->config_file, p->lineno, cookie); } } } -/* - * Compare function to sort the list of programmers - */ +// Compare function to sort the list of programmers static int sort_programmer_compare(const PROGRAMMER *p1, const PROGRAMMER *p2) { if(p1 == NULL || p1->id == NULL || p2 == NULL || p2->id == NULL) return 0; @@ -401,18 +392,14 @@ static int sort_programmer_compare(const PROGRAMMER *p1, const PROGRAMMER *p2) { return strcasecmp(ldata(lfirst(p1->id)), ldata(lfirst(p2->id))); } -/* - * Sort the list of programmers given as "programmers" - */ -void sort_programmers(LISTID programmers) -{ - lsort(programmers,(int (*)(void*, void*)) sort_programmer_compare); +// Sort the list of programmers given as "programmers" +void sort_programmers(LISTID programmers) { + lsort(programmers, (int (*)(void *, void *)) sort_programmer_compare); } - // Soft assignment: some PROGRAMMER entries can be both programmers and serial adapters int is_programmer(const PROGRAMMER *p) { - return p && p->id && lsize(p->id) && p->prog_modes && p->initpgm; + return p && p->id && lsize(p->id) && p->prog_modes && p->initpgm; } int is_serialadapter(const SERIALADAPTER *p) { diff --git a/src/pgm_type.c b/src/pgm_type.c index d80097ee1..59f97de80 100644 --- a/src/pgm_type.c +++ b/src/pgm_type.c @@ -17,8 +17,6 @@ * along with this program. If not, see . */ -/* $Id: pgm.c 976 2011-08-23 21:03:36Z joerg_wunsch $ */ - #include #include @@ -61,67 +59,66 @@ #include "wiring.h" #include "xbee.h" - -const PROGRAMMER_TYPE programmers_types[] = { // Name(s) the programmers call themselves - {"arduino", arduino_initpgm, arduino_desc}, // "Arduino" - {"avr910", avr910_initpgm, avr910_desc}, // "avr910" - {"avrftdi", avrftdi_initpgm, avrftdi_desc}, // "avrftdi" - {"avrftdi_jtag", avrftdi_jtag_initpgm, avrftdi_jtag_desc}, // "avrftdi_jtag" - {"buspirate", buspirate_initpgm, buspirate_desc}, // "BusPirate" - {"buspirate_bb", buspirate_bb_initpgm, buspirate_bb_desc}, // "BusPirate_BB" - {"butterfly", butterfly_initpgm, butterfly_desc}, // "butterfly" - {"butterfly_mk", butterfly_mk_initpgm, butterfly_mk_desc}, // "butterfly_mk" - {"ch341a", ch341a_initpgm, ch341a_desc}, // "ch341a" - {"dryrun", dryrun_initpgm, dryrun_desc}, // "Dryrun" - {"dragon_dw", jtagmkII_dragon_dw_initpgm, jtagmkII_dragon_dw_desc}, // "DRAGON_DW" - {"dragon_hvsp", stk500v2_dragon_hvsp_initpgm, stk500v2_dragon_hvsp_desc}, // "DRAGON_HVSP" - {"dragon_isp", stk500v2_dragon_isp_initpgm, stk500v2_dragon_isp_desc}, // "DRAGON_ISP" - {"dragon_jtag", jtagmkII_dragon_initpgm, jtagmkII_dragon_desc}, // "DRAGON_JTAG" - {"dragon_pdi", jtagmkII_dragon_pdi_initpgm, jtagmkII_dragon_pdi_desc}, // "DRAGON_PDI" - {"dragon_pp", stk500v2_dragon_pp_initpgm, stk500v2_dragon_pp_desc}, // "DRAGON_PP" +const PROGRAMMER_TYPE programmers_types[] = { // Name(s) the programmers call themselves + {"arduino", arduino_initpgm, arduino_desc}, // "Arduino" + {"avr910", avr910_initpgm, avr910_desc}, // "avr910" + {"avrftdi", avrftdi_initpgm, avrftdi_desc}, // "avrftdi" + {"avrftdi_jtag", avrftdi_jtag_initpgm, avrftdi_jtag_desc}, // "avrftdi_jtag" + {"buspirate", buspirate_initpgm, buspirate_desc}, // "BusPirate" + {"buspirate_bb", buspirate_bb_initpgm, buspirate_bb_desc}, // "BusPirate_BB" + {"butterfly", butterfly_initpgm, butterfly_desc}, // "butterfly" + {"butterfly_mk", butterfly_mk_initpgm, butterfly_mk_desc}, // "butterfly_mk" + {"ch341a", ch341a_initpgm, ch341a_desc}, // "ch341a" + {"dryrun", dryrun_initpgm, dryrun_desc}, // "Dryrun" + {"dragon_dw", jtagmkII_dragon_dw_initpgm, jtagmkII_dragon_dw_desc}, // "DRAGON_DW" + {"dragon_hvsp", stk500v2_dragon_hvsp_initpgm, stk500v2_dragon_hvsp_desc}, // "DRAGON_HVSP" + {"dragon_isp", stk500v2_dragon_isp_initpgm, stk500v2_dragon_isp_desc}, // "DRAGON_ISP" + {"dragon_jtag", jtagmkII_dragon_initpgm, jtagmkII_dragon_desc}, // "DRAGON_JTAG" + {"dragon_pdi", jtagmkII_dragon_pdi_initpgm, jtagmkII_dragon_pdi_desc}, // "DRAGON_PDI" + {"dragon_pp", stk500v2_dragon_pp_initpgm, stk500v2_dragon_pp_desc}, // "DRAGON_PP" {"flip1", flip1_initpgm, flip1_desc}, // "flip1" {"flip2", flip2_initpgm, flip2_desc}, // "flip2" {"ftdi_syncbb", ft245r_initpgm, ft245r_desc}, // "ftdi_syncbb" - {"jtagmki", jtagmkI_initpgm, jtagmkI_desc}, // "JTAGMKI" - {"jtagmkii", jtagmkII_initpgm, jtagmkII_desc}, // "JTAGMKII" - {"jtagmkii_avr32", jtagmkII_avr32_initpgm, jtagmkII_avr32_desc}, // "JTAGMKII_AVR32" - {"jtagmkii_dw", jtagmkII_dw_initpgm, jtagmkII_dw_desc}, // "JTAGMKII_DW" - {"jtagmkii_isp", stk500v2_jtagmkII_initpgm, stk500v2_jtagmkII_desc}, // "JTAGMKII_ISP" - {"jtagmkii_pdi", jtagmkII_pdi_initpgm, jtagmkII_pdi_desc}, // "JTAGMKII_PDI" + {"jtagmki", jtagmkI_initpgm, jtagmkI_desc}, // "JTAGMKI" + {"jtagmkii", jtagmkII_initpgm, jtagmkII_desc}, // "JTAGMKII" + {"jtagmkii_avr32", jtagmkII_avr32_initpgm, jtagmkII_avr32_desc}, // "JTAGMKII_AVR32" + {"jtagmkii_dw", jtagmkII_dw_initpgm, jtagmkII_dw_desc}, // "JTAGMKII_DW" + {"jtagmkii_isp", stk500v2_jtagmkII_initpgm, stk500v2_jtagmkII_desc}, // "JTAGMKII_ISP" + {"jtagmkii_pdi", jtagmkII_pdi_initpgm, jtagmkII_pdi_desc}, // "JTAGMKII_PDI" {"jtagmkii_updi", jtagmkII_updi_initpgm, jtagmkII_updi_desc}, // "JTAGMKII_UPDI" - {"jtagice3", jtag3_initpgm, jtag3_desc}, // "JTAGICE3" - {"jtagice3_pdi", jtag3_pdi_initpgm, jtag3_pdi_desc}, // "JTAGICE3_PDI" - {"jtagice3_updi", jtag3_updi_initpgm, jtag3_updi_desc}, // "JTAGICE3_UPDI" - {"jtagice3_dw", jtag3_dw_initpgm, jtag3_dw_desc}, // "JTAGICE3_DW" - {"jtagice3_isp", stk500v2_jtag3_initpgm, stk500v2_jtag3_desc}, // "JTAG3_ISP" - {"jtagice3_tpi", jtag3_tpi_initpgm, jtag3_tpi_desc}, // "JTAGICE3_TPI" - {"linuxgpio", linuxgpio_initpgm, linuxgpio_desc}, // "linuxgpio" - {"linuxspi", linuxspi_initpgm, linuxspi_desc}, // LINUXSPI - {"micronucleus", micronucleus_initpgm, micronucleus_desc}, // "micronucleus" or "Micronucleus V2.0" - {"par", par_initpgm, par_desc}, // "PPI" - {"pickit2", pickit2_initpgm, pickit2_desc}, // "pickit2" - {"pickit5_updi", pickit5_initpgm, pickit5_desc}, // "pickit5" + {"jtagice3", jtag3_initpgm, jtag3_desc}, // "JTAGICE3" + {"jtagice3_pdi", jtag3_pdi_initpgm, jtag3_pdi_desc}, // "JTAGICE3_PDI" + {"jtagice3_updi", jtag3_updi_initpgm, jtag3_updi_desc}, // "JTAGICE3_UPDI" + {"jtagice3_dw", jtag3_dw_initpgm, jtag3_dw_desc}, // "JTAGICE3_DW" + {"jtagice3_isp", stk500v2_jtag3_initpgm, stk500v2_jtag3_desc}, // "JTAG3_ISP" + {"jtagice3_tpi", jtag3_tpi_initpgm, jtag3_tpi_desc}, // "JTAGICE3_TPI" + {"linuxgpio", linuxgpio_initpgm, linuxgpio_desc}, // "linuxgpio" + {"linuxspi", linuxspi_initpgm, linuxspi_desc}, // LINUXSPI + {"micronucleus", micronucleus_initpgm, micronucleus_desc}, // "micronucleus" or "Micronucleus V2.0" + {"par", par_initpgm, par_desc}, // "PPI" + {"pickit2", pickit2_initpgm, pickit2_desc}, // "pickit2" + {"pickit5_updi", pickit5_initpgm, pickit5_desc}, // "pickit5" {"serbb", serbb_initpgm, serbb_desc}, // "SERBB" - {"serialupdi", serialupdi_initpgm, serialupdi_desc}, // "serialupdi" - {"serprog", serprog_initpgm, serprog_desc}, // "serprog" - {"stk500", stk500_initpgm, stk500_desc}, // "STK500" + {"serialupdi", serialupdi_initpgm, serialupdi_desc}, // "serialupdi" + {"serprog", serprog_initpgm, serprog_desc}, // "serprog" + {"stk500", stk500_initpgm, stk500_desc}, // "STK500" {"stk500generic", stk500generic_initpgm, stk500generic_desc}, // "STK500GENERIC" - {"stk500v2", stk500v2_initpgm, stk500v2_desc}, // "STK500V2" - {"stk500hvsp", stk500hvsp_initpgm, stk500hvsp_desc}, // "STK500HVSP" - {"stk500pp", stk500pp_initpgm, stk500pp_desc}, // "STK500PP" - {"stk600", stk600_initpgm, stk600_desc}, // "STK600" - {"stk600hvsp", stk600hvsp_initpgm, stk600hvsp_desc}, // "STK600HVSP" - {"stk600pp", stk600pp_initpgm, stk600pp_desc}, // "STK600PP" - {"teensy", teensy_initpgm, teensy_desc}, // "teensy" - {"urclock", urclock_initpgm, urclock_desc}, // "Urclock" - {"usbasp", usbasp_initpgm, usbasp_desc}, // "usbasp" - {"usbtiny", usbtiny_initpgm, usbtiny_desc}, // "USBtiny" or "usbtiny" - {"wiring", wiring_initpgm, wiring_desc}, // "Wiring" - {"xbee", xbee_initpgm, xbee_desc}, // "XBee" + {"stk500v2", stk500v2_initpgm, stk500v2_desc}, // "STK500V2" + {"stk500hvsp", stk500hvsp_initpgm, stk500hvsp_desc}, // "STK500HVSP" + {"stk500pp", stk500pp_initpgm, stk500pp_desc}, // "STK500PP" + {"stk600", stk600_initpgm, stk600_desc}, // "STK600" + {"stk600hvsp", stk600hvsp_initpgm, stk600hvsp_desc}, // "STK600HVSP" + {"stk600pp", stk600pp_initpgm, stk600pp_desc}, // "STK600PP" + {"teensy", teensy_initpgm, teensy_desc}, // "teensy" + {"urclock", urclock_initpgm, urclock_desc}, // "Urclock" + {"usbasp", usbasp_initpgm, usbasp_desc}, // "usbasp" + {"usbtiny", usbtiny_initpgm, usbtiny_desc}, // "USBtiny" or "usbtiny" + {"wiring", wiring_initpgm, wiring_desc}, // "Wiring" + {"xbee", xbee_initpgm, xbee_desc}, // "XBee" }; const PROGRAMMER_TYPE *locate_programmer_type(const char *id) { - for(size_t i = 0; i < sizeof programmers_types/sizeof*programmers_types; i++) + for(size_t i = 0; i < sizeof programmers_types/sizeof *programmers_types; i++) if(str_caseeq(id, programmers_types[i].id)) return programmers_types + i; @@ -130,14 +127,13 @@ const PROGRAMMER_TYPE *locate_programmer_type(const char *id) { // Return type id given the init function or "" if not found const char *locate_programmer_type_id(void (*initpgm)(PROGRAMMER *pgm)) { - for(size_t i=0; i < sizeof programmers_types/sizeof*programmers_types; i++) + for(size_t i = 0; i < sizeof programmers_types/sizeof *programmers_types; i++) if(programmers_types[i].initpgm == initpgm) return programmers_types[i].id; return ""; } - /* * Iterate over the list of programmer types given in the table above and * call the callback function cb for each entry found. cb is being @@ -148,6 +144,6 @@ const char *locate_programmer_type_id(void (*initpgm)(PROGRAMMER *pgm)) { */ void walk_programmer_types(walk_programmer_types_cb cb, void *cookie) { - for (size_t i = 0; i < sizeof(programmers_types)/sizeof(programmers_types[0]); i++) + for(size_t i = 0; i < sizeof(programmers_types)/sizeof(programmers_types[0]); i++) cb(programmers_types[i].id, programmers_types[i].desc, cookie); } diff --git a/src/pickit2.c b/src/pickit2.c index aa676db68..91b204f20 100644 --- a/src/pickit2.c +++ b/src/pickit2.c @@ -19,9 +19,6 @@ * along with this program. If not, see . */ -/* $Id: pickit2.c 2010-05-03 dbrown$ */ -/* Based on Id: stk500v2.c 836 2009-07-10 22:39:37Z joerg_wunsch */ - /* * avrdude interface for PicKit2 programmer * @@ -62,12 +59,13 @@ #include #include #else + #if defined(HAVE_USB_H) -# include +#include #elif defined(HAVE_LUSB0_USB_H) -# include +#include #else -# error "libusb needs either or " +#error "libusb needs either or " #endif #endif @@ -86,47 +84,45 @@ #define PICKIT2_VID 0x04d8 #define PICKIT2_PID 0x0033 -#define SPI_MAX_CHUNK (64 - 10) // max packet size less the command overhead +#define SPI_MAX_CHUNK (64 - 10) // Max packet size less the command overhead #ifdef WIN32 static HANDLE open_hid(unsigned short vid, unsigned short pid); -static const char *usb_strerror() -{ - return ""; +static const char *usb_strerror() { + return ""; } #else static int usb_open_device(PROGRAMMER *pgm, struct usb_dev_handle **dev, int vid, int pid); -//#define INVALID_HANDLE_VALUE NULL + +// #define INVALID_HANDLE_VALUE NULL #define USB_ERROR_NONE 0 #define USB_ERROR_ACCESS 1 #define USB_ERROR_NOTFOUND 2 #define USB_ERROR_BUSY 16 #define USB_ERROR_IO 5 -#endif // WIN32 +#endif // WIN32 static int pickit2_write_report(const PROGRAMMER *pgm, const unsigned char report[65]); static int pickit2_read_report(const PROGRAMMER *pgm, unsigned char report[65]); #ifndef MIN -#define MIN(X,Y) ((X) < (Y) ? (X) : (Y)) +#define MIN(X, Y) ((X) < (Y)? (X): (Y)) #endif -/* - * Private data for this programmer. - */ -struct pdata -{ +struct pdata { + #ifdef WIN32 - HANDLE usb_handle, write_event, read_event; + HANDLE usb_handle, write_event, read_event; #else - struct usb_dev_handle *usb_handle; // LIBUSB STUFF - int USB_init; // Used in usb_open_device() + struct usb_dev_handle *usb_handle; // LIBUSB STUFF + int USB_init; // Used in usb_open_device() #endif - uint8_t clock_period; // SPI clock period in us - int transaction_timeout; // usb trans timeout in ms + + uint8_t clock_period; // SPI clock period in us + int transaction_timeout; // USB trans timeout in ms }; -#define PDATA(pgm) ((struct pdata *)(pgm->cookie)) +#define my (*(struct pdata *) (pgm->cookie)) #define CMD_NOP 0x5A #define CMD_GET_VERSION 0x76 @@ -162,611 +158,532 @@ struct pdata #define SCR_SPI_LIT_2(v) 0xC7,(v) static void pickit2_setup(PROGRAMMER *pgm) { - pgm->cookie = mmt_malloc(sizeof(struct pdata)); - PDATA(pgm)->transaction_timeout = 1500; // Can be changed with -x timeout=ms - PDATA(pgm)->clock_period = 10; // Can be changed with -x clockrate=us or -B or -i + pgm->cookie = mmt_malloc(sizeof(struct pdata)); + my.transaction_timeout = 1500; // Can be changed with -x timeout=ms + my.clock_period = 10; // Can be changed with -x clockrate=us or -B or -i } static void pickit2_teardown(PROGRAMMER *pgm) { - mmt_free(pgm->cookie); - pgm->cookie = NULL; + mmt_free(pgm->cookie); + pgm->cookie = NULL; } static int pickit2_open(PROGRAMMER *pgm, const char *port) { + #ifdef WIN32 - PDATA(pgm)->usb_handle = open_hid(PICKIT2_VID, PICKIT2_PID); + my.usb_handle = open_hid(PICKIT2_VID, PICKIT2_PID); - if (PDATA(pgm)->usb_handle == INVALID_HANDLE_VALUE) - { - /* no PICkit2 found */ - pmsg_error("cannot find PICkit2 with vid=0x%x pid=0x%x\n", PICKIT2_VID, PICKIT2_PID); - return -1; - } - else - { - // Get the device description while we're at it and overlay it on pgm->desc - short wbuf[80-1]; - char *cbuf = mmt_malloc(sizeof wbuf/sizeof*wbuf + (pgm->desc? strlen(pgm->desc): 0) + 2); - HidD_GetProductString(PDATA(pgm)->usb_handle, wbuf, sizeof wbuf/sizeof*wbuf); - - if(pgm->desc && *pgm->desc) - strcpy(cbuf, pgm->desc); - - // Convert from wide chars and overlay over initial part of desc - for(size_t i = 0; i < sizeof wbuf/sizeof*wbuf && wbuf[i]; i++) - cbuf[i] = (char) wbuf[i]; // TODO what about little/big endian??? - pgm->desc = cache_string(cbuf); - mmt_free(cbuf); - } + if(my.usb_handle == INVALID_HANDLE_VALUE) { + // No PICkit2 found + pmsg_error("cannot find PICkit2 with vid=0x%x pid=0x%x\n", PICKIT2_VID, PICKIT2_PID); + return -1; + } else { + // Get the device description while we're at it and overlay it on pgm->desc + short wbuf[80 - 1]; + char *cbuf = mmt_malloc(sizeof wbuf/sizeof *wbuf + (pgm->desc? strlen(pgm->desc): 0) + 2); + + HidD_GetProductString(my.usb_handle, wbuf, sizeof wbuf/sizeof *wbuf); + + if(pgm->desc && *pgm->desc) + strcpy(cbuf, pgm->desc); + + // Convert from wide chars and overlay over initial part of desc + for(size_t i = 0; i < sizeof wbuf/sizeof *wbuf && wbuf[i]; i++) + cbuf[i] = (char) wbuf[i]; // TODO what about little/big endian??? + pgm->desc = cache_string(cbuf); + mmt_free(cbuf); + } #else - if(usb_open_device(pgm, &(PDATA(pgm)->usb_handle), PICKIT2_VID, PICKIT2_PID) < 0) { - /* no PICkit2 found */ - pmsg_error("cannot find PICkit2 with vid=0x%x pid=0x%x\n", PICKIT2_VID, PICKIT2_PID); - return -1; - } + if(usb_open_device(pgm, &(my.usb_handle), PICKIT2_VID, PICKIT2_PID) < 0) { + // No PICkit2 found + pmsg_error("cannot find PICkit2 with vid=0x%x pid=0x%x\n", PICKIT2_VID, PICKIT2_PID); + return -1; + } #endif - if (pgm->ispdelay > 0) - { - PDATA(pgm)->clock_period = MIN(pgm->ispdelay, 255); - } - else if (pgm->bitclock > 0.0) - { - PDATA(pgm)->clock_period = MIN(pgm->bitclock * 1e6, 255); - } + if(pgm->ispdelay > 0) { + my.clock_period = MIN(pgm->ispdelay, 255); + } else if(pgm->bitclock > 0.0) { + my.clock_period = MIN(pgm->bitclock*1e6, 255); + } - return 0; + return 0; } +static void pickit2_close(PROGRAMMER *pgm) { -static void pickit2_close(PROGRAMMER * pgm) -{ #ifdef WIN32 - CloseHandle(PDATA(pgm)->usb_handle); - CloseHandle(PDATA(pgm)->read_event); - CloseHandle(PDATA(pgm)->write_event); + CloseHandle(my.usb_handle); + CloseHandle(my.read_event); + CloseHandle(my.write_event); #else - usb_close(PDATA(pgm)->usb_handle); -#endif // WIN32 + usb_close(my.usb_handle); +#endif // WIN32 } - static int pickit2_initialize(const PROGRAMMER *pgm, const AVRPART *p) { - unsigned char temp[4]; - memset(temp, 0, sizeof(temp)); - - int errorCode = 0; - - /* set sck period */ - if (pgm->set_sck_period) - pgm->set_sck_period(pgm, pgm->bitclock); - - /* connect to target device -- we'll just ask for the firmware version */ - static const unsigned char report[65] = {0, CMD_GET_VERSION, CMD_END_OF_BUFFER}; - if ((errorCode = pickit2_write_report(pgm, report)) > 0) - { - unsigned char report[65] = {0}; - //memset(report, 0, sizeof(report)); - if ((errorCode = pickit2_read_report(pgm, report)) >= 4) - { - pmsg_notice2("%s firmware version %d.%d.%d\n", pgm->desc, report[1], report[2], report[3]); - - // set the pins, apply reset, - // TO DO: apply vtarget (if requested though -x option) - unsigned char report[65] = - { - 0, CMD_SET_VDD_4(5), - CMD_SET_VPP_4(5), - CMD_EXEC_SCRIPT_2(24), - SCR_SPI_SETUP_PINS_4, // SDO, SDI, SCK - SCR_SET_ICSP_DELAY_2(PDATA(pgm)->clock_period), // slow down the SPI - SCR_VDD_ON, - SCR_MCLR_GND_OFF, // let reset float high - SCR_VPP_PWM_ON, - SCR_DELAY_2(.1), - SCR_VPP_ON, - SCR_DELAY_2(.1), - SCR_VPP_OFF, - SCR_DELAY_2(.01), - - SCR_MCLR_GND_ON, // reset low - programming mode - SCR_DELAY_2(.1), - - SCR_BUSY_LED_ON, - SCR_DELAY_2(.3), - SCR_BUSY_LED_OFF, - - CMD_CLR_DLOAD_BUFF, - CMD_CLR_ULOAD_BUFF, - - CMD_END_OF_BUFFER - }; - - if (pickit2_write_report(pgm, report) < 0) - { - pmsg_error("pickit2_read_report failed (ec %d). %s\n", errorCode, usb_strerror()); - return -1; - } - } - else - { - pmsg_error("pickit2_read_report failed (ec %d). %s\n", errorCode, usb_strerror()); - return -1; - } - } - else - { - pmsg_error("pickit2_write_report failed (ec %d). %s\n", errorCode, usb_strerror()); - return -1; - } - - if (pgm->program_enable) - return pgm->program_enable(pgm, p); - else - return -1; -} - -static void pickit2_disable(const PROGRAMMER *pgm) { - /* make sure all pins are floating & all voltages are off */ - static const unsigned char report[65] = - { - 0, CMD_EXEC_SCRIPT_2(8), - SCR_SET_PINS_2(1,1,0,0), - SCR_SET_AUX_2(1,0), - SCR_MCLR_GND_OFF, + unsigned char temp[4]; + + memset(temp, 0, sizeof(temp)); + + int errorCode = 0; + + // Set sck period + if(pgm->set_sck_period) + pgm->set_sck_period(pgm, pgm->bitclock); + + // Connect to target device -- we'll just ask for the firmware version + static const unsigned char report[65] = { 0, CMD_GET_VERSION, CMD_END_OF_BUFFER }; + if((errorCode = pickit2_write_report(pgm, report)) > 0) { + unsigned char report[65] = { 0 }; + // memset(report, 0, sizeof(report)); + if((errorCode = pickit2_read_report(pgm, report)) >= 4) { + pmsg_notice2("%s firmware version %d.%d.%d\n", pgm->desc, report[1], report[2], report[3]); + + // Set the pins, apply reset. TODO: apply vtarget (if requested though -x option) + unsigned char report[65] = { + 0, CMD_SET_VDD_4(5), + CMD_SET_VPP_4(5), + CMD_EXEC_SCRIPT_2(24), + SCR_SPI_SETUP_PINS_4, // SDO, SDI, SCK + SCR_SET_ICSP_DELAY_2(my.clock_period), // Slow down the SPI + SCR_VDD_ON, + SCR_MCLR_GND_OFF, // Let reset float high + SCR_VPP_PWM_ON, + SCR_DELAY_2(.1), + SCR_VPP_ON, + SCR_DELAY_2(.1), SCR_VPP_OFF, - SCR_VDD_OFF, - SCR_VPP_PWM_OFF, SCR_DELAY_2(.01), + + SCR_MCLR_GND_ON, // Reset low - programming mode + SCR_DELAY_2(.1), + + SCR_BUSY_LED_ON, + SCR_DELAY_2(.3), SCR_BUSY_LED_OFF, + + CMD_CLR_DLOAD_BUFF, + CMD_CLR_ULOAD_BUFF, + CMD_END_OF_BUFFER - }; + }; + + if(pickit2_write_report(pgm, report) < 0) { + pmsg_error("pickit2_read_report failed (ec %d). %s\n", errorCode, usb_strerror()); + return -1; + } + } else { + pmsg_error("pickit2_read_report failed (ec %d). %s\n", errorCode, usb_strerror()); + return -1; + } + } else { + pmsg_error("pickit2_write_report failed (ec %d). %s\n", errorCode, usb_strerror()); + return -1; + } - pickit2_write_report(pgm, report); + if(pgm->program_enable) + return pgm->program_enable(pgm, p); + else + return -1; +} - return; +static void pickit2_disable(const PROGRAMMER *pgm) { + // Make sure all pins are floating & all voltages are off + static const unsigned char report[65] = { + 0, CMD_EXEC_SCRIPT_2(8), + SCR_SET_PINS_2(1, 1, 0, 0), + SCR_SET_AUX_2(1, 0), + SCR_MCLR_GND_OFF, + SCR_VPP_OFF, + SCR_VDD_OFF, + SCR_VPP_PWM_OFF, + SCR_DELAY_2(.01), + SCR_BUSY_LED_OFF, + CMD_END_OF_BUFFER + }; + + pickit2_write_report(pgm, report); + + return; } static void pickit2_enable(PROGRAMMER *pgm, const AVRPART *p) { - return; + return; } static void pickit2_display(const PROGRAMMER *pgm, const char *p) { - DEBUG("%s: found %s version %d.%d.%d\n", progname, p, 1, 1, 1); - return; + DEBUG("%s: found %s version %d.%d.%d\n", progname, p, 1, 1, 1); + return; } #define sendReport(x) #define readReport(x) 0 #if 0 -static int pickit2_rdy_led(const PROGRAMMER *pgm, int value) { - // no rdy led - return 0; +static int pickit2_rdy_led(const PROGRAMMER *pgm, int value) { + // No rdy led + return 0; } -static int pickit2_err_led(const PROGRAMMER *pgm, int value) { - // there is no error led, so just flash the busy led a few times - uint8_t report[65] = - { - 0, CMD_EXEC_SCRIPT_2(9), - SCR_BUSY_LED_ON, - SCR_DELAY_2(.2), - SCR_BUSY_LED_OFF, - SCR_DELAY_2(.2), - SCR_LOOP_3(6, 9), - CMD_END_OF_BUFFER - }; - - // busy stops flashing by itself, so just return - if (!value) - { - return 0; - } +static int pickit2_err_led(const PROGRAMMER *pgm, int value) { + // There is no error led, so just flash the busy led a few times + uint8_t report[65] = { + 0, CMD_EXEC_SCRIPT_2(9), + SCR_BUSY_LED_ON, + SCR_DELAY_2(.2), + SCR_BUSY_LED_OFF, + SCR_DELAY_2(.2), + SCR_LOOP_3(6, 9), + CMD_END_OF_BUFFER + }; + + // Busy stops flashing by itself, so just return + if(!value) { + return 0; + } - return pickit2_write_report(pgm, report) != -1; + return pickit2_write_report(pgm, report) != -1; } #endif -static int pickit2_pgm_led(const PROGRAMMER *pgm, int value) { - // script to set busy led appropriately - uint8_t report[65] = {0, CMD_EXEC_SCRIPT_2(1), - value ? SCR_BUSY_LED_ON : SCR_BUSY_LED_OFF, - CMD_END_OF_BUFFER - }; +static int pickit2_pgm_led(const PROGRAMMER *pgm, int value) { + // Script to set busy led appropriately + uint8_t report[65] = { + 0, CMD_EXEC_SCRIPT_2(1), + value? SCR_BUSY_LED_ON: SCR_BUSY_LED_OFF, + CMD_END_OF_BUFFER + }; - return pickit2_write_report(pgm, report) != -1; + return pickit2_write_report(pgm, report) != -1; } -static int pickit2_vfy_led(const PROGRAMMER *pgm, int value) { - // no such thing - return 0; +static int pickit2_vfy_led(const PROGRAMMER *pgm, int value) { + return 0; } static void pickit2_powerup(const PROGRAMMER *pgm) { - // turn vdd on? } static void pickit2_powerdown(const PROGRAMMER *pgm) { - // do what? - pgm->disable(pgm); + pgm->disable(pgm); } -static int pickit2_program_enable(const PROGRAMMER *pgm, const AVRPART *p) { - unsigned char cmd[4]; - unsigned char res[4]; +static int pickit2_program_enable(const PROGRAMMER *pgm, const AVRPART *p) { + unsigned char cmd[4]; + unsigned char res[4]; - if (p->op[AVR_OP_PGM_ENABLE] == NULL) - { - pmsg_error("program enable instruction not defined for part %s\n", p->desc); - return -1; - } + if(p->op[AVR_OP_PGM_ENABLE] == NULL) { + pmsg_error("program enable instruction not defined for part %s\n", p->desc); + return -1; + } - memset(cmd, 0, sizeof(cmd)); - avr_set_bits(p->op[AVR_OP_PGM_ENABLE], cmd); - pgm->cmd(pgm, cmd, res); + memset(cmd, 0, sizeof(cmd)); + avr_set_bits(p->op[AVR_OP_PGM_ENABLE], cmd); + pgm->cmd(pgm, cmd, res); - { - int i; - msg_debug("%s(): sending command. Resp = ", __func__); + { + int i; - for (i = 0; i < 4; i++) - { - msg_debug("%x ", (int)res[i]); - } - msg_debug("\n"); + msg_debug("%s(): sending command. Resp = ", __func__); + + for(i = 0; i < 4; i++) { + msg_debug("%x ", (int) res[i]); } + msg_debug("\n"); + } - // check for sync character - if (res[2] != cmd[1]) - return -2; + // Check for sync character + if(res[2] != cmd[1]) + return -2; - return 0; + return 0; } -static int pickit2_chip_erase(const PROGRAMMER *pgm, const AVRPART *p) { - unsigned char cmd[4]; - unsigned char res[4]; +static int pickit2_chip_erase(const PROGRAMMER *pgm, const AVRPART *p) { + unsigned char cmd[4]; + unsigned char res[4]; - if (p->op[AVR_OP_CHIP_ERASE] == NULL) - { - pmsg_error("chip erase instruction not defined for part %s\n", p->desc); - return -1; - } + if(p->op[AVR_OP_CHIP_ERASE] == NULL) { + pmsg_error("chip erase instruction not defined for part %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; } static int pickit2_paged_load(const PROGRAMMER *pgm, const AVRPART *p, const AVRMEM *mem, unsigned int page_size, unsigned int addr, unsigned int n_bytes) { - // only supporting flash & eeprom page reads - if ((!mem->paged || page_size <= 1) || (!mem_is_flash(mem) && !mem_is_eeprom(mem))) - { - return -1; - } + // Only supporting flash & eeprom page reads + if((!mem->paged || page_size <= 1) || (!mem_is_flash(mem) && !mem_is_eeprom(mem))) { + return -1; + } - DEBUG( "paged read ps %d, mem %s\n", page_size, mem->desc); + DEBUG("paged read ps %d, mem %s\n", page_size, mem->desc); - OPCODE *readop = 0, *lext = mem->op[AVR_OP_LOAD_EXT_ADDR]; - uint8_t data = 0, cmd[SPI_MAX_CHUNK], res[SPI_MAX_CHUNK]; - unsigned int addr_base; - unsigned int max_addr = addr + n_bytes; + OPCODE *readop = 0, *lext = mem->op[AVR_OP_LOAD_EXT_ADDR]; + uint8_t data = 0, cmd[SPI_MAX_CHUNK], res[SPI_MAX_CHUNK]; + unsigned int addr_base; + unsigned int max_addr = addr + n_bytes; - if (lext) { - memset(cmd, 0, sizeof(cmd)); - avr_set_bits(lext, cmd); - avr_set_addr(lext, cmd, addr/2); - pgm->cmd(pgm, cmd, res); - } + if(lext) { + memset(cmd, 0, sizeof(cmd)); + avr_set_bits(lext, cmd); + avr_set_addr(lext, cmd, addr/2); + pgm->cmd(pgm, cmd, res); + } - for (addr_base = addr; addr_base < max_addr; ) - { - // bytes to send in the next packet -- not necessary as pickit2_spi() handles breaking up - // the data into packets -- but we need to keep transfers frequent so that we can update the - // status indicator bar - uint32_t blockSize = MIN(65536 - (addr_base % 65536), MIN(max_addr - addr_base, SPI_MAX_CHUNK / 4)); - - memset(cmd, 0, sizeof(cmd)); - memset(res, 0, sizeof(res)); - - uint8_t addr_off; - for (addr_off = 0; addr_off < blockSize; addr_off++) - { - int addr = addr_base + addr_off, caddr = addr; - - if (mem->op[AVR_OP_READ_LO] != NULL && mem->op[AVR_OP_READ_HI] != NULL) - { - if (addr & 0x00000001) - readop = mem->op[AVR_OP_READ_HI]; - else - readop = mem->op[AVR_OP_READ_LO]; - - caddr /= 2; - } - else if (mem->op[AVR_OP_READ] != NULL) - { - readop = mem->op[AVR_OP_READ]; - } - else - { - pmsg_error("no read command specified\n"); - return -1; - } - - avr_set_bits(readop, &cmd[addr_off*4]); - avr_set_addr(readop, &cmd[addr_off*4], caddr); - } + for(addr_base = addr; addr_base < max_addr;) { + /* + * Bytes to send in the next packet -- not necessary as pickit2_spi() + * handles breaking up the data into packets -- but we need to keep + * transfers frequent so that we can update the status indicator bar. + */ + uint32_t blockSize = MIN(65536 - (addr_base%65536), MIN(max_addr - addr_base, SPI_MAX_CHUNK/4)); - int bytes_read = pgm->spi(pgm, cmd, res, blockSize*4); + memset(cmd, 0, sizeof(cmd)); + memset(res, 0, sizeof(res)); - if (bytes_read < 0) - { - pmsg_error("failed @ pgm->spi()\n"); - return -1; - } + uint8_t addr_off; - DEBUG( "\npaged_load @ %X, wrote: %d, read: %d bytes\n", addr_base, blockSize*4, bytes_read); + for(addr_off = 0; addr_off < blockSize; addr_off++) { + int addr = addr_base + addr_off, caddr = addr; - for (addr_off = 0; addr_off < bytes_read / 4; addr_off++) - { - data = 0; - avr_get_output(readop, &res[addr_off*4], &data); - mem->buf[addr_base + addr_off] = data; + if(mem->op[AVR_OP_READ_LO] != NULL && mem->op[AVR_OP_READ_HI] != NULL) { + if(addr & 0x00000001) + readop = mem->op[AVR_OP_READ_HI]; + else + readop = mem->op[AVR_OP_READ_LO]; - DEBUG( "%2X(%c)", (int)data, data<0x20?'.':data); - } - DEBUG( "\n"); + caddr /= 2; + } else if(mem->op[AVR_OP_READ] != NULL) { + readop = mem->op[AVR_OP_READ]; + } else { + pmsg_error("no read command specified\n"); + return -1; + } - addr_base += blockSize; + avr_set_bits(readop, &cmd[addr_off*4]); + avr_set_addr(readop, &cmd[addr_off*4], caddr); } - return n_bytes; -} + int bytes_read = pgm->spi(pgm, cmd, res, blockSize*4); + + if(bytes_read < 0) { + pmsg_error("failed @ pgm->spi()\n"); + return -1; + } + DEBUG("\npaged_load @ %X, wrote: %d, read: %d bytes\n", addr_base, blockSize*4, bytes_read); -static int pickit2_commit_page(const PROGRAMMER *pgm, const AVRPART *p, const AVRMEM *mem, - unsigned long addr) -{ - OPCODE * wp, * lext; + for(addr_off = 0; addr_off < bytes_read/4; addr_off++) { + data = 0; + avr_get_output(readop, &res[addr_off*4], &data); + mem->buf[addr_base + addr_off] = data; - wp = mem->op[AVR_OP_WRITEPAGE]; - if (wp == NULL) - { - pmsg_error("memory %s not configured for page writes\n", mem->desc); - return -1; + DEBUG("%2X(%c)", (int) data, data < 0x20? '.': data); } + DEBUG("\n"); - // adjust the address if this memory is word-addressable - if ((mem->op[AVR_OP_LOADPAGE_LO]) || (mem->op[AVR_OP_READ_LO])) - addr /= 2; + addr_base += blockSize; + } - unsigned char cmd[8]; - memset(cmd, 0, sizeof(cmd)); + return n_bytes; +} - // use the "load extended address" command, if available - lext = mem->op[AVR_OP_LOAD_EXT_ADDR]; - if (lext != NULL) - { - avr_set_bits(lext, cmd); - avr_set_addr(lext, cmd, addr); - } +static int pickit2_commit_page(const PROGRAMMER *pgm, const AVRPART *p, const AVRMEM *mem, unsigned long addr) { + OPCODE *wp, *lext; - // make up the write page command in the 2nd cmd position - avr_set_bits(wp, &cmd[4]); - avr_set_addr(wp, &cmd[4], addr); + wp = mem->op[AVR_OP_WRITEPAGE]; + if(wp == NULL) { + pmsg_error("memory %s not configured for page writes\n", mem->desc); + return -1; + } - if (lext != NULL) - { - // write the load extended address cmd && the write_page cmd - pgm->spi(pgm, cmd, NULL, 8); - } - else - { - // write just the write_page cmd - pgm->spi(pgm, &cmd[4], NULL, 4); - } + // Adjust the address if this memory is word-addressable + if((mem->op[AVR_OP_LOADPAGE_LO]) || (mem->op[AVR_OP_READ_LO])) + addr /= 2; - // just delay the max (we could do the delay in the PICkit2 if we wanted) - usleep(mem->max_write_delay); + unsigned char cmd[8]; - return 0; + memset(cmd, 0, sizeof(cmd)); + + // Use the "load extended address" command, if available + lext = mem->op[AVR_OP_LOAD_EXT_ADDR]; + if(lext != NULL) { + avr_set_bits(lext, cmd); + avr_set_addr(lext, cmd, addr); + } + + // Make up the write page command in the 2nd cmd position + avr_set_bits(wp, &cmd[4]); + avr_set_addr(wp, &cmd[4], addr); + + if(lext != NULL) { + // Write the load extended address cmd && the write_page cmd + pgm->spi(pgm, cmd, NULL, 8); + } else { + // Write just the write_page cmd + pgm->spi(pgm, &cmd[4], NULL, 4); + } + + // Just delay the max (we could do the delay in the PICkit2 if we wanted) + usleep(mem->max_write_delay); + + return 0; } -// not actually a paged write, but a bulk/batch write -static int pickit2_paged_write(const PROGRAMMER *pgm, const AVRPART *p, const AVRMEM *mem, - unsigned int page_size, unsigned int addr, unsigned int n_bytes) -{ - // only paged write for flash implemented - if (!mem_is_flash(mem) && !mem_is_eeprom(mem)) - { - pmsg_error("part does not support %d paged write of %s\n", page_size, mem->desc); - return -1; +// Not actually a paged write, but a bulk/batch write +static int pickit2_paged_write(const PROGRAMMER *pgm, const AVRPART *p, const AVRMEM *mem, + unsigned int page_size, unsigned int addr, unsigned int n_bytes) { + // Only paged write for flash implemented + if(!mem_is_flash(mem) && !mem_is_eeprom(mem)) { + pmsg_error("part does not support %d paged write of %s\n", page_size, mem->desc); + return -1; + } + + DEBUG("page size %d mem %s supported: %d\n", page_size, mem->desc, mem->paged); + DEBUG("loadpagehi %x, loadpagelow %x, writepage %x\n", + (int) mem->op[AVR_OP_LOADPAGE_HI], (int) mem->op[AVR_OP_LOADPAGE_LO], (int) mem->op[AVR_OP_WRITEPAGE]); + + OPCODE *writeop; + uint8_t cmd[SPI_MAX_CHUNK], res[SPI_MAX_CHUNK]; + unsigned int addr_base; + unsigned int max_addr = addr + n_bytes; + + for(addr_base = addr; addr_base < max_addr;) { + uint32_t blockSize; + + if(mem->paged) { + blockSize = MIN(page_size - (addr_base%page_size), + MIN(max_addr - addr_base, SPI_MAX_CHUNK/4)); // Bytes remaining in page + } else { + blockSize = 1; } - DEBUG( "page size %d mem %s supported: %d\n", page_size, mem->desc, mem->paged); - DEBUG( "loadpagehi %x, loadpagelow %x, writepage %x\n", (int)mem->op[AVR_OP_LOADPAGE_HI], (int)mem->op[AVR_OP_LOADPAGE_LO], (int)mem->op[AVR_OP_WRITEPAGE]); + memset(cmd, 0, sizeof(cmd)); + memset(res, 0, sizeof(res)); - OPCODE *writeop; - uint8_t cmd[SPI_MAX_CHUNK], res[SPI_MAX_CHUNK]; - unsigned int addr_base; - unsigned int max_addr = addr + n_bytes; + uint8_t addr_off; - for (addr_base = addr; addr_base < max_addr; ) - { - uint32_t blockSize; + for(addr_off = 0; addr_off < blockSize; addr_off++) { + int addr = addr_base + addr_off; + int caddr = 0; - if (mem->paged) - { - blockSize = MIN(page_size - (addr_base % page_size), MIN(max_addr - addr_base, SPI_MAX_CHUNK/4) ); // bytes remaining in page - } + // Determine which memory opcode to use + if(mem->paged && mem->op[AVR_OP_LOADPAGE_HI] && mem->op[AVR_OP_LOADPAGE_LO]) { + if(addr & 0x01) + writeop = mem->op[AVR_OP_LOADPAGE_HI]; else - { - blockSize = 1; - } + writeop = mem->op[AVR_OP_LOADPAGE_LO]; + caddr = addr/2; + } else if(mem->paged && mem->op[AVR_OP_LOADPAGE_LO]) { + writeop = mem->op[AVR_OP_LOADPAGE_LO]; + caddr = addr; + } else if(mem->op[AVR_OP_WRITE_LO]) { + writeop = mem->op[AVR_OP_WRITE_LO]; + caddr = addr; // Maybe this should divide by 2 & use the write_high opcode also + + pmsg_error("%s AVR_OP_WRITE_LO defined only (where is the HIGH command?)\n", mem->desc); + return -1; + } else { + writeop = mem->op[AVR_OP_WRITE]; + caddr = addr; + } - memset(cmd, 0, sizeof(cmd)); - memset(res, 0, sizeof(res)); - - uint8_t addr_off; - for (addr_off = 0; addr_off < blockSize; addr_off++) - { - int addr = addr_base + addr_off; - int caddr = 0; - - /* - * determine which memory opcode to use - */ - if (mem->paged && mem->op[AVR_OP_LOADPAGE_HI] && mem->op[AVR_OP_LOADPAGE_LO]) - { - if (addr & 0x01) - writeop = mem->op[AVR_OP_LOADPAGE_HI]; - else - writeop = mem->op[AVR_OP_LOADPAGE_LO]; - caddr = addr / 2; - } - else if (mem->paged && mem->op[AVR_OP_LOADPAGE_LO]) - { - writeop = mem->op[AVR_OP_LOADPAGE_LO]; - caddr = addr; - } - else if (mem->op[AVR_OP_WRITE_LO]) - { - writeop = mem->op[AVR_OP_WRITE_LO]; - caddr = addr; // maybe this should divide by 2 & use the write_high opcode also - - pmsg_error("%s AVR_OP_WRITE_LO defined only (where is the HIGH command?)\n", mem->desc); - return -1; - } - else - { - writeop = mem->op[AVR_OP_WRITE]; - caddr = addr; - } - - if (writeop == NULL) - { - // not supported! - return -1; - } - - avr_set_bits(writeop, &cmd[addr_off*4]); - avr_set_addr(writeop, &cmd[addr_off*4], caddr); - avr_set_input(writeop, &cmd[addr_off*4], mem->buf[addr]); - } + if(writeop == NULL) // Not supported! + return -1; - int bytes_read = pgm->spi(pgm, cmd, res, blockSize*4); + avr_set_bits(writeop, &cmd[addr_off*4]); + avr_set_addr(writeop, &cmd[addr_off*4], caddr); + avr_set_input(writeop, &cmd[addr_off*4], mem->buf[addr]); + } - if (bytes_read < 0) - { - pmsg_error("failed @ pgm->spi()\n"); - return -1; - } + int bytes_read = pgm->spi(pgm, cmd, res, blockSize*4); - addr_base += blockSize; + if(bytes_read < 0) { + pmsg_error("failed @ pgm->spi()\n"); + return -1; + } - // write the page - this function looks after extended address also - if (mem->paged && (((addr_base % page_size) == 0) || (addr_base == max_addr))) - { - DEBUG( "Calling pickit2_commit_page()\n"); - pickit2_commit_page(pgm, p, mem, addr_base-1); - } - else if (!mem->paged) - { - usleep(mem->max_write_delay); - } + addr_base += blockSize; + + // Write the page - this function looks after extended address also + if(mem->paged && (((addr_base%page_size) == 0) || (addr_base == max_addr))) { + DEBUG("Calling pickit2_commit_page()\n"); + pickit2_commit_page(pgm, p, mem, addr_base - 1); + } else if(!mem->paged) { + usleep(mem->max_write_delay); } + } - return n_bytes; + return n_bytes; } - -static int pickit2_cmd(const PROGRAMMER *pgm, const unsigned char *cmd, - unsigned char *res) -{ - return pgm->spi(pgm, cmd, res, 4); +static int pickit2_cmd(const PROGRAMMER *pgm, const unsigned char *cmd, unsigned char *res) { + return pgm->spi(pgm, cmd, res, 4); } -// breaks up the cmd[] data into packets & sends to the pickit2. Data shifted in is stored in res[]. -static int pickit2_spi(const PROGRAMMER *pgm, const unsigned char *cmd, - unsigned char *res, int n_bytes) -{ - int retval = 0, temp1 = 0, temp2 = 0, count = n_bytes; - - while (count > 0) - { - uint8_t i, blockSize = MIN(count, SPI_MAX_CHUNK); - uint8_t report[65] = {0, CMD_DOWNLOAD_DATA_2(blockSize)}; - uint8_t *repptr = report + 3; - - memset(report + 3, CMD_END_OF_BUFFER, sizeof(report) - 3); - - // append some data to write to SPI - for (i = 0; i < blockSize; i++) - { - *repptr++ = *cmd++; - count--; // 1 less byte to pack - } +// Breaks up the cmd[] data into packets & sends to the pickit2; data shifted in is stored in res[] +static int pickit2_spi(const PROGRAMMER *pgm, const unsigned char *cmd, unsigned char *res, int n_bytes) { + int retval = 0, temp1 = 0, temp2 = 0, count = n_bytes; - if (blockSize == 1) - { - *repptr++ = 0xa6; //CMD_EXECUTE_SCRIPT; - *repptr++ = 1; - *repptr++ = SCR_SPI; - } - else - { - *repptr++ = 0xa6; //CMD_EXECUTE_SCRIPT_2; - *repptr++ = 4; - *repptr++ = SCR_SPI; - *repptr++ = 0xe9; //SCR_LOOP_3; - *repptr++ = 1; - *repptr++ = blockSize - 1; - } + while(count > 0) { + uint8_t i, blockSize = MIN(count, SPI_MAX_CHUNK); + uint8_t report[65] = { 0, CMD_DOWNLOAD_DATA_2(blockSize) }; + uint8_t *repptr = report + 3; - // request the data read to be sent to us - *repptr++ = CMD_UPLOAD_DATA; + memset(report + 3, CMD_END_OF_BUFFER, sizeof(report) - 3); - // check return values - if ((temp1=pickit2_write_report(pgm, report)) < 0 || - (temp2=pickit2_read_report(pgm, report)) < 0) - { - return -1; - }/* - else - { - int i; - DEBUG( "in spi. wrote %d, read %d\n", temp1, temp2); + // Append some data to write to SPI + for(i = 0; i < blockSize; i++) { + *repptr++ = *cmd++; + count--; // 1 less byte to pack + } + + if(blockSize == 1) { + *repptr++ = 0xa6; // CMD_EXECUTE_SCRIPT; + *repptr++ = 1; + *repptr++ = SCR_SPI; + } else { + *repptr++ = 0xa6; // CMD_EXECUTE_SCRIPT_2; + *repptr++ = 4; + *repptr++ = SCR_SPI; + *repptr++ = 0xe9; // SCR_LOOP_3; + *repptr++ = 1; + *repptr++ = blockSize - 1; + } - for (i = 0; i < temp2; i++) - { - DEBUG( "%2.2x ", report[i]); - } + // Request the data read to be sent to us + *repptr++ = CMD_UPLOAD_DATA; - DEBUG( "\n"); - }*/ + // Check return values + if((temp1 = pickit2_write_report(pgm, report)) < 0 || (temp2 = pickit2_read_report(pgm, report)) < 0) { + return -1; + } - retval = report[1]; // upload-length field - repptr = &report[2]; // actual data starts here + retval = report[1]; // Upload-length field + repptr = &report[2]; // Actual data starts here - if (res) // copy data if user has specified a storage location - { - memcpy(res, repptr, retval); - res += retval; - } + if(res) { // Copy data if user has specified a storage location + memcpy(res, repptr, retval); + res += retval; } + } - return n_bytes; + return n_bytes; } #ifdef WIN32 + /* Func: open_hid() Desc: finds & opens device having specified VID & PID. @@ -779,511 +696,420 @@ static int pickit2_spi(const PROGRAMMER *pgm, const unsigned char *cmd, Date: 7/18/05 by Jan Axelson (jan@Lvr.com) */ -static HANDLE open_hid(unsigned short vid, unsigned short pid) -{ - //Use a series of API calls to find a HID with a specified Vendor IF and Product ID. - HANDLE returnHandle = INVALID_HANDLE_VALUE; - HIDD_ATTRIBUTES Attributes; -// DWORD DeviceUsage; - SP_DEVICE_INTERFACE_DATA devInfoData; - BOOL LastDevice = FALSE; - int MemberIndex = 0; - LONG Result; - - // were global, now just local scrap - DWORD Length = 0; - PSP_DEVICE_INTERFACE_DETAIL_DATA detailData = NULL; - HANDLE DeviceHandle=NULL; - GUID HidGuid; - HANDLE hDevInfo; - ULONG Required; - BOOL MyDeviceDetected = 0; +static HANDLE open_hid(unsigned short vid, unsigned short pid) { + // Use a series of API calls to find a HID with a specified Vendor IF and Product ID + HANDLE returnHandle = INVALID_HANDLE_VALUE; + HIDD_ATTRIBUTES Attributes; +// DWORD DeviceUsage; + SP_DEVICE_INTERFACE_DATA devInfoData; + BOOL LastDevice = FALSE; + int MemberIndex = 0; + LONG Result; + + // Were global, now just local scrap + DWORD Length = 0; + PSP_DEVICE_INTERFACE_DETAIL_DATA detailData = NULL; + HANDLE DeviceHandle = NULL; + GUID HidGuid; + HANDLE hDevInfo; + ULONG Required; + BOOL MyDeviceDetected = 0; + + /* + API function: HidD_GetHidGuid + Get the GUID for all system HIDs. + Returns: the GUID in HidGuid. + */ + + HidD_GetHidGuid(&HidGuid); + DEBUG("\nHidD_GetHidGuid returned.\n"); + + /* + API function: SetupDiGetClassDevs + Returns: a handle to a device information set for all installed devices. + Requires: the GUID returned by GetHidGuid. + */ + + hDevInfo = SetupDiGetClassDevs(&HidGuid, NULL, NULL, DIGCF_PRESENT | DIGCF_INTERFACEDEVICE); + + DEBUG("\nSetupDiGetClassDevs returned 0x%x\n", hDevInfo); + devInfoData.cbSize = sizeof(devInfoData); + + /* + * Step through the available devices looking for the one we want. Quit on + * detecting the desired device or checking all available devices without + * success. + */ + + MemberIndex = 0; + LastDevice = FALSE; + + do { /* - API function: HidD_GetHidGuid - Get the GUID for all system HIDs. - Returns: the GUID in HidGuid. - */ + API function: SetupDiEnumDeviceInterfaces + On return, MyDeviceInterfaceData contains the handle to a + SP_DEVICE_INTERFACE_DATA structure for a detected device. + Requires: + The DeviceInfoSet returned in SetupDiGetClassDevs. + The HidGuid returned in GetHidGuid. + An index to specify a device. + */ - HidD_GetHidGuid(&HidGuid); - DEBUG("\nHidD_GetHidGuid returned.\n"); + Result = SetupDiEnumDeviceInterfaces(hDevInfo, 0, &HidGuid, MemberIndex, &devInfoData); - /* - API function: SetupDiGetClassDevs - Returns: a handle to a device information set for all installed devices. - Requires: the GUID returned by GetHidGuid. - */ - - hDevInfo=SetupDiGetClassDevs - (&HidGuid, - NULL, - NULL, - DIGCF_PRESENT|DIGCF_INTERFACEDEVICE); - - DEBUG("\nSetupDiGetClassDevs returned 0x%x\n", hDevInfo); - devInfoData.cbSize = sizeof(devInfoData); - - //Step through the available devices looking for the one we want. - //Quit on detecting the desired device or checking all available devices without success. - - MemberIndex = 0; - LastDevice = FALSE; - - do - { - /* - API function: SetupDiEnumDeviceInterfaces - On return, MyDeviceInterfaceData contains the handle to a - SP_DEVICE_INTERFACE_DATA structure for a detected device. - Requires: - The DeviceInfoSet returned in SetupDiGetClassDevs. - The HidGuid returned in GetHidGuid. - An index to specify a device. - */ - - - Result=SetupDiEnumDeviceInterfaces - (hDevInfo, - 0, - &HidGuid, - MemberIndex, - &devInfoData); - - DEBUG("\nSetupDiEnumDeviceInterfaces returned 0x%x\n", Result); - - if (Result != 0) - { - //A device has been detected, so get more information about it. - - /* - API function: SetupDiGetDeviceInterfaceDetail - Returns: an SP_DEVICE_INTERFACE_DETAIL_DATA structure - containing information about a device. - To retrieve the information, call this function twice. - The first time returns the size of the structure in Length. - The second time returns a pointer to the data in DeviceInfoSet. - Requires: - A DeviceInfoSet returned by SetupDiGetClassDevs - The SP_DEVICE_INTERFACE_DATA structure returned by SetupDiEnumDeviceInterfaces. - - The final parameter is an optional pointer to an SP_DEV_INFO_DATA structure. - This application doesn't retrieve or use the structure. - If retrieving the structure, set - MyDeviceInfoData.cbSize = length of MyDeviceInfoData. - and pass the structure's address. - */ - - //Get the Length value. - //The call will return with a "buffer too small" error which can be ignored. - Result = SetupDiGetDeviceInterfaceDetail - (hDevInfo, - &devInfoData, - NULL, - 0, - &Length, - NULL); - - DEBUG("\nSetupDiGetDeviceInterfaceDetail returned 0x%x\n", Result); - - //Allocate memory for the hDevInfo structure, using the returned Length. - - detailData = (PSP_DEVICE_INTERFACE_DETAIL_DATA) mmt_malloc(Length); - - //Set cbSize in the detailData structure. - - detailData -> cbSize = sizeof(SP_DEVICE_INTERFACE_DETAIL_DATA); - - //Call the function again, this time passing it the returned buffer size. - - Result = SetupDiGetDeviceInterfaceDetail - (hDevInfo, - &devInfoData, - detailData, - Length, - &Required, - NULL); - - // Open a handle to the device. - // To enable retrieving information about a system mouse or keyboard, - // don't request Read or Write access for this handle. - - /* - API function: CreateFile - Returns: a handle that enables reading and writing to the device. - Requires: - The DevicePath in the detailData structure - returned by SetupDiGetDeviceInterfaceDetail. - */ - - DeviceHandle=CreateFile - (detailData->DevicePath, - 0, - FILE_SHARE_READ|FILE_SHARE_WRITE, - (LPSECURITY_ATTRIBUTES)NULL, - OPEN_EXISTING, - 0, - NULL); - - DEBUG("CreateFile(): %s\n", detailData->DevicePath); - /* - API function: HidD_GetAttributes - Requests information from the device. - Requires: the handle returned by CreateFile. - Returns: a HIDD_ATTRIBUTES structure containing - the Vendor ID, Product ID, and Product Version Number. - Use this information to decide if the detected device is - the one we're looking for. - */ - - //Set the Size to the number of bytes in the structure. - - Attributes.Size = sizeof(Attributes); - - Result = HidD_GetAttributes - (DeviceHandle, - &Attributes); - - DEBUG("HidD_GetAttributes returned 0x%x\n", Result); - DEBUG("VID: %.4X PID: %.4X\n", Attributes.VendorID, Attributes.ProductID); - - //Is it the desired device? - MyDeviceDetected = FALSE; - if (Attributes.VendorID == vid) - { - if (Attributes.ProductID == pid) - { - //Both the Vendor ID and Product ID match. - - MyDeviceDetected = TRUE; - - // Get a handle for us to use. - - returnHandle = CreateFile - (detailData->DevicePath, - GENERIC_WRITE | GENERIC_READ, - FILE_SHARE_READ|FILE_SHARE_WRITE, - (LPSECURITY_ATTRIBUTES)NULL, - OPEN_EXISTING, - FILE_FLAG_OVERLAPPED, - NULL); + DEBUG("\nSetupDiEnumDeviceInterfaces returned 0x%x\n", Result); + + if(Result != 0) { + //A device has been detected, so get more information about it. + + /* + API function: SetupDiGetDeviceInterfaceDetail + Returns: an SP_DEVICE_INTERFACE_DETAIL_DATA structure + containing information about a device. + To retrieve the information, call this function twice. + The first time returns the size of the structure in Length. + The second time returns a pointer to the data in DeviceInfoSet. + Requires: + A DeviceInfoSet returned by SetupDiGetClassDevs + The SP_DEVICE_INTERFACE_DATA structure returned by SetupDiEnumDeviceInterfaces. - } //if (Attributes.ProductID == ProductID) + The final parameter is an optional pointer to an SP_DEV_INFO_DATA structure. + This application doesn't retrieve or use the structure. + If retrieving the structure, set + MyDeviceInfoData.cbSize = length of MyDeviceInfoData. + and pass the structure's address. + */ - else - //The Product ID doesn't match. + // Get the Length value; the call will return with a "buffer too small" error which can be ignored + Result = SetupDiGetDeviceInterfaceDetail(hDevInfo, &devInfoData, NULL, 0, &Length, NULL); - CloseHandle(DeviceHandle); + DEBUG("\nSetupDiGetDeviceInterfaceDetail returned 0x%x\n", Result); - } //if (Attributes.VendorID == VendorID) + // Allocate memory for the hDevInfo structure, using the returned Length + detailData = (PSP_DEVICE_INTERFACE_DETAIL_DATA) mmt_malloc(Length); - else - //The Vendor ID doesn't match. + // Set cbSize in the detailData structure + detailData->cbSize = sizeof(SP_DEVICE_INTERFACE_DETAIL_DATA); - CloseHandle(DeviceHandle); + // Call the function again, this time passing it the returned buffer size + Result = SetupDiGetDeviceInterfaceDetail(hDevInfo, &devInfoData, detailData, Length, &Required, NULL); - //Free the memory used by the detailData structure (no longer needed). + /* + * Open a handle to the device. + * To enable retrieving information about a system mouse or keyboard, + * don't request Read or Write access for this handle. + */ - mmt_free(detailData); + /* + API function: CreateFile + Returns: a handle that enables reading and writing to the device. + Requires: + The DevicePath in the detailData structure + returned by SetupDiGetDeviceInterfaceDetail. + */ - } //if (Result != 0) + DeviceHandle = CreateFile(detailData->DevicePath, 0, + FILE_SHARE_READ | FILE_SHARE_WRITE, (LPSECURITY_ATTRIBUTES) NULL, OPEN_EXISTING, 0, NULL); - else - //SetupDiEnumDeviceInterfaces returned 0, so there are no more devices to check. + DEBUG("CreateFile(): %s\n", detailData->DevicePath); + /* + API function: HidD_GetAttributes + Requests information from the device. + Requires: the handle returned by CreateFile. + Returns: a HIDD_ATTRIBUTES structure containing + the Vendor ID, Product ID, and Product Version Number. + Use this information to decide if the detected device is + the one we're looking for. + */ - LastDevice=TRUE; + //Set the Size to the number of bytes in the structure. - //If we haven't found the device yet, and haven't tried every available device, - //try the next one. + Attributes.Size = sizeof(Attributes); - MemberIndex = MemberIndex + 1; + Result = HidD_GetAttributes(DeviceHandle, &Attributes); - } //do + DEBUG("HidD_GetAttributes returned 0x%x\n", Result); + DEBUG("VID: %.4X PID: %.4X\n", Attributes.VendorID, Attributes.ProductID); - while ((LastDevice == FALSE) && (MyDeviceDetected == FALSE)); + //Is it the desired device? + MyDeviceDetected = FALSE; + if(Attributes.VendorID == vid) { + if(Attributes.ProductID == pid) { + //Both the Vendor ID and Product ID match. - if (MyDeviceDetected == FALSE) - DEBUG("Device not detected\n"); - else - DEBUG("Device detected\n"); + MyDeviceDetected = TRUE; - //Free the memory reserved for hDevInfo by SetupDiClassDevs. + // Get a handle for us to use. - DEBUG("Calling SetupDiDestroyDeviceInfoList\n"); - SetupDiDestroyDeviceInfoList(hDevInfo); + returnHandle = CreateFile(detailData->DevicePath, + GENERIC_WRITE | GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE, + (LPSECURITY_ATTRIBUTES) NULL, OPEN_EXISTING, FILE_FLAG_OVERLAPPED, NULL); - return returnHandle; + } else // The Product ID doesn't match + CloseHandle(DeviceHandle); + } else // The Vendor ID doesn't match + CloseHandle(DeviceHandle); + + // Free the memory used by the detailData structure (no longer needed) + mmt_free(detailData); + } else // if(Result != 0) + // SetupDiEnumDeviceInterfaces returned 0, so there are no more devices to check. + LastDevice = TRUE; + + // If we haven't found the device yet, and haven't tried every available device, try the next one + MemberIndex = MemberIndex + 1; + } while((LastDevice == FALSE) && (MyDeviceDetected == FALSE)); + + if(MyDeviceDetected == FALSE) + DEBUG("Device not detected\n"); + else + DEBUG("Device detected\n"); + + // Free the memory reserved for hDevInfo by SetupDiClassDevs + + DEBUG("Calling SetupDiDestroyDeviceInfoList\n"); + SetupDiDestroyDeviceInfoList(hDevInfo); + + return returnHandle; } -// simple read with timeout +// Simple read with timeout static int usb_read_interrupt(const PROGRAMMER *pgm, void *buff, int size, int timeout) { - OVERLAPPED ovr; - DWORD bytesRead = 0; + OVERLAPPED ovr; + DWORD bytesRead = 0; - if (PDATA(pgm)->read_event == NULL) - { - PDATA(pgm)->read_event = CreateEvent(0, 0, 0, 0); - } + if(my.read_event == NULL) { + my.read_event = CreateEvent(0, 0, 0, 0); + } - memset(&ovr, 0, sizeof(ovr)); - ovr.hEvent = PDATA(pgm)->read_event; + memset(&ovr, 0, sizeof(ovr)); + ovr.hEvent = my.read_event; - ReadFile(PDATA(pgm)->usb_handle, buff, size, &bytesRead, &ovr); - if (WaitForSingleObject(PDATA(pgm)->read_event, timeout) == WAIT_TIMEOUT) - { - CancelIo(PDATA(pgm)->usb_handle); - return -1; - } + ReadFile(my.usb_handle, buff, size, &bytesRead, &ovr); + if(WaitForSingleObject(my.read_event, timeout) == WAIT_TIMEOUT) { + CancelIo(my.usb_handle); + return -1; + } - GetOverlappedResult(PDATA(pgm)->usb_handle, &ovr, &bytesRead, 0); + GetOverlappedResult(my.usb_handle, &ovr, &bytesRead, 0); - return bytesRead > 0? (int) bytesRead: -1; + return bytesRead > 0? (int) bytesRead: -1; } -// simple write with timeout +// Simple write with timeout static int usb_write_interrupt(const PROGRAMMER *pgm, const void *buff, int size, int timeout) { - OVERLAPPED ovr; - DWORD bytesWritten = 0; + OVERLAPPED ovr; + DWORD bytesWritten = 0; - if (PDATA(pgm)->write_event == NULL) - { - PDATA(pgm)->write_event = CreateEvent(0, 0, 0, 0); - } + if(my.write_event == NULL) { + my.write_event = CreateEvent(0, 0, 0, 0); + } - memset(&ovr, 0, sizeof(ovr)); - ovr.hEvent = PDATA(pgm)->write_event; + memset(&ovr, 0, sizeof(ovr)); + ovr.hEvent = my.write_event; - WriteFile(PDATA(pgm)->usb_handle, buff, size, &bytesWritten, &ovr); - if (WaitForSingleObject(PDATA(pgm)->write_event, timeout) == WAIT_TIMEOUT) - { - CancelIo(PDATA(pgm)->usb_handle); - return -1; - } + WriteFile(my.usb_handle, buff, size, &bytesWritten, &ovr); + if(WaitForSingleObject(my.write_event, timeout) == WAIT_TIMEOUT) { + CancelIo(my.usb_handle); + return -1; + } - GetOverlappedResult(PDATA(pgm)->usb_handle, &ovr, &bytesWritten, 0); + GetOverlappedResult(my.usb_handle, &ovr, &bytesWritten, 0); - return bytesWritten > 0? (int) bytesWritten: -1; + return bytesWritten > 0? (int) bytesWritten: -1; } static int pickit2_write_report(const PROGRAMMER *pgm, const unsigned char report[65]) { - return usb_write_interrupt(pgm, report, 65, PDATA(pgm)->transaction_timeout); // XXX + return usb_write_interrupt(pgm, report, 65, my.transaction_timeout); // XXX } static int pickit2_read_report(const PROGRAMMER *pgm, unsigned char report[65]) { - return usb_read_interrupt(pgm, report, 65, PDATA(pgm)->transaction_timeout); + return usb_read_interrupt(pgm, report, 65, my.transaction_timeout); } -#else // WIN32 -/* taken (modified) from avrdude usbasp.c */ +#else // WIN32 + +// Taken (modified) from avrdude usbasp.c static int usb_open_device(PROGRAMMER *pgm, struct usb_dev_handle **device, int vendor, int product) { - struct usb_bus *bus; - struct usb_device *dev; - usb_dev_handle *handle = NULL; - int errorCode = USB_ERROR_NOTFOUND; - - if(!PDATA(pgm)->USB_init) { - PDATA(pgm)->USB_init = 1; - usb_init(); - } - usb_find_busses(); - usb_find_devices(); - for (bus=usb_get_busses(); bus; bus=bus->next) - { - for (dev=bus->devices; dev; dev=dev->next) - { - DEBUG( "Enumerating device list.. VID: 0x%4.4x, PID: 0x%4.4x\n", dev->descriptor.idVendor, dev->descriptor.idProduct); - if (dev->descriptor.idVendor == vendor && dev->descriptor.idProduct == product) - { - /* we need to open the device in order to query strings */ - handle = usb_open(dev); - if (handle == NULL) - { - errorCode = USB_ERROR_ACCESS; - pmsg_warning("cannot open USB device: %s\n", usb_strerror()); - continue; - } - - // return with opened device handle - else - { - msg_notice2("device %p seemed to open OK\n", handle); - - if ((errorCode = usb_set_configuration(handle, 1)) < 0) - { - cx->usb_access_error = 1; - pmsg_ext_error("cannot set configuration, error code %d, %s\n", - errorCode, usb_strerror()); - } - - if ((errorCode = usb_claim_interface(handle, 0)) < 0) - { - cx->usb_access_error = 1; - pmsg_ext_error("cannot claim interface, error code %d, %s\n", - errorCode, usb_strerror()); - } - - errorCode = 0; - *device = handle; - return 0; - } - } + struct usb_bus *bus; + struct usb_device *dev; + usb_dev_handle *handle = NULL; + int errorCode = USB_ERROR_NOTFOUND; + + if(!my.USB_init) { + my.USB_init = 1; + usb_init(); + } + usb_find_busses(); + usb_find_devices(); + for(bus = usb_get_busses(); bus; bus = bus->next) { + for(dev = bus->devices; dev; dev = dev->next) { + DEBUG("Enumerating device list.. VID: 0x%4.4x, PID: 0x%4.4x\n", + dev->descriptor.idVendor, dev->descriptor.idProduct); + if(dev->descriptor.idVendor == vendor && dev->descriptor.idProduct == product) { + // We need to open the device in order to query strings + handle = usb_open(dev); + if(handle == NULL) { + errorCode = USB_ERROR_ACCESS; + pmsg_warning("cannot open USB device: %s\n", usb_strerror()); + continue; + } else { // Return with opened device handle + msg_notice2("device %p seemed to open OK\n", handle); + if((errorCode = usb_set_configuration(handle, 1)) < 0) { + cx->usb_access_error = 1; + pmsg_ext_error("cannot set configuration, error code %d, %s\n", + errorCode, usb_strerror()); + } + if((errorCode = usb_claim_interface(handle, 0)) < 0) { + cx->usb_access_error = 1; + pmsg_ext_error("cannot claim interface, error code %d, %s\n", + errorCode, usb_strerror()); + } + + errorCode = 0; + *device = handle; + return 0; } + } } + } - return -1; + return -1; } static int pickit2_write_report(const PROGRAMMER *pgm, const unsigned char report[65]) { - // endpoint 1 OUT?? - return usb_interrupt_write(PDATA(pgm)->usb_handle, USB_ENDPOINT_OUT | 1, (char*)(report+1), 64, PDATA(pgm)->transaction_timeout); + // Endpoint 1 OUT?? + return usb_interrupt_write(my.usb_handle, USB_ENDPOINT_OUT | 1, (char *) (report + 1), 64, + my.transaction_timeout); } static int pickit2_read_report(const PROGRAMMER *pgm, unsigned char report[65]) { - // endpoint 1 IN?? - return usb_interrupt_read(PDATA(pgm)->usb_handle, USB_ENDPOINT_IN | 1, (char*)(report+1), 64, PDATA(pgm)->transaction_timeout); + // Endpoint 1 IN?? + return usb_interrupt_read(my.usb_handle, USB_ENDPOINT_IN | 1, (char *) (report + 1), 64, + my.transaction_timeout); } -#endif // WIN32 - -static int pickit2_parseextparams(const PROGRAMMER *pgm, const LISTID extparms) { - int rv = 0; - bool help = false; - - for (LNODEID ln = lfirst(extparms); ln; ln = lnext(ln)) - { - const char *extended_param = ldata(ln); - - if (str_starts(extended_param, "clockrate=")) - { - int clock_rate; - if (sscanf(extended_param, "clockrate=%i", &clock_rate) != 1 || clock_rate <= 0) - { - pmsg_error("invalid clock rate in -x %s\n", extended_param); - rv = -1; - break; - } - - int clock_period = MIN(1000000 / clock_rate, 255); // max period is 255 - clock_rate = (int)(1000000 / (clock_period + 5e-7)); // assume highest speed is 2MHz - should probably check this - - pmsg_notice2("%s(): effective clock rate set to 0x%02x\n", __func__, clock_rate); - PDATA(pgm)->clock_period = clock_period; - continue; - } +#endif // WIN32 - if (str_starts(extended_param, "timeout=")) - { - int timeout; - if (sscanf(extended_param, "timeout=%i", &timeout) != 1 || timeout <= 0) - { - pmsg_error("invalid timeout in -x %s\n", extended_param); - rv = -1; - break; - } - - pmsg_notice2("%s(): usb timeout set to 0x%02x\n", __func__, timeout); - PDATA(pgm)->transaction_timeout = timeout; - continue; - } +static int pickit2_parseextparams(const PROGRAMMER *pgm, const LISTID extparms) { + int rv = 0; + bool help = false; - if (str_eq(extended_param, "help")) - { - help = true; - rv = LIBAVRDUDE_EXIT; - } + for(LNODEID ln = lfirst(extparms); ln; ln = lnext(ln)) { + const char *extended_param = ldata(ln); - if (!help) - { - pmsg_error("invalid extended parameter -x %s\n", extended_param); - rv = -1; - } - msg_error("%s -c %s extended options:\n", progname, pgmid); - msg_error(" -x clockrate= Set the SPI clock rate to Hz\n"); - msg_error(" -x timeout= Set the timeout for USB read/write to ms\n"); - msg_error(" -x help Show this help menu and exit\n"); - return rv; - } + if(str_starts(extended_param, "clockrate=")) { + int clock_rate; - return rv; -} + if(sscanf(extended_param, "clockrate=%i", &clock_rate) != 1 || clock_rate <= 0) { + pmsg_error("invalid clock rate in -x %s\n", extended_param); + rv = -1; + break; + } + int clock_period = MIN(1000000/clock_rate, 255); // Max period is 255 -void pickit2_initpgm(PROGRAMMER *pgm) { - /* - * mandatory functions - these are called without checking to see - * whether they are assigned or not - */ + clock_rate = (int) (1000000/(clock_period + 5e-7)); // Assume highest speed is 2MHz - pgm->initialize = pickit2_initialize; - pgm->display = pickit2_display; - pgm->enable = pickit2_enable; - pgm->disable = pickit2_disable; - pgm->powerup = pickit2_powerup; - pgm->powerdown = pickit2_powerdown; - pgm->program_enable = pickit2_program_enable; - pgm->chip_erase = pickit2_chip_erase; - pgm->open = pickit2_open; - pgm->close = pickit2_close; + pmsg_notice2("%s(): effective clock rate set to 0x%02x\n", __func__, clock_rate); + my.clock_period = clock_period; + continue; + } - pgm->read_byte = avr_read_byte_default; - pgm->write_byte = avr_write_byte_default; + if(str_starts(extended_param, "timeout=")) { + int timeout; - /* - * predefined functions - these functions have a valid default - * implementation. Hence, they don't need to be defined in - * the programmer. - */ - //pgm->rdy_led = pickit2_rdy_led; - //pgm->err_led = pickit2_err_led; - pgm->pgm_led = pickit2_pgm_led; - pgm->vfy_led = pickit2_vfy_led; + if(sscanf(extended_param, "timeout=%i", &timeout) != 1 || timeout <= 0) { + pmsg_error("invalid timeout in -x %s\n", extended_param); + rv = -1; + break; + } - /* - * optional functions - these are checked to make sure they are - * assigned before they are called - */ + pmsg_notice2("%s(): usb timeout set to 0x%02x\n", __func__, timeout); + my.transaction_timeout = timeout; + continue; + } - pgm->cmd = pickit2_cmd; - pgm->spi = pickit2_spi; - pgm->paged_write = pickit2_paged_write; - pgm->paged_load = pickit2_paged_load; - //pgm->write_setup = NULL; - //pgm->read_sig_bytes = NULL; - //pgm->set_vtarget = NULL;//pickit2_vtarget; - //pgm->set_varef = NULL; - //pgm->set_fosc = NULL; - //pgm->perform_osccal = NULL; + if(str_eq(extended_param, "help")) { + help = true; + rv = LIBAVRDUDE_EXIT; + } - pgm->parseextparams = pickit2_parseextparams; + if(!help) { + pmsg_error("invalid extended parameter -x %s\n", extended_param); + rv = -1; + } + msg_error("%s -c %s extended options:\n", progname, pgmid); + msg_error(" -x clockrate= Set the SPI clock rate to Hz\n"); + msg_error(" -x timeout= Set the timeout for USB read/write to ms\n"); + msg_error(" -x help Show this help menu and exit\n"); + return rv; + } - pgm->setup = pickit2_setup; - pgm->teardown = pickit2_teardown; - // pgm->page_size = 256; // not sure what this does ... maybe the max page size that the page read/write function can handle + return rv; +} - strncpy(pgm->type, "pickit2", sizeof(pgm->type)); +void pickit2_initpgm(PROGRAMMER *pgm) { + // Mandatory functions - these are called without checking whether they are assigned + pgm->initialize = pickit2_initialize; + pgm->display = pickit2_display; + pgm->enable = pickit2_enable; + pgm->disable = pickit2_disable; + pgm->powerup = pickit2_powerup; + pgm->powerdown = pickit2_powerdown; + pgm->program_enable = pickit2_program_enable; + pgm->chip_erase = pickit2_chip_erase; + pgm->open = pickit2_open; + pgm->close = pickit2_close; + + pgm->read_byte = avr_read_byte_default; + pgm->write_byte = avr_write_byte_default; + + // Predefined functions - these functions have a valid default implementation + pgm->pgm_led = pickit2_pgm_led; + pgm->vfy_led = pickit2_vfy_led; + // pgm->rdy_led = pickit2_rdy_led; + // pgm->err_led = pickit2_err_led; + + // Optional functions - these are checked to make sure they are assigned before they are called + pgm->cmd = pickit2_cmd; + pgm->spi = pickit2_spi; + pgm->paged_write = pickit2_paged_write; + pgm->paged_load = pickit2_paged_load; + // pgm->write_setup = NULL; + // pgm->read_sig_bytes = NULL; + // pgm->set_vtarget = NULL; // pickit2_vtarget; + // pgm->set_varef = NULL; + // pgm->set_fosc = NULL; + // pgm->perform_osccal = NULL; + + pgm->parseextparams = pickit2_parseextparams; + + pgm->setup = pickit2_setup; + pgm->teardown = pickit2_teardown; + // pgm->page_size = 256; // Not sure what this does ... maybe the max page size that paged read/write can handle + + strncpy(pgm->type, "pickit2", sizeof(pgm->type)); } #else static int pickit2_nousb_open(PROGRAMMER *pgm, const char *name) { - pmsg_error( + pmsg_error( #ifdef WIN32 - "no usb or hid support; please compile again with libusb or HID support from Win32 DDK installed\n" + "no usb or hid support; please compile again with libusb or HID support from Win32 DDK installed\n" #else - "no usb support; please compile again with libusb installed\n" + "no usb support; please compile again with libusb installed\n" #endif - ); + ); - return -1; + return -1; } void pickit2_initpgm(PROGRAMMER *pgm) { - /* - * mandatory functions - these are called without checking to see - * whether they are assigned or not - */ + // Mandatory function + pgm->open = pickit2_nousb_open; - pgm->open = pickit2_nousb_open; - - strncpy(pgm->type, "pickit2", sizeof(pgm->type)); + strncpy(pgm->type, "pickit2", sizeof(pgm->type)); } - -#endif /* defined(HAVE_LIBUSB) || defined(WIN32) */ +#endif // defined(HAVE_LIBUSB) || defined(WIN32) const char pickit2_desc[] = "Microchip's PICkit2 Programmer"; diff --git a/src/pickit2.h b/src/pickit2.h index b56a33ef8..cdfa3dc03 100644 --- a/src/pickit2.h +++ b/src/pickit2.h @@ -16,8 +16,6 @@ * along with this program. If not, see . */ -/* $Id: pickit2.h 2010-05-03 dbrown $ */ - #ifndef pickit2_h #define pickit2_h @@ -25,11 +23,11 @@ extern "C" { #endif -extern const char pickit2_desc[]; -void pickit2_initpgm(PROGRAMMER *pgm); + extern const char pickit2_desc[]; + void pickit2_initpgm(PROGRAMMER *pgm); #ifdef __cplusplus } #endif -#endif // pickit2_h +#endif diff --git a/src/pindefs.c b/src/pindefs.c index adba1607b..8805d3973 100644 --- a/src/pindefs.c +++ b/src/pindefs.c @@ -16,8 +16,6 @@ * along with this program. If not, see . */ -/* $Id: pindefs.h 1132 2013-01-09 19:23:30Z rliebscher $ */ - #include #include #include @@ -27,50 +25,51 @@ #include "avrdude.h" #include "libavrdude.h" -/** +/* * Adds a pin in the pin definition as normal or inverse pin. * * @param[out] pindef pin definition to update * @param[in] pin number of pin [0..PIN_MAX] * @param[in] inverse inverse (true) or normal (false) pin */ -void pin_set_value(struct pindef * const pindef, const int pin, const bool inverse) { +void pin_set_value(struct pindef *const pindef, const int pin, const bool inverse) { - pindef->mask[pin / PIN_FIELD_ELEMENT_SIZE] |= 1 << (pin % PIN_FIELD_ELEMENT_SIZE); + pindef->mask[pin/PIN_FIELD_ELEMENT_SIZE] |= 1 << (pin%PIN_FIELD_ELEMENT_SIZE); if(inverse) { - pindef->inverse[pin / PIN_FIELD_ELEMENT_SIZE] |= (1 << (pin % PIN_FIELD_ELEMENT_SIZE)); + pindef->inverse[pin/PIN_FIELD_ELEMENT_SIZE] |= (1 << (pin%PIN_FIELD_ELEMENT_SIZE)); } else { - pindef->inverse[pin / PIN_FIELD_ELEMENT_SIZE] &= ~(1 << (pin % PIN_FIELD_ELEMENT_SIZE)); + pindef->inverse[pin/PIN_FIELD_ELEMENT_SIZE] &= ~(1 << (pin%PIN_FIELD_ELEMENT_SIZE)); } } -/** +/* * Clear all defined pins in pindef. * * @param[out] pindef pin definition to clear */ -void pin_clear_all(struct pindef * const pindef) { +void pin_clear_all(struct pindef *const pindef) { memset(pindef, 0, sizeof(struct pindef)); } -/** +/* * Convert new pin definition to old pin number * * @param[in] pindef new pin definition structure * @param[out] pinno old pin definition integer */ -static int pin_fill_old_pinno(const struct pindef * const pindef, unsigned int * const pinno) { +static int pin_fill_old_pinno(const struct pindef *const pindef, unsigned int *const pinno) { bool found = false; int i; + for(i = 0; i <= PIN_MAX; i++) { - if(pindef->mask[i / PIN_FIELD_ELEMENT_SIZE] & (1 << (i % PIN_FIELD_ELEMENT_SIZE))) { + if(pindef->mask[i/PIN_FIELD_ELEMENT_SIZE] & (1 << (i%PIN_FIELD_ELEMENT_SIZE))) { if(found) { - pmsg_error("multiple pins found\n"); // TODO + pmsg_error("multiple pins found\n"); // TODO return -1; } found = true; *pinno = i; - if(pindef->inverse[i / PIN_FIELD_ELEMENT_SIZE] & (1 << (i % PIN_FIELD_ELEMENT_SIZE))) { + if(pindef->inverse[i/PIN_FIELD_ELEMENT_SIZE] & (1 << (i%PIN_FIELD_ELEMENT_SIZE))) { *pinno |= PIN_INVERSE; } } @@ -78,26 +77,26 @@ static int pin_fill_old_pinno(const struct pindef * const pindef, unsigned int * return 0; } -/** +/* * Convert new pin definition to old pinlist, does not support mixed inverted/non-inverted pin * * @param[in] pindef new pin definition structure * @param[out] pinno old pin definition integer */ -static int pin_fill_old_pinlist(const struct pindef * const pindef, unsigned int * const pinno) { +static int pin_fill_old_pinlist(const struct pindef *const pindef, unsigned int *const pinno) { for(size_t i = 0; i < PIN_FIELD_SIZE; i++) { if(i == 0) { if((pindef->mask[i] & ~PIN_MASK) != 0) { pmsg_error("pins of higher index than max field size for old pinno found\n"); return -1; } - if (pindef->mask[i] == 0) { - /* this pin function is not using any pins */ + if(pindef->mask[i] == 0) { + // This pin function is not using any pins *pinno = NO_PIN; - } else if(pindef->mask[i] == pindef->inverse[i]) { /* all set bits in mask are set in inverse */ + } else if(pindef->mask[i] == pindef->inverse[i]) { // All set bits in mask are set in inverse *pinno = pindef->mask[i]; *pinno |= PIN_INVERSE; - } else if(pindef->mask[i] == ((~pindef->inverse[i]) & pindef->mask[i])) { /* all set bits in mask are cleared in inverse */ + } else if(pindef->mask[i] == ((~pindef->inverse[i]) & pindef->mask[i])) { // All set bits in mask are cleared in inverse *pinno = pindef->mask[i]; } else { pmsg_error("pins have different polarity set\n"); @@ -111,55 +110,54 @@ static int pin_fill_old_pinlist(const struct pindef * const pindef, unsigned int return 0; } - -/** +/* * Convert for given programmer new pin definitions to old pin definitions. * * @param[inout] pgm programmer whose pins shall be converted. */ -int pgm_fill_old_pins(PROGRAMMER * const pgm) { +int pgm_fill_old_pins(PROGRAMMER *const pgm) { - if (pin_fill_old_pinlist(&(pgm->pin[PPI_AVR_VCC]), &(pgm->pinno[PPI_AVR_VCC])) < 0) + if(pin_fill_old_pinlist(&(pgm->pin[PPI_AVR_VCC]), &(pgm->pinno[PPI_AVR_VCC])) < 0) return -1; - if (pin_fill_old_pinlist(&(pgm->pin[PPI_AVR_BUFF]), &(pgm->pinno[PPI_AVR_BUFF])) < 0) + if(pin_fill_old_pinlist(&(pgm->pin[PPI_AVR_BUFF]), &(pgm->pinno[PPI_AVR_BUFF])) < 0) return -1; - if (pin_fill_old_pinno(&(pgm->pin[PIN_AVR_RESET]), &(pgm->pinno[PIN_AVR_RESET])) < 0) + if(pin_fill_old_pinno(&(pgm->pin[PIN_AVR_RESET]), &(pgm->pinno[PIN_AVR_RESET])) < 0) return -1; - if (pin_fill_old_pinno(&(pgm->pin[PIN_AVR_SCK]), &(pgm->pinno[PIN_AVR_SCK])) < 0) + if(pin_fill_old_pinno(&(pgm->pin[PIN_AVR_SCK]), &(pgm->pinno[PIN_AVR_SCK])) < 0) return -1; - if (pin_fill_old_pinno(&(pgm->pin[PIN_AVR_SDO]), &(pgm->pinno[PIN_AVR_SDO])) < 0) + if(pin_fill_old_pinno(&(pgm->pin[PIN_AVR_SDO]), &(pgm->pinno[PIN_AVR_SDO])) < 0) return -1; - if (pin_fill_old_pinno(&(pgm->pin[PIN_AVR_SDI]), &(pgm->pinno[PIN_AVR_SDI])) < 0) + if(pin_fill_old_pinno(&(pgm->pin[PIN_AVR_SDI]), &(pgm->pinno[PIN_AVR_SDI])) < 0) return -1; - if (pin_fill_old_pinno(&(pgm->pin[PIN_JTAG_TCK]), &(pgm->pinno[PIN_JTAG_TCK])) < 0) + if(pin_fill_old_pinno(&(pgm->pin[PIN_JTAG_TCK]), &(pgm->pinno[PIN_JTAG_TCK])) < 0) return -1; - if (pin_fill_old_pinno(&(pgm->pin[PIN_JTAG_TDI]), &(pgm->pinno[PIN_JTAG_TDI])) < 0) + if(pin_fill_old_pinno(&(pgm->pin[PIN_JTAG_TDI]), &(pgm->pinno[PIN_JTAG_TDI])) < 0) return -1; - if (pin_fill_old_pinno(&(pgm->pin[PIN_JTAG_TDO]), &(pgm->pinno[PIN_JTAG_TDO])) < 0) + if(pin_fill_old_pinno(&(pgm->pin[PIN_JTAG_TDO]), &(pgm->pinno[PIN_JTAG_TDO])) < 0) return -1; - if (pin_fill_old_pinno(&(pgm->pin[PIN_JTAG_TMS]), &(pgm->pinno[PIN_JTAG_TMS])) < 0) + if(pin_fill_old_pinno(&(pgm->pin[PIN_JTAG_TMS]), &(pgm->pinno[PIN_JTAG_TMS])) < 0) return -1; - if (pin_fill_old_pinno(&(pgm->pin[PIN_LED_ERR]), &(pgm->pinno[PIN_LED_ERR])) < 0) + if(pin_fill_old_pinno(&(pgm->pin[PIN_LED_ERR]), &(pgm->pinno[PIN_LED_ERR])) < 0) return -1; - if (pin_fill_old_pinno(&(pgm->pin[PIN_LED_RDY]), &(pgm->pinno[PIN_LED_RDY])) < 0) + if(pin_fill_old_pinno(&(pgm->pin[PIN_LED_RDY]), &(pgm->pinno[PIN_LED_RDY])) < 0) return -1; - if (pin_fill_old_pinno(&(pgm->pin[PIN_LED_PGM]), &(pgm->pinno[PIN_LED_PGM])) < 0) + if(pin_fill_old_pinno(&(pgm->pin[PIN_LED_PGM]), &(pgm->pinno[PIN_LED_PGM])) < 0) return -1; - if (pin_fill_old_pinno(&(pgm->pin[PIN_LED_VFY]), &(pgm->pinno[PIN_LED_VFY])) < 0) + if(pin_fill_old_pinno(&(pgm->pin[PIN_LED_VFY]), &(pgm->pinno[PIN_LED_VFY])) < 0) return -1; return 0; } -/** +/* * This function returns a string representation of pins in the mask eg. 1, 3, 5-7, 9, 12 * Consecutive pin numbers are represented as start-end. * * @param[in] pinmask the pin mask for which we want the string representation * @returns a temporary string that lives in closed-circuit space */ -const char *pinmask_to_str(const Pinmask * const pinmask) { - char buf[6 * (PIN_MAX + 1)]; +const char *pinmask_to_str(const Pinmask *const pinmask) { + char buf[6*(PIN_MAX + 1)]; char *p = buf; int n; int pin; @@ -168,10 +166,12 @@ const char *pinmask_to_str(const Pinmask * const pinmask) { buf[0] = 0; for(pin = PIN_MIN; pin <= PIN_MAX; pin++) { - int index = pin / PIN_FIELD_ELEMENT_SIZE; - int bit = pin % PIN_FIELD_ELEMENT_SIZE; + int index = pin/PIN_FIELD_ELEMENT_SIZE; + int bit = pin%PIN_FIELD_ELEMENT_SIZE; + if(pinmask[index] & (1 << bit)) { bool output = false; + if(start == -1) { output = true; start = pin; @@ -199,10 +199,9 @@ const char *pinmask_to_str(const Pinmask * const pinmask) { return str_ccstrdup(*buf? buf: "(no pins)"); } - -/** +/* * This function checks all pin of pgm against the constraints given in the checklist. - * It checks if + * It checks if * @li any invalid pins are used * @li valid pins are used inverted when not allowed * @li any pins are used by more than one function @@ -218,24 +217,24 @@ const char *pinmask_to_str(const Pinmask * const pinmask) { * @returns 0 if all pin definitions are valid, -1 otherwise */ int pins_check(const PROGRAMMER *const pgm, const Pin_checklist *const checklist, const int size, const bool output) { - static const struct pindef no_valid_pins = {{0}, {0}}; // default value if check list does not contain anything else - int rv = 0; // return value - int pinname; // loop counter through pinnames - Pinmask already_used_all[PIN_FIELD_SIZE] = {0}; // collect pin definitions of all pin names for check of double use - // loop over all possible pinnames + static const struct pindef no_valid_pins = { {0}, {0} }; // Default value if check list does not contain anything else + int rv = 0; + int pinname; + Pinmask already_used_all[PIN_FIELD_SIZE] = { 0 }; // Collect pin definitions of all pin names for check of double use for(pinname = 0; pinname < N_PINS; pinname++) { bool used = false; bool invalid = false; bool inverse = false; int index; bool mandatory_used = false; - Pinmask invalid_used[PIN_FIELD_SIZE] = {0}; - Pinmask inverse_used[PIN_FIELD_SIZE] = {0}; - Pinmask already_used[PIN_FIELD_SIZE] = {0}; - const struct pindef * valid_pins = &no_valid_pins; + Pinmask invalid_used[PIN_FIELD_SIZE] = { 0 }; + Pinmask inverse_used[PIN_FIELD_SIZE] = { 0 }; + Pinmask already_used[PIN_FIELD_SIZE] = { 0 }; + const struct pindef *valid_pins = &no_valid_pins; bool is_mandatory = false; bool is_ok = true; - //find corresponding check pattern + + // Find corresponding check pattern for(index = 0; index < size; index++) { if(checklist[index].pinname == pinname) { valid_pins = checklist[index].valid_pins; @@ -245,34 +244,33 @@ int pins_check(const PROGRAMMER *const pgm, const Pin_checklist *const checklist } for(size_t segment = 0; segment < PIN_FIELD_SIZE; segment++) { - // check if for mandatory any pin is defined + // Check if for mandatory any pin is defined invalid_used[segment] = pgm->pin[pinname].mask[segment] & ~valid_pins->mask[segment]; if(is_mandatory && (0 != (pgm->pin[pinname].mask[segment] & valid_pins->mask[segment]))) { mandatory_used = true; } - // check if it does not use any non valid pins + // Check if it does not use any non valid pins invalid_used[segment] = pgm->pin[pinname].mask[segment] & ~valid_pins->mask[segment]; if(invalid_used[segment]) { invalid = true; } - // check if it does not use any valid pins as inverse if not allowed - inverse_used[segment] = pgm->pin[pinname].inverse[segment] & valid_pins->mask[segment] & ~valid_pins->inverse[segment]; - if(inverse_used[segment]) { + // Check if it does not use any valid pins as inverse if not allowed + inverse_used[segment] = pgm->pin[pinname].inverse[segment] & + valid_pins->mask[segment] & ~valid_pins->inverse[segment]; + if(inverse_used[segment]) inverse = true; - } - // check if it does not use same pins as other function + // Check if it does not use same pins as other function already_used[segment] = pgm->pin[pinname].mask[segment] & already_used_all[segment]; - if(already_used[segment]) { + if(already_used[segment]) used = true; - } already_used_all[segment] |= pgm->pin[pinname].mask[segment]; } if(invalid) { if(output) { pmsg_error("%s: these pins are not valid pins for this function: %s\n", avr_pin_name(pinname), pinmask_to_str(invalid_used)); - imsg_error("%s: valid pins for this function are: %s\n", - avr_pin_name(pinname), pinmask_to_str(valid_pins->mask)); + imsg_error("%s: valid pins for this function are: %s\n", avr_pin_name(pinname), + pinmask_to_str(valid_pins->mask)); } is_ok = false; } @@ -307,22 +305,22 @@ int pins_check(const PROGRAMMER *const pgm, const Pin_checklist *const checklist return rv; } - -/** +/* * This function returns a string of defined pins, eg, ~1, 2, ~4, ~5, 7 or "" * * @param[in] pindef the pin definition for which we want the string representation * @returns a temporary string that lives in closed-circuit space */ -const char *pins_to_str(const struct pindef * const pindef) { - char buf[6*(PIN_MAX+1)], *p = buf; +const char *pins_to_str(const struct pindef *const pindef) { + char buf[6*(PIN_MAX + 1)], *p = buf; *buf = 0; for(int pin = PIN_MIN; pin <= PIN_MAX; pin++) { - int index = pin / PIN_FIELD_ELEMENT_SIZE, bit = pin % PIN_FIELD_ELEMENT_SIZE; + int index = pin/PIN_FIELD_ELEMENT_SIZE, bit = pin%PIN_FIELD_ELEMENT_SIZE; + if(pindef->mask[index] & (1 << bit)) { if(*buf) - *p++ = ',', *p++=' '; + *p++ = ',', *p++ = ' '; p += sprintf(p, pindef->inverse[index] & (1 << bit)? "~%d": "%d", pin); } } @@ -330,55 +328,84 @@ const char *pins_to_str(const struct pindef * const pindef) { return str_ccstrdup(buf); } -/** +/* * Returns the name of the pin as string. * * @param pinname the pinname which we want as string. * @returns a string with the pinname, or if pinname is invalid. */ -const char * avr_pin_name(int pinname) { +const char *avr_pin_name(int pinname) { switch(pinname) { - case PPI_AVR_VCC : return "VCC"; - case PPI_AVR_BUFF : return "BUFF"; - case PIN_AVR_RESET : return "RESET"; - case PIN_AVR_SCK : return "SCK"; - case PIN_AVR_SDO : return "SDO"; - case PIN_AVR_SDI : return "SDI"; - case PIN_JTAG_TCK : return "TCK"; - case PIN_JTAG_TDI : return "TDI"; - case PIN_JTAG_TDO : return "TDO"; - case PIN_JTAG_TMS : return "TMS"; - case PIN_LED_ERR : return "ERRLED"; - case PIN_LED_RDY : return "RDYLED"; - case PIN_LED_PGM : return "PGMLED"; - case PIN_LED_VFY : return "VFYLED"; - default : return ""; + case PPI_AVR_VCC: + return "VCC"; + case PPI_AVR_BUFF: + return "BUFF"; + case PIN_AVR_RESET: + return "RESET"; + case PIN_AVR_SCK: + return "SCK"; + case PIN_AVR_SDO: + return "SDO"; + case PIN_AVR_SDI: + return "SDI"; + case PIN_JTAG_TCK: + return "TCK"; + case PIN_JTAG_TDI: + return "TDI"; + case PIN_JTAG_TDO: + return "TDO"; + case PIN_JTAG_TMS: + return "TMS"; + case PIN_LED_ERR: + return "ERRLED"; + case PIN_LED_RDY: + return "RDYLED"; + case PIN_LED_PGM: + return "PGMLED"; + case PIN_LED_VFY: + return "VFYLED"; + default: + return ""; } } - -/** +/* * Returns the name of the pin as string. * * @param pinname the pinname which we want as string. * @returns a lowercase string with the pinname, or if pinname is invalid. */ -const char * avr_pin_lcname(int pinname) { +const char *avr_pin_lcname(int pinname) { switch(pinname) { - case PPI_AVR_VCC : return "vcc"; - case PPI_AVR_BUFF : return "buff"; - case PIN_AVR_RESET : return "reset"; - case PIN_AVR_SCK : return "sck"; - case PIN_AVR_SDO : return "sdo"; - case PIN_AVR_SDI : return "sdi"; - case PIN_JTAG_TCK : return "tck"; - case PIN_JTAG_TDI : return "tdi"; - case PIN_JTAG_TDO : return "tdo"; - case PIN_JTAG_TMS : return "tms"; - case PIN_LED_ERR : return "errled"; - case PIN_LED_RDY : return "rdyled"; - case PIN_LED_PGM : return "pgmled"; - case PIN_LED_VFY : return "vfyled"; - default : return ""; + case PPI_AVR_VCC: + return "vcc"; + case PPI_AVR_BUFF: + return "buff"; + case PIN_AVR_RESET: + return "reset"; + case PIN_AVR_SCK: + return "sck"; + case PIN_AVR_SDO: + return "sdo"; + case PIN_AVR_SDI: + return "sdi"; + case PIN_JTAG_TCK: + return "tck"; + case PIN_JTAG_TDI: + return "tdi"; + case PIN_JTAG_TDO: + return "tdo"; + case PIN_JTAG_TMS: + return "tms"; + case PIN_LED_ERR: + return "errled"; + case PIN_LED_RDY: + return "rdyled"; + case PIN_LED_PGM: + return "pgmled"; + case PIN_LED_VFY: + return "vfyled"; + default: + return ""; } } diff --git a/src/ppi.c b/src/ppi.c index 61bd55ab2..a817fd97a 100644 --- a/src/ppi.c +++ b/src/ppi.c @@ -16,13 +16,10 @@ * along with this program. If not, see . */ - #if !defined(WIN32) - #include #if HAVE_PARPORT - #include #include #include @@ -31,11 +28,11 @@ #include #if defined(__FreeBSD__) || defined(__FreeBSD_kernel__) -# include "freebsd_ppi.h" +#include "freebsd_ppi.h" #elif defined(__linux__) -# include "linux_ppdev.h" -#elif defined(__sun__) || defined(__sun) /* Solaris */ -# include "solaris_ecpp.h" +#include "linux_ppdev.h" +#elif defined(__sun__) || defined(__sun) // Solaris +#include "solaris_ecpp.h" #endif #include "avrdude.h" @@ -49,46 +46,42 @@ enum { PPI_SHADOWREAD }; -static int ppi_shadow_access(const union filedescriptor *fdp, int reg, - unsigned char *v, unsigned char action) -{ +static int ppi_shadow_access(const union filedescriptor *fdp, int reg, unsigned char *v, unsigned char action) { int shadow_num; - switch (reg) { - case PPIDATA: - shadow_num = 0; - break; - case PPICTRL: - shadow_num = 1; - break; - case PPISTATUS: - shadow_num = 2; - break; - default: - pmsg_error("invalid register=%d\n", reg); - return -1; - break; + switch(reg) { + case PPIDATA: + shadow_num = 0; + break; + case PPICTRL: + shadow_num = 1; + break; + case PPISTATUS: + shadow_num = 2; + break; + default: + pmsg_error("invalid register=%d\n", reg); + return -1; + break; } - switch (action) { - case PPI_SHADOWREAD: - *v = cx->ppi_shadow[shadow_num]; - break; - case PPI_READ: - DO_PPI_READ(fdp->ifd, reg, v); - cx->ppi_shadow[shadow_num]=*v; - break; - case PPI_WRITE: - cx->ppi_shadow[shadow_num]=*v; - DO_PPI_WRITE(fdp->ifd, reg, v); - break; + switch(action) { + case PPI_SHADOWREAD: + *v = cx->ppi_shadow[shadow_num]; + break; + case PPI_READ: + DO_PPI_READ(fdp->ifd, reg, v); + cx->ppi_shadow[shadow_num] = *v; + break; + case PPI_WRITE: + cx->ppi_shadow[shadow_num] = *v; + DO_PPI_WRITE(fdp->ifd, reg, v); + break; } return 0; } -/* - * set the indicated bit of the specified register. - */ +// Set the indicated bit of the specified register int ppi_set(const union filedescriptor *fdp, int reg, int bit) { unsigned char v; int rc; @@ -97,16 +90,13 @@ int ppi_set(const union filedescriptor *fdp, int reg, int bit) { v |= bit; rc |= ppi_shadow_access(fdp, reg, &v, PPI_WRITE); - if (rc) + if(rc) return -1; return 0; } - -/* - * clear the indicated bit of the specified register. - */ +// Clear the indicated bit of the specified register int ppi_clr(const union filedescriptor *fdp, int reg, int bit) { unsigned char v; int rc; @@ -115,16 +105,13 @@ int ppi_clr(const union filedescriptor *fdp, int reg, int bit) { v &= ~bit; rc |= ppi_shadow_access(fdp, reg, &v, PPI_WRITE); - if (rc) + if(rc) return -1; return 0; } - -/* - * get the indicated bit of the specified register. - */ +// Get the indicated bit of the specified register int ppi_get(const union filedescriptor *fdp, int reg, int bit) { unsigned char v; int rc; @@ -132,15 +119,13 @@ int ppi_get(const union filedescriptor *fdp, int reg, int bit) { rc = ppi_shadow_access(fdp, reg, &v, PPI_READ); v &= bit; - if (rc) + if(rc) return -1; - return v; /* v == bit */ + return v; // v == bit } -/* - * toggle the indicated bit of the specified register. - */ +// Toggle the indicated bit of the specified register int ppi_toggle(const union filedescriptor *fdp, int reg, int bit) { unsigned char v; int rc; @@ -149,31 +134,26 @@ int ppi_toggle(const union filedescriptor *fdp, int reg, int bit) { v ^= bit; rc |= ppi_shadow_access(fdp, reg, &v, PPI_WRITE); - if (rc) + if(rc) return -1; return 0; } - -/* - * get all bits of the specified register. - */ +// Get all bits of the specified register int ppi_getall(const union filedescriptor *fdp, int reg) { unsigned char v; int rc; rc = ppi_shadow_access(fdp, reg, &v, PPI_READ); - if (rc) + if(rc) return -1; - return v; /* v == bit */ + return v; // v == bit } -/* - * set all bits of the specified register to val. - */ +// Set all bits of the specified register to val int ppi_setall(const union filedescriptor *fdp, int reg, int val) { unsigned char v; int rc; @@ -181,43 +161,36 @@ int ppi_setall(const union filedescriptor *fdp, int reg, int val) { v = val; rc = ppi_shadow_access(fdp, reg, &v, PPI_WRITE); - if (rc) + if(rc) return -1; return 0; } - void ppi_open(const char *port, union filedescriptor *fdp) { int fd; unsigned char v; fd = open(port, O_RDWR); - if (fd < 0) { + if(fd < 0) { pmsg_ext_error("cannot open port %s: %s\n", port, strerror(errno)); fdp->ifd = -1; return; } - ppi_claim (fd); - - /* - * Initialize shadow registers - */ + ppi_claim(fd); - ppi_shadow_access (fdp, PPIDATA, &v, PPI_READ); - ppi_shadow_access (fdp, PPICTRL, &v, PPI_READ); - ppi_shadow_access (fdp, PPISTATUS, &v, PPI_READ); + // Initialize shadow registers + ppi_shadow_access(fdp, PPIDATA, &v, PPI_READ); + ppi_shadow_access(fdp, PPICTRL, &v, PPI_READ); + ppi_shadow_access(fdp, PPISTATUS, &v, PPI_READ); fdp->ifd = fd; } - void ppi_close(const union filedescriptor *fdp) { - ppi_release (fdp->ifd); + ppi_release(fdp->ifd); close(fdp->ifd); } - -#endif /* HAVE_PARPORT */ - -#endif /* !WIN32 */ +#endif // HAVE_PARPORT +#endif // ! WIN32 diff --git a/src/ppi.h b/src/ppi.h index 8b64a12a4..f0e8e6894 100644 --- a/src/ppi.h +++ b/src/ppi.h @@ -19,9 +19,7 @@ #ifndef ppi_h #define ppi_h -/* - * PPI registers - */ +// PPI registers enum { PPIDATA, PPICTRL, @@ -32,26 +30,23 @@ enum { extern "C" { #endif -int ppi_get (const union filedescriptor *fdp, int reg, int bit); + int ppi_get(const union filedescriptor *fdp, int reg, int bit); -int ppi_set (const union filedescriptor *fdp, int reg, int bit); + int ppi_set(const union filedescriptor *fdp, int reg, int bit); -int ppi_clr (const union filedescriptor *fdp, int reg, int bit); + int ppi_clr(const union filedescriptor *fdp, int reg, int bit); -int ppi_getall (const union filedescriptor *fdp, int reg); + int ppi_getall(const union filedescriptor *fdp, int reg); -int ppi_setall (const union filedescriptor *fdp, int reg, int val); + int ppi_setall(const union filedescriptor *fdp, int reg, int val); -int ppi_toggle (const union filedescriptor *fdp, int reg, int bit); + int ppi_toggle(const union filedescriptor *fdp, int reg, int bit); -void ppi_open (const char *port, union filedescriptor *fdp); + void ppi_open(const char *port, union filedescriptor *fdp); -void ppi_close (const union filedescriptor *fdp); + void ppi_close(const union filedescriptor *fdp); #ifdef __cplusplus } #endif - #endif - - diff --git a/src/ppiwin.c b/src/ppiwin.c index 410e3e815..e8816494d 100644 --- a/src/ppiwin.c +++ b/src/ppiwin.c @@ -18,19 +18,17 @@ */ /* -This is the parallel port interface for Windows built using Cygwin. - -In the ppi_* functions that access the parallel port registers, -fd = parallel port address -reg = register as defined in an enum in ppi.h. This must be converted - to a proper offset of the base address. -*/ - + * This is the parallel port interface for Windows built using Cygwin. + * + * In the ppi_* functions that access the parallel port registers, + * fd = parallel port address + * reg = register as defined in an enum in ppi.h. This must be converted + * to a proper offset of the base address. + */ #include #if defined(HAVE_PARPORT) && defined(WIN32) - #define WIN32_LEAN_AND_MEAN #include #include @@ -51,273 +49,212 @@ reg = register as defined in an enum in ppi.h. This must be converted #define DEVICE_LPT2 "lpt2" #define DEVICE_LPT3 "lpt3" -#define DEVICE_MAX 3 +#define DEVICE_MAX 3 -typedef struct -{ - const char *name; - int base_address; +typedef struct { + const char *name; + int base_address; } winpp; -static const winpp winports[DEVICE_MAX] = -{ - {DEVICE_LPT1, 0x378}, - {DEVICE_LPT2, 0x278}, - {DEVICE_LPT3, 0x3BC}, +static const winpp winports[DEVICE_MAX] = { + {DEVICE_LPT1, 0x378}, + {DEVICE_LPT2, 0x278}, + {DEVICE_LPT3, 0x3BC}, }; - - - - -/* FUNCTION PROTOTYPES */ static int winnt_pp_open(void); static unsigned short port_get(union filedescriptor *fdp, int reg); static unsigned char reg2offset(int reg); static unsigned char inb(unsigned short port); static void outb(unsigned char value, unsigned short port); - - -/* FUNCTION DEFINITIONS */ - void ppi_open(const char *port, union filedescriptor *fdp) { - unsigned char i; - int fd; - - fd = winnt_pp_open(); + unsigned char i; + int fd; - if(fd < 0) - { - pmsg_ext_error("cannot open device \"giveio\"\n\n"); // giveio?!? FIXME! - fdp->ifd = -1; - return; - } + fd = winnt_pp_open(); - /* Search the windows port names for a match */ - fd = -1; - for(i = 0; i < DEVICE_MAX; i++) - { - if(str_eq(winports[i].name, port)) - { - /* Set the file descriptor with the Windows parallel port base address. */ - fd = winports[i].base_address; - break; - } - } - if(fd == -1) - { - /* - * Supplied port name did not match any of the pre-defined - * names. Try interpreting it as a numeric - * (hexadecimal/decimal/octal) address. - */ - char *cp; - - fd = strtol(port, &cp, 0); - if(*port == '\0' || *cp != '\0') - { - pmsg_error("port %s is neither lpt1/2/3 nor valid number\n", port); - fd = -1; - } + if(fd < 0) { + pmsg_ext_error("cannot winnt_pp_open()\n"); + fdp->ifd = -1; + return; + } + + // Search the windows port names for a match + fd = -1; + for(i = 0; i < DEVICE_MAX; i++) { + if(str_eq(winports[i].name, port)) { + // Set the file descriptor with the Windows parallel port base address + fd = winports[i].base_address; + break; } - if(fd < 0) - { - pmsg_ext_error("cannot open port %s\n\n", port); - fdp->ifd = -1; - return; + } + if(fd == -1) { + /* + * Supplied port name did not match any of the pre-defined names. Try + * interpreting it as a numeric (hexadecimal/decimal/octal) address. + */ + char *cp; + + fd = strtol(port, &cp, 0); + if(*port == '\0' || *cp != '\0') { + pmsg_error("port %s is neither lpt1/2/3 nor valid number\n", port); + fd = -1; } + } + if(fd < 0) { + pmsg_ext_error("cannot open port %s\n\n", port); + fdp->ifd = -1; + return; + } - fdp->ifd = fd; + fdp->ifd = fd; } - #define DRIVERNAME "\\\\.\\giveio" static int winnt_pp_open(void) { - // Only try to use giveio under Windows NT/2000/XP. - OSVERSIONINFO ver_info; - - memset(&ver_info, 0, sizeof(ver_info)); - - ver_info.dwOSVersionInfoSize = sizeof(ver_info); - - if(!GetVersionEx(&ver_info)) - { - return(-1); + // Only try to use giveio under Windows NT/2000/XP. + OSVERSIONINFO ver_info; + + memset(&ver_info, 0, sizeof(ver_info)); + + ver_info.dwOSVersionInfoSize = sizeof(ver_info); + + if(!GetVersionEx(&ver_info)) { + return (-1); + } else if(ver_info.dwPlatformId == VER_PLATFORM_WIN32_NT) { + HANDLE h = CreateFile(DRIVERNAME, + GENERIC_READ, + 0, + NULL, + OPEN_EXISTING, + FILE_ATTRIBUTE_NORMAL, + NULL); + + if(h == INVALID_HANDLE_VALUE) { + return (-1); } - else if(ver_info.dwPlatformId == VER_PLATFORM_WIN32_NT) - { - HANDLE h = CreateFile(DRIVERNAME, - GENERIC_READ, - 0, - NULL, - OPEN_EXISTING, - FILE_ATTRIBUTE_NORMAL, - NULL); - - if(h == INVALID_HANDLE_VALUE) - { - return(-1); - } - - /* Close immediately. The process now has the rights it needs. */ - if(h != NULL) - { - CloseHandle(h); - } + + // Close immediately; the process now has the rights it needs + if(h != NULL) { + CloseHandle(h); } - return(0); + } + return (0); } - - - void ppi_close(const union filedescriptor *fdp) { - return; + return; } - - -/* - * set the indicated bit of the specified register. - */ +// Set the indicated bit of the specified register int ppi_set(const union filedescriptor *fdp, int reg, int bit) { - unsigned char v; - unsigned short port; - - port = port_get(fdp, reg); - v = inb(port); - v |= bit; - outb(v, port); - return 0; + unsigned char v; + unsigned short port; + + port = port_get(fdp, reg); + v = inb(port); + v |= bit; + outb(v, port); + return 0; } - -/* - * clear the indicated bit of the specified register. - */ +// Clear the indicated bit of the specified register int ppi_clr(const union filedescriptor *fdp, int reg, int bit) { - unsigned char v; - unsigned short port; + unsigned char v; + unsigned short port; - port = port_get(fdp, reg); - v = inb(port); - v &= ~bit; - outb(v, port); + port = port_get(fdp, reg); + v = inb(port); + v &= ~bit; + outb(v, port); - return 0; + return 0; } - -/* - * get the indicated bit of the specified register. - */ +// Get the indicated bit of the specified register int ppi_get(const union filedescriptor *fdp, int reg, int bit) { - unsigned char v; + unsigned char v; - v = inb(port_get(fdp, reg)); - v &= bit; + v = inb(port_get(fdp, reg)); + v &= bit; - return(v); + return (v); } - - - -/* - * toggle the indicated bit of the specified register. - */ +// Toggle the indicated bit of the specified register int ppi_toggle(const union filedescriptor *fdp, int reg, int bit) { - unsigned char v; - unsigned short port; + unsigned char v; + unsigned short port; - port = port_get(fdp, reg); + port = port_get(fdp, reg); - v = inb(port); - v ^= bit; - outb(v, port); + v = inb(port); + v ^= bit; + outb(v, port); - return 0; + return 0; } - -/* - * get all bits of the specified register. - */ +// Get all bits of the specified register int ppi_getall(const union filedescriptor *fdp, int reg) { - unsigned char v; + unsigned char v; - v = inb(port_get(fdp, reg)); + v = inb(port_get(fdp, reg)); - return((int)v); + return ((int) v); } - - - -/* - * set all bits of the specified register to val. - */ +// Set all bits of the specified register to val int ppi_setall(const union filedescriptor *fdp, int reg, int val) { - outb((unsigned char)val, port_get(fdp, reg)); - return 0; + outb((unsigned char) val, port_get(fdp, reg)); + return 0; } - - - -/* Calculate port address to access. */ +// Calculate port address to access static unsigned short port_get(const union filedescriptor *fdp, int reg) { - return((unsigned short)(fdp->ifd + reg2offset(reg))); + return ((unsigned short) (fdp->ifd + reg2offset(reg))); } - -/* Convert register enum to offset of base address. */ +// Convert register enum to offset of base address static unsigned char reg2offset(int reg) { - unsigned char offset = 0; + unsigned char offset = 0; - switch(reg) + switch(reg) { + case PPIDATA: + { + offset = 0; + break; + } + case PPISTATUS: { - case PPIDATA: - { - offset = 0; - break; - } - case PPISTATUS: - { - offset = 1; - break; - } - case PPICTRL: - { - offset = 2; - break; - } + offset = 1; + break; } + case PPICTRL: + { + offset = 2; + break; + } + } - return(offset); + return (offset); } - -/* Read in value from port. */ +// Read in value from port static unsigned char inb(unsigned short port) { - unsigned char t; - - asm volatile ("in %1, %0" - : "=a" (t) - : "d" (port)); - - return t; -} + unsigned char t; + asm volatile ("in %1, %0":"=a" (t) + :"d"(port)); -/* Write value to port. */ + return t; +} + +// Write value to port static void outb(unsigned char value, unsigned short port) { - asm volatile ("out %1, %0" - : - : "d" (port), "a" (value) ); + asm volatile ("out %1, %0"::"d" (port), "a"(value)); - return; + return; } - #endif diff --git a/src/ser_avrdoper.c b/src/ser_avrdoper.c index b3f1f8456..4b8e8cbe4 100644 --- a/src/ser_avrdoper.c +++ b/src/ser_avrdoper.c @@ -18,14 +18,11 @@ * along with this program. If not, see . */ -/* - * Serial Interface emulation for USB programmer "AVR-Doper" in HID mode. - */ +// Serial Interface emulation for USB programmer "AVR-Doper" in HID mode #include #if defined(HAVE_LIBHIDAPI) - #include #include #include @@ -34,9 +31,9 @@ #include "avrdude.h" #include "libavrdude.h" -/* ------------------------------------------------------------------------ */ +// - ----------------------------------------------------------------------- -/* Numeric constants for 'reportType' parameters */ +// Numeric constants for 'reportType' parameters #define USB_HID_REPORT_TYPE_INPUT 1 #define USB_HID_REPORT_TYPE_OUTPUT 2 #define USB_HID_REPORT_TYPE_FEATURE 3 @@ -53,296 +50,279 @@ #define USB_VENDOR_ID 0x16c0 #define USB_PRODUCT_ID 0x05df -static const int reportDataSizes[4] = {13, 29, 61, 125}; +static const int reportDataSizes[4] = { 13, 29, 61, 125 }; -/* ------------------------------------------------------------------------ */ -/* ------------------------------------------------------------------------ */ -/* ------------------------------------------------------------------------ */ +// ------------------------------------------------------------------------ static int usbOpenDevice(union filedescriptor *fdp, int vendor, const char *vendorName, - int product, const char *productName, int doReportIDs) -{ - hid_device *dev; - - dev = hid_open(vendor, product, NULL); - if (dev == NULL) - { - pmsg_ext_error("no device found\n"); - return USB_ERROR_NOTFOUND; - } - fdp->usb.handle = dev; - return USB_ERROR_NONE; + int product, const char *productName, int doReportIDs) { + hid_device *dev; + + dev = hid_open(vendor, product, NULL); + if(dev == NULL) { + pmsg_ext_error("no device found\n"); + return USB_ERROR_NOTFOUND; + } + fdp->usb.handle = dev; + return USB_ERROR_NONE; } -/* ------------------------------------------------------------------------- */ +// ------------------------------------------------------------------------- + +static void usbCloseDevice(union filedescriptor *fdp) { + hid_device *udev = (hid_device *) fdp->usb.handle; -static void usbCloseDevice(union filedescriptor *fdp) -{ - hid_device *udev = (hid_device *)fdp->usb.handle; fdp->usb.handle = NULL; - if (udev == NULL) + if(udev == NULL) return; hid_close(udev); } -/* ------------------------------------------------------------------------- */ +// ------------------------------------------------------------------------- static int usbSetReport(const union filedescriptor *fdp, int reportType, char *buffer, int len) { - hid_device *udev = (hid_device *)fdp->usb.handle; + hid_device *udev = (hid_device *) fdp->usb.handle; int bytesSent = -1; - switch(reportType){ + switch(reportType) { case USB_HID_REPORT_TYPE_INPUT: - break; + break; case USB_HID_REPORT_TYPE_OUTPUT: - bytesSent = hid_write(udev, (unsigned char*) buffer, len); - break; + bytesSent = hid_write(udev, (unsigned char *) buffer, len); + break; case USB_HID_REPORT_TYPE_FEATURE: - bytesSent = hid_send_feature_report(udev, (unsigned char*) buffer, len); - break; + bytesSent = hid_send_feature_report(udev, (unsigned char *) buffer, len); + break; } - if(bytesSent != len){ - if(bytesSent < 0) - pmsg_error("unable to send message: %ls\n", hid_error(udev)); - return USB_ERROR_IO; + if(bytesSent != len) { + if(bytesSent < 0) + pmsg_error("unable to send message: %ls\n", hid_error(udev)); + return USB_ERROR_IO; } return USB_ERROR_NONE; } -/* ------------------------------------------------------------------------- */ +// ------------------------------------------------------------------------- -static int usbGetReport(const union filedescriptor *fdp, int reportType, int reportNumber, - char *buffer, int *len) -{ - hid_device *udev = (hid_device *)fdp->usb.handle; +static int usbGetReport(const union filedescriptor *fdp, int reportType, int reportNumber, char *buffer, int *len) { + hid_device *udev = (hid_device *) fdp->usb.handle; int bytesReceived = -1; - switch(reportType){ + switch(reportType) { case USB_HID_REPORT_TYPE_INPUT: - bytesReceived = hid_read_timeout(udev, (unsigned char*) buffer, *len, 300); - break; + bytesReceived = hid_read_timeout(udev, (unsigned char *) buffer, *len, 300); + break; case USB_HID_REPORT_TYPE_OUTPUT: - break; + break; case USB_HID_REPORT_TYPE_FEATURE: - bytesReceived = hid_get_feature_report(udev, (unsigned char*) buffer, *len); - break; + bytesReceived = hid_get_feature_report(udev, (unsigned char *) buffer, *len); + break; } - if(bytesReceived < 0){ - pmsg_error("unable to send message: %ls\n", hid_error(udev)); - return USB_ERROR_IO; + if(bytesReceived < 0) { + pmsg_error("unable to send message: %ls\n", hid_error(udev)); + return USB_ERROR_IO; } *len = bytesReceived; return USB_ERROR_NONE; } -/* ------------------------------------------------------------------------ */ -/* ------------------------------------------------------------------------ */ -/* ------------------------------------------------------------------------ */ +// ------------------------------------------------------------------------ -/* ------------------------------------------------------------------------ */ -/* ------------------------------------------------------------------------ */ -/* ------------------------------------------------------------------------ */ +static void dumpBlock(const char *prefix, const unsigned char *buf, int len) { + int i; -/* ------------------------------------------------------------------------- */ - -static void dumpBlock(const char *prefix, const unsigned char *buf, int len) -{ - int i; - - if(len <= 8){ /* more compact format for short blocks */ - msg_info("%s: %d bytes: ", prefix, len); - for(i = 0; i < len; i++){ - msg_info("%02x ", buf[i]); - } - msg_info(" \""); - for(i = 0; i < len; i++) - msg_info("%c", buf[i] >= 0x20 && buf[i] < 0x7f? buf[i]: '.'); - msg_info("\"\n"); - }else{ - msg_info("%s: %d bytes:\n", prefix, len); - while(len > 0){ - for(i = 0; i < 16; i++){ - if(i < len){ - msg_info("%02x ", buf[i]); - }else{ - msg_info(" "); - } - if(i == 7) - msg_info(" "); - } - msg_info(" \""); - for(i = 0; i < 16 && i < len; i++) - msg_info("%c", buf[i] >= 0x20 && buf[i] < 0x7f? buf[i]: '.'); - msg_info("\"\n"); - buf += 16; - len -= 16; + if(len <= 8) { // More compact format for short blocks + msg_info("%s: %d bytes: ", prefix, len); + for(i = 0; i < len; i++) { + msg_info("%02x ", buf[i]); + } + msg_info(" \""); + for(i = 0; i < len; i++) + msg_info("%c", buf[i] >= 0x20 && buf[i] < 0x7f? buf[i]: '.'); + msg_info("\"\n"); + } else { + msg_info("%s: %d bytes:\n", prefix, len); + while(len > 0) { + for(i = 0; i < 16; i++) { + if(i < len) { + msg_info("%02x ", buf[i]); + } else { + msg_info(" "); } + if(i == 7) + msg_info(" "); + } + msg_info(" \""); + for(i = 0; i < 16 && i < len; i++) + msg_info("%c", buf[i] >= 0x20 && buf[i] < 0x7f? buf[i]: '.'); + msg_info("\"\n"); + buf += 16; + len -= 16; } + } } static const char *usbErrorText(int usbErrno) { - switch(usbErrno){ - case USB_ERROR_NONE: return "success"; - case USB_ERROR_ACCESS: return "access denied"; - case USB_ERROR_NOTFOUND:return "device not found"; - case USB_ERROR_BUSY: return "device is busy"; - case USB_ERROR_IO: return "I/O Error"; - default: { - char *buffer = avr_cc_buffer(32); - sprintf(buffer, "unknown error %d", usbErrno); - return buffer; - } + switch(usbErrno) { + case USB_ERROR_NONE: + return "success"; + case USB_ERROR_ACCESS: + return "access denied"; + case USB_ERROR_NOTFOUND: + return "device not found"; + case USB_ERROR_BUSY: + return "device is busy"; + case USB_ERROR_IO: + return "I/O Error"; + default:{ + char *buffer = avr_cc_buffer(32); + + sprintf(buffer, "unknown error %d", usbErrno); + return buffer; } + } } -/* ------------------------------------------------------------------------- */ +// ------------------------------------------------------------------------- -static int avrdoper_open(const char *port, union pinfo pinfo, union filedescriptor *fdp) -{ - int rval; - char *vname = "obdev.at"; - char *devname = "AVR-Doper"; +static int avrdoper_open(const char *port, union pinfo pinfo, union filedescriptor *fdp) { + int rval; + char *vname = "obdev.at"; + char *devname = "AVR-Doper"; - rval = usbOpenDevice(fdp, USB_VENDOR_ID, vname, USB_PRODUCT_ID, devname, 1); - if(rval != 0){ - pmsg_ext_error("USB %s\n", usbErrorText(rval)); - return -1; - } - return 0; + rval = usbOpenDevice(fdp, USB_VENDOR_ID, vname, USB_PRODUCT_ID, devname, 1); + if(rval != 0) { + pmsg_ext_error("USB %s\n", usbErrorText(rval)); + return -1; + } + return 0; } -/* ------------------------------------------------------------------------- */ +// ------------------------------------------------------------------------- -static void avrdoper_close(union filedescriptor *fdp) -{ - usbCloseDevice(fdp); +static void avrdoper_close(union filedescriptor *fdp) { + usbCloseDevice(fdp); } -/* ------------------------------------------------------------------------- */ +// ------------------------------------------------------------------------- -static int chooseDataSize(int len) -{ - size_t i; +static int chooseDataSize(int len) { + size_t i; - for(i = 0; i < sizeof(reportDataSizes)/sizeof(reportDataSizes[0]); i++){ - if(reportDataSizes[i] >= len) - return i; - } - return i - 1; + for(i = 0; i < sizeof(reportDataSizes)/sizeof(reportDataSizes[0]); i++) { + if(reportDataSizes[i] >= len) + return i; + } + return i - 1; } -static int avrdoper_send(const union filedescriptor *fdp, const unsigned char *buf, size_t buflen) -{ - if(buflen > INT_MAX) { - pmsg_error("%s() called with too large buflen = %lu\n", __func__, (unsigned long) buflen); - return -1; - } - if(verbose >= MSG_TRACE) - dumpBlock("Send", buf, buflen); - while(buflen > 0){ - unsigned char buffer[256]; - int rval, lenIndex = chooseDataSize(buflen); - int thisLen = (int) buflen > reportDataSizes[lenIndex]? - reportDataSizes[lenIndex]: (int) buflen; - buffer[0] = lenIndex + 1; /* report ID */ - buffer[1] = thisLen; - memcpy(buffer + 2, buf, thisLen); - msg_trace("Sending %d bytes data chunk\n", thisLen); - rval = usbSetReport(fdp, USB_HID_REPORT_TYPE_FEATURE, (char *)buffer, - reportDataSizes[lenIndex] + 2); - if(rval != 0){ - pmsg_error("USB %s\n", usbErrorText(rval)); - return -1; - } - buflen -= thisLen; - buf += thisLen; +static int avrdoper_send(const union filedescriptor *fdp, const unsigned char *buf, size_t buflen) { + if(buflen > INT_MAX) { + pmsg_error("%s() called with too large buflen = %lu\n", __func__, (unsigned long) buflen); + return -1; + } + if(verbose >= MSG_TRACE) + dumpBlock("Send", buf, buflen); + while(buflen > 0) { + unsigned char buffer[256]; + int rval, lenIndex = chooseDataSize(buflen); + int thisLen = (int) buflen > reportDataSizes[lenIndex]? reportDataSizes[lenIndex]: (int) buflen; + + buffer[0] = lenIndex + 1; // Report ID + buffer[1] = thisLen; + memcpy(buffer + 2, buf, thisLen); + msg_trace("Sending %d bytes data chunk\n", thisLen); + rval = usbSetReport(fdp, USB_HID_REPORT_TYPE_FEATURE, (char *) buffer, reportDataSizes[lenIndex] + 2); + if(rval != 0) { + pmsg_error("USB %s\n", usbErrorText(rval)); + return -1; } - return 0; + buflen -= thisLen; + buf += thisLen; + } + return 0; } -/* ------------------------------------------------------------------------- */ +// ------------------------------------------------------------------------- static int avrdoperFillBuffer(const union filedescriptor *fdp) { - int bytesPending = reportDataSizes[1]; /* guess how much data is buffered in device */ - - cx->sad_avrdoperRxPosition = cx->sad_avrdoperRxLength = 0; - while(bytesPending > 0){ - int len, usbErr, lenIndex = chooseDataSize(bytesPending); - unsigned char buffer[128]; - len = sizeof(cx->sad_avrdoperRxBuffer) - cx->sad_avrdoperRxLength; /* bytes remaining */ - if(reportDataSizes[lenIndex] + 2 > len) /* requested data would not fit into buffer */ - break; - len = reportDataSizes[lenIndex] + 2; - usbErr = usbGetReport(fdp, USB_HID_REPORT_TYPE_FEATURE, lenIndex + 1, - (char *)buffer, &len); - if(usbErr != 0){ - pmsg_error("USB %s\n", usbErrorText(usbErr)); - return -1; - } - msg_trace("Received %d bytes data chunk of total %d\n", len - 2, buffer[1]); - len -= 2; /* compensate for report ID and length byte */ - bytesPending = buffer[1] - len; /* amount still buffered */ - if(len > buffer[1]) /* cut away padding */ - len = buffer[1]; - if(cx->sad_avrdoperRxLength + len > (int) sizeof(cx->sad_avrdoperRxBuffer)){ - pmsg_error("buffer overflow\n"); - return -1; - } - memcpy(cx->sad_avrdoperRxBuffer + cx->sad_avrdoperRxLength, buffer + 2, len); - cx->sad_avrdoperRxLength += len; + int bytesPending = reportDataSizes[1]; // Guess how much data is buffered in device + + cx->sad_avrdoperRxPosition = cx->sad_avrdoperRxLength = 0; + while(bytesPending > 0) { + int len, usbErr, lenIndex = chooseDataSize(bytesPending); + unsigned char buffer[128]; + + len = sizeof(cx->sad_avrdoperRxBuffer) - cx->sad_avrdoperRxLength; // Bytes remaining + if(reportDataSizes[lenIndex] + 2 > len) // Requested data would not fit into buffer + break; + len = reportDataSizes[lenIndex] + 2; + usbErr = usbGetReport(fdp, USB_HID_REPORT_TYPE_FEATURE, lenIndex + 1, (char *) buffer, &len); + if(usbErr != 0) { + pmsg_error("USB %s\n", usbErrorText(usbErr)); + return -1; } - return 0; + msg_trace("Received %d bytes data chunk of total %d\n", len - 2, buffer[1]); + len -= 2; // Compensate for report ID and length byte + bytesPending = buffer[1] - len; // Amount still buffered + if(len > buffer[1]) // Cut away padding + len = buffer[1]; + if(cx->sad_avrdoperRxLength + len > (int) sizeof(cx->sad_avrdoperRxBuffer)) { + pmsg_error("buffer overflow\n"); + return -1; + } + memcpy(cx->sad_avrdoperRxBuffer + cx->sad_avrdoperRxLength, buffer + 2, len); + cx->sad_avrdoperRxLength += len; + } + return 0; } -static int avrdoper_recv(const union filedescriptor *fdp, unsigned char *buf, size_t buflen) -{ - unsigned char *p = buf; - int remaining = buflen; - - while(remaining > 0){ - int len, available = cx->sad_avrdoperRxLength - cx->sad_avrdoperRxPosition; - if(available <= 0){ /* buffer is empty */ - if (avrdoperFillBuffer(fdp) < 0) - return -1; - continue; - } - len = remaining < available ? remaining : available; - memcpy(p, cx->sad_avrdoperRxBuffer + cx->sad_avrdoperRxPosition, len); - p += len; - remaining -= len; - cx->sad_avrdoperRxPosition += len; +static int avrdoper_recv(const union filedescriptor *fdp, unsigned char *buf, size_t buflen) { + unsigned char *p = buf; + int remaining = buflen; + + while(remaining > 0) { + int len, available = cx->sad_avrdoperRxLength - cx->sad_avrdoperRxPosition; + + if(available <= 0) { // Buffer is empty + if(avrdoperFillBuffer(fdp) < 0) + return -1; + continue; } - if(verbose >= MSG_TRACE) - dumpBlock("Receive", buf, buflen); - return 0; + len = remaining < available? remaining: available; + memcpy(p, cx->sad_avrdoperRxBuffer + cx->sad_avrdoperRxPosition, len); + p += len; + remaining -= len; + cx->sad_avrdoperRxPosition += len; + } + if(verbose >= MSG_TRACE) + dumpBlock("Receive", buf, buflen); + return 0; } -/* ------------------------------------------------------------------------- */ +// ------------------------------------------------------------------------- -static int avrdoper_drain(const union filedescriptor *fdp, int display) -{ - do{ - if (avrdoperFillBuffer(fdp) < 0) - return -1; - }while(cx->sad_avrdoperRxLength > 0); - return 0; +static int avrdoper_drain(const union filedescriptor *fdp, int display) { + do { + if(avrdoperFillBuffer(fdp) < 0) + return -1; + } while(cx->sad_avrdoperRxLength > 0); + return 0; } -/* ------------------------------------------------------------------------- */ +// ------------------------------------------------------------------------- -static int avrdoper_set_dtr_rts(const union filedescriptor *fdp, int is_on) -{ - pmsg_error("AVR-Doper does not support DTR/RTS setting\n"); - return -1; +static int avrdoper_set_dtr_rts(const union filedescriptor *fdp, int is_on) { + pmsg_error("AVR-Doper does not support DTR/RTS setting\n"); + return -1; } -/* ------------------------------------------------------------------------- */ +// ------------------------------------------------------------------------- -struct serial_device avrdoper_serdev = -{ +struct serial_device avrdoper_serdev = { .open = avrdoper_open, .close = avrdoper_close, .rawclose = avrdoper_close, @@ -352,5 +332,4 @@ struct serial_device avrdoper_serdev = .set_dtr_rts = avrdoper_set_dtr_rts, .flags = SERDEV_FL_NONE, }; - -#endif /* defined(HAVE_LIBHIDAPI) */ +#endif // defined(HAVE_LIBHIDAPI) diff --git a/src/ser_posix.c b/src/ser_posix.c index 96a13f3d0..b71028f89 100644 --- a/src/ser_posix.c +++ b/src/ser_posix.c @@ -17,12 +17,9 @@ * along with this program. If not, see . */ -/* - * Posix serial interface for avrdude. - */ +// Posix serial interface for avrdude #if !defined(WIN32) - #include #include @@ -43,85 +40,101 @@ #include #ifdef __APPLE__ -# include +#include #endif #include "avrdude.h" #include "libavrdude.h" -long serial_recv_timeout = 5000; /* ms */ -long serial_drain_timeout = 250; /* ms */ +long serial_recv_timeout = 5000; // ms +long serial_drain_timeout = 250; // ms struct baud_mapping { long baud; speed_t speed; }; -static const struct baud_mapping baud_lookup_table [] = { - { 300, B300 }, - { 600, B600 }, - { 1200, B1200 }, - { 2400, B2400 }, - { 4800, B4800 }, - { 9600, B9600 }, - { 19200, B19200 }, - { 38400, B38400 }, +static const struct baud_mapping baud_lookup_table[] = { + {300, B300}, + {600, B600}, + {1200, B1200}, + {2400, B2400}, + {4800, B4800}, + {9600, B9600}, + {19200, B19200}, + {38400, B38400}, + #ifdef B57600 - { 57600, B57600 }, + {57600, B57600}, #endif + #ifdef B115200 - { 115200, B115200 }, + {115200, B115200}, #endif + #ifdef B230400 - { 230400, B230400 }, + {230400, B230400}, #endif + #ifdef B250000 - { 250000, B250000 }, + {250000, B250000}, #endif + #ifdef B460800 - { 460800, B460800 }, + {460800, B460800}, #endif + #ifdef B500000 - { 500000, B500000 }, + {500000, B500000}, #endif + #ifdef B576000 - { 576000, B576000 }, + {576000, B576000}, #endif + #ifdef B921600 - { 921600, B921600 }, + {921600, B921600}, #endif + #ifdef B1000000 - { 1000000, B1000000 }, + {1000000, B1000000}, #endif + #ifdef B1152000 - { 1152000, B1152000 }, + {1152000, B1152000}, #endif + #ifdef B1500000 - { 1500000, B1500000 }, + {1500000, B1500000}, #endif + #ifdef B2000000 - { 2000000, B2000000 }, + {2000000, B2000000}, #endif + #ifdef B2500000 - { 2500000, B2500000 }, + {2500000, B2500000}, #endif + #ifdef B3000000 - { 3000000, B3000000 }, + {3000000, B3000000}, #endif + #ifdef B3500000 - { 3500000, B3500000 }, + {3500000, B3500000}, #endif + #ifdef B4000000 - { 4000000, B4000000 }, + {4000000, B4000000}, #endif - { 0, 0 } /* Terminator. */ + {0, 0} // Terminator }; static speed_t serial_baud_lookup(long baud, bool *nonstandard) { *nonstandard = false; for(const struct baud_mapping *map = baud_lookup_table; map->baud; map++) - if (map->baud == baud) + if(map->baud == baud) return map->speed; // Return the raw rate when asked for non-standard baud rate @@ -135,75 +148,78 @@ static int ser_setparams(const union filedescriptor *fd, long baud, unsigned lon int rc; struct termios termios; bool nonstandard; - speed_t speed = serial_baud_lookup (baud, &nonstandard); - - if (!isatty(fd->ifd)) + speed_t speed = serial_baud_lookup(baud, &nonstandard); + + if(!isatty(fd->ifd)) return -ENOTTY; - - /* - * initialize terminal modes - */ + + // Initialize terminal modes rc = tcgetattr(fd->ifd, &termios); - if (rc < 0) { + if(rc < 0) { int ret = -errno; + pmsg_ext_error("tcgetattr() failed\n"); return ret; } - /* - * copy termios for ser_close if we haven't already - */ + // Copy termios for ser_close if we haven't already if(!cx->ser_saved_original_termios++) cx->ser_original_termios = termios; - if (cflags & SERIAL_CREAD) { - termios.c_cflag |= CREAD; + if(cflags & SERIAL_CREAD) { + termios.c_cflag |= CREAD; } - if (cflags & SERIAL_CLOCAL) { + if(cflags & SERIAL_CLOCAL) { termios.c_cflag |= CLOCAL; } termios.c_lflag &= ~(ICANON | ECHO | ECHOE | ECHOK | ECHONL | ISIG | IEXTEN); + #ifdef ECHOCTL termios.c_lflag &= ~ECHOCTL; -#endif /* ECHOCTL */ +#endif // ECHOCTL + #ifdef ECHOKE termios.c_lflag &= ~ECHOKE; -#endif /* ECHOKE */ - termios.c_oflag &= ~(OPOST | ONLCR | OCRNL); +#endif // ECHOKE + + termios.c_oflag &= ~(OPOST | ONLCR | OCRNL); termios.c_iflag &= ~(INLCR | IGNCR | ICRNL | IGNBRK); + #ifdef IUCLC termios.c_iflag &= ~IUCLC; -#endif /* IUCLC */ +#endif // IUCLC + #ifdef PARMRK termios.c_iflag &= ~PARMRK; -#endif /* PARMRK */ +#endif // PARMRK - // MacOS doesn't handle nonstandard baudrate values in - // normal tcsetattr(), sigh. + // MacOS doesn't handle nonstandard baudrate values in normal tcsetattr(), sigh #ifdef __APPLE__ - if (!nonstandard) { + if(!nonstandard) { #endif + cfsetospeed(&termios, speed); cfsetispeed(&termios, speed); + #ifdef __APPLE__ } #endif termios.c_cflag &= ~CSIZE; - if (cflags & SERIAL_CS8) { + if(cflags & SERIAL_CS8) { termios.c_cflag |= CS8; } - if (cflags & SERIAL_CS7) { + if(cflags & SERIAL_CS7) { termios.c_cflag |= CS7; } - if (cflags & SERIAL_CS6) { + if(cflags & SERIAL_CS6) { termios.c_cflag |= CS6; } - if (cflags & SERIAL_CS5) { + if(cflags & SERIAL_CS5) { termios.c_cflag |= CS5; } - if (cflags & SERIAL_CSTOPB) { + if(cflags & SERIAL_CSTOPB) { termios.c_cflag |= CSTOPB; } else { termios.c_cflag &= ~CSTOPB; @@ -211,13 +227,13 @@ static int ser_setparams(const union filedescriptor *fd, long baud, unsigned lon termios.c_iflag &= ~(INPCK | ISTRIP); - if (cflags & (SERIAL_PARENB | SERIAL_PARODD)) { + if(cflags & (SERIAL_PARENB | SERIAL_PARODD)) { termios.c_cflag |= PARENB; } else { termios.c_cflag &= ~PARENB; } - if (cflags & SERIAL_PARODD) { + if(cflags & SERIAL_PARODD) { termios.c_cflag |= PARODD; } else { termios.c_cflag &= ~PARODD; @@ -225,46 +241,48 @@ static int ser_setparams(const union filedescriptor *fd, long baud, unsigned lon #ifdef IXANY termios.c_iflag &= ~IXANY; -#endif /* IXANY */ +#endif // IXANY + termios.c_iflag &= ~(IXON | IXOFF); #ifdef CRTSCTS termios.c_iflag &= ~CRTSCTS; -#endif /* CRTSCTS */ +#endif // CRTSCTS #ifdef CNEW_RTSCTS termios.c_iflag &= ~CNEW_RTSCTS; -#endif /* CRTSCTS */ - +#endif // CRTSCTS rc = tcsetattr(fd->ifd, TCSANOW, &termios); - if (rc < 0) { + if(rc < 0) { int ret = -errno; + pmsg_ext_error("tcsetattr() failed\n"); return ret; } #ifdef __APPLE__ - // handle nonstandard speed values the MacOS way - if (nonstandard) { - if (ioctl(fd->ifd, IOSSIOSPEED, &speed) < 0) { + // Handle nonstandard speed values the MacOS way + if(nonstandard) { + if(ioctl(fd->ifd, IOSSIOSPEED, &speed) < 0) { int ret = -errno; + pmsg_ext_error("ioctrl(IOSSIOSPEED) failed\n"); return ret; } } -#endif // __APPLE__ +#endif // __APPLE__ tcflush(fd->ifd, TCIFLUSH); - + return 0; } /* - * Given a port description of the form :, open a TCP - * connection to the specified destination, which is assumed to be a - * terminal/console server with serial parameters configured - * appropriately (e. g. 115200-8-N-1 for a STK500.) + * Given a port description of the form :, open a TCP connection to + * the specified destination, which is assumed to be a terminal/console server + * with serial parameters configured appropriately (e.g. 115200-8-N-1 for a + * STK500.) */ static int net_open(const char *port, union filedescriptor *fdp) { char *hp, *hstr, *pstr; @@ -275,26 +293,22 @@ static int net_open(const char *port, union filedescriptor *fdp) { hstr = hp = mmt_strdup(port); /* - * As numeric IPv6 addresses use colons as separators, we need to - * look for the last colon here, which separates the port number or - * service name from the host or IP address. + * As numeric IPv6 addresses use colons as separators, we need to look for + * the last colon here, which separates the port number or service name from + * the host or IP address. */ - if (((pstr = strrchr(hstr, ':')) == NULL) || (pstr == hstr)) { + if(((pstr = strrchr(hstr, ':')) == NULL) || (pstr == hstr)) { pmsg_error("mangled host:port string %s\n", hstr); goto error; } - /* - * Remove brackets from the host part, if present. - */ - if (*hstr == '[' && *(pstr-1) == ']') { + // Remove brackets from the host part, if present + if(*hstr == '[' && *(pstr - 1) == ']') { hstr++; - *(pstr-1) = '\0'; + *(pstr - 1) = '\0'; } - /* - * Terminate the host section of the description. - */ + // Terminate the host section of the description *pstr++ = '\0'; memset(&hints, 0, sizeof(hints)); @@ -302,27 +316,25 @@ static int net_open(const char *port, union filedescriptor *fdp) { hints.ai_socktype = SOCK_STREAM; s = getaddrinfo(hstr, pstr, &hints, &result); - if (s != 0) { - pmsg_ext_error("cannot resolve host=\"%s\", port=\"%s\": %s\n", - hstr, pstr, gai_strerror(s)); + if(s != 0) { + pmsg_ext_error("cannot resolve host=\"%s\", port=\"%s\": %s\n", hstr, pstr, gai_strerror(s)); goto error; } - for (rp = result; rp != NULL; rp = rp->ai_next) { + for(rp = result; rp != NULL; rp = rp->ai_next) { fd = socket(rp->ai_family, rp->ai_socktype, rp->ai_protocol); - if (fd == -1) { - /* This one failed, loop over */ + if(fd == -1) { + // This one failed, loop over continue; } - if (connect(fd, rp->ai_addr, rp->ai_addrlen) != -1) { - /* Success, we are connected */ + if(connect(fd, rp->ai_addr, rp->ai_addrlen) != -1) { + // Success, we are connected break; } close(fd); } - if (rp == NULL) { + if(rp == NULL) { pmsg_ext_error("cannot connect: %s\n", strerror(errno)); - } - else { + } else { fdp->ifd = fd; ret = 0; } @@ -334,26 +346,25 @@ static int net_open(const char *port, union filedescriptor *fdp) { } static int ser_set_dtr_rts(const union filedescriptor *fdp, int is_on) { - unsigned int ctl; - int r; + unsigned int ctl; + int r; r = ioctl(fdp->ifd, TIOCMGET, &ctl); - if (r < 0) { + if(r < 0) { pmsg_ext_error("ioctl(\"TIOCMGET\"): %s\n", strerror(errno)); return -1; } - if (is_on) { - /* Set DTR and RTS */ + if(is_on) { + // Set DTR and RTS ctl |= (TIOCM_DTR | TIOCM_RTS); - } - else { - /* Clear DTR and RTS */ + } else { + // Clear DTR and RTS ctl &= ~(TIOCM_DTR | TIOCM_RTS); } r = ioctl(fdp->ifd, TIOCMSET, &ctl); - if (r < 0) { + if(r < 0) { pmsg_ext_error("ioctl(\"TIOCMSET\"): %s\n", strerror(errno)); return -1; } @@ -366,29 +377,25 @@ static int ser_open(const char *port, union pinfo pinfo, union filedescriptor *f int fd; /* - * If the port is of the form "net::", then - * handle it as a TCP connection to a terminal server. + * If the port is of the form "net::", then handle it as a TCP + * connection to a terminal server. */ - if (str_starts(port, "net:")) { + if(str_starts(port, "net:")) { return net_open(port + strlen("net:"), fdp); } - /* - * open the serial port - */ + // Open the serial port fd = open(port, O_RDWR | O_NOCTTY | O_NONBLOCK); - if (fd < 0) { + if(fd < 0) { pmsg_ext_error("cannot open port %s: %s\n", port, strerror(errno)); return -1; } fdp->ifd = fd; - /* - * set serial line attributes - */ + // Set serial line attributes rc = ser_setparams(fdp, pinfo.serialinfo.baud, pinfo.serialinfo.cflags); - if (rc) { + if(rc) { pmsg_ext_error("cannot set attributes for port %s: %s\n", port, strerror(-rc)); close(fd); return -1; @@ -400,6 +407,7 @@ static void ser_close(union filedescriptor *fd) { // Restore original termios settings from ser_open if(cx->ser_saved_original_termios) { int rc = tcsetattr(fd->ifd, TCSANOW | TCSADRAIN, &cx->ser_original_termios); + if(rc) pmsg_ext_error("cannot reset attributes for device: %s\n", strerror(errno)); cx->ser_saved_original_termios = 0; @@ -422,7 +430,7 @@ static int ser_send(const union filedescriptor *fd, const unsigned char *buf, si while(len) { rc = write(fd->ifd, buf, len > 1024? 1024: len); - if (rc < 0) { + if(rc < 0) { pmsg_ext_error("unable to write: %s\n", strerror(errno)); return -1; } @@ -433,7 +441,6 @@ static int ser_send(const union filedescriptor *fd, const unsigned char *buf, si return 0; } - static int ser_recv(const union filedescriptor *fd, unsigned char *buf, size_t buflen) { struct timeval timeout, to2; fd_set rfds; @@ -442,33 +449,31 @@ static int ser_recv(const union filedescriptor *fd, unsigned char *buf, size_t b unsigned char *p = buf; size_t len = 0; - timeout.tv_sec = serial_recv_timeout / 1000L; - timeout.tv_usec = (serial_recv_timeout % 1000L) * 1000; + timeout.tv_sec = serial_recv_timeout/1000L; + timeout.tv_usec = (serial_recv_timeout%1000L)*1000; to2 = timeout; - while (len < buflen) { + while(len < buflen) { reselect: FD_ZERO(&rfds); FD_SET(fd->ifd, &rfds); nfds = select(fd->ifd + 1, &rfds, NULL, NULL, &to2); - if (nfds == 0) { + if(nfds == 0) { pmsg_notice2("%s(): programmer is not responding\n", __func__); return -1; - } - else if (nfds == -1) { - if (errno == EINTR || errno == EAGAIN) { - pmsg_warning("programmer is not responding, reselecting\n"); + } else if(nfds == -1) { + if(errno == EINTR || errno == EAGAIN) { + pmsg_warning("programmer is not responding, reselecting\n"); goto reselect; - } - else { + } else { pmsg_ext_error("select(): %s\n", strerror(errno)); return -1; } } rc = read(fd->ifd, p, buflen - len > 1024? 1024: buflen - len); - if (rc < 0) { + if(rc < 0) { pmsg_ext_error("unable to read: %s\n", strerror(errno)); return -1; } @@ -482,7 +487,6 @@ static int ser_recv(const union filedescriptor *fd, unsigned char *buf, size_t b return 0; } - static int ser_drain(const union filedescriptor *fd, int display) { struct timeval timeout; fd_set rfds; @@ -493,39 +497,37 @@ static int ser_drain(const union filedescriptor *fd, int display) { timeout.tv_sec = 0; timeout.tv_usec = serial_drain_timeout*1000L; - if (display) { + if(display) { msg_info("drain>"); } - while (1) { + while(1) { FD_ZERO(&rfds); FD_SET(fd->ifd, &rfds); reselect: nfds = select(fd->ifd + 1, &rfds, NULL, NULL, &timeout); - if (nfds == 0) { - if (display) { + if(nfds == 0) { + if(display) { msg_info("ifd, &buf, 1); - if (rc < 0) { + if(rc < 0) { pmsg_ext_error("unable to read: %s\n", strerror(errno)); return -1; } - if (display) { + if(display) { msg_info("%02x ", buf); } } @@ -533,8 +535,7 @@ static int ser_drain(const union filedescriptor *fd, int display) { return 0; } -struct serial_device serial_serdev = -{ +struct serial_device serial_serdev = { .open = ser_open, .setparams = ser_setparams, .close = ser_close, @@ -547,6 +548,4 @@ struct serial_device serial_serdev = }; struct serial_device *serdev = &serial_serdev; - -#endif /* WIN32 */ - +#endif // WIN32 diff --git a/src/ser_win32.c b/src/ser_win32.c index f37f4bb5f..8a53ad46c 100644 --- a/src/ser_win32.c +++ b/src/ser_win32.c @@ -17,27 +17,24 @@ * along with this program. If not, see . */ -/* - * Native Win32 serial interface for avrdude. - */ +// Native Win32 serial interface for avrdude #include #if defined(WIN32) - #define WIN32_LEAN_AND_MEAN #include #include #include #include -#include /* for isprint */ -#include /* ENOTTY */ +#include // For isprint +#include // ENOTTY #include "avrdude.h" #include "libavrdude.h" -long serial_recv_timeout = 5000; /* ms */ -long serial_drain_timeout = 250; /* ms */ +long serial_recv_timeout = 5000; // ms +long serial_drain_timeout = 250; // ms #define W32SERBUFSIZE 1024 @@ -46,25 +43,25 @@ struct baud_mapping { DWORD speed; }; -/* HANDLE hComPort=INVALID_HANDLE_VALUE; */ - -static const struct baud_mapping baud_lookup_table [] = { - { 300, CBR_300 }, - { 600, CBR_600 }, - { 1200, CBR_1200 }, - { 2400, CBR_2400 }, - { 4800, CBR_4800 }, - { 9600, CBR_9600 }, - { 19200, CBR_19200 }, - { 38400, CBR_38400 }, - { 57600, CBR_57600 }, - { 115200, CBR_115200 }, - { 0, 0 } /* Terminator. */ +// HANDLE hComPort=INVALID_HANDLE_VALUE; + +static const struct baud_mapping baud_lookup_table[] = { + {300, CBR_300}, + {600, CBR_600}, + {1200, CBR_1200}, + {2400, CBR_2400}, + {4800, CBR_4800}, + {9600, CBR_9600}, + {19200, CBR_19200}, + {38400, CBR_38400}, + {57600, CBR_57600}, + {115200, CBR_115200}, + {0, 0} // Terminator }; static DWORD serial_baud_lookup(long baud) { for(const struct baud_mapping *map = baud_lookup_table; map->baud; map++) - if (map->baud == baud) + if(map->baud == baud) return map->speed; // Return the raw rate when asked for non-standard baud rate @@ -73,580 +70,508 @@ static DWORD serial_baud_lookup(long baud) { return baud; } +static BOOL serial_w32SetTimeOut(HANDLE hComPort, DWORD timeout) { // ms + COMMTIMEOUTS ctmo; -static BOOL serial_w32SetTimeOut(HANDLE hComPort, DWORD timeout) // in ms -{ - COMMTIMEOUTS ctmo; - ZeroMemory (&ctmo, sizeof(COMMTIMEOUTS)); - ctmo.ReadIntervalTimeout = 0; - ctmo.ReadTotalTimeoutMultiplier = 0; - ctmo.ReadTotalTimeoutConstant = timeout; + ZeroMemory(&ctmo, sizeof(COMMTIMEOUTS)); + ctmo.ReadIntervalTimeout = 0; + ctmo.ReadTotalTimeoutMultiplier = 0; + ctmo.ReadTotalTimeoutConstant = timeout; - return SetCommTimeouts(hComPort, &ctmo); + return SetCommTimeouts(hComPort, &ctmo); } static int ser_setparams(const union filedescriptor *fd, long baud, unsigned long cflags) { - if(cx->ser_serial_over_ethernet) - return -ENOTTY; - - DCB dcb; - HANDLE hComPort = (HANDLE)fd->pfd; - - ZeroMemory (&dcb, sizeof(DCB)); - dcb.DCBlength = sizeof(DCB); - dcb.BaudRate = serial_baud_lookup (baud); - dcb.fBinary = 1; - dcb.fDtrControl = DTR_CONTROL_DISABLE; - dcb.fRtsControl = RTS_CONTROL_DISABLE; - switch ((cflags & (SERIAL_CS5 | SERIAL_CS6 | SERIAL_CS7 | SERIAL_CS8))) { - case SERIAL_CS5: - dcb.ByteSize = 5; - break; - case SERIAL_CS6: - dcb.ByteSize = 6; - break; - case SERIAL_CS7: - dcb.ByteSize = 7; - break; - case SERIAL_CS8: - dcb.ByteSize = 8; - break; - } - switch ((cflags & (SERIAL_NO_PARITY | SERIAL_PARENB | SERIAL_PARODD))) { - case SERIAL_NO_PARITY: - dcb.Parity = NOPARITY; - break; - case SERIAL_PARENB: - dcb.Parity = EVENPARITY; - break; - case SERIAL_PARODD: - dcb.Parity = ODDPARITY; - break; - } - switch ((cflags & (SERIAL_NO_CSTOPB | SERIAL_CSTOPB))) { - case SERIAL_NO_CSTOPB: - dcb.StopBits = ONESTOPBIT; - break; - case SERIAL_CSTOPB: - dcb.StopBits = TWOSTOPBITS; - break; - } - if (!SetCommState(hComPort, &dcb)) - return -1; - - return 0; + if(cx->ser_serial_over_ethernet) + return -ENOTTY; + + DCB dcb; + HANDLE hComPort = (HANDLE) fd->pfd; + + ZeroMemory(&dcb, sizeof(DCB)); + dcb.DCBlength = sizeof(DCB); + dcb.BaudRate = serial_baud_lookup(baud); + dcb.fBinary = 1; + dcb.fDtrControl = DTR_CONTROL_DISABLE; + dcb.fRtsControl = RTS_CONTROL_DISABLE; + switch((cflags & (SERIAL_CS5 | SERIAL_CS6 | SERIAL_CS7 | SERIAL_CS8))) { + case SERIAL_CS5: + dcb.ByteSize = 5; + break; + case SERIAL_CS6: + dcb.ByteSize = 6; + break; + case SERIAL_CS7: + dcb.ByteSize = 7; + break; + case SERIAL_CS8: + dcb.ByteSize = 8; + break; + } + switch((cflags & (SERIAL_NO_PARITY | SERIAL_PARENB | SERIAL_PARODD))) { + case SERIAL_NO_PARITY: + dcb.Parity = NOPARITY; + break; + case SERIAL_PARENB: + dcb.Parity = EVENPARITY; + break; + case SERIAL_PARODD: + dcb.Parity = ODDPARITY; + break; + } + switch((cflags & (SERIAL_NO_CSTOPB | SERIAL_CSTOPB))) { + case SERIAL_NO_CSTOPB: + dcb.StopBits = ONESTOPBIT; + break; + case SERIAL_CSTOPB: + dcb.StopBits = TWOSTOPBITS; + break; + } + if(!SetCommState(hComPort, &dcb)) + return -1; + + return 0; } static int net_open(const char *port, union filedescriptor *fdp) { - WSADATA wsaData; - LPVOID lpMsgBuf; - - char *hstr, *pstr, *end; - unsigned int pnum; - int fd; - struct sockaddr_in sockaddr; - struct hostent *hp; - - if (WSAStartup(MAKEWORD(2, 0), &wsaData) != 0) { - pmsg_error("WSAStartup() failed\n"); - return -1; - } - - hstr = mmt_strdup(port); - if (((pstr = strchr(hstr, ':')) == NULL) || (pstr == hstr)) { - pmsg_error("mangled host:port string %s\n", hstr); - mmt_free(hstr); - return -1; - } - - /* - * Terminate the host section of the description. - */ - *pstr++ = '\0'; - - pnum = strtoul(pstr, &end, 10); - - if ((*pstr == '\0') || (*end != '\0') || (pnum == 0) || (pnum > 65535)) { - pmsg_error("bad port number %s\n", pstr); - mmt_free(hstr); - return -1; - } - - if ((hp = gethostbyname(hstr)) == NULL) { - pmsg_error("unknown host %s\n", hstr); - mmt_free(hstr); - return -1; - } - - mmt_free(hstr); - - if ((fd = socket(PF_INET, SOCK_STREAM, 0)) < 0) { - FormatMessage( - FORMAT_MESSAGE_ALLOCATE_BUFFER | - FORMAT_MESSAGE_FROM_SYSTEM | - FORMAT_MESSAGE_IGNORE_INSERTS, - NULL, - WSAGetLastError(), - MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), - (LPTSTR)&lpMsgBuf, - 0, - NULL); - pmsg_error("cannot open socket: %s\n", (char *) lpMsgBuf); - LocalFree(lpMsgBuf); - return -1; - } - - memset(&sockaddr, 0, sizeof(struct sockaddr_in)); - sockaddr.sin_family = AF_INET; - sockaddr.sin_port = htons(pnum); - memcpy(&(sockaddr.sin_addr.s_addr), hp->h_addr, sizeof(struct in_addr)); - - if (connect(fd, (struct sockaddr *)&sockaddr, sizeof(sockaddr))) { - FormatMessage( - FORMAT_MESSAGE_ALLOCATE_BUFFER | - FORMAT_MESSAGE_FROM_SYSTEM | - FORMAT_MESSAGE_IGNORE_INSERTS, - NULL, - WSAGetLastError(), - MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), - (LPTSTR)&lpMsgBuf, - 0, - NULL); - pmsg_error("connect failed: %s\n", (char *) lpMsgBuf); - LocalFree(lpMsgBuf); - return -1; - } - - fdp->ifd = fd; - - cx->ser_serial_over_ethernet = 1; - return 0; + WSADATA wsaData; + LPVOID lpMsgBuf; + + char *hstr, *pstr, *end; + unsigned int pnum; + int fd; + struct sockaddr_in sockaddr; + struct hostent *hp; + + if(WSAStartup(MAKEWORD(2, 0), &wsaData) != 0) { + pmsg_error("WSAStartup() failed\n"); + return -1; + } + + hstr = mmt_strdup(port); + if(((pstr = strchr(hstr, ':')) == NULL) || (pstr == hstr)) { + pmsg_error("mangled host:port string %s\n", hstr); + mmt_free(hstr); + return -1; + } + + // Terminate the host section of the description + *pstr++ = '\0'; + + pnum = strtoul(pstr, &end, 10); + + if((*pstr == '\0') || (*end != '\0') || (pnum == 0) || (pnum > 65535)) { + pmsg_error("bad port number %s\n", pstr); + mmt_free(hstr); + return -1; + } + + if((hp = gethostbyname(hstr)) == NULL) { + pmsg_error("unknown host %s\n", hstr); + mmt_free(hstr); + return -1; + } + + mmt_free(hstr); + + if((fd = socket(PF_INET, SOCK_STREAM, 0)) < 0) { + FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | + FORMAT_MESSAGE_FROM_SYSTEM | + FORMAT_MESSAGE_IGNORE_INSERTS, + NULL, WSAGetLastError(), MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), (LPTSTR) & lpMsgBuf, 0, NULL); + pmsg_error("cannot open socket: %s\n", (char *) lpMsgBuf); + LocalFree(lpMsgBuf); + return -1; + } + + memset(&sockaddr, 0, sizeof(struct sockaddr_in)); + sockaddr.sin_family = AF_INET; + sockaddr.sin_port = htons(pnum); + memcpy(&(sockaddr.sin_addr.s_addr), hp->h_addr, sizeof(struct in_addr)); + + if(connect(fd, (struct sockaddr *) &sockaddr, sizeof(sockaddr))) { + FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | + FORMAT_MESSAGE_FROM_SYSTEM | + FORMAT_MESSAGE_IGNORE_INSERTS, + NULL, WSAGetLastError(), MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), (LPTSTR) & lpMsgBuf, 0, NULL); + pmsg_error("connect failed: %s\n", (char *) lpMsgBuf); + LocalFree(lpMsgBuf); + return -1; + } + + fdp->ifd = fd; + + cx->ser_serial_over_ethernet = 1; + return 0; } - static int ser_open(const char *port, union pinfo pinfo, union filedescriptor *fdp) { - LPVOID lpMsgBuf; - HANDLE hComPort=INVALID_HANDLE_VALUE; - char *newname = 0; - - /* - * If the port is of the form "net::", then - * handle it as a TCP connection to a terminal server. - */ - if (str_starts(port, "net:")) { - return net_open(port + strlen("net:"), fdp); - } - - if (str_casestarts(port, "com")) { - - // prepend "\\\\.\\" to name, required for port # >= 10 - newname = mmt_malloc(strlen("\\\\.\\") + strlen(port) + 1); - strcpy(newname, "\\\\.\\"); - strcat(newname, port); - - port = newname; - } - - hComPort = CreateFile(port, GENERIC_READ | GENERIC_WRITE, 0, NULL, - OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); - - if (hComPort == INVALID_HANDLE_VALUE) { - FormatMessage( - FORMAT_MESSAGE_ALLOCATE_BUFFER | - FORMAT_MESSAGE_FROM_SYSTEM | - FORMAT_MESSAGE_IGNORE_INSERTS, - NULL, - GetLastError(), - MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), // Default language - (LPTSTR) &lpMsgBuf, - 0, - NULL); - pmsg_error("cannot open port %s: %s\n", port, (char*) lpMsgBuf); - LocalFree( lpMsgBuf ); - return -1; - } - - if (!SetupComm(hComPort, W32SERBUFSIZE, W32SERBUFSIZE)) - { - CloseHandle(hComPort); - pmsg_error("cannot set buffers for %s\n", port); - return -1; - } - - fdp->pfd = (void *)hComPort; - if (ser_setparams(fdp, pinfo.serialinfo.baud, pinfo.serialinfo.cflags) != 0) - { - CloseHandle(hComPort); - pmsg_error("cannot set com-state for %s\n", port); - return -1; - } - - if (!serial_w32SetTimeOut(hComPort,0)) - { - CloseHandle(hComPort); - pmsg_error("cannot set initial timeout for %s\n", port); - return -1; - } - - if (newname != 0) { - mmt_free(newname); - } - return 0; + LPVOID lpMsgBuf; + HANDLE hComPort = INVALID_HANDLE_VALUE; + char *newname = 0; + + /* + * If the port is of the form "net::", then handle it as a TCP + * connection to a terminal server. + */ + if(str_starts(port, "net:")) { + return net_open(port + strlen("net:"), fdp); + } + + if(str_casestarts(port, "com")) { + + // Prepend "\\\\.\\" to name, required for port # >= 10 + newname = mmt_malloc(strlen("\\\\.\\") + strlen(port) + 1); + strcpy(newname, "\\\\.\\"); + strcat(newname, port); + + port = newname; + } + + hComPort = CreateFile(port, GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); + + if(hComPort == INVALID_HANDLE_VALUE) { + FormatMessage( + FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, + NULL, GetLastError(), MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), // Default language + (LPTSTR) & lpMsgBuf, 0, NULL); + pmsg_error("cannot open port %s: %s\n", port, (char *) lpMsgBuf); + LocalFree(lpMsgBuf); + return -1; + } + + if(!SetupComm(hComPort, W32SERBUFSIZE, W32SERBUFSIZE)) { + CloseHandle(hComPort); + pmsg_error("cannot set buffers for %s\n", port); + return -1; + } + + fdp->pfd = (void *) hComPort; + if(ser_setparams(fdp, pinfo.serialinfo.baud, pinfo.serialinfo.cflags) != 0) { + CloseHandle(hComPort); + pmsg_error("cannot set com-state for %s\n", port); + return -1; + } + + if(!serial_w32SetTimeOut(hComPort, 0)) { + CloseHandle(hComPort); + pmsg_error("cannot set initial timeout for %s\n", port); + return -1; + } + + if(newname != 0) { + mmt_free(newname); + } + return 0; } - static void ser_close(union filedescriptor *fd) { - if (cx->ser_serial_over_ethernet) { - closesocket(fd->ifd); - WSACleanup(); - } else { - HANDLE hComPort=(HANDLE)fd->pfd; - if (hComPort != INVALID_HANDLE_VALUE) - CloseHandle (hComPort); - - hComPort = INVALID_HANDLE_VALUE; - } + if(cx->ser_serial_over_ethernet) { + closesocket(fd->ifd); + WSACleanup(); + } else { + HANDLE hComPort = (HANDLE) fd->pfd; + + if(hComPort != INVALID_HANDLE_VALUE) + CloseHandle(hComPort); + + hComPort = INVALID_HANDLE_VALUE; + } } static int ser_set_dtr_rts(const union filedescriptor *fd, int is_on) { - if(cx->ser_serial_over_ethernet) - return 0; + if(cx->ser_serial_over_ethernet) + return 0; - HANDLE hComPort=(HANDLE)fd->pfd; + HANDLE hComPort = (HANDLE) fd->pfd; - EscapeCommFunction(hComPort, is_on? SETDTR: CLRDTR); - EscapeCommFunction(hComPort, is_on? SETRTS: CLRRTS); + EscapeCommFunction(hComPort, is_on? SETDTR: CLRDTR); + EscapeCommFunction(hComPort, is_on? SETRTS: CLRRTS); - return 0; + return 0; } static int net_send(const union filedescriptor *fd, const unsigned char *buf, size_t len) { - LPVOID lpMsgBuf; - int rc; - - if (fd->ifd < 0) { - pmsg_notice("%s(): connection not open\n", __func__); - return -1; - } - - if (!len) - return 0; - - if (verbose >= MSG_TRACE) - trace_buffer(__func__, buf, len); - - while (len) { - rc = send(fd->ifd, (const char *) buf, len > 1024? 1024: len, 0); - if (rc < 0) { - FormatMessage( - FORMAT_MESSAGE_ALLOCATE_BUFFER | - FORMAT_MESSAGE_FROM_SYSTEM | - FORMAT_MESSAGE_IGNORE_INSERTS, - NULL, - WSAGetLastError(), - MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), - (LPTSTR)&lpMsgBuf, - 0, - NULL); - pmsg_error("unable to send: %s\n", (char *) lpMsgBuf); - LocalFree(lpMsgBuf); - return -1; - } - buf += rc; - len -= rc; - } - - return 0; -} + LPVOID lpMsgBuf; + int rc; + + if(fd->ifd < 0) { + pmsg_notice("%s(): connection not open\n", __func__); + return -1; + } + + if(!len) + return 0; + + if(verbose >= MSG_TRACE) + trace_buffer(__func__, buf, len); + + while(len) { + rc = send(fd->ifd, (const char *) buf, len > 1024? 1024: len, 0); + if(rc < 0) { + FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | + FORMAT_MESSAGE_FROM_SYSTEM | + FORMAT_MESSAGE_IGNORE_INSERTS, + NULL, WSAGetLastError(), MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), (LPTSTR) & lpMsgBuf, 0, NULL); + pmsg_error("unable to send: %s\n", (char *) lpMsgBuf); + LocalFree(lpMsgBuf); + return -1; + } + buf += rc; + len -= rc; + } + return 0; +} static int ser_send(const union filedescriptor *fd, const unsigned char *buf, size_t len) { - if(cx->ser_serial_over_ethernet) - return net_send(fd, buf, len); + if(cx->ser_serial_over_ethernet) + return net_send(fd, buf, len); - DWORD written; + DWORD written; - HANDLE hComPort=(HANDLE)fd->pfd; + HANDLE hComPort = (HANDLE) fd->pfd; - if (hComPort == INVALID_HANDLE_VALUE) { - pmsg_error("port not open\n"); - return -1; - } + if(hComPort == INVALID_HANDLE_VALUE) { + pmsg_error("port not open\n"); + return -1; + } - if (!len) - return 0; + if(!len) + return 0; - if (verbose >= MSG_TRACE) - trace_buffer(__func__, buf, len); - - serial_w32SetTimeOut(hComPort,500); + if(verbose >= MSG_TRACE) + trace_buffer(__func__, buf, len); - if (!WriteFile (hComPort, buf, len, &written, NULL)) { - pmsg_error("unable to write: %s\n", "sorry no info avail"); // TODO - return -1; - } + serial_w32SetTimeOut(hComPort, 500); - if (written != len) { - pmsg_error("size/send mismatch\n"); - return -1; - } + if(!WriteFile(hComPort, buf, len, &written, NULL)) { + pmsg_error("unable to write: %s\n", "sorry no info avail"); // TODO + return -1; + } - return 0; -} + if(written != len) { + pmsg_error("size/send mismatch\n"); + return -1; + } + return 0; +} static int net_recv(const union filedescriptor *fd, unsigned char *buf, size_t buflen) { - LPVOID lpMsgBuf; - struct timeval timeout, to2; - fd_set rfds; - int nfds; - int rc; - unsigned char *p = buf; - size_t len = 0; - - if (fd->ifd < 0) { - pmsg_error("connection not open\n"); - return -1; - } - - timeout.tv_sec = serial_recv_timeout / 1000L; - timeout.tv_usec = (serial_recv_timeout % 1000L) * 1000; - to2 = timeout; - - while (len < buflen) { -reselect: - FD_ZERO(&rfds); - FD_SET(fd->ifd, &rfds); - - nfds = select(fd->ifd + 1, &rfds, NULL, NULL, &to2); - if (nfds == 0) { - pmsg_notice2("%s(): programmer is not responding\n", __func__); - return -1; - } else if (nfds == -1) { - if (WSAGetLastError() == WSAEINTR || WSAGetLastError() == WSAEINPROGRESS) { - pmsg_notice("%s(): programmer is not responding, reselecting\n", __func__); - goto reselect; - } else { - FormatMessage( - FORMAT_MESSAGE_ALLOCATE_BUFFER | - FORMAT_MESSAGE_FROM_SYSTEM | - FORMAT_MESSAGE_IGNORE_INSERTS, - NULL, - WSAGetLastError(), - MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), - (LPTSTR)&lpMsgBuf, - 0, - NULL); - pmsg_error("%s(): %s\n", __func__, (char *) lpMsgBuf); - LocalFree(lpMsgBuf); - return -1; - } - } - - rc = recv(fd->ifd, (char *) p, (buflen - len > 1024)? 1024: buflen - len, 0); - if (rc < 0) { - FormatMessage( - FORMAT_MESSAGE_ALLOCATE_BUFFER | - FORMAT_MESSAGE_FROM_SYSTEM | - FORMAT_MESSAGE_IGNORE_INSERTS, - NULL, - WSAGetLastError(), - MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), - (LPTSTR)&lpMsgBuf, - 0, - NULL); - pmsg_error("unable to read: %s\n", (char *) lpMsgBuf); - LocalFree(lpMsgBuf); - return -1; - } - p += rc; - len += rc; - } - - if (verbose >= MSG_TRACE) - trace_buffer(__func__, buf, len); - - return 0; + LPVOID lpMsgBuf; + struct timeval timeout, to2; + fd_set rfds; + int nfds; + int rc; + unsigned char *p = buf; + size_t len = 0; + + if(fd->ifd < 0) { + pmsg_error("connection not open\n"); + return -1; + } + + timeout.tv_sec = serial_recv_timeout/1000L; + timeout.tv_usec = (serial_recv_timeout%1000L)*1000; + to2 = timeout; + + while(len < buflen) { + reselect: + FD_ZERO(&rfds); + FD_SET(fd->ifd, &rfds); + + nfds = select(fd->ifd + 1, &rfds, NULL, NULL, &to2); + if(nfds == 0) { + pmsg_notice2("%s(): programmer is not responding\n", __func__); + return -1; + } else if(nfds == -1) { + if(WSAGetLastError() == WSAEINTR || WSAGetLastError() == WSAEINPROGRESS) { + pmsg_notice("%s(): programmer is not responding, reselecting\n", __func__); + goto reselect; + } else { + FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | + FORMAT_MESSAGE_FROM_SYSTEM | + FORMAT_MESSAGE_IGNORE_INSERTS, + NULL, WSAGetLastError(), MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), (LPTSTR) & lpMsgBuf, 0, NULL); + pmsg_error("%s(): %s\n", __func__, (char *) lpMsgBuf); + LocalFree(lpMsgBuf); + return -1; + } + } + + rc = recv(fd->ifd, (char *) p, (buflen - len > 1024)? 1024: buflen - len, 0); + if(rc < 0) { + FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | + FORMAT_MESSAGE_FROM_SYSTEM | + FORMAT_MESSAGE_IGNORE_INSERTS, + NULL, WSAGetLastError(), MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), (LPTSTR) & lpMsgBuf, 0, NULL); + pmsg_error("unable to read: %s\n", (char *) lpMsgBuf); + LocalFree(lpMsgBuf); + return -1; + } + p += rc; + len += rc; + } + + if(verbose >= MSG_TRACE) + trace_buffer(__func__, buf, len); + + return 0; } static int ser_recv(const union filedescriptor *fd, unsigned char *buf, size_t buflen) { - if(cx->ser_serial_over_ethernet) - return net_recv(fd, buf, buflen); - - DWORD read; - - HANDLE hComPort=(HANDLE)fd->pfd; - - if (hComPort == INVALID_HANDLE_VALUE) { - pmsg_error("port not open\n"); - return -1; - } - - serial_w32SetTimeOut(hComPort, serial_recv_timeout); - - if (!ReadFile(hComPort, buf, buflen, &read, NULL)) { - LPVOID lpMsgBuf; - FormatMessage( - FORMAT_MESSAGE_ALLOCATE_BUFFER | - FORMAT_MESSAGE_FROM_SYSTEM | - FORMAT_MESSAGE_IGNORE_INSERTS, - NULL, - GetLastError(), - MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), // Default language - (LPTSTR) &lpMsgBuf, - 0, - NULL); - pmsg_error("unable to read: %s\n", (char*) lpMsgBuf); - LocalFree(lpMsgBuf); - return -1; - } - - /* time out detected */ - if (read < buflen) { - pmsg_notice2("%s(): programmer is not responding\n", __func__); - return -1; - } - - if (verbose >= MSG_TRACE) - trace_buffer(__func__, buf, read); - - return 0; + if(cx->ser_serial_over_ethernet) + return net_recv(fd, buf, buflen); + + DWORD read; + + HANDLE hComPort = (HANDLE) fd->pfd; + + if(hComPort == INVALID_HANDLE_VALUE) { + pmsg_error("port not open\n"); + return -1; + } + + serial_w32SetTimeOut(hComPort, serial_recv_timeout); + + if(!ReadFile(hComPort, buf, buflen, &read, NULL)) { + LPVOID lpMsgBuf; + + FormatMessage( + FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, + NULL, GetLastError(), MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), // Default language + (LPTSTR) & lpMsgBuf, 0, NULL); + pmsg_error("unable to read: %s\n", (char *) lpMsgBuf); + LocalFree(lpMsgBuf); + return -1; + } + + // Time out detected + if(read < buflen) { + pmsg_notice2("%s(): programmer is not responding\n", __func__); + return -1; + } + + if(verbose >= MSG_TRACE) + trace_buffer(__func__, buf, read); + + return 0; } static int net_drain(const union filedescriptor *fd, int display) { - LPVOID lpMsgBuf; - struct timeval timeout; - fd_set rfds; - int nfds; - unsigned char buf; - int rc; - - if (fd->ifd < 0) { - pmsg_error("connection not open\n"); - return -1; - } - - if (display) { - msg_info("drain>"); - } - - timeout.tv_sec = 0; - timeout.tv_usec = serial_drain_timeout*1000L; - - while (1) { - FD_ZERO(&rfds); - FD_SET(fd->ifd, &rfds); - - reselect: - nfds = select(fd->ifd + 1, &rfds, NULL, NULL, &timeout); - if (nfds == 0) { - if (display) { - msg_info("ifd, (char *) &buf, 1, 0); - if (rc < 0) { - FormatMessage( - FORMAT_MESSAGE_ALLOCATE_BUFFER | - FORMAT_MESSAGE_FROM_SYSTEM | - FORMAT_MESSAGE_IGNORE_INSERTS, - NULL, - WSAGetLastError(), - MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), - (LPTSTR)&lpMsgBuf, - 0, - NULL); - pmsg_error("unable to read: %s\n", (char *) lpMsgBuf); - LocalFree(lpMsgBuf); - return -1; - } - - if (display) { - msg_info("%02x ", buf); - } - } - - return 0; + LPVOID lpMsgBuf; + struct timeval timeout; + fd_set rfds; + int nfds; + unsigned char buf; + int rc; + + if(fd->ifd < 0) { + pmsg_error("connection not open\n"); + return -1; + } + + if(display) { + msg_info("drain>"); + } + + timeout.tv_sec = 0; + timeout.tv_usec = serial_drain_timeout*1000L; + + while(1) { + FD_ZERO(&rfds); + FD_SET(fd->ifd, &rfds); + + reselect: + nfds = select(fd->ifd + 1, &rfds, NULL, NULL, &timeout); + if(nfds == 0) { + if(display) { + msg_info("ifd, (char *) &buf, 1, 0); + if(rc < 0) { + FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | + FORMAT_MESSAGE_FROM_SYSTEM | + FORMAT_MESSAGE_IGNORE_INSERTS, + NULL, WSAGetLastError(), MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), (LPTSTR) & lpMsgBuf, 0, NULL); + pmsg_error("unable to read: %s\n", (char *) lpMsgBuf); + LocalFree(lpMsgBuf); + return -1; + } + + if(display) { + msg_info("%02x ", buf); + } + } + + return 0; } static int ser_drain(const union filedescriptor *fd, int display) { - if(cx->ser_serial_over_ethernet) - return net_drain(fd, display); - - // int rc; - unsigned char buf[10]; - BOOL readres; - DWORD read; - - HANDLE hComPort=(HANDLE)fd->pfd; - - if (hComPort == INVALID_HANDLE_VALUE) { - pmsg_error("port not open\n"); - return -1; - } - - serial_w32SetTimeOut(hComPort, serial_drain_timeout); - - if (display) { - msg_info("drain>"); - } - - while (1) { - readres=ReadFile(hComPort, buf, 1, &read, NULL); - if (!readres) { - LPVOID lpMsgBuf; - FormatMessage( - FORMAT_MESSAGE_ALLOCATE_BUFFER | - FORMAT_MESSAGE_FROM_SYSTEM | - FORMAT_MESSAGE_IGNORE_INSERTS, - NULL, - GetLastError(), - MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), // Default language - (LPTSTR) &lpMsgBuf, - 0, - NULL ); - pmsg_error("unable to read: %s\n", (char*) lpMsgBuf); - LocalFree( lpMsgBuf ); - return -1; - } - - if (read) { // data avail - if (display) - msg_info("%02x ", buf[0]); - } - else { // no more data - if (display) - msg_info("ser_serial_over_ethernet) + return net_drain(fd, display); + + unsigned char buf[10]; + BOOL readres; + DWORD read; + + HANDLE hComPort = (HANDLE) fd->pfd; + + if(hComPort == INVALID_HANDLE_VALUE) { + pmsg_error("port not open\n"); + return -1; + } + + serial_w32SetTimeOut(hComPort, serial_drain_timeout); + + if(display) { + msg_info("drain>"); + } + + while(1) { + readres = ReadFile(hComPort, buf, 1, &read, NULL); + if(!readres) { + LPVOID lpMsgBuf; + + FormatMessage( + FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, + NULL, GetLastError(), MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), // Default language + (LPTSTR) & lpMsgBuf, 0, NULL); + pmsg_error("unable to read: %s\n", (char *) lpMsgBuf); + LocalFree(lpMsgBuf); + return -1; + } + + if(read) { // Data avail + if(display) + msg_info("%02x ", buf[0]); + } else { // No more data + if(display) + msg_info(". */ -/* - * Posix serial bitbanging interface for avrdude. - */ +// Posix serial bitbanging interface for avrdude #if !defined(WIN32) - #include #include @@ -50,152 +47,151 @@ struct pdata { // Use private programmer data as if they were a global structure my #define my (*(struct pdata *)(pgm->cookie)) - /* - serial port/pin mapping - - 1 cd <- - 2 (rxd) <- - 3 txd -> - 4 dtr -> - 5 GND - 6 dsr <- - 7 rts -> - 8 cts <- - 9 ri <- -*/ + * Serial port/pin mapping + * + * 1 cd <- + * 2 (rxd) <- + * 3 txd -> + * 4 dtr -> + * 5 GND + * 6 dsr <- + * 7 rts -> + * 8 cts <- + * 9 ri <- + * + */ #define DB9PINS 9 -static const int serregbits[DB9PINS + 1] = -{ 0, TIOCM_CD, 0, 0, TIOCM_DTR, 0, TIOCM_DSR, TIOCM_RTS, TIOCM_CTS, TIOCM_RI }; +static const int serregbits[DB9PINS + 1] = { + 0, TIOCM_CD, 0, 0, TIOCM_DTR, 0, TIOCM_DSR, TIOCM_RTS, TIOCM_CTS, TIOCM_RI +}; #ifdef DEBUG -static const char * const serpins[DB9PINS + 1] = - { "NONE", "CD", "RXD", "TXD", "DTR", "GND", "DSR", "RTS", "CTS", "RI" }; +static const char *const serpins[DB9PINS + 1] = { + "NONE", "CD", "RXD", "TXD", "DTR", "GND", "DSR", "RTS", "CTS", "RI" +}; #endif static int serbb_setpin(const PROGRAMMER *pgm, int pinfunc, int value) { - unsigned int ctl; - int r; + unsigned int ctl; + int r; if(pinfunc < 0 || pinfunc >= N_PINS) return -1; - int pin = pgm->pinno[pinfunc]; // get its value + int pin = pgm->pinno[pinfunc]; // Get its value - if (pin & PIN_INVERSE) - { - value = !value; - pin &= PIN_MASK; + if(pin & PIN_INVERSE) { + value = !value; + pin &= PIN_MASK; } - if ( pin < 1 || pin > DB9PINS ) + if(pin < 1 || pin > DB9PINS) return -1; #ifdef DEBUG msg_notice("%s to %d\n", serpins[pin], value); #endif - switch ( pin ) - { - case 3: /* txd */ - r = ioctl(pgm->fd.ifd, value ? TIOCSBRK : TIOCCBRK, 0); - if (r < 0) { - pmsg_ext_error("ioctl(\"TIOCxBRK\"): %s\n", strerror(errno)); - return -1; - } - break; - - case 4: /* dtr */ - case 7: /* rts */ - r = ioctl(pgm->fd.ifd, TIOCMGET, &ctl); - if (r < 0) { - pmsg_ext_error("ioctl(\"TIOCMGET\"): %s\n", strerror(errno)); - return -1; - } - if (value) - ctl |= serregbits[pin]; - else - ctl &= ~(serregbits[pin]); - r = ioctl(pgm->fd.ifd, TIOCMSET, &ctl); - if (r < 0) { - pmsg_ext_error("ioctl(\"TIOCMSET\"): %s\n", strerror(errno)); - return -1; - } - break; - - default: /* impossible */ + switch(pin) { + case 3: // txd + r = ioctl(pgm->fd.ifd, value? TIOCSBRK: TIOCCBRK, 0); + if(r < 0) { + pmsg_ext_error("ioctl(\"TIOCxBRK\"): %s\n", strerror(errno)); return -1; + } + break; + + case 4: // dtr + case 7: // rts + r = ioctl(pgm->fd.ifd, TIOCMGET, &ctl); + if(r < 0) { + pmsg_ext_error("ioctl(\"TIOCMGET\"): %s\n", strerror(errno)); + return -1; + } + if(value) + ctl |= serregbits[pin]; + else + ctl &= ~(serregbits[pin]); + r = ioctl(pgm->fd.ifd, TIOCMSET, &ctl); + if(r < 0) { + pmsg_ext_error("ioctl(\"TIOCMSET\"): %s\n", strerror(errno)); + return -1; + } + break; + + default: // Impossible + return -1; } - if (pgm->ispdelay > 1) + if(pgm->ispdelay > 1) bitbang_delay(pgm->ispdelay); return 0; } static int serbb_getpin(const PROGRAMMER *pgm, int pinfunc) { - unsigned int ctl; + unsigned int ctl; unsigned char invert; - int r; + int r; if(pinfunc < 0 || pinfunc >= N_PINS) return -1; - int pin = pgm->pinno[pinfunc]; // get its value + int pin = pgm->pinno[pinfunc]; // Get its value - if (pin & PIN_INVERSE) - { + if(pin & PIN_INVERSE) { invert = 1; - pin &= PIN_MASK; + pin &= PIN_MASK; } else invert = 0; - if ( pin < 1 || pin > DB9PINS ) - return(-1); - - switch ( pin ) - { - case 2: /* rxd, currently not implemented, FIXME */ - return(-1); - - case 1: /* cd */ - case 6: /* dsr */ - case 8: /* cts */ - case 9: /* ri */ - r = ioctl(pgm->fd.ifd, TIOCMGET, &ctl); - if (r < 0) { - pmsg_ext_error("ioctl(\"TIOCMGET\"): %s\n", strerror(errno)); - return -1; - } - if ( !invert ) - { + if(pin < 1 || pin > DB9PINS) + return (-1); + + switch(pin) { + case 2: // rxd, currently not implemented, FIXME + return (-1); + + case 1: // cd + case 6: // dsr + case 8: // cts + case 9: // ri + r = ioctl(pgm->fd.ifd, TIOCMGET, &ctl); + if(r < 0) { + pmsg_ext_error("ioctl(\"TIOCMGET\"): %s\n", strerror(errno)); + return -1; + } + if(!invert) { + #ifdef DEBUG - msg_notice("%s is %d\n", serpins[pin], ctl & serregbits[pin]? 1: 0); + msg_notice("%s is %d\n", serpins[pin], ctl & serregbits[pin]? 1: 0); #endif - return ctl & serregbits[pin]? 1: 0; - } - else - { + + return ctl & serregbits[pin]? 1: 0; + } else { + #ifdef DEBUG - msg_notice("%s is %d (~)\n", serpins[pin], ctl & serregbits[pin]? 0: 1); + msg_notice("%s is %d (~)\n", serpins[pin], ctl & serregbits[pin]? 0: 1); #endif - return ctl & serregbits[pin]? 0: 1; - } - default: /* impossible */ - return(-1); + return ctl & serregbits[pin]? 0: 1; + } + + default: // Impossible + return (-1); } } static int serbb_highpulsepin(const PROGRAMMER *pgm, int pinfunc) { - if (pinfunc < 0 || pinfunc >= N_PINS) + if(pinfunc < 0 || pinfunc >= N_PINS) return -1; - int pin = pgm->pinno[pinfunc]; // replace pin name by its value + int pin = pgm->pinno[pinfunc]; // Replace pin name by its value - if ( (pin & PIN_MASK) < 1 || (pin & PIN_MASK) > DB9PINS ) + if((pin & PIN_MASK) < 1 || (pin & PIN_MASK) > DB9PINS) return -1; serbb_setpin(pgm, pinfunc, 1); @@ -204,26 +200,19 @@ static int serbb_highpulsepin(const PROGRAMMER *pgm, int pinfunc) { return 0; } - - static void serbb_display(const PROGRAMMER *pgm, const char *p) { - /* MAYBE */ } static void serbb_enable(PROGRAMMER *pgm, const AVRPART *p) { - /* nothing */ } static void serbb_disable(const PROGRAMMER *pgm) { - /* nothing */ } static void serbb_powerup(const PROGRAMMER *pgm) { - /* nothing */ } static void serbb_powerdown(const PROGRAMMER *pgm) { - /* nothing */ } static int serbb_open(PROGRAMMER *pgm, const char *port) { @@ -231,60 +220,57 @@ static int serbb_open(PROGRAMMER *pgm, const char *port) { int flags; int r; - if (bitbang_check_prerequisites(pgm) < 0) + if(bitbang_check_prerequisites(pgm) < 0) return -1; - /* adapted from uisp code */ + // Adapted from uisp code pgm->fd.ifd = open(port, O_RDWR | O_NOCTTY | O_NONBLOCK); - if (pgm->fd.ifd < 0) { + if(pgm->fd.ifd < 0) { pmsg_ext_error("%s: %s\n", port, strerror(errno)); - return(-1); + return (-1); } r = tcgetattr(pgm->fd.ifd, &mode); - if (r < 0) { + if(r < 0) { pmsg_ext_error("%s, tcgetattr(): %s\n", port, strerror(errno)); - return(-1); + return (-1); } my.oldmode = mode; mode.c_iflag = IGNBRK | IGNPAR; mode.c_oflag = 0; mode.c_cflag = CLOCAL | CREAD | CS8 | B9600; - mode.c_cc [VMIN] = 1; - mode.c_cc [VTIME] = 0; + mode.c_cc[VMIN] = 1; + mode.c_cc[VTIME] = 0; r = tcsetattr(pgm->fd.ifd, TCSANOW, &mode); - if (r < 0) { - pmsg_ext_error("%s, tcsetattr(): %s", port, strerror(errno)); - return(-1); + if(r < 0) { + pmsg_ext_error("%s, tcsetattr(): %s", port, strerror(errno)); + return (-1); } - /* Clear O_NONBLOCK flag. */ + // Clear O_NONBLOCK flag flags = fcntl(pgm->fd.ifd, F_GETFL, 0); - if (flags == -1) - { - pmsg_ext_error("cannot get flags: %s\n", strerror(errno)); - return(-1); - } + if(flags == -1) { + pmsg_ext_error("cannot get flags: %s\n", strerror(errno)); + return (-1); + } flags &= ~O_NONBLOCK; - if (fcntl(pgm->fd.ifd, F_SETFL, flags) == -1) - { - pmsg_ext_error("cannot clear nonblock flag: %s\n", strerror(errno)); - return(-1); - } + if(fcntl(pgm->fd.ifd, F_SETFL, flags) == -1) { + pmsg_ext_error("cannot clear nonblock flag: %s\n", strerror(errno)); + return (-1); + } - return(0); + return (0); } static void serbb_close(PROGRAMMER *pgm) { - if (pgm->fd.ifd != -1) - { - (void) tcsetattr(pgm->fd.ifd, TCSANOW, &my.oldmode); - pgm->setpin(pgm, PIN_AVR_RESET, 1); - close(pgm->fd.ifd); + if(pgm->fd.ifd != -1) { + (void) tcsetattr(pgm->fd.ifd, TCSANOW, &my.oldmode); + pgm->setpin(pgm, PIN_AVR_RESET, 1); + close(pgm->fd.ifd); } return; } @@ -303,31 +289,30 @@ const char serbb_desc[] = "Serial port bitbanging"; void serbb_initpgm(PROGRAMMER *pgm) { strcpy(pgm->type, "SERBB"); - pgm_fill_old_pins(pgm); // TODO to be removed if old pin data no longer needed - - pgm->setup = serbb_setup; - pgm->teardown = serbb_teardown; - pgm->rdy_led = bitbang_rdy_led; - pgm->err_led = bitbang_err_led; - pgm->pgm_led = bitbang_pgm_led; - pgm->vfy_led = bitbang_vfy_led; - pgm->initialize = bitbang_initialize; - pgm->display = serbb_display; - pgm->enable = serbb_enable; - pgm->disable = serbb_disable; - pgm->powerup = serbb_powerup; - pgm->powerdown = serbb_powerdown; + pgm_fill_old_pins(pgm); // TODO to be removed if old pin data no longer needed + + pgm->setup = serbb_setup; + pgm->teardown = serbb_teardown; + pgm->rdy_led = bitbang_rdy_led; + pgm->err_led = bitbang_err_led; + pgm->pgm_led = bitbang_pgm_led; + pgm->vfy_led = bitbang_vfy_led; + pgm->initialize = bitbang_initialize; + pgm->display = serbb_display; + pgm->enable = serbb_enable; + pgm->disable = serbb_disable; + pgm->powerup = serbb_powerup; + pgm->powerdown = serbb_powerdown; pgm->program_enable = bitbang_program_enable; - pgm->chip_erase = bitbang_chip_erase; - pgm->cmd = bitbang_cmd; - pgm->cmd_tpi = bitbang_cmd_tpi; - pgm->open = serbb_open; - pgm->close = serbb_close; - pgm->setpin = serbb_setpin; - pgm->getpin = serbb_getpin; - pgm->highpulsepin = serbb_highpulsepin; - pgm->read_byte = avr_read_byte_default; - pgm->write_byte = avr_write_byte_default; + pgm->chip_erase = bitbang_chip_erase; + pgm->cmd = bitbang_cmd; + pgm->cmd_tpi = bitbang_cmd_tpi; + pgm->open = serbb_open; + pgm->close = serbb_close; + pgm->setpin = serbb_setpin; + pgm->getpin = serbb_getpin; + pgm->highpulsepin = serbb_highpulsepin; + pgm->read_byte = avr_read_byte_default; + pgm->write_byte = avr_write_byte_default; } - -#endif /* WIN32 */ +#endif // WIN32 diff --git a/src/serbb_win32.c b/src/serbb_win32.c index 26aa02617..4b35952c2 100644 --- a/src/serbb_win32.c +++ b/src/serbb_win32.c @@ -18,15 +18,11 @@ * along with this program. If not, see . */ -/* - * Win32 serial bitbanging interface for avrdude. - */ +// Win32 serial bitbanging interface for avrdude #include "avrdude.h" #if defined(WIN32) - - #include #define WIN32_LEAN_AND_MEAN @@ -49,279 +45,245 @@ struct pdata { #define W32SERBUFSIZE 1024 /* - serial port/pin mapping - - 1 cd <- - 2 (rxd) <- - 3 txd -> - 4 dtr -> - 5 GND - 6 dsr <- - 7 rts -> - 8 cts <- - 9 ri <- -*/ + * Serial port/pin mapping + * + * 1 cd <- + * 2 (rxd) <- + * 3 txd -> + * 4 dtr -> + * 5 GND + * 6 dsr <- + * 7 rts -> + * 8 cts <- + * 9 ri <- + * + */ #define DB9PINS 9 static int serbb_setpin(const PROGRAMMER *pgm, int pinfunc, int value) { - if(pinfunc < 0 || pinfunc >= N_PINS) - return -1; - - int pin = pgm->pinno[pinfunc]; - HANDLE hComPort = (HANDLE)pgm->fd.pfd; - LPVOID lpMsgBuf; - DWORD dwFunc; - const char *name; - - if (pin & PIN_INVERSE) - { - value = !value; - pin &= PIN_MASK; - } - - if (pin < 1 || pin > DB9PINS) - return -1; - - switch (pin) - { - case 3: /* txd */ - dwFunc = value? SETBREAK: CLRBREAK; - name = value? "SETBREAK": "CLRBREAK"; - my.txd = value; - break; - - case 4: /* dtr */ - dwFunc = value? SETDTR: CLRDTR; - name = value? "SETDTR": "CLRDTR"; - my.dtr = value; - break; - - case 7: /* rts */ - dwFunc = value? SETRTS: CLRRTS; - name = value? "SETRTS": "CLRRTS"; - my.rts = value; - break; - - default: - pmsg_warning("%s(): unknown pin %d\n", __func__, pin + 1); - return -1; - } - pmsg_trace2("%s(): EscapeCommFunction(%s)\n", __func__, name); - if (!EscapeCommFunction(hComPort, dwFunc)) - { - FormatMessage( - FORMAT_MESSAGE_ALLOCATE_BUFFER | - FORMAT_MESSAGE_FROM_SYSTEM | - FORMAT_MESSAGE_IGNORE_INSERTS, - NULL, - GetLastError(), - MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), // Default language - (LPTSTR) &lpMsgBuf, - 0, - NULL); - pmsg_error("SetCommState() failed: %s\n", (char *) lpMsgBuf); - CloseHandle(hComPort); - LocalFree(lpMsgBuf); - return -1; - } - - if (pgm->ispdelay > 1) - bitbang_delay(pgm->ispdelay); - - return 0; + if(pinfunc < 0 || pinfunc >= N_PINS) + return -1; + + int pin = pgm->pinno[pinfunc]; + HANDLE hComPort = (HANDLE) pgm->fd.pfd; + LPVOID lpMsgBuf; + DWORD dwFunc; + const char *name; + + if(pin & PIN_INVERSE) { + value = !value; + pin &= PIN_MASK; + } + + if(pin < 1 || pin > DB9PINS) + return -1; + + switch(pin) { + case 3: // txd + dwFunc = value? SETBREAK: CLRBREAK; + name = value? "SETBREAK": "CLRBREAK"; + my.txd = value; + break; + + case 4: // dtr + dwFunc = value? SETDTR: CLRDTR; + name = value? "SETDTR": "CLRDTR"; + my.dtr = value; + break; + + case 7: // rts + dwFunc = value? SETRTS: CLRRTS; + name = value? "SETRTS": "CLRRTS"; + my.rts = value; + break; + + default: + pmsg_warning("%s(): unknown pin %d\n", __func__, pin + 1); + return -1; + } + pmsg_trace2("%s(): EscapeCommFunction(%s)\n", __func__, name); + if(!EscapeCommFunction(hComPort, dwFunc)) { + FormatMessage( + FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, + NULL, GetLastError(), MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), // Default language + (LPTSTR) & lpMsgBuf, 0, NULL); + pmsg_error("SetCommState() failed: %s\n", (char *) lpMsgBuf); + CloseHandle(hComPort); + LocalFree(lpMsgBuf); + return -1; + } + + if(pgm->ispdelay > 1) + bitbang_delay(pgm->ispdelay); + + return 0; } static int serbb_getpin(const PROGRAMMER *pgm, int pinfunc) { - if(pinfunc < 0 || pinfunc >= N_PINS) - return -1; - - int pin = pgm->pinno[pinfunc]; - HANDLE hComPort = (HANDLE)pgm->fd.pfd; - LPVOID lpMsgBuf; - int invert, rv; - const char *name; - DWORD modemstate; - - if (pin & PIN_INVERSE) - { - invert = 1; - pin &= PIN_MASK; - } else - invert = 0; - - if (pin < 1 || pin > DB9PINS) - return -1; - - if (pin == 1 /* cd */ || pin == 6 /* dsr */ || pin == 8 /* cts */) - { - if (!GetCommModemStatus(hComPort, &modemstate)) - { - FormatMessage( - FORMAT_MESSAGE_ALLOCATE_BUFFER | - FORMAT_MESSAGE_FROM_SYSTEM | - FORMAT_MESSAGE_IGNORE_INSERTS, - NULL, - GetLastError(), - MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), // Default language - (LPTSTR) &lpMsgBuf, - 0, - NULL); - pmsg_error("GetCommModemStatus() failed: %s\n", (char *) lpMsgBuf); - CloseHandle(hComPort); - LocalFree(lpMsgBuf); - return -1; - } - pmsg_trace2("%s(): GetCommState() => 0x%lx\n", __func__, modemstate); - switch (pin) - { - case 1: - modemstate &= MS_RLSD_ON; - break; - case 6: - modemstate &= MS_DSR_ON; - break; - case 8: - modemstate &= MS_CTS_ON; - break; - } - rv = modemstate != 0; - if (invert) - rv = !rv; - - return rv; - } - - switch (pin) - { - case 3: /* txd */ - rv = my.txd; - name = "TXD"; - break; - case 4: /* dtr */ - rv = my.dtr; - name = "DTR"; - break; - case 7: /* rts */ - rv = my.rts; - name = "RTS"; - break; - default: - pmsg_warning("%s(): unknown pin %d\n", __func__, pin + 1); - return -1; - } - pmsg_trace2("%s(): return cached state for %s\n", __func__, name); - if (invert) - rv = !rv; - - return rv; + if(pinfunc < 0 || pinfunc >= N_PINS) + return -1; + + int pin = pgm->pinno[pinfunc]; + HANDLE hComPort = (HANDLE) pgm->fd.pfd; + LPVOID lpMsgBuf; + int invert, rv; + const char *name; + DWORD modemstate; + + if(pin & PIN_INVERSE) { + invert = 1; + pin &= PIN_MASK; + } else + invert = 0; + + if(pin < 1 || pin > DB9PINS) + return -1; + + if(pin == 1 /* cd */ || pin == 6 /* dsr */ || pin == 8 /* cts */ ) { + if(!GetCommModemStatus(hComPort, &modemstate)) { + FormatMessage( + FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, + NULL, GetLastError(), MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), // Default language + (LPTSTR) & lpMsgBuf, 0, NULL); + pmsg_error("GetCommModemStatus() failed: %s\n", (char *) lpMsgBuf); + CloseHandle(hComPort); + LocalFree(lpMsgBuf); + return -1; + } + pmsg_trace2("%s(): GetCommState() => 0x%lx\n", __func__, modemstate); + switch(pin) { + case 1: + modemstate &= MS_RLSD_ON; + break; + case 6: + modemstate &= MS_DSR_ON; + break; + case 8: + modemstate &= MS_CTS_ON; + break; + } + rv = modemstate != 0; + if(invert) + rv = !rv; + + return rv; + } + + switch(pin) { + case 3: // txd + rv = my.txd; + name = "TXD"; + break; + case 4: // dtr + rv = my.dtr; + name = "DTR"; + break; + case 7: // rts + rv = my.rts; + name = "RTS"; + break; + default: + pmsg_warning("%s(): unknown pin %d\n", __func__, pin + 1); + return -1; + } + pmsg_trace2("%s(): return cached state for %s\n", __func__, name); + if(invert) + rv = !rv; + + return rv; } static int serbb_highpulsepin(const PROGRAMMER *pgm, int pinfunc) { - if(pinfunc < 0 || pinfunc >= N_PINS) - return -1; + if(pinfunc < 0 || pinfunc >= N_PINS) + return -1; - int pin = pgm->pinno[pinfunc]; - if ( (pin & PIN_MASK) < 1 || (pin & PIN_MASK) > DB9PINS ) - return -1; + int pin = pgm->pinno[pinfunc]; - serbb_setpin(pgm, pinfunc, 1); - serbb_setpin(pgm, pinfunc, 0); + if((pin & PIN_MASK) < 1 || (pin & PIN_MASK) > DB9PINS) + return -1; - return 0; -} + serbb_setpin(pgm, pinfunc, 1); + serbb_setpin(pgm, pinfunc, 0); + return 0; +} static void serbb_display(const PROGRAMMER *pgm, const char *p) { - /* MAYBE */ } static void serbb_enable(PROGRAMMER *pgm, const AVRPART *p) { - /* nothing */ } static void serbb_disable(const PROGRAMMER *pgm) { - /* nothing */ } static void serbb_powerup(const PROGRAMMER *pgm) { - /* nothing */ } static void serbb_powerdown(const PROGRAMMER *pgm) { - /* nothing */ } static int serbb_open(PROGRAMMER *pgm, const char *port) { - DCB dcb; - LPVOID lpMsgBuf; - HANDLE hComPort = INVALID_HANDLE_VALUE; - - if (bitbang_check_prerequisites(pgm) < 0) - return -1; - - hComPort = CreateFile(port, GENERIC_READ | GENERIC_WRITE, 0, NULL, - OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); - - if (hComPort == INVALID_HANDLE_VALUE) { - FormatMessage( - FORMAT_MESSAGE_ALLOCATE_BUFFER | - FORMAT_MESSAGE_FROM_SYSTEM | - FORMAT_MESSAGE_IGNORE_INSERTS, - NULL, - GetLastError(), - MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), // Default language - (LPTSTR) &lpMsgBuf, - 0, - NULL); - pmsg_error("cannot open port %s: %s\n", port, (char*) lpMsgBuf); - LocalFree(lpMsgBuf); - return -1; - } - - if (!SetupComm(hComPort, W32SERBUFSIZE, W32SERBUFSIZE)) - { - CloseHandle(hComPort); - pmsg_error("cannot set buffers for %s\n", port); - return -1; - } - - - ZeroMemory(&dcb, sizeof(DCB)); - dcb.DCBlength = sizeof(DCB); - dcb.BaudRate = CBR_9600; - dcb.fBinary = 1; - dcb.fDtrControl = DTR_CONTROL_DISABLE; - dcb.fRtsControl = RTS_CONTROL_DISABLE; - dcb.ByteSize = 8; - dcb.Parity = NOPARITY; - dcb.StopBits = ONESTOPBIT; - - if (!SetCommState(hComPort, &dcb)) - { - CloseHandle(hComPort); - pmsg_error("cannot set com-state for %s\n", port); - return -1; - } - pmsg_debug("%s(): opened comm port %s, handle 0x%lx\n", __func__, port, (long) (INT_PTR) hComPort); - - pgm->fd.pfd = (void *)hComPort; - - my.dtr = my.rts = my.txd = 0; - - return 0; + DCB dcb; + LPVOID lpMsgBuf; + HANDLE hComPort = INVALID_HANDLE_VALUE; + + if(bitbang_check_prerequisites(pgm) < 0) + return -1; + + hComPort = CreateFile(port, GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); + + if(hComPort == INVALID_HANDLE_VALUE) { + FormatMessage( + FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, + NULL, GetLastError(), MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), // Default language + (LPTSTR) & lpMsgBuf, 0, NULL); + pmsg_error("cannot open port %s: %s\n", port, (char *) lpMsgBuf); + LocalFree(lpMsgBuf); + return -1; + } + + if(!SetupComm(hComPort, W32SERBUFSIZE, W32SERBUFSIZE)) { + CloseHandle(hComPort); + pmsg_error("cannot set buffers for %s\n", port); + return -1; + } + + ZeroMemory(&dcb, sizeof(DCB)); + dcb.DCBlength = sizeof(DCB); + dcb.BaudRate = CBR_9600; + dcb.fBinary = 1; + dcb.fDtrControl = DTR_CONTROL_DISABLE; + dcb.fRtsControl = RTS_CONTROL_DISABLE; + dcb.ByteSize = 8; + dcb.Parity = NOPARITY; + dcb.StopBits = ONESTOPBIT; + + if(!SetCommState(hComPort, &dcb)) { + CloseHandle(hComPort); + pmsg_error("cannot set com-state for %s\n", port); + return -1; + } + pmsg_debug("%s(): opened comm port %s, handle 0x%lx\n", __func__, port, (long) (INT_PTR) hComPort); + + pgm->fd.pfd = (void *) hComPort; + + my.dtr = my.rts = my.txd = 0; + + return 0; } static void serbb_close(PROGRAMMER *pgm) { - HANDLE hComPort=(HANDLE)pgm->fd.pfd; - if (hComPort != INVALID_HANDLE_VALUE) - { - pgm->setpin(pgm, PIN_AVR_RESET, 1); - CloseHandle (hComPort); - } - pmsg_debug("%s(): closed comm port handle 0x%lx\n", __func__, (long) (INT_PTR) hComPort); - - hComPort = INVALID_HANDLE_VALUE; + HANDLE hComPort = (HANDLE) pgm->fd.pfd; + + if(hComPort != INVALID_HANDLE_VALUE) { + pgm->setpin(pgm, PIN_AVR_RESET, 1); + CloseHandle(hComPort); + } + pmsg_debug("%s(): closed comm port handle 0x%lx\n", __func__, (long) (INT_PTR) hComPort); + + hComPort = INVALID_HANDLE_VALUE; } static void serbb_setup(PROGRAMMER *pgm) { @@ -338,31 +300,30 @@ const char serbb_desc[] = "Serial port bitbanging"; void serbb_initpgm(PROGRAMMER *pgm) { strcpy(pgm->type, "SERBB"); - pgm_fill_old_pins(pgm); // TODO to be removed if old pin data no longer needed - - pgm->setup = serbb_setup; - pgm->teardown = serbb_teardown; - pgm->rdy_led = bitbang_rdy_led; - pgm->err_led = bitbang_err_led; - pgm->pgm_led = bitbang_pgm_led; - pgm->vfy_led = bitbang_vfy_led; - pgm->initialize = bitbang_initialize; - pgm->display = serbb_display; - pgm->enable = serbb_enable; - pgm->disable = serbb_disable; - pgm->powerup = serbb_powerup; - pgm->powerdown = serbb_powerdown; + pgm_fill_old_pins(pgm); // TODO to be removed if old pin data no longer needed + + pgm->setup = serbb_setup; + pgm->teardown = serbb_teardown; + pgm->rdy_led = bitbang_rdy_led; + pgm->err_led = bitbang_err_led; + pgm->pgm_led = bitbang_pgm_led; + pgm->vfy_led = bitbang_vfy_led; + pgm->initialize = bitbang_initialize; + pgm->display = serbb_display; + pgm->enable = serbb_enable; + pgm->disable = serbb_disable; + pgm->powerup = serbb_powerup; + pgm->powerdown = serbb_powerdown; pgm->program_enable = bitbang_program_enable; - pgm->chip_erase = bitbang_chip_erase; - pgm->cmd = bitbang_cmd; - pgm->cmd_tpi = bitbang_cmd_tpi; - pgm->open = serbb_open; - pgm->close = serbb_close; - pgm->setpin = serbb_setpin; - pgm->getpin = serbb_getpin; - pgm->highpulsepin = serbb_highpulsepin; - pgm->read_byte = avr_read_byte_default; - pgm->write_byte = avr_write_byte_default; + pgm->chip_erase = bitbang_chip_erase; + pgm->cmd = bitbang_cmd; + pgm->cmd_tpi = bitbang_cmd_tpi; + pgm->open = serbb_open; + pgm->close = serbb_close; + pgm->setpin = serbb_setpin; + pgm->getpin = serbb_getpin; + pgm->highpulsepin = serbb_highpulsepin; + pgm->read_byte = avr_read_byte_default; + pgm->write_byte = avr_write_byte_default; } - -#endif /* WIN32 */ +#endif // WIN32 diff --git a/src/serialadapter.c b/src/serialadapter.c index 575de63fc..c186cd960 100644 --- a/src/serialadapter.c +++ b/src/serialadapter.c @@ -1,5 +1,5 @@ /* - * AVRDUDE - A Downloader/Uploader for AVR device programmers + * avrdude - A Downloader/Uploader for AVR device programmers * Copyright (C) 2023 Stefan Rueger * Copyright (C) 2023 Hans Eirik Bull * @@ -28,7 +28,6 @@ #include "libavrdude.h" #ifdef HAVE_LIBSERIALPORT - #include #include @@ -55,7 +54,7 @@ static int sa_setport(char **portp, const char *sp_port) { // Is the actual serial number sn matched by the query q? static int sa_snmatch(const char *sn, const char *q) { - return sn && (str_starts(sn, q) || (str_starts(q , "...") && str_ends(sn, q+3))); + return sn && (str_starts(sn, q) || (str_starts(q, "...") && str_ends(sn, q + 3))); } #define null_len(s) ((s)? strlen(s): 0) @@ -70,13 +69,14 @@ static int sa_portcmp(const void *p, const void *q) { // Compare string bases first if(la && lb && (ret = strncasecmp(a, b, la < lb? la: lb))) return ret; - if((ret = la-lb)) + if((ret = la - lb)) return ret; // If string bases are the same then compare trailing numbers if(na && nb) { long long d; - if((d = atoll(na)-atoll(nb))) + + if((d = atoll(na) - atoll(nb))) return d < 0? -1: 1; } else if(na) return 1; @@ -104,14 +104,16 @@ static SERPORT *get_libserialport_data(int *np) { } int i, j, n; + // Count the number of available ports and allocate space accordingly for(n = 0; port_list[n]; n++) continue; - SERPORT *sp = mmt_malloc(n*sizeof*sp); + SERPORT *sp = mmt_malloc(n*sizeof *sp); - for(j = 0, i = 0; i < n; i++) { // j counts the number of valid ports + for(j = 0, i = 0; i < n; i++) { // j counts the number of valid ports struct sp_port *p = port_list[i]; char *q; + // Fill sp struct with port information if((q = sp_get_port_name(p))) { sp[j].port = mmt_strdup(q); @@ -123,7 +125,7 @@ static SERPORT *get_libserialport_data(int *np) { } if(j > 0) - qsort(sp, j, sizeof*sp, sa_portcmp); + qsort(sp, j, sizeof *sp, sa_portcmp); else mmt_free(sp), sp = NULL; @@ -143,21 +145,22 @@ static void free_libserialport_data(SERPORT *sp, int n) { // Returns a NULL-terminated mmt_malloc'd list of items in SERPORT list spa that are not in spb SERPORT **sa_spa_not_spb(SERPORT *spa, int na, SERPORT *spb, int nb) { - SERPORT **ret = mmt_malloc((na+1)*sizeof*ret); + SERPORT **ret = mmt_malloc((na + 1)*sizeof *ret); int ia = 0, ib = 0, ir = 0; // Use the comm algorithm on two sorted SERPORT lists while(ia < na && ib < nb) { - int d = sa_portcmp(spa+ia, spb+ib); + int d = sa_portcmp(spa + ia, spb + ib); + if(d < 0) - ret[ir++] = spa+ia++; + ret[ir++] = spa + ia++; else if(d > 0) ib++; else ia++, ib++; } while(ia < na) - ret[ir++] = spa+ia++; + ret[ir++] = spa + ia++; ret[ir] = NULL; return ret; @@ -192,40 +195,42 @@ static int sa_num_matches_by_ids(int vid, int pid, const char *sernum, const SER // Is the i-th SERPORT the only match with the serial adapter wrt all plugged-in ones? static int sa_unique_by_sea(const SERIALADAPTER *sea, const char *sn, const SERPORT *sp, int n, int i) { - return sa_num_matches_by_sea(sea, sn, sp, n) == 1 && sa_num_matches_by_sea(sea, sn, sp+i, 1); + return sa_num_matches_by_sea(sea, sn, sp, n) == 1 && sa_num_matches_by_sea(sea, sn, sp + i, 1); } // Is the i-th SERPORT the only match with (vid, pid, sn) wrt all plugged-in ones? static int sa_unique_by_ids(int vid, int pid, const char *sn, const SERPORT *sp, int n, int i) { - return sa_num_matches_by_ids(vid, pid, sn, sp, n) == 1 && sa_num_matches_by_ids(vid, pid, sn, sp+i, 1); + return sa_num_matches_by_ids(vid, pid, sn, sp, n) == 1 && sa_num_matches_by_ids(vid, pid, sn, sp + i, 1); } // Return an mmt_malloc'd list of -P specifications that uniquely address sp[i] static char **sa_list_specs(const SERPORT *sp, int n, int i) { int Pn = 4, Pi = 0; - char **Plist = mmt_malloc(Pn*sizeof*Plist); + char **Plist = mmt_malloc(Pn*sizeof *Plist); const char *sn = sp[i].sernum, *via = NULL; // Loop though all serial adapters in avrdude.conf - for(LNODEID ln1 = lfirst(programmers); ln1; ln1=lnext(ln1)) { + for(LNODEID ln1 = lfirst(programmers); ln1; ln1 = lnext(ln1)) { SERIALADAPTER *sea = ldata(ln1); + if(!is_serialadapter(sea)) continue; for(LNODEID sid = lfirst(sea->id); sid; sid = lnext(sid)) { char *id = ldata(sid); + // Put id or id:sn into list if it uniquely matches sp[i] if(sa_unique_by_sea(sea, "", sp, n, i)) Plist[Pi++] = mmt_strdup(id); else if(*sn && sa_unique_by_sea(sea, sn, sp, n, i)) Plist[Pi++] = mmt_sprintf("%s:%s", id, sn); - else if(!via && sa_num_matches_by_sea(sea, "", sp+i, 1)) + else if(!via && sa_num_matches_by_sea(sea, "", sp + i, 1)) via = id; - if(Pi >= Pn-1) { // Ensure there is space for one more and NULL + if(Pi >= Pn - 1) { // Ensure there is space for one more and NULL if(Pn >= INT_MAX/2) break; Pn *= 2; - Plist = mmt_realloc(Plist, Pn*sizeof*Plist); + Plist = mmt_realloc(Plist, Pn*sizeof *Plist); } } } @@ -261,6 +266,7 @@ static void sa_print_specs(const SERPORT *sp, int n, int i) { int setport_from_serialadapter(char **portp, const SERIALADAPTER *sea, const char *sernum) { int rv, m, n; SERPORT *sp = get_libserialport_data(&n); + if(!sp || n <= 0) return -1; @@ -268,13 +274,13 @@ int setport_from_serialadapter(char **portp, const SERIALADAPTER *sea, const cha if(m == 1) { // Unique result, set port string rv = -1; for(int i = 0; i < n; i++) - if(sa_num_matches_by_sea(sea, sernum, sp+i, 1)) + if(sa_num_matches_by_sea(sea, sernum, sp + i, 1)) rv = sa_setport(portp, sp[i].port); } else { rv = -2; pmsg_warning("-P %s is %s; consider\n", *portp, m? "ambiguous": "not connected"); for(int i = 0; i < n; i++) - if(m == 0 || sa_num_matches_by_sea(sea, sernum, sp+i, 1) == 1) + if(m == 0 || sa_num_matches_by_sea(sea, sernum, sp + i, 1) == 1) sa_print_specs(sp, n, i); } free_libserialport_data(sp, n); @@ -286,6 +292,7 @@ int setport_from_serialadapter(char **portp, const SERIALADAPTER *sea, const cha int setport_from_vid_pid(char **portp, int vid, int pid, const char *sernum) { int rv, m, n; SERPORT *sp = get_libserialport_data(&n); + if(!sp || n <= 0) return -1; @@ -293,13 +300,13 @@ int setport_from_vid_pid(char **portp, int vid, int pid, const char *sernum) { if(m == 1) { // Unique result, set port string rv = -1; for(int i = 0; i < n; i++) - if(sa_num_matches_by_ids(vid, pid, sernum, sp+i, 1)) + if(sa_num_matches_by_ids(vid, pid, sernum, sp + i, 1)) rv = sa_setport(portp, sp[i].port); } else { rv = -2; pmsg_warning("-P %s is %s; consider\n", *portp, m? "ambiguous": "not connected"); for(int i = 0; i < n; i++) - if(m == 0 || sa_num_matches_by_ids(vid, pid, sernum, sp+i, 1) == 1) + if(m == 0 || sa_num_matches_by_ids(vid, pid, sernum, sp + i, 1) == 1) sa_print_specs(sp, n, i); } free_libserialport_data(sp, n); @@ -311,6 +318,7 @@ int setport_from_vid_pid(char **portp, int vid, int pid, const char *sernum) { int touch_serialport(char **portp, int baudrate, int nwaits) { int i, n1, n2; SERPORT *sp1, *sp2, **diff; + sp1 = get_libserialport_data(&n1); if(!sp1 || n1 <= 0 || !portp) return -1; @@ -319,6 +327,7 @@ int touch_serialport(char **portp, int baudrate, int nwaits) { union pinfo pinfo; union filedescriptor fd; + pinfo.serialinfo.baud = baudrate; pinfo.serialinfo.cflags = SERIAL_8N1; if(serial_open(*portp, pinfo, &fd) == -1) { @@ -331,29 +340,31 @@ int touch_serialport(char **portp, int baudrate, int nwaits) { serial_rawclose(&fd); const int nloops = 32, nap = 50; + #if (defined(__arm__) || defined(__aarch64__)) && !defined(__APPLE__) nwaits += 2; #endif + pmsg_notice("waiting for new port..."); usleep(400*1000*nwaits); for(i = nloops; i > 0; i--) { usleep(nap*1000); if((sp2 = get_libserialport_data(&n2))) { diff = sa_spa_not_spb(sp2, n2, sp1, n1); - if(*diff && diff[0]->port && !diff[1]) { // Exactly one new port sprung up + if(*diff && diff[0]->port && !diff[1]) { // Exactly one new port sprung up pmsg_notice2("new port %s discovered\n", (*diff)->port); if(*portp) mmt_free(*portp); *portp = mmt_strdup((*diff)->port); - msg_notice(" %d ms:", (nloops-i+1)*nap + nwaits*400); + msg_notice(" %d ms:", (nloops - i + 1)*nap + nwaits*400); i = -1; // Leave loop } - mmt_free(diff); + mmt_free(diff); free_libserialport_data(sp2, n2); } } free_libserialport_data(sp1, n1); - msg_notice(" using %s port %s\n", i<0? "new": "same", *portp); + msg_notice(" using %s port %s\n", i < 0? "new": "same", *portp); return 0; } @@ -363,17 +374,16 @@ int list_available_serialports(LISTID programmers) { // Get serial port information from libserialport int n; SERPORT *sp = get_libserialport_data(&n); + if(!sp || n <= 0) return -1; - msg_warning("%sossible candidate serial port%s:\n", - n>1? "P": "A p", n>1? "s are": " is"); + msg_warning("%sossible candidate serial port%s:\n", n > 1? "P": "A p", n > 1? "s are": " is"); for(int i = 0; i < n; i++) sa_print_specs(sp, n, i); - msg_warning("Note that above port%s might not be connected to a target board or an AVR programmer.\n", - str_plural(n)); + msg_warning("Note that above port%s might not be connected to a target board or an AVR programmer.\n", str_plural(n)); msg_warning("Also note there may be other direct serial ports not listed above.\n"); for(int k = 0; k < n; k++) @@ -404,13 +414,12 @@ int touch_serialport(char **portp, int baudrate, int nwaits) { pmsg_error("avrdude built without libserialport support; please compile again with libserialport installed\n"); return -1; } - #endif void list_serialadapters(FILE *fp, const char *prefix, LISTID programmers) { LNODEID ln1, ln2, ln3; SERIALADAPTER *sea; - int maxlen=0, len; + int maxlen = 0, len; sort_programmers(programmers); @@ -419,8 +428,9 @@ void list_serialadapters(FILE *fp, const char *prefix, LISTID programmers) { sea = ldata(ln1); if(!is_serialadapter(sea)) continue; - for(ln2=lfirst(sea->id); ln2; ln2=lnext(ln2)) { + for(ln2 = lfirst(sea->id); ln2; ln2 = lnext(ln2)) { const char *id = ldata(ln2); + if(*id == 0 || *id == '.') continue; if((len = strlen(id)) > maxlen) @@ -432,12 +442,13 @@ void list_serialadapters(FILE *fp, const char *prefix, LISTID programmers) { sea = ldata(ln1); if(!is_serialadapter(sea)) continue; - for(ln2=lfirst(sea->id); ln2; ln2=lnext(ln2)) { + for(ln2 = lfirst(sea->id); ln2; ln2 = lnext(ln2)) { const char *id = ldata(ln2); + if(*id == 0 || *id == '.') continue; fprintf(fp, "%s%-*s = [usbvid 0x%04x, usbpid", prefix, maxlen, id, sea->usbvid); - for(ln3=lfirst(sea->usbpid); ln3; ln3=lnext(ln3)) + for(ln3 = lfirst(sea->usbpid); ln3; ln3 = lnext(ln3)) fprintf(fp, " 0x%04x", *(int *) ldata(ln3)); if(sea->usbsn && *sea->usbsn) fprintf(fp, ", usbsn %s", sea->usbsn); diff --git a/src/serialupdi.c b/src/serialupdi.c index ddaa40271..b5f7304a5 100644 --- a/src/serialupdi.c +++ b/src/serialupdi.c @@ -82,24 +82,24 @@ static int serialupdi_reset(const PROGRAMMER *pgm, reset_mode mode) { self.logger.info("Release reset") self.readwrite.write_cs(constants.UPDI_ASI_RESET_REQ, 0x00) */ - switch (mode) { - case APPLY_RESET: - pmsg_debug("sending reset request\n"); - return updi_write_cs(pgm, UPDI_ASI_RESET_REQ, UPDI_RESET_REQ_VALUE); - case RELEASE_RESET: - pmsg_debug("sending release reset request\n"); - return updi_write_cs(pgm, UPDI_ASI_RESET_REQ, 0x00); + switch(mode) { + case APPLY_RESET: + pmsg_debug("sending reset request\n"); + return updi_write_cs(pgm, UPDI_ASI_RESET_REQ, UPDI_RESET_REQ_VALUE); + case RELEASE_RESET: + pmsg_debug("sending release reset request\n"); + return updi_write_cs(pgm, UPDI_ASI_RESET_REQ, 0x00); } return -1; } static int serialupdi_reset_connection(const PROGRAMMER *pgm) { - if (serialupdi_reset(pgm, APPLY_RESET) < 0) { + if(serialupdi_reset(pgm, APPLY_RESET) < 0) { pmsg_error("apply reset operation failed\n"); return -1; } - if (serialupdi_reset(pgm, RELEASE_RESET) < 0) { + if(serialupdi_reset(pgm, RELEASE_RESET) < 0) { pmsg_error("release reset operation failed\n"); return -1; } @@ -108,82 +108,81 @@ static int serialupdi_reset_connection(const PROGRAMMER *pgm) { } static int serialupdi_decode_sib(const PROGRAMMER *pgm, updi_sib_info *sib_info) { - char * str_ptr; + char *str_ptr; - sib_info->sib_string[SIB_INFO_STRING_LENGTH]=0; + sib_info->sib_string[SIB_INFO_STRING_LENGTH] = 0; pmsg_debug("received SIB: [%s]\n", sib_info->sib_string); - memset(sib_info->family_string, 0, SIB_INFO_FAMILY_LENGTH+1); - memset(sib_info->nvm_string, 0, SIB_INFO_NVM_LENGTH+1); - memset(sib_info->debug_string, 0, SIB_INFO_DEBUG_LENGTH+1); - memset(sib_info->pdi_string, 0, SIB_INFO_PDI_LENGTH+1); - memset(sib_info->extra_string, 0, SIB_INFO_EXTRA_LENGTH+1); + memset(sib_info->family_string, 0, SIB_INFO_FAMILY_LENGTH + 1); + memset(sib_info->nvm_string, 0, SIB_INFO_NVM_LENGTH + 1); + memset(sib_info->debug_string, 0, SIB_INFO_DEBUG_LENGTH + 1); + memset(sib_info->pdi_string, 0, SIB_INFO_PDI_LENGTH + 1); + memset(sib_info->extra_string, 0, SIB_INFO_EXTRA_LENGTH + 1); memcpy(sib_info->family_string, sib_info->sib_string, SIB_INFO_FAMILY_LENGTH); memcpy(sib_info->nvm_string, sib_info->sib_string + 8, SIB_INFO_NVM_LENGTH); memcpy(sib_info->debug_string, sib_info->sib_string + 11, SIB_INFO_DEBUG_LENGTH); memcpy(sib_info->pdi_string, sib_info->sib_string + 15, SIB_INFO_PDI_LENGTH); - strcpy(sib_info->extra_string, (char *)sib_info->sib_string + 19); + strcpy(sib_info->extra_string, (char *) sib_info->sib_string + 19); str_ptr = strstr(sib_info->nvm_string, ":"); - if (!str_ptr) { + if(!str_ptr) { pmsg_error("incorrect format of NVM string\n"); return -1; } - sib_info->nvm_version = *(str_ptr+1); + sib_info->nvm_version = *(str_ptr + 1); str_ptr = strstr(sib_info->debug_string, ":"); - if (!str_ptr) { + if(!str_ptr) { pmsg_error("incorrect format of DEBUG string\n"); return -1; } - sib_info->debug_version = *(str_ptr+1); + sib_info->debug_version = *(str_ptr + 1); pmsg_debug("Device family ID: %s\n", sib_info->family_string); pmsg_debug("NVM interface: %s\n", sib_info->nvm_string); pmsg_debug("Debug interface: %s\n", sib_info->debug_string); pmsg_debug("PDI oscillator: %s\n", sib_info->pdi_string); pmsg_debug("Extra information: %s\n", sib_info->extra_string); - switch (sib_info->nvm_version) { - case '0': - pmsg_notice("NVM type 0: 16-bit, page oriented write\n"); - updi_set_nvm_mode(pgm, UPDI_NVM_MODE_V0); - updi_set_datalink_mode(pgm, UPDI_LINK_MODE_16BIT); - break; - case '2': - pmsg_notice("NVM type 2: 24-bit, word oriented write\n"); - updi_set_nvm_mode(pgm, UPDI_NVM_MODE_V2); - updi_set_datalink_mode(pgm, UPDI_LINK_MODE_24BIT); - break; - case '3': - pmsg_notice("NVM type 3: 24-bit, page oriented\n"); - updi_set_nvm_mode(pgm, UPDI_NVM_MODE_V3); - updi_set_datalink_mode(pgm, UPDI_LINK_MODE_24BIT); - break; - case '4': - pmsg_notice("NVM type 4: 24-bit, word oriented\n"); - updi_set_nvm_mode(pgm, UPDI_NVM_MODE_V4); - updi_set_datalink_mode(pgm, UPDI_LINK_MODE_24BIT); - break; - case '5': - pmsg_notice("NVM type 5: 24-bit, page oriented\n"); - updi_set_nvm_mode(pgm, UPDI_NVM_MODE_V5); - updi_set_datalink_mode(pgm, UPDI_LINK_MODE_24BIT); - break; - default: - pmsg_warning("unsupported NVM type: %c, please update software\n", sib_info->nvm_version); - return -1; + switch(sib_info->nvm_version) { + case '0': + pmsg_notice("NVM type 0: 16-bit, page oriented write\n"); + updi_set_nvm_mode(pgm, UPDI_NVM_MODE_V0); + updi_set_datalink_mode(pgm, UPDI_LINK_MODE_16BIT); + break; + case '2': + pmsg_notice("NVM type 2: 24-bit, word oriented write\n"); + updi_set_nvm_mode(pgm, UPDI_NVM_MODE_V2); + updi_set_datalink_mode(pgm, UPDI_LINK_MODE_24BIT); + break; + case '3': + pmsg_notice("NVM type 3: 24-bit, page oriented\n"); + updi_set_nvm_mode(pgm, UPDI_NVM_MODE_V3); + updi_set_datalink_mode(pgm, UPDI_LINK_MODE_24BIT); + break; + case '4': + pmsg_notice("NVM type 4: 24-bit, word oriented\n"); + updi_set_nvm_mode(pgm, UPDI_NVM_MODE_V4); + updi_set_datalink_mode(pgm, UPDI_LINK_MODE_24BIT); + break; + case '5': + pmsg_notice("NVM type 5: 24-bit, page oriented\n"); + updi_set_nvm_mode(pgm, UPDI_NVM_MODE_V5); + updi_set_datalink_mode(pgm, UPDI_LINK_MODE_24BIT); + break; + default: + pmsg_warning("unsupported NVM type: %c, please update software\n", sib_info->nvm_version); + return -1; } return 0; } -static void serialupdi_close(PROGRAMMER * pgm) -{ +static void serialupdi_close(PROGRAMMER *pgm) { pmsg_notice("leaving NVM programming mode\n"); - if (serialupdi_leave_progmode(pgm) < 0) { + if(serialupdi_leave_progmode(pgm) < 0) { pmsg_error("unable to leave NVM programming mode\n"); } - if (updi_get_rts_mode(pgm) != RTS_MODE_DEFAULT) { + if(updi_get_rts_mode(pgm) != RTS_MODE_DEFAULT) { pmsg_notice("releasing DTR/RTS handshake lines\n"); } @@ -208,19 +207,20 @@ static int serialupdi_wait_for_unlock(const PROGRAMMER *pgm, unsigned int ms) { self.logger.error("Timeout waiting for device to unlock") return False -*/ +*/ unsigned long start_time; unsigned long current_time; uint8_t status; + start_time = avr_ustimestamp(); do { - if (updi_read_cs(pgm, UPDI_ASI_SYS_STATUS, &status) >= 0) { - if (!(status & (1 << UPDI_ASI_SYS_STATUS_LOCKSTATUS))) { + if(updi_read_cs(pgm, UPDI_ASI_SYS_STATUS, &status) >= 0) { + if(!(status & (1 << UPDI_ASI_SYS_STATUS_LOCKSTATUS))) { return 0; } } current_time = avr_ustimestamp(); - } while ((current_time - start_time) < (ms * 1000)); + } while((current_time - start_time) < (ms*1000)); pmsg_error("timeout waiting for device to unlock\n"); return -1; @@ -254,25 +254,26 @@ static int serialupdi_wait_for_urow(const PROGRAMMER *pgm, unsigned int ms, urow self.logger.error("Timeout waiting for device to enter UROW WRITE mode") return False -*/ +*/ unsigned long start_time; unsigned long current_time; uint8_t status; + start_time = avr_ustimestamp(); do { - if (updi_read_cs(pgm, UPDI_ASI_SYS_STATUS, &status) >= 0) { - if (mode == WAIT_FOR_UROW_HIGH) { - if (status & (1 << UPDI_ASI_SYS_STATUS_UROWPROG)) { + if(updi_read_cs(pgm, UPDI_ASI_SYS_STATUS, &status) >= 0) { + if(mode == WAIT_FOR_UROW_HIGH) { + if(status & (1 << UPDI_ASI_SYS_STATUS_UROWPROG)) { return 0; } } else { - if (!(status & (1 << UPDI_ASI_SYS_STATUS_UROWPROG))) { + if(!(status & (1 << UPDI_ASI_SYS_STATUS_UROWPROG))) { return 0; } } } current_time = avr_ustimestamp(); - } while ((current_time - start_time) < (ms * 1000)); + } while((current_time - start_time) < (ms*1000)); pmsg_error("timeout waiting for device to complete UROW WRITE\n"); return -1; @@ -283,21 +284,21 @@ static int serialupdi_wait_for_nvmprog(const PROGRAMMER *pgm, unsigned int ms) { unsigned long start_time; unsigned long current_time; uint8_t status; + start_time = avr_ustimestamp(); do { - if (updi_read_cs(pgm, UPDI_ASI_SYS_STATUS, &status) >= 0) { - if (status & (1 << UPDI_ASI_SYS_STATUS_NVMPROG)) { + if(updi_read_cs(pgm, UPDI_ASI_SYS_STATUS, &status) >= 0) { + if(status & (1 << UPDI_ASI_SYS_STATUS_NVMPROG)) { return 0; } } current_time = avr_ustimestamp(); - } while ((current_time - start_time) < (ms * 1000)); + } while((current_time - start_time) < (ms*1000)); pmsg_error("timeout waiting for device to enter NVMPROG mode\n"); return -1; } - static int serialupdi_in_prog_mode(const PROGRAMMER *pgm, uint8_t *in_prog_mode) { /* def in_prog_mode(self): @@ -310,15 +311,15 @@ static int serialupdi_in_prog_mode(const PROGRAMMER *pgm, uint8_t *in_prog_mode) */ uint8_t value; int rc; - + rc = updi_read_cs(pgm, UPDI_ASI_SYS_STATUS, &value); - - if (rc < 0) { + + if(rc < 0) { pmsg_error("read CS operation failed\n"); return rc; } - if (value & (1 << UPDI_ASI_SYS_STATUS_NVMPROG)) { + if(value & (1 << UPDI_ASI_SYS_STATUS_NVMPROG)) { *in_prog_mode = 1; } else { *in_prog_mode = 0; @@ -369,52 +370,52 @@ def enter_progmode(self): unsigned char buffer[8]; uint8_t key_status; - if (serialupdi_in_prog_mode(pgm, &in_prog_mode) < 0) { + if(serialupdi_in_prog_mode(pgm, &in_prog_mode) < 0) { pmsg_error("checking UPDI NVM prog mode failed\n"); return -1; } - if (in_prog_mode) { + if(in_prog_mode) { pmsg_debug("already in prog mode\n"); return 0; } - if (serialupdi_reset(pgm, APPLY_RESET) < 0) { + if(serialupdi_reset(pgm, APPLY_RESET) < 0) { pmsg_error("apply reset operation failed\n"); return -1; } memcpy(buffer, UPDI_KEY_NVM, sizeof(buffer)); - if (updi_write_key(pgm, buffer, UPDI_KEY_64, sizeof(buffer)) < 0) { + if(updi_write_key(pgm, buffer, UPDI_KEY_64, sizeof(buffer)) < 0) { pmsg_error("writing NVM KEY failed\n"); return -1; } - if (updi_read_cs(pgm, UPDI_ASI_KEY_STATUS, &key_status) < 0) { + if(updi_read_cs(pgm, UPDI_ASI_KEY_STATUS, &key_status) < 0) { pmsg_error("checking KEY status failed\n"); return -1; } pmsg_debug("key status: 0x%02X\n", key_status); - if (!(key_status & (1 << UPDI_ASI_KEY_STATUS_NVMPROG))) { + if(!(key_status & (1 << UPDI_ASI_KEY_STATUS_NVMPROG))) { pmsg_warning("key was not accepted\n"); } - if (serialupdi_reset(pgm, APPLY_RESET) < 0) { + if(serialupdi_reset(pgm, APPLY_RESET) < 0) { pmsg_error("apply reset operation failed\n"); return -1; } - if (serialupdi_reset(pgm, RELEASE_RESET) < 0) { + if(serialupdi_reset(pgm, RELEASE_RESET) < 0) { pmsg_error("release reset operation failed\n"); return -1; } - if (serialupdi_wait_for_unlock(pgm, 100) < 0) { + if(serialupdi_wait_for_unlock(pgm, 100) < 0) { pmsg_error("unable to enter NVM programming mode: device is locked\n"); return -1; } - if (serialupdi_wait_for_nvmprog(pgm, 500) < 0) { + if(serialupdi_wait_for_nvmprog(pgm, 500) < 0) { pmsg_error("unable to enter NVM programming mode\n"); return -1; } @@ -436,12 +437,12 @@ static int serialupdi_leave_progmode(const PROGRAMMER *pgm) { self.readwrite.write_cs(constants.UPDI_CS_CTRLB, (1 << constants.UPDI_CTRLB_UPDIDIS_BIT) | (1 << constants.UPDI_CTRLB_CCDETDIS_BIT)) */ - if (serialupdi_reset(pgm, APPLY_RESET) < 0) { + if(serialupdi_reset(pgm, APPLY_RESET) < 0) { pmsg_error("apply reset operation failed\n"); return -1; } - if (serialupdi_reset(pgm, RELEASE_RESET) < 0) { + if(serialupdi_reset(pgm, RELEASE_RESET) < 0) { pmsg_error("release reset operation failed\n"); return -1; } @@ -450,136 +451,136 @@ static int serialupdi_leave_progmode(const PROGRAMMER *pgm) { } static int serialupdi_write_userrow(const PROGRAMMER *pgm, const AVRPART *p, const AVRMEM *m, - unsigned int page_size, - unsigned int addr, unsigned int n_bytes) -{ + unsigned int page_size, unsigned int addr, unsigned int n_bytes) { /* - def write_user_row_locked_device(self, address, data): - """ - Writes data to the user row when the device is locked, using a key. - """ - # Put in the key - self.readwrite.write_key(constants.UPDI_KEY_64, constants.UPDI_KEY_UROW) - - # Check key status - key_status = self.readwrite.read_cs(constants.UPDI_ASI_KEY_STATUS) - self.logger.debug("Key status = 0x%02X", key_status) - - if not key_status & (1 << constants.UPDI_ASI_KEY_STATUS_UROWWRITE): - raise PymcuprogError("Key not accepted") - - # Toggle reset - self.reset(apply_reset=True) - self.reset(apply_reset=False) - - # Wait for mode to be entered - if not self.wait_urow_prog(500, wait_for_high=True): - raise PymcuprogError("Failed to enter urow write mode using key") - - # At this point we can write one 'page' to the device, and have it transfered into the user row - # Transfer data - self.readwrite.write_data(address, data) - - # Finalize - self.readwrite.write_cs(constants.UPDI_ASI_SYS_CTRLA, - (1 << constants.UPDI_ASI_SYS_CTRLA_UROW_FINAL) | - (1 << constants.UPDI_CTRLB_CCDETDIS_BIT)) - - # Wait for mode to be exited - if not self.wait_urow_prog(500, wait_for_high=False): - # Toggle reset - self.reset(apply_reset=True) - self.reset(apply_reset=False) - raise PymcuprogError("Failed to exit urow write mode") - - # Clear status - self.readwrite.write_cs(constants.UPDI_ASI_KEY_STATUS, - (1 << constants.UPDI_ASI_KEY_STATUS_UROWWRITE) | - (1 << constants.UPDI_CTRLB_CCDETDIS_BIT)) - - # Toggle reset - self.reset(apply_reset=True) - self.reset(apply_reset=False) - */ + def write_user_row_locked_device(self, address, data): + """ + Writes data to the user row when the device is locked, using a key. + """ + # Put in the key + self.readwrite.write_key(constants.UPDI_KEY_64, constants.UPDI_KEY_UROW) + + # Check key status + key_status = self.readwrite.read_cs(constants.UPDI_ASI_KEY_STATUS) + self.logger.debug("Key status = 0x%02X", key_status) + + if not key_status & (1 << constants.UPDI_ASI_KEY_STATUS_UROWWRITE): + raise PymcuprogError("Key not accepted") + + # Toggle reset + self.reset(apply_reset=True) + self.reset(apply_reset=False) + + # Wait for mode to be entered + if not self.wait_urow_prog(500, wait_for_high=True): + raise PymcuprogError("Failed to enter urow write mode using key") + + # At this point we can write one 'page' to the device, and have it transfered into the user row + # Transfer data + self.readwrite.write_data(address, data) + + # Finalize + self.readwrite.write_cs(constants.UPDI_ASI_SYS_CTRLA, + (1 << constants.UPDI_ASI_SYS_CTRLA_UROW_FINAL) | + (1 << constants.UPDI_CTRLB_CCDETDIS_BIT)) + + # Wait for mode to be exited + if not self.wait_urow_prog(500, wait_for_high=False): + # Toggle reset + self.reset(apply_reset=True) + self.reset(apply_reset=False) + raise PymcuprogError("Failed to exit urow write mode") + + # Clear status + self.readwrite.write_cs(constants.UPDI_ASI_KEY_STATUS, + (1 << constants.UPDI_ASI_KEY_STATUS_UROWWRITE) | + (1 << constants.UPDI_CTRLB_CCDETDIS_BIT)) + + # Toggle reset + self.reset(apply_reset=True) + self.reset(apply_reset=False) + */ unsigned char buffer[8]; uint8_t key_status; memcpy(buffer, UPDI_KEY_UROW, sizeof(buffer)); - if (updi_write_key(pgm, buffer, UPDI_KEY_64, sizeof(buffer)) < 0) { + if(updi_write_key(pgm, buffer, UPDI_KEY_64, sizeof(buffer)) < 0) { pmsg_error("writing USERROW KEY failed\n"); return -1; } - if (updi_read_cs(pgm, UPDI_ASI_KEY_STATUS, &key_status) < 0) { + if(updi_read_cs(pgm, UPDI_ASI_KEY_STATUS, &key_status) < 0) { pmsg_error("checking KEY status failed\n"); return -1; } pmsg_debug("key status: 0x%02X\n", key_status); - if (!(key_status & (1 << UPDI_ASI_KEY_STATUS_UROWWRITE))) { + if(!(key_status & (1 << UPDI_ASI_KEY_STATUS_UROWWRITE))) { pmsg_error("key was not accepted\n"); return -1; } - if (serialupdi_reset(pgm, APPLY_RESET) < 0) { + if(serialupdi_reset(pgm, APPLY_RESET) < 0) { pmsg_error("apply reset operation failed\n"); return -1; } - if (serialupdi_reset(pgm, RELEASE_RESET) < 0) { + if(serialupdi_reset(pgm, RELEASE_RESET) < 0) { pmsg_error("release reset operation failed\n"); return -1; } - if (serialupdi_wait_for_urow(pgm, 500, WAIT_FOR_UROW_HIGH) < 0) { + if(serialupdi_wait_for_urow(pgm, 500, WAIT_FOR_UROW_HIGH) < 0) { pmsg_error("unable to enter USERROW programming mode\n"); return -1; } - if (n_bytes <= UPDI_MAX_REPEAT_SIZE) { - if (updi_write_data(pgm, m->offset+addr, m->buf + addr, n_bytes) < 0) { + if(n_bytes <= UPDI_MAX_REPEAT_SIZE) { + if(updi_write_data(pgm, m->offset + addr, m->buf + addr, n_bytes) < 0) { pmsg_error("writing USER ROW failed\n"); return -1; } } else { - if (updi_write_data_words(pgm, m->offset+addr, m->buf + addr, n_bytes) < 0) { + if(updi_write_data_words(pgm, m->offset + addr, m->buf + addr, n_bytes) < 0) { pmsg_error("writing USER ROW failed\n"); return -1; } } - if (updi_write_cs(pgm, UPDI_ASI_SYS_CTRLA, (1 << UPDI_ASI_SYS_CTRLA_UROW_FINAL) | - (1 << UPDI_CTRLB_CCDETDIS_BIT)) < 0) { + if(updi_write_cs(pgm, UPDI_ASI_SYS_CTRLA, + (1 << UPDI_ASI_SYS_CTRLA_UROW_FINAL) | (1 << UPDI_CTRLB_CCDETDIS_BIT)) < 0) { + pmsg_error("unable to commit user row write\n"); return -1; } - if (serialupdi_wait_for_urow(pgm, 500, WAIT_FOR_UROW_LOW) < 0) { + if(serialupdi_wait_for_urow(pgm, 500, WAIT_FOR_UROW_LOW) < 0) { pmsg_debug("unable to exit USERROW programming mode\n"); - if (serialupdi_reset(pgm, APPLY_RESET) < 0) { + if(serialupdi_reset(pgm, APPLY_RESET) < 0) { pmsg_error("apply reset operation failed\n"); return -1; } - if (serialupdi_reset(pgm, RELEASE_RESET) < 0) { + if(serialupdi_reset(pgm, RELEASE_RESET) < 0) { pmsg_error("release reset operation failed\n"); return -1; } } - if (updi_write_cs(pgm, UPDI_ASI_KEY_STATUS, (1 << UPDI_ASI_KEY_STATUS_UROWWRITE) | - (1 << UPDI_CTRLB_CCDETDIS_BIT)) < 0) { + if(updi_write_cs(pgm, UPDI_ASI_KEY_STATUS, + (1 << UPDI_ASI_KEY_STATUS_UROWWRITE) | (1 << UPDI_CTRLB_CCDETDIS_BIT)) < 0) { + pmsg_error("unable to complete user row write\n"); return -1; } - if (serialupdi_reset(pgm, APPLY_RESET) < 0) { + if(serialupdi_reset(pgm, APPLY_RESET) < 0) { pmsg_error("apply reset operation failed\n"); return -1; } - if (serialupdi_reset(pgm, RELEASE_RESET) < 0) { + if(serialupdi_reset(pgm, RELEASE_RESET) < 0) { pmsg_error("release reset operation failed\n"); return -1; } @@ -593,88 +594,89 @@ static int serialupdi_write_userrow(const PROGRAMMER *pgm, const AVRPART *p, con static int serialupdi_initialize(const PROGRAMMER *pgm, const AVRPART *p) { uint8_t value; - uint8_t reset_link_required=0; - - if (updi_link_init(pgm) < 0) { + uint8_t reset_link_required = 0; + + if(updi_link_init(pgm) < 0) { pmsg_error("UPDI link initialization failed\n"); return -1; } pmsg_notice2("UPDI link initialization OK\n"); - if (updi_get_rts_mode(pgm) != RTS_MODE_DEFAULT) { - pmsg_notice("forcing serial DTR/RTS handshake lines %s\n", updi_get_rts_mode(pgm) == RTS_MODE_LOW ? "LOW" : "HIGH"); + if(updi_get_rts_mode(pgm) != RTS_MODE_DEFAULT) { + pmsg_notice("forcing serial DTR/RTS handshake lines %s\n", updi_get_rts_mode(pgm) == RTS_MODE_LOW? "LOW": "HIGH"); } - if (updi_read_cs(pgm, UPDI_ASI_SYS_STATUS, &value)<0) { + if(updi_read_cs(pgm, UPDI_ASI_SYS_STATUS, &value) < 0) { - /* let's try reset the connection */ - if (!serialupdi_reset_connection(pgm)) { + // Let's try reset the connection + if(!serialupdi_reset_connection(pgm)) { return -1; } - if (updi_read_cs(pgm, UPDI_ASI_SYS_STATUS, &value)<0) { + if(updi_read_cs(pgm, UPDI_ASI_SYS_STATUS, &value) < 0) { pmsg_error("read CS operation during initialization failed\n"); return -1; } } - if (value & (1 << UPDI_ASI_SYS_STATUS_LOCKSTATUS)) { + if(value & (1 << UPDI_ASI_SYS_STATUS_LOCKSTATUS)) { pmsg_notice("device is locked\n"); } - if (value & (1 << UPDI_ASI_SYS_STATUS_UROWPROG)) { + if(value & (1 << UPDI_ASI_SYS_STATUS_UROWPROG)) { pmsg_notice("device in USER ROW programming state, leaving programming mode\n"); reset_link_required = 1; } - if (value & (1 << UPDI_ASI_SYS_STATUS_NVMPROG)) { + if(value & (1 << UPDI_ASI_SYS_STATUS_NVMPROG)) { pmsg_notice("device in NVM programming state, leaving programming mode\n"); reset_link_required = 1; } - if (value & (1 << UPDI_ASI_SYS_STATUS_INSLEEP)) { + if(value & (1 << UPDI_ASI_SYS_STATUS_INSLEEP)) { pmsg_notice("device is in SLEEP mode\n"); } - if (value & (1 << UPDI_ASI_SYS_STATUS_RSTSYS)) { + if(value & (1 << UPDI_ASI_SYS_STATUS_RSTSYS)) { pmsg_notice("device in reset status, trying to release it\n"); - if (serialupdi_reset(pgm, RELEASE_RESET) < 0) { + if(serialupdi_reset(pgm, RELEASE_RESET) < 0) { return -1; } } - if (reset_link_required) { - if (serialupdi_reset_connection(pgm) < 0) { + if(reset_link_required) { + if(serialupdi_reset_connection(pgm) < 0) { pmsg_error("UPDI link reset failed\n"); return -1; } } - updi_sib_info * sib_info = updi_get_sib_info(pgm); + updi_sib_info *sib_info = updi_get_sib_info(pgm); - if (updi_read_sib(pgm, sib_info->sib_string, 32) < 0) { - /* this should never happen, let's try to reset connection and try again */ - if (serialupdi_reset_connection(pgm) < 0) { + if(updi_read_sib(pgm, sib_info->sib_string, 32) < 0) { + // This should never happen, let's try to reset connection and try again + if(serialupdi_reset_connection(pgm) < 0) { pmsg_error("SerialUPDI reset connection failed\n"); return -1; } - if (updi_read_sib(pgm, sib_info->sib_string, 32) < 0) { + if(updi_read_sib(pgm, sib_info->sib_string, 32) < 0) { pmsg_error("read SIB operation failed\n"); return -1; } } - if (serialupdi_decode_sib(pgm, sib_info) < 0) { + if(serialupdi_decode_sib(pgm, sib_info) < 0) { pmsg_error("decode SIB_INFO failed\n"); return -1; } - if (updi_link_init(pgm) < 0) { + if(updi_link_init(pgm) < 0) { pmsg_error("UPDI link initialization failed\n"); return -1; } pmsg_notice("entering NVM programming mode\n"); - /* try, but ignore failure */ - /* It will always fail if the device is locked */ - /* The device will be unlocked by erasing the chip after this. */ - if (serialupdi_enter_progmode(pgm) == 0) { - /* If successful, you can run silicon check */ - if (updi_read_data(pgm, p->syscfg_base+1, &value, 1) < 0) { + /* + * Try, but ignore failure. It will always fail if the device is locked. The + * device will be unlocked by erasing the chip after this. + */ + if(serialupdi_enter_progmode(pgm) == 0) { + // If successful, you can run silicon check + if(updi_read_data(pgm, p->syscfg_base + 1, &value, 1) < 0) { pmsg_error("reading chip silicon revision failed\n"); return -1; } else { @@ -687,14 +689,10 @@ static int serialupdi_initialize(const PROGRAMMER *pgm, const AVRPART *p) { } static void serialupdi_disable(const PROGRAMMER *pgm) { - /* Do nothing. */ - return; } -static void serialupdi_enable(PROGRAMMER * pgm, const AVRPART *p) { - /* Do nothing. */ - +static void serialupdi_enable(PROGRAMMER *pgm, const AVRPART *p) { return; } @@ -702,9 +700,7 @@ static void serialupdi_display(const PROGRAMMER *pgm, const char *p) { return; } -static int serialupdi_cmd(const PROGRAMMER *pgm, const unsigned char *cmd, - unsigned char * res) -{ +static int serialupdi_cmd(const PROGRAMMER *pgm, const unsigned char *cmd, unsigned char *res) { pmsg_error("cmd %s[%s] not implemented yet\n", cmd, res); return -1; } @@ -714,24 +710,23 @@ static int serialupdi_program_enable(const PROGRAMMER *pgm, const AVRPART *p) { return -1; } -#define Return(...) do { pmsg_error(__VA_ARGS__); msg_error("\n"); return -1; } while (0) +#define Return(...) do { pmsg_error(__VA_ARGS__); msg_error("\n"); return -1; } while(0) static int serialupdi_read_byte(const PROGRAMMER *pgm, const AVRPART *p, const AVRMEM *mem, - unsigned long addr, unsigned char * value) -{ + unsigned long addr, unsigned char *value) { pmsg_debug("%s(%s, 0x%04lx)\n", __func__, mem->desc, addr); if(mem->size < 1) Return("cannot read byte from %s %s owing to its size %d", p->desc, mem->desc, mem->size); if(addr >= (unsigned long) mem->size) Return("cannot read byte from %s %s as address 0x%04lx outside range [0, 0x%04x]", - p->desc, mem->desc, addr, mem->size-1); + p->desc, mem->desc, addr, mem->size - 1); if(mem_is_sib(mem)) { if(addr >= SIB_INFO_STRING_LENGTH) Return("cannot read byte from %s sib as address 0x%04lx outside range [0, 0x%04x]", - p->desc, addr, SIB_INFO_STRING_LENGTH-1); - if(!*updi_get_sib_info(pgm)->sib_string) // This should never happen + p->desc, addr, SIB_INFO_STRING_LENGTH - 1); + if(!*updi_get_sib_info(pgm)->sib_string) // This should never happen Return("cannot read byte from %s sib as memory not initialised", p->desc); *value = updi_get_sib_info(pgm)->sib_string[addr]; return 0; @@ -741,40 +736,43 @@ static int serialupdi_read_byte(const PROGRAMMER *pgm, const AVRPART *p, const A } static int serialupdi_write_byte(const PROGRAMMER *pgm, const AVRPART *p, const AVRMEM *mem, - unsigned long addr, unsigned char value) -{ + unsigned long addr, unsigned char value) { pmsg_debug("%s(%s, 0x%04lx, 0x%02x)\n", __func__, mem->desc, addr, value); if(mem->size < 1) Return("cannot write byte to %s %s owing to its size %d", p->desc, mem->desc, mem->size); if(addr >= (unsigned long) mem->size) Return("cannot write byte to %s %s as address 0x%04lx outside range [0, 0x%04x]", - p->desc, mem->desc, addr, mem->size-1); + p->desc, mem->desc, addr, mem->size - 1); - if (mem_is_a_fuse(mem) || mem_is_fuses(mem)) { + if(mem_is_a_fuse(mem) || mem_is_fuses(mem)) { return updi_nvm_write_fuse(pgm, p, mem->offset + addr, value); } - if (mem_is_lock(mem)) { + if(mem_is_lock(mem)) { return updi_nvm_write_fuse(pgm, p, mem->offset + addr, value); } - if (mem_is_eeprom(mem)) { + if(mem_is_eeprom(mem)) { unsigned char buffer[1]; - buffer[0]=value; + + buffer[0] = value; return updi_nvm_write_eeprom(pgm, p, mem->offset + addr, buffer, 1); } - if (mem_is_flash(mem)) { + if(mem_is_flash(mem)) { unsigned char buffer[1]; - buffer[0]=value; + + buffer[0] = value; return updi_nvm_write_flash(pgm, p, mem->offset + addr, buffer, 1); } - if (mem_is_bootrow(mem)) { + if(mem_is_bootrow(mem)) { unsigned char buffer[1]; - buffer[0]=value; + + buffer[0] = value; return updi_nvm_write_boot_row(pgm, p, mem->offset + addr, buffer, 1); } // Read-only memories if(mem_is_readonly(mem)) { unsigned char is; + if(serialupdi_read_byte(pgm, p, mem, addr, &is) >= 0 && is == value) return 0; @@ -784,32 +782,29 @@ static int serialupdi_write_byte(const PROGRAMMER *pgm, const AVRPART *p, const return updi_write_byte(pgm, mem->offset + addr, value); } - static int serialupdi_paged_load(const PROGRAMMER *pgm, const AVRPART *p, const AVRMEM *m, - unsigned int page_size, - unsigned int addr, unsigned int n_bytes) -{ + unsigned int page_size, unsigned int addr, unsigned int n_bytes) { if(n_bytes > 65535) { pmsg_error("%s() called with implausibly high n_bytes = %u\n", __func__, n_bytes); return -1; } - if ((int) n_bytes > m->readsize) { + if((int) n_bytes > m->readsize) { unsigned int read_offset = addr; int remaining_bytes = n_bytes; int read_bytes = 0; int rc; - while (remaining_bytes > 0) { - rc = updi_read_data(pgm, m->offset + read_offset, m->buf + read_offset, - remaining_bytes > m->readsize ? m->readsize : remaining_bytes); - if (rc < 0) { + while(remaining_bytes > 0) { + rc = updi_read_data(pgm, m->offset + read_offset, m->buf + read_offset, + remaining_bytes > m->readsize? m->readsize: remaining_bytes); + if(rc < 0) { pmsg_error("paged load operation failed\n"); return rc; } else { - read_bytes+=rc; - read_offset+=m->readsize; - remaining_bytes-=m->readsize; + read_bytes += rc; + read_offset += m->readsize; + remaining_bytes -= m->readsize; } } return read_bytes; @@ -819,35 +814,33 @@ static int serialupdi_paged_load(const PROGRAMMER *pgm, const AVRPART *p, const } static int serialupdi_paged_write(const PROGRAMMER *pgm, const AVRPART *p, const AVRMEM *m, - unsigned int page_size, - unsigned int addr, unsigned int n_bytes) -{ + unsigned int page_size, unsigned int addr, unsigned int n_bytes) { int rc; if(n_bytes > 65535) { pmsg_error("%s() called with implausibly high n_bytes = %u\n", __func__, n_bytes); return -1; } - if ((int) n_bytes > m->page_size) { + if((int) n_bytes > m->page_size) { unsigned int write_offset = addr; int remaining_bytes = n_bytes; int write_bytes = 0; - while (remaining_bytes > 0) { - - if (mem_is_eeprom(m)) { - rc = updi_nvm_write_eeprom(pgm, p, m->offset + write_offset, m->buf + write_offset, - remaining_bytes > m->page_size ? m->page_size : remaining_bytes); - } else if (mem_is_flash(m)) { - rc = updi_nvm_write_flash(pgm, p, m->offset + write_offset, m->buf + write_offset, - remaining_bytes > m->page_size ? m->page_size : remaining_bytes); - } else if (mem_is_userrow(m)) { - rc = serialupdi_write_userrow(pgm, p, m, page_size, write_offset, - remaining_bytes > m->page_size ? m->page_size : remaining_bytes); - } else if (mem_is_bootrow(m)) { - rc = updi_nvm_write_boot_row(pgm, p, m->offset + write_offset, m->buf + write_offset, - remaining_bytes > m->page_size ? m->page_size : remaining_bytes); - } else if (mem_is_fuses(m)) { + while(remaining_bytes > 0) { + + if(mem_is_eeprom(m)) { + rc = updi_nvm_write_eeprom(pgm, p, m->offset + write_offset, m->buf + write_offset, + remaining_bytes > m->page_size? m->page_size: remaining_bytes); + } else if(mem_is_flash(m)) { + rc = updi_nvm_write_flash(pgm, p, m->offset + write_offset, m->buf + write_offset, + remaining_bytes > m->page_size? m->page_size: remaining_bytes); + } else if(mem_is_userrow(m)) { + rc = serialupdi_write_userrow(pgm, p, m, page_size, write_offset, + remaining_bytes > m->page_size? m->page_size: remaining_bytes); + } else if(mem_is_bootrow(m)) { + rc = updi_nvm_write_boot_row(pgm, p, m->offset + write_offset, m->buf + write_offset, + remaining_bytes > m->page_size? m->page_size: remaining_bytes); + } else if(mem_is_fuses(m)) { pmsg_debug("page write operation requested for fuses, falling back to byte-level write\n"); return -1; } else { @@ -855,28 +848,28 @@ static int serialupdi_paged_write(const PROGRAMMER *pgm, const AVRPART *p, const rc = -1; } - if (rc < 0) { + if(rc < 0) { pmsg_error("paged write operation failed\n"); return rc; } else { - write_bytes+=rc; - write_offset+=m->page_size; - remaining_bytes-=m->page_size; + write_bytes += rc; + write_offset += m->page_size; + remaining_bytes -= m->page_size; } } return write_bytes; } else { - if (mem_is_eeprom(m)) { - rc = updi_nvm_write_eeprom(pgm, p, m->offset+addr, m->buf+addr, n_bytes); - } else if (mem_is_flash(m)) { - rc = updi_nvm_write_flash(pgm, p, m->offset+addr, m->buf+addr, n_bytes); - } else if (mem_is_userrow(m)) { + if(mem_is_eeprom(m)) { + rc = updi_nvm_write_eeprom(pgm, p, m->offset + addr, m->buf + addr, n_bytes); + } else if(mem_is_flash(m)) { + rc = updi_nvm_write_flash(pgm, p, m->offset + addr, m->buf + addr, n_bytes); + } else if(mem_is_userrow(m)) { rc = serialupdi_write_userrow(pgm, p, m, page_size, addr, n_bytes); - } else if (mem_is_bootrow(m)) { - rc = updi_nvm_write_boot_row(pgm, p, m->offset+addr, m->buf+addr, n_bytes); - } else if (mem_is_fuses(m)) { - pmsg_debug("page write operation requested for fuses, falling back to byte-level write\n"); - rc = -1; + } else if(mem_is_bootrow(m)) { + rc = updi_nvm_write_boot_row(pgm, p, m->offset + addr, m->buf + addr, n_bytes); + } else if(mem_is_fuses(m)) { + pmsg_debug("page write operation requested for fuses, falling back to byte-level write\n"); + rc = -1; } else { pmsg_error("invalid memory: <%s:%d>, 0x%06X, %d (0x%04X)\n", m->desc, page_size, addr, n_bytes, n_bytes); rc = -1; @@ -911,41 +904,41 @@ static int serialupdi_unlock(const PROGRAMMER *pgm, const AVRPART *p) { */ unsigned char buffer[8]; uint8_t key_status; - + memcpy(buffer, UPDI_KEY_CHIPERASE, sizeof(buffer)); - if (updi_write_key(pgm, buffer, UPDI_KEY_64, sizeof(buffer)) < 0) { + if(updi_write_key(pgm, buffer, UPDI_KEY_64, sizeof(buffer)) < 0) { pmsg_error("writing NVM KEY failed\n"); return -1; } - if (updi_read_cs(pgm, UPDI_ASI_KEY_STATUS, &key_status) < 0) { + if(updi_read_cs(pgm, UPDI_ASI_KEY_STATUS, &key_status) < 0) { pmsg_error("checking KEY status failed\n"); return -1; } pmsg_debug("key status: 0x%02X\n", key_status); - if (!(key_status & (1 << UPDI_ASI_KEY_STATUS_CHIPERASE))) { + if(!(key_status & (1 << UPDI_ASI_KEY_STATUS_CHIPERASE))) { pmsg_error("key not accepted\n"); return -1; } - if (serialupdi_reset(pgm, APPLY_RESET) < 0) { + if(serialupdi_reset(pgm, APPLY_RESET) < 0) { pmsg_error("apply reset operation failed\n"); return -1; } - if (serialupdi_reset(pgm, RELEASE_RESET) < 0) { + if(serialupdi_reset(pgm, RELEASE_RESET) < 0) { pmsg_error("release reset operation failed\n"); return -1; } - if (serialupdi_wait_for_unlock(pgm, 500) < 0) { + if(serialupdi_wait_for_unlock(pgm, 500) < 0) { pmsg_error("waiting for unlock failed\n"); return -1; } - if (updi_link_init(pgm) < 0) { + if(updi_link_init(pgm) < 0) { pmsg_error("UPDI link reinitialization failed\n"); return -1; } @@ -956,14 +949,14 @@ static int serialupdi_unlock(const PROGRAMMER *pgm, const AVRPART *p) { static int serialupdi_chip_erase(const PROGRAMMER *pgm, const AVRPART *p) { uint8_t value; - if (updi_read_cs(pgm, UPDI_ASI_SYS_STATUS, &value)<0) { + if(updi_read_cs(pgm, UPDI_ASI_SYS_STATUS, &value) < 0) { pmsg_error("read CS operation during chip erase failed\n"); return -1; } - - if (value & (1 << UPDI_ASI_SYS_STATUS_LOCKSTATUS)) { + + if(value & (1 << UPDI_ASI_SYS_STATUS_LOCKSTATUS)) { pmsg_warning("device is locked\n"); - if (ovsigck) { + if(ovsigck) { pmsg_warning("attempting device erase\n"); return serialupdi_unlock(pgm, p); } @@ -973,9 +966,7 @@ static int serialupdi_chip_erase(const PROGRAMMER *pgm, const AVRPART *p) { return -1; } -static int serialupdi_page_erase(const PROGRAMMER *pgm, const AVRPART *p, const AVRMEM *m, - unsigned int baseaddr) -{ +static int serialupdi_page_erase(const PROGRAMMER *pgm, const AVRPART *p, const AVRMEM *m, unsigned int baseaddr) { return updi_nvm_erase_flash_page(pgm, p, m->offset + baseaddr); } @@ -983,20 +974,20 @@ static int serialupdi_read_signature(const PROGRAMMER *pgm, const AVRPART *p, co uint8_t value; - if (updi_read_cs(pgm, UPDI_ASI_SYS_STATUS, &value)<0) { + if(updi_read_cs(pgm, UPDI_ASI_SYS_STATUS, &value) < 0) { pmsg_error("read CS operation during signature read failed\n"); return -1; } - if (value & (1 << UPDI_ASI_SYS_STATUS_LOCKSTATUS)) { - m->buf[0]=0x00; - m->buf[1]=0x00; - m->buf[2]=0x00; + if(value & (1 << UPDI_ASI_SYS_STATUS_LOCKSTATUS)) { + m->buf[0] = 0x00; + m->buf[1] = 0x00; + m->buf[2] = 0x00; return LIBAVRDUDE_SOFTFAIL; } else { updi_read_byte(pgm, m->offset + 0, m->buf); - updi_read_byte(pgm, m->offset + 1, m->buf+1); - updi_read_byte(pgm, m->offset + 2, m->buf+2); + updi_read_byte(pgm, m->offset + 1, m->buf + 1); + updi_read_byte(pgm, m->offset + 2, m->buf + 2); } return 3; @@ -1004,10 +995,10 @@ static int serialupdi_read_signature(const PROGRAMMER *pgm, const AVRPART *p, co static int serialupdi_read_sib(const PROGRAMMER *pgm, const AVRPART *p, char *sib) { - updi_sib_info * sib_info = updi_get_sib_info(pgm); + updi_sib_info *sib_info = updi_get_sib_info(pgm); memcpy(sib, sib_info->sib_string, 32); - + return 0; } @@ -1016,13 +1007,13 @@ static int serialupdi_parseextparms(const PROGRAMMER *pgm, const LISTID extparms int rv = 0; bool help = false; - for (LNODEID ln = lfirst(extparms); ln; ln = lnext(ln)) { + for(LNODEID ln = lfirst(extparms); ln; ln = lnext(ln)) { const char *extended_param = ldata(ln); - if (sscanf(extended_param, "rtsdtr=%4s", rts_mode) == 1) { - if (str_caseeq(rts_mode, "low")) { + if(sscanf(extended_param, "rtsdtr=%4s", rts_mode) == 1) { + if(str_caseeq(rts_mode, "low")) { updi_set_rts_mode(pgm, RTS_MODE_LOW); - } else if (str_caseeq(rts_mode, "high")) { + } else if(str_caseeq(rts_mode, "high")) { updi_set_rts_mode(pgm, RTS_MODE_HIGH); } else { pmsg_error("-x rtsdtr=: RTS/DTR mode must be LOW or HIGH\n"); @@ -1032,12 +1023,12 @@ static int serialupdi_parseextparms(const PROGRAMMER *pgm, const LISTID extparms continue; } - if (str_eq(extended_param, "help")) { + if(str_eq(extended_param, "help")) { help = true; rv = LIBAVRDUDE_EXIT; } - if (!help) { + if(!help) { pmsg_error("invalid extended parameter -x %s\n", extended_param); rv = -1; } @@ -1053,35 +1044,29 @@ static int serialupdi_parseextparms(const PROGRAMMER *pgm, const LISTID extparms void serialupdi_initpgm(PROGRAMMER *pgm) { strcpy(pgm->type, "serialupdi"); - /* - * mandatory functions - */ - - pgm->initialize = serialupdi_initialize; + // Mandatory functions + pgm->initialize = serialupdi_initialize; pgm->parseextparams = serialupdi_parseextparms; - pgm->display = serialupdi_display; - pgm->enable = serialupdi_enable; - pgm->disable = serialupdi_disable; + pgm->display = serialupdi_display; + pgm->enable = serialupdi_enable; + pgm->disable = serialupdi_disable; pgm->program_enable = serialupdi_program_enable; - pgm->chip_erase = serialupdi_chip_erase; - pgm->cmd = serialupdi_cmd; - pgm->open = serialupdi_open; - pgm->close = serialupdi_close; - pgm->read_byte = serialupdi_read_byte; - pgm->write_byte = serialupdi_write_byte; - - /* - * optional functions - */ - - pgm->unlock = serialupdi_unlock; - pgm->paged_write = serialupdi_paged_write; + pgm->chip_erase = serialupdi_chip_erase; + pgm->cmd = serialupdi_cmd; + pgm->open = serialupdi_open; + pgm->close = serialupdi_close; + pgm->read_byte = serialupdi_read_byte; + pgm->write_byte = serialupdi_write_byte; + + // Optional functions + pgm->unlock = serialupdi_unlock; + pgm->paged_write = serialupdi_paged_write; pgm->read_sig_bytes = serialupdi_read_signature; - pgm->read_sib = serialupdi_read_sib; - pgm->paged_load = serialupdi_paged_load; - pgm->page_erase = serialupdi_page_erase; - pgm->setup = serialupdi_setup; - pgm->teardown = serialupdi_teardown; + pgm->read_sib = serialupdi_read_sib; + pgm->paged_load = serialupdi_paged_load; + pgm->page_erase = serialupdi_page_erase; + pgm->setup = serialupdi_setup; + pgm->teardown = serialupdi_teardown; } diff --git a/src/serialupdi.h b/src/serialupdi.h index f5b2bdbf1..288916941 100644 --- a/src/serialupdi.h +++ b/src/serialupdi.h @@ -31,11 +31,11 @@ extern "C" { #endif -extern const char serialupdi_desc[]; -void serialupdi_initpgm(PROGRAMMER *pgm); + extern const char serialupdi_desc[]; + void serialupdi_initpgm(PROGRAMMER *pgm); #ifdef __cplusplus } #endif -#endif /* serialupdi_h */ +#endif diff --git a/src/serprog.c b/src/serprog.c index a3767b5d8..c6622254e 100644 --- a/src/serprog.c +++ b/src/serprog.c @@ -56,31 +56,31 @@ struct pdata { // According to Serial Flasher Protocol Specification - version 1 #define S_ACK 0x06 #define S_NAK 0x15 -#define S_CMD_NOP 0x00 // No operation -#define S_CMD_Q_IFACE 0x01 // Query interface version -#define S_CMD_Q_CMDMAP 0x02 // Query supported commands bitmap -#define S_CMD_Q_PGMNAME 0x03 // Query programmer name -#define S_CMD_Q_SERBUF 0x04 // Query Serial Buffer Size -#define S_CMD_Q_BUSTYPE 0x05 // Query supported bustypes -#define S_CMD_Q_CHIPSIZE 0x06 // Query supported chipsize (2^n format) -#define S_CMD_Q_OPBUF 0x07 // Query operation buffer size -#define S_CMD_Q_WRNMAXLEN 0x08 // Query Write to opbuf: Write-N maximum length -#define S_CMD_R_BYTE 0x09 // Read a single byte -#define S_CMD_R_NBYTES 0x0A // Read n bytes -#define S_CMD_O_INIT 0x0B // Initialize operation buffer -#define S_CMD_O_WRITEB 0x0C // Write opbuf: Write byte with address -#define S_CMD_O_WRITEN 0x0D // Write to opbuf: Write-N -#define S_CMD_O_DELAY 0x0E // Write opbuf: udelay -#define S_CMD_O_EXEC 0x0F // Execute operation buffer -#define S_CMD_SYNCNOP 0x10 // Special no-operation that returns NAK+ACK -#define S_CMD_Q_RDNMAXLEN 0x11 // Query read-n maximum length -#define S_CMD_S_BUSTYPE 0x12 // Set used bustype(s). -#define S_CMD_O_SPIOP 0x13 // Perform SPI operation. -#define S_CMD_S_SPI_FREQ 0x14 // Set SPI clock frequency -#define S_CMD_S_PIN_STATE 0x15 // Enable/disable output drivers -#define S_CMD_S_SPI_CS 0x16 // Set SPI chip select to use -#define S_CMD_S_SPI_MODE 0x17 // Sets the SPI mode used by S_CMD_O_SPIOP -#define S_CMD_S_CS_MODE 0x18 // Sets the way the CS is controlled +#define S_CMD_NOP 0x00 // No operation +#define S_CMD_Q_IFACE 0x01 // Query interface version +#define S_CMD_Q_CMDMAP 0x02 // Query supported commands bitmap +#define S_CMD_Q_PGMNAME 0x03 // Query programmer name +#define S_CMD_Q_SERBUF 0x04 // Query Serial Buffer Size +#define S_CMD_Q_BUSTYPE 0x05 // Query supported bustypes +#define S_CMD_Q_CHIPSIZE 0x06 // Query supported chipsize (2^n format) +#define S_CMD_Q_OPBUF 0x07 // Query operation buffer size +#define S_CMD_Q_WRNMAXLEN 0x08 // Query Write to opbuf: Write-N maximum length +#define S_CMD_R_BYTE 0x09 // Read a single byte +#define S_CMD_R_NBYTES 0x0A // Read n bytes +#define S_CMD_O_INIT 0x0B // Initialize operation buffer +#define S_CMD_O_WRITEB 0x0C // Write opbuf: Write byte with address +#define S_CMD_O_WRITEN 0x0D // Write to opbuf: Write-N +#define S_CMD_O_DELAY 0x0E // Write opbuf: udelay +#define S_CMD_O_EXEC 0x0F // Execute operation buffer +#define S_CMD_SYNCNOP 0x10 // Special no-operation that returns NAK+ACK +#define S_CMD_Q_RDNMAXLEN 0x11 // Query read-n maximum length +#define S_CMD_S_BUSTYPE 0x12 // Set used bustype(s). +#define S_CMD_O_SPIOP 0x13 // Perform SPI operation. +#define S_CMD_S_SPI_FREQ 0x14 // Set SPI clock frequency +#define S_CMD_S_PIN_STATE 0x15 // Enable/disable output drivers +#define S_CMD_S_SPI_CS 0x16 // Set SPI chip select to use +#define S_CMD_S_SPI_MODE 0x17 // Sets the SPI mode used by S_CMD_O_SPIOP +#define S_CMD_S_CS_MODE 0x18 // Sets the way the CS is controlled enum spi_mode { SPI_MODE_HALF_DUPLEX = 0, @@ -146,7 +146,7 @@ static int perform_serprog_cmd(const PROGRAMMER *pgm, uint8_t cmd, return perform_serprog_cmd_full(pgm, cmd, params, params_len, NULL, 0, recv_buf, recv_len); } -/** +/* * @brief Sends/receives a message to the AVR in full duplex mode * @return -1 on failure, otherwise number of bytes sent/received */ @@ -162,7 +162,7 @@ static int serprog_spi_duplex(const PROGRAMMER *pgm, const unsigned char *tx, un } static bool is_serprog_cmd_supported(const unsigned char *cmd_bitmap, unsigned char cmd) { - return (cmd_bitmap[cmd / 8] >> (cmd % 8)) & 1; + return (cmd_bitmap[cmd/8] >> (cmd%8)) & 1; } // Programmer lifecycle handlers @@ -281,7 +281,7 @@ static int serprog_cmd(const PROGRAMMER *pgm, const unsigned char *cmd, unsigned } static int serprog_initialize(const PROGRAMMER *pgm, const AVRPART *part) { - if(part->prog_modes & PM_TPI) { + if(is_tpi(part)) { // We do not support TPI; this is a dedicated SPI thing pmsg_error("the %s programmer does not support TPI\n", pgmid); return -1; @@ -292,10 +292,8 @@ static int serprog_initialize(const PROGRAMMER *pgm, const AVRPART *part) { // Set SPI clock frequency if(is_serprog_cmd_supported(my.cmd_bitmap, S_CMD_S_SPI_FREQ)) { memset(buf, 0, sizeof buf); - uint32_t frequency = - pgm->bitclock > 0? 1/pgm->bitclock: - part->factory_fcpu > 0? part->factory_fcpu/4: - 250000; + uint32_t frequency = pgm->bitclock > 0? 1/pgm->bitclock: part->factory_fcpu > 0? part->factory_fcpu/4: 250000; + write_le32(buf, frequency); if(perform_serprog_cmd(pgm, S_CMD_S_SPI_FREQ, buf, 4, buf, 4) != 0) { pmsg_error("cannot set SPI frequency %u Hz\n", (unsigned) frequency); @@ -374,24 +372,25 @@ static int serprog_program_enable(const PROGRAMMER *pgm, const AVRPART *p) { if(res[2] != cmd[1]) { - /** From ATtiny441 datasheet: + /* + * From ATtiny441 datasheet: * * In some systems, the programmer cannot guarantee that SCK is held low - * during power-up. In this case, RESET must be given a positive pulse after - * SCK has been set to '0'. The duration of the pulse must be at least t RST - * plus two CPU clock cycles. See Table 25-5 on page 240 for definition of - * minimum pulse width on RESET pin, t RST - * 2. Wait for at least 20 ms and then enable serial programming by sending - * the Programming Enable serial instruction to the SDO pin - * 3. The serial programming instructions will not work if the communication - * is out of synchronization. When in sync, the second byte (0x53) will echo - * back when issuing the third byte of the Programming Enable instruction - * ... - * If the 0x53 did not echo back, give RESET a positive pulse and issue a - * new Programming Enable command + * during power-up. In this case, RESET must be given a positive pulse + * after SCK has been set to '0'. The duration of the pulse must be at + * least t RST plus two CPU clock cycles. See Table 25-5 on page 240 for + * definition of minimum pulse width on RESET pin, t RST 2. Wait for at + * least 20 ms and then enable serial programming by sending the + * Programming Enable serial instruction to the SDO pin 3. The serial + * programming instructions will not work if the communication is out of + * synchronization. When in sync, the second byte (0x53) will echo back + * when issuing the third byte of the Programming Enable instruction ... If + * the 0x53 did not echo back, give RESET a positive pulse and issue a new + * Programming Enable command */ unsigned char cs_mode = CS_MODE_DESELECTED; + if(perform_serprog_cmd(pgm, S_CMD_S_CS_MODE, &cs_mode, 1, NULL, 0) != 0) return -1; diff --git a/src/serprog.h b/src/serprog.h index 587f66f8e..e9a444a68 100644 --- a/src/serprog.h +++ b/src/serprog.h @@ -1,4 +1,3 @@ - /* * avrdude - A Downloader/Uploader for AVR device programmers * @@ -26,10 +25,11 @@ extern "C" { #endif -extern const char serprog_desc[]; -void serprog_initpgm(PROGRAMMER *pgm); + extern const char serprog_desc[]; + void serprog_initpgm(PROGRAMMER *pgm); #ifdef __cplusplus } #endif -#endif // serprog_h + +#endif diff --git a/src/solaris_ecpp.h b/src/solaris_ecpp.h index af956f7bc..3b851ea25 100644 --- a/src/solaris_ecpp.h +++ b/src/solaris_ecpp.h @@ -22,27 +22,38 @@ #include #define ppi_claim(fd) \ - do { \ - struct ecpp_transfer_parms p; \ - (void)ioctl(fd, ECPPIOC_GETPARMS, &p); \ - p.mode = ECPP_DIAG_MODE; \ - (void)ioctl(fd, ECPPIOC_SETPARMS, &p); \ - } while(0); + do { \ + struct ecpp_transfer_parms p; \ + (void) ioctl((fd), ECPPIOC_GETPARMS, &p); \ + p.mode = ECPP_DIAG_MODE; \ + (void) ioctl((fd), ECPPIOC_SETPARMS, &p); \ + } while(0) #define ppi_release(fd) #define DO_PPI_READ(fd, reg, valp) \ - do { struct ecpp_regs r; \ - if ((reg) == PPIDATA) { (void)ioctl(fd, ECPPIOC_GETDATA, valp); } \ - else { (void)ioctl(fd, ECPPIOC_GETREGS, &r); \ - *(valp) = ((reg) == PPICTRL)? r.dcr: r.dsr; } \ - } while(0) -#define DO_PPI_WRITE(fd, reg, valp) \ - do { struct ecpp_regs r; \ - if ((reg) == PPIDATA) { (void)ioctl(fd, ECPPIOC_SETDATA, valp); } \ - else { if ((reg) == PPICTRL) r.dcr = *(valp); else r.dsr = *(valp); \ - (void)ioctl(fd, ECPPIOC_SETREGS, &r); } \ - } while(0) + do { \ + struct ecpp_regs r; \ + if((reg) == PPIDATA) { \ + (void) ioctl((fd), ECPPIOC_GETDATA, (valp)); \ + } else { \ + (void) ioctl(*fd), ECPPIOC_GETREGS, &r); \ + *(valp) = ((reg) == PPICTRL)? r.dcr: r.dsr; \ + } \ + } while(0) +#define DO_PPI_WRITE(fd, reg, valp) \ + do { \ + struct ecpp_regs r; \ + if((reg) == PPIDATA) { \ + (void) ioctl((fd), ECPPIOC_SETDATA, (valp)); \ + } else { \ + if((reg) == PPICTRL) \ + r.dcr = *(valp); \ + else \ + r.dsr = *(valp); \ + (void) ioctl((fd), ECPPIOC_SETREGS, &r); \ + } \ + } while(0) -#endif /* solaris_ecpp_h */ +#endif diff --git a/src/stk500.c b/src/stk500.c index 0f4e48773..9fc0a674e 100644 --- a/src/stk500.c +++ b/src/stk500.c @@ -44,10 +44,10 @@ #define MAX_SYNC_ATTEMPTS 10 static double f_to_kHz_MHz(double f, const char **unit) { - if (f >= 1e6) { + if(f >= 1e6) { f /= 1e6; *unit = "MHz"; - } else if (f >= 1e3) { + } else if(f >= 1e3) { f /= 1000; *unit = "kHz"; } else @@ -56,9 +56,9 @@ static double f_to_kHz_MHz(double f, const char **unit) { } static int get_decimals(double f) { - if (f >= 1e6) + if(f >= 1e6) return 6; - if (f >= 1e3) + if(f >= 1e3) return 3; return 0; } @@ -67,29 +67,25 @@ static int stk500_getparm(const PROGRAMMER *pgm, unsigned parm, unsigned *value) static int stk500_setparm(const PROGRAMMER *pgm, unsigned parm, unsigned value); static void stk500_print_parms1(const PROGRAMMER *pgm, const char *p, FILE *fp); - static int stk500_send(const PROGRAMMER *pgm, unsigned char *buf, size_t len) { return serial_send(&pgm->fd, buf, len); } - static int stk500_recv(const PROGRAMMER *pgm, unsigned char *buf, size_t len) { int rv; rv = serial_recv(&pgm->fd, buf, len); - if (rv < 0) { + if(rv < 0) { pmsg_error("programmer is not responding\n"); return -1; } return 0; } - int stk500_drain(const PROGRAMMER *pgm, int display) { return serial_drain(&pgm->fd, display); } - int stk500_getsync(const PROGRAMMER *pgm) { unsigned char buf[32], resp[32]; int attempt; @@ -97,24 +93,21 @@ int stk500_getsync(const PROGRAMMER *pgm) { buf[0] = Cmnd_STK_GET_SYNC; buf[1] = Sync_CRC_EOP; - - /* - * First send and drain a few times to get rid of line noise - */ - + + // First send and drain a few times to get rid of line noise stk500_send(pgm, buf, 2); stk500_drain(pgm, 0); stk500_send(pgm, buf, 2); stk500_drain(pgm, 0); - if(PDATA(pgm)->retry_attempts) - max_sync_attempts = PDATA(pgm)->retry_attempts; + if(my.retry_attempts) + max_sync_attempts = my.retry_attempts; else max_sync_attempts = MAX_SYNC_ATTEMPTS; - for (attempt = 0; attempt < max_sync_attempts; attempt++) { + for(attempt = 0; attempt < max_sync_attempts; attempt++) { // Restart Arduino bootloader for every sync attempt - if(str_eq(pgm->type, "Arduino") && PDATA(pgm)->autoreset && attempt > 0) { + if(str_eq(pgm->type, "Arduino") && my.autoreset && attempt > 0) { // This code assumes a negative-logic USB to TTL serial adapter // Pull the RTS/DTR line low to reset AVR: it is still high from open()/last attempt serial_set_dtr_rts(&pgm->fd, 1); @@ -133,14 +126,14 @@ int stk500_getsync(const PROGRAMMER *pgm) { pmsg_warning("attempt %d of %d: not in sync: resp=0x%02x\n", attempt + 1, max_sync_attempts, resp[0]); } - if (attempt == max_sync_attempts) { + if(attempt == max_sync_attempts) { stk500_drain(pgm, 0); return -1; } - if (stk500_recv(pgm, resp, 1) < 0) + if(stk500_recv(pgm, resp, 1) < 0) return -1; - if (resp[0] != Resp_STK_OK) { + if(resp[0] != Resp_STK_OK) { pmsg_error("cannot communicate with device: resp=0x%02x\n", resp[0]); return -1; } @@ -148,14 +141,11 @@ int stk500_getsync(const PROGRAMMER *pgm) { return 0; } - /* - * transmit an AVR device command and return the results; 'cmd' and - * 'res' must point to at least a 4 byte data buffer + * Transmit an AVR device command and return the results; 'cmd' and 'res' must + * point to at least a 4 byte data buffer */ -static int stk500_cmd(const PROGRAMMER *pgm, const unsigned char *cmd, - unsigned char *res) -{ +static int stk500_cmd(const PROGRAMMER *pgm, const unsigned char *cmd, unsigned char *res) { unsigned char buf[32]; buf[0] = Cmnd_STK_UNIVERSAL; @@ -167,9 +157,9 @@ static int stk500_cmd(const PROGRAMMER *pgm, const unsigned char *cmd, stk500_send(pgm, buf, 6); - if (stk500_recv(pgm, buf, 1) < 0) + if(stk500_recv(pgm, buf, 1) < 0) return -1; - if (buf[0] != Resp_STK_INSYNC) { + if(buf[0] != Resp_STK_INSYNC) { pmsg_error("programmer is out of sync\n"); return -1; } @@ -177,12 +167,12 @@ static int stk500_cmd(const PROGRAMMER *pgm, const unsigned char *cmd, res[0] = cmd[1]; res[1] = cmd[2]; res[2] = cmd[3]; - if (stk500_recv(pgm, &res[3], 1) < 0) + if(stk500_recv(pgm, &res[3], 1) < 0) return -1; - if (stk500_recv(pgm, buf, 1) < 0) + if(stk500_recv(pgm, buf, 1) < 0) return -1; - if (buf[0] != Resp_STK_OK) { + if(buf[0] != Resp_STK_OK) { pmsg_error("protocol expects OK byte 0x%02x but got 0x%02x\n", Resp_STK_OK, buf[0]); return -1; } @@ -190,21 +180,17 @@ static int stk500_cmd(const PROGRAMMER *pgm, const unsigned char *cmd, return 0; } - - -/* - * issue the 'chip erase' command to the AVR device - */ +// Issue the 'chip erase' command to the AVR device static int stk500_chip_erase(const PROGRAMMER *pgm, const AVRPART *p) { unsigned char cmd[4]; unsigned char res[4]; - if (pgm->cmd == NULL) { + if(pgm->cmd == NULL) { pmsg_error("%s programmer uses %s() without providing a cmd() method\n", pgm->type, __func__); return -1; } - if (p->op[AVR_OP_CHIP_ERASE] == NULL) { + if(p->op[AVR_OP_CHIP_ERASE] == NULL) { pmsg_error("chip erase instruction not defined for part %s\n", p->desc); return -1; } @@ -218,102 +204,90 @@ static int stk500_chip_erase(const PROGRAMMER *pgm, const AVRPART *p) { return 0; } -/* - * issue the 'program enable' command to the AVR device - */ +// Issue the 'program enable' command to the AVR device static int stk500_program_enable(const PROGRAMMER *pgm, const AVRPART *p) { unsigned char buf[16]; - int tries=0; + int tries = 0; + +retry: - retry: - tries++; buf[0] = Cmnd_STK_ENTER_PROGMODE; buf[1] = Sync_CRC_EOP; stk500_send(pgm, buf, 2); - if (stk500_recv(pgm, buf, 1) < 0) + if(stk500_recv(pgm, buf, 1) < 0) return -1; - if (buf[0] == Resp_STK_NOSYNC) { - if (tries > 33) { + if(buf[0] == Resp_STK_NOSYNC) { + if(tries > 33) { pmsg_error("cannot get into sync\n"); return -1; } - if (stk500_getsync(pgm) < 0) + if(stk500_getsync(pgm) < 0) return -1; goto retry; - } - else if (buf[0] != Resp_STK_INSYNC) { + } else if(buf[0] != Resp_STK_INSYNC) { pmsg_error("protocol expects sync byte 0x%02x but got 0x%02x\n", Resp_STK_INSYNC, buf[0]); return -1; } - if (stk500_recv(pgm, buf, 1) < 0) + if(stk500_recv(pgm, buf, 1) < 0) return -1; - if (buf[0] == Resp_STK_OK) { + if(buf[0] == Resp_STK_OK) { return 0; - } - else if (buf[0] == Resp_STK_NODEVICE) { + } else if(buf[0] == Resp_STK_NODEVICE) { pmsg_error("no device\n"); return -1; } - if(buf[0] == Resp_STK_FAILED) - { - pmsg_error("unable to enter programming mode\n"); - return -1; + if(buf[0] == Resp_STK_FAILED) { + pmsg_error("unable to enter programming mode\n"); + return -1; } - pmsg_error("unknown response=0x%02x\n", buf[0]); return -1; } - - -static int stk500_set_extended_parms(const PROGRAMMER *pgm, int n, - unsigned char * cmd) -{ +static int stk500_set_extended_parms(const PROGRAMMER *pgm, int n, unsigned char *cmd) { unsigned char buf[16]; - int tries=0; + int tries = 0; int i; - retry: - +retry: + tries++; buf[0] = Cmnd_STK_SET_DEVICE_EXT; - for (i=0; i 33) { + if(buf[0] == Resp_STK_NOSYNC) { + if(tries > 33) { pmsg_error("cannot get into sync\n"); return -1; } - if (stk500_getsync(pgm) < 0) + if(stk500_getsync(pgm) < 0) return -1; goto retry; - } - else if (buf[0] != Resp_STK_INSYNC) { + } else if(buf[0] != Resp_STK_INSYNC) { pmsg_error("protocol expects sync byte 0x%02x but got 0x%02x\n", Resp_STK_INSYNC, buf[0]); return -1; } - if (stk500_recv(pgm, buf, 1) < 0) + if(stk500_recv(pgm, buf, 1) < 0) return -1; - if (buf[0] == Resp_STK_OK) { + if(buf[0] == Resp_STK_OK) { return 0; - } - else if (buf[0] == Resp_STK_NODEVICE) { + } else if(buf[0] == Resp_STK_NODEVICE) { pmsg_error("no device\n"); return -1; } @@ -329,8 +303,8 @@ static int stk500_set_extended_parms(const PROGRAMMER *pgm, int n, } /* - * Crossbow MIB510 initialization and shutdown. Use cmd = 1 to - * initialize, cmd = 0 to close. + * Crossbow MIB510 initialization and shutdown. Use cmd = 1 to initialize and + * cmd = 0 to close. */ static int mib510_isp(const PROGRAMMER *pgm, unsigned char cmd) { unsigned char buf[9]; @@ -346,112 +320,102 @@ static int mib510_isp(const PROGRAMMER *pgm, unsigned char cmd) { buf[7] = 0x13; buf[8] = cmd; - - retry: +retry: tries++; stk500_send(pgm, buf, 9); - if (stk500_recv(pgm, buf, 1) < 0) + if(stk500_recv(pgm, buf, 1) < 0) return -1; - if (buf[0] == Resp_STK_NOSYNC) { - if (tries > 33) { + if(buf[0] == Resp_STK_NOSYNC) { + if(tries > 33) { pmsg_error("cannot get into sync\n"); return -1; } - if (stk500_getsync(pgm) < 0) + if(stk500_getsync(pgm) < 0) return -1; goto retry; - } - else if (buf[0] != Resp_STK_INSYNC) { + } else if(buf[0] != Resp_STK_INSYNC) { pmsg_error("protocol expects sync byte 0x%02x but got 0x%02x\n", Resp_STK_INSYNC, buf[0]); return -1; } - if (stk500_recv(pgm, buf, 1) < 0) + if(stk500_recv(pgm, buf, 1) < 0) return -1; - if (buf[0] == Resp_STK_OK) { + if(buf[0] == Resp_STK_OK) { return 0; - } - else if (buf[0] == Resp_STK_NODEVICE) { + } else if(buf[0] == Resp_STK_NODEVICE) { pmsg_error("no device\n"); return -1; } - if (buf[0] == Resp_STK_FAILED) - { - pmsg_error("command %d failed\n", cmd); - return -1; + if(buf[0] == Resp_STK_FAILED) { + pmsg_error("command %d failed\n", cmd); + return -1; } - pmsg_error("unknown response=0x%02x\n", buf[0]); return -1; } - -/* - * initialize the AVR device and prepare it to accept commands - */ +// Initialize the AVR device and prepare it to accept commands static int stk500_initialize(const PROGRAMMER *pgm, const AVRPART *p) { unsigned char buf[32]; - AVRMEM * m; + AVRMEM *m; int tries; unsigned maj = 0, min = 0; int rc; int n_extparms; - if ((rc = stk500_getparm(pgm, Parm_STK_SW_MAJOR, &maj)) < 0 - || (rc = stk500_getparm(pgm, Parm_STK_SW_MINOR, &min)) < 0 ) { + if((rc = stk500_getparm(pgm, Parm_STK_SW_MAJOR, &maj)) < 0 || + (rc = stk500_getparm(pgm, Parm_STK_SW_MINOR, &min)) < 0) { + pmsg_error("cannot obtain SW version\n"); return rc; } // MIB510 does not need extparams - if (str_eq(pgmid, "mib510")) + if(str_eq(pgmid, "mib510")) n_extparms = 0; - else if ((maj > 1) || ((maj == 1) && (min > 10))) + else if((maj > 1) || ((maj == 1) && (min > 10))) n_extparms = 4; else n_extparms = 3; tries = 0; - retry: +retry: tries++; memset(buf, 0, sizeof(buf)); - /* - * set device programming parameters - */ + // Set device programming parameters buf[0] = Cmnd_STK_SET_DEVICE; buf[1] = p->stk500_devcode; - buf[2] = 0; /* device revision */ + buf[2] = 0; // Device revision - if ((p->flags & AVRPART_SERIALOK) && (p->flags & AVRPART_PARALLELOK)) - buf[3] = 0; /* device supports parallel and serial programming */ + if((p->flags & AVRPART_SERIALOK) && (p->flags & AVRPART_PARALLELOK)) + buf[3] = 0; // Device supports parallel and serial programming else - buf[3] = 1; /* device supports parallel only */ + buf[3] = 1; // Device supports parallel only - if (p->flags & AVRPART_PARALLELOK) { - if (p->flags & AVRPART_PSEUDOPARALLEL) { - buf[4] = 0; /* pseudo parallel interface */ + if(p->flags & AVRPART_PARALLELOK) { + if(p->flags & AVRPART_PSEUDOPARALLEL) { + buf[4] = 0; // Pseudo parallel interface n_extparms = 0; - } - else { - buf[4] = 1; /* full parallel interface */ + } else { + buf[4] = 1; // Full parallel interface } } #if 0 pmsg_notice("%s(): n_extparms = %d\n", __func__, n_extparms); #endif - - buf[5] = 1; /* polling supported - XXX need this in config file */ - buf[6] = 1; /* programming is self-timed - XXX need in config file */ + + buf[5] = 1; // Polling supported - XXX need this in config file + buf[6] = 1; // Programming is self-timed - XXX need in config file buf[7] = (m = avr_locate_lock(p))? m->size: 0; @@ -461,10 +425,10 @@ static int stk500_initialize(const PROGRAMMER *pgm, const AVRPART *p) { if((m = avr_locate_fuse_by_offset(p, fu))) buf[8] += m->size; - if ((m = avr_locate_flash(p))) { + if((m = avr_locate_flash(p))) { buf[9] = m->readback[0]; buf[10] = m->readback[1]; - if (m->paged) { + if(m->paged) { buf[13] = (m->page_size >> 8) & 0x00ff; buf[14] = m->page_size & 0x00ff; } @@ -473,7 +437,7 @@ static int stk500_initialize(const PROGRAMMER *pgm, const AVRPART *p) { buf[19] = (m->size >> 8) & 0xff; buf[20] = m->size & 0xff; } else { - buf[9] = 0xff; + buf[9] = 0xff; buf[10] = 0xff; buf[13] = 0; buf[14] = 0; @@ -483,7 +447,7 @@ static int stk500_initialize(const PROGRAMMER *pgm, const AVRPART *p) { buf[20] = 0; } - if ((m = avr_locate_eeprom(p))) { + if((m = avr_locate_eeprom(p))) { buf[11] = m->readback[0]; buf[12] = m->readback[1]; if(!buf[11] && !buf[12]) // Make default readback values 0xff for eeproms @@ -500,136 +464,144 @@ static int stk500_initialize(const PROGRAMMER *pgm, const AVRPART *p) { buf[21] = Sync_CRC_EOP; stk500_send(pgm, buf, 22); - if (stk500_recv(pgm, buf, 1) < 0) + if(stk500_recv(pgm, buf, 1) < 0) return -1; - if (buf[0] == Resp_STK_NOSYNC) { + if(buf[0] == Resp_STK_NOSYNC) { pmsg_warning("programmer not in sync, resp=0x%02x\n", buf[0]); - if (tries > 33) + if(tries > 33) return -1; - if (stk500_getsync(pgm) < 0) + if(stk500_getsync(pgm) < 0) return -1; goto retry; - } - else if (buf[0] != Resp_STK_INSYNC) { + } else if(buf[0] != Resp_STK_INSYNC) { pmsg_error("protocol expects sync byte 0x%02x but got 0x%02x\n", Resp_STK_INSYNC, buf[0]); return -1; } - if (stk500_recv(pgm, buf, 1) < 0) + if(stk500_recv(pgm, buf, 1) < 0) return -1; - if (buf[0] != Resp_STK_OK) { + if(buf[0] != Resp_STK_OK) { pmsg_error("protocol expects OK byte 0x%02x but got 0x%02x\n", Resp_STK_OK, buf[0]); return -1; } - if (n_extparms) { - if ((p->pagel == 0) || (p->bs2 == 0)) { + if(n_extparms) { + if((p->pagel == 0) || (p->bs2 == 0)) { pmsg_notice2("PAGEL and BS2 signals not defined in the configuration " "file for part %s, using dummy values\n", p->desc); - buf[2] = 0xD7; /* they look somehow possible, */ - buf[3] = 0xA0; /* don't they? ;) */ - } - else { + buf[2] = 0xD7; // They look somehow possible, don't they? ;) + buf[3] = 0xA0; + } else { buf[2] = p->pagel; buf[3] = p->bs2; } - buf[0] = n_extparms+1; + buf[0] = n_extparms + 1; - /* - * m is currently pointing to eeprom memory if the part has it - */ - if (m) + // m is currently pointing to eeprom memory if the part has it + if(m) buf[1] = m->page_size; else buf[1] = 0; - - if (n_extparms == 4) { - if (p->reset_disposition == RESET_DEDICATED) + if(n_extparms == 4) { + if(p->reset_disposition == RESET_DEDICATED) buf[4] = 0; else buf[4] = 1; } - rc = stk500_set_extended_parms(pgm, n_extparms+1, buf); - if (rc) { + rc = stk500_set_extended_parms(pgm, n_extparms + 1, buf); + if(rc) { pmsg_error("failed to initialise programmer\n"); return -1; } } - // Read or write target voltage - if (PDATA(pgm)->vtarg_get || PDATA(pgm)->vtarg_set) { + if(my.vtarg_get || my.vtarg_set) { // Read current target voltage set value unsigned int vtarg_read = 0; - if ((rc = stk500_getparm(pgm, Parm_STK_VTARGET, &vtarg_read)) < 0) { + + if((rc = stk500_getparm(pgm, Parm_STK_VTARGET, &vtarg_read)) < 0) { pmsg_error("cannot obtain V[target]\n"); return rc; } - if (PDATA(pgm)->vtarg_get) - msg_info("Target voltage value read as %.2f V\n", (vtarg_read / 10.0)); + if(my.vtarg_get) + msg_info("Target voltage value read as %.2f V\n", (vtarg_read/10.0)); // Write target voltage value else { - msg_info("Changing target voltage from %.2f V to %.2f V\n", (vtarg_read / 10.0), PDATA(pgm)->vtarg_data); - if(pgm->set_vtarget(pgm, PDATA(pgm)->vtarg_data) < 0) + msg_info("Changing target voltage from %.2f V to %.2f V\n", (vtarg_read/10.0), my.vtarg_data); + if(pgm->set_vtarget(pgm, my.vtarg_data) < 0) return -1; } } - // Read or write analog reference voltage - if (PDATA(pgm)->varef_get || PDATA(pgm)->varef_set) { + if(my.varef_get || my.varef_set) { // Read current analog reference voltage unsigned int varef_read = 0; - if ((rc = stk500_getparm(pgm, Parm_STK_VADJUST, &varef_read)) < 0) { + + if((rc = stk500_getparm(pgm, Parm_STK_VADJUST, &varef_read)) < 0) { pmsg_error("cannot obtain V[aref]\n"); return rc; } - if (PDATA(pgm)->varef_get) - msg_info("Analog reference voltage value read as %.2f V\n", (varef_read / 10.0)); + if(my.varef_get) + msg_info("Analog reference voltage value read as %.2f V\n", (varef_read/10.0)); // Write analog reference voltage else { - msg_info("Changing analog reference voltage from %.2f V to %.2f V\n", - (varef_read / 10.0), PDATA(pgm)->varef_data); - if(pgm->set_varef(pgm, 0, PDATA(pgm)->varef_data) < 0) + msg_info("Changing analog reference voltage from %.2f V to %.2f V\n", (varef_read/10.0), my.varef_data); + if(pgm->set_varef(pgm, 0, my.varef_data) < 0) return -1; } } - // Read or write clock generator frequency - if (PDATA(pgm)->fosc_get || PDATA(pgm)->fosc_set) { + if(my.fosc_get || my.fosc_set) { // Read current target voltage set value unsigned int osc_pscale = 0; unsigned int osc_cmatch = 0; - const char *unit_get = {"Hz"}; + const char *unit_get = { "Hz" }; double f_get = 0.0; - if ((rc = stk500_getparm(pgm, Parm_STK_OSC_PSCALE, &osc_pscale)) < 0 + + if((rc = stk500_getparm(pgm, Parm_STK_OSC_PSCALE, &osc_pscale)) < 0 || (rc = stk500_getparm(pgm, Parm_STK_OSC_CMATCH, &osc_cmatch) < 0)) { pmsg_error("cannot obtain fosc values\n"); return rc; } if(osc_pscale) { int prescale = 1; - f_get = PDATA(pgm)->xtal / 2; - switch (osc_pscale) { - case 2: prescale = 8; break; - case 3: prescale = 32; break; - case 4: prescale = 64; break; - case 5: prescale = 128; break; - case 6: prescale = 256; break; - case 7: prescale = 1024; break; + + f_get = my.xtal/2; + switch(osc_pscale) { + case 2: + prescale = 8; + break; + case 3: + prescale = 32; + break; + case 4: + prescale = 64; + break; + case 5: + prescale = 128; + break; + case 6: + prescale = 256; + break; + case 7: + prescale = 1024; + break; } f_get /= prescale; f_get /= (osc_cmatch + 1); f_get = f_to_kHz_MHz(f_get, &unit_get); } - if (PDATA(pgm)->fosc_get) - msg_info("Oscillator currently set to %.3f %s\n", f_get, unit_get); + if(my.fosc_get) + msg_info("Oscillator currently set to %.3f %s\n", f_get, unit_get); // Write target voltage value else { const char *unit_set; - double f_set = f_to_kHz_MHz(PDATA(pgm)->fosc_data, &unit_set); + double f_set = f_to_kHz_MHz(my.fosc_data, &unit_set); + msg_info("Changing oscillator frequency from %.3f %s to %.3f %s\n", f_get, unit_get, f_set, unit_set); - if(pgm->set_fosc(pgm, PDATA(pgm)->fosc_data) < 0) + if(pgm->set_fosc(pgm, my.fosc_data) < 0) return -1; } } @@ -642,60 +614,62 @@ static int stk500_parseextparms(const PROGRAMMER *pgm, const LISTID extparms) { int rv = 0; bool help = false; - for (LNODEID ln = lfirst(extparms); ln; ln = lnext(ln)) { + for(LNODEID ln = lfirst(extparms); ln; ln = lnext(ln)) { const char *extended_param = ldata(ln); - if (sscanf(extended_param, "attempts=%i", &attempts) == 1) { - PDATA(pgm)->retry_attempts = attempts; + if(sscanf(extended_param, "attempts=%i", &attempts) == 1) { + my.retry_attempts = attempts; pmsg_info("setting number of retry attempts to %d\n", attempts); continue; } - if (str_starts(extended_param, "vtarg")) { - if ((pgm->extra_features & HAS_VTARG_ADJ) && (str_starts(extended_param, "vtarg="))) { + if(str_starts(extended_param, "vtarg")) { + if((pgm->extra_features & HAS_VTARG_ADJ) && (str_starts(extended_param, "vtarg="))) { // Set target voltage - double vtarg_set_val = -1; // default = invlid value + double vtarg_set_val = -1; // Default = invlid value int sscanf_success = sscanf(extended_param, "vtarg=%lf", &vtarg_set_val); - PDATA(pgm)->vtarg_data = (double)((int)(vtarg_set_val * 100 + .5)) / 100; - if (sscanf_success < 1 || vtarg_set_val < 0) { + + my.vtarg_data = (double) ((int) (vtarg_set_val*100 + .5))/100; + if(sscanf_success < 1 || vtarg_set_val < 0) { pmsg_error("invalid target voltage in -x %s\n", extended_param); rv = -1; break; } - PDATA(pgm)->vtarg_set = true; + my.vtarg_set = true; continue; - } else if ((pgm->extra_features & HAS_VTARG_READ) && str_eq(extended_param, "vtarg")) { + } else if((pgm->extra_features & HAS_VTARG_READ) && str_eq(extended_param, "vtarg")) { // Get target voltage - PDATA(pgm)->vtarg_get = true; + my.vtarg_get = true; continue; } } - else if (str_starts(extended_param, "varef")) { - if (pgm->extra_features & HAS_VAREF_ADJ) { + else if(str_starts(extended_param, "varef")) { + if(pgm->extra_features & HAS_VAREF_ADJ) { int sscanf_success = 0; double varef_set_val = -1; + // Get new analog reference voltage for channel 0 - if (str_starts(extended_param, "varef=")) { + if(str_starts(extended_param, "varef=")) { sscanf_success = sscanf(extended_param, "varef=%lf", &varef_set_val); - PDATA(pgm)->varef_set = true; + my.varef_set = true; } // Get new analog reference voltage for channel 0 else if(str_starts(extended_param, "varef0=")) { sscanf_success = sscanf(extended_param, "varef0=%lf", &varef_set_val); - PDATA(pgm)->varef_set = true; + my.varef_set = true; } // Get current analog reference voltage for channel 0 else if(str_eq(extended_param, "varef") || str_eq(extended_param, "varef0")) { - PDATA(pgm)->varef_get = true; + my.varef_get = true; continue; } // Set analog reference voltage - if (PDATA(pgm)->varef_set) { - PDATA(pgm)->varef_data = (double)((int)(varef_set_val * 100 + .5)) / 100; - if (sscanf_success < 1 || varef_set_val < 0) { + if(my.varef_set) { + my.varef_data = (double) ((int) (varef_set_val*100 + .5))/100; + if(sscanf_success < 1 || varef_set_val < 0) { pmsg_error("invalid value in -x %s\n", extended_param); - PDATA(pgm)->varef_set = false; + my.varef_set = false; rv = -1; break; } @@ -704,100 +678,104 @@ static int stk500_parseextparms(const PROGRAMMER *pgm, const LISTID extparms) { } } - else if (str_starts(extended_param, "fosc")) { - if (pgm->extra_features & HAS_FOSC_ADJ) { + else if(str_starts(extended_param, "fosc")) { + if(pgm->extra_features & HAS_FOSC_ADJ) { // Set clock generator frequency - if (str_starts(extended_param, "fosc=")) { - char fosc_str[16] = {0}; - // allow spaces in fosc_str + if(str_starts(extended_param, "fosc=")) { + char fosc_str[16] = { 0 }; + // Allow spaces in fosc_str int sscanf_success = sscanf(extended_param, "fosc=%15[0-9.eE MmKkHhZzof]", fosc_str); - if (sscanf_success < 1) { + + if(sscanf_success < 1) { pmsg_error("invalid value in -x %s\n", extended_param); rv = -1; break; } char *endp; double v = strtod(fosc_str, &endp); - if (endp == fosc_str){ // no number - while ( *endp == ' ' ) // remove leading spaces + + if(endp == fosc_str) { // No number + while(*endp == ' ') // Remove leading spaces ++endp; - if (!str_eq(endp, "off")) { + if(!str_eq(endp, "off")) { pmsg_error("invalid -x fosc=%s value\n", fosc_str); rv = -1; break; } - PDATA(pgm)->fosc_data = 0.0; + my.fosc_data = 0.0; } - while ( *endp == ' ' ) // remove leading spaces before unit + while(*endp == ' ') // Remove leading spaces before unit ++endp; - if (*endp == 'm' || *endp == 'M') - PDATA(pgm)->fosc_data = v * 1e6; - else if (*endp == 'k' || *endp == 'K') - PDATA(pgm)->fosc_data = v * 1e3; - else if (*endp == 0 || *endp == 'h' || *endp == 'H') - PDATA(pgm)->fosc_data = v; - PDATA(pgm)->fosc_set = true; + if(*endp == 'm' || *endp == 'M') + my.fosc_data = v*1e6; + else if(*endp == 'k' || *endp == 'K') + my.fosc_data = v*1e3; + else if(*endp == 0 || *endp == 'h' || *endp == 'H') + my.fosc_data = v; + my.fosc_set = true; continue; } // Get clock generator frequency else if(str_eq(extended_param, "fosc")) { - PDATA(pgm)->fosc_get = true; - continue; + my.fosc_get = true; + continue; } } } - else if (str_starts(extended_param, "xtal")) { + else if(str_starts(extended_param, "xtal")) { // Set clock generator frequency - if (str_starts(extended_param, "xtal=")) { - char xtal_str[16] = {0}; + if(str_starts(extended_param, "xtal=")) { + char xtal_str[16] = { 0 }; int sscanf_success = sscanf(extended_param, "xtal=%15[0-9.eE MmKkHhZz]", xtal_str); - if (sscanf_success < 1) { + + if(sscanf_success < 1) { pmsg_error("invalid value in -x %s\n", extended_param); rv = -1; break; } char *endp; double v = strtod(xtal_str, &endp); - if (endp == xtal_str){ + + if(endp == xtal_str) { pmsg_error("invalid -x xtal=%s value\n", xtal_str); rv = -1; break; } - while ( *endp == ' ' ) // remove leading spaces before unit + while(*endp == ' ') // Remove leading spaces before unit ++endp; - if (*endp == 'm' || *endp == 'M') // fits also e.g. "nnnnMHz" - PDATA(pgm)->xtal = v * 1e6; - else if (*endp == 'k' || *endp == 'K') - PDATA(pgm)->xtal = v * 1e3; - else if (*endp == 0 || *endp == 'h' || *endp == 'H') // "nnnn" or "nnnnHz" - PDATA(pgm)->xtal = v; + if(*endp == 'm' || *endp == 'M') // Fits also e.g. "nnnnMHz" + my.xtal = v*1e6; + else if(*endp == 'k' || *endp == 'K') + my.xtal = v*1e3; + else if(*endp == 0 || *endp == 'h' || *endp == 'H') // "nnnn" or "nnnnHz" + my.xtal = v; continue; } } - else if (str_eq(extended_param, "help")) { + else if(str_eq(extended_param, "help")) { help = true; - rv = LIBAVRDUDE_EXIT; + rv = LIBAVRDUDE_EXIT; } - if (!help) { + if(!help) { pmsg_error("invalid extended parameter -x %s\n", extended_param); rv = -1; } msg_error("%s -c %s extended options:\n", progname, pgmid); msg_error(" -x attempts= Specify the number of connection retry attempts\n"); - if (pgm->extra_features & HAS_VTARG_READ) { + if(pgm->extra_features & HAS_VTARG_READ) { msg_error(" -x vtarg Read target supply voltage\n"); } - if (pgm->extra_features & HAS_VTARG_ADJ) { + if(pgm->extra_features & HAS_VTARG_ADJ) { msg_error(" -x vtarg= Set target supply voltage to V\n"); } - if (pgm->extra_features & HAS_VAREF_ADJ) { + if(pgm->extra_features & HAS_VAREF_ADJ) { msg_error(" -x varef Read analog reference voltage\n"); msg_error(" -x varef= Set analog reference voltage to V\n"); } - if (pgm->extra_features & HAS_FOSC_ADJ) { + if(pgm->extra_features & HAS_FOSC_ADJ) { msg_error(" -x fosc Read oscillator clock frequency\n"); msg_error(" -x fosc=[unit] Set oscillator clock frequency to Hz (or kHz/MHz)\n"); msg_error(" -x fosc=off Switch the oscillator clock off\n"); @@ -812,38 +790,36 @@ static int stk500_parseextparms(const PROGRAMMER *pgm, const LISTID extparms) { static void stk500_disable(const PROGRAMMER *pgm) { unsigned char buf[16]; - int tries=0; + int tries = 0; + +retry: - retry: - tries++; buf[0] = Cmnd_STK_LEAVE_PROGMODE; buf[1] = Sync_CRC_EOP; stk500_send(pgm, buf, 2); - if (stk500_recv(pgm, buf, 1) < 0) + if(stk500_recv(pgm, buf, 1) < 0) return; - if (buf[0] == Resp_STK_NOSYNC) { - if (tries > 33) { + if(buf[0] == Resp_STK_NOSYNC) { + if(tries > 33) { pmsg_error("cannot get into sync\n"); return; } - if (stk500_getsync(pgm) < 0) + if(stk500_getsync(pgm) < 0) return; goto retry; - } - else if (buf[0] != Resp_STK_INSYNC) { + } else if(buf[0] != Resp_STK_INSYNC) { pmsg_error("protocol expects sync byte 0x%02x but got 0x%02x\n", Resp_STK_INSYNC, buf[0]); return; } - if (stk500_recv(pgm, buf, 1) < 0) + if(stk500_recv(pgm, buf, 1) < 0) return; - if (buf[0] == Resp_STK_OK) { + if(buf[0] == Resp_STK_OK) { return; - } - else if (buf[0] == Resp_STK_NODEVICE) { + } else if(buf[0] == Resp_STK_NODEVICE) { pmsg_error("no device\n"); return; } @@ -855,54 +831,51 @@ static void stk500_disable(const PROGRAMMER *pgm) { static void stk500_enable(PROGRAMMER *pgm, const AVRPART *p) { AVRMEM *mem; - if(pgm->prog_modes & PM_SPM) // For bootloaders (eg, arduino) + + if(is_spm(pgm)) // For bootloaders (eg, arduino) if((mem = avr_locate_eeprom(p))) if(mem->page_size == 1) // Change EEPROM page size from 1 to 16 to force paged r/w mem->page_size = 16; return; } - static int stk500_open(PROGRAMMER *pgm, const char *port) { union pinfo pinfo; + pgm->port = port; pinfo.serialinfo.baud = pgm->baudrate? pgm->baudrate: 115200; pinfo.serialinfo.cflags = SERIAL_8N1; - if (serial_open(port, pinfo, &pgm->fd)==-1) { + if(serial_open(port, pinfo, &pgm->fd) == -1) { return -1; } - /* - * drain any extraneous input - */ + // Drain any extraneous input stk500_drain(pgm, 0); // MIB510 init - if (str_eq(pgmid, "mib510") && mib510_isp(pgm, 1) != 0) + if(str_eq(pgmid, "mib510") && mib510_isp(pgm, 1) != 0) return -1; - if (stk500_getsync(pgm) < 0) + if(stk500_getsync(pgm) < 0) return -1; - if (pgm->bitclock != 0.0) { - if (pgm->set_sck_period(pgm, pgm->bitclock) != 0) + if(pgm->bitclock != 0.0) { + if(pgm->set_sck_period(pgm, pgm->bitclock) != 0) return -1; } return 0; } - static void stk500_close(PROGRAMMER *pgm) { // MIB510 close - if (str_eq(pgmid, "mib510")) - (void)mib510_isp(pgm, 0); + if(str_eq(pgmid, "mib510")) + (void) mib510_isp(pgm, 0); serial_close(&pgm->fd); pgm->fd.ifd = -1; } - // Address is byte address; a_div == 2: send word address; a_div == 1: send byte address static int stk500_loadaddr(const PROGRAMMER *pgm, const AVRMEM *mem, unsigned int addr, int a_div) { unsigned char buf[16]; @@ -912,46 +885,49 @@ static int stk500_loadaddr(const PROGRAMMER *pgm, const AVRMEM *mem, unsigned in addr /= a_div; tries = 0; - retry: +retry: tries++; // Support large flash by sending the correct extended address byte when needed - if(pgm->prog_modes & PM_SPM) { // Bootloaders, eg, optiboot, optiboot_dx, optiboot_x - if(mem->size/a_div > 64*1024) { // Extended addressing needed + if(is_spm(pgm)) { // Bootloaders, eg, optiboot, optiboot_dx, optiboot_x + if(mem->size/a_div > 64*1024) { // Extended addressing needed ext_byte = (addr >> 16) & 0xff; - if(ext_byte != PDATA(pgm)->ext_addr_byte) { // First addr load or a different 64k section + if(ext_byte != my.ext_addr_byte) { // First addr load or a different 64k section buf[0] = 0x4d; // Protocol bytes that bootloaders expect buf[1] = 0x00; buf[2] = ext_byte; buf[3] = 0x00; if(stk500_cmd(pgm, buf, buf) == 0) - PDATA(pgm)->ext_addr_byte = ext_byte; + my.ext_addr_byte = ext_byte; } /* - * Ensure next paged r/w will load ext addr again if page sits just below a 64k boundary + * Ensure next paged r/w will load ext addr again if page sits just below + * a 64k boundary * - * Some bootloaders increment their copy of ext_addr_byte in that situation, eg, when they - * use elpm rx,Z+ to read a byte from flash or spm Z+ to write to flash whilst they keep - * ext_addr_byte in RAMPZ, which in turn gets incremented by Z+ at 64k page boundaries. So, - * if an upload with automated verify finishes just below 64k, AVRDUDE still holds - * ext_addr_byte at the current 64k segment whilst its copy in the bootloader has been - * auto-incremented. Verifying the code from start exposes the discrepancy. + * Some bootloaders increment their copy of ext_addr_byte in that + * situation, eg, when they use elpm rx, Z+ to read a byte from flash or + * spm Z+ to write to flash whilst they keep ext_addr_byte in RAMPZ, + * which in turn gets incremented by Z+ at 64k page boundaries. So, if an + * upload with automated verify finishes just below 64k, AVRDUDE still + * holds ext_addr_byte at the current 64k segment whilst its copy in the + * bootloader has been auto-incremented. Verifying the code from start + * exposes the discrepancy. */ - if((addr & 0xffff0000) != ((addr+mem->page_size/a_div) & 0xffff0000)) - PDATA(pgm)->ext_addr_byte = 0xff; + if((addr & 0xffff0000) != ((addr + mem->page_size/a_div) & 0xffff0000)) + my.ext_addr_byte = 0xff; } } else { // Programmer *not* for bootloaders? Original stk500v1 protocol! OPCODE *lext = mem->op[AVR_OP_LOAD_EXT_ADDR]; if(lext) { ext_byte = (addr >> 16) & 0xff; - if(ext_byte != PDATA(pgm)->ext_addr_byte) { // First addr load or a different 64k section + if(ext_byte != my.ext_addr_byte) { // First addr load or a different 64k section memset(buf, 0, 4); // Part's load_ext_addr command is typically 4d 00 ext_addr 00 avr_set_bits(lext, buf); avr_set_addr(lext, buf, addr); if(stk500_cmd(pgm, buf, buf) == 0) - PDATA(pgm)->ext_addr_byte = ext_byte; + my.ext_addr_byte = ext_byte; } } } @@ -963,25 +939,24 @@ static int stk500_loadaddr(const PROGRAMMER *pgm, const AVRMEM *mem, unsigned in stk500_send(pgm, buf, 4); - if (stk500_recv(pgm, buf, 1) < 0) + if(stk500_recv(pgm, buf, 1) < 0) return -1; - if (buf[0] == Resp_STK_NOSYNC) { - if (tries > 33) { + if(buf[0] == Resp_STK_NOSYNC) { + if(tries > 33) { pmsg_error("cannot get into sync\n"); return -1; } - if (stk500_getsync(pgm) < 0) + if(stk500_getsync(pgm) < 0) return -1; goto retry; - } - else if (buf[0] != Resp_STK_INSYNC) { + } else if(buf[0] != Resp_STK_INSYNC) { pmsg_error("protocol expects sync byte 0x%02x but got 0x%02x\n", Resp_STK_INSYNC, buf[0]); return -1; } - if (stk500_recv(pgm, buf, 1) < 0) + if(stk500_recv(pgm, buf, 1) < 0) return -1; - if (buf[0] == Resp_STK_OK) + if(buf[0] == Resp_STK_OK) return 0; pmsg_error("protocol expects OK byte 0x%02x but got 0x%02x\n", Resp_STK_OK, buf[0]); @@ -989,11 +964,10 @@ static int stk500_loadaddr(const PROGRAMMER *pgm, const AVRMEM *mem, unsigned in return -1; } - static int set_memchr_a_div(const PROGRAMMER *pgm, const AVRPART *p, const AVRMEM *m, int *memchrp, int *a_divp) { if(mem_is_in_flash(m)) { *memchrp = 'F'; - if(!(pgm->prog_modes & PM_SPM)) // Programmer *not* for bootloaders: original stk500v1 protocol + if(!is_spm(pgm)) // Programmer *not* for bootloaders: original stk500v1 protocol *a_divp = m->op[AVR_OP_LOADPAGE_LO] || m->op[AVR_OP_READ_LO]? 2: 1; else if(!(p->prog_modes & (PM_UPDI | PM_PDI | PM_aWire))) *a_divp = 2; // Bootloader where part is a "classic" part (eg, optiboot) @@ -1005,20 +979,17 @@ static int set_memchr_a_div(const PROGRAMMER *pgm, const AVRPART *p, const AVRME if(mem_is_eeprom(m)) { *memchrp = 'E'; // Word addr for bootloaders or Arduino as ISP if part is a classic part; byte addr otherwise - *a_divp = ((pgm->prog_modes & PM_SPM) || str_caseeq(pgmid, "arduino_as_isp")) \ - && (p->prog_modes & PM_Classic)? 2: 1; + *a_divp = (is_spm(pgm) || str_caseeq(pgmid, "arduino_as_isp")) + && is_classic(p)? 2: 1; return 0; } return -1; } - static int stk500_paged_write(const PROGRAMMER *pgm, const AVRPART *p, const AVRMEM *m, - unsigned int page_size, - unsigned int addr, unsigned int n_bytes) -{ - unsigned char* buf = alloca(page_size + 16); + unsigned int page_size, unsigned int addr, unsigned int n_bytes) { + unsigned char *buf = alloca(page_size + 16); int memchr; int a_div; int block_size; @@ -1030,21 +1001,17 @@ static int stk500_paged_write(const PROGRAMMER *pgm, const AVRPART *p, const AVR return -2; n = addr + n_bytes; + #if 0 - msg_debug( - "n_bytes = %d\n" - "n = %u\n" - "a_div = %d\n" - "page_size = %d\n", - n_bytes, n, a_div, page_size); + msg_debug("n_bytes = %d\n" "n = %u\n" "a_div = %d\n" "page_size = %d\n", n_bytes, n, a_div, page_size); #endif - for (; addr < n; addr += block_size) { + for(; addr < n; addr += block_size) { // MIB510 uses fixed blocks size of 256 bytes - if (str_eq(pgmid, "mib510")) { + if(str_eq(pgmid, "mib510")) { block_size = 256; } else { - if (n - addr < page_size) + if(n - addr < page_size) block_size = n - addr; else block_size = page_size; @@ -1055,7 +1022,7 @@ static int stk500_paged_write(const PROGRAMMER *pgm, const AVRPART *p, const AVR stk500_loadaddr(pgm, m, addr, a_div); /* build command block and avoid multiple send commands as it leads to a crash - of the silabs usb serial driver on mac os x */ + of the silabs usb serial driver on mac os x */ i = 0; buf[i++] = Cmnd_STK_PROG_PAGE; buf[i++] = (block_size >> 8) & 0xff; @@ -1064,29 +1031,28 @@ static int stk500_paged_write(const PROGRAMMER *pgm, const AVRPART *p, const AVR memcpy(&buf[i], &m->buf[addr], block_size); i += block_size; buf[i++] = Sync_CRC_EOP; - stk500_send( pgm, buf, i); + stk500_send(pgm, buf, i); - if (stk500_recv(pgm, buf, 1) < 0) + if(stk500_recv(pgm, buf, 1) < 0) return -1; - if (buf[0] == Resp_STK_NOSYNC) { - if (tries > 33) { + if(buf[0] == Resp_STK_NOSYNC) { + if(tries > 33) { msg_error("\n"); pmsg_error("cannot get into sync\n"); return -3; } - if (stk500_getsync(pgm) < 0) + if(stk500_getsync(pgm) < 0) return -1; goto retry; - } - else if (buf[0] != Resp_STK_INSYNC) { + } else if(buf[0] != Resp_STK_INSYNC) { msg_error("\n"); pmsg_error("protocol expects sync byte 0x%02x but got 0x%02x\n", Resp_STK_INSYNC, buf[0]); return -4; } - if (stk500_recv(pgm, buf, 1) < 0) + if(stk500_recv(pgm, buf, 1) < 0) return -1; - if (buf[0] != Resp_STK_OK) { + if(buf[0] != Resp_STK_OK) { msg_error("\n"); pmsg_error("protocol expects OK byte 0x%02x but got 0x%02x\n", Resp_STK_OK, buf[0]); return -5; @@ -1097,9 +1063,7 @@ static int stk500_paged_write(const PROGRAMMER *pgm, const AVRPART *p, const AVR } static int stk500_paged_load(const PROGRAMMER *pgm, const AVRPART *p, const AVRMEM *m, - unsigned int page_size, - unsigned int addr, unsigned int n_bytes) -{ + unsigned int page_size, unsigned int addr, unsigned int n_bytes) { unsigned char buf[16]; int memchr; int a_div; @@ -1111,12 +1075,12 @@ static int stk500_paged_load(const PROGRAMMER *pgm, const AVRPART *p, const AVRM return -2; n = addr + n_bytes; - for (; addr < n; addr += block_size) { + for(; addr < n; addr += block_size) { // MIB510 uses fixed blocks size of 256 bytes if(str_eq(pgmid, "mib510")) { block_size = 256; } else { - if (n - addr < page_size) + if(n - addr < page_size) block_size = n - addr; else block_size = page_size; @@ -1133,39 +1097,37 @@ static int stk500_paged_load(const PROGRAMMER *pgm, const AVRPART *p, const AVRM buf[4] = Sync_CRC_EOP; stk500_send(pgm, buf, 5); - if (stk500_recv(pgm, buf, 1) < 0) + if(stk500_recv(pgm, buf, 1) < 0) return -1; - if (buf[0] == Resp_STK_NOSYNC) { - if (tries > 33) { + if(buf[0] == Resp_STK_NOSYNC) { + if(tries > 33) { msg_error("\n"); pmsg_error("cannot get into sync\n"); return -3; } - if (stk500_getsync(pgm) < 0) + if(stk500_getsync(pgm) < 0) return -1; goto retry; - } - else if (buf[0] != Resp_STK_INSYNC) { + } else if(buf[0] != Resp_STK_INSYNC) { msg_error("\n"); pmsg_error("protocol expects sync byte 0x%02x but got 0x%02x\n", Resp_STK_INSYNC, buf[0]); return -4; } - if (stk500_recv(pgm, &m->buf[addr], block_size) < 0) + if(stk500_recv(pgm, &m->buf[addr], block_size) < 0) return -1; - if (stk500_recv(pgm, buf, 1) < 0) + if(stk500_recv(pgm, buf, 1) < 0) return -1; if(str_eq(pgmid, "mib510")) { - if (buf[0] != Resp_STK_INSYNC) { + if(buf[0] != Resp_STK_INSYNC) { msg_error("\n"); pmsg_error("protocol expects sync byte 0x%02x but got 0x%02x\n", Resp_STK_INSYNC, buf[0]); return -5; } - } - else { - if (buf[0] != Resp_STK_OK) { + } else { + if(buf[0] != Resp_STK_OK) { msg_error("\n"); pmsg_error("protocol expects OK byte 0x%02x but got 0x%02x\n", Resp_STK_OK, buf[0]); return -5; @@ -1176,20 +1138,19 @@ static int stk500_paged_load(const PROGRAMMER *pgm, const AVRPART *p, const AVRM return n_bytes; } - static int stk500_set_vtarget(const PROGRAMMER *pgm, double v) { unsigned uaref = 0; - unsigned utarg = (unsigned)((v + 0.049) * 10); + unsigned utarg = (unsigned) ((v + 0.049)*10); int rc = 0; - if ((rc = stk500_getparm(pgm, Parm_STK_VADJUST, &uaref)) != 0) { + if((rc = stk500_getparm(pgm, Parm_STK_VADJUST, &uaref)) != 0) { pmsg_error("cannot obtain V[aref]\n"); return rc; } - if (uaref > utarg) { - pmsg_warning("reducing V[aref] from %.1f to %.1f\n", uaref / 10.0, v); - if ((rc = stk500_setparm(pgm, Parm_STK_VADJUST, utarg)) != 0) { + if(uaref > utarg) { + pmsg_warning("reducing V[aref] from %.1f to %.1f\n", uaref/10.0, v); + if((rc = stk500_setparm(pgm, Parm_STK_VADJUST, utarg)) != 0) { pmsg_error("cannot set V[aref]\n"); return rc; } @@ -1197,62 +1158,55 @@ static int stk500_set_vtarget(const PROGRAMMER *pgm, double v) { return stk500_setparm(pgm, Parm_STK_VTARGET, utarg); } - static int stk500_get_vtarget(const PROGRAMMER *pgm, double *v) { unsigned utarg = 0; int rv; - if ((rv = stk500_getparm(pgm, Parm_STK_VTARGET, &utarg)) != 0) { + if((rv = stk500_getparm(pgm, Parm_STK_VTARGET, &utarg)) != 0) { pmsg_error("cannot obtain V[target]\n"); return rv; } - *v = utarg / 10.0; + *v = utarg/10.0; return 0; } - -static int stk500_set_varef(const PROGRAMMER *pgm, unsigned int chan /* unused */, - double v) -{ +static int stk500_set_varef(const PROGRAMMER *pgm, unsigned int chan, double v) { unsigned utarg = 0; - unsigned uaref = (unsigned)((v + 0.049) * 10); + unsigned uaref = (unsigned) ((v + 0.049)*10); int rc = 0; - if ((rc = stk500_getparm(pgm, Parm_STK_VTARGET, &utarg)) != 0) { + if((rc = stk500_getparm(pgm, Parm_STK_VTARGET, &utarg)) != 0) { pmsg_error("cannot obtain V[target]\n"); return rc; } - if (uaref > utarg) { - pmsg_error("V[aref] must not be greater than " - "V[target] = %.1f\n", utarg/10.0); + if(uaref > utarg) { + pmsg_error("V[aref] must not be greater than " "V[target] = %.1f\n", utarg/10.0); return -1; } - if ((rc = stk500_setparm(pgm, Parm_STK_VADJUST, uaref)) < 0) + if((rc = stk500_setparm(pgm, Parm_STK_VADJUST, uaref)) < 0) pmsg_error("cannot set V[aref]\n"); return rc; } - -static int stk500_get_varef(const PROGRAMMER *pgm, unsigned int chan /* unused */, - double *v) { +static int stk500_get_varef(const PROGRAMMER *pgm, unsigned int chan, double *v) { unsigned uaref = 0; int rv; - if ((rv = stk500_getparm(pgm, Parm_STK_VADJUST, &uaref)) != 0) { + if((rv = stk500_getparm(pgm, Parm_STK_VADJUST, &uaref)) != 0) { pmsg_error("cannot obtain V[aref]\n"); return rv; } - *v = uaref / 10.0; + *v = uaref/10.0; return 0; } - static int stk500_set_fosc(const PROGRAMMER *pgm, double v) { unsigned prescale, cmatch, fosc; + static const unsigned ps[] = { 1, 8, 32, 64, 128, 256, 1024 }; @@ -1260,43 +1214,44 @@ static int stk500_set_fosc(const PROGRAMMER *pgm, double v) { int rc = 0; prescale = cmatch = 0; - if (v > 0.0) { - if (v > PDATA(pgm)->xtal / 2.0) { + if(v > 0.0) { + if(v > my.xtal/2.0) { const char *unit; - if (v >= 1e6) { + + if(v >= 1e6) { v /= 1e6; unit = "MHz"; - } else if (v >= 1e3) { + } else if(v >= 1e3) { v /= 1e3; unit = "kHz"; } else unit = "Hz"; - pmsg_warning("f = %.3f %s too high, using %.3f MHz\n", v, unit, PDATA(pgm)->xtal/2e6); - fosc = PDATA(pgm)->xtal / 2.0; + pmsg_warning("f = %.3f %s too high, using %.3f MHz\n", v, unit, my.xtal/2e6); + fosc = my.xtal/2.0; } else fosc = (unsigned) v; - - for (idx = 0; idx < sizeof(ps) / sizeof(ps[0]); idx++) { - if (fosc >= PDATA(pgm)->xtal / (256 * ps[idx] * 2)) { - /* this prescaler value can handle our frequency */ + + for(idx = 0; idx < sizeof(ps)/sizeof(ps[0]); idx++) { + if(fosc >= my.xtal/(256*ps[idx] * 2)) { + // This prescaler value can handle our frequency prescale = idx + 1; - cmatch = (unsigned)(PDATA(pgm)->xtal / (2 * fosc * ps[idx])) - 1; + cmatch = (unsigned) (my.xtal/(2*fosc*ps[idx])) - 1; break; } } - if (idx == sizeof(ps) / sizeof(ps[0])) { - pmsg_warning("f = %u Hz too low, using %u Hz\n", fosc, PDATA(pgm)->xtal / (256 * 1024 * 2)); + if(idx == sizeof(ps)/sizeof(ps[0])) { + pmsg_warning("f = %u Hz too low, using %u Hz\n", fosc, my.xtal/(256*1024*2)); prescale = idx; cmatch = 255; } } - - if ((rc = stk500_setparm(pgm, Parm_STK_OSC_PSCALE, prescale)) != 0 ) { + + if((rc = stk500_setparm(pgm, Parm_STK_OSC_PSCALE, prescale)) != 0) { pmsg_error("cannot set Parm_STK_OSC_PSCALE\n"); return rc; } - if ((rc = stk500_setparm(pgm, Parm_STK_OSC_CMATCH, cmatch)) != 0) { + if((rc = stk500_setparm(pgm, Parm_STK_OSC_CMATCH, cmatch)) != 0) { pmsg_error("cannot set Parm_STK_OSC_CMATCH\n"); return rc; } @@ -1304,83 +1259,79 @@ static int stk500_set_fosc(const PROGRAMMER *pgm, double v) { return 0; } - static int stk500_get_fosc(const PROGRAMMER *pgm, double *v) { - unsigned prescale=0, cmatch=0; + unsigned prescale = 0, cmatch = 0; + static const unsigned ps[] = { 1, 8, 32, 64, 128, 256, 1024 }; int rc; - if ((rc = stk500_getparm(pgm, Parm_STK_OSC_PSCALE, &prescale)) != 0) { + if((rc = stk500_getparm(pgm, Parm_STK_OSC_PSCALE, &prescale)) != 0) { pmsg_error("cannot get Parm_STK_OSC_PSCALE\n"); return rc; -} + } - if ((rc = stk500_getparm(pgm, Parm_STK_OSC_CMATCH, &cmatch)) != 0) { + if((rc = stk500_getparm(pgm, Parm_STK_OSC_CMATCH, &cmatch)) != 0) { pmsg_error("cannot get Parm_STK_OSC_CMATCH\n"); return rc; } - *v = !prescale ? 0 : PDATA(pgm)->xtal / ((cmatch + 1) * 2 * ps[prescale - 1]); + *v = !prescale? 0: my.xtal/((cmatch + 1)*2*ps[prescale - 1]); return 0; } - -/* This code assumes that each count of the SCK duration parameter - represents 8/f, where f is the clock frequency of the STK500 controller - processors (not the target). This number comes from Atmel - application note AVR061. It appears that the STK500 bit bangs SCK. - For small duration values, the actual SCK width is larger than - expected. As the duration value increases, the SCK width error - diminishes. */ +/* + * This code assumes that each count of the SCK duration parameter represents + * 8/f, where f is the clock frequency of the STK500 controller processors (not + * the target). This number comes from Atmel application note AVR061. It + * appears that the STK500 bit bangs SCK. For small duration values, the actual + * SCK width is larger than expected. As the duration value increases, the SCK + * width error diminishes. + */ static int stk500_set_sck_period(const PROGRAMMER *pgm, double v) { int dur; double min, max; int rv = 0; - min = 8.0 / PDATA(pgm)->xtal; - max = 255 * min; - dur = v / min + 0.5; - - if (v < min) { - dur = 1; - pmsg_warning("p = %.1f us too small, using %.1f us\n", - v/1e-6, dur*min/1e-6); - } else if (v > max) { - dur = 255; - pmsg_warning("p = %.1f us too large, using %.1f us\n", - v/1e-6, dur*min/1e-6); + min = 8.0/my.xtal; + max = 255*min; + dur = v/min + 0.5; + + if(v < min) { + dur = 1; + pmsg_warning("p = %.1f us too small, using %.1f us\n", v/1e-6, dur*min/1e-6); + } else if(v > max) { + dur = 255; + pmsg_warning("p = %.1f us too large, using %.1f us\n", v/1e-6, dur*min/1e-6); } - if ((rv = stk500_setparm(pgm, Parm_STK_SCK_DURATION, dur)) < 0) { + if((rv = stk500_setparm(pgm, Parm_STK_SCK_DURATION, dur)) < 0) { pmsg_error("cannot set Parm_STK_SCK_DURATION\n"); return rv; } return 0; } - static int stk500_get_sck_period(const PROGRAMMER *pgm, double *v) { unsigned dur; int rv = 0; - if ((rv = stk500_getparm(pgm, Parm_STK_SCK_DURATION, &dur)) < 0) { + if((rv = stk500_getparm(pgm, Parm_STK_SCK_DURATION, &dur)) < 0) { pmsg_error("cannot obtain Parm_STK_SCK_DURATION\n"); return rv; } - *v = dur * 8.0 / PDATA(pgm)->xtal; + *v = dur*8.0/my.xtal; return 0; } - static int stk500_getparm(const PROGRAMMER *pgm, unsigned parm, unsigned *value) { unsigned char buf[16]; unsigned v; int tries = 0; - retry: +retry: tries++; buf[0] = Cmnd_STK_GET_PARAMETER; buf[1] = parm; @@ -1388,36 +1339,34 @@ static int stk500_getparm(const PROGRAMMER *pgm, unsigned parm, unsigned *value) stk500_send(pgm, buf, 3); - if (stk500_recv(pgm, buf, 1) < 0) + if(stk500_recv(pgm, buf, 1) < 0) return -1; - if (buf[0] == Resp_STK_NOSYNC) { - if (tries > 33) { + if(buf[0] == Resp_STK_NOSYNC) { + if(tries > 33) { msg_error("\n"); pmsg_error("cannot get into sync\n"); return -1; } - if (stk500_getsync(pgm) < 0) + if(stk500_getsync(pgm) < 0) return -1; goto retry; - } - else if (buf[0] != Resp_STK_INSYNC) { + } else if(buf[0] != Resp_STK_INSYNC) { msg_error("\n"); pmsg_error("protocol expects sync byte 0x%02x but got 0x%02x\n", Resp_STK_INSYNC, buf[0]); return -2; } - if (stk500_recv(pgm, buf, 1) < 0) + if(stk500_recv(pgm, buf, 1) < 0) return -1; v = buf[0]; - if (stk500_recv(pgm, buf, 1) < 0) + if(stk500_recv(pgm, buf, 1) < 0) return -1; - if (buf[0] == Resp_STK_FAILED) { + if(buf[0] == Resp_STK_FAILED) { msg_error("\n"); pmsg_error("parameter 0x%02x failed\n", v); return -3; - } - else if (buf[0] != Resp_STK_OK) { + } else if(buf[0] != Resp_STK_OK) { msg_error("\n"); pmsg_error("protocol expects OK byte 0x%02x but got 0x%02x\n", Resp_STK_OK, buf[0]); return -3; @@ -1428,12 +1377,11 @@ static int stk500_getparm(const PROGRAMMER *pgm, unsigned parm, unsigned *value) return 0; } - static int stk500_setparm(const PROGRAMMER *pgm, unsigned parm, unsigned value) { unsigned char buf[16]; int tries = 0; - retry: +retry: tries++; buf[0] = Cmnd_STK_SET_PARAMETER; buf[1] = parm; @@ -1442,45 +1390,42 @@ static int stk500_setparm(const PROGRAMMER *pgm, unsigned parm, unsigned value) stk500_send(pgm, buf, 4); - if (stk500_recv(pgm, buf, 1) < 0) + if(stk500_recv(pgm, buf, 1) < 0) return -1; - if (buf[0] == Resp_STK_NOSYNC) { - if (tries > 33) { + if(buf[0] == Resp_STK_NOSYNC) { + if(tries > 33) { msg_error("\n"); pmsg_error("cannot get into sync\n"); return -1; } - if (stk500_getsync(pgm) < 0) + if(stk500_getsync(pgm) < 0) return -1; goto retry; - } - else if (buf[0] != Resp_STK_INSYNC) { + } else if(buf[0] != Resp_STK_INSYNC) { msg_error("\n"); pmsg_error("protocol expects sync byte 0x%02x but got 0x%02x\n", Resp_STK_INSYNC, buf[0]); return -2; } - if (stk500_recv(pgm, buf, 1) < 0) + if(stk500_recv(pgm, buf, 1) < 0) return -1; - if (buf[0] == Resp_STK_OK) + if(buf[0] == Resp_STK_OK) return 0; - parm = buf[0]; /* if not STK_OK, we've been echoed parm here */ - if (stk500_recv(pgm, buf, 1) < 0) + parm = buf[0]; // If not STK_OK, we've been echoed parm here + if(stk500_recv(pgm, buf, 1) < 0) return -1; - if (buf[0] == Resp_STK_FAILED) { + if(buf[0] == Resp_STK_FAILED) { msg_error("\n"); pmsg_error("parameter 0x%02x failed\n", parm); return -3; - } - else { + } else { msg_error("\n"); pmsg_error("protocol expects OK byte 0x%02x but got 0x%02x\n", Resp_STK_OK, buf[0]); return -3; } } - static void stk500_display(const PROGRAMMER *pgm, const char *p) { unsigned maj = 0, min = 0, hdw = 0, topcard = 0; @@ -1490,17 +1435,17 @@ static void stk500_display(const PROGRAMMER *pgm, const char *p) { stk500_getparm(pgm, Param_STK500_TOPCARD_DETECT, &topcard); msg_info("%sHW Version : %d\n", p, hdw); msg_info("%sFW Version : %d.%d\n", p, maj, min); - if (topcard < 3) { + if(topcard < 3) { const char *n = "Unknown"; - switch (topcard) { - case 1: - n = "STK502"; - break; + switch(topcard) { + case 1: + n = "STK502"; + break; - case 2: - n = "STK501"; - break; + case 2: + n = "STK501"; + break; } msg_info("%sTopcard : %s\n", p, n); } @@ -1510,38 +1455,49 @@ static void stk500_display(const PROGRAMMER *pgm, const char *p) { return; } - static void stk500_print_parms1(const PROGRAMMER *pgm, const char *p, FILE *fp) { unsigned vtarget = 0, vadjust = 0; unsigned osc_pscale = 0, osc_cmatch = 0, sck_duration = 0; const char *unit; int decimals; - if (pgm->extra_features & HAS_VTARG_READ) { + if(pgm->extra_features & HAS_VTARG_READ) { stk500_getparm(pgm, Parm_STK_VTARGET, &vtarget); - fmsg_out(fp, "%sVtarget : %.1f V\n", p, vtarget / 10.0); + fmsg_out(fp, "%sVtarget : %.1f V\n", p, vtarget/10.0); } - if (pgm->extra_features & HAS_VAREF_ADJ) { + if(pgm->extra_features & HAS_VAREF_ADJ) { stk500_getparm(pgm, Parm_STK_VADJUST, &vadjust); - fmsg_out(fp, "%sVaref : %.1f V\n", p, vadjust / 10.0); + fmsg_out(fp, "%sVaref : %.1f V\n", p, vadjust/10.0); } - if (pgm->extra_features & HAS_FOSC_ADJ) { + if(pgm->extra_features & HAS_FOSC_ADJ) { stk500_getparm(pgm, Parm_STK_OSC_PSCALE, &osc_pscale); stk500_getparm(pgm, Parm_STK_OSC_CMATCH, &osc_cmatch); fmsg_out(fp, "%sOscillator : ", p); - if (osc_pscale == 0) + if(osc_pscale == 0) fmsg_out(fp, "Off\n"); else { int prescale = 1; - double f = PDATA(pgm)->xtal / 2.0; - - switch (osc_pscale) { - case 2: prescale = 8; break; - case 3: prescale = 32; break; - case 4: prescale = 64; break; - case 5: prescale = 128; break; - case 6: prescale = 256; break; - case 7: prescale = 1024; break; + double f = my.xtal/2.0; + + switch(osc_pscale) { + case 2: + prescale = 8; + break; + case 3: + prescale = 32; + break; + case 4: + prescale = 64; + break; + case 5: + prescale = 128; + break; + case 6: + prescale = 256; + break; + case 7: + prescale = 1024; + break; } f /= prescale; f /= (osc_cmatch + 1); @@ -1552,9 +1508,10 @@ static void stk500_print_parms1(const PROGRAMMER *pgm, const char *p, FILE *fp) } stk500_getparm(pgm, Parm_STK_SCK_DURATION, &sck_duration); - fmsg_out(fp, "%sSCK period : %.1f us\n", p, sck_duration * 8.0e6 / PDATA(pgm)->xtal + 0.0499); + fmsg_out(fp, "%sSCK period : %.1f us\n", p, sck_duration*8.0e6/my.xtal + 0.0499); + + double f = my.xtal; - double f = PDATA(pgm)->xtal; decimals = get_decimals(f); f = f_to_kHz_MHz(f, &unit); fmsg_out(fp, "%sXTAL frequency : %.*f %s\n", p, decimals, f, unit); @@ -1562,23 +1519,22 @@ static void stk500_print_parms1(const PROGRAMMER *pgm, const char *p, FILE *fp) return; } - static void stk500_print_parms(const PROGRAMMER *pgm, FILE *fp) { stk500_print_parms1(pgm, "", fp); } static void stk500_setup(PROGRAMMER *pgm) { pgm->cookie = mmt_malloc(sizeof(struct pdata)); - PDATA(pgm)->ext_addr_byte = 0xff; - PDATA(pgm)->xbeeResetPin = XBEE_DEFAULT_RESET_PIN; + my.ext_addr_byte = 0xff; + my.xbeeResetPin = XBEE_DEFAULT_RESET_PIN; // nanoSTK (Arduino Nano HW) uses 16 MHz - if (str_starts(pgmid, "nanoSTK")) - PDATA(pgm)->xtal = 16000000U; + if(str_starts(pgmid, "nanoSTK")) + my.xtal = 16000000U; else - PDATA(pgm)->xtal = STK500_XTAL; + my.xtal = STK500_XTAL; // The -c arduino programmer has auto-reset enabled be default - if (str_eq(pgm->type, "Arduino")) - PDATA(pgm)->autoreset = true; + if(str_eq(pgm->type, "Arduino")) + my.autoreset = true; } static void stk500_teardown(PROGRAMMER *pgm) { @@ -1591,47 +1547,41 @@ const char stk500_desc[] = "Atmel STK500 Version 1.x firmware"; void stk500_initpgm(PROGRAMMER *pgm) { strcpy(pgm->type, "STK500"); - /* - * mandatory functions - */ - pgm->initialize = stk500_initialize; - pgm->display = stk500_display; - pgm->enable = stk500_enable; - pgm->disable = stk500_disable; + // Mandatory functions + pgm->initialize = stk500_initialize; + pgm->display = stk500_display; + pgm->enable = stk500_enable; + pgm->disable = stk500_disable; pgm->program_enable = stk500_program_enable; - pgm->chip_erase = stk500_chip_erase; - pgm->cmd = stk500_cmd; - pgm->open = stk500_open; - pgm->close = stk500_close; - pgm->read_byte = avr_read_byte_default; - pgm->write_byte = avr_write_byte_default; - - /* - * optional functions - */ - pgm->paged_write = stk500_paged_write; - pgm->paged_load = stk500_paged_load; - pgm->print_parms = stk500_print_parms; + pgm->chip_erase = stk500_chip_erase; + pgm->cmd = stk500_cmd; + pgm->open = stk500_open; + pgm->close = stk500_close; + pgm->read_byte = avr_read_byte_default; + pgm->write_byte = avr_write_byte_default; + + // Optional functions + pgm->paged_write = stk500_paged_write; + pgm->paged_load = stk500_paged_load; + pgm->print_parms = stk500_print_parms; pgm->set_sck_period = stk500_set_sck_period; pgm->get_sck_period = stk500_get_sck_period; pgm->parseextparams = stk500_parseextparms; - pgm->setup = stk500_setup; - pgm->teardown = stk500_teardown; - pgm->page_size = 256; - - /* - * hardware dependent functions - */ - if (pgm->extra_features & HAS_VTARG_ADJ) - pgm->set_vtarget = stk500_set_vtarget; - if (pgm->extra_features & HAS_VTARG_READ) - pgm->get_vtarget = stk500_get_vtarget; - if (pgm->extra_features & HAS_VAREF_ADJ) { - pgm->set_varef = stk500_set_varef; - pgm->get_varef = stk500_get_varef; - } - if (pgm->extra_features & HAS_FOSC_ADJ) { - pgm->set_fosc = stk500_set_fosc; - pgm->get_fosc = stk500_get_fosc; + pgm->setup = stk500_setup; + pgm->teardown = stk500_teardown; + pgm->page_size = 256; + + // Hardware dependent functions + if(pgm->extra_features & HAS_VTARG_ADJ) + pgm->set_vtarget = stk500_set_vtarget; + if(pgm->extra_features & HAS_VTARG_READ) + pgm->get_vtarget = stk500_get_vtarget; + if(pgm->extra_features & HAS_VAREF_ADJ) { + pgm->set_varef = stk500_set_varef; + pgm->get_varef = stk500_get_varef; + } + if(pgm->extra_features & HAS_FOSC_ADJ) { + pgm->set_fosc = stk500_set_fosc; + pgm->get_fosc = stk500_get_fosc; } } diff --git a/src/stk500.h b/src/stk500.h index 32cc23b99..86029c27f 100644 --- a/src/stk500.h +++ b/src/stk500.h @@ -23,24 +23,23 @@ extern "C" { #endif -extern const char stk500_desc[]; -void stk500_initpgm(PROGRAMMER *pgm); + extern const char stk500_desc[]; + void stk500_initpgm(PROGRAMMER *pgm); -/* used by arduino.c to avoid duplicate code */ -int stk500_getsync(const PROGRAMMER *pgm); -int stk500_drain(const PROGRAMMER *pgm, int display); + // Used by arduino.c to avoid duplicate code + int stk500_getsync(const PROGRAMMER *pgm); + int stk500_drain(const PROGRAMMER *pgm, int display); #ifdef __cplusplus } #endif #include "xbee.h" - struct pdata { unsigned char ext_addr_byte; // Record ext-addr byte set in the target device (if used) int retry_attempts; // Number of connection attempts provided by the user int xbeeResetPin; // Piggy back variable used by xbee programmmer - struct serial_device xbee_serdev; // Piggy back device descriptor for XBee framing + struct serial_device xbee_serdev; // Piggy back device descriptor for XBee framing // Get/set flags for adjustable target voltage bool vtarg_get; @@ -63,8 +62,5 @@ struct pdata { bool autoreset; }; -#define PDATA(pgm) ((struct pdata *)(pgm->cookie)) - +#define my (*(struct pdata *) (pgm->cookie)) #endif - - diff --git a/src/stk500_private.h b/src/stk500_private.h index 7efe866c4..81608e7da 100644 --- a/src/stk500_private.h +++ b/src/stk500_private.h @@ -1,11 +1,11 @@ //**** ATMEL AVR - A P P L I C A T I O N N O T E ************************ //* -//* Title: AVR061 - STK500 Communication Protocol -//* Filename: command.h -//* Version: 1.0 -//* Last updated: 09.09.2002 +//* Title: AVR061 - STK500 Communication Protocol +//* Filename: command.h +//* Version: 1.0 +//* Last updated: 09.09.2002 //* -//* Support E-mail: avr@atmel.com +//* Support E-mail: avr@atmel.com //* //************************************************************************** @@ -15,89 +15,88 @@ // *****************[ STK Response constants ]*************************** -#define Resp_STK_OK 0x10 // ' ' -#define Resp_STK_FAILED 0x11 // ' ' -#define Resp_STK_UNKNOWN 0x12 // ' ' -#define Resp_STK_NODEVICE 0x13 // ' ' -#define Resp_STK_INSYNC 0x14 // ' ' -#define Resp_STK_NOSYNC 0x15 // ' ' +#define Resp_STK_OK 0x10 // ' ' +#define Resp_STK_FAILED 0x11 // ' ' +#define Resp_STK_UNKNOWN 0x12 // ' ' +#define Resp_STK_NODEVICE 0x13 // ' ' +#define Resp_STK_INSYNC 0x14 // ' ' +#define Resp_STK_NOSYNC 0x15 // ' ' -#define Resp_ADC_CHANNEL_ERROR 0x16 // ' ' -#define Resp_ADC_MEASURE_OK 0x17 // ' ' -#define Resp_PWM_CHANNEL_ERROR 0x18 // ' ' -#define Resp_PWM_ADJUST_OK 0x19 // ' ' +#define Resp_ADC_CHANNEL_ERROR 0x16 // ' ' +#define Resp_ADC_MEASURE_OK 0x17 // ' ' +#define Resp_PWM_CHANNEL_ERROR 0x18 // ' ' +#define Resp_PWM_ADJUST_OK 0x19 // ' ' // *****************[ STK Special constants ]*************************** -#define Sync_CRC_EOP 0x20 // 'SPACE' +#define Sync_CRC_EOP 0x20 // 'SPACE' // *****************[ STK Command constants ]*************************** -#define Cmnd_STK_GET_SYNC 0x30 // ' ' -#define Cmnd_STK_GET_SIGN_ON 0x31 // ' ' - -#define Cmnd_STK_SET_PARAMETER 0x40 // ' ' -#define Cmnd_STK_GET_PARAMETER 0x41 // ' ' -#define Cmnd_STK_SET_DEVICE 0x42 // ' ' -#define Cmnd_STK_SET_DEVICE_EXT 0x45 // ' ' - -#define Cmnd_STK_ENTER_PROGMODE 0x50 // ' ' -#define Cmnd_STK_LEAVE_PROGMODE 0x51 // ' ' -#define Cmnd_STK_CHIP_ERASE 0x52 // ' ' -#define Cmnd_STK_CHECK_AUTOINC 0x53 // ' ' -#define Cmnd_STK_LOAD_ADDRESS 0x55 // ' ' -#define Cmnd_STK_UNIVERSAL 0x56 // ' ' -#define Cmnd_STK_UNIVERSAL_MULTI 0x57 // ' ' - -#define Cmnd_STK_PROG_FLASH 0x60 // ' ' -#define Cmnd_STK_PROG_DATA 0x61 // ' ' -#define Cmnd_STK_PROG_FUSE 0x62 // ' ' -#define Cmnd_STK_PROG_LOCK 0x63 // ' ' -#define Cmnd_STK_PROG_PAGE 0x64 // ' ' -#define Cmnd_STK_PROG_FUSE_EXT 0x65 // ' ' - -#define Cmnd_STK_READ_FLASH 0x70 // ' ' -#define Cmnd_STK_READ_DATA 0x71 // ' ' -#define Cmnd_STK_READ_FUSE 0x72 // ' ' -#define Cmnd_STK_READ_LOCK 0x73 // ' ' -#define Cmnd_STK_READ_PAGE 0x74 // ' ' -#define Cmnd_STK_READ_SIGN 0x75 // ' ' -#define Cmnd_STK_READ_OSCCAL 0x76 // ' ' -#define Cmnd_STK_READ_FUSE_EXT 0x77 // ' ' -#define Cmnd_STK_READ_OSCCAL_EXT 0x78 // ' ' +#define Cmnd_STK_GET_SYNC 0x30 // ' ' +#define Cmnd_STK_GET_SIGN_ON 0x31 // ' ' + +#define Cmnd_STK_SET_PARAMETER 0x40 // ' ' +#define Cmnd_STK_GET_PARAMETER 0x41 // ' ' +#define Cmnd_STK_SET_DEVICE 0x42 // ' ' +#define Cmnd_STK_SET_DEVICE_EXT 0x45 // ' ' + +#define Cmnd_STK_ENTER_PROGMODE 0x50 // ' ' +#define Cmnd_STK_LEAVE_PROGMODE 0x51 // ' ' +#define Cmnd_STK_CHIP_ERASE 0x52 // ' ' +#define Cmnd_STK_CHECK_AUTOINC 0x53 // ' ' +#define Cmnd_STK_LOAD_ADDRESS 0x55 // ' ' +#define Cmnd_STK_UNIVERSAL 0x56 // ' ' +#define Cmnd_STK_UNIVERSAL_MULTI 0x57 // ' ' + +#define Cmnd_STK_PROG_FLASH 0x60 // ' ' +#define Cmnd_STK_PROG_DATA 0x61 // ' ' +#define Cmnd_STK_PROG_FUSE 0x62 // ' ' +#define Cmnd_STK_PROG_LOCK 0x63 // ' ' +#define Cmnd_STK_PROG_PAGE 0x64 // ' ' +#define Cmnd_STK_PROG_FUSE_EXT 0x65 // ' ' + +#define Cmnd_STK_READ_FLASH 0x70 // ' ' +#define Cmnd_STK_READ_DATA 0x71 // ' ' +#define Cmnd_STK_READ_FUSE 0x72 // ' ' +#define Cmnd_STK_READ_LOCK 0x73 // ' ' +#define Cmnd_STK_READ_PAGE 0x74 // ' ' +#define Cmnd_STK_READ_SIGN 0x75 // ' ' +#define Cmnd_STK_READ_OSCCAL 0x76 // ' ' +#define Cmnd_STK_READ_FUSE_EXT 0x77 // ' ' +#define Cmnd_STK_READ_OSCCAL_EXT 0x78 // ' ' // *****************[ STK Parameter constants ]*************************** -#define Parm_STK_HW_VER 0x80 // ' ' - R -#define Parm_STK_SW_MAJOR 0x81 // ' ' - R -#define Parm_STK_SW_MINOR 0x82 // ' ' - R -#define Parm_STK_LEDS 0x83 // ' ' - R/W -#define Parm_STK_VTARGET 0x84 // ' ' - R/W -#define Parm_STK_VADJUST 0x85 // ' ' - R/W -#define Parm_STK_OSC_PSCALE 0x86 // ' ' - R/W -#define Parm_STK_OSC_CMATCH 0x87 // ' ' - R/W -#define Parm_STK_RESET_DURATION 0x88 // ' ' - R/W -#define Parm_STK_SCK_DURATION 0x89 // ' ' - R/W - -#define Parm_STK_BUFSIZEL 0x90 // ' ' - R/W, Range {0..255} -#define Parm_STK_BUFSIZEH 0x91 // ' ' - R/W, Range {0..255} -#define Parm_STK_DEVICE 0x92 // ' ' - R/W, Range {0..255} -#define Parm_STK_PROGMODE 0x93 // ' ' - 'P' or 'S' -#define Parm_STK_PARAMODE 0x94 // ' ' - TRUE or FALSE -#define Parm_STK_POLLING 0x95 // ' ' - TRUE or FALSE -#define Parm_STK_SELFTIMED 0x96 // ' ' - TRUE or FALSE -#define Param_STK500_TOPCARD_DETECT 0x98 // ' ' - Detect top-card attached +#define Parm_STK_HW_VER 0x80 // ' ' - R +#define Parm_STK_SW_MAJOR 0x81 // ' ' - R +#define Parm_STK_SW_MINOR 0x82 // ' ' - R +#define Parm_STK_LEDS 0x83 // ' ' - R/W +#define Parm_STK_VTARGET 0x84 // ' ' - R/W +#define Parm_STK_VADJUST 0x85 // ' ' - R/W +#define Parm_STK_OSC_PSCALE 0x86 // ' ' - R/W +#define Parm_STK_OSC_CMATCH 0x87 // ' ' - R/W +#define Parm_STK_RESET_DURATION 0x88 // ' ' - R/W +#define Parm_STK_SCK_DURATION 0x89 // ' ' - R/W + +#define Parm_STK_BUFSIZEL 0x90 // ' ' - R/W, Range {0..255} +#define Parm_STK_BUFSIZEH 0x91 // ' ' - R/W, Range {0..255} +#define Parm_STK_DEVICE 0x92 // ' ' - R/W, Range {0..255} +#define Parm_STK_PROGMODE 0x93 // ' ' - 'P' or 'S' +#define Parm_STK_PARAMODE 0x94 // ' ' - TRUE or FALSE +#define Parm_STK_POLLING 0x95 // ' ' - TRUE or FALSE +#define Parm_STK_SELFTIMED 0x96 // ' ' - TRUE or FALSE +#define Param_STK500_TOPCARD_DETECT 0x98 // ' ' - Detect top-card attached // *****************[ STK status bit definitions ]*************************** -#define Stat_STK_INSYNC 0x01 // INSYNC status bit, '1' - INSYNC -#define Stat_STK_PROGMODE 0x02 // Programming mode, '1' - PROGMODE -#define Stat_STK_STANDALONE 0x04 // Standalone mode, '1' - SM mode -#define Stat_STK_RESET 0x08 // RESET button, '1' - Pushed -#define Stat_STK_PROGRAM 0x10 // Program button, ' 1' - Pushed -#define Stat_STK_LEDG 0x20 // Green LED status, '1' - Lit -#define Stat_STK_LEDR 0x40 // Red LED status, '1' - Lit -#define Stat_STK_LEDBLINK 0x80 // LED blink ON/OFF, '1' - Blink - +#define Stat_STK_INSYNC 0x01 // INSYNC status bit, '1' - INSYNC +#define Stat_STK_PROGMODE 0x02 // Programming mode, '1' - PROGMODE +#define Stat_STK_STANDALONE 0x04 // Standalone mode, '1' - SM mode +#define Stat_STK_RESET 0x08 // RESET button, '1' - Pushed +#define Stat_STK_PROGRAM 0x10 // Program button, ' 1' - Pushed +#define Stat_STK_LEDG 0x20 // Green LED status, '1' - Lit +#define Stat_STK_LEDR 0x40 // Red LED status, '1' - Lit +#define Stat_STK_LEDBLINK 0x80 // LED blink ON/OFF, '1' - Blink // *****************************[ End Of COMMAND.H ]************************** diff --git a/src/stk500generic.c b/src/stk500generic.c index 6d040eb63..29d60c54a 100644 --- a/src/stk500generic.c +++ b/src/stk500generic.c @@ -71,5 +71,5 @@ const char stk500generic_desc[] = "Atmel STK500, autodetect firmware version"; void stk500generic_initpgm(PROGRAMMER *pgm) { strcpy(pgm->type, "STK500GENERIC"); - pgm->open = stk500generic_open; + pgm->open = stk500generic_open; } diff --git a/src/stk500generic.h b/src/stk500generic.h index 40b6b25db..c30a5540a 100644 --- a/src/stk500generic.h +++ b/src/stk500generic.h @@ -21,7 +21,4 @@ extern const char stk500generic_desc[]; void stk500generic_initpgm(PROGRAMMER *pgm); - #endif - - diff --git a/src/stk500v2.c b/src/stk500v2.c index 3f6243c56..b0f891b8d 100644 --- a/src/stk500v2.c +++ b/src/stk500v2.c @@ -19,8 +19,6 @@ * along with this program. If not, see . */ -/* Based on Id: stk500.c,v 1.46 2004/12/22 01:52:45 bdean Exp */ - /* * avrdude interface for Atmel STK500V2 programmer * @@ -54,17 +52,17 @@ #include "usbdevs.h" /* - * We need to import enough from the JTAG ICE mkII definitions to be - * able to talk to the ICE, query some parameters etc. The macro + * We need to import enough from the JTAG ICE mkII definitions to be able to + * talk to the ICE, query some parameters etc. The macro * JTAGMKII_PRIVATE_EXPORTED limits the amount of definitions that - * jtagmkII_private.h will export, so to avoid conflicts with those - * names that are identical to the STK500v2 ones. + * jtagmkII_private.h will export, so to avoid conflicts with those names that + * are identical to the STK500v2 ones. */ -#include "jtagmkII.h" // public interfaces from jtagmkII.c +#include "jtagmkII.h" #define JTAGMKII_PRIVATE_EXPORTED #include "jtagmkII_private.h" -#include "jtag3.h" // public interfaces from jtagmkII.c +#include "jtag3.h" #define JTAG3_PRIVATE_EXPORTED #include "jtag3_private.h" @@ -81,27 +79,22 @@ #define DEBUGRECV(...) msg_trace2(__VA_ARGS__) -enum hvmode -{ +enum hvmode { PPMODE, HVSPMODE }; +#define my (*(struct pdata *) (pgm->cookie)) -#define PDATA(pgm) ((struct pdata *)(pgm->cookie)) - - -/* - * Data structure for displaying STK600 routing and socket cards. - */ -struct carddata -{ +// Data structure for displaying STK600 routing and socket cards +struct carddata { int id; const char *name; }; static const char *pgmname(const PROGRAMMER *pgm) { - unsigned int i = PDATA(pgm)->pgmtype; - const char *name[] = { // Parallel to PGMTYPE_ definitions in stk500v2_private.h + unsigned int i = my.pgmtype; + + const char *name[] = { // Parallel to PGMTYPE_ definitions in stk500v2_private.h "unknown", "STK500", "AVRISP", @@ -111,12 +104,11 @@ static const char *pgmname(const PROGRAMMER *pgm) { "JTAGICE3", }; - return i==PGMTYPE_STK500 && PDATA(pgm)->is_scratchmonkey? "SCRATCHMONKEY": // STK500 with LEDs - i1 */ + /* - * These two tables can be semi-automatically updated from - * targetboards.xml using tools/get-stk600-cards.xsl. + * These two tables can be semi-automatically updated from targetboards.xml + * using tools/get-stk600-cards.xsl. */ -static const struct carddata routing_cards[] = -{ - { 0x01, "STK600-RC020T-1" }, - { 0x03, "STK600-RC028T-3" }, - { 0x05, "STK600-RC040M-5" }, - { 0x08, "STK600-RC020T-8" }, - { 0x0A, "STK600-RC040M-4" }, - { 0x0C, "STK600-RC008T-2" }, - { 0x0D, "STK600-RC028M-6" }, - { 0x10, "STK600-RC064M-10" }, - { 0x11, "STK600-RC100M-11" }, - { 0x13, "STK600-RC100X-13" }, - { 0x15, "STK600-RC044X-15" }, - { 0x18, "STK600-RC100M-18" }, - { 0x19, "STK600-RCPWM-19" }, - { 0x1A, "STK600-RC064X-14" }, - { 0x1B, "STK600-RC032U-20" }, - { 0x1C, "STK600-RC014T-12" }, - { 0x1E, "STK600-RC064U-17" }, - { 0x1F, "STK600-RCuC3B0-21" }, - { 0x20, "STK600-RCPWM-22" }, - { 0x21, "STK600-RC020T-23" }, - { 0x22, "STK600-RC044M-24" }, - { 0x23, "STK600-RC044U-25" }, - { 0x24, "STK600-RCPWM-26" }, - { 0x25, "STK600-RCuC3B48-27" }, - { 0x27, "STK600-RC032M-29" }, - { 0x28, "STK600-RC044M-30" }, - { 0x29, "STK600-RC044M-31" }, - { 0x2A, "STK600-RC014T-42" }, - { 0x2B, "STK600-RC020T-43" }, - { 0x30, "STK600-RCUC3A144-32" }, - { 0x34, "STK600-RCUC3L0-34" }, - { 0x38, "STK600-RCUC3C0-36" }, - { 0x3B, "STK600-RCUC3C0-37" }, - { 0x3E, "STK600-RCUC3A144-33" }, - { 0x46, "STK600-RCuC3A100-28" }, - { 0x55, "STK600-RC064M-9" }, - { 0x88, "STK600-RCUC3C1-38" }, - { 0x8B, "STK600-RCUC3C1-39" }, - { 0xA0, "STK600-RC008T-7" }, - { 0xB8, "STK600-RCUC3C2-40" }, - { 0xBB, "STK600-RCUC3C2-41" }, +static const struct carddata routing_cards[] = { + {0x01, "STK600-RC020T-1"}, + {0x03, "STK600-RC028T-3"}, + {0x05, "STK600-RC040M-5"}, + {0x08, "STK600-RC020T-8"}, + {0x0A, "STK600-RC040M-4"}, + {0x0C, "STK600-RC008T-2"}, + {0x0D, "STK600-RC028M-6"}, + {0x10, "STK600-RC064M-10"}, + {0x11, "STK600-RC100M-11"}, + {0x13, "STK600-RC100X-13"}, + {0x15, "STK600-RC044X-15"}, + {0x18, "STK600-RC100M-18"}, + {0x19, "STK600-RCPWM-19"}, + {0x1A, "STK600-RC064X-14"}, + {0x1B, "STK600-RC032U-20"}, + {0x1C, "STK600-RC014T-12"}, + {0x1E, "STK600-RC064U-17"}, + {0x1F, "STK600-RCuC3B0-21"}, + {0x20, "STK600-RCPWM-22"}, + {0x21, "STK600-RC020T-23"}, + {0x22, "STK600-RC044M-24"}, + {0x23, "STK600-RC044U-25"}, + {0x24, "STK600-RCPWM-26"}, + {0x25, "STK600-RCuC3B48-27"}, + {0x27, "STK600-RC032M-29"}, + {0x28, "STK600-RC044M-30"}, + {0x29, "STK600-RC044M-31"}, + {0x2A, "STK600-RC014T-42"}, + {0x2B, "STK600-RC020T-43"}, + {0x30, "STK600-RCUC3A144-32"}, + {0x34, "STK600-RCUC3L0-34"}, + {0x38, "STK600-RCUC3C0-36"}, + {0x3B, "STK600-RCUC3C0-37"}, + {0x3E, "STK600-RCUC3A144-33"}, + {0x46, "STK600-RCuC3A100-28"}, + {0x55, "STK600-RC064M-9"}, + {0x88, "STK600-RCUC3C1-38"}, + {0x8B, "STK600-RCUC3C1-39"}, + {0xA0, "STK600-RC008T-7"}, + {0xB8, "STK600-RCUC3C2-40"}, + {0xBB, "STK600-RCUC3C2-41"}, }; -static const struct carddata socket_cards[] = -{ - { 0x01, "STK600-TQFP48" }, - { 0x02, "STK600-TQFP32" }, - { 0x03, "STK600-TQFP100" }, - { 0x04, "STK600-SOIC" }, - { 0x06, "STK600-TQFP144" }, - { 0x09, "STK600-TinyX3U" }, - { 0x0C, "STK600-TSSOP44" }, - { 0x0D, "STK600-TQFP44" }, - { 0x0E, "STK600-TQFP64-2" }, - { 0x0F, "STK600-ATMEGA2560" }, - { 0x15, "STK600-MLF64" }, - { 0x16, "STK600-ATXMEGAT0" }, - { 0x18, "QT600-ATMEGA324-QM64" }, - { 0x19, "STK600-ATMEGA128RFA1" }, - { 0x1A, "QT600-ATTINY88-QT8" }, - { 0x1B, "QT600-ATXMEGA128A1-QT16" }, - { 0x1C, "QT600-AT32UC3L-QM64" }, - { 0x1D, "STK600-HVE2" }, - { 0x1E, "STK600-ATTINY10" }, - { 0x55, "STK600-TQFP64" }, - { 0x69, "STK600-uC3-144" }, - { 0xF0, "STK600-ATXMEGA1281A1" }, - { 0xF1, "STK600-DIP" }, +static const struct carddata socket_cards[] = { + {0x01, "STK600-TQFP48"}, + {0x02, "STK600-TQFP32"}, + {0x03, "STK600-TQFP100"}, + {0x04, "STK600-SOIC"}, + {0x06, "STK600-TQFP144"}, + {0x09, "STK600-TinyX3U"}, + {0x0C, "STK600-TSSOP44"}, + {0x0D, "STK600-TQFP44"}, + {0x0E, "STK600-TQFP64-2"}, + {0x0F, "STK600-ATMEGA2560"}, + {0x15, "STK600-MLF64"}, + {0x16, "STK600-ATXMEGAT0"}, + {0x18, "QT600-ATMEGA324-QM64"}, + {0x19, "STK600-ATMEGA128RFA1"}, + {0x1A, "QT600-ATTINY88-QT8"}, + {0x1B, "QT600-ATXMEGA128A1-QT16"}, + {0x1C, "QT600-AT32UC3L-QM64"}, + {0x1D, "STK600-HVE2"}, + {0x1E, "STK600-ATTINY10"}, + {0x55, "STK600-TQFP64"}, + {0x69, "STK600-uC3-144"}, + {0xF0, "STK600-ATXMEGA1281A1"}, + {0xF1, "STK600-DIP"}, }; static int stk500v2_getparm(const PROGRAMMER *pgm, unsigned char parm, unsigned char *value); @@ -268,11 +259,9 @@ static int stk500v2_setparm2(const PROGRAMMER *pgm, unsigned char parm, unsigned static int stk500v2_setparm_real(const PROGRAMMER *pgm, unsigned char parm, unsigned char value); static void stk500v2_print_parms1(const PROGRAMMER *pgm, const char *p, FILE *fp); static int stk500v2_paged_load(const PROGRAMMER *pgm, const AVRPART *p, const AVRMEM *m, - unsigned int page_size, - unsigned int addr, unsigned int n_bytes); + unsigned int page_size, unsigned int addr, unsigned int n_bytes); static int stk500v2_paged_write(const PROGRAMMER *pgm, const AVRPART *p, const AVRMEM *m, - unsigned int page_size, - unsigned int addr, unsigned int n_bytes); + unsigned int page_size, unsigned int addr, unsigned int n_bytes); static unsigned int stk500v2_mode_for_pagesize(unsigned int pagesize); @@ -293,43 +282,43 @@ static int stk600_xprog_program_enable(const PROGRAMMER *pgm, const AVRPART *p); void stk500v2_setup(PROGRAMMER *pgm) { pgm->cookie = mmt_malloc(sizeof(struct pdata)); - PDATA(pgm)->command_sequence = 1; - PDATA(pgm)->boot_start = ULONG_MAX; - PDATA(pgm)->xtal = str_starts(pgmid, "scratchmonkey") ? SCRATCHMONKEY_XTAL : STK500V2_XTAL; + my.command_sequence = 1; + my.boot_start = ULONG_MAX; + my.xtal = str_starts(pgmid, "scratchmonkey")? SCRATCHMONKEY_XTAL: STK500V2_XTAL; } static void stk500v2_jtagmkII_setup(PROGRAMMER *pgm) { void *mycookie, *theircookie; pgm->cookie = mmt_malloc(sizeof(struct pdata)); - PDATA(pgm)->command_sequence = 1; + my.command_sequence = 1; /* - * Now, have the JTAG ICE mkII backend allocate its own private - * data. Store our own cookie in a safe place for the time being. + * Now, have the JTAG ICE mkII backend allocate its own private data. Store + * our own cookie in a safe place for the time being. */ mycookie = pgm->cookie; jtagmkII_setup(pgm); theircookie = pgm->cookie; pgm->cookie = mycookie; - PDATA(pgm)->chained_pdata = theircookie; + my.chained_pdata = theircookie; } static void stk500v2_jtag3_setup(PROGRAMMER *pgm) { void *mycookie, *theircookie; pgm->cookie = mmt_malloc(sizeof(struct pdata)); - PDATA(pgm)->command_sequence = 1; + my.command_sequence = 1; /* - * Now, have the JTAGICE3 backend allocate its own private - * data. Store our own cookie in a safe place for the time being. + * Now, have the JTAGICE3 backend allocate its own private data. Store our + * own cookie in a safe place for the time being. */ mycookie = pgm->cookie; jtag3_setup(pgm); theircookie = pgm->cookie; pgm->cookie = mycookie; - PDATA(pgm)->chained_pdata = theircookie; + my.chained_pdata = theircookie; } void stk500v2_teardown(PROGRAMMER *pgm) { @@ -339,11 +328,12 @@ void stk500v2_teardown(PROGRAMMER *pgm) { static void stk500v2_jtagmkII_teardown(PROGRAMMER *pgm) { if(pgm->cookie) { - mmt_free(PDATA(pgm)->flash_pagecache); - mmt_free(PDATA(pgm)->eeprom_pagecache); + mmt_free(my.flash_pagecache); + mmt_free(my.eeprom_pagecache); void *mycookie = pgm->cookie; - pgm->cookie = PDATA(pgm)->chained_pdata; + + pgm->cookie = my.chained_pdata; jtagmkII_teardown(pgm); pgm->cookie = mycookie; } @@ -355,7 +345,8 @@ static void stk500v2_jtagmkII_teardown(PROGRAMMER *pgm) { static void stk500v2_jtag3_teardown(PROGRAMMER *pgm) { if(pgm->cookie) { void *mycookie = pgm->cookie; - pgm->cookie = PDATA(pgm)->chained_pdata; + + pgm->cookie = my.chained_pdata; jtag3_teardown(pgm); pgm->cookie = mycookie; } @@ -364,11 +355,11 @@ static void stk500v2_jtag3_teardown(PROGRAMMER *pgm) { pgm->cookie = NULL; } - static unsigned short b2_to_u16(unsigned char *b) { unsigned short l; + l = b[0]; - l += (unsigned)b[1] << 8; + l += (unsigned) b[1] << 8; return l; } @@ -379,10 +370,10 @@ static void u16_to_b2(unsigned char *b, unsigned short l) { } static double f_to_kHz_MHz(double f, const char **unit) { - if (f >= 1e6) { + if(f >= 1e6) { f /= 1e6; *unit = "MHz"; - } else if (f >= 1e3) { + } else if(f >= 1e3) { f /= 1000; *unit = "kHz"; } else @@ -392,15 +383,15 @@ static double f_to_kHz_MHz(double f, const char **unit) { } static int get_decimals(double f) { - if (f >= 1e6) + if(f >= 1e6) return 6; - if (f >= 1e3) + if(f >= 1e3) return 3; return 0; } static int stk500v2_send_mk2(const PROGRAMMER *pgm, unsigned char *data, size_t len) { - if (serial_send(&pgm->fd, data, len) != 0) { + if(serial_send(&pgm->fd, data, len) != 0) { pmsg_error("unable to send command to serial port\n"); return -1; } @@ -408,20 +399,18 @@ static int stk500v2_send_mk2(const PROGRAMMER *pgm, unsigned char *data, size_t return 0; } -static unsigned short get_jtagisp_return_size(unsigned char cmd) -{ - for (size_t i = 0; i < sizeof jtagispcmds / sizeof jtagispcmds[0]; i++) - if (jtagispcmds[i].cmd == cmd) +static unsigned short get_jtagisp_return_size(unsigned char cmd) { + for(size_t i = 0; i < sizeof jtagispcmds/sizeof jtagispcmds[0]; i++) + if(jtagispcmds[i].cmd == cmd) return jtagispcmds[i].size; return 0; } /* - * Send the data as a JTAG ICE mkII encapsulated ISP packet. - * Unlike what AVR067 says, the packet gets a length of our - * response buffer prepended, and replies with RSP_SPI_DATA - * if successful. + * Send the data as a JTAG ICE mkII encapsulated ISP packet. Unlike what AVR067 + * says, the packet gets a length of our response buffer prepended, and replies + * with RSP_SPI_DATA if successful. */ static int stk500v2_jtagmkII_send(const PROGRAMMER *pgm, unsigned char *data, size_t len) { unsigned char *cmdbuf; @@ -429,28 +418,27 @@ static int stk500v2_jtagmkII_send(const PROGRAMMER *pgm, unsigned char *data, si unsigned short sz; sz = get_jtagisp_return_size(data[0]); - if (sz == 0) { + if(sz == 0) { pmsg_error("unsupported encapsulated ISP command: %#x\n", data[0]); return -1; } - if (sz == SZ_READ_FLASH_EE) { + if(sz == SZ_READ_FLASH_EE) { /* - * For CMND_READ_FLASH_ISP and CMND_READ_EEPROM_ISP, extract the - * size of the return data from the request. Note that the - * request itself has the size in big endian format, while we are - * supposed to deliver it in little endian. + * For CMND_READ_FLASH_ISP and CMND_READ_EEPROM_ISP, extract the size of + * the return data from the request. Note that the request itself has the + * size in big endian format, while we are supposed to deliver it in little + * endian. */ sz = 3 + (data[1] << 8) + data[2]; - } else if (sz == SZ_SPI_MULTI) { - /* - * CMND_SPI_MULTI has the Rx size encoded in its 3rd byte. - */ + } else if(sz == SZ_SPI_MULTI) { + // CMND_SPI_MULTI has the Rx size encoded in its 3rd byte sz = 3 + data[2]; } cmdbuf = mmt_malloc(len + 3); PROGRAMMER *pgmcp = pgm_dup(pgm); - pgmcp->cookie = PDATA(pgm)->chained_pdata; + + pgmcp->cookie = my.chained_pdata; cmdbuf[0] = CMND_ISP_PACKET; cmdbuf[1] = sz & 0xff; cmdbuf[2] = (sz >> 8) & 0xff; @@ -462,16 +450,15 @@ static int stk500v2_jtagmkII_send(const PROGRAMMER *pgm, unsigned char *data, si return rv; } -/* - * Send the data as a JTAGICE3 encapsulated ISP packet. - */ +// Send the data as a JTAGICE3 encapsulated ISP packet static int stk500v2_jtag3_send(const PROGRAMMER *pgm, unsigned char *data, size_t len) { unsigned char *cmdbuf; int rv; cmdbuf = mmt_malloc(len + 1); PROGRAMMER *pgmcp = pgm_dup(pgm); - pgmcp->cookie = PDATA(pgm)->chained_pdata; + + pgmcp->cookie = my.chained_pdata; cmdbuf[0] = SCOPE_AVR_ISP; memcpy(cmdbuf + 1, data, len); rv = jtag3_send(pgmcp, cmdbuf, len + 1); @@ -482,34 +469,33 @@ static int stk500v2_jtag3_send(const PROGRAMMER *pgm, unsigned char *data, size_ } static int stk500v2_send(const PROGRAMMER *pgm, unsigned char *data, size_t len) { - unsigned char buf[275 + 6]; // max MESSAGE_BODY of 275 bytes, 6 bytes overhead + unsigned char buf[275 + 6]; // Max MESSAGE_BODY of 275 bytes, 6 bytes overhead - if (PDATA(pgm)->pgmtype == PGMTYPE_AVRISP_MKII || - PDATA(pgm)->pgmtype == PGMTYPE_STK600) + if(my.pgmtype == PGMTYPE_AVRISP_MKII || my.pgmtype == PGMTYPE_STK600) return stk500v2_send_mk2(pgm, data, len); - else if (PDATA(pgm)->pgmtype == PGMTYPE_JTAGICE_MKII) + if(my.pgmtype == PGMTYPE_JTAGICE_MKII) return stk500v2_jtagmkII_send(pgm, data, len); - else if (PDATA(pgm)->pgmtype == PGMTYPE_JTAGICE3) + if(my.pgmtype == PGMTYPE_JTAGICE3) return stk500v2_jtag3_send(pgm, data, len); buf[0] = MESSAGE_START; - buf[1] = PDATA(pgm)->command_sequence; - buf[2] = len / 256; - buf[3] = len % 256; + buf[1] = my.command_sequence; + buf[2] = len/256; + buf[3] = len%256; buf[4] = TOKEN; - memcpy(buf+5, data, len); + memcpy(buf + 5, data, len); - // calculate the XOR checksum - buf[5+len] = 0; - for (size_t i=0; i<5+len; i++) - buf[5+len] ^= buf[i]; + // Calculate the XOR checksum + buf[5 + len] = 0; + for(size_t i = 0; i < 5 + len; i++) + buf[5 + len] ^= buf[i]; DEBUG("STK500V2: stk500v2_send("); - for (size_t i=0; ifd, buf, len+6) != 0) { + if(serial_send(&pgm->fd, buf, len + 6) != 0) { pmsg_error("unable to send command to serial port\n"); return -1; } @@ -517,18 +503,15 @@ static int stk500v2_send(const PROGRAMMER *pgm, unsigned char *data, size_t len) return 0; } - int stk500v2_drain(const PROGRAMMER *pgm, int display) { return serial_drain(&pgm->fd, display); } -static int stk500v2_recv_mk2(const PROGRAMMER *pgm, unsigned char *msg, - size_t maxsize) -{ +static int stk500v2_recv_mk2(const PROGRAMMER *pgm, unsigned char *msg, size_t maxsize) { int rv; rv = serial_recv(&pgm->fd, msg, maxsize); - if (rv < 0) { + if(rv < 0) { pmsg_error("unable to receive from USB\n"); return -1; } @@ -536,25 +519,24 @@ static int stk500v2_recv_mk2(const PROGRAMMER *pgm, unsigned char *msg, return rv; } -static int stk500v2_jtagmkII_recv(const PROGRAMMER *pgm, unsigned char *msg, - size_t maxsize) -{ +static int stk500v2_jtagmkII_recv(const PROGRAMMER *pgm, unsigned char *msg, size_t maxsize) { int rv; unsigned char *jtagmsg; PROGRAMMER *pgmcp = pgm_dup(pgm); - pgmcp->cookie = PDATA(pgm)->chained_pdata; + + pgmcp->cookie = my.chained_pdata; rv = jtagmkII_recv(pgmcp, &jtagmsg); pgm_free(pgmcp); - if (rv <= 0) { + if(rv <= 0) { pmsg_error("unable to receive\n"); return -1; } - if ((size_t) rv - 1 > maxsize) { + if((size_t) rv - 1 > maxsize) { pmsg_warning("got %u bytes, have only room for %u bytes\n", (unsigned) rv - 1, (unsigned) maxsize); rv = maxsize; } - switch (jtagmsg[0]) { + switch(jtagmsg[0]) { case RSP_SPI_DATA: break; case RSP_FAILED: @@ -572,30 +554,30 @@ static int stk500v2_jtagmkII_recv(const PROGRAMMER *pgm, unsigned char *msg, return rv; } -static int stk500v2_jtag3_recv(const PROGRAMMER *pgm, unsigned char *msg, - size_t maxsize) -{ +static int stk500v2_jtag3_recv(const PROGRAMMER *pgm, unsigned char *msg, size_t maxsize) { int rv; unsigned char *jtagmsg; PROGRAMMER *pgmcp = pgm_dup(pgm); - pgmcp->cookie = PDATA(pgm)->chained_pdata; + + pgmcp->cookie = my.chained_pdata; rv = jtag3_recv(pgmcp, &jtagmsg); pgm_free(pgmcp); - if (rv <= 0) { + if(rv <= 0) { pmsg_error("unable to receive\n"); return -1; } - /* Getting more data than expected is a normal case for the EDBG - implementation of JTAGICE3, as they always request a full 512 - octets from the ICE. Thus, only complain at high verbose - levels. */ - if ((size_t) rv - 1 > maxsize) { + /* + * Getting more data than expected is a normal case for the EDBG + * implementation of JTAGICE3, as they always request a full 512 octets from + * the ICE. Thus, only complain at high verbose levels. + */ + if((size_t) rv - 1 > maxsize) { pmsg_debug("%s(): got %u bytes, have only room for %u bytes\n", __func__, (unsigned) rv - 1, (unsigned) maxsize); rv = maxsize; } - if (jtagmsg[0] != SCOPE_AVR_ISP) { + if(jtagmsg[0] != SCOPE_AVR_ISP) { pmsg_error("message is not AVR ISP: 0x%02x\n", jtagmsg[0]); mmt_free(jtagmsg); return -1; @@ -606,7 +588,7 @@ static int stk500v2_jtag3_recv(const PROGRAMMER *pgm, unsigned char *msg, } static int stk500v2_recv(const PROGRAMMER *pgm, unsigned char *msg, size_t maxsize) { - enum states { sINIT, sSTART, sSEQNUM, sSIZE1, sSIZE2, sTOKEN, sDATA, sCSUM, sDONE } state = sSTART; + enum states { sINIT, sSTART, sSEQNUM, sSIZE1, sSIZE2, sTOKEN, sDATA, sCSUM, sDONE } state = sSTART; unsigned int msglen = 0; unsigned int curlen = 0; int timeout = 0; @@ -614,109 +596,109 @@ static int stk500v2_recv(const PROGRAMMER *pgm, unsigned char *msg, size_t maxsi /* * The entire timeout handling here is not very consistent, see - * * https://savannah.nongnu.org/bugs/index.php?43626 */ - long timeoutval = SERIAL_TIMEOUT; // seconds + long timeoutval = SERIAL_TIMEOUT; // Seconds double tstart, tnow; - if (PDATA(pgm)->pgmtype == PGMTYPE_AVRISP_MKII || - PDATA(pgm)->pgmtype == PGMTYPE_STK600) + if(my.pgmtype == PGMTYPE_AVRISP_MKII || my.pgmtype == PGMTYPE_STK600) return stk500v2_recv_mk2(pgm, msg, maxsize); - else if (PDATA(pgm)->pgmtype == PGMTYPE_JTAGICE_MKII) + else if(my.pgmtype == PGMTYPE_JTAGICE_MKII) return stk500v2_jtagmkII_recv(pgm, msg, maxsize); - else if (PDATA(pgm)->pgmtype == PGMTYPE_JTAGICE3) + else if(my.pgmtype == PGMTYPE_JTAGICE3) return stk500v2_jtag3_recv(pgm, msg, maxsize); DEBUG("STK500V2: stk500v2_recv(): "); tstart = avr_timestamp(); - while ( (state != sDONE ) && (!timeout) ) { - if (serial_recv(&pgm->fd, &c, 1) < 0) + while((state != sDONE) && (!timeout)) { + if(serial_recv(&pgm->fd, &c, 1) < 0) goto timedout; - DEBUG("0x%02x ",c); + DEBUG("0x%02x ", c); checksum ^= c; - switch (state) { - case sSTART: - DEBUGRECV("hoping for start token ..."); - if (c == MESSAGE_START) { - DEBUGRECV("got it\n"); - checksum = MESSAGE_START; - state = sSEQNUM; - } else - DEBUGRECV("sorry\n"); - break; - case sSEQNUM: - DEBUGRECV("hoping for sequence ...\n"); - if (c == PDATA(pgm)->command_sequence) { - DEBUGRECV("got it, incrementing\n"); - state = sSIZE1; - PDATA(pgm)->command_sequence++; - } else { - DEBUGRECV("sorry\n"); - state = sSTART; - } - break; - case sSIZE1: - DEBUGRECV("hoping for size LSB\n"); - msglen = (unsigned)c * 256; - state = sSIZE2; - break; - case sSIZE2: - DEBUGRECV("hoping for size MSB ..."); - msglen += (unsigned)c; - DEBUG(" msg is %u bytes\n",msglen); - state = sTOKEN; - break; - case sTOKEN: - if (c == TOKEN) state = sDATA; - else state = sSTART; - break; - case sDATA: - if (curlen < maxsize) { - msg[curlen] = c; - } else { - pmsg_error("buffer too small, received %d byte into %u byte buffer\n", - curlen, (unsigned int) maxsize); - return -2; - } - if ((curlen == 0) && (msg[0] == ANSWER_CKSUM_ERROR)) { - pmsg_error("previous packet sent with wrong checksum\n"); - return -3; - } - curlen++; - if (curlen == msglen) state = sCSUM; - break; - case sCSUM: - if (checksum == 0) { - state = sDONE; - } else { - state = sSTART; - pmsg_error("wrong checksum\n"); - return -4; - } - break; - default: - pmsg_error("unknown state\n"); - return -5; - } /* switch */ - - tnow = avr_timestamp(); - if (tnow-tstart > timeoutval) { - timedout: - pmsg_error("timeout\n"); - return -1; - } - - } /* while */ + switch(state) { + case sSTART: + DEBUGRECV("hoping for start token ..."); + if(c == MESSAGE_START) { + DEBUGRECV("got it\n"); + checksum = MESSAGE_START; + state = sSEQNUM; + } else + DEBUGRECV("sorry\n"); + break; + case sSEQNUM: + DEBUGRECV("hoping for sequence ...\n"); + if(c == my.command_sequence) { + DEBUGRECV("got it, incrementing\n"); + state = sSIZE1; + my.command_sequence++; + } else { + DEBUGRECV("sorry\n"); + state = sSTART; + } + break; + case sSIZE1: + DEBUGRECV("hoping for size LSB\n"); + msglen = (unsigned) c *256; + + state = sSIZE2; + break; + case sSIZE2: + DEBUGRECV("hoping for size MSB ..."); + msglen += (unsigned) c; + DEBUG(" msg is %u bytes\n", msglen); + state = sTOKEN; + break; + case sTOKEN: + if(c == TOKEN) + state = sDATA; + else + state = sSTART; + break; + case sDATA: + if(curlen < maxsize) { + msg[curlen] = c; + } else { + pmsg_error("buffer too small, received %d byte into %u byte buffer\n", curlen, (unsigned int) maxsize); + return -2; + } + if((curlen == 0) && (msg[0] == ANSWER_CKSUM_ERROR)) { + pmsg_error("previous packet sent with wrong checksum\n"); + return -3; + } + curlen++; + if(curlen == msglen) + state = sCSUM; + break; + case sCSUM: + if(checksum == 0) { + state = sDONE; + } else { + state = sSTART; + pmsg_error("wrong checksum\n"); + return -4; + } + break; + default: + pmsg_error("unknown state\n"); + return -5; + } // Switch + + tnow = avr_timestamp(); + if(tnow - tstart > timeoutval) { + timedout: + pmsg_error("timeout\n"); + return -1; + } + + } // While DEBUG("\n"); - return (int)(msglen+6); + return (int) (msglen + 6); } - int stk500v2_getsync(const PROGRAMMER *pgm) { int tries = 0; unsigned char buf[1], resp[32]; @@ -724,51 +706,53 @@ int stk500v2_getsync(const PROGRAMMER *pgm) { DEBUG("STK500V2: stk500v2_getsync()\n"); - if (PDATA(pgm)->pgmtype == PGMTYPE_JTAGICE_MKII || - PDATA(pgm)->pgmtype == PGMTYPE_JTAGICE3) + if(my.pgmtype == PGMTYPE_JTAGICE_MKII || my.pgmtype == PGMTYPE_JTAGICE3) return 0; long bak_serial_recv_timeout = serial_recv_timeout; + serial_recv_timeout = 200; retry: tries++; - // send the sync command and see if we can get there + // Send the sync command and see if we can get there buf[0] = CMD_SIGN_ON; stk500v2_send(pgm, buf, 1); - // try to get the response back and see where we got + // Try to get the response back and see where we got memset(resp, 0, sizeof resp); status = stk500v2_recv(pgm, resp, sizeof(resp)); - // if we got bytes returned, check to see what came back - if (status > 0) { - if (resp[0] == CMD_SIGN_ON && resp[1] == STATUS_CMD_OK && status > 3) { - // success! + // If we got bytes returned, check to see what came back + if(status > 0) { + if(resp[0] == CMD_SIGN_ON && resp[1] == STATUS_CMD_OK && status > 3) { + // Success! char *name = (char *) resp + 3; + if(str_starts(name, "STK500_2")) { - PDATA(pgm)->pgmtype = PGMTYPE_STK500; + my.pgmtype = PGMTYPE_STK500; } else if(str_starts(name, "SCRATCHMONKEY")) { - PDATA(pgm)->is_scratchmonkey = 1; - PDATA(pgm)->pgmtype = PGMTYPE_STK500; + my.is_scratchmonkey = 1; + my.pgmtype = PGMTYPE_STK500; } else if(str_starts(name, "AVRISP_2")) { - PDATA(pgm)->pgmtype = PGMTYPE_AVRISP; + my.pgmtype = PGMTYPE_AVRISP; } else if(str_starts(name, "AVRISP_MK2")) { - PDATA(pgm)->pgmtype = PGMTYPE_AVRISP_MKII; + my.pgmtype = PGMTYPE_AVRISP_MKII; } else if(str_starts(name, "STK600")) { - PDATA(pgm)->pgmtype = PGMTYPE_STK600; + my.pgmtype = PGMTYPE_STK600; } else { unsigned int len = resp[2]; - resp[len + 3 >= sizeof resp? sizeof resp - 1: len + 3] = 0; + + resp[len + 3 >= sizeof resp? sizeof resp - 1: len + 3] = 0; pmsg_notice("%s(): unknown programmer %s, assuming STK500\n", __func__, name); - PDATA(pgm)->pgmtype = PGMTYPE_STK500; + my.pgmtype = PGMTYPE_STK500; } pmsg_debug("%s(): found %s programmer\n", __func__, pgmname(pgm)); serial_recv_timeout = bak_serial_recv_timeout; return 0; } else { - if (tries > RETRIES) { + if(tries > RETRIES) { pmsg_error("cannot communicate with device: resp=0x%02x\n", resp[0]); serial_recv_timeout = bak_serial_recv_timeout; return -6; @@ -776,18 +760,18 @@ int stk500v2_getsync(const PROGRAMMER *pgm) { goto retry; } - // or if we got a timeout - } else if (status == -1) { - if (tries > RETRIES) { + // Or if we got a timeout + } else if(status == -1) { + if(tries > RETRIES) { pmsg_error("timeout communicating with programmer\n"); serial_recv_timeout = bak_serial_recv_timeout; return -1; } else goto retry; - // or any other error + // Or any other error } else { - if (tries > RETRIES) { + if(tries > RETRIES) { pmsg_error("unable to communicate with programmer (%d)\n", status); } else goto retry; @@ -797,109 +781,111 @@ int stk500v2_getsync(const PROGRAMMER *pgm) { return 0; } -static int stk500v2_command(const PROGRAMMER *pgm, unsigned char *buf, - size_t len, size_t maxlen) { +static int stk500v2_command(const PROGRAMMER *pgm, unsigned char *buf, size_t len, size_t maxlen) { int tries = 0; int status; DEBUG("STK500V2: stk500v2_command("); - for (size_t i=0; i 0) { - DEBUG(" = %d\n",status); - if (status < 2) { + // If we got a successful readback, return + if(status > 0) { + DEBUG(" = %d\n", status); + if(status < 2) { pmsg_error("short reply\n"); return -1; } - if (buf[0] == CMD_XPROG_SETMODE || buf[0] == CMD_XPROG) { - /* - * Decode XPROG wrapper errors. - */ - const char *msg; - int i; - - /* - * For CMD_XPROG_SETMODE, the status is returned in buf[1]. - * For CMD_XPROG, buf[1] contains the XPRG_CMD_* command, and - * buf[2] contains the status. - */ - i = buf[0] == CMD_XPROG_SETMODE? 1: 2; - - if (buf[i] != XPRG_ERR_OK) { - switch (buf[i]) { - case XPRG_ERR_FAILED: msg = "Failed"; break; - case XPRG_ERR_COLLISION: msg = "Collision"; break; - case XPRG_ERR_TIMEOUT: msg = "Timeout"; break; - default: msg = "Unknown"; break; - } - pmsg_error("%s: %s\n", - buf[0]==CMD_XPROG_SETMODE? "CMD_XPROG_SETMODE": "CMD_XPROG", msg); - return -1; + if(buf[0] == CMD_XPROG_SETMODE || buf[0] == CMD_XPROG) { + // Decode XPROG wrapper errors + const char *msg; + int i; + + /* + * For CMD_XPROG_SETMODE, the status is returned in buf[1]. For + * CMD_XPROG, buf[1] contains the XPRG_CMD_* command, and buf[2] contains + * the status. + */ + i = buf[0] == CMD_XPROG_SETMODE? 1: 2; + + if(buf[i] != XPRG_ERR_OK) { + switch(buf[i]) { + case XPRG_ERR_FAILED: + msg = "Failed"; + break; + case XPRG_ERR_COLLISION: + msg = "Collision"; + break; + case XPRG_ERR_TIMEOUT: + msg = "Timeout"; + break; + default: + msg = "Unknown"; + break; } - return 0; + pmsg_error("%s: %s\n", buf[0] == CMD_XPROG_SETMODE? "CMD_XPROG_SETMODE": "CMD_XPROG", msg); + return -1; + } + return 0; } else { - /* - * Decode STK500v2 errors. - */ - if (buf[1] >= STATUS_CMD_TOUT && buf[1] < 0xa0) { - const char *msg; - char msgbuf[30]; - switch (buf[1]) { - case STATUS_CMD_TOUT: - msg = "Command timed out"; - break; - - case STATUS_RDY_BSY_TOUT: - msg = "Sampling of the RDY/nBSY pin timed out"; - break; - - case STATUS_SET_PARAM_MISSING: - msg = "The `Set Device Parameters' have not been " - "executed in advance of this command"; - break; - - default: - sprintf(msgbuf, "unknown, code 0x%02x", buf[1]); - msg = msgbuf; - break; - } - pmsg_warning("%s\n", msg); - } else if (buf[1] == STATUS_CMD_OK) { - return status; - } else if (buf[1] == STATUS_CMD_FAILED) { - pmsg_error("command failed\n"); - } else if (buf[1] == STATUS_CLOCK_ERROR) { - pmsg_error("target clock speed error\n"); - return -2; - } else if (buf[1] == STATUS_CMD_UNKNOWN) { - pmsg_error("unknown command\n"); - } else { - pmsg_error("unknown status 0x%02x\n", buf[1]); + // Decode STK500v2 errors + if(buf[1] >= STATUS_CMD_TOUT && buf[1] < 0xa0) { + const char *msg; + char msgbuf[30]; + + switch(buf[1]) { + case STATUS_CMD_TOUT: + msg = "Command timed out"; + break; + + case STATUS_RDY_BSY_TOUT: + msg = "Sampling of the RDY/nBSY pin timed out"; + break; + + case STATUS_SET_PARAM_MISSING: + msg = "The `Set Device Parameters' have not been " "executed in advance of this command"; + break; + + default: + sprintf(msgbuf, "unknown, code 0x%02x", buf[1]); + msg = msgbuf; + break; } - return -1; + pmsg_warning("%s\n", msg); + } else if(buf[1] == STATUS_CMD_OK) { + return status; + } else if(buf[1] == STATUS_CMD_FAILED) { + pmsg_error("command failed\n"); + } else if(buf[1] == STATUS_CLOCK_ERROR) { + pmsg_error("target clock speed error\n"); + return -2; + } else if(buf[1] == STATUS_CMD_UNKNOWN) { + pmsg_error("unknown command\n"); + } else { + pmsg_error("unknown status 0x%02x\n", buf[1]); + } + return -1; } } - // otherwise try to sync up again + // Otherwise try to sync up again status = stk500v2_getsync(pgm); - if (status != 0) { - if (tries > RETRIES) { + if(status != 0) { + if(tries > RETRIES) { pmsg_error("failed to execute command 0x%02x\n", buf[0]); return -1; } else @@ -910,13 +896,11 @@ static int stk500v2_command(const PROGRAMMER *pgm, unsigned char *buf, return 0; } -static int stk500v2_cmd(const PROGRAMMER *pgm, const unsigned char *cmd, - unsigned char *res) -{ +static int stk500v2_cmd(const PROGRAMMER *pgm, const unsigned char *cmd, unsigned char *res) { unsigned char buf[8]; int result; - DEBUG("STK500V2: stk500v2_cmd(%02x,%02x,%02x,%02x)\n",cmd[0],cmd[1],cmd[2],cmd[3]); + DEBUG("STK500V2: stk500v2_cmd(%02x,%02x,%02x,%02x)\n", cmd[0], cmd[1], cmd[2], cmd[3]); buf[0] = CMD_SPI_MULTI; buf[1] = 4; @@ -928,10 +912,10 @@ static int stk500v2_cmd(const PROGRAMMER *pgm, const unsigned char *cmd, buf[7] = cmd[3]; result = stk500v2_command(pgm, buf, 8, sizeof(buf)); - if (result < 0) { + if(result < 0) { pmsg_error("send command failed\n"); return -1; - } else if (result < 6) { + } else if(result < 6) { pmsg_error("short reply, len = %d\n", result); return -1; } @@ -944,50 +928,42 @@ static int stk500v2_cmd(const PROGRAMMER *pgm, const unsigned char *cmd, return 0; } - -static int stk500v2_jtag3_cmd(const PROGRAMMER *pgm, const unsigned char *cmd, - unsigned char *res) -{ +static int stk500v2_jtag3_cmd(const PROGRAMMER *pgm, const unsigned char *cmd, unsigned char *res) { pmsg_error("not available in JTAGICE3\n"); return -1; } - -/* - * issue the 'chip erase' command to the AVR device - */ +// Issue the 'chip erase' command to the AVR device static int stk500v2_chip_erase(const PROGRAMMER *pgm, const AVRPART *p) { int result; unsigned char buf[16]; - if (p->op[AVR_OP_CHIP_ERASE] == NULL) { + if(p->op[AVR_OP_CHIP_ERASE] == NULL) { pmsg_error("chip erase instruction not defined for part %s\n", p->desc); return -1; } buf[0] = CMD_CHIP_ERASE_ISP; - buf[1] = p->chip_erase_delay / 1000; - buf[2] = 0; // use delay (?) - memset(buf+3, 0, 4); - avr_set_bits(p->op[AVR_OP_CHIP_ERASE], buf+3); + buf[1] = p->chip_erase_delay/1000; + buf[2] = 0; // Use delay (?) + memset(buf + 3, 0, 4); + avr_set_bits(p->op[AVR_OP_CHIP_ERASE], buf + 3); result = stk500v2_command(pgm, buf, 7, sizeof(buf)); - usleep(p->chip_erase_delay); // should not be needed - if (PDATA(pgm)->pgmtype != PGMTYPE_JTAGICE_MKII) { // skip for JTAGICE mkII (FW v7.39) - pgm->initialize(pgm, p); // should not be needed + usleep(p->chip_erase_delay); // Should not be needed + if(my.pgmtype != PGMTYPE_JTAGICE_MKII) { // Skip for JTAGICE mkII (FW v7.39) + pgm->initialize(pgm, p); // Should not be needed } return result >= 0? 0: -1; } -/* - * issue the 'chip erase' command to the AVR device, generic HV mode - */ +// Issue the 'chip erase' command to the AVR device, generic HV mode static int stk500hv_chip_erase(const PROGRAMMER *pgm, const AVRPART *p, enum hvmode mode) { int result; unsigned char buf[3]; - if (mode == PPMODE) { + if(mode == PPMODE) { buf[0] = CMD_CHIP_ERASE_PP; buf[1] = p->chiperasepulsewidth; buf[2] = p->chiperasepolltimeout; @@ -1003,39 +979,35 @@ static int stk500hv_chip_erase(const PROGRAMMER *pgm, const AVRPART *p, enum hvm return result >= 0? 0: -1; } -/* - * issue the 'chip erase' command to the AVR device, parallel mode - */ +// Issue the 'chip erase' command to the AVR device, parallel mode static int stk500pp_chip_erase(const PROGRAMMER *pgm, const AVRPART *p) { return stk500hv_chip_erase(pgm, p, PPMODE); } -/* - * issue the 'chip erase' command to the AVR device, HVSP mode - */ +// Issue the 'chip erase' command to the AVR device, HVSP mode static int stk500hvsp_chip_erase(const PROGRAMMER *pgm, const AVRPART *p) { return stk500hv_chip_erase(pgm, p, HVSPMODE); } /* - * Max length of returned message is the sum of all the description - * strings in the table below, plus 2 characters for separation each. - * Currently, this is 74 chars plus the terminating nul. + * Max length of returned message is the sum of all the description strings in + * the table below, plus 2 characters for separation each. Currently, this is + * 74 chars plus the terminating nul. */ static void stk500v2_translate_conn_status(unsigned char status, char *msg) { struct { unsigned int state; const char *description; } const conn_status[] = { - { STATUS_CONN_FAIL_SDO, "SDO fail" }, - { STATUS_CONN_FAIL_RST, "RST fail" }, - { STATUS_CONN_FAIL_SCK, "SCK fail" }, - { STATUS_TGT_NOT_DETECTED, "Target not detected" }, - { STATUS_TGT_REVERSE_INSERTED, "Target reverse inserted" }, + {STATUS_CONN_FAIL_SDO, "SDO fail"}, + {STATUS_CONN_FAIL_RST, "RST fail"}, + {STATUS_CONN_FAIL_SCK, "SCK fail"}, + {STATUS_TGT_NOT_DETECTED, "Target not detected"}, + {STATUS_TGT_REVERSE_INSERTED, "Target reverse inserted"}, }; *msg = 0; - for(size_t i = 0; i < sizeof conn_status / sizeof *conn_status; i++) { + for(size_t i = 0; i < sizeof conn_status/sizeof *conn_status; i++) { if(status & conn_status[i].state) { if(*msg) strcat(msg, ", "); @@ -1046,26 +1018,22 @@ static void stk500v2_translate_conn_status(unsigned char status, char *msg) { sprintf(msg, "Unknown status 0x%02x", status); } - -/* - * issue the 'program enable' command to the AVR device - */ +// Issue the 'program enable' command to the AVR device static int stk500v2_program_enable(const PROGRAMMER *pgm, const AVRPART *p) { unsigned char buf[16]; - char msg[100]; /* see remarks above about size needed */ + char msg[100]; // See remarks above about size needed int rv, tries; - PDATA(pgm)->lastpart = p; + my.lastpart = p; - if (p->op[AVR_OP_PGM_ENABLE] == NULL) { + if(p->op[AVR_OP_PGM_ENABLE] == NULL) { pmsg_error("program enable instruction not defined for part %s\n", p->desc); return -1; } - if (PDATA(pgm)->pgmtype == PGMTYPE_STK500 || - PDATA(pgm)->pgmtype == PGMTYPE_STK600) - /* Activate AVR-style (low active) RESET */ - stk500v2_setparm_real(pgm, PARAM_RESET_POLARITY, 0x01); + if(my.pgmtype == PGMTYPE_STK500 || my.pgmtype == PGMTYPE_STK600) + // Activate AVR-style (low active) RESET + stk500v2_setparm_real(pgm, PARAM_RESET_POLARITY, 0x01); tries = 0; retry: @@ -1077,83 +1045,81 @@ static int stk500v2_program_enable(const PROGRAMMER *pgm, const AVRPART *p) { buf[5] = p->bytedelay; buf[6] = p->pollvalue; buf[7] = p->pollindex; - memset(buf+8, 0, 4); - avr_set_bits(p->op[AVR_OP_PGM_ENABLE], buf+8); + memset(buf + 8, 0, 4); + avr_set_bits(p->op[AVR_OP_PGM_ENABLE], buf + 8); rv = stk500v2_command(pgm, buf, 12, sizeof(buf)); - if (rv < 0) { - switch (PDATA(pgm)->pgmtype) - { + if(rv < 0) { + switch(my.pgmtype) { case PGMTYPE_STK600: case PGMTYPE_AVRISP_MKII: - if (stk500v2_getparm(pgm, PARAM_STATUS_TGT_CONN, &buf[0]) != 0) { - pmsg_error("cannot get connection status\n"); - } else { - stk500v2_translate_conn_status(buf[0], msg); - pmsg_error("bad AVRISPmkII connection status: %s\n", msg); - } - break; + if(stk500v2_getparm(pgm, PARAM_STATUS_TGT_CONN, &buf[0]) != 0) { + pmsg_error("cannot get connection status\n"); + } else { + stk500v2_translate_conn_status(buf[0], msg); + pmsg_error("bad AVRISPmkII connection status: %s\n", msg); + } + break; case PGMTYPE_JTAGICE3: - if (buf[1] == STATUS_CMD_FAILED && (p->prog_modes & PM_debugWIRE)) { - unsigned char cmd[4], *resp; + if(buf[1] == STATUS_CMD_FAILED && is_debugwire(p)) { + unsigned char cmd[4], *resp; - /* Try debugWIRE, and MONCON_DISABLE */ - pmsg_notice2("no response in ISP mode, trying debugWIRE\n"); + // Try debugWIRE, and MONCON_DISABLE + pmsg_notice2("no response in ISP mode, trying debugWIRE\n"); - PROGRAMMER *pgmcp = pgm_dup(pgm); - pgmcp->cookie = PDATA(pgm)->chained_pdata; + PROGRAMMER *pgmcp = pgm_dup(pgm); - cmd[0] = PARM3_CONN_DW; - if (jtag3_setparm(pgmcp, SCOPE_AVR, 1, PARM3_CONNECTION, cmd, 1) < 0) { - pgm_free(pgmcp); - break; - } + pgmcp->cookie = my.chained_pdata; - cmd[0] = SCOPE_AVR; + cmd[0] = PARM3_CONN_DW; + if(jtag3_setparm(pgmcp, SCOPE_AVR, 1, PARM3_CONNECTION, cmd, 1) < 0) { + pgm_free(pgmcp); + break; + } - cmd[1] = CMD3_SIGN_ON; - cmd[2] = cmd[3] = 0; - if (jtag3_command(pgmcp, cmd, 4, &resp, "AVR sign-on") >= 0) { - mmt_free(resp); + cmd[0] = SCOPE_AVR; - cmd[1] = CMD3_START_DW_DEBUG; - if (jtag3_command(pgmcp, cmd, 4, &resp, "start DW debug") >= 0) { - mmt_free(resp); + cmd[1] = CMD3_SIGN_ON; + cmd[2] = cmd[3] = 0; + if(jtag3_command(pgmcp, cmd, 4, &resp, "AVR sign-on") >= 0) { + mmt_free(resp); - cmd[1] = CMD3_MONCON_DISABLE; - if (jtag3_command(pgmcp, cmd, 3, &resp, "MonCon disable") >= 0) - mmt_free(resp); - } - } - pgm_free(pgmcp); - if (tries++ > 3) { - pmsg_error("unable to return from debugWIRE to ISP\n"); - break; - } - pmsg_warning("target prepared for ISP, signed off; now\n"); - imsg_warning("retrying without power-cycling the target\n"); - goto retry; + cmd[1] = CMD3_START_DW_DEBUG; + if(jtag3_command(pgmcp, cmd, 4, &resp, "start DW debug") >= 0) { + mmt_free(resp); + + cmd[1] = CMD3_MONCON_DISABLE; + if(jtag3_command(pgmcp, cmd, 3, &resp, "MonCon disable") >= 0) + mmt_free(resp); + } } - break; + pgm_free(pgmcp); + if(tries++ > 3) { + pmsg_error("unable to return from debugWIRE to ISP\n"); + break; + } + pmsg_warning("target prepared for ISP, signed off; now\n"); + imsg_warning("retrying without power-cycling the target\n"); + goto retry; + } + break; default: - /* cannot report anything for other pgmtypes */ - break; + // Cannot report anything for other pgmtypes + break; } } return rv; } -/* - * issue the 'program enable' command to the AVR device, parallel mode - */ +// Issue the 'program enable' command to the AVR device, parallel mode static int stk500pp_program_enable(const PROGRAMMER *pgm, const AVRPART *p) { unsigned char buf[16]; - PDATA(pgm)->lastpart = p; + my.lastpart = p; buf[0] = CMD_ENTER_PROGMODE_PP; buf[1] = p->hventerstabdelay; @@ -1167,17 +1133,13 @@ static int stk500pp_program_enable(const PROGRAMMER *pgm, const AVRPART *p) { return stk500v2_command(pgm, buf, 8, sizeof(buf)); } -/* - * issue the 'program enable' command to the AVR device, HVSP mode - */ +// Issue the 'program enable' command to the AVR device, HVSP mode static int stk500hvsp_program_enable(const PROGRAMMER *pgm, const AVRPART *p) { unsigned char buf[16]; - PDATA(pgm)->lastpart = p; + my.lastpart = p; - buf[0] = PDATA(pgm)->pgmtype == PGMTYPE_STK600? - CMD_ENTER_PROGMODE_HVSP_STK600: - CMD_ENTER_PROGMODE_HVSP; + buf[0] = my.pgmtype == PGMTYPE_STK600? CMD_ENTER_PROGMODE_HVSP_STK600: CMD_ENTER_PROGMODE_HVSP; buf[1] = p->hventerstabdelay; buf[2] = p->hvspcmdexedelay; buf[3] = p->synchcycles; @@ -1190,30 +1152,24 @@ static int stk500hvsp_program_enable(const PROGRAMMER *pgm, const AVRPART *p) { return stk500v2_command(pgm, buf, 9, sizeof(buf)); } - -/* - * initialize the AVR device and prepare it to accept commands - */ +// Initialize the AVR device and prepare it to accept commands static int stk500v2_initialize(const PROGRAMMER *pgm, const AVRPART *p) { LNODEID ln; - AVRMEM * m; + AVRMEM *m; - if ((PDATA(pgm)->pgmtype == PGMTYPE_STK600 || - PDATA(pgm)->pgmtype == PGMTYPE_AVRISP_MKII || - PDATA(pgm)->pgmtype == PGMTYPE_JTAGICE_MKII) != 0 - && (p->prog_modes & (PM_PDI | PM_TPI)) != 0) { - /* - * This is an ATxmega device, must use XPROG protocol for the - * remaining actions. - */ - if (p->prog_modes & PM_PDI) { + if((my.pgmtype == PGMTYPE_STK600 || + my.pgmtype == PGMTYPE_AVRISP_MKII || + my.pgmtype == PGMTYPE_JTAGICE_MKII) != 0 && (p->prog_modes & (PM_PDI | PM_TPI)) != 0) { + // This is an ATxmega device, must use XPROG protocol for the remaining actions + if(is_pdi(p)) { // Find the border between application and boot area AVRMEM *bootmem = avr_locate_boot(p); AVRMEM *flashmem = avr_locate_flash(p); - if (bootmem == NULL || flashmem == NULL) { + + if(bootmem == NULL || flashmem == NULL) { pmsg_error("cannot locate flash or boot memories\n"); } else { - PDATA(pgm)->boot_start = bootmem->offset - flashmem->offset; + my.boot_start = bootmem->offset - flashmem->offset; } } // stk600_setup_xprog(pgm); [moved to pgm->enable()] @@ -1222,105 +1178,109 @@ static int stk500v2_initialize(const PROGRAMMER *pgm, const AVRPART *p) { } // Read or write target voltage - if (PDATA(pgm)->vtarg_get || PDATA(pgm)->vtarg_set) { + if(my.vtarg_get || my.vtarg_set) { // Read current target voltage set value unsigned char vtarg_read = 0; - if (stk500v2_getparm(pgm, PARAM_VTARGET, &vtarg_read) < 0) + + if(stk500v2_getparm(pgm, PARAM_VTARGET, &vtarg_read) < 0) return -1; - if (PDATA(pgm)->vtarg_get) - msg_info("Target voltage value read as %.2f V\n", (vtarg_read / 10.0)); + if(my.vtarg_get) + msg_info("Target voltage value read as %.2f V\n", (vtarg_read/10.0)); // Write target voltage value else { - msg_info("Changing target voltage from %.2f V to %.2f V\n", (vtarg_read / 10.0), PDATA(pgm)->vtarg_data); - if(pgm->set_vtarget(pgm, PDATA(pgm)->vtarg_data) < 0) + msg_info("Changing target voltage from %.2f V to %.2f V\n", (vtarg_read/10.0), my.vtarg_data); + if(pgm->set_vtarget(pgm, my.vtarg_data) < 0) return -1; } } // Read or write analog reference voltage - if (PDATA(pgm)->varef_get || PDATA(pgm)->varef_set) { - if(PDATA(pgm)->pgmtype == PGMTYPE_STK500) { + if(my.varef_get || my.varef_set) { + if(my.pgmtype == PGMTYPE_STK500) { // STK500: Read current analog reference voltage unsigned char varef_read = 0; - if (stk500v2_getparm(pgm, PARAM_VADJUST, &varef_read) < 0 ) + + if(stk500v2_getparm(pgm, PARAM_VADJUST, &varef_read) < 0) return -1; - if (PDATA(pgm)->varef_get) - msg_info("Analog reference voltage value read as %.2f V\n", (varef_read / 10.0)); + if(my.varef_get) + msg_info("Analog reference voltage value read as %.2f V\n", (varef_read/10.0)); // STK500: Write analog reference voltage else { msg_info("Changing analog reference voltage from %.2f V to %.2f V\n", - (varef_read / 10.0), PDATA(pgm)->varef_data); - if(pgm->set_varef(pgm, 0, PDATA(pgm)->varef_data) < 0) + varef_read/10.0, my.varef_data); + if(pgm->set_varef(pgm, 0, my.varef_data) < 0) return -1; } - } else if(PDATA(pgm)->pgmtype == PGMTYPE_STK600) { + } else if(my.pgmtype == PGMTYPE_STK600) { // STK600: Read current target voltage set value unsigned int varef_read = 0; - if (stk500v2_getparm2(pgm, PDATA(pgm)->varef_channel == 0 ? PARAM2_AREF0 : PARAM2_AREF1, &varef_read) < 0) + + if(stk500v2_getparm2(pgm, my.varef_channel == 0? PARAM2_AREF0: PARAM2_AREF1, &varef_read) < 0) return -1; - if (PDATA(pgm)->varef_get) - msg_info("Analog reference channel %d voltage read as %.2f V\n", PDATA(pgm)->varef_channel, (varef_read / 100.0)); + if(my.varef_get) + msg_info("Analog reference channel %d voltage read as %.2f V\n", + my.varef_channel, (varef_read/100.0)); // STK600: Write target voltage value for channel n else { msg_info("Changing analog reference channel %d voltage from %.2f V to %.2f V\n", - PDATA(pgm)->varef_channel, (varef_read / 100.0), PDATA(pgm)->varef_data); - if(pgm->set_varef(pgm, PDATA(pgm)->varef_channel, PDATA(pgm)->varef_data) < 0) + my.varef_channel, (varef_read/100.0), my.varef_data); + if(pgm->set_varef(pgm, my.varef_channel, my.varef_data) < 0) return -1; } } } // Read or write clock generator frequency - if (PDATA(pgm)->fosc_get || PDATA(pgm)->fosc_set) { - if(PDATA(pgm)->pgmtype == PGMTYPE_STK500 || PDATA(pgm)->pgmtype == PGMTYPE_STK600) { - const char *unit_get = {"Hz"}; + if(my.fosc_get || my.fosc_set) { + if(my.pgmtype == PGMTYPE_STK500 || my.pgmtype == PGMTYPE_STK600) { + const char *unit_get = { "Hz" }; double f_get = stk500v2_fosc_value(pgm); - if (f_get) + + if(f_get) f_get = f_to_kHz_MHz(f_get, &unit_get); - if (PDATA(pgm)->fosc_get) - msg_info("Oscillator currently set to %.3f %s\n", f_get, unit_get); + if(my.fosc_get) + msg_info("Oscillator currently set to %.3f %s\n", f_get, unit_get); // Write new osc freq else { const char *unit_set; - double f_set = f_to_kHz_MHz(PDATA(pgm)->fosc_data, &unit_set); + double f_set = f_to_kHz_MHz(my.fosc_data, &unit_set); + msg_info("Changing oscillator frequency from %.3f %s to %.3f %s\n", f_get, unit_get, f_set, unit_set); - if(pgm->set_fosc(pgm, PDATA(pgm)->fosc_data) < 0) + if(pgm->set_fosc(pgm, my.fosc_data) < 0) return -1; } } } /* - * Examine the avrpart's memory definitions, and initialize the page - * caches. For devices/memory that are not page oriented, treat - * them as page size 1 for EEPROM, and 2 for flash. + * Examine the avrpart's memory definitions, and initialize the page caches. + * For devices/memory that are not page oriented, treat them as page size 1 + * for EEPROM, and 2 for flash. */ - PDATA(pgm)->flash_pagesize = 2; - PDATA(pgm)->eeprom_pagesize = 1; - for (ln = lfirst(p->mem); ln; ln = lnext(ln)) { + my.flash_pagesize = 2; + my.eeprom_pagesize = 1; + for(ln = lfirst(p->mem); ln; ln = lnext(ln)) { m = ldata(ln); - if (mem_is_flash(m)) { - if (m->page_size > 1) { - if (m->page_size > 256) - PDATA(pgm)->flash_pagesize = 256; + if(mem_is_flash(m)) { + if(m->page_size > 1) { + if(m->page_size > 256) + my.flash_pagesize = 256; else - PDATA(pgm)->flash_pagesize = m->page_size; + my.flash_pagesize = m->page_size; } - } else if (mem_is_eeprom(m)) { - if (m->page_size > 1) - PDATA(pgm)->eeprom_pagesize = m->page_size; + } else if(mem_is_eeprom(m)) { + if(m->page_size > 1) + my.eeprom_pagesize = m->page_size; } } - mmt_free(PDATA(pgm)->flash_pagecache); - mmt_free(PDATA(pgm)->eeprom_pagecache); - PDATA(pgm)->flash_pagecache = mmt_malloc(PDATA(pgm)->flash_pagesize); - PDATA(pgm)->eeprom_pagecache = mmt_malloc(PDATA(pgm)->eeprom_pagesize); - PDATA(pgm)->flash_pageaddr = PDATA(pgm)->eeprom_pageaddr = ~0UL; + mmt_free(my.flash_pagecache); + mmt_free(my.eeprom_pagecache); + my.flash_pagecache = mmt_malloc(my.flash_pagesize); + my.eeprom_pagecache = mmt_malloc(my.eeprom_pagesize); + my.flash_pageaddr = my.eeprom_pageaddr = ~0UL; - if (p->flags & AVRPART_IS_AT90S1200) { - /* - * AT90S1200 needs a positive reset pulse after a chip erase. - */ + if(p->flags & AVRPART_IS_AT90S1200) { + // AT90S1200 needs a positive reset pulse after a chip erase pgm->disable(pgm); usleep(10000); } @@ -1328,41 +1288,39 @@ static int stk500v2_initialize(const PROGRAMMER *pgm, const AVRPART *p) { return pgm->program_enable(pgm, p); } - -/* - * initialize the AVR device and prepare it to accept commands - */ +// Initialize the AVR device and prepare it to accept commands static int stk500v2_jtag3_initialize(const PROGRAMMER *pgm, const AVRPART *p) { unsigned char parm[4], *resp; LNODEID ln; - AVRMEM * m; + AVRMEM *m; - // FIXME: condition below looks fishy, suspect the code wants !(p->prog_modes & (PM_debugWIRE | PM_JTAG | PM_JTAGmkI /* | PM_XMEGAJTAG | PM_AVR32JTAG */)) - if (p->prog_modes & (PM_PDI | PM_TPI)) { + // FIXME: how does condition below make sense? + if(p->prog_modes & (PM_PDI | PM_TPI)) { pmsg_error("part %s has no ISP interface\n", p->desc); return -1; } PROGRAMMER *pgmcp = pgm_dup(pgm); - pgmcp->cookie = PDATA(pgm)->chained_pdata; - if (p->prog_modes & PM_debugWIRE) + pgmcp->cookie = my.chained_pdata; + + if(is_debugwire(p)) parm[0] = PARM3_ARCH_TINY; else parm[0] = PARM3_ARCH_MEGA; - if (jtag3_setparm(pgmcp, SCOPE_AVR, 0, PARM3_ARCH, parm, 1) < 0) { + if(jtag3_setparm(pgmcp, SCOPE_AVR, 0, PARM3_ARCH, parm, 1) < 0) { pgm_free(pgmcp); return -1; } parm[0] = PARM3_SESS_PROGRAMMING; - if (jtag3_setparm(pgmcp, SCOPE_AVR, 0, PARM3_SESS_PURPOSE, parm, 1) < 0) { + if(jtag3_setparm(pgmcp, SCOPE_AVR, 0, PARM3_SESS_PURPOSE, parm, 1) < 0) { pgm_free(pgmcp); return -1; } parm[0] = PARM3_CONN_ISP; - if (jtag3_setparm(pgmcp, SCOPE_AVR, 1, PARM3_CONNECTION, parm, 1) < 0) { + if(jtag3_setparm(pgmcp, SCOPE_AVR, 1, PARM3_CONNECTION, parm, 1) < 0) { pgm_free(pgmcp); return -1; } @@ -1371,38 +1329,52 @@ static int stk500v2_jtag3_initialize(const PROGRAMMER *pgm, const AVRPART *p) { parm[1] = 0x1e; jtag3_send(pgmcp, parm, 2); - if (jtag3_recv(pgmcp, &resp) > 0) + if(jtag3_recv(pgmcp, &resp) > 0) mmt_free(resp); // Read or write SUFFER register - if (PDATA(pgm)->suffer_get || PDATA(pgm)->suffer_set) { + if(my.suffer_get || my.suffer_set) { // Read existing SUFFER value - if (jtag3_getparm(pgmcp, SCOPE_EDBG, MEDBG_REG_SUFFER_BANK + 0x10, MEDBG_REG_SUFFER_OFFSET, PDATA(pgm)->suffer_data, 1) < 0) + if(jtag3_getparm(pgmcp, SCOPE_EDBG, MEDBG_REG_SUFFER_BANK + 0x10, + MEDBG_REG_SUFFER_OFFSET, my.suffer_data, 1) < 0) { + return -1; - if (!PDATA(pgm)->suffer_set) - imsg_info("SUFFER register value read as 0x%02x\n", PDATA(pgm)->suffer_data[0]); + } + if(!my.suffer_set) + imsg_info("SUFFER register value read as 0x%02x\n", my.suffer_data[0]); // Write new SUFFER value else { - if (jtag3_setparm(pgmcp, SCOPE_EDBG, MEDBG_REG_SUFFER_BANK + 0x10, MEDBG_REG_SUFFER_OFFSET, PDATA(pgm)->suffer_data+1, 1) < 0) + if(jtag3_setparm(pgmcp, SCOPE_EDBG, MEDBG_REG_SUFFER_BANK + 0x10, + MEDBG_REG_SUFFER_OFFSET, my.suffer_data + 1, 1) < 0) { + return -1; - imsg_info("SUFFER register value changed from 0x%02x to 0x%02x\n", PDATA(pgm)->suffer_data[0], PDATA(pgm)->suffer_data[1]); + } + imsg_info("SUFFER register value changed from 0x%02x to 0x%02x\n", + my.suffer_data[0], my.suffer_data[1]); } } // Read or write Vtarg switch - if (PDATA(pgm)->vtarg_switch_get || PDATA(pgm)->vtarg_switch_set) { + if(my.vtarg_switch_get || my.vtarg_switch_set) { // Read existing Vtarg switch value - if (jtag3_getparm(pgmcp, SCOPE_EDBG, EDBG_CTXT_CONTROL, EDBG_CONTROL_TARGET_POWER, PDATA(pgm)->vtarg_switch_data, 1) < 0) + if(jtag3_getparm(pgmcp, SCOPE_EDBG, EDBG_CTXT_CONTROL, + EDBG_CONTROL_TARGET_POWER, my.vtarg_switch_data, 1) < 0) { + return -1; - if (!PDATA(pgm)->vtarg_switch_set) - pmsg_info("Vtarg switch setting read as %u: target power is switched %s\n", PDATA(pgm)->vtarg_switch_data[0], PDATA(pgm)->vtarg_switch_data[0] ? "on" : "off"); - // Write Vtarg switch value - else { - if (jtag3_setparm(pgmcp, SCOPE_EDBG, EDBG_CTXT_CONTROL, EDBG_CONTROL_TARGET_POWER, PDATA(pgm)->vtarg_switch_data+1, 1) < 0) + } + if(!my.vtarg_switch_set) { + pmsg_info("Vtarg switch setting read as %u: target power is switched %s\n", + my.vtarg_switch_data[0], my.vtarg_switch_data[0]? "on": "off"); + } else { // Write Vtarg switch value + if(jtag3_setparm(pgmcp, SCOPE_EDBG, EDBG_CTXT_CONTROL, + EDBG_CONTROL_TARGET_POWER, my.vtarg_switch_data + 1, 1) < 0) { + return -1; - pmsg_info("Vtarg switch setting changed from %u to %u\n", PDATA(pgm)->vtarg_switch_data[0], PDATA(pgm)->vtarg_switch_data[1]); - // Exit early is the target power switch is off and print sensible info message - if (PDATA(pgm)->vtarg_switch_data[1] == 0) { + } + pmsg_info("Vtarg switch setting changed from %u to %u\n", my.vtarg_switch_data[0], + my.vtarg_switch_data[1]); + // Exit early if the target power switch is off and print sensible info message + if(my.vtarg_switch_data[1] == 0) { pmsg_info("turn on the Vtarg switch to establish connection with the target\n\n"); return -1; } @@ -1410,20 +1382,22 @@ static int stk500v2_jtag3_initialize(const PROGRAMMER *pgm, const AVRPART *p) { } // Read or write target voltage - if (PDATA(pgm)->vtarg_get || PDATA(pgm)->vtarg_set) { + if(my.vtarg_get || my.vtarg_set) { // Read current target voltage set value unsigned char buf[2]; - if (jtag3_getparm(pgmcp, SCOPE_GENERAL, 1, PARM3_VADJUST, buf, 2) < 0) + + if(jtag3_getparm(pgmcp, SCOPE_GENERAL, 1, PARM3_VADJUST, buf, 2) < 0) return -1; - double vtarg_read = b2_to_u16(buf) / 1000.0; - if (PDATA(pgm)->vtarg_get) + double vtarg_read = b2_to_u16(buf)/1000.0; + + if(my.vtarg_get) msg_info("Target voltage value read as %.2f V\n", vtarg_read); // Write target voltage value else { - u16_to_b2(buf, (unsigned)(PDATA(pgm)->vtarg_data * 1000)); - msg_info("Changing target voltage from %.2f V to %.2f V\n", vtarg_read, PDATA(pgm)->vtarg_data); - if (jtag3_setparm(pgmcp, SCOPE_GENERAL, 1, PARM3_VADJUST, buf, sizeof(buf)) < 0) { - msg_warning("Cannot set target voltage %.2f V\n", PDATA(pgm)->vtarg_data); + u16_to_b2(buf, (unsigned) (my.vtarg_data*1000)); + msg_info("Changing target voltage from %.2f V to %.2f V\n", vtarg_read, my.vtarg_data); + if(jtag3_setparm(pgmcp, SCOPE_GENERAL, 1, PARM3_VADJUST, buf, sizeof(buf)) < 0) { + msg_warning("Cannot set target voltage %.2f V\n", my.vtarg_data); return -1; } } @@ -1432,46 +1406,43 @@ static int stk500v2_jtag3_initialize(const PROGRAMMER *pgm, const AVRPART *p) { mmt_free(pgmcp); /* - * Examine the avrpart's memory definitions, and initialize the page - * caches. For devices/memory that are not page oriented, treat - * them as page size 1 for EEPROM, and 2 for flash. + * Examine the avrpart's memory definitions, and initialize the page caches. + * For devices/memory that are not page oriented, treat them as page size 1 + * for EEPROM, and 2 for flash. */ - PDATA(pgm)->flash_pagesize = 2; - PDATA(pgm)->eeprom_pagesize = 1; - for (ln = lfirst(p->mem); ln; ln = lnext(ln)) { + my.flash_pagesize = 2; + my.eeprom_pagesize = 1; + for(ln = lfirst(p->mem); ln; ln = lnext(ln)) { m = ldata(ln); - if (mem_is_flash(m)) { - if (m->page_size > 1) { - if (m->page_size > 256) - PDATA(pgm)->flash_pagesize = 256; + if(mem_is_flash(m)) { + if(m->page_size > 1) { + if(m->page_size > 256) + my.flash_pagesize = 256; else - PDATA(pgm)->flash_pagesize = m->page_size; + my.flash_pagesize = m->page_size; } - } else if (mem_is_eeprom(m)) { - if (m->page_size > 1) - PDATA(pgm)->eeprom_pagesize = m->page_size; + } else if(mem_is_eeprom(m)) { + if(m->page_size > 1) + my.eeprom_pagesize = m->page_size; } } - mmt_free(PDATA(pgm)->flash_pagecache); - mmt_free(PDATA(pgm)->eeprom_pagecache); - PDATA(pgm)->flash_pagecache = mmt_malloc(PDATA(pgm)->flash_pagesize); - PDATA(pgm)->eeprom_pagecache = mmt_malloc(PDATA(pgm)->eeprom_pagesize); - PDATA(pgm)->flash_pageaddr = PDATA(pgm)->eeprom_pageaddr = ~0UL; + mmt_free(my.flash_pagecache); + mmt_free(my.eeprom_pagecache); + my.flash_pagecache = mmt_malloc(my.flash_pagesize); + my.eeprom_pagecache = mmt_malloc(my.eeprom_pagesize); + my.flash_pageaddr = my.eeprom_pageaddr = ~0UL; return pgm->program_enable(pgm, p); } - -/* - * initialize the AVR device and prepare it to accept commands, generic HV mode - */ +// Initialize the AVR device and prepare it to accept commands, generic HV mode static int stk500hv_initialize(const PROGRAMMER *pgm, const AVRPART *p, enum hvmode mode) { unsigned char buf[CTL_STACK_SIZE + 1]; int result; LNODEID ln; - AVRMEM * m; + AVRMEM *m; - if (p->ctl_stack_type != (mode == PPMODE? CTL_STACK_PP: CTL_STACK_HVSP)) { + if(p->ctl_stack_type != (mode == PPMODE? CTL_STACK_PP: CTL_STACK_HVSP)) { pmsg_error("%s programming control stack not defined for part %s\n", mode == PPMODE? "parallel": "high-voltage serial", p->desc); return -1; @@ -1482,159 +1453,176 @@ static int stk500hv_initialize(const PROGRAMMER *pgm, const AVRPART *p, enum hvm result = stk500v2_command(pgm, buf, CTL_STACK_SIZE + 1, sizeof(buf)); - if (result < 0) { + if(result < 0) { pmsg_error("unable to set control stack\n"); return -1; } // Read or write target voltage - if (PDATA(pgm)->vtarg_get || PDATA(pgm)->vtarg_set) { + if(my.vtarg_get || my.vtarg_set) { // Read current target voltage set value unsigned char vtarg_read = 0; - if (stk500v2_getparm(pgm, PARAM_VTARGET, &vtarg_read) < 0) + + if(stk500v2_getparm(pgm, PARAM_VTARGET, &vtarg_read) < 0) return -1; - if (PDATA(pgm)->vtarg_get) - msg_info("Target voltage value read as %.2f V\n", (vtarg_read / 10.0)); + if(my.vtarg_get) + msg_info("Target voltage value read as %.2f V\n", (vtarg_read/10.0)); // Write target voltage value else { - msg_info("Changing target voltage from %.2f V to %.2f V\n", (vtarg_read / 10.0), PDATA(pgm)->vtarg_data); - if(pgm->set_vtarget(pgm, PDATA(pgm)->vtarg_data) < 0) + msg_info("Changing target voltage from %.2f V to %.2f V\n", (vtarg_read/10.0), my.vtarg_data); + if(pgm->set_vtarget(pgm, my.vtarg_data) < 0) return -1; } } // Read or write analog reference voltage - if (PDATA(pgm)->varef_get || PDATA(pgm)->varef_set) { - if(PDATA(pgm)->pgmtype == PGMTYPE_STK500) { + if(my.varef_get || my.varef_set) { + if(my.pgmtype == PGMTYPE_STK500) { // STK500: Read current analog reference voltage unsigned char varef_read = 0; - if (stk500v2_getparm(pgm, PARAM_VADJUST, &varef_read) < 0) + + if(stk500v2_getparm(pgm, PARAM_VADJUST, &varef_read) < 0) return -1; - if (PDATA(pgm)->varef_get) - msg_info("Analog reference voltage value read as %.2f V\n", (varef_read / 10.0)); - // STK500: Write analog reference voltage - else { + if(my.varef_get) { + msg_info("Analog reference voltage value read as %.2f V\n", varef_read/10.0); + } else { // STK500: Write analog reference voltage msg_info("Changing analog reference voltage from %.2f V to %.2f V\n", - (varef_read / 10.0), PDATA(pgm)->varef_data); - if(pgm->set_varef(pgm, 0, PDATA(pgm)->varef_data) < 0) + varef_read/10.0, my.varef_data); + if(pgm->set_varef(pgm, 0, my.varef_data) < 0) return -1; } - } else if(PDATA(pgm)->pgmtype == PGMTYPE_STK600) { + } else if(my.pgmtype == PGMTYPE_STK600) { // STK600: Read current target voltage set value unsigned int varef_read = 0; - if (stk500v2_getparm2(pgm, PDATA(pgm)->varef_channel == 0 ? PARAM2_AREF0 : PARAM2_AREF1, &varef_read) < 0) + + if(stk500v2_getparm2(pgm, my.varef_channel == 0? PARAM2_AREF0: PARAM2_AREF1, &varef_read) < 0) return -1; - if (PDATA(pgm)->varef_get) - msg_info("Analog reference channel %d voltage read as %.2f V\n", PDATA(pgm)->varef_channel, (varef_read / 100.0)); - // STK600: Write target voltage value for channel n - else { + if(my.varef_get) { + msg_info("Analog reference channel %d voltage read as %.2f V\n", + my.varef_channel, (varef_read/100.0)); + } else { // STK600: Write target voltage value for channel n msg_info("Changing analog reference channel %d voltage from %.2f V to %.2f V\n", - PDATA(pgm)->varef_channel, (varef_read / 100.0), PDATA(pgm)->varef_data); - if(pgm->set_varef(pgm, PDATA(pgm)->varef_channel, PDATA(pgm)->varef_data) < 0) + my.varef_channel, (varef_read/100.0), my.varef_data); + if(pgm->set_varef(pgm, my.varef_channel, my.varef_data) < 0) return -1; } } } // Read or write clock generator frequency - if (PDATA(pgm)->fosc_get || PDATA(pgm)->fosc_set) { - if(PDATA(pgm)->pgmtype == PGMTYPE_STK500) { + if(my.fosc_get || my.fosc_set) { + if(my.pgmtype == PGMTYPE_STK500) { // Read current target voltage set value unsigned char osc_pscale = 0; unsigned char osc_cmatch = 0; - const char *unit_get = {"Hz"}; + const char *unit_get = { "Hz" }; double f_get = 0.0; - if (stk500v2_getparm(pgm, PARAM_OSC_PSCALE, &osc_pscale) < 0 - || stk500v2_getparm(pgm, PARAM_OSC_CMATCH, &osc_cmatch) < 0) + + if(stk500v2_getparm(pgm, PARAM_OSC_PSCALE, &osc_pscale) < 0 || + stk500v2_getparm(pgm, PARAM_OSC_CMATCH, &osc_cmatch) < 0) { + return -1; + } if(osc_pscale) { int prescale = 1; - f_get = PDATA(pgm)->xtal / 2; - switch (osc_pscale) { - case 2: prescale = 8; break; - case 3: prescale = 32; break; - case 4: prescale = 64; break; - case 5: prescale = 128; break; - case 6: prescale = 256; break; - case 7: prescale = 1024; break; + + f_get = my.xtal/2; + switch(osc_pscale) { + case 2: + prescale = 8; + break; + case 3: + prescale = 32; + break; + case 4: + prescale = 64; + break; + case 5: + prescale = 128; + break; + case 6: + prescale = 256; + break; + case 7: + prescale = 1024; + break; } f_get /= prescale; f_get /= (osc_cmatch + 1); f_get = f_to_kHz_MHz(f_get, &unit_get); } - if (PDATA(pgm)->fosc_get) - msg_info("Oscillator currently set to %.3f %s\n", f_get, unit_get); + if(my.fosc_get) + msg_info("Oscillator currently set to %.3f %s\n", f_get, unit_get); // Write target voltage value else { const char *unit_set; - double f_set = f_to_kHz_MHz(PDATA(pgm)->fosc_data, &unit_set); + double f_set = f_to_kHz_MHz(my.fosc_data, &unit_set); + msg_info("Changing oscillator frequency from %.3f %s to %.3f %s\n", f_get, unit_get, f_set, unit_set); - if(pgm->set_fosc(pgm, PDATA(pgm)->fosc_data) < 0) + if(pgm->set_fosc(pgm, my.fosc_data) < 0) return -1; } - } else if(PDATA(pgm)->pgmtype == PGMTYPE_STK600) { + } else if(my.pgmtype == PGMTYPE_STK600) { // Read current target voltage set value unsigned int clock_conf = 0; - if (stk500v2_getparm2(pgm, PARAM2_CLOCK_CONF, &clock_conf) < 0) + + if(stk500v2_getparm2(pgm, PARAM2_CLOCK_CONF, &clock_conf) < 0) return -1; unsigned int oct = (clock_conf & 0xf000) >> 12u; unsigned int dac = (clock_conf & 0x0ffc) >> 2u; - double f_get = pow(2, (double)oct) * 2078.0 / (2 - (double)dac / 1024.0); - const char *unit_get = {"Hz"}; + double f_get = pow(2, (double) oct)*2078.0/(2 - (double) dac/1024.0); + const char *unit_get = { "Hz" }; f_get = f_to_kHz_MHz(f_get, &unit_get); - if (PDATA(pgm)->fosc_get) - msg_info("Oscillator currently set to %.3f %s\n", f_get, unit_get); + if(my.fosc_get) + msg_info("Oscillator currently set to %.3f %s\n", f_get, unit_get); // Write target voltage value else { const char *unit_set; - double f_set = f_to_kHz_MHz(PDATA(pgm)->fosc_data, &unit_set); + double f_set = f_to_kHz_MHz(my.fosc_data, &unit_set); + msg_info("Changing oscillator frequency from %.3f %s to %.3f %s\n", f_get, unit_get, f_set, unit_set); - if(pgm->set_fosc(pgm, PDATA(pgm)->fosc_data) < 0) + if(pgm->set_fosc(pgm, my.fosc_data) < 0) return -1; } } } /* - * Examine the avrpart's memory definitions, and initialize the page - * caches. For devices/memory that are not page oriented, treat - * them as page size 1 for EEPROM, and 2 for flash. + * Examine the avrpart's memory definitions, and initialize the page caches. + * For devices/memory that are not page oriented, treat them as page size 1 + * for EEPROM, and 2 for flash. */ - PDATA(pgm)->flash_pagesize = 2; - PDATA(pgm)->eeprom_pagesize = 1; - for (ln = lfirst(p->mem); ln; ln = lnext(ln)) { + my.flash_pagesize = 2; + my.eeprom_pagesize = 1; + for(ln = lfirst(p->mem); ln; ln = lnext(ln)) { m = ldata(ln); - if (mem_is_flash(m)) { - if (m->page_size > 1) { - if (m->page_size > 256) - PDATA(pgm)->flash_pagesize = 256; + if(mem_is_flash(m)) { + if(m->page_size > 1) { + if(m->page_size > 256) + my.flash_pagesize = 256; else - PDATA(pgm)->flash_pagesize = m->page_size; + my.flash_pagesize = m->page_size; } - } else if (mem_is_eeprom(m)) { - if (m->page_size > 1) - PDATA(pgm)->eeprom_pagesize = m->page_size; + } else if(mem_is_eeprom(m)) { + if(m->page_size > 1) + my.eeprom_pagesize = m->page_size; } } - mmt_free(PDATA(pgm)->flash_pagecache); - mmt_free(PDATA(pgm)->eeprom_pagecache); - PDATA(pgm)->flash_pagecache = mmt_malloc(PDATA(pgm)->flash_pagesize); - PDATA(pgm)->eeprom_pagecache = mmt_malloc(PDATA(pgm)->eeprom_pagesize); - PDATA(pgm)->flash_pageaddr = PDATA(pgm)->eeprom_pageaddr = ~0UL; + mmt_free(my.flash_pagecache); + mmt_free(my.eeprom_pagecache); + my.flash_pagecache = mmt_malloc(my.flash_pagesize); + my.eeprom_pagecache = mmt_malloc(my.eeprom_pagesize); + my.flash_pageaddr = my.eeprom_pageaddr = ~0UL; return pgm->program_enable(pgm, p); } -/* - * initialize the AVR device and prepare it to accept commands, PP mode - */ +// Initialize the AVR device and prepare it to accept commands, PP mode static int stk500pp_initialize(const PROGRAMMER *pgm, const AVRPART *p) { return stk500hv_initialize(pgm, p, PPMODE); } -/* - * initialize the AVR device and prepare it to accept commands, HVSP mode - */ +// Initialize the AVR device and prepare it to accept commands, HVSP mode static int stk500hvsp_initialize(const PROGRAMMER *pgm, const AVRPART *p) { return stk500hv_initialize(pgm, p, HVSPMODE); } @@ -1643,18 +1631,18 @@ static void stk500v2_jtag3_disable(const PROGRAMMER *pgm) { unsigned char buf[16]; int result; - mmt_free(PDATA(pgm)->flash_pagecache); - PDATA(pgm)->flash_pagecache = NULL; - mmt_free(PDATA(pgm)->eeprom_pagecache); - PDATA(pgm)->eeprom_pagecache = NULL; + mmt_free(my.flash_pagecache); + my.flash_pagecache = NULL; + mmt_free(my.eeprom_pagecache); + my.eeprom_pagecache = NULL; buf[0] = CMD_LEAVE_PROGMODE_ISP; - buf[1] = 1; // preDelay; - buf[2] = 1; // postDelay; + buf[1] = 1; // preDelay; + buf[2] = 1; // postDelay; result = stk500v2_command(pgm, buf, 3, sizeof(buf)); - if (result < 0) { + if(result < 0) { pmsg_error("unable to leave programming mode\n"); } @@ -1666,56 +1654,48 @@ static void stk500v2_disable(const PROGRAMMER *pgm) { int result; buf[0] = CMD_LEAVE_PROGMODE_ISP; - buf[1] = 1; // preDelay; - buf[2] = 1; // postDelay; + buf[1] = 1; // preDelay; + buf[2] = 1; // postDelay; result = stk500v2_command(pgm, buf, 3, sizeof(buf)); - if (result < 0) { + if(result < 0) { pmsg_error("unable to leave programming mode\n"); } return; } -/* - * Leave programming mode, generic HV mode - */ +// Leave programming mode, generic HV mode static void stk500hv_disable(const PROGRAMMER *pgm, enum hvmode mode) { unsigned char buf[16]; int result; - mmt_free(PDATA(pgm)->flash_pagecache); - PDATA(pgm)->flash_pagecache = NULL; - mmt_free(PDATA(pgm)->eeprom_pagecache); - PDATA(pgm)->eeprom_pagecache = NULL; + mmt_free(my.flash_pagecache); + my.flash_pagecache = NULL; + mmt_free(my.eeprom_pagecache); + my.eeprom_pagecache = NULL; buf[0] = mode == PPMODE? CMD_LEAVE_PROGMODE_PP: - (PDATA(pgm)->pgmtype == PGMTYPE_STK600? - CMD_LEAVE_PROGMODE_HVSP_STK600: - CMD_LEAVE_PROGMODE_HVSP); - buf[1] = 15; // p->hvleavestabdelay; - buf[2] = 15; // p->resetdelay; + (my.pgmtype == PGMTYPE_STK600? CMD_LEAVE_PROGMODE_HVSP_STK600: CMD_LEAVE_PROGMODE_HVSP); + buf[1] = 15; // p->hvleavestabdelay; + buf[2] = 15; // p->resetdelay; result = stk500v2_command(pgm, buf, 3, sizeof(buf)); - if (result < 0) { + if(result < 0) { pmsg_error("unable to leave programming mode\n"); } return; } -/* - * Leave programming mode, PP mode - */ +// Leave programming mode, PP mode static void stk500pp_disable(const PROGRAMMER *pgm) { stk500hv_disable(pgm, PPMODE); } -/* - * Leave programming mode, HVSP mode - */ +// Leave programming mode, HVSP mode static void stk500hvsp_disable(const PROGRAMMER *pgm) { stk500hv_disable(pgm, HVSPMODE); } @@ -1723,18 +1703,18 @@ static void stk500hvsp_disable(const PROGRAMMER *pgm) { static void stk500v2_enable(PROGRAMMER *pgm, const AVRPART *p) { // Previously stk500v2_initialize() set up pgm if(pgm->initialize == stk500v2_initialize) { - if((PDATA(pgm)->pgmtype == PGMTYPE_STK600 || - PDATA(pgm)->pgmtype == PGMTYPE_AVRISP_MKII || - PDATA(pgm)->pgmtype == PGMTYPE_JTAGICE_MKII) != 0 - && (p->prog_modes & (PM_PDI | PM_TPI)) != 0) { + if((my.pgmtype == PGMTYPE_STK600 || + my.pgmtype == PGMTYPE_AVRISP_MKII || + my.pgmtype == PGMTYPE_JTAGICE_MKII) != 0 && (p->prog_modes & (PM_PDI | PM_TPI)) != 0) { stk600_setup_xprog(pgm); } else { stk600_setup_isp(pgm); } } AVRMEM *mem = avr_locate_flash(p); - if(mem && mem->op[AVR_OP_WRITE_LO]) // Old part that can only write flash bytewise - if(mem->page_size < 2) // Override page size, as STK500v2/EDBG uses flash word addresses + + if(mem && mem->op[AVR_OP_WRITE_LO]) // Old part that can only write flash bytewise + if(mem->page_size < 2) // Override page size, as STK500v2/EDBG uses flash word addresses mem->page_size = 2; return; @@ -1744,72 +1724,74 @@ static int stk500v2_parseextparms(const PROGRAMMER *pgm, const LISTID extparms) int rv = 0; bool help = false; - for (LNODEID ln = lfirst(extparms); ln; ln = lnext(ln)) { + for(LNODEID ln = lfirst(extparms); ln; ln = lnext(ln)) { const char *extended_param = ldata(ln); - if (str_starts(extended_param, "vtarg")) { - if (pgm->extra_features & HAS_VTARG_ADJ) { + if(str_starts(extended_param, "vtarg")) { + if(pgm->extra_features & HAS_VTARG_ADJ) { // Set target voltage - if (str_starts(extended_param, "vtarg=") ) { - double vtarg_set_val = -1; // default = invalid value + if(str_starts(extended_param, "vtarg=")) { + double vtarg_set_val = -1; // Default = invalid value int sscanf_success = sscanf(extended_param, "vtarg=%lf", &vtarg_set_val); - PDATA(pgm)->vtarg_data = (double)((int)(vtarg_set_val * 100 + .5)) / 100; - if (sscanf_success < 1 || vtarg_set_val < 0) { + + my.vtarg_data = (double) ((int) (vtarg_set_val*100 + .5))/100; + if(sscanf_success < 1 || vtarg_set_val < 0) { pmsg_error("invalid value in -x %s\n", extended_param); rv = -1; break; } - PDATA(pgm)->vtarg_set = true; + my.vtarg_set = true; continue; } // Get target voltage else if(str_eq(extended_param, "vtarg")) { - PDATA(pgm)->vtarg_get = true; + my.vtarg_get = true; continue; } } } - if (str_starts(extended_param, "varef")) { - if (pgm->extra_features & HAS_VAREF_ADJ) { + if(str_starts(extended_param, "varef")) { + if(pgm->extra_features & HAS_VAREF_ADJ) { int sscanf_success = 0; double varef_set_val = -1; + // Get new analog reference voltage for channel 0 - if (str_starts(extended_param, "varef=")) { + if(str_starts(extended_param, "varef=")) { sscanf_success = sscanf(extended_param, "varef=%lf", &varef_set_val); - PDATA(pgm)->varef_channel = 0; - PDATA(pgm)->varef_set = true; + my.varef_channel = 0; + my.varef_set = true; } // Get new analog reference voltage for channel 0 else if(str_starts(extended_param, "varef0=")) { sscanf_success = sscanf(extended_param, "varef0=%lf", &varef_set_val); - PDATA(pgm)->varef_channel = 0; - PDATA(pgm)->varef_set = true; + my.varef_channel = 0; + my.varef_set = true; } // Get new analog reference voltage for channel 1 - else if (str_starts(extended_param, "varef1=") && str_contains(pgm->type, "STK600")) { + else if(str_starts(extended_param, "varef1=") && str_contains(pgm->type, "STK600")) { sscanf_success = sscanf(extended_param, "varef1=%lf", &varef_set_val); - PDATA(pgm)->varef_channel = 1; - PDATA(pgm)->varef_set = true; + my.varef_channel = 1; + my.varef_set = true; } // Get current analog reference voltage for channel 0 else if(str_eq(extended_param, "varef") || str_eq(extended_param, "varef0")) { - PDATA(pgm)->varef_get = true; - PDATA(pgm)->varef_channel = 0; + my.varef_get = true; + my.varef_channel = 0; continue; } // Get current analog reference voltage for channel 1 else if(str_eq(extended_param, "varef1") && str_contains(pgm->type, "STK600")) { - PDATA(pgm)->varef_get = true; - PDATA(pgm)->varef_channel = 1; + my.varef_get = true; + my.varef_channel = 1; continue; } // Set analog reference voltage - if (PDATA(pgm)->varef_set) { - PDATA(pgm)->varef_data = (double)((int)(varef_set_val * 100 + .5)) / 100; - if (sscanf_success < 1 || varef_set_val < 0) { + if(my.varef_set) { + my.varef_data = (double) ((int) (varef_set_val*100 + .5))/100; + if(sscanf_success < 1 || varef_set_val < 0) { pmsg_error("invalid value in -x %s\n", extended_param); - PDATA(pgm)->varef_set = false; + my.varef_set = false; rv = -1; break; } @@ -1818,98 +1800,101 @@ static int stk500v2_parseextparms(const PROGRAMMER *pgm, const LISTID extparms) } } - if (str_starts(extended_param, "fosc")) { - if (pgm->extra_features & HAS_FOSC_ADJ) { + if(str_starts(extended_param, "fosc")) { + if(pgm->extra_features & HAS_FOSC_ADJ) { // Set clock generator frequency - if (str_starts(extended_param, "fosc=")) { - char fosc_str[16] = {0}; + if(str_starts(extended_param, "fosc=")) { + char fosc_str[16] = { 0 }; int sscanf_success = sscanf(extended_param, "fosc=%15[0-9.eE MmKkHhZzof]", fosc_str); - if (sscanf_success < 1) { + + if(sscanf_success < 1) { pmsg_error("invalid value in -x %s\n", extended_param); rv = -1; break; } char *endp; double v = strtod(fosc_str, &endp); - if (endp == fosc_str){ // no number - while ( *endp == ' ' ) // remove leading spaces + + if(endp == fosc_str) { // No number + while(*endp == ' ') // Remove leading spaces ++endp; - if (str_starts(endp, "off")) - PDATA(pgm)->fosc_data = 0.0; + if(str_starts(endp, "off")) + my.fosc_data = 0.0; else { pmsg_error("invalid fosc value %s\n", endp); rv = -1; break; } } - while ( *endp == ' ' ) // remove leading spaces before unit + while(*endp == ' ') // Remove leading spaces before unit ++endp; - if (*endp == 'm' || *endp == 'M') - PDATA(pgm)->fosc_data = v * 1e6; - else if (*endp == 'k' || *endp == 'K') - PDATA(pgm)->fosc_data = v * 1e3; - else if (*endp == 0 || *endp == 'h' || *endp == 'H' || *endp == 0) - PDATA(pgm)->fosc_data = v; - PDATA(pgm)->fosc_set = true; + if(*endp == 'm' || *endp == 'M') + my.fosc_data = v*1e6; + else if(*endp == 'k' || *endp == 'K') + my.fosc_data = v*1e3; + else if(*endp == 0 || *endp == 'h' || *endp == 'H' || *endp == 0) + my.fosc_data = v; + my.fosc_set = true; continue; } // Get clock generator frequency else if(str_eq(extended_param, "fosc")) { - PDATA(pgm)->fosc_get = true; - continue; + my.fosc_get = true; + continue; } } } - if (str_starts(extended_param, "xtal")) { + if(str_starts(extended_param, "xtal")) { // Set clock generator frequency - if (str_starts(extended_param, "xtal=")) { - char xtal_str[16] = {0}; + if(str_starts(extended_param, "xtal=")) { + char xtal_str[16] = { 0 }; int sscanf_success = sscanf(extended_param, "xtal=%15[0-9.eE MmKkHhZz]", xtal_str); - if (sscanf_success < 1) { + + if(sscanf_success < 1) { pmsg_error("invalid value in -x %s\n", extended_param); rv = -1; break; } char *endp; double v = strtod(xtal_str, &endp); - if (endp == xtal_str){ + + if(endp == xtal_str) { pmsg_error("invalid xtal value %s\n", xtal_str); rv = -1; break; } - while ( *endp == ' ' ) // remove leading spaces before unit + while(*endp == ' ') // Remove leading spaces before unit ++endp; - if (*endp == 'm' || *endp == 'M') // fits also e.g. "nnnnMHz" - PDATA(pgm)->xtal = v * 1e6; - else if (*endp == 'k' || *endp == 'K') - PDATA(pgm)->xtal = v * 1e3; - else if (*endp == 0 || *endp == 'h' || *endp == 'H') // "nnnn" or "nnnnHz" - PDATA(pgm)->xtal = (unsigned)v; + if(*endp == 'm' || *endp == 'M') // Fits also e.g. "nnnnMHz" + my.xtal = v*1e6; + else if(*endp == 'k' || *endp == 'K') + my.xtal = v*1e3; + else if(*endp == 0 || *endp == 'h' || *endp == 'H') // "nnnn" or "nnnnHz" + my.xtal = (unsigned) v; continue; } } - if (str_eq(extended_param, "help")) { + if(str_eq(extended_param, "help")) { help = true; rv = LIBAVRDUDE_EXIT; } - if (!help) { + if(!help) { pmsg_error("invalid extended parameter -x %s\n", extended_param); rv = -1; } msg_error("%s -c %s extended options:\n", progname, pgmid); - if (pgm->extra_features & HAS_VTARG_ADJ) { + if(pgm->extra_features & HAS_VTARG_ADJ) { msg_error(" -x vtarg Read target supply voltage\n"); msg_error(" -x vtarg= Set target supply voltage to V\n"); } - if (pgm->extra_features & HAS_VAREF_ADJ) { - if (str_contains(pgm->type, "STK500")) { + if(pgm->extra_features & HAS_VAREF_ADJ) { + if(str_contains(pgm->type, "STK500")) { msg_error(" -x varef Read analog reference voltage\n"); msg_error(" -x varef= Set analog reference voltage to V\n"); - } - else if (str_contains(pgm->type, "STK600")) { + } else if(str_contains(pgm->type, "STK600")) { msg_error(" -x varef Read channel 0 analog reference voltage\n"); msg_error(" -x varef0 Alias for -x varef\n"); msg_error(" -x varef1 Read channel 1 analog reference voltage\n"); @@ -1918,7 +1903,7 @@ static int stk500v2_parseextparms(const PROGRAMMER *pgm, const LISTID extparms) msg_error(" -x varef1= Set channel 1 analog reference voltage to V\n"); } } - if (pgm->extra_features & HAS_FOSC_ADJ) { + if(pgm->extra_features & HAS_FOSC_ADJ) { msg_error(" -x fosc Read oscillator clock frequency\n"); msg_error(" -x fosc=[unit] Set oscillator clock frequency to Hz (or kHz/MHz)\n"); msg_error(" -x fosc=off Switch the oscillator clock off\n"); @@ -1947,22 +1932,21 @@ static int stk500v2_jtag3_parseextparms(const PROGRAMMER *pgm, const LISTID extp if(pgm->extra_features & HAS_SUFFER) { // Set SUFFER value if(str_starts(extended_param, "suffer=")) { - if(sscanf(extended_param, "suffer=%hhi", PDATA(pgm)->suffer_data+1) < 1) { + if(sscanf(extended_param, "suffer=%hhi", my.suffer_data + 1) < 1) { pmsg_error("invalid value in -x %s\n", extended_param); rv = -1; break; } - if((PDATA(pgm)->suffer_data[1] & 0x78) != 0x78) { - PDATA(pgm)->suffer_data[1] |= 0x78; - pmsg_info("setting -x suffer=0x%02x so that reserved bits 3..6 are set\n", - PDATA(pgm)->suffer_data[1]); + if((my.suffer_data[1] & 0x78) != 0x78) { + my.suffer_data[1] |= 0x78; + pmsg_info("setting -x suffer=0x%02x so that reserved bits 3..6 are set\n", my.suffer_data[1]); } - PDATA(pgm)->suffer_set = true; + my.suffer_set = true; continue; } // Get SUFFER value if(str_eq(extended_param, "suffer")) { - PDATA(pgm)->suffer_get = true; + my.suffer_get = true; continue; } pmsg_error("invalid setting in -x %s; use -x suffer or -x suffer=\n", extended_param); @@ -1975,18 +1959,19 @@ static int stk500v2_jtag3_parseextparms(const PROGRAMMER *pgm, const LISTID extp if(pgm->extra_features & HAS_VTARG_SWITCH) { // Set Vtarget switch value if(str_starts(extended_param, "vtarg_switch=")) { - int sscanf_success = sscanf(extended_param, "vtarg_switch=%hhi", PDATA(pgm)->vtarg_switch_data+1); - if(sscanf_success < 1 || PDATA(pgm)->vtarg_switch_data[1] > 1) { + int sscanf_success = sscanf(extended_param, "vtarg_switch=%hhi", my.vtarg_switch_data + 1); + + if(sscanf_success < 1 || my.vtarg_switch_data[1] > 1) { pmsg_error("invalid value in -x %s\n", extended_param); rv = -1; break; } - PDATA(pgm)->vtarg_switch_set = true; + my.vtarg_switch_set = true; continue; } // Get Vtarget switch value if(str_eq(extended_param, "vtarg_switch")) { - PDATA(pgm)->vtarg_switch_get = true; + my.vtarg_switch_get = true; continue; } pmsg_error("invalid setting in -x %s; use -x vtarg_switch or -x vtarg_switch=<0..1>\n", extended_param); @@ -1998,21 +1983,22 @@ static int stk500v2_jtag3_parseextparms(const PROGRAMMER *pgm, const LISTID extp if(str_starts(extended_param, "vtarg")) { if(pgm->extra_features & HAS_VTARG_ADJ) { // Set target voltage - if(str_starts(extended_param, "vtarg=") ) { + if(str_starts(extended_param, "vtarg=")) { double vtarg_set_val = 0; int sscanf_success = sscanf(extended_param, "vtarg=%lf", &vtarg_set_val); - PDATA(pgm)->vtarg_data = (double)((int)(vtarg_set_val * 100 + .5)) / 100; + + my.vtarg_data = (double) ((int) (vtarg_set_val*100 + .5))/100; if(sscanf_success < 1 || vtarg_set_val < 0) { pmsg_error("invalid value in -x %s\n", extended_param); rv = -1; break; } - PDATA(pgm)->vtarg_set = true; + my.vtarg_set = true; continue; } // Get target voltage else if(str_eq(extended_param, "vtarg")) { - PDATA(pgm)->vtarg_get = true; + my.vtarg_get = true; continue; } pmsg_error("invalid setting in -x %s; use -x vtarg or -x vtarg=\n", extended_param); @@ -2021,16 +2007,15 @@ static int stk500v2_jtag3_parseextparms(const PROGRAMMER *pgm, const LISTID extp } } - if(str_starts(extended_param, "mode") && - (str_starts(pgmid, "pickit4") || str_starts(pgmid, "snap"))) { + if(str_starts(extended_param, "mode") && (str_starts(pgmid, "pickit4") || str_starts(pgmid, "snap"))) { // Flag a switch to AVR mode if(str_caseeq(extended_param, "mode=avr")) { - PDATA(pgm)->pk4_snap_mode = PK4_SNAP_MODE_AVR; + my.pk4_snap_mode = PK4_SNAP_MODE_AVR; continue; } // Flag a switch to PIC mode if(str_caseeq(extended_param, "mode=pic")) { - PDATA(pgm)->pk4_snap_mode = PK4_SNAP_MODE_PIC; + my.pk4_snap_mode = PK4_SNAP_MODE_PIC; continue; } pmsg_error("invalid setting in -x %s; use -x mode=avr or -x mode=pic\n", extended_param); @@ -2062,13 +2047,12 @@ static int stk500v2_jtag3_parseextparms(const PROGRAMMER *pgm, const LISTID extp } if(str_starts(pgmid, "pickit4") || str_starts(pgmid, "snap")) msg_error(" -x mode=avr|pic Set programmer to AVR or PIC mode, then exit\n"); - msg_error (" -x help Show this help menu and exit\n"); + msg_error(" -x help Show this help menu and exit\n"); return rv; } return rv; } - // ScratchMonkey LED functions (Arduino Micro, Nano and UNO) enum { SCRATCHMONKEY_RDY_LED = 1, // D5 (green) @@ -2080,11 +2064,11 @@ enum { static void scratchmonkey_led_state(const PROGRAMMER *pgm, int flag, int value) { if(value) - PDATA(pgm)->scratchmonkey_leds |= flag; + my.scratchmonkey_leds |= flag; else - PDATA(pgm)->scratchmonkey_leds &= ~flag; + my.scratchmonkey_leds &= ~flag; - stk500v2_setparm_real(pgm, PARAM_SCRATCHMONKEY_STATUS_LEDS, PDATA(pgm)->scratchmonkey_leds); + stk500v2_setparm_real(pgm, PARAM_SCRATCHMONKEY_STATUS_LEDS, my.scratchmonkey_leds); } static int scratchmonkey_rdy_led(const PROGRAMMER *pgm, int value) { @@ -2108,19 +2092,20 @@ static int scratchmonkey_vfy_led(const PROGRAMMER *pgm, int value) { } static int stk500v2_open(PROGRAMMER *pgm, const char *port) { - union pinfo pinfo = { .serialinfo.baud = 115200, .serialinfo.cflags = SERIAL_8N1 }; + union pinfo pinfo = {.serialinfo.baud = 115200,.serialinfo.cflags = SERIAL_8N1 }; DEBUG("STK500V2: stk500v2_open()\n"); - if (pgm->baudrate) + if(pgm->baudrate) pinfo.serialinfo.baud = pgm->baudrate; - PDATA(pgm)->pgmtype = PGMTYPE_UNKNOWN; + my.pgmtype = PGMTYPE_UNKNOWN; + + if(str_caseeq(port, "avrdoper")) { - if(str_caseeq(port, "avrdoper")){ #if defined(HAVE_LIBHIDAPI) serdev = &avrdoper_serdev; - PDATA(pgm)->pgmtype = PGMTYPE_STK500; + my.pgmtype = PGMTYPE_STK500; #else pmsg_error("avrdoper requires avrdude with libhidapi support\n"); return -1; @@ -2128,23 +2113,23 @@ static int stk500v2_open(PROGRAMMER *pgm, const char *port) { } /* - * If the port name starts with "usb", divert the serial routines - * to the USB ones. The serial_open() function for USB overrides - * the meaning of the "baud" parameter to be the USB device ID to - * search for. + * If the port name starts with "usb", divert the serial routines to the USB + * ones. The serial_open() function for USB overrides the meaning of the + * "baud" parameter to be the USB device ID to search for. */ - if (str_starts(port, "usb")) { + if(str_starts(port, "usb")) { + #if defined(HAVE_LIBUSB) serdev = &usb_serdev_frame; pinfo.usbinfo.vid = USB_VENDOR_ATMEL; pinfo.usbinfo.flags = 0; pinfo.usbinfo.pid = USB_DEVICE_AVRISPMKII; - PDATA(pgm)->pgmtype = PGMTYPE_AVRISP_MKII; + my.pgmtype = PGMTYPE_AVRISP_MKII; pgm->set_sck_period = stk500v2_set_sck_period_mk2; pgm->fd.usb.max_xfer = USBDEV_MAX_XFER_MKII; pgm->fd.usb.rep = USBDEV_BULK_EP_READ_MKII; pgm->fd.usb.wep = USBDEV_BULK_EP_WRITE_MKII; - pgm->fd.usb.eep = 0; /* no seperate EP for events */ + pgm->fd.usb.eep = 0; // No seperate EP for events #else pmsg_error("avrdude was compiled without usb support\n"); return -1; @@ -2152,15 +2137,15 @@ static int stk500v2_open(PROGRAMMER *pgm, const char *port) { } pgm->port = port; - if (serial_open(port, pinfo, &pgm->fd)==-1) { + if(serial_open(port, pinfo, &pgm->fd) == -1) { return -1; } // Make USB serial number and USB product name available to programmer - if (serdev) { - if (serdev->usbsn) + if(serdev) { + if(serdev->usbsn) pgm->usbsn = serdev->usbsn; - if (serdev->usbproduct) + if(serdev->usbproduct) pgm->usbproduct = serdev->usbproduct; } @@ -2168,12 +2153,12 @@ static int stk500v2_open(PROGRAMMER *pgm, const char *port) { if(stk500v2_drain(pgm, 0) < 0 || stk500v2_getsync(pgm) < 0 || stk500v2_drain(pgm, 0) < 0) return -1; - if (pgm->bitclock != 0.0) { - if (pgm->set_sck_period(pgm, pgm->bitclock) != 0) + if(pgm->bitclock != 0.0) { + if(pgm->set_sck_period(pgm, pgm->bitclock) != 0) return -1; } - if(PDATA(pgm)->is_scratchmonkey) { + if(my.is_scratchmonkey) { pgm->rdy_led = scratchmonkey_rdy_led; pgm->err_led = scratchmonkey_err_led; pgm->pgm_led = scratchmonkey_pgm_led; @@ -2183,35 +2168,34 @@ static int stk500v2_open(PROGRAMMER *pgm, const char *port) { return 0; } - static int stk600_open(PROGRAMMER *pgm, const char *port) { - union pinfo pinfo = { .serialinfo.baud = 115200, .serialinfo.cflags = SERIAL_8N1 }; + union pinfo pinfo = {.serialinfo.baud = 115200,.serialinfo.cflags = SERIAL_8N1 }; DEBUG("STK500V2: stk600_open()\n"); - if (pgm->baudrate) + if(pgm->baudrate) pinfo.serialinfo.baud = pgm->baudrate; - PDATA(pgm)->pgmtype = PGMTYPE_UNKNOWN; + my.pgmtype = PGMTYPE_UNKNOWN; /* - * If the port name starts with "usb", divert the serial routines - * to the USB ones. The serial_open() function for USB overrides - * the meaning of the "baud" parameter to be the USB device ID to - * search for. + * If the port name starts with "usb", divert the serial routines to the USB + * ones. The serial_open() function for USB overrides the meaning of the + * "baud" parameter to be the USB device ID to search for. */ - if (str_starts(port, "usb")) { + if(str_starts(port, "usb")) { + #if defined(HAVE_LIBUSB) serdev = &usb_serdev_frame; pinfo.usbinfo.vid = USB_VENDOR_ATMEL; pinfo.usbinfo.flags = 0; pinfo.usbinfo.pid = USB_DEVICE_STK600; - PDATA(pgm)->pgmtype = PGMTYPE_STK600; + my.pgmtype = PGMTYPE_STK600; pgm->set_sck_period = stk600_set_sck_period; pgm->fd.usb.max_xfer = USBDEV_MAX_XFER_MKII; pgm->fd.usb.rep = USBDEV_BULK_EP_READ_STK600; pgm->fd.usb.wep = USBDEV_BULK_EP_WRITE_STK600; - pgm->fd.usb.eep = 0; /* no seperate EP for events */ + pgm->fd.usb.eep = 0; // No seperate EP for events #else pmsg_error("avrdude was compiled without usb support\n"); return -1; @@ -2219,7 +2203,7 @@ static int stk600_open(PROGRAMMER *pgm, const char *port) { } pgm->port = port; - if (serial_open(port, pinfo, &pgm->fd)==-1) { + if(serial_open(port, pinfo, &pgm->fd) == -1) { return -1; } @@ -2227,15 +2211,14 @@ static int stk600_open(PROGRAMMER *pgm, const char *port) { if(stk500v2_drain(pgm, 0) < 0 || stk500v2_getsync(pgm) < 0 || stk500v2_drain(pgm, 0) < 0) return -1; - if (pgm->bitclock != 0.0) { - if (pgm->set_sck_period(pgm, pgm->bitclock) != 0) + if(pgm->bitclock != 0.0) { + if(pgm->set_sck_period(pgm, pgm->bitclock) != 0) return -1; } return 0; } - static void stk500v2_close(PROGRAMMER *pgm) { DEBUG("STK500V2: stk500v2_close()\n"); @@ -2243,12 +2226,11 @@ static void stk500v2_close(PROGRAMMER *pgm) { pgm->fd.ifd = -1; } - static int stk500v2_loadaddr(const PROGRAMMER *pgm, unsigned int addr) { unsigned char buf[16]; int result; - DEBUG("STK500V2: stk500v2_loadaddr(%d)\n",addr); + DEBUG("STK500V2: stk500v2_loadaddr(%d)\n", addr); buf[0] = CMD_LOAD_ADDRESS; buf[1] = (addr >> 24) & 0xff; @@ -2258,7 +2240,7 @@ static int stk500v2_loadaddr(const PROGRAMMER *pgm, unsigned int addr) { result = stk500v2_command(pgm, buf, 5, sizeof(buf)); - if (result < 0) { + if(result < 0) { pmsg_error("unable to set load address\n"); return -1; } @@ -2266,14 +2248,9 @@ static int stk500v2_loadaddr(const PROGRAMMER *pgm, unsigned int addr) { return 0; } - -/* - * Read a single byte, generic HV mode - */ +// Read a single byte, generic HV mode static int stk500hv_read_byte(const PROGRAMMER *pgm, const AVRPART *p, const AVRMEM *mem, - unsigned long addr, unsigned char * value, - enum hvmode mode) -{ + unsigned long addr, unsigned char *value, enum hvmode mode) { int result, cmdlen = 2; unsigned char buf[266]; unsigned long paddr = 0UL, *paddr_ptr = NULL; @@ -2282,44 +2259,43 @@ static int stk500hv_read_byte(const PROGRAMMER *pgm, const AVRPART *p, const AVR pmsg_notice2("stk500hv_read_byte(.., %s, 0x%lx, ...)\n", mem->desc, addr); - if (mem_is_flash(mem)) { + if(mem_is_flash(mem)) { buf[0] = mode == PPMODE? CMD_READ_FLASH_PP: CMD_READ_FLASH_HVSP; cmdlen = 3; - pagesize = PDATA(pgm)->flash_pagesize; + pagesize = my.flash_pagesize; paddr = addr & ~(pagesize - 1); - paddr_ptr = &PDATA(pgm)->flash_pageaddr; - cache_ptr = PDATA(pgm)->flash_pagecache; + paddr_ptr = &my.flash_pageaddr; + cache_ptr = my.flash_pagecache; addrshift = 1; /* - * If bit 31 is set, this indicates that the following read/write - * operation will be performed on a memory that is larger than - * 64KBytes. This is an indication to STK500 that a load extended - * address must be executed. + * If bit 31 is set, this indicates that the following read/write operation + * will be performed on a memory that is larger than 64KBytes. This is an + * indication to STK500 that a load extended address must be executed. */ - if (mem->op[AVR_OP_LOAD_EXT_ADDR] != NULL) { + if(mem->op[AVR_OP_LOAD_EXT_ADDR] != NULL) { use_ext_addr = (1U << 31); } - } else if (mem_is_eeprom(mem)) { + } else if(mem_is_eeprom(mem)) { buf[0] = mode == PPMODE? CMD_READ_EEPROM_PP: CMD_READ_EEPROM_HVSP; cmdlen = 3; pagesize = mem->page_size; - if (pagesize == 0) + if(pagesize == 0) pagesize = 1; paddr = addr & ~(pagesize - 1); - paddr_ptr = &PDATA(pgm)->eeprom_pageaddr; - cache_ptr = PDATA(pgm)->eeprom_pagecache; - } else if (mem_is_a_fuse(mem) || mem_is_fuses(mem)) { + paddr_ptr = &my.eeprom_pageaddr; + cache_ptr = my.eeprom_pagecache; + } else if(mem_is_a_fuse(mem) || mem_is_fuses(mem)) { buf[0] = mode == PPMODE? CMD_READ_FUSE_PP: CMD_READ_FUSE_HVSP; if(mem_is_a_fuse(mem)) addr = mem_fuse_offset(mem); - } else if (mem_is_lock(mem)) { + } else if(mem_is_lock(mem)) { buf[0] = mode == PPMODE? CMD_READ_LOCK_PP: CMD_READ_LOCK_HVSP; - } else if (mem_is_calibration(mem)) { + } else if(mem_is_calibration(mem)) { buf[0] = mode == PPMODE? CMD_READ_OSCCAL_PP: CMD_READ_OSCCAL_HVSP; - } else if (mem_is_signature(mem)) { + } else if(mem_is_signature(mem)) { buf[0] = mode == PPMODE? CMD_READ_SIGNATURE_PP: CMD_READ_SIGNATURE_HVSP; - } else if (mem_is_in_sigrow(mem)) { - buf[0] = addr&1? + } else if(mem_is_in_sigrow(mem)) { + buf[0] = addr & 1? (mode == PPMODE? CMD_READ_OSCCAL_PP: CMD_READ_OSCCAL_HVSP): (mode == PPMODE? CMD_READ_SIGNATURE_PP: CMD_READ_SIGNATURE_HVSP); addr = (addr + avr_sigrow_offset(p, mem, addr))/2; @@ -2329,27 +2305,26 @@ static int stk500hv_read_byte(const PROGRAMMER *pgm, const AVRPART *p, const AVR } /* - * In HV mode, we have to use paged reads for flash and - * EEPROM, and cache the results in a page cache. + * In HV mode, we have to use paged reads for flash and EEPROM, and cache the + * results in a page cache. * - * Page cache validation is based on "{flash,eeprom}_pageaddr" - * (holding the base address of the most recent cache fill - * operation). This variable is set to ~0UL when the - * cache needs to be invalidated. + * Page cache validation is based on "{flash,eeprom}_pageaddr" (holding the + * base address of the most recent cache fill operation). This variable is + * set to ~0UL when the cache needs to be invalidated. */ - if (pagesize && paddr == *paddr_ptr) { + if(pagesize && paddr == *paddr_ptr) { *value = cache_ptr[addr & (pagesize - 1)]; return 0; } - if (cmdlen == 3) { - /* long command, fill in # of bytes */ + if(cmdlen == 3) { + // Long command, fill in # of bytes buf[1] = (pagesize >> 8) & 0xff; buf[2] = pagesize & 0xff; - /* flash and EEPROM reads require the load address command */ - if (stk500v2_loadaddr(pgm, use_ext_addr | (paddr >> addrshift)) < 0) - return -1; + // Flash and EEPROM reads require the load address command + if(stk500v2_loadaddr(pgm, use_ext_addr | (paddr >> addrshift)) < 0) + return -1; } else { buf[1] = addr; } @@ -2358,12 +2333,12 @@ static int stk500hv_read_byte(const PROGRAMMER *pgm, const AVRPART *p, const AVR result = stk500v2_command(pgm, buf, cmdlen, sizeof(buf)); - if (result < 0) { + if(result < 0) { pmsg_error("timeout/error communicating with programmer\n"); return -1; } - if (pagesize) { + if(pagesize) { *paddr_ptr = paddr; memcpy(cache_ptr, buf + 2, pagesize); *value = cache_ptr[addr & (pagesize - 1)]; @@ -2374,33 +2349,26 @@ static int stk500hv_read_byte(const PROGRAMMER *pgm, const AVRPART *p, const AVR return 0; } -/* - * Read a single byte, PP mode - */ +// Read a single byte, PP mode static int stk500pp_read_byte(const PROGRAMMER *pgm, const AVRPART *p, const AVRMEM *mem, - unsigned long addr, unsigned char * value) -{ + unsigned long addr, unsigned char *value) { return stk500hv_read_byte(pgm, p, mem, addr, value, PPMODE); } -/* - * Read a single byte, HVSP mode - */ +// Read a single byte, HVSP mode static int stk500hvsp_read_byte(const PROGRAMMER *pgm, const AVRPART *p, const AVRMEM *mem, - unsigned long addr, unsigned char * value) -{ + unsigned long addr, unsigned char *value) { return stk500hv_read_byte(pgm, p, mem, addr, value, HVSPMODE); } /* * Read a single byte, ISP mode * - * By now, only used on the JTAGICE3 which does not implement the - * CMD_SPI_MULTI SPI passthrough command. + * By now, only used on the JTAGICE3 which does not implement the CMD_SPI_MULTI + * SPI passthrough command. */ static int stk500isp_read_byte(const PROGRAMMER *pgm, const AVRPART *p, const AVRMEM *mem, - unsigned long addr, unsigned char * value) -{ + unsigned long addr, unsigned char *value) { int result, pollidx, offset = 0; unsigned char buf[6]; unsigned long paddr = 0UL, *paddr_ptr = NULL; @@ -2410,28 +2378,28 @@ static int stk500isp_read_byte(const PROGRAMMER *pgm, const AVRPART *p, const AV pmsg_notice2("stk500isp_read_byte(.., %s, 0x%lx, ...)\n", mem->desc, addr); - if (mem_is_flash(mem) || mem_is_eeprom(mem)) { - // use paged access, and cache result - if (mem_is_flash(mem)) { - pagesize = PDATA(pgm)->flash_pagesize; + if(mem_is_flash(mem) || mem_is_eeprom(mem)) { + // Use paged access, and cache result + if(mem_is_flash(mem)) { + pagesize = my.flash_pagesize; paddr = addr & ~(pagesize - 1); - paddr_ptr = &PDATA(pgm)->flash_pageaddr; - cache_ptr = PDATA(pgm)->flash_pagecache; + paddr_ptr = &my.flash_pageaddr; + cache_ptr = my.flash_pagecache; } else { pagesize = mem->page_size; - if (pagesize == 0) + if(pagesize == 0) pagesize = 1; paddr = addr & ~(pagesize - 1); - paddr_ptr = &PDATA(pgm)->eeprom_pageaddr; - cache_ptr = PDATA(pgm)->eeprom_pagecache; + paddr_ptr = &my.eeprom_pageaddr; + cache_ptr = my.eeprom_pagecache; } - if (paddr == *paddr_ptr) { + if(paddr == *paddr_ptr) { *value = cache_ptr[addr & (pagesize - 1)]; return 0; } - if (stk500v2_paged_load(pgm, p, mem, pagesize, paddr, pagesize) < 0) + if(stk500v2_paged_load(pgm, p, mem, pagesize, paddr, pagesize) < 0) return -1; *paddr_ptr = paddr; @@ -2441,31 +2409,31 @@ static int stk500isp_read_byte(const PROGRAMMER *pgm, const AVRPART *p, const AV return 0; } - if (mem_is_a_fuse(mem) || mem_is_fuses(mem)) { + if(mem_is_a_fuse(mem) || mem_is_fuses(mem)) { buf[0] = CMD_READ_FUSE_ISP; if(mem_is_a_fuse(mem)) addr = mem_fuse_offset(mem); - } else if (mem_is_lock(mem)) { + } else if(mem_is_lock(mem)) { buf[0] = CMD_READ_LOCK_ISP; - } else if (mem_is_calibration(mem)) { + } else if(mem_is_calibration(mem)) { buf[0] = CMD_READ_OSCCAL_ISP; - } else if (mem_is_signature(mem)) { + } else if(mem_is_signature(mem)) { buf[0] = CMD_READ_SIGNATURE_ISP; - } else if (mem_is_in_sigrow(mem)) { // Sernum and prodsig/sigrow (m324pb/m328pb) - buf[0] = addr&1? CMD_READ_OSCCAL_ISP: CMD_READ_SIGNATURE_ISP; + } else if(mem_is_in_sigrow(mem)) { // Sernum and prodsig/sigrow (m324pb/m328pb) + buf[0] = addr & 1? CMD_READ_OSCCAL_ISP: CMD_READ_SIGNATURE_ISP; offset = avr_sigrow_offset(p, mem, addr); } else { pmsg_error("unsupported memory %s\n", mem->desc); return -1; } - if ((op = mem->op[AVR_OP_READ]) == NULL) { + if((op = mem->op[AVR_OP_READ]) == NULL) { pmsg_error("invalid operation AVR_OP_READ on %s memory\n", mem->desc); return -1; } - memset(buf+2, 0, 4); + memset(buf + 2, 0, 4); avr_set_bits(op, buf + 2); - if ((pollidx = avr_get_output_index(op)) == -1) { + if((pollidx = avr_get_output_index(op)) == -1) { pmsg_warning("cannot determine pollidx to read %s memory\n", mem->desc); pollidx = 3; } @@ -2476,7 +2444,7 @@ static int stk500isp_read_byte(const PROGRAMMER *pgm, const AVRPART *p, const AV result = stk500v2_command(pgm, buf, 6, sizeof(buf)); - if (result < 0) { + if(result < 0) { pmsg_error("timeout/error communicating with programmer\n"); return -1; } @@ -2486,13 +2454,9 @@ static int stk500isp_read_byte(const PROGRAMMER *pgm, const AVRPART *p, const AV return 0; } -/* - * Write one byte, generic HV mode - */ +// Write one byte, generic HV mode static int stk500hv_write_byte(const PROGRAMMER *pgm, const AVRPART *p, const AVRMEM *mem, - unsigned long addr, unsigned char data, - enum hvmode mode) -{ + unsigned long addr, unsigned char data, enum hvmode mode) { int result, cmdlen, timeout = 0, pulsewidth = 0; unsigned char buf[266]; unsigned long paddr = 0UL, *paddr_ptr = NULL; @@ -2501,42 +2465,42 @@ static int stk500hv_write_byte(const PROGRAMMER *pgm, const AVRPART *p, const AV pmsg_notice2("stk500hv_write_byte(.., %s, 0x%lx, ...)\n", mem->desc, addr); - if (mem_is_flash(mem)) { + if(mem_is_flash(mem)) { buf[0] = mode == PPMODE? CMD_PROGRAM_FLASH_PP: CMD_PROGRAM_FLASH_HVSP; - pagesize = PDATA(pgm)->flash_pagesize; + pagesize = my.flash_pagesize; paddr = addr & ~(pagesize - 1); - paddr_ptr = &PDATA(pgm)->flash_pageaddr; - cache_ptr = PDATA(pgm)->flash_pagecache; + paddr_ptr = &my.flash_pageaddr; + cache_ptr = my.flash_pagecache; addrshift = 1; /* - * If bit 31 is set, this indicates that the following read/write - * operation will be performed on a memory that is larger than - * 64KBytes. This is an indication to STK500 that a load extended - * address must be executed. + * If bit 31 is set, this indicates that the following read/write operation + * will be performed on a memory that is larger than 64KBytes. This is an + * indication to STK500 that a load extended address must be executed. */ - if (mem->op[AVR_OP_LOAD_EXT_ADDR] != NULL) { + if(mem->op[AVR_OP_LOAD_EXT_ADDR] != NULL) { use_ext_addr = (1U << 31); } - } else if (mem_is_eeprom(mem)) { + } else if(mem_is_eeprom(mem)) { buf[0] = mode == PPMODE? CMD_PROGRAM_EEPROM_PP: CMD_PROGRAM_EEPROM_HVSP; pagesize = mem->page_size; - if (pagesize == 0) + if(pagesize == 0) pagesize = 1; paddr = addr & ~(pagesize - 1); - paddr_ptr = &PDATA(pgm)->eeprom_pageaddr; - cache_ptr = PDATA(pgm)->eeprom_pagecache; - } else if (mem_is_a_fuse(mem) || mem_is_fuses(mem)) { + paddr_ptr = &my.eeprom_pageaddr; + cache_ptr = my.eeprom_pagecache; + } else if(mem_is_a_fuse(mem) || mem_is_fuses(mem)) { buf[0] = mode == PPMODE? CMD_PROGRAM_FUSE_PP: CMD_PROGRAM_FUSE_HVSP; pulsewidth = p->programfusepulsewidth; timeout = p->programfusepolltimeout; if(mem_is_a_fuse(mem)) addr = mem_fuse_offset(mem); - } else if (mem_is_lock(mem)) { + } else if(mem_is_lock(mem)) { buf[0] = mode == PPMODE? CMD_PROGRAM_LOCK_PP: CMD_PROGRAM_LOCK_HVSP; pulsewidth = p->programlockpulsewidth; timeout = p->programlockpolltimeout; } else if(mem_is_readonly(mem)) { unsigned char is; + if(pgm->read_byte(pgm, p, mem, addr, &is) >= 0 && is == data) return 0; @@ -2550,35 +2514,34 @@ static int stk500hv_write_byte(const PROGRAMMER *pgm, const AVRPART *p, const AV cmdlen = 5 + pagesize; /* - * In HV mode, we have to use paged writes for flash and - * EEPROM. As both, flash and EEPROM cells can only be programmed - * from `1' to `0' bits (even EEPROM does not support auto-erase in - * parallel mode), we just pre-fill the page cache with 0xff, so all - * those cells that are outside our current address will remain - * unaffected. + * In HV mode, we have to use paged writes for flash and EEPROM. As both, + * flash and EEPROM cells can only be programmed from `1' to `0' bits (even + * EEPROM does not support auto-erase in parallel mode), we just pre-fill the + * page cache with 0xff, so all those cells that are outside our current + * address will remain unaffected. */ - if (pagesize) { + if(pagesize) { memset(cache_ptr, 0xff, pagesize); cache_ptr[addr & (pagesize - 1)] = data; - /* long command, fill in # of bytes */ + // Long command, fill in # of bytes buf[1] = (pagesize >> 8) & 0xff; buf[2] = pagesize & 0xff; /* - * Synthesize the mode byte. This is simpler than adding yet - * another parameter to the avrdude.conf file. We calculate the - * bits corresponding to the page size, as explained in AVR068. - * We set bit 7, to indicate this is to actually write the page to - * the target device. We set bit 6 to indicate this is the very - * last page to be programmed, whatever this means -- we just - * pretend we don't know any better. ;-) Bit 0 is set if this is - * a paged memory, which means it has a page size of more than 2. + * Synthesize the mode byte. This is simpler than adding yet another + * parameter to the avrdude.conf file. We calculate the bits corresponding + * to the page size, as explained in AVR068. We set bit 7, to indicate this + * is to actually write the page to the target device. We set bit 6 to + * indicate this is the very last page to be programmed, whatever this + * means -- we just pretend we don't know any better. ;-) Bit 0 is set if + * this is a paged memory, which means it has a page size of more than 2. */ buf[3] = 0x80 | 0x40; - if (pagesize > 2) { + if(pagesize > 2) { unsigned int rv = stk500v2_mode_for_pagesize(pagesize); - if (rv == 0) + + if(rv == 0) return -1; buf[3] |= rv; buf[3] |= 0x01; @@ -2586,13 +2549,13 @@ static int stk500hv_write_byte(const PROGRAMMER *pgm, const AVRPART *p, const AV buf[4] = mem->delay; memcpy(buf + 5, cache_ptr, pagesize); - /* flash and EEPROM reads require the load address command */ - if (stk500v2_loadaddr(pgm, use_ext_addr | (paddr >> addrshift)) < 0) - return -1; + // Flash and EEPROM reads require the load address command + if(stk500v2_loadaddr(pgm, use_ext_addr | (paddr >> addrshift)) < 0) + return -1; } else { buf[1] = addr; buf[2] = data; - if (mode == PPMODE) { + if(mode == PPMODE) { buf[3] = pulsewidth; buf[4] = timeout; } else { @@ -2605,44 +2568,34 @@ static int stk500hv_write_byte(const PROGRAMMER *pgm, const AVRPART *p, const AV result = stk500v2_command(pgm, buf, cmdlen, sizeof(buf)); - if (result < 0) { + if(result < 0) { pmsg_error("timeout/error communicating with programmer\n"); return -1; } - if (pagesize) { - /* Invalidate the page cache. */ + if(pagesize) { + // Invalidate the page cache *paddr_ptr = ~0UL; } return 0; } -/* - * Write one byte, PP mode - */ +// Write one byte, PP mode static int stk500pp_write_byte(const PROGRAMMER *pgm, const AVRPART *p, const AVRMEM *mem, - unsigned long addr, unsigned char data) -{ + unsigned long addr, unsigned char data) { return stk500hv_write_byte(pgm, p, mem, addr, data, PPMODE); } -/* - * Write one byte, HVSP mode - */ +// Write one byte, HVSP mode static int stk500hvsp_write_byte(const PROGRAMMER *pgm, const AVRPART *p, const AVRMEM *mem, - unsigned long addr, unsigned char data) -{ + unsigned long addr, unsigned char data) { return stk500hv_write_byte(pgm, p, mem, addr, data, HVSPMODE); } - -/* - * Write one byte, ISP mode - */ +// Write one byte, ISP mode static int stk500isp_write_byte(const PROGRAMMER *pgm, const AVRPART *p, const AVRMEM *mem, - unsigned long addr, unsigned char data) -{ + unsigned long addr, unsigned char data) { int result; unsigned char buf[5]; unsigned long paddr = 0UL, *paddr_ptr = NULL; @@ -2652,30 +2605,29 @@ static int stk500isp_write_byte(const PROGRAMMER *pgm, const AVRPART *p, const A pmsg_notice2("stk500isp_write_byte(.., %s, 0x%lx, ...)\n", mem->desc, addr); - if (mem_is_flash(mem) || mem_is_eeprom(mem)) { - if (mem_is_flash(mem)) { - pagesize = PDATA(pgm)->flash_pagesize; + if(mem_is_flash(mem) || mem_is_eeprom(mem)) { + if(mem_is_flash(mem)) { + pagesize = my.flash_pagesize; paddr = addr & ~(pagesize - 1); - paddr_ptr = &PDATA(pgm)->flash_pageaddr; - cache_ptr = PDATA(pgm)->flash_pagecache; - if ((mem->mode & 1) == 0) - /* old, unpaged device, really write single bytes */ + paddr_ptr = &my.flash_pageaddr; + cache_ptr = my.flash_pagecache; + if((mem->mode & 1) == 0) + // Old, unpaged device, really write single bytes pagesize = 1; } else { pagesize = mem->page_size; - if (pagesize == 0) + if(pagesize == 0) pagesize = 1; paddr = addr & ~(pagesize - 1); - paddr_ptr = &PDATA(pgm)->eeprom_pageaddr; - cache_ptr = PDATA(pgm)->eeprom_pagecache; + paddr_ptr = &my.eeprom_pageaddr; + cache_ptr = my.eeprom_pagecache; } /* - * We use paged writes for flash and EEPROM, reading back the - * current page first, modify the byte to write, and write out the - * entire page. + * We use paged writes for flash and EEPROM, reading back the current page + * first, modify the byte to write, and write out the entire page. */ - if (stk500v2_paged_load(pgm, p, mem, pagesize, paddr, pagesize) < 0) + if(stk500v2_paged_load(pgm, p, mem, pagesize, paddr, pagesize) < 0) return -1; memcpy(cache_ptr, mem->buf + paddr, pagesize); @@ -2689,14 +2641,15 @@ static int stk500isp_write_byte(const PROGRAMMER *pgm, const AVRPART *p, const A } memset(buf, 0, sizeof buf); - if (mem_is_a_fuse(mem) || mem_is_fuses(mem)) { + if(mem_is_a_fuse(mem) || mem_is_fuses(mem)) { buf[0] = CMD_PROGRAM_FUSE_ISP; if(mem_is_a_fuse(mem)) addr = mem_fuse_offset(mem); - } else if (mem_is_lock(mem)) { + } else if(mem_is_lock(mem)) { buf[0] = CMD_PROGRAM_LOCK_ISP; } else if(mem_is_readonly(mem)) { unsigned char is; + if(pgm->read_byte(pgm, p, mem, addr, &is) >= 0 && is == data) return 0; pmsg_error("cannot write to read-only memory %s of %s\n", mem->desc, p->desc); @@ -2706,7 +2659,7 @@ static int stk500isp_write_byte(const PROGRAMMER *pgm, const AVRPART *p, const A return -1; } - if ((op = mem->op[AVR_OP_WRITE]) == NULL) { + if((op = mem->op[AVR_OP_WRITE]) == NULL) { pmsg_error("no AVR_OP_WRITE for %s memory\n", mem->desc); return -1; } @@ -2719,7 +2672,7 @@ static int stk500isp_write_byte(const PROGRAMMER *pgm, const AVRPART *p, const A result = stk500v2_command(pgm, buf, 5, sizeof(buf)); - if (result < 0) { + if(result < 0) { pmsg_error("timeout/error communicating with programmer\n"); return -1; } @@ -2728,10 +2681,10 @@ static int stk500isp_write_byte(const PROGRAMMER *pgm, const AVRPART *p, const A * Prevent verification readback to be too fast, see * https://savannah.nongnu.org/bugs/index.php?42267 * - * After all, this is just an ugly hack working around some - * brokeness in the Atmel firmware starting with the AVRISPmkII (the - * old JTAGICEmkII isn't affected). Let's hope 10 ms of additional - * delay are good enough for everyone. + * After all, this is just an ugly hack working around some brokeness in the + * Atmel firmware starting with the AVRISPmkII (the old JTAGICEmkII isn't + * affected). Let's hope 10 ms of additional delay are good enough for + * everyone. */ usleep(10000); @@ -2739,58 +2692,54 @@ static int stk500isp_write_byte(const PROGRAMMER *pgm, const AVRPART *p, const A } static int stk500v2_paged_write(const PROGRAMMER *pgm, const AVRPART *p, const AVRMEM *m, - unsigned int page_size, - unsigned int addr, unsigned int n_bytes) -{ + unsigned int page_size, unsigned int addr, unsigned int n_bytes) { unsigned int block_size, last_addr, addrshift, use_ext_addr; unsigned int maxaddr = addr + n_bytes; unsigned char commandbuf[10]; unsigned char buf[266]; unsigned char cmds[4]; int result; - OPCODE * rop, * wop; + OPCODE *rop, *wop; - DEBUG("STK500V2: stk500v2_paged_write(..,%s,%u,%u,%u)\n", - m->desc, page_size, addr, n_bytes); + DEBUG("STK500V2: stk500v2_paged_write(..,%s,%u,%u,%u)\n", m->desc, page_size, addr, n_bytes); - if (page_size == 0) page_size = 256; + if(page_size == 0) + page_size = 256; addrshift = 0; use_ext_addr = 0; - // determine which command is to be used - if (mem_is_flash(m)) { + // Determine which command is to be used + if(mem_is_flash(m)) { addrshift = 1; - PDATA(pgm)->flash_pageaddr = ~0UL; // Invalidate cache + my.flash_pageaddr = ~0UL; // Invalidate cache commandbuf[0] = CMD_PROGRAM_FLASH_ISP; /* - * If bit 31 is set, this indicates that the following read/write - * operation will be performed on a memory that is larger than - * 64KBytes. This is an indication to STK500 that a load extended - * address must be executed. + * If bit 31 is set, this indicates that the following read/write operation + * will be performed on a memory that is larger than 64KBytes. This is an + * indication to STK500 that a load extended address must be executed. */ - if (m->op[AVR_OP_LOAD_EXT_ADDR] != NULL) { + if(m->op[AVR_OP_LOAD_EXT_ADDR] != NULL) { use_ext_addr = (1U << 31); } - } else if (mem_is_eeprom(m)) { - PDATA(pgm)->eeprom_pageaddr = ~0UL; // Invalidate cache + } else if(mem_is_eeprom(m)) { + my.eeprom_pageaddr = ~0UL; // Invalidate cache commandbuf[0] = CMD_PROGRAM_EEPROM_ISP; } commandbuf[4] = m->delay; - if (addrshift == 0) { + if(addrshift == 0) { wop = m->op[AVR_OP_WRITE]; rop = m->op[AVR_OP_READ]; - } - else { + } else { wop = m->op[AVR_OP_WRITE_LO]; rop = m->op[AVR_OP_READ_LO]; } - // if the memory is paged, load the appropriate commands into the buffer - if (m->mode & 0x01) { - commandbuf[3] = m->mode | 0x80; // yes, write the page to flash + // If the memory is paged, load the appropriate commands into the buffer + if(m->mode & 0x01) { + commandbuf[3] = m->mode | 0x80; // Yes, write the page to flash - if (m->op[AVR_OP_LOADPAGE_LO] == NULL) { + if(m->op[AVR_OP_LOADPAGE_LO] == NULL) { pmsg_error("loadpage instruction not defined for part %s\n", p->desc); return -1; } @@ -2798,7 +2747,7 @@ static int stk500v2_paged_write(const PROGRAMMER *pgm, const AVRPART *p, const A avr_set_bits(m->op[AVR_OP_LOADPAGE_LO], cmds); commandbuf[5] = cmds[0]; - if (m->op[AVR_OP_WRITEPAGE] == NULL) { + if(m->op[AVR_OP_WRITEPAGE] == NULL) { pmsg_error("write page instruction not defined for part %s\n", p->desc); return -1; } @@ -2807,12 +2756,11 @@ static int stk500v2_paged_write(const PROGRAMMER *pgm, const AVRPART *p, const A avr_set_bits(m->op[AVR_OP_WRITEPAGE], cmds); commandbuf[6] = cmds[0]; - // otherwise, we need to load different commands in - } - else { - commandbuf[3] = m->mode | 0x80; // yes, write the words to flash + // Otherwise, we need to load different commands in + } else { + commandbuf[3] = m->mode | 0x80; // Yes, write the words to flash - if (wop == NULL) { + if(wop == NULL) { pmsg_error("write instruction not defined for part %s\n", p->desc); return -1; } @@ -2822,8 +2770,8 @@ static int stk500v2_paged_write(const PROGRAMMER *pgm, const AVRPART *p, const A commandbuf[6] = 0; } - // the read command is common to both methods - if (rop == NULL) { + // The read command is common to both methods + if(rop == NULL) { pmsg_error("read instruction not defined for memory %s of part %s\n", m->desc, p->desc); return -1; } @@ -2834,35 +2782,36 @@ static int stk500v2_paged_write(const PROGRAMMER *pgm, const AVRPART *p, const A commandbuf[8] = m->readback[0]; commandbuf[9] = m->readback[1]; - last_addr=UINT_MAX; /* impossible address */ + last_addr = UINT_MAX; // Impossible address - for (; addr < maxaddr; addr += page_size) { - if ((maxaddr - addr) < page_size) + for(; addr < maxaddr; addr += page_size) { + if((maxaddr - addr) < page_size) block_size = maxaddr - addr; else block_size = page_size; - DEBUG("block_size at addr %d is %d\n",addr,block_size); + DEBUG("block_size at addr %d is %d\n", addr, block_size); - memcpy(buf,commandbuf,sizeof(commandbuf)); + memcpy(buf, commandbuf, sizeof(commandbuf)); buf[1] = block_size >> 8; buf[2] = block_size & 0xff; - if((last_addr==UINT_MAX)||(last_addr+block_size != addr)){ - if (stk500v2_loadaddr(pgm, use_ext_addr | (addr >> addrshift)) < 0) + if((last_addr == UINT_MAX) || (last_addr + block_size != addr)) { + if(stk500v2_loadaddr(pgm, use_ext_addr | (addr >> addrshift)) < 0) return -1; } - last_addr=addr; + last_addr = addr; - memcpy(buf+10,m->buf+addr, block_size); + memcpy(buf + 10, m->buf + addr, block_size); // Do not send request to write empty flash pages except for bootloaders (fixes Issue #425) - unsigned char *p = m->buf+addr; - result = (pgm->prog_modes & PM_SPM) || !addrshift || *p != 0xff || memcmp(p, p+1, block_size-1)? - stk500v2_command(pgm, buf, block_size+10, sizeof buf): 0; + unsigned char *p = m->buf + addr; - if (result < 0) { + result = is_spm(pgm) || !addrshift || *p != 0xff || memcmp(p, p + 1, block_size - 1)? + stk500v2_command(pgm, buf, block_size + 10, sizeof buf): 0; + + if(result < 0) { pmsg_error("write command failed\n"); return -1; } @@ -2871,92 +2820,86 @@ static int stk500v2_paged_write(const PROGRAMMER *pgm, const AVRPART *p, const A return n_bytes; } -/* - * Write pages of flash/EEPROM, generic HV mode - */ +// Write pages of flash/EEPROM, generic HV mode static int stk500hv_paged_write(const PROGRAMMER *pgm, const AVRPART *p, const AVRMEM *m, - unsigned int page_size, - unsigned int addr, unsigned int n_bytes, - enum hvmode mode) -{ + unsigned int page_size, unsigned int addr, unsigned int n_bytes, enum hvmode mode) { unsigned int block_size, last_addr, addrshift, use_ext_addr; unsigned int maxaddr = addr + n_bytes; unsigned char commandbuf[5], buf[266]; int result; - DEBUG("STK500V2: stk500hv_paged_write(..,%s,%u,%u,%u)\n", - m->desc, page_size, addr, n_bytes); + DEBUG("STK500V2: stk500hv_paged_write(..,%s,%u,%u,%u)\n", m->desc, page_size, addr, n_bytes); addrshift = 0; use_ext_addr = 0; - // determine which command is to be used - if (mem_is_flash(m)) { + // Determine which command is to be used + if(mem_is_flash(m)) { addrshift = 1; - PDATA(pgm)->flash_pageaddr = ~0UL; + my.flash_pageaddr = ~0UL; commandbuf[0] = mode == PPMODE? CMD_PROGRAM_FLASH_PP: CMD_PROGRAM_FLASH_HVSP; /* - * If bit 31 is set, this indicates that the following read/write - * operation will be performed on a memory that is larger than - * 64KBytes. This is an indication to STK500 that a load extended - * address must be executed. + * If bit 31 is set, this indicates that the following read/write operation + * will be performed on a memory that is larger than 64KBytes. This is an + * indication to STK500 that a load extended address must be executed. */ - if (m->op[AVR_OP_LOAD_EXT_ADDR] != NULL) { + if(m->op[AVR_OP_LOAD_EXT_ADDR] != NULL) { use_ext_addr = (1U << 31); } - } else if (mem_is_eeprom(m)) { - PDATA(pgm)->eeprom_pageaddr = ~0UL; + } else if(mem_is_eeprom(m)) { + my.eeprom_pageaddr = ~0UL; commandbuf[0] = mode == PPMODE? CMD_PROGRAM_EEPROM_PP: CMD_PROGRAM_EEPROM_HVSP; } /* - * Synthesize the mode byte. This is simpler than adding yet - * another parameter to the avrdude.conf file. We calculate the - * bits corresponding to the page size, as explained in AVR068. We - * set bit 7, to indicate this is to actually write the page to the - * target device. We set bit 6 to indicate this is the very last - * page to be programmed, whatever this means -- we just pretend we - * don't know any better. ;-) Finally, we set bit 0 to say this is - * a paged memory, after all, that's why we got here at all. + * Synthesize the mode byte. This is simpler than adding yet another + * parameter to the avrdude.conf file. We calculate the bits corresponding + * to the page size, as explained in AVR068. We set bit 7, to indicate this + * is to actually write the page to the target device. We set bit 6 to + * indicate this is the very last page to be programmed, whatever this means + * -- we just pretend we don't know any better. ;-) Finally, we set bit 0 to + * say this is a paged memory, after all, that's why we got here at all. */ commandbuf[3] = 0x80 | 0x40; - if (page_size > 2) { + if(page_size > 2) { unsigned int rv = stk500v2_mode_for_pagesize(page_size); - if (rv == 0) + + if(rv == 0) return -1; commandbuf[3] |= rv; commandbuf[3] |= 0x01; } commandbuf[4] = m->delay; - if (page_size == 0) page_size = 256; + if(page_size == 0) + page_size = 256; - last_addr = UINT_MAX; /* impossible address */ + last_addr = UINT_MAX; // Impossible address - for (; addr < maxaddr; addr += page_size) { - if ((maxaddr - addr) < page_size) + for(; addr < maxaddr; addr += page_size) { + if((maxaddr - addr) < page_size) block_size = maxaddr - addr; else block_size = page_size; - DEBUG("block_size at addr %d is %d\n",addr,block_size); + DEBUG("block_size at addr %d is %d\n", addr, block_size); memcpy(buf, commandbuf, sizeof(commandbuf)); buf[1] = page_size >> 8; buf[2] = page_size & 0xff; - if ((last_addr == UINT_MAX) || (last_addr + block_size != addr)) { - if (stk500v2_loadaddr(pgm, use_ext_addr | (addr >> addrshift)) < 0) + if((last_addr == UINT_MAX) || (last_addr + block_size != addr)) { + if(stk500v2_loadaddr(pgm, use_ext_addr | (addr >> addrshift)) < 0) return -1; } - last_addr=addr; + last_addr = addr; memcpy(buf + 5, m->buf + addr, block_size); - if (block_size != page_size) + if(block_size != page_size) memset(buf + 5 + block_size, 0xff, page_size - block_size); result = stk500v2_command(pgm, buf, page_size + 5, sizeof(buf)); - if (result < 0) { + if(result < 0) { pmsg_error("write command failed\n"); return -1; } @@ -2965,40 +2908,29 @@ static int stk500hv_paged_write(const PROGRAMMER *pgm, const AVRPART *p, const A return n_bytes; } -/* - * Write pages of flash/EEPROM, PP mode - */ +// Write pages of flash/EEPROM, PP mode static int stk500pp_paged_write(const PROGRAMMER *pgm, const AVRPART *p, const AVRMEM *m, - unsigned int page_size, - unsigned int addr, unsigned int n_bytes) -{ + unsigned int page_size, unsigned int addr, unsigned int n_bytes) { return stk500hv_paged_write(pgm, p, m, page_size, addr, n_bytes, PPMODE); } -/* - * Write pages of flash/EEPROM, HVSP mode - */ +// Write pages of flash/EEPROM, HVSP mode static int stk500hvsp_paged_write(const PROGRAMMER *pgm, const AVRPART *p, const AVRMEM *m, - unsigned int page_size, - unsigned int addr, unsigned int n_bytes) -{ + unsigned int page_size, unsigned int addr, unsigned int n_bytes) { return stk500hv_paged_write(pgm, p, m, page_size, addr, n_bytes, HVSPMODE); } static int stk500v2_paged_load(const PROGRAMMER *pgm, const AVRPART *p, const AVRMEM *m, - unsigned int page_size, - unsigned int addr, unsigned int n_bytes) -{ + unsigned int page_size, unsigned int addr, unsigned int n_bytes) { unsigned int block_size, hiaddr, addrshift, use_ext_addr; unsigned int maxaddr = addr + n_bytes; unsigned char commandbuf[4]; - unsigned char buf[275]; // max buffer size for stk500v2 at this point + unsigned char buf[275]; // Max buffer size for stk500v2 at this point unsigned char cmds[4]; int result; - OPCODE * rop; + OPCODE *rop; - DEBUG("STK500V2: stk500v2_paged_load(..,%s,%u,%u,%u)\n", - m->desc, page_size, addr, n_bytes); + DEBUG("STK500V2: stk500v2_paged_load(..,%s,%u,%u,%u)\n", m->desc, page_size, addr, n_bytes); page_size = m->readsize; @@ -3008,27 +2940,25 @@ static int stk500v2_paged_load(const PROGRAMMER *pgm, const AVRPART *p, const AV addrshift = 0; use_ext_addr = 0; - // determine which command is to be used - if (mem_is_flash(m)) { + // Determine which command is to be used + if(mem_is_flash(m)) { commandbuf[0] = CMD_READ_FLASH_ISP; rop = m->op[AVR_OP_READ_LO]; addrshift = 1; /* - * If bit 31 is set, this indicates that the following read/write - * operation will be performed on a memory that is larger than - * 64KBytes. This is an indication to STK500 that a load extended - * address must be executed. + * If bit 31 is set, this indicates that the following read/write operation + * will be performed on a memory that is larger than 64KBytes. This is an + * indication to STK500 that a load extended address must be executed. */ - if (m->op[AVR_OP_LOAD_EXT_ADDR] != NULL) { + if(m->op[AVR_OP_LOAD_EXT_ADDR] != NULL) { use_ext_addr = (1U << 31); } - } - else if (mem_is_eeprom(m)) { + } else if(mem_is_eeprom(m)) { commandbuf[0] = CMD_READ_EEPROM_ISP; } - // the read command is common to both methods - if (rop == NULL) { + // The read command is common to both methods + if(rop == NULL) { pmsg_error("read instruction not defined for memory %s of part %s\n", m->desc, p->desc); return -1; } @@ -3036,35 +2966,35 @@ static int stk500v2_paged_load(const PROGRAMMER *pgm, const AVRPART *p, const AV avr_set_bits(rop, cmds); commandbuf[3] = cmds[0]; - for (; addr < maxaddr; addr += page_size) { - if ((maxaddr - addr) < page_size) + for(; addr < maxaddr; addr += page_size) { + if((maxaddr - addr) < page_size) block_size = maxaddr - addr; else block_size = page_size; - DEBUG("block_size at addr %d is %d\n",addr,block_size); + DEBUG("block_size at addr %d is %d\n", addr, block_size); - memcpy(buf,commandbuf,sizeof(commandbuf)); + memcpy(buf, commandbuf, sizeof(commandbuf)); buf[1] = block_size >> 8; buf[2] = block_size & 0xff; - // Ensure a new "load extended address" will be issued - // when crossing a 64 KB boundary in flash. - if (hiaddr != (addr & ~0xFFFF)) { + // Ensure load extended address will be issued when crossing a 64 KB boundary in flash + if(hiaddr != (addr & ~0xFFFF)) { hiaddr = addr & ~0xFFFF; - if (stk500v2_loadaddr(pgm, use_ext_addr | (addr >> addrshift)) < 0) + if(stk500v2_loadaddr(pgm, use_ext_addr | (addr >> addrshift)) < 0) return -1; } - result = stk500v2_command(pgm,buf,4,sizeof(buf)); - if (result < 0) { + result = stk500v2_command(pgm, buf, 4, sizeof(buf)); + if(result < 0) { pmsg_error("read command failed\n"); return -1; } + #if 0 - for (i=0; idesc, page_size, addr, n_bytes); + DEBUG("STK500V2: stk500hv_paged_load(..,%s,%u,%u,%u)\n", m->desc, page_size, addr, n_bytes); page_size = m->readsize; @@ -3098,53 +3021,51 @@ static int stk500hv_paged_load(const PROGRAMMER *pgm, const AVRPART *p, const AV addrshift = 0; use_ext_addr = 0; - // determine which command is to be used - if (mem_is_flash(m)) { + // Determine which command is to be used + if(mem_is_flash(m)) { commandbuf[0] = mode == PPMODE? CMD_READ_FLASH_PP: CMD_READ_FLASH_HVSP; addrshift = 1; /* - * If bit 31 is set, this indicates that the following read/write - * operation will be performed on a memory that is larger than - * 64KBytes. This is an indication to STK500 that a load extended - * address must be executed. + * If bit 31 is set, this indicates that the following read/write operation + * will be performed on a memory that is larger than 64KBytes. This is an + * indication to STK500 that a load extended address must be executed. */ - if (m->op[AVR_OP_LOAD_EXT_ADDR] != NULL) { + if(m->op[AVR_OP_LOAD_EXT_ADDR] != NULL) { use_ext_addr = (1U << 31); } - } - else if (mem_is_eeprom(m)) { + } else if(mem_is_eeprom(m)) { commandbuf[0] = mode == PPMODE? CMD_READ_EEPROM_PP: CMD_READ_EEPROM_HVSP; } - for (; addr < maxaddr; addr += page_size) { - if ((maxaddr - addr) < page_size) + for(; addr < maxaddr; addr += page_size) { + if((maxaddr - addr) < page_size) block_size = maxaddr - addr; else block_size = page_size; - DEBUG("block_size at addr %d is %d\n",addr,block_size); + DEBUG("block_size at addr %d is %d\n", addr, block_size); memcpy(buf, commandbuf, sizeof(commandbuf)); buf[1] = block_size >> 8; buf[2] = block_size & 0xff; - // Ensure a new "load extended address" will be issued - // when crossing a 64 KB boundary in flash. - if (hiaddr != (addr & ~0xFFFF)) { + // Ensure load extended address will be issued when crossing a 64 KB boundary in flash + if(hiaddr != (addr & ~0xFFFF)) { hiaddr = addr & ~0xFFFF; - if (stk500v2_loadaddr(pgm, use_ext_addr | (addr >> addrshift)) < 0) + if(stk500v2_loadaddr(pgm, use_ext_addr | (addr >> addrshift)) < 0) return -1; } result = stk500v2_command(pgm, buf, 3, sizeof(buf)); - if (result < 0) { + if(result < 0) { pmsg_error("read command failed\n"); return -1; } + #if 0 - for (i = 0; i < page_size; i++) { + for(i = 0; i < page_size; i++) { msg_notice("%02X", buf[2 + i]); - if (i % 16 == 15) + if(i%16 == 15) msg_notice("\n"); } #endif @@ -3155,76 +3076,60 @@ static int stk500hv_paged_load(const PROGRAMMER *pgm, const AVRPART *p, const AV return n_bytes; } -/* - * Read pages of flash/EEPROM, PP mode - */ +// Read pages of flash/EEPROM, PP mode static int stk500pp_paged_load(const PROGRAMMER *pgm, const AVRPART *p, const AVRMEM *m, - unsigned int page_size, - unsigned int addr, unsigned int n_bytes) -{ + unsigned int page_size, unsigned int addr, unsigned int n_bytes) { return stk500hv_paged_load(pgm, p, m, page_size, addr, n_bytes, PPMODE); } -/* - * Read pages of flash/EEPROM, HVSP mode - */ +// Read pages of flash/EEPROM, HVSP mode static int stk500hvsp_paged_load(const PROGRAMMER *pgm, const AVRPART *p, const AVRMEM *m, - unsigned int page_size, - unsigned int addr, unsigned int n_bytes) -{ + unsigned int page_size, unsigned int addr, unsigned int n_bytes) { return stk500hv_paged_load(pgm, p, m, page_size, addr, n_bytes, HVSPMODE); } - static int stk500v2_set_vtarget(const PROGRAMMER *pgm, double v) { unsigned char uaref = 0; - unsigned char utarg = (unsigned)((v + 0.049) * 10); + unsigned char utarg = (unsigned) ((v + 0.049)*10); - if (stk500v2_getparm(pgm, PARAM_VADJUST, &uaref) != 0) { + if(stk500v2_getparm(pgm, PARAM_VADJUST, &uaref) != 0) { pmsg_error("cannot obtain V[aref]\n"); return -1; } - if (uaref > utarg) { + if(uaref > utarg) { pmsg_warning("reducing V[aref] from %.1f to %.1f\n", uaref/10.0, v); - if (stk500v2_setparm(pgm, PARAM_VADJUST, utarg) != 0) + if(stk500v2_setparm(pgm, PARAM_VADJUST, utarg) != 0) return -1; } return stk500v2_setparm(pgm, PARAM_VTARGET, utarg); } - static int stk500v2_get_vtarget(const PROGRAMMER *pgm, double *v) { *v = stk500v2_vtarget_value(pgm); return 0; } - -static int stk500v2_set_varef(const PROGRAMMER *pgm, unsigned int chan /* unused */, - double v) -{ +static int stk500v2_set_varef(const PROGRAMMER *pgm, unsigned int chan, double v) { unsigned char utarg = 0; - unsigned char uaref = (unsigned)((v + 0.049) * 10); + unsigned char uaref = (unsigned) ((v + 0.049)*10); - if (stk500v2_getparm(pgm, PARAM_VTARGET, &utarg) != 0) { + if(stk500v2_getparm(pgm, PARAM_VTARGET, &utarg) != 0) { pmsg_error("cannot obtain V[target]\n"); return -1; } - if (uaref > utarg) { - pmsg_error("V[aref] must not be greater than " - "V[target] = %.1f\n", utarg/10.0); + if(uaref > utarg) { + pmsg_error("V[aref] must not be greater than " "V[target] = %.1f\n", utarg/10.0); return -1; } return stk500v2_setparm(pgm, PARAM_VADJUST, uaref); } - -static int stk500v2_get_varef(const PROGRAMMER *pgm, unsigned int chan, double *v) -{ - if(PDATA(pgm)->pgmtype == PGMTYPE_STK500) +static int stk500v2_get_varef(const PROGRAMMER *pgm, unsigned int chan, double *v) { + if(my.pgmtype == PGMTYPE_STK500) *v = stk500v2_varef_value(pgm); - else if(PDATA(pgm)->pgmtype == PGMTYPE_STK600) { + else if(my.pgmtype == PGMTYPE_STK600) { if(chan == 0) *v = stk600_varef_0_value(pgm); else if(chan == 1) @@ -3237,10 +3142,10 @@ static int stk500v2_get_varef(const PROGRAMMER *pgm, unsigned int chan, double * return 0; } - static int stk500v2_set_fosc(const PROGRAMMER *pgm, double v) { int fosc; unsigned char prescale, cmatch; + const unsigned ps[] = { 1, 8, 32, 64, 128, 256, 1024 }; @@ -3248,83 +3153,81 @@ static int stk500v2_set_fosc(const PROGRAMMER *pgm, double v) { int rc; prescale = cmatch = 0; - if (v > 0.0) { - if (v > PDATA(pgm)->xtal / 2) { + if(v > 0.0) { + if(v > my.xtal/2) { const char *unit; - if (v >= 1e6) { + + if(v >= 1e6) { v /= 1e6; unit = "MHz"; - } else if (v >= 1e3) { + } else if(v >= 1e3) { v /= 1e3; unit = "kHz"; } else unit = "Hz"; - pmsg_warning("f = %.3f %s too high, using %.3f MHz\n", - v, unit, PDATA(pgm)->xtal / 2e6); - fosc = PDATA(pgm)->xtal / 2; + pmsg_warning("f = %.3f %s too high, using %.3f MHz\n", v, unit, my.xtal/2e6); + fosc = my.xtal/2; } else - fosc = (unsigned)v; + fosc = (unsigned) v; - for (idx = 0; idx < sizeof(ps) / sizeof(ps[0]); idx++) { - if ((unsigned) fosc >= PDATA(pgm)->xtal / (256 * ps[idx] * 2)) { - /* this prescaler value can handle our frequency */ + for(idx = 0; idx < sizeof(ps)/sizeof(ps[0]); idx++) { + if((unsigned) fosc >= my.xtal/(256*ps[idx] * 2)) { + // This prescaler value can handle our frequency prescale = idx + 1; - cmatch = (unsigned)(PDATA(pgm)->xtal / (2 * fosc * ps[idx])) - 1; + cmatch = (unsigned) (my.xtal/(2*fosc*ps[idx])) - 1; break; } } - if (idx == sizeof(ps) / sizeof(ps[0])) { - pmsg_warning("f = %u Hz too low, %u Hz min\n", - fosc, PDATA(pgm)->xtal / (256 * 1024 * 2)); + if(idx == sizeof(ps)/sizeof(ps[0])) { + pmsg_warning("f = %u Hz too low, %u Hz min\n", fosc, my.xtal/(256*1024*2)); return -1; } } - if ((rc = stk500v2_setparm(pgm, PARAM_OSC_PSCALE, prescale)) != 0 - || (rc = stk500v2_setparm(pgm, PARAM_OSC_CMATCH, cmatch)) != 0) + if((rc = stk500v2_setparm(pgm, PARAM_OSC_PSCALE, prescale)) != 0 || + (rc = stk500v2_setparm(pgm, PARAM_OSC_CMATCH, cmatch)) != 0) { + return rc; + } return 0; } - static int stk500v2_get_fosc(const PROGRAMMER *pgm, double *v) { *v = stk500v2_fosc_value(pgm); return 0; } - -/* The list of SCK frequencies supported by the AVRISP mkII, as listed - * in AVR069 */ +// The list of SCK frequencies supported by the AVRISP mkII, as listed in AVR069 static const double avrispmkIIfreqs[] = { - 8000000, 4000000, 2000000, 1000000, 500000, 250000, 125000, - 96386, 89888, 84211, 79208, 74767, 70797, 67227, 64000, - 61069, 58395, 55945, 51613, 49690, 47905, 46243, 43244, - 41885, 39409, 38278, 36200, 34335, 32654, 31129, 29740, - 28470, 27304, 25724, 24768, 23461, 22285, 21221, 20254, - 19371, 18562, 17583, 16914, 16097, 15356, 14520, 13914, - 13224, 12599, 12031, 11511, 10944, 10431, 9963, 9468, - 9081, 8612, 8239, 7851, 7498, 7137, 6809, 6478, 6178, - 5879, 5607, 5359, 5093, 4870, 4633, 4418, 4209, 4019, - 3823, 3645, 3474, 3310, 3161, 3011, 2869, 2734, 2611, - 2484, 2369, 2257, 2152, 2052, 1956, 1866, 1779, 1695, - 1615, 1539, 1468, 1398, 1333, 1271, 1212, 1155, 1101, - 1049, 1000, 953, 909, 866, 826, 787, 750, 715, 682, - 650, 619, 590, 563, 536, 511, 487, 465, 443, 422, - 402, 384, 366, 349, 332, 317, 302, 288, 274, 261, - 249, 238, 226, 216, 206, 196, 187, 178, 170, 162, - 154, 147, 140, 134, 128, 122, 116, 111, 105, 100, - 95.4, 90.9, 86.6, 82.6, 78.7, 75.0, 71.5, 68.2, - 65.0, 61.9, 59.0, 56.3, 53.6, 51.1 + 8000000, 4000000, 2000000, 1000000, 500000, 250000, 125000, + 96386, 89888, 84211, 79208, 74767, 70797, 67227, 64000, + 61069, 58395, 55945, 51613, 49690, 47905, 46243, 43244, + 41885, 39409, 38278, 36200, 34335, 32654, 31129, 29740, + 28470, 27304, 25724, 24768, 23461, 22285, 21221, 20254, + 19371, 18562, 17583, 16914, 16097, 15356, 14520, 13914, + 13224, 12599, 12031, 11511, 10944, 10431, 9963, 9468, + 9081, 8612, 8239, 7851, 7498, 7137, 6809, 6478, 6178, + 5879, 5607, 5359, 5093, 4870, 4633, 4418, 4209, 4019, + 3823, 3645, 3474, 3310, 3161, 3011, 2869, 2734, 2611, + 2484, 2369, 2257, 2152, 2052, 1956, 1866, 1779, 1695, + 1615, 1539, 1468, 1398, 1333, 1271, 1212, 1155, 1101, + 1049, 1000, 953, 909, 866, 826, 787, 750, 715, 682, + 650, 619, 590, 563, 536, 511, 487, 465, 443, 422, + 402, 384, 366, 349, 332, 317, 302, 288, 274, 261, + 249, 238, 226, 216, 206, 196, 187, 178, 170, 162, + 154, 147, 140, 134, 128, 122, 116, 111, 105, 100, + 95.4, 90.9, 86.6, 82.6, 78.7, 75.0, 71.5, 68.2, + 65.0, 61.9, 59.0, 56.3, 53.6, 51.1 }; -#define NavrispmkIIfreqs (sizeof avrispmkIIfreqs / sizeof *avrispmkIIfreqs) +#define NavrispmkIIfreqs (sizeof avrispmkIIfreqs/sizeof *avrispmkIIfreqs) static int stk500v2_set_sck_period_mk2(const PROGRAMMER *pgm, double v) { size_t i; for(i = 0; i < NavrispmkIIfreqs; i++) - if(1 / avrispmkIIfreqs[i] >= v) + if(1/avrispmkIIfreqs[i] >= v) break; if(i >= NavrispmkIIfreqs) { @@ -3332,28 +3235,31 @@ static int stk500v2_set_sck_period_mk2(const PROGRAMMER *pgm, double v) { return -1; } - msg_notice2("Using p = %.2f us for SCK (i = %d)\n", 1e6 / avrispmkIIfreqs[i], (int) i); + msg_notice2("Using p = %.2f us for SCK (i = %d)\n", 1e6/avrispmkIIfreqs[i], (int) i); return stk500v2_setparm(pgm, PARAM_SCK_DURATION, i); } -/* - * Return the "mode" value for the parallel and HVSP modes that - * corresponds to the pagesize. - */ -static unsigned int stk500v2_mode_for_pagesize(unsigned int pagesize) -{ - switch (pagesize) - { - case 256: return 0u << 1; - case 2: return 1u << 1; - case 4: return 2u << 1; - case 8: return 3u << 1; - case 16: return 4u << 1; - case 32: return 5u << 1; - case 64: return 6u << 1; - case 128: return 7u << 1; - } +// Return the "mode" value for the parallel and HVSP modes that corresponds to* the pagesize +static unsigned int stk500v2_mode_for_pagesize(unsigned int pagesize) { + switch(pagesize) { + case 256: + return 0u << 1; + case 2: + return 1u << 1; + case 4: + return 2u << 1; + case 8: + return 3u << 1; + case 16: + return 4u << 1; + case 32: + return 5u << 1; + case 64: + return 6u << 1; + case 128: + return 7u << 1; + } pmsg_error("invalid pagesize: %u\n", pagesize); return 0; } @@ -3361,32 +3267,32 @@ static unsigned int stk500v2_mode_for_pagesize(unsigned int pagesize) /* * See pseudo-code in AVR068 * - * This algorithm only fits for the STK500 itself. For the (old) - * AVRISP, the resulting ISP clock is only half. While this would be - * easy to fix in the algorithm, we'd need to add another - * configuration flag for this to the config file. Given the old - * AVRISP devices are virtually no longer around (and the AVRISPmkII - * uses a different algorithm below), it's probably not worth the - * hassle. - * Originally, magic constants based on the XTAL frequency - * 7.3728 MHz of the original STK500 HW were used here. + * This algorithm only fits for the STK500 itself. For the (old) AVRISP, the + * resulting ISP clock is only half. While this would be easy to fix in the + * algorithm, we'd need to add another configuration flag for this to the + * config file. Given the old AVRISP devices are virtually no longer around + * (and the AVRISPmkII uses a different algorithm below), it's probably not + * worth the hassle. + * + * Originally, magic constants based on the XTAL frequency 7.3728 MHz of the + * original STK500 HW were used here. */ static int stk500v2_set_sck_period(const PROGRAMMER *pgm, double v) { unsigned int d; unsigned char dur; - double f = 1 / v; + double f = 1/v; - if (f >= PDATA(pgm)->xtal / 4.0) // 1.8432E6 + if(f >= my.xtal/4.0) // 1.8432E6 d = 0; - else if (f > PDATA(pgm)->xtal / 16.0) // 460.8E3 + else if(f > my.xtal/16.0) // 460.8E3 d = 1; - else if (f > PDATA(pgm)->xtal / 64.0) // 115.2E3 + else if(f > my.xtal/64.0) // 115.2E3 d = 2; - else if (f > PDATA(pgm)->xtal / 128.0) // 57.6E3 + else if(f > my.xtal/128.0) // 57.6E3 d = 3; else - d = (unsigned int)ceil(1 / (24 * f / (double)PDATA(pgm)->xtal) - 10.0 / 12.0); - if (d >= 255) + d = (unsigned int) ceil(1/(24*f/(double) my.xtal) - 10.0/12.0); + if(d >= 255) d = 254; dur = d; @@ -3394,91 +3300,84 @@ static int stk500v2_set_sck_period(const PROGRAMMER *pgm, double v) { } static int stk500v2_get_sck_period(const PROGRAMMER *pgm, double *v) { - *v = stk500v2_sck_duration_value(pgm) / 1e6; + *v = stk500v2_sck_duration_value(pgm)/1e6; return 0; } - static double stk500v2_sck_to_us(const PROGRAMMER *pgm, unsigned char dur) { double x; - if (dur == 0) - return 4.E6 / PDATA(pgm)->xtal; // 0.5425; - if (dur == 1) - return 16.E6 / PDATA(pgm)->xtal; // 2.17; - if (dur == 2) - return 64.E6 / PDATA(pgm)->xtal; // 8.68; - if (dur == 3) - return 128.E6 / PDATA(pgm)->xtal; // 17.36; - - x = (double)dur + 10.0 / 12.0; - x = 1.0 / x; + if(dur == 0) + return 4.E6/my.xtal; // 0.5425; + if(dur == 1) + return 16.E6/my.xtal; // 2.17; + if(dur == 2) + return 64.E6/my.xtal; // 8.68; + if(dur == 3) + return 128.E6/my.xtal; // 17.36; + + x = (double) dur + 10.0/12.0; + x = 1.0/x; x /= 24.0; - x *= (double)PDATA(pgm)->xtal; - return 1e6 / x; + x *= (double) my.xtal; + return 1e6/x; } - static int stk600_set_vtarget(const PROGRAMMER *pgm, double v) { unsigned int uaref = 0; - unsigned char utarg = (unsigned)((v + 0.049) * 10); + unsigned char utarg = (unsigned) ((v + 0.049)*10); int rv; - if (stk500v2_getparm2(pgm, PARAM2_AREF0, &uaref) != 0) { + if(stk500v2_getparm2(pgm, PARAM2_AREF0, &uaref) != 0) { pmsg_error("cannot obtain V[aref][0]\n"); return -1; } - if (uaref > (unsigned)utarg * 10) { + if(uaref > (unsigned) utarg*10) { pmsg_warning("reducing V[aref][0] from %.2f V to %.1f\n", uaref/100.0, v); - uaref = 10 * (unsigned)utarg; - if (stk500v2_setparm2(pgm, PARAM2_AREF0, uaref) != 0) + uaref = 10 * (unsigned) utarg; + if(stk500v2_setparm2(pgm, PARAM2_AREF0, uaref) != 0) return -1; } - if (stk500v2_getparm2(pgm, PARAM2_AREF1, &uaref) != 0) { + if(stk500v2_getparm2(pgm, PARAM2_AREF1, &uaref) != 0) { pmsg_error("cannot obtain V[aref][1]\n"); return -1; } - if (uaref > (unsigned)utarg * 10) { + if(uaref > (unsigned) utarg*10) { pmsg_warning("reducing V[aref][1] from %.2f V to %.1f\n", uaref/100.0, v); - uaref = 10 * (unsigned)utarg; - if (stk500v2_setparm2(pgm, PARAM2_AREF1, uaref) - != 0) + uaref = 10 * (unsigned) utarg; + if(stk500v2_setparm2(pgm, PARAM2_AREF1, uaref) + != 0) return -1; } - /* - * Vtarget on the STK600 can only be adjusted while not being in - * programming mode. - */ - if (PDATA(pgm)->lastpart) - pgm->disable(pgm); + // Vtarget on the STK600 can only be adjusted while not being in programming mode + if(my.lastpart) + pgm->disable(pgm); rv = stk500v2_setparm(pgm, PARAM_VTARGET, utarg); - if (PDATA(pgm)->lastpart) - pgm->program_enable(pgm, PDATA(pgm)->lastpart); + if(my.lastpart) + pgm->program_enable(pgm, my.lastpart); return rv; } - static int stk600_set_varef(const PROGRAMMER *pgm, unsigned int chan, double v) { unsigned char utarg = 0; - unsigned int uaref = (unsigned)((v + 0.0049) * 100); + unsigned int uaref = (unsigned) ((v + 0.0049)*100); - if (stk500v2_getparm(pgm, PARAM_VTARGET, &utarg) != 0) { + if(stk500v2_getparm(pgm, PARAM_VTARGET, &utarg) != 0) { pmsg_error("cannot obtain V[target]\n"); return -1; } - if (uaref > (unsigned)utarg * 10) { + if(uaref > (unsigned) utarg*10) { pmsg_error("V[aref] must not be greater than V[target] = %.1f\n", utarg/10.0); return -1; } - switch (chan) - { + switch(chan) { case 0: return stk500v2_setparm2(pgm, PARAM2_AREF0, uaref); @@ -3491,12 +3390,11 @@ static int stk600_set_varef(const PROGRAMMER *pgm, unsigned int chan, double v) } } - static int stk600_set_fosc(const PROGRAMMER *pgm, double v) { unsigned int oct, dac; - oct = 1.443 * log(v / 1039.0); - dac = 2048 - (2078.0 * pow(2, (double)(10 + oct))) / v; + oct = 1.443*log(v/1039.0); + dac = 2048 - (2078.0*pow(2, (double) (10 + oct)))/v; return stk500v2_setparm2(pgm, PARAM2_CLOCK_CONF, (oct << 12) | (dac << 2)); } @@ -3504,9 +3402,9 @@ static int stk600_set_fosc(const PROGRAMMER *pgm, double v) { static int stk600_set_sck_period(const PROGRAMMER *pgm, double v) { unsigned int sck; - sck = ceil((16e6 / (2 * 1.0 / v)) - 1); + sck = ceil((16e6/(2*1.0/v)) - 1); - if (sck >= 4096) + if(sck >= 4096) sck = 4095; return stk500v2_setparm2(pgm, PARAM2_SCK_DURATION, sck); @@ -3516,40 +3414,42 @@ static int stk500v2_jtag3_set_sck_period(const PROGRAMMER *pgm, double v) { unsigned char value[3]; unsigned int sck; - if (v < 1 / (1000.0 * 0xffff)) + if(v < 1/(1000.0*0xffff)) sck = 0xffff; - else if (v > 1E-3) + else if(v > 1E-3) sck = 1; else - sck = 1.0 / (1000.0 * v); + sck = 1.0/(1000.0*v); value[0] = CMD_SET_SCK; value[1] = sck & 0xff; value[2] = (sck >> 8) & 0xff; - if (stk500v2_jtag3_send(pgm, value, 3) < 0) + if(stk500v2_jtag3_send(pgm, value, 3) < 0) return -1; - if (stk500v2_jtag3_recv(pgm, value, 3) < 0) + if(stk500v2_jtag3_recv(pgm, value, 3) < 0) return -1; return 0; } static int stk500v2_jtag3_get_sck_period(const PROGRAMMER *pgm, double *v) { unsigned char cmd[4]; + *v = 0; cmd[0] = CMD_GET_SCK; - if (stk500v2_jtag3_send(pgm, cmd, 1) < 0 || stk500v2_jtag3_recv(pgm, cmd, 4) < 2) { + if(stk500v2_jtag3_send(pgm, cmd, 1) < 0 || stk500v2_jtag3_recv(pgm, cmd, 4) < 2) { pmsg_error("cannot read ISP clock speed\n"); return -1; } unsigned int sck = cmd[1] | (cmd[2] << 8); + if(!sck) { pmsg_error("reported ISP clock speed not valid\n"); return -1; } - *v = 1 / (1000.0 * sck); + *v = 1/(1000.0*sck); return 0; } @@ -3559,7 +3459,7 @@ static int stk500v2_getparm(const PROGRAMMER *pgm, unsigned char parm, unsigned buf[0] = CMD_GET_PARAMETER; buf[1] = parm; - if (stk500v2_command(pgm, buf, 2, sizeof(buf)) < 0) { + if(stk500v2_command(pgm, buf, 2, sizeof(buf)) < 0) { pmsg_error("unable to get parameter 0x%02x\n", parm); return -1; } @@ -3576,7 +3476,7 @@ static int stk500v2_setparm_real(const PROGRAMMER *pgm, unsigned char parm, unsi buf[1] = parm; buf[2] = value; - if (stk500v2_command(pgm, buf, 3, sizeof(buf)) < 0) { + if(stk500v2_command(pgm, buf, 3, sizeof(buf)) < 0) { pmsg_error("unable to set parameter 0x%02x\n", parm); return -1; } @@ -3589,13 +3489,13 @@ static int stk500v2_setparm(const PROGRAMMER *pgm, unsigned char parm, unsigned int res; res = stk500v2_getparm(pgm, parm, ¤t_value); - if (res < 0) { + if(res < 0) { pmsg_error("unable to get parameter 0x%02x\n", parm); return -1; } - // don't issue a write if the correct value is already set. - if (value == current_value) { + // Don't issue a write if the correct value is already set + if(value == current_value) { pmsg_notice2("skipping parameter write; parameter value already set\n"); return 0; } @@ -3609,12 +3509,12 @@ static int stk500v2_getparm2(const PROGRAMMER *pgm, unsigned char parm, unsigned buf[0] = CMD_GET_PARAMETER; buf[1] = parm; - if (stk500v2_command(pgm, buf, 2, sizeof(buf)) < 0) { + if(stk500v2_command(pgm, buf, 2, sizeof(buf)) < 0) { pmsg_error("unable to get parameter 0x%02x\n", parm); return -1; } - *value = ((unsigned)buf[2] << 8) | buf[3]; + *value = ((unsigned) buf[2] << 8) | buf[3]; return 0; } @@ -3627,7 +3527,7 @@ static int stk500v2_setparm2(const PROGRAMMER *pgm, unsigned char parm, unsigned buf[2] = value >> 8; buf[3] = value; - if (stk500v2_command(pgm, buf, 4, sizeof(buf)) < 0) { + if(stk500v2_command(pgm, buf, 4, sizeof(buf)) < 0) { pmsg_error("unable to set parameter 0x%02x\n", parm); return -1; } @@ -3635,40 +3535,35 @@ static int stk500v2_setparm2(const PROGRAMMER *pgm, unsigned char parm, unsigned return 0; } -static const char *stk600_get_cardname(const struct carddata *table, - size_t nele, int id) -{ +static const char *stk600_get_cardname(const struct carddata *table, size_t nele, int id) { const struct carddata *cdp; - if (id == 0xFF) - /* 0xFF means this card is not present at all. */ + if(id == 0xFF) + // 0xFF means this card is not present at all return "Not present"; - for (cdp = table; nele > 0; cdp++, nele--) - if (cdp->id == id) + for(cdp = table; nele > 0; cdp++, nele--) + if(cdp->id == id) return cdp->name; return "Unknown"; } - static void stk500v2_display(const PROGRAMMER *pgm, const char *p) { - unsigned char maj = 0, min = 0, hdw = 0, topcard = 0, - maj_s1 = 0, min_s1 = 0, maj_s2 = 0, min_s2 = 0; + unsigned char maj = 0, min = 0, hdw = 0, topcard = 0, maj_s1 = 0, min_s1 = 0, maj_s2 = 0, min_s2 = 0; unsigned int rev = 0; const char *topcard_name; - if (PDATA(pgm)->pgmtype != PGMTYPE_JTAGICE_MKII && - PDATA(pgm)->pgmtype != PGMTYPE_JTAGICE3) { + if(my.pgmtype != PGMTYPE_JTAGICE_MKII && my.pgmtype != PGMTYPE_JTAGICE3) { msg_info("%sProgrammer model : %s\n", p, pgmname(pgm)); stk500v2_getparm(pgm, PARAM_HW_VER, &hdw); stk500v2_getparm(pgm, PARAM_SW_MAJOR, &maj); stk500v2_getparm(pgm, PARAM_SW_MINOR, &min); msg_info("%sHW version : %d\n", p, hdw); - if (pgm->usbsn && *pgm->usbsn) + if(pgm->usbsn && *pgm->usbsn) msg_info("%sSerial number : %s\n", p, pgm->usbsn); msg_info("%sFW Version Controller : %d.%02d\n", p, maj, min); - if (PDATA(pgm)->pgmtype == PGMTYPE_STK600) { + if(my.pgmtype == PGMTYPE_STK600) { stk500v2_getparm(pgm, PARAM_SW_MAJOR_PERIPHERY1, &maj_s1); stk500v2_getparm(pgm, PARAM_SW_MINOR_PERIPHERY1, &min_s1); stk500v2_getparm(pgm, PARAM_SW_MAJOR_PERIPHERY2, &maj_s2); @@ -3678,36 +3573,47 @@ static void stk500v2_display(const PROGRAMMER *pgm, const char *p) { } } - if (PDATA(pgm)->pgmtype == PGMTYPE_STK500) { + if(my.pgmtype == PGMTYPE_STK500) { stk500v2_getparm(pgm, PARAM_TOPCARD_DETECT, &topcard); - switch (topcard) { - case 0xAA: topcard_name = "STK501"; break; - case 0x55: topcard_name = "STK502"; break; - case 0xFA: topcard_name = "STK503"; break; - case 0xEE: topcard_name = "STK504"; break; - case 0xE4: topcard_name = "STK505"; break; - case 0xDD: topcard_name = "STK520"; break; - default: topcard_name = "Unknown"; break; + switch(topcard) { + case 0xAA: + topcard_name = "STK501"; + break; + case 0x55: + topcard_name = "STK502"; + break; + case 0xFA: + topcard_name = "STK503"; + break; + case 0xEE: + topcard_name = "STK504"; + break; + case 0xE4: + topcard_name = "STK505"; + break; + case 0xDD: + topcard_name = "STK520"; + break; + default: + topcard_name = "Unknown"; + break; } msg_info("%sTopcard : %s\n", p, topcard_name); - } else if (PDATA(pgm)->pgmtype == PGMTYPE_STK600) { + } else if(my.pgmtype == PGMTYPE_STK600) { stk500v2_getparm(pgm, PARAM_ROUTINGCARD_ID, &topcard); msg_info("%sRouting card : %s\n", p, - stk600_get_cardname(routing_cards, - sizeof routing_cards / sizeof routing_cards[0], - topcard)); + stk600_get_cardname(routing_cards, sizeof routing_cards/sizeof routing_cards[0], topcard)); stk500v2_getparm(pgm, PARAM_SOCKETCARD_ID, &topcard); msg_info("%sSocket card : %s\n", p, - stk600_get_cardname(socket_cards, - sizeof socket_cards / sizeof socket_cards[0], - topcard)); + stk600_get_cardname(socket_cards, sizeof socket_cards/sizeof socket_cards[0], topcard)); stk500v2_getparm2(pgm, PARAM2_RC_ID_TABLE_REV, &rev); msg_info("%sRC_ID table rev : %d\n", p, rev); stk500v2_getparm2(pgm, PARAM2_EC_ID_TABLE_REV, &rev); msg_info("%sEC_ID table rev : %d\n", p, rev); - } else if (PDATA(pgm)->pgmtype == PGMTYPE_JTAGICE3) { + } else if(my.pgmtype == PGMTYPE_JTAGICE3) { PROGRAMMER *pgmcp = pgm_dup(pgm); - pgmcp->cookie = PDATA(pgm)->chained_pdata; + + pgmcp->cookie = my.chained_pdata; jtag3_display(pgmcp, p); pgm_free(pgmcp); } @@ -3716,112 +3622,125 @@ static void stk500v2_display(const PROGRAMMER *pgm, const char *p) { return; } - static double stk500v2_vtarget_value(const PROGRAMMER *pgm) { - if (PDATA(pgm)->pgmtype == PGMTYPE_JTAGICE_MKII) { + if(my.pgmtype == PGMTYPE_JTAGICE_MKII) { unsigned char vtarget_jtag[4]; + memset(vtarget_jtag, 0, sizeof vtarget_jtag); PROGRAMMER *pgmcp = pgm_dup(pgm); - pgmcp->cookie = PDATA(pgm)->chained_pdata; + + pgmcp->cookie = my.chained_pdata; jtagmkII_getparm(pgmcp, PAR_OCD_VTARGET, vtarget_jtag); pgm_free(pgmcp); - return b2_to_u16(vtarget_jtag) / 1000.0; + return b2_to_u16(vtarget_jtag)/1000.0; } - if (PDATA(pgm)->pgmtype != PGMTYPE_JTAGICE3) { + if(my.pgmtype != PGMTYPE_JTAGICE3) { unsigned char vtarget = 0; + stk500v2_getparm(pgm, PARAM_VTARGET, &vtarget); - return vtarget / 10.0; + return vtarget/10.0; } return 0; } - static double stk500v2_sck_duration_value(const PROGRAMMER *pgm) { unsigned char sck_duration = 0; unsigned int sck_stk600 = 0; - switch (PDATA(pgm)->pgmtype) { + switch(my.pgmtype) { case PGMTYPE_STK500: - return stk500v2_getparm(pgm, PARAM_SCK_DURATION, &sck_duration) < 0? 0: - stk500v2_sck_to_us(pgm, sck_duration); + return stk500v2_getparm(pgm, PARAM_SCK_DURATION, &sck_duration) < 0? 0: stk500v2_sck_to_us(pgm, sck_duration); case PGMTYPE_AVRISP_MKII: case PGMTYPE_JTAGICE_MKII: return stk500v2_getparm(pgm, PARAM_SCK_DURATION, &sck_duration) < 0 || - sck_duration >= NavrispmkIIfreqs? 0: 1e6 / avrispmkIIfreqs[sck_duration]; + sck_duration >= NavrispmkIIfreqs? 0: 1e6/avrispmkIIfreqs[sck_duration]; case PGMTYPE_JTAGICE3: { unsigned char cmd[4]; + cmd[0] = CMD_GET_SCK; - if (stk500v2_jtag3_send(pgm, cmd, 1) >= 0 && stk500v2_jtag3_recv(pgm, cmd, 4) >= 2) { + if(stk500v2_jtag3_send(pgm, cmd, 1) >= 0 && stk500v2_jtag3_recv(pgm, cmd, 4) >= 2) { unsigned int sck = cmd[1] | (cmd[2] << 8); - return sck? 1E6 / (1000.0 * sck): 0; + + return sck? 1E6/(1000.0*sck): 0; } return 0; } case PGMTYPE_STK600: - return stk500v2_getparm2(pgm, PARAM2_SCK_DURATION, &sck_stk600) < 0? 0: (sck_stk600 + 1) / 8.0; + return stk500v2_getparm2(pgm, PARAM2_SCK_DURATION, &sck_stk600) < 0? 0: (sck_stk600 + 1)/8.0; default: - return sck_duration * 8.0e6 / PDATA(pgm)->xtal + 0.05; + return sck_duration*8.0e6/my.xtal + 0.05; } return 0; } - static double stk500v2_varef_value(const PROGRAMMER *pgm) { unsigned char vadjust = 0; - if (stk500v2_getparm(pgm, PARAM_VADJUST, &vadjust) < 0) + + if(stk500v2_getparm(pgm, PARAM_VADJUST, &vadjust) < 0) return 0; - return vadjust / 10.0; + return vadjust/10.0; } - static double stk600_varef_0_value(const PROGRAMMER *pgm) { unsigned int varef = 0; - if (stk500v2_getparm2(pgm, PARAM2_AREF0, &varef) < 0) + + if(stk500v2_getparm2(pgm, PARAM2_AREF0, &varef) < 0) return 0; - return varef / 100.0; + return varef/100.0; } - static double stk600_varef_1_value(const PROGRAMMER *pgm) { unsigned int varef = 0; - if (stk500v2_getparm2(pgm, PARAM2_AREF1, &varef) < 0) + + if(stk500v2_getparm2(pgm, PARAM2_AREF1, &varef) < 0) return 0; - return varef / 100.0; + return varef/100.0; } - static double stk500v2_fosc_value(const PROGRAMMER *pgm) { unsigned char osc_pscale = 0, osc_cmatch = 0, sck_duration = 0; unsigned int clock_conf = 0, dac, oct; int prescale; double fosc = 0.0; - switch (PDATA(pgm)->pgmtype) { + switch(my.pgmtype) { case PGMTYPE_STK500: - if (stk500v2_getparm(pgm, PARAM_OSC_PSCALE, &osc_pscale) < 0) + if(stk500v2_getparm(pgm, PARAM_OSC_PSCALE, &osc_pscale) < 0) return 0.0; - if (stk500v2_getparm(pgm, PARAM_OSC_CMATCH, &osc_cmatch) < 0) + if(stk500v2_getparm(pgm, PARAM_OSC_CMATCH, &osc_cmatch) < 0) return 0.0; - if (osc_pscale == 0) + if(osc_pscale == 0) return 0.0; prescale = 1; - fosc = PDATA(pgm)->xtal / 2; - - switch (osc_pscale) { - case 2: prescale = 8; break; - case 3: prescale = 32; break; - case 4: prescale = 64; break; - case 5: prescale = 128; break; - case 6: prescale = 256; break; - case 7: prescale = 1024; break; + fosc = my.xtal/2; + + switch(osc_pscale) { + case 2: + prescale = 8; + break; + case 3: + prescale = 32; + break; + case 4: + prescale = 64; + break; + case 5: + prescale = 128; + break; + case 6: + prescale = 256; + break; + case 7: + prescale = 1024; + break; } fosc /= prescale; fosc /= (osc_cmatch + 1); @@ -3830,14 +3749,14 @@ static double stk500v2_fosc_value(const PROGRAMMER *pgm) { case PGMTYPE_AVRISP_MKII: case PGMTYPE_JTAGICE_MKII: return stk500v2_getparm(pgm, PARAM_SCK_DURATION, &sck_duration) < 0 || - sck_duration >= NavrispmkIIfreqs? 0: 1e6 / avrispmkIIfreqs[sck_duration]; + sck_duration >= NavrispmkIIfreqs? 0: 1e6/avrispmkIIfreqs[sck_duration]; case PGMTYPE_STK600: - if (stk500v2_getparm2(pgm, PARAM2_CLOCK_CONF, &clock_conf) < 0) + if(stk500v2_getparm2(pgm, PARAM2_CLOCK_CONF, &clock_conf) < 0) return 0.0; oct = (clock_conf & 0xf000) >> 12u; dac = (clock_conf & 0x0ffc) >> 2u; - fosc = pow(2, (double)oct) * 2078.0 / (2 - (double)dac / 1024.0); + fosc = pow(2, (double) oct)*2078.0/(2 - (double) dac/1024.0); return fosc; default: @@ -3845,25 +3764,24 @@ static double stk500v2_fosc_value(const PROGRAMMER *pgm) { } } - static void stk500v2_print_parms1(const PROGRAMMER *pgm, const char *p, FILE *fp) { double f; int decimals; const char *unit; - if (pgm->extra_features & HAS_VTARG_READ) { + if(pgm->extra_features & HAS_VTARG_READ) { fmsg_out(fp, "%sVtarget : %.1f V\n", p, stk500v2_vtarget_value(pgm)); } - switch (PDATA(pgm)->pgmtype) { + switch(my.pgmtype) { case PGMTYPE_STK500: - if (pgm->extra_features & HAS_VAREF_ADJ) { + if(pgm->extra_features & HAS_VAREF_ADJ) { fmsg_out(fp, "%sVaref : %.1f V\n", p, stk500v2_varef_value(pgm)); } - if (pgm->extra_features & HAS_FOSC_ADJ) { + if(pgm->extra_features & HAS_FOSC_ADJ) { fmsg_out(fp, "%sOscillator : ", p); f = stk500v2_fosc_value(pgm); - if (f == 0.0) + if(f == 0.0) fmsg_out(fp, "Off\n"); else { decimals = get_decimals(f); @@ -3872,10 +3790,10 @@ static void stk500v2_print_parms1(const PROGRAMMER *pgm, const char *p, FILE *fp } } // SCK duration is always available - fmsg_out(fp, "%sSCK period : %.1f us\n", p, - stk500v2_sck_duration_value(pgm)); + fmsg_out(fp, "%sSCK period : %.1f us\n", p, stk500v2_sck_duration_value(pgm)); // XTAL frequency is always available - double f = PDATA(pgm)->xtal; + double f = my.xtal; + decimals = get_decimals(f); f = f_to_kHz_MHz(f, &unit); fmsg_out(fp, "%sXTAL frequency : %.*f %s\n", p, decimals, f, unit); @@ -3889,16 +3807,19 @@ static void stk500v2_print_parms1(const PROGRAMMER *pgm, const char *p, FILE *fp case PGMTYPE_JTAGICE3: { unsigned char cmd[4]; + cmd[0] = CMD_GET_SCK; - if (stk500v2_jtag3_send(pgm, cmd, 1) >= 0 && stk500v2_jtag3_recv(pgm, cmd, 4) >= 2) { - unsigned int sck = cmd[1] | (cmd[2] << 8); - fmsg_out(fp, "%sSCK period : %.1f us\n", p, (1E6 / (1000.0 * sck))); + if(stk500v2_jtag3_send(pgm, cmd, 1) >= 0 && stk500v2_jtag3_recv(pgm, cmd, 4) >= 2) { + unsigned int sck = cmd[1] | (cmd[2] << 8); + + fmsg_out(fp, "%sSCK period : %.1f us\n", p, (1E6/(1000.0*sck))); } PROGRAMMER *pgmcp = pgm_dup(pgm); - pgmcp->cookie = PDATA(pgm)->chained_pdata; + + pgmcp->cookie = my.chained_pdata; pgmcp->id = lcreat(NULL, 0); // Copy pgm->id contents over to pgmcp->id - for(LNODEID ln=lfirst(pgm->id); ln; ln=lnext(ln)) + for(LNODEID ln = lfirst(pgm->id); ln; ln = lnext(ln)) ladd(pgmcp->id, mmt_strdup(ldata(ln))); jtag3_print_parms1(pgmcp, p, fp); pgm_free(pgmcp); @@ -3906,12 +3827,12 @@ static void stk500v2_print_parms1(const PROGRAMMER *pgm, const char *p, FILE *fp break; case PGMTYPE_STK600: - if (pgm->extra_features & HAS_VAREF_ADJ) { + if(pgm->extra_features & HAS_VAREF_ADJ) { fmsg_out(fp, "%sVaref 0 : %.2f V\n", p, stk600_varef_0_value(pgm)); fmsg_out(fp, "%sVaref 1 : %.2f V\n", p, stk600_varef_1_value(pgm)); } fmsg_out(fp, "%sSCK period : %.1f us\n", p, stk500v2_sck_duration_value(pgm)); - if (pgm->extra_features & HAS_FOSC_ADJ) { + if(pgm->extra_features & HAS_FOSC_ADJ) { f = stk500v2_fosc_value(pgm); f = f_to_kHz_MHz(f, &unit); fmsg_out(fp, "%sOscillator : %.3f %s\n", p, f, unit); @@ -3926,7 +3847,6 @@ static void stk500v2_print_parms1(const PROGRAMMER *pgm, const char *p, FILE *fp return; } - static void stk500v2_print_parms(const PROGRAMMER *pgm, FILE *fp) { stk500v2_print_parms1(pgm, "", fp); } @@ -3938,7 +3858,7 @@ static int stk500v2_perform_osccal(const PROGRAMMER *pgm) { buf[0] = CMD_OSCCAL; rv = stk500v2_command(pgm, buf, 1, sizeof(buf)); - if (rv < 0) { + if(rv < 0) { pmsg_error("unable to perform oscillator calibaration\n"); return -1; } @@ -3947,15 +3867,12 @@ static int stk500v2_perform_osccal(const PROGRAMMER *pgm) { } /* - * Wrapper functions for the JTAG ICE mkII in ISP mode. This mode - * uses the normal JTAG ICE mkII packet stream to communicate with the - * ICE, but then encapsulates AVRISP mkII commands using - * CMND_ISP_PACKET. + * Wrapper functions for the JTAG ICE mkII in ISP mode. This mode uses the + * normal JTAG ICE mkII packet stream to communicate with the ICE, but then + * encapsulates AVRISP mkII commands using CMND_ISP_PACKET. */ -/* - * Open a JTAG ICE mkII in ISP mode. - */ +// Open a JTAG ICE mkII in ISP mode static int stk500v2_jtagmkII_open(PROGRAMMER *pgm, const char *port) { union pinfo pinfo; void *mycookie; @@ -3965,20 +3882,20 @@ static int stk500v2_jtagmkII_open(PROGRAMMER *pgm, const char *port) { /* * The JTAG ICE mkII always starts with a baud rate of 19200 Bd upon - * attaching. If the config file or command-line parameters specify - * a higher baud rate, we switch to it later on, after establishing - * the connection with the ICE. + * attaching. If the config file or command-line parameters specify a higher + * baud rate, we switch to it later on, after establishing the connection + * with the ICE. */ pinfo.serialinfo.baud = 19200; pinfo.serialinfo.cflags = SERIAL_8N1; /* - * If the port name starts with "usb", divert the serial routines - * to the USB ones. The serial_open() function for USB overrides - * the meaning of the "baud" parameter to be the USB device ID to - * search for. + * If the port name starts with "usb", divert the serial routines to the USB + * ones. The serial_open() function for USB overrides the meaning of the + * "baud" parameter to be the USB device ID to search for. */ - if (str_starts(port, "usb")) { + if(str_starts(port, "usb")) { + #if defined(HAVE_LIBUSB) serdev = &usb_serdev; pinfo.usbinfo.vid = USB_VENDOR_ATMEL; @@ -3987,7 +3904,7 @@ static int stk500v2_jtagmkII_open(PROGRAMMER *pgm, const char *port) { pgm->fd.usb.max_xfer = USBDEV_MAX_XFER_MKII; pgm->fd.usb.rep = USBDEV_BULK_EP_READ_MKII; pgm->fd.usb.wep = USBDEV_BULK_EP_WRITE_MKII; - pgm->fd.usb.eep = 0; /* no seperate EP for events */ + pgm->fd.usb.eep = 0; // No seperate EP for events #else pmsg_error("avrdude was compiled without usb support\n"); return -1; @@ -3995,78 +3912,64 @@ static int stk500v2_jtagmkII_open(PROGRAMMER *pgm, const char *port) { } pgm->port = port; - if (serial_open(port, pinfo, &pgm->fd)==-1) { + if(serial_open(port, pinfo, &pgm->fd) == -1) { return -1; } - /* - * drain any extraneous input - */ + // Drain any extraneous input stk500v2_drain(pgm, 0); mycookie = pgm->cookie; - pgm->cookie = PDATA(pgm)->chained_pdata; - if ((rv = jtagmkII_getsync(pgm, EMULATOR_MODE_SPI)) != 0) { - if (rv != JTAGII_GETSYNC_FAIL_GRACEFUL) - pmsg_error("unable to sync with the JTAG ICE mkII in ISP mode\n"); + pgm->cookie = my.chained_pdata; + if((rv = jtagmkII_getsync(pgm, EMULATOR_MODE_SPI)) != 0) { + if(rv != JTAGII_GETSYNC_FAIL_GRACEFUL) + pmsg_error("unable to sync with the JTAG ICE mkII in ISP mode\n"); pgm->cookie = mycookie; return -1; } pgm->cookie = mycookie; - PDATA(pgm)->pgmtype = PGMTYPE_JTAGICE_MKII; + my.pgmtype = PGMTYPE_JTAGICE_MKII; - if (pgm->bitclock != 0.0) { - if (pgm->set_sck_period(pgm, pgm->bitclock) != 0) + if(pgm->bitclock != 0.0) { + if(pgm->set_sck_period(pgm, pgm->bitclock) != 0) return -1; } return 0; } - -/* - * Close an AVR Dragon or JTAG ICE mkII in ISP/HVSP/PP mode. - */ -static void stk500v2_jtagmkII_close(PROGRAMMER * pgm) -{ +// Close an AVR Dragon or JTAG ICE mkII in ISP/HVSP/PP mode +static void stk500v2_jtagmkII_close(PROGRAMMER *pgm) { void *mycookie; pmsg_notice2("stk500v2_jtagmkII_close()\n"); mycookie = pgm->cookie; - pgm->cookie = PDATA(pgm)->chained_pdata; + pgm->cookie = my.chained_pdata; jtagmkII_close(pgm); pgm->cookie = mycookie; } - -/* - * Close JTAGICE3. - */ -static void stk500v2_jtag3_close(PROGRAMMER * pgm) -{ +// Close JTAGICE3 +static void stk500v2_jtag3_close(PROGRAMMER *pgm) { void *mycookie; pmsg_notice2("stk500v2_jtag3_close()\n"); mycookie = pgm->cookie; - pgm->cookie = PDATA(pgm)->chained_pdata; + pgm->cookie = my.chained_pdata; jtag3_close(pgm); pgm->cookie = mycookie; } - /* - * Wrapper functions for the AVR Dragon in ISP mode. This mode - * uses the normal JTAG ICE mkII packet stream to communicate with the - * ICE, but then encapsulates AVRISP mkII commands using - * CMND_ISP_PACKET. + * Wrapper functions for the AVR Dragon in ISP mode. This mode uses the normal + * JTAG ICE mkII packet stream to communicate with the ICE, but then + * encapsulates AVRISP mkII commands using CMND_ISP_PACKET. */ -/* - * Open an AVR Dragon in ISP mode. - */ +// Open an AVR Dragon in ISP mode static int stk500v2_dragon_isp_open(PROGRAMMER *pgm, const char *port) { union pinfo pinfo; void *mycookie; @@ -4075,20 +3978,20 @@ static int stk500v2_dragon_isp_open(PROGRAMMER *pgm, const char *port) { /* * The JTAG ICE mkII always starts with a baud rate of 19200 Bd upon - * attaching. If the config file or command-line parameters specify - * a higher baud rate, we switch to it later on, after establishing - * the connection with the ICE. + * attaching. If the config file or command-line parameters specify a higher + * baud rate, we switch to it later on, after establishing the connection + * with the ICE. */ pinfo.serialinfo.baud = 19200; pinfo.serialinfo.cflags = SERIAL_8N1; /* - * If the port name starts with "usb", divert the serial routines - * to the USB ones. The serial_open() function for USB overrides - * the meaning of the "baud" parameter to be the USB device ID to - * search for. + * If the port name starts with "usb", divert the serial routines to the USB + * ones. The serial_open() function for USB overrides the meaning of the + * "baud" parameter to be the USB device ID to search for. */ - if (str_starts(port, "usb")) { + if(str_starts(port, "usb")) { + #if defined(HAVE_LIBUSB) serdev = &usb_serdev; pinfo.usbinfo.vid = USB_VENDOR_ATMEL; @@ -4097,7 +4000,7 @@ static int stk500v2_dragon_isp_open(PROGRAMMER *pgm, const char *port) { pgm->fd.usb.max_xfer = USBDEV_MAX_XFER_MKII; pgm->fd.usb.rep = USBDEV_BULK_EP_READ_MKII; pgm->fd.usb.wep = USBDEV_BULK_EP_WRITE_MKII; - pgm->fd.usb.eep = 0; /* no seperate EP for events */ + pgm->fd.usb.eep = 0; // No seperate EP for events #else pmsg_error("avrdude was compiled without usb support\n"); return -1; @@ -4105,35 +4008,32 @@ static int stk500v2_dragon_isp_open(PROGRAMMER *pgm, const char *port) { } pgm->port = port; - if (serial_open(port, pinfo, &pgm->fd)==-1) { + if(serial_open(port, pinfo, &pgm->fd) == -1) { return -1; } - /* - * drain any extraneous input - */ + // Drain any extraneous input stk500v2_drain(pgm, 0); mycookie = pgm->cookie; - pgm->cookie = PDATA(pgm)->chained_pdata; - if (jtagmkII_getsync(pgm, EMULATOR_MODE_SPI) != 0) { + pgm->cookie = my.chained_pdata; + if(jtagmkII_getsync(pgm, EMULATOR_MODE_SPI) != 0) { pmsg_error("unable to sync with the AVR Dragon in ISP mode\n"); pgm->cookie = mycookie; return -1; } pgm->cookie = mycookie; - PDATA(pgm)->pgmtype = PGMTYPE_JTAGICE_MKII; + my.pgmtype = PGMTYPE_JTAGICE_MKII; - if (pgm->bitclock != 0.0) { - if (pgm->set_sck_period(pgm, pgm->bitclock) != 0) + if(pgm->bitclock != 0.0) { + if(pgm->set_sck_period(pgm, pgm->bitclock) != 0) return -1; } return 0; } - /* * Wrapper functions for the AVR Dragon in HV mode. This mode * uses the normal JTAG ICE mkII packet stream to communicate with the @@ -4141,9 +4041,7 @@ static int stk500v2_dragon_isp_open(PROGRAMMER *pgm, const char *port) { * CMND_ISP_PACKET. */ -/* - * Open an AVR Dragon in HV mode (HVSP or parallel). - */ +// Open an AVR Dragon in HV mode (HVSP or parallel) static int stk500v2_dragon_hv_open(PROGRAMMER *pgm, const char *port) { union pinfo pinfo; @@ -4151,20 +4049,20 @@ static int stk500v2_dragon_hv_open(PROGRAMMER *pgm, const char *port) { /* * The JTAG ICE mkII always starts with a baud rate of 19200 Bd upon - * attaching. If the config file or command-line parameters specify - * a higher baud rate, we switch to it later on, after establishing - * the connection with the ICE. + * attaching. If the config file or command-line parameters specify a higher + * baud rate, we switch to it later on, after establishing the connection + * with the ICE. */ pinfo.serialinfo.baud = 19200; pinfo.serialinfo.cflags = SERIAL_8N1; /* - * If the port name starts with "usb", divert the serial routines - * to the USB ones. The serial_open() function for USB overrides - * the meaning of the "baud" parameter to be the USB device ID to - * search for. + * If the port name starts with "usb", divert the serial routines to the USB + * ones. The serial_open() function for USB overrides the meaning of the + * "baud" parameter to be the USB device ID to search for. */ - if (str_starts(port, "usb")) { + if(str_starts(port, "usb")) { + #if defined(HAVE_LIBUSB) serdev = &usb_serdev; pinfo.usbinfo.vid = USB_VENDOR_ATMEL; @@ -4173,7 +4071,7 @@ static int stk500v2_dragon_hv_open(PROGRAMMER *pgm, const char *port) { pgm->fd.usb.max_xfer = USBDEV_MAX_XFER_MKII; pgm->fd.usb.rep = USBDEV_BULK_EP_READ_MKII; pgm->fd.usb.wep = USBDEV_BULK_EP_WRITE_MKII; - pgm->fd.usb.eep = 0; /* no seperate EP for events */ + pgm->fd.usb.eep = 0; // No seperate EP for events #else pmsg_error("avrdude was compiled without usb support\n"); return -1; @@ -4181,27 +4079,26 @@ static int stk500v2_dragon_hv_open(PROGRAMMER *pgm, const char *port) { } pgm->port = port; - if (serial_open(port, pinfo, &pgm->fd)==-1) { + if(serial_open(port, pinfo, &pgm->fd) == -1) { return -1; } - /* - * drain any extraneous input - */ + // Drain any extraneous input stk500v2_drain(pgm, 0); PROGRAMMER *pgmcp = pgm_dup(pgm); - pgmcp->cookie = PDATA(pgm)->chained_pdata; - if (jtagmkII_getsync(pgmcp, EMULATOR_MODE_HV) != 0) { + + pgmcp->cookie = my.chained_pdata; + if(jtagmkII_getsync(pgmcp, EMULATOR_MODE_HV) != 0) { pmsg_error("unable to sync with the AVR Dragon in HV mode\n"); pgm_free(pgmcp); return -1; } pgm_free(pgmcp); - PDATA(pgm)->pgmtype = PGMTYPE_JTAGICE_MKII; + my.pgmtype = PGMTYPE_JTAGICE_MKII; - if (pgm->bitclock != 0.0) { - if (pgm->set_sck_period(pgm, pgm->bitclock) != 0) + if(pgm->bitclock != 0.0) { + if(pgm->set_sck_period(pgm, pgm->bitclock) != 0) return -1; } @@ -4209,667 +4106,624 @@ static int stk500v2_dragon_hv_open(PROGRAMMER *pgm, const char *port) { } /* - * Wrapper functions for the JTAGICE3 in ISP mode. This mode - * uses the normal JTAGICE3 packet stream to communicate with the - * ICE, but then encapsulates AVRISP mkII commands using - * scope AVRISP. + * Wrapper functions for the JTAGICE3 in ISP mode. This mode uses the normal + * JTAGICE3 packet stream to communicate with the ICE, but then encapsulates + * AVRISP mkII commands using scope AVRISP. */ -/* - * Open a JTAGICE3 in ISP mode. - */ +// Open a JTAGICE3 in ISP mode static int stk500v2_jtag3_open(PROGRAMMER *pgm, const char *port) { void *mycookie; int rv; pmsg_notice2("%s()\n", __func__); - rv = jtag3_open_common(pgm, port, PDATA(pgm)->pk4_snap_mode); - if (rv < 0) + rv = jtag3_open_common(pgm, port, my.pk4_snap_mode); + if(rv < 0) return rv; mycookie = pgm->cookie; - pgm->cookie = PDATA(pgm)->chained_pdata; - if ((rv = jtag3_getsync(pgm, 42)) != 0) { - if (rv != JTAGII_GETSYNC_FAIL_GRACEFUL) - pmsg_error("unable to sync with the JTAGICE3 in ISP mode\n"); + pgm->cookie = my.chained_pdata; + if((rv = jtag3_getsync(pgm, 42)) != 0) { + if(rv != JTAGII_GETSYNC_FAIL_GRACEFUL) + pmsg_error("unable to sync with the JTAGICE3 in ISP mode\n"); pgm->cookie = mycookie; return -1; } pgm->cookie = mycookie; - PDATA(pgm)->pgmtype = PGMTYPE_JTAGICE3; + my.pgmtype = PGMTYPE_JTAGICE3; - if (pgm->bitclock != 0.0) { - if (pgm->set_sck_period(pgm, pgm->bitclock) != 0) + if(pgm->bitclock != 0.0) { + if(pgm->set_sck_period(pgm, pgm->bitclock) != 0) return -1; } return 0; } - -/* - * XPROG wrapper - */ +// XPROG wrapper static int stk600_xprog_command(const PROGRAMMER *pgm, unsigned char *b, - unsigned int cmdsize, unsigned int responsesize) -{ - unsigned char *newb; - unsigned int s; - int rv; - - if (cmdsize < responsesize) - s = responsesize; - else - s = cmdsize; + unsigned int cmdsize, unsigned int responsesize) { - newb = mmt_malloc(s + 1); - newb[0] = CMD_XPROG; - memcpy(newb + 1, b, cmdsize); - rv = stk500v2_command(pgm, newb, cmdsize + 1, responsesize + 1); - if (rv == 0) - memcpy(b, newb + 1, responsesize); + unsigned char *newb; + unsigned int s; + int rv; - mmt_free(newb); + if(cmdsize < responsesize) + s = responsesize; + else + s = cmdsize; - return rv; -} + newb = mmt_malloc(s + 1); + newb[0] = CMD_XPROG; + memcpy(newb + 1, b, cmdsize); + rv = stk500v2_command(pgm, newb, cmdsize + 1, responsesize + 1); + if(rv == 0) + memcpy(b, newb + 1, responsesize); + mmt_free(newb); -/* - * issue the 'program enable' command to the AVR device, XPROG version - */ + return rv; +} + +// Issue the 'program enable' command to the AVR device, XPROG version static int stk600_xprog_program_enable(const PROGRAMMER *pgm, const AVRPART *p) { - unsigned char buf[16]; - unsigned int eepagesize = 42; - unsigned int nvm_base; - AVRMEM *mem = NULL; - int use_tpi; - - use_tpi = (p->prog_modes & PM_TPI) != 0; - - if (!use_tpi) { - if (p->nvm_base == 0) { - pmsg_error("no nvm_base parameter for PDI device\n"); - return -1; - } - if ((mem = avr_locate_eeprom(p)) != NULL) { - if (mem->page_size <= 1) { - pmsg_error("no EEPROM page_size parameter for PDI device\n"); - return -1; - } - eepagesize = mem->page_size; - } - } + unsigned char buf[16]; + unsigned int eepagesize = 42; + unsigned int nvm_base; + AVRMEM *mem = NULL; + int use_tpi; - buf[0] = CMD_XPROG_SETMODE; - buf[1] = use_tpi? XPRG_MODE_TPI: XPRG_MODE_PDI; - if (stk500v2_command(pgm, buf, 2, sizeof(buf)) < 0) { - pmsg_error("CMD_XPROG_SETMODE(XPRG_MODE_%s) failed\n", use_tpi? "TPI": "PDI"); - return -1; - } + use_tpi = is_tpi(p) != 0; - buf[0] = XPRG_CMD_ENTER_PROGMODE; - if (stk600_xprog_command(pgm, buf, 1, 2) < 0) { - pmsg_error("XPRG_CMD_ENTER_PROGMODE failed\n"); + if(!use_tpi) { + if(p->nvm_base == 0) { + pmsg_error("no nvm_base parameter for PDI device\n"); + return -1; + } + if((mem = avr_locate_eeprom(p)) != NULL) { + if(mem->page_size <= 1) { + pmsg_error("no EEPROM page_size parameter for PDI device\n"); return -1; + } + eepagesize = mem->page_size; } + } - if (use_tpi) { - /* - * Whatever all that might mean, it matches what AVR Studio - * does. - */ - if (stk500v2_setparm_real(pgm, PARAM_DISCHARGEDELAY, 232) < 0) - return -1; - - buf[0] = XPRG_CMD_SET_PARAM; - buf[1] = XPRG_PARAM_NVMCMD_ADDR; - buf[2] = 51; - if (stk600_xprog_command(pgm, buf, 3, 2) < 0) { - pmsg_error("XPRG_CMD_SET_PARAM(XPRG_PARAM_NVMCMD_ADDR) failed\n"); - return -1; - } + buf[0] = CMD_XPROG_SETMODE; + buf[1] = use_tpi? XPRG_MODE_TPI: XPRG_MODE_PDI; + if(stk500v2_command(pgm, buf, 2, sizeof(buf)) < 0) { + pmsg_error("CMD_XPROG_SETMODE(XPRG_MODE_%s) failed\n", use_tpi? "TPI": "PDI"); + return -1; + } - buf[0] = XPRG_CMD_SET_PARAM; - buf[1] = XPRG_PARAM_NVMCSR_ADDR; - buf[2] = 50; - if (stk600_xprog_command(pgm, buf, 3, 2) < 0) { - pmsg_error("XPRG_CMD_SET_PARAM(XPRG_PARAM_NVMCSR_ADDR) failed\n"); - return -1; - } - } else { - buf[0] = XPRG_CMD_SET_PARAM; - buf[1] = XPRG_PARAM_NVMBASE; - nvm_base = p->nvm_base; - /* - * The 0x01000000 appears to be an indication to the programmer - * that the respective address is located in IO (i.e., SRAM) - * memory address space rather than flash. This is not documented - * anywhere in AVR079 but matches what AVR Studio does. - */ - nvm_base |= 0x01000000; - buf[2] = nvm_base >> 24; - buf[3] = nvm_base >> 16; - buf[4] = nvm_base >> 8; - buf[5] = nvm_base; - if (stk600_xprog_command(pgm, buf, 6, 2) < 0) { - pmsg_error("XPRG_CMD_SET_PARAM(XPRG_PARAM_NVMBASE) failed\n"); - return -1; - } + buf[0] = XPRG_CMD_ENTER_PROGMODE; + if(stk600_xprog_command(pgm, buf, 1, 2) < 0) { + pmsg_error("XPRG_CMD_ENTER_PROGMODE failed\n"); + return -1; + } - if (mem != NULL) { - buf[0] = XPRG_CMD_SET_PARAM; - buf[1] = XPRG_PARAM_EEPPAGESIZE; - buf[2] = eepagesize >> 8; - buf[3] = eepagesize; - if (stk600_xprog_command(pgm, buf, 4, 2) < 0) { - pmsg_error("XPRG_CMD_SET_PARAM(XPRG_PARAM_EEPPAGESIZE) failed\n"); - return -1; - } - } + if(use_tpi) { + // Whatever all that might mean, it matches what AVR Studio does + if(stk500v2_setparm_real(pgm, PARAM_DISCHARGEDELAY, 232) < 0) + return -1; + + buf[0] = XPRG_CMD_SET_PARAM; + buf[1] = XPRG_PARAM_NVMCMD_ADDR; + buf[2] = 51; + if(stk600_xprog_command(pgm, buf, 3, 2) < 0) { + pmsg_error("XPRG_CMD_SET_PARAM(XPRG_PARAM_NVMCMD_ADDR) failed\n"); + return -1; } - // Read XMEGA chip silicon revision - if(p->prog_modes & PM_PDI) { - AVRMEM *m = avr_locate_io(p); - unsigned char chip_rev[AVR_CHIP_REVLEN]; - if(m && pgm->read_byte(pgm, p, m, p->mcu_base+3, chip_rev) >= 0) - pmsg_notice("silicon revision: %x.%x\n", chip_rev[0] >> 4, chip_rev[0] & 0x0f); - else - pmsg_warning("cannot read silicon revision; is avrdude.conf up to date?\n"); + buf[0] = XPRG_CMD_SET_PARAM; + buf[1] = XPRG_PARAM_NVMCSR_ADDR; + buf[2] = 50; + if(stk600_xprog_command(pgm, buf, 3, 2) < 0) { + pmsg_error("XPRG_CMD_SET_PARAM(XPRG_PARAM_NVMCSR_ADDR) failed\n"); + return -1; + } + } else { + buf[0] = XPRG_CMD_SET_PARAM; + buf[1] = XPRG_PARAM_NVMBASE; + nvm_base = p->nvm_base; + /* + * The 0x01000000 appears to be an indication to the programmer that the + * respective address is located in IO (i.e., SRAM) memory address space + * rather than flash. This is not documented anywhere in AVR079 but + * matches what AVR Studio does. + */ + nvm_base |= 0x01000000; + buf[2] = nvm_base >> 24; + buf[3] = nvm_base >> 16; + buf[4] = nvm_base >> 8; + buf[5] = nvm_base; + if(stk600_xprog_command(pgm, buf, 6, 2) < 0) { + pmsg_error("XPRG_CMD_SET_PARAM(XPRG_PARAM_NVMBASE) failed\n"); + return -1; } - return 0; -} + if(mem != NULL) { + buf[0] = XPRG_CMD_SET_PARAM; + buf[1] = XPRG_PARAM_EEPPAGESIZE; + buf[2] = eepagesize >> 8; + buf[3] = eepagesize; + if(stk600_xprog_command(pgm, buf, 4, 2) < 0) { + pmsg_error("XPRG_CMD_SET_PARAM(XPRG_PARAM_EEPPAGESIZE) failed\n"); + return -1; + } + } + } -static unsigned char stk600_xprog_mtype(const PROGRAMMER *pgm, unsigned long addr) { - if (addr >= PDATA(pgm)->boot_start) - return XPRG_MEM_TYPE_BOOT; + // Read XMEGA chip silicon revision + if(is_pdi(p)) { + AVRMEM *m = avr_locate_io(p); + unsigned char chip_rev[AVR_CHIP_REVLEN]; + + if(m && pgm->read_byte(pgm, p, m, p->mcu_base + 3, chip_rev) >= 0) + pmsg_notice("silicon revision: %x.%x\n", chip_rev[0] >> 4, chip_rev[0] & 0x0f); else - return XPRG_MEM_TYPE_APPL; + pmsg_warning("cannot read silicon revision; is avrdude.conf up to date?\n"); + } + + return 0; } +static unsigned char stk600_xprog_mtype(const PROGRAMMER *pgm, unsigned long addr) { + if(addr >= my.boot_start) + return XPRG_MEM_TYPE_BOOT; + else + return XPRG_MEM_TYPE_APPL; +} static void stk600_xprog_disable(const PROGRAMMER *pgm) { - unsigned char buf[2]; + unsigned char buf[2]; - buf[0] = XPRG_CMD_LEAVE_PROGMODE; - if (stk600_xprog_command(pgm, buf, 1, 2) < 0) { - pmsg_error("XPRG_CMD_LEAVE_PROGMODE failed\n"); - } + buf[0] = XPRG_CMD_LEAVE_PROGMODE; + if(stk600_xprog_command(pgm, buf, 1, 2) < 0) { + pmsg_error("XPRG_CMD_LEAVE_PROGMODE failed\n"); + } } static int stk600_xprog_write_byte(const PROGRAMMER *pgm, const AVRPART *p, const AVRMEM *mem, - unsigned long addr, unsigned char data) -{ - unsigned char b[9 + 256]; - int need_erase = 0; - unsigned char write_size = 1; - unsigned char memcode; - - memset(b, 0, sizeof(b)); - - if (mem_is_flash(mem)) { - memcode = stk600_xprog_mtype(pgm, addr); - } else if (mem_is_application(mem) || mem_is_apptable(mem)) { - memcode = XPRG_MEM_TYPE_APPL; - } else if (mem_is_boot(mem)) { - memcode = XPRG_MEM_TYPE_BOOT; - } else if (mem_is_eeprom(mem)) { - memcode = XPRG_MEM_TYPE_EEPROM; - } else if (mem_is_io(mem) || mem_is_sram(mem)) { - memcode = XPRG_MEM_TYPE_APPL; - addr += avr_data_offset(p); - } else if (mem_is_lock(mem)) { - memcode = XPRG_MEM_TYPE_LOCKBITS; - } else if (mem_is_a_fuse(mem) || mem_is_fuses(mem)) { - memcode = XPRG_MEM_TYPE_FUSE; - if (p->prog_modes & PM_TPI) - need_erase = 1; - } else if (mem_is_userrow(mem)) { - memcode = XPRG_MEM_TYPE_USERSIG; - } else if(mem_is_readonly(mem)) { - unsigned char is; - if(pgm->read_byte(pgm, p, mem, addr, &is) >= 0 && is == data) - return 0; - - pmsg_error("cannot write to read-only memory %s of %s\n", mem->desc, p->desc); + unsigned long addr, unsigned char data) { + unsigned char b[9 + 256]; + int need_erase = 0; + unsigned char write_size = 1; + unsigned char memcode; + + memset(b, 0, sizeof(b)); + + if(mem_is_flash(mem)) { + memcode = stk600_xprog_mtype(pgm, addr); + } else if(mem_is_application(mem) || mem_is_apptable(mem)) { + memcode = XPRG_MEM_TYPE_APPL; + } else if(mem_is_boot(mem)) { + memcode = XPRG_MEM_TYPE_BOOT; + } else if(mem_is_eeprom(mem)) { + memcode = XPRG_MEM_TYPE_EEPROM; + } else if(mem_is_io(mem) || mem_is_sram(mem)) { + memcode = XPRG_MEM_TYPE_APPL; + addr += avr_data_offset(p); + } else if(mem_is_lock(mem)) { + memcode = XPRG_MEM_TYPE_LOCKBITS; + } else if(mem_is_a_fuse(mem) || mem_is_fuses(mem)) { + memcode = XPRG_MEM_TYPE_FUSE; + if(is_tpi(p)) + need_erase = 1; + } else if(mem_is_userrow(mem)) { + memcode = XPRG_MEM_TYPE_USERSIG; + } else if(mem_is_readonly(mem)) { + unsigned char is; + + if(pgm->read_byte(pgm, p, mem, addr, &is) >= 0 && is == data) + return 0; + + pmsg_error("cannot write to read-only memory %s of %s\n", mem->desc, p->desc); + return -1; + } else { + pmsg_error("unsupported memory %s\n", mem->desc); + return -1; + } + addr += mem->offset; + + if(need_erase) { + b[0] = XPRG_CMD_ERASE; + b[1] = XPRG_ERASE_CONFIG; + b[2] = mem->offset >> 24; + b[3] = mem->offset >> 16; + b[4] = mem->offset >> 8; + b[5] = mem->offset + 1; + if(stk600_xprog_command(pgm, b, 6, 2) < 0) { + pmsg_error("XPRG_CMD_ERASE(XPRG_ERASE_CONFIG) failed\n"); return -1; - } else { - pmsg_error("unsupported memory %s\n", mem->desc); - return -1; - } - addr += mem->offset; - - if (need_erase) { - b[0] = XPRG_CMD_ERASE; - b[1] = XPRG_ERASE_CONFIG; - b[2] = mem->offset >> 24; - b[3] = mem->offset >> 16; - b[4] = mem->offset >> 8; - b[5] = mem->offset + 1; - if (stk600_xprog_command(pgm, b, 6, 2) < 0) { - pmsg_error("XPRG_CMD_ERASE(XPRG_ERASE_CONFIG) failed\n"); - return -1; - } } + } - if (p->prog_modes & PM_TPI) { - /* - * Some TPI memories (configuration aka. fuse) require a - * larger write block size. We record that as a blocksize in - * avrdude.conf. - */ - if (mem->blocksize != 0) - write_size = mem->blocksize; - } - b[0] = XPRG_CMD_WRITE_MEM; - b[1] = memcode; - b[2] = 0; /* pagemode: non-paged write */ - b[3] = addr >> 24; - b[4] = addr >> 16; - b[5] = addr >> 8; - b[6] = addr; - b[7] = 0; - b[8] = write_size; - b[9] = data; - if (stk600_xprog_command(pgm, b, 9 + write_size, 2) < 0) { - pmsg_error("XPRG_CMD_WRITE_MEM failed\n"); - return -1; - } - return 0; + if(is_tpi(p)) { + /* + * Some TPI memories (configuration aka. fuse) require a larger write block + * size. We record that as a blocksize in avrdude.conf. + */ + if(mem->blocksize != 0) + write_size = mem->blocksize; + } + b[0] = XPRG_CMD_WRITE_MEM; + b[1] = memcode; + b[2] = 0; // Pagemode: non-paged write + b[3] = addr >> 24; + b[4] = addr >> 16; + b[5] = addr >> 8; + b[6] = addr; + b[7] = 0; + b[8] = write_size; + b[9] = data; + if(stk600_xprog_command(pgm, b, 9 + write_size, 2) < 0) { + pmsg_error("XPRG_CMD_WRITE_MEM failed\n"); + return -1; + } + return 0; } - static int stk600_xprog_read_byte(const PROGRAMMER *pgm, const AVRPART *p, const AVRMEM *mem, - unsigned long addr, unsigned char * value) -{ - unsigned char b[8]; - - if (mem_is_flash(mem)) { - b[1] = stk600_xprog_mtype(pgm, addr); - } else if (mem_is_application(mem) || mem_is_apptable(mem)) { - b[1] = XPRG_MEM_TYPE_APPL; - } else if (mem_is_boot(mem)) { - b[1] = XPRG_MEM_TYPE_BOOT; - } else if (mem_is_eeprom(mem)) { - b[1] = XPRG_MEM_TYPE_EEPROM; - } else if (mem_is_io(mem) || mem_is_sram(mem)) { - b[1] = XPRG_MEM_TYPE_APPL; - addr += avr_data_offset(p); - } else if (mem_is_signature(mem)) { - b[1] = XPRG_MEM_TYPE_APPL; - } else if (mem_is_a_fuse(mem) || mem_is_fuses(mem)) { - b[1] = XPRG_MEM_TYPE_FUSE; - } else if (mem_is_lock(mem)) { - b[1] = XPRG_MEM_TYPE_LOCKBITS; - } else if (mem_is_calibration(mem) || mem_is_in_sigrow(mem)) { - b[1] = XPRG_MEM_TYPE_FACTORY_CALIBRATION; - } else if (mem_is_userrow(mem)) { - b[1] = XPRG_MEM_TYPE_USERSIG; - } else { - pmsg_error("unsupported memory %s\n", mem->desc); - return -1; - } - addr += mem->offset; + unsigned long addr, unsigned char *value) { + unsigned char b[8]; + + if(mem_is_flash(mem)) { + b[1] = stk600_xprog_mtype(pgm, addr); + } else if(mem_is_application(mem) || mem_is_apptable(mem)) { + b[1] = XPRG_MEM_TYPE_APPL; + } else if(mem_is_boot(mem)) { + b[1] = XPRG_MEM_TYPE_BOOT; + } else if(mem_is_eeprom(mem)) { + b[1] = XPRG_MEM_TYPE_EEPROM; + } else if(mem_is_io(mem) || mem_is_sram(mem)) { + b[1] = XPRG_MEM_TYPE_APPL; + addr += avr_data_offset(p); + } else if(mem_is_signature(mem)) { + b[1] = XPRG_MEM_TYPE_APPL; + } else if(mem_is_a_fuse(mem) || mem_is_fuses(mem)) { + b[1] = XPRG_MEM_TYPE_FUSE; + } else if(mem_is_lock(mem)) { + b[1] = XPRG_MEM_TYPE_LOCKBITS; + } else if(mem_is_calibration(mem) || mem_is_in_sigrow(mem)) { + b[1] = XPRG_MEM_TYPE_FACTORY_CALIBRATION; + } else if(mem_is_userrow(mem)) { + b[1] = XPRG_MEM_TYPE_USERSIG; + } else { + pmsg_error("unsupported memory %s\n", mem->desc); + return -1; + } + addr += mem->offset; + + b[0] = XPRG_CMD_READ_MEM; + b[2] = addr >> 24; + b[3] = addr >> 16; + b[4] = addr >> 8; + b[5] = addr; + b[6] = 0; + b[7] = 1; + if(stk600_xprog_command(pgm, b, 8, 3) < 0) { + pmsg_error("XPRG_CMD_READ_MEM failed\n"); + return -1; + } + *value = b[2]; + return 0; +} + +static int stk600_xprog_paged_load(const PROGRAMMER *pgm, const AVRPART *p, const AVRMEM *mem, + unsigned int page_size, unsigned int addr, unsigned int n_bytes) { + unsigned char *b; + unsigned int offset; + unsigned char mtype; + int n_bytes_orig = n_bytes, dynamic_mtype = 0; + unsigned long use_ext_addr = 0; + + // The XPROG read command supports at most 256 bytes in one transfer + if(page_size > 256) + page_size = 256; // Not really a page size anymore + + /* + * Fancy offsets everywhere. This is probably what AVR079 means when writing + * about the "TIF address space". + */ + if(mem_is_flash(mem)) { + mtype = 0; + dynamic_mtype = 1; + if(mem->size > 64*1024) + use_ext_addr = (1UL << 31); + } else if(mem_is_application(mem) || mem_is_apptable(mem)) { + mtype = XPRG_MEM_TYPE_APPL; + if(mem->size > 64*1024) + use_ext_addr = (1UL << 31); + } else if(mem_is_boot(mem)) { + mtype = XPRG_MEM_TYPE_BOOT; + // @@@ Should consider flash size instead to decide whether to use extended addressing + if(mem->size > 64*1024) + use_ext_addr = (1UL << 31); + } else if(mem_is_eeprom(mem)) { + mtype = XPRG_MEM_TYPE_EEPROM; + } else if(mem_is_io(mem) || mem_is_sram(mem)) { + mtype = XPRG_MEM_TYPE_APPL; + addr += avr_data_offset(p); + } else if(mem_is_signature(mem)) { + mtype = XPRG_MEM_TYPE_APPL; + } else if(mem_is_a_fuse(mem) || mem_is_fuses(mem)) { + mtype = XPRG_MEM_TYPE_FUSE; + } else if(mem_is_lock(mem)) { + mtype = XPRG_MEM_TYPE_LOCKBITS; + } else if(mem_is_calibration(mem) || mem_is_in_sigrow(mem)) { + mtype = XPRG_MEM_TYPE_FACTORY_CALIBRATION; + } else if(mem_is_userrow(mem)) { + mtype = XPRG_MEM_TYPE_USERSIG; + } else { + pmsg_error("unsupported memory %s\n", mem->desc); + return -1; + } + offset = addr; + addr += mem->offset; + + b = mmt_malloc(page_size + 2); + if(stk500v2_loadaddr(pgm, use_ext_addr) < 0) { + mmt_free(b); + return -1; + } + + while(n_bytes != 0) { + if(dynamic_mtype) + mtype = stk600_xprog_mtype(pgm, addr - mem->offset); b[0] = XPRG_CMD_READ_MEM; + b[1] = mtype; b[2] = addr >> 24; b[3] = addr >> 16; b[4] = addr >> 8; b[5] = addr; - b[6] = 0; - b[7] = 1; - if (stk600_xprog_command(pgm, b, 8, 3) < 0) { - pmsg_error("XPRG_CMD_READ_MEM failed\n"); - return -1; + b[6] = page_size >> 8; + b[7] = page_size; + if(stk600_xprog_command(pgm, b, 8, page_size + 2) < 0) { + pmsg_error("XPRG_CMD_READ_MEM failed\n"); + mmt_free(b); + return -1; } - *value = b[2]; - return 0; + memcpy(mem->buf + offset, b + 2, page_size); + if(n_bytes < page_size) { + n_bytes = page_size; + } + offset += page_size; + addr += page_size; + n_bytes -= page_size; + } + mmt_free(b); + + return n_bytes_orig; } +static int stk600_xprog_paged_write(const PROGRAMMER *pgm, const AVRPART *p, const AVRMEM *mem, + unsigned int page_size, unsigned int addr, unsigned int n_bytes) { + unsigned char *b; + unsigned int offset; + unsigned char mtype; + int n_bytes_orig = n_bytes, dynamic_mtype = 0; + size_t writesize; + unsigned long use_ext_addr = 0; + unsigned char writemode; + + // The XPROG read command supports at most 256 bytes in one transfer + if(page_size > 512) { + pmsg_error("cannot handle page size > 512\n"); + return -1; + } -static int stk600_xprog_paged_load(const PROGRAMMER *pgm, const AVRPART *p, const AVRMEM *mem, - unsigned int page_size, - unsigned int addr, unsigned int n_bytes) -{ - unsigned char *b; - unsigned int offset; - unsigned char mtype; - int n_bytes_orig = n_bytes, dynamic_mtype = 0; - unsigned long use_ext_addr = 0; + /* + * Fancy offsets everywhere. This is probably what AVR079 means when writing + * about the "TIF address space". + */ + if(mem_is_flash(mem)) { + mtype = 0; + dynamic_mtype = 1; + writemode = (1 << XPRG_MEM_WRITE_WRITE); + if(mem->size > 64*1024) + use_ext_addr = (1UL << 31); + } else if(mem_is_application(mem) || mem_is_apptable(mem)) { + mtype = XPRG_MEM_TYPE_APPL; + writemode = (1 << XPRG_MEM_WRITE_WRITE); + if(mem->size > 64*1024) + use_ext_addr = (1UL << 31); + } else if(mem_is_boot(mem)) { + mtype = XPRG_MEM_TYPE_BOOT; + writemode = (1 << XPRG_MEM_WRITE_WRITE); + // @@@ Should consider flash size instead to decide whether to use extended addressing + if(mem->size > 64*1024) + use_ext_addr = (1UL << 31); + } else if(mem_is_eeprom(mem)) { + mtype = XPRG_MEM_TYPE_EEPROM; + writemode = (1 << XPRG_MEM_WRITE_WRITE) | (1 << XPRG_MEM_WRITE_ERASE); + } else if(mem_is_signature(mem)) { + mtype = XPRG_MEM_TYPE_APPL; + writemode = (1 << XPRG_MEM_WRITE_WRITE); + } else if(mem_is_a_fuse(mem) || mem_is_fuses(mem)) { + mtype = XPRG_MEM_TYPE_FUSE; + writemode = (1 << XPRG_MEM_WRITE_WRITE); + } else if(mem_is_lock(mem)) { + mtype = XPRG_MEM_TYPE_LOCKBITS; + writemode = (1 << XPRG_MEM_WRITE_WRITE); + } else if(mem_is_calibration(mem)) { + mtype = XPRG_MEM_TYPE_FACTORY_CALIBRATION; + writemode = (1 << XPRG_MEM_WRITE_WRITE); + } else if(mem_is_userrow(mem)) { + mtype = XPRG_MEM_TYPE_USERSIG; + writemode = (1 << XPRG_MEM_WRITE_WRITE); + } else { + pmsg_error("unsupported memory %s\n", mem->desc); + return -1; + } + offset = addr; + addr += mem->offset; - /* - * The XPROG read command supports at most 256 bytes in one - * transfer. - */ - if (page_size > 256) - page_size = 256; /* not really a page size anymore */ + b = mmt_malloc(page_size + 9); + if(stk500v2_loadaddr(pgm, use_ext_addr) < 0) { + mmt_free(b); + return -1; + } - /* - * Fancy offsets everywhere. - * This is probably what AVR079 means when writing about the - * "TIF address space". - */ - if (mem_is_flash(mem)) { - mtype = 0; - dynamic_mtype = 1; - if (mem->size > 64 * 1024) - use_ext_addr = (1UL << 31); - } else if (mem_is_application(mem) || mem_is_apptable(mem)) { - mtype = XPRG_MEM_TYPE_APPL; - if (mem->size > 64 * 1024) - use_ext_addr = (1UL << 31); - } else if (mem_is_boot(mem)) { - mtype = XPRG_MEM_TYPE_BOOT; - // Do we have to consider the total amount of flash - // instead to decide whether to use extended addressing? - if (mem->size > 64 * 1024) - use_ext_addr = (1UL << 31); - } else if (mem_is_eeprom(mem)) { - mtype = XPRG_MEM_TYPE_EEPROM; - } else if (mem_is_io(mem) || mem_is_sram(mem)) { - mtype = XPRG_MEM_TYPE_APPL; - addr += avr_data_offset(p); - } else if (mem_is_signature(mem)) { - mtype = XPRG_MEM_TYPE_APPL; - } else if (mem_is_a_fuse(mem) || mem_is_fuses(mem)) { - mtype = XPRG_MEM_TYPE_FUSE; - } else if (mem_is_lock(mem)) { - mtype = XPRG_MEM_TYPE_LOCKBITS; - } else if (mem_is_calibration(mem) || mem_is_in_sigrow(mem)) { - mtype = XPRG_MEM_TYPE_FACTORY_CALIBRATION; - } else if (mem_is_userrow(mem)) { - mtype = XPRG_MEM_TYPE_USERSIG; - } else { - pmsg_error("unsupported memory %s\n", mem->desc); - return -1; - } - offset = addr; - addr += mem->offset; + while(n_bytes != 0) { + + if(dynamic_mtype) + mtype = stk600_xprog_mtype(pgm, addr - mem->offset); - b = mmt_malloc(page_size + 2); - if (stk500v2_loadaddr(pgm, use_ext_addr) < 0) { + if(page_size > 256) { + /* + * AVR079 is not quite clear. While it suggests that downloading up to + * 512 bytes (256 words) were OK, it obviously isn't -- 512-byte pages on + * the ATxmega128A1 are getting corrupted when written as a single piece. + * It writes random junk somewhere beyond byte 256. Splitting it into 256 + * byte chunks, and only setting the erase page/write page bits in the + * final chunk helps. + */ + if(page_size%256 != 0) { + pmsg_error("page size not multiple of 256\n"); mmt_free(b); return -1; - } - - while (n_bytes != 0) { - if (dynamic_mtype) - mtype = stk600_xprog_mtype(pgm, addr - mem->offset); - - b[0] = XPRG_CMD_READ_MEM; - b[1] = mtype; - b[2] = addr >> 24; - b[3] = addr >> 16; - b[4] = addr >> 8; - b[5] = addr; - b[6] = page_size >> 8; - b[7] = page_size; - if (stk600_xprog_command(pgm, b, 8, page_size + 2) < 0) { - pmsg_error("XPRG_CMD_READ_MEM failed\n"); - mmt_free(b); - return -1; - } - memcpy(mem->buf + offset, b + 2, page_size); - if (n_bytes < page_size) { - n_bytes = page_size; - } - offset += page_size; - addr += page_size; - n_bytes -= page_size; - } - mmt_free(b); - - return n_bytes_orig; -} - -static int stk600_xprog_paged_write(const PROGRAMMER *pgm, const AVRPART *p, const AVRMEM *mem, - unsigned int page_size, - unsigned int addr, unsigned int n_bytes) -{ - unsigned char *b; - unsigned int offset; - unsigned char mtype; - int n_bytes_orig = n_bytes, dynamic_mtype = 0; - size_t writesize; - unsigned long use_ext_addr = 0; - unsigned char writemode; + } + unsigned int chunk; - /* - * The XPROG read command supports at most 256 bytes in one - * transfer. - */ - if (page_size > 512) { - pmsg_error("cannot handle page size > 512\n"); - return -1; - } + for(chunk = 0; chunk < page_size; chunk += 256) { + if(n_bytes < 256) { + memset(b + 9 + n_bytes, 0xff, 256 - n_bytes); + writesize = n_bytes; + } else { + writesize = 256; + } + b[0] = XPRG_CMD_WRITE_MEM; + b[1] = mtype; + b[2] = writemode; + b[3] = addr >> 24; + b[4] = addr >> 16; + b[5] = addr >> 8; + b[6] = addr; + b[7] = 1; + b[8] = 0; + memcpy(b + 9, mem->buf + offset, writesize); + if(stk600_xprog_command(pgm, b, 256 + 9, 2) < 0) { + pmsg_error("XPRG_CMD_WRITE_MEM failed\n"); + mmt_free(b); + return -1; + } + if(n_bytes < 256) + n_bytes = 256; - /* - * Fancy offsets everywhere. - * This is probably what AVR079 means when writing about the - * "TIF address space". - */ - if (mem_is_flash(mem)) { - mtype = 0; - dynamic_mtype = 1; - writemode = (1 << XPRG_MEM_WRITE_WRITE); - if (mem->size > 64 * 1024) - use_ext_addr = (1UL << 31); - } else if (mem_is_application(mem) || mem_is_apptable(mem)) { - mtype = XPRG_MEM_TYPE_APPL; - writemode = (1 << XPRG_MEM_WRITE_WRITE); - if (mem->size > 64 * 1024) - use_ext_addr = (1UL << 31); - } else if (mem_is_boot(mem)) { - mtype = XPRG_MEM_TYPE_BOOT; - writemode = (1 << XPRG_MEM_WRITE_WRITE); - // Do we have to consider the total amount of flash - // instead to decide whether to use extended addressing? - if (mem->size > 64 * 1024) - use_ext_addr = (1UL << 31); - } else if (mem_is_eeprom(mem)) { - mtype = XPRG_MEM_TYPE_EEPROM; - writemode = (1 << XPRG_MEM_WRITE_WRITE) | (1 << XPRG_MEM_WRITE_ERASE); - } else if (mem_is_signature(mem)) { - mtype = XPRG_MEM_TYPE_APPL; - writemode = (1 << XPRG_MEM_WRITE_WRITE); - } else if (mem_is_a_fuse(mem) || mem_is_fuses(mem)) { - mtype = XPRG_MEM_TYPE_FUSE; - writemode = (1 << XPRG_MEM_WRITE_WRITE); - } else if (mem_is_lock(mem)) { - mtype = XPRG_MEM_TYPE_LOCKBITS; - writemode = (1 << XPRG_MEM_WRITE_WRITE); - } else if (mem_is_calibration(mem)) { - mtype = XPRG_MEM_TYPE_FACTORY_CALIBRATION; - writemode = (1 << XPRG_MEM_WRITE_WRITE); - } else if (mem_is_userrow(mem)) { - mtype = XPRG_MEM_TYPE_USERSIG; - writemode = (1 << XPRG_MEM_WRITE_WRITE); + offset += 256; + addr += 256; + n_bytes -= 256; + } } else { - pmsg_error("unsupported memory %s\n", mem->desc); - return -1; - } - offset = addr; - addr += mem->offset; - - b = mmt_malloc(page_size + 9); - if (stk500v2_loadaddr(pgm, use_ext_addr) < 0) { + if(n_bytes < page_size) { + // This can easily happen if the input file was not a multiple of the page size + memset(b + 9 + n_bytes, 0xff, page_size - n_bytes); + writesize = n_bytes; + } else { + writesize = page_size; + } + b[0] = XPRG_CMD_WRITE_MEM; + b[1] = mtype; + b[2] = writemode; + b[3] = addr >> 24; + b[4] = addr >> 16; + b[5] = addr >> 8; + b[6] = addr; + b[7] = page_size >> 8; + b[8] = page_size; + memcpy(b + 9, mem->buf + offset, writesize); + if(stk600_xprog_command(pgm, b, page_size + 9, 2) < 0) { + pmsg_error("XPRG_CMD_WRITE_MEM failed\n"); mmt_free(b); return -1; - } + } + if(n_bytes < page_size) + n_bytes = page_size; - while (n_bytes != 0) { - - if (dynamic_mtype) - mtype = stk600_xprog_mtype(pgm, addr - mem->offset); - - if (page_size > 256) { - /* - * AVR079 is not quite clear. While it suggests that - * downloading up to 512 bytes (256 words) were OK, it - * obviously isn't -- 512-byte pages on the ATxmega128A1 - * are getting corrupted when written as a single piece. - * It writes random junk somewhere beyond byte 256. - * Splitting it into 256 byte chunks, and only setting the - * erase page / write page bits in the final chunk helps. - */ - if (page_size % 256 != 0) { - pmsg_error("page size not multiple of 256\n"); - mmt_free(b); - return -1; - } - unsigned int chunk; - for (chunk = 0; chunk < page_size; chunk += 256) { - if (n_bytes < 256) { - memset(b + 9 + n_bytes, 0xff, 256 - n_bytes); - writesize = n_bytes; - } else { - writesize = 256; - } - b[0] = XPRG_CMD_WRITE_MEM; - b[1] = mtype; - b[2] = writemode; - b[3] = addr >> 24; - b[4] = addr >> 16; - b[5] = addr >> 8; - b[6] = addr; - b[7] = 1; - b[8] = 0; - memcpy(b + 9, mem->buf + offset, writesize); - if (stk600_xprog_command(pgm, b, 256 + 9, 2) < 0) { - pmsg_error("XPRG_CMD_WRITE_MEM failed\n"); - mmt_free(b); - return -1; - } - if (n_bytes < 256) - n_bytes = 256; - - offset += 256; - addr += 256; - n_bytes -= 256; - } - } else { - if (n_bytes < page_size) { - /* - * This can easily happen if the input file was not a - * multiple of the page size. - */ - memset(b + 9 + n_bytes, 0xff, page_size - n_bytes); - writesize = n_bytes; - } else { - writesize = page_size; - } - b[0] = XPRG_CMD_WRITE_MEM; - b[1] = mtype; - b[2] = writemode; - b[3] = addr >> 24; - b[4] = addr >> 16; - b[5] = addr >> 8; - b[6] = addr; - b[7] = page_size >> 8; - b[8] = page_size; - memcpy(b + 9, mem->buf + offset, writesize); - if (stk600_xprog_command(pgm, b, page_size + 9, 2) < 0) { - pmsg_error("XPRG_CMD_WRITE_MEM failed\n"); - mmt_free(b); - return -1; - } - if (n_bytes < page_size) - n_bytes = page_size; - - offset += page_size; - addr += page_size; - n_bytes -= page_size; - } + offset += page_size; + addr += page_size; + n_bytes -= page_size; } - mmt_free(b); + } + mmt_free(b); - return n_bytes_orig; + return n_bytes_orig; } static int stk600_xprog_chip_erase(const PROGRAMMER *pgm, const AVRPART *p) { - unsigned char b[6]; - AVRMEM *mem; - unsigned int addr = 0; - - if (p->prog_modes & PM_TPI) { - if ((mem = avr_locate_flash(p)) == NULL) { - pmsg_error("no FLASH definition found for TPI device\n"); - return -1; - } - addr = mem->offset + 1; - } + unsigned char b[6]; + AVRMEM *mem; + unsigned int addr = 0; - b[0] = XPRG_CMD_ERASE; - b[1] = XPRG_ERASE_CHIP; - b[2] = addr >> 24; - b[3] = addr >> 16; - b[4] = addr >> 8; - b[5] = addr; - if (stk600_xprog_command(pgm, b, 6, 2) < 0) { - pmsg_error("XPRG_CMD_ERASE(XPRG_ERASE_CHIP) failed\n"); - return -1; - } - return 0; -} - -static int stk600_xprog_page_erase(const PROGRAMMER *pgm, const AVRPART *p, const AVRMEM *m, - unsigned int addr) -{ - unsigned char b[6]; - - if (mem_is_flash(m)) { - b[1] = stk600_xprog_mtype(pgm, addr) == XPRG_MEM_TYPE_APPL? - XPRG_ERASE_APP_PAGE: XPRG_ERASE_BOOT_PAGE; - } else if (mem_is_application(m) || mem_is_apptable(m)) { - b[1] = XPRG_ERASE_APP_PAGE; - } else if (mem_is_boot(m)) { - b[1] = XPRG_ERASE_BOOT_PAGE; - } else if (mem_is_eeprom(m)) { - b[1] = XPRG_ERASE_EEPROM_PAGE; - } else if (mem_is_userrow(m)) { - b[1] = XPRG_ERASE_USERSIG; - } else { - pmsg_error("unknown paged memory %s\n", m->desc); + if(is_tpi(p)) { + if((mem = avr_locate_flash(p)) == NULL) { + pmsg_error("no FLASH definition found for TPI device\n"); return -1; } - addr += m->offset; - b[0] = XPRG_CMD_ERASE; - b[2] = addr >> 24; - b[3] = addr >> 16; - b[4] = addr >> 8; - b[5] = addr; - if (stk600_xprog_command(pgm, b, 6, 2) < 0) { - pmsg_error("XPRG_CMD_ERASE(%d) failed\n", b[1]); - return -1; - } - return 0; + addr = mem->offset + 1; + } + + b[0] = XPRG_CMD_ERASE; + b[1] = XPRG_ERASE_CHIP; + b[2] = addr >> 24; + b[3] = addr >> 16; + b[4] = addr >> 8; + b[5] = addr; + if(stk600_xprog_command(pgm, b, 6, 2) < 0) { + pmsg_error("XPRG_CMD_ERASE(XPRG_ERASE_CHIP) failed\n"); + return -1; + } + return 0; } -/* - * Modify pgm's methods for XPROG operation. - */ -static void stk600_setup_xprog(PROGRAMMER * pgm) -{ - pgm->program_enable = stk600_xprog_program_enable; - pgm->disable = stk600_xprog_disable; - pgm->read_byte = stk600_xprog_read_byte; - pgm->write_byte = stk600_xprog_write_byte; - pgm->paged_load = stk600_xprog_paged_load; - pgm->paged_write = stk600_xprog_paged_write; - pgm->page_erase = stk600_xprog_page_erase; - pgm->chip_erase = stk600_xprog_chip_erase; +static int stk600_xprog_page_erase(const PROGRAMMER *pgm, const AVRPART *p, const AVRMEM *m, unsigned int addr) { + unsigned char b[6]; + + if(mem_is_flash(m)) { + b[1] = stk600_xprog_mtype(pgm, addr) == XPRG_MEM_TYPE_APPL? XPRG_ERASE_APP_PAGE: XPRG_ERASE_BOOT_PAGE; + } else if(mem_is_application(m) || mem_is_apptable(m)) { + b[1] = XPRG_ERASE_APP_PAGE; + } else if(mem_is_boot(m)) { + b[1] = XPRG_ERASE_BOOT_PAGE; + } else if(mem_is_eeprom(m)) { + b[1] = XPRG_ERASE_EEPROM_PAGE; + } else if(mem_is_userrow(m)) { + b[1] = XPRG_ERASE_USERSIG; + } else { + pmsg_error("unknown paged memory %s\n", m->desc); + return -1; + } + addr += m->offset; + b[0] = XPRG_CMD_ERASE; + b[2] = addr >> 24; + b[3] = addr >> 16; + b[4] = addr >> 8; + b[5] = addr; + if(stk600_xprog_command(pgm, b, 6, 2) < 0) { + pmsg_error("XPRG_CMD_ERASE(%d) failed\n", b[1]); + return -1; + } + return 0; } +// Modify pgm's methods for XPROG operation +static void stk600_setup_xprog(PROGRAMMER *pgm) { + pgm->program_enable = stk600_xprog_program_enable; + pgm->disable = stk600_xprog_disable; + pgm->read_byte = stk600_xprog_read_byte; + pgm->write_byte = stk600_xprog_write_byte; + pgm->paged_load = stk600_xprog_paged_load; + pgm->paged_write = stk600_xprog_paged_write; + pgm->page_erase = stk600_xprog_page_erase; + pgm->chip_erase = stk600_xprog_chip_erase; +} -/* - * Modify pgm's methods for ISP operation. - */ -static void stk600_setup_isp(PROGRAMMER * pgm) -{ +// Modify pgm's methods for ISP operation +static void stk600_setup_isp(PROGRAMMER *pgm) { pgm->program_enable = stk500v2_program_enable; pgm->disable = stk500v2_disable; pgm->read_byte = stk500isp_read_byte; @@ -4885,50 +4739,44 @@ const char stk500v2_desc[] = "Atmel STK500 Version 2.x firmware"; void stk500v2_initpgm(PROGRAMMER *pgm) { strcpy(pgm->type, "STK500V2"); - /* - * mandatory functions - */ - pgm->initialize = stk500v2_initialize; - pgm->display = stk500v2_display; - pgm->enable = stk500v2_enable; - pgm->disable = stk500v2_disable; + // Mandatory functions + pgm->initialize = stk500v2_initialize; + pgm->display = stk500v2_display; + pgm->enable = stk500v2_enable; + pgm->disable = stk500v2_disable; pgm->program_enable = stk500v2_program_enable; - pgm->chip_erase = stk500v2_chip_erase; - pgm->cmd = stk500v2_cmd; - pgm->open = stk500v2_open; - pgm->close = stk500v2_close; - pgm->read_byte = stk500isp_read_byte; - pgm->write_byte = stk500isp_write_byte; + pgm->chip_erase = stk500v2_chip_erase; + pgm->cmd = stk500v2_cmd; + pgm->open = stk500v2_open; + pgm->close = stk500v2_close; + pgm->read_byte = stk500isp_read_byte; + pgm->write_byte = stk500isp_write_byte; - /* - * optional functions - */ - pgm->paged_write = stk500v2_paged_write; - pgm->paged_load = stk500v2_paged_load; - pgm->page_erase = NULL; - pgm->print_parms = stk500v2_print_parms; + // Optional functions + pgm->paged_write = stk500v2_paged_write; + pgm->paged_load = stk500v2_paged_load; + pgm->page_erase = NULL; + pgm->print_parms = stk500v2_print_parms; pgm->set_sck_period = stk500v2_set_sck_period; pgm->get_sck_period = stk500v2_get_sck_period; pgm->perform_osccal = stk500v2_perform_osccal; pgm->parseextparams = stk500v2_parseextparms; - pgm->setup = stk500v2_setup; - pgm->teardown = stk500v2_teardown; - pgm->page_size = 256; + pgm->setup = stk500v2_setup; + pgm->teardown = stk500v2_teardown; + pgm->page_size = 256; - /* - * hardware dependent functions - */ - if (pgm->extra_features & HAS_VTARG_ADJ) - pgm->set_vtarget = stk500v2_set_vtarget; - if (pgm->extra_features & HAS_VTARG_READ) - pgm->get_vtarget = stk500v2_get_vtarget; - if (pgm->extra_features & HAS_VAREF_ADJ) { - pgm->set_varef = stk500v2_set_varef; - pgm->get_varef = stk500v2_get_varef; + // Hardware dependent functions + if(pgm->extra_features & HAS_VTARG_ADJ) + pgm->set_vtarget = stk500v2_set_vtarget; + if(pgm->extra_features & HAS_VTARG_READ) + pgm->get_vtarget = stk500v2_get_vtarget; + if(pgm->extra_features & HAS_VAREF_ADJ) { + pgm->set_varef = stk500v2_set_varef; + pgm->get_varef = stk500v2_get_varef; } - if (pgm->extra_features & HAS_FOSC_ADJ) { - pgm->set_fosc = stk500v2_set_fosc; - pgm->get_fosc = stk500v2_get_fosc; + if(pgm->extra_features & HAS_FOSC_ADJ) { + pgm->set_fosc = stk500v2_set_fosc; + pgm->get_fosc = stk500v2_get_fosc; } } @@ -4937,41 +4785,35 @@ const char stk500pp_desc[] = "Atmel STK500 V2 in parallel programming mode"; void stk500pp_initpgm(PROGRAMMER *pgm) { strcpy(pgm->type, "STK500PP"); - /* - * mandatory functions - */ - pgm->initialize = stk500pp_initialize; - pgm->display = stk500v2_display; - pgm->enable = stk500v2_enable; - pgm->disable = stk500pp_disable; + // Mandatory functions + pgm->initialize = stk500pp_initialize; + pgm->display = stk500v2_display; + pgm->enable = stk500v2_enable; + pgm->disable = stk500pp_disable; pgm->program_enable = stk500pp_program_enable; - pgm->chip_erase = stk500pp_chip_erase; - pgm->open = stk500v2_open; - pgm->close = stk500v2_close; - pgm->read_byte = stk500pp_read_byte; - pgm->write_byte = stk500pp_write_byte; - - /* - * optional functions - */ - pgm->paged_write = stk500pp_paged_write; - pgm->paged_load = stk500pp_paged_load; - pgm->print_parms = stk500v2_print_parms; + pgm->chip_erase = stk500pp_chip_erase; + pgm->open = stk500v2_open; + pgm->close = stk500v2_close; + pgm->read_byte = stk500pp_read_byte; + pgm->write_byte = stk500pp_write_byte; + + // Optional functions + pgm->paged_write = stk500pp_paged_write; + pgm->paged_load = stk500pp_paged_load; + pgm->print_parms = stk500v2_print_parms; pgm->set_sck_period = stk500v2_set_sck_period; pgm->parseextparams = stk500v2_parseextparms; - pgm->setup = stk500v2_setup; - pgm->teardown = stk500v2_teardown; - pgm->page_size = 256; + pgm->setup = stk500v2_setup; + pgm->teardown = stk500v2_teardown; + pgm->page_size = 256; - /* - * hardware dependent functions - */ - if (pgm->extra_features & HAS_VTARG_ADJ) - pgm->set_vtarget = stk500v2_set_vtarget; - if (pgm->extra_features & HAS_VAREF_ADJ) - pgm->set_varef = stk500v2_set_varef; - if (pgm->extra_features & HAS_FOSC_ADJ) - pgm->set_fosc = stk500v2_set_fosc; + // Hardware dependent functions + if(pgm->extra_features & HAS_VTARG_ADJ) + pgm->set_vtarget = stk500v2_set_vtarget; + if(pgm->extra_features & HAS_VAREF_ADJ) + pgm->set_varef = stk500v2_set_varef; + if(pgm->extra_features & HAS_FOSC_ADJ) + pgm->set_fosc = stk500v2_set_fosc; } const char stk500hvsp_desc[] = "Atmel STK500 V2 in high-voltage serial programming mode"; @@ -4979,41 +4821,35 @@ const char stk500hvsp_desc[] = "Atmel STK500 V2 in high-voltage serial programmi void stk500hvsp_initpgm(PROGRAMMER *pgm) { strcpy(pgm->type, "STK500HVSP"); - /* - * mandatory functions - */ - pgm->initialize = stk500hvsp_initialize; - pgm->display = stk500v2_display; - pgm->enable = stk500v2_enable; - pgm->disable = stk500hvsp_disable; + // Mandatory functions + pgm->initialize = stk500hvsp_initialize; + pgm->display = stk500v2_display; + pgm->enable = stk500v2_enable; + pgm->disable = stk500hvsp_disable; pgm->program_enable = stk500hvsp_program_enable; - pgm->chip_erase = stk500hvsp_chip_erase; - pgm->open = stk500v2_open; - pgm->close = stk500v2_close; - pgm->read_byte = stk500hvsp_read_byte; - pgm->write_byte = stk500hvsp_write_byte; - - /* - * optional functions - */ - pgm->paged_write = stk500hvsp_paged_write; - pgm->paged_load = stk500hvsp_paged_load; - pgm->print_parms = stk500v2_print_parms; + pgm->chip_erase = stk500hvsp_chip_erase; + pgm->open = stk500v2_open; + pgm->close = stk500v2_close; + pgm->read_byte = stk500hvsp_read_byte; + pgm->write_byte = stk500hvsp_write_byte; + + // Optional functions + pgm->paged_write = stk500hvsp_paged_write; + pgm->paged_load = stk500hvsp_paged_load; + pgm->print_parms = stk500v2_print_parms; pgm->set_sck_period = stk500v2_set_sck_period; pgm->parseextparams = stk500v2_parseextparms; - pgm->setup = stk500v2_setup; - pgm->teardown = stk500v2_teardown; - pgm->page_size = 256; + pgm->setup = stk500v2_setup; + pgm->teardown = stk500v2_teardown; + pgm->page_size = 256; - /* - * hardware dependent functions - */ - if (pgm->extra_features & HAS_VTARG_ADJ) - pgm->set_vtarget = stk500v2_set_vtarget; - if (pgm->extra_features & HAS_VAREF_ADJ) - pgm->set_varef = stk500v2_set_varef; - if (pgm->extra_features & HAS_FOSC_ADJ) - pgm->set_fosc = stk500v2_set_fosc; + // Hardware dependent functions + if(pgm->extra_features & HAS_VTARG_ADJ) + pgm->set_vtarget = stk500v2_set_vtarget; + if(pgm->extra_features & HAS_VAREF_ADJ) + pgm->set_varef = stk500v2_set_varef; + if(pgm->extra_features & HAS_FOSC_ADJ) + pgm->set_fosc = stk500v2_set_fosc; } const char stk500v2_jtagmkII_desc[] = "Atmel JTAG ICE mkII in ISP mode"; @@ -5021,34 +4857,30 @@ const char stk500v2_jtagmkII_desc[] = "Atmel JTAG ICE mkII in ISP mode"; void stk500v2_jtagmkII_initpgm(PROGRAMMER *pgm) { strcpy(pgm->type, "JTAGMKII_ISP"); - /* - * mandatory functions - */ - pgm->initialize = stk500v2_initialize; - pgm->display = stk500v2_display; - pgm->enable = stk500v2_enable; - pgm->disable = stk500v2_disable; + // Mandatory functions + pgm->initialize = stk500v2_initialize; + pgm->display = stk500v2_display; + pgm->enable = stk500v2_enable; + pgm->disable = stk500v2_disable; pgm->program_enable = stk500v2_program_enable; - pgm->chip_erase = stk500v2_chip_erase; - pgm->cmd = stk500v2_cmd; - pgm->open = stk500v2_jtagmkII_open; - pgm->close = stk500v2_jtagmkII_close; - pgm->read_byte = stk500isp_read_byte; - pgm->write_byte = stk500isp_write_byte; + pgm->chip_erase = stk500v2_chip_erase; + pgm->cmd = stk500v2_cmd; + pgm->open = stk500v2_jtagmkII_open; + pgm->close = stk500v2_jtagmkII_close; + pgm->read_byte = stk500isp_read_byte; + pgm->write_byte = stk500isp_write_byte; - /* - * optional functions - */ - pgm->paged_write = stk500v2_paged_write; - pgm->paged_load = stk500v2_paged_load; - pgm->page_erase = NULL; - pgm->print_parms = stk500v2_print_parms; + // Optional functions + pgm->paged_write = stk500v2_paged_write; + pgm->paged_load = stk500v2_paged_load; + pgm->page_erase = NULL; + pgm->print_parms = stk500v2_print_parms; pgm->set_sck_period = stk500v2_set_sck_period_mk2; pgm->get_sck_period = stk500v2_get_sck_period; pgm->perform_osccal = stk500v2_perform_osccal; - pgm->setup = stk500v2_jtagmkII_setup; - pgm->teardown = stk500v2_jtagmkII_teardown; - pgm->page_size = 256; + pgm->setup = stk500v2_jtagmkII_setup; + pgm->teardown = stk500v2_jtagmkII_teardown; + pgm->page_size = 256; } const char stk500v2_dragon_isp_desc[] = "Atmel AVR Dragon in ISP mode"; @@ -5056,34 +4888,30 @@ const char stk500v2_dragon_isp_desc[] = "Atmel AVR Dragon in ISP mode"; void stk500v2_dragon_isp_initpgm(PROGRAMMER *pgm) { strcpy(pgm->type, "DRAGON_ISP"); - /* - * mandatory functions - */ - pgm->initialize = stk500v2_initialize; - pgm->display = stk500v2_display; - pgm->enable = stk500v2_enable; - pgm->disable = stk500v2_disable; + // Mandatory functions + pgm->initialize = stk500v2_initialize; + pgm->display = stk500v2_display; + pgm->enable = stk500v2_enable; + pgm->disable = stk500v2_disable; pgm->program_enable = stk500v2_program_enable; - pgm->chip_erase = stk500v2_chip_erase; - pgm->cmd = stk500v2_cmd; - pgm->open = stk500v2_dragon_isp_open; - pgm->close = stk500v2_jtagmkII_close; - pgm->read_byte = stk500isp_read_byte; - pgm->write_byte = stk500isp_write_byte; + pgm->chip_erase = stk500v2_chip_erase; + pgm->cmd = stk500v2_cmd; + pgm->open = stk500v2_dragon_isp_open; + pgm->close = stk500v2_jtagmkII_close; + pgm->read_byte = stk500isp_read_byte; + pgm->write_byte = stk500isp_write_byte; - /* - * optional functions - */ - pgm->paged_write = stk500v2_paged_write; - pgm->paged_load = stk500v2_paged_load; - pgm->page_erase = NULL; - pgm->print_parms = stk500v2_print_parms; + // Optional functions + pgm->paged_write = stk500v2_paged_write; + pgm->paged_load = stk500v2_paged_load; + pgm->page_erase = NULL; + pgm->print_parms = stk500v2_print_parms; pgm->set_sck_period = stk500v2_set_sck_period_mk2; pgm->get_sck_period = stk500v2_get_sck_period; pgm->perform_osccal = stk500v2_perform_osccal; - pgm->setup = stk500v2_jtagmkII_setup; - pgm->teardown = stk500v2_jtagmkII_teardown; - pgm->page_size = 256; + pgm->setup = stk500v2_jtagmkII_setup; + pgm->teardown = stk500v2_jtagmkII_teardown; + pgm->page_size = 256; } const char stk500v2_dragon_pp_desc[] = "Atmel AVR Dragon in PP mode"; @@ -5091,31 +4919,27 @@ const char stk500v2_dragon_pp_desc[] = "Atmel AVR Dragon in PP mode"; void stk500v2_dragon_pp_initpgm(PROGRAMMER *pgm) { strcpy(pgm->type, "DRAGON_PP"); - /* - * mandatory functions - */ - pgm->initialize = stk500pp_initialize; - pgm->display = stk500v2_display; - pgm->enable = stk500v2_enable; - pgm->disable = stk500pp_disable; + // Mandatory functions + pgm->initialize = stk500pp_initialize; + pgm->display = stk500v2_display; + pgm->enable = stk500v2_enable; + pgm->disable = stk500pp_disable; pgm->program_enable = stk500pp_program_enable; - pgm->chip_erase = stk500pp_chip_erase; - pgm->open = stk500v2_dragon_hv_open; - pgm->close = stk500v2_jtagmkII_close; - pgm->read_byte = stk500pp_read_byte; - pgm->write_byte = stk500pp_write_byte; - - /* - * optional functions - */ - pgm->paged_write = stk500pp_paged_write; - pgm->paged_load = stk500pp_paged_load; - pgm->print_parms = stk500v2_print_parms; + pgm->chip_erase = stk500pp_chip_erase; + pgm->open = stk500v2_dragon_hv_open; + pgm->close = stk500v2_jtagmkII_close; + pgm->read_byte = stk500pp_read_byte; + pgm->write_byte = stk500pp_write_byte; + + // Optional functions + pgm->paged_write = stk500pp_paged_write; + pgm->paged_load = stk500pp_paged_load; + pgm->print_parms = stk500v2_print_parms; pgm->set_sck_period = stk500v2_set_sck_period_mk2; pgm->get_sck_period = stk500v2_get_sck_period; - pgm->setup = stk500v2_jtagmkII_setup; - pgm->teardown = stk500v2_jtagmkII_teardown; - pgm->page_size = 256; + pgm->setup = stk500v2_jtagmkII_setup; + pgm->teardown = stk500v2_jtagmkII_teardown; + pgm->page_size = 256; } const char stk500v2_dragon_hvsp_desc[] = "Atmel AVR Dragon in HVSP mode"; @@ -5123,31 +4947,27 @@ const char stk500v2_dragon_hvsp_desc[] = "Atmel AVR Dragon in HVSP mode"; void stk500v2_dragon_hvsp_initpgm(PROGRAMMER *pgm) { strcpy(pgm->type, "DRAGON_HVSP"); - /* - * mandatory functions - */ - pgm->initialize = stk500hvsp_initialize; - pgm->display = stk500v2_display; - pgm->enable = stk500v2_enable; - pgm->disable = stk500hvsp_disable; + // Mandatory functions + pgm->initialize = stk500hvsp_initialize; + pgm->display = stk500v2_display; + pgm->enable = stk500v2_enable; + pgm->disable = stk500hvsp_disable; pgm->program_enable = stk500hvsp_program_enable; - pgm->chip_erase = stk500hvsp_chip_erase; - pgm->open = stk500v2_dragon_hv_open; - pgm->close = stk500v2_jtagmkII_close; - pgm->read_byte = stk500hvsp_read_byte; - pgm->write_byte = stk500hvsp_write_byte; - - /* - * optional functions - */ - pgm->paged_write = stk500hvsp_paged_write; - pgm->paged_load = stk500hvsp_paged_load; - pgm->print_parms = stk500v2_print_parms; + pgm->chip_erase = stk500hvsp_chip_erase; + pgm->open = stk500v2_dragon_hv_open; + pgm->close = stk500v2_jtagmkII_close; + pgm->read_byte = stk500hvsp_read_byte; + pgm->write_byte = stk500hvsp_write_byte; + + // Optional functions + pgm->paged_write = stk500hvsp_paged_write; + pgm->paged_load = stk500hvsp_paged_load; + pgm->print_parms = stk500v2_print_parms; pgm->set_sck_period = stk500v2_set_sck_period_mk2; pgm->get_sck_period = stk500v2_get_sck_period; - pgm->setup = stk500v2_jtagmkII_setup; - pgm->teardown = stk500v2_jtagmkII_teardown; - pgm->page_size = 256; + pgm->setup = stk500v2_jtagmkII_setup; + pgm->teardown = stk500v2_jtagmkII_teardown; + pgm->page_size = 256; } const char stk600_desc[] = "Atmel STK600"; @@ -5155,41 +4975,37 @@ const char stk600_desc[] = "Atmel STK600"; void stk600_initpgm(PROGRAMMER *pgm) { strcpy(pgm->type, "STK600"); - /* - * mandatory functions - */ - pgm->initialize = stk500v2_initialize; - pgm->display = stk500v2_display; - pgm->enable = stk500v2_enable; - pgm->disable = stk500v2_disable; + // Mandatory functions + pgm->initialize = stk500v2_initialize; + pgm->display = stk500v2_display; + pgm->enable = stk500v2_enable; + pgm->disable = stk500v2_disable; pgm->program_enable = stk500v2_program_enable; - pgm->chip_erase = stk500v2_chip_erase; - pgm->cmd = stk500v2_cmd; - pgm->open = stk600_open; - pgm->close = stk500v2_close; - pgm->read_byte = stk500isp_read_byte; - pgm->write_byte = stk500isp_write_byte; + pgm->chip_erase = stk500v2_chip_erase; + pgm->cmd = stk500v2_cmd; + pgm->open = stk600_open; + pgm->close = stk500v2_close; + pgm->read_byte = stk500isp_read_byte; + pgm->write_byte = stk500isp_write_byte; - /* - * optional functions - */ - pgm->paged_write = stk500v2_paged_write; - pgm->paged_load = stk500v2_paged_load; - pgm->page_erase = NULL; - pgm->print_parms = stk500v2_print_parms; - pgm->set_vtarget = stk600_set_vtarget; - pgm->get_vtarget = stk500v2_get_vtarget; - pgm->set_varef = stk600_set_varef; - pgm->get_varef = stk500v2_get_varef; - pgm->set_fosc = stk600_set_fosc; - pgm->get_fosc = stk500v2_get_fosc; + // Optional functions + pgm->paged_write = stk500v2_paged_write; + pgm->paged_load = stk500v2_paged_load; + pgm->page_erase = NULL; + pgm->print_parms = stk500v2_print_parms; + pgm->set_vtarget = stk600_set_vtarget; + pgm->get_vtarget = stk500v2_get_vtarget; + pgm->set_varef = stk600_set_varef; + pgm->get_varef = stk500v2_get_varef; + pgm->set_fosc = stk600_set_fosc; + pgm->get_fosc = stk500v2_get_fosc; pgm->set_sck_period = stk600_set_sck_period; pgm->get_sck_period = stk500v2_get_sck_period; pgm->perform_osccal = stk500v2_perform_osccal; pgm->parseextparams = stk500v2_parseextparms; - pgm->setup = stk500v2_setup; - pgm->teardown = stk500v2_teardown; - pgm->page_size = 256; + pgm->setup = stk500v2_setup; + pgm->teardown = stk500v2_teardown; + pgm->page_size = 256; } const char stk600pp_desc[] = "Atmel STK600 in parallel programming mode"; @@ -5197,38 +5013,34 @@ const char stk600pp_desc[] = "Atmel STK600 in parallel programming mode"; void stk600pp_initpgm(PROGRAMMER *pgm) { strcpy(pgm->type, "STK600PP"); - /* - * mandatory functions - */ - pgm->initialize = stk500pp_initialize; - pgm->display = stk500v2_display; - pgm->enable = stk500v2_enable; - pgm->disable = stk500pp_disable; + // Mandatory functions + pgm->initialize = stk500pp_initialize; + pgm->display = stk500v2_display; + pgm->enable = stk500v2_enable; + pgm->disable = stk500pp_disable; pgm->program_enable = stk500pp_program_enable; - pgm->chip_erase = stk500pp_chip_erase; - pgm->open = stk600_open; - pgm->close = stk500v2_close; - pgm->read_byte = stk500pp_read_byte; - pgm->write_byte = stk500pp_write_byte; - - /* - * optional functions - */ - pgm->paged_write = stk500pp_paged_write; - pgm->paged_load = stk500pp_paged_load; - pgm->print_parms = stk500v2_print_parms; - pgm->set_vtarget = stk600_set_vtarget; - pgm->get_vtarget = stk500v2_get_vtarget; - pgm->set_varef = stk600_set_varef; - pgm->get_varef = stk500v2_get_varef; - pgm->set_fosc = stk600_set_fosc; - pgm->get_fosc = stk500v2_get_fosc; + pgm->chip_erase = stk500pp_chip_erase; + pgm->open = stk600_open; + pgm->close = stk500v2_close; + pgm->read_byte = stk500pp_read_byte; + pgm->write_byte = stk500pp_write_byte; + + // Optional functions + pgm->paged_write = stk500pp_paged_write; + pgm->paged_load = stk500pp_paged_load; + pgm->print_parms = stk500v2_print_parms; + pgm->set_vtarget = stk600_set_vtarget; + pgm->get_vtarget = stk500v2_get_vtarget; + pgm->set_varef = stk600_set_varef; + pgm->get_varef = stk500v2_get_varef; + pgm->set_fosc = stk600_set_fosc; + pgm->get_fosc = stk500v2_get_fosc; pgm->set_sck_period = stk600_set_sck_period; pgm->get_sck_period = stk500v2_get_sck_period; pgm->parseextparams = stk500v2_parseextparms; - pgm->setup = stk500v2_setup; - pgm->teardown = stk500v2_teardown; - pgm->page_size = 256; + pgm->setup = stk500v2_setup; + pgm->teardown = stk500v2_teardown; + pgm->page_size = 256; } const char stk600hvsp_desc[] = "Atmel STK600 in high-voltage serial programming mode"; @@ -5236,38 +5048,34 @@ const char stk600hvsp_desc[] = "Atmel STK600 in high-voltage serial programming void stk600hvsp_initpgm(PROGRAMMER *pgm) { strcpy(pgm->type, "STK600HVSP"); - /* - * mandatory functions - */ - pgm->initialize = stk500hvsp_initialize; - pgm->display = stk500v2_display; - pgm->enable = stk500v2_enable; - pgm->disable = stk500hvsp_disable; + // Mandatory functions + pgm->initialize = stk500hvsp_initialize; + pgm->display = stk500v2_display; + pgm->enable = stk500v2_enable; + pgm->disable = stk500hvsp_disable; pgm->program_enable = stk500hvsp_program_enable; - pgm->chip_erase = stk500hvsp_chip_erase; - pgm->open = stk600_open; - pgm->close = stk500v2_close; - pgm->read_byte = stk500hvsp_read_byte; - pgm->write_byte = stk500hvsp_write_byte; - - /* - * optional functions - */ - pgm->paged_write = stk500hvsp_paged_write; - pgm->paged_load = stk500hvsp_paged_load; - pgm->print_parms = stk500v2_print_parms; - pgm->set_vtarget = stk600_set_vtarget; - pgm->get_vtarget = stk500v2_get_vtarget; - pgm->set_varef = stk600_set_varef; - pgm->get_varef = stk500v2_get_varef; - pgm->set_fosc = stk600_set_fosc; - pgm->get_fosc = stk500v2_get_fosc; + pgm->chip_erase = stk500hvsp_chip_erase; + pgm->open = stk600_open; + pgm->close = stk500v2_close; + pgm->read_byte = stk500hvsp_read_byte; + pgm->write_byte = stk500hvsp_write_byte; + + // Optional functions + pgm->paged_write = stk500hvsp_paged_write; + pgm->paged_load = stk500hvsp_paged_load; + pgm->print_parms = stk500v2_print_parms; + pgm->set_vtarget = stk600_set_vtarget; + pgm->get_vtarget = stk500v2_get_vtarget; + pgm->set_varef = stk600_set_varef; + pgm->get_varef = stk500v2_get_varef; + pgm->set_fosc = stk600_set_fosc; + pgm->get_fosc = stk500v2_get_fosc; pgm->set_sck_period = stk600_set_sck_period; pgm->get_sck_period = stk500v2_get_sck_period; pgm->parseextparams = stk500v2_parseextparms; - pgm->setup = stk500v2_setup; - pgm->teardown = stk500v2_teardown; - pgm->page_size = 256; + pgm->setup = stk500v2_setup; + pgm->teardown = stk500v2_teardown; + pgm->page_size = 256; } const char stk500v2_jtag3_desc[] = "Atmel JTAGICE3 in ISP mode"; @@ -5275,41 +5083,35 @@ const char stk500v2_jtag3_desc[] = "Atmel JTAGICE3 in ISP mode"; void stk500v2_jtag3_initpgm(PROGRAMMER *pgm) { strcpy(pgm->type, "JTAG3_ISP"); - /* - * mandatory functions - */ - pgm->initialize = stk500v2_jtag3_initialize; - pgm->display = stk500v2_display; - pgm->enable = stk500v2_enable; - pgm->disable = stk500v2_jtag3_disable; + // Mandatory functions + pgm->initialize = stk500v2_jtag3_initialize; + pgm->display = stk500v2_display; + pgm->enable = stk500v2_enable; + pgm->disable = stk500v2_jtag3_disable; pgm->program_enable = stk500v2_program_enable; - pgm->chip_erase = stk500v2_chip_erase; - pgm->cmd = stk500v2_jtag3_cmd; - pgm->open = stk500v2_jtag3_open; - pgm->close = stk500v2_jtag3_close; - pgm->read_byte = stk500isp_read_byte; - pgm->write_byte = stk500isp_write_byte; + pgm->chip_erase = stk500v2_chip_erase; + pgm->cmd = stk500v2_jtag3_cmd; + pgm->open = stk500v2_jtag3_open; + pgm->close = stk500v2_jtag3_close; + pgm->read_byte = stk500isp_read_byte; + pgm->write_byte = stk500isp_write_byte; - /* - * optional functions - */ - pgm->paged_write = stk500v2_paged_write; - pgm->paged_load = stk500v2_paged_load; - pgm->page_erase = NULL; - pgm->print_parms = stk500v2_print_parms; + // Optional functions + pgm->paged_write = stk500v2_paged_write; + pgm->paged_load = stk500v2_paged_load; + pgm->page_erase = NULL; + pgm->print_parms = stk500v2_print_parms; pgm->set_sck_period = stk500v2_jtag3_set_sck_period; pgm->get_sck_period = stk500v2_jtag3_get_sck_period; pgm->perform_osccal = stk500v2_perform_osccal; pgm->parseextparams = stk500v2_jtag3_parseextparms; - pgm->setup = stk500v2_jtag3_setup; - pgm->teardown = stk500v2_jtag3_teardown; - pgm->page_size = 256; + pgm->setup = stk500v2_jtag3_setup; + pgm->teardown = stk500v2_jtag3_teardown; + pgm->page_size = 256; - /* - * hardware dependent functions - */ - if (pgm->extra_features & HAS_VTARG_ADJ) + // Hardware dependent functions + if(pgm->extra_features & HAS_VTARG_ADJ) pgm->set_vtarget = jtag3_set_vtarget; - if (pgm->extra_features & HAS_VTARG_READ) + if(pgm->extra_features & HAS_VTARG_READ) pgm->get_vtarget = jtag3_get_vtarget; } diff --git a/src/stk500v2.h b/src/stk500v2.h index 9f060f3c0..6fbd28d86 100644 --- a/src/stk500v2.h +++ b/src/stk500v2.h @@ -24,38 +24,35 @@ extern "C" { #endif -extern const char stk500v2_desc[]; -extern const char stk500hvsp_desc[]; -extern const char stk500pp_desc[]; -extern const char stk500v2_jtagmkII_desc[]; -extern const char stk500v2_dragon_hvsp_desc[]; -extern const char stk500v2_dragon_isp_desc[]; -extern const char stk500v2_dragon_pp_desc[]; -extern const char stk500v2_jtag3_desc[]; -extern const char stk600_desc[]; -extern const char stk600hvsp_desc[]; -extern const char stk600pp_desc[]; -void stk500v2_initpgm(PROGRAMMER *pgm); -void stk500hvsp_initpgm(PROGRAMMER *pgm); -void stk500pp_initpgm(PROGRAMMER *pgm); -void stk500v2_jtagmkII_initpgm(PROGRAMMER *pgm); -void stk500v2_jtag3_initpgm(PROGRAMMER *pgm); -void stk500v2_dragon_hvsp_initpgm(PROGRAMMER *pgm); -void stk500v2_dragon_isp_initpgm(PROGRAMMER *pgm); -void stk500v2_dragon_pp_initpgm(PROGRAMMER *pgm); -void stk600_initpgm(PROGRAMMER *pgm); -void stk600hvsp_initpgm(PROGRAMMER *pgm); -void stk600pp_initpgm(PROGRAMMER *pgm); - -void stk500v2_setup(PROGRAMMER * pgm); -void stk500v2_teardown(PROGRAMMER * pgm); -int stk500v2_drain(const PROGRAMMER *pgm, int display); -int stk500v2_getsync(const PROGRAMMER *pgm); + extern const char stk500v2_desc[]; + extern const char stk500hvsp_desc[]; + extern const char stk500pp_desc[]; + extern const char stk500v2_jtagmkII_desc[]; + extern const char stk500v2_dragon_hvsp_desc[]; + extern const char stk500v2_dragon_isp_desc[]; + extern const char stk500v2_dragon_pp_desc[]; + extern const char stk500v2_jtag3_desc[]; + extern const char stk600_desc[]; + extern const char stk600hvsp_desc[]; + extern const char stk600pp_desc[]; + void stk500v2_initpgm(PROGRAMMER *pgm); + void stk500hvsp_initpgm(PROGRAMMER *pgm); + void stk500pp_initpgm(PROGRAMMER *pgm); + void stk500v2_jtagmkII_initpgm(PROGRAMMER *pgm); + void stk500v2_jtag3_initpgm(PROGRAMMER *pgm); + void stk500v2_dragon_hvsp_initpgm(PROGRAMMER *pgm); + void stk500v2_dragon_isp_initpgm(PROGRAMMER *pgm); + void stk500v2_dragon_pp_initpgm(PROGRAMMER *pgm); + void stk600_initpgm(PROGRAMMER *pgm); + void stk600hvsp_initpgm(PROGRAMMER *pgm); + void stk600pp_initpgm(PROGRAMMER *pgm); + + void stk500v2_setup(PROGRAMMER *pgm); + void stk500v2_teardown(PROGRAMMER *pgm); + int stk500v2_drain(const PROGRAMMER *pgm, int display); + int stk500v2_getsync(const PROGRAMMER *pgm); #ifdef __cplusplus } #endif - #endif - - diff --git a/src/stk500v2_private.h b/src/stk500v2_private.h index 723f0712e..8c19ba481 100644 --- a/src/stk500v2_private.h +++ b/src/stk500v2_private.h @@ -1,11 +1,11 @@ //**** ATMEL AVR - A P P L I C A T I O N N O T E ************************ //* -//* Title: AVR068 - STK500 Communication Protocol -//* Filename: command.h -//* Version: 1.0 -//* Last updated: 10.01.2005 +//* Title: AVR068 - STK500 Communication Protocol +//* Filename: command.h +//* Version: 1.0 +//* Last updated: 10.01.2005 //* -//* Support E-mail: avr@atmel.com +//* Support E-mail: avr@atmel.com //* //************************************************************************** @@ -27,7 +27,6 @@ #define CMD_LOAD_RC_ID_TABLE 0x0E #define CMD_LOAD_EC_ID_TABLE 0x0F - // *****************[ STK ISP command constants ]****************************** #define CMD_ENTER_PROGMODE_ISP 0x10 @@ -43,10 +42,9 @@ #define CMD_READ_LOCK_ISP 0x1A #define CMD_READ_SIGNATURE_ISP 0x1B #define CMD_READ_OSCCAL_ISP 0x1C -#define CMD_SPI_MULTI 0x1D /* STK500v2, AVRISPmkII, - * JTAGICEmkII */ -#define CMD_SET_SCK 0x1D /* JTAGICE3 */ -#define CMD_GET_SCK 0x1E /* JTAGICE3 */ +#define CMD_SPI_MULTI 0x1D // STK500v2, AVRISPmkII, JTAGICEmkII +#define CMD_SET_SCK 0x1D // JTAGICE3 +#define CMD_GET_SCK 0x1E // JTAGICE3 // *****************[ STK PP command constants ]******************************* @@ -81,8 +79,7 @@ #define CMD_READ_LOCK_HVSP 0x3A #define CMD_READ_SIGNATURE_HVSP 0x3B #define CMD_READ_OSCCAL_HVSP 0x3C -// These two are redefined since 0x30/0x31 collide -// with the STK600 bootloader. +// These two are redefined since 0x30/0x31 collide with the STK600 bootloader #define CMD_ENTER_PROGMODE_HVSP_STK600 0x3D #define CMD_LEAVE_PROGMODE_HVSP_STK600 0x3E @@ -91,14 +88,12 @@ #define CMD_XPROG 0x50 #define CMD_XPROG_SETMODE 0x51 - // *** AVR32 JTAG Programming command *** #define CMD_JTAG_AVR32 0x80 #define CMD_ENTER_PROGMODE_JTAG_AVR32 0x81 #define CMD_LEAVE_PROGMODE_JTAG_AVR32 0x82 - // *** AVR JTAG Programming command *** #define CMD_JTAG_AVR 0x90 @@ -171,24 +166,23 @@ // Set to '1' if board draws excessive current // *****************[ STK parameter constants ]*************************** -#define PARAM_BUILD_NUMBER_LOW 0x80 /* ??? */ -#define PARAM_BUILD_NUMBER_HIGH 0x81 /* ??? */ +#define PARAM_BUILD_NUMBER_LOW 0x80 // ??? +#define PARAM_BUILD_NUMBER_HIGH 0x81 // ??? #define PARAM_HW_VER 0x90 #define PARAM_SW_MAJOR 0x91 #define PARAM_SW_MINOR 0x92 #define PARAM_VTARGET 0x94 -#define PARAM_VADJUST 0x95 /* STK500 only */ -#define PARAM_OSC_PSCALE 0x96 /* STK500 only */ -#define PARAM_OSC_CMATCH 0x97 /* STK500 only */ -#define PARAM_SCK_DURATION 0x98 /* STK500 only */ -#define PARAM_TOPCARD_DETECT 0x9A /* STK500 only */ -#define PARAM_STATUS 0x9C /* STK500 only */ -#define PARAM_DATA 0x9D /* STK500 only */ -#define PARAM_RESET_POLARITY 0x9E /* STK500 only, and STK600 FW - * version <= 2.0.3 */ +#define PARAM_VADJUST 0x95 // STK500 only +#define PARAM_OSC_PSCALE 0x96 // STK500 only +#define PARAM_OSC_CMATCH 0x97 // STK500 only +#define PARAM_SCK_DURATION 0x98 // STK500 only +#define PARAM_TOPCARD_DETECT 0x9A // STK500 only +#define PARAM_STATUS 0x9C // STK500 only +#define PARAM_DATA 0x9D // STK500 only +#define PARAM_RESET_POLARITY 0x9E // STK500 only, and STK600 FW version <= 2.0.3 #define PARAM_CONTROLLER_INIT 0x9F -/* STK600 parameters */ +// STK600 parameters #define PARAM_STATUS_TGT_CONN 0xA1 #define PARAM_DISCHARGEDELAY 0xA4 #define PARAM_SOCKETCARD_ID 0xA5 @@ -220,34 +214,28 @@ #define PARAM2_RC_ID_TABLE_REV 0xC8 #define PARAM2_EC_ID_TABLE_REV 0xC9 -/* STK600 XPROG section */ +// STK600 XPROG section + // XPROG modes #define XPRG_MODE_PDI 0 #define XPRG_MODE_JTAG 1 #define XPRG_MODE_TPI 2 // Write mode flags -#define XPRG_MEM_WRITE_ERASE 0 -#define XPRG_MEM_WRITE_WRITE 1 +#define XPRG_MEM_WRITE_ERASE 0 +#define XPRG_MEM_WRITE_WRITE 1 // CRC types -#define XPRG_CRC_APP 1 -#define XPRG_CRC_BOOT 2 -#define XPRG_CRC_FLASH 3 +#define XPRG_CRC_APP 1 +#define XPRG_CRC_BOOT 2 +#define XPRG_CRC_FLASH 3 // *****************[ STK answer constants ]*************************** #define ANSWER_CKSUM_ERROR 0xB0 -/* - * Private data for this programmer. - */ -struct pdata -{ - /* - * See stk500pp_read_byte() for an explanation of the flash and - * EEPROM page caches. - */ +struct pdata { + // See stk500pp_read_byte() for an explanation of the flash and EEPROM page caches unsigned char *flash_pagecache; unsigned long flash_pageaddr; unsigned int flash_pagesize; @@ -258,62 +246,59 @@ struct pdata unsigned char command_sequence; - enum - { - PGMTYPE_UNKNOWN, - PGMTYPE_STK500, - PGMTYPE_AVRISP, - PGMTYPE_AVRISP_MKII, - PGMTYPE_JTAGICE_MKII, - PGMTYPE_STK600, - PGMTYPE_JTAGICE3 - } - pgmtype; + enum { + PGMTYPE_UNKNOWN, + PGMTYPE_STK500, + PGMTYPE_AVRISP, + PGMTYPE_AVRISP_MKII, + PGMTYPE_JTAGICE_MKII, + PGMTYPE_STK600, + PGMTYPE_JTAGICE3 + } pgmtype; int is_scratchmonkey, scratchmonkey_leds; - /* Get/set flags for Xplained Mini SUFFER register */ + // Get/set flags for Xplained Mini SUFFER register bool suffer_get; bool suffer_set; unsigned char suffer_data[2]; - /* Get/set flags for target power switch */ + // Get/set flags for target power switch bool vtarg_switch_get; bool vtarg_switch_set; unsigned char vtarg_switch_data[2]; - /* Get/set flags for adjustable target voltage */ + // Get/set flags for adjustable target voltage bool vtarg_get; bool vtarg_set; double vtarg_data; - /* Get/set flags for adjustable analog reference voltage */ + // Get/set flags for adjustable analog reference voltage bool varef_get; bool varef_set; int varef_channel; double varef_data; - /* Get/set flags for programmable clock generator */ + // Get/set flags for programmable clock generator bool fosc_get; bool fosc_set; double fosc_data; - /* Set STK500 XTAL frequency */ + // Set STK500 XTAL frequency unsigned xtal; - /* Flag for PICkit4/SNAP mode switching */ + // Flag for PICkit4/SNAP mode switching int pk4_snap_mode; const AVRPART *lastpart; - /* Start address of Xmega boot area */ + // Start address of Xmega boot area unsigned long boot_start; /* - * Chained pdata for the JTAG ICE mkII backend. This is used when - * calling the backend functions for ISP/HVSP/PP programming - * functionality of the JTAG ICE mkII and AVR Dragon. + * Chained pdata for the JTAG ICE mkII backend. This is used when calling + * the backend functions for ISP/HVSP/PP programming functionality of the + * JTAG ICE mkII and AVR Dragon. */ void *chained_pdata; }; - diff --git a/src/strutil.c b/src/strutil.c index cfd491f49..c60a83ba8 100644 --- a/src/strutil.c +++ b/src/strutil.c @@ -1,5 +1,5 @@ /* - * AVRDUDE - A Downloader/Uploader for AVR device programmers + * avrdude - A Downloader/Uploader for AVR device programmers * Copyright (C) 2023 Hans Eirik Bull * Copyright (C) 2023 Stefan Rueger * @@ -47,10 +47,10 @@ int str_contains(const char *str, const char *substr) { // Return 1 if str ends in ends, 0 otherwise int str_ends(const char *str, const char *ends) { - size_t str_len = strlen(str); + size_t str_len = strlen(str); size_t ends_len = strlen(ends); - if (ends_len > str_len) + if(ends_len > str_len) return 0; return str_eq(str + str_len - ends_len, ends); @@ -68,10 +68,10 @@ int str_caseeq(const char *str1, const char *str2) { // Return 1 if str ends in ends irrespective of case, 0 otherwise int str_caseends(const char *str, const char *ends) { - size_t str_len = strlen(str); + size_t str_len = strlen(str); size_t ends_len = strlen(ends); - if (ends_len > str_len) + if(ends_len > str_len) return 0; return str_caseeq(str + str_len - ends_len, ends); @@ -86,7 +86,7 @@ int str_caseends(const char *str, const char *ends) { */ inline static int fold(int c) { - return (c >= 'A' && c <= 'Z')? c+('a'-'A'): c; + return (c >= 'A' && c <= 'Z')? c + ('a' - 'A'): c; } inline static int nofold(int c) { @@ -122,7 +122,7 @@ static int str_match_core(const char *pattern, const char *string, int (*fold)(i return 1; { - unsigned char c1 = fold(c == '\\'? *p : c); // This char + unsigned char c1 = fold(c == '\\'? *p: c); // This char for(--p; *n; ++n) // Recursively check reminder of string for * if((c == '[' || fold(*n) == c1) && str_match_core(p, n, fold) == 1) @@ -223,14 +223,19 @@ int str_casematched_by(const char *string, const char *pattern) { int str_is_pattern(const char *str) { for(;;) switch(*str++) { - case 0: return 0; - case '*': case '?': case '[': case '\\': return 1; + case 0: + return 0; + case '*': + case '?': + case '[': + case '\\': + return 1; } } // Is the string s in the list l of strings as matched by f(s, l[i])? -int str_is_in_list(const char *s, const char **l, size_t nl, int (*f)(const char *, const char*)) { - for(size_t i=0; iavr_space - AVR_SAFETY_MARGIN; + if(size > avail) size = avail; char *ret = avr_cc_buffer(size); + strncpy(ret, str, size); - ret[size-1] = 0; + ret[size - 1] = 0; return ret; } - // Reads a potentially long line and returns it in a mmt_malloc'd buffer char *str_fgets(FILE *fp, const char **errpp) { int bs = 1023; // Must be 2^n - 1 char *ret = (char *) mmt_malloc(bs); - ret[bs-2] = 0; + ret[bs - 2] = 0; if(!fgets(ret, bs, fp)) { mmt_free(ret); if(errpp) @@ -316,7 +322,7 @@ char *str_fgets(FILE *fp, const char **errpp) { return NULL; } - while(ret[bs-2] != 0 && ret[bs-2] != '\n' && ret[bs-2] != '\r') { + while(ret[bs - 2] != 0 && ret[bs - 2] != '\n' && ret[bs - 2] != '\r') { if(bs >= INT_MAX/2) { mmt_free(ret); if(errpp) @@ -324,10 +330,11 @@ char *str_fgets(FILE *fp, const char **errpp) { return NULL; } int was = bs; - bs = 2*bs+1; + + bs = 2*bs + 1; ret = mmt_realloc(ret, bs); - ret[was-1] = ret[bs-2] = 0; - if(!fgets(ret+was-1, bs-(was-1), fp)) { // EOF? Error? + ret[was - 1] = ret[bs - 2] = 0; + if(!fgets(ret + was - 1, bs - (was - 1), fp)) { // EOF? Error? if(ferror(fp)) { mmt_free(ret); if(errpp) @@ -343,7 +350,6 @@ char *str_fgets(FILE *fp, const char **errpp) { return ret; } - // Return the number of times a character c occurs in str size_t str_numc(const char *str, char c) { size_t ret = 0; @@ -366,7 +372,7 @@ const char *str_ltrim(const char *s) { char *str_nrtrim(char *s, size_t n) { s[n] = 0; if(n) - for(char *z = s+n-1; z >= s && isascii(*z & 0xff) && isspace(*z & 0xff); z--) + for(char *z = s + n - 1; z >= s && isascii(*z & 0xff) && isspace(*z & 0xff); z--) *z = 0; return s; } @@ -416,23 +422,57 @@ char *str_ucfirst(char *s) { char *str_asciiname(char *s) { for(char *t = s; *t; t++) switch(*t) { - case '?': *t = 'Q'; break; - case '*': *t = 'X'; break; - case '|': *t = 'I'; break; - case '{': *t = 'l'; break; - case '}': *t = 'j'; break; - case '[': *t = 'L'; break; - case ']': *t = 'J'; break; - case '(': *t = 'L'; break; - case ')': *t = 'J'; break; - case '<': *t = 'l'; break; - case '>': *t = 'j'; break; - case '&': *t = '+'; break; - case '!': *t = 'I'; break; - case '"': *t = 'q'; break; - case '\'': *t = 'q'; break; - case '`': *t = 'q'; break; - case '.': case '-': break; + case '?': + *t = 'Q'; + break; + case '*': + *t = 'X'; + break; + case '|': + *t = 'I'; + break; + case '{': + *t = 'l'; + break; + case '}': + *t = 'j'; + break; + case '[': + *t = 'L'; + break; + case ']': + *t = 'J'; + break; + case '(': + *t = 'L'; + break; + case ')': + *t = 'J'; + break; + case '<': + *t = 'l'; + break; + case '>': + *t = 'j'; + break; + case '&': + *t = '+'; + break; + case '!': + *t = 'I'; + break; + case '"': + *t = 'q'; + break; + case '\'': + *t = 'q'; + break; + case '`': + *t = 'q'; + break; + case '.': + case '-': + break; default: if(!isascii(*t & 0xff) || !isalnum(*t & 0xff)) *t = '_'; @@ -441,7 +481,6 @@ char *str_asciiname(char *s) { return s; } - // Convert unsigned to ASCII string; caller needs to allocate enough space for buf char *str_utoa(unsigned n, char *buf, int base) { unsigned q; @@ -449,7 +488,7 @@ char *str_utoa(unsigned n, char *buf, int base) { if(base == 'r') { const char *units = "IVXLCDMFTYHSNabcdefghijkl"; - const char *rep[10] = {"", "a", "aa", "aaa", "ab", "b", "ba", "baa", "baaa", "ac"}; + const char *rep[10] = { "", "a", "aa", "aaa", "ab", "b", "ba", "baa", "baaa", "ac" }; if(n == 0) { strcpy(buf, "0"); @@ -457,15 +496,18 @@ char *str_utoa(unsigned n, char *buf, int base) { } int i = 0; + for(unsigned u = n; u; u /= 10) i++; for(*buf = 0; i > 0; i--) { unsigned u = n; - for(int j=1; j cp2; ) { + for(char *cp2 = buf; cp > cp2;) { char c = *cp; + *cp-- = *cp2; *cp2++ = c; } @@ -507,7 +547,7 @@ char *str_endnumber(const char *str) { if(!str) return NULL; - for(const char *end = str + strlen(str)-1; end >= str; end--) + for(const char *end = str + strlen(str) - 1; end >= str; end--) if(isdigit((unsigned char) *end)) ret = end; else @@ -516,17 +556,17 @@ char *str_endnumber(const char *str) { return (char *) ret; } - // Convenience functions for printing const char *str_plural(int x) { - return x==1? "": "s"; + return x == 1? "": "s"; } static const char *str_filename(const char *fn, const char *stdname) { if(!fn) fn = "???"; char *p1 = strrchr(fn, '/'), *p2 = strrchr(fn, '\\'); - return str_eq(fn, "-")? stdname: str_starts(fn, "/dev/")? fn: p1? p1+1: p2? p2+1: fn; + + return str_eq(fn, "-")? stdname: str_starts(fn, "/dev/")? fn: p1? p1 + 1: p2? p2 + 1: fn; } // Path name fn or if fn is - @@ -551,17 +591,19 @@ const char *str_outfilename(const char *fn) { // Return sth like "[0, 0x1ff]" in closed-circuit space const char *str_ccinterval(int a, int b) { - char *ret = avr_cc_buffer(45); // Interval strings each max 45 bytes at 64-bit int + char *ret = avr_cc_buffer(45); // Interval strings each max 45 bytes at 64-bit int - sprintf(ret, a<16? "[%d": "[0x%x", a); - sprintf(ret+strlen(ret), b<16? ", %d]": ", 0x%x]", b); + sprintf(ret, a < 16? "[%d": "[0x%x", a); + sprintf(ret + strlen(ret), b < 16? ", %d]": ", 0x%x]", b); return ret; } - bool is_bigendian() { - union {char a[2]; int16_t i;} u = {.i = 1}; + union { + char a[2]; + int16_t i; + } u = {.i = 1 }; return u.a[1] == 1; } @@ -569,11 +611,10 @@ bool is_bigendian() { void change_endian(void *p, int size) { uint8_t tmp, *w = p; - for(int i=0; ilim; - size_t ni = i+1; - for(unsigned j=0; jchr)) break; ret += dig->val; @@ -652,7 +694,6 @@ unsigned long long int easteregg(const char *str, const char **endpp) { return ret; } - // Like strtoull but knows binary, too unsigned long long int str_ull(const char *str, char **endptr, int base) { const char *nptr = str, *ep; @@ -676,9 +717,9 @@ unsigned long long int str_ull(const char *str, char **endptr, int base) { } if((base == 0 || base == 2) && *nptr == '0' && (nptr[1] == 'b' || nptr[1] == 'B')) - base = 2, nptr+=2; + base = 2, nptr += 2; else if((base == 0 || base == 16) && *nptr == '0' && (nptr[1] == 'x' || nptr[1] == 'X')) - base = 16, nptr+=2; + base = 16, nptr += 2; errno = 0; if((base == 0 || base == 'r') && (ret = easteregg(nptr, &ep)) && ep != nptr && !*ep) { @@ -687,12 +728,11 @@ unsigned long long int str_ull(const char *str, char **endptr, int base) { } else { ret = strtoull(nptr, endptr, base); if(endptr && *endptr == nptr) - *endptr = (char *) str; + *endptr = (char *) str; } - if(neg && errno == 0) - ret = ~ret+1; // Same as -ret but silences overzealous compiler warnings + ret = ~ret + 1; // Same as -ret but silences overzealous compiler warnings return ret; } @@ -713,10 +753,9 @@ int looks_like_number(const char *str) { } if(*str == '0' && (str[1] == 'b' || str[1] == 'B')) - base = 2, str+=2; + base = 2, str += 2; else if(*str == '0' && (str[1] == 'x' || str[1] == 'X')) - base = 16, str+=2; - + base = 16, str += 2; errno = 0; (void) strtoull(str, &endptr, base); @@ -724,13 +763,14 @@ int looks_like_number(const char *str) { return endptr != str && !*endptr && !errno; } - /* - * str_todata() is the workhorse for generic string to data conversion for the terminal write - * function, but is also used for generic string to integer conversions in str_int() below. Both - * routines define the "character" of how avrdude understands strings in (most) of its dealings. - * The granularity of type is an bitwise-or combination of bits making up STR_INTEGER; STR_FLOAT; - * STR_DOUBLE or STR_STRING. The arguments part and memstr are only needed for input from files. + * str_todata() is the workhorse for generic string to data conversion for the + * terminal write function, but is also used for generic string to integer + * conversions in str_int() below. Both routines define the "character" of how + * avrdude understands strings in (most) of its dealings. The granularity of + * type is an bitwise-or combination of bits making up STR_INTEGER; STR_FLOAT; + * STR_DOUBLE or STR_STRING. The arguments part and memstr are only needed for + * input from files. */ #define Return(...) do { \ @@ -738,13 +778,13 @@ int looks_like_number(const char *str) { sd->type = 0; \ mmt_free(str); \ return sd; \ -} while (0) +} while(0) #define Warning(...) do { \ if(sd->warnstr) \ mmt_free(sd->warnstr); \ sd->warnstr = mmt_sprintf(__VA_ARGS__); \ -} while (0) +} while(0) #define sizeforsigned(ll) ( \ (ll) < INT32_MIN || (ll) > INT32_MAX? 8: \ @@ -757,8 +797,9 @@ Str2data *str_todata(const char *s, int type, const AVRPART *part, const char *m char *str = mmt_strdup(s); size_t arglen = strlen(str); + // Remove trailing comma to allow cut and paste of lists - if(arglen > 0 && str[arglen-1] == ',') + if(arglen > 0 && str[arglen - 1] == ',') str[--arglen] = 0; if(arglen == 0) @@ -773,7 +814,7 @@ Str2data *str_todata(const char *s, int type, const AVRPART *part, const char *m stri++; sd->ull = 1; - if(sizeof(long long) != sizeof(int64_t) || (sd->a[0]^sd->a[7]) != 1) + if(sizeof(long long) != sizeof(int64_t) || (sd->a[0] ^ sd->a[7]) != 1) Return("assumption on data types not met? Check source and recompile"); is_big_endian = sd->a[7]; @@ -782,39 +823,47 @@ Str2data *str_todata(const char *s, int type, const AVRPART *part, const char *m sd->ull = str_ull(stri, &end_ptr, 0); if(!(end_ptr == stri || errno)) { - unsigned int nu=0, nl=0, nh=0, ns=0, nx=0; + unsigned int nu = 0, nl = 0, nh = 0, ns = 0, nx = 0; // Parse suffixes: ULL, LL, UL, L ... UHH, HH - for(char *p=end_ptr; *p; p++) { + for(char *p = end_ptr; *p; p++) { switch(toupper(*p)) { - case 'U': nu++; break; - case 'L': nl++; break; - case 'H': nh++; break; - case 'S': ns++; break; - default: nx++; + case 'U': + nu++; + break; + case 'L': + nl++; + break; + case 'H': + nh++; + break; + case 'S': + ns++; + break; + default: + nx++; } } - if(nx==0 && nu<2 && nl<3 && nh<3 && ns<2) { // Could be valid integer suffix + if(nx == 0 && nu < 2 && nl < 3 && nh < 3 && ns < 2) { // Could be valid integer suffix // If U, then must be at start or end - if(nu==0 || toupper(*end_ptr) == 'U' || toupper(str[arglen-1]) == 'U') { + if(nu == 0 || toupper(*end_ptr) == 'U' || toupper(str[arglen - 1]) == 'U') { bool is_hex, is_bin; int ndigits; - is_hex = str_casestarts(stri, "0x"); // Ordinary hex without explicit +/- sign - is_bin = str_casestarts(stri, "0b"); // Ordinary bin without explicit +/- sign - ndigits = end_ptr - stri - 2; // Used for is_hex and is_bin - is_signed = !(nu || is_hex || is_bin); // Neither explicitly unsigned nor 0x/0b + is_hex = str_casestarts(stri, "0x"); // Ordinary hex without explicit +/- sign + is_bin = str_casestarts(stri, "0b"); // Ordinary bin without explicit +/- sign + ndigits = end_ptr - stri - 2; // Used for is_hex and is_bin + is_signed = !(nu || is_hex || is_bin); // Neither explicitly unsigned nor 0x/0b if(is_signed) { // Is input in range for int64_t? - if(*stri == '-' && (sd->ull == ~(~0ULL>>1) || sd->ll > 0)) + if(*stri == '-' && (sd->ull == ~(~0ULL >> 1) || sd->ll > 0)) is_outside_int64 = 1; if(*stri != '-' && sd->ll < 0) is_outside_int64 = 1; } - // Set size - if(nl==0 && ns==0 && nh==0) { // No explicit data size + if(nl == 0 && ns == 0 && nh == 0) { // No explicit data size // Ordinary hex/bin get implicit size by number of digits, including leading zeros if(is_hex) { sd->size = ndigits > 8? 8: ndigits > 4? 4: ndigits > 2? 2: 1; @@ -826,41 +875,38 @@ Str2data *str_todata(const char *s, int type, const AVRPART *part, const char *m is_outside_int64? 8: sd->ll < INT32_MIN || sd->ll > (long long) UINT32_MAX? 8: sd->ll < INT16_MIN || sd->ll > (long long) UINT16_MAX? 4: - sd->ll < INT8_MIN || sd->ll > (long long) UINT8_MAX? 2: 1; + sd->ll < INT8_MIN || sd->ll > (long long) UINT8_MAX? 2: 1; if(sd->size < 8) // sigsz is the one needed for signed int sd->sigsz = sizeforsigned(sd->ll); } else { // Smallest size that fits unsigned representation - sd->size = - sd->ull > UINT32_MAX? 8: - sd->ull > UINT16_MAX? 4: - sd->ull > UINT8_MAX? 2: 1; + sd->size = sd->ull > UINT32_MAX? 8: sd->ull > UINT16_MAX? 4: sd->ull > UINT8_MAX? 2: 1; } - } else if(nl==0 && nh==2 && ns==0) { // HH + } else if(nl == 0 && nh == 2 && ns == 0) { // HH sd->size = 1; - if(is_signed && (sd->ll < INT8_MIN || sd->ll > INT8_MAX)) - is_out_of_range = 1; // out of range if uint64 and -uint64 are - else if(!is_signed && sd->ull > UINT8_MAX && ~sd->ull+1 > UINT8_MAX) + if(is_signed && (sd->ll < INT8_MIN || sd->ll > INT8_MAX)) + is_out_of_range = 1; // Out of range if uint64 and -uint64 are + else if(!is_signed && sd->ull > UINT8_MAX && ~sd->ull + 1 > UINT8_MAX) is_out_of_range = 1; if(is_signed) sd->sigsz = sizeforsigned(sd->ll); - } else if(nl==0 && ((nh==1 && ns==0) || (nh==0 && ns==1))) { // H or S + } else if(nl == 0 && ((nh == 1 && ns == 0) || (nh == 0 && ns == 1))) { // H or S sd->size = 2; - if(is_signed && (sd->ll < INT16_MIN || sd->ll > INT16_MAX)) + if(is_signed && (sd->ll < INT16_MIN || sd->ll > INT16_MAX)) is_out_of_range = 1; - else if(!is_signed && sd->ull > UINT16_MAX && ~sd->ull+1 > UINT16_MAX) + else if(!is_signed && sd->ull > UINT16_MAX && ~sd->ull + 1 > UINT16_MAX) is_out_of_range = 1; if(is_signed) sd->sigsz = sizeforsigned(sd->ll); - } else if(nl==1 && nh==0 && ns==0) { // L + } else if(nl == 1 && nh == 0 && ns == 0) { // L sd->size = 4; - if(is_signed && (sd->ll < INT32_MIN || sd->ll > INT32_MAX)) + if(is_signed && (sd->ll < INT32_MIN || sd->ll > INT32_MAX)) is_out_of_range = 1; - else if(!is_signed && sd->ull > UINT32_MAX && ~sd->ull+1 > UINT32_MAX) + else if(!is_signed && sd->ull > UINT32_MAX && ~sd->ull + 1 > UINT32_MAX) is_out_of_range = 1; if(is_signed) sd->sigsz = sizeforsigned(sd->ll); - } else if(nl==2 && nh==0 && ns==0) { // LL + } else if(nl == 2 && nh == 0 && ns == 0) { // LL sd->size = 8; } } @@ -869,18 +915,17 @@ Str2data *str_todata(const char *s, int type, const AVRPART *part, const char *m if(sd->size) { if(sd->sigsz < sd->size) sd->sigsz = sd->size; - if(sd->sigsz < 8) { // Curtail and sign extend the number + if(sd->sigsz < 8) { // Curtail and sign extend the number if(is_big_endian && sd->size > 1) change_endian(sd->a, sd->size); - memset(sd->a+sd->sigsz, is_signed && (sd->a[sd->sigsz-1] & 0x80)? 0xff: 0, 8-sd->sigsz); + memset(sd->a + sd->sigsz, is_signed && (sd->a[sd->sigsz - 1] & 0x80)? 0xff: 0, 8 - sd->sigsz); if(is_big_endian) change_endian(sd->a, sizeof sd->a); } if(is_signed && is_out_of_range) Warning("%s out of int%d range, interpreted as %d-byte %lld%sU", - stri, sd->size*8, sd->size, (long long int) sd->ll, - sd->size == 4? "L": sd->size==2? "H": "HH"); + stri, sd->size*8, sd->size, (long long int) sd->ll, sd->size == 4? "L": sd->size == 2? "H": "HH"); else if(is_out_of_range) Warning("%s out of uint%d range, interpreted as %d-byte %llu", stri, sd->size*8, sd->size, (long long unsigned int) sd->ull); @@ -895,7 +940,7 @@ Str2data *str_todata(const char *s, int type, const AVRPART *part, const char *m if(type & STR_DOUBLE) { // Try double next, must have D suffix sd->d = strtod(str, &end_ptr); - if (end_ptr != str && toupper(*end_ptr) == 'D' && end_ptr[1] == 0) { + if(end_ptr != str && toupper(*end_ptr) == 'D' && end_ptr[1] == 0) { sd->size = 8; sd->type = STR_DOUBLE; mmt_free(str); @@ -906,7 +951,7 @@ Str2data *str_todata(const char *s, int type, const AVRPART *part, const char *m if(type & STR_FLOAT) { // Try float next sd->size = 0; sd->f = strtof(str, &end_ptr); - if (end_ptr != str && toupper(*end_ptr) == 'F' && end_ptr[1] == 0) + if(end_ptr != str && toupper(*end_ptr) == 'F' && end_ptr[1] == 0) sd->size = 4; // Do not accept valid mantissa-only floats that are integer rejects (eg, 078 or ULL overflows) if(end_ptr != str && *end_ptr == 0 && !is_mantissa_only(str)) @@ -919,21 +964,21 @@ Str2data *str_todata(const char *s, int type, const AVRPART *part, const char *m } if(type & STR_STRING && arglen > 1) { // Try C-style string or single character - if((*str == '\'' && str[arglen-1] == '\'') || (*str == '\"' && str[arglen-1] == '\"')) { - char *s = mmt_malloc(arglen-1); + if((*str == '\'' && str[arglen - 1] == '\'') || (*str == '\"' && str[arglen - 1] == '\"')) { + char *s = mmt_malloc(arglen - 1); // Strip start and end quotes, and unescape C string - strncpy(s, str+1, arglen-2); + strncpy(s, str + 1, arglen - 2); cfg_unescape(s, s); - if (*str == '\'') { // Single C-style character + if(*str == '\'') { // Single C-style character if(*s && s[1]) Warning("only using first character of %s", str); sd->a[0] = *s; - memset(sd->a+1, 0, 7); + memset(sd->a + 1, 0, 7); sd->sigsz = sd->size = 1; sd->type = STR_INTEGER; mmt_free(s); - } else { // C-style string + } else { // C-style string sd->str_ptr = s; sd->type = STR_STRING; } @@ -942,17 +987,18 @@ Str2data *str_todata(const char *s, int type, const AVRPART *part, const char *m } } - if(type & STR_FILE && part && memstr) { // File name containing data to be loaded + if(type & STR_FILE && part && memstr) { // File name containing data to be loaded int format = FMT_AUTO; FILE *f; char fmtstr[4] = { 0 }; - if(arglen > 2 && str[arglen-2] == ':') { - fmtstr[0] = ' '; strcpy(fmtstr+1, str+arglen-2); - format = fileio_format(str[arglen-1]); + if(arglen > 2 && str[arglen - 2] == ':') { + fmtstr[0] = ' '; + strcpy(fmtstr + 1, str + arglen - 2); + format = fileio_format(str[arglen - 1]); if(format == FMT_ERROR) Return("unknown format%s suffix of file name", fmtstr); - str[arglen-=2] = 0; + str[arglen -= 2] = 0; } if(format == FMT_AUTO) { f = fileio_fopenr(str); @@ -967,11 +1013,13 @@ Str2data *str_todata(const char *s, int type, const AVRPART *part, const char *m // Obtain a copy of the part incl all memories AVRPART *dp = avr_dup_part(part); AVRMEM *mem = avr_locate_mem(dp, memstr); + if(!mem) { avr_free_part(dp); Return("memory %s not configured for device %s", memstr, part->desc); } int rc = fileio(FIO_READ_FOR_VERIFY, str, format, dp, memstr, -1); + if(rc < 0) { avr_free_part(dp); Return("unable to read the%s %s file", fmtstr, fileio_fmtstr(format)); @@ -1000,33 +1048,37 @@ void str_freedata(Str2data *sd) { } } - /* * Generic string to integer routine that conforms to avrdude terminal syntax * - * Str points to a string that contains an integer terminal data item. Type can be STR_INTEGER or - * a non-zero bitwise-or combination of integer size designators STR_1, STR_2, STR_4 and STR_8 and - * sign type STR_SIGNED or, independently, STR_UNSIGNED. A corresponding range check will be done - * for the numbers that are encoded in the string. If neither or both of STR_UNSIGNED and - * STR_SIGNED was given then the admitted integer can be in either the signed or the unsigned - * range of the given size, otherwise only numbers of the requested signedness range will be - * admitted. Either way, if the string itself restricts the size through a size suffix (see below) - * then any overflow in there will trigger a range error, too. As in C, a sign-changed unsigned - * number will yield another unsigned number greater than or equal to zero. As such, the numbers - * 0, -255U, -254U, ..., -1U are all valid unsigned representations of one-byte integers 0, 1, ... - * 255. At the same time -256U and 256U are not in the one-byte unsigned range [0, 255]. Finally, - * in the case of success str_int() will set the character pointer pointed to by errptr to NULL - * and return an integer in the range of the requested type as unsigned long long. In the case of - * a conversion error, the pointer pointed to by errptr will be set to a human-readable error - * message whilst the returned value has no meaning. + * Str points to a string that contains an integer terminal data item. Type can + * be STR_INTEGER or a non-zero bitwise-or combination of integer size + * designators STR_1, STR_2, STR_4 and STR_8 and sign type STR_SIGNED or, + * independently, STR_UNSIGNED. A corresponding range check will be done for + * the numbers that are encoded in the string. If neither or both of + * STR_UNSIGNED and STR_SIGNED was given then the admitted integer can be in + * either the signed or the unsigned range of the given size, otherwise only + * numbers of the requested signedness range will be admitted. Either way, if + * the string itself restricts the size through a size suffix (see below) then + * any overflow in there will trigger a range error, too. As in C, a + * sign-changed unsigned number will yield another unsigned number greater than + * or equal to zero. As such, the numbers 0, -255U, -254U, ..., -1U are all + * valid unsigned representations of one-byte integers 0, 1, ... 255. At the + * same time -256U and 256U are not in the one-byte unsigned range [0, 255]. + * Finally, in the case of success str_int() will set the character pointer + * pointed to by errptr to NULL and return an integer in the range of the + * requested type as unsigned long long. In the case of a conversion error, the + * pointer pointed to by errptr will be set to a human-readable error message + * whilst the returned value has no meaning. * - * Integer terminal data items are either a literal C-like character such as '\t' or an integer - * string with optional leading white space; optional + or - sign; a binary (leading 0b), octal - * (leading 0), decimal or hexadecimal number (leading 0x); optional size suffix LL/L/S/H/HH; - * optional unsigned U suffix. All terminal data items can have an optional trailing comma to - * allow cutting and pasting lists, and will undergo automated data size and base detection. The - * known integer sizes are either 1 (suffix HH), 2 (suffix H or S), 4 (suffix L) or 8 bytes - * (suffix LL). + * Integer terminal data items are either a literal C-like character such as + * '\t' or an integer string with optional leading white space; optional + or - + * sign; a binary (leading 0b), octal (leading 0), decimal or hexadecimal + * number (leading 0x); optional size suffix LL/L/S/H/HH; optional unsigned U + * suffix. All terminal data items can have an optional trailing comma to allow + * cutting and pasting lists, and will undergo automated data size and base + * detection. The known integer sizes are either 1 (suffix HH), 2 (suffix H or + * S), 4 (suffix L) or 8 bytes (suffix LL). * * Usage example: * @@ -1053,19 +1105,20 @@ unsigned long long int str_int(const char *str, int type, const char **errpp) { sd = str_todata(str, type | STR_STRING, NULL, NULL); // 1<type != STR_INTEGER || sd->errstr) { err = sd->errstr? cache_string(sd->errstr): "not an integral type"; goto finished; } - if(sd->warnstr && strstr(sd->warnstr, " out of ")) { // Convert out of range warning into error + if(sd->warnstr && strstr(sd->warnstr, " out of ")) { // Convert out of range warning into error char *p = strstr(sd->warnstr, "out of "); + if(p) { p = mmt_strdup(p); if(strchr(p, ',')) - *strchr(p, ',') = 0; + *strchr(p, ',') = 0; err = cache_string(p); mmt_free(p); } else { @@ -1074,25 +1127,25 @@ unsigned long long int str_int(const char *str, int type, const char **errpp) { goto finished; } - if(sd->sigsz > (1<sigsz > (1 << lds)) { // Check for range if returned size bigger than requested + int signd = type & (STR_SIGNED | STR_UNSIGNED); long long int smin[4] = { INT8_MIN, INT16_MIN, INT32_MIN, INT64_MIN }; long long int smax[4] = { INT8_MAX, INT16_MAX, INT32_MAX, INT64_MAX }; unsigned long long int umax[4] = { UINT8_MAX, UINT16_MAX, UINT32_MAX, UINT64_MAX }; if(signd == STR_SIGNED) { // Strictly signed if(sd->ll < smin[lds] || sd->ll > smax[lds]) { - err = cache_string(str_ccprintf("out of int%d range", 1<<(3+lds))); + err = cache_string(str_ccprintf("out of int%d range", 1 << (3 + lds))); goto finished; } - } else if(signd == STR_UNSIGNED) { // Strictly unsigned are out of range if u and -u are - if(sd->ull > umax[lds] && ~sd->ull+1 > umax[lds]) { - err = cache_string(str_ccprintf("out of uint%d range", 1<<(3+lds))); + } else if(signd == STR_UNSIGNED) { // Strictly unsigned are out of range if u and -u are + if(sd->ull > umax[lds] && ~sd->ull + 1 > umax[lds]) { + err = cache_string(str_ccprintf("out of uint%d range", 1 << (3 + lds))); goto finished; } } else { // Neither strictly signed or unsigned - if((sd->ll < smin[lds] || sd->ll > smax[lds]) && sd->ull > umax[lds] && ~sd->ull+1 > umax[lds]) { - err = cache_string(str_ccprintf("out of int%d and uint%d range", 1<<(3+lds), 1<<(3+lds))); + if((sd->ll < smin[lds] || sd->ll > smax[lds]) && sd->ull > umax[lds] && ~sd->ull + 1 > umax[lds]) { + err = cache_string(str_ccprintf("out of int%d and uint%d range", 1 << (3 + lds), 1 << (3 + lds))); goto finished; } } @@ -1108,7 +1161,6 @@ unsigned long long int str_int(const char *str, int type, const char **errpp) { return ret; } - // Convert a data string (except STR_FILE) to a memory buffer suitable for AVRMEM use int str_membuf(const char *str, int type, unsigned char *buf, int size, const char **errpp) { int n = 0; @@ -1128,19 +1180,19 @@ int str_membuf(const char *str, int type, unsigned char *buf, int size, const ch if(sd->type == STR_STRING && sd->str_ptr) { size_t len = strlen(sd->str_ptr); + for(size_t j = 0; j < len && n < size; j++) buf[n++] = (uint8_t) sd->str_ptr[j]; if(n < size) // Terminating nul buf[n++] = 0; } else if(sd->size > 0 && (sd->type & STR_NUMBER)) { - // Always write little endian to AVR memory + // Always write little endian to AVR memory if(is_bigendian() && sd->size > 0 && (sd->type & STR_NUMBER)) change_endian(sd->a, sd->size); for(int k = 0; k < sd->size && n < size; k++) buf[n++] = sd->a[k]; } - finished: if(errpp) *errpp = err; @@ -1149,13 +1201,12 @@ int str_membuf(const char *str, int type, unsigned char *buf, int size, const ch return n; } - /* - * Returns the next space separated token in buf (terminating it) and - * places start of next token into pointer pointed to by next. Keeps - * single or double quoted strings together and changes backslash-space - * sequences to space whilst keeping other backslashed characters. - * Used for terminal line parsing and reading files with ASCII numbers. + * Returns the next space separated token in buf (terminating it) and places + * start of next token into pointer pointed to by next. Keeps single or double + * quoted strings together and changes backslash-space sequences to space + * whilst keeping other backslashed characters. Used for terminal line parsing + * and reading files with ASCII numbers. */ char *str_nexttok(char *buf, const char *delim, char **next) { unsigned char *q, *r, *w, inquote; @@ -1169,9 +1220,9 @@ char *str_nexttok(char *buf, const char *delim, char **next) { // Poor man's quote and escape processing if(*r == '"' || *r == '\'') inquote = inquote && *r == inquote? 0: inquote? inquote: *r; - else if(*r == '\\' && r[1] && strchr(delim, r[1])) // Remove \ before space for file names + else if(*r == '\\' && r[1] && strchr(delim, r[1])) // Remove \ before space for file names r++; - else if(*r == '\\' && r[1]) // Leave other \ to keep C-style, eg, '\n' + else if(*r == '\\' && r[1]) // Leave other \ to keep C-style, eg, '\n' *w++ = *r++; } if(*r) @@ -1190,9 +1241,12 @@ char *str_nexttok(char *buf, const char *delim, char **next) { // Return string for frequency with n significant digits and xHz unit in closed-circuit space const char *str_ccfrq(double f, int n) { - struct { double fq; const char *pre; } prefix[] = {{1e9, "G"}, {1e6, "M"}, {1e3, "k"},}; + struct { + double fq; + const char *pre; + } prefix[] = { {1e9, "G"}, {1e6, "M"}, {1e3, "k"}, }; - for(size_t i = 0; i < sizeof prefix/sizeof*prefix; i++) + for(size_t i = 0; i < sizeof prefix/sizeof *prefix; i++) if(f >= prefix[i].fq) return str_ccprintf("%.*g %sHz", n, f/prefix[i].fq, prefix[i].pre); return str_ccprintf("%.*g Hz", n, f); @@ -1204,78 +1258,77 @@ const char *str_cchex(const void *buf, size_t len, int add_space) { len = 64; int wd = 2 + !!add_space; char *ret = avr_cc_buffer(wd*len + 1); - for(size_t i=0; i 0 && j > 0 && str1[i-1] == str2[j] && - str1[i] == str2[j-1] && row2[j+1] > row0[j-1] + swap) - row2[j+1] = row0[j-1] + swap; + if(i > 0 && j > 0 && str1[i - 1] == str2[j] && str1[i] == str2[j - 1] && row2[j + 1] > row0[j - 1] + swap) + row2[j + 1] = row0[j - 1] + swap; // Deletion - if (row2[j+1] > row1[j+1] + del) - row2[j+1] = row1[j+1] + del; + if(row2[j + 1] > row1[j + 1] + del) + row2[j + 1] = row1[j + 1] + del; // Insertion - if (row2[j+1] > row2[j] + add) - row2[j+1] = row2[j] + add; + if(row2[j + 1] > row2[j] + add) + row2[j + 1] = row2[j] + add; } int *temp = row0; + row0 = row1; row1 = row2; row2 = temp; @@ -1287,7 +1340,6 @@ int str_levenshtein(const char *str1, const char *str2, return i; } - // Alphanumeric chars get the full weight, all others such as hyphen or underscore get less static size_t wchr(size_t w, unsigned char c) { return isascii(c) && isalnum(c)? w: w >= 8? w/8: 1; @@ -1296,7 +1348,8 @@ static size_t wchr(size_t w, unsigned char c) { // Index of character in string or -1 of not found static int chridx(char *str, char c) { char *e = strchr(str, c); - return e? e-str: -1; + + return e? e - str: -1; } // (x, y) position of key on keyboard 1 being the centre @@ -1308,16 +1361,16 @@ static void xypos(char c, double *x, double *y) { // My laptop's keyboard layout: your mileage may vary (smr) *x = num >= 0? num: upp >= 0? upp + 0.5: mid >= 0? mid + 0.75: low >= 0? low + 1.25: -3.0; - *y = num >= 0? 0.0: upp >= 0? 1.0: mid >= 0? 2.0: low >= 0? 3.0: -3.0; + *y = num >= 0? 0.0: upp >= 0? 1.0: mid >= 0? 2.0: low >= 0? 3.0: -3.0; } - // Weight by keyboard distance static size_t qwertydist(size_t w, unsigned char c1, unsigned char c2) { if(c1 == c2) return 0; double x1, y1, x2, y2; + xypos(tolower(c1), &x1, &y1); xypos(tolower(c2), &x2, &y2); @@ -1325,7 +1378,8 @@ static size_t qwertydist(size_t w, unsigned char c1, unsigned char c2) { return w; size_t ret = isalpha(c1) && isalpha(c2) && isupper(c1) != isupper(c2)? w/8: 0; - ret += sqrt((x1-x2)*(x1-x2) + (y1-y2)*(y1-y2))/2.5 * w; + + ret += sqrt((x1 - x2)*(x1 - x2) + (y1 - y2)*(y1 - y2))/2.5*w; return ret > w? w: ret > 0? ret: 1; } @@ -1339,6 +1393,7 @@ static size_t csubs(size_t w, unsigned char c1, unsigned char c2) { w = 8; static size_t wmat[128][128]; // Compute once, read-only cache + if(!wmat[0][1]) // Initialize weight matrix for(size_t k1 = 0; k1 < 128; k1++) for(size_t k2 = 0; k2 < 128; k2++) @@ -1346,8 +1401,7 @@ static size_t csubs(size_t w, unsigned char c1, unsigned char c2) { k1 == k2? 0: !isalnum(k1) && !isalnum(k2)? w/8: !isalnum(k1) || !isalnum(k2)? w: - isalpha(k1) && isalpha(k2) && tolower(k1) == tolower(k2)? w/8: - qwertydist(w, k1, k2); + isalpha(k1) && isalpha(k2) && tolower(k1) == tolower(k2)? w/8: qwertydist(w, k1, k2); return wmat[c1][c2]; } @@ -1355,36 +1409,39 @@ static size_t csubs(size_t w, unsigned char c1, unsigned char c2) { // Cost of morphing s1 to s2 modelling typos and mix-up of non-alphanumeric letters size_t str_weighted_damerau_levenshtein(const char *s1, const char *s2) { const size_t swap = 3; // Transposing neighbouring letters is an easy mistake to make - const size_t subst = 32, add = 32, del = 32; // Must be multiples of 8 + const size_t subst = 32, add = 32, del = 32; // Must be multiples of 8 size_t i, j, len1 = strlen(s1), len2 = strlen(s2); - size_t *row0 = mmt_malloc((len2+1)*sizeof*row0); - size_t *row1 = mmt_malloc((len2+1)*sizeof*row1); - size_t *row2 = mmt_malloc((len2+1)*sizeof*row2); + size_t *row0 = mmt_malloc((len2 + 1)*sizeof *row0); + size_t *row1 = mmt_malloc((len2 + 1)*sizeof *row1); + size_t *row2 = mmt_malloc((len2 + 1)*sizeof *row2); unsigned char *str1 = (unsigned char *) s1, *str2 = (unsigned char *) s2; for(j = 0; j < len2; j++) - row1[j+1] = row1[j]+ wchr(add, str2[j]); + row1[j + 1] = row1[j] + wchr(add, str2[j]); for(i = 0; i < len1; i++) { row2[0] = 0; for(size_t k = 0; k <= i; k++) row2[0] += wchr(del, str1[k]); for(j = 0; j < len2; j++) { // Substitution of str1[i] with str2[j] - row2[j+1] = row1[j] + (str1[i] != str2[j]? csubs(subst, str1[i], str2[j]): 0); + row2[j + 1] = row1[j] + (str1[i] != str2[j]? csubs(subst, str1[i], str2[j]): 0); // Swap: str1[i-1]str1[i] is same as str2[j]str2[j-1] - if(i > 0 && j > 0 && str1[i-1] == str2[j] && str1[i] == str2[j-1] && row2[j+1] > row0[j-1] + swap) - row2[j+1] = row0[j-1] + swap; + if(i > 0 && j > 0 && str1[i - 1] == str2[j] && str1[i] == str2[j - 1] && row2[j + 1] > row0[j - 1] + swap) + row2[j + 1] = row0[j - 1] + swap; // Deletion of str1[i] size_t wdel = wchr(del, str1[i]); - if(row2[j+1] > row1[j+1] + wdel) - row2[j+1] = row1[j+1] + wdel; + + if(row2[j + 1] > row1[j + 1] + wdel) + row2[j + 1] = row1[j + 1] + wdel; // Insertion of str2[j] size_t wadd = wchr(add, str2[j]); - if(row2[j+1] > row2[j] + wadd) - row2[j+1] = row2[j] + wadd; + + if(row2[j + 1] > row2[j] + wadd) + row2[j + 1] = row2[j] + wadd; // Todo: fat finger, eg, typing test as tesdt or tedst } size_t *temp = row0; + row0 = row1; row1 = row2; row2 = temp; @@ -1396,21 +1453,21 @@ size_t str_weighted_damerau_levenshtein(const char *s1, const char *s2) { return i; } - // Puts a comma-separated list of matching MCU names into array p with n chars space int str_mcunames_signature(const unsigned char *sigs, int pm, char *p, size_t n) { const char *matches[100]; - int matching = 0, k, N = sizeof matches/sizeof*matches; + int matching = 0, k, N = sizeof matches/sizeof *matches; - if(!pm || (pm & PM_ALL) == PM_ALL) // Look up uP table when unrestricted by prog modes - for(size_t i=0; i < sizeof uP_table/sizeof *uP_table; i++) + if(!pm || (pm & PM_ALL) == PM_ALL) // Look up uP table when unrestricted by prog modes + for(size_t i = 0; i < sizeof uP_table/sizeof *uP_table; i++) if(!is_memset(uP_table[i].sigs, 0xff, 3) && !is_memset(uP_table[i].sigs, 0, 3)) if(0 == memcmp(sigs, uP_table[i].sigs, sizeof uP_table->sigs) && matching < N) matches[matching++] = uP_table[i].name; for(LNODEID lp = lfirst(part_list); lp; lp = lnext(lp)) { AVRPART *pp = ldata(lp); - if(!*pp->id || *pp->id == '.') // Skip invalid entries + + if(!*pp->id || *pp->id == '.') // Skip invalid entries continue; if(is_memset(pp->signature, 0xff, 3) || is_memset(pp->signature, 0, 3)) continue; @@ -1428,6 +1485,7 @@ int str_mcunames_signature(const unsigned char *sigs, int pm, char *p, size_t n) for(int i = 0; i < matching; i++) { size_t len = strlen(matches[i]); + if(n > len + 2) { if(i) { strcpy(p, ", "); @@ -1445,6 +1503,7 @@ int str_mcunames_signature(const unsigned char *sigs, int pm, char *p, size_t n) // Returns a comma-separated list of matching MCU names in closed-circuit space const char *str_ccmcunames_signature(const unsigned char *sigs, int pm) { char names[1024]; + // If no match is found, given required prog_modes, relax the match to any prog mode if(!str_mcunames_signature(sigs, pm, names, sizeof names) && pm && (pm & PM_ALL) != PM_ALL) (void) str_mcunames_signature(sigs, 0, names, sizeof names); @@ -1456,8 +1515,9 @@ const char *str_ccmcunames_signature(const unsigned char *sigs, int pm) { const char *str_ccpgmids(LISTID pgm_id) { char ids[1024], *idp = ids; - for(LNODEID idn=lfirst(pgm_id); idn; idn=lnext(idn)) { + for(LNODEID idn = lfirst(pgm_id); idn; idn = lnext(idn)) { char *id = ldata(idn); + if((idp - ids) + 3 + strlen(id) <= sizeof ids) { if(idp > ids) strcpy(idp, ", "), idp += 2; diff --git a/src/teensy.c b/src/teensy.c index 05adf6dc1..e9fabe1e9 100644 --- a/src/teensy.c +++ b/src/teensy.c @@ -16,26 +16,27 @@ * along with this program. If not, see . */ -// Notes: -// This file adds support for the HalfKay bootloader, -// so you do no longer need the Teensy loader utility. -// -// This HalfKay bootloader is used on various PJRC Teensy boards, -// such as Teensy 2.0 (ATmega32U4), Teensy++ 2.0 (AT90USB1286), -// and the respective clones. -// By default, it bootloader uses the VID/PID 16C0:0478 (VOTI). -// -// As the Teensy bootloader is optimized for size, it implements -// writing to flash memory only. Since it does not support reading, -// use the -V option to prevent avrdude from verifing the flash memory. -// To have avrdude wait for the device to be connected, use the -// extended option '-x wait'. -// -// Example: -// avrdude -c teensy -p m32u4 -x wait -V -U flash:w:main.hex:i +/* + * Notes: + * This file adds support for the HalfKay bootloader, + * so you do no longer need the Teensy loader utility. + * + * This HalfKay bootloader is used on various PJRC Teensy boards, + * such as Teensy 2.0 (ATmega32U4), Teensy++ 2.0 (AT90USB1286), + * and the respective clones. + * By default, it bootloader uses the VID/PID 16C0:0478 (VOTI). + * + * As the Teensy bootloader is optimized for size, it implements + * writing to flash memory only. Since it does not support reading, + * use the -V option to prevent avrdude from verifing the flash memory. + * To have avrdude wait for the device to be connected, use the + * extended option '-x wait'. + * + * Example: + * avrdude -c teensy -p m32u4 -x wait -V -U flash:w:main.hex:i + */ #include - #include #include #include @@ -49,567 +50,513 @@ #include "usbdevs.h" #if defined(HAVE_LIBHIDAPI) - #include -//----------------------------------------------------------------------------- +// ----------------------------------------------------------------------------- #define TEENSY_VID 0x16C0 #define TEENSY_PID 0x0478 #define TEENSY_CONNECT_WAIT 100 -#define PDATA(pgm) ((struct pdata *)(pgm->cookie)) +#define my (*(struct pdata *) (pgm->cookie)) -//----------------------------------------------------------------------------- +// ----------------------------------------------------------------------------- struct pdata { - hid_device* hid_handle; - uint16_t hid_usage; - // Extended parameters - bool wait_until_device_present; - int wait_timout; // in seconds - // Bootloader info (from hid_usage) - const char* board; - uint32_t flash_size; - uint16_t page_size; - uint8_t sig_bytes[3]; - // State - bool erase_flash; - bool reboot; + hid_device *hid_handle; + uint16_t hid_usage; + // Extended parameters + bool wait_until_device_present; + int wait_timout; // Seconds + // Bootloader info (from hid_usage) + const char *board; + uint32_t flash_size; + uint16_t page_size; + uint8_t sig_bytes[3]; + // State + bool erase_flash; + bool reboot; }; -//----------------------------------------------------------------------------- +// ----------------------------------------------------------------------------- -static void delay_ms(uint32_t duration) -{ - usleep(duration * 1000); +static void delay_ms(uint32_t duration) { + usleep(duration*1000); } static int teensy_get_bootloader_info(struct pdata *pdata, const AVRPART *p) { - switch (pdata->hid_usage) - { - case 0x19: - pdata->board = "Teensy 1.0 (AT90USB162)"; - pdata->flash_size = 0x4000 - 0x200; - pdata->page_size = 128; - pdata->sig_bytes[0] = 0x1E; - pdata->sig_bytes[1] = 0x94; - pdata->sig_bytes[2] = 0x82; - break; - case 0x1A: - pdata->board = "Teensy++ 1.0 (AT90USB646)"; - pdata->flash_size = 0x10000 - 0x400; - pdata->page_size = 256; - pdata->sig_bytes[0] = 0x1E; - pdata->sig_bytes[1] = 0x96; - pdata->sig_bytes[2] = 0x82; - break; - case 0x1B: - pdata->board = "Teensy 2.0 (ATmega32U4)"; - pdata->flash_size = 0x8000 - 0x200; - pdata->page_size = 128; - pdata->sig_bytes[0] = 0x1E; - pdata->sig_bytes[1] = 0x95; - pdata->sig_bytes[2] = 0x87; - break; - case 0x1C: - pdata->board = "Teensy++ 2.0 (AT90USB1286)"; - pdata->flash_size = 0x20000 - 0x400; - pdata->page_size = 256; - pdata->sig_bytes[0] = 0x1E; - pdata->sig_bytes[1] = 0x97; - pdata->sig_bytes[2] = 0x82; - break; - default: - if (pdata->hid_usage == 0) - { - // On Linux, libhidapi does not seem to return the HID usage from the report descriptor. - // We try to infer the board from the part information, until somebody fixes libhidapi. - // To use this workaround, the -F option is required. - pmsg_error("cannot detect board type (HID usage is 0)\n"); - - AVRMEM* mem = avr_locate_flash(p); - if (mem == NULL) - { - pmsg_error("no flash memory defined for part %s\n", p->desc); - return -1; - } - - pdata->board = "Unknown Board"; - pdata->flash_size = mem->size - (mem->size < 0x10000 ? 0x200 : 0x400); - pdata->page_size = mem->page_size; - - // Pass an invalid signature to require -F option. - pdata->sig_bytes[0] = 0x1E; - pdata->sig_bytes[1] = 0x00; - pdata->sig_bytes[2] = 0x00; - } - else - { - pmsg_error("Teensy board not supported (HID usage 0x%02X)\n", pdata->hid_usage); - return -1; - } + switch(pdata->hid_usage) { + case 0x19: + pdata->board = "Teensy 1.0 (AT90USB162)"; + pdata->flash_size = 0x4000 - 0x200; + pdata->page_size = 128; + pdata->sig_bytes[0] = 0x1E; + pdata->sig_bytes[1] = 0x94; + pdata->sig_bytes[2] = 0x82; + break; + case 0x1A: + pdata->board = "Teensy++ 1.0 (AT90USB646)"; + pdata->flash_size = 0x10000 - 0x400; + pdata->page_size = 256; + pdata->sig_bytes[0] = 0x1E; + pdata->sig_bytes[1] = 0x96; + pdata->sig_bytes[2] = 0x82; + break; + case 0x1B: + pdata->board = "Teensy 2.0 (ATmega32U4)"; + pdata->flash_size = 0x8000 - 0x200; + pdata->page_size = 128; + pdata->sig_bytes[0] = 0x1E; + pdata->sig_bytes[1] = 0x95; + pdata->sig_bytes[2] = 0x87; + break; + case 0x1C: + pdata->board = "Teensy++ 2.0 (AT90USB1286)"; + pdata->flash_size = 0x20000 - 0x400; + pdata->page_size = 256; + pdata->sig_bytes[0] = 0x1E; + pdata->sig_bytes[1] = 0x97; + pdata->sig_bytes[2] = 0x82; + break; + default: + if(pdata->hid_usage == 0) { + // On Linux, libhidapi does not seem to return the HID usage from the report descriptor. + // We try to infer the board from the part information, until somebody fixes libhidapi. + // To use this workaround, the -F option is required. + pmsg_error("cannot detect board type (HID usage is 0)\n"); + + AVRMEM *mem = avr_locate_flash(p); + + if(mem == NULL) { + pmsg_error("no flash memory defined for part %s\n", p->desc); + return -1; + } + + pdata->board = "Unknown Board"; + pdata->flash_size = mem->size - (mem->size < 0x10000? 0x200: 0x400); + pdata->page_size = mem->page_size; + + // Pass an invalid signature to require -F option. + pdata->sig_bytes[0] = 0x1E; + pdata->sig_bytes[1] = 0x00; + pdata->sig_bytes[2] = 0x00; + } else { + pmsg_error("Teensy board not supported (HID usage 0x%02X)\n", pdata->hid_usage); + return -1; } + } - return 0; + return 0; } static void teensy_dump_device_info(struct pdata *pdata) { - pmsg_notice("HID usage: 0x%02X\n", pdata->hid_usage); - pmsg_notice("Board: %s\n", pdata->board); - pmsg_notice("Available flash size: %u\n", pdata->flash_size); - pmsg_notice("Page size: %u\n", pdata->page_size); - pmsg_notice("Signature: 0x%02X%02X%02X\n", - pdata->sig_bytes[0], pdata->sig_bytes[1], pdata->sig_bytes[2]); + pmsg_notice("HID usage: 0x%02X\n", pdata->hid_usage); + pmsg_notice("Board: %s\n", pdata->board); + pmsg_notice("Available flash size: %u\n", pdata->flash_size); + pmsg_notice("Page size: %u\n", pdata->page_size); + pmsg_notice("Signature: 0x%02X%02X%02X\n", pdata->sig_bytes[0], pdata->sig_bytes[1], pdata->sig_bytes[2]); } -static int teensy_write_page(struct pdata *pdata, uint32_t address, const uint8_t *buffer, uint32_t size, bool suppress_warning) { - pmsg_debug("teensy_write_page(address=0x%06X, size=%d)\n", address, size); +static int teensy_write_page(struct pdata *pdata, uint32_t address, + const uint8_t *buffer, uint32_t size, bool suppress_warning) { - if (size > pdata->page_size) - { - pmsg_error("invalid page size: %u\n", pdata->page_size); - return -1; - } + pmsg_debug("teensy_write_page(address=0x%06X, size=%d)\n", address, size); - size_t report_size = 1 + 2 + (size_t)pdata->page_size; - uint8_t *report = (uint8_t *) mmt_malloc(report_size); + if(size > pdata->page_size) { + pmsg_error("invalid page size: %u\n", pdata->page_size); + return -1; + } - report[0] = 0; // report number - if (pdata->page_size <= 256 && pdata->flash_size < 0x10000) - { - report[1] = (uint8_t)(address >> 0); - report[2] = (uint8_t)(address >> 8); - } - else - { - report[1] = (uint8_t)(address >> 8); - report[2] = (uint8_t)(address >> 16); - } + size_t report_size = 1 + 2 + (size_t) pdata->page_size; + uint8_t *report = (uint8_t *) mmt_malloc(report_size); - if (size > 0) - { - memcpy(report + 1 + 2, buffer, size); - } + report[0] = 0; // Report number + if(pdata->page_size <= 256 && pdata->flash_size < 0x10000) { + report[1] = (uint8_t) (address >> 0); + report[2] = (uint8_t) (address >> 8); + } else { + report[1] = (uint8_t) (address >> 8); + report[2] = (uint8_t) (address >> 16); + } - memset(report + 1 + 2 + size, 0xFF, report_size - (1 + 2 + size)); + if(size > 0) { + memcpy(report + 1 + 2, buffer, size); + } - int result = hid_write(pdata->hid_handle, report, report_size); - mmt_free(report); - if (result < 0) - { - if (!suppress_warning) - pmsg_error("unable to write page: %ls\n", hid_error(pdata->hid_handle)); + memset(report + 1 + 2 + size, 0xFF, report_size - (1 + 2 + size)); - return result; - } + int result = hid_write(pdata->hid_handle, report, report_size); - return 0; + mmt_free(report); + if(result < 0) { + if(!suppress_warning) + pmsg_error("unable to write page: %ls\n", hid_error(pdata->hid_handle)); + + return result; + } + + return 0; } static int teensy_erase_flash(struct pdata *pdata) { - pmsg_debug("teensy_erase_flash()\n"); + pmsg_debug("teensy_erase_flash()\n"); - // Write a dummy page at address 0 to explicitly erase the flash. - return teensy_write_page(pdata, 0, NULL, 0, false); + // Write a dummy page at address 0 to explicitly erase the flash. + return teensy_write_page(pdata, 0, NULL, 0, false); } static int teensy_reboot(struct pdata *pdata) { - pmsg_debug("teensy_reboot()\n"); + pmsg_debug("teensy_reboot()\n"); - // Write a dummy page at address -1 to reboot the Teensy. - return teensy_write_page(pdata, 0xFFFFFFFF, NULL, 0, true); + // Write a dummy page at address -1 to reboot the Teensy. + return teensy_write_page(pdata, 0xFFFFFFFF, NULL, 0, true); } -//----------------------------------------------------------------------------- +// ----------------------------------------------------------------------------- static void teensy_setup(PROGRAMMER *pgm) { - pmsg_debug("teensy_setup()\n"); - pgm->cookie = mmt_malloc(sizeof(struct pdata)); + pmsg_debug("teensy_setup()\n"); + pgm->cookie = mmt_malloc(sizeof(struct pdata)); } static void teensy_teardown(PROGRAMMER *pgm) { - pmsg_debug("teensy_teardown()\n"); - mmt_free(pgm->cookie); - pgm->cookie = NULL; + pmsg_debug("teensy_teardown()\n"); + mmt_free(pgm->cookie); + pgm->cookie = NULL; } static int teensy_initialize(const PROGRAMMER *pgm, const AVRPART *p) { - pmsg_debug("teensy_initialize()\n"); + pmsg_debug("teensy_initialize()\n"); - struct pdata *pdata = PDATA(pgm); + struct pdata *pdata = &my; - int result = teensy_get_bootloader_info(pdata, p); - if (result < 0) - return result; + int result = teensy_get_bootloader_info(pdata, p); - teensy_dump_device_info(pdata); + if(result < 0) + return result; - return 0; + teensy_dump_device_info(pdata); + + return 0; } static void teensy_display(const PROGRAMMER *pgm, const char *prefix) { - // pmsg_debug("teensy_display()\n"); + // pmsg_debug("teensy_display()\n"); } static void teensy_powerup(const PROGRAMMER *pgm) { - pmsg_debug("teensy_powerup()\n"); + pmsg_debug("teensy_powerup()\n"); } static void teensy_powerdown(const PROGRAMMER *pgm) { - pmsg_debug("teensy_powerdown()\n"); + pmsg_debug("teensy_powerdown()\n"); - struct pdata *pdata = PDATA(pgm); + struct pdata *pdata = &my; - if (pdata->erase_flash) - { - teensy_erase_flash(pdata); - pdata->erase_flash = false; - } + if(pdata->erase_flash) { + teensy_erase_flash(pdata); + pdata->erase_flash = false; + } - if (pdata->reboot) - { - teensy_reboot(pdata); - pdata->reboot = false; - } + if(pdata->reboot) { + teensy_reboot(pdata); + pdata->reboot = false; + } } -static void teensy_enable(PROGRAMMER* pgm, const AVRPART *p) { - pmsg_debug("teensy_enable()\n"); +static void teensy_enable(PROGRAMMER *pgm, const AVRPART *p) { + pmsg_debug("teensy_enable()\n"); } static void teensy_disable(const PROGRAMMER *pgm) { - pmsg_debug("teensy_disable()\n"); + pmsg_debug("teensy_disable()\n"); } static int teensy_program_enable(const PROGRAMMER *pgm, const AVRPART *p) { - pmsg_debug("teensy_program_enable()\n"); - return 0; + pmsg_debug("teensy_program_enable()\n"); + return 0; } static int teensy_read_sig_bytes(const PROGRAMMER *pgm, const AVRPART *p, const AVRMEM *mem) { - pmsg_debug("teensy_read_sig_bytes()\n"); + pmsg_debug("teensy_read_sig_bytes()\n"); - if (mem->size < 3) - { - pmsg_error("memory size too small for read_sig_bytes\n"); - return -1; - } + if(mem->size < 3) { + pmsg_error("memory size too small for read_sig_bytes\n"); + return -1; + } - struct pdata *pdata = PDATA(pgm); - memcpy(mem->buf, pdata->sig_bytes, sizeof(pdata->sig_bytes)); + struct pdata *pdata = &my; - return 0; + memcpy(mem->buf, pdata->sig_bytes, sizeof(pdata->sig_bytes)); + + return 0; } static int teensy_chip_erase(const PROGRAMMER *pgm, const AVRPART *p) { - pmsg_debug("teensy_chip_erase()\n"); + pmsg_debug("teensy_chip_erase()\n"); - struct pdata *pdata = PDATA(pgm); + struct pdata *pdata = &my; - // Schedule a chip erase, either at first write or on powerdown. - pdata->erase_flash = true; + // Schedule a chip erase, either at first write or on powerdown. + pdata->erase_flash = true; - return 0; + return 0; } static int teensy_open(PROGRAMMER *pgm, const char *port) { - pmsg_debug("teensy_open(\"%s\")\n", port); + pmsg_debug("teensy_open(\"%s\")\n", port); + + struct pdata *pdata = &my; + const char *bus_name = NULL; + char *dev_name = NULL; + + // If no -P was given or '-P usb' was given + if(str_eq(port, "usb")) { + port = NULL; + } else { + // Calculate bus and device names from -P option + if(str_starts(port, "usb") && ':' == port[3]) { + bus_name = port + 4; + dev_name = strchr(bus_name, ':'); + if(dev_name != NULL) { + *dev_name = '\0'; + dev_name++; + } + } + } - struct pdata *pdata = PDATA(pgm); - const char *bus_name = NULL; - char* dev_name = NULL; + if(port != NULL && dev_name == NULL) { + pmsg_error("invalid -P %s; use -P usb:bus:device\n", port); + return -1; + } + // Determine VID/PID + int vid = pgm->usbvid? pgm->usbvid: TEENSY_VID; + int pid = TEENSY_PID; - // if no -P was given or '-P usb' was given - if (str_eq(port, "usb")) - { - port = NULL; - } - else - { - // calculate bus and device names from -P option - if (str_starts(port, "usb") && ':' == port[3]) - { - bus_name = port + 4; - dev_name = strchr(bus_name, ':'); - if (dev_name != NULL) - { - *dev_name = '\0'; - dev_name++; - } - } - } + LNODEID usbpid = lfirst(pgm->usbpid); - if (port != NULL && dev_name == NULL) - { - pmsg_error("invalid -P %s; use -P usb:bus:device\n", port); - return -1; + if(usbpid != NULL) { + pid = *(int *) (ldata(usbpid)); + if(lnext(usbpid)) { + pmsg_error("using PID 0x%04x, ignoring remaining PIDs in list\n", pid); } + } - // Determine VID/PID - int vid = pgm->usbvid ? pgm->usbvid : TEENSY_VID; - int pid = TEENSY_PID; - - LNODEID usbpid = lfirst(pgm->usbpid); - if (usbpid != NULL) - { - pid = *(int*)(ldata(usbpid)); - if (lnext(usbpid)) - { - pmsg_error("using PID 0x%04x, ignoring remaining PIDs in list\n", pid); + bool show_retry_message = true; + + time_t start_time = time(NULL); + + for(;;) { + // Search for device + struct hid_device_info *devices = hid_enumerate(vid, pid); + struct hid_device_info *device = devices; + + while(device) { + if(device->vendor_id == vid && device->product_id == pid) { + pdata->hid_handle = hid_open_path(device->path); + if(pdata->hid_handle == NULL) { + pmsg_error("found HID device, but hid_open_path() failed\n"); + } else { + pdata->hid_usage = device->usage; + break; } + } + + device = device->next; } - bool show_retry_message = true; - - time_t start_time = time(NULL); - for (;;) - { - // Search for device - struct hid_device_info* devices = hid_enumerate(vid, pid); - struct hid_device_info* device = devices; - - while (device) - { - if (device->vendor_id == vid && device->product_id == pid) - { - pdata->hid_handle = hid_open_path(device->path); - if (pdata->hid_handle == NULL) - { - pmsg_error("found HID device, but hid_open_path() failed\n"); - } - else - { - pdata->hid_usage = device->usage; - break; - } - } - - device = device->next; - } + hid_free_enumeration(devices); - hid_free_enumeration(devices); - - if (pdata->hid_handle == NULL && pdata->wait_until_device_present) - { - if (show_retry_message) - { - if (pdata->wait_timout < 0) - { - pmsg_error("no device found, waiting for device to be plugged in ...\n"); - } - else - { - pmsg_error("no device found, waiting %d seconds for device to be plugged in ...\n", - pdata->wait_timout); - } - - pmsg_error("press CTRL-C to terminate\n"); - show_retry_message = false; - } - - if (pdata->wait_timout < 0 || (time(NULL) - start_time) < pdata->wait_timout) - { - delay_ms(TEENSY_CONNECT_WAIT); - continue; - } + if(pdata->hid_handle == NULL && pdata->wait_until_device_present) { + if(show_retry_message) { + if(pdata->wait_timout < 0) { + pmsg_error("no device found, waiting for device to be plugged in ...\n"); + } else { + pmsg_error("no device found, waiting %d seconds for device to be plugged in ...\n", pdata->wait_timout); } - break; - } + pmsg_error("press CTRL-C to terminate\n"); + show_retry_message = false; + } - if (!pdata->hid_handle) - { - pmsg_error("cannot find device with Teensy bootloader (%04X:%04X)\n", vid, pid); - return -1; + if(pdata->wait_timout < 0 || (time(NULL) - start_time) < pdata->wait_timout) { + delay_ms(TEENSY_CONNECT_WAIT); + continue; + } } - return 0; + break; + } + + if(!pdata->hid_handle) { + pmsg_error("cannot find device with Teensy bootloader (%04X:%04X)\n", vid, pid); + return -1; + } + + return 0; } -static void teensy_close(PROGRAMMER* pgm) -{ - pmsg_debug("teensy_close()\n"); +static void teensy_close(PROGRAMMER *pgm) { + pmsg_debug("teensy_close()\n"); - struct pdata *pdata = PDATA(pgm); - if (pdata->hid_handle != NULL) - { - hid_close(pdata->hid_handle); - pdata->hid_handle = NULL; - } + struct pdata *pdata = &my; + + if(pdata->hid_handle != NULL) { + hid_close(pdata->hid_handle); + pdata->hid_handle = NULL; + } } static int teensy_read_byte(const PROGRAMMER *pgm, const AVRPART *p, const AVRMEM *mem, - unsigned long addr, unsigned char* value) -{ - pmsg_debug("teensy_read_byte(desc=%s, addr=0x%04lX)\n", mem->desc, addr); - - if (mem_is_a_fuse(mem) || mem_is_lock(mem)) - { - *value = 0xFF; - return 0; - } - else - { - pmsg_error("unsupported memory %s\n", mem->desc); - return -1; - } + unsigned long addr, unsigned char *value) { + pmsg_debug("teensy_read_byte(desc=%s, addr=0x%04lX)\n", mem->desc, addr); + + if(mem_is_a_fuse(mem) || mem_is_lock(mem)) { + *value = 0xFF; + return 0; + } else { + pmsg_error("unsupported memory %s\n", mem->desc); + return -1; + } } static int teensy_write_byte(const PROGRAMMER *pgm, const AVRPART *p, const AVRMEM *mem, - unsigned long addr, unsigned char value) -{ - pmsg_debug("teensy_write_byte(desc=%s, addr=0x%04lX)\n", mem->desc, addr); - return -1; + unsigned long addr, unsigned char value) { + pmsg_debug("teensy_write_byte(desc=%s, addr=0x%04lX)\n", mem->desc, addr); + return -1; } static int teensy_paged_load(const PROGRAMMER *pgm, const AVRPART *p, const AVRMEM *mem, - unsigned int page_size, - unsigned int addr, unsigned int n_bytes) -{ - pmsg_debug("teensy_paged_load(page_size=0x%X, addr=0x%X, n_bytes=0x%X)\n", page_size, addr, n_bytes); - return -1; + unsigned int page_size, unsigned int addr, unsigned int n_bytes) { + pmsg_debug("teensy_paged_load(page_size=0x%X, addr=0x%X, n_bytes=0x%X)\n", page_size, addr, n_bytes); + return -1; } static int teensy_paged_write(const PROGRAMMER *pgm, const AVRPART *p, const AVRMEM *mem, - unsigned int page_size, - unsigned int addr, unsigned int n_bytes) -{ - pmsg_debug("teensy_paged_write(page_size=0x%X, addr=0x%X, n_bytes=0x%X)\n", page_size, addr, n_bytes); - - if (mem_is_flash(mem)) - { - struct pdata *pdata = PDATA(pgm); - - if (n_bytes > page_size) - { - pmsg_error("buffer size %u exceeds page size %u\n", n_bytes, page_size); - return -1; - } + unsigned int page_size, unsigned int addr, unsigned int n_bytes) { + pmsg_debug("teensy_paged_write(page_size=0x%X, addr=0x%X, n_bytes=0x%X)\n", page_size, addr, n_bytes); - if (addr + n_bytes > pdata->flash_size) - { - pmsg_error("program size %u exceeds flash size %u\n", addr + n_bytes, pdata->flash_size); - return -1; - } + if(mem_is_flash(mem)) { + struct pdata *pdata = &my; - if (pdata->erase_flash) - { - // Writing page 0 will automatically erase the flash. - // If mem does not contain a page at address 0, write a dummy page at address 0. - if (addr != 0) - { - int result = teensy_erase_flash(pdata); - if (result < 0) - { - return result; - } - } - - pdata->erase_flash = false; - } + if(n_bytes > page_size) { + pmsg_error("buffer size %u exceeds page size %u\n", n_bytes, page_size); + return -1; + } - int result = teensy_write_page(pdata, addr, mem->buf + addr, n_bytes, false); - if (result < 0) - { - return result; - } + if(addr + n_bytes > pdata->flash_size) { + pmsg_error("program size %u exceeds flash size %u\n", addr + n_bytes, pdata->flash_size); + return -1; + } + + if(pdata->erase_flash) { + // Writing page 0 will automatically erase the flash. + // If mem does not contain a page at address 0, write a dummy page at address 0. + if(addr != 0) { + int result = teensy_erase_flash(pdata); - // Schedule a reboot. - pdata->reboot = true; + if(result < 0) { + return result; + } + } - return result; + pdata->erase_flash = false; } - else - { - pmsg_error("unsupported memory %s\n", mem->desc); - return -1; + + int result = teensy_write_page(pdata, addr, mem->buf + addr, n_bytes, false); + + if(result < 0) { + return result; } + // Schedule a reboot. + pdata->reboot = true; + + return result; + } else { + pmsg_error("unsupported memory %s\n", mem->desc); + return -1; + } } static int teensy_parseextparams(const PROGRAMMER *pgm, const LISTID xparams) { - int rv = 0; - bool help = false; - pmsg_debug("teensy_parseextparams()\n"); - - struct pdata *pdata = PDATA(pgm); - for (LNODEID node = lfirst(xparams); node; node = lnext(node)) - { - const char* extended_param = ldata(node); - - if (str_eq(extended_param, "wait")) - { - pdata->wait_until_device_present = true; - pdata->wait_timout = -1; - continue; - } + int rv = 0; + bool help = false; - if (str_starts(extended_param, "wait=")) - { - pdata->wait_until_device_present = true; - pdata->wait_timout = atoi(extended_param + 5); - continue; - } + pmsg_debug("teensy_parseextparams()\n"); - if (str_eq(extended_param, "help")) - { - help = true; - rv = LIBAVRDUDE_EXIT; - } + struct pdata *pdata = &my; - if (!help) - { - pmsg_error("invalid extended parameter -x %s\n", extended_param); - rv = -1; - } - msg_error("%s -c %s extended options:\n", progname, pgmid); - msg_error(" -x wait Wait for the device to be plugged in if not connected\n"); - msg_error(" -x wait= Wait s for the device to be plugged in if not connected\n"); - msg_error(" -x help Show this help menu and exit\n"); - return rv; + for(LNODEID node = lfirst(xparams); node; node = lnext(node)) { + const char *extended_param = ldata(node); + + if(str_eq(extended_param, "wait")) { + pdata->wait_until_device_present = true; + pdata->wait_timout = -1; + continue; + } + + if(str_starts(extended_param, "wait=")) { + pdata->wait_until_device_present = true; + pdata->wait_timout = atoi(extended_param + 5); + continue; + } + + if(str_eq(extended_param, "help")) { + help = true; + rv = LIBAVRDUDE_EXIT; } + if(!help) { + pmsg_error("invalid extended parameter -x %s\n", extended_param); + rv = -1; + } + msg_error("%s -c %s extended options:\n", progname, pgmid); + msg_error(" -x wait Wait for the device to be plugged in if not connected\n"); + msg_error(" -x wait= Wait s for the device to be plugged in if not connected\n"); + msg_error(" -x help Show this help menu and exit\n"); return rv; + } + + return rv; } void teensy_initpgm(PROGRAMMER *pgm) { - strcpy(pgm->type, "teensy"); - - pgm->setup = teensy_setup; - pgm->teardown = teensy_teardown; - pgm->initialize = teensy_initialize; - pgm->display = teensy_display; - pgm->powerup = teensy_powerup; - pgm->powerdown = teensy_powerdown; - pgm->enable = teensy_enable; - pgm->disable = teensy_disable; - pgm->program_enable = teensy_program_enable; - pgm->read_sig_bytes = teensy_read_sig_bytes; - pgm->chip_erase = teensy_chip_erase; - pgm->cmd = NULL; - pgm->open = teensy_open; - pgm->close = teensy_close; - pgm->read_byte = teensy_read_byte; - pgm->write_byte = teensy_write_byte; - pgm->paged_load = teensy_paged_load; - pgm->paged_write = teensy_paged_write; - pgm->parseextparams = teensy_parseextparams; + strcpy(pgm->type, "teensy"); + + pgm->setup = teensy_setup; + pgm->teardown = teensy_teardown; + pgm->initialize = teensy_initialize; + pgm->display = teensy_display; + pgm->powerup = teensy_powerup; + pgm->powerdown = teensy_powerdown; + pgm->enable = teensy_enable; + pgm->disable = teensy_disable; + pgm->program_enable = teensy_program_enable; + pgm->read_sig_bytes = teensy_read_sig_bytes; + pgm->chip_erase = teensy_chip_erase; + pgm->cmd = NULL; + pgm->open = teensy_open; + pgm->close = teensy_close; + pgm->read_byte = teensy_read_byte; + pgm->write_byte = teensy_write_byte; + pgm->paged_load = teensy_paged_load; + pgm->paged_write = teensy_paged_write; + pgm->parseextparams = teensy_parseextparams; } -#else /* !HAVE_LIBHIDAPI */ +#else // ! HAVE_LIBHIDAPI // Give a proper error if we were not compiled with libhidapi static int teensy_nousb_open(PROGRAMMER *pgm, const char *name) { - pmsg_error("no HID support; please compile again with libhidapi installed\n"); - return -1; + pmsg_error("no HID support; please compile again with libhidapi installed\n"); + return -1; } void teensy_initpgm(PROGRAMMER *pgm) { - strcpy(pgm->type, "teensy"); - pgm->open = teensy_nousb_open; + strcpy(pgm->type, "teensy"); + pgm->open = teensy_nousb_open; } - -#endif /* HAVE_LIBHIDAPI */ +#endif // HAVE_LIBHIDAPI const char teensy_desc[] = "Teensy Bootloader"; diff --git a/src/teensy.h b/src/teensy.h index f617e9d5b..ddaa6b3ab 100644 --- a/src/teensy.h +++ b/src/teensy.h @@ -25,11 +25,11 @@ extern "C" { #endif -extern const char teensy_desc[]; -void teensy_initpgm(PROGRAMMER *pgm); + extern const char teensy_desc[]; + void teensy_initpgm(PROGRAMMER *pgm); #ifdef __cplusplus } #endif -#endif /* teensy_h */ +#endif diff --git a/src/term.c b/src/term.c index e097185b1..eb32a2254 100644 --- a/src/term.c +++ b/src/term.c @@ -51,7 +51,6 @@ #endif #endif - #include "avrdude.h" struct command { @@ -61,78 +60,76 @@ struct command { char *desc; }; - -static int cmd_dump (const PROGRAMMER *pgm, const AVRPART *p, int argc, const char *argv[]); -static int cmd_disasm (const PROGRAMMER *pgm, const AVRPART *p, int argc, const char *argv[]); -static int cmd_write (const PROGRAMMER *pgm, const AVRPART *p, int argc, const char *argv[]); -static int cmd_save (const PROGRAMMER *pgm, const AVRPART *p, int argc, const char *argv[]); -static int cmd_backup (const PROGRAMMER *pgm, const AVRPART *p, int argc, const char *argv[]); +static int cmd_dump(const PROGRAMMER *pgm, const AVRPART *p, int argc, const char *argv[]); +static int cmd_disasm(const PROGRAMMER *pgm, const AVRPART *p, int argc, const char *argv[]); +static int cmd_write(const PROGRAMMER *pgm, const AVRPART *p, int argc, const char *argv[]); +static int cmd_save(const PROGRAMMER *pgm, const AVRPART *p, int argc, const char *argv[]); +static int cmd_backup(const PROGRAMMER *pgm, const AVRPART *p, int argc, const char *argv[]); static int cmd_restore(const PROGRAMMER *pgm, const AVRPART *p, int argc, const char *argv[]); -static int cmd_verify (const PROGRAMMER *pgm, const AVRPART *p, int argc, const char *argv[]); -static int cmd_flush (const PROGRAMMER *pgm, const AVRPART *p, int argc, const char *argv[]); -static int cmd_abort (const PROGRAMMER *pgm, const AVRPART *p, int argc, const char *argv[]); -static int cmd_erase (const PROGRAMMER *pgm, const AVRPART *p, int argc, const char *argv[]); +static int cmd_verify(const PROGRAMMER *pgm, const AVRPART *p, int argc, const char *argv[]); +static int cmd_flush(const PROGRAMMER *pgm, const AVRPART *p, int argc, const char *argv[]); +static int cmd_abort(const PROGRAMMER *pgm, const AVRPART *p, int argc, const char *argv[]); +static int cmd_erase(const PROGRAMMER *pgm, const AVRPART *p, int argc, const char *argv[]); static int cmd_pgerase(const PROGRAMMER *pgm, const AVRPART *p, int argc, const char *argv[]); -static int cmd_config (const PROGRAMMER *pgm, const AVRPART *p, int argc, const char *argv[]); +static int cmd_config(const PROGRAMMER *pgm, const AVRPART *p, int argc, const char *argv[]); static int cmd_factory(const PROGRAMMER *pgm, const AVRPART *p, int argc, const char *argv[]); static int cmd_regfile(const PROGRAMMER *pgm, const AVRPART *p, int argc, const char *argv[]); static int cmd_include(const PROGRAMMER *pgm, const AVRPART *p, int argc, const char *argv[]); -static int cmd_sig (const PROGRAMMER *pgm, const AVRPART *p, int argc, const char *argv[]); -static int cmd_part (const PROGRAMMER *pgm, const AVRPART *p, int argc, const char *argv[]); -static int cmd_help (const PROGRAMMER *pgm, const AVRPART *p, int argc, const char *argv[]); -static int cmd_quit (const PROGRAMMER *pgm, const AVRPART *p, int argc, const char *argv[]); -static int cmd_send (const PROGRAMMER *pgm, const AVRPART *p, int argc, const char *argv[]); -static int cmd_parms (const PROGRAMMER *pgm, const AVRPART *p, int argc, const char *argv[]); -static int cmd_vtarg (const PROGRAMMER *pgm, const AVRPART *p, int argc, const char *argv[]); -static int cmd_varef (const PROGRAMMER *pgm, const AVRPART *p, int argc, const char *argv[]); -static int cmd_fosc (const PROGRAMMER *pgm, const AVRPART *p, int argc, const char *argv[]); -static int cmd_sck (const PROGRAMMER *pgm, const AVRPART *p, int argc, const char *argv[]); -static int cmd_spi (const PROGRAMMER *pgm, const AVRPART *p, int argc, const char *argv[]); -static int cmd_pgm (const PROGRAMMER *pgm, const AVRPART *p, int argc, const char *argv[]); +static int cmd_sig(const PROGRAMMER *pgm, const AVRPART *p, int argc, const char *argv[]); +static int cmd_part(const PROGRAMMER *pgm, const AVRPART *p, int argc, const char *argv[]); +static int cmd_help(const PROGRAMMER *pgm, const AVRPART *p, int argc, const char *argv[]); +static int cmd_quit(const PROGRAMMER *pgm, const AVRPART *p, int argc, const char *argv[]); +static int cmd_send(const PROGRAMMER *pgm, const AVRPART *p, int argc, const char *argv[]); +static int cmd_parms(const PROGRAMMER *pgm, const AVRPART *p, int argc, const char *argv[]); +static int cmd_vtarg(const PROGRAMMER *pgm, const AVRPART *p, int argc, const char *argv[]); +static int cmd_varef(const PROGRAMMER *pgm, const AVRPART *p, int argc, const char *argv[]); +static int cmd_fosc(const PROGRAMMER *pgm, const AVRPART *p, int argc, const char *argv[]); +static int cmd_sck(const PROGRAMMER *pgm, const AVRPART *p, int argc, const char *argv[]); +static int cmd_spi(const PROGRAMMER *pgm, const AVRPART *p, int argc, const char *argv[]); +static int cmd_pgm(const PROGRAMMER *pgm, const AVRPART *p, int argc, const char *argv[]); static int cmd_verbose(const PROGRAMMER *pgm, const AVRPART *p, int argc, const char *argv[]); -static int cmd_quell (const PROGRAMMER *pgm, const AVRPART *p, int argc, const char *argv[]); +static int cmd_quell(const PROGRAMMER *pgm, const AVRPART *p, int argc, const char *argv[]); #define _fo(x) offsetof(PROGRAMMER, x) // List of commands; don't add a command starting with e: main.c relies on e expanding to erase struct command cmd[] = { - { "dump", cmd_dump, _fo(read_byte_cached), "display a memory section as hex dump" }, - { "read", cmd_dump, _fo(read_byte_cached), "alias for dump" }, - { "disasm", cmd_disasm, _fo(read_byte_cached), "disassemble a memory section" }, - { "write", cmd_write, _fo(write_byte_cached), "write data to memory; flash and EEPROM are cached" }, - { "save", cmd_save, _fo(write_byte_cached), "save memory segments to file" }, - { "backup", cmd_backup, _fo(write_byte_cached), "backup memories to file" }, - { "restore", cmd_restore, _fo(write_byte_cached), "restore memories from file" }, - { "verify", cmd_verify, _fo(write_byte_cached), "compare memories with file" }, - { "flush", cmd_flush, _fo(flush_cache), "synchronise flash and EEPROM cache with the device" }, - { "abort", cmd_abort, _fo(reset_cache), "abort flash and EEPROM writes, ie, reset the r/w cache" }, - { "erase", cmd_erase, _fo(chip_erase_cached), "perform a chip or memory erase" }, - { "pgerase", cmd_pgerase, _fo(page_erase), "erase one page of flash or EEPROM memory" }, - { "config", cmd_config, _fo(open), "change or show configuration properties of the part" }, - { "factory", cmd_factory, _fo(open), "reset part to factory state" }, - { "regfile", cmd_regfile, _fo(open), "I/O register addresses and contents" }, - { "include", cmd_include, _fo(open), "include contents of named file as if it was typed" }, - { "sig", cmd_sig, _fo(open), "display device signature bytes" }, - { "part", cmd_part, _fo(open), "display the current part information" }, - { "send", cmd_send, _fo(cmd), "send a raw command to the programmer" }, - { "parms", cmd_parms, _fo(print_parms), "display useful parameters" }, - { "vtarg", cmd_vtarg, _fo(set_vtarget), "set or get the target voltage" }, - { "varef", cmd_varef, _fo(set_varef), "set or get the analog reference voltage" }, - { "fosc", cmd_fosc, _fo(set_fosc), "set or get the oscillator frequency" }, - { "sck", cmd_sck, _fo(set_sck_period), "set or get the SCK period or frequency" }, - { "spi", cmd_spi, _fo(setpin), "enter direct SPI mode" }, - { "pgm", cmd_pgm, _fo(setpin), "return to programming mode" }, - { "verbose", cmd_verbose, _fo(open), "display or set -v verbosity level" }, - { "quell", cmd_quell, _fo(open), "display or set -q quell level for progress bars" }, - { "help", cmd_help, _fo(open), "show help message" }, - { "?", cmd_help, _fo(open), "same as help" }, - { "quit", cmd_quit, _fo(open), "synchronise flash/EEPROM cache with device and quit" }, - { "q", cmd_quit, _fo(open), "abbreviation for quit" }, + {"dump", cmd_dump, _fo(read_byte_cached), "display a memory section as hex dump"}, + {"read", cmd_dump, _fo(read_byte_cached), "alias for dump"}, + {"disasm", cmd_disasm, _fo(read_byte_cached), "disassemble a memory section"}, + {"write", cmd_write, _fo(write_byte_cached), "write data to memory; flash and EEPROM are cached"}, + {"save", cmd_save, _fo(write_byte_cached), "save memory segments to file"}, + {"backup", cmd_backup, _fo(write_byte_cached), "backup memories to file"}, + {"restore", cmd_restore, _fo(write_byte_cached), "restore memories from file"}, + {"verify", cmd_verify, _fo(write_byte_cached), "compare memories with file"}, + {"flush", cmd_flush, _fo(flush_cache), "synchronise flash and EEPROM cache with the device"}, + {"abort", cmd_abort, _fo(reset_cache), "abort flash and EEPROM writes, ie, reset the r/w cache"}, + {"erase", cmd_erase, _fo(chip_erase_cached), "perform a chip or memory erase"}, + {"pgerase", cmd_pgerase, _fo(page_erase), "erase one page of flash or EEPROM memory"}, + {"config", cmd_config, _fo(open), "change or show configuration properties of the part"}, + {"factory", cmd_factory, _fo(open), "reset part to factory state"}, + {"regfile", cmd_regfile, _fo(open), "I/O register addresses and contents"}, + {"include", cmd_include, _fo(open), "include contents of named file as if it was typed"}, + {"sig", cmd_sig, _fo(open), "display device signature bytes"}, + {"part", cmd_part, _fo(open), "display the current part information"}, + {"send", cmd_send, _fo(cmd), "send a raw command to the programmer"}, + {"parms", cmd_parms, _fo(print_parms), "display useful parameters"}, + {"vtarg", cmd_vtarg, _fo(set_vtarget), "set or get the target voltage"}, + {"varef", cmd_varef, _fo(set_varef), "set or get the analog reference voltage"}, + {"fosc", cmd_fosc, _fo(set_fosc), "set or get the oscillator frequency"}, + {"sck", cmd_sck, _fo(set_sck_period), "set or get the SCK period or frequency"}, + {"spi", cmd_spi, _fo(setpin), "enter direct SPI mode"}, + {"pgm", cmd_pgm, _fo(setpin), "return to programming mode"}, + {"verbose", cmd_verbose, _fo(open), "display or set -v verbosity level"}, + {"quell", cmd_quell, _fo(open), "display or set -q quell level for progress bars"}, + {"help", cmd_help, _fo(open), "show help message"}, + {"?", cmd_help, _fo(open), "same as help"}, + {"quit", cmd_quit, _fo(open), "synchronise flash/EEPROM cache with device and quit"}, + {"q", cmd_quit, _fo(open), "abbreviation for quit"}, }; #define NCMDS ((int)(sizeof(cmd)/sizeof(struct command))) - #define spi_mode (cx->term_spi_mode) static int hexdump_line(char *buffer, unsigned char *p, int n, int pad) { @@ -141,29 +138,28 @@ static int hexdump_line(char *buffer, unsigned char *p, int n, int pad) { int i = 0; int j = 0; - for (i=0; i> 4]; b[j++] = hexdata[(p[i] & 0x0f)]; - if (i < 15) + if(i < 15) b[j++] = ' '; } - for (i=j; i (int) sizeof b? (int) sizeof b: n; memcpy(b, p, n); - for (int i = 0; i < n; i++) - buffer[i] = isascii(b[i]) && isspace(b[i])? ' ': - isascii(b[i]) && isgraph(b[i])? b[i]: '.'; + for(int i = 0; i < n; i++) + buffer[i] = isascii(b[i]) && isspace(b[i])? ' ': isascii(b[i]) && isgraph(b[i])? b[i]: '.'; - for (i = n; i < pad; i++) + for(i = n; i < pad; i++) buffer[i] = ' '; buffer[i] = 0; @@ -184,26 +179,27 @@ static int chardump_line(char *buffer, unsigned char *p, int n, int pad) { return 0; } - static int hexdump_buf(const FILE *f, const AVRMEM *m, int startaddr, const unsigned char *buf, int len) { char dst1[80]; char dst2[80]; int addr = startaddr; unsigned char *p = (unsigned char *) buf; - while (len) { + + while(len) { int n = 16; - if (n > len) + + if(n > len) n = len; if(addr + n > m->size) n = m->size - addr; hexdump_line(dst1, p, n, 48); chardump_line(dst2, p, n, 16); - term_out("%0*x %s |%s|\n", m->size > 0x10000 ? 5: 4, addr, dst1, dst2); + term_out("%0*x %s |%s|\n", m->size > 0x10000? 5: 4, addr, dst1, dst2); len -= n; addr += n; - if (addr >= m->size) + if(addr >= m->size) addr = 0; p += n; } @@ -213,17 +209,28 @@ static int hexdump_buf(const FILE *f, const AVRMEM *m, int startaddr, const unsi static int disasm_ison(char c) { switch(c) { - case 'g': return !!cx->dis_opts.gcc_source; - case 'a': return !!cx->dis_opts.addresses; - case 'o': return !!cx->dis_opts.opcode_bytes; - case 'c': return !!cx->dis_opts.comments; - case 'f': return !!cx->dis_opts.sreg_flags; - case 'q': return !!cx->dis_opts.cycles; - case 'n': return !!cx->dis_opts.op_names; - case 'e': return !!cx->dis_opts.op_explanations; - case 's': return !!cx->dis_opts.avrgcc_style; - case 'l': return !!cx->dis_opts.labels; - case 'd': return cx->dis_opts.avrlevel == (PART_ALL | OP_AVR_ILL); + case 'g': + return !!cx->dis_opts.gcc_source; + case 'a': + return !!cx->dis_opts.addresses; + case 'o': + return !!cx->dis_opts.opcode_bytes; + case 'c': + return !!cx->dis_opts.comments; + case 'f': + return !!cx->dis_opts.sreg_flags; + case 'q': + return !!cx->dis_opts.cycles; + case 'n': + return !!cx->dis_opts.op_names; + case 'e': + return !!cx->dis_opts.op_explanations; + case 's': + return !!cx->dis_opts.avrgcc_style; + case 'l': + return !!cx->dis_opts.labels; + case 'd': + return cx->dis_opts.avrlevel == (PART_ALL | OP_AVR_ILL); } return 0; } @@ -245,8 +252,9 @@ static int disasm_ison(char c) { static unsigned char *readbuf(const PROGRAMMER *pgm, const AVRPART *p, int argc, const char *argv[], const AVRMEM **memp, int *baddr, int *blen, int *prequel, int *sequel) { - const int Nmems = sizeof cx->term_rmem/sizeof*cx->term_rmem; + const int Nmems = sizeof cx->term_rmem/sizeof *cx->term_rmem; int mi = cx->term_mi; + if(mi < 0 || mi >= Nmems) mi = 0; @@ -257,17 +265,17 @@ static unsigned char *readbuf(const PROGRAMMER *pgm, const AVRPART *p, int argc, if((argc < 2 && cx->term_rmem[0].mem == NULL) || argc > 4 || (argc > 1 && str_eq(argv[1], "-?"))) { const char *hcmd = is_disasm? "disasm []": cmd; - msg_error( - "Syntax: %s # Entire region\n" + msg_error("Syntax: %s # Entire region\n" " %s # Start at \n" " %s # Continue with memory where left off\n" " %s # Continue with most recently shown \n" - "Function: %s\n", - hcmd, hcmd, hcmd, hcmd, - is_disasm? "disassemble memory section": "display memory section as hex dump" - ); + "Function: %s\n", hcmd, hcmd, hcmd, hcmd, + is_disasm? "disassemble memory section": "display memory section as hex dump"); if(is_disasm) { - struct { char ochr[2]; const char *info[2]; } opts[] = { + struct { + char ochr[2]; + const char *info[2]; + } opts[] = { {{'g', 'G'}, {"generate avr-gcc source: sets -sOFQ", "do not create gcc source"}}, {{'a', 'A'}, {"show addresses", "do not show addresses"}}, {{'o', 'O'}, {"show opcode bytes", "do not show opcode bytes"}}, @@ -282,14 +290,14 @@ static unsigned char *readbuf(const PROGRAMMER *pgm, const AVRPART *p, int argc, }; msg_error("Options:\n"); - for(size_t i = 0; i < sizeof opts/sizeof*opts; i++) { + for(size_t i = 0; i < sizeof opts/sizeof *opts; i++) { int on = disasm_ison(opts[i].ochr[0]); - msg_error(" -%c %s, -%c %s\n", opts[i].ochr[on], opts[i].info[on], opts[i].ochr[!on], opts[i].info[!on]); + + msg_error(" -%c %s, -%c %s\n", opts[i].ochr[on], + opts[i].info[on], opts[i].ochr[!on], opts[i].info[!on]); } - msg_error( - " -z zap the list of jumps and calls before disassembly\n" - " -t= drop symbols from a previous tagfile and initialise them anew\n" - ); + msg_error(" -z zap the list of jumps and calls before disassembly\n" + " -t= drop symbols from a previous tagfile and initialise them anew\n"); } msg_error("\n" "Both the and can be negative numbers; a negative starts\n" @@ -297,27 +305,25 @@ static unsigned char *readbuf(const PROGRAMMER *pgm, const AVRPART *p, int argc, "the interval at that many bytes below the memory size.\n" "\n" "The latter two versions of the command page through the memory with a page\n" - "size of the last used effective length (%d bytes default)\n", default_len - ); + "size of the last used effective length (%d bytes default)\n", default_len); return NULL; } - const char *memstr = - argc > 1? argv[1]: - cx->term_rmem[mi].mem? cx->term_rmem[mi].mem->desc: NULL; + const char *memstr = argc > 1? argv[1]: cx->term_rmem[mi].mem? cx->term_rmem[mi].mem->desc: NULL; const AVRMEM *mem = memstr && *memstr? avr_locate_mem(p, memstr): NULL; - if (mem == NULL) { + + if(mem == NULL) { pmsg_error("(%s) memory %s not defined for part %s\n", cmd, memstr? memstr: "???", p->desc); return NULL; } int maxsize = mem->size; + if(maxsize <= 0) { // Sanity check pmsg_error("(%s) cannot read memory %s of size %d\n", cmd, mem->desc, maxsize); return NULL; } - // Iterate through the cx->term_rmem structs to find relevant address and length info for(mi = 0; mi < Nmems; mi++) { if(cx->term_rmem[mi].mem == NULL) @@ -340,47 +346,48 @@ static unsigned char *readbuf(const PROGRAMMER *pgm, const AVRPART *p, int argc, // Get start address if present const char *errptr; + if(argc >= 3 && !str_eq(argv[2], "...")) { int addr = str_int(argv[2], STR_INT32, &errptr); + if(errptr) { pmsg_error("(%s) address %s: %s\n", cmd, argv[2], errptr); return NULL; } - // Turn negative addr value (counting from top and down) into an actual memory address - if (addr < 0) + if(addr < 0) addr = maxsize + addr; - if (addr < 0 || addr >= maxsize) { + if(addr < 0 || addr >= maxsize) { int digits = maxsize > 0x10000? 5: 4; + pmsg_error("(%s) %s address %s is out of range [-0x%0*x, 0x%0*x]\n", - cmd, mem->desc, argv[2], digits, maxsize, digits, maxsize-1); + cmd, mem->desc, argv[2], digits, maxsize, digits, maxsize - 1); return NULL; } cx->term_rmem[mi].addr = addr; } - // Get number of bytes to read if present - if (argc >= 3) { + if(argc >= 3) { if(str_eq(argv[argc - 1], "...")) { - if (argc == 3) + if(argc == 3) cx->term_rmem[mi].addr = 0; cx->term_rmem[mi].len = maxsize - cx->term_rmem[mi].addr; - } else if (argc == 4) { + } else if(argc == 4) { int len = str_int(argv[3], STR_INT32, &errptr); + if(errptr) { pmsg_error("(%s) length %s: %s\n", cmd, argv[3], errptr); return NULL; } - // Turn negative len (ends at number of bytes from top of memory) into an actual length - if (len < 0) + if(len < 0) len = maxsize + len + 1 - cx->term_rmem[mi].addr; - if (len == 0) + if(len == 0) goto nocontent; - if (len < 0) { + if(len < 0) { pmsg_error("(%s) invalid effective length %d\n", cmd, len); return NULL; } @@ -392,37 +399,39 @@ static unsigned char *readbuf(const PROGRAMMER *pgm, const AVRPART *p, int argc, cx->term_rmem[mi].addr = 0; // Trim len if nessary to prevent reading from the same memory address twice - if (cx->term_rmem[mi].len > maxsize) + if(cx->term_rmem[mi].len > maxsize) cx->term_rmem[mi].len = maxsize; - uint8_t *buf = mmt_malloc(cx->term_rmem[mi].len + 32); // Add margin for disasm + uint8_t *buf = mmt_malloc(cx->term_rmem[mi].len + 32); // Add margin for disasm + if(argc < 4 && verbose) - term_out(">>> %s %s 0x%x 0x%x\n", cmd, cx->term_rmem[mi].mem->desc, - cx->term_rmem[mi].addr, cx->term_rmem[mi].len); + term_out(">>> %s %s 0x%x 0x%x\n", cmd, cx->term_rmem[mi].mem->desc, cx->term_rmem[mi].addr, cx->term_rmem[mi].len); int toread = cx->term_rmem[mi].len; int whence = cx->term_rmem[mi].addr; int before = 0, after = 0, flash_offset = 0; + if(is_disasm) { // Read a few bytes before/after & don't wrap round if(whence >= 2) before = 2, whence -= 2, toread += 2; - if(whence + toread > maxsize) // Clip to end of memory + if(whence + toread > maxsize) // Clip to end of memory toread = maxsize - whence; int gap = maxsize - whence - toread; + after = gap >= 16? 16: gap < 0? 0: gap; toread += after; - if(toread-before < 2) // Cannot disassemble just one byte + if(toread - before < 2) // Cannot disassemble just one byte goto nocontent; } report_progress(0, 1, "Reading"); for(int j = 0; j < toread; j++) { - int addr = (whence + j) % maxsize; + int addr = (whence + j)%maxsize; int rc = pgm->read_byte_cached(pgm, p, mem, addr, &buf[j]); - if (rc != 0) { + + if(rc != 0) { report_progress(1, -1, NULL); - pmsg_error("(%s) error reading %s address 0x%05lx of part %s\n", cmd, mem->desc, - (long) whence + j, p->desc); + pmsg_error("(%s) error reading %s address 0x%05lx of part %s\n", cmd, mem->desc, (long) whence + j, p->desc); mmt_free(buf); return NULL; } @@ -431,36 +440,47 @@ static unsigned char *readbuf(const PROGRAMMER *pgm, const AVRPART *p, int argc, report_progress(1, 1, NULL); if(is_disasm) { // Adjust length so buffer does not split opcodes - int j = before, end = toread-after, wend = after? end: end-1; + int j = before, end = toread - after, wend = after? end: end - 1; + while(j < wend) - j += op_width(buf[j] | buf[j+1]<<8); + j += op_width(buf[j] | buf[j + 1] << 8); if(j < end) // Odd length: shorten by one byte - after += end-j; - else if(j > end && after >= j-end) // Increase length to accommodate last 32-bit opcode - after -= j-end; + after += end - j; + else if(j > end && after >= j - end) // Increase length to accommodate last 32-bit opcode + after -= j - end; else if(j > end) // Reduce length - after += j-end; + after += j - end; // Disassembly of XMEGA's boot/apptable memory needs to know absolute addr in flash flash_offset = avr_flash_offset(p, mem, whence + before); } - if(memp) *memp = mem; - if(baddr) *baddr = whence + before + flash_offset; - if(blen) *blen = toread - before - after; - if(prequel) *prequel = before; - if(sequel) *sequel = after; + if(memp) + *memp = mem; + if(baddr) + *baddr = whence + before + flash_offset; + if(blen) + *blen = toread - before - after; + if(prequel) + *prequel = before; + if(sequel) + *sequel = after; // Memorise where to start next time - cx->term_rmem[mi].addr = (whence + toread - after) % maxsize; + cx->term_rmem[mi].addr = (whence + toread - after)%maxsize; return buf; nocontent: - if(memp) *memp = mem; - if(baddr) *baddr = 0; - if(blen) *blen = 0; - if(prequel) *prequel = 0; - if(sequel) *sequel = 0; + if(memp) + *memp = mem; + if(baddr) + *baddr = 0; + if(blen) + *blen = 0; + if(prequel) + *prequel = 0; + if(sequel) + *sequel = 0; return mmt_malloc(16); } @@ -503,8 +523,9 @@ static int cmd_disasm(const PROGRAMMER *pgm, const AVRPART *p, int argc, const c cx->dis_initopts++; } - for(int ai = 0; --argc > 0; ) { // Simple option parsing + for(int ai = 0; --argc > 0;) { // Simple option parsing const char *q; + if(*(q = argv[++ai]) != '-' || !q[1] || looks_like_number(q)) argv[itemac++] = argv[ai]; else { @@ -514,7 +535,8 @@ static int cmd_disasm(const PROGRAMMER *pgm, const AVRPART *p, int argc, const c case 'h': help++; break; - case 'g': case 'G': + case 'g': + case 'G': cx->dis_opts.gcc_source = !!islower(chr); if(cx->dis_opts.gcc_source) { cx->dis_opts.opcode_bytes = 0; @@ -523,31 +545,40 @@ static int cmd_disasm(const PROGRAMMER *pgm, const AVRPART *p, int argc, const c cx->dis_opts.avrgcc_style = 1; } break; - case 'a': case 'A': + case 'a': + case 'A': cx->dis_opts.addresses = !!islower(chr); break; - case 'o': case 'O': + case 'o': + case 'O': cx->dis_opts.opcode_bytes = !!islower(chr); break; - case 'c': case 'C': + case 'c': + case 'C': cx->dis_opts.comments = !!islower(chr); break; - case 'f': case 'F': + case 'f': + case 'F': cx->dis_opts.sreg_flags = !!islower(chr); break; - case 'q': case 'Q': + case 'q': + case 'Q': cx->dis_opts.cycles = !!islower(chr); break; - case 'n': case 'N': + case 'n': + case 'N': cx->dis_opts.op_names = !!islower(chr); break; - case 'e': case 'E': + case 'e': + case 'E': cx->dis_opts.op_explanations = !!islower(chr); break; - case 's': case 'S': + case 's': + case 'S': cx->dis_opts.avrgcc_style = !!islower(chr); break; - case 'l': case 'L': + case 'l': + case 'L': cx->dis_opts.labels = !!islower(chr); break; case 'z': @@ -574,7 +605,7 @@ static int cmd_disasm(const PROGRAMMER *pgm, const AVRPART *p, int argc, const c } } } - argc = itemac; // (arg,c argv) still valid but options have been removed + argc = itemac; // (argc, argv) still valid but options have been removed if(help || invalid) { const char *help[] = { "disasm", "-?", NULL, }; @@ -592,18 +623,17 @@ static int cmd_disasm(const PROGRAMMER *pgm, const AVRPART *p, int argc, const c return -1; if(len > 1) - disasm((char *) buf+leadin, len, addr, leadin, leadout); + disasm((char *) buf + leadin, len, addr, leadin, leadout); lterm_out(""); mmt_free(buf); return 0; } - static size_t maxstrlen(int argc, const char **argv) { size_t max = 0; - for(int i=0; i max) max = strlen(argv[i]); @@ -612,13 +642,12 @@ static size_t maxstrlen(int argc, const char **argv) { typedef enum { WRITE_MODE_STANDARD = 0, - WRITE_MODE_FILL = 1, + WRITE_MODE_FILL = 1, } Write_mode; static int cmd_write(const PROGRAMMER *pgm, const AVRPART *p, int argc, const char *argv[]) { - if (argc < 3 || (argc > 1 && str_eq(argv[1], "-?"))) { - msg_error( - "Syntax: write [,] {[,]}\n" + if(argc < 3 || (argc > 1 && str_eq(argv[1], "-?"))) { + msg_error("Syntax: write [,] {[,]}\n" " write [,] {[,]} ... # Fill, see below\n" " write # Any incl file if memory has only 1 byte\n" " write # Must be file if memory has more than 1 byte\n" @@ -660,8 +689,7 @@ static int cmd_write(const PROGRAMMER *pgm, const AVRPART *p, int argc, const ch "smallest unsigned representation: For example, 255 is stored as one byte as\n" "255U would fit in one byte, though as a signed number it would not fit into a\n" "one-byte interval [-128, 127]. The number -1 is stored in one byte whilst -1U\n" - "needs eight bytes as it is the same as 0xFFFFffffFFFFffffU.\n" - ); + "needs eight bytes as it is the same as 0xFFFFffffFFFFffffU.\n"); return -1; } @@ -671,15 +699,17 @@ static int cmd_write(const PROGRAMMER *pgm, const AVRPART *p, int argc, const ch int len; // Number of bytes to write to memory const char *memstr = argv[1]; // Memory name string const AVRMEM *mem = avr_locate_mem(p, memstr); - if (mem == NULL) { + + if(mem == NULL) { pmsg_error("(write) memory %s not defined for part %s\n", memstr, p->desc); return -1; } int maxsize = mem->size; - if (argc == 3 && maxsize > 1) { + if(argc == 3 && maxsize > 1) { // Check whether argv[2] might be anything other than a file Str2data *sd = str_todata(argv[2], STR_ANY & ~STR_FILE, NULL, NULL); + if(sd && sd->type) { if(sd->type & STR_INTEGER && sd->ll >= -maxsize && sd->ll < maxsize) pmsg_error("(write) no data specified for %s address %s\n", mem->desc, argv[2]); @@ -694,6 +724,7 @@ static int cmd_write(const PROGRAMMER *pgm, const AVRPART *p, int argc, const ch const char *errptr; int addr = 0; + if(argc >= 4) { addr = str_int(argv[2], STR_INT32, &errptr); if(errptr) { @@ -701,25 +732,26 @@ static int cmd_write(const PROGRAMMER *pgm, const AVRPART *p, int argc, const ch return -1; } } - // Turn negative addr value (counting from top and down) into an actual memory address - if (addr < 0) + if(addr < 0) addr = maxsize + addr; - if (addr < 0 || addr >= maxsize) { + if(addr < 0 || addr >= maxsize) { int digits = maxsize > 0x10000? 5: 4; + pmsg_error("(write) %s address 0x%0*x is out of range [-0x%0*x, 0x%0*x]\n", - mem->desc, digits, addr, digits, maxsize, digits, maxsize-1); + mem->desc, digits, addr, digits, maxsize, digits, maxsize - 1); return -1; } - // Allocate large enough data and allocation tags space - size_t bufsz = mem->size + 8 + maxstrlen(argc-3, argv+3)+1; + size_t bufsz = mem->size + 8 + maxstrlen(argc - 3, argv + 3) + 1; + if(bufsz > INT_MAX) { pmsg_error("(write) too large memory request (%lu)\n", (unsigned long) bufsz); return -1; } unsigned char *buf = mmt_malloc(bufsz), *tags = mmt_malloc(bufsz); + // Find the first argument to write to flash and how many arguments to parse and write if(str_eq(argv[argc - 1], "...")) { write_mode = WRITE_MODE_FILL; @@ -727,16 +759,16 @@ static int cmd_write(const PROGRAMMER *pgm, const AVRPART *p, int argc, const ch len = str_int(argv[3], STR_INT32, &errptr); if(errptr) { pmsg_error("(write ...) length %s: %s\n", argv[3], errptr); - mmt_free(buf); mmt_free(tags); + mmt_free(buf); + mmt_free(tags); return -1; } - // Turn negative len value (number of bytes from top of memory) into an actual length number - if (len < 0) + if(len < 0) len = maxsize + len - addr + 1; - if (len == 0) + if(len == 0) return 0; - if (len < 0 || len > maxsize - addr) { + if(len < 0 || len > maxsize - addr) { pmsg_error("(write ...) effective %s start address 0x%0*x and effective length %d incompatible with memory size %d\n", mem->desc, maxsize > 0x10000? 5: 4, addr, len, maxsize); return -1; @@ -752,17 +784,18 @@ static int cmd_write(const PROGRAMMER *pgm, const AVRPART *p, int argc, const ch len = argc - start_offset; } - int bytes_grown = 0, filling = 0, recorded = 0, maxneeded = maxsize-addr; + int bytes_grown = 0, filling = 0, recorded = 0, maxneeded = maxsize - addr; Str2data *sd = NULL; - for (i = start_offset; i < len + start_offset; i++) { + for(i = start_offset; i < len + start_offset; i++) { // Handle the next argument - if (i < argc - start_offset + 3) { + if(i < argc - start_offset + 3) { str_freedata(sd); sd = str_todata(argv[i], STR_ANY, p, mem->desc); if(!sd->type || sd->errstr) { pmsg_error("(write) data %s: %s\n", argv[i], sd->errstr? sd->errstr: "str_todata"); - mmt_free(buf); mmt_free(tags); + mmt_free(buf); + mmt_free(tags); str_freedata(sd); return -1; } @@ -777,8 +810,10 @@ static int cmd_write(const PROGRAMMER *pgm, const AVRPART *p, int argc, const ch break; } int n = i - start_offset + bytes_grown; + if(sd->type == STR_STRING && sd->str_ptr) { size_t len = strlen(sd->str_ptr); + for(size_t j = 0; j < len; j++, n++) { buf[n] = (uint8_t) sd->str_ptr[j]; tags[n] = TAG_ALLOCATED; @@ -788,6 +823,7 @@ static int cmd_write(const PROGRAMMER *pgm, const AVRPART *p, int argc, const ch bytes_grown += (int) len; // Sic: one less than written } else if(sd->type == STR_FILE && sd->mem && sd->size > 0) { int end = bufsz - n; // Available buffer size + if(sd->size < end) end = sd->size; for(int j = 0; j < end; j++, n++) { @@ -797,13 +833,13 @@ static int cmd_write(const PROGRAMMER *pgm, const AVRPART *p, int argc, const ch } } if(end > 0) // Should always be true - bytes_grown += end-1; + bytes_grown += end - 1; } else if(sd->size > 0 && (sd->type & STR_NUMBER)) { for(int k = 0; k < sd->size; k++, n++) { buf[n] = sd->a[k]; tags[n] = TAG_ALLOCATED; } - bytes_grown += sd->size-1; + bytes_grown += sd->size - 1; } else { // Nothing written bytes_grown--; // Sic: stay stagnat as i increases, but break when filling if(write_mode == WRITE_MODE_FILL && filling) { @@ -832,30 +868,32 @@ static int cmd_write(const PROGRAMMER *pgm, const AVRPART *p, int argc, const ch pmsg_notice2("(write) writing %d byte%s starting from address 0x%04x", len + bytes_grown, str_plural(len + bytes_grown), addr); - if (write_mode == WRITE_MODE_FILL && filling) + if(write_mode == WRITE_MODE_FILL && filling) msg_notice2("; remaining space filled with %s", argv[argc - 2]); msg_notice2("\n"); report_progress(0, 1, avr_has_paged_access(pgm, p, mem)? "Caching": "Writing"); - for (i = 0; i < len + bytes_grown; i++) { + for(i = 0; i < len + bytes_grown; i++) { report_progress(i, len + bytes_grown, NULL); if(!tags[i]) continue; uint8_t b; - int rc = pgm->write_byte_cached(pgm, p, mem, addr+i, buf[i]); - if (rc == LIBAVRDUDE_SOFTFAIL) { - pmsg_warning("(write) programmer write protects %s address 0x%04x\n", mem->desc, addr+i); + int rc = pgm->write_byte_cached(pgm, p, mem, addr + i, buf[i]); + + if(rc == LIBAVRDUDE_SOFTFAIL) { + pmsg_warning("(write) programmer write protects %s address 0x%04x\n", mem->desc, addr + i); } else if(rc) { - pmsg_error("(write) error writing 0x%02x at 0x%05x (rc = %d)\n", buf[i], addr+i, (int) rc); - // if (rc == -1) + pmsg_error("(write) error writing 0x%02x at 0x%05x (rc = %d)\n", buf[i], addr + i, (int) rc); + // if(rc == -1) // imsg_error("write operation not supported on memory %s\n", mem->desc); - } else if(pgm->read_byte_cached(pgm, p, mem, addr+i, &b) < 0) { + } else if(pgm->read_byte_cached(pgm, p, mem, addr + i, &b) < 0) { pmsg_error("(write) readback from %s failed\n", mem->desc); } else { // Read back byte b is now set - int bitmask = avr_mem_bitmask(p, mem, addr+i); + int bitmask = avr_mem_bitmask(p, mem, addr + i); + if((b & bitmask) != (buf[i] & bitmask)) { - pmsg_error("(write) verification error writing 0x%02x at 0x%05x cell=0x%02x", buf[i], addr+i, b); + pmsg_error("(write) verification error writing 0x%02x at 0x%05x cell=0x%02x", buf[i], addr + i, b); if(bitmask != 0xff) msg_error(" using bit mask 0x%02x", bitmask); msg_error("\n"); @@ -871,38 +909,37 @@ static int cmd_write(const PROGRAMMER *pgm, const AVRPART *p, int argc, const ch static int cmd_save(const PROGRAMMER *pgm, const AVRPART *p, int argc, const char *argv[]) { if(argc < 3 || (argc > 1 && str_eq(argv[1], "-?"))) { - msg_error( - "Syntax: save { } [:]\n" - "Function: save memory segments to file (default format :r raw binary)\n" - ); + msg_error("Syntax: save { } [:]\n" + "Function: save memory segments to file (default format :r raw binary)\n"); return -1; } AVRMEM *mem, *omem; + if(!(omem = avr_locate_mem(p, argv[1]))) { pmsg_error("(save) memory %s not defined for part %s\n", argv[1], p->desc); return -1; } - if(argc > 3 && !(argc&1)) { + if(argc > 3 && !(argc & 1)) { pmsg_error("(save) need pairs to describe memory segments\n"); return -1; } - // Last char of filename is format if the penultimate char is a colon FILEFMT format = FMT_RBIN; - const char *fn = argv[argc-1]; + const char *fn = argv[argc - 1]; size_t len = strlen(fn); - if(len > 2 && fn[len-2] == ':') { // Assume format specified - if((format = fileio_format_with_errmsg(fn[len-1], "(save) ")) == FMT_ERROR) + + if(len > 2 && fn[len - 2] == ':') { // Assume format specified + if((format = fileio_format_with_errmsg(fn[len - 1], "(save) ")) == FMT_ERROR) return -1; len -= 2; } - char *filename = memcpy(mmt_malloc(len+1), fn, len); + char *filename = memcpy(mmt_malloc(len + 1), fn, len); mem = avr_dup_mem(omem); - int n = argc > 3? (argc-3)/2: 1; - Segment *seglist = mmt_malloc(n*sizeof*seglist); + int n = argc > 3? (argc - 3)/2: 1; + Segment *seglist = mmt_malloc(n*sizeof *seglist); int ret = -1; @@ -910,14 +947,15 @@ static int cmd_save(const PROGRAMMER *pgm, const AVRPART *p, int argc, const cha seglist[0].addr = 0; // Defaults to entire memory seglist[0].len = mem->size; if(argc > 3) { - for(int cc = 2, i = 0; i < n; i++, cc+=2) { + for(int cc = 2, i = 0; i < n; i++, cc += 2) { const char *errstr; + seglist[i].addr = str_int(argv[cc], STR_INT32, &errstr); if(errstr) { pmsg_error("(save) address %s: %s\n", argv[cc], errstr); goto done; } - seglist[i].len = str_int(argv[cc+1], STR_INT32, &errstr); + seglist[i].len = str_int(argv[cc + 1], STR_INT32, &errstr); if(errstr) { pmsg_error("(save) length %s: %s\n", argv[cc], errstr); goto done; @@ -926,30 +964,30 @@ static int cmd_save(const PROGRAMMER *pgm, const AVRPART *p, int argc, const cha } int nbytes = 0; // Total number of bytes to save - for(int i=0; iread_byte_cached(pgm, p, mem, j, mem->buf+j); + int rc = pgm->read_byte_cached(pgm, p, mem, j, mem->buf + j); + if(rc < 0) { report_progress(1, -1, NULL); pmsg_error("(save) error reading %s address 0x%0*x of part %s\n", - mem->desc, j<16? 1: j<256? 2: j<65536? 4: 5, j, p->desc); + mem->desc, j < 16? 1: j < 256? 2: j < 65536? 4: 5, j, p->desc); return -1; } report_progress(j, nbytes, NULL); @@ -959,7 +997,7 @@ static int cmd_save(const PROGRAMMER *pgm, const AVRPART *p, int argc, const cha ret = fileio_segments(FIO_WRITE, filename, format, p, mem, n, seglist); - done: +done: avr_free_mem(mem); mmt_free(seglist); mmt_free(filename); @@ -969,27 +1007,26 @@ static int cmd_save(const PROGRAMMER *pgm, const AVRPART *p, int argc, const cha static int cmd_backup(const PROGRAMMER *pgm, const AVRPART *p, int argc, const char *argv[]) { if(argc != 3 || (argc > 1 && str_eq(argv[1], "-?"))) { - msg_error( - "Syntax: backup [:]\n" + msg_error("Syntax: backup [:]\n" "Function: backup memories to file; default format :I Intel Hex + comments\n" "Notes:\n" " - Backup flushes the cache before reading memories\n" " - can be a comma separated list of known memories, all, etc or ALL\n" " - ALL also includes sub-memories, eg, boot; all doesn't; etc is same as all\n" - " - A leading - or \\ removes that memory from the list so far, eg, all,-bootrow\n" - ); + " - A leading - or \\ removes that memory from the list so far, eg, all,-bootrow\n"); return -1; } FILEFMT format = FMT_IHXC; const char *fn = argv[2]; size_t len = strlen(fn); - if(len > 2 && fn[len-2] == ':') { // :format - if((format = fileio_format_with_errmsg(fn[len-1], "(backup) ")) == FMT_ERROR) + + if(len > 2 && fn[len - 2] == ':') { // :format + if((format = fileio_format_with_errmsg(fn[len - 1], "(backup) ")) == FMT_ERROR) return -1; len -= 2; } - char *filename = memcpy(mmt_malloc(len+1), fn, len); + char *filename = memcpy(mmt_malloc(len + 1), fn, len); UPDATE upd = { .cmdline = NULL, @@ -999,8 +1036,9 @@ static int cmd_backup(const PROGRAMMER *pgm, const AVRPART *p, int argc, const c .format = format, }; - pgm->flush_cache(pgm, p); // Flush cache before any device memory access - int ret = do_op(pgm, p, &upd, UF_AUTO_ERASE|UF_NOHEADING); // -U argv[1]:r:file + pgm->flush_cache(pgm, p); // Flush cache before any device memory access + int ret = do_op(pgm, p, &upd, UF_AUTO_ERASE | UF_NOHEADING); // -U argv[1]:r:file + mmt_free(upd.filename); mmt_free(upd.memstr); @@ -1009,8 +1047,7 @@ static int cmd_backup(const PROGRAMMER *pgm, const AVRPART *p, int argc, const c static int cmd_restore(const PROGRAMMER *pgm, const AVRPART *p, int argc, const char *argv[]) { if(argc != 3 || (argc > 1 && str_eq(argv[1], "-?"))) { - msg_error( - "Syntax: restore [:]\n" + msg_error("Syntax: restore [:]\n" "Function: restore memories from file\n" "Notes:\n" " - User should erase flash before using restore involving flash\n" @@ -1020,20 +1057,20 @@ static int cmd_restore(const PROGRAMMER *pgm, const AVRPART *p, int argc, const " - ALL also includes sub-memories, eg, boot; all doesn't; etc is same as all\n" " - A leading - or \\ removes that memory from the list so far, eg, all,-bootrow\n" " - Skips read-only memories in a list and, for bootloaders, also fuses and lock\n" - " - Writing to single read-only memories only fails if the contents differs\n" - ); + " - Writing to single read-only memories only fails if the contents differs\n"); return -1; } FILEFMT format = FMT_AUTO; const char *fn = argv[2]; size_t len = strlen(fn); - if(len > 2 && fn[len-2] == ':') { // :format - if((format = fileio_format_with_errmsg(fn[len-1], "(restore) ")) == FMT_ERROR) + + if(len > 2 && fn[len - 2] == ':') { // :format + if((format = fileio_format_with_errmsg(fn[len - 1], "(restore) ")) == FMT_ERROR) return -1; len -= 2; } - char *filename = memcpy(mmt_malloc(len+1), fn, len); + char *filename = memcpy(mmt_malloc(len + 1), fn, len); UPDATE upd = { .cmdline = NULL, @@ -1043,38 +1080,38 @@ static int cmd_restore(const PROGRAMMER *pgm, const AVRPART *p, int argc, const .format = format, }; - pgm->flush_cache(pgm, p); // Flush cache before any device memory access - int ret = do_op(pgm, p, &upd, UF_AUTO_ERASE|UF_VERIFY|UF_NOHEADING); // -U argv[1]:w:file (no -V) + pgm->flush_cache(pgm, p); // Flush cache before any device memory access + int ret = do_op(pgm, p, &upd, UF_AUTO_ERASE | UF_VERIFY | UF_NOHEADING); // -U argv[1]:w:file (no -V) + mmt_free(upd.filename); mmt_free(upd.memstr); - pgm->reset_cache(pgm, p); // Reset cache after writing to memories + pgm->reset_cache(pgm, p); // Reset cache after writing to memories return ret <= 0? ret: 0; } static int cmd_verify(const PROGRAMMER *pgm, const AVRPART *p, int argc, const char *argv[]) { if(argc != 3 || (argc > 1 && str_eq(argv[1], "-?"))) { - msg_error( - "Syntax: verify [:]\n" + msg_error("Syntax: verify [:]\n" "Function: compare memories with file\n" "Notes:\n" " - Verify flushes the cache before verifying memories\n" " - can be a comma separated list of known memories, all, etc or ALL\n" " - ALL also includes sub-memories, eg, boot; all doesn't; etc is same as all\n" - " - A leading - or \\ removes that memory from the list so far, eg, all,-bootrow\n" - ); + " - A leading - or \\ removes that memory from the list so far, eg, all,-bootrow\n"); return -1; } FILEFMT format = FMT_AUTO; const char *fn = argv[2]; size_t len = strlen(fn); - if(len > 2 && fn[len-2] == ':') { // :format - if((format = fileio_format_with_errmsg(fn[len-1], "(verify) ")) == FMT_ERROR) + + if(len > 2 && fn[len - 2] == ':') { // :format + if((format = fileio_format_with_errmsg(fn[len - 1], "(verify) ")) == FMT_ERROR) return -1; len -= 2; } - char *filename = memcpy(mmt_malloc(len+1), fn, len); + char *filename = memcpy(mmt_malloc(len + 1), fn, len); UPDATE upd = { .cmdline = NULL, @@ -1084,34 +1121,27 @@ static int cmd_verify(const PROGRAMMER *pgm, const AVRPART *p, int argc, const c .format = format, }; - pgm->flush_cache(pgm, p); // Flush cache before any device memory access - int ret = do_op(pgm, p, &upd, UF_AUTO_ERASE|UF_NOHEADING); // -V -U argv[1]:v:file + pgm->flush_cache(pgm, p); // Flush cache before any device memory access + int ret = do_op(pgm, p, &upd, UF_AUTO_ERASE | UF_NOHEADING); // -V -U argv[1]:v:file + mmt_free(upd.filename); mmt_free(upd.memstr); return ret <= 0? ret: 0; } - static int cmd_flush(const PROGRAMMER *pgm, const AVRPART *p, int argc, const char *argv[]) { if(argc > 1) { - msg_error( - "Syntax: flush\n" - "Function: synchronise flash and EEPROM cache with the device\n" - ); + msg_error("Syntax: flush\n" "Function: synchronise flash and EEPROM cache with the device\n"); return -1; } return pgm->flush_cache(pgm, p) < 0? -1: 0; } - static int cmd_abort(const PROGRAMMER *pgm, const AVRPART *p, int argc, const char *argv[]) { if(argc > 1) { - msg_error( - "Syntax: abort\n" - "Function: abort flash and EEPROM writes, ie, reset the r/w cache\n" - ); + msg_error("Syntax: abort\n" "Function: abort flash and EEPROM writes, ie, reset the r/w cache\n"); return -1; } @@ -1119,7 +1149,6 @@ static int cmd_abort(const PROGRAMMER *pgm, const AVRPART *p, int argc, const ch return 0; } - static int cmd_send(const PROGRAMMER *pgm, const AVRPART *p, int argc, const char *argv[]) { unsigned char cmd[4], res[4]; const char *errptr; @@ -1127,26 +1156,22 @@ static int cmd_send(const PROGRAMMER *pgm, const AVRPART *p, int argc, const cha if(argc > 5 || (argc < 5 && !spi_mode) || (argc > 1 && str_eq(argv[1], "-?"))) { msg_error(spi_mode? - "Syntax: send [ [ []]]\n": - "Syntax: send \n" - ); - msg_error( - "Function: send a raw command to the programmer\n" - ); + "Syntax: send [ [ []]]\n": "Syntax: send \n"); + msg_error("Function: send a raw command to the programmer\n"); return -1; } - if (spi_mode && (pgm->spi == NULL)) { + if(spi_mode && (pgm->spi == NULL)) { pmsg_error("(send) the %s programmer does not support direct SPI transfers\n", pgm->type); return -1; } - /* number of bytes to write at the specified address */ + // Number of bytes to write at the specified address len = argc - 1; - /* load command bytes */ - for (int i=1; ispi(pgm, cmd, res, argc-1): pgm->cmd(pgm, cmd, res); + rc = spi_mode? pgm->spi(pgm, cmd, res, argc - 1): pgm->cmd(pgm, cmd, res); if(rc < 0) led_set(pgm, LED_ERR); @@ -1164,7 +1189,7 @@ static int cmd_send(const PROGRAMMER *pgm, const AVRPART *p, int argc, const cha if(rc >= 0) { term_out("results:"); - for(int i=0; i 4 || argc == 3 || (argc > 1 && str_eq(argv[1], "-?"))) { - msg_error( - "Syntax: erase # Fill section with 0xff values\n" + if(argc > 4 || argc == 3 || (argc > 1 && str_eq(argv[1], "-?"))) { + msg_error("Syntax: erase # Fill section with 0xff values\n" " erase # Fill with 0xff values\n" " erase # Chip erase (no chache, immediate effect)\n" - "Function: perform a chip or memory erase; flash or EEPROM erase is cached\n" - ); + "Function: perform a chip or memory erase; flash or EEPROM erase is cached\n"); return -1; } - if (argc > 1) { + if(argc > 1) { const char *memstr = argv[1]; const AVRMEM *mem = avr_locate_mem(p, memstr); - if (mem == NULL) { + + if(mem == NULL) { pmsg_error("(erase) memory %s not defined for part %s\n", argv[1], p->desc); return -1; } - const char *args[] = {"write", memstr, "", "", "0xff", "...", NULL}; + const char *args[] = { "write", memstr, "", "", "0xff", "...", NULL }; // Erase - if (argc == 2 && pgm->readonly) { // Process intervals that are writable + if(argc == 2 && pgm->readonly) { // Process intervals that are writable int addr, start = 0, end, memend = mem->size - 1; + do { for(addr = start; addr <= memend; addr++) if(!pgm->readonly(pgm, p, mem, addr)) { @@ -1205,22 +1229,23 @@ static int cmd_erase(const PROGRAMMER *pgm, const AVRPART *p, int argc, const ch if(addr > memend) break; end = memend; - for(addr = start+1; addr <= memend; addr++) + for(addr = start + 1; addr <= memend; addr++) if(pgm->readonly(pgm, p, mem, addr)) { - end = addr-1; + end = addr - 1; break; } if(start <= end) { char nums[2][128]; + sprintf(nums[0], "0x%04x", start); - sprintf(nums[1], "0x%04x", end-start+1); + sprintf(nums[1], "0x%04x", end - start + 1); args[2] = nums[0]; args[3] = nums[1]; if(cmd_write(pgm, p, 6, args) < 0) return -1; } - start = end+1; - } while (start <= memend); + start = end + 1; + } while(start <= memend); return 0; } @@ -1230,7 +1255,6 @@ static int cmd_erase(const PROGRAMMER *pgm, const AVRPART *p, int argc, const ch args[3] = "-1"; return cmd_write(pgm, p, 6, args); } - // Erase args[2] = argv[2]; args[3] = argv[3]; @@ -1238,7 +1262,7 @@ static int cmd_erase(const PROGRAMMER *pgm, const AVRPART *p, int argc, const ch } term_out("%s chip erase; discarded pending writes to flash%s\n", - (pgm->prog_modes & PM_SPM)? "asking bootloader to perform": "performing", + is_spm(pgm)? "asking bootloader to perform": "performing", avr_locate_bootrow(p)? ", EEPROM and bootrow": avr_locate_eeprom(p)? " and EEPROM": ""); // Erase chip and clear cache @@ -1247,13 +1271,15 @@ static int cmd_erase(const PROGRAMMER *pgm, const AVRPART *p, int argc, const ch if(rc == LIBAVRDUDE_SOFTFAIL) { pmsg_info("(erase) emulating chip erase by writing 0xff to flash "); const AVRMEM *flm = avr_locate_flash(p); + if(!flm) { msg_error("but flash not defined for part %s?\n", p->desc); return -1; } - int addr, beg = 0, end = flm->size-1; + int addr, beg = 0, end = flm->size - 1; + if(pgm->readonly) { - for(addr=beg; addr < flm->size; addr++) + for(addr = beg; addr < flm->size; addr++) if(!pgm->readonly(pgm, p, flm, addr)) { beg = addr; break; @@ -1262,7 +1288,7 @@ static int cmd_erase(const PROGRAMMER *pgm, const AVRPART *p, int argc, const ch msg_info("but all flash is write protected\n"); return 0; } - for(addr=end; addr >= 0; addr--) + for(addr = end; addr >= 0; addr--) if(!pgm->readonly(pgm, p, flm, addr)) { end = addr; break; @@ -1270,7 +1296,7 @@ static int cmd_erase(const PROGRAMMER *pgm, const AVRPART *p, int argc, const ch } msg_info("[0x%04x, 0x%04x]; undo with abort\n", beg, end); - for(int addr=beg; addr <= end; addr++) + for(int addr = beg; addr <= end; addr++) if(!pgm->readonly || !pgm->readonly(pgm, p, flm, addr)) if(pgm->write_byte_cached(pgm, p, flm, addr, 0xff) == -1) return -1; @@ -1285,18 +1311,15 @@ static int cmd_erase(const PROGRAMMER *pgm, const AVRPART *p, int argc, const ch return 0; } - static int cmd_pgerase(const PROGRAMMER *pgm, const AVRPART *p, int argc, const char *argv[]) { if(argc != 3 || (argc > 1 && str_eq(argv[1], "-?"))) { - msg_error( - "Syntax: pgerase \n" - "Function: erase one page of flash or EEPROM memory\n" - ); + msg_error("Syntax: pgerase \n" "Function: erase one page of flash or EEPROM memory\n"); return -1; } const char *memstr = argv[1]; const AVRMEM *mem = avr_locate_mem(p, memstr); + if(!mem) { pmsg_error("(pgerase) memory %s not defined for part %s\n", memstr, p->desc); return -1; @@ -1310,13 +1333,14 @@ static int cmd_pgerase(const PROGRAMMER *pgm, const AVRPART *p, int argc, const const char *errptr; int addr = str_int(argv[2], STR_INT32, &errptr); + if(errptr) { pmsg_error("(pgerase) address %s: %s\n", argv[2], errptr); return -1; } - if (addr < 0 || addr >= maxsize) { - pmsg_error("(pgerase) %s address 0x%05x is out of range [0, 0x%05x]\n", mem->desc, addr, maxsize-1); + if(addr < 0 || addr >= maxsize) { + pmsg_error("(pgerase) %s address 0x%05x is out of range [0, 0x%05x]\n", mem->desc, addr, maxsize - 1); return -1; } @@ -1328,7 +1352,6 @@ static int cmd_pgerase(const PROGRAMMER *pgm, const AVRPART *p, int argc, const return 0; } - // Config command static const int MAX_PAD = 10; // Align value labels if their length difference is less than this @@ -1347,7 +1370,7 @@ typedef struct { // Fuses and lock bits } Part_FL; typedef struct { - const Configitem *t; // Configuration bitfield table + const Configitem *t; // Configuration bitfield table const char *memstr; // Memory name but could also be "lockbits" const char *alt; // Set when memstr is an alias int match; // Matched by user request @@ -1365,25 +1388,26 @@ static int getfusel(const PROGRAMMER *pgm, const AVRPART *p, Part_FL *fl, const islock = str_starts(cci->memstr, "lock"); if((islock && cci->t->memoffset != 0) || - (!islock && (cci->t->memoffset < 0 || cci->t->memoffset >= (int) (sizeof fl->fuses/sizeof*fl->fuses)))) { + (!islock && (cci->t->memoffset < 0 || cci->t->memoffset >= (int) (sizeof fl->fuses/sizeof *fl->fuses)))) { err = cache_string(str_ccprintf("%s's %s has invalid memoffset %d", p->desc, cci->memstr, cci->t->memoffset)); goto back; } - if(islock && fl->lread) { // Cached lock OK + if(islock && fl->lread) { // Cached lock OK fl->current = fl->lock; fl->islock = 1; goto back; } - if(!islock && fl->fread[cci->t->memoffset]) { // Cached fuse OK + if(!islock && fl->fread[cci->t->memoffset]) { // Cached fuse OK fl->current = fl->fuses[cci->t->memoffset]; fl->islock = 0; goto back; } const AVRMEM *mem = avr_locate_mem(p, cci->memstr); + if(!mem) { err = cache_string(str_ccprintf("memory %s not defined for part %s", cci->memstr, p->desc)); goto back; @@ -1394,9 +1418,9 @@ static int getfusel(const PROGRAMMER *pgm, const AVRPART *p, Part_FL *fl, const goto back; } - Intbytes m = {.i = 0}; - for(int i=0; isize; i++) - if(led_read_byte(pgm, p, mem, i, m.b+i) < 0) { + Intbytes m = {.i = 0 }; + for(int i = 0; i < mem->size; i++) + if(led_read_byte(pgm, p, mem, i, m.b + i) < 0) { err = cache_string(str_ccprintf("cannot read %s's %s memory", p->desc, mem->desc)); goto back; } @@ -1407,7 +1431,8 @@ static int getfusel(const PROGRAMMER *pgm, const AVRPART *p, Part_FL *fl, const } else { fl->fread[cci->t->memoffset] = 1; int result = 0; - for(int i=mem->size-1; i>=0; i--) + + for(int i = mem->size - 1; i >= 0; i--) result <<= 8, result |= m.b[i]; fl->fuses[cci->t->memoffset] = result; } @@ -1426,7 +1451,7 @@ static int setmatches(const char *str, int n, Cnfg *cc) { if(!*str) return 0; - for(int i=0; iname, str)) { - for(int j=0; jcurrent; @@ -1503,33 +1527,34 @@ static const char *valuecomment(const Configitem *cti, const Configvalue *vp, in if(!vp && cti->vlist) // No symbolic value despite symbol list? strcpy(buf, "reserved"); // Enter reserved instead of the number - else if (m > 65535) // 4-byte lock + else if(m > 65535) // 4-byte lock sprintf(buf, "0x%08x", value); - else if (m > 255) // 2-byte fuse + else if(m > 255) // 2-byte fuse sprintf(buf, "0x%04x", value); else sprintf(buf, "%*d", o.vmax >= 100? 3: o.vmax >= 10? 2: 1, value); // Show as binary with leading bitmask zeros if 2 or more bits in bitmask - if(u < 256 && (m & (m-1)) && (o.allscript || o.verb > 0)) + if(u < 256 && (m & (m - 1)) && (o.allscript || o.verb > 0)) if(cti->mask != 0xff && (unsigned) cti->mask != 0xffffffff) - sprintf(buf+strlen(buf), " = 0b%s", str_utoa(u | (1<<(intlog2(m)+1)), bin, 2)+1); + sprintf(buf + strlen(buf), " = 0b%s", str_utoa(u | (1 << (intlog2(m) + 1)), bin, 2) + 1); if(o.allscript || o.verb > 1) // Fuse mask visible: print shift pattern - sprintf(buf+strlen(buf), " = 0x%02x>>%d", u<>%d", u << lsh, lsh); // Print value comment and/or factory setting int prvcom = (vp || !cti->vlist) && o.verb > 1; int prfact = value >= 0 && value == cti->initval && (o.allv || o.printfactory); + if(prvcom || prfact) { - strcat(buf+strlen(buf), " ("); + strcat(buf + strlen(buf), " ("); if(prvcom) - strncat(buf+strlen(buf), !cti->vlist? "arbitrary": vp->vcomment, sizeof buf-strlen(buf)-32); + strncat(buf + strlen(buf), !cti->vlist? "arbitrary": vp->vcomment, sizeof buf - strlen(buf) - 32); if(prvcom && prfact) - strcat(buf+strlen(buf), ", "); + strcat(buf + strlen(buf), ", "); if(prfact) - strcat(buf+strlen(buf), "factory"); - strcat(buf+strlen(buf), ")"); + strcat(buf + strlen(buf), "factory"); + strcat(buf + strlen(buf), ")"); } return str_ccstrdup(buf); } @@ -1537,6 +1562,7 @@ static const char *valuecomment(const Configitem *cti, const Configvalue *vp, in // How a single property is printed static void printoneproperty(Cnfg *cc, int ii, const Configvalue *vp, int llen, const char *vstr, Cfg_opts o) { int value = vp? vp->value: cc[ii].val; + term_out("%s %s=%-*s # %s\n", vp && cc[ii].val != vp->value? "# conf": "config", cc[ii].t->name, llen, vstr, valuecomment(cc[ii].t, vp, value, o)); } @@ -1551,38 +1577,42 @@ static void printproperty(Cnfg *cc, int ii, Cfg_opts o) { // Scan value list for symbolic label and update it vp = NULL; const char *vstr = NULL; + if(vt) - for(int j=0; jmask > 255? "0x%08x": "%d", cc[ii].val); + sprintf(buf, (unsigned) cc[ii].t->mask > 255? "0x%08x": "%d", cc[ii].val); vstr = buf; } size_t lmin, lmax, llen; + lmin = lmax = strlen(vstr); if(o.verb > 0) { const char *vcom = !cc[ii].t->vlist? "arbitrary": vp? vp->vcomment: ""; + // Remove some redundancy in explanations - int cclen = col && str_ends(vcom, col+1)? (int) (col-ccom-1): (int) strlen(ccom); + int cclen = col && str_ends(vcom, col + 1)? (int) (col - ccom - 1): (int) strlen(ccom); if(o.verb > 1) term_out("# Mask 0x%02x of %s: %.*s\n", cc->t[ii].mask, cc[ii].memstr, cclen, ccom); else if(*cc[ii].t->ccomment) - term_out("# %c%.*s\n", toupper(*cc[ii].t->ccomment), cclen-1, cc[ii].t->ccomment+1); + term_out("# %c%.*s\n", toupper(*cc[ii].t->ccomment), cclen - 1, cc[ii].t->ccomment + 1); else term_out("# %s\n", cc[ii].t->name); } int done = 0; + o.vmax = cc[ii].val; if(o.allv && vt) { - for(int j=0; j o.vmax) o.vmax = vt[j].value; llen = strlen(vt[j].label); @@ -1590,11 +1620,11 @@ static void printproperty(Cnfg *cc, int ii, Cfg_opts o) { lmax = llen > lmax? llen: lmax; } } - llen = lmax <= lmin+MAX_PAD? lmax: 1; // Align label width if max and min length are similar + llen = lmax <= lmin + MAX_PAD? lmax: 1; // Align label width if max and min length are similar if(o.allv && vt) { - for(int j=0; j 0; ) { // Simple option parsing + for(int ai = 0; --argc > 0;) { // Simple option parsing const char *q; - if(*(q=argv[++ai]) != '-' || !q[1]) + + if(*(q = argv[++ai]) != '-' || !q[1]) argv[itemac++] = argv[ai]; else { while(*++q) { @@ -1666,14 +1698,13 @@ static int cmd_config(const PROGRAMMER *pgm, const AVRPART *p, int argc, const c } } } - argc = itemac; // (arg,c argv) still valid but options have been removed + argc = itemac; // (argc, argv) still valid but options have been removed if(o.allscript && argc > 1) pmsg_error("(config) -a does not allow any further arguments\n"); - if(argc > 2 || help || invalid || (argc >1 && o.allscript)) { - msg_error( - "Syntax: config [] [[=]] []\n" + if(argc > 2 || help || invalid || (argc > 1 && o.allscript)) { + msg_error("Syntax: config [] [[=]] []\n" "Function: Show or change configuration properties of the part\n" "Options:\n" " -f show value of fuse and lock bit memories as well\n" @@ -1704,13 +1735,12 @@ static int cmd_config(const PROGRAMMER *pgm, const AVRPART *p, int argc, const c "\n" "It is quite possible, as is with direct writing to the underlying fuses and\n" "lock bits, to brick a part, i.e., make it unresponsive to further programming\n" - "with the chosen programmer: here be dragons.\n" - ); + "with the chosen programmer: here be dragons.\n"); return !help || invalid? -1: 0; } int idx = -1; // Index in uP_table[] - const Configitem *ct; // Configuration bitfield table + const Configitem *ct; // Configuration bitfield table int nc; // Number of config properties, some may not be available Part_FL fusel; // Copy of fuses and lock bits const Configvalue *vt; // Pointer to symbolic labels and associated values @@ -1738,16 +1768,20 @@ static int cmd_config(const PROGRAMMER *pgm, const AVRPART *p, int argc, const c } int ret = 0; + cc = mmt_malloc(sizeof *cc*nc); fc = mmt_malloc(sizeof *fc*nc); AVRMEM *m = avr_locate_lock(p); const char *locktype = m? m->desc: "lock"; - for(int i=0; idesc); continue; @@ -1755,40 +1789,43 @@ static int cmd_config(const PROGRAMMER *pgm, const AVRPART *p, int argc, const c cc[i].ok = 1; cc[i].alt = str_eq(mem->desc, mt)? NULL: mem->desc; cc[i].initval = mem->initval; - if(!nf || !str_eq(fc[nf-1].memstr, mt)) + if(!nf || !str_eq(fc[nf - 1].memstr, mt)) fc[nf++].memstr = mt; - if(fc[nf-1].mask & ct[i].mask) { // This should not happen + if(fc[nf - 1].mask & ct[i].mask) { // This should not happen pmsg_error("(config) overlapping bit values of %s mask 0x%02x in %s's %s\n", cc[i].t->name, ct[i].mask, p->desc, cc[i].memstr); ret = -1; goto finished; } - fc[nf-1].mask |= ct[i].mask; + fc[nf - 1].mask |= ct[i].mask; } const char *item = argc < 2? "*": argv[1]; char *rhs = strchr(item, '='); + if(rhs) // Right-hand side of assignment *rhs++ = 0; // Terminate lhs int nm = setmatches(item, nc, cc); + if(nm == 0) { pmsg_warning("(config) non-matching %s; known config items are:\n", item); - for(int i=0; iname); ret = -1; goto finished; } - if(!rhs || !*rhs || o.allscript) { // Show (all possible) values + if(!rhs || !*rhs || o.allscript) { // Show (all possible) values const char *lastfuse = "not a fuse"; + for(int printed = 0, i = 0; i < nc; i++) { if(!cc[i].match || !cc[i].ok) continue; if(gatherval(pgm, p, cc, i, &fusel, fc, nf) < 0) { - for(int ii=i+1; ii 1)) term_out("\n"); - o.allv = (rhs && !*rhs) || o.allscript; // Print list of all values + o.allv = (rhs && !*rhs) || o.allscript; // Print list of all values printproperty(cc, i, o); printed = 1; } goto finished; } - // Non-empty rhs: attempt assignment if(nm > 1) { pmsg_warning("(config) ambiguous; known %s=... config items are:\n", item); - for(int i=0; iname); ret = -1; @@ -1821,6 +1857,7 @@ static int cmd_config(const PROGRAMMER *pgm, const AVRPART *p, int argc, const c } int ci; + for(ci = 0; ci < nc; ci++) if(cc[ci].match) break; @@ -1830,7 +1867,6 @@ static int cmd_config(const PROGRAMMER *pgm, const AVRPART *p, int argc, const c ret = -1; goto finished; } - // ci is fixed now: save what we have for sanity check Cnfg safecc = cc[ci]; @@ -1840,6 +1876,7 @@ static int cmd_config(const PROGRAMMER *pgm, const AVRPART *p, int argc, const c // Assignment can be an integer or symbolic value const char *errptr; int toassign = str_int(rhs, STR_UINT32, &errptr); + if(errptr) { // Cannot parse as int? Match against symbols, if possible if(!vt) { pmsg_error("(config) no symbols known: assign an appropriate number\n"); @@ -1847,6 +1884,7 @@ static int cmd_config(const PROGRAMMER *pgm, const AVRPART *p, int argc, const c goto finished; } int vj = getvalidx(rhs, nv, vt); + if(vj < 0) { if(vj == -1) pmsg_warning("(config) non-matching %s; known %s symbols are:\n", rhs, cc[ci].t->name); @@ -1855,7 +1893,8 @@ static int cmd_config(const PROGRAMMER *pgm, const AVRPART *p, int argc, const c o.vmax = 0; o.printfactory = 1; int llen, lmin = 9999, lmax = 0; - for(int j=0; j o.vmax? vt[j].value: o.vmax; } } - llen = lmax <= lmin+MAX_PAD? lmax: 1; // Align label width if max and min length are similar - for(int j=0; jname, llen, vt[j].label, - valuecomment(ct+ci, vt+j, vt[j].value, o)); + valuecomment(ct + ci, vt + j, vt[j].value, o)); ret = -1; goto finished; } toassign = vt[vj].value; } - if((toassign<>ct[ci].lsh); + toassign << ct[ci].lsh, ct[ci].mask, ct[ci].mask >> ct[ci].lsh); ret = -1; goto finished; } - // Check with safe copies of ct[ci] and cc[ci] - if(memcmp(&safecc, cc+ci, sizeof *cc)) { + if(memcmp(&safecc, cc + ci, sizeof *cc)) { pmsg_error("(config) unexpected data changes (this should never happen)\n"); ret = -1; goto finished; @@ -1890,17 +1928,18 @@ static int cmd_config(const PROGRAMMER *pgm, const AVRPART *p, int argc, const c if(vt) { int j; - for(j=0; jname, cc[ci].memstr, errstr); @@ -1909,8 +1948,10 @@ static int cmd_config(const PROGRAMMER *pgm, const AVRPART *p, int argc, const c } Intbytes towrite; - towrite.i = (fusel.current & ~ct[ci].mask) | (toassign<desc); ret = -1; @@ -1924,7 +1965,7 @@ static int cmd_config(const PROGRAMMER *pgm, const AVRPART *p, int argc, const c } if(towrite.i != fusel.current) { - for(int i=0; isize; i++) + for(int i = 0; i < mem->size; i++) if(led_write_byte(pgm, p, mem, i, towrite.b[i]) < 0) { pmsg_error("(config) cannot write to %s's %s memory\n", p->desc, mem->desc); ret = -1; @@ -1943,7 +1984,6 @@ static int cmd_config(const PROGRAMMER *pgm, const AVRPART *p, int argc, const c return ret; } - // Update the value of a fuse or lock static int fusel_factory(const PROGRAMMER *pgm, const AVRPART *p, const AVRMEM *mem) { unsigned char current[sizeof(int)], value[sizeof(int)]; @@ -1957,54 +1997,48 @@ static int fusel_factory(const PROGRAMMER *pgm, const AVRPART *p, const AVRMEM * pmsg_warning("cannot update %s owing to unusual memory size %d\n", mem->desc, mem->size); return -1; } - // Read in memory as little endian - for(int i=0; isize; i++) { + for(int i = 0; i < mem->size; i++) { value[i] = mem->initval >> (8*i); - if(led_read_byte(pgm, p, mem, i, current+i) < 0) + if(led_read_byte(pgm, p, mem, i, current + i) < 0) current[i] = ~value[i]; } // Update memory if needed - for(int i=0; isize; i++) { + for(int i = 0; i < mem->size; i++) { if(current[i] != value[i]) { if(led_write_byte(pgm, p, mem, i, value[i]) < 0) { pmsg_warning("(factory) cannot write to %s memory\n", mem->desc); return -1; } } - pmsg_notice2("(factory) %s %s 0x%02x\n", value[i] == current[i]? " unchanged": "writing to", - mem->desc, value[i]); + pmsg_notice2("(factory) %s %s 0x%02x\n", value[i] == current[i]? " unchanged": "writing to", mem->desc, value[i]); } return 0; } - // Reset part to factory state static int cmd_factory(const PROGRAMMER *pgm, const AVRPART *p, int argc, const char *argv[]) { - const char *args[] = {"erase", NULL, NULL}; + const char *args[] = { "erase", NULL, NULL }; AVRMEM *m; int ret = 0; if(argc != 2 || !str_eq(argv[1], "reset")) { - msg_error( - "Syntax: factory reset\n" - "Function: reset part to factory state\n" - ); + msg_error("Syntax: factory reset\n" "Function: reset part to factory state\n"); return -1; } - if(pgm->prog_modes & PM_SPM) { // Bootloader + if(is_spm(pgm)) { // Bootloader pmsg_warning("-c %s is for bootloaders, which cannot set fuses;\n", pgmid); imsg_warning("only erasing flash and other writable memories as far as possible\n"); - if((m = avr_locate_flash(p))) { // First erase flash + if((m = avr_locate_flash(p))) { // First erase flash args[1] = m->desc; if(cmd_erase(pgm, p, 2, args) < 0) ret = -1; } - for(LNODEID ln=lfirst(p->mem); ln; ln=lnext(ln)) { + for(LNODEID ln = lfirst(p->mem); ln; ln = lnext(ln)) { if(!avr_mem_exclude(pgm, p, (m = ldata(ln)))) if(mem_is_eeprom(m) || mem_is_user_type(m)) { args[1] = m->desc; @@ -2018,9 +2052,8 @@ static int cmd_factory(const PROGRAMMER *pgm, const AVRPART *p, int argc, const return ret; } - // Reset fuses to factory values - for(LNODEID ln=lfirst(p->mem); ln; ln=lnext(ln)) + for(LNODEID ln = lfirst(p->mem); ln; ln = lnext(ln)) if(!avr_mem_exclude(pgm, p, (m = ldata(ln)))) if(mem_is_a_fuse(m)) if(fusel_factory(pgm, p, m) < 0) @@ -2032,7 +2065,7 @@ static int cmd_factory(const PROGRAMMER *pgm, const AVRPART *p, int argc, const if(cmd_erase(pgm, p, 1, args) < 0) ret = -1; - for(LNODEID ln=lfirst(p->mem); ln; ln=lnext(ln)) { + for(LNODEID ln = lfirst(p->mem); ln; ln = lnext(ln)) { if(!avr_mem_exclude(pgm, p, (m = ldata(ln)))) if(mem_is_flash(m) || mem_is_eeprom(m) || mem_is_user_type(m)) { args[1] = m->desc; @@ -2045,15 +2078,15 @@ static int cmd_factory(const PROGRAMMER *pgm, const AVRPART *p, int argc, const ret = -1; // Reset lock to factory value - for(LNODEID ln=lfirst(p->mem); ln; ln=lnext(ln)) + for(LNODEID ln = lfirst(p->mem); ln; ln = lnext(ln)) if(!avr_mem_exclude(pgm, p, (m = ldata(ln)))) if(mem_is_lock(m)) if(fusel_factory(pgm, p, m) < 0) ret = -1; if(p->factory_fcpu) - term_out("after the next reset the part %s have F_CPU = %.3f MHz\n", fuseok? "will": "should", - p->factory_fcpu/1e6); + term_out("after the next reset the part %s have F_CPU = %.3f MHz\n", + fuseok? "will": "should", p->factory_fcpu/1e6); return ret; } @@ -2063,9 +2096,10 @@ static int cmd_regfile(const PROGRAMMER *pgm, const AVRPART *p, int argc, const int show_addr = 0, offset = 0, show_size = 0, show_mem = 0, verb = 0, help = 0, invalid = 0, itemac = 1; AVRMEM *io = avr_locate_io(p); - for(int ai = 0; --argc > 0; ) { // Simple option parsing + for(int ai = 0; --argc > 0;) { // Simple option parsing const char *q; - if(*(q=argv[++ai]) != '-' || !q[1]) + + if(*(q = argv[++ai]) != '-' || !q[1]) argv[itemac++] = argv[ai]; else { while(*++q) { @@ -2094,11 +2128,10 @@ static int cmd_regfile(const PROGRAMMER *pgm, const AVRPART *p, int argc, const } } } - argc = itemac; // (arg,c argv) still valid but options have been removed + argc = itemac; // (argc, argv) still valid but options have been removed if(argc > 2 || help || invalid) { - msg_error( - "Syntax: regfile [] [[=]] []\n" + msg_error("Syntax: regfile [] [[=]] []\n" "Function: Show or change I/O registers of the part (programmer permitting)\n" "Options:\n" " -a show register I/O address\n" @@ -2117,8 +2150,7 @@ static int cmd_regfile(const PROGRAMMER *pgm, const AVRPART *p, int argc, const "avrdude> regfile =\n" "\n" "modifies the corresponding register contents if the programmer can do that.\n" - "This is normally only possible with modern (UPDI) AVR parts.\n" - ); + "This is normally only possible with modern (UPDI) AVR parts.\n"); return !help || invalid? -1: 0; } @@ -2135,11 +2167,13 @@ static int cmd_regfile(const PROGRAMMER *pgm, const AVRPART *p, int argc, const } char *reg = mmt_strdup(argc > 1? argv[1]: ""), *rhs = strrchr(reg, '='); + if(rhs) // Right-hand side of assignment *rhs++ = 0; // Terminate lhs // Create mmt_malloc'd NULL-terminated list of register pointers const Register_file *r, **rl, **rlist; + rlist = avr_locate_registerlist(rf, nr, reg, str_is_pattern(reg)? str_matched_by: str_contains); if(rhs) { // Write to single register @@ -2157,7 +2191,7 @@ static int cmd_regfile(const PROGRAMMER *pgm, const AVRPART *p, int argc, const if(rlist[1]) { pmsg_error("(regfile) register %s not unique (", reg); for(rl = rlist; *rl; rl++) - msg_error("%s%s", rl[0]->reg, rl[1]? ", ": ")\n"); + msg_error("%s%s", rl[0]->reg, rl[1]? ", ": ")\n"); goto error; } @@ -2169,31 +2203,33 @@ static int cmd_regfile(const PROGRAMMER *pgm, const AVRPART *p, int argc, const const char *errptr; uint32_t toassign = str_int(rhs, STR_UINT32, &errptr); + if(errptr) { pmsg_error("(regfile) cannot parse assignment %s: %s\n", rhs, errptr); goto error; } for(int i = 0; i < r->size; i++) - if(led_write_byte(pgm, p, io, r->addr+i, ((unsigned char *) &toassign)[i]) < 0) { + if(led_write_byte(pgm, p, io, r->addr + i, ((unsigned char *) &toassign)[i]) < 0) { pmsg_warning("(reg_file) cannot write to %s\n", r->reg); goto error; } goto success; } - // Read I/O registers int maxsize = 0, maxlen = 0, addrlen = 2; + for(rl = rlist; (r = *rl); rl++) { int len = strlen(r->reg); + if(len > maxlen) maxlen = len; if(r->size > maxsize) maxsize = r->size; if(rl[1] == NULL) - addrlen = (uint32_t) (r->addr+offset) > 0xfffu? 4: (uint32_t) (r->addr+offset) > 0xffu? 3: 2; + addrlen = (uint32_t) (r->addr + offset) > 0xfffu? 4: (uint32_t) (r->addr + offset) > 0xffu? 3: 2; } for(rl = rlist; (r = *rl); rl++) { @@ -2202,26 +2238,28 @@ static int cmd_regfile(const PROGRAMMER *pgm, const AVRPART *p, int argc, const continue; } if(show_addr) - term_out("%s 0x%0*x: ", show_mem? "mem": "I/O", addrlen, r->addr+offset); + term_out("%s 0x%0*x: ", show_mem? "mem": "I/O", addrlen, r->addr + offset); if(show_size) term_out("(%d) ", r->size); if(do_read && io) { uint32_t value = 0; + for(int i = 0; i < r->size; i++) - if(do_read && led_read_byte(pgm, p, io, r->addr+i, (unsigned char *) &value + i) < 0) { + if(do_read && led_read_byte(pgm, p, io, r->addr + i, (unsigned char *) &value + i) < 0) { do_read = 0; pmsg_warning("(reg_file) cannot read %s\n", r->reg); } if(do_read) { if(r->mask != -1) value &= r->mask; - term_out("%*s0x%0*x ", 2*(maxsize-r->size), "", 2*r->size, value); + term_out("%*s0x%0*x ", 2*(maxsize - r->size), "", 2*r->size, value); } } term_out("%s", r->reg); int c = *r->caption; + if(verb) - term_out("%*s # %c%s", maxlen - (int) strlen(r->reg), "", c? toupper(c): ' ', c? r->caption+1: ""); + term_out("%*s # %c%s", maxlen - (int) strlen(r->reg), "", c? toupper(c): ' ', c? r->caption + 1: ""); term_out("\n"); } @@ -2239,9 +2277,10 @@ static int cmd_regfile(const PROGRAMMER *pgm, const AVRPART *p, int argc, const static int cmd_part(const PROGRAMMER *pgm, const AVRPART *p, int argc, const char *argv[]) { int help = 0, onlymem = 0, onlyvariants = 0, invalid = 0, itemac = 1; - for(int ai = 0; --argc > 0; ) { // Simple option parsing + for(int ai = 0; --argc > 0;) { // Simple option parsing const char *q; - if(*(q=argv[++ai]) != '-' || !q[1]) + + if(*(q = argv[++ai]) != '-' || !q[1]) argv[itemac++] = argv[ai]; else { while(*++q) { @@ -2264,18 +2303,14 @@ static int cmd_part(const PROGRAMMER *pgm, const AVRPART *p, int argc, const cha } } } - argc = itemac; // (arg,c argv) still valid but options have been removed + argc = itemac; // (argc, argv) still valid but options have been removed if(argc > 1 || help || invalid || (onlymem && onlyvariants)) { if(onlymem && onlyvariants) pmsg_error("(part) cannot mix -v and -m\n"); - msg_error( - "Syntax: part\n" + msg_error("Syntax: part\n" "Function: display the current part information including memory and variants\n" - "Options:\n" - " -m only display memory information\n" - " -v only display variants information\n" - ); + "Options:\n" " -m only display memory information\n" " -v only display variants information\n"); return -1; } @@ -2285,6 +2320,7 @@ static int cmd_part(const PROGRAMMER *pgm, const AVRPART *p, int argc, const cha avr_variants_display(stdout, p, ""); else { char *q = str_prog_modes(p->prog_modes); + term_out("%s with programming mode%s %s\n", p->desc, strchr(q, ',')? "s": "", q); avr_mem_display(stdout, pgm, p, ""); avr_variants_display(stdout, p, ""); @@ -2294,17 +2330,13 @@ static int cmd_part(const PROGRAMMER *pgm, const AVRPART *p, int argc, const cha return 0; } - static int cmd_sig(const PROGRAMMER *pgm, const AVRPART *p, int argc, const char *argv[]) { int i; int rc; const AVRMEM *m; if(argc > 1) { - msg_error( - "Syntax: sig\n" - "Function: display device signature bytes\n" - ); + msg_error("Syntax: sig\n" "Function: display device signature bytes\n"); return -1; } @@ -2317,7 +2349,7 @@ static int cmd_sig(const PROGRAMMER *pgm, const AVRPART *p, int argc, const char pmsg_error("(sig) signature data not defined for device %s\n", p->desc); } else { term_out("Device signature = 0x"); - for(i=0; isize; i++) + for(i = 0; i < m->size; i++) term_out("%02x", m->buf[i]); term_out("\n"); } @@ -2325,30 +2357,22 @@ static int cmd_sig(const PROGRAMMER *pgm, const AVRPART *p, int argc, const char return 0; } - static int cmd_quit(const PROGRAMMER *pgm, const AVRPART *p, int argc, const char *argv[]) { if(argc > 1) { - msg_error( - "Syntax: quit\n" - "Function: synchronise flash/EEPROM cache with device and quit\n" - ); + msg_error("Syntax: quit\n" "Function: synchronise flash/EEPROM cache with device and quit\n"); return -1; } - /* FUSE bit verify will fail if left in SPI mode */ - if (spi_mode) { + // FUSE bit verify will fail if left in SPI mode + if(spi_mode) { cmd_pgm(pgm, p, 0, NULL); } return 1; } - static int cmd_parms(const PROGRAMMER *pgm, const AVRPART *p, int argc, const char *argv[]) { if(argc > 1) { - msg_error( - "Syntax: parms\n" - "Function: display useful parameters\n" - ); + msg_error("Syntax: parms\n" "Function: display useful parameters\n"); return -1; } @@ -2357,14 +2381,13 @@ static int cmd_parms(const PROGRAMMER *pgm, const AVRPART *p, int argc, const ch return 0; } - static int cmd_vtarg(const PROGRAMMER *pgm, const AVRPART *p, int argc, const char *argv[]) { int rc; double v = 0; char *endp; - if (argc == 1 && pgm->get_vtarget){ // no parameter: query vtarg if fkt exists - if ((rc = pgm->get_vtarget(pgm, &v)) != 0) { + if(argc == 1 && pgm->get_vtarget) { // No parameter: query vtarg if fkt exists + if((rc = pgm->get_vtarget(pgm, &v)) != 0) { pmsg_error("(vtarg) unable to get V[target] (rc = %d)\n", rc); return -3; } @@ -2373,40 +2396,36 @@ static int cmd_vtarg(const PROGRAMMER *pgm, const AVRPART *p, int argc, const ch } if(argc != 2 || (argc > 1 && str_eq(argv[1], "-?"))) { - msg_error( - "Syntax: vtarg \n" - "Function: set target voltage\n" - ); + msg_error("Syntax: vtarg \n" "Function: set target voltage\n"); return -1; } v = strtod(argv[1], &endp); - if (endp == argv[1]) { + if(endp == argv[1]) { pmsg_error("(vtarg) cannot parse voltage %s\n", argv[1]); return -1; } - if ((rc = pgm->set_vtarget(pgm, v)) != 0) { + if((rc = pgm->set_vtarget(pgm, v)) != 0) { pmsg_error("(vtarg) unable to set V[target] (rc = %d)\n", rc); return -3; } return 0; } - static int cmd_fosc(const PROGRAMMER *pgm, const AVRPART *p, int argc, const char *argv[]) { int rc; double v = 0; char *endp; - if (argc == 1 && pgm->get_fosc) { // query fosc - if ((rc = pgm->get_fosc(pgm, &v)) != 0) { + if(argc == 1 && pgm->get_fosc) { // Query fosc + if((rc = pgm->get_fosc(pgm, &v)) != 0) { pmsg_error("(fosc) unable to get oscillator frequency (rc = %d)\n", rc); return -3; } - if (v >= 1e6) - term_out("fosc = %.6f MHz\n", v / 1e6); - else if (v >= 1e3) - term_out("fosc = %.3f kHz\n", v / 1e3); - else if (v) + if(v >= 1e6) + term_out("fosc = %.6f MHz\n", v/1e6); + else if(v >= 1e3) + term_out("fosc = %.3f kHz\n", v/1e3); + else if(v) term_out("fosc = %.0f Hz\n", v); else term_out("fosc off\n"); @@ -2414,14 +2433,11 @@ static int cmd_fosc(const PROGRAMMER *pgm, const AVRPART *p, int argc, const cha } if(argc != 2 || (argc > 1 && str_eq(argv[1], "-?"))) { - msg_error( - "Syntax: fosc [M|k] | off\n" - "Function: set the oscillator frequency\n" - ); + msg_error("Syntax: fosc [M|k] | off\n" "Function: set the oscillator frequency\n"); return -1; } v = strtod(argv[1], &endp); - if (endp == argv[1]) { + if(endp == argv[1]) { if(str_eq(argv[1], "off")) v = 0.0; else { @@ -2429,75 +2445,70 @@ static int cmd_fosc(const PROGRAMMER *pgm, const AVRPART *p, int argc, const cha return -1; } } - if (*endp == 'm' || *endp == 'M') + if(*endp == 'm' || *endp == 'M') v *= 1e6; - else if (*endp == 'k' || *endp == 'K') + else if(*endp == 'k' || *endp == 'K') v *= 1e3; - if ((rc = pgm->set_fosc(pgm, v)) != 0) { + if((rc = pgm->set_fosc(pgm, v)) != 0) { pmsg_error("(fosc) unable to set oscillator frequency (rc = %d)\n", rc); return -3; } return 0; } - static int cmd_sck(const PROGRAMMER *pgm, const AVRPART *p, int argc, const char *argv[]) { int rc; double v; char *endp; - if (argc == 1 && pgm->get_sck_period){ - if ((rc = pgm->get_sck_period(pgm, &v)) != 0) { + if(argc == 1 && pgm->get_sck_period) { + if((rc = pgm->get_sck_period(pgm, &v)) != 0) { pmsg_error("(fosc) unable to get SCK period (rc = %d)\n", rc); return -3; } - term_out("SCK period = %.1f us\n", v * 1e6); - term_out("SCK freq = %d kHz\n", (int)(0.001/v)); + term_out("SCK period = %.1f us\n", v*1e6); + term_out("SCK freq = %d kHz\n", (int) (0.001/v)); return 0; } if(argc != 2 || (argc > 1 && str_eq(argv[1], "-?"))) { - msg_error( - "Syntax: sck \n" - "Function: set the SCK period in us or frequency in [kM]Hz\n" - ); + msg_error("Syntax: sck \n" "Function: set the SCK period in us or frequency in [kM]Hz\n"); return -1; } v = strtod(argv[1], &endp); - if ((endp == argv[1]) || v <= 0.0) { + if((endp == argv[1]) || v <= 0.0) { pmsg_error("(sck) invalid bit clock period %s\n", argv[1]); return -1; } - if(*endp == 0 || str_caseeq(endp, "us")) // us is optional and the default + if(*endp == 0 || str_caseeq(endp, "us")) // us is optional and the default ; else if(str_caseeq(endp, "m") || str_caseeq(endp, "mhz")) - v = 1 / v; + v = 1/v; else if(str_caseeq(endp, "k") || str_caseeq(endp, "khz")) - v = 1e3 / v; + v = 1e3/v; else if(str_caseeq(endp, "hz")) - v = 1e6 / v; + v = 1e6/v; else { pmsg_error("(sck) invalid bit clock unit %s\n", endp); return -1; } - v *= 1e-6; // us to s - if ((rc = pgm->set_sck_period(pgm, v)) != 0) { + v *= 1e-6; // us to s + if((rc = pgm->set_sck_period(pgm, v)) != 0) { pmsg_error("(sck) unable to set SCK period (rc = %d)\n", rc); return -3; } return 0; } - static int cmd_varef(const PROGRAMMER *pgm, const AVRPART *p, int argc, const char *argv[]) { int rc; unsigned int chan; double v; char *endp; - if (argc == 1 && pgm->get_varef) { // varef w/o parameter returns value of channel 0 - if ((rc = pgm->get_varef(pgm, 0, &v)) != 0) { + if(argc == 1 && pgm->get_varef) { // varef w/o parameter returns value of channel 0 + if((rc = pgm->get_varef(pgm, 0, &v)) != 0) { pmsg_error("(varef) unable to get V[aref] (rc = %d)\n", rc); return -3; } @@ -2505,61 +2516,54 @@ static int cmd_varef(const PROGRAMMER *pgm, const AVRPART *p, int argc, const ch return 0; } - if (argc < 2 || argc > 3 || (argc > 1 && str_eq(argv[1], "-?"))) { - msg_error( - "Syntax: varef [channel] \n" - "Function: set the analog reference voltage\n" - ); + if(argc < 2 || argc > 3 || (argc > 1 && str_eq(argv[1], "-?"))) { + msg_error("Syntax: varef [channel] \n" "Function: set the analog reference voltage\n"); return -1; } - if (argc == 2) { + if(argc == 2) { chan = 0; v = strtod(argv[1], &endp); - if (endp == argv[1]) { + if(endp == argv[1]) { pmsg_error("(varef) cannot parse voltage %s\n", argv[1]); return -1; } } else { const char *errptr; + chan = str_int(argv[1], STR_UINT32, &errptr); if(errptr) { pmsg_error("(varef) channel %s: %s\n", argv[1], errptr); return -1; } v = strtod(argv[2], &endp); - if (endp == argv[2]) { + if(endp == argv[2]) { pmsg_error("(varef) cannot parse voltage %s\n", argv[2]); return -1; } } - if ((rc = pgm->set_varef(pgm, chan, v)) != 0) { + if((rc = pgm->set_varef(pgm, chan, v)) != 0) { pmsg_error("(varef) unable to set V[aref] (rc = %d)\n", rc); return -3; } return 0; } - static int cmd_help(const PROGRAMMER *pgm, const AVRPART *p, int argc, const char *argv[]) { if(argc > 1) { - msg_error( - "Syntax: help\n" - "Function: show help message for terminal commands\n" - ); + msg_error("Syntax: help\n" "Function: show help message for terminal commands\n"); return -1; } term_out("Valid commands:\n"); - for(int i=0; i : run the shell in a subshell, eg, !ls *.hex\n" " # ... : ignore rest of line (eg, used as comments in scripts)\n\n" @@ -2572,10 +2576,7 @@ static int cmd_help(const PROGRAMMER *pgm, const AVRPART *p, int argc, const cha static int cmd_spi(const PROGRAMMER *pgm, const AVRPART *p, int argc, const char *argv[]) { if(argc > 1) { - msg_error( - "Syntax: spi\n" - "Function: enter direct SPI mode\n" - ); + msg_error("Syntax: spi\n" "Function: enter direct SPI mode\n"); return -1; } @@ -2586,10 +2587,7 @@ static int cmd_spi(const PROGRAMMER *pgm, const AVRPART *p, int argc, const char static int cmd_pgm(const PROGRAMMER *pgm, const AVRPART *p, int argc, const char *argv[]) { if(argc > 1) { - msg_error( - "Syntax: pgm\n" - "Function: return to programming mode\n" - ); + msg_error("Syntax: pgm\n" "Function: return to programming mode\n"); return -1; } @@ -2599,20 +2597,16 @@ static int cmd_pgm(const PROGRAMMER *pgm, const AVRPART *p, int argc, const char return 0; } - static int cmd_verbose(const PROGRAMMER *pgm, const AVRPART *p, int argc, const char *argv[]) { int nverb; const char *errptr; - if (argc > 2 || (argc > 1 && str_eq(argv[1], "-?"))) { - msg_error( - "Syntax: verbose []\n" - "Function: display or set -v verbosity level\n" - ); + if(argc > 2 || (argc > 1 && str_eq(argv[1], "-?"))) { + msg_error("Syntax: verbose []\n" "Function: display or set -v verbosity level\n"); return -1; } - if (argc == 1) { + if(argc == 1) { msg_error("Verbosity level: %d\n", verbose); return 0; } @@ -2621,7 +2615,7 @@ static int cmd_verbose(const PROGRAMMER *pgm, const AVRPART *p, int argc, const pmsg_error("(verbose) verbosity level %s: %s\n", argv[1], errptr); return -1; } - if (nverb < 0) { + if(nverb < 0) { pmsg_error("(verbose) level must not be negative: %d\n", nverb); return -1; } @@ -2631,19 +2625,15 @@ static int cmd_verbose(const PROGRAMMER *pgm, const AVRPART *p, int argc, const return 0; } - static int cmd_quell(const PROGRAMMER *pgm, const AVRPART *p, int argc, const char *argv[]) { int nquell; const char *errptr; - if (argc > 2 || (argc > 1 && str_eq(argv[1], "-?"))) { - msg_error( - "Syntax: quell []\n" - "Function: display or set -q quell level for progress bars\n" - ); + if(argc > 2 || (argc > 1 && str_eq(argv[1], "-?"))) { + msg_error("Syntax: quell []\n" "Function: display or set -q quell level for progress bars\n"); return -1; } - if (argc == 1) { + if(argc == 1) { msg_error("Quell level: %d\n", quell_progress); return 0; } @@ -2652,7 +2642,7 @@ static int cmd_quell(const PROGRAMMER *pgm, const AVRPART *p, int argc, const ch pmsg_error("(quell) quell level %s: %s\n", argv[1], errptr); return -1; } - if (nquell < 0) { + if(nquell < 0) { pmsg_error("(quell) level must not be negative: %d\n", nquell); return -1; } @@ -2667,13 +2657,12 @@ static int cmd_quell(const PROGRAMMER *pgm, const AVRPART *p, int argc, const ch return 0; } - /* * Simplified shell-like tokenising of a command line, which is broken up * into an (argc, argv) style pointer array until - * - A not end-of-line token ends with a semicolon, which is set to nul - * - A token starts with a comment character # or subshell character ! - * - The end of the string is encountered + * - A not end-of-line token ends with a semicolon, which is set to nul + * - A token starts with a comment character # or subshell character ! + * - The end of the string is encountered * * Tokenisation takes single and double quoted strings into consideration. In * the second and third case a pointer to the end-of-string nul is returned @@ -2690,7 +2679,7 @@ static char *tokenize(char *s, int *argcp, const char ***argvp) { char *buf, *q, *r; // Upper estimate of the number of arguments - for(nargs=0, q=s; *q; nargs++) { + for(nargs = 0, q = s; *q; nargs++) { while(*q && !isspace((unsigned char) *q)) q++; while(*q && isspace((unsigned char) *q)) @@ -2699,31 +2688,32 @@ static char *tokenize(char *s, int *argcp, const char ***argvp) { slen = q - s; // Limit input line to some 186 Megabytes as max nargs is (slen+1)/2 - if(slen > 2*((INT_MAX - 2*sizeof(char *))/(sizeof(char *)+3))) + if(slen > 2*((INT_MAX - 2*sizeof(char *))/(sizeof(char *) + 3))) return NULL; // Allocate once for pointers and contents, so caller only needs to mmt_free(argv) - argv = mmt_malloc((nargs+2)*sizeof(char *) + slen + nargs); - buf = (char *) (argv+nargs+1); + argv = mmt_malloc((nargs + 2)*sizeof(char *) + slen + nargs); + buf = (char *) (argv + nargs + 1); - for(n=0, r=s; *r; ) { + for(n = 0, r = s; *r;) { if(n == 0 && *r == '!') { // Subshell command ! takes rest of line q = r; - r = q+strlen(q); + r = q + strlen(q); } else { q = str_nexttok(r, " \t\n\r\v\f", &r); if(*q == '#') { // Inline comment: ignore rest of line - r = q+strlen(q); + r = q + strlen(q); break; } } strcpy(buf, q); - if(*buf && !str_eq(buf, ";")) // Don't record empty arguments + if(*buf && !str_eq(buf, ";")) // Don't record empty arguments argv[n++] = buf; size_t len = strlen(q); + buf += len + 1; - if(n && **argv != '!' && len > 1 && buf[-2] == ';') { // End command + if(n && **argv != '!' && len > 1 && buf[-2] == ';') { // End command buf[-2] = 0; break; } @@ -2734,7 +2724,6 @@ static char *tokenize(char *s, int *argcp, const char ***argvp) { return r; } - static int do_cmd(const PROGRAMMER *pgm, const AVRPART *p, int argc, const char *argv[]) { int hold, matches; size_t len; @@ -2743,10 +2732,10 @@ static int do_cmd(const PROGRAMMER *pgm, const AVRPART *p, int argc, const char matches = 0; for(int i = 0; i < NCMDS; i++) if(*(void (**)(void)) ((char *) pgm + cmd[i].fnoff)) - if(len && strncasecmp(argv[0], cmd[i].name, len)==0) { // Partial initial match + if(len && strncasecmp(argv[0], cmd[i].name, len) == 0) { // Partial initial match hold = i; matches++; - if(cmd[i].name[len] == 0) { // Exact match + if(cmd[i].name[len] == 0) { // Exact match matches = 1; break; } @@ -2759,29 +2748,28 @@ static int do_cmd(const PROGRAMMER *pgm, const AVRPART *p, int argc, const char if(matches > 1) for(int ch = ':', i = 0; i < NCMDS; i++) if(*(void (**)(void)) ((char *) pgm + cmd[i].fnoff)) - if(len && strncasecmp(argv[0], cmd[i].name, len)==0) + if(len && strncasecmp(argv[0], cmd[i].name, len) == 0) msg_error("%c %s", ch, cmd[i].name), ch = ','; msg_error("\n"); return -1; } - char *terminal_get_input(const char *prompt) { char input[256]; term_out("%s", prompt); if(fgets(input, sizeof(input), stdin)) { int len = strlen(input); - if(len > 0 && input[len-1] == '\n') - input[len-1] = 0; + + if(len > 0 && input[len - 1] == '\n') + input[len - 1] = 0; return mmt_strdup(input); } return NULL; } - static int process_line(char *q, const PROGRAMMER *pgm, const AVRPART *p) { int argc, rc = 0; const char **argv; @@ -2791,12 +2779,13 @@ static int process_line(char *q, const PROGRAMMER *pgm, const AVRPART *p) { q++; // Skip blank lines and comments - if (!*q || (*q == '#')) + if(!*q || (*q == '#')) return 0; // Tokenise command line do { - argc = 0; argv = NULL; + argc = 0; + argv = NULL; q = tokenize(q, &argc, &argv); if(!q) return -1; @@ -2807,14 +2796,17 @@ static int process_line(char *q, const PROGRAMMER *pgm, const AVRPART *p) { if(argc == 1 && **argv == '!') { if(allow_subshells) { const char *q; - for(q=argv[0]+1; *q && isspace((unsigned char) *q); q++) + + for(q = argv[0] + 1; *q && isspace((unsigned char) *q); q++) continue; errno = 0; int shret = *q? system(q): 0; + if(errno) pmsg_warning("system() call returned %d: %s\n", shret, strerror(errno)); } else { pmsg_info("by default subshell commands are not allowed in the terminal; to change put\n"); + #if defined(WIN32) imsg_info("allow_subshells = yes; into " USER_CONF_FILE " in the avrdude.exe directory\n"); #else @@ -2824,14 +2816,13 @@ static int process_line(char *q, const PROGRAMMER *pgm, const AVRPART *p) { mmt_free(argv); return 0; } - // Run the command led_clr(pgm, LED_ERR); led_set(pgm, LED_PGM); rc = do_cmd(pgm, p, argc, argv); - if(rc<0) + if(rc < 0) led_set(pgm, LED_ERR); led_clr(pgm, LED_PGM); @@ -2841,30 +2832,29 @@ static int process_line(char *q, const PROGRAMMER *pgm, const AVRPART *p) { return rc; } - /* * Process individual terminal line - * - Used by main's -T argument - * - The terminal manages a cache, -U does not: the caller is responsible for executing - * + pgm->flush_cache(pgm, p) between -T line and -U memory read/avrdude exit - * + pgm->reset_cache(pgm, p) between -U memory write and -T line + * - Used by main's -T argument + * - The terminal manages a cache, -U does not: the caller is responsible for executing + * + pgm->flush_cache(pgm, p) between -T line and -U memory read/avrdude exit + * + pgm->reset_cache(pgm, p) between -U memory write and -T line */ int terminal_line(const PROGRAMMER *pgm, const AVRPART *p, const char *line) { char *ln = mmt_strdup(line); int ret = process_line(ln, pgm, p); + mmt_free(ln); return ret; } - #if defined(HAVE_LIBREADLINE) - // Any character in standard input available (without sleeping)? static int readytoread() { + #ifdef _MSC_VER - return rl_input_available(); + return rl_input_available(); #elif defined(WIN32) HANDLE hStdin = GetStdHandle(STD_INPUT_HANDLE); @@ -2883,7 +2873,7 @@ static int readytoread() { return -1; } - if(dwNumberOfEventsRead <= 0) // Nothing in the input buffer + if(dwNumberOfEventsRead <= 0) // Nothing in the input buffer return 0; // Filter out all the events that readline does not handle ... @@ -2897,12 +2887,13 @@ static int readytoread() { } } #else - struct timeval tv = { 0L, 0L }; - fd_set fds; - FD_ZERO(&fds); - FD_SET(0, &fds); + struct timeval tv = { 0L, 0L }; + fd_set fds; + + FD_ZERO(&fds); + FD_SET(0, &fds); - return select(1, &fds, NULL, NULL, &tv) > 0; + return select(1, &fds, NULL, NULL, &tv) > 0; #endif } @@ -2917,11 +2908,10 @@ static void term_gotline(char *cmdstr) { } mmt_free(cmdstr); /* - * This is a workaround for a bug apparently present in the - * readline compat layer of libedit which is natively present in - * NetBSD and MacOS. + * This is a workaround for a bug apparently present in the readline compat + * layer of libedit which is natively present in NetBSD and MacOS. * - * see https://github.com/avrdudes/avrdude/issues/1173 + * See https://github.com/avrdudes/avrdude/issues/1173 */ if(cx->term_running) { rl_callback_handler_remove(); @@ -2937,7 +2927,6 @@ static void term_gotline(char *cmdstr) { rl_callback_handler_remove(); } - static int terminal_mode_interactive(const PROGRAMMER *pgm, const AVRPART *p) { cx->term_pgm = pgm; // For callback routine cx->term_p = p; @@ -2945,8 +2934,8 @@ static int terminal_mode_interactive(const PROGRAMMER *pgm, const AVRPART *p) { rl_callback_handler_install("avrdude> ", term_gotline); cx->term_running = 1; - for(int n=1; cx->term_running; n++) { - if(n%16 == 0) { // Every 100 ms (16*6.25 us) reset bootloader watchdog timer + for(int n = 1; cx->term_running; n++) { + if(n%16 == 0) { // Every 100 ms (16*6.25 us) reset bootloader watchdog timer if(pgm->term_keep_alive) pgm->term_keep_alive(pgm, NULL); led_set(pgm, LED_NOP); @@ -2958,16 +2947,15 @@ static int terminal_mode_interactive(const PROGRAMMER *pgm, const AVRPART *p) { return pgm->flush_cache(pgm, p); } - #endif - int terminal_mode_noninteractive(const PROGRAMMER *pgm, const AVRPART *p) { char *cmdbuf; int rc = 0; while((cmdbuf = terminal_get_input("avrdude> "))) { int rc = process_line(cmdbuf, pgm, p); + mmt_free(cmdbuf); if(rc > 0) break; @@ -2978,27 +2966,29 @@ int terminal_mode_noninteractive(const PROGRAMMER *pgm, const AVRPART *p) { return pgm->flush_cache(pgm, p); } - // Terminal shell that is called on avrdude -t int terminal_mode(const PROGRAMMER *pgm, const AVRPART *p) { + #if defined(HAVE_LIBREADLINE) - // GNU libreadline can also work if input is a pipe. - // EditLine (NetBSD, MacOS) has issues with that, so only use it when - // running interactively. - // EditLine uses version 4.2 (0x0402). - if (isatty(fileno(stdin)) || rl_readline_version > 0x0500) + /* + * GNU libreadline can also work if input is a pipe. EditLine (NetBSD, MacOS) + * has issues with that, so only use it when running interactively. EditLine + * uses version 4.2 (0x0402). + */ + if(isatty(fileno(stdin)) || rl_readline_version > 0x0500) return terminal_mode_interactive(pgm, p); #endif + return terminal_mode_noninteractive(pgm, p); } - static int cmd_include(const PROGRAMMER *pgm, const AVRPART *p, int argc, const char *argv[]) { int help = 0, invalid = 0, echo = 0, itemac = 1; - for(int ai = 0; --argc > 0; ) { // Simple option parsing + for(int ai = 0; --argc > 0;) { // Simple option parsing const char *q; - if(*(q=argv[++ai]) != '-' || !q[1]) + + if(*(q = argv[++ai]) != '-' || !q[1]) argv[itemac++] = argv[ai]; else { while(*++q) { @@ -3018,21 +3008,20 @@ static int cmd_include(const PROGRAMMER *pgm, const AVRPART *p, int argc, const } } } - argc = itemac; // (arg,c argv) still valid but options have been removed + argc = itemac; // (argc, argv) still valid but options have been removed if(argc != 2 || help || invalid) { - msg_error( - "Syntax: include [opts] \n" + msg_error("Syntax: include [opts] \n" "Function: include contents of named file as if it was typed\n" "Option:\n" - " -e echo lines as they are processed\n" - ); + " -e echo lines as they are processed\n"); return !help || invalid? -1: 0; } int lineno = 0, rc = 0; const char *errstr; FILE *fp = fopen(argv[1], "r"); + if(fp == NULL) { pmsg_ext_error("(include) cannot open file %s: %s\n", argv[1], strerror(errno)); return -1; @@ -3043,7 +3032,7 @@ static int cmd_include(const PROGRAMMER *pgm, const AVRPART *p, int argc, const if(echo) { term_out("# "); if(verbose > 0) - term_out("%d: ", lineno); + term_out("%d: ", lineno); term_out("%s", buffer); lterm_out(""); } @@ -3060,7 +3049,6 @@ static int cmd_include(const PROGRAMMER *pgm, const AVRPART *p, int argc, const return rc; } - /* * ASCII progress bar * @@ -3074,15 +3062,15 @@ static int cmd_include(const PROGRAMMER *pgm, const AVRPART *p, int argc, const * First non-NULL heading hdr starts reporting, percent=100 stops reporting; * etime is the wall-clock time in seconds that the task has taken so for; * finish can take on three values: - * -1 task ended in error, show the last valid percentage and fill - * progress bar with hyphens instead of hashes - * 0 do not terminate progress bar with \n when finishing at 100 percent - * 1 terminate progress bar with \n when finishing at 100 percent + * -1 task ended in error, show the last valid percentage and fill + * progress bar with hyphens instead of hashes + * 0 do not terminate progress bar with \n when finishing at 100 percent + * 1 terminate progress bar with \n when finishing at 100 percent */ static void update_progress_tty(int percent, double etime, const char *hdr, int finish) { int i; - setvbuf(stderr, (char *) NULL, _IONBF, 0); // Set stderr to be ubuffered + setvbuf(stderr, (char *) NULL, _IONBF, 0); // Set stderr to be ubuffered if(hdr) { lmsg_info(""); // Print new line unless already done before @@ -3102,8 +3090,9 @@ static void update_progress_tty(int percent, double etime, const char *hdr, int int showperc = finish >= 0? percent: cx->term_tty_last; char hashes[51]; + memset(hashes, finish >= 0? ' ': '-', 50); - for(i=0; iterm_tty_last = percent; - setvbuf(stderr, (char *) NULL, _IOLBF, 0); // Set stderr to be line buffered + setvbuf(stderr, (char *) NULL, _IOLBF, 0); // Set stderr to be line buffered } static void update_progress_no_tty(int percent, double etime, const char *hdr, int finish) { @@ -3148,14 +3137,14 @@ static void update_progress_no_tty(int percent, double etime, const char *hdr, i } void terminal_setup_update_progress() { - if (isatty (STDERR_FILENO)) + if(isatty(STDERR_FILENO)) update_progress = update_progress_tty; else { update_progress = update_progress_no_tty; /* disable all buffering of stderr for compatibility with software that captures and redirects output to a GUI i.e. Programmers Notepad */ - setvbuf( stderr, NULL, _IONBF, 0 ); - setvbuf( stdout, NULL, _IONBF, 0 ); + setvbuf(stderr, NULL, _IONBF, 0); + setvbuf(stdout, NULL, _IONBF, 0); } } diff --git a/src/tpi.h b/src/tpi.h index 88c548d2e..b6c0a291a 100644 --- a/src/tpi.h +++ b/src/tpi.h @@ -23,9 +23,11 @@ extern "C" { #endif -static const unsigned char tpi_skey[] = { 0x12, 0x89, 0xAB, 0x45, 0xCD, 0xD8, 0x88, 0xFF }; +static const unsigned char tpi_skey[] = { + 0x12, 0x89, 0xAB, 0x45, 0xCD, 0xD8, 0x88, 0xFF +}; -/* registers */ +// Registers #define TPI_REG_TPIIR 0x0F #define TPI_IDENT_CODE 0x80 @@ -33,42 +35,42 @@ static const unsigned char tpi_skey[] = { 0x12, 0x89, 0xAB, 0x45, 0xCD, 0xD8, 0x #define TPI_REG_TPIPCR 0x02 #define TPI_REG_TPISR 0x00 -#define TPI_REG_TPISR_NVMEN (1 << 1) +#define TPI_REG_TPISR_NVMEN (1<<1) -/* TPI commands */ -#define TPI_CMD_SLD 0x20 -#define TPI_CMD_SLD_PI 0x24 -#define TPI_CMD_SIN 0x10 -#define TPI_CMD_SOUT 0x90 -#define TPI_CMD_SSTCS 0xC0 -#define TPI_CMD_SST 0x60 -#define TPI_CMD_SST_PI 0x64 +// TPI commands +#define TPI_CMD_SLD 0x20 +#define TPI_CMD_SLD_PI 0x24 +#define TPI_CMD_SIN 0x10 +#define TPI_CMD_SOUT 0x90 +#define TPI_CMD_SSTCS 0xC0 +#define TPI_CMD_SST 0x60 +#define TPI_CMD_SST_PI 0x64 -#define TPI_CMD_SLDCS 0x80 -#define TPI_CMD_SSTPR 0x68 -#define TPI_CMD_SKEY 0xE0 +#define TPI_CMD_SLDCS 0x80 +#define TPI_CMD_SSTPR 0x68 +#define TPI_CMD_SKEY 0xE0 -/* for TPI_CMD_SIN & TPI_CMD_SOUT */ -#define TPI_SIO_ADDR(x) ((x & 0x30) << 1 | (x & 0x0F)) +// For TPI_CMD_SIN & TPI_CMD_SOUT +#define TPI_SIO_ADDR(x) ((x & 0x30) << 1 | (x & 0x0F)) -/* ATtiny4/5/9/10 I/O registers */ -#define TPI_IOREG_NVMCSR 0x32 -#define TPI_IOREG_NVMCMD 0x33 +// ATtiny4/5/9/10 I/O registers +#define TPI_IOREG_NVMCSR 0x32 +#define TPI_IOREG_NVMCMD 0x33 -/* bit for NVMCSR */ -#define TPI_IOREG_NVMCSR_NVMBSY (1 << 7) +// Bit for NVMCSR +#define TPI_IOREG_NVMCSR_NVMBSY (1<<7) -/* NVM commands */ -#define TPI_NVMCMD_NO_OPERATION 0x00 -#define TPI_NVMCMD_CHIP_ERASE 0x10 -#define TPI_NVMCMD_SECTION_ERASE 0x14 -#define TPI_NVMCMD_WORD_WRITE 0x1D +// NVM commands +#define TPI_NVMCMD_NO_OPERATION 0x00 +#define TPI_NVMCMD_CHIP_ERASE 0x10 +#define TPI_NVMCMD_SECTION_ERASE 0x14 +#define TPI_NVMCMD_WORD_WRITE 0x1D -static const unsigned char tpi_skey_cmd[] = { TPI_CMD_SKEY, 0xff, 0x88, 0xd8, 0xcd, 0x45, 0xab, 0x89, 0x12 }; +static const unsigned char tpi_skey_cmd[] = { + TPI_CMD_SKEY, 0xff, 0x88, 0xd8, 0xcd, 0x45, 0xab, 0x89, 0x12 +}; #ifdef __cplusplus } #endif - #endif - diff --git a/src/update.c b/src/update.c index 66929a7f5..c33a823cc 100644 --- a/src/update.c +++ b/src/update.c @@ -33,7 +33,6 @@ #include "avrdude.h" #include "libavrdude.h" - // Is s a multi-memory string (comma-separates list, all, ALL, etc or list subtraction)? static int is_multimem(const char *s) { return str_eq(s, "ALL") || str_eq(s, "all") || str_eq(s, "etc") || strpbrk(s, "-,\\"); @@ -42,21 +41,23 @@ static int is_multimem(const char *s) { /* * Parsing of [::[:] | [:]] * - * As memory names don't contain colons and the r/w/v operation is - * a single character, check whether the first two colons sandwich one - * character. If not, treat the argument as a filename (defaulting to - * flash write). This allows colons in filenames other than those for - * enclosing and separating , eg, C:/some/file.hex + * As memory names don't contain colons and the r/w/v operation is a + * single character, check whether the first two colons sandwich one character. + * If not, treat the argument as a filename (defaulting to flash write). This + * allows colons in filenames other than those for enclosing and + * separating , eg, C:/some/file.hex */ UPDATE *parse_op(const char *s) { // Assume -U [:] first UPDATE *upd = (UPDATE *) mmt_malloc(sizeof *upd); + upd->memstr = NULL; // Defaults to flash or application upd->op = DEVICE_WRITE; const char *fn = s; // Check for :c: start in which case override defaults const char *fc = strchr(s, ':'); + if(fc && fc[1] && fc[2] == ':') { if(!strchr("rwv", fc[1])) { pmsg_error("invalid I/O mode :%c: in -U %s\n", fc[1], s); @@ -66,21 +67,18 @@ UPDATE *parse_op(const char *s) { return NULL; } - upd->memstr = memcpy(mmt_malloc(fc-s+1), s, fc-s); - upd->op = - fc[1]=='r'? DEVICE_READ: - fc[1]=='w'? DEVICE_WRITE: DEVICE_VERIFY; - fn = fc+3; + upd->memstr = memcpy(mmt_malloc(fc - s + 1), s, fc - s); + upd->op = fc[1] == 'r'? DEVICE_READ: fc[1] == 'w'? DEVICE_WRITE: DEVICE_VERIFY; + fn = fc + 3; } - - // Autodetect for file reads, and hex (multi-mem)/raw (single mem) for file writes - upd->format = upd->op != DEVICE_READ? FMT_AUTO: - is_multimem(upd->memstr)? FMT_IHXC: FMT_RBIN; + // Autodetect for file reads, and hex (multi-mem)/raw (single mem) for file writes + upd->format = upd->op != DEVICE_READ? FMT_AUTO: is_multimem(upd->memstr)? FMT_IHXC: FMT_RBIN; // Filename: last char is format if the penultimate char is a colon size_t len = strlen(fn); - if(len > 2 && fn[len-2] == ':') { // Assume format specified - upd->format = fileio_format_with_errmsg(fn[len-1], ""); + + if(len > 2 && fn[len - 2] == ':') { // Assume format specified + upd->format = fileio_format_with_errmsg(fn[len - 1], ""); if(upd->format == FMT_ERROR) { mmt_free(upd->memstr); mmt_free(upd); @@ -89,15 +87,15 @@ UPDATE *parse_op(const char *s) { len -= 2; } - upd->filename = memcpy(mmt_malloc(len+1), fn, len); + upd->filename = memcpy(mmt_malloc(len + 1), fn, len); return upd; } - UPDATE *dup_update(const UPDATE *upd) { UPDATE *u = (UPDATE *) mmt_malloc(sizeof *u); - memcpy(u, upd, sizeof*u); + + memcpy(u, upd, sizeof *u); u->memstr = upd->memstr? mmt_strdup(upd->memstr): NULL; u->filename = mmt_strdup(upd->filename); @@ -106,6 +104,7 @@ UPDATE *dup_update(const UPDATE *upd) { UPDATE *new_update(int op, const char *memstr, int filefmt, const char *fname) { UPDATE *u = (UPDATE *) mmt_malloc(sizeof *u); + u->memstr = mmt_strdup(memstr); u->filename = mmt_strdup(fname); u->op = op; @@ -116,6 +115,7 @@ UPDATE *new_update(int op, const char *memstr, int filefmt, const char *fname) { UPDATE *cmd_update(const char *cmd) { UPDATE *u = (UPDATE *) mmt_malloc(sizeof *u); + u->cmdline = cmd; return u; @@ -132,13 +132,10 @@ void free_update(UPDATE *u) { char *update_str(const UPDATE *upd) { if(upd->cmdline) - return mmt_sprintf("-%c %s", - str_eq("interactive terminal", upd->cmdline)? 't': 'T', upd->cmdline); - return mmt_sprintf("-U %s:%c:%s:%c", - upd->memstr, + return mmt_sprintf("-%c %s", str_eq("interactive terminal", upd->cmdline)? 't': 'T', upd->cmdline); + return mmt_sprintf("-U %s:%c:%s:%c", upd->memstr, upd->op == DEVICE_READ? 'r': upd->op == DEVICE_WRITE? 'w': 'v', - upd->filename, - fileio_fmtchr(upd->format)); + upd->filename, fileio_fmtchr(upd->format)); } // Memory statistics considering holes after a file read returned size bytes @@ -162,6 +159,7 @@ int memstats_mem(const AVRPART *p, const AVRMEM *mem, int size, Filestats *fsp) } int pgsize = mem->page_size; + if(pgsize < 1) pgsize = 1; @@ -172,9 +170,11 @@ int memstats_mem(const AVRPART *p, const AVRMEM *mem, int size, Filestats *fsp) ret.lastaddr = -1; int firstset = 0, insection = 0; + // Scan all memory - for(int addr = 0; addr < mem->size; ) { + for(int addr = 0; addr < mem->size;) { int pageset = 0; + // Go page by page for(int pgi = 0; pgi < pgsize; pgi++, addr++) { if(mem->tags[addr] & TAG_ALLOCATED) { @@ -183,7 +183,7 @@ int memstats_mem(const AVRPART *p, const AVRMEM *mem, int size, Filestats *fsp) ret.firstaddr = addr; } ret.lastaddr = addr; - // size can be smaller than tags suggest owing to flash trailing-0xff + // Size can be smaller than tags suggest owing to flash trailing-0xff if(addr < size) { ret.nbytes++; if(!pageset) { @@ -214,7 +214,6 @@ int memstats_mem(const AVRPART *p, const AVRMEM *mem, int size, Filestats *fsp) return LIBAVRDUDE_SUCCESS; } - // Helper functions for dry run to determine file access int update_is_okfile(const char *fn) { @@ -238,6 +237,7 @@ int update_is_writeable(const char *fn) { // File does not exist: try to create it FILE *test = fopen(fn, "w"); + if(test) { unlink(fn); fclose(test); @@ -257,7 +257,6 @@ int update_is_readable(const char *fn) { return access(fn, R_OK) == 0 && update_is_okfile(fn); } - static void ioerror(const char *iotype, const UPDATE *upd) { int errnocp = errno; @@ -278,8 +277,7 @@ static int is_interesting_mem(const PROGRAMMER *pgm, const AVRPART *p, const AVR static int is_backup_mem(const PROGRAMMER *pgm, const AVRPART *p, const AVRMEM *mem) { return mem_is_in_flash(mem)? mem_is_flash(mem): mem_is_in_sigrow(mem)? mem_is_sigrow(mem): - mem_is_in_fuses(mem)? mem_is_fuses(mem) || !avr_locate_fuses(p): - is_interesting_mem(pgm, p, mem); + mem_is_in_fuses(mem)? mem_is_fuses(mem) || !avr_locate_fuses(p): is_interesting_mem(pgm, p, mem); } // Add (not == 0) or subtract (not == 1) a memory from list @@ -304,11 +302,10 @@ static int memadd(AVRMEM **mlist, int nm, int not, AVRMEM *m) { * to *np and *rwvsoftfail indicating unknown memories for this part. If dry is * set then -1 will be written to *dry when a generally unknown memory is used. */ -AVRMEM **memory_list(const char *mstr, const PROGRAMMER *pgm, const AVRPART *p, - int *np, int *rwvsoftp, int *dry) { +AVRMEM **memory_list(const char *mstr, const PROGRAMMER *pgm, const AVRPART *p, int *np, int *rwvsoftp, int *dry) { - int not, nm = (lsize(p->mem) + 1) * ((int) str_numc(mstr, ',') + 1); // Upper limit - AVRMEM *m, **umemlist = mmt_malloc(nm*sizeof*umemlist); + int not, nm = (lsize(p->mem) + 1)*((int) str_numc(mstr, ',') + 1); // Upper limit + AVRMEM *m, **umemlist = mmt_malloc(nm*sizeof *umemlist); char *dstr = mmt_strdup(mstr), *s = dstr, *e; nm = 0; // Now count how many there really are mentioned @@ -317,16 +314,16 @@ AVRMEM **memory_list(const char *mstr, const PROGRAMMER *pgm, const AVRPART *p, if(e) *e = 0; s = str_trim(s); - if((not = *s == '\\' || *s =='-')) // \mem or -mem removes the memory + if((not = *s == '\\' || *s == '-')) // \mem or -mem removes the memory s++; if(str_eq(s, "ALL")) { for(LNODEID lm = lfirst(p->mem); lm; lm = lnext(lm)) if(is_interesting_mem(pgm, p, (m = ldata(lm)))) - nm = memadd(umemlist, nm, not, m); + nm = memadd(umemlist, nm, not, m); } else if(str_eq(s, "all") || str_eq(s, "etc")) { for(LNODEID lm = lfirst(p->mem); lm; lm = lnext(lm)) if(is_backup_mem(pgm, p, (m = ldata(lm)))) - nm = memadd(umemlist, nm, not, m); + nm = memadd(umemlist, nm, not, m); } else if(!*s) { // Ignore empty list elements } else { if(dry) { @@ -340,7 +337,7 @@ AVRMEM **memory_list(const char *mstr, const PROGRAMMER *pgm, const AVRPART *p, *dry = LIBAVRDUDE_SOFTFAIL; } if((m = avr_locate_mem(p, s))) - nm = memadd(umemlist, nm, not, m); + nm = memadd(umemlist, nm, not, m); else if(rwvsoftp) { pmsg_warning("skipping unknown memory %s in list -U %s:...\n", s, mstr); *rwvsoftp = 1; @@ -348,11 +345,12 @@ AVRMEM **memory_list(const char *mstr, const PROGRAMMER *pgm, const AVRPART *p, } if(!e) break; - s = e+1; + s = e + 1; } mmt_free(dstr); int nj = 0; + for(int i = 0; i < nm; i++) // Remove NULL entries if((umemlist[nj] = umemlist[i])) nj++; @@ -365,17 +363,17 @@ AVRMEM **memory_list(const char *mstr, const PROGRAMMER *pgm, const AVRPART *p, return umemlist; } - // Returns whether or not the memory list contains a flash memory int memlist_contains_flash(const char *mstr, const AVRPART *p) { int ret = 0, nm = 0; AVRMEM **mlist = memory_list(mstr, NULL, p, &nm, NULL, NULL); - for(int i=0; icmdline) { // Todo: parse terminal command line? - cx->upd_termcmds = mmt_realloc(cx->upd_termcmds, sizeof(*cx->upd_termcmds) * (cx->upd_nterms+1)); + cx->upd_termcmds = mmt_realloc(cx->upd_termcmds, sizeof(*cx->upd_termcmds)*(cx->upd_nterms + 1)); cx->upd_termcmds[cx->upd_nterms++] = upd->cmdline; return 0; } @@ -410,7 +408,7 @@ int update_dryrun(const AVRPART *p, UPDATE *upd) { errno = 0; if(!known && !update_is_readable(upd->filename)) { ioerror("readable", upd); - ret = LIBAVRDUDE_SOFTFAIL; // Even so it might still be there later on + ret = LIBAVRDUDE_SOFTFAIL; // Even so it might still be there later on known = 1; // Pretend we know it, so no auto detect needed } } @@ -428,8 +426,7 @@ int update_dryrun(const AVRPART *p, UPDATE *upd) { upd->format = format_detect; if(quell_progress < 2) pmsg_notice2("%s file %s auto detected as %s\n", - upd->op == DEVICE_READ? "output": "input", upd->filename, - fileio_fmtstr(upd->format)); + upd->op == DEVICE_READ? "output": "input", upd->filename, fileio_fmtstr(upd->format)); } } @@ -443,15 +440,15 @@ int update_dryrun(const AVRPART *p, UPDATE *upd) { if(!update_is_writeable(upd->filename)) { ioerror("writeable", upd); ret = LIBAVRDUDE_SOFTFAIL; - } else if(upd->filename) { // Record filename (other than stdout) is available for future reads + } else if(upd->filename) { // Record filename (other than stdout) is available for future reads if(!str_eq(upd->filename, "-") && - (cx->upd_wrote = mmt_realloc(cx->upd_wrote, sizeof(*cx->upd_wrote) * (cx->upd_nfwritten+1)))) + (cx->upd_wrote = mmt_realloc(cx->upd_wrote, sizeof(*cx->upd_wrote)*(cx->upd_nfwritten + 1)))) cx->upd_wrote[cx->upd_nfwritten++] = upd->filename; } } break; - case DEVICE_VERIFY: // Already checked that file is readable + case DEVICE_VERIFY: // Already checked that file is readable case DEVICE_WRITE: break; @@ -463,7 +460,6 @@ int update_dryrun(const AVRPART *p, UPDATE *upd) { return ret; } - static int update_avr_write(const PROGRAMMER *pgm, const AVRPART *p, const AVRMEM *mem, const UPDATE *upd, enum updateflags flags, int size, int multiple) { @@ -497,30 +493,26 @@ static int update_avr_write(const PROGRAMMER *pgm, const AVRPART *p, const AVRME if(memstats_mem(p, mem, size, &fs_patched) < 0) return -1; if(memcmp(&fs_patched, &fs, sizeof fs)) { - pmsg_notice("preparing flash input for device%s\n", - pgm->prog_modes & PM_SPM? " bootloader": ""); - imsg_notice("%d byte%s in %d section%s %s%s", - fs_patched.nbytes, str_plural(fs_patched.nbytes), - fs_patched.nsections, str_plural(fs_patched.nsections), - fs_patched.nsections == 1? "": "of ", - str_ccinterval(fs_patched.firstaddr, fs_patched.lastaddr)); - if(mem->page_size > 1) { - msg_notice(": %d page%s and %d pad byte%s", - fs_patched.npages, str_plural(fs_patched.npages), - fs_patched.nfill, str_plural(fs_patched.nfill)); - if(fs_patched.ntrailing) - imsg_notice("note %d trailing 0xff byte%s", - fs_patched.ntrailing, str_plural(fs_patched.ntrailing)); - } - msg_notice("\n"); + pmsg_notice("preparing flash input for device%s\n", is_spm(pgm)? " bootloader": ""); + imsg_notice("%d byte%s in %d section%s %s%s", + fs_patched.nbytes, str_plural(fs_patched.nbytes), + fs_patched.nsections, str_plural(fs_patched.nsections), + fs_patched.nsections == 1? "": "of ", str_ccinterval(fs_patched.firstaddr, fs_patched.lastaddr)); + if(mem->page_size > 1) { + msg_notice(": %d page%s and %d pad byte%s", + fs_patched.npages, str_plural(fs_patched.npages), fs_patched.nfill, str_plural(fs_patched.nfill)); + if(fs_patched.ntrailing) + imsg_notice("note %d trailing 0xff byte%s", fs_patched.ntrailing, str_plural(fs_patched.ntrailing)); + } + msg_notice("\n"); memcpy(&fs, &fs_patched, sizeof fs); } } - // Write the buffer contents to the selected memory int spellout = size > 0 && size <= 4 && fs.nbytes == size; + pmsg_info("writing %d byte%s %sto %s", fs.nbytes, str_plural(fs.nbytes), - spellout? str_ccprintf("(0x%s) ", str_cchex(mem->buf, size, 1)+1): "", m_name); + spellout? str_ccprintf("(0x%s) ", str_cchex(mem->buf, size, 1) + 1): "", m_name); if(flags & UF_NOWRITE) { // Test mode: write to stdout in intel hex rather than to the chip @@ -556,9 +548,10 @@ static int update_avr_verify(const PROGRAMMER *pgm, const AVRPART *p, const AVRM led_set(pgm, LED_VFY); if(pbar) - report_progress (0, 1, caption); + report_progress(0, 1, caption); int rc = avr_read_mem(pgm, p, mem, v); - report_progress (1, 1, NULL); + + report_progress(1, 1, NULL); if(rc < 0) { pmsg_error("unable to read all of %s (rc = %d)\n", m_name, rc); led_set(pgm, LED_ERR); @@ -571,9 +564,9 @@ static int update_avr_verify(const PROGRAMMER *pgm, const AVRPART *p, const AVRM led_set(pgm, LED_ERR); goto error; } - // @@@ has there has been output in the meantime to make the ", x bytes verified" look out of place? int verified = fs.nbytes + fs.ntrailing; + if(pbar || upd->op == DEVICE_VERIFY) pmsg_info("%d byte%s of %s verified\n", verified, str_plural(verified), m_name); else @@ -587,26 +580,27 @@ static int update_avr_verify(const PROGRAMMER *pgm, const AVRPART *p, const AVRM return retval; } -static int update_mem_from_all(const UPDATE *upd, const AVRPART *p, const AVRMEM *m, - const AVRMEM *all, int allsize) { +static int update_mem_from_all(const UPDATE *upd, const AVRPART *p, const AVRMEM *m, const AVRMEM *all, int allsize) { const char *m_name = avr_mem_name(p, m); int off = fileio_mem_offset(p, m); + if(off < 0) { pmsg_warning("cannot map %s to flat address space, skipping ...\n", m_name); return LIBAVRDUDE_GENERAL_FAILURE; } // Copy input file contents into memory int size = m->size; - if(allsize-off < size) // Clip to available data in input - size = allsize > off? allsize-off: 0; - if(is_memset(all->tags+off, 0, size)) // Nothing set? This memory was not present + + if(allsize - off < size) // Clip to available data in input + size = allsize > off? allsize - off: 0; + if(is_memset(all->tags + off, 0, size)) // Nothing set? This memory was not present size = 0; if(size == 0) pmsg_warning("%s has no data for %s, skipping ...\n", str_infilename(upd->filename), m_name); - memcpy(m->buf, all->buf+off, size); - memcpy(m->tags, all->tags+off, size); + memcpy(m->buf, all->buf + off, size); + memcpy(m->tags, all->tags + off, size); return size; } @@ -616,6 +610,7 @@ static int update_all_from_file(const UPDATE *upd, const PROGRAMMER *pgm, const // On writing to the device trailing 0xff might be cut off int op = upd->op == DEVICE_WRITE? FIO_READ: FIO_READ_FOR_VERIFY; int allsize = fileio_mem(op, upd->filename, upd->format, p, all, -1); + if(allsize < 0) { pmsg_error("reading from file %s failed\n", str_infilename(upd->filename)); return -1; @@ -626,7 +621,7 @@ static int update_all_from_file(const UPDATE *upd, const PROGRAMMER *pgm, const "reading %d byte%s for %s from input file %s\n": "verifying %d byte%s of %s against input file %s\n", fsp->nbytes, str_plural(fsp->nbytes), mem_desc, str_infilename(upd->filename) - ); + ); return allsize; } @@ -639,7 +634,8 @@ int do_op(const PROGRAMMER *pgm, const AVRPART *p, const UPDATE *upd, enum updat const char *umstr = upd->memstr; if(!(flags & UF_NOHEADING)) { - char *heading = update_str(upd); + char *heading = update_str(upd); + lmsg_info("\n"); // Ensure an empty line for visual separation of operations pmsg_info("processing %s\n", heading); mmt_free(heading); @@ -663,13 +659,12 @@ int do_op(const PROGRAMMER *pgm, const AVRPART *p, const UPDATE *upd, enum updat mmt_free(umemlist); return LIBAVRDUDE_SOFTFAIL; } - // Maximum length of memory names for to-be-processed memories - for(int i=0; i maxrlen) maxrlen = len; - seglist = mmt_malloc(ns*sizeof*seglist); + seglist = mmt_malloc(ns*sizeof *seglist); } mem = umemlist? fileio_any_memory("any"): avr_locate_mem(p, umstr); @@ -679,9 +674,9 @@ int do_op(const PROGRAMMER *pgm, const AVRPART *p, const UPDATE *upd, enum updat } const char *rcap = str_ccprintf("%*sReading", (int) strlen(progbuf), ""); - const char *mem_desc = !umemlist? avr_mem_name(p, mem): - ns==1? avr_mem_name(p, umemlist[0]): "multiple memories"; + const char *mem_desc = !umemlist? avr_mem_name(p, mem): ns == 1? avr_mem_name(p, umemlist[0]): "multiple memories"; int rc = 0; + switch(upd->op) { case DEVICE_READ: // Read out the specified device memory and write it to a file @@ -704,6 +699,7 @@ int do_op(const PROGRAMMER *pgm, const AVRPART *p, const UPDATE *upd, enum updat * paged memories to be erased first, so the code goes the full hog. */ int dffo = cx->avr_disableffopt; + cx->avr_disableffopt = 1; if(upd->format != FMT_IHEX && upd->format != FMT_IHXC && upd->format != FMT_SREC && upd->format != FMT_ELF) { pmsg_warning("generating %s file format with multiple memories that cannot\n", fileio_fmtstr(upd->format)); @@ -711,12 +707,15 @@ int do_op(const PROGRAMMER *pgm, const AVRPART *p, const UPDATE *upd, enum updat } pmsg_info("reading %s ...\n", mem_desc); int nn = 0, nbytes = 0; + for(int ii = 0; ii < ns; ii++) { m = umemlist[ii]; const char *m_name = avr_mem_name(p, m); const char *cap = str_ccprintf("%*s - %-*s", (int) strlen(progbuf), "", maxrlen, m_name); + report_progress(0, 1, cap); int ret = avr_read_mem(pgm, p, m, NULL); + report_progress(1, 1, NULL); if(ret < 0) { pmsg_warning("unable to read %s (ret = %d), skipping...\n", m_name, ret); @@ -724,6 +723,7 @@ int do_op(const PROGRAMMER *pgm, const AVRPART *p, const UPDATE *upd, enum updat continue; } unsigned off = fileio_mem_offset(p, m); + if(off == ~0U) { pmsg_warning("cannot map %s to flat address space, skipping ...\n", m_name); rwvproblem = 1; @@ -731,7 +731,7 @@ int do_op(const PROGRAMMER *pgm, const AVRPART *p, const UPDATE *upd, enum updat } if(ret > 0) { // Copy individual memory into multi memory - memcpy(mem->buf+off, m->buf, ret); + memcpy(mem->buf + off, m->buf, ret); seglist[nn].addr = off; seglist[nn].len = ret; nbytes += ret; @@ -739,8 +739,7 @@ int do_op(const PROGRAMMER *pgm, const AVRPART *p, const UPDATE *upd, enum updat } } - pmsg_info("writing %d byte%s to output file %s\n", - nbytes, str_plural(nbytes), str_outfilename(upd->filename)); + pmsg_info("writing %d byte%s to output file %s\n", nbytes, str_plural(nbytes), str_outfilename(upd->filename)); if(nn) rc = fileio_segments(FIO_WRITE, upd->filename, upd->format, p, mem, nn, seglist); else @@ -758,8 +757,7 @@ int do_op(const PROGRAMMER *pgm, const AVRPART *p, const UPDATE *upd, enum updat } if(rc == 0) pmsg_notice("empty memory, resulting file has no contents\n"); - pmsg_info("writing %d byte%s to output file %s\n", - rc, str_plural(rc), str_outfilename(upd->filename)); + pmsg_info("writing %d byte%s to output file %s\n", rc, str_plural(rc), str_outfilename(upd->filename)); rc = fileio_mem(FIO_WRITE, upd->filename, upd->format, p, mem, rc); } @@ -774,18 +772,21 @@ int do_op(const PROGRAMMER *pgm, const AVRPART *p, const UPDATE *upd, enum updat if((allsize = update_all_from_file(upd, pgm, p, mem, mem_desc, &fs)) < 0) goto error; if(umemlist) { - for(int i=0; iprog_modes & PM_SPM) && (mem_is_in_fuses(m) || mem_is_lock(m)))) + if(mem_is_readonly(m) || (is_spm(pgm) && (mem_is_in_fuses(m) || mem_is_lock(m)))) continue; int ret, size = update_mem_from_all(upd, p, m, mem, allsize); + switch(size) { case LIBAVRDUDE_GENERAL_FAILURE: - rwvproblem = 1; break; + rwvproblem = 1; + break; case 0: - rwvsoftfail = 1; break; + rwvsoftfail = 1; + break; default: if((ret = update_avr_write(pgm, p, m, upd, flags, size, 1)) < 0) { pmsg_warning("unable to write %s (ret = %d), skipping...\n", avr_mem_name(p, m), ret); @@ -804,7 +805,7 @@ int do_op(const PROGRAMMER *pgm, const AVRPART *p, const UPDATE *upd, enum updat pmsg_error("unable to write %s (rc = %d)\n", mem_desc, rc); goto error; } - if((flags & UF_VERIFY) && update_avr_verify(pgm, p, mem, upd, fs.lastaddr+1, rcap) < 0) + if((flags & UF_VERIFY) && update_avr_verify(pgm, p, mem, upd, fs.lastaddr + 1, rcap) < 0) goto error; } break; @@ -814,15 +815,18 @@ int do_op(const PROGRAMMER *pgm, const AVRPART *p, const UPDATE *upd, enum updat if((allsize = update_all_from_file(upd, pgm, p, mem, mem_desc, &fs)) < 0) goto error; if(umemlist) { - for(int i=0; ifd, 0); - serial_set_dtr_rts(&pgm->fd, rts_mode == RTS_MODE_LOW ? 1 : 0); + serial_set_dtr_rts(&pgm->fd, rts_mode == RTS_MODE_LOW? 1: 0); } -static int updi_physical_open(PROGRAMMER* pgm, int baudrate, unsigned long cflags) -{ +static int updi_physical_open(PROGRAMMER *pgm, int baudrate, unsigned long cflags) { serial_recv_timeout = 1000; union pinfo pinfo; @@ -58,27 +57,22 @@ static int updi_physical_open(PROGRAMMER* pgm, int baudrate, unsigned long cflag pmsg_debug("opening serial port ...\n"); - if (serial_open(pgm->port, pinfo, &pgm->fd)==-1) { + if(serial_open(pgm->port, pinfo, &pgm->fd) == -1) { pmsg_debug("serial port open failed!\n"); return -1; } - /* - * drain any extraneous input - */ + // Drain any extraneous input serial_drain(&pgm->fd, 0); - /* - * set RTS/DTR mode if needed - */ + // Set RTS/DTR mode if needed updi_set_rtsdtr_mode(pgm); return 0; } -static void updi_physical_close(PROGRAMMER* pgm) -{ +static void updi_physical_close(PROGRAMMER *pgm) { serial_set_dtr_rts(&pgm->fd, 0); serial_close(&pgm->fd); pgm->fd.ifd = -1; @@ -89,9 +83,9 @@ static int updi_physical_send(const PROGRAMMER *pgm, unsigned char *buf, size_t int rv; pmsg_debug("sending %lu bytes [", (unsigned long) len); - for (i=0; ifd, buf, len); - if (rv < 0) { + if(rv < 0) { pmsg_debug("%s(): programmer is not responding\n", __func__); return -1; } pmsg_debug("received %lu bytes [", (unsigned long) len); - for (i=0; ifd, 300, SERIAL_8E1) < 0) { + if(serial_setparams(&pgm->fd, 300, SERIAL_8E1) < 0) { return -1; } @@ -149,15 +143,13 @@ static int updi_physical_send_double_break(const PROGRAMMER *pgm) { serial_drain(&pgm->fd, 0); - if (serial_setparams(&pgm->fd, pgm->baudrate? pgm->baudrate: 115200, SERIAL_8E2) < 0) { + if(serial_setparams(&pgm->fd, pgm->baudrate? pgm->baudrate: 115200, SERIAL_8E2) < 0) { return -1; } updi_set_rtsdtr_mode(pgm); - /* - * drain any extraneous input - */ + // Drain any extraneous input serial_drain(&pgm->fd, 0); return 0; @@ -179,7 +171,7 @@ int updi_physical_sib(const PROGRAMMER *pgm, unsigned char *buffer, uint8_t size send_buffer[0] = UPDI_PHY_SYNC; send_buffer[1] = UPDI_KEY | UPDI_KEY_SIB | UPDI_SIB_32BYTES; - if (updi_physical_send(pgm, send_buffer, 2) < 0) { + if(updi_physical_send(pgm, send_buffer, 2) < 0) { pmsg_debug("SIB request send failed\n"); return -1; } @@ -187,14 +179,14 @@ int updi_physical_sib(const PROGRAMMER *pgm, unsigned char *buffer, uint8_t size return updi_physical_recv(pgm, buffer, size); } -int updi_link_open(PROGRAMMER *pgm) { +int updi_link_open(PROGRAMMER *pgm) { unsigned char init_buffer[1]; - if (updi_physical_open(pgm, pgm->baudrate? pgm->baudrate: 115200, SERIAL_8E2) < 0) { + if(updi_physical_open(pgm, pgm->baudrate? pgm->baudrate: 115200, SERIAL_8E2) < 0) { return -1; } - init_buffer[0]=UPDI_BREAK; + init_buffer[0] = UPDI_BREAK; return updi_physical_send(pgm, init_buffer, 1); } @@ -202,7 +194,7 @@ void updi_link_close(PROGRAMMER *pgm) { updi_physical_close(pgm); } -static int updi_link_init_session_parameters(const PROGRAMMER *pgm) { +static int updi_link_init_session_parameters(const PROGRAMMER *pgm) { /* def _init_session_parameters(self): """ @@ -211,11 +203,11 @@ static int updi_link_init_session_parameters(const PROGRAMMER *pgm) { self.stcs(constants.UPDI_CS_CTRLB, 1 << constants.UPDI_CTRLB_CCDETDIS_BIT) self.stcs(constants.UPDI_CS_CTRLA, 1 << constants.UPDI_CTRLA_IBDLY_BIT) */ - if (updi_link_stcs(pgm, UPDI_CS_CTRLB, 1 << UPDI_CTRLB_CCDETDIS_BIT) < 0) { + if(updi_link_stcs(pgm, UPDI_CS_CTRLB, 1 << UPDI_CTRLB_CCDETDIS_BIT) < 0) { return -1; } - if (updi_link_stcs(pgm, UPDI_CS_CTRLA, 1 << UPDI_CTRLA_IBDLY_BIT) < 0) { + if(updi_link_stcs(pgm, UPDI_CS_CTRLA, 1 << UPDI_CTRLA_IBDLY_BIT) < 0) { return -1; } @@ -240,12 +232,13 @@ static int updi_link_check(const PROGRAMMER *pgm) { */ int result; uint8_t value; + result = updi_link_ldcs(pgm, UPDI_CS_STATUSA, &value); - if (result < 0) { + if(result < 0) { pmsg_debug("check failed\n"); return -1; } else { - if (value > 0) { + if(value > 0) { pmsg_debug("UDPI init OK\n"); return 0; } else { @@ -255,7 +248,6 @@ static int updi_link_check(const PROGRAMMER *pgm) { } } - int updi_link_init(const PROGRAMMER *pgm) { /* def init_datalink(self): @@ -271,22 +263,22 @@ int updi_link_init(const PROGRAMMER *pgm) { if not self._check_datalink(): raise PymcuprogError("UPDI initialisation failed") */ - if (updi_link_init_session_parameters(pgm) < 0) { + if(updi_link_init_session_parameters(pgm) < 0) { pmsg_debug("session initialisation failed\n"); return -1; } - if (updi_link_check(pgm) < 0) { + if(updi_link_check(pgm) < 0) { pmsg_debug("datalink not active, resetting ...\n"); - if (updi_physical_send_double_break(pgm) < 0) { + if(updi_physical_send_double_break(pgm) < 0) { pmsg_debug("datalink initialisation failed\n"); return -1; } - if (updi_link_init_session_parameters(pgm) < 0) { + if(updi_link_init_session_parameters(pgm) < 0) { pmsg_debug("session initialisation failed\n"); return -1; } - if (updi_link_check(pgm) < 0) { + if(updi_link_check(pgm) < 0) { pmsg_debug("restoring datalink failed\n"); return -1; } @@ -294,7 +286,7 @@ int updi_link_init(const PROGRAMMER *pgm) { return 0; } -int updi_link_ldcs(const PROGRAMMER *pgm, uint8_t address, uint8_t *value) { +int updi_link_ldcs(const PROGRAMMER *pgm, uint8_t address, uint8_t *value) { /* def ldcs(self, address): """ @@ -314,21 +306,22 @@ int updi_link_ldcs(const PROGRAMMER *pgm, uint8_t address, uint8_t *value) { */ unsigned char buffer[2]; int result; + pmsg_debug("LDCS from 0x%02X\n", address); - buffer[0]=UPDI_PHY_SYNC; - buffer[1]=UPDI_LDCS | (address & 0x0F); - if (updi_physical_send(pgm, buffer, 2) < 0) { + buffer[0] = UPDI_PHY_SYNC; + buffer[1] = UPDI_LDCS | (address & 0x0F); + if(updi_physical_send(pgm, buffer, 2) < 0) { pmsg_debug("LDCS send operation failed\n"); return -1; } result = updi_physical_recv(pgm, buffer, 1); - if (result != 1) { - if (result >= 0) { + if(result != 1) { + if(result >= 0) { pmsg_debug("incorrect response size, received %d instead of %d bytes\n", result, 1); } return -1; } - * value = buffer[0]; + *value = buffer[0]; return 0; } @@ -345,6 +338,7 @@ int updi_link_stcs(const PROGRAMMER *pgm, uint8_t address, uint8_t value) { self.updi_phy.send([constants.UPDI_PHY_SYNC, constants.UPDI_STCS | (address & 0x0F), value]) */ unsigned char buffer[3]; + pmsg_debug("STCS 0x%02X to address 0x%02X\n", value, address); buffer[0] = UPDI_PHY_SYNC; buffer[1] = UPDI_STCS | (address & 0x0F); @@ -357,7 +351,7 @@ int updi_link_ld_ptr_inc(const PROGRAMMER *pgm, unsigned char *buffer, uint16_t def ld_ptr_inc(self, size): """ Loads a number of bytes from the pointer location with pointer post-increment - + :param size: number of bytes to load :return: values read """ @@ -367,10 +361,11 @@ int updi_link_ld_ptr_inc(const PROGRAMMER *pgm, unsigned char *buffer, uint16_t return self.updi_phy.receive(size) */ unsigned char send_buffer[2]; + pmsg_debug("LD8 from ptr++\n"); send_buffer[0] = UPDI_PHY_SYNC; send_buffer[1] = UPDI_LD | UPDI_PTR_INC | UPDI_DATA_8; - if (updi_physical_send(pgm, send_buffer, 2) < 0) { + if(updi_physical_send(pgm, send_buffer, 2) < 0) { pmsg_debug("LD_PTR_INC send operation failed\n"); return -1; } @@ -392,10 +387,11 @@ int updi_link_ld_ptr_inc16(const PROGRAMMER *pgm, unsigned char *buffer, uint16_ return self.updi_phy.receive(words << 1) */ unsigned char send_buffer[2]; + pmsg_debug("LD16 from ptr++\n"); send_buffer[0] = UPDI_PHY_SYNC; send_buffer[1] = UPDI_LD | UPDI_PTR_INC | UPDI_DATA_16; - if (updi_physical_send(pgm, send_buffer, 2) < 0) { + if(updi_physical_send(pgm, send_buffer, 2) < 0) { pmsg_debug("LD_PTR_INC send operation failed\n"); return -1; } @@ -431,31 +427,32 @@ int updi_link_st_ptr_inc(const PROGRAMMER *pgm, unsigned char *buffer, uint16_t unsigned char recv_buffer[1]; int response; int num = 1; + pmsg_debug("ST8 to *ptr++\n"); send_buffer[0] = UPDI_PHY_SYNC; send_buffer[1] = UPDI_ST | UPDI_PTR_INC | UPDI_DATA_8; send_buffer[2] = buffer[0]; - if (updi_physical_send(pgm, send_buffer, 3) < 0) { + if(updi_physical_send(pgm, send_buffer, 3) < 0) { pmsg_debug("ST_PTR_INC send operation failed\n"); return -1; } response = updi_physical_recv(pgm, recv_buffer, 1); - if (response != 1 || recv_buffer[0] != UPDI_PHY_ACK) { + if(response != 1 || recv_buffer[0] != UPDI_PHY_ACK) { pmsg_debug("ACK was expected but not received\n"); return -1; } - while (num < size) { - send_buffer[0]=buffer[num]; - if (updi_physical_send(pgm, send_buffer, 1) < 0) { + while(num < size) { + send_buffer[0] = buffer[num]; + if(updi_physical_send(pgm, send_buffer, 1) < 0) { pmsg_debug("ST_PTR_INC data send operation failed\n"); return -1; } response = updi_physical_recv(pgm, recv_buffer, 1); - if (response != 1 || recv_buffer[0] != UPDI_PHY_ACK) { + if(response != 1 || recv_buffer[0] != UPDI_PHY_ACK) { pmsg_debug("data ACK was expected but not received\n"); return -1; } @@ -494,37 +491,38 @@ int updi_link_st_ptr_inc16(const PROGRAMMER *pgm, unsigned char *buffer, uint16_ unsigned char recv_buffer[1]; int response; int num = 2; + pmsg_debug("ST16 to *ptr++\n"); send_buffer[0] = UPDI_PHY_SYNC; send_buffer[1] = UPDI_ST | UPDI_PTR_INC | UPDI_DATA_16; send_buffer[2] = buffer[0]; send_buffer[3] = buffer[1]; - if (updi_physical_send(pgm, send_buffer, 4) < 0) { + if(updi_physical_send(pgm, send_buffer, 4) < 0) { pmsg_debug("ST_PTR_INC16 send operation failed\n"); return -1; } response = updi_physical_recv(pgm, recv_buffer, 1); - if (response != 1 || recv_buffer[0] != UPDI_PHY_ACK) { + if(response != 1 || recv_buffer[0] != UPDI_PHY_ACK) { pmsg_debug("ACK was expected but not received\n"); return -1; } - while (num < words) { - send_buffer[0]=buffer[num]; - send_buffer[1]=buffer[num+1]; - if (updi_physical_send(pgm, send_buffer, 2) < 0) { + while(num < words) { + send_buffer[0] = buffer[num]; + send_buffer[1] = buffer[num + 1]; + if(updi_physical_send(pgm, send_buffer, 2) < 0) { pmsg_debug("ST_PTR_INC data send operation failed\n"); return -1; } response = updi_physical_recv(pgm, recv_buffer, 1); - if (response != 1 || recv_buffer[0] != UPDI_PHY_ACK) { + if(response != 1 || recv_buffer[0] != UPDI_PHY_ACK) { pmsg_debug("data ACK was expected but not received\n"); return -1; } - num+=2; + num += 2; } return 0; @@ -548,12 +546,12 @@ int updi_link_st_ptr_inc16_RSD(const PROGRAMMER *pgm, unsigned char *buffer, uin repnumber= ((len(data) >> 1) -1) data = [*data, *[constants.UPDI_PHY_SYNC, constants.UPDI_STCS | constants.UPDI_CS_CTRLA, 0x06]] - if blocksize == -1 : + if blocksize == -1: # Send whole thing at once stcs + repeat + st + (data + stcs) blocksize = 3 + 3 + 2 + len(data) num = 0 firstpacket = [] - if blocksize < 10 : + if blocksize < 10: # very small block size - we send pair of 2-byte commands first. firstpacket = [*[constants.UPDI_PHY_SYNC, constants.UPDI_STCS | constants.UPDI_CS_CTRLA, 0x0E], *[constants.UPDI_PHY_SYNC, constants.UPDI_REPEAT | constants.UPDI_REPEAT_BYTE, (repnumber & 0xFF)]] @@ -565,7 +563,7 @@ int updi_link_st_ptr_inc16_RSD(const PROGRAMMER *pgm, unsigned char *buffer, uin *[constants.UPDI_PHY_SYNC, constants.UPDI_ST | constants.UPDI_PTR_INC | constants.UPDI_DATA_16], *data[:blocksize - 8]] num = blocksize - 8 - self.updi_phy.send( firstpacket ) + self.updi_phy.send(firstpacket) # if finite block size, this is used. while num < len(data): @@ -573,13 +571,13 @@ int updi_link_st_ptr_inc16_RSD(const PROGRAMMER *pgm, unsigned char *buffer, uin self.updi_phy.send(data_slice) num += len(data_slice) */ - pmsg_debug("ST16 to *ptr++ with RSD, data length: 0x%03X in blocks of: %d\n", words * 2, blocksize); + pmsg_debug("ST16 to *ptr++ with RSD, data length: 0x%03X in blocks of: %d\n", words*2, blocksize); - unsigned int temp_buffer_size = 3 + 3 + 2 + (words * 2) + 3; - unsigned int num=0; - unsigned char* temp_buffer = mmt_malloc(temp_buffer_size); + unsigned int temp_buffer_size = 3 + 3 + 2 + (words*2) + 3; + unsigned int num = 0; + unsigned char *temp_buffer = mmt_malloc(temp_buffer_size); - if (blocksize == -1) { + if(blocksize == -1) { blocksize = temp_buffer_size; } @@ -592,37 +590,37 @@ int updi_link_st_ptr_inc16_RSD(const PROGRAMMER *pgm, unsigned char *buffer, uin temp_buffer[6] = UPDI_PHY_SYNC; temp_buffer[7] = UPDI_ST | UPDI_PTR_INC | UPDI_DATA_16; - memcpy(temp_buffer + 8, buffer, words * 2); + memcpy(temp_buffer + 8, buffer, words*2); - temp_buffer[temp_buffer_size-3] = UPDI_PHY_SYNC; - temp_buffer[temp_buffer_size-2] = UPDI_STCS | UPDI_CS_CTRLA; - temp_buffer[temp_buffer_size-1] = 0x06; + temp_buffer[temp_buffer_size - 3] = UPDI_PHY_SYNC; + temp_buffer[temp_buffer_size - 2] = UPDI_STCS | UPDI_CS_CTRLA; + temp_buffer[temp_buffer_size - 1] = 0x06; - if (blocksize < 10) { - if (updi_physical_send(pgm, temp_buffer, 6) < 0) { + if(blocksize < 10) { + if(updi_physical_send(pgm, temp_buffer, 6) < 0) { pmsg_debug("unable to send first package\n"); mmt_free(temp_buffer); return -1; } num = 6; - } + } - while (num < temp_buffer_size) { + while(num < temp_buffer_size) { int next_package_size; - if (num + blocksize > temp_buffer_size) { + if(num + blocksize > temp_buffer_size) { next_package_size = temp_buffer_size - num; } else { next_package_size = blocksize; } - if (updi_physical_send(pgm, temp_buffer + num, next_package_size) < 0) { + if(updi_physical_send(pgm, temp_buffer + num, next_package_size) < 0) { pmsg_debug("unable to send package\n"); mmt_free(temp_buffer); return -1; } - num+=next_package_size; + num += next_package_size; } mmt_free(temp_buffer); return 0; @@ -645,12 +643,13 @@ int updi_link_repeat(const PROGRAMMER *pgm, uint16_t repeats) { repeats & 0xFF]) */ unsigned char buffer[3]; + pmsg_debug("repeat %d\n", repeats); - if ((repeats - 1) > UPDI_MAX_REPEAT_SIZE) { + if((repeats - 1) > UPDI_MAX_REPEAT_SIZE) { pmsg_debug("invalid repeat count of %d\n", repeats); return -1; } - repeats-=1; + repeats -= 1; buffer[0] = UPDI_PHY_SYNC; buffer[1] = UPDI_REPEAT | UPDI_REPEAT_BYTE; buffer[2] = repeats & 0xFF; @@ -673,7 +672,7 @@ int updi_link_key(const PROGRAMMER *pgm, unsigned char *buffer, uint8_t size_typ def key(self, size, key): """ Write a key - + :param size: size of key (0=64B, 1=128B, 2=256B) :param key: key value """ @@ -686,20 +685,21 @@ int updi_link_key(const PROGRAMMER *pgm, unsigned char *buffer, uint8_t size_typ unsigned char send_buffer[2]; unsigned char reversed_key[256]; int index; + pmsg_debug("UPDI writing key\n"); - if (size != (8 << size_type)) { + if(size != (8 << size_type)) { pmsg_debug("invalid key length\n"); return -1; } send_buffer[0] = UPDI_PHY_SYNC; send_buffer[1] = UPDI_KEY | UPDI_KEY_KEY | size_type; - if (updi_physical_send(pgm, send_buffer, 2) < 0) { + if(updi_physical_send(pgm, send_buffer, 2) < 0) { pmsg_debug("UPDI key send message failed\n"); return -1; } - /* reverse key contents */ - for (index=0; index> 8) & 0xFF; send_buffer[4] = (address >> 16) & 0xFF; - if (updi_physical_send(pgm, send_buffer, updi_get_datalink_mode(pgm) == UPDI_LINK_MODE_24BIT ? 5 : 4) < 0) { + if(updi_physical_send(pgm, send_buffer, updi_get_datalink_mode(pgm) == UPDI_LINK_MODE_24BIT? 5: 4) < 0) { pmsg_debug("LD operation send failed\n"); return -1; } - if (updi_physical_recv(pgm, recv_buffer, 1) < 0) { + if(updi_physical_recv(pgm, recv_buffer, 1) < 0) { pmsg_debug("LD operation recv failed\n"); return -1; } - * value = recv_buffer[0]; + *value = recv_buffer[0]; return 0; } @@ -756,21 +758,23 @@ int updi_link_ld16(const PROGRAMMER *pgm, uint32_t address, uint16_t *value) { */ unsigned char send_buffer[5]; unsigned char recv_buffer[2]; + pmsg_debug("LD16 from 0x%06X\n", address); send_buffer[0] = UPDI_PHY_SYNC; - send_buffer[1] = UPDI_LDS | UPDI_DATA_16 | (updi_get_datalink_mode(pgm) == UPDI_LINK_MODE_24BIT ? UPDI_ADDRESS_24 : UPDI_ADDRESS_16); + send_buffer[1] = + UPDI_LDS | UPDI_DATA_16 | (updi_get_datalink_mode(pgm) == UPDI_LINK_MODE_24BIT? UPDI_ADDRESS_24: UPDI_ADDRESS_16); send_buffer[2] = address & 0xFF; send_buffer[3] = (address >> 8) & 0xFF; send_buffer[4] = (address >> 16) & 0xFF; - if (updi_physical_send(pgm, send_buffer, updi_get_datalink_mode(pgm) == UPDI_LINK_MODE_24BIT ? 5 : 4) < 0) { + if(updi_physical_send(pgm, send_buffer, updi_get_datalink_mode(pgm) == UPDI_LINK_MODE_24BIT? 5: 4) < 0) { pmsg_debug("LD16 operation send failed\n"); return -1; } - if (updi_physical_recv(pgm, recv_buffer, 2) < 0) { + if(updi_physical_recv(pgm, recv_buffer, 2) < 0) { pmsg_debug("LD16 operation recv failed\n"); return -1; } - * value = (recv_buffer[0] << 8 | recv_buffer[1]); + *value = (recv_buffer[0] << 8 | recv_buffer[1]); return 0; } @@ -794,23 +798,24 @@ static int updi_link_st_data_phase(const PROGRAMMER *pgm, unsigned char *buffer, raise PymcuprogError("Error with st") */ unsigned char recv_buffer[1]; - if (updi_physical_recv(pgm, recv_buffer, 1) < 0) { + + if(updi_physical_recv(pgm, recv_buffer, 1) < 0) { pmsg_debug("UPDI data phase recv failed on first ACK\n"); return -1; } - if (recv_buffer[0] != UPDI_PHY_ACK) { + if(recv_buffer[0] != UPDI_PHY_ACK) { pmsg_debug("UPDI data phase expected first ACK\n"); return -1; } - if (updi_physical_send(pgm, buffer, size) < 0) { + if(updi_physical_send(pgm, buffer, size) < 0) { pmsg_debug("UPDI data phase send failed\n"); return -1; } - if (updi_physical_recv(pgm, recv_buffer, 1) < 0) { + if(updi_physical_recv(pgm, recv_buffer, 1) < 0) { pmsg_debug("UPDI data phase recv failed on second ACK\n"); return -1; } - if (recv_buffer[0] != UPDI_PHY_ACK) { + if(recv_buffer[0] != UPDI_PHY_ACK) { pmsg_debug("UPDI data phase expected second ACK\n"); return -1; } @@ -833,13 +838,15 @@ int updi_link_st(const PROGRAMMER *pgm, uint32_t address, uint8_t value) { return self._st_data_phase([value & 0xFF]) */ unsigned char send_buffer[5]; + pmsg_debug("ST to 0x%06X\n", address); send_buffer[0] = UPDI_PHY_SYNC; - send_buffer[1] = UPDI_STS | UPDI_DATA_8 | (updi_get_datalink_mode(pgm) == UPDI_LINK_MODE_24BIT ? UPDI_ADDRESS_24 : UPDI_ADDRESS_16); + send_buffer[1] = + UPDI_STS | UPDI_DATA_8 | (updi_get_datalink_mode(pgm) == UPDI_LINK_MODE_24BIT? UPDI_ADDRESS_24: UPDI_ADDRESS_16); send_buffer[2] = address & 0xFF; send_buffer[3] = (address >> 8) & 0xFF; send_buffer[4] = (address >> 16) & 0xFF; - if (updi_physical_send(pgm, send_buffer, updi_get_datalink_mode(pgm) == UPDI_LINK_MODE_24BIT ? 5 : 4) < 0) { + if(updi_physical_send(pgm, send_buffer, updi_get_datalink_mode(pgm) == UPDI_LINK_MODE_24BIT? 5: 4) < 0) { pmsg_debug("ST operation send failed\n"); return -1; } @@ -863,13 +870,15 @@ int updi_link_st16(const PROGRAMMER *pgm, uint32_t address, uint16_t value) { return self._st_data_phase([value & 0xFF, (value >> 8) & 0xFF]) */ unsigned char send_buffer[5]; + pmsg_debug("ST16 to 0x%06X\n", address); send_buffer[0] = UPDI_PHY_SYNC; - send_buffer[1] = UPDI_STS | UPDI_DATA_16 | (updi_get_datalink_mode(pgm) == UPDI_LINK_MODE_24BIT ? UPDI_ADDRESS_24 : UPDI_ADDRESS_16); + send_buffer[1] = + UPDI_STS | UPDI_DATA_16 | (updi_get_datalink_mode(pgm) == UPDI_LINK_MODE_24BIT? UPDI_ADDRESS_24: UPDI_ADDRESS_16); send_buffer[2] = address & 0xFF; send_buffer[3] = (address >> 8) & 0xFF; send_buffer[4] = (address >> 16) & 0xFF; - if (updi_physical_send(pgm, send_buffer, updi_get_datalink_mode(pgm) == UPDI_LINK_MODE_24BIT ? 5 : 4) < 0) { + if(updi_physical_send(pgm, send_buffer, updi_get_datalink_mode(pgm) == UPDI_LINK_MODE_24BIT? 5: 4) < 0) { pmsg_debug("ST16 operation send failed\n"); return -1; } @@ -896,21 +905,23 @@ int updi_link_st_ptr(const PROGRAMMER *pgm, uint32_t address) { */ unsigned char send_buffer[5]; unsigned char recv_buffer[1]; + pmsg_debug("ST_PTR to 0x%06X\n", address); send_buffer[0] = UPDI_PHY_SYNC; - send_buffer[1] = UPDI_STS | UPDI_ST | UPDI_PTR_ADDRESS | (updi_get_datalink_mode(pgm) == UPDI_LINK_MODE_24BIT ? UPDI_DATA_24 : UPDI_DATA_16); + send_buffer[1] = UPDI_STS | UPDI_ST | UPDI_PTR_ADDRESS | + (updi_get_datalink_mode(pgm) == UPDI_LINK_MODE_24BIT? UPDI_DATA_24: UPDI_DATA_16); send_buffer[2] = address & 0xFF; send_buffer[3] = (address >> 8) & 0xFF; send_buffer[4] = (address >> 16) & 0xFF; - if (updi_physical_send(pgm, send_buffer, updi_get_datalink_mode(pgm) == UPDI_LINK_MODE_24BIT ? 5 : 4) < 0) { + if(updi_physical_send(pgm, send_buffer, updi_get_datalink_mode(pgm) == UPDI_LINK_MODE_24BIT? 5: 4) < 0) { pmsg_debug("ST_PTR operation send failed\n"); return -1; } - if (updi_physical_recv(pgm, recv_buffer, 1) < 0) { + if(updi_physical_recv(pgm, recv_buffer, 1) < 0) { pmsg_debug("UPDI ST_PTR recv failed on ACK\n"); return -1; } - if (recv_buffer[0] != UPDI_PHY_ACK) { + if(recv_buffer[0] != UPDI_PHY_ACK) { pmsg_debug("UPDI ST_PTR expected ACK\n"); return -1; } diff --git a/src/updi_link.h b/src/updi_link.h index 2e16ba0e4..9b43a3f48 100644 --- a/src/updi_link.h +++ b/src/updi_link.h @@ -31,27 +31,27 @@ extern "C" { #endif -int updi_link_open(PROGRAMMER * pgm); -void updi_link_close(PROGRAMMER * pgm); -int updi_link_init(const PROGRAMMER *pgm); -int updi_link_ldcs(const PROGRAMMER *pgm, uint8_t address, uint8_t *value); -int updi_link_stcs(const PROGRAMMER *pgm, uint8_t address, uint8_t value); -int updi_link_ld_ptr_inc(const PROGRAMMER *pgm, unsigned char *buffer, uint16_t size); -int updi_link_ld_ptr_inc16(const PROGRAMMER *pgm, unsigned char *buffer, uint16_t words); -int updi_link_st_ptr_inc(const PROGRAMMER *pgm, unsigned char *buffer, uint16_t size); -int updi_link_st_ptr_inc16(const PROGRAMMER *pgm, unsigned char *buffer, uint16_t words); -int updi_link_st_ptr_inc16_RSD(const PROGRAMMER *pgm, unsigned char *buffer, uint16_t words, int blocksize); -int updi_link_repeat(const PROGRAMMER *pgm, uint16_t repeats); -int updi_link_read_sib(const PROGRAMMER *pgm, unsigned char *buffer, uint16_t size); -int updi_link_key(const PROGRAMMER *pgm, unsigned char *buffer, uint8_t size_type, uint16_t size); -int updi_link_ld(const PROGRAMMER *pgm, uint32_t address, uint8_t *value); -int updi_link_ld16(const PROGRAMMER *pgm, uint32_t address, uint16_t *value); -int updi_link_st(const PROGRAMMER *pgm, uint32_t address, uint8_t value); -int updi_link_st16(const PROGRAMMER *pgm, uint32_t address, uint16_t value); -int updi_link_st_ptr(const PROGRAMMER *pgm, uint32_t address); + int updi_link_open(PROGRAMMER *pgm); + void updi_link_close(PROGRAMMER *pgm); + int updi_link_init(const PROGRAMMER *pgm); + int updi_link_ldcs(const PROGRAMMER *pgm, uint8_t address, uint8_t *value); + int updi_link_stcs(const PROGRAMMER *pgm, uint8_t address, uint8_t value); + int updi_link_ld_ptr_inc(const PROGRAMMER *pgm, unsigned char *buffer, uint16_t size); + int updi_link_ld_ptr_inc16(const PROGRAMMER *pgm, unsigned char *buffer, uint16_t words); + int updi_link_st_ptr_inc(const PROGRAMMER *pgm, unsigned char *buffer, uint16_t size); + int updi_link_st_ptr_inc16(const PROGRAMMER *pgm, unsigned char *buffer, uint16_t words); + int updi_link_st_ptr_inc16_RSD(const PROGRAMMER *pgm, unsigned char *buffer, uint16_t words, int blocksize); + int updi_link_repeat(const PROGRAMMER *pgm, uint16_t repeats); + int updi_link_read_sib(const PROGRAMMER *pgm, unsigned char *buffer, uint16_t size); + int updi_link_key(const PROGRAMMER *pgm, unsigned char *buffer, uint8_t size_type, uint16_t size); + int updi_link_ld(const PROGRAMMER *pgm, uint32_t address, uint8_t *value); + int updi_link_ld16(const PROGRAMMER *pgm, uint32_t address, uint16_t *value); + int updi_link_st(const PROGRAMMER *pgm, uint32_t address, uint8_t value); + int updi_link_st16(const PROGRAMMER *pgm, uint32_t address, uint16_t value); + int updi_link_st_ptr(const PROGRAMMER *pgm, uint32_t address); #ifdef __cplusplus } #endif -#endif /* updi_link_h */ +#endif diff --git a/src/updi_nvm.c b/src/updi_nvm.c index 683a7bea5..749c34364 100644 --- a/src/updi_nvm.c +++ b/src/updi_nvm.c @@ -42,210 +42,207 @@ #include "updi_state.h" int updi_nvm_chip_erase(const PROGRAMMER *pgm, const AVRPART *p) { - switch(updi_get_nvm_mode(pgm)) - { - case UPDI_NVM_MODE_V0: - return updi_nvm_chip_erase_V0(pgm, p); - case UPDI_NVM_MODE_V2: - return updi_nvm_chip_erase_V2(pgm, p); - case UPDI_NVM_MODE_V3: - return updi_nvm_chip_erase_V3(pgm, p); - case UPDI_NVM_MODE_V4: - return updi_nvm_chip_erase_V4(pgm, p); - case UPDI_NVM_MODE_V5: - return updi_nvm_chip_erase_V5(pgm, p); - default: - pmsg_error("invalid NVM Mode %d\n", updi_get_nvm_mode(pgm)); - return -1; + switch(updi_get_nvm_mode(pgm)) { + case UPDI_NVM_MODE_V0: + return updi_nvm_chip_erase_V0(pgm, p); + case UPDI_NVM_MODE_V2: + return updi_nvm_chip_erase_V2(pgm, p); + case UPDI_NVM_MODE_V3: + return updi_nvm_chip_erase_V3(pgm, p); + case UPDI_NVM_MODE_V4: + return updi_nvm_chip_erase_V4(pgm, p); + case UPDI_NVM_MODE_V5: + return updi_nvm_chip_erase_V5(pgm, p); + default: + pmsg_error("invalid NVM Mode %d\n", updi_get_nvm_mode(pgm)); + return -1; } } int updi_nvm_erase_flash_page(const PROGRAMMER *pgm, const AVRPART *p, uint32_t address) { - switch(updi_get_nvm_mode(pgm)) - { - case UPDI_NVM_MODE_V0: - return updi_nvm_erase_flash_page_V0(pgm, p, address); - case UPDI_NVM_MODE_V2: - return updi_nvm_erase_flash_page_V2(pgm, p, address); - case UPDI_NVM_MODE_V3: - return updi_nvm_erase_flash_page_V3(pgm, p, address); - case UPDI_NVM_MODE_V4: - return updi_nvm_erase_flash_page_V4(pgm, p, address); - case UPDI_NVM_MODE_V5: - return updi_nvm_erase_flash_page_V5(pgm, p, address); - default: - pmsg_error("invalid NVM Mode %d\n", updi_get_nvm_mode(pgm)); - return -1; + switch(updi_get_nvm_mode(pgm)) { + case UPDI_NVM_MODE_V0: + return updi_nvm_erase_flash_page_V0(pgm, p, address); + case UPDI_NVM_MODE_V2: + return updi_nvm_erase_flash_page_V2(pgm, p, address); + case UPDI_NVM_MODE_V3: + return updi_nvm_erase_flash_page_V3(pgm, p, address); + case UPDI_NVM_MODE_V4: + return updi_nvm_erase_flash_page_V4(pgm, p, address); + case UPDI_NVM_MODE_V5: + return updi_nvm_erase_flash_page_V5(pgm, p, address); + default: + pmsg_error("invalid NVM Mode %d\n", updi_get_nvm_mode(pgm)); + return -1; } } int updi_nvm_erase_eeprom(const PROGRAMMER *pgm, const AVRPART *p) { - switch(updi_get_nvm_mode(pgm)) - { - case UPDI_NVM_MODE_V0: - return updi_nvm_erase_eeprom_V0(pgm, p); - case UPDI_NVM_MODE_V2: - return updi_nvm_erase_eeprom_V2(pgm, p); - case UPDI_NVM_MODE_V3: - return updi_nvm_erase_eeprom_V3(pgm, p); - case UPDI_NVM_MODE_V4: - return updi_nvm_erase_eeprom_V4(pgm, p); - case UPDI_NVM_MODE_V5: - return updi_nvm_erase_eeprom_V5(pgm, p); - default: - pmsg_error("invalid NVM Mode %d\n", updi_get_nvm_mode(pgm)); - return -1; + switch(updi_get_nvm_mode(pgm)) { + case UPDI_NVM_MODE_V0: + return updi_nvm_erase_eeprom_V0(pgm, p); + case UPDI_NVM_MODE_V2: + return updi_nvm_erase_eeprom_V2(pgm, p); + case UPDI_NVM_MODE_V3: + return updi_nvm_erase_eeprom_V3(pgm, p); + case UPDI_NVM_MODE_V4: + return updi_nvm_erase_eeprom_V4(pgm, p); + case UPDI_NVM_MODE_V5: + return updi_nvm_erase_eeprom_V5(pgm, p); + default: + pmsg_error("invalid NVM Mode %d\n", updi_get_nvm_mode(pgm)); + return -1; } } int updi_nvm_erase_user_row(const PROGRAMMER *pgm, const AVRPART *p, uint32_t address, uint16_t size) { - switch(updi_get_nvm_mode(pgm)) - { - case UPDI_NVM_MODE_V0: - return updi_nvm_erase_user_row_V0(pgm, p, address, size); - case UPDI_NVM_MODE_V2: - return updi_nvm_erase_user_row_V2(pgm, p, address, size); - case UPDI_NVM_MODE_V3: - return updi_nvm_erase_user_row_V3(pgm, p, address, size); - case UPDI_NVM_MODE_V4: - return updi_nvm_erase_user_row_V4(pgm, p, address, size); - case UPDI_NVM_MODE_V5: - return updi_nvm_erase_user_row_V5(pgm, p, address, size); - default: - pmsg_error("invalid NVM Mode %d\n", updi_get_nvm_mode(pgm)); - return -1; + switch(updi_get_nvm_mode(pgm)) { + case UPDI_NVM_MODE_V0: + return updi_nvm_erase_user_row_V0(pgm, p, address, size); + case UPDI_NVM_MODE_V2: + return updi_nvm_erase_user_row_V2(pgm, p, address, size); + case UPDI_NVM_MODE_V3: + return updi_nvm_erase_user_row_V3(pgm, p, address, size); + case UPDI_NVM_MODE_V4: + return updi_nvm_erase_user_row_V4(pgm, p, address, size); + case UPDI_NVM_MODE_V5: + return updi_nvm_erase_user_row_V5(pgm, p, address, size); + default: + pmsg_error("invalid NVM Mode %d\n", updi_get_nvm_mode(pgm)); + return -1; } } -int updi_nvm_write_flash(const PROGRAMMER *pgm, const AVRPART *p, uint32_t address, unsigned char *buffer, uint16_t size) { - switch(updi_get_nvm_mode(pgm)) - { - case UPDI_NVM_MODE_V0: - return updi_nvm_write_flash_V0(pgm, p, address, buffer, size); - case UPDI_NVM_MODE_V2: - return updi_nvm_write_flash_V2(pgm, p, address, buffer, size); - case UPDI_NVM_MODE_V3: - return updi_nvm_write_flash_V3(pgm, p, address, buffer, size); - case UPDI_NVM_MODE_V4: - return updi_nvm_write_flash_V4(pgm, p, address, buffer, size); - case UPDI_NVM_MODE_V5: - return updi_nvm_write_flash_V5(pgm, p, address, buffer, size); - default: - pmsg_error("invalid NVM Mode %d\n", updi_get_nvm_mode(pgm)); - return -1; +int updi_nvm_write_flash(const PROGRAMMER *pgm, const AVRPART *p, uint32_t address, + unsigned char *buffer, uint16_t size) { + + switch(updi_get_nvm_mode(pgm)) { + case UPDI_NVM_MODE_V0: + return updi_nvm_write_flash_V0(pgm, p, address, buffer, size); + case UPDI_NVM_MODE_V2: + return updi_nvm_write_flash_V2(pgm, p, address, buffer, size); + case UPDI_NVM_MODE_V3: + return updi_nvm_write_flash_V3(pgm, p, address, buffer, size); + case UPDI_NVM_MODE_V4: + return updi_nvm_write_flash_V4(pgm, p, address, buffer, size); + case UPDI_NVM_MODE_V5: + return updi_nvm_write_flash_V5(pgm, p, address, buffer, size); + default: + pmsg_error("invalid NVM Mode %d\n", updi_get_nvm_mode(pgm)); + return -1; } } -int updi_nvm_write_user_row(const PROGRAMMER *pgm, const AVRPART *p, uint32_t address, unsigned char *buffer, uint16_t size) { - switch(updi_get_nvm_mode(pgm)) - { - case UPDI_NVM_MODE_V0: - return updi_nvm_write_user_row_V0(pgm, p, address, buffer, size); - case UPDI_NVM_MODE_V2: - return updi_nvm_write_user_row_V2(pgm, p, address, buffer, size); - case UPDI_NVM_MODE_V3: - return updi_nvm_write_user_row_V3(pgm, p, address, buffer, size); - case UPDI_NVM_MODE_V4: - return updi_nvm_write_user_row_V4(pgm, p, address, buffer, size); - case UPDI_NVM_MODE_V5: - return updi_nvm_write_user_row_V5(pgm, p, address, buffer, size); - default: - pmsg_error("invalid NVM Mode %d\n", updi_get_nvm_mode(pgm)); - return -1; +int updi_nvm_write_user_row(const PROGRAMMER *pgm, const AVRPART *p, uint32_t address, + unsigned char *buffer, uint16_t size) { + + switch(updi_get_nvm_mode(pgm)) { + case UPDI_NVM_MODE_V0: + return updi_nvm_write_user_row_V0(pgm, p, address, buffer, size); + case UPDI_NVM_MODE_V2: + return updi_nvm_write_user_row_V2(pgm, p, address, buffer, size); + case UPDI_NVM_MODE_V3: + return updi_nvm_write_user_row_V3(pgm, p, address, buffer, size); + case UPDI_NVM_MODE_V4: + return updi_nvm_write_user_row_V4(pgm, p, address, buffer, size); + case UPDI_NVM_MODE_V5: + return updi_nvm_write_user_row_V5(pgm, p, address, buffer, size); + default: + pmsg_error("invalid NVM Mode %d\n", updi_get_nvm_mode(pgm)); + return -1; } } -int updi_nvm_write_boot_row(const PROGRAMMER *pgm, const AVRPART *p, uint32_t address, unsigned char *buffer, uint16_t size) { - switch(updi_get_nvm_mode(pgm)) - { - case UPDI_NVM_MODE_V0: - return updi_nvm_write_boot_row_V0(pgm, p, address, buffer, size); - case UPDI_NVM_MODE_V2: - return updi_nvm_write_boot_row_V2(pgm, p, address, buffer, size); - case UPDI_NVM_MODE_V3: - return updi_nvm_write_boot_row_V3(pgm, p, address, buffer, size); - case UPDI_NVM_MODE_V4: - return updi_nvm_write_boot_row_V4(pgm, p, address, buffer, size); - case UPDI_NVM_MODE_V5: - return updi_nvm_write_boot_row_V5(pgm, p, address, buffer, size); - default: - pmsg_error("invalid NVM Mode %d\n", updi_get_nvm_mode(pgm)); - return -1; +int updi_nvm_write_boot_row(const PROGRAMMER *pgm, const AVRPART *p, uint32_t address, + unsigned char *buffer, uint16_t size) { + + switch(updi_get_nvm_mode(pgm)) { + case UPDI_NVM_MODE_V0: + return updi_nvm_write_boot_row_V0(pgm, p, address, buffer, size); + case UPDI_NVM_MODE_V2: + return updi_nvm_write_boot_row_V2(pgm, p, address, buffer, size); + case UPDI_NVM_MODE_V3: + return updi_nvm_write_boot_row_V3(pgm, p, address, buffer, size); + case UPDI_NVM_MODE_V4: + return updi_nvm_write_boot_row_V4(pgm, p, address, buffer, size); + case UPDI_NVM_MODE_V5: + return updi_nvm_write_boot_row_V5(pgm, p, address, buffer, size); + default: + pmsg_error("invalid NVM Mode %d\n", updi_get_nvm_mode(pgm)); + return -1; } } -int updi_nvm_write_eeprom(const PROGRAMMER *pgm, const AVRPART *p, uint32_t address, unsigned char *buffer, uint16_t size) { - switch(updi_get_nvm_mode(pgm)) - { - case UPDI_NVM_MODE_V0: - return updi_nvm_write_eeprom_V0(pgm, p, address, buffer, size); - case UPDI_NVM_MODE_V2: - return updi_nvm_write_eeprom_V2(pgm, p, address, buffer, size); - case UPDI_NVM_MODE_V3: - return updi_nvm_write_eeprom_V3(pgm, p, address, buffer, size); - case UPDI_NVM_MODE_V4: - return updi_nvm_write_eeprom_V4(pgm, p, address, buffer, size); - case UPDI_NVM_MODE_V5: - return updi_nvm_write_eeprom_V5(pgm, p, address, buffer, size); - default: - pmsg_error("invalid NVM Mode %d\n", updi_get_nvm_mode(pgm)); - return -1; +int updi_nvm_write_eeprom(const PROGRAMMER *pgm, const AVRPART *p, uint32_t address, + unsigned char *buffer, uint16_t size) { + + switch(updi_get_nvm_mode(pgm)) { + case UPDI_NVM_MODE_V0: + return updi_nvm_write_eeprom_V0(pgm, p, address, buffer, size); + case UPDI_NVM_MODE_V2: + return updi_nvm_write_eeprom_V2(pgm, p, address, buffer, size); + case UPDI_NVM_MODE_V3: + return updi_nvm_write_eeprom_V3(pgm, p, address, buffer, size); + case UPDI_NVM_MODE_V4: + return updi_nvm_write_eeprom_V4(pgm, p, address, buffer, size); + case UPDI_NVM_MODE_V5: + return updi_nvm_write_eeprom_V5(pgm, p, address, buffer, size); + default: + pmsg_error("invalid NVM Mode %d\n", updi_get_nvm_mode(pgm)); + return -1; } } int updi_nvm_write_fuse(const PROGRAMMER *pgm, const AVRPART *p, uint32_t address, uint8_t value) { - switch(updi_get_nvm_mode(pgm)) - { - case UPDI_NVM_MODE_V0: - return updi_nvm_write_fuse_V0(pgm, p, address, value); - case UPDI_NVM_MODE_V2: - return updi_nvm_write_fuse_V2(pgm, p, address, value); - case UPDI_NVM_MODE_V3: - return updi_nvm_write_fuse_V3(pgm, p, address, value); - case UPDI_NVM_MODE_V4: - return updi_nvm_write_fuse_V4(pgm, p, address, value); - case UPDI_NVM_MODE_V5: - return updi_nvm_write_fuse_V5(pgm, p, address, value); - default: - pmsg_error("invalid NVM Mode %d\n", updi_get_nvm_mode(pgm)); - return -1; + switch(updi_get_nvm_mode(pgm)) { + case UPDI_NVM_MODE_V0: + return updi_nvm_write_fuse_V0(pgm, p, address, value); + case UPDI_NVM_MODE_V2: + return updi_nvm_write_fuse_V2(pgm, p, address, value); + case UPDI_NVM_MODE_V3: + return updi_nvm_write_fuse_V3(pgm, p, address, value); + case UPDI_NVM_MODE_V4: + return updi_nvm_write_fuse_V4(pgm, p, address, value); + case UPDI_NVM_MODE_V5: + return updi_nvm_write_fuse_V5(pgm, p, address, value); + default: + pmsg_error("invalid NVM Mode %d\n", updi_get_nvm_mode(pgm)); + return -1; } } int updi_nvm_wait_ready(const PROGRAMMER *pgm, const AVRPART *p) { - switch(updi_get_nvm_mode(pgm)) - { - case UPDI_NVM_MODE_V0: - return updi_nvm_wait_ready_V0(pgm, p); - case UPDI_NVM_MODE_V2: - return updi_nvm_wait_ready_V2(pgm, p); - case UPDI_NVM_MODE_V3: - return updi_nvm_wait_ready_V3(pgm, p); - case UPDI_NVM_MODE_V4: - return updi_nvm_wait_ready_V4(pgm, p); - case UPDI_NVM_MODE_V5: - return updi_nvm_wait_ready_V5(pgm, p); - default: - pmsg_error("invalid NVM Mode %d\n", updi_get_nvm_mode(pgm)); - return -1; + switch(updi_get_nvm_mode(pgm)) { + case UPDI_NVM_MODE_V0: + return updi_nvm_wait_ready_V0(pgm, p); + case UPDI_NVM_MODE_V2: + return updi_nvm_wait_ready_V2(pgm, p); + case UPDI_NVM_MODE_V3: + return updi_nvm_wait_ready_V3(pgm, p); + case UPDI_NVM_MODE_V4: + return updi_nvm_wait_ready_V4(pgm, p); + case UPDI_NVM_MODE_V5: + return updi_nvm_wait_ready_V5(pgm, p); + default: + pmsg_error("invalid NVM Mode %d\n", updi_get_nvm_mode(pgm)); + return -1; } } int updi_nvm_command(const PROGRAMMER *pgm, const AVRPART *p, uint8_t command) { - switch(updi_get_nvm_mode(pgm)) - { - case UPDI_NVM_MODE_V0: - return updi_nvm_command_V0(pgm, p, command); - case UPDI_NVM_MODE_V2: - return updi_nvm_command_V2(pgm, p, command); - case UPDI_NVM_MODE_V3: - return updi_nvm_command_V3(pgm, p, command); - case UPDI_NVM_MODE_V4: - return updi_nvm_command_V4(pgm, p, command); - case UPDI_NVM_MODE_V5: - return updi_nvm_command_V5(pgm, p, command); - default: - pmsg_error("invalid NVM Mode %d\n", updi_get_nvm_mode(pgm)); - return -1; + switch(updi_get_nvm_mode(pgm)) { + case UPDI_NVM_MODE_V0: + return updi_nvm_command_V0(pgm, p, command); + case UPDI_NVM_MODE_V2: + return updi_nvm_command_V2(pgm, p, command); + case UPDI_NVM_MODE_V3: + return updi_nvm_command_V3(pgm, p, command); + case UPDI_NVM_MODE_V4: + return updi_nvm_command_V4(pgm, p, command); + case UPDI_NVM_MODE_V5: + return updi_nvm_command_V5(pgm, p, command); + default: + pmsg_error("invalid NVM Mode %d\n", updi_get_nvm_mode(pgm)); + return -1; } } diff --git a/src/updi_nvm.h b/src/updi_nvm.h index 60c42b920..4c0a1d14b 100644 --- a/src/updi_nvm.h +++ b/src/updi_nvm.h @@ -31,20 +31,24 @@ extern "C" { #endif -int updi_nvm_chip_erase(const PROGRAMMER *pgm, const AVRPART *p); -int updi_nvm_erase_flash_page(const PROGRAMMER *pgm, const AVRPART *p, uint32_t address); -int updi_nvm_erase_eeprom(const PROGRAMMER *pgm, const AVRPART *p); -int updi_nvm_erase_user_row(const PROGRAMMER *pgm, const AVRPART *p, uint32_t address, uint16_t size); -int updi_nvm_write_flash(const PROGRAMMER *pgm, const AVRPART *p, uint32_t address, unsigned char *buffer, uint16_t size); -int updi_nvm_write_user_row(const PROGRAMMER *pgm, const AVRPART *p, uint32_t address, unsigned char *buffer, uint16_t size); -int updi_nvm_write_boot_row(const PROGRAMMER *pgm, const AVRPART *p, uint32_t address, unsigned char *buffer, uint16_t size); -int updi_nvm_write_eeprom(const PROGRAMMER *pgm, const AVRPART *p, uint32_t address, unsigned char *buffer, uint16_t size); -int updi_nvm_write_fuse(const PROGRAMMER *pgm, const AVRPART *p, uint32_t address, uint8_t value); -int updi_nvm_wait_ready(const PROGRAMMER *pgm, const AVRPART *p); -int updi_nvm_command(const PROGRAMMER *pgm, const AVRPART *p, uint8_t command); + int updi_nvm_chip_erase(const PROGRAMMER *pgm, const AVRPART *p); + int updi_nvm_erase_flash_page(const PROGRAMMER *pgm, const AVRPART *p, uint32_t address); + int updi_nvm_erase_eeprom(const PROGRAMMER *pgm, const AVRPART *p); + int updi_nvm_erase_user_row(const PROGRAMMER *pgm, const AVRPART *p, uint32_t address, uint16_t size); + int updi_nvm_write_flash(const PROGRAMMER *pgm, const AVRPART *p, uint32_t address, + unsigned char *buffer, uint16_t size); + int updi_nvm_write_user_row(const PROGRAMMER *pgm, const AVRPART *p, uint32_t address, + unsigned char *buffer, uint16_t size); + int updi_nvm_write_boot_row(const PROGRAMMER *pgm, const AVRPART *p, uint32_t address, + unsigned char *buffer, uint16_t size); + int updi_nvm_write_eeprom(const PROGRAMMER *pgm, const AVRPART *p, uint32_t address, + unsigned char *buffer, uint16_t size); + int updi_nvm_write_fuse(const PROGRAMMER *pgm, const AVRPART *p, uint32_t address, uint8_t value); + int updi_nvm_wait_ready(const PROGRAMMER *pgm, const AVRPART *p); + int updi_nvm_command(const PROGRAMMER *pgm, const AVRPART *p, uint8_t command); #ifdef __cplusplus } #endif -#endif /* updi_nvm_h */ +#endif diff --git a/src/updi_nvm_v0.c b/src/updi_nvm_v0.c index 647582702..9744bb671 100644 --- a/src/updi_nvm_v0.c +++ b/src/updi_nvm_v0.c @@ -66,13 +66,11 @@ #define USE_DEFAULT_COMMAND 0xFF -typedef enum -{ +typedef enum { DONT_USE_WORD_ACCESS, USE_WORD_ACCESS } access_mode; - int updi_nvm_chip_erase_V0(const PROGRAMMER *pgm, const AVRPART *p) { /* def chip_erase(self): @@ -98,15 +96,15 @@ int updi_nvm_chip_erase_V0(const PROGRAMMER *pgm, const AVRPART *p) { return True */ pmsg_debug("chip erase using NVM CTRL\n"); - if (updi_nvm_wait_ready_V0(pgm, p) < 0) { + if(updi_nvm_wait_ready_V0(pgm, p) < 0) { pmsg_error("updi_nvm_wait_ready_V0() failed\n"); return -1; } - if (updi_nvm_command_V0(pgm, p, UPDI_V0_NVMCTRL_CTRLA_CHIP_ERASE) < 0) { + if(updi_nvm_command_V0(pgm, p, UPDI_V0_NVMCTRL_CTRLA_CHIP_ERASE) < 0) { pmsg_error("UPDI chip erase command failed\n"); return -1; } - if (updi_nvm_wait_ready_V0(pgm, p) < 0) { + if(updi_nvm_wait_ready_V0(pgm, p) < 0) { pmsg_error("updi_nvm_wait_ready_V0() failed\n"); return -1; } @@ -139,21 +137,22 @@ int updi_nvm_erase_flash_page_V0(const PROGRAMMER *pgm, const AVRPART *p, uint32 raise IOError("Timeout waiting for NVM controller to be ready after flash page erase") */ unsigned char data[1]; + pmsg_debug("erase flash page at address 0x%06X\n", address); - if (updi_nvm_wait_ready_V0(pgm, p) < 0) { + if(updi_nvm_wait_ready_V0(pgm, p) < 0) { pmsg_error("updi_nvm_wait_ready_V0() failed\n"); return -1; } data[0] = 0xFF; - if (updi_write_data(pgm, address, data, 1) < 0) { + if(updi_write_data(pgm, address, data, 1) < 0) { pmsg_error("dummy write operation failed\n"); return -1; } - if (updi_nvm_command_V0(pgm, p, UPDI_V0_NVMCTRL_CTRLA_ERASE_PAGE) < 0) { + if(updi_nvm_command_V0(pgm, p, UPDI_V0_NVMCTRL_CTRLA_ERASE_PAGE) < 0) { pmsg_error("UPDI flash page erase command failed\n"); return -1; } - if (updi_nvm_wait_ready_V0(pgm, p) < 0) { + if(updi_nvm_wait_ready_V0(pgm, p) < 0) { pmsg_error("updi_nvm_wait_ready_V0() failed\n"); return -1; } @@ -178,17 +177,17 @@ int updi_nvm_erase_eeprom_V0(const PROGRAMMER *pgm, const AVRPART *p) { # And wait for it if not self.wait_nvm_ready(): raise IOError("Timeout waiting for NVM controller to be ready after EEPROM erase") -*/ +*/ pmsg_debug("erase EEPROM\n"); - if (updi_nvm_wait_ready_V0(pgm, p) < 0) { + if(updi_nvm_wait_ready_V0(pgm, p) < 0) { pmsg_error("updi_nvm_wait_ready_V0() failed\n"); return -1; } - if (updi_nvm_command_V0(pgm, p, UPDI_V0_NVMCTRL_CTRLA_ERASE_EEPROM) < 0) { + if(updi_nvm_command_V0(pgm, p, UPDI_V0_NVMCTRL_CTRLA_ERASE_EEPROM) < 0) { pmsg_error("UPDI EEPROM erase command failed\n"); return -1; } - if (updi_nvm_wait_ready_V0(pgm, p) < 0) { + if(updi_nvm_wait_ready_V0(pgm, p) < 0) { pmsg_error("updi_nvm_wait_ready_V0() failed\n"); return -1; } @@ -224,24 +223,24 @@ int updi_nvm_erase_user_row_V0(const PROGRAMMER *pgm, const AVRPART *p, uint32_t */ uint16_t offset; unsigned char data[1]; + pmsg_debug("erase user row\n"); - if (updi_nvm_wait_ready_V0(pgm, p) < 0) { + if(updi_nvm_wait_ready_V0(pgm, p) < 0) { pmsg_error("updi_nvm_wait_ready_V0() failed\n"); return -1; } - data[0]=0xFF; - for (offset = 0; offsetnvm_base + UPDI_V0_NVMCTRL_ADDRL, address & 0xFF) < 0) { + if(updi_write_byte(pgm, p->nvm_base + UPDI_V0_NVMCTRL_ADDRL, address & 0xFF) < 0) { pmsg_error("UPDI write ADDRL operation failed\n"); return -1; } - if (updi_write_byte(pgm, p->nvm_base + UPDI_V0_NVMCTRL_ADDRH, (address >> 8) & 0xFF) < 0) { + if(updi_write_byte(pgm, p->nvm_base + UPDI_V0_NVMCTRL_ADDRH, (address >> 8) & 0xFF) < 0) { pmsg_error("write ADDRH operation failed\n"); return -1; } pmsg_debug("load fuse data\n"); - if (updi_write_byte(pgm, p->nvm_base + UPDI_V0_NVMCTRL_DATAL, value & 0xFF) < 0) { + if(updi_write_byte(pgm, p->nvm_base + UPDI_V0_NVMCTRL_DATAL, value & 0xFF) < 0) { pmsg_error("write DATAL operation failed\n"); return -1; } pmsg_debug("execute fuse write\n"); - if (updi_nvm_command_V0(pgm, p, UPDI_V0_NVMCTRL_CTRLA_WRITE_FUSE) < 0) { + if(updi_nvm_command_V0(pgm, p, UPDI_V0_NVMCTRL_CTRLA_WRITE_FUSE) < 0) { pmsg_error("write fuse operation failed\n"); return -1; } - if (updi_nvm_wait_ready_V0(pgm, p) < 0) { + if(updi_nvm_wait_ready_V0(pgm, p) < 0) { pmsg_error("updi_nvm_wait_ready_V0() failed\n"); return -1; } @@ -363,8 +365,7 @@ int updi_nvm_write_fuse_V0(const PROGRAMMER *pgm, const AVRPART *p, uint32_t add } static int nvm_write_V0(const PROGRAMMER *pgm, const AVRPART *p, uint32_t address, unsigned char *buffer, - uint16_t size, access_mode mode, uint8_t nvm_command) -{ + uint16_t size, access_mode mode, uint8_t nvm_command) { /* def write_nvm(self, address, data, use_word_access, nvmcommand=constants.UPDI_V0_NVMCTRL_CTRLA_WRITE_PAGE): """ @@ -406,39 +407,39 @@ static int nvm_write_V0(const PROGRAMMER *pgm, const AVRPART *p, uint32_t addres if not self.wait_nvm_ready(): raise PymcuprogError("Timeout waiting for NVM controller to be ready after page write") */ - if (updi_nvm_wait_ready_V0(pgm, p) < 0) { + if(updi_nvm_wait_ready_V0(pgm, p) < 0) { pmsg_error("updi_nvm_wait_ready_V0() failed\n"); return -1; } pmsg_debug("clear page buffer\n"); - if (updi_nvm_command_V0(pgm, p, UPDI_V0_NVMCTRL_CTRLA_PAGE_BUFFER_CLR) < 0) { + if(updi_nvm_command_V0(pgm, p, UPDI_V0_NVMCTRL_CTRLA_PAGE_BUFFER_CLR) < 0) { pmsg_error("clear page operation failed\n"); return -1; } - if (updi_nvm_wait_ready_V0(pgm, p) < 0) { + if(updi_nvm_wait_ready_V0(pgm, p) < 0) { pmsg_error("updi_nvm_wait_ready_V0() failed\n"); return -1; } - if (mode == USE_WORD_ACCESS) { - if (updi_write_data_words(pgm, address, buffer, size) < 0) { + if(mode == USE_WORD_ACCESS) { + if(updi_write_data_words(pgm, address, buffer, size) < 0) { pmsg_error("write data words operation failed\n"); return -1; } } else { - if (updi_write_data(pgm, address, buffer, size) < 0) { + if(updi_write_data(pgm, address, buffer, size) < 0) { pmsg_error("write data operation failed\n"); return -1; } } pmsg_debug("committing data\n"); - if (nvm_command == USE_DEFAULT_COMMAND) { + if(nvm_command == USE_DEFAULT_COMMAND) { nvm_command = UPDI_V0_NVMCTRL_CTRLA_WRITE_PAGE; } - if (updi_nvm_command_V0(pgm, p, nvm_command) < 0) { - pmsg_error("commit data command failed\n"); - return -1; + if(updi_nvm_command_V0(pgm, p, nvm_command) < 0) { + pmsg_error("commit data command failed\n"); + return -1; } - if (updi_nvm_wait_ready_V0(pgm, p) < 0) { + if(updi_nvm_wait_ready_V0(pgm, p) < 0) { pmsg_error("updi_nvm_wait_ready_V0() failed\n"); return -1; } @@ -470,20 +471,20 @@ int updi_nvm_wait_ready_V0(const PROGRAMMER *pgm, const AVRPART *p) { unsigned long start_time; unsigned long current_time; uint8_t status; + start_time = avr_ustimestamp(); do { - if (updi_read_byte(pgm, p->nvm_base + UPDI_V0_NVMCTRL_STATUS, &status) >= 0) { - if (status & (1 << UPDI_V0_NVM_STATUS_WRITE_ERROR_BIT)) { + if(updi_read_byte(pgm, p->nvm_base + UPDI_V0_NVMCTRL_STATUS, &status) >= 0) { + if(status & (1 << UPDI_V0_NVM_STATUS_WRITE_ERROR_BIT)) { pmsg_error("unable to write NVM status\n"); return -1; } - if (!(status & ((1 << UPDI_V0_NVM_STATUS_EEPROM_BUSY_BIT) | - (1 << UPDI_V0_NVM_STATUS_FLASH_BUSY_BIT)))) { + if(!(status & ((1 << UPDI_V0_NVM_STATUS_EEPROM_BUSY_BIT) | (1 << UPDI_V0_NVM_STATUS_FLASH_BUSY_BIT)))) { return 0; } } current_time = avr_ustimestamp(); - } while ((current_time - start_time) < 10000000); + } while((current_time - start_time) < 10000000); pmsg_error("wait NVM ready timed out\n"); return -1; diff --git a/src/updi_nvm_v0.h b/src/updi_nvm_v0.h index cda8a6f39..c6cdd09cc 100644 --- a/src/updi_nvm_v0.h +++ b/src/updi_nvm_v0.h @@ -31,20 +31,26 @@ extern "C" { #endif -int updi_nvm_chip_erase_V0(const PROGRAMMER *pgm, const AVRPART *p); -int updi_nvm_erase_flash_page_V0(const PROGRAMMER *pgm, const AVRPART *p, uint32_t address); -int updi_nvm_erase_eeprom_V0(const PROGRAMMER *pgm, const AVRPART *p); -int updi_nvm_erase_user_row_V0(const PROGRAMMER *pgm, const AVRPART *p, uint32_t address, uint16_t size); -int updi_nvm_write_flash_V0(const PROGRAMMER *pgm, const AVRPART *p, uint32_t address, unsigned char *buffer, uint16_t size); -int updi_nvm_write_user_row_V0(const PROGRAMMER *pgm, const AVRPART *p, uint32_t address, unsigned char *buffer, uint16_t size); -int updi_nvm_write_boot_row_V0(const PROGRAMMER *pgm, const AVRPART *p, uint32_t address, unsigned char *buffer, uint16_t size); -int updi_nvm_write_eeprom_V0(const PROGRAMMER *pgm, const AVRPART *p, uint32_t address, unsigned char *buffer, uint16_t size); -int updi_nvm_write_fuse_V0(const PROGRAMMER *pgm, const AVRPART *p, uint32_t address, uint8_t value); -int updi_nvm_wait_ready_V0(const PROGRAMMER *pgm, const AVRPART *p); -int updi_nvm_command_V0(const PROGRAMMER *pgm, const AVRPART *p, uint8_t command); + int updi_nvm_chip_erase_V0(const PROGRAMMER *pgm, const AVRPART *p); + int updi_nvm_erase_flash_page_V0(const PROGRAMMER *pgm, const AVRPART *p, uint32_t address); + int updi_nvm_erase_eeprom_V0(const PROGRAMMER *pgm, const AVRPART *p); + int updi_nvm_erase_user_row_V0(const PROGRAMMER *pgm, const AVRPART *p, uint32_t address, + uint16_t size); + int updi_nvm_write_flash_V0(const PROGRAMMER *pgm, const AVRPART *p, uint32_t address, + unsigned char *buffer, uint16_t size); + int updi_nvm_write_user_row_V0(const PROGRAMMER *pgm, const AVRPART *p, uint32_t address, + unsigned char *buffer, uint16_t size); + int updi_nvm_write_boot_row_V0(const PROGRAMMER *pgm, const AVRPART *p, uint32_t address, + unsigned char *buffer, uint16_t size); + int updi_nvm_write_eeprom_V0(const PROGRAMMER *pgm, const AVRPART *p, uint32_t address, + unsigned char *buffer, uint16_t size); + int updi_nvm_write_fuse_V0(const PROGRAMMER *pgm, const AVRPART *p, uint32_t address, + uint8_t value); + int updi_nvm_wait_ready_V0(const PROGRAMMER *pgm, const AVRPART *p); + int updi_nvm_command_V0(const PROGRAMMER *pgm, const AVRPART *p, uint8_t command); #ifdef __cplusplus } #endif -#endif /* updi_nvm_v0_h */ +#endif diff --git a/src/updi_nvm_v2.c b/src/updi_nvm_v2.c index 136a06c32..a74dfd833 100644 --- a/src/updi_nvm_v2.c +++ b/src/updi_nvm_v2.c @@ -70,8 +70,7 @@ #define USE_DEFAULT_COMMAND 0xFF -typedef enum -{ +typedef enum { DONT_USE_WORD_ACCESS, USE_WORD_ACCESS } access_mode; @@ -103,22 +102,23 @@ int updi_nvm_chip_erase_V2(const PROGRAMMER *pgm, const AVRPART *p) { raise PymcuprogSerialUpdiNvmTimeout("Timeout waiting for NVM controller to be ready after chip erase") */ int status; + pmsg_debug("chip erase using NVM CTRL\n"); - if (updi_nvm_wait_ready_V2(pgm, p) < 0) { + if(updi_nvm_wait_ready_V2(pgm, p) < 0) { pmsg_error("updi_nvm_wait_ready_V2() failed\n"); return -1; } - if (updi_nvm_command_V2(pgm, p, UPDI_V2_NVMCTRL_CTRLA_CHIP_ERASE) < 0) { + if(updi_nvm_command_V2(pgm, p, UPDI_V2_NVMCTRL_CTRLA_CHIP_ERASE) < 0) { pmsg_error("chip erase command failed\n"); return -1; } - status = updi_nvm_wait_ready_V2(pgm, p); + status = updi_nvm_wait_ready_V2(pgm, p); pmsg_debug("clear NVM command\n"); - if (updi_nvm_command_V2(pgm, p, UPDI_V2_NVMCTRL_CTRLA_NOCMD) < 0) { + if(updi_nvm_command_V2(pgm, p, UPDI_V2_NVMCTRL_CTRLA_NOCMD) < 0) { pmsg_error("command buffer erase failed\n"); return -1; } - if (status < 0) { + if(status < 0) { pmsg_error("updi_nvm_wait_ready_V2() failed\n"); return -1; } @@ -157,27 +157,28 @@ int updi_nvm_erase_flash_page_V2(const PROGRAMMER *pgm, const AVRPART *p, uint32 */ unsigned char data[1]; int status; + pmsg_debug("erase flash page at address 0x%08X\n", address); - if (updi_nvm_wait_ready_V2(pgm, p) < 0) { + if(updi_nvm_wait_ready_V2(pgm, p) < 0) { pmsg_error("updi_nvm_wait_ready_V2() failed\n"); return -1; } - if (updi_nvm_command_V2(pgm, p, UPDI_V2_NVMCTRL_CTRLA_FLASH_PAGE_ERASE) < 0) { + if(updi_nvm_command_V2(pgm, p, UPDI_V2_NVMCTRL_CTRLA_FLASH_PAGE_ERASE) < 0) { pmsg_error("flash page erase command failed\n"); return -1; } data[0] = 0xFF; - if (updi_write_data(pgm, address, data, 1) < 0) { + if(updi_write_data(pgm, address, data, 1) < 0) { pmsg_error("dummy write operation failed\n"); return -1; } - status = updi_nvm_wait_ready_V2(pgm, p); + status = updi_nvm_wait_ready_V2(pgm, p); pmsg_debug("clear NVM command\n"); - if (updi_nvm_command_V2(pgm, p, UPDI_V2_NVMCTRL_CTRLA_NOCMD) < 0) { + if(updi_nvm_command_V2(pgm, p, UPDI_V2_NVMCTRL_CTRLA_NOCMD) < 0) { pmsg_error("command buffer erase failed\n"); return -1; } - if (status < 0) { + if(status < 0) { pmsg_error("updi_nvm_wait_ready_V2() failed\n"); return -1; } @@ -209,22 +210,23 @@ int updi_nvm_erase_eeprom_V2(const PROGRAMMER *pgm, const AVRPART *p) { raise PymcuprogSerialUpdiNvmTimeout("Timeout waiting for NVM controller to be ready after EEPROM erase") */ int status; + pmsg_debug("erase EEPROM\n"); - if (updi_nvm_wait_ready_V2(pgm, p) < 0) { + if(updi_nvm_wait_ready_V2(pgm, p) < 0) { pmsg_error("updi_nvm_wait_ready_V2() failed\n"); return -1; } - if (updi_nvm_command_V2(pgm, p, UPDI_V2_NVMCTRL_CTRLA_EEPROM_ERASE) < 0) { + if(updi_nvm_command_V2(pgm, p, UPDI_V2_NVMCTRL_CTRLA_EEPROM_ERASE) < 0) { pmsg_error("EEPROM erase command failed\n"); return -1; } - status = updi_nvm_wait_ready_V2(pgm, p); + status = updi_nvm_wait_ready_V2(pgm, p); pmsg_debug("clear NVM command\n"); - if (updi_nvm_command_V2(pgm, p, UPDI_V2_NVMCTRL_CTRLA_NOCMD) < 0) { + if(updi_nvm_command_V2(pgm, p, UPDI_V2_NVMCTRL_CTRLA_NOCMD) < 0) { pmsg_error("command buffer erase failed\n"); return -1; } - if (status < 0) { + if(status < 0) { pmsg_error("updi_nvm_wait_ready_V2() failed\n"); return -1; } @@ -249,9 +251,10 @@ int updi_nvm_erase_user_row_V2(const PROGRAMMER *pgm, const AVRPART *p, uint32_t } static int nvm_write_V2(const PROGRAMMER *pgm, const AVRPART *p, uint32_t address, unsigned char *buffer, - uint16_t size, access_mode mode); + uint16_t size, access_mode mode); -int updi_nvm_write_flash_V2(const PROGRAMMER *pgm, const AVRPART *p, uint32_t address, unsigned char *buffer, uint16_t size) { +int updi_nvm_write_flash_V2(const PROGRAMMER *pgm, const AVRPART *p, uint32_t address, + unsigned char *buffer, uint16_t size) { /* def write_flash(self, address, data): """ @@ -265,7 +268,8 @@ int updi_nvm_write_flash_V2(const PROGRAMMER *pgm, const AVRPART *p, uint32_t ad return nvm_write_V2(pgm, p, address, buffer, size, USE_WORD_ACCESS); } -int updi_nvm_write_user_row_V2(const PROGRAMMER *pgm, const AVRPART *p, uint32_t address, unsigned char *buffer, uint16_t size) { +int updi_nvm_write_user_row_V2(const PROGRAMMER *pgm, const AVRPART *p, uint32_t address, + unsigned char *buffer, uint16_t size) { /* def write_user_row(self, address, data): """ @@ -280,14 +284,15 @@ int updi_nvm_write_user_row_V2(const PROGRAMMER *pgm, const AVRPART *p, uint32_t return nvm_write_V2(pgm, p, address, buffer, size, DONT_USE_WORD_ACCESS); } -int updi_nvm_write_boot_row_V2(const PROGRAMMER *pgm, const AVRPART *p, uint32_t address, unsigned char *buffer, uint16_t size) { -/* - Perform write operation as if it was regular flash memory -*/ +int updi_nvm_write_boot_row_V2(const PROGRAMMER *pgm, const AVRPART *p, uint32_t address, + unsigned char *buffer, uint16_t size) { + + // Perform write operation as if it was regular flash memory return nvm_write_V2(pgm, p, address, buffer, size, USE_WORD_ACCESS); } -int updi_nvm_write_eeprom_V2(const PROGRAMMER *pgm, const AVRPART *p, uint32_t address, unsigned char *buffer, uint16_t size) { +int updi_nvm_write_eeprom_V2(const PROGRAMMER *pgm, const AVRPART *p, uint32_t address, + unsigned char *buffer, uint16_t size) { /* def write_eeprom(self, address, data): """ @@ -321,26 +326,27 @@ int updi_nvm_write_eeprom_V2(const PROGRAMMER *pgm, const AVRPART *p, uint32_t a raise PymcuprogSerialUpdiNvmTimeout("Timeout waiting for NVM ready after data write") */ int status; - if (updi_nvm_wait_ready_V2(pgm, p) < 0) { + + if(updi_nvm_wait_ready_V2(pgm, p) < 0) { pmsg_error("updi_nvm_wait_ready_V2() failed\n"); return -1; } pmsg_debug("NVM EEPROM erase/write command\n"); - if (updi_nvm_command_V2(pgm, p, UPDI_V2_NVMCTRL_CTRLA_EEPROM_ERASE_WRITE) < 0) { + if(updi_nvm_command_V2(pgm, p, UPDI_V2_NVMCTRL_CTRLA_EEPROM_ERASE_WRITE) < 0) { pmsg_error("EEPROM erase command failed\n"); return -1; } - if (updi_write_data(pgm, address, buffer, size) < 0) { + if(updi_write_data(pgm, address, buffer, size) < 0) { pmsg_error("write data operation failed\n"); return -1; } - status = updi_nvm_wait_ready_V2(pgm, p); + status = updi_nvm_wait_ready_V2(pgm, p); pmsg_debug("clear NVM command\n"); - if (updi_nvm_command_V2(pgm, p, UPDI_V2_NVMCTRL_CTRLA_NOCMD) < 0) { + if(updi_nvm_command_V2(pgm, p, UPDI_V2_NVMCTRL_CTRLA_NOCMD) < 0) { pmsg_error("command buffer erase failed\n"); return -1; } - if (status < 0) { + if(status < 0) { pmsg_error("updi_nvm_wait_ready_V2() failed\n"); return -1; } @@ -360,13 +366,13 @@ int updi_nvm_write_fuse_V2(const PROGRAMMER *pgm, const AVRPART *p, uint32_t add return self.write_eeprom(address, data) */ unsigned char buffer[1]; - buffer[0]=value; + + buffer[0] = value; return updi_nvm_write_eeprom_V2(pgm, p, address, buffer, 1); } static int nvm_write_V2(const PROGRAMMER *pgm, const AVRPART *p, uint32_t address, unsigned char *buffer, - uint16_t size, access_mode mode) -{ + uint16_t size, access_mode mode) { /* def write_nvm(self, address, data, use_word_access=True): """ @@ -409,33 +415,34 @@ static int nvm_write_V2(const PROGRAMMER *pgm, const AVRPART *p, uint32_t addres raise PymcuprogSerialUpdiNvmTimeout("Timeout waiting for NVM controller to be ready after data write") */ int status; - if (updi_nvm_wait_ready_V2(pgm, p) < 0) { + + if(updi_nvm_wait_ready_V2(pgm, p) < 0) { pmsg_error("updi_nvm_wait_ready_V2() failed\n"); return -1; } pmsg_debug("NVM write command\n"); - if (updi_nvm_command_V2(pgm, p, UPDI_V2_NVMCTRL_CTRLA_FLASH_WRITE) < 0) { + if(updi_nvm_command_V2(pgm, p, UPDI_V2_NVMCTRL_CTRLA_FLASH_WRITE) < 0) { pmsg_error("clear page operation failed\n"); return -1; } - if (mode == USE_WORD_ACCESS) { - if (updi_write_data_words(pgm, address, buffer, size) < 0) { + if(mode == USE_WORD_ACCESS) { + if(updi_write_data_words(pgm, address, buffer, size) < 0) { pmsg_error("write data words operation failed\n"); return -1; } } else { - if (updi_write_data(pgm, address, buffer, size) < 0) { + if(updi_write_data(pgm, address, buffer, size) < 0) { pmsg_error("write data operation failed\n"); return -1; } } - status = updi_nvm_wait_ready_V2(pgm, p); + status = updi_nvm_wait_ready_V2(pgm, p); pmsg_debug("clear NVM command\n"); - if (updi_nvm_command_V2(pgm, p, UPDI_V2_NVMCTRL_CTRLA_NOCMD) < 0) { + if(updi_nvm_command_V2(pgm, p, UPDI_V2_NVMCTRL_CTRLA_NOCMD) < 0) { pmsg_error("command buffer erase failed\n"); return -1; } - if (status < 0) { + if(status < 0) { pmsg_error("updi_nvm_wait_ready_V2() failed\n"); return -1; } @@ -472,20 +479,20 @@ int updi_nvm_wait_ready_V2(const PROGRAMMER *pgm, const AVRPART *p) { unsigned long start_time; unsigned long current_time; uint8_t status; + start_time = avr_ustimestamp(); do { - if (updi_read_byte(pgm, p->nvm_base + UPDI_V2_NVMCTRL_STATUS, &status) >= 0) { - if (status & UPDI_V2_NVM_STATUS_WRITE_ERROR_MASK) { + if(updi_read_byte(pgm, p->nvm_base + UPDI_V2_NVMCTRL_STATUS, &status) >= 0) { + if(status & UPDI_V2_NVM_STATUS_WRITE_ERROR_MASK) { pmsg_error("unable to write NVM status, error %d\n", status >> UPDI_V2_NVM_STATUS_WRITE_ERROR_BIT); return -1; } - if (!(status & ((1 << UPDI_V2_NVM_STATUS_EEPROM_BUSY_BIT) | - (1 << UPDI_V2_NVM_STATUS_FLASH_BUSY_BIT)))) { + if(!(status & ((1 << UPDI_V2_NVM_STATUS_EEPROM_BUSY_BIT) | (1 << UPDI_V2_NVM_STATUS_FLASH_BUSY_BIT)))) { return 0; } } current_time = avr_ustimestamp(); - } while ((current_time - start_time) < 10000000); + } while((current_time - start_time) < 10000000); pmsg_error("wait NVM ready timed out\n"); return -1; diff --git a/src/updi_nvm_v2.h b/src/updi_nvm_v2.h index 0daa12631..9daed6163 100644 --- a/src/updi_nvm_v2.h +++ b/src/updi_nvm_v2.h @@ -31,20 +31,26 @@ extern "C" { #endif -int updi_nvm_chip_erase_V2(const PROGRAMMER *pgm, const AVRPART *p); -int updi_nvm_erase_flash_page_V2(const PROGRAMMER *pgm, const AVRPART *p, uint32_t address); -int updi_nvm_erase_eeprom_V2(const PROGRAMMER *pgm, const AVRPART *p); -int updi_nvm_erase_user_row_V2(const PROGRAMMER *pgm, const AVRPART *p, uint32_t address, uint16_t size); -int updi_nvm_write_flash_V2(const PROGRAMMER *pgm, const AVRPART *p, uint32_t address, unsigned char *buffer, uint16_t size); -int updi_nvm_write_user_row_V2(const PROGRAMMER *pgm, const AVRPART *p, uint32_t address, unsigned char *buffer, uint16_t size); -int updi_nvm_write_boot_row_V2(const PROGRAMMER *pgm, const AVRPART *p, uint32_t address, unsigned char *buffer, uint16_t size); -int updi_nvm_write_eeprom_V2(const PROGRAMMER *pgm, const AVRPART *p, uint32_t address, unsigned char *buffer, uint16_t size); -int updi_nvm_write_fuse_V2(const PROGRAMMER *pgm, const AVRPART *p, uint32_t address, uint8_t value); -int updi_nvm_wait_ready_V2(const PROGRAMMER *pgm, const AVRPART *p); -int updi_nvm_command_V2(const PROGRAMMER *pgm, const AVRPART *p, uint8_t command); + int updi_nvm_chip_erase_V2(const PROGRAMMER *pgm, const AVRPART *p); + int updi_nvm_erase_flash_page_V2(const PROGRAMMER *pgm, const AVRPART *p, uint32_t address); + int updi_nvm_erase_eeprom_V2(const PROGRAMMER *pgm, const AVRPART *p); + int updi_nvm_erase_user_row_V2(const PROGRAMMER *pgm, const AVRPART *p, uint32_t address, + uint16_t size); + int updi_nvm_write_flash_V2(const PROGRAMMER *pgm, const AVRPART *p, uint32_t address, + unsigned char *buffer, uint16_t size); + int updi_nvm_write_user_row_V2(const PROGRAMMER *pgm, const AVRPART *p, uint32_t address, + unsigned char *buffer, uint16_t size); + int updi_nvm_write_boot_row_V2(const PROGRAMMER *pgm, const AVRPART *p, uint32_t address, + unsigned char *buffer, uint16_t size); + int updi_nvm_write_eeprom_V2(const PROGRAMMER *pgm, const AVRPART *p, uint32_t address, + unsigned char *buffer, uint16_t size); + int updi_nvm_write_fuse_V2(const PROGRAMMER *pgm, const AVRPART *p, uint32_t address, + uint8_t value); + int updi_nvm_wait_ready_V2(const PROGRAMMER *pgm, const AVRPART *p); + int updi_nvm_command_V2(const PROGRAMMER *pgm, const AVRPART *p, uint8_t command); #ifdef __cplusplus } #endif -#endif /* updi_nvm_v2_h */ +#endif diff --git a/src/updi_nvm_v3.c b/src/updi_nvm_v3.c index 38f0605bc..9929702e4 100644 --- a/src/updi_nvm_v3.c +++ b/src/updi_nvm_v3.c @@ -73,8 +73,7 @@ #define USE_DEFAULT_COMMAND 0xFF -typedef enum -{ +typedef enum { DONT_USE_WORD_ACCESS, USE_WORD_ACCESS } access_mode; @@ -106,34 +105,35 @@ int updi_nvm_chip_erase_V3(const PROGRAMMER *pgm, const AVRPART *p) { raise PymcuprogSerialUpdiNvmTimeout("Timeout waiting for NVM controller to be ready after chip erase") */ int status; + pmsg_debug("chip erase using NVM CTRL\n"); - if (updi_nvm_wait_ready_V3(pgm, p) < 0) { + if(updi_nvm_wait_ready_V3(pgm, p) < 0) { pmsg_error("updi_nvm_wait_ready_V3() failed\n"); return -1; } - if (updi_nvm_command_V3(pgm, p, UPDI_V3_NVMCTRL_CTRLA_CHIP_ERASE) < 0) { + if(updi_nvm_command_V3(pgm, p, UPDI_V3_NVMCTRL_CTRLA_CHIP_ERASE) < 0) { pmsg_error("chip erase command failed\n"); return -1; } status = updi_nvm_wait_ready_V3(pgm, p); - if (updi_nvm_command_V3(pgm, p, UPDI_V3_NVMCTRL_CTRLA_NOCMD) < 0) { + if(updi_nvm_command_V3(pgm, p, UPDI_V3_NVMCTRL_CTRLA_NOCMD) < 0) { pmsg_error("sending empty command failed\n"); return -1; } - if (status < 0) { + if(status < 0) { pmsg_error("updi_nvm_wait_ready_V3() failed\n"); return -1; } - if (updi_nvm_command_V3(pgm, p, UPDI_V3_NVMCTRL_CTRLA_EEPROM_PAGE_BUFFER_CLEAR) < 0) { + if(updi_nvm_command_V3(pgm, p, UPDI_V3_NVMCTRL_CTRLA_EEPROM_PAGE_BUFFER_CLEAR) < 0) { pmsg_error("sending eeprom page buffer clear command failed\n"); return -1; } status = updi_nvm_wait_ready_V3(pgm, p); - if (updi_nvm_command_V3(pgm, p, UPDI_V3_NVMCTRL_CTRLA_NOCMD) < 0) { + if(updi_nvm_command_V3(pgm, p, UPDI_V3_NVMCTRL_CTRLA_NOCMD) < 0) { pmsg_error("sending empty command failed\n"); return -1; } - if (status < 0) { + if(status < 0) { pmsg_error("updi_nvm_wait_ready_V3() failed\n"); return -1; } @@ -169,29 +169,30 @@ int updi_nvm_erase_flash_page_V3(const PROGRAMMER *pgm, const AVRPART *p, uint32 if not status: raise PymcuprogSerialUpdiNvmTimeout("Timeout waiting for NVM controller to be ready after flash page erase") -*/ +*/ int status; unsigned char data[1]; + pmsg_debug("erase flash page at address 0x%06X\n", address); - if (updi_nvm_wait_ready_V3(pgm, p) < 0) { + if(updi_nvm_wait_ready_V3(pgm, p) < 0) { pmsg_error("updi_nvm_wait_ready_V3() failed\n"); return -1; } data[0] = 0xFF; - if (updi_write_data(pgm, address, data, 1) < 0) { + if(updi_write_data(pgm, address, data, 1) < 0) { pmsg_error("dummy write operation failed\n"); return -1; } - if (updi_nvm_command_V3(pgm, p, UPDI_V3_NVMCTRL_CTRLA_FLASH_PAGE_ERASE) < 0) { + if(updi_nvm_command_V3(pgm, p, UPDI_V3_NVMCTRL_CTRLA_FLASH_PAGE_ERASE) < 0) { pmsg_error("flash page erase command failed\n"); return -1; } status = updi_nvm_wait_ready_V3(pgm, p); - if (updi_nvm_command_V3(pgm, p, UPDI_V3_NVMCTRL_CTRLA_NOCMD) < 0) { + if(updi_nvm_command_V3(pgm, p, UPDI_V3_NVMCTRL_CTRLA_NOCMD) < 0) { pmsg_error("sending empty command failed\n"); return -1; } - if (status < 0) { + if(status < 0) { pmsg_error("updi_nvm_wait_ready_V3() failed\n"); return -1; } @@ -223,21 +224,22 @@ int updi_nvm_erase_eeprom_V3(const PROGRAMMER *pgm, const AVRPART *p) { raise IOError("Timeout waiting for NVM controller to be ready after EEPROM erase") */ int status; + pmsg_debug("erase EEPROM\n"); - if (updi_nvm_wait_ready_V3(pgm, p) < 0) { + if(updi_nvm_wait_ready_V3(pgm, p) < 0) { pmsg_error("updi_nvm_wait_ready_V3() failed\n"); return -1; } - if (updi_nvm_command_V3(pgm, p, UPDI_V3_NVMCTRL_CTRLA_EEPROM_ERASE) < 0) { + if(updi_nvm_command_V3(pgm, p, UPDI_V3_NVMCTRL_CTRLA_EEPROM_ERASE) < 0) { pmsg_error("EEPROM erase command failed\n"); return -1; } status = updi_nvm_wait_ready_V3(pgm, p); - if (updi_nvm_command_V3(pgm, p, UPDI_V3_NVMCTRL_CTRLA_NOCMD) < 0) { + if(updi_nvm_command_V3(pgm, p, UPDI_V3_NVMCTRL_CTRLA_NOCMD) < 0) { pmsg_error("sending empty command failed\n"); return -1; } - if (status < 0) { + if(status < 0) { pmsg_error("updi_nvm_wait_ready_V3() failed\n"); return -1; } @@ -259,14 +261,15 @@ int updi_nvm_erase_user_row_V3(const PROGRAMMER *pgm, const AVRPART *p, uint32_t return self.erase_flash_page(self, address) */ pmsg_debug("erase user row at address 0x%06X\n", address); - + return updi_nvm_erase_flash_page_V3(pgm, p, address); } static int nvm_write_V3(const PROGRAMMER *pgm, const AVRPART *p, uint32_t address, unsigned char *buffer, - uint16_t size, access_mode mode, uint8_t nvm_command); + uint16_t size, access_mode mode, uint8_t nvm_command); -int updi_nvm_write_flash_V3(const PROGRAMMER *pgm, const AVRPART *p, uint32_t address, unsigned char *buffer, uint16_t size) { +int updi_nvm_write_flash_V3(const PROGRAMMER *pgm, const AVRPART *p, uint32_t address, + unsigned char *buffer, uint16_t size) { /* def write_flash(self, address, data): """ @@ -280,7 +283,8 @@ int updi_nvm_write_flash_V3(const PROGRAMMER *pgm, const AVRPART *p, uint32_t ad return nvm_write_V3(pgm, p, address, buffer, size, USE_WORD_ACCESS, USE_DEFAULT_COMMAND); } -int updi_nvm_write_user_row_V3(const PROGRAMMER *pgm, const AVRPART *p, uint32_t address, unsigned char *buffer, uint16_t size) { +int updi_nvm_write_user_row_V3(const PROGRAMMER *pgm, const AVRPART *p, uint32_t address, + unsigned char *buffer, uint16_t size) { /* def write_user_row(self, address, data): """ @@ -295,14 +299,14 @@ int updi_nvm_write_user_row_V3(const PROGRAMMER *pgm, const AVRPART *p, uint32_t return nvm_write_V3(pgm, p, address, buffer, size, USE_WORD_ACCESS, USE_DEFAULT_COMMAND); } -int updi_nvm_write_boot_row_V3(const PROGRAMMER *pgm, const AVRPART *p, uint32_t address, unsigned char *buffer, uint16_t size) { -/* - Perform the operation as the regular flash write -*/ +int updi_nvm_write_boot_row_V3(const PROGRAMMER *pgm, const AVRPART *p, uint32_t address, + unsigned char *buffer, uint16_t size) { + // Perform the operation as the regular flash write return nvm_write_V3(pgm, p, address, buffer, size, USE_WORD_ACCESS, USE_DEFAULT_COMMAND); } -int updi_nvm_write_eeprom_V3(const PROGRAMMER *pgm, const AVRPART *p, uint32_t address, unsigned char *buffer, uint16_t size) { +int updi_nvm_write_eeprom_V3(const PROGRAMMER *pgm, const AVRPART *p, uint32_t address, + unsigned char *buffer, uint16_t size) { /* def write_eeprom(self, address, data): """ @@ -314,7 +318,8 @@ int updi_nvm_write_eeprom_V3(const PROGRAMMER *pgm, const AVRPART *p, uint32_t a return self.write_nvm(address, data, use_word_access=False, nvmcommand=constants.UPDI_V3_NVMCTRL_CTRLA_EEPROM_PAGE_ERASE_WRITE) */ - return nvm_write_V3(pgm, p, address, buffer, size, DONT_USE_WORD_ACCESS, UPDI_V3_NVMCTRL_CTRLA_EEPROM_PAGE_ERASE_WRITE); + return nvm_write_V3(pgm, p, address, buffer, size, DONT_USE_WORD_ACCESS, + UPDI_V3_NVMCTRL_CTRLA_EEPROM_PAGE_ERASE_WRITE); } int updi_nvm_write_fuse_V3(const PROGRAMMER *pgm, const AVRPART *p, uint32_t address, uint8_t value) { @@ -329,13 +334,13 @@ int updi_nvm_write_fuse_V3(const PROGRAMMER *pgm, const AVRPART *p, uint32_t add return self.write_eeprom(address, data) */ unsigned char buffer[1]; + buffer[0] = value; return updi_nvm_write_eeprom_V3(pgm, p, address, buffer, 1); } static int nvm_write_V3(const PROGRAMMER *pgm, const AVRPART *p, uint32_t address, unsigned char *buffer, - uint16_t size, access_mode mode, uint8_t nvm_command) -{ + uint16_t size, access_mode mode, uint8_t nvm_command) { /* def write_nvm(self, address, data, use_word_access, nvmcommand=constants.UPDI_V3_NVMCTRL_CTRLA_FLASH_PAGE_WRITE): """ @@ -380,50 +385,49 @@ static int nvm_write_V3(const PROGRAMMER *pgm, const AVRPART *p, uint32_t addres # Remove command self.execute_nvm_command(constants.UPDI_V3_NVMCTRL_CTRLA_NOCMD) */ - if (updi_nvm_wait_ready_V3(pgm, p) < 0) { + if(updi_nvm_wait_ready_V3(pgm, p) < 0) { pmsg_error("updi_nvm_wait_ready_V3() failed\n"); return -1; } pmsg_debug("clear page buffer\n"); - if (updi_nvm_command_V3(pgm, p, UPDI_V3_NVMCTRL_CTRLA_FLASH_PAGE_BUFFER_CLEAR) < 0) { + if(updi_nvm_command_V3(pgm, p, UPDI_V3_NVMCTRL_CTRLA_FLASH_PAGE_BUFFER_CLEAR) < 0) { pmsg_error("clear page operation failed\n"); return -1; } - if (updi_nvm_wait_ready_V3(pgm, p) < 0) { + if(updi_nvm_wait_ready_V3(pgm, p) < 0) { pmsg_error("updi_nvm_wait_ready_V3() failed\n"); return -1; } - if (mode == USE_WORD_ACCESS) { - if (updi_write_data_words(pgm, address, buffer, size) < 0) { + if(mode == USE_WORD_ACCESS) { + if(updi_write_data_words(pgm, address, buffer, size) < 0) { pmsg_error("write data words operation failed\n"); return -1; } } else { - if (updi_write_data(pgm, address, buffer, size) < 0) { + if(updi_write_data(pgm, address, buffer, size) < 0) { pmsg_error("write data operation failed\n"); return -1; } } pmsg_debug("committing data\n"); - if (nvm_command == USE_DEFAULT_COMMAND) { + if(nvm_command == USE_DEFAULT_COMMAND) { nvm_command = UPDI_V3_NVMCTRL_CTRLA_FLASH_PAGE_WRITE; } - if (updi_nvm_command_V3(pgm, p, nvm_command) < 0) { - pmsg_error("commit data command failed\n"); - return -1; + if(updi_nvm_command_V3(pgm, p, nvm_command) < 0) { + pmsg_error("commit data command failed\n"); + return -1; } - if (updi_nvm_wait_ready_V3(pgm, p) < 0) { + if(updi_nvm_wait_ready_V3(pgm, p) < 0) { pmsg_error("updi_nvm_wait_ready_V3() failed\n"); return -1; } - if (updi_nvm_command_V3(pgm, p, UPDI_V3_NVMCTRL_CTRLA_NOCMD) < 0) { + if(updi_nvm_command_V3(pgm, p, UPDI_V3_NVMCTRL_CTRLA_NOCMD) < 0) { pmsg_error("sending empty command failed\n"); return -1; } return 0; } - int updi_nvm_wait_ready_V3(const PROGRAMMER *pgm, const AVRPART *p) { /* def wait_nvm_ready(self, timeout_ms=100): @@ -454,20 +458,20 @@ int updi_nvm_wait_ready_V3(const PROGRAMMER *pgm, const AVRPART *p) { unsigned long start_time; unsigned long current_time; uint8_t status; + start_time = avr_ustimestamp(); do { - if (updi_read_byte(pgm, p->nvm_base + UPDI_V3_NVMCTRL_STATUS, &status) >= 0) { - if (status & UPDI_V3_NVM_STATUS_WRITE_ERROR_MASK) { + if(updi_read_byte(pgm, p->nvm_base + UPDI_V3_NVMCTRL_STATUS, &status) >= 0) { + if(status & UPDI_V3_NVM_STATUS_WRITE_ERROR_MASK) { pmsg_error("unable to write NVM status, error code %d\n", status >> UPDI_V3_NVM_STATUS_WRITE_ERROR_BIT); return -1; } - if (!(status & ((1 << UPDI_V3_NVM_STATUS_EEPROM_BUSY_BIT) | - (1 << UPDI_V3_NVM_STATUS_FLASH_BUSY_BIT)))) { + if(!(status & ((1 << UPDI_V3_NVM_STATUS_EEPROM_BUSY_BIT) | (1 << UPDI_V3_NVM_STATUS_FLASH_BUSY_BIT)))) { return 0; } } current_time = avr_ustimestamp(); - } while ((current_time - start_time) < 10000000); + } while((current_time - start_time) < 10000000); pmsg_error("wait NVM ready timed out\n"); return -1; diff --git a/src/updi_nvm_v3.h b/src/updi_nvm_v3.h index ca0d3e1f9..6dbb8b045 100644 --- a/src/updi_nvm_v3.h +++ b/src/updi_nvm_v3.h @@ -31,20 +31,26 @@ extern "C" { #endif -int updi_nvm_chip_erase_V3(const PROGRAMMER *pgm, const AVRPART *p); -int updi_nvm_erase_flash_page_V3(const PROGRAMMER *pgm, const AVRPART *p, uint32_t address); -int updi_nvm_erase_eeprom_V3(const PROGRAMMER *pgm, const AVRPART *p); -int updi_nvm_erase_user_row_V3(const PROGRAMMER *pgm, const AVRPART *p, uint32_t address, uint16_t size); -int updi_nvm_write_flash_V3(const PROGRAMMER *pgm, const AVRPART *p, uint32_t address, unsigned char *buffer, uint16_t size); -int updi_nvm_write_user_row_V3(const PROGRAMMER *pgm, const AVRPART *p, uint32_t address, unsigned char *buffer, uint16_t size); -int updi_nvm_write_boot_row_V3(const PROGRAMMER *pgm, const AVRPART *p, uint32_t address, unsigned char *buffer, uint16_t size); -int updi_nvm_write_eeprom_V3(const PROGRAMMER *pgm, const AVRPART *p, uint32_t address, unsigned char *buffer, uint16_t size); -int updi_nvm_write_fuse_V3(const PROGRAMMER *pgm, const AVRPART *p, uint32_t address, uint8_t value); -int updi_nvm_wait_ready_V3(const PROGRAMMER *pgm, const AVRPART *p); -int updi_nvm_command_V3(const PROGRAMMER *pgm, const AVRPART *p, uint8_t command); + int updi_nvm_chip_erase_V3(const PROGRAMMER *pgm, const AVRPART *p); + int updi_nvm_erase_flash_page_V3(const PROGRAMMER *pgm, const AVRPART *p, uint32_t address); + int updi_nvm_erase_eeprom_V3(const PROGRAMMER *pgm, const AVRPART *p); + int updi_nvm_erase_user_row_V3(const PROGRAMMER *pgm, const AVRPART *p, uint32_t address, + uint16_t size); + int updi_nvm_write_flash_V3(const PROGRAMMER *pgm, const AVRPART *p, uint32_t address, + unsigned char *buffer, uint16_t size); + int updi_nvm_write_user_row_V3(const PROGRAMMER *pgm, const AVRPART *p, uint32_t address, + unsigned char *buffer, uint16_t size); + int updi_nvm_write_boot_row_V3(const PROGRAMMER *pgm, const AVRPART *p, uint32_t address, + unsigned char *buffer, uint16_t size); + int updi_nvm_write_eeprom_V3(const PROGRAMMER *pgm, const AVRPART *p, uint32_t address, + unsigned char *buffer, uint16_t size); + int updi_nvm_write_fuse_V3(const PROGRAMMER *pgm, const AVRPART *p, uint32_t address, + uint8_t value); + int updi_nvm_wait_ready_V3(const PROGRAMMER *pgm, const AVRPART *p); + int updi_nvm_command_V3(const PROGRAMMER *pgm, const AVRPART *p, uint8_t command); #ifdef __cplusplus } #endif -#endif /* updi_nvm_v3_h */ +#endif diff --git a/src/updi_nvm_v4.c b/src/updi_nvm_v4.c index 67d0901a7..f511f9a11 100644 --- a/src/updi_nvm_v4.c +++ b/src/updi_nvm_v4.c @@ -71,8 +71,7 @@ #define USE_DEFAULT_COMMAND 0xFF -typedef enum -{ +typedef enum { DONT_USE_WORD_ACCESS, USE_WORD_ACCESS } access_mode; @@ -104,22 +103,23 @@ int updi_nvm_chip_erase_V4(const PROGRAMMER *pgm, const AVRPART *p) { raise PymcuprogSerialUpdiNvmTimeout("Timeout waiting for NVM controller to be ready after chip erase") */ int status; + pmsg_debug("chip erase using NVM CTRL\n"); - if (updi_nvm_wait_ready_V4(pgm, p) < 0) { + if(updi_nvm_wait_ready_V4(pgm, p) < 0) { pmsg_error("updi_nvm_wait_ready_V4() failed\n"); return -1; } - if (updi_nvm_command_V4(pgm, p, UPDI_V4_NVMCTRL_CTRLA_CHIP_ERASE) < 0) { + if(updi_nvm_command_V4(pgm, p, UPDI_V4_NVMCTRL_CTRLA_CHIP_ERASE) < 0) { pmsg_error("chip erase command failed\n"); return -1; } - status = updi_nvm_wait_ready_V4(pgm, p); + status = updi_nvm_wait_ready_V4(pgm, p); pmsg_debug("clear NVM command\n"); - if (updi_nvm_command_V4(pgm, p, UPDI_V4_NVMCTRL_CTRLA_NOCMD) < 0) { + if(updi_nvm_command_V4(pgm, p, UPDI_V4_NVMCTRL_CTRLA_NOCMD) < 0) { pmsg_error("command buffer erase failed\n"); return -1; } - if (status < 0) { + if(status < 0) { pmsg_error("updi_nvm_wait_ready_V4() failed\n"); return -1; } @@ -158,27 +158,28 @@ int updi_nvm_erase_flash_page_V4(const PROGRAMMER *pgm, const AVRPART *p, uint32 */ unsigned char data[1]; int status; + pmsg_debug("erase flash page at address 0x%08X\n", address); - if (updi_nvm_wait_ready_V4(pgm, p) < 0) { + if(updi_nvm_wait_ready_V4(pgm, p) < 0) { pmsg_error("updi_nvm_wait_ready_V4() failed\n"); return -1; } - if (updi_nvm_command_V4(pgm, p, UPDI_V4_NVMCTRL_CTRLA_FLASH_PAGE_ERASE) < 0) { + if(updi_nvm_command_V4(pgm, p, UPDI_V4_NVMCTRL_CTRLA_FLASH_PAGE_ERASE) < 0) { pmsg_error("flash page erase command failed\n"); return -1; } data[0] = 0xFF; - if (updi_write_data(pgm, address, data, 1) < 0) { + if(updi_write_data(pgm, address, data, 1) < 0) { pmsg_error("dummy write operation failed\n"); return -1; } - status = updi_nvm_wait_ready_V4(pgm, p); + status = updi_nvm_wait_ready_V4(pgm, p); pmsg_debug("clear NVM command\n"); - if (updi_nvm_command_V4(pgm, p, UPDI_V4_NVMCTRL_CTRLA_NOCMD) < 0) { + if(updi_nvm_command_V4(pgm, p, UPDI_V4_NVMCTRL_CTRLA_NOCMD) < 0) { pmsg_error("command buffer erase failed\n"); return -1; } - if (status < 0) { + if(status < 0) { pmsg_error("updi_nvm_wait_ready_V4() failed\n"); return -1; } @@ -210,22 +211,23 @@ int updi_nvm_erase_eeprom_V4(const PROGRAMMER *pgm, const AVRPART *p) { raise PymcuprogSerialUpdiNvmTimeout("Timeout waiting for NVM controller to be ready after EEPROM erase") */ int status; + pmsg_debug("erase EEPROM\n"); - if (updi_nvm_wait_ready_V4(pgm, p) < 0) { + if(updi_nvm_wait_ready_V4(pgm, p) < 0) { pmsg_error("updi_nvm_wait_ready_V4() failed\n"); return -1; } - if (updi_nvm_command_V4(pgm, p, UPDI_V4_NVMCTRL_CTRLA_EEPROM_ERASE) < 0) { + if(updi_nvm_command_V4(pgm, p, UPDI_V4_NVMCTRL_CTRLA_EEPROM_ERASE) < 0) { pmsg_error("EEPROM erase command failed\n"); return -1; } - status = updi_nvm_wait_ready_V4(pgm, p); + status = updi_nvm_wait_ready_V4(pgm, p); pmsg_debug("clear NVM command\n"); - if (updi_nvm_command_V4(pgm, p, UPDI_V4_NVMCTRL_CTRLA_NOCMD) < 0) { + if(updi_nvm_command_V4(pgm, p, UPDI_V4_NVMCTRL_CTRLA_NOCMD) < 0) { pmsg_error("command buffer erase failed\n"); return -1; } - if (status < 0) { + if(status < 0) { pmsg_error("updi_nvm_wait_ready_V4() failed\n"); return -1; } @@ -249,10 +251,11 @@ int updi_nvm_erase_user_row_V4(const PROGRAMMER *pgm, const AVRPART *p, uint32_t return updi_nvm_erase_flash_page_V4(pgm, p, address); } -static int nvm_write_V4(const PROGRAMMER *pgm, const AVRPART *p, uint32_t address, unsigned char *buffer, - uint16_t size, access_mode mode); +static int nvm_write_V4(const PROGRAMMER *pgm, const AVRPART *p, uint32_t address, + unsigned char *buffer, uint16_t size, access_mode mode); -int updi_nvm_write_flash_V4(const PROGRAMMER *pgm, const AVRPART *p, uint32_t address, unsigned char *buffer, uint16_t size) { +int updi_nvm_write_flash_V4(const PROGRAMMER *pgm, const AVRPART *p, uint32_t address, + unsigned char *buffer, uint16_t size) { /* def write_flash(self, address, data): """ @@ -266,7 +269,8 @@ int updi_nvm_write_flash_V4(const PROGRAMMER *pgm, const AVRPART *p, uint32_t ad return nvm_write_V4(pgm, p, address, buffer, size, USE_WORD_ACCESS); } -int updi_nvm_write_user_row_V4(const PROGRAMMER *pgm, const AVRPART *p, uint32_t address, unsigned char *buffer, uint16_t size) { +int updi_nvm_write_user_row_V4(const PROGRAMMER *pgm, const AVRPART *p, uint32_t address, + unsigned char *buffer, uint16_t size) { /* def write_user_row(self, address, data): """ @@ -281,14 +285,15 @@ int updi_nvm_write_user_row_V4(const PROGRAMMER *pgm, const AVRPART *p, uint32_t return nvm_write_V4(pgm, p, address, buffer, size, DONT_USE_WORD_ACCESS); } -int updi_nvm_write_boot_row_V4(const PROGRAMMER *pgm, const AVRPART *p, uint32_t address, unsigned char *buffer, uint16_t size) { -/* - Write it as a regular flash page -*/ +int updi_nvm_write_boot_row_V4(const PROGRAMMER *pgm, const AVRPART *p, uint32_t address, + unsigned char *buffer, uint16_t size) { + + // Write it as a regular flash page return nvm_write_V4(pgm, p, address, buffer, size, USE_WORD_ACCESS); } -int updi_nvm_write_eeprom_V4(const PROGRAMMER *pgm, const AVRPART *p, uint32_t address, unsigned char *buffer, uint16_t size) { +int updi_nvm_write_eeprom_V4(const PROGRAMMER *pgm, const AVRPART *p, uint32_t address, + unsigned char *buffer, uint16_t size) { /* def write_eeprom(self, address, data): """ @@ -322,26 +327,27 @@ int updi_nvm_write_eeprom_V4(const PROGRAMMER *pgm, const AVRPART *p, uint32_t a raise PymcuprogSerialUpdiNvmTimeout("Timeout waiting for NVM ready after data write") */ int status; - if (updi_nvm_wait_ready_V4(pgm, p) < 0) { + + if(updi_nvm_wait_ready_V4(pgm, p) < 0) { pmsg_error("updi_nvm_wait_ready_V4() failed\n"); return -1; } pmsg_debug("NVM EEPROM erase/write command\n"); - if (updi_nvm_command_V4(pgm, p, UPDI_V4_NVMCTRL_CTRLA_EEPROM_ERASE_WRITE) < 0) { + if(updi_nvm_command_V4(pgm, p, UPDI_V4_NVMCTRL_CTRLA_EEPROM_ERASE_WRITE) < 0) { pmsg_error("EEPROM erase command failed\n"); return -1; } - if (updi_write_data(pgm, address, buffer, size) < 0) { + if(updi_write_data(pgm, address, buffer, size) < 0) { pmsg_error("write data operation failed\n"); return -1; } - status = updi_nvm_wait_ready_V4(pgm, p); + status = updi_nvm_wait_ready_V4(pgm, p); pmsg_debug("clear NVM command\n"); - if (updi_nvm_command_V4(pgm, p, UPDI_V4_NVMCTRL_CTRLA_NOCMD) < 0) { + if(updi_nvm_command_V4(pgm, p, UPDI_V4_NVMCTRL_CTRLA_NOCMD) < 0) { pmsg_error("command buffer erase failed\n"); return -1; } - if (status < 0) { + if(status < 0) { pmsg_error("updi_nvm_wait_ready_V4() failed\n"); return -1; } @@ -361,13 +367,13 @@ int updi_nvm_write_fuse_V4(const PROGRAMMER *pgm, const AVRPART *p, uint32_t add return self.write_eeprom(address, data) */ unsigned char buffer[1]; - buffer[0]=value; + + buffer[0] = value; return updi_nvm_write_eeprom_V4(pgm, p, address, buffer, 1); } static int nvm_write_V4(const PROGRAMMER *pgm, const AVRPART *p, uint32_t address, unsigned char *buffer, - uint16_t size, access_mode mode) -{ + uint16_t size, access_mode mode) { /* def write_nvm(self, address, data, use_word_access=True): """ @@ -410,33 +416,34 @@ static int nvm_write_V4(const PROGRAMMER *pgm, const AVRPART *p, uint32_t addres raise PymcuprogSerialUpdiNvmTimeout("Timeout waiting for NVM controller to be ready after data write") */ int status; - if (updi_nvm_wait_ready_V4(pgm, p) < 0) { + + if(updi_nvm_wait_ready_V4(pgm, p) < 0) { pmsg_error("updi_nvm_wait_ready_V4() failed\n"); return -1; } pmsg_debug("NVM write command\n"); - if (updi_nvm_command_V4(pgm, p, UPDI_V4_NVMCTRL_CTRLA_FLASH_WRITE) < 0) { + if(updi_nvm_command_V4(pgm, p, UPDI_V4_NVMCTRL_CTRLA_FLASH_WRITE) < 0) { pmsg_error("clear page operation failed\n"); return -1; } - if (mode == USE_WORD_ACCESS) { - if (updi_write_data_words(pgm, address, buffer, size) < 0) { + if(mode == USE_WORD_ACCESS) { + if(updi_write_data_words(pgm, address, buffer, size) < 0) { pmsg_error("write data words operation failed\n"); return -1; } } else { - if (updi_write_data(pgm, address, buffer, size) < 0) { + if(updi_write_data(pgm, address, buffer, size) < 0) { pmsg_error("write data operation failed\n"); return -1; } } - status = updi_nvm_wait_ready_V4(pgm, p); + status = updi_nvm_wait_ready_V4(pgm, p); pmsg_debug("clear NVM command\n"); - if (updi_nvm_command_V4(pgm, p, UPDI_V4_NVMCTRL_CTRLA_NOCMD) < 0) { + if(updi_nvm_command_V4(pgm, p, UPDI_V4_NVMCTRL_CTRLA_NOCMD) < 0) { pmsg_error("command buffer erase failed\n"); return -1; } - if (status < 0) { + if(status < 0) { pmsg_error("updi_nvm_wait_ready_V4() failed\n"); return -1; } @@ -473,20 +480,20 @@ int updi_nvm_wait_ready_V4(const PROGRAMMER *pgm, const AVRPART *p) { unsigned long start_time; unsigned long current_time; uint8_t status; + start_time = avr_ustimestamp(); do { - if (updi_read_byte(pgm, p->nvm_base + UPDI_V4_NVMCTRL_STATUS, &status) >= 0) { - if (status & UPDI_V4_NVM_STATUS_WRITE_ERROR_MASK) { + if(updi_read_byte(pgm, p->nvm_base + UPDI_V4_NVMCTRL_STATUS, &status) >= 0) { + if(status & UPDI_V4_NVM_STATUS_WRITE_ERROR_MASK) { pmsg_error("unable to write NVM status, error %d\n", status >> UPDI_V4_NVM_STATUS_WRITE_ERROR_BIT); return -1; } - if (!(status & ((1 << UPDI_V4_NVM_STATUS_EEPROM_BUSY_BIT) | - (1 << UPDI_V4_NVM_STATUS_FLASH_BUSY_BIT)))) { + if(!(status & ((1 << UPDI_V4_NVM_STATUS_EEPROM_BUSY_BIT) | (1 << UPDI_V4_NVM_STATUS_FLASH_BUSY_BIT)))) { return 0; } } current_time = avr_ustimestamp(); - } while ((current_time - start_time) < 10000000); + } while((current_time - start_time) < 10000000); pmsg_error("wait NVM ready timed out\n"); return -1; diff --git a/src/updi_nvm_v4.h b/src/updi_nvm_v4.h index 448c30857..5c7c7287e 100644 --- a/src/updi_nvm_v4.h +++ b/src/updi_nvm_v4.h @@ -31,20 +31,26 @@ extern "C" { #endif -int updi_nvm_chip_erase_V4(const PROGRAMMER *pgm, const AVRPART *p); -int updi_nvm_erase_flash_page_V4(const PROGRAMMER *pgm, const AVRPART *p, uint32_t address); -int updi_nvm_erase_eeprom_V4(const PROGRAMMER *pgm, const AVRPART *p); -int updi_nvm_erase_user_row_V4(const PROGRAMMER *pgm, const AVRPART *p, uint32_t address, uint16_t size); -int updi_nvm_write_flash_V4(const PROGRAMMER *pgm, const AVRPART *p, uint32_t address, unsigned char *buffer, uint16_t size); -int updi_nvm_write_user_row_V4(const PROGRAMMER *pgm, const AVRPART *p, uint32_t address, unsigned char *buffer, uint16_t size); -int updi_nvm_write_boot_row_V4(const PROGRAMMER *pgm, const AVRPART *p, uint32_t address, unsigned char *buffer, uint16_t size); -int updi_nvm_write_eeprom_V4(const PROGRAMMER *pgm, const AVRPART *p, uint32_t address, unsigned char *buffer, uint16_t size); -int updi_nvm_write_fuse_V4(const PROGRAMMER *pgm, const AVRPART *p, uint32_t address, uint8_t value); -int updi_nvm_wait_ready_V4(const PROGRAMMER *pgm, const AVRPART *p); -int updi_nvm_command_V4(const PROGRAMMER *pgm, const AVRPART *p, uint8_t command); + int updi_nvm_chip_erase_V4(const PROGRAMMER *pgm, const AVRPART *p); + int updi_nvm_erase_flash_page_V4(const PROGRAMMER *pgm, const AVRPART *p, uint32_t address); + int updi_nvm_erase_eeprom_V4(const PROGRAMMER *pgm, const AVRPART *p); + int updi_nvm_erase_user_row_V4(const PROGRAMMER *pgm, const AVRPART *p, uint32_t address, + uint16_t size); + int updi_nvm_write_flash_V4(const PROGRAMMER *pgm, const AVRPART *p, uint32_t address, + unsigned char *buffer, uint16_t size); + int updi_nvm_write_user_row_V4(const PROGRAMMER *pgm, const AVRPART *p, uint32_t address, + unsigned char *buffer, uint16_t size); + int updi_nvm_write_boot_row_V4(const PROGRAMMER *pgm, const AVRPART *p, uint32_t address, + unsigned char *buffer, uint16_t size); + int updi_nvm_write_eeprom_V4(const PROGRAMMER *pgm, const AVRPART *p, uint32_t address, + unsigned char *buffer, uint16_t size); + int updi_nvm_write_fuse_V4(const PROGRAMMER *pgm, const AVRPART *p, uint32_t address, + uint8_t value); + int updi_nvm_wait_ready_V4(const PROGRAMMER *pgm, const AVRPART *p); + int updi_nvm_command_V4(const PROGRAMMER *pgm, const AVRPART *p, uint8_t command); #ifdef __cplusplus } #endif -#endif /* updi_nvm_v4_h */ +#endif diff --git a/src/updi_nvm_v5.c b/src/updi_nvm_v5.c index 6a7d04890..d141278d0 100644 --- a/src/updi_nvm_v5.c +++ b/src/updi_nvm_v5.c @@ -74,8 +74,7 @@ #define USE_DEFAULT_COMMAND 0xFF -typedef enum -{ +typedef enum { DONT_USE_WORD_ACCESS, USE_WORD_ACCESS } access_mode; @@ -107,34 +106,35 @@ int updi_nvm_chip_erase_V5(const PROGRAMMER *pgm, const AVRPART *p) { raise PymcuprogSerialUpdiNvmTimeout("Timeout waiting for NVM controller to be ready after chip erase") */ int status; + pmsg_debug("chip erase using NVM CTRL\n"); - if (updi_nvm_wait_ready_V5(pgm, p) < 0) { + if(updi_nvm_wait_ready_V5(pgm, p) < 0) { pmsg_error("updi_nvm_wait_ready_V5() failed\n"); return -1; } - if (updi_nvm_command_V5(pgm, p, UPDI_V5_NVMCTRL_CTRLA_CHIP_ERASE) < 0) { + if(updi_nvm_command_V5(pgm, p, UPDI_V5_NVMCTRL_CTRLA_CHIP_ERASE) < 0) { pmsg_error("chip erase command failed\n"); return -1; } status = updi_nvm_wait_ready_V5(pgm, p); - if (updi_nvm_command_V5(pgm, p, UPDI_V5_NVMCTRL_CTRLA_NOCMD) < 0) { + if(updi_nvm_command_V5(pgm, p, UPDI_V5_NVMCTRL_CTRLA_NOCMD) < 0) { pmsg_error("sending empty command failed\n"); return -1; } - if (status < 0) { + if(status < 0) { pmsg_error("updi_nvm_wait_ready_V5() failed\n"); return -1; } - if (updi_nvm_command_V5(pgm, p, UPDI_V5_NVMCTRL_CTRLA_EEPROM_PAGE_BUFFER_CLEAR) < 0) { + if(updi_nvm_command_V5(pgm, p, UPDI_V5_NVMCTRL_CTRLA_EEPROM_PAGE_BUFFER_CLEAR) < 0) { pmsg_error("sending eeprom page buffer clear command failed\n"); return -1; } status = updi_nvm_wait_ready_V5(pgm, p); - if (updi_nvm_command_V5(pgm, p, UPDI_V5_NVMCTRL_CTRLA_NOCMD) < 0) { + if(updi_nvm_command_V5(pgm, p, UPDI_V5_NVMCTRL_CTRLA_NOCMD) < 0) { pmsg_error("sending empty command failed\n"); return -1; } - if (status < 0) { + if(status < 0) { pmsg_error("updi_nvm_wait_ready_V5() failed\n"); return -1; } @@ -170,29 +170,30 @@ int updi_nvm_erase_flash_page_V5(const PROGRAMMER *pgm, const AVRPART *p, uint32 if not status: raise PymcuprogSerialUpdiNvmTimeout("Timeout waiting for NVM controller to be ready after flash page erase") -*/ +*/ int status; unsigned char data[1]; + pmsg_debug("erase flash page at address 0x%06X\n", address); - if (updi_nvm_wait_ready_V5(pgm, p) < 0) { + if(updi_nvm_wait_ready_V5(pgm, p) < 0) { pmsg_error("updi_nvm_wait_ready_V5() failed\n"); return -1; } data[0] = 0xFF; - if (updi_write_data(pgm, address, data, 1) < 0) { + if(updi_write_data(pgm, address, data, 1) < 0) { pmsg_error("dummy write operation failed\n"); return -1; } - if (updi_nvm_command_V5(pgm, p, UPDI_V5_NVMCTRL_CTRLA_FLASH_PAGE_ERASE) < 0) { + if(updi_nvm_command_V5(pgm, p, UPDI_V5_NVMCTRL_CTRLA_FLASH_PAGE_ERASE) < 0) { pmsg_error("flash page erase command failed\n"); return -1; } status = updi_nvm_wait_ready_V5(pgm, p); - if (updi_nvm_command_V5(pgm, p, UPDI_V5_NVMCTRL_CTRLA_NOCMD) < 0) { + if(updi_nvm_command_V5(pgm, p, UPDI_V5_NVMCTRL_CTRLA_NOCMD) < 0) { pmsg_error("sending empty command failed\n"); return -1; } - if (status < 0) { + if(status < 0) { pmsg_error("updi_nvm_wait_ready_V5() failed\n"); return -1; } @@ -224,21 +225,22 @@ int updi_nvm_erase_eeprom_V5(const PROGRAMMER *pgm, const AVRPART *p) { raise IOError("Timeout waiting for NVM controller to be ready after EEPROM erase") */ int status; + pmsg_debug("erase EEPROM\n"); - if (updi_nvm_wait_ready_V5(pgm, p) < 0) { + if(updi_nvm_wait_ready_V5(pgm, p) < 0) { pmsg_error("updi_nvm_wait_ready_V5() failed\n"); return -1; } - if (updi_nvm_command_V5(pgm, p, UPDI_V5_NVMCTRL_CTRLA_EEPROM_ERASE) < 0) { + if(updi_nvm_command_V5(pgm, p, UPDI_V5_NVMCTRL_CTRLA_EEPROM_ERASE) < 0) { pmsg_error("EEPROM erase command failed\n"); return -1; } status = updi_nvm_wait_ready_V5(pgm, p); - if (updi_nvm_command_V5(pgm, p, UPDI_V5_NVMCTRL_CTRLA_NOCMD) < 0) { + if(updi_nvm_command_V5(pgm, p, UPDI_V5_NVMCTRL_CTRLA_NOCMD) < 0) { pmsg_error("sending empty command failed\n"); return -1; } - if (status < 0) { + if(status < 0) { pmsg_error("updi_nvm_wait_ready_V5() failed\n"); return -1; } @@ -260,14 +262,15 @@ int updi_nvm_erase_user_row_V5(const PROGRAMMER *pgm, const AVRPART *p, uint32_t return self.erase_flash_page(self, address) */ pmsg_debug("erase user row at address 0x%06X\n", address); - + return updi_nvm_erase_flash_page_V5(pgm, p, address); } static int nvm_write_V5(const PROGRAMMER *pgm, const AVRPART *p, uint32_t address, unsigned char *buffer, - uint16_t size, access_mode mode, uint8_t nvm_command); + uint16_t size, access_mode mode, uint8_t nvm_command); -int updi_nvm_write_flash_V5(const PROGRAMMER *pgm, const AVRPART *p, uint32_t address, unsigned char *buffer, uint16_t size) { +int updi_nvm_write_flash_V5(const PROGRAMMER *pgm, const AVRPART *p, uint32_t address, + unsigned char *buffer, uint16_t size) { /* def write_flash(self, address, data): """ @@ -281,7 +284,8 @@ int updi_nvm_write_flash_V5(const PROGRAMMER *pgm, const AVRPART *p, uint32_t ad return nvm_write_V5(pgm, p, address, buffer, size, USE_WORD_ACCESS, USE_DEFAULT_COMMAND); } -int updi_nvm_write_user_row_V5(const PROGRAMMER *pgm, const AVRPART *p, uint32_t address, unsigned char *buffer, uint16_t size) { +int updi_nvm_write_user_row_V5(const PROGRAMMER *pgm, const AVRPART *p, uint32_t address, + unsigned char *buffer, uint16_t size) { /* def write_user_row(self, address, data): """ @@ -296,14 +300,15 @@ int updi_nvm_write_user_row_V5(const PROGRAMMER *pgm, const AVRPART *p, uint32_t return nvm_write_V5(pgm, p, address, buffer, size, USE_WORD_ACCESS, USE_DEFAULT_COMMAND); } -int updi_nvm_write_boot_row_V5(const PROGRAMMER *pgm, const AVRPART *p, uint32_t address, unsigned char *buffer, uint16_t size) { -/* - Perform the operation as the regular flash write -*/ +int updi_nvm_write_boot_row_V5(const PROGRAMMER *pgm, const AVRPART *p, uint32_t address, + unsigned char *buffer, uint16_t size) { + + // Perform the operation as the regular flash write return nvm_write_V5(pgm, p, address, buffer, size, USE_WORD_ACCESS, USE_DEFAULT_COMMAND); } -int updi_nvm_write_eeprom_V5(const PROGRAMMER *pgm, const AVRPART *p, uint32_t address, unsigned char *buffer, uint16_t size) { +int updi_nvm_write_eeprom_V5(const PROGRAMMER *pgm, const AVRPART *p, uint32_t address, + unsigned char *buffer, uint16_t size) { /* def write_eeprom(self, address, data): """ @@ -315,7 +320,8 @@ int updi_nvm_write_eeprom_V5(const PROGRAMMER *pgm, const AVRPART *p, uint32_t a return self.write_nvm(address, data, use_word_access=False, nvmcommand=constants.UPDI_V5_NVMCTRL_CTRLA_EEPROM_PAGE_ERASE_WRITE) */ - return nvm_write_V5(pgm, p, address, buffer, size, DONT_USE_WORD_ACCESS, UPDI_V5_NVMCTRL_CTRLA_EEPROM_PAGE_ERASE_WRITE); + return nvm_write_V5(pgm, p, address, buffer, size, DONT_USE_WORD_ACCESS, + UPDI_V5_NVMCTRL_CTRLA_EEPROM_PAGE_ERASE_WRITE); } int updi_nvm_write_fuse_V5(const PROGRAMMER *pgm, const AVRPART *p, uint32_t address, uint8_t value) { @@ -330,13 +336,13 @@ int updi_nvm_write_fuse_V5(const PROGRAMMER *pgm, const AVRPART *p, uint32_t add return self.write_eeprom(address, data) */ unsigned char buffer[1]; + buffer[0] = value; return updi_nvm_write_eeprom_V5(pgm, p, address, buffer, 1); } static int nvm_write_V5(const PROGRAMMER *pgm, const AVRPART *p, uint32_t address, unsigned char *buffer, - uint16_t size, access_mode mode, uint8_t nvm_command) -{ + uint16_t size, access_mode mode, uint8_t nvm_command) { /* def write_nvm(self, address, data, use_word_access, nvmcommand=constants.UPDI_V5_NVMCTRL_CTRLA_FLASH_PAGE_WRITE): """ @@ -381,50 +387,49 @@ static int nvm_write_V5(const PROGRAMMER *pgm, const AVRPART *p, uint32_t addres # Remove command self.execute_nvm_command(constants.UPDI_V5_NVMCTRL_CTRLA_NOCMD) */ - if (updi_nvm_wait_ready_V5(pgm, p) < 0) { + if(updi_nvm_wait_ready_V5(pgm, p) < 0) { pmsg_error("updi_nvm_wait_ready_V5() failed\n"); return -1; } pmsg_debug("clear page buffer\n"); - if (updi_nvm_command_V5(pgm, p, UPDI_V5_NVMCTRL_CTRLA_FLASH_PAGE_BUFFER_CLEAR) < 0) { + if(updi_nvm_command_V5(pgm, p, UPDI_V5_NVMCTRL_CTRLA_FLASH_PAGE_BUFFER_CLEAR) < 0) { pmsg_error("clear page operation failed\n"); return -1; } - if (updi_nvm_wait_ready_V5(pgm, p) < 0) { + if(updi_nvm_wait_ready_V5(pgm, p) < 0) { pmsg_error("updi_nvm_wait_ready_V5() failed\n"); return -1; } - if (mode == USE_WORD_ACCESS) { - if (updi_write_data_words(pgm, address, buffer, size) < 0) { + if(mode == USE_WORD_ACCESS) { + if(updi_write_data_words(pgm, address, buffer, size) < 0) { pmsg_error("write data words operation failed\n"); return -1; } } else { - if (updi_write_data(pgm, address, buffer, size) < 0) { + if(updi_write_data(pgm, address, buffer, size) < 0) { pmsg_error("write data operation failed\n"); return -1; } } pmsg_debug("committing data\n"); - if (nvm_command == USE_DEFAULT_COMMAND) { + if(nvm_command == USE_DEFAULT_COMMAND) { nvm_command = UPDI_V5_NVMCTRL_CTRLA_FLASH_PAGE_WRITE; } - if (updi_nvm_command_V5(pgm, p, nvm_command) < 0) { - pmsg_error("commit data command failed\n"); - return -1; + if(updi_nvm_command_V5(pgm, p, nvm_command) < 0) { + pmsg_error("commit data command failed\n"); + return -1; } - if (updi_nvm_wait_ready_V5(pgm, p) < 0) { + if(updi_nvm_wait_ready_V5(pgm, p) < 0) { pmsg_error("updi_nvm_wait_ready_V5() failed\n"); return -1; } - if (updi_nvm_command_V5(pgm, p, UPDI_V5_NVMCTRL_CTRLA_NOCMD) < 0) { + if(updi_nvm_command_V5(pgm, p, UPDI_V5_NVMCTRL_CTRLA_NOCMD) < 0) { pmsg_error("sending empty command failed\n"); return -1; } return 0; } - int updi_nvm_wait_ready_V5(const PROGRAMMER *pgm, const AVRPART *p) { /* def wait_nvm_ready(self, timeout_ms=100): @@ -455,20 +460,20 @@ int updi_nvm_wait_ready_V5(const PROGRAMMER *pgm, const AVRPART *p) { unsigned long start_time; unsigned long current_time; uint8_t status; + start_time = avr_ustimestamp(); do { - if (updi_read_byte(pgm, p->nvm_base + UPDI_V5_NVMCTRL_STATUS, &status) >= 0) { - if (status & UPDI_V5_NVM_STATUS_WRITE_ERROR_MASK) { + if(updi_read_byte(pgm, p->nvm_base + UPDI_V5_NVMCTRL_STATUS, &status) >= 0) { + if(status & UPDI_V5_NVM_STATUS_WRITE_ERROR_MASK) { pmsg_error("unable to write NVM status, error code %d\n", status >> UPDI_V5_NVM_STATUS_WRITE_ERROR_BIT); return -1; } - if (!(status & ((1 << UPDI_V5_NVM_STATUS_EEPROM_BUSY_BIT) | - (1 << UPDI_V5_NVM_STATUS_FLASH_BUSY_BIT)))) { + if(!(status & ((1 << UPDI_V5_NVM_STATUS_EEPROM_BUSY_BIT) | (1 << UPDI_V5_NVM_STATUS_FLASH_BUSY_BIT)))) { return 0; } } current_time = avr_ustimestamp(); - } while ((current_time - start_time) < 10000000); + } while((current_time - start_time) < 10000000); pmsg_error("wait NVM ready timed out\n"); return -1; diff --git a/src/updi_nvm_v5.h b/src/updi_nvm_v5.h index c8ade93f6..c9ba29cfe 100644 --- a/src/updi_nvm_v5.h +++ b/src/updi_nvm_v5.h @@ -31,20 +31,26 @@ extern "C" { #endif -int updi_nvm_chip_erase_V5(const PROGRAMMER *pgm, const AVRPART *p); -int updi_nvm_erase_flash_page_V5(const PROGRAMMER *pgm, const AVRPART *p, uint32_t address); -int updi_nvm_erase_eeprom_V5(const PROGRAMMER *pgm, const AVRPART *p); -int updi_nvm_erase_user_row_V5(const PROGRAMMER *pgm, const AVRPART *p, uint32_t address, uint16_t size); -int updi_nvm_write_flash_V5(const PROGRAMMER *pgm, const AVRPART *p, uint32_t address, unsigned char *buffer, uint16_t size); -int updi_nvm_write_user_row_V5(const PROGRAMMER *pgm, const AVRPART *p, uint32_t address, unsigned char *buffer, uint16_t size); -int updi_nvm_write_boot_row_V5(const PROGRAMMER *pgm, const AVRPART *p, uint32_t address, unsigned char *buffer, uint16_t size); -int updi_nvm_write_eeprom_V5(const PROGRAMMER *pgm, const AVRPART *p, uint32_t address, unsigned char *buffer, uint16_t size); -int updi_nvm_write_fuse_V5(const PROGRAMMER *pgm, const AVRPART *p, uint32_t address, uint8_t value); -int updi_nvm_wait_ready_V5(const PROGRAMMER *pgm, const AVRPART *p); -int updi_nvm_command_V5(const PROGRAMMER *pgm, const AVRPART *p, uint8_t command); + int updi_nvm_chip_erase_V5(const PROGRAMMER *pgm, const AVRPART *p); + int updi_nvm_erase_flash_page_V5(const PROGRAMMER *pgm, const AVRPART *p, uint32_t address); + int updi_nvm_erase_eeprom_V5(const PROGRAMMER *pgm, const AVRPART *p); + int updi_nvm_erase_user_row_V5(const PROGRAMMER *pgm, const AVRPART *p, uint32_t address, + uint16_t size); + int updi_nvm_write_flash_V5(const PROGRAMMER *pgm, const AVRPART *p, uint32_t address, + unsigned char *buffer, uint16_t size); + int updi_nvm_write_user_row_V5(const PROGRAMMER *pgm, const AVRPART *p, uint32_t address, + unsigned char *buffer, uint16_t size); + int updi_nvm_write_boot_row_V5(const PROGRAMMER *pgm, const AVRPART *p, uint32_t address, + unsigned char *buffer, uint16_t size); + int updi_nvm_write_eeprom_V5(const PROGRAMMER *pgm, const AVRPART *p, uint32_t address, + unsigned char *buffer, uint16_t size); + int updi_nvm_write_fuse_V5(const PROGRAMMER *pgm, const AVRPART *p, uint32_t address, + uint8_t value); + int updi_nvm_wait_ready_V5(const PROGRAMMER *pgm, const AVRPART *p); + int updi_nvm_command_V5(const PROGRAMMER *pgm, const AVRPART *p, uint8_t command); #ifdef __cplusplus } #endif -#endif /* updi_nvm_v5_h */ +#endif diff --git a/src/updi_readwrite.c b/src/updi_readwrite.c index 167e16823..038ab03e0 100644 --- a/src/updi_readwrite.c +++ b/src/updi_readwrite.c @@ -146,18 +146,18 @@ int updi_read_data(const PROGRAMMER *pgm, uint32_t address, uint8_t *buffer, uin */ pmsg_debug("reading %d bytes from 0x%06X\n", size, address); - if (size > UPDI_MAX_REPEAT_SIZE) { + if(size > UPDI_MAX_REPEAT_SIZE) { pmsg_debug("cannot read that many bytes in one go\n"); return -1; } - if (updi_link_st_ptr(pgm, address) < 0) { + if(updi_link_st_ptr(pgm, address) < 0) { pmsg_debug("ST_PTR operation failed\n"); return -1; } - if (size > 1) { - if (updi_link_repeat(pgm, size) < 0) { + if(size > 1) { + if(updi_link_repeat(pgm, size) < 0) { pmsg_debug("repeat operation failed\n"); return -1; } @@ -193,25 +193,25 @@ int updi_write_data(const PROGRAMMER *pgm, uint32_t address, uint8_t *buffer, ui self.datalink.repeat(len(data)) return self.datalink.st_ptr_inc(data) */ - if (size == 1) { + if(size == 1) { return updi_link_st(pgm, address, buffer[0]); } - if (size == 2) { - if (updi_link_st(pgm, address, buffer[0]) < 0) { + if(size == 2) { + if(updi_link_st(pgm, address, buffer[0]) < 0) { pmsg_debug("ST operation failed\n"); return -1; } - return updi_link_st(pgm, address+1, buffer[1]); + return updi_link_st(pgm, address + 1, buffer[1]); } - if (size > UPDI_MAX_REPEAT_SIZE) { + if(size > UPDI_MAX_REPEAT_SIZE) { pmsg_debug("invalid length\n"); return -1; } - if (updi_link_st_ptr(pgm, address) < 0) { + if(updi_link_st_ptr(pgm, address) < 0) { pmsg_debug("ST_PTR operation failed\n"); return -1; } - if (updi_link_repeat(pgm, size) < 0) { + if(updi_link_repeat(pgm, size) < 0) { pmsg_debug("repeat operation failed\n"); return -1; } @@ -245,18 +245,18 @@ int updi_read_data_words(const PROGRAMMER *pgm, uint32_t address, uint8_t *buffe */ pmsg_debug("reading %d words from 0x%06X", size, address); - if (size > (UPDI_MAX_REPEAT_SIZE >> 1)) { + if(size > (UPDI_MAX_REPEAT_SIZE >> 1)) { pmsg_debug("cannot read that many words in one go\n"); return -1; } - if (updi_link_st_ptr(pgm, address) < 0) { + if(updi_link_st_ptr(pgm, address) < 0) { pmsg_debug("ST_PTR operation failed\n"); return -1; } - if (size > 1) { - if (updi_link_repeat(pgm, size) < 0) { + if(size > 1) { + if(updi_link_repeat(pgm, size) < 0) { pmsg_debug("repeat operation failed\n"); return -1; } @@ -289,14 +289,14 @@ int updi_write_data_words(const PROGRAMMER *pgm, uint32_t address, uint8_t *buff self.datalink.repeat(len(data) >> 1) return self.datalink.st_ptr_inc16(data) */ - if (size == 2) { + if(size == 2) { return updi_link_st16(pgm, address, buffer[0] + (buffer[1] << 8)); } - if (size > UPDI_MAX_REPEAT_SIZE << 1) { + if(size > UPDI_MAX_REPEAT_SIZE << 1) { pmsg_debug("invalid length\n"); return -1; } - if (updi_link_st_ptr(pgm, address) < 0) { + if(updi_link_st_ptr(pgm, address) < 0) { pmsg_debug("ST_PTR operation failed\n"); return -1; } diff --git a/src/updi_readwrite.h b/src/updi_readwrite.h index 7d06c3ff4..c8b1dd765 100644 --- a/src/updi_readwrite.h +++ b/src/updi_readwrite.h @@ -31,19 +31,19 @@ extern "C" { #endif -int updi_read_cs(const PROGRAMMER *pgm, uint8_t address, uint8_t *value); -int updi_write_cs(const PROGRAMMER *pgm, uint8_t address, uint8_t value); -int updi_write_key(const PROGRAMMER *pgm, unsigned char *buffer, uint8_t size_type, uint16_t size); -int updi_read_sib(const PROGRAMMER *pgm, unsigned char *buffer, uint16_t size); -int updi_read_byte(const PROGRAMMER *pgm, uint32_t address, uint8_t *value); -int updi_write_byte(const PROGRAMMER *pgm, uint32_t address, uint8_t value); -int updi_read_data(const PROGRAMMER *pgm, uint32_t address, uint8_t *buffer, uint16_t size); -int updi_write_data(const PROGRAMMER *pgm, uint32_t address, uint8_t *buffer, uint16_t size); -int updi_read_data_words(const PROGRAMMER *pgm, uint32_t address, uint8_t *buffer, uint16_t size); -int updi_write_data_words(const PROGRAMMER *pgm, uint32_t address, uint8_t *buffer, uint16_t size); + int updi_read_cs(const PROGRAMMER *pgm, uint8_t address, uint8_t *value); + int updi_write_cs(const PROGRAMMER *pgm, uint8_t address, uint8_t value); + int updi_write_key(const PROGRAMMER *pgm, unsigned char *buffer, uint8_t size_type, uint16_t size); + int updi_read_sib(const PROGRAMMER *pgm, unsigned char *buffer, uint16_t size); + int updi_read_byte(const PROGRAMMER *pgm, uint32_t address, uint8_t *value); + int updi_write_byte(const PROGRAMMER *pgm, uint32_t address, uint8_t value); + int updi_read_data(const PROGRAMMER *pgm, uint32_t address, uint8_t *buffer, uint16_t size); + int updi_write_data(const PROGRAMMER *pgm, uint32_t address, uint8_t *buffer, uint16_t size); + int updi_read_data_words(const PROGRAMMER *pgm, uint32_t address, uint8_t *buffer, uint16_t size); + int updi_write_data_words(const PROGRAMMER *pgm, uint32_t address, uint8_t *buffer, uint16_t size); #ifdef __cplusplus } #endif -#endif /* updi_readwrite_h */ +#endif diff --git a/src/updi_state.c b/src/updi_state.c index 8522a75a7..7ec3c7251 100644 --- a/src/updi_state.c +++ b/src/updi_state.c @@ -27,30 +27,30 @@ #include "libavrdude.h" #include "updi_state.h" -updi_sib_info* updi_get_sib_info(const PROGRAMMER *pgm) { - return &((updi_state *)(pgm->cookie))->sib_info; +updi_sib_info *updi_get_sib_info(const PROGRAMMER *pgm) { + return &((updi_state *) (pgm->cookie))->sib_info; } updi_datalink_mode updi_get_datalink_mode(const PROGRAMMER *pgm) { - return ((updi_state *)(pgm->cookie))->datalink_mode; + return ((updi_state *) (pgm->cookie))->datalink_mode; } void updi_set_datalink_mode(const PROGRAMMER *pgm, updi_datalink_mode mode) { - ((updi_state *)(pgm->cookie))->datalink_mode = mode; + ((updi_state *) (pgm->cookie))->datalink_mode = mode; } updi_nvm_mode updi_get_nvm_mode(const PROGRAMMER *pgm) { - return ((updi_state *)(pgm->cookie))->nvm_mode; + return ((updi_state *) (pgm->cookie))->nvm_mode; } void updi_set_nvm_mode(const PROGRAMMER *pgm, updi_nvm_mode mode) { - ((updi_state *)(pgm->cookie))->nvm_mode = mode; + ((updi_state *) (pgm->cookie))->nvm_mode = mode; } updi_rts_mode updi_get_rts_mode(const PROGRAMMER *pgm) { - return ((updi_state *)(pgm->cookie))->rts_mode; + return ((updi_state *) (pgm->cookie))->rts_mode; } void updi_set_rts_mode(const PROGRAMMER *pgm, updi_rts_mode mode) { - ((updi_state *)(pgm->cookie))->rts_mode = mode; + ((updi_state *) (pgm->cookie))->rts_mode = mode; } diff --git a/src/updi_state.h b/src/updi_state.h index 552cb4699..0f7d6fbba 100644 --- a/src/updi_state.h +++ b/src/updi_state.h @@ -27,14 +27,12 @@ #include "libavrdude.h" -typedef enum -{ +typedef enum { UPDI_LINK_MODE_16BIT, UPDI_LINK_MODE_24BIT } updi_datalink_mode; -typedef enum -{ +typedef enum { UPDI_NVM_MODE_V0, UPDI_NVM_MODE_V2, UPDI_NVM_MODE_V3, @@ -49,27 +47,24 @@ typedef enum #define SIB_INFO_PDI_LENGTH 4 #define SIB_INFO_EXTRA_LENGTH 20 -typedef struct -{ - unsigned char sib_string[SIB_INFO_STRING_LENGTH+1]; - char family_string[SIB_INFO_FAMILY_LENGTH+1]; - char nvm_string[SIB_INFO_NVM_LENGTH+1]; - char debug_string[SIB_INFO_DEBUG_LENGTH+1]; - char pdi_string[SIB_INFO_PDI_LENGTH+1]; - char extra_string[SIB_INFO_EXTRA_LENGTH+1]; +typedef struct { + unsigned char sib_string[SIB_INFO_STRING_LENGTH + 1]; + char family_string[SIB_INFO_FAMILY_LENGTH + 1]; + char nvm_string[SIB_INFO_NVM_LENGTH + 1]; + char debug_string[SIB_INFO_DEBUG_LENGTH + 1]; + char pdi_string[SIB_INFO_PDI_LENGTH + 1]; + char extra_string[SIB_INFO_EXTRA_LENGTH + 1]; char nvm_version; char debug_version; } updi_sib_info; -typedef enum -{ +typedef enum { RTS_MODE_DEFAULT, RTS_MODE_LOW, RTS_MODE_HIGH } updi_rts_mode; -typedef struct -{ +typedef struct { updi_sib_info sib_info; updi_datalink_mode datalink_mode; updi_nvm_mode nvm_mode; @@ -80,16 +75,16 @@ typedef struct extern "C" { #endif -updi_sib_info* updi_get_sib_info(const PROGRAMMER *pgm); -updi_datalink_mode updi_get_datalink_mode(const PROGRAMMER *pgm); -void updi_set_datalink_mode(const PROGRAMMER *pgm, updi_datalink_mode mode); -updi_nvm_mode updi_get_nvm_mode(const PROGRAMMER *pgm); -void updi_set_nvm_mode(const PROGRAMMER *pgm, updi_nvm_mode mode); -updi_rts_mode updi_get_rts_mode(const PROGRAMMER *pgm); -void updi_set_rts_mode(const PROGRAMMER *pgm, updi_rts_mode mode); + updi_sib_info *updi_get_sib_info(const PROGRAMMER *pgm); + updi_datalink_mode updi_get_datalink_mode(const PROGRAMMER *pgm); + void updi_set_datalink_mode(const PROGRAMMER *pgm, updi_datalink_mode mode); + updi_nvm_mode updi_get_nvm_mode(const PROGRAMMER *pgm); + void updi_set_nvm_mode(const PROGRAMMER *pgm, updi_nvm_mode mode); + updi_rts_mode updi_get_rts_mode(const PROGRAMMER *pgm); + void updi_set_rts_mode(const PROGRAMMER *pgm, updi_rts_mode mode); #ifdef __cplusplus } #endif -#endif /* updi_state_h */ +#endif diff --git a/src/urclock.c b/src/urclock.c index 3d016d17d..424d425d3 100644 --- a/src/urclock.c +++ b/src/urclock.c @@ -390,7 +390,7 @@ static uint16_t rjmp_opcode(int dist, int flashsize) { // rjmp opcode from reset to bootloader start; same as above if bl start is in top half of flash -static uint16_t rjmp_bwd_blstart(int blstart, int flashsize) { // flashsize must be power of 2 +static uint16_t rjmp_bwd_blstart(int blstart, int flashsize) { // Flashsize must be power of 2 return 0xc000 | (((uint16_t)((blstart-flashsize-2)/2)) & 0xfff); // Urboot uses this formula } @@ -530,7 +530,7 @@ static int set_reset(const PROGRAMMER *pgm, unsigned char *jmptoboot, int vecsz) // Called after the input file has been read for writing or verifying flash static int urclock_flash_readhook(const PROGRAMMER *pgm, const AVRPART *p, const AVRMEM *flm, - const char *fname, int size) { // size is max memory address + 1 + const char *fname, int size) { // Size is max memory address + 1 int nmdata, maxsize, firstbeg, firstlen; const int vecsz = ur.uP.flashsize <= 8192? 2: 4; // Small parts use rjmp, large a 4-byte jmp @@ -990,7 +990,7 @@ static int urclock_res_check(const PROGRAMMER *pgm, const char *funcname, int ig } -// set ur.uP from mcuid, potentially overwritten by p +// Set ur.uP from mcuid, potentially overwritten by p static void set_uP(const PROGRAMMER *pgm, const AVRPART *p, int mcuid, int mcuid_wins) { int idx_m = -1, idx_p = -1; @@ -1025,9 +1025,9 @@ static void set_uP(const PROGRAMMER *pgm, const AVRPART *p, int mcuid, int mcuid ur.uP.name = p->desc; ur.uP.mcuid = p->mcuid; ur.uP.avrarch = - p->prog_modes & PM_UPDI? F_AVR8X: - p->prog_modes & PM_PDI? F_XMEGA: - p->prog_modes & PM_TPI? F_AVR8L: + is_updi(p)? F_AVR8X: + is_pdi(p)? F_XMEGA: + is_tpi(p)? F_AVR8L: p->prog_modes & (PM_ISP | PM_HVPP | PM_HVSP)? F_AVR8: 0; memcpy(ur.uP.sigs, p->signature, sizeof ur.uP.sigs); if((mem = avr_locate_flash(p))) { @@ -1150,7 +1150,7 @@ static void guessblstart(const PROGRAMMER *pgm, const AVRPART *p) { while(bi < sz) { if(ur_readEF(pgm, p, b128, ur.uP.flashsize-bi-128, 128, 'F') < 0) return; - for(int ti=127; ti >= 0; ti--) // read in backwards + for(int ti=127; ti >= 0; ti--) // Read in backwards buf[bi++] = b128[ti]; } @@ -1289,11 +1289,11 @@ static int ur_initstruct(const PROGRAMMER *pgm, const AVRPART *p) { ur.bleepromrw = 0; // No urboot bootloaders on AVR32 parts, neither on really small devices - if((p->prog_modes & PM_aWire) || flm->size < 512) + if(is_awire(p) || flm->size < 512) goto alldone; // UPDI parts have bootloader in low flash - ur.boothigh = !(p->prog_modes & PM_UPDI); + ur.boothigh = !is_updi(p); // Manual provision of above bootloader parameters if(ur.xbootsize) { @@ -1315,7 +1315,7 @@ static int ur_initstruct(const PROGRAMMER *pgm, const AVRPART *p) { } if(ur.boothigh) { - if((int8_t) ur.uP.ninterrupts >= 0) // valid range is 0..127 + if((int8_t) ur.uP.ninterrupts >= 0) // Valid range is 0..127 if(ur.xvectornum < -1 || ur.xvectornum > ur.uP.ninterrupts) Return("unknown interrupt vector #%d for vector bootloader -- should be in [-1, %d]", ur.xvectornum, ur.uP.ninterrupts); diff --git a/src/urclock_private.h b/src/urclock_private.h index 39fa979a6..7f244d036 100644 --- a/src/urclock_private.h +++ b/src/urclock_private.h @@ -117,11 +117,11 @@ typedef struct { (uint8_t) (_vh >= 072 && _vh != 0xff? _vh: 0); }) #define vercapis(capver, mask) ({ uint16_t _vi = capver; !!(capabilities_cv(_vi) & (mask)); }) -#define isautobaud_cv(capver) vercapis(capver, UR_AUTOBAUD) // from v7.7 +#define isautobaud_cv(capver) vercapis(capver, UR_AUTOBAUD) // From v7.7 #define iseeprom_cv(capver) vercapis(capver, UR_EEPROM) #define isdual_cv(capver) vercapis(capver, UR_DUAL) -#define isprotectreset_cv(capver) vercapis(capver, UR_PROTECTRESET) // from 7.7 -#define ishas_ce_cv(capver) vercapis(capver, UR_HAS_CE) // from v7.7 +#define isprotectreset_cv(capver) vercapis(capver, UR_PROTECTRESET) // From 7.7 +#define ishas_ce_cv(capver) vercapis(capver, UR_HAS_CE) // From v7.7 // Up to v7.7 #define isurprotocol077_cv(capver) vercapis(capver, UR_URPROTOCOL) @@ -134,11 +134,11 @@ typedef struct { // Capability bits incl position -#define autobaud_bit_cap(cap) ((cap) & UR_AUTOBAUD) // from v7.7 +#define autobaud_bit_cap(cap) ((cap) & UR_AUTOBAUD) // From v7.7 #define eeprom_bit_cap(cap) ((cap) & UR_EEPROM) #define dual_bit_cap(cap) ((cap) & UR_DUAL) -#define protectreset_bit_cap(cap) ((cap) & UR_PROTECTRESET) // from v7.7 -#define has_ce_bit_cap(cap) ((cap) & UR_HAS_CE) // from v7.7 +#define protectreset_bit_cap(cap) ((cap) & UR_PROTECTRESET) // From v7.7 +#define has_ce_bit_cap(cap) ((cap) & UR_HAS_CE) // From v7.7 // Up to v7.7 #define urprotocol077_bit_cap(cap) ((cap) & UR_URPROTOCOL) @@ -151,11 +151,11 @@ typedef struct { // Boolean capabilities -#define isautobaud_cap(cap) (!!((cap) & UR_AUTOBAUD)) // from v7.7 +#define isautobaud_cap(cap) (!!((cap) & UR_AUTOBAUD)) // From v7.7 #define iseeprom_cap(cap) (!!((cap) & UR_EEPROM)) #define isdual_cap(cap) (!!((cap) & UR_DUAL)) -#define isprotectreset_cap(cap) (!!((cap) & UR_PROTECTRESET)) // from v7.7 -#define ishas_ce_cap(cap) (!!((cap) & UR_HAS_CE)) // from v7.7 +#define isprotectreset_cap(cap) (!!((cap) & UR_PROTECTRESET)) // From v7.7 +#define ishas_ce_cap(cap) (!!((cap) & UR_HAS_CE)) // From v7.7 // Up to v7.7 #define isurprotocol077_cap(cap) (!!((cap) & UR_URPROTOCOL)) diff --git a/src/usb_hidapi.c b/src/usb_hidapi.c index 06cdb7197..d03342707 100644 --- a/src/usb_hidapi.c +++ b/src/usb_hidapi.c @@ -16,14 +16,11 @@ * along with this program. If not, see . */ -/* - * USB interface via libhidapi for avrdude; it's used for jtag3 programmers - */ +// USB interface via libhidapi for avrdude; it's used for jtag3 programmers #include -#if defined(HAVE_LIBHIDAPI) - +#if defined(HAVE_LIBHIDAPI) #include #include #include @@ -41,8 +38,8 @@ #include "usbdevs.h" /* - * The "baud" parameter is meaningless for USB devices, so we reuse it - * to pass the desired USB device ID. + * The "baud" parameter is meaningless for USB devices, so we reuse it to pass + * the desired USB device ID. */ static int usbhid_open(const char *port, union pinfo pinfo, union filedescriptor *fd) { hid_device *dev = NULL; @@ -50,7 +47,7 @@ static int usbhid_open(const char *port, union pinfo pinfo, union filedescriptor const char *serp, *vidp, *pidp; unsigned char usbbuf[USBDEV_MAX_XFER_3 + 1]; - if (fd->usb.max_xfer == 0) + if(fd->usb.max_xfer == 0) fd->usb.max_xfer = USBDEV_MAX_XFER_3; /* @@ -66,10 +63,10 @@ static int usbhid_open(const char *port, union pinfo pinfo, union filedescriptor * be specified. */ - if((vidp = strchr(port, ':')) && (pidp = strchr(vidp+1, ':'))) { + if((vidp = strchr(port, ':')) && (pidp = strchr(vidp + 1, ':'))) { int vid, pid; - if(sscanf(vidp+1, "%x", &vid) == 1 && sscanf(pidp+1, "%x", &pid) == 1) { + if(sscanf(vidp + 1, "%x", &vid) == 1 && sscanf(pidp + 1, "%x", &pid) == 1) { if((dev = hid_open(vid, pid, NULL))) { pmsg_notice2("USB device with VID: 0x%04x and PID: 0x%04x\n", vid, pid); pinfo.usbinfo.vid = vid; @@ -85,34 +82,36 @@ static int usbhid_open(const char *port, union pinfo pinfo, union filedescriptor *s++ = *serp; *s = 0; - wchar_t wserno[sizeof serno] = {0}; + wchar_t wserno[sizeof serno] = { 0 }; mbstowcs(wserno, serno, sizeof serno); size_t serlen = s - serno; /* - * Now, try finding all devices matching VID:PID, and compare - * their serial numbers against the requested one. + * Now, try finding all devices matching VID:PID, and compare their serial + * numbers against the requested one. */ struct hid_device_info *list, *walk; + list = hid_enumerate(pinfo.usbinfo.vid, pinfo.usbinfo.pid); - if (list == NULL) { + if(list == NULL) { pmsg_error("no USB HID devices found\n"); return -1; } walk = list; - while (walk) { + while(walk) { if(walk->serial_number) { pmsg_notice("%s(): found %ls, serno: %ls\n", __func__, walk->product_string, walk->serial_number); size_t slen = wcslen(walk->serial_number); + // Found matching serial number? - if (slen >= serlen && wcscmp(walk->serial_number + slen - serlen, wserno) == 0) + if(slen >= serlen && wcscmp(walk->serial_number + slen - serlen, wserno) == 0) break; pmsg_debug("%s(): serial number does not match\n", __func__); } walk = walk->next; } - if (walk == NULL) { + if(walk == NULL) { pmsg_error("no matching device found\n"); hid_free_enumeration(list); return -1; @@ -120,40 +119,42 @@ static int usbhid_open(const char *port, union pinfo pinfo, union filedescriptor pmsg_debug("%s(): opening path %s\n", __func__, walk->path); dev = hid_open_path(walk->path); hid_free_enumeration(list); - if (dev == NULL) { + if(dev == NULL) { pmsg_error("found device, but hid_open_path() failed\n"); return -1; } } else if(!dev) { dev = hid_open(pinfo.usbinfo.vid, pinfo.usbinfo.pid, NULL); - if (dev == NULL) - { - pmsg_notice2("USB device with VID: 0x%04x and PID: 0x%04x not found\n", - pinfo.usbinfo.vid, pinfo.usbinfo.pid); + if(dev == NULL) { + pmsg_notice2("USB device with VID: 0x%04x and PID: 0x%04x not found\n", pinfo.usbinfo.vid, pinfo.usbinfo.pid); return -1; } } - // Store USB serial number to usbsn string wchar_t sn[256]; - if (hid_get_serial_number_string(dev, sn, sizeof(sn)/sizeof(*sn)) == 0) { + + if(hid_get_serial_number_string(dev, sn, sizeof(sn)/sizeof(*sn)) == 0) { size_t n = wcstombs(NULL, sn, 0) + 1; - if (n) { + + if(n) { char *cn = mmt_malloc(n); - if (wcstombs(cn, sn, n) != (size_t) -1) + + if(wcstombs(cn, sn, n) != (size_t) -1) if(serdev) serdev->usbsn = cache_string(cn); mmt_free(cn); } } - // Store USB product string to prod_str wchar_t prodstr[256]; - if (hid_get_product_string(dev, prodstr, sizeof(prodstr)/sizeof(*prodstr)) == 0) { + + if(hid_get_product_string(dev, prodstr, sizeof(prodstr)/sizeof(*prodstr)) == 0) { size_t n = wcstombs(NULL, prodstr, 0) + 1; - if (n) { + + if(n) { char *cn = mmt_malloc(n); - if (wcstombs(cn, prodstr, n) != (size_t) -1) + + if(wcstombs(cn, prodstr, n) != (size_t) -1) if(serdev) serdev->usbproduct = cache_string(cn); mmt_free(cn); @@ -169,11 +170,14 @@ static int usbhid_open(const char *port, union pinfo pinfo, union filedescriptor * cannot be any other value. Standard-Speed (8 bytes) will not work. */ wchar_t ps[256]; - if (hid_get_product_string(dev, ps, 255) == 0) { + + if(hid_get_product_string(dev, ps, 255) == 0) { size_t n = wcstombs(NULL, ps, 0) + 1; - if (n) { + + if(n) { char cn[255]; - if (wcstombs(cn, ps, n) != (size_t) -1 && str_contains(cn, "CMSIS-DAP")) { + + if(wcstombs(cn, ps, n) != (size_t) -1 && str_contains(cn, "CMSIS-DAP")) { // The JTAGICE3 running CMSIS-DAP doesn't use a separate endpoint for event reception fd->usb.eep = 0; fd->usb.max_xfer = 64; @@ -183,67 +187,63 @@ static int usbhid_open(const char *port, union pinfo pinfo, union filedescriptor } /* - * Try finding out the endpoint size. Alas, libhidapi doesn't - * provide us with an API function for that, nor for the report - * descriptor (which also contains that information). + * Try finding out the endpoint size. Alas, libhidapi doesn't provide us + * with an API function for that, nor for the report descriptor (which also + * contains that information). * - * Since the Atmel tools are very picky to only respond to incoming - * packets that have full size, we need to know whether our device - * handles 512-byte data (JTAGICE3 in CMSIS-DAP mode, or AtmelICE, - * both on USB 2.0 connections), or 64-byte data only (both these on - * USB 1.1 connections, or mEDBG devices). + * Since the Atmel tools are very picky to only respond to incoming packets + * that have full size, we need to know whether our device handles 512-byte + * data (JTAGICE3 in CMSIS-DAP mode, or AtmelICE, both on USB 2.0 + * connections), or 64-byte data only (both these on USB 1.1 connections, or + * mEDBG devices). * - * In order to find out, we send a CMSIS-DAP DAP_Info command - * (0x00), with an ID of 0xFF (get maximum packet size). In theory, - * this gets us the desired information, but this suffers from a - * chicken-and-egg problem: the request must be sent with a - * full-sized packet lest the ICE won't answer. Thus, we send a - * 64-byte packet first, and if we don't get a timely reply, - * complete that request by sending another 448 bytes, and hope it - * will eventually reply. + * In order to find out, we send a CMSIS-DAP DAP_Info command (0x00), with an + * ID of 0xFF (get maximum packet size). In theory, this gets us the desired + * information, but this suffers from a chicken-and-egg problem: the request + * must be sent with a full-sized packet lest the ICE won't answer. Thus, we + * send a 64-byte packet first, and if we don't get a timely reply, complete + * that request by sending another 448 bytes, and hope it will eventually + * reply. * - * Note that libhidapi always requires a report ID as the first - * byte. If the target doesn't use report IDs (Atmel targets - * don't), this first byte must be 0x00. However, the length must - * be incremented by one, as the report ID will be omitted by the - * hidapi library. + * Note that libhidapi always requires a report ID as the first byte. If the + * target doesn't use report IDs (Atmel targets don't), this first byte must + * be 0x00. However, the length must be incremented by one, as the report ID + * will be omitted by the hidapi library. */ if(pinfo.usbinfo.vid == USB_VENDOR_ATMEL || pinfo.usbinfo.vid == USB_VENDOR_MICROCHIP) { pmsg_debug("%s(): probing for max packet size\n", __func__); memset(usbbuf, 0, sizeof usbbuf); - usbbuf[0] = 0; /* no HID reports used */ - usbbuf[1] = 0; /* DAP_Info */ - usbbuf[2] = 0xFF; /* get max. packet size */ + usbbuf[0] = 0; // No HID reports used + usbbuf[1] = 0; // DAP_Info + usbbuf[2] = 0xFF; // Get max. packet size hid_write(dev, usbbuf, 65); - fd->usb.max_xfer = 64; /* first guess */ + fd->usb.max_xfer = 64; // First guess memset(usbbuf, 0, sizeof usbbuf); - int res = hid_read_timeout(dev, usbbuf, 10 /* bytes */, 50 /* milliseconds */); - if (res == 0) { - /* No timely response, assume 512 byte size */ + int res = hid_read_timeout(dev, usbbuf, 10 /* bytes */ , 50 /* milliseconds */); + + if(res == 0) { + // No timely response, assume 512 byte size hid_write(dev, usbbuf, (512 - 64) + 1); fd->usb.max_xfer = 512; res = hid_read_timeout(dev, usbbuf, 10, 50); } - if (res <= 0) { + if(res <= 0) { pmsg_error("no response from device\n"); hid_close(dev); return -1; } - if (usbbuf[0] != 0 || usbbuf[1] != 2) { - pmsg_error("unexpected reply to DAP_Info: 0x%02x 0x%02x\n", - usbbuf[0], usbbuf[1]); + if(usbbuf[0] != 0 || usbbuf[1] != 2) { + pmsg_error("unexpected reply to DAP_Info: 0x%02x 0x%02x\n", usbbuf[0], usbbuf[1]); } else { fd->usb.max_xfer = usbbuf[2] + (usbbuf[3] << 8); - pmsg_debug("%s(): setting max_xfer from DAP_Info response to %d\n", __func__, - fd->usb.max_xfer); + pmsg_debug("%s(): setting max_xfer from DAP_Info response to %d\n", __func__, fd->usb.max_xfer); } } - if (fd->usb.max_xfer > USBDEV_MAX_XFER_3) { - pmsg_error("unexpected max size %d, reducing to %d\n", - fd->usb.max_xfer, USBDEV_MAX_XFER_3); + if(fd->usb.max_xfer > USBDEV_MAX_XFER_3) { + pmsg_error("unexpected max size %d, reducing to %d\n", fd->usb.max_xfer, USBDEV_MAX_XFER_3); fd->usb.max_xfer = USBDEV_MAX_XFER_3; } @@ -251,32 +251,31 @@ static int usbhid_open(const char *port, union pinfo pinfo, union filedescriptor } static void usbhid_close(union filedescriptor *fd) { - hid_device *udev = (hid_device *)fd->usb.handle; + hid_device *udev = (hid_device *) fd->usb.handle; - if (udev == NULL) + if(udev == NULL) return; hid_close(udev); } - static int usbhid_send(const union filedescriptor *fd, const unsigned char *bp, size_t mlen) { - hid_device *udev = (hid_device *)fd->usb.handle; + hid_device *udev = (hid_device *) fd->usb.handle; int rv; unsigned char usbbuf[USBDEV_MAX_XFER_3 + 1]; const int tx_size = mlen < USBDEV_MAX_XFER_3? mlen: USBDEV_MAX_XFER_3; - if (udev == NULL) + if(udev == NULL) return -1; - usbbuf[0] = 0; /* No report ID used */ + usbbuf[0] = 0; // No report ID used memcpy(usbbuf + 1, bp, tx_size); rv = hid_write(udev, usbbuf, tx_size + 1); - if (rv < 0) { + if(rv < 0) { pmsg_error("unable to write %d bytes to USB\n", tx_size); return -1; } - if (rv != tx_size + 1) + if(rv != tx_size + 1) pmsg_error("short write to USB: %d bytes out of %d written\n", rv, tx_size + 1); if(verbose >= MSG_TRACE2) @@ -286,20 +285,20 @@ static int usbhid_send(const union filedescriptor *fd, const unsigned char *bp, } static int usbhid_recv(const union filedescriptor *fd, unsigned char *buf, size_t nbytes) { - hid_device *udev = (hid_device *)fd->usb.handle; + hid_device *udev = (hid_device *) fd->usb.handle; int i, rv; - unsigned char * p = buf; + unsigned char *p = buf; - if (udev == NULL) + if(udev == NULL) return -1; rv = i = hid_read_timeout(udev, buf, nbytes, 10000); - if (i < 0) + if(i < 0) pmsg_error("hid_read_timeout(usb, %lu, 10000) failed\n", (unsigned long) nbytes); - else if ((size_t) i != nbytes) + else if((size_t) i != nbytes) pmsg_error("short read, read only %d out of %lu bytes\n", i, (unsigned long) nbytes); - if (verbose >= MSG_TRACE2 && i > 0) + if(verbose >= MSG_TRACE2 && i > 0) trace_buffer(__func__, p, i); return rv; @@ -307,22 +306,18 @@ static int usbhid_recv(const union filedescriptor *fd, unsigned char *buf, size_ static int usbhid_drain(const union filedescriptor *fd, int display) { /* - * There is not much point in trying to flush any data - * on an USB endpoint, as the endpoint is supposed to - * start afresh after being configured from the host. + * There is not much point in trying to flush any data on an USB endpoint, as + * the endpoint is supposed to start afresh after being configured from the + * host. * - * As trying to flush the data here caused strange effects - * in some situations (see - * https://savannah.nongnu.org/bugs/index.php?43268 ) - * better avoid it. + * As trying to flush the data here caused strange effects in some situations + * (see https://savannah.nongnu.org/bugs/index.php?43268) better avoid it. */ return 0; } -/* - * Device descriptor. - */ +// Device descriptor struct serial_device usbhid_serdev = { .open = usbhid_open, .close = usbhid_close, @@ -332,5 +327,4 @@ struct serial_device usbhid_serdev = { .drain = usbhid_drain, .flags = SERDEV_FL_NONE, }; - -#endif /* HAVE_LIBHIDAPI */ +#endif // HAVE_LIBHIDAPI diff --git a/src/usb_libusb.c b/src/usb_libusb.c index abbe62040..62243adea 100644 --- a/src/usb_libusb.c +++ b/src/usb_libusb.c @@ -17,14 +17,11 @@ * along with this program. If not, see . */ -/* - * USB interface via libusb for avrdude. - */ +// USB interface via libusb for avrdude #include -#if defined(HAVE_LIBUSB) - +#if defined(HAVE_LIBUSB) #include #include #include @@ -34,11 +31,11 @@ #include #if defined(HAVE_USB_H) -# include +#include #elif defined(HAVE_LUSB0_USB_H) -# include +#include #else -# error "libusb needs either or " +#error "libusb needs either or " #endif #include "avrdude.h" @@ -47,13 +44,14 @@ #include "usbdevs.h" #if defined(WIN32) -/* someone has defined "interface" to "struct" in Cygwin */ -# undef interface + +// Someone has defined interface to struct in Cygwin +#undef interface #endif /* - * The "baud" parameter is meaningless for USB devices, so we reuse it - * to pass the desired USB device ID. + * The baud parameter is meaningless for USB devices, so we reuse it to pass + * the desired USB device ID. */ static int usbdev_open(const char *port, union pinfo pinfo, union filedescriptor *fd) { char string[256]; @@ -61,7 +59,7 @@ static int usbdev_open(const char *port, union pinfo pinfo, union filedescriptor struct usb_bus *bus; struct usb_device *dev; usb_dev_handle *udev; - char *s, serno[64] = {0}; + char *s, serno[64] = { 0 }; const char *serp; int i, iface; @@ -70,10 +68,9 @@ static int usbdev_open(const char *port, union pinfo pinfo, union filedescriptor * * -P usb[:serialnumber] * - * See if we've got a serial number passed here. The serial number - * might contain colons which we remove below, and we compare it - * right-to-left, so only the least significant nibbles need to be - * specified. + * See if we've got a serial number passed here. The serial number might + * contain colons which we remove below, and we compare it right-to-left, so + * only the least significant nibbles need to be specified. */ if((serp = strchr(port, ':')) && *++serp) { // First, get a copy of the serial number w/out colons @@ -83,7 +80,7 @@ static int usbdev_open(const char *port, union pinfo pinfo, union filedescriptor *s = 0; } - if (fd->usb.max_xfer == 0) + if(fd->usb.max_xfer == 0) fd->usb.max_xfer = USBDEV_MAX_XFER_MKII; usb_init(); @@ -91,220 +88,178 @@ static int usbdev_open(const char *port, union pinfo pinfo, union filedescriptor usb_find_busses(); usb_find_devices(); - for (bus = usb_get_busses(); bus; bus = bus->next) - { - for (dev = bus->devices; dev; dev = dev->next) - { - if (dev->descriptor.idVendor == pinfo.usbinfo.vid && - dev->descriptor.idProduct == pinfo.usbinfo.pid) - { - udev = usb_open(dev); - if (udev) - { - /* yeah, we found something */ - if (usb_get_string_simple(udev, - dev->descriptor.iSerialNumber, - string, sizeof(string)) < 0) - { - pmsg_warning("reading serial number, %s\n", usb_strerror()); - /* - * On some systems, libusb appears to have - * problems sending control messages. Catch the - * benign case where the user did not request a - * particular serial number, so we could - * continue anyway. - */ - cx->usb_access_error = 1; - if(*serno) - goto none_matching; // No chance of serno matches - strcpy(string, "[unknown]"); - } - if(serdev) - serdev->usbsn = cache_string(string); - if (usb_get_string_simple(udev, - dev->descriptor.iProduct, - product, sizeof(product)) < 0) - { - pmsg_warning("reading product name, %s\n", usb_strerror()); - strcpy(product, "[unnamed product]"); - } - if(serdev) - serdev->usbproduct = cache_string(product); - - /* We need to write to endpoint 2 to switch the PICkit4 and SNAP - * from PIC to AVR mode - */ - if(str_casestarts(product, "MPLAB") && (str_caseends(product, "Snap ICD") - || str_caseends(product, "PICkit 4"))) - { - pinfo.usbinfo.flags = 0; - fd->usb.wep = 2; - } - /* - * The CMSIS-DAP specification mandates the string - * "CMSIS-DAP" must be present somewhere in the - * product name string for a device compliant to - * that protocol. Use this for the decisision - * whether we have to search for a HID interface - * below. - */ - if(str_contains(product, "CMSIS-DAP")) - { - pinfo.usbinfo.flags |= PINFO_FL_USEHID; - /* The JTAGICE3 running the CMSIS-DAP firmware doesn't - * use a separate endpoint for event reception. */ - fd->usb.eep = 0; - } - - if(str_contains(product, "mEDBG")) - { - /* The AVR Xplained Mini uses different endpoints. */ - fd->usb.rep = 0x81; - fd->usb.wep = 0x02; - } - - pmsg_notice("%s(): found %s, serno: %s\n", __func__, product, string); - if (*serno) - { - /* - * See if the serial number requested by the - * user matches what we found, matching - * right-to-left. - */ - int x = strlen(string) - strlen(serno); - if (x < 0 || !str_caseeq(string + x, serno)) - { - pmsg_debug("%s(): serial number does not match\n", __func__); - usb_close(udev); - continue; - } - } - - if (dev->config == NULL) - { - pmsg_warning("USB device has no configuration\n"); - goto trynext; - } - - if (usb_set_configuration(udev, dev->config[0].bConfigurationValue)) - { - pmsg_notice("(config %d) %s\n", dev->config[0].bConfigurationValue, usb_strerror()); - /* let's hope it has already been configured */ - // goto trynext; - } - - for (iface = 0; iface < dev->config[0].bNumInterfaces; iface++) - { - cx->usb_interface = dev->config[0].interface[iface].altsetting[0].bInterfaceNumber; + for(bus = usb_get_busses(); bus; bus = bus->next) { + for(dev = bus->devices; dev; dev = dev->next) { + if(dev->descriptor.idVendor == pinfo.usbinfo.vid && dev->descriptor.idProduct == pinfo.usbinfo.pid) { + udev = usb_open(dev); + if(udev) { + // Yeah, we found something + if(usb_get_string_simple(udev, dev->descriptor.iSerialNumber, string, sizeof(string)) < 0) { + pmsg_warning("reading serial number, %s\n", usb_strerror()); + /* + * On some systems, libusb appears to have problems sending control + * messages. Catch the benign case where the user did not request + * a particular serial number, so we could continue anyway. + */ + cx->usb_access_error = 1; + if(*serno) + goto none_matching; // No chance of serno matches + strcpy(string, "[unknown]"); + } + if(serdev) + serdev->usbsn = cache_string(string); + if(usb_get_string_simple(udev, dev->descriptor.iProduct, product, sizeof(product)) < 0) { + pmsg_warning("reading product name, %s\n", usb_strerror()); + strcpy(product, "[unnamed product]"); + } + if(serdev) + serdev->usbproduct = cache_string(product); + + /* We need to write to endpoint 2 to switch the PICkit4 and SNAP + * from PIC to AVR mode + */ + if(str_casestarts(product, "MPLAB") && (str_caseends(product, "Snap ICD") + || str_caseends(product, "PICkit 4"))) { + pinfo.usbinfo.flags = 0; + fd->usb.wep = 2; + } + /* + * The CMSIS-DAP specification mandates the string "CMSIS-DAP" must + * be present somewhere in the product name string for a device + * compliant to that protocol. Use this for the decisision whether + * we have to search for a HID interface below. + */ + if(str_contains(product, "CMSIS-DAP")) { + pinfo.usbinfo.flags |= PINFO_FL_USEHID; + /* The JTAGICE3 running the CMSIS-DAP firmware doesn't + * use a separate endpoint for event reception */ + fd->usb.eep = 0; + } + + if(str_contains(product, "mEDBG")) { + // The AVR Xplained Mini uses different endpoints + fd->usb.rep = 0x81; + fd->usb.wep = 0x02; + } + + pmsg_notice("%s(): found %s, serno: %s\n", __func__, product, string); + if(*serno) { + /* + * See if the serial number requested by the user matches what we + * found, matching right-to-left. + */ + int x = strlen(string) - strlen(serno); + + if(x < 0 || !str_caseeq(string + x, serno)) { + pmsg_debug("%s(): serial number does not match\n", __func__); + usb_close(udev); + continue; + } + } + + if(dev->config == NULL) { + pmsg_warning("USB device has no configuration\n"); + goto trynext; + } + + if(usb_set_configuration(udev, dev->config[0].bConfigurationValue)) { + pmsg_notice("(config %d) %s\n", dev->config[0].bConfigurationValue, usb_strerror()); + // goto trynext; // Let's hope it has already been configured + } + + for(iface = 0; iface < dev->config[0].bNumInterfaces; iface++) { + cx->usb_interface = dev->config[0].interface[iface].altsetting[0].bInterfaceNumber; + #ifdef LIBUSB_HAS_GET_DRIVER_NP - /* - * Many Linux systems attach the usbhid driver - * by default to any HID-class device. On - * those, the driver needs to be detached before - * we can claim the interface. - */ - (void) usb_detach_kernel_driver_np(udev, cx->usb_interface); + /* + * Many Linux systems attach the usbhid driver by default to any + * HID-class device. On those, the driver needs to be detached + * before we can claim the interface. + */ + (void) usb_detach_kernel_driver_np(udev, cx->usb_interface); #endif - if (usb_claim_interface(udev, cx->usb_interface)) - { - pmsg_warning("(i/face %d) %s\n", cx->usb_interface, usb_strerror()); - cx->usb_access_error = 1; - } - else - { - if (pinfo.usbinfo.flags & PINFO_FL_USEHID) - { - /* only consider an interface that is of class HID */ - if (dev->config[0].interface[iface].altsetting[0].bInterfaceClass != - USB_CLASS_HID) - continue; - fd->usb.use_interrupt_xfer = 1; - } - break; - } - } - if (iface == dev->config[0].bNumInterfaces) - { - pmsg_warning("no usable interface found\n"); - goto trynext; - } - - fd->usb.handle = udev; - if (fd->usb.rep == 0) - { - /* Try finding out what our read endpoint is. */ - for (i = 0; i < dev->config[0].interface[iface].altsetting[0].bNumEndpoints; i++) - { - int possible_ep = dev->config[0].interface[iface].altsetting[0]. - endpoint[i].bEndpointAddress; - - if ((possible_ep & USB_ENDPOINT_DIR_MASK) != 0) - { - pmsg_notice2("%s(): using read endpoint 0x%02x\n", __func__, possible_ep); - fd->usb.rep = possible_ep; - break; - } - } - if (fd->usb.rep == 0) - { - pmsg_warning("cannot find a read endpoint, using 0x%02x\n", - USBDEV_BULK_EP_READ_MKII); - fd->usb.rep = USBDEV_BULK_EP_READ_MKII; - } - } - for (i = 0; i < dev->config[0].interface[iface].altsetting[0].bNumEndpoints; i++) - { - if ((dev->config[0].interface[iface].altsetting[0].endpoint[i].bEndpointAddress == fd->usb.rep || - dev->config[0].interface[iface].altsetting[0].endpoint[i].bEndpointAddress == fd->usb.wep) && - dev->config[0].interface[iface].altsetting[0].endpoint[i].wMaxPacketSize < fd->usb.max_xfer) - { - pmsg_notice("max packet size expected %d, but found %d due to EP 0x%02x's wMaxPacketSize\n", - fd->usb.max_xfer, - dev->config[0].interface[iface].altsetting[0].endpoint[i].wMaxPacketSize, - dev->config[0].interface[iface].altsetting[0].endpoint[i].bEndpointAddress); - fd->usb.max_xfer = dev->config[0].interface[iface].altsetting[0].endpoint[i].wMaxPacketSize; - } - } - if (pinfo.usbinfo.flags & PINFO_FL_USEHID) - { - if (usb_control_msg(udev, 0x21, 0x0a /* SET_IDLE */, 0, 0, NULL, 0, 100) < 0) - pmsg_warning("SET_IDLE failed\n"); - } - return 0; - - trynext: - usb_close(udev); - } - else - pmsg_warning("cannot open device: %s\n", usb_strerror()); - } - } + + if(usb_claim_interface(udev, cx->usb_interface)) { + pmsg_warning("(i/face %d) %s\n", cx->usb_interface, usb_strerror()); + cx->usb_access_error = 1; + } else { + if(pinfo.usbinfo.flags & PINFO_FL_USEHID) { + // Only consider an interface that is of class HID + if(dev->config[0].interface[iface].altsetting[0].bInterfaceClass != USB_CLASS_HID) + continue; + fd->usb.use_interrupt_xfer = 1; + } + break; + } + } + if(iface == dev->config[0].bNumInterfaces) { + pmsg_warning("no usable interface found\n"); + goto trynext; + } + + fd->usb.handle = udev; + if(fd->usb.rep == 0) { + // Try finding out what our read endpoint is + for(i = 0; i < dev->config[0].interface[iface].altsetting[0].bNumEndpoints; i++) { + int possible_ep = dev->config[0].interface[iface].altsetting[0].endpoint[i].bEndpointAddress; + + if((possible_ep & USB_ENDPOINT_DIR_MASK) != 0) { + pmsg_notice2("%s(): using read endpoint 0x%02x\n", __func__, possible_ep); + fd->usb.rep = possible_ep; + break; + } + } + if(fd->usb.rep == 0) { + pmsg_warning("cannot find a read endpoint, using 0x%02x\n", USBDEV_BULK_EP_READ_MKII); + fd->usb.rep = USBDEV_BULK_EP_READ_MKII; + } + } + for(i = 0; i < dev->config[0].interface[iface].altsetting[0].bNumEndpoints; i++) { + if((dev->config[0].interface[iface].altsetting[0].endpoint[i].bEndpointAddress == fd->usb.rep || + dev->config[0].interface[iface].altsetting[0].endpoint[i].bEndpointAddress == fd->usb.wep) && + dev->config[0].interface[iface].altsetting[0].endpoint[i].wMaxPacketSize < fd->usb.max_xfer) { + pmsg_notice("max packet size expected %d, but found %d due to EP 0x%02x's wMaxPacketSize\n", + fd->usb.max_xfer, + dev->config[0].interface[iface].altsetting[0].endpoint[i].wMaxPacketSize, + dev->config[0].interface[iface].altsetting[0].endpoint[i].bEndpointAddress); + fd->usb.max_xfer = dev->config[0].interface[iface].altsetting[0].endpoint[i].wMaxPacketSize; + } + } + if(pinfo.usbinfo.flags & PINFO_FL_USEHID) { + if(usb_control_msg(udev, 0x21, 0x0a /* SET_IDLE */ , 0, 0, NULL, 0, 100) < 0) + pmsg_warning("SET_IDLE failed\n"); + } + return 0; + + trynext: + usb_close(udev); + } else + pmsg_warning("cannot open device: %s\n", usb_strerror()); + } } + } none_matching: - if ((pinfo.usbinfo.flags & PINFO_FL_SILENT) == 0) + if((pinfo.usbinfo.flags & PINFO_FL_SILENT) == 0) pmsg_error("%s%s USB device %s (%04x:%04x)\n", cx->usb_access_error? "found but could not access": "did not find any", - *serno && !cx->usb_access_error? " (matching)": "", - port, pinfo.usbinfo.vid, pinfo.usbinfo.pid); + *serno && !cx->usb_access_error? " (matching)": "", port, pinfo.usbinfo.vid, pinfo.usbinfo.pid); return -1; } -static void usbdev_close(union filedescriptor *fd) -{ - usb_dev_handle *udev = (usb_dev_handle *)fd->usb.handle; +static void usbdev_close(union filedescriptor *fd) { + usb_dev_handle *udev = (usb_dev_handle *) fd->usb.handle; - if (udev == NULL) + if(udev == NULL) return; (void) usb_release_interface(udev, cx->usb_interface); #if defined(__linux__) /* - * Without this reset, the AVRISP mkII seems to stall the second - * time we try to connect to it. This is not necessary on - * FreeBSD. + * Without this reset, the AVRISP mkII seems to stall the second time we try + * to connect to it. This is not necessary on FreeBSD. */ usb_reset(udev); #endif @@ -312,39 +267,35 @@ static void usbdev_close(union filedescriptor *fd) usb_close(udev); } - -static int usbdev_send(const union filedescriptor *fd, const unsigned char *bp, size_t mlen) -{ - usb_dev_handle *udev = (usb_dev_handle *)fd->usb.handle; +static int usbdev_send(const union filedescriptor *fd, const unsigned char *bp, size_t mlen) { + usb_dev_handle *udev = (usb_dev_handle *) fd->usb.handle; int rv; int i = mlen; - const unsigned char * p = bp; + const unsigned char *p = bp; int tx_size; - if (udev == NULL) + if(udev == NULL) return -1; /* - * Split the frame into multiple packets. It's important to make - * sure we finish with a short packet, or else the device won't know - * the frame is finished. For example, if we need to send 64 bytes, - * we must send a packet of length 64 followed by a packet of length - * 0. + * Split the frame into multiple packets. It's important to make sure we + * finish with a short packet, or else the device won't know the frame is + * finished. For example, if we need to send 64 bytes, we must send a packet + * of length 64 followed by a packet of length 0. */ do { tx_size = ((int) mlen < fd->usb.max_xfer)? (int) mlen: fd->usb.max_xfer; - if (fd->usb.use_interrupt_xfer) - rv = usb_interrupt_write(udev, fd->usb.wep, (char *)bp, tx_size, 10000); + if(fd->usb.use_interrupt_xfer) + rv = usb_interrupt_write(udev, fd->usb.wep, (char *) bp, tx_size, 10000); else - rv = usb_bulk_write(udev, fd->usb.wep, (char *)bp, tx_size, 10000); - if (rv != tx_size) - { - pmsg_error("wrote %d out of %d bytes, err = %s\n", rv, tx_size, usb_strerror()); - return -1; + rv = usb_bulk_write(udev, fd->usb.wep, (char *) bp, tx_size, 10000); + if(rv != tx_size) { + pmsg_error("wrote %d out of %d bytes, err = %s\n", rv, tx_size, usb_strerror()); + return -1; } bp += tx_size; mlen -= tx_size; - } while (mlen > 0); + } while(mlen > 0); if(verbose >= MSG_TRACE) trace_buffer(__func__, p, i); @@ -352,27 +303,23 @@ static int usbdev_send(const union filedescriptor *fd, const unsigned char *bp, } /* - * As calls to usb_bulk_read() result in exactly one USB request, we - * have to buffer the read results ourselves, so the single-char read - * requests performed by the upper layers will be handled. In order - * to do this, we maintain a private buffer of what we've got so far, - * and transparently issue another USB read request if the buffer is - * empty and more data are requested. + * As calls to usb_bulk_read() result in exactly one USB request, we have to + * buffer the read results ourselves, so the single-char read requests + * performed by the upper layers will be handled. In order to do this, we + * maintain a private buffer of what we've got so far, and transparently issue + * another USB read request if the buffer is empty and more data are requested. */ -static int usb_fill_buf(usb_dev_handle *udev, int maxsize, int ep, int use_interrupt_xfer) -{ +static int usb_fill_buf(usb_dev_handle *udev, int maxsize, int ep, int use_interrupt_xfer) { int rv; - if (use_interrupt_xfer) + if(use_interrupt_xfer) rv = usb_interrupt_read(udev, ep, cx->usb_buf, maxsize, 10000); else rv = usb_bulk_read(udev, ep, cx->usb_buf, maxsize, 10000); - if (rv < 0) - { - pmsg_notice2("%s(): usb_%s_read() error: %s\n", __func__, - use_interrupt_xfer? "interrupt": "bulk", usb_strerror()); - return -1; - } + if(rv < 0) { + pmsg_notice2("%s(): usb_%s_read() error: %s\n", __func__, use_interrupt_xfer? "interrupt": "bulk", usb_strerror()); + return -1; + } cx->usb_buflen = rv; cx->usb_bufptr = 0; @@ -380,28 +327,25 @@ static int usb_fill_buf(usb_dev_handle *udev, int maxsize, int ep, int use_inter return 0; } -static int usbdev_recv(const union filedescriptor *fd, unsigned char *buf, size_t nbytes) -{ - usb_dev_handle *udev = (usb_dev_handle *)fd->usb.handle; +static int usbdev_recv(const union filedescriptor *fd, unsigned char *buf, size_t nbytes) { + usb_dev_handle *udev = (usb_dev_handle *) fd->usb.handle; int i, amnt; - unsigned char * p = buf; + unsigned char *p = buf; - if (udev == NULL) + if(udev == NULL) return -1; - for (i = 0; nbytes > 0;) - { - if (cx->usb_buflen <= cx->usb_bufptr) - { - if (usb_fill_buf(udev, fd->usb.max_xfer, fd->usb.rep, fd->usb.use_interrupt_xfer) < 0) - return -1; - } - amnt = cx->usb_buflen - cx->usb_bufptr > (int) nbytes? (int) nbytes: cx->usb_buflen - cx->usb_bufptr; - memcpy(buf + i, cx->usb_buf + cx->usb_bufptr, amnt); - cx->usb_bufptr += amnt; - nbytes -= amnt; - i += amnt; + for(i = 0; nbytes > 0;) { + if(cx->usb_buflen <= cx->usb_bufptr) { + if(usb_fill_buf(udev, fd->usb.max_xfer, fd->usb.rep, fd->usb.use_interrupt_xfer) < 0) + return -1; } + amnt = cx->usb_buflen - cx->usb_bufptr > (int) nbytes? (int) nbytes: cx->usb_buflen - cx->usb_bufptr; + memcpy(buf + i, cx->usb_buf + cx->usb_bufptr, amnt); + cx->usb_bufptr += amnt; + nbytes -= amnt; + i += amnt; + } if(verbose >= MSG_TRACE2) trace_buffer(__func__, p, i); @@ -410,116 +354,95 @@ static int usbdev_recv(const union filedescriptor *fd, unsigned char *buf, size_ } /* - * This version of recv keeps reading packets until we receive a short - * packet. Then, the entire frame is assembled and returned to the - * user. The length will be unknown in advance, so we return the - * length as the return value of this function, or -1 in case of an - * error. + * This version of recv keeps reading packets until we receive a short packet. + * Then, the entire frame is assembled and returned to the user. The length + * will be unknown in advance, so we return the length as the return value of + * this function, or -1 in case of an error. * * This is used for the AVRISP mkII device. */ -static int usbdev_recv_frame(const union filedescriptor *fd, unsigned char *buf, size_t nbytes) -{ - usb_dev_handle *udev = (usb_dev_handle *)fd->usb.handle; +static int usbdev_recv_frame(const union filedescriptor *fd, unsigned char *buf, size_t nbytes) { + usb_dev_handle *udev = (usb_dev_handle *) fd->usb.handle; int rv, n; unsigned char *p = buf; - if (udev == NULL) + if(udev == NULL) return -1; - /* If there's an event EP, and it has data pending, return it first. */ - if (fd->usb.eep != 0) - { - rv = usb_bulk_read(udev, fd->usb.eep, cx->usb_buf, - fd->usb.max_xfer, 1); - if (rv > 4) - { - memcpy(buf, cx->usb_buf, rv); - n = rv; - n |= USB_RECV_FLAG_EVENT; - goto printout; - } - else if (rv > 0) - { - pmsg_warning("short event len = %d, ignored\n", rv); - /* fallthrough */ - } + // If there's an event EP, and it has data pending, return it first + if(fd->usb.eep != 0) { + rv = usb_bulk_read(udev, fd->usb.eep, cx->usb_buf, fd->usb.max_xfer, 1); + if(rv > 4) { + memcpy(buf, cx->usb_buf, rv); + n = rv; + n |= USB_RECV_FLAG_EVENT; + goto printout; + } else if(rv > 0) { + pmsg_warning("short event len = %d, ignored\n", rv); + // Fallthrough + } } n = 0; - do - { - if (fd->usb.use_interrupt_xfer) - rv = usb_interrupt_read(udev, fd->usb.rep, cx->usb_buf, - fd->usb.max_xfer, 10000); - else - rv = usb_bulk_read(udev, fd->usb.rep, cx->usb_buf, - fd->usb.max_xfer, 10000); - if (rv < 0) - { - pmsg_notice2("%s(): usb_%s_read(): %s\n", __func__, - fd->usb.use_interrupt_xfer? "interrupt": "bulk", usb_strerror()); - return -1; - } - - if (rv <= (int) nbytes) - { - memcpy (buf, cx->usb_buf, rv); - buf += rv; - } - else - { - return -1; // buffer overflow - } - - n += rv; - nbytes -= rv; + do { + if(fd->usb.use_interrupt_xfer) + rv = usb_interrupt_read(udev, fd->usb.rep, cx->usb_buf, fd->usb.max_xfer, 10000); + else + rv = usb_bulk_read(udev, fd->usb.rep, cx->usb_buf, fd->usb.max_xfer, 10000); + if(rv < 0) { + pmsg_notice2("%s(): usb_%s_read(): %s\n", __func__, + fd->usb.use_interrupt_xfer? "interrupt": "bulk", usb_strerror()); + return -1; } - while (nbytes > 0 && rv == fd->usb.max_xfer); -/* - this ends when the buffer is completly filled (nbytes=0) or was too small (nbytes< 0) - or a short packet is found. - however we cannot say for nbytes=0 that there was really a packet completed, - we had to check the last rv value than for a short packet, - but what happens if the packet does not end with a short packet? - and what if the buffer is filled without the packet was completed? + if(rv <= (int) nbytes) { + memcpy(buf, cx->usb_buf, rv); + buf += rv; + } else + return -1; // Buffer overflow - preconditions: - expected packet is not a multiple of usb.max_xfer. (prevents further waiting) - - expected packet is shorter than the provided buffer (so it cannot filled completely) - or buffer size is not a multiple of usb.max_xfer. (so it can clearly detected if the buffer was overflown.) -*/ + n += rv; + nbytes -= rv; + } + while(nbytes > 0 && rv == fd->usb.max_xfer); - printout: +/* + * This ends when the buffer is completly filled (nbytes=0) or was too small + * (nbytes< 0) or a short packet is found. However we cannot say for nbytes=0 + * that there was really a packet completed, we had to check the last rv value + * than for a short packet, but what happens if the packet does not end with a + * short packet? and what if the buffer is filled without the packet was + * completed? + * + * Preconditions: + * - expected packet is not a multiple of usb.max_xfer (prevents further waiting) + * - expected packet is shorter than the provided buffer (so it cannot fill it + * completely) or buffer size is not a multiple of usb.max_xfer (so it can + * clearly be detected if the buffer was overflown.) + * + */ +printout: if(verbose >= MSG_TRACE) trace_buffer(__func__, p, n & USB_RECV_LENGTH_MASK); return n; } -static int usbdev_drain(const union filedescriptor *fd, int display) -{ +static int usbdev_drain(const union filedescriptor *fd, int display) { /* - * There is not much point in trying to flush any data - * on an USB endpoint, as the endpoint is supposed to - * start afresh after being configured from the host. + * There is not much point in trying to flush any data on an USB endpoint, as + * the endpoint is supposed to start afresh after being configured from the + * host. * - * As trying to flush the data here caused strange effects - * in some situations (see - * https://savannah.nongnu.org/bugs/index.php?43268 ) - * better avoid it. + * As trying to flush the data here caused strange effects in some situations + * (see https://savannah.nongnu.org/bugs/index.php?43268) better avoid it. */ return 0; } -/* - * Device descriptor for the JTAG ICE mkII. - */ -struct serial_device usb_serdev = -{ +// Device descriptor for the JTAG ICE mkII +struct serial_device usb_serdev = { .open = usbdev_open, .close = usbdev_close, .rawclose = usbdev_close, @@ -529,11 +452,8 @@ struct serial_device usb_serdev = .flags = SERDEV_FL_NONE, }; -/* - * Device descriptor for the AVRISP mkII. - */ -struct serial_device usb_serdev_frame = -{ +// Device descriptor for the AVRISP mkII +struct serial_device usb_serdev_frame = { .open = usbdev_open, .close = usbdev_close, .rawclose = usbdev_close, @@ -542,5 +462,4 @@ struct serial_device usb_serdev_frame = .drain = usbdev_drain, .flags = SERDEV_FL_NONE, }; - -#endif /* HAVE_LIBUSB */ +#endif // HAVE_LIBUSB diff --git a/src/usbasp.c b/src/usbasp.c index e6de2d815..86a20a4df 100644 --- a/src/usbasp.c +++ b/src/usbasp.c @@ -18,7 +18,7 @@ */ /* - * Interface to the USBasp programmer. + * Interface to the USBasp programmer * * See http://www.fischl.de/usbasp/ */ @@ -42,34 +42,38 @@ #if defined(HAVE_LIBUSB) || defined(HAVE_LIBUSB_1_0) #ifdef HAVE_LIBUSB_1_0 -# define USE_LIBUSB_1_0 +#define USE_LIBUSB_1_0 #endif #if defined(USE_LIBUSB_1_0) -# if defined(HAVE_LIBUSB_1_0_LIBUSB_H) -# include -# else -# include -# endif + +#if defined(HAVE_LIBUSB_1_0_LIBUSB_H) +#include #else -# if defined(HAVE_USB_H) -# include -# elif defined(HAVE_LUSB0_USB_H) -# include -# else -# error "libusb needs either or " -# endif +#include +#endif +#else + +#if defined(HAVE_USB_H) +#include +#elif defined(HAVE_LUSB0_USB_H) +#include +#else +#error "libusb needs either or " +#endif #endif #include // Private data for this programmer struct pdata { + #ifdef USE_LIBUSB_1_0 libusb_device_handle *usbhandle; #else usb_dev_handle *usbhandle; #endif + int sckfreq_hz; unsigned int capabilities; int use_tpi; @@ -80,151 +84,149 @@ struct pdata { libusb_context *ctx; char msg[30]; // Used in errstr() #endif + int USB_init; // Used in both usbOpenDevice() variants }; -#define PDATA(pgm) ((struct pdata *)(pgm->cookie)) +#define my (*(struct pdata *) (pgm->cookie)) #ifdef USE_LIBUSB_1_0 - static const char *errstr(const PROGRAMMER *pgm, int result) { - char *msg = PDATA(pgm)->msg; - size_t msgsiz = sizeof(PDATA(pgm)->msg); - int n = 0; - - switch (result) { - case LIBUSB_SUCCESS: - return "No error"; - case LIBUSB_ERROR_IO: - n = EIO; - break; - case LIBUSB_ERROR_INVALID_PARAM: - n = EINVAL; - break; - case LIBUSB_ERROR_ACCESS: - n = EACCES; - break; - case LIBUSB_ERROR_NO_DEVICE: - n = ENXIO; - break; - case LIBUSB_ERROR_NOT_FOUND: - n = ENOENT; - break; - case LIBUSB_ERROR_BUSY: - n = EBUSY; - break; - case LIBUSB_ERROR_TIMEOUT: + char *msg = my.msg; + size_t msgsiz = sizeof(my.msg); + int n = 0; + + switch(result) { + case LIBUSB_SUCCESS: + return "No error"; + case LIBUSB_ERROR_IO: + n = EIO; + break; + case LIBUSB_ERROR_INVALID_PARAM: + n = EINVAL; + break; + case LIBUSB_ERROR_ACCESS: + n = EACCES; + break; + case LIBUSB_ERROR_NO_DEVICE: + n = ENXIO; + break; + case LIBUSB_ERROR_NOT_FOUND: + n = ENOENT; + break; + case LIBUSB_ERROR_BUSY: + n = EBUSY; + break; + case LIBUSB_ERROR_TIMEOUT: + #ifdef ETIMEDOUT - n = ETIMEDOUT; - break; + n = ETIMEDOUT; + break; #else - return "Operation timed out" + return "Operation timed out" #endif - case LIBUSB_ERROR_OVERFLOW: + + case LIBUSB_ERROR_OVERFLOW: + #ifdef EOVERFLOW - n = EOVERFLOW; - break; + n = EOVERFLOW; + break; #else - return "Value too large to be stored in data type" + return "Value too large to be stored in data type" #endif - case LIBUSB_ERROR_PIPE: - n = EPIPE; - break; - case LIBUSB_ERROR_INTERRUPTED: - n = EINTR; - break; - case LIBUSB_ERROR_NO_MEM: - n = ENOMEM; - break; - case LIBUSB_ERROR_NOT_SUPPORTED: - n = ENOSYS; - break; - default: - snprintf(msg, msgsiz, "Unknown libusb error code %d", result); - return msg; - } - return strerror(n); -} + case LIBUSB_ERROR_PIPE: + n = EPIPE; + break; + case LIBUSB_ERROR_INTERRUPTED: + n = EINTR; + break; + case LIBUSB_ERROR_NO_MEM: + n = ENOMEM; + break; + case LIBUSB_ERROR_NOT_SUPPORTED: + n = ENOSYS; + break; + default: + snprintf(msg, msgsiz, "Unknown libusb error code %d", result); + return msg; + } + return strerror(n); +} #endif - -/* Prototypes */ -// interface - management +// Interface management static void usbasp_setup(PROGRAMMER *pgm); static void usbasp_teardown(PROGRAMMER *pgm); static int usbasp_parseextparms(const PROGRAMMER *pgm, const LISTID extparms); -// internal functions + +// Internal functions static int usbasp_transmit(const PROGRAMMER *pgm, unsigned char receive, - unsigned char functionid, const unsigned char *send, - unsigned char *buffer, int buffersize); + unsigned char functionid, const unsigned char *send, unsigned char *buffer, int buffersize); + #ifdef USE_LIBUSB_1_0 -static int usbOpenDevice(const PROGRAMMER *pgm, libusb_device_handle **device, int vendor, +static int usbOpenDevice(const PROGRAMMER *pgm, libusb_device_handle ** device, int vendor, const char *vendorName, int product, const char *productName, const char *port); #else -static int usbOpenDevice(const PROGRAMMER *pgm, usb_dev_handle **device, int vendor, +static int usbOpenDevice(const PROGRAMMER *pgm, usb_dev_handle ** device, int vendor, const char *vendorName, int product, const char *productName, const char *port); #endif -// interface - prog. + +// Interface prog static int usbasp_open(PROGRAMMER *pgm, const char *port); static void usbasp_close(PROGRAMMER *pgm); -// dummy functions + +// Dummy functions static void usbasp_disable(const PROGRAMMER *pgm); static void usbasp_enable(PROGRAMMER *pgm, const AVRPART *p); static void usbasp_display(const PROGRAMMER *pgm, const char *p); -// universal functions + +// Universal functions static int usbasp_initialize(const PROGRAMMER *pgm, const AVRPART *p); + // SPI specific functions static int usbasp_spi_cmd(const PROGRAMMER *pgm, const unsigned char *cmd, unsigned char *res); static int usbasp_spi_program_enable(const PROGRAMMER *pgm, const AVRPART *p); static int usbasp_spi_chip_erase(const PROGRAMMER *pgm, const AVRPART *p); static int usbasp_spi_paged_load(const PROGRAMMER *pgm, const AVRPART *p, const AVRMEM *m, - unsigned int page_size, - unsigned int addr, unsigned int n_bytes); + unsigned int page_size, unsigned int addr, unsigned int n_bytes); static int usbasp_spi_paged_write(const PROGRAMMER *pgm, const AVRPART *p, const AVRMEM *m, - unsigned int page_size, - unsigned int addr, unsigned int n_bytes); + unsigned int page_size, unsigned int addr, unsigned int n_bytes); static int usbasp_spi_set_sck_period(const PROGRAMMER *pgm, double sckperiod); + // TPI specific functions static void usbasp_tpi_send_byte(const PROGRAMMER *pgm, uint8_t b); static int usbasp_tpi_cmd(const PROGRAMMER *pgm, const unsigned char *cmd, unsigned char *res); static int usbasp_tpi_program_enable(const PROGRAMMER *pgm, const AVRPART *p); static int usbasp_tpi_chip_erase(const PROGRAMMER *pgm, const AVRPART *p); static int usbasp_tpi_paged_load(const PROGRAMMER *pgm, const AVRPART *p, const AVRMEM *m, - unsigned int page_size, - unsigned int addr, unsigned int n_bytes); + unsigned int page_size, unsigned int addr, unsigned int n_bytes); static int usbasp_tpi_paged_write(const PROGRAMMER *pgm, const AVRPART *p, const AVRMEM *m, - unsigned int page_size, - unsigned int addr, unsigned int n_bytes); + unsigned int page_size, unsigned int addr, unsigned int n_bytes); static int usbasp_tpi_set_sck_period(const PROGRAMMER *pgm, double sckperiod); -static int usbasp_tpi_read_byte(const PROGRAMMER * pgm, const AVRPART *p, const AVRMEM *m, unsigned long addr, unsigned char *value); -static int usbasp_tpi_write_byte(const PROGRAMMER *pgm, const AVRPART *p, const AVRMEM *m, unsigned long addr, unsigned char data); - +static int usbasp_tpi_read_byte(const PROGRAMMER *pgm, const AVRPART *p, const AVRMEM *m, unsigned long addr, + unsigned char *value); +static int usbasp_tpi_write_byte(const PROGRAMMER *pgm, const AVRPART *p, const AVRMEM *m, unsigned long addr, + unsigned char data); // Dispatching wrappers static int usbasp_cmd(const PROGRAMMER *pgm, const unsigned char *cmd, unsigned char *res) { - return PDATA(pgm)->use_tpi? - usbasp_tpi_cmd(pgm, cmd, res): - usbasp_spi_cmd(pgm, cmd, res); + return my.use_tpi? usbasp_tpi_cmd(pgm, cmd, res): usbasp_spi_cmd(pgm, cmd, res); } static int usbasp_program_enable(const PROGRAMMER *pgm, const AVRPART *p) { - return PDATA(pgm)->use_tpi? - usbasp_tpi_program_enable(pgm, p): - usbasp_spi_program_enable(pgm, p); + return my.use_tpi? usbasp_tpi_program_enable(pgm, p): usbasp_spi_program_enable(pgm, p); } static int usbasp_chip_erase(const PROGRAMMER *pgm, const AVRPART *p) { - return PDATA(pgm)->use_tpi? - usbasp_tpi_chip_erase(pgm, p): - usbasp_spi_chip_erase(pgm, p); + return my.use_tpi? usbasp_tpi_chip_erase(pgm, p): usbasp_spi_chip_erase(pgm, p); } static int usbasp_paged_load(const PROGRAMMER *pgm, const AVRPART *p, const AVRMEM *m, unsigned int page_size, unsigned int addr, unsigned int n_bytes) { - return PDATA(pgm)->use_tpi? + return my.use_tpi? usbasp_tpi_paged_load(pgm, p, m, page_size, addr, n_bytes): usbasp_spi_paged_load(pgm, p, m, page_size, addr, n_bytes); } @@ -232,21 +234,19 @@ static int usbasp_paged_load(const PROGRAMMER *pgm, const AVRPART *p, const AVRM static int usbasp_paged_write(const PROGRAMMER *pgm, const AVRPART *p, const AVRMEM *m, unsigned int page_size, unsigned int addr, unsigned int n_bytes) { - return PDATA(pgm)->use_tpi? + return my.use_tpi? usbasp_tpi_paged_write(pgm, p, m, page_size, addr, n_bytes): usbasp_spi_paged_write(pgm, p, m, page_size, addr, n_bytes); } static int usbasp_set_sck_period(const PROGRAMMER *pgm, double sckperiod) { - return PDATA(pgm)->use_tpi? - usbasp_tpi_set_sck_period(pgm, sckperiod): - usbasp_spi_set_sck_period(pgm, sckperiod); + return my.use_tpi? usbasp_tpi_set_sck_period(pgm, sckperiod): usbasp_spi_set_sck_period(pgm, sckperiod); } static int usbasp_read_byte(const PROGRAMMER *pgm, const AVRPART *p, const AVRMEM *m, - unsigned long addr, unsigned char * value) { + unsigned long addr, unsigned char *value) { - return PDATA(pgm)->use_tpi? + return my.use_tpi? usbasp_tpi_read_byte(pgm, p, m, addr, value): avr_read_byte_default(pgm, p, m, addr, value); } @@ -256,6 +256,7 @@ static int usbasp_write_byte(const PROGRAMMER *pgm, const AVRPART *p, const AVRM if(mem_is_readonly(m)) { unsigned char is; + if(pgm->read_byte(pgm, p, m, addr, &is) >= 0 && is == data) return 0; @@ -263,13 +264,12 @@ static int usbasp_write_byte(const PROGRAMMER *pgm, const AVRPART *p, const AVRM return -1; } - return PDATA(pgm)->use_tpi? + return my.use_tpi? usbasp_tpi_write_byte(pgm, p, m, addr, data): avr_write_byte_default(pgm, p, m, addr, data); } - -/* Interface - management */ +// Interface management static void usbasp_setup(PROGRAMMER *pgm) { pgm->cookie = mmt_malloc(sizeof(struct pdata)); } @@ -283,21 +283,21 @@ static int usbasp_parseextparms(const PROGRAMMER *pgm, const LISTID extparms) { int rv = 0; bool help = false; - for (LNODEID ln = lfirst(extparms); ln; ln = lnext(ln)) { + for(LNODEID ln = lfirst(extparms); ln; ln = lnext(ln)) { const char *extended_param = ldata(ln); - if (str_eq(extended_param, "section_config")) { + if(str_eq(extended_param, "section_config")) { pmsg_notice2("%s(): set section_e to 1 (config section)\n", __func__); - PDATA(pgm)->section_e = 1; + my.section_e = 1; continue; } - if (str_eq(extended_param, "help")) { + if(str_eq(extended_param, "help")) { help = true; rv = LIBAVRDUDE_EXIT; } - if (!help) { + if(!help) { pmsg_error("invalid extended parameter -x %s\n", extended_param); rv = -1; } @@ -310,86 +310,107 @@ static int usbasp_parseextparms(const PROGRAMMER *pgm, const LISTID extparms) { return rv; } - -/* Internal functions */ - -static const char *usbasp_get_funcname(unsigned char functionid) -{ - switch (functionid) { - case USBASP_FUNC_CONNECT: return "USBASP_FUNC_CONNECT"; break; - case USBASP_FUNC_DISCONNECT: return "USBASP_FUNC_DISCONNECT"; break; - case USBASP_FUNC_TRANSMIT: return "USBASP_FUNC_TRANSMIT"; break; - case USBASP_FUNC_READFLASH: return "USBASP_FUNC_READFLASH"; break; - case USBASP_FUNC_ENABLEPROG: return "USBASP_FUNC_ENABLEPROG"; break; - case USBASP_FUNC_WRITEFLASH: return "USBASP_FUNC_WRITEFLASH"; break; - case USBASP_FUNC_READEEPROM: return "USBASP_FUNC_READEEPROM"; break; - case USBASP_FUNC_WRITEEEPROM: return "USBASP_FUNC_WRITEEEPROM"; break; - case USBASP_FUNC_SETLONGADDRESS: return "USBASP_FUNC_SETLONGADDRESS"; break; - case USBASP_FUNC_SETISPSCK: return "USBASP_FUNC_SETISPSCK"; break; - case USBASP_FUNC_TPI_CONNECT: return "USBASP_FUNC_TPI_CONNECT"; break; - case USBASP_FUNC_TPI_DISCONNECT: return "USBASP_FUNC_TPI_DISCONNECT"; break; - case USBASP_FUNC_TPI_RAWREAD: return "USBASP_FUNC_TPI_RAWREAD"; break; - case USBASP_FUNC_TPI_RAWWRITE: return "USBASP_FUNC_TPI_RAWWRITE"; break; - case USBASP_FUNC_TPI_READBLOCK: return "USBASP_FUNC_TPI_READBLOCK"; break; - case USBASP_FUNC_TPI_WRITEBLOCK: return "USBASP_FUNC_TPI_WRITEBLOCK"; break; - case USBASP_FUNC_GETCAPABILITIES: return "USBASP_FUNC_GETCAPABILITIES"; break; - default: return "Unknown USBASP function"; break; +static const char *usbasp_get_funcname(unsigned char functionid) { + switch(functionid) { + case USBASP_FUNC_CONNECT: + return "USBASP_FUNC_CONNECT"; + break; + case USBASP_FUNC_DISCONNECT: + return "USBASP_FUNC_DISCONNECT"; + break; + case USBASP_FUNC_TRANSMIT: + return "USBASP_FUNC_TRANSMIT"; + break; + case USBASP_FUNC_READFLASH: + return "USBASP_FUNC_READFLASH"; + break; + case USBASP_FUNC_ENABLEPROG: + return "USBASP_FUNC_ENABLEPROG"; + break; + case USBASP_FUNC_WRITEFLASH: + return "USBASP_FUNC_WRITEFLASH"; + break; + case USBASP_FUNC_READEEPROM: + return "USBASP_FUNC_READEEPROM"; + break; + case USBASP_FUNC_WRITEEEPROM: + return "USBASP_FUNC_WRITEEEPROM"; + break; + case USBASP_FUNC_SETLONGADDRESS: + return "USBASP_FUNC_SETLONGADDRESS"; + break; + case USBASP_FUNC_SETISPSCK: + return "USBASP_FUNC_SETISPSCK"; + break; + case USBASP_FUNC_TPI_CONNECT: + return "USBASP_FUNC_TPI_CONNECT"; + break; + case USBASP_FUNC_TPI_DISCONNECT: + return "USBASP_FUNC_TPI_DISCONNECT"; + break; + case USBASP_FUNC_TPI_RAWREAD: + return "USBASP_FUNC_TPI_RAWREAD"; + break; + case USBASP_FUNC_TPI_RAWWRITE: + return "USBASP_FUNC_TPI_RAWWRITE"; + break; + case USBASP_FUNC_TPI_READBLOCK: + return "USBASP_FUNC_TPI_READBLOCK"; + break; + case USBASP_FUNC_TPI_WRITEBLOCK: + return "USBASP_FUNC_TPI_WRITEBLOCK"; + break; + case USBASP_FUNC_GETCAPABILITIES: + return "USBASP_FUNC_GETCAPABILITIES"; + break; + default: + return "Unknown USBASP function"; + break; } } -/* - * wrapper for usb_control_msg call - */ +// Wrapper for usb_control_msg call static int usbasp_transmit(const PROGRAMMER *pgm, - unsigned char receive, unsigned char functionid, - const unsigned char *send, - unsigned char *buffer, int buffersize) -{ + unsigned char receive, unsigned char functionid, const unsigned char *send, unsigned char *buffer, int buffersize) { int nbytes; - if (verbose >= MSG_TRACE) { + if(verbose >= MSG_TRACE) { pmsg_trace("usbasp_transmit(\"%s\", 0x%02x, 0x%02x, 0x%02x, 0x%02x)\n", usbasp_get_funcname(functionid), send[0], send[1], send[2], send[3]); - if (!receive && buffersize > 0) { + if(!receive && buffersize > 0) { int i; + imsg_trace(" => "); - for (i = 0; i < buffersize; i++) - msg_trace("[%02x] ", buffer[i]); + for(i = 0; i < buffersize; i++) + msg_trace("[%02x] ", buffer[i]); msg_trace("\n"); } } #ifdef USE_LIBUSB_1_0 - nbytes = libusb_control_transfer(PDATA(pgm)->usbhandle, - (LIBUSB_REQUEST_TYPE_VENDOR | LIBUSB_RECIPIENT_DEVICE | (receive << 7)) & 0xff, - functionid & 0xff, - ((send[1] << 8) | send[0]) & 0xffff, - ((send[3] << 8) | send[2]) & 0xffff, - buffer, - buffersize & 0xffff, - 5000); - if(nbytes < 0){ + nbytes = libusb_control_transfer(my.usbhandle, + (LIBUSB_REQUEST_TYPE_VENDOR | LIBUSB_RECIPIENT_DEVICE | (receive << 7)) & 0xff, + functionid & 0xff, + ((send[1] << 8) | send[0]) & 0xffff, ((send[3] << 8) | send[2]) & 0xffff, buffer, buffersize & 0xffff, 5000); + if(nbytes < 0) { pmsg_ext_error("%s\n", errstr(pgm, nbytes)); return -1; } #else - nbytes = usb_control_msg(PDATA(pgm)->usbhandle, - USB_TYPE_VENDOR | USB_RECIP_DEVICE | (receive << 7), - functionid, - (send[1] << 8) | send[0], - (send[3] << 8) | send[2], - (char *)buffer, buffersize, - 5000); - if(nbytes < 0){ + nbytes = usb_control_msg(my.usbhandle, + USB_TYPE_VENDOR | USB_RECIP_DEVICE | (receive << 7), + functionid, (send[1] << 8) | send[0], (send[3] << 8) | send[2], (char *) buffer, buffersize, 5000); + if(nbytes < 0) { pmsg_error("%s\n", usb_strerror()); return -1; } #endif - if (verbose >= MSG_TRACE && receive && nbytes > 0) { + if(verbose >= MSG_TRACE && receive && nbytes > 0) { int i; + imsg_trace("<= "); - for (i = 0; i < nbytes; i++) + for(i = 0; i < nbytes; i++) msg_trace("[%02x] ", buffer[i]); msg_trace("\n"); } @@ -401,234 +422,242 @@ static int check_for_port_argument_match(const char *port, char *bus, char *devi pmsg_debug("%s(): found USBasp, bus:device: %s:%s, serial_number: %s\n", __func__, bus, device, serial_num); const size_t usb_len = strlen("usb"); + if(str_starts(port, "usb") && ':' == port[usb_len]) { port += usb_len + 1; char *colon_pointer = strchr(port, ':'); - if (colon_pointer) { + + if(colon_pointer) { // Value contains ':' character. Compare with bus/device. - if (strncmp(port, bus, colon_pointer - port)) + if(strncmp(port, bus, colon_pointer - port)) return 0; port = colon_pointer + 1; return str_eq(port, device); } - // serial number case + // Serial number case return *port && str_ends(serial_num, port); } // Invalid -P option. - return 0; + return 0; } /* - * Try to open USB device with given VID, PID, vendor and product name - * Parts of this function were taken from an example code by OBJECTIVE - * DEVELOPMENT Software GmbH (www.obdev.at) to meet conditions for - * shared VID/PID + * Try to open USB device with given VID, PID, vendor and product name Parts of + * this function were taken from an example code by OBJECTIVE DEVELOPMENT + * Software GmbH (www.obdev.at) to meet conditions for shared VID/PID */ + #ifdef USE_LIBUSB_1_0 -static int usbOpenDevice(const PROGRAMMER *pgm, libusb_device_handle **device, int vendor, +static int usbOpenDevice(const PROGRAMMER *pgm, libusb_device_handle ** device, int vendor, const char *vendorName, int product, const char *productName, const char *port) { - libusb_device_handle *handle = NULL; - int errorCode = USB_ERROR_NOTFOUND; - int j; - int r; + libusb_device_handle *handle = NULL; + int errorCode = USB_ERROR_NOTFOUND; + int j; + int r; - if(!PDATA(pgm)->USB_init){ - PDATA(pgm)->USB_init = 1; - libusb_init(&PDATA(pgm)->ctx); - } - - libusb_device **dev_list; - int dev_list_len = libusb_get_device_list(PDATA(pgm)->ctx, &dev_list); - - for (j=0; jusb_access_error = 1; - errorCode = USB_ERROR_ACCESS; - pmsg_warning("cannot open USB device: %s\n", errstr(pgm, r)); - continue; - } - errorCode = 0; - /* now check whether the names match: */ - /* if vendorName not given ignore it (any vendor matches) */ - r = libusb_get_string_descriptor_ascii(handle, descriptor.iManufacturer & 0xff, (unsigned char*)string, sizeof(string)); - if (r < 0) { - cx->usb_access_error = 1; - if ((vendorName != NULL) && (vendorName[0] != 0)) { - errorCode = USB_ERROR_IO; - pmsg_warning("cannot query manufacturer for device: %s\n", errstr(pgm, r)); - } - } else { - pmsg_notice2("seen device from vendor >%s<\n", string); - if ((vendorName != NULL) && (vendorName[0] != 0) && !str_eq(string, vendorName)) - errorCode = USB_ERROR_NOTFOUND; - } - /* if productName not given ignore it (any product matches) */ - r = libusb_get_string_descriptor_ascii(handle, descriptor.iProduct & 0xff, (unsigned char*)string, sizeof(string)); - if (r < 0) { - cx->usb_access_error = 1; - if ((productName != NULL) && (productName[0] != 0)) { - errorCode = USB_ERROR_IO; - pmsg_warning("cannot query product for device: %s\n", errstr(pgm, r)); - } - } else { - pmsg_notice2("seen product >%s<\n", string); - if((productName != NULL) && (productName[0] != 0) && !str_eq(string, productName)) - errorCode = USB_ERROR_NOTFOUND; - } - if (errorCode == 0) { - if(!str_eq(port, "usb")) { - // -P option given - libusb_get_string_descriptor_ascii(handle, descriptor.iSerialNumber, (unsigned char*)string, sizeof(string)); - char bus_num[21]; - sprintf(bus_num, "%d", libusb_get_bus_number(dev)); - char dev_addr[21]; - sprintf(dev_addr, "%d", libusb_get_device_address(dev)); - if (!check_for_port_argument_match(port, bus_num, dev_addr, string)) - errorCode = USB_ERROR_NOTFOUND; - } - } - if (errorCode == 0) - break; - libusb_close(handle); - handle = NULL; + if(!my.USB_init) { + my.USB_init = 1; + libusb_init(&my.ctx); + } + + libusb_device **dev_list; + int dev_list_len = libusb_get_device_list(my.ctx, &dev_list); + + for(j = 0; j < dev_list_len; ++j) { + libusb_device *dev = dev_list[j]; + struct libusb_device_descriptor descriptor; + + libusb_get_device_descriptor(dev, &descriptor); + if(descriptor.idVendor == vendor && descriptor.idProduct == product) { + char string[256]; + + // We need to open the device in order to query strings + r = libusb_open(dev, &handle); + if(!handle) { + cx->usb_access_error = 1; + errorCode = USB_ERROR_ACCESS; + pmsg_warning("cannot open USB device: %s\n", errstr(pgm, r)); + continue; + } + errorCode = 0; + // Do the names match? if vendorName not given ignore it (any vendor matches) + r = libusb_get_string_descriptor_ascii(handle, descriptor.iManufacturer & 0xff, + (unsigned char *) string, sizeof(string)); + if(r < 0) { + cx->usb_access_error = 1; + if((vendorName != NULL) && (vendorName[0] != 0)) { + errorCode = USB_ERROR_IO; + pmsg_warning("cannot query manufacturer for device: %s\n", errstr(pgm, r)); } + } else { + pmsg_notice2("seen device from vendor >%s<\n", string); + if((vendorName != NULL) && (vendorName[0] != 0) && !str_eq(string, vendorName)) + errorCode = USB_ERROR_NOTFOUND; + } + // If productName not given ignore it (any product matches) + r = libusb_get_string_descriptor_ascii(handle, descriptor.iProduct & 0xff, + (unsigned char *) string, sizeof(string)); + if(r < 0) { + cx->usb_access_error = 1; + if((productName != NULL) && (productName[0] != 0)) { + errorCode = USB_ERROR_IO; + pmsg_warning("cannot query product for device: %s\n", errstr(pgm, r)); + } + } else { + pmsg_notice2("seen product >%s<\n", string); + if((productName != NULL) && (productName[0] != 0) && !str_eq(string, productName)) + errorCode = USB_ERROR_NOTFOUND; + } + if(errorCode == 0) { + if(!str_eq(port, "usb")) { + // -P option given + libusb_get_string_descriptor_ascii(handle, descriptor.iSerialNumber, + (unsigned char *) string, sizeof(string)); + char bus_num[21]; + + sprintf(bus_num, "%d", libusb_get_bus_number(dev)); + char dev_addr[21]; + + sprintf(dev_addr, "%d", libusb_get_device_address(dev)); + if(!check_for_port_argument_match(port, bus_num, dev_addr, string)) + errorCode = USB_ERROR_NOTFOUND; + } + } + if(errorCode == 0) + break; + libusb_close(handle); + handle = NULL; } - libusb_free_device_list(dev_list,1); - if (handle != NULL){ - errorCode = 0; - *device = handle; - } - return errorCode; + } + libusb_free_device_list(dev_list, 1); + if(handle != NULL) { + errorCode = 0; + *device = handle; + } + return errorCode; } #else -static int usbOpenDevice(const PROGRAMMER *pgm, usb_dev_handle **device, int vendor, +static int usbOpenDevice(const PROGRAMMER *pgm, usb_dev_handle ** device, int vendor, const char *vendorName, int product, const char *productName, const char *port) { - struct usb_bus * bus; - struct usb_device * dev; - usb_dev_handle * handle = NULL; - int errorCode = USB_ERROR_NOTFOUND; + struct usb_bus *bus; + struct usb_device *dev; + usb_dev_handle *handle = NULL; + int errorCode = USB_ERROR_NOTFOUND; - if(!PDATA(pgm)->USB_init) { - PDATA(pgm)->USB_init = 1; - usb_init(); - } - usb_find_busses(); - usb_find_devices(); - for(bus=usb_get_busses(); bus; bus=bus->next){ - for(dev=bus->devices; dev; dev=dev->next){ - if(dev->descriptor.idVendor == vendor && - dev->descriptor.idProduct == product){ - char string[256]; - int len; - /* we need to open the device in order to query strings */ - handle = usb_open(dev); - if(!handle){ - cx->usb_access_error = 1; - errorCode = USB_ERROR_ACCESS; - pmsg_warning("cannot open USB device: %s\n", usb_strerror()); - continue; - } - errorCode = 0; - /* now check whether the names match: */ - /* if vendorName not given ignore it (any vendor matches) */ - len = usb_get_string_simple(handle, dev->descriptor.iManufacturer, - string, sizeof(string)); - if(len < 0){ - cx->usb_access_error = 1; - if ((vendorName != NULL) && (vendorName[0] != 0)) { - errorCode = USB_ERROR_IO; - pmsg_warning("cannot query manufacturer for device: %s\n", usb_strerror()); - } - } else { - pmsg_notice2("seen device from vendor >%s<\n", string); - if((vendorName != NULL) && (vendorName[0] != 0) && !str_eq(string, vendorName)) - errorCode = USB_ERROR_NOTFOUND; - } - /* if productName not given ignore it (any product matches) */ - len = usb_get_string_simple(handle, dev->descriptor.iProduct, - string, sizeof(string)); - if(len < 0){ - cx->usb_access_error = 1; - if ((productName != NULL) && (productName[0] != 0)) { - errorCode = USB_ERROR_IO; - pmsg_warning("cannot query product for device: %s\n", usb_strerror()); - } - } else { - pmsg_notice2("seen product >%s<\n", string); - if((productName != NULL) && (productName[0] != 0) && !str_eq(string, productName)) - errorCode = USB_ERROR_NOTFOUND; - } - if (errorCode == 0) { - if(!str_eq(port, "usb")) { - // -P option given - usb_get_string_simple(handle, dev->descriptor.iSerialNumber, - string, sizeof(string)); - if (!check_for_port_argument_match(port, bus->dirname, dev->filename, string)) - errorCode = USB_ERROR_NOTFOUND; - } - } - if (errorCode == 0) - break; - usb_close(handle); - handle = NULL; - } + if(!my.USB_init) { + my.USB_init = 1; + usb_init(); + } + usb_find_busses(); + usb_find_devices(); + for(bus = usb_get_busses(); bus; bus = bus->next) { + for(dev = bus->devices; dev; dev = dev->next) { + if(dev->descriptor.idVendor == vendor && dev->descriptor.idProduct == product) { + char string[256]; + int len; + + // We need to open the device in order to query strings + handle = usb_open(dev); + if(!handle) { + cx->usb_access_error = 1; + errorCode = USB_ERROR_ACCESS; + pmsg_warning("cannot open USB device: %s\n", usb_strerror()); + continue; } - if(handle) - break; - } - if(handle != NULL){ errorCode = 0; - *device = handle; + // Do the names match? If vendorName not given ignore it (any vendor matches) + len = usb_get_string_simple(handle, dev->descriptor.iManufacturer, string, sizeof(string)); + if(len < 0) { + cx->usb_access_error = 1; + if((vendorName != NULL) && (vendorName[0] != 0)) { + errorCode = USB_ERROR_IO; + pmsg_warning("cannot query manufacturer for device: %s\n", usb_strerror()); + } + } else { + pmsg_notice2("seen device from vendor >%s<\n", string); + if((vendorName != NULL) && (vendorName[0] != 0) && !str_eq(string, vendorName)) + errorCode = USB_ERROR_NOTFOUND; + } + // If productName not given ignore it (any product matches) + len = usb_get_string_simple(handle, dev->descriptor.iProduct, string, sizeof(string)); + if(len < 0) { + cx->usb_access_error = 1; + if((productName != NULL) && (productName[0] != 0)) { + errorCode = USB_ERROR_IO; + pmsg_warning("cannot query product for device: %s\n", usb_strerror()); + } + } else { + pmsg_notice2("seen product >%s<\n", string); + if((productName != NULL) && (productName[0] != 0) && !str_eq(string, productName)) + errorCode = USB_ERROR_NOTFOUND; + } + if(errorCode == 0) { + if(!str_eq(port, "usb")) { + // -P option given + usb_get_string_simple(handle, dev->descriptor.iSerialNumber, string, sizeof(string)); + if(!check_for_port_argument_match(port, bus->dirname, dev->filename, string)) + errorCode = USB_ERROR_NOTFOUND; + } + } + if(errorCode == 0) + break; + usb_close(handle); + handle = NULL; + } } - return errorCode; + if(handle) + break; + } + if(handle != NULL) { + errorCode = 0; + *device = handle; + } + return errorCode; } #endif - -/* Interface - prog. */ +// Interface prog static int usbasp_open(PROGRAMMER *pgm, const char *port) { pmsg_debug("usbasp_open(\"%s\")\n", port); - /* usb_init will be done in usbOpenDevice */ + // usb_init will be done in usbOpenDevice LNODEID usbpid = lfirst(pgm->usbpid); int pid, vid; - if (usbpid) { - pid = *(int *)(ldata(usbpid)); - if (lnext(usbpid)) + + if(usbpid) { + pid = *(int *) (ldata(usbpid)); + if(lnext(usbpid)) pmsg_warning("using PID 0x%04x, ignoring remaining PIDs in list\n", pid); } else { pid = USBASP_SHARED_PID; } vid = pgm->usbvid? pgm->usbvid: USBASP_SHARED_VID; - if(usbOpenDevice(pgm, &PDATA(pgm)->usbhandle, vid, pgm->usbvendor, pid, pgm->usbproduct, port) != 0) { + if(usbOpenDevice(pgm, &my.usbhandle, vid, pgm->usbvendor, pid, pgm->usbproduct, port) != 0) { if(str_eq(pgmid, "usbasp")) { - /* check if device with old VID/PID is available */ - if(usbOpenDevice(pgm, &PDATA(pgm)->usbhandle, USBASP_OLD_VID, "www.fischl.de", - USBASP_OLD_PID, "USBasp", port) == 0) { + // Check if device with old VID/PID is available + if(usbOpenDevice(pgm, &my.usbhandle, USBASP_OLD_VID, "www.fischl.de", + USBASP_OLD_PID, "USBasp", port) == 0) { + cx->usb_access_error = 0; - /* found USBasp with old IDs */ + // Found USBasp with old IDs pmsg_error("found USB device USBasp with old VID/PID; please update firmware of USBasp\n"); - return 0; + return 0; } - /* original USBasp is specified in config file, so no need to check it again here */ - /* no alternative found => fall through to generic error message */ + /* + * original USBasp is specified in config file, so no need to check it + * again here; no alternative found => fall through to generic error + * message + */ } pmsg_error("cannot find USB device with vid=0x%x pid=0x%x", vid, pid); - if (pgm->usbvendor[0] != 0) { - msg_error(" vendor='%s'", pgm->usbvendor); + if(pgm->usbvendor[0] != 0) { + msg_error(" vendor='%s'", pgm->usbvendor); } - if (pgm->usbproduct[0] != 0) { - msg_error(" product='%s'", pgm->usbproduct); + if(pgm->usbproduct[0] != 0) { + msg_error(" product='%s'", pgm->usbproduct); } msg_error("\n"); return -1; @@ -637,35 +666,34 @@ static int usbasp_open(PROGRAMMER *pgm, const char *port) { return 0; } -static void usbasp_close(PROGRAMMER * pgm) -{ +static void usbasp_close(PROGRAMMER *pgm) { pmsg_debug("usbasp_close()\n"); - if (PDATA(pgm)->usbhandle!=NULL) { + if(my.usbhandle != NULL) { unsigned char temp[4]; + memset(temp, 0, sizeof(temp)); - if (PDATA(pgm)->use_tpi) { - usbasp_transmit(pgm, 1, USBASP_FUNC_TPI_DISCONNECT, temp, temp, sizeof(temp)); + if(my.use_tpi) { + usbasp_transmit(pgm, 1, USBASP_FUNC_TPI_DISCONNECT, temp, temp, sizeof(temp)); } else { - usbasp_transmit(pgm, 1, USBASP_FUNC_DISCONNECT, temp, temp, sizeof(temp)); + usbasp_transmit(pgm, 1, USBASP_FUNC_DISCONNECT, temp, temp, sizeof(temp)); } #ifdef USE_LIBUSB_1_0 - libusb_close(PDATA(pgm)->usbhandle); + libusb_close(my.usbhandle); #else - usb_close(PDATA(pgm)->usbhandle); + usb_close(my.usbhandle); #endif } + #ifdef USE_LIBUSB_1_0 - libusb_exit(PDATA(pgm)->ctx); + libusb_exit(my.ctx); #else - /* nothing for usb 0.1 ? */ + // Nothing for usb 0.1? #endif } - -/* Dummy functions */ static void usbasp_disable(const PROGRAMMER *pgm) { return; } @@ -678,78 +706,65 @@ static void usbasp_display(const PROGRAMMER *pgm, const char *p) { return; } - - -// @@@ - -/* Universal functions: for both SPI and TPI */ +// Universal functions: for both SPI and TPI static int usbasp_initialize(const PROGRAMMER *pgm, const AVRPART *p) { unsigned char temp[4]; unsigned char res[4]; - struct pdata *pdata = PDATA(pgm); + struct pdata *pdata = &my; pmsg_debug("usbasp_initialize()\n"); - /* get capabilities */ + // Get capabilities memset(temp, 0, sizeof(temp)); - if(usbasp_transmit(pgm, 1, USBASP_FUNC_GETCAPABILITIES, temp, res, sizeof(res)) == 4) - pdata->capabilities = res[0] | ((unsigned int)res[1] << 8) | ((unsigned int)res[2] << 16) | ((unsigned int)res[3] << 24); - else - pdata->capabilities = 0; - - pdata->use_tpi = (pdata->capabilities & USBASP_CAP_TPI) && (p->prog_modes & PM_TPI); - // query support for 3 MHz SCK in UsbAsp-flash firmware - // https://github.com/nofeletru/UsbAsp-flash - pdata->sck_3mhz = ((pdata->capabilities & USBASP_CAP_3MHZ) != 0) ? 1 :0; - - if(pdata->use_tpi) - { - /* calc tpiclk delay */ - int dly = 1500000.0 * pgm->bitclock; + pdata->capabilities = usbasp_transmit(pgm, 1, USBASP_FUNC_GETCAPABILITIES, temp, res, sizeof(res)) == 4? + res[0] | ((unsigned int) res[1] << 8) | ((unsigned int) res[2] << 16) | ((unsigned int) res[3] << 24): 0; + + pdata->use_tpi = (pdata->capabilities & USBASP_CAP_TPI) && is_tpi(p); + // Query support for 3 MHz SCK in UsbAsp-flash firmware https://github.com/nofeletru/UsbAsp-flash + pdata->sck_3mhz = ((pdata->capabilities & USBASP_CAP_3MHZ) != 0)? 1: 0; + + if(pdata->use_tpi) { + // Calc tpiclk delay + int dly = 1500000.0*pgm->bitclock; + if(dly < 1) - dly = 1; + dly = 1; else if(dly > 2047) - dly = 2047; + dly = 2047; temp[0] = dly; temp[1] = dly >> 8; - /* connect */ + // Connect usbasp_transmit(pgm, 1, USBASP_FUNC_TPI_CONNECT, temp, res, sizeof(res)); - } - else - { - /* set sck period */ + } else { + // Set sck period pgm->set_sck_period(pgm, pgm->bitclock); - /* connect to target device */ + // Connect to target device usbasp_transmit(pgm, 1, USBASP_FUNC_CONNECT, temp, res, sizeof(res)); } - /* wait, so device is ready to receive commands */ + // Wait, so device is ready to receive commands usleep(100000); return pgm->program_enable(pgm, p); } -/* SPI specific functions */ -static int usbasp_spi_cmd(const PROGRAMMER *pgm, const unsigned char *cmd, - unsigned char *res) -{ +// SPI specific functions +static int usbasp_spi_cmd(const PROGRAMMER *pgm, const unsigned char *cmd, unsigned char *res) { pmsg_debug("usbasp_spi_cmd(0x%02x, 0x%02x, 0x%02x, 0x%02x)%s", cmd[0], cmd[1], cmd[2], cmd[3], verbose >= MSG_TRACE? " ...\n": ""); - int nbytes = - usbasp_transmit(pgm, 1, USBASP_FUNC_TRANSMIT, cmd, res, 4); + int nbytes = usbasp_transmit(pgm, 1, USBASP_FUNC_TRANSMIT, cmd, res, 4); - if(nbytes != 4){ + if(nbytes != 4) { msg_debug("\n"); pmsg_error("wrong response size\n"); return -1; } pmsg_trace("usbasp_spi_cmd()"); - msg_debug(" => 0x%02x, 0x%02x, 0x%02x, 0x%02x\n", - res[0], res[1], res[2], res[3]); + msg_debug(" => 0x%02x, 0x%02x, 0x%02x, 0x%02x\n", res[0], res[1], res[2], res[3]); return 0; } @@ -757,6 +772,7 @@ static int usbasp_spi_cmd(const PROGRAMMER *pgm, const unsigned char *cmd, static int usbasp_spi_program_enable(const PROGRAMMER *pgm, const AVRPART *p) { unsigned char res[4]; unsigned char cmd[4]; + memset(cmd, 0, sizeof(cmd)); memset(res, 0, sizeof(res)); @@ -764,10 +780,9 @@ static int usbasp_spi_program_enable(const PROGRAMMER *pgm, const AVRPART *p) { pmsg_debug("usbasp_program_enable()\n"); - int nbytes = - usbasp_transmit(pgm, 1, USBASP_FUNC_ENABLEPROG, cmd, res, sizeof(res)); + int nbytes = usbasp_transmit(pgm, 1, USBASP_FUNC_ENABLEPROG, cmd, res, sizeof(res)); - if ((nbytes != 1) | (res[0] != 0)) { + if((nbytes != 1) | (res[0] != 0)) { pmsg_error("program enable: target does not answer (0x%02x)\n", res[0]); return -1; } @@ -781,7 +796,7 @@ static int usbasp_spi_chip_erase(const PROGRAMMER *pgm, const AVRPART *p) { pmsg_debug("usbasp_chip_erase()\n"); - if (p->op[AVR_OP_CHIP_ERASE] == NULL) { + if(p->op[AVR_OP_CHIP_ERASE] == NULL) { pmsg_error("chip erase instruction not defined for part %s\n", p->desc); return -1; } @@ -808,29 +823,30 @@ static int usbasp_spi_paged_load(const PROGRAMMER *pgm, const AVRPART *p, const pmsg_debug("usbasp_program_paged_load(\"%s\", 0x%x, %d)\n", m->desc, address, n_bytes); - if (mem_is_flash(m)) { + if(mem_is_flash(m)) { function = USBASP_FUNC_READFLASH; - } else if (mem_is_eeprom(m)) { + } else if(mem_is_eeprom(m)) { function = USBASP_FUNC_READEEPROM; } else { return -2; } - /* set blocksize depending on sck frequency */ - if ((PDATA(pgm)->sckfreq_hz > 0) && (PDATA(pgm)->sckfreq_hz < 10000)) { - blocksize = USBASP_READBLOCKSIZE / 10; + // Set blocksize depending on sck frequency + if((my.sckfreq_hz > 0) && (my.sckfreq_hz < 10000)) { + blocksize = USBASP_READBLOCKSIZE/10; } else { - blocksize = USBASP_READBLOCKSIZE; + blocksize = USBASP_READBLOCKSIZE; } - while (wbytes) { - if (wbytes <= blocksize) { + while(wbytes) { + if(wbytes <= blocksize) { blocksize = wbytes; } wbytes -= blocksize; - /* set address (new mode) - if firmware on usbasp support newmode, then they use address from this command */ + // Set address (new mode) - if firmware on usbasp support newmode, then they use address from this command unsigned char temp[4]; + memset(temp, 0, sizeof(temp)); cmd[0] = address & 0xFF; cmd[1] = address >> 8; @@ -839,16 +855,16 @@ static int usbasp_spi_paged_load(const PROGRAMMER *pgm, const AVRPART *p, const usbasp_transmit(pgm, 1, USBASP_FUNC_SETLONGADDRESS, cmd, temp, sizeof(temp)); /* send command with address (compatibility mode) - if firmware on - usbasp doesn't support newmode, then they use address from this */ + usbasp doesn't support newmode, then they use address from this */ cmd[0] = address & 0xFF; cmd[1] = address >> 8; - // for compatibility - previous version of usbasp.c doesn't initialize this fields (firmware ignore it) + // For compatibility: previous version of usbasp.c has not initializes these fields (as FW ignored them) cmd[2] = 0; cmd[3] = 0; n = usbasp_transmit(pgm, 1, function, cmd, buffer, blocksize); - if (n != blocksize) { + if(n != blocksize) { pmsg_error("wrong reading bytes %x\n", n); return -3; } @@ -873,32 +889,32 @@ static int usbasp_spi_paged_write(const PROGRAMMER *pgm, const AVRPART *p, const pmsg_debug("usbasp_program_paged_write(\"%s\", 0x%x, %d)\n", m->desc, address, n_bytes); - if (mem_is_flash(m)) { + if(mem_is_flash(m)) { function = USBASP_FUNC_WRITEFLASH; - } else if (mem_is_eeprom(m)) { + } else if(mem_is_eeprom(m)) { function = USBASP_FUNC_WRITEEEPROM; } else { return -2; } - /* set blocksize depending on sck frequency */ - if ((PDATA(pgm)->sckfreq_hz > 0) && (PDATA(pgm)->sckfreq_hz < 10000)) { - blocksize = USBASP_WRITEBLOCKSIZE / 10; + // Set blocksize depending on sck frequency + if((my.sckfreq_hz > 0) && (my.sckfreq_hz < 10000)) { + blocksize = USBASP_WRITEBLOCKSIZE/10; } else { - blocksize = USBASP_WRITEBLOCKSIZE; + blocksize = USBASP_WRITEBLOCKSIZE; } - while (wbytes) { + while(wbytes) { - if (wbytes <= blocksize) { + if(wbytes <= blocksize) { blocksize = wbytes; } wbytes -= blocksize; - /* set address (new mode) - if firmware on usbasp support newmode, then - they use address from this command */ + they use address from this command */ unsigned char temp[4]; + memset(temp, 0, sizeof(temp)); cmd[0] = address & 0xFF; cmd[1] = address >> 8; @@ -907,22 +923,21 @@ static int usbasp_spi_paged_write(const PROGRAMMER *pgm, const AVRPART *p, const usbasp_transmit(pgm, 1, USBASP_FUNC_SETLONGADDRESS, cmd, temp, sizeof(temp)); /* normal command - firmware what support newmode - use address from previous command, - firmware what doesn't support newmode - ignore previous command and use address from this command */ + firmware what doesn't support newmode - ignore previous command and use address from this command */ cmd[0] = address & 0xFF; cmd[1] = address >> 8; cmd[2] = page_size & 0xFF; - cmd[3] = (blockflags & 0x0F) + ((page_size & 0xF00) >> 4); //TP: Mega128 fix + cmd[3] = (blockflags & 0x0F) + ((page_size & 0xF00) >> 4); // TP: Mega128 fix blockflags = 0; n = usbasp_transmit(pgm, 0, function, cmd, buffer, blocksize); - if (n != blocksize) { + if(n != blocksize) { pmsg_error("wrong count at writing %x\n", n); - return -3; + return -3; } - buffer += blocksize; address += blocksize; } @@ -930,26 +945,26 @@ static int usbasp_spi_paged_write(const PROGRAMMER *pgm, const AVRPART *p, const return n_bytes; } -/* The list of SCK frequencies in Hz supported by USBasp */ +// The list of SCK frequencies in Hz supported by USBasp static const struct sckoptions usbaspSCKoptions[] = { - { USBASP_ISP_SCK_3000, 3000000 }, - { USBASP_ISP_SCK_1500, 1500000 }, - { USBASP_ISP_SCK_750, 750000 }, - { USBASP_ISP_SCK_375, 375000 }, - { USBASP_ISP_SCK_187_5, 187500 }, - { USBASP_ISP_SCK_93_75, 93750 }, - { USBASP_ISP_SCK_32, 32000 }, - { USBASP_ISP_SCK_16, 16000 }, - { USBASP_ISP_SCK_8, 8000 }, - { USBASP_ISP_SCK_4, 4000 }, - { USBASP_ISP_SCK_2, 2000 }, - { USBASP_ISP_SCK_1, 1000 }, - { USBASP_ISP_SCK_0_5, 500 } + {USBASP_ISP_SCK_3000, 3000000}, + {USBASP_ISP_SCK_1500, 1500000}, + {USBASP_ISP_SCK_750, 750000}, + {USBASP_ISP_SCK_375, 375000}, + {USBASP_ISP_SCK_187_5, 187500}, + {USBASP_ISP_SCK_93_75, 93750}, + {USBASP_ISP_SCK_32, 32000}, + {USBASP_ISP_SCK_16, 16000}, + {USBASP_ISP_SCK_8, 8000}, + {USBASP_ISP_SCK_4, 4000}, + {USBASP_ISP_SCK_2, 2000}, + {USBASP_ISP_SCK_1, 1000}, + {USBASP_ISP_SCK_0_5, 500} }; /* * Set sck period (in seconds) - * Find next possible sck period and write it to the programmer. + * Find next possible sck period and write it to the programmer */ static int usbasp_spi_set_sck_period(const PROGRAMMER *pgm, double sckperiod) { char clockoption = USBASP_ISP_SCK_AUTO; @@ -961,39 +976,39 @@ static int usbasp_spi_set_sck_period(const PROGRAMMER *pgm, double sckperiod) { memset(cmd, 0, sizeof(cmd)); memset(res, 0, sizeof(res)); - /* reset global sck frequency to auto */ - PDATA(pgm)->sckfreq_hz = 0; - - if (sckperiod == 0) { - /* auto sck set */ + // Reset global sck frequency to auto + my.sckfreq_hz = 0; + if(sckperiod == 0) { + // Auto sck set pmsg_notice2("auto set sck period\n"); } else { - int sckfreq = 1 / sckperiod; /* sck in Hz */ + int sckfreq = 1/sckperiod; // sck in Hz int usefreq = 0; pmsg_notice2("try to set SCK period to %g s (= %i Hz)\n", sckperiod, sckfreq); - /* Check if programmer is capable of 3 MHz SCK, if not then ommit 3 MHz setting */ + // Check if programmer is capable of 3 MHz SCK, if not then ommit 3 MHz setting size_t i; - if (PDATA(pgm)->sck_3mhz) { + + if(my.sck_3mhz) { pmsg_notice2("connected USBasp is capable of 3 MHz SCK\n"); i = 0; } else { pmsg_notice2("connected USBasp is not cabable of 3 MHz SCK\n"); i = 1; } - if (sckfreq >= usbaspSCKoptions[i].frequency) { + if(sckfreq >= usbaspSCKoptions[i].frequency) { clockoption = usbaspSCKoptions[i].id; usefreq = usbaspSCKoptions[i].frequency; } else { - /* find clock option next to given clock */ + // Find clock option next to given clock - for (; i < sizeof(usbaspSCKoptions) / sizeof(usbaspSCKoptions[0]); i++) { - if (sckfreq >= usbaspSCKoptions[i].frequency - 1) { /* subtract 1 to compensate round errors */ + for(; i < sizeof(usbaspSCKoptions)/sizeof(usbaspSCKoptions[0]); i++) { + if(sckfreq >= usbaspSCKoptions[i].frequency - 1) { // Subtract 1 to compensate rounding errors clockoption = usbaspSCKoptions[i].id; usefreq = usbaspSCKoptions[i].frequency; break; @@ -1001,18 +1016,17 @@ static int usbasp_spi_set_sck_period(const PROGRAMMER *pgm, double sckperiod) { } } - /* save used sck frequency */ - PDATA(pgm)->sckfreq_hz = usefreq; + // Save used sck frequency + my.sckfreq_hz = usefreq; pmsg_info("set SCK frequency to %i Hz\n", usefreq); } cmd[0] = clockoption; - int nbytes = - usbasp_transmit(pgm, 1, USBASP_FUNC_SETISPSCK, cmd, res, sizeof(res)); + int nbytes = usbasp_transmit(pgm, 1, USBASP_FUNC_SETISPSCK, cmd, res, sizeof(res)); - if ((nbytes != 1) | (res[0] != 0)) { + if((nbytes != 1) | (res[0] != 0)) { pmsg_error("cannot set sck period; please check for usbasp firmware update\n"); return -1; } @@ -1020,9 +1034,10 @@ static int usbasp_spi_set_sck_period(const PROGRAMMER *pgm, double sckperiod) { return 0; } -/* TPI specific functions */ +// TPI specific functions static void usbasp_tpi_send_byte(const PROGRAMMER *pgm, uint8_t b) { unsigned char temp[4]; + memset(temp, 0, sizeof(temp)); temp[0] = b; @@ -1030,13 +1045,12 @@ static void usbasp_tpi_send_byte(const PROGRAMMER *pgm, uint8_t b) { usbasp_transmit(pgm, 1, USBASP_FUNC_TPI_RAWWRITE, temp, temp, sizeof(temp)); } - static int usbasp_tpi_recv_byte(const PROGRAMMER *pgm) { unsigned char temp[4]; + memset(temp, 0, sizeof(temp)); - if(usbasp_transmit(pgm, 1, USBASP_FUNC_TPI_RAWREAD, temp, temp, sizeof(temp)) != 1) - { + if(usbasp_transmit(pgm, 1, USBASP_FUNC_TPI_RAWREAD, temp, temp, sizeof(temp)) != 1) { pmsg_error("wrong response size\n"); return -1; } @@ -1044,14 +1058,12 @@ static int usbasp_tpi_recv_byte(const PROGRAMMER *pgm) { return temp[0]; } - static int usbasp_tpi_nvm_waitbusy(const PROGRAMMER *pgm) { int retry; pmsg_debug("usbasp_tpi_nvm_waitbusy() ..."); - for(retry=50; retry>0; retry--) - { + for(retry = 50; retry > 0; retry--) { usbasp_tpi_send_byte(pgm, TPI_OP_SIN(NVMCSR)); if(usbasp_tpi_recv_byte(pgm) & NVMCSR_BSY) continue; @@ -1076,11 +1088,11 @@ static int usbasp_tpi_program_enable(const PROGRAMMER *pgm, const AVRPART *p) { pmsg_debug("usbasp_tpi_program_enable()\n"); - /* change guard time */ + // Change guard time usbasp_tpi_send_byte(pgm, TPI_OP_SSTCS(TPIPCR)); usbasp_tpi_send_byte(pgm, TPIPCR_GT_2b); - /* send SKEY */ + // Send SKEY usbasp_tpi_send_byte(pgm, 0xE0); usbasp_tpi_send_byte(pgm, 0xFF); usbasp_tpi_send_byte(pgm, 0x88); @@ -1091,9 +1103,8 @@ static int usbasp_tpi_program_enable(const PROGRAMMER *pgm, const AVRPART *p) { usbasp_tpi_send_byte(pgm, 0x89); usbasp_tpi_send_byte(pgm, 0x12); - /* check if device is ready */ - for(retry=0; retry<10; retry++) - { + // Check if device is ready + for(retry = 0; retry < 10; retry++) { usbasp_tpi_send_byte(pgm, TPI_OP_SLDCS(TPIIR)); if(usbasp_tpi_recv_byte(pgm) != 0x80) continue; @@ -1102,8 +1113,7 @@ static int usbasp_tpi_program_enable(const PROGRAMMER *pgm, const AVRPART *p) { continue; break; } - if(retry >= 10) - { + if(retry >= 10) { pmsg_error("program enable, target does not answer\n"); return -1; } @@ -1116,15 +1126,15 @@ static int usbasp_tpi_chip_erase(const PROGRAMMER *pgm, const AVRPART *p) { int pr_1; int nvm_cmd; - switch (PDATA(pgm)->section_e) { - /* Config bits section erase */ + switch(my.section_e) { + // Config bits section erase case 1: pr_0 = 0x41; pr_1 = 0x3F; nvm_cmd = NVMCMD_SECTION_ERASE; pmsg_debug("usbasp_tpi_chip_erase() - section erase\n"); break; - /* Chip erase (flash only) */ + // Chip erase (flash only) default: pr_0 = 0x01; pr_1 = 0x40; @@ -1133,15 +1143,15 @@ static int usbasp_tpi_chip_erase(const PROGRAMMER *pgm, const AVRPART *p) { break; } - /* Set PR */ + // Set PR usbasp_tpi_send_byte(pgm, TPI_OP_SSTPR(0)); usbasp_tpi_send_byte(pgm, pr_0); usbasp_tpi_send_byte(pgm, TPI_OP_SSTPR(1)); usbasp_tpi_send_byte(pgm, pr_1); - /* select what been erase */ + // Select what been erase usbasp_tpi_send_byte(pgm, TPI_OP_SOUT(NVMCMD)); usbasp_tpi_send_byte(pgm, nvm_cmd); - /* dummy write */ + // Dummy write usbasp_tpi_send_byte(pgm, TPI_OP_SST_INC); usbasp_tpi_send_byte(pgm, 0x00); usbasp_tpi_nvm_waitbusy(pgm); @@ -1156,35 +1166,32 @@ static int usbasp_tpi_paged_load(const PROGRAMMER *pgm, const AVRPART *p, const unsigned int page_size, unsigned int addr, unsigned int n_bytes) { unsigned char cmd[4]; - unsigned char* dptr; + unsigned char *dptr; int read, clen, n; uint16_t pr; - pmsg_debug("usbasp_tpi_paged_load(\"%s\", 0x%0x, %d)\n", m->desc, addr, n_bytes); dptr = addr + m->buf; pr = addr + m->offset; read = 0; - while(read < (int) n_bytes) - { + while(read < (int) n_bytes) { clen = n_bytes - read; if(clen > 32) clen = 32; - /* prepare READBLOCK cmd */ + // Prepare READBLOCK cmd cmd[0] = pr & 0xFF; cmd[1] = pr >> 8; cmd[2] = 0; cmd[3] = 0; n = usbasp_transmit(pgm, 1, USBASP_FUNC_TPI_READBLOCK, cmd, dptr, clen); - if(n != clen) - { + if(n != clen) { pmsg_error("wrong reading bytes %x\n", n); return -3; } - + read += clen; pr += clen; dptr += clen; @@ -1197,58 +1204,55 @@ int usbasp_tpi_paged_write(const PROGRAMMER *pgm, const AVRPART *p, const AVRMEM unsigned int page_size, unsigned int addr, unsigned int n_bytes) { unsigned char cmd[4]; - unsigned char* sptr; + unsigned char *sptr; int written, clen, n; uint16_t pr; - pmsg_debug("usbasp_tpi_paged_write(\"%s\", 0x%0x, %d)\n", m->desc, addr, n_bytes); sptr = addr + m->buf; pr = addr + m->offset; written = 0; - /* must erase fuse first, TPI parts only have one fuse */ + // Must erase fuse first, TPI parts only have one fuse if(mem_is_a_fuse(m)) { // Keep fuse writing ability for backward compatibility - /* Set PR */ + // Set PR usbasp_tpi_send_byte(pgm, TPI_OP_SSTPR(0)); - usbasp_tpi_send_byte(pgm, (pr & 0xFF) | 1 ); + usbasp_tpi_send_byte(pgm, (pr & 0xFF) | 1); usbasp_tpi_send_byte(pgm, TPI_OP_SSTPR(1)); - usbasp_tpi_send_byte(pgm, (pr >> 8) ); - /* select SECTION_ERASE */ + usbasp_tpi_send_byte(pgm, (pr >> 8)); + // Select SECTION_ERASE usbasp_tpi_send_byte(pgm, TPI_OP_SOUT(NVMCMD)); usbasp_tpi_send_byte(pgm, NVMCMD_SECTION_ERASE); - /* dummy write */ + // Dummy write usbasp_tpi_send_byte(pgm, TPI_OP_SST_INC); usbasp_tpi_send_byte(pgm, 0x00); usbasp_tpi_nvm_waitbusy(pgm); } - /* Set PR to flash */ + // Set PR to flash usbasp_tpi_send_byte(pgm, TPI_OP_SSTPR(0)); - usbasp_tpi_send_byte(pgm, (pr & 0xFF) | 1 ); + usbasp_tpi_send_byte(pgm, (pr & 0xFF) | 1); usbasp_tpi_send_byte(pgm, TPI_OP_SSTPR(1)); - usbasp_tpi_send_byte(pgm, (pr >> 8) ); + usbasp_tpi_send_byte(pgm, (pr >> 8)); - while(written < (int) n_bytes) - { + while(written < (int) n_bytes) { clen = n_bytes - written; if(clen > 32) clen = 32; - /* prepare WRITEBLOCK cmd */ + // Prepare WRITEBLOCK cmd cmd[0] = pr & 0xFF; cmd[1] = pr >> 8; cmd[2] = 0; cmd[3] = 0; n = usbasp_transmit(pgm, 0, USBASP_FUNC_TPI_WRITEBLOCK, cmd, sptr, clen); - if(n != clen) - { + if(n != clen) { pmsg_error("wrong count at writing %x\n", n); return -3; } - + written += clen; pr += clen; sptr += clen; @@ -1261,7 +1265,8 @@ static int usbasp_tpi_set_sck_period(const PROGRAMMER *pgm, double sckperiod) { return 0; } -static int usbasp_tpi_read_byte(const PROGRAMMER * pgm, const AVRPART *p, const AVRMEM *m, unsigned long addr, unsigned char *value) { +static int usbasp_tpi_read_byte(const PROGRAMMER *pgm, const AVRPART *p, const AVRMEM *m, unsigned long addr, + unsigned char *value) { unsigned char cmd[4]; int n; uint16_t pr; @@ -1270,7 +1275,7 @@ static int usbasp_tpi_read_byte(const PROGRAMMER * pgm, const AVRPART *p, const pr = m->offset + addr; - /* READBLOCK */ + // READBLOCK cmd[0] = pr & 0xFF; cmd[1] = pr >> 8; cmd[2] = 0; @@ -1292,24 +1297,23 @@ static int usbasp_tpi_write_byte(const PROGRAMMER *pgm, const AVRPART *p, const pmsg_error("cannot write_byte() to %s; use paged_write()\n", m->desc); return -1; } - // Memories left: fuse and lockbits if(addr != 0) { pmsg_error("unexpected address 0x%04lx of %s memory\n", addr, m->desc); return -1; - } + } uint16_t pr = addr + m->offset; usbasp_tpi_nvm_waitbusy(pgm); // Must erase fuse first, TPI parts only have one fuse - if(mem_is_a_fuse(m)) { // Lockbits are reset during chip erase + if(mem_is_a_fuse(m)) { // Lockbits are reset during chip erase // Set pointer register to pr + 1 usbasp_tpi_send_byte(pgm, TPI_OP_SSTPR(0)); - usbasp_tpi_send_byte(pgm, (pr & 0xFF) | 1 ); + usbasp_tpi_send_byte(pgm, (pr & 0xFF) | 1); usbasp_tpi_send_byte(pgm, TPI_OP_SSTPR(1)); - usbasp_tpi_send_byte(pgm, (pr >> 8) ); + usbasp_tpi_send_byte(pgm, (pr >> 8)); // Select SECTION_ERASE usbasp_tpi_send_byte(pgm, TPI_OP_SOUT(NVMCMD)); usbasp_tpi_send_byte(pgm, NVMCMD_SECTION_ERASE); @@ -1319,12 +1323,11 @@ static int usbasp_tpi_write_byte(const PROGRAMMER *pgm, const AVRPART *p, const usbasp_tpi_nvm_waitbusy(pgm); } - // Reset pointer register to pr usbasp_tpi_send_byte(pgm, TPI_OP_SSTPR(0)); usbasp_tpi_send_byte(pgm, pr & 0xFF); usbasp_tpi_send_byte(pgm, TPI_OP_SSTPR(1)); - usbasp_tpi_send_byte(pgm, (pr >> 8) ); + usbasp_tpi_send_byte(pgm, (pr >> 8)); // Select word write usbasp_tpi_send_byte(pgm, TPI_OP_SOUT(NVMCMD)); usbasp_tpi_send_byte(pgm, NVMCMD_WORD_WRITE); @@ -1340,41 +1343,33 @@ static int usbasp_tpi_write_byte(const PROGRAMMER *pgm, const AVRPART *p, const return 0; } - void usbasp_initpgm(PROGRAMMER *pgm) { strcpy(pgm->type, "usbasp"); - /* - * mandatory functions - */ - - pgm->initialize = usbasp_initialize; - pgm->display = usbasp_display; - pgm->enable = usbasp_enable; - pgm->disable = usbasp_disable; + // Mandatory functions + pgm->initialize = usbasp_initialize; + pgm->display = usbasp_display; + pgm->enable = usbasp_enable; + pgm->disable = usbasp_disable; pgm->program_enable = usbasp_program_enable; - pgm->chip_erase = usbasp_chip_erase; - pgm->cmd = usbasp_cmd; - pgm->open = usbasp_open; - pgm->close = usbasp_close; - pgm->read_byte = usbasp_read_byte; - pgm->write_byte = usbasp_write_byte; - - /* - * optional functions - */ - - pgm->paged_write = usbasp_paged_write; - pgm->paged_load = usbasp_paged_load; - pgm->setup = usbasp_setup; - pgm->teardown = usbasp_teardown; + pgm->chip_erase = usbasp_chip_erase; + pgm->cmd = usbasp_cmd; + pgm->open = usbasp_open; + pgm->close = usbasp_close; + pgm->read_byte = usbasp_read_byte; + pgm->write_byte = usbasp_write_byte; + + // Optional functions + pgm->paged_write = usbasp_paged_write; + pgm->paged_load = usbasp_paged_load; + pgm->setup = usbasp_setup; + pgm->teardown = usbasp_teardown; pgm->set_sck_period = usbasp_set_sck_period; pgm->parseextparams = usbasp_parseextparms; } - -#else /* HAVE_LIBUSB */ +#else // HAVE_LIBUSB static int usbasp_nousb_open(PROGRAMMER *pgm, const char *name) { pmsg_error("no usb support; please compile again with libusb installed\n"); @@ -1385,9 +1380,8 @@ static int usbasp_nousb_open(PROGRAMMER *pgm, const char *name) { void usbasp_initpgm(PROGRAMMER *pgm) { strcpy(pgm->type, "usbasp"); - pgm->open = usbasp_nousb_open; + pgm->open = usbasp_nousb_open; } - -#endif /* HAVE_LIBUSB */ +#endif // HAVE_LIBUSB const char usbasp_desc[] = "USBasp programmer, see http://www.fischl.de/usbasp/"; diff --git a/src/usbasp.h b/src/usbasp.h index 853c6d900..a44c6ef9f 100644 --- a/src/usbasp.h +++ b/src/usbasp.h @@ -19,7 +19,7 @@ #ifndef usbasp_h #define usbasp_h -/* USB function call identifiers */ +// USB function call identifiers #define USBASP_FUNC_CONNECT 1 #define USBASP_FUNC_DISCONNECT 2 #define USBASP_FUNC_TRANSMIT 3 @@ -38,47 +38,47 @@ #define USBASP_FUNC_TPI_WRITEBLOCK 16 #define USBASP_FUNC_GETCAPABILITIES 127 -/* USBASP capabilities */ +// USBASP capabilities #define USBASP_CAP_TPI 0x01 -#define USBASP_CAP_3MHZ (1 << 24) // 3 MHz SCK in UsbAsp-flash firmware +#define USBASP_CAP_3MHZ (1 << 24) // 3 MHz SCK in UsbAsp-flash firmware -/* Block mode flags */ +// Block mode flags #define USBASP_BLOCKFLAG_FIRST 1 #define USBASP_BLOCKFLAG_LAST 2 -/* Block mode data size */ +// Block mode data size #define USBASP_READBLOCKSIZE 200 #define USBASP_WRITEBLOCKSIZE 200 -/* ISP SCK speed identifiers */ +// ISP SCK speed identifiers #define USBASP_ISP_SCK_AUTO 0 -#define USBASP_ISP_SCK_0_5 1 /* 500 Hz */ -#define USBASP_ISP_SCK_1 2 /* 1 kHz */ -#define USBASP_ISP_SCK_2 3 /* 2 kHz */ -#define USBASP_ISP_SCK_4 4 /* 4 kHz */ -#define USBASP_ISP_SCK_8 5 /* 8 kHz */ -#define USBASP_ISP_SCK_16 6 /* 16 kHz */ -#define USBASP_ISP_SCK_32 7 /* 32 kHz */ -#define USBASP_ISP_SCK_93_75 8 /* 93.75 kHz */ -#define USBASP_ISP_SCK_187_5 9 /* 187.5 kHz */ -#define USBASP_ISP_SCK_375 10 /* 375 kHz */ -#define USBASP_ISP_SCK_750 11 /* 750 kHz */ -#define USBASP_ISP_SCK_1500 12 /* 1.5 MHz */ -#define USBASP_ISP_SCK_3000 13 /* 3 MHz only UsbAsp-flash firmware*/ - -/* TPI instructions */ +#define USBASP_ISP_SCK_0_5 1 // 500 Hz +#define USBASP_ISP_SCK_1 2 // 1 kHz +#define USBASP_ISP_SCK_2 3 // 2 kHz +#define USBASP_ISP_SCK_4 4 // 4 kHz +#define USBASP_ISP_SCK_8 5 // 8 kHz +#define USBASP_ISP_SCK_16 6 // 16 kHz +#define USBASP_ISP_SCK_32 7 // 32 kHz +#define USBASP_ISP_SCK_93_75 8 // 93.75 kHz +#define USBASP_ISP_SCK_187_5 9 // 187.5 kHz +#define USBASP_ISP_SCK_375 10 // 375 kHz +#define USBASP_ISP_SCK_750 11 // 750 kHz +#define USBASP_ISP_SCK_1500 12 // 1.5 MHz +#define USBASP_ISP_SCK_3000 13 // 3 MHz only UsbAsp-flash firmware + +// TPI instructions #define TPI_OP_SLD 0x20 #define TPI_OP_SLD_INC 0x24 #define TPI_OP_SST 0x60 #define TPI_OP_SST_INC 0x64 #define TPI_OP_SSTPR(a) (0x68 | (a)) -#define TPI_OP_SIN(a) (0x10 | (((a)<<1)&0x60) | ((a)&0x0F) ) -#define TPI_OP_SOUT(a) (0x90 | (((a)<<1)&0x60) | ((a)&0x0F) ) -#define TPI_OP_SLDCS(a) (0x80 | ((a)&0x0F) ) -#define TPI_OP_SSTCS(a) (0xC0 | ((a)&0x0F) ) +#define TPI_OP_SIN(a) (0x10 | (((a)<<1)&0x60) | ((a)&0x0F)) +#define TPI_OP_SOUT(a) (0x90 | (((a)<<1)&0x60) | ((a)&0x0F)) +#define TPI_OP_SLDCS(a) (0x80 | ((a)&0x0F)) +#define TPI_OP_SSTCS(a) (0xC0 | ((a)&0x0F)) #define TPI_OP_SKEY 0xE0 -/* TPI control/status registers */ +// TPI control/status registers #define TPIIR 0xF #define TPIPCR 0x2 #define TPISR 0x0 @@ -99,7 +99,7 @@ // TPISR bits #define TPISR_NVMEN 0x02 -/* NVM registers */ +// NVM registers #define NVMCSR 0x32 #define NVMCMD 0x33 @@ -112,13 +112,12 @@ #define NVMCMD_SECTION_ERASE 0x14 #define NVMCMD_WORD_WRITE 0x1D - typedef struct sckoptions { int id; double frequency; } CLOCKOPTIONS; -/* USB error identifiers */ +// USB error identifiers #define USB_ERROR_NOTFOUND 1 #define USB_ERROR_ACCESS 2 #define USB_ERROR_IO 3 @@ -127,11 +126,11 @@ typedef struct sckoptions { extern "C" { #endif -extern const char usbasp_desc[]; -void usbasp_initpgm(PROGRAMMER *pgm); + extern const char usbasp_desc[]; + void usbasp_initpgm(PROGRAMMER *pgm); #ifdef __cplusplus } #endif -#endif /* usbasp_h */ +#endif diff --git a/src/usbdevs.h b/src/usbdevs.h index 7213badd0..3652eb223 100644 --- a/src/usbdevs.h +++ b/src/usbdevs.h @@ -16,9 +16,7 @@ * along with this program. If not, see . */ -/* - * defines for the USB interface - */ +// Defines for the USB interface #ifndef usbdevs_h #define usbdevs_h @@ -39,62 +37,61 @@ #define USB_DEVICE_PKOBN 0x2175 #define USB_DEVICE_PICKIT4_AVR_MODE 0x2177 #define USB_DEVICE_PICKIT4_PIC_MODE 0x9012 -#define USB_DEVICE_PICKIT4_PIC_MODE_BL 0x9017 // PICkit4 in bootloader mode +#define USB_DEVICE_PICKIT4_PIC_MODE_BL 0x9017 // PICkit4 in bootloader mode #define USB_DEVICE_PICKIT5 0x9036 #define USB_DEVICE_SNAP_AVR_MODE 0x2180 #define USB_DEVICE_SNAP_PIC_MODE 0x9018 -#define USB_DEVICE_SNAP_PIC_MODE_BL 0x9019 // SNAP in bootloader mode +#define USB_DEVICE_SNAP_PIC_MODE_BL 0x9019 // SNAP in bootloader mode #define USB_VENDOR_FTDI 0x0403 #define USB_DEVICE_FT2232 0x6010 #define USB_DEVICE_FT245 0x6001 -#define USBASP_SHARED_VID 0x16C0 /* VOTI */ -#define USBASP_SHARED_PID 0x05DC /* Obdev's free shared PID */ +#define USBASP_SHARED_VID 0x16C0 // VOTI +#define USBASP_SHARED_PID 0x05DC // Obdev's free shared PID -#define USBASP_OLD_VID 0x03EB /* ATMEL */ -#define USBASP_OLD_PID 0xC7B4 /* (unoffical) USBasp */ +#define USBASP_OLD_VID 0x03EB // ATMEL +#define USBASP_OLD_PID 0xC7B4 // (unoffical) USBasp -#define USBASP_NIBOBEE_VID 0x16C0 /* VOTI */ -#define USBASP_NIBOBEE_PID 0x092F /* NIBObee PID */ +#define USBASP_NIBOBEE_VID 0x16C0 // VOTI +#define USBASP_NIBOBEE_PID 0x092F // NIBObee PID -// these are specifically assigned to USBtiny, -// if you need your own VID and PIDs you can get them for cheap from -// www.mecanique.co.uk so please don't reuse these. Thanks! +/* + * These are specifically assigned to USBtiny, if you need your own VID and + * PIDs you can get them for cheap from www.mecanique.co.uk so please don't + * reuse these. Thanks! + */ #define USBTINY_VENDOR_DEFAULT 0x1781 #define USBTINY_PRODUCT_DEFAULT 0x0C9F - - -/* JTAGICEmkII, AVRISPmkII */ +// JTAGICEmkII, AVRISPmkII #define USBDEV_BULK_EP_WRITE_MKII 0x02 #define USBDEV_BULK_EP_READ_MKII 0x82 #define USBDEV_MAX_XFER_MKII 64 -/* STK600 */ +// STK600 #define USBDEV_BULK_EP_WRITE_STK600 0x02 #define USBDEV_BULK_EP_READ_STK600 0x83 -/* JTAGICE3 */ +// JTAGICE3 #define USBDEV_BULK_EP_WRITE_3 0x01 #define USBDEV_BULK_EP_READ_3 0x82 #define USBDEV_EVT_EP_READ_3 0x83 -/* - * The mk3 tools (type jtagice3) have a maxPayloadSize of 912. When - * accessing paged memory the access should be limited to pageSize. - * When accessing memory without pageSize the payload should be - * limited to 256. + +/* + * The mk3 tools (type jtagice3) have a maxPayloadSize of 912. When accessing + * paged memory the access should be limited to pageSize. When accessing memory + * without pageSize the payload should be limited to 256. */ #define USBDEV_MAX_XFER_3 912 #define USBDEV_MAX_XFER_3_UNPAGED 256 /* - * When operating on the JTAGICE3, usbdev_recv_frame() returns an - * indication in the upper bits of the return value whether the - * message has been received from the event endpoint rather than the - * normal conversation endpoint. + * When operating on the JTAGICE3, usbdev_recv_frame() returns an indication in + * the upper bits of the return value whether the message has been received + * from the event endpoint rather than the normal conversation endpoint. */ -#define USB_RECV_LENGTH_MASK 0x0fff /* up to 4 KiB */ +#define USB_RECV_LENGTH_MASK 0x0fff // Up to 4 KiB #define USB_RECV_FLAG_EVENT 0x1000 -#endif /* usbdevs_h */ +#endif diff --git a/src/usbtiny.c b/src/usbtiny.c index a5c53ebab..8c9df8e1c 100644 --- a/src/usbtiny.c +++ b/src/usbtiny.c @@ -38,41 +38,39 @@ #include "usbtiny.h" #include "usbdevs.h" -#if defined(HAVE_LIBUSB) // we use LIBUSB to talk to the board +#if defined(HAVE_LIBUSB) // We use LIBUSB to talk to the board + #if defined(HAVE_USB_H) -# include +#include #elif defined(HAVE_LUSB0_USB_H) -# include +#include #else -# error "libusb needs either or " +#error "libusb needs either or " #endif #include "tpi.h" -#define TPIPCR_GT_0b 0x07 -#define TPI_STOP_BITS 0x03 +#define TPIPCR_GT_0b 0x07 +#define TPI_STOP_BITS 0x03 #define LITTLE_TO_BIG_16(x) ((((x) << 8) & 0xFF00) | (((x) >> 8) & 0x00FF)) #ifndef HAVE_UINT_T -typedef unsigned int uint_t; +typedef unsigned int uint_t; #endif + #ifndef HAVE_ULONG_T -typedef unsigned long ulong_t; +typedef unsigned long ulong_t; #endif -/* - * Private data for this programmer. - */ -struct pdata -{ +struct pdata { usb_dev_handle *usb_handle; int sck_period; int chunk_size; int retries; }; -#define PDATA(pgm) ((struct pdata *)(pgm->cookie)) +#define my (*(struct pdata *) (pgm->cookie)) // ---------------------------------------------------------------------- @@ -86,17 +84,17 @@ static void usbtiny_teardown(PROGRAMMER *pgm) { } // Wrapper for simple usb_control_msg messages -static int usb_control(const PROGRAMMER *pgm, - unsigned int requestid, unsigned int val, unsigned int index, int silent) { +static int usb_control(const PROGRAMMER *pgm, unsigned int requestid, + unsigned int val, unsigned int index, int silent) { int nbytes; - nbytes = usb_control_msg( PDATA(pgm)->usb_handle, - USB_ENDPOINT_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE, - requestid, - val, index, // 2 bytes each of data - NULL, 0, // no data buffer in control message - USB_TIMEOUT ); // default timeout - if(nbytes < 0){ + + nbytes = usb_control_msg(my.usb_handle, + USB_ENDPOINT_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE, requestid, + val, index, // 2 bytes each of data + NULL, 0, // No data buffer in control message + USB_TIMEOUT); // Default timeout + if(nbytes < 0) { cx->usb_access_error = 1; if(!silent) { msg_error("\n"); @@ -109,29 +107,25 @@ static int usb_control(const PROGRAMMER *pgm, } // Wrapper for simple usb_control_msg messages to receive data from programmer -static int usb_in (const PROGRAMMER *pgm, - unsigned int requestid, unsigned int val, unsigned int index, - unsigned char* buffer, int buflen, int bitclk ) -{ +static int usb_in(const PROGRAMMER *pgm, + unsigned int requestid, unsigned int val, unsigned int index, unsigned char *buffer, int buflen, int bitclk) { int nbytes; int timeout; int i; - // calculate the amount of time we expect the process to take by - // figuring the bit-clock time and buffer size and adding to the standard USB timeout. - timeout = USB_TIMEOUT + (buflen * bitclk) / 1000; - - for (i = 0; i < 10; i++) { - nbytes = usb_control_msg( PDATA(pgm)->usb_handle, - USB_ENDPOINT_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE, - requestid, - val, index, - (char *)buffer, buflen, - timeout); - if (nbytes == buflen) { + /* + * Calculate the amount of time we expect the process to take by figuring the + * bit-clock time and buffer size and adding to the standard USB timeout. + */ + timeout = USB_TIMEOUT + (buflen*bitclk)/1000; + + for(i = 0; i < 10; i++) { + nbytes = usb_control_msg(my.usb_handle, + USB_ENDPOINT_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE, requestid, val, index, (char *) buffer, buflen, timeout); + if(nbytes == buflen) { return nbytes; } - PDATA(pgm)->retries++; + my.retries++; } msg_error("\n"); pmsg_error("%s (expected %d, got %d)\n", usb_strerror(), buflen, nbytes); @@ -139,31 +133,27 @@ static int usb_in (const PROGRAMMER *pgm, } // Report the number of retries, and reset the counter. -static void check_retries (const PROGRAMMER *pgm, const char *operation) { - if (PDATA(pgm)->retries > 0) - pmsg_info("%d retries during %s\n", PDATA(pgm)->retries, operation); - PDATA(pgm)->retries = 0; +static void check_retries(const PROGRAMMER *pgm, const char *operation) { + if(my.retries > 0) + pmsg_info("%d retries during %s\n", my.retries, operation); + my.retries = 0; } // Wrapper for simple usb_control_msg messages to send data to programmer -static int usb_out (const PROGRAMMER *pgm, - unsigned int requestid, unsigned int val, unsigned int index, - unsigned char* buffer, int buflen, int bitclk ) -{ +static int usb_out(const PROGRAMMER *pgm, + unsigned int requestid, unsigned int val, unsigned int index, unsigned char *buffer, int buflen, int bitclk) { int nbytes; int timeout; - // calculate the amount of time we expect the process to take by - // figuring the bit-clock time and buffer size and adding to the standard USB timeout. - timeout = USB_TIMEOUT + (buflen * bitclk) / 1000; - - nbytes = usb_control_msg( PDATA(pgm)->usb_handle, - USB_ENDPOINT_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE, - requestid, - val, index, - (char *)buffer, buflen, - timeout); - if (nbytes != buflen) { + /* + * Calculate the amount of time we expect the process to take by figuring the + * bit-clock time and buffer size and adding to the standard USB timeout. + */ + timeout = USB_TIMEOUT + (buflen*bitclk)/1000; + + nbytes = usb_control_msg(my.usb_handle, + USB_ENDPOINT_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE, requestid, val, index, (char *) buffer, buflen, timeout); + if(nbytes != buflen) { msg_error("\n"); pmsg_error("%s (expected %d, got %d)\n", usb_strerror(), buflen, nbytes); return -1; @@ -175,8 +165,7 @@ static int usb_out (const PROGRAMMER *pgm, /* Reverse the bits in a byte. Needed since TPI uses little-endian bit order (LSB first) whereas SPI uses big-endian (MSB first).*/ static unsigned char reverse(unsigned char b) { - return - ( (b & 0x01) << 7) + return ((b & 0x01) << 7) | ((b & 0x02) << 5) | ((b & 0x04) << 3) | ((b & 0x08) << 1) @@ -186,82 +175,79 @@ static unsigned char reverse(unsigned char b) { | ((b & 0x80) >> 7); } -/* Calculate even parity. */ -static unsigned char tpi_parity(unsigned char b) -{ +// Calculate even parity +static unsigned char tpi_parity(unsigned char b) { unsigned char parity = 0; int i; - for (i = 0; i < 8; ++i) { - if (b & 1) + for(i = 0; i < 8; ++i) { + if(b & 1) parity ^= 1; b >>= 1; } return parity; } -/* Encode 1 start bit (0), 8 data bits, 1 parity, 2 stop bits (1) - inside 16 bits. The data is padded to 16 bits by 4 leading 1s - (which will be ignored since they're not start bits). This layout - enables a write to be followed by a read. */ +/* + * Encode 1 start bit (0), 8 data bits, 1 parity, 2 stop bits (1) inside 16 + * bits. The data is padded to 16 bits by 4 leading 1s (which will be ignored + * since they're not start bits). This layout enables a write to be followed by + * a read + */ static unsigned short tpi_frame(unsigned char b) { - return LITTLE_TO_BIG_16(0xf000 | - (reverse(b) << 3) | - tpi_parity(b) << 2 | - TPI_STOP_BITS); + return LITTLE_TO_BIG_16(0xf000 | (reverse(b) << 3) | tpi_parity(b) << 2 | TPI_STOP_BITS); } -/* Transmit a single byte encapsulated in a 32-bit transfer. Unused - bits are padded with 1s. */ +// Transmit a single byte encapsulated in a 32-bit transfer; unused bits are padded with 1s static int usbtiny_tpi_tx(const PROGRAMMER *pgm, unsigned char b0) { unsigned char res[4]; - if (usb_in(pgm, USBTINY_SPI, tpi_frame(b0), 0xffff, - res, sizeof(res), 8 * sizeof(res) * PDATA(pgm)->sck_period) < 0) + if(usb_in(pgm, USBTINY_SPI, tpi_frame(b0), 0xffff, res, sizeof(res), 8*sizeof(res)*my.sck_period) < 0) return -1; msg_debug("CMD_TPI_TX: [0x%02x]\n", b0); return 1; } -/* Transmit a two bytes encapsulated in a 32-bit transfer. Unused - bits are padded with 1s. */ -static int usbtiny_tpi_txtx(const PROGRAMMER *pgm, - unsigned char b0, unsigned char b1) -{ +// Transmit a two bytes encapsulated in a 32-bit transfer; unused bits are padded with 1s +static int usbtiny_tpi_txtx(const PROGRAMMER *pgm, unsigned char b0, unsigned char b1) { unsigned char res[4]; - if (usb_in(pgm, USBTINY_SPI, tpi_frame(b0), tpi_frame(b1), - res, sizeof(res), 8 * sizeof(res) * PDATA(pgm)->sck_period) < 0) + if(usb_in(pgm, USBTINY_SPI, tpi_frame(b0), tpi_frame(b1), res, sizeof(res), + 8*sizeof(res)*my.sck_period) < 0) { + return -1; + } msg_debug("CMD_TPI_TX_TX: [0x%02x 0x%02x]\n", b0, b1); return 1; } -/* Transmit a byte then receive a byte, all encapsulated in a 32-bit - transfer. Unused bits are padded with 1s. This code assumes that - the start bit of the byte being received arrives within at most 2 - TPICLKs. We ensure this by calling avr_tpi_program_enable() with - delay==TPIPCR_GT_0b. */ +/* + * Transmit a byte then receive a byte, all encapsulated in a 32-bit transfer. + * Unused bits are padded with 1s. This code assumes that the start bit of the + * byte being received arrives within at most 2 TPICLKs. We ensure this by + * calling avr_tpi_program_enable() with delay==TPIPCR_GT_0b. + */ static int usbtiny_tpi_txrx(const PROGRAMMER *pgm, unsigned char b0) { unsigned char res[4], r; short w; - if (usb_in(pgm, USBTINY_SPI, tpi_frame(b0), 0xffff, - res, sizeof(res), 8 * sizeof(res) * PDATA(pgm)->sck_period) < 0) + if(usb_in(pgm, USBTINY_SPI, tpi_frame(b0), 0xffff, res, sizeof(res), 8*sizeof(res)*my.sck_period) < 0) return -1; w = (res[2] << 8) | res[3]; - /* Look for start bit (there should be no more than two 1 bits): */ - while (w < 0) + // Look for start bit (there should be no more than two 1 bits) + while(w < 0) w <<= 1; - /* Now that we found the start bit, the top 9 bits contain the start - bit and the 8 data bits, but the latter in reverse order. */ + /* + * Now that we found the start bit, the top 9 bits contain the start bit and + * the 8 data bits, but the latter in reverse order + */ r = reverse(w >> 7); - if (tpi_parity(r) != ((w >> 6) & 1)) { + if(tpi_parity(r) != ((w >> 6) & 1)) { pmsg_error("parity bit is wrong\n"); return -1; } - if (((w >> 4) & 0x3) != TPI_STOP_BITS) { + if(((w >> 4) & 0x3) != TPI_STOP_BITS) { pmsg_error("stop bits not received correctly\n"); return -1; } @@ -270,17 +256,16 @@ static int usbtiny_tpi_txrx(const PROGRAMMER *pgm, unsigned char b0) { return r; } -// Sometimes we just need to know the SPI command for the part to perform -// a function. Here we wrap this request for an operation so that we -// can just specify the part and operation and it'll do the right stuff -// to get the information from AvrDude and send to the USBtiny -static int usbtiny_avr_op (const PROGRAMMER *pgm, const AVRPART *p, - int op, - unsigned char *res) -{ - unsigned char cmd[4]; +/* + * Sometimes we just need to know the SPI command for the part to perform a + * function. Here we wrap this request for an operation so that we can just + * specify the part and operation and it'll do the right stuff to get the + * information from AvrDude and send to the USBtiny. + */ +static int usbtiny_avr_op(const PROGRAMMER *pgm, const AVRPART *p, int op, unsigned char *res) { + unsigned char cmd[4]; - if (p->op[op] == NULL) { + if(p->op[op] == NULL) { pmsg_error("operation %d not defined for this chip\n", op); return -1; } @@ -292,69 +277,66 @@ static int usbtiny_avr_op (const PROGRAMMER *pgm, const AVRPART *p, // ---------------------------------------------------------------------- -/* Find a device with the correct VID/PID match for USBtiny */ +// Find a device with the correct VID/PID match for USBtiny static int usbtiny_open(PROGRAMMER *pgm, const char *name) { - struct usb_bus *bus; - struct usb_device *dev = 0; + struct usb_bus *bus; + struct usb_device *dev = 0; const char *bus_name = NULL; char *dev_name = NULL; int vid, pid; - // if no -P was given or '-P usb' was given + // If no -P was given or '-P usb' was given if(str_eq(name, "usb")) name = NULL; else { - // calculate bus and device names from -P option + // Calculate bus and device names from -P option const size_t usb_len = strlen("usb"); + if(str_starts(name, "usb") && ':' == name[usb_len]) { - bus_name = name + usb_len + 1; - dev_name = strchr(bus_name, ':'); - if(NULL != dev_name) - *dev_name++ = '\0'; + bus_name = name + usb_len + 1; + dev_name = strchr(bus_name, ':'); + if(NULL != dev_name) + *dev_name++ = '\0'; } } - usb_init(); // initialize the libusb system - usb_find_busses(); // have libusb scan all the usb buses available - usb_find_devices(); // have libusb scan all the usb devices available + usb_init(); // Initialize the libusb system + usb_find_busses(); // Have libusb scan all the usb buses available + usb_find_devices(); // Have libusb scan all the usb devices available - PDATA(pgm)->usb_handle = NULL; + my.usb_handle = NULL; - if (pgm->usbvid) + if(pgm->usbvid) vid = pgm->usbvid; else vid = USBTINY_VENDOR_DEFAULT; LNODEID usbpid = lfirst(pgm->usbpid); - if (usbpid) { - pid = *(int *)(ldata(usbpid)); - if (lnext(usbpid)) + + if(usbpid) { + pid = *(int *) (ldata(usbpid)); + if(lnext(usbpid)) pmsg_warning("using PID 0x%04x, ignoring remaining PIDs in list\n", pid); } else { pid = USBTINY_PRODUCT_DEFAULT; } - - - // now we iterate through all the buses and devices - for ( bus = usb_busses; bus; bus = bus->next ) { - for ( dev = bus->devices; dev; dev = dev->next ) { - if (dev->descriptor.idVendor == vid - && dev->descriptor.idProduct == pid ) { // found match? - pmsg_debug("%s(): found USBtinyISP, bus:device: %s:%s\n", __func__, bus->dirname, dev->filename); - // if -P was given, match device by device name and bus name - if(name != NULL && - (NULL == dev_name || - !str_eq(bus->dirname, bus_name) || - !str_eq(dev->filename, dev_name))) - continue; - PDATA(pgm)->usb_handle = usb_open(dev); // attempt to connect to device - - // wrong permissions or something? - if (!PDATA(pgm)->usb_handle) { - pmsg_warning("cannot open USB device: %s\n", usb_strerror()); - continue; - } + + // Now we iterate through all the buses and devices + for(bus = usb_busses; bus; bus = bus->next) { + for(dev = bus->devices; dev; dev = dev->next) { + if(dev->descriptor.idVendor == vid && dev->descriptor.idProduct == pid) { // Found match? + pmsg_debug("%s(): found USBtinyISP, bus:device: %s:%s\n", __func__, bus->dirname, dev->filename); + // If -P was given, match device by device name and bus name + if(name != NULL && (NULL == dev_name || !str_eq(bus->dirname, bus_name) || !str_eq(dev->filename, dev_name))) + continue; + my.usb_handle = usb_open(dev); // Attempt to connect to device + + // Wrong permissions or something? + if(!my.usb_handle) { + pmsg_warning("cannot open USB device: %s\n", usb_strerror()); + continue; + } } } } @@ -363,131 +345,124 @@ static int usbtiny_open(PROGRAMMER *pgm, const char *name) { pmsg_error("invalid -P %s; use -P usb:bus:device\n", name); return -1; } - if (!PDATA(pgm)->usb_handle) { - pmsg_error("cannot find USBtiny device (0x%x/0x%x)\n", vid, pid ); + if(!my.usb_handle) { + pmsg_error("cannot find USBtiny device (0x%x/0x%x)\n", vid, pid); return -1; } - return 0; // If we got here, we must have found a good USB device + return 0; // If we got here, we must have found a good USB device } -/* Clean up the handle for the usbtiny */ -static void usbtiny_close ( PROGRAMMER* pgm ) -{ - if (! PDATA(pgm)->usb_handle) { - return; // not a valid handle, bail! - } - usb_close(PDATA(pgm)->usb_handle); // ask libusb to clean up - PDATA(pgm)->usb_handle = NULL; +// Clean up the handle for the usbtiny +static void usbtiny_close(PROGRAMMER *pgm) { + if(!my.usb_handle) // Not a valid handle, bail! + return; + usb_close(my.usb_handle); // Ask libusb to clean up + my.usb_handle = NULL; } /* A simple calculator function determines the maximum size of data we can shove through a USB connection without getting errors */ -static void usbtiny_set_chunk_size (const PROGRAMMER *pgm, int period) { - PDATA(pgm)->chunk_size = CHUNK_SIZE; // start with the maximum (default) - while (PDATA(pgm)->chunk_size > 8 && period > 16) { - // Reduce the chunk size for a slow SCK to reduce - // the maximum time of a single USB transfer. - PDATA(pgm)->chunk_size >>= 1; +static void usbtiny_set_chunk_size(const PROGRAMMER *pgm, int period) { + my.chunk_size = CHUNK_SIZE; // Start with the maximum (default) + while(my.chunk_size > 8 && period > 16) { + // Reduce the chunk size for a slow SCK to reduce the maximum time of a single USB transfer + my.chunk_size >>= 1; period >>= 1; } } /* Given a SCK bit-clock speed (in useconds) we verify its an OK speed and tell the USBtiny to update itself to the new frequency */ -static int usbtiny_set_sck_period (const PROGRAMMER *pgm, double v) { - PDATA(pgm)->sck_period = (int)(v * 1e6 + 0.5); // convert from us to 'int', the 0.5 is for rounding up +static int usbtiny_set_sck_period(const PROGRAMMER *pgm, double v) { + my.sck_period = (int) (v*1e6 + 0.5); // Convert from us to int, the 0.5 is for rounding up // Make sure its not 0, as that will confuse the usbtiny - if (PDATA(pgm)->sck_period < SCK_MIN) - PDATA(pgm)->sck_period = SCK_MIN; + if(my.sck_period < SCK_MIN) + my.sck_period = SCK_MIN; // We can't go slower, due to the byte-size of the clock variable - if (PDATA(pgm)->sck_period > SCK_MAX) - PDATA(pgm)->sck_period = SCK_MAX; + if(my.sck_period > SCK_MAX) + my.sck_period = SCK_MAX; - pmsg_notice("setting SCK period to %d usec\n", - PDATA(pgm)->sck_period ); + pmsg_notice("setting SCK period to %d usec\n", my.sck_period); - // send the command to the usbtiny device. - // MEME: for at90's fix resetstate? - if (usb_control(pgm, USBTINY_POWERUP, PDATA(pgm)->sck_period, RESET_LOW, 0) < 0) + // Send the command to the usbtiny device; MEME: for at90's fix resetstate? + if(usb_control(pgm, USBTINY_POWERUP, my.sck_period, RESET_LOW, 0) < 0) return -1; - // with the new speed, we'll have to update how much data we send per usb transfer - usbtiny_set_chunk_size(pgm, PDATA(pgm)->sck_period); + // With the new speed, we'll have to update how much data we send per usb transfer + usbtiny_set_chunk_size(pgm, my.sck_period); return 0; } - -static int usbtiny_initialize (const PROGRAMMER *pgm, const AVRPART *p ) { - unsigned char res[4]; // store the response from usbtinyisp +static int usbtiny_initialize(const PROGRAMMER *pgm, const AVRPART *p) { + unsigned char res[4]; // Store the response from usbtinyisp int tries; // Check for bit-clock and tell the usbtiny to adjust itself - if (pgm->bitclock > 0.0) { + if(pgm->bitclock > 0.0) { // -B option specified: convert to valid range for sck_period usbtiny_set_sck_period(pgm, pgm->bitclock); } else { // -B option not specified: use default - PDATA(pgm)->sck_period = SCK_DEFAULT; - pmsg_notice("using SCK period of %d usec\n", PDATA(pgm)->sck_period ); - if (usb_control(pgm, USBTINY_POWERUP, - PDATA(pgm)->sck_period, RESET_LOW, 0) < 0) + my.sck_period = SCK_DEFAULT; + pmsg_notice("using SCK period of %d usec\n", my.sck_period); + if(usb_control(pgm, USBTINY_POWERUP, my.sck_period, RESET_LOW, 0) < 0) return -1; - usbtiny_set_chunk_size(pgm, PDATA(pgm)->sck_period); + usbtiny_set_chunk_size(pgm, my.sck_period); } // Let the device wake up. usleep(50000); - if (p->prog_modes & PM_TPI) { - /* Since there is a single TPIDATA line, SDO and SDI must be - linked together through a 1kOhm resistor. Verify that - everything we send on SDO gets mirrored back on SDI. */ + if(is_tpi(p)) { + /* + * Since there is a single TPIDATA line, SDO and SDI must be linked + * together through a 1kOhm resistor. Verify that everything we send on + * SDO gets mirrored back on SDI. + */ msg_debug("doing SDO-SDI link check\n"); memset(res, 0xaa, sizeof(res)); - if (usb_in(pgm, USBTINY_SPI, LITTLE_TO_BIG_16(0x1234), LITTLE_TO_BIG_16(0x5678), - res, 4, 32 * PDATA(pgm)->sck_period) < 0) { + if(usb_in(pgm, USBTINY_SPI, LITTLE_TO_BIG_16(0x1234), LITTLE_TO_BIG_16(0x5678), + res, 4, 32*my.sck_period) < 0) { + pmsg_error("usb_in() failed\n"); return -1; } - if (res[0] != 0x12 || res[1] != 0x34 || res[2] != 0x56 || res[3] != 0x78) { + if(res[0] != 0x12 || res[1] != 0x34 || res[2] != 0x56 || res[3] != 0x78) { pmsg_error("SDO->SDI check failed (got 0x%02x 0x%02x 0x%02x 0x%02x)\n" "\tplease verify that SDI is connected directly to TPIDATA and\n" - "\tSDO is connected to TPIDATA through a 1kOhm resistor\n", - res[0], res[1], res[2], res[3]); + "\tSDO is connected to TPIDATA through a 1kOhm resistor\n", res[0], res[1], res[2], res[3]); return -1; } - /* keep TPIDATA high for >= 16 clock cycles: */ - if (usb_in(pgm, USBTINY_SPI, 0xffff, 0xffff, res, 4, - 32 * PDATA(pgm)->sck_period) < 0) - { + // Keep TPIDATA high for >= 16 clock cycles: + if(usb_in(pgm, USBTINY_SPI, 0xffff, 0xffff, res, 4, 32*my.sck_period) < 0) { pmsg_error("unable to switch chip into TPI mode\n"); return -1; } } - for (tries = 0; tries < 4; ++tries) { - if (pgm->program_enable(pgm, p) >= 0) + for(tries = 0; tries < 4; ++tries) { + if(pgm->program_enable(pgm, p) >= 0) break; - // no response, RESET and try again - if(usb_control(pgm, USBTINY_POWERUP, PDATA(pgm)->sck_period, RESET_HIGH, 0) < 0 || - usb_control(pgm, USBTINY_POWERUP, PDATA(pgm)->sck_period, RESET_LOW, 0) < 0) + // No response, RESET and try again + if(usb_control(pgm, USBTINY_POWERUP, my.sck_period, RESET_HIGH, 0) < 0 || + usb_control(pgm, USBTINY_POWERUP, my.sck_period, RESET_LOW, 0) < 0) return -1; usleep(50000); } - if (tries >= 4) + if(tries >= 4) return -1; return 0; } static int usbtiny_setpin(const PROGRAMMER *pgm, int pinfunc, int value) { - /* USBtiny is not a bit bang device, but it can set RESET */ + // USBtiny is not a bit bang device, but it can set RESET if(pinfunc == PIN_AVR_RESET) { - if(usb_control(pgm, USBTINY_POWERUP, PDATA(pgm)->sck_period, value? RESET_HIGH: RESET_LOW, 0) < 0) + if(usb_control(pgm, USBTINY_POWERUP, my.sck_period, value? RESET_HIGH: RESET_LOW, 0) < 0) return -1; usleep(50000); return 0; @@ -495,10 +470,10 @@ static int usbtiny_setpin(const PROGRAMMER *pgm, int pinfunc, int value) { return -1; } -/* Tell the USBtiny to release the output pins, etc */ +// Tell the USBtiny to release the output pins, etc static void usbtiny_powerdown(const PROGRAMMER *pgm) { - if (!PDATA(pgm)->usb_handle) - return; // wasn't connected in the first place + if(!my.usb_handle) + return; // Wasn't connected in the first place usb_control(pgm, USBTINY_POWERDOWN, 0, 0, 1); } @@ -508,52 +483,50 @@ static int usbtiny_cmd(const PROGRAMMER *pgm, const unsigned char *cmd, unsigned int nbytes; // Make sure its empty so we don't read previous calls if it fails - memset(res, '\0', 4 ); + memset(res, '\0', 4); - nbytes = usb_in( pgm, USBTINY_SPI, - (cmd[1] << 8) | cmd[0], // convert to 16-bit words - (cmd[3] << 8) | cmd[2], // " - res, 4, 8 * PDATA(pgm)->sck_period ); - if (nbytes < 0) + nbytes = usb_in(pgm, USBTINY_SPI, (cmd[1] << 8) | cmd[0], // Convert to 16-bit words + (cmd[3] << 8) | cmd[2], // " + res, 4, 8*my.sck_period); + if(nbytes < 0) return -1; check_retries(pgm, "SPI command"); - // print out the data we sent and received + // Print out the data we sent and received msg_debug("CMD: [%02x %02x %02x %02x] [%02x %02x %02x %02x]\n", - cmd[0], cmd[1], cmd[2], cmd[3], - res[0], res[1], res[2], res[3] ); + cmd[0], cmd[1], cmd[2], cmd[3], res[0], res[1], res[2], res[3]); return nbytes == 4 && res[2] == cmd[1]? LIBAVRDUDE_SUCCESS: LIBAVRDUDE_GENERAL_FAILURE; } -int usbtiny_cmd_tpi(const PROGRAMMER *pgm, const unsigned char *cmd, - int cmd_len, unsigned char *res, int res_len) -{ +int usbtiny_cmd_tpi(const PROGRAMMER *pgm, const unsigned char *cmd, int cmd_len, unsigned char *res, int res_len) { unsigned char b0, b1; int tx, rx, r; - /* Transmits command two bytes at the time until we're down to 0 or - 1 command byte. Then we're either done or we transmit the final - byte optionally followed by reading 1 byte. With the current TPI - protocol, we never receive more than one byte. */ - for (tx = rx = 0; tx < cmd_len; ) { + /* + * Transmits command two bytes at the time until we're down to 0 or + * 1 command byte. Then we're either done or we transmit the final + * byte optionally followed by reading 1 byte. With the current TPI + * protocol, we never receive more than one byte. + */ + for(tx = rx = 0; tx < cmd_len;) { b0 = cmd[tx++]; - if (tx < cmd_len) { + if(tx < cmd_len) { b1 = cmd[tx++]; - if (usbtiny_tpi_txtx(pgm, b0, b1) < 0) - return -1; + if(usbtiny_tpi_txtx(pgm, b0, b1) < 0) + return -1; } else { - if (res_len > 0) { - if ((r = usbtiny_tpi_txrx(pgm, b0)) < 0) - return -1; - res[rx++] = r; + if(res_len > 0) { + if((r = usbtiny_tpi_txrx(pgm, b0)) < 0) + return -1; + res[rx++] = r; } else { - if (usbtiny_tpi_tx(pgm, b0) < 0) - return -1; + if(usbtiny_tpi_tx(pgm, b0) < 0) + return -1; } } } - if (rx < res_len) { + if(rx < res_len) { pmsg_error("unexpected cmd_len=%d/res_len=%d\n", cmd_len, res_len); return -1; } @@ -566,43 +539,44 @@ static int usbtiny_spi(const PROGRAMMER *pgm, const unsigned char *cmd, unsigned // Clear the receive buffer so we don't read old data in case of failure memset(res, 0, count); - if (count % 4) { + if(count%4) { pmsg_error("direct SPI write must be a multiple of 4 bytes for %s\n", pgm->type); return -1; } - for (i = 0; i < count; i += 4) { - if (usbtiny_cmd(pgm, cmd + i, res + i) < 0) { + for(i = 0; i < count; i += 4) { + if(usbtiny_cmd(pgm, cmd + i, res + i) < 0) { return -1; } } return 0; } -/* Send the chip-erase command */ +// Send the chip-erase command static int usbtiny_chip_erase(const PROGRAMMER *pgm, const AVRPART *p) { unsigned char res[4]; - if (p->prog_modes & PM_TPI) + if(is_tpi(p)) return avr_tpi_chip_erase(pgm, p); - if (p->op[AVR_OP_CHIP_ERASE] == NULL) { + if(p->op[AVR_OP_CHIP_ERASE] == NULL) { pmsg_error("chip erase instruction not defined for part %s\n", p->desc); return -1; } - // get the command for erasing this chip and transmit to avrdude - if (usbtiny_avr_op(pgm, p, AVR_OP_CHIP_ERASE, res) < 0) + // Get the command for erasing this chip and transmit to avrdude + if(usbtiny_avr_op(pgm, p, AVR_OP_CHIP_ERASE, res) < 0) return -1; - if(pgm->prog_modes & PM_SPM) { // Talking to bootloader directly + if(is_spm(pgm)) { // Talking to bootloader directly AVRMEM *fl = avr_locate_flash(p); + // Estimated time it takes to erase all pages in bootloader - usleep(p->chip_erase_delay * (fl? fl->num_pages: 999)); + usleep(p->chip_erase_delay*(fl? fl->num_pages: 999)); } else usleep(p->chip_erase_delay); - // prepare for further instruction + // Prepare for further instruction pgm->initialize(pgm, p); return 0; @@ -615,20 +589,16 @@ static void usbtiny_enable(PROGRAMMER *pgm, const AVRPART *p) { static void usbtiny_disable(const PROGRAMMER *pgm) { } - static void usbtiny_display(const PROGRAMMER *pgm, const char *p) { } - /* To speed up programming and reading, we do a 'chunked' read. * We request just the data itself and the USBtiny uses the SPI function * given to read in the data. Much faster than sending a 4-byte SPI request * per byte */ -static int usbtiny_paged_load (const PROGRAMMER *pgm, const AVRPART *p, const AVRMEM *m, - unsigned int page_size, - unsigned int addr, unsigned int n_bytes) -{ +static int usbtiny_paged_load(const PROGRAMMER *pgm, const AVRPART *p, const AVRMEM *m, + unsigned int page_size, unsigned int addr, unsigned int n_bytes) { unsigned int maxaddr = addr + n_bytes; int chunk, function; OPCODE *lext, *readop; @@ -642,45 +612,41 @@ static int usbtiny_paged_load (const PROGRAMMER *pgm, const AVRPART *p, const AV memset(cmd, 0, sizeof(cmd)); avr_set_bits(lext, cmd); avr_set_addr(lext, cmd, addr/2); - if(pgm->cmd(pgm, cmd, cmd+4) < 0) + if(pgm->cmd(pgm, cmd, cmd + 4) < 0) return -1; } // Byte acces as work around to correctly read flash above 64 kiB if(function == USBTINY_FLASH_READ && addr >= 0x10000) { - for(unsigned int i=0; iop[addr&1? AVR_OP_READ_HI: AVR_OP_READ_LO])) + for(unsigned int i = 0; i < n_bytes; i++, addr++) { + if(!(readop = m->op[addr & 1? AVR_OP_READ_HI: AVR_OP_READ_LO])) return -1; memset(cmd, 0, sizeof(cmd)); avr_set_bits(readop, cmd); avr_set_addr(readop, cmd, addr/2); - if(pgm->cmd(pgm, cmd, cmd+4) < 0) + if(pgm->cmd(pgm, cmd, cmd + 4) < 0) return -1; m->buf[addr] = 0; - avr_get_output(readop, cmd+4, m->buf + addr); + avr_get_output(readop, cmd + 4, m->buf + addr); } return n_bytes; } - for (; addr < maxaddr; addr += chunk) { - chunk = PDATA(pgm)->chunk_size; // start with the maximum chunk size possible - if (addr + chunk > maxaddr) { - chunk = maxaddr - addr; - } - - // Send the chunk of data to the USBtiny with the function we want - // to perform - if (usb_in(pgm, - function, // EEPROM or flash - 0, // delay between SPI commands - addr, // address in memory - m->buf + addr, // pointer to where we store data - chunk, // number of bytes - 32 * PDATA(pgm)->sck_period) // each byte gets turned into a 4-byte SPI cmd - < 0) { - // usb_in() multiplies this per byte. + for(; addr < maxaddr; addr += chunk) { + chunk = my.chunk_size; // Start with the maximum chunk size possible + if(addr + chunk > maxaddr) + chunk = maxaddr - addr; + + // Send the chunk of data to the USBtiny with the function we want to perform + if(usb_in(pgm, function, // EEPROM or flash + 0, // Delay between SPI commands + addr, // Address in memory + m->buf + addr, // Pointer to where we store data + chunk, // Number of bytes + 32*my.sck_period) < 0) { // Each byte gets turned into a 4-byte SPI cmd + // usb_in() multiplies this per byte return -1; } } @@ -695,25 +661,24 @@ static int usbtiny_paged_load (const PROGRAMMER *pgm, const AVRPART *p, const AV * per byte. */ static int usbtiny_paged_write(const PROGRAMMER *pgm, const AVRPART *p, const AVRMEM *m, - unsigned int page_size, - unsigned int addr, unsigned int n_bytes) -{ + unsigned int page_size, unsigned int addr, unsigned int n_bytes) { unsigned int maxaddr = addr + n_bytes; - int chunk; // Size of data to write at once + int chunk; // Size of data to write at once int next; - int function; // which SPI command to use - int delay; // delay required between SPI commands + int function; // Which SPI command to use + int delay; // Delay required between SPI commands // First determine what we're doing - if (mem_is_flash(m)) { + if(mem_is_flash(m)) { function = USBTINY_FLASH_WRITE; } else { function = USBTINY_EEPROM_WRITE; } delay = 0; - if (! m->paged) { + if(!m->paged) { unsigned int poll_value = (m->readback[1] << 8) | m->readback[0]; + if(!poll_value) poll_value = 0xffff; if(usb_control(pgm, USBTINY_POLL_BYTES, poll_value, 0, 0) < 0) @@ -721,32 +686,29 @@ static int usbtiny_paged_write(const PROGRAMMER *pgm, const AVRPART *p, const AV delay = m->max_write_delay; } - for (; addr < maxaddr; addr += chunk) { - // start with the max chunk size - chunk = PDATA(pgm)->chunk_size; - if (addr + chunk > maxaddr) { - chunk = maxaddr - addr; + for(; addr < maxaddr; addr += chunk) { + // Start with the max chunk size + chunk = my.chunk_size; + if(addr + chunk > maxaddr) { + chunk = maxaddr - addr; } - // we can only write a page at a time anyways - if (m->paged && chunk > (int) page_size) + // We can only write a page at a time anyways + if(m->paged && chunk > (int) page_size) chunk = page_size; - if (usb_out(pgm, - function, // Flash or EEPROM - delay, // How much to wait between each byte - addr, // Address in memory - m->buf + addr, // Pointer to data - chunk, // Number of bytes to write - 32 * PDATA(pgm)->sck_period + delay // each byte gets turned into a - // 4-byte SPI cmd usb_out() multiplies - // this per byte. Then add the cmd-delay - ) < 0) { + if(usb_out(pgm, function, // Flash or EEPROM + delay, // How much to wait between each byte + addr, // Address in memory + m->buf + addr, // Pointer to data + chunk, // Number of bytes to write + // Each byte gets turned into a 4-byte SPI cmd; usb_out() multiplies this per byte; then add the cmd-delay + 32*my.sck_period + delay) < 0) { return -1; } - next = addr + chunk; // Calculate what address we're at now - if (m->paged && (next % page_size == 0 || next == (int) maxaddr) ) { + next = addr + chunk; // Calculate what address we're at now + if(m->paged && (next%page_size == 0 || next == (int) maxaddr)) { // If we're at a page boundary, send the SPI command to flush it. avr_write_page(pgm, p, m, (unsigned long) addr); } @@ -757,7 +719,7 @@ static int usbtiny_paged_write(const PROGRAMMER *pgm, const AVRPART *p, const AV static int usbtiny_program_enable(const PROGRAMMER *pgm, const AVRPART *p) { unsigned char buf[4]; - if (p->prog_modes & PM_TPI) + if(is_tpi(p)) return avr_tpi_program_enable(pgm, p, TPIPCR_GT_0b); else return usbtiny_avr_op(pgm, p, AVR_OP_PGM_ENABLE, buf); @@ -766,33 +728,33 @@ static int usbtiny_program_enable(const PROGRAMMER *pgm, const AVRPART *p) { void usbtiny_initpgm(PROGRAMMER *pgm) { strcpy(pgm->type, "USBtiny"); - /* Mandatory Functions */ - pgm->initialize = usbtiny_initialize; - pgm->display = usbtiny_display; - pgm->enable = usbtiny_enable; - pgm->disable = usbtiny_disable; - pgm->program_enable = usbtiny_program_enable; - pgm->chip_erase = usbtiny_chip_erase; - pgm->cmd = usbtiny_cmd; - pgm->cmd_tpi = usbtiny_cmd_tpi; - pgm->open = usbtiny_open; - pgm->close = usbtiny_close; - pgm->read_byte = avr_read_byte_default; - pgm->write_byte = avr_write_byte_default; - - /* Optional Functions */ - pgm->powerup = NULL; - pgm->powerdown = usbtiny_powerdown; - pgm->paged_load = usbtiny_paged_load; - pgm->paged_write = usbtiny_paged_write; - pgm->set_sck_period = usbtiny_set_sck_period; - pgm->setup = usbtiny_setup; - pgm->teardown = usbtiny_teardown; - pgm->setpin = usbtiny_setpin; - pgm->spi = usbtiny_spi; -} - -#else /* !HAVE_LIBUSB */ + // Mandatory Functions + pgm->initialize = usbtiny_initialize; + pgm->display = usbtiny_display; + pgm->enable = usbtiny_enable; + pgm->disable = usbtiny_disable; + pgm->program_enable = usbtiny_program_enable; + pgm->chip_erase = usbtiny_chip_erase; + pgm->cmd = usbtiny_cmd; + pgm->cmd_tpi = usbtiny_cmd_tpi; + pgm->open = usbtiny_open; + pgm->close = usbtiny_close; + pgm->read_byte = avr_read_byte_default; + pgm->write_byte = avr_write_byte_default; + + // Optional Functions + pgm->powerup = NULL; + pgm->powerdown = usbtiny_powerdown; + pgm->paged_load = usbtiny_paged_load; + pgm->paged_write = usbtiny_paged_write; + pgm->set_sck_period = usbtiny_set_sck_period; + pgm->setup = usbtiny_setup; + pgm->teardown = usbtiny_teardown; + pgm->setpin = usbtiny_setpin; + pgm->spi = usbtiny_spi; +} + +#else // ! HAVE_LIBUSB // Give a proper error if we were not compiled with libusb @@ -807,7 +769,6 @@ void usbtiny_initpgm(PROGRAMMER *pgm) { pgm->open = usbtiny_nousb_open; } - -#endif /* HAVE_LIBUSB */ +#endif // HAVE_LIBUSB const char usbtiny_desc[] = "Usbtiny-type programmers incl arduinoisp, arduino_gemma and adafruit_gemma"; diff --git a/src/usbtiny.h b/src/usbtiny.h index 153d75c4b..a221a8618 100644 --- a/src/usbtiny.h +++ b/src/usbtiny.h @@ -16,53 +16,50 @@ * along with this program. If not, see . */ - #ifndef usbtiny_h #define usbtiny_h // Generic requests to the USBtiny -#define USBTINY_ECHO 0 // echo test -#define USBTINY_READ 1 // read byte (wIndex:address) -#define USBTINY_WRITE 2 // write byte (wIndex:address, wValue:value) -#define USBTINY_CLR 3 // clear bit (wIndex:address, wValue:bitno) -#define USBTINY_SET 4 // set bit (wIndex:address, wValue:bitno) +#define USBTINY_ECHO 0 // Echo test +#define USBTINY_READ 1 // Read byte (wIndex:address) +#define USBTINY_WRITE 2 // Write byte (wIndex:address, wValue:value) +#define USBTINY_CLR 3 // Clear bit (wIndex:address, wValue:bitno) +#define USBTINY_SET 4 // Set bit (wIndex:address, wValue:bitno) // Programming requests -#define USBTINY_POWERUP 5 // apply power (wValue:SCK-period, wIndex:RESET) -#define USBTINY_POWERDOWN 6 // remove power from chip -#define USBTINY_SPI 7 // issue SPI command (wValue:c1c0, wIndex:c3c2) -#define USBTINY_POLL_BYTES 8 // set poll bytes for write (wValue:p1p2) -#define USBTINY_FLASH_READ 9 // read flash (wIndex:address) -#define USBTINY_FLASH_WRITE 10 // write flash (wIndex:address, wValue:timeout) -#define USBTINY_EEPROM_READ 11 // read eeprom (wIndex:address) -#define USBTINY_EEPROM_WRITE 12 // write eeprom (wIndex:address, wValue:timeout) - - +#define USBTINY_POWERUP 5 // Apply power (wValue:SCK-period, wIndex:RESET) +#define USBTINY_POWERDOWN 6 // Remove power from chip +#define USBTINY_SPI 7 // Issue SPI command (wValue:c1c0, wIndex:c3c2) +#define USBTINY_POLL_BYTES 8 // Set poll bytes for write (wValue:p1p2) +#define USBTINY_FLASH_READ 9 // Read flash (wIndex:address) +#define USBTINY_FLASH_WRITE 10 // Write flash (wIndex:address, wValue:timeout) +#define USBTINY_EEPROM_READ 11 // Read eeprom (wIndex:address) +#define USBTINY_EEPROM_WRITE 12 // Write eeprom (wIndex:address, wValue:timeout) // Flags to indicate how to set RESET on power up -#define RESET_LOW 0 -#define RESET_HIGH 1 +#define RESET_LOW 0 +#define RESET_HIGH 1 // The SCK speed can be set by avrdude, to allow programming of slow-clocked parts -#define SCK_MIN 1 // usec delay (target clock >= 4 MHz) -#define SCK_MAX 250 // usec (target clock >= 16 kHz) -#define SCK_DEFAULT 10 // usec (target clock >= 0.4 MHz) +#define SCK_MIN 1 // usec delay (target clock >= 4 MHz) +#define SCK_MAX 250 // usec (target clock >= 16 kHz) +#define SCK_DEFAULT 10 // usec (target clock >= 0.4 MHz) // How much data, max, do we want to send in one USB packet? -#define CHUNK_SIZE 128 // must be power of 2 less than 256 +#define CHUNK_SIZE 128 // Must be power of 2 less than 256 // The default USB Timeout -#define USB_TIMEOUT 500 // msec +#define USB_TIMEOUT 500 // msec #ifdef __cplusplus extern "C" { #endif -extern const char usbtiny_desc[]; -void usbtiny_initpgm(PROGRAMMER *pgm); + extern const char usbtiny_desc[]; + void usbtiny_initpgm(PROGRAMMER *pgm); #ifdef __cplusplus } #endif -#endif /* usbtiny_h */ +#endif diff --git a/src/whereami.c b/src/whereami.c index d8ff67e00..8147905e1 100644 --- a/src/whereami.c +++ b/src/whereami.c @@ -3,7 +3,8 @@ // by Gregory Pakosz (@gpakosz) // https://github.com/gpakosz/whereami -// in case you want to #include "whereami.c" in a larger compilation unit +// In case you want to #include "whereami.c" in a larger compilation unit + #if !defined(WHEREAMI_H) #include #endif @@ -14,9 +15,11 @@ extern "C" { #if !defined(WAI_MALLOC) || !defined(WAI_FREE) || !defined(WAI_REALLOC) #include + #ifndef PATH_MAX #define PATH_MAX _MAX_PATH #endif + #include "avrdude.h" #include "libavrdude.h" #endif @@ -34,6 +37,7 @@ extern "C" { #endif #ifndef WAI_NOINLINE + #if defined(_MSC_VER) #define WAI_NOINLINE __declspec(noinline) #elif defined(__GNUC__) @@ -56,132 +60,132 @@ extern "C" { #ifndef WIN32_LEAN_AND_MEAN #define WIN32_LEAN_AND_MEAN #endif + #if defined(_MSC_VER) #pragma warning(push, 3) #endif + #include #include + #if defined(_MSC_VER) #pragma warning(pop) #endif + #include -static int WAI_PREFIX(getModulePath_)(HMODULE module, char* out, int capacity, int* dirname_length) -{ - wchar_t buffer1[MAX_PATH]; - wchar_t buffer2[MAX_PATH]; - wchar_t* path = NULL; - int length = -1; - bool ok; + static int WAI_PREFIX(getModulePath_) (HMODULE module, char *out, int capacity, int *dirname_length) { + wchar_t buffer1[MAX_PATH]; + wchar_t buffer2[MAX_PATH]; + wchar_t *path = NULL; + int length = -1; + bool ok; - for (ok = false; !ok; ok = true) - { - DWORD size; - int length_, length__; + for(ok = false; !ok; ok = true) { + DWORD size; + int length_, length__; - size = GetModuleFileNameW(module, buffer1, sizeof(buffer1) / sizeof(buffer1[0])); + size = GetModuleFileNameW(module, buffer1, sizeof(buffer1)/sizeof(buffer1[0])); - if (size == 0) - break; - else if (size == (DWORD)(sizeof(buffer1) / sizeof(buffer1[0]))) - { - DWORD size_ = size; - do - { - wchar_t* path_; + if(size == 0) + break; + else if(size == (DWORD) (sizeof(buffer1)/sizeof(buffer1[0]))) { + DWORD size_ = size; + do { + wchar_t *path_; + + path_ = (wchar_t *) WAI_REALLOC(path, sizeof(wchar_t)*size_*2); + if(!path_) + break; + size_ *= 2; + path = path_; + size = GetModuleFileNameW(module, path, size_); + } + while(size == size_); - path_ = (wchar_t*)WAI_REALLOC(path, sizeof(wchar_t) * size_ * 2); - if (!path_) + if(size == size_) break; - size_ *= 2; - path = path_; - size = GetModuleFileNameW(module, path, size_); - } - while (size == size_); + } else + path = buffer1; - if (size == size_) + if(!_wfullpath(buffer2, path, MAX_PATH)) break; - } - else - path = buffer1; - - if (!_wfullpath(buffer2, path, MAX_PATH)) - break; - length_ = (int)wcslen(buffer2); - length__ = WideCharToMultiByte(CP_UTF8, 0, buffer2, length_ , out, capacity, NULL, NULL); + length_ = (int) wcslen(buffer2); + length__ = WideCharToMultiByte(CP_UTF8, 0, buffer2, length_, out, capacity, NULL, NULL); - if (length__ == 0) - length__ = WideCharToMultiByte(CP_UTF8, 0, buffer2, length_, NULL, 0, NULL, NULL); - if (length__ == 0) - break; + if(length__ == 0) + length__ = WideCharToMultiByte(CP_UTF8, 0, buffer2, length_, NULL, 0, NULL, NULL); + if(length__ == 0) + break; - if (length__ <= capacity && dirname_length) - { - int i; + if(length__ <= capacity && dirname_length) { + int i; - for (i = length__ - 1; i >= 0; --i) - { - if (out[i] == '\\') - { - *dirname_length = i; - break; + for(i = length__ - 1; i >= 0; --i) { + if(out[i] == '\\') { + *dirname_length = i; + break; + } } } - } - length = length__; - } + length = length__; + } - if (path != buffer1) - WAI_FREE(path); + if(path != buffer1) + WAI_FREE(path); - return ok ? length : -1; -} + return ok? length: -1; + } -WAI_NOINLINE WAI_FUNCSPEC -int WAI_PREFIX(getExecutablePath)(char* out, int capacity, int* dirname_length) -{ - return WAI_PREFIX(getModulePath_)(NULL, out, capacity, dirname_length); -} + WAI_NOINLINE WAI_FUNCSPEC int WAI_PREFIX(getExecutablePath) (char *out, int capacity, int *dirname_length) { + return WAI_PREFIX(getModulePath_) (NULL, out, capacity, dirname_length); + } -WAI_NOINLINE WAI_FUNCSPEC -int WAI_PREFIX(getModulePath)(char* out, int capacity, int* dirname_length) -{ - HMODULE module; - int length = -1; + WAI_NOINLINE WAI_FUNCSPEC int WAI_PREFIX(getModulePath) (char *out, int capacity, int *dirname_length) { + HMODULE module; + int length = -1; #if defined(_MSC_VER) #pragma warning(push) #pragma warning(disable: 4054) #endif - if (GetModuleHandleEx(GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS | GET_MODULE_HANDLE_EX_FLAG_UNCHANGED_REFCOUNT, (LPCTSTR)WAI_RETURN_ADDRESS(), &module)) + + if(GetModuleHandleEx(GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS | GET_MODULE_HANDLE_EX_FLAG_UNCHANGED_REFCOUNT, + (LPCTSTR) WAI_RETURN_ADDRESS(), &module)) + #if defined(_MSC_VER) #pragma warning(pop) #endif - { - length = WAI_PREFIX(getModulePath_)(module, out, capacity, dirname_length); - } - return length; -} + { + length = WAI_PREFIX(getModulePath_) (module, out, capacity, dirname_length); + } + + return length; + } #elif defined(__linux__) || defined(__CYGWIN__) || defined(__sun) || defined(WAI_USE_PROC_SELF_EXE) #include #include #include + #if defined(__linux__) #include #else #include #endif + #ifndef __STDC_FORMAT_MACROS #define __STDC_FORMAT_MACROS #endif + #include #include #if !defined(WAI_PROC_SELF_EXE) + #if defined(__sun) #define WAI_PROC_SELF_EXE "/proc/self/path/a.out" #else @@ -189,49 +193,40 @@ int WAI_PREFIX(getModulePath)(char* out, int capacity, int* dirname_length) #endif #endif -WAI_FUNCSPEC -int WAI_PREFIX(getExecutablePath)(char* out, int capacity, int* dirname_length) -{ - char buffer[PATH_MAX]; - char* resolved = NULL; - int length = -1; - bool ok; - - for (ok = false; !ok; ok = true) - { - resolved = realpath(WAI_PROC_SELF_EXE, buffer); - if (!resolved) - break; + WAI_FUNCSPEC int WAI_PREFIX(getExecutablePath) (char *out, int capacity, int *dirname_length) { + char buffer[PATH_MAX]; + char *resolved = NULL; + int length = -1; + bool ok; - length = (int)strlen(resolved); - if (length <= capacity) - { - memcpy(out, resolved, length); + for(ok = false; !ok; ok = true) { + resolved = realpath(WAI_PROC_SELF_EXE, buffer); + if(!resolved) + break; - if (dirname_length) - { - int i; + length = (int) strlen(resolved); + if(length <= capacity) { + memcpy(out, resolved, length); - for (i = length - 1; i >= 0; --i) - { - if (out[i] == '/') - { - *dirname_length = i; - break; - } - } + if(dirname_length) { + int i; + + for(i = length - 1; i >= 0; --i) { + if(out[i] == '/') { + *dirname_length = i; + break; + } + }} } - } + } return ok? length: -1; } - return ok ? length : -1; -} - #if !defined(WAI_PROC_SELF_MAPS_RETRY) #define WAI_PROC_SELF_MAPS_RETRY 5 #endif #if !defined(WAI_PROC_SELF_MAPS) + #if defined(__sun) #define WAI_PROC_SELF_MAPS "/proc/self/map" #else @@ -244,124 +239,117 @@ int WAI_PREFIX(getExecutablePath)(char* out, int capacity, int* dirname_length) #include #include #endif -#include -WAI_NOINLINE WAI_FUNCSPEC -int WAI_PREFIX(getModulePath)(char* out, int capacity, int* dirname_length) -{ - int length = -1; - FILE* maps = NULL; +#include - for (int r = 0; r < WAI_PROC_SELF_MAPS_RETRY; ++r) - { - maps = fopen(WAI_PROC_SELF_MAPS, "r"); - if (!maps) - break; + WAI_NOINLINE WAI_FUNCSPEC int WAI_PREFIX(getModulePath) (char *out, int capacity, int *dirname_length) { + int length = -1; + FILE *maps = NULL; - for (;;) - { - char buffer[PATH_MAX < 1024 ? 1024 : PATH_MAX]; - uint64_t low, high; - char perms[5]; - uint64_t offset; - uint32_t major, minor; - char path[PATH_MAX]; - uint32_t inode; - - if (!fgets(buffer, sizeof(buffer), maps)) + for(int r = 0; r < WAI_PROC_SELF_MAPS_RETRY; ++r) { + maps = fopen(WAI_PROC_SELF_MAPS, "r"); + if(!maps) break; - if (sscanf(buffer, "%" PRIx64 "-%" PRIx64 " %s %" PRIx64 " %x:%x %u %s\n", &low, &high, perms, &offset, &major, &minor, &inode, path) == 8) - { - uint64_t addr = (uintptr_t)WAI_RETURN_ADDRESS(); - if (low <= addr && addr <= high) - { - char* resolved; + for(;;) { + char buffer[PATH_MAX < 1024? 1024: PATH_MAX]; + uint64_t low, high; + char perms[5]; + uint64_t offset; + uint32_t major, minor; + char path[PATH_MAX]; + uint32_t inode; - resolved = realpath(path, buffer); - if (!resolved) - break; + if(!fgets(buffer, sizeof(buffer), maps)) + break; - length = (int)strlen(resolved); -#if defined(__ANDROID__) || defined(ANDROID) - if (length > 4 - &&buffer[length - 1] == 'k' - &&buffer[length - 2] == 'p' - &&buffer[length - 3] == 'a' - &&buffer[length - 4] == '.') - { - int fd = open(path, O_RDONLY); - if (fd == -1) - { - length = -1; // retry - break; - } + if(sscanf(buffer, "%" PRIx64 "-%" PRIx64 " %s %" PRIx64 " %x:%x %u %s\n", + &low, &high, perms, &offset, &major, &minor, &inode, path) == 8) { - char* begin = (char*)mmap(0, offset, PROT_READ, MAP_SHARED, fd, 0); - if (begin == MAP_FAILED) - { - close(fd); - length = -1; // retry + uint64_t addr = (uintptr_t) WAI_RETURN_ADDRESS(); + + if(low <= addr && addr <= high) { + char *resolved; + + resolved = realpath(path, buffer); + if(!resolved) break; - } - char* p = begin + offset - 30; // minimum size of local file header - while (p >= begin) // scan backwards - { - if (*((uint32_t*)p) == 0x04034b50UL) // local file header signature found - { - uint16_t length_ = *((uint16_t*)(p + 26)); + length = (int) strlen(resolved); - if (length + 2 + length_ < (int)sizeof(buffer)) - { - memcpy(&buffer[length], "!/", 2); - memcpy(&buffer[length + 2], p + 30, length_); - length += 2 + length_; - } +#if defined(__ANDROID__) || defined(ANDROID) + if(length > 4 + && buffer[length - 1] == 'k' + && buffer[length - 2] == 'p' && buffer[length - 3] == 'a' && buffer[length - 4] == '.') { + int fd = open(path, O_RDONLY); + if(fd == -1) { + length = -1; // Retry break; } - --p; - } + char *begin = (char *) mmap(0, offset, PROT_READ, MAP_SHARED, fd, 0); - munmap(begin, offset); - close(fd); - } -#endif - if (length <= capacity) - { - memcpy(out, resolved, length); + if(begin == MAP_FAILED) { + close(fd); + length = -1; // Retry + break; + } - if (dirname_length) - { - int i; + char *p = begin + offset - 30; // Minimum size of local file header - for (i = length - 1; i >= 0; --i) + while(p >= begin) // Scan backwards { - if (out[i] == '/') + if(*((uint32_t *) p) == 0x04034b50UL) // Local file header signature found { - *dirname_length = i; + uint16_t length_ = *((uint16_t *) (p + 26)); + + if(length + 2 + length_ < (int) sizeof(buffer)) { + memcpy(&buffer[length], "!/", 2); + memcpy(&buffer[length + 2], p + 30, length_); + length += 2 + length_; + } + break; } + + --p; } + + munmap(begin, offset); + close(fd); } - } +#endif - break; + if(length <= capacity) { + memcpy(out, resolved, length); + + if(dirname_length) { + int i; + + for(i = length - 1; i >= 0; --i) { + if(out[i] == '/') { + *dirname_length = i; + break; + } + } + } + } + + break; + } } } - } - fclose(maps); - maps = NULL; + fclose(maps); + maps = NULL; - if (length != -1) - break; - } + if(length != -1) + break; + } - return length; -} + return length; + } #elif defined(__APPLE__) @@ -373,101 +361,86 @@ int WAI_PREFIX(getModulePath)(char* out, int capacity, int* dirname_length) #include #include -WAI_FUNCSPEC -int WAI_PREFIX(getExecutablePath)(char* out, int capacity, int* dirname_length) -{ - char buffer1[PATH_MAX]; - char buffer2[PATH_MAX]; - char* path = buffer1; - char* resolved = NULL; - int length = -1; - bool ok; - - for (ok = false; !ok; ok = true) - { - uint32_t size = (uint32_t)sizeof(buffer1); - if (_NSGetExecutablePath(path, &size) == -1) - { - path = (char*)WAI_MALLOC(size); - if (!_NSGetExecutablePath(path, &size)) - break; - } + WAI_FUNCSPEC int WAI_PREFIX(getExecutablePath) (char *out, int capacity, int *dirname_length) { + char buffer1[PATH_MAX]; + char buffer2[PATH_MAX]; + char *path = buffer1; + char *resolved = NULL; + int length = -1; + bool ok; + + for(ok = false; !ok; ok = true) { + uint32_t size = (uint32_t) sizeof(buffer1); + if(_NSGetExecutablePath(path, &size) == -1) { + path = (char *) WAI_MALLOC(size); + if(!_NSGetExecutablePath(path, &size)) + break; + } - resolved = realpath(path, buffer2); - if (!resolved) - break; + resolved = realpath(path, buffer2); - length = (int)strlen(resolved); - if (length <= capacity) - { - memcpy(out, resolved, length); + if(!resolved) + break; - if (dirname_length) - { - int i; + length = (int) strlen(resolved); + if(length <= capacity) { + memcpy(out, resolved, length); - for (i = length - 1; i >= 0; --i) - { - if (out[i] == '/') - { - *dirname_length = i; - break; + if(dirname_length) { + int i; + + for(i = length - 1; i >= 0; --i) { + if(out[i] == '/') { + *dirname_length = i; + break; + } } } } } - } - if (path != buffer1) - WAI_FREE(path); + if(path != buffer1) + WAI_FREE(path); - return ok ? length : -1; -} + return ok? length: -1; + } -WAI_NOINLINE WAI_FUNCSPEC -int WAI_PREFIX(getModulePath)(char* out, int capacity, int* dirname_length) -{ - char buffer[PATH_MAX]; - char* resolved = NULL; - int length = -1; + WAI_NOINLINE WAI_FUNCSPEC int WAI_PREFIX(getModulePath) (char *out, int capacity, int *dirname_length) { + char buffer[PATH_MAX]; + char *resolved = NULL; + int length = -1; - for(;;) - { - Dl_info info; + for(;;) { + Dl_info info; - if (dladdr(WAI_RETURN_ADDRESS(), &info)) - { - resolved = realpath(info.dli_fname, buffer); - if (!resolved) - break; + if(dladdr(WAI_RETURN_ADDRESS(), &info)) { + resolved = realpath(info.dli_fname, buffer); + if(!resolved) + break; - length = (int)strlen(resolved); - if (length <= capacity) - { - memcpy(out, resolved, length); + length = (int) strlen(resolved); + if(length <= capacity) { + memcpy(out, resolved, length); - if (dirname_length) - { - int i; + if(dirname_length) { + int i; - for (i = length - 1; i >= 0; --i) - { - if (out[i] == '/') - { - *dirname_length = i; - break; + for(i = length - 1; i >= 0; --i) { + if(out[i] == '/') { + *dirname_length = i; + break; + } } } } } + + break; } - break; + return length; } - return length; -} - #elif defined(__QNXNTO__) #include @@ -481,99 +454,81 @@ int WAI_PREFIX(getModulePath)(char* out, int capacity, int* dirname_length) #define WAI_PROC_SELF_EXE "/proc/self/exefile" #endif -WAI_FUNCSPEC -int WAI_PREFIX(getExecutablePath)(char* out, int capacity, int* dirname_length) -{ - char buffer1[PATH_MAX]; - char buffer2[PATH_MAX]; - char* resolved = NULL; - FILE* self_exe = NULL; - int length = -1; - bool ok; - - for (ok = false; !ok; ok = true) - { - self_exe = fopen(WAI_PROC_SELF_EXE, "r"); - if (!self_exe) - break; + WAI_FUNCSPEC int WAI_PREFIX(getExecutablePath) (char *out, int capacity, int *dirname_length) { + char buffer1[PATH_MAX]; + char buffer2[PATH_MAX]; + char *resolved = NULL; + FILE *self_exe = NULL; + int length = -1; + bool ok; + + for(ok = false; !ok; ok = true) { + self_exe = fopen(WAI_PROC_SELF_EXE, "r"); + if(!self_exe) + break; - if (!fgets(buffer1, sizeof(buffer1), self_exe)) - break; + if(!fgets(buffer1, sizeof(buffer1), self_exe)) + break; - resolved = realpath(buffer1, buffer2); - if (!resolved) - break; + resolved = realpath(buffer1, buffer2); + if(!resolved) + break; - length = (int)strlen(resolved); - if (length <= capacity) - { - memcpy(out, resolved, length); + length = (int) strlen(resolved); + if(length <= capacity) { + memcpy(out, resolved, length); - if (dirname_length) - { - int i; + if(dirname_length) { + int i; - for (i = length - 1; i >= 0; --i) - { - if (out[i] == '/') - { - *dirname_length = i; - break; - } - } + for(i = length - 1; i >= 0; --i) { + if(out[i] == '/') { + *dirname_length = i; + break; + } + }} } - } - } + } fclose(self_exe); - fclose(self_exe); - - return ok ? length : -1; -} + return ok? length: -1; + } -WAI_FUNCSPEC -int WAI_PREFIX(getModulePath)(char* out, int capacity, int* dirname_length) -{ - char buffer[PATH_MAX]; - char* resolved = NULL; - int length = -1; + WAI_FUNCSPEC int WAI_PREFIX(getModulePath) (char *out, int capacity, int *dirname_length) { + char buffer[PATH_MAX]; + char *resolved = NULL; + int length = -1; - for(;;) - { - Dl_info info; + for(;;) { + Dl_info info; - if (dladdr(WAI_RETURN_ADDRESS(), &info)) - { - resolved = realpath(info.dli_fname, buffer); - if (!resolved) - break; + if(dladdr(WAI_RETURN_ADDRESS(), &info)) { + resolved = realpath(info.dli_fname, buffer); + if(!resolved) + break; - length = (int)strlen(resolved); - if (length <= capacity) - { - memcpy(out, resolved, length); + length = (int) strlen(resolved); + if(length <= capacity) { + memcpy(out, resolved, length); - if (dirname_length) - { - int i; + if(dirname_length) { + int i; - for (i = length - 1; i >= 0; --i) - { - if (out[i] == '/') - { - *dirname_length = i; - break; + for(i = length - 1; i >= 0; --i) { + if(out[i] == '/') { + *dirname_length = i; + break; + } } } } } + + break; } - break; + return length; } - return length; -} - #elif defined(__DragonFly__) || defined(__FreeBSD__) || \ defined(__FreeBSD_kernel__) || defined(__NetBSD__) || defined(__OpenBSD__) @@ -586,216 +541,188 @@ int WAI_PREFIX(getModulePath)(char* out, int capacity, int* dirname_length) #include #if defined(__OpenBSD__) - #include -WAI_FUNCSPEC -int WAI_PREFIX(getExecutablePath)(char* out, int capacity, int* dirname_length) -{ - char buffer1[4096]; - char buffer2[PATH_MAX]; - char buffer3[PATH_MAX]; - char** argv = (char**)buffer1; - char* resolved = NULL; - int length = -1; - bool ok; - - for (ok = false; !ok; ok = true) - { - int mib[4] = { CTL_KERN, KERN_PROC_ARGS, getpid(), KERN_PROC_ARGV }; - size_t size; - - if (sysctl(mib, 4, NULL, &size, NULL, 0) != 0) - break; + WAI_FUNCSPEC int WAI_PREFIX(getExecutablePath) (char *out, int capacity, int *dirname_length) { + char buffer1[4096]; + char buffer2[PATH_MAX]; + char buffer3[PATH_MAX]; + char **argv = (char **) buffer1; + char *resolved = NULL; + int length = -1; + bool ok; - if (size > sizeof(buffer1)) - { - argv = (char**)WAI_MALLOC(size); - if (!argv) - break; - } + for(ok = false; !ok; ok = true) { + int mib[4] = { CTL_KERN, KERN_PROC_ARGS, getpid(), KERN_PROC_ARGV }; + size_t size; - if (sysctl(mib, 4, argv, &size, NULL, 0) != 0) + if(sysctl(mib, 4, NULL, &size, NULL, 0) != 0) break; - if (strchr(argv[0], '/')) - { - resolved = realpath(argv[0], buffer2); - if (!resolved) - break; - } - else - { - const char* PATH = getenv("PATH"); - if (!PATH) + if(size > sizeof(buffer1)) { + argv = (char **) WAI_MALLOC(size); + if(!argv) + break; + } + + if(sysctl(mib, 4, argv, &size, NULL, 0) != 0) break; - size_t argv0_length = strlen(argv[0]); + if(strchr(argv[0], '/')) { + resolved = realpath(argv[0], buffer2); + if(!resolved) + break; + } else { + const char *PATH = getenv("PATH"); - const char* begin = PATH; - while (1) - { - const char* separator = strchr(begin, ':'); - const char* end = separator ? separator : begin + strlen(begin); + if(!PATH) + break; - if (end - begin > 0) - { - if (*(end -1) == '/') - --end; + size_t argv0_length = strlen(argv[0]); - if (((end - begin) + 1 + argv0_length + 1) <= sizeof(buffer2)) - { - memcpy(buffer2, begin, end - begin); - buffer2[end - begin] = '/'; - memcpy(buffer2 + (end - begin) + 1, argv[0], argv0_length + 1); + const char *begin = PATH; - resolved = realpath(buffer2, buffer3); - if (resolved) - break; + while(1) { + const char *separator = strchr(begin, ':'); + const char *end = separator? separator: begin + strlen(begin); + + if(end - begin > 0) { + if(*(end - 1) == '/') + --end; + + if(((end - begin) + 1 + argv0_length + 1) <= sizeof(buffer2)) { + memcpy(buffer2, begin, end - begin); + buffer2[end - begin] = '/'; + memcpy(buffer2 + (end - begin) + 1, argv[0], argv0_length + 1); + + resolved = realpath(buffer2, buffer3); + if(resolved) + break; + } } + + if(!separator) + break; + + begin = ++separator; } - if (!separator) + if(!resolved) break; - - begin = ++separator; } - if (!resolved) - break; - } - - length = (int)strlen(resolved); - if (length <= capacity) - { - memcpy(out, resolved, length); + length = (int) strlen(resolved); + if(length <= capacity) { + memcpy(out, resolved, length); - if (dirname_length) - { - int i; + if(dirname_length) { + int i; - for (i = length - 1; i >= 0; --i) - { - if (out[i] == '/') - { - *dirname_length = i; - break; + for(i = length - 1; i >= 0; --i) { + if(out[i] == '/') { + *dirname_length = i; + break; + } } } } } - } - if (argv != (char**)buffer1) - WAI_FREE(argv); + if(argv != (char **) buffer1) + WAI_FREE(argv); - return ok ? length : -1; -} + return ok? length: -1; + } #else -WAI_FUNCSPEC -int WAI_PREFIX(getExecutablePath)(char* out, int capacity, int* dirname_length) -{ - char buffer1[PATH_MAX]; - char buffer2[PATH_MAX]; - char* path = buffer1; - char* resolved = NULL; - int length = -1; - bool ok; - - for (ok = false; !ok; ok = true) - { + WAI_FUNCSPEC int WAI_PREFIX(getExecutablePath) (char *out, int capacity, int *dirname_length) { + char buffer1[PATH_MAX]; + char buffer2[PATH_MAX]; + char *path = buffer1; + char *resolved = NULL; + int length = -1; + bool ok; + + for(ok = false; !ok; ok = true) { + #if defined(__NetBSD__) - int mib[4] = { CTL_KERN, KERN_PROC_ARGS, -1, KERN_PROC_PATHNAME }; + int mib[4] = { CTL_KERN, KERN_PROC_ARGS, -1, KERN_PROC_PATHNAME }; #else - int mib[4] = { CTL_KERN, KERN_PROC, KERN_PROC_PATHNAME, -1 }; + int mib[4] = { CTL_KERN, KERN_PROC, KERN_PROC_PATHNAME, -1 }; #endif - size_t size = sizeof(buffer1); - if (sysctl(mib, 4, path, &size, NULL, 0) != 0) + size_t size = sizeof(buffer1); + + if(sysctl(mib, 4, path, &size, NULL, 0) != 0) break; - resolved = realpath(path, buffer2); - if (!resolved) - break; + resolved = realpath(path, buffer2); + if(!resolved) + break; - length = (int)strlen(resolved); - if (length <= capacity) - { - memcpy(out, resolved, length); + length = (int) strlen(resolved); + if(length <= capacity) { + memcpy(out, resolved, length); - if (dirname_length) - { - int i; + if(dirname_length) { + int i; - for (i = length - 1; i >= 0; --i) - { - if (out[i] == '/') - { - *dirname_length = i; - break; + for(i = length - 1; i >= 0; --i) { + if(out[i] == '/') { + *dirname_length = i; + break; + } } } } } - } - - return ok ? length : -1; -} + return ok? length: -1; + } #endif -WAI_NOINLINE WAI_FUNCSPEC -int WAI_PREFIX(getModulePath)(char* out, int capacity, int* dirname_length) -{ - char buffer[PATH_MAX]; - char* resolved = NULL; - int length = -1; + WAI_NOINLINE WAI_FUNCSPEC int WAI_PREFIX(getModulePath) (char *out, int capacity, int *dirname_length) { + char buffer[PATH_MAX]; + char *resolved = NULL; + int length = -1; - for(;;) - { - Dl_info info; + for(;;) { + Dl_info info; - if (dladdr(WAI_RETURN_ADDRESS(), &info)) - { - resolved = realpath(info.dli_fname, buffer); - if (!resolved) - break; + if(dladdr(WAI_RETURN_ADDRESS(), &info)) { + resolved = realpath(info.dli_fname, buffer); + if(!resolved) + break; - length = (int)strlen(resolved); - if (length <= capacity) - { - memcpy(out, resolved, length); + length = (int) strlen(resolved); + if(length <= capacity) { + memcpy(out, resolved, length); - if (dirname_length) - { - int i; + if(dirname_length) { + int i; - for (i = length - 1; i >= 0; --i) - { - if (out[i] == '/') - { - *dirname_length = i; - break; + for(i = length - 1; i >= 0; --i) { + if(out[i] == '/') { + *dirname_length = i; + break; + } } } } } + + break; } - break; + return length; } - return length; -} - #else #error unsupported platform - #endif #ifdef __cplusplus } -#endif \ No newline at end of file +#endif diff --git a/src/whereami.h b/src/whereami.h index 0eabee7c8..0b86c308d 100644 --- a/src/whereami.h +++ b/src/whereami.h @@ -11,13 +11,14 @@ extern "C" { #endif #ifndef WAI_FUNCSPEC - #define WAI_FUNCSPEC +#define WAI_FUNCSPEC #endif + #ifndef WAI_PREFIX #define WAI_PREFIX(function) wai_##function #endif -/** +/* * Returns the path to the current executable. * * Usage: @@ -36,10 +37,9 @@ extern "C" { * @return the length of the executable path on success (without a terminal NUL * character), otherwise `-1` */ -WAI_FUNCSPEC -int WAI_PREFIX(getExecutablePath)(char* out, int capacity, int* dirname_length); + WAI_FUNCSPEC int WAI_PREFIX(getExecutablePath) (char *out, int capacity, int *dirname_length); -/** +/* * Returns the path to the current module * * Usage: @@ -57,11 +57,9 @@ int WAI_PREFIX(getExecutablePath)(char* out, int capacity, int* dirname_length); * @return the length of the module path on success (without a terminal NUL * character), otherwise `-1` */ -WAI_FUNCSPEC -int WAI_PREFIX(getModulePath)(char* out, int capacity, int* dirname_length); + WAI_FUNCSPEC int WAI_PREFIX(getModulePath) (char *out, int capacity, int *dirname_length); #ifdef __cplusplus } #endif - -#endif // #ifndef WHEREAMI_H +#endif // #ifndef WHEREAMI_H diff --git a/src/wiring.c b/src/wiring.c index 76a2a53be..ca6186d24 100644 --- a/src/wiring.c +++ b/src/wiring.c @@ -49,31 +49,28 @@ #include "stk500v2.h" #include "wiring.h" -/* - * Private data for this programmer. - */ struct wiringpdata { int snoozetime, delay; bool noautoreset; }; +// wiringpdata is our private data -/* wiringpdata is our private data */ -/* pdata is stk500v2's private data (inherited) */ +// pdata is stk500v2's private data (inherited) -#define WIRINGPDATA(pgm) ((struct wiringpdata *)(((struct pdata *)(pgm->cookie)) -> chained_pdata)) +#define mywiring (*(struct wiringpdata *) (((struct pdata *) (pgm->cookie)) -> chained_pdata)) static void wiring_setup(PROGRAMMER *pgm) { // First, have STK500v2 backend allocate its own private data stk500v2_setup(pgm); // Then prepare our data and store in a safe place for the time being - ((struct pdata *)(pgm->cookie))->chained_pdata = mmt_malloc(sizeof(struct wiringpdata)); + ((struct pdata *) (pgm->cookie))->chained_pdata = mmt_malloc(sizeof(struct wiringpdata)); } static void wiring_teardown(PROGRAMMER *pgm) { if(pgm->cookie) - mmt_free(((struct pdata *)(pgm->cookie))->chained_pdata); + mmt_free(((struct pdata *) (pgm->cookie))->chained_pdata); stk500v2_teardown(pgm); pgm->cookie = NULL; } @@ -83,44 +80,46 @@ static int wiring_parseextparms(const PROGRAMMER *pgm, const LISTID extparms) { int rv = 0; bool help = 0; - for (LNODEID ln = lfirst(extparms); ln; ln = lnext(ln)) { + for(LNODEID ln = lfirst(extparms); ln; ln = lnext(ln)) { const char *extended_param = ldata(ln); - if (str_starts(extended_param, "snooze=")) { - int val = str_int(extended_param+7, STR_INT32, &errstr); + if(str_starts(extended_param, "snooze=")) { + int val = str_int(extended_param + 7, STR_INT32, &errstr); + if(errstr || val < 0) { pmsg_error("-x %s: %s\n", extended_param, errstr? errstr: "snooze time cannot be negative"); rv = -1; break; } pmsg_notice2("%s(): snooze time set to %d ms\n", __func__, val); - WIRINGPDATA(pgm)->snoozetime = val; + mywiring.snoozetime = val; continue; } - if (str_starts(extended_param, "delay=")) { - int val = str_int(extended_param+6, STR_INT32, &errstr); + if(str_starts(extended_param, "delay=")) { + int val = str_int(extended_param + 6, STR_INT32, &errstr); + if(errstr) { pmsg_error("-x %s: %s\n", extended_param, errstr); rv = -1; break; } pmsg_notice2("%s(): delay set to %d ms\n", __func__, val); - WIRINGPDATA(pgm)->delay = val; + mywiring.delay = val; continue; } if(str_eq(extended_param, "noautoreset")) { - WIRINGPDATA(pgm)->noautoreset = true; + mywiring.noautoreset = true; continue; } - if (str_eq(extended_param, "help")) { + if(str_eq(extended_param, "help")) { help = true; rv = LIBAVRDUDE_EXIT; } - if (!help) { + if(!help) { pmsg_error("invalid extended parameter -x %s\n", extended_param); rv = -1; } @@ -140,19 +139,19 @@ static int wiring_open(PROGRAMMER *pgm, const char *port) { union pinfo pinfo; pgm->port = port; - pinfo.serialinfo.baud = pgm->baudrate ? pgm->baudrate: 115200; + pinfo.serialinfo.baud = pgm->baudrate? pgm->baudrate: 115200; pinfo.serialinfo.cflags = SERIAL_8N1; serial_open(port, pinfo, &pgm->fd); // If we have a snoozetime, then we wait and do NOT toggle DTR/RTS - if (WIRINGPDATA(pgm)->snoozetime > 0) { - timetosnooze = WIRINGPDATA(pgm)->snoozetime; + if(mywiring.snoozetime > 0) { + timetosnooze = mywiring.snoozetime; pmsg_notice2("%s(): snoozing for %d ms\n", __func__, timetosnooze); - while (timetosnooze--) + while(timetosnooze--) usleep(1000); pmsg_notice2("%s(): done snoozing\n", __func__); - } else if (WIRINGPDATA(pgm)->noautoreset == false) { + } else if(mywiring.noautoreset == false) { // This code assumes a negative-logic USB to TTL serial adapter // Set RTS/DTR high to discharge the series-capacitor, if present pmsg_notice2("%s(): releasing DTR/RTS\n", __func__); @@ -168,15 +167,15 @@ static int wiring_open(PROGRAMMER *pgm, const char *port) { // Set the RTS/DTR line back to high, so direct connection to reset works serial_set_dtr_rts(&pgm->fd, 0); - int delay = WIRINGPDATA(pgm)->delay; - if((100+delay) > 0) - usleep((100+delay)*1000); // Wait until board comes out of reset - } + int delay = mywiring.delay; + if((100 + delay) > 0) + usleep((100 + delay)*1000); // Wait until board comes out of reset + } // Drain any extraneous input stk500v2_drain(pgm, 0); - if (stk500v2_getsync(pgm) < 0) { + if(stk500v2_getsync(pgm) < 0) { pmsg_error("stk500v2_getsync() failed; try -x delay=n with some n in [-80, 100]\n"); return -1; } @@ -192,16 +191,14 @@ static void wiring_close(PROGRAMMER *pgm) { const char wiring_desc[] = "Bootloader using STK500v2 protocol, see http://wiring.org.co"; void wiring_initpgm(PROGRAMMER *pgm) { - /* The Wiring bootloader uses a near-complete STK500v2 protocol. */ - + // The Wiring bootloader uses a near-complete STK500v2 protocol stk500v2_initpgm(pgm); strcpy(pgm->type, "Wiring"); - pgm->open = wiring_open; - pgm->close = wiring_close; - pgm->setup = wiring_setup; - pgm->teardown = wiring_teardown; + pgm->open = wiring_open; + pgm->close = wiring_close; + pgm->setup = wiring_setup; + pgm->teardown = wiring_teardown; pgm->parseextparams = wiring_parseextparms; } - diff --git a/src/wiring.h b/src/wiring.h index 08d8112ac..cf54366df 100644 --- a/src/wiring.h +++ b/src/wiring.h @@ -21,7 +21,4 @@ extern const char wiring_desc[]; void wiring_initpgm(PROGRAMMER *pgm); - #endif - - diff --git a/src/xbee.c b/src/xbee.c index 9c013b408..4d77039af 100644 --- a/src/xbee.c +++ b/src/xbee.c @@ -43,11 +43,11 @@ #include "xbee.h" /* - * After eight seconds the AVR bootloader watchdog will kick in. But - * to allow for the possibility of eight seconds upstream and another - * eight seconds downstream, allow for 16 retries (of roughly one - * second each). + * After eight seconds the AVR bootloader watchdog will kick in. But to allow + * for the possibility of eight seconds upstream and another eight seconds + * downstream, allow for 16 retries (of roughly one second each). */ + #ifndef XBEE_MAX_RETRIES #define XBEE_MAX_RETRIES 16 #endif @@ -56,59 +56,55 @@ * Maximum chunk size, which is the maximum encapsulated payload to be * delivered to the remote CPU. * - * There is an additional overhead of 3 bytes encapsulation, one - * "REQUEST" byte, one sequence number byte, and one - * "FIRMWARE_DELIVER" request type. + * There is an additional overhead of 3 bytes encapsulation, one "REQUEST" + * byte, one sequence number byte, and one "FIRMWARE_DELIVER" request type. * - * The ZigBee maximum (unfragmented) payload is 84 bytes. Source - * routing decreases that by two bytes overhead, plus two bytes per - * hop. Maximum hop support is for 11 or 25 hops depending on - * firmware. + * The ZigBee maximum (unfragmented) payload is 84 bytes. Source routing + * decreases that by two bytes overhead, plus two bytes per hop. Maximum hop + * support is for 11 or 25 hops depending on firmware. * - * Network layer encryption decreases the maximum payload by 18 bytes. - * APS end-to-end encryption decreases the maximum payload by 9 bytes. - * Both these layers are available in concert, as seen in the section - * "Network and APS layer encryption", decreasing our maximum payload - * by both 18 bytes and 9 bytes. + * Network layer encryption decreases the maximum payload by 18 bytes. APS + * end-to-end encryption decreases the maximum payload by 9 bytes. Both these + * layers are available in concert, as seen in the section "Network and APS + * layer encryption", decreasing our maximum payload by both 18 bytes and 9 + * bytes. * - * Our maximum payload size should therefore ideally be 84 - 18 - 9 = - * 57 bytes, and therefore a chunk size of 54 bytes for zero hops. + * Our maximum payload size should therefore ideally be 84 - 18 - 9 = 57 bytes, + * and therefore a chunk size of 54 bytes for zero hops. * - * Source: XBee X2C manual: "Maximum RF payload size" section for most - * details; "Network layer encryption and decryption" section for the - * reference to 18 bytes of overhead; and "Enable APS encryption" for - * the reference to 9 bytes of overhead. + * Source: XBee X2C manual: "Maximum RF payload size" section for most details; + * "Network layer encryption and decryption" section for the reference to 18 + * bytes of overhead; and "Enable APS encryption" for the reference to 9 bytes + * of overhead. */ + #ifndef XBEEBOOT_MAX_CHUNK #define XBEEBOOT_MAX_CHUNK 54 #endif /* * Maximum source route intermediate hops. This is described in the - * documentation variously as 40 hops (routing table); OR 25 hops - * (firmware 4x58 or later); OR 11 hops (firmware earlier than 4x58). + * documentation variously as 40 hops (routing table); OR 25 hops (firmware + * 4x58 or later); OR 11 hops (firmware earlier than 4x58). * - * What isn't described is how to know if a given source route length - * is actually supported by the mesh for our target device. + * What isn't described is how to know if a given source route length is + * actually supported by the mesh for our target device. */ + #ifndef XBEE_MAX_INTERMEDIATE_HOPS #define XBEE_MAX_INTERMEDIATE_HOPS 40 #endif -/* Protocol */ +// Protocol #define XBEEBOOT_PACKET_TYPE_ACK 0 #define XBEEBOOT_PACKET_TYPE_REQUEST 1 -/* - * Read signature bytes - Direct copy of the Arduino behaviour to - * satisfy Optiboot. - */ +// Read signature bytes: direct copy of the Arduino behaviour to satisfy Optiboot static int xbee_read_sig_bytes(const PROGRAMMER *pgm, const AVRPART *p, const AVRMEM *m) { unsigned char buf[32]; - /* Signature byte reads are always 3 bytes. */ - - if (m->size < 3) { + // Signature byte reads are always 3 bytes + if(m->size < 3) { pmsg_error("memsize too small for sig byte read\n"); return -1; } @@ -118,17 +114,17 @@ static int xbee_read_sig_bytes(const PROGRAMMER *pgm, const AVRPART *p, const AV serial_send(&pgm->fd, buf, 2); - if (serial_recv(&pgm->fd, buf, 5) < 0) + if(serial_recv(&pgm->fd, buf, 5) < 0) return -1; - if (buf[0] == Resp_STK_NOSYNC) { + if(buf[0] == Resp_STK_NOSYNC) { pmsg_error("programmer is out of sync\n"); return -1; - } else if (buf[0] != Resp_STK_INSYNC) { + } else if(buf[0] != Resp_STK_INSYNC) { msg_error("\n"); pmsg_error("protocol expects sync byte 0x%02x but got 0x%02x\n", Resp_STK_INSYNC, buf[0]); return -2; } - if (buf[4] != Resp_STK_OK) { + if(buf[4] != Resp_STK_OK) { msg_error("\n"); pmsg_error("protocol expects OK byte 0x%02x but got 0x%02x\n", Resp_STK_OK, buf[4]); return -3; @@ -158,13 +154,12 @@ struct XBeeStaticticsSummary { #define XBEE_STATS_TRANSMIT 2 #define XBEE_STATS_RECEIVE 3 -static const char * const groupNames[] = - { - "FRAME_LOCAL", - "FRAME_REMOTE", - "TRANSMIT", - "RECEIVE" - }; +static const char *const groupNames[] = { + "FRAME_LOCAL", + "FRAME_REMOTE", + "TRANSMIT", + "RECEIVE" +}; struct XBeeBootSession { struct serial_device *serialDevice; @@ -175,15 +170,10 @@ struct XBeeBootSession { unsigned char outSequence; unsigned char inSequence; - /* - * XBee API frame sequence number. - */ + // XBee API frame sequence number unsigned char txSequence; - /* - * Set to non-zero if the transport is broken to the point it is - * considered unusable. - */ + // Set to non-zero if the transport is broken to the point it is considered unusable int transportUnusable; int xbeeResetPin; @@ -192,22 +182,21 @@ struct XBeeBootSession { size_t inOutIndex; unsigned char inBuffer[256]; - int sourceRouteHops; /* -1 if unset */ + int sourceRouteHops; // -1 if unset int sourceRouteChanged; /* - * The source route is an array of intermediate 16 bit addresses, - * starting with the address nearest to the target address, and - * finishing with the address closest to our local device. + * The source route is an array of intermediate 16 bit addresses, starting + * with the address nearest to the target address, and finishing with the + * address closest to our local device. */ - unsigned char sourceRoute[2 * XBEE_MAX_INTERMEDIATE_HOPS]; + unsigned char sourceRoute[2*XBEE_MAX_INTERMEDIATE_HOPS]; - struct XBeeSequenceStatistics sequenceStatistics[256 * XBEE_STATS_GROUPS]; + struct XBeeSequenceStatistics sequenceStatistics[256*XBEE_STATS_GROUPS]; struct XBeeStaticticsSummary groupSummary[XBEE_STATS_GROUPS]; }; -static void xbeeStatsReset(struct XBeeStaticticsSummary *summary) -{ +static void xbeeStatsReset(struct XBeeStaticticsSummary *summary) { summary->minimum.tv_sec = 0; summary->minimum.tv_usec = 0; summary->maximum.tv_sec = 0; @@ -217,47 +206,46 @@ static void xbeeStatsReset(struct XBeeStaticticsSummary *summary) summary->samples = 0; } -static void xbeeStatsAdd(struct XBeeStaticticsSummary *summary, - struct timeval const *sample) -{ +static void xbeeStatsAdd(struct XBeeStaticticsSummary *summary, struct timeval const *sample) { summary->sum.tv_usec += sample->tv_usec; - if (summary->sum.tv_usec > 1000000) { + if(summary->sum.tv_usec > 1000000) { summary->sum.tv_usec -= 1000000; summary->sum.tv_sec++; } summary->sum.tv_sec += sample->tv_sec; - if (summary->samples == 0 || - summary->minimum.tv_sec > sample->tv_sec || - (summary->minimum.tv_sec == sample->tv_sec && - summary->minimum.tv_usec > sample->tv_usec)) { + if(summary->samples == 0 || + summary->minimum.tv_sec > sample->tv_sec || + (summary->minimum.tv_sec == sample->tv_sec && summary->minimum.tv_usec > sample->tv_usec)) { summary->minimum = *sample; } - if (summary->maximum.tv_sec < sample->tv_sec || - (summary->maximum.tv_sec == sample->tv_sec && - summary->maximum.tv_usec < sample->tv_usec)) { + if(summary->maximum.tv_sec < sample->tv_sec || + (summary->maximum.tv_sec == sample->tv_sec && summary->maximum.tv_usec < sample->tv_usec)) { summary->maximum = *sample; } summary->samples++; } -static void xbeeStatsSummarise(struct XBeeStaticticsSummary const *summary) -{ - pmsg_notice(" Minimum response time: %lu.%06lu\n", summary->minimum.tv_sec, (unsigned long) summary->minimum.tv_usec); - pmsg_notice(" Maximum response time: %lu.%06lu\n", summary->maximum.tv_sec, (unsigned long) summary->maximum.tv_usec); +static void xbeeStatsSummarise(struct XBeeStaticticsSummary const *summary) { + pmsg_notice(" Minimum response time: %lu.%06lu\n", + summary->minimum.tv_sec, (unsigned long) summary->minimum.tv_usec); + pmsg_notice(" Maximum response time: %lu.%06lu\n", + summary->maximum.tv_sec, (unsigned long) summary->maximum.tv_usec); struct timeval average; const unsigned long samples = summary->samples; - average.tv_sec = summary->sum.tv_sec / samples; + + average.tv_sec = summary->sum.tv_sec/samples; unsigned long long usecs = summary->sum.tv_usec; - usecs += (summary->sum.tv_sec % samples) * 1000000; - usecs = usecs / samples; - average.tv_sec += usecs / 1000000; - average.tv_usec = usecs % 1000000; + + usecs += (summary->sum.tv_sec%samples)*1000000; + usecs = usecs/samples; + average.tv_sec += usecs/1000000; + average.tv_usec = usecs%1000000; pmsg_notice(" Average response time: %lu.%06lu\n", average.tv_sec, (unsigned long) average.tv_usec); } @@ -276,64 +264,53 @@ static void XBeeBootSessionInit(struct XBeeBootSession *xbs) { xbs->sourceRouteChanged = 0; int group; - for (group = 0; group < 3; group++) { + + for(group = 0; group < 3; group++) { int index; - for (index = 0; index < 256; index++) - xbs->sequenceStatistics[group * 256 + index].sendTime.tv_sec = (time_t)0; + + for(index = 0; index < 256; index++) + xbs->sequenceStatistics[group*256 + index].sendTime.tv_sec = (time_t) 0; xbeeStatsReset(&xbs->groupSummary[group]); } } #define xbeebootsession(fdp) (struct XBeeBootSession*)((fdp)->pfd) -static void xbeedev_setresetpin(const union filedescriptor *fdp, int xbeeResetPin) -{ +static void xbeedev_setresetpin(const union filedescriptor *fdp, int xbeeResetPin) { struct XBeeBootSession *xbs = xbeebootsession(fdp); + xbs->xbeeResetPin = xbeeResetPin; } -enum xbee_stat_is_retry_enum {XBEE_STATS_NOT_RETRY, XBEE_STATS_IS_RETRY}; +enum xbee_stat_is_retry_enum { XBEE_STATS_NOT_RETRY, XBEE_STATS_IS_RETRY }; typedef enum xbee_stat_is_retry_enum xbee_stat_is_retry; static void xbeedev_stats_send(struct XBeeBootSession *xbs, - char const *detail, - int detailSequence, - unsigned int group, unsigned char sequence, - xbee_stat_is_retry retry, - struct timeval const *sendTime) -{ - struct XBeeSequenceStatistics *stats = - &xbs->sequenceStatistics[group * 256 + sequence]; - - if (retry == XBEE_STATS_NOT_RETRY) + char const *detail, + int detailSequence, unsigned int group, unsigned char sequence, xbee_stat_is_retry retry, + struct timeval const *sendTime) { + + struct XBeeSequenceStatistics *stats = &xbs->sequenceStatistics[group*256 + sequence]; + + if(retry == XBEE_STATS_NOT_RETRY) stats->sendTime = *sendTime; - if (detailSequence >= 0) { + if(detailSequence >= 0) { pmsg_debug("stats: send Group %s Sequence %u : " "Send %lu.%06lu %s Sequence %d\n", groupNames[group], - (unsigned int) sequence, - (unsigned long) sendTime->tv_sec, - (unsigned long) sendTime->tv_usec, - detail, detailSequence); + (unsigned int) sequence, (unsigned long) sendTime->tv_sec, + (unsigned long) sendTime->tv_usec, detail, detailSequence); } else { - pmsg_debug("stats: send Group %s Sequence %u : " - "Send %lu.%06lu %s\n", - groupNames[group], - (unsigned int) sequence, - (unsigned long) sendTime->tv_sec, - (unsigned long) sendTime->tv_usec, - detail); + pmsg_debug("stats: send Group %s Sequence %u : Send %lu.%06lu %s\n", + groupNames[group], (unsigned int) sequence, (unsigned long) sendTime->tv_sec, + (unsigned long) sendTime->tv_usec, detail); } } static void xbeedev_stats_receive(struct XBeeBootSession *xbs, - char const *detail, - unsigned int group, unsigned char sequence, - struct timeval const *receiveTime) -{ - struct XBeeSequenceStatistics *stats = - &xbs->sequenceStatistics[group * 256 + sequence]; + char const *detail, unsigned int group, unsigned char sequence, struct timeval const *receiveTime) { + struct XBeeSequenceStatistics *stats = &xbs->sequenceStatistics[group*256 + sequence]; struct timeval delay; time_t secs; long usecs; @@ -341,7 +318,7 @@ static void xbeedev_stats_receive(struct XBeeBootSession *xbs, secs = receiveTime->tv_sec - stats->sendTime.tv_sec; usecs = receiveTime->tv_usec - stats->sendTime.tv_usec; - if (usecs < 0) { + if(usecs < 0) { usecs += 1000000; secs--; } @@ -356,32 +333,25 @@ static void xbeedev_stats_receive(struct XBeeBootSession *xbs, (unsigned long) stats->sendTime.tv_sec, (unsigned long) stats->sendTime.tv_usec, (unsigned long) receiveTime->tv_sec, - (unsigned long) receiveTime->tv_usec, - (unsigned long) secs, - (unsigned long) usecs, - detail); + (unsigned long) receiveTime->tv_usec, (unsigned long) secs, (unsigned long) usecs, detail); xbeeStatsAdd(&xbs->groupSummary[group], &delay); } static int sendAPIRequest(struct XBeeBootSession *xbs, - unsigned char apiType, - int txSequence, - int apiOption, - int prePayload1, - int prePayload2, - int packetType, - int sequence, - int appType, - char const *detail, - int detailSequence, - unsigned int frameGroup, - xbee_stat_is_retry retry, - unsigned int dataLength, - const unsigned char *data) -{ - unsigned char frame[256]; + unsigned char apiType, + int txSequence, + int apiOption, + int prePayload1, + int prePayload2, + int packetType, + int sequence, + int appType, + char const *detail, + int detailSequence, unsigned int frameGroup, xbee_stat_is_retry retry, + unsigned int dataLength, const unsigned char *data) { + unsigned char frame[256]; unsigned char *fp = &frame[5]; unsigned char *dataStart = fp; unsigned char checksum = 0xff; @@ -392,104 +362,100 @@ static int sendAPIRequest(struct XBeeBootSession *xbs, pmsg_debug("%s(): %lu.%06lu %d, %d, %d, %d %s\n", __func__, (unsigned long) time.tv_sec, - (unsigned long) time.tv_usec, - (int) packetType, (int)sequence, appType, - data == NULL ? -1 : (int)*data, detail); - -#define fpput(x) \ - do { \ - const unsigned char v = (x); \ - if (v == 0x7d || v == 0x7e || v == 0x11 || v == 0x13) { \ - *fp++ = 0x7d; \ - *fp++ = v ^ 0x20; \ - } else { \ - *fp++ = v; \ - } \ - checksum -= v; \ - length++; \ - } while (0) - - fpput(apiType); /* ZigBee Receive Packet or ZigBee Transmit Request */ - - if (apiOption >= 0) - fpput(apiOption); /* Receive options (RX) */ - - if (txSequence >= 0) { - fpput(txSequence); /* Delivery sequence (TX/AT) */ - - /* - * Record the frame send time. Note that frame sequences are - * never retries. - */ - xbeedev_stats_send(xbs, detail, detailSequence, - frameGroup, txSequence, 0, &time); + (unsigned long) time.tv_usec, (int) packetType, (int) sequence, appType, data == NULL? -1: (int) *data, detail); + +#define fpput(x) \ + do { \ + const unsigned char v = (x); \ + if(v == 0x7d || v == 0x7e || v == 0x11 || v == 0x13) { \ + *fp++ = 0x7d; \ + *fp++ = v ^ 0x20; \ + } else { \ + *fp++ = v; \ + } \ + checksum -= v; \ + length++; \ + } while(0) + + fpput(apiType); // ZigBee Receive Packet or ZigBee Transmit Request + + if(apiOption >= 0) + fpput(apiOption); // Receive options (RX) + + if(txSequence >= 0) { + fpput(txSequence); // Delivery sequence (TX/AT) + + // Record the frame send time; note that frame sequences are never retries + xbeedev_stats_send(xbs, detail, detailSequence, frameGroup, txSequence, 0, &time); } - if (apiType != 0x08) { - /* Automatically inhibit addressing for local AT command requests. */ + if(apiType != 0x08) { + // Automatically inhibit addressing for local AT command requests size_t index; - for (index = 0; index < 10; index++) { + + for(index = 0; index < 10; index++) { const unsigned char val = xbs->xbee_address[index]; + fpput(val); } /* - * If this is an API call with remote address, but is not a Create - * Source Route request, consider prefixing it with source routing - * instructions. + * If this is an API call with remote address, but is not a Create Source + * Route request, consider prefixing it with source routing instructions. */ - if (apiType != 0x21 && xbs->sourceRouteChanged) { + if(apiType != 0x21 && xbs->sourceRouteChanged) { pmsg_debug("%s(): issuing Create Source Route request with %d hops\n", __func__, xbs->sourceRouteHops); - int rc = sendAPIRequest(xbs, 0x21, /* Create Source Route */ - 0, -1, 0, xbs->sourceRouteHops, - -1, -1, -1, - "Create Source Route for FRAME_REMOTE", - txSequence, - XBEE_STATS_FRAME_LOCAL, /* Local, no response */ - 0, /* Not a retry */ - xbs->sourceRouteHops * 2, - xbs->sourceRoute); - if (rc != 0) + int rc = sendAPIRequest(xbs, 0x21, // Create Source Route + 0, -1, 0, xbs->sourceRouteHops, + -1, -1, -1, + "Create Source Route for FRAME_REMOTE", + txSequence, + XBEE_STATS_FRAME_LOCAL, // Local, no response + 0, // Not a retry + xbs->sourceRouteHops*2, + xbs->sourceRoute); + + if(rc != 0) return rc; xbs->sourceRouteChanged = 0; } } - if (prePayload1 >= 0) - fpput(prePayload1); /* Transmit broadcast radius */ + if(prePayload1 >= 0) + fpput(prePayload1); // Transmit broadcast radius - if (prePayload2 >= 0) - fpput(prePayload2); /* Transmit options */ + if(prePayload2 >= 0) + fpput(prePayload2); // Transmit options - if (packetType >= 0) - fpput(packetType); /* XBEEBOOT_PACKET_TYPE_{ACK,REQUEST} */ + if(packetType >= 0) + fpput(packetType); // XBEEBOOT_PACKET_TYPE_{ACK,REQUEST} - if (sequence >= 0) { + if(sequence >= 0) { fpput(sequence); - /* Record the send time */ - if (packetType == XBEEBOOT_PACKET_TYPE_REQUEST) - xbeedev_stats_send(xbs, detail, sequence, XBEE_STATS_TRANSMIT, - sequence, retry, &time); + // Record the send time + if(packetType == XBEEBOOT_PACKET_TYPE_REQUEST) + xbeedev_stats_send(xbs, detail, sequence, XBEE_STATS_TRANSMIT, sequence, retry, &time); } - if (appType >= 0) - fpput(appType); /* FIRMWARE_DELIVER */ + if(appType >= 0) + fpput(appType); // FIRMWARE_DELIVER { size_t index; - for (index = 0; index < dataLength; index++) + + for(index = 0; index < dataLength; index++) fpput(data[index]); } - /* Length BEFORE checksum byte */ + // Length BEFORE checksum byte const unsigned char unescapedLength = length; fpput(checksum); - /* Length AFTER checksum byte */ + // Length AFTER checksum byte const unsigned int finalLength = fp - dataStart; frame[0] = 0x7e; @@ -498,52 +464,40 @@ static int sendAPIRequest(struct XBeeBootSession *xbs, fpput(unescapedLength); const unsigned int prefixLength = fp - frame; unsigned char *frameStart = dataStart - prefixLength; + memmove(frameStart, frame, prefixLength); - return xbs->serialDevice->send(&xbs->serialDescriptor, - frameStart, finalLength + prefixLength); + return xbs->serialDevice->send(&xbs->serialDescriptor, frameStart, finalLength + prefixLength); } static int sendPacket(struct XBeeBootSession *xbs, - const char *detail, - unsigned char packetType, - unsigned char sequence, - xbee_stat_is_retry retry, - int appType, - unsigned int dataLength, - const unsigned char *data) -{ + const char *detail, + unsigned char packetType, + unsigned char sequence, xbee_stat_is_retry retry, int appType, unsigned int dataLength, const unsigned char *data) { unsigned char apiType; int prePayload1; int prePayload2; - if (xbs->directMode) { + if(xbs->directMode) { /* - * In direct mode we are pretending to be an XBee device - * forwarding on data received from the transmitting XBee. We - * therefore format the data as a remote XBee would, encapsulated - * in a 0x90 packet. + * In direct mode we are pretending to be an XBee device forwarding on data + * received from the transmitting XBee. We therefore format the data as a + * remote XBee would, encapsulated in a 0x90 packet. */ - apiType = 0x90; /* ZigBee Receive Packet */ + apiType = 0x90; // ZigBee Receive Packet prePayload1 = -1; prePayload2 = -1; } else { - /* - * In normal mode we are requesting a payload delivery, - * encapsulated in a 0x10 packet. - */ - apiType = 0x10; /* ZigBee Transmit Request */ + // In normal mode we are requesting a payload delivery, encapsulated in a 0x10 packet + apiType = 0x10; // ZigBee Transmit Request prePayload1 = 0; prePayload2 = 0; } - while ((++xbs->txSequence & 0xff) == 0); + while((++xbs->txSequence & 0xff) == 0); return sendAPIRequest(xbs, apiType, xbs->txSequence, -1, - prePayload1, prePayload2, packetType, - sequence, appType, - detail, sequence, - XBEE_STATS_FRAME_REMOTE, retry, - dataLength, data); + prePayload1, prePayload2, packetType, sequence, appType, detail, sequence, + XBEE_STATS_FRAME_REMOTE, retry, dataLength, data); } #define XBEE_LENGTH_LEN 2 @@ -556,36 +510,30 @@ static int sendPacket(struct XBeeBootSession *xbs, #define XBEE_TXOPTIONS_LEN 1 #define XBEE_RXOPTIONS_LEN 1 -static void xbeedev_record16Bit(struct XBeeBootSession *xbs, - const unsigned char *rx16Bit) -{ +static void xbeedev_record16Bit(struct XBeeBootSession *xbs, const unsigned char *rx16Bit) { /* - * We don't start out knowing what the 16-bit device address is, but - * we should receive it on the return packets, and re-use it from - * that point on. + * We don't start out knowing what the 16-bit device address is, but we + * should receive it on the return packets, and re-use it from that point on. */ - unsigned char * const tx16Bit = - &xbs->xbee_address[XBEE_ADDRESS_64BIT_LEN]; - if (memcmp(rx16Bit, tx16Bit, XBEE_ADDRESS_16BIT_LEN) != 0) { - pmsg_debug("%s(): new 16-bit address: %02x%02x\n", __func__, - (unsigned int)rx16Bit[0], - (unsigned int)rx16Bit[1]); + unsigned char *const tx16Bit = &xbs->xbee_address[XBEE_ADDRESS_64BIT_LEN]; + + if(memcmp(rx16Bit, tx16Bit, XBEE_ADDRESS_16BIT_LEN) != 0) { + pmsg_debug("%s(): new 16-bit address: %02x%02x\n", + __func__, (unsigned int) rx16Bit[0], (unsigned int) rx16Bit[1]); memcpy(tx16Bit, rx16Bit, XBEE_ADDRESS_16BIT_LEN); } } /* - * Return 0 on success. - * Return -1 on generic error (normally serial timeout). + * Return 0 on success + * Return -1 on generic error (normally serial timeout) * Return -512 + XBee AT Response code */ -#define XBEE_AT_RETURN_CODE(x) (((x) >= -512 && (x) <= -256) ? (x) + 512 : -1) -static int xbeedev_poll(struct XBeeBootSession *xbs, - unsigned char **buf, size_t *buflen, - int waitForAck, - int waitForSequence) -{ - for (;;) { +#define XBEE_AT_RETURN_CODE(x) (((x) >= -512 && (x) <= -256)? (x) + 512: -1) +static int xbeedev_poll(struct XBeeBootSession *xbs, unsigned char **buf, size_t *buflen, + int waitForAck, int waitForSequence) { + + for(;;) { unsigned char byte; unsigned char frame[256]; unsigned int frameSize; @@ -593,61 +541,64 @@ static int xbeedev_poll(struct XBeeBootSession *xbs, before_frame: do { const int rc = xbs->serialDevice->recv(&xbs->serialDescriptor, &byte, 1); - if (rc < 0) + + if(rc < 0) return rc; - } while (byte != 0x7e); + } while(byte != 0x7e); start_of_frame: { size_t index = 0; int escaped = 0; + frameSize = XBEE_LENGTH_LEN; do { const int rc = xbs->serialDevice->recv(&xbs->serialDescriptor, - &byte, 1); - if (rc < 0) + &byte, 1); + + if(rc < 0) return rc; - if (byte == 0x7e) + if(byte == 0x7e) /* - * No matter when we receive a frame start byte, we should - * abort parsing and start a fresh frame. + * No matter when we receive a frame start byte, we should abort + * parsing and start a fresh frame. */ goto start_of_frame; - if (escaped) { + if(escaped) { byte ^= 0x20; escaped = 0; - } else if (byte == 0x7d) { + } else if(byte == 0x7d) { escaped = 1; continue; } - if (index >= sizeof(frame)) + if(index >= sizeof(frame)) goto before_frame; frame[index++] = byte; - if (index == XBEE_LENGTH_LEN) { - /* Length plus the two length bytes, plus the checksum byte */ - frameSize = (frame[0] << 8 | frame[1]) + - XBEE_LENGTH_LEN + XBEE_CHECKSUM_LEN; + if(index == XBEE_LENGTH_LEN) { + // Length plus the two length bytes, plus the checksum byte + frameSize = (frame[0] << 8 | frame[1]) + XBEE_LENGTH_LEN + XBEE_CHECKSUM_LEN; - if (frameSize >= sizeof(frame)) - /* Too long - immediately give up on this frame */ + if(frameSize >= sizeof(frame)) + // Too long - immediately give up on this frame goto before_frame; } - } while (index < frameSize); + } while(index < frameSize); - /* End of frame */ + // End of frame unsigned char checksum = 1; size_t cIndex; - for (cIndex = 2; cIndex < index; cIndex++) { + + for(cIndex = 2; cIndex < index; cIndex++) { checksum += frame[cIndex]; } - if (checksum) { - /* Checksum didn't match */ + if(checksum) { + // Checksum didn't match pmsg_debug("%s(): bad checksum %d\n", __func__, (int) checksum); continue; } @@ -656,204 +607,182 @@ static int xbeedev_poll(struct XBeeBootSession *xbs, const unsigned char frameType = frame[2]; struct timeval receiveTime; + gettimeofday(&receiveTime, NULL); pmsg_debug("%s(): %lu.%06lu Received frame type %x\n", __func__, - (unsigned long) receiveTime.tv_sec, - (unsigned long) receiveTime.tv_usec, - (unsigned int) frameType); + (unsigned long) receiveTime.tv_sec, (unsigned long) receiveTime.tv_usec, (unsigned int) frameType); - if (frameType == 0x97 && frameSize > 16) { - /* Remote command response */ + if(frameType == 0x97 && frameSize > 16) { + // Remote command response unsigned char txSequence = frame[3]; unsigned char resultCode = frame[16]; - xbeedev_stats_receive(xbs, "Remote AT command response", - XBEE_STATS_FRAME_REMOTE, txSequence, &receiveTime); + xbeedev_stats_receive(xbs, "Remote AT command response", XBEE_STATS_FRAME_REMOTE, txSequence, &receiveTime); - pmsg_notice("%s(): remote command %d result code %d\n", __func__, - (int) txSequence, (int) resultCode); + pmsg_notice("%s(): remote command %d result code %d\n", __func__, (int) txSequence, (int) resultCode); - if (waitForSequence >= 0 && waitForSequence == frame[3]) - /* Received result for our sequence numbered request */ + if(waitForSequence >= 0 && waitForSequence == frame[3]) + // Received result for our sequence numbered request return -512 + resultCode; - } else if (frameType == 0x88 && frameSize > 6) { - /* Local command response */ + } else if(frameType == 0x88 && frameSize > 6) { + // Local command response unsigned char txSequence = frame[3]; - xbeedev_stats_receive(xbs, "Local AT command response", - XBEE_STATS_FRAME_LOCAL, txSequence, &receiveTime); + xbeedev_stats_receive(xbs, "Local AT command response", XBEE_STATS_FRAME_LOCAL, txSequence, &receiveTime); - pmsg_notice("%s(): local command %c%c result code %d\n", __func__, - frame[4], frame[5], (int)frame[6]); + pmsg_notice("%s(): local command %c%c result code %d\n", __func__, frame[4], frame[5], (int) frame[6]); - if (waitForSequence >= 0 && waitForSequence == txSequence) - /* Received result for our sequence numbered request */ + if(waitForSequence >= 0 && waitForSequence == txSequence) + // Received result for our sequence numbered request return 0; - } else if (frameType == 0x8b && frameSize > 7) { - /* Transmit status */ + } else if(frameType == 0x8b && frameSize > 7) { + // Transmit status unsigned char txSequence = frame[3]; - xbeedev_stats_receive(xbs, "Transmit status", XBEE_STATS_FRAME_REMOTE, - txSequence, &receiveTime); - - pmsg_debug("%s(): transmit status %d result code %d\n", __func__, - (int) frame[3], (int) frame[7]); - } else if (frameType == 0xa1 && - frameSize >= XBEE_LENGTH_LEN + XBEE_APITYPE_LEN + - XBEE_ADDRESS_64BIT_LEN + - XBEE_ADDRESS_16BIT_LEN + 2 + XBEE_CHECKSUM_LEN) { - /* Route Record Indicator */ - if (memcmp(&frame[XBEE_LENGTH_LEN + XBEE_APITYPE_LEN], - xbs->xbee_address, XBEE_ADDRESS_64BIT_LEN) != 0) { - /* Not from our target device */ + xbeedev_stats_receive(xbs, "Transmit status", XBEE_STATS_FRAME_REMOTE, txSequence, &receiveTime); + + pmsg_debug("%s(): transmit status %d result code %d\n", __func__, (int) frame[3], (int) frame[7]); + } else if(frameType == 0xa1 && + frameSize >= XBEE_LENGTH_LEN + XBEE_APITYPE_LEN + XBEE_ADDRESS_64BIT_LEN + + XBEE_ADDRESS_16BIT_LEN + 2 + XBEE_CHECKSUM_LEN) { + + // Route Record Indicator + if(memcmp(&frame[XBEE_LENGTH_LEN + XBEE_APITYPE_LEN], xbs->xbee_address, XBEE_ADDRESS_64BIT_LEN) != 0) { + // Not from our target device pmsg_debug("%s(): route Record Indicator from other XBee\n", __func__); continue; } /* - * We don't start out knowing what the 16-bit device address is, - * but we should receive it on the return packets, and re-use it - * from that point on. + * We don't start out knowing what the 16-bit device address is, but we + * should receive it on the return packets, and re-use it from that point + * on. */ { - const unsigned char *rx16Bit = - &frame[XBEE_LENGTH_LEN + XBEE_APITYPE_LEN + - XBEE_ADDRESS_64BIT_LEN]; + const unsigned char *rx16Bit = &frame[XBEE_LENGTH_LEN + XBEE_APITYPE_LEN + XBEE_ADDRESS_64BIT_LEN]; + xbeedev_record16Bit(xbs, rx16Bit); } - const unsigned int header = XBEE_LENGTH_LEN + XBEE_APITYPE_LEN + - XBEE_ADDRESS_64BIT_LEN + - XBEE_ADDRESS_16BIT_LEN; + const unsigned int header = XBEE_LENGTH_LEN + XBEE_APITYPE_LEN + XBEE_ADDRESS_64BIT_LEN + XBEE_ADDRESS_16BIT_LEN; const unsigned char receiveOptions = frame[header]; const unsigned char hops = frame[header + 1]; pmsg_debug("%s(): Route Record Indicator from target XBee: " - "hops=%d options=%d\n", __func__, (int)hops, (int)receiveOptions); + "hops=%d options=%d\n", __func__, (int) hops, (int) receiveOptions); - if (frameSize < header + 2 + hops * 2 + XBEE_CHECKSUM_LEN) - /* Bounds check: Frame is too small */ + if(frameSize < header + 2 + hops*2 + XBEE_CHECKSUM_LEN) + // Bounds check: Frame is too small continue; const unsigned int tableOffset = header + 2; unsigned char index; - for (index = 0; index < hops; index++) { - pmsg_debug("%s(): Route Intermediate Hop %d : %02x%02x\n", __func__, (int)index, - (int)frame[tableOffset + index * 2], - (int)frame[tableOffset + index * 2 + 1]); + + for(index = 0; index < hops; index++) { + pmsg_debug("%s(): Route Intermediate Hop %d : %02x%02x\n", __func__, (int) index, + (int) frame[tableOffset + index*2], (int) frame[tableOffset + index*2 + 1]); } - if (hops <= XBEE_MAX_INTERMEDIATE_HOPS) { - if (xbs->sourceRouteHops != (int)hops || - memcmp(&frame[tableOffset], xbs->sourceRoute, hops * 2) != 0) { - memcpy(xbs->sourceRoute, &frame[tableOffset], hops * 2); + if(hops <= XBEE_MAX_INTERMEDIATE_HOPS) { + if(xbs->sourceRouteHops != (int) hops || memcmp(&frame[tableOffset], xbs->sourceRoute, hops*2) != 0) { + memcpy(xbs->sourceRoute, &frame[tableOffset], hops*2); xbs->sourceRouteHops = hops; xbs->sourceRouteChanged = 1; pmsg_debug("%s(): route has changed\n", __func__); } } - } else if (frameType == 0x10 || frameType == 0x90) { + } else if(frameType == 0x10 || frameType == 0x90) { unsigned char *dataStart; unsigned int dataLength; - if (frameType == 0x10) { - /* Direct mode frame */ + if(frameType == 0x10) { + // Direct mode frame const unsigned int header = XBEE_LENGTH_LEN + XBEE_APITYPE_LEN + XBEE_APISEQUENCE_LEN + - XBEE_ADDRESS_64BIT_LEN + XBEE_ADDRESS_16BIT_LEN + - XBEE_RADIUS_LEN + XBEE_TXOPTIONS_LEN; + XBEE_ADDRESS_64BIT_LEN + XBEE_ADDRESS_16BIT_LEN + XBEE_RADIUS_LEN + XBEE_TXOPTIONS_LEN; - if (frameSize <= header + XBEE_CHECKSUM_LEN) - /* Bounds check: Frame is too small */ + if(frameSize <= header + XBEE_CHECKSUM_LEN) + // Bounds check: Frame is too small continue; dataLength = frameSize - header - XBEE_CHECKSUM_LEN; dataStart = &frame[header]; } else { - /* Remote reply frame */ + // Remote reply frame const unsigned int header = XBEE_LENGTH_LEN + - XBEE_APITYPE_LEN + XBEE_ADDRESS_64BIT_LEN + XBEE_ADDRESS_16BIT_LEN + - XBEE_RXOPTIONS_LEN; + XBEE_APITYPE_LEN + XBEE_ADDRESS_64BIT_LEN + XBEE_ADDRESS_16BIT_LEN + XBEE_RXOPTIONS_LEN; - if (frameSize <= header + XBEE_CHECKSUM_LEN) - /* Bounds check: Frame is too small */ + if(frameSize <= header + XBEE_CHECKSUM_LEN) + // Bounds check: Frame is too small continue; dataLength = frameSize - header - XBEE_CHECKSUM_LEN; dataStart = &frame[header]; - if (memcmp(&frame[XBEE_LENGTH_LEN + XBEE_APITYPE_LEN], - xbs->xbee_address, XBEE_ADDRESS_64BIT_LEN) != 0) { + if(memcmp(&frame[XBEE_LENGTH_LEN + XBEE_APITYPE_LEN], xbs->xbee_address, XBEE_ADDRESS_64BIT_LEN) != 0) { /* - * This packet is not from our target device. Unlikely - * to ever happen, but if it does we have to ignore - * it. + * This packet is not from our target device. Unlikely to ever + * happen, but if it does we have to ignore it. */ continue; } /* - * We don't start out knowing what the 16-bit device address - * is, but we should receive it on the return packets, and - * re-use it from that point on. + * We don't start out knowing what the 16-bit device address is, but we + * should receive it on the return packets, and re-use it from that + * point on. */ { - const unsigned char *rx16Bit = - &frame[XBEE_LENGTH_LEN + XBEE_APITYPE_LEN + - XBEE_ADDRESS_64BIT_LEN]; + const unsigned char *rx16Bit = &frame[XBEE_LENGTH_LEN + XBEE_APITYPE_LEN + XBEE_ADDRESS_64BIT_LEN]; + xbeedev_record16Bit(xbs, rx16Bit); } } - if (dataLength >= 2) { + if(dataLength >= 2) { const unsigned char protocolType = dataStart[0]; const unsigned char sequence = dataStart[1]; - pmsg_debug("%s(): %lu.%06lu Packet %d #%d\n", __func__, (unsigned long)receiveTime.tv_sec, - (unsigned long)receiveTime.tv_usec, - (int)protocolType, (int)sequence); + pmsg_debug("%s(): %lu.%06lu Packet %d #%d\n", __func__, (unsigned long) receiveTime.tv_sec, + (unsigned long) receiveTime.tv_usec, (int) protocolType, (int) sequence); - if (protocolType == XBEEBOOT_PACKET_TYPE_ACK) { - /* ACK */ - xbeedev_stats_receive(xbs, "XBeeBoot ACK", - XBEE_STATS_TRANSMIT, sequence, - &receiveTime); + if(protocolType == XBEEBOOT_PACKET_TYPE_ACK) { + // ACK + xbeedev_stats_receive(xbs, "XBeeBoot ACK", XBEE_STATS_TRANSMIT, sequence, &receiveTime); - /* - * We can't update outSequence here, we already do that - * somewhere else. - */ - if (waitForAck >= 0 && waitForAck == sequence) + // We can't update outSequence here, we already do that somewhere else + if(waitForAck >= 0 && waitForAck == sequence) return 0; - } else if (protocolType == XBEEBOOT_PACKET_TYPE_REQUEST && - dataLength >= 4 && dataStart[2] == 24) { - /* REQUEST FRAME_REPLY */ - xbeedev_stats_receive(xbs, "XBeeBoot Receive", XBEE_STATS_RECEIVE, - sequence, &receiveTime); + } else if(protocolType == XBEEBOOT_PACKET_TYPE_REQUEST && dataLength >= 4 && dataStart[2] == 24) { + // REQUEST FRAME_REPLY + xbeedev_stats_receive(xbs, "XBeeBoot Receive", XBEE_STATS_RECEIVE, sequence, &receiveTime); unsigned char nextSequence = xbs->inSequence; - while ((++nextSequence & 0xff) == 0); - if (sequence == nextSequence) { + + while((++nextSequence & 0xff) == 0); + if(sequence == nextSequence) { xbs->inSequence = nextSequence; const size_t textLength = dataLength - 3; size_t index; - for (index = 0; index < textLength; index++) { + + for(index = 0; index < textLength; index++) { const unsigned char data = dataStart[3 + index]; - if (buflen != NULL && *buflen > 0) { - /* If we are receiving right now, and have a buffer ... */ + + if(buflen != NULL && *buflen > 0) { + // If we are receiving right now, and have a buffer ... *(*buf)++ = data; (*buflen)--; } else { xbs->inBuffer[xbs->inInIndex++] = data; - if (xbs->inInIndex == sizeof(xbs->inBuffer)) + if(xbs->inInIndex == sizeof(xbs->inBuffer)) xbs->inInIndex = 0; - if (xbs->inInIndex == xbs->inOutIndex) { - /* Should be impossible */ + if(xbs->inInIndex == xbs->inOutIndex) { + // Should be impossible pmsg_error("buffer overrun\n"); xbs->transportUnusable = 1; return -1; @@ -861,27 +790,22 @@ static int xbeedev_poll(struct XBeeBootSession *xbs, } } - /*msg_error("ACK %x\n", (unsigned int)sequence);*/ + // msg_error("ACK %x\n", (unsigned int) sequence); sendPacket(xbs, "Transmit Request ACK for RECEIVE", - XBEEBOOT_PACKET_TYPE_ACK, sequence, - XBEE_STATS_NOT_RETRY, - -1, 0, NULL); + XBEEBOOT_PACKET_TYPE_ACK, sequence, XBEE_STATS_NOT_RETRY, -1, 0, NULL); - if (buf != NULL && *buflen == 0) - /* Input buffer has been filled */ + if(buf != NULL && *buflen == 0) + // Input buffer has been filled return 0; /* - * Input buffer has NOT been filled, we are still in a - * receive. Not a retry, this is the first point we know - * for sure for this sequence number. + * Input buffer has NOT been filled, we are still in a receive. + * Not a retry, this is the first point we know for sure for this + * sequence number. */ - while ((++nextSequence & 0xff) == 0); + while((++nextSequence & 0xff) == 0); xbeedev_stats_send(xbs, "poll() implies pending RECEIVE", - nextSequence, - XBEE_STATS_RECEIVE, - nextSequence, XBEE_STATS_NOT_RETRY, - &receiveTime); + nextSequence, XBEE_STATS_RECEIVE, nextSequence, XBEE_STATS_NOT_RETRY, &receiveTime); } } } @@ -891,23 +815,22 @@ static int xbeedev_poll(struct XBeeBootSession *xbs, /* * @return - * 0 on success, a negative value on failure, or a positive - * value indicating the sequence number associated with the - * request. + * 0 on success, a negative value on failure, or a positive + * value indicating the sequence number associated with the request */ static int localAsyncAT(struct XBeeBootSession *xbs, char const *detail, - unsigned char at1, unsigned char at2, int value) -{ - if (xbs->directMode) + unsigned char at1, unsigned char at2, int value) { + + if(xbs->directMode) /* - * Remote XBee AT commands make no sense in direct mode - there is - * no XBee device to communicate with. + * Remote XBee AT commands make no sense in direct mode - there is no XBee + * device to communicate with * - * Return success, no sequence number. + * Return success, no sequence number */ return 0; - while ((++xbs->txSequence & 0xff) == 0); + while((++xbs->txSequence & 0xff) == 0); const unsigned char sequence = xbs->txSequence; unsigned char buf[3]; @@ -916,39 +839,38 @@ static int localAsyncAT(struct XBeeBootSession *xbs, char const *detail, buf[length++] = at1; buf[length++] = at2; - if (value >= 0) - buf[length++] = (unsigned char)value; + if(value >= 0) + buf[length++] = (unsigned char) value; pmsg_notice("local AT command: %c%c\n", at1, at2); - /* Local AT command 0x08 */ + // Local AT command 0x08 int rc = sendAPIRequest(xbs, 0x08, sequence, -1, -1, -1, -1, -1, -1, - detail, -1, XBEE_STATS_FRAME_LOCAL, - XBEE_STATS_NOT_RETRY, - length, buf); - if (rc < 0) - /* Failed */ + detail, -1, XBEE_STATS_FRAME_LOCAL, + XBEE_STATS_NOT_RETRY, + length, buf); + + if(rc < 0) return rc; - /* Success, positive sequence number */ - return (int)sequence; + // Success, positive sequence number + return (int) sequence; } -static int localAT(struct XBeeBootSession *xbs, char const *detail, - unsigned char at1, unsigned char at2, int value) -{ +static int localAT(struct XBeeBootSession *xbs, char const *detail, unsigned char at1, unsigned char at2, int value) { int result = localAsyncAT(xbs, detail, at1, at2, value); - if (result <= 0) - /* Failure, or success without a sequence number */ + if(result <= 0) // Failure, or success without a sequence number return result; - unsigned char sequence = (unsigned char)result; + unsigned char sequence = (unsigned char) result; int retries; - for (retries = 0; retries < 5; retries++) { + + for(retries = 0; retries < 5; retries++) { const int rc = xbeedev_poll(xbs, NULL, NULL, -1, sequence); - if (rc == 0) + + if(rc == 0) return 0; } @@ -956,21 +878,19 @@ static int localAT(struct XBeeBootSession *xbs, char const *detail, } /* - * Return 0 on success. - * Return -1 on generic error (normally serial timeout). + * Return 0 on success + * Return -1 on generic error (normally serial timeout) * Return -512 + XBee AT Response code */ -static int sendAT(struct XBeeBootSession *xbs, char const *detail, - unsigned char at1, unsigned char at2, int value) -{ - if (xbs->directMode) +static int sendAT(struct XBeeBootSession *xbs, char const *detail, unsigned char at1, unsigned char at2, int value) { + if(xbs->directMode) /* - * Remote XBee AT commands make no sense in direct mode - there is - * no XBee device to communicate with. + * Remote XBee AT commands make no sense in direct mode - there is no XBee + * device to communicate with. */ return 0; - while ((++xbs->txSequence & 0xff) == 0); + while((++xbs->txSequence & 0xff) == 0); const unsigned char sequence = xbs->txSequence; unsigned char buf[3]; @@ -979,48 +899,44 @@ static int sendAT(struct XBeeBootSession *xbs, char const *detail, buf[length++] = at1; buf[length++] = at2; - if (value >= 0) - buf[length++] = (unsigned char)value; + if(value >= 0) + buf[length++] = (unsigned char) value; pmsg_notice("remote AT command: %c%c\n", at1, at2); - /* Remote AT command 0x17 with Apply Changes 0x02 */ + // Remote AT command 0x17 with Apply Changes 0x02 sendAPIRequest(xbs, 0x17, sequence, -1, - -1, -1, -1, - 0x02, -1, - detail, -1, XBEE_STATS_FRAME_REMOTE, - XBEE_STATS_NOT_RETRY, - length, buf); + -1, -1, -1, 0x02, -1, detail, -1, XBEE_STATS_FRAME_REMOTE, XBEE_STATS_NOT_RETRY, length, buf); int retries; - for (retries = 0; retries < 30; retries++) { + + for(retries = 0; retries < 30; retries++) { const int rc = xbeedev_poll(xbs, NULL, NULL, -1, sequence); const int xbeeRc = XBEE_AT_RETURN_CODE(rc); - if (xbeeRc == 0) - /* Translate to normal success code */ + + if(xbeeRc == 0) // Translate to normal success code return 0; - if (rc != -1) + if(rc != -1) return rc; } return -1; } -/* - * Return 0 on no error recognised, 1 if error was detected and reported - */ +// Return 0 on no error recognised, 1 if error was detected and reported static int xbeeATError(int rc) { const int xbeeRc = XBEE_AT_RETURN_CODE(rc); - if (xbeeRc < 0) + + if(xbeeRc < 0) return 0; - if (xbeeRc == 1) { + if(xbeeRc == 1) { pmsg_error("unable to communicate with remote XBee\n"); - } else if (xbeeRc == 2) { + } else if(xbeeRc == 2) { pmsg_error("remote XBee: invalid command\n"); - } else if (xbeeRc == 3) { + } else if(xbeeRc == 3) { pmsg_error("remote XBee: invalid command parameter\n"); - } else if (xbeeRc == 4) { + } else if(xbeeRc == 4) { pmsg_error("remote XBee: transmission failure\n"); } else { pmsg_error("unrecognised remote XBee error code %d\n", xbeeRc); @@ -1028,21 +944,18 @@ static int xbeeATError(int rc) { return 1; } -static void xbeedev_free(struct XBeeBootSession *xbs) -{ +static void xbeedev_free(struct XBeeBootSession *xbs) { xbs->serialDevice->close(&xbs->serialDescriptor); mmt_free(xbs); } -static void xbeedev_close(union filedescriptor *fdp) -{ +static void xbeedev_close(union filedescriptor *fdp) { struct XBeeBootSession *xbs = xbeebootsession(fdp); + xbeedev_free(xbs); } -static int xbeedev_open(const char *port, union pinfo pinfo, - union filedescriptor *fdp) -{ +static int xbeedev_open(const char *port, union pinfo pinfo, union filedescriptor *fdp) { /* * The syntax for XBee devices is defined as: * @@ -1055,47 +968,51 @@ static int xbeedev_open(const char *port, union pinfo pinfo, * ... for a direct connection. */ char *ttySeparator = strchr(port, '@'); - if (ttySeparator == NULL) { + + if(ttySeparator == NULL) { pmsg_error("XBee: bad port syntax, require @\n"); return -1; } struct XBeeBootSession *xbs = mmt_malloc(sizeof(struct XBeeBootSession)); + XBeeBootSessionInit(xbs); char *tty = &ttySeparator[1]; - if (ttySeparator == port) { - /* Direct connection */ + if(ttySeparator == port) { + // Direct connection memset(xbs->xbee_address, 0, 8); xbs->directMode = 1; } else { size_t addrIndex = 0; int nybble = -1; char const *address = port; - while (address != ttySeparator) { + + while(address != ttySeparator) { char hex = *address++; unsigned int val; - if (hex >= '0' && hex <= '9') { + + if(hex >= '0' && hex <= '9') { val = hex - '0'; - } else if (hex >= 'A' && hex <= 'F') { + } else if(hex >= 'A' && hex <= 'F') { val = hex - 'A' + 10; - } else if (hex >= 'a' && hex <= 'f') { + } else if(hex >= 'a' && hex <= 'f') { val = hex - 'a' + 10; } else { break; } - if (nybble == -1) { + if(nybble == -1) { nybble = val; } else { - xbs->xbee_address[addrIndex++] = (nybble * 16) | val; + xbs->xbee_address[addrIndex++] = (nybble*16) | val; nybble = -1; - if (addrIndex == 8) + if(addrIndex == 8) break; } } - if (addrIndex != 8 || address != ttySeparator || nybble != -1) { + if(addrIndex != 8 || address != ttySeparator || nybble != -1) { pmsg_error("XBee: bad XBee address, require 16-character hexadecimal address\n"); mmt_free(xbs); return -1; @@ -1104,7 +1021,7 @@ static int xbeedev_open(const char *port, union pinfo pinfo, xbs->directMode = 0; } - /* Unknown 16 bit address */ + // Unknown 16 bit address xbs->xbee_address[8] = 0xff; xbs->xbee_address[9] = 0xfe; @@ -1114,33 +1031,28 @@ static int xbeedev_open(const char *port, union pinfo pinfo, (unsigned int) xbs->xbee_address[2], (unsigned int) xbs->xbee_address[3], (unsigned int) xbs->xbee_address[4], - (unsigned int) xbs->xbee_address[5], - (unsigned int) xbs->xbee_address[6], - (unsigned int) xbs->xbee_address[7]); + (unsigned int) xbs->xbee_address[5], (unsigned int) xbs->xbee_address[6], (unsigned int) xbs->xbee_address[7]); - if (pinfo.serialinfo.baud) { - /* - * User supplied the correct baud rate. - */ - } else if (xbs->directMode) { + if(pinfo.serialinfo.baud) { + // User supplied the correct baud rate + } else if(xbs->directMode) { /* * In direct mode, default to 19200. * * Why? * - * In this mode, we are NOT talking to an XBee, we are talking - * directly to an AVR device that thinks it is talking to an XBee - * itself. + * In this mode, we are NOT talking to an XBee, we are talking directly to + * an AVR device that thinks it is talking to an XBee itself. * - * Because, an XBee is a 3.3V device defaulting to 9600baud, and - * the Atmel328P is only rated at a maximum clock rate of 8MHz - * with a 3.3V supply, so there's a high likelihood a remote - * Atmel328P will be clocked at 8MHz. + * Because, an XBee is a 3.3V device defaulting to 9600baud, and the + * Atmel328P is only rated at a maximum clock rate of 8MHz with a 3.3V + * supply, so there's a high likelihood a remote Atmel328P will be clocked + * at 8MHz. * - * With a direct connection, there's a good chance we're talking - * to an Arduino clocked at 16MHz with an XBee-enabled chip - * plugged in. The doubled clock rate means a doubled serial - * rate. Double 9600 baud == 19200 baud. + * With a direct connection, there's a good chance we're talking to an + * Arduino clocked at 16MHz with an XBee-enabled chip plugged in. The + * doubled clock rate means a doubled serial rate. Double 9600 baud == + * 19200 baud. */ pinfo.serialinfo.baud = 19200; } else { @@ -1149,31 +1061,32 @@ static int xbeedev_open(const char *port, union pinfo pinfo, * * Why? * - * XBee devices default to 9600 baud. In this mode we are talking - * to the XBee device, not the far-end device, so it's the local - * XBee baud rate we should select. The baud rate of the AVR - * device is irrelevant. + * XBee devices default to 9600 baud. In this mode we are talking to the + * XBee device, not the far-end device, so it's the local XBee baud rate we + * should select. The baud rate of the AVR device is irrelevant. */ pinfo.serialinfo.baud = 9600; } pinfo.serialinfo.cflags = SERIAL_8N1; - pmsg_notice("baud %ld\n", (long)pinfo.serialinfo.baud); + pmsg_notice("baud %ld\n", (long) pinfo.serialinfo.baud); { const int rc = xbs->serialDevice->open(tty, pinfo, - &xbs->serialDescriptor); - if (rc < 0) { + &xbs->serialDescriptor); + + if(rc < 0) { mmt_free(xbs); return rc; } } - if (!xbs->directMode) { - /* Attempt to ensure the local XBee is in API mode 2 */ + if(!xbs->directMode) { + // Attempt to ensure the local XBee is in API mode 2 { const int rc = localAT(xbs, "AT AP=2", 'A', 'P', 2); - if (rc < 0) { + + if(rc < 0) { pmsg_error("local XBee is not responding\n"); xbeedev_free(xbs); return rc; @@ -1181,39 +1094,37 @@ static int xbeedev_open(const char *port, union pinfo pinfo, } /* - * At this point we want to set the remote XBee parameters as - * required for talking to XBeeBoot. Ideally we would start with - * an "FR" full reset, but because that causes the XBee to - * disappear off the mesh for a significant period and become - * unresponsive, we don't do that. + * At this point we want to set the remote XBee parameters as required for + * talking to XBeeBoot. Ideally we would start with an "FR" full reset, + * but because that causes the XBee to disappear off the mesh for a + * significant period and become unresponsive, we don't do that. */ /* - * Issue an "Aggregate Routing Notification" to enable many-to-one - * routing to this device. This has two effects: + * Issue an "Aggregate Routing Notification" to enable many-to-one routing + * to this device. This has two effects: * - * - Establishes a route from the remote XBee attached to the CPU - * being programmed back to the local XBee. + * - Establishes a route from the remote XBee attached to the CPU being + * programmed back to the local XBee. * - * - Enables the 0xa1 Route frames so that we can make use of - * Source Routing to deliver packets directly to the remote - * XBee. + * - Enables the 0xa1 Route frames so that we can make use of Source + * Routing to deliver packets directly to the remote XBee. * - * Under "RF packet routing" subsection "Many-to-One routing", the - * XBee S2C manual states "Applications that require multiple data - * collectors can also use many-to-one routing. If more than one - * data collector device sends a many-to-one broadcast, devices - * create one reverse routing table entry for each collector." + * Under "RF packet routing" subsection "Many-to-One routing", the XBee S2C + * manual states "Applications that require multiple data collectors can + * also use many-to-one routing. If more than one data collector device + * sends a many-to-one broadcast, devices create one reverse routing table + * entry for each collector." * - * Under "RF packet routing" subsection "Source routing", the XBee - * S2C manual states "To use source routing, a device must use the - * API mode, and it must send periodic many-to-one route request - * broadcasts (AR command) to create a many-to-one route to it on - * all devices". + * Under "RF packet routing" subsection "Source routing", the XBee S2C + * manual states "To use source routing, a device must use the API mode, + * and it must send periodic many-to-one route request broadcasts (AR + * command) to create a many-to-one route to it on all devices". */ { const int rc = localAT(xbs, "AT AR=0", 'A', 'R', 0); - if (rc < 0) { + + if(rc < 0) { pmsg_error("local XBee is not responding\n"); xbeedev_free(xbs); return rc; @@ -1221,19 +1132,20 @@ static int xbeedev_open(const char *port, union pinfo pinfo, } /* - * Disable RTS input on the remote XBee, just in case it is - * enabled by default. XBeeBoot doesn't attempt to support flow - * control, and so it may not correctly drive this pin if RTS mode - * is the default configuration. + * Disable RTS input on the remote XBee, just in case it is enabled by + * default. XBeeBoot doesn't attempt to support flow control, and so it + * may not correctly drive this pin if RTS mode is the default + * configuration. * * XBee IO port 6 is the only pin that supports RTS mode, so there * is no need to support any alternative pin. */ const int rc = sendAT(xbs, "AT D6=0", 'D', '6', 0); - if (rc < 0) { + + if(rc < 0) { xbeedev_free(xbs); - if (xbeeATError(rc)) + if(xbeeATError(rc)) return -1; pmsg_error("remote XBee is not responding\n"); @@ -1246,122 +1158,117 @@ static int xbeedev_open(const char *port, union pinfo pinfo, return 0; } -static int xbeedev_send(const union filedescriptor *fdp, - const unsigned char *buf, size_t buflen) -{ +static int xbeedev_send(const union filedescriptor *fdp, const unsigned char *buf, size_t buflen) { struct XBeeBootSession *xbs = xbeebootsession(fdp); - if (xbs->transportUnusable) - /* Don't attempt to continue on an unusable transport layer */ + if(xbs->transportUnusable) // Don't attempt to continue on an unusable transport layer return -1; - while (buflen > 0) { + while(buflen > 0) { unsigned char sequence = xbs->outSequence; - while ((++sequence & 0xff) == 0); + + while((++sequence & 0xff) == 0); xbs->outSequence = sequence; /* - * We are about to send some data, and that might lead potentially - * to received data before we see the ACK for this transmission. - * As this might be the trigger seen before the next "recv" - * operation, record that we have delivered this potential - * trigger. + * We are about to send some data, and that might lead potentially to + * received data before we see the ACK for this transmission. As this might + * be the trigger seen before the next "recv" operation, record that we + * have delivered this potential trigger. */ { unsigned char nextSequence = xbs->inSequence; - while ((++nextSequence & 0xff) == 0); + + while((++nextSequence & 0xff) == 0); struct timeval sendTime; + gettimeofday(&sendTime, NULL); /* - * Optimistic records should never be treated as retries, - * because they might simply be guessing too optimistically. + * Optimistic records should never be treated as retries, because they + * might simply be guessing too optimistically. */ xbeedev_stats_send(xbs, "send() hints possible triggered RECEIVE", - nextSequence, - XBEE_STATS_RECEIVE, - nextSequence, 0, &sendTime); + nextSequence, XBEE_STATS_RECEIVE, nextSequence, 0, &sendTime); } - /* - * Chunk the data into chunks of up to XBEEBOOT_MAX_CHUNK bytes. - */ + // Chunk the data into chunks of up to XBEEBOOT_MAX_CHUNK bytes unsigned char maximum_chunk = XBEEBOOT_MAX_CHUNK; /* - * Source routing incurs a two byte fixed overhead, plus a two - * byte additional cost per intermediate hop. + * Source routing incurs a two byte fixed overhead, plus a two byte + * additional cost per intermediate hop. * - * We are attempting to avoid fragmentation here, so resize our - * maximum size to anticipate the overhead of the current number - * of hops. If our maximum chunk would be less than one, just - * give up and hope fragmentation will somehow save us. + * We are attempting to avoid fragmentation here, so resize our maximum + * size to anticipate the overhead of the current number of hops. If our + * maximum chunk would be less than one, just give up and hope + * fragmentation will somehow save us. */ const int hops = xbs->sourceRouteHops; - if (hops > 0 && (hops * 2 + 2) < XBEEBOOT_MAX_CHUNK) - maximum_chunk -= hops * 2 + 2; - const unsigned char blockLength = - (buflen > maximum_chunk) ? maximum_chunk : buflen; + if(hops > 0 && (hops*2 + 2) < XBEEBOOT_MAX_CHUNK) + maximum_chunk -= hops*2 + 2; + + const unsigned char blockLength = (buflen > maximum_chunk)? maximum_chunk: buflen; int pollRc = 0; - /* Repeatedly send whilst timing out waiting for ACK responses. */ + // Repeatedly send whilst timing out waiting for ACK responses int retries; - for (retries = 0; retries < XBEE_MAX_RETRIES; retries++) { - int sendRc = - sendPacket(xbs, - "Transmit Request Data, expect ACK for TRANSMIT", - XBEEBOOT_PACKET_TYPE_REQUEST, sequence, - retries > 0 ? XBEE_STATS_IS_RETRY : XBEE_STATS_NOT_RETRY, - 23 /* FIRMWARE_DELIVER */, - blockLength, buf); - if (sendRc < 0) { - /* There is no way to recover from a failure mid-send */ + + for(retries = 0; retries < XBEE_MAX_RETRIES; retries++) { + int sendRc = sendPacket(xbs, + "Transmit Request Data, expect ACK for TRANSMIT", + XBEEBOOT_PACKET_TYPE_REQUEST, sequence, + retries > 0? XBEE_STATS_IS_RETRY: XBEE_STATS_NOT_RETRY, + 23, // FIRMWARE_DELIVER + blockLength, buf); + + if(sendRc < 0) { + // There is no way to recover from a failure mid-send xbs->transportUnusable = 1; return sendRc; } pollRc = xbeedev_poll(xbs, NULL, NULL, sequence, -1); - if (pollRc == 0) { - /* Send was ACK'd */ + if(pollRc == 0) { + // Send was ACK'd buflen -= blockLength; buf += blockLength; break; } /* - * Test the connection to the local XBee by repeatedly - * requesting local configuration details. This functionally - * has no effect, but will allow us to measure any reliability - * issues on this link. + * Test the connection to the local XBee by repeatedly requesting local + * configuration details. This functionally has no effect, but will + * allow us to measure any reliability issues on this link. */ localAsyncAT(xbs, "Local XBee ping [send]", 'A', 'P', -1); /* - * If we don't receive an ACK it might be because the chip - * missed an ACK from us. Resend that too after a timeout, - * unless it's zero which is an illegal sequence number. + * If we don't receive an ACK it might be because the chip missed an ACK + * from us. Resend that too after a timeout, unless it's zero which is + * an illegal sequence number. */ - if (xbs->inSequence != 0) { + if(xbs->inSequence != 0) { int ackRc = sendPacket(xbs, - "Transmit Request ACK [Retry in send] " - "for RECEIVE", - XBEEBOOT_PACKET_TYPE_ACK, - xbs->inSequence, - XBEE_STATS_IS_RETRY, - -1, 0, NULL); - if (ackRc < 0) { - /* There is no way to recover from a failure mid-send */ + "Transmit Request ACK [Retry in send] " "for RECEIVE", + XBEEBOOT_PACKET_TYPE_ACK, + xbs->inSequence, + XBEE_STATS_IS_RETRY, + -1, 0, NULL); + + if(ackRc < 0) { + // There is no way to recover from a failure mid-send xbs->transportUnusable = 1; return ackRc; } } } - if (pollRc < 0) { - /* There is no way to recover from a failure mid-send */ + if(pollRc < 0) { + // There is no way to recover from a failure mid-send xbs->transportUnusable = 1; return pollRc; } @@ -1370,116 +1277,95 @@ static int xbeedev_send(const union filedescriptor *fdp, return 0; } -static int xbeedev_recv(const union filedescriptor *fdp, - unsigned char *buf, size_t buflen) -{ +static int xbeedev_recv(const union filedescriptor *fdp, unsigned char *buf, size_t buflen) { struct XBeeBootSession *xbs = xbeebootsession(fdp); /* - * First de-buffer anything previously received in a chunk that - * couldn't be immediately delievered. + * First de-buffer anything previously received in a chunk that couldn't be + * immediately delievered. */ - while (xbs->inInIndex != xbs->inOutIndex) { + while(xbs->inInIndex != xbs->inOutIndex) { *buf++ = xbs->inBuffer[xbs->inOutIndex++]; - if (xbs->inOutIndex == sizeof(xbs->inBuffer)) + if(xbs->inOutIndex == sizeof(xbs->inBuffer)) xbs->inOutIndex = 0; - if (--buflen == 0) + if(--buflen == 0) return 0; } - if (xbs->transportUnusable) - /* Don't attempt to continue on an unusable transport layer */ + if(xbs->transportUnusable) // Don't attempt to continue on an unusable transport layer return -1; - /* - * When we expect to receive data, that is the time to start the - * clock. - */ + // When we expect to receive data, that is the time to start the clock { unsigned char nextSequence = xbs->inSequence; - while ((++nextSequence & 0xff) == 0); + + while((++nextSequence & 0xff) == 0); struct timeval sendTime; + gettimeofday(&sendTime, NULL); - /* - * Not a retry - in fact this is the first stage we know for sure - * a RECEIVE is due. - */ + // Not a retry - in fact this is the first stage we know for sure a RECEIVE is due xbeedev_stats_send(xbs, "recv() implies pending RECEIVE", - nextSequence, - XBEE_STATS_RECEIVE, - nextSequence, - XBEE_STATS_NOT_RETRY, - &sendTime); + nextSequence, XBEE_STATS_RECEIVE, nextSequence, XBEE_STATS_NOT_RETRY, &sendTime); } int retries; - for (retries = 0; retries < XBEE_MAX_RETRIES; retries++) { + + for(retries = 0; retries < XBEE_MAX_RETRIES; retries++) { const int rc = xbeedev_poll(xbs, &buf, &buflen, -1, -1); - if (rc == 0) + + if(rc == 0) return 0; - if (xbs->transportUnusable) - /* Don't attempt to continue on an unusable transport layer */ + if(xbs->transportUnusable) // Don't attempt to continue on an unusable transport layer return -1; /* - * Test the connection to the local XBee by repeatedly - * requesting local configuration details. This functionally - * has no effect, but will allow us to measure any reliability - * issues on this link. + * Test the connection to the local XBee by repeatedly requesting local + * configuration details. This functionally has no effect, but will allow + * us to measure any reliability issues on this link. */ localAsyncAT(xbs, "Local XBee ping [recv]", 'A', 'P', -1); - /* - * The chip may have missed an ACK from us. Resend after a - * timeout. - */ - if (xbs->inSequence != 0) + // The chip may have missed an ACK from us; resend after a timeout + if(xbs->inSequence != 0) sendPacket(xbs, "Transmit Request ACK [Retry in recv] for RECEIVE", - XBEEBOOT_PACKET_TYPE_ACK, xbs->inSequence, - XBEE_STATS_IS_RETRY, - -1, 0, NULL); + XBEEBOOT_PACKET_TYPE_ACK, xbs->inSequence, XBEE_STATS_IS_RETRY, -1, 0, NULL); } return -1; } -static int xbeedev_drain(const union filedescriptor *fdp, int display) -{ +static int xbeedev_drain(const union filedescriptor *fdp, int display) { struct XBeeBootSession *xbs = xbeebootsession(fdp); - if (xbs->transportUnusable) - /* Don't attempt to continue on an unusable transport layer */ + if(xbs->transportUnusable) // Don't attempt to continue on an unusable transport layer return -1; - /* - * Flushing the local serial buffer is unhelpful under this protocol - */ + // Flushing the local serial buffer is unhelpful under this protocol do { xbs->inOutIndex = xbs->inInIndex = 0; - } while (xbeedev_poll(xbs, NULL, NULL, -1, -1) == 0); + } while(xbeedev_poll(xbs, NULL, NULL, -1, -1) == 0); return 0; } -static int xbeedev_set_dtr_rts(const union filedescriptor *fdp, int is_on) -{ +static int xbeedev_set_dtr_rts(const union filedescriptor *fdp, int is_on) { struct XBeeBootSession *xbs = xbeebootsession(fdp); - if (xbs->directMode) - /* Correct for direct mode */ + if(xbs->directMode) // Correct for direct mode return xbs->serialDevice->set_dtr_rts(&xbs->serialDescriptor, is_on); /* - * For non-direct mode (Over-The-Air) we need to issue XBee commands - * to the remote XBee in order to reset the AVR CPU and initiate the - * XBeeBoot bootloader. + * For non-direct mode (Over-The-Air) we need to issue XBee commands to the + * remote XBee in order to reset the AVR CPU and initiate the XBeeBoot + * bootloader. */ - const int rc = sendAT(xbs, is_on ? "AT [DTR]=low" : "AT [DTR]=high", - 'D', '0' + xbs->xbeeResetPin, is_on ? 5 : 4); - if (rc < 0) { - if (xbeeATError(rc)) + const int rc = sendAT(xbs, is_on? "AT [DTR]=low": "AT [DTR]=high", + 'D', '0' + xbs->xbeeResetPin, is_on? 5: 4); + + if(rc < 0) { + if(xbeeATError(rc)) return -1; pmsg_error("remote XBee is not responding\n"); @@ -1493,35 +1379,34 @@ static int xbee_getsync(const PROGRAMMER *pgm) { unsigned char buf[2], resp[2]; /* - * Issue sync request as per STK500. Unlike stk500_getsync(), don't - * retry here - the underlying protocol will deal with retries for - * us in xbeedev_send() and should be reliable. + * Issue sync request as per STK500. Unlike stk500_getsync(), don't retry + * here - the underlying protocol will deal with retries for us in + * xbeedev_send() and should be reliable. */ buf[0] = Cmnd_STK_GET_SYNC; buf[1] = Sync_CRC_EOP; int sendRc = serial_send(&pgm->fd, buf, 2); - if (sendRc < 0) { + + if(sendRc < 0) { pmsg_error("unable to deliver STK_GET_SYNC to the remote XBeeBoot bootloader\n"); return sendRc; } - /* - * The same is true of the receive - it will retry on timeouts until - * the response buffer is full. - */ + // The same is true of the receive - it will retry on timeouts until the response buffer is full int recvRc = serial_recv(&pgm->fd, resp, 2); - if (recvRc < 0) { + + if(recvRc < 0) { pmsg_error("no response to STK_GET_SYNC from the remote XBeeBoot bootloader\n"); return recvRc; } - if (resp[0] != Resp_STK_INSYNC) { + if(resp[0] != Resp_STK_INSYNC) { pmsg_error("not in sync, resp=0x%02x\n", (unsigned int) resp[0]); return -1; } - if (resp[1] != Resp_STK_OK) { + if(resp[1] != Resp_STK_OK) { pmsg_error("in sync, not OK, resp=0x%02x\n", (unsigned int) resp[1]); return -1; } @@ -1531,14 +1416,15 @@ static int xbee_getsync(const PROGRAMMER *pgm) { static int xbee_open(PROGRAMMER *pgm, const char *port) { union pinfo pinfo; + pgm->port = port; pinfo.serialinfo.baud = pgm->baudrate; pinfo.serialinfo.cflags = SERIAL_8N1; - /* Wireless is lossier than normal serial */ + // Wireless is lossier than normal serial serial_recv_timeout = 1000; - serdev = &PDATA(pgm)->xbee_serdev; + serdev = &my.xbee_serdev; serdev->open = xbeedev_open; serdev->close = xbeedev_close; serdev->rawclose = xbeedev_close; @@ -1548,54 +1434,50 @@ static int xbee_open(PROGRAMMER *pgm, const char *port) { serdev->set_dtr_rts = xbeedev_set_dtr_rts; serdev->flags = SERDEV_FL_NONE; - if (serial_open(port, pinfo, &pgm->fd) == -1) { + if(serial_open(port, pinfo, &pgm->fd) == -1) { return -1; } - xbeedev_setresetpin(&pgm->fd, PDATA(pgm)->xbeeResetPin); + xbeedev_setresetpin(&pgm->fd, my.xbeeResetPin); - /* Clear DTR and RTS */ + // Clear DTR and RTS serial_set_dtr_rts(&pgm->fd, 0); usleep(250*1000); - /* Set DTR and RTS back to high */ + // Set DTR and RTS back to high serial_set_dtr_rts(&pgm->fd, 1); usleep(50*1000); /* - * At this point stk500_drain() and stk500_getsync() calls would - * normally be made. But given that we have a transport layer over - * the serial command stream, the drain and repeated STK_GET_SYNC - * requests are not very helpful. Instead, skip the draining - * entirely, and issue the STK_GET_SYNC ourselves. + * At this point stk500_drain() and stk500_getsync() calls would normally be + * made. But given that we have a transport layer over the serial command + * stream, the drain and repeated STK_GET_SYNC requests are not very helpful. + * Instead, skip the draining entirely, and issue the STK_GET_SYNC ourselves. */ - if (xbee_getsync(pgm) < 0) + if(xbee_getsync(pgm) < 0) return -1; return 0; } -static void xbee_close(PROGRAMMER *pgm) -{ +static void xbee_close(PROGRAMMER *pgm) { struct XBeeBootSession *xbs = xbeebootsession(&pgm->fd); - /* - * NB: This request is for the target device, not the locally - * connected serial device. - */ + // NB: This request is for the target device, not the locally connected serial device serial_set_dtr_rts(&pgm->fd, 0); /* - * We have tweaked a few settings on the XBee, including the RTS - * mode and the reset pin's configuration. Do a soft full reset, - * restoring the device to its normal power-on settings. + * We have tweaked a few settings on the XBee, including the RTS mode and the + * reset pin's configuration. Do a soft full reset, restoring the device to + * its normal power-on settings. * * Note that this DOES mean that the remote XBee will be * uncontactable until it has restarted and re-established * communications on the mesh. */ - if (!xbs->directMode) { + if(!xbs->directMode) { const int rc = sendAT(xbs, "AT FR", 'F', 'R', -1); + xbeeATError(rc); } @@ -1620,28 +1502,28 @@ static int xbee_parseextparms(const PROGRAMMER *pgm, const LISTID extparms) { int rc = 0; bool help = false; - for (LNODEID ln = lfirst(extparms); ln; ln = lnext(ln)) { + for(LNODEID ln = lfirst(extparms); ln; ln = lnext(ln)) { const char *extended_param = ldata(ln); - if (str_starts(extended_param, "xbeeresetpin=")) { + if(str_starts(extended_param, "xbeeresetpin=")) { int resetpin; - if (sscanf(extended_param, "xbeeresetpin=%i", &resetpin) != 1 || - resetpin <= 0 || resetpin > 7) { + + if(sscanf(extended_param, "xbeeresetpin=%i", &resetpin) != 1 || resetpin <= 0 || resetpin > 7) { pmsg_error("invalid value in -x %s\n", extended_param); rc = -1; break; } - PDATA(pgm)->xbeeResetPin = resetpin; + my.xbeeResetPin = resetpin; continue; } - if (str_eq(extended_param, "help")) { + if(str_eq(extended_param, "help")) { help = true; rc = LIBAVRDUDE_EXIT; } - if (!help) { + if(!help) { pmsg_error("invalid extended parameter -x %s\n", extended_param); rc = -1; } @@ -1658,9 +1540,9 @@ const char xbee_desc[] = "XBee Series 2 Over-The-Air (XBeeBoot)"; void xbee_initpgm(PROGRAMMER *pgm) { /* - * This behaves like an Arduino, but with packet encapsulation of - * the serial streams, XBee device management, and XBee GPIO for the - * Auto-Reset feature. stk500.c sets PDATA(pgm)->xbeeResetPin + * This behaves like an Arduino, but with packet encapsulation of the serial + * streams, XBee device management, and XBee GPIO for the Auto-Reset feature. + * stk500.c sets my.xbeeResetPin */ stk500_initpgm(pgm); diff --git a/src/xbee.h b/src/xbee.h index a12f62b2c..fc6426685 100644 --- a/src/xbee.h +++ b/src/xbee.h @@ -23,22 +23,23 @@ extern const char xbee_desc[]; void xbee_initpgm(PROGRAMMER *pgm); /* - * For non-direct mode (Over-The-Air) we need to issue XBee commands - * to the remote XBee in order to reset the AVR CPU and initiate the - * XBeeBoot bootloader. + * For non-direct mode (Over-The-Air) we need to issue XBee commands to the + * remote XBee in order to reset the AVR CPU and initiate the XBeeBoot + * bootloader. * - * XBee IO port 3 is a somewhat-arbitrarily chosen pin that can be - * connected directly to the AVR reset pin. + * XBee IO port 3 is a somewhat-arbitrarily chosen pin that can be connected + * directly to the AVR reset pin. * - * Note that port 7 was not used because it is the only pin that can - * be used as a CTS flow control output. Port 6 is the only pin that - * can be used as an RTS flow control input. + * Note that port 7 was not used because it is the only pin that can be used as + * a CTS flow control output. Port 6 is the only pin that can be used as an + * RTS flow control input. * - * Some off-the-shelf Arduino shields select a different pin. For - * example this one uses XBee IO port 7. + * Some off-the-shelf Arduino shields select a different pin. For example this + * one uses XBee IO port 7. * * https://wiki.dfrobot.com/Xbee_Shield_For_Arduino__no_Xbee___SKU_DFR0015_ */ + #ifndef XBEE_DEFAULT_RESET_PIN #define XBEE_DEFAULT_RESET_PIN 3 #endif