⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 stk500v2.c

📁 这是一个非常有价值的参考代码
💻 C
📖 第 1 页 / 共 2 页
字号:
static int stk500v2_paged_write(PROGRAMMER * pgm, AVRPART * p, AVRMEM * m,                               int page_size, int n_bytes){  int addr, block_size, last_addr;  int a_div=1;  unsigned char commandbuf[10];  unsigned char buf[266];  unsigned char cmds[4];  int result;  OPCODE * rop, * wop;  DEBUG("STK500V2: stk500v2_paged_write(..,%s,%d,%d)\n",m->desc,page_size,n_bytes);  if (page_size == 0) page_size = 256;  // determine which command is to be used  if (strcmp(m->desc, "flash") == 0) {    a_div=2;    commandbuf[0] = CMD_PROGRAM_FLASH_ISP;  } else if (strcmp(m->desc, "eeprom") == 0) {    commandbuf[0] = CMD_PROGRAM_EEPROM_ISP;  }  commandbuf[4] = m->delay;  if (a_div == 1) {    wop = m->op[AVR_OP_WRITE];    rop = m->op[AVR_OP_READ];  }  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 (m->op[AVR_OP_LOADPAGE_LO] == NULL) {      fprintf(stderr, "%s: stk500v2_paged_write: loadpage instruction not defined for part \"%s\"\n",              progname, p->desc);      return -1;    }    avr_set_bits(m->op[AVR_OP_LOADPAGE_LO], cmds);    commandbuf[5] = cmds[0];    if (m->op[AVR_OP_WRITEPAGE] == NULL) {      fprintf(stderr, "%s: stk500v2_paged_write: write page instruction not defined for part \"%s\"\n",              progname, p->desc);      return -1;    }    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    if (wop == NULL) {      fprintf(stderr, "%s: stk500v2_paged_write: write instruction not defined for part \"%s\"\n",              progname, p->desc);      return -1;    }    avr_set_bits(wop, cmds);    commandbuf[5] = cmds[0];    commandbuf[6] = 0;  }  // the read command is common to both methods  if (rop == NULL) {    fprintf(stderr, "%s: stk500v2_paged_write: read instruction not defined for part \"%s\"\n",            progname, p->desc);    return -1;  }  avr_set_bits(rop, cmds);  commandbuf[7] = cmds[0];  commandbuf[8] = m->readback[0];  commandbuf[9] = m->readback[1];  last_addr=-1;  for (addr=0; addr < n_bytes; addr += page_size) {    report_progress(addr,n_bytes,NULL);    if ((n_bytes-addr) < page_size)      block_size = n_bytes - addr;    else      block_size = page_size;    DEBUG("block_size at addr %d is %d\n",addr,block_size);    if(commandbuf[0] == CMD_PROGRAM_FLASH_ISP){      if (stk500v2_is_page_empty(addr, block_size, m->buf)) {          continue;      }    }    memcpy(buf,commandbuf,sizeof(commandbuf));    buf[1] = block_size >> 8;    buf[2] = block_size & 0xff;    if((last_addr==-1)||(last_addr+block_size != addr)){      stk500v2_loadaddr(pgm, addr/a_div);    }    last_addr=addr;    memcpy(buf+10,m->buf+addr, block_size);    result = stk500v2_command(pgm,buf,block_size+10, sizeof(buf));    if (buf[1] != STATUS_CMD_OK) {      fprintf(stderr,"%s: stk500v2_paged_write: write command failed with %d\n",              progname,buf[1]);      return -1;    }  }  return n_bytes;}static int stk500v2_is_page_empty(unsigned int address, int page_size,                                const unsigned char *buf){    int i;    for(i = 0; i < page_size; i++) {        if(buf[address + i] != 0xFF) {            /* Page is not empty. */            return(0);        }    }    /* Page is empty. */    return(1);}static int stk500v2_paged_load(PROGRAMMER * pgm, AVRPART * p, AVRMEM * m,                             int page_size, int n_bytes){  int addr, block_size;  unsigned char commandbuf[4];  unsigned char buf[275];	// max buffer size for stk500v2 at this point  unsigned char cmds[4];  int result;  OPCODE * rop;  DEBUG("STK500V2: stk500v2_paged_load(..,%s,%d,%d)\n",m->desc,page_size,n_bytes);  page_size = m->readsize;  rop = m->op[AVR_OP_READ];  // determine which command is to be used  if (strcmp(m->desc, "flash") == 0) {    commandbuf[0] = CMD_READ_FLASH_ISP;    rop = m->op[AVR_OP_READ_LO];  }   else if (strcmp(m->desc, "eeprom") == 0) {    commandbuf[0] = CMD_READ_EEPROM_ISP;  }  // the read command is common to both methods  if (rop == NULL) {    fprintf(stderr, "%s: stk500v2_paged_load: read instruction not defined for part \"%s\"\n",            progname, p->desc);    return -1;  }  avr_set_bits(rop, cmds);  commandbuf[3] = cmds[0];  stk500v2_loadaddr(pgm, 0);  for (addr=0; addr < n_bytes; addr += page_size) {    report_progress(addr, n_bytes,NULL);    if ((n_bytes-addr) < page_size)      block_size = n_bytes - addr;    else      block_size = page_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;    result = stk500v2_command(pgm,buf,4,sizeof(buf));    if (buf[1] != STATUS_CMD_OK) {      fprintf(stderr,"%s: stk500v2_paged_load: read command failed with %d\n",              progname,buf[1]);      return -1;    }#if 0    for (i=0;i<page_size;i++) {      fprintf(stderr,"%02X",buf[2+i]);      if (i%16 == 15) fprintf(stderr,"\n");    }#endif    memcpy(&m->buf[addr], &buf[2], block_size);  }  return n_bytes;}static int stk500v2_set_vtarget(PROGRAMMER * pgm, double v){  unsigned char uaref, utarg;  utarg = (unsigned)((v + 0.049) * 10);  if (stk500v2_getparm(pgm, PARAM_VADJUST, &uaref) != 0) {    fprintf(stderr,	    "%s: stk500v2_set_vtarget(): cannot obtain V[aref]\n",	    progname);    return -1;  }  if (uaref > utarg) {    fprintf(stderr,	    "%s: stk500v2_set_vtarget(): reducing V[aref] from %.1f to %.1f\n",	    progname, uaref / 10.0, v);    if (stk500v2_setparm(pgm, PARAM_VADJUST, utarg)	!= 0)      return -1;  }  return stk500v2_setparm(pgm, PARAM_VTARGET, utarg);}static int stk500v2_set_varef(PROGRAMMER * pgm, double v){  unsigned char uaref, utarg;  uaref = (unsigned)((v + 0.049) * 10);  if (stk500v2_getparm(pgm, PARAM_VTARGET, &utarg) != 0) {    fprintf(stderr,	    "%s: stk500v2_set_varef(): cannot obtain V[target]\n",	    progname);    return -1;  }  if (uaref > utarg) {    fprintf(stderr,	    "%s: stk500v2_set_varef(): V[aref] must not be greater than "	    "V[target] = %.1f\n",	    progname, utarg / 10.0);    return -1;  }  return stk500v2_setparm(pgm, PARAM_VADJUST, uaref);}static int stk500v2_set_fosc(PROGRAMMER * pgm, double v){  int fosc;  unsigned char prescale, cmatch;  static unsigned ps[] = {    1, 8, 32, 64, 128, 256, 1024  };  int idx, rc;  prescale = cmatch = 0;  if (v > 0.0) {    if (v > STK500V2_XTAL / 2) {      const char *unit;      if (v > 1e6) {        v /= 1e6;        unit = "MHz";      } else if (v > 1e3) {        v /= 1e3;        unit = "kHz";      } else        unit = "Hz";      fprintf(stderr,          "%s: stk500v2_set_fosc(): f = %.3f %s too high, using %.3f MHz\n",          progname, v, unit, STK500V2_XTAL / 2e6);      fosc = STK500V2_XTAL / 2;    } else      fosc = (unsigned)v;    for (idx = 0; idx < sizeof(ps) / sizeof(ps[0]); idx++) {      if (fosc >= STK500V2_XTAL / (256 * ps[idx] * 2)) {        /* this prescaler value can handle our frequency */        prescale = idx + 1;        cmatch = (unsigned)(STK500V2_XTAL / (2 * fosc * ps[idx])) - 1;        break;      }    }    if (idx == sizeof(ps) / sizeof(ps[0])) {      fprintf(stderr, "%s: stk500v2_set_fosc(): f = %u Hz too low, %u Hz min\n",          progname, fosc, STK500V2_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)    return rc;  return 0;}/* This code assumes that each count of the SCK duration parameter   represents 8/f, where f is the clock frequency of the STK500V2 master   processors (not the target).  This number comes from Atmel   application note AVR061.  It appears that the STK500V2 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 stk500v2_set_sck_period(PROGRAMMER * pgm, double v){  unsigned char dur;  double min, max;  min = 8.0 / STK500V2_XTAL;  max = 255 * min;  dur = v / min + 0.5;  if (v < min) {      dur = 1;      fprintf(stderr,	      "%s: stk500v2_set_sck_period(): p = %.1f us too small, using %.1f us\n",	      progname, v / 1e-6, dur * min / 1e-6);  } else if (v > max) {      dur = 255;      fprintf(stderr,	      "%s: stk500v2_set_sck_period(): p = %.1f us too large, using %.1f us\n",	      progname, v / 1e-6, dur * min / 1e-6);  }  return stk500v2_setparm(pgm, PARAM_SCK_DURATION, dur);}static int stk500v2_getparm(PROGRAMMER * pgm, unsigned char parm, unsigned char * value){  unsigned char buf[32];  buf[0] = CMD_GET_PARAMETER;  buf[1] = parm;  if (stk500v2_command(pgm, buf, 2, sizeof(buf)) < 0) {    fprintf(stderr,"%s: stk500v2_getparm(): failed to get parameter 0x%02x\n",            progname, parm);    return -1;  }  *value = buf[2];  return 0;}static int stk500v2_setparm(PROGRAMMER * pgm, unsigned char parm, unsigned char value){  unsigned char buf[32];  buf[0] = CMD_SET_PARAMETER;  buf[1] = parm;  buf[2] = value;  if (stk500v2_command(pgm, buf, 3, sizeof(buf)) < 0) {    fprintf(stderr, "\n%s: stk500v2_setparm(): failed to set parameter 0x%02x\n",            progname, parm);    return -1;  }  return 0;}static void stk500v2_display(PROGRAMMER * pgm, char * p){  unsigned char maj, min, hdw, topcard;  const char *topcard_name;  stk500v2_getparm(pgm, PARAM_HW_VER, &hdw);  stk500v2_getparm(pgm, PARAM_SW_MAJOR, &maj);  stk500v2_getparm(pgm, PARAM_SW_MINOR, &min);  stk500v2_getparm(pgm, PARAM_TOPCARD_DETECT, &topcard);  fprintf(stderr, "%sHardware Version: %d\n", p, hdw);  fprintf(stderr, "%sFirmware Version: %d.%d\n", p, maj, min);  if (1) {			// should check to see if it's a stk500 first    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;    }    fprintf(stderr, "%sTopcard         : %s\n", p, topcard_name);  }  stk500v2_print_parms1(pgm, p);  return;}static void stk500v2_print_parms1(PROGRAMMER * pgm, char * p){  unsigned char vtarget, vadjust, osc_pscale, osc_cmatch, sck_duration;  stk500v2_getparm(pgm, PARAM_VTARGET, &vtarget);  stk500v2_getparm(pgm, PARAM_VADJUST, &vadjust);  stk500v2_getparm(pgm, PARAM_OSC_PSCALE, &osc_pscale);  stk500v2_getparm(pgm, PARAM_OSC_CMATCH, &osc_cmatch);  stk500v2_getparm(pgm, PARAM_SCK_DURATION, &sck_duration);  fprintf(stderr, "%sVtarget         : %.1f V\n", p, vtarget / 10.0);  fprintf(stderr, "%sVaref           : %.1f V\n", p, vadjust / 10.0);  fprintf(stderr, "%sOscillator      : ", p);  if (osc_pscale == 0)    fprintf(stderr, "Off\n");  else {    int prescale = 1;    double f = STK500V2_XTAL / 2;    const char *unit;    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);    if (f > 1e6) {      f /= 1e6;      unit = "MHz";    } else if (f > 1e3) {      f /= 1000;      unit = "kHz";    } else      unit = "Hz";    fprintf(stderr, "%.3f %s\n", f, unit);  }  fprintf(stderr, "%sSCK period      : %.1f us\n", p,	  sck_duration * 8.0e6 / STK500V2_XTAL + 0.05);  return;}static void stk500v2_print_parms(PROGRAMMER * pgm){  stk500v2_print_parms1(pgm, "");}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;  pgm->program_enable = stk500v2_program_enable;  pgm->chip_erase     = stk500v2_chip_erase;  pgm->cmd            = stk500v2_cmd;  pgm->open           = stk500v2_open;  pgm->close          = stk500v2_close;  /*   * optional functions   */  pgm->paged_write    = stk500v2_paged_write;  pgm->paged_load     = stk500v2_paged_load;  pgm->print_parms    = stk500v2_print_parms;  pgm->set_vtarget    = stk500v2_set_vtarget;  pgm->set_varef      = stk500v2_set_varef;  pgm->set_fosc       = stk500v2_set_fosc;  pgm->set_sck_period = stk500v2_set_sck_period;  pgm->page_size      = 256;}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -