Create new pin definition data structures to support 0-based pin numbers, and mixed inverse/non-inverse pin lists.

* avrftdi.c,buspirate.c,linuxgpio.c,par.c,serbb_*.c: added function call 
          to fill old pinno entries from new pin definitions.
	* pindefs.[hc]: added data struct and helper functions for new pin definitions
	* avrdude.conf.in: pins in entries using ftdi_syncbb are now 0-based
	* config_gram.y: allow combinations of inverted and non-inverted pins in pin lists
	* ft245r.c: reworked to work directly with the new pin definitions,
          pins are now 0-based, inverse pins are supported, buff is supported
	* pgm.[ch]: added new pin definitions field to programmer structure, 
          adapted pin display functions

git-svn-id: svn://svn.savannah.nongnu.org/avrdude/trunk@1160 81a1dc3b-b13d-400b-aceb-764788c761c2
This commit is contained in:
Rene Liebscher 2013-05-03 22:35:00 +00:00
parent e72e92f027
commit bb0092eb4e
16 changed files with 436 additions and 174 deletions

View File

@ -1,3 +1,17 @@
2013-05-03 Rene Liebscher <R.Liebscher@gmx.de>
Create new pin definition data structures to support 0-based pin numbers,
and mixed inverse/non-inverse pin lists.
* avrftdi.c,buspirate.c,linuxgpio.c,par.c,serbb_*.c: added function call
to fill old pinno entries from new pin definitions.
* pindefs.[hc]: added data struct and helper functions for new pin definitions
* avrdude.conf.in: pins in entries using ftdi_syncbb are now 0-based
* config_gram.y: allow combinations of inverted and non-inverted pins in pin lists
* ft245r.c: reworked to work directly with the new pin definitions,
pins are now 0-based, inverse pins are supported, buff is supported
* pgm.[ch]: added new pin definitions field to programmer structure,
adapted pin display functions
2013-05-03 Hannes Weisbach <hannes_weisbach@gmx.net>
* avrftdi_private.h: Remove update forward declaration from avrftdi_print to
@ -42,7 +56,7 @@
of the ongoing OUT request and subsequently timeout, because an IN request
cannot be issued due to the synchronous part of libftdi. This should fix
#38831 and #38659.
2013-04-25 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
* configure.ac(AC_CONFIG_HEADERS): Replace the old AM_CONFIG_HEADER

View File

@ -140,6 +140,7 @@ libavrdude_a_SOURCES = \
pgm_type.h \
pickit2.c \
pickit2.h \
pindefs.c \
pindefs.h \
ppi.c \
ppi.h \

View File

@ -645,10 +645,10 @@ programmer
desc = "FT245R Synchronous BitBang";
type = "ftdi_syncbb";
connection_type = usb;
miso = 2; # D1
sck = 1; # D0
mosi = 3; # D2
reset = 5; # D4
miso = 1; # D1
sck = 0; # D0
mosi = 2; # D2
reset = 4; # D4
;
programmer
@ -656,10 +656,10 @@ programmer
desc = "FT232R Synchronous BitBang";
type = "ftdi_syncbb";
connection_type = usb;
miso = 2; # RxD
sck = 1; # RTS
mosi = 3; # TxD
reset = 5; # DTR
miso = 1; # RxD
sck = 0; # RTS
mosi = 2; # TxD
reset = 4; # DTR
;
# see http://www.bitwizard.nl/wiki/index.php/FTDI_ATmega
@ -668,10 +668,10 @@ programmer
desc = "BitWizard ftdi_atmega builtin programmer";
type = "ftdi_syncbb";
connection_type = usb;
miso = 6; # DSR
sck = 7; # DCD
mosi = 4; # CTS
reset = 8; # RI
miso = 5; # DSR
sck = 6; # DCD
mosi = 3; # CTS
reset = 7; # RI
;
# see http://www.geocities.jp/arduino_diecimila/bootloader/index_en.html
@ -681,10 +681,10 @@ programmer
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)
miso = 3; # CTS X3(1)
sck = 5; # DSR X3(2)
mosi = 6; # DCD X3(3)
reset = 7; # RI X3(4)
;
# website mentioned above uses this id

View File

@ -1299,6 +1299,8 @@ void avrftdi_initpgm(PROGRAMMER * pgm)
strcpy(pgm->type, "avrftdi");
pgm_fill_old_pins(pgm); // TODO to be removed if old pin data no longer needed
/*
* mandatory functions
*/

View File

@ -1283,6 +1283,8 @@ void buspirate_bb_initpgm(struct programmer_t *pgm)
{
strcpy(pgm->type, "BusPirate_BB");
pgm_fill_old_pins(pgm); // TODO to be removed if old pin data no longer needed
pgm->display = buspirate_dummy_6;
/* BusPirate itself related methods */

View File

@ -288,6 +288,8 @@ prog_def :
pgm_free(existing_prog);
}
PUSH(programmers, current_prog);
// pgm_fill_old_pins(current_prog); // TODO to be removed if old pin data no longer needed
// pgm_display_generic(current_prog, id);
current_prog = NULL;
}
;
@ -533,24 +535,35 @@ prog_parm_usb:
}
;
pin_number:
pin_number_non_empty:
TKN_NUMBER { assign_pin(pin_name, $1, 0); }
|
TKN_TILDE TKN_NUMBER { assign_pin(pin_name, $2, 1); }
|
/* empty */ { current_prog->pinno[pin_name] = 0; }
;
pin_list:
num_list { assign_pin_list(0); }
pin_number:
pin_number_non_empty
|
TKN_TILDE TKN_NUMBER { assign_pin(pin_name, $2, 1); }
/* empty */ { pin_clear_all(&(current_prog->pin[pin_name])); }
;
pin_list_element:
pin_number_non_empty
|
TKN_TILDE TKN_LEFT_PAREN num_list TKN_RIGHT_PAREN { assign_pin_list(1); }
;
pin_list_non_empty:
pin_list_element
|
/* empty */ {
current_prog->pinno[pin_name] = 0;
}
pin_list_non_empty TKN_COMMA pin_list_element
;
pin_list:
pin_list_non_empty
|
/* empty */ { pin_clear_all(&(current_prog->pin[pin_name])); }
;
prog_parm_pins:
@ -1353,10 +1366,8 @@ static int assign_pin(int pinno, TOKEN * v, int invert)
progname, lineno, infile, PIN_MIN, PIN_MAX);
exit(1);
}
if (invert)
value |= PIN_INVERSE;
current_prog->pinno[pinno] = value;
pin_set_value(&(current_prog->pin[pinno]), value, invert);
return 0;
}
@ -1370,9 +1381,15 @@ static int assign_pin_list(int invert)
while (lsize(number_list)) {
t = lrmv_n(number_list, 1);
pin = t->value.number;
current_prog->pinno[pin_name] |= (1 << pin);
if (invert)
current_prog->pinno[pin_name] |= PIN_INVERSE;
if ((pin < PIN_MIN) || (pin > PIN_MAX)) {
fprintf(stderr,
"%s: error at line %d of %s: pin must be in the "
"range %d-%d\n",
progname, lineno, infile, PIN_MIN, PIN_MAX);
exit(1);
/* TODO clear list and free tokens if no exit is done */
}
pin_set_value(&(current_prog->pin[pin_name]), pin, invert);
free_token(t);
}

View File

@ -25,10 +25,10 @@
/* 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
miso = 1; # RxD / D1
sck = 0; # RTS / D0
mosi = 2; # TxD / D2
reset = 4; # DTR / D4
*/
/*
@ -105,10 +105,9 @@ typedef dispatch_semaphore_t sem_t;
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;
static unsigned char ft245r_out;
static unsigned char ft245r_in;
static unsigned char saved_signature[3];
#define BUFSIZE 0x2000
@ -149,22 +148,6 @@ static void *reader (void *arg) {
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;
@ -235,7 +218,6 @@ static int ft245r_chip_erase(PROGRAMMER * pgm, AVRPART * p) {
return 0;
}
static unsigned char saved_signature[3];
static void ft245r_set_bitclock(PROGRAMMER * pgm) {
int r;
@ -265,8 +247,19 @@ static void ft245r_set_bitclock(PROGRAMMER * pgm) {
static int set_reset(PROGRAMMER * pgm, int val) {
unsigned char buf[1];
buf[0] = 0;
if (val) buf[0] |= ft245r_reset;
ft245r_out = SET_BITS_0(ft245r_out,pgm,PIN_AVR_RESET,val);
buf[0] = ft245r_out;
ft245r_send (pgm, buf, 1);
ft245r_recv (pgm, buf, 1);
return 0;
}
static int set_buff(PROGRAMMER * pgm, int val) {
unsigned char buf[1];
ft245r_out = SET_BITS_0(ft245r_out,pgm,PPI_AVR_BUFF,val);
buf[0] = ft245r_out;
ft245r_send (pgm, buf, 1);
ft245r_recv (pgm, buf, 1);
@ -335,55 +328,65 @@ static int ft245r_read_sig_bytes(PROGRAMMER * pgm, AVRPART * p, AVRMEM * m) {
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);\
}\
static int ft245r_check_pins(PROGRAMMER * pgm){
static const int pinlist[] = {PIN_AVR_SCK,PIN_AVR_MOSI,PIN_AVR_MISO,PIN_AVR_RESET,PPI_AVR_BUFF};
static const pinmask_t valid_pins[PIN_FIELD_SIZE] = { 0x000000ff }; // only lower 8 pins are allowed
pinmask_t already_used[PIN_FIELD_SIZE] = {0};
int i,j;
for( i=0; i<sizeof(pinlist)/sizeof(pinlist[0]); i++){
for( j=0; j<PIN_FIELD_SIZE; j++){
// check if it does not use any non valid pins
if(pgm->pin[pinlist[i]].mask[j] & ~valid_pins[j]){
fprintf(stderr,
"%s: at least one pin is not a valid pin number\n",
progname);
exit(1);
}
// check if it does not use same pins as other function
if(pgm->pin[pinlist[i]].mask[j] & already_used[j]){
fprintf(stderr,
"%s: at least one pin is set for multiple functions.\n",
progname);
exit(1);
}
already_used[j] |= pgm->pin[pinlist[i]].mask[j];
}
}
return 0;
}
/*
* 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;
set_buff(pgm,0);
}
static void ft245r_enable(PROGRAMMER * pgm) {
/* Do nothing. */
return;
set_buff(pgm,1);
}
static inline int set_data(unsigned char *buf, unsigned char data) {
static inline int set_data(PROGRAMMER * pgm, 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;
ft245r_out = SET_BITS_0(ft245r_out,pgm,PIN_AVR_MOSI,data & bit);
ft245r_out = SET_BITS_0(ft245r_out,pgm,PIN_AVR_SCK,0);
buf[buf_pos] = ft245r_out;
buf_pos++;
buf[buf_pos] = 0;
if (data & bit) buf[buf_pos] |= ft245r_mosi;
buf[buf_pos] |= ft245r_sck;
ft245r_out = SET_BITS_0(ft245r_out,pgm,PIN_AVR_SCK,1);
buf[buf_pos] = ft245r_out;
buf_pos++;
bit >>= 1;
@ -391,7 +394,7 @@ static inline int set_data(unsigned char *buf, unsigned char data) {
return buf_pos;
}
static inline unsigned char extract_data(unsigned char *buf, int offset) {
static inline unsigned char extract_data(PROGRAMMER * pgm, unsigned char *buf, int offset) {
int j;
int buf_pos = 1;
unsigned char bit = 0x80;
@ -399,7 +402,7 @@ static inline unsigned char extract_data(unsigned char *buf, int offset) {
buf += offset * (8 * FT245R_CYCLES);
for (j=0; j<8; j++) {
if (buf[buf_pos] & ft245r_miso) {
if (GET_BITS_0(buf[buf_pos],pgm,PIN_AVR_MISO)) {
r |= bit;
}
buf_pos += FT245R_CYCLES;
@ -409,7 +412,7 @@ static inline unsigned char extract_data(unsigned char *buf, int offset) {
}
/* to check data */
static inline unsigned char extract_data_out(unsigned char *buf, int offset) {
static inline unsigned char extract_data_out(PROGRAMMER * pgm, unsigned char *buf, int offset) {
int j;
int buf_pos = 1;
unsigned char bit = 0x80;
@ -417,7 +420,7 @@ static inline unsigned char extract_data_out(unsigned char *buf, int offset) {
buf += offset * (8 * FT245R_CYCLES);
for (j=0; j<8; j++) {
if (buf[buf_pos] & ft245r_mosi) {
if (GET_BITS_0(buf[buf_pos],pgm,PIN_AVR_MOSI)) {
r |= bit;
}
buf_pos += FT245R_CYCLES;
@ -438,17 +441,17 @@ static int ft245r_cmd(PROGRAMMER * pgm, unsigned char cmd[4],
buf_pos = 0;
for (i=0; i<4; i++) {
buf_pos += set_data(buf+buf_pos, cmd[i]);
buf_pos += set_data(pgm, 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);
res[0] = extract_data(pgm, buf, 0);
res[1] = extract_data(pgm, buf, 1);
res[2] = extract_data(pgm, buf, 2);
res[3] = extract_data(pgm, buf, 3);
return 0;
}
@ -457,6 +460,9 @@ static int ft245r_cmd(PROGRAMMER * pgm, unsigned char cmd[4],
static int ft245r_open(PROGRAMMER * pgm, char * port) {
int rv;
int devnum = -1;
ft245r_check_pins(pgm);
strcpy(pgm->port, port);
if (strcmp(port,DEFAULT_USB) != 0) {
@ -502,19 +508,29 @@ static int ft245r_open(PROGRAMMER * pgm, char * port) {
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_ddr =
pgm->pin[PIN_AVR_SCK].mask[0]
| pgm->pin[PIN_AVR_MOSI].mask[0]
| pgm->pin[PIN_AVR_RESET].mask[0]
| pgm->pin[PPI_AVR_BUFF].mask[0]
| pgm->pin[PPI_AVR_VCC].mask[0]
| pgm->pin[PIN_LED_ERR].mask[0]
| pgm->pin[PIN_LED_RDY].mask[0]
| pgm->pin[PIN_LED_PGM].mask[0]
| pgm->pin[PIN_LED_VFY].mask[0];
/* set initial values for outputs, no reset everything else is off */
ft245r_out = 0;
ft245r_out = SET_BITS_0(ft245r_out,pgm,PIN_AVR_RESET,1);
ft245r_out = SET_BITS_0(ft245r_out,pgm,PIN_AVR_SCK,0);
ft245r_out = SET_BITS_0(ft245r_out,pgm,PIN_AVR_MOSI,0);
ft245r_out = SET_BITS_0(ft245r_out,pgm,PPI_AVR_BUFF,0);
ft245r_out = SET_BITS_0(ft245r_out,pgm,PPI_AVR_VCC,0);
ft245r_out = SET_BITS_0(ft245r_out,pgm,PIN_LED_ERR,0);
ft245r_out = SET_BITS_0(ft245r_out,pgm,PIN_LED_RDY,0);
ft245r_out = SET_BITS_0(ft245r_out,pgm,PIN_LED_PGM,0);
ft245r_out = SET_BITS_0(ft245r_out,pgm,PIN_LED_VFY,0);
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
@ -532,6 +548,9 @@ static int ft245r_open(PROGRAMMER * pgm, char * port) {
*/
ft245r_drain (pgm, 0);
ft245r_send (pgm, &ft245r_out, 1);
ft245r_recv (pgm, &ft245r_in, 1);
return 0;
}
@ -548,8 +567,8 @@ static void ft245r_close(PROGRAMMER * pgm) {
}
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);
fprintf(stderr, "%sPin assignment : 0..7 = DBUS0..7\n",p);/* , 8..11 = GPIO0..3\n",p);*/
pgm_display_generic_mask(pgm, p, SHOW_AVR_PINS|1<<PPI_AVR_BUFF);
}
static int ft245r_paged_write_gen(PROGRAMMER * pgm, AVRPART * p, AVRMEM * m,
@ -636,7 +655,7 @@ static int do_request(PROGRAMMER * pgm, AVRMEM *m) {
ft245r_recv(pgm, buf, bytes);
for (j=0; j<n; j++) {
m->buf[addr++] = extract_data(buf , (j * 4 + 3));
m->buf[addr++] = extract_data(pgm, buf , (j * 4 + 3));
}
return 1;
}
@ -653,10 +672,10 @@ static int ft245r_paged_write_flash(PROGRAMMER * pgm, AVRPART * p, AVRMEM * m,
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]);
buf_pos += set_data(pgm, buf+buf_pos, (addr & 1)?0x48:0x40 );
buf_pos += set_data(pgm, buf+buf_pos, (addr >> 9) & 0xff );
buf_pos += set_data(pgm, buf+buf_pos, (addr >> 1) & 0xff );
buf_pos += set_data(pgm, buf+buf_pos, m->buf[addr]);
addr ++;
i++;
if ( (m->paged) &&
@ -676,19 +695,20 @@ static int ft245r_paged_write_flash(PROGRAMMER * pgm, AVRPART * p, AVRMEM * m,
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(pgm, buf+buf_pos, cmd[0]);
buf_pos += set_data(pgm, buf+buf_pos, cmd[1]);
buf_pos += set_data(pgm, buf+buf_pos, cmd[2]);
buf_pos += set_data(pgm, 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);
buf_pos += set_data(pgm, buf+buf_pos, 0x4C); /* Issue Page Write */
buf_pos += set_data(pgm, buf+buf_pos,(addr_wk >> 9) & 0xff);
buf_pos += set_data(pgm, buf+buf_pos,(addr_wk >> 1) & 0xff);
buf_pos += set_data(pgm, buf+buf_pos, 0);
}
#endif
if (i >= n_bytes) {
buf[buf_pos++] = 0; // sck down
ft245r_out = SET_BITS_0(ft245r_out,pgm,PIN_AVR_SCK,0); // sck down
buf[buf_pos++] = ft245r_out;
}
ft245r_send(pgm, buf, buf_pos);
put_request(addr_save, buf_pos, 0);
@ -696,8 +716,8 @@ static int ft245r_paged_write_flash(PROGRAMMER * pgm, AVRPART * p, AVRMEM * m,
#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) ),
extract_data_out(pgm, buf , (0*4 + 3) ),
extract_data_out(pgm, buf , (1*4 + 3) ),
do_page_write);
#endif
req_count++;
@ -768,15 +788,16 @@ static int ft245r_paged_load_flash(PROGRAMMER * pgm, AVRPART * p, AVRMEM * m,
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);
buf_pos += set_data(pgm, buf+buf_pos, (addr & 1)?0x28:0x20 );
buf_pos += set_data(pgm, buf+buf_pos, (addr >> 9) & 0xff );
buf_pos += set_data(pgm, buf+buf_pos, (addr >> 1) & 0xff );
buf_pos += set_data(pgm, buf+buf_pos, 0);
addr ++;
i++;
}
if (i >= n_bytes) {
buf[buf_pos++] = 0; // sck down
ft245r_out = SET_BITS_0(ft245r_out,pgm,PIN_AVR_SCK,0); // sck down
buf[buf_pos++] = ft245r_out;
}
n = j;
ft245r_send(pgm, buf, buf_pos);

View File

@ -216,7 +216,8 @@ static int linuxgpio_highpulsepin(PROGRAMMER * pgm, int pin)
static void linuxgpio_display(PROGRAMMER *pgm, const char *p)
{
/* MAYBE */
fprintf(stderr, "%sPin assignment : /sys/class/gpio/gpio{n}\n",p);
pgm_display_generic_mask(pgm, p, SHOW_AVR_PINS);
}
static void linuxgpio_enable(PROGRAMMER *pgm)
@ -311,6 +312,8 @@ void linuxgpio_initpgm(PROGRAMMER *pgm)
{
strcpy(pgm->type, "linuxgpio");
pgm_fill_old_pins(pgm); // TODO to be removed if old pin data no longer needed
pgm->rdy_led = bitbang_rdy_led;
pgm->err_led = bitbang_err_led;
pgm->pgm_led = bitbang_pgm_led;

View File

@ -921,6 +921,12 @@ int main(int argc, char * argv [])
pgm->ispdelay = ispdelay;
}
if (verbose) {
avr_display(stderr, p, progbuf, verbose);
fprintf(stderr, "\n");
programmer_display(pgm, progbuf);
}
rc = pgm->open(pgm, port);
if (rc < 0) {
exitrc = 1;
@ -937,7 +943,7 @@ int main(int argc, char * argv [])
if (pgm->perform_osccal == 0) {
fprintf(stderr,
"%s: programmer does not support RC oscillator calibration\n",
progname);
progname);
exitrc = 1;
} else {
fprintf(stderr, "%s: performing RC oscillator calibration\n", progname);
@ -951,12 +957,6 @@ int main(int argc, char * argv [])
goto main_exit;
}
if (verbose) {
avr_display(stderr, p, progbuf, verbose);
fprintf(stderr, "\n");
programmer_display(pgm, progbuf);
}
if (quell_progress < 2) {
fprintf(stderr, "\n");
}

View File

@ -359,6 +359,8 @@ void par_initpgm(PROGRAMMER * pgm)
{
strcpy(pgm->type, "PPI");
pgm_fill_old_pins(pgm); // TODO to be removed if old pin data no longer needed
pgm->exit_vcc = EXIT_VCC_UNSPEC;
pgm->exit_reset = EXIT_RESET_UNSPEC;
pgm->exit_datahigh = EXIT_DATAHIGH_UNSPEC;

View File

@ -211,65 +211,57 @@ void programmer_display(PROGRAMMER * pgm, const char * p)
pgm->display(pgm, p);
}
static char * pins_to_str(unsigned int pmask)
static char * pins_to_str(const struct pindef_t * const pindef)
{
static char buf[64];
static char buf[(PIN_MAX+1)*5]; // should be enough for PIN_MAX=255
char *p = buf;
int n;
int pin;
char b2[8];
const char * fmt;
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);
buf[0] = 0;
for (pin = PIN_MIN; pin <= PIN_MAX; pin++) {
int index = pin/PIN_FIELD_ELEMENT_SIZE;
int bit = pin%PIN_FIELD_ELEMENT_SIZE;
if (pindef->mask[index] & (1 << bit)) {
if (pindef->inverse[index] & (1 << bit)) {
fmt = (buf[0]==0)?"~%d":",~%d";
} else {
fmt = (buf[0]==0)?" %d":",%d";
}
n = sprintf(p, fmt, pin);
p += n;
}
}
return buf;
}
static char * pin_to_str(unsigned int pin)
{
static char buf[12];
if ((pin & PIN_MASK) == 0)
if (buf[0] == 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]));
fprintf(stderr, "%s VCC = %s\n", p, pins_to_str(&pgm->pin[PPI_AVR_VCC]));
if(show & (1<<PPI_AVR_BUFF))
fprintf(stderr, "%s BUFF = %s\n", p, pins_to_str(pgm->pinno[PPI_AVR_BUFF]));
fprintf(stderr, "%s BUFF = %s\n", p, pins_to_str(&pgm->pin[PPI_AVR_BUFF]));
if(show & (1<<PIN_AVR_RESET))
fprintf(stderr, "%s RESET = %s\n", p, pin_to_str(pgm->pinno[PIN_AVR_RESET]));
fprintf(stderr, "%s RESET = %s\n", p, pins_to_str(&pgm->pin[PIN_AVR_RESET]));
if(show & (1<<PIN_AVR_SCK))
fprintf(stderr, "%s SCK = %s\n", p, pin_to_str(pgm->pinno[PIN_AVR_SCK]));
fprintf(stderr, "%s SCK = %s\n", p, pins_to_str(&pgm->pin[PIN_AVR_SCK]));
if(show & (1<<PIN_AVR_MOSI))
fprintf(stderr, "%s MOSI = %s\n", p, pin_to_str(pgm->pinno[PIN_AVR_MOSI]));
fprintf(stderr, "%s MOSI = %s\n", p, pins_to_str(&pgm->pin[PIN_AVR_MOSI]));
if(show & (1<<PIN_AVR_MISO))
fprintf(stderr, "%s MISO = %s\n", p, pin_to_str(pgm->pinno[PIN_AVR_MISO]));
fprintf(stderr, "%s MISO = %s\n", p, pins_to_str(&pgm->pin[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]));
fprintf(stderr, "%s ERR LED = %s\n", p, pins_to_str(&pgm->pin[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]));
fprintf(stderr, "%s RDY LED = %s\n", p, pins_to_str(&pgm->pin[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]));
fprintf(stderr, "%s PGM LED = %s\n", p, pins_to_str(&pgm->pin[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]));
fprintf(stderr, "%s VFY LED = %s\n", p, pins_to_str(&pgm->pin[PIN_LED_VFY]));
}
void pgm_display_generic(PROGRAMMER * pgm, const char * p)

View File

@ -68,6 +68,7 @@ typedef struct programmer_t {
char port[PGM_PORTLEN];
void (*initpgm)(struct programmer_t * pgm);
unsigned int pinno[N_PINS];
struct pindef_t pin[N_PINS];
exit_vcc_t exit_vcc;
exit_reset_t exit_reset;
exit_datahigh_t exit_datahigh;

126
avrdude/pindefs.c Normal file
View File

@ -0,0 +1,126 @@
/*
* avrdude - A Downloader/Uploader for AVR device programmers
* Copyright (C) 2000-2004 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, see <http://www.gnu.org/licenses/>.
*/
/* $Id: pindefs.h 1132 2013-01-09 19:23:30Z rliebscher $ */
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#include "pindefs.h"
#include "pgm.h"
/**
* Adds a pin in the pin definition as normal or inverse pin.
*
* @param[out] pindef pin definition to update
* @param[in] pin number of pin [0..PIN_MAX]
* @param[in] inverse inverse (true) or normal (false) pin
*/
void pin_set_value(struct pindef_t * const pindef, const int pin, const bool inverse){
pindef->mask[pin/PIN_FIELD_ELEMENT_SIZE] |= 1 << (pin % PIN_FIELD_ELEMENT_SIZE);
if (inverse)
pindef->inverse[pin/PIN_FIELD_ELEMENT_SIZE] |= (1 << (pin % PIN_FIELD_ELEMENT_SIZE));
else
pindef->inverse[pin/PIN_FIELD_ELEMENT_SIZE] &= ~(1 << (pin % PIN_FIELD_ELEMENT_SIZE));
}
/**
* Clear all defined pins in pindef.
*
* @param[out] pindef pin definition to clear
*/
void pin_clear_all(struct pindef_t * const pindef){
memset(pindef,0,sizeof(struct pindef_t));
}
/**
* Convert new pin definition to old pin number
*
* @param[in] pindef new pin definition structure
* @param[out] pinno old pin definition integer
*/
static void pin_fill_old_pinno(const struct pindef_t * const pindef, unsigned int * const pinno){
bool found = false;
int i;
for (i=0;i<PIN_MAX;i++){
if (pindef->mask[i/PIN_FIELD_ELEMENT_SIZE] & (1 << (i % PIN_FIELD_ELEMENT_SIZE))){
if(found){
fprintf(stderr,"Multiple pins found\n"); //TODO
exit(1);
}
found = true;
*pinno = i;
if (pindef->inverse[i/PIN_FIELD_ELEMENT_SIZE] & (1 << (i % PIN_FIELD_ELEMENT_SIZE))){
*pinno |= PIN_INVERSE;
}
}
}
}
/**
* Convert new pin definition to old pinlist, does not support mixed inverted/non-inverted pin
*
* @param[in] pindef new pin definition structure
* @param[out] pinno old pin definition integer
*/
static void pin_fill_old_pinlist(const struct pindef_t * const pindef, unsigned int * const pinno){
int i;
for (i=0;i<PIN_FIELD_SIZE;i++){
if(i == 0) {
if ((pindef->mask[i] & ~PIN_MASK) != 0){
fprintf(stderr,"Pins of higher index than max field size for old pinno found\n");
exit(1);
}
if (pindef->mask[i] == pindef->inverse[i]) { /* all set bits in mask are set in inverse */
*pinno = pindef->mask[i];
*pinno |= PIN_INVERSE;
} else if (pindef->mask[i] == ((~pindef->inverse[i]) & pindef->mask[i])) { /* all set bits in mask are cleared in inverse */
*pinno = pindef->mask[i];
} else {
fprintf(stderr,"pins have different polarity set\n");
exit(1);
}
} else if (pindef->mask[i] != 0){
fprintf(stderr,"Pins have higher number than fit in old format\n");
exit(1);
}
}
}
/**
* Convert for given programmer new pin definitions to old pin definitions.
*
* @param[inout] pgm programmer whose pins shall be converted.
*/
void pgm_fill_old_pins(struct programmer_t * const pgm) {
pin_fill_old_pinlist(&(pgm->pin[PPI_AVR_VCC]), &(pgm->pinno[PPI_AVR_VCC]));
pin_fill_old_pinlist(&(pgm->pin[PPI_AVR_BUFF]), &(pgm->pinno[PPI_AVR_BUFF]));
pin_fill_old_pinno( &(pgm->pin[PIN_AVR_RESET]),&(pgm->pinno[PIN_AVR_RESET]));
pin_fill_old_pinno( &(pgm->pin[PIN_AVR_SCK]), &(pgm->pinno[PIN_AVR_SCK]));
pin_fill_old_pinno( &(pgm->pin[PIN_AVR_MOSI]), &(pgm->pinno[PIN_AVR_MOSI]));
pin_fill_old_pinno( &(pgm->pin[PIN_AVR_MISO]), &(pgm->pinno[PIN_AVR_MISO]));
pin_fill_old_pinno( &(pgm->pin[PIN_LED_ERR]), &(pgm->pinno[PIN_LED_ERR]));
pin_fill_old_pinno( &(pgm->pin[PIN_LED_RDY]), &(pgm->pinno[PIN_LED_RDY]));
pin_fill_old_pinno( &(pgm->pin[PIN_LED_PGM]), &(pgm->pinno[PIN_LED_PGM]));
pin_fill_old_pinno( &(pgm->pin[PIN_LED_VFY]), &(pgm->pinno[PIN_LED_VFY]));
}

View File

@ -23,6 +23,17 @@
#include <limits.h>
/* lets try to select at least 32 bits */
#ifdef HAVE_STDINT_H
#include <stdint.h>
typedef uint32_t pinmask_t;
#else
typedef unsigned long pinmask_t;
#endif
#include <stdbool.h>
enum {
PPI_AVR_VCC=1,
PPI_AVR_BUFF,
@ -36,9 +47,75 @@ enum {
PIN_LED_VFY,
N_PINS
};
#define PIN_MASK (UINT_MAX>>1)
#define PIN_INVERSE (~(PIN_MASK)) /* flag for inverted pin in serbb */
#define PIN_MIN 1 /* smallest allowed pin number */
#define PIN_MIN 0 /* smallest allowed pin number */
#define PIN_MAX 31 /* largest allowed pin number */
#ifdef HAVE_LINUX_GPIO
/* Embedded systems might have a lot more gpio than only 0-31 */
#undef PIN_MAX
#define PIN_MAX 255 /* largest allowed pin number */
#endif
/** Number of pins in each element of the bitfield */
#define PIN_FIELD_ELEMENT_SIZE (sizeof(pinmask_t) * 8)
/** Numer of elements to store the complete bitfield of all pins */
#define PIN_FIELD_SIZE ((PIN_MAX + PIN_FIELD_ELEMENT_SIZE)/PIN_FIELD_ELEMENT_SIZE)
/**
* This sets the corresponding bits to 1 or 0, the inverse mask is used to invert the value in necessary.
* It uses only the lowest element (index=0) of the bitfield, which should be enough for most
* programmers.
*
* @param[in] x input value
* @param[in] pgm the programmer whose pin definitions to use
* @param[in] pinname the logical name of the pin (PIN_AVR_*, ...)
* @param[in] level the logical level (level != 0 => 1, level == 0 => 0),
* if the pin is defined as inverted the resulting bit is also inverted
* @returns the input value with the relevant bits modified
*/
#define SET_BITS_0(x,pgm,pinname,level) (((x) & ~(pgm)->pin[pinname].mask[0]) \
| (\
(pgm)->pin[pinname].mask[0] & ( \
(level) \
?~((pgm)->pin[pinname].inverse[0]) \
: ((pgm)->pin[pinname].inverse[0]) \
) \
) \
)
/**
* Check if the corresponding bit is set (returns != 0) or cleared.
* The inverse mask is used, to invert the relevant bits.
* If the pin definition contains multiple pins, then a single set pin leads to return value != 0.
* Then you have to check the relevant bits of the returned value, if you need more information.
* It uses only the lowest element (index=0) of the bitfield, which should be enough for most
* programmers.
*
* @param[in] x input value
* @param[in] pgm the programmer whose pin definitions to use
* @param[in] pinname the logical name of the pin (PIN_AVR_*, ...)
* @returns the input value with only the relevant bits (which are already inverted,
* so you get always the logical level)
*/
#define GET_BITS_0(x,pgm,pinname) (((x) ^ (pgm)->pin[pinname].inverse[0]) & (pgm)->pin[pinname].mask[0])
/**
* Data structure to hold used pins by logical function (PIN_AVR_*, ...)
*/
struct pindef_t {
pinmask_t mask[PIN_FIELD_SIZE]; ///< bitfield of used pins
pinmask_t inverse[PIN_FIELD_SIZE]; ///< bitfield of inverse/normal usage of used pins
};
void pin_set_value(struct pindef_t * const pindef, const int pin, const bool inverse);
void pin_clear_all(struct pindef_t * const pindef);
struct programmer_t; /* forward declaration */
void pgm_fill_old_pins(struct programmer_t * const pgm);
#endif

View File

@ -289,6 +289,8 @@ void serbb_initpgm(PROGRAMMER *pgm)
{
strcpy(pgm->type, "SERBB");
pgm_fill_old_pins(pgm); // TODO to be removed if old pin data no longer needed
pgm->rdy_led = bitbang_rdy_led;
pgm->err_led = bitbang_err_led;
pgm->pgm_led = bitbang_pgm_led;

View File

@ -350,6 +350,8 @@ void serbb_initpgm(PROGRAMMER *pgm)
{
strcpy(pgm->type, "SERBB");
pgm_fill_old_pins(pgm); // TODO to be removed if old pin data no longer needed
pgm->rdy_led = bitbang_rdy_led;
pgm->err_led = bitbang_err_led;
pgm->pgm_led = bitbang_pgm_led;