Skip to content

Commit c3deb84

Browse files
mossmannmartinling
andcommitted
Add radio configuration update callback
Co-authored-by: Martin Ling <martin-git@earth.li>
1 parent b354264 commit c3deb84

6 files changed

Lines changed: 161 additions & 67 deletions

File tree

firmware/common/radio.c

Lines changed: 36 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,6 @@
2828
#include "platform_detect.h"
2929
#include "radio.h"
3030
#include "fixed_point.h"
31-
#include "hackrf_ui.h"
3231

3332
#define MIN(x, y) ((x) < (y) ? (x) : (y))
3433
#define MAX(x, y) ((x) > (y) ? (x) : (y))
@@ -225,11 +224,6 @@ static bool radio_update_sample_rate(radio_t* const radio, uint64_t* bank)
225224
new_rate = (rate != radio->config[RADIO_BANK_APPLIED][RADIO_SAMPLE_RATE]);
226225
if (new_rate) {
227226
radio->config[RADIO_BANK_APPLIED][RADIO_SAMPLE_RATE] = rate;
228-
if (rate != RADIO_UNSET) {
229-
/* Round to the nearest Hz for display. */
230-
const uint32_t rate_hz = (rate + (FP_ONE_HZ >> 1)) / FP_ONE_HZ;
231-
hackrf_ui()->set_sample_rate(rate_hz);
232-
}
233227
}
234228

235229
return (new_afe_rate || new_rate || new_n);
@@ -613,6 +607,7 @@ bool radio_update(radio_t* const radio)
613607
uint64_t tmp_bank[RADIO_NUM_REGS];
614608
nvic_disable_irq(NVIC_USB0_IRQ);
615609
uint32_t dirty = radio->regs_dirty;
610+
uint32_t changed = 0;
616611
if (dirty == 0) {
617612
nvic_enable_irq(NVIC_USB0_IRQ);
618613
return false;
@@ -621,56 +616,57 @@ bool radio_update(radio_t* const radio)
621616
memcpy(&tmp_bank[0], &(radio->config[RADIO_BANK_ACTIVE][0]), sizeof(tmp_bank));
622617
nvic_enable_irq(NVIC_USB0_IRQ);
623618

624-
bool dir = false;
625-
bool rate = false;
626-
bool freq = false;
627-
bool bw = false;
628-
bool gain = false;
629-
bool bias = false;
630-
bool trig = false;
631-
bool dc = false;
632-
633-
if ((dirty &
634-
((1 << RADIO_SAMPLE_RATE) | (1 << RADIO_RESAMPLE_TX) |
635-
(1 << RADIO_RESAMPLE_RX))) ||
619+
if ((dirty & RADIO_REG_GROUP_RATE) ||
636620
((detected_platform() == BOARD_ID_PRALINE) &&
637621
(dirty & (1 << RADIO_OPMODE)))) {
638-
rate = radio_update_sample_rate(radio, &tmp_bank[0]);
622+
if (radio_update_sample_rate(radio, &tmp_bank[0])) {
623+
changed |= RADIO_REG_GROUP_RATE;
624+
}
639625
}
640-
if ((dirty &
641-
((1 << RADIO_FREQUENCY_RF) | (1 << RADIO_FREQUENCY_IF) |
642-
(1 << RADIO_FREQUENCY_LO) | (1 << RADIO_IMAGE_REJECT) |
643-
(1 << RADIO_ROTATION))) ||
626+
if ((dirty & RADIO_REG_GROUP_FREQ) ||
644627
((detected_platform() == BOARD_ID_PRALINE) &&
645-
(rate || (dirty & (1 << RADIO_OPMODE))))) {
646-
freq = radio_update_frequency(radio, &tmp_bank[0]);
628+
((changed & RADIO_REG_GROUP_RATE) || (dirty & (1 << RADIO_OPMODE))))) {
629+
if (radio_update_frequency(radio, &tmp_bank[0])) {
630+
changed |= RADIO_REG_GROUP_FREQ;
631+
}
647632
}
648-
if ((dirty &
649-
((1 << RADIO_BB_BANDWIDTH_TX) | (1 << RADIO_BB_BANDWIDTH_RX) |
650-
(1 << RADIO_XCVR_TX_LPF) | (1 << RADIO_XCVR_RX_LPF) |
651-
(1 << RADIO_XCVR_RX_HPF) | (1 << RADIO_RX_NARROW_LPF))) ||
652-
((detected_platform() == BOARD_ID_PRALINE) && (rate || freq))) {
653-
bw = radio_update_bandwidth(radio, &tmp_bank[0]);
633+
if ((dirty & RADIO_REG_GROUP_BW) ||
634+
((detected_platform() == BOARD_ID_PRALINE) &&
635+
(changed & (RADIO_REG_GROUP_RATE | RADIO_REG_GROUP_FREQ)))) {
636+
if (radio_update_bandwidth(radio, &tmp_bank[0])) {
637+
changed |= RADIO_REG_GROUP_BW;
638+
}
654639
}
655-
if (dirty &
656-
((1 << RADIO_GAIN_TX_RF) | (1 << RADIO_GAIN_TX_IF) | (1 << RADIO_GAIN_RX_RF) |
657-
(1 << RADIO_GAIN_RX_IF) | (1 << RADIO_GAIN_RX_BB) | (1 << RADIO_OPMODE))) {
658-
gain = radio_update_gain(radio, &tmp_bank[0]);
640+
if (dirty & (RADIO_REG_GROUP_GAIN | (1 << RADIO_OPMODE))) {
641+
if (radio_update_gain(radio, &tmp_bank[0])) {
642+
changed |= RADIO_REG_GROUP_GAIN;
643+
}
659644
}
660645
if (dirty & ((1 << RADIO_BIAS_TEE) | (1 << RADIO_OPMODE))) {
661-
bias = radio_update_bias_tee(radio, &tmp_bank[0]);
646+
if (radio_update_bias_tee(radio, &tmp_bank[0])) {
647+
changed |= (1 << RADIO_BIAS_TEE);
648+
}
662649
}
663650
if (dirty & (1 << RADIO_TRIGGER)) {
664-
trig = radio_update_trigger(radio, &tmp_bank[0]);
651+
if (radio_update_trigger(radio, &tmp_bank[0])) {
652+
changed |= (1 << RADIO_TRIGGER);
653+
}
665654
}
666655
if (dirty & (1 << RADIO_DC_BLOCK)) {
667-
dc = radio_update_dc_block(radio, &tmp_bank[0]);
656+
if (radio_update_dc_block(radio, &tmp_bank[0])) {
657+
changed |= (1 << RADIO_DC_BLOCK);
658+
}
668659
}
669660
if (dirty & (1 << RADIO_OPMODE)) {
670-
dir = radio_update_direction(radio, &tmp_bank[0]);
661+
if (radio_update_direction(radio, &tmp_bank[0])) {
662+
changed |= (1 << RADIO_OPMODE);
663+
}
671664
}
672665

673-
return trig || dir || rate || freq || bw || gain || bias || dc;
666+
if (radio->update_cb) {
667+
radio->update_cb(changed);
668+
}
669+
return (changed != 0);
674670
}
675671

676672
void radio_switch_opmode(radio_t* const radio, const transceiver_mode_t mode)

firmware/common/radio.h

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -186,6 +186,20 @@ typedef enum {
186186
#define RADIO_NUM_REGS (23)
187187
#define RADIO_UNSET (0xffffffffffffffff)
188188

189+
/* register groups for bitfield convenience */
190+
#define RADIO_REG_GROUP_RATE \
191+
((1 << RADIO_SAMPLE_RATE) | (1 << RADIO_RESAMPLE_TX) | (1 << RADIO_RESAMPLE_RX))
192+
#define RADIO_REG_GROUP_FREQ \
193+
((1 << RADIO_FREQUENCY_RF) | (1 << RADIO_FREQUENCY_IF) | \
194+
(1 << RADIO_FREQUENCY_LO) | (1 << RADIO_IMAGE_REJECT) | (1 << RADIO_ROTATION))
195+
#define RADIO_REG_GROUP_BW \
196+
((1 << RADIO_BB_BANDWIDTH_TX) | (1 << RADIO_BB_BANDWIDTH_RX) | \
197+
(1 << RADIO_XCVR_TX_LPF) | (1 << RADIO_XCVR_RX_LPF) | \
198+
(1 << RADIO_XCVR_RX_HPF) | (1 << RADIO_RX_NARROW_LPF))
199+
#define RADIO_REG_GROUP_GAIN \
200+
((1 << RADIO_GAIN_TX_RF) | (1 << RADIO_GAIN_TX_IF) | (1 << RADIO_GAIN_RX_RF) | \
201+
(1 << RADIO_GAIN_RX_IF) | (1 << RADIO_GAIN_RX_BB))
202+
189203
/**
190204
* Register bank RADIO_BANK_ACTIVE stores the active configuration. Active
191205
* register settings are copied to the applied register when applied.
@@ -216,11 +230,19 @@ typedef enum {
216230
*/
217231
typedef fp_40_24_t (*sample_rate_fn)(const fp_40_24_t sample_rate, const bool program);
218232

233+
/**
234+
* An optional callback may be provided that is called after each time the
235+
* radio configuration has been updated. The single argument is a bitfield
236+
* indicating registers that have been changed.
237+
*/
238+
typedef void (*update_fn)(const uint32_t changed_regs);
239+
219240
typedef struct radio_t {
220241
radio_config_mode_t config_mode;
221242
uint64_t config[RADIO_NUM_BANKS][RADIO_NUM_REGS];
222243
volatile uint32_t regs_dirty;
223244
sample_rate_fn sample_rate_cb;
245+
update_fn update_cb;
224246
} radio_t;
225247

226248
void radio_init(radio_t* const radio);

firmware/common/rf_path.c

Lines changed: 0 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,6 @@
2727

2828
#include <hackrf_core.h>
2929

30-
#include "hackrf_ui.h"
3130
#include "gpio_lpc.h"
3231
#include "platform_detect.h"
3332
#include "mixer.h"
@@ -533,8 +532,6 @@ void rf_path_set_direction(rf_path_t* const rf_path, const rf_path_direction_t d
533532
}
534533

535534
switchctrl_set(rf_path, rf_path->switchctrl);
536-
537-
hackrf_ui()->set_direction(direction);
538535
}
539536

540537
void rf_path_set_filter(rf_path_t* const rf_path, const rf_path_filter_t filter)
@@ -559,8 +556,6 @@ void rf_path_set_filter(rf_path_t* const rf_path, const rf_path_filter_t filter)
559556
}
560557

561558
switchctrl_set(rf_path, rf_path->switchctrl);
562-
563-
hackrf_ui()->set_filter(filter);
564559
}
565560

566561
void rf_path_set_lna(rf_path_t* const rf_path, const uint_fast8_t enable)
@@ -584,8 +579,6 @@ void rf_path_set_lna(rf_path_t* const rf_path, const uint_fast8_t enable)
584579
}
585580

586581
switchctrl_set(rf_path, rf_path->switchctrl);
587-
588-
hackrf_ui()->set_lna_power(enable);
589582
}
590583

591584
/* antenna port power control */
@@ -598,6 +591,4 @@ void rf_path_set_antenna(rf_path_t* const rf_path, const uint_fast8_t enable)
598591
}
599592

600593
switchctrl_set(rf_path, rf_path->switchctrl);
601-
602-
hackrf_ui()->set_antenna_bias(enable);
603594
}

firmware/common/tuning.c

Lines changed: 0 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -22,11 +22,9 @@
2222
*/
2323

2424
#include "tuning.h"
25-
#include "hackrf_ui.h"
2625
#include "hackrf_core.h"
2726
#include "mixer.h"
2827
#include "sgpio.h"
29-
#include "operacake.h"
3028
#include "platform_detect.h"
3129

3230
#ifndef PRALINE
@@ -129,12 +127,6 @@ bool set_freq(const uint64_t freq)
129127
success = false;
130128
}
131129
max283x_set_mode(&max283x, prior_max283x_mode);
132-
if (success) {
133-
hackrf_ui()->set_frequency(freq);
134-
#ifdef HACKRF_ONE
135-
operacake_set_range(freq_mhz);
136-
#endif
137-
}
138130
return success;
139131
}
140132

@@ -194,8 +186,6 @@ bool tuning_set_frequency(
194186
}
195187

196188
max283x_set_mode(&max283x, prior_max283x_mode);
197-
hackrf_ui()->set_frequency(freq);
198-
operacake_set_range(freq_mhz);
199189
return true;
200190
}
201191
#endif

firmware/hackrf_usb/hackrf_usb.c

Lines changed: 103 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -256,6 +256,108 @@ static void m0_rom_to_ram(void)
256256
memcpy(dest, (uint32_t*) (base + src), len);
257257
}
258258

259+
void radio_changed(const uint32_t changed)
260+
{
261+
const uint64_t opmode = radio_reg_read(&radio, RADIO_BANK_APPLIED, RADIO_OPMODE);
262+
263+
if (changed & (1 << RADIO_OPMODE)) {
264+
switch (opmode) {
265+
case TRANSCEIVER_MODE_TX:
266+
case TRANSCEIVER_MODE_SS:
267+
hackrf_ui()->set_direction(RF_PATH_DIRECTION_TX);
268+
break;
269+
case TRANSCEIVER_MODE_RX:
270+
case TRANSCEIVER_MODE_RX_SWEEP:
271+
hackrf_ui()->set_direction(RF_PATH_DIRECTION_RX);
272+
break;
273+
default:
274+
hackrf_ui()->set_direction(RF_PATH_DIRECTION_OFF);
275+
break;
276+
}
277+
}
278+
if (changed & (1 << RADIO_SAMPLE_RATE)) {
279+
const uint64_t rate =
280+
radio_reg_read(&radio, RADIO_BANK_APPLIED, RADIO_SAMPLE_RATE);
281+
hackrf_ui()->set_sample_rate(rate / FP_ONE_HZ);
282+
}
283+
if (changed & (1 << RADIO_FREQUENCY_RF)) {
284+
const uint64_t freq =
285+
radio_reg_read(&radio, RADIO_BANK_APPLIED, RADIO_FREQUENCY_RF);
286+
hackrf_ui()->set_frequency(freq / FP_ONE_HZ);
287+
#if defined(HACKRF_ONE) || defined(PRALINE)
288+
operacake_set_range(freq / FP_ONE_MHZ);
289+
#endif
290+
}
291+
if (changed & (1 << RADIO_IMAGE_REJECT)) {
292+
const uint64_t img_reject =
293+
radio_reg_read(&radio, RADIO_BANK_APPLIED, RADIO_IMAGE_REJECT);
294+
hackrf_ui()->set_filter(img_reject);
295+
}
296+
if (changed &
297+
((1 << RADIO_BB_BANDWIDTH_TX) | (1 << RADIO_BB_BANDWIDTH_RX) |
298+
(1 << RADIO_OPMODE))) {
299+
uint64_t bw;
300+
301+
switch (opmode) {
302+
case TRANSCEIVER_MODE_TX:
303+
case TRANSCEIVER_MODE_SS:
304+
bw = radio_reg_read(
305+
&radio,
306+
RADIO_BANK_APPLIED,
307+
RADIO_BB_BANDWIDTH_TX);
308+
break;
309+
default:
310+
bw = radio_reg_read(
311+
&radio,
312+
RADIO_BANK_APPLIED,
313+
RADIO_BB_BANDWIDTH_RX);
314+
}
315+
hackrf_ui()->set_filter_bw(bw);
316+
}
317+
if (changed &
318+
((1 << RADIO_GAIN_TX_RF) | (1 << RADIO_GAIN_RX_RF) | (1 << RADIO_OPMODE))) {
319+
const uint64_t tx_rf =
320+
radio_reg_read(&radio, RADIO_BANK_APPLIED, RADIO_GAIN_TX_RF);
321+
const uint64_t rx_rf =
322+
radio_reg_read(&radio, RADIO_BANK_APPLIED, RADIO_GAIN_RX_RF);
323+
bool enable;
324+
325+
switch (opmode) {
326+
case TRANSCEIVER_MODE_TX:
327+
case TRANSCEIVER_MODE_SS:
328+
enable = tx_rf;
329+
break;
330+
case TRANSCEIVER_MODE_RX:
331+
case TRANSCEIVER_MODE_RX_SWEEP:
332+
enable = rx_rf;
333+
break;
334+
default:
335+
enable = false;
336+
}
337+
hackrf_ui()->set_lna_power(enable);
338+
}
339+
if (changed & (1 << RADIO_GAIN_TX_IF)) {
340+
const uint64_t tx_if =
341+
radio_reg_read(&radio, RADIO_BANK_APPLIED, RADIO_GAIN_TX_IF);
342+
hackrf_ui()->set_bb_tx_vga_gain(tx_if);
343+
}
344+
if (changed & (1 << RADIO_GAIN_RX_IF)) {
345+
const uint64_t rx_if =
346+
radio_reg_read(&radio, RADIO_BANK_APPLIED, RADIO_GAIN_RX_IF);
347+
hackrf_ui()->set_bb_lna_gain(rx_if);
348+
}
349+
if (changed & (1 << RADIO_GAIN_RX_BB)) {
350+
const uint64_t rx_bb =
351+
radio_reg_read(&radio, RADIO_BANK_APPLIED, RADIO_GAIN_RX_BB);
352+
hackrf_ui()->set_bb_vga_gain(rx_bb);
353+
}
354+
if (changed & (1 << RADIO_BIAS_TEE)) {
355+
const uint64_t enable =
356+
radio_reg_read(&radio, RADIO_BANK_APPLIED, RADIO_BIAS_TEE);
357+
hackrf_ui()->set_antenna_bias(enable);
358+
}
359+
}
360+
259361
int main(void)
260362
{
261363
// Copy M0 image from ROM before SPIFI is disabled
@@ -320,6 +422,7 @@ int main(void)
320422
fpga_spi_selftest();
321423
fpga_sgpio_selftest();
322424
#endif
425+
radio.update_cb = radio_changed;
323426
radio_init(&radio);
324427

325428
#if (defined HACKRF_ONE || defined PRALINE)

0 commit comments

Comments
 (0)