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

📄 avr.c

📁 AVR的USB文件
💻 C
📖 第 1 页 / 共 2 页
字号:
/* * avrdude - A Downloader/Uploader for AVR device programmers * Copyright (C) 2000, 2001, 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: avr.c,v 1.52 2003/03/05 04:30:20 bdean Exp $ */#include "ac_cfg.h"#include <stdio.h>#include <stdlib.h>#include <unistd.h>#include <string.h>#include "avr.h"#include "config.h"#include "lists.h"#include "pindefs.h"#include "ppi.h"#define DEBUG 0extern char       * progname;extern char         progbuf[];extern PROGRAMMER * pgm;extern int do_cycles;AVRPART * avr_new_part(void){  AVRPART * p;  p = (AVRPART *)malloc(sizeof(AVRPART));  if (p == NULL) {    fprintf(stderr, "new_part(): out of memory\n");    exit(1);  }  memset(p, 0, sizeof(*p));  p->id[0]   = 0;  p->desc[0] = 0;  p->reset_disposition = RESET_DEDICATED;  p->retry_pulse = PIN_AVR_SCK;  p->flags = AVRPART_SERIALOK | AVRPART_PARALLELOK;  p->config_file[0] = 0;  p->lineno = 0;  p->mem = lcreat(NULL, 0);  return p;}OPCODE * avr_new_opcode(void){  OPCODE * m;  m = (OPCODE *)malloc(sizeof(*m));  if (m == NULL) {    fprintf(stderr, "avr_new_opcode(): out of memory\n");    exit(1);  }  memset(m, 0, sizeof(*m));  return m;}AVRMEM * avr_new_memtype(void){  AVRMEM * m;  m = (AVRMEM *)malloc(sizeof(*m));  if (m == NULL) {    fprintf(stderr, "avr_new_memtype(): out of memory\n");    exit(1);  }  memset(m, 0, sizeof(*m));  return m;}AVRMEM * avr_dup_mem(AVRMEM * m){  AVRMEM * n;  n = avr_new_memtype();  *n = *m;  n->buf = (unsigned char *)malloc(n->size);  if (n->buf == NULL) {    fprintf(stderr,             "avr_dup_mem(): out of memory (memsize=%d)\n",             n->size);    exit(1);  }  memset(n->buf, 0, n->size);  return n;}AVRPART * avr_dup_part(AVRPART * d){  AVRPART * p;  LISTID save;  LNODEID ln;  p = avr_new_part();  save = p->mem;  *p = *d;  p->mem = save;  for (ln=lfirst(d->mem); ln; ln=lnext(ln)) {    ladd(p->mem, avr_dup_mem(ldata(ln)));  }  return p;}AVRMEM * avr_locate_mem(AVRPART * p, char * desc){  AVRMEM * m, * match;  LNODEID ln;  int matches;  int l;  l = strlen(desc);  matches = 0;  match = NULL;  for (ln=lfirst(p->mem); ln; ln=lnext(ln)) {    m = ldata(ln);    if (strncmp(desc, m->desc, l) == 0) {      match = m;      matches++;    }  }  if (matches == 1)    return match;  return NULL;}/* * avr_set_bits() * * Set instruction bits in the specified command based on the opcode.   */int avr_set_bits(OPCODE * op, unsigned char * cmd){  int i, j, bit;  unsigned char mask;  for (i=0; i<32; i++) {    if (op->bit[i].type == AVR_CMDBIT_VALUE) {      j = 3 - i / 8;      bit = i % 8;      mask = 1 << bit;      if (op->bit[i].value)        cmd[j] = cmd[j] | mask;      else        cmd[j] = cmd[j] & ~mask;    }  }  return 0;}/* * avr_set_addr() * * Set address bits in the specified command based on the opcode, and * the address. */int avr_set_addr(OPCODE * op, unsigned char * cmd, unsigned long addr){  int i, j, bit;  unsigned long value;  unsigned char mask;  for (i=0; i<32; i++) {    if (op->bit[i].type == AVR_CMDBIT_ADDRESS) {      j = 3 - i / 8;      bit = i % 8;      mask = 1 << bit;      value = addr >> op->bit[i].bitno & 0x01;      if (value)        cmd[j] = cmd[j] | mask;      else        cmd[j] = cmd[j] & ~mask;    }  }  return 0;}/* * avr_set_input() * * Set input data bits in the specified command based on the opcode, * and the data byte. */int avr_set_input(OPCODE * op, unsigned char * cmd, unsigned char data){  int i, j, bit;  unsigned char value;  unsigned char mask;  for (i=0; i<32; i++) {    if (op->bit[i].type == AVR_CMDBIT_INPUT) {      j = 3 - i / 8;      bit = i % 8;      mask = 1 << bit;      value = data >> op->bit[i].bitno & 0x01;      if (value)        cmd[j] = cmd[j] | mask;      else        cmd[j] = cmd[j] & ~mask;    }  }  return 0;}/* * avr_get_output() * * Retreive output data bits from the command results based on the * opcode data. */int avr_get_output(OPCODE * op, unsigned char * res, unsigned char * data){  int i, j, bit;  unsigned char value;  unsigned char mask;  for (i=0; i<32; i++) {    if (op->bit[i].type == AVR_CMDBIT_OUTPUT) {      j = 3 - i / 8;      bit = i % 8;      mask = 1 << bit;      value = ((res[j] & mask) >> bit) & 0x01;      value = value << op->bit[i].bitno;      if (value)        *data = *data | value;      else        *data = *data & ~value;    }  }  return 0;}/* * read a byte of data from the indicated memory region */int avr_read_byte(PROGRAMMER * pgm, AVRPART * p, AVRMEM * mem,                   unsigned long addr, unsigned char * value){  unsigned char cmd[4];  unsigned char res[4];  unsigned char data;  OPCODE * readop;  pgm->pgm_led(pgm, ON);  pgm->err_led(pgm, OFF);  /*   * figure out what opcode to use   */  if (mem->op[AVR_OP_READ_LO]) {    if (addr & 0x00000001)      readop = mem->op[AVR_OP_READ_HI];    else      readop = mem->op[AVR_OP_READ_LO];    addr = addr / 2;  }  else {    readop = mem->op[AVR_OP_READ];  }  if (readop == NULL) {#if DEBUG    fprintf(stderr,             "avr_read_byte(): operation not supported on memory type \"%s\"\n",            p->desc);#endif    return -1;  }  memset(cmd, 0, sizeof(cmd));  avr_set_bits(readop, cmd);  avr_set_addr(readop, cmd, addr);  pgm->cmd(pgm, cmd, res);  data = 0;  avr_get_output(readop, res, &data);  pgm->pgm_led(pgm, OFF);  *value = data;  return 0;}/* * Read the entirety of the specified memory type into the * corresponding buffer of the avrpart pointed to by 'p'.  If size = * 0, read the entire contents, otherwise, read 'size' bytes. * * Return the number of bytes read, or < 0 if an error occurs.   */int avr_read(PROGRAMMER * pgm, AVRPART * p, char * memtype, int size,              int verbose){  unsigned char    rbyte;  unsigned long    i;  unsigned char  * buf;  AVRMEM * mem;  int rc;  int printed;  mem = avr_locate_mem(p, memtype);  if (mem == NULL) {    fprintf(stderr, "No \"%s\" memory for part %s\n",            memtype, p->desc);    return -1;  }  buf  = mem->buf;  if (size == 0) {    size = mem->size;  }  if ((strcmp(mem->desc, "flash")==0) || (strcmp(mem->desc, "eeprom")==0)) {    if (pgm->paged_load != NULL) {      /*       * the programmer supports a paged mode read, perhaps more       * efficiently than we can read it directly, so use its routine       * instead       */      if (mem->paged) {        return pgm->paged_load(pgm, p, mem, mem->page_size, size);      }      else {        return pgm->paged_load(pgm, p, mem, pgm->page_size, size);      }    }  }  printed = 0;  for (i=0; i<size; i++) {    rc = avr_read_byte(pgm, p, mem, i, &rbyte);    if (rc != 0) {      fprintf(stderr, "avr_read(): error reading address 0x%04lx\n", i);      if (rc == -1)         fprintf(stderr,                 "    read operation not supported for memory \"%s\"\n",                memtype);      return -2;    }    buf[i] = rbyte;    if (verbose) {      if ((i % 16 == 0)||(i == (size-1))) {        printed = 1;        fprintf(stderr, "\r        \r%6lu", i);      }    }  }  if (printed) {    fprintf(stderr, "\n");  }  return i;}/* * write a page data at the specified address */int avr_write_page(PROGRAMMER * pgm, AVRPART * p, AVRMEM * mem,                    unsigned long addr){  unsigned char cmd[4];  unsigned char res[4];  OPCODE * wp;  wp = mem->op[AVR_OP_WRITEPAGE];  if (wp == NULL) {    fprintf(stderr,             "avr_write_page(): memory \"%s\" not configured for page writes\n",            mem->desc);    return -1;  }  /*   * if this memory is word-addressable, adjust the address   * accordingly   */  if ((mem->op[AVR_OP_LOADPAGE_LO]) || (mem->op[AVR_OP_READ_LO]))    addr = addr / 2;  pgm->pgm_led(pgm, ON);  pgm->err_led(pgm, OFF);  memset(cmd, 0, sizeof(cmd));  avr_set_bits(wp, cmd);  avr_set_addr(wp, cmd, addr);  pgm->cmd(pgm, cmd, res);  /*   * since we don't know what voltage the target AVR is powered by, be   * conservative and delay the max amount the spec says to wait    */  usleep(mem->max_write_delay);  pgm->pgm_led(pgm, OFF);  return 0;}/* * write a byte of data at the specified address */int avr_write_byte(PROGRAMMER * pgm, AVRPART * p, AVRMEM * mem,                   unsigned long addr, unsigned char data){  unsigned char cmd[4];  unsigned char res[4];  unsigned char r;  int ready;  int tries;  unsigned char b;  unsigned short caddr;  OPCODE * writeop;  int rc;  int readok=0;  if (!mem->paged) {    /*      * check to see if the write is necessary by reading the existing     * value and only write if we are changing the value; we can't     * use this optimization for paged addressing.     */    rc = avr_read_byte(pgm, p, mem, addr, &b);    if (rc != 0) {      if (rc != -1) {        return -2;      }      /*       * the read operation is not support on this memory type       */    }    else {      readok = 1;      if (b == data) {        return 0;      }    }  }  /*   * determine which memory opcode to use   */  if (mem->op[AVR_OP_WRITE_LO]) {    if (addr & 0x01)      writeop = mem->op[AVR_OP_WRITE_HI];    else      writeop = mem->op[AVR_OP_WRITE_LO];    caddr = addr / 2;  }  else if (mem->op[AVR_OP_LOADPAGE_LO]) {    if (addr & 0x01)      writeop = mem->op[AVR_OP_LOADPAGE_HI];    else      writeop = mem->op[AVR_OP_LOADPAGE_LO];    caddr = addr / 2;  }  else {    writeop = mem->op[AVR_OP_WRITE];    caddr = addr;  }  if (writeop == NULL) {#if DEBUG    fprintf(stderr,             "avr_write_byte(): write not supported for memory type \"%s\"\n",            mem->desc);#endif    return -1;  }  pgm->pgm_led(pgm, ON);  pgm->err_led(pgm, OFF);  memset(cmd, 0, sizeof(cmd));  avr_set_bits(writeop, cmd);  avr_set_addr(writeop, cmd, caddr);  avr_set_input(writeop, cmd, data);  pgm->cmd(pgm, cmd, res);  if (mem->paged) {    /*     * in paged addressing, single bytes to be written to the memory     * page complete immediately, we only need to delay when we commit     * the whole page via the avr_write_page() routine.     */    pgm->pgm_led(pgm, OFF);    return 0;  }  if (readok == 0) {    /*     * read operation not supported for this memory type, just wait     * the max programming time and then return      */    usleep(mem->max_write_delay); /* maximum write delay */    pgm->pgm_led(pgm, OFF);    return 0;  }  tries = 0;  ready = 0;  while (!ready) {

⌨️ 快捷键说明

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