Skip to content
Merged
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
18 changes: 17 additions & 1 deletion Inc/HALAL/Models/TimerDomain/TimerDomain.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,16 @@

#include "ErrorHandler/ErrorHandler.hpp"

#ifndef SCHEDULER_TIMER_DOMAIN
/* default is tim2 */
#define SCHEDULER_TIMER_DOMAIN 2
#elif (SCHEDULER_TIMER_DOMAIN != 2) && (SCHEDULER_TIMER_DOMAIN != 3) && \
(SCHEDULER_TIMER_DOMAIN != 23) && (SCHEDULER_TIMER_DOMAIN != 24)
#error Scheduler timer must be a 32 bit timer
#endif

#define SCHEDULER_GLOBAL_TIMER_IRQn glue(TIM, glue(SCHEDULER_TIMER_DOMAIN, _IRQn))

// NOTE: only works for static arrays
#define ARRAY_LENGTH(a) (sizeof(a) / sizeof(*a))

Expand Down Expand Up @@ -531,6 +541,10 @@ TimerXList
remaining_requests[i] = i;

for (int i = 0; i < (int)requests.size(); i++) {
if (static_cast<uint8_t>(requests[i].request) == SCHEDULER_TIMER_DOMAIN) {
ST_LIB::compile_error("This timer is used by the scheduler");
}

if (requests[i].request != TimerRequest::AnyGeneralPurpose &&
(requests[i].request < 1 || requests[i].request > 24 ||
(requests[i].request > 17 && requests[i].request < 23))) {
Expand Down Expand Up @@ -576,7 +590,7 @@ TimerXList
uint8_t count_32bit_requests = 0;

for (int i = 0; i < (int)ARRAY_LENGTH(bits32_timers); i++) {
if (!used_timers[bits32_timers[i]])
if (!used_timers[bits32_timers[i]] && (bits32_timers[i] != SCHEDULER_TIMER_DOMAIN))
remaining_32bit_timers[count_remaining_32bit_timers++] = bits32_timers[i];
}

Expand Down Expand Up @@ -662,6 +676,8 @@ TimerXList
static inline std::array<Instance, N> instances{};

static void init(std::span<const Config, N> cfgs) {
rcc_enable_timer(cmsis_timers[static_cast<uint8_t>(SCHEDULER_TIMER_DOMAIN)]);

for (std::size_t i = 0; i < N; i++) {
const Config& e = cfgs[i];

Expand Down
20 changes: 5 additions & 15 deletions Inc/HALAL/Services/Time/Scheduler.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -15,31 +15,21 @@
#include <cstdint>
#include <functional>

/* NOTE(vic): Esto cambiará pronto */
#ifndef SCHEDULER_TIMER_IDX
#define SCHEDULER_TIMER_IDX 2
#endif

#ifndef glue
#define glue_(a, b) a##b
#define glue(a, b) glue_(a, b)
#endif
#define SCHEDULER_TIMER_BASE glue(TIM, glue(SCHEDULER_TIMER_IDX, _BASE))

// Used to reserve a TimerPeripheral
#ifndef SIM_ON
#include "stm32h7xx_hal_tim.h"
#define SCHEDULER_HAL_TIM glue(htim, SCHEDULER_TIMER_IDX)
extern TIM_HandleTypeDef SCHEDULER_HAL_TIM;
#endif

extern TIM_TypeDef* Scheduler_global_timer;

struct Scheduler {
using callback_t = void (*)();
static constexpr uint32_t INVALID_ID = 0xFFu;

static void start();
static void update();
static inline uint64_t get_global_tick() { return global_tick_us_; }
static inline uint64_t get_global_tick() {
return global_tick_us_ + Scheduler_global_timer->CNT;
}

static uint16_t register_task(uint32_t period_us, callback_t func);
static bool unregister_task(uint16_t id);
Expand Down
19 changes: 6 additions & 13 deletions Src/HALAL/Services/Time/Scheduler.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -10,11 +10,8 @@

#include <stdint.h>

/* NOTE(vic): Pido perdón a Boris pero es la mejor manera que se me ha ocurrido hacer esto */
#define SCHEDULER_RCC_TIMER_ENABLE glue(glue(RCC_APB1LENR_TIM, SCHEDULER_TIMER_IDX), EN)
#define SCHEDULER_GLOBAL_TIMER_IRQn glue(TIM, glue(SCHEDULER_TIMER_IDX, _IRQn))
TIM_TypeDef* Scheduler_global_timer = nullptr;

#define Scheduler_global_timer ((TIM_TypeDef*)SCHEDULER_TIMER_BASE)
namespace {
constexpr uint64_t kMaxIntervalUs = static_cast<uint64_t>(UINT32_MAX) / 2 + 1ULL;
}
Expand Down Expand Up @@ -68,6 +65,8 @@ void scheduler_global_timer_callback(void* raw) {

void Scheduler::start() {
static_assert((Scheduler::FREQUENCY % 1'000'000) == 0u, "frequenct must be a multiple of 1MHz");
Scheduler_global_timer =
ST_LIB::TimerDomain::cmsis_timers[ST_LIB::timer_idxmap[SCHEDULER_TIMER_DOMAIN]];

uint32_t prescaler = (SystemCoreClock / Scheduler::FREQUENCY);
// setup prescaler
Expand Down Expand Up @@ -133,23 +132,17 @@ void Scheduler::start() {

if (prescaler == 0 || prescaler > 0xFFFF) {
ErrorHandler("Invalid prescaler value: %u", prescaler);
return;
}

// static_assert(prescaler < 0xFFFF, "Prescaler is 16 bit, so it must be in that range");
// static_assert(prescaler != 0, "Prescaler must be in the range [1, 65535]");
#ifndef SIM_ON
RCC->APB1LENR |= SCHEDULER_RCC_TIMER_ENABLE;
#endif

Scheduler_global_timer->PSC = (uint16_t)prescaler;
Scheduler_global_timer->ARR = 0;
Scheduler_global_timer->DIER |= LL_TIM_DIER_UIE;
Scheduler_global_timer->CR1 =
LL_TIM_CLOCKDIVISION_DIV1 | (Scheduler_global_timer->CR1 & ~TIM_CR1_CKD);

// Temporary solution for TimerDomain
ST_LIB::TimerDomain::callbacks[ST_LIB::timer_idxmap[SCHEDULER_TIMER_IDX]] =
scheduler_global_timer_callback;
ST_LIB::TimerDomain::callbacks[ST_LIB::timer_idxmap[static_cast<uint8_t>(SCHEDULER_TIMER_DOMAIN
)]] = scheduler_global_timer_callback;

Scheduler_global_timer->CNT = 0; /* Clear counter value */

Expand Down
1 change: 1 addition & 0 deletions Tests/Time/scheduler_test.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ class SchedulerTests : public ::testing::Test {
Scheduler::sorted_task_ids_ = 0;
Scheduler::global_tick_us_ = 0;
Scheduler::current_interval_us_ = 0;
Scheduler_global_timer = TIM2_BASE;

// Reset global callback task count
count = 0;
Expand Down