From 69730487968116f6455a88d203536c10c2b22db8 Mon Sep 17 00:00:00 2001 From: Yann Locatelli Date: Mon, 4 Mar 2024 09:46:39 +0100 Subject: [PATCH] New code --- drivers/CoreDAC/CMakeLists.txt | 1 + drivers/CoreDAC/include/CoreDAC.h | 4 +- .../CoreDAC/include/CoreSTM32HalBasicTimer.h | 5 +- .../include/interface/STM32HalBasicTimer.h | 2 + drivers/CoreDAC/source/CoreDAC.cpp | 23 +- .../CoreDAC/source/CoreSTM32HalBasicTimer.cpp | 37 ++-- drivers/CoreDAC/source/HAL_IRQHandlers.cpp | 5 + drivers/CoreDAC/tests/CoreDAC_test.cpp | 30 ++- .../tests/CoreSTM32HalBasicTimer_test.cpp | 202 ++++++++++++++++++ drivers/CoreDAC/tests/mocks/STM32HalTimer.h | 2 + drivers/CoreSTM32Hal/include/CoreSTM32Hal.h | 2 + drivers/CoreSTM32Hal/source/CoreSTM32Hal.cpp | 10 + include/interface/drivers/STM32Hal.h | 3 + spikes/lk_dac/main.cpp | 21 +- tests/unit/mocks/mocks/leka/CoreSTM32Hal.h | 2 + 15 files changed, 294 insertions(+), 55 deletions(-) create mode 100644 drivers/CoreDAC/tests/CoreSTM32HalBasicTimer_test.cpp diff --git a/drivers/CoreDAC/CMakeLists.txt b/drivers/CoreDAC/CMakeLists.txt index 094c5a6393..357c1aa84f 100644 --- a/drivers/CoreDAC/CMakeLists.txt +++ b/drivers/CoreDAC/CMakeLists.txt @@ -29,6 +29,7 @@ target_link_libraries(CoreDAC if(${CMAKE_PROJECT_NAME} STREQUAL "LekaOSUnitTests") leka_unit_tests_sources( + tests/CoreSTM32HalBasicTimer_test.cpp tests/CoreDAC_test.cpp ) endif() diff --git a/drivers/CoreDAC/include/CoreDAC.h b/drivers/CoreDAC/include/CoreDAC.h index 2de4c665d8..a04818033f 100644 --- a/drivers/CoreDAC/include/CoreDAC.h +++ b/drivers/CoreDAC/include/CoreDAC.h @@ -42,8 +42,8 @@ class CoreDAC : public interface::DACBase DMA_HandleTypeDef _hdma {}; std::span _data; - std::function _on_half_transfer = [] {}; - std::function _on_complete_transfer = [] {}; + std::function _on_half_transfer {}; + std::function _on_complete_transfer {}; }; } // namespace leka diff --git a/drivers/CoreDAC/include/CoreSTM32HalBasicTimer.h b/drivers/CoreDAC/include/CoreSTM32HalBasicTimer.h index dc5baee7e2..3806d73c7f 100644 --- a/drivers/CoreDAC/include/CoreSTM32HalBasicTimer.h +++ b/drivers/CoreDAC/include/CoreSTM32HalBasicTimer.h @@ -18,8 +18,9 @@ class CoreSTM32HalBasicTimer : public interface::STM32HalBasicTimer [[nodiscard]] auto getHandle() -> TIM_HandleTypeDef & final; void registerCallback(std::function const &callback); + void linkDACTimer(DAC_ChannelConfTypeDef *config) final; - void initialize(uint32_t frequency) final; + void initialize(uint32_t frequency = 44'100) final; void terminate() final; void start() final; @@ -32,7 +33,7 @@ class CoreSTM32HalBasicTimer : public interface::STM32HalBasicTimer TIM_HandleTypeDef _htim {}; - std::function _callback = [] {}; + std::function _callback {}; }; } // namespace leka diff --git a/drivers/CoreDAC/include/interface/STM32HalBasicTimer.h b/drivers/CoreDAC/include/interface/STM32HalBasicTimer.h index e6013d15b0..b9338a42c1 100644 --- a/drivers/CoreDAC/include/interface/STM32HalBasicTimer.h +++ b/drivers/CoreDAC/include/interface/STM32HalBasicTimer.h @@ -15,6 +15,8 @@ class STM32HalBasicTimer [[nodiscard]] virtual auto getHandle() -> TIM_HandleTypeDef & = 0; + virtual void linkDACTimer(DAC_ChannelConfTypeDef *config) = 0; + virtual void initialize(uint32_t frequency) = 0; virtual void terminate() = 0; diff --git a/drivers/CoreDAC/source/CoreDAC.cpp b/drivers/CoreDAC/source/CoreDAC.cpp index 8f981d652b..c3a28f899e 100644 --- a/drivers/CoreDAC/source/CoreDAC.cpp +++ b/drivers/CoreDAC/source/CoreDAC.cpp @@ -23,15 +23,22 @@ void CoreDAC::initialize() _hal.HAL_DAC_Init(&_hdac); DAC_ChannelConfTypeDef config = {}; - config.DAC_OutputBuffer = DAC_OUTPUTBUFFER_ENABLE; // necessary to reach the full voltage range in DAC output - config.DAC_Trigger = DAC_TRIGGER_T6_TRGO; // configure the DAC to be triggered by TIM6 through TRGO signal + config.DAC_OutputBuffer = DAC_OUTPUTBUFFER_ENABLE; + _hal_timer.linkDACTimer(&config); _hal.HAL_DAC_ConfigChannel(&_hdac, &config, DAC_CHANNEL_1); - static auto &self = *this; + static const auto &self = *this; _hal.HAL_DAC_RegisterCallback(&_hdac, HAL_DAC_CH1_HALF_COMPLETE_CB_ID, - [](DAC_HandleTypeDef *hdac) { self._on_half_transfer(); }); - _hal.HAL_DAC_RegisterCallback(&_hdac, HAL_DAC_CH1_COMPLETE_CB_ID, - [](DAC_HandleTypeDef *hdac) { self._on_complete_transfer(); }); + []([[maybe_unused]] DAC_HandleTypeDef *hdac) { + if (self._on_half_transfer != nullptr) { + self._on_half_transfer(); + } + }); + _hal.HAL_DAC_RegisterCallback(&_hdac, HAL_DAC_CH1_COMPLETE_CB_ID, []([[maybe_unused]] DAC_HandleTypeDef *hdac) { + if (self._on_complete_transfer != nullptr) { + self._on_complete_transfer(); + } + }); } void CoreDAC::terminate() @@ -67,14 +74,14 @@ void CoreDAC::_registerMspCallbacks() { static auto &self = *this; - _hal.HAL_DAC_RegisterCallback(&_hdac, HAL_DAC_MSPINIT_CB_ID, [](DAC_HandleTypeDef *hdac) { + _hal.HAL_DAC_RegisterCallback(&_hdac, HAL_DAC_MSPINIT_CB_ID, []([[maybe_unused]] DAC_HandleTypeDef *hdac) { __HAL_LINKDMA(&self._hdac, DMA_Handle1, self._hdma); self._initializeDMA(); self._hal.HAL_RCC_DAC_CLK_ENABLE(); }); - _hal.HAL_DAC_RegisterCallback(&_hdac, HAL_DAC_MSPDEINIT_CB_ID, [](DAC_HandleTypeDef *hdac) { + _hal.HAL_DAC_RegisterCallback(&_hdac, HAL_DAC_MSPDEINIT_CB_ID, []([[maybe_unused]] DAC_HandleTypeDef *hdac) { self._hal.HAL_DMA_DeInit(&self._hdma); self._hal.HAL_RCC_DAC_CLK_DISABLE(); diff --git a/drivers/CoreDAC/source/CoreSTM32HalBasicTimer.cpp b/drivers/CoreDAC/source/CoreSTM32HalBasicTimer.cpp index 388bd48986..96f4c9d49e 100644 --- a/drivers/CoreDAC/source/CoreSTM32HalBasicTimer.cpp +++ b/drivers/CoreDAC/source/CoreSTM32HalBasicTimer.cpp @@ -28,37 +28,44 @@ void CoreSTM32HalBasicTimer::initialize(uint32_t frequency) // CK_Timer = CK_Int / ((Prescaler + 1) * (Period + 1)) auto divider = 54'000'000 / frequency; - _htim.Init.Prescaler = 2; - _htim.Init.Period = 100; // ? min 1 - _htim.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_DISABLE; // Disable shadow write - // _htim.Init.CounterMode; // NOT AVAILABLE for BasicTimer - // _htim.Init.ClockDivision; // NOT AVAILABLE for BasicTimer - // _htim.Init.RepetitionCounter; // NOT AVAILABLE for BasicTimer + _htim.Init.Prescaler = divider / 100; + _htim.Init.Period = 100; // ? min 1 + _htim.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_DISABLE; _hal.HAL_TIM_Base_Init(&_htim); auto timerMasterConfig = TIM_MasterConfigTypeDef {}; - timerMasterConfig.MasterOutputTrigger = TIM_TRGO_UPDATE; // Use hardware trigger - // timerMasterConfig.MasterSlaveMode; // NOT AVAILABLE for BasicTimer + timerMasterConfig.MasterOutputTrigger = TIM_TRGO_UPDATE; _hal.HAL_TIMEx_MasterConfigSynchronization(&_htim, &timerMasterConfig); - static auto &self = *this; - _hal.HAL_TIM_RegisterCallback(&_htim, HAL_TIM_PERIOD_ELAPSED_CB_ID, - [](TIM_HandleTypeDef *htim) { self._callback(); }); + static const auto &self = *this; + _hal.HAL_TIM_RegisterCallback(&_htim, HAL_TIM_PERIOD_ELAPSED_CB_ID, []([[maybe_unused]] TIM_HandleTypeDef *htim) { + if (self._callback != nullptr) { + self._callback(); + } + }); } void CoreSTM32HalBasicTimer::_registerMspCallbacks() { - static auto &self = *this; + static const auto &self = *this; - _hal.HAL_TIM_RegisterCallback(&_htim, HAL_TIM_BASE_MSPINIT_CB_ID, [](TIM_HandleTypeDef *htim) { + _hal.HAL_TIM_RegisterCallback(&_htim, HAL_TIM_BASE_MSPINIT_CB_ID, []([[maybe_unused]] TIM_HandleTypeDef *htim) { self._hal.HAL_RCC_TIM6_CLK_ENABLE(); self._hal.HAL_NVIC_SetPriority(TIM6_DAC_IRQn, 0x00, 0x00); self._hal.HAL_NVIC_EnableIRQ(TIM6_DAC_IRQn); }); - _hal.HAL_TIM_RegisterCallback(&_htim, HAL_TIM_BASE_MSPDEINIT_CB_ID, - [](TIM_HandleTypeDef *htim) { self._hal.HAL_RCC_TIM6_CLK_DISABLE(); }); + _hal.HAL_TIM_RegisterCallback(&_htim, HAL_TIM_BASE_MSPDEINIT_CB_ID, []([[maybe_unused]] TIM_HandleTypeDef *htim) { + self._hal.HAL_RCC_TIM6_CLK_DISABLE(); + }); +} + +void CoreSTM32HalBasicTimer::linkDACTimer(DAC_ChannelConfTypeDef *config) +{ + if (config != nullptr) { + config->DAC_Trigger = DAC_TRIGGER_T6_TRGO; + } } void CoreSTM32HalBasicTimer::terminate() diff --git a/drivers/CoreDAC/source/HAL_IRQHandlers.cpp b/drivers/CoreDAC/source/HAL_IRQHandlers.cpp index cac30f391a..31ae2946df 100644 --- a/drivers/CoreDAC/source/HAL_IRQHandlers.cpp +++ b/drivers/CoreDAC/source/HAL_IRQHandlers.cpp @@ -11,6 +11,11 @@ void TIM6_DAC_IRQHandler() HAL_TIM_IRQHandler(&hal_timer.getHandle()); } +void TIM7_DAC_IRQHandler() +{ + HAL_TIM_IRQHandler(&hal_timer.getHandle()); +} + void DMA1_Stream5_IRQHandler() { HAL_DMA_IRQHandler(coredac.getHandle().DMA_Handle1); diff --git a/drivers/CoreDAC/tests/CoreDAC_test.cpp b/drivers/CoreDAC/tests/CoreDAC_test.cpp index 04b22fad78..f832d99391 100644 --- a/drivers/CoreDAC/tests/CoreDAC_test.cpp +++ b/drivers/CoreDAC/tests/CoreDAC_test.cpp @@ -14,7 +14,6 @@ using namespace leka; using testing::_; using ::testing::DoAll; using ::testing::InSequence; -using ::testing::Matcher; using ::testing::MockFunction; using ::testing::Return; using ::testing::SaveArg; @@ -38,6 +37,7 @@ class CoreDACTest : public ::testing::Test .WillOnce(DoAll(SaveArg<2>(&dma_complete_transfer_callback), Return(HAL_StatusTypeDef::HAL_OK))); EXPECT_CALL(halmock, HAL_DAC_Init); + EXPECT_CALL(haltimermock, linkDACTimer); EXPECT_CALL(halmock, HAL_DAC_ConfigChannel) .WillOnce(DoAll(SaveArgPointee<1>(&dac_config), Return(HAL_StatusTypeDef::HAL_OK))); @@ -74,8 +74,6 @@ TEST_F(CoreDACTest, initializationDefault) TEST_F(CoreDACTest, initialize) { - dac.registerDMACallbacks(on_half_transfer_callback.AsStdFunction(), on_complete_transfer_callback.AsStdFunction()); - { InSequence seq; @@ -86,6 +84,7 @@ TEST_F(CoreDACTest, initialize) { EXPECT_CALL(halmock, HAL_DAC_Init); + EXPECT_CALL(haltimermock, linkDACTimer); EXPECT_CALL(halmock, HAL_DAC_ConfigChannel); } // DAC config @@ -107,7 +106,14 @@ TEST_F(CoreDACTest, initializeMspInit) EXPECT_CALL(halmock, HAL_RCC_DAC_CLK_ENABLE); - mspinit_callback(nullptr); + mspinit_callback(&dac.getHandle()); +} + +TEST_F(CoreDACTest, initializeMspDeinit) +{ + EXPECT_CALL(halmock, HAL_DMA_DeInit); + EXPECT_CALL(halmock, HAL_RCC_DAC_CLK_DISABLE); + mspdeinit_callback(&dac.getHandle()); } TEST_F(CoreDACTest, initializeMspInitDMAConfig) @@ -122,7 +128,7 @@ TEST_F(CoreDACTest, initializeMspInitDMAConfig) EXPECT_CALL(halmock, HAL_RCC_DAC_CLK_ENABLE); - mspinit_callback(nullptr); + mspinit_callback(&dac.getHandle()); EXPECT_NE(&dma_handle, nullptr); EXPECT_EQ(dma_handle.Instance, DMA1_Stream5); @@ -131,32 +137,22 @@ TEST_F(CoreDACTest, initializeMspInitDMAConfig) EXPECT_EQ(dma_handle.Init.Direction, DMA_MEMORY_TO_PERIPH); } -TEST_F(CoreDACTest, initializeMspDeinit) -{ - EXPECT_CALL(halmock, HAL_DMA_DeInit); - EXPECT_CALL(halmock, HAL_RCC_DAC_CLK_DISABLE); - mspdeinit_callback(nullptr); -} - TEST_F(CoreDACTest, initializeConfig) { // necessary to reach the full voltage range in DAC output EXPECT_EQ(dac_config.DAC_OutputBuffer, DAC_OUTPUTBUFFER_ENABLE); - - // configure the DAC to be triggered by TIM6 through TRGO signal - EXPECT_EQ(dac_config.DAC_Trigger, DAC_TRIGGER_T6_TRGO); } TEST_F(CoreDACTest, initializeDmaHalfTransferCallback) { EXPECT_CALL(on_half_transfer_callback, Call); - dma_half_transfer_callback(nullptr); + dma_half_transfer_callback(&dac.getHandle()); } TEST_F(CoreDACTest, initializeDmaCompleteTransferCallback) { EXPECT_CALL(on_complete_transfer_callback, Call); - dma_complete_transfer_callback(nullptr); + dma_complete_transfer_callback(&dac.getHandle()); } TEST_F(CoreDACTest, terminate) diff --git a/drivers/CoreDAC/tests/CoreSTM32HalBasicTimer_test.cpp b/drivers/CoreDAC/tests/CoreSTM32HalBasicTimer_test.cpp new file mode 100644 index 0000000000..500a21010e --- /dev/null +++ b/drivers/CoreDAC/tests/CoreSTM32HalBasicTimer_test.cpp @@ -0,0 +1,202 @@ +// Leka - LekaOS +// Copyright 2024 APF France handicap +// SPDX-License-Identifier: Apache-2.0 + +#include "CoreSTM32HalBasicTimer.h" + +#include "gmock/gmock.h" +#include "gtest/gtest.h" +#include "mocks/STM32HalTimer.h" +#include "mocks/leka/CoreSTM32Hal.h" + +using namespace leka; + +using testing::_; +using ::testing::DoAll; +using ::testing::InSequence; +using ::testing::Matcher; +using ::testing::MockFunction; +using ::testing::Return; +using ::testing::SaveArg; +using ::testing::SaveArgPointee; + +class CoreSTM32HalBasicTimerTest : public ::testing::Test +{ + protected: + void SetUp() override + { + basic_timer.registerCallback(callback.AsStdFunction()); + + EXPECT_CALL(halmock, HAL_TIM_RegisterCallback(_, HAL_TIM_BASE_MSPINIT_CB_ID, _)) + .WillOnce(DoAll(SaveArg<2>(&mspinit_callback), Return(HAL_StatusTypeDef::HAL_OK))); + EXPECT_CALL(halmock, HAL_TIM_RegisterCallback(_, HAL_TIM_BASE_MSPDEINIT_CB_ID, _)) + .WillOnce(DoAll(SaveArg<2>(&mspdeinit_callback), Return(HAL_StatusTypeDef::HAL_OK))); + EXPECT_CALL(halmock, HAL_TIM_RegisterCallback(_, HAL_TIM_PERIOD_ELAPSED_CB_ID, _)) + .WillOnce(DoAll(SaveArg<2>(&period_elapsed_callback), Return(HAL_StatusTypeDef::HAL_OK))); + + EXPECT_CALL(halmock, HAL_TIM_Base_Init); + EXPECT_CALL(halmock, HAL_TIMEx_MasterConfigSynchronization) + .WillOnce(DoAll(SaveArgPointee<1>(&basic_timer_master_config), Return(HAL_StatusTypeDef::HAL_OK))); + + basic_timer.initialize(); + } + // void TearDown() override {} + + mock::CoreSTM32Hal halmock; + + CoreSTM32HalBasicTimer basic_timer {halmock}; + TIM_MasterConfigTypeDef basic_timer_master_config {}; + + MockFunction callback; + + std::function mspinit_callback = [](TIM_HandleTypeDef *) {}; + std::function mspdeinit_callback = [](TIM_HandleTypeDef *) {}; + std::function period_elapsed_callback = [](TIM_HandleTypeDef *) {}; +}; + +TEST_F(CoreSTM32HalBasicTimerTest, initializationDefault) +{ + auto new_basic_timer = CoreSTM32HalBasicTimer {halmock}; + EXPECT_NE(&new_basic_timer, nullptr); + + auto handle = new_basic_timer.getHandle(); + EXPECT_NE(&handle, nullptr); + auto allowed_instance = handle.Instance == TIM6 || handle.Instance == TIM7; + EXPECT_TRUE(allowed_instance); +} + +TEST_F(CoreSTM32HalBasicTimerTest, initialize) +{ + { + InSequence seq; + + { + EXPECT_CALL(halmock, HAL_TIM_RegisterCallback(_, HAL_TIM_BASE_MSPINIT_CB_ID, _)); + EXPECT_CALL(halmock, HAL_TIM_RegisterCallback(_, HAL_TIM_BASE_MSPDEINIT_CB_ID, _)); + } // MSP callbacks + + { + EXPECT_CALL(halmock, HAL_TIM_Base_Init); + EXPECT_CALL(halmock, HAL_TIMEx_MasterConfigSynchronization); + } // BasicTimer config + + { + EXPECT_CALL(halmock, HAL_TIM_RegisterCallback(_, HAL_TIM_PERIOD_ELAPSED_CB_ID, _)); + } // Callback on event + } + + basic_timer.initialize(); +} + +TEST_F(CoreSTM32HalBasicTimerTest, initializeMspInit) +{ + auto *basic_timer_instance = basic_timer.getHandle().Instance; + + if (basic_timer_instance == TIM6) { + EXPECT_CALL(halmock, HAL_RCC_TIM6_CLK_ENABLE); + EXPECT_CALL(halmock, HAL_NVIC_SetPriority(TIM6_DAC_IRQn, _, _)); + EXPECT_CALL(halmock, HAL_NVIC_EnableIRQ(TIM6_DAC_IRQn)); + } else if (basic_timer_instance == TIM7) { + EXPECT_CALL(halmock, HAL_RCC_TIM7_CLK_ENABLE); + EXPECT_CALL(halmock, HAL_NVIC_SetPriority(TIM7_IRQn, _, _)); + EXPECT_CALL(halmock, HAL_NVIC_EnableIRQ(TIM7_IRQn)); + } else { + FAIL(); // Only timers 6 and 7 can be used as Basic Timer + } + + mspinit_callback(&basic_timer.getHandle()); +} + +TEST_F(CoreSTM32HalBasicTimerTest, initializeMspDeinit) +{ + auto *basic_timer_instance = basic_timer.getHandle().Instance; + + if (basic_timer_instance == TIM6) { + EXPECT_CALL(halmock, HAL_RCC_TIM6_CLK_DISABLE); + } else if (basic_timer_instance == TIM7) { + EXPECT_CALL(halmock, HAL_RCC_TIM7_CLK_DISABLE); + } else { + FAIL(); // Only timers 6 and 7 can be used as Basic Timer + } + + mspdeinit_callback(&basic_timer.getHandle()); +} + +TEST_F(CoreSTM32HalBasicTimerTest, initializeConfig) +{ + auto timer_handle = basic_timer.getHandle(); + + auto CK_INT = 54'000'000; + auto default_sample_rate = 44'100; + auto divider = CK_INT / default_sample_rate; + + // The prescaler can divide the counter clock frequency by any factor between 1 and 65536, see 28.3.1 of RM + auto prescaler = timer_handle.Init.Prescaler; + EXPECT_LE(prescaler, 0xFFF); + + // The counter counts from 0 to the auto-reload value, see 28.3.2 of RM + auto auto_reload_value = timer_handle.Init.Period; + EXPECT_GE(auto_reload_value, 1); + EXPECT_LE(auto_reload_value, 0xFFF); + + // To fit required frequency (default sample rate), multiplying prescaler and auto-reload value must give + // approximately the divider + EXPECT_NEAR(prescaler * auto_reload_value, divider, 50); + + // Disable shadow write + EXPECT_EQ(timer_handle.Init.AutoReloadPreload, TIM_AUTORELOAD_PRELOAD_DISABLE); + + // The update event is selected as a trigger output, see 28.4.2 of RM + EXPECT_EQ(basic_timer_master_config.MasterOutputTrigger, TIM_TRGO_UPDATE); + + // ? Config not available for BasicTimer (TIM6 and TIM7) + // _htim.Init.CounterMode; + // _htim.Init.ClockDivision; + // _htim.Init.RepetitionCounter; + // timerMasterConfig.MasterSlaveMode; +} + +TEST_F(CoreSTM32HalBasicTimerTest, initializePeriodElapsedCallback) +{ + EXPECT_CALL(callback, Call); + period_elapsed_callback(&basic_timer.getHandle()); +} + +TEST_F(CoreSTM32HalBasicTimerTest, linkDACTimer) +{ + basic_timer.linkDACTimer(nullptr); + + DAC_ChannelConfTypeDef dac_config {}; + + basic_timer.linkDACTimer(&dac_config); + + auto *basic_timer_instance = basic_timer.getHandle().Instance; + if (basic_timer_instance == TIM6) { + EXPECT_EQ(dac_config.DAC_Trigger, DAC_TRIGGER_T6_TRGO); + } else if (basic_timer_instance == TIM7) { + EXPECT_EQ(dac_config.DAC_Trigger, DAC_TRIGGER_T7_TRGO); + } else { + FAIL(); // Only timers 6 and 7 can be used as DAC Timer + } +} + +TEST_F(CoreSTM32HalBasicTimerTest, terminate) +{ + EXPECT_CALL(halmock, HAL_TIM_Base_DeInit); + + basic_timer.terminate(); +} + +TEST_F(CoreSTM32HalBasicTimerTest, start) +{ + EXPECT_CALL(halmock, HAL_TIM_Base_Start_IT); + + basic_timer.start(); +} + +TEST_F(CoreSTM32HalBasicTimerTest, stop) +{ + EXPECT_CALL(halmock, HAL_TIM_Base_Stop_IT); + + basic_timer.stop(); +} diff --git a/drivers/CoreDAC/tests/mocks/STM32HalTimer.h b/drivers/CoreDAC/tests/mocks/STM32HalTimer.h index ea81e67b53..8ff5b5c47c 100644 --- a/drivers/CoreDAC/tests/mocks/STM32HalTimer.h +++ b/drivers/CoreDAC/tests/mocks/STM32HalTimer.h @@ -14,6 +14,8 @@ class STM32HalTimer : public interface::STM32HalBasicTimer public: MOCK_METHOD(TIM_HandleTypeDef &, getHandle, (), (override)); + MOCK_METHOD(void, linkDACTimer, (DAC_ChannelConfTypeDef *), (override)); + MOCK_METHOD(void, initialize, (uint32_t), (override)); MOCK_METHOD(void, terminate, (), (override)); diff --git a/drivers/CoreSTM32Hal/include/CoreSTM32Hal.h b/drivers/CoreSTM32Hal/include/CoreSTM32Hal.h index fd5c1736a2..2453a066f8 100644 --- a/drivers/CoreSTM32Hal/include/CoreSTM32Hal.h +++ b/drivers/CoreSTM32Hal/include/CoreSTM32Hal.h @@ -24,6 +24,8 @@ class CoreSTM32Hal : public interface::STM32Hal void HAL_RCC_TIM6_CLK_ENABLE() final; void HAL_RCC_TIM6_CLK_DISABLE() final; + void HAL_RCC_TIM7_CLK_ENABLE() final; + void HAL_RCC_TIM7_CLK_DISABLE() final; void HAL_RCC_FMC_CLK_ENABLE() final; diff --git a/drivers/CoreSTM32Hal/source/CoreSTM32Hal.cpp b/drivers/CoreSTM32Hal/source/CoreSTM32Hal.cpp index c549a7d659..2beb724e2a 100644 --- a/drivers/CoreSTM32Hal/source/CoreSTM32Hal.cpp +++ b/drivers/CoreSTM32Hal/source/CoreSTM32Hal.cpp @@ -51,6 +51,16 @@ void CoreSTM32Hal::HAL_RCC_TIM6_CLK_DISABLE() __HAL_RCC_TIM6_CLK_DISABLE(); // NOLINT } +void CoreSTM32Hal::HAL_RCC_TIM7_CLK_ENABLE() +{ + __HAL_RCC_TIM7_CLK_ENABLE(); // NOLINT +} + +void CoreSTM32Hal::HAL_RCC_TIM7_CLK_DISABLE() +{ + __HAL_RCC_TIM7_CLK_DISABLE(); // NOLINT +} + void CoreSTM32Hal::HAL_RCC_FMC_CLK_ENABLE() { __HAL_RCC_FMC_CLK_ENABLE(); // NOLINT diff --git a/include/interface/drivers/STM32Hal.h b/include/interface/drivers/STM32Hal.h index 3a4c8f35a4..4b5f56ad86 100644 --- a/include/interface/drivers/STM32Hal.h +++ b/include/interface/drivers/STM32Hal.h @@ -24,6 +24,9 @@ class STM32Hal virtual void HAL_RCC_TIM6_CLK_ENABLE() = 0; virtual void HAL_RCC_TIM6_CLK_DISABLE() = 0; + virtual void HAL_RCC_TIM7_CLK_ENABLE() = 0; + virtual void HAL_RCC_TIM7_CLK_DISABLE() = 0; + virtual void HAL_RCC_FMC_CLK_ENABLE() = 0; virtual void HAL_RCC_DMA1_CLK_ENABLE() = 0; diff --git a/spikes/lk_dac/main.cpp b/spikes/lk_dac/main.cpp index 833210f9cb..37221646f8 100644 --- a/spikes/lk_dac/main.cpp +++ b/spikes/lk_dac/main.cpp @@ -21,13 +21,11 @@ auto coredac = CoreDAC {hal, hal_timer}; auto audio_enable = mbed::DigitalOut {SOUND_ENABLE, 1}; -constexpr uint32_t _samplingRate_hertz = 44'100; +constexpr uint32_t sample_rate_hz = 44'100; -void fillBufferWithSinWave(uint16_t *buffer, uint32_t bufferSize, uint32_t sinFreq, uint32_t samplingRate, - uint16_t maxValue, uint16_t minValue) +void fillBufferWithSinWave(uint16_t *buffer, uint32_t samples_per_period, uint16_t maxValue, uint16_t minValue) { - auto samples_per_period = bufferSize; - auto resolution = 2.0 * M_PI / samples_per_period; + auto resolution = 2.0 * M_PI / samples_per_period; auto sin0_1 = [](double value) { return (sin(value) + 1.0) / 2.0; }; auto normalization = [maxValue, minValue](double standard_value) { @@ -50,14 +48,15 @@ auto main() -> int hal_timer.initialize(500); coredac.initialize(); - std::array outBuff {}; - const uint32_t sinFreq = 440; - const uint16_t maxVal = 0x100; - const uint16_t minVal = 0x000; - fillBufferWithSinWave(outBuff.data(), outBuff.size(), sinFreq, _samplingRate_hertz, maxVal, minVal); + const uint32_t frequency = 440; + const uint16_t maxVal = 0x100; + const uint16_t minVal = 0x000; + std::array buffer {}; + fillBufferWithSinWave(buffer.data(), buffer.size(), maxVal, minVal); - coredac.registerDataToPlay(outBuff); + coredac.registerDataToPlay(buffer); + log_info("buffer size: %d", buffer.size()); log_info("Start sound"); coredac.start(); diff --git a/tests/unit/mocks/mocks/leka/CoreSTM32Hal.h b/tests/unit/mocks/mocks/leka/CoreSTM32Hal.h index d3e39ec421..5751098106 100644 --- a/tests/unit/mocks/mocks/leka/CoreSTM32Hal.h +++ b/tests/unit/mocks/mocks/leka/CoreSTM32Hal.h @@ -21,6 +21,8 @@ class CoreSTM32Hal : public interface::STM32Hal MOCK_METHOD(void, HAL_RCC_GPIOJ_CLK_ENABLE, (), (override)); MOCK_METHOD(void, HAL_RCC_TIM6_CLK_ENABLE, (), (override)); MOCK_METHOD(void, HAL_RCC_TIM6_CLK_DISABLE, (), (override)); + MOCK_METHOD(void, HAL_RCC_TIM7_CLK_ENABLE, (), (override)); + MOCK_METHOD(void, HAL_RCC_TIM7_CLK_DISABLE, (), (override)); MOCK_METHOD(void, HAL_RCC_FMC_CLK_ENABLE, (), (override)); MOCK_METHOD(void, HAL_RCC_DMA1_CLK_ENABLE, (), (override)); MOCK_METHOD(void, HAL_RCC_DMA2_CLK_ENABLE, (), (override));