📄 avratmel.c
字号:
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#endifvoid 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.TByteTAvrAtmel::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 + -