diff options
Diffstat (limited to 'usbblaster_spi.c')
-rw-r--r-- | usbblaster_spi.c | 140 |
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, +}; |