jtagmkii.c
来自「这是一个非常有价值的参考代码」· C语言 代码 · 共 1,822 行 · 第 1/4 页
C
1,822 行
progname, mem->desc, addr); if (jtagmkII_program_enable(pgm) < 0) return -1; cmd[0] = CMND_READ_MEMORY; if (strcmp(mem->desc, "flash") == 0) { cmd[1] = MTYPE_FLASH_PAGE; pagesize = mem->page_size; paddr = addr & ~(pagesize - 1); paddr_ptr = &flash_pageaddr; cache_ptr = flash_pagecache; } else if (strcmp(mem->desc, "eeprom") == 0) { cmd[1] = MTYPE_EEPROM_PAGE; pagesize = mem->page_size; paddr = addr & ~(pagesize - 1); paddr_ptr = &eeprom_pageaddr; cache_ptr = eeprom_pagecache; } else if (strcmp(mem->desc, "lfuse") == 0) { cmd[1] = MTYPE_FUSE_BITS; addr = 0; } else if (strcmp(mem->desc, "hfuse") == 0) { cmd[1] = MTYPE_FUSE_BITS; addr = 1; } else if (strcmp(mem->desc, "efuse") == 0) { cmd[1] = MTYPE_FUSE_BITS; addr = 2; } else if (strcmp(mem->desc, "lock") == 0) { cmd[1] = MTYPE_LOCK_BITS; } else if (strcmp(mem->desc, "calibration") == 0) { cmd[1] = MTYPE_OSCCAL_BYTE; } else if (strcmp(mem->desc, "signature") == 0) { cmd[1] = MTYPE_SIGN_JTAG; } /* * 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 (unsigned long)-1L when the * cache needs to be invalidated. */ if (pagesize && paddr == *paddr_ptr) { *value = cache_ptr[addr & (pagesize - 1)]; return 0; } if (pagesize) { u32_to_b4(cmd + 2, pagesize); u32_to_b4(cmd + 6, paddr); } else { u32_to_b4(cmd + 2, 1); u32_to_b4(cmd + 6, addr); } tries = 0; retry: if (verbose >= 2) fprintf(stderr, "%s: jtagmkII_read_byte(): Sending read memory command: ", progname); jtagmkII_send(pgm, cmd, 10); status = jtagmkII_recv(pgm, &resp); if (status <= 0) { if (verbose >= 2) putc('\n', stderr); if (verbose >= 1) fprintf(stderr, "%s: jtagmkII_read_byte(): " "timeout/error communicating with programmer (status %d)\n", progname, status); if (tries++ < 3) goto retry; fprintf(stderr, "%s: jtagmkII_read_byte(): " "fatal timeout/error communicating with programmer (status %d)\n", progname, status); goto fail; } if (verbose >= 3) { putc('\n', stderr); jtagmkII_prmsg(pgm, resp, status); } else if (verbose == 2) fprintf(stderr, "0x%02x (%d bytes msg)\n", resp[0], status); if (resp[0] != RSP_MEMORY) { fprintf(stderr, "%s: jtagmkII_read_byte(): " "bad response to read memory command: 0x%02x\n", progname, resp[0]); goto fail; } if (pagesize) { *paddr_ptr = paddr; memcpy(cache_ptr, resp + 1, pagesize); *value = cache_ptr[addr & (pagesize - 1)]; } else *value = resp[1]; free(resp); return 0;fail: /* * XXX should return an error status here, but that would cause * the generic methods to retry the request using the SPI method, * which is complete nonsense for JTAG. */ *value = 42; free(resp); return 0;}static int jtagmkII_write_byte(PROGRAMMER * pgm, AVRPART * p, AVRMEM * mem, unsigned long addr, unsigned char data){ unsigned char cmd[11]; unsigned char *resp = NULL, writedata; int status, tries, need_progmode = 1; if (verbose >= 2) fprintf(stderr, "%s: jtagmkII_write_byte(.., %s, 0x%lx, ...)\n", progname, mem->desc, addr); writedata = data; cmd[0] = CMND_WRITE_MEMORY; if (strcmp(mem->desc, "flash") == 0) { cmd[1] = MTYPE_SPM; need_progmode = 0; flash_pageaddr = (unsigned long)-1L; } else if (strcmp(mem->desc, "eeprom") == 0) { cmd[1] = MTYPE_EEPROM; need_progmode = 0; eeprom_pageaddr = (unsigned long)-1L; } else if (strcmp(mem->desc, "lfuse") == 0) { cmd[1] = MTYPE_FUSE_BITS; addr = 0; } else if (strcmp(mem->desc, "hfuse") == 0) { cmd[1] = MTYPE_FUSE_BITS; addr = 1; } else if (strcmp(mem->desc, "efuse") == 0) { cmd[1] = MTYPE_FUSE_BITS; addr = 2; } else if (strcmp(mem->desc, "lock") == 0) { cmd[1] = MTYPE_LOCK_BITS; } else if (strcmp(mem->desc, "calibration") == 0) { cmd[1] = MTYPE_OSCCAL_BYTE; } else if (strcmp(mem->desc, "signature") == 0) { cmd[1] = MTYPE_SIGN_JTAG; } if (need_progmode) { if (jtagmkII_program_enable(pgm) < 0) return -1; } else { if (jtagmkII_program_disable(pgm) < 0) return -1; } u32_to_b4(cmd + 2, 1); u32_to_b4(cmd + 6, addr); cmd[10] = writedata; tries = 0; retry: if (verbose >= 2) fprintf(stderr, "%s: jtagmkII_write_byte(): Sending write memory command: ", progname); jtagmkII_send(pgm, cmd, 11); status = jtagmkII_recv(pgm, &resp); if (status <= 0) { if (verbose >= 2) putc('\n', stderr); if (verbose > 1) fprintf(stderr, "%s: jtagmkII_write_byte(): " "timeout/error communicating with programmer (status %d)\n", progname, status); if (tries++ < 3) goto retry; fprintf(stderr, "%s: jtagmkII_write_byte(): " "fatal timeout/error communicating with programmer (status %d)\n", progname, status); goto fail; } if (verbose >= 3) { putc('\n', stderr); jtagmkII_prmsg(pgm, resp, status); } else if (verbose == 2) fprintf(stderr, "0x%02x (%d bytes msg)\n", resp[0], status); if (resp[0] != RSP_OK) { fprintf(stderr, "%s: jtagmkII_write_byte(): " "bad response to write memory command: 0x%02x\n", progname, resp[0]); goto fail; } free(resp); return 0;fail: /* * XXX should return an error status here, but that would cause * the generic methods to retry the request using the SPI method, * which is complete nonsense for JTAG. */ free(resp); 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. * * 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(PROGRAMMER * pgm, double v){ unsigned char dur; v = 1 / v; /* convert to frequency */ if (v >= 6.4e6) dur = 0; else if (v >= 2.8e6) dur = 1; else if (v >= 20.9e3) dur = (unsigned char)(5.35e6 / v); else dur = 255; return jtagmkII_setparm(pgm, PAR_OCD_JTAG_CLK, &dur);}/* * 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. */static int jtagmkII_getparm(PROGRAMMER * pgm, unsigned char parm, unsigned char * value){ int status; unsigned char buf[2], *resp, c; if (verbose >= 2) fprintf(stderr, "%s: jtagmkII_getparm()\n", progname); buf[0] = CMND_GET_PARAMETER; buf[1] = parm; if (verbose >= 2) fprintf(stderr, "%s: jtagmkII_getparm(): " "Sending get parameter command (parm 0x%02x): ", progname, parm); jtagmkII_send(pgm, buf, 2); status = jtagmkII_recv(pgm, &resp); if (status <= 0) { if (verbose >= 2) putc('\n', stderr); fprintf(stderr, "%s: jtagmkII_getparm(): " "timeout/error communicating with programmer (status %d)\n", progname, status); return -1; } if (verbose >= 3) { putc('\n', stderr); jtagmkII_prmsg(pgm, resp, status); } else if (verbose == 2) fprintf(stderr, "0x%02x (%d bytes msg)\n", resp[0], status); c = resp[0]; if (c != RSP_PARAMETER) { fprintf(stderr, "%s: jtagmkII_getparm(): " "bad response to get parameter command: 0x%02x\n", progname, c); free(resp); return -1; } memcpy(value, resp + 1, 4); free(resp); return 0;}/* * Write an emulator parameter. */static int jtagmkII_setparm(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. */ unsigned char buf[2 + 4], *resp, c; size_t size; if (verbose >= 2) fprintf(stderr, "%s: jtagmkII_setparm()\n", progname); switch (parm) { case PAR_HW_VERSION: size = 2; break; case PAR_FW_VERSION: size = 4; break; case PAR_EMULATOR_MODE: size = 1; break; case PAR_BAUD_RATE: size = 1; break; case PAR_OCD_VTARGET: size = 2; break; case PAR_OCD_JTAG_CLK: size = 1; break; default: fprintf(stderr, "%s: jtagmkII_setparm(): unknown parameter 0x%02x\n", progname, parm); return -1; } buf[0] = CMND_SET_PARAMETER; buf[1] = parm; memcpy(buf + 2, value, size); if (verbose >= 2) fprintf(stderr, "%s: jtagmkII_setparm(): " "Sending set parameter command (parm 0x%02x, %zu bytes): ", progname, parm, size); jtagmkII_send(pgm, buf, size + 2); status = jtagmkII_recv(pgm, &resp); if (status <= 0) { if (verbose >= 2) putc('\n', stderr); fprintf(stderr, "%s: jtagmkII_setparm(): " "timeout/error communicating with programmer (status %d)\n", progname, status); return -1; } if (verbose >= 3) { putc('\n', stderr); jtagmkII_prmsg(pgm, resp, status); } else if (verbose == 2) fprintf(stderr, "0x%02x (%d bytes msg)\n", resp[0], status); c = resp[0]; free(resp); if (c != RSP_OK) { fprintf(stderr, "%s: jtagmkII_setparm(): " "bad response to set parameter command: 0x%02x\n", progname, c); return -1; } return 0;}static void jtagmkII_display(PROGRAMMER * pgm, 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) return; fprintf(stderr, "%sM_MCU hardware version: %d\n", p, hw[0]); fprintf(stderr, "%sM_MCU firmware version: %d.%02d\n", p, fw[1], fw[0]); fprintf(stderr, "%sS_MCU hardware version: %d\n", p, hw[1]); fprintf(stderr, "%sS_MCU firmware version: %d.%02d\n", p, fw[3], fw[2]); fprintf(stderr, "%sSerial number: %02x:%02x:%02x:%02x:%02x:%02x\n", p, serno[0], serno[1], serno[2], serno[3], serno[4], serno[5]); jtagmkII_print_parms1(pgm, p); return;}static void jtagmkII_print_parms1(PROGRAMMER * pgm, char * p){ unsigned char vtarget[4], jtag_clock[4]; char clkbuf[20]; double clk; if (jtagmkII_getparm(pgm, PAR_OCD_VTARGET, vtarget) < 0 || jtagmkII_getparm(pgm, PAR_OCD_JTAG_CLK, jtag_clock) < 0) return; if (jtag_clock[0] == 0) { strcpy(clkbuf, "6.4 MHz"); clk = 6.4e6; } 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 { sprintf(clkbuf, "%.1f kHz", 5.35e3 / (double)jtag_clock[0]); clk = 5.35e6 / (double)jtag_clock[0]; } fprintf(stderr, "%sVtarget : %.1f V\n", p, b2_to_u16(vtarget) / 1000.0); fprintf(stderr, "%sJTAG clock : %s (%.1f us)\n", p, clkbuf, 1.0e6 / clk); return;}static void jtagmkII_print_parms(PROGRAMMER * pgm){ jtagmkII_print_parms1(pgm, "");}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; pgm->program_enable = jtagmkII_program_enable_dummy; pgm->chip_erase = jtagmkII_chip_erase; pgm->cmd = jtagmkII_cmd; pgm->open = jtagmkII_open; pgm->close = jtagmkII_close; /* * optional functions */ pgm->paged_write = jtagmkII_paged_write; pgm->paged_load = jtagmkII_paged_load; pgm->read_byte = jtagmkII_read_byte; pgm->write_byte = jtagmkII_write_byte; pgm->print_parms = jtagmkII_print_parms; pgm->set_sck_period = jtagmkII_set_sck_period; pgm->page_size = 256;}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?