Use LNA gain options to control bias strength
This commit is contained in:
parent
c188d809df
commit
46c061f177
4 changed files with 20 additions and 13 deletions
|
@ -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`.
|
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.
|
||||||
|
|
|
@ -374,7 +374,7 @@ blocks:
|
||||||
freq7: 100e6
|
freq7: 100e6
|
||||||
freq8: 100e6
|
freq8: 100e6
|
||||||
freq9: 100e6
|
freq9: 100e6
|
||||||
gain0: '0'
|
gain0: '30'
|
||||||
gain1: '10'
|
gain1: '10'
|
||||||
gain10: '10'
|
gain10: '10'
|
||||||
gain11: '10'
|
gain11: '10'
|
||||||
|
|
|
@ -401,7 +401,7 @@ blocks:
|
||||||
freq7: 100e6
|
freq7: 100e6
|
||||||
freq8: 100e6
|
freq8: 100e6
|
||||||
freq9: 100e6
|
freq9: 100e6
|
||||||
gain0: '0'
|
gain0: '30'
|
||||||
gain1: '10'
|
gain1: '10'
|
||||||
gain10: '10'
|
gain10: '10'
|
||||||
gain11: '10'
|
gain11: '10'
|
||||||
|
|
27
src/main.c
27
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_cos[RX_WORDS] __attribute__((__aligned__(1 << RX_BITS_DEPTH)));
|
||||||
static uint32_t rx_sin[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_SAMPLE_RATE 100000
|
||||||
#define INIT_FREQ 94600000
|
#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,
|
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,
|
166, 197, 207, 229, 254, 280, 297, 328, 338, 364,
|
||||||
372, 386, 402, 421, 434, 439, 445, 480, 496 };
|
372, 386, 402, 421, 434, 439, 445, 480, 496 };
|
||||||
static int gain = INIT_GAIN;
|
|
||||||
static int sample_rate = INIT_SAMPLE_RATE;
|
static int sample_rate = INIT_SAMPLE_RATE;
|
||||||
|
|
||||||
#define SIN_PHASE (0u)
|
#define SIN_PHASE (0u)
|
||||||
|
@ -91,6 +89,17 @@ inline static uint32_t rnd_next()
|
||||||
return rnd;
|
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)
|
static void bias_init(int in_pin, int out_pin)
|
||||||
{
|
{
|
||||||
gpio_disable_pulls(in_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);
|
gpio_set_slew_rate(out_pin, GPIO_SLEW_RATE_SLOW);
|
||||||
|
|
||||||
const uint16_t insn[] = {
|
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),
|
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_mov(pio_isr, pio_null),
|
||||||
|
|
||||||
pio_encode_jmp_x_dec(11),
|
pio_encode_jmp_x_dec(11),
|
||||||
|
pio_encode_mov_not(pio_pins, pio_pins) | pio_encode_sideset(1, 1),
|
||||||
};
|
};
|
||||||
|
|
||||||
pio_program_t prog = {
|
pio_program_t prog = {
|
||||||
|
@ -552,7 +561,7 @@ static void rf_rx(void)
|
||||||
int64_t I = sI;
|
int64_t I = sI;
|
||||||
int64_t Q = sQ;
|
int64_t Q = sQ;
|
||||||
|
|
||||||
I *= gain;
|
I *= 127;
|
||||||
I -= (max_amplitude * 181) / 256;
|
I -= (max_amplitude * 181) / 256;
|
||||||
I /= max_amplitude;
|
I /= max_amplitude;
|
||||||
|
|
||||||
|
@ -563,7 +572,7 @@ static void rf_rx(void)
|
||||||
|
|
||||||
*blockptr++ = (uint8_t)I + 128;
|
*blockptr++ = (uint8_t)I + 128;
|
||||||
|
|
||||||
Q *= gain;
|
Q *= 127;
|
||||||
Q -= (max_amplitude * 181) / 256;
|
Q -= (max_amplitude * 181) / 256;
|
||||||
Q /= max_amplitude;
|
Q /= max_amplitude;
|
||||||
|
|
||||||
|
@ -599,12 +608,10 @@ static void run_command(uint8_t cmd, uint32_t arg)
|
||||||
rx_lo_init(arg - sample_rate, true);
|
rx_lo_init(arg - sample_rate, true);
|
||||||
} else if (0x04 == cmd) {
|
} else if (0x04 == cmd) {
|
||||||
/* Set the tuner gain level */
|
/* Set the tuner gain level */
|
||||||
gain = INIT_GAIN * powf(10.0f, 0.005f * arg);
|
bias_set_gain((arg + 14) / 30);
|
||||||
} else if (0x0d == cmd) {
|
} else if (0x0d == cmd) {
|
||||||
/* Set tuner gain by the tuner's gain index */
|
/* Set tuner gain by the tuner's gain index */
|
||||||
if (arg < NUM_GAINS) {
|
bias_set_gain((gains[arg] + 14) / 30);
|
||||||
gain = INIT_GAIN * powf(10.0f, 0.005f * gains[arg]);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue