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

📄 avratmel.c

📁 用于传感器网络的节点操作系统 TinyOS 结构设计非常有意思
💻 C
字号:
/*	AvrAtmel.C		Device driver for the Serial Atmel Low Cost Programmer	Uros Platise (c) 1999*/#include <sys/time.h>#include <sys/types.h>#include <unistd.h>#include <stdio.h>#include <string.h>#include <stdlib.h>#include "AvrAtmel.h"#define AUTO_SELECT	0/* Low Cost Atmel Programmer AVR Codes   Valid for software version: SW_MAJOR=2 SW_MINOR=0      Code 0xff is reserved for invalid code. Update the   TAvrAtmel constructor if Atmel comes up with it.*/TAvrAtmel::SPrgPart TAvrAtmel::prg_part [] = {  /* 0x10, 0x11 = AT90S1200 rev. A, B (very old) */  {"S1200C", 0x12, "AT90S1200 Revision C", false}, /* old */  {"S1200D", 0x13, "AT90S1200 Revision D", false},  {"S2313A", 0x20, "AT90S2313 Revision A", false},  {"S2323A", 0x48, "AT90S2323 Revision A", false},  {"S4414A", 0x28, "AT90S4414 Revision A", false},  {"S8515A", 0x38, "AT90S8515 Revision A", false},  {"S8252",  0x86, "AT89S8252", false},  {"S01838C",0x40, "ATmega103 Revision C", false}, /* old */  {"S01838D",0x41, "ATmega103 Revision D", false},#if 1  /* more device codes, mostly reverse-engineered from avrprog.exe that     comes with AVR Studio (but where is the updated avr910.asm ???     version 2.0 updated 1998-01-06 only handles the above devices).     XXX - ATtiny22 is missing from avrprog.exe (should work as a 2343).  */  {"S4433",  0x30, "AT90S4433", false},  {"S2333",  0x34, "AT90S2333", false},	  /* 0x38 = AT90S8515 */	  /* 0x40 = ATmega103 rev. C (old) */	  /* 0x41 = ATmega103 */  {"M603",   0x42, "ATmega603", false},	  /* 0x48 = AT90S2323 */  {"S2343",  0x4C, "AT90S2343", false}, /* ATtiny22 ??? */  {"TN11",   0x50, "ATtiny11",  false}, /* parallel */  {"TN10",   0x51, "ATtiny10",  false}, /* parallel */  {"TN12",   0x55, "ATtiny12",  false},  {"TN15",   0x56, "ATtiny15",  false},  {"TN19",   0x58, "ATtiny19",  false}, /* parallel ??? */  {"TN28",   0x5C, "ATtiny28",  false}, /* parallel */  {"M161",   0x60, "ATmega161", false},  {"M163",   0x64, "ATmega163", false},  {"M83",    0x65, "ATmega83",  false},  {"AVR109", 0x66, "AVR109",    false}, /* self programming, AVR109 app note */  {"S8535",  0x68, "AT90S8535", false},  {"S4434",  0x6C, "AT90S4434", false},  {"C8534",  0x70, "AT90C8534", false}, /* parallel */  {"M323",   0x72, "ATmega323", false},  {"89C2051",0x81, "AT89C2051", false}, /* parallel */  {"89C51",  0x82, "AT89C51",   false}, /* parallel */  {"89LV51", 0x83, "AT89LV51",  false}, /* parallel */  {"89C52",  0x84, "AT89C52",   false}, /* parallel */  {"89LV52", 0x85, "AT89LV52",  false}, /* parallel */	  /* 0x86 = AT89S8252 */  {"89S53",  0x87, "AT89S53",   false},  /* 0x88..0xDF reserved for AT89,     0xE0..0xFF reserved */#endif  {"auto",   AUTO_SELECT, "Auto detect", false},    {"",       0x00, "", false}};/* Private Functions*/void TAvrAtmel::EnterProgrammingMode(){  /* Select Device Type */  TByte set_device[2] = {'T', desired_avrcode};  Send(set_device, 2, 1);  CheckResponse(set_device[0]);  /* Enter Programming Mode */  TByte enter_prg[1] = {'P'};  Send(enter_prg, 1);  CheckResponse(enter_prg[0]);  /* Read Signature Bytes */  TByte sig_bytes[3] = {'s', 0, 0};  Send(sig_bytes, 1, 3);  part_number = sig_bytes[0];  part_family = sig_bytes[1];  vendor_code = sig_bytes[2];}void TAvrAtmel::LeaveProgrammingMode(){  TByte leave_prg [1] = { 'L' };  Send(leave_prg, 1);    }void TAvrAtmel::CheckResponse(TByte x){  if (x!=13){throw Error_Device ("Device is not responding correctly.");}}void TAvrAtmel::EnableAvr(){  bool auto_select = desired_avrcode == AUTO_SELECT;    for (unsigned pidx=0; prg_part[pidx].code != AUTO_SELECT; pidx++){      if (!prg_part[pidx].supported && auto_select){continue;}    if (auto_select){      desired_avrcode = prg_part[pidx].code;      Info(2, "Trying with: %s\n", prg_part[pidx].description);    }        EnterProgrammingMode();    if (!auto_select ||        !(vendor_code==0 && part_family==1 && part_number==2)){      break;    }    LeaveProgrammingMode();      } // OverridePart("atmega163"); // XXXXX local hack for broken signature bytes    Identify();    if (auto_select){    /* If avr was recongnized by the Identify(), try to find better match       in the support list.    */        unsigned better_pidx = 0;    TByte better_avrcode = desired_avrcode;        for (unsigned pidx=0; prg_part[pidx].code != AUTO_SELECT; pidx++){      if (!prg_part[pidx].supported){continue;}            if (strstr(prg_part[pidx].description, GetPartName())){        better_avrcode = prg_part[better_pidx = pidx].code;      }    }    if (better_avrcode != desired_avrcode){      Info(2, "Retrying with better match: %s\n",         prg_part[better_pidx].description);      desired_avrcode = better_avrcode;      LeaveProgrammingMode();      EnterProgrammingMode();      Identify();    }  }}void TAvrAtmel::SetAddress(TAddr addr){  apc_address = addr;  TByte setAddr [3] = { 'A', (addr>>8)&0xff, addr&0xff};  Send(setAddr, 3, 1);  CheckResponse(setAddr [0]);}void TAvrAtmel::WriteProgramMemoryPage(){  SetAddress(page_addr >> 1);  TByte prg_page [1] = { 'm' };  Send(prg_page, 1);    }/* Device Interface Functions*/TByte TAvrAtmel::ReadByte(TAddr addr){  CheckMemoryRange(addr);  if (segment==SEG_FLASH){    TAddr saddr = addr>>1;    TByte rdF [2] = { 'R', 0 };        if (buf_addr==addr && cache_lowbyte==true){return buf_lowbyte;}    if (apc_address!=saddr || apc_autoinc==false) SetAddress(saddr);        apc_address++;    Send(rdF, 1, 2);    /* cache low byte */    cache_lowbyte = true;    buf_addr = (saddr<<1) + 1;    buf_lowbyte = rdF[0];    return rdF [1 - (addr&1)];  }  else if (segment==SEG_EEPROM){        SetAddress(addr);    TByte readEE [1] = { 'd' };        Send(readEE, 1);    return readEE[0];  }  else return 0;}void TAvrAtmel::WriteByte(TAddr addr, TByte byte, bool flush_buffer){  CheckMemoryRange(addr);    /* do not check if byte is already written -- it spoils auto-increment     feature which reduces the speed for 50%!  */       if (segment==SEG_FLASH){      cache_lowbyte = false;		/* clear read cache buffer */      if (!page_size && byte==0xff) return;      /* PAGE MODE PROGRAMMING:       If page mode is enabled cache page address.       When current address is out of the page address       flush page buffer and continue programming.    */      if (page_size){      Info(4, "Loading data to address: %d (page_addr_fetched=%s)\n", 	addr, page_addr_fetched?"Yes":"No");      if (page_addr_fetched && page_addr != (addr & ~(page_size - 1))){	WriteProgramMemoryPage();	page_addr_fetched = false;      }      if (page_addr_fetched==false){	page_addr=addr & ~(page_size - 1);	page_addr_fetched=true;      }      if (flush_buffer){WriteProgramMemoryPage();}    }        TByte wrF [2] = { (addr&1)?'C':'c', byte };        if (apc_address!=(addr>>1) || apc_autoinc==false) SetAddress (addr>>1);    if (wrF[0]=='C') apc_address++;    Send(wrF, 2, 1);    CheckResponse(wrF[0]);  }  else if (segment==SEG_EEPROM){    SetAddress(addr);    TByte writeEE [2] = { 'D', byte };    Send(writeEE, 2, 1);    CheckResponse(writeEE[0]);  }  }void TAvrAtmel::FlushWriteBuffer(){  if (page_addr_fetched){    WriteProgramMemoryPage();    }}void TAvrAtmel::ChipErase(){  TByte eraseTarget [1] = { 'e' };  Send (eraseTarget, 1);  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();}/* 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 (strcmp (desired_partname, prg_part[j].name)==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'};  TByte sup_prg_code[32];  Tx(sup_codes, 1);  TByte buf_code;  timeval timeout = {1, 0};  int i=0;  if (desired_partname==NULL){    Info(1, "  Supported Parts:\n\tNo\tAbbreviation\tDescription\n");  }  do{    Rx(&buf_code, 1, &timeout);    sup_prg_code[i++] = buf_code;    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 + -