From 8f544ee60d39cd44b25bbf3b4732ea1ff225ce6b Mon Sep 17 00:00:00 2001 From: Dominic Spill Date: Tue, 29 Aug 2017 21:30:00 -0600 Subject: [PATCH 1/3] Add flash status read --- firmware/common/w25q80bv.c | 14 ++++++++++++++ firmware/common/w25q80bv.h | 1 + firmware/hackrf_usb/hackrf_usb.c | 3 ++- firmware/hackrf_usb/usb_api_spiflash.c | 15 +++++++++++++++ firmware/hackrf_usb/usb_api_spiflash.h | 2 ++ firmware/libopencm3 | 2 +- host/hackrf-tools/src/hackrf_spiflash.c | 5 +++++ host/libhackrf/src/hackrf.c | 25 +++++++++++++++++++++++++ host/libhackrf/src/hackrf.h | 2 +- 9 files changed, 66 insertions(+), 3 deletions(-) diff --git a/firmware/common/w25q80bv.c b/firmware/common/w25q80bv.c index 73dd0224..ea4372fd 100644 --- a/firmware/common/w25q80bv.c +++ b/firmware/common/w25q80bv.c @@ -39,11 +39,13 @@ #define W25Q80BV_WRITE_ENABLE 0x06 #define W25Q80BV_CHIP_ERASE 0xC7 #define W25Q80BV_READ_STATUS1 0x05 +#define W25Q80BV_READ_STATUS2 0x35 #define W25Q80BV_PAGE_PROGRAM 0x02 #define W25Q80BV_DEVICE_ID 0xAB #define W25Q80BV_UNIQUE_ID 0x4B #define W25Q80BV_STATUS_BUSY 0x01 +#define W25Q80BV_STATUS_WEL 0x02 #define W25Q80BV_DEVICE_ID_RES 0x13 /* Expected device_id for W25Q80BV */ @@ -74,6 +76,17 @@ uint8_t w25q80bv_get_status(w25q80bv_driver_t* const drv) return data[1]; } +void w25q80bv_get_full_status(w25q80bv_driver_t* const drv, uint8_t* data) +{ + uint8_t cmd[] = { W25Q80BV_READ_STATUS1, 0xFF }; + spi_bus_transfer(drv->bus, cmd, ARRAY_SIZE(cmd)); + data[0] = cmd[1]; + cmd[0] =W25Q80BV_READ_STATUS2; + cmd[1] = 0xFF; + spi_bus_transfer(drv->bus, cmd, ARRAY_SIZE(cmd)); + data[1] = cmd[1]; +} + /* Release power down / Device ID */ uint8_t w25q80bv_get_device_id(w25q80bv_driver_t* const drv) { @@ -110,6 +123,7 @@ void w25q80bv_write_enable(w25q80bv_driver_t* const drv) uint8_t data[] = { W25Q80BV_WRITE_ENABLE }; spi_bus_transfer(drv->bus, data, ARRAY_SIZE(data)); + while (w25q80bv_get_status(drv) ^ W25Q80BV_STATUS_WEL); } void w25q80bv_chip_erase(w25q80bv_driver_t* const drv) diff --git a/firmware/common/w25q80bv.h b/firmware/common/w25q80bv.h index 494332a1..71e7ddb7 100644 --- a/firmware/common/w25q80bv.h +++ b/firmware/common/w25q80bv.h @@ -53,6 +53,7 @@ struct w25q80bv_driver_t { }; void w25q80bv_setup(w25q80bv_driver_t* const drv); +void w25q80bv_get_full_status(w25q80bv_driver_t* const drv, uint8_t* data); void w25q80bv_chip_erase(w25q80bv_driver_t* const drv); void w25q80bv_program(w25q80bv_driver_t* const drv, uint32_t addr, uint32_t len, uint8_t* data); uint8_t w25q80bv_get_device_id(w25q80bv_driver_t* const drv); diff --git a/firmware/hackrf_usb/hackrf_usb.c b/firmware/hackrf_usb/hackrf_usb.c index 5d7467e4..3c5189fe 100644 --- a/firmware/hackrf_usb/hackrf_usb.c +++ b/firmware/hackrf_usb/hackrf_usb.c @@ -89,7 +89,8 @@ static const usb_request_handler_fn vendor_request_handler[] = { usb_vendor_request_operacake_set_ports, usb_vendor_request_set_hw_sync_mode, usb_vendor_request_reset, - usb_vendor_request_operacake_set_ranges + usb_vendor_request_operacake_set_ranges, + usb_vendor_request_spiflash_status }; static const uint32_t vendor_request_handler_count = diff --git a/firmware/hackrf_usb/usb_api_spiflash.c b/firmware/hackrf_usb/usb_api_spiflash.c index 6b3f8502..5b2dcf06 100644 --- a/firmware/hackrf_usb/usb_api_spiflash.c +++ b/firmware/hackrf_usb/usb_api_spiflash.c @@ -121,3 +121,18 @@ usb_request_status_t usb_vendor_request_read_spiflash( } } +usb_request_status_t usb_vendor_request_spiflash_status( + usb_endpoint_t* const endpoint, const usb_transfer_stage_t stage) +{ + uint8_t data[2]; + if (stage == USB_TRANSFER_STAGE_SETUP) { + w25q80bv_get_full_status(&spi_flash, data); + usb_transfer_schedule_block(endpoint->in, &data, 2, NULL, NULL); + return USB_REQUEST_STATUS_OK; + } else if (stage == USB_TRANSFER_STAGE_DATA) { + usb_transfer_schedule_ack(endpoint->out); + return USB_REQUEST_STATUS_OK; + } else { + return USB_REQUEST_STATUS_OK; + } +} diff --git a/firmware/hackrf_usb/usb_api_spiflash.h b/firmware/hackrf_usb/usb_api_spiflash.h index f8f9f52e..78104855 100644 --- a/firmware/hackrf_usb/usb_api_spiflash.h +++ b/firmware/hackrf_usb/usb_api_spiflash.h @@ -32,5 +32,7 @@ usb_request_status_t usb_vendor_request_write_spiflash( usb_endpoint_t* const endpoint, const usb_transfer_stage_t stage); usb_request_status_t usb_vendor_request_read_spiflash( usb_endpoint_t* const endpoint, const usb_transfer_stage_t stage); +usb_request_status_t usb_vendor_request_spiflash_status( + usb_endpoint_t* const endpoint, const usb_transfer_stage_t stage); #endif /* end of include guard: __USB_API_SPIFLASH_H__ */ diff --git a/firmware/libopencm3 b/firmware/libopencm3 index d3d6f3e7..c9f40aae 160000 --- a/firmware/libopencm3 +++ b/firmware/libopencm3 @@ -1 +1 @@ -Subproject commit d3d6f3e74b34593d1b56175abe5b4cb72da4ec9d +Subproject commit c9f40aae0ba25f1ffb7f2a49e050fd50714d0632 diff --git a/host/hackrf-tools/src/hackrf_spiflash.c b/host/hackrf-tools/src/hackrf_spiflash.c index aa30dfcd..757f6ea1 100644 --- a/host/hackrf-tools/src/hackrf_spiflash.c +++ b/host/hackrf-tools/src/hackrf_spiflash.c @@ -102,6 +102,7 @@ static void usage() int main(int argc, char** argv) { int opt; + uint8_t status[2]; uint32_t address = 0; uint32_t length = MAX_LENGTH; uint32_t tmp_length; @@ -278,6 +279,8 @@ int main(int argc, char** argv) fd = NULL; return EXIT_FAILURE; } + hackrf_spiflash_status(device, status); + printf("Status: 0x%02x %02x\n", status[0], status[1]); printf("Erasing SPI flash.\n"); result = hackrf_spiflash_erase(device); if (result != HACKRF_SUCCESS) { @@ -289,6 +292,8 @@ int main(int argc, char** argv) } if( !verbose ) printf("Writing %d bytes at 0x%06x.\n", length, address); while (length) { + hackrf_spiflash_status(device, status); + printf("Status: 0x%02x %02x\n", status[0], status[1]); xfer_len = (length > 256) ? 256 : length; if( verbose ) printf("Writing %d bytes at 0x%06x.\n", xfer_len, address); result = hackrf_spiflash_write(device, address, xfer_len, pdata); diff --git a/host/libhackrf/src/hackrf.c b/host/libhackrf/src/hackrf.c index 4fb28406..1952dd31 100644 --- a/host/libhackrf/src/hackrf.c +++ b/host/libhackrf/src/hackrf.c @@ -79,6 +79,7 @@ typedef enum { HACKRF_VENDOR_REQUEST_SET_HW_SYNC_MODE = 29, HACKRF_VENDOR_REQUEST_RESET = 30, HACKRF_VENDOR_REQUEST_OPERACAKE_SET_RANGES = 31, + HACKRF_VENDOR_REQUEST_SPIFLASH_STATUS = 32, } hackrf_vendor_request; #define USB_CONFIG_STANDARD 0x1 @@ -957,6 +958,30 @@ int ADDCALL hackrf_spiflash_read(hackrf_device* device, const uint32_t address, } } +int ADDCALL hackrf_spiflash_status(hackrf_device* device, uint8_t* data) +{ + int result; + + result = libusb_control_transfer( + device->usb_device, + LIBUSB_ENDPOINT_IN | LIBUSB_REQUEST_TYPE_VENDOR | LIBUSB_RECIPIENT_DEVICE, + HACKRF_VENDOR_REQUEST_SPIFLASH_STATUS, + 0, + 0, + data, + 2, + 0 + ); + + if (result < 1) + { + last_libusb_error = result; + return HACKRF_ERROR_LIBUSB; + } else { + return HACKRF_SUCCESS; + } +} + int ADDCALL hackrf_cpld_write(hackrf_device* device, unsigned char* const data, const unsigned int total_length) { diff --git a/host/libhackrf/src/hackrf.h b/host/libhackrf/src/hackrf.h index c2b28206..f9a5509b 100644 --- a/host/libhackrf/src/hackrf.h +++ b/host/libhackrf/src/hackrf.h @@ -176,7 +176,7 @@ extern ADDAPI int ADDCALL hackrf_rffc5071_write(hackrf_device* device, uint8_t r extern ADDAPI int ADDCALL hackrf_spiflash_erase(hackrf_device* device); extern ADDAPI int ADDCALL hackrf_spiflash_write(hackrf_device* device, const uint32_t address, const uint16_t length, unsigned char* const data); extern ADDAPI int ADDCALL hackrf_spiflash_read(hackrf_device* device, const uint32_t address, const uint16_t length, unsigned char* data); - +extern ADDAPI int ADDCALL hackrf_spiflash_status(hackrf_device* device, uint8_t* data); /* device will need to be reset after hackrf_cpld_write */ extern ADDAPI int ADDCALL hackrf_cpld_write(hackrf_device* device, unsigned char* const data, const unsigned int total_length); From f20763419f08bdef8f1c4aa9d2d0268b513b412e Mon Sep 17 00:00:00 2001 From: Dominic Spill Date: Tue, 12 Sep 2017 18:04:15 -0600 Subject: [PATCH 2/3] Optional spi flash status read --- host/hackrf-tools/src/hackrf_spiflash.c | 20 ++++++++++++++------ host/libhackrf/src/hackrf.c | 13 +++++++------ 2 files changed, 21 insertions(+), 12 deletions(-) diff --git a/host/hackrf-tools/src/hackrf_spiflash.c b/host/hackrf-tools/src/hackrf_spiflash.c index 757f6ea1..9e5e7fd8 100644 --- a/host/hackrf-tools/src/hackrf_spiflash.c +++ b/host/hackrf-tools/src/hackrf_spiflash.c @@ -53,6 +53,7 @@ static struct option long_options[] = { { "write", required_argument, 0, 'w' }, { "device", required_argument, 0, 'd' }, { "reset", no_argument, 0, 'R' }, + { "status", no_argument, 0, 's' }, { "verbose", no_argument, 0, 'v' }, { "help", no_argument, 0, 'h' }, { 0, 0, 0, 0 }, @@ -95,6 +96,7 @@ static void usage() printf("\t-r, --read : Read data into file.\n"); printf("\t-w, --write : Write data from file.\n"); printf("\t-d, --device : Serial number of device, if multiple devices\n"); + printf("\t-s, --status: Read SPI flash status registers before other operations.\n"); printf("\t-R, --reset: Reset HackRF after other operations.\n"); printf("\t-v, --verbose: Verbose output.\n"); } @@ -119,9 +121,10 @@ int main(int argc, char** argv) bool write = false; bool verbose = false; bool reset = false; + bool read_status = false; uint16_t usb_api; - while ((opt = getopt_long(argc, argv, "a:l:r:w:d:vRh?", long_options, + while ((opt = getopt_long(argc, argv, "a:l:r:w:d:svRh?", long_options, &option_index)) != EOF) { switch (opt) { case 'a': @@ -146,6 +149,10 @@ int main(int argc, char** argv) serial_number = optarg; break; + case 's': + read_status = true; + break; + case 'v': verbose = true; break; @@ -179,7 +186,7 @@ int main(int argc, char** argv) return EXIT_FAILURE; } - if(!(write || read || reset)) { + if(!(write || read || reset || read_status)) { fprintf(stderr, "Specify either read, write, or reset option.\n"); usage(); return EXIT_FAILURE; @@ -241,6 +248,11 @@ int main(int argc, char** argv) return EXIT_FAILURE; } + if(read_status) { + hackrf_spiflash_status(device, status); + printf("Status: 0x%02x %02x\n", status[0], status[1]); + } + if(read) { ssize_t bytes_written; tmp_length = length; @@ -279,8 +291,6 @@ int main(int argc, char** argv) fd = NULL; return EXIT_FAILURE; } - hackrf_spiflash_status(device, status); - printf("Status: 0x%02x %02x\n", status[0], status[1]); printf("Erasing SPI flash.\n"); result = hackrf_spiflash_erase(device); if (result != HACKRF_SUCCESS) { @@ -292,8 +302,6 @@ int main(int argc, char** argv) } if( !verbose ) printf("Writing %d bytes at 0x%06x.\n", length, address); while (length) { - hackrf_spiflash_status(device, status); - printf("Status: 0x%02x %02x\n", status[0], status[1]); xfer_len = (length > 256) ? 256 : length; if( verbose ) printf("Writing %d bytes at 0x%06x.\n", xfer_len, address); result = hackrf_spiflash_write(device, address, xfer_len, pdata); diff --git a/host/libhackrf/src/hackrf.c b/host/libhackrf/src/hackrf.c index 1952dd31..2b2b562c 100644 --- a/host/libhackrf/src/hackrf.c +++ b/host/libhackrf/src/hackrf.c @@ -136,6 +136,12 @@ static const max2837_ft_t max2837_ft[] = { { 0 } }; +#define USB_API_REQUIRED(device, version) \ +uint16_t usb_version = 0; \ +hackrf_usb_api_version_read(device, &usb_version); \ +if(usb_version < version) \ + return HACKRF_ERROR_USB_API_VERSION; + static volatile bool do_exit = false; static const uint16_t hackrf_usb_vid = 0x1d50; @@ -960,6 +966,7 @@ int ADDCALL hackrf_spiflash_read(hackrf_device* device, const uint32_t address, int ADDCALL hackrf_spiflash_status(hackrf_device* device, uint8_t* data) { + USB_API_REQUIRED(device, 0x0103) int result; result = libusb_control_transfer( @@ -1078,12 +1085,6 @@ extern ADDAPI int ADDCALL hackrf_usb_api_version_read(hackrf_device* device, return HACKRF_SUCCESS; } -#define USB_API_REQUIRED(device, version) \ -uint16_t usb_version = 0; \ -hackrf_usb_api_version_read(device, &usb_version); \ -if(usb_version < version) \ - return HACKRF_ERROR_USB_API_VERSION; - typedef struct { uint32_t freq_mhz; /* From 0 to 6000+MHz */ uint32_t freq_hz; /* From 0 to 999999Hz */ From c416fa129490c561154607569c247bb0955b7f78 Mon Sep 17 00:00:00 2001 From: Dominic Spill Date: Mon, 6 Nov 2017 10:42:19 -0700 Subject: [PATCH 3/3] SPI Flash: add function to clear SPI flash status register --- firmware/common/w25q80bv.c | 31 +++++++++++------ firmware/common/w25q80bv.h | 1 + firmware/hackrf_usb/hackrf_usb.c | 3 +- firmware/hackrf_usb/usb_api_spiflash.c | 10 ++++++ firmware/hackrf_usb/usb_api_spiflash.h | 2 ++ host/hackrf-tools/src/hackrf_spiflash.c | 46 ++++++++++++++++++++++--- host/libhackrf/src/hackrf.c | 26 ++++++++++++++ host/libhackrf/src/hackrf.h | 2 ++ 8 files changed, 105 insertions(+), 16 deletions(-) diff --git a/firmware/common/w25q80bv.c b/firmware/common/w25q80bv.c index ea4372fd..5397354c 100644 --- a/firmware/common/w25q80bv.c +++ b/firmware/common/w25q80bv.c @@ -38,6 +38,7 @@ #define W25Q80BV_FAST_READ 0x0b #define W25Q80BV_WRITE_ENABLE 0x06 #define W25Q80BV_CHIP_ERASE 0xC7 +#define W25Q80BV_WRITE_STATUS 0x01 #define W25Q80BV_READ_STATUS1 0x05 #define W25Q80BV_READ_STATUS2 0x35 #define W25Q80BV_PAGE_PROGRAM 0x02 @@ -76,17 +77,6 @@ uint8_t w25q80bv_get_status(w25q80bv_driver_t* const drv) return data[1]; } -void w25q80bv_get_full_status(w25q80bv_driver_t* const drv, uint8_t* data) -{ - uint8_t cmd[] = { W25Q80BV_READ_STATUS1, 0xFF }; - spi_bus_transfer(drv->bus, cmd, ARRAY_SIZE(cmd)); - data[0] = cmd[1]; - cmd[0] =W25Q80BV_READ_STATUS2; - cmd[1] = 0xFF; - spi_bus_transfer(drv->bus, cmd, ARRAY_SIZE(cmd)); - data[1] = cmd[1]; -} - /* Release power down / Device ID */ uint8_t w25q80bv_get_device_id(w25q80bv_driver_t* const drv) { @@ -237,3 +227,22 @@ void w25q80bv_read(w25q80bv_driver_t* const drv, uint32_t addr, uint32_t len, ui spi_bus_transfer_gather(drv->bus, transfers, ARRAY_SIZE(transfers)); } + +void w25q80bv_clear_status(w25q80bv_driver_t* const drv) +{ + w25q80bv_write_enable(drv); + w25q80bv_wait_while_busy(drv); + uint8_t data[] = { W25Q80BV_WRITE_STATUS, 0x00, 0x00 }; + spi_bus_transfer(drv->bus, data, ARRAY_SIZE(data)); +} + +void w25q80bv_get_full_status(w25q80bv_driver_t* const drv, uint8_t* data) +{ + uint8_t cmd[] = { W25Q80BV_READ_STATUS1, 0xFF }; + spi_bus_transfer(drv->bus, cmd, ARRAY_SIZE(cmd)); + data[0] = cmd[1]; + cmd[0] =W25Q80BV_READ_STATUS2; + cmd[1] = 0xFF; + spi_bus_transfer(drv->bus, cmd, ARRAY_SIZE(cmd)); + data[1] = cmd[1]; +} diff --git a/firmware/common/w25q80bv.h b/firmware/common/w25q80bv.h index 71e7ddb7..d98dd302 100644 --- a/firmware/common/w25q80bv.h +++ b/firmware/common/w25q80bv.h @@ -59,5 +59,6 @@ void w25q80bv_program(w25q80bv_driver_t* const drv, uint32_t addr, uint32_t len, uint8_t w25q80bv_get_device_id(w25q80bv_driver_t* const drv); void w25q80bv_get_unique_id(w25q80bv_driver_t* const drv, w25q80bv_unique_id_t* unique_id); void w25q80bv_read(w25q80bv_driver_t* const drv, uint32_t addr, uint32_t len, uint8_t* const data); +void w25q80bv_clear_status(w25q80bv_driver_t* const drv); #endif//__W25Q80BV_H__ diff --git a/firmware/hackrf_usb/hackrf_usb.c b/firmware/hackrf_usb/hackrf_usb.c index 3c5189fe..18a87861 100644 --- a/firmware/hackrf_usb/hackrf_usb.c +++ b/firmware/hackrf_usb/hackrf_usb.c @@ -90,7 +90,8 @@ static const usb_request_handler_fn vendor_request_handler[] = { usb_vendor_request_set_hw_sync_mode, usb_vendor_request_reset, usb_vendor_request_operacake_set_ranges, - usb_vendor_request_spiflash_status + usb_vendor_request_spiflash_status, + usb_vendor_request_spiflash_clear_status }; static const uint32_t vendor_request_handler_count = diff --git a/firmware/hackrf_usb/usb_api_spiflash.c b/firmware/hackrf_usb/usb_api_spiflash.c index 5b2dcf06..9663f676 100644 --- a/firmware/hackrf_usb/usb_api_spiflash.c +++ b/firmware/hackrf_usb/usb_api_spiflash.c @@ -136,3 +136,13 @@ usb_request_status_t usb_vendor_request_spiflash_status( return USB_REQUEST_STATUS_OK; } } + +usb_request_status_t usb_vendor_request_spiflash_clear_status( + usb_endpoint_t* const endpoint, const usb_transfer_stage_t stage) +{ + if (stage == USB_TRANSFER_STAGE_SETUP) { + w25q80bv_clear_status(&spi_flash); + usb_transfer_schedule_ack(endpoint->in); + } +return USB_REQUEST_STATUS_OK; +} \ No newline at end of file diff --git a/firmware/hackrf_usb/usb_api_spiflash.h b/firmware/hackrf_usb/usb_api_spiflash.h index 78104855..3d17203d 100644 --- a/firmware/hackrf_usb/usb_api_spiflash.h +++ b/firmware/hackrf_usb/usb_api_spiflash.h @@ -34,5 +34,7 @@ usb_request_status_t usb_vendor_request_read_spiflash( usb_endpoint_t* const endpoint, const usb_transfer_stage_t stage); usb_request_status_t usb_vendor_request_spiflash_status( usb_endpoint_t* const endpoint, const usb_transfer_stage_t stage); +usb_request_status_t usb_vendor_request_spiflash_clear_status( + usb_endpoint_t* const endpoint, const usb_transfer_stage_t stage); #endif /* end of include guard: __USB_API_SPIFLASH_H__ */ diff --git a/host/hackrf-tools/src/hackrf_spiflash.c b/host/hackrf-tools/src/hackrf_spiflash.c index 9e5e7fd8..51c2d40c 100644 --- a/host/hackrf-tools/src/hackrf_spiflash.c +++ b/host/hackrf-tools/src/hackrf_spiflash.c @@ -54,6 +54,7 @@ static struct option long_options[] = { { "device", required_argument, 0, 'd' }, { "reset", no_argument, 0, 'R' }, { "status", no_argument, 0, 's' }, + { "clear", no_argument, 0, 'c' }, { "verbose", no_argument, 0, 'v' }, { "help", no_argument, 0, 'h' }, { 0, 0, 0, 0 }, @@ -97,6 +98,7 @@ static void usage() printf("\t-w, --write : Write data from file.\n"); printf("\t-d, --device : Serial number of device, if multiple devices\n"); printf("\t-s, --status: Read SPI flash status registers before other operations.\n"); + printf("\t-c, --clear: Clear SPI flash status registers before other operations.\n"); printf("\t-R, --reset: Reset HackRF after other operations.\n"); printf("\t-v, --verbose: Verbose output.\n"); } @@ -122,9 +124,10 @@ int main(int argc, char** argv) bool verbose = false; bool reset = false; bool read_status = false; + bool clear_status = false; uint16_t usb_api; - while ((opt = getopt_long(argc, argv, "a:l:r:w:d:svRh?", long_options, + while ((opt = getopt_long(argc, argv, "a:l:r:w:d:scvRh?", long_options, &option_index)) != EOF) { switch (opt) { case 'a': @@ -153,6 +156,10 @@ int main(int argc, char** argv) read_status = true; break; + case 'c': + clear_status = true; + break; + case 'v': verbose = true; break; @@ -186,7 +193,7 @@ int main(int argc, char** argv) return EXIT_FAILURE; } - if(!(write || read || reset || read_status)) { + if(!(write || read || reset || read_status || clear_status)) { fprintf(stderr, "Specify either read, write, or reset option.\n"); usage(); return EXIT_FAILURE; @@ -249,8 +256,39 @@ int main(int argc, char** argv) } if(read_status) { - hackrf_spiflash_status(device, status); - printf("Status: 0x%02x %02x\n", status[0], status[1]); + result = hackrf_spiflash_status(device, status); + if (result != HACKRF_SUCCESS) { + fprintf(stderr, "hackrf_spiflash_status() failed: %s (%d)\n", + hackrf_error_name(result), result); + return EXIT_FAILURE; + } + if(!verbose) { + printf("Status: 0x%02x %02x\n", status[0], status[1]); + } else { + printf("SRP0\t%x\nSEC\t%x\nTB\t%x\nBP\t%x\nWEL\t%x\nBusy\t%x\n", + (status[0] & 0x80) >> 7, + (status[0] & 0x40) >> 6, + (status[0] & 0x20) >> 5, + (status[0] & 0x1C) >> 2, + (status[0] & 0x02) >> 1, + status[0] & 0x01); + printf("SUS\t%x\nCMP\t%x\nLB\t%x\nRes\t%x\nQE\t%x\nSRP1\t%x\n", + (status[1] & 0x80) >> 7, + (status[1] & 0x40) >> 6, + (status[1] & 0x38) >> 3, + (status[1] & 0x04) >> 2, + (status[1] & 0x02) >> 1, + status[1] & 0x01); + } + } + + if(clear_status) { + result = hackrf_spiflash_clear_status(device); + if (result != HACKRF_SUCCESS) { + fprintf(stderr, "hackrf_spiflash_clear_status() failed: %s (%d)\n", + hackrf_error_name(result), result); + return EXIT_FAILURE; + } } if(read) { diff --git a/host/libhackrf/src/hackrf.c b/host/libhackrf/src/hackrf.c index 2b2b562c..4157778d 100644 --- a/host/libhackrf/src/hackrf.c +++ b/host/libhackrf/src/hackrf.c @@ -80,6 +80,7 @@ typedef enum { HACKRF_VENDOR_REQUEST_RESET = 30, HACKRF_VENDOR_REQUEST_OPERACAKE_SET_RANGES = 31, HACKRF_VENDOR_REQUEST_SPIFLASH_STATUS = 32, + HACKRF_VENDOR_REQUEST_SPIFLASH_CLEAR_STATUS = 33, } hackrf_vendor_request; #define USB_CONFIG_STANDARD 0x1 @@ -989,6 +990,30 @@ int ADDCALL hackrf_spiflash_status(hackrf_device* device, uint8_t* data) } } +int ADDCALL hackrf_spiflash_clear_status(hackrf_device* device) +{ + USB_API_REQUIRED(device, 0x0103) + int result; + result = libusb_control_transfer( + device->usb_device, + LIBUSB_ENDPOINT_OUT | LIBUSB_REQUEST_TYPE_VENDOR | LIBUSB_RECIPIENT_DEVICE, + HACKRF_VENDOR_REQUEST_SPIFLASH_CLEAR_STATUS, + 0, + 0, + NULL, + 0, + 0 + ); + + if( result != 0 ) + { + last_libusb_error = result; + return HACKRF_ERROR_LIBUSB; + } else { + return HACKRF_SUCCESS; + } +} + int ADDCALL hackrf_cpld_write(hackrf_device* device, unsigned char* const data, const unsigned int total_length) { @@ -2017,6 +2042,7 @@ int ADDCALL hackrf_set_operacake_ranges(hackrf_device* device, uint8_t* ranges, return HACKRF_SUCCESS; } } + #ifdef __cplusplus } // __cplusplus defined. #endif diff --git a/host/libhackrf/src/hackrf.h b/host/libhackrf/src/hackrf.h index f9a5509b..021889f6 100644 --- a/host/libhackrf/src/hackrf.h +++ b/host/libhackrf/src/hackrf.h @@ -177,6 +177,8 @@ extern ADDAPI int ADDCALL hackrf_spiflash_erase(hackrf_device* device); extern ADDAPI int ADDCALL hackrf_spiflash_write(hackrf_device* device, const uint32_t address, const uint16_t length, unsigned char* const data); extern ADDAPI int ADDCALL hackrf_spiflash_read(hackrf_device* device, const uint32_t address, const uint16_t length, unsigned char* data); extern ADDAPI int ADDCALL hackrf_spiflash_status(hackrf_device* device, uint8_t* data); +extern ADDAPI int ADDCALL hackrf_spiflash_clear_status(hackrf_device* device); + /* device will need to be reset after hackrf_cpld_write */ extern ADDAPI int ADDCALL hackrf_cpld_write(hackrf_device* device, unsigned char* const data, const unsigned int total_length);