From c54e31f397efed25d46e691c02d23b0cbb168800 Mon Sep 17 00:00:00 2001 From: Dominic Spill Date: Fri, 23 Dec 2016 21:59:45 +0000 Subject: [PATCH] Add support for multiple operacake boards connected to one HackRF --- firmware/common/operacake.c | 65 +++++++++++++++---------- firmware/common/operacake.h | 3 ++ firmware/hackrf_usb/hackrf_usb.c | 1 + firmware/hackrf_usb/usb_api_operacake.c | 12 ++++- firmware/hackrf_usb/usb_api_operacake.h | 3 ++ host/hackrf-tools/src/hackrf_info.c | 18 ++++++- host/libhackrf/src/hackrf.c | 29 ++++++++++- host/libhackrf/src/hackrf.h | 6 +++ 8 files changed, 106 insertions(+), 31 deletions(-) diff --git a/firmware/common/operacake.c b/firmware/common/operacake.c index 02d16851..3dad30c9 100644 --- a/firmware/common/operacake.c +++ b/firmware/common/operacake.c @@ -57,31 +57,50 @@ | OPERACAKE_EN_LEDS) #define OPERACAKE_CONFIG_ALL_OUTPUT (0x00) -typedef struct { - i2c_bus_t* const bus; - uint8_t i2c_address; -} operacake_driver_t; +#define OPERACAKE_DEFAULT_ADDRESS 0x18 -operacake_driver_t operacake_driver = { - .bus = &i2c0, - .i2c_address = 0x18, -}; +i2c_bus_t* const oc_bus = &i2c0; +uint8_t operacake_boards[8] = {0,0,0,0,0,0,0,0}; -uint8_t operacake_read_single(operacake_driver_t* drv, uint8_t reg); -void operacake_write(operacake_driver_t* drv, const uint8_t* const data, const size_t data_count); +/* read single register */ +uint8_t operacake_read_reg(i2c_bus_t* const bus, uint8_t address, uint8_t reg) { + const uint8_t data_tx[] = { reg }; + uint8_t data_rx[] = { 0x00 }; + i2c_bus_transfer(bus, address, data_tx, 1, data_rx, 1); + return data_rx[0]; +} +/* Write to one of the PCA9557 registers */ +void operacake_write_reg(i2c_bus_t* const bus, uint8_t address, uint8_t reg, uint8_t value) { + const uint8_t data[] = {reg, value}; + i2c_bus_transfer(bus, address, data, 2, NULL, 0); +} uint8_t operacake_init(void) { - /* TODO: detect Operacake */ - uint8_t output_data[] = {OPERACAKE_REG_OUTPUT, - OPERACAKE_DEFAULT_OUTPUT}; - operacake_write(&operacake_driver, output_data, 2); - const uint8_t config_data[] = {OPERACAKE_REG_CONFIG, - OPERACAKE_CONFIG_ALL_OUTPUT}; - operacake_write(&operacake_driver, config_data, 2); + int reg, addr, i, j = 0; + /* Find connected operacakes */ + for(i=0; i<8; i++) { + addr = OPERACAKE_DEFAULT_ADDRESS | i; + operacake_write_reg(oc_bus, addr, OPERACAKE_REG_OUTPUT, + OPERACAKE_DEFAULT_OUTPUT); + operacake_write_reg(oc_bus, addr, OPERACAKE_REG_CONFIG, + OPERACAKE_CONFIG_ALL_OUTPUT); + reg = operacake_read_reg(oc_bus, addr, OPERACAKE_REG_CONFIG); + if(reg==OPERACAKE_CONFIG_ALL_OUTPUT) + operacake_boards[j++] = addr; + } return 0; } +// uint8_t operacake_get_boards(uint8_t *boards) { +// int i, j = 0; +// for(i=0; i<8; i++) { +// if(operacake_boards & (1<bus, drv->i2c_address, data, data_count, NULL, 0); -} diff --git a/firmware/common/operacake.h b/firmware/common/operacake.h index 20a9a998..78dba000 100644 --- a/firmware/common/operacake.h +++ b/firmware/common/operacake.h @@ -40,6 +40,9 @@ extern "C" #define OPERACAKE_PB3 6 #define OPERACAKE_PB4 7 +/* Up to 8 Operacake boards can be used with one HackRF */ +extern uint8_t operacake_boards[8]; + uint8_t operacake_init(void); uint8_t operacake_set_ports(uint8_t PA, uint8_t PB); diff --git a/firmware/hackrf_usb/hackrf_usb.c b/firmware/hackrf_usb/hackrf_usb.c index bea6add6..2d5fd2ff 100644 --- a/firmware/hackrf_usb/hackrf_usb.c +++ b/firmware/hackrf_usb/hackrf_usb.c @@ -142,6 +142,7 @@ static const usb_request_handler_fn vendor_request_handler[] = { #endif usb_vendor_request_set_freq_explicit, usb_vendor_request_read_wcid, // USB_WCID_VENDOR_REQ + usb_vendor_request_operacake_get_boards, usb_vendor_request_operacake_set_ports }; diff --git a/firmware/hackrf_usb/usb_api_operacake.c b/firmware/hackrf_usb/usb_api_operacake.c index c93ec494..ce420860 100644 --- a/firmware/hackrf_usb/usb_api_operacake.c +++ b/firmware/hackrf_usb/usb_api_operacake.c @@ -24,8 +24,18 @@ #include +usb_request_status_t usb_vendor_request_operacake_get_boards( + usb_endpoint_t* const endpoint, const usb_transfer_stage_t stage) +{ + if (stage == USB_TRANSFER_STAGE_SETUP) { + usb_transfer_schedule_block(endpoint->in, operacake_boards, 8, NULL, NULL); + usb_transfer_schedule_ack(endpoint->out); + } + return USB_REQUEST_STATUS_OK; +} + usb_request_status_t usb_vendor_request_operacake_set_ports( - usb_endpoint_t* const endpoint, const usb_transfer_stage_t stage) + usb_endpoint_t* const endpoint, const usb_transfer_stage_t stage) { if (stage == USB_TRANSFER_STAGE_SETUP) { operacake_set_ports(endpoint->setup.index, endpoint->setup.value); diff --git a/firmware/hackrf_usb/usb_api_operacake.h b/firmware/hackrf_usb/usb_api_operacake.h index b2f4f890..4339488d 100644 --- a/firmware/hackrf_usb/usb_api_operacake.h +++ b/firmware/hackrf_usb/usb_api_operacake.h @@ -25,6 +25,9 @@ #include #include +usb_request_status_t usb_vendor_request_operacake_get_boards( + usb_endpoint_t* const endpoint, const usb_transfer_stage_t stage); + usb_request_status_t usb_vendor_request_operacake_set_ports( usb_endpoint_t* const endpoint, const usb_transfer_stage_t stage); diff --git a/host/hackrf-tools/src/hackrf_info.c b/host/hackrf-tools/src/hackrf_info.c index eed24c37..def5371d 100644 --- a/host/hackrf-tools/src/hackrf_info.c +++ b/host/hackrf-tools/src/hackrf_info.c @@ -32,9 +32,10 @@ int main(void) uint8_t board_id = BOARD_ID_INVALID; char version[255 + 1]; read_partid_serialno_t read_partid_serialno; + uint8_t operacakes[8]; hackrf_device_list_t *list; hackrf_device* device; - int i; + int i, j; result = hackrf_init(); if (result != HACKRF_SUCCESS) { @@ -98,7 +99,20 @@ int main(void) read_partid_serialno.serial_no[1], read_partid_serialno.serial_no[2], read_partid_serialno.serial_no[3]); - + + result = hackrf_get_operacake_boards(device, &operacakes[0]); + if (result != HACKRF_SUCCESS) { + fprintf(stderr, "hackrf_get_operacake_boards() failed: %s (%d)\n", + hackrf_error_name(result), result); + return EXIT_FAILURE; + } + for(j=0; j<8; j++) { + if(operacakes[j] == 0) + break; + printf("Operacake found, address: 0x%02x\n", operacakes[j]); + + } + result = hackrf_close(device); if (result != HACKRF_SUCCESS) { fprintf(stderr, "hackrf_close() failed: %s (%d)\n", diff --git a/host/libhackrf/src/hackrf.c b/host/libhackrf/src/hackrf.c index c9ccd858..dc7edec3 100644 --- a/host/libhackrf/src/hackrf.c +++ b/host/libhackrf/src/hackrf.c @@ -68,8 +68,8 @@ typedef enum { HACKRF_VENDOR_REQUEST_ANTENNA_ENABLE = 23, HACKRF_VENDOR_REQUEST_SET_FREQ_EXPLICIT = 24, HACKRF_VENDOR_REQUEST_READ_WCID = 25, - HACKRF_VENDOR_REQUEST_OPERACAKE_SET_PORTS = 26, - HACKRF_VENDOR_REQUEST_GET_OPERACAKES = 27, + HACKRF_VENDOR_REQUEST_OPERACAKE_GET_BOARDS = 26, + HACKRF_VENDOR_REQUEST_OPERACAKE_SET_PORTS = 27, } hackrf_vendor_request; typedef enum { @@ -1698,6 +1698,31 @@ uint32_t ADDCALL hackrf_compute_baseband_filter_bw(const uint32_t bandwidth_hz) return p->bandwidth_hz; } +/* Retrieve list of Operacake board addresses + * boards must be *uint8_t[8] + */ +int ADDCALL hackrf_get_operacake_boards(hackrf_device* device, uint8_t* boards) +{ + int result; + result = libusb_control_transfer( + device->usb_device, + LIBUSB_ENDPOINT_IN | LIBUSB_REQUEST_TYPE_VENDOR | LIBUSB_RECIPIENT_DEVICE, + HACKRF_VENDOR_REQUEST_OPERACAKE_GET_BOARDS, + 0, + 0, + boards, + 8, + 0 + ); + + if (result < 8) + { + return HACKRF_ERROR_LIBUSB; + } else { + return HACKRF_SUCCESS; + } +} + /* Set Operacake ports */ int ADDCALL hackrf_set_operacake_ports(hackrf_device* device, const uint8_t port_a, diff --git a/host/libhackrf/src/hackrf.h b/host/libhackrf/src/hackrf.h index e4e0d1c9..87e9556b 100644 --- a/host/libhackrf/src/hackrf.h +++ b/host/libhackrf/src/hackrf.h @@ -208,6 +208,12 @@ extern ADDAPI uint32_t ADDCALL hackrf_compute_baseband_filter_bw_round_down_lt(c /* Compute best default value depending on sample rate (auto filter) */ extern ADDAPI uint32_t ADDCALL hackrf_compute_baseband_filter_bw(const uint32_t bandwidth_hz); +/* Operacake functions */ +int ADDCALL hackrf_get_operacake_boards(hackrf_device* device, uint8_t* boards); +int ADDCALL hackrf_set_operacake_ports(hackrf_device* device, + const uint8_t port_a, + const uint8_t port_b); + #ifdef __cplusplus } // __cplusplus defined. #endif