1 /*
2  * avrdude - A Downloader/Uploader for AVR device programmers
3  * Copyright (C) 2000-2004  Brian S. Dean <bsd@bsdhome.com>
4  *
5  * This program is free software; you can redistribute it and/or modify
6  * it under the terms of the GNU General Public License as published by
7  * the Free Software Foundation; either version 2 of the License, or
8  * (at your option) any later version.
9  *
10  * This program is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13  * GNU General Public License for more details.
14  *
15  * You should have received a copy of the GNU General Public License
16  * along with this program. If not, see <http://www.gnu.org/licenses/>.
17  */
18 
19 /* $Id: pindefs.h 1132 2013-01-09 19:23:30Z rliebscher $ */
20 
21 #include <string.h>
22 #include <stdio.h>
23 #include <stdlib.h>
24 
25 #include "avrdude.h"
26 #include "libavrdude.h"
27 
28 /**
29  * Adds a pin in the pin definition as normal or inverse pin.
30  *
31  * @param[out] pindef pin definition to update
32  * @param[in] pin number of pin [0..PIN_MAX]
33  * @param[in] inverse inverse (true) or normal (false) pin
34  */
pin_set_value(struct pindef_t * const pindef,const int pin,const bool inverse)35 void pin_set_value(struct pindef_t * const pindef, const int pin, const bool inverse) {
36 
37   pindef->mask[pin / PIN_FIELD_ELEMENT_SIZE] |= 1 << (pin % PIN_FIELD_ELEMENT_SIZE);
38   if(inverse) {
39     pindef->inverse[pin / PIN_FIELD_ELEMENT_SIZE] |= (1 << (pin % PIN_FIELD_ELEMENT_SIZE));
40   } else {
41     pindef->inverse[pin / PIN_FIELD_ELEMENT_SIZE] &= ~(1 << (pin % PIN_FIELD_ELEMENT_SIZE));
42   }
43 }
44 
45 /**
46  * Clear all defined pins in pindef.
47  *
48  * @param[out] pindef pin definition to clear
49  */
pin_clear_all(struct pindef_t * const pindef)50 void pin_clear_all(struct pindef_t * const pindef) {
51   memset(pindef, 0, sizeof(struct pindef_t));
52 }
53 
54 /**
55  * Convert new pin definition to old pin number
56  *
57  * @param[in] pindef new pin definition structure
58  * @param[out] pinno old pin definition integer
59  */
pin_fill_old_pinno(const struct pindef_t * const pindef,unsigned int * const pinno)60 static int pin_fill_old_pinno(const struct pindef_t * const pindef, unsigned int * const pinno) {
61   bool found = false;
62   int i;
63   for(i = 0; i < PIN_MAX; i++) {
64     if(pindef->mask[i / PIN_FIELD_ELEMENT_SIZE] & (1 << (i % PIN_FIELD_ELEMENT_SIZE))) {
65       if(found) {
66         avrdude_message(MSG_INFO, "Multiple pins found\n"); //TODO
67         return -1;
68       }
69       found = true;
70       *pinno = i;
71       if(pindef->inverse[i / PIN_FIELD_ELEMENT_SIZE] & (1 << (i % PIN_FIELD_ELEMENT_SIZE))) {
72         *pinno |= PIN_INVERSE;
73       }
74     }
75   }
76   return 0;
77 }
78 
79 /**
80  * Convert new pin definition to old pinlist, does not support mixed inverted/non-inverted pin
81  *
82  * @param[in] pindef new pin definition structure
83  * @param[out] pinno old pin definition integer
84  */
pin_fill_old_pinlist(const struct pindef_t * const pindef,unsigned int * const pinno)85 static int pin_fill_old_pinlist(const struct pindef_t * const pindef, unsigned int * const pinno) {
86   int i;
87 
88   for(i = 0; i < PIN_FIELD_SIZE; i++) {
89     if(i == 0) {
90       if((pindef->mask[i] & ~PIN_MASK) != 0) {
91         avrdude_message(MSG_INFO, "Pins of higher index than max field size for old pinno found\n");
92         return -1;
93       }
94       if (pindef->mask[i] == 0) {
95         /* this pin function is not using any pins */
96         *pinno = 0;
97       } else if(pindef->mask[i] == pindef->inverse[i]) {  /* all set bits in mask are set in inverse */
98         *pinno = pindef->mask[i];
99         *pinno |= PIN_INVERSE;
100       } else if(pindef->mask[i] == ((~pindef->inverse[i]) & pindef->mask[i])) {  /* all set bits in mask are cleared in inverse */
101         *pinno = pindef->mask[i];
102       } else {
103         avrdude_message(MSG_INFO, "pins have different polarity set\n");
104         return -1;
105       }
106     } else if(pindef->mask[i] != 0) {
107       avrdude_message(MSG_INFO, "Pins have higher number than fit in old format\n");
108       return -1;
109     }
110   }
111   return 0;
112 }
113 
114 
115 /**
116  * Convert for given programmer new pin definitions to old pin definitions.
117  *
118  * @param[inout] pgm programmer whose pins shall be converted.
119  */
pgm_fill_old_pins(struct programmer_t * const pgm)120 int pgm_fill_old_pins(struct programmer_t * const pgm) {
121 
122   if (pin_fill_old_pinlist(&(pgm->pin[PPI_AVR_VCC]),  &(pgm->pinno[PPI_AVR_VCC])) < 0)
123     return -1;
124   if (pin_fill_old_pinlist(&(pgm->pin[PPI_AVR_BUFF]), &(pgm->pinno[PPI_AVR_BUFF])) < 0)
125     return -1;
126   if (pin_fill_old_pinno(&(pgm->pin[PIN_AVR_RESET]), &(pgm->pinno[PIN_AVR_RESET])) < 0)
127     return -1;
128   if (pin_fill_old_pinno(&(pgm->pin[PIN_AVR_SCK]),  &(pgm->pinno[PIN_AVR_SCK])) < 0)
129     return -1;
130   if (pin_fill_old_pinno(&(pgm->pin[PIN_AVR_MOSI]), &(pgm->pinno[PIN_AVR_MOSI])) < 0)
131     return -1;
132   if (pin_fill_old_pinno(&(pgm->pin[PIN_AVR_MISO]), &(pgm->pinno[PIN_AVR_MISO])) < 0)
133     return -1;
134   if (pin_fill_old_pinno(&(pgm->pin[PIN_LED_ERR]),  &(pgm->pinno[PIN_LED_ERR])) < 0)
135     return -1;
136   if (pin_fill_old_pinno(&(pgm->pin[PIN_LED_RDY]),  &(pgm->pinno[PIN_LED_RDY])) < 0)
137     return -1;
138   if (pin_fill_old_pinno(&(pgm->pin[PIN_LED_PGM]),  &(pgm->pinno[PIN_LED_PGM])) < 0)
139     return -1;
140   if (pin_fill_old_pinno(&(pgm->pin[PIN_LED_VFY]),  &(pgm->pinno[PIN_LED_VFY])) < 0)
141     return -1;
142 
143   return 0;
144 }
145 
146 /**
147  * This function returns a string representation of pins in the mask eg. 1,3,5-7,9,12
148  * Another execution of this function will overwrite the previous result in the static buffer.
149  * Consecutive pin number are representated as start-end.
150  *
151  * @param[in] pinmask the pin mask for which we want the string representation
152  * @returns pointer to a static string.
153  */
pinmask_to_str(const pinmask_t * const pinmask)154 const char * pinmask_to_str(const pinmask_t * const pinmask) {
155   static char buf[(PIN_MAX + 1) * 5]; // should be enough for PIN_MAX=255
156   char *p = buf;
157   int n;
158   int pin;
159   const char * fmt;
160   int start = -1;
161   int end = -1;
162 
163   buf[0] = 0;
164   for(pin = PIN_MIN; pin <= PIN_MAX; pin++) {
165     int index = pin / PIN_FIELD_ELEMENT_SIZE;
166     int bit = pin % PIN_FIELD_ELEMENT_SIZE;
167     if(pinmask[index] & (1 << bit)) {
168       bool output = false;
169       if(start == -1) {
170         output = true;
171         start = pin;
172         end = start;
173       } else if(pin == end + 1) {
174         end = pin;
175       } else {
176         if(start != end) {
177           n = sprintf(p, "-%d", end);
178           p += n;
179         }
180         output = true;
181         start = pin;
182         end = start;
183       }
184       if(output) {
185         fmt = (buf[0] == 0) ? "%d" : ",%d";
186         n = sprintf(p, fmt, pin);
187         p += n;
188       }
189     }
190   }
191   if(start != end) {
192     n = sprintf(p, "-%d", end);
193     p += n;
194   }
195 
196   if(buf[0] == 0)
197     return  "(no pins)";
198 
199   return buf;
200 }
201 
202 
203 /**
204  * This function checks all pin of pgm against the constraints given in the checklist.
205  * It checks if
206  * @li any invalid pins are used
207  * @li valid pins are used inverted when not allowed
208  * @li any pins are used by more than one function
209  * @li any mandatory pin is not set all.
210  *
211  * In case of any error it report the wrong function and the pin numbers.
212  * For verbose >= 2 it also reports the possible correct values.
213  * For verbose >=3 it shows also which pins were ok.
214  *
215  * @param[in] pgm the programmer to check
216  * @param[in] checklist the constraint for the pins
217  * @param[in] size the number of entries in checklist
218  * @returns 0 if all pin definitions are valid, -1 otherwise
219  */
pins_check(const struct programmer_t * const pgm,const struct pin_checklist_t * const checklist,const int size,bool output)220 int pins_check(const struct programmer_t * const pgm, const struct pin_checklist_t * const checklist, const int size, bool output) {
221   static const struct pindef_t no_valid_pins = {{0}, {0}}; // default value if check list does not contain anything else
222   int rv = 0; // return value
223   int pinname; // loop counter through pinnames
224   pinmask_t already_used_all[PIN_FIELD_SIZE] = {0}; // collect pin definitions of all pin names for check of double use
225   // loop over all possible pinnames
226   for(pinname = 0; pinname < N_PINS; pinname++) {
227     bool used = false;
228     bool invalid = false;
229     bool inverse = false;
230     int index;
231     int segment;
232     bool mandatory_used = false;
233     pinmask_t invalid_used[PIN_FIELD_SIZE] = {0};
234     pinmask_t inverse_used[PIN_FIELD_SIZE] = {0};
235     pinmask_t already_used[PIN_FIELD_SIZE] = {0};
236     const struct pindef_t * valid_pins = &no_valid_pins;
237     bool is_mandatory = false;
238     bool is_ok = true;
239     //find corresponding check pattern
240     for(index = 0; index < size; index++) {
241       if(checklist[index].pinname == pinname) {
242         valid_pins = checklist[index].valid_pins;
243         is_mandatory = checklist[index].mandatory;
244         break;
245       }
246     }
247 
248     for(segment = 0; segment < PIN_FIELD_SIZE; segment++) {
249       // check if for mandatory any pin is defined
250       invalid_used[segment] = pgm->pin[pinname].mask[segment] & ~valid_pins->mask[segment];
251       if(is_mandatory && (0 != (pgm->pin[pinname].mask[segment] & valid_pins->mask[segment]))) {
252         mandatory_used = true;
253       }
254       // check if it does not use any non valid pins
255       invalid_used[segment] = pgm->pin[pinname].mask[segment] & ~valid_pins->mask[segment];
256       if(invalid_used[segment]) {
257         invalid = true;
258       }
259       // check if it does not use any valid pins as inverse if not allowed
260       inverse_used[segment] = pgm->pin[pinname].inverse[segment] & valid_pins->mask[segment] & ~valid_pins->inverse[segment];
261       if(inverse_used[segment]) {
262         inverse = true;
263       }
264       // check if it does not use same pins as other function
265       already_used[segment] = pgm->pin[pinname].mask[segment] & already_used_all[segment];
266       if(already_used[segment]) {
267         used = true;
268       }
269       already_used_all[segment] |= pgm->pin[pinname].mask[segment];
270     }
271     if(invalid) {
272       if(output) {
273         avrdude_message(MSG_INFO, "%s: %s: Following pins are not valid pins for this function: %s\n",
274                         progname, avr_pin_name(pinname), pinmask_to_str(invalid_used));
275         avrdude_message(MSG_NOTICE2, "%s: %s: Valid pins for this function are: %s\n",
276                   progname, avr_pin_name(pinname), pinmask_to_str(valid_pins->mask));
277       }
278       is_ok = false;
279     }
280     if(inverse) {
281       if(output) {
282         avrdude_message(MSG_INFO, "%s: %s: Following pins are not usable as inverse pins for this function: %s\n",
283                         progname, avr_pin_name(pinname), pinmask_to_str(inverse_used));
284         avrdude_message(MSG_NOTICE2, "%s: %s: Valid inverse pins for this function are: %s\n",
285                           progname, avr_pin_name(pinname), pinmask_to_str(valid_pins->inverse));
286       }
287       is_ok = false;
288     }
289     if(used) {
290       if(output) {
291         avrdude_message(MSG_INFO, "%s: %s: Following pins are set for other functions too: %s\n",
292                         progname, avr_pin_name(pinname), pinmask_to_str(already_used));
293         is_ok = false;
294       }
295     }
296     if(!mandatory_used && is_mandatory && !invalid) {
297       if(output) {
298         avrdude_message(MSG_INFO, "%s: %s: Mandatory pin is not defined.\n",
299                         progname, avr_pin_name(pinname));
300       }
301       is_ok = false;
302     }
303     if(!is_ok) {
304       rv = -1;
305     } else if(output) {
306       avrdude_message(MSG_DEBUG, "%s: %s: Pin is ok.\n",
307                       progname, avr_pin_name(pinname));
308     }
309   }
310   return rv;
311 }
312 
313 /**
314  * This function returns a string representation of defined pins eg. ~1,2,~4,~5,7
315  * Another execution of this function will overwrite the previous result in the static buffer.
316  *
317  * @param[in] pindef the pin definition for which we want the string representation
318  * @returns pointer to a static string.
319  */
pins_to_str(const struct pindef_t * const pindef)320 const char * pins_to_str(const struct pindef_t * const pindef) {
321   static char buf[(PIN_MAX + 1) * 5]; // should be enough for PIN_MAX=255
322   char *p = buf;
323   int n;
324   int pin;
325   const char * fmt;
326 
327   buf[0] = 0;
328   for(pin = PIN_MIN; pin <= PIN_MAX; pin++) {
329     int index = pin / PIN_FIELD_ELEMENT_SIZE;
330     int bit = pin % PIN_FIELD_ELEMENT_SIZE;
331     if(pindef->mask[index] & (1 << bit)) {
332       if(pindef->inverse[index] & (1 << bit)) {
333         fmt = (buf[0] == 0) ? "~%d" : ",~%d";
334       } else {
335         fmt = (buf[0] == 0) ? " %d" : ",%d";
336       }
337       n = sprintf(p, fmt, pin);
338       p += n;
339     }
340   }
341 
342   if(buf[0] == 0)
343     return " (not used)";
344 
345   return buf;
346 }
347 
348 /**
349  * Returns the name of the pin as string.
350  *
351  * @param pinname the pinname which we want as string.
352  * @returns a string with the pinname, or <unknown> if pinname is invalid.
353  */
avr_pin_name(int pinname)354 const char * avr_pin_name(int pinname) {
355   switch(pinname) {
356   case PPI_AVR_VCC   : return "VCC";
357   case PPI_AVR_BUFF  : return "BUFF";
358   case PIN_AVR_RESET : return "RESET";
359   case PIN_AVR_SCK   : return "SCK";
360   case PIN_AVR_MOSI  : return "MOSI";
361   case PIN_AVR_MISO  : return "MISO";
362   case PIN_LED_ERR   : return "ERRLED";
363   case PIN_LED_RDY   : return "RDYLED";
364   case PIN_LED_PGM   : return "PGMLED";
365   case PIN_LED_VFY   : return "VFYLED";
366   default : return "<unknown>";
367   }
368 }
369 
370 
371