Skip to content
2 changes: 2 additions & 0 deletions .changesets/scheduler-get-perf.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
release: minor
summary: Implement simple performance gathering with the scheduler
20 changes: 20 additions & 0 deletions Inc/HALAL/Models/TimerDomain/TimerDomain.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -209,6 +209,26 @@ struct TimerPin {
ST_LIB::TimerChannel channel;
};

struct TimerOutputChannelConfig {
uint32_t OCMode; /*!< Specifies the TIM mode.
This parameter can be a value of @ref TIM_Output_Compare_and_PWM_modes */

uint32_t OCPolarity; /*!< Specifies the output polarity.
This parameter can be a value of @ref TIM_Output_Compare_Polarity */

uint32_t OCNPolarity; /*!< Specifies the complementary output polarity.
This parameter can be a value of @ref TIM_Output_Compare_N_Polarity
@note This parameter is valid only for timer instances supporting break feature. */

uint32_t OCIdleState; /*!< Specifies the TIM Output Compare pin state during Idle state.
This parameter can be a value of @ref TIM_Output_Compare_Idle_State
@note This parameter is valid only for timer instances supporting break feature. */

uint32_t OCNIdleState; /*!< Specifies the TIM Output Compare pin state during Idle state.
This parameter can be a value of @ref TIM_Output_Compare_N_Idle_State
@note This parameter is valid only for timer instances supporting break feature. */
};

#ifndef DEFAULT_PWM_FREQUENCY_MODE
#define DEFAULT_PWM_FREQUENCY_MODE ST_LIB::PWM_Frequency_Mode::PRECISION
#endif
Expand Down
10 changes: 10 additions & 0 deletions Inc/HALAL/Services/Communication/UART/UART.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -160,6 +160,16 @@ class UART {
*/
static bool transmit_polling(uint8_t id, span<uint8_t> data);

/**@brief Transmits size bytes by polling.
*
* @param id Id of the UART
* @param data Pointer to data to be sent.
* @param length Length of data to be sent.
* @return bool Returns true if the packet has been send successfully.
* Returns false if the UART is busy or a problem has occurred.
*/
static bool transmit_polling(uint8_t id, uint8_t* data, size_t length);

/**
* @brief This method request the receive of size bytes
* by DMA and interrupts. Thus the data should not be used until
Expand Down
65 changes: 62 additions & 3 deletions Inc/HALAL/Services/PWM/DualPWM.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -49,14 +49,12 @@ class DualPWM {
PANIC("Timer instance is not set for DualPWM");
return;
}
TIM_OC_InitTypeDef sConfigOC = {
ST_LIB::TimerOutputChannelConfig sConfigOC = {
.OCMode = TIM_OCMODE_PWM1,
.Pulse = 0,

.OCPolarity = polarity,
.OCNPolarity = negated_polarity,

.OCFastMode = TIM_OCFAST_DISABLE,
.OCIdleState = TIM_OCIDLESTATE_RESET,
.OCNIdleState = TIM_OCNIDLESTATE_RESET,
};
Expand Down Expand Up @@ -274,6 +272,67 @@ class DualPWM {
SET_BIT(timer->instance->tim->BDTR, TIM_BDTR_MOE);
}
}

/* NOTE: fast mode is only supported in pwms */
inline void enable_fast_mode() {
if constexpr (pin.channel == TimerChannel::CHANNEL_1 || pin.channel == TimerChannel::CHANNEL_1_NEGATED) {
SET_BIT(this->timer->instance->tim->CCMR1, TIM_CCMR1_OC1FE);
} else if constexpr (pin.channel == TimerChannel::CHANNEL_2 || pin.channel == TimerChannel::CHANNEL_2_NEGATED) {
SET_BIT(this->timer->instance->tim->CCMR1, TIM_CCMR1_OC2FE);
} else if constexpr (pin.channel == TimerChannel::CHANNEL_3 || pin.channel == TimerChannel::CHANNEL_3_NEGATED) {
SET_BIT(this->timer->instance->tim->CCMR2, TIM_CCMR2_OC3FE);
} else if constexpr (pin.channel == TimerChannel::CHANNEL_4 || pin.channel == TimerChannel::CHANNEL_4_NEGATED) {
SET_BIT(this->timer->instance->tim->CCMR2, TIM_CCMR2_OC4FE);
} else if constexpr (pin.channel == TimerChannel::CHANNEL_5) {
SET_BIT(this->timer->instance->tim->CCMR3, TIM_CCMR3_OC5FE);
} else if constexpr (pin.channel == TimerChannel::CHANNEL_6) {
SET_BIT(this->timer->instance->tim->CCMR3, TIM_CCMR3_OC6FE);
}

if constexpr (negated_pin.channel == TimerChannel::CHANNEL_1 || negated_pin.channel == TimerChannel::CHANNEL_1_NEGATED) {
SET_BIT(this->timer->instance->tim->CCMR1, TIM_CCMR1_OC1FE);
} else if constexpr (negated_pin.channel == TimerChannel::CHANNEL_2 || negated_pin.channel == TimerChannel::CHANNEL_2_NEGATED) {
SET_BIT(this->timer->instance->tim->CCMR1, TIM_CCMR1_OC2FE);
} else if constexpr (negated_pin.channel == TimerChannel::CHANNEL_3 || negated_pin.channel == TimerChannel::CHANNEL_3_NEGATED) {
SET_BIT(this->timer->instance->tim->CCMR2, TIM_CCMR2_OC3FE);
} else if constexpr (negated_pin.channel == TimerChannel::CHANNEL_4 || negated_pin.channel == TimerChannel::CHANNEL_4_NEGATED) {
SET_BIT(this->timer->instance->tim->CCMR2, TIM_CCMR2_OC4FE);
} else if constexpr (negated_pin.channel == TimerChannel::CHANNEL_5) {
SET_BIT(this->timer->instance->tim->CCMR3, TIM_CCMR3_OC5FE);
} else if constexpr (negated_pin.channel == TimerChannel::CHANNEL_6) {
SET_BIT(this->timer->instance->tim->CCMR3, TIM_CCMR3_OC6FE);
}
}

inline void disable_fast_mode() {
if constexpr (pin.channel == TimerChannel::CHANNEL_1 || pin.channel == TimerChannel::CHANNEL_1_NEGATED) {
CLEAR_BIT(this->timer->instance->tim->CCMR1, TIM_CCMR1_OC1FE);
} else if constexpr (pin.channel == TimerChannel::CHANNEL_2 || pin.channel == TimerChannel::CHANNEL_2_NEGATED) {
CLEAR_BIT(this->timer->instance->tim->CCMR1, TIM_CCMR1_OC2FE);
} else if constexpr (pin.channel == TimerChannel::CHANNEL_3 || pin.channel == TimerChannel::CHANNEL_3_NEGATED) {
CLEAR_BIT(this->timer->instance->tim->CCMR2, TIM_CCMR2_OC3FE);
} else if constexpr (pin.channel == TimerChannel::CHANNEL_4 || pin.channel == TimerChannel::CHANNEL_4_NEGATED) {
CLEAR_BIT(this->timer->instance->tim->CCMR2, TIM_CCMR2_OC4FE);
} else if constexpr (pin.channel == TimerChannel::CHANNEL_5) {
CLEAR_BIT(this->timer->instance->tim->CCMR3, TIM_CCMR3_OC5FE);
} else if constexpr (pin.channel == TimerChannel::CHANNEL_6) {
CLEAR_BIT(this->timer->instance->tim->CCMR3, TIM_CCMR3_OC6FE);
}

if constexpr (negated_pin.channel == TimerChannel::CHANNEL_1 || negated_pin.channel == TimerChannel::CHANNEL_1_NEGATED) {
CLEAR_BIT(this->timer->instance->tim->CCMR1, TIM_CCMR1_OC1FE);
} else if constexpr (negated_pin.channel == TimerChannel::CHANNEL_2 || negated_pin.channel == TimerChannel::CHANNEL_2_NEGATED) {
CLEAR_BIT(this->timer->instance->tim->CCMR1, TIM_CCMR1_OC2FE);
} else if constexpr (negated_pin.channel == TimerChannel::CHANNEL_3 || negated_pin.channel == TimerChannel::CHANNEL_3_NEGATED) {
CLEAR_BIT(this->timer->instance->tim->CCMR2, TIM_CCMR2_OC3FE);
} else if constexpr (negated_pin.channel == TimerChannel::CHANNEL_4 || negated_pin.channel == TimerChannel::CHANNEL_4_NEGATED) {
CLEAR_BIT(this->timer->instance->tim->CCMR2, TIM_CCMR2_OC4FE);
} else if constexpr (negated_pin.channel == TimerChannel::CHANNEL_5) {
CLEAR_BIT(this->timer->instance->tim->CCMR3, TIM_CCMR3_OC5FE);
} else if constexpr (negated_pin.channel == TimerChannel::CHANNEL_6) {
CLEAR_BIT(this->timer->instance->tim->CCMR3, TIM_CCMR3_OC6FE);
}
}
};
} // namespace ST_LIB

Expand Down
37 changes: 34 additions & 3 deletions Inc/HALAL/Services/PWM/PWM.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -40,14 +40,12 @@ template <const TimerDomain::Timer& dev, const ST_LIB::TimerPin pin> class PWM {
PANIC("Timer instance is not set for PWM");
return;
}
TIM_OC_InitTypeDef sConfigOC = {
ST_LIB::TimerOutputChannelConfig sConfigOC = {
.OCMode = TIM_OCMODE_PWM1,
.Pulse = 0,

.OCPolarity = polarity,
.OCNPolarity = negated_polarity,

.OCFastMode = TIM_OCFAST_DISABLE,
.OCIdleState = TIM_OCIDLESTATE_RESET,
.OCNIdleState = TIM_OCNIDLESTATE_RESET,
};
Expand Down Expand Up @@ -153,6 +151,39 @@ template <const TimerDomain::Timer& dev, const ST_LIB::TimerPin pin> class PWM {

inline uint32_t get_frequency() const { return *(this->frequency); }
inline float get_duty_cycle() const { return *(this->duty_cycle); }

/* NOTE: fast mode is only supported in pwms */
inline void enable_fast_mode() {
if constexpr (pin.channel == TimerChannel::CHANNEL_1 || pin.channel == TimerChannel::CHANNEL_1_NEGATED) {
SET_BIT(this->timer->instance->tim->CCMR1, TIM_CCMR1_OC1FE);
} else if constexpr (pin.channel == TimerChannel::CHANNEL_2 || pin.channel == TimerChannel::CHANNEL_2_NEGATED) {
SET_BIT(this->timer->instance->tim->CCMR1, TIM_CCMR1_OC2FE);
} else if constexpr (pin.channel == TimerChannel::CHANNEL_3 || pin.channel == TimerChannel::CHANNEL_3_NEGATED) {
SET_BIT(this->timer->instance->tim->CCMR2, TIM_CCMR2_OC3FE);
} else if constexpr (pin.channel == TimerChannel::CHANNEL_4 || pin.channel == TimerChannel::CHANNEL_4_NEGATED) {
SET_BIT(this->timer->instance->tim->CCMR2, TIM_CCMR2_OC4FE);
} else if constexpr (pin.channel == TimerChannel::CHANNEL_5) {
SET_BIT(this->timer->instance->tim->CCMR3, TIM_CCMR3_OC5FE);
} else if constexpr (pin.channel == TimerChannel::CHANNEL_6) {
SET_BIT(this->timer->instance->tim->CCMR3, TIM_CCMR3_OC6FE);
}
}

inline void disable_fast_mode() {
if constexpr (pin.channel == TimerChannel::CHANNEL_1 || pin.channel == TimerChannel::CHANNEL_1_NEGATED) {
CLEAR_BIT(this->timer->instance->tim->CCMR1, TIM_CCMR1_OC1FE);
} else if constexpr (pin.channel == TimerChannel::CHANNEL_2 || pin.channel == TimerChannel::CHANNEL_2_NEGATED) {
CLEAR_BIT(this->timer->instance->tim->CCMR1, TIM_CCMR1_OC2FE);
} else if constexpr (pin.channel == TimerChannel::CHANNEL_3 || pin.channel == TimerChannel::CHANNEL_3_NEGATED) {
CLEAR_BIT(this->timer->instance->tim->CCMR2, TIM_CCMR2_OC3FE);
} else if constexpr (pin.channel == TimerChannel::CHANNEL_4 || pin.channel == TimerChannel::CHANNEL_4_NEGATED) {
CLEAR_BIT(this->timer->instance->tim->CCMR2, TIM_CCMR2_OC4FE);
} else if constexpr (pin.channel == TimerChannel::CHANNEL_5) {
CLEAR_BIT(this->timer->instance->tim->CCMR3, TIM_CCMR3_OC5FE);
} else if constexpr (pin.channel == TimerChannel::CHANNEL_6) {
CLEAR_BIT(this->timer->instance->tim->CCMR3, TIM_CCMR3_OC6FE);
}
}
};
} // namespace ST_LIB

Expand Down
29 changes: 26 additions & 3 deletions Inc/HALAL/Services/Time/Scheduler.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@
#endif

#include "stm32h7xx_ll_tim_wrapper.h"
#include "HALAL/Models/Packets/Packet.hpp"
#include "HALAL/Services/Communication/UART/UART.hpp"

#include <array>
#include <cstdint>
Expand All @@ -27,6 +27,25 @@
#include "stm32h7xx_hal_tim.h"
#endif

#ifndef SIM_ON
//#define SCHEDULER_GET_LAST_N_TASKS
#else
struct UART {
struct Peripheral {
uint8_t ignore0;
};
uint8_t ignore1;
};
#endif

#if !defined(SCHEDULER_GET_LAST_N_TASKS) && !defined(SLOW_CHECK_USE_READY_BITMAP)
#define SLOW_CHECK_USE_READY_BITMAP
#endif

#if !defined(SCHEDULER_GET_LAST_N_TASKS_COUNT)
#define SCHEDULER_GET_LAST_N_TASKS_COUNT 64
#endif

extern TIM_TypeDef* Scheduler_global_timer;
void Scheduler_global_timer_callback(void* raw);
void Scheduler_start(void);
Expand All @@ -38,8 +57,12 @@ struct Scheduler {
// if it isn't it could theoretically be used as an id in set_timeout
static constexpr uint32_t INVALID_ID = 2 * kMaxTasks;

// temporary, will be removed
[[deprecated]] static inline void start() {}
/* gets and checks the performance gathering requirements
* @param tim32bit: A timer or null if not gathering perf info (preferrably 32 bit)
* @return If the given arguments are correct
*/
static bool init_perf(TIM_TypeDef* tim32bit, UART::Peripheral* uart);

static void update();
static uint64_t get_global_tick();

Expand Down
15 changes: 1 addition & 14 deletions Inc/HALAL/Services/Time/TimerWrapper.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -564,7 +564,7 @@ template <const TimerDomain::Timer& dev> struct TimerWrapper {
/* NOTE(vic): Both config_output_compare_channel and config_input_compare_channel
* Could probably be done better if not using TIM_[OC/IC]_InitTypeDef structures */
template <ST_LIB::TimerChannel ch>
inline void config_output_compare_channel(const TIM_OC_InitTypeDef* OC_Config) {
inline void config_output_compare_channel(const ST_LIB::TimerOutputChannelConfig* OC_Config) {
if constexpr (!((ch == TimerChannel::CHANNEL_1) || (ch == TimerChannel::CHANNEL_2) ||
(ch == TimerChannel::CHANNEL_3) || (ch == TimerChannel::CHANNEL_4) ||
(ch == TimerChannel::CHANNEL_5) || (ch == TimerChannel::CHANNEL_6))) {
Expand Down Expand Up @@ -700,19 +700,6 @@ template <const TimerDomain::Timer& dev> struct TimerWrapper {
instance->tim->CCMR3 = tmpccmrx;
}

if constexpr (ch == TimerChannel::CHANNEL_1)
instance->tim->CCR1 = OC_Config->Pulse;
else if constexpr (ch == TimerChannel::CHANNEL_2)
instance->tim->CCR2 = OC_Config->Pulse;
else if constexpr (ch == TimerChannel::CHANNEL_3)
instance->tim->CCR3 = OC_Config->Pulse;
else if constexpr (ch == TimerChannel::CHANNEL_4)
instance->tim->CCR4 = OC_Config->Pulse;
else if constexpr (ch == TimerChannel::CHANNEL_5)
instance->tim->CCR5 = OC_Config->Pulse;
else if constexpr (ch == TimerChannel::CHANNEL_6)
instance->tim->CCR6 = OC_Config->Pulse;

instance->tim->CCER = tmpccer;
}

Expand Down
6 changes: 5 additions & 1 deletion Src/HALAL/Services/Communication/UART/UART.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,10 @@ bool UART::transmit_polling(uint8_t id, uint8_t data) {
}

bool UART::transmit_polling(uint8_t id, span<uint8_t> data) {
return UART::transmit_polling(id, data.data(), data.size());
}

bool UART::transmit_polling(uint8_t id, uint8_t* data, size_t length) {
if (not UART::registered_uart.contains(id))
return false; // TODO: Error handler

Expand All @@ -72,7 +76,7 @@ bool UART::transmit_polling(uint8_t id, span<uint8_t> data) {
if ((handle->ErrorCode & TXBUSYMASK) == 1)
return false;

if (HAL_UART_Transmit(handle, data.data(), data.size(), 10) != HAL_OK) {
if (HAL_UART_Transmit(handle, data, length, 10) != HAL_OK) {
return false; // TODO: Warning, Error during transmision
}

Expand Down
Loading
Loading