On Mon, Jun 2, 2014 at 9:43 PM, Justin Chevrier <[email protected]> wrote:
> Hi Stefan,
>
> Attached is a second revision of my patch. Hopefully it addresses
> everything you pointed out previously! Keep me posted if more work
> needs to be done.
>
> I have attached a log of a write as well.
>
> Thanks again,
>
> Justin
>
> On Fri, May 30, 2014 at 8:27 PM, Stefan Tauner
> <[email protected]> wrote:
>> On Thu, 1 May 2014 13:39:44 -0400
>> Justin Chevrier <[email protected]> wrote:
>>
>>> Very sorry for not replying to your email (thanks for the review by the 
>>> way).
>>>
>>> I do have a newer patch that fixes most if not all of the points you
>>> made, but I've been slacking in going over it one last time and
>>> getting it sent in. I had someone contact me directly around December
>>> and they successfully used this updated patch on their hardware.
>>>
>>> I'll see if I can get the patch brushed up and sent in shortly.
>>>
>>> Thanks for the reminder (ugh, can't believe it's been over one year).
>>
>> Hi Justin,
>>
>> this is just a friendly ping. I am planning to do a stable release in
>> the not too distant future (next few weeks) and would like to include
>> your module if it gets ready by then.
>>
>> --
>> Kind regards/Mit freundlichen Grüßen, Stefan Tauner

Ugh, sorry for the top post and the flashrom.8 junk in the patch.

New version attached.

Justin
Index: Makefile
===================================================================
--- Makefile    (revision 1817)
+++ Makefile    (working copy)
@@ -137,7 +137,7 @@
 else
 override CONFIG_PONY_SPI = no
 endif
-# Dediprog and FT2232 are not supported under DOS (missing USB support).
+# Dediprog, FT2232 and PICkit2 are not supported under DOS (missing USB 
support).
 ifeq ($(CONFIG_DEDIPROG), yes)
 UNSUPPORTED_FEATURES += CONFIG_DEDIPROG=yes
 else
@@ -153,7 +153,12 @@
 else
 override CONFIG_USBBLASTER_SPI = no
 endif
+ifeq ($(CONFIG_PICKIT2_SPI), yes)
+UNSUPPORTED_FEATURES += CONFIG_PICKIT2_SPI=yes
+else
+override CONFIG_PICKIT2_SPI = no
 endif
+endif
 
 # FIXME: Should we check for Cygwin/MSVC as well?
 ifeq ($(TARGET_OS), MinGW)
@@ -271,7 +276,7 @@
 else
 override CONFIG_PONY_SPI = no
 endif
-# Dediprog and FT2232 are not supported with libpayload (missing libusb 
support)
+# Dediprog, FT2232 and PICkit2 are not supported with libpayload (missing 
libusb support)
 ifeq ($(CONFIG_DEDIPROG), yes)
 UNSUPPORTED_FEATURES += CONFIG_DEDIPROG=yes
 else
@@ -287,7 +292,12 @@
 else
 override CONFIG_USBBLASTER_SPI = no
 endif
+ifeq ($(CONFIG_PICKIT2_SPI), yes)
+UNSUPPORTED_FEATURES += CONFIG_PICKIT2_SPI=yes
+else
+override CONFIG_PICKIT2_SPI = no
 endif
+endif
 
 ifneq ($(TARGET_OS), Linux)
 ifeq ($(CONFIG_LINUX_SPI), yes)
@@ -408,6 +418,9 @@
 # Always enable Altera USB-Blaster dongles for now.
 CONFIG_USBBLASTER_SPI ?= yes
 
+# Always enable PICkit2 SPI dongles for now.
+CONFIG_PICKIT2_SPI ?= yes
+
 # Always enable dummy tracing for now.
 CONFIG_DUMMY ?= yes
 
@@ -583,6 +596,12 @@
 PROGRAMMER_OBJS += usbblaster_spi.o
 endif
 
+ifeq ($(CONFIG_PICKIT2_SPI), yes)
+FEATURE_CFLAGS += -D'CONFIG_PICKIT2_SPI=1'
+PROGRAMMER_OBJS += pickit2_spi.o
+NEED_USB := yes
+endif
+
 ifeq ($(NEED_FTDI), yes)
 FTDILIBS := $(shell pkg-config --libs libftdi 2>/dev/null || printf "%s" 
"-lftdi -lusb")
 FEATURE_CFLAGS += $(shell LC_ALL=C grep -q "FT232H := yes" .features && printf 
"%s" "-D'HAVE_FT232H=1'")
Index: flashrom.8.tmpl
===================================================================
--- flashrom.8.tmpl     (revision 1817)
+++ flashrom.8.tmpl     (working copy)
@@ -225,6 +225,8 @@
 .sp
 .BR "* usbblaster_spi" " (for SPI flash ROMs attached to an Altera USB-Blaster 
compatible cable)"
 .sp
+.BR "* pickit2_spi" " (for SPI flash ROMs accessible via Microchip PICkit2)"
+.sp
 Some programmers have optional or mandatory parameters which are described
 in detail in the
 .B PROGRAMMER SPECIFIC INFO
@@ -724,6 +726,34 @@
 .BR 
"http://dangerousprototypes.com/docs/Practical_guide_to_Bus_Pirate_pull-up_resistors
 " .
 Only the external supply voltage (Vpu) is supported as of this writing.
 .SS
+.BR "pickit2_spi " programmer
+.B voltage
+parameter specifies the voltage the PICkit2 should use. The default unit is
+Volt if no unit is specified. You can use
+.BR mV ", " milliVolt ", " V " or " Volt
+as unit specifier. Syntax is
+.sp
+.B "  flashrom \-p pickit2_spi:voltage=value"
+.sp
+where
+.B value
+can be
+.BR 0V ", " 1.8V ", " 2.5V ", " 3.5V
+or the equivalent in mV.
+.sp
+An optional
+.B spispeed
+parameter specifies the frequency of the SPI bus.
+Syntax is
+.sp
+.B "  flashrom \-p pickit2_spi:spispeed=frequency"
+.sp
+where
+.B frequency
+can be
+.BR 250k ", " 333k ", " 500k " or " 1M "
+(in Hz). The default is a frequency of 1 MHz.
+.SS
 .BR "dediprog " programmer
 An optional
 .B voltage
@@ -935,7 +965,7 @@
 .B buspirate_spi
 needs userspace access to a serial port.
 .sp
-.BR dediprog ", " ft2232_spi " and " usbblaster_spi
+.BR dediprog ", " ft2232_spi " and " usbblaster_spi and " pickit2_spi
 need access to the USB device via libusb.
 .sp
 .B dummy
@@ -945,7 +975,7 @@
 .BR gfxnvidia ", " drkaiser ", " satasii ", " satamv ", " atahpt" and " atavia
 have to be run as superuser/root, and need additional raw access permission.
 .sp
-.BR serprog ", " buspirate_spi ", " dediprog ", " usbblaster_spi " and " 
ft2232_spi
+.BR serprog ", " buspirate_spi ", " dediprog ", " usbblaster_spi " and " 
ft2232_spi and " pickit2_spi
 can be run as normal user on most operating systems if appropriate device
 permissions are set.
 .sp
Index: flashrom.c
===================================================================
--- flashrom.c  (revision 1817)
+++ flashrom.c  (working copy)
@@ -345,6 +345,19 @@
        },
 #endif
 
+#if CONFIG_PICKIT2_SPI == 1
+       {
+               .name                   = "pickit2_spi",
+               .type                   = OTHER,
+                                       /* FIXME */
+               .devs.note              = "Microchip PICkit2\n",
+               .init                   = pickit2_spi_init,
+               .map_flash_region       = fallback_map,
+               .unmap_flash_region     = fallback_unmap,
+               .delay                  = internal_delay,
+       },
+#endif
+
        {0}, /* This entry corresponds to PROGRAMMER_INVALID. */
 };
 
Index: pickit2_spi.c
===================================================================
--- pickit2_spi.c       (revision 0)
+++ pickit2_spi.c       (working copy)
@@ -0,0 +1,527 @@
+/*
+ * This file is part of the flashrom project.
+ *
+ * Copyright (C) 2010 Carl-Daniel Hailfinger
+ * Copyright (C) 2014 Justin Chevrier
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301 USA
+ */
+
+/*
+ * Connections are as follows:
+ *
+ *      +------+-----+----------+
+ *      | SPI  | Pin | PICkit2  |
+ *      +------+-----+----------+
+ *      | /CS  | 1   | VPP/MCLR |
+ *      | VCC  | 2   | VDD      |
+ *      | GND  | 3   | GND      |
+ *      | MISO | 4   | PGD      |
+ *      | SCLK | 5   | PDC      |
+ *      | MOSI | 6   | AUX      |
+ *      +------+-----+----------+
+ *
+ * Inspiration and some specifics of the interface came via the AVRDude 
+ * PICkit2 code: https://github.com/steve-m/avrdude/blob/master/pickit2.c
+ */
+
+#include <stdio.h>
+#include <string.h>
+#include <limits.h>
+#include <errno.h>
+#include <usb.h>
+#include "flash.h"
+#include "chipdrivers.h"
+#include "programmer.h"
+#include "spi.h"
+
+static usb_dev_handle *pickit2_handle;
+
+/* Default USB transaction timeout in ms */
+#define DEFAULT_TIMEOUT         10000
+
+#define CMD_LENGTH              64
+#define ENDPOINT_OUT            0x01
+#define ENDPOINT_IN             0x81
+
+#define PICKIT2_VID             0x04D8
+#define PICKIT2_PID             0x0033
+
+#define CMD_GET_VERSION         0x76
+#define CMD_SET_VDD             0xA0
+#define CMD_SET_VPP             0xA1
+#define CMD_READ_VDD_VPP        0xA3
+#define CMD_EXEC_SCRIPT         0xA6
+#define CMD_CLR_DLOAD_BUFF      0xA7
+#define CMD_DOWNLOAD_DATA       0xA8
+#define CMD_CLR_ULOAD_BUFF      0xA9
+#define CMD_UPLOAD_DATA         0xAA
+#define CMD_END_OF_BUFFER       0xAD
+
+#define SCR_SPI_READ_BUF        0xC5
+#define SCR_SPI_WRITE_BUF       0xC6
+#define SCR_SET_AUX             0xCF
+#define SCR_LOOP                0xE9
+#define SCR_SET_ICSP_CLK_PERIOD 0xEA
+#define SCR_SET_PINS            0xF3
+#define SCR_BUSY_LED_OFF        0xF4
+#define SCR_BUSY_LED_ON         0xF5
+#define SCR_MCLR_GND_OFF        0xF6
+#define SCR_MCLR_GND_ON         0xF7
+#define SCR_VPP_PWM_OFF         0xF8
+#define SCR_VPP_PWM_ON          0xF9
+#define SCR_VPP_OFF             0xFA
+#define SCR_VPP_ON              0xFB
+#define SCR_VDD_OFF             0xFE
+#define SCR_VDD_ON              0xFF
+
+/* Copied from dediprog.c */
+/* Might be useful for other USB devices as well. static for now. */
+/* device parameter allows user to specify one device of multiple installed */
+static struct usb_device *get_device_by_vid_pid(uint16_t vid, uint16_t pid, 
unsigned int device)
+{
+       struct usb_bus *bus;
+       struct usb_device *dev;
+
+       for (bus = usb_get_busses(); bus; bus = bus->next)
+               for (dev = bus->devices; dev; dev = dev->next)
+                       if ((dev->descriptor.idVendor == vid) &&
+                           (dev->descriptor.idProduct == pid)) {
+                               if (device == 0)
+                                       return dev;
+                               device--;
+                       }
+
+       return NULL;
+}
+
+static int pickit2_get_firmware_version(void)
+{
+       int ret;
+       uint8_t command[CMD_LENGTH] = {CMD_GET_VERSION, CMD_END_OF_BUFFER};
+
+       ret = usb_interrupt_write(pickit2_handle, ENDPOINT_OUT, (char 
*)command, CMD_LENGTH, DEFAULT_TIMEOUT);
+       ret = usb_interrupt_read(pickit2_handle, ENDPOINT_IN, (char *)command, 
CMD_LENGTH, DEFAULT_TIMEOUT);
+       
+       msg_pdbg("PICkit2 Firmware Version: %d.%d\n", (int)command[0], 
(int)command[1]);
+       if (ret != CMD_LENGTH) {
+               msg_perr("Command Get Firmware Version failed (%s)!\n",
+                        usb_strerror());
+               return 1;
+       }
+
+       return 0;
+}
+
+static int pickit2_set_spi_voltage(int millivolt)
+{
+       int ret;
+       double voltage_selector;
+
+       switch (millivolt) {
+       case 0:
+               /* Admittedly this one is an assumption. */
+               voltage_selector = 0;
+               break;
+       case 1800:
+               voltage_selector = 1.8;
+               break;
+       case 2500:
+               voltage_selector = 2.5;
+               break;
+       case 3500:
+               voltage_selector = 3.5;
+               break;
+       default:
+               msg_perr("Unknown voltage %i mV! Aborting.\n", millivolt);
+               return 1;
+       }
+       msg_pdbg("Setting SPI voltage to %u.%03u V\n", millivolt / 1000,
+                millivolt % 1000);
+
+       uint8_t command[CMD_LENGTH] = {
+               CMD_SET_VDD,
+               voltage_selector * 2048 + 672,
+               (voltage_selector * 2048 + 672) / 256,
+               voltage_selector * 36,
+               CMD_SET_VPP,
+               0x40,
+               voltage_selector * 18.61,
+               voltage_selector * 13,
+               CMD_END_OF_BUFFER
+       };
+
+       ret = usb_interrupt_write(pickit2_handle, ENDPOINT_OUT, (char 
*)command, CMD_LENGTH, DEFAULT_TIMEOUT);
+
+       if (ret != CMD_LENGTH) {
+               msg_perr("Command Set Voltage failed (%s)!\n",
+                        usb_strerror());
+               return 1;
+       }
+
+       return 0;
+}
+
+
+struct pickit2_spispeeds {
+       const char *const name;
+       const int speed;
+};
+
+static const struct pickit2_spispeeds spispeeds[] = {
+       { "1M",         0x1 },
+       { "500k",       0x2 },
+       { "333k",       0x3 },
+       { "250k",       0x4 },
+       { NULL,         0x0 },
+};
+
+static int pickit2_set_spi_speed(unsigned int spispeed_idx)
+{
+       int ret;
+
+       msg_pdbg("SPI speed is %sHz\n", spispeeds[spispeed_idx].name);
+
+       uint8_t command[CMD_LENGTH] = {
+               CMD_EXEC_SCRIPT,
+               2,
+               SCR_SET_ICSP_CLK_PERIOD,
+               spispeed_idx,
+               CMD_END_OF_BUFFER
+       };
+
+       ret = usb_interrupt_write(pickit2_handle, ENDPOINT_OUT, (char 
*)command, CMD_LENGTH, DEFAULT_TIMEOUT);
+
+       if (ret != CMD_LENGTH) {
+               msg_perr("Command Set SPI Speed failed (%s)!\n",
+                        usb_strerror());
+               return 1;
+       }
+
+       return 0;
+}
+
+static int pickit2_spi_send_command(struct flashctx *flash,
+                                    unsigned int writecnt,
+                                    unsigned int readcnt,
+                                    const unsigned char *writearr,
+                                    unsigned char *readarr)
+{
+       int ret, i;
+
+       uint8_t buf[CMD_LENGTH] = {CMD_DOWNLOAD_DATA, writecnt};
+
+       /* Maximum number of bytes per transaction (including command overhead) 
is 64. Lets play it safe
+        * and always assume the worst case scenario of 20 bytes command 
overhead.
+        */
+       msg_pspew("%s, writecnt=%i, readcnt=%i\n", __func__, writecnt, readcnt);
+       if (writecnt + readcnt + 20 > CMD_LENGTH) {
+               msg_perr("\nTotal packetsize (%i) is greater than 64 supported, 
aborting.\n", writecnt + readcnt + 20);
+               return 1;
+       }
+
+       for (i = 2; i < writecnt + 2; i++) {
+               buf[i] = writearr[i - 2];
+       }
+
+       buf[i++] = CMD_CLR_ULOAD_BUFF;
+       buf[i++] = CMD_EXEC_SCRIPT;
+
+       /* Determine script length based on number of bytes to be read or 
written */
+       if (writecnt == 1 && readcnt == 1)
+               buf[i++] = 7;
+       else if (writecnt == 1 || readcnt == 1)
+               buf[i++] = 10;
+       else
+               buf[i++] = 13;
+               
+       /* Assert CS# */
+       buf[i++] = SCR_VPP_OFF;
+       buf[i++] = SCR_MCLR_GND_ON;
+
+       buf[i++] = SCR_SPI_WRITE_BUF;
+
+       if (writecnt > 1) {
+               buf[i++] = SCR_LOOP;
+               buf[i++] = 1; /* Loop back one instruction */
+               buf[i++] = writecnt - 1; /* Number of times to loop */
+       }
+
+       if (readcnt)
+               buf[i++] = SCR_SPI_READ_BUF;
+
+       if (readcnt > 1) {
+               buf[i++] = SCR_LOOP;
+               buf[i++] = 1; /* Loop back one instruction */
+               buf[i++] = readcnt - 1; /* Number of times to loop */
+       }
+
+       /* De-assert CS# */
+       buf[i++] = SCR_MCLR_GND_OFF;
+       buf[i++] = SCR_VPP_PWM_ON;
+       buf[i++] = SCR_VPP_ON;
+
+       buf[i++] = CMD_UPLOAD_DATA;
+       buf[i++] = CMD_END_OF_BUFFER;
+
+       ret = usb_interrupt_write(pickit2_handle, ENDPOINT_OUT, (char *)buf, 
CMD_LENGTH, DEFAULT_TIMEOUT);
+
+       if (ret != CMD_LENGTH) {
+               msg_perr("Send SPI failed, expected %i, got %i %s!\n",
+                       writecnt, ret, usb_strerror());
+                       return 1;
+       }
+
+       if (readcnt) {
+               ret = usb_interrupt_read(pickit2_handle, ENDPOINT_IN, (char 
*)buf, CMD_LENGTH, DEFAULT_TIMEOUT);
+
+               if (ret != CMD_LENGTH) {
+                       msg_perr("Receive SPI failed, expected %i, got %i 
%s!\n",
+                               readcnt, ret, usb_strerror());
+                       return 1;
+               }
+
+               /* First byte indicates number of bytes transferred from upload 
buffer */
+               if (buf[0] != readcnt) {
+                       msg_perr("Unexpected number of bytes transferred, 
expected %i, got %i!\n",
+                                readcnt, ret);
+                       return 1;
+               }
+               
+               /* Actual data starts at byte number two */
+               memcpy(readarr, &buf[1], readcnt);
+       }
+
+       return 0;
+}
+
+/* Copied from dediprog.c */
+/* Might be useful for other USB devices as well. static for now. */
+static int parse_voltage(char *voltage)
+{
+       char *tmp = NULL;
+       int i;
+       int millivolt = 0, fraction = 0;
+
+       if (!voltage || !strlen(voltage)) {
+               msg_perr("Empty voltage= specified.\n");
+               return -1;
+       }
+       millivolt = (int)strtol(voltage, &tmp, 0);
+       voltage = tmp;
+       /* Handle "," and "." as decimal point. Everything after it is assumed
+        * to be in decimal notation.
+        */
+       if ((*voltage == '.') || (*voltage == ',')) {
+               voltage++;
+               for (i = 0; i < 3; i++) {
+                       fraction *= 10;
+                       /* Don't advance if the current character is invalid,
+                        * but continue multiplying.
+                        */
+                       if ((*voltage < '0') || (*voltage > '9'))
+                               continue;
+                       fraction += *voltage - '0';
+                       voltage++;
+               }
+               /* Throw away remaining digits. */
+               voltage += strspn(voltage, "0123456789");
+       }
+       /* The remaining string must be empty or "mV" or "V". */
+       tolower_string(voltage);
+
+       /* No unit or "V". */
+       if ((*voltage == '\0') || !strncmp(voltage, "v", 1)) {
+               millivolt *= 1000;
+               millivolt += fraction;
+       } else if (!strncmp(voltage, "mv", 2) ||
+                  !strncmp(voltage, "milliv", 6)) {
+               /* No adjustment. fraction is discarded. */
+       } else {
+               /* Garbage at the end of the string. */
+               msg_perr("Garbage voltage= specified.\n");
+               return -1;
+       }
+       return millivolt;
+}
+
+static const struct spi_programmer spi_programmer_pickit2 = {
+       .type           = SPI_CONTROLLER_PICKIT2,
+       .max_data_read  = 40,
+       .max_data_write = 40,
+       .command        = pickit2_spi_send_command,
+       .multicommand   = default_spi_send_multicommand,
+       .read           = default_spi_read,
+       .write_256      = default_spi_write_256,
+       .write_aai      = default_spi_write_aai,
+};
+
+static int pickit2_shutdown(void *data)
+{
+       int ret;
+       msg_pspew("%s\n", __func__);
+
+       /* Set all pins to float and turn voltages off */
+       uint8_t command[CMD_LENGTH] = {
+               CMD_EXEC_SCRIPT,
+               8,
+               SCR_SET_PINS,
+               /* Bit-0=1(PDC In), Bit-1=1(PGD In), Bit-2=0(PDC LL), 
Bit-3=0(PGD LL) */
+               3,
+               SCR_SET_AUX,
+               /* Bit-0=1(Aux In), Bit-1=0(Aux LL) */
+               1,
+               SCR_MCLR_GND_OFF,
+               SCR_VPP_OFF,
+               SCR_VDD_OFF,
+               SCR_BUSY_LED_OFF,
+               CMD_END_OF_BUFFER
+       };
+
+       ret = usb_interrupt_write(pickit2_handle, ENDPOINT_OUT, (char 
*)command, CMD_LENGTH, DEFAULT_TIMEOUT);
+
+       if (ret != CMD_LENGTH) {
+               msg_perr("Command Shutdown failed (%s)!\n",
+                        usb_strerror());
+               return 1;
+       }
+
+       if (usb_release_interface(pickit2_handle, 0)) {
+               msg_perr("Could not release USB interface!\n");
+               return 1;
+       }
+       if (usb_close(pickit2_handle)) {
+               msg_perr("Could not close USB device!\n");
+               return 1;
+       }
+       return 0;
+}
+
+int pickit2_spi_init(void)
+{
+       struct usb_device *dev;
+       char *voltage, *spispeed;
+       int spispeed_idx = 0;
+       int millivolt = 3500;
+       long usedevice = 0;
+       int i, ret;
+
+       uint8_t buf[CMD_LENGTH] = {
+               CMD_EXEC_SCRIPT,
+               10,                     /* Script length */
+               SCR_SET_PINS,
+               /* Bit-0=0(PDC Out), Bit-1=1(PGD In), Bit-2=0(PDC LL), 
Bit-3=0(PGD LL) */
+               2,
+               SCR_SET_AUX,
+               /* Bit-0=0(Aux Out), Bit-1=0(Aux LL) */
+               0,
+               SCR_VDD_ON,
+               SCR_MCLR_GND_OFF,       /* Let CS# float */
+               SCR_VPP_PWM_ON,
+               SCR_VPP_ON,             /* Pull CS# high */
+               SCR_BUSY_LED_ON,
+               CMD_CLR_DLOAD_BUFF,
+               CMD_CLR_ULOAD_BUFF,
+               CMD_END_OF_BUFFER
+       };
+
+       msg_pspew("%s\n", __func__);
+
+       spispeed = extract_programmer_param("spispeed");
+       if (spispeed) {
+               for (i = 0; spispeeds[i].name; ++i) {
+                       if (!strcasecmp(spispeeds[i].name, spispeed)) {
+                               spispeed_idx = i;
+                               break;
+                       }
+               }
+               if (!spispeeds[i].name) {
+                       msg_perr("Error: Invalid 'spispeed' value.\n");
+                       free(spispeed);
+                       return 1;
+               }
+               free(spispeed);
+       }
+       voltage = extract_programmer_param("voltage");
+       if (voltage) {
+               millivolt = parse_voltage(voltage);
+               free(voltage);
+               if (millivolt < 0)
+                       return 1;
+               msg_pinfo("Setting voltage to %i mV\n", millivolt);
+       }
+
+       /* Here comes the USB stuff */
+       usb_init();
+       usb_find_busses();
+       usb_find_devices();
+       dev = get_device_by_vid_pid(PICKIT2_VID, PICKIT2_PID, (unsigned int) 
usedevice);
+       if (!dev) {
+               msg_perr("Could not find a PICkit2 on USB!\n");
+               return 1;
+       }
+       msg_pdbg("Found USB device (%04x:%04x).\n",
+                dev->descriptor.idVendor, dev->descriptor.idProduct);
+
+       pickit2_handle = usb_open(dev);
+       ret = usb_set_configuration(pickit2_handle, 1);
+       if (ret < 0) {
+               msg_perr("Could not set USB device configuration: %i %s\n",
+                        ret, usb_strerror());
+               if (usb_close(pickit2_handle))
+                       msg_perr("Could not close USB device!\n");
+               return 1;
+       }
+       ret = usb_claim_interface(pickit2_handle, 0);
+       if (ret < 0) {
+               msg_perr("Could not claim USB device interface %i: %i %s\n",
+                        0, ret, usb_strerror());
+               if (usb_close(pickit2_handle))
+                       msg_perr("Could not close USB device!\n");
+               return 1;
+       }
+
+       if (register_shutdown(pickit2_shutdown, NULL))
+               return 1;
+
+       if (pickit2_get_firmware_version()) {
+               return 1;
+       }
+
+       /* Command Set SPI Speed */
+       if (pickit2_set_spi_speed(spispeed_idx)) {
+               return 1;
+       }
+
+       /* Command Set SPI Voltage */
+       if (pickit2_set_spi_voltage(millivolt)) {
+               return 1;
+       }
+
+       /* Perform basic setup */
+       /* Configure pins for correct directions and logic levels,
+        * turn Vdd on, turn busy LED on and clear buffers
+        */
+       ret = usb_interrupt_write(pickit2_handle, ENDPOINT_OUT, (char *)buf, 
CMD_LENGTH, DEFAULT_TIMEOUT);
+
+       if (ret != CMD_LENGTH) {
+               msg_perr("Command Setup failed (%s)!\n",
+                         usb_strerror());
+               return 1;
+       }
+
+       register_spi_programmer(&spi_programmer_pickit2);
+
+       return 0;
+}
Index: programmer.h
===================================================================
--- programmer.h        (revision 1817)
+++ programmer.h        (working copy)
@@ -96,6 +96,9 @@
 #if CONFIG_USBBLASTER_SPI == 1
        PROGRAMMER_USBBLASTER_SPI,
 #endif
+#if CONFIG_PICKIT2_SPI == 1
+       PROGRAMMER_PICKIT2_SPI,
+#endif
        PROGRAMMER_INVALID /* This must always be the last entry. */
 };
 
@@ -464,6 +467,11 @@
 extern const struct dev_entry devs_usbblasterspi[];
 #endif
 
+/* pickit2_spi.c */
+#if CONFIG_PICKIT2_SPI == 1
+int pickit2_spi_init(void);
+#endif
+
 /* rayer_spi.c */
 #if CONFIG_RAYER_SPI == 1
 int rayer_spi_init(void);
@@ -546,6 +554,9 @@
 #if CONFIG_USBBLASTER_SPI == 1
        SPI_CONTROLLER_USBBLASTER,
 #endif
+#if CONFIG_PICKIT2_SPI == 1
+       SPI_CONTROLLER_PICKIT2,
+#endif
 };
 
 #define MAX_DATA_UNSPECIFIED 0
_______________________________________________
flashrom mailing list
[email protected]
http://www.flashrom.org/mailman/listinfo/flashrom

Reply via email to