1 /*
2  * avrdude - A Downloader/Uploader for AVR device programmers
3  * Copyright (C) 2012 Kirill Levchenko
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$ */
20 
21 #include "ac_cfg.h"
22 
23 #include <stdio.h>
24 #include <stdlib.h>
25 #include <string.h>
26 #include <errno.h>
27 #include <limits.h>
28 #include <unistd.h>
29 
30 #if HAVE_STDINT_H
31 #include <stdint.h>
32 #elif HAVE_INTTYPES_H
33 #include <inttypes.h>
34 #endif
35 
36 #include "avrdude.h"
37 #include "libavrdude.h"
38 
39 #include "flip2.h"
40 #include "dfu.h"
41 #include "usbdevs.h" /* for USB_VENDOR_ATMEL */
42 
43 /* There are three versions of the FLIP protocol:
44  *
45  * Version 0: C51 parts
46  * Version 1: megaAVR parts ("USB DFU Bootloader Datasheet" [doc7618])
47  * Version 2: XMEGA parts (AVR4023 [doc8457])
48  *
49  * We currently only support Version 2, as documented in AVR4023.
50  *
51  * Additional references:
52  *   flip_protocol.h from the Atmel Software Framework.
53  *   udi_dfu_atmel.c from XMEGA bootloaders archive.
54  */
55 
56 /* EXPORTED CONSTANT STRINGS */
57 
58 const char flip2_desc[] = "FLIP USB DFU protocol version 2 (AVR4023)";
59 
60 /* PRIVATE DATA STRUCTURES */
61 
62 struct flip2
63 {
64   struct dfu_dev *dfu;
65   unsigned char part_sig[3];
66   unsigned char part_rev;
67   unsigned char boot_ver;
68 };
69 
70 #define FLIP2(pgm) ((struct flip2 *)(pgm->cookie))
71 
72 /* The FLIP2 protocol assigns specific meaning to certain combinations of
73  * status and state bytes in the DFU_GETSTATUS response. These constants en-
74  * code these combinations as a 16-bit value: the high order byte is the
75  * status and the low order byte is the state of the status-state pairing.
76  */
77 
78 #define FLIP2_STATUS_OK 0x0000
79 #define FLIP2_STATUS_STALL 0x0F0A
80 #define FLIP2_STATUS_MEM_UKNOWN 0x030A
81 #define FLIP2_STATUS_MEM_PROTECTED 0x0300
82 #define FLIP2_STATUS_OUTOFRANGE 0x080A
83 #define FLIP2_STATUS_BLANK_FAIL 0x0500
84 #define FLIP2_STATUS_ERASE_ONGOING 0x0904
85 
86 /* FLIP2 data structures and constants. */
87 
88 struct flip2_cmd {
89   unsigned char group_id;
90   unsigned char cmd_id;
91   unsigned char args[4];
92 };
93 
94 #define FLIP2_CMD_GROUP_DOWNLOAD 0x01
95 #define FLIP2_CMD_GROUP_UPLOAD 0x03
96 #define FLIP2_CMD_GROUP_EXEC 0x04
97 #define FLIP2_CMD_GROUP_SELECT 0x06
98 
99 #define FLIP2_CMD_PROG_START 0x00
100 #define FLIP2_CMD_READ_MEMORY 0x00
101 #define FLIP2_CMD_SELECT_MEMORY 0x03
102 #define FLIP2_CMD_CHIP_ERASE 0x00
103 #define FLIP2_CMD_START_APP 0x03
104 
105 #define FLIP2_SELECT_MEMORY_UNIT 0x00
106 #define FLIP2_SELECT_MEMORY_PAGE 0x01
107 
108 enum flip2_mem_unit {
109   FLIP2_MEM_UNIT_UNKNOWN = -1,
110   FLIP2_MEM_UNIT_FLASH = 0x00,
111   FLIP2_MEM_UNIT_EEPROM = 0x01,
112   FLIP2_MEM_UNIT_SECURITY = 0x02,
113   FLIP2_MEM_UNIT_CONFIGURATION = 0x03,
114   FLIP2_MEM_UNIT_BOOTLOADER = 0x04,
115   FLIP2_MEM_UNIT_SIGNATURE = 0x05,
116   FLIP2_MEM_UNIT_USER = 0x06,
117   FLIP2_MEM_UNIT_INT_RAM = 0x07,
118   FLIP2_MEM_UNIT_EXT_MEM_CS0 = 0x08,
119   FLIP2_MEM_UNIT_EXT_MEM_CS1 = 0x09,
120   FLIP2_MEM_UNIT_EXT_MEM_CS2 = 0x0A,
121   FLIP2_MEM_UNIT_EXT_MEM_CS3 = 0x0B,
122   FLIP2_MEM_UNIT_EXT_MEM_CS4 = 0x0C,
123   FLIP2_MEM_UNIT_EXT_MEM_CS5 = 0x0D,
124   FLIP2_MEM_UNIT_EXT_MEM_CS6 = 0x0E,
125   FLIP2_MEM_UNIT_EXT_MEM_CS7 = 0x0F,
126   FLIP2_MEM_UNIT_EXT_MEM_DF = 0x10
127 };
128 
129 /* EXPORTED PROGRAMMER FUNCTION PROTOTYPES */
130 
131 static int flip2_open(PROGRAMMER *pgm, char *port_spec);
132 static int flip2_initialize(PROGRAMMER* pgm, AVRPART *part);
133 static void flip2_close(PROGRAMMER* pgm);
134 static void flip2_enable(PROGRAMMER* pgm);
135 static void flip2_disable(PROGRAMMER* pgm);
136 static void flip2_display(PROGRAMMER* pgm, const char *prefix);
137 static int flip2_program_enable(PROGRAMMER* pgm, AVRPART *part);
138 static int flip2_chip_erase(PROGRAMMER* pgm, AVRPART *part);
139 static int flip2_read_byte(PROGRAMMER* pgm, AVRPART *part, AVRMEM *mem,
140   unsigned long addr, unsigned char *value);
141 static int flip2_write_byte(PROGRAMMER* pgm, AVRPART *part, AVRMEM *mem,
142   unsigned long addr, unsigned char value);
143 static int flip2_paged_load(PROGRAMMER* pgm, AVRPART *part, AVRMEM *mem,
144   unsigned int page_size, unsigned int addr, unsigned int n_bytes);
145 static int flip2_paged_write(PROGRAMMER* pgm, AVRPART *part, AVRMEM *mem,
146   unsigned int page_size, unsigned int addr, unsigned int n_bytes);
147 static int flip2_read_sig_bytes(PROGRAMMER* pgm, AVRPART *part, AVRMEM *mem);
148 static void flip2_setup(PROGRAMMER * pgm);
149 static void flip2_teardown(PROGRAMMER * pgm);
150 
151 /* INTERNAL PROGRAMMER FUNCTION PROTOTYPES */
152 #ifdef HAVE_LIBUSB
153 // The internal ones are made conditional, as they're not defined further down #ifndef HAVE_LIBUSB
154 
155 static void flip2_show_info(struct flip2 *flip2);
156 
157 static int flip2_read_memory(struct dfu_dev *dfu,
158   enum flip2_mem_unit mem_unit, uint32_t addr, void *ptr, int size);
159 static int flip2_write_memory(struct dfu_dev *dfu,
160   enum flip2_mem_unit mem_unit, uint32_t addr, const void *ptr, int size);
161 
162 static int flip2_set_mem_unit(struct dfu_dev *dfu,
163   enum flip2_mem_unit mem_unit);
164 static int flip2_set_mem_page(struct dfu_dev *dfu, unsigned short page_addr);
165 static int flip2_read_max1k(struct dfu_dev *dfu,
166   unsigned short offset, void *ptr, unsigned short size);
167 static int flip2_write_max1k(struct dfu_dev *dfu,
168   unsigned short offset, const void *ptr, unsigned short size);
169 
170 static const char * flip2_status_str(const struct dfu_status *status);
171 static const char * flip2_mem_unit_str(enum flip2_mem_unit mem_unit);
172 static enum flip2_mem_unit flip2_mem_unit(const char *name);
173 
174 #endif /* HAVE_LIBUSB */
175 
176 /* THE INITPGM FUNCTION DEFINITIONS */
177 
flip2_initpgm(PROGRAMMER * pgm)178 void flip2_initpgm(PROGRAMMER *pgm)
179 {
180   strcpy(pgm->type, "flip2");
181 
182   /* Mandatory Functions */
183   pgm->initialize       = flip2_initialize;
184   pgm->enable           = flip2_enable;
185   pgm->disable          = flip2_disable;
186   pgm->display          = flip2_display;
187   pgm->program_enable   = flip2_program_enable;
188   pgm->chip_erase       = flip2_chip_erase;
189   pgm->open             = flip2_open;
190   pgm->close            = flip2_close;
191   pgm->paged_load       = flip2_paged_load;
192   pgm->paged_write      = flip2_paged_write;
193   pgm->read_byte        = flip2_read_byte;
194   pgm->write_byte       = flip2_write_byte;
195   pgm->read_sig_bytes   = flip2_read_sig_bytes;
196   pgm->setup            = flip2_setup;
197   pgm->teardown         = flip2_teardown;
198 }
199 
200 #ifdef HAVE_LIBUSB
201 /* EXPORTED PROGRAMMER FUNCTION DEFINITIONS */
202 
flip2_open(PROGRAMMER * pgm,char * port_spec)203 int flip2_open(PROGRAMMER *pgm, char *port_spec)
204 {
205   FLIP2(pgm)->dfu = dfu_open(port_spec);
206   return (FLIP2(pgm)->dfu != NULL) ? 0 : -1;
207 }
208 
flip2_initialize(PROGRAMMER * pgm,AVRPART * part)209 int flip2_initialize(PROGRAMMER* pgm, AVRPART *part)
210 {
211   unsigned short vid, pid;
212   int result;
213   struct dfu_dev *dfu = FLIP2(pgm)->dfu;
214 
215   /* A note about return values. Negative return values from this function are
216    * interpreted as failure by main(), from where this function is called.
217    * However such failures are interpreted as a device signature check failure
218    * and the user is adviced to use the -F option to override this check. In
219    * our case, this is misleading, so we defer reporting an error until another
220    * function is called. Thus, we always return 0 (success) from initialize().
221    * I don't like this, but I don't want to mess with main().
222    */
223 
224   /* The dfu_init() function will try to find the target part either based on
225    * a USB address provided by the user with the -P option or by matching the
226    * VID and PID of the device. The VID may be specified in the programmer
227    * definition; if not specified, it defaults to USB_VENDOR_ATMEL (defined
228    * in usbdevs.h). The PID may be specified either in the programmer
229    * definition or the part definition; the programmer definition takes
230    * priority. The default PID value is 0, which causes dfu_init() to ignore
231    * the PID when matching a target device.
232    */
233 
234   vid = (pgm->usbvid != 0) ? pgm->usbvid : USB_VENDOR_ATMEL;
235   LNODEID usbpid = lfirst(pgm->usbpid);
236   if (usbpid) {
237     pid = *(int *)(ldata(usbpid));
238     if (lnext(usbpid))
239       avrdude_message(MSG_INFO, "%s: Warning: using PID 0x%04x, ignoring remaining PIDs in list\n",
240                       progname, pid);
241   } else {
242     pid = part->usbpid;
243   }
244 
245   if (!ovsigck && !(part->flags & AVRPART_HAS_PDI)) {
246     avrdude_message(MSG_INFO, "%s: \"flip2\" (FLIP protocol version 2) is for Xmega devices.\n"
247                     "%s For AT90USB* or ATmega*U* devices, use \"flip1\".\n"
248                     "%s (Use -F to bypass this check.)\n",
249                     progname, progbuf, progbuf);
250     return -1;
251   }
252 
253   result = dfu_init(dfu, vid, pid);
254 
255   if (result != 0)
256     goto flip2_initialize_fail;
257 
258   /* Check if descriptor values are what we expect. */
259 
260   if (dfu->dev_desc.idVendor != vid)
261     avrdude_message(MSG_INFO, "%s: Warning: USB idVendor = 0x%04X (expected 0x%04X)\n",
262       progname, dfu->dev_desc.idVendor, vid);
263 
264   if (pid != 0 && dfu->dev_desc.idProduct != pid)
265     avrdude_message(MSG_INFO, "%s: Warning: USB idProduct = 0x%04X (expected 0x%04X)\n",
266       progname, dfu->dev_desc.idProduct, pid);
267 
268   if (dfu->dev_desc.bNumConfigurations != 1)
269     avrdude_message(MSG_INFO, "%s: Warning: USB bNumConfigurations = %d (expected 1)\n",
270       progname, (int) dfu->dev_desc.bNumConfigurations);
271 
272   if (dfu->conf_desc.bNumInterfaces != 1)
273     avrdude_message(MSG_INFO, "%s: Warning: USB bNumInterfaces = %d (expected 1)\n",
274       progname, (int) dfu->conf_desc.bNumInterfaces);
275 
276   if (dfu->dev_desc.bDeviceClass != 0)
277     avrdude_message(MSG_INFO, "%s: Warning: USB bDeviceClass = %d (expected 0)\n",
278       progname, (int) dfu->dev_desc.bDeviceClass);
279 
280   if (dfu->dev_desc.bDeviceSubClass != 0)
281     avrdude_message(MSG_INFO, "%s: Warning: USB bDeviceSubClass = %d (expected 0)\n",
282       progname, (int) dfu->dev_desc.bDeviceSubClass);
283 
284   if (dfu->dev_desc.bDeviceProtocol != 0)
285     avrdude_message(MSG_INFO, "%s: Warning: USB bDeviceProtocol = %d (expected 0)\n",
286       progname, (int) dfu->dev_desc.bDeviceProtocol);
287 
288   if (dfu->intf_desc.bInterfaceClass != 0xFF)
289     avrdude_message(MSG_INFO, "%s: Warning: USB bInterfaceClass = %d (expected 255)\n",
290       progname, (int) dfu->intf_desc.bInterfaceClass);
291 
292   if (dfu->intf_desc.bInterfaceSubClass != 0)
293     avrdude_message(MSG_INFO, "%s: Warning: USB bInterfaceSubClass = %d (expected 0)\n",
294       progname, (int) dfu->intf_desc.bInterfaceSubClass);
295 
296   if (dfu->intf_desc.bInterfaceProtocol != 0)
297     avrdude_message(MSG_INFO, "%s: Warning: USB bInterfaceSubClass = %d (expected 0)\n",
298       progname, (int) dfu->intf_desc.bInterfaceProtocol);
299 
300   result = flip2_read_memory(FLIP2(pgm)->dfu,
301     FLIP2_MEM_UNIT_SIGNATURE, 0, FLIP2(pgm)->part_sig, 4);
302 
303   if (result != 0)
304     goto flip2_initialize_fail;
305 
306   result = flip2_read_memory(FLIP2(pgm)->dfu,
307     FLIP2_MEM_UNIT_BOOTLOADER, 0, &FLIP2(pgm)->boot_ver, 1);
308 
309   if (result != 0)
310     goto flip2_initialize_fail;
311 
312   if (verbose)
313     flip2_show_info(FLIP2(pgm));
314 
315   return 0;
316 
317 flip2_initialize_fail:
318   dfu_close(FLIP2(pgm)->dfu);
319   FLIP2(pgm)->dfu = NULL;
320   return 0;
321 }
322 
flip2_close(PROGRAMMER * pgm)323 void flip2_close(PROGRAMMER* pgm)
324 {
325   if (FLIP2(pgm)->dfu != NULL) {
326     dfu_close(FLIP2(pgm)->dfu);
327     FLIP2(pgm)->dfu = NULL;
328   }
329 }
330 
flip2_enable(PROGRAMMER * pgm)331 void flip2_enable(PROGRAMMER* pgm)
332 {
333   /* Nothing to do. */
334 }
335 
flip2_disable(PROGRAMMER * pgm)336 void flip2_disable(PROGRAMMER* pgm)
337 {
338   /* Nothing to do. */
339 }
340 
flip2_display(PROGRAMMER * pgm,const char * prefix)341 void flip2_display(PROGRAMMER* pgm, const char *prefix)
342 {
343   /* Nothing to do. */
344 }
345 
flip2_program_enable(PROGRAMMER * pgm,AVRPART * part)346 int flip2_program_enable(PROGRAMMER* pgm, AVRPART *part)
347 {
348   /* I couldn't find anything that uses this function, although it is marked
349    * as "mandatory" in pgm.c. In case anyone does use it, we'll report an
350    * error if we failed to initialize.
351    */
352 
353   return (FLIP2(pgm)->dfu != NULL) ? 0 : -1;
354 }
355 
flip2_chip_erase(PROGRAMMER * pgm,AVRPART * part)356 int flip2_chip_erase(PROGRAMMER* pgm, AVRPART *part)
357 {
358   struct dfu_status status;
359   int cmd_result = 0;
360   int aux_result;
361 
362   avrdude_message(MSG_NOTICE2, "%s: flip_chip_erase()\n", progname);
363 
364   struct flip2_cmd cmd = {
365     FLIP2_CMD_GROUP_EXEC, FLIP2_CMD_CHIP_ERASE, { 0xFF, 0, 0, 0 }
366   };
367 
368   for (;;) {
369     cmd_result = dfu_dnload(FLIP2(pgm)->dfu, &cmd, sizeof(cmd));
370     aux_result = dfu_getstatus(FLIP2(pgm)->dfu, &status);
371 
372     if (aux_result != 0)
373       return aux_result;
374 
375     if (status.bStatus != DFU_STATUS_OK) {
376       if (status.bStatus == ((FLIP2_STATUS_ERASE_ONGOING >> 8) & 0xFF) &&
377           status.bState == ((FLIP2_STATUS_ERASE_ONGOING >> 0) & 0xFF))
378       {
379         continue;
380       } else
381         avrdude_message(MSG_INFO, "%s: Error: DFU status %s\n", progname,
382           flip2_status_str(&status));
383       dfu_clrstatus(FLIP2(pgm)->dfu);
384     } else
385       break;
386   }
387 
388   return cmd_result;
389 }
390 
flip2_read_byte(PROGRAMMER * pgm,AVRPART * part,AVRMEM * mem,unsigned long addr,unsigned char * value)391 int flip2_read_byte(PROGRAMMER* pgm, AVRPART *part, AVRMEM *mem,
392   unsigned long addr, unsigned char *value)
393 {
394   enum flip2_mem_unit mem_unit;
395 
396   if (FLIP2(pgm)->dfu == NULL)
397     return -1;
398 
399   mem_unit = flip2_mem_unit(mem->desc);
400 
401   if (mem_unit == FLIP2_MEM_UNIT_UNKNOWN) {
402     avrdude_message(MSG_INFO, "%s: Error: "
403       "\"%s\" memory not accessible using FLIP",
404       progname, mem->desc);
405     if (strcmp(mem->desc, "flash") == 0)
406       avrdude_message(MSG_INFO, " (did you mean \"application\"?)");
407     avrdude_message(MSG_INFO, "\n");
408     return -1;
409   }
410 
411   return flip2_read_memory(FLIP2(pgm)->dfu, mem_unit, addr, value, 1);
412 }
413 
flip2_write_byte(PROGRAMMER * pgm,AVRPART * part,AVRMEM * mem,unsigned long addr,unsigned char value)414 int flip2_write_byte(PROGRAMMER* pgm, AVRPART *part, AVRMEM *mem,
415   unsigned long addr, unsigned char value)
416 {
417   enum flip2_mem_unit mem_unit;
418 
419   if (FLIP2(pgm)->dfu == NULL)
420     return -1;
421 
422   mem_unit = flip2_mem_unit(mem->desc);
423 
424   if (mem_unit == FLIP2_MEM_UNIT_UNKNOWN) {
425     avrdude_message(MSG_INFO, "%s: Error: "
426       "\"%s\" memory not accessible using FLIP",
427       progname, mem->desc);
428     if (strcmp(mem->desc, "flash") == 0)
429       avrdude_message(MSG_INFO, " (did you mean \"application\"?)");
430     avrdude_message(MSG_INFO, "\n");
431     return -1;
432   }
433 
434   return flip2_write_memory(FLIP2(pgm)->dfu, mem_unit, addr, &value, 1);
435 }
436 
flip2_paged_load(PROGRAMMER * pgm,AVRPART * part,AVRMEM * mem,unsigned int page_size,unsigned int addr,unsigned int n_bytes)437 int flip2_paged_load(PROGRAMMER* pgm, AVRPART *part, AVRMEM *mem,
438   unsigned int page_size, unsigned int addr, unsigned int n_bytes)
439 {
440   enum flip2_mem_unit mem_unit;
441   int result;
442 
443   if (FLIP2(pgm)->dfu == NULL)
444     return -1;
445 
446   mem_unit = flip2_mem_unit(mem->desc);
447 
448   if (mem_unit == FLIP2_MEM_UNIT_UNKNOWN) {
449     avrdude_message(MSG_INFO, "%s: Error: "
450       "\"%s\" memory not accessible using FLIP",
451       progname, mem->desc);
452     if (strcmp(mem->desc, "flash") == 0)
453       avrdude_message(MSG_INFO, " (did you mean \"application\"?)");
454     avrdude_message(MSG_INFO, "\n");
455     return -1;
456   }
457 
458   if (n_bytes > INT_MAX) {
459     /* This should never happen, unless the int type is only 16 bits. */
460     avrdude_message(MSG_INFO, "%s: Error: Attempting to read more than %d bytes\n",
461       progname, INT_MAX);
462     exit(1);
463   }
464 
465   result = flip2_read_memory(FLIP2(pgm)->dfu, mem_unit, addr,
466     mem->buf + addr, n_bytes);
467 
468   return (result == 0) ? n_bytes : -1;
469 }
470 
flip2_paged_write(PROGRAMMER * pgm,AVRPART * part,AVRMEM * mem,unsigned int page_size,unsigned int addr,unsigned int n_bytes)471 int flip2_paged_write(PROGRAMMER* pgm, AVRPART *part, AVRMEM *mem,
472   unsigned int page_size, unsigned int addr, unsigned int n_bytes)
473 {
474   enum flip2_mem_unit mem_unit;
475   int result;
476 
477   if (FLIP2(pgm)->dfu == NULL)
478     return -1;
479 
480   mem_unit = flip2_mem_unit(mem->desc);
481 
482   if (mem_unit == FLIP2_MEM_UNIT_UNKNOWN) {
483     avrdude_message(MSG_INFO, "%s: Error: "
484       "\"%s\" memory not accessible using FLIP",
485       progname, mem->desc);
486     if (strcmp(mem->desc, "flash") == 0)
487       avrdude_message(MSG_INFO, " (did you mean \"application\"?)");
488     avrdude_message(MSG_INFO, "\n");
489     return -1;
490   }
491 
492   if (n_bytes > INT_MAX) {
493     /* This should never happen, unless the int type is only 16 bits. */
494     avrdude_message(MSG_INFO, "%s: Error: Attempting to read more than %d bytes\n",
495       progname, INT_MAX);
496     exit(1);
497   }
498 
499   result = flip2_write_memory(FLIP2(pgm)->dfu, mem_unit, addr,
500     mem->buf + addr, n_bytes);
501 
502   return (result == 0) ? n_bytes : -1;
503 }
504 
flip2_read_sig_bytes(PROGRAMMER * pgm,AVRPART * part,AVRMEM * mem)505 int flip2_read_sig_bytes(PROGRAMMER* pgm, AVRPART *part, AVRMEM *mem)
506 {
507   if (FLIP2(pgm)->dfu == NULL)
508     return -1;
509 
510   if (mem->size < sizeof(FLIP2(pgm)->part_sig)) {
511     avrdude_message(MSG_INFO, "%s: Error: Signature read must be at least %u bytes\n",
512       progname, (unsigned int) sizeof(FLIP2(pgm)->part_sig));
513     return -1;
514   }
515 
516   memcpy(mem->buf, FLIP2(pgm)->part_sig, sizeof(FLIP2(pgm)->part_sig));
517   return 0;
518 }
519 
flip2_setup(PROGRAMMER * pgm)520 void flip2_setup(PROGRAMMER * pgm)
521 {
522   pgm->cookie = calloc(1, sizeof(struct flip2));
523 
524   if (pgm->cookie == NULL) {
525     avrdude_message(MSG_INFO, "%s: Out of memory allocating private data structure\n",
526             progname);
527     exit(1);
528   }
529 }
530 
flip2_teardown(PROGRAMMER * pgm)531 void flip2_teardown(PROGRAMMER * pgm)
532 {
533   free(pgm->cookie);
534   pgm->cookie = NULL;
535 }
536 
537 /* INTERNAL FUNCTION DEFINITIONS
538  */
539 
flip2_show_info(struct flip2 * flip2)540 void flip2_show_info(struct flip2 *flip2)
541 {
542   dfu_show_info(flip2->dfu);
543 
544   avrdude_message(MSG_INFO, "    Part signature      : 0x%02X%02X%02X\n",
545     (int) flip2->part_sig[0],
546     (int) flip2->part_sig[1],
547     (int) flip2->part_sig[2]);
548 
549   if (flip2->part_rev < 26)
550     avrdude_message(MSG_INFO, "    Part revision       : %c\n",
551       (char) (flip2->part_rev + 'A'));
552   else
553     avrdude_message(MSG_INFO, "    Part revision       : %c%c\n",
554       (char) (flip2->part_rev / 26 - 1 + 'A'),
555       (char) (flip2->part_rev % 26 + 'A'));
556 
557   avrdude_message(MSG_INFO, "    Bootloader version  : 2.%hu.%hu\n",
558     ((unsigned short) flip2->boot_ver >> 4) & 0xF,
559     ((unsigned short) flip2->boot_ver >> 0) & 0xF);
560 
561   avrdude_message(MSG_INFO, "    USB max packet size : %hu\n",
562     (unsigned short) flip2->dfu->dev_desc.bMaxPacketSize0);
563 }
564 
flip2_read_memory(struct dfu_dev * dfu,enum flip2_mem_unit mem_unit,uint32_t addr,void * ptr,int size)565 int flip2_read_memory(struct dfu_dev *dfu,
566   enum flip2_mem_unit mem_unit, uint32_t addr, void *ptr, int size)
567 {
568   unsigned short prev_page_addr;
569   unsigned short page_addr;
570   const char * mem_name;
571   int read_size;
572   int result;
573 
574   avrdude_message(MSG_NOTICE2, "%s: flip_read_memory(%s, 0x%04x, %d)\n",
575                   progname, flip2_mem_unit_str(mem_unit), addr, size);
576 
577   result = flip2_set_mem_unit(dfu, mem_unit);
578 
579   if (result != 0) {
580     if ((mem_name = flip2_mem_unit_str(mem_unit)) != NULL)
581       avrdude_message(MSG_INFO, "%s: Error: Failed to set memory unit 0x%02X (%s)\n",
582         progname, (int) mem_unit, mem_name);
583     else
584       avrdude_message(MSG_INFO, "%s: Error: Failed to set memory unit 0x%02X\n",
585         progname, (int) mem_unit);
586     return -1;
587   }
588 
589   page_addr = addr >> 16;
590   result = flip2_set_mem_page(dfu, page_addr);
591 
592   if (result != 0) {
593     avrdude_message(MSG_INFO, "%s: Error: Failed to set memory page 0x%04hX\n",
594         progname, page_addr);
595     return -1;
596   }
597 
598   while (size > 0) {
599     prev_page_addr = page_addr;
600     page_addr = addr >> 16;
601 
602     if (page_addr != prev_page_addr) {
603       result = flip2_set_mem_page(dfu, page_addr);
604       if (result != 0) {
605         avrdude_message(MSG_INFO, "%s: Error: Failed to set memory page 0x%04hX\n",
606             progname, page_addr);
607         return -1;
608       }
609     }
610 
611     read_size = (size > 0x400) ? 0x400 : size;
612     result = flip2_read_max1k(dfu, addr & 0xFFFF, ptr, read_size);
613 
614     if (result != 0) {
615       avrdude_message(MSG_INFO, "%s: Error: Failed to read 0x%04X bytes at 0x%04lX\n",
616           progname, read_size, (unsigned long) addr);
617       return -1;
618     }
619 
620     ptr += read_size;
621     addr += read_size;
622     size -= read_size;
623   }
624 
625   return 0;
626 }
627 
flip2_write_memory(struct dfu_dev * dfu,enum flip2_mem_unit mem_unit,uint32_t addr,const void * ptr,int size)628 int flip2_write_memory(struct dfu_dev *dfu,
629   enum flip2_mem_unit mem_unit, uint32_t addr, const void *ptr, int size)
630 {
631   unsigned short prev_page_addr;
632   unsigned short page_addr;
633   const char * mem_name;
634   int write_size;
635   int result;
636 
637   avrdude_message(MSG_NOTICE2, "%s: flip_write_memory(%s, 0x%04x, %d)\n",
638                   progname, flip2_mem_unit_str(mem_unit), addr, size);
639 
640   result = flip2_set_mem_unit(dfu, mem_unit);
641 
642   if (result != 0) {
643     if ((mem_name = flip2_mem_unit_str(mem_unit)) != NULL)
644       avrdude_message(MSG_INFO, "%s: Error: Failed to set memory unit 0x%02X (%s)\n",
645         progname, (int) mem_unit, mem_name);
646     else
647       avrdude_message(MSG_INFO, "%s: Error: Failed to set memory unit 0x%02X\n",
648         progname, (int) mem_unit);
649     return -1;
650   }
651 
652   page_addr = addr >> 16;
653   result = flip2_set_mem_page(dfu, page_addr);
654 
655   if (result != 0) {
656     avrdude_message(MSG_INFO, "%s: Error: Failed to set memory page 0x%04hX\n",
657         progname, page_addr);
658     return -1;
659   }
660 
661   while (size > 0) {
662     prev_page_addr = page_addr;
663     page_addr = addr >> 16;
664 
665     if (page_addr != prev_page_addr) {
666       result = flip2_set_mem_page(dfu, page_addr);
667       if (result != 0) {
668         avrdude_message(MSG_INFO, "%s: Error: Failed to set memory page 0x%04hX\n",
669             progname, page_addr);
670         return -1;
671       }
672     }
673 
674     write_size = (size > 0x800) ? 0x800 : size;
675     result = flip2_write_max1k(dfu, addr & 0xFFFF, ptr, write_size);
676 
677     if (result != 0) {
678       avrdude_message(MSG_INFO, "%s: Error: Failed to write 0x%04X bytes at 0x%04lX\n",
679           progname, write_size, (unsigned long) addr);
680       return -1;
681     }
682 
683     ptr += write_size;
684     addr += write_size;
685     size -= write_size;
686   }
687 
688   return 0;
689 }
690 
flip2_set_mem_unit(struct dfu_dev * dfu,enum flip2_mem_unit mem_unit)691 int flip2_set_mem_unit(struct dfu_dev *dfu, enum flip2_mem_unit mem_unit)
692 {
693   struct dfu_status status;
694   int cmd_result = 0;
695   int aux_result;
696 
697   struct flip2_cmd cmd = {
698     FLIP2_CMD_GROUP_SELECT, FLIP2_CMD_SELECT_MEMORY, { 0, 0, 0, 0 }
699   };
700 
701   cmd.args[0] = FLIP2_SELECT_MEMORY_UNIT;
702   cmd.args[1] = mem_unit;
703 
704   cmd_result = dfu_dnload(dfu, &cmd, sizeof(cmd));
705 
706   aux_result = dfu_getstatus(dfu, &status);
707 
708   if (aux_result != 0)
709     return aux_result;
710 
711   if (status.bStatus != DFU_STATUS_OK) {
712     if (status.bStatus == ((FLIP2_STATUS_OUTOFRANGE >> 8) & 0xFF) &&
713         status.bState == ((FLIP2_STATUS_OUTOFRANGE >> 0) & 0xFF))
714     {
715       avrdude_message(MSG_INFO, "%s: Error: Unknown memory unit (0x%02x)\n",
716         progname, (unsigned int) mem_unit);
717     } else
718       avrdude_message(MSG_INFO, "%s: Error: DFU status %s\n", progname,
719         flip2_status_str(&status));
720     dfu_clrstatus(dfu);
721   }
722 
723   return cmd_result;
724 }
725 
flip2_set_mem_page(struct dfu_dev * dfu,unsigned short page_addr)726 int flip2_set_mem_page(struct dfu_dev *dfu,
727   unsigned short page_addr)
728 {
729   struct dfu_status status;
730   int cmd_result = 0;
731   int aux_result;
732 
733   struct flip2_cmd cmd = {
734     FLIP2_CMD_GROUP_SELECT, FLIP2_CMD_SELECT_MEMORY, { 0, 0, 0, 0 }
735   };
736 
737   cmd.args[0] = FLIP2_SELECT_MEMORY_PAGE;
738   cmd.args[1] = (page_addr >> 8) & 0xFF;
739   cmd.args[2] = (page_addr >> 0) & 0xFF;
740 
741   cmd_result = dfu_dnload(dfu, &cmd, sizeof(cmd));
742 
743   aux_result = dfu_getstatus(dfu, &status);
744 
745   if (aux_result != 0)
746     return aux_result;
747 
748   if (status.bStatus != DFU_STATUS_OK) {
749     if (status.bStatus == ((FLIP2_STATUS_OUTOFRANGE >> 8) & 0xFF) &&
750         status.bState == ((FLIP2_STATUS_OUTOFRANGE >> 0) & 0xFF))
751     {
752       avrdude_message(MSG_INFO, "%s: Error: Page address out of range (0x%04hx)\n",
753         progname, page_addr);
754     } else
755       avrdude_message(MSG_INFO, "%s: Error: DFU status %s\n", progname,
756         flip2_status_str(&status));
757     dfu_clrstatus(dfu);
758   }
759 
760   return cmd_result;
761 }
762 
flip2_read_max1k(struct dfu_dev * dfu,unsigned short offset,void * ptr,unsigned short size)763 int flip2_read_max1k(struct dfu_dev *dfu,
764   unsigned short offset, void *ptr, unsigned short size)
765 {
766   struct dfu_status status;
767   int cmd_result = 0;
768   int aux_result;
769 
770   struct flip2_cmd cmd = {
771     FLIP2_CMD_GROUP_UPLOAD, FLIP2_CMD_READ_MEMORY, { 0, 0, 0, 0 }
772   };
773 
774   cmd.args[0] = (offset >> 8) & 0xFF;
775   cmd.args[1] = (offset >> 0) & 0xFF;
776   cmd.args[2] = ((offset+size-1) >> 8) & 0xFF;
777   cmd.args[3] = ((offset+size-1) >> 0) & 0xFF;
778 
779   cmd_result = dfu_dnload(dfu, &cmd, sizeof(cmd));
780 
781   if (cmd_result != 0)
782     goto flip2_read_max1k_status;
783 
784   cmd_result = dfu_upload(dfu, (char*) ptr, size);
785 
786 flip2_read_max1k_status:
787 
788   aux_result = dfu_getstatus(dfu, &status);
789 
790   if (aux_result != 0)
791     return aux_result;
792 
793   if (status.bStatus != DFU_STATUS_OK) {
794     if (status.bStatus == ((FLIP2_STATUS_OUTOFRANGE >> 8) & 0xFF) &&
795         status.bState == ((FLIP2_STATUS_OUTOFRANGE >> 0) & 0xFF))
796     {
797       avrdude_message(MSG_INFO, "%s: Error: Address out of range [0x%04hX,0x%04hX]\n",
798         progname, offset, offset+size-1);
799     } else
800       avrdude_message(MSG_INFO, "%s: Error: DFU status %s\n", progname,
801         flip2_status_str(&status));
802     dfu_clrstatus(dfu);
803   }
804 
805   return cmd_result;
806 }
807 
flip2_write_max1k(struct dfu_dev * dfu,unsigned short offset,const void * ptr,unsigned short size)808 int flip2_write_max1k(struct dfu_dev *dfu,
809   unsigned short offset, const void *ptr, unsigned short size)
810 {
811   char buffer[64+64+0x400];
812   unsigned short data_offset;
813   struct dfu_status status;
814   int cmd_result = 0;
815   int aux_result;
816 
817   struct flip2_cmd cmd = {
818     FLIP2_CMD_GROUP_DOWNLOAD, FLIP2_CMD_PROG_START, { 0, 0, 0, 0 }
819   };
820 
821   cmd.args[0] = (offset >> 8) & 0xFF;
822   cmd.args[1] = (offset >> 0) & 0xFF;
823   cmd.args[2] = ((offset+size-1) >> 8) & 0xFF;
824   cmd.args[3] = ((offset+size-1) >> 0) & 0xFF;
825 
826   if (size > 0x400) {
827     avrdude_message(MSG_INFO, "%s: Error: Write block too large (%hu > 1024)\n",
828       progname, size);
829     return -1;
830   }
831 
832   /* There are some special padding requirements for writes. The first packet
833    * must consist only of the FLIP2 command data, which must be padded to
834    * fill out the USB packet (the packet size is given by bMaxPacketSize0 in
835    * the device descriptor). In addition, the data must be padded so that the
836    * first byte of data to be written is at located at position (offset mod
837    * bMaxPacketSize0) within the packet.
838    */
839 
840   data_offset = dfu->dev_desc.bMaxPacketSize0;
841   data_offset += offset % dfu->dev_desc.bMaxPacketSize0;
842 
843   memcpy(buffer, &cmd, sizeof(cmd));
844   memset(buffer + sizeof(cmd), 0, data_offset - sizeof(cmd));
845   memcpy(buffer + data_offset, ptr, size);
846 
847   cmd_result = dfu_dnload(dfu, buffer, data_offset + size);
848 
849   aux_result = dfu_getstatus(dfu, &status);
850 
851   if (aux_result != 0)
852     return aux_result;
853 
854   if (status.bStatus != DFU_STATUS_OK) {
855     if (status.bStatus == ((FLIP2_STATUS_OUTOFRANGE >> 8) & 0xFF) &&
856         status.bState == ((FLIP2_STATUS_OUTOFRANGE >> 0) & 0xFF))
857     {
858       avrdude_message(MSG_INFO, "%s: Error: Address out of range [0x%04hX,0x%04hX]\n",
859         progname, offset, offset+size-1);
860     } else
861       avrdude_message(MSG_INFO, "%s: Error: DFU status %s\n", progname,
862         flip2_status_str(&status));
863     dfu_clrstatus(dfu);
864   }
865 
866   return cmd_result;
867 }
868 
flip2_status_str(const struct dfu_status * status)869 const char * flip2_status_str(const struct dfu_status *status)
870 {
871   unsigned short selector;
872 
873   selector = (unsigned short) status->bStatus << 8;
874   selector |= status->bState;
875 
876   switch (selector) {
877     case FLIP2_STATUS_OK: return "OK";
878     case FLIP2_STATUS_STALL: return "STALL";
879     case FLIP2_STATUS_MEM_UKNOWN: return "MEM_UKNOWN";
880     case FLIP2_STATUS_MEM_PROTECTED: return "MEM_PROTECTED";
881     case FLIP2_STATUS_OUTOFRANGE: return "OUTOFRANGE";
882     case FLIP2_STATUS_BLANK_FAIL: return "BLANK_FAIL";
883     case FLIP2_STATUS_ERASE_ONGOING: return "ERASE_ONGOING";
884     default: return dfu_status_str(status->bStatus);
885   }
886 }
887 
flip2_mem_unit_str(enum flip2_mem_unit mem_unit)888 const char * flip2_mem_unit_str(enum flip2_mem_unit mem_unit)
889 {
890   switch (mem_unit) {
891   case FLIP2_MEM_UNIT_FLASH: return "Flash";
892   case FLIP2_MEM_UNIT_EEPROM: return "EEPROM";
893   case FLIP2_MEM_UNIT_SECURITY: return "security";
894   case FLIP2_MEM_UNIT_CONFIGURATION: return "configuration";
895   case FLIP2_MEM_UNIT_BOOTLOADER: return "bootloader version";
896   case FLIP2_MEM_UNIT_SIGNATURE: return "signature";
897   case FLIP2_MEM_UNIT_USER: return "user";
898   case FLIP2_MEM_UNIT_INT_RAM: return "internal RAM";
899   case FLIP2_MEM_UNIT_EXT_MEM_CS0: return "EXT_MEM_CS0";
900   case FLIP2_MEM_UNIT_EXT_MEM_CS1: return "EXT_MEM_CS1";
901   case FLIP2_MEM_UNIT_EXT_MEM_CS2: return "EXT_MEM_CS2";
902   case FLIP2_MEM_UNIT_EXT_MEM_CS3: return "EXT_MEM_CS3";
903   case FLIP2_MEM_UNIT_EXT_MEM_CS4: return "EXT_MEM_CS4";
904   case FLIP2_MEM_UNIT_EXT_MEM_CS5: return "EXT_MEM_CS5";
905   case FLIP2_MEM_UNIT_EXT_MEM_CS6: return "EXT_MEM_CS6";
906   case FLIP2_MEM_UNIT_EXT_MEM_CS7: return "EXT_MEM_CS7";
907   case FLIP2_MEM_UNIT_EXT_MEM_DF: return "EXT_MEM_DF";
908   default: return "unknown";
909   }
910 }
911 
flip2_mem_unit(const char * name)912 enum flip2_mem_unit flip2_mem_unit(const char *name) {
913   if (strcasecmp(name, "application") == 0)
914     return FLIP2_MEM_UNIT_FLASH;
915   if (strcasecmp(name, "eeprom") == 0)
916     return FLIP2_MEM_UNIT_EEPROM;
917   if (strcasecmp(name, "signature") == 0)
918     return FLIP2_MEM_UNIT_SIGNATURE;
919   return FLIP2_MEM_UNIT_UNKNOWN;
920 }
921 
922 #else /* HAVE_LIBUSB */
923 
924 /* EXPORTED PROGRAMMER FUNCTION DEFINITIONS */
925 
flip2_open(PROGRAMMER * pgm,char * port_spec)926 int flip2_open(PROGRAMMER *pgm, char *port_spec)
927 {
928   fprintf(stderr, "%s: Error: No USB support in this compile of avrdude\n",
929     progname);
930   return -1;
931 }
932 
flip2_initialize(PROGRAMMER * pgm,AVRPART * part)933 int flip2_initialize(PROGRAMMER* pgm, AVRPART *part)
934 {
935   return -1;
936 }
937 
flip2_close(PROGRAMMER * pgm)938 void flip2_close(PROGRAMMER* pgm)
939 {
940 }
941 
flip2_enable(PROGRAMMER * pgm)942 void flip2_enable(PROGRAMMER* pgm)
943 {
944 }
945 
flip2_disable(PROGRAMMER * pgm)946 void flip2_disable(PROGRAMMER* pgm)
947 {
948 }
949 
flip2_display(PROGRAMMER * pgm,const char * prefix)950 void flip2_display(PROGRAMMER* pgm, const char *prefix)
951 {
952 }
953 
flip2_program_enable(PROGRAMMER * pgm,AVRPART * part)954 int flip2_program_enable(PROGRAMMER* pgm, AVRPART *part)
955 {
956   return -1;
957 }
958 
flip2_chip_erase(PROGRAMMER * pgm,AVRPART * part)959 int flip2_chip_erase(PROGRAMMER* pgm, AVRPART *part)
960 {
961   return -1;
962 }
963 
flip2_read_byte(PROGRAMMER * pgm,AVRPART * part,AVRMEM * mem,unsigned long addr,unsigned char * value)964 int flip2_read_byte(PROGRAMMER* pgm, AVRPART *part, AVRMEM *mem,
965   unsigned long addr, unsigned char *value)
966 {
967   return -1;
968 }
969 
flip2_write_byte(PROGRAMMER * pgm,AVRPART * part,AVRMEM * mem,unsigned long addr,unsigned char value)970 int flip2_write_byte(PROGRAMMER* pgm, AVRPART *part, AVRMEM *mem,
971   unsigned long addr, unsigned char value)
972 {
973   return -1;
974 }
975 
flip2_paged_load(PROGRAMMER * pgm,AVRPART * part,AVRMEM * mem,unsigned int page_size,unsigned int addr,unsigned int n_bytes)976 int flip2_paged_load(PROGRAMMER* pgm, AVRPART *part, AVRMEM *mem,
977   unsigned int page_size, unsigned int addr, unsigned int n_bytes)
978 {
979   return -1;
980 }
981 
flip2_paged_write(PROGRAMMER * pgm,AVRPART * part,AVRMEM * mem,unsigned int page_size,unsigned int addr,unsigned int n_bytes)982 int flip2_paged_write(PROGRAMMER* pgm, AVRPART *part, AVRMEM *mem,
983   unsigned int page_size, unsigned int addr, unsigned int n_bytes)
984 {
985   return -1;
986 }
987 
flip2_read_sig_bytes(PROGRAMMER * pgm,AVRPART * part,AVRMEM * mem)988 int flip2_read_sig_bytes(PROGRAMMER* pgm, AVRPART *part, AVRMEM *mem)
989 {
990   return -1;
991 }
992 
flip2_setup(PROGRAMMER * pgm)993 void flip2_setup(PROGRAMMER * pgm)
994 {
995 }
996 
flip2_teardown(PROGRAMMER * pgm)997 void flip2_teardown(PROGRAMMER * pgm)
998 {
999 }
1000 
1001 
1002 #endif /* HAVE_LIBUSB */
1003