operacake: add time switching mode

This commit is contained in:
Mike Walters
2021-08-04 22:14:59 +01:00
parent 9ee25ab48a
commit c50ebb1a36
3 changed files with 48 additions and 4 deletions

View File

@ -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) {
@ -200,6 +227,14 @@ uint8_t operacake_set_ports(uint8_t address, uint8_t PA, uint8_t PB) {
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);

View File

@ -47,7 +47,7 @@ static void usage() {
printf("\t-h, --help: this help\n");
printf("\t-d, --device <n>: specify a particular device by serial number\n");
printf("\t-o, --address <n>: specify a particular operacake by address [default: 0x00]\n");
printf("\t-m, --mode <mode>: specify switching mode [options: manual, frequency]\n");
printf("\t-m, --mode <mode>: specify switching mode [options: manual, frequency, time]\n");
printf("\t-a <n>: set port A connection\n");
printf("\t-b <n>: set port B connection\n");
printf("\t-f <min:max:port>: automatically assign <port> for range <min:max> 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");
}

View File

@ -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 {