Skip to content

Commit 86bd8f0

Browse files
committed
Code refactor
1 parent 627adcc commit 86bd8f0

File tree

11 files changed

+91
-77
lines changed

11 files changed

+91
-77
lines changed

.cproject

+2-2
Original file line numberDiff line numberDiff line change
@@ -188,8 +188,8 @@
188188
<option id="ilg.gnuarmeclipse.managedbuild.cross.option.arm.target.architecture.1028387022" name="Architecture" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.arm.target.architecture" useByScannerDiscovery="false" value="ilg.gnuarmeclipse.managedbuild.cross.option.arm.target.arch.armv7e-m" valueType="enumerated"/>
189189
<option id="ilg.gnuarmeclipse.managedbuild.cross.option.toolchain.id.1780260696" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.toolchain.id" useByScannerDiscovery="false" value="962691777" valueType="string"/>
190190
<option id="ilg.gnuarmeclipse.managedbuild.cross.option.warnings.allwarn.1233743181" name="Enable all common warnings (-Wall)" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.warnings.allwarn" useByScannerDiscovery="true" value="true" valueType="boolean"/>
191-
<option id="ilg.gnuarmeclipse.managedbuild.cross.option.optimization.lto.1183045901" name="Link-time optimizer (-flto)" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.optimization.lto" value="false" valueType="boolean"/>
192-
<option id="ilg.gnuarmeclipse.managedbuild.cross.option.optimization.spconstant.417076202" name="Single precision constants (-fsingle-precision-constant)" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.optimization.spconstant" value="true" valueType="boolean"/>
191+
<option id="ilg.gnuarmeclipse.managedbuild.cross.option.optimization.lto.1183045901" name="Link-time optimizer (-flto)" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.optimization.lto" useByScannerDiscovery="true" value="false" valueType="boolean"/>
192+
<option id="ilg.gnuarmeclipse.managedbuild.cross.option.optimization.spconstant.417076202" name="Single precision constants (-fsingle-precision-constant)" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.optimization.spconstant" useByScannerDiscovery="true" value="true" valueType="boolean"/>
193193
<targetPlatform archList="all" binaryParser="org.eclipse.cdt.core.ELF" id="ilg.gnuarmeclipse.managedbuild.cross.targetPlatform.1269353534" isAbstract="false" osList="all" superClass="ilg.gnuarmeclipse.managedbuild.cross.targetPlatform"/>
194194
<builder buildPath="${workspace_loc:/spl-meter}/Debug" id="ilg.gnuarmeclipse.managedbuild.cross.builder.97973665" keepEnvironmentInBuildfile="false" managedBuildOn="true" name="Gnu Make Builder" parallelBuildOn="true" parallelizationNumber="optimal" superClass="ilg.gnuarmeclipse.managedbuild.cross.builder"/>
195195
<tool id="ilg.gnuarmeclipse.managedbuild.cross.tool.assembler.206879582" name="GNU ARM Cross Assembler" superClass="ilg.gnuarmeclipse.managedbuild.cross.tool.assembler">

.settings/.gitignore

+1
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
/language.settings.xml

app/model/meter.cpp

+41-45
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ using namespace spl;
1616
//---------------------------------------------------------------------------
1717
/* private */
1818

19-
/* warning: This function is called from ISR */
19+
/* WARNING: This function is called from ISR */
2020
void meter::mic_data_ready(const int16_t *data, uint16_t data_len)
2121
{
2222
if (this->dsp_buffer_ready)
@@ -53,19 +53,19 @@ meter::meter(hal::microphone &microphone, const new_data_cb_t &new_data_cb) : mi
5353
this->new_spl_data_cb = new_data_cb;
5454
this->spl_data.spl_min = 120;
5555
this->spl_data.spl_max = 0;
56+
this->spl_data.spl = 0;
5657
this->spl_data_period = static_cast<float32_t>(this->dsp_buffer.size()) / this->mic.get_sampling_frequency();
5758

5859
this->spl_data.weighting = weighting_t::a;
59-
this->weighting_filter = new a_weighting();
60+
this->weighting_filter = std::make_unique<spl::a_weighting>();
6061

6162
this->spl_data.averaging = averaging_t::slow;
62-
this->averaging_filter = new slow_averaging(this->spl_data_period, this->spl_data.spl);
63+
this->averaging_filter = std::make_unique<spl::slow_averaging>(this->spl_data_period, this->spl_data.spl);
6364
}
6465

6566
meter::~meter()
6667
{
67-
delete this->weighting_filter;
68-
delete this->averaging_filter;
68+
6969
}
7070

7171
void meter::enable(void)
@@ -77,47 +77,47 @@ void meter::enable(void)
7777
void meter::process(void)
7878
{
7979
/* DSP processing takes around 2.68 msec at 48MHz */
80-
if (this->dsp_buffer_ready)
81-
{
82-
auto &current_dsp_buffer = this->dsp_buffer;
80+
if (!this->dsp_buffer_ready)
81+
return;
8382

84-
/* Apply weighting filter */
85-
this->weighting_filter->process(current_dsp_buffer, this->aux_dsp_buffer);
86-
this->dsp_buffer_ready = false;
83+
auto &current_dsp_buffer = this->dsp_buffer;
8784

88-
current_dsp_buffer = this->aux_dsp_buffer;
85+
/* Apply weighting filter */
86+
this->weighting_filter->process(current_dsp_buffer, this->aux_dsp_buffer);
87+
this->dsp_buffer_ready = false;
8988

90-
/* Delete offset */
91-
float32_t mean;
92-
arm_mean_f32(current_dsp_buffer.data(), current_dsp_buffer.size(), &mean);
93-
arm_offset_f32(current_dsp_buffer.data(), -mean, current_dsp_buffer.data(), current_dsp_buffer.size());
89+
current_dsp_buffer = this->aux_dsp_buffer;
9490

95-
/* Calculate RMS value */
96-
float32_t rms;
97-
arm_rms_f32(current_dsp_buffer.data(), current_dsp_buffer.size(), &rms);
91+
/* Delete offset */
92+
float32_t mean;
93+
arm_mean_f32(current_dsp_buffer.data(), current_dsp_buffer.size(), &mean);
94+
arm_offset_f32(current_dsp_buffer.data(), -mean, current_dsp_buffer.data(), current_dsp_buffer.size());
9895

99-
/* Normalize RMS value */
100-
rms /= INT16_MAX;
96+
/* Calculate RMS value */
97+
float32_t rms;
98+
arm_rms_f32(current_dsp_buffer.data(), current_dsp_buffer.size(), &rms);
10199

102-
/* Calculate dB SPL */
103-
float32_t db_spl_raw = 94 - this->mic.get_sensitivity() + 20.0f * log10f(rms);
100+
/* Normalize RMS value */
101+
rms /= INT16_MAX;
104102

105-
/* Apply averaging */
106-
float32_t db_spl = this->averaging_filter->process(db_spl_raw);
103+
/* Calculate dB SPL */
104+
float32_t db_spl_raw = 94 - this->mic.get_sensitivity() + 20.0f * log10f(rms);
107105

108-
const uint32_t averaging_period = this->averaging_filter->time_constant * 1000;
106+
/* Apply averaging */
107+
float32_t db_spl = this->averaging_filter->process(db_spl_raw);
109108

110-
if (hal::system::clock::is_elapsed(this->averaging_time_point, std::chrono::milliseconds(averaging_period)))
111-
{
112-
this->averaging_time_point = hal::system::clock::now();
109+
const uint32_t averaging_period = this->averaging_filter->time_constant * 1000;
113110

114-
this->spl_data.spl_max = std::max(db_spl, this->spl_data.spl_max);
115-
this->spl_data.spl_min = std::min(db_spl, this->spl_data.spl_min);
116-
this->spl_data.spl = db_spl;
111+
if (hal::system::clock::is_elapsed(this->averaging_time_point, std::chrono::milliseconds(averaging_period)))
112+
{
113+
this->averaging_time_point = hal::system::clock::now();
114+
115+
this->spl_data.spl_max = std::max(db_spl, this->spl_data.spl_max);
116+
this->spl_data.spl_min = std::min(db_spl, this->spl_data.spl_min);
117+
this->spl_data.spl = db_spl;
117118

118-
if (this->new_spl_data_cb != nullptr)
119-
this->new_spl_data_cb(this->spl_data);
120-
}
119+
if (this->new_spl_data_cb != nullptr)
120+
this->new_spl_data_cb(this->spl_data);
121121
}
122122
}
123123

@@ -146,16 +146,13 @@ void meter::set_weighting(weighting_t weighting)
146146
switch (weighting)
147147
{
148148
case weighting_t::a:
149-
delete this->weighting_filter;
150-
this->weighting_filter = new a_weighting();
149+
this->weighting_filter = std::make_unique<spl::a_weighting>();
151150
break;
152151
case weighting_t::c:
153-
delete this->weighting_filter;
154-
this->weighting_filter = new c_weighting();
152+
this->weighting_filter = std::make_unique<spl::c_weighting>();
155153
break;
156154
case weighting_t::z:
157-
delete this->weighting_filter;
158-
this->weighting_filter = new z_weighting();
155+
this->weighting_filter = std::make_unique<spl::z_weighting>();
159156
break;
160157
default:
161158
return;
@@ -172,12 +169,11 @@ void meter::set_averaging(averaging_t averaging)
172169
switch (averaging)
173170
{
174171
case averaging_t::fast:
175-
delete this->averaging_filter;
176-
this->averaging_filter = new fast_averaging(this->spl_data_period, this->spl_data.spl);
172+
this->averaging_filter = std::make_unique<spl::fast_averaging>(this->spl_data_period, this->spl_data.spl);
173+
177174
break;
178175
case averaging_t::slow:
179-
delete this->averaging_filter;
180-
this->averaging_filter = new slow_averaging(this->spl_data_period, this->spl_data.spl);
176+
this->averaging_filter = std::make_unique<spl::slow_averaging>(this->spl_data_period, this->spl_data.spl);
181177
break;
182178
default:
183179
return;

app/model/meter.hpp

+3-2
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010

1111
#include <vector>
1212
#include <functional>
13+
#include <memory>
1314

1415
#include <hal/hal_system.hpp>
1516
#include <hal/hal_microphone.hpp>
@@ -49,8 +50,8 @@ class meter
4950
std::vector<int16_t> mic_data_buffer;
5051
void mic_data_ready(const int16_t *data, uint16_t data_len);
5152

52-
spl::weighting_filter *weighting_filter;
53-
spl::averaging_filter *averaging_filter;
53+
std::unique_ptr<spl::weighting_filter> weighting_filter;
54+
std::unique_ptr<spl::averaging_filter> averaging_filter;
5455
hal::system::clock::time_point averaging_time_point;
5556

5657
std::vector<float32_t> dsp_buffer;

app/view/console_view.cpp

+1-1
Original file line numberDiff line numberDiff line change
@@ -118,7 +118,7 @@ void console_view::process(void)
118118
{
119119
/* Statistics (clear MIN/MAX) */
120120
clear_max_spl_data_evt_t e1;
121-
clear_max_spl_data_evt_t e2;
121+
clear_min_spl_data_evt_t e2;
122122
this->send_event_cb(e1);
123123
this->send_event_cb(e2);
124124
break;

drivers/stm32l4/usart.cpp

+8-10
Original file line numberDiff line numberDiff line change
@@ -18,8 +18,6 @@
1818

1919
using namespace drivers;
2020

21-
std::array<usart*, 3> usart::active_objects;
22-
2321
struct usart::usart_hw
2422
{
2523
usart::id id;
@@ -33,9 +31,8 @@ struct usart::usart_hw
3331

3432
static const std::map<usart::id, usart::usart_hw> usartx =
3533
{
36-
{usart::id::usart2,
37-
{usart::id::usart2, USART2, { rcc::bus::APB1, RCC_APB1ENR1_USART2EN }, gpio::af::af7,
38-
{ gpio::port::portd, gpio::pin::pin5 }, { gpio::port::portd, gpio::pin::pin6 }}},
34+
{ usart::id::usart2, { usart::id::usart2, USART2, { rcc::bus::APB1, RCC_APB1ENR1_USART2EN }, gpio::af::af7,
35+
{ gpio::port::portd, gpio::pin::pin5 }, { gpio::port::portd, gpio::pin::pin6 }}},
3936
};
4037

4138
usart::usart(id id, uint32_t baudrate) :
@@ -49,17 +46,17 @@ usart::usart(id id, uint32_t baudrate) :
4946
gpio::configure(this->hw.rx_pin, gpio::mode::af, this->hw.pin_af);
5047

5148
uint8_t object_id = static_cast<uint8_t>(id);
52-
if (object_id < this->active_objects.size())
53-
this->active_objects[object_id] = this;
49+
if (object_id < this->instance.size())
50+
this->instance[object_id] = this;
5451

55-
this->hw.reg->BRR = (uint32_t) (hal::system::system_clock + baudrate / 2) / baudrate;
52+
this->hw.reg->BRR = (uint32_t) (rcc::get_bus_freq(this->hw.pbus.bus) + baudrate / 2) / baudrate;
5653
this->hw.reg->CR1 = USART_CR1_TE | USART_CR1_RE | USART_CR1_UE;
5754
}
5855

5956
usart::~usart()
6057
{
6158
uint8_t object_id = static_cast<uint8_t>(this->hw.id);
62-
this->active_objects[object_id] = nullptr;
59+
this->instance[object_id] = nullptr;
6360
}
6461

6562
std::byte usart::read()
@@ -108,6 +105,7 @@ void usart::read_async(std::byte *data, std::size_t size, const read_cb_t &callb
108105
this->hw.reg->CR1 &= ~USART_CR1_RXNEIE;
109106

110107
IRQn_Type nvic_irq = static_cast<IRQn_Type>(USART1_IRQn + static_cast<uint8_t>(this->hw.id)); /* TODO: Only supported 1, 2 & 3 */
108+
NVIC_ClearPendingIRQ(nvic_irq);
111109
NVIC_DisableIRQ(nvic_irq);
112110

113111
return;
@@ -123,7 +121,7 @@ void usart::read_async(std::byte *data, std::size_t size, const read_cb_t &callb
123121

124122
IRQn_Type nvic_irq = static_cast<IRQn_Type>(USART1_IRQn + static_cast<uint8_t>(this->hw.id)); /* TODO: Only supported 1, 2 & 3 */
125123
NVIC_SetPriority(nvic_irq, NVIC_EncodePriority( NVIC_GetPriorityGrouping(), 15, 0 ));
126-
// NVIC_ClearPendingIRQ(nvic_irq);
124+
NVIC_ClearPendingIRQ(nvic_irq);
127125
NVIC_EnableIRQ(nvic_irq);
128126
}
129127

drivers/stm32l4/usart.hpp

+1-1
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@ class usart : public hal::interface::serial
3737

3838
void irq_handler(void);
3939

40-
static std::array<usart*, 3> active_objects; /* For IRQ handling, must correspond to the enum class usart::id */
40+
static inline std::array<usart*, 3> instance; /* Used for global access (e.g. from interrupt) */
4141
struct usart_hw;
4242
private:
4343
const usart_hw &hw;

hal/hal_button.cpp

+29-13
Original file line numberDiff line numberDiff line change
@@ -17,15 +17,30 @@ using namespace hal;
1717

1818
button::button(hal::interface::button *interface) : interface {interface}
1919
{
20-
this->pressed = false;
20+
this->released = this->pressed = false;
2121
this->debounce_state = 0;
2222
}
2323

2424
void button::debounce(void)
2525
{
26-
/* This works like FIFO of button states, shifts actual button state to MSB */
27-
this->debounce_state = (this->debounce_state << 1) | this->interface->is_pressed() | 0xFFFFFE00;
28-
if (this->debounce_state == 0xFFFFFF00)
26+
// This works like FIFO of button states, shifts actual button state bit from LSB to MSB
27+
// _ ____
28+
// MSB < __| |____| |_______ < LSB
29+
// ^ ^
30+
// | |
31+
// pressed --+ +-- released
32+
33+
constexpr uint32_t ignore_mask = 0xFFFFFFE0;
34+
/* Release debounce time: 3 <bits> * <loop period> */
35+
constexpr uint32_t release_mask = 0xFFFFFFF8;
36+
/* Press debounce time: 2 <bit> * <loop period> */
37+
constexpr uint32_t press_mask = 0xFFFFFFE3;
38+
39+
this->debounce_state = (this->debounce_state << 1) | this->interface->is_pressed() | ignore_mask;
40+
41+
if (this->debounce_state == release_mask)
42+
this->released = true;
43+
else if (this->debounce_state == press_mask)
2944
this->pressed = true;
3045
}
3146

@@ -34,16 +49,17 @@ bool button::is_pressed(void)
3449
return this->interface->is_pressed();
3550
}
3651

52+
bool button::was_released(void)
53+
{
54+
bool state = this->released;
55+
this->released = false;
56+
return state;
57+
}
58+
3759
bool button::was_pressed(void)
3860
{
39-
if (this->pressed)
40-
{
41-
this->pressed = false;
42-
return true;
43-
}
44-
else
45-
{
46-
return false;
47-
}
61+
bool state = this->pressed;
62+
this->pressed = false;
63+
return state;
4864
}
4965

hal/hal_button.hpp

+2-1
Original file line numberDiff line numberDiff line change
@@ -25,10 +25,11 @@ namespace hal
2525
virtual void debounce(void);
2626
bool is_pressed(void);
2727
bool was_pressed(void);
28+
bool was_released(void);
2829
protected:
2930
hal::interface::button *interface;
3031
private:
31-
bool pressed;
32+
bool pressed, released;
3233
uint32_t debounce_state;
3334
};
3435

main.cpp

+2
Original file line numberDiff line numberDiff line change
@@ -45,5 +45,7 @@ int main(void)
4545
led_blink_start = hal::system::clock::now();
4646
led.set(led_state ^= true);
4747
}
48+
49+
__WFI();
4850
}
4951
}

system/interrupt_handlers.cpp

+1-2
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,6 @@ extern "C" void DMA1_Channel4_IRQHandler(void)
2525

2626
extern "C" void USART2_IRQHandler(void)
2727
{
28-
constexpr uint8_t id = static_cast<uint8_t>(drivers::usart::id::usart2);
29-
drivers::usart::active_objects[id]->irq_handler();
28+
drivers::usart::instance[static_cast<uint8_t>(drivers::usart::id::usart2)]->irq_handler();
3029
}
3130

0 commit comments

Comments
 (0)