stk500.c
来自「tinyos-2.x.rar」· C语言 代码 · 共 960 行 · 第 1/2 页
C
960 行
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= 5; //try 5 times
while (itry > 0){
itry--;
memcpy(buf, IspMode, sizeof(IspMode));
buf[8] = 1;
SendOnly(buf, sizeof(IspMode));
try {
Send(buf, sizeof(IspMode), sizeof(IspMode_Reply), 1);
if (memcmp(buf, IspMode_Reply, sizeof(IspMode_Reply)) == 0) itry = 0;
}
catch (Error_Device e) {
}
}
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 addr
void 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 TByte
convert_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 + =
减小字号Ctrl + -
显示快捷键?