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 + -
显示快捷键?