diff --git a/README.md b/README.md index 911f941..dd5e711 100644 --- a/README.md +++ b/README.md @@ -9,7 +9,7 @@ Sound pressure meter running on STM32L476-DISCOVERY board - A, C and Z frequency weighting according to IEC 61672-1:2013 - Fast and Slow time weightings according to IEC 61672-1:2013 - Frequency range: 20Hz - 20kHz -- SPL range: 37 - 120dB +- SPL range: 33 - 120dB - MAX/MIN display ## Overview diff --git a/app/model/meter.cpp b/app/model/meter.cpp index a844f11..d636e38 100644 --- a/app/model/meter.cpp +++ b/app/model/meter.cpp @@ -88,17 +88,17 @@ void meter::process(void) current_dsp_buffer = this->aux_dsp_buffer; - /* Delete offset */ - float32_t mean; - arm_mean_f32(current_dsp_buffer.data(), current_dsp_buffer.size(), &mean); - arm_offset_f32(current_dsp_buffer.data(), -mean, current_dsp_buffer.data(), current_dsp_buffer.size()); - /* Calculate RMS value */ float32_t rms; arm_rms_f32(current_dsp_buffer.data(), current_dsp_buffer.size(), &rms); + /* Delete offset */ + float32_t mean; + arm_mean_f32(current_dsp_buffer.data(), current_dsp_buffer.size(), &mean); + rms -= mean; + /* Normalize RMS value */ - rms /= INT16_MAX; + rms /= -INT16_MIN; /* Calculate dB SPL */ float32_t db_spl_raw = 94 - this->mic.get_sensitivity() + 20.0f * log10f(rms); diff --git a/app/model/weighting_filter.hpp b/app/model/weighting_filter.hpp index 9c9f0a5..751636c 100644 --- a/app/model/weighting_filter.hpp +++ b/app/model/weighting_filter.hpp @@ -35,11 +35,11 @@ class a_weighting : public weighting_filter private: arm_biquad_cascade_df2T_instance_f32 iir_filter; static constexpr uint32_t iir_stages = 3; - static constexpr float32_t coeffs[5 * iir_stages] = + static constexpr float32_t coeffs[5 * iir_stages] = // Fs: 46875 Hz { - 0.28147504346, -0.56291022628, 0.28143518563, 0.04318103380, -0.00046615042, - 1.00000000000, -2.00014161345, 1.00014162348, 1.99353908705, -0.99354952290, - 1.00000000000, 2.00000000000, 1.00000000000, 1.87367745134, -0.87551448640 + 0.240209840, -0.480385663, 0.240175825, 0.201110797, -0.010111388, + 1.000000000, -2.000141613, 1.000141623, 1.891429991, -0.892780174, + 1.000000000, 2.000000000, 1.000000000, 1.994485381, -0.994492984 }; float32_t iir_state[2 * iir_stages]; }; @@ -52,10 +52,10 @@ class c_weighting : public weighting_filter private: arm_biquad_cascade_df2T_instance_f32 iir_filter; static constexpr uint32_t iir_stages = 2; - static constexpr float32_t coeffs[5 * iir_stages] = + static constexpr float32_t coeffs[5 * iir_stages] = // Fs: 46875 Hz { - 0.24025487669, 0.48050975338, 0.24025487669, 0.04318103380, -0.00046615042, - 1.00000000000, -2.00000000000, 1.00000000000, 1.99353908697, -0.99354952282 + 0.203135364, 0.406270729, 0.203135364, 0.201110797, -0.010111388, + 1.000000000, -2.000000000, 1.000000000, 1.994485381, -0.994492984 }; float32_t iir_state[2 * iir_stages]; }; diff --git a/drivers/mic_mp34dt01.cpp b/drivers/mic_mp34dt01.cpp index 08e8cbe..df8c94c 100644 --- a/drivers/mic_mp34dt01.cpp +++ b/drivers/mic_mp34dt01.cpp @@ -22,7 +22,7 @@ mic_mp34dt01::mic_mp34dt01(dfsdm::channel::id ch, dfsdm::filter::id f) : channel void mic_mp34dt01::init(std::vector &data_buffer, const hal::interface::microphone::data_ready_cb_t &data_ready_cb) { - /* Digital microphone on channel 2, fclk=2.4MHz, fs=40kHz, 16bit */ + /* Digital microphone on channel 2, fclk=3MHz, fs=46.875kHz, 16bit */ dfsdm::enable(true); dfsdm::channel::enable(this->channel, false); @@ -36,21 +36,21 @@ void mic_mp34dt01::init(std::vector &data_buffer, const hal::interface: dfsdm::channel::clk_src::int_ckout, dfsdm::channel::protocol::spi_r_edge); - const uint16_t filter_decim = 60; + const uint16_t filter_decim = 64; const uint8_t integrator_avg = 1; dfsdm::filter::configure(this->filter, dfsdm::filter::order::sinc4, filter_decim, integrator_avg); dfsdm::filter::link_channel(this->filter, this->channel); dfsdm::filter::enable_dma(this->filter, data_buffer.data(), data_buffer.size() , data_ready_cb); - uint32_t clk = dfsdm::configure_clock_output(dfsdm::clk_out_src::apb2, 2400000, true); + uint32_t clk = dfsdm::configure_clock_output(dfsdm::clk_out_src::apb2, clock, true); this->sampling_frequency = clk / (filter_decim * integrator_avg); } void mic_mp34dt01::enable(void) { - dfsdm::configure_clock_output(dfsdm::clk_out_src::apb2, 2400000, true); + dfsdm::configure_clock_output(dfsdm::clk_out_src::apb2, clock, true); dfsdm::channel::enable(this->channel, true); dfsdm::filter::enable(this->filter, true); @@ -62,7 +62,7 @@ void mic_mp34dt01::disable(void) dfsdm::channel::enable(this->channel, false); dfsdm::filter::enable(this->filter, false); - dfsdm::configure_clock_output(dfsdm::clk_out_src::apb2, 2400000, false); + dfsdm::configure_clock_output(dfsdm::clk_out_src::apb2, clock, false); } diff --git a/drivers/mic_mp34dt01.hpp b/drivers/mic_mp34dt01.hpp index 89c492a..04843ca 100644 --- a/drivers/mic_mp34dt01.hpp +++ b/drivers/mic_mp34dt01.hpp @@ -30,6 +30,7 @@ namespace drivers static constexpr uint32_t aop = 120; /* 120dB SPL */ static constexpr uint32_t snr = 61; /* 61dB */ static constexpr int32_t sensitivity = -26; /* -26dbFS */ + static constexpr uint32_t clock = 3000000; /* 3MHz */ const drivers::dfsdm::channel::id channel; drivers::dfsdm::filter::id filter; diff --git a/drivers/stm32l4/dfsdm.cpp b/drivers/stm32l4/dfsdm.cpp index 2d5d264..50f06f9 100644 --- a/drivers/stm32l4/dfsdm.cpp +++ b/drivers/stm32l4/dfsdm.cpp @@ -161,18 +161,18 @@ void dfsdm::channel::configure(id ch, data_pack dp, data_input di, clk_src clk, channel->CHCFGR1 |= static_cast(proto) << DFSDM_CHCFGR1_SITP_Pos; } -void dfsdm::channel::set_offset(id ch, uint32_t offset) +void dfsdm::channel::set_offset(id ch, int32_t offset) { auto channel = get_channel_reg(ch); channel->CHCFGR2 &= DFSDM_CHCFGR2_OFFSET_Msk; - channel->CHCFGR2 |= (offset & DFSDM_CHCFGR2_OFFSET_Msk) << DFSDM_CHCFGR2_OFFSET_Pos; + channel->CHCFGR2 |= static_cast(offset) << DFSDM_CHCFGR2_OFFSET_Pos; } void dfsdm::channel::set_bitshift(id ch, uint8_t right_shift) { auto channel = get_channel_reg(ch); channel->CHCFGR2 &= DFSDM_CHCFGR2_DTRBS_Msk; - channel->CHCFGR2 |= (right_shift & DFSDM_CHCFGR2_DTRBS_Msk) << DFSDM_CHCFGR2_DTRBS_Pos; + channel->CHCFGR2 |= ((right_shift) << DFSDM_CHCFGR2_DTRBS_Pos) & DFSDM_CHCFGR2_DTRBS_Msk; } void dfsdm::channel::enable(id ch, bool state) diff --git a/drivers/stm32l4/dfsdm.hpp b/drivers/stm32l4/dfsdm.hpp index 358b9b5..1c56299 100644 --- a/drivers/stm32l4/dfsdm.hpp +++ b/drivers/stm32l4/dfsdm.hpp @@ -62,7 +62,7 @@ class dfsdm final static void enable(id ch, bool state); static void configure(id ch, data_pack dp, data_input di, clk_src clk, protocol proto); - static void set_offset(id ch, uint32_t offset); + static void set_offset(id ch, int32_t offset); static void set_bitshift(id ch, uint8_t right_shift); } channel; diff --git a/scripts/weighting_filter.m b/scripts/weighting_filter.m index a394492..df5e1dd 100644 --- a/scripts/weighting_filter.m +++ b/scripts/weighting_filter.m @@ -4,7 +4,7 @@ clear all close all -Fs = 40000; +Fs = 46875; T = 1/Fs; % Definition of analog A-weighting filter according to IEC/CD 1672.