Use LNA gain options to control bias strength

This commit is contained in:
Jan Hamal Dvořák 2024-07-10 22:32:45 +02:00
parent c188d809df
commit 46c061f177
4 changed files with 20 additions and 13 deletions

View file

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

View file

@ -374,7 +374,7 @@ blocks:
freq7: 100e6
freq8: 100e6
freq9: 100e6
gain0: '0'
gain0: '30'
gain1: '10'
gain10: '10'
gain11: '10'

View file

@ -401,7 +401,7 @@ blocks:
freq7: 100e6
freq8: 100e6
freq9: 100e6
gain0: '0'
gain0: '30'
gain1: '10'
gain10: '10'
gain11: '10'

View file

@ -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);
}
}