diff --git a/.gitignore b/.gitignore index c5d3b94..4613b38 100644 --- a/.gitignore +++ b/.gitignore @@ -1,2 +1,3 @@ /build/ /grc/*.py +/.cache/ diff --git a/grc/PicoSDR.grc b/grc/PicoSDR.grc index 70ffba7..e8afc05 100644 --- a/grc/PicoSDR.grc +++ b/grc/PicoSDR.grc @@ -37,7 +37,7 @@ blocks: id: variable parameters: comment: '' - value: '40_680_000' + value: 169.5e6 states: bus_sink: false bus_source: false @@ -49,24 +49,24 @@ blocks: id: variable parameters: comment: '' - value: '4' + value: '16' states: bus_sink: false bus_source: false bus_structure: null - coordinate: [352, 8.0] + coordinate: [368, 8.0] rotation: 0 state: enabled - name: rf_rate id: variable parameters: comment: '' - value: '200_000' + value: '400_000' states: bus_sink: false bus_source: false bus_structure: null - coordinate: [264, 8.0] + coordinate: [280, 8.0] rotation: 0 state: enabled - name: samp_rate @@ -78,7 +78,7 @@ blocks: bus_sink: false bus_source: false bus_structure: null - coordinate: [456, 8.0] + coordinate: [472, 8.0] rotation: 0 state: enabled - name: analog_agc_xx_0 @@ -88,17 +88,17 @@ blocks: alias: '' comment: '' gain: '1.0' - max_gain: '65536' + max_gain: '1' maxoutbuf: '0' minoutbuf: '0' rate: 1e-4 - reference: '0.7' + reference: '0.707' type: complex states: bus_sink: false bus_source: false bus_structure: null - coordinate: [360, 312.0] + coordinate: [632, 312.0] rotation: 0 state: enabled - name: analog_quadrature_demod_cf_0 @@ -114,9 +114,26 @@ blocks: bus_sink: false bus_source: false bus_structure: null - coordinate: [768, 616.0] + coordinate: [912, 616.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: @@ -129,7 +146,7 @@ blocks: bus_sink: false bus_source: false bus_structure: null - coordinate: [1056, 112.0] + coordinate: [1200, 112.0] rotation: 0 state: true - name: blocks_probe_rate_0 @@ -149,7 +166,7 @@ blocks: bus_sink: false bus_source: false bus_structure: null - coordinate: [768, 120.0] + coordinate: [912, 120.0] rotation: 0 state: true - name: digital_costas_loop_cc_0 @@ -162,12 +179,12 @@ blocks: minoutbuf: '0' order: '2' use_snr: 'False' - w: 2 * math.pi / 100 + w: math.pi / 100 states: bus_sink: false bus_source: false bus_structure: null - coordinate: [768, 424.0] + coordinate: [912, 424.0] rotation: 0 state: true - name: low_pass_filter_0 @@ -177,7 +194,7 @@ blocks: alias: '' beta: '6.76' comment: '' - cutoff_freq: samp_rate / 8 + cutoff_freq: samp_rate / 4 decim: decimation gain: '1' interp: '1' @@ -185,13 +202,13 @@ blocks: minoutbuf: '0' samp_rate: rf_rate type: fir_filter_ccf - width: samp_rate / 8 + width: samp_rate / 4 win: window.WIN_HAMMING states: bus_sink: false bus_source: false bus_structure: null - coordinate: [520, 284.0] + coordinate: [440, 284.0] rotation: 0 state: enabled - name: osmosdr_source_0 @@ -548,7 +565,7 @@ blocks: bus_sink: false bus_source: false bus_structure: null - coordinate: [104, 244.0] + coordinate: [8, 244.0] rotation: 0 state: enabled - name: qtgui_const_sink_x_0 @@ -640,7 +657,7 @@ blocks: bus_sink: false bus_source: false bus_structure: null - coordinate: [1056, 408.0] + coordinate: [1200, 408.0] rotation: 0 state: true - name: qtgui_time_sink_x_0 @@ -700,7 +717,7 @@ blocks: nconnections: '1' size: '256' srate: samp_rate - stemplot: 'False' + stemplot: 'True' style1: '1' style10: '1' style2: '1' @@ -737,7 +754,7 @@ blocks: bus_sink: false bus_source: false bus_structure: null - coordinate: [768, 312.0] + coordinate: [912, 312.0] rotation: 0 state: true - name: qtgui_time_sink_x_0_0 @@ -797,7 +814,7 @@ blocks: nconnections: '1' size: '256' srate: samp_rate - stemplot: 'False' + stemplot: 'True' style1: '1' style10: '1' style2: '1' @@ -816,7 +833,7 @@ blocks: tr_tag: '""' type: float update_time: 1/30 - width1: '1' + width1: '2' width10: '1' width2: '1' width3: '1' @@ -834,7 +851,7 @@ blocks: bus_sink: false bus_source: false bus_structure: null - coordinate: [1056, 592.0] + coordinate: [1200, 592.0] rotation: 0 state: true - name: qtgui_time_sink_x_0_1 @@ -894,7 +911,7 @@ blocks: nconnections: '1' size: '256' srate: samp_rate - stemplot: 'False' + stemplot: 'True' style1: '1' style10: '1' style2: '1' @@ -913,9 +930,9 @@ blocks: tr_tag: '""' type: complex update_time: 1/30 - width1: '1' + width1: '2' width10: '1' - width2: '1' + width2: '2' width3: '1' width4: '1' width5: '1' @@ -931,7 +948,7 @@ blocks: bus_sink: false bus_source: false bus_structure: null - coordinate: [1056, 480.0] + coordinate: [1200, 480.0] rotation: 0 state: true - name: qtgui_waterfall_sink_x_0_0 @@ -992,23 +1009,24 @@ blocks: bus_sink: false bus_source: false bus_structure: null - coordinate: [768, 208.0] + coordinate: [912, 208.0] rotation: 0 state: true connections: -- [analog_agc_xx_0, '0', low_pass_filter_0, '0'] +- [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_quadrature_demod_cf_0, '0'] -- [low_pass_filter_0, '0', blocks_probe_rate_0, '0'] -- [low_pass_filter_0, '0', digital_costas_loop_cc_0, '0'] -- [low_pass_filter_0, '0', qtgui_time_sink_x_0, '0'] -- [low_pass_filter_0, '0', qtgui_waterfall_sink_x_0_0, '0'] -- [osmosdr_source_0, '0', analog_agc_xx_0, '0'] +- [low_pass_filter_0, '0', analog_agc_xx_0, '0'] +- [osmosdr_source_0, '0', blocks_freqshift_cc_0, '0'] metadata: file_format: 1 - grc_version: 3.10.9.2 + grc_version: 3.10.11.0 diff --git a/src/main.c b/src/main.c index 39fe9fc..33e3391 100644 --- a/src/main.c +++ b/src/main.c @@ -21,12 +21,13 @@ #include #include -#define VREG_VOLTAGE VREG_VOLTAGE_1_20 -#define CLK_SYS_HZ (320 * MHZ) +#define VREG_VOLTAGE VREG_VOLTAGE_1_30 +#define CLK_SYS_HZ (300 * MHZ) #define RX_PIN 10 #define FB_PIN 6 #define PSU_PIN 23 +#define AMP_PIN 21 #define PIO pio0 #define SM_RX 0 @@ -46,8 +47,8 @@ #define SIN_PHASE (0u) #define COS_PHASE (3u << 30) -static uint32_t lo_cos[LO_WORDS] __attribute__((__aligned__(1 << LO_BITS_DEPTH))); -static uint32_t lo_sin[LO_WORDS] __attribute__((__aligned__(1 << LO_BITS_DEPTH))); +static uint32_t lo_cos[LO_WORDS] __aligned(1 << LO_BITS_DEPTH); +static uint32_t lo_sin[LO_WORDS] __aligned(1 << LO_BITS_DEPTH); #define INIT_SAMPLE_RATE 100000 #define INIT_FREQ 94600000 @@ -55,11 +56,9 @@ static uint32_t lo_sin[LO_WORDS] __attribute__((__aligned__(1 << LO_BITS_DEPTH)) static int frequency = INIT_FREQ; static int sample_rate = INIT_SAMPLE_RATE; -#define BASE_GAIN (1 << 15) -#define ATTN_BITS 12 #define DECIMATE 4 -static int gain = BASE_GAIN / (CLK_SYS_HZ / INIT_SAMPLE_RATE); +static int gain = 0x7fff / 750; static queue_t iq_queue; static uint8_t iq_queue_buffer[IQ_QUEUE_LEN][IQ_BLOCK_LEN]; @@ -143,16 +142,8 @@ static void init_bias() gpio_set_slew_rate(FB_PIN, GPIO_SLEW_RATE_SLOW); const uint16_t insn[] = { - pio_encode_mov(pio_isr, pio_null), - pio_encode_in(pio_y, 4), - pio_encode_in(pio_pins, 1) | pio_encode_delay(15), - pio_encode_in(pio_pins, 1) | pio_encode_delay(15), - - pio_encode_mov(pio_y, pio_isr), - pio_encode_mov(pio_x, pio_isr), - - pio_encode_jmp_x_dec(6), - pio_encode_mov_not(pio_pins, pio_pins) | pio_encode_sideset(1, 1), + pio_encode_mov_not(pio_pins, pio_pins) | pio_encode_sideset(1, 1) | + pio_encode_delay(0), }; pio_program_t prog = { @@ -249,9 +240,9 @@ static void lo_generate_phase(uint32_t *buf, size_t len, uint32_t step, uint32_t static void rx_lo_init(double freq) { - double frac = (double)CLK_SYS_HZ / (8 << LO_BITS_DEPTH); - freq = roundf(freq / frac) * frac; - uint32_t step = freq * 4294967296.0 / CLK_SYS_HZ; + double n = round(freq * (8 << LO_BITS_DEPTH) / CLK_SYS_HZ); + freq = n * CLK_SYS_HZ / (8 << LO_BITS_DEPTH); + uint32_t step = fmod(freq * 4294967296.0 / CLK_SYS_HZ, 4294967296.0); lo_generate_phase(lo_cos, LO_WORDS, step, COS_PHASE); lo_generate_phase(lo_sin, LO_WORDS, step, SIN_PHASE); } @@ -516,6 +507,8 @@ inline static int getQ() static void rf_rx(void) { + int dcI = 0, dcQ = 0; + while (true) { if (multicore_fifo_rvalid()) { multicore_fifo_pop_blocking(); @@ -532,13 +525,51 @@ static void rf_rx(void) accQ(); } - int I = getI() * gain; - int Q = getQ() * gain; + // ~22-24b + int I = getI() << 12; + int Q = getQ() << 12; + + dcI += (I - dcI) >> 12; + dcQ += (Q - dcQ) >> 12; + + I -= dcI; + Q -= dcQ; + + // ~10-12b + I >>= 12; + Q >>= 12; + + // ~8b + I = (I * gain) >> 16; + Q = (Q * gain) >> 16; + + int absI = abs(I); + int absQ = abs(Q); + + if (absI >= 96 || absQ >= 96) { + gain--; + } else { + gain++; + } + + if (I < -128) + I = -128; + + if (I > 127) + I = 127; + + if (Q < -128) + Q = -128; + + if (Q > 127) + Q = 127; + + if (gain < 1) + gain = 1; + else if (gain > 0xffff) + gain = 0xffff; - I >>= ATTN_BITS; *blockptr++ = I + 128; - - Q >>= ATTN_BITS; *blockptr++ = Q + 128; } @@ -560,7 +591,6 @@ static void run_command(uint8_t cmd, uint32_t arg) } else if (0x02 == cmd) { /* Set the rate at which IQ sample pairs are sent */ sample_rate = arg; - gain = BASE_GAIN / (CLK_SYS_HZ / sample_rate); dma_timer_set_fraction(dma_t_samp, 1, CLK_SYS_HZ / (sample_rate * DECIMATE)); rx_lo_init(frequency); } @@ -641,6 +671,10 @@ int main() gpio_set_dir(PSU_PIN, GPIO_OUT); gpio_put(PSU_PIN, 1); + gpio_init(AMP_PIN); + gpio_set_dir(AMP_PIN, GPIO_OUT); + gpio_put(AMP_PIN, 1); + gpio_init(PICO_DEFAULT_LED_PIN); gpio_set_dir(PICO_DEFAULT_LED_PIN, GPIO_OUT); gpio_put(PICO_DEFAULT_LED_PIN, 0);