butterfly.c

来自「这是一个非常有价值的参考代码」· C语言 代码 · 共 694 行 · 第 1/2 页

C
694
字号
/* * avrdude - A Downloader/Uploader for AVR device programmers * Copyright (C) 2003-2004  Theodore A. Roth  <troth@openavr.org> * Copyright (C) 2005 Joerg Wunsch <j@uriah.heep.sax.de> * * 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: butterfly.c,v 1.11 2005/09/20 04:53:09 joerg_wunsch Exp $ *//* * avrdude interface for the serial programming mode of the Atmel butterfly * evaluation board. This board features a bootloader which uses a protocol * very similar, but not identical, to the one described in application note * avr910. * * Actually, the butterfly uses a predecessor of the avr910 protocol * which is described in application notes avr109 (generic AVR * bootloader) and avr911 (opensource programmer).  This file now * fully handles the features present in avr109.  It should probably * be renamed to avr109, but we rather stick with the old name inside * the file.  We'll provide aliases for "avr109" and "avr911" in * avrdude.conf so users could call it by these name as well. */#include "ac_cfg.h"#include <stdio.h>#include <stdlib.h>#include <string.h>#include <errno.h>#include <ctype.h>#include "avr.h"#include "pgm.h"#include "butterfly.h"#include "serial.h"extern char * progname;extern int do_cycles;static char has_auto_incr_addr;static unsigned buffersize = 0;/* These two defines are only for debugging. Will remove them once it starts   working. */#define show_func_info() \  fprintf(stderr, "%s: line %d: called %s()\n", \          __FILE__, __LINE__, __FUNCTION__)#define no_show_func_info()static int butterfly_send(PROGRAMMER * pgm, char * buf, size_t len){  no_show_func_info();  return serial_send(pgm->fd, (unsigned char *)buf, len);}static int butterfly_recv(PROGRAMMER * pgm, char * buf, size_t len){  int rv;  no_show_func_info();  rv = serial_recv(pgm->fd, (unsigned char *)buf, len);  if (rv < 0) {    fprintf(stderr,	    "%s: butterfly_recv(): programmer is not responding\n",	    progname);    exit(1);  }  return 0;}static int butterfly_drain(PROGRAMMER * pgm, int display){  no_show_func_info();  return serial_drain(pgm->fd, display);}static void butterfly_vfy_cmd_sent(PROGRAMMER * pgm, char * errmsg){  char c;  butterfly_recv(pgm, &c, 1);  if (c != '\r') {    fprintf(stderr, "%s: error: programmer did not respond to command: %s\n",            progname, errmsg);    exit(1);  }}static int butterfly_rdy_led(PROGRAMMER * pgm, int value){  no_show_func_info();  /* Do nothing. */  return 0;}static int butterfly_err_led(PROGRAMMER * pgm, int value){  no_show_func_info();  /* Do nothing. */  return 0;}static int butterfly_pgm_led(PROGRAMMER * pgm, int value){  no_show_func_info();  /* Do nothing. */  return 0;}static int butterfly_vfy_led(PROGRAMMER * pgm, int value){  no_show_func_info();  /* Do nothing. */  return 0;}/* * issue the 'chip erase' command to the butterfly board */static int butterfly_chip_erase(PROGRAMMER * pgm, AVRPART * p){  no_show_func_info();  butterfly_send(pgm, "e", 1);  butterfly_vfy_cmd_sent(pgm, "chip erase");  return 0;}static void butterfly_enter_prog_mode(PROGRAMMER * pgm){  butterfly_send(pgm, "P", 1);  butterfly_vfy_cmd_sent(pgm, "enter prog mode");}static void butterfly_leave_prog_mode(PROGRAMMER * pgm){  butterfly_send(pgm, "L", 1);  butterfly_vfy_cmd_sent(pgm, "leave prog mode");}/* * issue the 'program enable' command to the AVR device */static int butterfly_program_enable(PROGRAMMER * pgm, AVRPART * p){  no_show_func_info();  return -1;}/* * apply power to the AVR processor */static void butterfly_powerup(PROGRAMMER * pgm){  no_show_func_info();  /* Do nothing. */  return;}/* * remove power from the AVR processor */static void butterfly_powerdown(PROGRAMMER * pgm){  no_show_func_info();  /* Do nothing. */  return;}/* * initialize the AVR device and prepare it to accept commands */static int butterfly_initialize(PROGRAMMER * pgm, AVRPART * p){  char id[8];  char sw[2];  char hw[2];  char buf[10];  char type;  char c;  int dev_supported = 0;  no_show_func_info();  /*   * Send some ESC to activate butterfly bootloader.  This is not needed   * for plain avr109 bootloaders but does not harm there either.   */  fprintf(stderr, "Connecting to programmer: ");  do {    putc('.', stderr);    butterfly_send(pgm, "\033", 1);    butterfly_drain(pgm, 0);    butterfly_send(pgm, "S", 1);    butterfly_recv(pgm, &c, 1);    if (c != '?') {        putc('\n', stderr);        /*         * Got a useful response, continue getting the programmer         * identifier. Programmer returns exactly 7 chars _without_         * the null.         */      id[0] = c;      butterfly_recv(pgm, &id[1], sizeof(id)-2);      id[sizeof(id)-1] = '\0';    }  } while (c == '?');  /* Get the HW and SW versions to see if the programmer is present. */  butterfly_send(pgm, "V", 1);  butterfly_recv(pgm, sw, sizeof(sw));  butterfly_send(pgm, "v", 1);  butterfly_recv(pgm, hw, 1);	/* first, read only _one_ byte */  if (hw[0]!='?') {    butterfly_recv(pgm, &hw[1], 1);/* now, read second byte */  };  /* Get the programmer type (serial or parallel). Expect serial. */  butterfly_send(pgm, "p", 1);  butterfly_recv(pgm, &type, 1);  fprintf(stderr, "Found programmer: Id = \"%s\"; type = %c\n", id, type);  fprintf(stderr, "    Software Version = %c.%c; ", sw[0], sw[1]);  if (hw[0]=='?') {    fprintf(stderr, "No Hardware Version given.\n");  } else {    fprintf(stderr, "Hardware Version = %c.%c\n", hw[0], hw[1]);  };  /* See if programmer supports autoincrement of address. */  butterfly_send(pgm, "a", 1);  butterfly_recv(pgm, &has_auto_incr_addr, 1);  if (has_auto_incr_addr == 'Y')      fprintf(stderr, "Programmer supports auto addr increment.\n");  /* Check support for buffered memory access, abort if not available */  butterfly_send(pgm, "b", 1);  butterfly_recv(pgm, &c, 1);  if (c != 'Y') {    fprintf(stderr,            "%s: error: buffered memory access not supported. Maybe it isn't\n"\            "a butterfly/AVR109 but a AVR910 device?\n", progname);    exit(1);  };  butterfly_recv(pgm, &c, 1);  buffersize = c<<8;  butterfly_recv(pgm, &c, 1);  buffersize += c;  fprintf(stderr,    "Programmer supports buffered memory access with buffersize=%i bytes.\n",     buffersize);  /* Get list of devices that the programmer supports. */  butterfly_send(pgm, "t", 1);  fprintf(stderr, "\nProgrammer supports the following devices:\n");  while (1) {    butterfly_recv(pgm, &c, 1);    if (c == 0)      break;    fprintf(stderr, "    Device code: 0x%02x\n", (unsigned int)(unsigned char)c);    /* FIXME: Need to lookup devcode and report the device. */    if (p->avr910_devcode == (int)(unsigned char)c)      dev_supported = 1;  };  fprintf(stderr,"\n");  if (!dev_supported) {    /* FIXME: if nothing matched, we should rather compare the device       signatures. */    fprintf(stderr,            "%s: error: selected device is not supported by programmer: %s\n",            progname, p->id);  }  /* Tell the programmer which part we selected. */  buf[0] = 'T';  buf[1] = p->avr910_devcode;  butterfly_send(pgm, buf, 2);  butterfly_vfy_cmd_sent(pgm, "select device");  if (dev_supported)      butterfly_enter_prog_mode(pgm);  return dev_supported? 0: -1;}

⌨️ 快捷键说明

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