From 22dd70cb706eeab335271ac4ac26be655cd25ee5 Mon Sep 17 00:00:00 2001 From: "@CarlWachter" Date: Wed, 25 Oct 2023 15:57:52 +0200 Subject: [PATCH 01/17] CAN bus completion of abstract class Can additions --- include/sta/devices/stm32/can.hpp | 8 ++++++++ src/devices/stm32/can.cpp | 23 +++++++++++++++++++++++ 2 files changed, 31 insertions(+) diff --git a/include/sta/devices/stm32/can.hpp b/include/sta/devices/stm32/can.hpp index e935cf5..cd75304 100644 --- a/include/sta/devices/stm32/can.hpp +++ b/include/sta/devices/stm32/can.hpp @@ -80,6 +80,14 @@ namespace sta void disableFilter(uint8_t idx) override; void clearFilters() override; + // TODO + CanPendingRxFifos getPendingRxFifos() override; + + // Const getters + uint8_t maxFilterCount() const override; + uint8_t maxFifoCount() const override; + uint8_t maxPayloadSize() const override; + private: /** * @brief Initialize filter settings. diff --git a/src/devices/stm32/can.cpp b/src/devices/stm32/can.cpp index 0c485ea..66b07ac 100644 --- a/src/devices/stm32/can.cpp +++ b/src/devices/stm32/can.cpp @@ -168,6 +168,29 @@ namespace sta config->SlaveStartFilterBank = MAX_FILTER_COUNT; } } + + CanPendingRxFifos STM32CanController::getPendingRxFifos(){ + CanPendingRxFifos pendingFifos(42, 3); + + // Example implementation: + //pendingFifos.fifo0Pending = HAL_CAN_GetRxFifoFillLevel(handle_, CAN_RX_FIFO0) != 0; + //pendingFifos.fifo1Pending = HAL_CAN_GetRxFifoFillLevel(handle_, CAN_RX_FIFO1) != 0; + + return pendingFifos; + } + + uint8_t STM32CanController::maxFilterCount() const{ + return MAX_FILTER_COUNT; + } + + uint8_t STM32CanController::maxFifoCount() const { + return MAX_FIFO_COUNT; + } + + uint8_t STM32CanController::maxPayloadSize() const { + return MAX_PAYLOAD_SIZE; + } + } // namespace sta From e8f7261030b71d8e80843d68532e595f545866fe Mon Sep 17 00:00:00 2001 From: "@CarlWachter" Date: Thu, 4 Jan 2024 16:54:53 +0100 Subject: [PATCH 02/17] Completed getPendingRxFifos --- include/sta/devices/stm32/can.hpp | 2 +- src/devices/stm32/can.cpp | 19 ++++++++++++++----- 2 files changed, 15 insertions(+), 6 deletions(-) diff --git a/include/sta/devices/stm32/can.hpp b/include/sta/devices/stm32/can.hpp index cd75304..598b2bd 100644 --- a/include/sta/devices/stm32/can.hpp +++ b/include/sta/devices/stm32/can.hpp @@ -80,7 +80,7 @@ namespace sta void disableFilter(uint8_t idx) override; void clearFilters() override; - // TODO + // Return pending RX FIFOs as iterable container CanPendingRxFifos getPendingRxFifos() override; // Const getters diff --git a/src/devices/stm32/can.cpp b/src/devices/stm32/can.cpp index 66b07ac..7a5cd59 100644 --- a/src/devices/stm32/can.cpp +++ b/src/devices/stm32/can.cpp @@ -170,13 +170,22 @@ namespace sta } CanPendingRxFifos STM32CanController::getPendingRxFifos(){ - CanPendingRxFifos pendingFifos(42, 3); - // Example implementation: - //pendingFifos.fifo0Pending = HAL_CAN_GetRxFifoFillLevel(handle_, CAN_RX_FIFO0) != 0; - //pendingFifos.fifo1Pending = HAL_CAN_GetRxFifoFillLevel(handle_, CAN_RX_FIFO1) != 0; - return pendingFifos; + uint32_t rxFlags = 0; + + // Conditions to set the least significant bits + if (HAL_CAN_GetRxFifoFillLevel(handle_, CAN_RX_FIFO0) != 0) { + // Set the first least significant bit + rxFlags |= 0x01; // 0x01 is 00000001 in binary (LSB set, others cleared) + } + + if (HAL_CAN_GetRxFifoFillLevel(handle_, CAN_RX_FIFO1) != 0) { + // Set the second least significant bit + rxFlags |= 0x02; // 0x02 is 00000010 in binary (2nd LSB set, others cleared) + } + + return CanPendingRxFifos(rxFlags, MAX_FIFO_COUNT);; } uint8_t STM32CanController::maxFilterCount() const{ From 8901abdb9cc393b3e7f2de295e75ba4205d6de39 Mon Sep 17 00:00:00 2001 From: CarlWachter Date: Tue, 30 Jan 2024 15:24:38 +0100 Subject: [PATCH 03/17] Added CAN to ASEAG --- include/sta/devices/stm32/mcu/STM32F407xx.hpp | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/include/sta/devices/stm32/mcu/STM32F407xx.hpp b/include/sta/devices/stm32/mcu/STM32F407xx.hpp index 48db885..f390ad0 100644 --- a/include/sta/devices/stm32/mcu/STM32F407xx.hpp +++ b/include/sta/devices/stm32/mcu/STM32F407xx.hpp @@ -14,9 +14,10 @@ #include -// uart setup +// uart/CAN setup #ifdef STA_STM32_ASEAG # define STA_STM32_USART_HANDLE huart1 +# define STA_STM32_CAN_HANDLE hcan1 #else # ifdef STA_STM32_SWD_USART_IDX # define STA_STM32_USART_HANDLE CONCAT(huart, STA_STM32_SWD_USART_IDX) @@ -100,4 +101,4 @@ /** @} */ -#endif // STA_CORE_STM32_MCU_STM32F407xx_HPP \ No newline at end of file +#endif // STA_CORE_STM32_MCU_STM32F407xx_HPP From 1fc34fa5742df03d324440b80ac2cd4939311849 Mon Sep 17 00:00:00 2001 From: dario Date: Fri, 15 Mar 2024 13:00:23 +0100 Subject: [PATCH 04/17] Added DMA support for ADC --- include/sta/devices/stm32/adc.hpp | 8 ++++++++ src/devices/stm32/adc.cpp | 11 +++++++++++ 2 files changed, 19 insertions(+) diff --git a/include/sta/devices/stm32/adc.hpp b/include/sta/devices/stm32/adc.hpp index 62b2985..e9b6292 100644 --- a/include/sta/devices/stm32/adc.hpp +++ b/include/sta/devices/stm32/adc.hpp @@ -31,6 +31,14 @@ namespace sta */ void start(); + /** + * @brief Starts conversion of the incoming analog signal in DMA mode. + * + * @param buffer The buffer to write the converted values to. + * @param length The length of the buffer to write the converted values to. + */ + void startDMA(uint32_t * buffer, size_t length); + /** * @brief Polls for the converted analog signal. * diff --git a/src/devices/stm32/adc.cpp b/src/devices/stm32/adc.cpp index 5c5d663..fa57930 100644 --- a/src/devices/stm32/adc.cpp +++ b/src/devices/stm32/adc.cpp @@ -17,6 +17,17 @@ namespace sta HAL_ADC_Start(handle_); } + void STM32ADC::startDMA(uint32_t * buffer, size_t length) + { + STA_ASSERT(buffer != nullptr); + STA_ASSERT(length != 0); + STA_ASSERT(handle_->DMA_Handle != nullptr); + + HAL_StatusTypeDef res = HAL_ADC_Start_DMA(handle_, buffer, length); + + STA_ASSERT(res == HAL_OK); + } + void STM32ADC::poll(uint32_t timeout) { HAL_StatusTypeDef res = HAL_ADC_PollForConversion(handle_, timeout); From 9f0defa24f6f384770bbf791e8765165840eb33d Mon Sep 17 00:00:00 2001 From: dario Date: Fri, 15 Mar 2024 17:19:26 +0100 Subject: [PATCH 05/17] Fixed breaking bug in printable --- src/debug/printing/printable_uart.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/debug/printing/printable_uart.cpp b/src/debug/printing/printable_uart.cpp index 76a63f8..f3f7453 100644 --- a/src/debug/printing/printable_uart.cpp +++ b/src/debug/printing/printable_uart.cpp @@ -19,7 +19,9 @@ namespace sta void PrintableUART::print(const char * str, size_t length) { + intf_->acquire(); intf_->transfer(reinterpret_cast(str), length); + intf_->release(); } } // namespace sta From 67e7d88a5be5dfc1aae536e587dd0cbeba0475e4 Mon Sep 17 00:00:00 2001 From: dario Date: Thu, 18 Apr 2024 00:01:14 +0200 Subject: [PATCH 06/17] Added easier GPIO pin API --- include/sta/gpio_pin.hpp | 18 ++++++++++++++++++ src/gpio_pin.cpp | 20 ++++++++++++++++++++ 2 files changed, 38 insertions(+) create mode 100644 src/gpio_pin.cpp diff --git a/include/sta/gpio_pin.hpp b/include/sta/gpio_pin.hpp index 9a26f4c..3ab32be 100644 --- a/include/sta/gpio_pin.hpp +++ b/include/sta/gpio_pin.hpp @@ -38,6 +38,24 @@ namespace sta */ virtual void setState(GpioPinState state) = 0; + /** + * @brief Set the GPIO pin to high. + * + */ + void setHigh(); + + /** + * @brief Set the GPIO pin to low. + * + */ + void setLow(); + + /** + * @brief Set the GPIO pin to the opposite of the current state. + * + */ + void toggle(); + /** * @brief Get pin input state. * diff --git a/src/gpio_pin.cpp b/src/gpio_pin.cpp new file mode 100644 index 0000000..aafd52e --- /dev/null +++ b/src/gpio_pin.cpp @@ -0,0 +1,20 @@ +#include + + +namespace sta +{ + void GpioPin::setHigh() + { + setState(GpioPinState::GPIO_HIGH); + } + + void GpioPin::setLow() + { + setState(GpioPinState::GPIO_LOW); + } + + void GpioPin::toggle() + { + setState(getState() == GpioPinState::GPIO_HIGH ? GpioPinState::GPIO_LOW : GpioPinState::GPIO_HIGH); + } +} // namespace sta From 3fe276f19d370d29f43c1a173a043e5b5a301a8b Mon Sep 17 00:00:00 2001 From: Iveta Date: Sat, 20 Apr 2024 15:58:36 +0300 Subject: [PATCH 07/17] added a delay check and updated README --- README.md | 7 +++++++ include/sta/devices/stm32/delay.hpp | 2 +- include/sta/devices/stm32/init.hpp | 1 + src/devices/stm32/delay.cpp | 3 ++- 4 files changed, 11 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 57a9791..0cc739d 100644 --- a/README.md +++ b/README.md @@ -85,6 +85,13 @@ Configuration: TIM time base must be started before using `sta::delayUs` by calling `sta::initHAL`. When using the startup system task this is handled automatically. +Steps to enable delayUs: +* Include sta/devices/stm32/delay.hpp in the file where the delayUs function is called +* Enable a timer TIM in .ioc file with the settings: Slave Mode=Disable, Trigger Mode=Disable, Clock Source=Internal Clock, all other channels =Disable) +* Define STA_STM32_DELAY_US_TIM in App/Inc/sta/config.hpp as the timer handle (can be found in Core/Inc/tim.h). For TIM1, this would be htim1 +* Do not use this timer for delays of over 1000 us; we have delayMs for that + + ## Interfaces diff --git a/include/sta/devices/stm32/delay.hpp b/include/sta/devices/stm32/delay.hpp index 6fbd3c5..81b3bb1 100644 --- a/include/sta/devices/stm32/delay.hpp +++ b/include/sta/devices/stm32/delay.hpp @@ -44,7 +44,7 @@ namespace sta * * @param us Microseconds */ - void delayUs(uint32_t us); + void delayUs(uint16_t us); #endif // STA_STM32_DELAY_US_TIM diff --git a/include/sta/devices/stm32/init.hpp b/include/sta/devices/stm32/init.hpp index 7fee75f..cd34558 100644 --- a/include/sta/devices/stm32/init.hpp +++ b/include/sta/devices/stm32/init.hpp @@ -5,6 +5,7 @@ #ifndef STA_CORE_STM32_INIT_HPP #define STA_CORE_STM32_INIT_HPP +#include namespace sta { diff --git a/src/devices/stm32/delay.cpp b/src/devices/stm32/delay.cpp index 8f51d73..dba0891 100644 --- a/src/devices/stm32/delay.cpp +++ b/src/devices/stm32/delay.cpp @@ -62,10 +62,11 @@ namespace sta return (updateFreq >= 1000000); } - void delayUs(uint32_t us) + void delayUs(uint16_t us) { // Check if the specified timer is usable for microsecond delays. STA_ASSERT(isValidDelayUsTIM()); + STA_ASSERT(us < 1000); __HAL_TIM_SET_COUNTER(&STA_STM32_DELAY_US_TIM, 0); while (__HAL_TIM_GET_COUNTER(&STA_STM32_DELAY_US_TIM) < us * gDelayUsMul); From 78479d528c99d5fb1965dd5864acb1eed4f02f07 Mon Sep 17 00:00:00 2001 From: CarlWachter Date: Tue, 30 Apr 2024 13:41:57 +0200 Subject: [PATCH 08/17] CAN via Interrupt --- src/devices/stm32/can.cpp | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/src/devices/stm32/can.cpp b/src/devices/stm32/can.cpp index 7a5cd59..31bde0d 100644 --- a/src/devices/stm32/can.cpp +++ b/src/devices/stm32/can.cpp @@ -203,16 +203,16 @@ namespace sta } // namespace sta -#ifdef STA_STM32_CAN_GLOBAL +#ifdef STA_STM32_CAN_HANDLE #include namespace sta { - STM32CanController CanBus(&STA_STM32_CAN_GLOBAL); + STM32CanController CanBus(&STA_STM32_CAN_HANDLE); STA_WEAK - void CanBus_RxPendingCallback() + void CanBus_RxPendingCallback(uint32_t fifo) {} } // namespace sta @@ -221,17 +221,17 @@ extern "C" { void HAL_CAN_RxFifo0MsgPendingCallback(CAN_HandleTypeDef *hcan) { - if (hcan == &STA_STM32_CAN_GLOBAL) + if (hcan == &STA_STM32_CAN_HANDLE) { - sta::CanBus_RxPendingCallback(); + sta::CanBus_RxPendingCallback(CAN_RX_FIFO0); } } void HAL_CAN_RxFifo1MsgPendingCallback(CAN_HandleTypeDef *hcan) { - if (hcan == &STA_STM32_CAN_GLOBAL) + if (hcan == &STA_STM32_CAN_HANDLE) { - sta::CanBus_RxPendingCallback(); + sta::CanBus_RxPendingCallback(CAN_RX_FIFO1); } } } From 61b738e2fc634c3525a74b1bc128a718707e2221 Mon Sep 17 00:00:00 2001 From: CarlWachter Date: Tue, 30 Apr 2024 15:25:06 +0200 Subject: [PATCH 09/17] Fix: Actually applying the configs for the CAN Filter --- src/devices/stm32/can.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/devices/stm32/can.cpp b/src/devices/stm32/can.cpp index 31bde0d..47e9c97 100644 --- a/src/devices/stm32/can.cpp +++ b/src/devices/stm32/can.cpp @@ -166,6 +166,7 @@ namespace sta config->FilterScale = CAN_FILTERSCALE_32BIT; config->FilterActivation = CAN_FILTER_DISABLE; config->SlaveStartFilterBank = MAX_FILTER_COUNT; + HAL_CAN_ConfigFilter(handle_, config); } } From 311f0a6fa6fbb7ad4f944468384cdd5337d6e71a Mon Sep 17 00:00:00 2001 From: Iveta Date: Wed, 1 May 2024 15:03:21 +0300 Subject: [PATCH 10/17] restored delayUs declaration --- include/sta/devices/stm32/delay.hpp | 2 +- src/devices/stm32/delay.cpp | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/include/sta/devices/stm32/delay.hpp b/include/sta/devices/stm32/delay.hpp index 81b3bb1..6fbd3c5 100644 --- a/include/sta/devices/stm32/delay.hpp +++ b/include/sta/devices/stm32/delay.hpp @@ -44,7 +44,7 @@ namespace sta * * @param us Microseconds */ - void delayUs(uint16_t us); + void delayUs(uint32_t us); #endif // STA_STM32_DELAY_US_TIM diff --git a/src/devices/stm32/delay.cpp b/src/devices/stm32/delay.cpp index dba0891..3592bf0 100644 --- a/src/devices/stm32/delay.cpp +++ b/src/devices/stm32/delay.cpp @@ -62,7 +62,7 @@ namespace sta return (updateFreq >= 1000000); } - void delayUs(uint16_t us) + void delayUs(uint32_t us) { // Check if the specified timer is usable for microsecond delays. STA_ASSERT(isValidDelayUsTIM()); From 767bd19c362a1a958e05c9e0fa68bfa616eff469 Mon Sep 17 00:00:00 2001 From: dario Date: Wed, 22 May 2024 13:07:36 +0200 Subject: [PATCH 11/17] added profiler and updated delay implementation --- include/sta/devices/stm32/clocks.hpp | 1 + include/sta/time.hpp | 15 +++++++++++++ src/devices/stm32/delay.cpp | 26 +++++++++++++++++++--- src/devices/stm32/init.cpp | 2 ++ src/devices/stm32/time.cpp | 32 ++++++++++++++++++++++++++++ src/time.cpp | 26 ++++++++++++++++++++++ 6 files changed, 99 insertions(+), 3 deletions(-) create mode 100644 src/devices/stm32/time.cpp create mode 100644 src/time.cpp diff --git a/include/sta/devices/stm32/clocks.hpp b/include/sta/devices/stm32/clocks.hpp index 0d8d832..cd2ac38 100644 --- a/include/sta/devices/stm32/clocks.hpp +++ b/include/sta/devices/stm32/clocks.hpp @@ -58,6 +58,7 @@ namespace sta */ #define _STA_STM32_PCLK_IDX_MAP(type, idx) STA_STM32_ ## type ## _ ## idx ## _PCLK_IDX // Get HAL handle to PCLK index map macro + /** * @brief Map instance handle to PCLK index. * diff --git a/include/sta/time.hpp b/include/sta/time.hpp index 6495952..1cb5562 100644 --- a/include/sta/time.hpp +++ b/include/sta/time.hpp @@ -16,12 +16,27 @@ namespace sta * @return Time in milliseconds */ using TimeMsFn = uint32_t (*)(); + /** * @brief Signature for microseconds precision time. * * @return Time in microseconds */ using TimeUsFn = uint32_t (*)(); + + /** + * @brief Gets the current time in milliseconds. + * + * @return Time in milliseconds + */ + uint32_t timeMs(); + + /** + * @brief Gets the current time in microseconds. + * + * @return Time in microseconds + */ + uint32_t timeUs(); } // namespace sta diff --git a/src/devices/stm32/delay.cpp b/src/devices/stm32/delay.cpp index 3592bf0..6475b51 100644 --- a/src/devices/stm32/delay.cpp +++ b/src/devices/stm32/delay.cpp @@ -52,6 +52,7 @@ namespace sta // Calculate TIM clock frequency uint32_t clkFreq = pclkMul * STA_STM32_GET_HANDLE_PCLK_FREQ_FN(STA_STM32_DELAY_US_TIM)(); + // Calculate update frequency based on prescaler value uint32_t prescaler = (STA_STM32_DELAY_US_TIM.Init.Prescaler) ? STA_STM32_DELAY_US_TIM.Init.Prescaler : 1; uint32_t updateFreq = clkFreq / prescaler; @@ -66,10 +67,29 @@ namespace sta { // Check if the specified timer is usable for microsecond delays. STA_ASSERT(isValidDelayUsTIM()); - STA_ASSERT(us < 1000); - __HAL_TIM_SET_COUNTER(&STA_STM32_DELAY_US_TIM, 0); - while (__HAL_TIM_GET_COUNTER(&STA_STM32_DELAY_US_TIM) < us * gDelayUsMul); + // Use millisecond delays for us > 1000 and use microseconds delay for the remainder. + delayMs(us / 1000); + us = us % 1000; + + // __HAL_TIM_SET_COUNTER(&STA_STM32_DELAY_US_TIM, 0); + + uint32_t startTime = __HAL_TIM_GET_COUNTER(&STA_STM32_DELAY_US_TIM); + + // Check if an overflow is expected during the delay time. + if (startTime < __HAL_TIM_GET_AUTORELOAD(&STA_STM32_DELAY_US_TIM) - us * gDelayUsMul) + { + while (__HAL_TIM_GET_COUNTER(&STA_STM32_DELAY_US_TIM) < startTime + us * gDelayUsMul); + } + else + { + uint32_t overflowTime = __HAL_TIM_GET_AUTORELOAD(&STA_STM32_DELAY_US_TIM) - startTime; + // Wait until the overflow happens + while (__HAL_TIM_GET_COUNTER(&STA_STM32_DELAY_US_TIM) > startTime); + + // Wait the remaining time after the overflow. + while (__HAL_TIM_GET_COUNTER(&STA_STM32_DELAY_US_TIM) < us * gDelayUsMul - overflowTime); + } } } // namespace sta diff --git a/src/devices/stm32/init.cpp b/src/devices/stm32/init.cpp index 0f06016..dc07c79 100644 --- a/src/devices/stm32/init.cpp +++ b/src/devices/stm32/init.cpp @@ -23,6 +23,8 @@ namespace sta STA_ASSERT(isValidDelayUsTIM()); // Start timer base HAL_TIM_Base_Start(&STA_STM32_DELAY_US_TIM); +#else + #endif // STA_STM32_DELAY_US_TIM } } // namespace sta diff --git a/src/devices/stm32/time.cpp b/src/devices/stm32/time.cpp new file mode 100644 index 0000000..3cc7df5 --- /dev/null +++ b/src/devices/stm32/time.cpp @@ -0,0 +1,32 @@ +/* + * time.cpp + * + * Created on: May 22, 2024 + * Author: Dario + */ + +#include + +#include +#ifdef STA_PLATFORM_STM32 + +#include + +namespace sta +{ + uint32_t timeMs() + { + return HAL_GetTick(); + } + +#ifdef STA_STM32_DELAY_US_TIM + extern uint32_t gDelayUsMul; + + uint32_t timeUs() + { + return __HAL_TIM_GET_COUNTER(&STA_STM32_DELAY_US_TIM) / gDelayUsMul; + } +} +#endif // STA_STM32_DELAY_US_TIM + +#endif // STA_PLATFORM_STM32 diff --git a/src/time.cpp b/src/time.cpp new file mode 100644 index 0000000..eeeba78 --- /dev/null +++ b/src/time.cpp @@ -0,0 +1,26 @@ +/* + * time.cpp + * + * Created on: May 22, 2024 + * Author: Dario + */ + +#include +#include + +namespace sta +{ + STA_WEAK + uint32_t timeMs() + { + STA_NOT_IMPLEMENTED(); + } + + STA_WEAK + uint32_t timeUs() + { + STA_NOT_IMPLEMENTED(); + } +} // namespace sta + + From e186eb757ccdddad5ff612b2a9204422c9c5f1f6 Mon Sep 17 00:00:00 2001 From: dario Date: Fri, 24 May 2024 15:37:55 +0200 Subject: [PATCH 12/17] Added profiler implementation based on RAII. --- include/sta/debug/profile.hpp | 36 +++++++++++++++++++++++++++++++++++ src/debug/profile.cpp | 29 ++++++++++++++++++++++++++++ 2 files changed, 65 insertions(+) create mode 100644 include/sta/debug/profile.hpp create mode 100644 src/debug/profile.cpp diff --git a/include/sta/debug/profile.hpp b/include/sta/debug/profile.hpp new file mode 100644 index 0000000..051f7ef --- /dev/null +++ b/include/sta/debug/profile.hpp @@ -0,0 +1,36 @@ +/* + * profile.hpp + * + * Created on: May 22, 2024 + * Author: Dario + */ + +#ifndef STA_DEBUGGING_PROFILING_HPP +#define STA_DEBUGGING_PROFILING_HPP + +#include +#ifdef STA_DEBUGGING_ENABLED + +namespace sta +{ + class Profiler { + public: + Profiler(const char* name); + + ~Profiler(); + private: + const char* name_; + uint32_t start_; + }; +} // namespace sta + +/** + * + */ +#define STA_TIME_IT(name) sta::Profiler profiler(name); + +#endif // STA_DEBUGGING_ENABLED + +#define STA_TIME_IT(name) ((void)0) + +#endif // STA_DEBUGGING_PROFILING_HPP diff --git a/src/debug/profile.cpp b/src/debug/profile.cpp new file mode 100644 index 0000000..6e0c8de --- /dev/null +++ b/src/debug/profile.cpp @@ -0,0 +1,29 @@ +/* + * profiler.cpp + * + * Created on: May 22, 2024 + * Author: Dario + */ + +#include + +#ifdef STA_DEBUGGING_ENABLED + +#include + +namespace sta +{ + Profiler::Profiler(const char* name) + : name_{name}, + start_{timeUs()} + { + + } + + Profiler::~Profiler() + { + STA_DEBUG_PRINTF("[PROFILER] %s took %d us", name_, timeUs() - start_); + } +} // namespace sta + +#endif // STA_DEBUGGING_ENABLED From e5c4b9a6ccc61ccd647a5c0afb128c32b152f504 Mon Sep 17 00:00:00 2001 From: dario Date: Fri, 24 May 2024 16:27:53 +0200 Subject: [PATCH 13/17] RAII-style mutex --- include/sta/mutex.hpp | 17 +++++++++++++++++ src/mutex.cpp | 10 ++++++++++ 2 files changed, 27 insertions(+) diff --git a/include/sta/mutex.hpp b/include/sta/mutex.hpp index 1147f75..6dd2094 100644 --- a/include/sta/mutex.hpp +++ b/include/sta/mutex.hpp @@ -5,9 +5,16 @@ #ifndef STA_CORE_MUTEX_HPP #define STA_CORE_MUTEX_HPP +#include + namespace sta { + /** + * @brief Hippity hoppity, this is now namespace sta's property. + */ + using std::lock_guard; + /** * @brief Interface for mutex objects. * @@ -25,6 +32,16 @@ namespace sta */ virtual void release() = 0; + /** + * @brief Identical to acquire(). Added for compatibility with std::lock_guard. + */ + void lock(); + + /** + * @brief Identical to release(). Added for compatibility with std::lock_guard. + */ + void unlock(); + static Mutex * ALWAYS_FREE; /**< Fake mutex that can always be acquired */ }; } // namespace sta diff --git a/src/mutex.cpp b/src/mutex.cpp index 2472911..ea8438b 100644 --- a/src/mutex.cpp +++ b/src/mutex.cpp @@ -3,6 +3,16 @@ namespace sta { + void Mutex::lock() + { + acquire(); + } + + void Mutex::unlock() + { + release(); + } + /** * @brief Dummy mutex implementation with no access control. */ From 4b0e8bd4ab12c375f4184dba7ba356093daf4701 Mon Sep 17 00:00:00 2001 From: dario Date: Tue, 28 May 2024 12:06:09 +0200 Subject: [PATCH 14/17] Updated clock prescaler, tested profiler and delayUs --- include/sta/debug/assert.hpp | 19 ++---- include/sta/debug/profile.hpp | 15 +++- include/sta/devices/stm32/clocks.hpp | 68 +++++++++++++++---- include/sta/devices/stm32/mcu/STM32F411xE.hpp | 5 ++ src/devices/stm32/delay.cpp | 31 +++------ src/devices/stm32/time.cpp | 1 + src/time.cpp | 4 ++ 7 files changed, 91 insertions(+), 52 deletions(-) diff --git a/include/sta/debug/assert.hpp b/include/sta/debug/assert.hpp index f6e82a9..bd02810 100644 --- a/include/sta/debug/assert.hpp +++ b/include/sta/debug/assert.hpp @@ -3,9 +3,8 @@ * @brief Assertion handling. * * Configuration: - * * STA_ASSERT_FORCE: Ignore debug defines and always enable assertions - * * DEBUG: Enables assertions when defined - * * NDEBUG: Disables assertions when defined (overrides DEBUG) + * * STA_ASSERT_ENABLED: Enable assertions + * * STA_ASSERT_FORCE: Enable assertions. Still there for backwards compatibility. */ #ifndef STA_CORE_ASSERT_HPP #define STA_CORE_ASSERT_HPP @@ -24,18 +23,10 @@ #include -// Determine if module should be enabled -// Condition: -// STA_ASSERT_FORCE is defined -// or -// DEBUG is defined but not NDEBUG +// Keep STA_ASSERT_FORCE for backwards comapatibility. #ifdef STA_ASSERT_FORCE -# define STA_ASSERT_ENABLED -#else // !STA_ASSERT_FORCE -# if defined(DEBUG) && !defined(NDEBUG) -# define STA_ASSERT_ENABLED -# endif // DEBUG && !NDEBUG -#endif // !STA_ASSERT_FORCE +# define STA_ASSERT_ENABLED +#endif // STA_ASSERT_FORCE #if defined(STA_ASSERT_ENABLED) || defined(DOXYGEN) diff --git a/include/sta/debug/profile.hpp b/include/sta/debug/profile.hpp index 051f7ef..f256ac5 100644 --- a/include/sta/debug/profile.hpp +++ b/include/sta/debug/profile.hpp @@ -9,7 +9,16 @@ #define STA_DEBUGGING_PROFILING_HPP #include -#ifdef STA_DEBUGGING_ENABLED + +#ifdef STA_PROFILING_ENABLED + +#ifndef STA_DEBUGGING_ENABLED +# error "Debugging has to be enabled in order to use profiling." +#endif // STA_DEBUGGING_ENABLED + +#ifndef STA_STM32_DELAY_US_TIM +# error "A microsecond timer has to be defined in order to use profiling." +#endif // STA_STM32_DELAY_US_TIM namespace sta { @@ -29,8 +38,10 @@ namespace sta */ #define STA_TIME_IT(name) sta::Profiler profiler(name); -#endif // STA_DEBUGGING_ENABLED +#else #define STA_TIME_IT(name) ((void)0) +#endif // // STA_PROFILING_ENABLED + #endif // STA_DEBUGGING_PROFILING_HPP diff --git a/include/sta/devices/stm32/clocks.hpp b/include/sta/devices/stm32/clocks.hpp index cd2ac38..bb1be59 100644 --- a/include/sta/devices/stm32/clocks.hpp +++ b/include/sta/devices/stm32/clocks.hpp @@ -39,7 +39,7 @@ namespace sta * * @param n Index of peripheral clock */ -#define STA_STM32_GET_PCLK_FREQ_FN(n) HAL_RCC_GetPCLK ## n ## Freq +#define STA_STM32_GET_PCLK_FREQ_FN(n) HAL_RCC_GetPCLK ## n ## Freq /** * @brief Internal helper for macro expansion. @@ -47,7 +47,31 @@ namespace sta * @param n PCLK index * @return Function returning PCLK frequency */ -#define _STA_STM32_GET_PCLK_FREQ_FN(n) STA_STM32_GET_PCLK_FREQ_FN(n) +#define _STA_STM32_GET_PCLK_FREQ_FN(n) STA_STM32_GET_PCLK_FREQ_FN(n) + +/** + * @brief Get the PCLK frequency. + * + * @param n PCLK index + * @return The PCLK frequency + */ +#define _STA_STM32_GET_PCLK_FREQ(n) STA_STM32_GET_PCLK_FREQ_FN(n)() + +/** + * @brief Gets the prescaler from APBx to APBx timer clocks. + * + * @param n PCLK index + * @return The prescaler from PCLK to TIM + */ +#define STA_STM32_GET_PCLK_TIM_PRESCALER(n) STA_STM32_TIM_PCLK_ ## n ## ## _PRESCALER + +/** + * @brief Internal helper for macro expansion. + * + * @param n PCLK index + * @return Function returning PCLK frequency + */ +#define _STA_STM32_GET_PCLK_TIM_PRESCALER(n) STA_STM32_GET_PCLK_TIM_PRESCALER(n) /** * @brief Map instance name to PCLK index. @@ -56,7 +80,7 @@ namespace sta * @param idx Instance index * @return PCLK index */ -#define _STA_STM32_PCLK_IDX_MAP(type, idx) STA_STM32_ ## type ## _ ## idx ## _PCLK_IDX +#define _STA_STM32_PCLK_IDX_MAP(type, idx) STA_STM32_ ## type ## _ ## idx ## _PCLK_IDX // Get HAL handle to PCLK index map macro /** @@ -65,44 +89,58 @@ namespace sta * @param handle HAL handle * @return PCLK index */ -#define _STA_STM32_HANDLE_PCLK_IDX_MAP(handle) STA_STM32_ ## handle ## _PCLK_IDX - +#define _STA_STM32_HANDLE_PCLK_IDX_MAP(handle) STA_STM32_ ## handle ## _PCLK_IDX /** - * @brief Get function returning frequency of PCLK used by TIM. + * @brief Get a function returning the frequency of PCLK used by TIM. * * @param n TIM index */ -#define STA_STM32_GET_TIM_PCLK_FREQ_FN(n) _STA_STM32_GET_PCLK_FREQ_FN(_STA_STM32_PCLK_IDX_MAP(TIM, n)) +#define STA_STM32_GET_TIM_PCLK_FREQ_FN(n) _STA_STM32_GET_PCLK_FREQ_FN(_STA_STM32_PCLK_IDX_MAP(TIM, n)) /** - * @brief Get function returning frequency of PCLK used by SPI interface. + * @brief Internal helper for macro expansion. + * + * @param n TIM index + */ +#define _STA_STM32_GET_TIM_PCLK_FREQ_FN(n) STA_STM32_GET_TIM_PCLK_FREQ_FN(n) + +/** + * @brief Get a function returning the frequency of PCLK used by SPI interface. * * @param n SPI interface index */ -#define STA_STM32_GET_SPI_PCLK_FREQ_FN(n) _STA_STM32_GET_PCLK_FREQ_FN(_STA_STM32_PCLK_IDX_MAP(SPI, n)) +#define STA_STM32_GET_SPI_PCLK_FREQ_FN(n) _STA_STM32_GET_PCLK_FREQ_FN(_STA_STM32_PCLK_IDX_MAP(SPI, n)) /** - * @brief Get function returning frequency of PCLK used by I2C interface. + * @brief Get a function returning the frequency of PCLK used by I2C interface. * * @param n I2C interface index */ -#define STA_STM32_GET_I2C_PCLK_FREQ_FN(n) _STA_STM32_GET_PCLK_FREQ_FN(_STA_STM32_PCLK_IDX_MAP(I2C, n)) +#define STA_STM32_GET_I2C_PCLK_FREQ_FN(n) _STA_STM32_GET_PCLK_FREQ_FN(_STA_STM32_PCLK_IDX_MAP(I2C, n)) /** - * @brief Get function returning frequency of PCLK used by USART interface. + * @brief Get a function returning the frequency of PCLK used by USART interface. * * @param n USART interface index */ -#define STA_STM32_GET_USART_PCLK_FREQ_FN(n) _STA_STM32_GET_PCLK_FREQ_FN(_STA_STM32_PCLK_IDX_MAP(USART, n)) +#define STA_STM32_GET_USART_PCLK_FREQ_FN(n) _STA_STM32_GET_PCLK_FREQ_FN(_STA_STM32_PCLK_IDX_MAP(USART, n)) /** - * @brief Get function returning frequency of PCLK used by HAL instance. + * @brief Get a function returning the frequency of PCLK used by HAL instance. * * @param handle Instance handle */ -#define STA_STM32_GET_HANDLE_PCLK_FREQ_FN(handle) _STA_STM32_GET_PCLK_FREQ_FN(_STA_STM32_HANDLE_PCLK_IDX_MAP(handle)) +#define STA_STM32_GET_HANDLE_PCLK_FREQ_FN(handle) _STA_STM32_GET_PCLK_FREQ_FN(_STA_STM32_HANDLE_PCLK_IDX_MAP(handle)) + +/** + * @brief Get the PCLK to timer prescaler for TIM given by the handle. + * + * @param handle TIM handle + * @return PCLK-TIM prescaler + */ +#define STA_STM32_GET_HANDLE_PCLK_TIM_PRESCALER(handle) _STA_STM32_GET_PCLK_TIM_PRESCALER(_STA_STM32_HANDLE_PCLK_IDX_MAP(handle)) /** @} */ diff --git a/include/sta/devices/stm32/mcu/STM32F411xE.hpp b/include/sta/devices/stm32/mcu/STM32F411xE.hpp index ee91c61..56608f5 100644 --- a/include/sta/devices/stm32/mcu/STM32F411xE.hpp +++ b/include/sta/devices/stm32/mcu/STM32F411xE.hpp @@ -63,8 +63,13 @@ #define STA_STM32_USART_2_PCLK_IDX 1 /**< USART2 to PCLK index 1 */ #define STA_STM32_USART_6_PCLK_IDX 2 /**< USART6 to PCLK index 2 */ +// prescaler from APBx to APBx timer clocks +#define STA_STM32_TIM_PCLK_1_PRESCALER 2 /**< PCLK1 has prescaler of 2 */ +#define STA_STM32_TIM_PCLK_2_PRESCALER 1 /**< PCLK2 has prescaler of 1 */ + // HAL handle mappings +// // TIM to PCLK #define STA_STM32_htim1_PCLK_IDX STA_STM32_TIM_1_PCLK_IDX /**< HAL TIM1 to PCLK index */ diff --git a/src/devices/stm32/delay.cpp b/src/devices/stm32/delay.cpp index 6475b51..3e754d5 100644 --- a/src/devices/stm32/delay.cpp +++ b/src/devices/stm32/delay.cpp @@ -51,7 +51,7 @@ namespace sta } // Calculate TIM clock frequency - uint32_t clkFreq = pclkMul * STA_STM32_GET_HANDLE_PCLK_FREQ_FN(STA_STM32_DELAY_US_TIM)(); + uint32_t clkFreq = pclkMul * STA_STM32_GET_HANDLE_PCLK_FREQ_FN(STA_STM32_DELAY_US_TIM)() * STA_STM32_GET_HANDLE_PCLK_TIM_PRESCALER(STA_STM32_DELAY_US_TIM); // Calculate update frequency based on prescaler value uint32_t prescaler = (STA_STM32_DELAY_US_TIM.Init.Prescaler) ? STA_STM32_DELAY_US_TIM.Init.Prescaler : 1; @@ -68,33 +68,22 @@ namespace sta // Check if the specified timer is usable for microsecond delays. STA_ASSERT(isValidDelayUsTIM()); - // Use millisecond delays for us > 1000 and use microseconds delay for the remainder. - delayMs(us / 1000); - us = us % 1000; + // Save the current value of the counter. + uint32_t current = __HAL_TIM_GET_COUNTER(&STA_STM32_DELAY_US_TIM); - // __HAL_TIM_SET_COUNTER(&STA_STM32_DELAY_US_TIM, 0); + // Set the timer counter to zero to avoid overflows during delay- + __HAL_TIM_SET_COUNTER(&STA_STM32_DELAY_US_TIM, 0); - uint32_t startTime = __HAL_TIM_GET_COUNTER(&STA_STM32_DELAY_US_TIM); + // Wait for the desired microseconds. + while (__HAL_TIM_GET_COUNTER(&STA_STM32_DELAY_US_TIM) < us * gDelayUsMul); - // Check if an overflow is expected during the delay time. - if (startTime < __HAL_TIM_GET_AUTORELOAD(&STA_STM32_DELAY_US_TIM) - us * gDelayUsMul) - { - while (__HAL_TIM_GET_COUNTER(&STA_STM32_DELAY_US_TIM) < startTime + us * gDelayUsMul); - } - else - { - uint32_t overflowTime = __HAL_TIM_GET_AUTORELOAD(&STA_STM32_DELAY_US_TIM) - startTime; - // Wait until the overflow happens - while (__HAL_TIM_GET_COUNTER(&STA_STM32_DELAY_US_TIM) > startTime); - - // Wait the remaining time after the overflow. - while (__HAL_TIM_GET_COUNTER(&STA_STM32_DELAY_US_TIM) < us * gDelayUsMul - overflowTime); - } + // Set the timer counter to the previous value and add the waited duration to it. + // This avoids collisions with code relying on timeUs measurements. + __HAL_TIM_SET_COUNTER(&STA_STM32_DELAY_US_TIM, current + us * gDelayUsMul); } } // namespace sta #endif // STA_STM32_DELAY_US_TIM - #endif // STA_PLATFORM_STM32 diff --git a/src/devices/stm32/time.cpp b/src/devices/stm32/time.cpp index 3cc7df5..97d5a1c 100644 --- a/src/devices/stm32/time.cpp +++ b/src/devices/stm32/time.cpp @@ -11,6 +11,7 @@ #ifdef STA_PLATFORM_STM32 #include +#include namespace sta { diff --git a/src/time.cpp b/src/time.cpp index eeeba78..6e00ccf 100644 --- a/src/time.cpp +++ b/src/time.cpp @@ -14,12 +14,16 @@ namespace sta uint32_t timeMs() { STA_NOT_IMPLEMENTED(); + + return 0; } STA_WEAK uint32_t timeUs() { STA_NOT_IMPLEMENTED(); + + return 0; } } // namespace sta From 0e5addfe9d61aaac28a94803d709009963f2a92b Mon Sep 17 00:00:00 2001 From: dario Date: Tue, 28 May 2024 12:08:23 +0200 Subject: [PATCH 15/17] Removed warning for us timers --- README.md | 1 - 1 file changed, 1 deletion(-) diff --git a/README.md b/README.md index 0cc739d..f36ca0e 100644 --- a/README.md +++ b/README.md @@ -89,7 +89,6 @@ Steps to enable delayUs: * Include sta/devices/stm32/delay.hpp in the file where the delayUs function is called * Enable a timer TIM in .ioc file with the settings: Slave Mode=Disable, Trigger Mode=Disable, Clock Source=Internal Clock, all other channels =Disable) * Define STA_STM32_DELAY_US_TIM in App/Inc/sta/config.hpp as the timer handle (can be found in Core/Inc/tim.h). For TIM1, this would be htim1 -* Do not use this timer for delays of over 1000 us; we have delayMs for that From ad2be63cbe5a8bc57b0f0c58c2cfd69963314ce9 Mon Sep 17 00:00:00 2001 From: dario Date: Tue, 28 May 2024 12:31:33 +0200 Subject: [PATCH 16/17] Updated config for F407 and fixed profiler error --- include/sta/devices/stm32/mcu/STM32F407xx.hpp | 5 +++++ src/debug/profile.cpp | 4 ++-- 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/include/sta/devices/stm32/mcu/STM32F407xx.hpp b/include/sta/devices/stm32/mcu/STM32F407xx.hpp index f390ad0..3a3b61d 100644 --- a/include/sta/devices/stm32/mcu/STM32F407xx.hpp +++ b/include/sta/devices/stm32/mcu/STM32F407xx.hpp @@ -64,6 +64,11 @@ #define STA_STM32_USART_3_PCLK_IDX 1 /**< USART3 to PCLK index */ #define STA_STM32_USART_6_PCLK_IDX 2 /**< USART6 to PCLK index */ +// prescaler from APBx to APBx timer clocks +#define STA_STM32_TIM_PCLK_1_PRESCALER 2 /**< PCLK1 has prescaler of 2 */ +#define STA_STM32_TIM_PCLK_2_PRESCALER 2 /**< PCLK2 has prescaler of 1 */ + + // HAL handle mappings // diff --git a/src/debug/profile.cpp b/src/debug/profile.cpp index 6e0c8de..4e7eec6 100644 --- a/src/debug/profile.cpp +++ b/src/debug/profile.cpp @@ -7,7 +7,7 @@ #include -#ifdef STA_DEBUGGING_ENABLED +#ifdef STA_PROFILING_ENABLED #include @@ -26,4 +26,4 @@ namespace sta } } // namespace sta -#endif // STA_DEBUGGING_ENABLED +#endif // STA_PROFILING_ENABLED From 5c7834990903ba7bdbf9cfc21492693f524b9480 Mon Sep 17 00:00:00 2001 From: "@CarlWachter" Date: Sat, 1 Jun 2024 16:50:42 +0200 Subject: [PATCH 17/17] Fix: Compiling without STA_STM32_DELAY_US_TIM --- src/devices/stm32/time.cpp | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/devices/stm32/time.cpp b/src/devices/stm32/time.cpp index 97d5a1c..11e2f45 100644 --- a/src/devices/stm32/time.cpp +++ b/src/devices/stm32/time.cpp @@ -27,7 +27,6 @@ namespace sta { return __HAL_TIM_GET_COUNTER(&STA_STM32_DELAY_US_TIM) / gDelayUsMul; } -} #endif // STA_STM32_DELAY_US_TIM - +} #endif // STA_PLATFORM_STM32