Compare commits
1 commit
master
...
headphones
Author | SHA1 | Date | |
---|---|---|---|
83bb953842 |
7 changed files with 554 additions and 432 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. 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.
|
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.
|
||||||
|
|
|
@ -49,7 +49,7 @@ blocks:
|
||||||
id: variable
|
id: variable
|
||||||
parameters:
|
parameters:
|
||||||
comment: ''
|
comment: ''
|
||||||
value: '200_000'
|
value: '192_000'
|
||||||
states:
|
states:
|
||||||
bus_sink: false
|
bus_sink: false
|
||||||
bus_source: false
|
bus_source: false
|
||||||
|
@ -78,7 +78,7 @@ blocks:
|
||||||
parameters:
|
parameters:
|
||||||
affinity: ''
|
affinity: ''
|
||||||
alias: ''
|
alias: ''
|
||||||
audio_decimation: '8'
|
audio_decimation: '4'
|
||||||
comment: ''
|
comment: ''
|
||||||
deemph_tau: 75e-6
|
deemph_tau: 75e-6
|
||||||
maxoutbuf: '0'
|
maxoutbuf: '0'
|
||||||
|
@ -100,7 +100,7 @@ blocks:
|
||||||
device_name: ''
|
device_name: ''
|
||||||
num_inputs: '2'
|
num_inputs: '2'
|
||||||
ok_to_block: 'True'
|
ok_to_block: 'True'
|
||||||
samp_rate: samp_rate // 8
|
samp_rate: samp_rate // 4
|
||||||
states:
|
states:
|
||||||
bus_sink: false
|
bus_sink: false
|
||||||
bus_source: false
|
bus_source: false
|
||||||
|
@ -150,15 +150,15 @@ blocks:
|
||||||
alias: ''
|
alias: ''
|
||||||
beta: '6.76'
|
beta: '6.76'
|
||||||
comment: ''
|
comment: ''
|
||||||
cutoff_freq: samp_rate / 16
|
cutoff_freq: samp_rate / 8
|
||||||
decim: '8'
|
decim: '4'
|
||||||
gain: '1'
|
gain: '1'
|
||||||
interp: '1'
|
interp: '1'
|
||||||
maxoutbuf: '0'
|
maxoutbuf: '0'
|
||||||
minoutbuf: '0'
|
minoutbuf: '0'
|
||||||
samp_rate: samp_rate
|
samp_rate: samp_rate
|
||||||
type: fir_filter_fff
|
type: fir_filter_fff
|
||||||
width: samp_rate / 16
|
width: samp_rate / 8
|
||||||
win: window.WIN_HAMMING
|
win: window.WIN_HAMMING
|
||||||
states:
|
states:
|
||||||
bus_sink: false
|
bus_sink: false
|
||||||
|
@ -205,7 +205,7 @@ blocks:
|
||||||
ant8: ''
|
ant8: ''
|
||||||
ant9: ''
|
ant9: ''
|
||||||
args: '"rtl_tcp"'
|
args: '"rtl_tcp"'
|
||||||
bb_gain0: '0'
|
bb_gain0: '20'
|
||||||
bb_gain1: '20'
|
bb_gain1: '20'
|
||||||
bb_gain10: '20'
|
bb_gain10: '20'
|
||||||
bb_gain11: '20'
|
bb_gain11: '20'
|
||||||
|
@ -374,7 +374,7 @@ blocks:
|
||||||
freq7: 100e6
|
freq7: 100e6
|
||||||
freq8: 100e6
|
freq8: 100e6
|
||||||
freq9: 100e6
|
freq9: 100e6
|
||||||
gain0: '0'
|
gain0: '10'
|
||||||
gain1: '10'
|
gain1: '10'
|
||||||
gain10: '10'
|
gain10: '10'
|
||||||
gain11: '10'
|
gain11: '10'
|
||||||
|
@ -438,7 +438,7 @@ blocks:
|
||||||
gain_mode7: 'False'
|
gain_mode7: 'False'
|
||||||
gain_mode8: 'False'
|
gain_mode8: 'False'
|
||||||
gain_mode9: 'False'
|
gain_mode9: 'False'
|
||||||
if_gain0: '0'
|
if_gain0: '20'
|
||||||
if_gain1: '20'
|
if_gain1: '20'
|
||||||
if_gain10: '20'
|
if_gain10: '20'
|
||||||
if_gain11: '20'
|
if_gain11: '20'
|
||||||
|
@ -677,7 +677,7 @@ blocks:
|
||||||
name: '"FM Demodulation"'
|
name: '"FM Demodulation"'
|
||||||
nconnections: '1'
|
nconnections: '1'
|
||||||
size: '512'
|
size: '512'
|
||||||
srate: samp_rate // 8
|
srate: samp_rate // (2 ** 3)
|
||||||
stemplot: 'False'
|
stemplot: 'False'
|
||||||
style1: '1'
|
style1: '1'
|
||||||
style10: '1'
|
style10: '1'
|
||||||
|
@ -856,4 +856,4 @@ connections:
|
||||||
|
|
||||||
metadata:
|
metadata:
|
||||||
file_format: 1
|
file_format: 1
|
||||||
grc_version: 3.10.11.0
|
grc_version: 3.10.9.2
|
||||||
|
|
112
grc/PicoSDR.grc
112
grc/PicoSDR.grc
|
@ -45,23 +45,11 @@ blocks:
|
||||||
coordinate: [168, 8.0]
|
coordinate: [168, 8.0]
|
||||||
rotation: 0
|
rotation: 0
|
||||||
state: enabled
|
state: enabled
|
||||||
- name: decimation
|
- name: samp_rate
|
||||||
id: variable
|
id: variable
|
||||||
parameters:
|
parameters:
|
||||||
comment: ''
|
comment: ''
|
||||||
value: '4'
|
value: '50_000'
|
||||||
states:
|
|
||||||
bus_sink: false
|
|
||||||
bus_source: false
|
|
||||||
bus_structure: null
|
|
||||||
coordinate: [352, 8.0]
|
|
||||||
rotation: 0
|
|
||||||
state: enabled
|
|
||||||
- name: rf_rate
|
|
||||||
id: variable
|
|
||||||
parameters:
|
|
||||||
comment: ''
|
|
||||||
value: '200_000'
|
|
||||||
states:
|
states:
|
||||||
bus_sink: false
|
bus_sink: false
|
||||||
bus_source: false
|
bus_source: false
|
||||||
|
@ -69,38 +57,6 @@ blocks:
|
||||||
coordinate: [264, 8.0]
|
coordinate: [264, 8.0]
|
||||||
rotation: 0
|
rotation: 0
|
||||||
state: enabled
|
state: enabled
|
||||||
- name: samp_rate
|
|
||||||
id: variable
|
|
||||||
parameters:
|
|
||||||
comment: ''
|
|
||||||
value: rf_rate // decimation
|
|
||||||
states:
|
|
||||||
bus_sink: false
|
|
||||||
bus_source: false
|
|
||||||
bus_structure: null
|
|
||||||
coordinate: [456, 8.0]
|
|
||||||
rotation: 0
|
|
||||||
state: enabled
|
|
||||||
- name: analog_agc_xx_0
|
|
||||||
id: analog_agc_xx
|
|
||||||
parameters:
|
|
||||||
affinity: ''
|
|
||||||
alias: ''
|
|
||||||
comment: ''
|
|
||||||
gain: '1.0'
|
|
||||||
max_gain: '65536'
|
|
||||||
maxoutbuf: '0'
|
|
||||||
minoutbuf: '0'
|
|
||||||
rate: 1e-4
|
|
||||||
reference: '0.7'
|
|
||||||
type: complex
|
|
||||||
states:
|
|
||||||
bus_sink: false
|
|
||||||
bus_source: false
|
|
||||||
bus_structure: null
|
|
||||||
coordinate: [360, 312.0]
|
|
||||||
rotation: 0
|
|
||||||
state: enabled
|
|
||||||
- name: analog_quadrature_demod_cf_0
|
- name: analog_quadrature_demod_cf_0
|
||||||
id: analog_quadrature_demod_cf
|
id: analog_quadrature_demod_cf
|
||||||
parameters:
|
parameters:
|
||||||
|
@ -114,7 +70,7 @@ blocks:
|
||||||
bus_sink: false
|
bus_sink: false
|
||||||
bus_source: false
|
bus_source: false
|
||||||
bus_structure: null
|
bus_structure: null
|
||||||
coordinate: [768, 616.0]
|
coordinate: [640, 536.0]
|
||||||
rotation: 0
|
rotation: 0
|
||||||
state: true
|
state: true
|
||||||
- name: blocks_message_debug_0
|
- name: blocks_message_debug_0
|
||||||
|
@ -129,7 +85,7 @@ blocks:
|
||||||
bus_sink: false
|
bus_sink: false
|
||||||
bus_source: false
|
bus_source: false
|
||||||
bus_structure: null
|
bus_structure: null
|
||||||
coordinate: [1056, 112.0]
|
coordinate: [928, 32.0]
|
||||||
rotation: 0
|
rotation: 0
|
||||||
state: true
|
state: true
|
||||||
- name: blocks_probe_rate_0
|
- name: blocks_probe_rate_0
|
||||||
|
@ -149,7 +105,7 @@ blocks:
|
||||||
bus_sink: false
|
bus_sink: false
|
||||||
bus_source: false
|
bus_source: false
|
||||||
bus_structure: null
|
bus_structure: null
|
||||||
coordinate: [768, 120.0]
|
coordinate: [640, 40.0]
|
||||||
rotation: 0
|
rotation: 0
|
||||||
state: true
|
state: true
|
||||||
- name: digital_costas_loop_cc_0
|
- name: digital_costas_loop_cc_0
|
||||||
|
@ -167,33 +123,9 @@ blocks:
|
||||||
bus_sink: false
|
bus_sink: false
|
||||||
bus_source: false
|
bus_source: false
|
||||||
bus_structure: null
|
bus_structure: null
|
||||||
coordinate: [768, 424.0]
|
coordinate: [640, 344.0]
|
||||||
rotation: 0
|
rotation: 0
|
||||||
state: true
|
state: true
|
||||||
- name: low_pass_filter_0
|
|
||||||
id: low_pass_filter
|
|
||||||
parameters:
|
|
||||||
affinity: ''
|
|
||||||
alias: ''
|
|
||||||
beta: '6.76'
|
|
||||||
comment: ''
|
|
||||||
cutoff_freq: samp_rate / 8
|
|
||||||
decim: decimation
|
|
||||||
gain: '1'
|
|
||||||
interp: '1'
|
|
||||||
maxoutbuf: '0'
|
|
||||||
minoutbuf: '0'
|
|
||||||
samp_rate: rf_rate
|
|
||||||
type: fir_filter_ccf
|
|
||||||
width: samp_rate / 8
|
|
||||||
win: window.WIN_HAMMING
|
|
||||||
states:
|
|
||||||
bus_sink: false
|
|
||||||
bus_source: false
|
|
||||||
bus_structure: null
|
|
||||||
coordinate: [520, 284.0]
|
|
||||||
rotation: 0
|
|
||||||
state: enabled
|
|
||||||
- name: osmosdr_source_0
|
- name: osmosdr_source_0
|
||||||
id: osmosdr_source
|
id: osmosdr_source
|
||||||
parameters:
|
parameters:
|
||||||
|
@ -232,7 +164,7 @@ blocks:
|
||||||
ant8: ''
|
ant8: ''
|
||||||
ant9: ''
|
ant9: ''
|
||||||
args: '"rtl_tcp"'
|
args: '"rtl_tcp"'
|
||||||
bb_gain0: '0'
|
bb_gain0: '20'
|
||||||
bb_gain1: '20'
|
bb_gain1: '20'
|
||||||
bb_gain10: '20'
|
bb_gain10: '20'
|
||||||
bb_gain11: '20'
|
bb_gain11: '20'
|
||||||
|
@ -401,7 +333,7 @@ blocks:
|
||||||
freq7: 100e6
|
freq7: 100e6
|
||||||
freq8: 100e6
|
freq8: 100e6
|
||||||
freq9: 100e6
|
freq9: 100e6
|
||||||
gain0: '0'
|
gain0: '10'
|
||||||
gain1: '10'
|
gain1: '10'
|
||||||
gain10: '10'
|
gain10: '10'
|
||||||
gain11: '10'
|
gain11: '10'
|
||||||
|
@ -465,7 +397,7 @@ blocks:
|
||||||
gain_mode7: 'False'
|
gain_mode7: 'False'
|
||||||
gain_mode8: 'False'
|
gain_mode8: 'False'
|
||||||
gain_mode9: 'False'
|
gain_mode9: 'False'
|
||||||
if_gain0: '0'
|
if_gain0: '20'
|
||||||
if_gain1: '20'
|
if_gain1: '20'
|
||||||
if_gain10: '20'
|
if_gain10: '20'
|
||||||
if_gain11: '20'
|
if_gain11: '20'
|
||||||
|
@ -533,7 +465,7 @@ blocks:
|
||||||
minoutbuf: '0'
|
minoutbuf: '0'
|
||||||
nchan: '1'
|
nchan: '1'
|
||||||
num_mboards: '1'
|
num_mboards: '1'
|
||||||
sample_rate: rf_rate
|
sample_rate: samp_rate
|
||||||
sync: sync
|
sync: sync
|
||||||
time_source0: ''
|
time_source0: ''
|
||||||
time_source1: ''
|
time_source1: ''
|
||||||
|
@ -548,7 +480,7 @@ blocks:
|
||||||
bus_sink: false
|
bus_sink: false
|
||||||
bus_source: false
|
bus_source: false
|
||||||
bus_structure: null
|
bus_structure: null
|
||||||
coordinate: [104, 244.0]
|
coordinate: [152, 164.0]
|
||||||
rotation: 0
|
rotation: 0
|
||||||
state: enabled
|
state: enabled
|
||||||
- name: qtgui_const_sink_x_0
|
- name: qtgui_const_sink_x_0
|
||||||
|
@ -640,7 +572,7 @@ blocks:
|
||||||
bus_sink: false
|
bus_sink: false
|
||||||
bus_source: false
|
bus_source: false
|
||||||
bus_structure: null
|
bus_structure: null
|
||||||
coordinate: [1056, 408.0]
|
coordinate: [928, 328.0]
|
||||||
rotation: 0
|
rotation: 0
|
||||||
state: true
|
state: true
|
||||||
- name: qtgui_time_sink_x_0
|
- name: qtgui_time_sink_x_0
|
||||||
|
@ -737,7 +669,7 @@ blocks:
|
||||||
bus_sink: false
|
bus_sink: false
|
||||||
bus_source: false
|
bus_source: false
|
||||||
bus_structure: null
|
bus_structure: null
|
||||||
coordinate: [768, 312.0]
|
coordinate: [640, 232.0]
|
||||||
rotation: 0
|
rotation: 0
|
||||||
state: true
|
state: true
|
||||||
- name: qtgui_time_sink_x_0_0
|
- name: qtgui_time_sink_x_0_0
|
||||||
|
@ -834,7 +766,7 @@ blocks:
|
||||||
bus_sink: false
|
bus_sink: false
|
||||||
bus_source: false
|
bus_source: false
|
||||||
bus_structure: null
|
bus_structure: null
|
||||||
coordinate: [1056, 592.0]
|
coordinate: [928, 512.0]
|
||||||
rotation: 0
|
rotation: 0
|
||||||
state: true
|
state: true
|
||||||
- name: qtgui_time_sink_x_0_1
|
- name: qtgui_time_sink_x_0_1
|
||||||
|
@ -931,7 +863,7 @@ blocks:
|
||||||
bus_sink: false
|
bus_sink: false
|
||||||
bus_source: false
|
bus_source: false
|
||||||
bus_structure: null
|
bus_structure: null
|
||||||
coordinate: [1056, 480.0]
|
coordinate: [928, 400.0]
|
||||||
rotation: 0
|
rotation: 0
|
||||||
state: true
|
state: true
|
||||||
- name: qtgui_waterfall_sink_x_0_0
|
- name: qtgui_waterfall_sink_x_0_0
|
||||||
|
@ -992,22 +924,20 @@ blocks:
|
||||||
bus_sink: false
|
bus_sink: false
|
||||||
bus_source: false
|
bus_source: false
|
||||||
bus_structure: null
|
bus_structure: null
|
||||||
coordinate: [768, 208.0]
|
coordinate: [640, 128.0]
|
||||||
rotation: 0
|
rotation: 0
|
||||||
state: true
|
state: true
|
||||||
|
|
||||||
connections:
|
connections:
|
||||||
- [analog_agc_xx_0, '0', low_pass_filter_0, '0']
|
|
||||||
- [analog_quadrature_demod_cf_0, '0', qtgui_time_sink_x_0_0, '0']
|
- [analog_quadrature_demod_cf_0, '0', qtgui_time_sink_x_0_0, '0']
|
||||||
- [blocks_probe_rate_0, rate, blocks_message_debug_0, print]
|
- [blocks_probe_rate_0, rate, blocks_message_debug_0, print]
|
||||||
- [digital_costas_loop_cc_0, '0', qtgui_const_sink_x_0, '0']
|
- [digital_costas_loop_cc_0, '0', qtgui_const_sink_x_0, '0']
|
||||||
- [digital_costas_loop_cc_0, '0', qtgui_time_sink_x_0_1, '0']
|
- [digital_costas_loop_cc_0, '0', qtgui_time_sink_x_0_1, '0']
|
||||||
- [low_pass_filter_0, '0', analog_quadrature_demod_cf_0, '0']
|
- [osmosdr_source_0, '0', analog_quadrature_demod_cf_0, '0']
|
||||||
- [low_pass_filter_0, '0', blocks_probe_rate_0, '0']
|
- [osmosdr_source_0, '0', blocks_probe_rate_0, '0']
|
||||||
- [low_pass_filter_0, '0', digital_costas_loop_cc_0, '0']
|
- [osmosdr_source_0, '0', digital_costas_loop_cc_0, '0']
|
||||||
- [low_pass_filter_0, '0', qtgui_time_sink_x_0, '0']
|
- [osmosdr_source_0, '0', qtgui_time_sink_x_0, '0']
|
||||||
- [low_pass_filter_0, '0', qtgui_waterfall_sink_x_0_0, '0']
|
- [osmosdr_source_0, '0', qtgui_waterfall_sink_x_0_0, '0']
|
||||||
- [osmosdr_source_0, '0', analog_agc_xx_0, '0']
|
|
||||||
|
|
||||||
metadata:
|
metadata:
|
||||||
file_format: 1
|
file_format: 1
|
||||||
|
|
|
@ -1,5 +1,4 @@
|
||||||
cmake_minimum_required(VERSION 3.21)
|
cmake_minimum_required(VERSION 3.21)
|
||||||
set(CMAKE_EXPORT_COMPILE_COMMANDS ON)
|
|
||||||
|
|
||||||
include($ENV{PICO_SDK_PATH}/pico_sdk_init.cmake)
|
include($ENV{PICO_SDK_PATH}/pico_sdk_init.cmake)
|
||||||
|
|
||||||
|
|
50
src/cordic.h
Normal file
50
src/cordic.h
Normal file
|
@ -0,0 +1,50 @@
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2020 STMicroelectronics.
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* This software component is licensed by ST under BSD 3-Clause license,
|
||||||
|
* the "License"; You may not use this file except in compliance with the
|
||||||
|
* License. You may obtain a copy of the License at:
|
||||||
|
*
|
||||||
|
* https://opensource.org/licenses/BSD-3-Clause
|
||||||
|
*/
|
||||||
|
|
||||||
|
#define CORDIC_MAXITER 9
|
||||||
|
#define CORDIC_PI 0x10000000
|
||||||
|
|
||||||
|
static int CORDIC_ZTBL[] = { 0x04000000, 0x025C80A4, 0x013F670B, 0x00A2223B, 0x005161A8, 0x0028BAFC,
|
||||||
|
0x00145EC4, 0x000A2F8B, 0x000517CA, 0x00028BE6, 0x000145F3, 0x0000A2FA,
|
||||||
|
0x0000517D, 0x000028BE, 0x0000145F, 0x00000A30 };
|
||||||
|
|
||||||
|
inline static __attribute__((__unused__)) int fast_atan2(int y, int x)
|
||||||
|
{
|
||||||
|
int k, tx, z = 0, fl = 0;
|
||||||
|
|
||||||
|
if (x < 0) {
|
||||||
|
fl = ((y > 0) ? +1 : -1);
|
||||||
|
x = -x;
|
||||||
|
y = -y;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (k = 0; k < CORDIC_MAXITER; k++) {
|
||||||
|
tx = x;
|
||||||
|
|
||||||
|
if (y <= 0) {
|
||||||
|
x -= (y >> k);
|
||||||
|
y += (tx >> k);
|
||||||
|
z -= CORDIC_ZTBL[k];
|
||||||
|
} else {
|
||||||
|
x += (y >> k);
|
||||||
|
y -= (tx >> k);
|
||||||
|
z += CORDIC_ZTBL[k];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (fl != 0) {
|
||||||
|
z += fl * CORDIC_PI;
|
||||||
|
}
|
||||||
|
|
||||||
|
return z;
|
||||||
|
}
|
797
src/main.c
797
src/main.c
File diff suppressed because it is too large
Load diff
2
src/vendor/pico-stdio-usb-simple
vendored
2
src/vendor/pico-stdio-usb-simple
vendored
|
@ -1 +1 @@
|
||||||
Subproject commit ed4858dda407ec66626aade9b7c6ad6016539f4c
|
Subproject commit b6b09e34b844326a156bc6734146a88111138473
|
Loading…
Reference in a new issue