From 46c061f1777116cd5cc7b4db2f64f4f0328399ee Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jan=20Hamal=20Dvo=C5=99=C3=A1k?= Date: Wed, 10 Jul 2024 22:32:45 +0200 Subject: [PATCH] Use LNA gain options to control bias strength --- README.md | 2 +- grc/PicoSDR-WBFM.grc | 2 +- grc/PicoSDR.grc | 2 +- src/main.c | 27 +++++++++++++++++---------- 4 files changed, 20 insertions(+), 13 deletions(-) diff --git a/README.md b/README.md index 2c72ea7..a7583d2 100644 --- a/README.md +++ b/README.md @@ -32,4 +32,4 @@ See the [blog post](https://blog.porucha.net/2024/pico-sdr/) for more informatio 4. Open `grc/PicoSDR-WBFM.grc` in GNU Radio Companion, adjust carrier frequency to match your favorite FM radio station and press `F6`. -5. Alternatively [gqrx](https://www.gqrx.dk/) works fine with `rtl_tcp` input mode. Maximum sample rate seem to be 400 ksps, above that the samples are dropped. +5. Alternatively [gqrx](https://www.gqrx.dk/) works fine with `rtl_tcp` input mode. Maximum sample rate seem to be 400 ksps, above that the samples are dropped. Make sure to adjust LNA gain to +30 dB. It's not accurate, but it does control bias strength which in turn does affect analog gain. diff --git a/grc/PicoSDR-WBFM.grc b/grc/PicoSDR-WBFM.grc index 9ade9bd..7f2a5c0 100644 --- a/grc/PicoSDR-WBFM.grc +++ b/grc/PicoSDR-WBFM.grc @@ -374,7 +374,7 @@ blocks: freq7: 100e6 freq8: 100e6 freq9: 100e6 - gain0: '0' + gain0: '30' gain1: '10' gain10: '10' gain11: '10' diff --git a/grc/PicoSDR.grc b/grc/PicoSDR.grc index 70ffba7..9a9fca4 100644 --- a/grc/PicoSDR.grc +++ b/grc/PicoSDR.grc @@ -401,7 +401,7 @@ blocks: freq7: 100e6 freq8: 100e6 freq9: 100e6 - gain0: '0' + gain0: '30' gain1: '10' gain10: '10' gain11: '10' diff --git a/src/main.c b/src/main.c index 1b86402..95380b9 100644 --- a/src/main.c +++ b/src/main.c @@ -48,7 +48,6 @@ static_assert(RX_STRIDE * 4 < RX_WORDS, "RX_STRIDE * 4 < RX_WORDS"); static uint32_t rx_cos[RX_WORDS] __attribute__((__aligned__(1 << RX_BITS_DEPTH))); static uint32_t rx_sin[RX_WORDS] __attribute__((__aligned__(1 << RX_BITS_DEPTH))); -#define INIT_GAIN 120 #define INIT_SAMPLE_RATE 100000 #define INIT_FREQ 94600000 @@ -56,7 +55,6 @@ static uint32_t rx_sin[RX_WORDS] __attribute__((__aligned__(1 << RX_BITS_DEPTH)) static int gains[NUM_GAINS] = { 0, 9, 14, 27, 37, 77, 87, 125, 144, 157, 166, 197, 207, 229, 254, 280, 297, 328, 338, 364, 372, 386, 402, 421, 434, 439, 445, 480, 496 }; -static int gain = INIT_GAIN; static int sample_rate = INIT_SAMPLE_RATE; #define SIN_PHASE (0u) @@ -91,6 +89,17 @@ inline static uint32_t rnd_next() return rnd; } +static void bias_set_gain(int gain) +{ + if (gain > 9) + gain = 9; + else if (gain < 0) + gain = 0; + + pio1->sm[0].execctrl = (pio1->sm[0].execctrl & ~PIO_SM0_EXECCTRL_WRAP_BOTTOM_BITS) | + ((19 - gain) << PIO_SM0_EXECCTRL_WRAP_BOTTOM_LSB); +} + static void bias_init(int in_pin, int out_pin) { gpio_disable_pulls(in_pin); @@ -103,8 +112,7 @@ static void bias_init(int in_pin, int out_pin) gpio_set_slew_rate(out_pin, GPIO_SLEW_RATE_SLOW); const uint16_t insn[] = { - pio_encode_mov_not(pio_pins, pio_pins) | pio_encode_sideset(1, 1), - + pio_encode_in(pio_pins, 1), pio_encode_in(pio_pins, 1), pio_encode_in(pio_pins, 1), pio_encode_in(pio_pins, 1), @@ -118,6 +126,7 @@ static void bias_init(int in_pin, int out_pin) pio_encode_mov(pio_isr, pio_null), pio_encode_jmp_x_dec(11), + pio_encode_mov_not(pio_pins, pio_pins) | pio_encode_sideset(1, 1), }; pio_program_t prog = { @@ -552,7 +561,7 @@ static void rf_rx(void) int64_t I = sI; int64_t Q = sQ; - I *= gain; + I *= 127; I -= (max_amplitude * 181) / 256; I /= max_amplitude; @@ -563,7 +572,7 @@ static void rf_rx(void) *blockptr++ = (uint8_t)I + 128; - Q *= gain; + Q *= 127; Q -= (max_amplitude * 181) / 256; Q /= max_amplitude; @@ -599,12 +608,10 @@ static void run_command(uint8_t cmd, uint32_t arg) rx_lo_init(arg - sample_rate, true); } else if (0x04 == cmd) { /* Set the tuner gain level */ - gain = INIT_GAIN * powf(10.0f, 0.005f * arg); + bias_set_gain((arg + 14) / 30); } else if (0x0d == cmd) { /* Set tuner gain by the tuner's gain index */ - if (arg < NUM_GAINS) { - gain = INIT_GAIN * powf(10.0f, 0.005f * gains[arg]); - } + bias_set_gain((gains[arg] + 14) / 30); } }