From c50ebb1a369922f557c77ee14843483ec18a4f5a Mon Sep 17 00:00:00 2001 From: Mike Walters Date: Wed, 4 Aug 2021 22:14:59 +0100 Subject: [PATCH] operacake: add time switching mode --- firmware/common/operacake.c | 39 ++++++++++++++++++++++-- host/hackrf-tools/src/hackrf_operacake.c | 9 ++++-- host/libhackrf/src/hackrf.h | 4 +++ 3 files changed, 48 insertions(+), 4 deletions(-) diff --git a/firmware/common/operacake.c b/firmware/common/operacake.c index 0ad97ee5..6230cb39 100644 --- a/firmware/common/operacake.c +++ b/firmware/common/operacake.c @@ -20,6 +20,7 @@ */ #include "operacake.h" +#include "operacake_sctimer.h" #include "hackrf_core.h" #include "gpio.h" #include "gpio_lpc.h" @@ -78,11 +79,14 @@ i2c_bus_t* const oc_bus = &i2c0; enum operacake_switching_mode { MODE_MANUAL = 0, MODE_FREQUENCY = 1, + MODE_TIME = 2, }; struct operacake_state { bool present; enum operacake_switching_mode mode; + uint8_t PA; + uint8_t PB; }; struct operacake_state operacake_boards[OPERACAKE_MAX_BOARDS]; @@ -119,8 +123,13 @@ uint8_t operacake_init(bool allow_gpio) { operacake_boards[addr].present = (reg == OPERACAKE_CONFIG_ALL_OUTPUT); operacake_boards[addr].mode = MODE_MANUAL; + operacake_boards[addr].PA = OPERACAKE_PORT_A1; + operacake_boards[addr].PB = OPERACAKE_PORT_B1; } allow_gpio_mode = allow_gpio; + if (allow_gpio) { + operacake_sctimer_init(); + } return 0; } @@ -147,6 +156,24 @@ void operacake_set_mode(uint8_t address, uint8_t mode) { return; operacake_boards[address].mode = mode; + + if (mode == MODE_TIME) { + // Switch Opera Cake to pin-control mode + uint8_t config_pins = (uint8_t)~(OPERACAKE_PIN_OE(1) | OPERACAKE_PIN_LEDEN(1) | OPERACAKE_PIN_LEDEN2(1)); + operacake_write_reg(oc_bus, address, OPERACAKE_REG_CONFIG, config_pins); + operacake_write_reg(oc_bus, address, OPERACAKE_REG_OUTPUT, OPERACAKE_GPIO_ENABLE | OPERACAKE_EN_LEDS); + } else { + operacake_write_reg(oc_bus, address, OPERACAKE_REG_CONFIG, OPERACAKE_CONFIG_ALL_OUTPUT); + operacake_set_ports(address, operacake_boards[address].PA, operacake_boards[address].PB); + } + + // If any boards are in MODE_TIME, enable the sctimer events. + bool enable_sctimer = false; + for (int i = 0; i < OPERACAKE_MAX_BOARDS; i++) { + if (operacake_boards[i].mode == MODE_TIME) + enable_sctimer = true; + } + operacake_sctimer_enable(enable_sctimer); } uint8_t operacake_get_mode(uint8_t address) { @@ -193,16 +220,24 @@ uint8_t operacake_set_ports(uint8_t address, uint8_t PA, uint8_t PB) { || ((PA > OPERACAKE_PA4) && (PB > OPERACAKE_PA4))) { return 1; } - + if(PA > OPERACAKE_PA4) { side = OPERACAKE_CROSSOVER; } else { side = OPERACAKE_SAMESIDE; } + // Keep track of manual settings for when we switch in/out of time/frequency modes. + operacake_boards[address].PA = PA; + operacake_boards[address].PB = PB; + + // Only apply register settings if the board is in manual mode. + if (operacake_boards[address].mode != MODE_MANUAL) + return 0; + pa = port_to_pins(PA); pb = port_to_pins(PB); - + reg = (OPERACAKE_GPIO_DISABLE | side | pa | pb | OPERACAKE_EN_LEDS); operacake_write_reg(oc_bus, address, OPERACAKE_REG_OUTPUT, reg); diff --git a/host/hackrf-tools/src/hackrf_operacake.c b/host/hackrf-tools/src/hackrf_operacake.c index 8c6e3ec8..ae71a1c4 100644 --- a/host/hackrf-tools/src/hackrf_operacake.c +++ b/host/hackrf-tools/src/hackrf_operacake.c @@ -47,7 +47,7 @@ static void usage() { printf("\t-h, --help: this help\n"); printf("\t-d, --device : specify a particular device by serial number\n"); printf("\t-o, --address : specify a particular operacake by address [default: 0x00]\n"); - printf("\t-m, --mode : specify switching mode [options: manual, frequency]\n"); + printf("\t-m, --mode : specify switching mode [options: manual, frequency, time]\n"); printf("\t-a : set port A connection\n"); printf("\t-b : set port B connection\n"); printf("\t-f : automatically assign for range in MHz\n"); @@ -184,9 +184,12 @@ int main(int argc, char** argv) { } else if (strcmp(optarg, "frequency") == 0) { mode = OPERACAKE_MODE_FREQUENCY; set_mode = true; + } else if (strcmp(optarg, "time") == 0) { + mode = OPERACAKE_MODE_TIME; + set_mode = true; } else { fprintf(stderr, - "argument error: mode must be one of [manual, frequency].\n"); + "argument error: mode must be one of [manual, frequency, time].\n"); usage(); return EXIT_FAILURE; } @@ -305,6 +308,8 @@ int main(int argc, char** argv) { printf("manual\n"); } else if (mode == OPERACAKE_MODE_FREQUENCY) { printf("frequency\n"); + } else if (mode == OPERACAKE_MODE_TIME) { + printf("time\n"); } else { printf("unknown\n"); } diff --git a/host/libhackrf/src/hackrf.h b/host/libhackrf/src/hackrf.h index 7a9d69e1..7055fdff 100644 --- a/host/libhackrf/src/hackrf.h +++ b/host/libhackrf/src/hackrf.h @@ -111,6 +111,10 @@ enum operacake_switching_mode { * Port connections are switched automatically when the frequency is changed. Frequency ranges can be set using @ref hackrf_set_operacake_ranges. */ OPERACAKE_MODE_FREQUENCY, + /** + * Port connections are switched automatically over time. + */ + OPERACAKE_MODE_TIME, }; enum sweep_style {