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