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 + -
显示快捷键?