operacake: add time switching mode
This commit is contained in:
@ -20,6 +20,7 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#include "operacake.h"
|
#include "operacake.h"
|
||||||
|
#include "operacake_sctimer.h"
|
||||||
#include "hackrf_core.h"
|
#include "hackrf_core.h"
|
||||||
#include "gpio.h"
|
#include "gpio.h"
|
||||||
#include "gpio_lpc.h"
|
#include "gpio_lpc.h"
|
||||||
@ -78,11 +79,14 @@ i2c_bus_t* const oc_bus = &i2c0;
|
|||||||
enum operacake_switching_mode {
|
enum operacake_switching_mode {
|
||||||
MODE_MANUAL = 0,
|
MODE_MANUAL = 0,
|
||||||
MODE_FREQUENCY = 1,
|
MODE_FREQUENCY = 1,
|
||||||
|
MODE_TIME = 2,
|
||||||
};
|
};
|
||||||
|
|
||||||
struct operacake_state {
|
struct operacake_state {
|
||||||
bool present;
|
bool present;
|
||||||
enum operacake_switching_mode mode;
|
enum operacake_switching_mode mode;
|
||||||
|
uint8_t PA;
|
||||||
|
uint8_t PB;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct operacake_state operacake_boards[OPERACAKE_MAX_BOARDS];
|
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].present = (reg == OPERACAKE_CONFIG_ALL_OUTPUT);
|
||||||
operacake_boards[addr].mode = MODE_MANUAL;
|
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;
|
allow_gpio_mode = allow_gpio;
|
||||||
|
if (allow_gpio) {
|
||||||
|
operacake_sctimer_init();
|
||||||
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -147,6 +156,24 @@ void operacake_set_mode(uint8_t address, uint8_t mode) {
|
|||||||
return;
|
return;
|
||||||
|
|
||||||
operacake_boards[address].mode = mode;
|
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) {
|
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;
|
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);
|
pa = port_to_pins(PA);
|
||||||
pb = port_to_pins(PB);
|
pb = port_to_pins(PB);
|
||||||
|
|
||||||
|
@ -47,7 +47,7 @@ static void usage() {
|
|||||||
printf("\t-h, --help: this help\n");
|
printf("\t-h, --help: this help\n");
|
||||||
printf("\t-d, --device <n>: specify a particular device by serial number\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-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-a <n>: set port A connection\n");
|
||||||
printf("\t-b <n>: set port B 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");
|
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) {
|
} else if (strcmp(optarg, "frequency") == 0) {
|
||||||
mode = OPERACAKE_MODE_FREQUENCY;
|
mode = OPERACAKE_MODE_FREQUENCY;
|
||||||
set_mode = true;
|
set_mode = true;
|
||||||
|
} else if (strcmp(optarg, "time") == 0) {
|
||||||
|
mode = OPERACAKE_MODE_TIME;
|
||||||
|
set_mode = true;
|
||||||
} else {
|
} else {
|
||||||
fprintf(stderr,
|
fprintf(stderr,
|
||||||
"argument error: mode must be one of [manual, frequency].\n");
|
"argument error: mode must be one of [manual, frequency, time].\n");
|
||||||
usage();
|
usage();
|
||||||
return EXIT_FAILURE;
|
return EXIT_FAILURE;
|
||||||
}
|
}
|
||||||
@ -305,6 +308,8 @@ int main(int argc, char** argv) {
|
|||||||
printf("manual\n");
|
printf("manual\n");
|
||||||
} else if (mode == OPERACAKE_MODE_FREQUENCY) {
|
} else if (mode == OPERACAKE_MODE_FREQUENCY) {
|
||||||
printf("frequency\n");
|
printf("frequency\n");
|
||||||
|
} else if (mode == OPERACAKE_MODE_TIME) {
|
||||||
|
printf("time\n");
|
||||||
} else {
|
} else {
|
||||||
printf("unknown\n");
|
printf("unknown\n");
|
||||||
}
|
}
|
||||||
|
@ -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.
|
* Port connections are switched automatically when the frequency is changed. Frequency ranges can be set using @ref hackrf_set_operacake_ranges.
|
||||||
*/
|
*/
|
||||||
OPERACAKE_MODE_FREQUENCY,
|
OPERACAKE_MODE_FREQUENCY,
|
||||||
|
/**
|
||||||
|
* Port connections are switched automatically over time.
|
||||||
|
*/
|
||||||
|
OPERACAKE_MODE_TIME,
|
||||||
};
|
};
|
||||||
|
|
||||||
enum sweep_style {
|
enum sweep_style {
|
||||||
|
Reference in New Issue
Block a user