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:
parent
90b0a233ef
commit
2d8c584c8c
16
ChangeLog
16
ChangeLog
|
@ -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
|
||||
|
|
|
@ -140,6 +140,7 @@ libavrdude_a_SOURCES = \
|
|||
pgm_type.h \
|
||||
pickit2.c \
|
||||
pickit2.h \
|
||||
pindefs.c \
|
||||
pindefs.h \
|
||||
ppi.c \
|
||||
ppi.h \
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
*/
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
215
ft245r.c
215
ft245r.c
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
|
|
14
main.c
14
main.c
|
@ -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");
|
||||
}
|
||||
|
|
2
par.c
2
par.c
|
@ -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;
|
||||
|
|
64
pgm.c
64
pgm.c
|
@ -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)
|
||||
|
|
1
pgm.h
1
pgm.h
|
@ -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;
|
||||
|
|
|
@ -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]));
|
||||
|
||||
}
|
79
pindefs.h
79
pindefs.h
|
@ -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
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
Loading…
Reference in New Issue