diff --git a/AZURE_RTOS/App/app_azure_rtos.c b/AZURE_RTOS/App/app_azure_rtos.c index eb04cca..5ab1f38 100644 --- a/AZURE_RTOS/App/app_azure_rtos.c +++ b/AZURE_RTOS/App/app_azure_rtos.c @@ -21,19 +21,19 @@ /* Includes ------------------------------------------------------------------*/ #include "app_azure_rtos.h" + #include "stm32h7xx.h" /* Private includes ----------------------------------------------------------*/ /* USER CODE BEGIN Includes */ #include "app.h" +#include "app_touchgfx.h" #include "leds.h" #include "main.h" -#include "ui.h" -#include "vehicle.h" - -#include "app_touchgfx.h" #include "tx_api.h" #include "tx_port.h" +#include "ui.h" +#include "vehicle.h" /* USER CODE END Includes */ @@ -56,10 +56,11 @@ #if (USE_STATIC_ALLOCATION == 1) /* USER CODE BEGIN TX_Pool_Buffer */ /* USER CODE END TX_Pool_Buffer */ -#if defined ( __ICCARM__ ) -#pragma data_alignment=4 +#if defined(__ICCARM__) +#pragma data_alignment = 4 #endif -__ALIGN_BEGIN static UCHAR tx_byte_pool_buffer[TX_APP_MEM_POOL_SIZE] __ALIGN_END; +__ALIGN_BEGIN static UCHAR + tx_byte_pool_buffer[TX_APP_MEM_POOL_SIZE] __ALIGN_END; static TX_BYTE_POOL tx_app_byte_pool; #endif @@ -69,6 +70,7 @@ TX_THREAD app_thread; TX_THREAD ui_thread; TX_THREAD vehicle_thread; TX_THREAD led_thread; +TX_THREAD params_thread; TX_QUEUE gui_button_queue; TX_EVENT_FLAGS_GROUP gui_update_events; /* USER CODE END PV */ @@ -79,12 +81,11 @@ TX_EVENT_FLAGS_GROUP gui_update_events; /* USER CODE END PFP */ /** - * @brief Define the initial system. - * @param first_unused_memory : Pointer to the first unused memory - * @retval None - */ -VOID tx_application_define(VOID *first_unused_memory) -{ + * @brief Define the initial system. + * @param first_unused_memory : Pointer to the first unused memory + * @retval None + */ +VOID tx_application_define(VOID *first_unused_memory) { /* USER CODE BEGIN tx_application_define_1*/ /* USER CODE END tx_application_define_1 */ @@ -92,22 +93,20 @@ VOID tx_application_define(VOID *first_unused_memory) UINT status = TX_SUCCESS; VOID *memory_ptr; - if (tx_byte_pool_create(&tx_app_byte_pool, "Tx App memory pool", tx_byte_pool_buffer, TX_APP_MEM_POOL_SIZE) != TX_SUCCESS) - { + if (tx_byte_pool_create(&tx_app_byte_pool, "Tx App memory pool", + tx_byte_pool_buffer, + TX_APP_MEM_POOL_SIZE) != TX_SUCCESS) { /* USER CODE BEGIN TX_Byte_Pool_Error */ /* USER CODE END TX_Byte_Pool_Error */ - } - else - { + } else { /* USER CODE BEGIN TX_Byte_Pool_Success */ /* USER CODE END TX_Byte_Pool_Success */ memory_ptr = (VOID *)&tx_app_byte_pool; status = App_ThreadX_Init(memory_ptr); - if (status != TX_SUCCESS) - { + if (status != TX_SUCCESS) { /* USER CODE BEGIN App_ThreadX_Init_Error */ while (1) { } @@ -117,21 +116,22 @@ VOID tx_application_define(VOID *first_unused_memory) /* USER CODE BEGIN App_ThreadX_Init_Success */ /* USER CODE END App_ThreadX_Init_Success */ - } #else /* - * Using dynamic memory allocation requires to apply some changes to the linker file. - * ThreadX needs to pass a pointer to the first free memory location in RAM to the tx_application_define() function, + * Using dynamic memory allocation requires to apply some changes to the + linker file. + * ThreadX needs to pass a pointer to the first free memory location in RAM to + the tx_application_define() function, * using the "first_unused_memory" argument. * This require changes in the linker files to expose this memory location. * For EWARM add the following section into the .icf file: place in RAM_region { last section FREE_MEM }; * For MDK-ARM - either define the RW_IRAM1 region in the ".sct" file - - or modify the line below in "tx_initialize_low_level.S to match the memory region being used - LDR r1, =|Image$$RW_IRAM1$$ZI$$Limit| + - or modify the line below in "tx_initialize_low_level.S to match the + memory region being used LDR r1, =|Image$$RW_IRAM1$$ZI$$Limit| * For STM32CubeIDE add the following section into the .ld file: ._threadx_heap : @@ -141,13 +141,17 @@ VOID tx_application_define(VOID *first_unused_memory) . = . + 64K; . = ALIGN(8); } >RAM_D1 AT> RAM_D1 - * The simplest way to provide memory for ThreadX is to define a new section, see ._threadx_heap above. + * The simplest way to provide memory for ThreadX is to define a new + section, see ._threadx_heap above. * In the example above the ThreadX heap size is set to 64KBytes. - * The ._threadx_heap must be located between the .bss and the ._user_heap_stack sections in the linker script. - * Caution: Make sure that ThreadX does not need more than the provided heap memory (64KBytes in this example). + * The ._threadx_heap must be located between the .bss and the + ._user_heap_stack sections in the linker script. + * Caution: Make sure that ThreadX does not need more than the provided + heap memory (64KBytes in this example). * Read more in STM32CubeIDE User Guide, chapter: "Linker script". - * The "tx_initialize_low_level.S" should be also modified to enable the "USE_DYNAMIC_MEMORY_ALLOCATION" flag. + * The "tx_initialize_low_level.S" should be also modified to enable the + "USE_DYNAMIC_MEMORY_ALLOCATION" flag. */ /* USER CODE BEGIN DYNAMIC_MEM_ALLOC */ @@ -208,6 +212,15 @@ VOID tx_application_define(VOID *first_unused_memory) Error_Handler(); } + void *params_thread_stack = mem; + mem += THREAD_STACK_SIZE; + if (tx_thread_create(¶ms_thread, "Params Thread", params_thread_entry, 0, + params_thread_stack, THREAD_STACK_SIZE, + THREAD_PRIO_PARAMS, THREAD_PRIO_UI, TX_NO_TIME_SLICE, + TX_AUTO_START) != TX_SUCCESS) { + Error_Handler(); + } + if (MX_TouchGFX_Init(mem) != TX_SUCCESS) { Error_Handler(); } @@ -215,5 +228,4 @@ VOID tx_application_define(VOID *first_unused_memory) mem += 4096; /* USER CODE END DYNAMIC_MEM_ALLOC */ #endif - } diff --git a/AZURE_RTOS/App/app_azure_rtos.h b/AZURE_RTOS/App/app_azure_rtos.h index 34bb52e..52db564 100644 --- a/AZURE_RTOS/App/app_azure_rtos.h +++ b/AZURE_RTOS/App/app_azure_rtos.h @@ -27,7 +27,6 @@ extern "C" { /* Includes ------------------------------------------------------------------*/ #include "app_azure_rtos_config.h" - #include "app_threadx.h" /* Private includes ----------------------------------------------------------*/ /* USER CODE BEGIN Includes */ @@ -44,6 +43,7 @@ extern "C" { #define THREAD_STACK_SIZE 4096 #define THREAD_PRIO_APP 10 +#define THREAD_PRIO_PARAMS 8 #define THREAD_PRIO_UI 6 #define THREAD_PRIO_VEHICLE 7 #define THREAD_PRIO_LED 11 diff --git a/Core/Inc/params.h b/Core/Inc/params.h index 4045086..c0d1bce 100644 --- a/Core/Inc/params.h +++ b/Core/Inc/params.h @@ -7,18 +7,20 @@ extern "C" { #include #include +#include #include "util.h" -CountedEnum(ParamType, size_t, PF_PLIM, PF_TLIM, PF_SLIM, PF_TVEC, PF_PG, PF_REKU); +CountedEnum(ParamType, size_t, PF_PLIM, PF_TLIM, PF_SLIM, PF_TVEC, PF_PG, + PF_REKU); typedef struct { - unsigned plim; //< Power limit - unsigned tlim; //< Torque limit - unsigned slim; //< Speed limit - unsigned tvec; //< Torque vectoring - unsigned pg; //< Power ground - unsigned reku; //< Rekuperation + unsigned plim; //< Power limit + unsigned tlim; //< Torque limit + unsigned slim; //< Speed limit + unsigned tvec; //< Torque vectoring + unsigned pg; //< Power ground + unsigned reku; //< Rekuperation } Params; extern Params params; @@ -28,8 +30,13 @@ void params_inc(ParamType param); void params_dec(ParamType param); void params_broadcast(ParamType param); +/** FT24 only + * Broadcasts the current registered params to the CAN bus every second + */ +void params_thread_entry(ULONG _); + #ifdef __cplusplus } #endif -#endif // INC_PARAMS_H +#endif // INC_PARAMS_H diff --git a/Core/Src/params.c b/Core/Src/params.c index 1816d97..154b786 100644 --- a/Core/Src/params.c +++ b/Core/Src/params.c @@ -1,19 +1,29 @@ #include "params.h" + +#include + #include "can-halal.h" +#include "leds.h" #include "vehicle.h" /** * Decrements the given value if it is above the minimum allowed value */ -// TODO these functions take into account that the parameters are unsigned, it's definitely better to have them -// signed but would need to be tested with the autobox -#define DEC_IF_ABOVE(param_val, min_val, decr_amt) ((param_val) = (((int)(param_val) - (int)(decr_amt)) > (int)(min_val)) ? ((param_val) - (decr_amt)) : (min_val)) -#define INC_IF_BELOW(param_val, max_val, incr_amt) ((param_val) = (((param_val) + (incr_amt)) < (max_val)) ? ((param_val) + (incr_amt)) : (max_val)) +// TODO these functions take into account that the parameters are unsigned, it's +// definitely better to have them signed but would need to be tested with the +// autobox +#define DEC_IF_ABOVE(param_val, min_val, decr_amt) \ + ((param_val) = (((int)(param_val) - (int)(decr_amt)) > (int)(min_val)) \ + ? ((param_val) - (decr_amt)) \ + : (min_val)) +#define INC_IF_BELOW(param_val, max_val, incr_amt) \ + ((param_val) = (((param_val) + (incr_amt)) < (max_val)) \ + ? ((param_val) + (incr_amt)) \ + : (max_val)) Params params = {0}; -void params_init() -{ +void params_init() { // Default values params.plim = 20; params.tlim = 1400; @@ -23,81 +33,89 @@ void params_init() params.reku = 0; } -void params_inc(ParamType param) -{ - switch (param) - { - case PF_PLIM: - INC_IF_BELOW(params.plim, 80, 1); - break; - case PF_TLIM: - INC_IF_BELOW(params.tlim, 1500, 100); - break; - case PF_SLIM: - INC_IF_BELOW(params.slim, 100, 1); - break; - case PF_TVEC: - INC_IF_BELOW(params.tvec, 100, 1); - break; - case PF_PG: - INC_IF_BELOW(params.pg, 100, 1); - break; - case PF_REKU: - INC_IF_BELOW(params.reku, 100, 1); - break; +void params_inc(ParamType param) { + switch (param) { + case PF_PLIM: + INC_IF_BELOW(params.plim, 80, 1); + break; + case PF_TLIM: + INC_IF_BELOW(params.tlim, 1500, 100); + break; + case PF_SLIM: + INC_IF_BELOW(params.slim, 100, 1); + break; + case PF_TVEC: + INC_IF_BELOW(params.tvec, 100, 1); + break; + case PF_PG: + INC_IF_BELOW(params.pg, 100, 1); + break; + case PF_REKU: + INC_IF_BELOW(params.reku, 100, 1); + break; } } -void params_dec(ParamType param) -{ - switch (param) - { - case PF_PLIM: - DEC_IF_ABOVE(params.plim, 0, 1); - break; - case PF_TLIM: - DEC_IF_ABOVE(params.tlim, 0, 100); - break; - case PF_SLIM: - DEC_IF_ABOVE(params.slim, 0, 1); - break; - case PF_TVEC: - DEC_IF_ABOVE(params.tvec, 0, 1); - break; - case PF_PG: - DEC_IF_ABOVE(params.pg, 0, 1); - break; - case PF_REKU: - DEC_IF_ABOVE(params.reku, 0, 1); - break; +void params_dec(ParamType param) { + switch (param) { + case PF_PLIM: + DEC_IF_ABOVE(params.plim, 0, 1); + break; + case PF_TLIM: + DEC_IF_ABOVE(params.tlim, 0, 100); + break; + case PF_SLIM: + DEC_IF_ABOVE(params.slim, 0, 1); + break; + case PF_TVEC: + DEC_IF_ABOVE(params.tvec, 0, 1); + break; + case PF_PG: + DEC_IF_ABOVE(params.pg, 0, 1); + break; + case PF_REKU: + DEC_IF_ABOVE(params.reku, 0, 1); + break; } } -void params_broadcast(ParamType param) -{ +void params_broadcast(ParamType param) { int32_t value; - switch (param) - { - case PF_PLIM: - value = params.plim; - break; - case PF_TLIM: - value = params.tlim; - break; - case PF_SLIM: - value = params.slim; - break; - case PF_TVEC: - value = params.tvec; - break; - case PF_PG: - value = params.pg; - break; - case PF_REKU: - value = params.reku; - break; - default: - return; + switch (param) { + case PF_PLIM: + value = params.plim; + break; + case PF_TLIM: + value = params.tlim; + break; + case PF_SLIM: + value = params.slim; + break; + case PF_TVEC: + value = params.tvec; + break; + case PF_PG: + value = params.pg; + break; + case PF_REKU: + value = params.reku; + break; + default: + return; } vehicle_broadcast_param(param, value); } + +void params_thread_entry(ULONG _) { + tx_thread_sleep(TX_TIMER_TICKS_PER_SECOND); + + while (1) { + for (size_t i = 0; i < ParamType_COUNT; i++) { + led_set(1, 0, 255, 0); + params_broadcast(i); + } + + // Wait one second + tx_thread_sleep(TX_TIMER_TICKS_PER_SECOND); + } +}