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

📄 stk500.c

📁 无线传感器网络操作系统源代码
💻 C
字号:
/* Stk500.C, Daniel Berntsson, 2001 */

#include "Stk500.h"
#include "Serial.h"


const TByte TStk500::pSTK500[] = { 0x30, 0x20 };
const TByte TStk500::pSTK500_Reply[] = { 0x14, 0x10 };

const TByte TStk500::SWminor[] = { 0x41, 0x82, 0x20 };
const TByte TStk500::SWminor_Reply[] = { 0x14, 0x07, 0x10 };

const TByte TStk500::SWmajor[] = { 0x41, 0x81, 0x20 };
const TByte TStk500::SWmajor_Reply[] = {0x14, 0x01, 0x10 };

const TByte TStk500::MagicNumber[] = { 0x45, 0x03, 0x00, 0xD7, 0xA0, 0x20 };
const TByte TStk500::MagicNumber_Reply[] = {0x14, 0x10 };

const TByte TStk500::EnterPgmMode[] = { 0x50, 0x20 };
const TByte TStk500::EnterPgmMode_Reply[] = { 0x14, 0x10 };

const TByte TStk500::LeavePgmMode[] = { 0x51, 0x20 };
const TByte TStk500::LeavePgmMode_Reply[] = { 0x14, 0x10 };

const TByte TStk500::SetAddress[] = { 0x55, '?', '?', 0x20 };
const TByte TStk500::SetAddress_Reply[] = { 0x14, 0x10 };

const TByte TStk500::EraseDevice[] = { 0x52, 0x20 };
const TByte TStk500::EraseDevice_Reply[] = { 0x14, 0x10 };

const TByte TStk500::WriteMemory[] = { 0x64, '?', '?', '?' };
const TByte TStk500::WriteMemory_Reply[] = { 0x14, 0x10 };

const TByte TStk500::ReadMemory[] = { 0x74, 0x01, 0x00, '?', 0x20 };;
const TByte TStk500::ReadMemory_Reply[] = { 0x14 };

const TByte TStk500::GetSignature[] = {0x75, 0x20};
const TByte TStk500::GetSignature_Reply[] = {0x75, '?', '?', '?', 0x20};

const TByte TStk500::CmdStopByte[] = { 0x20 };

const TByte TStk500::ReplyStopByte[] = { 0x10 };

const TByte TStk500::Flash = 'F';

const TByte TStk500::EEPROM = 'E';

const TByte TStk500::DeviceParam_Reply[] = { 0x14, 0x10 };

const TStk500::SPrgPart TStk500::prg_part[] = {
  {"AT90S4414",
   {0x42, 0x50, 0x00, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x7f, 0x7f, 0x80,
    0x7f, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x10, 0x00, 0x20}
  },
  {"AT90S2313",
   {0x42, 0x40, 0x00, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x7f, 0x7f, 0x80,
    0x7f, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x08, 0x00, 0x20}
  },
  {"AT90S1200",
   {0x42, 0x33, 0x00, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0xff, 0xff, 0x00,
    0xff, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x04, 0x00, 0x20}
  },
  {"AT90S2323",
   {0x42, 0x41, 0x00, 0x00, 0x00, 0x01, 0x00, 0x01, 0x01, 0xff, 0xff, 0x00,
    0xff, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x08, 0x00, 0x20}
  },
  {"AT90S2343",
   {0x42, 0x43, 0x00, 0x00, 0x00, 0x01, 0x00, 0x01, 0x01, 0xff, 0xff, 0x00,
    0xff, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x08, 0x00, 0x20}
  },
  {"AT90S2333",
   {0x42, 0x42, 0x00, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0xff, 0xff, 0x00,
    0xff, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x08, 0x00, 0x20}
  },
  {"AT90S4433",
   {0x42, 0x51, 0x00, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0xff, 0xff, 0x00,
    0xff, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x10, 0x00, 0x20}
  },
  {"AT90S4434",
   {0x42, 0x52, 0x00, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0xff, 0xff, 0x00,
    0xff, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x10, 0x00, 0x20}
  },
  {"AT90S8515",
   {0x42, 0x60, 0x00, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x7f, 0x7f, 0x80,
    0x7f, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x20, 0x00, 0x20}
  },
  {"AT90S8535",
   {0x42, 0x61, 0x00, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0xff, 0xff, 0x00,
    0xff, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x20, 0x00, 0x20}
  },
  {"ATtiny11",
   {0x42, 0x11, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x20}
  },
  {"ATtiny12",
   {0x42, 0x12, 0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x01, 0xff, 0xff, 0xff,
    0xff, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x04, 0x00, 0x20}
  },
  {"ATtiny15",
   {0x42, 0x13, 0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x01, 0xff, 0xff, 0xff,
    0xff, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x04, 0x00, 0x20}
  },
  {"ATtiny22",
   {0x42, 0x20, 0x00, 0x00, 0x00, 0x01, 0x00, 0x01, 0x01, 0xff, 0xff, 0x00,
    0xff, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x08, 0x00, 0x20}
  },
  {"ATtiny28",
   {0x42, 0x22, 0x00, 0x00, 0x01, 0x00, 0x01, 0x01, 0x01, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x20}
  },
  {"ATmega323",
   {0x42, 0x90, 0x00, 0x00, 0x01, 0x01, 0x01, 0x01, 0x02, 0xff, 0xff, 0xff,
    0xff, 0x00, 0x80, 0x04, 0x00, 0x00, 0x00, 0x80, 0x00, 0x20}
  },
  {"ATmega161",
   {0x42, 0x80, 0x00, 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0xff, 0xff, 0xff,
    0xff, 0x00, 0x80, 0x02, 0x00, 0x00, 0x00, 0x40, 0x00, 0x20}
  },
  {"ATmega163",
   {0x42, 0x81, 0x00, 0x00, 0x01, 0x01, 0x01, 0x01, 0x02, 0xff, 0xff, 0xff,
    0xff, 0x00, 0x80, 0x02, 0x00, 0x00, 0x00, 0x40, 0x00, 0x20}
  },
  {"ATmega103",
   {0x42, 0xb1, 0x00, 0x00, 0x01, 0x00, 0x00, 0x01, 0x01, 0x00, 0x00, 0x00,
    0x00, 0x01, 0x00, 0x10, 0x00, 0x00, 0x02, 0x00, 0x00, 0x20}
  },
  {"ATmega128",
   {0x42, 0xb2, 0x00, 0x00, 0x01, 0x01, 0x01, 0x01, 0x03, 0xff, 0xff, 0xff,
    0xff, 0x01, 0x00, 0x10, 0x00, 0x00, 0x02, 0x00, 0x00, 0x20}
  },
  {"", {0}}
};


/* Read byte from active segment at address addr. */
TByte TStk500::ReadByte(TAddr addr){

  if (read_buffer == NULL)
    ReadMem();

  return read_buffer[addr];
}


/* Write byte to active segment */
void TStk500::WriteByte(TAddr addr, TByte byte, bool flush_buffer=true){

  if (write_buffer == NULL) {
    write_buffer = new TByte[GetSegmentSize()];
    memset(write_buffer, 0xff, GetSegmentSize());
  }

  if (addr > maxaddr)
    maxaddr = addr;

  write_buffer[addr] = byte;
}


void TStk500::FlushWriteBuffer(){
  TByte buf[0x200];
  int wordsize;
  TAddr addr;
  TByte seg;

  if (segment == SEG_FLASH) {
    wordsize = 2;
    seg = Flash;
  } else {
    wordsize = 1;
    seg = EEPROM;
  }

  EnterProgrammingMode();

  addr = 0;
  for (unsigned int addr=0; addr<maxaddr; 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 ("Device is not responding correctly."); }

    memcpy(buf, WriteMemory, sizeof(WriteMemory));
    buf[1] = 0x01;
    buf[2] = 0x00;
    buf[3] = seg;
    memcpy(buf+sizeof(WriteMemory), write_buffer+addr, 0x100);
    memcpy(buf+sizeof(WriteMemory)+0x100,
       CmdStopByte, sizeof(CmdStopByte));
    Send(buf, sizeof(WriteMemory)+0x100+sizeof(CmdStopByte),
     sizeof(WriteMemory_Reply));
    if (memcmp(buf, WriteMemory_Reply, sizeof(WriteMemory_Reply)) != 0) {
      throw Error_Device ("Device is not responding correctly."); }
  }   
  LeaveProgrammingMode();
}


/* Chip Erase */
void TStk500::ChipErase(){
  TByte buf[100];

  EnterProgrammingMode();

  memcpy(buf, EraseDevice, sizeof(EraseDevice));
  Send(buf, sizeof(EraseDevice), sizeof(EraseDevice_Reply));
  if (memcmp(buf, EraseDevice_Reply, sizeof(EraseDevice_Reply)) != 0) {
    throw Error_Device ("Device is not responding correctly."); }

  LeaveProgrammingMode();
}


/* Brrr.. evil :( */
void TStk500::WriteLockBits(TByte bits){
  throw Error_Device ("TStk500::WriteLockBits not implemented.");
}


void TStk500::EnterProgrammingMode() {
  TByte buf[100];
  TByte vmajor;
  TByte vminor;

  memcpy(buf, pSTK500, sizeof(pSTK500));
  Send(buf, sizeof(pSTK500), sizeof(pSTK500_Reply));
  if (memcmp(buf, pSTK500_Reply, sizeof(pSTK500_Reply)) != 0) {
    throw Error_Device ("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 ("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];

  if (! (vmajor == 1 && vminor == 7))
    throw Error_Device ("Need STK500 firmware version 1.7.");

  memcpy(buf, MagicNumber, sizeof(MagicNumber));
  Send(buf, sizeof(MagicNumber), sizeof(MagicNumber_Reply));
  if (memcmp(buf, MagicNumber_Reply, sizeof(MagicNumber_Reply)) != 0) {
    throw Error_Device ("Device is not responding correctly."); }

  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 ("Device is not responding correctly."); }
}


void TStk500::ReadSignature() {
  TByte buf[100];

  memcpy(buf, GetSignature, sizeof(GetSignature));
  Send(buf, sizeof(GetSignature), sizeof(GetSignature_Reply));
  part_number = buf[1];
  part_family = buf[2];
  vendor_code = buf[3];
}


void TStk500::ReadMem(){
  TByte buf[0x200];
  int wordsize;
  TAddr addr;
  TByte seg;

  read_buffer = new TByte[GetSegmentSize()];

  if (segment == SEG_FLASH) {
    wordsize = 2;
    seg = Flash;
  } else {
    wordsize = 1;
    seg = EEPROM;
  }

  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 ("Device is not responding correctly."); }
   
    memcpy(buf, ReadMemory, sizeof(ReadMemory));
    buf[3] = seg;
    Send(buf, sizeof(ReadMemory), 2+0x100);

    memcpy(read_buffer+addr, buf+1, 0x100);
  }

  LeaveProgrammingMode();
}


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 (strcmp (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("");
  }

  EnterProgrammingMode();
  ReadSignature();
  LeaveProgrammingMode();
  Identify();

  write_buffer = NULL;
  read_buffer = NULL;
  maxaddr = 0;
}



TStk500::~TStk500() {
  delete write_buffer;
  delete read_buffer;
}

⌨️ 快捷键说明

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