Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

✨ (dac): Add CoreSTM32HalBasicTimer #1415

Open
wants to merge 1 commit into
base: develop
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions config/mbed_app.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,10 @@
"USE_HAL_JPEG_REGISTER_CALLBACKS": {
"macro_name": "USE_HAL_JPEG_REGISTER_CALLBACKS",
"value": "1U"
},
"USE_HAL_TIM_REGISTER_CALLBACKS": {
"macro_name": "USE_HAL_TIM_REGISTER_CALLBACKS",
"value": "1U"
}
},
"target_overrides": {
Expand Down
1 change: 1 addition & 0 deletions drivers/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
add_subdirectory(${DRIVERS_DIR}/CoreBufferedSerial)
add_subdirectory(${DRIVERS_DIR}/CoreEventFlags)
add_subdirectory(${DRIVERS_DIR}/CoreEventQueue)
add_subdirectory(${DRIVERS_DIR}/CoreDAC)
add_subdirectory(${DRIVERS_DIR}/CoreI2C)
add_subdirectory(${DRIVERS_DIR}/CoreInterruptIn)
add_subdirectory(${DRIVERS_DIR}/CoreLL)
Expand Down
27 changes: 27 additions & 0 deletions drivers/CoreDAC/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
# Leka - LekaOS
# Copyright 2024 APF France handicap
# SPDX-License-Identifier: Apache-2.0

add_library(CoreDAC STATIC)

target_include_directories(CoreDAC
PUBLIC
include
)

target_sources(CoreDAC
PRIVATE
source/CoreSTM32HalBasicTimer.cpp
)

if(NOT(${CMAKE_PROJECT_NAME} STREQUAL "LekaOSUnitTests"))
target_sources(CoreDAC
PUBLIC
source/HAL_IRQHandlers.cpp
)
endif()

target_link_libraries(CoreDAC
mbed-os
CoreSTM32Hal
)
41 changes: 41 additions & 0 deletions drivers/CoreDAC/include/CoreSTM32HalBasicTimer.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
// Leka - LekaOS
// Copyright 2024 APF France handicap
// SPDX-License-Identifier: Apache-2.0

#pragma once

#include <functional>

#include "interface/drivers/STM32HalBasicTimer.h"

namespace leka {

class CoreSTM32HalBasicTimer : public interface::STM32HalBasicTimer
{
static constexpr float DEFAULT_AUDIO_FILE_SAMPLE_RATE = 44'100;

public:
CoreSTM32HalBasicTimer(interface::STM32Hal &hal);

[[nodiscard]] auto getHandle() -> TIM_HandleTypeDef & final;

void registerCallback(std::function<void()> const &callback);
void linkDACTimer(DAC_ChannelConfTypeDef *config) final;

void initialize(float frequency = DEFAULT_AUDIO_FILE_SAMPLE_RATE) final;
void terminate() final;

void start() final;
void stop() final;

private:
void _registerMspCallbacks();

interface::STM32Hal &_hal;

TIM_HandleTypeDef _htim {};

std::function<void()> _callback {};
};

} // namespace leka
86 changes: 86 additions & 0 deletions drivers/CoreDAC/source/CoreSTM32HalBasicTimer.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
// Leka - LekaOS
// Copyright 2024 APF France handicap
// SPDX-License-Identifier: Apache-2.0

#include "CoreSTM32HalBasicTimer.h"
#include <cmath>

using namespace leka;

CoreSTM32HalBasicTimer::CoreSTM32HalBasicTimer(interface::STM32Hal &hal) : _hal(hal)
{
_htim.Instance = TIM6;
}

auto CoreSTM32HalBasicTimer::getHandle() -> TIM_HandleTypeDef &
{
return _htim;
}

void CoreSTM32HalBasicTimer::registerCallback(std::function<void()> const &callback)
{
_callback = callback;
}

void CoreSTM32HalBasicTimer::initialize(float frequency)
{
_registerMspCallbacks();

// CK_Timer = CK_INT / ((Prescaler + 1) * (Period + 1))
const auto CK_INT = float {108'000'000.0};
auto divider = static_cast<int>(std::round(CK_INT / frequency));

_htim.Init.Prescaler = 0;
_htim.Init.Period = divider - 1; // ? min 1
_htim.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_DISABLE;
_hal.HAL_TIM_Base_Init(&_htim);

auto timerMasterConfig = TIM_MasterConfigTypeDef {};
timerMasterConfig.MasterOutputTrigger = TIM_TRGO_UPDATE;
_hal.HAL_TIMEx_MasterConfigSynchronization(&_htim, &timerMasterConfig);

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 const auto &self = *this;

_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, []([[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()
{
_hal.HAL_TIM_Base_DeInit(&_htim);
}

void CoreSTM32HalBasicTimer::start()
{
_hal.HAL_TIM_Base_Start_IT(&_htim);
}

void CoreSTM32HalBasicTimer::stop()
{
_hal.HAL_TIM_Base_Stop_IT(&_htim);
}
19 changes: 19 additions & 0 deletions drivers/CoreDAC/source/HAL_IRQHandlers.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
#include "CoreSTM32HalBasicTimer.h"

extern "C" {

namespace audio::internal {
extern leka::CoreSTM32HalBasicTimer hal_timer;
}

void TIM6_DAC_IRQHandler()
{
HAL_TIM_IRQHandler(&audio::internal::hal_timer.getHandle());
}

void TIM7_DAC_IRQHandler()
{
HAL_TIM_IRQHandler(&audio::internal::hal_timer.getHandle());
}

} // extern "C"
14 changes: 14 additions & 0 deletions drivers/CoreSTM32Hal/include/CoreSTM32Hal.h
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,11 @@ class CoreSTM32Hal : public interface::STM32Hal
void HAL_RCC_GPIOI_CLK_ENABLE() final;
void HAL_RCC_GPIOJ_CLK_ENABLE() final;

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;

void HAL_RCC_DMA2_CLK_ENABLE() final;
Expand Down Expand Up @@ -104,6 +109,15 @@ class CoreSTM32Hal : public interface::STM32Hal

auto HAL_JPEG_Pause(JPEG_HandleTypeDef *hjpeg, uint32_t XferSelection) -> HAL_StatusTypeDef final;
auto HAL_JPEG_Resume(JPEG_HandleTypeDef *hjpeg, uint32_t XferSelection) -> HAL_StatusTypeDef final;

auto HAL_TIM_Base_Init(TIM_HandleTypeDef *htim) -> HAL_StatusTypeDef final;
auto HAL_TIMEx_MasterConfigSynchronization(TIM_HandleTypeDef *htim, TIM_MasterConfigTypeDef *sMasterConfig)
-> HAL_StatusTypeDef final;
auto HAL_TIM_RegisterCallback(TIM_HandleTypeDef *htim, HAL_TIM_CallbackIDTypeDef CallbackID,
pTIM_CallbackTypeDef pCallback) -> HAL_StatusTypeDef final;
auto HAL_TIM_Base_Start_IT(TIM_HandleTypeDef *htim) -> HAL_StatusTypeDef final;
auto HAL_TIM_Base_Stop_IT(TIM_HandleTypeDef *htim) -> HAL_StatusTypeDef final;
auto HAL_TIM_Base_DeInit(TIM_HandleTypeDef *htim) -> HAL_StatusTypeDef final;
};

} // namespace leka
52 changes: 52 additions & 0 deletions drivers/CoreSTM32Hal/source/CoreSTM32Hal.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,26 @@ void CoreSTM32Hal::HAL_RCC_GPIOJ_CLK_ENABLE()
__HAL_RCC_GPIOJ_CLK_ENABLE(); // NOLINT
}

void CoreSTM32Hal::HAL_RCC_TIM6_CLK_ENABLE()
{
__HAL_RCC_TIM6_CLK_ENABLE(); // NOLINT
}

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
Expand Down Expand Up @@ -311,4 +331,36 @@ auto CoreSTM32Hal::HAL_JPEG_Resume(JPEG_HandleTypeDef *hjpeg, uint32_t XferSelec
return ::HAL_JPEG_Resume(hjpeg, XferSelection);
}

auto CoreSTM32Hal::HAL_TIM_Base_Init(TIM_HandleTypeDef *htim) -> HAL_StatusTypeDef
{
return ::HAL_TIM_Base_Init(htim);
}

auto CoreSTM32Hal::HAL_TIMEx_MasterConfigSynchronization(TIM_HandleTypeDef *htim,
TIM_MasterConfigTypeDef *sMasterConfig) -> HAL_StatusTypeDef
{
return ::HAL_TIMEx_MasterConfigSynchronization(htim, sMasterConfig);
}

auto CoreSTM32Hal::HAL_TIM_RegisterCallback(TIM_HandleTypeDef *htim, HAL_TIM_CallbackIDTypeDef CallbackID,
pTIM_CallbackTypeDef pCallback) -> HAL_StatusTypeDef
{
return ::HAL_TIM_RegisterCallback(htim, CallbackID, pCallback);
}

auto CoreSTM32Hal::HAL_TIM_Base_Start_IT(TIM_HandleTypeDef *htim) -> HAL_StatusTypeDef
{
return ::HAL_TIM_Base_Start_IT(htim);
}

auto CoreSTM32Hal::HAL_TIM_Base_Stop_IT(TIM_HandleTypeDef *htim) -> HAL_StatusTypeDef
{
return ::HAL_TIM_Base_Stop_IT(htim);
}

auto CoreSTM32Hal::HAL_TIM_Base_DeInit(TIM_HandleTypeDef *htim) -> HAL_StatusTypeDef
{
return ::HAL_TIM_Base_DeInit(htim);
}

} // namespace leka
15 changes: 15 additions & 0 deletions include/interface/drivers/STM32Hal.h
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,12 @@ class STM32Hal
virtual void HAL_RCC_GPIOI_CLK_ENABLE() = 0;
virtual void HAL_RCC_GPIOJ_CLK_ENABLE() = 0;

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_DMA2_CLK_ENABLE() = 0;
Expand Down Expand Up @@ -106,6 +112,15 @@ class STM32Hal

virtual auto HAL_JPEG_Pause(JPEG_HandleTypeDef *hjpeg, uint32_t XferSelection) -> HAL_StatusTypeDef = 0;
virtual auto HAL_JPEG_Resume(JPEG_HandleTypeDef *hjpeg, uint32_t XferSelection) -> HAL_StatusTypeDef = 0;

virtual auto HAL_TIM_Base_Init(TIM_HandleTypeDef *htim) -> HAL_StatusTypeDef = 0;
virtual auto HAL_TIMEx_MasterConfigSynchronization(TIM_HandleTypeDef *htim, TIM_MasterConfigTypeDef *sMasterConfig)
-> HAL_StatusTypeDef = 0;
virtual auto HAL_TIM_RegisterCallback(TIM_HandleTypeDef *htim, HAL_TIM_CallbackIDTypeDef CallbackID,
pTIM_CallbackTypeDef pCallback) -> HAL_StatusTypeDef = 0;
virtual auto HAL_TIM_Base_Start_IT(TIM_HandleTypeDef *htim) -> HAL_StatusTypeDef = 0;
virtual auto HAL_TIM_Base_Stop_IT(TIM_HandleTypeDef *htim) -> HAL_StatusTypeDef = 0;
virtual auto HAL_TIM_Base_DeInit(TIM_HandleTypeDef *htim) -> HAL_StatusTypeDef = 0;
};

} // namespace leka::interface
27 changes: 27 additions & 0 deletions include/interface/drivers/STM32HalBasicTimer.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
// Leka - LekaOS
// Copyright 2024 APF France handicap
// SPDX-License-Identifier: Apache-2.0

#pragma once

#include "interface/drivers/STM32Hal.h"

namespace leka::interface {

class STM32HalBasicTimer
{
public:
virtual ~STM32HalBasicTimer() = default;

[[nodiscard]] virtual auto getHandle() -> TIM_HandleTypeDef & = 0;

virtual void linkDACTimer(DAC_ChannelConfTypeDef *config) = 0;

virtual void initialize(float frequency) = 0;
virtual void terminate() = 0;

virtual void start() = 0;
virtual void stop() = 0;
};

} // namespace leka::interface
1 change: 1 addition & 0 deletions tests/unit/headers/mbed/mbed_config.h
Original file line number Diff line number Diff line change
Expand Up @@ -288,6 +288,7 @@
#define SMP_DB_MAX_DEVICES 3 // set by library:cordio
#define TARGET_LSE_DRIVE_LOAD_LEVEL RCC_LSEDRIVE_LOW // set by target:MCU_STM32F7
#define USE_HAL_JPEG_REGISTER_CALLBACKS 1U // set by application
#define USE_HAL_TIM_REGISTER_CALLBACKS 1U // set by application
// Macros
#define WSF_MS_PER_TICK 1 // defined by library:cordio
#define _RTE_ // defined by library:rtos
Expand Down
14 changes: 13 additions & 1 deletion tests/unit/mocks/mocks/leka/CoreSTM32Hal.h
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,10 @@ class CoreSTM32Hal : public interface::STM32Hal
MOCK_METHOD(void, HAL_RCC_GPIOH_CLK_ENABLE, (), (override));
MOCK_METHOD(void, HAL_RCC_GPIOI_CLK_ENABLE, (), (override));
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_DMA2_CLK_ENABLE, (), (override));
MOCK_METHOD(void, HAL_RCC_JPEG_CLK_ENABLE, (), (override));
Expand Down Expand Up @@ -113,6 +116,15 @@ class CoreSTM32Hal : public interface::STM32Hal

MOCK_METHOD(HAL_StatusTypeDef, HAL_JPEG_Pause, (JPEG_HandleTypeDef *, uint32_t), (override));
MOCK_METHOD(HAL_StatusTypeDef, HAL_JPEG_Resume, (JPEG_HandleTypeDef *, uint32_t), (override));
MOCK_METHOD(HAL_StatusTypeDef, HAL_TIM_Base_Init, (TIM_HandleTypeDef * htim), (override));
MOCK_METHOD(HAL_StatusTypeDef, HAL_TIMEx_MasterConfigSynchronization,
(TIM_HandleTypeDef * htim, TIM_MasterConfigTypeDef *sMasterConfig), (override));
MOCK_METHOD(HAL_StatusTypeDef, HAL_TIM_RegisterCallback,
(TIM_HandleTypeDef * htim, HAL_TIM_CallbackIDTypeDef CallbackID, pTIM_CallbackTypeDef pCallback),
(override));
MOCK_METHOD(HAL_StatusTypeDef, HAL_TIM_Base_Start_IT, (TIM_HandleTypeDef * htim), (override));
MOCK_METHOD(HAL_StatusTypeDef, HAL_TIM_Base_Stop_IT, (TIM_HandleTypeDef * htim), (override));
MOCK_METHOD(HAL_StatusTypeDef, HAL_TIM_Base_DeInit, (TIM_HandleTypeDef * htim), (override));
};

} // namespace leka::mock
Loading
Loading