* main.c: revert to rev 1159 (doing pgm_display after pgm_open)
* avrpart.[ch]: moved avr_pin_name to pindefs.[ch] * pgm.c: moved pins_to_str to pindefs.[ch], added initialization of new pin definitions in pgm_new() * pindefs.[ch]: added moved functions from other files, added a lot of documentation, reformatted files using astyle to have consistent spacing, added a new generic check function for pins * ft245r.c: used new generic pin check function git-svn-id: svn://svn.savannah.nongnu.org/avrdude/trunk/avrdude@1161 81a1dc3b-b13d-400b-aceb-764788c761c2
This commit is contained in:
parent
2d8c584c8c
commit
a816d19d02
11
ChangeLog
11
ChangeLog
|
@ -1,3 +1,14 @@
|
|||
2013-05-05 Rene Liebscher <R.Liebscher@gmx.de>
|
||||
|
||||
* main.c: revert to rev 1159 (doing pgm_display after pgm_open)
|
||||
* avrpart.[ch]: moved avr_pin_name to pindefs.[ch]
|
||||
* pgm.c: moved pins_to_str to pindefs.[ch], added initialization of
|
||||
new pin definitions in pgm_new()
|
||||
* pindefs.[ch]: added moved functions from other files, added a lot of
|
||||
documentation, reformatted files using astyle to have consistent spacing,
|
||||
added a new generic check function for pins
|
||||
* ft245r.c: used new generic pin check function
|
||||
|
||||
2013-05-03 Rene Liebscher <R.Liebscher@gmx.de>
|
||||
|
||||
Create new pin definition data structures to support 0-based pin numbers,
|
||||
|
|
18
avrpart.c
18
avrpart.c
|
@ -595,24 +595,6 @@ static char * reset_disp_str(int r)
|
|||
}
|
||||
|
||||
|
||||
const char * avr_pin_name(int pinno)
|
||||
{
|
||||
switch (pinno) {
|
||||
case PPI_AVR_VCC : return "VCC";
|
||||
case PPI_AVR_BUFF : return "BUFF";
|
||||
case PIN_AVR_RESET : return "RESET";
|
||||
case PIN_AVR_SCK : return "SCK";
|
||||
case PIN_AVR_MOSI : return "MOSI";
|
||||
case PIN_AVR_MISO : return "MISO";
|
||||
case PIN_LED_ERR : return "ERRLED";
|
||||
case PIN_LED_RDY : return "RDYLED";
|
||||
case PIN_LED_PGM : return "PGMLED";
|
||||
case PIN_LED_VFY : return "VFYLED";
|
||||
default : return "<unknown>";
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void avr_display(FILE * f, AVRPART * p, const char * prefix, int verbose)
|
||||
{
|
||||
int i;
|
||||
|
|
|
@ -222,7 +222,6 @@ void avr_free_part(AVRPART * d);
|
|||
AVRPART * locate_part(LISTID parts, char * partdesc);
|
||||
AVRPART * locate_part_by_avr910_devcode(LISTID parts, int devcode);
|
||||
void avr_display(FILE * f, AVRPART * p, const char * prefix, int verbose);
|
||||
const char * avr_pin_name(int);
|
||||
|
||||
typedef void (*walk_avrparts_cb)(const char *name, const char *desc,
|
||||
const char *cfgname, int cfglineno,
|
||||
|
|
65
ft245r.c
65
ft245r.c
|
@ -328,34 +328,6 @@ static int ft245r_read_sig_bytes(PROGRAMMER * pgm, AVRPART * p, AVRMEM * m) {
|
|||
return 3;
|
||||
}
|
||||
|
||||
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
|
||||
*/
|
||||
|
@ -456,12 +428,26 @@ static int ft245r_cmd(PROGRAMMER * pgm, unsigned char cmd[4],
|
|||
return 0;
|
||||
}
|
||||
|
||||
/* lower 8 pins are accepted, they might be also inverted */
|
||||
static const struct pindef_t valid_pins = {{0xff},{0xff}} ;
|
||||
|
||||
static const struct pin_checklist_t pin_checklist[] = {
|
||||
{ PIN_AVR_SCK, 1, &valid_pins},
|
||||
{ PIN_AVR_MOSI, 1, &valid_pins},
|
||||
{ PIN_AVR_MISO, 1, &valid_pins},
|
||||
{ PIN_AVR_RESET,1, &valid_pins},
|
||||
{ PPI_AVR_BUFF, 0, &valid_pins},
|
||||
};
|
||||
|
||||
static int ft245r_open(PROGRAMMER * pgm, char * port) {
|
||||
int rv;
|
||||
int devnum = -1;
|
||||
|
||||
ft245r_check_pins(pgm);
|
||||
rv = pins_check(pgm,pin_checklist,sizeof(pin_checklist)/sizeof(pin_checklist[0]));
|
||||
if(rv) {
|
||||
pgm->display(pgm, progbuf);
|
||||
return rv;
|
||||
}
|
||||
|
||||
strcpy(pgm->port, port);
|
||||
|
||||
|
@ -556,14 +542,17 @@ static int ft245r_open(PROGRAMMER * pgm, char * port) {
|
|||
|
||||
|
||||
static void ft245r_close(PROGRAMMER * pgm) {
|
||||
// I think the switch to BB mode and back flushes the buffer.
|
||||
ftdi_set_bitmode(handle, 0, BITMODE_SYNCBB); // set Synchronous BitBang, all in puts
|
||||
ftdi_set_bitmode(handle, 0, BITMODE_RESET); // disable Synchronous BitBang
|
||||
pthread_cancel(readerthread);
|
||||
pthread_join(readerthread, NULL);
|
||||
ftdi_usb_close(handle);
|
||||
ftdi_deinit (handle);
|
||||
free(handle);
|
||||
if (handle) {
|
||||
// I think the switch to BB mode and back flushes the buffer.
|
||||
ftdi_set_bitmode(handle, 0, BITMODE_SYNCBB); // set Synchronous BitBang, all in puts
|
||||
ftdi_set_bitmode(handle, 0, BITMODE_RESET); // disable Synchronous BitBang
|
||||
pthread_cancel(readerthread);
|
||||
pthread_join(readerthread, NULL);
|
||||
ftdi_usb_close(handle);
|
||||
ftdi_deinit (handle);
|
||||
free(handle);
|
||||
handle = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
static void ft245r_display(PROGRAMMER * pgm, const char * p) {
|
||||
|
@ -849,6 +838,8 @@ void ft245r_initpgm(PROGRAMMER * pgm) {
|
|||
pgm->paged_load = ft245r_paged_load;
|
||||
|
||||
pgm->read_sig_bytes = ft245r_read_sig_bytes;
|
||||
|
||||
handle = NULL;
|
||||
}
|
||||
|
||||
#else
|
||||
|
|
14
main.c
14
main.c
|
@ -921,12 +921,6 @@ 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;
|
||||
|
@ -943,7 +937,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);
|
||||
|
@ -957,6 +951,12 @@ 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");
|
||||
}
|
||||
|
|
32
pgm.c
32
pgm.c
|
@ -83,8 +83,10 @@ PROGRAMMER * pgm_new(void)
|
|||
pgm->baudrate = 0;
|
||||
pgm->initpgm = NULL;
|
||||
|
||||
for (i=0; i<N_PINS; i++)
|
||||
for (i=0; i<N_PINS; i++) {
|
||||
pgm->pinno[i] = 0;
|
||||
pin_clear_all(&(pgm->pin[i]));
|
||||
}
|
||||
|
||||
/*
|
||||
* mandatory functions - these are called without checking to see
|
||||
|
@ -211,34 +213,6 @@ void programmer_display(PROGRAMMER * pgm, const char * p)
|
|||
pgm->display(pgm, p);
|
||||
}
|
||||
|
||||
static char * pins_to_str(const struct pindef_t * const pindef)
|
||||
{
|
||||
static char buf[(PIN_MAX+1)*5]; // should be enough for PIN_MAX=255
|
||||
char *p = buf;
|
||||
int n;
|
||||
int pin;
|
||||
const char * fmt;
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
if (buf[0] == 0)
|
||||
return " (not used)";
|
||||
|
||||
return buf;
|
||||
}
|
||||
|
||||
void pgm_display_generic_mask(PROGRAMMER * pgm, const char * p, unsigned int show)
|
||||
{
|
||||
|
|
334
pindefs.c
334
pindefs.c
|
@ -21,6 +21,7 @@
|
|||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include "avrdude.h"
|
||||
#include "pindefs.h"
|
||||
#include "pgm.h"
|
||||
|
||||
|
@ -31,13 +32,14 @@
|
|||
* @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){
|
||||
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));
|
||||
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));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -45,8 +47,8 @@ void pin_set_value(struct pindef_t * const pindef, const int pin, const bool inv
|
|||
*
|
||||
* @param[out] pindef pin definition to clear
|
||||
*/
|
||||
void pin_clear_all(struct pindef_t * const pindef){
|
||||
memset(pindef,0,sizeof(struct pindef_t));
|
||||
void pin_clear_all(struct pindef_t * const pindef) {
|
||||
memset(pindef, 0, sizeof(struct pindef_t));
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -55,22 +57,22 @@ void pin_clear_all(struct pindef_t * const pindef){
|
|||
* @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;
|
||||
}
|
||||
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;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -79,29 +81,29 @@ static void pin_fill_old_pinno(const struct pindef_t * const pindef, unsigned in
|
|||
* @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;
|
||||
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);
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
@ -114,13 +116,243 @@ 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]));
|
||||
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]));
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* This function returns a string representation of pins in the mask eg. 1,3,5-7,9,12
|
||||
* Another execution of this function will overwrite the previous result in the static buffer.
|
||||
* Consecutive pin number are representated as start-end.
|
||||
*
|
||||
* @param[in] pinmask the pin mask for which we want the string representation
|
||||
* @returns pointer to a static string.
|
||||
*/
|
||||
const char * pinmask_to_str(const pinmask_t * const pinmask) {
|
||||
static char buf[(PIN_MAX + 1) * 5]; // should be enough for PIN_MAX=255
|
||||
char *p = buf;
|
||||
int n;
|
||||
int pin;
|
||||
const char * fmt;
|
||||
int start = -1;
|
||||
int end = -1;
|
||||
|
||||
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(pinmask[index] & (1 << bit)) {
|
||||
bool output = false;
|
||||
if(start == -1) {
|
||||
output = true;
|
||||
start = pin;
|
||||
end = start;
|
||||
} else if(pin == end + 1) {
|
||||
end = pin;
|
||||
} else {
|
||||
if(start != end) {
|
||||
n = sprintf(p, "-%d", end);
|
||||
p += n;
|
||||
}
|
||||
output = true;
|
||||
start = pin;
|
||||
end = start;
|
||||
}
|
||||
if(output) {
|
||||
fmt = (buf[0] == 0) ? "%d" : ",%d";
|
||||
n = sprintf(p, fmt, pin);
|
||||
p += n;
|
||||
}
|
||||
}
|
||||
}
|
||||
if(start != end) {
|
||||
n = sprintf(p, "-%d", end);
|
||||
p += n;
|
||||
}
|
||||
|
||||
if(buf[0] == 0)
|
||||
return "(no pins)";
|
||||
|
||||
return buf;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* This function checks all pin of pgm against the constraints given in the checklist.
|
||||
* It checks if
|
||||
* @li any invalid pins are used
|
||||
* @li valid pins are used inverted when not allowed
|
||||
* @li any pins are used by more than one function
|
||||
* @li any mandatory pin is not set all.
|
||||
*
|
||||
* In case of any error it report the wrong function and the pin numbers.
|
||||
* For verbose >= 2 it also reports the possible correct values.
|
||||
* For verbose >=3 it shows also which pins were ok.
|
||||
*
|
||||
* @param[in] pgm the programmer to check
|
||||
* @param[in] checklist the constraint for the pins
|
||||
* @param[in] size the number of entries in checklist
|
||||
* @returns 0 if all pin definitions are valid, -1 otherwise
|
||||
*/
|
||||
int pins_check(const struct programmer_t * const pgm, const struct pin_checklist_t * const checklist, const int size) {
|
||||
static const struct pindef_t no_valid_pins = {{0}, {0}}; // default value if check list does not contain anything else
|
||||
int rv = 0; // return value
|
||||
int pinname; // loop counter through pinnames
|
||||
pinmask_t already_used_all[PIN_FIELD_SIZE] = {0}; // collect pin definitions of all pin names for check of double use
|
||||
// loop over all possible pinnames
|
||||
for(pinname = 0; pinname < N_PINS; pinname++) {
|
||||
bool used = false;
|
||||
bool invalid = false;
|
||||
bool inverse = false;
|
||||
int index;
|
||||
int segment;
|
||||
bool mandatory_used = false;
|
||||
pinmask_t invalid_used[PIN_FIELD_SIZE] = {0};
|
||||
pinmask_t inverse_used[PIN_FIELD_SIZE] = {0};
|
||||
pinmask_t already_used[PIN_FIELD_SIZE] = {0};
|
||||
const struct pindef_t * valid_pins = &no_valid_pins;
|
||||
bool is_mandatory = false;
|
||||
bool is_ok = true;
|
||||
//find corresponding check pattern
|
||||
for(index = 0; index < size; index++) {
|
||||
if(checklist[index].pinname == pinname) {
|
||||
valid_pins = checklist[index].valid_pins;
|
||||
is_mandatory = checklist[index].mandatory;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
for(segment = 0; segment < PIN_FIELD_SIZE; segment++) {
|
||||
// check if for mandatory any pin is defined
|
||||
invalid_used[segment] = pgm->pin[pinname].mask[segment] & ~valid_pins->mask[segment];
|
||||
if(is_mandatory && (0 != (pgm->pin[pinname].mask[segment] & valid_pins->mask[segment]))) {
|
||||
mandatory_used = true;
|
||||
}
|
||||
// check if it does not use any non valid pins
|
||||
invalid_used[segment] = pgm->pin[pinname].mask[segment] & ~valid_pins->mask[segment];
|
||||
if(invalid_used[segment]) {
|
||||
invalid = true;
|
||||
}
|
||||
// check if it does not use any valid pins as inverse if not allowed
|
||||
inverse_used[segment] = pgm->pin[pinname].inverse[segment] & valid_pins->mask[segment] & ~valid_pins->inverse[segment];
|
||||
if(inverse_used[segment]) {
|
||||
inverse = true;
|
||||
}
|
||||
// check if it does not use same pins as other function
|
||||
already_used[segment] = pgm->pin[pinname].mask[segment] & already_used_all[segment];
|
||||
if(already_used[segment]) {
|
||||
used = true;
|
||||
}
|
||||
already_used_all[segment] |= pgm->pin[pinname].mask[segment];
|
||||
}
|
||||
if(invalid) {
|
||||
fprintf(stderr,
|
||||
"%s: %s: Following pins are not valid pins for this function: %s\n",
|
||||
progname, avr_pin_name(pinname), pinmask_to_str(invalid_used));
|
||||
if(verbose >= 2) {
|
||||
fprintf(stderr,
|
||||
"%s: %s: Valid pins for this function are: %s\n",
|
||||
progname, avr_pin_name(pinname), pinmask_to_str(valid_pins->mask));
|
||||
}
|
||||
is_ok = false;
|
||||
}
|
||||
if(inverse) {
|
||||
fprintf(stderr,
|
||||
"%s: %s: Following pins are not usable as inverse pins for this function: %s\n",
|
||||
progname, avr_pin_name(pinname), pinmask_to_str(inverse_used));
|
||||
if(verbose >= 2) {
|
||||
fprintf(stderr,
|
||||
"%s: %s: Valid inverse pins for this function are: %s\n",
|
||||
progname, avr_pin_name(pinname), pinmask_to_str(valid_pins->inverse));
|
||||
}
|
||||
is_ok = false;
|
||||
}
|
||||
if(used) {
|
||||
fprintf(stderr,
|
||||
"%s: %s: Following pins are set for other functions too: %s\n",
|
||||
progname, avr_pin_name(pinname), pinmask_to_str(already_used));
|
||||
is_ok = false;
|
||||
}
|
||||
if(!mandatory_used && is_mandatory && !invalid) {
|
||||
fprintf(stderr,
|
||||
"%s: %s: Mandatory pin is not defined.\n",
|
||||
progname, avr_pin_name(pinname));
|
||||
is_ok = false;
|
||||
}
|
||||
if(!is_ok) {
|
||||
rv = -1;
|
||||
} else if(verbose >= 3) {
|
||||
fprintf(stderr,
|
||||
"%s: %s: Pin is ok.\n",
|
||||
progname, avr_pin_name(pinname));
|
||||
|
||||
}
|
||||
}
|
||||
return rv;
|
||||
}
|
||||
|
||||
/**
|
||||
* This function returns a string representation of defined pins eg. ~1,2,~4,~5,7
|
||||
* Another execution of this function will overwrite the previous result in the static buffer.
|
||||
*
|
||||
* @param[in] pindef the pin definition for which we want the string representation
|
||||
* @returns pointer to a static string.
|
||||
*/
|
||||
const char * pins_to_str(const struct pindef_t * const pindef) {
|
||||
static char buf[(PIN_MAX + 1) * 5]; // should be enough for PIN_MAX=255
|
||||
char *p = buf;
|
||||
int n;
|
||||
int pin;
|
||||
const char * fmt;
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
if(buf[0] == 0)
|
||||
return " (not used)";
|
||||
|
||||
return buf;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the name of the pin as string.
|
||||
*
|
||||
* @param pinname the pinname which we want as string.
|
||||
* @returns a string with the pinname, or <unknown> if pinname is invalid.
|
||||
*/
|
||||
const char * avr_pin_name(int pinname) {
|
||||
switch(pinname) {
|
||||
case PPI_AVR_VCC : return "VCC";
|
||||
case PPI_AVR_BUFF : return "BUFF";
|
||||
case PIN_AVR_RESET : return "RESET";
|
||||
case PIN_AVR_SCK : return "SCK";
|
||||
case PIN_AVR_MOSI : return "MOSI";
|
||||
case PIN_AVR_MISO : return "MISO";
|
||||
case PIN_LED_ERR : return "ERRLED";
|
||||
case PIN_LED_RDY : return "RDYLED";
|
||||
case PIN_LED_PGM : return "PGMLED";
|
||||
case PIN_LED_VFY : return "VFYLED";
|
||||
default : return "<unknown>";
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
82
pindefs.h
82
pindefs.h
|
@ -35,7 +35,7 @@ typedef unsigned long pinmask_t;
|
|||
|
||||
|
||||
enum {
|
||||
PPI_AVR_VCC=1,
|
||||
PPI_AVR_VCC = 1,
|
||||
PPI_AVR_BUFF,
|
||||
PIN_AVR_RESET,
|
||||
PIN_AVR_SCK,
|
||||
|
@ -72,7 +72,7 @@ enum {
|
|||
* @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),
|
||||
* @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
|
||||
*/
|
||||
|
@ -106,16 +106,90 @@ enum {
|
|||
* 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
|
||||
pinmask_t mask[PIN_FIELD_SIZE]; ///< bitfield of used pins
|
||||
pinmask_t inverse[PIN_FIELD_SIZE]; ///< bitfield of inverse/normal usage of used pins
|
||||
};
|
||||
|
||||
/**
|
||||
* Data structure to define a checklist of valid pins for each function.
|
||||
*/
|
||||
struct pin_checklist_t {
|
||||
int pinname; ///< logical pinname eg. PIN_AVR_SCK
|
||||
int mandatory; ///< is this a mandatory pin
|
||||
const struct pindef_t* valid_pins; ///< mask defines allowed pins, inverse define is they might be used inverted
|
||||
};
|
||||
|
||||
/**
|
||||
* 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);
|
||||
|
||||
/**
|
||||
* Clear all defined pins in pindef.
|
||||
*
|
||||
* @param[out] pindef pin definition to clear
|
||||
*/
|
||||
void pin_clear_all(struct pindef_t * const pindef);
|
||||
|
||||
struct programmer_t; /* forward declaration */
|
||||
|
||||
/**
|
||||
* 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);
|
||||
|
||||
/**
|
||||
* This function checks all pin of pgm against the constraints given in the checklist.
|
||||
* It checks if
|
||||
* @li any invalid pins are used
|
||||
* @li valid pins are used inverted when not allowed
|
||||
* @li any pins are used by more than one function
|
||||
* @li any mandatory pin is not set all.
|
||||
*
|
||||
* In case of any error it report the wrong function and the pin numbers.
|
||||
* For verbose >= 2 it also reports the possible correct values.
|
||||
* For verbose >=3 it shows also which pins were ok.
|
||||
*
|
||||
* @param[in] pgm the programmer to check
|
||||
* @param[in] checklist the constraint for the pins
|
||||
* @param[in] size the number of entries in checklist
|
||||
* @returns 0 if all pin definitions are valid, -1 otherwise
|
||||
*/
|
||||
int pins_check(const struct programmer_t * const pgm, const struct pin_checklist_t * const checklist, const int size);
|
||||
|
||||
/**
|
||||
* Returns the name of the pin as string.
|
||||
*
|
||||
* @param pinname the pinname which we want as string.
|
||||
* @returns a string with the pinname, or <unknown> if pinname is invalid.
|
||||
*/
|
||||
const char * avr_pin_name(int pinname);
|
||||
|
||||
/**
|
||||
* This function returns a string representation of defined pins eg. ~1,2,~4,~5,7
|
||||
* Another execution of this function will overwrite the previous result in the static buffer.
|
||||
*
|
||||
* @param[in] pindef the pin definition for which we want the string representation
|
||||
* @returns pointer to a static string.
|
||||
*/
|
||||
const char * pins_to_str(const struct pindef_t * const pindef);
|
||||
|
||||
/**
|
||||
* This function returns a string representation of pins in the mask eg. 1,3,5-7,9,12
|
||||
* Another execution of this function will overwrite the previous result in the static buffer.
|
||||
* Consecutive pin number are representated as start-end.
|
||||
*
|
||||
* @param[in] pinmask the pin mask for which we want the string representation
|
||||
* @returns pointer to a static string.
|
||||
*/
|
||||
const char * pinmask_to_str(const pinmask_t * const pinmask);
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
|
|
Loading…
Reference in New Issue