Add support for multiple operacake boards connected to one HackRF
This commit is contained in:
@ -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<<i)) {
|
||||
// ;
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
|
||||
uint8_t port_to_pins(uint8_t port) {
|
||||
switch(port) {
|
||||
case OPERACAKE_PA1:
|
||||
@ -106,8 +125,7 @@ uint8_t port_to_pins(uint8_t port) {
|
||||
}
|
||||
|
||||
uint8_t operacake_set_ports(uint8_t PA, uint8_t PB) {
|
||||
uint8_t side, pa, pb;
|
||||
uint8_t output_data[2];
|
||||
uint8_t side, pa, pb, reg;
|
||||
/* Start with some error checking,
|
||||
* which should have been done either
|
||||
* on the host or elsewhere in firmware
|
||||
@ -129,14 +147,9 @@ uint8_t operacake_set_ports(uint8_t PA, uint8_t PB) {
|
||||
pa = port_to_pins(PA);
|
||||
pb = port_to_pins(PB);
|
||||
|
||||
output_data[0] = OPERACAKE_REG_OUTPUT;
|
||||
output_data[1] = (OPERACAKE_GPIO_DISABLE | side
|
||||
reg = (OPERACAKE_GPIO_DISABLE | side
|
||||
| pa | pb | OPERACAKE_EN_LEDS);
|
||||
operacake_write(&operacake_driver, output_data, 2);
|
||||
operacake_write_reg(oc_bus, 0x00, OPERACAKE_REG_OUTPUT, reg);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Write to one of the PCA9557 registers */
|
||||
void operacake_write(operacake_driver_t* drv, const uint8_t* const data, const size_t data_count) {
|
||||
i2c_bus_transfer(drv->bus, drv->i2c_address, data, data_count, NULL, 0);
|
||||
}
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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
|
||||
};
|
||||
|
||||
|
@ -24,8 +24,18 @@
|
||||
|
||||
#include <operacake.h>
|
||||
|
||||
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);
|
||||
|
@ -25,6 +25,9 @@
|
||||
#include <usb_type.h>
|
||||
#include <usb_request.h>
|
||||
|
||||
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);
|
||||
|
||||
|
@ -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",
|
||||
|
@ -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,
|
||||
|
@ -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
|
||||
|
Reference in New Issue
Block a user