Compare commits
1 commit
master
...
headphones
Author | SHA1 | Date | |
---|---|---|---|
83bb953842 |
10 changed files with 555 additions and 495 deletions
1
.gitignore
vendored
1
.gitignore
vendored
|
@ -1,3 +1,2 @@
|
|||
/build/
|
||||
/grc/*.py
|
||||
/.cache/
|
||||
|
|
|
@ -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. 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
|
||||
parameters:
|
||||
comment: ''
|
||||
value: '200_000'
|
||||
value: '192_000'
|
||||
states:
|
||||
bus_sink: false
|
||||
bus_source: false
|
||||
|
@ -78,7 +78,7 @@ blocks:
|
|||
parameters:
|
||||
affinity: ''
|
||||
alias: ''
|
||||
audio_decimation: '8'
|
||||
audio_decimation: '4'
|
||||
comment: ''
|
||||
deemph_tau: 75e-6
|
||||
maxoutbuf: '0'
|
||||
|
@ -100,7 +100,7 @@ blocks:
|
|||
device_name: ''
|
||||
num_inputs: '2'
|
||||
ok_to_block: 'True'
|
||||
samp_rate: samp_rate // 8
|
||||
samp_rate: samp_rate // 4
|
||||
states:
|
||||
bus_sink: false
|
||||
bus_source: false
|
||||
|
@ -150,15 +150,15 @@ blocks:
|
|||
alias: ''
|
||||
beta: '6.76'
|
||||
comment: ''
|
||||
cutoff_freq: samp_rate / 16
|
||||
decim: '8'
|
||||
cutoff_freq: samp_rate / 8
|
||||
decim: '4'
|
||||
gain: '1'
|
||||
interp: '1'
|
||||
maxoutbuf: '0'
|
||||
minoutbuf: '0'
|
||||
samp_rate: samp_rate
|
||||
type: fir_filter_fff
|
||||
width: samp_rate / 16
|
||||
width: samp_rate / 8
|
||||
win: window.WIN_HAMMING
|
||||
states:
|
||||
bus_sink: false
|
||||
|
@ -205,7 +205,7 @@ blocks:
|
|||
ant8: ''
|
||||
ant9: ''
|
||||
args: '"rtl_tcp"'
|
||||
bb_gain0: '0'
|
||||
bb_gain0: '20'
|
||||
bb_gain1: '20'
|
||||
bb_gain10: '20'
|
||||
bb_gain11: '20'
|
||||
|
@ -374,7 +374,7 @@ blocks:
|
|||
freq7: 100e6
|
||||
freq8: 100e6
|
||||
freq9: 100e6
|
||||
gain0: '0'
|
||||
gain0: '10'
|
||||
gain1: '10'
|
||||
gain10: '10'
|
||||
gain11: '10'
|
||||
|
@ -438,7 +438,7 @@ blocks:
|
|||
gain_mode7: 'False'
|
||||
gain_mode8: 'False'
|
||||
gain_mode9: 'False'
|
||||
if_gain0: '0'
|
||||
if_gain0: '20'
|
||||
if_gain1: '20'
|
||||
if_gain10: '20'
|
||||
if_gain11: '20'
|
||||
|
@ -677,7 +677,7 @@ blocks:
|
|||
name: '"FM Demodulation"'
|
||||
nconnections: '1'
|
||||
size: '512'
|
||||
srate: samp_rate // 8
|
||||
srate: samp_rate // (2 ** 3)
|
||||
stemplot: 'False'
|
||||
style1: '1'
|
||||
style10: '1'
|
||||
|
@ -856,4 +856,4 @@ connections:
|
|||
|
||||
metadata:
|
||||
file_format: 1
|
||||
grc_version: 3.10.11.0
|
||||
grc_version: 3.10.9.2
|
||||
|
|
148
grc/PicoSDR.grc
148
grc/PicoSDR.grc
|
@ -37,7 +37,7 @@ blocks:
|
|||
id: variable
|
||||
parameters:
|
||||
comment: ''
|
||||
value: 169.5e6
|
||||
value: '40_680_000'
|
||||
states:
|
||||
bus_sink: false
|
||||
bus_source: false
|
||||
|
@ -45,60 +45,16 @@ blocks:
|
|||
coordinate: [168, 8.0]
|
||||
rotation: 0
|
||||
state: enabled
|
||||
- name: decimation
|
||||
id: variable
|
||||
parameters:
|
||||
comment: ''
|
||||
value: '16'
|
||||
states:
|
||||
bus_sink: false
|
||||
bus_source: false
|
||||
bus_structure: null
|
||||
coordinate: [368, 8.0]
|
||||
rotation: 0
|
||||
state: enabled
|
||||
- name: rf_rate
|
||||
id: variable
|
||||
parameters:
|
||||
comment: ''
|
||||
value: '400_000'
|
||||
states:
|
||||
bus_sink: false
|
||||
bus_source: false
|
||||
bus_structure: null
|
||||
coordinate: [280, 8.0]
|
||||
rotation: 0
|
||||
state: enabled
|
||||
- name: samp_rate
|
||||
id: variable
|
||||
parameters:
|
||||
comment: ''
|
||||
value: rf_rate // decimation
|
||||
value: '50_000'
|
||||
states:
|
||||
bus_sink: false
|
||||
bus_source: false
|
||||
bus_structure: null
|
||||
coordinate: [472, 8.0]
|
||||
rotation: 0
|
||||
state: enabled
|
||||
- name: analog_agc_xx_0
|
||||
id: analog_agc_xx
|
||||
parameters:
|
||||
affinity: ''
|
||||
alias: ''
|
||||
comment: ''
|
||||
gain: '1.0'
|
||||
max_gain: '1'
|
||||
maxoutbuf: '0'
|
||||
minoutbuf: '0'
|
||||
rate: 1e-4
|
||||
reference: '0.707'
|
||||
type: complex
|
||||
states:
|
||||
bus_sink: false
|
||||
bus_source: false
|
||||
bus_structure: null
|
||||
coordinate: [632, 312.0]
|
||||
coordinate: [264, 8.0]
|
||||
rotation: 0
|
||||
state: enabled
|
||||
- name: analog_quadrature_demod_cf_0
|
||||
|
@ -114,26 +70,9 @@ blocks:
|
|||
bus_sink: false
|
||||
bus_source: false
|
||||
bus_structure: null
|
||||
coordinate: [912, 616.0]
|
||||
coordinate: [640, 536.0]
|
||||
rotation: 0
|
||||
state: true
|
||||
- name: blocks_freqshift_cc_0
|
||||
id: blocks_freqshift_cc
|
||||
parameters:
|
||||
affinity: ''
|
||||
alias: ''
|
||||
comment: ''
|
||||
freq: '0'
|
||||
maxoutbuf: '0'
|
||||
minoutbuf: '0'
|
||||
sample_rate: rf_rate
|
||||
states:
|
||||
bus_sink: false
|
||||
bus_source: false
|
||||
bus_structure: null
|
||||
coordinate: [256, 328.0]
|
||||
rotation: 0
|
||||
state: enabled
|
||||
- name: blocks_message_debug_0
|
||||
id: blocks_message_debug
|
||||
parameters:
|
||||
|
@ -146,7 +85,7 @@ blocks:
|
|||
bus_sink: false
|
||||
bus_source: false
|
||||
bus_structure: null
|
||||
coordinate: [1200, 112.0]
|
||||
coordinate: [928, 32.0]
|
||||
rotation: 0
|
||||
state: true
|
||||
- name: blocks_probe_rate_0
|
||||
|
@ -166,7 +105,7 @@ blocks:
|
|||
bus_sink: false
|
||||
bus_source: false
|
||||
bus_structure: null
|
||||
coordinate: [912, 120.0]
|
||||
coordinate: [640, 40.0]
|
||||
rotation: 0
|
||||
state: true
|
||||
- name: digital_costas_loop_cc_0
|
||||
|
@ -179,38 +118,14 @@ blocks:
|
|||
minoutbuf: '0'
|
||||
order: '2'
|
||||
use_snr: 'False'
|
||||
w: math.pi / 100
|
||||
w: 2 * math.pi / 100
|
||||
states:
|
||||
bus_sink: false
|
||||
bus_source: false
|
||||
bus_structure: null
|
||||
coordinate: [912, 424.0]
|
||||
coordinate: [640, 344.0]
|
||||
rotation: 0
|
||||
state: true
|
||||
- name: low_pass_filter_0
|
||||
id: low_pass_filter
|
||||
parameters:
|
||||
affinity: ''
|
||||
alias: ''
|
||||
beta: '6.76'
|
||||
comment: ''
|
||||
cutoff_freq: samp_rate / 4
|
||||
decim: decimation
|
||||
gain: '1'
|
||||
interp: '1'
|
||||
maxoutbuf: '0'
|
||||
minoutbuf: '0'
|
||||
samp_rate: rf_rate
|
||||
type: fir_filter_ccf
|
||||
width: samp_rate / 4
|
||||
win: window.WIN_HAMMING
|
||||
states:
|
||||
bus_sink: false
|
||||
bus_source: false
|
||||
bus_structure: null
|
||||
coordinate: [440, 284.0]
|
||||
rotation: 0
|
||||
state: enabled
|
||||
- name: osmosdr_source_0
|
||||
id: osmosdr_source
|
||||
parameters:
|
||||
|
@ -249,7 +164,7 @@ blocks:
|
|||
ant8: ''
|
||||
ant9: ''
|
||||
args: '"rtl_tcp"'
|
||||
bb_gain0: '0'
|
||||
bb_gain0: '20'
|
||||
bb_gain1: '20'
|
||||
bb_gain10: '20'
|
||||
bb_gain11: '20'
|
||||
|
@ -418,7 +333,7 @@ blocks:
|
|||
freq7: 100e6
|
||||
freq8: 100e6
|
||||
freq9: 100e6
|
||||
gain0: '0'
|
||||
gain0: '10'
|
||||
gain1: '10'
|
||||
gain10: '10'
|
||||
gain11: '10'
|
||||
|
@ -482,7 +397,7 @@ blocks:
|
|||
gain_mode7: 'False'
|
||||
gain_mode8: 'False'
|
||||
gain_mode9: 'False'
|
||||
if_gain0: '0'
|
||||
if_gain0: '20'
|
||||
if_gain1: '20'
|
||||
if_gain10: '20'
|
||||
if_gain11: '20'
|
||||
|
@ -550,7 +465,7 @@ blocks:
|
|||
minoutbuf: '0'
|
||||
nchan: '1'
|
||||
num_mboards: '1'
|
||||
sample_rate: rf_rate
|
||||
sample_rate: samp_rate
|
||||
sync: sync
|
||||
time_source0: ''
|
||||
time_source1: ''
|
||||
|
@ -565,7 +480,7 @@ blocks:
|
|||
bus_sink: false
|
||||
bus_source: false
|
||||
bus_structure: null
|
||||
coordinate: [8, 244.0]
|
||||
coordinate: [152, 164.0]
|
||||
rotation: 0
|
||||
state: enabled
|
||||
- name: qtgui_const_sink_x_0
|
||||
|
@ -657,7 +572,7 @@ blocks:
|
|||
bus_sink: false
|
||||
bus_source: false
|
||||
bus_structure: null
|
||||
coordinate: [1200, 408.0]
|
||||
coordinate: [928, 328.0]
|
||||
rotation: 0
|
||||
state: true
|
||||
- name: qtgui_time_sink_x_0
|
||||
|
@ -717,7 +632,7 @@ blocks:
|
|||
nconnections: '1'
|
||||
size: '256'
|
||||
srate: samp_rate
|
||||
stemplot: 'True'
|
||||
stemplot: 'False'
|
||||
style1: '1'
|
||||
style10: '1'
|
||||
style2: '1'
|
||||
|
@ -754,7 +669,7 @@ blocks:
|
|||
bus_sink: false
|
||||
bus_source: false
|
||||
bus_structure: null
|
||||
coordinate: [912, 312.0]
|
||||
coordinate: [640, 232.0]
|
||||
rotation: 0
|
||||
state: true
|
||||
- name: qtgui_time_sink_x_0_0
|
||||
|
@ -814,7 +729,7 @@ blocks:
|
|||
nconnections: '1'
|
||||
size: '256'
|
||||
srate: samp_rate
|
||||
stemplot: 'True'
|
||||
stemplot: 'False'
|
||||
style1: '1'
|
||||
style10: '1'
|
||||
style2: '1'
|
||||
|
@ -833,7 +748,7 @@ blocks:
|
|||
tr_tag: '""'
|
||||
type: float
|
||||
update_time: 1/30
|
||||
width1: '2'
|
||||
width1: '1'
|
||||
width10: '1'
|
||||
width2: '1'
|
||||
width3: '1'
|
||||
|
@ -851,7 +766,7 @@ blocks:
|
|||
bus_sink: false
|
||||
bus_source: false
|
||||
bus_structure: null
|
||||
coordinate: [1200, 592.0]
|
||||
coordinate: [928, 512.0]
|
||||
rotation: 0
|
||||
state: true
|
||||
- name: qtgui_time_sink_x_0_1
|
||||
|
@ -911,7 +826,7 @@ blocks:
|
|||
nconnections: '1'
|
||||
size: '256'
|
||||
srate: samp_rate
|
||||
stemplot: 'True'
|
||||
stemplot: 'False'
|
||||
style1: '1'
|
||||
style10: '1'
|
||||
style2: '1'
|
||||
|
@ -930,9 +845,9 @@ blocks:
|
|||
tr_tag: '""'
|
||||
type: complex
|
||||
update_time: 1/30
|
||||
width1: '2'
|
||||
width1: '1'
|
||||
width10: '1'
|
||||
width2: '2'
|
||||
width2: '1'
|
||||
width3: '1'
|
||||
width4: '1'
|
||||
width5: '1'
|
||||
|
@ -948,7 +863,7 @@ blocks:
|
|||
bus_sink: false
|
||||
bus_source: false
|
||||
bus_structure: null
|
||||
coordinate: [1200, 480.0]
|
||||
coordinate: [928, 400.0]
|
||||
rotation: 0
|
||||
state: true
|
||||
- name: qtgui_waterfall_sink_x_0_0
|
||||
|
@ -1009,24 +924,21 @@ blocks:
|
|||
bus_sink: false
|
||||
bus_source: false
|
||||
bus_structure: null
|
||||
coordinate: [912, 208.0]
|
||||
coordinate: [640, 128.0]
|
||||
rotation: 0
|
||||
state: true
|
||||
|
||||
connections:
|
||||
- [analog_agc_xx_0, '0', analog_quadrature_demod_cf_0, '0']
|
||||
- [analog_agc_xx_0, '0', blocks_probe_rate_0, '0']
|
||||
- [analog_agc_xx_0, '0', digital_costas_loop_cc_0, '0']
|
||||
- [analog_agc_xx_0, '0', qtgui_time_sink_x_0, '0']
|
||||
- [analog_agc_xx_0, '0', qtgui_waterfall_sink_x_0_0, '0']
|
||||
- [analog_quadrature_demod_cf_0, '0', qtgui_time_sink_x_0_0, '0']
|
||||
- [blocks_freqshift_cc_0, '0', low_pass_filter_0, '0']
|
||||
- [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_time_sink_x_0_1, '0']
|
||||
- [low_pass_filter_0, '0', analog_agc_xx_0, '0']
|
||||
- [osmosdr_source_0, '0', blocks_freqshift_cc_0, '0']
|
||||
- [osmosdr_source_0, '0', analog_quadrature_demod_cf_0, '0']
|
||||
- [osmosdr_source_0, '0', blocks_probe_rate_0, '0']
|
||||
- [osmosdr_source_0, '0', digital_costas_loop_cc_0, '0']
|
||||
- [osmosdr_source_0, '0', qtgui_time_sink_x_0, '0']
|
||||
- [osmosdr_source_0, '0', qtgui_waterfall_sink_x_0_0, '0']
|
||||
|
||||
metadata:
|
||||
file_format: 1
|
||||
grc_version: 3.10.11.0
|
||||
grc_version: 3.10.9.2
|
||||
|
|
|
@ -1,2 +0,0 @@
|
|||
CompileFlags:
|
||||
CompilationDatabase: ../build
|
|
@ -1,5 +1,4 @@
|
|||
cmake_minimum_required(VERSION 3.21)
|
||||
set(CMAKE_EXPORT_COMPILE_COMMANDS ON)
|
||||
|
||||
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;
|
||||
}
|
805
src/main.c
805
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
|
|
@ -1,15 +1,8 @@
|
|||
#!/usr/bin/env python
|
||||
|
||||
import struct
|
||||
from socket import (
|
||||
AF_INET6,
|
||||
MSG_DONTWAIT,
|
||||
SO_REUSEADDR,
|
||||
SO_SNDBUF,
|
||||
SOCK_STREAM,
|
||||
SOL_SOCKET,
|
||||
socket,
|
||||
)
|
||||
from socket import (AF_INET, MSG_DONTWAIT, SO_REUSEADDR, SO_SNDBUF,
|
||||
SOCK_STREAM, SOL_SOCKET, socket)
|
||||
|
||||
import click
|
||||
import serial
|
||||
|
@ -44,12 +37,12 @@ def describe(cmd: int, arg: int):
|
|||
@click.option("-f", "--frequency", default=88200000, help="Frequency to tune to")
|
||||
@click.option("-d", "--device", default="/dev/ttyACM0", help="Serial port device")
|
||||
def bridge(frequency, device):
|
||||
sock = socket(AF_INET6, SOCK_STREAM)
|
||||
sock = socket(AF_INET, SOCK_STREAM)
|
||||
sock.setsockopt(SOL_SOCKET, SO_REUSEADDR, 1)
|
||||
sock.setsockopt(SOL_SOCKET, SO_SNDBUF, 1024 * 100)
|
||||
|
||||
print("Posing as rtl_tcp at tcp://localhost:1234")
|
||||
sock.bind(("::", 1234))
|
||||
print("Posing as rtl_tcp at tcp://127.0.0.1:1234")
|
||||
sock.bind(("127.0.0.1", 1234))
|
||||
sock.listen(3)
|
||||
|
||||
while True:
|
||||
|
|
Loading…
Reference in a new issue