1 /*
2  * avrdude - A Downloader/Uploader for AVR device programmers
3  * Copyright (C) 2005 Erik Walthinsen
4  * Copyright (C) 2002-2004 Brian S. Dean <bsd@bsdhome.com>
5  * Copyright (C) 2006 David Moore
6  * Copyright (C) 2006,2007 Joerg Wunsch <j@uriah.heep.sax.de>
7  *
8  * This program is free software; you can redistribute it and/or modify
9  * it under the terms of the GNU General Public License as published by
10  * the Free Software Foundation; either version 2 of the License, or
11  * (at your option) any later version.
12  *
13  * This program is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16  * GNU General Public License for more details.
17  *
18  * You should have received a copy of the GNU General Public License
19  * along with this program. If not, see <http://www.gnu.org/licenses/>.
20  */
21 
22 /* $Id: pickit2.c 2010-05-03 dbrown$ */
23 /* Based on Id: stk500v2.c 836 2009-07-10 22:39:37Z joerg_wunsch */
24 
25 /*
26  * avrdude interface for PicKit2 programmer
27  *
28  * The PicKit2 programmer is a cheap device capable
29  * of 2 (bidirectional data line), 3, 4 wire SPI comms
30  *
31  * The PICkit2 software license doesn't allow the source to be
32  * modified to program other devices - nor can we distribute
33  * their source code. This program is not derived from nor does it
34  * contain any of the pickit2 source and should be exempt from any
35  * licensing issues.
36  *
37  * ISP Pinout (AVR - PICKit2 (pin)):
38  * RST  - VPP/MCLR (1)
39  * VDD  - VDD Target (2) -- possibly optional if AVR self powered
40  * GND  - GND (3)
41  * MISO - PGD (4)
42  * SCLK - PDC (5)
43  * MOSI - AUX (6)
44  */
45 
46 #include "ac_cfg.h"
47 
48 #include <stdio.h>
49 #include <stdlib.h>
50 #include <string.h>
51 #include <inttypes.h>
52 #include <unistd.h>
53 
54 #include "avrdude.h"
55 #include "libavrdude.h"
56 
57 #if defined(HAVE_LIBUSB) || (defined(WIN32NATIVE) && defined(HAVE_LIBHID))
58 
59 #if (defined(WIN32NATIVE) && defined(HAVE_LIBHID))
60 #include <windows.h>
61 #if defined(HAVE_DDK_HIDSDI_H)
62 #  include <ddk/hidsdi.h>
63 #else
64 #  include "my_ddk_hidsdi.h"
65 #endif
66 #include <setupapi.h>
67 #else
68 #if defined(HAVE_USB_H)
69 #  include <usb.h>
70 #elif defined(HAVE_LUSB0_USB_H)
71 #  include <lusb0_usb.h>
72 #else
73 #  error "libusb needs either <usb.h> or <lusb0_usb.h>"
74 #endif
75 #endif
76 
77 #if 0
78 #define DEBUG(...) do { avrdude_message(MSG_DEBUG, __VA_ARGS__); } while(0)
79 #else
80 #define DEBUG(...) ((void)0)
81 #endif
82 
83 #if 0
84 #define DEBUGRECV(...) do { avrdude_message(MSG_DEBUG, __VA_ARGS__); } while(0)
85 #else
86 #define DEBUGRECV(...) ((void)0)
87 #endif
88 
89 #define PICKIT2_VID 0x04d8
90 #define PICKIT2_PID 0x0033
91 
92 #define SPI_MAX_CHUNK (64 - 10)    // max packet size less the command overhead
93 
94 // win32native only:
95 #if (defined(WIN32NATIVE) && defined(HAVE_LIBHID))
96 static HANDLE open_hid(unsigned short vid, unsigned short pid);
usb_strerror()97 const char *usb_strerror()
98 {
99     return "";
100 }
101 #else
102 static int usb_open_device(struct usb_dev_handle **dev, int vid, int pid);
103 //#define INVALID_HANDLE_VALUE NULL
104 #define USB_ERROR_NONE      0
105 #define USB_ERROR_ACCESS    1
106 #define USB_ERROR_NOTFOUND  2
107 #define USB_ERROR_BUSY      16
108 #define USB_ERROR_IO        5
109 #endif  // WIN32NATIVE
110 
111 static int pickit2_write_report(PROGRAMMER *pgm, const unsigned char report[65]);
112 static int pickit2_read_report(PROGRAMMER *pgm, unsigned char report[65]);
113 
114 #ifndef MIN
115 #define MIN(X,Y) ((X) < (Y) ? (X) : (Y))
116 #endif
117 
118 /*
119  * Private data for this programmer.
120  */
121 struct pdata
122 {
123 #if (defined(WIN32NATIVE) && defined(HAVE_LIBHID))
124     HANDLE usb_handle, write_event, read_event;
125 #else
126     struct usb_dev_handle *usb_handle;     // LIBUSB STUFF
127 #endif
128     uint8_t clock_period;  // SPI clock period in us
129     int transaction_timeout;    // usb trans timeout in ms
130 };
131 
132 #define PDATA(pgm) ((struct pdata *)(pgm->cookie))
133 
134 #define CMD_NOP             0x5A
135 #define CMD_GET_VERSION     0x76
136 #define CMD_SET_VDD_4(v)    0xA0, (uint8_t)((v)*2048+672), (uint8_t)(((v)*2048+672)/256), (uint8_t)((v)*36)
137 #define CMD_SET_VPP_4(v)    0xA1, 0x40, (uint8_t)((v)*18.61), (uint8_t)((v)*13)
138 #define CMD_READ_VDD_VPP    0xA3
139 #define CMD_EXEC_SCRIPT_2(len)  0xA6, (len)
140 #define CMD_CLR_DLOAD_BUFF  0xA7
141 #define CMD_DOWNLOAD_DATA_2(len)  0xA8, (len)
142 #define CMD_CLR_ULOAD_BUFF  0xA9
143 #define CMD_UPLOAD_DATA     0xAA
144 #define CMD_UPLOAD_DATA_NO_LEN     0xAC
145 #define CMD_END_OF_BUFFER   0xAD
146 
147 #define SCR_VDD_ON          0xFF
148 #define SCR_VDD_OFF         0xFE
149 #define SCR_VPP_ON          0xFB
150 #define SCR_VPP_OFF         0xFA
151 #define SCR_VPP_PWM_ON      0xF9
152 #define SCR_VPP_PWM_OFF     0xF8
153 #define SCR_MCLR_GND_ON     0xF7
154 #define SCR_MCLR_GND_OFF    0xF6
155 #define SCR_BUSY_LED_ON     0xF5
156 #define SCR_BUSY_LED_OFF    0xF4
157 #define SCR_SET_ICSP_DELAY_2(us) 0xEA,(us)
158 #define SCR_SET_PINS_2(dd, cd, dv, cv) 0xF3, (((cd)!=0) | (((dd)!=0)<<1) | (((cv)!=0)<<2) | (((dv)!=0)<<3))
159 #define SCR_GET_PINS        0xDC
160 #define SCR_LOOP_3(rel, cnt)    0xE9, rel, cnt
161 #define SCR_DELAY_2(sec)    ((sec)>0.0054528?0xE8:0xE7), (uint8_t)((sec)>0.0054528?(.999+(sec)/.00546):(.999+(sec)/.0000213))
162 #define SCR_SET_AUX_2(ad, av)   0xCF, (((ad)!=0) | (((av)!=0)<<1))
163 #define SCR_SPI_SETUP_PINS_4    SCR_SET_PINS_2(1,0,0,0), SCR_SET_AUX_2(0,0)
164 #define SCR_SPI             0xC3
165 #define SCR_SPI_LIT_2(v)    0xC7,(v)
166 
pickit2_setup(PROGRAMMER * pgm)167 static void pickit2_setup(PROGRAMMER * pgm)
168 {
169     if ((pgm->cookie = malloc(sizeof(struct pdata))) == 0)
170     {
171         avrdude_message(MSG_INFO, "%s: pickit2_setup(): Out of memory allocating private data\n",
172                         progname);
173         exit(1);
174     }
175     memset(pgm->cookie, 0, sizeof(struct pdata));
176 
177     PDATA(pgm)->transaction_timeout = 1500;    // default value, may be overridden with -x timeout=ms
178     PDATA(pgm)->clock_period = 10;    // default value, may be overridden with -x clockrate=us or -B or -i
179 }
180 
pickit2_teardown(PROGRAMMER * pgm)181 static void pickit2_teardown(PROGRAMMER * pgm)
182 {
183     free(pgm->cookie);
184 }
185 
pickit2_open(PROGRAMMER * pgm,char * port)186 static int pickit2_open(PROGRAMMER * pgm, char * port)
187 {
188 #if (defined(WIN32NATIVE) && defined(HAVE_LIBHID))
189     PDATA(pgm)->usb_handle = open_hid(PICKIT2_VID, PICKIT2_PID);
190 
191     if (PDATA(pgm)->usb_handle == INVALID_HANDLE_VALUE)
192     {
193         /* no PICkit2 found */
194         avrdude_message(MSG_INFO, "%s: error: could not find PICkit2 with vid=0x%x pid=0x%x\n",
195                         progname, PICKIT2_VID, PICKIT2_PID);
196         return -1;
197     }
198     else
199     {
200         // get the device description while we're at it
201         short buff[PGM_DESCLEN-1], i;
202         HidD_GetProductString(PDATA(pgm)->usb_handle, buff, PGM_DESCLEN-1);
203 
204         // convert from wide chars, but do not overwrite trailing '\0'
205         memset(&(pgm->type), 0, PGM_DESCLEN);
206         for (i = 0; i < (PGM_DESCLEN-1) && buff[i]; i++)
207         {
208             pgm->type[i] = (char)buff[i]; // TODO what about little/big endian???
209         }
210     }
211 #else
212     if (usb_open_device(&(PDATA(pgm)->usb_handle), PICKIT2_VID, PICKIT2_PID) < 0)
213     {
214         /* no PICkit2 found */
215         avrdude_message(MSG_INFO, "%s: error: could not find PICkit2 with vid=0x%x pid=0x%x\n",
216                         progname, PICKIT2_VID, PICKIT2_PID);
217         return -1;
218     }
219 #endif
220 
221     if (pgm->ispdelay > 0)
222     {
223         PDATA(pgm)->clock_period = MIN(pgm->ispdelay, 255);
224     }
225     else if (pgm->bitclock > 0.0)
226     {
227         PDATA(pgm)->clock_period = MIN(pgm->bitclock * 1e6, 255);
228     }
229 
230     return 0;
231 }
232 
233 
pickit2_close(PROGRAMMER * pgm)234 static void pickit2_close(PROGRAMMER * pgm)
235 {
236 #if (defined(WIN32NATIVE) && defined(HAVE_LIBHID))
237     CloseHandle(PDATA(pgm)->usb_handle);
238     CloseHandle(PDATA(pgm)->read_event);
239     CloseHandle(PDATA(pgm)->write_event);
240 #else
241     usb_close(PDATA(pgm)->usb_handle);
242 #endif  // WIN32NATIVE
243 }
244 
245 
pickit2_initialize(PROGRAMMER * pgm,AVRPART * p)246 static int pickit2_initialize(PROGRAMMER * pgm, AVRPART * p)
247 {
248     unsigned char temp[4];
249     memset(temp, 0, sizeof(temp));
250 
251     int errorCode = 0;
252 
253     /* set sck period */
254     if (pgm->set_sck_period)
255         pgm->set_sck_period(pgm, pgm->bitclock);
256 
257     /* connect to target device -- we'll just ask for the firmware version */
258     static const unsigned char report[65] = {0, CMD_GET_VERSION, CMD_END_OF_BUFFER};
259     if ((errorCode = pickit2_write_report(pgm, report)) > 0)
260     {
261         unsigned char report[65] = {0};
262         //memset(report, 0, sizeof(report));
263         if ((errorCode = pickit2_read_report(pgm, report)) >= 4)
264         {
265             avrdude_message(MSG_NOTICE, "%s: %s firmware version %d.%d.%d\n", progname, pgm->desc, (int)report[1], (int)report[2], (int)report[3]);
266 
267             // set the pins, apply reset,
268             // TO DO: apply vtarget (if requested though -x option)
269             unsigned char report[65] =
270             {
271                 0, CMD_SET_VDD_4(5),
272                 CMD_SET_VPP_4(5),
273                 CMD_EXEC_SCRIPT_2(24),
274                 SCR_SPI_SETUP_PINS_4,   // SDO, SDI, SCK
275                 SCR_SET_ICSP_DELAY_2(PDATA(pgm)->clock_period),    // slow down the SPI
276                 SCR_VDD_ON,
277                 SCR_MCLR_GND_OFF,       // let reset float high
278                 SCR_VPP_PWM_ON,
279                 SCR_DELAY_2(.1),
280                 SCR_VPP_ON,
281                 SCR_DELAY_2(.1),
282                 SCR_VPP_OFF,
283                 SCR_DELAY_2(.01),
284 
285                 SCR_MCLR_GND_ON,        // reset low - programming mode
286                 SCR_DELAY_2(.1),
287 
288                 SCR_BUSY_LED_ON,
289                 SCR_DELAY_2(.3),
290                 SCR_BUSY_LED_OFF,
291 
292                 CMD_CLR_DLOAD_BUFF,
293                 CMD_CLR_ULOAD_BUFF,
294 
295                 CMD_END_OF_BUFFER
296             };
297 
298             if (pickit2_write_report(pgm, report) < 0)
299             {
300                 avrdude_message(MSG_INFO, "pickit2_read_report failed (ec %d). %s\n", errorCode, usb_strerror());
301                 return -1;
302             }
303         }
304         else
305         {
306             avrdude_message(MSG_INFO, "pickit2_read_report failed (ec %d). %s\n", errorCode, usb_strerror());
307             return -1;
308         }
309     }
310     else
311     {
312         avrdude_message(MSG_INFO, "pickit2_write_report failed (ec %d). %s\n", errorCode, usb_strerror());
313         return -1;
314     }
315 
316     if (pgm->program_enable)
317         return pgm->program_enable(pgm, p);
318     else
319         return -1;
320 }
321 
pickit2_disable(PROGRAMMER * pgm)322 static void pickit2_disable(PROGRAMMER * pgm)
323 {
324     /* make sure all pins are floating & all voltages are off */
325     static const unsigned char report[65] =
326     {
327         0, CMD_EXEC_SCRIPT_2(8),
328         SCR_SET_PINS_2(1,1,0,0),
329         SCR_SET_AUX_2(1,0),
330         SCR_MCLR_GND_OFF,
331         SCR_VPP_OFF,
332         SCR_VDD_OFF,
333         SCR_BUSY_LED_OFF,
334         CMD_END_OF_BUFFER
335     };
336 
337     pickit2_write_report(pgm, report);
338 
339     return;
340 }
341 
pickit2_enable(PROGRAMMER * pgm)342 static void pickit2_enable(PROGRAMMER * pgm)
343 {
344     /* Do nothing. */
345 
346     return;
347 }
348 
pickit2_display(PROGRAMMER * pgm,const char * p)349 static void pickit2_display(PROGRAMMER * pgm, const char * p)
350 {
351     DEBUG( "%s: Found \"%s\" version %d.%d.%d\n", progname, p, 1, 1, 1);
352     return;
353 }
354 
355 #define sendReport(x)
356 #define readReport(x) 0
357 
358 #if 0
359 static int  pickit2_rdy_led        (struct programmer_t * pgm, int value)
360 {
361     // no rdy led
362     return 0;
363 }
364 
365 static int  pickit2_err_led(struct programmer_t * pgm, int value)
366 {
367     // there is no error led, so just flash the busy led a few times
368     uint8_t report[65] =
369     {
370         0, CMD_EXEC_SCRIPT_2(9),
371         SCR_BUSY_LED_ON,
372         SCR_DELAY_2(.2),
373         SCR_BUSY_LED_OFF,
374         SCR_DELAY_2(.2),
375         SCR_LOOP_3(6, 9),
376         CMD_END_OF_BUFFER
377     };
378 
379     // busy stops flashing by itself, so just return
380     if (!value)
381     {
382         return 0;
383     }
384 
385     return pickit2_write_report(pgm, report) != -1;
386 }
387 #endif
388 
pickit2_pgm_led(struct programmer_t * pgm,int value)389 static int  pickit2_pgm_led (struct programmer_t * pgm, int value)
390 {
391     // script to set busy led appropriately
392     uint8_t report[65] = {0, CMD_EXEC_SCRIPT_2(1),
393                         value ? SCR_BUSY_LED_ON : SCR_BUSY_LED_OFF,
394                         CMD_END_OF_BUFFER
395                        };
396 
397     return pickit2_write_report(pgm, report) != -1;
398 }
399 
pickit2_vfy_led(struct programmer_t * pgm,int value)400 static int  pickit2_vfy_led        (struct programmer_t * pgm, int value)
401 {
402     // no such thing - maybe just call pgm_led
403 
404     return pgm->pgm_led(pgm, value);
405 }
406 
pickit2_powerup(struct programmer_t * pgm)407 static void pickit2_powerup(struct programmer_t * pgm)
408 {
409     // turn vdd on?
410 }
411 
pickit2_powerdown(struct programmer_t * pgm)412 static void pickit2_powerdown(struct programmer_t * pgm)
413 {
414     // do what?
415     pgm->disable(pgm);
416 }
417 
pickit2_program_enable(struct programmer_t * pgm,AVRPART * p)418 static int  pickit2_program_enable(struct programmer_t * pgm, AVRPART * p)
419 {
420     unsigned char cmd[4];
421     unsigned char res[4];
422 
423     if (p->op[AVR_OP_PGM_ENABLE] == NULL)
424     {
425         avrdude_message(MSG_INFO, "program enable instruction not defined for part \"%s\"\n",
426                 p->desc);
427         return -1;
428     }
429 
430     memset(cmd, 0, sizeof(cmd));
431     avr_set_bits(p->op[AVR_OP_PGM_ENABLE], cmd);
432     pgm->cmd(pgm, cmd, res);
433 
434     {
435         int i;
436         avrdude_message(MSG_DEBUG, "program_enable(): sending command. Resp = ");
437 
438         for (i = 0; i < 4; i++)
439         {
440             avrdude_message(MSG_DEBUG, "%x ", (int)res[i]);
441         }
442         avrdude_message(MSG_DEBUG, "\n");
443     }
444 
445     // check for sync character
446     if (res[2] != cmd[1])
447         return -2;
448 
449     return 0;
450 }
451 
pickit2_chip_erase(struct programmer_t * pgm,AVRPART * p)452 static int  pickit2_chip_erase(struct programmer_t * pgm, AVRPART * p)
453 {
454     unsigned char cmd[4];
455     unsigned char res[4];
456 
457     if (p->op[AVR_OP_CHIP_ERASE] == NULL)
458     {
459         avrdude_message(MSG_INFO, "chip erase instruction not defined for part \"%s\"\n",
460                 p->desc);
461         return -1;
462     }
463 
464     pgm->pgm_led(pgm, ON);
465 
466     memset(cmd, 0, sizeof(cmd));
467 
468     avr_set_bits(p->op[AVR_OP_CHIP_ERASE], cmd);
469     pgm->cmd(pgm, cmd, res);
470     usleep(p->chip_erase_delay);
471     pgm->initialize(pgm, p);
472 
473     pgm->pgm_led(pgm, OFF);
474 
475     return 0;
476 }
477 
pickit2_paged_load(PROGRAMMER * pgm,AVRPART * p,AVRMEM * mem,unsigned int page_size,unsigned int addr,unsigned int n_bytes)478 static int  pickit2_paged_load(PROGRAMMER * pgm, AVRPART * p, AVRMEM * mem,
479                         unsigned int page_size, unsigned int addr, unsigned int n_bytes)
480 {
481     // only supporting flash & eeprom page reads
482     if ((!mem->paged || page_size <= 1) || (strcmp(mem->desc, "flash") != 0 && strcmp(mem->desc, "eeprom") != 0))
483     {
484         return -1;
485     }
486 
487     DEBUG( "paged read ps %d, mem %s\n", page_size, mem->desc);
488 
489     OPCODE *readop = 0, *lext = mem->op[AVR_OP_LOAD_EXT_ADDR];
490     uint8_t data = 0, cmd[SPI_MAX_CHUNK], res[SPI_MAX_CHUNK];
491     unsigned int addr_base;
492     unsigned int max_addr = addr + n_bytes;
493 
494     pgm->pgm_led(pgm, ON);
495 
496     for (addr_base = addr; addr_base < max_addr; )
497     {
498         if ((addr_base == 0 || (addr_base % /*ext_address_boundary*/ 65536) == 0)
499                 && lext != NULL)
500         {
501             memset(cmd, 0, sizeof(cmd));
502 
503             avr_set_bits(lext, cmd);
504             avr_set_addr(lext, cmd, addr_base);
505             pgm->cmd(pgm, cmd, res);
506         }
507 
508         // bytes to send in the next packet -- not necessary as pickit2_spi() handles breaking up
509         // the data into packets -- but we need to keep transfers frequent so that we can update the
510         // status indicator bar
511         uint32_t blockSize = MIN(65536 - (addr_base % 65536), MIN(max_addr - addr_base, SPI_MAX_CHUNK / 4));
512 
513         memset(cmd, 0, sizeof(cmd));
514         memset(res, 0, sizeof(res));
515 
516         uint8_t addr_off;
517         for (addr_off = 0; addr_off < blockSize; addr_off++)
518         {
519             int addr = addr_base + addr_off, caddr = addr;
520 
521             if (mem->op[AVR_OP_READ_LO] != NULL && mem->op[AVR_OP_READ_HI] != NULL)
522             {
523                 if (addr & 0x00000001)
524                     readop = mem->op[AVR_OP_READ_HI];
525                 else
526                     readop = mem->op[AVR_OP_READ_LO];
527 
528                 caddr /= 2;
529             }
530             else if (mem->op[AVR_OP_READ] != NULL)
531             {
532                 readop = mem->op[AVR_OP_READ];
533             }
534             else
535             {
536                 avrdude_message(MSG_INFO, "no read command specified\n");
537                 return -1;
538             }
539 
540             avr_set_bits(readop, &cmd[addr_off*4]);
541             avr_set_addr(readop, &cmd[addr_off*4], caddr);
542         }
543 
544         int bytes_read = pgm->spi(pgm, cmd, res, blockSize*4);
545 
546         if (bytes_read < 0)
547         {
548             avrdude_message(MSG_INFO, "Failed @ pgm->spi()\n");
549             pgm->err_led(pgm, ON);
550             return -1;
551         }
552 
553         DEBUG( "\npaged_load @ %X, wrote: %d, read: %d bytes\n", addr_base, blockSize*4, bytes_read);
554 
555         for (addr_off = 0; addr_off < bytes_read / 4; addr_off++)
556         {
557             data = 0;
558             avr_get_output(readop, &res[addr_off*4], &data);
559             mem->buf[addr_base + addr_off] = data;
560 
561             DEBUG( "%2X(%c)", (int)data, data<0x20?'.':data);
562         }
563         DEBUG( "\n");
564 
565         addr_base += blockSize;
566     }
567 
568     pgm->pgm_led(pgm, OFF);
569 
570     return n_bytes;
571 }
572 
573 
pickit2_commit_page(PROGRAMMER * pgm,AVRPART * p,AVRMEM * mem,unsigned long addr)574 static int pickit2_commit_page(PROGRAMMER * pgm, AVRPART * p, AVRMEM * mem,
575                         unsigned long addr)
576 {
577     OPCODE * wp, * lext;
578 
579     wp = mem->op[AVR_OP_WRITEPAGE];
580     if (wp == NULL)
581     {
582         avrdude_message(MSG_INFO, "pickit2_commit_page(): memory \"%s\" not configured for page writes\n",
583                         mem->desc);
584         return -1;
585     }
586 
587     // adjust the address if this memory is word-addressable
588     if ((mem->op[AVR_OP_LOADPAGE_LO]) || (mem->op[AVR_OP_READ_LO]))
589         addr /= 2;
590 
591     unsigned char cmd[8];
592     memset(cmd, 0, sizeof(cmd));
593 
594     // use the "load extended address" command, if available
595     lext = mem->op[AVR_OP_LOAD_EXT_ADDR];
596     if (lext != NULL)
597     {
598         avr_set_bits(lext, cmd);
599         avr_set_addr(lext, cmd, addr);
600     }
601 
602     // make up the write page command in the 2nd cmd position
603     avr_set_bits(wp, &cmd[4]);
604     avr_set_addr(wp, &cmd[4], addr);
605 
606     if (lext != NULL)
607     {
608         // write the load extended address cmd && the write_page cmd
609         pgm->spi(pgm, cmd, NULL, 8);
610     }
611     else
612     {
613         // write just the write_page cmd
614         pgm->spi(pgm, &cmd[4], NULL, 4);
615     }
616 
617     // just delay the max (we could do the delay in the PICkit2 if we wanted)
618     usleep(mem->max_write_delay);
619 
620     return 0;
621 }
622 
623 // not actually a paged write, but a bulk/batch write
pickit2_paged_write(PROGRAMMER * pgm,AVRPART * p,AVRMEM * mem,unsigned int page_size,unsigned int addr,unsigned int n_bytes)624 static int  pickit2_paged_write(PROGRAMMER * pgm, AVRPART * p, AVRMEM * mem,
625                          unsigned int page_size, unsigned int addr, unsigned int n_bytes)
626 {
627     // only paged write for flash implemented
628     if (strcmp(mem->desc, "flash") != 0 && strcmp(mem->desc, "eeprom") != 0)
629     {
630         avrdude_message(MSG_INFO, "Part does not support %d paged write of %s\n", page_size, mem->desc);
631         return -1;
632     }
633 
634     DEBUG( "page size %d mem %s supported: %d\n", page_size, mem->desc, mem->paged);
635     DEBUG( "loadpagehi %x, loadpagelow %x, writepage %x\n", (int)mem->op[AVR_OP_LOADPAGE_HI], (int)mem->op[AVR_OP_LOADPAGE_LO], (int)mem->op[AVR_OP_WRITEPAGE]);
636 
637     OPCODE *writeop;
638     uint8_t cmd[SPI_MAX_CHUNK], res[SPI_MAX_CHUNK];
639     unsigned int addr_base;
640     unsigned int max_addr = addr + n_bytes;
641 
642     pgm->pgm_led(pgm, ON);
643 
644     for (addr_base = addr; addr_base < max_addr; )
645     {
646         uint32_t blockSize;
647 
648         if (mem->paged)
649         {
650             blockSize = MIN(page_size - (addr_base % page_size), MIN(max_addr - addr_base, SPI_MAX_CHUNK/4) );     // bytes remaining in page
651         }
652         else
653         {
654             blockSize = 1;
655         }
656 
657         memset(cmd, 0, sizeof(cmd));
658         memset(res, 0, sizeof(res));
659 
660         uint8_t addr_off;
661         for (addr_off = 0; addr_off < blockSize; addr_off++)
662         {
663             int addr = addr_base + addr_off;
664             int caddr = 0;
665 
666             /*
667              * determine which memory opcode to use
668              */
669             if (mem->paged && mem->op[AVR_OP_LOADPAGE_HI] && mem->op[AVR_OP_LOADPAGE_LO])
670             {
671                 if (addr & 0x01)
672                     writeop = mem->op[AVR_OP_LOADPAGE_HI];
673                 else
674                     writeop = mem->op[AVR_OP_LOADPAGE_LO];
675                 caddr = addr / 2;
676             }
677             else if (mem->paged && mem->op[AVR_OP_LOADPAGE_LO])
678             {
679                 writeop = mem->op[AVR_OP_LOADPAGE_LO];
680                 caddr = addr;
681             }
682             else if (mem->op[AVR_OP_WRITE_LO])
683             {
684                 writeop = mem->op[AVR_OP_WRITE_LO];
685                 caddr = addr;       // maybe this should divide by 2 & use the write_high opcode also
686 
687                 avrdude_message(MSG_INFO, "Error AVR_OP_WRITE_LO defined only (where's the HIGH command?)\n");
688                 return -1;
689             }
690             else
691             {
692                 writeop = mem->op[AVR_OP_WRITE];
693                 caddr = addr;
694             }
695 
696             if (writeop == NULL)
697             {
698                 pgm->err_led(pgm, ON);
699                 // not supported!
700                 return -1;
701             }
702 
703             avr_set_bits(writeop, &cmd[addr_off*4]);
704             avr_set_addr(writeop, &cmd[addr_off*4], caddr);
705             avr_set_input(writeop, &cmd[addr_off*4], mem->buf[addr]);
706         }
707 
708         int bytes_read = pgm->spi(pgm, cmd, res, blockSize*4);
709 
710         if (bytes_read < 0)
711         {
712             avrdude_message(MSG_INFO, "Failed @ pgm->spi()\n");
713             pgm->err_led(pgm, ON);
714             return -1;
715         }
716 
717         addr_base += blockSize;
718 
719         // write the page - this function looks after extended address also
720         if (mem->paged && (((addr_base % page_size) == 0) || (addr_base == max_addr)))
721         {
722             DEBUG( "Calling pickit2_commit_page()\n");
723             pickit2_commit_page(pgm, p, mem, addr_base-1);
724         }
725         else if (!mem->paged)
726         {
727             usleep(mem->max_write_delay);
728         }
729     }
730 
731     pgm->pgm_led(pgm, OFF);
732 
733     return n_bytes;
734 }
735 
736 
pickit2_cmd(struct programmer_t * pgm,const unsigned char * cmd,unsigned char * res)737 static int pickit2_cmd(struct programmer_t * pgm, const unsigned char *cmd,
738                 unsigned char *res)
739 {
740     return pgm->spi(pgm, cmd, res, 4);
741 }
742 
743 // breaks up the cmd[] data into  packets & sends to the pickit2. Data shifted in is stored in res[].
pickit2_spi(struct programmer_t * pgm,const unsigned char * cmd,unsigned char * res,int n_bytes)744 static int pickit2_spi(struct programmer_t * pgm, const unsigned char *cmd,
745                 unsigned char *res, int n_bytes)
746 {
747     int retval = 0, temp1 = 0, temp2 = 0, count = n_bytes;
748 
749     while (count > 0)
750     {
751         uint8_t i, blockSize = MIN(count, SPI_MAX_CHUNK);
752         uint8_t report[65] = {0, CMD_DOWNLOAD_DATA_2(blockSize)};
753         uint8_t *repptr = report + 3;
754 
755         memset(report + 3, CMD_END_OF_BUFFER, sizeof(report) - 3);
756 
757         // append some data to write to SPI
758         for (i = 0; i < blockSize; i++)
759         {
760             *repptr++ = *cmd++;
761             count--;    // 1 less byte to pack
762         }
763 
764         if (blockSize == 1)
765         {
766             *repptr++ = 0xa6;       //CMD_EXECUTE_SCRIPT;
767             *repptr++ = 1;
768             *repptr++ = SCR_SPI;
769         }
770         else
771         {
772             *repptr++ = 0xa6;       //CMD_EXECUTE_SCRIPT_2;
773             *repptr++ = 4;
774             *repptr++ = SCR_SPI;
775             *repptr++ = 0xe9;       //SCR_LOOP_3;
776             *repptr++ = 1;
777             *repptr++ = blockSize - 1;
778         }
779 
780         // request the data read to be sent to us
781         *repptr++ = CMD_UPLOAD_DATA;
782 
783         // check return values
784         if ((temp1=pickit2_write_report(pgm, report)) < 0 ||
785                 (temp2=pickit2_read_report(pgm, report)) < 0)
786         {
787             return -1;
788         }/*
789         else
790         {
791             int i;
792             DEBUG( "in spi. wrote %d, read %d\n", temp1, temp2);
793 
794             for (i = 0; i < temp2; i++)
795             {
796                   DEBUG( "%2.2x ", report[i]);
797             }
798 
799             DEBUG( "\n");
800         }*/
801 
802         retval = report[1]; // upload-length field
803         repptr = &report[2];    // actual data starts here
804 
805         if (res)                // copy data if user has specified a storage location
806         {
807             memcpy(res, repptr, retval);
808             res += retval;
809         }
810     }
811 
812     return n_bytes;
813 }
814 
815 #if (defined(WIN32NATIVE) && defined(HAVE_LIBHID))
816 /*
817     Func: open_hid()
818     Desc: finds & opens device having specified VID & PID.
819     Retn: Handle of open device or INVALID_HANDLE_VALUE on fail
820 
821     Note this routine is a modified function from:
822         usbhidiocDlg.cpp : implementation file
823         Project: usbhidioc.cpp
824         Version: 3.0
825         Date: 7/18/05
826         by Jan Axelson (jan@Lvr.com)
827 */
open_hid(unsigned short vid,unsigned short pid)828 static HANDLE open_hid(unsigned short vid, unsigned short pid)
829 {
830     //Use a series of API calls to find a HID with a specified Vendor IF and Product ID.
831     HANDLE                              returnHandle = INVALID_HANDLE_VALUE;
832     HIDD_ATTRIBUTES                     Attributes;
833 //    DWORD                               DeviceUsage;
834     SP_DEVICE_INTERFACE_DATA            devInfoData;
835     BOOL                                LastDevice = FALSE;
836     int                                 MemberIndex = 0;
837     LONG                                Result;
838 
839     // were global, now just local scrap
840     DWORD                               Length = 0;
841     PSP_DEVICE_INTERFACE_DETAIL_DATA    detailData = NULL;
842     HANDLE                              DeviceHandle=NULL;
843     GUID                                HidGuid;
844     HANDLE                              hDevInfo;
845     ULONG                               Required;
846     BOOL                                MyDeviceDetected = 0;
847 
848     /*
849     API function: HidD_GetHidGuid
850     Get the GUID for all system HIDs.
851     Returns: the GUID in HidGuid.
852     */
853 
854     HidD_GetHidGuid(&HidGuid);
855     DEBUG("\nHidD_GetHidGuid returned.\n");
856 
857     /*
858     API function: SetupDiGetClassDevs
859     Returns: a handle to a device information set for all installed devices.
860     Requires: the GUID returned by GetHidGuid.
861     */
862 
863     hDevInfo=SetupDiGetClassDevs
864              (&HidGuid,
865               NULL,
866               NULL,
867               DIGCF_PRESENT|DIGCF_INTERFACEDEVICE);
868 
869     DEBUG("\nSetupDiGetClassDevs returned 0x%x\n", hDevInfo);
870     devInfoData.cbSize = sizeof(devInfoData);
871 
872     //Step through the available devices looking for the one we want.
873     //Quit on detecting the desired device or checking all available devices without success.
874 
875     MemberIndex = 0;
876     LastDevice = FALSE;
877 
878     do
879     {
880         /*
881         API function: SetupDiEnumDeviceInterfaces
882         On return, MyDeviceInterfaceData contains the handle to a
883         SP_DEVICE_INTERFACE_DATA structure for a detected device.
884         Requires:
885         The DeviceInfoSet returned in SetupDiGetClassDevs.
886         The HidGuid returned in GetHidGuid.
887         An index to specify a device.
888         */
889 
890 
891         Result=SetupDiEnumDeviceInterfaces
892                (hDevInfo,
893                 0,
894                 &HidGuid,
895                 MemberIndex,
896                 &devInfoData);
897 
898         DEBUG("\nSetupDiEnumDeviceInterfaces returned 0x%x\n", Result);
899 
900         if (Result != 0)
901         {
902             //A device has been detected, so get more information about it.
903 
904             /*
905             API function: SetupDiGetDeviceInterfaceDetail
906             Returns: an SP_DEVICE_INTERFACE_DETAIL_DATA structure
907             containing information about a device.
908             To retrieve the information, call this function twice.
909             The first time returns the size of the structure in Length.
910             The second time returns a pointer to the data in DeviceInfoSet.
911             Requires:
912             A DeviceInfoSet returned by SetupDiGetClassDevs
913             The SP_DEVICE_INTERFACE_DATA structure returned by SetupDiEnumDeviceInterfaces.
914 
915             The final parameter is an optional pointer to an SP_DEV_INFO_DATA structure.
916             This application doesn't retrieve or use the structure.
917             If retrieving the structure, set
918             MyDeviceInfoData.cbSize = length of MyDeviceInfoData.
919             and pass the structure's address.
920             */
921 
922             //Get the Length value.
923             //The call will return with a "buffer too small" error which can be ignored.
924             Result = SetupDiGetDeviceInterfaceDetail
925                      (hDevInfo,
926                       &devInfoData,
927                       NULL,
928                       0,
929                       &Length,
930                       NULL);
931 
932             DEBUG("\nSetupDiGetDeviceInterfaceDetail returned 0x%x\n", Result);
933 
934             //Allocate memory for the hDevInfo structure, using the returned Length.
935 
936             detailData = (PSP_DEVICE_INTERFACE_DETAIL_DATA)malloc(Length);
937 
938             //Set cbSize in the detailData structure.
939 
940             detailData -> cbSize = sizeof(SP_DEVICE_INTERFACE_DETAIL_DATA);
941 
942             //Call the function again, this time passing it the returned buffer size.
943 
944             Result = SetupDiGetDeviceInterfaceDetail
945                      (hDevInfo,
946                       &devInfoData,
947                       detailData,
948                       Length,
949                       &Required,
950                       NULL);
951 
952             // Open a handle to the device.
953             // To enable retrieving information about a system mouse or keyboard,
954             // don't request Read or Write access for this handle.
955 
956             /*
957             API function: CreateFile
958             Returns: a handle that enables reading and writing to the device.
959             Requires:
960             The DevicePath in the detailData structure
961             returned by SetupDiGetDeviceInterfaceDetail.
962             */
963 
964             DeviceHandle=CreateFile
965                          (detailData->DevicePath,
966                           0,
967                           FILE_SHARE_READ|FILE_SHARE_WRITE,
968                           (LPSECURITY_ATTRIBUTES)NULL,
969                           OPEN_EXISTING,
970                           0,
971                           NULL);
972 
973             DEBUG("CreateFile(): %s\n", detailData->DevicePath);
974             /*
975             API function: HidD_GetAttributes
976             Requests information from the device.
977             Requires: the handle returned by CreateFile.
978             Returns: a HIDD_ATTRIBUTES structure containing
979             the Vendor ID, Product ID, and Product Version Number.
980             Use this information to decide if the detected device is
981             the one we're looking for.
982             */
983 
984             //Set the Size to the number of bytes in the structure.
985 
986             Attributes.Size = sizeof(Attributes);
987 
988             Result = HidD_GetAttributes
989                      (DeviceHandle,
990                       &Attributes);
991 
992             DEBUG("HidD_GetAttributes returned 0x%x\n", Result);
993             DEBUG("VID: %.4X PID: %.4X\n", Attributes.VendorID, Attributes.ProductID);
994 
995             //Is it the desired device?
996             MyDeviceDetected = FALSE;
997             if (Attributes.VendorID == vid)
998             {
999                 if (Attributes.ProductID == pid)
1000                 {
1001                     //Both the Vendor ID and Product ID match.
1002 
1003                     MyDeviceDetected = TRUE;
1004 
1005                     // Get a handle for us to use.
1006 
1007                     returnHandle = CreateFile
1008                                    (detailData->DevicePath,
1009                                     GENERIC_WRITE | GENERIC_READ,
1010                                     FILE_SHARE_READ|FILE_SHARE_WRITE,
1011                                     (LPSECURITY_ATTRIBUTES)NULL,
1012                                     OPEN_EXISTING,
1013                                     FILE_FLAG_OVERLAPPED,
1014                                     NULL);
1015 
1016                 } //if (Attributes.ProductID == ProductID)
1017 
1018                 else
1019                     //The Product ID doesn't match.
1020 
1021                     CloseHandle(DeviceHandle);
1022 
1023             } //if (Attributes.VendorID == VendorID)
1024 
1025             else
1026                 //The Vendor ID doesn't match.
1027 
1028                 CloseHandle(DeviceHandle);
1029 
1030             //Free the memory used by the detailData structure (no longer needed).
1031 
1032             free(detailData);
1033 
1034         }  //if (Result != 0)
1035 
1036         else
1037             //SetupDiEnumDeviceInterfaces returned 0, so there are no more devices to check.
1038 
1039             LastDevice=TRUE;
1040 
1041         //If we haven't found the device yet, and haven't tried every available device,
1042         //try the next one.
1043 
1044         MemberIndex = MemberIndex + 1;
1045 
1046     } //do
1047 
1048     while ((LastDevice == FALSE) && (MyDeviceDetected == FALSE));
1049 
1050     if (MyDeviceDetected == FALSE)
1051         DEBUG("Device not detected\n");
1052     else
1053         DEBUG("Device detected\n");
1054 
1055     //Free the memory reserved for hDevInfo by SetupDiClassDevs.
1056 
1057     DEBUG("Calling SetupDiDestroyDeviceInfoList\n");
1058     SetupDiDestroyDeviceInfoList(hDevInfo);
1059 
1060     return returnHandle;
1061 }
1062 
1063 // simple read with timeout
usb_read_interrupt(PROGRAMMER * pgm,void * buff,int size,int timeout)1064 static int usb_read_interrupt(PROGRAMMER *pgm, void *buff, int size, int timeout)
1065 {
1066     OVERLAPPED ovr;
1067     DWORD bytesRead = 0;
1068 
1069     if (PDATA(pgm)->read_event == NULL)
1070     {
1071         PDATA(pgm)->read_event = CreateEvent(0, 0, 0, 0);
1072     }
1073 
1074     memset(&ovr, 0, sizeof(ovr));
1075     ovr.hEvent = PDATA(pgm)->read_event;
1076 
1077     ReadFile(PDATA(pgm)->usb_handle, buff, size, &bytesRead, &ovr);
1078     if (WaitForSingleObject(PDATA(pgm)->read_event, timeout) == WAIT_TIMEOUT)
1079     {
1080         CancelIo(PDATA(pgm)->usb_handle);
1081         return -1;
1082     }
1083 
1084     GetOverlappedResult(PDATA(pgm)->usb_handle, &ovr, &bytesRead, 0);
1085 
1086     return bytesRead > 0 ? bytesRead : -1;
1087 }
1088 
1089 // simple write with timeout
usb_write_interrupt(PROGRAMMER * pgm,const void * buff,int size,int timeout)1090 static int usb_write_interrupt(PROGRAMMER *pgm, const void *buff, int size, int timeout)
1091 {
1092     OVERLAPPED ovr;
1093     DWORD bytesWritten = 0;
1094 
1095     if (PDATA(pgm)->write_event == NULL)
1096     {
1097         PDATA(pgm)->write_event = CreateEvent(0, 0, 0, 0);
1098     }
1099 
1100     memset(&ovr, 0, sizeof(ovr));
1101     ovr.hEvent = PDATA(pgm)->write_event;
1102 
1103     WriteFile(PDATA(pgm)->usb_handle, buff, size, &bytesWritten, &ovr);
1104     if (WaitForSingleObject(PDATA(pgm)->write_event, timeout) == WAIT_TIMEOUT)
1105     {
1106         CancelIo(PDATA(pgm)->usb_handle);
1107         return -1;
1108     }
1109 
1110     GetOverlappedResult(PDATA(pgm)->usb_handle, &ovr, &bytesWritten, 0);
1111 
1112     return bytesWritten > 0 ? bytesWritten : -1;
1113 }
1114 
pickit2_write_report(PROGRAMMER * pgm,const unsigned char report[65])1115 static int pickit2_write_report(PROGRAMMER * pgm, const unsigned char report[65])
1116 {
1117     return usb_write_interrupt(pgm, report, 65, PDATA(pgm)->transaction_timeout); // XXX
1118 }
1119 
pickit2_read_report(PROGRAMMER * pgm,unsigned char report[65])1120 static int pickit2_read_report(PROGRAMMER * pgm, unsigned char report[65])
1121 {
1122     return usb_read_interrupt(pgm, report, 65, PDATA(pgm)->transaction_timeout);
1123 }
1124 
1125 #else   // WIN32NATIVE
1126 /* taken (modified) from avrdude usbasp.c */
usb_open_device(struct usb_dev_handle ** device,int vendor,int product)1127 static int usb_open_device(struct usb_dev_handle **device, int vendor, int product)
1128 {
1129     struct usb_bus      *bus;
1130     struct usb_device   *dev;
1131     usb_dev_handle      *handle = NULL;
1132     int                 errorCode = USB_ERROR_NOTFOUND;
1133     static int          didUsbInit = 0;
1134 
1135     if (!didUsbInit)
1136     {
1137         didUsbInit = 1;
1138         usb_init();
1139     }
1140     usb_find_busses();
1141     usb_find_devices();
1142     for (bus=usb_get_busses(); bus; bus=bus->next)
1143     {
1144         for (dev=bus->devices; dev; dev=dev->next)
1145         {
1146             DEBUG( "Enumerating device list.. VID: 0x%4.4x, PID: 0x%4.4x\n", dev->descriptor.idVendor, dev->descriptor.idProduct);
1147             if (dev->descriptor.idVendor == vendor && dev->descriptor.idProduct == product)
1148             {
1149                 /* we need to open the device in order to query strings */
1150                 handle = usb_open(dev);
1151                 if (handle == NULL)
1152                 {
1153                     errorCode = USB_ERROR_ACCESS;
1154                     avrdude_message(MSG_INFO, "%s: Warning: cannot open USB device: %s\n", progname, usb_strerror());
1155                     continue;
1156                 }
1157 
1158                 // return with opened device handle
1159                 else
1160                 {
1161                     avrdude_message(MSG_NOTICE, "Device %p seemed to open OK.\n", handle);
1162 
1163                     if ((errorCode = usb_set_configuration(handle, 1)) < 0)
1164                     {
1165                         avrdude_message(MSG_INFO, "Could not set configuration. Error code %d, %s.\n"
1166                                 "You may need to run avrdude as root or set up correct usb port permissions.", errorCode, usb_strerror());
1167                     }
1168 
1169                     if ((errorCode = usb_claim_interface(handle, 0)) < 0)
1170                     {
1171                         avrdude_message(MSG_INFO, "Could not claim interface. Error code %d, %s\n"
1172                                 "You may need to run avrdude as root or set up correct usb port permissions.", errorCode, usb_strerror());
1173                     }
1174 
1175                     errorCode = 0;
1176                     *device = handle;
1177                     return 0;
1178                 }
1179             }
1180         }
1181     }
1182 
1183     return -1;
1184 }
1185 
pickit2_write_report(PROGRAMMER * pgm,const unsigned char report[65])1186 static int pickit2_write_report(PROGRAMMER * pgm, const unsigned char report[65])
1187 {
1188     // endpoint 1 OUT??
1189     return usb_interrupt_write(PDATA(pgm)->usb_handle, USB_ENDPOINT_OUT | 1, (const char*)(report+1), 64, PDATA(pgm)->transaction_timeout);
1190 }
1191 
pickit2_read_report(PROGRAMMER * pgm,unsigned char report[65])1192 static int pickit2_read_report(PROGRAMMER * pgm, unsigned char report[65])
1193 {
1194     // endpoint 1 IN??
1195     return usb_interrupt_read(PDATA(pgm)->usb_handle, USB_ENDPOINT_IN | 1, (char*)(report+1), 64, PDATA(pgm)->transaction_timeout);
1196 }
1197 #endif  // WIN323NATIVE
1198 
pickit2_parseextparams(struct programmer_t * pgm,LISTID extparms)1199 static int  pickit2_parseextparams(struct programmer_t * pgm, LISTID extparms)
1200 {
1201     LNODEID ln;
1202     const char *extended_param;
1203     int rv = 0;
1204 
1205     for (ln = lfirst(extparms); ln; ln = lnext(ln))
1206     {
1207         extended_param = ldata(ln);
1208 
1209         if (strncmp(extended_param, "clockrate=", strlen("clockrate=")) == 0)
1210         {
1211             int clock_rate;
1212             if (sscanf(extended_param, "clockrate=%i", &clock_rate) != 1 || clock_rate <= 0)
1213             {
1214                 avrdude_message(MSG_INFO, "%s: pickit2_parseextparms(): invalid clockrate '%s'\n",
1215                                 progname, extended_param);
1216                 rv = -1;
1217                 continue;
1218             }
1219 
1220             int clock_period = MIN(1000000 / clock_rate, 255);    // max period is 255
1221             clock_rate = (int)(1000000 / (clock_period + 5e-7));    // assume highest speed is 2MHz - should probably check this
1222 
1223             avrdude_message(MSG_NOTICE2, "%s: pickit2_parseextparms(): clockrate set to 0x%02x\n",
1224                                 progname, clock_rate);
1225             PDATA(pgm)->clock_period = clock_period;
1226 
1227             continue;
1228         }
1229 
1230         if (strncmp(extended_param, "timeout=", strlen("timeout=")) == 0)
1231         {
1232             int timeout;
1233             if (sscanf(extended_param, "timeout=%i", &timeout) != 1 || timeout <= 0)
1234             {
1235                 avrdude_message(MSG_INFO, "%s: pickit2_parseextparms(): invalid timeout '%s'\n",
1236                                 progname, extended_param);
1237                 rv = -1;
1238                 continue;
1239             }
1240 
1241             avrdude_message(MSG_NOTICE2, "%s: pickit2_parseextparms(): usb timeout set to 0x%02x\n",
1242                                 progname, timeout);
1243             PDATA(pgm)->transaction_timeout = timeout;
1244 
1245             continue;
1246         }
1247 
1248         avrdude_message(MSG_INFO, "%s: pickit2_parseextparms(): invalid extended parameter '%s'\n",
1249                         progname, extended_param);
1250         rv = -1;
1251     }
1252 
1253     return rv;
1254 }
1255 
1256 
pickit2_initpgm(PROGRAMMER * pgm)1257 void pickit2_initpgm (PROGRAMMER * pgm)
1258 {
1259     /*
1260      * mandatory functions - these are called without checking to see
1261      * whether they are assigned or not
1262      */
1263 
1264     pgm->initialize     = pickit2_initialize;
1265     pgm->display        = pickit2_display;
1266     pgm->enable         = pickit2_enable;
1267     pgm->disable        = pickit2_disable;
1268     pgm->powerup        = pickit2_powerup;
1269     pgm->powerdown      = pickit2_powerdown;
1270     pgm->program_enable = pickit2_program_enable;
1271     pgm->chip_erase     = pickit2_chip_erase;
1272     pgm->open           = pickit2_open;
1273     pgm->close          = pickit2_close;
1274 
1275     pgm->read_byte      = avr_read_byte_default;
1276     pgm->write_byte     = avr_write_byte_default;
1277 
1278     /*
1279      * predefined functions - these functions have a valid default
1280      * implementation. Hence, they don't need to be defined in
1281      * the programmer.
1282      */
1283     //pgm->rdy_led        = pickit2_rdy_led;
1284     //pgm->err_led        = pickit2_err_led;
1285     pgm->pgm_led        = pickit2_pgm_led;
1286     pgm->vfy_led        = pickit2_vfy_led;
1287 
1288     /*
1289      * optional functions - these are checked to make sure they are
1290      * assigned before they are called
1291      */
1292 
1293     pgm->cmd            = pickit2_cmd;
1294     pgm->spi            = pickit2_spi;
1295     pgm->paged_write    = pickit2_paged_write;
1296     pgm->paged_load     = pickit2_paged_load;
1297     //pgm->write_setup    = NULL;
1298     //pgm->read_sig_bytes = NULL;
1299     //pgm->set_vtarget    = NULL;//pickit2_vtarget;
1300     //pgm->set_varef      = NULL;
1301     //pgm->set_fosc       = NULL;
1302     //pgm->perform_osccal = NULL;
1303 
1304     pgm->parseextparams = pickit2_parseextparams;
1305 
1306     pgm->setup          = pickit2_setup;
1307     pgm->teardown       = pickit2_teardown;
1308     // pgm->page_size      = 256;        // not sure what this does... maybe the max page size that the page read/write function can handle
1309 
1310     strncpy(pgm->type, "pickit2", sizeof(pgm->type));
1311 }
1312 #else
pickit2_nousb_open(struct programmer_t * pgm,char * name)1313 static int pickit2_nousb_open (struct programmer_t *pgm, char * name) {
1314     avrdude_message(MSG_INFO,
1315 #ifdef WIN32NATIVE
1316             "%s: error: no usb or hid support. Please compile again with libusb or HID support from Win32 DDK installed.\n",
1317 #else
1318             "%s: error: no usb support. Please compile again with libusb installed.\n",
1319 #endif
1320             progname);
1321 
1322     return -1;
1323 }
1324 
pickit2_initpgm(PROGRAMMER * pgm)1325 void pickit2_initpgm (PROGRAMMER * pgm)
1326 {
1327     /*
1328      * mandatory functions - these are called without checking to see
1329      * whether they are assigned or not
1330      */
1331 
1332     pgm->open           = pickit2_nousb_open;
1333 
1334     strncpy(pgm->type, "pickit2", sizeof(pgm->type));
1335 }
1336 
1337 #endif /* defined(HAVE_LIBUSB) || (defined(WIN32NATIVE) && defined(HAVE_LIBHID)) */
1338 
1339 const char pickit2_desc[] = "Microchip's PICkit2 Programmer";
1340 
1341