bug #30559 Ft232 bit-bang support
* ft245r.[ch]: new programmer type implementation * configure.ac: add pthread as link library * avrdude.conf.in: added some new programmers * Makefile.am: added new source files to compile * pindefs.h: change PIN_MASK, PIN_INVERSE to highest bit of unsigned int * pgm.[ch]: added generic function to print pin assignments (taken from par.c) * par.c: moved pin assigment print function to pgm.c git-svn-id: svn://svn.savannah.nongnu.org/avrdude/trunk/avrdude@1055 81a1dc3b-b13d-400b-aceb-764788c761c2
This commit is contained in:
parent
c05b7bb0ab
commit
7240bbec2f
11
ChangeLog
11
ChangeLog
|
@ -1,3 +1,14 @@
|
|||
2012-02-01 Rene Liebscher <R.Liebscher@gmx.de>
|
||||
|
||||
bug #30559 Ft232 bit-bang support
|
||||
* ft245r.[ch]: new programmer type implementation
|
||||
* configure.ac: add pthread as link library
|
||||
* avrdude.conf.in: added some new programmers
|
||||
* Makefile.am: added new source files to compile
|
||||
* pindefs.h: change PIN_MASK, PIN_INVERSE to highest bit of unsigned int
|
||||
* pgm.[ch]: added generic function to print pin assignments (taken from par.c)
|
||||
* par.c: moved pin assigment print function to pgm.c
|
||||
|
||||
2012-02-01 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
|
||||
|
||||
* lexer.l: Sort keyword tokens into alphabetic order.
|
||||
|
|
|
@ -91,6 +91,8 @@ libavrdude_a_SOURCES = \
|
|||
avr.h \
|
||||
avr910.c \
|
||||
avr910.h \
|
||||
ft245r.c \
|
||||
ft245r.h \
|
||||
avrdude.h \
|
||||
avrftdi.c \
|
||||
avrftdi.h \
|
||||
|
|
|
@ -16,13 +16,8 @@
|
|||
# parent <id> # optional parent
|
||||
# id = <id1> [, <id2> [, <id3>] ...] ; # <idN> are quoted strings
|
||||
# desc = <description> ; # quoted string
|
||||
# type = par | stk500 | stk500v2 | stk500pp | stk500hvsp | stk500generic |
|
||||
# stk600 | stk600pp | stk600hvsp |
|
||||
# avr910 | butterfly | usbasp |
|
||||
# jtagmki | jtagmkii | jtagmkii_isp | jtagmkii_dw |
|
||||
# jtagmkII_avr32 | jtagmkii_pdi |
|
||||
# dragon_dw | dragon_jtag | dragon_isp | dragon_pp |
|
||||
# dragon_hvsp | dragon_pdi | arduino | wiring; # programmer type
|
||||
# type = <type>; # programmer type, quoted string
|
||||
# # supported programmer types can be listed by "-c ?type"
|
||||
# connection_type = parallel | serial | usb
|
||||
# baudrate = <num> ; # baudrate for avr910-programmer
|
||||
# vcc = <num1> [, <num2> ... ] ; # pin number(s)
|
||||
|
@ -576,6 +571,59 @@ programmer
|
|||
connection_type = serial;
|
||||
;
|
||||
|
||||
programmer
|
||||
id = "ft245r";
|
||||
desc = "FT245R Synchronous BitBang";
|
||||
type = "ftdi_syncbb";
|
||||
connection_type = usb;
|
||||
miso = 2; # D1
|
||||
sck = 1; # D0
|
||||
mosi = 3; # D2
|
||||
reset = 5; # D4
|
||||
;
|
||||
|
||||
programmer
|
||||
id = "ft232r";
|
||||
desc = "FT232R Synchronous BitBang";
|
||||
type = "ftdi_syncbb";
|
||||
connection_type = usb;
|
||||
miso = 2; # RxD
|
||||
sck = 1; # RTS
|
||||
mosi = 3; # TxD
|
||||
reset = 5; # DTR
|
||||
;
|
||||
|
||||
# see http://www.bitwizard.nl/wiki/index.php/FTDI_ATmega
|
||||
programmer
|
||||
id = "bwmega";
|
||||
desc = "BitWizard ftdi_atmega builtin programmer";
|
||||
type = "ftdi_syncbb";
|
||||
connection_type = usb;
|
||||
miso = 6; # DSR
|
||||
sck = 7; # DCD
|
||||
mosi = 4; # CTS
|
||||
reset = 8; # RI
|
||||
;
|
||||
|
||||
# see http://www.geocities.jp/arduino_diecimila/bootloader/index_en.html
|
||||
# Note: pins are numbered from 1!
|
||||
programmer
|
||||
id = "arduino-ft232r";
|
||||
desc = "Arduino: FT232R connected to ISP";
|
||||
type = "ftdi_syncbb";
|
||||
connection_type = usb;
|
||||
miso = 4; # CTS X3(1)
|
||||
sck = 6; # DSR X3(2)
|
||||
mosi = 7; # DCD X3(3)
|
||||
reset = 8; # RI X3(4)
|
||||
;
|
||||
|
||||
# website mentioned above uses this id
|
||||
programmer parent "arduino-ft232r"
|
||||
id = "diecimila";
|
||||
desc = "alias for arduino-ft232r";
|
||||
;
|
||||
|
||||
programmer
|
||||
id = "usbasp";
|
||||
desc = "USBasp, http://www.fischl.de/usbasp/";
|
||||
|
|
|
@ -135,7 +135,7 @@ AH_TEMPLATE([HAVE_LIBFTDI],
|
|||
[Define if FTDI support is enabled via libftdi])
|
||||
AC_CHECK_LIB([ftdi], [ftdi_usb_get_strings], [have_libftdi=yes], [], [-lusb])
|
||||
if test x$have_libftdi = xyes; then
|
||||
LIBFTDI="-lftdi -lusb"
|
||||
LIBFTDI="-lftdi -lusb -lpthread"
|
||||
AC_DEFINE([HAVE_LIBFTDI])
|
||||
fi
|
||||
AC_SUBST(LIBFTDI, $LIBFTDI)
|
||||
|
|
|
@ -0,0 +1,831 @@
|
|||
|
||||
/*
|
||||
* avrdude - A Downloader/Uploader for AVR device programmers
|
||||
* Copyright (C) 2003-2004 Theodore A. Roth <troth@openavr.org>
|
||||
* some code:
|
||||
* Copyright (C) 2011-2012 Roger E. Wolff <R.E.Wolff@BitWizard.nl>
|
||||
*
|
||||
* 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$ */
|
||||
|
||||
/* ft245r -- FT245R/FT232R Synchronous BitBangMode Programmer
|
||||
default pin assign
|
||||
FT232R / FT245R
|
||||
miso = 2; # RxD / D1
|
||||
sck = 1; # RTS / D0
|
||||
mosi = 3; # TxD / D2
|
||||
reset = 5; # DTR / D4
|
||||
*/
|
||||
|
||||
/*
|
||||
The ft232r is very similar, or even "identical" in the synchronous
|
||||
bitbang mode that we use here.
|
||||
|
||||
This allows boards that have an ft232r for communication and an avr
|
||||
as the processor to function as their own "ICSP". Boards that fit
|
||||
this description include the Arduino Duemilanove, Arduino Diecimila,
|
||||
Arduino NG (http://arduino.cc/it/main/boards) and the BitWizard
|
||||
ftdi_atmega board (http://www.bitwizard.nl/wiki/index.php/FTDI_ATmega)
|
||||
|
||||
The Arduinos have to be patched to bring some of the control lines
|
||||
to the ICSP header. The BitWizard board already has the neccessary
|
||||
wiring on the PCB.
|
||||
|
||||
How to add the wires to an arduino is documented here:
|
||||
http://www.geocities.jp/arduino_diecimila/bootloader/index_en.html
|
||||
*/
|
||||
|
||||
|
||||
#include "ac_cfg.h"
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <errno.h>
|
||||
#include <sys/time.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include "avrdude.h"
|
||||
#include "avr.h"
|
||||
#include "avrpart.h"
|
||||
#include "pindefs.h"
|
||||
#include "pgm.h"
|
||||
#include "config.h"
|
||||
#include "bitbang.h"
|
||||
#include "ft245r.h"
|
||||
|
||||
#include <pthread.h>
|
||||
#include <semaphore.h>
|
||||
|
||||
#ifdef HAVE_LIBFTDI
|
||||
|
||||
#if defined(_WIN32)
|
||||
#include <windows.h>
|
||||
#endif
|
||||
|
||||
#include <ftdi.h>
|
||||
|
||||
|
||||
#define FT245R_CYCLES 2
|
||||
#define FT245R_FRAGMENT_SIZE 512
|
||||
#define REQ_OUTSTANDINGS 10
|
||||
//#define USE_INLINE_WRITE_PAGE
|
||||
|
||||
#define FT245R_DEBUG 1
|
||||
|
||||
static struct ftdi_context *handle;
|
||||
|
||||
static unsigned char ft245r_ddr;
|
||||
static unsigned char ft245r_sck;
|
||||
static unsigned char ft245r_mosi;
|
||||
static unsigned char ft245r_reset;
|
||||
static unsigned char ft245r_miso;
|
||||
|
||||
#define BUFSIZE 0x2000
|
||||
|
||||
// libftdi / libftd2xx compatibility functions.
|
||||
|
||||
static pthread_t readerthread;
|
||||
static sem_t buf_data, buf_space;
|
||||
static unsigned char buffer[BUFSIZE];
|
||||
static int head, tail;
|
||||
|
||||
static void add_to_buf (unsigned char c) {
|
||||
int nh;
|
||||
|
||||
sem_wait (&buf_space);
|
||||
if (head == (BUFSIZE -1)) nh = 0;
|
||||
else nh = head + 1;
|
||||
|
||||
if (nh == tail) {
|
||||
fprintf (stderr, "buffer overflow. Cannot happen!\n");
|
||||
//exit (1);
|
||||
}
|
||||
buffer[head] = c;
|
||||
head = nh;
|
||||
sem_post (&buf_data);
|
||||
}
|
||||
|
||||
static void *reader (void *arg) {
|
||||
struct ftdi_context *handle = (struct ftdi_context *)(arg);
|
||||
unsigned char buf[0x1000];
|
||||
int br, i;
|
||||
|
||||
while (1) {
|
||||
br = ftdi_read_data (handle, buf, sizeof(buf));
|
||||
for (i=0; i<br; i++)
|
||||
add_to_buf (buf[i]);
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static inline void setmybits(unsigned char *data, int pins, int v) {
|
||||
if (v) {
|
||||
*data |= (pins >> 1);
|
||||
} else {
|
||||
*data &= ~(pins >> 1);
|
||||
}
|
||||
}
|
||||
|
||||
static inline void setmybit(unsigned char *data, int pinno, int v) {
|
||||
if (v) {
|
||||
*data |= (1 << (pinno-1));
|
||||
} else {
|
||||
*data &= ~(1 <<(pinno-1));
|
||||
}
|
||||
}
|
||||
|
||||
static int ft245r_send(PROGRAMMER * pgm, unsigned char * buf, size_t len) {
|
||||
int rv;
|
||||
|
||||
rv = ftdi_write_data(handle, buf, len);
|
||||
if (len != rv) return -1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int ft245r_recv(PROGRAMMER * pgm, unsigned char * buf, size_t len) {
|
||||
int i;
|
||||
|
||||
// Copy over data from the circular buffer..
|
||||
// XXX This should timeout, and return error if there isn't enough
|
||||
// data.
|
||||
for (i=0; i<len; i++) {
|
||||
sem_wait (&buf_data);
|
||||
buf[i] = buffer[tail];
|
||||
if (tail == (BUFSIZE -1)) tail = 0;
|
||||
else tail++;
|
||||
sem_post (&buf_space);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static int ft245r_drain(PROGRAMMER * pgm, int display) {
|
||||
int r;
|
||||
unsigned char t;
|
||||
|
||||
// flush the buffer in the chip by changing the mode.....
|
||||
r = ftdi_set_bitmode(handle, 0, BITMODE_RESET); // reset
|
||||
if (r) return -1;
|
||||
r = ftdi_set_bitmode(handle, ft245r_ddr, BITMODE_SYNCBB); // set Synchronuse BitBang
|
||||
if (r) return -1;
|
||||
|
||||
// drain our buffer.
|
||||
while (head != tail) {
|
||||
ft245r_recv (pgm, &t, 1);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline int ft245r_sync(PROGRAMMER * pgm) {
|
||||
//printf ("sync.\n");
|
||||
// The old code did something that evaluated to a no-op.
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int ft245r_chip_erase(PROGRAMMER * pgm, AVRPART * p) {
|
||||
unsigned char cmd[4];
|
||||
unsigned char res[4];
|
||||
|
||||
if (p->op[AVR_OP_CHIP_ERASE] == NULL) {
|
||||
fprintf(stderr, "chip erase instruction not defined for part \"%s\"\n",
|
||||
p->desc);
|
||||
return -1;
|
||||
}
|
||||
|
||||
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);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static unsigned char saved_signature[3];
|
||||
|
||||
static void ft245r_set_bitclock(PROGRAMMER * pgm) {
|
||||
int r;
|
||||
int rate = 0;
|
||||
|
||||
/* bitclock is second. 1us = 0.000001. Max rate for ft232r 750000 */
|
||||
if(pgm->bitclock) {
|
||||
rate = (uint32_t)(1.0/pgm->bitclock) * 2;
|
||||
} else if (pgm->baudrate) {
|
||||
rate = pgm->baudrate * 2;
|
||||
} else {
|
||||
rate = 150000; /* should work for all ftdi chips and the avr default internal clock of 1MHz */
|
||||
}
|
||||
|
||||
if ((verbose>=1) || FT245R_DEBUG) {
|
||||
fprintf(stderr," ft245r: spi bitclk %d -> ft baudrate %d\n",
|
||||
rate / 2, rate);
|
||||
}
|
||||
r = ftdi_set_baudrate(handle, rate);
|
||||
if (r) {
|
||||
fprintf(stderr, "Set baudrate (%d) failed with error '%s'.\n",
|
||||
rate, ftdi_get_error_string (handle));
|
||||
exit (1);
|
||||
}
|
||||
}
|
||||
|
||||
static int set_reset(PROGRAMMER * pgm, int val) {
|
||||
unsigned char buf[1];
|
||||
|
||||
buf[0] = 0;
|
||||
if (val) buf[0] |= ft245r_reset;
|
||||
|
||||
ft245r_send (pgm, buf, 1);
|
||||
ft245r_recv (pgm, buf, 1);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int ft245r_cmd(PROGRAMMER * pgm, unsigned char cmd[4],
|
||||
unsigned char res[4]);
|
||||
/*
|
||||
* issue the 'program enable' command to the AVR device
|
||||
*/
|
||||
static int ft245r_program_enable(PROGRAMMER * pgm, AVRPART * p) {
|
||||
int retry_count = 0;
|
||||
unsigned char cmd[4];
|
||||
unsigned char res[4];
|
||||
int i,reset_ok;
|
||||
|
||||
ft245r_set_bitclock(pgm);
|
||||
|
||||
retry:
|
||||
reset_ok = 0;
|
||||
set_reset(pgm, 0);
|
||||
usleep(5000); // 5ms
|
||||
set_reset(pgm, 1);
|
||||
usleep(5000); // 5ms
|
||||
set_reset(pgm, 0);
|
||||
usleep(5000); // 5ms
|
||||
|
||||
cmd[0] = 0xAC;
|
||||
cmd[1] = 0x53;
|
||||
cmd[2] = 0;
|
||||
cmd[3] = 0;
|
||||
ft245r_cmd(pgm, cmd, res);
|
||||
if (res[2] == 0x53 ) reset_ok = 1;
|
||||
for (i=0; i<3; i++) {
|
||||
cmd[0] = 0x30;
|
||||
cmd[1] = 0;
|
||||
cmd[2] = i;
|
||||
cmd[3] = 0;
|
||||
ft245r_cmd(pgm, cmd, res);
|
||||
saved_signature[i] = res[3];
|
||||
}
|
||||
if (reset_ok && (saved_signature[0] == 0x1e)) // success
|
||||
return 0;
|
||||
|
||||
if (retry_count < 5) {
|
||||
if (retry_count == 3) {
|
||||
ft245r_drain (pgm, 0);
|
||||
tail = head;
|
||||
}
|
||||
retry_count++;
|
||||
goto retry;
|
||||
}
|
||||
if ((verbose>=1) || FT245R_DEBUG) {
|
||||
fprintf(stderr,
|
||||
"%s: ft245r_program_enable: failed\n", progname);
|
||||
fflush(stderr);
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
static int ft245r_read_sig_bytes(PROGRAMMER * pgm, AVRPART * p, AVRMEM * m) {
|
||||
m->buf[0] = saved_signature[0];
|
||||
m->buf[1] = saved_signature[1];
|
||||
m->buf[2] = saved_signature[2];
|
||||
return 3;
|
||||
}
|
||||
|
||||
#define check_pin(s) {\
|
||||
if ((pgm->pinno[s] & PIN_MASK) == 0) {\
|
||||
fprintf(stderr,\
|
||||
"%s: pin %s is not set\n",\
|
||||
progname,#s);\
|
||||
exit(1);\
|
||||
}\
|
||||
if ((pgm->pinno[s] & PIN_INVERSE) != 0) {\
|
||||
fprintf(stderr,\
|
||||
"%s: pin %s inverse is not supported.\n",\
|
||||
progname,#s);\
|
||||
exit(1);\
|
||||
}\
|
||||
}
|
||||
|
||||
/*
|
||||
* initialize the AVR device and prepare it to accept commands
|
||||
*/
|
||||
static int ft245r_initialize(PROGRAMMER * pgm, AVRPART * p) {
|
||||
check_pin(PIN_AVR_SCK);
|
||||
check_pin(PIN_AVR_MOSI);
|
||||
check_pin(PIN_AVR_MISO);
|
||||
check_pin(PIN_AVR_RESET);
|
||||
return ft245r_program_enable(pgm, p);
|
||||
}
|
||||
|
||||
static void ft245r_disable(PROGRAMMER * pgm) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
static void ft245r_enable(PROGRAMMER * pgm) {
|
||||
/* Do nothing. */
|
||||
return;
|
||||
}
|
||||
|
||||
static inline int set_data(unsigned char *buf, unsigned char data) {
|
||||
int j;
|
||||
int buf_pos = 0;
|
||||
unsigned char bit = 0x80;
|
||||
|
||||
for (j=0; j<8; j++) {
|
||||
buf[buf_pos] = 0;
|
||||
if (data & bit) buf[buf_pos] |= ft245r_mosi;
|
||||
buf_pos++;
|
||||
|
||||
buf[buf_pos] = 0;
|
||||
if (data & bit) buf[buf_pos] |= ft245r_mosi;
|
||||
buf[buf_pos] |= ft245r_sck;
|
||||
buf_pos++;
|
||||
|
||||
bit >>= 1;
|
||||
}
|
||||
return buf_pos;
|
||||
}
|
||||
|
||||
static inline unsigned char extract_data(unsigned char *buf, int offset) {
|
||||
int j;
|
||||
int buf_pos = 1;
|
||||
unsigned char bit = 0x80;
|
||||
unsigned char r = 0;
|
||||
|
||||
buf += offset * (8 * FT245R_CYCLES);
|
||||
for (j=0; j<8; j++) {
|
||||
if (buf[buf_pos] & ft245r_miso) {
|
||||
r |= bit;
|
||||
}
|
||||
buf_pos += FT245R_CYCLES;
|
||||
bit >>= 1;
|
||||
}
|
||||
return r;
|
||||
}
|
||||
|
||||
/* to check data */
|
||||
static inline unsigned char extract_data_out(unsigned char *buf, int offset) {
|
||||
int j;
|
||||
int buf_pos = 1;
|
||||
unsigned char bit = 0x80;
|
||||
unsigned char r = 0;
|
||||
|
||||
buf += offset * (8 * FT245R_CYCLES);
|
||||
for (j=0; j<8; j++) {
|
||||
if (buf[buf_pos] & ft245r_mosi) {
|
||||
r |= bit;
|
||||
}
|
||||
buf_pos += FT245R_CYCLES;
|
||||
bit >>= 1;
|
||||
}
|
||||
return r;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* transmit an AVR device command and return the results; 'cmd' and
|
||||
* 'res' must point to at least a 4 byte data buffer
|
||||
*/
|
||||
static int ft245r_cmd(PROGRAMMER * pgm, unsigned char cmd[4],
|
||||
unsigned char res[4]) {
|
||||
int i,buf_pos;
|
||||
unsigned char buf[128];
|
||||
|
||||
buf_pos = 0;
|
||||
for (i=0; i<4; i++) {
|
||||
buf_pos += set_data(buf+buf_pos, cmd[i]);
|
||||
}
|
||||
buf[buf_pos] = 0;
|
||||
buf_pos++;
|
||||
|
||||
ft245r_send (pgm, buf, buf_pos);
|
||||
ft245r_recv (pgm, buf, buf_pos);
|
||||
res[0] = extract_data(buf, 0);
|
||||
res[1] = extract_data(buf, 1);
|
||||
res[2] = extract_data(buf, 2);
|
||||
res[3] = extract_data(buf, 3);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static int ft245r_open(PROGRAMMER * pgm, char * port) {
|
||||
int rv;
|
||||
int devnum = -1;
|
||||
strcpy(pgm->port, port);
|
||||
|
||||
if (strcmp(port,DEFAULT_USB) != 0) {
|
||||
if (strncasecmp("ft", port, 2) == 0) {
|
||||
char *startptr = port + 2;
|
||||
char *endptr = NULL;
|
||||
devnum = strtol(startptr,&endptr,10);
|
||||
if ((startptr==endptr) || (*endptr != '\0')) {
|
||||
devnum = -1;
|
||||
}
|
||||
}
|
||||
if (devnum < 0) {
|
||||
fprintf(stderr,
|
||||
"%s: invalid portname '%s': use 'ft[0-9]+'\n",
|
||||
progname,port);
|
||||
exit(1);
|
||||
}
|
||||
} else {
|
||||
devnum = 0;
|
||||
}
|
||||
|
||||
handle = malloc (sizeof (struct ftdi_context));
|
||||
ftdi_init(handle);
|
||||
rv = ftdi_usb_open_desc_index(handle,
|
||||
pgm->usbvid?pgm->usbvid:0x0403,
|
||||
pgm->usbpid?pgm->usbpid:0x6001,
|
||||
pgm->usbproduct[0]?pgm->usbproduct:NULL,
|
||||
pgm->usbsn[0]?pgm->usbsn:NULL,
|
||||
devnum);
|
||||
if (rv) {
|
||||
fprintf (stderr, "can't open ftdi device %d. (%s)\n", devnum, ftdi_get_error_string(handle));
|
||||
ftdi_deinit (handle);
|
||||
free(handle);
|
||||
exit (1);
|
||||
}
|
||||
|
||||
/* We start a new thread to read the output from the FTDI. This is
|
||||
* necessary because otherwise we'll deadlock. We cannot finish
|
||||
* writing because the ftdi cannot send the results because we
|
||||
* haven't provided a read buffer yet. */
|
||||
|
||||
sem_init (&buf_data, 0, 0);
|
||||
sem_init (&buf_space, 0, BUFSIZE);
|
||||
pthread_create (&readerthread, NULL, reader, handle);
|
||||
|
||||
ft245r_ddr = 0;
|
||||
setmybit(&ft245r_ddr, pgm->pinno[PIN_AVR_SCK], 1);
|
||||
setmybit(&ft245r_ddr, pgm->pinno[PIN_AVR_MOSI], 1);
|
||||
setmybit(&ft245r_ddr, pgm->pinno[PIN_AVR_RESET], 1);
|
||||
|
||||
ft245r_sck = 0;
|
||||
setmybit(&ft245r_sck, pgm->pinno[PIN_AVR_SCK], 1);
|
||||
ft245r_mosi = 0;
|
||||
setmybit(&ft245r_mosi, pgm->pinno[PIN_AVR_MOSI], 1);
|
||||
ft245r_reset = 0;
|
||||
setmybit(&ft245r_reset, pgm->pinno[PIN_AVR_RESET], 1);
|
||||
ft245r_miso = 0;
|
||||
setmybit(&ft245r_miso, pgm->pinno[PIN_AVR_MISO], 1);
|
||||
|
||||
rv = ftdi_set_bitmode(handle, ft245r_ddr, BITMODE_SYNCBB); // set Synchronous BitBang
|
||||
|
||||
if (rv) {
|
||||
fprintf(stderr,
|
||||
"%s: Synchronous BitBangMode is not supported (%s)\n",
|
||||
progname, ftdi_get_error_string(handle));
|
||||
ftdi_usb_close(handle);
|
||||
ftdi_deinit (handle);
|
||||
free(handle);
|
||||
exit(1);
|
||||
}
|
||||
/*
|
||||
* drain any extraneous input
|
||||
*/
|
||||
ft245r_drain (pgm, 0);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static void ft245r_close(PROGRAMMER * pgm) {
|
||||
// I think the switch to BB mode and back flushes the buffer.
|
||||
ftdi_set_bitmode(handle, 0, BITMODE_SYNCBB); // set Synchronous BitBang, all in puts
|
||||
ftdi_set_bitmode(handle, 0, BITMODE_RESET); // disable Synchronous BitBang
|
||||
ftdi_usb_close(handle);
|
||||
ftdi_deinit (handle);
|
||||
free(handle);
|
||||
}
|
||||
|
||||
static void ft245r_display(PROGRAMMER * pgm, const char * p) {
|
||||
fprintf(stderr, "%sPin assignment : 1..8 = DBUS0..7, 9..12 = GPIO0..3\n",p);
|
||||
pgm_display_generic_mask(pgm, p, SHOW_AVR_PINS);
|
||||
}
|
||||
|
||||
static int ft245r_paged_write_gen(PROGRAMMER * pgm, AVRPART * p, AVRMEM * m,
|
||||
unsigned int page_size, unsigned int addr,
|
||||
unsigned int n_bytes) {
|
||||
unsigned long i, pa;
|
||||
int rc;
|
||||
|
||||
for (i=0; i<n_bytes; i++, addr++) {
|
||||
rc = avr_write_byte_default(pgm, p, m, addr, m->buf[addr]);
|
||||
if (rc != 0) {
|
||||
return -2;
|
||||
}
|
||||
|
||||
if (m->paged) {
|
||||
// Can this piece of code ever be activated?? Do AVRs exist that
|
||||
// have paged non-flash memories? -- REW
|
||||
// XXX Untested code below.
|
||||
/*
|
||||
* check to see if it is time to flush the page with a page
|
||||
* write
|
||||
*/
|
||||
|
||||
if (((addr % m->page_size) == m->page_size-1) || (i == n_bytes-1)) {
|
||||
pa = addr - (addr % m->page_size);
|
||||
|
||||
rc = avr_write_page(pgm, p, m, pa);
|
||||
if (rc != 0) {
|
||||
return -2;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return i;
|
||||
}
|
||||
|
||||
static struct ft245r_request {
|
||||
int addr;
|
||||
int bytes;
|
||||
int n;
|
||||
struct ft245r_request *next;
|
||||
} *req_head,*req_tail,*req_pool;
|
||||
|
||||
static void put_request(int addr, int bytes, int n) {
|
||||
struct ft245r_request *p;
|
||||
if (req_pool) {
|
||||
p = req_pool;
|
||||
req_pool = p->next;
|
||||
} else {
|
||||
p = malloc(sizeof(struct ft245r_request));
|
||||
if (!p) {
|
||||
fprintf(stderr, "can't alloc memory\n");
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
memset(p, 0, sizeof(struct ft245r_request));
|
||||
p->addr = addr;
|
||||
p->bytes = bytes;
|
||||
p->n = n;
|
||||
if (req_tail) {
|
||||
req_tail->next = p;
|
||||
req_tail = p;
|
||||
} else {
|
||||
req_head = req_tail = p;
|
||||
}
|
||||
}
|
||||
|
||||
static int do_request(PROGRAMMER * pgm, AVRMEM *m) {
|
||||
struct ft245r_request *p;
|
||||
int addr, bytes, j, n;
|
||||
unsigned char buf[FT245R_FRAGMENT_SIZE+1+128];
|
||||
|
||||
if (!req_head) return 0;
|
||||
p = req_head;
|
||||
req_head = p->next;
|
||||
if (!req_head) req_tail = req_head;
|
||||
|
||||
addr = p->addr;
|
||||
bytes = p->bytes;
|
||||
n = p->n;
|
||||
memset(p, 0, sizeof(struct ft245r_request));
|
||||
p->next = req_pool;
|
||||
req_pool = p;
|
||||
|
||||
ft245r_recv(pgm, buf, bytes);
|
||||
for (j=0; j<n; j++) {
|
||||
m->buf[addr++] = extract_data(buf , (j * 4 + 3));
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int ft245r_paged_write_flash(PROGRAMMER * pgm, AVRPART * p, AVRMEM * m,
|
||||
int page_size, int addr, int n_bytes) {
|
||||
unsigned int i,j;
|
||||
int addr_save,buf_pos,do_page_write,req_count;
|
||||
unsigned char buf[FT245R_FRAGMENT_SIZE+1+128];
|
||||
|
||||
req_count = 0;
|
||||
for (i=0; i<n_bytes; ) {
|
||||
addr_save = addr;
|
||||
buf_pos = 0;
|
||||
do_page_write = 0;
|
||||
for (j=0; j< FT245R_FRAGMENT_SIZE/8/FT245R_CYCLES/4; j++) {
|
||||
buf_pos += set_data(buf+buf_pos, (addr & 1)?0x48:0x40 );
|
||||
buf_pos += set_data(buf+buf_pos, (addr >> 9) & 0xff );
|
||||
buf_pos += set_data(buf+buf_pos, (addr >> 1) & 0xff );
|
||||
buf_pos += set_data(buf+buf_pos, m->buf[addr]);
|
||||
addr ++;
|
||||
i++;
|
||||
if ( (m->paged) &&
|
||||
(((i % m->page_size) == 0) || (i == n_bytes))) {
|
||||
do_page_write = 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
#if defined(USE_INLINE_WRITE_PAGE)
|
||||
if (do_page_write) {
|
||||
int addr_wk = addr_save - (addr_save % m->page_size);
|
||||
/* If this device has a "load extended address" command, issue it. */
|
||||
if (m->op[AVR_OP_LOAD_EXT_ADDR]) {
|
||||
unsigned char cmd[4];
|
||||
OPCODE *lext = m->op[AVR_OP_LOAD_EXT_ADDR];
|
||||
|
||||
memset(cmd, 0, 4);
|
||||
avr_set_bits(lext, cmd);
|
||||
avr_set_addr(lext, cmd, addr_wk/2);
|
||||
buf_pos += set_data(buf+buf_pos, cmd[0]);
|
||||
buf_pos += set_data(buf+buf_pos, cmd[1]);
|
||||
buf_pos += set_data(buf+buf_pos, cmd[2]);
|
||||
buf_pos += set_data(buf+buf_pos, cmd[3]);
|
||||
}
|
||||
buf_pos += set_data(buf+buf_pos, 0x4C); /* Issue Page Write */
|
||||
buf_pos += set_data(buf+buf_pos,(addr_wk >> 9) & 0xff);
|
||||
buf_pos += set_data(buf+buf_pos,(addr_wk >> 1) & 0xff);
|
||||
buf_pos += set_data(buf+buf_pos, 0);
|
||||
}
|
||||
#endif
|
||||
if (i >= n_bytes) {
|
||||
buf[buf_pos++] = 0; // sck down
|
||||
}
|
||||
ft245r_send(pgm, buf, buf_pos);
|
||||
put_request(addr_save, buf_pos, 0);
|
||||
//ft245r_sync(pgm);
|
||||
#if 0
|
||||
fprintf(stderr, "send addr 0x%04x bufsize %d [%02x %02x] page_write %d\n",
|
||||
addr_save,buf_pos,
|
||||
extract_data_out(buf , (0*4 + 3) ),
|
||||
extract_data_out(buf , (1*4 + 3) ),
|
||||
do_page_write);
|
||||
#endif
|
||||
req_count++;
|
||||
if (req_count > REQ_OUTSTANDINGS)
|
||||
do_request(pgm, m);
|
||||
if (do_page_write) {
|
||||
#if defined(USE_INLINE_WRITE_PAGE)
|
||||
while (do_request(pgm, m))
|
||||
;
|
||||
usleep(m->max_write_delay);
|
||||
#else
|
||||
int addr_wk = addr_save - (addr_save % m->page_size);
|
||||
int rc;
|
||||
while (do_request(pgm, m))
|
||||
;
|
||||
rc = avr_write_page(pgm, p, m, addr_wk);
|
||||
if (rc != 0) {
|
||||
return -2;
|
||||
}
|
||||
#endif
|
||||
req_count = 0;
|
||||
}
|
||||
}
|
||||
while (do_request(pgm, m))
|
||||
;
|
||||
return i;
|
||||
}
|
||||
|
||||
|
||||
static int ft245r_paged_write(PROGRAMMER * pgm, AVRPART * p, AVRMEM * m,
|
||||
unsigned int page_size, unsigned int addr, unsigned int n_bytes) {
|
||||
if (strcmp(m->desc, "flash") == 0) {
|
||||
return ft245r_paged_write_flash(pgm, p, m, page_size, addr, n_bytes);
|
||||
} else if (strcmp(m->desc, "eeprom") == 0) {
|
||||
return ft245r_paged_write_gen(pgm, p, m, page_size, addr, n_bytes);
|
||||
} else {
|
||||
return -2;
|
||||
}
|
||||
}
|
||||
|
||||
static int ft245r_paged_load_gen(PROGRAMMER * pgm, AVRPART * p, AVRMEM * m,
|
||||
unsigned int page_size, unsigned int addr,
|
||||
int n_bytes) {
|
||||
unsigned char rbyte;
|
||||
unsigned long i;
|
||||
int rc;
|
||||
|
||||
for (i=0; i<n_bytes; i++) {
|
||||
rc = avr_read_byte_default(pgm, p, m, i+addr, &rbyte);
|
||||
if (rc != 0) {
|
||||
return -2;
|
||||
}
|
||||
m->buf[i+addr] = rbyte;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int ft245r_paged_load_flash(PROGRAMMER * pgm, AVRPART * p, AVRMEM * m,
|
||||
unsigned int page_size, unsigned int addr,
|
||||
unsigned int n_bytes) {
|
||||
unsigned long i,j,n;
|
||||
int addr_save,buf_pos;
|
||||
int req_count = 0;
|
||||
unsigned char buf[FT245R_FRAGMENT_SIZE+1];
|
||||
|
||||
for (i=0; i<n_bytes; ) {
|
||||
buf_pos = 0;
|
||||
addr_save = addr;
|
||||
for (j=0; j< FT245R_FRAGMENT_SIZE/8/FT245R_CYCLES/4; j++) {
|
||||
if (i >= n_bytes) break;
|
||||
buf_pos += set_data(buf+buf_pos, (addr & 1)?0x28:0x20 );
|
||||
buf_pos += set_data(buf+buf_pos, (addr >> 9) & 0xff );
|
||||
buf_pos += set_data(buf+buf_pos, (addr >> 1) & 0xff );
|
||||
buf_pos += set_data(buf+buf_pos, 0);
|
||||
addr ++;
|
||||
i++;
|
||||
}
|
||||
if (i >= n_bytes) {
|
||||
buf[buf_pos++] = 0; // sck down
|
||||
}
|
||||
n = j;
|
||||
ft245r_send(pgm, buf, buf_pos);
|
||||
put_request(addr_save, buf_pos, n);
|
||||
req_count++;
|
||||
if (req_count > REQ_OUTSTANDINGS)
|
||||
do_request(pgm, m);
|
||||
|
||||
}
|
||||
while (do_request(pgm, m))
|
||||
;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int ft245r_paged_load(PROGRAMMER * pgm, AVRPART * p, AVRMEM * m,
|
||||
unsigned int page_size, unsigned int addr,
|
||||
unsigned int n_bytes) {
|
||||
if (strcmp(m->desc, "flash") == 0) {
|
||||
return ft245r_paged_load_flash(pgm, p, m, page_size, addr, n_bytes);
|
||||
} else if (strcmp(m->desc, "eeprom") == 0) {
|
||||
return ft245r_paged_load_gen(pgm, p, m, page_size, addr, n_bytes);
|
||||
} else {
|
||||
return -2;
|
||||
}
|
||||
}
|
||||
|
||||
void ft245r_initpgm(PROGRAMMER * pgm) {
|
||||
strcpy(pgm->type, "ftdi_syncbb");
|
||||
|
||||
/*
|
||||
* mandatory functions
|
||||
*/
|
||||
pgm->initialize = ft245r_initialize;
|
||||
pgm->display = ft245r_display;
|
||||
pgm->enable = ft245r_enable;
|
||||
pgm->disable = ft245r_disable;
|
||||
pgm->program_enable = ft245r_program_enable;
|
||||
pgm->chip_erase = ft245r_chip_erase;
|
||||
pgm->cmd = ft245r_cmd;
|
||||
pgm->open = ft245r_open;
|
||||
pgm->close = ft245r_close;
|
||||
pgm->read_byte = avr_read_byte_default;
|
||||
pgm->write_byte = avr_write_byte_default;
|
||||
|
||||
/*
|
||||
* optional functions
|
||||
*/
|
||||
pgm->paged_write = ft245r_paged_write;
|
||||
pgm->paged_load = ft245r_paged_load;
|
||||
|
||||
pgm->read_sig_bytes = ft245r_read_sig_bytes;
|
||||
}
|
||||
|
||||
#else
|
||||
static int ft245r_noftdi_open (struct programmer_t *pgm, char * name) {
|
||||
fprintf(stderr,
|
||||
"%s: error: no ftdi support. Please compile again with libftdi installed.\n",
|
||||
progname);
|
||||
|
||||
exit(1);
|
||||
}
|
||||
|
||||
void ft245r_initpgm(PROGRAMMER * pgm) {
|
||||
strcpy(pgm->type, "ftdi_syncbb");
|
||||
pgm->open = ft245r_noftdi_open;
|
||||
}
|
||||
#endif
|
||||
|
||||
const char ft245r_desc[] = "FT245R/FT232R Synchronous BitBangMode Programmer";
|
|
@ -0,0 +1,10 @@
|
|||
#ifndef ft245r_h
|
||||
#define ft245r_h
|
||||
|
||||
#include "pgm.h"
|
||||
|
||||
extern const char ft245r_desc[];
|
||||
void ft245r_initpgm (PROGRAMMER * pgm);
|
||||
|
||||
|
||||
#endif /* ft245r_h */
|
67
par.c
67
par.c
|
@ -178,25 +178,6 @@ static int par_highpulsepin(PROGRAMMER * pgm, int pin)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static char * pins_to_str(unsigned int pmask)
|
||||
{
|
||||
static char buf[64];
|
||||
int pin;
|
||||
char b2[8];
|
||||
|
||||
buf[0] = 0;
|
||||
for (pin = 1; pin <= 17; pin++) {
|
||||
if (pmask & (1 << pin)) {
|
||||
sprintf(b2, "%d", pin);
|
||||
if (buf[0] != 0)
|
||||
strcat(buf, ",");
|
||||
strcat(buf, b2);
|
||||
}
|
||||
}
|
||||
|
||||
return buf;
|
||||
}
|
||||
|
||||
/*
|
||||
* apply power to the AVR processor
|
||||
*/
|
||||
|
@ -337,52 +318,6 @@ static void par_close(PROGRAMMER * pgm)
|
|||
pgm->fd.ifd = -1;
|
||||
}
|
||||
|
||||
static void par_display(PROGRAMMER * pgm, const char * p)
|
||||
{
|
||||
char vccpins[64];
|
||||
char buffpins[64];
|
||||
|
||||
if (pgm->pinno[PPI_AVR_VCC]) {
|
||||
snprintf(vccpins, sizeof(vccpins), "%s",
|
||||
pins_to_str(pgm->pinno[PPI_AVR_VCC]));
|
||||
}
|
||||
else {
|
||||
strcpy(vccpins, " (not used)");
|
||||
}
|
||||
|
||||
if (pgm->pinno[PPI_AVR_BUFF]) {
|
||||
snprintf(buffpins, sizeof(buffpins), "%s",
|
||||
pins_to_str(pgm->pinno[PPI_AVR_BUFF]));
|
||||
}
|
||||
else {
|
||||
strcpy(buffpins, " (not used)");
|
||||
}
|
||||
|
||||
fprintf(stderr,
|
||||
"%s VCC = %s\n"
|
||||
"%s BUFF = %s\n"
|
||||
"%s RESET = %d\n"
|
||||
"%s SCK = %d\n"
|
||||
"%s MOSI = %d\n"
|
||||
"%s MISO = %d\n"
|
||||
"%s ERR LED = %d\n"
|
||||
"%s RDY LED = %d\n"
|
||||
"%s PGM LED = %d\n"
|
||||
"%s VFY LED = %d\n",
|
||||
|
||||
p, vccpins,
|
||||
p, buffpins,
|
||||
p, pgm->pinno[PIN_AVR_RESET],
|
||||
p, pgm->pinno[PIN_AVR_SCK],
|
||||
p, pgm->pinno[PIN_AVR_MOSI],
|
||||
p, pgm->pinno[PIN_AVR_MISO],
|
||||
p, pgm->pinno[PIN_LED_ERR],
|
||||
p, pgm->pinno[PIN_LED_RDY],
|
||||
p, pgm->pinno[PIN_LED_PGM],
|
||||
p, pgm->pinno[PIN_LED_VFY]);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* parse the -E string
|
||||
*/
|
||||
|
@ -433,7 +368,7 @@ void par_initpgm(PROGRAMMER * pgm)
|
|||
pgm->pgm_led = bitbang_pgm_led;
|
||||
pgm->vfy_led = bitbang_vfy_led;
|
||||
pgm->initialize = bitbang_initialize;
|
||||
pgm->display = par_display;
|
||||
pgm->display = pgm_display_generic;
|
||||
pgm->enable = par_enable;
|
||||
pgm->disable = par_disable;
|
||||
pgm->powerup = par_powerup;
|
||||
|
|
66
pgm.c
66
pgm.c
|
@ -212,6 +212,72 @@ void programmer_display(PROGRAMMER * pgm, const char * p)
|
|||
pgm->display(pgm, p);
|
||||
}
|
||||
|
||||
static char * pins_to_str(unsigned int pmask)
|
||||
{
|
||||
static char buf[64];
|
||||
int pin;
|
||||
char b2[8];
|
||||
|
||||
if ((pmask & PIN_MASK) == 0)
|
||||
return " (not used)";
|
||||
|
||||
buf[0] = ' ';
|
||||
buf[1] = 0;
|
||||
for (pin = 0; pin <= 17; pin++) {
|
||||
if (pmask & (1 << pin)) {
|
||||
sprintf(b2, "%d", pin);
|
||||
if (buf[1] != 0)
|
||||
strcat(buf, ",");
|
||||
strcat(buf, b2);
|
||||
}
|
||||
}
|
||||
|
||||
return buf;
|
||||
}
|
||||
|
||||
static char * pin_to_str(unsigned int pin)
|
||||
{
|
||||
static char buf[12];
|
||||
|
||||
if ((pin & PIN_MASK) == 0)
|
||||
return " (not used)";
|
||||
|
||||
buf[0] = (pin & PIN_INVERSE)?'~':' ';
|
||||
buf[1] = 0;
|
||||
sprintf(buf+1, "%d", pin & PIN_MASK);
|
||||
|
||||
return buf;
|
||||
}
|
||||
|
||||
void pgm_display_generic_mask(PROGRAMMER * pgm, const char * p, unsigned int show)
|
||||
{
|
||||
if(show & (1<<PPI_AVR_VCC))
|
||||
fprintf(stderr, "%s VCC = %s\n", p, pins_to_str(pgm->pinno[PPI_AVR_VCC]));
|
||||
if(show & (1<<PPI_AVR_BUFF))
|
||||
fprintf(stderr, "%s BUFF = %s\n", p, pins_to_str(pgm->pinno[PPI_AVR_BUFF]));
|
||||
if(show & (1<<PIN_AVR_RESET))
|
||||
fprintf(stderr, "%s RESET = %s\n", p, pin_to_str(pgm->pinno[PIN_AVR_RESET]));
|
||||
if(show & (1<<PIN_AVR_SCK))
|
||||
fprintf(stderr, "%s SCK = %s\n", p, pin_to_str(pgm->pinno[PIN_AVR_SCK]));
|
||||
if(show & (1<<PIN_AVR_MOSI))
|
||||
fprintf(stderr, "%s MOSI = %s\n", p, pin_to_str(pgm->pinno[PIN_AVR_MOSI]));
|
||||
if(show & (1<<PIN_AVR_MISO))
|
||||
fprintf(stderr, "%s MISO = %s\n", p, pin_to_str(pgm->pinno[PIN_AVR_MISO]));
|
||||
if(show & (1<<PIN_LED_ERR))
|
||||
fprintf(stderr, "%s ERR LED = %s\n", p, pin_to_str(pgm->pinno[PIN_LED_ERR]));
|
||||
if(show & (1<<PIN_LED_RDY))
|
||||
fprintf(stderr, "%s RDY LED = %s\n", p, pin_to_str(pgm->pinno[PIN_LED_RDY]));
|
||||
if(show & (1<<PIN_LED_PGM))
|
||||
fprintf(stderr, "%s PGM LED = %s\n", p, pin_to_str(pgm->pinno[PIN_LED_PGM]));
|
||||
if(show & (1<<PIN_LED_VFY))
|
||||
fprintf(stderr, "%s VFY LED = %s\n", p, pin_to_str(pgm->pinno[PIN_LED_VFY]));
|
||||
}
|
||||
|
||||
void pgm_display_generic(PROGRAMMER * pgm, const char * p)
|
||||
{
|
||||
pgm_display_generic_mask(pgm, p, SHOW_ALL_PINS);
|
||||
}
|
||||
|
||||
PROGRAMMER * locate_programmer(LISTID programmers, const char * configid)
|
||||
{
|
||||
LNODEID ln1, ln2;
|
||||
|
|
9
pgm.h
9
pgm.h
|
@ -143,6 +143,15 @@ PROGRAMMER * pgm_dup(const PROGRAMMER const * src);
|
|||
void pgm_free(PROGRAMMER * const p);
|
||||
|
||||
void programmer_display(PROGRAMMER * pgm, const char * p);
|
||||
|
||||
/* show is a mask like this (1<<PIN_AVR_SCK)|(1<<PIN_AVR_MOSI)| ... */
|
||||
#define SHOW_ALL_PINS (~0u)
|
||||
#define SHOW_PPI_PINS ((1<<PPI_AVR_VCC)|(1<<PPI_AVR_BUFF))
|
||||
#define SHOW_AVR_PINS ((1<<PIN_AVR_RESET)|(1<<PIN_AVR_SCK)|(1<<PIN_AVR_MOSI)|(1<<PIN_AVR_MISO))
|
||||
#define SHOW_LED_PINS ((1<<PIN_LED_ERR)|(1<<PIN_LED_RDY)|(1<<PIN_LED_PGM)|(1<<PIN_LED_VFY))
|
||||
void pgm_display_generic_mask(PROGRAMMER * pgm, const char * p, unsigned int show);
|
||||
void pgm_display_generic(PROGRAMMER * pgm, const char * p);
|
||||
|
||||
PROGRAMMER * locate_programmer(LISTID programmers, const char * configid);
|
||||
|
||||
typedef void (*walk_programmers_cb)(const char *name, const char *desc,
|
||||
|
|
|
@ -35,6 +35,7 @@
|
|||
#include "avrftdi.h"
|
||||
#include "buspirate.h"
|
||||
#include "butterfly.h"
|
||||
#include "ft245r.h"
|
||||
#include "jtagmkI.h"
|
||||
#include "jtagmkII.h"
|
||||
#include "par.h"
|
||||
|
@ -61,6 +62,7 @@ const PROGRAMMER_TYPE const programmers_types[] = {
|
|||
{"dragon_jtag", jtagmkII_dragon_initpgm, jtagmkII_dragon_desc},
|
||||
{"dragon_pdi", jtagmkII_dragon_pdi_initpgm, jtagmkII_dragon_pdi_desc},
|
||||
{"dragon_pp", stk500v2_dragon_pp_initpgm, stk500v2_dragon_pp_desc},
|
||||
{"ftdi_syncbb", ft245r_initpgm, ft245r_desc},
|
||||
{"jtagmki", jtagmkI_initpgm, jtagmkI_desc},
|
||||
{"jtagmkii", jtagmkII_initpgm, jtagmkII_desc},
|
||||
{"jtagmkii_avr32", jtagmkII_avr32_initpgm, jtagmkII_avr32_desc},
|
||||
|
|
|
@ -22,6 +22,8 @@
|
|||
#ifndef __pindefs_h__
|
||||
#define __pindefs_h__
|
||||
|
||||
#include <limits.h>
|
||||
|
||||
enum {
|
||||
PPI_AVR_VCC=1,
|
||||
PPI_AVR_BUFF,
|
||||
|
@ -35,8 +37,8 @@ enum {
|
|||
PIN_LED_VFY,
|
||||
N_PINS
|
||||
};
|
||||
#define PIN_INVERSE 0x80 /* flag for inverted pin in serbb */
|
||||
#define PIN_MASK 0x7f
|
||||
#define PIN_MASK (UINT_MAX>>1)
|
||||
#define PIN_INVERSE (~(PIN_MASK)) /* flag for inverted pin in serbb */
|
||||
|
||||
#define LED_ON(fd,pin) ppi_setpin(fd,pin,0)
|
||||
#define LED_OFF(fd,pin) ppi_setpin(fd,pin,1)
|
||||
|
|
Loading…
Reference in New Issue