From c703b380cf0c4cc8817f4cd6690a24256916389e Mon Sep 17 00:00:00 2001 From: Michael Ossmann Date: Fri, 22 Feb 2013 22:20:19 -0700 Subject: [PATCH] SPI flash chip erase USB command, updated hackrf_spiflash.c to operate one page at a time --- firmware/usb_performance/usb_performance.c | 17 ++++++++++++- host/libhackrf/examples/hackrf_spiflash.c | 28 ++++++++++++++++++++-- host/libhackrf/src/hackrf.c | 28 ++++++++++++++++++---- host/libhackrf/src/hackrf.h | 1 + 4 files changed, 67 insertions(+), 7 deletions(-) diff --git a/firmware/usb_performance/usb_performance.c b/firmware/usb_performance/usb_performance.c index ef2fa84b..d9710136 100644 --- a/firmware/usb_performance/usb_performance.c +++ b/firmware/usb_performance/usb_performance.c @@ -369,6 +369,21 @@ usb_request_status_t usb_vendor_request_read_rffc5071( } } +usb_request_status_t usb_vendor_request_erase_spiflash( + usb_endpoint_t* const endpoint, const usb_transfer_stage_t stage) +{ + //FIXME This should refuse to run if executing from SPI flash. + + if (stage == USB_TRANSFER_STAGE_SETUP) { + w25q80bv_setup(); + /* only chip erase is implemented */ + w25q80bv_chip_erase(); + usb_endpoint_schedule_ack(endpoint->in); + //FIXME probably should undo w25q80bv_setup() + } + return USB_REQUEST_STATUS_OK; +} + usb_request_status_t usb_vendor_request_write_spiflash( usb_endpoint_t* const endpoint, const usb_transfer_stage_t stage) { @@ -451,7 +466,6 @@ usb_request_status_t usb_vendor_request_read_board_id( endpoint->buffer[0] = BOARD_ID; usb_endpoint_schedule(endpoint->in, &endpoint->buffer, 1); usb_endpoint_schedule_ack(endpoint->out); - return USB_REQUEST_STATUS_OK; } return USB_REQUEST_STATUS_OK; } @@ -467,6 +481,7 @@ static const usb_request_handler_fn vendor_request_handler[] = { usb_vendor_request_set_baseband_filter_bandwidth, usb_vendor_request_write_rffc5071, usb_vendor_request_read_rffc5071, + usb_vendor_request_erase_spiflash, usb_vendor_request_write_spiflash, usb_vendor_request_read_spiflash, usb_vendor_request_write_cpld, diff --git a/host/libhackrf/examples/hackrf_spiflash.c b/host/libhackrf/examples/hackrf_spiflash.c index d32124c0..4f0749b1 100644 --- a/host/libhackrf/examples/hackrf_spiflash.c +++ b/host/libhackrf/examples/hackrf_spiflash.c @@ -80,11 +80,13 @@ int main(int argc, char** argv) int opt; uint32_t address = 0; uint32_t length = 0; + uint16_t xfer_len = 0; const char* path = NULL; hackrf_device* device = NULL; int result = HACKRF_SUCCESS; int option_index = 0; uint8_t data[MAX_LENGTH]; + uint8_t* pdata = &data[0]; FILE* fd = NULL; bool read = false; bool write = false; @@ -133,6 +135,12 @@ int main(int argc, char** argv) return EXIT_FAILURE; } + if (length == 0) { + fprintf(stderr, "Requested transfer of zero bytes.\n"); + usage(); + return EXIT_FAILURE; + } + if ((length > MAX_LENGTH) || (address > MAX_LENGTH) || ((address + length) > MAX_LENGTH)) { fprintf(stderr, "Request exceeds size of flash memory.\n"); @@ -197,14 +205,30 @@ int main(int argc, char** argv) fd = NULL; return EXIT_FAILURE; } - result = hackrf_spiflash_write(device, address, length, data); + printf("Erasing SPI flash.\n"); + result = hackrf_spiflash_erase(device); if (result != HACKRF_SUCCESS) { - fprintf(stderr, "hackrf_spiflash_write() failed: %s (%d)\n", + fprintf(stderr, "hackrf_spiflash_erase() failed: %s (%d)\n", hackrf_error_name(result), result); fclose(fd); fd = NULL; return EXIT_FAILURE; } + while (length) { + xfer_len = (length > 256) ? 256 : length; + printf("Writing %d bytes at 0x%06x.\n", xfer_len, address); + result = hackrf_spiflash_write(device, address, xfer_len, pdata); + if (result != HACKRF_SUCCESS) { + fprintf(stderr, "hackrf_spiflash_write() failed: %s (%d)\n", + hackrf_error_name(result), result); + fclose(fd); + fd = NULL; + return EXIT_FAILURE; + } + address += xfer_len; + pdata += xfer_len; + length -= xfer_len; + } } result = hackrf_close(device); diff --git a/host/libhackrf/src/hackrf.c b/host/libhackrf/src/hackrf.c index 3f0815ed..7bd2f7b5 100644 --- a/host/libhackrf/src/hackrf.c +++ b/host/libhackrf/src/hackrf.c @@ -39,10 +39,11 @@ typedef enum { HACKRF_VENDOR_REQUEST_BASEBAND_FILTER_BANDWIDTH_SET = 7, HACKRF_VENDOR_REQUEST_RFFC5071_WRITE = 8, HACKRF_VENDOR_REQUEST_RFFC5071_READ = 9, - HACKRF_VENDOR_REQUEST_SPIFLASH_WRITE = 10, - HACKRF_VENDOR_REQUEST_SPIFLASH_READ = 11, - HACKRF_VENDOR_REQUEST_CPLD_WRITE = 12, - HACKRF_VENDOR_REQUEST_BOARD_ID_READ = 13 + HACKRF_VENDOR_REQUEST_SPIFLASH_ERASE = 10, + HACKRF_VENDOR_REQUEST_SPIFLASH_WRITE = 11, + HACKRF_VENDOR_REQUEST_SPIFLASH_READ = 12, + HACKRF_VENDOR_REQUEST_CPLD_WRITE = 13, + HACKRF_VENDOR_REQUEST_BOARD_ID_READ = 14 } hackrf_vendor_request; typedef enum { @@ -435,6 +436,25 @@ int hackrf_rffc5071_write(hackrf_device* device, uint8_t register_number, uint16 } } +int hackrf_spiflash_erase(hackrf_device* device) { + int result = libusb_control_transfer( + device->usb_device, + LIBUSB_ENDPOINT_OUT | LIBUSB_REQUEST_TYPE_VENDOR | LIBUSB_RECIPIENT_DEVICE, + HACKRF_VENDOR_REQUEST_SPIFLASH_ERASE, + 0, + 0, + NULL, + 0, + 0 + ); + + if (result != 0) { + return HACKRF_ERROR_LIBUSB; + } else { + return HACKRF_SUCCESS; + } +} + int hackrf_spiflash_write(hackrf_device* device, const uint32_t address, const uint16_t length, unsigned char* const data) { diff --git a/host/libhackrf/src/hackrf.h b/host/libhackrf/src/hackrf.h index 712b4fce..94494e70 100644 --- a/host/libhackrf/src/hackrf.h +++ b/host/libhackrf/src/hackrf.h @@ -80,6 +80,7 @@ int hackrf_baseband_filter_bandwidth_set(hackrf_device* device, const uint32_t b int hackrf_rffc5071_read(hackrf_device* device, uint8_t register_number, uint16_t* value); int hackrf_rffc5071_write(hackrf_device* device, uint8_t register_number, uint16_t value); +int hackrf_spiflash_erase(hackrf_device* device); int hackrf_spiflash_write(hackrf_device* device, const uint32_t address, const uint16_t length, unsigned char* const data); int hackrf_spiflash_read(hackrf_device* device, const uint32_t address,