diff --git a/.vscode/launch.json b/.vscode/launch.json index fc890b664..d1718913c 100644 --- a/.vscode/launch.json +++ b/.vscode/launch.json @@ -373,6 +373,134 @@ ] } }, + { + "cwd": "${workspaceFolder}", + "executable": "${command:cmake.buildDirectory}/InboardFloor.elf", + "name": "Inboard Floor FL", + "request": "launch", + "type": "cortex-debug", + "servertype": "openocd", + "configFiles": [ + "interface/stlink-dap.cfg", + "target/stm32h5x.cfg" + ], + "searchDir": [], + "preLaunchTask": "CMake: configure and build InboardFloor FL", + "showDevDebugOutput": "raw", + "svdPath": "${workspaceFolder}/Lib/Vendor/CMSIS_5/SVD/STM32H523.svd" + }, + { + "cwd": "${workspaceFolder}", + "executable": "${command:cmake.buildDirectory}/InboardFloor.elf", + "name": "Inboard Floor FR", + "request": "launch", + "type": "cortex-debug", + "servertype": "openocd", + "configFiles": [ + "interface/stlink-dap.cfg", + "target/stm32h5x.cfg" + ], + "searchDir": [], + "preLaunchTask": "CMake: configure and build InboardFloor FR", + "showDevDebugOutput": "raw", + "svdPath": "${workspaceFolder}/Lib/Vendor/CMSIS_5/SVD/STM32H523.svd" + }, + { + "cwd": "${workspaceFolder}", + "executable": "${command:cmake.buildDirectory}/InboardFloor.elf", + "name": "Inboard Floor RL", + "request": "launch", + "type": "cortex-debug", + "servertype": "openocd", + "configFiles": [ + "interface/stlink-dap.cfg", + "target/stm32h5x.cfg" + ], + "searchDir": [], + "preLaunchTask": "CMake: configure and build InboardFloor RL", + "showDevDebugOutput": "raw", + "svdPath": "${workspaceFolder}/Lib/Vendor/CMSIS_5/SVD/STM32H523.svd" + }, + { + "cwd": "${workspaceFolder}", + "executable": "${command:cmake.buildDirectory}/InboardFloor.elf", + "name": "Inboard Floor RR", + "request": "launch", + "type": "cortex-debug", + "servertype": "openocd", + "configFiles": [ + "interface/stlink-dap.cfg", + "target/stm32h5x.cfg" + ], + "searchDir": [], + "preLaunchTask": "CMake: configure and build InboardFloor RR", + "showDevDebugOutput": "raw", + "svdPath": "${workspaceFolder}/Lib/Vendor/CMSIS_5/SVD/STM32H523.svd" + }, + { + "cwd": "${workspaceFolder}", + "executable": "${command:cmake.buildDirectory}/SuspensionNode.elf", + "name": "Suspension Node FL", + "request": "launch", + "type": "cortex-debug", + "servertype": "openocd", + "configFiles": [ + "interface/stlink-dap.cfg", + "target/stm32h5x.cfg" + ], + "searchDir": [], + "preLaunchTask": "CMake: configure and build SuspensionNode FL", + "showDevDebugOutput": "raw", + "svdPath": "${workspaceFolder}/Lib/Vendor/CMSIS_5/SVD/STM32H523.svd" + }, + { + "cwd": "${workspaceFolder}", + "executable": "${command:cmake.buildDirectory}/SuspensionNode.elf", + "name": "Suspension Node FR", + "request": "launch", + "type": "cortex-debug", + "servertype": "openocd", + "configFiles": [ + "interface/stlink-dap.cfg", + "target/stm32h5x.cfg" + ], + "searchDir": [], + "preLaunchTask": "CMake: configure and build SuspensionNode FR", + "showDevDebugOutput": "raw", + "svdPath": "${workspaceFolder}/Lib/Vendor/CMSIS_5/SVD/STM32H523.svd" + }, + { + "cwd": "${workspaceFolder}", + "executable": "${command:cmake.buildDirectory}/SuspensionNode.elf", + "name": "Suspension Node RL", + "request": "launch", + "type": "cortex-debug", + "servertype": "openocd", + "configFiles": [ + "interface/stlink-dap.cfg", + "target/stm32h5x.cfg" + ], + "searchDir": [], + "preLaunchTask": "CMake: configure and build SuspensionNode RL", + "showDevDebugOutput": "raw", + "svdPath": "${workspaceFolder}/Lib/Vendor/CMSIS_5/SVD/STM32H523.svd" + }, + { + "cwd": "${workspaceFolder}", + "executable": "${command:cmake.buildDirectory}/SuspensionNode.elf", + "name": "Suspension Node RR", + "request": "launch", + "type": "cortex-debug", + "servertype": "openocd", + "configFiles": [ + "interface/stlink-dap.cfg", + "target/stm32h5x.cfg" + ], + "searchDir": [], + "preLaunchTask": "CMake: configure and build SuspensionNode RR", + "showDevDebugOutput": "raw", + "svdPath": "${workspaceFolder}/Lib/Vendor/CMSIS_5/SVD/STM32H523.svd" + }, { "cwd": "${workspaceFolder}", "executable": "${command:cmake.buildDirectory}/G4HELLO.elf", @@ -932,6 +1060,22 @@ } ] } + }, + { + "cwd": "${workspaceFolder}", + "executable": "${command:cmake.buildDirectory}/H523xx_CAN_BASIC_TEST.elf", + "name": "H523xx_CAN_BASIC_TEST", + "request": "launch", + "type": "cortex-debug", + "servertype": "openocd", + "configFiles": [ + "interface/stlink-dap.cfg", + "target/stm32h5x.cfg" + ], + "searchDir": [], + "preLaunchTask": "CMake: configure and build H523xx_CAN_BASIC_TEST", + "showDevDebugOutput": "raw", + "svdPath": "${workspaceFolder}/Lib/Vendor/CMSIS_5/SVD/STM32H523.svd" } ] } diff --git a/.vscode/tasks.json b/.vscode/tasks.json index bf2d6e115..d65bb5c08 100644 --- a/.vscode/tasks.json +++ b/.vscode/tasks.json @@ -137,6 +137,78 @@ ], "command": "cmake --build --preset ${command:cmake.activeBuildPresetName} --target BrakeTemp" }, + { + "label": "CMake: configure and build InboardFloor FL", + "type": "shell", + "dependsOrder": "sequence", + "dependsOn": [ + "CMake: configure NODE=FL" + ], + "command": "cmake --build --preset ${command:cmake.activeBuildPresetName} --target InboardFloor" + }, + { + "label": "CMake: configure and build InboardFloor FR", + "type": "shell", + "dependsOrder": "sequence", + "dependsOn": [ + "CMake: configure NODE=FR" + ], + "command": "cmake --build --preset ${command:cmake.activeBuildPresetName} --target InboardFloor" + }, + { + "label": "CMake: configure and build InboardFloor RL", + "type": "shell", + "dependsOrder": "sequence", + "dependsOn": [ + "CMake: configure NODE=RL" + ], + "command": "cmake --build --preset ${command:cmake.activeBuildPresetName} --target InboardFloor" + }, + { + "label": "CMake: configure and build InboardFloor RR", + "type": "shell", + "dependsOrder": "sequence", + "dependsOn": [ + "CMake: configure NODE=RR" + ], + "command": "cmake --build --preset ${command:cmake.activeBuildPresetName} --target InboardFloor" + }, + { + "label": "CMake: configure and build SuspensionNode FL", + "type": "shell", + "dependsOrder": "sequence", + "dependsOn": [ + "CMake: configure NODE=FL" + ], + "command": "cmake --build --preset ${command:cmake.activeBuildPresetName} --target SuspensionNode" + }, + { + "label": "CMake: configure and build SuspensionNode FR", + "type": "shell", + "dependsOrder": "sequence", + "dependsOn": [ + "CMake: configure NODE=FR" + ], + "command": "cmake --build --preset ${command:cmake.activeBuildPresetName} --target SuspensionNode" + }, + { + "label": "CMake: configure and build SuspensionNode RL", + "type": "shell", + "dependsOrder": "sequence", + "dependsOn": [ + "CMake: configure NODE=RL" + ], + "command": "cmake --build --preset ${command:cmake.activeBuildPresetName} --target SuspensionNode" + }, + { + "label": "CMake: configure and build SuspensionNode RR", + "type": "shell", + "dependsOrder": "sequence", + "dependsOn": [ + "CMake: configure NODE=RR" + ], + "command": "cmake --build --preset ${command:cmake.activeBuildPresetName} --target SuspensionNode" + }, { "label": "CMake: configure and build G4ECHO", "type": "shell", @@ -316,6 +388,15 @@ "CMake: configure" ], "command": "cmake --build --preset ${command:cmake.activeBuildPresetName} --target G431x8_CAN_BASIC_TEST" + }, + { + "label": "CMake: configure and build H523xx_CAN_BASIC_TEST", + "type": "shell", + "dependsOrder": "sequence", + "dependsOn": [ + "CMake: configure" + ], + "command": "cmake --build --preset ${command:cmake.activeBuildPresetName} --target H523xx_CAN_BASIC_TEST" } ] } diff --git a/CMakeLists.txt b/CMakeLists.txt index dd6d899d4..d964077b9 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -156,6 +156,11 @@ add_gr_project(STM32G474xE CANine) add_gr_project(STM32G431x8 OutboardSensors TireTemp) add_gr_project(STM32G431x8 OutboardSensors BrakeTemp) +# SAMM +include("SAMM/samm.cmake") +add_gr_project(STM32H523xE SAMM InboardFloor) +add_gr_project(STM32H523xE SAMM SuspensionNode) + # Development add_gr_project(STM32G474xE G4PERTESTING) add_gr_project(STM32G474xE G4SPITESTING) @@ -169,7 +174,9 @@ add_gr_project(STM32G474xE G474xE_CAN_TESTING CAN_STRESS_TEST) add_gr_project(STM32G474xE G474xE_CAN_TESTING CAN_LOST_RX_TEST) add_gr_project(STM32G474xE G474xE_CAN_TESTING CAN_FILTER_TEST) add_gr_project(STM32G474xE G474xE_CAN_TESTING PROFILER_TEST) + add_gr_project(STM32G431x8 G431x8_CAN_TESTING G431x8_CAN_BASIC_TEST) +add_gr_project(STM32H523xE H523xx_CAN_TESTING H523xx_CAN_BASIC_TEST) add_gr_project(STM32G474xE G4FANCYCANTESTING CAN_LOOPBACK_TEST) diff --git a/G4FANCYCANTESTING/CAN_LOOPBACK_TEST/CMakeLists.txt b/G4FANCYCANTESTING/CAN_LOOPBACK_TEST/CMakeLists.txt index fdf940e7b..508a7788b 100644 --- a/G4FANCYCANTESTING/CAN_LOOPBACK_TEST/CMakeLists.txt +++ b/G4FANCYCANTESTING/CAN_LOOPBACK_TEST/CMakeLists.txt @@ -36,6 +36,7 @@ target_sources( ../Core/Src/gpio.c ../Core/Src/i2c.c main.c + profile.c ../Core/Src/spi.c ../Core/Src/stm32g4xx_hal_msp.c ../Core/Src/stm32g4xx_it.c diff --git a/G4FANCYCANTESTING/CAN_LOOPBACK_TEST/profile.c b/G4FANCYCANTESTING/CAN_LOOPBACK_TEST/profile.c new file mode 100644 index 000000000..1ece3baae --- /dev/null +++ b/G4FANCYCANTESTING/CAN_LOOPBACK_TEST/profile.c @@ -0,0 +1,23 @@ +#include "profile.h" + +dwt_timer_t GLOBAL_DWT_TIMER = {0}; + +void profiler_test() +{ + dwt_timer_t timer = {0}; + + start_dwt(); + + for (int i = 0; i < 100; i++) { + // global_dwt_timer_start_measurement(); + dwt_timer_start_measurement(&timer); + // HAL_Delay(1); + // for (int i = 0; i < 10; i++); + dwt_timer_end_measurement(&timer); + // global_dwt_timer_start_measurement(); + } + + dwt_timer_print_info(&timer); + + stop_dwt(); +} diff --git a/G4FANCYCANTESTING/Core/Inc/can_cfg.h b/G4FANCYCANTESTING/Core/Inc/can_cfg.h index 5e7e78550..ab2c1d13f 100644 --- a/G4FANCYCANTESTING/Core/Inc/can_cfg.h +++ b/G4FANCYCANTESTING/Core/Inc/can_cfg.h @@ -6,4 +6,6 @@ #define TX_BUFFER_2_SIZE 10 +#define CAN_TIMER_SEND_PERIOD_US 625 + #endif diff --git a/G4FANCYCANTESTING/Core/Inc/can_tests.h b/G4FANCYCANTESTING/Core/Inc/can_tests.h new file mode 100644 index 000000000..f1cbef2d3 --- /dev/null +++ b/G4FANCYCANTESTING/Core/Inc/can_tests.h @@ -0,0 +1,20 @@ +#ifndef CAN_TESTS_H +#define CAN_TESTS_H + +#include "Logomatic.h" +#include "can.h" +#include "can_platform_deps.h" +#include "profile.h" + +// abstract families +// extern int get_cfg(FDCAN_GlobalTypeDef *instance, CAN_RXCallback callback, CANConfig *out_cfg, uint32_t Mode); + +// testing functions +extern int can_external_two_node(void); +extern int can_basic_test(void); +extern int can_stress_test(void); +extern int can_release_test(void); +extern int can_filter_test(void); +extern int can_lost_rx_test(void); + +#endif diff --git a/G4FANCYCANTESTING/Core/Inc/profile.h b/G4FANCYCANTESTING/Core/Inc/profile.h new file mode 100644 index 000000000..764bc8bec --- /dev/null +++ b/G4FANCYCANTESTING/Core/Inc/profile.h @@ -0,0 +1,143 @@ +#ifndef PROFILE_H +#define PROFILE_H + +#define PROFILE 0 + +#include +#include + +#include "Logomatic.h" + +static inline uint32_t max_u32(uint32_t a, uint32_t b) +{ + return a > b ? a : b; +} +typedef struct dwt_timer_t { + uint32_t total_cycles; + uint32_t total_samples; + + volatile uint32_t start_cycle; + volatile uint32_t end_cycle; + + volatile uint32_t max_cycles; + volatile uint32_t min_cycles; + + volatile bool measuring; +} dwt_timer_t; + +static inline void start_dwt() +{ + // DWT->CYCCNT = 0; + CoreDebug->DEMCR |= CoreDebug_DEMCR_TRCENA_Msk; + DWT->CTRL |= DWT_CTRL_CYCCNTENA_Msk; + __ISB(); +} + +static inline void stop_dwt() +{ + DWT->CTRL &= ~DWT_CTRL_CYCCNTENA_Msk; +} + +// static number of cycles is 37 +#define STATIC_CYCLE_COST 36 + +static inline float dwt_timer_average_cycles(const dwt_timer_t *dt) +{ + return (dt->total_cycles) / ((float)dt->total_samples); +} +static inline void dwt_timer_start_measurement(dwt_timer_t *dt) +{ + dt->measuring = true; + dt->start_cycle = DWT->CYCCNT; + __DSB(); + __ISB(); +} + +static inline void dwt_timer_end_measurement(dwt_timer_t *dt) +{ + if (!dt->measuring) { + return; + } + + dt->end_cycle = DWT->CYCCNT; + + // handles one overflow + uint32_t elapsed_cycle = dt->end_cycle - dt->start_cycle; + + dt->total_cycles += elapsed_cycle; //- STATIC_CYCLE_COST; + dt->total_samples++; + + dt->measuring = false; + + dt->max_cycles = max_u32(dt->max_cycles, elapsed_cycle); + __DSB(); +} + +static inline void dwt_timer_reset(dwt_timer_t *dt) +{ + dwt_timer_end_measurement(dt); + + dt->start_cycle = 0; + dt->end_cycle = 0; + dt->measuring = false; + dt->total_cycles = 0; + dt->total_samples = 0; +} + +static inline void dwt_timer_print_info(dwt_timer_t *dt) +{ + LOGOMATIC("AVG: %f\n", dwt_timer_average_cycles(dt)); + LOGOMATIC("Total Cycles: %lu\n", dt->total_cycles); + LOGOMATIC("Total Samples: %lu\n", dt->total_samples); + LOGOMATIC("Max Cycle: %lu\n", dt->max_cycles); +} + +// testing +extern void profiler_test(); + +/*extern dwt_timer_t GLOBAL_DWT_TIMER; + +//static number of cycles is 30 +static inline void global_dwt_timer_start_measurement(void) { + GLOBAL_DWT_TIMER.measuring = true; + GLOBAL_DWT_TIMER.start_cycle = DWT->CYCCNT; +} + +static inline void global_dwt_timer_end_measurement(void) { + if (!GLOBAL_DWT_TIMER.measuring) { + return; + } + + GLOBAL_DWT_TIMER.end_cycle = DWT->CYCCNT; + + //handles one overflow + uint32_t elapsed_cycle = GLOBAL_DWT_TIMER.end_cycle - GLOBAL_DWT_TIMER.start_cycle; + GLOBAL_DWT_TIMER.total_cycles += elapsed_cycle; + GLOBAL_DWT_TIMER.total_samples++; + + GLOBAL_DWT_TIMER.measuring = false; + + GLOBAL_DWT_TIMER.max_cycles = MAX(GLOBAL_DWT_TIMER.max_cycles, elapsed_cycle); + //GLOBAL_DWT_TIMER.min_cycles; +} +static inline float global_dwt_timer_average_cycles() { + return (GLOBAL_DWT_TIMER.total_cycles)/((float) GLOBAL_DWT_TIMER.total_samples); + +}*/ + +// extern volatile uint32_t PROFILE_AVG_RX_CYCLES; +// extern volatile uint32_t PROFILE_RX_SAMPLES; +// extern volatile uint32_t ELAPSED_CYCLES; +// extern volatile float AVG; + +/*#define START_COUNT \ + do { \ + DWT->CYCCNT = 0; \ + DWT->CTRL |= DWT_CTRL_CYCCNTENA_Msk; \ + } while (); + +#define END_COUNT +#define PROFILER_STOP (DWT->CTRL &= ~DWT_CTRL_CYCCNTENA_Msk;) +*/ + +#endif diff --git a/G4FANCYCANTESTING/Core/Src/FancyCAN_LoopbackTest.c b/G4FANCYCANTESTING/Core/Src/FancyCAN_LoopbackTest.c index 07f9ca72a..347ffa071 100644 --- a/G4FANCYCANTESTING/Core/Src/FancyCAN_LoopbackTest.c +++ b/G4FANCYCANTESTING/Core/Src/FancyCAN_LoopbackTest.c @@ -49,24 +49,9 @@ int GRCAN_Validate_InitBus(GRCAN_BUS_ID bus, GRCAN_OperatingMode mode, FDCAN_Glo } } -// GRCAN_ALL = 0xFF, -// GRCAN_ACU = 0x03, -// GRCAN_ECU = 0x02, -// GRCAN_CCU = 0x02, -// GRCAN_Charger = 0x00, -// GRCAN_Charging_SDC = 0x0C, -// GRCAN_DGPS = 0x30, -// GRCAN_Dash_Panel = 0x05, -// GRCAN_Debugger = 0x01, -// GRCAN_Fan_Ctrl_1 = 0x0D, -// GRCAN_Fan_Ctrl_2 = 0x0E, -// GRCAN_Fan_Ctrl_3 = 0x0F, -// GRCAN_GR_Inv = 0x08, -// GRCAN_TCM = 0x04, - GRCAN_NODE_ID get_nodeID(GRCAN_BUS_ID bus) { - switch (bus) { + switch ((int)bus) { case GRCAN_BUS_PRIMARY: return GRCAN_ACU; case GRCAN_BUS_DATA: @@ -74,57 +59,17 @@ GRCAN_NODE_ID get_nodeID(GRCAN_BUS_ID bus) case GRCAN_BUS_TESTING: return GRCAN_Debugger; case GRCAN_BUS_CHARGER: - return GRCAN_Charger; + return GRCAN_CCU; + case GRCAN_BUS_DATA_SUBNET: + return GRCAN_ECU; default: return GRCAN_ALL; // All causes error } } -// typedef enum { -// GRCAN_DEBUG_2_0 = 0x000, -// GRCAN_DEBUG_FD = 0x001, -// GRCAN_PING = 0x002, -// GRCAN_ECU_STATUS_1 = 0x003, -// GRCAN_ECU_STATUS_2 = 0x004, -// GRCAN_ECU_STATUS_3 = 0x005, -// GRCAN_ECU_CONFIG = 0x006, -// GRCAN_ACU_STATUS_1 = 0x007, -// GRCAN_ACU_STATUS_2 = 0x008, -// GRCAN_ACU_STATUS_3 = 0x009, -// GRCAN_ACU_PRECHARGE = 0x00A, -// GRCAN_ACU_CONFIG_CHARGE_PARAMETERS = 0x00B, -// GRCAN_ACU_CONFIG_OPERATIONAL_PARAMETERS = 0x00C, -// GRCAN_ACU_CELL_DATA_1 = 0x00D, -// GRCAN_ACU_CELL_DATA_2 = 0x00E, -// GRCAN_ACU_CELL_DATA_3 = 0x00F, -// GRCAN_ACU_CELL_DATA_4 = 0x010, -// GRCAN_ACU_CELL_DATA_5 = 0x011, -// GRCAN_INV_STATUS_1 = 0x013, -// GRCAN_INV_STATUS_2 = 0x014, -// GRCAN_INV_STATUS_3 = 0x015, -// GRCAN_INV_CONFIG = 0x016, -// GRCAN_INV_CMD = 0x017, -// GRCAN_FAN_STATUS = 0x018, -// GRCAN_FAN_COMMAND = 0x019, -// GRCAN_DASH_STATUS = 0x01A, -// GRCAN_DASH_CONFIG = 0x01B, -// GRCAN_TCM_STATUS = 0x029, -// GRCAN_TCM_RESOURCE_UTILIZATION = 0x02A, -// GRCAN_DASH_WARNING_FLAGS = 0x02B, -// GRCAN_ECU_ANALOG_DATA = 0x02E, -// GRCAN_GPS_LAT = 0x031, -// GRCAN_GPS_LON = 0x032, -// GRCAN_GPS_ALT = 0x033, -// GRCAN_GPS_PX = 0x034, -// GRCAN_GPS_QY = 0x035, -// GRCAN_GPS_RZ = 0x036, -// GRCAN_UVW_DGPS = 0x030, -// GRCAN_ECU_PERFORMANCE = 0x123, -// } GRCAN_MSG_ID; - GRCAN_MSG_ID get_messageID(GRCAN_BUS_ID bus) { - switch (bus) { + switch ((int)bus) { case GRCAN_BUS_PRIMARY: return GRCAN_ACU_STATUS_1; case GRCAN_BUS_DATA: @@ -133,6 +78,8 @@ GRCAN_MSG_ID get_messageID(GRCAN_BUS_ID bus) return GRCAN_DEBUG_2_0; case GRCAN_BUS_CHARGER: return GRCAN_ACU_CONFIG_CHG_PARAMS; + case GRCAN_BUS_DATA_SUBNET: + return GRCAN_ECU_STATUS_1; default: return (GRCAN_MSG_ID)0xFF; // Invalid message ID } @@ -303,7 +250,7 @@ int FancyCAN_LoopbackTest(void) { GRCAN_BUS_ID bus; - for (bus = GRCAN_BUS_TESTING; bus <= GRCAN_BUS_CHARGER; bus++) { + for (bus = GRCAN_BUS_TESTING; bus <= GRCAN_BUS_CHARGER + 1; bus++) { LOGOMATIC("\n--- Testing bus %d ---\n", bus); int res1 = GRCAN_Validate_InitBus(bus, GRCAN_OPMODE_INTERNAL_LOOPBACK, FDCAN2); // GRCAN_OPMODE_EXTERNAL_LOOPBACK needs to be tested, can change FDCAN: make sure to #define USECANx @@ -320,7 +267,7 @@ int FancyCAN_LoopbackTest(void) res2 = GRCAN_SendReceive(bus, nodeID, dest_nodeID, messageID, data, size); // if (res2 == 0) { uint8_t data_value = *(uint8_t *)data; - switch (bus) { + switch ((int)bus) { case GRCAN_BUS_PRIMARY: LOGOMATIC("Testing Bus:PRIMARY Loopback Test FAILED for message with first byte: %d.\n", data_value); break; @@ -333,6 +280,9 @@ int FancyCAN_LoopbackTest(void) case GRCAN_BUS_TESTING: LOGOMATIC("Testing Bus:TESTING Loopback Test FAILED for message with first byte: %d.\n", data_value); break; + case GRCAN_BUS_DATA_SUBNET: + LOGOMATIC("Testing Bus:DATA_SUBNET Loopback Test FAILED for message with first byte: %d.\n", data_value); + break; default: LOGOMATIC("Testing Bus:UNKNOWN Loopback Test FAILED for message with first byte: %d.\n", data_value); break; @@ -344,7 +294,7 @@ int FancyCAN_LoopbackTest(void) bool res4 = GRCAN_DeactivateBus(bus); if (!res1 || !res2) { - switch (bus) { + switch ((int)bus) { case GRCAN_BUS_PRIMARY: LOGOMATIC("Testing Bus:PRIMARY Loopback Test FAILED during initialization or send/receive test.\n"); break; @@ -357,13 +307,16 @@ int FancyCAN_LoopbackTest(void) case GRCAN_BUS_CHARGER: LOGOMATIC("Testing Bus:CHARGER Loopback Test FAILED during initialization or send/receive test.\n"); break; + case GRCAN_BUS_DATA_SUBNET: + LOGOMATIC("Testing Bus:DATA_SUBNET Loopback Test FAILED during initialization or send/receive test.\n"); + break; default: LOGOMATIC("Testing Bus:UNKNOWN Loopback Test FAILED during initialization or send/receive test.\n"); break; } } if (!res4) { - switch (bus) { + switch ((int)bus) { case GRCAN_BUS_PRIMARY: LOGOMATIC("Testing Bus:PRIMARY Loopback Test FAILED during bus deactivation.\n"); break; @@ -376,6 +329,9 @@ int FancyCAN_LoopbackTest(void) case GRCAN_BUS_CHARGER: LOGOMATIC("Testing Bus:CHARGER Loopback Test FAILED during bus deactivation.\n"); break; + case GRCAN_BUS_DATA_SUBNET: + LOGOMATIC("Testing Bus:DATA_SUBNET Loopback Test FAILED during bus deactivation.\n"); + break; default: LOGOMATIC("Testing Bus:UNKNOWN Loopback Test FAILED during bus deactivation.\n"); break; @@ -383,13 +339,12 @@ int FancyCAN_LoopbackTest(void) } } - if (bus < 4) { + if (bus < 5) { LOGOMATIC("\nLoopback Test FAILED. Not all buses were tested.\n"); return 0; } - // The next tests takes a while, completely fine to remove - for (bus = GRCAN_BUS_TESTING; bus <= GRCAN_BUS_CHARGER; bus++) { + for (bus = GRCAN_BUS_TESTING; bus <= GRCAN_BUS_CHARGER + 1; bus++) { LOGOMATIC("\n--- Testing burst send on bus %d ---\n", bus); GRCAN_Validate_InitBus(bus, GRCAN_OPMODE_INTERNAL_LOOPBACK, FDCAN2); int burst_result = GRCAN_BurstSendTest(bus, get_nodeID(bus), get_nodeID(bus), get_messageID(bus), 100); @@ -400,7 +355,7 @@ int FancyCAN_LoopbackTest(void) GRCAN_DeactivateBus(bus); } - for (bus = GRCAN_BUS_TESTING; bus <= GRCAN_BUS_CHARGER; bus++) { + for (bus = GRCAN_BUS_TESTING; bus <= GRCAN_BUS_CHARGER + 1; bus++) { LOGOMATIC("\n--- Testing init/deactivate stress test on bus %d ---\n", bus); int stress_result = GRCAN_InitDeactivateStressTest(bus, get_nodeID(bus), get_nodeID(bus), get_messageID(bus), FDCAN2, 50); if (!stress_result) { diff --git a/H523xx_CAN_TESTING/Core/Inc/FancyCAN_LoopbackTest.h b/H523xx_CAN_TESTING/Core/Inc/FancyCAN_LoopbackTest.h new file mode 100644 index 000000000..9a2ba9a26 --- /dev/null +++ b/H523xx_CAN_TESTING/Core/Inc/FancyCAN_LoopbackTest.h @@ -0,0 +1,6 @@ +#ifndef FANCYCAN_LOOPBACKTEST_H +#define FANCYCAN_LOOPBACKTEST_H + +int FancyCAN_LoopbackTest(void); + +#endif // FANCYCAN_LOOPBACKTEST_H diff --git a/H523xx_CAN_TESTING/Core/Inc/adc.h b/H523xx_CAN_TESTING/Core/Inc/adc.h new file mode 100644 index 000000000..41154538b --- /dev/null +++ b/H523xx_CAN_TESTING/Core/Inc/adc.h @@ -0,0 +1,49 @@ +/* USER CODE BEGIN Header */ +/** + ****************************************************************************** + * @file adc.h + * @brief This file contains all the function prototypes for + * the adc.c file + ****************************************************************************** + * @attention + * + * Copyright (c) 2024 STMicroelectronics. + * All rights reserved. + * + * This software is licensed under terms that can be found in the LICENSE file + * in the root directory of this software component. + * If no LICENSE file comes with this software, it is provided AS-IS. + * + ****************************************************************************** + */ +/* USER CODE END Header */ +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef __ADC_H__ +#define __ADC_H__ + +#ifdef __cplusplus +extern "C" { +#endif + +/* Includes ------------------------------------------------------------------*/ +#include "main.h" + +/* USER CODE BEGIN Includes */ + +/* USER CODE END Includes */ + +/* USER CODE BEGIN Private defines */ + +/* USER CODE END Private defines */ + +void MX_ADC1_Init(void); + +/* USER CODE BEGIN Prototypes */ + +/* USER CODE END Prototypes */ + +#ifdef __cplusplus +} +#endif + +#endif /* __ADC_H__ */ diff --git a/H523xx_CAN_TESTING/Core/Inc/crc.h b/H523xx_CAN_TESTING/Core/Inc/crc.h new file mode 100644 index 000000000..133957e92 --- /dev/null +++ b/H523xx_CAN_TESTING/Core/Inc/crc.h @@ -0,0 +1,51 @@ +/* USER CODE BEGIN Header */ +/** + ****************************************************************************** + * @file crc.h + * @brief This file contains all the function prototypes for + * the crc.c file + ****************************************************************************** + * @attention + * + * Copyright (c) 2024 STMicroelectronics. + * All rights reserved. + * + * This software is licensed under terms that can be found in the LICENSE file + * in the root directory of this software component. + * If no LICENSE file comes with this software, it is provided AS-IS. + * + ****************************************************************************** + */ +/* USER CODE END Header */ +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef __CRC_H__ +#define __CRC_H__ + +#ifdef __cplusplus +extern "C" { +#endif + +/* Includes ------------------------------------------------------------------*/ +#include "main.h" + +/* USER CODE BEGIN Includes */ + +/* USER CODE END Includes */ + +extern CRC_HandleTypeDef hcrc; + +/* USER CODE BEGIN Private defines */ + +/* USER CODE END Private defines */ + +void MX_CRC_Init(void); + +/* USER CODE BEGIN Prototypes */ + +/* USER CODE END Prototypes */ + +#ifdef __cplusplus +} +#endif + +#endif /* __CRC_H__ */ diff --git a/H523xx_CAN_TESTING/Core/Inc/dma.h b/H523xx_CAN_TESTING/Core/Inc/dma.h new file mode 100644 index 000000000..ae819cab4 --- /dev/null +++ b/H523xx_CAN_TESTING/Core/Inc/dma.h @@ -0,0 +1,51 @@ +/* USER CODE BEGIN Header */ +/** + ****************************************************************************** + * @file dma.h + * @brief This file contains all the function prototypes for + * the dma.c file + ****************************************************************************** + * @attention + * + * Copyright (c) 2025 STMicroelectronics. + * All rights reserved. + * + * This software is licensed under terms that can be found in the LICENSE file + * in the root directory of this software component. + * If no LICENSE file comes with this software, it is provided AS-IS. + * + ****************************************************************************** + */ +/* USER CODE END Header */ +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef __DMA_H__ +#define __DMA_H__ + +#ifdef __cplusplus +extern "C" { +#endif + +/* Includes ------------------------------------------------------------------*/ +#include "main.h" + +/* DMA memory to memory transfer handles -------------------------------------*/ + +/* USER CODE BEGIN Includes */ + +/* USER CODE END Includes */ + +/* USER CODE BEGIN Private defines */ + +/* USER CODE END Private defines */ + +void MX_DMA_Init(void); + +/* USER CODE BEGIN Prototypes */ + +/* USER CODE END Prototypes */ + +#ifdef __cplusplus +} +#endif + +#endif /* __DMA_H__ */ diff --git a/H523xx_CAN_TESTING/Core/Inc/fdcan.h b/H523xx_CAN_TESTING/Core/Inc/fdcan.h new file mode 100644 index 000000000..56c4a8adb --- /dev/null +++ b/H523xx_CAN_TESTING/Core/Inc/fdcan.h @@ -0,0 +1,51 @@ +/* USER CODE BEGIN Header */ +/** + ****************************************************************************** + * @file fdcan.h + * @brief This file contains all the function prototypes for + * the fdcan.c file + ****************************************************************************** + * @attention + * + * Copyright (c) 2024 STMicroelectronics. + * All rights reserved. + * + * This software is licensed under terms that can be found in the LICENSE file + * in the root directory of this software component. + * If no LICENSE file comes with this software, it is provided AS-IS. + * + ****************************************************************************** + */ +/* USER CODE END Header */ +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef __FDCAN_H__ +#define __FDCAN_H__ + +#ifdef __cplusplus +extern "C" { +#endif + +/* Includes ------------------------------------------------------------------*/ +#include "main.h" + +/* USER CODE BEGIN Includes */ + +/* USER CODE END Includes */ + +extern FDCAN_HandleTypeDef hfdcan2; + +/* USER CODE BEGIN Private defines */ + +/* USER CODE END Private defines */ + +void MX_FDCAN2_Init(void); + +/* USER CODE BEGIN Prototypes */ + +/* USER CODE END Prototypes */ + +#ifdef __cplusplus +} +#endif + +#endif /* __FDCAN_H__ */ diff --git a/H523xx_CAN_TESTING/Core/Inc/gpio.h b/H523xx_CAN_TESTING/Core/Inc/gpio.h new file mode 100644 index 000000000..843d4e9e7 --- /dev/null +++ b/H523xx_CAN_TESTING/Core/Inc/gpio.h @@ -0,0 +1,48 @@ +/* USER CODE BEGIN Header */ +/** + ****************************************************************************** + * @file gpio.h + * @brief This file contains all the function prototypes for + * the gpio.c file + ****************************************************************************** + * @attention + * + * Copyright (c) 2024 STMicroelectronics. + * All rights reserved. + * + * This software is licensed under terms that can be found in the LICENSE file + * in the root directory of this software component. + * If no LICENSE file comes with this software, it is provided AS-IS. + * + ****************************************************************************** + */ +/* USER CODE END Header */ +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef __GPIO_H__ +#define __GPIO_H__ + +#ifdef __cplusplus +extern "C" { +#endif + +/* Includes ------------------------------------------------------------------*/ +#include "main.h" + +/* USER CODE BEGIN Includes */ + +/* USER CODE END Includes */ + +/* USER CODE BEGIN Private defines */ + +/* USER CODE END Private defines */ + +void MX_GPIO_Init(void); + +/* USER CODE BEGIN Prototypes */ + +/* USER CODE END Prototypes */ + +#ifdef __cplusplus +} +#endif +#endif /*__ GPIO_H__ */ diff --git a/H523xx_CAN_TESTING/Core/Inc/i2c.h b/H523xx_CAN_TESTING/Core/Inc/i2c.h new file mode 100644 index 000000000..0a0a50803 --- /dev/null +++ b/H523xx_CAN_TESTING/Core/Inc/i2c.h @@ -0,0 +1,49 @@ +/* USER CODE BEGIN Header */ +/** + ****************************************************************************** + * @file i2c.h + * @brief This file contains all the function prototypes for + * the i2c.c file + ****************************************************************************** + * @attention + * + * Copyright (c) 2025 STMicroelectronics. + * All rights reserved. + * + * This software is licensed under terms that can be found in the LICENSE file + * in the root directory of this software component. + * If no LICENSE file comes with this software, it is provided AS-IS. + * + ****************************************************************************** + */ +/* USER CODE END Header */ +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef __I2C_H__ +#define __I2C_H__ + +#ifdef __cplusplus +extern "C" { +#endif + +/* Includes ------------------------------------------------------------------*/ +#include "main.h" + +/* USER CODE BEGIN Includes */ + +/* USER CODE END Includes */ + +/* USER CODE BEGIN Private defines */ + +/* USER CODE END Private defines */ + +void MX_I2C2_Init(void); + +/* USER CODE BEGIN Prototypes */ + +/* USER CODE END Prototypes */ + +#ifdef __cplusplus +} +#endif + +#endif /* __I2C_H__ */ diff --git a/H523xx_CAN_TESTING/Core/Inc/main.h b/H523xx_CAN_TESTING/Core/Inc/main.h new file mode 100644 index 000000000..e8511a935 --- /dev/null +++ b/H523xx_CAN_TESTING/Core/Inc/main.h @@ -0,0 +1,115 @@ +/* USER CODE BEGIN Header */ +/** + ****************************************************************************** + * @file : main.h + * @brief : Header for main.c file. + * This file contains the common defines of the application. + ****************************************************************************** + * @attention + * + * Copyright (c) 2024 STMicroelectronics. + * All rights reserved. + * + * This software is licensed under terms that can be found in the LICENSE file + * in the root directory of this software component. + * If no LICENSE file comes with this software, it is provided AS-IS. + * + ****************************************************************************** + */ +/* USER CODE END Header */ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef __MAIN_H +#define __MAIN_H + +#ifdef __cplusplus +extern "C" { +#endif + +/* Includes ------------------------------------------------------------------*/ +#include "stm32h5xx_hal.h" +#include "stm32h5xx_ll_adc.h" +#include "stm32h5xx_ll_bus.h" +#include "stm32h5xx_ll_cortex.h" +#include "stm32h5xx_ll_crs.h" +#include "stm32h5xx_ll_dma.h" +#include "stm32h5xx_ll_exti.h" +#include "stm32h5xx_ll_gpio.h" +#include "stm32h5xx_ll_i2c.h" +#include "stm32h5xx_ll_lpuart.h" +#include "stm32h5xx_ll_pwr.h" +#include "stm32h5xx_ll_rcc.h" +#include "stm32h5xx_ll_spi.h" +#include "stm32h5xx_ll_system.h" +#include "stm32h5xx_ll_tim.h" +#include "stm32h5xx_ll_usart.h" +#include "stm32h5xx_ll_utils.h" + +/* Private includes ----------------------------------------------------------*/ +/* USER CODE BEGIN Includes */ + +/* USER CODE END Includes */ + +/* Exported types ------------------------------------------------------------*/ +/* USER CODE BEGIN ET */ + +/* USER CODE END ET */ + +/* Exported constants --------------------------------------------------------*/ +/* USER CODE BEGIN EC */ + +/* USER CODE END EC */ + +/* Exported macro ------------------------------------------------------------*/ +/* USER CODE BEGIN EM */ + +/* USER CODE END EM */ + +/* Exported functions prototypes ---------------------------------------------*/ +void Error_Handler(void); + +/* USER CODE BEGIN EFP */ + +/* USER CODE END EFP */ + +/* Private defines -----------------------------------------------------------*/ +#define BSPD_SIGNAL_Pin LL_GPIO_PIN_1 +#define BSPD_SIGNAL_GPIO_Port GPIOC +#define APPS1_SIGNAL_Pin LL_GPIO_PIN_2 +#define APPS1_SIGNAL_GPIO_Port GPIOC +#define APPS2_SIGNAL_Pin LL_GPIO_PIN_3 +#define APPS2_SIGNAL_GPIO_Port GPIOC +#define BLINKY_Pin LL_GPIO_PIN_5 +#define BLINKY_GPIO_Port GPIOA +#define IMD_SENSE_Pin LL_GPIO_PIN_6 +#define IMD_SENSE_GPIO_Port GPIOA +#define AMS_SENSE_Pin LL_GPIO_PIN_7 +#define AMS_SENSE_GPIO_Port GPIOA +#define BRAKE_F_SIGNAL_Pin LL_GPIO_PIN_0 +#define BRAKE_F_SIGNAL_GPIO_Port GPIOB +#define BRAKE_R_SIGNAL_Pin LL_GPIO_PIN_1 +#define BRAKE_R_SIGNAL_GPIO_Port GPIOB +#define LED_TEST_Pin LL_GPIO_PIN_11 +#define LED_TEST_GPIO_Port GPIOB +#define AUX_SIGNAL_Pin LL_GPIO_PIN_14 +#define AUX_SIGNAL_GPIO_Port GPIOB +#define STEERING_ANGLE_Pin LL_GPIO_PIN_15 +#define STEERING_ANGLE_GPIO_Port GPIOB +#define BRAKE_LIGHT_Pin LL_GPIO_PIN_4 +#define BRAKE_LIGHT_GPIO_Port GPIOB +#define TSSI_G_CONTROL_Pin LL_GPIO_PIN_5 +#define TSSI_G_CONTROL_GPIO_Port GPIOB +#define AUX_CONTROL_Pin LL_GPIO_PIN_8 +#define AUX_CONTROL_GPIO_Port GPIOB +#define SOFTWARE_OK_CONTROL_Pin LL_GPIO_PIN_9 +#define SOFTWARE_OK_CONTROL_GPIO_Port GPIOB + +/* USER CODE BEGIN Private defines */ + +/* USER CODE END Private defines */ + +#ifdef __cplusplus +} +#endif + +#endif /* __MAIN_H */ diff --git a/H523xx_CAN_TESTING/Core/Inc/spi.h b/H523xx_CAN_TESTING/Core/Inc/spi.h new file mode 100644 index 000000000..74bed003b --- /dev/null +++ b/H523xx_CAN_TESTING/Core/Inc/spi.h @@ -0,0 +1,49 @@ +/* USER CODE BEGIN Header */ +/** + ****************************************************************************** + * @file spi.h + * @brief This file contains all the function prototypes for + * the spi.c file + ****************************************************************************** + * @attention + * + * Copyright (c) 2024 STMicroelectronics. + * All rights reserved. + * + * This software is licensed under terms that can be found in the LICENSE file + * in the root directory of this software component. + * If no LICENSE file comes with this software, it is provided AS-IS. + * + ****************************************************************************** + */ +/* USER CODE END Header */ +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef __SPI_H__ +#define __SPI_H__ + +#ifdef __cplusplus +extern "C" { +#endif + +/* Includes ------------------------------------------------------------------*/ +#include "main.h" + +/* USER CODE BEGIN Includes */ + +/* USER CODE END Includes */ + +/* USER CODE BEGIN Private defines */ + +/* USER CODE END Private defines */ + +void MX_SPI3_Init(void); + +/* USER CODE BEGIN Prototypes */ + +/* USER CODE END Prototypes */ + +#ifdef __cplusplus +} +#endif + +#endif /* __SPI_H__ */ diff --git a/H523xx_CAN_TESTING/Core/Inc/stm32h5xx_hal_conf.h b/H523xx_CAN_TESTING/Core/Inc/stm32h5xx_hal_conf.h new file mode 100644 index 000000000..8c03cc07d --- /dev/null +++ b/H523xx_CAN_TESTING/Core/Inc/stm32h5xx_hal_conf.h @@ -0,0 +1,473 @@ +/* USER CODE BEGIN Header */ +/** + ********************************************************************************************************************** + + * @file stm32h5xx_hal_conf.h + * @author MCD Application Team + * @brief HAL configuration file. + ********************************************************************************************************************** + + * @attention + * + * Copyright (c) 2023 STMicroelectronics. + * All rights reserved. + * + * This software is licensed under terms that can be found in the LICENSE file + * in the root directory of this software component. + * If no LICENSE file comes with this software, it is provided AS-IS. + * + ********************************************************************************************************************** + + */ +/* USER CODE END Header */ + +/* Define to prevent recursive inclusion -----------------------------------------------------------------------------*/ + +#ifndef STM32H5xx_HAL_CONF_H +#define STM32H5xx_HAL_CONF_H + +#ifdef __cplusplus +extern "C" { +#endif + +/* Exported types ----------------------------------------------------------------------------------------------------*/ +/* Exported constants ------------------------------------------------------------------------------------------------*/ + +/* ########################################### Module Selection ##################################################### */ + +/** + * @brief This is the list of modules to be used in the HAL driver + */ + +#define HAL_MODULE_ENABLED +/*#define HAL_ADC_MODULE_ENABLED */ +/*#define HAL_CEC_MODULE_ENABLED */ +/*#define HAL_CRC_MODULE_ENABLED */ +/*#define HAL_CRYP_MODULE_ENABLED */ +/*#define HAL_DAC_MODULE_ENABLED */ +/*#define HAL_DCACHE_MODULE_ENABLED */ +/*#define HAL_DCMI_MODULE_ENABLED */ +/*#define HAL_DTS_MODULE_ENABLED */ +#define HAL_FDCAN_MODULE_ENABLED +/*#define HAL_GTZC_MODULE_ENABLED */ +/*#define HAL_HASH_MODULE_ENABLED */ +/*#define HAL_IWDG_MODULE_ENABLED */ +/*#define HAL_I2C_MODULE_ENABLED */ +/*#define HAL_I3C_MODULE_ENABLED */ +/*#define HAL_I2S_MODULE_ENABLED */ +/*#define HAL_LPTIM_MODULE_ENABLED */ +/*#define HAL_NAND_MODULE_ENABLED */ +/*#define HAL_NOR_MODULE_ENABLED */ +/*#define HAL_XSPI_MODULE_ENABLED */ +/*#define HAL_OTFDEC_MODULE_ENABLED */ +/*#define HAL_PKA_MODULE_ENABLED */ +/*#define HAL_RNG_MODULE_ENABLED */ +/*#define HAL_RTC_MODULE_ENABLED */ +/*#define HAL_SD_MODULE_ENABLED */ +/*#define HAL_MMC_MODULE_ENABLED */ +/*#define HAL_SPI_MODULE_ENABLED */ +/*#define HAL_SRAM_MODULE_ENABLED */ +/*#define HAL_TIM_MODULE_ENABLED */ +/*#define HAL_RAMCFG_MODULE_ENABLED */ +/*#define HAL_UART_MODULE_ENABLED */ +/*#define HAL_USART_MODULE_ENABLED */ +/*#define HAL_WWDG_MODULE_ENABLED */ +/*#define HAL_PSSI_MODULE_ENABLED */ +/*#define HAL_ICACHE_MODULE_ENABLED */ +/*#define HAL_PCD_MODULE_ENABLED */ +/*#define HAL_HCD_MODULE_ENABLED */ +/*#define HAL_SMARTCARD_MODULE_ENABLED */ +/*#define HAL_SMBUS_MODULE_ENABLED */ +/*#define HAL_IRDA_MODULE_ENABLED */ +#define HAL_GPIO_MODULE_ENABLED +#define HAL_EXTI_MODULE_ENABLED +#define HAL_DMA_MODULE_ENABLED +#define HAL_RCC_MODULE_ENABLED +#define HAL_FLASH_MODULE_ENABLED +#define HAL_PWR_MODULE_ENABLED +#define HAL_CORTEX_MODULE_ENABLED + +/* ####################################### Oscillator Values adaptation ##############################################*/ + +/** + * @brief Adjust the value of External High Speed oscillator (HSE) used in your application. + * This value is used by the RCC HAL module to compute the system frequency + * (when HSE is used as system clock source, directly or through the PLL). + */ +#if !defined(HSE_VALUE) +#define HSE_VALUE 25000000U /*!< Value of the External oscillator in Hz */ +#endif /* HSE_VALUE */ + +#if !defined(HSE_STARTUP_TIMEOUT) +#define HSE_STARTUP_TIMEOUT 100U /*!< Time out for HSE start up, in ms */ +#endif /* HSE_STARTUP_TIMEOUT */ + +/** + * @brief Internal Core Speed oscillator (CSI) default value. + * This value is the default CSI range value after Reset. + */ +#if !defined(CSI_VALUE) +#define CSI_VALUE 4000000UL /*!< Value of the Internal oscillator in Hz*/ +#endif /* CSI_VALUE */ + +/** + * @brief Internal High Speed oscillator (HSI) value. + * This value is used by the RCC HAL module to compute the system frequency + * (when HSI is used as system clock source, directly or through the PLL). + */ +#if !defined(HSI_VALUE) +#define HSI_VALUE 64000000UL /*!< Value of the Internal oscillator in Hz*/ +#endif /* HSI_VALUE */ + +/** + * @brief Internal High Speed oscillator (HSI48) value for USB FS, SDMMC and RNG. + * This internal oscillator is mainly dedicated to provide a high precision clock to + * the USB peripheral by means of a special Clock Recovery System (CRS) circuitry. + * When the CRS is not used, the HSI48 RC oscillator runs on it default frequency + * which is subject to manufacturing process variations. + */ +#if !defined(HSI48_VALUE) +#define HSI48_VALUE \ + 48000000UL /*!< Value of the Internal High Speed oscillator for USB FS/SDMMC/RNG in Hz. \ + The real value my vary depending on manufacturing process variations.*/ +#endif /* HSI48_VALUE */ + +/** + * @brief Internal Low Speed oscillator (LSI) value. + */ +#if !defined(LSI_VALUE) +#define LSI_VALUE 32000UL /*!< LSI Typical Value in Hz*/ +#endif /* LSI_VALUE */ /*!< Value of the Internal Low Speed oscillator in Hz \ + The real value may vary depending on the variations \ + in voltage and temperature.*/ + +#if !defined(LSI_STARTUP_TIME) +#define LSI_STARTUP_TIME 130UL /*!< Time out for LSI start up, in us */ +#endif /* LSI_STARTUP_TIME */ + +/** + * @brief External Low Speed oscillator (LSE) value. + * This value is used by the UART, RTC HAL module to compute the system frequency + */ +#if !defined(LSE_VALUE) +#define LSE_VALUE 32768UL /*!< Value of the External oscillator in Hz*/ +#endif /* LSE_VALUE */ + +#if !defined(LSE_STARTUP_TIMEOUT) +#define LSE_STARTUP_TIMEOUT 5000UL /*!< Time out for LSE start up, in ms */ +#endif /* LSE_STARTUP_TIMEOUT */ +/** + * @brief External clock source for SPI peripheral + * This value is used by the SPI HAL module to compute the SPI clock source + * frequency, this source is inserted directly through I2S_CKIN pad. + + */ +#if !defined(EXTERNAL_CLOCK_VALUE) +#define EXTERNAL_CLOCK_VALUE 12288000UL /*!< Value of the External clock in Hz*/ +#endif /* EXTERNAL_CLOCK_VALUE */ + +/* Tip: To avoid modifying this file each time you need to use different HSE, + === you can define the HSE value in your toolchain compiler preprocessor. */ + +/* ############################################ System Configuration ################################################ */ + +/** + * @brief This is the HAL system configuration section + */ + +#define VDD_VALUE 3300UL /*!< Value of VDD in mv */ +#define TICK_INT_PRIORITY (15UL) /*!< tick interrupt priority (lowest by default) */ +#define USE_RTOS 0U +#define PREFETCH_ENABLE 0U /*!< Enable prefetch */ + +/* ############################################ Assert Selection #################################################### */ + +/** + * @brief Uncomment the line below to expanse the "assert_param" macro in the + * HAL drivers code + */ + +/* #define USE_FULL_ASSERT 1U */ + +/* ############################################ Register callback feature configuration ############################# */ + +/** + * @brief Set below the peripheral configuration to "1U" to add the support + * of HAL callback registration/unregistration feature for the HAL + * driver(s). This allows user application to provide specific callback + * functions thanks to HAL_PPP_RegisterCallback() rather than overwriting + * the default weak callback functions (see each stm32h5xx_hal_ppp.h file + * for possible callback identifiers defined in HAL_PPP_CallbackIDTypeDef + * for each PPP peripheral). + */ +#define USE_HAL_ADC_REGISTER_CALLBACKS 0U /* ADC register callback disabled */ +#define USE_HAL_CEC_REGISTER_CALLBACKS 0U /* CEC register callback disabled */ +#define USE_HAL_CRYP_REGISTER_CALLBACKS 0U /* CRYP register callback disabled */ +#define USE_HAL_DAC_REGISTER_CALLBACKS 0U /* DAC register callback disabled */ +#define USE_HAL_DCMI_REGISTER_CALLBACKS 0U /* DCMI register callback disabled */ +#define USE_HAL_DTS_REGISTER_CALLBACKS 0U /* DTS register callback disabled */ +#define USE_HAL_FDCAN_REGISTER_CALLBACKS 0U /* FDCAN register callback disabled */ +#define USE_HAL_NOR_REGISTER_CALLBACKS 0U /* NOR register callback disabled */ +#define USE_HAL_HASH_REGISTER_CALLBACKS 0U /* HASH register callback disabled */ +#define USE_HAL_HCD_REGISTER_CALLBACKS 0U /* HCD register callback disabled */ +#define USE_HAL_I2C_REGISTER_CALLBACKS 0U /* I2C register callback disabled */ +#define USE_HAL_I2S_REGISTER_CALLBACKS 0U /* I2S register callback disabled */ +#define USE_HAL_I3C_REGISTER_CALLBACKS 0U /* I3C register callback disabled */ +#define USE_HAL_IRDA_REGISTER_CALLBACKS 0U /* IRDA register callback disabled */ +#define USE_HAL_IWDG_REGISTER_CALLBACKS 0U /* IWDG register callback disabled */ +#define USE_HAL_LPTIM_REGISTER_CALLBACKS 0U /* LPTIM register callback disabled */ +#define USE_HAL_MMC_REGISTER_CALLBACKS 0U /* MMC register callback disabled */ +#define USE_HAL_NAND_REGISTER_CALLBACKS 0U /* NAND register callback disabled */ +#define USE_HAL_OTFDEC_REGISTER_CALLBACKS 0U /* OTFDEC register callback disabled */ +#define USE_HAL_PCD_REGISTER_CALLBACKS 0U /* PCD register callback disabled */ +#define USE_HAL_PKA_REGISTER_CALLBACKS 0U /* PKA register callback disabled */ +#define USE_HAL_RAMCFG_REGISTER_CALLBACKS 0U /* RAMCFG register callback disabled */ +#define USE_HAL_RNG_REGISTER_CALLBACKS 0U /* RNG register callback disabled */ +#define USE_HAL_RTC_REGISTER_CALLBACKS 0U /* RTC register callback disabled */ +#define USE_HAL_SD_REGISTER_CALLBACKS 0U /* SD register callback disabled */ +#define USE_HAL_SDIO_REGISTER_CALLBACKS 0U /* SDIO register callback disabled */ +#define USE_HAL_SMARTCARD_REGISTER_CALLBACKS 0U /* SMARTCARD register callback disabled */ +#define USE_HAL_SMBUS_REGISTER_CALLBACKS 0U /* SMBUS register callback disabled */ +#define USE_HAL_SPI_REGISTER_CALLBACKS 0U /* SPI register callback disabled */ +#define USE_HAL_SRAM_REGISTER_CALLBACKS 0U /* SRAM register callback disabled */ +#define USE_HAL_TIM_REGISTER_CALLBACKS 0U /* TIM register callback disabled */ +#define USE_HAL_UART_REGISTER_CALLBACKS 0U /* UART register callback disabled */ +#define USE_HAL_USART_REGISTER_CALLBACKS 0U /* USART register callback disabled */ +#define USE_HAL_WWDG_REGISTER_CALLBACKS 0U /* WWDG register callback disabled */ +#define USE_HAL_XSPI_REGISTER_CALLBACKS 0U /* XSPI register callback disabled */ + +/* ############################################ SPI peripheral configuration ######################################## */ + +/* CRC FEATURE: Use to activate CRC feature inside HAL SPI Driver + * Activated: CRC code is present inside driver + * Deactivated: CRC code cleaned from driver + */ +#define USE_SPI_CRC 0U + +/* ################## SDMMC peripheral configuration ######################### */ + +#define USE_SD_TRANSCEIVER 0U + +/* ################## SDIO peripheral configuration ######################### */ + +#define USE_SDIO_TRANSCEIVER 0U +#define SDIO_MAX_IO_NUMBER 7U + +/* Includes ----------------------------------------------------------------------------------------------------------*/ + +/** + * @brief Include module's header file + */ + +#ifdef HAL_RCC_MODULE_ENABLED +#include "stm32h5xx_hal_rcc.h" +#endif /* HAL_RCC_MODULE_ENABLED */ + +#ifdef HAL_GPIO_MODULE_ENABLED +#include "stm32h5xx_hal_gpio.h" +#endif /* HAL_GPIO_MODULE_ENABLED */ + +#ifdef HAL_ICACHE_MODULE_ENABLED +#include "stm32h5xx_hal_icache.h" +#endif /* HAL_ICACHE_MODULE_ENABLED */ + +#ifdef HAL_DCACHE_MODULE_ENABLED +#include "stm32h5xx_hal_dcache.h" +#endif /* HAL_DCACHE_MODULE_ENABLED */ + +#ifdef HAL_GTZC_MODULE_ENABLED +#include "stm32h5xx_hal_gtzc.h" +#endif /* HAL_GTZC_MODULE_ENABLED */ + +#ifdef HAL_DMA_MODULE_ENABLED +#include "stm32h5xx_hal_dma.h" +#endif /* HAL_DMA_MODULE_ENABLED */ + +#ifdef HAL_DTS_MODULE_ENABLED +#include "stm32h5xx_hal_dts.h" +#endif /* HAL_DTS_MODULE_ENABLED */ + +#ifdef HAL_CORTEX_MODULE_ENABLED +#include "stm32h5xx_hal_cortex.h" +#endif /* HAL_CORTEX_MODULE_ENABLED */ + +#ifdef HAL_PKA_MODULE_ENABLED +#include "stm32h5xx_hal_pka.h" +#endif /* HAL_PKA_MODULE_ENABLED */ + +#ifdef HAL_ADC_MODULE_ENABLED +#include "stm32h5xx_hal_adc.h" +#endif /* HAL_ADC_MODULE_ENABLED */ + +#ifdef HAL_CRC_MODULE_ENABLED +#include "stm32h5xx_hal_crc.h" +#endif /* HAL_CRC_MODULE_ENABLED */ + +#ifdef HAL_CRYP_MODULE_ENABLED +#include "stm32h5xx_hal_cryp.h" +#endif /* HAL_CRYP_MODULE_ENABLED */ + +#ifdef HAL_DAC_MODULE_ENABLED +#include "stm32h5xx_hal_dac.h" +#endif /* HAL_DAC_MODULE_ENABLED */ + +#ifdef HAL_FLASH_MODULE_ENABLED +#include "stm32h5xx_hal_flash.h" +#endif /* HAL_FLASH_MODULE_ENABLED */ + +#ifdef HAL_HASH_MODULE_ENABLED +#include "stm32h5xx_hal_hash.h" +#endif /* HAL_HASH_MODULE_ENABLED */ + +#ifdef HAL_SRAM_MODULE_ENABLED +#include "stm32h5xx_hal_sram.h" +#endif /* HAL_SRAM_MODULE_ENABLED */ + +#ifdef HAL_SDIO_MODULE_ENABLED +#include "stm32h5xx_hal_sdio.h" +#endif /* HAL_SDIO_MODULE_ENABLED */ + +#ifdef HAL_MMC_MODULE_ENABLED +#include "stm32h5xx_hal_mmc.h" +#endif /* HAL_MMC_MODULE_ENABLED */ + +#ifdef HAL_NOR_MODULE_ENABLED +#include "stm32h5xx_hal_nor.h" +#endif /* HAL_NOR_MODULE_ENABLED */ + +#ifdef HAL_NAND_MODULE_ENABLED +#include "stm32h5xx_hal_nand.h" +#endif /* HAL_NAND_MODULE_ENABLED */ + +#ifdef HAL_I2C_MODULE_ENABLED +#include "stm32h5xx_hal_i2c.h" +#endif /* HAL_I2C_MODULE_ENABLED */ + +#ifdef HAL_I2S_MODULE_ENABLED +#include "stm32h5xx_hal_i2s.h" +#endif /* HAL_I2S_MODULE_ENABLED */ + +#ifdef HAL_I3C_MODULE_ENABLED +#include "stm32h5xx_hal_i3c.h" +#endif /* HAL_I3C_MODULE_ENABLED */ + +#ifdef HAL_IWDG_MODULE_ENABLED +#include "stm32h5xx_hal_iwdg.h" +#endif /* HAL_IWDG_MODULE_ENABLED */ + +#ifdef HAL_LPTIM_MODULE_ENABLED +#include "stm32h5xx_hal_lptim.h" +#endif /* HAL_LPTIM_MODULE_ENABLED */ + +#ifdef HAL_PWR_MODULE_ENABLED +#include "stm32h5xx_hal_pwr.h" +#endif /* HAL_PWR_MODULE_ENABLED */ + +#ifdef HAL_XSPI_MODULE_ENABLED +#include "stm32h5xx_hal_xspi.h" +#endif /* HAL_XSPI_MODULE_ENABLED */ + +#ifdef HAL_RNG_MODULE_ENABLED +#include "stm32h5xx_hal_rng.h" +#endif /* HAL_RNG_MODULE_ENABLED */ + +#ifdef HAL_RTC_MODULE_ENABLED +#include "stm32h5xx_hal_rtc.h" +#endif /* HAL_RTC_MODULE_ENABLED */ + +#ifdef HAL_SD_MODULE_ENABLED +#include "stm32h5xx_hal_sd.h" +#endif /* HAL_SD_MODULE_ENABLED */ + +#ifdef HAL_SMBUS_MODULE_ENABLED +#include "stm32h5xx_hal_smbus.h" +#endif /* HAL_SMBUS_MODULE_ENABLED */ + +#ifdef HAL_SPI_MODULE_ENABLED +#include "stm32h5xx_hal_spi.h" +#endif /* HAL_SPI_MODULE_ENABLED */ + +#ifdef HAL_TIM_MODULE_ENABLED +#include "stm32h5xx_hal_tim.h" +#endif /* HAL_TIM_MODULE_ENABLED */ + +#ifdef HAL_UART_MODULE_ENABLED +#include "stm32h5xx_hal_uart.h" +#endif /* HAL_UART_MODULE_ENABLED */ + +#ifdef HAL_USART_MODULE_ENABLED +#include "stm32h5xx_hal_usart.h" +#endif /* HAL_USART_MODULE_ENABLED */ + +#ifdef HAL_IRDA_MODULE_ENABLED +#include "stm32h5xx_hal_irda.h" +#endif /* HAL_IRDA_MODULE_ENABLED */ + +#ifdef HAL_SMARTCARD_MODULE_ENABLED +#include "stm32h5xx_hal_smartcard.h" +#endif /* HAL_SMARTCARD_MODULE_ENABLED */ + +#ifdef HAL_WWDG_MODULE_ENABLED +#include "stm32h5xx_hal_wwdg.h" +#endif /* HAL_WWDG_MODULE_ENABLED */ + +#ifdef HAL_PCD_MODULE_ENABLED +#include "stm32h5xx_hal_pcd.h" +#endif /* HAL_PCD_MODULE_ENABLED */ + +#ifdef HAL_HCD_MODULE_ENABLED +#include "stm32h5xx_hal_hcd.h" +#endif /* HAL_HCD_MODULE_ENABLED */ + +#ifdef HAL_DCMI_MODULE_ENABLED +#include "stm32h5xx_hal_dcmi.h" +#endif /* HAL_DCMI_MODULE_ENABLED */ + +#ifdef HAL_EXTI_MODULE_ENABLED +#include "stm32h5xx_hal_exti.h" +#endif /* HAL_EXTI_MODULE_ENABLED */ + +#ifdef HAL_FDCAN_MODULE_ENABLED +#include "stm32h5xx_hal_fdcan.h" +#endif /* HAL_FDCAN_MODULE_ENABLED */ + +#ifdef HAL_CEC_MODULE_ENABLED +#include "stm32h5xx_hal_cec.h" +#endif /* HAL_CEC_MODULE_ENABLED */ + +#ifdef HAL_OTFDEC_MODULE_ENABLED +#include "stm32h5xx_hal_otfdec.h" +#endif /* HAL_OTFDEC_MODULE_ENABLED */ + +#ifdef HAL_PSSI_MODULE_ENABLED +#include "stm32h5xx_hal_pssi.h" +#endif /* HAL_PSSI_MODULE_ENABLED */ + +#ifdef HAL_RAMCFG_MODULE_ENABLED +#include "stm32h5xx_hal_ramcfg.h" +#endif /* HAL_RAMCFG_MODULE_ENABLED */ + +/* Exported macro ----------------------------------------------------------------------------------------------------*/ + +#ifdef USE_FULL_ASSERT +/** + * @brief The assert_param macro is used for function's parameters check. + * @param expr: If expr is false, it calls assert_failed function + * which reports the name of the source file and the source + * line number of the call that failed. + * If expr is true, it returns no value. + * @retval None + */ +#define assert_param(expr) ((expr) ? (void)0U : assert_failed((uint8_t *)__FILE__, __LINE__)) +/* Exported functions ----------------------------------------------------------------------------------------------- */ + +void assert_failed(uint8_t *file, uint32_t line); +#else +#define assert_param(expr) ((void)0U) +#endif /* USE_FULL_ASSERT */ + +#ifdef __cplusplus +} +#endif + +#endif /* STM32H5xx_HAL_CONF_H */ diff --git a/H523xx_CAN_TESTING/Core/Inc/stm32h5xx_it.h b/H523xx_CAN_TESTING/Core/Inc/stm32h5xx_it.h new file mode 100644 index 000000000..3ceea5ce8 --- /dev/null +++ b/H523xx_CAN_TESTING/Core/Inc/stm32h5xx_it.h @@ -0,0 +1,66 @@ +/* USER CODE BEGIN Header */ +/** + ****************************************************************************** + * @file stm32h5xx_it.h + * @brief This file contains the headers of the interrupt handlers. + ****************************************************************************** + * @attention + * + * Copyright (c) 2026 STMicroelectronics. + * All rights reserved. + * + * This software is licensed under terms that can be found in the LICENSE file + * in the root directory of this software component. + * If no LICENSE file comes with this software, it is provided AS-IS. + * + ****************************************************************************** + */ +/* USER CODE END Header */ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef __STM32H5xx_IT_H +#define __STM32H5xx_IT_H + +#ifdef __cplusplus +extern "C" { +#endif + +/* Private includes ----------------------------------------------------------*/ +/* USER CODE BEGIN Includes */ + +/* USER CODE END Includes */ + +/* Exported types ------------------------------------------------------------*/ +/* USER CODE BEGIN ET */ + +/* USER CODE END ET */ + +/* Exported constants --------------------------------------------------------*/ +/* USER CODE BEGIN EC */ + +/* USER CODE END EC */ + +/* Exported macro ------------------------------------------------------------*/ +/* USER CODE BEGIN EM */ + +/* USER CODE END EM */ + +/* Exported functions prototypes ---------------------------------------------*/ +void NMI_Handler(void); +void HardFault_Handler(void); +void MemManage_Handler(void); +void BusFault_Handler(void); +void UsageFault_Handler(void); +void SVC_Handler(void); +void DebugMon_Handler(void); +void PendSV_Handler(void); +void SysTick_Handler(void); +/* USER CODE BEGIN EFP */ + +/* USER CODE END EFP */ + +#ifdef __cplusplus +} +#endif + +#endif /* __STM32H5xx_IT_H */ diff --git a/H523xx_CAN_TESTING/Core/Inc/tim.h b/H523xx_CAN_TESTING/Core/Inc/tim.h new file mode 100644 index 000000000..c19e6cc71 --- /dev/null +++ b/H523xx_CAN_TESTING/Core/Inc/tim.h @@ -0,0 +1,49 @@ +/* USER CODE BEGIN Header */ +/** + ****************************************************************************** + * @file tim.h + * @brief This file contains all the function prototypes for + * the tim.c file + ****************************************************************************** + * @attention + * + * Copyright (c) 2025 STMicroelectronics. + * All rights reserved. + * + * This software is licensed under terms that can be found in the LICENSE file + * in the root directory of this software component. + * If no LICENSE file comes with this software, it is provided AS-IS. + * + ****************************************************************************** + */ +/* USER CODE END Header */ +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef __TIM_H__ +#define __TIM_H__ + +#ifdef __cplusplus +extern "C" { +#endif + +/* Includes ------------------------------------------------------------------*/ +#include "main.h" + +/* USER CODE BEGIN Includes */ + +/* USER CODE END Includes */ + +/* USER CODE BEGIN Private defines */ + +/* USER CODE END Private defines */ + +void MX_TIM2_Init(void); + +/* USER CODE BEGIN Prototypes */ + +/* USER CODE END Prototypes */ + +#ifdef __cplusplus +} +#endif + +#endif /* __TIM_H__ */ diff --git a/H523xx_CAN_TESTING/Core/Inc/usart.h b/H523xx_CAN_TESTING/Core/Inc/usart.h new file mode 100644 index 000000000..daefd73e6 --- /dev/null +++ b/H523xx_CAN_TESTING/Core/Inc/usart.h @@ -0,0 +1,50 @@ +/* USER CODE BEGIN Header */ +/** + ****************************************************************************** + * @file usart.h + * @brief This file contains all the function prototypes for + * the usart.c file + ****************************************************************************** + * @attention + * + * Copyright (c) 2025 STMicroelectronics. + * All rights reserved. + * + * This software is licensed under terms that can be found in the LICENSE file + * in the root directory of this software component. + * If no LICENSE file comes with this software, it is provided AS-IS. + * + ****************************************************************************** + */ +/* USER CODE END Header */ +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef __USART_H__ +#define __USART_H__ + +#ifdef __cplusplus +extern "C" { +#endif + +/* Includes ------------------------------------------------------------------*/ +#include "main.h" + +/* USER CODE BEGIN Includes */ + +/* USER CODE END Includes */ + +/* USER CODE BEGIN Private defines */ + +/* USER CODE END Private defines */ + +void MX_LPUART1_UART_Init(void); +void MX_USART1_UART_Init(void); + +/* USER CODE BEGIN Prototypes */ + +/* USER CODE END Prototypes */ + +#ifdef __cplusplus +} +#endif + +#endif /* __USART_H__ */ diff --git a/H523xx_CAN_TESTING/Core/Src/FancyCAN_LoopbackTest.c b/H523xx_CAN_TESTING/Core/Src/FancyCAN_LoopbackTest.c new file mode 100644 index 000000000..347ffa071 --- /dev/null +++ b/H523xx_CAN_TESTING/Core/Src/FancyCAN_LoopbackTest.c @@ -0,0 +1,374 @@ +#include +#include +#include + +#include "GRCAN_FancyLayer.h" +#include "Logomatic.h" +#include "stdlib.h" + +static volatile uint32_t rx_received = 0; +static volatile bool data_valid = false; +static uint8_t expected_data[TX_BUFFER_2_SIZE]; +static volatile uint32_t expected_size = 0; +static volatile uint32_t expected_id = 0; +static volatile bool id_valid = false; + +static void can_test_rx_callback(uint32_t id, void *data, uint32_t size) +{ + rx_received++; + if (size > sizeof(expected_data)) { + data_valid = false; + return; + } + data_valid = (size == expected_size) && (memcmp(data, expected_data, size) == 0); + id_valid = (id == expected_id); + + LOGOMATIC("\nCallback triggered: ID=%" PRIu32 ", Size=%lu, Data[0]=0x%x\n", id, (unsigned long)size, *(uint8_t *)data); +} + +// TODO - allow user to send data without needing to construct a header for the buffer +// TODO: G4 tests are dependent on the System clock configuration?? + +int GRCAN_Validate_InitBus(GRCAN_BUS_ID bus, GRCAN_OperatingMode mode, FDCAN_GlobalTypeDef *fdcan_instance) +{ + GRCAN_BusConfig bus_config; + GRCAN_SetDefaultBusConfig(&bus_config, bus); + bus_config.operating_mode = mode; // GRCAN_OPMODE_INTERNAL_LOOPBACK is only one tested so far + bus_config.fdcan_instance = fdcan_instance; + bus_config.rx_callback = can_test_rx_callback; // test loopback + + LOGOMATIC("Testing GRCAN_InitBus...\n"); + bool result = GRCAN_InitBus(&bus_config); + + if (result == true) { + LOGOMATIC("GRCAN_InitBus PASSED.\n"); + return 1; + } else { + LOGOMATIC("GRCAN_InitBus FAILED.\n"); + return 0; + } +} + +GRCAN_NODE_ID get_nodeID(GRCAN_BUS_ID bus) +{ + switch ((int)bus) { + case GRCAN_BUS_PRIMARY: + return GRCAN_ACU; + case GRCAN_BUS_DATA: + return GRCAN_ECU; + case GRCAN_BUS_TESTING: + return GRCAN_Debugger; + case GRCAN_BUS_CHARGER: + return GRCAN_CCU; + case GRCAN_BUS_DATA_SUBNET: + return GRCAN_ECU; + default: + return GRCAN_ALL; // All causes error + } +} + +GRCAN_MSG_ID get_messageID(GRCAN_BUS_ID bus) +{ + switch ((int)bus) { + case GRCAN_BUS_PRIMARY: + return GRCAN_ACU_STATUS_1; + case GRCAN_BUS_DATA: + return GRCAN_ECU_STATUS_1; + case GRCAN_BUS_TESTING: + return GRCAN_DEBUG_2_0; + case GRCAN_BUS_CHARGER: + return GRCAN_ACU_CONFIG_CHG_PARAMS; + case GRCAN_BUS_DATA_SUBNET: + return GRCAN_ECU_STATUS_1; + default: + return (GRCAN_MSG_ID)0xFF; // Invalid message ID + } +} + +int GRCAN_SendReceive(GRCAN_BUS_ID bus, GRCAN_NODE_ID nodeID, GRCAN_NODE_ID dest_nodeID, GRCAN_MSG_ID messageID, void *data, uint32_t size) +{ + if (data == NULL) { + data = "Hello"; + size = sizeof("Hello"); + } + + if (size > sizeof(expected_data)) { + LOGOMATIC("Data size exceeds expected_data buffer size. Test cannot proceed.\n"); + return 0; + } + + // typedef struct { + // GRCAN_NODE_ID srcID; + // GRCAN_NODE_ID destNode; + // GRCAN_MSG_ID messageID; + // } GRCAN_Fancy_ID; + + expected_size = size; + GRCAN_Fancy_ID GRCAN_Fancy_ID; + GRCAN_Fancy_ID.srcID = nodeID; + GRCAN_Fancy_ID.destNode = dest_nodeID; + GRCAN_Fancy_ID.messageID = messageID; + expected_id = GRCAN_Fancy_EncodeID(&GRCAN_Fancy_ID); + + rx_received = 0; + data_valid = false; + id_valid = false; + + GRCAN_SetLocalNodeID(nodeID); + + memcpy(expected_data, data, size); + bool send_result = GRCAN_Fancy_Send(bus, dest_nodeID, messageID, data, size); + + if (!send_result) { + LOGOMATIC("GRCAN_Fancy_Send failed to send message on bus %d\n", bus); + return 0; + } + + HAL_Delay(1); + + if (rx_received > 0 && data_valid && id_valid) { + LOGOMATIC("GRCAN_Fancy_Send PASSED. Callback verified and data is valid.\n"); + return 1; + } else { + LOGOMATIC("GRCAN_Fancy_Send FAILED. Callback not triggered or data is invalid.\n"); + return 0; + } +} + +int GRCAN_ErrorHandling() +{ + GRCAN_BusConfig invalid_config = {0}; + + LOGOMATIC("\nTesting GRCAN_InitBus with invalid config...\n"); + bool result = GRCAN_InitBus(&invalid_config); + if (result == false) { + LOGOMATIC("GRCAN_InitBus error handling PASSED.\n"); + return 1; + } else { + LOGOMATIC("GRCAN_InitBus error handling FAILED.\n"); + return 0; + } +} + +void get_test_payload(int idx, void **data, uint32_t *size) +{ + static uint8_t msg1[] = "Hello"; + static uint8_t msg2[] = "World"; + static uint8_t msg3[] = {12}; + static uint8_t msg4[] = {23}; + static uint8_t msg5[] = {0x00, 0x00, 0x00, 0x00}; + static uint8_t msg6[] = {0xFF, 0xFF, 0xFF, 0xFF}; + static uint8_t msg7[] = {0xAA, 0x55, 0xAA, 0x55}; + static uint8_t msg8[] = {0, 1, 2, 3, 4, 5, 6, 7}; + + switch (idx) { + case 0: + *data = msg1; + *size = sizeof(msg1); + break; + case 1: + *data = msg2; + *size = sizeof(msg2); + break; + case 2: + *data = msg3; + *size = sizeof(msg3); + break; + case 3: + *data = msg4; + *size = sizeof(msg4); + break; + case 4: + *data = msg5; + *size = sizeof(msg5); + break; + case 5: + *data = msg6; + *size = sizeof(msg6); + break; + case 6: + *data = msg7; + *size = sizeof(msg7); + break; + case 7: + *data = msg8; + *size = sizeof(msg8); + break; + default: + *data = NULL; + *size = 0; + break; + } +} + +int GRCAN_BurstSendTest(GRCAN_BUS_ID bus, GRCAN_NODE_ID nodeID, GRCAN_NODE_ID dest_nodeID, GRCAN_MSG_ID messageID, uint32_t count) +{ + uint8_t burst_msg[] = {0x10, 0x20, 0x30, 0x40}; + + LOGOMATIC("Starting burst send test on bus %d with %lu messages...\n", bus, (unsigned long)count); + + for (uint32_t i = 0; i < count; i++) { + if (!GRCAN_SendReceive(bus, nodeID, dest_nodeID, messageID, burst_msg, sizeof(burst_msg))) { + LOGOMATIC("Burst send test FAILED on iteration %lu.\n", (unsigned long)i); + return 0; + } + } + + LOGOMATIC("Burst send test PASSED on bus %d.\n", bus); + return 1; +} + +int GRCAN_InitDeactivateStressTest(GRCAN_BUS_ID bus, GRCAN_NODE_ID nodeID, GRCAN_NODE_ID dest_nodeID, GRCAN_MSG_ID messageID, FDCAN_GlobalTypeDef *fdcan_instance, uint32_t iterations) +{ + uint8_t stress_msg[] = "Stress"; + + LOGOMATIC("Starting init/deactivate stress test on bus %d for %lu iterations...\n", bus, (unsigned long)iterations); + + for (uint32_t i = 0; i < iterations; i++) { + if (!GRCAN_Validate_InitBus(bus, GRCAN_OPMODE_INTERNAL_LOOPBACK, fdcan_instance)) { + LOGOMATIC("Stress test FAILED during init on iteration %lu.\n", (unsigned long)i); + return 0; + } + + if (!GRCAN_SendReceive(bus, nodeID, dest_nodeID, messageID, stress_msg, sizeof(stress_msg))) { + LOGOMATIC("Stress test FAILED during send/receive on iteration %lu.\n", (unsigned long)i); + GRCAN_DeactivateBus(bus); + return 0; + } + + if (!GRCAN_DeactivateBus(bus)) { + LOGOMATIC("Stress test FAILED during deactivate on iteration %lu.\n", (unsigned long)i); + return 0; + } + } + + LOGOMATIC("Init/deactivate stress test PASSED on bus %d.\n", bus); + return 1; +} + +int FancyCAN_LoopbackTest(void) +{ + GRCAN_BUS_ID bus; + + for (bus = GRCAN_BUS_TESTING; bus <= GRCAN_BUS_CHARGER + 1; bus++) { + LOGOMATIC("\n--- Testing bus %d ---\n", bus); + int res1 = GRCAN_Validate_InitBus(bus, GRCAN_OPMODE_INTERNAL_LOOPBACK, FDCAN2); + // GRCAN_OPMODE_EXTERNAL_LOOPBACK needs to be tested, can change FDCAN: make sure to #define USECANx + GRCAN_NODE_ID nodeID = get_nodeID(bus); + GRCAN_MSG_ID messageID = get_messageID(bus); + GRCAN_NODE_ID dest_nodeID = nodeID; // Loopback to self for internal + int res2 = 1; + for (int i = 0; i < 8; i++) { + void *data; + uint32_t size; + get_test_payload(i, &data, &size); + + LOGOMATIC("\nTesting GRCAN_SendReceive on bus %d...\n", bus); + res2 = GRCAN_SendReceive(bus, nodeID, dest_nodeID, messageID, data, size); // + if (res2 == 0) { + uint8_t data_value = *(uint8_t *)data; + switch ((int)bus) { + case GRCAN_BUS_PRIMARY: + LOGOMATIC("Testing Bus:PRIMARY Loopback Test FAILED for message with first byte: %d.\n", data_value); + break; + case GRCAN_BUS_DATA: + LOGOMATIC("Testing Bus:DATA Loopback Test FAILED for message with first byte: %d.\n", data_value); + break; + case GRCAN_BUS_CHARGER: + LOGOMATIC("Testing Bus:CHARGER Loopback Test FAILED for message with first byte: %d.\n", data_value); + break; + case GRCAN_BUS_TESTING: + LOGOMATIC("Testing Bus:TESTING Loopback Test FAILED for message with first byte: %d.\n", data_value); + break; + case GRCAN_BUS_DATA_SUBNET: + LOGOMATIC("Testing Bus:DATA_SUBNET Loopback Test FAILED for message with first byte: %d.\n", data_value); + break; + default: + LOGOMATIC("Testing Bus:UNKNOWN Loopback Test FAILED for message with first byte: %d.\n", data_value); + break; + } + break; + } + } + + bool res4 = GRCAN_DeactivateBus(bus); + + if (!res1 || !res2) { + switch ((int)bus) { + case GRCAN_BUS_PRIMARY: + LOGOMATIC("Testing Bus:PRIMARY Loopback Test FAILED during initialization or send/receive test.\n"); + break; + case GRCAN_BUS_DATA: + LOGOMATIC("Testing Bus:DATA Loopback Test FAILED during initialization or send/receive test.\n"); + break; + case GRCAN_BUS_TESTING: + LOGOMATIC("Testing Bus:TESTING Loopback Test FAILED during initialization or send/receive test.\n"); + break; + case GRCAN_BUS_CHARGER: + LOGOMATIC("Testing Bus:CHARGER Loopback Test FAILED during initialization or send/receive test.\n"); + break; + case GRCAN_BUS_DATA_SUBNET: + LOGOMATIC("Testing Bus:DATA_SUBNET Loopback Test FAILED during initialization or send/receive test.\n"); + break; + default: + LOGOMATIC("Testing Bus:UNKNOWN Loopback Test FAILED during initialization or send/receive test.\n"); + break; + } + } + if (!res4) { + switch ((int)bus) { + case GRCAN_BUS_PRIMARY: + LOGOMATIC("Testing Bus:PRIMARY Loopback Test FAILED during bus deactivation.\n"); + break; + case GRCAN_BUS_DATA: + LOGOMATIC("Testing Bus:DATA Loopback Test FAILED during bus deactivation.\n"); + break; + case GRCAN_BUS_TESTING: + LOGOMATIC("Testing Bus:TESTING Loopback Test FAILED during bus deactivation.\n"); + break; + case GRCAN_BUS_CHARGER: + LOGOMATIC("Testing Bus:CHARGER Loopback Test FAILED during bus deactivation.\n"); + break; + case GRCAN_BUS_DATA_SUBNET: + LOGOMATIC("Testing Bus:DATA_SUBNET Loopback Test FAILED during bus deactivation.\n"); + break; + default: + LOGOMATIC("Testing Bus:UNKNOWN Loopback Test FAILED during bus deactivation.\n"); + break; + } + } + } + + if (bus < 5) { + LOGOMATIC("\nLoopback Test FAILED. Not all buses were tested.\n"); + return 0; + } + + for (bus = GRCAN_BUS_TESTING; bus <= GRCAN_BUS_CHARGER + 1; bus++) { + LOGOMATIC("\n--- Testing burst send on bus %d ---\n", bus); + GRCAN_Validate_InitBus(bus, GRCAN_OPMODE_INTERNAL_LOOPBACK, FDCAN2); + int burst_result = GRCAN_BurstSendTest(bus, get_nodeID(bus), get_nodeID(bus), get_messageID(bus), 100); + if (!burst_result) { + LOGOMATIC("\nLoopback Test FAILED during burst send test on bus %d.\n", bus); + return 0; + } + GRCAN_DeactivateBus(bus); + } + + for (bus = GRCAN_BUS_TESTING; bus <= GRCAN_BUS_CHARGER + 1; bus++) { + LOGOMATIC("\n--- Testing init/deactivate stress test on bus %d ---\n", bus); + int stress_result = GRCAN_InitDeactivateStressTest(bus, get_nodeID(bus), get_nodeID(bus), get_messageID(bus), FDCAN2, 50); + if (!stress_result) { + LOGOMATIC("\nLoopback Test FAILED during init/deactivate stress test on bus %d.\n", bus); + return 0; + } + } + + int res3 = GRCAN_ErrorHandling(); + if (!res3) { + LOGOMATIC("\nLoopback Test FAILED during error handling test.\n"); + return 0; + } + + return 1; +} diff --git a/H523xx_CAN_TESTING/Core/Src/adc.c b/H523xx_CAN_TESTING/Core/Src/adc.c new file mode 100644 index 000000000..f3dbff8ed --- /dev/null +++ b/H523xx_CAN_TESTING/Core/Src/adc.c @@ -0,0 +1,186 @@ +/* USER CODE BEGIN Header */ +/** + ****************************************************************************** + * @file adc.c + * @brief This file provides code for the configuration + * of the ADC instances. + ****************************************************************************** + * @attention + * + * Copyright (c) 2024 STMicroelectronics. + * All rights reserved. + * + * This software is licensed under terms that can be found in the LICENSE file + * in the root directory of this software component. + * If no LICENSE file comes with this software, it is provided AS-IS. + * + ****************************************************************************** + */ +/* USER CODE END Header */ +/* Includes ------------------------------------------------------------------*/ +#include "adc.h" + +/* USER CODE BEGIN 0 */ + +/* USER CODE END 0 */ + +/* ADC1 init function */ +void MX_ADC1_Init(void) +{ + + /* USER CODE BEGIN ADC1_Init 0 */ + + /* USER CODE END ADC1_Init 0 */ + + LL_ADC_InitTypeDef ADC_InitStruct = {0}; + LL_ADC_REG_InitTypeDef ADC_REG_InitStruct = {0}; + LL_ADC_CommonInitTypeDef ADC_CommonInitStruct = {0}; + + LL_GPIO_InitTypeDef GPIO_InitStruct = {0}; + + LL_RCC_SetADCClockSource(LL_RCC_ADC12_CLKSOURCE_SYSCLK); + + /* Peripheral clock enable */ + LL_AHB2_GRP1_EnableClock(LL_AHB2_GRP1_PERIPH_ADC12); + + LL_AHB2_GRP1_EnableClock(LL_AHB2_GRP1_PERIPH_GPIOC); + LL_AHB2_GRP1_EnableClock(LL_AHB2_GRP1_PERIPH_GPIOB); + /**ADC1 GPIO Configuration + PC1 ------> ADC1_IN7 + PC2 ------> ADC1_IN8 + PC3 ------> ADC1_IN9 + PB0 ------> ADC1_IN15 + PB1 ------> ADC1_IN12 + PB14 ------> ADC1_IN5 + */ + GPIO_InitStruct.Pin = BSPD_SIGNAL_Pin; + GPIO_InitStruct.Mode = LL_GPIO_MODE_ANALOG; + GPIO_InitStruct.Pull = LL_GPIO_PULL_NO; + LL_GPIO_Init(BSPD_SIGNAL_GPIO_Port, &GPIO_InitStruct); + + GPIO_InitStruct.Pin = APPS1_SIGNAL_Pin; + GPIO_InitStruct.Mode = LL_GPIO_MODE_ANALOG; + GPIO_InitStruct.Pull = LL_GPIO_PULL_NO; + LL_GPIO_Init(APPS1_SIGNAL_GPIO_Port, &GPIO_InitStruct); + + GPIO_InitStruct.Pin = APPS2_SIGNAL_Pin; + GPIO_InitStruct.Mode = LL_GPIO_MODE_ANALOG; + GPIO_InitStruct.Pull = LL_GPIO_PULL_NO; + LL_GPIO_Init(APPS2_SIGNAL_GPIO_Port, &GPIO_InitStruct); + + GPIO_InitStruct.Pin = BRAKE_F_SIGNAL_Pin; + GPIO_InitStruct.Mode = LL_GPIO_MODE_ANALOG; + GPIO_InitStruct.Pull = LL_GPIO_PULL_NO; + LL_GPIO_Init(BRAKE_F_SIGNAL_GPIO_Port, &GPIO_InitStruct); + + GPIO_InitStruct.Pin = BRAKE_R_SIGNAL_Pin; + GPIO_InitStruct.Mode = LL_GPIO_MODE_ANALOG; + GPIO_InitStruct.Pull = LL_GPIO_PULL_NO; + LL_GPIO_Init(BRAKE_R_SIGNAL_GPIO_Port, &GPIO_InitStruct); + + GPIO_InitStruct.Pin = AUX_SIGNAL_Pin; + GPIO_InitStruct.Mode = LL_GPIO_MODE_ANALOG; + GPIO_InitStruct.Pull = LL_GPIO_PULL_NO; + LL_GPIO_Init(AUX_SIGNAL_GPIO_Port, &GPIO_InitStruct); + + /* ADC1 DMA Init */ + + /* ADC1 Init */ + LL_DMA_SetPeriphRequest(DMA1, LL_DMA_CHANNEL_1, LL_DMAMUX_REQ_ADC1); + + LL_DMA_SetDataTransferDirection(DMA1, LL_DMA_CHANNEL_1, LL_DMA_DIRECTION_PERIPH_TO_MEMORY); + + LL_DMA_SetChannelPriorityLevel(DMA1, LL_DMA_CHANNEL_1, LL_DMA_PRIORITY_LOW); + + LL_DMA_SetMode(DMA1, LL_DMA_CHANNEL_1, LL_DMA_MODE_CIRCULAR); + + LL_DMA_SetPeriphIncMode(DMA1, LL_DMA_CHANNEL_1, LL_DMA_PERIPH_NOINCREMENT); + + LL_DMA_SetMemoryIncMode(DMA1, LL_DMA_CHANNEL_1, LL_DMA_MEMORY_INCREMENT); + + LL_DMA_SetPeriphSize(DMA1, LL_DMA_CHANNEL_1, LL_DMA_PDATAALIGN_HALFWORD); + + LL_DMA_SetMemorySize(DMA1, LL_DMA_CHANNEL_1, LL_DMA_MDATAALIGN_HALFWORD); + + /* USER CODE BEGIN ADC1_Init 1 */ + + /* USER CODE END ADC1_Init 1 */ + + /** Common config + */ + ADC_InitStruct.Resolution = LL_ADC_RESOLUTION_12B; + ADC_InitStruct.DataAlignment = LL_ADC_DATA_ALIGN_RIGHT; + ADC_InitStruct.LowPowerMode = LL_ADC_LP_MODE_NONE; + LL_ADC_Init(ADC1, &ADC_InitStruct); + ADC_REG_InitStruct.TriggerSource = LL_ADC_REG_TRIG_SOFTWARE; + ADC_REG_InitStruct.SequencerLength = LL_ADC_REG_SEQ_SCAN_ENABLE_6RANKS; + ADC_REG_InitStruct.SequencerDiscont = LL_ADC_REG_SEQ_DISCONT_DISABLE; + ADC_REG_InitStruct.ContinuousMode = LL_ADC_REG_CONV_CONTINUOUS; + ADC_REG_InitStruct.DMATransfer = LL_ADC_REG_DMA_TRANSFER_UNLIMITED; + ADC_REG_InitStruct.Overrun = LL_ADC_REG_OVR_DATA_PRESERVED; + LL_ADC_REG_Init(ADC1, &ADC_REG_InitStruct); + LL_ADC_SetGainCompensation(ADC1, 0); + LL_ADC_SetOverSamplingScope(ADC1, LL_ADC_OVS_DISABLE); + ADC_CommonInitStruct.CommonClock = LL_ADC_CLOCK_ASYNC_DIV256; + ADC_CommonInitStruct.Multimode = LL_ADC_MULTI_INDEPENDENT; + LL_ADC_CommonInit(__LL_ADC_COMMON_INSTANCE(ADC1), &ADC_CommonInitStruct); + + /* Disable ADC deep power down (enabled by default after reset state) */ + LL_ADC_DisableDeepPowerDown(ADC1); + /* Enable ADC internal voltage regulator */ + LL_ADC_EnableInternalRegulator(ADC1); + /* Delay for ADC internal voltage regulator stabilization. */ + /* Compute number of CPU cycles to wait for, from delay in us. */ + /* Note: Variable divided by 2 to compensate partially */ + /* CPU processing cycles (depends on compilation optimization). */ + /* Note: If system core clock frequency is below 200kHz, wait time */ + /* is only a few CPU processing cycles. */ + uint32_t wait_loop_index; + wait_loop_index = ((LL_ADC_DELAY_INTERNAL_REGUL_STAB_US * (SystemCoreClock / (100000 * 2))) / 10); + while (wait_loop_index != 0) { + wait_loop_index--; + } + + /** Configure Regular Channel + */ + LL_ADC_REG_SetSequencerRanks(ADC1, LL_ADC_REG_RANK_1, LL_ADC_CHANNEL_5); + LL_ADC_SetChannelSamplingTime(ADC1, LL_ADC_CHANNEL_5, LL_ADC_SAMPLINGTIME_92CYCLES_5); + LL_ADC_SetChannelSingleDiff(ADC1, LL_ADC_CHANNEL_5, LL_ADC_SINGLE_ENDED); + + /** Configure Regular Channel + */ + LL_ADC_REG_SetSequencerRanks(ADC1, LL_ADC_REG_RANK_2, LL_ADC_CHANNEL_7); + LL_ADC_SetChannelSamplingTime(ADC1, LL_ADC_CHANNEL_7, LL_ADC_SAMPLINGTIME_92CYCLES_5); + LL_ADC_SetChannelSingleDiff(ADC1, LL_ADC_CHANNEL_7, LL_ADC_SINGLE_ENDED); + + /** Configure Regular Channel + */ + LL_ADC_REG_SetSequencerRanks(ADC1, LL_ADC_REG_RANK_3, LL_ADC_CHANNEL_8); + LL_ADC_SetChannelSamplingTime(ADC1, LL_ADC_CHANNEL_8, LL_ADC_SAMPLINGTIME_92CYCLES_5); + LL_ADC_SetChannelSingleDiff(ADC1, LL_ADC_CHANNEL_8, LL_ADC_SINGLE_ENDED); + + /** Configure Regular Channel + */ + LL_ADC_REG_SetSequencerRanks(ADC1, LL_ADC_REG_RANK_4, LL_ADC_CHANNEL_9); + LL_ADC_SetChannelSamplingTime(ADC1, LL_ADC_CHANNEL_9, LL_ADC_SAMPLINGTIME_92CYCLES_5); + LL_ADC_SetChannelSingleDiff(ADC1, LL_ADC_CHANNEL_9, LL_ADC_SINGLE_ENDED); + + /** Configure Regular Channel + */ + LL_ADC_REG_SetSequencerRanks(ADC1, LL_ADC_REG_RANK_5, LL_ADC_CHANNEL_12); + LL_ADC_SetChannelSamplingTime(ADC1, LL_ADC_CHANNEL_12, LL_ADC_SAMPLINGTIME_92CYCLES_5); + LL_ADC_SetChannelSingleDiff(ADC1, LL_ADC_CHANNEL_12, LL_ADC_SINGLE_ENDED); + + /** Configure Regular Channel + */ + LL_ADC_REG_SetSequencerRanks(ADC1, LL_ADC_REG_RANK_6, LL_ADC_CHANNEL_15); + LL_ADC_SetChannelSamplingTime(ADC1, LL_ADC_CHANNEL_15, LL_ADC_SAMPLINGTIME_92CYCLES_5); + LL_ADC_SetChannelSingleDiff(ADC1, LL_ADC_CHANNEL_15, LL_ADC_SINGLE_ENDED); + /* USER CODE BEGIN ADC1_Init 2 */ + + /* USER CODE END ADC1_Init 2 */ +} + +/* USER CODE BEGIN 1 */ + +/* USER CODE END 1 */ diff --git a/H523xx_CAN_TESTING/Core/Src/crc.c b/H523xx_CAN_TESTING/Core/Src/crc.c new file mode 100644 index 000000000..213510a5d --- /dev/null +++ b/H523xx_CAN_TESTING/Core/Src/crc.c @@ -0,0 +1,86 @@ +/* USER CODE BEGIN Header */ +/** + ****************************************************************************** + * @file crc.c + * @brief This file provides code for the configuration + * of the CRC instances. + ****************************************************************************** + * @attention + * + * Copyright (c) 2024 STMicroelectronics. + * All rights reserved. + * + * This software is licensed under terms that can be found in the LICENSE file + * in the root directory of this software component. + * If no LICENSE file comes with this software, it is provided AS-IS. + * + ****************************************************************************** + */ +/* USER CODE END Header */ +/* Includes ------------------------------------------------------------------*/ +#include "crc.h" + +/* USER CODE BEGIN 0 */ + +/* USER CODE END 0 */ + +CRC_HandleTypeDef hcrc; + +/* CRC init function */ +void MX_CRC_Init(void) +{ + + /* USER CODE BEGIN CRC_Init 0 */ + + /* USER CODE END CRC_Init 0 */ + + /* USER CODE BEGIN CRC_Init 1 */ + + /* USER CODE END CRC_Init 1 */ + hcrc.Instance = CRC; + hcrc.Init.DefaultPolynomialUse = DEFAULT_POLYNOMIAL_ENABLE; + hcrc.Init.DefaultInitValueUse = DEFAULT_INIT_VALUE_ENABLE; + hcrc.Init.InputDataInversionMode = CRC_INPUTDATA_INVERSION_NONE; + hcrc.Init.OutputDataInversionMode = CRC_OUTPUTDATA_INVERSION_DISABLE; + hcrc.InputDataFormat = CRC_INPUTDATA_FORMAT_BYTES; + if (HAL_CRC_Init(&hcrc) != HAL_OK) { + Error_Handler(); + } + /* USER CODE BEGIN CRC_Init 2 */ + + /* USER CODE END CRC_Init 2 */ +} + +void HAL_CRC_MspInit(CRC_HandleTypeDef *crcHandle) +{ + + if (crcHandle->Instance == CRC) { + /* USER CODE BEGIN CRC_MspInit 0 */ + + /* USER CODE END CRC_MspInit 0 */ + /* CRC clock enable */ + __HAL_RCC_CRC_CLK_ENABLE(); + /* USER CODE BEGIN CRC_MspInit 1 */ + + /* USER CODE END CRC_MspInit 1 */ + } +} + +void HAL_CRC_MspDeInit(CRC_HandleTypeDef *crcHandle) +{ + + if (crcHandle->Instance == CRC) { + /* USER CODE BEGIN CRC_MspDeInit 0 */ + + /* USER CODE END CRC_MspDeInit 0 */ + /* Peripheral clock disable */ + __HAL_RCC_CRC_CLK_DISABLE(); + /* USER CODE BEGIN CRC_MspDeInit 1 */ + + /* USER CODE END CRC_MspDeInit 1 */ + } +} + +/* USER CODE BEGIN 1 */ + +/* USER CODE END 1 */ diff --git a/H523xx_CAN_TESTING/Core/Src/dma.c b/H523xx_CAN_TESTING/Core/Src/dma.c new file mode 100644 index 000000000..491e3889d --- /dev/null +++ b/H523xx_CAN_TESTING/Core/Src/dma.c @@ -0,0 +1,50 @@ +/* USER CODE BEGIN Header */ +/** + ****************************************************************************** + * @file dma.c + * @brief This file provides code for the configuration + * of all the requested memory to memory DMA transfers. + ****************************************************************************** + * @attention + * + * Copyright (c) 2025 STMicroelectronics. + * All rights reserved. + * + * This software is licensed under terms that can be found in the LICENSE file + * in the root directory of this software component. + * If no LICENSE file comes with this software, it is provided AS-IS. + * + ****************************************************************************** + */ +/* USER CODE END Header */ + +/* Includes ------------------------------------------------------------------*/ +#include "dma.h" + +/* USER CODE BEGIN 0 */ + +/* USER CODE END 0 */ + +/*----------------------------------------------------------------------------*/ +/* Configure DMA */ +/*----------------------------------------------------------------------------*/ + +/* USER CODE BEGIN 1 */ + +/* USER CODE END 1 */ + +/** + * Enable DMA controller clock + */ +void MX_DMA_Init(void) +{ + + /* Init with LL driver */ + /* DMA controller clock enable */ + LL_AHB1_GRP1_EnableClock(LL_AHB1_GRP1_PERIPH_DMAMUX1); + LL_AHB1_GRP1_EnableClock(LL_AHB1_GRP1_PERIPH_DMA1); +} + +/* USER CODE BEGIN 2 */ + +/* USER CODE END 2 */ diff --git a/H523xx_CAN_TESTING/Core/Src/fdcan.c b/H523xx_CAN_TESTING/Core/Src/fdcan.c new file mode 100644 index 000000000..ebc13ea73 --- /dev/null +++ b/H523xx_CAN_TESTING/Core/Src/fdcan.c @@ -0,0 +1,135 @@ +// #include "unused.h" +// /* USER CODE BEGIN Header */ +// /** +// ****************************************************************************** +// * @file fdcan.c +// * @brief This file provides code for the configuration +// * of the FDCAN instances. +// ****************************************************************************** +// * @attention +// * +// * Copyright (c) 2024 STMicroelectronics. +// * All rights reserved. +// * +// * This software is licensed under terms that can be found in the LICENSE file +// * in the root directory of this software component. +// * If no LICENSE file comes with this software, it is provided AS-IS. +// * +// ****************************************************************************** +// */ +// /* USER CODE END Header */ +// /* Includes ------------------------------------------------------------------*/ +// #include "fdcan.h" + +// /* USER CODE BEGIN 0 */ + +// /* USER CODE END 0 */ + +// FDCAN_HandleTypeDef hfdcan2; + +// /* FDCAN2 init function */ +// void MX_FDCAN2_Init(void) +// { + +// /* USER CODE BEGIN FDCAN2_Init 0 */ + +// /* USER CODE END FDCAN2_Init 0 */ + +// /* USER CODE BEGIN FDCAN2_Init 1 */ + +// /* USER CODE END FDCAN2_Init 1 */ +// hfdcan2.Instance = FDCAN2; +// hfdcan2.Init.ClockDivider = FDCAN_CLOCK_DIV1; +// hfdcan2.Init.FrameFormat = FDCAN_FRAME_CLASSIC; +// hfdcan2.Init.Mode = FDCAN_MODE_NORMAL; +// hfdcan2.Init.AutoRetransmission = ENABLE; +// hfdcan2.Init.TransmitPause = DISABLE; +// hfdcan2.Init.ProtocolException = ENABLE; +// hfdcan2.Init.NominalPrescaler = 1; +// hfdcan2.Init.NominalSyncJumpWidth = 16; +// hfdcan2.Init.NominalTimeSeg1 = 119; +// hfdcan2.Init.NominalTimeSeg2 = 40; +// hfdcan2.Init.DataPrescaler = 8; +// hfdcan2.Init.DataSyncJumpWidth = 16; +// hfdcan2.Init.DataTimeSeg1 = 14; +// hfdcan2.Init.DataTimeSeg2 = 5; +// hfdcan2.Init.StdFiltersNbr = 0; +// hfdcan2.Init.ExtFiltersNbr = 2; +// hfdcan2.Init.TxFifoQueueMode = FDCAN_TX_FIFO_OPERATION; +// if (HAL_FDCAN_Init(&hfdcan2) != HAL_OK) { +// Error_Handler(); +// } +// /* USER CODE BEGIN FDCAN2_Init 2 */ + +// /* USER CODE END FDCAN2_Init 2 */ +// } + +// void HAL_FDCAN_MspInit(FDCAN_HandleTypeDef *fdcanHandle) +// { + +// GPIO_InitTypeDef GPIO_InitStruct = {0}; +// if (fdcanHandle->Instance == FDCAN2) { +// /* USER CODE BEGIN FDCAN2_MspInit 0 */ + +// /* USER CODE END FDCAN2_MspInit 0 */ +// LL_RCC_SetFDCANClockSource(LL_RCC_FDCAN_CLKSOURCE_PCLK1); + +// /* FDCAN2 clock enable */ +// __HAL_RCC_FDCAN_CLK_ENABLE(); + +// __HAL_RCC_GPIOB_CLK_ENABLE(); +// /**FDCAN2 GPIO Configuration +// PB12 ------> FDCAN2_RX +// PB13 ------> FDCAN2_TX +// */ +// GPIO_InitStruct.Pin = GPIO_PIN_12; +// GPIO_InitStruct.Mode = GPIO_MODE_AF_PP; +// GPIO_InitStruct.Pull = GPIO_PULLUP; +// GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH; +// GPIO_InitStruct.Alternate = GPIO_AF9_FDCAN2; +// HAL_GPIO_Init(GPIOB, &GPIO_InitStruct); + +// GPIO_InitStruct.Pin = GPIO_PIN_13; +// GPIO_InitStruct.Mode = GPIO_MODE_AF_PP; +// GPIO_InitStruct.Pull = GPIO_NOPULL; +// GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH; +// GPIO_InitStruct.Alternate = GPIO_AF9_FDCAN2; +// HAL_GPIO_Init(GPIOB, &GPIO_InitStruct); + +// /* FDCAN2 interrupt Init */ +// HAL_NVIC_SetPriority(FDCAN2_IT0_IRQn, 0, 0); +// HAL_NVIC_EnableIRQ(FDCAN2_IT0_IRQn); +// /* USER CODE BEGIN FDCAN2_MspInit 1 */ + +// /* USER CODE END FDCAN2_MspInit 1 */ +// } +// } + +// /*void HAL_FDCAN_MspDeInit(FDCAN_HandleTypeDef *fdcanHandle) +// { + +// if (fdcanHandle->Instance == FDCAN2) { +// /* USER CODE BEGIN FDCAN2_MspDeInit 0 */ + +// /* USER CODE END FDCAN2_MspDeInit 0 */ +// /* Peripheral clock disable */ +// __HAL_RCC_FDCAN_CLK_DISABLE(); + +// /**FDCAN2 GPIO Configuration +// PB12 ------> FDCAN2_RX +// PB13 ------> FDCAN2_TX +// */ +// HAL_GPIO_DeInit(GPIOB, GPIO_PIN_12 | GPIO_PIN_13); + +// /* FDCAN2 interrupt Deinit */ +// HAL_NVIC_DisableIRQ(FDCAN2_IT0_IRQn); +// /* USER CODE BEGIN FDCAN2_MspDeInit 1 */ + +// /* USER CODE END FDCAN2_MspDeInit 1 */ +// } +// } + +// /* USER CODE BEGIN 1 */ + +/* USER CODE END 1 */ +// UNUSED(5); diff --git a/H523xx_CAN_TESTING/Core/Src/gpio.c b/H523xx_CAN_TESTING/Core/Src/gpio.c new file mode 100644 index 000000000..d36e6eca6 --- /dev/null +++ b/H523xx_CAN_TESTING/Core/Src/gpio.c @@ -0,0 +1,260 @@ +/* USER CODE BEGIN Header */ +/** + ****************************************************************************** + * @file gpio.c + * @brief This file provides code for the configuration + * of all used GPIO pins. + ****************************************************************************** + * @attention + * + * Copyright (c) 2024 STMicroelectronics. + * All rights reserved. + * + * This software is licensed under terms that can be found in the LICENSE file + * in the root directory of this software component. + * If no LICENSE file comes with this software, it is provided AS-IS. + * + ****************************************************************************** + */ +/* USER CODE END Header */ + +/* Includes ------------------------------------------------------------------*/ +#include "gpio.h" + +/* USER CODE BEGIN 0 */ + +/* USER CODE END 0 */ + +/*----------------------------------------------------------------------------*/ +/* Configure GPIO */ +/*----------------------------------------------------------------------------*/ +/* USER CODE BEGIN 1 */ + +/* USER CODE END 1 */ + +/** Configure pins as + * Analog + * Input + * Output + * EVENT_OUT + * EXTI + * Free pins are configured automatically as Analog (this feature is + enabled through + * the Code Generation settings) + PA6 ------> ADC2_IN3 + PA7 ------> ADC2_IN4 + PB15 ------> ADC2_IN15 + PB7 ------> UART4_CTS +*/ +void MX_GPIO_Init(void) +{ + + LL_GPIO_InitTypeDef GPIO_InitStruct = {0}; + + /* GPIO Ports Clock Enable */ + LL_AHB2_GRP1_EnableClock(LL_AHB2_GRP1_PERIPH_GPIOC); + LL_AHB2_GRP1_EnableClock(LL_AHB2_GRP1_PERIPH_GPIOF); + LL_AHB2_GRP1_EnableClock(LL_AHB2_GRP1_PERIPH_GPIOG); + LL_AHB2_GRP1_EnableClock(LL_AHB2_GRP1_PERIPH_GPIOA); + LL_AHB2_GRP1_EnableClock(LL_AHB2_GRP1_PERIPH_GPIOB); + LL_AHB2_GRP1_EnableClock(LL_AHB2_GRP1_PERIPH_GPIOD); + + /**/ + LL_GPIO_ResetOutputPin(BLINKY_GPIO_Port, BLINKY_Pin); + + /**/ + LL_GPIO_ResetOutputPin(LED_TEST_GPIO_Port, LED_TEST_Pin); + + /**/ + LL_GPIO_ResetOutputPin(BRAKE_LIGHT_GPIO_Port, BRAKE_LIGHT_Pin); + + /**/ + LL_GPIO_ResetOutputPin(TSSI_G_CONTROL_GPIO_Port, TSSI_G_CONTROL_Pin); + + /**/ + LL_GPIO_ResetOutputPin(AUX_CONTROL_GPIO_Port, AUX_CONTROL_Pin); + + /**/ + LL_GPIO_ResetOutputPin(SOFTWARE_OK_CONTROL_GPIO_Port, SOFTWARE_OK_CONTROL_Pin); + + /**/ + GPIO_InitStruct.Pin = LL_GPIO_PIN_13; + GPIO_InitStruct.Mode = LL_GPIO_MODE_ANALOG; + GPIO_InitStruct.Pull = LL_GPIO_PULL_NO; + LL_GPIO_Init(GPIOC, &GPIO_InitStruct); + + /**/ + GPIO_InitStruct.Pin = LL_GPIO_PIN_14; + GPIO_InitStruct.Mode = LL_GPIO_MODE_ANALOG; + GPIO_InitStruct.Pull = LL_GPIO_PULL_NO; + LL_GPIO_Init(GPIOC, &GPIO_InitStruct); + + /**/ + GPIO_InitStruct.Pin = LL_GPIO_PIN_15; + GPIO_InitStruct.Mode = LL_GPIO_MODE_ANALOG; + GPIO_InitStruct.Pull = LL_GPIO_PULL_NO; + LL_GPIO_Init(GPIOC, &GPIO_InitStruct); + + /**/ + GPIO_InitStruct.Pin = LL_GPIO_PIN_10; + GPIO_InitStruct.Mode = LL_GPIO_MODE_ANALOG; + GPIO_InitStruct.Pull = LL_GPIO_PULL_NO; + LL_GPIO_Init(GPIOG, &GPIO_InitStruct); + + /**/ + GPIO_InitStruct.Pin = LL_GPIO_PIN_0; + GPIO_InitStruct.Mode = LL_GPIO_MODE_ANALOG; + GPIO_InitStruct.Pull = LL_GPIO_PULL_NO; + LL_GPIO_Init(GPIOC, &GPIO_InitStruct); + + /**/ + GPIO_InitStruct.Pin = LL_GPIO_PIN_1; + GPIO_InitStruct.Mode = LL_GPIO_MODE_ANALOG; + GPIO_InitStruct.Pull = LL_GPIO_PULL_NO; + LL_GPIO_Init(GPIOA, &GPIO_InitStruct); + + /**/ + GPIO_InitStruct.Pin = LL_GPIO_PIN_4; + GPIO_InitStruct.Mode = LL_GPIO_MODE_ANALOG; + GPIO_InitStruct.Pull = LL_GPIO_PULL_NO; + LL_GPIO_Init(GPIOA, &GPIO_InitStruct); + + /**/ + GPIO_InitStruct.Pin = BLINKY_Pin; + GPIO_InitStruct.Mode = LL_GPIO_MODE_OUTPUT; + GPIO_InitStruct.Speed = LL_GPIO_SPEED_FREQ_LOW; + GPIO_InitStruct.OutputType = LL_GPIO_OUTPUT_PUSHPULL; + GPIO_InitStruct.Pull = LL_GPIO_PULL_NO; + LL_GPIO_Init(BLINKY_GPIO_Port, &GPIO_InitStruct); + + /**/ + GPIO_InitStruct.Pin = IMD_SENSE_Pin; + GPIO_InitStruct.Mode = LL_GPIO_MODE_ANALOG; + GPIO_InitStruct.Pull = LL_GPIO_PULL_NO; + LL_GPIO_Init(IMD_SENSE_GPIO_Port, &GPIO_InitStruct); + + /**/ + GPIO_InitStruct.Pin = AMS_SENSE_Pin; + GPIO_InitStruct.Mode = LL_GPIO_MODE_ANALOG; + GPIO_InitStruct.Pull = LL_GPIO_PULL_NO; + LL_GPIO_Init(AMS_SENSE_GPIO_Port, &GPIO_InitStruct); + + /**/ + GPIO_InitStruct.Pin = LL_GPIO_PIN_2; + GPIO_InitStruct.Mode = LL_GPIO_MODE_ANALOG; + GPIO_InitStruct.Pull = LL_GPIO_PULL_NO; + LL_GPIO_Init(GPIOB, &GPIO_InitStruct); + + /**/ + GPIO_InitStruct.Pin = LL_GPIO_PIN_10; + GPIO_InitStruct.Mode = LL_GPIO_MODE_ANALOG; + GPIO_InitStruct.Pull = LL_GPIO_PULL_NO; + LL_GPIO_Init(GPIOB, &GPIO_InitStruct); + + /**/ + GPIO_InitStruct.Pin = LED_TEST_Pin; + GPIO_InitStruct.Mode = LL_GPIO_MODE_OUTPUT; + GPIO_InitStruct.Speed = LL_GPIO_SPEED_FREQ_LOW; + GPIO_InitStruct.OutputType = LL_GPIO_OUTPUT_PUSHPULL; + GPIO_InitStruct.Pull = LL_GPIO_PULL_NO; + LL_GPIO_Init(LED_TEST_GPIO_Port, &GPIO_InitStruct); + + /**/ + GPIO_InitStruct.Pin = STEERING_ANGLE_Pin; + GPIO_InitStruct.Mode = LL_GPIO_MODE_ANALOG; + GPIO_InitStruct.Pull = LL_GPIO_PULL_NO; + LL_GPIO_Init(STEERING_ANGLE_GPIO_Port, &GPIO_InitStruct); + + /**/ + GPIO_InitStruct.Pin = LL_GPIO_PIN_6; + GPIO_InitStruct.Mode = LL_GPIO_MODE_ANALOG; + GPIO_InitStruct.Pull = LL_GPIO_PULL_NO; + LL_GPIO_Init(GPIOC, &GPIO_InitStruct); + + /**/ + GPIO_InitStruct.Pin = LL_GPIO_PIN_7; + GPIO_InitStruct.Mode = LL_GPIO_MODE_ANALOG; + GPIO_InitStruct.Pull = LL_GPIO_PULL_NO; + LL_GPIO_Init(GPIOC, &GPIO_InitStruct); + + /**/ + GPIO_InitStruct.Pin = LL_GPIO_PIN_8; + GPIO_InitStruct.Mode = LL_GPIO_MODE_ANALOG; + GPIO_InitStruct.Pull = LL_GPIO_PULL_NO; + LL_GPIO_Init(GPIOC, &GPIO_InitStruct); + + /**/ + GPIO_InitStruct.Pin = LL_GPIO_PIN_9; + GPIO_InitStruct.Mode = LL_GPIO_MODE_ANALOG; + GPIO_InitStruct.Pull = LL_GPIO_PULL_NO; + LL_GPIO_Init(GPIOC, &GPIO_InitStruct); + + /**/ + GPIO_InitStruct.Pin = LL_GPIO_PIN_9; + GPIO_InitStruct.Mode = LL_GPIO_MODE_ANALOG; + GPIO_InitStruct.Pull = LL_GPIO_PULL_NO; + LL_GPIO_Init(GPIOA, &GPIO_InitStruct); + + /**/ + GPIO_InitStruct.Pin = LL_GPIO_PIN_10; + GPIO_InitStruct.Mode = LL_GPIO_MODE_ANALOG; + GPIO_InitStruct.Pull = LL_GPIO_PULL_NO; + LL_GPIO_Init(GPIOA, &GPIO_InitStruct); + + /**/ + GPIO_InitStruct.Pin = LL_GPIO_PIN_15; + GPIO_InitStruct.Mode = LL_GPIO_MODE_ANALOG; + GPIO_InitStruct.Pull = LL_GPIO_PULL_NO; + LL_GPIO_Init(GPIOA, &GPIO_InitStruct); + + /**/ + GPIO_InitStruct.Pin = LL_GPIO_PIN_2; + GPIO_InitStruct.Mode = LL_GPIO_MODE_ANALOG; + GPIO_InitStruct.Pull = LL_GPIO_PULL_NO; + LL_GPIO_Init(GPIOD, &GPIO_InitStruct); + + /**/ + GPIO_InitStruct.Pin = BRAKE_LIGHT_Pin; + GPIO_InitStruct.Mode = LL_GPIO_MODE_OUTPUT; + GPIO_InitStruct.Speed = LL_GPIO_SPEED_FREQ_LOW; + GPIO_InitStruct.OutputType = LL_GPIO_OUTPUT_PUSHPULL; + GPIO_InitStruct.Pull = LL_GPIO_PULL_NO; + LL_GPIO_Init(BRAKE_LIGHT_GPIO_Port, &GPIO_InitStruct); + + /**/ + GPIO_InitStruct.Pin = TSSI_G_CONTROL_Pin; + GPIO_InitStruct.Mode = LL_GPIO_MODE_OUTPUT; + GPIO_InitStruct.Speed = LL_GPIO_SPEED_FREQ_LOW; + GPIO_InitStruct.OutputType = LL_GPIO_OUTPUT_PUSHPULL; + GPIO_InitStruct.Pull = LL_GPIO_PULL_NO; + LL_GPIO_Init(TSSI_G_CONTROL_GPIO_Port, &GPIO_InitStruct); + + /**/ + GPIO_InitStruct.Pin = LL_GPIO_PIN_7; + GPIO_InitStruct.Mode = LL_GPIO_MODE_ALTERNATE; + GPIO_InitStruct.Speed = LL_GPIO_SPEED_FREQ_LOW; + GPIO_InitStruct.OutputType = LL_GPIO_OUTPUT_PUSHPULL; + GPIO_InitStruct.Pull = LL_GPIO_PULL_NO; + GPIO_InitStruct.Alternate = LL_GPIO_AF_14; + LL_GPIO_Init(GPIOB, &GPIO_InitStruct); + + /**/ + GPIO_InitStruct.Pin = AUX_CONTROL_Pin; + GPIO_InitStruct.Mode = LL_GPIO_MODE_OUTPUT; + GPIO_InitStruct.Speed = LL_GPIO_SPEED_FREQ_LOW; + GPIO_InitStruct.OutputType = LL_GPIO_OUTPUT_PUSHPULL; + GPIO_InitStruct.Pull = LL_GPIO_PULL_NO; + LL_GPIO_Init(AUX_CONTROL_GPIO_Port, &GPIO_InitStruct); + + /**/ + GPIO_InitStruct.Pin = SOFTWARE_OK_CONTROL_Pin; + GPIO_InitStruct.Mode = LL_GPIO_MODE_OUTPUT; + GPIO_InitStruct.Speed = LL_GPIO_SPEED_FREQ_LOW; + GPIO_InitStruct.OutputType = LL_GPIO_OUTPUT_PUSHPULL; + GPIO_InitStruct.Pull = LL_GPIO_PULL_NO; + LL_GPIO_Init(SOFTWARE_OK_CONTROL_GPIO_Port, &GPIO_InitStruct); +} + +/* USER CODE BEGIN 2 */ + +/* USER CODE END 2 */ diff --git a/H523xx_CAN_TESTING/Core/Src/i2c.c b/H523xx_CAN_TESTING/Core/Src/i2c.c new file mode 100644 index 000000000..bfb4e0153 --- /dev/null +++ b/H523xx_CAN_TESTING/Core/Src/i2c.c @@ -0,0 +1,92 @@ +/* USER CODE BEGIN Header */ +/** + ****************************************************************************** + * @file i2c.c + * @brief This file provides code for the configuration + * of the I2C instances. + ****************************************************************************** + * @attention + * + * Copyright (c) 2025 STMicroelectronics. + * All rights reserved. + * + * This software is licensed under terms that can be found in the LICENSE file + * in the root directory of this software component. + * If no LICENSE file comes with this software, it is provided AS-IS. + * + ****************************************************************************** + */ +/* USER CODE END Header */ +/* Includes ------------------------------------------------------------------*/ +#include "i2c.h" + +/* USER CODE BEGIN 0 */ + +/* USER CODE END 0 */ + +/* I2C2 init function */ +void MX_I2C2_Init(void) +{ + + /* USER CODE BEGIN I2C2_Init 0 */ + + /* USER CODE END I2C2_Init 0 */ + + LL_I2C_InitTypeDef I2C_InitStruct = {0}; + + LL_GPIO_InitTypeDef GPIO_InitStruct = {0}; + + LL_RCC_SetI2CClockSource(LL_RCC_I2C2_CLKSOURCE_PCLK1); + + LL_AHB2_GRP1_EnableClock(LL_AHB2_GRP1_PERIPH_GPIOC); + LL_AHB2_GRP1_EnableClock(LL_AHB2_GRP1_PERIPH_GPIOA); + /**I2C2 GPIO Configuration + PC4 ------> I2C2_SCL + PA8 ------> I2C2_SDA + */ + GPIO_InitStruct.Pin = LL_GPIO_PIN_4; + GPIO_InitStruct.Mode = LL_GPIO_MODE_ALTERNATE; + GPIO_InitStruct.Speed = LL_GPIO_SPEED_FREQ_LOW; + GPIO_InitStruct.OutputType = LL_GPIO_OUTPUT_OPENDRAIN; + GPIO_InitStruct.Pull = LL_GPIO_PULL_NO; + GPIO_InitStruct.Alternate = LL_GPIO_AF_4; + LL_GPIO_Init(GPIOC, &GPIO_InitStruct); + + GPIO_InitStruct.Pin = LL_GPIO_PIN_8; + GPIO_InitStruct.Mode = LL_GPIO_MODE_ALTERNATE; + GPIO_InitStruct.Speed = LL_GPIO_SPEED_FREQ_LOW; + GPIO_InitStruct.OutputType = LL_GPIO_OUTPUT_OPENDRAIN; + GPIO_InitStruct.Pull = LL_GPIO_PULL_NO; + GPIO_InitStruct.Alternate = LL_GPIO_AF_4; + LL_GPIO_Init(GPIOA, &GPIO_InitStruct); + + /* Peripheral clock enable */ + LL_APB1_GRP1_EnableClock(LL_APB1_GRP1_PERIPH_I2C2); + + /* USER CODE BEGIN I2C2_Init 1 */ + + /* USER CODE END I2C2_Init 1 */ + + /** I2C Initialization + */ + I2C_InitStruct.PeripheralMode = LL_I2C_MODE_I2C; + I2C_InitStruct.Timing = 0x30D29DE4; + I2C_InitStruct.AnalogFilter = LL_I2C_ANALOGFILTER_ENABLE; + I2C_InitStruct.DigitalFilter = 0; + I2C_InitStruct.OwnAddress1 = 0; + I2C_InitStruct.TypeAcknowledge = LL_I2C_ACK; + I2C_InitStruct.OwnAddrSize = LL_I2C_OWNADDRESS1_7BIT; + LL_I2C_Init(I2C2, &I2C_InitStruct); + LL_I2C_EnableAutoEndMode(I2C2); + LL_I2C_SetOwnAddress2(I2C2, 0, LL_I2C_OWNADDRESS2_NOMASK); + LL_I2C_DisableOwnAddress2(I2C2); + LL_I2C_DisableGeneralCall(I2C2); + LL_I2C_EnableClockStretching(I2C2); + /* USER CODE BEGIN I2C2_Init 2 */ + + /* USER CODE END I2C2_Init 2 */ +} + +/* USER CODE BEGIN 1 */ + +/* USER CODE END 1 */ diff --git a/H523xx_CAN_TESTING/Core/Src/spi.c b/H523xx_CAN_TESTING/Core/Src/spi.c new file mode 100644 index 000000000..66459f2ec --- /dev/null +++ b/H523xx_CAN_TESTING/Core/Src/spi.c @@ -0,0 +1,95 @@ +/* USER CODE BEGIN Header */ +/** + ****************************************************************************** + * @file spi.c + * @brief This file provides code for the configuration + * of the SPI instances. + ****************************************************************************** + * @attention + * + * Copyright (c) 2024 STMicroelectronics. + * All rights reserved. + * + * This software is licensed under terms that can be found in the LICENSE file + * in the root directory of this software component. + * If no LICENSE file comes with this software, it is provided AS-IS. + * + ****************************************************************************** + */ +/* USER CODE END Header */ +/* Includes ------------------------------------------------------------------*/ +#include "spi.h" + +/* USER CODE BEGIN 0 */ + +/* USER CODE END 0 */ + +/* SPI3 init function */ +void MX_SPI3_Init(void) +{ + + /* USER CODE BEGIN SPI3_Init 0 */ + + /* USER CODE END SPI3_Init 0 */ + + LL_SPI_InitTypeDef SPI_InitStruct = {0}; + + LL_GPIO_InitTypeDef GPIO_InitStruct = {0}; + + /* Peripheral clock enable */ + LL_APB1_GRP1_EnableClock(LL_APB1_GRP1_PERIPH_SPI3); + + LL_AHB2_GRP1_EnableClock(LL_AHB2_GRP1_PERIPH_GPIOC); + /**SPI3 GPIO Configuration + PC10 ------> SPI3_SCK + PC11 ------> SPI3_MISO + PC12 ------> SPI3_MOSI + */ + GPIO_InitStruct.Pin = LL_GPIO_PIN_10; + GPIO_InitStruct.Mode = LL_GPIO_MODE_ALTERNATE; + GPIO_InitStruct.Speed = LL_GPIO_SPEED_FREQ_LOW; + GPIO_InitStruct.OutputType = LL_GPIO_OUTPUT_PUSHPULL; + GPIO_InitStruct.Pull = LL_GPIO_PULL_NO; + GPIO_InitStruct.Alternate = LL_GPIO_AF_6; + LL_GPIO_Init(GPIOC, &GPIO_InitStruct); + + GPIO_InitStruct.Pin = LL_GPIO_PIN_11; + GPIO_InitStruct.Mode = LL_GPIO_MODE_ALTERNATE; + GPIO_InitStruct.Speed = LL_GPIO_SPEED_FREQ_LOW; + GPIO_InitStruct.OutputType = LL_GPIO_OUTPUT_PUSHPULL; + GPIO_InitStruct.Pull = LL_GPIO_PULL_NO; + GPIO_InitStruct.Alternate = LL_GPIO_AF_6; + LL_GPIO_Init(GPIOC, &GPIO_InitStruct); + + GPIO_InitStruct.Pin = LL_GPIO_PIN_12; + GPIO_InitStruct.Mode = LL_GPIO_MODE_ALTERNATE; + GPIO_InitStruct.Speed = LL_GPIO_SPEED_FREQ_LOW; + GPIO_InitStruct.OutputType = LL_GPIO_OUTPUT_PUSHPULL; + GPIO_InitStruct.Pull = LL_GPIO_PULL_NO; + GPIO_InitStruct.Alternate = LL_GPIO_AF_6; + LL_GPIO_Init(GPIOC, &GPIO_InitStruct); + + /* USER CODE BEGIN SPI3_Init 1 */ + + /* USER CODE END SPI3_Init 1 */ + SPI_InitStruct.TransferDirection = LL_SPI_FULL_DUPLEX; + SPI_InitStruct.Mode = LL_SPI_MODE_MASTER; + SPI_InitStruct.DataWidth = LL_SPI_DATAWIDTH_4BIT; + SPI_InitStruct.ClockPolarity = LL_SPI_POLARITY_LOW; + SPI_InitStruct.ClockPhase = LL_SPI_PHASE_1EDGE; + SPI_InitStruct.NSS = LL_SPI_NSS_SOFT; + SPI_InitStruct.BaudRate = LL_SPI_BAUDRATEPRESCALER_DIV32; + SPI_InitStruct.BitOrder = LL_SPI_MSB_FIRST; + SPI_InitStruct.CRCCalculation = LL_SPI_CRCCALCULATION_DISABLE; + SPI_InitStruct.CRCPoly = 7; + LL_SPI_Init(SPI3, &SPI_InitStruct); + LL_SPI_SetStandard(SPI3, LL_SPI_PROTOCOL_MOTOROLA); + LL_SPI_EnableNSSPulseMgt(SPI3); + /* USER CODE BEGIN SPI3_Init 2 */ + + /* USER CODE END SPI3_Init 2 */ +} + +/* USER CODE BEGIN 1 */ + +/* USER CODE END 1 */ diff --git a/H523xx_CAN_TESTING/Core/Src/stm32h5xx_hal_msp.c b/H523xx_CAN_TESTING/Core/Src/stm32h5xx_hal_msp.c new file mode 100644 index 000000000..08ba6fe07 --- /dev/null +++ b/H523xx_CAN_TESTING/Core/Src/stm32h5xx_hal_msp.c @@ -0,0 +1,79 @@ +/* USER CODE BEGIN Header */ +/** + ****************************************************************************** + * @file stm32h5xx_hal_msp.c + * @brief This file provides code for the MSP Initialization + * and de-Initialization codes. + ****************************************************************************** + * @attention + * + * Copyright (c) 2026 STMicroelectronics. + * All rights reserved. + * + * This software is licensed under terms that can be found in the LICENSE file + * in the root directory of this software component. + * If no LICENSE file comes with this software, it is provided AS-IS. + * + ****************************************************************************** + */ +/* USER CODE END Header */ + +/* Includes ------------------------------------------------------------------*/ +#include "main.h" +/* USER CODE BEGIN Includes */ + +/* USER CODE END Includes */ + +/* Private typedef -----------------------------------------------------------*/ +/* USER CODE BEGIN TD */ + +/* USER CODE END TD */ + +/* Private define ------------------------------------------------------------*/ +/* USER CODE BEGIN Define */ + +/* USER CODE END Define */ + +/* Private macro -------------------------------------------------------------*/ +/* USER CODE BEGIN Macro */ + +/* USER CODE END Macro */ + +/* Private variables ---------------------------------------------------------*/ +/* USER CODE BEGIN PV */ + +/* USER CODE END PV */ + +/* Private function prototypes -----------------------------------------------*/ +/* USER CODE BEGIN PFP */ + +/* USER CODE END PFP */ + +/* External functions --------------------------------------------------------*/ +/* USER CODE BEGIN ExternalFunctions */ + +/* USER CODE END ExternalFunctions */ + +/* USER CODE BEGIN 0 */ + +/* USER CODE END 0 */ +/** + * Initializes the Global MSP. + */ +void HAL_MspInit(void) +{ + + /* USER CODE BEGIN MspInit 0 */ + + /* USER CODE END MspInit 0 */ + + /* System interrupt init*/ + + /* USER CODE BEGIN MspInit 1 */ + + /* USER CODE END MspInit 1 */ +} + +/* USER CODE BEGIN 1 */ + +/* USER CODE END 1 */ diff --git a/H523xx_CAN_TESTING/Core/Src/stm32h5xx_it.c b/H523xx_CAN_TESTING/Core/Src/stm32h5xx_it.c new file mode 100644 index 000000000..7ab0795f9 --- /dev/null +++ b/H523xx_CAN_TESTING/Core/Src/stm32h5xx_it.c @@ -0,0 +1,198 @@ +/* USER CODE BEGIN Header */ +/** + ****************************************************************************** + * @file stm32h5xx_it.c + * @brief Interrupt Service Routines. + ****************************************************************************** + * @attention + * + * Copyright (c) 2026 STMicroelectronics. + * All rights reserved. + * + * This software is licensed under terms that can be found in the LICENSE file + * in the root directory of this software component. + * If no LICENSE file comes with this software, it is provided AS-IS. + * + ****************************************************************************** + */ +/* USER CODE END Header */ + +/* Includes ------------------------------------------------------------------*/ +#include "stm32h5xx_it.h" + +#include "main.h" +/* Private includes ----------------------------------------------------------*/ +/* USER CODE BEGIN Includes */ +/* USER CODE END Includes */ + +/* Private typedef -----------------------------------------------------------*/ +/* USER CODE BEGIN TD */ + +/* USER CODE END TD */ + +/* Private define ------------------------------------------------------------*/ +/* USER CODE BEGIN PD */ + +/* USER CODE END PD */ + +/* Private macro -------------------------------------------------------------*/ +/* USER CODE BEGIN PM */ + +/* USER CODE END PM */ + +/* Private variables ---------------------------------------------------------*/ +/* USER CODE BEGIN PV */ + +/* USER CODE END PV */ + +/* Private function prototypes -----------------------------------------------*/ +/* USER CODE BEGIN PFP */ + +/* USER CODE END PFP */ + +/* Private user code ---------------------------------------------------------*/ +/* USER CODE BEGIN 0 */ + +/* USER CODE END 0 */ + +/* External variables --------------------------------------------------------*/ + +/* USER CODE BEGIN EV */ + +/* USER CODE END EV */ + +/******************************************************************************/ +/* Cortex Processor Interruption and Exception Handlers */ +/******************************************************************************/ +/** + * @brief This function handles Non maskable interrupt. + */ +void NMI_Handler(void) +{ + /* USER CODE BEGIN NonMaskableInt_IRQn 0 */ + + /* USER CODE END NonMaskableInt_IRQn 0 */ + /* USER CODE BEGIN NonMaskableInt_IRQn 1 */ + while (1) {} + /* USER CODE END NonMaskableInt_IRQn 1 */ +} + +/** + * @brief This function handles Hard fault interrupt. + */ +void HardFault_Handler(void) +{ + /* USER CODE BEGIN HardFault_IRQn 0 */ + + /* USER CODE END HardFault_IRQn 0 */ + while (1) { + /* USER CODE BEGIN W1_HardFault_IRQn 0 */ + /* USER CODE END W1_HardFault_IRQn 0 */ + } +} + +/** + * @brief This function handles Memory management fault. + */ +void MemManage_Handler(void) +{ + /* USER CODE BEGIN MemoryManagement_IRQn 0 */ + + /* USER CODE END MemoryManagement_IRQn 0 */ + while (1) { + /* USER CODE BEGIN W1_MemoryManagement_IRQn 0 */ + /* USER CODE END W1_MemoryManagement_IRQn 0 */ + } +} + +/** + * @brief This function handles Pre-fetch fault, memory access fault. + */ +void BusFault_Handler(void) +{ + /* USER CODE BEGIN BusFault_IRQn 0 */ + + /* USER CODE END BusFault_IRQn 0 */ + while (1) { + /* USER CODE BEGIN W1_BusFault_IRQn 0 */ + /* USER CODE END W1_BusFault_IRQn 0 */ + } +} + +/** + * @brief This function handles Undefined instruction or illegal state. + */ +void UsageFault_Handler(void) +{ + /* USER CODE BEGIN UsageFault_IRQn 0 */ + + /* USER CODE END UsageFault_IRQn 0 */ + while (1) { + /* USER CODE BEGIN W1_UsageFault_IRQn 0 */ + /* USER CODE END W1_UsageFault_IRQn 0 */ + } +} + +/** + * @brief This function handles System service call via SWI instruction. + */ +void SVC_Handler(void) +{ + /* USER CODE BEGIN SVCall_IRQn 0 */ + + /* USER CODE END SVCall_IRQn 0 */ + /* USER CODE BEGIN SVCall_IRQn 1 */ + + /* USER CODE END SVCall_IRQn 1 */ +} + +/** + * @brief This function handles Debug monitor. + */ +void DebugMon_Handler(void) +{ + /* USER CODE BEGIN DebugMonitor_IRQn 0 */ + + /* USER CODE END DebugMonitor_IRQn 0 */ + /* USER CODE BEGIN DebugMonitor_IRQn 1 */ + + /* USER CODE END DebugMonitor_IRQn 1 */ +} + +/** + * @brief This function handles Pendable request for system service. + */ +void PendSV_Handler(void) +{ + /* USER CODE BEGIN PendSV_IRQn 0 */ + + /* USER CODE END PendSV_IRQn 0 */ + /* USER CODE BEGIN PendSV_IRQn 1 */ + + /* USER CODE END PendSV_IRQn 1 */ +} + +/** + * @brief This function handles System tick timer. + */ +void SysTick_Handler(void) +{ + /* USER CODE BEGIN SysTick_IRQn 0 */ + + /* USER CODE END SysTick_IRQn 0 */ + HAL_IncTick(); + /* USER CODE BEGIN SysTick_IRQn 1 */ + + /* USER CODE END SysTick_IRQn 1 */ +} + +/******************************************************************************/ +/* STM32H5xx Peripheral Interrupt Handlers */ +/* Add here the Interrupt Handlers for the used peripherals. */ +/* For the available peripheral interrupt handler names, */ +/* please refer to the startup file (startup_stm32h5xx.s). */ +/******************************************************************************/ + +/* USER CODE BEGIN 1 */ + +/* USER CODE END 1 */ diff --git a/H523xx_CAN_TESTING/Core/Src/tim.c b/H523xx_CAN_TESTING/Core/Src/tim.c new file mode 100644 index 000000000..7f521c3bf --- /dev/null +++ b/H523xx_CAN_TESTING/Core/Src/tim.c @@ -0,0 +1,79 @@ +/* USER CODE BEGIN Header */ +/** + ****************************************************************************** + * @file tim.c + * @brief This file provides code for the configuration + * of the TIM instances. + ****************************************************************************** + * @attention + * + * Copyright (c) 2025 STMicroelectronics. + * All rights reserved. + * + * This software is licensed under terms that can be found in the LICENSE file + * in the root directory of this software component. + * If no LICENSE file comes with this software, it is provided AS-IS. + * + ****************************************************************************** + */ +/* USER CODE END Header */ +/* Includes ------------------------------------------------------------------*/ +#include "tim.h" + +/* USER CODE BEGIN 0 */ + +/* USER CODE END 0 */ + +/* TIM2 init function */ +void MX_TIM2_Init(void) +{ + + /* USER CODE BEGIN TIM2_Init 0 */ + + /* USER CODE END TIM2_Init 0 */ + + LL_TIM_InitTypeDef TIM_InitStruct = {0}; + LL_TIM_OC_InitTypeDef TIM_OC_InitStruct = {0}; + + LL_GPIO_InitTypeDef GPIO_InitStruct = {0}; + /* Peripheral clock enable */ + LL_APB1_GRP1_EnableClock(LL_APB1_GRP1_PERIPH_TIM2); + + /* USER CODE BEGIN TIM2_Init 1 */ + + /* USER CODE END TIM2_Init 1 */ + TIM_InitStruct.Prescaler = 0; + TIM_InitStruct.CounterMode = LL_TIM_COUNTERMODE_UP; + TIM_InitStruct.Autoreload = 4294967295; + TIM_InitStruct.ClockDivision = LL_TIM_CLOCKDIVISION_DIV1; + LL_TIM_Init(TIM2, &TIM_InitStruct); + LL_TIM_DisableARRPreload(TIM2); + LL_TIM_SetClockSource(TIM2, LL_TIM_CLOCKSOURCE_INTERNAL); + TIM_OC_InitStruct.OCMode = LL_TIM_OCMODE_FORCED_ACTIVE; + TIM_OC_InitStruct.OCState = LL_TIM_OCSTATE_DISABLE; + TIM_OC_InitStruct.OCNState = LL_TIM_OCSTATE_DISABLE; + TIM_OC_InitStruct.CompareValue = 0; + TIM_OC_InitStruct.OCPolarity = LL_TIM_OCPOLARITY_HIGH; + LL_TIM_OC_Init(TIM2, LL_TIM_CHANNEL_CH1, &TIM_OC_InitStruct); + LL_TIM_OC_DisableFast(TIM2, LL_TIM_CHANNEL_CH1); + LL_TIM_SetTriggerOutput(TIM2, LL_TIM_TRGO_RESET); + LL_TIM_DisableMasterSlaveMode(TIM2); + /* USER CODE BEGIN TIM2_Init 2 */ + + /* USER CODE END TIM2_Init 2 */ + LL_AHB2_GRP1_EnableClock(LL_AHB2_GRP1_PERIPH_GPIOA); + /**TIM2 GPIO Configuration + PA0 ------> TIM2_CH1 + */ + GPIO_InitStruct.Pin = LL_GPIO_PIN_0; + GPIO_InitStruct.Mode = LL_GPIO_MODE_ALTERNATE; + GPIO_InitStruct.Speed = LL_GPIO_SPEED_FREQ_LOW; + GPIO_InitStruct.OutputType = LL_GPIO_OUTPUT_PUSHPULL; + GPIO_InitStruct.Pull = LL_GPIO_PULL_NO; + GPIO_InitStruct.Alternate = LL_GPIO_AF_1; + LL_GPIO_Init(GPIOA, &GPIO_InitStruct); +} + +/* USER CODE BEGIN 1 */ + +/* USER CODE END 1 */ diff --git a/H523xx_CAN_TESTING/Core/Src/usart.c b/H523xx_CAN_TESTING/Core/Src/usart.c new file mode 100644 index 000000000..ed1d3db0f --- /dev/null +++ b/H523xx_CAN_TESTING/Core/Src/usart.c @@ -0,0 +1,184 @@ +/* USER CODE BEGIN Header */ +/** + ****************************************************************************** + * @file usart.c + * @brief This file provides code for the configuration + * of the USART instances. + ****************************************************************************** + * @attention + * + * Copyright (c) 2025 STMicroelectronics. + * All rights reserved. + * + * This software is licensed under terms that can be found in the LICENSE file + * in the root directory of this software component. + * If no LICENSE file comes with this software, it is provided AS-IS. + * + ****************************************************************************** + */ +/* USER CODE END Header */ +/* Includes ------------------------------------------------------------------*/ +#include "usart.h" + +/* USER CODE BEGIN 0 */ + +/* USER CODE END 0 */ + +/* LPUART1 init function */ + +void MX_LPUART1_UART_Init(void) +{ + + /* USER CODE BEGIN LPUART1_Init 0 */ + + /* USER CODE END LPUART1_Init 0 */ + + LL_LPUART_InitTypeDef LPUART_InitStruct = {0}; + + LL_GPIO_InitTypeDef GPIO_InitStruct = {0}; + + LL_RCC_SetLPUARTClockSource(LL_RCC_LPUART1_CLKSOURCE_HSI); + + /* Peripheral clock enable */ + LL_APB3_GRP1_EnableClock(LL_APB3_GRP1_PERIPH_LPUART1); + + LL_AHB2_GRP1_EnableClock(LL_AHB2_GRP1_PERIPH_GPIOA); + /**LPUART1 GPIO Configuration + PA2 ------> LPUART1_TX + PA3 ------> LPUART1_RX + */ + GPIO_InitStruct.Pin = LL_GPIO_PIN_2; + GPIO_InitStruct.Mode = LL_GPIO_MODE_ALTERNATE; + GPIO_InitStruct.Speed = LL_GPIO_SPEED_FREQ_HIGH; + GPIO_InitStruct.OutputType = LL_GPIO_OUTPUT_PUSHPULL; + GPIO_InitStruct.Pull = LL_GPIO_PULL_NO; + GPIO_InitStruct.Alternate = LL_GPIO_AF_12; + LL_GPIO_Init(GPIOA, &GPIO_InitStruct); + + GPIO_InitStruct.Pin = LL_GPIO_PIN_3; + GPIO_InitStruct.Mode = LL_GPIO_MODE_ALTERNATE; + GPIO_InitStruct.Speed = LL_GPIO_SPEED_FREQ_HIGH; + GPIO_InitStruct.OutputType = LL_GPIO_OUTPUT_PUSHPULL; + GPIO_InitStruct.Pull = LL_GPIO_PULL_NO; + GPIO_InitStruct.Alternate = LL_GPIO_AF_12; + LL_GPIO_Init(GPIOA, &GPIO_InitStruct); + + /* USER CODE BEGIN LPUART1_Init 1 */ + + /* USER CODE END LPUART1_Init 1 */ + LPUART_InitStruct.PrescalerValue = LL_LPUART_PRESCALER_DIV1; + LPUART_InitStruct.BaudRate = 115200; + LPUART_InitStruct.DataWidth = LL_LPUART_DATAWIDTH_8B; + LPUART_InitStruct.StopBits = LL_LPUART_STOPBITS_1; + LPUART_InitStruct.Parity = LL_LPUART_PARITY_NONE; + LPUART_InitStruct.TransferDirection = LL_LPUART_DIRECTION_TX_RX; + LPUART_InitStruct.HardwareFlowControl = LL_LPUART_HWCONTROL_NONE; + LL_LPUART_Init(LPUART1, &LPUART_InitStruct); + LL_LPUART_SetTXFIFOThreshold(LPUART1, LL_LPUART_FIFOTHRESHOLD_1_8); + LL_LPUART_SetRXFIFOThreshold(LPUART1, LL_LPUART_FIFOTHRESHOLD_1_8); + LL_LPUART_DisableFIFO(LPUART1); + + /* USER CODE BEGIN WKUPType LPUART1 */ + + /* USER CODE END WKUPType LPUART1 */ + + LL_LPUART_Enable(LPUART1); + + /* Polling LPUART1 initialisation */ + while ((!(LL_LPUART_IsActiveFlag_TEACK(LPUART1))) || (!(LL_LPUART_IsActiveFlag_REACK(LPUART1)))) {} + /* USER CODE BEGIN LPUART1_Init 2 */ + + /* USER CODE END LPUART1_Init 2 */ +} +/* USART1 init function */ + +void MX_USART1_UART_Init(void) +{ + + /* USER CODE BEGIN USART1_Init 0 */ + + /* USER CODE END USART1_Init 0 */ + + LL_USART_InitTypeDef USART_InitStruct = {0}; + + LL_GPIO_InitTypeDef GPIO_InitStruct = {0}; + + LL_RCC_SetUSARTClockSource(LL_RCC_USART1_CLKSOURCE_PCLK2); + + /* Peripheral clock enable */ + LL_APB2_GRP1_EnableClock(LL_APB2_GRP1_PERIPH_USART1); + + LL_AHB2_GRP1_EnableClock(LL_AHB2_GRP1_PERIPH_GPIOC); + LL_AHB2_GRP1_EnableClock(LL_AHB2_GRP1_PERIPH_GPIOA); + LL_AHB2_GRP1_EnableClock(LL_AHB2_GRP1_PERIPH_GPIOB); + /**USART1 GPIO Configuration + PC5 ------> USART1_RX + PA11 ------> USART1_CTS + PA12 ------> USART1_RTS + PB6 ------> USART1_TX + */ + GPIO_InitStruct.Pin = LL_GPIO_PIN_5; + GPIO_InitStruct.Mode = LL_GPIO_MODE_ALTERNATE; + GPIO_InitStruct.Speed = LL_GPIO_SPEED_FREQ_LOW; + GPIO_InitStruct.OutputType = LL_GPIO_OUTPUT_PUSHPULL; + GPIO_InitStruct.Pull = LL_GPIO_PULL_NO; + GPIO_InitStruct.Alternate = LL_GPIO_AF_7; + LL_GPIO_Init(GPIOC, &GPIO_InitStruct); + + GPIO_InitStruct.Pin = LL_GPIO_PIN_11; + GPIO_InitStruct.Mode = LL_GPIO_MODE_ALTERNATE; + GPIO_InitStruct.Speed = LL_GPIO_SPEED_FREQ_LOW; + GPIO_InitStruct.OutputType = LL_GPIO_OUTPUT_PUSHPULL; + GPIO_InitStruct.Pull = LL_GPIO_PULL_NO; + GPIO_InitStruct.Alternate = LL_GPIO_AF_7; + LL_GPIO_Init(GPIOA, &GPIO_InitStruct); + + GPIO_InitStruct.Pin = LL_GPIO_PIN_12; + GPIO_InitStruct.Mode = LL_GPIO_MODE_ALTERNATE; + GPIO_InitStruct.Speed = LL_GPIO_SPEED_FREQ_LOW; + GPIO_InitStruct.OutputType = LL_GPIO_OUTPUT_PUSHPULL; + GPIO_InitStruct.Pull = LL_GPIO_PULL_NO; + GPIO_InitStruct.Alternate = LL_GPIO_AF_7; + LL_GPIO_Init(GPIOA, &GPIO_InitStruct); + + GPIO_InitStruct.Pin = LL_GPIO_PIN_6; + GPIO_InitStruct.Mode = LL_GPIO_MODE_ALTERNATE; + GPIO_InitStruct.Speed = LL_GPIO_SPEED_FREQ_LOW; + GPIO_InitStruct.OutputType = LL_GPIO_OUTPUT_PUSHPULL; + GPIO_InitStruct.Pull = LL_GPIO_PULL_NO; + GPIO_InitStruct.Alternate = LL_GPIO_AF_7; + LL_GPIO_Init(GPIOB, &GPIO_InitStruct); + + /* USER CODE BEGIN USART1_Init 1 */ + + /* USER CODE END USART1_Init 1 */ + USART_InitStruct.PrescalerValue = LL_USART_PRESCALER_DIV1; + USART_InitStruct.BaudRate = 115200; + USART_InitStruct.DataWidth = LL_USART_DATAWIDTH_8B; + USART_InitStruct.StopBits = LL_USART_STOPBITS_1; + USART_InitStruct.Parity = LL_USART_PARITY_NONE; + USART_InitStruct.TransferDirection = LL_USART_DIRECTION_TX_RX; + USART_InitStruct.HardwareFlowControl = LL_USART_HWCONTROL_RTS_CTS; + USART_InitStruct.OverSampling = LL_USART_OVERSAMPLING_16; + LL_USART_Init(USART1, &USART_InitStruct); + LL_USART_SetTXFIFOThreshold(USART1, LL_USART_FIFOTHRESHOLD_1_8); + LL_USART_SetRXFIFOThreshold(USART1, LL_USART_FIFOTHRESHOLD_1_8); + LL_USART_DisableFIFO(USART1); + LL_USART_ConfigAsyncMode(USART1); + + /* USER CODE BEGIN WKUPType USART1 */ + + /* USER CODE END WKUPType USART1 */ + + LL_USART_Enable(USART1); + + /* Polling USART1 initialisation */ + while ((!(LL_USART_IsActiveFlag_TEACK(USART1))) || (!(LL_USART_IsActiveFlag_REACK(USART1)))) {} + /* USER CODE BEGIN USART1_Init 2 */ + + /* USER CODE END USART1_Init 2 */ +} + +/* USER CODE BEGIN 1 */ + +/* USER CODE END 1 */ diff --git a/H523xx_CAN_TESTING/H523xx_CAN_BASIC_TEST/CMakeLists.txt b/H523xx_CAN_TESTING/H523xx_CAN_BASIC_TEST/CMakeLists.txt new file mode 100644 index 000000000..d33fbe114 --- /dev/null +++ b/H523xx_CAN_TESTING/H523xx_CAN_BASIC_TEST/CMakeLists.txt @@ -0,0 +1,63 @@ +cmake_minimum_required(VERSION 3.25) + +# Setup compiler settings +set(CMAKE_C_STANDARD 11) +set(CMAKE_C_STANDARD_REQUIRED ON) +set(CMAKE_C_EXTENSIONS ON) + +# Define the build type +if(NOT CMAKE_BUILD_TYPE) + set(CMAKE_BUILD_TYPE "Debug") +endif() + +# Enable compile command to ease indexing with e.g. clangd +set(CMAKE_EXPORT_COMPILE_COMMANDS TRUE) + +# Enable CMake support for ASM and C languages +enable_language( + C + ASM +) + +# Core project settings +project(${CMAKE_PROJECT_NAME}) + +# what, does in fact not get the filename of somthing but rather the name of the project from the path +get_filename_component(PROJECT_NAME ${CMAKE_CURRENT_SOURCE_DIR} NAME) + +add_library(${PROJECT_NAME}_USER_CODE INTERFACE) + +target_sources( + ${PROJECT_NAME}_USER_CODE + INTERFACE + #../Core/Src/adc.c + #../Core/Src/crc.c + #../Core/Src/dma.c + #../Core/Src/gpio.c + #../Core/Src/i2c.c + main.c + #../Core/Src/spi.c + ../Core/Src/stm32h5xx_hal_msp.c + ../Core/Src/stm32h5xx_it.c + ../Core/Src/FancyCAN_LoopbackTest.c + profile.c + can_basic_test.c + #../Core/Src/tim.c + #../Core/Src/usart.c +) + +set_target_properties( + ${NAME} + PROPERTIES + OUTPUT_NAME + "CAN_${NAME}" +) + +target_include_directories( + ${PROJECT_NAME}_USER_CODE + INTERFACE + ../Core/Inc + . +) + +target_link_libraries(${PROJECT_NAME}_USER_CODE INTERFACE GRCAN_FANCYLAYER) diff --git a/H523xx_CAN_TESTING/H523xx_CAN_BASIC_TEST/can_basic_test.c b/H523xx_CAN_TESTING/H523xx_CAN_BASIC_TEST/can_basic_test.c new file mode 100644 index 000000000..c89b4e771 --- /dev/null +++ b/H523xx_CAN_TESTING/H523xx_CAN_BASIC_TEST/can_basic_test.c @@ -0,0 +1,389 @@ +#include +#include + +#include "can.h" +#include "can_tests.h" +#include "profile.h" + +// #include "can_basic_test_cfg.h" + +// CAN Configuration +// #define OLD_SAM + +// define +#define LOOPBACK_MODE FDCAN_MODE_NORMAL +// #define RELEASE_AFTER_TEST +#ifdef RELEASE_AFTER_TEST +#pragma message "RELEASING CAN AFTER TESTS" +#endif + +#define NODE_ID 2 + +#ifndef NODE_ID +#error "can_basic_test.c: please define node in can_basic_test_cfg.h" +#endif + +// TODO: Decide how much of these parameters should go into config +#define NUM_NODES 2 // total number of nodes on the bus (including this one) +#define NUM_MESSAGES 20 // number of messages each node sends to every other node + +#define CAN_PACKET_SIZE FDCAN_DLC_BYTES_64 // max is 64 + +#define NUM_TESTS FDCAN_DLC_BYTES_64 +static float rx_stats[NUM_TESTS + 1] = {0}; + +// TODO: figure out if ifdef soup is avoidable +#ifdef FDCAN2 +#define DATA_CAN +#endif + +// FDCAN_DLC_BYTES_ + +CAN_STATUS defaultSTM32H523xx_CANCfg(FDCAN_GlobalTypeDef *instance, CAN_RXCallback callback, CANConfig *out_cfg, uint32_t Mode, uint32_t numStdFilters, uint32_t numExtFilters) +{ + CANConfig canCfg; + + canCfg.hal_fdcan_init.ClockDivider = FDCAN_CLOCK_DIV1; + canCfg.hal_fdcan_init.FrameFormat = FDCAN_FRAME_FD_BRS; + canCfg.hal_fdcan_init.TxFifoQueueMode = FDCAN_TX_FIFO_OPERATION; + canCfg.hal_fdcan_init.Mode = Mode; + canCfg.hal_fdcan_init.AutoRetransmission = ENABLE; + canCfg.hal_fdcan_init.TransmitPause = DISABLE; + canCfg.hal_fdcan_init.ProtocolException = ENABLE; + canCfg.hal_fdcan_init.NominalPrescaler = 1; + canCfg.hal_fdcan_init.NominalSyncJumpWidth = 16; + canCfg.hal_fdcan_init.NominalTimeSeg1 = 47; // 64 MHz PLL1Q clock -> (1+47+16) = 64 tq, 1 Mbps at 75% sample point + canCfg.hal_fdcan_init.NominalTimeSeg2 = 16; + canCfg.hal_fdcan_init.DataPrescaler = 1; + canCfg.hal_fdcan_init.DataSyncJumpWidth = 16; + canCfg.hal_fdcan_init.DataTimeSeg1 = 5; // 64 MHz PLL1Q clock -> (1+5+2) = 8 tq, 8 Mbps at 75% sample point + canCfg.hal_fdcan_init.DataTimeSeg2 = 2; + canCfg.hal_fdcan_init.StdFiltersNbr = numStdFilters; + canCfg.hal_fdcan_init.ExtFiltersNbr = numExtFilters; + + canCfg.rx_callback = NULL; + canCfg.rx_interrupt_priority = 14; + canCfg.tx_interrupt_priority = 14; + + canCfg.init_rx_gpio.Mode = GPIO_MODE_AF_PP; + canCfg.init_rx_gpio.Pull = GPIO_PULLUP; + canCfg.init_rx_gpio.Speed = GPIO_SPEED_FREQ_VERY_HIGH; + + canCfg.init_tx_gpio.Mode = GPIO_MODE_AF_PP; + canCfg.init_tx_gpio.Pull = GPIO_NOPULL; + canCfg.init_tx_gpio.Speed = GPIO_SPEED_FREQ_VERY_HIGH; + + canCfg.rx_callback = callback; + +#ifdef USECAN1 + if (instance == FDCAN1) { + canCfg.fdcan_instance = FDCAN1; + canCfg.rx_gpio = GPIOA; + canCfg.init_rx_gpio.Pin = GPIO_PIN_11; + canCfg.init_rx_gpio.Alternate = GPIO_AF9_FDCAN1; + + canCfg.tx_gpio = GPIOA; + canCfg.init_tx_gpio.Pin = GPIO_PIN_12; + canCfg.init_tx_gpio.Alternate = GPIO_AF9_FDCAN1; + + *out_cfg = canCfg; + return CAN_SUCCESS; + } +#endif + +#ifdef USECAN2 + if (instance == FDCAN2) { + canCfg.fdcan_instance = FDCAN2; + canCfg.rx_gpio = GPIOA; + canCfg.init_rx_gpio.Pin = GPIO_PIN_0; + canCfg.init_rx_gpio.Alternate = GPIO_AF9_FDCAN2; + + canCfg.tx_gpio = GPIOA; + canCfg.init_tx_gpio.Pin = GPIO_PIN_10; + canCfg.init_tx_gpio.Alternate = GPIO_AF9_FDCAN2; + + *out_cfg = canCfg; + return CAN_SUCCESS; + } +#endif + + return CAN_ERROR; +} + +dwt_timer_t rx_timer = {0}; + +// TODO: could make creating these callbacks a macro, rather than defining each one separately +static volatile uint32_t rx_1_received = 0; +static volatile uint8_t can1_data[64] = {0}; +static void can_test_rx_callback1(uint32_t id, void *data, uint32_t size) +{ + dwt_timer_end_measurement(&rx_timer); + + rx_1_received++; + LOGOMATIC("CAN1 Got data! Size %ld, data[0] = 0x%x, id %" PRIu32 "\n", size, *(char *)data, id); + // Is within an ISR, so needs to exit quickly + uint8_t *data_bytes = (uint8_t *)data; + + // allow for cache coherency + // for (int i = 0; i < 100000; i++); + + bool failure = false; + for (uint32_t i = 0; i < size; i++) { + can1_data[i] = data_bytes[i]; + + if (can1_data[i] != i) { + failure = true; + } + } + + // reset + for (uint32_t i = 0; i < size; i++) { + can1_data[i] = 0; + } + if (failure) { + LOGOMATIC("FAIL: did not copy data correctly\n"); + } + + return; +} + +#ifdef DATA_CAN +static volatile uint32_t rx_2_received = 0; +static void can_test_rx_callback2(uint32_t id, void *data, uint32_t size) +{ + rx_2_received++; + LOGOMATIC("CAN2 Got data! Size %ld, data[0] = 0x%x, id %" PRIu32 "\n", size, *(char *)data, id); + + // Is within an ISR, so needs to exit quickly + return; +} +#endif + +// TODO - allow user to send data without needing to construct a header for the buffer +// TODO: G4 tests are dependent on the System clock configuration?? +int can_basic_test(void) +{ + FDCAN_TxHeaderTypeDef TxHeader = { + .Identifier = NODE_ID, + .FDFormat = FDCAN_FD_CAN, + .IdType = FDCAN_STANDARD_ID, + .TxFrameType = FDCAN_DATA_FRAME, + .ErrorStateIndicator = FDCAN_ESI_ACTIVE, // honestly this might be a value you have to read from a node + // FDCAN_ESI_ACTIVE is just a state that assumes there are minimal errors + .DataLength = CAN_PACKET_SIZE, + .BitRateSwitch = FDCAN_BRS_ON, + .TxEventFifoControl = FDCAN_NO_TX_EVENTS, // change to FDCAN_STORE_TX_EVENTS if you need to store info regarding transmitted messages + .MessageMarker = 0 // also change this to a real address if you change fifo control + }; + + CANHandle *primary_can = NULL; + primary_can = NULL; + CANConfig cfg1; + +#ifdef DATA_CAN + CANHandle *data_can = NULL; + CANConfig cfg2; +#endif + + LOGOMATIC("Initializing primary and data CAN Bus in Normal mode.\n"); + if (defaultSTM32H523xx_CANCfg(FDCAN1, can_test_rx_callback1, &cfg1, LOOPBACK_MODE, 0, 0)) { + LOGOMATIC("Could not get config for FDCAN1\n"); + return ERROR; + } + /*cfg1.rx_gpio = GPIOA; + cfg1.init_rx_gpio.Pin = GPIO_PIN_11; + cfg1.init_rx_gpio.Alternate = GPIO_AF9_FDCAN1; + + cfg1.tx_gpio = GPIOA; + cfg1.init_tx_gpio.Pin = GPIO_PIN_12; + cfg1.init_tx_gpio.Alternate = GPIO_AF9_FDCAN1; + */ + +#ifdef DATA_CAN + if (defaultSTM32H523xx_CANCfg(FDCAN2, can_test_rx_callback2, &cfg2, LOOPBACK_MODE, 0, 0)) { + LOGOMATIC("Could not get config for FDCAN2\n"); + return ERROR; + } +#endif + +#ifdef OLD_SAM + cfg2.rx_gpio = GPIOB; + cfg2.init_rx_gpio.Pin = GPIO_PIN_13; + cfg2.init_rx_gpio.Alternate = GPIO_AF9_FDCAN2; + + cfg2.tx_gpio = GPIOB; + cfg2.init_tx_gpio.Pin = GPIO_PIN_5; + cfg2.init_tx_gpio.Alternate = GPIO_AF9_FDCAN2; +#endif + + can_set_clksource(LL_RCC_FDCAN_CLKSOURCE_PLL1Q); + + //============================================================================================= + if ((primary_can = can_init(&cfg1)) == NULL) { + LOGOMATIC("Could not initialize primary_can\n"); + return ERROR; + } + HAL_FDCAN_ConfigGlobalFilter(primary_can->hal_fdcanP, 0, 0, 0, 0); + +#ifdef DATA_CAN + if ((data_can = can_init(&cfg2)) == NULL) { + LOGOMATIC("Could not initialize data_can\n"); + return ERROR; + } + HAL_FDCAN_ConfigGlobalFilter(data_can->hal_fdcanP, 0, 0, 0, 0); +#endif + + //============================================================================================= + if (can_start(primary_can)) { + LOGOMATIC("Could not start primary_can\n"); + return ERROR; + } + +#ifdef DATA_CAN + if (can_start(data_can)) { + LOGOMATIC("Could not start data_can\n"); + return ERROR; + } +#endif + + FDCANTxMessage msg = {0}; + // msg.data[0] = 0x80; + for (int i = 0; i < CANFD_DLCtoBytes[CAN_PACKET_SIZE]; i++) { + msg.data[i] = i; + } + + msg.tx_header = TxHeader; + + LOGOMATIC("Sending %d messages on each bus...\n", NUM_MESSAGES); + + // uint32_t node_target = 0; + + start_dwt(); + + for (uint32_t data_length_code = 0; data_length_code < FDCAN_DLC_BYTES_64 + 1; data_length_code++) { + msg.tx_header.DataLength = data_length_code; + dwt_timer_t send1_timer = {0}; +#ifdef DATA_CAN + dwt_timer_t send2_timer = {0}; +#endif + + dwt_timer_reset(&rx_timer); + + uint32_t i = 0; + while (i < NUM_MESSAGES) { + HAL_Delay(10); + // msg.data[0] = 0x2; + + dwt_timer_start_measurement(&send1_timer); + can_enqueue(primary_can, &msg); + dwt_timer_end_measurement(&send1_timer); + + HAL_Delay(10); + // msg.data[0] = 0x10; + +#ifdef DATA_CAN + dwt_timer_start_measurement(&send2_timer); + can_enqueue(data_can, &msg); + // for(int i = 0; i < 100; i++); + dwt_timer_end_measurement(&send2_timer); +#endif + + i += 1; + } + +#ifdef PROFILE + // LOGOMATIC("NORMAL MODE - timing entire Rx callback (not just fifo copy)\n"); + LOGOMATIC("CAN PACKET SIZE: %u\n", CANFD_DLCtoBytes[data_length_code]); + LOGOMATIC("Send1 ===========\n"); + dwt_timer_print_info(&send1_timer); + +#ifdef DATA_CAN + LOGOMATIC("Send2 ===============\n"); + dwt_timer_print_info(&send2_timer); +#endif + + LOGOMATIC("Rx ===============\n"); + dwt_timer_print_info(&rx_timer); + + rx_stats[data_length_code] = dwt_timer_average_cycles(&rx_timer); + + LOGOMATIC("can_basic_test: SUCCESS\n"); +#endif + + HAL_Delay(100); + LOGOMATIC("Received %ld messages on bus1...\n", rx_1_received); + +#ifdef DATA_CAN + LOGOMATIC("Received %ld messages on bus2...\n", rx_2_received); +#endif + + uint32_t error = false; + + // TODO: Create testing functions to check state of can instance + if (rx_1_received != NUM_MESSAGES * (NUM_NODES - 1)) { + error = true; + LOGOMATIC("FAIL: can_basic_test: did not receive all rx1\n"); + } else { + LOGOMATIC("SUCCESS: can_basic_test: received all rx1\n"); + } + rx_1_received = 0; + +#ifdef DATA_CAN + if ((rx_2_received != NUM_MESSAGES * (NUM_NODES - 1))) { + error = true; + LOGOMATIC("FAIL: can_basic_test: did not receive all rx2\n"); + } else { + LOGOMATIC("SUCCESS: can_basic_test: received all rx2\n"); + } + rx_2_received = 0; +#endif + + if (primary_can->tx_elements > 0) { + LOGOMATIC("can_basic_test: FAIL: did not send all messages from primary tx_buffer\n"); + } + +#ifdef DATA_CAN + if (data_can->tx_elements > 0) { + LOGOMATIC("can_basic_test: FAIL: did not send all messages from data tx_buffer\n"); + } +#endif + + LOGOMATIC("\n"); + UNUSED(error); + } + + stop_dwt(); + + LOGOMATIC("=================PROFILING RESULTS ============================\n"); + for (uint32_t i = 0; i <= FDCAN_DLC_BYTES_64; i++) { + LOGOMATIC("%d: %.2f\n", CANFD_DLCtoBytes[i], rx_stats[i]); + } + LOGOMATIC("\n"); + + uint32_t error = false; + +#ifdef RELEASE_AFTER_TEST + if ((error |= can_release(primary_can))) { + LOGOMATIC("FAIL: can_basic_test; could not release primary_can\n"); + } + +#ifdef DATA_CAN + if ((error |= can_release(data_can))) { + LOGOMATIC("FAIL: can_basic_test; could not release data_can\n"); + } +#endif +#endif + +#ifndef RELEASE_AFTER_TEST + while (true) { + can_enqueue(primary_can, &msg); + HAL_Delay(100); + } +#endif + + if (error) { + return ERROR; + } + + return SUCCESS; +} diff --git a/H523xx_CAN_TESTING/H523xx_CAN_BASIC_TEST/can_cfg.h b/H523xx_CAN_TESTING/H523xx_CAN_BASIC_TEST/can_cfg.h new file mode 100644 index 000000000..f22b62b7a --- /dev/null +++ b/H523xx_CAN_TESTING/H523xx_CAN_BASIC_TEST/can_cfg.h @@ -0,0 +1,10 @@ +#ifndef CAN_CFG_H +#define CAN_CFG_H + +#define USECAN1 +#define TX_BUFFER_1_SIZE 10 +#define TX_BUFFER_2_SIZE 10 + +#define CAN_TIMER_SEND_PERIOD_US 625 + +#endif diff --git a/H523xx_CAN_TESTING/H523xx_CAN_BASIC_TEST/can_external_test_cfg.h b/H523xx_CAN_TESTING/H523xx_CAN_BASIC_TEST/can_external_test_cfg.h new file mode 100644 index 000000000..0b7e7a815 --- /dev/null +++ b/H523xx_CAN_TESTING/H523xx_CAN_BASIC_TEST/can_external_test_cfg.h @@ -0,0 +1,6 @@ +#ifndef CAN_BASIC_TEST_CFG_H +#define CAN_BASIC_TEST_CFG_H + +#define NODE_ID 1 + +#endif diff --git a/H523xx_CAN_TESTING/H523xx_CAN_BASIC_TEST/can_tests.h b/H523xx_CAN_TESTING/H523xx_CAN_BASIC_TEST/can_tests.h new file mode 100644 index 000000000..7776e9c48 --- /dev/null +++ b/H523xx_CAN_TESTING/H523xx_CAN_BASIC_TEST/can_tests.h @@ -0,0 +1,24 @@ +#ifndef CAN_TESTS_H +#define CAN_TESTS_H + +#include "Logomatic.h" +#include "can.h" +#include "can_platform_deps.h" +#include "profile.h" + +// abstract families +// extern int get_cfg(FDCAN_GlobalTypeDef *instance, CAN_RXCallback callback, CANConfig *out_cfg, uint32_t Mode); + +// testing functions +extern int can_external_two_node(void); +extern int can_basic_test(void); +extern int can_stress_test(void); +extern int can_release_test(void); +extern int can_filter_test(void); +extern int can_lost_rx_test(void); + +// timers +extern dwt_timer_t rx_timer; +extern dwt_timer_t send_timer; + +#endif diff --git a/H523xx_CAN_TESTING/H523xx_CAN_BASIC_TEST/main.c b/H523xx_CAN_TESTING/H523xx_CAN_BASIC_TEST/main.c new file mode 100644 index 000000000..c8eeba1e4 --- /dev/null +++ b/H523xx_CAN_TESTING/H523xx_CAN_BASIC_TEST/main.c @@ -0,0 +1,272 @@ +/* USER CODE BEGIN Header */ +/** + ****************************************************************************** + * @file : main.c + * @brief : Main program body + ****************************************************************************** + * @attention + * + * Copyright (c) 2024 STMicroelectronics. + * All rights reserved. + * + * This software is licensed under terms that can be found in the LICENSE file + * in the root directory of this software component. + * If no LICENSE file comes with this software, it is provided AS-IS. + * + ****************************************************************************** + */ +/* USER CODE END Header */ +/* Includes ------------------------------------------------------------------*/ +#include "main.h" + +#include "adc.h" +#include "can.h" // Assume this works +#include "can_tests.h" +#include "dma.h" +#include "fdcan.h" +#include "gpio.h" +#include "i2c.h" +#include "spi.h" +#include "tim.h" +#include "usart.h" + +/* Private includes ----------------------------------------------------------*/ +/* USER CODE BEGIN Includes */ +#include "FancyCAN_LoopbackTest.h" +#include "GRCAN_FancyLayer.h" +#include "Logomatic.h" +/* USER CODE END Includes */ + +/* Private typedef -----------------------------------------------------------*/ +/* USER CODE BEGIN PTD */ + +/* USER CODE END PTD */ + +/* Private define ------------------------------------------------------------*/ +/* USER CODE BEGIN PD */ + +/* USER CODE END PD */ + +/* Private macro -------------------------------------------------------------*/ +/* USER CODE BEGIN PM */ + +/* USER CODE END PM */ + +/* Private variables ---------------------------------------------------------*/ + +/* USER CODE BEGIN PV */ +/* USER CODE END PV */ + +/* Private function prototypes -----------------------------------------------*/ +void SystemClock_Config(void); +/* USER CODE BEGIN PFP */ + +/* USER CODE END PFP */ + +/* Private user code ---------------------------------------------------------*/ +/* USER CODE BEGIN 0 */ +/* Enable ITM for SWO output */ +LogomaticConfig logomatic_config = { + .baud_rate = 115200, + .clock_source = LOGOMATIC_PCLK3, + .data_width = LOGOMATIC_DATAWIDTH_8B, + .gpio_pin_rx_tx_mask = LL_GPIO_PIN_6 | LL_GPIO_PIN_7, + .gpio_port = LOGOMATIC_GPIOB, + .hardware_flow_control = LOGOMATIC_HWCONTROL_NONE, + .parity = LOGOMATIC_PARITY_NONE, + .prescaler = LOGOMATIC_PRESCALER_DIV1, + .stop_bits = LOGOMATIC_STOPBITS_1, + .transfer_direction = LOGOMATIC_DIRECTION_TX, + .tx_fifo_threshold = LOGOMATIC_FIFOTHRESHOLD_1_8, + .rx_fifo_threshold = LOGOMATIC_FIFOTHRESHOLD_1_8, + .bus = LOGOMATIC_BUS, +}; + +static void ITM_Enable(void) +{ + LL_AHB2_GRP1_EnableClock(LL_AHB2_GRP1_PERIPH_GPIOB); + LL_GPIO_InitTypeDef GPIO_InitStruct = {0}; + GPIO_InitStruct.Pin = LL_GPIO_PIN_3; + GPIO_InitStruct.Mode = LL_GPIO_MODE_ALTERNATE; + GPIO_InitStruct.Speed = LL_GPIO_SPEED_FREQ_VERY_HIGH; + GPIO_InitStruct.OutputType = LL_GPIO_OUTPUT_PUSHPULL; + GPIO_InitStruct.Pull = LL_GPIO_PULL_NO; + GPIO_InitStruct.Alternate = LL_GPIO_AF_0; + LL_GPIO_Init(GPIOB, &GPIO_InitStruct); + + // DBGMCU->CR |= DBGMCU_CR_TRACE_IOEN; + + /* Enable TRC (Trace) */ + CoreDebug->DEMCR |= CoreDebug_DEMCR_TRCENA_Msk; + + /* Configure TPI for SWO output (set prescaler for 2MHz SWO clock) */ + TPI->SPPR = 2U; /* 2 = Manchester/async UART mode */ + TPI->ACPR = 84U; /* Prescaler: (250 MHz / (84+1) / 2) ≈ 1MHz SWO */ + + ITM->TER |= (1UL << 0); + ITM->TCR |= (ITM_TCR_ITMENA_Msk | ITM_TCR_SWOENA_Msk); +} +// static int toggleze = 0; +/* USER CODE END 0 */ + +/** + * @brief The application entry point. + * @retval int + */ +int main(void) +{ + /* USER CODE BEGIN 1 */ + + /* USER CODE END 1 */ + + /* MCU + * Configuration--------------------------------------------------------*/ + + /* Reset of all peripherals, Initializes the Flash interface and the + * Systick. */ + HAL_Init(); + /* USER CODE BEGIN Init */ + ITM_Enable(); + /* USER CODE END Init */ + + /* Configure the system clock */ + SystemClock_Config(); + + /* USER CODE BEGIN SysInit */ + + /* USER CODE END SysInit */ + + /* Initialize all configured peripherals */ + // MX_GPIO_Init(); + // MX_DMA_Init(); + // MX_FDCAN2_Init(); + // MX_ADC1_Init(); + + // MX_LPUART1_UART_Init(); + Setup_Logomatic(&logomatic_config); + // MX_I2C2_Init(); + // MX_USART1_UART_Init(); + // MX_SPI3_Init(); + // MX_TIM2_Init(); + int result = FancyCAN_LoopbackTest(); + LOGOMATIC("\n"); + if (result) { + LOGOMATIC("CAN Loopback Test PASSED!\n"); + } else { + LOGOMATIC("CAN Loopback Test FAILED!\n"); + } + + /* USER CODE BEGIN 2 */ + + LOGOMATIC("Booted!\n"); + + // LOGOMATIC("running can_basic_test:\n"); + can_basic_test(); + + /* Infinite loop */ + /* USER CODE BEGIN WHILE */ + while (1) { + /* USER CODE END WHILE */ + LOGOMATIC("Main Loop\n"); + LL_mDelay(10000); + + // Receive on GPIOs + // HAL_GPIO_WritePin(GPIOA, GPIO_PIN_5, toggleze ? GPIO_PIN_SET + // : GPIO_PIN_RESET); HAL_Delay(1000); msg.data[0] = toggleze ? + // 0x00 : 0x80; can_send(data_can, &msg); + + // RCC->CFGR |= RCC_CFGR_SW; + /* USER CODE BEGIN 3 */ + } +} + +/** + * @brief System Clock Configuration + * @retval None + */ + +// For 250 MHz +void SystemClock_Config(void) +{ + RCC_OscInitTypeDef RCC_OscInitStruct = {0}; + RCC_ClkInitTypeDef RCC_ClkInitStruct = {0}; + + /** Configure the main internal regulator output voltage + */ + __HAL_PWR_VOLTAGESCALING_CONFIG(PWR_REGULATOR_VOLTAGE_SCALE0); + + while (!__HAL_PWR_GET_FLAG(PWR_FLAG_VOSRDY)) {} + + /** 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_ON; + RCC_OscInitStruct.PLL.PLLSource = RCC_PLL1_SOURCE_HSI; // 64 MHz initially + RCC_OscInitStruct.HSIDiv = RCC_HSI_DIV4; // 16 MHz + RCC_OscInitStruct.PLL.PLLM = 4; // 4 MHz + RCC_OscInitStruct.PLL.PLLN = 90; // 360 MHz + RCC_OscInitStruct.PLL.PLLP = 2; // 180 MHz + RCC_OscInitStruct.PLL.PLLQ = 2; + RCC_OscInitStruct.PLL.PLLR = 2; + RCC_OscInitStruct.PLL.PLLRGE = RCC_PLL1_VCIRANGE_2; + RCC_OscInitStruct.PLL.PLLVCOSEL = RCC_PLL1_VCORANGE_WIDE; + RCC_OscInitStruct.PLL.PLLFRACN = 0; + 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_CLOCKTYPE_PCLK3; + RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK; + RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1; + RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV1; + RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1; + RCC_ClkInitStruct.APB3CLKDivider = RCC_HCLK_DIV1; + + if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_5) != HAL_OK) { + Error_Handler(); + } + + /** Configure the programming delay + */ + __HAL_FLASH_SET_PROGRAM_DELAY(FLASH_PROGRAMMING_DELAY_2); +} + +/* USER CODE BEGIN 4 */ + +/* USER CODE END 4 */ + +/** + * @brief This function is executed in case of error occurrence. + * @retval None + */ +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 */ +} +#ifdef USE_FULL_ASSERT +/** + * @brief Reports the name of the source file and the source line number + * where the assert_param error has occurred. + * @param file: pointer to the source file name + * @param line: assert_param error line source number + * @retval None + */ +void assert_failed(uint8_t *file, uint32_t line) +{ + /* USER CODE BEGIN 6 */ + /* User can add his own implementation to report the file name and line + number, ex: printf("Wrong parameters value: file %s on line %d\r\n", + file, line) */ + /* USER CODE END 6 */ +} +#endif /* USE_FULL_ASSERT */ diff --git a/H523xx_CAN_TESTING/H523xx_CAN_BASIC_TEST/profile.c b/H523xx_CAN_TESTING/H523xx_CAN_BASIC_TEST/profile.c new file mode 100644 index 000000000..1ece3baae --- /dev/null +++ b/H523xx_CAN_TESTING/H523xx_CAN_BASIC_TEST/profile.c @@ -0,0 +1,23 @@ +#include "profile.h" + +dwt_timer_t GLOBAL_DWT_TIMER = {0}; + +void profiler_test() +{ + dwt_timer_t timer = {0}; + + start_dwt(); + + for (int i = 0; i < 100; i++) { + // global_dwt_timer_start_measurement(); + dwt_timer_start_measurement(&timer); + // HAL_Delay(1); + // for (int i = 0; i < 10; i++); + dwt_timer_end_measurement(&timer); + // global_dwt_timer_start_measurement(); + } + + dwt_timer_print_info(&timer); + + stop_dwt(); +} diff --git a/H523xx_CAN_TESTING/H523xx_CAN_BASIC_TEST/profile.h b/H523xx_CAN_TESTING/H523xx_CAN_BASIC_TEST/profile.h new file mode 100644 index 000000000..764bc8bec --- /dev/null +++ b/H523xx_CAN_TESTING/H523xx_CAN_BASIC_TEST/profile.h @@ -0,0 +1,143 @@ +#ifndef PROFILE_H +#define PROFILE_H + +#define PROFILE 0 + +#include +#include + +#include "Logomatic.h" + +static inline uint32_t max_u32(uint32_t a, uint32_t b) +{ + return a > b ? a : b; +} +typedef struct dwt_timer_t { + uint32_t total_cycles; + uint32_t total_samples; + + volatile uint32_t start_cycle; + volatile uint32_t end_cycle; + + volatile uint32_t max_cycles; + volatile uint32_t min_cycles; + + volatile bool measuring; +} dwt_timer_t; + +static inline void start_dwt() +{ + // DWT->CYCCNT = 0; + CoreDebug->DEMCR |= CoreDebug_DEMCR_TRCENA_Msk; + DWT->CTRL |= DWT_CTRL_CYCCNTENA_Msk; + __ISB(); +} + +static inline void stop_dwt() +{ + DWT->CTRL &= ~DWT_CTRL_CYCCNTENA_Msk; +} + +// static number of cycles is 37 +#define STATIC_CYCLE_COST 36 + +static inline float dwt_timer_average_cycles(const dwt_timer_t *dt) +{ + return (dt->total_cycles) / ((float)dt->total_samples); +} +static inline void dwt_timer_start_measurement(dwt_timer_t *dt) +{ + dt->measuring = true; + dt->start_cycle = DWT->CYCCNT; + __DSB(); + __ISB(); +} + +static inline void dwt_timer_end_measurement(dwt_timer_t *dt) +{ + if (!dt->measuring) { + return; + } + + dt->end_cycle = DWT->CYCCNT; + + // handles one overflow + uint32_t elapsed_cycle = dt->end_cycle - dt->start_cycle; + + dt->total_cycles += elapsed_cycle; //- STATIC_CYCLE_COST; + dt->total_samples++; + + dt->measuring = false; + + dt->max_cycles = max_u32(dt->max_cycles, elapsed_cycle); + __DSB(); +} + +static inline void dwt_timer_reset(dwt_timer_t *dt) +{ + dwt_timer_end_measurement(dt); + + dt->start_cycle = 0; + dt->end_cycle = 0; + dt->measuring = false; + dt->total_cycles = 0; + dt->total_samples = 0; +} + +static inline void dwt_timer_print_info(dwt_timer_t *dt) +{ + LOGOMATIC("AVG: %f\n", dwt_timer_average_cycles(dt)); + LOGOMATIC("Total Cycles: %lu\n", dt->total_cycles); + LOGOMATIC("Total Samples: %lu\n", dt->total_samples); + LOGOMATIC("Max Cycle: %lu\n", dt->max_cycles); +} + +// testing +extern void profiler_test(); + +/*extern dwt_timer_t GLOBAL_DWT_TIMER; + +//static number of cycles is 30 +static inline void global_dwt_timer_start_measurement(void) { + GLOBAL_DWT_TIMER.measuring = true; + GLOBAL_DWT_TIMER.start_cycle = DWT->CYCCNT; +} + +static inline void global_dwt_timer_end_measurement(void) { + if (!GLOBAL_DWT_TIMER.measuring) { + return; + } + + GLOBAL_DWT_TIMER.end_cycle = DWT->CYCCNT; + + //handles one overflow + uint32_t elapsed_cycle = GLOBAL_DWT_TIMER.end_cycle - GLOBAL_DWT_TIMER.start_cycle; + GLOBAL_DWT_TIMER.total_cycles += elapsed_cycle; + GLOBAL_DWT_TIMER.total_samples++; + + GLOBAL_DWT_TIMER.measuring = false; + + GLOBAL_DWT_TIMER.max_cycles = MAX(GLOBAL_DWT_TIMER.max_cycles, elapsed_cycle); + //GLOBAL_DWT_TIMER.min_cycles; +} +static inline float global_dwt_timer_average_cycles() { + return (GLOBAL_DWT_TIMER.total_cycles)/((float) GLOBAL_DWT_TIMER.total_samples); + +}*/ + +// extern volatile uint32_t PROFILE_AVG_RX_CYCLES; +// extern volatile uint32_t PROFILE_RX_SAMPLES; +// extern volatile uint32_t ELAPSED_CYCLES; +// extern volatile float AVG; + +/*#define START_COUNT \ + do { \ + DWT->CYCCNT = 0; \ + DWT->CTRL |= DWT_CTRL_CYCCNTENA_Msk; \ + } while (); + +#define END_COUNT +#define PROFILER_STOP (DWT->CTRL &= ~DWT_CTRL_CYCCNTENA_Msk;) +*/ + +#endif diff --git a/H523xx_CAN_TESTING/README.md b/H523xx_CAN_TESTING/README.md new file mode 100644 index 000000000..c347af3e2 --- /dev/null +++ b/H523xx_CAN_TESTING/README.md @@ -0,0 +1,5 @@ +# STM32H523xx CAN +STM32H523xx + +Plug in the board following ST-LINK pinout +Compile and flash H523xx_CAN_TESTING.elf diff --git a/Lib/FancyLayers-RENAME/GRCAN/Inc/GRCAN_FancyLayer.h b/Lib/FancyLayers-RENAME/GRCAN/Inc/GRCAN_FancyLayer.h index 2974cc3c9..97597a5ad 100644 --- a/Lib/FancyLayers-RENAME/GRCAN/Inc/GRCAN_FancyLayer.h +++ b/Lib/FancyLayers-RENAME/GRCAN/Inc/GRCAN_FancyLayer.h @@ -9,6 +9,7 @@ #include "can.h" #include "can_cfg.h" #include "grcan_utils.h" +#include "main.h" #ifndef GRCAN_FANCYLAYER_H #define GRCAN_FANCYLAYER_H @@ -27,5 +28,6 @@ uint32_t GRCAN_Fancy_EncodeID(GRCAN_Fancy_ID *id); void GRCAN_Fancy_DecodeID(GRCAN_Fancy_ID *id, uint32_t rawID); bool GRCAN_Fancy_Send(GRCAN_BUS_ID bus, GRCAN_NODE_ID destNode, GRCAN_MSG_ID messageID, void *data, uint32_t size); +bool GRCAN_Raw_Send(GRCAN_BUS_ID bus, uint32_t rawID, void *data, uint32_t size); #endif diff --git a/Lib/FancyLayers-RENAME/GRCAN/Inc/grcan_utils.h b/Lib/FancyLayers-RENAME/GRCAN/Inc/grcan_utils.h index c469dedae..95d0b00ce 100644 --- a/Lib/FancyLayers-RENAME/GRCAN/Inc/grcan_utils.h +++ b/Lib/FancyLayers-RENAME/GRCAN/Inc/grcan_utils.h @@ -11,6 +11,7 @@ #ifndef GRCAN_UTILS_H #define GRCAN_UTILS_H +#define GRCAN_BUS_DATA_SUBNET ((GRCAN_BUS_ID)4) // could be source of error typedef enum { GRCAN_MODE_CLASSIC, GRCAN_MODE_FD @@ -31,8 +32,16 @@ typedef enum { } GRCAN_FrameFormat; typedef enum { +#if defined(STM32G4) || defined(STM32L4) || defined(STM32U5) GRCAN_CLKSRC_PCLK1, GRCAN_CLKSRC_PLL, +#endif + +#if defined(STM32H5) + GRCAN_CLKSRC_PLL1Q, + GRCAN_CLKSRC_PLL2Q, +#endif + GRCAN_CLKSRC_HSE } GRCAN_ClockSource; diff --git a/Lib/FancyLayers-RENAME/GRCAN/Src/grcan_fancylayer.c b/Lib/FancyLayers-RENAME/GRCAN/Src/grcan_fancylayer.c index 4cc460bfa..6baf51965 100644 --- a/Lib/FancyLayers-RENAME/GRCAN/Src/grcan_fancylayer.c +++ b/Lib/FancyLayers-RENAME/GRCAN/Src/grcan_fancylayer.c @@ -11,6 +11,7 @@ static CANHandle *grcan_primary = NULL; static CANHandle *grcan_data = NULL; static CANHandle *grcan_testing = NULL; static CANHandle *grcan_charging = NULL; +static CANHandle *grcan_data_subnet = NULL; // typedef struct { // FDCAN_HandleTypeDef *hal_fdcanP; @@ -42,7 +43,7 @@ bool GRCAN_ValidateBusConfig(GRCAN_BusConfig *bus_config) CANHandle *GRCAN_GetHandle(GRCAN_BUS_ID bus) { - switch (bus) { + switch ((int)bus) { case GRCAN_BUS_PRIMARY: return grcan_primary; case GRCAN_BUS_DATA: @@ -51,6 +52,9 @@ CANHandle *GRCAN_GetHandle(GRCAN_BUS_ID bus) return grcan_testing; case GRCAN_BUS_CHARGER: return grcan_charging; + case GRCAN_BUS_DATA_SUBNET: // Subnet bus, ghost bus for SAMM boards (4) + LOGOMATIC("GRCAN_GetHandle: returning handle for subnet bus\n"); + return grcan_data_subnet; default: return NULL; } @@ -123,11 +127,6 @@ bool GRCAN_InitBus(GRCAN_BusConfig *bus_config) return false; } - if (!GRCAN_ValidateBusConfig(bus_config)) { - LOGOMATIC("GRCAN_InitBus: invalid config for bus %d\n", bus_config->bus); - return false; - } - enable_port_clock(bus_config->rx_pin.port); enable_port_clock(bus_config->tx_pin.port); @@ -174,24 +173,53 @@ bool GRCAN_InitBus(GRCAN_BusConfig *bus_config) cfg.init_tx_gpio.Speed = GPIO_SPEED_FREQ_VERY_HIGH; cfg.init_tx_gpio.Alternate = bus_config->tx_pin.alternate_function; - switch (bus_config->bus) { + switch ((int)bus_config->bus) { case GRCAN_BUS_PRIMARY: + if (grcan_primary != NULL) { + LOGOMATIC("GRCAN_InitBus: primary bus already initialized\n"); + return false; + } slot = &grcan_primary; break; case GRCAN_BUS_DATA: + if (grcan_data != NULL) { + LOGOMATIC("GRCAN_InitBus: data bus already initialized\n"); + return false; + } slot = &grcan_data; break; case GRCAN_BUS_TESTING: + if (grcan_testing != NULL) { + LOGOMATIC("GRCAN_InitBus: testing bus already initialized\n"); + return false; + } slot = &grcan_testing; break; case GRCAN_BUS_CHARGER: + if (grcan_charging != NULL) { + LOGOMATIC("GRCAN_InitBus: charging bus already initialized\n"); + return false; + } slot = &grcan_charging; break; + case GRCAN_BUS_DATA_SUBNET: + if (grcan_data_subnet != NULL) { + LOGOMATIC("GRCAN_InitBus: subnet bus already initialized\n"); + return false; + } + LOGOMATIC("GRCAN_InitBus: initializing subnet bus\n"); + slot = &grcan_data_subnet; + break; default: LOGOMATIC("GRCAN_InitBus: invalid bus %d\n", bus_config->bus); return false; } + if (!GRCAN_ValidateBusConfig(bus_config)) { + LOGOMATIC("GRCAN_InitBus: invalid config for bus %d\n", bus_config->bus); + return false; + } + handle = can_init(&cfg); if (handle == NULL) { LOGOMATIC("\nGRCAN_InitBus: can_init failed for bus %d\n", bus_config->bus); @@ -243,7 +271,7 @@ bool GRCAN_DeactivateBus(GRCAN_BUS_ID bus) deactivate_port_clock(rx); deactivate_port_clock(tx); - switch (bus) { + switch ((int)bus) { case GRCAN_BUS_PRIMARY: grcan_primary = NULL; break; @@ -256,6 +284,10 @@ bool GRCAN_DeactivateBus(GRCAN_BUS_ID bus) case GRCAN_BUS_CHARGER: grcan_charging = NULL; break; + case GRCAN_BUS_DATA_SUBNET: + LOGOMATIC("GRCAN_DeactivateBus: deactivating subnet bus\n"); + grcan_data_subnet = NULL; + break; default: LOGOMATIC("GRCAN_DeactivateBus: invalid bus %d\n", bus); return false; @@ -378,8 +410,8 @@ bool GRCAN_Raw_Send(GRCAN_BUS_ID bus, uint32_t rawID, void *data, uint32_t size) memcpy(msg.data, data, size); } - if (can_send(handle, &msg) != 0) { - LOGOMATIC("GRCAN_Raw_Send: can_send failed on bus %d\n", bus); + if (can_enqueue(handle, &msg) != 0) { + LOGOMATIC("GRCAN_Raw_Send: can_enqueue failed on bus %d\n", bus); return false; } diff --git a/Lib/FancyLayers-RENAME/GRCAN/Src/grcan_utils.c b/Lib/FancyLayers-RENAME/GRCAN/Src/grcan_utils.c index e1fea0096..1b9ee24cd 100644 --- a/Lib/FancyLayers-RENAME/GRCAN/Src/grcan_utils.c +++ b/Lib/FancyLayers-RENAME/GRCAN/Src/grcan_utils.c @@ -9,7 +9,7 @@ GRCAN_BusMode GRCAN_BusModeForBus(GRCAN_BUS_ID bus) { - switch (bus) { + switch ((int)bus) { case GRCAN_BUS_PRIMARY: return GRCAN_MODE_FD; case GRCAN_BUS_TESTING: @@ -18,6 +18,9 @@ GRCAN_BusMode GRCAN_BusModeForBus(GRCAN_BUS_ID bus) return GRCAN_MODE_CLASSIC; case GRCAN_BUS_CHARGER: return GRCAN_MODE_CLASSIC; // update later + case GRCAN_BUS_DATA_SUBNET: + LOGOMATIC("GRCAN_BusModeForBus: returning bus mode for subnet bus\n"); + return GRCAN_MODE_FD; default: LOGOMATIC("GRCAN_BusModeForBus: unknown bus %d\n", bus); return GRCAN_MODE_CLASSIC; @@ -26,17 +29,43 @@ GRCAN_BusMode GRCAN_BusModeForBus(GRCAN_BUS_ID bus) uint32_t GRCAN_ToHAL_ClockSource(GRCAN_ClockSource src) { +#if defined(STM32H5) + + switch (src) { + case GRCAN_CLKSRC_PLL1Q: + return LL_RCC_FDCAN_CLKSOURCE_PLL1Q; + + case GRCAN_CLKSRC_PLL2Q: + return LL_RCC_FDCAN_CLKSOURCE_PLL2Q; + + case GRCAN_CLKSRC_HSE: + return LL_RCC_FDCAN_CLKSOURCE_HSE; + + default: + LOGOMATIC("GRCAN_ToHAL_ClockSource: default source %d, defaulting to PLL2Q\n", src); + return LL_RCC_FDCAN_CLKSOURCE_PLL2Q; + } + +#elif defined(STM32G4) || defined(STM32L4) || defined(STM32U5) + switch (src) { case GRCAN_CLKSRC_PCLK1: return LL_RCC_FDCAN_CLKSOURCE_PCLK1; + case GRCAN_CLKSRC_PLL: return LL_RCC_FDCAN_CLKSOURCE_PLL; + case GRCAN_CLKSRC_HSE: return LL_RCC_FDCAN_CLKSOURCE_HSE; + default: LOGOMATIC("GRCAN_ToHAL_ClockSource: default source %d, defaulting to PCLK1\n", src); return LL_RCC_FDCAN_CLKSOURCE_PCLK1; } + +#else +#error "Unsupported STM32 Family" +#endif } uint32_t GRCAN_ToHAL_ClockDivider(GRCAN_ClockDivider div) @@ -124,6 +153,38 @@ uint32_t GRCAN_ToHAL_FeatureState(GRCAN_FeatureState state) } } +GRCAN_ClockSource GRCAN_DefaultClockSource(void) +{ +#if defined(STM32H5) + return GRCAN_CLKSRC_PLL2Q; +#elif defined(STM32G4) || defined(STM32L4) || defined(STM32U5) + return GRCAN_CLKSRC_PCLK1; +#else +#error "Unsupported STM32 Family" +#endif +} + +GRCAN_FrameFormat GRCAN_Frame_FormatForBus(GRCAN_BUS_ID bus) +{ + // This is an educate guess, the frame format for FD may change to GRCAN_FRAME_FD_BRS + switch ((int)bus) { + case GRCAN_BUS_PRIMARY: + return GRCAN_FRAME_FD_NO_BRS; + case GRCAN_BUS_TESTING: + return GRCAN_FRAME_FD_NO_BRS; + case GRCAN_BUS_DATA: + return GRCAN_FRAME_CLASSIC; + case GRCAN_BUS_CHARGER: + return GRCAN_FRAME_CLASSIC; + case GRCAN_BUS_DATA_SUBNET: + LOGOMATIC("GRCAN_Frame_FormatForBus: returning frame format for subnet bus\n"); + return GRCAN_FRAME_FD_NO_BRS; + default: + LOGOMATIC("GRCAN_Frame_FormatForBus: unknown bus %d\n", bus); + return GRCAN_FRAME_CLASSIC; + } +} + void GRCAN_SetDefaultBusConfig(GRCAN_BusConfig *busCfg, GRCAN_BUS_ID bus) { if (busCfg == NULL) { @@ -131,15 +192,15 @@ void GRCAN_SetDefaultBusConfig(GRCAN_BusConfig *busCfg, GRCAN_BUS_ID bus) return; } - busCfg->fdcan_instance = FDCAN2; - memset(busCfg, 0, sizeof(*busCfg)); + busCfg->fdcan_instance = FDCAN2; + busCfg->bus = bus; - busCfg->clock_source = GRCAN_CLKSRC_PCLK1; + busCfg->clock_source = GRCAN_DefaultClockSource(); busCfg->clock_divider = GRCAN_CLK_DIV1; - busCfg->frame_format = GRCAN_FRAME_FD_NO_BRS; + busCfg->frame_format = GRCAN_Frame_FormatForBus(bus); busCfg->operating_mode = GRCAN_OPMODE_NORMAL; busCfg->auto_retransmission = GRCAN_Feature_ENABLE; diff --git a/Lib/FancyLayers-RENAME/GRCAN/grcan_fancylayer.cmake b/Lib/FancyLayers-RENAME/GRCAN/grcan_fancylayer.cmake index eb82067ff..85373f2f7 100644 --- a/Lib/FancyLayers-RENAME/GRCAN/grcan_fancylayer.cmake +++ b/Lib/FancyLayers-RENAME/GRCAN/grcan_fancylayer.cmake @@ -23,10 +23,7 @@ target_link_libraries( GLOBALSHARE_LIB CANfigurator CircularBuffer_Lib - PERIPHERAL_CAN_LIB - #GR_OLD_CAN_MESSAGES - STM32_HAL_LL_G4xx - #GRCAN_LIB #maybe add back + PERIPHERAL_TIMEDCAN_LIB ) if(CMAKE_PRESET_NAME STREQUAL "HOOTLTest") diff --git a/Lib/Peripherals/CAN/Inc/STM32H5_hal_fdcan_defines.h b/Lib/Peripherals/CAN/Inc/STM32H5_hal_fdcan_defines.h new file mode 100644 index 000000000..062570e0a --- /dev/null +++ b/Lib/Peripherals/CAN/Inc/STM32H5_hal_fdcan_defines.h @@ -0,0 +1,61 @@ +#ifndef STM32H5_HAL_FDCAN_DEFINES_H +#define STM32H5_HAL_FDCAN_DEFINES_H + +#ifdef HAL_FDCAN_MODULE_ENABLED + +/* Private typedef -----------------------------------------------------------*/ +/* Private define ------------------------------------------------------------*/ +/** @addtogroup FDCAN_Private_Constants + * @{ + */ +#define FDCAN_TIMEOUT_VALUE 10U + +#define FDCAN_TX_EVENT_FIFO_MASK (FDCAN_IR_TEFL | FDCAN_IR_TEFF | FDCAN_IR_TEFN) +#define FDCAN_RX_FIFO0_MASK (FDCAN_IR_RF0L | FDCAN_IR_RF0F | FDCAN_IR_RF0N) +#define FDCAN_RX_FIFO1_MASK (FDCAN_IR_RF1L | FDCAN_IR_RF1F | FDCAN_IR_RF1N) +#define FDCAN_ERROR_MASK (FDCAN_IR_ELO | FDCAN_IR_WDI | FDCAN_IR_PEA | FDCAN_IR_PED | FDCAN_IR_ARA) +#define FDCAN_ERROR_STATUS_MASK (FDCAN_IR_EP | FDCAN_IR_EW | FDCAN_IR_BO) + +#define FDCAN_ELEMENT_MASK_STDID ((uint32_t)0x1FFC0000U) /* Standard Identifier */ +#define FDCAN_ELEMENT_MASK_EXTID ((uint32_t)0x1FFFFFFFU) /* Extended Identifier */ +#define FDCAN_ELEMENT_MASK_RTR ((uint32_t)0x20000000U) /* Remote Transmission Request */ +#define FDCAN_ELEMENT_MASK_XTD ((uint32_t)0x40000000U) /* Extended Identifier */ +#define FDCAN_ELEMENT_MASK_ESI ((uint32_t)0x80000000U) /* Error State Indicator */ +#define FDCAN_ELEMENT_MASK_TS ((uint32_t)0x0000FFFFU) /* Timestamp */ +#define FDCAN_ELEMENT_MASK_DLC ((uint32_t)0x000F0000U) /* Data Length Code */ +#define FDCAN_ELEMENT_MASK_BRS ((uint32_t)0x00100000U) /* Bit Rate Switch */ +#define FDCAN_ELEMENT_MASK_FDF ((uint32_t)0x00200000U) /* FD Format */ +#define FDCAN_ELEMENT_MASK_EFC ((uint32_t)0x00800000U) /* Event FIFO Control */ +#define FDCAN_ELEMENT_MASK_MM ((uint32_t)0xFF000000U) /* Message Marker */ +#define FDCAN_ELEMENT_MASK_FIDX ((uint32_t)0x7F000000U) /* Filter Index */ +#define FDCAN_ELEMENT_MASK_ANMF ((uint32_t)0x80000000U) /* Accepted Non-matching Frame */ +#define FDCAN_ELEMENT_MASK_ET ((uint32_t)0x00C00000U) /* Event type */ + +#define SRAMCAN_FLS_NBR (28U) /* Max. Filter List Standard Number */ +#define SRAMCAN_FLE_NBR (8U) /* Max. Filter List Extended Number */ +#define SRAMCAN_RF0_NBR (3U) /* RX FIFO 0 Elements Number */ +#define SRAMCAN_RF1_NBR (3U) /* RX FIFO 1 Elements Number */ +#define SRAMCAN_TEF_NBR (3U) /* TX Event FIFO Elements Number */ +#define SRAMCAN_TFQ_NBR (3U) /* TX FIFO/Queue Elements Number */ + +#define SRAMCAN_FLS_SIZE (1U * 4U) /* Filter Standard Element Size in bytes */ +#define SRAMCAN_FLE_SIZE (2U * 4U) /* Filter Extended Element Size in bytes */ +#define SRAMCAN_RF0_SIZE (18U * 4U) /* RX FIFO 0 Elements Size in bytes */ +#define SRAMCAN_RF1_SIZE (18U * 4U) /* RX FIFO 1 Elements Size in bytes */ +#define SRAMCAN_TEF_SIZE (2U * 4U) /* TX Event FIFO Elements Size in bytes */ +#define SRAMCAN_TFQ_SIZE (18U * 4U) /* TX FIFO/Queue Elements Size in bytes */ + +#define SRAMCAN_FLSSA ((uint32_t)0) /* Filter List Standard Start Address */ +#define SRAMCAN_FLESA ((uint32_t)(SRAMCAN_FLSSA + (SRAMCAN_FLS_NBR * SRAMCAN_FLS_SIZE))) /* Filter List Extended Start Address */ +#define SRAMCAN_RF0SA ((uint32_t)(SRAMCAN_FLESA + (SRAMCAN_FLE_NBR * SRAMCAN_FLE_SIZE))) /* Rx FIFO 0 Start Address */ +#define SRAMCAN_RF1SA ((uint32_t)(SRAMCAN_RF0SA + (SRAMCAN_RF0_NBR * SRAMCAN_RF0_SIZE))) /* Rx FIFO 1 Start Address */ +#define SRAMCAN_TEFSA ((uint32_t)(SRAMCAN_RF1SA + (SRAMCAN_RF1_NBR * SRAMCAN_RF1_SIZE))) /* Tx Event FIFO Start Address */ +#define SRAMCAN_TFQSA ((uint32_t)(SRAMCAN_TEFSA + (SRAMCAN_TEF_NBR * SRAMCAN_TEF_SIZE))) /* Tx FIFO/Queue Start Address */ +#define SRAMCAN_SIZE ((uint32_t)(SRAMCAN_TFQSA + (SRAMCAN_TFQ_NBR * SRAMCAN_TFQ_SIZE))) /* Message RAM size */ + +/** + * @} + */ +#endif + +#endif diff --git a/Lib/Peripherals/CAN/Inc/can.h b/Lib/Peripherals/CAN/Inc/can.h index 9b6efbeb9..90cde968e 100644 --- a/Lib/Peripherals/CAN/Inc/can.h +++ b/Lib/Peripherals/CAN/Inc/can.h @@ -3,8 +3,10 @@ // Supported STM32 Families #ifdef STM32G4 +#elif defined(STM32H5) #elif defined(STM32L4) #elif defined(STM32U5) +#else #error "Unsupported STM32 Family" #endif @@ -13,6 +15,10 @@ // #include "circularBuffer.h" #include +#if defined(STM32H523xx) && defined(USECAN3) +#error "STM32H523xx supports only FDCAN1/FDCAN2. Remove USECAN3." +#endif + // RX Callback must perform a deep copy of the data // typedef void (*CAN_RXCallback)(uint32_t ID, void *data, uint32_t size); @@ -88,7 +94,9 @@ CANHandle *can_init(const CANConfig *config); // user must supply an rx callback CAN_STATUS can_start(CANHandle *handle); CAN_STATUS can_stop(CANHandle *handle); CAN_STATUS can_send(CANHandle *handle, FDCANTxMessage *buffer); + CAN_STATUS can_release(CANHandle *handle); // deinit circular buffer and turn off can peripheral and gpios + CAN_STATUS can_add_filter(CANHandle *handle, FDCAN_FilterTypeDef *filter); // pass in a buffer to store the status string @@ -106,6 +114,8 @@ CAN_STATUS can_add_filter(CANHandle *handle, FDCAN_FilterTypeDef *filter); __HAL_RCC_GPIOB_CLK_ENABLE(); \ else if (GPIOX == GPIOD) \ __HAL_RCC_GPIOD_CLK_ENABLE(); \ + else if (GPIOX == GPIOE) \ + __HAL_RCC_GPIOE_CLK_ENABLE(); \ else \ LOGOMATIC("BAD FDCAN GPIO Port"); \ } while (0) @@ -118,6 +128,8 @@ CAN_STATUS can_add_filter(CANHandle *handle, FDCAN_FilterTypeDef *filter); __HAL_RCC_GPIOB_CLK_DISABLE(); \ else if (GPIOX == GPIOD) \ __HAL_RCC_GPIOD_CLK_DISABLE(); \ + else if (GPIOX == GPIOE) \ + __HAL_RCC_GPIOE_CLK_DISABLE(); \ else \ LOGOMATIC("BAD FDCAN GPIO Port"); \ } while (0) @@ -133,6 +145,8 @@ void can_set_clksource(uint32_t clksource); // ex. LL_RCC_FDCAN_CLKSOURCE_PCLK1 // default Configuration helpers int get_cfg(FDCAN_GlobalTypeDef *instance, CAN_RXCallback callback, CANConfig *out_cfg, uint32_t FDCAN_Mode, uint32_t numStdFilters, uint32_t numExtFilters); +void set_default_can_clksource(); + // converts CAN FD TxHeader DataLength Field static const uint8_t CANFD_DLCtoBytes[] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 12, 16, 20, 24, 32, 48, 64}; diff --git a/Lib/Peripherals/CAN/Inc/can_platform_deps.h b/Lib/Peripherals/CAN/Inc/can_platform_deps.h index 3958adbc9..2f8ff3c9d 100644 --- a/Lib/Peripherals/CAN/Inc/can_platform_deps.h +++ b/Lib/Peripherals/CAN/Inc/can_platform_deps.h @@ -9,6 +9,15 @@ #include "stm32g4xx_hal_rcc.h" #include "stm32g4xx_ll_gpio.h" #include "stm32g4xx_ll_rcc.h" +#elif defined(STM32H5) +#include "stm32h5xx_hal.h" +#include "stm32h5xx_hal_fdcan.h" +#include "stm32h5xx_hal_gpio.h" +#include "stm32h5xx_hal_gpio_ex.h" +#include "stm32h5xx_hal_rcc.h" +#include "stm32h5xx_hal_rcc_ex.h" +#include "stm32h5xx_ll_gpio.h" +#include "stm32h5xx_ll_rcc.h" // #elif defined(STM32L4) // #elif defined(STM32U5) #else diff --git a/Lib/Peripherals/CAN/Src/can.c b/Lib/Peripherals/CAN/Src/can.c index 8c6d2d2a8..dcbf82f50 100644 --- a/Lib/Peripherals/CAN/Src/can.c +++ b/Lib/Peripherals/CAN/Src/can.c @@ -5,12 +5,18 @@ #include #include +#ifdef STM32G4 +#include "STM32G4_hal_fdcan_defines.h" #include "stm32g4xx_ll_bus.h" #include "stm32g4xx_ll_dma.h" +#elif defined(STM32H5) +#include "STM32H5_hal_fdcan_defines.h" +#include "stm32h5xx_ll_bus.h" +#include "stm32h5xx_ll_dma.h" +#endif // TODO: make the profiler cleaner #include "Logomatic.h" -#include "STM32G4_hal_fdcan_defines.h" #include "profile.h" // TODO: define DMA usage in a better way @@ -172,6 +178,30 @@ CANHandle *can_init(const CANConfig *config) } #endif +#elif defined(STM32H523xx) +#ifdef USECAN1 + if (config->fdcan_instance == FDCAN1) { + if (CAN1.init) { + LOGOMATIC("CAN: CAN1 is already initialized\n"); + return CAN_SUCCESS; + } else { + canHandle = &CAN1; + canHandle->tx_capacity = TX_BUFFER_1_SIZE; + } + } +#endif +#ifdef USECAN2 + if (config->fdcan_instance == FDCAN2) { + if (CAN2.init) { + LOGOMATIC("CAN: CAN2 is already initialized\n"); + return CAN_SUCCESS; + } else { + canHandle = &CAN2; + canHandle->tx_capacity = TX_BUFFER_2_SIZE; + } + } +#endif + #endif // #elif defined(STM32L476xx) @@ -755,6 +785,17 @@ static CAN_STATUS can_get_irqs(FDCAN_GlobalTypeDef *instance, IRQn_Type *it0, IR *it1 = FDCAN1_IT1_IRQn; return CAN_SUCCESS; } +#elif defined(STM32H523xx) + if (instance == FDCAN1) { + *it0 = FDCAN1_IT0_IRQn; + *it1 = FDCAN1_IT1_IRQn; + return CAN_SUCCESS; + } + if (instance == FDCAN2) { + *it0 = FDCAN2_IT0_IRQn; + *it1 = FDCAN2_IT1_IRQn; + return CAN_SUCCESS; + } #endif LOGOMATIC("can_get_irqs: could not obtain irq #s\n"); @@ -779,6 +820,17 @@ static CANHandle *can_get_handle(FDCAN_HandleTypeDef *hfdcan) return &CAN3; } #endif +#elif defined(STM32H5) +#ifdef USECAN1 + if (hfdcan->Instance == FDCAN1) { + return &CAN1; + } +#endif +#ifdef USECAN2 + if (hfdcan->Instance == FDCAN2) { + return &CAN2; + } +#endif #endif LOGOMATIC("CAN_get_handle: was given invalid FDCAN instance\n"); @@ -810,6 +862,17 @@ static CAN_STATUS validate_can_handle(CANHandle *canHandle) return CAN_SUCCESS; } #endif +#elif defined(STM32H5) +#ifdef USECAN1 + if (canHandle == &CAN1) { + return CAN_SUCCESS; + } +#endif +#ifdef USECAN2 + if (canHandle == &CAN2) { + return CAN_SUCCESS; + } +#endif #endif LOGOMATIC("can.c: invalid can handle\n"); @@ -939,7 +1002,6 @@ static void FDCAN_InstanceDeInit(FDCAN_HandleTypeDef *hfdcan) static const char *can_get_instance_name(FDCAN_GlobalTypeDef *instance) { #ifdef STM32G474xx - if (instance == FDCAN1) { return "FDCAN1"; } else if (instance == FDCAN2) { @@ -951,6 +1013,12 @@ static const char *can_get_instance_name(FDCAN_GlobalTypeDef *instance) if (instance == FDCAN1) { return "FDCAN1"; } +#elif defined(STM32H523xx) + if (instance == FDCAN1) { + return "FDCAN1"; + } else if (instance == FDCAN2) { + return "FDCAN2"; + } #endif return "UNKNOWN"; } @@ -983,6 +1051,7 @@ void FDCAN2_IT1_IRQHandler(void) #endif } +#ifdef STM32G4 void FDCAN3_IT0_IRQHandler(void) { #ifdef USECAN3 @@ -995,3 +1064,5 @@ void FDCAN3_IT1_IRQHandler(void) HAL_FDCAN_IRQHandler(&hal_fdcan3); #endif } + +#endif diff --git a/Lib/Peripherals/CAN/Src/can_cfg_helpers.c b/Lib/Peripherals/CAN/Src/can_cfg_helpers.c index 308ed6d3a..900bab5f4 100644 --- a/Lib/Peripherals/CAN/Src/can_cfg_helpers.c +++ b/Lib/Peripherals/CAN/Src/can_cfg_helpers.c @@ -18,12 +18,27 @@ static can_cfg_helper defaultSTM32G431x8_CANCfg; static can_cfg_helper defaultSTM32G474xE_CANCfg; #endif +#ifdef STM32H523xx +static can_cfg_helper defaultSTM32H523xx_CANCfg; +#endif + +void set_default_can_clksource() +{ +#ifdef STM32G4 + can_set_clksource(LL_RCC_FDCAN_CLKSOURCE_PCLK1); +#elif defined(STM32H5) + can_set_clksource(LL_RCC_FDCAN_CLKSOURCE_PLL1Q); +#endif +} + int get_cfg(FDCAN_GlobalTypeDef *instance, CAN_RXCallback callback, CANConfig *out_cfg, uint32_t Mode, uint32_t numStdFilters, uint32_t numExtFilters) { #ifdef STM32G474xx return defaultSTM32G474xE_CANCfg(instance, callback, out_cfg, Mode, numStdFilters, numExtFilters); #elif defined(STM32G431xx) return defaultSTM32G431x8_CANCfg(instance, callback, out_cfg, Mode, numStdFilters, numExtFilters); +#elif defined(STM32H523xx) + return defaultSTM32H523xx_CANCfg(instance, callback, out_cfg, Mode, numStdFilters, numExtFilters); #elif defined(STM32L4) #error "STM32L4 is untested" #elif defined(STM32U5) @@ -192,3 +207,76 @@ CAN_STATUS defaultSTM32G431x8_CANCfg(FDCAN_GlobalTypeDef *instance, CAN_RXCallba return CAN_ERROR; } #endif + +#ifdef STM32H523xx +CAN_STATUS defaultSTM32H523xx_CANCfg(FDCAN_GlobalTypeDef *instance, CAN_RXCallback callback, CANConfig *out_cfg, uint32_t Mode, uint32_t numStdFilters, uint32_t numExtFilters) +{ + CANConfig canCfg; + + canCfg.hal_fdcan_init.ClockDivider = FDCAN_CLOCK_DIV1; + canCfg.hal_fdcan_init.FrameFormat = FDCAN_FRAME_FD_BRS; + canCfg.hal_fdcan_init.TxFifoQueueMode = FDCAN_TX_FIFO_OPERATION; + canCfg.hal_fdcan_init.Mode = Mode; + canCfg.hal_fdcan_init.AutoRetransmission = ENABLE; + canCfg.hal_fdcan_init.TransmitPause = DISABLE; + canCfg.hal_fdcan_init.ProtocolException = ENABLE; + canCfg.hal_fdcan_init.NominalPrescaler = 1; + canCfg.hal_fdcan_init.NominalSyncJumpWidth = 16; + canCfg.hal_fdcan_init.NominalTimeSeg1 = 47; // 64 MHz PLL1Q clock -> (1+47+16) = 64 tq, 1 Mbps at 75% sample point + canCfg.hal_fdcan_init.NominalTimeSeg2 = 16; + canCfg.hal_fdcan_init.DataPrescaler = 1; + canCfg.hal_fdcan_init.DataSyncJumpWidth = 16; + canCfg.hal_fdcan_init.DataTimeSeg1 = 5; // 64 MHz PLL1Q clock -> (1+5+2) = 8 tq, 8 Mbps at 75% sample point + canCfg.hal_fdcan_init.DataTimeSeg2 = 2; + canCfg.hal_fdcan_init.StdFiltersNbr = numStdFilters; + canCfg.hal_fdcan_init.ExtFiltersNbr = numExtFilters; + + canCfg.rx_callback = NULL; + canCfg.rx_interrupt_priority = 14; + canCfg.tx_interrupt_priority = 14; + + canCfg.init_rx_gpio.Mode = GPIO_MODE_AF_PP; + canCfg.init_rx_gpio.Pull = GPIO_PULLUP; + canCfg.init_rx_gpio.Speed = GPIO_SPEED_FREQ_VERY_HIGH; + + canCfg.init_tx_gpio.Mode = GPIO_MODE_AF_PP; + canCfg.init_tx_gpio.Pull = GPIO_NOPULL; + canCfg.init_tx_gpio.Speed = GPIO_SPEED_FREQ_VERY_HIGH; + + canCfg.rx_callback = callback; + +#ifdef USECAN1 + if (instance == FDCAN1) { + canCfg.fdcan_instance = FDCAN1; + canCfg.rx_gpio = GPIOA; + canCfg.init_rx_gpio.Pin = GPIO_PIN_11; + canCfg.init_rx_gpio.Alternate = GPIO_AF9_FDCAN1; + + canCfg.tx_gpio = GPIOA; + canCfg.init_tx_gpio.Pin = GPIO_PIN_12; + canCfg.init_tx_gpio.Alternate = GPIO_AF9_FDCAN1; + + *out_cfg = canCfg; + return CAN_SUCCESS; + } +#endif + +#ifdef USECAN2 + if (instance == FDCAN2) { + canCfg.fdcan_instance = FDCAN2; + canCfg.rx_gpio = GPIOA; + canCfg.init_rx_gpio.Pin = GPIO_PIN_0; + canCfg.init_rx_gpio.Alternate = GPIO_AF9_FDCAN2; + + canCfg.tx_gpio = GPIOA; + canCfg.init_tx_gpio.Pin = GPIO_PIN_10; + canCfg.init_tx_gpio.Alternate = GPIO_AF9_FDCAN2; + + *out_cfg = canCfg; + return CAN_SUCCESS; + } +#endif + + return CAN_ERROR; +} +#endif diff --git a/Lib/Peripherals/CAN/Src/can_dma.c b/Lib/Peripherals/CAN/Src/can_dma.c index 2ed89e76e..8d29a6b00 100644 --- a/Lib/Peripherals/CAN/Src/can_dma.c +++ b/Lib/Peripherals/CAN/Src/can_dma.c @@ -3,14 +3,16 @@ #include -#include "stm32g4xx_ll_bus.h" -#include "stm32g4xx_ll_dma.h" +// #include "stm32g4xx_ll_bus.h" +// #include "stm32g4xx_ll_dma.h" -// #include "can_platform_deps.h" #include "Logomatic.h" +#include "can_platform_deps.h" #ifdef STM32G4 #include "STM32G4_hal_fdcan_defines.h" +#elif defined(STM32H5) +#include "STM32H5_hal_fdcan_defines.h" #else #error "CAN with DMA not yet supported for this family" #endif diff --git a/Lib/Peripherals/CAN/Test/can_basic_test.c b/Lib/Peripherals/CAN/Test/can_basic_test.c index 9646c4ea5..700f08deb 100644 --- a/Lib/Peripherals/CAN/Test/can_basic_test.c +++ b/Lib/Peripherals/CAN/Test/can_basic_test.c @@ -143,7 +143,7 @@ int can_basic_test(void) cfg2.init_tx_gpio.Alternate = GPIO_AF9_FDCAN2; #endif - can_set_clksource(LL_RCC_FDCAN_CLKSOURCE_PCLK1); + set_default_can_clksource(); //============================================================================================= if ((primary_can = can_init(&cfg1)) == NULL) { diff --git a/Lib/Peripherals/CAN/Test/can_filter_test.c b/Lib/Peripherals/CAN/Test/can_filter_test.c index 6f749e6b8..cf4e06795 100644 --- a/Lib/Peripherals/CAN/Test/can_filter_test.c +++ b/Lib/Peripherals/CAN/Test/can_filter_test.c @@ -54,7 +54,7 @@ int can_filter_test(void) primary_can = data_can = NULL; CANConfig cfg1; - can_set_clksource(LL_RCC_FDCAN_CLKSOURCE_PCLK1); + set_default_can_clksource(); if (get_cfg(FDCAN1, can_filter_test_rx_callback, &cfg1, FDCAN_MODE_INTERNAL_LOOPBACK, 1, 0)) { LOGOMATIC("can_filter_test: FAIL, could not get config for FDCAN1\n"); diff --git a/Lib/Peripherals/CAN/Test/can_lost_rx_test.c b/Lib/Peripherals/CAN/Test/can_lost_rx_test.c index 6c85b47e4..33b37ae2a 100644 --- a/Lib/Peripherals/CAN/Test/can_lost_rx_test.c +++ b/Lib/Peripherals/CAN/Test/can_lost_rx_test.c @@ -31,7 +31,7 @@ int can_lost_rx_test(void) return ERROR; } - can_set_clksource(LL_RCC_FDCAN_CLKSOURCE_PCLK1); + set_default_can_clksource(); // TODO: Make the stress test more stressful FDCAN_TxHeaderTypeDef TxHeader = { diff --git a/Lib/Peripherals/CAN/Test/can_release_test.c b/Lib/Peripherals/CAN/Test/can_release_test.c index cb0e9d5e5..0d6652745 100644 --- a/Lib/Peripherals/CAN/Test/can_release_test.c +++ b/Lib/Peripherals/CAN/Test/can_release_test.c @@ -22,7 +22,7 @@ int can_release_test() CANHandle *can = NULL; - can_set_clksource(LL_RCC_FDCAN_CLKSOURCE_PCLK1); + set_default_can_clksource(); //============================================================================================= LOGOMATIC("can_release_test: initializing handle\n"); diff --git a/Lib/Peripherals/CAN/Test/can_stress_test.c b/Lib/Peripherals/CAN/Test/can_stress_test.c index 70c11fce0..08548e677 100644 --- a/Lib/Peripherals/CAN/Test/can_stress_test.c +++ b/Lib/Peripherals/CAN/Test/can_stress_test.c @@ -58,7 +58,7 @@ int can_stress_test(void) return ERROR; } - can_set_clksource(LL_RCC_FDCAN_CLKSOURCE_PCLK1); + set_default_can_clksource(); // TODO: Make the stress test more stressful FDCAN_TxHeaderTypeDef TxHeader = { diff --git a/Lib/Peripherals/CAN/common.cmake b/Lib/Peripherals/CAN/common.cmake index ad9709a07..118d8b6a1 100644 --- a/Lib/Peripherals/CAN/common.cmake +++ b/Lib/Peripherals/CAN/common.cmake @@ -11,7 +11,6 @@ target_sources( PERIPHERAL_CAN_LIB INTERFACE ${CMAKE_CURRENT_LIST_DIR}/Src/can.c - ${CMAKE_CURRENT_LIST_DIR}/Src/can_dma.c ${CMAKE_CURRENT_LIST_DIR}/Src/can_cfg_helpers.c ) @@ -22,7 +21,7 @@ target_include_directories( ${CMAKE_CURRENT_LIST_DIR}/Inc ) -#tests +# Tests add_library(PERIPHERAL_CAN_TEST_LIB INTERFACE) target_sources( PERIPHERAL_CAN_TEST_LIB @@ -33,8 +32,6 @@ target_sources( ${CMAKE_CURRENT_LIST_DIR}/Test/can_filter_test.c ${CMAKE_CURRENT_LIST_DIR}/Test/can_lost_rx_test.c ${CMAKE_CURRENT_LIST_DIR}/Test/profile.c - #${CMAKE_CURRENT_LIST_DIR}/Test/can.c - #${CMAKE_CURRENT_LIST_DIR}/Test/can_tests.c ) target_include_directories( PERIPHERAL_CAN_TEST_LIB @@ -42,6 +39,15 @@ target_include_directories( ${CMAKE_CURRENT_LIST_DIR}/Test ) +# CAN with DMA +add_library(PERIPHERAL_CAN_DMA INTERFACE) +target_sources( + PERIPHERAL_CAN_DMA + INTERFACE + ${CMAKE_CURRENT_LIST_DIR}/Src/can_dma.c +) +target_link_libraries(PERIPHERAL_CAN_DMA INTERFACE PERIPHERAL_CAN_LIB) + # link test to this library #if(CMAKE_BUILD_TYPE STREQUAL "Test") # Initialization diff --git a/Lib/Peripherals/TimedCAN/Inc/can.h b/Lib/Peripherals/TimedCAN/Inc/can.h index 38319c214..96847dd63 100644 --- a/Lib/Peripherals/TimedCAN/Inc/can.h +++ b/Lib/Peripherals/TimedCAN/Inc/can.h @@ -2,9 +2,7 @@ #define CAN_H // Supported STM32 Families -#ifdef STM32G4 -#elif defined(STM32L4) -#elif defined(STM32U5) +#if !defined(STM32G4) && !defined(STM32H5) #error "Unsupported STM32 Family" #endif @@ -14,6 +12,7 @@ // #include "circularBuffer.h" #include +#include #ifdef SKETCHY_OVERRIDE #include "timed_can_override.h" diff --git a/Lib/Peripherals/TimedCAN/Inc/can_platform_deps.h b/Lib/Peripherals/TimedCAN/Inc/can_platform_deps.h index 986329ac0..b92b26d37 100644 --- a/Lib/Peripherals/TimedCAN/Inc/can_platform_deps.h +++ b/Lib/Peripherals/TimedCAN/Inc/can_platform_deps.h @@ -7,10 +7,25 @@ #include "stm32g4xx_hal_gpio.h" #include "stm32g4xx_hal_gpio_ex.h" #include "stm32g4xx_hal_rcc.h" +#include "stm32g4xx_ll_bus.h" +#include "stm32g4xx_ll_dma.h" #include "stm32g4xx_ll_gpio.h" #include "stm32g4xx_ll_rcc.h" +#include "stm32g4xx_ll_tim.h" // #elif defined(STM32L4) // #elif defined(STM32U5) +#elif defined(STM32H5) +#include "stm32h5xx_hal.h" +#include "stm32h5xx_hal_fdcan.h" +#include "stm32h5xx_hal_gpio.h" +#include "stm32h5xx_hal_gpio_ex.h" +#include "stm32h5xx_hal_rcc.h" +#include "stm32h5xx_ll_bus.h" +#include "stm32h5xx_ll_dma.h" +#include "stm32h5xx_ll_gpio.h" +#include "stm32h5xx_ll_rcc.h" +#include "stm32h5xx_ll_tim.h" + #else #error "Unsupported STM32 family" #endif diff --git a/Lib/Peripherals/TimedCAN/Src/can.c b/Lib/Peripherals/TimedCAN/Src/can.c index 486b1fcf8..ea221fdf3 100644 --- a/Lib/Peripherals/TimedCAN/Src/can.c +++ b/Lib/Peripherals/TimedCAN/Src/can.c @@ -5,10 +5,6 @@ #include #include -#include "stm32g4xx_ll_bus.h" -#include "stm32g4xx_ll_dma.h" -#include "stm32g4xx_ll_tim.h" - // TODO: make the profiler cleaner #include "Logomatic.h" #include "main.h" @@ -178,6 +174,30 @@ CANHandle *can_init(const CANConfig *config) } #endif +#elif defined(STM32H523xx) +#if defined(USECAN1) + if (config->fdcan_instance == FDCAN1) { + if (CAN1.init) { + LOGOMATIC("CAN: CAN1 is already initialized\n"); + return CAN_SUCCESS; + } else { + canHandle = &CAN1; + canHandle->tx_capacity = TX_BUFFER_1_SIZE; + } + } +#endif +#if defined(USECAN2) + if (config->fdcan_instance == FDCAN2) { + if (CAN2.init) { + LOGOMATIC("CAN: CAN2 is already initialized\n"); + return CAN_SUCCESS; + } else { + canHandle = &CAN2; + canHandle->tx_capacity = TX_BUFFER_2_SIZE; + LOGOMATIC("CAN: CAN2 selected with tx capacity %lu\n", canHandle->tx_capacity); + } + } +#endif #endif // #elif defined(STM32L476xx) @@ -801,6 +821,17 @@ static CAN_STATUS can_get_irqs(FDCAN_GlobalTypeDef *instance, IRQn_Type *it0, IR *it1 = FDCAN1_IT1_IRQn; return CAN_SUCCESS; } +#elif defined(STM32H523xx) + if (instance == FDCAN1) { + *it0 = FDCAN1_IT0_IRQn; + *it1 = FDCAN1_IT1_IRQn; + return CAN_SUCCESS; + } + if (instance == FDCAN2) { + *it0 = FDCAN2_IT0_IRQn; + *it1 = FDCAN2_IT1_IRQn; + return CAN_SUCCESS; + } #endif LOGOMATIC("can_get_irqs: could not obtain irq #s\n"); @@ -825,6 +856,17 @@ static CANHandle *can_get_handle(FDCAN_HandleTypeDef *hfdcan) return &CAN3; } #endif +#elif defined(STM32H5) +#ifdef USECAN1 + if (hfdcan->Instance == FDCAN1) { + return &CAN1; + } +#endif +#ifdef USECAN2 + if (hfdcan->Instance == FDCAN2) { + return &CAN2; + } +#endif #endif LOGOMATIC("CAN_get_handle: was given invalid FDCAN instance\n"); @@ -856,6 +898,17 @@ static CAN_STATUS validate_can_handle(CANHandle *canHandle) return CAN_SUCCESS; } #endif +#elif defined(STM32H5) +#ifdef USECAN1 + if (canHandle == &CAN1) { + return CAN_SUCCESS; + } +#endif +#ifdef USECAN2 + if (canHandle == &CAN2) { + return CAN_SUCCESS; + } +#endif #endif LOGOMATIC("can.c: invalid can handle\n"); @@ -997,6 +1050,12 @@ static const char *can_get_instance_name(FDCAN_GlobalTypeDef *instance) if (instance == FDCAN1) { return "FDCAN1"; } +#elif defined(STM32H523xx) + if (instance == FDCAN1) { + return "FDCAN1"; + } else if (instance == FDCAN2) { + return "FDCAN2"; + } #endif return "UNKNOWN"; } diff --git a/Lib/Utils/Logomatic/Inc/Logomatic.h b/Lib/Utils/Logomatic/Inc/Logomatic.h index d291f296a..2b08827c4 100644 --- a/Lib/Utils/Logomatic/Inc/Logomatic.h +++ b/Lib/Utils/Logomatic/Inc/Logomatic.h @@ -8,14 +8,28 @@ #if defined(ITM) && defined(LL_GPIO_MODE_ALTERNATE) typedef enum { +#if defined(STM32G4) LOGOMATIC_PCLK1 = LL_RCC_LPUART1_CLKSOURCE_PCLK1, LOGOMATIC_SYSCLK = LL_RCC_LPUART1_CLKSOURCE_SYSCLK, +#elif defined(STM32H5) + LOGOMATIC_PCLK3 = LL_RCC_LPUART1_CLKSOURCE_PCLK3, + LOGOMATIC_PLL2Q = LL_RCC_LPUART1_CLKSOURCE_PLL2Q, + LOGOMATIC_PLL3Q = LL_RCC_LPUART1_CLKSOURCE_PLL3Q, + LOGOMATIC_CSI = LL_RCC_LPUART1_CLKSOURCE_CSI, +#else +#error "Unsupported STM32 series. Please define the appropriate clock source for LPUART1." +#endif LOGOMATIC_HSI = LL_RCC_LPUART1_CLKSOURCE_HSI, LOGOMATIC_LSE = LL_RCC_LPUART1_CLKSOURCE_LSE } LPUART_Clock_Source; - typedef enum { +#if defined(STM32G4) LOGOMATIC_BUS = LL_APB1_GRP2_PERIPH_LPUART1, +#elif defined(STM32H5) + LOGOMATIC_BUS = LL_APB3_GRP1_PERIPH_LPUART1, +#else +#error "Unsupported STM32 series. Please define the appropriate bus for LPUART1." +#endif } LPUART_Bus; typedef enum { diff --git a/Lib/Vendor/STM32_HAL_LL/STM32H5xx/Src/stm32h5xx_hal_i2s_ex.c b/Lib/Vendor/STM32_HAL_LL/STM32H5xx/Src/stm32h5xx_hal_i2s_ex.c index 99a6cc20f..660ddc4cf 100644 --- a/Lib/Vendor/STM32_HAL_LL/STM32H5xx/Src/stm32h5xx_hal_i2s_ex.c +++ b/Lib/Vendor/STM32_HAL_LL/STM32H5xx/Src/stm32h5xx_hal_i2s_ex.c @@ -19,6 +19,8 @@ ****************************************************************************** */ +typedef int make_iso_compilers_happy_by_providing_a_dummy_declaration; // Resolve compiler warnings about no symbols being defined in this file + /** ****************************************************************************** ===== I2S FULL DUPLEX FEATURE ===== diff --git a/Lib/Vendor/STM32_HAL_LL/STM32H5xx/Src/stm32h5xx_hal_pwr.c b/Lib/Vendor/STM32_HAL_LL/STM32H5xx/Src/stm32h5xx_hal_pwr.c index 8bd37e077..dcaeb5e7a 100644 --- a/Lib/Vendor/STM32_HAL_LL/STM32H5xx/Src/stm32h5xx_hal_pwr.c +++ b/Lib/Vendor/STM32_HAL_LL/STM32H5xx/Src/stm32h5xx_hal_pwr.c @@ -524,6 +524,8 @@ __weak void HAL_PWR_PVDCallback(void) */ void HAL_PWR_ConfigAttributes(uint32_t Item, uint32_t Attributes) { + UNUSED(Item); // Resolve compiler warnings on unused parameters + /* Check the parameters */ assert_param(IS_PWR_ATTRIBUTES(Attributes)); @@ -591,6 +593,8 @@ void HAL_PWR_ConfigAttributes(uint32_t Item, uint32_t Attributes) */ HAL_StatusTypeDef HAL_PWR_GetConfigAttributes(uint32_t Item, uint32_t *pAttributes) { + UNUSED(Item); // Resolve compiler warnings on unused parameters + uint32_t attributes; /* Check attribute pointer */ diff --git a/Lib/Vendor/STM32_HAL_LL/STM32H5xx/Src/stm32h5xx_hal_rcc.c b/Lib/Vendor/STM32_HAL_LL/STM32H5xx/Src/stm32h5xx_hal_rcc.c index 3cd83f66e..58893327a 100644 --- a/Lib/Vendor/STM32_HAL_LL/STM32H5xx/Src/stm32h5xx_hal_rcc.c +++ b/Lib/Vendor/STM32_HAL_LL/STM32H5xx/Src/stm32h5xx_hal_rcc.c @@ -1552,6 +1552,7 @@ __weak void HAL_RCC_CSSCallback(void) */ void HAL_RCC_ConfigAttributes(uint32_t Item, uint32_t Attributes) { + UNUSED(Item); // Resolve compiler warnings on unused parameters /* Check the parameters */ assert_param(IS_RCC_ATTRIBUTES(Attributes)); @@ -1630,6 +1631,8 @@ void HAL_RCC_ConfigAttributes(uint32_t Item, uint32_t Attributes) */ HAL_StatusTypeDef HAL_RCC_GetConfigAttributes(uint32_t Item, uint32_t *pAttributes) { + UNUSED(Item); // Resolve compiler warnings on unused parameters + uint32_t attributes; /* Check null pointer */ diff --git a/Lib/Vendor/STM32_HAL_LL/STM32H5xx/Src/stm32h5xx_ll_dac.c b/Lib/Vendor/STM32_HAL_LL/STM32H5xx/Src/stm32h5xx_ll_dac.c index 4114494c4..274222ede 100644 --- a/Lib/Vendor/STM32_HAL_LL/STM32H5xx/Src/stm32h5xx_ll_dac.c +++ b/Lib/Vendor/STM32_HAL_LL/STM32H5xx/Src/stm32h5xx_ll_dac.c @@ -122,6 +122,8 @@ */ ErrorStatus LL_DAC_DeInit(const DAC_TypeDef *DACx) { + UNUSED(DACx); // Resolve compiler warnings on unused parameters + /* Check the parameters */ assert_param(IS_DAC_ALL_INSTANCE(DACx)); diff --git a/OutboardSensors/BrakeTemp/Core/Inc/timed_can_override.h b/OutboardSensors/BrakeTemp/Core/Inc/timed_can_override.h index 89ec743eb..37704bba4 100644 --- a/OutboardSensors/BrakeTemp/Core/Inc/timed_can_override.h +++ b/OutboardSensors/BrakeTemp/Core/Inc/timed_can_override.h @@ -6,10 +6,12 @@ #undef TIM5 #undef TIM5_IRQn #undef TIM5_IRQHandler +#undef LL_APB1_GRP1_PERIPH_TIM5 #define TIM5 TIM2 #define TIM5_IRQn TIM2_IRQn #define TIM5_IRQHandler TIM2_IRQHandler +#define LL_APB1_GRP1_PERIPH_TIM5 LL_APB1_GRP1_PERIPH_TIM2 #define RCC_APB1ENR1_TIM5EN RCC_APB1ENR1_TIM2EN // FIXME After this development cycle, replace this janky workaround with a proper manner to configure the timer instance diff --git a/OutboardSensors/TireTemp/Core/Inc/timed_can_override.h b/OutboardSensors/TireTemp/Core/Inc/timed_can_override.h index 89ec743eb..37704bba4 100644 --- a/OutboardSensors/TireTemp/Core/Inc/timed_can_override.h +++ b/OutboardSensors/TireTemp/Core/Inc/timed_can_override.h @@ -6,10 +6,12 @@ #undef TIM5 #undef TIM5_IRQn #undef TIM5_IRQHandler +#undef LL_APB1_GRP1_PERIPH_TIM5 #define TIM5 TIM2 #define TIM5_IRQn TIM2_IRQn #define TIM5_IRQHandler TIM2_IRQHandler +#define LL_APB1_GRP1_PERIPH_TIM5 LL_APB1_GRP1_PERIPH_TIM2 #define RCC_APB1ENR1_TIM5EN RCC_APB1ENR1_TIM2EN // FIXME After this development cycle, replace this janky workaround with a proper manner to configure the timer instance diff --git a/SAMM/IMU/Inc/bmi323.h b/SAMM/IMU/Inc/bmi323.h new file mode 100644 index 000000000..1d36570bb --- /dev/null +++ b/SAMM/IMU/Inc/bmi323.h @@ -0,0 +1,197 @@ +#ifndef BMI323_H +#define BMI323_H + +// includes + +#include + +#include "main.h" +#include "spi.h" +#include "stm32h5xx.h" + +// BMI323 register defines + +#define BMI323_CHIP_ID 0x00 +#define BMI323_ERR_REG 0x01 +#define BMI323_STATUS 0x02 +#define BMI323_ACC_X 0x03 +#define BMI323_ACC_Y 0x04 +#define BMI323_ACC_Z 0x05 +#define BMI323_GYR_X 0x06 +#define BMI323_GYR_Y 0x07 +#define BMI323_GYR_Z 0x08 +#define BMI323_TEMP_DATA 0x09 + +#define BMI323_FEATURE_IO0 0x10 +#define BMI323_FEATURE_I01 0x11 +#define BMI323_FEATURE_IO2 0x12 +#define BMI323_FEATURE_IO3 0x13 +#define BMI323_FEATURE_IO_STATUS 0x14 + +#define BMI323_ACC_CONF 0x20 +#define BMI323_GYR_CONF 0x21 +#define BMI323_ALT_ACC_CONF 0x28 +#define BMI323_ALT_GYR_CONF 0x29 +#define BMI323_ALT_CONF 0x2A + +#define BMI323_FIFO_CONF 0x36 +#define BMI323_FIFO_CTRL 0x38 + +#define BMI323_FEATURE_CTRL 0x40 + +#define BMI323_ACC_DP_OFF_X 0x60 +#define BMI323_ACC_DP_DGAIN_X 0x61 +#define BMI323_ACC_DP_OFF_Y 0x62 +#define BMI323_ACC_DP_DGAIN_Y 0x63 +#define BMI323_ACC_DP_OFF_Z 0x64 +#define BMI323_ACC_DP_DGAIN_Z 0x65 +#define BMI323_GYR_DP_OFF_X 0x66 +#define BMI323_GYR_DP_DGAIN_X 0x67 +#define BMI323_GYR_DP_OFF_Y 0x68 +#define BMI323_GYR_DP_DGAIN_Y 0x69 +#define BMI323_GYR_DP_OFF_Z 0x6A +#define BMI323_GYR_DP_DGAIN_Z 0x6B + +#define BMI323_CMD 0x7E +#define BMI323_CFG_RES 0x7F + +// BMI323 potential spi address +#define BMI323_I2C_ADDR 0x68 +#define BMI323_I2C_ADDR_ALT 0x69 + +// BMI323 sub-defines for registers +#define BMI323_CHIP_ID_RESET_VAL 0x0043 +#define BMI323_ERR_REG_RESET_VAL 0x0000 +#define BMI323_STATUS_RESET_VAL 0x0001 +#define BMI323_ACC_X_RESET_VAL 0x8000 +#define BMI323_ACC_Y_RESET_VAL 0x8000 +#define BMI323_ACC_Z_RESET_VAL 0x8000 +#define BMI323_GYR_X_RESET_VAL 0x8000 +#define BMI323_GYR_Y_RESET_VAL 0x8000 +#define BMI323_GYR_Z_RESET_VAL 0x8000 +#define BMI323_TEMP_DATA_RESET_VAL 0x8000 + +#define BMI323_FEATURE_IO0_RESET_VAL 0x0000 +#define BMI323_FEATURE_I01_RESET_VAL 0x0000 + +#define BMI323_ACC_CONF_RESET_VAL 0x0028 +#define BMI323_GYR_CONF_RESET_VAL 0x0048 + +#define BMI323_FIFO_CONF_RESET_VAL 0x0000 +#define BMI323_FIFO_CTRL_RESET_VAL 0x0000 + +#define BMI323_ACC_DP_OFF_X_RESET_VAL 0x0000 +#define BMI323_ACC_DP_DGAIN_X_RESET_VAL 0x0000 +#define BMI323_ACC_DP_OFF_Y_RESET_VAL 0x0000 +#define BMI323_ACC_DP_DGAIN_Y_RESET_VAL 0x0000 +#define BMI323_ACC_DP_OFF_Z_RESET_VAL 0x0000 +#define BMI323_ACC_DP_DGAIN_Z_RESET_VAL 0x0000 +#define BMI323_GYR_DP_OFF_X_RESET_VAL 0x0000 +#define BMI323_GYR_DP_DGAIN_X_RESET_VAL 0x0000 +#define BMI323_GYR_DP_OFF_Y_RESET_VAL 0x0000 +#define BMI323_GYR_DP_DGAIN_Y_RESET_VAL 0x0000 +#define BMI323_GYR_DP_OFF_Z_RESET_VAL 0x0000 +#define BMI323_GYR_DP_DGAIN_Z_RESET_VAL 0x0000 + +#define BMI323_CMD_RESET_VAL 0x0000 +#define BMI323_CFG_RES_RESET_VAL 0x0000 + +// defines for commands +#define BMI323_CMD_SOFT_RESET 0xDEAF +#define BMI323_CMD_CALIB 0x0101 +#define BMI323_CMD_CALIB_ABORT 0x0200 + +// defines for features +#define BMI323_FEATURE_IO2_EN 0x012C +#define BMI323_FEATURE_IO_STS 0x0001 +#define BMI323_FEATURE_CTRL_ENGINE_EN 0x0001 +#define BMI323_FEATURE_IO1_STATUS 0x0001 + +// defines for acc and gyro conf +#define SUSPEND 0x0 +#define LOW_POWER 0x3 +#define HIGH_PERF 0x7 +#define NORMAL 0x4 + +// these are the values that are used for the polling frequency +#define ODR_0_78 0x1 +#define ODR_1_56 0x2 +#define ODR_3_12 0x3 +#define ODR_6_25 0x4 +#define ODR_12_5 0x5 +#define ODR_25 0x6 +#define ODR_50 0x7 +#define ODR_100 0x8 +#define ODR_200 0x9 +#define ODR_400 0xA +#define ODR_800 0xB +#define ODR_1600 0xC +#define ODR_3200 0xD +#define ODR_6400 0xE + +// these are the values that are used for the -3dB bandwidth +#define ODR_DIV_2 0x0 +#define ODR_DIV_4 0x1 + +// these are defines for the sample averaging +#define AVG_0 0x0 +#define AVG_2 0x1 +#define AVG_4 0x2 +#define AVG_8 0x3 +#define AVG_16 0x4 +#define AVG_32 0x5 +#define AVG_64 0x6 + +// acc specific defines for range +#define ACC_RANGE_2G 0x0 +#define ACC_RANGE_4G 0x1 +#define ACC_RANGE_8G 0x2 +#define ACC_RANGE_16G 0x3 + +// gyro specific defines for range +// WRONG VALUES +#define GYR_RANGE_2000 0x0 +#define GYR_RANGE_1000 0x1 +#define GYR_RANGE_500 0x2 +#define GYR_RANGE_250 0x3 + +#define BMI323_TIMEOUT 1000 + +typedef struct { + SPI_HandleTypeDef *spi_port; + uint16_t chip_id; + GPIO_TypeDef *port; + uint16_t pin; + /* data */ +} bmi323; + +uint8_t bmi323_init(bmi323 *bmi323_dev, SPI_HandleTypeDef *spi_port, GPIO_TypeDef *port, uint16_t pin); +uint16_t bmi323_read(bmi323 *bmi323_dev, uint8_t reg); +uint8_t bmi323_write(bmi323 *bmi323_dev, uint8_t reg, uint16_t data); +uint8_t bmi323_soft_reset(bmi323 *bmi323_dev); +uint8_t bmi323_calib(bmi323 *bmi323_dev); +uint8_t bmi323_calib_abort(bmi323 *bmi323_dev); +uint16_t bmi323_read_acc_x(bmi323 *bmi323_dev); +uint16_t bmi323_read_acc_y(bmi323 *bmi323_dev); +uint16_t bmi323_read_acc_z(bmi323 *bmi323_dev); +uint16_t bmi323_read_gyr_x(bmi323 *bmi323_dev); +uint16_t bmi323_read_gyr_y(bmi323 *bmi323_dev); +uint16_t bmi323_read_gyr_z(bmi323 *bmi323_dev); +uint16_t bmi323_read_temp_data(bmi323 *bmi323_dev); +uint16_t bmi323_read_status(bmi323 *bmi323_dev); +uint16_t bmi323_read_err_reg(bmi323 *bmi323_dev); +uint16_t bmi323_read_chip_id(bmi323 *bmi323_dev); +uint16_t bmi323_read_acc_conf(bmi323 *bmi323_dev); +uint16_t bmi323_read_gyr_conf(bmi323 *bmi323_dev); +uint16_t bmi323_read_acc_alt_conf(bmi323 *bmi323_dev); +uint16_t bmi323_read_gyr_alt_conf(bmi323 *bmi323_dev); +// uint8_t bmi323_enable_acc(bmi323 *bmi323_dev); +// uint8_t bmi323_enable_gyr(bmi323 *bmi323_dev); +uint8_t bmi323_disable_acc(bmi323 *bmi323_dev); +uint8_t bmi323_enable_gyro(bmi323 *bmi323_dev, uint8_t gyr_mode, uint8_t gyr_avg_num, uint8_t gyr_bw, uint8_t gyr_range, uint8_t gyr_odr); +uint8_t bmi323_enable_acc(bmi323 *bmi323_dev, uint8_t acc_mode, uint8_t acc_avg_num, uint8_t acc_bw, uint8_t acc_range, uint8_t acc_odr); +uint8_t bmi323_read_acc(bmi323 *bmi323_dev, int16_t *acc_data); +uint8_t bmi323_read_gyr(bmi323 *bmi323_dev, int16_t *gyr_data); +uint8_t bmi323_read_all(bmi323 *bmi323_dev, int16_t *temp_data); + +#endif // BMI323_H diff --git a/SAMM/IMU/Src/bmi323.c b/SAMM/IMU/Src/bmi323.c new file mode 100644 index 000000000..0944c22b7 --- /dev/null +++ b/SAMM/IMU/Src/bmi323.c @@ -0,0 +1,319 @@ +#include "bmi323.h" + +#include + +#include "main.h" +#include "stm32h5xx.h" +#include "stm32h5xx_hal_spi.h" + +// init spi port before calling this function +uint8_t bmi323_init(bmi323 *bmi323_dev, SPI_HandleTypeDef *spi_port, GPIO_TypeDef *port, uint16_t pin) +{ + uint8_t tx_word[4]; + uint8_t rx_word[4] = {0}; + HAL_StatusTypeDef status = 0; + + bmi323_dev->spi_port = spi_port; + bmi323_dev->port = port; + bmi323_dev->pin = pin; + + tx_word[0] = (BMI323_CHIP_ID) | 0x80; // Read register + tx_word[1] = 0x69; // Dummy byte + tx_word[2] = 0x00; // Nothing to get back chip id low byte in rx + tx_word[3] = 0x00; // Nothing to get back chip id high byte in rx + + /* + Okay so for one of these transmits we need to follow the following operation:bmi323_dev + 1. to read the register we want to: + transmit first 8 bytes, then transmit a fake 8 bytes + after we want to read 16 bytes. This should complete a single read + */ + // first we read do the dummy read to switch to spi mode + HAL_GPIO_WritePin(bmi323_dev->port, bmi323_dev->pin, GPIO_PIN_RESET); + status = HAL_SPI_TransmitReceive(bmi323_dev->spi_port, tx_word, rx_word, 4, HAL_MAX_DELAY); + HAL_GPIO_WritePin(bmi323_dev->port, bmi323_dev->pin, GPIO_PIN_SET); + + // actual reliable read of chip id + HAL_GPIO_WritePin(bmi323_dev->port, bmi323_dev->pin, GPIO_PIN_RESET); + status = HAL_SPI_TransmitReceive(bmi323_dev->spi_port, tx_word, rx_word, 4, HAL_MAX_DELAY); + HAL_GPIO_WritePin(bmi323_dev->port, bmi323_dev->pin, GPIO_PIN_SET); + + if (status != HAL_OK) { + return HAL_ERROR; + } + + if (rx_word[2] == 0x43) { + return HAL_OK; + } + return HAL_ERROR; +} + +/* +TODO: VIN DO THESE FUNCYIONS +*/ +uint16_t bmi323_read(bmi323 *bmi323_dev, uint8_t reg) +{ + uint8_t tx_word[4] = {reg | 0x80, 0, 0, 0}; // Separate into two bytes + uint8_t rx_word[4] = {0}; + + HAL_GPIO_WritePin(bmi323_dev->port, bmi323_dev->pin, GPIO_PIN_RESET); // bmi323 chip select active low + HAL_SPI_TransmitReceive(bmi323_dev->spi_port, tx_word, rx_word, 4, HAL_MAX_DELAY); + HAL_GPIO_WritePin(bmi323_dev->port, bmi323_dev->pin, GPIO_PIN_SET); // Release chip select back to high + return ((uint16_t)rx_word[3] << 8) | rx_word[2]; +} + +uint8_t bmi323_write(bmi323 *bmi323_dev, uint8_t reg, uint16_t data) +{ + uint8_t tx_word[3] = {reg, data & 0xFF, data >> 8}; // Separate into two bytes + uint8_t rx_word[3] = {0}; + + HAL_GPIO_WritePin(bmi323_dev->port, bmi323_dev->pin, GPIO_PIN_RESET); // bmi323 chip select active low + + HAL_SPI_TransmitReceive(bmi323_dev->spi_port, tx_word, rx_word, 3, HAL_MAX_DELAY); + HAL_GPIO_WritePin(bmi323_dev->port, bmi323_dev->pin, GPIO_PIN_SET); // Release chip select back to high + return 0; +} + +uint8_t bmi323_soft_reset(bmi323 *bmi323_dev) +{ + bmi323_write(bmi323_dev, BMI323_CMD, BMI323_CMD_SOFT_RESET); + return 1; +} + +/* +CALIBRATION PROCEDURE. VERY DANGEROUS. ONLY USE IF YOU KNOW WHAT YOU ARE DOING +THIS FUNCTION IS BLOCKING, CAN TAKE UP TO 3 SECONDS TO TIMEOUT +IF EVERYTHING IS DONE PROPERLY, THE FUNCTION WILL BLOCK FOR UP TO 500ms +THE FUNCTION WILL RETURN 1 IF CALIBRATION WAS SUCCESSFUL, 0 IF NOT +STEPS: +1. Disable all sensors +2. Enable the feature engine +3. Check if a calibration is already in progress +4. Check if the accelerometer is in high performance mode and the ODR is between 25 and 200 hertz +5. Start the calibration +6. Check if the calibration was successful +7. If not, reset the accelerometer and try again +8. If successful, reset the accelerometer and gyro to their original configuration +9. Done +*/ + +uint8_t bmi323_calib(bmi323 *bmi323_dev) +{ + // first we have to fucking start the feature engine + // to do that we have to disable all sensors + uint16_t acc_conf = bmi323_read(bmi323_dev, BMI323_ACC_CONF); + uint16_t gyro_conf = bmi323_read(bmi323_dev, BMI323_GYR_CONF); + uint32_t timeout_ref = 0; + if ((acc_conf & 0x7000) != 0x0000) { + bmi323_write(bmi323_dev, BMI323_ACC_CONF, BMI323_ACC_CONF_RESET_VAL); + } + if ((gyro_conf & 0x7000) != 0x0000) { + bmi323_write(bmi323_dev, BMI323_GYR_CONF, BMI323_GYR_CONF_RESET_VAL); + } + // now we need to check if the feature engine has been enabled prior + if ((bmi323_read(bmi323_dev, BMI323_FEATURE_CTRL) & 0x0001) == 0x0000) { + // then we write 0x012C to Feature Io 2 + bmi323_write(bmi323_dev, BMI323_FEATURE_IO2, BMI323_FEATURE_IO2_EN); + // then we write 0x0001 to Feature Io status + bmi323_write(bmi323_dev, BMI323_FEATURE_IO_STATUS, BMI323_FEATURE_IO_STS); + // now we set the feature ctrol engine enable to 1 + bmi323_write(bmi323_dev, BMI323_FEATURE_CTRL, BMI323_FEATURE_CTRL_ENGINE_EN); + // now we poll the feature engine + timeout_ref = MillisecondsSinceBoot(); + while ((bmi323_read(bmi323_dev, BMI323_FEATURE_I01) & 0x000F) != 0x0001) { + if (MillisecondsSinceBoot() - timeout_ref > BMI323_TIMEOUT) { + ////D_println("Feature engine enable timeout"); + return 0; + } + continue; + } + // D_println("enabled feature engine Hooray!"); + } + // no need for an else statement as the feature engine is already enabled and we can continue + // now we need to check if a calibration is already in progress + // polls the bmi323 FEATURE I01 state untill the state is 0b00, this means calibration can start. + timeout_ref = MillisecondsSinceBoot(); + while (((bmi323_read(bmi323_dev, BMI323_FEATURE_I01) & (0x1800)) >> 11) != 0x0000) { + if (MillisecondsSinceBoot() - timeout_ref > BMI323_TIMEOUT) { + ////D_println("Calibration state timeout"); + return 0; + } + continue; + } +// check the current configuration of the accelerometer and make sure it is in high performance adn +// ODR is between 25 and 200 hertz +calibrate: + // read the acc conf register + uint16_t data = bmi323_read(bmi323_dev, BMI323_ACC_CONF) & 0x700F; + // checks if we are in the correct configuration. if not skips if statement + if (((data >> 12) == HIGH_PERF) && (((data & 0x000F) >= ODR_25) && ((data & 0x000F) <= ODR_200))) { + // D_println("Starting calibration"); + // if it is, then we can start the calibration + // first we check if the alernalte configuration acc mode is set to 0: + if (((bmi323_read(bmi323_dev, BMI323_ALT_ACC_CONF) & 0x7000) >> 11) != 0x0000) { + // if it is, we set it to 0 + bmi323_write(bmi323_dev, BMI323_ALT_ACC_CONF, 0x0206); + } + // next we check if the alternate configuration gyro mode is set to 0: + if (((bmi323_read(bmi323_dev, BMI323_ALT_GYR_CONF) & 0x7000) >> 11) != 0x0000) { + // if it is, we set it to 0 + bmi323_write(bmi323_dev, BMI323_ALT_GYR_CONF, 0x0206); + } + // D_println("Alternate configurations set"); + // next we can actually send the command for calibration + // reset all of the gyro calibration values + bmi323_write(bmi323_dev, BMI323_GYR_DP_DGAIN_X, BMI323_ACC_DP_DGAIN_X_RESET_VAL); + bmi323_write(bmi323_dev, BMI323_GYR_DP_DGAIN_Y, BMI323_ACC_DP_DGAIN_Y_RESET_VAL); + bmi323_write(bmi323_dev, BMI323_GYR_DP_DGAIN_Z, BMI323_ACC_DP_DGAIN_Z_RESET_VAL); + bmi323_write(bmi323_dev, BMI323_GYR_DP_OFF_X, BMI323_ACC_DP_OFF_X_RESET_VAL); + bmi323_write(bmi323_dev, BMI323_GYR_DP_OFF_Y, BMI323_ACC_DP_OFF_Y_RESET_VAL); + bmi323_write(bmi323_dev, BMI323_GYR_DP_OFF_Z, BMI323_ACC_DP_OFF_Z_RESET_VAL); + // now we poll the state of the calibration untill we get 0b1 + // D_println("Starting calibration"); + bmi323_write(bmi323_dev, BMI323_CMD, BMI323_CMD_CALIB); + + // D_println("Polling calibration state"); + // check if the feature engine is enabled + timeout_ref = MillisecondsSinceBoot(); + while (((bmi323_read(bmi323_dev, BMI323_FEATURE_I01) & 0x0010) >> 4) != 0x0001) { + if (MillisecondsSinceBoot() - timeout_ref > BMI323_TIMEOUT) { + // D_println("Feature engine enable timeout"); + return 0; + } + continue; + } + // D_println("Calibration complete"); + if (((bmi323_read(bmi323_dev, BMI323_FEATURE_I01) & 0x0020) >> 5) == 0x0001) { + // //D_println("Calibration successful"); + // //D_println("reseting values to original configuration"); + // cycle the acc + bmi323_write(bmi323_dev, BMI323_ACC_CONF, BMI323_ACC_CONF_RESET_VAL); + bmi323_write(bmi323_dev, BMI323_ACC_CONF, acc_conf); + // cycle the gyro + bmi323_write(bmi323_dev, BMI323_GYR_CONF, BMI323_GYR_CONF_RESET_VAL); + // //D_println(gyro_conf); + bmi323_write(bmi323_dev, BMI323_GYR_CONF, gyro_conf); + // display the calibration values + // //D_println(bmi323_read(bmi323_dev, BMI323_ACC_DP_DGAIN_X), HEX); + // //D_println(bmi323_read(bmi323_dev, BMI323_ACC_DP_DGAIN_Y), HEX); + // //D_println(bmi323_read(bmi323_dev, BMI323_ACC_DP_DGAIN_Z), HEX); + // //D_println(bmi323_read(bmi323_dev, BMI323_ACC_DP_OFF_X), HEX); + // //D_println(bmi323_read(bmi323_dev, BMI323_ACC_DP_OFF_Y), HEX); + // //D_println(bmi323_read(bmi323_dev, BMI323_ACC_DP_OFF_Z), HEX); + return 1; + } else { + // //D_println("Calibration failed"); + return 0; + } + } + // //D_println("Calibration failed"); + // //D_println("reseting values trying again"); + // turns off the acc + bmi323_write(bmi323_dev, BMI323_ACC_CONF, BMI323_ACC_CONF_RESET_VAL); + // turn on the acc + bmi323_write(bmi323_dev, BMI323_ACC_CONF, BMI323_ACC_CONF_RESET_VAL | 0x7000); + // jumps to the calibration sequence + goto calibrate; // TODO: Goto are evil but we did not write this so leave it be until it breaks things because it is evil + return 1; +} + +uint8_t bmi323_calib_abort(bmi323 *bmi323_dev) +{ + bmi323_write(bmi323_dev, BMI323_CMD, BMI323_CMD_CALIB_ABORT); + return 1; +} + +/* +TODO: this todo is from last year lol +Check the status of the acc, gyro and temp before returning the values + if they are not ready return 0 + if they are ready return 1 + need to pass by reference the values to be returned + +*/ + +uint16_t bmi323_read_acc_x(bmi323 *bmi323_dev) +{ + return bmi323_read(bmi323_dev, BMI323_ACC_X); +} + +uint16_t bmi323_read_acc_y(bmi323 *bmi323_dev) +{ + return bmi323_read(bmi323_dev, BMI323_ACC_Y); +} + +uint16_t bmi323_read_acc_z(bmi323 *bmi323_dev) +{ + return bmi323_read(bmi323_dev, BMI323_ACC_Z); +} + +uint16_t bmi323_read_gyr_x(bmi323 *bmi323_dev) +{ + return bmi323_read(bmi323_dev, BMI323_GYR_X); +} + +uint16_t bmi323_read_gyr_y(bmi323 *bmi323_dev) +{ + return bmi323_read(bmi323_dev, BMI323_GYR_Y); +} + +uint16_t bmi323_read_gyr_z(bmi323 *bmi323_dev) +{ + return bmi323_read(bmi323_dev, BMI323_GYR_Z); +} + +uint16_t bmi323_read_temp_data(bmi323 *bmi323_dev) +{ + return bmi323_read(bmi323_dev, BMI323_TEMP_DATA); +} + +uint16_t bmi323_read_status(bmi323 *bmi323_dev) +{ + return bmi323_read(bmi323_dev, BMI323_STATUS); +} + +uint16_t bmi323_read_err_reg(bmi323 *bmi323_dev) +{ + return bmi323_read(bmi323_dev, BMI323_ERR_REG); +} + +uint16_t bmi323_read_chip_id(bmi323 *bmi323_dev) +{ + return bmi323_read(bmi323_dev, BMI323_CHIP_ID); +} + +uint16_t bmi323_read_acc_conf(bmi323 *bmi323_dev) +{ + return bmi323_read(bmi323_dev, BMI323_ACC_CONF); +} + +uint16_t bmi323_read_gyr_conf(bmi323 *bmi323_dev) +{ + return bmi323_read(bmi323_dev, BMI323_GYR_CONF); +} + +uint8_t bmi323_enable_acc(bmi323 *bmi323_dev, uint8_t acc_mode, uint8_t acc_avg_num, uint8_t acc_bw, uint8_t acc_range, uint8_t acc_odr) +{ + // uint16_t acc_conf = bmi323_read_acc_conf(bmi323_dev); + uint16_t new_conf = 0; + new_conf |= acc_mode << 12; + new_conf |= acc_avg_num << 8; + new_conf |= acc_bw << 7; + new_conf |= acc_range << 4; + new_conf |= acc_odr; + bmi323_write(bmi323_dev, BMI323_ACC_CONF, new_conf); + return 1; +} + +uint8_t bmi323_enable_gyro(bmi323 *bmi323_dev, uint8_t gyr_mode, uint8_t gyr_avg_num, uint8_t gyr_bw, uint8_t gyr_range, uint8_t gyr_odr) +{ + // uint16_t acc_conf = bmi323_read_acc_conf(bmi323_dev); + uint16_t new_conf = 0; + new_conf |= gyr_mode << 12; + new_conf |= gyr_avg_num << 8; + new_conf |= gyr_bw << 7; + new_conf |= gyr_range << 4; + new_conf |= gyr_odr; + bmi323_write(bmi323_dev, BMI323_GYR_CONF, new_conf); + return 1; +} diff --git a/SAMM/IMU/imu.cmake b/SAMM/IMU/imu.cmake new file mode 100644 index 000000000..b0719dc1a --- /dev/null +++ b/SAMM/IMU/imu.cmake @@ -0,0 +1,5 @@ +add_library(SAMM_IMU_Lib INTERFACE) + +target_include_directories(SAMM_IMU_Lib INTERFACE ${CMAKE_CURRENT_LIST_DIR}/Inc) + +target_sources(SAMM_IMU_Lib INTERFACE ${CMAKE_CURRENT_LIST_DIR}/Src/bmi323.c) diff --git a/SAMM/InboardFloor/CMakeLists.txt b/SAMM/InboardFloor/CMakeLists.txt new file mode 100644 index 000000000..82547e47f --- /dev/null +++ b/SAMM/InboardFloor/CMakeLists.txt @@ -0,0 +1,58 @@ +cmake_minimum_required(VERSION 3.25) + +# Setup compiler settings +set(CMAKE_C_STANDARD 11) +set(CMAKE_C_STANDARD_REQUIRED ON) +set(CMAKE_C_EXTENSIONS ON) + +# Define the build type +if(NOT CMAKE_BUILD_TYPE) + set(CMAKE_BUILD_TYPE "Debug") +endif() + +# what, does in fact not get the filename of somthing but rather the name of the project from the path +get_filename_component(GR_PROJECT_NAME ${CMAKE_CURRENT_SOURCE_DIR} NAME) + +# Enable CMake support for ASM and C languages +enable_language( + C + ASM +) + +# Core project settings +project(${CMAKE_PROJECT_NAME}) + +add_library(${GR_PROJECT_NAME}_USER_CODE INTERFACE) +target_sources( + ${GR_PROJECT_NAME}_USER_CODE + INTERFACE + # Core + Src/crc.c + Src/dma.c + Src/gpio.c + Src/i2c.c + Src/main.c + Src/spi.c + Src/stm32h5xx_it.c + Src/platform.c + Src/VL53L4ED_api.c + Src/VL53L4ED_calibration.c + Src/can_inboardfloor.c +) + +target_link_libraries( + ${GR_PROJECT_NAME}_USER_CODE + INTERFACE + CANfigurator + PERIPHERAL_TIMEDCAN_LIB + BitManipulations_Lib + SAMM_IMU_Lib + GRCAN_FANCYLAYER +) + +target_include_directories( + ${GR_PROJECT_NAME}_USER_CODE + INTERFACE + Inc + GRCAN +) diff --git a/SAMM/InboardFloor/GRCAN/NodeID.h b/SAMM/InboardFloor/GRCAN/NodeID.h new file mode 100644 index 000000000..8713be57c --- /dev/null +++ b/SAMM/InboardFloor/GRCAN/NodeID.h @@ -0,0 +1,16 @@ +#include "GRCAN_NODE_ID.h" +#include "Stringification.h" + +#ifndef NODE_ID_H +#define NODE_ID_H + +#ifndef NODE +#pragma message("NODE is not defined. Please compile Inboard Floor for a specific target. Defaulting to FL.") +#define LOCAL_GR_ID GRCAN_InboardFloor_FL +#else +#define LOCAL_GR_ID CONCAT(GRCAN_InboardFloor_, NODE) +#endif + +#pragma message "Compiling Inboard Floor node as " STRINGIFY_MACRO(LOCAL_GR_ID) + +#endif diff --git a/SAMM/InboardFloor/Inc/VL53L4ED_api.h b/SAMM/InboardFloor/Inc/VL53L4ED_api.h new file mode 100644 index 000000000..e5d7acf2b --- /dev/null +++ b/SAMM/InboardFloor/Inc/VL53L4ED_api.h @@ -0,0 +1,373 @@ +/** + * + * Copyright (c) 2023 STMicroelectronics. + * All rights reserved. + * + * This software is licensed under terms that can be found in the LICENSE file + * in the root directory of this software component. + * If no LICENSE file comes with this software, it is provided AS-IS. + * + ****************************************************************************** + */ + +#ifndef VL53L4ED_API_H_ +#define VL53L4ED_API_H_ + +#include "platform.h" + +/** + * @brief Driver version + */ + +#define VL53L4ED_IMPLEMENTATION_VER_MAJOR 1 +#define VL53L4ED_IMPLEMENTATION_VER_MINOR 1 +#define VL53L4ED_IMPLEMENTATION_VER_BUILD 2 +#define VL53L4ED_IMPLEMENTATION_VER_REVISION 0 + +/** + * @brief Driver error type + */ + +typedef uint8_t VL53L4ED_Error; + +#define VL53L4ED_ERROR_NONE ((uint8_t)0U) +#define VL53L4ED_ERROR_XTALK_FAILED ((uint8_t)253U) +#define VL53L4ED_ERROR_INVALID_ARGUMENT ((uint8_t)254U) +#define VL53L4ED_ERROR_TIMEOUT ((uint8_t)255U) + +/** + * @brief Inner Macro for API. Not for user, only for development. + */ + +#define VL53L4ED_SOFT_RESET ((uint16_t)0x0000)) +#define VL53L4ED_I2C_SLAVE__DEVICE_ADDRESS ((uint16_t)0x0001) +#define VL53L4ED_VHV_CONFIG__TIMEOUT_MACROP_LOOP_BOUND ((uint16_t)0x0008) +#define VL53L4ED_XTALK_PLANE_OFFSET_KCPS ((uint16_t)0x0016) +#define VL53L4ED_XTALK_X_PLANE_GRADIENT_KCPS ((uint16_t)0x0018) +#define VL53L4ED_XTALK_Y_PLANE_GRADIENT_KCPS ((uint16_t)0x001A) +#define VL53L4ED_RANGE_OFFSET_MM ((uint16_t)0x001E) +#define VL53L4ED_INNER_OFFSET_MM ((uint16_t)0x0020) +#define VL53L4ED_OUTER_OFFSET_MM ((uint16_t)0x0022) +#define VL53L4ED_GPIO_HV_MUX__CTRL ((uint16_t)0x0030) +#define VL53L4ED_GPIO__TIO_HV_STATUS ((uint16_t)0x0031) +#define VL53L4ED_SYSTEM__INTERRUPT ((uint16_t)0x0046) +#define VL53L4ED_RANGE_CONFIG_A ((uint16_t)0x005E) +#define VL53L4ED_RANGE_CONFIG_B ((uint16_t)0x0061) +#define VL53L4ED_RANGE_CONFIG__SIGMA_THRESH ((uint16_t)0x0064) +#define VL53L4ED_MIN_COUNT_RATE_RTN_LIMIT_MCPS ((uint16_t)0x0066) +#define VL53L4ED_INTERMEASUREMENT_MS ((uint16_t)0x006C) +#define VL53L4ED_THRESH_HIGH ((uint16_t)0x0072) +#define VL53L4ED_THRESH_LOW ((uint16_t)0x0074) +#define VL53L4ED_SYSTEM__INTERRUPT_CLEAR ((uint16_t)0x0086) +#define VL53L4ED_SYSTEM_START ((uint16_t)0x0087) +#define VL53L4ED_RESULT__RANGE_STATUS ((uint16_t)0x0089) +#define VL53L4ED_RESULT__SPAD_NB ((uint16_t)0x008C) +#define VL53L4ED_RESULT__SIGNAL_RATE ((uint16_t)0x008E) +#define VL53L4ED_RESULT__AMBIENT_RATE ((uint16_t)0x0090) +#define VL53L4ED_RESULT__SIGMA ((uint16_t)0x0092) +#define VL53L4ED_RESULT__DISTANCE ((uint16_t)0x0096) + +#define VL53L4ED_RESULT__OSC_CALIBRATE_VAL ((uint16_t)0x00DE) +#define VL53L4ED_FIRMWARE__SYSTEM_STATUS ((uint16_t)0x00E5) +#define VL53L4ED_IDENTIFICATION__MODEL_ID ((uint16_t)0x010F) + +/** + * @brief defines Software Version + */ + +typedef struct { + uint8_t major; /*!< major number */ + uint8_t minor; /*!< minor number */ + uint8_t build; /*!< build number */ + uint32_t revision; /*!< revision number */ +} VL53L4ED_Version_t; + +/** + * @brief Packed reading results type + */ + +typedef struct { + + /* Status of measurements. If the status is equal to 0, the data are valid*/ + uint8_t range_status; + /* Measured distance in millimeters */ + uint16_t distance_mm; + /* Ambient noise in kcps */ + uint16_t ambient_rate_kcps; + /* Ambient noise in kcps/SPAD */ + uint16_t ambient_per_spad_kcps; + /* Measured signal of the target in kcps */ + uint16_t signal_rate_kcps; + /* Measured signal of the target in kcps/SPAD */ + uint16_t signal_per_spad_kcps; + /* Number of SPADs enabled */ + uint16_t number_of_spad; + /* Estimated measurements std deviation in mm */ + uint16_t sigma_mm; +} VL53L4ED_ResultsData_t; + +/** + * @brief This function programs the software driver version. + * @param (VL53L4ED_Version_t) pVersion : Pointer of structure, containing the + * software version. + * @return (VL53L4ED_ERROR) status : 0 if SW version is OK. + */ + +VL53L4ED_Error VL53L4ED_GetSWVersion(VL53L4ED_Version_t *pVersion); + +/** + * @brief This function sets a new I2C address to a sensor. It can be used for + * example when multiple sensors share the same I2C bus. + * @param (Dev_t) dev : Device instance to update. + * @param (uint8_t) new_address : New I2C address. + * @return (VL53L4ED_ERROR) status : 0 if I2C address has been correctly + * programmed. + */ + +VL53L4ED_Error VL53L4ED_SetI2CAddress(Dev_t dev, uint8_t new_address); + +/** + * @brief This function is used to get the sensor id of VL53L4ED. The sensor id + * should be 0xEBAA. + * @param (Dev_t) dev : Device instance. + * @param (uint16_t) *p_id : Sensor id. + * @return (VL53L4ED_ERROR) status : 0 if OK. + */ + +VL53L4ED_Error VL53L4ED_GetSensorId(Dev_t dev, uint16_t *p_id); + +/** + * @brief This function is used to initialize the sensor. + * @param (Dev_t) dev : Device instance to initialize. + * @return (VL53L4ED_ERROR) status : 0 if init is OK. + */ + +VL53L4ED_Error VL53L4ED_SensorInit(Dev_t dev); + +/** + * @brief This function clears the interrupt. It needs to be called after a + * ranging data reading to arm the interrupt for the next data ready event. + * @param (Dev_t) dev : Device instance. + * @return (VL53L4ED_ERROR) status : 0 if OK. + */ + +VL53L4ED_Error VL53L4ED_ClearInterrupt(Dev_t dev); + +/** + * @brief This function starts a ranging session. The ranging operation is + * continuous. The clear interrupt has to be done after each get data to allow + * the interrupt to raise when the next data is ready. + * @param (Dev_t) dev : instance of selected VL53L4ED sensor. + * @return (VL53L4ED_ERROR) status : 0 if OK. + */ + +VL53L4ED_Error VL53L4ED_StartRanging(Dev_t dev); + +/** + * @brief This function stops the ranging in progress. + * @param (Dev_t) dev : instance of selected VL53L4ED sensor. + * @return (VL53L4ED_ERROR) status : 0 if OK. + */ + +VL53L4ED_Error VL53L4ED_StopRanging(Dev_t dev); + +/** + * @brief This function check if a new data is available by polling a dedicated + * register. + * @param (Dev_t) dev : instance of selected VL53L4ED sensor. + * @param (uint8_t) *p_is_data_ready : Pointer containing a flag to know if a + * data is ready : 0 = no data ready, 1 = data ready. + * @return (VL53L4ED_ERROR) status : 0 if OK. + */ + +VL53L4ED_Error VL53L4ED_CheckForDataReady(Dev_t dev, uint8_t *p_is_data_ready); + +/** + * @brief This function sets new range timing. Timing are composed of + * TimingBudget and InterMeasurement. TimingBudget represents the timing during + * VCSEL enabled, and InterMeasurement the time between two measurements. + * The sensor can have different ranging mode depending of the configuration, + * please refer to the user manual for more information. + * @param (Dev_t) dev : instance of selected VL53L4ED sensor. + * @param (uint32_t) timing_budget_ms : New timing budget in ms. Value can be + * between 10ms and 200ms. Default is 50ms. + * @param (uint32_t) inter_measurement_ms : New inter-measurement in ms. If the + * value is equal to 0, the ranging period is defined by the timing budget. + * Otherwise, inter-measurement must be > timing budget. When all the timing + * budget is consumed, the device goes in low power mode until inter-measurement + * is done. + * @return (uint8_t) status : 0 if OK. + */ + +VL53L4ED_Error VL53L4ED_SetRangeTiming(Dev_t dev, uint32_t timing_budget_ms, uint32_t inter_measurement_ms); + +/** + * @brief This function gets the current range timing. Timing are composed of + * TimingBudget and InterMeasurement. TimingBudget represents the timing during + * VCSEL enabled, and InterMeasurement the time between two measurements. + * The sensor can have different ranging mode depending of the configuration, + * please refer to the user manual for more information. + * @param (Dev_t) dev : instance of selected VL53L4ED sensor. + * @param (uint32_t) *p_timing_budget_ms : Pointer containing the current + * timing budget in ms. + * @param (uint32_t) *p_inter_measurement_ms : Pointer containing the current + * inter-measurement in ms. + * @return (uint8_t) status : 0 if OK. + */ + +VL53L4ED_Error VL53L4ED_GetRangeTiming(Dev_t dev, uint32_t *p_timing_budget_ms, uint32_t *p_inter_measurement_ms); + +/** + * @brief This function gets the results reported by the sensor. + * @param (Dev_t) dev : instance of selected VL53L4ED sensor. + * @param (VL53L4ED_ResultsData_t) *pResult : Pointer of structure, filled with the + * ranging results. + * @return (uint8_t) status : 0 if OK. + */ + +VL53L4ED_Error VL53L4ED_GetResult(Dev_t dev, VL53L4ED_ResultsData_t *pResult); + +/** + * @brief This function sets a new offset correction in mm. Offset corresponds + * to the difference in millimeters between real distance and measured distance. + * @param (Dev_t) dev : instance of selected VL53L4ED sensor. + * @param (int16_t) OffsetValueInMm : Offset value in millimeters. The minimum + * value is -1024mm and maximum is 1023mm. + * @return (uint8_t) status : 0 if OK. + */ + +VL53L4ED_Error VL53L4ED_SetOffset(Dev_t dev, int16_t OffsetValueInMm); + +/** + * @brief This function gets the current offset correction in mm. Offset + * corresponds to the difference in millimeters between real distance and + * measured distance. + * @param (Dev_t) dev : instance of selected VL53L4ED sensor. + * @param (int16_t) OffsetValueInMm : Offset value in millimeters. The minimum + * value is -1024mm and maximum is 1023mm. + * @return (uint8_t) status : 0 if OK. + */ + +VL53L4ED_Error VL53L4ED_GetOffset(Dev_t dev, int16_t *Offset); + +/** + * @brief This function sets a new Xtalk value in kcps. Xtalk represents the + * correction to apply to the sensor when a protective coverglass is placed + * at the top of the sensor. + * @param (Dev_t) dev : instance of selected VL53L4ED sensor. + * @param (uint16_t) XtalkValueKcps : New xtalk value in kcps. The default + * value is 0 kcps (no coverglass). Minimum is 0 kcps , and maximum is 128 + * kcps. + * @return (VL53L4ED_ERROR) status : 0 if OK. + */ + +VL53L4ED_Error VL53L4ED_SetXtalk(Dev_t dev, uint16_t XtalkValueKcps); + +/** + * @brief This function gets the current Xtalk value in kcps. Xtalk represents + * the correction to apply to the sensor when a protective coverglass is placed + * at the top of the sensor. + * @param (Dev_t) dev : instance of selected VL53L4ED sensor. + * @param (uint16_t) p_xtalk_kcps : Pointer of current xtalk value in kcps. + * @return (VL53L4ED_ERROR) status : 0 if OK. + */ + +VL53L4ED_Error VL53L4ED_GetXtalk(Dev_t dev, uint16_t *p_xtalk_kcps); + +/** + * @brief This function sets new detection thresholds. The detection + * thresholds can be programmed to generate an interrupt on pin 7 (GPIO1), only + * when a condition on distance is reach. Example: + * VL53L4ED_SetDistanceThreshold(dev,100,300,0): Below 100 mm + * VL53L4ED_SetDistanceThreshold(dev,100,300,1): Above 300 mm + * VL53L4ED_SetDistanceThreshold(dev,100,300,2): Below 100mm or above 300mm + * VL53L4ED_SetDistanceThreshold(dev,100,300,3): Above 100mm or below 300mm + * @param (Dev_t) dev : instance of selected VL53L4ED sensor. + * @param (uint16_t) distance_low_mm : Low distance threshold in millimeters. + * @param (uint16_t) distance_high_mm : High distance threshold in millimeters. + * @param (uint8_t) window : Interrupt windows (0=below low threshold; + * 1=above high threshold; 2=out of low/high windows; 3=in low/high windows) + * @return (VL53L4ED_ERROR) status : 0 if OK. + */ + +VL53L4ED_Error VL53L4ED_SetDetectionThresholds(Dev_t dev, uint16_t distance_low_mm, uint16_t distance_high_mm, uint8_t window); + +/** + * @brief This function gets the current detection thresholds. The detection + * thresholds can be programmed to generate an interrupt on pin 7 (GPIO1), only + * when a condition on distance is reach. + * @param (Dev_t) dev : instance of selected VL53L4ED sensor. + * @param (uint16_t) *p_distance_low_mm : Pointer of low distance threshold in + * millimeters. + * @param (uint16_t) *p_distance_high_mm : Pointer of high distance threshold in + * millimeters. + * @param (uint8_t) *p_window : Interrupt windows (0=below low threshold; + * 1=above high threshold; 2=out of low/high windows; 3=in low/high windows) + * @return (VL53L4ED_ERROR) status : 0 if OK. + */ + +VL53L4ED_Error VL53L4ED_GetDetectionThresholds(Dev_t dev, uint16_t *p_distance_low_mm, uint16_t *p_distance_high_mm, uint8_t *p_window); + +/** + * @brief This function sets a new signal threshold in kcps. If a + * target has a lower signal as the programmed value, the result status in + * structure 'VL53L4ED_ResultsData_t' will be equal to 2. + * @param (Dev_t) dev : instance of selected VL53L4ED sensor. + * @param (uint16_t) signal_kcps : New signal threshold in kcps. The default + * value is 1024 kcps. Minimum is 0 kcps (no threshold), and maximum is 16384 + * kcps. + * @return (VL53L4ED_ERROR) status : 0 if OK. + */ + +VL53L4ED_Error VL53L4ED_SetSignalThreshold(Dev_t dev, uint16_t signal_kcps); + +/** + * @brief This function returns the current signal threshold in kcps. If a + * target has a lower signal as the programmed value, the result status in + * structure 'VL53L4ED_ResultsData_t' will be equal to 2. + * @param (Dev_t) dev : instance of selected VL53L4ED sensor. + * @param (uint16_t) *p_signal_kcps : Pointer of signal threshold in kcps. + * @return (VL53L4ED_ERROR) status : 0 if OK. + */ + +VL53L4ED_Error VL53L4ED_GetSignalThreshold(Dev_t dev, uint16_t *p_signal_kcps); + +/** + * @brief This function programs a new sigma threshold. The sigma corresponds to + * the standard deviation of the returned pulse. If the computed sigma is above + * the programmed value, the result status in structure 'VL53L4ED_ResultsData_t' + * will be equal to 1. + * @param (Dev_t) dev : instance of selected VL53L4ED sensor. + * @param (uint16_t) sigma_mm : New sigma threshold in mm. The default value is + * 15mm. Minimum is 0mm (not threshold), and maximum is 16383mm. + * @return (VL53L4ED_ERROR) status : 0 if programming is or 255 if value is too + * high. + */ + +VL53L4ED_Error VL53L4ED_SetSigmaThreshold(Dev_t dev, uint16_t sigma_mm); + +/** + * @brief This function gets the current sigma threshold. The sigma corresponds + * to the standard deviation of the returned pulse. If the computed sigma is + * above the programmed value, the result status in structure + * 'VL53L4ED_ResultsData_t' will be equal to 1. + * @param (Dev_t) dev : instance of selected VL53L4ED sensor. + * @param (uint16_t) *p_sigma_mm : Current sigma threshold in mm. + * @return (VL53L4ED_ERROR) status : 0 if programming is OK. + */ + +VL53L4ED_Error VL53L4ED_GetSigmaThreshold(Dev_t dev, uint16_t *p_sigma_mm); + +/** + * @brief This function can be called when the temperature might have changed by + * more than 8 degrees Celsius. The function can only be used if the sensor is + * not ranging, otherwise, the ranging needs to be stopped using function + * 'VL53L4ED_StopRanging()'. After calling this function, the ranging can + * restart normally. + * @param (Dev_t) dev : instance of selected VL53L4ED sensor. + * @return (VL53L4ED_ERROR) status : 0 if update is OK. + */ + +VL53L4ED_Error VL53L4ED_StartTemperatureUpdate(Dev_t dev); + +#endif // VL53L4ED_API_H_ diff --git a/SAMM/InboardFloor/Inc/VL53L4ED_calibration.h b/SAMM/InboardFloor/Inc/VL53L4ED_calibration.h new file mode 100644 index 000000000..97daa1d3c --- /dev/null +++ b/SAMM/InboardFloor/Inc/VL53L4ED_calibration.h @@ -0,0 +1,64 @@ +/** + * + * Copyright (c) 2023 STMicroelectronics. + * All rights reserved. + * + * This software is licensed under terms that can be found in the LICENSE file + * in the root directory of this software component. + * If no LICENSE file comes with this software, it is provided AS-IS. + * + ****************************************************************************** + */ + +/** + * @file vl53l4ed_calibration.h + * @brief Calibration Functions definition + */ + +#ifndef VL53L4ED_CALIBRATION_H_ +#define VL53L4ED_CALIBRATION_H_ + +#include "platform.h" + +/** + * @brief This function can be used to perform an offset calibration. Offset + * corresponds to the difference in millimeters between real distance and + * measured distance. ST recommend to perform offset at 100m, on a grey17% + * reflective target, but any other distance and reflectance can be used. + * The function returns the offset value found and programs the offset + * compensation into the device. + * @param (Dev_t) dev : instance of selected VL53L4ED sensor. + * @param (int16_t) TargetDistInMm : Real distance between the sensor and the + * target in millimeters. ST recommend 100mm. Min distance is 10mm and max is + * 1000mm. + * @param (int16_t) nb_samples : Number of samples (between 5 and 255). A higher + * number of samples increases the accuracy, but it also takes more time. ST + * recommend to use at least 10 samples. + * @return (VL53L4ED_ERROR) status : 0 if OK, or 255 if something occurred (e.g + * invalid nb of samples). + */ + +VL53L4ED_Error VL53L4ED_CalibrateOffset(Dev_t dev, int16_t TargetDistInMm, int16_t *p_measured_offset_mm, int16_t nb_samples); + +/** + * @brief This function can be used to perform a Xtalk calibration. Xtalk + * represents the correction to apply to the sensor when a protective coverglass + * is placed at the top of the sensor. The distance for calibration depends of + * the coverglass, it needs to be characterized. Please refer to the User Manual + * for more information. + * The function returns the Xtalk value found and programs the Xtalk + * compensation into the device. + * @param (Dev_t) dev : instance of selected VL53L4ED sensor. + * @param uint16_t) TargetDistInMm : Real distance between the sensor and the + * target in millimeters. This distance needs to be characterized, as described + * into the User Manual. + * @param (int16_t) nb_samples : Number of samples (between 5 and 255). A higher + * number of samples increases the accuracy, but it also takes more time. ST + * recommend to use at least 10 samples. + * @return (VL53L4ED_ERROR) status : 0 if OK, or 255 if something occurred (e.g + * invalid nb of samples). + */ + +VL53L4ED_Error VL53L4ED_CalibrateXtalk(Dev_t dev, int16_t TargetDistInMm, uint16_t *p_measured_xtalk_kcps, int16_t nb_samples); + +#endif // VL53L4ED_CALIBRATION_H_ diff --git a/SAMM/InboardFloor/Inc/can_cfg.h b/SAMM/InboardFloor/Inc/can_cfg.h new file mode 100644 index 000000000..6e9142a57 --- /dev/null +++ b/SAMM/InboardFloor/Inc/can_cfg.h @@ -0,0 +1,12 @@ +#ifndef CAN_CFG_H +#define CAN_CFG_H + +#define USECAN1 +#define TX_BUFFER_1_SIZE 16 + +#define USECAN2 +#define TX_BUFFER_2_SIZE 16 + +#define CAN_TIMER_SEND_PERIOD_US 625 + +#endif diff --git a/SAMM/InboardFloor/Inc/can_inboardfloor.h b/SAMM/InboardFloor/Inc/can_inboardfloor.h new file mode 100644 index 000000000..8c7a3aac2 --- /dev/null +++ b/SAMM/InboardFloor/Inc/can_inboardfloor.h @@ -0,0 +1,52 @@ +#ifndef CAN_SUS_H +#define CAN_SUS_H + +#include +#include + +#include "GRCAN_FancyLayer.h" +#include "Logomatic.h" +#include "NodeID.h" + +typedef enum { + BrakeTemp_FL = GRCAN_BrakeTemp_FL, + BrakeTemp_FR = GRCAN_BrakeTemp_FR, + BrakeTemp_RL = GRCAN_BrakeTemp_RL, + BrakeTemp_RR = GRCAN_BrakeTemp_RR +} BrakeTemp_Node; + +typedef enum { + InboardFloor_FL = GRCAN_InboardFloor_FL, + InboardFloor_FR = GRCAN_InboardFloor_FR, + InboardFloor_RL = GRCAN_InboardFloor_RL, + InboardFloor_RR = GRCAN_InboardFloor_RR +} InboardFloor_Node; + +typedef struct { + /* IMU Data */ + uint16_t bmi323_acc_x; + uint16_t bmi323_acc_y; + uint16_t bmi323_acc_z; + uint16_t bmi323_gyro_x; + uint16_t bmi323_gyro_y; + uint16_t bmi323_gyro_z; + uint16_t bmi323_temp; + uint16_t bmi323_status; + + /* Time of Flight Data */ + uint16_t distance_mm; + uint16_t ambient_rate_kcps; + uint16_t ambient_per_spad_kcps; + uint16_t signal_rate_kcps; + uint16_t signal_per_spad_kcps; + uint16_t number_of_spad; + uint16_t sigma_mm; + uint8_t range_status; +} IMU_ToF_Data; + +void BrakeTemp_Callback(uint32_t id, void *data, uint32_t size); +void TCM_Callback(uint32_t id, void *data, uint32_t size); +int InboardFloor_CAN_Init(GRCAN_BUS_ID busID); +bool InboardFloor_CAN_Send(GRCAN_NODE_ID dest_node, GRCAN_MSG_ID msg_id, void *data); + +#endif diff --git a/SAMM/InboardFloor/Inc/crc.h b/SAMM/InboardFloor/Inc/crc.h new file mode 100644 index 000000000..133957e92 --- /dev/null +++ b/SAMM/InboardFloor/Inc/crc.h @@ -0,0 +1,51 @@ +/* USER CODE BEGIN Header */ +/** + ****************************************************************************** + * @file crc.h + * @brief This file contains all the function prototypes for + * the crc.c file + ****************************************************************************** + * @attention + * + * Copyright (c) 2024 STMicroelectronics. + * All rights reserved. + * + * This software is licensed under terms that can be found in the LICENSE file + * in the root directory of this software component. + * If no LICENSE file comes with this software, it is provided AS-IS. + * + ****************************************************************************** + */ +/* USER CODE END Header */ +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef __CRC_H__ +#define __CRC_H__ + +#ifdef __cplusplus +extern "C" { +#endif + +/* Includes ------------------------------------------------------------------*/ +#include "main.h" + +/* USER CODE BEGIN Includes */ + +/* USER CODE END Includes */ + +extern CRC_HandleTypeDef hcrc; + +/* USER CODE BEGIN Private defines */ + +/* USER CODE END Private defines */ + +void MX_CRC_Init(void); + +/* USER CODE BEGIN Prototypes */ + +/* USER CODE END Prototypes */ + +#ifdef __cplusplus +} +#endif + +#endif /* __CRC_H__ */ diff --git a/SAMM/InboardFloor/Inc/dma.h b/SAMM/InboardFloor/Inc/dma.h new file mode 100644 index 000000000..7774831e0 --- /dev/null +++ b/SAMM/InboardFloor/Inc/dma.h @@ -0,0 +1,51 @@ +/* USER CODE BEGIN Header */ +/** + ****************************************************************************** + * @file dma.h + * @brief This file contains all the function prototypes for + * the dma.c file + ****************************************************************************** + * @attention + * + * Copyright (c) 2024 STMicroelectronics. + * All rights reserved. + * + * This software is licensed under terms that can be found in the LICENSE file + * in the root directory of this software component. + * If no LICENSE file comes with this software, it is provided AS-IS. + * + ****************************************************************************** + */ +/* USER CODE END Header */ +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef __DMA_H__ +#define __DMA_H__ + +#ifdef __cplusplus +extern "C" { +#endif + +/* Includes ------------------------------------------------------------------*/ +#include "main.h" + +/* DMA memory to memory transfer handles -------------------------------------*/ + +/* USER CODE BEGIN Includes */ + +/* USER CODE END Includes */ + +/* USER CODE BEGIN Private defines */ + +/* USER CODE END Private defines */ + +void MX_DMA_Init(void); + +/* USER CODE BEGIN Prototypes */ + +/* USER CODE END Prototypes */ + +#ifdef __cplusplus +} +#endif + +#endif /* __DMA_H__ */ diff --git a/SAMM/InboardFloor/Inc/gpio.h b/SAMM/InboardFloor/Inc/gpio.h new file mode 100644 index 000000000..843d4e9e7 --- /dev/null +++ b/SAMM/InboardFloor/Inc/gpio.h @@ -0,0 +1,48 @@ +/* USER CODE BEGIN Header */ +/** + ****************************************************************************** + * @file gpio.h + * @brief This file contains all the function prototypes for + * the gpio.c file + ****************************************************************************** + * @attention + * + * Copyright (c) 2024 STMicroelectronics. + * All rights reserved. + * + * This software is licensed under terms that can be found in the LICENSE file + * in the root directory of this software component. + * If no LICENSE file comes with this software, it is provided AS-IS. + * + ****************************************************************************** + */ +/* USER CODE END Header */ +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef __GPIO_H__ +#define __GPIO_H__ + +#ifdef __cplusplus +extern "C" { +#endif + +/* Includes ------------------------------------------------------------------*/ +#include "main.h" + +/* USER CODE BEGIN Includes */ + +/* USER CODE END Includes */ + +/* USER CODE BEGIN Private defines */ + +/* USER CODE END Private defines */ + +void MX_GPIO_Init(void); + +/* USER CODE BEGIN Prototypes */ + +/* USER CODE END Prototypes */ + +#ifdef __cplusplus +} +#endif +#endif /*__ GPIO_H__ */ diff --git a/SAMM/InboardFloor/Inc/i2c.h b/SAMM/InboardFloor/Inc/i2c.h new file mode 100644 index 000000000..64f5543e6 --- /dev/null +++ b/SAMM/InboardFloor/Inc/i2c.h @@ -0,0 +1,51 @@ +/* USER CODE BEGIN Header */ +/** + ****************************************************************************** + * @file i2c.h + * @brief This file contains all the function prototypes for + * the i2c.c file + ****************************************************************************** + * @attention + * + * Copyright (c) 2024 STMicroelectronics. + * All rights reserved. + * + * This software is licensed under terms that can be found in the LICENSE file + * in the root directory of this software component. + * If no LICENSE file comes with this software, it is provided AS-IS. + * + ****************************************************************************** + */ +/* USER CODE END Header */ +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef __I2C_H__ +#define __I2C_H__ + +#ifdef __cplusplus +extern "C" { +#endif + +/* Includes ------------------------------------------------------------------*/ +#include "main.h" + +/* USER CODE BEGIN Includes */ + +/* USER CODE END Includes */ + +extern I2C_HandleTypeDef hi2c1; + +/* USER CODE BEGIN Private defines */ + +/* USER CODE END Private defines */ + +void MX_I2C1_Init(void); + +/* USER CODE BEGIN Prototypes */ + +/* USER CODE END Prototypes */ + +#ifdef __cplusplus +} +#endif + +#endif /* __I2C_H__ */ diff --git a/SAMM/InboardFloor/Inc/main.h b/SAMM/InboardFloor/Inc/main.h new file mode 100644 index 000000000..ea2a1bcbd --- /dev/null +++ b/SAMM/InboardFloor/Inc/main.h @@ -0,0 +1,85 @@ +/* USER CODE BEGIN Header */ +/** + ****************************************************************************** + * @file : main.h + * @brief : Header for main.c file. + * This file contains the common defines of the application. + ****************************************************************************** + * @attention + * + * Copyright (c) 2024 STMicroelectronics. + * All rights reserved. + * + * This software is licensed under terms that can be found in the LICENSE file + * in the root directory of this software component. + * If no LICENSE file comes with this software, it is provided AS-IS. + * + ****************************************************************************** + */ +/* USER CODE END Header */ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef __MAIN_H +#define __MAIN_H + +#ifdef __cplusplus +extern "C" { +#endif + +/* Includes ------------------------------------------------------------------*/ +#include "stm32h5xx.h" +#include "stm32h5xx_hal.h" +#include "stm32h5xx_hal_dma.h" +#include "stm32h5xx_hal_i2c.h" +#include "stm32h5xx_hal_rcc.h" +#include "stm32h5xx_ll_bus.h" +#include "stm32h5xx_ll_cortex.h" +#include "stm32h5xx_ll_crs.h" +#include "stm32h5xx_ll_dma.h" +#include "stm32h5xx_ll_exti.h" +#include "stm32h5xx_ll_gpio.h" +#include "stm32h5xx_ll_i2c.h" +#include "stm32h5xx_ll_lpuart.h" +#include "stm32h5xx_ll_pwr.h" +#include "stm32h5xx_ll_rcc.h" +#include "stm32h5xx_ll_spi.h" +#include "stm32h5xx_ll_system.h" +#include "stm32h5xx_ll_utils.h" +/* Private includes ----------------------------------------------------------*/ +/* USER CODE BEGIN Includes */ +#include +/* USER CODE END Includes */ + +/* Exported types ------------------------------------------------------------*/ +/* USER CODE BEGIN ET */ + +/* USER CODE END ET */ + +/* Exported constants --------------------------------------------------------*/ +/* USER CODE BEGIN EC */ + +/* USER CODE END EC */ + +/* Exported macro ------------------------------------------------------------*/ +/* USER CODE BEGIN EM */ + +/* USER CODE END EM */ + +/* Exported functions prototypes ---------------------------------------------*/ +void Error_Handler(void); + +/* USER CODE BEGIN EFP */ +uint32_t MillisecondsSinceBoot(void); +/* USER CODE END EFP */ + +/* Private defines -----------------------------------------------------------*/ + +/* USER CODE BEGIN Private defines */ + +/* USER CODE END Private defines */ + +#ifdef __cplusplus +} +#endif + +#endif /* __MAIN_H */ diff --git a/SAMM/InboardFloor/Inc/platform.h b/SAMM/InboardFloor/Inc/platform.h new file mode 100644 index 000000000..9c7754970 --- /dev/null +++ b/SAMM/InboardFloor/Inc/platform.h @@ -0,0 +1,79 @@ +/** + * + * Copyright (c) 2023 STMicroelectronics. + * All rights reserved. + * + * This software is licensed under terms that can be found in the LICENSE file + * in the root directory of this software component. + * If no LICENSE file comes with this software, it is provided AS-IS. + * + ****************************************************************************** + */ + +#ifndef _PLATFORM_H_ +#define _PLATFORM_H_ +#pragma once + +#include +#include + +/** + * VL53L4ED device instance. + */ + +typedef uint16_t Dev_t; + +/** + * @brief Error instance. + */ +typedef uint8_t VL53L4ED_Error; + +/** + * @brief If the macro below is defined, the device will be programmed to run + * with I2C Fast Mode Plus (up to 1MHz). Otherwise, default max value is 400kHz. + */ + +// #define VL53L4ED_I2C_FAST_MODE_PLUS + +/** + * @brief Read 32 bits through I2C. + */ + +uint8_t VL53L4ED_RdDWord(Dev_t dev, uint16_t registerAddr, uint32_t *value); +/** + * @brief Read 16 bits through I2C. + */ + +uint8_t VL53L4ED_RdWord(Dev_t dev, uint16_t registerAddr, uint16_t *value); + +/** + * @brief Read 8 bits through I2C. + */ + +uint8_t VL53L4ED_RdByte(Dev_t dev, uint16_t registerAddr, uint8_t *value); + +/** + * @brief Write 8 bits through I2C. + */ + +uint8_t VL53L4ED_WrByte(Dev_t dev, uint16_t registerAddr, uint8_t value); + +/** + * @brief Write 16 bits through I2C. + */ + +uint8_t VL53L4ED_WrWord(Dev_t dev, uint16_t RegisterAdress, uint16_t value); + +/** + * @brief Write 32 bits through I2C. + */ + +uint8_t VL53L4ED_WrDWord(Dev_t dev, uint16_t RegisterAdress, uint32_t value); + +/** + * @brief Wait during N milliseconds. + */ + +uint8_t VL53L4ED_WaitMs(Dev_t dev, uint32_t TimeMs); + +#endif // _PLATFORM_H_ \ No newline at end of file diff --git a/SAMM/InboardFloor/Inc/spi.h b/SAMM/InboardFloor/Inc/spi.h new file mode 100644 index 000000000..795f9dd81 --- /dev/null +++ b/SAMM/InboardFloor/Inc/spi.h @@ -0,0 +1,51 @@ +/* USER CODE BEGIN Header */ +/** + ****************************************************************************** + * @file spi.h + * @brief This file contains all the function prototypes for + * the spi.c file + ****************************************************************************** + * @attention + * + * Copyright (c) 2024 STMicroelectronics. + * All rights reserved. + * + * This software is licensed under terms that can be found in the LICENSE file + * in the root directory of this software component. + * If no LICENSE file comes with this software, it is provided AS-IS. + * + ****************************************************************************** + */ +/* USER CODE END Header */ +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef __SPI_H__ +#define __SPI_H__ + +#ifdef __cplusplus +extern "C" { +#endif + +/* Includes ------------------------------------------------------------------*/ +#include "main.h" + +/* USER CODE BEGIN Includes */ + +/* USER CODE END Includes */ + +extern SPI_HandleTypeDef hspi1; + +/* USER CODE BEGIN Private defines */ + +/* USER CODE END Private defines */ + +void MX_SPI1_Init(void); + +/* USER CODE BEGIN Prototypes */ + +/* USER CODE END Prototypes */ + +#ifdef __cplusplus +} +#endif + +#endif /* __SPI_H__ */ diff --git a/SAMM/InboardFloor/Inc/stm32h5xx_hal_conf.h b/SAMM/InboardFloor/Inc/stm32h5xx_hal_conf.h new file mode 100644 index 000000000..c27ed6a0d --- /dev/null +++ b/SAMM/InboardFloor/Inc/stm32h5xx_hal_conf.h @@ -0,0 +1,395 @@ +/* USER CODE BEGIN Header */ +/** + ****************************************************************************** + * @file stm32h5xx_hal_conf.h + * @author MCD Application Team + * @brief HAL configuration file + ****************************************************************************** + * @attention + * + * Copyright (c) 2019 STMicroelectronics. + * All rights reserved. + * + * This software is licensed under terms that can be found in the LICENSE file + * in the root directory of this software component. + * If no LICENSE file comes with this software, it is provided AS-IS. + * + ****************************************************************************** + */ +/* USER CODE END Header */ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef STM32H5xx_HAL_CONF_H +#define STM32H5xx_HAL_CONF_H + +#ifdef __cplusplus +extern "C" { +#endif + +/* Exported types ------------------------------------------------------------*/ +/* Exported constants --------------------------------------------------------*/ + +/* ########################## Module Selection ############################## */ +/** + * @brief This is the list of modules to be used in the HAL driver + */ + +#define HAL_MODULE_ENABLED + +/*#define HAL_ADC_MODULE_ENABLED */ +/*#define HAL_COMP_MODULE_ENABLED */ +/*#define HAL_CORDIC_MODULE_ENABLED */ +#define HAL_CRC_MODULE_ENABLED +/*#define HAL_CRYP_MODULE_ENABLED */ +/*#define HAL_DAC_MODULE_ENABLED */ +#define HAL_FDCAN_MODULE_ENABLED +/*#define HAL_FMAC_MODULE_ENABLED */ +/*#define HAL_HRTIM_MODULE_ENABLED */ +/*#define HAL_IRDA_MODULE_ENABLED */ +/*#define HAL_IWDG_MODULE_ENABLED */ +#define HAL_I2C_MODULE_ENABLED +/*#define HAL_I2S_MODULE_ENABLED */ +/*#define HAL_LPTIM_MODULE_ENABLED */ +/*#define HAL_NAND_MODULE_ENABLED */ +/*#define HAL_NOR_MODULE_ENABLED */ +/*#define HAL_OPAMP_MODULE_ENABLED */ +/*#define HAL_PCD_MODULE_ENABLED */ +/*#define HAL_QSPI_MODULE_ENABLED */ +/*#define HAL_RNG_MODULE_ENABLED */ +/*#define HAL_RTC_MODULE_ENABLED */ +/*#define HAL_SAI_MODULE_ENABLED */ +/*#define HAL_SMARTCARD_MODULE_ENABLED */ +/*#define HAL_SMBUS_MODULE_ENABLED */ +#define HAL_SPI_MODULE_ENABLED +/*#define HAL_SRAM_MODULE_ENABLED */ +#define HAL_TIM_MODULE_ENABLED +/*#define HAL_UART_MODULE_ENABLED */ +/*#define HAL_USART_MODULE_ENABLED */ +/*#define HAL_WWDG_MODULE_ENABLED */ +#define HAL_GPIO_MODULE_ENABLED +#define HAL_EXTI_MODULE_ENABLED +#define HAL_DMA_MODULE_ENABLED +#define HAL_RCC_MODULE_ENABLED +#define HAL_FLASH_MODULE_ENABLED +#define HAL_PWR_MODULE_ENABLED +#define HAL_CORTEX_MODULE_ENABLED + +/* ########################## Register Callbacks selection ############################## */ +/** + * @brief This is the list of modules where register callback can be used + */ +#define USE_HAL_ADC_REGISTER_CALLBACKS 0U +#define USE_HAL_COMP_REGISTER_CALLBACKS 0U +#define USE_HAL_CORDIC_REGISTER_CALLBACKS 0U +#define USE_HAL_CRYP_REGISTER_CALLBACKS 0U +#define USE_HAL_DAC_REGISTER_CALLBACKS 0U +#define USE_HAL_EXTI_REGISTER_CALLBACKS 0U +#define USE_HAL_FDCAN_REGISTER_CALLBACKS 0U +#define USE_HAL_FMAC_REGISTER_CALLBACKS 0U +#define USE_HAL_HRTIM_REGISTER_CALLBACKS 0U +#define USE_HAL_I2C_REGISTER_CALLBACKS 0U +#define USE_HAL_I2S_REGISTER_CALLBACKS 0U +#define USE_HAL_IRDA_REGISTER_CALLBACKS 0U +#define USE_HAL_LPTIM_REGISTER_CALLBACKS 0U +#define USE_HAL_NAND_REGISTER_CALLBACKS 0U +#define USE_HAL_NOR_REGISTER_CALLBACKS 0U +#define USE_HAL_OPAMP_REGISTER_CALLBACKS 0U +#define USE_HAL_PCD_REGISTER_CALLBACKS 0U +#define USE_HAL_QSPI_REGISTER_CALLBACKS 0U +#define USE_HAL_RNG_REGISTER_CALLBACKS 0U +#define USE_HAL_RTC_REGISTER_CALLBACKS 0U +#define USE_HAL_SAI_REGISTER_CALLBACKS 0U +#define USE_HAL_SMARTCARD_REGISTER_CALLBACKS 0U +#define USE_HAL_SMBUS_REGISTER_CALLBACKS 0U +#define USE_HAL_SPI_REGISTER_CALLBACKS 0U +#define USE_HAL_SRAM_REGISTER_CALLBACKS 0U +#define USE_HAL_TIM_REGISTER_CALLBACKS 0U +#define USE_HAL_UART_REGISTER_CALLBACKS 0U +#define USE_HAL_USART_REGISTER_CALLBACKS 0U +#define USE_HAL_WWDG_REGISTER_CALLBACKS 0U + +/* ####################################### Oscillator Values adaptation ##############################################*/ + +/** + * @brief Adjust the value of External High Speed oscillator (HSE) used in your application. + * This value is used by the RCC HAL module to compute the system frequency + * (when HSE is used as system clock source, directly or through the PLL). + */ +#if !defined(HSE_VALUE) +#define HSE_VALUE 25000000U /*!< Value of the External oscillator in Hz */ +#endif /* HSE_VALUE */ + +#if !defined(HSE_STARTUP_TIMEOUT) +#define HSE_STARTUP_TIMEOUT 100U /*!< Time out for HSE start up, in ms */ +#endif /* HSE_STARTUP_TIMEOUT */ + +/** + * @brief Internal Core Speed oscillator (CSI) default value. + * This value is the default CSI range value after Reset. + */ +#if !defined(CSI_VALUE) +#define CSI_VALUE 4000000UL /*!< Value of the Internal oscillator in Hz*/ +#endif /* CSI_VALUE */ + +/** + * @brief Internal High Speed oscillator (HSI) value. + * This value is used by the RCC HAL module to compute the system frequency + * (when HSI is used as system clock source, directly or through the PLL). + */ +#if !defined(HSI_VALUE) +#define HSI_VALUE 64000000UL /*!< Value of the Internal oscillator in Hz*/ +#endif /* HSI_VALUE */ + +/** + * @brief Internal High Speed oscillator (HSI48) value for USB FS, SDMMC and RNG. + * This internal oscillator is mainly dedicated to provide a high precision clock to + * the USB peripheral by means of a special Clock Recovery System (CRS) circuitry. + * When the CRS is not used, the HSI48 RC oscillator runs on it default frequency + * which is subject to manufacturing process variations. + */ +#if !defined(HSI48_VALUE) +#define HSI48_VALUE \ + 48000000UL /*!< Value of the Internal High Speed oscillator for USB FS/SDMMC/RNG in Hz. \ + The real value my vary depending on manufacturing process variations.*/ +#endif /* HSI48_VALUE */ + +/** + * @brief Internal Low Speed oscillator (LSI) value. + */ +#if !defined(LSI_VALUE) +#define LSI_VALUE 32000UL /*!< LSI Typical Value in Hz*/ +#endif /* LSI_VALUE */ /*!< Value of the Internal Low Speed oscillator in Hz \ + The real value may vary depending on the variations \ + in voltage and temperature.*/ + +#if !defined(LSI_STARTUP_TIME) +#define LSI_STARTUP_TIME 130UL /*!< Time out for LSI start up, in us */ +#endif /* LSI_STARTUP_TIME */ + +/** + * @brief External Low Speed oscillator (LSE) value. + * This value is used by the UART, RTC HAL module to compute the system frequency + */ +#if !defined(LSE_VALUE) +#define LSE_VALUE 32768UL /*!< Value of the External oscillator in Hz*/ +#endif /* LSE_VALUE */ + +#if !defined(LSE_STARTUP_TIMEOUT) +#define LSE_STARTUP_TIMEOUT 5000UL /*!< Time out for LSE start up, in ms */ +#endif /* LSE_STARTUP_TIMEOUT */ +/** + * @brief External clock source for SPI peripheral + * This value is used by the SPI HAL module to compute the SPI clock source + * frequency, this source is inserted directly through I2S_CKIN pad. + + */ +#if !defined(EXTERNAL_CLOCK_VALUE) +#define EXTERNAL_CLOCK_VALUE 12288000UL /*!< Value of the External clock in Hz*/ +#endif /* EXTERNAL_CLOCK_VALUE */ + +/* Tip: To avoid modifying this file each time you need to use different HSE, + === you can define the HSE value in your toolchain compiler preprocessor. */ + +/* ########################### System Configuration ######################### */ +/** + * @brief This is the HAL system configuration section + */ + +#define VDD_VALUE (3300UL) /*!< Value of VDD in mv */ +#define TICK_INT_PRIORITY (15UL) /*!< tick interrupt priority (lowest by default) */ +#define USE_RTOS 0U +#define PREFETCH_ENABLE 0U +#define INSTRUCTION_CACHE_ENABLE 1U +#define DATA_CACHE_ENABLE 1U + +/* ########################## Assert Selection ############################## */ +/** + * @brief Uncomment the line below to expanse the "assert_param" macro in the + * HAL drivers code + */ +/* #define USE_FULL_ASSERT 1U */ + +/* ################## SPI peripheral configuration ########################## */ + +/* CRC FEATURE: Use to activate CRC feature inside HAL SPI Driver + * Activated: CRC code is present inside driver + * Deactivated: CRC code cleaned from driver + */ + +#define USE_SPI_CRC 0U + +/* Includes ------------------------------------------------------------------*/ +/** + * @brief Include module's header file + */ + +#ifdef HAL_RCC_MODULE_ENABLED +#include "stm32h5xx_hal_rcc.h" +#endif /* HAL_RCC_MODULE_ENABLED */ + +#ifdef HAL_GPIO_MODULE_ENABLED +#include "stm32h5xx_hal_gpio.h" +#endif /* HAL_GPIO_MODULE_ENABLED */ + +#ifdef HAL_DMA_MODULE_ENABLED +#include "stm32h5xx_hal_dma.h" +#endif /* HAL_DMA_MODULE_ENABLED */ + +#ifdef HAL_CORTEX_MODULE_ENABLED +#include "stm32h5xx_hal_cortex.h" +#endif /* HAL_CORTEX_MODULE_ENABLED */ + +#ifdef HAL_ADC_MODULE_ENABLED +#include "stm32h5xx_hal_adc.h" +#endif /* HAL_ADC_MODULE_ENABLED */ + +#ifdef HAL_COMP_MODULE_ENABLED +#include "stm32h5xx_hal_comp.h" +#endif /* HAL_COMP_MODULE_ENABLED */ + +#ifdef HAL_CORDIC_MODULE_ENABLED +#include "stm32h5xx_hal_cordic.h" +#endif /* HAL_CORDIC_MODULE_ENABLED */ + +#ifdef HAL_CRC_MODULE_ENABLED +#include "stm32h5xx_hal_crc.h" +#endif /* HAL_CRC_MODULE_ENABLED */ + +#ifdef HAL_CRYP_MODULE_ENABLED +#include "stm32h5xx_hal_cryp.h" +#endif /* HAL_CRYP_MODULE_ENABLED */ + +#ifdef HAL_DAC_MODULE_ENABLED +#include "stm32h5xx_hal_dac.h" +#endif /* HAL_DAC_MODULE_ENABLED */ + +#ifdef HAL_EXTI_MODULE_ENABLED +#include "stm32h5xx_hal_exti.h" +#endif /* HAL_EXTI_MODULE_ENABLED */ + +#ifdef HAL_FDCAN_MODULE_ENABLED +#include "stm32h5xx_hal_fdcan.h" +#endif /* HAL_FDCAN_MODULE_ENABLED */ + +#ifdef HAL_FLASH_MODULE_ENABLED +#include "stm32h5xx_hal_flash.h" +#endif /* HAL_FLASH_MODULE_ENABLED */ + +#ifdef HAL_FMAC_MODULE_ENABLED +#include "stm32h5xx_hal_fmac.h" +#endif /* HAL_FMAC_MODULE_ENABLED */ + +#ifdef HAL_HRTIM_MODULE_ENABLED +#include "stm32h5xx_hal_hrtim.h" +#endif /* HAL_HRTIM_MODULE_ENABLED */ + +#ifdef HAL_IRDA_MODULE_ENABLED +#include "stm32h5xx_hal_irda.h" +#endif /* HAL_IRDA_MODULE_ENABLED */ + +#ifdef HAL_IWDG_MODULE_ENABLED +#include "stm32h5xx_hal_iwdg.h" +#endif /* HAL_IWDG_MODULE_ENABLED */ + +#ifdef HAL_I2C_MODULE_ENABLED +#include "stm32h5xx_hal_i2c.h" +#endif /* HAL_I2C_MODULE_ENABLED */ + +#ifdef HAL_I2S_MODULE_ENABLED +#include "stm32h5xx_hal_i2s.h" +#endif /* HAL_I2S_MODULE_ENABLED */ + +#ifdef HAL_LPTIM_MODULE_ENABLED +#include "stm32h5xx_hal_lptim.h" +#endif /* HAL_LPTIM_MODULE_ENABLED */ + +#ifdef HAL_NAND_MODULE_ENABLED +#include "stm32h5xx_hal_nand.h" +#endif /* HAL_NAND_MODULE_ENABLED */ + +#ifdef HAL_NOR_MODULE_ENABLED +#include "stm32h5xx_hal_nor.h" +#endif /* HAL_NOR_MODULE_ENABLED */ + +#ifdef HAL_OPAMP_MODULE_ENABLED +#include "stm32h5xx_hal_opamp.h" +#endif /* HAL_OPAMP_MODULE_ENABLED */ + +#ifdef HAL_PCD_MODULE_ENABLED +#include "stm32h5xx_hal_pcd.h" +#endif /* HAL_PCD_MODULE_ENABLED */ + +#ifdef HAL_PWR_MODULE_ENABLED +#include "stm32h5xx_hal_pwr.h" +#endif /* HAL_PWR_MODULE_ENABLED */ + +#ifdef HAL_QSPI_MODULE_ENABLED +#include "stm32h5xx_hal_qspi.h" +#endif /* HAL_QSPI_MODULE_ENABLED */ + +#ifdef HAL_RNG_MODULE_ENABLED +#include "stm32h5xx_hal_rng.h" +#endif /* HAL_RNG_MODULE_ENABLED */ + +#ifdef HAL_RTC_MODULE_ENABLED +#include "stm32h5xx_hal_rtc.h" +#endif /* HAL_RTC_MODULE_ENABLED */ + +#ifdef HAL_SAI_MODULE_ENABLED +#include "stm32h5xx_hal_sai.h" +#endif /* HAL_SAI_MODULE_ENABLED */ + +#ifdef HAL_SMARTCARD_MODULE_ENABLED +#include "stm32h5xx_hal_smartcard.h" +#endif /* HAL_SMARTCARD_MODULE_ENABLED */ + +#ifdef HAL_SMBUS_MODULE_ENABLED +#include "stm32h5xx_hal_smbus.h" +#endif /* HAL_SMBUS_MODULE_ENABLED */ + +#ifdef HAL_SPI_MODULE_ENABLED +#include "stm32h5xx_hal_spi.h" +#endif /* HAL_SPI_MODULE_ENABLED */ + +#ifdef HAL_SRAM_MODULE_ENABLED +#include "stm32h5xx_hal_sram.h" +#endif /* HAL_SRAM_MODULE_ENABLED */ + +#ifdef HAL_TIM_MODULE_ENABLED +#include "stm32h5xx_hal_tim.h" +#endif /* HAL_TIM_MODULE_ENABLED */ + +#ifdef HAL_UART_MODULE_ENABLED +#include "stm32h5xx_hal_uart.h" +#endif /* HAL_UART_MODULE_ENABLED */ + +#ifdef HAL_USART_MODULE_ENABLED +#include "stm32h5xx_hal_usart.h" +#endif /* HAL_USART_MODULE_ENABLED */ + +#ifdef HAL_WWDG_MODULE_ENABLED +#include "stm32h5xx_hal_wwdg.h" +#endif /* HAL_WWDG_MODULE_ENABLED */ + +/* Exported macro ------------------------------------------------------------*/ +#ifdef USE_FULL_ASSERT +/** + * @brief The assert_param macro is used for function's parameters check. + * @param expr: If expr is false, it calls assert_failed function + * which reports the name of the source file and the source + * line number of the call that failed. + * If expr is true, it returns no value. + * @retval None + */ +#define assert_param(expr) ((expr) ? (void)0U : assert_failed((uint8_t *)__FILE__, __LINE__)) +/* Exported functions ------------------------------------------------------- */ +void assert_failed(uint8_t *file, uint32_t line); +#else +#define assert_param(expr) ((void)0U) +#endif /* USE_FULL_ASSERT */ + +#ifdef __cplusplus +} +#endif + +#endif /* STM32H5xx_HAL_CONF_H */ diff --git a/SAMM/InboardFloor/Inc/stm32h5xx_it.h b/SAMM/InboardFloor/Inc/stm32h5xx_it.h new file mode 100644 index 000000000..89694865e --- /dev/null +++ b/SAMM/InboardFloor/Inc/stm32h5xx_it.h @@ -0,0 +1,67 @@ +/* USER CODE BEGIN Header */ +/** + ****************************************************************************** + * @file stm32h5xx_it.h + * @brief This file contains the headers of the interrupt handlers. + ****************************************************************************** + * @attention + * + * Copyright (c) 2024 STMicroelectronics. + * All rights reserved. + * + * This software is licensed under terms that can be found in the LICENSE file + * in the root directory of this software component. + * If no LICENSE file comes with this software, it is provided AS-IS. + * + ****************************************************************************** + */ +/* USER CODE END Header */ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef __STM32H5xx_IT_H +#define __STM32H5xx_IT_H + +#ifdef __cplusplus +extern "C" { +#endif + +/* Private includes ----------------------------------------------------------*/ +/* USER CODE BEGIN Includes */ + +/* USER CODE END Includes */ + +/* Exported types ------------------------------------------------------------*/ +/* USER CODE BEGIN ET */ + +/* USER CODE END ET */ + +/* Exported constants --------------------------------------------------------*/ +/* USER CODE BEGIN EC */ + +/* USER CODE END EC */ + +/* Exported macro ------------------------------------------------------------*/ +/* USER CODE BEGIN EM */ + +/* USER CODE END EM */ + +/* Exported functions prototypes ---------------------------------------------*/ +void NMI_Handler(void); +void HardFault_Handler(void); +void MemManage_Handler(void); +void BusFault_Handler(void); +void UsageFault_Handler(void); +void SVC_Handler(void); +void DebugMon_Handler(void); +void PendSV_Handler(void); +void SysTick_Handler(void); +void TIM1_UP_TIM16_IRQHandler(void); +/* USER CODE BEGIN EFP */ + +/* USER CODE END EFP */ + +#ifdef __cplusplus +} +#endif + +#endif /* __STM32H5xx_IT_H */ diff --git a/SAMM/InboardFloor/Src/VL53L4ED_api.c b/SAMM/InboardFloor/Src/VL53L4ED_api.c new file mode 100644 index 000000000..7c844100e --- /dev/null +++ b/SAMM/InboardFloor/Src/VL53L4ED_api.c @@ -0,0 +1,584 @@ +/** + * + * Copyright (c) 2023 STMicroelectronics. + * All rights reserved. + * + * This software is licensed under terms that can be found in the LICENSE file + * in the root directory of this software component. + * If no LICENSE file comes with this software, it is provided AS-IS. + * + ****************************************************************************** + */ + +/** + * @file vl53l4ed_api.c + * @brief Functions implementation + */ + +#include "VL53L4ED_api.h" + +#include +#include + +static const uint8_t VL53L4ED_DEFAULT_CONFIGURATION[] = { +#ifdef VL53L4ED_I2C_FAST_MODE_PLUS + 0x12, /* 0x2d : set bit 2 and 5 to 1 for fast plus mode (1MHz I2C), + else don't touch */ +#else + 0x00, /* 0x2d : set bit 2 and 5 to 1 for fast plus mode (1MHz I2C), + else don't touch */ +#endif + 0x00, /* 0x2e : bit 0 if I2C pulled up at 1.8V, else set bit 0 to 1 + (pull up at AVDD) */ + 0x00, /* 0x2f : bit 0 if GPIO pulled up at 1.8V, else set bit 0 to 1 + (pull up at AVDD) */ + 0x11, /* 0x30 : set bit 4 to 0 for active high interrupt and 1 for active low + (bits 3:0 must be 0x1), use SetInterruptPolarity() */ + 0x02, /* 0x31 : bit 1 = interrupt depending on the polarity, + use CheckForDataReady() */ + 0x00, /* 0x32 : not user-modifiable */ + 0x02, /* 0x33 : not user-modifiable */ + 0x08, /* 0x34 : not user-modifiable */ + 0x00, /* 0x35 : not user-modifiable */ + 0x08, /* 0x36 : not user-modifiable */ + 0x10, /* 0x37 : not user-modifiable */ + 0x01, /* 0x38 : not user-modifiable */ + 0x01, /* 0x39 : not user-modifiable */ + 0x00, /* 0x3a : not user-modifiable */ + 0x00, /* 0x3b : not user-modifiable */ + 0x00, /* 0x3c : not user-modifiable */ + 0x00, /* 0x3d : not user-modifiable */ + 0xff, /* 0x3e : not user-modifiable */ + 0x00, /* 0x3f : not user-modifiable */ + 0x0F, /* 0x40 : not user-modifiable */ + 0x00, /* 0x41 : not user-modifiable */ + 0x00, /* 0x42 : not user-modifiable */ + 0x00, /* 0x43 : not user-modifiable */ + 0x00, /* 0x44 : not user-modifiable */ + 0x00, /* 0x45 : not user-modifiable */ + 0x20, /* 0x46 : interrupt configuration 0->level low detection, 1-> level high, + 2-> Out of window, 3->In window, 0x20-> New sample ready , TBC */ + 0x0b, /* 0x47 : not user-modifiable */ + 0x00, /* 0x48 : not user-modifiable */ + 0x00, /* 0x49 : not user-modifiable */ + 0x02, /* 0x4a : not user-modifiable */ + 0x14, /* 0x4b : not user-modifiable */ + 0x21, /* 0x4c : not user-modifiable */ + 0x00, /* 0x4d : not user-modifiable */ + 0x00, /* 0x4e : not user-modifiable */ + 0x05, /* 0x4f : not user-modifiable */ + 0x00, /* 0x50 : not user-modifiable */ + 0x00, /* 0x51 : not user-modifiable */ + 0x00, /* 0x52 : not user-modifiable */ + 0x00, /* 0x53 : not user-modifiable */ + 0xc8, /* 0x54 : not user-modifiable */ + 0x00, /* 0x55 : not user-modifiable */ + 0x00, /* 0x56 : not user-modifiable */ + 0x38, /* 0x57 : not user-modifiable */ + 0xff, /* 0x58 : not user-modifiable */ + 0x01, /* 0x59 : not user-modifiable */ + 0x00, /* 0x5a : not user-modifiable */ + 0x08, /* 0x5b : not user-modifiable */ + 0x00, /* 0x5c : not user-modifiable */ + 0x00, /* 0x5d : not user-modifiable */ + 0x01, /* 0x5e : not user-modifiable */ + 0xcc, /* 0x5f : not user-modifiable */ + 0x07, /* 0x60 : not user-modifiable */ + 0x01, /* 0x61 : not user-modifiable */ + 0xf1, /* 0x62 : not user-modifiable */ + 0x05, /* 0x63 : not user-modifiable */ + 0x00, /* 0x64 : Sigma threshold MSB (mm in 14.2 format for MSB+LSB), + use SetSigmaThreshold(), default value 90 mm */ + 0xa0, /* 0x65 : Sigma threshold LSB */ + 0x00, /* 0x66 : Min count Rate MSB (MCPS in 9.7 format for MSB+LSB), + use SetSignalThreshold() */ + 0x80, /* 0x67 : Min count Rate LSB */ + 0x08, /* 0x68 : not user-modifiable */ + 0x38, /* 0x69 : not user-modifiable */ + 0x00, /* 0x6a : not user-modifiable */ + 0x00, /* 0x6b : not user-modifiable */ + 0x00, /* 0x6c : Intermeasurement period MSB, 32 bits register, + use SetIntermeasurementInMs() */ + 0x00, /* 0x6d : Intermeasurement period */ + 0x0f, /* 0x6e : Intermeasurement period */ + 0x89, /* 0x6f : Intermeasurement period LSB */ + 0x00, /* 0x70 : not user-modifiable */ + 0x00, /* 0x71 : not user-modifiable */ + 0x00, /* 0x72 : distance threshold high MSB (in mm, MSB+LSB), + use SetD:tanceThreshold() */ + 0x00, /* 0x73 : distance threshold high LSB */ + 0x00, /* 0x74 : distance threshold low MSB ( in mm, MSB+LSB), + use SetD:tanceThreshold() */ + 0x00, /* 0x75 : distance threshold low LSB */ + 0x00, /* 0x76 : not user-modifiable */ + 0x01, /* 0x77 : not user-modifiable */ + 0x07, /* 0x78 : not user-modifiable */ + 0x05, /* 0x79 : not user-modifiable */ + 0x06, /* 0x7a : not user-modifiable */ + 0x06, /* 0x7b : not user-modifiable */ + 0x00, /* 0x7c : not user-modifiable */ + 0x00, /* 0x7d : not user-modifiable */ + 0x02, /* 0x7e : not user-modifiable */ + 0xc7, /* 0x7f : not user-modifiable */ + 0xff, /* 0x80 : not user-modifiable */ + 0x9B, /* 0x81 : not user-modifiable */ + 0x00, /* 0x82 : not user-modifiable */ + 0x00, /* 0x83 : not user-modifiable */ + 0x00, /* 0x84 : not user-modifiable */ + 0x01, /* 0x85 : not user-modifiable */ + 0x00, /* 0x86 : clear interrupt, use ClearInterrupt() */ + 0x00 /* 0x87 : start ranging, use StartRanging() or StopRanging(), + If you want an automatic start after VL53L4ED_init() call, + put 0x40 in location 0x87 */ +}; + +VL53L4ED_Error VL53L4ED_GetSWVersion(VL53L4ED_Version_t *p_Version) +{ + VL53L4ED_Error Status = VL53L4ED_ERROR_NONE; + + p_Version->major = VL53L4ED_IMPLEMENTATION_VER_MAJOR; + p_Version->minor = VL53L4ED_IMPLEMENTATION_VER_MINOR; + p_Version->build = VL53L4ED_IMPLEMENTATION_VER_BUILD; + p_Version->revision = VL53L4ED_IMPLEMENTATION_VER_REVISION; + return Status; +} + +VL53L4ED_Error VL53L4ED_SetI2CAddress(Dev_t dev, uint8_t new_address) +{ + VL53L4ED_Error status = VL53L4ED_ERROR_NONE; + + status |= VL53L4ED_WrByte(dev, VL53L4ED_I2C_SLAVE__DEVICE_ADDRESS, (uint8_t)(new_address >> (uint8_t)1)); + return status; +} + +VL53L4ED_Error VL53L4ED_GetSensorId(Dev_t dev, uint16_t *p_id) +{ + VL53L4ED_Error status = VL53L4ED_ERROR_NONE; + + status |= VL53L4ED_RdWord(dev, VL53L4ED_IDENTIFICATION__MODEL_ID, p_id); + return status; +} + +VL53L4ED_Error VL53L4ED_SensorInit(Dev_t dev) +{ + VL53L4ED_Error status = VL53L4ED_ERROR_NONE; + uint8_t Addr, tmp; + uint8_t continue_loop = 1; + uint16_t i = 0; + + do { + status |= VL53L4ED_RdByte(dev, VL53L4ED_FIRMWARE__SYSTEM_STATUS, &tmp); + + if (tmp == (uint8_t)0x3) /* Sensor booted */ + { + continue_loop = (uint8_t)0; + } else if (i < (uint16_t)1000) /* Wait for boot */ + { + i++; + } else /* Timeout 1000ms reached */ + { + continue_loop = (uint8_t)0; + status |= (uint8_t)VL53L4ED_ERROR_TIMEOUT; + } + VL53L4ED_WaitMs(dev, 1); + } while (continue_loop == (uint8_t)1); + + /* Load default configuration */ + for (Addr = (uint8_t)0x2D; Addr <= (uint8_t)0x87; Addr++) { + status |= VL53L4ED_WrByte(dev, Addr, VL53L4ED_DEFAULT_CONFIGURATION[Addr - (uint8_t)0x2D]); + } + + /* Start VHV */ + status |= VL53L4ED_WrByte(dev, VL53L4ED_SYSTEM_START, (uint8_t)0x40); + i = (uint8_t)0; + continue_loop = (uint8_t)1; + do { + status |= VL53L4ED_CheckForDataReady(dev, &tmp); + if (tmp == (uint8_t)1) /* Data ready */ + { + continue_loop = (uint8_t)0; + } else if (i < (uint16_t)1000) /* Wait for answer */ + { + i++; + } else /* Timeout 1000ms reached */ + { + continue_loop = (uint8_t)0; + status |= (uint8_t)VL53L4ED_ERROR_TIMEOUT; + } + VL53L4ED_WaitMs(dev, 1); + } while (continue_loop == (uint8_t)1); + + status |= VL53L4ED_ClearInterrupt(dev); + status |= VL53L4ED_StopRanging(dev); + status |= VL53L4ED_WrByte(dev, VL53L4ED_VHV_CONFIG__TIMEOUT_MACROP_LOOP_BOUND, (uint8_t)0x09); + status |= VL53L4ED_WrByte(dev, 0x0B, (uint8_t)0); + status |= VL53L4ED_WrWord(dev, 0x0024, 0x500); + + status |= VL53L4ED_SetRangeTiming(dev, 100, 0); + + return status; +} + +VL53L4ED_Error VL53L4ED_ClearInterrupt(Dev_t dev) +{ + VL53L4ED_Error status = VL53L4ED_ERROR_NONE; + + status |= VL53L4ED_WrByte(dev, VL53L4ED_SYSTEM__INTERRUPT_CLEAR, 0x01); + return status; +} + +VL53L4ED_Error VL53L4ED_StartRanging(Dev_t dev) +{ + VL53L4ED_Error status = VL53L4ED_ERROR_NONE; + uint32_t tmp; + + status |= VL53L4ED_RdDWord(dev, VL53L4ED_INTERMEASUREMENT_MS, &tmp); + + /* Sensor runs in continuous mode */ + if (tmp == (uint32_t)0) { + status |= VL53L4ED_WrByte(dev, VL53L4ED_SYSTEM_START, 0x21); + } + /* Sensor runs in autonomous mode */ + else { + status |= VL53L4ED_WrByte(dev, VL53L4ED_SYSTEM_START, 0x40); + } + + return status; +} + +VL53L4ED_Error VL53L4ED_StopRanging(Dev_t dev) +{ + VL53L4ED_Error status = VL53L4ED_ERROR_NONE; + + status |= VL53L4ED_WrByte(dev, VL53L4ED_SYSTEM_START, 0x80); + return status; +} + +VL53L4ED_Error VL53L4ED_CheckForDataReady(Dev_t dev, uint8_t *p_is_data_ready) +{ + VL53L4ED_Error status = VL53L4ED_ERROR_NONE; + uint8_t temp; + uint8_t int_pol; + + status |= VL53L4ED_RdByte(dev, VL53L4ED_GPIO_HV_MUX__CTRL, &temp); + temp = temp & (uint8_t)0x10; + temp = temp >> 4; + + if (temp == (uint8_t)1) { + int_pol = (uint8_t)0; + } else { + int_pol = (uint8_t)1; + } + + status |= VL53L4ED_RdByte(dev, VL53L4ED_GPIO__TIO_HV_STATUS, &temp); + + if ((temp & (uint8_t)1) == int_pol) { + *p_is_data_ready = (uint8_t)1; + } else { + *p_is_data_ready = (uint8_t)0; + } + + return status; +} + +VL53L4ED_Error VL53L4ED_SetRangeTiming(Dev_t dev, uint32_t timing_budget_ms, uint32_t inter_measurement_ms) +{ + VL53L4ED_Error status = VL53L4ED_ERROR_NONE; + uint16_t clock_pll, osc_frequency, ms_byte; + uint32_t macro_period_us = 0, timing_budget_us = 0, ls_byte, tmp; + float_t inter_measurement_factor = (float_t)1.055; + + status |= VL53L4ED_RdWord(dev, 0x0006, &osc_frequency); + if (osc_frequency != (uint16_t)0) { + timing_budget_us = timing_budget_ms * (uint32_t)1000; + macro_period_us = (uint32_t)((uint32_t)2304 * ((uint32_t)0x40000000 / (uint32_t)osc_frequency)) >> 6; + } else { + status |= (uint8_t)VL53L4ED_ERROR_INVALID_ARGUMENT; + } + + /* Timing budget check validity */ + if ((timing_budget_ms < (uint32_t)10) || (timing_budget_ms > (uint32_t)200) || (status != (uint8_t)0)) { + status |= VL53L4ED_ERROR_INVALID_ARGUMENT; + } + /* Sensor runs in continuous mode */ + else if (inter_measurement_ms == (uint32_t)0) { + status |= VL53L4ED_WrDWord(dev, VL53L4ED_INTERMEASUREMENT_MS, 0); + timing_budget_us -= (uint32_t)2500; + } + /* Sensor runs in autonomous low power mode */ + else if (inter_measurement_ms > timing_budget_ms) { + status |= VL53L4ED_RdWord(dev, VL53L4ED_RESULT__OSC_CALIBRATE_VAL, &clock_pll); + clock_pll = clock_pll & (uint16_t)0x3FF; + inter_measurement_factor = inter_measurement_factor * (float_t)inter_measurement_ms * (float_t)clock_pll; + status |= VL53L4ED_WrDWord(dev, VL53L4ED_INTERMEASUREMENT_MS, (uint32_t)inter_measurement_factor); + + timing_budget_us -= (uint32_t)4300; + timing_budget_us /= (uint32_t)2; + + } + /* Invalid case */ + else { + status |= (uint8_t)VL53L4ED_ERROR_INVALID_ARGUMENT; + } + + if (status != (uint8_t)VL53L4ED_ERROR_INVALID_ARGUMENT) { + ms_byte = 0; + timing_budget_us = timing_budget_us << 12; + tmp = macro_period_us * (uint32_t)16; + ls_byte = ((timing_budget_us + ((tmp >> 6) >> 1)) / (tmp >> 6)) - (uint32_t)1; + + while ((ls_byte & 0xFFFFFF00U) > 0U) { + ls_byte = ls_byte >> 1; + ms_byte++; + } + ms_byte = (uint16_t)(ms_byte << 8) + (uint16_t)(ls_byte & (uint32_t)0xFF); + status |= VL53L4ED_WrWord(dev, VL53L4ED_RANGE_CONFIG_A, ms_byte); + + ms_byte = 0; + tmp = macro_period_us * (uint32_t)12; + ls_byte = ((timing_budget_us + ((tmp >> 6) >> 1)) / (tmp >> 6)) - (uint32_t)1; + + while ((ls_byte & 0xFFFFFF00U) > 0U) { + ls_byte = ls_byte >> 1; + ms_byte++; + } + ms_byte = (uint16_t)(ms_byte << 8) + (uint16_t)(ls_byte & (uint32_t)0xFF); + status |= VL53L4ED_WrWord(dev, VL53L4ED_RANGE_CONFIG_B, ms_byte); + } + + return status; +} + +VL53L4ED_Error VL53L4ED_GetRangeTiming(Dev_t dev, uint32_t *p_timing_budget_ms, uint32_t *p_inter_measurement_ms) +{ + VL53L4ED_Error status = VL53L4ED_ERROR_NONE; + uint16_t osc_frequency = 1, range_config_macrop_high, clock_pll = 1; + uint32_t tmp, ls_byte, ms_byte, macro_period_us; + float_t clock_pll_factor = (float_t)1.065; + + /* Get InterMeasurement */ + status |= VL53L4ED_RdDWord(dev, VL53L4ED_INTERMEASUREMENT_MS, &tmp); + status |= VL53L4ED_RdWord(dev, VL53L4ED_RESULT__OSC_CALIBRATE_VAL, &clock_pll); + clock_pll = clock_pll & (uint16_t)0x3FF; + clock_pll_factor = clock_pll_factor * (float_t)clock_pll; + clock_pll = (uint16_t)clock_pll_factor; + *p_inter_measurement_ms = (uint16_t)(tmp / (uint32_t)clock_pll); + + /* Get TimingBudget */ + status |= VL53L4ED_RdWord(dev, 0x0006, &osc_frequency); + status |= VL53L4ED_RdWord(dev, VL53L4ED_RANGE_CONFIG_A, &range_config_macrop_high); + + macro_period_us = (uint32_t)((uint32_t)2304 * ((uint32_t)0x40000000 / (uint32_t)osc_frequency)) >> 6; + ls_byte = (range_config_macrop_high & (uint32_t)0x00FF) << 4; + ms_byte = (range_config_macrop_high & (uint32_t)0xFF00) >> 8; + ms_byte = (uint32_t)0x04 - (ms_byte - (uint32_t)1) - (uint32_t)1; + + macro_period_us = macro_period_us * (uint32_t)16; + *p_timing_budget_ms = (((ls_byte + (uint32_t)1) * (macro_period_us >> 6)) - ((macro_period_us >> 6) >> 1)) >> 12; + + if (ms_byte < (uint8_t)12) { + *p_timing_budget_ms = (uint32_t)(*p_timing_budget_ms >> (uint8_t)ms_byte); + } + + /* Mode continuous */ + if (tmp == (uint32_t)0) { + *p_timing_budget_ms += (uint32_t)2500; + } + /* Mode autonomous */ + else { + *p_timing_budget_ms *= (uint32_t)2; + *p_timing_budget_ms += (uint32_t)4300; + } + + *p_timing_budget_ms = *p_timing_budget_ms / (uint32_t)1000; + + return status; +} + +VL53L4ED_Error VL53L4ED_GetResult(Dev_t dev, VL53L4ED_ResultsData_t *p_result) +{ + VL53L4ED_Error status = VL53L4ED_ERROR_NONE; + uint16_t temp_16; + uint8_t temp_8; + uint8_t status_rtn[24] = {255, 255, 255, 5, 2, 4, 1, 7, 3, 0, 255, 255, 9, 13, 255, 255, 255, 255, 10, 6, 255, 255, 11, 12}; + + status |= VL53L4ED_RdByte(dev, VL53L4ED_RESULT__RANGE_STATUS, &temp_8); + temp_8 = temp_8 & (uint8_t)0x1F; + if (temp_8 < (uint8_t)24) { + temp_8 = status_rtn[temp_8]; + } + p_result->range_status = temp_8; + + status |= VL53L4ED_RdWord(dev, VL53L4ED_RESULT__SPAD_NB, &temp_16); + p_result->number_of_spad = temp_16 / (uint16_t)256; + + status |= VL53L4ED_RdWord(dev, VL53L4ED_RESULT__SIGNAL_RATE, &temp_16); + p_result->signal_rate_kcps = temp_16 * (uint16_t)8; + + status |= VL53L4ED_RdWord(dev, VL53L4ED_RESULT__AMBIENT_RATE, &temp_16); + p_result->ambient_rate_kcps = temp_16 * (uint16_t)8; + + status |= VL53L4ED_RdWord(dev, VL53L4ED_RESULT__SIGMA, &temp_16); + p_result->sigma_mm = temp_16 / (uint16_t)4; + + status |= VL53L4ED_RdWord(dev, VL53L4ED_RESULT__DISTANCE, &temp_16); + p_result->distance_mm = temp_16; + + p_result->signal_per_spad_kcps = p_result->signal_rate_kcps / p_result->number_of_spad; + p_result->ambient_per_spad_kcps = p_result->ambient_rate_kcps / p_result->number_of_spad; + + return status; +} + +VL53L4ED_Error VL53L4ED_SetOffset(Dev_t dev, int16_t OffsetValueInMm) +{ + VL53L4ED_Error status = VL53L4ED_ERROR_NONE; + uint16_t temp; + + temp = (uint16_t)((uint16_t)OffsetValueInMm * (uint16_t)4); + + status |= VL53L4ED_WrWord(dev, VL53L4ED_RANGE_OFFSET_MM, temp); + status |= VL53L4ED_WrWord(dev, VL53L4ED_INNER_OFFSET_MM, (uint8_t)0x0); + status |= VL53L4ED_WrWord(dev, VL53L4ED_OUTER_OFFSET_MM, (uint8_t)0x0); + return status; +} + +VL53L4ED_Error VL53L4ED_GetOffset(Dev_t dev, int16_t *p_offset) +{ + VL53L4ED_Error status = VL53L4ED_ERROR_NONE; + uint16_t temp; + + status |= VL53L4ED_RdWord(dev, VL53L4ED_RANGE_OFFSET_MM, &temp); + + temp = temp << 3; + temp = temp >> 5; + *p_offset = (int16_t)(temp); + + if (*p_offset > 1024) { + *p_offset = *p_offset - 2048; + } + + return status; +} + +VL53L4ED_Error VL53L4ED_SetXtalk(Dev_t dev, uint16_t XtalkValueKcps) +{ + VL53L4ED_Error status = VL53L4ED_ERROR_NONE; + + status |= VL53L4ED_WrWord(dev, VL53L4ED_XTALK_X_PLANE_GRADIENT_KCPS, 0x0000); + status |= VL53L4ED_WrWord(dev, VL53L4ED_XTALK_Y_PLANE_GRADIENT_KCPS, 0x0000); + status |= VL53L4ED_WrWord(dev, VL53L4ED_XTALK_PLANE_OFFSET_KCPS, (XtalkValueKcps << 9)); + + return status; +} + +VL53L4ED_Error VL53L4ED_GetXtalk(Dev_t dev, uint16_t *p_xtalk_kcps) +{ + VL53L4ED_Error status = VL53L4ED_ERROR_NONE; + float_t tmp_xtalk; + + status |= VL53L4ED_RdWord(dev, VL53L4ED_XTALK_PLANE_OFFSET_KCPS, p_xtalk_kcps); + + tmp_xtalk = (float_t)*p_xtalk_kcps / (float_t)512.0; + *p_xtalk_kcps = (uint16_t)(round(tmp_xtalk)); + + return status; +} + +VL53L4ED_Error VL53L4ED_SetDetectionThresholds(Dev_t dev, uint16_t distance_low_mm, uint16_t distance_high_mm, uint8_t window) +{ + VL53L4ED_Error status = VL53L4ED_ERROR_NONE; + + status |= VL53L4ED_WrByte(dev, VL53L4ED_SYSTEM__INTERRUPT, window); + status |= VL53L4ED_WrWord(dev, VL53L4ED_THRESH_HIGH, distance_high_mm); + status |= VL53L4ED_WrWord(dev, VL53L4ED_THRESH_LOW, distance_low_mm); + return status; +} + +VL53L4ED_Error VL53L4ED_GetDetectionThresholds(Dev_t dev, uint16_t *p_distance_low_mm, uint16_t *p_distance_high_mm, uint8_t *p_window) +{ + VL53L4ED_Error status = VL53L4ED_ERROR_NONE; + + status |= VL53L4ED_RdWord(dev, VL53L4ED_THRESH_HIGH, p_distance_high_mm); + status |= VL53L4ED_RdWord(dev, VL53L4ED_THRESH_LOW, p_distance_low_mm); + status |= VL53L4ED_RdByte(dev, VL53L4ED_SYSTEM__INTERRUPT, p_window); + *p_window = (*p_window & (uint8_t)0x7); + + return status; +} + +VL53L4ED_Error VL53L4ED_SetSignalThreshold(Dev_t dev, uint16_t signal_kcps) +{ + VL53L4ED_Error status = VL53L4ED_ERROR_NONE; + + status |= VL53L4ED_WrWord(dev, VL53L4ED_MIN_COUNT_RATE_RTN_LIMIT_MCPS, signal_kcps >> 3); + return status; +} + +VL53L4ED_Error VL53L4ED_GetSignalThreshold(Dev_t dev, uint16_t *p_signal_kcps) +{ + VL53L4ED_Error status = VL53L4ED_ERROR_NONE; + uint16_t tmp = 0; + + status |= VL53L4ED_RdWord(dev, VL53L4ED_MIN_COUNT_RATE_RTN_LIMIT_MCPS, &tmp); + *p_signal_kcps = tmp << 3; + + return status; +} + +VL53L4ED_Error VL53L4ED_SetSigmaThreshold(Dev_t dev, uint16_t sigma_mm) +{ + VL53L4ED_Error status = VL53L4ED_ERROR_NONE; + + if (sigma_mm > (uint16_t)((uint16_t)0xFFFF >> 2)) { + status |= (uint8_t)VL53L4ED_ERROR_INVALID_ARGUMENT; + } else { + status |= VL53L4ED_WrWord(dev, VL53L4ED_RANGE_CONFIG__SIGMA_THRESH, sigma_mm << 2); + } + + return status; +} + +VL53L4ED_Error VL53L4ED_GetSigmaThreshold(Dev_t dev, uint16_t *p_sigma_mm) +{ + VL53L4ED_Error status = VL53L4ED_ERROR_NONE; + + status += VL53L4ED_RdWord(dev, VL53L4ED_RANGE_CONFIG__SIGMA_THRESH, p_sigma_mm); + *p_sigma_mm = *p_sigma_mm >> 2; + + return status; +} + +VL53L4ED_Error VL53L4ED_StartTemperatureUpdate(Dev_t dev) +{ + VL53L4ED_Error status = VL53L4ED_ERROR_NONE; + uint8_t tmp = 0, continue_loop = 1; + uint16_t i = 0; + + status |= VL53L4ED_WrByte(dev, VL53L4ED_VHV_CONFIG__TIMEOUT_MACROP_LOOP_BOUND, (uint8_t)0x81); + status |= VL53L4ED_WrByte(dev, 0x0B, (uint8_t)0x92); + status |= VL53L4ED_StartRanging(dev); + + do { + status |= VL53L4ED_CheckForDataReady(dev, &tmp); + if (tmp == (uint8_t)1) /* Data ready */ + { + continue_loop = (uint8_t)0; + } else if (i < (uint16_t)1000) /* Wait for answer */ + { + i++; + } else /* Timeout 1000ms reached */ + { + continue_loop = (uint8_t)0; + status = (uint8_t)VL53L4ED_ERROR_TIMEOUT; + } + VL53L4ED_WaitMs(dev, 1); + } while (continue_loop == (uint8_t)1); + + status |= VL53L4ED_ClearInterrupt(dev); + status |= VL53L4ED_StopRanging(dev); + + status += VL53L4ED_WrByte(dev, VL53L4ED_VHV_CONFIG__TIMEOUT_MACROP_LOOP_BOUND, 0x09); + status += VL53L4ED_WrByte(dev, 0x0B, 0); + return status; +} diff --git a/SAMM/InboardFloor/Src/VL53L4ED_calibration.c b/SAMM/InboardFloor/Src/VL53L4ED_calibration.c new file mode 100644 index 000000000..6a0d96eb1 --- /dev/null +++ b/SAMM/InboardFloor/Src/VL53L4ED_calibration.c @@ -0,0 +1,207 @@ +/** + * + * Copyright (c) 2023 STMicroelectronics. + * All rights reserved. + * + * This software is licensed under terms that can be found in the LICENSE file + * in the root directory of this software component. + * If no LICENSE file comes with this software, it is provided AS-IS. + * + ****************************************************************************** + */ + +/** + * @file vl53l4ed_calibration.c + * @brief Calibration functions implementation + */ + +#include "VL53L4ED_calibration.h" + +#include + +#include "VL53L4ED_api.h" + +VL53L4ED_Error VL53L4ED_CalibrateOffset(Dev_t dev, int16_t TargetDistInMm, int16_t *p_measured_offset_mm, int16_t nb_samples) +{ + VL53L4ED_Error status = VL53L4ED_ERROR_NONE; + uint8_t i, tmp, continue_loop; + uint16_t j, tmpOff; + int16_t AvgDistance = 0; + VL53L4ED_ResultsData_t results; + + if (((nb_samples < (int16_t)5) || (nb_samples > (int16_t)255)) || ((TargetDistInMm < (int16_t)10) || (TargetDistInMm > (int16_t)1000))) { + status |= (uint8_t)VL53L4ED_ERROR_INVALID_ARGUMENT; + } else { + status |= VL53L4ED_WrWord(dev, VL53L4ED_RANGE_OFFSET_MM, 0x0); + status |= VL53L4ED_WrWord(dev, VL53L4ED_INNER_OFFSET_MM, 0x0); + status |= VL53L4ED_WrWord(dev, VL53L4ED_OUTER_OFFSET_MM, 0x0); + + /* Device heat loop (10 samples) */ + status |= VL53L4ED_StartRanging(dev); + for (i = 0; i < (uint8_t)10; i++) { + tmp = (uint8_t)0; + j = (uint16_t)0; + continue_loop = (uint8_t)1; + do { + status |= VL53L4ED_CheckForDataReady(dev, &tmp); + if (tmp == (uint8_t)1) /* Data ready */ + { + continue_loop = (uint8_t)0; + } else if (j < (uint16_t)5000) /* Wait for answer*/ + { + j++; + } else /* Timeout 5000ms reached */ + { + continue_loop = (uint8_t)0; + status |= (uint8_t)VL53L4ED_ERROR_TIMEOUT; + } + VL53L4ED_WaitMs(dev, 1); + } while (continue_loop == (uint8_t)1); + status |= VL53L4ED_GetResult(dev, &results); + status |= VL53L4ED_ClearInterrupt(dev); + } + status |= VL53L4ED_StopRanging(dev); + + /* Device ranging */ + status |= VL53L4ED_StartRanging(dev); + for (i = 0; i < (uint8_t)nb_samples; i++) { + tmp = (uint8_t)0; + j = (uint16_t)0; + continue_loop = (uint8_t)1; + do { + status |= VL53L4ED_CheckForDataReady(dev, &tmp); + if (tmp == (uint8_t)1) /* Data ready */ + { + continue_loop = (uint8_t)0; + } else if (j < (uint16_t)5000) /* Wait for answer*/ + { + j++; + } else /* Timeout 5000ms reached */ + { + continue_loop = (uint8_t)0; + status |= (uint8_t)VL53L4ED_ERROR_TIMEOUT; + } + VL53L4ED_WaitMs(dev, 1); + } while (continue_loop == (uint8_t)1); + + status |= VL53L4ED_GetResult(dev, &results); + status |= VL53L4ED_ClearInterrupt(dev); + AvgDistance += (int16_t)results.distance_mm; + } + + status |= VL53L4ED_StopRanging(dev); + AvgDistance = AvgDistance / nb_samples; + *p_measured_offset_mm = (int16_t)TargetDistInMm - AvgDistance; + tmpOff = (uint16_t)*p_measured_offset_mm * (uint16_t)4; + status |= VL53L4ED_WrWord(dev, VL53L4ED_RANGE_OFFSET_MM, tmpOff); + } + + return status; +} + +VL53L4ED_Error VL53L4ED_CalibrateXtalk(Dev_t dev, int16_t TargetDistInMm, uint16_t *p_measured_xtalk_kcps, int16_t nb_samples) +{ + VL53L4ED_Error status = VL53L4ED_ERROR_NONE; + uint8_t i, tmp, continue_loop; + float_t AverageSignal = (float_t)0.0; + float_t AvgDistance = (float_t)0.0; + float_t AverageSpadNb = (float_t)0.0; + float_t TargetDistance = (float_t)TargetDistInMm; + float_t tmp_xtalk, CounterNbSamples = (float_t)0.0; + VL53L4ED_ResultsData_t results; + + uint16_t calXtalk, j; + + *p_measured_xtalk_kcps = 0; + if (((nb_samples < (int16_t)5) || (nb_samples > (int16_t)255)) || ((TargetDistInMm < (int16_t)10) || (TargetDistInMm > (int16_t)5000))) { + status |= (uint8_t)VL53L4ED_ERROR_INVALID_ARGUMENT; + } else { + /* Disable Xtalk compensation */ + status |= VL53L4ED_WrWord(dev, VL53L4ED_XTALK_PLANE_OFFSET_KCPS, *p_measured_xtalk_kcps); + + /* Device heat loop (10 samples) */ + status |= VL53L4ED_StartRanging(dev); + for (i = 0; i < (uint8_t)10; i++) { + tmp = (uint8_t)0; + j = (uint16_t)0; + continue_loop = (uint8_t)1; + do { + status |= VL53L4ED_CheckForDataReady(dev, &tmp); + if (tmp == (uint8_t)1) /* Data ready */ + { + continue_loop = (uint8_t)0; + } else if (j < (uint16_t)5000) /* Wait for answer*/ + { + j++; + } else /* Timeout 5000ms reached */ + { + continue_loop = (uint8_t)0; + status |= (uint8_t)VL53L4ED_ERROR_TIMEOUT; + } + VL53L4ED_WaitMs(dev, 1); + } while (continue_loop == (uint8_t)1); + status |= VL53L4ED_GetResult(dev, &results); + status |= VL53L4ED_ClearInterrupt(dev); + } + status |= VL53L4ED_StopRanging(dev); + + /* Device ranging loop */ + status |= VL53L4ED_StartRanging(dev); + for (i = 0; i < (uint8_t)nb_samples; i++) { + tmp = (uint8_t)0; + j = (uint16_t)0; + continue_loop = (uint8_t)1; + do { + status |= VL53L4ED_CheckForDataReady(dev, &tmp); + if (tmp == (uint8_t)1) /* Data ready */ + { + continue_loop = (uint8_t)0; + } else if (j < (uint16_t)5000) /* Wait for answer*/ + { + j++; + } else /* Timeout 5000ms reached */ + { + continue_loop = (uint8_t)0; + status |= (uint8_t)VL53L4ED_ERROR_TIMEOUT; + } + VL53L4ED_WaitMs(dev, 1); + } while (continue_loop == (uint8_t)1); + + status |= VL53L4ED_GetResult(dev, &results); + status |= VL53L4ED_ClearInterrupt(dev); + + /* Discard invalid measurements and first frame */ + if (results.range_status == (uint8_t)0 && i > (uint8_t)0) { + AvgDistance += (float_t)results.distance_mm; + AverageSpadNb += (float_t)results.number_of_spad; + AverageSignal += (float_t)results.signal_rate_kcps; + CounterNbSamples++; + } + } + status |= VL53L4ED_StopRanging(dev); + + if (CounterNbSamples == 0) { + status = VL53L4ED_ERROR_XTALK_FAILED; + } else { + AvgDistance /= CounterNbSamples; + AverageSpadNb /= CounterNbSamples; + AverageSignal /= CounterNbSamples; + + tmp_xtalk = (float_t)1.0 - (AvgDistance / TargetDistance); + tmp_xtalk *= (AverageSignal / AverageSpadNb); + + /* 127kcps is the max Xtalk value (65536/512) */ + if (tmp_xtalk > (uint16_t)127) { + status = VL53L4ED_ERROR_XTALK_FAILED; + } else { + *p_measured_xtalk_kcps = (uint16_t)(round(tmp_xtalk)); + + /* Send data to firmware */ + calXtalk = (uint16_t)(tmp_xtalk * (float_t)512.0); + status |= VL53L4ED_WrWord(dev, VL53L4ED_XTALK_PLANE_OFFSET_KCPS, calXtalk); + } + } + } + + return status; +} diff --git a/SAMM/InboardFloor/Src/can_inboardfloor.c b/SAMM/InboardFloor/Src/can_inboardfloor.c new file mode 100644 index 000000000..d0de25964 --- /dev/null +++ b/SAMM/InboardFloor/Src/can_inboardfloor.c @@ -0,0 +1,133 @@ +#include "can_inboardfloor.h" + +#include "can_cfg.h" + +static GRCAN_MSG_ID CAN_INBOARDFLOOR_MSG_DATA = GRCAN_INBOARDFLOOR_IMU_TOF_DATA; +static GRCAN_NODE_ID sensorNode = GRCAN_ALL; // Before initialization +static GRCAN_NODE_ID localNode = LOCAL_GR_ID; +static GRCAN_NODE_ID TCMNode = GRCAN_TCM; +static GRCAN_BUS_ID mainBus = GRCAN_BUS_DATA; +static GRCAN_BUS_ID subnetBus = GRCAN_BUS_DATA_SUBNET; +static uint32_t data_length = 64; + +uint32_t *forwarded_brake_temp_data = 0; +uint32_t *forwarded_TCM_data = 0; + +// For messages from brake temp +void BrakeTemp_Callback(uint32_t id, void *data, uint32_t size) +{ + + GRCAN_Fancy_ID GRCAN_Fancy_ID; + GRCAN_Fancy_ID.srcID = 0; + GRCAN_Fancy_ID.destNode = 0; + GRCAN_Fancy_ID.messageID = 0; + + GRCAN_Fancy_DecodeID(&GRCAN_Fancy_ID, id); + + forwarded_brake_temp_data = (uint32_t *)data; + + // Forward messages to TCM via main data bus -- does not filter anything right now (should only be brake temp though) + GRCAN_Fancy_Send(mainBus, TCMNode, GRCAN_Fancy_ID.messageID, data, size); +} + +// For messages from TCM +void TCM_Callback(uint32_t id, void *data, uint32_t size) +{ + + GRCAN_Fancy_ID GRCAN_Fancy_ID; + GRCAN_Fancy_ID.srcID = 0; + GRCAN_Fancy_ID.destNode = 0; + GRCAN_Fancy_ID.messageID = 0; + + GRCAN_Fancy_DecodeID(&GRCAN_Fancy_ID, id); + + forwarded_TCM_data = (uint32_t *)data; + // Forward all messages to brake temp sensor via subnet bus -- does not filter for anything right now + GRCAN_Fancy_Send(subnetBus, sensorNode, GRCAN_Fancy_ID.messageID, data, size); + + if (GRCAN_Fancy_ID.messageID == GRCAN_PING) { + // Send ping back to sender on main data bus + GRCAN_Fancy_Send(mainBus, GRCAN_Fancy_ID.srcID, GRCAN_PING, data, size); + } +} + +int InboardFloor_CAN_Init(GRCAN_BUS_ID busID) +{ + int bus = (int)busID; // technically GRCAN_BUS_DATA_SUBNET does not exist, avoid warnings by casting to int + + if (bus != GRCAN_BUS_DATA && bus != GRCAN_BUS_DATA_SUBNET) { + LOGOMATIC("Invalid bus for Inboard Floor Node CAN Init"); + return 0; + } + + GRCAN_BusConfig bus_config = {0}; + GRCAN_SetDefaultBusConfig(&bus_config, bus); + +#if defined(STM32H5) + bus_config.clock_source = GRCAN_CLKSRC_PLL1Q; // should be 180MHz, defaults should work +#endif + + if (bus == GRCAN_BUS_DATA_SUBNET) { + bus_config.fdcan_instance = FDCAN2; + bus_config.rx_callback = BrakeTemp_Callback; // callback + } else if (bus == GRCAN_BUS_DATA) { + bus_config.fdcan_instance = FDCAN1; + bus_config.rx_callback = TCM_Callback; // callback + + InboardFloor_Node if_node = (InboardFloor_Node)localNode; + BrakeTemp_Node braketemp_node; + + switch (if_node) { + case InboardFloor_FL: + braketemp_node = BrakeTemp_FL; + break; + case InboardFloor_FR: + braketemp_node = BrakeTemp_FR; + break; + case InboardFloor_RL: + braketemp_node = BrakeTemp_RL; + break; + case InboardFloor_RR: + braketemp_node = BrakeTemp_RR; + break; + default: + LOGOMATIC("Invalid inboard floor node, defaulting to FL\n"); + braketemp_node = BrakeTemp_FL; + break; + } + + sensorNode = (GRCAN_NODE_ID)braketemp_node; + } + + bool result = GRCAN_InitBus(&bus_config); + + if (!result) { + LOGOMATIC("Failed to intialize Inboard Floor CAN Bus"); + return 0; + } + + GRCAN_SetLocalNodeID(localNode); + + return 1; // success +} + +bool InboardFloor_CAN_Send(GRCAN_NODE_ID dest_node, GRCAN_MSG_ID msg_id, void *data) +{ + if (data == NULL) { + LOGOMATIC("Inboard Floor Node CAN send: NULL data"); + return false; + } + + if (msg_id != CAN_INBOARDFLOOR_MSG_DATA) { + LOGOMATIC("Invalid Inboard Floor Node message ID, defaulting to DATA\n"); + msg_id = (GRCAN_MSG_ID)CAN_INBOARDFLOOR_MSG_DATA; + } + + bool result = GRCAN_Fancy_Send(mainBus, dest_node, msg_id, data, data_length); + + if (!result) { + LOGOMATIC("Inboard Floor Node CAN send failed"); + } + + return result; +} diff --git a/SAMM/InboardFloor/Src/crc.c b/SAMM/InboardFloor/Src/crc.c new file mode 100644 index 000000000..213510a5d --- /dev/null +++ b/SAMM/InboardFloor/Src/crc.c @@ -0,0 +1,86 @@ +/* USER CODE BEGIN Header */ +/** + ****************************************************************************** + * @file crc.c + * @brief This file provides code for the configuration + * of the CRC instances. + ****************************************************************************** + * @attention + * + * Copyright (c) 2024 STMicroelectronics. + * All rights reserved. + * + * This software is licensed under terms that can be found in the LICENSE file + * in the root directory of this software component. + * If no LICENSE file comes with this software, it is provided AS-IS. + * + ****************************************************************************** + */ +/* USER CODE END Header */ +/* Includes ------------------------------------------------------------------*/ +#include "crc.h" + +/* USER CODE BEGIN 0 */ + +/* USER CODE END 0 */ + +CRC_HandleTypeDef hcrc; + +/* CRC init function */ +void MX_CRC_Init(void) +{ + + /* USER CODE BEGIN CRC_Init 0 */ + + /* USER CODE END CRC_Init 0 */ + + /* USER CODE BEGIN CRC_Init 1 */ + + /* USER CODE END CRC_Init 1 */ + hcrc.Instance = CRC; + hcrc.Init.DefaultPolynomialUse = DEFAULT_POLYNOMIAL_ENABLE; + hcrc.Init.DefaultInitValueUse = DEFAULT_INIT_VALUE_ENABLE; + hcrc.Init.InputDataInversionMode = CRC_INPUTDATA_INVERSION_NONE; + hcrc.Init.OutputDataInversionMode = CRC_OUTPUTDATA_INVERSION_DISABLE; + hcrc.InputDataFormat = CRC_INPUTDATA_FORMAT_BYTES; + if (HAL_CRC_Init(&hcrc) != HAL_OK) { + Error_Handler(); + } + /* USER CODE BEGIN CRC_Init 2 */ + + /* USER CODE END CRC_Init 2 */ +} + +void HAL_CRC_MspInit(CRC_HandleTypeDef *crcHandle) +{ + + if (crcHandle->Instance == CRC) { + /* USER CODE BEGIN CRC_MspInit 0 */ + + /* USER CODE END CRC_MspInit 0 */ + /* CRC clock enable */ + __HAL_RCC_CRC_CLK_ENABLE(); + /* USER CODE BEGIN CRC_MspInit 1 */ + + /* USER CODE END CRC_MspInit 1 */ + } +} + +void HAL_CRC_MspDeInit(CRC_HandleTypeDef *crcHandle) +{ + + if (crcHandle->Instance == CRC) { + /* USER CODE BEGIN CRC_MspDeInit 0 */ + + /* USER CODE END CRC_MspDeInit 0 */ + /* Peripheral clock disable */ + __HAL_RCC_CRC_CLK_DISABLE(); + /* USER CODE BEGIN CRC_MspDeInit 1 */ + + /* USER CODE END CRC_MspDeInit 1 */ + } +} + +/* USER CODE BEGIN 1 */ + +/* USER CODE END 1 */ diff --git a/SAMM/InboardFloor/Src/dma.c b/SAMM/InboardFloor/Src/dma.c new file mode 100644 index 000000000..972b9efea --- /dev/null +++ b/SAMM/InboardFloor/Src/dma.c @@ -0,0 +1,56 @@ +/* USER CODE BEGIN Header */ +/** + ****************************************************************************** + * @file dma.c + * @brief This file provides code for the configuration + * of all the requested memory to memory DMA transfers. + ****************************************************************************** + * @attention + * + * Copyright (c) 2024 STMicroelectronics. + * All rights reserved. + * + * This software is licensed under terms that can be found in the LICENSE file + * in the root directory of this software component. + * If no LICENSE file comes with this software, it is provided AS-IS. + * + ****************************************************************************** + */ +/* USER CODE END Header */ + +/* Includes ------------------------------------------------------------------*/ +#include "dma.h" + +/* USER CODE BEGIN 0 */ + +/* USER CODE END 0 */ + +/*----------------------------------------------------------------------------*/ +/* Configure DMA */ +/*----------------------------------------------------------------------------*/ + +/* USER CODE BEGIN 1 */ + +/* USER CODE END 1 */ + +/** + * Enable DMA controller clock + */ +void MX_DMA_Init(void) +{ + + /* DMA controller clock enable */ + __HAL_RCC_GPDMA1_CLK_ENABLE(); + + /* DMA interrupt init */ + /* DMA1_Channel1_IRQn interrupt configuration */ + HAL_NVIC_SetPriority(GPDMA1_Channel1_IRQn, 0, 0); + HAL_NVIC_EnableIRQ(GPDMA1_Channel1_IRQn); + /* DMA1_Channel2_IRQn interrupt configuration */ + HAL_NVIC_SetPriority(GPDMA1_Channel2_IRQn, 0, 0); + HAL_NVIC_EnableIRQ(GPDMA1_Channel2_IRQn); +} + +/* USER CODE BEGIN 2 */ + +/* USER CODE END 2 */ diff --git a/SAMM/InboardFloor/Src/gpio.c b/SAMM/InboardFloor/Src/gpio.c new file mode 100644 index 000000000..6205c6ee0 --- /dev/null +++ b/SAMM/InboardFloor/Src/gpio.c @@ -0,0 +1,63 @@ +/* USER CODE BEGIN Header */ +/** + ****************************************************************************** + * @file gpio.c + * @brief This file provides code for the configuration + * of all used GPIO pins. + ****************************************************************************** + * @attention + * + * Copyright (c) 2024 STMicroelectronics. + * All rights reserved. + * + * This software is licensed under terms that can be found in the LICENSE file + * in the root directory of this software component. + * If no LICENSE file comes with this software, it is provided AS-IS. + * + ****************************************************************************** + */ +/* USER CODE END Header */ + +/* Includes ------------------------------------------------------------------*/ +#include "gpio.h" + +/* USER CODE BEGIN 0 */ + +/* USER CODE END 0 */ + +/*----------------------------------------------------------------------------*/ +/* Configure GPIO */ +/*----------------------------------------------------------------------------*/ +/* USER CODE BEGIN 1 */ + +/* USER CODE END 1 */ +/** + * @brief GPIO Initialization Function + * @param None + * @retval None + */ +void MX_GPIO_Init(void) +{ + LL_GPIO_InitTypeDef GPIO_InitStruct = {0}; + /* USER CODE BEGIN MX_GPIO_Init_1 */ + /* USER CODE END MX_GPIO_Init_1 */ + + /* GPIO Ports Clock Enable */ + LL_AHB2_GRP1_EnableClock(LL_AHB2_GRP1_PERIPH_GPIOH); + LL_AHB2_GRP1_EnableClock(LL_AHB2_GRP1_PERIPH_GPIOA); + LL_AHB2_GRP1_EnableClock(LL_AHB2_GRP1_PERIPH_GPIOB); + + /**/ + LL_GPIO_ResetOutputPin(GPIOB, LL_GPIO_PIN_10); + + /**/ + GPIO_InitStruct.Pin = LL_GPIO_PIN_10; + GPIO_InitStruct.Mode = LL_GPIO_MODE_OUTPUT; + GPIO_InitStruct.Speed = LL_GPIO_SPEED_FREQ_LOW; + GPIO_InitStruct.OutputType = LL_GPIO_OUTPUT_PUSHPULL; + GPIO_InitStruct.Pull = LL_GPIO_PULL_NO; + LL_GPIO_Init(GPIOB, &GPIO_InitStruct); + + /* USER CODE BEGIN MX_GPIO_Init_2 */ + /* USER CODE END MX_GPIO_Init_2 */ +} diff --git a/SAMM/InboardFloor/Src/i2c.c b/SAMM/InboardFloor/Src/i2c.c new file mode 100644 index 000000000..f4ddeb4f8 --- /dev/null +++ b/SAMM/InboardFloor/Src/i2c.c @@ -0,0 +1,141 @@ +/* USER CODE BEGIN Header */ +/** + ****************************************************************************** + * @file i2c.c + * @brief This file provides code for the configuration + * of the I2C instances. + ****************************************************************************** + * @attention + * + * Copyright (c) 2024 STMicroelectronics. + * All rights reserved. + * + * This software is licensed under terms that can be found in the LICENSE file + * in the root directory of this software component. + * If no LICENSE file comes with this software, it is provided AS-IS. + * + ****************************************************************************** + */ +/* USER CODE END Header */ +/* Includes ------------------------------------------------------------------*/ +#include "i2c.h" + +/* USER CODE BEGIN 0 */ +extern uint32_t I2C_Freq; +/* USER CODE END 0 */ + +I2C_HandleTypeDef hi2c1; + +/** + * @brief I2C1 Initialization Function + * @param None + * @retval None + */ +void MX_I2C1_Init(void) +{ + + /* USER CODE BEGIN I2C1_Init 0 */ + + /* USER CODE END I2C1_Init 0 */ + + /* USER CODE BEGIN I2C1_Init 1 */ + + /* USER CODE END I2C1_Init 1 */ + hi2c1.Instance = I2C1; + hi2c1.Init.Timing = 0x00100413; + hi2c1.Init.OwnAddress1 = 0; + hi2c1.Init.AddressingMode = I2C_ADDRESSINGMODE_7BIT; + hi2c1.Init.DualAddressMode = I2C_DUALADDRESS_DISABLE; + hi2c1.Init.OwnAddress2 = 0; + hi2c1.Init.OwnAddress2Masks = I2C_OA2_NOMASK; + hi2c1.Init.GeneralCallMode = I2C_GENERALCALL_DISABLE; + hi2c1.Init.NoStretchMode = I2C_NOSTRETCH_DISABLE; + if (HAL_I2C_Init(&hi2c1) != HAL_OK) { + Error_Handler(); + } + + /** Configure Analogue filter + */ + if (HAL_I2CEx_ConfigAnalogFilter(&hi2c1, I2C_ANALOGFILTER_ENABLE) != HAL_OK) { + Error_Handler(); + } + + /** Configure Digital filter + */ + if (HAL_I2CEx_ConfigDigitalFilter(&hi2c1, 0) != HAL_OK) { + Error_Handler(); + } + + /** I2C Fast mode Plus enable + */ + if (HAL_I2CEx_ConfigFastModePlus(&hi2c1, I2C_FASTMODEPLUS_ENABLE) != HAL_OK) { + Error_Handler(); + } + /* USER CODE BEGIN I2C1_Init 2 */ + + /* USER CODE END I2C1_Init 2 */ +} + +/** + * @brief I2C MSP Initialization + * This function configures the hardware resources used in this example + * @param hi2c: I2C handle pointer + * @retval None + */ +void HAL_I2C_MspInit(I2C_HandleTypeDef *hi2c) +{ + GPIO_InitTypeDef GPIO_InitStruct = {0}; + if (hi2c->Instance == I2C1) { + /* USER CODE BEGIN I2C1_MspInit 0 */ + + /* USER CODE END I2C1_MspInit 0 */ + LL_RCC_SetI2CClockSource(LL_RCC_I2C1_CLKSOURCE_PCLK1); + + __HAL_RCC_GPIOB_CLK_ENABLE(); + /**I2C1 GPIO Configuration + PB6 ------> I2C1_SCL + PB7 ------> I2C1_SDA + */ + GPIO_InitStruct.Pin = GPIO_PIN_6 | GPIO_PIN_7; + GPIO_InitStruct.Mode = GPIO_MODE_AF_OD; + GPIO_InitStruct.Pull = GPIO_NOPULL; + GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW; + GPIO_InitStruct.Alternate = GPIO_AF4_I2C1; + HAL_GPIO_Init(GPIOB, &GPIO_InitStruct); + + /* Peripheral clock enable */ + __HAL_RCC_I2C1_CLK_ENABLE(); + /* USER CODE BEGIN I2C1_MspInit 1 */ + + /* USER CODE END I2C1_MspInit 1 */ + } +} + +/** + * @brief I2C MSP De-Initialization + * This function freeze the hardware resources used in this example + * @param hi2c: I2C handle pointer + * @retval None + */ +void HAL_I2C_MspDeInit(I2C_HandleTypeDef *hi2c) +{ + if (hi2c->Instance == I2C1) { + /* USER CODE BEGIN I2C1_MspDeInit 0 */ + + /* USER CODE END I2C1_MspDeInit 0 */ + /* Peripheral clock disable */ + __HAL_RCC_I2C1_CLK_DISABLE(); + + /**I2C1 GPIO Configuration + PB6 ------> I2C1_SCL + PB7 ------> I2C1_SDA + */ + HAL_GPIO_DeInit(GPIOB, GPIO_PIN_6); + + HAL_GPIO_DeInit(GPIOB, GPIO_PIN_7); + + /* USER CODE BEGIN I2C1_MspDeInit 1 */ + + /* USER CODE END I2C1_MspDeInit 1 */ + } +} diff --git a/SAMM/InboardFloor/Src/main.c b/SAMM/InboardFloor/Src/main.c new file mode 100644 index 000000000..a8b3d7675 --- /dev/null +++ b/SAMM/InboardFloor/Src/main.c @@ -0,0 +1,442 @@ +/* USER CODE BEGIN Header */ +/** + ****************************************************************************** + * @file : main.c + * @brief : Main program body + ****************************************************************************** + * @attention + * + * Copyright (c) 2024 STMicroelectronics. + * All rights reserved. + * + * This software is licensed under terms that can be found in the LICENSE file + * in the root directory of this software component. + * If no LICENSE file comes with this software, it is provided AS-IS. + * + ****************************************************************************** + */ +/* USER CODE END Header */ +/* Includes ------------------------------------------------------------------*/ +#include "main.h" + +// #include "crc.h" +// #include "fdcan.h" +#include "NodeID.h" +#include "can_inboardfloor.h" +#include "gpio.h" +#include "i2c.h" +#include "spi.h" + +/* Private includes ----------------------------------------------------------*/ +/* USER CODE BEGIN Includes */ +#include +#include + +#include "VL53L4ED_api.h" +#include "bmi323.h" +// #include "circularBuffer.h" +/* USER CODE END Includes */ + +/* Private typedef -----------------------------------------------------------*/ +/* USER CODE BEGIN PTD */ +#define BMI323_CS_GPIO_Port GPIOA +#define BMI323_CS_Pin GPIO_PIN_4 + +#define TOF_XSHUT_GPIO_Port GPIOA +#define TOF_XSHUT_Pin GPIO_PIN_1 +/* USER CODE END PTD */ + +/* Private define ------------------------------------------------------------*/ +/* USER CODE BEGIN PD */ +#ifdef __GNUC__ +#define PUTCHAR_PROTOTYPE int __io_putchar(int ch) +#else +#define PUTCHAR_PROTOTYPE int fputc(int ch, FILE *f) +#endif + +#define BMI_ACC_ODR 0x7 // Output data rate -> 50 Hz +#define BMI_ACC_RANGE 0x2 // +/- 8g +#define BMI_ACC_MODE 0x7 // High performance mode +#define BMI_ACC_BW 0x0 // Sets cut off freq to ODR/2 +#define BMI_ACC_AVGNUM 0x0 // No averaging + +#define BMI_GYR_ODR 0x7 // Output data rate -> 50 Hz +#define BMI_GYR_RANGE 0x4 // 2000 deg/s (default) +#define BMI_GYR_MODE 0x7 // High performance mode +#define BMI_GYR_BW 0x0 // Sets cut off freq to ODR/2 +#define BMI_GYR_AVGNUM 0x0 // No averaging +/* USER CODE END PD */ + +/* Private macro -------------------------------------------------------------*/ +/* USER CODE BEGIN PM */ +PUTCHAR_PROTOTYPE +{ + ITM_SendChar(ch); + return ch; +} +// CircularBuffer *cb; +/* USER CODE END PM */ + +/* Private variables ---------------------------------------------------------*/ + +/* USER CODE BEGIN PV */ +// FDCAN_RxHeaderTypeDef RxHeader_FDCAN2; +const uint16_t avgcalc_interval = 100; +const uint16_t send_interval = 100; +const float alpha = 0.2; +/* USER CODE END PV */ + +/* Private function prototypes -----------------------------------------------*/ +void SystemClock_Config(void); +/* USER CODE BEGIN PFP */ + +/* USER CODE END PFP */ + +/* Private user code ---------------------------------------------------------*/ +/* USER CODE BEGIN 0 */ + +// TODO: MOVE THIS FUNCTION ELSEWHERE +uint16_t ewa(uint16_t new_value, uint16_t old_value) +{ + if (old_value == 0xFFFF) { + return new_value; + } + return alpha * new_value + (1 - alpha) * old_value; +} + +uint32_t MillisecondsSinceBoot() +{ + uint32_t tick = HAL_GetTick(); + HAL_TickFreqTypeDef freq = HAL_GetTickFreq(); + return tick * freq; +} + +/* USER CODE END 0 */ + +/** + * @brief The application entry point. + * @retval int + */ + +int main(void) +{ + + /* USER CODE BEGIN 1 */ + // cb = circular_buffer_init(64, 68 * sizeof(uint8_t)); + /* USER CODE END 1 */ + + /* MCU Configuration--------------------------------------------------------*/ + + /* Reset of all peripherals, Initializes the Flash interface and the Systick. */ + HAL_Init(); + + /* USER CODE BEGIN Init */ + + /* USER CODE END Init */ + + /* Configure the system clock */ + SystemClock_Config(); + + /* USER CODE BEGIN SysInit */ + + /* USER CODE END SysInit */ + + /* Initialize all configured peripherals */ + MX_GPIO_Init(); + // MX_CRC_Init(); + // MX_FDCAN1_Init(); + // MX_FDCAN2_Init(); + MX_I2C1_Init(); + MX_SPI1_Init(); + + /* USER CODE BEGIN 2 */ + /* USER CODE BEGIN Init */ + InboardFloor_CAN_Init(GRCAN_BUS_DATA); + InboardFloor_CAN_Init(GRCAN_BUS_DATA_SUBNET); + + // HAL_FDCAN_Start(&hfdcan1); + // HAL_FDCAN_Start(&hfdcan2); + // HAL_FDCAN_ActivateNotification(&hfdcan1, FDCAN_IT_RX_FIFO0_NEW_MESSAGE, 0); + // HAL_FDCAN_ActivateNotification(&hfdcan2, FDCAN_IT_RX_FIFO0_NEW_MESSAGE, 0); + + bmi323 bmi323_dev; + HAL_GPIO_WritePin(BMI323_CS_GPIO_Port, BMI323_CS_Pin, GPIO_PIN_SET); + + // Initialize IMU + if (bmi323_init(&bmi323_dev, &hspi1, BMI323_CS_GPIO_Port, BMI323_CS_Pin) != HAL_OK) { + LOGOMATIC("BMI323 initialization failed!\n"); + Error_Handler(); + } + + bmi323_soft_reset(&bmi323_dev); + HAL_Delay(10); + + // Switch to IMU to SPI mode + uint8_t bmi323_mode_tx[4] = {0x00 | 0x80, 0x00, 0x00, 0x00}; + HAL_GPIO_WritePin(BMI323_CS_GPIO_Port, BMI323_CS_Pin, GPIO_PIN_RESET); + HAL_SPI_Transmit(&hspi1, bmi323_mode_tx, 4, HAL_MAX_DELAY); + HAL_GPIO_WritePin(BMI323_CS_GPIO_Port, BMI323_CS_Pin, GPIO_PIN_SET); + HAL_Delay(1); // Short delay after mode switch + + // Set up accelerometer and gyroscope configuration + bmi323_enable_acc(&bmi323_dev, BMI_ACC_MODE, BMI_ACC_AVGNUM, BMI_ACC_BW, BMI_ACC_RANGE, BMI_ACC_ODR); + bmi323_enable_gyro(&bmi323_dev, BMI_GYR_MODE, BMI_GYR_AVGNUM, BMI_GYR_BW, BMI_GYR_RANGE, BMI_GYR_ODR); + + /* Infinite loop */ + // begin VL53L4ED + HAL_Delay(100); // wait for 5ms to power up the device + HAL_GPIO_WritePin(TOF_XSHUT_GPIO_Port, TOF_XSHUT_Pin, GPIO_PIN_RESET); // TOF_L_XSHUT_Pin + // HAL_GPIO_WritePin(GPIOF, GPIO_PIN_1, GPIO_PIN_RESET); //TOF_C_XSHUT_Pin + HAL_Delay(100); // wait for 5ms to reset the device + HAL_GPIO_WritePin(TOF_XSHUT_GPIO_Port, TOF_XSHUT_Pin, GPIO_PIN_SET); // TOF_L_XSHUT_Pin + // HAL_GPIO_WritePin(GPIOF, GPIO_PIN_1, GPIO_PIN_SET); //TOF_C_XSHUT_Pin + HAL_Delay(100); // wait for 5ms to power up the device + + uint16_t status = 0; + uint16_t sensor_id = 0; + VL53L4ED_ResultsData_t results; + uint8_t p_data_ready; + + int TOF_ID = 0x52; + HAL_GPIO_TogglePin(TOF_XSHUT_GPIO_Port, TOF_XSHUT_Pin); + status = VL53L4ED_GetSensorId(TOF_ID, &sensor_id); + LOGOMATIC("VL53L4ED Sensor ID: 0x%04X\n", sensor_id); + + status = VL53L4ED_StartRanging(TOF_ID); + status = VL53L4ED_SetRangeTiming(TOF_ID, 50, 70); + status = VL53L4ED_SetOffset(TOF_ID, 0); // Set offset to 0 for testing, 50 otherwise? + + uint16_t imu_ax = 0xFFFF; + uint16_t imu_ay = 0xFFFF; + uint16_t imu_az = 0xFFFF; + uint16_t imu_gyrx = 0xFFFF; + uint16_t imu_gyry = 0xFFFF; + uint16_t imu_gyrz = 0xFFFF; + uint16_t imu_temp = 0xFFFF; + uint16_t imu_status = 0; + + results.distance_mm = 0xFFFF; + results.ambient_rate_kcps = 0xFFFF; + results.ambient_per_spad_kcps = 0xFFFF; + results.signal_rate_kcps = 0xFFFF; + results.signal_per_spad_kcps = 0xFFFF; + results.number_of_spad = 0xFFFF; + results.sigma_mm = 0xFFFF; + results.range_status = 0xFF; + + uint32_t last_avgcalc_ms = MillisecondsSinceBoot(); + uint32_t last_send_ms = MillisecondsSinceBoot(); + IMU_ToF_Data test_data = {0}; + /* USER CODE END 2 */ + + /* USER CODE BEGIN WHILE */ + while (1) { + /* USER CODE BEGIN 3 */ + uint32_t current_time = MillisecondsSinceBoot(); + + if (current_time - last_avgcalc_ms > avgcalc_interval) { + last_avgcalc_ms = current_time; + + imu_ax = ewa(bmi323_read_acc_x(&bmi323_dev), imu_ax); + imu_ay = ewa(bmi323_read_acc_y(&bmi323_dev), imu_ay); + imu_az = ewa(bmi323_read_acc_z(&bmi323_dev), imu_az); + imu_gyrx = ewa(bmi323_read_gyr_x(&bmi323_dev), imu_gyrx); + imu_gyry = ewa(bmi323_read_gyr_y(&bmi323_dev), imu_gyry); + imu_gyrz = ewa(bmi323_read_gyr_z(&bmi323_dev), imu_gyrz); + imu_temp = ewa(bmi323_read_temp_data(&bmi323_dev), imu_temp); + imu_status = bmi323_read_status(&bmi323_dev); + + float imu_ax_test = ((float)imu_ax) / 4096.f; + float imu_ay_test = ((float)imu_ay) / 4096.f; + float imu_az_test = ((float)imu_az) / 4096.f; + float imu_gyrx_test = ((float)imu_gyrx) / 16.384f; + float imu_gyry_test = ((float)imu_gyry) / 16.384f; + float imu_gyrz_test = ((float)imu_gyrz) / 16.384f; + float imu_temp_test = ((float)imu_temp / 512.f) + 23.0f; + + LOGOMATIC("Acceleration: x = %f g, y = %f g, z = %f g\n", imu_ax_test, imu_ay_test, imu_az_test); + LOGOMATIC("Angular rate: x = %f deg/s, y = %f deg/s, z = %f deg/s\n", imu_gyrx_test, imu_gyry_test, imu_gyrz_test); + LOGOMATIC("IMU temperature: %f", imu_temp_test); + + // begin VL53L4ED + status = VL53L4ED_CheckForDataReady(TOF_ID, &p_data_ready); + if (p_data_ready) { + /* (Mandatory) Clear HW interrupt to restart measurements */ + VL53L4ED_ClearInterrupt(TOF_ID); + + VL53L4ED_ResultsData_t old_results = results; + + /* Read measured distance. RangeStatus = 0 means valid data */ + VL53L4ED_GetResult(TOF_ID, &results); + results.distance_mm = ewa(results.distance_mm, old_results.distance_mm); + results.ambient_rate_kcps = ewa(results.ambient_rate_kcps, old_results.ambient_rate_kcps); + results.ambient_per_spad_kcps = ewa(results.ambient_per_spad_kcps, old_results.ambient_per_spad_kcps); + results.signal_rate_kcps = ewa(results.signal_rate_kcps, old_results.signal_rate_kcps); + results.signal_per_spad_kcps = ewa(results.signal_per_spad_kcps, old_results.signal_per_spad_kcps); + results.number_of_spad = ewa(results.number_of_spad, old_results.number_of_spad); + results.sigma_mm = ewa(results.sigma_mm, old_results.sigma_mm); + + LOGOMATIC("Status = %3u & Internal = %3u, Distance = %5u mm, Signal = %6u kcps/spad\n", results.range_status, status, results.distance_mm - 67, + results.signal_per_spad_kcps); + } else { + HAL_Delay(10); + __disable_irq(); + __enable_irq(); + } + + test_data.bmi323_acc_x = imu_ax; + test_data.bmi323_acc_y = imu_ay; + test_data.bmi323_acc_z = imu_az; + test_data.bmi323_gyro_x = imu_gyrx; + test_data.bmi323_gyro_y = imu_gyry; + test_data.bmi323_gyro_z = imu_gyrz; + test_data.bmi323_temp = imu_temp; + test_data.bmi323_status = imu_status; + + test_data.distance_mm = results.distance_mm; + test_data.ambient_rate_kcps = results.ambient_rate_kcps; + test_data.ambient_per_spad_kcps = results.ambient_per_spad_kcps; + test_data.signal_rate_kcps = results.signal_rate_kcps; + test_data.signal_per_spad_kcps = results.signal_per_spad_kcps; + test_data.number_of_spad = results.number_of_spad; + test_data.sigma_mm = results.sigma_mm; + test_data.range_status = results.range_status; + } + + if (current_time - last_send_ms > send_interval) { + last_send_ms = current_time; + + GRCAN_NODE_ID dest_node = GRCAN_TCM; + GRCAN_MSG_ID msg_id = GRCAN_INBOARDFLOOR_IMU_TOF_DATA; + InboardFloor_CAN_Send(dest_node, msg_id, &test_data); + + if (imu_status != 0) { + LOGOMATIC("IMU is cooked"); + Error_Handler(); + } + if (results.range_status != 0) { + LOGOMATIC("ToF is cooked"); + Error_Handler(); + } + } + + /* USER CODE END 3 */ + } +} + +/** + * @brief System Clock Configuration + * @retval None + */ +void SystemClock_Config(void) +{ + LL_FLASH_SetLatency(LL_FLASH_LATENCY_1); + while (LL_FLASH_GetLatency() != LL_FLASH_LATENCY_1) {} + + LL_PWR_SetRegulVoltageScaling(LL_PWR_REGU_VOLTAGE_SCALE3); + while (LL_PWR_IsActiveFlag_VOS() == 0) {} + LL_RCC_HSI_Enable(); + + /* Wait till HSI is ready */ + while (LL_RCC_HSI_IsReady() != 1) {} + + LL_RCC_HSI_SetCalibTrimming(64); + LL_RCC_HSI_SetDivider(LL_RCC_HSI_DIV_2); + LL_RCC_CSI_Enable(); + + /* Wait till CSI is ready */ + while (LL_RCC_CSI_IsReady() != 1) {} + + LL_RCC_CSI_SetCalibTrimming(32); + LL_RCC_PLL1_SetSource(LL_RCC_PLL1SOURCE_CSI); + LL_RCC_PLL1_SetVCOInputRange(LL_RCC_PLLINPUTRANGE_4_8); + LL_RCC_PLL1_SetVCOOutputRange(LL_RCC_PLLVCORANGE_WIDE); + LL_RCC_PLL1_SetM(1); + LL_RCC_PLL1_SetN(32); + LL_RCC_PLL1_SetP(2); + LL_RCC_PLL1_SetQ(2); + LL_RCC_PLL1_SetR(2); + LL_RCC_PLL1Q_Enable(); + LL_RCC_PLL1_Enable(); + + /* Wait till PLL is ready */ + while (LL_RCC_PLL1_IsReady() != 1) {} + + LL_RCC_SetSysClkSource(LL_RCC_SYS_CLKSOURCE_HSI); + + /* Wait till System clock is ready */ + while (LL_RCC_GetSysClkSource() != LL_RCC_SYS_CLKSOURCE_STATUS_HSI) {} + + LL_RCC_SetAHBPrescaler(LL_RCC_SYSCLK_DIV_1); + LL_RCC_SetAPB1Prescaler(LL_RCC_APB1_DIV_1); + LL_RCC_SetAPB2Prescaler(LL_RCC_APB2_DIV_1); + LL_RCC_SetAPB3Prescaler(LL_RCC_APB3_DIV_1); + LL_SetSystemCoreClock(32000000); + + /* Update the time base */ + if (HAL_InitTick(TICK_INT_PRIORITY) != HAL_OK) { + Error_Handler(); + } +} + +/* USER CODE BEGIN 4 */ +// void HAL_FDCAN_RxFifo0Callback(FDCAN_HandleTypeDef *hfdcan, uint32_t RxFifo0ITs) +// { +// uint8_t RxData[64]; +// HAL_FDCAN_GetRxMessage(hfdcan, FDCAN_RX_FIFO0, &RxHeader_FDCAN2, RxData); +// printf("got messgae\n"); +// //circularBufferPush(cb, RxData, sizeof(RxData)); + +// } +/* USER CODE END 4 */ + +/** + * @brief Period elapsed callback in non blocking mode + * @note This function is called when TIM1 interrupt took place, inside + * HAL_TIM_IRQHandler(). It makes a direct call to HAL_IncTick() to increment + * a global variable "uwTick" used as application time base. + * @param htim : TIM handle + * @retval None + */ +void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim) +{ + /* USER CODE BEGIN Callback 0 */ + + /* USER CODE END Callback 0 */ + if (htim->Instance == TIM1) { + HAL_IncTick(); + } + /* USER CODE BEGIN Callback 1 */ + + /* USER CODE END Callback 1 */ +} + +/** + * @brief This function is executed in case of error occurrence. + * @retval None + */ +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 */ +} + +#ifdef USE_FULL_ASSERT +/** + * @brief Reports the name of the source file and the source line number + * where the assert_param error has occurred. + * @param file: pointer to the source file name + * @param line: assert_param error line source number + * @retval None + */ +void assert_failed(uint8_t *file, uint32_t line) +{ + /* USER CODE BEGIN 6 */ + /* User can add his own implementation to report the file name and line number, + ex: printf("Wrong parameters value: file %s on line %d\r\n", file, line) */ + /* USER CODE END 6 */ +} +#endif /* USE_FULL_ASSERT */ diff --git a/SAMM/InboardFloor/Src/platform.c b/SAMM/InboardFloor/Src/platform.c new file mode 100644 index 000000000..1da0466de --- /dev/null +++ b/SAMM/InboardFloor/Src/platform.c @@ -0,0 +1,113 @@ +/** + * + * Copyright (c) 2023 STMicroelectronics. + * All rights reserved. + * + * This software is licensed under terms that can be found in the LICENSE file + * in the root directory of this software component. + * If no LICENSE file comes with this software, it is provided AS-IS. + * + ****************************************************************************** + */ + +#include "platform.h" + +#include "i2c.h" +#include "main.h" + +extern I2C_HandleTypeDef hi2c1; + +/* +Im legit just using the example stm provides but instead of filling everything out im only copying the platform.c implemintation +for the vl53l4ed sensor. + + +*/ + +uint8_t VL53L4ED_RdDWord(Dev_t dev, uint16_t RegisterAdress, uint32_t *value) +{ + uint8_t status = 0; + uint8_t data_write[2]; + uint8_t data_read[4]; + + data_write[0] = (RegisterAdress >> 8) & 0xFF; + data_write[1] = RegisterAdress & 0xFF; + status = HAL_I2C_Master_Transmit(&hi2c1, dev, data_write, 2, 100); + status = HAL_I2C_Master_Receive(&hi2c1, dev, data_read, 4, 100); + *value = ((data_read[0] << 24) | (data_read[1] << 16) | (data_read[2] << 8) | (data_read[3])); + return status; +} + +uint8_t VL53L4ED_RdWord(uint16_t dev, uint16_t RegisterAdress, uint16_t *value) +{ + uint8_t status = 0; + uint8_t data_write[2]; + uint8_t data_read[2]; + + data_write[0] = (RegisterAdress >> 8) & 0xFF; + data_write[1] = RegisterAdress & 0xFF; + status = HAL_I2C_Master_Transmit(&hi2c1, dev, data_write, 2, 100); + status = HAL_I2C_Master_Receive(&hi2c1, dev, data_read, 2, 100); + *value = (data_read[0] << 8) | (data_read[1]); + return status; +} + +uint8_t VL53L4ED_RdByte(uint16_t dev, uint16_t RegisterAdress, uint8_t *value) +{ + uint8_t status = 0; + uint8_t data_write[2]; + uint8_t data_read[1]; + + data_write[0] = (RegisterAdress >> 8) & 0xFF; + data_write[1] = RegisterAdress & 0xFF; + status = HAL_I2C_Master_Transmit(&hi2c1, dev, data_write, 2, 100); + status = HAL_I2C_Master_Receive(&hi2c1, dev, data_read, 1, 100); + *value = data_read[0]; + return status; +} + +uint8_t VL53L4ED_WrByte(uint16_t dev, uint16_t RegisterAdress, uint8_t value) +{ + uint8_t data_write[3]; + uint8_t status = 0; + + data_write[0] = (RegisterAdress >> 8) & 0xFF; + data_write[1] = RegisterAdress & 0xFF; + data_write[2] = value & 0xFF; + status = HAL_I2C_Master_Transmit(&hi2c1, dev, data_write, 3, 100); + return status; +} + +uint8_t VL53L4ED_WrWord(uint16_t dev, uint16_t RegisterAdress, uint16_t value) +{ + uint8_t data_write[4]; + uint8_t status = 0; + data_write[0] = (RegisterAdress >> 8) & 0xFF; + data_write[1] = RegisterAdress & 0xFF; + data_write[2] = (value >> 8) & 0xFF; + data_write[3] = value & 0xFF; + status = HAL_I2C_Master_Transmit(&hi2c1, dev, data_write, 4, 100); + return status; +} + +uint8_t VL53L4ED_WrDWord(uint16_t dev, uint16_t RegisterAdress, uint32_t value) +{ + uint8_t data_write[6]; + uint8_t status = 0; + + data_write[0] = (RegisterAdress >> 8) & 0xFF; + data_write[1] = RegisterAdress & 0xFF; + data_write[2] = (value >> 24) & 0xFF; + data_write[3] = (value >> 16) & 0xFF; + data_write[4] = (value >> 8) & 0xFF; + data_write[5] = value & 0xFF; + status = HAL_I2C_Master_Transmit(&hi2c1, dev, data_write, 6, 100); + return status; +} + +uint8_t VL53L4ED_WaitMs(Dev_t dev, uint32_t time_ms) +{ + UNUSED(dev); + HAL_Delay(time_ms); + return 0; +} diff --git a/SAMM/InboardFloor/Src/spi.c b/SAMM/InboardFloor/Src/spi.c new file mode 100644 index 000000000..f8bf9a352 --- /dev/null +++ b/SAMM/InboardFloor/Src/spi.c @@ -0,0 +1,135 @@ +/* USER CODE BEGIN Header */ +/** + ****************************************************************************** + * @file spi.c + * @brief This file provides code for the configuration + * of the SPI instances. + ****************************************************************************** + * @attention + * + * Copyright (c) 2024 STMicroelectronics. + * All rights reserved. + * + * This software is licensed under terms that can be found in the LICENSE file + * in the root directory of this software component. + * If no LICENSE file comes with this software, it is provided AS-IS. + * + ****************************************************************************** + */ +/* USER CODE END Header */ +/* Includes ------------------------------------------------------------------*/ +#include "spi.h" + +/* USER CODE BEGIN 0 */ + +/* USER CODE END 0 */ + +SPI_HandleTypeDef hspi1; + +/** + * @brief SPI1 Initialization Function + * @param None + * @retval None + */ +void MX_SPI1_Init(void) +{ + + /* USER CODE BEGIN spi1_Init 0 */ + + /* USER CODE END spi1_Init 0 */ + + /* USER CODE BEGIN spi1_Init 1 */ + + /* USER CODE END spi1_Init 1 */ + hspi1.Instance = SPI1; + hspi1.Init.Mode = SPI_MODE_MASTER; + hspi1.Init.Direction = SPI_DIRECTION_2LINES; + hspi1.Init.DataSize = SPI_DATASIZE_4BIT; + hspi1.Init.CLKPolarity = SPI_POLARITY_HIGH; + hspi1.Init.CLKPhase = SPI_PHASE_1EDGE; + hspi1.Init.NSS = SPI_NSS_SOFT; + hspi1.Init.BaudRatePrescaler = SPI_BAUDRATEPRESCALER_8; + hspi1.Init.FirstBit = SPI_FIRSTBIT_MSB; + hspi1.Init.TIMode = SPI_TIMODE_DISABLE; + hspi1.Init.CRCCalculation = SPI_CRCCALCULATION_DISABLE; + hspi1.Init.CRCPolynomial = 0x13; + hspi1.Init.CRCLength = SPI_CRC_LENGTH_DATASIZE; + hspi1.Init.NSSPMode = SPI_NSS_PULSE_DISABLE; + if (HAL_SPI_Init(&hspi1) != HAL_OK) { + Error_Handler(); + } + /* USER CODE BEGIN spi1_Init 2 */ + + /* USER CODE END spi1_Init 2 */ +} + +/** + * @brief SPI MSP Initialization + * This function configures the hardware resources used in this example + * @param hspi: SPI handle pointer + * @retval None + */ +void HAL_SPI_MspInit(SPI_HandleTypeDef *hspi) +{ + GPIO_InitTypeDef GPIO_InitStruct = {0}; + if (hspi->Instance == SPI1) { + /* USER CODE BEGIN SPI1_MspInit 0 */ + + /* USER CODE END SPI1_MspInit 0 */ + LL_RCC_SetSPIClockSource(LL_RCC_SPI1_CLKSOURCE_PLL1Q); + + /* Peripheral clock enable */ + __HAL_RCC_SPI1_CLK_ENABLE(); + + __HAL_RCC_GPIOA_CLK_ENABLE(); + /**SPI1 GPIO Configuration + PA4 ------> SPI1_NSS + PA5 ------> SPI1_SCK + PA6 ------> SPI1_MISO + PA7 ------> SPI1_MOSI + */ + GPIO_InitStruct.Pin = GPIO_PIN_4 | GPIO_PIN_5 | GPIO_PIN_6 | GPIO_PIN_7; + GPIO_InitStruct.Mode = GPIO_MODE_AF_PP; + GPIO_InitStruct.Pull = GPIO_NOPULL; + GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW; + GPIO_InitStruct.Alternate = GPIO_AF5_SPI1; + HAL_GPIO_Init(GPIOA, &GPIO_InitStruct); + + /* USER CODE BEGIN SPI1_MspInit 1 */ + + /* USER CODE END SPI1_MspInit 1 */ + } +} + +/** + * @brief SPI MSP De-Initialization + * This function freeze the hardware resources used in this example + * @param hspi: SPI handle pointer + * @retval None + */ +void HAL_SPI_MspDeInit(SPI_HandleTypeDef *hspi) +{ + if (hspi->Instance == SPI1) { + /* USER CODE BEGIN SPI1_MspDeInit 0 */ + + /* USER CODE END SPI1_MspDeInit 0 */ + /* Peripheral clock disable */ + __HAL_RCC_SPI1_CLK_DISABLE(); + + /**SPI1 GPIO Configuration + PA4 ------> SPI1_NSS + PA5 ------> SPI1_SCK + PA6 ------> SPI1_MISO + PA7 ------> SPI1_MOSI + */ + HAL_GPIO_DeInit(GPIOA, GPIO_PIN_4 | GPIO_PIN_5 | GPIO_PIN_6 | GPIO_PIN_7); + + /* USER CODE BEGIN SPI1_MspDeInit 1 */ + + /* USER CODE END SPI1_MspDeInit 1 */ + } +} + +/* USER CODE BEGIN 1 */ + +/* USER CODE END 1 */ diff --git a/SAMM/InboardFloor/Src/stm32h5xx_it.c b/SAMM/InboardFloor/Src/stm32h5xx_it.c new file mode 100644 index 000000000..8f4f91774 --- /dev/null +++ b/SAMM/InboardFloor/Src/stm32h5xx_it.c @@ -0,0 +1,213 @@ +/* USER CODE BEGIN Header */ +/** + ****************************************************************************** + * @file stm32h5xx_it.c + * @brief Interrupt Service Routines. + ****************************************************************************** + * @attention + * + * Copyright (c) 2024 STMicroelectronics. + * All rights reserved. + * + * This software is licensed under terms that can be found in the LICENSE file + * in the root directory of this software component. + * If no LICENSE file comes with this software, it is provided AS-IS. + * + ****************************************************************************** + */ +/* USER CODE END Header */ + +/* Includes ------------------------------------------------------------------*/ +#include "stm32h5xx_it.h" + +#include "main.h" +/* Private includes ----------------------------------------------------------*/ +/* USER CODE BEGIN Includes */ +/* USER CODE END Includes */ + +/* Private typedef -----------------------------------------------------------*/ +/* USER CODE BEGIN TD */ + +/* USER CODE END TD */ + +/* Private define ------------------------------------------------------------*/ +/* USER CODE BEGIN PD */ + +/* USER CODE END PD */ + +/* Private macro -------------------------------------------------------------*/ +/* USER CODE BEGIN PM */ + +/* USER CODE END PM */ + +/* Private variables ---------------------------------------------------------*/ +/* USER CODE BEGIN PV */ + +/* USER CODE END PV */ + +/* Private function prototypes -----------------------------------------------*/ +/* USER CODE BEGIN PFP */ + +/* USER CODE END PFP */ + +/* Private user code ---------------------------------------------------------*/ +/* USER CODE BEGIN 0 */ + +/* USER CODE END 0 */ + +/* External variables --------------------------------------------------------*/ +extern TIM_HandleTypeDef htim1; + +/* USER CODE BEGIN EV */ + +/* USER CODE END EV */ + +/******************************************************************************/ +/* Cortex-M4 Processor Interruption and Exception Handlers */ +/******************************************************************************/ +/** + * @brief This function handles Non maskable interrupt. + */ +void NMI_Handler(void) +{ + /* USER CODE BEGIN NonMaskableInt_IRQn 0 */ + + /* USER CODE END NonMaskableInt_IRQn 0 */ + /* USER CODE BEGIN NonMaskableInt_IRQn 1 */ + while (1) {} + /* USER CODE END NonMaskableInt_IRQn 1 */ +} + +/** + * @brief This function handles Hard fault interrupt. + */ +void HardFault_Handler(void) +{ + /* USER CODE BEGIN HardFault_IRQn 0 */ + + /* USER CODE END HardFault_IRQn 0 */ + while (1) { + /* USER CODE BEGIN W1_HardFault_IRQn 0 */ + /* USER CODE END W1_HardFault_IRQn 0 */ + } +} + +/** + * @brief This function handles Memory management fault. + */ +void MemManage_Handler(void) +{ + /* USER CODE BEGIN MemoryManagement_IRQn 0 */ + + /* USER CODE END MemoryManagement_IRQn 0 */ + while (1) { + /* USER CODE BEGIN W1_MemoryManagement_IRQn 0 */ + /* USER CODE END W1_MemoryManagement_IRQn 0 */ + } +} + +/** + * @brief This function handles Prefetch fault, memory access fault. + */ +void BusFault_Handler(void) +{ + /* USER CODE BEGIN BusFault_IRQn 0 */ + + /* USER CODE END BusFault_IRQn 0 */ + while (1) { + /* USER CODE BEGIN W1_BusFault_IRQn 0 */ + /* USER CODE END W1_BusFault_IRQn 0 */ + } +} + +/** + * @brief This function handles Undefined instruction or illegal state. + */ +void UsageFault_Handler(void) +{ + /* USER CODE BEGIN UsageFault_IRQn 0 */ + + /* USER CODE END UsageFault_IRQn 0 */ + while (1) { + /* USER CODE BEGIN W1_UsageFault_IRQn 0 */ + /* USER CODE END W1_UsageFault_IRQn 0 */ + } +} + +/** + * @brief This function handles System service call via SWI instruction. + */ +void SVC_Handler(void) +{ + /* USER CODE BEGIN SVCall_IRQn 0 */ + + /* USER CODE END SVCall_IRQn 0 */ + /* USER CODE BEGIN SVCall_IRQn 1 */ + + /* USER CODE END SVCall_IRQn 1 */ +} + +/** + * @brief This function handles Debug monitor. + */ +void DebugMon_Handler(void) +{ + /* USER CODE BEGIN DebugMonitor_IRQn 0 */ + + /* USER CODE END DebugMonitor_IRQn 0 */ + /* USER CODE BEGIN DebugMonitor_IRQn 1 */ + + /* USER CODE END DebugMonitor_IRQn 1 */ +} + +/** + * @brief This function handles Pendable request for system service. + */ +void PendSV_Handler(void) +{ + /* USER CODE BEGIN PendSV_IRQn 0 */ + + /* USER CODE END PendSV_IRQn 0 */ + /* USER CODE BEGIN PendSV_IRQn 1 */ + + /* USER CODE END PendSV_IRQn 1 */ +} + +/** + * @brief This function handles System tick timer. + */ +void SysTick_Handler(void) +{ + /* USER CODE BEGIN SysTick_IRQn 0 */ + + /* USER CODE END SysTick_IRQn 0 */ + + /* USER CODE BEGIN SysTick_IRQn 1 */ + + /* USER CODE END SysTick_IRQn 1 */ +} + +/******************************************************************************/ +/* STM32H5xx Peripheral Interrupt Handlers */ +/* Add here the Interrupt Handlers for the used peripherals. */ +/* For the available peripheral interrupt handler names, */ +/* please refer to the startup file (startup_stm32h5xx.s). */ +/******************************************************************************/ + +/** + * @brief This function handles TIM1 update interrupt and TIM16 global interrupt. + */ +void TIM1_UP_TIM16_IRQHandler(void) +{ + /* USER CODE BEGIN TIM1_UP_TIM16_IRQn 0 */ + + /* USER CODE END TIM1_UP_TIM16_IRQn 0 */ + HAL_TIM_IRQHandler(&htim1); + /* USER CODE BEGIN TIM1_UP_TIM16_IRQn 1 */ + + /* USER CODE END TIM1_UP_TIM16_IRQn 1 */ +} + +/* USER CODE BEGIN 1 */ + +/* USER CODE END 1 */ diff --git a/SAMM/SuspensionNode/CMakeLists.txt b/SAMM/SuspensionNode/CMakeLists.txt new file mode 100644 index 000000000..7b33c2e96 --- /dev/null +++ b/SAMM/SuspensionNode/CMakeLists.txt @@ -0,0 +1,56 @@ +cmake_minimum_required(VERSION 3.25) + +# Setup compiler settings +set(CMAKE_C_STANDARD 11) +set(CMAKE_C_STANDARD_REQUIRED ON) +set(CMAKE_C_EXTENSIONS ON) + +# Define the build type +if(NOT CMAKE_BUILD_TYPE) + set(CMAKE_BUILD_TYPE "Debug") +endif() + +# what, does in fact not get the filename of somthing but rather the name of the project from the path +get_filename_component(GR_PROJECT_NAME ${CMAKE_CURRENT_SOURCE_DIR} NAME) + +# Enable CMake support for ASM and C languages +enable_language( + C + ASM +) + +# Core project settings +project(${CMAKE_PROJECT_NAME}) + +add_library(${GR_PROJECT_NAME}_USER_CODE INTERFACE) +target_sources( + ${GR_PROJECT_NAME}_USER_CODE + INTERFACE + # Core + Src/crc.c + Src/dma.c + Src/gpio.c + Src/mag.c + Src/main.c + Src/spi.c + Src/stm32h5xx_it.c + Src/can_sus.c + Src/tim.c +) + +target_link_libraries( + ${GR_PROJECT_NAME}_USER_CODE + INTERFACE + CANfigurator + PERIPHERAL_TIMEDCAN_LIB + BitManipulations_Lib + SAMM_IMU_Lib + GRCAN_FANCYLAYER +) + +target_include_directories( + ${GR_PROJECT_NAME}_USER_CODE + INTERFACE + Inc + GRCAN +) diff --git a/SAMM/SuspensionNode/GRCAN/NodeID.h b/SAMM/SuspensionNode/GRCAN/NodeID.h new file mode 100644 index 000000000..c4092405e --- /dev/null +++ b/SAMM/SuspensionNode/GRCAN/NodeID.h @@ -0,0 +1,16 @@ +#include "GRCAN_NODE_ID.h" +#include "Stringification.h" + +#ifndef NODE_ID_H +#define NODE_ID_H + +#ifndef NODE +#pragma message("NODE is not defined. Please compile Suspension Node for a specific target. Defaulting to FL.") +#define LOCAL_GR_ID GRCAN_Suspension_FL +#else +#define LOCAL_GR_ID CONCAT(GRCAN_Suspension_, NODE) +#endif + +#pragma message "Compiling Suspension Node node as " STRINGIFY_MACRO(LOCAL_GR_ID) + +#endif diff --git a/SAMM/SuspensionNode/Inc/can_cfg.h b/SAMM/SuspensionNode/Inc/can_cfg.h new file mode 100644 index 000000000..6e9142a57 --- /dev/null +++ b/SAMM/SuspensionNode/Inc/can_cfg.h @@ -0,0 +1,12 @@ +#ifndef CAN_CFG_H +#define CAN_CFG_H + +#define USECAN1 +#define TX_BUFFER_1_SIZE 16 + +#define USECAN2 +#define TX_BUFFER_2_SIZE 16 + +#define CAN_TIMER_SEND_PERIOD_US 625 + +#endif diff --git a/SAMM/SuspensionNode/Inc/can_sus.h b/SAMM/SuspensionNode/Inc/can_sus.h new file mode 100644 index 000000000..15f14873e --- /dev/null +++ b/SAMM/SuspensionNode/Inc/can_sus.h @@ -0,0 +1,37 @@ +#ifndef CAN_SUS_H +#define CAN_SUS_H + +#include +#include + +#include "GRCAN_FancyLayer.h" +#include "Logomatic.h" +#include "NodeID.h" + +typedef struct { + /* IMU Data */ + /* + uint16_t bmi323_acc_x; + uint16_t bmi323_acc_y; + uint16_t bmi323_acc_z; + uint16_t bmi323_gyro_x; + uint16_t bmi323_gyro_y; + uint16_t bmi323_gyro_z; + uint16_t bmi323_temp; + uint16_t bmi323_status; + */ + + /* Mag Encoder Data */ + uint16_t mag_temp; + uint16_t mag_hysteresis; + uint16_t mag_angle; + int16_t mag_turns; + uint8_t mag_status; +} IMU_Mag_Data; + +void TireTemp_Callback(uint32_t id, void *data, uint32_t size); +void TCM_Callback(uint32_t id, void *data, uint32_t size); +int SusNode_CAN_Init(GRCAN_BUS_ID busID); +bool SusNode_CAN_Send(GRCAN_NODE_ID dest_node, GRCAN_MSG_ID msg_id, void *data); + +#endif diff --git a/SAMM/SuspensionNode/Inc/crc.h b/SAMM/SuspensionNode/Inc/crc.h new file mode 100644 index 000000000..133957e92 --- /dev/null +++ b/SAMM/SuspensionNode/Inc/crc.h @@ -0,0 +1,51 @@ +/* USER CODE BEGIN Header */ +/** + ****************************************************************************** + * @file crc.h + * @brief This file contains all the function prototypes for + * the crc.c file + ****************************************************************************** + * @attention + * + * Copyright (c) 2024 STMicroelectronics. + * All rights reserved. + * + * This software is licensed under terms that can be found in the LICENSE file + * in the root directory of this software component. + * If no LICENSE file comes with this software, it is provided AS-IS. + * + ****************************************************************************** + */ +/* USER CODE END Header */ +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef __CRC_H__ +#define __CRC_H__ + +#ifdef __cplusplus +extern "C" { +#endif + +/* Includes ------------------------------------------------------------------*/ +#include "main.h" + +/* USER CODE BEGIN Includes */ + +/* USER CODE END Includes */ + +extern CRC_HandleTypeDef hcrc; + +/* USER CODE BEGIN Private defines */ + +/* USER CODE END Private defines */ + +void MX_CRC_Init(void); + +/* USER CODE BEGIN Prototypes */ + +/* USER CODE END Prototypes */ + +#ifdef __cplusplus +} +#endif + +#endif /* __CRC_H__ */ diff --git a/SAMM/SuspensionNode/Inc/dma.h b/SAMM/SuspensionNode/Inc/dma.h new file mode 100644 index 000000000..7774831e0 --- /dev/null +++ b/SAMM/SuspensionNode/Inc/dma.h @@ -0,0 +1,51 @@ +/* USER CODE BEGIN Header */ +/** + ****************************************************************************** + * @file dma.h + * @brief This file contains all the function prototypes for + * the dma.c file + ****************************************************************************** + * @attention + * + * Copyright (c) 2024 STMicroelectronics. + * All rights reserved. + * + * This software is licensed under terms that can be found in the LICENSE file + * in the root directory of this software component. + * If no LICENSE file comes with this software, it is provided AS-IS. + * + ****************************************************************************** + */ +/* USER CODE END Header */ +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef __DMA_H__ +#define __DMA_H__ + +#ifdef __cplusplus +extern "C" { +#endif + +/* Includes ------------------------------------------------------------------*/ +#include "main.h" + +/* DMA memory to memory transfer handles -------------------------------------*/ + +/* USER CODE BEGIN Includes */ + +/* USER CODE END Includes */ + +/* USER CODE BEGIN Private defines */ + +/* USER CODE END Private defines */ + +void MX_DMA_Init(void); + +/* USER CODE BEGIN Prototypes */ + +/* USER CODE END Prototypes */ + +#ifdef __cplusplus +} +#endif + +#endif /* __DMA_H__ */ diff --git a/SAMM/SuspensionNode/Inc/gpio.h b/SAMM/SuspensionNode/Inc/gpio.h new file mode 100644 index 000000000..843d4e9e7 --- /dev/null +++ b/SAMM/SuspensionNode/Inc/gpio.h @@ -0,0 +1,48 @@ +/* USER CODE BEGIN Header */ +/** + ****************************************************************************** + * @file gpio.h + * @brief This file contains all the function prototypes for + * the gpio.c file + ****************************************************************************** + * @attention + * + * Copyright (c) 2024 STMicroelectronics. + * All rights reserved. + * + * This software is licensed under terms that can be found in the LICENSE file + * in the root directory of this software component. + * If no LICENSE file comes with this software, it is provided AS-IS. + * + ****************************************************************************** + */ +/* USER CODE END Header */ +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef __GPIO_H__ +#define __GPIO_H__ + +#ifdef __cplusplus +extern "C" { +#endif + +/* Includes ------------------------------------------------------------------*/ +#include "main.h" + +/* USER CODE BEGIN Includes */ + +/* USER CODE END Includes */ + +/* USER CODE BEGIN Private defines */ + +/* USER CODE END Private defines */ + +void MX_GPIO_Init(void); + +/* USER CODE BEGIN Prototypes */ + +/* USER CODE END Prototypes */ + +#ifdef __cplusplus +} +#endif +#endif /*__ GPIO_H__ */ diff --git a/SAMM/SuspensionNode/Inc/mag.h b/SAMM/SuspensionNode/Inc/mag.h new file mode 100644 index 000000000..262696152 --- /dev/null +++ b/SAMM/SuspensionNode/Inc/mag.h @@ -0,0 +1,54 @@ +#ifndef __MAG_H__ +#define __MAG_H__ + +/* Includes ------------------------------------------------------------------*/ +#include "Logomatic.h" +#include "main.h" +#include "spi.h" +#include "can_sus.h" +#include "stm32h5xx.h" + +typedef struct { + SPI_HandleTypeDef *spi_port; + uint16_t chip_id; + GPIO_TypeDef *port; + uint16_t pin; + /* data */ +} mag; + +typedef struct { + uint16_t mag_temp; + uint16_t mag_HANG; + uint16_t mag_angle; + int16_t mag_turns; + uint8_t mag_status; +} mag_values; + +extern mag mag_dev; +extern IMU_Mag_Data test_data; + +HAL_StatusTypeDef mag_init(mag *mag_dev, SPI_HandleTypeDef *spi_port, GPIO_TypeDef *port, uint16_t pin); + +uint16_t mag_transmit(mag *mag_dev, uint16_t data); + +uint16_t mag_read(mag *mag_dev, uint8_t reg); + +void mag_write(mag *mag_dev, uint8_t reg, uint16_t data); + +bool mag_read_device_status(mag *mag_dev); + +uint16_t mag_read_temp(mag *mag_dev); + +uint16_t mag_read_HANG(mag *mag_dev); + +uint16_t mag_read_encoder_angle(mag *mag_dev); + +int16_t mag_read_turns(mag *mag_dev); + +uint8_t check_status(mag *mag_dev); + +void mag_write_error(mag *mag_dev); + +void mag_read_data(void); + +#endif diff --git a/SAMM/SuspensionNode/Inc/main.h b/SAMM/SuspensionNode/Inc/main.h new file mode 100644 index 000000000..36168b86d --- /dev/null +++ b/SAMM/SuspensionNode/Inc/main.h @@ -0,0 +1,88 @@ +/* USER CODE BEGIN Header */ +/** + ****************************************************************************** + * @file : main.h + * @brief : Header for main.c file. + * This file contains the common defines of the application. + ****************************************************************************** + * @attention + * + * Copyright (c) 2024 STMicroelectronics. + * All rights reserved. + * + * This software is licensed under terms that can be found in the LICENSE file + * in the root directory of this software component. + * If no LICENSE file comes with this software, it is provided AS-IS. + * + ****************************************************************************** + */ +/* USER CODE END Header */ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef __MAIN_H +#define __MAIN_H + +#ifdef __cplusplus +extern "C" { +#endif + +/* Includes ------------------------------------------------------------------*/ +#include "stm32h5xx.h" +#include "stm32h5xx_hal.h" +#include "stm32h5xx_hal_dma.h" +#include "stm32h5xx_hal_i2c.h" +#include "stm32h5xx_hal_rcc.h" +#include "stm32h5xx_hal_spi.h" +#include "stm32h5xx_ll_bus.h" +#include "stm32h5xx_ll_cortex.h" +#include "stm32h5xx_ll_crs.h" +#include "stm32h5xx_ll_dma.h" +#include "stm32h5xx_ll_exti.h" +#include "stm32h5xx_ll_gpio.h" +#include "stm32h5xx_ll_i2c.h" +#include "stm32h5xx_ll_lpuart.h" +#include "stm32h5xx_ll_pwr.h" +#include "stm32h5xx_ll_rcc.h" +#include "stm32h5xx_ll_spi.h" +#include "stm32h5xx_ll_system.h" +#include "stm32h5xx_ll_utils.h" + +/* Private includes ----------------------------------------------------------*/ +/* USER CODE BEGIN Includes */ +#include +#include +/* USER CODE END Includes */ + +/* Exported types ------------------------------------------------------------*/ +/* USER CODE BEGIN ET */ + +/* USER CODE END ET */ + +/* Exported constants --------------------------------------------------------*/ +/* USER CODE BEGIN EC */ + +/* USER CODE END EC */ + +/* Exported macro ------------------------------------------------------------*/ +/* USER CODE BEGIN EM */ + +/* USER CODE END EM */ + +/* Exported functions prototypes ---------------------------------------------*/ +void Error_Handler(void); + +/* USER CODE BEGIN EFP */ +uint32_t MillisecondsSinceBoot(void); +/* USER CODE END EFP */ + +/* Private defines -----------------------------------------------------------*/ + +/* USER CODE BEGIN Private defines */ + +/* USER CODE END Private defines */ + +#ifdef __cplusplus +} +#endif + +#endif /* __MAIN_H */ diff --git a/SAMM/SuspensionNode/Inc/spi.h b/SAMM/SuspensionNode/Inc/spi.h new file mode 100644 index 000000000..1aab1cb91 --- /dev/null +++ b/SAMM/SuspensionNode/Inc/spi.h @@ -0,0 +1,53 @@ +/* USER CODE BEGIN Header */ +/** + ****************************************************************************** + * @file spi.h + * @brief This file contains all the function prototypes for + * the spi.c file + ****************************************************************************** + * @attention + * + * Copyright (c) 2024 STMicroelectronics. + * All rights reserved. + * + * This software is licensed under terms that can be found in the LICENSE file + * in the root directory of this software component. + * If no LICENSE file comes with this software, it is provided AS-IS. + * + ****************************************************************************** + */ +/* USER CODE END Header */ +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef __SPI_H__ +#define __SPI_H__ + +#ifdef __cplusplus +extern "C" { +#endif + +/* Includes ------------------------------------------------------------------*/ +#include "main.h" + +/* USER CODE BEGIN Includes */ + +/* USER CODE END Includes */ + +extern SPI_HandleTypeDef hspi1; +extern SPI_HandleTypeDef hspi3; + +/* USER CODE BEGIN Private defines */ + +/* USER CODE END Private defines */ + +void MX_SPI1_Init(void); +void MX_SPI3_Init(void); + +/* USER CODE BEGIN Prototypes */ + +/* USER CODE END Prototypes */ + +#ifdef __cplusplus +} +#endif + +#endif /* __SPI_H__ */ diff --git a/SAMM/SuspensionNode/Inc/stm32h5xx_hal_conf.h b/SAMM/SuspensionNode/Inc/stm32h5xx_hal_conf.h new file mode 100644 index 000000000..fe73a2580 --- /dev/null +++ b/SAMM/SuspensionNode/Inc/stm32h5xx_hal_conf.h @@ -0,0 +1,389 @@ +/* USER CODE BEGIN Header */ +/** + ****************************************************************************** + * @file stm32h5xx_hal_conf.h + * @author MCD Application Team + * @brief HAL configuration file + ****************************************************************************** + * @attention + * + * Copyright (c) 2019 STMicroelectronics. + * All rights reserved. + * + * This software is licensed under terms that can be found in the LICENSE file + * in the root directory of this software component. + * If no LICENSE file comes with this software, it is provided AS-IS. + * + ****************************************************************************** + */ +/* USER CODE END Header */ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef STM32H5xx_HAL_CONF_H +#define STM32H5xx_HAL_CONF_H + +#ifdef __cplusplus +extern "C" { +#endif + +/* Exported types ------------------------------------------------------------*/ +/* Exported constants --------------------------------------------------------*/ + +/* ########################## Module Selection ############################## */ +/** + * @brief This is the list of modules to be used in the HAL driver + */ + +#define HAL_MODULE_ENABLED + +/*#define HAL_ADC_MODULE_ENABLED */ +/*#define HAL_COMP_MODULE_ENABLED */ +/*#define HAL_CORDIC_MODULE_ENABLED */ +#define HAL_CRC_MODULE_ENABLED +/*#define HAL_CRYP_MODULE_ENABLED */ +/*#define HAL_DAC_MODULE_ENABLED */ +#define HAL_FDCAN_MODULE_ENABLED +/*#define HAL_FMAC_MODULE_ENABLED */ +/*#define HAL_HRTIM_MODULE_ENABLED */ +/*#define HAL_IRDA_MODULE_ENABLED */ +/*#define HAL_IWDG_MODULE_ENABLED */ +#define HAL_I2C_MODULE_ENABLED +/*#define HAL_I2S_MODULE_ENABLED */ +/*#define HAL_LPTIM_MODULE_ENABLED */ +/*#define HAL_NAND_MODULE_ENABLED */ +/*#define HAL_NOR_MODULE_ENABLED */ +/*#define HAL_OPAMP_MODULE_ENABLED */ +/*#define HAL_PCD_MODULE_ENABLED */ +/*#define HAL_QSPI_MODULE_ENABLED */ +/*#define HAL_RNG_MODULE_ENABLED */ +/*#define HAL_RTC_MODULE_ENABLED */ +/*#define HAL_SAI_MODULE_ENABLED */ +/*#define HAL_SMARTCARD_MODULE_ENABLED */ +/*#define HAL_SMBUS_MODULE_ENABLED */ +#define HAL_SPI_MODULE_ENABLED +/*#define HAL_SRAM_MODULE_ENABLED */ +#define HAL_TIM_MODULE_ENABLED +/*#define HAL_UART_MODULE_ENABLED */ +/*#define HAL_USART_MODULE_ENABLED */ +/*#define HAL_WWDG_MODULE_ENABLED */ +#define HAL_GPIO_MODULE_ENABLED +#define HAL_EXTI_MODULE_ENABLED +#define HAL_DMA_MODULE_ENABLED +#define HAL_RCC_MODULE_ENABLED +#define HAL_FLASH_MODULE_ENABLED +#define HAL_PWR_MODULE_ENABLED +#define HAL_CORTEX_MODULE_ENABLED + +/* ########################## Register Callbacks selection ############################## */ +/** + * @brief This is the list of modules where register callback can be used + */ +#define USE_HAL_ADC_REGISTER_CALLBACKS 0U +#define USE_HAL_COMP_REGISTER_CALLBACKS 0U +#define USE_HAL_CORDIC_REGISTER_CALLBACKS 0U +#define USE_HAL_CRYP_REGISTER_CALLBACKS 0U +#define USE_HAL_DAC_REGISTER_CALLBACKS 0U +#define USE_HAL_EXTI_REGISTER_CALLBACKS 0U +#define USE_HAL_FDCAN_REGISTER_CALLBACKS 0U +#define USE_HAL_FMAC_REGISTER_CALLBACKS 0U +#define USE_HAL_HRTIM_REGISTER_CALLBACKS 0U +#define USE_HAL_I2C_REGISTER_CALLBACKS 0U +#define USE_HAL_I2S_REGISTER_CALLBACKS 0U +#define USE_HAL_IRDA_REGISTER_CALLBACKS 0U +#define USE_HAL_LPTIM_REGISTER_CALLBACKS 0U +#define USE_HAL_NAND_REGISTER_CALLBACKS 0U +#define USE_HAL_NOR_REGISTER_CALLBACKS 0U +#define USE_HAL_OPAMP_REGISTER_CALLBACKS 0U +#define USE_HAL_PCD_REGISTER_CALLBACKS 0U +#define USE_HAL_QSPI_REGISTER_CALLBACKS 0U +#define USE_HAL_RNG_REGISTER_CALLBACKS 0U +#define USE_HAL_RTC_REGISTER_CALLBACKS 0U +#define USE_HAL_SAI_REGISTER_CALLBACKS 0U +#define USE_HAL_SMARTCARD_REGISTER_CALLBACKS 0U +#define USE_HAL_SMBUS_REGISTER_CALLBACKS 0U +#define USE_HAL_SPI_REGISTER_CALLBACKS 0U +#define USE_HAL_SRAM_REGISTER_CALLBACKS 0U +#define USE_HAL_TIM_REGISTER_CALLBACKS 0U +#define USE_HAL_UART_REGISTER_CALLBACKS 0U +#define USE_HAL_USART_REGISTER_CALLBACKS 0U +#define USE_HAL_WWDG_REGISTER_CALLBACKS 0U + +/* ########################## Oscillator Values adaptation ####################*/ +/** + * @brief Adjust the value of External High Speed oscillator (HSE) used in your application. + * This value is used by the RCC HAL module to compute the system frequency + * (when HSE is used as system clock source, directly or through the PLL). + */ +#if !defined(HSE_VALUE) +#define HSE_VALUE (8000000UL) /*!< Value of the External oscillator in Hz */ +#endif /* HSE_VALUE */ + +#if !defined(HSE_STARTUP_TIMEOUT) +#define HSE_STARTUP_TIMEOUT (100UL) /*!< Time out for HSE start up, in ms */ +#endif /* HSE_STARTUP_TIMEOUT */ + +/** + * @brief Internal Core Speed oscillator (CSI) default value. + * This value is the default CSI range value after Reset. + */ +#if !defined(CSI_VALUE) +#define CSI_VALUE (4000000UL) /*!< Value of the Internal oscillator in Hz*/ +#endif /* CSI_VALUE */ + +/** + * @brief Internal High Speed oscillator (HSI) value. + * This value is used by the RCC HAL module to compute the system frequency + * (when HSI is used as system clock source, directly or through the PLL). + */ +#if !defined(HSI_VALUE) +#define HSI_VALUE (16000000UL) /*!< Value of the Internal oscillator in Hz*/ +#endif /* HSI_VALUE */ + +/** + * @brief Internal High Speed oscillator (HSI48) value for USB FS and RNG. + * This internal oscillator is mainly dedicated to provide a high precision clock to + * the USB peripheral by means of a special Clock Recovery System (CRS) circuitry. + * When the CRS is not used, the HSI48 RC oscillator runs on it default frequency + * which is subject to manufacturing process variations. + */ +#if !defined(HSI48_VALUE) +#define HSI48_VALUE \ + (48000000UL) /*!< Value of the Internal High Speed oscillator for USB FS/RNG in Hz. \ + The real value my vary depending on manufacturing process variations.*/ +#endif /* HSI48_VALUE */ + +/** + * @brief Internal Low Speed oscillator (LSI) value. + */ +#if !defined(LSI_VALUE) +/*!< Value of the Internal Low Speed oscillator in Hz +The real value may vary depending on the variations in voltage and temperature.*/ +#define LSI_VALUE (32000UL) /*!< LSI Typical Value in Hz*/ +#endif /* LSI_VALUE */ +/** + * @brief External Low Speed oscillator (LSE) value. + * This value is used by the UART, RTC HAL module to compute the system frequency + */ +#if !defined(LSE_VALUE) +#define LSE_VALUE (32768UL) /*!< Value of the External Low Speed oscillator in Hz */ +#endif /* LSE_VALUE */ + +#if !defined(LSE_STARTUP_TIMEOUT) +#define LSE_STARTUP_TIMEOUT (5000UL) /*!< Time out for LSE start up, in ms */ +#endif /* LSE_STARTUP_TIMEOUT */ + +/** + * @brief External clock source for I2S and SAI peripherals + * This value is used by the I2S and SAI HAL modules to compute the I2S and SAI clock source + * frequency, this source is inserted directly through I2S_CKIN pad. + */ +#if !defined(EXTERNAL_CLOCK_VALUE) +#define EXTERNAL_CLOCK_VALUE (12288000UL) /*!< Value of the External oscillator in Hz*/ +#endif /* EXTERNAL_CLOCK_VALUE */ + +/* Tip: To avoid modifying this file each time you need to use different HSE, + === you can define the HSE value in your toolchain compiler preprocessor. */ + +/* ########################### System Configuration ######################### */ +/** + * @brief This is the HAL system configuration section + */ + +#define VDD_VALUE (3300UL) /*!< Value of VDD in mv */ +#define TICK_INT_PRIORITY (1UL) /*!< tick interrupt priority (lowest by default) */ +#define USE_RTOS 0U +#define PREFETCH_ENABLE 0U +#define INSTRUCTION_CACHE_ENABLE 1U +#define DATA_CACHE_ENABLE 1U + +/* ########################## Assert Selection ############################## */ +/** + * @brief Uncomment the line below to expanse the "assert_param" macro in the + * HAL drivers code + */ +/* #define USE_FULL_ASSERT 1U */ + +/* ################## SPI peripheral configuration ########################## */ + +/* CRC FEATURE: Use to activate CRC feature inside HAL SPI Driver + * Activated: CRC code is present inside driver + * Deactivated: CRC code cleaned from driver + */ + +#define USE_SPI_CRC 0U + +/* Includes ------------------------------------------------------------------*/ +/** + * @brief Include module's header file + */ + +#ifdef HAL_RCC_MODULE_ENABLED +#include "stm32h5xx_hal_rcc.h" +#endif /* HAL_RCC_MODULE_ENABLED */ + +#ifdef HAL_GPIO_MODULE_ENABLED +#include "stm32h5xx_hal_gpio.h" +#endif /* HAL_GPIO_MODULE_ENABLED */ + +#ifdef HAL_DMA_MODULE_ENABLED +#include "stm32h5xx_hal_dma.h" +#endif /* HAL_DMA_MODULE_ENABLED */ + +#ifdef HAL_CORTEX_MODULE_ENABLED +#include "stm32h5xx_hal_cortex.h" +#endif /* HAL_CORTEX_MODULE_ENABLED */ + +#ifdef HAL_ADC_MODULE_ENABLED +#include "stm32h5xx_hal_adc.h" +#endif /* HAL_ADC_MODULE_ENABLED */ + +#ifdef HAL_COMP_MODULE_ENABLED +#include "stm32h5xx_hal_comp.h" +#endif /* HAL_COMP_MODULE_ENABLED */ + +#ifdef HAL_CORDIC_MODULE_ENABLED +#include "stm32h5xx_hal_cordic.h" +#endif /* HAL_CORDIC_MODULE_ENABLED */ + +#ifdef HAL_CRC_MODULE_ENABLED +#include "stm32h5xx_hal_crc.h" +#endif /* HAL_CRC_MODULE_ENABLED */ + +#ifdef HAL_CRYP_MODULE_ENABLED +#include "stm32h5xx_hal_cryp.h" +#endif /* HAL_CRYP_MODULE_ENABLED */ + +#ifdef HAL_DAC_MODULE_ENABLED +#include "stm32h5xx_hal_dac.h" +#endif /* HAL_DAC_MODULE_ENABLED */ + +#ifdef HAL_EXTI_MODULE_ENABLED +#include "stm32h5xx_hal_exti.h" +#endif /* HAL_EXTI_MODULE_ENABLED */ + +#ifdef HAL_FDCAN_MODULE_ENABLED +#include "stm32h5xx_hal_fdcan.h" +#endif /* HAL_FDCAN_MODULE_ENABLED */ + +#ifdef HAL_FLASH_MODULE_ENABLED +#include "stm32h5xx_hal_flash.h" +#endif /* HAL_FLASH_MODULE_ENABLED */ + +#ifdef HAL_FMAC_MODULE_ENABLED +#include "stm32h5xx_hal_fmac.h" +#endif /* HAL_FMAC_MODULE_ENABLED */ + +#ifdef HAL_HRTIM_MODULE_ENABLED +#include "stm32h5xx_hal_hrtim.h" +#endif /* HAL_HRTIM_MODULE_ENABLED */ + +#ifdef HAL_IRDA_MODULE_ENABLED +#include "stm32h5xx_hal_irda.h" +#endif /* HAL_IRDA_MODULE_ENABLED */ + +#ifdef HAL_IWDG_MODULE_ENABLED +#include "stm32h5xx_hal_iwdg.h" +#endif /* HAL_IWDG_MODULE_ENABLED */ + +#ifdef HAL_I2C_MODULE_ENABLED +#include "stm32h5xx_hal_i2c.h" +#endif /* HAL_I2C_MODULE_ENABLED */ + +#ifdef HAL_I2S_MODULE_ENABLED +#include "stm32h5xx_hal_i2s.h" +#endif /* HAL_I2S_MODULE_ENABLED */ + +#ifdef HAL_LPTIM_MODULE_ENABLED +#include "stm32h5xx_hal_lptim.h" +#endif /* HAL_LPTIM_MODULE_ENABLED */ + +#ifdef HAL_NAND_MODULE_ENABLED +#include "stm32h5xx_hal_nand.h" +#endif /* HAL_NAND_MODULE_ENABLED */ + +#ifdef HAL_NOR_MODULE_ENABLED +#include "stm32h5xx_hal_nor.h" +#endif /* HAL_NOR_MODULE_ENABLED */ + +#ifdef HAL_OPAMP_MODULE_ENABLED +#include "stm32h5xx_hal_opamp.h" +#endif /* HAL_OPAMP_MODULE_ENABLED */ + +#ifdef HAL_PCD_MODULE_ENABLED +#include "stm32h5xx_hal_pcd.h" +#endif /* HAL_PCD_MODULE_ENABLED */ + +#ifdef HAL_PWR_MODULE_ENABLED +#include "stm32h5xx_hal_pwr.h" +#endif /* HAL_PWR_MODULE_ENABLED */ + +#ifdef HAL_QSPI_MODULE_ENABLED +#include "stm32h5xx_hal_qspi.h" +#endif /* HAL_QSPI_MODULE_ENABLED */ + +#ifdef HAL_RNG_MODULE_ENABLED +#include "stm32h5xx_hal_rng.h" +#endif /* HAL_RNG_MODULE_ENABLED */ + +#ifdef HAL_RTC_MODULE_ENABLED +#include "stm32h5xx_hal_rtc.h" +#endif /* HAL_RTC_MODULE_ENABLED */ + +#ifdef HAL_SAI_MODULE_ENABLED +#include "stm32h5xx_hal_sai.h" +#endif /* HAL_SAI_MODULE_ENABLED */ + +#ifdef HAL_SMARTCARD_MODULE_ENABLED +#include "stm32h5xx_hal_smartcard.h" +#endif /* HAL_SMARTCARD_MODULE_ENABLED */ + +#ifdef HAL_SMBUS_MODULE_ENABLED +#include "stm32h5xx_hal_smbus.h" +#endif /* HAL_SMBUS_MODULE_ENABLED */ + +#ifdef HAL_SPI_MODULE_ENABLED +#include "stm32h5xx_hal_spi.h" +#endif /* HAL_SPI_MODULE_ENABLED */ + +#ifdef HAL_SRAM_MODULE_ENABLED +#include "stm32h5xx_hal_sram.h" +#endif /* HAL_SRAM_MODULE_ENABLED */ + +#ifdef HAL_TIM_MODULE_ENABLED +#include "stm32h5xx_hal_tim.h" +#endif /* HAL_TIM_MODULE_ENABLED */ + +#ifdef HAL_UART_MODULE_ENABLED +#include "stm32h5xx_hal_uart.h" +#endif /* HAL_UART_MODULE_ENABLED */ + +#ifdef HAL_USART_MODULE_ENABLED +#include "stm32h5xx_hal_usart.h" +#endif /* HAL_USART_MODULE_ENABLED */ + +#ifdef HAL_WWDG_MODULE_ENABLED +#include "stm32h5xx_hal_wwdg.h" +#endif /* HAL_WWDG_MODULE_ENABLED */ + +/* Exported macro ------------------------------------------------------------*/ +#ifdef USE_FULL_ASSERT +/** + * @brief The assert_param macro is used for function's parameters check. + * @param expr: If expr is false, it calls assert_failed function + * which reports the name of the source file and the source + * line number of the call that failed. + * If expr is true, it returns no value. + * @retval None + */ +#define assert_param(expr) ((expr) ? (void)0U : assert_failed((uint8_t *)__FILE__, __LINE__)) +/* Exported functions ------------------------------------------------------- */ +void assert_failed(uint8_t *file, uint32_t line); +#else +#define assert_param(expr) ((void)0U) +#endif /* USE_FULL_ASSERT */ + +#ifdef __cplusplus +} +#endif + +#endif /* STM32H5xx_HAL_CONF_H */ diff --git a/SAMM/SuspensionNode/Inc/stm32h5xx_it.h b/SAMM/SuspensionNode/Inc/stm32h5xx_it.h new file mode 100644 index 000000000..b44336397 --- /dev/null +++ b/SAMM/SuspensionNode/Inc/stm32h5xx_it.h @@ -0,0 +1,71 @@ +/* USER CODE BEGIN Header */ +/** + ****************************************************************************** + * @file stm32h5xx_it.h + * @brief This file contains the headers of the interrupt handlers. + ****************************************************************************** + * @attention + * + * Copyright (c) 2024 STMicroelectronics. + * All rights reserved. + * + * This software is licensed under terms that can be found in the LICENSE file + * in the root directory of this software component. + * If no LICENSE file comes with this software, it is provided AS-IS. + * + ****************************************************************************** + */ +/* USER CODE END Header */ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef __STM32H5xx_IT_H +#define __STM32H5xx_IT_H + +#ifdef __cplusplus +extern "C" { +#endif + +/* Private includes ----------------------------------------------------------*/ +/* USER CODE BEGIN Includes */ +#include "main.h" +/* USER CODE END Includes */ + +/* Exported types ------------------------------------------------------------*/ +/* USER CODE BEGIN ET */ + +/* USER CODE END ET */ + +/* Exported constants --------------------------------------------------------*/ +/* USER CODE BEGIN EC */ + +/* USER CODE END EC */ + +/* Exported macro ------------------------------------------------------------*/ +/* USER CODE BEGIN EM */ + +/* USER CODE END EM */ + +/* Exported functions prototypes ---------------------------------------------*/ +void NMI_Handler(void); +void HardFault_Handler(void); +void MemManage_Handler(void); +void BusFault_Handler(void); +void UsageFault_Handler(void); +void SVC_Handler(void); +void DebugMon_Handler(void); +void PendSV_Handler(void); +void SysTick_Handler(void); +void TIM1_UP_TIM16_IRQHandler(void); +void TIM3_IRQHandler(void); +/* USER CODE BEGIN EFP */ + +/* USER CODE END EFP */ + +extern TIM_HandleTypeDef htim1; +extern TIM_HandleTypeDef htim3; + +#ifdef __cplusplus +} +#endif + +#endif /* __STM32H5xx_IT_H */ diff --git a/SAMM/SuspensionNode/Inc/tim.h b/SAMM/SuspensionNode/Inc/tim.h new file mode 100644 index 000000000..a3c3067f0 --- /dev/null +++ b/SAMM/SuspensionNode/Inc/tim.h @@ -0,0 +1,52 @@ +/* USER CODE BEGIN Header */ +/** + ****************************************************************************** + * @file tim.h + * @brief This file contains all the function prototypes for + * the tim.c file + ****************************************************************************** + * @attention + * + * Copyright (c) 2026 STMicroelectronics. + * All rights reserved. + * + * This software is licensed under terms that can be found in the LICENSE file + * in the root directory of this software component. + * If no LICENSE file comes with this software, it is provided AS-IS. + * + ****************************************************************************** + */ +/* USER CODE END Header */ +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef __TIM_H__ +#define __TIM_H__ + +#ifdef __cplusplus +extern "C" { +#endif + +/* Includes ------------------------------------------------------------------*/ +#include "main.h" + +/* USER CODE BEGIN Includes */ + +/* USER CODE END Includes */ + +extern TIM_HandleTypeDef htim3; + +/* USER CODE BEGIN Private defines */ + +/* USER CODE END Private defines */ + +void MX_TIM3_Init(void); + +/* USER CODE BEGIN Prototypes */ + +/* USER CODE END Prototypes */ + +#ifdef __cplusplus +} +#endif + +#endif /* __TIM_H__ */ + diff --git a/SAMM/SuspensionNode/Src/can_sus.c b/SAMM/SuspensionNode/Src/can_sus.c new file mode 100644 index 000000000..3f853c96b --- /dev/null +++ b/SAMM/SuspensionNode/Src/can_sus.c @@ -0,0 +1,90 @@ +#include "can_sus.h" + +#include "can_cfg.h" + +static GRCAN_MSG_ID CAN_SUS_MSG_DATA = GRCAN_SUSPENSION_IMU_MAG_DATA; +static GRCAN_NODE_ID localNode = LOCAL_GR_ID; +static GRCAN_BUS_ID mainBus = GRCAN_BUS_DATA; +static GRCAN_BUS_ID subnetBus = GRCAN_BUS_DATA_SUBNET; +static uint32_t data_length = 64; + +uint32_t *forwarded_tire_temp_data = 0; +uint32_t *forwarded_TCM_data = 0; + +// For messages from tire temp +void TireTemp_Callback(uint32_t id, void *data, uint32_t size) +{ + GRCAN_Raw_Send(mainBus, id, data, size); +} + +// For messages from TCM +void TCM_Callback(uint32_t id, void *data, uint32_t size) +{ + GRCAN_Raw_Send(subnetBus, id, data, size); + + GRCAN_Fancy_ID GRCAN_Fancy_ID = {0}; + GRCAN_Fancy_DecodeID(&GRCAN_Fancy_ID, id); + if (GRCAN_Fancy_ID.messageID == GRCAN_PING) { + GRCAN_Fancy_Send(mainBus, GRCAN_Fancy_ID.srcID, GRCAN_PING, data, size); + } +} + +int SusNode_CAN_Init(GRCAN_BUS_ID busID) +{ + int bus = (int)busID; // technically GRCAN_BUS_DATA_SUBNET does not exist, avoid warnings by casting to int + + if (bus != GRCAN_BUS_DATA && bus != GRCAN_BUS_DATA_SUBNET) { + LOGOMATIC("Invalid bus for Suspension Node CAN Init"); + return 0; + } + + GRCAN_BusConfig bus_config = {0}; + GRCAN_SetDefaultBusConfig(&bus_config, bus); + +#if defined(STM32H5) + bus_config.clock_source = GRCAN_CLKSRC_PLL1Q; // should be 180MHz, defaults should work +#endif + + if (bus == GRCAN_BUS_DATA_SUBNET) { + bus_config.fdcan_instance = FDCAN2; + bus_config.rx_callback = TireTemp_Callback; // callback + } else if (bus == GRCAN_BUS_DATA) { + bus_config.fdcan_instance = FDCAN1; + bus_config.rx_callback = TCM_Callback; // callback + } + + // TODO Comment in/out for testing loopback + // bus_config.operating_mode = GRCAN_OPMODE_EXTERNAL_LOOPBACK; + + bool result = GRCAN_InitBus(&bus_config); + + if (!result) { + LOGOMATIC("Failed to intialize Suspension CAN Bus"); + return 0; + } + + GRCAN_SetLocalNodeID(localNode); + + return 1; // success +} + +bool SusNode_CAN_Send(GRCAN_NODE_ID dest_node, GRCAN_MSG_ID msg_id, void *data) +{ + if (data == NULL) { + LOGOMATIC("Suspension Node CAN send: NULL data"); + return false; + } + + if (msg_id != CAN_SUS_MSG_DATA) { + LOGOMATIC("Invalid Suspension Node message ID, defaulting to DATA\n"); + msg_id = (GRCAN_MSG_ID)CAN_SUS_MSG_DATA; + } + + bool result = GRCAN_Fancy_Send(mainBus, dest_node, msg_id, data, data_length); + + if (!result) { + LOGOMATIC("Suspension Node CAN send failed"); + } + + return result; +} diff --git a/SAMM/SuspensionNode/Src/crc.c b/SAMM/SuspensionNode/Src/crc.c new file mode 100644 index 000000000..213510a5d --- /dev/null +++ b/SAMM/SuspensionNode/Src/crc.c @@ -0,0 +1,86 @@ +/* USER CODE BEGIN Header */ +/** + ****************************************************************************** + * @file crc.c + * @brief This file provides code for the configuration + * of the CRC instances. + ****************************************************************************** + * @attention + * + * Copyright (c) 2024 STMicroelectronics. + * All rights reserved. + * + * This software is licensed under terms that can be found in the LICENSE file + * in the root directory of this software component. + * If no LICENSE file comes with this software, it is provided AS-IS. + * + ****************************************************************************** + */ +/* USER CODE END Header */ +/* Includes ------------------------------------------------------------------*/ +#include "crc.h" + +/* USER CODE BEGIN 0 */ + +/* USER CODE END 0 */ + +CRC_HandleTypeDef hcrc; + +/* CRC init function */ +void MX_CRC_Init(void) +{ + + /* USER CODE BEGIN CRC_Init 0 */ + + /* USER CODE END CRC_Init 0 */ + + /* USER CODE BEGIN CRC_Init 1 */ + + /* USER CODE END CRC_Init 1 */ + hcrc.Instance = CRC; + hcrc.Init.DefaultPolynomialUse = DEFAULT_POLYNOMIAL_ENABLE; + hcrc.Init.DefaultInitValueUse = DEFAULT_INIT_VALUE_ENABLE; + hcrc.Init.InputDataInversionMode = CRC_INPUTDATA_INVERSION_NONE; + hcrc.Init.OutputDataInversionMode = CRC_OUTPUTDATA_INVERSION_DISABLE; + hcrc.InputDataFormat = CRC_INPUTDATA_FORMAT_BYTES; + if (HAL_CRC_Init(&hcrc) != HAL_OK) { + Error_Handler(); + } + /* USER CODE BEGIN CRC_Init 2 */ + + /* USER CODE END CRC_Init 2 */ +} + +void HAL_CRC_MspInit(CRC_HandleTypeDef *crcHandle) +{ + + if (crcHandle->Instance == CRC) { + /* USER CODE BEGIN CRC_MspInit 0 */ + + /* USER CODE END CRC_MspInit 0 */ + /* CRC clock enable */ + __HAL_RCC_CRC_CLK_ENABLE(); + /* USER CODE BEGIN CRC_MspInit 1 */ + + /* USER CODE END CRC_MspInit 1 */ + } +} + +void HAL_CRC_MspDeInit(CRC_HandleTypeDef *crcHandle) +{ + + if (crcHandle->Instance == CRC) { + /* USER CODE BEGIN CRC_MspDeInit 0 */ + + /* USER CODE END CRC_MspDeInit 0 */ + /* Peripheral clock disable */ + __HAL_RCC_CRC_CLK_DISABLE(); + /* USER CODE BEGIN CRC_MspDeInit 1 */ + + /* USER CODE END CRC_MspDeInit 1 */ + } +} + +/* USER CODE BEGIN 1 */ + +/* USER CODE END 1 */ diff --git a/SAMM/SuspensionNode/Src/dma.c b/SAMM/SuspensionNode/Src/dma.c new file mode 100644 index 000000000..972b9efea --- /dev/null +++ b/SAMM/SuspensionNode/Src/dma.c @@ -0,0 +1,56 @@ +/* USER CODE BEGIN Header */ +/** + ****************************************************************************** + * @file dma.c + * @brief This file provides code for the configuration + * of all the requested memory to memory DMA transfers. + ****************************************************************************** + * @attention + * + * Copyright (c) 2024 STMicroelectronics. + * All rights reserved. + * + * This software is licensed under terms that can be found in the LICENSE file + * in the root directory of this software component. + * If no LICENSE file comes with this software, it is provided AS-IS. + * + ****************************************************************************** + */ +/* USER CODE END Header */ + +/* Includes ------------------------------------------------------------------*/ +#include "dma.h" + +/* USER CODE BEGIN 0 */ + +/* USER CODE END 0 */ + +/*----------------------------------------------------------------------------*/ +/* Configure DMA */ +/*----------------------------------------------------------------------------*/ + +/* USER CODE BEGIN 1 */ + +/* USER CODE END 1 */ + +/** + * Enable DMA controller clock + */ +void MX_DMA_Init(void) +{ + + /* DMA controller clock enable */ + __HAL_RCC_GPDMA1_CLK_ENABLE(); + + /* DMA interrupt init */ + /* DMA1_Channel1_IRQn interrupt configuration */ + HAL_NVIC_SetPriority(GPDMA1_Channel1_IRQn, 0, 0); + HAL_NVIC_EnableIRQ(GPDMA1_Channel1_IRQn); + /* DMA1_Channel2_IRQn interrupt configuration */ + HAL_NVIC_SetPriority(GPDMA1_Channel2_IRQn, 0, 0); + HAL_NVIC_EnableIRQ(GPDMA1_Channel2_IRQn); +} + +/* USER CODE BEGIN 2 */ + +/* USER CODE END 2 */ diff --git a/SAMM/SuspensionNode/Src/gpio.c b/SAMM/SuspensionNode/Src/gpio.c new file mode 100644 index 000000000..6205c6ee0 --- /dev/null +++ b/SAMM/SuspensionNode/Src/gpio.c @@ -0,0 +1,63 @@ +/* USER CODE BEGIN Header */ +/** + ****************************************************************************** + * @file gpio.c + * @brief This file provides code for the configuration + * of all used GPIO pins. + ****************************************************************************** + * @attention + * + * Copyright (c) 2024 STMicroelectronics. + * All rights reserved. + * + * This software is licensed under terms that can be found in the LICENSE file + * in the root directory of this software component. + * If no LICENSE file comes with this software, it is provided AS-IS. + * + ****************************************************************************** + */ +/* USER CODE END Header */ + +/* Includes ------------------------------------------------------------------*/ +#include "gpio.h" + +/* USER CODE BEGIN 0 */ + +/* USER CODE END 0 */ + +/*----------------------------------------------------------------------------*/ +/* Configure GPIO */ +/*----------------------------------------------------------------------------*/ +/* USER CODE BEGIN 1 */ + +/* USER CODE END 1 */ +/** + * @brief GPIO Initialization Function + * @param None + * @retval None + */ +void MX_GPIO_Init(void) +{ + LL_GPIO_InitTypeDef GPIO_InitStruct = {0}; + /* USER CODE BEGIN MX_GPIO_Init_1 */ + /* USER CODE END MX_GPIO_Init_1 */ + + /* GPIO Ports Clock Enable */ + LL_AHB2_GRP1_EnableClock(LL_AHB2_GRP1_PERIPH_GPIOH); + LL_AHB2_GRP1_EnableClock(LL_AHB2_GRP1_PERIPH_GPIOA); + LL_AHB2_GRP1_EnableClock(LL_AHB2_GRP1_PERIPH_GPIOB); + + /**/ + LL_GPIO_ResetOutputPin(GPIOB, LL_GPIO_PIN_10); + + /**/ + GPIO_InitStruct.Pin = LL_GPIO_PIN_10; + GPIO_InitStruct.Mode = LL_GPIO_MODE_OUTPUT; + GPIO_InitStruct.Speed = LL_GPIO_SPEED_FREQ_LOW; + GPIO_InitStruct.OutputType = LL_GPIO_OUTPUT_PUSHPULL; + GPIO_InitStruct.Pull = LL_GPIO_PULL_NO; + LL_GPIO_Init(GPIOB, &GPIO_InitStruct); + + /* USER CODE BEGIN MX_GPIO_Init_2 */ + /* USER CODE END MX_GPIO_Init_2 */ +} diff --git a/SAMM/SuspensionNode/Src/mag.c b/SAMM/SuspensionNode/Src/mag.c new file mode 100644 index 000000000..2733c8c67 --- /dev/null +++ b/SAMM/SuspensionNode/Src/mag.c @@ -0,0 +1,253 @@ +#include "mag.h" + +#include + +#include "main.h" +#include "stm32h5xx.h" + +#define mag_write_address_msb 22 +#define mag_write_address_lsb 23 + +#define mag_addr_mask 0x3F +#define mag_msb 0xFF00 +#define mag_lsb 0x00FF + +HAL_StatusTypeDef mag_init(mag *mag_dev, SPI_HandleTypeDef *spi_port, GPIO_TypeDef *port, uint16_t pin) +{ + mag_dev->spi_port = spi_port; + mag_dev->port = port; + mag_dev->pin = pin; + + LL_mDelay(20); + + uint16_t null = mag_read(mag_dev, 0x00); + uint16_t error_reg = mag_read(mag_dev, 0x24); + uint16_t status = mag_read(mag_dev, 0x22); + UNUSED(null); // Used for debugging + UNUSED(error_reg); // Used for debugging + + // Check AOK=1 (bit 0) and BIP=0 (bit 1) + // If either not true, return error + /* + if (!((status & 0x0001) || ((status | ~(0x0002)) != 0xFFFF))) { + return HAL_ERROR; + } + */ + + if (!(status & 0x0003)) { + return HAL_ERROR; + } + + mag_write(mag_dev, 0x1E, 0x01); + + return HAL_OK; +} + +uint16_t mag_transmit(mag *mag_dev, uint16_t data) +{ + /* + uint8_t tx_bytes[4] = {(uint8_t)(data >> 8), (uint8_t)(data & 0xFF), 0x00, 0x00}; + uint8_t rx_bytes[4] = {0}; + + HAL_GPIO_WritePin(mag_dev->port, mag_dev->pin, GPIO_PIN_RESET); + LL_mDelay(5); + HAL_StatusTypeDef res = HAL_SPI_TransmitReceive(mag_dev->spi_port, tx_bytes, rx_bytes, 4, HAL_MAX_DELAY); + LL_mDelay(5); + HAL_GPIO_WritePin(mag_dev->port, mag_dev->pin, GPIO_PIN_SET); + + if (res != HAL_OK) { + return 0xFFFF; + } + + return ((uint16_t)rx_bytes[2] << 8) | rx_bytes[3]; + */ + + uint8_t tx_bytes[2] = {(uint8_t)(data >> 8), (uint8_t)(data & 0xFF)}; + uint8_t tx_dummy[2] = {0}; + + uint8_t rx_dummy[2] = {0}; + uint8_t rx_bytes[2] = {0}; + + HAL_GPIO_WritePin(mag_dev->port, mag_dev->pin, GPIO_PIN_RESET); + HAL_StatusTypeDef send_res = HAL_SPI_TransmitReceive(mag_dev->spi_port, tx_bytes, rx_dummy, 2, 100); + HAL_GPIO_WritePin(mag_dev->port, mag_dev->pin, GPIO_PIN_SET); + + if (send_res != HAL_OK) { + return 0xFFFF; + } + + for (int i = 0; i < 40; i++) { + __NOP(); + } + + HAL_GPIO_WritePin(mag_dev->port, mag_dev->pin, GPIO_PIN_RESET); + HAL_StatusTypeDef receive_res = HAL_SPI_TransmitReceive(mag_dev->spi_port, tx_dummy, rx_bytes, 2, 100); + HAL_GPIO_WritePin(mag_dev->port, mag_dev->pin, GPIO_PIN_SET); + + if (receive_res != HAL_OK) { + return 0xFFFF; + } + + uint16_t new_data = ((uint16_t)rx_bytes[0] << 8) | rx_bytes[1]; + + return new_data; +} + +/* +0 +0 (W/R') +addr (6 bits) +data (8 bits) +crc (4 bits -- optional) + +0 +0 +addr +0x00 +crc +*/ + +uint16_t mag_read(mag *mag_dev, uint8_t reg) +{ + uint16_t cmd = (uint16_t)((reg & mag_addr_mask) << 8); // read: bit 14 = 0, address in bits 13:8 + return mag_transmit(mag_dev, cmd); // frame 1: send command, discard response +} + +/* +write cycle: +0 +1 (W/R') +addr (6 bits) +data (8 bits) +crc (4 bits -- optional) +*/ + +void mag_write(mag *mag_dev, uint8_t reg, uint16_t data) +{ + uint16_t msb = ((data & mag_msb) >> 8) | (((uint16_t)reg & mag_addr_mask) << 8) | 0x4000; + + mag_transmit(mag_dev, msb); + + reg += 1; // increment from 0x22 to 0x23 for lsb + + uint16_t lsb = (data & mag_lsb) | (((uint16_t)reg & mag_addr_mask) << 8) | 0x4000; + + mag_transmit(mag_dev, lsb); +} + +// Address 0x22:0x23 (STA)—Device Status +// read bit 0 AOK [0] +bool mag_read_device_status(mag *mag_dev) +{ + uint16_t read = mag_read(mag_dev, 0x22); // 0x22 is device status + return (read & 0x0001); // read aok +} + +// Address 0x28:0x29 (TSEN) — 12 bits +// Difference between junction (internal) temperature and room temperature +uint16_t mag_read_temp(mag *mag_dev) +{ + uint16_t read_temp = mag_read(mag_dev, 0x28); // 0x28 is temp register + uint16_t masked_temp = read_temp & 0x0FFF; + float_t calc_temp = (masked_temp / 8.0f) + 25.0f; // Mask to 12 bits (valid temp data), range is -60 to 180 C + UNUSED(calc_temp); // for debugging + + return ((uint16_t)masked_temp); +} + +// Address 0x30:0x31 (HANG) — 12 bits +// Hysteresis Angle Value (original range is 0 to 360 degrees) +uint16_t mag_read_HANG(mag *mag_dev) +{ + uint16_t read_HANG = mag_read(mag_dev, 0x30); // 0x30 is Hysteresis Angle Value + return ((uint16_t)(read_HANG & 0x0FFF)); // Mask to 12 bits +} + +// Address 0x32:0x33 (ANG15) — 15 bits +// Current Angle Reading (original range is 0 to 360 degrees) +uint16_t mag_read_encoder_angle(mag *mag_dev) +{ + uint16_t read_angle = mag_read(mag_dev, 0x32); // 0x32 is angle register + uint16_t masked_angle = read_angle & 0x7FFF; + float_t calc_angle = masked_angle * (360.0f / 32768.0f); + UNUSED(calc_angle); // for debugging + + return ((uint16_t)(masked_angle)); // Mask to 15 bits (valid angle data) before conversion +} + +// Address 0x2C:02D (TURNS) – 15 bits +// Total number of turns relative to angle observed on power-up +int16_t mag_read_turns(mag *mag_dev) +{ + uint16_t read_turns = mag_read(mag_dev, 0x2C); // 0x2C is turn counter + int parity_bit = read_turns & (0x1000); + UNUSED(parity_bit); // for debugging + + int16_t masked_turns = (int16_t)((read_turns & 0x0FFF) << 4) >> 4; // Mask to 12 bits (valid angle data) + return masked_turns; +} + +/* +TODO: +Check the status of the acc, gyro and temp before returning the values + if they are not ready return 0 + if they are ready return 1 + need to pass by reference the values to be returned + +12 bit angle: 0 EF UV P data(12 bits) -- can use EF for error flag, uv for undervoltage + +0x09 : extended write status +0x0D : extended read status +*/ + +uint8_t check_status(mag *mag_dev) +{ + uint8_t errors = 0; + // Device Error Flags + uint16_t error25 = mag_read(mag_dev, 0x24); + int voltage_err = ((error25 & 0x0C) > 0); + errors += voltage_err * 64; + int magnetic_err = ((error25 & 0x02) > 0); + errors += magnetic_err * 32; + uint16_t error24 = mag_read(mag_dev, 0x24); + int angle_error = ((error24 & 0x02) > 0); + errors += angle_error * 16; + // Device Warning Flags + uint32_t warning27 = mag_read(mag_dev, 0x27); + uint32_t warning26 = mag_read(mag_dev, 0x26); + + int invalid_spi_len = ((warning26 & 0x80) > 0); + errors += invalid_spi_len * 8; + int temp_out_of_range = ((warning27 & 0x40) > 0); + errors += temp_out_of_range * 4; + + int turn_counter_saturated = ((warning27 & 0x01) > 0); + errors += turn_counter_saturated * 2; + int excessive_magnet_vel = ((warning27 & 0x08) > 0); + errors += excessive_magnet_vel; + + // fix-me add LOGOMATIC + if (errors != 0) { + LOGOMATIC("Something is cooked"); + } + return errors; +} + +// Address 0x24:0x25 (ERR)—Device Error Flags +// FIXME: add error handling + +// Address 0x1E:0x1F (CTRL)—Device Control +void mag_write_error(mag *mag_dev) +{ + mag_write(mag_dev, 0x1E, 0x0300); + return; +} +// FIXME: add error flag handling + +void mag_read_data(void) { + test_data.mag_temp = mag_read_temp(&mag_dev); + test_data.mag_hysteresis = mag_read_HANG(&mag_dev); + test_data.mag_angle = mag_read_encoder_angle(&mag_dev); + test_data.mag_turns = mag_read_turns(&mag_dev); + test_data.mag_status = check_status(&mag_dev); +} diff --git a/SAMM/SuspensionNode/Src/main.c b/SAMM/SuspensionNode/Src/main.c new file mode 100644 index 000000000..bc98d671d --- /dev/null +++ b/SAMM/SuspensionNode/Src/main.c @@ -0,0 +1,406 @@ +/* USER CODE BEGIN Header */ +/** + ****************************************************************************** + * @file : main.c + * @brief : Main program body + ****************************************************************************** + * @attention + * + * Copyright (c) 2024 STMicroelectronics. + * All rights reserved. + * + * This software is licensed under terms that can be found in the LICENSE file + * in the root directory of this software component. + * If no LICENSE file comes with this software, it is provided AS-IS. + * + ****************************************************************************** + */ +/* USER CODE END Header */ +/* Includes ------------------------------------------------------------------*/ +#include "main.h" + +// #include "crc.h" +// #include "fdcan.h" +#include "NodeID.h" +#include "can_sus.h" +#include "gpio.h" +#include "spi.h" +#include "stm32h5xx_it.h" + +/* Private includes ----------------------------------------------------------*/ +/* USER CODE BEGIN Includes */ +#include +#include + +// #include "VL53L4ED_api.h" +// #include "bmi323.h" +#include "mag.h" +// #include "circularBuffer.h" +/* USER CODE END Includes */ + +/* Private typedef -----------------------------------------------------------*/ +/* USER CODE BEGIN PTD */ +// #define BMI323_CS_GPIO_Port GPIOA +// #define BMI323_CS_Pin GPIO_PIN_4 +#define MAG_CS_GPIO_Port GPIOB +#define MAG_CS_Pin GPIO_PIN_10 +/* USER CODE END PTD */ + +/* Private define ------------------------------------------------------------*/ +/* USER CODE BEGIN PD */ +#ifdef __GNUC__ +#define PUTCHAR_PROTOTYPE int __io_putchar(int ch) +#else +#define PUTCHAR_PROTOTYPE int fputc(int ch, FILE *f) +#endif + +// #define BMI_ACC_ODR 0x7 // Output data rate -> 50 Hz +// #define BMI_ACC_RANGE 0x2 // +/- 8g +// #define BMI_ACC_MODE 0x7 // High performance mode +// #define BMI_ACC_BW 0x0 // Sets cut off freq to ODR/2 +// #define BMI_ACC_AVGNUM 0x0 // No averaging + +// #define BMI_GYR_ODR 0x7 // Output data rate -> 50 Hz +// #define BMI_GYR_RANGE 0x4 // 2000 deg/s (default) +// #define BMI_GYR_MODE 0x7 // High performance mode +// #define BMI_GYR_BW 0x0 // Sets cut off freq to ODR/2 +// #define BMI_GYR_AVGNUM 0x0 // No averaging + +/* USER CODE END PD */ + +/* Private macro -------------------------------------------------------------*/ +/* USER CODE BEGIN PM */ +PUTCHAR_PROTOTYPE +{ + ITM_SendChar(ch); + return ch; +} +// CircularBuffer *cb; +/* USER CODE END PM */ + +/* Private variables ---------------------------------------------------------*/ + +/* USER CODE BEGIN PV */ +// FDCAN_RxHeaderTypeDef RxHeader_FDCAN2; +const uint16_t avgcalc_interval = 1; +const uint16_t send_interval = 30; +const float alpha = 0.2; +static bool ewa_signed_initialization = false; +/* USER CODE END PV */ + +/* Private function prototypes -----------------------------------------------*/ +void SystemClock_Config(void); +/* USER CODE BEGIN PFP */ + +/* USER CODE END PFP */ + +/* Private user code ---------------------------------------------------------*/ +/* USER CODE BEGIN 0 */ + +uint16_t ewa_u(uint16_t new_value, uint16_t old_value) +{ + float new_value_f = (float)new_value; + float old_value_f = (float)old_value; + + if (old_value == 0xFFFF) { + return new_value; + } + return (uint16_t)(alpha * new_value_f + (1.0f - alpha) * old_value_f); +} + +int16_t ewa_i(int16_t new_value, int16_t old_value) +{ + float new_value_f = (float)new_value; + float old_value_f = (float)old_value; + + if (!ewa_signed_initialization) { + ewa_signed_initialization = true; + return new_value; + } + + return (int16_t)(alpha * new_value_f + (1.0f - alpha) * old_value_f); +} + +uint32_t MillisecondsSinceBoot() +{ + return HAL_GetTick() * HAL_GetTickFreq(); +} + +mag mag_dev = {0}; +IMU_Mag_Data test_data = {0}; +/* USER CODE END 0 */ + +/** + * @brief The application entry point. + * @retval int + */ +int main(void) +{ + + /* USER CODE BEGIN 1 */ + // cb = circular_buffer_init(64, 68 * sizeof(uint8_t)); + /* USER CODE END 1 */ + + /* MCU Configuration--------------------------------------------------------*/ + + /* Reset of all peripherals, Initializes the Flash interface and the Systick. */ + HAL_Init(); + + /* USER CODE BEGIN Init */ + /* USER CODE END Init */ + + /* Configure the system clock */ + SystemClock_Config(); + + /* USER CODE BEGIN SysInit */ + + /* USER CODE END SysInit */ + + /* Initialize all configured peripherals */ + MX_GPIO_Init(); + // MX_CRC_Init(); + // MX_FDCAN1_Init(); + // MX_FDCAN2_Init(); + MX_SPI1_Init(); + MX_SPI3_Init(); + /* USER CODE BEGIN 2 */ + SusNode_CAN_Init(GRCAN_BUS_DATA); + SusNode_CAN_Init(GRCAN_BUS_DATA_SUBNET); + // HAL_FDCAN_Start(&hfdcan1); + // HAL_FDCAN_Start(&hfdcan2); + // HAL_FDCAN_ActivateNotification(&hfdcan1, FDCAN_IT_RX_FIFO0_NEW_MESSAGE, 0); + // HAL_FDCAN_ActivateNotification(&hfdcan2, FDCAN_IT_RX_FIFO0_NEW_MESSAGE, 0); + + // bmi323 bmi323_dev; + // HAL_GPIO_WritePin(BMI323_CS_GPIO_Port, BMI323_CS_Pin, GPIO_PIN_SET); + + /* + // Initialize IMU + if (bmi323_init(&bmi323_dev, &hspi1, BMI323_CS_GPIO_Port, BMI323_CS_Pin) != HAL_OK) { + LOGOMATIC("BMI323 initialization failed!\n"); + Error_Handler(); + } + + + bmi323_soft_reset(&bmi323_dev); + HAL_Delay(10); + + // Switch to IMU to SPI mode + uint8_t bmi323_mode_tx[4] = {0x00 | 0x80, 0x00, 0x00, 0x00}; + HAL_GPIO_WritePin(BMI323_CS_GPIO_Port, BMI323_CS_Pin, GPIO_PIN_RESET); + HAL_SPI_Transmit(&hspi1, bmi323_mode_tx, 4, HAL_MAX_DELAY); + HAL_GPIO_WritePin(BMI323_CS_GPIO_Port, BMI323_CS_Pin, GPIO_PIN_SET); + HAL_Delay(1); // Short delay after mode switch + + // Set up accelerometer and gyroscope configuration + bmi323_enable_acc(&bmi323_dev, BMI_ACC_MODE, BMI_ACC_AVGNUM, BMI_ACC_BW, BMI_ACC_RANGE, BMI_ACC_ODR); + bmi323_enable_gyro(&bmi323_dev, BMI_GYR_MODE, BMI_GYR_AVGNUM, BMI_GYR_BW, BMI_GYR_RANGE, BMI_GYR_ODR); + */ + + HAL_GPIO_WritePin(MAG_CS_GPIO_Port, MAG_CS_Pin, GPIO_PIN_SET); + + HAL_StatusTypeDef init_status = mag_init(&mag_dev, &hspi3, MAG_CS_GPIO_Port, MAG_CS_Pin); + + // Initialize magnetic encoder + if (init_status != HAL_OK) { + LOGOMATIC("MAG initialization failed!\n"); // logomatic does NOT work for SAMM lol + Error_Handler(); + } + + HAL_TIM_Base_Start_IT(&htim3); + + /* USER CODE BEGIN WHILE */ + + // uint16_t imu_ax = 0xFFFF; + // uint16_t imu_ay = 0xFFFF; + // uint16_t imu_az = 0xFFFF; + // uint16_t imu_gyrx = 0xFFFF; + // uint16_t imu_gyry = 0xFFFF; + // uint16_t imu_gyrz = 0xFFFF; + // uint16_t imu_temp = 0xFFFF; + // uint16_t imu_status = 0; + uint16_t mag_temp = 0xFFFF; + uint16_t mag_hysteresis = 0xFFFF; + uint16_t mag_angle = 0xFFFF; + int16_t mag_turns = 0; + uint8_t mag_status = 0; + + uint32_t mssinceboot = MillisecondsSinceBoot(); + + uint32_t last_avgcalc_ms = mssinceboot; + uint32_t last_send_ms = mssinceboot; + + while (1) { + uint32_t current_time = MillisecondsSinceBoot(); + + /* + imu_ax = ewa_u(bmi323_read_acc_x(&bmi323_dev), imu_ax); + imu_ay = ewa_u(bmi323_read_acc_y(&bmi323_dev), imu_ay); + imu_az = ewa_u(bmi323_read_acc_z(&bmi323_dev), imu_az); + imu_gyrx = ewa_u(bmi323_read_gyr_x(&bmi323_dev), imu_gyrx); + imu_gyry = ewa_u(bmi323_read_gyr_y(&bmi323_dev), imu_gyry); + imu_gyrz = ewa_u(bmi323_read_gyr_z(&bmi323_dev), imu_gyrz); + imu_temp = ewa_u(bmi323_read_temp_data(&bmi323_dev), imu_temp); + imu_status = bmi323_read_status(&bmi323_dev); + + float imu_ax_test = ((float)imu_ax) / 4096.f; + float imu_ay_test = ((float)imu_ay) / 4096.f; + float imu_az_test = ((float)imu_az) / 4096.f; + float imu_gyrx_test = ((float)imu_gyrx) / 16.384f; + float imu_gyry_test = ((float)imu_gyry) / 16.384f; + float imu_gyrz_test = ((float)imu_gyrz) / 16.384f; + float imu_temp_test = ((float)imu_temp / 512.f) + 23.0f; + */ + + mag_temp = ewa_u(test_data.mag_temp, mag_temp); + mag_hysteresis = ewa_u(test_data.mag_hysteresis, mag_hysteresis); + mag_angle = ewa_u(test_data.mag_angle, mag_angle); + mag_turns = ewa_i(test_data.mag_turns, mag_turns); + mag_status = test_data.mag_status; + + // uint8_t buffer[8] = {0}; + // buffer[0] = (angle >> 8) & 0xFF; + // buffer[1] = angle & 0xFF; + + // buffer[2] = temp; + + // buffer[3] = (turns >> 8) & 0xFF; + // buffer[4] = turns & 0xFF; + + // // status + // buffer[5] = bad; + // buffer[6] = 0x00; + // buffer[7] = 0x00; + + /* + test_data.bmi323_acc_x = imu_ax; + test_data.bmi323_acc_y = imu_ay; + test_data.bmi323_acc_z = imu_az; + test_data.bmi323_gyro_x = imu_gyrx; + test_data.bmi323_gyro_y = imu_gyry; + test_data.bmi323_gyro_z = imu_gyrz; + test_data.bmi323_temp = imu_temp; + test_data.bmi323_status = imu_status; + */ + + test_data.mag_angle = mag_angle; + test_data.mag_temp = mag_temp; + test_data.mag_turns = mag_turns; + test_data.mag_status = mag_status; + test_data.mag_hysteresis = mag_hysteresis; + + if (current_time - last_send_ms > send_interval) { + + last_send_ms = current_time; + GRCAN_NODE_ID test_dest_node = GRCAN_TCM; + GRCAN_MSG_ID test_msg_id = GRCAN_SUSPENSION_IMU_MAG_DATA; + SusNode_CAN_Send(test_dest_node, test_msg_id, &test_data); + + /* + if (imu_status != 0) { + LOGOMATIC("IMU is cooked"); + Error_Handler(); + } + */ + + if (mag_status != 0) { + LOGOMATIC("Mag is cooked"); + mag_write_error(&mag_dev); + } + } + } + /* USER CODE END 3 */ +} + +/** + * @brief System Clock Configuration + * @retval None + */ +void SystemClock_Config(void) +{ + LL_FLASH_SetLatency(LL_FLASH_LATENCY_5); + while (LL_FLASH_GetLatency() != LL_FLASH_LATENCY_5) {} + + LL_PWR_SetRegulVoltageScaling(LL_PWR_REGU_VOLTAGE_SCALE1); + while (LL_PWR_IsActiveFlag_VOS() == 0) {} + LL_RCC_HSI_Enable(); + + /* Wait till HSI is ready */ + while (LL_RCC_HSI_IsReady() != 1) {} + + LL_RCC_HSI_SetCalibTrimming(64); + LL_RCC_HSI_SetDivider(LL_RCC_HSI_DIV_1); + LL_RCC_PLL1_SetSource(LL_RCC_PLL1SOURCE_HSI); + LL_RCC_PLL1_SetVCOInputRange(LL_RCC_PLLINPUTRANGE_8_16); + LL_RCC_PLL1_SetVCOOutputRange(LL_RCC_PLLVCORANGE_WIDE); + LL_RCC_PLL1_SetM(4); + LL_RCC_PLL1_SetN(22); + LL_RCC_PLL1_SetP(2); + LL_RCC_PLL1_SetQ(15); + LL_RCC_PLL1_SetR(2); + LL_RCC_PLL1Q_Enable(); + LL_RCC_PLL1P_Enable(); + LL_RCC_PLL1FRACN_Enable(); + LL_RCC_PLL1_SetFRACN(4096); + LL_RCC_PLL1_Enable(); + + /* Wait till PLL is ready */ + while (LL_RCC_PLL1_IsReady() != 1) {} + + LL_RCC_SetSysClkSource(LL_RCC_SYS_CLKSOURCE_PLL1); + + /* Wait till System clock is ready */ + while (LL_RCC_GetSysClkSource() != LL_RCC_SYS_CLKSOURCE_STATUS_PLL1) {} + + LL_RCC_SetAHBPrescaler(LL_RCC_SYSCLK_DIV_1); + LL_RCC_SetAPB1Prescaler(LL_RCC_APB1_DIV_1); + LL_RCC_SetAPB2Prescaler(LL_RCC_APB2_DIV_1); + LL_RCC_SetAPB3Prescaler(LL_RCC_APB3_DIV_1); + LL_SetSystemCoreClock(180000000); + + /* Update the time base */ + if (HAL_InitTick(TICK_INT_PRIORITY) != HAL_OK) { + Error_Handler(); + } +} + +/* USER CODE BEGIN 4 */ +// void HAL_FDCAN_RxFifo0Callback(FDCAN_HandleTypeDef *hfdcan, uint32_t RxFifo0ITs) +// { +// uint8_t RxData[64]; +// HAL_FDCAN_GetRxMessage(hfdcan, FDCAN_RX_FIFO0, &RxHeader_FDCAN2, RxData); +// printf("got messgae\n"); +// //circularBufferPush(cb, RxData, sizeof(RxData)); + +// } +/* USER CODE END 4 */ + +/** + * @brief This function is executed in case of error occurrence. + * @retval None + */ +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 */ +} + +#ifdef USE_FULL_ASSERT +/** + * @brief Reports the name of the source file and the source line number + * where the assert_param error has occurred. + * @param file: pointer to the source file name + * @param line: assert_param error line source number + * @retval None + */ +void assert_failed(uint8_t *file, uint32_t line) +{ + /* USER CODE BEGIN 6 */ + /* User can add his own implementation to report the file name and line number, + ex: printf("Wrong parameters value: file %s on line %d\r\n", file, line) */ + /* USER CODE END 6 */ +} +#endif /* USE_FULL_ASSERT */ diff --git a/SAMM/SuspensionNode/Src/spi.c b/SAMM/SuspensionNode/Src/spi.c new file mode 100644 index 000000000..fc7c706c7 --- /dev/null +++ b/SAMM/SuspensionNode/Src/spi.c @@ -0,0 +1,248 @@ +/* USER CODE BEGIN Header */ +/** + ****************************************************************************** + * @file spi.c + * @brief This file provides code for the configuration + * of the SPI instances. + ****************************************************************************** + * @attention + * + * Copyright (c) 2024 STMicroelectronics. + * All rights reserved. + * + * This software is licensed under terms that can be found in the LICENSE file + * in the root directory of this software component. + * If no LICENSE file comes with this software, it is provided AS-IS. + * + ****************************************************************************** + */ +/* USER CODE END Header */ +/* Includes ------------------------------------------------------------------*/ +#include "spi.h" + +/* USER CODE BEGIN 0 */ + +/* USER CODE END 0 */ + +SPI_HandleTypeDef hspi1; +SPI_HandleTypeDef hspi3; + +/** + * @brief SPI1 Initialization Function + * @param None + * @retval None + */ +void MX_SPI1_Init(void) +{ + + /* USER CODE BEGIN SPI1_Init 0 */ + + /* USER CODE END SPI1_Init 0 */ + + /* USER CODE BEGIN SPI1_Init 1 */ + + /* USER CODE END SPI1_Init 1 */ + /* SPI1 parameter configuration*/ + hspi1.Instance = SPI1; + hspi1.Init.Mode = SPI_MODE_MASTER; + hspi1.Init.Direction = SPI_DIRECTION_2LINES; + hspi1.Init.DataSize = SPI_DATASIZE_8BIT; + hspi1.Init.CLKPolarity = SPI_POLARITY_HIGH; + hspi1.Init.CLKPhase = SPI_PHASE_1EDGE; + hspi1.Init.NSS = SPI_NSS_SOFT; + hspi1.Init.BaudRatePrescaler = SPI_BAUDRATEPRESCALER_8; + hspi1.Init.FirstBit = SPI_FIRSTBIT_MSB; + hspi1.Init.TIMode = SPI_TIMODE_DISABLE; + hspi1.Init.CRCCalculation = SPI_CRCCALCULATION_DISABLE; + hspi1.Init.CRCPolynomial = 0x13; + hspi1.Init.NSSPMode = SPI_NSS_PULSE_ENABLE; + hspi1.Init.NSSPolarity = SPI_NSS_POLARITY_LOW; + hspi1.Init.FifoThreshold = SPI_FIFO_THRESHOLD_01DATA; + hspi1.Init.MasterSSIdleness = SPI_MASTER_SS_IDLENESS_00CYCLE; + hspi1.Init.MasterInterDataIdleness = SPI_MASTER_INTERDATA_IDLENESS_00CYCLE; + hspi1.Init.MasterReceiverAutoSusp = SPI_MASTER_RX_AUTOSUSP_DISABLE; + hspi1.Init.MasterKeepIOState = SPI_MASTER_KEEP_IO_STATE_DISABLE; + hspi1.Init.IOSwap = SPI_IO_SWAP_DISABLE; + hspi1.Init.ReadyMasterManagement = SPI_RDY_MASTER_MANAGEMENT_INTERNALLY; + hspi1.Init.ReadyPolarity = SPI_RDY_POLARITY_HIGH; + if (HAL_SPI_Init(&hspi1) != HAL_OK) { + Error_Handler(); + } + /* USER CODE BEGIN SPI1_Init 2 */ + + /* USER CODE END SPI1_Init 2 */ +} + +/** + * @brief SPI3 Initialization Function + * @param None + * @retval None + */ +void MX_SPI3_Init(void) +{ + + /* USER CODE BEGIN SPI3_Init 0 */ + + /* USER CODE END SPI3_Init 0 */ + + /* USER CODE BEGIN SPI3_Init 1 */ + + /* USER CODE END SPI3_Init 1 */ + /* SPI3 parameter configuration*/ + hspi3.Instance = SPI3; + hspi3.Init.Mode = SPI_MODE_MASTER; + hspi3.Init.Direction = SPI_DIRECTION_2LINES; + hspi3.Init.DataSize = SPI_DATASIZE_8BIT; + hspi3.Init.CLKPolarity = SPI_POLARITY_HIGH; + hspi3.Init.CLKPhase = SPI_PHASE_2EDGE; + hspi3.Init.NSS = SPI_NSS_SOFT; + hspi3.Init.BaudRatePrescaler = SPI_BAUDRATEPRESCALER_8; + hspi3.Init.FirstBit = SPI_FIRSTBIT_MSB; + hspi3.Init.TIMode = SPI_TIMODE_DISABLE; + hspi3.Init.CRCCalculation = SPI_CRCCALCULATION_DISABLE; + hspi3.Init.CRCPolynomial = 0x13; + hspi3.Init.NSSPMode = SPI_NSS_PULSE_DISABLE; + hspi3.Init.NSSPolarity = SPI_NSS_POLARITY_LOW; + hspi3.Init.FifoThreshold = SPI_FIFO_THRESHOLD_01DATA; + hspi3.Init.MasterSSIdleness = SPI_MASTER_SS_IDLENESS_00CYCLE; + hspi3.Init.MasterInterDataIdleness = SPI_MASTER_INTERDATA_IDLENESS_00CYCLE; + hspi3.Init.MasterReceiverAutoSusp = SPI_MASTER_RX_AUTOSUSP_DISABLE; + hspi3.Init.MasterKeepIOState = SPI_MASTER_KEEP_IO_STATE_DISABLE; + hspi3.Init.IOSwap = SPI_IO_SWAP_DISABLE; + hspi3.Init.ReadyMasterManagement = SPI_RDY_MASTER_MANAGEMENT_INTERNALLY; + hspi3.Init.ReadyPolarity = SPI_RDY_POLARITY_HIGH; + if (HAL_SPI_Init(&hspi3) != HAL_OK) { + Error_Handler(); + } + /* USER CODE BEGIN SPI3_Init 2 */ + + /* USER CODE END SPI3_Init 2 */ +} + +/** + * @brief SPI MSP Initialization + * This function configures the hardware resources used in this example + * @param hspi: SPI handle pointer + * @retval None + */ +void HAL_SPI_MspInit(SPI_HandleTypeDef *hspi) +{ + GPIO_InitTypeDef GPIO_InitStruct = {0}; + if (hspi->Instance == SPI1) { + /* USER CODE BEGIN SPI1_MspInit 0 */ + + /* USER CODE END SPI1_MspInit 0 */ + LL_RCC_SetSPIClockSource(LL_RCC_SPI1_CLKSOURCE_PLL1Q); + + /* Peripheral clock enable */ + __HAL_RCC_SPI1_CLK_ENABLE(); + + __HAL_RCC_GPIOA_CLK_ENABLE(); + /**SPI1 GPIO Configuration + PA4 ------> SPI1_NSS + PA5 ------> SPI1_SCK + PA6 ------> SPI1_MISO + PA7 ------> SPI1_MOSI + */ + GPIO_InitStruct.Pin = GPIO_PIN_4 | GPIO_PIN_5 | GPIO_PIN_6 | GPIO_PIN_7; + GPIO_InitStruct.Mode = GPIO_MODE_AF_PP; + GPIO_InitStruct.Pull = GPIO_NOPULL; + GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW; + GPIO_InitStruct.Alternate = GPIO_AF5_SPI1; + HAL_GPIO_Init(GPIOA, &GPIO_InitStruct); + + /* USER CODE BEGIN SPI1_MspInit 1 */ + + /* USER CODE END SPI1_MspInit 1 */ + } else if (hspi->Instance == SPI3) { + /* USER CODE BEGIN SPI3_MspInit 0 */ + + /* USER CODE END SPI3_MspInit 0 */ + + LL_RCC_SetSPIClockSource(LL_RCC_SPI3_CLKSOURCE_PLL1Q); + + /* Peripheral clock enable */ + __HAL_RCC_SPI3_CLK_ENABLE(); + + __HAL_RCC_GPIOB_CLK_ENABLE(); + /**SPI3 GPIO Configuration + PB0 ------> SPI3_MISO + PB1 ------> SPI3_SCK + PB2 ------> SPI3_MOSI + */ + GPIO_InitStruct.Pin = GPIO_PIN_0; + GPIO_InitStruct.Mode = GPIO_MODE_AF_PP; + GPIO_InitStruct.Pull = GPIO_NOPULL; + GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW; + GPIO_InitStruct.Alternate = GPIO_AF5_SPI3; + HAL_GPIO_Init(GPIOB, &GPIO_InitStruct); + + GPIO_InitStruct.Pin = GPIO_PIN_1; + GPIO_InitStruct.Mode = GPIO_MODE_AF_PP; + GPIO_InitStruct.Pull = GPIO_NOPULL; + GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW; + GPIO_InitStruct.Alternate = GPIO_AF4_SPI3; + HAL_GPIO_Init(GPIOB, &GPIO_InitStruct); + + GPIO_InitStruct.Pin = GPIO_PIN_2; + GPIO_InitStruct.Mode = GPIO_MODE_AF_PP; + GPIO_InitStruct.Pull = GPIO_NOPULL; + GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW; + GPIO_InitStruct.Alternate = GPIO_AF7_SPI3; + HAL_GPIO_Init(GPIOB, &GPIO_InitStruct); + + /* USER CODE BEGIN SPI3_MspInit 1 */ + + /* USER CODE END SPI3_MspInit 1 */ + } +} + +/** + * @brief SPI MSP De-Initialization + * This function freeze the hardware resources used in this example + * @param hspi: SPI handle pointer + * @retval None + */ +void HAL_SPI_MspDeInit(SPI_HandleTypeDef *hspi) +{ + if (hspi->Instance == SPI1) { + /* USER CODE BEGIN SPI1_MspDeInit 0 */ + + /* USER CODE END SPI1_MspDeInit 0 */ + /* Peripheral clock disable */ + __HAL_RCC_SPI1_CLK_DISABLE(); + + /**SPI1 GPIO Configuration + PA4 ------> SPI1_NSS + PA5 ------> SPI1_SCK + PA6 ------> SPI1_MISO + PA7 ------> SPI1_MOSI + */ + HAL_GPIO_DeInit(GPIOA, GPIO_PIN_4 | GPIO_PIN_5 | GPIO_PIN_6 | GPIO_PIN_7); + + /* USER CODE BEGIN SPI1_MspDeInit 1 */ + + /* USER CODE END SPI1_MspDeInit 1 */ + } else if (hspi->Instance == SPI3) { + /* USER CODE BEGIN SPI3_MspDeInit 0 */ + + /* USER CODE END SPI3_MspDeInit 0 */ + /* Peripheral clock disable */ + __HAL_RCC_SPI3_CLK_DISABLE(); + + /**SPI3 GPIO Configuration + PB0 ------> SPI3_MISO + PB1 ------> SPI3_SCK + PB2 ------> SPI3_MOSI + */ + HAL_GPIO_DeInit(GPIOB, GPIO_PIN_0 | GPIO_PIN_1 | GPIO_PIN_2); + + /* USER CODE BEGIN SPI3_MspDeInit 1 */ + + /* USER CODE END SPI3_MspDeInit 1 */ + } +} + +/* USER CODE BEGIN 1 */ + +/* USER CODE END 1 */ diff --git a/SAMM/SuspensionNode/Src/stm32h5xx_it.c b/SAMM/SuspensionNode/Src/stm32h5xx_it.c new file mode 100644 index 000000000..2f34278d4 --- /dev/null +++ b/SAMM/SuspensionNode/Src/stm32h5xx_it.c @@ -0,0 +1,256 @@ +/* USER CODE BEGIN Header */ +/** + ****************************************************************************** + * @file stm32h5xx_it.c + * @brief Interrupt Service Routines. + ****************************************************************************** + * @attention + * + * Copyright (c) 2024 STMicroelectronics. + * All rights reserved. + * + * This software is licensed under terms that can be found in the LICENSE file + * in the root directory of this software component. + * If no LICENSE file comes with this software, it is provided AS-IS. + * + ****************************************************************************** + */ +/* USER CODE END Header */ + +/* Includes ------------------------------------------------------------------*/ +#include "stm32h5xx_it.h" + +#include "mag.h" +#include "main.h" +/* Private includes ----------------------------------------------------------*/ +/* USER CODE BEGIN Includes */ +/* USER CODE END Includes */ + +/* Private typedef -----------------------------------------------------------*/ +/* USER CODE BEGIN TD */ + +/* USER CODE END TD */ + +/* Private define ------------------------------------------------------------*/ +/* USER CODE BEGIN PD */ + +/* USER CODE END PD */ + +/* Private macro -------------------------------------------------------------*/ +/* USER CODE BEGIN PM */ + +/* USER CODE END PM */ + +/* Private variables ---------------------------------------------------------*/ +/* USER CODE BEGIN PV */ + +/* USER CODE END PV */ + +/* Private function prototypes -----------------------------------------------*/ +/* USER CODE BEGIN PFP */ + +/* USER CODE END PFP */ + +/* Private user code ---------------------------------------------------------*/ +/* USER CODE BEGIN 0 */ + +/* USER CODE END 0 */ + +/* External variables --------------------------------------------------------*/ + +/* USER CODE BEGIN EV */ + +/* USER CODE END EV */ + +/******************************************************************************/ +/* Cortex-M4 Processor Interruption and Exception Handlers */ +/******************************************************************************/ +/** + * @brief This function handles Non maskable interrupt. + */ +void NMI_Handler(void) +{ + /* USER CODE BEGIN NonMaskableInt_IRQn 0 */ + + /* USER CODE END NonMaskableInt_IRQn 0 */ + /* USER CODE BEGIN NonMaskableInt_IRQn 1 */ + while (1) {} + /* USER CODE END NonMaskableInt_IRQn 1 */ +} + +/** + * @brief This function handles Hard fault interrupt. + */ +void HardFault_Handler(void) +{ + /* USER CODE BEGIN HardFault_IRQn 0 */ + + /* USER CODE END HardFault_IRQn 0 */ + while (1) { + /* USER CODE BEGIN W1_HardFault_IRQn 0 */ + /* USER CODE END W1_HardFault_IRQn 0 */ + } +} + +/** + * @brief This function handles Memory management fault. + */ +void MemManage_Handler(void) +{ + /* USER CODE BEGIN MemoryManagement_IRQn 0 */ + + /* USER CODE END MemoryManagement_IRQn 0 */ + while (1) { + /* USER CODE BEGIN W1_MemoryManagement_IRQn 0 */ + /* USER CODE END W1_MemoryManagement_IRQn 0 */ + } +} + +/** + * @brief This function handles Prefetch fault, memory access fault. + */ +void BusFault_Handler(void) +{ + /* USER CODE BEGIN BusFault_IRQn 0 */ + + /* USER CODE END BusFault_IRQn 0 */ + while (1) { + /* USER CODE BEGIN W1_BusFault_IRQn 0 */ + /* USER CODE END W1_BusFault_IRQn 0 */ + } +} + +/** + * @brief This function handles Undefined instruction or illegal state. + */ +void UsageFault_Handler(void) +{ + /* USER CODE BEGIN UsageFault_IRQn 0 */ + + /* USER CODE END UsageFault_IRQn 0 */ + while (1) { + /* USER CODE BEGIN W1_UsageFault_IRQn 0 */ + /* USER CODE END W1_UsageFault_IRQn 0 */ + } +} + +/** + * @brief This function handles System service call via SWI instruction. + */ +void SVC_Handler(void) +{ + /* USER CODE BEGIN SVCall_IRQn 0 */ + + /* USER CODE END SVCall_IRQn 0 */ + /* USER CODE BEGIN SVCall_IRQn 1 */ + + /* USER CODE END SVCall_IRQn 1 */ +} + +/** + * @brief This function handles Debug monitor. + */ +void DebugMon_Handler(void) +{ + /* USER CODE BEGIN DebugMonitor_IRQn 0 */ + + /* USER CODE END DebugMonitor_IRQn 0 */ + /* USER CODE BEGIN DebugMonitor_IRQn 1 */ + + /* USER CODE END DebugMonitor_IRQn 1 */ +} + +/** + * @brief This function handles Pendable request for system service. + */ +void PendSV_Handler(void) +{ + /* USER CODE BEGIN PendSV_IRQn 0 */ + + /* USER CODE END PendSV_IRQn 0 */ + /* USER CODE BEGIN PendSV_IRQn 1 */ + + /* USER CODE END PendSV_IRQn 1 */ +} + +/** + * @brief Period elapsed callback in non blocking mode + * @note This function is called when TIM1 interrupt took place, inside + * HAL_TIM_IRQHandler(). It makes a direct call to HAL_IncTick() to increment + * a global variable "uwTick" used as application time base. + * @param htim : TIM handle + * @retval None + */ +void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim) +{ + /* USER CODE BEGIN Callback 0 */ + + /* USER CODE END Callback 0 */ + if (htim->Instance == TIM1) { + HAL_IncTick(); + } + + if (htim->Instance == TIM3) { + mag_read_data(); + } + /* USER CODE BEGIN Callback 1 */ + + /* USER CODE END Callback 1 */ +} + +/** + * @brief This function handles System tick timer. + */ +void SysTick_Handler(void) +{ + /* USER CODE BEGIN SysTick_IRQn 0 */ + + /* USER CODE END SysTick_IRQn 0 */ + HAL_IncTick(); + /* USER CODE BEGIN SysTick_IRQn 1 */ + + /* USER CODE END SysTick_IRQn 1 */ +} + +/******************************************************************************/ +/* STM32H5xx Peripheral Interrupt Handlers */ +/* Add here the Interrupt Handlers for the used peripherals. */ +/* For the available peripheral interrupt handler names, */ +/* please refer to the startup file (startup_stm32h5xx.s). */ +/******************************************************************************/ + +/** + * @brief This function handles TIM1 update interrupt and TIM16 global interrupt. + */ +void TIM1_UP_TIM16_IRQHandler(void) +{ + /* USER CODE BEGIN TIM1_UP_TIM16_IRQn 0 */ + + /* USER CODE END TIM1_UP_TIM16_IRQn 0 */ + HAL_TIM_IRQHandler(&htim1); + /* USER CODE BEGIN TIM1_UP_TIM16_IRQn 1 */ + + /* USER CODE END TIM1_UP_TIM16_IRQn 1 */ +} + +/* USER CODE BEGIN 1 */ + +/* USER CODE END 1 */ + +/** + * @brief This function handles TIM3 global interrupt. + */ +void TIM3_IRQHandler(void) +{ + /* USER CODE BEGIN TIM3_IRQn 0 */ + + /* USER CODE END TIM3_IRQn 0 */ + HAL_TIM_IRQHandler(&htim3); + /* USER CODE BEGIN TIM3_IRQn 1 */ + + /* USER CODE END TIM3_IRQn 1 */ +} + +/* USER CODE BEGIN 1 */ + +/* USER CODE END 1 */ diff --git a/SAMM/SuspensionNode/Src/tim.c b/SAMM/SuspensionNode/Src/tim.c new file mode 100644 index 000000000..9b8c03ed6 --- /dev/null +++ b/SAMM/SuspensionNode/Src/tim.c @@ -0,0 +1,111 @@ +/* USER CODE BEGIN Header */ +/** + ****************************************************************************** + * @file tim.c + * @brief This file provides code for the configuration + * of the TIM instances. + ****************************************************************************** + * @attention + * + * Copyright (c) 2026 STMicroelectronics. + * All rights reserved. + * + * This software is licensed under terms that can be found in the LICENSE file + * in the root directory of this software component. + * If no LICENSE file comes with this software, it is provided AS-IS. + * + ****************************************************************************** + */ +/* USER CODE END Header */ +/* Includes ------------------------------------------------------------------*/ +#include "tim.h" + +/* USER CODE BEGIN 0 */ + +/* USER CODE END 0 */ + +TIM_HandleTypeDef htim3; + +/* TIM3 init function */ +void MX_TIM3_Init(void) +{ + + /* USER CODE BEGIN TIM3_Init 0 */ + + /* USER CODE END TIM3_Init 0 */ + + TIM_ClockConfigTypeDef sClockSourceConfig = {0}; + TIM_MasterConfigTypeDef sMasterConfig = {0}; + + /* USER CODE BEGIN TIM3_Init 1 */ + + /* USER CODE END TIM3_Init 1 */ + htim3.Instance = TIM3; + htim3.Init.Prescaler = 179; + htim3.Init.CounterMode = TIM_COUNTERMODE_UP; + htim3.Init.Period = 999; + htim3.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1; + htim3.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_DISABLE; + if (HAL_TIM_Base_Init(&htim3) != HAL_OK) + { + Error_Handler(); + } + sClockSourceConfig.ClockSource = TIM_CLOCKSOURCE_INTERNAL; + if (HAL_TIM_ConfigClockSource(&htim3, &sClockSourceConfig) != HAL_OK) + { + Error_Handler(); + } + sMasterConfig.MasterOutputTrigger = TIM_TRGO_RESET; + sMasterConfig.MasterSlaveMode = TIM_MASTERSLAVEMODE_DISABLE; + if (HAL_TIMEx_MasterConfigSynchronization(&htim3, &sMasterConfig) != HAL_OK) + { + Error_Handler(); + } + /* USER CODE BEGIN TIM3_Init 2 */ + + /* USER CODE END TIM3_Init 2 */ + +} + +void HAL_TIM_Base_MspInit(TIM_HandleTypeDef* tim_baseHandle) +{ + + if(tim_baseHandle->Instance==TIM3) + { + /* USER CODE BEGIN TIM3_MspInit 0 */ + + /* USER CODE END TIM3_MspInit 0 */ + /* TIM3 clock enable */ + __HAL_RCC_TIM3_CLK_ENABLE(); + + /* TIM3 interrupt Init */ + HAL_NVIC_SetPriority(TIM3_IRQn, 5, 0); + HAL_NVIC_EnableIRQ(TIM3_IRQn); + /* USER CODE BEGIN TIM3_MspInit 1 */ + + /* USER CODE END TIM3_MspInit 1 */ + } +} + +void HAL_TIM_Base_MspDeInit(TIM_HandleTypeDef* tim_baseHandle) +{ + + if(tim_baseHandle->Instance==TIM3) + { + /* USER CODE BEGIN TIM3_MspDeInit 0 */ + + /* USER CODE END TIM3_MspDeInit 0 */ + /* Peripheral clock disable */ + __HAL_RCC_TIM3_CLK_DISABLE(); + + /* TIM3 interrupt Deinit */ + HAL_NVIC_DisableIRQ(TIM3_IRQn); + /* USER CODE BEGIN TIM3_MspDeInit 1 */ + + /* USER CODE END TIM3_MspDeInit 1 */ + } +} + +/* USER CODE BEGIN 1 */ + +/* USER CODE END 1 */ diff --git a/SAMM/samm.cmake b/SAMM/samm.cmake new file mode 100644 index 000000000..1550e1a1a --- /dev/null +++ b/SAMM/samm.cmake @@ -0,0 +1 @@ +include("${CMAKE_CURRENT_LIST_DIR}/IMU/imu.cmake")