📄 stk500.c
字号:
/* 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?", pNodename); } } return rbits;}TByte TStk500::ReadCalFuseBits(int addr){ TByte cmd[] = { 0xc8, 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; bool bMIB510 = false; //----------------- XBOW mod for MIB510, cmd MIB510 to control RS232 lines---- if (bMIB510 = strcmp(GetCmdParam("-dprog"), "mib510") == 0) { int itry= 8; //try 8 times while (itry > 0){ itry--; memcpy(buf, IspMode, sizeof(IspMode)); buf[8] = 1; SendOnly(buf, sizeof(IspMode)); Send(buf, sizeof(IspMode), sizeof(IspMode_Reply)); if (memcmp(buf, IspMode_Reply, sizeof(IspMode_Reply)) == 0) itry = 0; } memcpy(buf, IspMode, sizeof(IspMode)); buf[8] = 1; Send(buf, sizeof(IspMode), sizeof(IspMode_Reply)); if (memcmp(buf, IspMode_Reply, sizeof(IspMode_Reply)) != 0) { throw Error_Device ("Device is not responding correctly.",pNodename); } }//----------------------------------------------------------------------------- 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.", pNodename); } 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.", pNodename); } 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]; if (bMIB510){ printf ("Firmware Version: %c.%c\n", vmajor, vminor); return; } printf ("Firmware Version: %d.%d\n", vmajor, vminor);#if 0 if (! ((vmajor == 1 && vminor >= 7) || (vmajor > 1))) throw Error_Device ("Need STK500 firmware version 1.7 or newer.", pNodename);#endif 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.", pNodename); }}void TStk500::Cleanup() { TByte buf[100]; //----------------- XBOW mod for MIB510, cmd MIB510 to release RS232 lines if (strcmp(GetCmdParam("-dprog"), "mib510") == 0) { memcpy(buf, IspMode, sizeof(IspMode)); buf[8] = 0; Send(buf, sizeof(IspMode), sizeof(IspMode_Reply)); if (memcmp(buf, IspMode_Reply, sizeof(IspMode_Reply)) != 0) { throw Error_Device ("Device is not responding correctly.",pNodename); } }}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.", pNodename); }}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.", pNodename); }}/* 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.", pNodename); } 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];}//mib510: read 256 bytes of flash memory starting at addrvoid TStk500::ReadMemPage(TAddr addr){ TByte buf[0x200]; int wordsize; TByte seg; if (segment == SEG_FLASH) { wordsize = 2; seg = Flash; } else if (segment == SEG_EEPROM) { wordsize = 1; seg = EEPROM; } else { throw Error_Device ("TStk500::ReadMemPage() called for invalid segment.",pNodename); } EnterProgrammingMode(); 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 ("Device is not responding correctly.",pNodename); } memcpy(buf, ReadMemory, sizeof(ReadMemory)); buf[3] = seg; Send(buf, sizeof(ReadMemory), 2+0x100); memcpy(read_buffer[segment]+addr, buf+1, 0x100); LeaveProgrammingMode();}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.",pNodename); } 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.", pNodename); } 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"); pNodename = GetCmdParam("-dhost"); 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.",pNodename);} } 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("-dparallel",false)) prg_part[desired_part].params.progtype = STK500_PROG_PARALLEL; 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); } EnterProgrammingMode(); ReadSignature(); LeaveProgrammingMode(); Identify(); write_buffer[SEG_FLASH] = NULL; write_buffer[SEG_EEPROM] = NULL; read_buffer[SEG_FLASH] = NULL; read_buffer[SEG_EEPROM] = NULL; maxaddr = 0;}TStk500::~TStk500() { Cleanup(); 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 + -