summaryrefslogtreecommitdiffstats
path: root/usbblaster_spi.c
diff options
context:
space:
mode:
Diffstat (limited to 'usbblaster_spi.c')
-rw-r--r--usbblaster_spi.c140
1 files changed, 76 insertions, 64 deletions
diff --git a/usbblaster_spi.c b/usbblaster_spi.c
index 58a8a0e3d..43acaad8e 100644
--- a/usbblaster_spi.c
+++ b/usbblaster_spi.c
@@ -30,8 +30,6 @@
* See also the USB-Blaster Download Cable User Guide: http://www.altera.com/literature/ug/ug_usb_blstr.pdf
*/
-#if CONFIG_USBBLASTER_SPI == 1
-
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
@@ -45,15 +43,15 @@
#define ALTERA_VID 0x09fb
#define ALTERA_USBBLASTER_PID 0x6001
-const struct dev_entry devs_usbblasterspi[] = {
+static const struct dev_entry devs_usbblasterspi[] = {
{ALTERA_VID, ALTERA_USBBLASTER_PID, OK, "Altera", "USB-Blaster"},
{0}
};
-static const struct spi_master spi_master_usbblaster;
-
-static struct ftdi_context ftdic;
+struct usbblaster_spi_data {
+ struct ftdi_context ftdic;
+};
// command bytes
#define BIT_BYTE (1<<7) // byte mode (rather than bitbang)
@@ -72,56 +70,10 @@ static uint8_t reverse(uint8_t b)
return ((b * 0x0802LU & 0x22110LU) | (b * 0x8020LU & 0x88440LU)) * 0x10101LU >> 16;
}
-
-/* Returns 0 upon success, a negative number upon errors. */
-int usbblaster_spi_init(void)
+static int send_write(unsigned int writecnt, const unsigned char *writearr, struct ftdi_context ftdic)
{
- uint8_t buf[BUF_SIZE + 1];
-
- if (ftdi_init(&ftdic) < 0)
- return -1;
-
- if (ftdi_usb_open(&ftdic, ALTERA_VID, ALTERA_USBBLASTER_PID) < 0) {
- msg_perr("Failed to open USB-Blaster: %s\n", ftdic.error_str);
- return -1;
- }
-
- if (ftdi_usb_reset(&ftdic) < 0) {
- msg_perr("USB-Blaster reset failed\n");
- return -1;
- }
-
- if (ftdi_set_latency_timer(&ftdic, 2) < 0) {
- msg_perr("USB-Blaster set latency timer failed\n");
- return -1;
- }
+ uint8_t buf[BUF_SIZE] = { 0 };
- if (ftdi_write_data_set_chunksize(&ftdic, 4096) < 0 ||
- ftdi_read_data_set_chunksize(&ftdic, BUF_SIZE) < 0) {
- msg_perr("USB-Blaster set chunk size failed\n");
- return -1;
- }
-
- memset(buf, 0, sizeof(buf));
- buf[sizeof(buf)-1] = BIT_LED | BIT_CS;
- if (ftdi_write_data(&ftdic, buf, sizeof(buf)) < 0) {
- msg_perr("USB-Blaster reset write failed\n");
- return -1;
- }
- if (ftdi_read_data(&ftdic, buf, sizeof(buf)) < 0) {
- msg_perr("USB-Blaster reset read failed\n");
- return -1;
- }
-
- register_spi_master(&spi_master_usbblaster);
- return 0;
-}
-
-static int send_write(unsigned int writecnt, const unsigned char *writearr)
-{
- uint8_t buf[BUF_SIZE];
-
- memset(buf, 0, sizeof(buf));
while (writecnt) {
unsigned int i;
unsigned int n_write = min(writecnt, BUF_SIZE - 1);
@@ -142,12 +94,11 @@ static int send_write(unsigned int writecnt, const unsigned char *writearr)
return 0;
}
-static int send_read(unsigned int readcnt, unsigned char *readarr)
+static int send_read(unsigned int readcnt, unsigned char *readarr, struct ftdi_context ftdic)
{
int i;
unsigned int n_read;
- uint8_t buf[BUF_SIZE];
- memset(buf, 0, sizeof(buf));
+ uint8_t buf[BUF_SIZE] = { 0 };
n_read = readcnt;
while (n_read) {
@@ -182,23 +133,24 @@ static int send_read(unsigned int readcnt, unsigned char *readarr)
static int usbblaster_spi_send_command(const struct flashctx *flash, unsigned int writecnt, unsigned int readcnt,
const unsigned char *writearr, unsigned char *readarr)
{
+ struct usbblaster_spi_data *usbblaster_data = flash->mst->spi.data;
uint8_t cmd;
int ret = 0;
cmd = BIT_LED; // asserts /CS
- if (ftdi_write_data(&ftdic, &cmd, 1) < 0) {
+ if (ftdi_write_data(&usbblaster_data->ftdic, &cmd, 1) < 0) {
msg_perr("USB-Blaster enable chip select failed\n");
ret = -1;
}
if (!ret && writecnt)
- ret = send_write(writecnt, writearr);
+ ret = send_write(writecnt, writearr, usbblaster_data->ftdic);
if (!ret && readcnt)
- ret = send_read(readcnt, readarr);
+ ret = send_read(readcnt, readarr, usbblaster_data->ftdic);
cmd = BIT_CS;
- if (ftdi_write_data(&ftdic, &cmd, 1) < 0) {
+ if (ftdi_write_data(&usbblaster_data->ftdic, &cmd, 1) < 0) {
msg_perr("USB-Blaster disable chip select failed\n");
ret = -1;
}
@@ -206,15 +158,75 @@ static int usbblaster_spi_send_command(const struct flashctx *flash, unsigned in
return ret;
}
+static int usbblaster_shutdown(void *data)
+{
+ free(data);
+ return 0;
+}
static const struct spi_master spi_master_usbblaster = {
.max_data_read = 256,
.max_data_write = 256,
.command = usbblaster_spi_send_command,
- .multicommand = default_spi_send_multicommand,
.read = default_spi_read,
.write_256 = default_spi_write_256,
- .write_aai = default_spi_write_aai,
+ .shutdown = usbblaster_shutdown,
};
-#endif
+/* Returns 0 upon success, a negative number upon errors. */
+static int usbblaster_spi_init(const struct programmer_cfg *cfg)
+{
+ uint8_t buf[BUF_SIZE + 1] = { 0 };
+ struct ftdi_context ftdic;
+ struct usbblaster_spi_data *usbblaster_data;
+
+ if (ftdi_init(&ftdic) < 0)
+ return -1;
+
+ if (ftdi_usb_open(&ftdic, ALTERA_VID, ALTERA_USBBLASTER_PID) < 0) {
+ msg_perr("Failed to open USB-Blaster: %s\n", ftdic.error_str);
+ return -1;
+ }
+
+ if (ftdi_usb_reset(&ftdic) < 0) {
+ msg_perr("USB-Blaster reset failed\n");
+ return -1;
+ }
+
+ if (ftdi_set_latency_timer(&ftdic, 2) < 0) {
+ msg_perr("USB-Blaster set latency timer failed\n");
+ return -1;
+ }
+
+ if (ftdi_write_data_set_chunksize(&ftdic, 4096) < 0 ||
+ ftdi_read_data_set_chunksize(&ftdic, BUF_SIZE) < 0) {
+ msg_perr("USB-Blaster set chunk size failed\n");
+ return -1;
+ }
+
+ buf[sizeof(buf)-1] = BIT_LED | BIT_CS;
+ if (ftdi_write_data(&ftdic, buf, sizeof(buf)) < 0) {
+ msg_perr("USB-Blaster reset write failed\n");
+ return -1;
+ }
+ if (ftdi_read_data(&ftdic, buf, sizeof(buf)) < 0) {
+ msg_perr("USB-Blaster reset read failed\n");
+ return -1;
+ }
+
+ usbblaster_data = calloc(1, sizeof(*usbblaster_data));
+ if (!usbblaster_data) {
+ msg_perr("Unable to allocate space for SPI master data\n");
+ return -1;
+ }
+ usbblaster_data->ftdic = ftdic;
+
+ return register_spi_master(&spi_master_usbblaster, usbblaster_data);
+}
+
+const struct programmer_entry programmer_usbblaster_spi = {
+ .name = "usbblaster_spi",
+ .type = USB,
+ .devs.dev = devs_usbblasterspi,
+ .init = usbblaster_spi_init,
+};