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/avrdude@1160 81a1dc3b-b13d-400b-aceb-764788c761c2
This commit is contained in:
rliebscher 2013-05-03 22:35:00 +00:00
parent a2ab9c6039
commit 22158cd03a
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> 2013-05-03 Hannes Weisbach <hannes_weisbach@gmx.net>
* avrftdi_private.h: Remove update forward declaration from avrftdi_print to * 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 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 cannot be issued due to the synchronous part of libftdi. This should fix
#38831 and #38659. #38831 and #38659.
2013-04-25 Joerg Wunsch <j.gnu@uriah.heep.sax.de> 2013-04-25 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
* configure.ac(AC_CONFIG_HEADERS): Replace the old AM_CONFIG_HEADER * configure.ac(AC_CONFIG_HEADERS): Replace the old AM_CONFIG_HEADER

View File

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

View File

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

View File

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

View File

@ -1283,6 +1283,8 @@ void buspirate_bb_initpgm(struct programmer_t *pgm)
{ {
strcpy(pgm->type, "BusPirate_BB"); 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; pgm->display = buspirate_dummy_6;
/* BusPirate itself related methods */ /* BusPirate itself related methods */

View File

@ -288,6 +288,8 @@ prog_def :
pgm_free(existing_prog); pgm_free(existing_prog);
} }
PUSH(programmers, current_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; 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_NUMBER { assign_pin(pin_name, $1, 0); }
| |
TKN_TILDE TKN_NUMBER { assign_pin(pin_name, $2, 1); } TKN_TILDE TKN_NUMBER { assign_pin(pin_name, $2, 1); }
|
/* empty */ { current_prog->pinno[pin_name] = 0; }
; ;
pin_list: pin_number:
num_list { assign_pin_list(0); } 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); } TKN_TILDE TKN_LEFT_PAREN num_list TKN_RIGHT_PAREN { assign_pin_list(1); }
;
pin_list_non_empty:
pin_list_element
| |
/* empty */ { pin_list_non_empty TKN_COMMA pin_list_element
current_prog->pinno[pin_name] = 0; ;
}
pin_list:
pin_list_non_empty
|
/* empty */ { pin_clear_all(&(current_prog->pin[pin_name])); }
; ;
prog_parm_pins: prog_parm_pins:
@ -1353,10 +1366,8 @@ static int assign_pin(int pinno, TOKEN * v, int invert)
progname, lineno, infile, PIN_MIN, PIN_MAX); progname, lineno, infile, PIN_MIN, PIN_MAX);
exit(1); exit(1);
} }
if (invert)
value |= PIN_INVERSE;
current_prog->pinno[pinno] = value; pin_set_value(&(current_prog->pin[pinno]), value, invert);
return 0; return 0;
} }
@ -1370,9 +1381,15 @@ static int assign_pin_list(int invert)
while (lsize(number_list)) { while (lsize(number_list)) {
t = lrmv_n(number_list, 1); t = lrmv_n(number_list, 1);
pin = t->value.number; pin = t->value.number;
current_prog->pinno[pin_name] |= (1 << pin); if ((pin < PIN_MIN) || (pin > PIN_MAX)) {
if (invert) fprintf(stderr,
current_prog->pinno[pin_name] |= PIN_INVERSE; "%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); free_token(t);
} }

215
ft245r.c
View File

@ -25,10 +25,10 @@
/* ft245r -- FT245R/FT232R Synchronous BitBangMode Programmer /* ft245r -- FT245R/FT232R Synchronous BitBangMode Programmer
default pin assign default pin assign
FT232R / FT245R FT232R / FT245R
miso = 2; # RxD / D1 miso = 1; # RxD / D1
sck = 1; # RTS / D0 sck = 0; # RTS / D0
mosi = 3; # TxD / D2 mosi = 2; # TxD / D2
reset = 5; # DTR / D4 reset = 4; # DTR / D4
*/ */
/* /*
@ -105,10 +105,9 @@ typedef dispatch_semaphore_t sem_t;
static struct ftdi_context *handle; static struct ftdi_context *handle;
static unsigned char ft245r_ddr; static unsigned char ft245r_ddr;
static unsigned char ft245r_sck; static unsigned char ft245r_out;
static unsigned char ft245r_mosi; static unsigned char ft245r_in;
static unsigned char ft245r_reset; static unsigned char saved_signature[3];
static unsigned char ft245r_miso;
#define BUFSIZE 0x2000 #define BUFSIZE 0x2000
@ -149,22 +148,6 @@ static void *reader (void *arg) {
return NULL; 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) { static int ft245r_send(PROGRAMMER * pgm, unsigned char * buf, size_t len) {
int rv; int rv;
@ -235,7 +218,6 @@ static int ft245r_chip_erase(PROGRAMMER * pgm, AVRPART * p) {
return 0; return 0;
} }
static unsigned char saved_signature[3];
static void ft245r_set_bitclock(PROGRAMMER * pgm) { static void ft245r_set_bitclock(PROGRAMMER * pgm) {
int r; int r;
@ -265,8 +247,19 @@ static void ft245r_set_bitclock(PROGRAMMER * pgm) {
static int set_reset(PROGRAMMER * pgm, int val) { static int set_reset(PROGRAMMER * pgm, int val) {
unsigned char buf[1]; unsigned char buf[1];
buf[0] = 0; ft245r_out = SET_BITS_0(ft245r_out,pgm,PIN_AVR_RESET,val);
if (val) buf[0] |= ft245r_reset; 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_send (pgm, buf, 1);
ft245r_recv (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; return 3;
} }
#define check_pin(s) {\ static int ft245r_check_pins(PROGRAMMER * pgm){
if ((pgm->pinno[s] & PIN_MASK) == 0) {\ static const int pinlist[] = {PIN_AVR_SCK,PIN_AVR_MOSI,PIN_AVR_MISO,PIN_AVR_RESET,PPI_AVR_BUFF};
fprintf(stderr,\ static const pinmask_t valid_pins[PIN_FIELD_SIZE] = { 0x000000ff }; // only lower 8 pins are allowed
"%s: pin %s is not set\n",\ pinmask_t already_used[PIN_FIELD_SIZE] = {0};
progname,#s);\ int i,j;
exit(1);\
}\ for( i=0; i<sizeof(pinlist)/sizeof(pinlist[0]); i++){
if ((pgm->pinno[s] & PIN_INVERSE) != 0) {\ for( j=0; j<PIN_FIELD_SIZE; j++){
fprintf(stderr,\ // check if it does not use any non valid pins
"%s: pin %s inverse is not supported.\n",\ if(pgm->pin[pinlist[i]].mask[j] & ~valid_pins[j]){
progname,#s);\ fprintf(stderr,
exit(1);\ "%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 * initialize the AVR device and prepare it to accept commands
*/ */
static int ft245r_initialize(PROGRAMMER * pgm, AVRPART * p) { 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); return ft245r_program_enable(pgm, p);
} }
static void ft245r_disable(PROGRAMMER * pgm) { static void ft245r_disable(PROGRAMMER * pgm) {
return; set_buff(pgm,0);
} }
static void ft245r_enable(PROGRAMMER * pgm) { static void ft245r_enable(PROGRAMMER * pgm) {
/* Do nothing. */ set_buff(pgm,1);
return;
} }
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 j;
int buf_pos = 0; int buf_pos = 0;
unsigned char bit = 0x80; unsigned char bit = 0x80;
for (j=0; j<8; j++) { for (j=0; j<8; j++) {
buf[buf_pos] = 0; ft245r_out = SET_BITS_0(ft245r_out,pgm,PIN_AVR_MOSI,data & bit);
if (data & bit) buf[buf_pos] |= ft245r_mosi;
ft245r_out = SET_BITS_0(ft245r_out,pgm,PIN_AVR_SCK,0);
buf[buf_pos] = ft245r_out;
buf_pos++; buf_pos++;
buf[buf_pos] = 0; ft245r_out = SET_BITS_0(ft245r_out,pgm,PIN_AVR_SCK,1);
if (data & bit) buf[buf_pos] |= ft245r_mosi; buf[buf_pos] = ft245r_out;
buf[buf_pos] |= ft245r_sck;
buf_pos++; buf_pos++;
bit >>= 1; bit >>= 1;
@ -391,7 +394,7 @@ static inline int set_data(unsigned char *buf, unsigned char data) {
return buf_pos; 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 j;
int buf_pos = 1; int buf_pos = 1;
unsigned char bit = 0x80; unsigned char bit = 0x80;
@ -399,7 +402,7 @@ static inline unsigned char extract_data(unsigned char *buf, int offset) {
buf += offset * (8 * FT245R_CYCLES); buf += offset * (8 * FT245R_CYCLES);
for (j=0; j<8; j++) { 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; r |= bit;
} }
buf_pos += FT245R_CYCLES; buf_pos += FT245R_CYCLES;
@ -409,7 +412,7 @@ static inline unsigned char extract_data(unsigned char *buf, int offset) {
} }
/* to check data */ /* 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 j;
int buf_pos = 1; int buf_pos = 1;
unsigned char bit = 0x80; 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); buf += offset * (8 * FT245R_CYCLES);
for (j=0; j<8; j++) { 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; r |= bit;
} }
buf_pos += FT245R_CYCLES; buf_pos += FT245R_CYCLES;
@ -438,17 +441,17 @@ static int ft245r_cmd(PROGRAMMER * pgm, unsigned char cmd[4],
buf_pos = 0; buf_pos = 0;
for (i=0; i<4; i++) { 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[buf_pos] = 0;
buf_pos++; buf_pos++;
ft245r_send (pgm, buf, buf_pos); ft245r_send (pgm, buf, buf_pos);
ft245r_recv (pgm, buf, buf_pos); ft245r_recv (pgm, buf, buf_pos);
res[0] = extract_data(buf, 0); res[0] = extract_data(pgm, buf, 0);
res[1] = extract_data(buf, 1); res[1] = extract_data(pgm, buf, 1);
res[2] = extract_data(buf, 2); res[2] = extract_data(pgm, buf, 2);
res[3] = extract_data(buf, 3); res[3] = extract_data(pgm, buf, 3);
return 0; return 0;
} }
@ -457,6 +460,9 @@ static int ft245r_cmd(PROGRAMMER * pgm, unsigned char cmd[4],
static int ft245r_open(PROGRAMMER * pgm, char * port) { static int ft245r_open(PROGRAMMER * pgm, char * port) {
int rv; int rv;
int devnum = -1; int devnum = -1;
ft245r_check_pins(pgm);
strcpy(pgm->port, port); strcpy(pgm->port, port);
if (strcmp(port,DEFAULT_USB) != 0) { if (strcmp(port,DEFAULT_USB) != 0) {
@ -502,19 +508,29 @@ static int ft245r_open(PROGRAMMER * pgm, char * port) {
sem_init (&buf_space, 0, BUFSIZE); sem_init (&buf_space, 0, BUFSIZE);
pthread_create (&readerthread, NULL, reader, handle); pthread_create (&readerthread, NULL, reader, handle);
ft245r_ddr = 0; ft245r_ddr =
setmybit(&ft245r_ddr, pgm->pinno[PIN_AVR_SCK], 1); pgm->pin[PIN_AVR_SCK].mask[0]
setmybit(&ft245r_ddr, pgm->pinno[PIN_AVR_MOSI], 1); | pgm->pin[PIN_AVR_MOSI].mask[0]
setmybit(&ft245r_ddr, pgm->pinno[PIN_AVR_RESET], 1); | 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 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_drain (pgm, 0);
ft245r_send (pgm, &ft245r_out, 1);
ft245r_recv (pgm, &ft245r_in, 1);
return 0; return 0;
} }
@ -548,8 +567,8 @@ static void ft245r_close(PROGRAMMER * pgm) {
} }
static void ft245r_display(PROGRAMMER * pgm, const char * p) { static void ft245r_display(PROGRAMMER * pgm, const char * p) {
fprintf(stderr, "%sPin assignment : 1..8 = DBUS0..7, 9..12 = GPIO0..3\n",p); 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); 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, 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); ft245r_recv(pgm, buf, bytes);
for (j=0; j<n; j++) { 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; return 1;
} }
@ -653,10 +672,10 @@ static int ft245r_paged_write_flash(PROGRAMMER * pgm, AVRPART * p, AVRMEM * m,
buf_pos = 0; buf_pos = 0;
do_page_write = 0; do_page_write = 0;
for (j=0; j< FT245R_FRAGMENT_SIZE/8/FT245R_CYCLES/4; j++) { 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(pgm, buf+buf_pos, (addr & 1)?0x48:0x40 );
buf_pos += set_data(buf+buf_pos, (addr >> 9) & 0xff ); buf_pos += set_data(pgm, buf+buf_pos, (addr >> 9) & 0xff );
buf_pos += set_data(buf+buf_pos, (addr >> 1) & 0xff ); buf_pos += set_data(pgm, buf+buf_pos, (addr >> 1) & 0xff );
buf_pos += set_data(buf+buf_pos, m->buf[addr]); buf_pos += set_data(pgm, buf+buf_pos, m->buf[addr]);
addr ++; addr ++;
i++; i++;
if ( (m->paged) && if ( (m->paged) &&
@ -676,19 +695,20 @@ static int ft245r_paged_write_flash(PROGRAMMER * pgm, AVRPART * p, AVRMEM * m,
memset(cmd, 0, 4); memset(cmd, 0, 4);
avr_set_bits(lext, cmd); avr_set_bits(lext, cmd);
avr_set_addr(lext, cmd, addr_wk/2); avr_set_addr(lext, cmd, addr_wk/2);
buf_pos += set_data(buf+buf_pos, cmd[0]); buf_pos += set_data(pgm, buf+buf_pos, cmd[0]);
buf_pos += set_data(buf+buf_pos, cmd[1]); buf_pos += set_data(pgm, buf+buf_pos, cmd[1]);
buf_pos += set_data(buf+buf_pos, cmd[2]); buf_pos += set_data(pgm, buf+buf_pos, cmd[2]);
buf_pos += set_data(buf+buf_pos, cmd[3]); 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(pgm, buf+buf_pos, 0x4C); /* Issue Page Write */
buf_pos += set_data(buf+buf_pos,(addr_wk >> 9) & 0xff); buf_pos += set_data(pgm, buf+buf_pos,(addr_wk >> 9) & 0xff);
buf_pos += set_data(buf+buf_pos,(addr_wk >> 1) & 0xff); buf_pos += set_data(pgm, buf+buf_pos,(addr_wk >> 1) & 0xff);
buf_pos += set_data(buf+buf_pos, 0); buf_pos += set_data(pgm, buf+buf_pos, 0);
} }
#endif #endif
if (i >= n_bytes) { 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); ft245r_send(pgm, buf, buf_pos);
put_request(addr_save, buf_pos, 0); 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 #if 0
fprintf(stderr, "send addr 0x%04x bufsize %d [%02x %02x] page_write %d\n", fprintf(stderr, "send addr 0x%04x bufsize %d [%02x %02x] page_write %d\n",
addr_save,buf_pos, addr_save,buf_pos,
extract_data_out(buf , (0*4 + 3) ), extract_data_out(pgm, buf , (0*4 + 3) ),
extract_data_out(buf , (1*4 + 3) ), extract_data_out(pgm, buf , (1*4 + 3) ),
do_page_write); do_page_write);
#endif #endif
req_count++; req_count++;
@ -768,15 +788,16 @@ static int ft245r_paged_load_flash(PROGRAMMER * pgm, AVRPART * p, AVRMEM * m,
addr_save = addr; addr_save = addr;
for (j=0; j< FT245R_FRAGMENT_SIZE/8/FT245R_CYCLES/4; j++) { for (j=0; j< FT245R_FRAGMENT_SIZE/8/FT245R_CYCLES/4; j++) {
if (i >= n_bytes) break; if (i >= n_bytes) break;
buf_pos += set_data(buf+buf_pos, (addr & 1)?0x28:0x20 ); buf_pos += set_data(pgm, buf+buf_pos, (addr & 1)?0x28:0x20 );
buf_pos += set_data(buf+buf_pos, (addr >> 9) & 0xff ); buf_pos += set_data(pgm, buf+buf_pos, (addr >> 9) & 0xff );
buf_pos += set_data(buf+buf_pos, (addr >> 1) & 0xff ); buf_pos += set_data(pgm, buf+buf_pos, (addr >> 1) & 0xff );
buf_pos += set_data(buf+buf_pos, 0); buf_pos += set_data(pgm, buf+buf_pos, 0);
addr ++; addr ++;
i++; i++;
} }
if (i >= n_bytes) { 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; n = j;
ft245r_send(pgm, buf, buf_pos); 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) 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) static void linuxgpio_enable(PROGRAMMER *pgm)
@ -311,6 +312,8 @@ void linuxgpio_initpgm(PROGRAMMER *pgm)
{ {
strcpy(pgm->type, "linuxgpio"); 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->rdy_led = bitbang_rdy_led;
pgm->err_led = bitbang_err_led; pgm->err_led = bitbang_err_led;
pgm->pgm_led = bitbang_pgm_led; pgm->pgm_led = bitbang_pgm_led;

14
main.c
View File

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

2
par.c
View File

@ -359,6 +359,8 @@ void par_initpgm(PROGRAMMER * pgm)
{ {
strcpy(pgm->type, "PPI"); 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_vcc = EXIT_VCC_UNSPEC;
pgm->exit_reset = EXIT_RESET_UNSPEC; pgm->exit_reset = EXIT_RESET_UNSPEC;
pgm->exit_datahigh = EXIT_DATAHIGH_UNSPEC; pgm->exit_datahigh = EXIT_DATAHIGH_UNSPEC;

64
pgm.c
View File

@ -211,65 +211,57 @@ void programmer_display(PROGRAMMER * pgm, const char * p)
pgm->display(pgm, 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; int pin;
char b2[8]; const char * fmt;
if ((pmask & PIN_MASK) == 0) buf[0] = 0;
return " (not used)"; for (pin = PIN_MIN; pin <= PIN_MAX; pin++) {
int index = pin/PIN_FIELD_ELEMENT_SIZE;
buf[0] = ' '; int bit = pin%PIN_FIELD_ELEMENT_SIZE;
buf[1] = 0; if (pindef->mask[index] & (1 << bit)) {
for (pin = 0; pin <= 17; pin++) { if (pindef->inverse[index] & (1 << bit)) {
if (pmask & (1 << pin)) { fmt = (buf[0]==0)?"~%d":",~%d";
sprintf(b2, "%d", pin); } else {
if (buf[1] != 0) fmt = (buf[0]==0)?" %d":",%d";
strcat(buf, ","); }
strcat(buf, b2); n = sprintf(p, fmt, pin);
p += n;
} }
} }
return buf; if (buf[0] == 0)
}
static char * pin_to_str(unsigned int pin)
{
static char buf[12];
if ((pin & PIN_MASK) == 0)
return " (not used)"; return " (not used)";
buf[0] = (pin & PIN_INVERSE)?'~':' ';
buf[1] = 0;
sprintf(buf+1, "%d", pin & PIN_MASK);
return buf; return buf;
} }
void pgm_display_generic_mask(PROGRAMMER * pgm, const char * p, unsigned int show) void pgm_display_generic_mask(PROGRAMMER * pgm, const char * p, unsigned int show)
{ {
if(show & (1<<PPI_AVR_VCC)) 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)) 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)) 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)) 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)) 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)) 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)) 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)) 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)) 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)) 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) void pgm_display_generic(PROGRAMMER * pgm, const char * p)

1
pgm.h
View File

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

126
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> #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 { enum {
PPI_AVR_VCC=1, PPI_AVR_VCC=1,
PPI_AVR_BUFF, PPI_AVR_BUFF,
@ -36,9 +47,75 @@ enum {
PIN_LED_VFY, PIN_LED_VFY,
N_PINS N_PINS
}; };
#define PIN_MASK (UINT_MAX>>1) #define PIN_MASK (UINT_MAX>>1)
#define PIN_INVERSE (~(PIN_MASK)) /* flag for inverted pin in serbb */ #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 */ #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 #endif

View File

@ -289,6 +289,8 @@ void serbb_initpgm(PROGRAMMER *pgm)
{ {
strcpy(pgm->type, "SERBB"); 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->rdy_led = bitbang_rdy_led;
pgm->err_led = bitbang_err_led; pgm->err_led = bitbang_err_led;
pgm->pgm_led = bitbang_pgm_led; pgm->pgm_led = bitbang_pgm_led;

View File

@ -350,6 +350,8 @@ void serbb_initpgm(PROGRAMMER *pgm)
{ {
strcpy(pgm->type, "SERBB"); 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->rdy_led = bitbang_rdy_led;
pgm->err_led = bitbang_err_led; pgm->err_led = bitbang_err_led;
pgm->pgm_led = bitbang_pgm_led; pgm->pgm_led = bitbang_pgm_led;