From 6de22f6d4abd2f2f1b31df4434ee6067396ed0bd Mon Sep 17 00:00:00 2001 From: Naichen Zhao Date: Tue, 7 Nov 2023 12:38:02 -0800 Subject: [PATCH 01/38] initial test for support for STM32 --- core/platform/CMakeLists.txt | 3 + core/platform/Platform.cmake | 2 + core/platform/lf_STM32f4_support.c | 262 +++++++++++++++++++++ include/core/platform.h | 2 + include/core/platform/lf_STM32f4_support.h | 27 +++ 5 files changed, 296 insertions(+) create mode 100644 core/platform/lf_STM32f4_support.c create mode 100644 include/core/platform/lf_STM32f4_support.h diff --git a/core/platform/CMakeLists.txt b/core/platform/CMakeLists.txt index 8ee47a9b5..1e3005d18 100644 --- a/core/platform/CMakeLists.txt +++ b/core/platform/CMakeLists.txt @@ -12,6 +12,7 @@ lf_zephyr_support.c lf_zephyr_clock_counter.c lf_zephyr_clock_kernel.c lf_rp2040_support.c +lf_STM32f4_support.c ) if(${CMAKE_SYSTEM_NAME} STREQUAL "Windows") @@ -21,6 +22,8 @@ elseif(${CMAKE_SYSTEM_NAME} STREQUAL "Nrf52") target_compile_definitions(core PUBLIC PLATFORM_NRF52) elseif(${CMAKE_SYSTEM_NAME} STREQUAL "Zephyr") target_compile_definitions(core PUBLIC PLATFORM_ZEPHYR) +elseif(${CMAKE_SYSTEM_NAME} STREQUAL "STM32f4") + target_compile_definitions(core PUBLIC PLATFORM_STM32F4) elseif(${CMAKE_SYSTEM_NAME} STREQUAL "Rp2040") target_compile_definitions(core PUBLIC PLATFORM_RP2040) endif() diff --git a/core/platform/Platform.cmake b/core/platform/Platform.cmake index cc6042c7c..10797a1c5 100644 --- a/core/platform/Platform.cmake +++ b/core/platform/Platform.cmake @@ -10,6 +10,8 @@ elseif(${CMAKE_SYSTEM_NAME} STREQUAL "Windows") message("Using Windows SDK version ${CMAKE_VS_WINDOWS_TARGET_PLATFORM_VERSION}") elseif(${CMAKE_SYSTEM_NAME} STREQUAL "Zephyr") set(LF_PLATFORM_FILE lf_zephyr_support.c) +elseif(${CMAKE_SYSTEM_NAME} STREQUAL "STM32f4") + set(LF_PLATFORM_FILE lf_STM32f4_support.c) elseif(${CMAKE_SYSTEM_NAME} STREQUAL "Rp2040") message("Using pico-sdk for RP2040 target") set(LF_PLATFORM_FILE lf_rp2040_support.c) diff --git a/core/platform/lf_STM32f4_support.c b/core/platform/lf_STM32f4_support.c new file mode 100644 index 000000000..4223244d8 --- /dev/null +++ b/core/platform/lf_STM32f4_support.c @@ -0,0 +1,262 @@ +#ifdef defined(PLATFORM_STM32F4) +/************* + I hope this software works LOL + ***************/ + +#include "lf_STM32f4_support.h" +#include "platform.h" +#include "utils/util.h" +#include "tag.h" + +// + -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- + +// | Important defines and global variables +// + -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- + + +static volatile bool _lf_sleep_interrupted = false; +static volatile bool _lf_async_event = false; + +#define LF_MAX_SLEEP_NS USEC(UINT32_MAX) +#define LF_MIN_SLEEP_NS USEC(5) + +// nested critical section counter +static uint32_t _lf_num_nested_crit_sec = 0; + +// Timer upper half (for overflow) +static uint32_t _lf_time_us_high = 0; + +// Combine 2 32bit works to a 64 bit word (Takes from nrf52 support) +#define COMBINE_HI_LO(hi, lo) ((((uint64_t)hi) << 32) | ((uint64_t)lo)) + + + + + +// + -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- + +// | Code for timer functions +// + -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- + + +// We use timer 5 for our clock (probably better than fucking with sysTick) +void _lf_initialize_clock(void) { + // Standard initializations from generated code + // HAL_Init(); + // SystemClock_Config(); + + // Configure TIM5 as our 32-bit clock timer + __HAL_RCC_TIM5_CLK_ENABLE(); // initialize counter + TIM5->CR1 = TIM_CR1_CEN; // enable counter + + // set prescaler to (16 - 1) = 15 + // CPU runs a 16MHz so timer ticks at 1MHz + // Which means period of 1 microsecond + TIM5->PSC = 15; + + // Setup ISR to increment upper bits + TIM5->DIER |= TIM_DIER_CC1IE; + NVIC_EnableIRQ(TIM5_IRQn); + + /* This is to make the Prescaler actually work + * For some reason, the Prescaler only kicks in once the timer has reset once. + * Thus, the current solution is to manually ret the value to a really large + * and force it to reset once. Its really jank but its the only way I could + * find to make it work + */ + TIM5->CNT = 0xFFFFFFFE; +} + +/** + * ISR for handling timer overflow -> We increment the upper timer + */ +void TIM5_IRQHandler(void){ + if (TIM5->SR & (1 << 1)) { + TIM5->SR &= ~(1 << 1); + _lf_time_us_high += 1; + } +} + +/** + * Write the time since boot into time variable + */ +int _lf_clock_now(instant_t *t){ + // Timer is cooked + if (!t) { + return -1; + } + // Get the current microseconds from TIM5 + uint32_t _lf_time_us_low = TIM5->CNT; + + // Combine upper and lower timers (Yoinked from lf_nrf52 support) + uint64_t now_us = COMBINE_HI_LO((_lf_time_us_high-1), _lf_time_us_low); + *t = ((instant_t)now_us) * 1000; + return 0; +} + +/** + * Make the STM32 go honk shoo mimimi for set nanoseconds + * I essentially stole this from the lf_nrf52 support + */ +int lf_sleep(interval_t sleep_duration){ + instant_t target_time; + instant_t current_time; + + _lf_clock_now(¤t_time); + target_time = current_time + sleep_duration; + while (current_time <= target_time) + _lf_clock_now(¤t_time); + + return 0; +} + +/** + * Make the STM32 go honk shoo honk shoo for set nanoseconds + * This one uses a do-while loop. :) + * I essentially stole this from the lf_nrf52 support + */ +static void lf_busy_wait_until(instant_t wakeup_time) { + instant_t now; + do { + _lf_clock_now(&now); + } while (now < wakeup_time); +} + +// I am pretty sure this function doesnt work +// Ill try to fix it once i know what the fuck its supposed to do, LOL +int _lf_interruptable_sleep_until_locked(environment_t *env, instant_t wakeup_time) { + // // Get the current time and sleep time + // instant_t now; + // _lf_clock_now(&now); + // interval_t duration = wakeup_time - now; + + // // Edge case handling for super small duration + // if (duration <= 0) { + // return 0; + // } else if (duration < 10) { + // lf_busy_wait_until(wakeup_time); + // return 0; + // } + + // // Enable interrupts and prepare to wait + // _lf_async_event = false; + // instant_t curr; + // lf_enable_interrupts_nested(); + + // do { + // _lf_clock_now(&curr); + + // // Exit wither when the timer is up or there is an exception + // } while (!_lf_async_event && (now < wakeup_time)); + + // // Disable interrupts again on exit + // lf_disable_interrupts_nested(); + + // if (!_lf_async_event) { + // return 0; + // } else { + // LF_PRINT_DEBUG(" *The STM32 rises from sleep* \n"); + // return -1; + // } + + instant_t now; + do { + _lf_clock_now(&now); + } while (now < wakeup_time); + return 0; +} + + + + + +// + -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- + +// | Code for enabling and disabling Interrupts +// + -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- + + +// disables the IRQ (checks if its already disabled) +int lf_disable_interrupts_nested() { + // Disable interrupts if they are currently enabled + if (_lf_num_nested_crit_sec == 0) { + __disable_irq(); + } + + // update the depth of disabling interrupts + _lf_num_nested_crit_sec++; + return 0; +} + +// enables the IRQ (checks if other programs still want it disabled first) +int lf_enable_interrupts_nested() { + // Somebody fucked up, LOL + if (_lf_num_nested_crit_sec <= 0) { + return 1; + } + + // update the depth of disabling interrupts + _lf_num_nested_crit_sec--; + + // If we have exited all important programs, we can enable them again + if (_lf_num_nested_crit_sec == 0) { + __enable_irq(); + } + return 0; +} + +int _lf_unthreaded_notify_of_event() { + _lf_async_event = true; + return 0; +} + +int test_func(void){ + return 5; +} + +// + -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- + +// | Other functions I found -> taken from the generated main.c +// + -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- + + +// void SystemClock_Config(void) { +// RCC_OscInitTypeDef RCC_OscInitStruct = {0}; +// RCC_ClkInitTypeDef RCC_ClkInitStruct = {0}; + +// /** Configure the main internal regulator output voltage +// */ +// __HAL_RCC_PWR_CLK_ENABLE(); +// __HAL_PWR_VOLTAGESCALING_CONFIG(PWR_REGULATOR_VOLTAGE_SCALE3); + +// /** Initializes the RCC Oscillators according to the specified parameters +// * in the RCC_OscInitTypeDef structure. +// */ +// RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSI; +// RCC_OscInitStruct.HSIState = RCC_HSI_ON; +// RCC_OscInitStruct.HSICalibrationValue = RCC_HSICALIBRATION_DEFAULT; +// RCC_OscInitStruct.PLL.PLLState = RCC_PLL_NONE; +// if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK) +// { +// Error_Handler(); +// } + +// /** Initializes the CPU, AHB and APB buses clocks +// */ +// RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK | RCC_CLOCKTYPE_SYSCLK | RCC_CLOCKTYPE_PCLK1 | RCC_CLOCKTYPE_PCLK2; +// RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_HSI; +// RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1; +// RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV1; +// RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1; + +// if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_0) != HAL_OK) +// { +// Error_Handler(); +// } +// } + + +// void Error_Handler(void) +// { +// /* USER CODE BEGIN Error_Handler_Debug */ +// /* User can add his own implementation to report the HAL error return state */ +// __disable_irq(); +// while (1) +// { +// } +// /* USER CODE END Error_Handler_Debug */ +// } + +#endif \ No newline at end of file diff --git a/include/core/platform.h b/include/core/platform.h index a32cfb516..e615a0f0a 100644 --- a/include/core/platform.h +++ b/include/core/platform.h @@ -74,6 +74,8 @@ int lf_critical_section_exit(environment_t* env); #include "platform/lf_zephyr_support.h" #elif defined(PLATFORM_NRF52) #include "platform/lf_nrf52_support.h" +#elif defined(PLATFORM_STM32F4) + #include "platform/lf_STM32f4_support.h" #elif defined(PLATFORM_RP2040) #include "platform/lf_rp2040_support.h" #elif defined(WIN32) || defined(_WIN32) || defined(__WIN32__) || defined(__NT__) diff --git a/include/core/platform/lf_STM32f4_support.h b/include/core/platform/lf_STM32f4_support.h new file mode 100644 index 000000000..7a8414576 --- /dev/null +++ b/include/core/platform/lf_STM32f4_support.h @@ -0,0 +1,27 @@ +/* STM32 API support for the C target of Lingua Franca. */ + +#ifndef LF_STM32F4_SUPPORT_H +#define LF_STM32F4_SUPPORT_H + +// I have no idea what the fuck TTY is so i guess we dont support it +#define NO_TTY + +// #include <../../../STM_Core/Inc/main.h> +// #include <../../../Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal.h> +#include + +// src-gen/Main/Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal.h + +// Defines for formatting time in printf for pico +#define PRINTF_TAG "(" PRINTF_TIME ", " PRINTF_MICROSTEP ")" +#define PRINTF_TIME "%lld" +#define PRINTF_MICROSTEP "%d" + +#define LF_TIME_BUFFER_LENGTH 80 +#define _LF_TIMEOUT 1 + +#ifdef LF_THREADED +#error "I have no idea how to support threading" +#endif // LF_THREADED + +#endif \ No newline at end of file From 256abcc50d79db57740d53c89e0f0933ad8772a7 Mon Sep 17 00:00:00 2001 From: Marten Lohstroh Date: Tue, 7 Nov 2023 14:11:49 -0800 Subject: [PATCH 02/38] Point to lingua-franca stm32 branch --- lingua-franca-ref.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lingua-franca-ref.txt b/lingua-franca-ref.txt index c8ed1b5d2..cb258ba1f 100644 --- a/lingua-franca-ref.txt +++ b/lingua-franca-ref.txt @@ -1 +1 @@ -decentralized-small-delay-bugfix +stm32 From 92fcfbe16f02c2fc2ae094fb9b30c36ed8217406 Mon Sep 17 00:00:00 2001 From: Naichen Zhao Date: Fri, 10 Nov 2023 18:41:26 -0800 Subject: [PATCH 03/38] fixed typo --- core/platform/lf_STM32f4_support.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core/platform/lf_STM32f4_support.c b/core/platform/lf_STM32f4_support.c index 4223244d8..e9aa852b7 100644 --- a/core/platform/lf_STM32f4_support.c +++ b/core/platform/lf_STM32f4_support.c @@ -1,4 +1,4 @@ -#ifdef defined(PLATFORM_STM32F4) +#if defined(PLATFORM_STM32F4) /************* I hope this software works LOL ***************/ From 89986a99ad0289b88f1a0a5064b56e46614cf8f1 Mon Sep 17 00:00:00 2001 From: Naichen Zhao Date: Sat, 11 Nov 2023 13:57:17 -0800 Subject: [PATCH 04/38] hard coded STM32 support --- core/CMakeLists.txt | 46 ++++++++++++++++++++++ core/platform/CMakeLists.txt | 2 +- core/platform/Platform.cmake | 2 +- include/core/platform/lf_STM32f4_support.h | 4 -- 4 files changed, 48 insertions(+), 6 deletions(-) diff --git a/core/CMakeLists.txt b/core/CMakeLists.txt index 16bf0e616..e7006164a 100644 --- a/core/CMakeLists.txt +++ b/core/CMakeLists.txt @@ -123,3 +123,49 @@ define(SCHEDULER) define(LF_SOURCE_DIRECTORY) define(LF_PACKAGE_DIRECTORY) define(LF_FILE_SEPARATOR) + + + +# ========================================================== +# Stuff I added +# ========================================================== + +if(${CMAKE_SYSTEM_NAME} MATCHES "Stm32") + set(CPU_PARAMETERS + -mcpu=cortex-m4 + -mthumb + -mfpu=fpv4-sp-d16 + -mfloat-abi=softfp ) + + set(MCU_FAMILY STM32F4xx ) + set(MCU_MODEL STM32F446xx ) + + target_compile_definitions(core PRIVATE + ${MCU_MODEL} + USE_HAL_DRIVER ) + + target_compile_options(core PRIVATE + ${CPU_PARAMETERS} + -Wall + -Wextra + -Wpedantic + -Wno-unused-parameter + $<$: + -Wno-volatile + -Wold-style-cast + -Wuseless-cast + -Wsuggest-override> + $<$:-Og -g3 -ggdb> + $<$:-Og -g0> ) + + set(CUBEMX_INCLUDE_DIRECTORIES + ../STM_sdk/Core/Inc + ../STM_sdk/Drivers/${MCU_FAMILY}_HAL_Driver/Inc + ../STM_sdk/Drivers/${MCU_FAMILY}_HAL_Driver/Inc/Legacy + ../STM_sdk/Drivers/CMSIS/Device/ST/${MCU_FAMILY}/Include + ../STM_sdk/Drivers/CMSIS/Include ) + + target_include_directories(core PUBLIC + ${CUBEMX_INCLUDE_DIRECTORIES} ) +endif() +# ========================================================== \ No newline at end of file diff --git a/core/platform/CMakeLists.txt b/core/platform/CMakeLists.txt index 1e3005d18..949d65177 100644 --- a/core/platform/CMakeLists.txt +++ b/core/platform/CMakeLists.txt @@ -22,7 +22,7 @@ elseif(${CMAKE_SYSTEM_NAME} STREQUAL "Nrf52") target_compile_definitions(core PUBLIC PLATFORM_NRF52) elseif(${CMAKE_SYSTEM_NAME} STREQUAL "Zephyr") target_compile_definitions(core PUBLIC PLATFORM_ZEPHYR) -elseif(${CMAKE_SYSTEM_NAME} STREQUAL "STM32f4") +elseif(${CMAKE_SYSTEM_NAME} STREQUAL "Stm32") target_compile_definitions(core PUBLIC PLATFORM_STM32F4) elseif(${CMAKE_SYSTEM_NAME} STREQUAL "Rp2040") target_compile_definitions(core PUBLIC PLATFORM_RP2040) diff --git a/core/platform/Platform.cmake b/core/platform/Platform.cmake index 10797a1c5..2d082bce6 100644 --- a/core/platform/Platform.cmake +++ b/core/platform/Platform.cmake @@ -10,7 +10,7 @@ elseif(${CMAKE_SYSTEM_NAME} STREQUAL "Windows") message("Using Windows SDK version ${CMAKE_VS_WINDOWS_TARGET_PLATFORM_VERSION}") elseif(${CMAKE_SYSTEM_NAME} STREQUAL "Zephyr") set(LF_PLATFORM_FILE lf_zephyr_support.c) -elseif(${CMAKE_SYSTEM_NAME} STREQUAL "STM32f4") +elseif(${CMAKE_SYSTEM_NAME} STREQUAL "Stm32") set(LF_PLATFORM_FILE lf_STM32f4_support.c) elseif(${CMAKE_SYSTEM_NAME} STREQUAL "Rp2040") message("Using pico-sdk for RP2040 target") diff --git a/include/core/platform/lf_STM32f4_support.h b/include/core/platform/lf_STM32f4_support.h index 7a8414576..063421d6d 100644 --- a/include/core/platform/lf_STM32f4_support.h +++ b/include/core/platform/lf_STM32f4_support.h @@ -6,12 +6,8 @@ // I have no idea what the fuck TTY is so i guess we dont support it #define NO_TTY -// #include <../../../STM_Core/Inc/main.h> -// #include <../../../Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal.h> #include -// src-gen/Main/Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal.h - // Defines for formatting time in printf for pico #define PRINTF_TAG "(" PRINTF_TIME ", " PRINTF_MICROSTEP ")" #define PRINTF_TIME "%lld" From 436b36bda45b7f14bbcbb34caea9688a97bde1cf Mon Sep 17 00:00:00 2001 From: Naichen Zhao Date: Sun, 19 Nov 2023 01:24:16 -0800 Subject: [PATCH 05/38] we dont need STM_main anymore --- core/platform/lf_STM32f4_support.c | 129 +++++++++++++---------------- 1 file changed, 59 insertions(+), 70 deletions(-) diff --git a/core/platform/lf_STM32f4_support.c b/core/platform/lf_STM32f4_support.c index e9aa852b7..dcd944113 100644 --- a/core/platform/lf_STM32f4_support.c +++ b/core/platform/lf_STM32f4_support.c @@ -29,8 +29,6 @@ static uint32_t _lf_time_us_high = 0; - - // + -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- + // | Code for timer functions // + -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- + @@ -38,35 +36,35 @@ static uint32_t _lf_time_us_high = 0; // We use timer 5 for our clock (probably better than fucking with sysTick) void _lf_initialize_clock(void) { // Standard initializations from generated code - // HAL_Init(); - // SystemClock_Config(); + HAL_Init(); + SystemClock_Config(); // Configure TIM5 as our 32-bit clock timer __HAL_RCC_TIM5_CLK_ENABLE(); // initialize counter - TIM5->CR1 = TIM_CR1_CEN; // enable counter + TIM5->CR1 = TIM_CR1_CEN; // enable counter // set prescaler to (16 - 1) = 15 // CPU runs a 16MHz so timer ticks at 1MHz // Which means period of 1 microsecond - TIM5->PSC = 15; + TIM5->PSC = 15; // Setup ISR to increment upper bits TIM5->DIER |= TIM_DIER_CC1IE; NVIC_EnableIRQ(TIM5_IRQn); /* This is to make the Prescaler actually work - * For some reason, the Prescaler only kicks in once the timer has reset once. - * Thus, the current solution is to manually ret the value to a really large + * For some reason, the Prescaler only kicks in once the timer has reset once. + * Thus, the current solution is to manually ret the value to a really large * and force it to reset once. Its really jank but its the only way I could * find to make it work - */ + */ TIM5->CNT = 0xFFFFFFFE; } /** * ISR for handling timer overflow -> We increment the upper timer */ -void TIM5_IRQHandler(void){ +void TIM5_IRQHandler(void) { if (TIM5->SR & (1 << 1)) { TIM5->SR &= ~(1 << 1); _lf_time_us_high += 1; @@ -76,16 +74,17 @@ void TIM5_IRQHandler(void){ /** * Write the time since boot into time variable */ -int _lf_clock_now(instant_t *t){ +int _lf_clock_now(instant_t *t) +{ // Timer is cooked if (!t) { return -1; } // Get the current microseconds from TIM5 - uint32_t _lf_time_us_low = TIM5->CNT; + uint32_t _lf_time_us_low = TIM5->CNT; // Combine upper and lower timers (Yoinked from lf_nrf52 support) - uint64_t now_us = COMBINE_HI_LO((_lf_time_us_high-1), _lf_time_us_low); + uint64_t now_us = COMBINE_HI_LO((_lf_time_us_high - 1), _lf_time_us_low); *t = ((instant_t)now_us) * 1000; return 0; } @@ -94,7 +93,7 @@ int _lf_clock_now(instant_t *t){ * Make the STM32 go honk shoo mimimi for set nanoseconds * I essentially stole this from the lf_nrf52 support */ -int lf_sleep(interval_t sleep_duration){ +int lf_sleep(interval_t sleep_duration) { instant_t target_time; instant_t current_time; @@ -133,12 +132,12 @@ int _lf_interruptable_sleep_until_locked(environment_t *env, instant_t wakeup_ti // lf_busy_wait_until(wakeup_time); // return 0; // } - + // // Enable interrupts and prepare to wait // _lf_async_event = false; // instant_t curr; // lf_enable_interrupts_nested(); - + // do { // _lf_clock_now(&curr); @@ -149,7 +148,7 @@ int _lf_interruptable_sleep_until_locked(environment_t *env, instant_t wakeup_ti // lf_disable_interrupts_nested(); // if (!_lf_async_event) { - // return 0; + // return 0; // } else { // LF_PRINT_DEBUG(" *The STM32 rises from sleep* \n"); // return -1; @@ -157,15 +156,11 @@ int _lf_interruptable_sleep_until_locked(environment_t *env, instant_t wakeup_ti instant_t now; do { - _lf_clock_now(&now); + _lf_clock_now(&now); } while (now < wakeup_time); return 0; } - - - - // + -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- + // | Code for enabling and disabling Interrupts // + -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- + @@ -204,59 +199,53 @@ int _lf_unthreaded_notify_of_event() { return 0; } -int test_func(void){ - return 5; +int test_func(void) { + return 5; } // + -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- + // | Other functions I found -> taken from the generated main.c // + -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- + +void SystemClock_Config(void) { + RCC_OscInitTypeDef RCC_OscInitStruct = {0}; + RCC_ClkInitTypeDef RCC_ClkInitStruct = {0}; + + /** Configure the main internal regulator output voltage + */ + __HAL_RCC_PWR_CLK_ENABLE(); + __HAL_PWR_VOLTAGESCALING_CONFIG(PWR_REGULATOR_VOLTAGE_SCALE3); + + /** Initializes the RCC Oscillators according to the specified parameters + * in the RCC_OscInitTypeDef structure. + */ + RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSI; + RCC_OscInitStruct.HSIState = RCC_HSI_ON; + RCC_OscInitStruct.HSICalibrationValue = RCC_HSICALIBRATION_DEFAULT; + RCC_OscInitStruct.PLL.PLLState = RCC_PLL_NONE; + if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK) { + Error_Handler(); + } + + /** Initializes the CPU, AHB and APB buses clocks + */ + RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK | RCC_CLOCKTYPE_SYSCLK | RCC_CLOCKTYPE_PCLK1 | RCC_CLOCKTYPE_PCLK2; + RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_HSI; + RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1; + RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV1; + RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1; + + if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_0) != HAL_OK) { + Error_Handler(); + } +} -// void SystemClock_Config(void) { -// RCC_OscInitTypeDef RCC_OscInitStruct = {0}; -// RCC_ClkInitTypeDef RCC_ClkInitStruct = {0}; - -// /** Configure the main internal regulator output voltage -// */ -// __HAL_RCC_PWR_CLK_ENABLE(); -// __HAL_PWR_VOLTAGESCALING_CONFIG(PWR_REGULATOR_VOLTAGE_SCALE3); - -// /** Initializes the RCC Oscillators according to the specified parameters -// * in the RCC_OscInitTypeDef structure. -// */ -// RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSI; -// RCC_OscInitStruct.HSIState = RCC_HSI_ON; -// RCC_OscInitStruct.HSICalibrationValue = RCC_HSICALIBRATION_DEFAULT; -// RCC_OscInitStruct.PLL.PLLState = RCC_PLL_NONE; -// if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK) -// { -// Error_Handler(); -// } - -// /** Initializes the CPU, AHB and APB buses clocks -// */ -// RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK | RCC_CLOCKTYPE_SYSCLK | RCC_CLOCKTYPE_PCLK1 | RCC_CLOCKTYPE_PCLK2; -// RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_HSI; -// RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1; -// RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV1; -// RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1; - -// if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_0) != HAL_OK) -// { -// Error_Handler(); -// } -// } - - -// void Error_Handler(void) -// { -// /* USER CODE BEGIN Error_Handler_Debug */ -// /* User can add his own implementation to report the HAL error return state */ -// __disable_irq(); -// while (1) -// { -// } -// /* USER CODE END Error_Handler_Debug */ -// } +void Error_Handler(void) { + /* USER CODE BEGIN Error_Handler_Debug */ + /* User can add his own implementation to report the HAL error return state */ + __disable_irq(); + while (1) { + } + /* USER CODE END Error_Handler_Debug */ +} #endif \ No newline at end of file From bcbbf43a05f81592dc23b78307de209ec7fcc212 Mon Sep 17 00:00:00 2001 From: Naichen Zhao Date: Tue, 21 Nov 2023 22:13:35 -0800 Subject: [PATCH 06/38] updated files to move stuff out of core cmake --- core/CMakeLists.txt | 46 -------------------- core/platform/lf_STM32f4_support.c | 70 +++++++++++++++--------------- 2 files changed, 34 insertions(+), 82 deletions(-) diff --git a/core/CMakeLists.txt b/core/CMakeLists.txt index e7006164a..16bf0e616 100644 --- a/core/CMakeLists.txt +++ b/core/CMakeLists.txt @@ -123,49 +123,3 @@ define(SCHEDULER) define(LF_SOURCE_DIRECTORY) define(LF_PACKAGE_DIRECTORY) define(LF_FILE_SEPARATOR) - - - -# ========================================================== -# Stuff I added -# ========================================================== - -if(${CMAKE_SYSTEM_NAME} MATCHES "Stm32") - set(CPU_PARAMETERS - -mcpu=cortex-m4 - -mthumb - -mfpu=fpv4-sp-d16 - -mfloat-abi=softfp ) - - set(MCU_FAMILY STM32F4xx ) - set(MCU_MODEL STM32F446xx ) - - target_compile_definitions(core PRIVATE - ${MCU_MODEL} - USE_HAL_DRIVER ) - - target_compile_options(core PRIVATE - ${CPU_PARAMETERS} - -Wall - -Wextra - -Wpedantic - -Wno-unused-parameter - $<$: - -Wno-volatile - -Wold-style-cast - -Wuseless-cast - -Wsuggest-override> - $<$:-Og -g3 -ggdb> - $<$:-Og -g0> ) - - set(CUBEMX_INCLUDE_DIRECTORIES - ../STM_sdk/Core/Inc - ../STM_sdk/Drivers/${MCU_FAMILY}_HAL_Driver/Inc - ../STM_sdk/Drivers/${MCU_FAMILY}_HAL_Driver/Inc/Legacy - ../STM_sdk/Drivers/CMSIS/Device/ST/${MCU_FAMILY}/Include - ../STM_sdk/Drivers/CMSIS/Include ) - - target_include_directories(core PUBLIC - ${CUBEMX_INCLUDE_DIRECTORIES} ) -endif() -# ========================================================== \ No newline at end of file diff --git a/core/platform/lf_STM32f4_support.c b/core/platform/lf_STM32f4_support.c index dcd944113..01eed54e0 100644 --- a/core/platform/lf_STM32f4_support.c +++ b/core/platform/lf_STM32f4_support.c @@ -119,46 +119,44 @@ static void lf_busy_wait_until(instant_t wakeup_time) { // I am pretty sure this function doesnt work // Ill try to fix it once i know what the fuck its supposed to do, LOL -int _lf_interruptable_sleep_until_locked(environment_t *env, instant_t wakeup_time) { - // // Get the current time and sleep time - // instant_t now; - // _lf_clock_now(&now); - // interval_t duration = wakeup_time - now; - - // // Edge case handling for super small duration - // if (duration <= 0) { - // return 0; - // } else if (duration < 10) { - // lf_busy_wait_until(wakeup_time); - // return 0; - // } - - // // Enable interrupts and prepare to wait - // _lf_async_event = false; - // instant_t curr; - // lf_enable_interrupts_nested(); - - // do { - // _lf_clock_now(&curr); - - // // Exit wither when the timer is up or there is an exception - // } while (!_lf_async_event && (now < wakeup_time)); - - // // Disable interrupts again on exit - // lf_disable_interrupts_nested(); - - // if (!_lf_async_event) { - // return 0; - // } else { - // LF_PRINT_DEBUG(" *The STM32 rises from sleep* \n"); - // return -1; - // } +/* sleep until wakeup time + But, wake up if there is an async event +*/ +int _lf_interruptable_sleep_until_locked(environment_t *env, instant_t wakeup_time) { + // Get the current time and sleep time instant_t now; + _lf_clock_now(&now); + interval_t duration = wakeup_time - now; + + // Edge case handling for super small duration + if (duration <= 0) { + return 0; + } else if (duration < 10) { + lf_busy_wait_until(wakeup_time); + return 0; + } + + // Enable interrupts and prepare to wait + _lf_async_event = false; + lf_enable_interrupts_nested(); + do { _lf_clock_now(&now); - } while (now < wakeup_time); - return 0; + + // Exit when the timer is up or there is an exception + } while (!_lf_async_event && (now < wakeup_time)); + + // Disable interrupts again on exit + lf_disable_interrupts_nested(); + + if (!_lf_async_event) { + return 0; + } else { + LF_PRINT_DEBUG(" *The STM32 rises from sleep* \n"); + return -1; + } + } // + -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- + From 48be057a08ada3378c87c4ebc50e6ead5658adb0 Mon Sep 17 00:00:00 2001 From: Naichen Zhao Date: Thu, 7 Dec 2023 15:09:47 -0800 Subject: [PATCH 07/38] fixed printing --- core/platform/lf_STM32f4_support.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/core/platform/lf_STM32f4_support.c b/core/platform/lf_STM32f4_support.c index 01eed54e0..a0dd01ae9 100644 --- a/core/platform/lf_STM32f4_support.c +++ b/core/platform/lf_STM32f4_support.c @@ -28,6 +28,8 @@ static uint32_t _lf_time_us_high = 0; #define COMBINE_HI_LO(hi, lo) ((((uint64_t)hi) << 32) | ((uint64_t)lo)) +void lf_SystemClock_Config(); +void Error_Handler(); // + -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- + // | Code for timer functions @@ -37,7 +39,7 @@ static uint32_t _lf_time_us_high = 0; void _lf_initialize_clock(void) { // Standard initializations from generated code HAL_Init(); - SystemClock_Config(); + lf_SystemClock_Config(); // Configure TIM5 as our 32-bit clock timer __HAL_RCC_TIM5_CLK_ENABLE(); // initialize counter @@ -204,7 +206,7 @@ int test_func(void) { // + -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- + // | Other functions I found -> taken from the generated main.c // + -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- + -void SystemClock_Config(void) { +void lf_SystemClock_Config(void) { RCC_OscInitTypeDef RCC_OscInitStruct = {0}; RCC_ClkInitTypeDef RCC_ClkInitStruct = {0}; From 31d62b2cdf4969bd48dac25f1718a1676dce5c67 Mon Sep 17 00:00:00 2001 From: Naichen Zhao Date: Mon, 18 Dec 2023 14:49:25 -0800 Subject: [PATCH 08/38] changed naming --- core/platform/lf_STM32f4_support.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core/platform/lf_STM32f4_support.c b/core/platform/lf_STM32f4_support.c index a0dd01ae9..77f0d9add 100644 --- a/core/platform/lf_STM32f4_support.c +++ b/core/platform/lf_STM32f4_support.c @@ -194,7 +194,7 @@ int lf_enable_interrupts_nested() { return 0; } -int _lf_unthreaded_notify_of_event() { +int _lf_single_threaded_notify_of_event() { _lf_async_event = true; return 0; } From 73aea2ed8b86f5ecd574bf14629d18f4cd3a9288 Mon Sep 17 00:00:00 2001 From: naichenzhao Date: Sun, 14 Jul 2024 19:04:28 -0700 Subject: [PATCH 09/38] updated sleep functions --- core/platform/lf_STM32f4_support.c | 33 ++++++++++++++++-------------- 1 file changed, 18 insertions(+), 15 deletions(-) diff --git a/core/platform/lf_STM32f4_support.c b/core/platform/lf_STM32f4_support.c index 77f0d9add..5f8dcfd85 100644 --- a/core/platform/lf_STM32f4_support.c +++ b/core/platform/lf_STM32f4_support.c @@ -92,8 +92,8 @@ int _lf_clock_now(instant_t *t) } /** - * Make the STM32 go honk shoo mimimi for set nanoseconds - * I essentially stole this from the lf_nrf52 support + * Make the STM32 sleep for set nanoseconds + * Based on the lf_nrf52 support implementation */ int lf_sleep(interval_t sleep_duration) { instant_t target_time; @@ -101,6 +101,12 @@ int lf_sleep(interval_t sleep_duration) { _lf_clock_now(¤t_time); target_time = current_time + sleep_duration; + + // HAL_Delay only supports miliseconds. We try to use that for as long as possible + // before switching to another meothd for finer tuned delay times + long delaytime_ms = sleep_duration / 1000000; + HAL_Delay(delaytime_ms); + while (current_time <= target_time) _lf_clock_now(¤t_time); @@ -108,22 +114,20 @@ int lf_sleep(interval_t sleep_duration) { } /** - * Make the STM32 go honk shoo honk shoo for set nanoseconds - * This one uses a do-while loop. :) - * I essentially stole this from the lf_nrf52 support + * Make the STM32 sleep for set nanoseconds + * Based on the lf_nrf52 support implementation */ static void lf_busy_wait_until(instant_t wakeup_time) { - instant_t now; - do { - _lf_clock_now(&now); - } while (now < wakeup_time); + instant_t current_time; + _lf_clock_now(¤t_time); + + // We repurpose the lf_sleep function here, just to better streamline the code + interval_t sleep_duration = wakeup_time - current_time; + lf_sleep(sleep_duration); } // I am pretty sure this function doesnt work -// Ill try to fix it once i know what the fuck its supposed to do, LOL -/* sleep until wakeup time - But, wake up if there is an async event - +/* sleep until wakeup time but wake up if there is an async event */ int _lf_interruptable_sleep_until_locked(environment_t *env, instant_t wakeup_time) { // Get the current time and sleep time @@ -134,7 +138,7 @@ int _lf_interruptable_sleep_until_locked(environment_t *env, instant_t wakeup_ti // Edge case handling for super small duration if (duration <= 0) { return 0; - } else if (duration < 10) { + } else if (duration < LF_MIN_SLEEP_NS) { lf_busy_wait_until(wakeup_time); return 0; } @@ -145,7 +149,6 @@ int _lf_interruptable_sleep_until_locked(environment_t *env, instant_t wakeup_ti do { _lf_clock_now(&now); - // Exit when the timer is up or there is an exception } while (!_lf_async_event && (now < wakeup_time)); From 7899e6befd7e5d6751d2d33a98c8946951d204fe Mon Sep 17 00:00:00 2001 From: naichenzhao Date: Sun, 14 Jul 2024 19:46:32 -0700 Subject: [PATCH 10/38] updated delay functions --- core/platform/lf_STM32f4_support.c | 36 +++++++++++++----------------- 1 file changed, 15 insertions(+), 21 deletions(-) diff --git a/core/platform/lf_STM32f4_support.c b/core/platform/lf_STM32f4_support.c index 5f8dcfd85..fa2099554 100644 --- a/core/platform/lf_STM32f4_support.c +++ b/core/platform/lf_STM32f4_support.c @@ -1,7 +1,5 @@ #if defined(PLATFORM_STM32F4) -/************* - I hope this software works LOL - ***************/ + #include "lf_STM32f4_support.h" #include "platform.h" @@ -15,15 +13,14 @@ static volatile bool _lf_sleep_interrupted = false; static volatile bool _lf_async_event = false; -#define LF_MAX_SLEEP_NS USEC(UINT32_MAX) -#define LF_MIN_SLEEP_NS USEC(5) - // nested critical section counter static uint32_t _lf_num_nested_crit_sec = 0; // Timer upper half (for overflow) static uint32_t _lf_time_us_high = 0; +#define LF_MIN_SLEEP_NS 10 + // Combine 2 32bit works to a 64 bit word (Takes from nrf52 support) #define COMBINE_HI_LO(hi, lo) ((((uint64_t)hi) << 32) | ((uint64_t)lo)) @@ -34,8 +31,7 @@ void Error_Handler(); // + -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- + // | Code for timer functions // + -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- + - -// We use timer 5 for our clock (probably better than fucking with sysTick) +// We use timer 5 for our clock (probably better than dealing with sysTick) void _lf_initialize_clock(void) { // Standard initializations from generated code HAL_Init(); @@ -63,9 +59,7 @@ void _lf_initialize_clock(void) { TIM5->CNT = 0xFFFFFFFE; } -/** - * ISR for handling timer overflow -> We increment the upper timer - */ +// ISR for handling timer overflow -> We increment the upper timer void TIM5_IRQHandler(void) { if (TIM5->SR & (1 << 1)) { TIM5->SR &= ~(1 << 1); @@ -73,6 +67,7 @@ void TIM5_IRQHandler(void) { } } + /** * Write the time since boot into time variable */ @@ -80,7 +75,8 @@ int _lf_clock_now(instant_t *t) { // Timer is cooked if (!t) { - return -1; + return 1; + } // Get the current microseconds from TIM5 uint32_t _lf_time_us_low = TIM5->CNT; @@ -101,7 +97,6 @@ int lf_sleep(interval_t sleep_duration) { _lf_clock_now(¤t_time); target_time = current_time + sleep_duration; - // HAL_Delay only supports miliseconds. We try to use that for as long as possible // before switching to another meothd for finer tuned delay times long delaytime_ms = sleep_duration / 1000000; @@ -158,8 +153,8 @@ int _lf_interruptable_sleep_until_locked(environment_t *env, instant_t wakeup_ti if (!_lf_async_event) { return 0; } else { - LF_PRINT_DEBUG(" *The STM32 rises from sleep* \n"); - return -1; + return 1; + } } @@ -182,7 +177,8 @@ int lf_disable_interrupts_nested() { // enables the IRQ (checks if other programs still want it disabled first) int lf_enable_interrupts_nested() { - // Somebody fucked up, LOL + // Left the critical section more often than it was entered. + if (_lf_num_nested_crit_sec <= 0) { return 1; } @@ -202,17 +198,14 @@ int _lf_single_threaded_notify_of_event() { return 0; } -int test_func(void) { - return 5; -} - // + -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- + -// | Other functions I found -> taken from the generated main.c +// | Other functions -> taken from the generated main.c // + -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- + void lf_SystemClock_Config(void) { RCC_OscInitTypeDef RCC_OscInitStruct = {0}; RCC_ClkInitTypeDef RCC_ClkInitStruct = {0}; + /** Configure the main internal regulator output voltage */ __HAL_RCC_PWR_CLK_ENABLE(); @@ -249,6 +242,7 @@ void Error_Handler(void) { while (1) { } /* USER CODE END Error_Handler_Debug */ + } #endif \ No newline at end of file From d11f3ff254ba00846545304de43557d75810ceb2 Mon Sep 17 00:00:00 2001 From: naichenzhao Date: Sun, 4 Aug 2024 20:38:29 -0700 Subject: [PATCH 11/38] rebased in main --- core/platform/CMakeLists.txt | 38 ++ core/platform/Platform.cmake | 20 + include/core/platform.h | 351 ++++++++++++++++++ .../api/platform/lf_STM32f4_support.h | 27 ++ .../impl/src/lf_STM32f4_support.c | 262 +++++++++++++ 5 files changed, 698 insertions(+) create mode 100644 core/platform/CMakeLists.txt create mode 100644 core/platform/Platform.cmake create mode 100644 include/core/platform.h create mode 100644 low_level_platform/api/platform/lf_STM32f4_support.h create mode 100644 low_level_platform/impl/src/lf_STM32f4_support.c diff --git a/core/platform/CMakeLists.txt b/core/platform/CMakeLists.txt new file mode 100644 index 000000000..1e3005d18 --- /dev/null +++ b/core/platform/CMakeLists.txt @@ -0,0 +1,38 @@ +# Check which system we are running on to select the correct platform support +# file and assign the file's path to LF_PLATFORM_FILE + +set(LF_PLATFORM_FILES +lf_unix_clock_support.c +lf_unix_syscall_support.c +lf_linux_support.c +lf_macos_support.c +lf_windows_support.c +lf_nrf52_support.c +lf_zephyr_support.c +lf_zephyr_clock_counter.c +lf_zephyr_clock_kernel.c +lf_rp2040_support.c +lf_STM32f4_support.c +) + +if(${CMAKE_SYSTEM_NAME} STREQUAL "Windows") + set(CMAKE_SYSTEM_VERSION 10.0) + message("Using Windows SDK version ${CMAKE_VS_WINDOWS_TARGET_PLATFORM_VERSION}") +elseif(${CMAKE_SYSTEM_NAME} STREQUAL "Nrf52") + target_compile_definitions(core PUBLIC PLATFORM_NRF52) +elseif(${CMAKE_SYSTEM_NAME} STREQUAL "Zephyr") + target_compile_definitions(core PUBLIC PLATFORM_ZEPHYR) +elseif(${CMAKE_SYSTEM_NAME} STREQUAL "STM32f4") + target_compile_definitions(core PUBLIC PLATFORM_STM32F4) +elseif(${CMAKE_SYSTEM_NAME} STREQUAL "Rp2040") + target_compile_definitions(core PUBLIC PLATFORM_RP2040) +endif() + +# Add sources to the list for debug info +list(APPEND INFO_SOURCES ${LF_PLATFORM_FILES}) + +# Prepend all sources with platform +list(TRANSFORM LF_PLATFORM_FILES PREPEND platform/) + +# Add sources to core lib +target_sources(core PRIVATE ${LF_PLATFORM_FILES}) diff --git a/core/platform/Platform.cmake b/core/platform/Platform.cmake new file mode 100644 index 000000000..10797a1c5 --- /dev/null +++ b/core/platform/Platform.cmake @@ -0,0 +1,20 @@ +# Check which system we are running on to select the correct platform support +# file and assign the file's path to LF_PLATFORM_FILE +if(${CMAKE_SYSTEM_NAME} STREQUAL "Linux") + set(LF_PLATFORM_FILE lf_linux_support.c) +elseif(${CMAKE_SYSTEM_NAME} STREQUAL "Darwin") + set(LF_PLATFORM_FILE lf_macos_support.c) +elseif(${CMAKE_SYSTEM_NAME} STREQUAL "Windows") + set(LF_PLATFORM_FILE lf_windows_support.c) + set(CMAKE_SYSTEM_VERSION 10.0) + message("Using Windows SDK version ${CMAKE_VS_WINDOWS_TARGET_PLATFORM_VERSION}") +elseif(${CMAKE_SYSTEM_NAME} STREQUAL "Zephyr") + set(LF_PLATFORM_FILE lf_zephyr_support.c) +elseif(${CMAKE_SYSTEM_NAME} STREQUAL "STM32f4") + set(LF_PLATFORM_FILE lf_STM32f4_support.c) +elseif(${CMAKE_SYSTEM_NAME} STREQUAL "Rp2040") + message("Using pico-sdk for RP2040 target") + set(LF_PLATFORM_FILE lf_rp2040_support.c) +else() + message(FATAL_ERROR "Your platform is not supported! The C target supports Linux, MacOS and Windows.") +endif() diff --git a/include/core/platform.h b/include/core/platform.h new file mode 100644 index 000000000..e615a0f0a --- /dev/null +++ b/include/core/platform.h @@ -0,0 +1,351 @@ +/* Platform API support for the C target of Lingua Franca. */ + +/************* +Copyright (c) 2021, The University of California at Berkeley. + +Redistribution and use in source and binary forms, with or without modification, +are permitted provided that the following conditions are met: + +1. Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + +2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY +EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF +MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL +THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, +STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF +THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +***************/ + +/** + * Platform API support for the C target of Lingua Franca. + * This file detects the platform on which the C compiler is being run + * (e.g. Windows, Linux, Mac) and conditionally includes platform-specific + * files that define core datatypes and function signatures for Lingua Franca. + * + * @author{Soroush Bateni } + */ + +#ifndef PLATFORM_H +#define PLATFORM_H + +#if defined(LF_THREADED) && defined(LF_UNTHREADED) +#error LF_UNTHREADED and LF_THREADED runtime requested +#endif + +#ifdef __cplusplus +extern "C" { +#endif + +#include "tag.h" +#include + +// Forward declarations +typedef struct environment_t environment_t; + +/** + * @brief Notify of new event by calling the unthreaded platform API + * @param env Environment in which we are executing. + */ +int lf_notify_of_event(environment_t* env); + +/** + * @brief Enter critical section by disabling interrupts + * @param env Environment in which we are executing. + */ +int lf_critical_section_enter(environment_t* env); + +/** + * @brief Leave a critical section by enabling interrupts + * @param env Environment in which we are executing. + */ +int lf_critical_section_exit(environment_t* env); + +#if defined(PLATFORM_ARDUINO) + #include "platform/lf_arduino_support.h" +#elif defined(PLATFORM_ZEPHYR) + #include "platform/lf_zephyr_support.h" +#elif defined(PLATFORM_NRF52) + #include "platform/lf_nrf52_support.h" +#elif defined(PLATFORM_STM32F4) + #include "platform/lf_STM32f4_support.h" +#elif defined(PLATFORM_RP2040) + #include "platform/lf_rp2040_support.h" +#elif defined(WIN32) || defined(_WIN32) || defined(__WIN32__) || defined(__NT__) + // Windows platforms + #include "lf_windows_support.h" +#elif __APPLE__ + // Apple platforms + #include "lf_macos_support.h" +#elif __linux__ + // Linux + #include "lf_linux_support.h" +#elif __unix__ // all unices not caught above + // Unix + #include "lf_POSIX_threads_support.h" +#elif defined(_POSIX_VERSION) + // POSIX + #include "lf_POSIX_threads_support.h" +#elif defined(__riscv) || defined(__riscv__) + // RISC-V (see https://github.com/riscv/riscv-toolchain-conventions) + #error "RISC-V not supported" +#else +#error "Platform not supported" +#endif + +#if !defined(LF_THREADED) + typedef void lf_mutex_t; +#endif + +#define LF_TIMEOUT 1 + + +// To support the unthreaded runtime, we need the following functions. They +// are not required by the threaded runtime and is thus hidden behind a #ifdef. +#if defined (LF_UNTHREADED) + /** + * @brief Disable interrupts with support for nested calls + * + * @return int + */ + int lf_disable_interrupts_nested(); + /** + * @brief Enable interrupts after potentially multiple callse to `lf_disable_interrupts_nested` + * + * @return int + */ + int lf_enable_interrupts_nested(); + + /** + * @brief Notify sleeping unthreaded context of new event + * + * @return int + */ + int _lf_unthreaded_notify_of_event(); +#endif + + +// For platforms with threading support, the following functions +// abstract the API so that the LF runtime remains portable. +#if defined LF_THREADED + + +/** + * @brief Get the number of cores on the host machine. + */ +int lf_available_cores(); + +/** + * Create a new thread, starting with execution of lf_thread + * getting passed arguments. The new handle is stored in thread_id. + * + * @return 0 on success, platform-specific error number otherwise. + * + */ +int lf_thread_create(lf_thread_t* thread, void *(*lf_thread) (void *), void* arguments); + +/** + * Make calling thread wait for termination of the thread. The + * exit status of the thread is stored in thread_return if thread_return + * is not NULL. + * @param thread The thread. + * @param thread_return A pointer to where to store the exit status of the thread. + * + * @return 0 on success, platform-specific error number otherwise. + */ +int lf_thread_join(lf_thread_t thread, void** thread_return); + +/** + * Initialize a mutex. + * + * @return 0 on success, platform-specific error number otherwise. + */ +int lf_mutex_init(lf_mutex_t* mutex); + +/** + * Lock a mutex. + * + * @return 0 on success, platform-specific error number otherwise. + */ +int lf_mutex_lock(lf_mutex_t* mutex); + +/** + * Unlock a mutex. + * + * @return 0 on success, platform-specific error number otherwise. + */ +int lf_mutex_unlock(lf_mutex_t* mutex); + +/** + * Initialize a conditional variable. + * + * @return 0 on success, platform-specific error number otherwise. + */ +int lf_cond_init(lf_cond_t* cond, lf_mutex_t* mutex); + +/** + * Wake up all threads waiting for condition variable cond. + * + * @return 0 on success, platform-specific error number otherwise. + */ +int lf_cond_broadcast(lf_cond_t* cond); + +/** + * Wake up one thread waiting for condition variable cond. + * + * @return 0 on success, platform-specific error number otherwise. + */ +int lf_cond_signal(lf_cond_t* cond); + +/** + * Wait for condition variable "cond" to be signaled or broadcast. + * "mutex" is assumed to be locked before. + * + * @return 0 on success, platform-specific error number otherwise. + */ +int lf_cond_wait(lf_cond_t* cond); + +/** + * Block current thread on the condition variable until condition variable + * pointed by "cond" is signaled or time pointed by "absolute_time_ns" in + * nanoseconds is reached. + * + * @return 0 on success, LF_TIMEOUT on timeout, and platform-specific error + * number otherwise. + */ +int lf_cond_timedwait(lf_cond_t* cond, instant_t absolute_time_ns); + +/* + * Atomically increment the variable that ptr points to by the given value, and return the original value of the variable. + * @param ptr A pointer to a variable. The value of this variable will be replaced with the result of the operation. + * @param value The value to be added to the variable pointed to by the ptr parameter. + * @return The original value of the variable that ptr points to (i.e., from before the application of this operation). + */ +#if defined(PLATFORM_ZEPHYR) +#define lf_atomic_fetch_add(ptr, value) _zephyr_atomic_fetch_add((int*) ptr, value) +#elif defined(WIN32) || defined(_WIN32) || defined(__WIN32__) || defined(__NT__) +// Assume that an integer is 32 bits. +#define lf_atomic_fetch_add(ptr, value) InterlockedExchangeAdd(ptr, value) +#elif defined(__GNUC__) || defined(__clang__) +#define lf_atomic_fetch_add(ptr, value) __sync_fetch_and_add(ptr, value) +#else +#error "Compiler not supported" +#endif + +/* + * Atomically increment the variable that ptr points to by the given value, and return the new value of the variable. + * @param ptr A pointer to a variable. The value of this variable will be replaced with the result of the operation. + * @param value The value to be added to the variable pointed to by the ptr parameter. + * @return The new value of the variable that ptr points to (i.e., from before the application of this operation). + */ +#if defined(PLATFORM_ZEPHYR) +#define lf_atomic_add_fetch(ptr, value) _zephyr_atomic_add_fetch((int*) ptr, value) +#elif defined(WIN32) || defined(_WIN32) || defined(__WIN32__) || defined(__NT__) +// Assume that an integer is 32 bits. +#define lf_atomic_add_fetch(ptr, value) InterlockedAdd(ptr, value) +#elif defined(__GNUC__) || defined(__clang__) +#define lf_atomic_add_fetch(ptr, value) __sync_add_and_fetch(ptr, value) +#else +#error "Compiler not supported" +#endif + +/* + * Atomically compare the variable that ptr points to against oldval. If the + * current value is oldval, then write newval into *ptr. + * @param ptr A pointer to a variable. + * @param oldval The value to compare against. + * @param newval The value to assign to *ptr if comparison is successful. + * @return True if comparison was successful. False otherwise. + */ +#if defined(PLATFORM_ZEPHYR) +#define lf_bool_compare_and_swap(ptr, value, newval) _zephyr_bool_compare_and_swap((bool*) ptr, value, newval) +#elif defined(WIN32) || defined(_WIN32) || defined(__WIN32__) || defined(__NT__) +// Assume that a boolean is represented with a 32-bit integer. +#define lf_bool_compare_and_swap(ptr, oldval, newval) (InterlockedCompareExchange(ptr, newval, oldval) == oldval) +#elif defined(__GNUC__) || defined(__clang__) +#define lf_bool_compare_and_swap(ptr, oldval, newval) __sync_bool_compare_and_swap(ptr, oldval, newval) +#else +#error "Compiler not supported" +#endif + +/* + * Atomically compare the 32-bit value that ptr points to against oldval. If the + * current value is oldval, then write newval into *ptr. + * @param ptr A pointer to a variable. + * @param oldval The value to compare against. + * @param newval The value to assign to *ptr if comparison is successful. + * @return The initial value of *ptr. + */ +#if defined(PLATFORM_ZEPHYR) +#define lf_val_compare_and_swap(ptr, value, newval) _zephyr_val_compare_and_swap((int*) ptr, value, newval) +#elif defined(WIN32) || defined(_WIN32) || defined(__WIN32__) || defined(__NT__) +#define lf_val_compare_and_swap(ptr, oldval, newval) InterlockedCompareExchange(ptr, newval, oldval) +#elif defined(__GNUC__) || defined(__clang__) +#define lf_val_compare_and_swap(ptr, oldval, newval) __sync_val_compare_and_swap(ptr, oldval, newval) +#else +#error "Compiler not supported" +#endif + +#endif + +/** + * Initialize the LF clock. Must be called before using other clock-related APIs. + */ +void _lf_initialize_clock(void); + +/** + * Fetch the value of an internal (and platform-specific) physical clock and + * store it in `t`. + * + * Ideally, the underlying platform clock should be monotonic. However, the + * core lib tries to enforce monotonicity at higher level APIs (see tag.h). + * + * @return 0 for success, or -1 for failure + */ +int _lf_clock_now(instant_t* t); + +/** + * Pause execution for a given duration. + * + * @return 0 for success, or -1 for failure. + */ +int lf_sleep(interval_t sleep_duration); + +/** + * @brief Sleep until the given wakeup time. Assumes the lock for the + * given environment is held + * + * @param env The environment within which to sleep. + * @param wakeup_time The time instant at which to wake up. + * @return int 0 if sleep completed, or -1 if it was interrupted. + */ +int _lf_interruptable_sleep_until_locked(environment_t* env, instant_t wakeup_time); + +/** + * Macros for marking function as deprecated + */ +#ifdef __GNUC__ + #define DEPRECATED(X) X __attribute__((deprecated)) +#elif defined(_MSC_VER) + #define DEPRECATED(X) __declspec(deprecated) X +#else + #define DEPRECATED(X) X +#endif + +/** + * @deprecated version of "lf_sleep" + */ +DEPRECATED(int lf_nanosleep(interval_t sleep_duration)); + +#ifdef __cplusplus +} +#endif + +#endif // PLATFORM_H diff --git a/low_level_platform/api/platform/lf_STM32f4_support.h b/low_level_platform/api/platform/lf_STM32f4_support.h new file mode 100644 index 000000000..7a8414576 --- /dev/null +++ b/low_level_platform/api/platform/lf_STM32f4_support.h @@ -0,0 +1,27 @@ +/* STM32 API support for the C target of Lingua Franca. */ + +#ifndef LF_STM32F4_SUPPORT_H +#define LF_STM32F4_SUPPORT_H + +// I have no idea what the fuck TTY is so i guess we dont support it +#define NO_TTY + +// #include <../../../STM_Core/Inc/main.h> +// #include <../../../Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal.h> +#include + +// src-gen/Main/Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal.h + +// Defines for formatting time in printf for pico +#define PRINTF_TAG "(" PRINTF_TIME ", " PRINTF_MICROSTEP ")" +#define PRINTF_TIME "%lld" +#define PRINTF_MICROSTEP "%d" + +#define LF_TIME_BUFFER_LENGTH 80 +#define _LF_TIMEOUT 1 + +#ifdef LF_THREADED +#error "I have no idea how to support threading" +#endif // LF_THREADED + +#endif \ No newline at end of file diff --git a/low_level_platform/impl/src/lf_STM32f4_support.c b/low_level_platform/impl/src/lf_STM32f4_support.c new file mode 100644 index 000000000..4223244d8 --- /dev/null +++ b/low_level_platform/impl/src/lf_STM32f4_support.c @@ -0,0 +1,262 @@ +#ifdef defined(PLATFORM_STM32F4) +/************* + I hope this software works LOL + ***************/ + +#include "lf_STM32f4_support.h" +#include "platform.h" +#include "utils/util.h" +#include "tag.h" + +// + -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- + +// | Important defines and global variables +// + -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- + + +static volatile bool _lf_sleep_interrupted = false; +static volatile bool _lf_async_event = false; + +#define LF_MAX_SLEEP_NS USEC(UINT32_MAX) +#define LF_MIN_SLEEP_NS USEC(5) + +// nested critical section counter +static uint32_t _lf_num_nested_crit_sec = 0; + +// Timer upper half (for overflow) +static uint32_t _lf_time_us_high = 0; + +// Combine 2 32bit works to a 64 bit word (Takes from nrf52 support) +#define COMBINE_HI_LO(hi, lo) ((((uint64_t)hi) << 32) | ((uint64_t)lo)) + + + + + +// + -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- + +// | Code for timer functions +// + -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- + + +// We use timer 5 for our clock (probably better than fucking with sysTick) +void _lf_initialize_clock(void) { + // Standard initializations from generated code + // HAL_Init(); + // SystemClock_Config(); + + // Configure TIM5 as our 32-bit clock timer + __HAL_RCC_TIM5_CLK_ENABLE(); // initialize counter + TIM5->CR1 = TIM_CR1_CEN; // enable counter + + // set prescaler to (16 - 1) = 15 + // CPU runs a 16MHz so timer ticks at 1MHz + // Which means period of 1 microsecond + TIM5->PSC = 15; + + // Setup ISR to increment upper bits + TIM5->DIER |= TIM_DIER_CC1IE; + NVIC_EnableIRQ(TIM5_IRQn); + + /* This is to make the Prescaler actually work + * For some reason, the Prescaler only kicks in once the timer has reset once. + * Thus, the current solution is to manually ret the value to a really large + * and force it to reset once. Its really jank but its the only way I could + * find to make it work + */ + TIM5->CNT = 0xFFFFFFFE; +} + +/** + * ISR for handling timer overflow -> We increment the upper timer + */ +void TIM5_IRQHandler(void){ + if (TIM5->SR & (1 << 1)) { + TIM5->SR &= ~(1 << 1); + _lf_time_us_high += 1; + } +} + +/** + * Write the time since boot into time variable + */ +int _lf_clock_now(instant_t *t){ + // Timer is cooked + if (!t) { + return -1; + } + // Get the current microseconds from TIM5 + uint32_t _lf_time_us_low = TIM5->CNT; + + // Combine upper and lower timers (Yoinked from lf_nrf52 support) + uint64_t now_us = COMBINE_HI_LO((_lf_time_us_high-1), _lf_time_us_low); + *t = ((instant_t)now_us) * 1000; + return 0; +} + +/** + * Make the STM32 go honk shoo mimimi for set nanoseconds + * I essentially stole this from the lf_nrf52 support + */ +int lf_sleep(interval_t sleep_duration){ + instant_t target_time; + instant_t current_time; + + _lf_clock_now(¤t_time); + target_time = current_time + sleep_duration; + while (current_time <= target_time) + _lf_clock_now(¤t_time); + + return 0; +} + +/** + * Make the STM32 go honk shoo honk shoo for set nanoseconds + * This one uses a do-while loop. :) + * I essentially stole this from the lf_nrf52 support + */ +static void lf_busy_wait_until(instant_t wakeup_time) { + instant_t now; + do { + _lf_clock_now(&now); + } while (now < wakeup_time); +} + +// I am pretty sure this function doesnt work +// Ill try to fix it once i know what the fuck its supposed to do, LOL +int _lf_interruptable_sleep_until_locked(environment_t *env, instant_t wakeup_time) { + // // Get the current time and sleep time + // instant_t now; + // _lf_clock_now(&now); + // interval_t duration = wakeup_time - now; + + // // Edge case handling for super small duration + // if (duration <= 0) { + // return 0; + // } else if (duration < 10) { + // lf_busy_wait_until(wakeup_time); + // return 0; + // } + + // // Enable interrupts and prepare to wait + // _lf_async_event = false; + // instant_t curr; + // lf_enable_interrupts_nested(); + + // do { + // _lf_clock_now(&curr); + + // // Exit wither when the timer is up or there is an exception + // } while (!_lf_async_event && (now < wakeup_time)); + + // // Disable interrupts again on exit + // lf_disable_interrupts_nested(); + + // if (!_lf_async_event) { + // return 0; + // } else { + // LF_PRINT_DEBUG(" *The STM32 rises from sleep* \n"); + // return -1; + // } + + instant_t now; + do { + _lf_clock_now(&now); + } while (now < wakeup_time); + return 0; +} + + + + + +// + -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- + +// | Code for enabling and disabling Interrupts +// + -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- + + +// disables the IRQ (checks if its already disabled) +int lf_disable_interrupts_nested() { + // Disable interrupts if they are currently enabled + if (_lf_num_nested_crit_sec == 0) { + __disable_irq(); + } + + // update the depth of disabling interrupts + _lf_num_nested_crit_sec++; + return 0; +} + +// enables the IRQ (checks if other programs still want it disabled first) +int lf_enable_interrupts_nested() { + // Somebody fucked up, LOL + if (_lf_num_nested_crit_sec <= 0) { + return 1; + } + + // update the depth of disabling interrupts + _lf_num_nested_crit_sec--; + + // If we have exited all important programs, we can enable them again + if (_lf_num_nested_crit_sec == 0) { + __enable_irq(); + } + return 0; +} + +int _lf_unthreaded_notify_of_event() { + _lf_async_event = true; + return 0; +} + +int test_func(void){ + return 5; +} + +// + -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- + +// | Other functions I found -> taken from the generated main.c +// + -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- + + +// void SystemClock_Config(void) { +// RCC_OscInitTypeDef RCC_OscInitStruct = {0}; +// RCC_ClkInitTypeDef RCC_ClkInitStruct = {0}; + +// /** Configure the main internal regulator output voltage +// */ +// __HAL_RCC_PWR_CLK_ENABLE(); +// __HAL_PWR_VOLTAGESCALING_CONFIG(PWR_REGULATOR_VOLTAGE_SCALE3); + +// /** Initializes the RCC Oscillators according to the specified parameters +// * in the RCC_OscInitTypeDef structure. +// */ +// RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSI; +// RCC_OscInitStruct.HSIState = RCC_HSI_ON; +// RCC_OscInitStruct.HSICalibrationValue = RCC_HSICALIBRATION_DEFAULT; +// RCC_OscInitStruct.PLL.PLLState = RCC_PLL_NONE; +// if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK) +// { +// Error_Handler(); +// } + +// /** Initializes the CPU, AHB and APB buses clocks +// */ +// RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK | RCC_CLOCKTYPE_SYSCLK | RCC_CLOCKTYPE_PCLK1 | RCC_CLOCKTYPE_PCLK2; +// RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_HSI; +// RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1; +// RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV1; +// RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1; + +// if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_0) != HAL_OK) +// { +// Error_Handler(); +// } +// } + + +// void Error_Handler(void) +// { +// /* USER CODE BEGIN Error_Handler_Debug */ +// /* User can add his own implementation to report the HAL error return state */ +// __disable_irq(); +// while (1) +// { +// } +// /* USER CODE END Error_Handler_Debug */ +// } + +#endif \ No newline at end of file From 58d232349666d4725895a7be50b64e21195a9c24 Mon Sep 17 00:00:00 2001 From: naichenzhao Date: Sun, 4 Aug 2024 20:39:40 -0700 Subject: [PATCH 12/38] change --- lingua-franca-ref.txt | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/lingua-franca-ref.txt b/lingua-franca-ref.txt index 1f7391f92..31439c511 100644 --- a/lingua-franca-ref.txt +++ b/lingua-franca-ref.txt @@ -1 +1,2 @@ -master +stm32 + From 5ae3be65685d26b3dd34b173962c0b3dd22c9c1f Mon Sep 17 00:00:00 2001 From: Naichen Zhao Date: Fri, 10 Nov 2023 18:41:26 -0800 Subject: [PATCH 13/38] fixed typo --- low_level_platform/impl/src/lf_STM32f4_support.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/low_level_platform/impl/src/lf_STM32f4_support.c b/low_level_platform/impl/src/lf_STM32f4_support.c index 4223244d8..e9aa852b7 100644 --- a/low_level_platform/impl/src/lf_STM32f4_support.c +++ b/low_level_platform/impl/src/lf_STM32f4_support.c @@ -1,4 +1,4 @@ -#ifdef defined(PLATFORM_STM32F4) +#if defined(PLATFORM_STM32F4) /************* I hope this software works LOL ***************/ From 4bb9231a670107c109a03bdf98853b7b4a39ee0d Mon Sep 17 00:00:00 2001 From: naichenzhao Date: Sun, 4 Aug 2024 20:40:53 -0700 Subject: [PATCH 14/38] bruh --- core/CMakeLists.txt | 45 +++++++++++++++++++ core/platform/CMakeLists.txt | 2 +- core/platform/Platform.cmake | 2 +- .../api/platform/lf_STM32f4_support.h | 4 -- 4 files changed, 47 insertions(+), 6 deletions(-) diff --git a/core/CMakeLists.txt b/core/CMakeLists.txt index 6d938ae0c..56654e3b4 100644 --- a/core/CMakeLists.txt +++ b/core/CMakeLists.txt @@ -184,3 +184,48 @@ define(LF_PACKAGE_DIRECTORY) define(LF_FILE_SEPARATOR) define(WORKERS_NEEDED_FOR_FEDERATE) define(LF_ENCLAVES) + + +# ========================================================== +# Additional support for stm32 +# ========================================================== + +if(${CMAKE_SYSTEM_NAME} MATCHES "Stm32") + set(CPU_PARAMETERS + -mcpu=cortex-m4 + -mthumb + -mfpu=fpv4-sp-d16 + -mfloat-abi=softfp ) + + set(MCU_FAMILY STM32F4xx ) + set(MCU_MODEL STM32F446xx ) + + target_compile_definitions(core PRIVATE + ${MCU_MODEL} + USE_HAL_DRIVER ) + + target_compile_options(core PRIVATE + ${CPU_PARAMETERS} + -Wall + -Wextra + -Wpedantic + -Wno-unused-parameter + $<$: + -Wno-volatile + -Wold-style-cast + -Wuseless-cast + -Wsuggest-override> + $<$:-Og -g3 -ggdb> + $<$:-Og -g0> ) + + set(CUBEMX_INCLUDE_DIRECTORIES + ../STM_sdk/Core/Inc + ../STM_sdk/Drivers/${MCU_FAMILY}_HAL_Driver/Inc + ../STM_sdk/Drivers/${MCU_FAMILY}_HAL_Driver/Inc/Legacy + ../STM_sdk/Drivers/CMSIS/Device/ST/${MCU_FAMILY}/Include + ../STM_sdk/Drivers/CMSIS/Include ) + + target_include_directories(core PUBLIC + ${CUBEMX_INCLUDE_DIRECTORIES} ) +endif() +# ========================================================== diff --git a/core/platform/CMakeLists.txt b/core/platform/CMakeLists.txt index 1e3005d18..949d65177 100644 --- a/core/platform/CMakeLists.txt +++ b/core/platform/CMakeLists.txt @@ -22,7 +22,7 @@ elseif(${CMAKE_SYSTEM_NAME} STREQUAL "Nrf52") target_compile_definitions(core PUBLIC PLATFORM_NRF52) elseif(${CMAKE_SYSTEM_NAME} STREQUAL "Zephyr") target_compile_definitions(core PUBLIC PLATFORM_ZEPHYR) -elseif(${CMAKE_SYSTEM_NAME} STREQUAL "STM32f4") +elseif(${CMAKE_SYSTEM_NAME} STREQUAL "Stm32") target_compile_definitions(core PUBLIC PLATFORM_STM32F4) elseif(${CMAKE_SYSTEM_NAME} STREQUAL "Rp2040") target_compile_definitions(core PUBLIC PLATFORM_RP2040) diff --git a/core/platform/Platform.cmake b/core/platform/Platform.cmake index 10797a1c5..2d082bce6 100644 --- a/core/platform/Platform.cmake +++ b/core/platform/Platform.cmake @@ -10,7 +10,7 @@ elseif(${CMAKE_SYSTEM_NAME} STREQUAL "Windows") message("Using Windows SDK version ${CMAKE_VS_WINDOWS_TARGET_PLATFORM_VERSION}") elseif(${CMAKE_SYSTEM_NAME} STREQUAL "Zephyr") set(LF_PLATFORM_FILE lf_zephyr_support.c) -elseif(${CMAKE_SYSTEM_NAME} STREQUAL "STM32f4") +elseif(${CMAKE_SYSTEM_NAME} STREQUAL "Stm32") set(LF_PLATFORM_FILE lf_STM32f4_support.c) elseif(${CMAKE_SYSTEM_NAME} STREQUAL "Rp2040") message("Using pico-sdk for RP2040 target") diff --git a/low_level_platform/api/platform/lf_STM32f4_support.h b/low_level_platform/api/platform/lf_STM32f4_support.h index 7a8414576..063421d6d 100644 --- a/low_level_platform/api/platform/lf_STM32f4_support.h +++ b/low_level_platform/api/platform/lf_STM32f4_support.h @@ -6,12 +6,8 @@ // I have no idea what the fuck TTY is so i guess we dont support it #define NO_TTY -// #include <../../../STM_Core/Inc/main.h> -// #include <../../../Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal.h> #include -// src-gen/Main/Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal.h - // Defines for formatting time in printf for pico #define PRINTF_TAG "(" PRINTF_TIME ", " PRINTF_MICROSTEP ")" #define PRINTF_TIME "%lld" From 952753741b55870509c79fc86aa69a1844469a09 Mon Sep 17 00:00:00 2001 From: Naichen Zhao Date: Sun, 19 Nov 2023 01:24:16 -0800 Subject: [PATCH 15/38] we dont need STM_main anymore --- .../impl/src/lf_STM32f4_support.c | 129 ++++++++---------- 1 file changed, 59 insertions(+), 70 deletions(-) diff --git a/low_level_platform/impl/src/lf_STM32f4_support.c b/low_level_platform/impl/src/lf_STM32f4_support.c index e9aa852b7..dcd944113 100644 --- a/low_level_platform/impl/src/lf_STM32f4_support.c +++ b/low_level_platform/impl/src/lf_STM32f4_support.c @@ -29,8 +29,6 @@ static uint32_t _lf_time_us_high = 0; - - // + -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- + // | Code for timer functions // + -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- + @@ -38,35 +36,35 @@ static uint32_t _lf_time_us_high = 0; // We use timer 5 for our clock (probably better than fucking with sysTick) void _lf_initialize_clock(void) { // Standard initializations from generated code - // HAL_Init(); - // SystemClock_Config(); + HAL_Init(); + SystemClock_Config(); // Configure TIM5 as our 32-bit clock timer __HAL_RCC_TIM5_CLK_ENABLE(); // initialize counter - TIM5->CR1 = TIM_CR1_CEN; // enable counter + TIM5->CR1 = TIM_CR1_CEN; // enable counter // set prescaler to (16 - 1) = 15 // CPU runs a 16MHz so timer ticks at 1MHz // Which means period of 1 microsecond - TIM5->PSC = 15; + TIM5->PSC = 15; // Setup ISR to increment upper bits TIM5->DIER |= TIM_DIER_CC1IE; NVIC_EnableIRQ(TIM5_IRQn); /* This is to make the Prescaler actually work - * For some reason, the Prescaler only kicks in once the timer has reset once. - * Thus, the current solution is to manually ret the value to a really large + * For some reason, the Prescaler only kicks in once the timer has reset once. + * Thus, the current solution is to manually ret the value to a really large * and force it to reset once. Its really jank but its the only way I could * find to make it work - */ + */ TIM5->CNT = 0xFFFFFFFE; } /** * ISR for handling timer overflow -> We increment the upper timer */ -void TIM5_IRQHandler(void){ +void TIM5_IRQHandler(void) { if (TIM5->SR & (1 << 1)) { TIM5->SR &= ~(1 << 1); _lf_time_us_high += 1; @@ -76,16 +74,17 @@ void TIM5_IRQHandler(void){ /** * Write the time since boot into time variable */ -int _lf_clock_now(instant_t *t){ +int _lf_clock_now(instant_t *t) +{ // Timer is cooked if (!t) { return -1; } // Get the current microseconds from TIM5 - uint32_t _lf_time_us_low = TIM5->CNT; + uint32_t _lf_time_us_low = TIM5->CNT; // Combine upper and lower timers (Yoinked from lf_nrf52 support) - uint64_t now_us = COMBINE_HI_LO((_lf_time_us_high-1), _lf_time_us_low); + uint64_t now_us = COMBINE_HI_LO((_lf_time_us_high - 1), _lf_time_us_low); *t = ((instant_t)now_us) * 1000; return 0; } @@ -94,7 +93,7 @@ int _lf_clock_now(instant_t *t){ * Make the STM32 go honk shoo mimimi for set nanoseconds * I essentially stole this from the lf_nrf52 support */ -int lf_sleep(interval_t sleep_duration){ +int lf_sleep(interval_t sleep_duration) { instant_t target_time; instant_t current_time; @@ -133,12 +132,12 @@ int _lf_interruptable_sleep_until_locked(environment_t *env, instant_t wakeup_ti // lf_busy_wait_until(wakeup_time); // return 0; // } - + // // Enable interrupts and prepare to wait // _lf_async_event = false; // instant_t curr; // lf_enable_interrupts_nested(); - + // do { // _lf_clock_now(&curr); @@ -149,7 +148,7 @@ int _lf_interruptable_sleep_until_locked(environment_t *env, instant_t wakeup_ti // lf_disable_interrupts_nested(); // if (!_lf_async_event) { - // return 0; + // return 0; // } else { // LF_PRINT_DEBUG(" *The STM32 rises from sleep* \n"); // return -1; @@ -157,15 +156,11 @@ int _lf_interruptable_sleep_until_locked(environment_t *env, instant_t wakeup_ti instant_t now; do { - _lf_clock_now(&now); + _lf_clock_now(&now); } while (now < wakeup_time); return 0; } - - - - // + -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- + // | Code for enabling and disabling Interrupts // + -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- + @@ -204,59 +199,53 @@ int _lf_unthreaded_notify_of_event() { return 0; } -int test_func(void){ - return 5; +int test_func(void) { + return 5; } // + -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- + // | Other functions I found -> taken from the generated main.c // + -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- + +void SystemClock_Config(void) { + RCC_OscInitTypeDef RCC_OscInitStruct = {0}; + RCC_ClkInitTypeDef RCC_ClkInitStruct = {0}; + + /** Configure the main internal regulator output voltage + */ + __HAL_RCC_PWR_CLK_ENABLE(); + __HAL_PWR_VOLTAGESCALING_CONFIG(PWR_REGULATOR_VOLTAGE_SCALE3); + + /** Initializes the RCC Oscillators according to the specified parameters + * in the RCC_OscInitTypeDef structure. + */ + RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSI; + RCC_OscInitStruct.HSIState = RCC_HSI_ON; + RCC_OscInitStruct.HSICalibrationValue = RCC_HSICALIBRATION_DEFAULT; + RCC_OscInitStruct.PLL.PLLState = RCC_PLL_NONE; + if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK) { + Error_Handler(); + } + + /** Initializes the CPU, AHB and APB buses clocks + */ + RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK | RCC_CLOCKTYPE_SYSCLK | RCC_CLOCKTYPE_PCLK1 | RCC_CLOCKTYPE_PCLK2; + RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_HSI; + RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1; + RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV1; + RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1; + + if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_0) != HAL_OK) { + Error_Handler(); + } +} -// void SystemClock_Config(void) { -// RCC_OscInitTypeDef RCC_OscInitStruct = {0}; -// RCC_ClkInitTypeDef RCC_ClkInitStruct = {0}; - -// /** Configure the main internal regulator output voltage -// */ -// __HAL_RCC_PWR_CLK_ENABLE(); -// __HAL_PWR_VOLTAGESCALING_CONFIG(PWR_REGULATOR_VOLTAGE_SCALE3); - -// /** Initializes the RCC Oscillators according to the specified parameters -// * in the RCC_OscInitTypeDef structure. -// */ -// RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSI; -// RCC_OscInitStruct.HSIState = RCC_HSI_ON; -// RCC_OscInitStruct.HSICalibrationValue = RCC_HSICALIBRATION_DEFAULT; -// RCC_OscInitStruct.PLL.PLLState = RCC_PLL_NONE; -// if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK) -// { -// Error_Handler(); -// } - -// /** Initializes the CPU, AHB and APB buses clocks -// */ -// RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK | RCC_CLOCKTYPE_SYSCLK | RCC_CLOCKTYPE_PCLK1 | RCC_CLOCKTYPE_PCLK2; -// RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_HSI; -// RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1; -// RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV1; -// RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1; - -// if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_0) != HAL_OK) -// { -// Error_Handler(); -// } -// } - - -// void Error_Handler(void) -// { -// /* USER CODE BEGIN Error_Handler_Debug */ -// /* User can add his own implementation to report the HAL error return state */ -// __disable_irq(); -// while (1) -// { -// } -// /* USER CODE END Error_Handler_Debug */ -// } +void Error_Handler(void) { + /* USER CODE BEGIN Error_Handler_Debug */ + /* User can add his own implementation to report the HAL error return state */ + __disable_irq(); + while (1) { + } + /* USER CODE END Error_Handler_Debug */ +} #endif \ No newline at end of file From 8a97bcd06cb8617572ad9ca899f8c67a2f90d710 Mon Sep 17 00:00:00 2001 From: naichenzhao Date: Sun, 4 Aug 2024 20:41:44 -0700 Subject: [PATCH 16/38] changes --- core/CMakeLists.txt | 44 ------------ .../impl/src/lf_STM32f4_support.c | 70 +++++++++---------- 2 files changed, 34 insertions(+), 80 deletions(-) diff --git a/core/CMakeLists.txt b/core/CMakeLists.txt index 56654e3b4..6c7f0ffe7 100644 --- a/core/CMakeLists.txt +++ b/core/CMakeLists.txt @@ -185,47 +185,3 @@ define(LF_FILE_SEPARATOR) define(WORKERS_NEEDED_FOR_FEDERATE) define(LF_ENCLAVES) - -# ========================================================== -# Additional support for stm32 -# ========================================================== - -if(${CMAKE_SYSTEM_NAME} MATCHES "Stm32") - set(CPU_PARAMETERS - -mcpu=cortex-m4 - -mthumb - -mfpu=fpv4-sp-d16 - -mfloat-abi=softfp ) - - set(MCU_FAMILY STM32F4xx ) - set(MCU_MODEL STM32F446xx ) - - target_compile_definitions(core PRIVATE - ${MCU_MODEL} - USE_HAL_DRIVER ) - - target_compile_options(core PRIVATE - ${CPU_PARAMETERS} - -Wall - -Wextra - -Wpedantic - -Wno-unused-parameter - $<$: - -Wno-volatile - -Wold-style-cast - -Wuseless-cast - -Wsuggest-override> - $<$:-Og -g3 -ggdb> - $<$:-Og -g0> ) - - set(CUBEMX_INCLUDE_DIRECTORIES - ../STM_sdk/Core/Inc - ../STM_sdk/Drivers/${MCU_FAMILY}_HAL_Driver/Inc - ../STM_sdk/Drivers/${MCU_FAMILY}_HAL_Driver/Inc/Legacy - ../STM_sdk/Drivers/CMSIS/Device/ST/${MCU_FAMILY}/Include - ../STM_sdk/Drivers/CMSIS/Include ) - - target_include_directories(core PUBLIC - ${CUBEMX_INCLUDE_DIRECTORIES} ) -endif() -# ========================================================== diff --git a/low_level_platform/impl/src/lf_STM32f4_support.c b/low_level_platform/impl/src/lf_STM32f4_support.c index dcd944113..01eed54e0 100644 --- a/low_level_platform/impl/src/lf_STM32f4_support.c +++ b/low_level_platform/impl/src/lf_STM32f4_support.c @@ -119,46 +119,44 @@ static void lf_busy_wait_until(instant_t wakeup_time) { // I am pretty sure this function doesnt work // Ill try to fix it once i know what the fuck its supposed to do, LOL -int _lf_interruptable_sleep_until_locked(environment_t *env, instant_t wakeup_time) { - // // Get the current time and sleep time - // instant_t now; - // _lf_clock_now(&now); - // interval_t duration = wakeup_time - now; - - // // Edge case handling for super small duration - // if (duration <= 0) { - // return 0; - // } else if (duration < 10) { - // lf_busy_wait_until(wakeup_time); - // return 0; - // } - - // // Enable interrupts and prepare to wait - // _lf_async_event = false; - // instant_t curr; - // lf_enable_interrupts_nested(); - - // do { - // _lf_clock_now(&curr); - - // // Exit wither when the timer is up or there is an exception - // } while (!_lf_async_event && (now < wakeup_time)); - - // // Disable interrupts again on exit - // lf_disable_interrupts_nested(); - - // if (!_lf_async_event) { - // return 0; - // } else { - // LF_PRINT_DEBUG(" *The STM32 rises from sleep* \n"); - // return -1; - // } +/* sleep until wakeup time + But, wake up if there is an async event +*/ +int _lf_interruptable_sleep_until_locked(environment_t *env, instant_t wakeup_time) { + // Get the current time and sleep time instant_t now; + _lf_clock_now(&now); + interval_t duration = wakeup_time - now; + + // Edge case handling for super small duration + if (duration <= 0) { + return 0; + } else if (duration < 10) { + lf_busy_wait_until(wakeup_time); + return 0; + } + + // Enable interrupts and prepare to wait + _lf_async_event = false; + lf_enable_interrupts_nested(); + do { _lf_clock_now(&now); - } while (now < wakeup_time); - return 0; + + // Exit when the timer is up or there is an exception + } while (!_lf_async_event && (now < wakeup_time)); + + // Disable interrupts again on exit + lf_disable_interrupts_nested(); + + if (!_lf_async_event) { + return 0; + } else { + LF_PRINT_DEBUG(" *The STM32 rises from sleep* \n"); + return -1; + } + } // + -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- + From c46fbccb308529501bac7c58433294119718c922 Mon Sep 17 00:00:00 2001 From: Naichen Zhao Date: Thu, 7 Dec 2023 15:09:47 -0800 Subject: [PATCH 17/38] fixed printing --- low_level_platform/impl/src/lf_STM32f4_support.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/low_level_platform/impl/src/lf_STM32f4_support.c b/low_level_platform/impl/src/lf_STM32f4_support.c index 01eed54e0..a0dd01ae9 100644 --- a/low_level_platform/impl/src/lf_STM32f4_support.c +++ b/low_level_platform/impl/src/lf_STM32f4_support.c @@ -28,6 +28,8 @@ static uint32_t _lf_time_us_high = 0; #define COMBINE_HI_LO(hi, lo) ((((uint64_t)hi) << 32) | ((uint64_t)lo)) +void lf_SystemClock_Config(); +void Error_Handler(); // + -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- + // | Code for timer functions @@ -37,7 +39,7 @@ static uint32_t _lf_time_us_high = 0; void _lf_initialize_clock(void) { // Standard initializations from generated code HAL_Init(); - SystemClock_Config(); + lf_SystemClock_Config(); // Configure TIM5 as our 32-bit clock timer __HAL_RCC_TIM5_CLK_ENABLE(); // initialize counter @@ -204,7 +206,7 @@ int test_func(void) { // + -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- + // | Other functions I found -> taken from the generated main.c // + -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- + -void SystemClock_Config(void) { +void lf_SystemClock_Config(void) { RCC_OscInitTypeDef RCC_OscInitStruct = {0}; RCC_ClkInitTypeDef RCC_ClkInitStruct = {0}; From b3097a894ec3bfe979cefd3333029a8caae07d21 Mon Sep 17 00:00:00 2001 From: Naichen Zhao Date: Mon, 18 Dec 2023 14:49:25 -0800 Subject: [PATCH 18/38] changed naming --- low_level_platform/impl/src/lf_STM32f4_support.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/low_level_platform/impl/src/lf_STM32f4_support.c b/low_level_platform/impl/src/lf_STM32f4_support.c index a0dd01ae9..77f0d9add 100644 --- a/low_level_platform/impl/src/lf_STM32f4_support.c +++ b/low_level_platform/impl/src/lf_STM32f4_support.c @@ -194,7 +194,7 @@ int lf_enable_interrupts_nested() { return 0; } -int _lf_unthreaded_notify_of_event() { +int _lf_single_threaded_notify_of_event() { _lf_async_event = true; return 0; } From f92307f044e9fd48ff90b313a8872b2325360b41 Mon Sep 17 00:00:00 2001 From: naichenzhao Date: Sun, 14 Jul 2024 19:04:28 -0700 Subject: [PATCH 19/38] updated sleep functions --- .../impl/src/lf_STM32f4_support.c | 33 ++++++++++--------- 1 file changed, 18 insertions(+), 15 deletions(-) diff --git a/low_level_platform/impl/src/lf_STM32f4_support.c b/low_level_platform/impl/src/lf_STM32f4_support.c index 77f0d9add..5f8dcfd85 100644 --- a/low_level_platform/impl/src/lf_STM32f4_support.c +++ b/low_level_platform/impl/src/lf_STM32f4_support.c @@ -92,8 +92,8 @@ int _lf_clock_now(instant_t *t) } /** - * Make the STM32 go honk shoo mimimi for set nanoseconds - * I essentially stole this from the lf_nrf52 support + * Make the STM32 sleep for set nanoseconds + * Based on the lf_nrf52 support implementation */ int lf_sleep(interval_t sleep_duration) { instant_t target_time; @@ -101,6 +101,12 @@ int lf_sleep(interval_t sleep_duration) { _lf_clock_now(¤t_time); target_time = current_time + sleep_duration; + + // HAL_Delay only supports miliseconds. We try to use that for as long as possible + // before switching to another meothd for finer tuned delay times + long delaytime_ms = sleep_duration / 1000000; + HAL_Delay(delaytime_ms); + while (current_time <= target_time) _lf_clock_now(¤t_time); @@ -108,22 +114,20 @@ int lf_sleep(interval_t sleep_duration) { } /** - * Make the STM32 go honk shoo honk shoo for set nanoseconds - * This one uses a do-while loop. :) - * I essentially stole this from the lf_nrf52 support + * Make the STM32 sleep for set nanoseconds + * Based on the lf_nrf52 support implementation */ static void lf_busy_wait_until(instant_t wakeup_time) { - instant_t now; - do { - _lf_clock_now(&now); - } while (now < wakeup_time); + instant_t current_time; + _lf_clock_now(¤t_time); + + // We repurpose the lf_sleep function here, just to better streamline the code + interval_t sleep_duration = wakeup_time - current_time; + lf_sleep(sleep_duration); } // I am pretty sure this function doesnt work -// Ill try to fix it once i know what the fuck its supposed to do, LOL -/* sleep until wakeup time - But, wake up if there is an async event - +/* sleep until wakeup time but wake up if there is an async event */ int _lf_interruptable_sleep_until_locked(environment_t *env, instant_t wakeup_time) { // Get the current time and sleep time @@ -134,7 +138,7 @@ int _lf_interruptable_sleep_until_locked(environment_t *env, instant_t wakeup_ti // Edge case handling for super small duration if (duration <= 0) { return 0; - } else if (duration < 10) { + } else if (duration < LF_MIN_SLEEP_NS) { lf_busy_wait_until(wakeup_time); return 0; } @@ -145,7 +149,6 @@ int _lf_interruptable_sleep_until_locked(environment_t *env, instant_t wakeup_ti do { _lf_clock_now(&now); - // Exit when the timer is up or there is an exception } while (!_lf_async_event && (now < wakeup_time)); From f2554ddc1d925b38a2ae3672b91da5f416cc6754 Mon Sep 17 00:00:00 2001 From: naichenzhao Date: Sun, 14 Jul 2024 19:46:32 -0700 Subject: [PATCH 20/38] updated delay functions --- .../impl/src/lf_STM32f4_support.c | 36 ++++++++----------- 1 file changed, 15 insertions(+), 21 deletions(-) diff --git a/low_level_platform/impl/src/lf_STM32f4_support.c b/low_level_platform/impl/src/lf_STM32f4_support.c index 5f8dcfd85..fa2099554 100644 --- a/low_level_platform/impl/src/lf_STM32f4_support.c +++ b/low_level_platform/impl/src/lf_STM32f4_support.c @@ -1,7 +1,5 @@ #if defined(PLATFORM_STM32F4) -/************* - I hope this software works LOL - ***************/ + #include "lf_STM32f4_support.h" #include "platform.h" @@ -15,15 +13,14 @@ static volatile bool _lf_sleep_interrupted = false; static volatile bool _lf_async_event = false; -#define LF_MAX_SLEEP_NS USEC(UINT32_MAX) -#define LF_MIN_SLEEP_NS USEC(5) - // nested critical section counter static uint32_t _lf_num_nested_crit_sec = 0; // Timer upper half (for overflow) static uint32_t _lf_time_us_high = 0; +#define LF_MIN_SLEEP_NS 10 + // Combine 2 32bit works to a 64 bit word (Takes from nrf52 support) #define COMBINE_HI_LO(hi, lo) ((((uint64_t)hi) << 32) | ((uint64_t)lo)) @@ -34,8 +31,7 @@ void Error_Handler(); // + -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- + // | Code for timer functions // + -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- + - -// We use timer 5 for our clock (probably better than fucking with sysTick) +// We use timer 5 for our clock (probably better than dealing with sysTick) void _lf_initialize_clock(void) { // Standard initializations from generated code HAL_Init(); @@ -63,9 +59,7 @@ void _lf_initialize_clock(void) { TIM5->CNT = 0xFFFFFFFE; } -/** - * ISR for handling timer overflow -> We increment the upper timer - */ +// ISR for handling timer overflow -> We increment the upper timer void TIM5_IRQHandler(void) { if (TIM5->SR & (1 << 1)) { TIM5->SR &= ~(1 << 1); @@ -73,6 +67,7 @@ void TIM5_IRQHandler(void) { } } + /** * Write the time since boot into time variable */ @@ -80,7 +75,8 @@ int _lf_clock_now(instant_t *t) { // Timer is cooked if (!t) { - return -1; + return 1; + } // Get the current microseconds from TIM5 uint32_t _lf_time_us_low = TIM5->CNT; @@ -101,7 +97,6 @@ int lf_sleep(interval_t sleep_duration) { _lf_clock_now(¤t_time); target_time = current_time + sleep_duration; - // HAL_Delay only supports miliseconds. We try to use that for as long as possible // before switching to another meothd for finer tuned delay times long delaytime_ms = sleep_duration / 1000000; @@ -158,8 +153,8 @@ int _lf_interruptable_sleep_until_locked(environment_t *env, instant_t wakeup_ti if (!_lf_async_event) { return 0; } else { - LF_PRINT_DEBUG(" *The STM32 rises from sleep* \n"); - return -1; + return 1; + } } @@ -182,7 +177,8 @@ int lf_disable_interrupts_nested() { // enables the IRQ (checks if other programs still want it disabled first) int lf_enable_interrupts_nested() { - // Somebody fucked up, LOL + // Left the critical section more often than it was entered. + if (_lf_num_nested_crit_sec <= 0) { return 1; } @@ -202,17 +198,14 @@ int _lf_single_threaded_notify_of_event() { return 0; } -int test_func(void) { - return 5; -} - // + -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- + -// | Other functions I found -> taken from the generated main.c +// | Other functions -> taken from the generated main.c // + -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- + void lf_SystemClock_Config(void) { RCC_OscInitTypeDef RCC_OscInitStruct = {0}; RCC_ClkInitTypeDef RCC_ClkInitStruct = {0}; + /** Configure the main internal regulator output voltage */ __HAL_RCC_PWR_CLK_ENABLE(); @@ -249,6 +242,7 @@ void Error_Handler(void) { while (1) { } /* USER CODE END Error_Handler_Debug */ + } #endif \ No newline at end of file From cd0c9c1bfc96ddf0397665a4ba31d6d125dadd7e Mon Sep 17 00:00:00 2001 From: naichenzhao Date: Sat, 31 Aug 2024 13:47:40 -0700 Subject: [PATCH 21/38] quick commit --- core/platform/CMakeLists.txt | 38 --- core/platform/Platform.cmake | 20 -- core/platform/lf_STM32f4_support.c | 248 ------------------ low_level_platform/api/CMakeLists.txt | 30 +++ low_level_platform/api/low_level_platform.h | 2 + low_level_platform/impl/CMakeLists.txt | 5 + .../impl/src/lf_STM32f4_support.c | 5 +- 7 files changed, 39 insertions(+), 309 deletions(-) delete mode 100644 core/platform/CMakeLists.txt delete mode 100644 core/platform/Platform.cmake delete mode 100644 core/platform/lf_STM32f4_support.c diff --git a/core/platform/CMakeLists.txt b/core/platform/CMakeLists.txt deleted file mode 100644 index 949d65177..000000000 --- a/core/platform/CMakeLists.txt +++ /dev/null @@ -1,38 +0,0 @@ -# Check which system we are running on to select the correct platform support -# file and assign the file's path to LF_PLATFORM_FILE - -set(LF_PLATFORM_FILES -lf_unix_clock_support.c -lf_unix_syscall_support.c -lf_linux_support.c -lf_macos_support.c -lf_windows_support.c -lf_nrf52_support.c -lf_zephyr_support.c -lf_zephyr_clock_counter.c -lf_zephyr_clock_kernel.c -lf_rp2040_support.c -lf_STM32f4_support.c -) - -if(${CMAKE_SYSTEM_NAME} STREQUAL "Windows") - set(CMAKE_SYSTEM_VERSION 10.0) - message("Using Windows SDK version ${CMAKE_VS_WINDOWS_TARGET_PLATFORM_VERSION}") -elseif(${CMAKE_SYSTEM_NAME} STREQUAL "Nrf52") - target_compile_definitions(core PUBLIC PLATFORM_NRF52) -elseif(${CMAKE_SYSTEM_NAME} STREQUAL "Zephyr") - target_compile_definitions(core PUBLIC PLATFORM_ZEPHYR) -elseif(${CMAKE_SYSTEM_NAME} STREQUAL "Stm32") - target_compile_definitions(core PUBLIC PLATFORM_STM32F4) -elseif(${CMAKE_SYSTEM_NAME} STREQUAL "Rp2040") - target_compile_definitions(core PUBLIC PLATFORM_RP2040) -endif() - -# Add sources to the list for debug info -list(APPEND INFO_SOURCES ${LF_PLATFORM_FILES}) - -# Prepend all sources with platform -list(TRANSFORM LF_PLATFORM_FILES PREPEND platform/) - -# Add sources to core lib -target_sources(core PRIVATE ${LF_PLATFORM_FILES}) diff --git a/core/platform/Platform.cmake b/core/platform/Platform.cmake deleted file mode 100644 index 2d082bce6..000000000 --- a/core/platform/Platform.cmake +++ /dev/null @@ -1,20 +0,0 @@ -# Check which system we are running on to select the correct platform support -# file and assign the file's path to LF_PLATFORM_FILE -if(${CMAKE_SYSTEM_NAME} STREQUAL "Linux") - set(LF_PLATFORM_FILE lf_linux_support.c) -elseif(${CMAKE_SYSTEM_NAME} STREQUAL "Darwin") - set(LF_PLATFORM_FILE lf_macos_support.c) -elseif(${CMAKE_SYSTEM_NAME} STREQUAL "Windows") - set(LF_PLATFORM_FILE lf_windows_support.c) - set(CMAKE_SYSTEM_VERSION 10.0) - message("Using Windows SDK version ${CMAKE_VS_WINDOWS_TARGET_PLATFORM_VERSION}") -elseif(${CMAKE_SYSTEM_NAME} STREQUAL "Zephyr") - set(LF_PLATFORM_FILE lf_zephyr_support.c) -elseif(${CMAKE_SYSTEM_NAME} STREQUAL "Stm32") - set(LF_PLATFORM_FILE lf_STM32f4_support.c) -elseif(${CMAKE_SYSTEM_NAME} STREQUAL "Rp2040") - message("Using pico-sdk for RP2040 target") - set(LF_PLATFORM_FILE lf_rp2040_support.c) -else() - message(FATAL_ERROR "Your platform is not supported! The C target supports Linux, MacOS and Windows.") -endif() diff --git a/core/platform/lf_STM32f4_support.c b/core/platform/lf_STM32f4_support.c deleted file mode 100644 index fa2099554..000000000 --- a/core/platform/lf_STM32f4_support.c +++ /dev/null @@ -1,248 +0,0 @@ -#if defined(PLATFORM_STM32F4) - - -#include "lf_STM32f4_support.h" -#include "platform.h" -#include "utils/util.h" -#include "tag.h" - -// + -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- + -// | Important defines and global variables -// + -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- + - -static volatile bool _lf_sleep_interrupted = false; -static volatile bool _lf_async_event = false; - -// nested critical section counter -static uint32_t _lf_num_nested_crit_sec = 0; - -// Timer upper half (for overflow) -static uint32_t _lf_time_us_high = 0; - -#define LF_MIN_SLEEP_NS 10 - -// Combine 2 32bit works to a 64 bit word (Takes from nrf52 support) -#define COMBINE_HI_LO(hi, lo) ((((uint64_t)hi) << 32) | ((uint64_t)lo)) - - -void lf_SystemClock_Config(); -void Error_Handler(); - -// + -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- + -// | Code for timer functions -// + -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- + -// We use timer 5 for our clock (probably better than dealing with sysTick) -void _lf_initialize_clock(void) { - // Standard initializations from generated code - HAL_Init(); - lf_SystemClock_Config(); - - // Configure TIM5 as our 32-bit clock timer - __HAL_RCC_TIM5_CLK_ENABLE(); // initialize counter - TIM5->CR1 = TIM_CR1_CEN; // enable counter - - // set prescaler to (16 - 1) = 15 - // CPU runs a 16MHz so timer ticks at 1MHz - // Which means period of 1 microsecond - TIM5->PSC = 15; - - // Setup ISR to increment upper bits - TIM5->DIER |= TIM_DIER_CC1IE; - NVIC_EnableIRQ(TIM5_IRQn); - - /* This is to make the Prescaler actually work - * For some reason, the Prescaler only kicks in once the timer has reset once. - * Thus, the current solution is to manually ret the value to a really large - * and force it to reset once. Its really jank but its the only way I could - * find to make it work - */ - TIM5->CNT = 0xFFFFFFFE; -} - -// ISR for handling timer overflow -> We increment the upper timer -void TIM5_IRQHandler(void) { - if (TIM5->SR & (1 << 1)) { - TIM5->SR &= ~(1 << 1); - _lf_time_us_high += 1; - } -} - - -/** - * Write the time since boot into time variable - */ -int _lf_clock_now(instant_t *t) -{ - // Timer is cooked - if (!t) { - return 1; - - } - // Get the current microseconds from TIM5 - uint32_t _lf_time_us_low = TIM5->CNT; - - // Combine upper and lower timers (Yoinked from lf_nrf52 support) - uint64_t now_us = COMBINE_HI_LO((_lf_time_us_high - 1), _lf_time_us_low); - *t = ((instant_t)now_us) * 1000; - return 0; -} - -/** - * Make the STM32 sleep for set nanoseconds - * Based on the lf_nrf52 support implementation - */ -int lf_sleep(interval_t sleep_duration) { - instant_t target_time; - instant_t current_time; - - _lf_clock_now(¤t_time); - target_time = current_time + sleep_duration; - // HAL_Delay only supports miliseconds. We try to use that for as long as possible - // before switching to another meothd for finer tuned delay times - long delaytime_ms = sleep_duration / 1000000; - HAL_Delay(delaytime_ms); - - while (current_time <= target_time) - _lf_clock_now(¤t_time); - - return 0; -} - -/** - * Make the STM32 sleep for set nanoseconds - * Based on the lf_nrf52 support implementation - */ -static void lf_busy_wait_until(instant_t wakeup_time) { - instant_t current_time; - _lf_clock_now(¤t_time); - - // We repurpose the lf_sleep function here, just to better streamline the code - interval_t sleep_duration = wakeup_time - current_time; - lf_sleep(sleep_duration); -} - -// I am pretty sure this function doesnt work -/* sleep until wakeup time but wake up if there is an async event -*/ -int _lf_interruptable_sleep_until_locked(environment_t *env, instant_t wakeup_time) { - // Get the current time and sleep time - instant_t now; - _lf_clock_now(&now); - interval_t duration = wakeup_time - now; - - // Edge case handling for super small duration - if (duration <= 0) { - return 0; - } else if (duration < LF_MIN_SLEEP_NS) { - lf_busy_wait_until(wakeup_time); - return 0; - } - - // Enable interrupts and prepare to wait - _lf_async_event = false; - lf_enable_interrupts_nested(); - - do { - _lf_clock_now(&now); - // Exit when the timer is up or there is an exception - } while (!_lf_async_event && (now < wakeup_time)); - - // Disable interrupts again on exit - lf_disable_interrupts_nested(); - - if (!_lf_async_event) { - return 0; - } else { - return 1; - - } - -} - -// + -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- + -// | Code for enabling and disabling Interrupts -// + -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- + - -// disables the IRQ (checks if its already disabled) -int lf_disable_interrupts_nested() { - // Disable interrupts if they are currently enabled - if (_lf_num_nested_crit_sec == 0) { - __disable_irq(); - } - - // update the depth of disabling interrupts - _lf_num_nested_crit_sec++; - return 0; -} - -// enables the IRQ (checks if other programs still want it disabled first) -int lf_enable_interrupts_nested() { - // Left the critical section more often than it was entered. - - if (_lf_num_nested_crit_sec <= 0) { - return 1; - } - - // update the depth of disabling interrupts - _lf_num_nested_crit_sec--; - - // If we have exited all important programs, we can enable them again - if (_lf_num_nested_crit_sec == 0) { - __enable_irq(); - } - return 0; -} - -int _lf_single_threaded_notify_of_event() { - _lf_async_event = true; - return 0; -} - -// + -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- + -// | Other functions -> taken from the generated main.c -// + -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- + -void lf_SystemClock_Config(void) { - RCC_OscInitTypeDef RCC_OscInitStruct = {0}; - RCC_ClkInitTypeDef RCC_ClkInitStruct = {0}; - - - /** Configure the main internal regulator output voltage - */ - __HAL_RCC_PWR_CLK_ENABLE(); - __HAL_PWR_VOLTAGESCALING_CONFIG(PWR_REGULATOR_VOLTAGE_SCALE3); - - /** Initializes the RCC Oscillators according to the specified parameters - * in the RCC_OscInitTypeDef structure. - */ - RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSI; - RCC_OscInitStruct.HSIState = RCC_HSI_ON; - RCC_OscInitStruct.HSICalibrationValue = RCC_HSICALIBRATION_DEFAULT; - RCC_OscInitStruct.PLL.PLLState = RCC_PLL_NONE; - if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK) { - Error_Handler(); - } - - /** Initializes the CPU, AHB and APB buses clocks - */ - RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK | RCC_CLOCKTYPE_SYSCLK | RCC_CLOCKTYPE_PCLK1 | RCC_CLOCKTYPE_PCLK2; - RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_HSI; - RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1; - RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV1; - RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1; - - if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_0) != HAL_OK) { - Error_Handler(); - } -} - -void Error_Handler(void) { - /* USER CODE BEGIN Error_Handler_Debug */ - /* User can add his own implementation to report the HAL error return state */ - __disable_irq(); - while (1) { - } - /* USER CODE END Error_Handler_Debug */ - -} - -#endif \ No newline at end of file diff --git a/low_level_platform/api/CMakeLists.txt b/low_level_platform/api/CMakeLists.txt index 599f87e59..18f774c14 100644 --- a/low_level_platform/api/CMakeLists.txt +++ b/low_level_platform/api/CMakeLists.txt @@ -14,6 +14,36 @@ elseif(${CMAKE_SYSTEM_NAME} STREQUAL "Rp2040") target_link_libraries(lf-low-level-platform-api INTERFACE pico_stdlib) target_link_libraries(lf-low-level-platform-api INTERFACE pico_multicore) target_link_libraries(lf-low-level-platform-api INTERFACE pico_sync) +elseif(${CMAKE_SYSTEM_NAME} STREQUAL "Stm32") + set(STM_DIR ${CMAKE_CURRENT_SOURCE_DIR}/../../../STM_sdk) + set(MCU_FAMILY STM32F4xx) + set(MCU_MODEL STM32F446xx) + set(CPU_PARAMETERS -mcpu=cortex-m4 -mthumb -mfpu=fpv4-sp-d16 -mfloat-abi=softfp) + + file(GLOB_RECURSE STM32CUBEMX_SOURCES ${STM_DIR}/Core/*.c ${STM_DIR}/Drivers/${MCU_FAMILY}_HAL_Driver/*.c) + set(CUBEMX_INCLUDE_DIRECTORIES + ${STM_DIR}/Core/Inc + ${STM_DIR}/Drivers/${MCU_FAMILY}_HAL_Driver/Inc + ${STM_DIR}/Drivers/CMSIS/Device/ST/${MCU_FAMILY}/Include + ${STM_DIR}/Drivers/CMSIS/Include + ) + target_compile_options(lf-low-level-platform-api INTERFACE + ${CPU_PARAMETERS} + -Wall + -Wextra + -Wpedantic + -Wno-unused-parameter + $<$: + -Wno-volatile + -Wold-style-cast + -Wuseless-cast + -Wsuggest-override> + $<$:-Og -g3 -ggdb> + $<$:-Og -g0>) + + target_compile_definitions(lf-low-level-platform-api INTERFACE PLATFORM_STM32F4) + target_include_directories(lf-low-level-platform-api INTERFACE ${CUBEMX_INCLUDE_DIRECTORIES}) + target_compile_definitions(lf-low-level-platform-api INTERFACE ${MCU_MODEL} USE_HAL_DRIVER) elseif(${CMAKE_SYSTEM_NAME} STREQUAL "FlexPRET") target_compile_definitions(lf-low-level-platform-api INTERFACE PLATFORM_FLEXPRET) target_link_libraries(lf-low-level-platform-api INTERFACE fp-sdk) diff --git a/low_level_platform/api/low_level_platform.h b/low_level_platform/api/low_level_platform.h index afffd2a9e..1b05e4073 100644 --- a/low_level_platform/api/low_level_platform.h +++ b/low_level_platform/api/low_level_platform.h @@ -52,6 +52,8 @@ int lf_critical_section_exit(environment_t* env); #include "platform/lf_patmos_support.h" #elif defined(PLATFORM_RP2040) #include "platform/lf_rp2040_support.h" +#elif defined(PLATFORM_STM32F4) +#include "platform/lf_STM32f4_support.h" #elif defined(PLATFORM_FLEXPRET) #include "platform/lf_flexpret_support.h" #elif defined(WIN32) || defined(_WIN32) || defined(__WIN32__) || defined(__NT__) diff --git a/low_level_platform/impl/CMakeLists.txt b/low_level_platform/impl/CMakeLists.txt index ac035dcf4..01d76d66e 100644 --- a/low_level_platform/impl/CMakeLists.txt +++ b/low_level_platform/impl/CMakeLists.txt @@ -39,6 +39,11 @@ elseif(${CMAKE_SYSTEM_NAME} STREQUAL "Rp2040") ${CMAKE_CURRENT_LIST_DIR}/src/lf_rp2040_support.c ${CMAKE_CURRENT_LIST_DIR}/src/lf_atomic_irq.c ) +elseif(${CMAKE_SYSTEM_NAME} STREQUAL "Stm32") + set(LF_LOW_LEVEL_PLATFORM_FILES + ${CMAKE_CURRENT_LIST_DIR}/src/lf_STM32f4_support.c + ${CMAKE_CURRENT_LIST_DIR}/src/lf_atomic_irq.c + ) elseif(${CMAKE_SYSTEM_NAME} STREQUAL "FlexPRET") set(LF_LOW_LEVEL_PLATFORM_FILES ${CMAKE_CURRENT_LIST_DIR}/src/lf_flexpret_support.c diff --git a/low_level_platform/impl/src/lf_STM32f4_support.c b/low_level_platform/impl/src/lf_STM32f4_support.c index fa2099554..3cc1a1632 100644 --- a/low_level_platform/impl/src/lf_STM32f4_support.c +++ b/low_level_platform/impl/src/lf_STM32f4_support.c @@ -1,9 +1,8 @@ #if defined(PLATFORM_STM32F4) -#include "lf_STM32f4_support.h" -#include "platform.h" -#include "utils/util.h" +#include "platform/lf_STM32f4_support.h" +#include "low_level_platform.h" #include "tag.h" // + -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- + From 6d8d4db636429dafdbd575e4a8c3b083b2cdb693 Mon Sep 17 00:00:00 2001 From: "Edward A. Lee" Date: Fri, 9 Aug 2024 16:27:12 -0400 Subject: [PATCH 22/38] Suppress unused parameter error From bb75db61f3fe91e5c6a15f45bf3c2e0496d75db6 Mon Sep 17 00:00:00 2001 From: "Edward A. Lee" Date: Fri, 9 Aug 2024 16:27:12 -0400 Subject: [PATCH 23/38] Suppress unused parameter error From 6a66f47aa02d875b342056debd2b70a2c5ad7ef5 Mon Sep 17 00:00:00 2001 From: naichenzhao Date: Sat, 31 Aug 2024 15:57:51 -0700 Subject: [PATCH 24/38] deleted artifact from rebase --- include/core/platform.h | 351 ---------------------------------------- 1 file changed, 351 deletions(-) delete mode 100644 include/core/platform.h diff --git a/include/core/platform.h b/include/core/platform.h deleted file mode 100644 index e615a0f0a..000000000 --- a/include/core/platform.h +++ /dev/null @@ -1,351 +0,0 @@ -/* Platform API support for the C target of Lingua Franca. */ - -/************* -Copyright (c) 2021, The University of California at Berkeley. - -Redistribution and use in source and binary forms, with or without modification, -are permitted provided that the following conditions are met: - -1. Redistributions of source code must retain the above copyright notice, - this list of conditions and the following disclaimer. - -2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY -EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF -MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL -THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, -PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, -STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF -THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -***************/ - -/** - * Platform API support for the C target of Lingua Franca. - * This file detects the platform on which the C compiler is being run - * (e.g. Windows, Linux, Mac) and conditionally includes platform-specific - * files that define core datatypes and function signatures for Lingua Franca. - * - * @author{Soroush Bateni } - */ - -#ifndef PLATFORM_H -#define PLATFORM_H - -#if defined(LF_THREADED) && defined(LF_UNTHREADED) -#error LF_UNTHREADED and LF_THREADED runtime requested -#endif - -#ifdef __cplusplus -extern "C" { -#endif - -#include "tag.h" -#include - -// Forward declarations -typedef struct environment_t environment_t; - -/** - * @brief Notify of new event by calling the unthreaded platform API - * @param env Environment in which we are executing. - */ -int lf_notify_of_event(environment_t* env); - -/** - * @brief Enter critical section by disabling interrupts - * @param env Environment in which we are executing. - */ -int lf_critical_section_enter(environment_t* env); - -/** - * @brief Leave a critical section by enabling interrupts - * @param env Environment in which we are executing. - */ -int lf_critical_section_exit(environment_t* env); - -#if defined(PLATFORM_ARDUINO) - #include "platform/lf_arduino_support.h" -#elif defined(PLATFORM_ZEPHYR) - #include "platform/lf_zephyr_support.h" -#elif defined(PLATFORM_NRF52) - #include "platform/lf_nrf52_support.h" -#elif defined(PLATFORM_STM32F4) - #include "platform/lf_STM32f4_support.h" -#elif defined(PLATFORM_RP2040) - #include "platform/lf_rp2040_support.h" -#elif defined(WIN32) || defined(_WIN32) || defined(__WIN32__) || defined(__NT__) - // Windows platforms - #include "lf_windows_support.h" -#elif __APPLE__ - // Apple platforms - #include "lf_macos_support.h" -#elif __linux__ - // Linux - #include "lf_linux_support.h" -#elif __unix__ // all unices not caught above - // Unix - #include "lf_POSIX_threads_support.h" -#elif defined(_POSIX_VERSION) - // POSIX - #include "lf_POSIX_threads_support.h" -#elif defined(__riscv) || defined(__riscv__) - // RISC-V (see https://github.com/riscv/riscv-toolchain-conventions) - #error "RISC-V not supported" -#else -#error "Platform not supported" -#endif - -#if !defined(LF_THREADED) - typedef void lf_mutex_t; -#endif - -#define LF_TIMEOUT 1 - - -// To support the unthreaded runtime, we need the following functions. They -// are not required by the threaded runtime and is thus hidden behind a #ifdef. -#if defined (LF_UNTHREADED) - /** - * @brief Disable interrupts with support for nested calls - * - * @return int - */ - int lf_disable_interrupts_nested(); - /** - * @brief Enable interrupts after potentially multiple callse to `lf_disable_interrupts_nested` - * - * @return int - */ - int lf_enable_interrupts_nested(); - - /** - * @brief Notify sleeping unthreaded context of new event - * - * @return int - */ - int _lf_unthreaded_notify_of_event(); -#endif - - -// For platforms with threading support, the following functions -// abstract the API so that the LF runtime remains portable. -#if defined LF_THREADED - - -/** - * @brief Get the number of cores on the host machine. - */ -int lf_available_cores(); - -/** - * Create a new thread, starting with execution of lf_thread - * getting passed arguments. The new handle is stored in thread_id. - * - * @return 0 on success, platform-specific error number otherwise. - * - */ -int lf_thread_create(lf_thread_t* thread, void *(*lf_thread) (void *), void* arguments); - -/** - * Make calling thread wait for termination of the thread. The - * exit status of the thread is stored in thread_return if thread_return - * is not NULL. - * @param thread The thread. - * @param thread_return A pointer to where to store the exit status of the thread. - * - * @return 0 on success, platform-specific error number otherwise. - */ -int lf_thread_join(lf_thread_t thread, void** thread_return); - -/** - * Initialize a mutex. - * - * @return 0 on success, platform-specific error number otherwise. - */ -int lf_mutex_init(lf_mutex_t* mutex); - -/** - * Lock a mutex. - * - * @return 0 on success, platform-specific error number otherwise. - */ -int lf_mutex_lock(lf_mutex_t* mutex); - -/** - * Unlock a mutex. - * - * @return 0 on success, platform-specific error number otherwise. - */ -int lf_mutex_unlock(lf_mutex_t* mutex); - -/** - * Initialize a conditional variable. - * - * @return 0 on success, platform-specific error number otherwise. - */ -int lf_cond_init(lf_cond_t* cond, lf_mutex_t* mutex); - -/** - * Wake up all threads waiting for condition variable cond. - * - * @return 0 on success, platform-specific error number otherwise. - */ -int lf_cond_broadcast(lf_cond_t* cond); - -/** - * Wake up one thread waiting for condition variable cond. - * - * @return 0 on success, platform-specific error number otherwise. - */ -int lf_cond_signal(lf_cond_t* cond); - -/** - * Wait for condition variable "cond" to be signaled or broadcast. - * "mutex" is assumed to be locked before. - * - * @return 0 on success, platform-specific error number otherwise. - */ -int lf_cond_wait(lf_cond_t* cond); - -/** - * Block current thread on the condition variable until condition variable - * pointed by "cond" is signaled or time pointed by "absolute_time_ns" in - * nanoseconds is reached. - * - * @return 0 on success, LF_TIMEOUT on timeout, and platform-specific error - * number otherwise. - */ -int lf_cond_timedwait(lf_cond_t* cond, instant_t absolute_time_ns); - -/* - * Atomically increment the variable that ptr points to by the given value, and return the original value of the variable. - * @param ptr A pointer to a variable. The value of this variable will be replaced with the result of the operation. - * @param value The value to be added to the variable pointed to by the ptr parameter. - * @return The original value of the variable that ptr points to (i.e., from before the application of this operation). - */ -#if defined(PLATFORM_ZEPHYR) -#define lf_atomic_fetch_add(ptr, value) _zephyr_atomic_fetch_add((int*) ptr, value) -#elif defined(WIN32) || defined(_WIN32) || defined(__WIN32__) || defined(__NT__) -// Assume that an integer is 32 bits. -#define lf_atomic_fetch_add(ptr, value) InterlockedExchangeAdd(ptr, value) -#elif defined(__GNUC__) || defined(__clang__) -#define lf_atomic_fetch_add(ptr, value) __sync_fetch_and_add(ptr, value) -#else -#error "Compiler not supported" -#endif - -/* - * Atomically increment the variable that ptr points to by the given value, and return the new value of the variable. - * @param ptr A pointer to a variable. The value of this variable will be replaced with the result of the operation. - * @param value The value to be added to the variable pointed to by the ptr parameter. - * @return The new value of the variable that ptr points to (i.e., from before the application of this operation). - */ -#if defined(PLATFORM_ZEPHYR) -#define lf_atomic_add_fetch(ptr, value) _zephyr_atomic_add_fetch((int*) ptr, value) -#elif defined(WIN32) || defined(_WIN32) || defined(__WIN32__) || defined(__NT__) -// Assume that an integer is 32 bits. -#define lf_atomic_add_fetch(ptr, value) InterlockedAdd(ptr, value) -#elif defined(__GNUC__) || defined(__clang__) -#define lf_atomic_add_fetch(ptr, value) __sync_add_and_fetch(ptr, value) -#else -#error "Compiler not supported" -#endif - -/* - * Atomically compare the variable that ptr points to against oldval. If the - * current value is oldval, then write newval into *ptr. - * @param ptr A pointer to a variable. - * @param oldval The value to compare against. - * @param newval The value to assign to *ptr if comparison is successful. - * @return True if comparison was successful. False otherwise. - */ -#if defined(PLATFORM_ZEPHYR) -#define lf_bool_compare_and_swap(ptr, value, newval) _zephyr_bool_compare_and_swap((bool*) ptr, value, newval) -#elif defined(WIN32) || defined(_WIN32) || defined(__WIN32__) || defined(__NT__) -// Assume that a boolean is represented with a 32-bit integer. -#define lf_bool_compare_and_swap(ptr, oldval, newval) (InterlockedCompareExchange(ptr, newval, oldval) == oldval) -#elif defined(__GNUC__) || defined(__clang__) -#define lf_bool_compare_and_swap(ptr, oldval, newval) __sync_bool_compare_and_swap(ptr, oldval, newval) -#else -#error "Compiler not supported" -#endif - -/* - * Atomically compare the 32-bit value that ptr points to against oldval. If the - * current value is oldval, then write newval into *ptr. - * @param ptr A pointer to a variable. - * @param oldval The value to compare against. - * @param newval The value to assign to *ptr if comparison is successful. - * @return The initial value of *ptr. - */ -#if defined(PLATFORM_ZEPHYR) -#define lf_val_compare_and_swap(ptr, value, newval) _zephyr_val_compare_and_swap((int*) ptr, value, newval) -#elif defined(WIN32) || defined(_WIN32) || defined(__WIN32__) || defined(__NT__) -#define lf_val_compare_and_swap(ptr, oldval, newval) InterlockedCompareExchange(ptr, newval, oldval) -#elif defined(__GNUC__) || defined(__clang__) -#define lf_val_compare_and_swap(ptr, oldval, newval) __sync_val_compare_and_swap(ptr, oldval, newval) -#else -#error "Compiler not supported" -#endif - -#endif - -/** - * Initialize the LF clock. Must be called before using other clock-related APIs. - */ -void _lf_initialize_clock(void); - -/** - * Fetch the value of an internal (and platform-specific) physical clock and - * store it in `t`. - * - * Ideally, the underlying platform clock should be monotonic. However, the - * core lib tries to enforce monotonicity at higher level APIs (see tag.h). - * - * @return 0 for success, or -1 for failure - */ -int _lf_clock_now(instant_t* t); - -/** - * Pause execution for a given duration. - * - * @return 0 for success, or -1 for failure. - */ -int lf_sleep(interval_t sleep_duration); - -/** - * @brief Sleep until the given wakeup time. Assumes the lock for the - * given environment is held - * - * @param env The environment within which to sleep. - * @param wakeup_time The time instant at which to wake up. - * @return int 0 if sleep completed, or -1 if it was interrupted. - */ -int _lf_interruptable_sleep_until_locked(environment_t* env, instant_t wakeup_time); - -/** - * Macros for marking function as deprecated - */ -#ifdef __GNUC__ - #define DEPRECATED(X) X __attribute__((deprecated)) -#elif defined(_MSC_VER) - #define DEPRECATED(X) __declspec(deprecated) X -#else - #define DEPRECATED(X) X -#endif - -/** - * @deprecated version of "lf_sleep" - */ -DEPRECATED(int lf_nanosleep(interval_t sleep_duration)); - -#ifdef __cplusplus -} -#endif - -#endif // PLATFORM_H From a285e528540bac6c75a21616cc2a21f1066c523c Mon Sep 17 00:00:00 2001 From: naichenzhao Date: Sat, 31 Aug 2024 16:52:33 -0700 Subject: [PATCH 25/38] works with newest version --- low_level_platform/impl/src/lf_STM32f4_support.c | 12 ++++++------ low_level_platform/impl/src/lf_atomic_irq.c | 2 +- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/low_level_platform/impl/src/lf_STM32f4_support.c b/low_level_platform/impl/src/lf_STM32f4_support.c index 3cc1a1632..d104b2284 100644 --- a/low_level_platform/impl/src/lf_STM32f4_support.c +++ b/low_level_platform/impl/src/lf_STM32f4_support.c @@ -70,7 +70,7 @@ void TIM5_IRQHandler(void) { /** * Write the time since boot into time variable */ -int _lf_clock_now(instant_t *t) +int _lf_clock_gettime(instant_t *t) { // Timer is cooked if (!t) { @@ -94,7 +94,7 @@ int lf_sleep(interval_t sleep_duration) { instant_t target_time; instant_t current_time; - _lf_clock_now(¤t_time); + _lf_clock_gettime(¤t_time); target_time = current_time + sleep_duration; // HAL_Delay only supports miliseconds. We try to use that for as long as possible // before switching to another meothd for finer tuned delay times @@ -102,7 +102,7 @@ int lf_sleep(interval_t sleep_duration) { HAL_Delay(delaytime_ms); while (current_time <= target_time) - _lf_clock_now(¤t_time); + _lf_clock_gettime(¤t_time); return 0; } @@ -113,7 +113,7 @@ int lf_sleep(interval_t sleep_duration) { */ static void lf_busy_wait_until(instant_t wakeup_time) { instant_t current_time; - _lf_clock_now(¤t_time); + _lf_clock_gettime(¤t_time); // We repurpose the lf_sleep function here, just to better streamline the code interval_t sleep_duration = wakeup_time - current_time; @@ -126,7 +126,7 @@ static void lf_busy_wait_until(instant_t wakeup_time) { int _lf_interruptable_sleep_until_locked(environment_t *env, instant_t wakeup_time) { // Get the current time and sleep time instant_t now; - _lf_clock_now(&now); + _lf_clock_gettime(&now); interval_t duration = wakeup_time - now; // Edge case handling for super small duration @@ -142,7 +142,7 @@ int _lf_interruptable_sleep_until_locked(environment_t *env, instant_t wakeup_ti lf_enable_interrupts_nested(); do { - _lf_clock_now(&now); + _lf_clock_gettime(&now); // Exit when the timer is up or there is an exception } while (!_lf_async_event && (now < wakeup_time)); diff --git a/low_level_platform/impl/src/lf_atomic_irq.c b/low_level_platform/impl/src/lf_atomic_irq.c index 3a9d72086..3ac073e91 100644 --- a/low_level_platform/impl/src/lf_atomic_irq.c +++ b/low_level_platform/impl/src/lf_atomic_irq.c @@ -1,5 +1,5 @@ #if defined(PLATFORM_ARDUINO) || defined(PLATFORM_NRF52) || defined(PLATFORM_ZEPHYR) || defined(PLATFORM_RP2040) || \ - defined(PLATFORM_FLEXPRET) || defined(PLATFORM_PATMOS) + defined(PLATFORM_FLEXPRET) || defined(PLATFORM_PATMOS) || defined(PLATFORM_STM32F4) /** * @author Erling Rennemo Jellum * @copyright (c) 2023 From 6ba0f42bd7787a43d06fd8afb2e444e449b9fe2f Mon Sep 17 00:00:00 2001 From: naichenzhao Date: Fri, 6 Sep 2024 19:12:42 -0700 Subject: [PATCH 26/38] did formatting --- .../impl/src/lf_STM32f4_support.c | 289 +++++++++--------- tag/api/tag.h | 6 +- 2 files changed, 142 insertions(+), 153 deletions(-) diff --git a/low_level_platform/impl/src/lf_STM32f4_support.c b/low_level_platform/impl/src/lf_STM32f4_support.c index d104b2284..ba6ca9c24 100644 --- a/low_level_platform/impl/src/lf_STM32f4_support.c +++ b/low_level_platform/impl/src/lf_STM32f4_support.c @@ -1,6 +1,5 @@ #if defined(PLATFORM_STM32F4) - #include "platform/lf_STM32f4_support.h" #include "low_level_platform.h" #include "tag.h" @@ -23,7 +22,6 @@ static uint32_t _lf_time_us_high = 0; // Combine 2 32bit works to a 64 bit word (Takes from nrf52 support) #define COMBINE_HI_LO(hi, lo) ((((uint64_t)hi) << 32) | ((uint64_t)lo)) - void lf_SystemClock_Config(); void Error_Handler(); @@ -32,58 +30,55 @@ void Error_Handler(); // + -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- + // We use timer 5 for our clock (probably better than dealing with sysTick) void _lf_initialize_clock(void) { - // Standard initializations from generated code - HAL_Init(); - lf_SystemClock_Config(); - - // Configure TIM5 as our 32-bit clock timer - __HAL_RCC_TIM5_CLK_ENABLE(); // initialize counter - TIM5->CR1 = TIM_CR1_CEN; // enable counter - - // set prescaler to (16 - 1) = 15 - // CPU runs a 16MHz so timer ticks at 1MHz - // Which means period of 1 microsecond - TIM5->PSC = 15; - - // Setup ISR to increment upper bits - TIM5->DIER |= TIM_DIER_CC1IE; - NVIC_EnableIRQ(TIM5_IRQn); - - /* This is to make the Prescaler actually work - * For some reason, the Prescaler only kicks in once the timer has reset once. - * Thus, the current solution is to manually ret the value to a really large - * and force it to reset once. Its really jank but its the only way I could - * find to make it work - */ - TIM5->CNT = 0xFFFFFFFE; + // Standard initializations from generated code + HAL_Init(); + lf_SystemClock_Config(); + + // Configure TIM5 as our 32-bit clock timer + __HAL_RCC_TIM5_CLK_ENABLE(); // initialize counter + TIM5->CR1 = TIM_CR1_CEN; // enable counter + + // set prescaler to (16 - 1) = 15 + // CPU runs a 16MHz so timer ticks at 1MHz + // Which means period of 1 microsecond + TIM5->PSC = 15; + + // Setup ISR to increment upper bits + TIM5->DIER |= TIM_DIER_CC1IE; + NVIC_EnableIRQ(TIM5_IRQn); + + /* This is to make the Prescaler actually work + * For some reason, the Prescaler only kicks in once the timer has reset once. + * Thus, the current solution is to manually ret the value to a really large + * and force it to reset once. Its really jank but its the only way I could + * find to make it work + */ + TIM5->CNT = 0xFFFFFFFE; } // ISR for handling timer overflow -> We increment the upper timer void TIM5_IRQHandler(void) { - if (TIM5->SR & (1 << 1)) { - TIM5->SR &= ~(1 << 1); - _lf_time_us_high += 1; - } + if (TIM5->SR & (1 << 1)) { + TIM5->SR &= ~(1 << 1); + _lf_time_us_high += 1; + } } - /** * Write the time since boot into time variable */ -int _lf_clock_gettime(instant_t *t) -{ - // Timer is cooked - if (!t) { - return 1; - - } - // Get the current microseconds from TIM5 - uint32_t _lf_time_us_low = TIM5->CNT; - - // Combine upper and lower timers (Yoinked from lf_nrf52 support) - uint64_t now_us = COMBINE_HI_LO((_lf_time_us_high - 1), _lf_time_us_low); - *t = ((instant_t)now_us) * 1000; - return 0; +int _lf_clock_gettime(instant_t* t) { + // Timer is cooked + if (!t) { + return 1; + } + // Get the current microseconds from TIM5 + uint32_t _lf_time_us_low = TIM5->CNT; + + // Combine upper and lower timers (Yoinked from lf_nrf52 support) + uint64_t now_us = COMBINE_HI_LO((_lf_time_us_high - 1), _lf_time_us_low); + *t = ((instant_t)now_us) * 1000; + return 0; } /** @@ -91,20 +86,20 @@ int _lf_clock_gettime(instant_t *t) * Based on the lf_nrf52 support implementation */ int lf_sleep(interval_t sleep_duration) { - instant_t target_time; - instant_t current_time; + instant_t target_time; + instant_t current_time; - _lf_clock_gettime(¤t_time); - target_time = current_time + sleep_duration; - // HAL_Delay only supports miliseconds. We try to use that for as long as possible - // before switching to another meothd for finer tuned delay times - long delaytime_ms = sleep_duration / 1000000; - HAL_Delay(delaytime_ms); + _lf_clock_gettime(¤t_time); + target_time = current_time + sleep_duration; + // HAL_Delay only supports miliseconds. We try to use that for as long as possible + // before switching to another meothd for finer tuned delay times + long delaytime_ms = sleep_duration / 1000000; + HAL_Delay(delaytime_ms); - while (current_time <= target_time) - _lf_clock_gettime(¤t_time); + while (current_time <= target_time) + _lf_clock_gettime(¤t_time); - return 0; + return 0; } /** @@ -112,50 +107,48 @@ int lf_sleep(interval_t sleep_duration) { * Based on the lf_nrf52 support implementation */ static void lf_busy_wait_until(instant_t wakeup_time) { - instant_t current_time; - _lf_clock_gettime(¤t_time); + instant_t current_time; + _lf_clock_gettime(¤t_time); - // We repurpose the lf_sleep function here, just to better streamline the code - interval_t sleep_duration = wakeup_time - current_time; - lf_sleep(sleep_duration); + // We repurpose the lf_sleep function here, just to better streamline the code + interval_t sleep_duration = wakeup_time - current_time; + lf_sleep(sleep_duration); } // I am pretty sure this function doesnt work /* sleep until wakeup time but wake up if there is an async event -*/ -int _lf_interruptable_sleep_until_locked(environment_t *env, instant_t wakeup_time) { - // Get the current time and sleep time - instant_t now; - _lf_clock_gettime(&now); - interval_t duration = wakeup_time - now; - - // Edge case handling for super small duration - if (duration <= 0) { - return 0; - } else if (duration < LF_MIN_SLEEP_NS) { - lf_busy_wait_until(wakeup_time); - return 0; - } - - // Enable interrupts and prepare to wait - _lf_async_event = false; - lf_enable_interrupts_nested(); - - do { - _lf_clock_gettime(&now); - // Exit when the timer is up or there is an exception - } while (!_lf_async_event && (now < wakeup_time)); + */ +int _lf_interruptable_sleep_until_locked(environment_t* env, instant_t wakeup_time) { + // Get the current time and sleep time + instant_t now; + _lf_clock_gettime(&now); + interval_t duration = wakeup_time - now; + + // Edge case handling for super small duration + if (duration <= 0) { + return 0; + } else if (duration < LF_MIN_SLEEP_NS) { + lf_busy_wait_until(wakeup_time); + return 0; + } - // Disable interrupts again on exit - lf_disable_interrupts_nested(); + // Enable interrupts and prepare to wait + _lf_async_event = false; + lf_enable_interrupts_nested(); - if (!_lf_async_event) { - return 0; - } else { - return 1; + do { + _lf_clock_gettime(&now); + // Exit when the timer is up or there is an exception + } while (!_lf_async_event && (now < wakeup_time)); - } + // Disable interrupts again on exit + lf_disable_interrupts_nested(); + if (!_lf_async_event) { + return 0; + } else { + return 1; + } } // + -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- + @@ -164,84 +157,82 @@ int _lf_interruptable_sleep_until_locked(environment_t *env, instant_t wakeup_ti // disables the IRQ (checks if its already disabled) int lf_disable_interrupts_nested() { - // Disable interrupts if they are currently enabled - if (_lf_num_nested_crit_sec == 0) { - __disable_irq(); - } + // Disable interrupts if they are currently enabled + if (_lf_num_nested_crit_sec == 0) { + __disable_irq(); + } - // update the depth of disabling interrupts - _lf_num_nested_crit_sec++; - return 0; + // update the depth of disabling interrupts + _lf_num_nested_crit_sec++; + return 0; } // enables the IRQ (checks if other programs still want it disabled first) int lf_enable_interrupts_nested() { - // Left the critical section more often than it was entered. + // Left the critical section more often than it was entered. - if (_lf_num_nested_crit_sec <= 0) { - return 1; - } + if (_lf_num_nested_crit_sec <= 0) { + return 1; + } - // update the depth of disabling interrupts - _lf_num_nested_crit_sec--; + // update the depth of disabling interrupts + _lf_num_nested_crit_sec--; - // If we have exited all important programs, we can enable them again - if (_lf_num_nested_crit_sec == 0) { - __enable_irq(); - } - return 0; + // If we have exited all important programs, we can enable them again + if (_lf_num_nested_crit_sec == 0) { + __enable_irq(); + } + return 0; } int _lf_single_threaded_notify_of_event() { - _lf_async_event = true; - return 0; + _lf_async_event = true; + return 0; } // + -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- + // | Other functions -> taken from the generated main.c // + -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- + void lf_SystemClock_Config(void) { - RCC_OscInitTypeDef RCC_OscInitStruct = {0}; - RCC_ClkInitTypeDef RCC_ClkInitStruct = {0}; - - - /** Configure the main internal regulator output voltage - */ - __HAL_RCC_PWR_CLK_ENABLE(); - __HAL_PWR_VOLTAGESCALING_CONFIG(PWR_REGULATOR_VOLTAGE_SCALE3); - - /** Initializes the RCC Oscillators according to the specified parameters - * in the RCC_OscInitTypeDef structure. - */ - RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSI; - RCC_OscInitStruct.HSIState = RCC_HSI_ON; - RCC_OscInitStruct.HSICalibrationValue = RCC_HSICALIBRATION_DEFAULT; - RCC_OscInitStruct.PLL.PLLState = RCC_PLL_NONE; - if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK) { - Error_Handler(); - } - - /** Initializes the CPU, AHB and APB buses clocks - */ - RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK | RCC_CLOCKTYPE_SYSCLK | RCC_CLOCKTYPE_PCLK1 | RCC_CLOCKTYPE_PCLK2; - RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_HSI; - RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1; - RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV1; - RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1; - - if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_0) != HAL_OK) { - Error_Handler(); - } + RCC_OscInitTypeDef RCC_OscInitStruct = {0}; + RCC_ClkInitTypeDef RCC_ClkInitStruct = {0}; + + /** Configure the main internal regulator output voltage + */ + __HAL_RCC_PWR_CLK_ENABLE(); + __HAL_PWR_VOLTAGESCALING_CONFIG(PWR_REGULATOR_VOLTAGE_SCALE3); + + /** Initializes the RCC Oscillators according to the specified parameters + * in the RCC_OscInitTypeDef structure. + */ + RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSI; + RCC_OscInitStruct.HSIState = RCC_HSI_ON; + RCC_OscInitStruct.HSICalibrationValue = RCC_HSICALIBRATION_DEFAULT; + RCC_OscInitStruct.PLL.PLLState = RCC_PLL_NONE; + if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK) { + Error_Handler(); + } + + /** Initializes the CPU, AHB and APB buses clocks + */ + RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK | RCC_CLOCKTYPE_SYSCLK | RCC_CLOCKTYPE_PCLK1 | RCC_CLOCKTYPE_PCLK2; + RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_HSI; + RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1; + RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV1; + RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1; + + if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_0) != HAL_OK) { + Error_Handler(); + } } void Error_Handler(void) { - /* USER CODE BEGIN Error_Handler_Debug */ - /* User can add his own implementation to report the HAL error return state */ - __disable_irq(); - while (1) { - } - /* USER CODE END Error_Handler_Debug */ - + /* USER CODE BEGIN Error_Handler_Debug */ + /* User can add his own implementation to report the HAL error return state */ + __disable_irq(); + while (1) { + } + /* USER CODE END Error_Handler_Debug */ } #endif \ No newline at end of file diff --git a/tag/api/tag.h b/tag/api/tag.h index c40e490f8..05d1a1822 100644 --- a/tag/api/tag.h +++ b/tag/api/tag.h @@ -37,13 +37,11 @@ #define NEVER_TAG \ (tag_t) { .time = NEVER, .microstep = NEVER_MICROSTEP } // Need a separate initializer expression to comply with some C compilers -#define NEVER_TAG_INITIALIZER \ - { NEVER, NEVER_MICROSTEP } +#define NEVER_TAG_INITIALIZER {NEVER, NEVER_MICROSTEP} #define FOREVER_TAG \ (tag_t) { .time = FOREVER, .microstep = FOREVER_MICROSTEP } // Need a separate initializer expression to comply with some C compilers -#define FOREVER_TAG_INITIALIZER \ - { FOREVER, FOREVER_MICROSTEP } +#define FOREVER_TAG_INITIALIZER {FOREVER, FOREVER_MICROSTEP} #define ZERO_TAG \ (tag_t) { .time = 0LL, .microstep = 0u } From a22a4fd0632277dc195cff9bd929d31417b285b5 Mon Sep 17 00:00:00 2001 From: Naichen <49353868+naichenzhao@users.noreply.github.com> Date: Mon, 16 Sep 2024 11:45:07 -0700 Subject: [PATCH 27/38] Update low_level_platform/api/platform/lf_STM32f4_support.h Co-authored-by: erling --- low_level_platform/api/platform/lf_STM32f4_support.h | 1 - 1 file changed, 1 deletion(-) diff --git a/low_level_platform/api/platform/lf_STM32f4_support.h b/low_level_platform/api/platform/lf_STM32f4_support.h index 063421d6d..c08a9fad0 100644 --- a/low_level_platform/api/platform/lf_STM32f4_support.h +++ b/low_level_platform/api/platform/lf_STM32f4_support.h @@ -8,7 +8,6 @@ #include -// Defines for formatting time in printf for pico #define PRINTF_TAG "(" PRINTF_TIME ", " PRINTF_MICROSTEP ")" #define PRINTF_TIME "%lld" #define PRINTF_MICROSTEP "%d" From 42fc2718eb71635de7e07026600dba0480703b8e Mon Sep 17 00:00:00 2001 From: Naichen <49353868+naichenzhao@users.noreply.github.com> Date: Mon, 16 Sep 2024 11:45:17 -0700 Subject: [PATCH 28/38] Update low_level_platform/api/platform/lf_STM32f4_support.h Co-authored-by: erling --- low_level_platform/api/platform/lf_STM32f4_support.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/low_level_platform/api/platform/lf_STM32f4_support.h b/low_level_platform/api/platform/lf_STM32f4_support.h index c08a9fad0..013d366dc 100644 --- a/low_level_platform/api/platform/lf_STM32f4_support.h +++ b/low_level_platform/api/platform/lf_STM32f4_support.h @@ -16,7 +16,7 @@ #define _LF_TIMEOUT 1 #ifdef LF_THREADED -#error "I have no idea how to support threading" +#error "Threaded runtime not supported on STM32" #endif // LF_THREADED #endif \ No newline at end of file From 895a8fb7019b8aedb9a9e0221ff9b07bb7d9bfaa Mon Sep 17 00:00:00 2001 From: Naichen <49353868+naichenzhao@users.noreply.github.com> Date: Mon, 16 Sep 2024 11:45:27 -0700 Subject: [PATCH 29/38] Update low_level_platform/impl/src/lf_STM32f4_support.c Co-authored-by: erling --- low_level_platform/impl/src/lf_STM32f4_support.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/low_level_platform/impl/src/lf_STM32f4_support.c b/low_level_platform/impl/src/lf_STM32f4_support.c index ba6ca9c24..185100720 100644 --- a/low_level_platform/impl/src/lf_STM32f4_support.c +++ b/low_level_platform/impl/src/lf_STM32f4_support.c @@ -155,7 +155,7 @@ int _lf_interruptable_sleep_until_locked(environment_t* env, instant_t wakeup_ti // | Code for enabling and disabling Interrupts // + -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- + -// disables the IRQ (checks if its already disabled) +// disables the IRQ with support for nested disabling int lf_disable_interrupts_nested() { // Disable interrupts if they are currently enabled if (_lf_num_nested_crit_sec == 0) { From 0d3af6d176fc2d0dc0f2ae0ce3b01146cd41bd43 Mon Sep 17 00:00:00 2001 From: Naichen <49353868+naichenzhao@users.noreply.github.com> Date: Mon, 16 Sep 2024 11:45:35 -0700 Subject: [PATCH 30/38] Update low_level_platform/api/platform/lf_STM32f4_support.h Co-authored-by: erling --- low_level_platform/api/platform/lf_STM32f4_support.h | 1 - 1 file changed, 1 deletion(-) diff --git a/low_level_platform/api/platform/lf_STM32f4_support.h b/low_level_platform/api/platform/lf_STM32f4_support.h index 013d366dc..061fbe449 100644 --- a/low_level_platform/api/platform/lf_STM32f4_support.h +++ b/low_level_platform/api/platform/lf_STM32f4_support.h @@ -3,7 +3,6 @@ #ifndef LF_STM32F4_SUPPORT_H #define LF_STM32F4_SUPPORT_H -// I have no idea what the fuck TTY is so i guess we dont support it #define NO_TTY #include From 50603d763b3092bc27e1f047b03496f270b24e8e Mon Sep 17 00:00:00 2001 From: Naichen <49353868+naichenzhao@users.noreply.github.com> Date: Mon, 16 Sep 2024 11:45:46 -0700 Subject: [PATCH 31/38] Update low_level_platform/impl/src/lf_STM32f4_support.c Co-authored-by: erling --- low_level_platform/impl/src/lf_STM32f4_support.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/low_level_platform/impl/src/lf_STM32f4_support.c b/low_level_platform/impl/src/lf_STM32f4_support.c index 185100720..d308473a2 100644 --- a/low_level_platform/impl/src/lf_STM32f4_support.c +++ b/low_level_platform/impl/src/lf_STM32f4_support.c @@ -75,7 +75,7 @@ int _lf_clock_gettime(instant_t* t) { // Get the current microseconds from TIM5 uint32_t _lf_time_us_low = TIM5->CNT; - // Combine upper and lower timers (Yoinked from lf_nrf52 support) + // Combine upper and lower timers uint64_t now_us = COMBINE_HI_LO((_lf_time_us_high - 1), _lf_time_us_low); *t = ((instant_t)now_us) * 1000; return 0; From cba919356d55bf0a36b3a94b56da2bacb5f41dae Mon Sep 17 00:00:00 2001 From: naichenzhao Date: Tue, 17 Sep 2024 14:57:21 -0700 Subject: [PATCH 32/38] resolved some more comments --- .../impl/src/lf_STM32f4_support.c | 25 ++++++------------- 1 file changed, 8 insertions(+), 17 deletions(-) diff --git a/low_level_platform/impl/src/lf_STM32f4_support.c b/low_level_platform/impl/src/lf_STM32f4_support.c index d308473a2..5ee1b08b0 100644 --- a/low_level_platform/impl/src/lf_STM32f4_support.c +++ b/low_level_platform/impl/src/lf_STM32f4_support.c @@ -102,20 +102,6 @@ int lf_sleep(interval_t sleep_duration) { return 0; } -/** - * Make the STM32 sleep for set nanoseconds - * Based on the lf_nrf52 support implementation - */ -static void lf_busy_wait_until(instant_t wakeup_time) { - instant_t current_time; - _lf_clock_gettime(¤t_time); - - // We repurpose the lf_sleep function here, just to better streamline the code - interval_t sleep_duration = wakeup_time - current_time; - lf_sleep(sleep_duration); -} - -// I am pretty sure this function doesnt work /* sleep until wakeup time but wake up if there is an async event */ int _lf_interruptable_sleep_until_locked(environment_t* env, instant_t wakeup_time) { @@ -128,7 +114,12 @@ int _lf_interruptable_sleep_until_locked(environment_t* env, instant_t wakeup_ti if (duration <= 0) { return 0; } else if (duration < LF_MIN_SLEEP_NS) { - lf_busy_wait_until(wakeup_time); + instant_t current_time; + _lf_clock_gettime(¤t_time); + + // We repurpose the lf_sleep function here, just to better streamline the code + interval_t sleep_duration = wakeup_time - current_time; + lf_sleep(sleep_duration); return 0; } @@ -167,7 +158,7 @@ int lf_disable_interrupts_nested() { return 0; } -// enables the IRQ (checks if other programs still want it disabled first) +// enables the IRQ (checks if other processes still want it disabled first) int lf_enable_interrupts_nested() { // Left the critical section more often than it was entered. @@ -178,7 +169,7 @@ int lf_enable_interrupts_nested() { // update the depth of disabling interrupts _lf_num_nested_crit_sec--; - // If we have exited all important programs, we can enable them again + // We enable interrupts again if (_lf_num_nested_crit_sec == 0) { __enable_irq(); } From cf36f59ae59e154626a098b6f4f6250fd8a007a6 Mon Sep 17 00:00:00 2001 From: naichenzhao Date: Tue, 24 Sep 2024 14:47:24 -0700 Subject: [PATCH 33/38] changed macro --- .../impl/src/lf_STM32f4_support.c | 19 +++++++++++++++---- 1 file changed, 15 insertions(+), 4 deletions(-) diff --git a/low_level_platform/impl/src/lf_STM32f4_support.c b/low_level_platform/impl/src/lf_STM32f4_support.c index 5ee1b08b0..ed8c4dd94 100644 --- a/low_level_platform/impl/src/lf_STM32f4_support.c +++ b/low_level_platform/impl/src/lf_STM32f4_support.c @@ -25,6 +25,8 @@ static uint32_t _lf_time_us_high = 0; void lf_SystemClock_Config(); void Error_Handler(); +TIM_HandleTypeDef htim5; + // + -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- + // | Code for timer functions // + -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- + @@ -58,8 +60,8 @@ void _lf_initialize_clock(void) { // ISR for handling timer overflow -> We increment the upper timer void TIM5_IRQHandler(void) { - if (TIM5->SR & (1 << 1)) { - TIM5->SR &= ~(1 << 1); + if (TIM5->SR & TIM_FLAG_CC1) { + TIM5->SR &= ~TIM_FLAG_CC1; _lf_time_us_high += 1; } } @@ -72,11 +74,20 @@ int _lf_clock_gettime(instant_t* t) { if (!t) { return 1; } + // Get the current microseconds from TIM5 - uint32_t _lf_time_us_low = TIM5->CNT; + uint32_t now_us_hi_pre = _lf_time_us_high; + uint32_t now_us_low = TIM5->CNT; + uint32_t now_us_hi_post = _lf_time_us_high; + + // Check if we read the time during a wrap + if (now_us_hi_pre != now_us_hi_post) { + // There was a wrap. read again and return + now_us_low = TIM5->CNT; + } // Combine upper and lower timers - uint64_t now_us = COMBINE_HI_LO((_lf_time_us_high - 1), _lf_time_us_low); + uint64_t now_us = COMBINE_HI_LO((now_us_hi_post - 1), now_us_low); *t = ((instant_t)now_us) * 1000; return 0; } From 68ec2d7bcda4fea821f7513bf4a50637d38e6dfa Mon Sep 17 00:00:00 2001 From: erlingrj Date: Sat, 5 Oct 2024 09:31:19 -0700 Subject: [PATCH 34/38] Run clang-format --- tag/api/tag.h | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/tag/api/tag.h b/tag/api/tag.h index 05d1a1822..c40e490f8 100644 --- a/tag/api/tag.h +++ b/tag/api/tag.h @@ -37,11 +37,13 @@ #define NEVER_TAG \ (tag_t) { .time = NEVER, .microstep = NEVER_MICROSTEP } // Need a separate initializer expression to comply with some C compilers -#define NEVER_TAG_INITIALIZER {NEVER, NEVER_MICROSTEP} +#define NEVER_TAG_INITIALIZER \ + { NEVER, NEVER_MICROSTEP } #define FOREVER_TAG \ (tag_t) { .time = FOREVER, .microstep = FOREVER_MICROSTEP } // Need a separate initializer expression to comply with some C compilers -#define FOREVER_TAG_INITIALIZER {FOREVER, FOREVER_MICROSTEP} +#define FOREVER_TAG_INITIALIZER \ + { FOREVER, FOREVER_MICROSTEP } #define ZERO_TAG \ (tag_t) { .time = 0LL, .microstep = 0u } From 2d23659dc93c353bb2529658dbbb3ac16e7c94f4 Mon Sep 17 00:00:00 2001 From: erlingrj Date: Sat, 5 Oct 2024 09:31:56 -0700 Subject: [PATCH 35/38] Update lf-ref to the new lf branch --- lingua-franca-ref.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lingua-franca-ref.txt b/lingua-franca-ref.txt index 31439c511..55d785547 100644 --- a/lingua-franca-ref.txt +++ b/lingua-franca-ref.txt @@ -1,2 +1,2 @@ -stm32 +stm32_2 From 22b871d9c869d2ed40e4cca1954720a13001fd11 Mon Sep 17 00:00:00 2001 From: erlingrj Date: Tue, 29 Oct 2024 11:50:43 -0700 Subject: [PATCH 36/38] Refactor comments --- .../impl/src/lf_STM32f4_support.c | 20 ++----------------- 1 file changed, 2 insertions(+), 18 deletions(-) diff --git a/low_level_platform/impl/src/lf_STM32f4_support.c b/low_level_platform/impl/src/lf_STM32f4_support.c index ed8c4dd94..2cc8ba5a2 100644 --- a/low_level_platform/impl/src/lf_STM32f4_support.c +++ b/low_level_platform/impl/src/lf_STM32f4_support.c @@ -4,10 +4,6 @@ #include "low_level_platform.h" #include "tag.h" -// + -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- + -// | Important defines and global variables -// + -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- + - static volatile bool _lf_sleep_interrupted = false; static volatile bool _lf_async_event = false; @@ -27,10 +23,6 @@ void Error_Handler(); TIM_HandleTypeDef htim5; -// + -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- + -// | Code for timer functions -// + -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- + -// We use timer 5 for our clock (probably better than dealing with sysTick) void _lf_initialize_clock(void) { // Standard initializations from generated code HAL_Init(); @@ -153,10 +145,6 @@ int _lf_interruptable_sleep_until_locked(environment_t* env, instant_t wakeup_ti } } -// + -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- + -// | Code for enabling and disabling Interrupts -// + -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- + - // disables the IRQ with support for nested disabling int lf_disable_interrupts_nested() { // Disable interrupts if they are currently enabled @@ -192,9 +180,7 @@ int _lf_single_threaded_notify_of_event() { return 0; } -// + -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- + -// | Other functions -> taken from the generated main.c -// + -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- + +// The following functions are copied from the STM32F4 HAL library void lf_SystemClock_Config(void) { RCC_OscInitTypeDef RCC_OscInitStruct = {0}; RCC_ClkInitTypeDef RCC_ClkInitStruct = {0}; @@ -228,13 +214,11 @@ void lf_SystemClock_Config(void) { } } +// Called upon error like a hardfault. void Error_Handler(void) { - /* USER CODE BEGIN Error_Handler_Debug */ - /* User can add his own implementation to report the HAL error return state */ __disable_irq(); while (1) { } - /* USER CODE END Error_Handler_Debug */ } #endif \ No newline at end of file From 68bd26af438e2779431e6450846df7602b949b38 Mon Sep 17 00:00:00 2001 From: erlingrj Date: Tue, 29 Oct 2024 11:58:54 -0700 Subject: [PATCH 37/38] Dont rely on hardcoded relative path to the "STM_SDK" --- low_level_platform/api/CMakeLists.txt | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/low_level_platform/api/CMakeLists.txt b/low_level_platform/api/CMakeLists.txt index 18f774c14..b143b9a1f 100644 --- a/low_level_platform/api/CMakeLists.txt +++ b/low_level_platform/api/CMakeLists.txt @@ -15,7 +15,12 @@ elseif(${CMAKE_SYSTEM_NAME} STREQUAL "Rp2040") target_link_libraries(lf-low-level-platform-api INTERFACE pico_multicore) target_link_libraries(lf-low-level-platform-api INTERFACE pico_sync) elseif(${CMAKE_SYSTEM_NAME} STREQUAL "Stm32") - set(STM_DIR ${CMAKE_CURRENT_SOURCE_DIR}/../../../STM_sdk) + if(DEFINED ENV{STM_SDK_DIR}) + message(STATUS "STM_SDK_DIR is set to $ENV{STM_SDK_DIR}") + else() + message(FATAL_ERROR "The STM_SDK_DIR environment variable must be set to point to the directory generated by CUBEMX for you project.") + endif() + set(STM_SDK_DIR $ENV{STM_SDK_DIR}) set(MCU_FAMILY STM32F4xx) set(MCU_MODEL STM32F446xx) set(CPU_PARAMETERS -mcpu=cortex-m4 -mthumb -mfpu=fpv4-sp-d16 -mfloat-abi=softfp) From 335d52b7d2aafaa794a7abb08fd2bcb1b8bf6603 Mon Sep 17 00:00:00 2001 From: erlingrj Date: Tue, 5 Nov 2024 12:11:23 -0800 Subject: [PATCH 38/38] Remove all the STM32 cmake setup from reactor-c. This happens outside --- low_level_platform/api/CMakeLists.txt | 35 +------------------ .../api/platform/lf_STM32f4_support.h | 1 - low_level_platform/impl/CMakeLists.txt | 4 +-- 3 files changed, 3 insertions(+), 37 deletions(-) diff --git a/low_level_platform/api/CMakeLists.txt b/low_level_platform/api/CMakeLists.txt index b143b9a1f..4092f6411 100644 --- a/low_level_platform/api/CMakeLists.txt +++ b/low_level_platform/api/CMakeLists.txt @@ -14,41 +14,8 @@ elseif(${CMAKE_SYSTEM_NAME} STREQUAL "Rp2040") target_link_libraries(lf-low-level-platform-api INTERFACE pico_stdlib) target_link_libraries(lf-low-level-platform-api INTERFACE pico_multicore) target_link_libraries(lf-low-level-platform-api INTERFACE pico_sync) -elseif(${CMAKE_SYSTEM_NAME} STREQUAL "Stm32") - if(DEFINED ENV{STM_SDK_DIR}) - message(STATUS "STM_SDK_DIR is set to $ENV{STM_SDK_DIR}") - else() - message(FATAL_ERROR "The STM_SDK_DIR environment variable must be set to point to the directory generated by CUBEMX for you project.") - endif() - set(STM_SDK_DIR $ENV{STM_SDK_DIR}) - set(MCU_FAMILY STM32F4xx) - set(MCU_MODEL STM32F446xx) - set(CPU_PARAMETERS -mcpu=cortex-m4 -mthumb -mfpu=fpv4-sp-d16 -mfloat-abi=softfp) - - file(GLOB_RECURSE STM32CUBEMX_SOURCES ${STM_DIR}/Core/*.c ${STM_DIR}/Drivers/${MCU_FAMILY}_HAL_Driver/*.c) - set(CUBEMX_INCLUDE_DIRECTORIES - ${STM_DIR}/Core/Inc - ${STM_DIR}/Drivers/${MCU_FAMILY}_HAL_Driver/Inc - ${STM_DIR}/Drivers/CMSIS/Device/ST/${MCU_FAMILY}/Include - ${STM_DIR}/Drivers/CMSIS/Include - ) - target_compile_options(lf-low-level-platform-api INTERFACE - ${CPU_PARAMETERS} - -Wall - -Wextra - -Wpedantic - -Wno-unused-parameter - $<$: - -Wno-volatile - -Wold-style-cast - -Wuseless-cast - -Wsuggest-override> - $<$:-Og -g3 -ggdb> - $<$:-Og -g0>) - +elseif(${CMAKE_SYSTEM_NAME} STREQUAL "STM32F4") target_compile_definitions(lf-low-level-platform-api INTERFACE PLATFORM_STM32F4) - target_include_directories(lf-low-level-platform-api INTERFACE ${CUBEMX_INCLUDE_DIRECTORIES}) - target_compile_definitions(lf-low-level-platform-api INTERFACE ${MCU_MODEL} USE_HAL_DRIVER) elseif(${CMAKE_SYSTEM_NAME} STREQUAL "FlexPRET") target_compile_definitions(lf-low-level-platform-api INTERFACE PLATFORM_FLEXPRET) target_link_libraries(lf-low-level-platform-api INTERFACE fp-sdk) diff --git a/low_level_platform/api/platform/lf_STM32f4_support.h b/low_level_platform/api/platform/lf_STM32f4_support.h index 061fbe449..19ff2cfa7 100644 --- a/low_level_platform/api/platform/lf_STM32f4_support.h +++ b/low_level_platform/api/platform/lf_STM32f4_support.h @@ -11,7 +11,6 @@ #define PRINTF_TIME "%lld" #define PRINTF_MICROSTEP "%d" -#define LF_TIME_BUFFER_LENGTH 80 #define _LF_TIMEOUT 1 #ifdef LF_THREADED diff --git a/low_level_platform/impl/CMakeLists.txt b/low_level_platform/impl/CMakeLists.txt index 01d76d66e..32cd760c2 100644 --- a/low_level_platform/impl/CMakeLists.txt +++ b/low_level_platform/impl/CMakeLists.txt @@ -39,7 +39,7 @@ elseif(${CMAKE_SYSTEM_NAME} STREQUAL "Rp2040") ${CMAKE_CURRENT_LIST_DIR}/src/lf_rp2040_support.c ${CMAKE_CURRENT_LIST_DIR}/src/lf_atomic_irq.c ) -elseif(${CMAKE_SYSTEM_NAME} STREQUAL "Stm32") +elseif(${CMAKE_SYSTEM_NAME} STREQUAL "STM32F4") set(LF_LOW_LEVEL_PLATFORM_FILES ${CMAKE_CURRENT_LIST_DIR}/src/lf_STM32f4_support.c ${CMAKE_CURRENT_LIST_DIR}/src/lf_atomic_irq.c @@ -55,7 +55,7 @@ elseif(${CMAKE_SYSTEM_NAME} STREQUAL "Patmos") ${CMAKE_CURRENT_LIST_DIR}/src/lf_atomic_irq.c ) else() - message(FATAL_ERROR "Your platform is not supported! The C target supports FlexPRET, Patmos, Linux, MacOS, nRF52, RP2040, Windows, and Zephyr.") + message(FATAL_ERROR "Your platform is not supported! The C target supports FlexPRET, Patmos, Linux, MacOS, nRF52, RP2040, STM32F4, Windows, and Zephyr.") endif() list(APPEND LF_LOW_LEVEL_PLATFORM_FILES ${CMAKE_CURRENT_LIST_DIR}/src/lf_platform_util.c)