From 574e6aa844ef1cfcf435c7a7f83b2278154409ab Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jan=20Hamal=20Dvo=C5=99=C3=A1k?= Date: Tue, 17 Jun 2025 17:34:56 +0200 Subject: [PATCH] 70-80 dB ADC --- grc/base.grc | 391 +++++++++++++++++++++++++++++ grc/file.grc | 594 +++++++++++++++++++++++++++++++++++++++++++++ src/CMakeLists.txt | 1 + src/main.c | 219 ++++++++++++++++- 4 files changed, 1204 insertions(+), 1 deletion(-) create mode 100644 grc/base.grc create mode 100644 grc/file.grc diff --git a/grc/base.grc b/grc/base.grc new file mode 100644 index 0000000..1c379f6 --- /dev/null +++ b/grc/base.grc @@ -0,0 +1,391 @@ +options: + parameters: + author: '' + catch_exceptions: 'True' + category: '[GRC Hier Blocks]' + cmake_opt: '' + comment: '' + copyright: '' + description: '' + gen_cmake: 'On' + gen_linking: dynamic + generate_options: qt_gui + hier_block_src_path: '.:' + id: file + max_nouts: '0' + output_language: python + placement: (0,0) + qt_qss_theme: '' + realtime_scheduling: '' + run: 'True' + run_command: '{python} -u {filename}' + run_options: prompt + sizing_mode: fixed + thread_safe_setters: '' + title: Not titled yet + window_size: (1000,1000) + states: + bus_sink: false + bus_source: false + bus_structure: null + coordinate: [8, 16.0] + rotation: 0 + state: enabled + +blocks: +- name: samp_rate + id: variable + parameters: + comment: '' + value: 132e6 / 256 + states: + bus_sink: false + bus_source: false + bus_structure: null + coordinate: [168, 16.0] + rotation: 0 + state: enabled +- name: blocks_char_to_float_0 + id: blocks_char_to_float + parameters: + affinity: '' + alias: '' + comment: '' + maxoutbuf: '0' + minoutbuf: '0' + scale: '128' + vlen: '1' + states: + bus_sink: false + bus_source: false + bus_structure: null + coordinate: [224, 280.0] + rotation: 0 + state: enabled +- name: blocks_file_source_0 + id: blocks_file_source + parameters: + affinity: '' + alias: '' + begin_tag: pmt.PMT_NIL + comment: '' + file: /home/mordae/work/smart/pico-pdm/samples.fifo + length: '0' + maxoutbuf: '0' + minoutbuf: '0' + offset: '0' + repeat: 'True' + type: byte + vlen: '1' + states: + bus_sink: false + bus_source: false + bus_structure: null + coordinate: [8, 248.0] + rotation: 0 + state: enabled +- name: blocks_message_debug_0 + id: blocks_message_debug + parameters: + affinity: '' + alias: '' + comment: '' + en_uvec: 'True' + log_level: info + states: + bus_sink: false + bus_source: false + bus_structure: null + coordinate: [856, 64.0] + rotation: 0 + state: enabled +- name: blocks_probe_rate_0 + id: blocks_probe_rate + parameters: + affinity: '' + alias: '' + alpha: '1' + comment: '' + maxoutbuf: '0' + minoutbuf: '0' + mintime: 1e3 + name: '' + type: float + vlen: '1' + states: + bus_sink: false + bus_source: false + bus_structure: null + coordinate: [592, 72.0] + rotation: 0 + state: enabled +- name: dc_blocker_xx_0 + id: dc_blocker_xx + parameters: + affinity: '' + alias: '' + comment: '' + length: '256' + long_form: 'True' + maxoutbuf: '0' + minoutbuf: '0' + type: ff + states: + bus_sink: false + bus_source: false + bus_structure: null + coordinate: [592, 272.0] + rotation: 0 + state: enabled +- name: qtgui_freq_sink_x_0 + id: qtgui_freq_sink_x + parameters: + affinity: '' + alias: '' + alpha1: '1.0' + alpha10: '1.0' + alpha2: '1.0' + alpha3: '1.0' + alpha4: '1.0' + alpha5: '1.0' + alpha6: '1.0' + alpha7: '1.0' + alpha8: '1.0' + alpha9: '1.0' + autoscale: 'False' + average: '0.05' + axislabels: 'True' + bw: samp_rate + color1: '"blue"' + color10: '"dark blue"' + color2: '"red"' + color3: '"green"' + color4: '"black"' + color5: '"cyan"' + color6: '"magenta"' + color7: '"yellow"' + color8: '"dark red"' + color9: '"dark green"' + comment: '' + ctrlpanel: 'False' + fc: '0' + fftsize: '16384' + freqhalf: 'False' + grid: 'True' + gui_hint: '' + label: Relative Gain + label1: '' + label10: '''''' + label2: '''''' + label3: '''''' + label4: '''''' + label5: '''''' + label6: '''''' + label7: '''''' + label8: '''''' + label9: '''''' + legend: 'False' + maxoutbuf: '0' + minoutbuf: '0' + name: '""' + nconnections: '1' + norm_window: 'True' + showports: 'False' + tr_chan: '0' + tr_level: '0.0' + tr_mode: qtgui.TRIG_MODE_FREE + tr_tag: '""' + type: float + units: dB + update_time: 1/30 + width1: '1' + width10: '1' + width2: '1' + width3: '1' + width4: '1' + width5: '1' + width6: '1' + width7: '1' + width8: '1' + width9: '1' + wintype: window.WIN_BLACKMAN_hARRIS + ymax: '0' + ymin: '-100' + states: + bus_sink: false + bus_source: false + bus_structure: null + coordinate: [856, 400.0] + rotation: 0 + state: enabled +- name: qtgui_time_sink_x_0 + id: qtgui_time_sink_x + parameters: + affinity: '' + alias: '' + alpha1: '1.0' + alpha10: '1.0' + alpha2: '1.0' + alpha3: '1.0' + alpha4: '1.0' + alpha5: '1.0' + alpha6: '1.0' + alpha7: '1.0' + alpha8: '1.0' + alpha9: '1.0' + autoscale: 'False' + axislabels: 'True' + color1: blue + color10: dark blue + color2: red + color3: green + color4: black + color5: cyan + color6: magenta + color7: yellow + color8: dark red + color9: dark green + comment: '' + ctrlpanel: 'False' + entags: 'False' + grid: 'False' + gui_hint: '' + label1: IR + label10: Signal 10 + label2: Signal 2 + label3: Signal 3 + label4: Signal 4 + label5: Signal 5 + label6: Signal 6 + label7: Signal 7 + label8: Signal 8 + label9: Signal 9 + legend: 'False' + marker1: '-1' + marker10: '-1' + marker2: '-1' + marker3: '-1' + marker4: '-1' + marker5: '-1' + marker6: '-1' + marker7: '-1' + marker8: '-1' + marker9: '-1' + name: '""' + nconnections: '1' + size: '512' + srate: samp_rate + stemplot: 'True' + style1: '1' + style10: '1' + style2: '1' + style3: '1' + style4: '1' + style5: '1' + style6: '1' + style7: '1' + style8: '1' + style9: '1' + tr_chan: '0' + tr_delay: '0' + tr_level: '0.0' + tr_mode: qtgui.TRIG_MODE_FREE + tr_slope: qtgui.TRIG_SLOPE_POS + tr_tag: '""' + type: float + update_time: 1/30 + width1: '1' + width10: '1' + width2: '1' + width3: '1' + width4: '1' + width5: '1' + width6: '1' + width7: '1' + width8: '1' + width9: '1' + ylabel: Amplitude + ymax: '1' + ymin: '-1' + yunit: '""' + states: + bus_sink: false + bus_source: false + bus_structure: null + coordinate: [856, 304.0] + rotation: 0 + state: enabled +- name: qtgui_waterfall_sink_x_0 + id: qtgui_waterfall_sink_x + parameters: + affinity: '' + alias: '' + alpha1: '1.0' + alpha10: '1.0' + alpha2: '1.0' + alpha3: '1.0' + alpha4: '1.0' + alpha5: '1.0' + alpha6: '1.0' + alpha7: '1.0' + alpha8: '1.0' + alpha9: '1.0' + axislabels: 'True' + bw: samp_rate + color1: '0' + color10: '0' + color2: '0' + color3: '0' + color4: '0' + color5: '0' + color6: '0' + color7: '0' + color8: '0' + color9: '0' + comment: '' + fc: '0' + fftsize: '16384' + freqhalf: 'False' + grid: 'False' + gui_hint: '' + int_max: '0' + int_min: '-120' + label1: '' + label10: '' + label2: '' + label3: '' + label4: '' + label5: '' + label6: '' + label7: '' + label8: '' + label9: '' + legend: 'True' + maxoutbuf: '0' + minoutbuf: '0' + name: '""' + nconnections: '1' + showports: 'False' + type: float + update_time: 1/30 + wintype: window.WIN_BLACKMAN_hARRIS + states: + bus_sink: false + bus_source: false + bus_structure: null + coordinate: [856, 208.0] + rotation: 0 + state: enabled + +connections: +- [blocks_char_to_float_0, '0', blocks_probe_rate_0, '0'] +- [blocks_char_to_float_0, '0', dc_blocker_xx_0, '0'] +- [blocks_file_source_0, '0', blocks_char_to_float_0, '0'] +- [blocks_probe_rate_0, rate, blocks_message_debug_0, print] +- [dc_blocker_xx_0, '0', qtgui_freq_sink_x_0, '0'] +- [dc_blocker_xx_0, '0', qtgui_time_sink_x_0, '0'] +- [dc_blocker_xx_0, '0', qtgui_waterfall_sink_x_0, '0'] + +metadata: + file_format: 1 + grc_version: 3.10.11.0 diff --git a/grc/file.grc b/grc/file.grc new file mode 100644 index 0000000..45be5be --- /dev/null +++ b/grc/file.grc @@ -0,0 +1,594 @@ +options: + parameters: + author: '' + catch_exceptions: 'True' + category: '[GRC Hier Blocks]' + cmake_opt: '' + comment: '' + copyright: '' + description: '' + gen_cmake: 'On' + gen_linking: dynamic + generate_options: qt_gui + hier_block_src_path: '.:' + id: file + max_nouts: '0' + output_language: python + placement: (0,0) + qt_qss_theme: '' + realtime_scheduling: '' + run: 'True' + run_command: '{python} -u {filename}' + run_options: prompt + sizing_mode: fixed + thread_safe_setters: '' + title: Not titled yet + window_size: (1000,1000) + states: + bus_sink: false + bus_source: false + bus_structure: null + coordinate: [8, 16.0] + rotation: 0 + state: enabled + +blocks: +- name: data_rate + id: variable + parameters: + comment: '' + value: samp_rate / decimation + states: + bus_sink: false + bus_source: false + bus_structure: null + coordinate: [368, 16.0] + rotation: 0 + state: enabled +- name: decimation + id: variable + parameters: + comment: '' + value: '64' + states: + bus_sink: false + bus_source: false + bus_structure: null + coordinate: [272, 16.0] + rotation: 0 + state: enabled +- name: samp_rate + id: variable + parameters: + comment: '' + value: 132e6 / 256 + states: + bus_sink: false + bus_source: false + bus_structure: null + coordinate: [168, 16.0] + rotation: 0 + state: enabled +- name: blocks_char_to_float_0 + id: blocks_char_to_float + parameters: + affinity: '' + alias: '' + comment: '' + maxoutbuf: '0' + minoutbuf: '0' + scale: '128' + vlen: '1' + states: + bus_sink: false + bus_source: false + bus_structure: null + coordinate: [224, 280.0] + rotation: 0 + state: enabled +- name: blocks_complex_to_mag_0 + id: blocks_complex_to_mag + parameters: + affinity: '' + alias: '' + comment: '' + maxoutbuf: '0' + minoutbuf: '0' + vlen: '1' + states: + bus_sink: false + bus_source: false + bus_structure: null + coordinate: [960, 448.0] + rotation: 180 + state: enabled +- name: blocks_file_source_0 + id: blocks_file_source + parameters: + affinity: '' + alias: '' + begin_tag: pmt.PMT_NIL + comment: '' + file: /home/mordae/work/smart/pico-pdm/samples.fifo + length: '0' + maxoutbuf: '0' + minoutbuf: '0' + offset: '0' + repeat: 'True' + type: byte + vlen: '1' + states: + bus_sink: false + bus_source: false + bus_structure: null + coordinate: [8, 248.0] + rotation: 0 + state: enabled +- name: blocks_float_to_complex_0 + id: blocks_float_to_complex + parameters: + affinity: '' + alias: '' + comment: '' + maxoutbuf: '0' + minoutbuf: '0' + vlen: '1' + states: + bus_sink: false + bus_source: false + bus_structure: null + coordinate: [408, 288.0] + rotation: 0 + state: enabled +- name: blocks_freqshift_cc_0 + id: blocks_freqshift_cc + parameters: + affinity: '' + alias: '' + comment: '' + freq: -38e3 + maxoutbuf: '0' + minoutbuf: '0' + sample_rate: samp_rate + states: + bus_sink: false + bus_source: false + bus_structure: null + coordinate: [744, 288.0] + rotation: 0 + state: enabled +- name: blocks_message_debug_0 + id: blocks_message_debug + parameters: + affinity: '' + alias: '' + comment: '' + en_uvec: 'True' + log_level: info + states: + bus_sink: false + bus_source: false + bus_structure: null + coordinate: [856, 64.0] + rotation: 0 + state: enabled +- name: blocks_probe_rate_0 + id: blocks_probe_rate + parameters: + affinity: '' + alias: '' + alpha: '1' + comment: '' + maxoutbuf: '0' + minoutbuf: '0' + mintime: 1e3 + name: '' + type: complex + vlen: '1' + states: + bus_sink: false + bus_source: false + bus_structure: null + coordinate: [592, 72.0] + rotation: 0 + state: enabled +- name: dc_blocker_xx_0 + id: dc_blocker_xx + parameters: + affinity: '' + alias: '' + comment: '' + length: '32' + long_form: 'True' + maxoutbuf: '0' + minoutbuf: '0' + type: cc + states: + bus_sink: false + bus_source: false + bus_structure: null + coordinate: [592, 288.0] + rotation: 0 + state: enabled +- name: fir_filter_xxx_0 + id: fir_filter_xxx + parameters: + affinity: '' + alias: '' + comment: '' + decim: decimation + maxoutbuf: '0' + minoutbuf: '0' + samp_delay: '0' + taps: '[0.002855073321371961, 0.004217810045954073, 0.006070979752995526, 0.008513978883235714, + 0.011633445764465426, 0.015487673582478250, 0.020089356277603183, 0.025389133050128021, + 0.031263078326193357, 0.037507457211444148, 0.043843530949484712, 0.049933894562348549, + 0.055409900908815000, 0.059907517556544401, 0.063106964465950877, 0.064770205340986750, + 0.064770205340986750, 0.063106964465950877, 0.059907517556544401, 0.055409900908815000, + 0.049933894562348549, 0.043843530949484712, 0.037507457211444148, 0.031263078326193357, + 0.025389133050128021, 0.020089356277603183, 0.015487673582478250, 0.011633445764465426, + 0.008513978883235714, 0.006070979752995526, 0.004217810045954073, 0.002855073321371961] + + ' + type: ccf + states: + bus_sink: false + bus_source: false + bus_structure: null + coordinate: [936, 288.0] + rotation: 0 + state: enabled +- name: qtgui_freq_sink_x_0 + id: qtgui_freq_sink_x + parameters: + affinity: '' + alias: '' + alpha1: '1.0' + alpha10: '1.0' + alpha2: '1.0' + alpha3: '1.0' + alpha4: '1.0' + alpha5: '1.0' + alpha6: '1.0' + alpha7: '1.0' + alpha8: '1.0' + alpha9: '1.0' + autoscale: 'False' + average: '0.05' + axislabels: 'True' + bw: data_rate + color1: '"blue"' + color10: '"dark blue"' + color2: '"red"' + color3: '"green"' + color4: '"black"' + color5: '"cyan"' + color6: '"magenta"' + color7: '"yellow"' + color8: '"dark red"' + color9: '"dark green"' + comment: '' + ctrlpanel: 'False' + fc: '0' + fftsize: '1024' + freqhalf: 'False' + grid: 'True' + gui_hint: '' + label: Relative Gain + label1: '' + label10: '''''' + label2: '''''' + label3: '''''' + label4: '''''' + label5: '''''' + label6: '''''' + label7: '''''' + label8: '''''' + label9: '''''' + legend: 'True' + maxoutbuf: '0' + minoutbuf: '0' + name: '""' + nconnections: '1' + norm_window: 'True' + showports: 'False' + tr_chan: '0' + tr_level: '0.0' + tr_mode: qtgui.TRIG_MODE_FREE + tr_tag: '""' + type: complex + units: dB + update_time: 1/30 + width1: '1' + width10: '1' + width2: '1' + width3: '1' + width4: '1' + width5: '1' + width6: '1' + width7: '1' + width8: '1' + width9: '1' + wintype: window.WIN_BLACKMAN_hARRIS + ymax: '0' + ymin: '-100' + states: + bus_sink: false + bus_source: false + bus_structure: null + coordinate: [1176, 376.0] + rotation: 0 + state: enabled +- name: qtgui_time_sink_x_0 + id: qtgui_time_sink_x + parameters: + affinity: '' + alias: '' + alpha1: '1.0' + alpha10: '1.0' + alpha2: '1.0' + alpha3: '1.0' + alpha4: '1.0' + alpha5: '1.0' + alpha6: '1.0' + alpha7: '1.0' + alpha8: '1.0' + alpha9: '1.0' + autoscale: 'False' + axislabels: 'True' + color1: blue + color10: dark blue + color2: red + color3: green + color4: black + color5: cyan + color6: magenta + color7: yellow + color8: dark red + color9: dark green + comment: '' + ctrlpanel: 'False' + entags: 'False' + grid: 'False' + gui_hint: '' + label1: IR + label10: Signal 10 + label2: Signal 2 + label3: Signal 3 + label4: Signal 4 + label5: Signal 5 + label6: Signal 6 + label7: Signal 7 + label8: Signal 8 + label9: Signal 9 + legend: 'False' + marker1: '-1' + marker10: '-1' + marker2: '-1' + marker3: '-1' + marker4: '-1' + marker5: '-1' + marker6: '-1' + marker7: '-1' + marker8: '-1' + marker9: '-1' + name: '""' + nconnections: '1' + size: '512' + srate: data_rate + stemplot: 'True' + style1: '1' + style10: '1' + style2: '1' + style3: '1' + style4: '1' + style5: '1' + style6: '1' + style7: '1' + style8: '1' + style9: '1' + tr_chan: '0' + tr_delay: '0' + tr_level: '0.0' + tr_mode: qtgui.TRIG_MODE_FREE + tr_slope: qtgui.TRIG_SLOPE_POS + tr_tag: '""' + type: complex + update_time: 1/30 + width1: '1' + width10: '1' + width2: '1' + width3: '1' + width4: '1' + width5: '1' + width6: '1' + width7: '1' + width8: '1' + width9: '1' + ylabel: Amplitude + ymax: '1' + ymin: '-1' + yunit: '""' + states: + bus_sink: false + bus_source: false + bus_structure: null + coordinate: [1176, 280.0] + rotation: 0 + state: enabled +- name: qtgui_time_sink_x_0_0 + id: qtgui_time_sink_x + parameters: + affinity: '' + alias: '' + alpha1: '1.0' + alpha10: '1.0' + alpha2: '1.0' + alpha3: '1.0' + alpha4: '1.0' + alpha5: '1.0' + alpha6: '1.0' + alpha7: '1.0' + alpha8: '1.0' + alpha9: '1.0' + autoscale: 'False' + axislabels: 'True' + color1: blue + color10: dark blue + color2: red + color3: green + color4: black + color5: cyan + color6: magenta + color7: yellow + color8: dark red + color9: dark green + comment: '' + ctrlpanel: 'False' + entags: 'False' + grid: 'False' + gui_hint: '' + label1: IR + label10: Signal 10 + label2: Signal 2 + label3: Signal 3 + label4: Signal 4 + label5: Signal 5 + label6: Signal 6 + label7: Signal 7 + label8: Signal 8 + label9: Signal 9 + legend: 'False' + marker1: '-1' + marker10: '-1' + marker2: '-1' + marker3: '-1' + marker4: '-1' + marker5: '-1' + marker6: '-1' + marker7: '-1' + marker8: '-1' + marker9: '-1' + name: '""' + nconnections: '1' + size: '512' + srate: data_rate + stemplot: 'False' + style1: '1' + style10: '1' + style2: '1' + style3: '1' + style4: '1' + style5: '1' + style6: '1' + style7: '1' + style8: '1' + style9: '1' + tr_chan: '0' + tr_delay: '0' + tr_level: '0.0' + tr_mode: qtgui.TRIG_MODE_FREE + tr_slope: qtgui.TRIG_SLOPE_POS + tr_tag: '""' + type: float + update_time: 1/30 + width1: '1' + width10: '1' + width2: '1' + width3: '1' + width4: '1' + width5: '1' + width6: '1' + width7: '1' + width8: '1' + width9: '1' + ylabel: Magnitude + ymax: '1' + ymin: '-1' + yunit: '""' + states: + bus_sink: false + bus_source: false + bus_structure: null + coordinate: [744, 424.0] + rotation: 180 + state: enabled +- name: qtgui_waterfall_sink_x_0 + id: qtgui_waterfall_sink_x + parameters: + affinity: '' + alias: '' + alpha1: '1.0' + alpha10: '1.0' + alpha2: '1.0' + alpha3: '1.0' + alpha4: '1.0' + alpha5: '1.0' + alpha6: '1.0' + alpha7: '1.0' + alpha8: '1.0' + alpha9: '1.0' + axislabels: 'True' + bw: data_rate + color1: '0' + color10: '0' + color2: '0' + color3: '0' + color4: '0' + color5: '0' + color6: '0' + color7: '0' + color8: '0' + color9: '0' + comment: '' + fc: '0' + fftsize: '1024' + freqhalf: 'False' + grid: 'False' + gui_hint: '' + int_max: '0' + int_min: '-120' + label1: '' + label10: '' + label2: '' + label3: '' + label4: '' + label5: '' + label6: '' + label7: '' + label8: '' + label9: '' + legend: 'True' + maxoutbuf: '0' + minoutbuf: '0' + name: '""' + nconnections: '1' + showports: 'False' + type: complex + update_time: 1/30 + wintype: window.WIN_BLACKMAN_hARRIS + states: + bus_sink: false + bus_source: false + bus_structure: null + coordinate: [1176, 184.0] + rotation: 0 + state: enabled + +connections: +- [blocks_char_to_float_0, '0', blocks_float_to_complex_0, '0'] +- [blocks_complex_to_mag_0, '0', qtgui_time_sink_x_0_0, '0'] +- [blocks_file_source_0, '0', blocks_char_to_float_0, '0'] +- [blocks_float_to_complex_0, '0', blocks_probe_rate_0, '0'] +- [blocks_float_to_complex_0, '0', dc_blocker_xx_0, '0'] +- [blocks_freqshift_cc_0, '0', fir_filter_xxx_0, '0'] +- [blocks_probe_rate_0, rate, blocks_message_debug_0, print] +- [dc_blocker_xx_0, '0', blocks_freqshift_cc_0, '0'] +- [fir_filter_xxx_0, '0', blocks_complex_to_mag_0, '0'] +- [fir_filter_xxx_0, '0', qtgui_freq_sink_x_0, '0'] +- [fir_filter_xxx_0, '0', qtgui_time_sink_x_0, '0'] +- [fir_filter_xxx_0, '0', qtgui_waterfall_sink_x_0, '0'] + +metadata: + file_format: 1 + grc_version: 3.10.11.0 diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 43bf553..b537733 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -42,6 +42,7 @@ target_compile_options(pdmtest PRIVATE -Wall -Wextra -Wnull-dereference) target_compile_definitions(pdmtest PUBLIC PICO_MAX_SHARED_IRQ_HANDLERS=8u) target_compile_definitions(pdmtest PUBLIC PICO_STDIO_ENABLE_CRLF_SUPPORT=1) target_compile_definitions(pdmtest PUBLIC PICO_STDIO_DEFAULT_CRLF=1) +target_compile_definitions(pdmtest PUBLIC PICO_STDIO_AUX=1) target_include_directories(pdmtest PRIVATE include) diff --git a/src/main.c b/src/main.c index 02c673d..a6c8e84 100644 --- a/src/main.c +++ b/src/main.c @@ -1,13 +1,22 @@ #include #include +#include #include +#include +#include +#include #include +#define SMPS_PIN 23 + #define IR_BIAS_PIN 3 #define IR_RX_PIN 6 -#define IR_FB_PIN 7 +#define IR_FB_PIN 8 + +#define IR_PIO pio0 +#define IR_SM 0 #define HP_GND_PIN 13 #define HP_LEFT_PIN 14 @@ -22,6 +31,82 @@ #define HP_PWM_SCALE (SYS_CLK_HZ / HP_PWM_RATE) #define HP_PWM_MID (HP_PWM_SCALE / 2) +typedef struct Sample { + uint16_t x; + uint16_t y; +} Sample; + +#define NUM_SAMPLES_BITS 10 +#define NUM_SAMPLES (1 << NUM_SAMPLES_BITS) +static Sample sample_buffer[NUM_SAMPLES] __aligned(4 * NUM_SAMPLES); +static int dma_ch_sample; +static int dma_ch_rx; + +/* Jump to 0, side-set 1. */ +static uint16_t sampling_script[] = { 0b0001100000000000 }; + +static void init_pio_sm(void) +{ + const uint16_t insn[] = { + pio_encode_in(pio_y, 16), + pio_encode_in(pio_x, 16) | pio_encode_sideset_opt(1, 0), + pio_encode_jmp_pin(4), + pio_encode_jmp_x_dec(2) | pio_encode_sideset_opt(1, 1), + pio_encode_jmp_y_dec(2) | pio_encode_sideset_opt(1, 0), + }; + + pio_program_t prog = { + .instructions = insn, + .length = sizeof(insn) / sizeof(*insn), + .origin = 0, + }; + pio_add_program(IR_PIO, &prog); + + pio_sm_config pc = pio_get_default_sm_config(); + sm_config_set_clkdiv_int_frac8(&pc, 1, 0); + sm_config_set_jmp_pin(&pc, IR_RX_PIN); + sm_config_set_in_pins(&pc, IR_RX_PIN); + sm_config_set_out_pins(&pc, IR_FB_PIN, 1); + sm_config_set_set_pins(&pc, IR_FB_PIN, 1); + sm_config_set_sideset_pin_base(&pc, IR_FB_PIN); + sm_config_set_sideset(&pc, 2, true, false); + sm_config_set_in_shift(&pc, false, true, 32); + sm_config_set_fifo_join(&pc, PIO_FIFO_JOIN_RX); + + pio_sm_init(IR_PIO, IR_SM, prog.origin, &pc); + pio_sm_set_wrap(IR_PIO, IR_SM, prog.origin + 2, prog.origin + prog.length - 1); + + pio_sm_set_consecutive_pindirs(IR_PIO, IR_SM, IR_RX_PIN, 1, GPIO_IN); + pio_sm_set_consecutive_pindirs(IR_PIO, IR_SM, IR_FB_PIN, 1, GPIO_OUT); + + pio_sm_restart(IR_PIO, IR_SM); + pio_sm_clear_fifos(IR_PIO, IR_SM); +} + +static unsigned tail; + +static bool read_sample(int *sample) +{ + unsigned head = (dma_hw->ch[dma_ch_rx].write_addr >> 2) % NUM_SAMPLES; + + if (tail == head) + return false; + + static Sample prev; + Sample next = sample_buffer[tail]; + tail = (tail + 1) % NUM_SAMPLES; + + int s = (prev.y - next.y) - (prev.x - next.x); + prev = next; + + static int dc; + dc += ((s << 16) - dc) >> 10; + s -= dc >> 16; + + *sample = s; + return true; +} + int main() { stdio_usb_init(); @@ -35,6 +120,12 @@ int main() printf("\nWelcome to PDM Test!\n"); + gpio_init(SMPS_PIN); + gpio_disable_pulls(SMPS_PIN); + gpio_put(SMPS_PIN, 1); + gpio_set_dir(SMPS_PIN, GPIO_OUT); + +#if 0 gpio_disable_pulls(HP_GND_PIN); gpio_disable_pulls(HP_LEFT_PIN); gpio_disable_pulls(HP_RIGHT_PIN); @@ -85,4 +176,130 @@ int main() sleep_ms(500); } +#else + // gpio_init(IR_BIAS_PIN); + gpio_disable_pulls(IR_BIAS_PIN); + // gpio_set_drive_strength(IR_BIAS_PIN, GPIO_DRIVE_STRENGTH_2MA); + // gpio_put(IR_BIAS_PIN, 1); + // gpio_set_dir(IR_BIAS_PIN, GPIO_OUT); + + gpio_disable_pulls(IR_RX_PIN); + gpio_disable_pulls(IR_FB_PIN); + + pio_gpio_init(IR_PIO, IR_FB_PIN); + + gpio_set_input_hysteresis_enabled(IR_RX_PIN, false); + gpio_set_drive_strength(IR_FB_PIN, GPIO_DRIVE_STRENGTH_2MA); + gpio_set_slew_rate(IR_FB_PIN, GPIO_SLEW_RATE_FAST); + + init_pio_sm(); + + dma_ch_sample = dma_claim_unused_channel(true); + dma_ch_rx = dma_claim_unused_channel(true); + int timer = dma_claim_unused_timer(true); + + dma_channel_config dma_conf; + + /* Copy sampling script into the PIO. */ + dma_conf = dma_channel_get_default_config(dma_ch_sample); + channel_config_set_transfer_data_size(&dma_conf, DMA_SIZE_16); + channel_config_set_read_increment(&dma_conf, false); + channel_config_set_write_increment(&dma_conf, false); + channel_config_set_chain_to(&dma_conf, dma_ch_rx); + channel_config_set_dreq(&dma_conf, dma_get_timer_dreq(timer)); + dma_channel_configure(dma_ch_sample, &dma_conf, &IR_PIO->sm[IR_SM].instr, sampling_script, + 1, false); + + /* Read samples from PIO. */ + dma_conf = dma_channel_get_default_config(dma_ch_rx); + channel_config_set_transfer_data_size(&dma_conf, DMA_SIZE_32); + channel_config_set_read_increment(&dma_conf, false); + channel_config_set_write_increment(&dma_conf, true); + channel_config_set_ring(&dma_conf, true, NUM_SAMPLES_BITS + 2); + channel_config_set_chain_to(&dma_conf, dma_ch_sample); + channel_config_set_dreq(&dma_conf, pio_get_dreq(IR_PIO, IR_SM, false)); + dma_channel_configure(dma_ch_rx, &dma_conf, sample_buffer, &IR_PIO->rxf[IR_SM], 1, false); + + /* 8 × 38 kHz */ + // dma_timer_set_fraction(timer, 8 * 16, 55579); + dma_timer_set_fraction(timer, 1, 256); + dma_channel_start(dma_ch_rx); + pio_sm_set_enabled(IR_PIO, IR_SM, true); + + static int8_t batch[64]; + unsigned written = 0; + +#if 0 + static int sin_lut[16] = { 0, 98, 180, 236, 255, 236, 180, 98, + 0, -98, -180, -236, -255, -236, -180, -98 }; + static int cos_lut[16] = { 255, 236, 180, 98, 0, -98, -180, -236, + -255, -236, -180, -98, 0, 98, 180, 236 }; + + int I = 0, Q = 0; + int phase = 0; + + while (true) { + /* Get last byte written. */ + unsigned head = (dma_hw->ch[dma_ch_rx].write_addr - 8u) & ((4 * NUM_SAMPLES) - 1); + + /* Convert to index into 4-byte array. */ + head = (head >> 2); + + while (tail != head) { + int sample = read_sample(); + + I += (cos_lut[phase] * sample) >> 8; + Q += (sin_lut[phase] * sample) >> 8; + + if (++phase >= 16) { + I >>= 3; + Q >>= 3; + + batch[written++] = I; + batch[written++] = Q; + + I = Q = 0; + phase = 0; + } + + if (written >= sizeof(batch) / sizeof(*batch)) { + written = 0; + if (tud_cdc_n_write_available(1) >= sizeof(batch)) { + tud_cdc_n_write(1, batch, sizeof(batch)); + tud_cdc_n_write_flush(1); + written = 0; + } + } + } + + sleep_us(10); + } +#else + stdio_usb_lock(); + + while (true) { + int sample; + + while (read_sample(&sample)) { + batch[written++] = sample << 1; + + if (written >= sizeof(batch) / sizeof(*batch)) { + while (tud_cdc_n_write_available(1) < sizeof(batch)) { + tud_cdc_n_write_flush(1); + tud_task(); + sleep_us(10); + } + + tud_cdc_n_write(1, batch, sizeof(batch)); + written = 0; + } + } + + tud_task(); + sleep_us(10); + } + + stdio_usb_unlock(); +#endif +#endif }