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

📄 stk500.c

📁 Micro In-System Programmer Brief Installation Notes Enter the src directory. If uisp does not
💻 C
📖 第 1 页 / 共 2 页
字号:
}/* ReadLockBits tries to return the lock bits in a uniform order, despite the   differences in different AVR versions.  The goal is to get the lock bits   into this order:       x x BLB12 BLB11 BLB02 BLB01 LB2 LB1   For devices that don't support a boot block, the BLB bits will be 1. */TByte TStk500::ReadLockBits(){  TByte rbits = 0xFF;  if (TestFeatures(AVR_LOCK_BOOT)) {    /* x x BLB12 BLB11 BLB02 BLB01 LB2 LB1 */    rbits = ReadLockFuseBits();  } else if (TestFeatures(AVR_LOCK_RD76)) {    rbits = ReadLockFuseBits();    /* LB1 LB2 x x x x x x -> 1 1 1 1 1 1 LB2 LB1 */    rbits = ((rbits >> 7) & 1) | ((rbits >> 5) & 1) | 0xFC;  } else if (TestFeatures(AVR_LOCK_RD12)) {    rbits = ReadLockFuseBits();    /* x x x x x LB2 LB1 x -> 1 1 1 1 1 1 LB2 LB1 */    rbits = ((rbits >> 1) & 3) | 0xFC;  } else {    /* if its signature returns 0,1,2 then say it's locked. */    EnterProgrammingMode();    ReadSignature();    LeaveProgrammingMode();    if (vendor_code == 0 &&        part_family == 1 &&        part_number == 2)    {      rbits = 0xFC;    }    else    {      throw Error_Device ("ReadLockBits failed: are you sure this device "                          "has lock bits?");    }  }  return rbits;}TByte TStk500::ReadCalFuseBits(int addr){  TByte cmd[] = { 0x38, 0x00, addr, 0x00 };  return UniversalCmd(cmd);}TByte TStk500::ReadFuseLowBits(){  TByte cmd[] = { 0x50, 0x00, 0x00, 0x00 };  return UniversalCmd(cmd);}TByte TStk500::ReadFuseHighBits(){  TByte cmd[] = { 0x58, 0x08, 0x00, 0x00 };  return UniversalCmd(cmd);}TByte TStk500::ReadFuseExtBits(){  TByte cmd[] = { 0x50, 0x08, 0x00, 0x00 };  return UniversalCmd(cmd);}void TStk500::WriteLockFuseBits(TByte bits){  TByte cmd[] = { 0xac, 0xff, 0xff, bits };  UniversalCmd(cmd);}void TStk500::WriteFuseLowBits(TByte bits){  TByte cmd[] = { 0xac, 0xa0, 0xff, bits };  UniversalCmd(cmd);}void TStk500::WriteFuseHighBits(TByte bits){  TByte cmd[] = { 0xac, 0xa8, 0xff, bits };  UniversalCmd(cmd);}void TStk500::WriteFuseExtBits(TByte bits){  TByte cmd[] = { 0xac, 0xa4, 0xff, bits };  UniversalCmd(cmd);}/*   0 = program (clear bit), 1 = leave unchanged   bit 0 = LB1   bit 1 = LB2   bit 2 = BLB01   bit 3 = BLB02   bit 4 = BLB11   bit 5 = BLB12   bit 6 = 1 (reserved)   bit 7 = 1 (reserved) */void TStk500::WriteLockBits(TByte bits){  TByte wbits;  if (TestFeatures(AVR_LOCK_BOOT))  {    /* x x BLB12 BLB11 BLB02 BLB01 LB2 LB1 */    wbits = bits;  }  else if (TestFeatures(AVR_LOCK_RD76))  {    /* x x x x x x LB2 LB1 -> LB1 LB2 1 1 1 1 1 1 */    wbits = ((bits << 7) & 0x80) | ((bits << 5) & 0x40) | 0x3f;  }  else if (TestFeatures(AVR_LOCK_RD12))  {    /* x x x x x x LB2 LB1 -> 1 1 1 1 1 LB2 LB1 1 */    wbits = ((bits << 1) & 0x06) | 0xF9;  }  else  {    Info (0, "WriteLockBits failed: are you sure this device has lock bits?");    return;  }  WriteLockFuseBits(wbits);}void TStk500::Initialize(){  TByte buf[100];  TByte vmajor;  TByte vminor;  TByte num_ext_parms = 3;  memcpy(buf, pSTK500, sizeof(pSTK500));  Send(buf, sizeof(pSTK500), sizeof(pSTK500_Reply));  if (memcmp(buf, pSTK500_Reply, sizeof(pSTK500_Reply)) != 0) {    throw Error_Device ("[VP 1] Device is not responding correctly."); }  memcpy(buf, &prg_part[desired_part].params,     sizeof(prg_part[desired_part].params));  Send(buf, sizeof(prg_part[desired_part].params),       sizeof(DeviceParam_Reply));  if (memcmp(buf, DeviceParam_Reply, sizeof(DeviceParam_Reply)) != 0) {    throw Error_Device ("[VP 2] Device is not responding correctly."); }  memcpy(buf, SWminor, sizeof(SWminor));  Send(buf, sizeof(SWminor), sizeof(SWminor_Reply));  vminor = buf[1];  memcpy(buf, SWmajor, sizeof(SWmajor));  Send(buf, sizeof(SWmajor), sizeof(SWmajor_Reply));  vmajor = buf[1];  printf ("Firmware Version: %d.%d\n", vmajor, vminor);  if (! ((vmajor == 1 && vminor >= 7) || (vmajor > 1)))    throw Error_Device ("Need STK500 firmware version 1.7 or newer.");  if ((vmajor == 1 && vminor >= 14) || (vmajor > 1))      num_ext_parms = 4;  buf[0] = 0x45;  buf[1] = num_ext_parms;  memcpy(buf+2, &prg_part[desired_part].ext_params, num_ext_parms);  buf[num_ext_parms+2] = 0x20;  Send(buf, num_ext_parms+3, sizeof(ExtDevParams_Reply));  if (memcmp(buf, ExtDevParams_Reply, sizeof(ExtDevParams_Reply)) != 0) {    throw Error_Device ("[VP 3] Device is not responding correctly."); }}void TStk500::EnterProgrammingMode() {  TByte buf[100];  memcpy(buf, EnterPgmMode, sizeof(EnterPgmMode));  Send(buf, sizeof(EnterPgmMode), sizeof(EnterPgmMode_Reply));  if (memcmp(buf, EnterPgmMode_Reply, sizeof(EnterPgmMode_Reply)) != 0) {    throw Error_Device ("Failed to enter programming mode."); }}void TStk500::LeaveProgrammingMode() {  TByte buf[100];  memcpy(buf, LeavePgmMode, sizeof(LeavePgmMode));  Send(buf, sizeof(LeavePgmMode), sizeof(LeavePgmMode_Reply));  if (memcmp(buf, LeavePgmMode_Reply, sizeof(LeavePgmMode_Reply)) != 0) {    throw Error_Device ("[LPM] Device is not responding correctly."); }}/* TRoth/2002-05-28: A Universal Command seems to be just the 4 bytes of an   SPI command. I'm basing this on my interpretation of the doc/README.stk500   and Table 129 of the mega128 datasheet (page 300). */TByte TStk500::UniversalCmd(TByte cmd[]){  TByte buf[6] = { 0x56, 0x00, 0x00, 0x00, 0x00, 0x20 };  memcpy(buf+1, cmd, 4);  EnterProgrammingMode();  /* Expected response is { 0x14, <output>, 0x10 } */  Send(buf, sizeof(buf), 3);  LeaveProgrammingMode();  if ((buf[0] != 0x14) || (buf[2] != 0x10))  {    throw Error_Device ("[UC] Device is not responding correctly.");  }  return buf[1];}void TStk500::ReadSignature() {  TByte buf[100];  memcpy(buf, GetSignature, sizeof(GetSignature));  Send(buf, sizeof(GetSignature), sizeof(GetSignature_Reply));  vendor_code = buf[1];  part_family = buf[2];  part_number = buf[3];}void TStk500::ReadMem(){  TByte buf[0x200];  int wordsize;  TAddr addr;  TByte seg;  if (segment == SEG_FLASH) {    wordsize = 2;    seg = Flash;  } else if (segment == SEG_EEPROM) {    wordsize = 1;    seg = EEPROM;  } else {    throw Error_Device ("TStk500::ReadMem() called for invalid segment.");  }  read_buffer[segment] = new TByte[GetSegmentSize()];  EnterProgrammingMode();  addr = 0;  for (unsigned int addr=0; addr<GetSegmentSize(); addr+=0x100) {    memcpy(buf, SetAddress, sizeof(SetAddress));    buf[1] = (addr/wordsize) & 0xff;    buf[2] = ((addr/wordsize) >> 8) & 0xff;    Send(buf, sizeof(SetAddress), sizeof(SetAddress_Reply));    if (memcmp(buf, SetAddress_Reply, sizeof(SetAddress_Reply)) != 0) {      throw Error_Device ("[RM] Device is not responding correctly."); }       memcpy(buf, ReadMemory, sizeof(ReadMemory));    buf[3] = seg;    Send(buf, sizeof(ReadMemory), 2+0x100);    memcpy(read_buffer[segment]+addr, buf+1, 0x100);  }  LeaveProgrammingMode();}static TByteconvert_voltage (const char *val){    char *endptr;    double v = strtod (val, &endptr);    if (endptr == val)        throw Error_Device ("Bad voltage value.");    if (v > 6.0)        throw Error_Device ("Voltages can not be greater than 6.0 volts");    if (v < 0.0)        throw Error_Device ("Voltages can not be less the 0.0 volts");    TByte res = (int)(v * 10.01);    return res;}TStk500::TStk500() {  /* Select Part by name */  desired_part=-1;  const char* desired_partname = GetCmdParam("-dpart");  if (desired_partname!=NULL) {    int j;    for (j=0; prg_part[j].name[0] != 0; j++){      if (strcasecmp (desired_partname, prg_part[j].name)==0){    desired_part = j;    break;      }    }    if (prg_part[j].name[0]==0){throw Error_Device("-dpart: Invalid name.");}  } else {    int i = 0;    Info(0, "No part specified, supported devices are:\n");    while (prg_part[i].name[0] != '\0')      Info(0, "%s\n", prg_part[i++].name);    throw Error_Device("");  }  /* Force parallel programming mode if the use wants it, otherwise, just use     what the device prefers (usually serial programming). */  if (GetCmdParam("-dhiv",false))      prg_part[desired_part].params.progtype = STK500_PROG_HIV;  Initialize();  /* Handle Reading/Writing ARef voltage level. */  const char *val;  if ((val=GetCmdParam("--wr_vtg", true)))  {      TByte value = convert_voltage (val);      printf ("Setting VTarget to %d.%d V\n", value/10, value%10);      TByte aref = ReadParam(0x85);      if (aref > value)      {          printf ("Setting ARef == VTarget to avoid damaging device.\n");          WriteParam(0x85, value);      }      WriteParam(0x84, value);  }  if ((val=GetCmdParam("--wr_aref", true)))  {      TByte value = convert_voltage (val);      printf ("Setting ARef to %d.%d V\n", value/10, value%10);      TByte vtg = ReadParam(0x84);      if (vtg < value)      {          printf ("Setting ARef == VTarget to avoid damaging device.\n");          WriteParam(0x84, value);      }      WriteParam(0x85, value);  }  if (GetCmdParam("--rd_vtg", false))  {      TByte val = ReadParam(0x84);      printf("VTarget = %d.%d V\n", val/10, val%10);  }  if (GetCmdParam("--rd_aref", false))  {      TByte val = ReadParam(0x85);      printf("ARef = %d.%d V\n", val/10, val%10);  }  if (GetCmdParam("--rd_osc", false))  {      TByte p = ReadParam(0x86);      TByte n = ReadParam(0x87);      TByte sc = ReadParam(0x89);      printf("Oscillator: p=%x, n=%x, sc=%x, ",p,n,sc);      if (p==0)          printf ("0 Hz (stopped)\n");      else      {          double freq=clockbase/clockscale[p] / (n+1.0);          printf ("frequency=%.8g Hz\n", freq);      }  }  if ((val=GetCmdParam("--wr_osc", true)))  {      /* See page 19 of the STK500 protocol documentation from Atmel */      TByte p,n,sc;      double freq=atof(val);      double setfreq;      if (val == 0)      {          /* Special case for stopped */          p=0;          n=0;          sc=0xff;      }      else      {          /* Select lowest usable prescaler value */          for (p=1; p<=7; p++)          {              if (clockbase / clockscale[p] / freq <= 256)                  break;          }          if (p > 7)          {              p=7;              n=0xff;          }          else              n=(int)(clockbase/clockscale[p]/freq+.5) - 1;          setfreq=clockbase/clockscale[p]/(n+1.0);          if (8000000/setfreq-1 > 0xff)              sc=0xff;          else              sc=(int)(8000000/setfreq) - 1;          printf ("Setting oscillator frequency to %.8g (p=%d,n=%d,sc=%d)\n",                  setfreq, p, n, sc);          WriteParam(0x86, p);          WriteParam(0x87, n);          WriteParam(0x89, sc);      }        }  EnterProgrammingMode();  ReadSignature();  LeaveProgrammingMode();  Identify();  /* For some unknown reason, some stk500 boards with firmware version 1.14,   * don't work right without this sleep and re-init.   * Reported 2003-07-31 by Simon Allen <simon@icemans.co.uk> */  sleep(1);  Initialize();  write_buffer[SEG_FLASH] = NULL;  write_buffer[SEG_EEPROM] = NULL;  read_buffer[SEG_FLASH] = NULL;  read_buffer[SEG_EEPROM] = NULL;  minaddr = TAddr(-1);  maxaddr = 0;}TStk500::~TStk500() {  delete write_buffer[SEG_FLASH];  delete write_buffer[SEG_EEPROM];  delete read_buffer[SEG_FLASH];  delete read_buffer[SEG_EEPROM];}

⌨️ 快捷键说明

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