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

📄 avratmel.c

📁 tinyos-2.x.rar
💻 C
📖 第 1 页 / 共 2 页
字号:
    Send(writeEE, 2, 1);
    CheckResponse(writeEE[0]);
  }  
  else if (segment==SEG_FUSE){
    Info(3, "Write fuse/lock: byte %d = 0x%02X\n",
	 (int) addr, (int) byte);
    switch (addr) {
    case AVR_FUSE_LOW_ADDR:
      if (TestFeatures(AVR_FUSE_NEWWR))
	WriteFuseLowBits(byte);
      else if (TestFeatures(AVR_FUSE_OLDWR))
	WriteOldFuseBits(byte);
      break;
    case AVR_FUSE_HIGH_ADDR:
      if (TestFeatures(AVR_FUSE_HIGH))
	WriteFuseHighBits(byte);
      else
        Info (1, "Cannot write high fuse bits on this device");
      break;
    /* calibration byte (addr == 2) is read only */
    case AVR_CAL_ADDR:
      Info (1, "Cannot write calibration byte. It is read-only.\n");
      break;
    case AVR_LOCK_ADDR:
      WriteLockBits(byte);
      break;
    case AVR_FUSE_EXT_ADDR:
      if (TestFeatures(AVR_FUSE_EXT))
	WriteFuseExtBits(byte);
    }
  }
}

/*
 Write Fuse Bits (old):         7     6     5     4     3     2     1     0
 2323,8535:                     x     x     x     1     1     1     1     FSTRT
 2343:                          x     x     x     1     1     1     1     RCEN
 2333,4433:                     x     x     x     BODLV BODEN CKSL2 CKSL1 CKSL0
 m103,m603:                     x     x     x     1     EESAV 1     SUT1  SUT0
 */
void TAvrAtmel::WriteOldFuseBits (TByte val)
{
  TByte buf[5] = {'.', 0xac, (val & 0x1f) | 0xa0, 0x00, 0xd2 };
  Info (2, "Write fuse high bits: %02x\n", (int)val);
  Send (buf, 5, 2);
  CheckResponse (buf[1]);
}

/*
 Write Fuse Bits (Low, new):    7     6     5     4     3     2     1     0
 m161:                          1     BTRST 1     BODLV BODEN CKSL2 CKSL1 CKSL0
 m163,m323:                     BODLV BODEN 1     1     CKSL3 CKSL2 CKSL1 CKSL0
 m8,m16,m64,m128:               BODLV BODEN SUT1  SUT0  CKSL3 CKSL2 CKSL1 CKSL0
 tn12:                          BODLV BODEN SPIEN RSTDI CKSL3 CKSL2 CKSL1 CKSL0
 tn15:                          BODLV BODEN SPIEN RSTDI 1     1     CKSL1 CKSL0

 WARNING (tn12,tn15): writing SPIEN=1 disables further low voltage programming!
 */
void TAvrAtmel::WriteFuseLowBits (TByte val)
{
  // use new universal command.
  TByte buf[5] = {'.', 0xac, 0xa0, 0x00, val };
  Info (2, "Write fuse high bits: %02x\n", (int)val);
  Send (buf, 5, 2);
  CheckResponse (buf[1]);
}

/*
 Write Fuse Bits High:          7     6     5     4     3     2     1     0
 m163:                          1     1     1     1     1     BTSZ1 BTSZ0 BTRST
 m323:                          OCDEN JTGEN 1     1     EESAV BTSZ1 BTSZ0 BTRST
 m16,m64,m128:                  OCDEN JTGEN x     CKOPT EESAV BTSZ1 BTSZ0 BTRST
 m8:                            RSTDI WDTON x     CKOPT EESAV BTSZ1 BTSZ0 BTRST
 */
void TAvrAtmel::WriteFuseHighBits (TByte val)
{
  // use new universal command.
  TByte buf[5] = {'.', 0xac, 0xa8, 0x00, val };
  Info (2, "Write fuse high bits: %02x\n", (int)val);
  Send (buf, 5, 2);
  CheckResponse (buf[1]);
}

/*
 Write Extended Fuse Bits:      7     6     5     4     3     2     1     0
 m64,m128:                      x     x     x     x     x     x     M103C WDTON
 */
void TAvrAtmel::WriteFuseExtBits (TByte val)
{
  // use new universal command.
  TByte buf[5] = {'.', 0xac, 0xa4, 0x00, val };
  Info (2, "Write fuse extended bits: %02x\n", (int)val);
  Send (buf, 5, 2);
  CheckResponse (buf[1]);
}


void TAvrAtmel::FlushWriteBuffer(){
  if (page_addr_fetched){
    WriteProgramMemoryPage();  
  }
}

/* Chip erase can take a few seconds when talking to a boot loader,
   which does it one page at a time.  */

#ifndef CHIP_ERASE_TIMEOUT
#define CHIP_ERASE_TIMEOUT 5
#endif

void TAvrAtmel::ChipErase(){
  TByte eraseTarget [1] = { 'e' };
  Send (eraseTarget, 1, -1, CHIP_ERASE_TIMEOUT);
  CheckResponse(eraseTarget [0]);
  Info(1, "Erasing device ...\nReinitializing device\n");
  EnableAvr();
}

void TAvrAtmel::WriteLockBits(TByte bits){
  TByte lockTarget [2] = { 'l', 0xF9 | ((bits << 1) & 0x06) };
  Send (lockTarget, 2, 1);
  CheckResponse(lockTarget [0]);
  Info(1, "Writing lock bits ...\nReinitializing device\n");
  EnableAvr();
}

TByte TAvrAtmel::ReadFuseLowBits ()
{
  // use new universal command.
  TByte buf[5] = {'.', 0x50, 0x00, 0x00, 0x00 };
  Send (buf, 5, 2);
  CheckResponse (buf[1]);
  Info (2, "Read fuse low bits: %02x\n", (int)buf[0]);
  return buf[0];
}

TByte TAvrAtmel::ReadFuseHighBits ()
{
  // use new universal command.
  TByte buf[5] = {'.', 0x58, 0x08, 0x00, 0x00 };
  Send (buf, 5, 2);
  CheckResponse (buf[1]);
  Info (2, "Read fuse high bits: %02x\n", (int)buf[0]);
  return buf[0];
}

TByte TAvrAtmel::ReadCalByte(TByte addr)
{
  // use new universal command.
  TByte buf[5] = {'.', 0x38, 0x00, addr, 0x00 };
  Send (buf, 5, 2);
  CheckResponse (buf[1]);
  Info (2, "Read calibration byte: %02x\n", (int)buf[0]);
  return buf[0];
}

TByte TAvrAtmel::ReadFuseExtBits ()
{
  // use new universal command.
  TByte buf[5] = {'.', 0x50, 0x08, 0x00, 0x00 };
  Send (buf, 5, 2);
  CheckResponse (buf[1]);
  return buf[0];
  Info (2, "Read extended fuse bits: %02x\n", (int)buf[0]);
  return buf[0];
}

TByte TAvrAtmel::ReadLockFuseBits ()
{
  // use new universal command.
  TByte buf[5] = {'.', 0x58, 0x00, 0x00, 0x00 };
  Send (buf, 5, 2);
  CheckResponse (buf[1]);
  Info (2, "Read lock bits: %02x\n", (int)buf[0]);
  return buf[0];
}

// 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
TAvrAtmel::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.
    /* Read Signature Bytes */
    TByte sig_bytes[3] = {'s', 0, 0};
    Send(sig_bytes, 1, 3);
    if (sig_bytes[0]==0 && sig_bytes[1]==1 && sig_bytes[2]==2)
      rbits = 0xFC;
    else
      throw Error_Device ("ReadLockBits failed: are you sure this device has lock bits?");
  }
  return rbits;
}


/* Constructor/Destructor
*/

TAvrAtmel::TAvrAtmel():
  cache_lowbyte(false), apc_address(0x10000), apc_autoinc(false)
  {

  /* Select Part by Number or Name */
  desired_avrcode=0xff;
  const char* desired_partname = GetCmdParam("-dpart");
  bool got_device=false;
  
  if (desired_partname!=NULL) {
    if (desired_partname[0] >= '0' && desired_partname[0] <= '9'){
      desired_avrcode = strtol(&desired_partname[0],(char**)NULL,16); 
    } else{
      int j;
      for (j=0; prg_part[j].name[0] != 0; j++){
        if ((strcasecmp (desired_partname, prg_part[j].name)==0) ||
            (strcasecmp (desired_partname, prg_part[j].description)==0))
        {
	  desired_avrcode = prg_part[j].code;
	  break;
	}
      }
      if (prg_part[j].name[0]==0){throw Error_Device("-dpart: Invalid name.");}
    }
  }
  
  /* check: software version and supported part codes */
  TByte sw_version [2] = {'V', 0};
  TByte hw_version [2] = {'v', 0};
  Send(sw_version, 1, 2);
  Send(hw_version, 1, 2);
  Info(1, "Programmer Information:\n"
          "  Software Version: %c.%c, Hardware Version: %c.%c\n", 
	  sw_version [0], sw_version [1],
	  hw_version [0], hw_version [1]);
  
  /* Detect Auto-Increment */
  if (sw_version[0]>='2'){
    apc_autoinc=true;
    Info(2, "Address Auto Increment Optimization Enabled\n");
  }
  
  /* Retrieve supported codes */
  TByte sup_codes[1] = {'t'};
  Tx(sup_codes, 1);
  TByte buf_code;
  timeval timeout = {1, 0};
  if (desired_partname==NULL){
    Info(1, "  Supported Parts:\n\tNo\tAbbreviation\tDescription\n");
  }
  do{
    Rx(&buf_code, 1, &timeout);
    if (buf_code==0){break;}    
    if (desired_partname!=NULL){ 
      if (buf_code==desired_avrcode){got_device=true;}
      if (desired_avrcode!=AUTO_SELECT) continue; 
    }
    int j;
    for (j=0; prg_part[j].name[0] != 0; j++){
      if (prg_part[j].code == buf_code){
        prg_part[j].supported = true;
	if (desired_avrcode!=AUTO_SELECT){
	  Info(1, "\t%.2x\t%s\t\t%s\n", 
	    buf_code, prg_part[j].name, prg_part[j].description);
	}
	break;
      }
    }
    if (prg_part[j].code == 0) {
      Info(1, "    - %.2xh (not on the uisp's list yet)\n", buf_code);
    }
  } while (1);  
  Info(1, "\n");
  
  if (got_device==false) {
    if (desired_partname==NULL){
      throw Error_Device("Select a part from the list with the: -dpart\n"
        "or use the -dpart=auto option for auto-select.\n");
    } 
    else if (desired_avrcode!=AUTO_SELECT){
      throw Error_Device("Programmer does not supported chosen device.");
    }
  }
  
  EnableAvr();
}

TAvrAtmel::~TAvrAtmel(){
  /* leave programming mode! Due to this 
     procedure, enableAvr had to be taken out
     of TAtmelAvr::TAtmelAvr func. */
  LeaveProgrammingMode();
}

⌨️ 快捷键说明

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