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

📄 stk500.c

📁 AVR的USB文件
💻 C
📖 第 1 页 / 共 2 页
字号:
/* * avrdude - A Downloader/Uploader for AVR device programmers * Copyright (C) 2002, 2003  Brian S. Dean <bsd@bsdhome.com> * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA *//* $Id: stk500.c,v 1.29 2003/03/10 22:58:21 bdean Exp $ *//* * avrdude interface for Atmel STK500 programmer * * Note: most commands use the "universal command" feature of the * programmer in a "pass through" mode, exceptions are "program * enable", "paged read", and "paged write". * */#include "ac_cfg.h"#include <stdio.h>#include <stdlib.h>#include <string.h>#include <fcntl.h>#include <unistd.h>#include <errno.h>#include <termios.h>#include <sys/time.h>#include "avr.h"#include "pgm.h"#include "stk500_private.h"extern char * progname;extern int do_cycles;static int stk500_getparm(PROGRAMMER * pgm, unsigned parm, unsigned * value);static int stk500_send(PROGRAMMER * pgm, char * buf, int buflen){  struct timeval timeout;  fd_set wfds;  int nfds;  int rc;  if (!buflen)    return 0;  timeout.tv_sec = 0;  timeout.tv_usec = 500000;  while (buflen) {    FD_ZERO(&wfds);    FD_SET(pgm->fd, &wfds);  reselect:    nfds = select(pgm->fd+1, NULL, &wfds, NULL, &timeout);    if (nfds == 0) {      fprintf(stderr,               "%s: stk500_send(): programmer is not responding on %s\n",              progname, pgm->port);      exit(1);    }    else if (nfds == -1) {      if (errno == EINTR) {        goto reselect;      }      else {        fprintf(stderr, "%s: stk500_send(): select(): %s\n",                progname, strerror(errno));        exit(1);      }    }    rc = write(pgm->fd, buf, 1);    if (rc < 0) {      fprintf(stderr, "%s: stk500_send(): write error: %s\n",              progname, strerror(errno));      exit(1);    }    buf++;    buflen--;  }  return 0;}        static int stk500_recv(PROGRAMMER * pgm, char * buf, int n){  struct timeval timeout;  fd_set rfds;  int nfds;  int rc;  timeout.tv_sec  = 5;  timeout.tv_usec = 0;  while (n) {    FD_ZERO(&rfds);    FD_SET(pgm->fd, &rfds);  reselect:    nfds = select(pgm->fd+1, &rfds, NULL, NULL, &timeout);    if (nfds == 0) {      fprintf(stderr,               "%s: stk500_recv(): programmer is not responding on %s\n",              progname, pgm->port);      exit(1);    }    else if (nfds == -1) {      if (errno == EINTR) {        goto reselect;      }      else {        fprintf(stderr, "%s: stk500_recv(): select(): %s\n",                progname, strerror(errno));        exit(1);      }    }    rc = read(pgm->fd, buf, 1);    if (rc < 0) {      fprintf(stderr, "%s: stk500_recv(): read error: %s\n",              progname, strerror(errno));      exit(1);    }    buf++;    n--;  }  return 0;}      static int stk500_drain(PROGRAMMER * pgm, int display){  struct timeval timeout;  fd_set rfds;  int nfds;  int rc;  unsigned char buf;  timeout.tv_sec = 0;  timeout.tv_usec = 250000;  if (display) {    fprintf(stderr, "drain>");  }  while (1) {    FD_ZERO(&rfds);    FD_SET(pgm->fd, &rfds);  reselect:    nfds = select(pgm->fd+1, &rfds, NULL, NULL, &timeout);    if (nfds == 0) {      if (display) {        fprintf(stderr, "<drain\n");      }            return 0;    }    else if (nfds == -1) {      if (errno == EINTR) {        goto reselect;      }      else {        fprintf(stderr, "%s: stk500_drain(): select(): %s\n",                progname, strerror(errno));        exit(1);      }    }    rc = read(pgm->fd, &buf, 1);    if (rc < 0) {      fprintf(stderr, "%s: stk500_drain(): read error: %s\n",              progname, strerror(errno));      exit(1);    }    if (display) {      fprintf(stderr, "%02x ", buf);    }  }}static int stk500_getsync(PROGRAMMER * pgm){  unsigned char buf[32], resp[32];  /*   * get in sync */  buf[0] = Cmnd_STK_GET_SYNC;  buf[1] = Sync_CRC_EOP;  stk500_send(pgm, buf, 2);  stk500_recv(pgm, resp, 1);  if (resp[0] != Resp_STK_INSYNC) {    fprintf(stderr,             "%s: stk500_getsync(): not in sync: resp=0x%02x\n",            progname, resp[0]);    stk500_drain(pgm, 0);    exit(1);  }  stk500_recv(pgm, resp, 1);  if (resp[0] != Resp_STK_OK) {    fprintf(stderr,             "%s: stk500_getsync(): can't communicate with device: "            "resp=0x%02x\n",            progname, resp[0]);    exit(1);  }  return 0;}static int stk500_rdy_led(PROGRAMMER * pgm, int value){  return 0;}static int stk500_err_led(PROGRAMMER * pgm, int value){  return 0;}static int stk500_pgm_led(PROGRAMMER * pgm, int value){  return 0;}static int stk500_vfy_led(PROGRAMMER * pgm, int value){  return 0;}/* * transmit an AVR device command and return the results; 'cmd' and * 'res' must point to at least a 4 byte data buffer */static int stk500_cmd(PROGRAMMER * pgm, unsigned char cmd[4],                       unsigned char res[4]){  unsigned char buf[32];  buf[0] = Cmnd_STK_UNIVERSAL;  buf[1] = cmd[0];  buf[2] = cmd[1];  buf[3] = cmd[2];  buf[4] = cmd[3];  buf[5] = Sync_CRC_EOP;  stk500_send(pgm, buf, 6);  stk500_recv(pgm, buf, 1);  if (buf[0] != Resp_STK_INSYNC) {    fprintf(stderr, "%s: stk500_cmd(): programmer is out of sync\n", progname);    exit(1);  }  res[0] = cmd[1];  res[1] = cmd[2];  res[2] = cmd[3];  stk500_recv(pgm, &res[3], 1);  stk500_recv(pgm, buf, 1);  if (buf[0] != Resp_STK_OK) {    fprintf(stderr, "%s: stk500_cmd(): protocol error\n", progname);    exit(1);  }  return 0;}/* * issue the 'chip erase' command to the AVR device */static int stk500_chip_erase(PROGRAMMER * pgm, AVRPART * p){  unsigned char cmd[4];  unsigned char res[4];  int cycles;  int rc;  if (p->op[AVR_OP_CHIP_ERASE] == NULL) {    fprintf(stderr, "chip erase instruction not defined for part \"%s\"\n",            p->desc);    return -1;  }  rc = avr_get_cycle_count(pgm, p, &cycles);  /*   * only print out the current cycle count if we aren't going to   * display it below    */  if (!do_cycles && ((rc >= 0) && (cycles != 0xffffffff))) {    fprintf(stderr,            "%s: current erase-rewrite cycle count is %d%s\n",            progname, cycles,             do_cycles ? "" : " (if being tracked)");  }  pgm->pgm_led(pgm, ON);  memset(cmd, 0, sizeof(cmd));  avr_set_bits(p->op[AVR_OP_CHIP_ERASE], cmd);  pgm->cmd(pgm, cmd, res);  usleep(p->chip_erase_delay);  pgm->initialize(pgm, p);  pgm->pgm_led(pgm, OFF);  if (do_cycles && (cycles != -1)) {    if (cycles == 0x00ffff) {      cycles = 0;    }    cycles++;    fprintf(stderr, "%s: erase-rewrite cycle count is now %d\n",             progname, cycles);    avr_put_cycle_count(pgm, p, cycles);  }  return 0;}/* * issue the 'program enable' command to the AVR device */static int stk500_program_enable(PROGRAMMER * pgm, AVRPART * p){  unsigned char buf[16];  int tries=0; retry:    tries++;  buf[0] = Cmnd_STK_ENTER_PROGMODE;  buf[1] = Sync_CRC_EOP;  stk500_send(pgm, buf, 2);  stk500_recv(pgm, buf, 1);  if (buf[0] == Resp_STK_NOSYNC) {    if (tries > 33) {      fprintf(stderr, "%s: stk500_program_enable(): can't get into sync\n",              progname);      return -1;    }    stk500_getsync(pgm);    goto retry;  }  else if (buf[0] != Resp_STK_INSYNC) {    fprintf(stderr,            "%s: stk500_program_enable(): protocol error, "            "expect=0x%02x, resp=0x%02x\n",             progname, Resp_STK_INSYNC, buf[0]);    return -1;  }  stk500_recv(pgm, buf, 1);  if (buf[0] == Resp_STK_OK) {    return 0;  }  else if (buf[0] == Resp_STK_NODEVICE) {    fprintf(stderr, "%s: stk500_program_enable(): no device\n",            progname);    return -1;  }  if(buf[0] == Resp_STK_FAILED)  {      fprintf(stderr, 	      "%s: stk500_program_enable(): failed to enter programming mode\n", 		  progname);	  return -1;  }  fprintf(stderr, "%s: stk500_program_enable(): unknown response=0x%02x\n",          progname, buf[0]);  return -1;}/* * apply power to the AVR processor */static void stk500_powerup(PROGRAMMER * pgm){  return;}/* * remove power from the AVR processor */static void stk500_powerdown(PROGRAMMER * pgm){  return;}static int stk500_set_extended_parms(PROGRAMMER * pgm, int n,                                      unsigned char * cmd){  unsigned char buf[16];  int tries=0;  int i; retry:    tries++;  buf[0] = Cmnd_STK_SET_DEVICE_EXT;  for (i=0; i<n; i++) {    buf[1+i] = cmd[i];  }  i++;  buf[i] = Sync_CRC_EOP;  stk500_send(pgm, buf, i+1);  stk500_recv(pgm, buf, 1);  if (buf[0] == Resp_STK_NOSYNC) {    if (tries > 33) {      fprintf(stderr, "%s: stk500_set_extended_parms(): can't get into sync\n",              progname);      return -1;    }    stk500_getsync(pgm);    goto retry;  }  else if (buf[0] != Resp_STK_INSYNC) {    fprintf(stderr,            "%s: stk500_set_extended_parms(): protocol error, "            "expect=0x%02x, resp=0x%02x\n",             progname, Resp_STK_INSYNC, buf[0]);    return -1;  }  stk500_recv(pgm, buf, 1);  if (buf[0] == Resp_STK_OK) {    return 0;  }  else if (buf[0] == Resp_STK_NODEVICE) {    fprintf(stderr, "%s: stk500_set_extended_parms(): no device\n",            progname);    return -1;  }  if(buf[0] == Resp_STK_FAILED)  {      fprintf(stderr, 	      "%s: stk500_set_extended_parms(): failed to set extended "              "device programming parameters\n",               progname);	  return -1;  }  fprintf(stderr, "%s: stk500_set_extended_parms(): unknown response=0x%02x\n",          progname, buf[0]);  return -1;}/* * initialize the AVR device and prepare it to accept commands */static int stk500_initialize(PROGRAMMER * pgm, AVRPART * p){  unsigned char buf[32];  AVRMEM * m;  int tries;  unsigned maj, min;  int rc;  int n_extparms = 3;  stk500_getparm(pgm, Parm_STK_SW_MAJOR, &maj);  stk500_getparm(pgm, Parm_STK_SW_MINOR, &min);  if ((maj > 1) || ((maj == 1) && (min > 10)))    n_extparms = 4;  tries = 0; retry:  tries++;  memset(buf, 0, sizeof(buf));  /*   * set device programming parameters   */  buf[0] = Cmnd_STK_SET_DEVICE;  buf[1] = p->devicecode;  buf[2] = 0; /* device revision */  if ((p->flags & AVRPART_SERIALOK) && (p->flags & AVRPART_PARALLELOK))    buf[3] = 0; /* device supports parallel and serial programming */  else    buf[3] = 1; /* device supports parallel only */  if (p->flags & AVRPART_PARALLELOK) {    if (p->flags & AVRPART_PSEUDOPARALLEL) {      buf[4] = 0; /* pseudo parallel interface */      n_extparms = 0;    }    else {      buf[4] = 1; /* full parallel interface */    }  }#if 0  fprintf(stderr, "%s: stk500_initialize(): n_extparms = %d\n",           progname, n_extparms);#endif      buf[5] = 1; /* polling supported - XXX need this in config file */  buf[6] = 1; /* programming is self-timed - XXX need in config file */  m = avr_locate_mem(p, "lock");  if (m)    buf[7] = m->size;  else    buf[7] = 0;  /*   * number of fuse bytes   */  buf[8] = 0;  m = avr_locate_mem(p, "fuse");  if (m)    buf[8] += m->size;  m = avr_locate_mem(p, "lfuse");  if (m)    buf[8] += m->size;  m = avr_locate_mem(p, "hfuse");  if (m)    buf[8] += m->size;  m = avr_locate_mem(p, "efuse");  if (m)    buf[8] += m->size;  m = avr_locate_mem(p, "flash");  if (m) {    buf[9] = m->readback[0];    buf[10] = m->readback[1];    if (m->paged) {      buf[13] = (m->page_size >> 8) & 0x00ff;      buf[14] = m->page_size & 0x00ff;    }    buf[17] = (m->size >> 24) & 0xff;    buf[18] = (m->size >> 16) & 0xff;    buf[19] = (m->size >> 8) & 0xff;    buf[20] = m->size & 0xff;  }  else {    buf[9]  = 0xff;    buf[10]  = 0xff;

⌨️ 快捷键说明

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