diff --git a/EnduranceTestBench/.mxproject b/EnduranceTestBench/.mxproject
index 10b2b48..426ee1b 100644
--- a/EnduranceTestBench/.mxproject
+++ b/EnduranceTestBench/.mxproject
@@ -2,33 +2,35 @@
LibFiles=Drivers\STM32G4xx_HAL_Driver\Inc\stm32g4xx_hal_adc.h;Drivers\STM32G4xx_HAL_Driver\Inc\stm32g4xx_hal_adc_ex.h;Drivers\STM32G4xx_HAL_Driver\Inc\stm32g4xx_ll_adc.h;Drivers\STM32G4xx_HAL_Driver\Inc\stm32g4xx_hal.h;Drivers\STM32G4xx_HAL_Driver\Inc\stm32g4xx_hal_def.h;Drivers\STM32G4xx_HAL_Driver\Inc\Legacy\stm32_hal_legacy.h;Drivers\STM32G4xx_HAL_Driver\Inc\stm32g4xx_hal_rcc.h;Drivers\STM32G4xx_HAL_Driver\Inc\stm32g4xx_hal_rcc_ex.h;Drivers\STM32G4xx_HAL_Driver\Inc\stm32g4xx_ll_bus.h;Drivers\STM32G4xx_HAL_Driver\Inc\stm32g4xx_ll_rcc.h;Drivers\STM32G4xx_HAL_Driver\Inc\stm32g4xx_ll_system.h;Drivers\STM32G4xx_HAL_Driver\Inc\stm32g4xx_ll_utils.h;Drivers\STM32G4xx_HAL_Driver\Inc\stm32g4xx_ll_crs.h;Drivers\STM32G4xx_HAL_Driver\Inc\stm32g4xx_hal_flash.h;Drivers\STM32G4xx_HAL_Driver\Inc\stm32g4xx_hal_flash_ex.h;Drivers\STM32G4xx_HAL_Driver\Inc\stm32g4xx_hal_flash_ramfunc.h;Drivers\STM32G4xx_HAL_Driver\Inc\stm32g4xx_hal_gpio.h;Drivers\STM32G4xx_HAL_Driver\Inc\stm32g4xx_hal_gpio_ex.h;Drivers\STM32G4xx_HAL_Driver\Inc\stm32g4xx_ll_gpio.h;Drivers\STM32G4xx_HAL_Driver\Inc\stm32g4xx_hal_exti.h;Drivers\STM32G4xx_HAL_Driver\Inc\stm32g4xx_ll_exti.h;Drivers\STM32G4xx_HAL_Driver\Inc\stm32g4xx_hal_dma.h;Drivers\STM32G4xx_HAL_Driver\Inc\stm32g4xx_hal_dma_ex.h;Drivers\STM32G4xx_HAL_Driver\Inc\stm32g4xx_ll_dma.h;Drivers\STM32G4xx_HAL_Driver\Inc\stm32g4xx_ll_dmamux.h;Drivers\STM32G4xx_HAL_Driver\Inc\stm32g4xx_hal_pwr.h;Drivers\STM32G4xx_HAL_Driver\Inc\stm32g4xx_hal_pwr_ex.h;Drivers\STM32G4xx_HAL_Driver\Inc\stm32g4xx_ll_pwr.h;Drivers\STM32G4xx_HAL_Driver\Inc\stm32g4xx_hal_cortex.h;Drivers\STM32G4xx_HAL_Driver\Inc\stm32g4xx_ll_cortex.h;Drivers\STM32G4xx_HAL_Driver\Inc\stm32g4xx_hal_fdcan.h;Drivers\STM32G4xx_HAL_Driver\Inc\stm32g4xx_hal_i2c.h;Drivers\STM32G4xx_HAL_Driver\Inc\stm32g4xx_ll_i2c.h;Drivers\STM32G4xx_HAL_Driver\Inc\stm32g4xx_hal_i2c_ex.h;Drivers\STM32G4xx_HAL_Driver\Inc\stm32g4xx_hal_tim.h;Drivers\STM32G4xx_HAL_Driver\Inc\stm32g4xx_hal_tim_ex.h;Drivers\STM32G4xx_HAL_Driver\Inc\stm32g4xx_ll_tim.h;Drivers\STM32G4xx_HAL_Driver\Src\stm32g4xx_hal_adc.c;Drivers\STM32G4xx_HAL_Driver\Src\stm32g4xx_hal_adc_ex.c;Drivers\STM32G4xx_HAL_Driver\Src\stm32g4xx_ll_adc.c;Drivers\STM32G4xx_HAL_Driver\Src\stm32g4xx_hal.c;Drivers\STM32G4xx_HAL_Driver\Src\stm32g4xx_hal_rcc.c;Drivers\STM32G4xx_HAL_Driver\Src\stm32g4xx_hal_rcc_ex.c;Drivers\STM32G4xx_HAL_Driver\Src\stm32g4xx_hal_flash.c;Drivers\STM32G4xx_HAL_Driver\Src\stm32g4xx_hal_flash_ex.c;Drivers\STM32G4xx_HAL_Driver\Src\stm32g4xx_hal_flash_ramfunc.c;Drivers\STM32G4xx_HAL_Driver\Src\stm32g4xx_hal_gpio.c;Drivers\STM32G4xx_HAL_Driver\Src\stm32g4xx_hal_exti.c;Drivers\STM32G4xx_HAL_Driver\Src\stm32g4xx_hal_dma.c;Drivers\STM32G4xx_HAL_Driver\Src\stm32g4xx_hal_dma_ex.c;Drivers\STM32G4xx_HAL_Driver\Src\stm32g4xx_hal_pwr.c;Drivers\STM32G4xx_HAL_Driver\Src\stm32g4xx_hal_pwr_ex.c;Drivers\STM32G4xx_HAL_Driver\Src\stm32g4xx_hal_cortex.c;Drivers\STM32G4xx_HAL_Driver\Src\stm32g4xx_hal_fdcan.c;Drivers\STM32G4xx_HAL_Driver\Src\stm32g4xx_hal_i2c.c;Drivers\STM32G4xx_HAL_Driver\Src\stm32g4xx_hal_i2c_ex.c;Drivers\STM32G4xx_HAL_Driver\Src\stm32g4xx_hal_tim.c;Drivers\STM32G4xx_HAL_Driver\Src\stm32g4xx_hal_tim_ex.c;Drivers\STM32G4xx_HAL_Driver\Inc\stm32g4xx_hal_adc.h;Drivers\STM32G4xx_HAL_Driver\Inc\stm32g4xx_hal_adc_ex.h;Drivers\STM32G4xx_HAL_Driver\Inc\stm32g4xx_ll_adc.h;Drivers\STM32G4xx_HAL_Driver\Inc\stm32g4xx_hal.h;Drivers\STM32G4xx_HAL_Driver\Inc\stm32g4xx_hal_def.h;Drivers\STM32G4xx_HAL_Driver\Inc\Legacy\stm32_hal_legacy.h;Drivers\STM32G4xx_HAL_Driver\Inc\stm32g4xx_hal_rcc.h;Drivers\STM32G4xx_HAL_Driver\Inc\stm32g4xx_hal_rcc_ex.h;Drivers\STM32G4xx_HAL_Driver\Inc\stm32g4xx_ll_bus.h;Drivers\STM32G4xx_HAL_Driver\Inc\stm32g4xx_ll_rcc.h;Drivers\STM32G4xx_HAL_Driver\Inc\stm32g4xx_ll_system.h;Drivers\STM32G4xx_HAL_Driver\Inc\stm32g4xx_ll_utils.h;Drivers\STM32G4xx_HAL_Driver\Inc\stm32g4xx_ll_crs.h;Drivers\STM32G4xx_HAL_Driver\Inc\stm32g4xx_hal_flash.h;Drivers\STM32G4xx_HAL_Driver\Inc\stm32g4xx_hal_flash_ex.h;Drivers\STM32G4xx_HAL_Driver\Inc\stm32g4xx_hal_flash_ramfunc.h;Drivers\STM32G4xx_HAL_Driver\Inc\stm32g4xx_hal_gpio.h;Drivers\STM32G4xx_HAL_Driver\Inc\stm32g4xx_hal_gpio_ex.h;Drivers\STM32G4xx_HAL_Driver\Inc\stm32g4xx_ll_gpio.h;Drivers\STM32G4xx_HAL_Driver\Inc\stm32g4xx_hal_exti.h;Drivers\STM32G4xx_HAL_Driver\Inc\stm32g4xx_ll_exti.h;Drivers\STM32G4xx_HAL_Driver\Inc\stm32g4xx_hal_dma.h;Drivers\STM32G4xx_HAL_Driver\Inc\stm32g4xx_hal_dma_ex.h;Drivers\STM32G4xx_HAL_Driver\Inc\stm32g4xx_ll_dma.h;Drivers\STM32G4xx_HAL_Driver\Inc\stm32g4xx_ll_dmamux.h;Drivers\STM32G4xx_HAL_Driver\Inc\stm32g4xx_hal_pwr.h;Drivers\STM32G4xx_HAL_Driver\Inc\stm32g4xx_hal_pwr_ex.h;Drivers\STM32G4xx_HAL_Driver\Inc\stm32g4xx_ll_pwr.h;Drivers\STM32G4xx_HAL_Driver\Inc\stm32g4xx_hal_cortex.h;Drivers\STM32G4xx_HAL_Driver\Inc\stm32g4xx_ll_cortex.h;Drivers\STM32G4xx_HAL_Driver\Inc\stm32g4xx_hal_fdcan.h;Drivers\STM32G4xx_HAL_Driver\Inc\stm32g4xx_hal_i2c.h;Drivers\STM32G4xx_HAL_Driver\Inc\stm32g4xx_ll_i2c.h;Drivers\STM32G4xx_HAL_Driver\Inc\stm32g4xx_hal_i2c_ex.h;Drivers\STM32G4xx_HAL_Driver\Inc\stm32g4xx_hal_tim.h;Drivers\STM32G4xx_HAL_Driver\Inc\stm32g4xx_hal_tim_ex.h;Drivers\STM32G4xx_HAL_Driver\Inc\stm32g4xx_ll_tim.h;Drivers\CMSIS\Device\ST\STM32G4xx\Include\stm32g474xx.h;Drivers\CMSIS\Device\ST\STM32G4xx\Include\stm32g4xx.h;Drivers\CMSIS\Device\ST\STM32G4xx\Include\system_stm32g4xx.h;Drivers\CMSIS\Device\ST\STM32G4xx\Include\system_stm32g4xx.h;Drivers\CMSIS\Device\ST\STM32G4xx\Source\Templates\system_stm32g4xx.c;Drivers\CMSIS\Include\cmsis_armcc.h;Drivers\CMSIS\Include\cmsis_armclang.h;Drivers\CMSIS\Include\cmsis_armclang_ltm.h;Drivers\CMSIS\Include\cmsis_compiler.h;Drivers\CMSIS\Include\cmsis_gcc.h;Drivers\CMSIS\Include\cmsis_iccarm.h;Drivers\CMSIS\Include\cmsis_version.h;Drivers\CMSIS\Include\core_armv81mml.h;Drivers\CMSIS\Include\core_armv8mbl.h;Drivers\CMSIS\Include\core_armv8mml.h;Drivers\CMSIS\Include\core_cm0.h;Drivers\CMSIS\Include\core_cm0plus.h;Drivers\CMSIS\Include\core_cm1.h;Drivers\CMSIS\Include\core_cm23.h;Drivers\CMSIS\Include\core_cm3.h;Drivers\CMSIS\Include\core_cm33.h;Drivers\CMSIS\Include\core_cm35p.h;Drivers\CMSIS\Include\core_cm4.h;Drivers\CMSIS\Include\core_cm7.h;Drivers\CMSIS\Include\core_sc000.h;Drivers\CMSIS\Include\core_sc300.h;Drivers\CMSIS\Include\mpu_armv7.h;Drivers\CMSIS\Include\mpu_armv8.h;Drivers\CMSIS\Include\tz_context.h;
[PreviousUsedCubeIDEFiles]
-SourceFiles=Core\Src\main.c;Core\Src\gpio.c;Core\Src\adc.c;Core\Src\fdcan.c;Core\Src\i2c.c;Core\Src\tim.c;Core\Src\stm32g4xx_it.c;Core\Src\stm32g4xx_hal_msp.c;Drivers\STM32G4xx_HAL_Driver\Src\stm32g4xx_hal_adc.c;Drivers\STM32G4xx_HAL_Driver\Src\stm32g4xx_hal_adc_ex.c;Drivers\STM32G4xx_HAL_Driver\Src\stm32g4xx_ll_adc.c;Drivers\STM32G4xx_HAL_Driver\Src\stm32g4xx_hal.c;Drivers\STM32G4xx_HAL_Driver\Src\stm32g4xx_hal_rcc.c;Drivers\STM32G4xx_HAL_Driver\Src\stm32g4xx_hal_rcc_ex.c;Drivers\STM32G4xx_HAL_Driver\Src\stm32g4xx_hal_flash.c;Drivers\STM32G4xx_HAL_Driver\Src\stm32g4xx_hal_flash_ex.c;Drivers\STM32G4xx_HAL_Driver\Src\stm32g4xx_hal_flash_ramfunc.c;Drivers\STM32G4xx_HAL_Driver\Src\stm32g4xx_hal_gpio.c;Drivers\STM32G4xx_HAL_Driver\Src\stm32g4xx_hal_exti.c;Drivers\STM32G4xx_HAL_Driver\Src\stm32g4xx_hal_dma.c;Drivers\STM32G4xx_HAL_Driver\Src\stm32g4xx_hal_dma_ex.c;Drivers\STM32G4xx_HAL_Driver\Src\stm32g4xx_hal_pwr.c;Drivers\STM32G4xx_HAL_Driver\Src\stm32g4xx_hal_pwr_ex.c;Drivers\STM32G4xx_HAL_Driver\Src\stm32g4xx_hal_cortex.c;Drivers\STM32G4xx_HAL_Driver\Src\stm32g4xx_hal_fdcan.c;Drivers\STM32G4xx_HAL_Driver\Src\stm32g4xx_hal_i2c.c;Drivers\STM32G4xx_HAL_Driver\Src\stm32g4xx_hal_i2c_ex.c;Drivers\STM32G4xx_HAL_Driver\Src\stm32g4xx_hal_tim.c;Drivers\STM32G4xx_HAL_Driver\Src\stm32g4xx_hal_tim_ex.c;Drivers\CMSIS\Device\ST\STM32G4xx\Source\Templates\system_stm32g4xx.c;Core\Src\system_stm32g4xx.c;Drivers\STM32G4xx_HAL_Driver\Src\stm32g4xx_hal_adc.c;Drivers\STM32G4xx_HAL_Driver\Src\stm32g4xx_hal_adc_ex.c;Drivers\STM32G4xx_HAL_Driver\Src\stm32g4xx_ll_adc.c;Drivers\STM32G4xx_HAL_Driver\Src\stm32g4xx_hal.c;Drivers\STM32G4xx_HAL_Driver\Src\stm32g4xx_hal_rcc.c;Drivers\STM32G4xx_HAL_Driver\Src\stm32g4xx_hal_rcc_ex.c;Drivers\STM32G4xx_HAL_Driver\Src\stm32g4xx_hal_flash.c;Drivers\STM32G4xx_HAL_Driver\Src\stm32g4xx_hal_flash_ex.c;Drivers\STM32G4xx_HAL_Driver\Src\stm32g4xx_hal_flash_ramfunc.c;Drivers\STM32G4xx_HAL_Driver\Src\stm32g4xx_hal_gpio.c;Drivers\STM32G4xx_HAL_Driver\Src\stm32g4xx_hal_exti.c;Drivers\STM32G4xx_HAL_Driver\Src\stm32g4xx_hal_dma.c;Drivers\STM32G4xx_HAL_Driver\Src\stm32g4xx_hal_dma_ex.c;Drivers\STM32G4xx_HAL_Driver\Src\stm32g4xx_hal_pwr.c;Drivers\STM32G4xx_HAL_Driver\Src\stm32g4xx_hal_pwr_ex.c;Drivers\STM32G4xx_HAL_Driver\Src\stm32g4xx_hal_cortex.c;Drivers\STM32G4xx_HAL_Driver\Src\stm32g4xx_hal_fdcan.c;Drivers\STM32G4xx_HAL_Driver\Src\stm32g4xx_hal_i2c.c;Drivers\STM32G4xx_HAL_Driver\Src\stm32g4xx_hal_i2c_ex.c;Drivers\STM32G4xx_HAL_Driver\Src\stm32g4xx_hal_tim.c;Drivers\STM32G4xx_HAL_Driver\Src\stm32g4xx_hal_tim_ex.c;Drivers\CMSIS\Device\ST\STM32G4xx\Source\Templates\system_stm32g4xx.c;Core\Src\system_stm32g4xx.c;;;
+SourceFiles=Core\Src\main.c;Core\Src\gpio.c;Core\Src\adc.c;Core\Src\dma.c;Core\Src\fdcan.c;Core\Src\i2c.c;Core\Src\tim.c;Core\Src\stm32g4xx_it.c;Core\Src\stm32g4xx_hal_msp.c;Drivers\STM32G4xx_HAL_Driver\Src\stm32g4xx_hal_adc.c;Drivers\STM32G4xx_HAL_Driver\Src\stm32g4xx_hal_adc_ex.c;Drivers\STM32G4xx_HAL_Driver\Src\stm32g4xx_ll_adc.c;Drivers\STM32G4xx_HAL_Driver\Src\stm32g4xx_hal.c;Drivers\STM32G4xx_HAL_Driver\Src\stm32g4xx_hal_rcc.c;Drivers\STM32G4xx_HAL_Driver\Src\stm32g4xx_hal_rcc_ex.c;Drivers\STM32G4xx_HAL_Driver\Src\stm32g4xx_hal_flash.c;Drivers\STM32G4xx_HAL_Driver\Src\stm32g4xx_hal_flash_ex.c;Drivers\STM32G4xx_HAL_Driver\Src\stm32g4xx_hal_flash_ramfunc.c;Drivers\STM32G4xx_HAL_Driver\Src\stm32g4xx_hal_gpio.c;Drivers\STM32G4xx_HAL_Driver\Src\stm32g4xx_hal_exti.c;Drivers\STM32G4xx_HAL_Driver\Src\stm32g4xx_hal_dma.c;Drivers\STM32G4xx_HAL_Driver\Src\stm32g4xx_hal_dma_ex.c;Drivers\STM32G4xx_HAL_Driver\Src\stm32g4xx_hal_pwr.c;Drivers\STM32G4xx_HAL_Driver\Src\stm32g4xx_hal_pwr_ex.c;Drivers\STM32G4xx_HAL_Driver\Src\stm32g4xx_hal_cortex.c;Drivers\STM32G4xx_HAL_Driver\Src\stm32g4xx_hal_fdcan.c;Drivers\STM32G4xx_HAL_Driver\Src\stm32g4xx_hal_i2c.c;Drivers\STM32G4xx_HAL_Driver\Src\stm32g4xx_hal_i2c_ex.c;Drivers\STM32G4xx_HAL_Driver\Src\stm32g4xx_hal_tim.c;Drivers\STM32G4xx_HAL_Driver\Src\stm32g4xx_hal_tim_ex.c;Drivers\CMSIS\Device\ST\STM32G4xx\Source\Templates\system_stm32g4xx.c;Core\Src\system_stm32g4xx.c;Drivers\STM32G4xx_HAL_Driver\Src\stm32g4xx_hal_adc.c;Drivers\STM32G4xx_HAL_Driver\Src\stm32g4xx_hal_adc_ex.c;Drivers\STM32G4xx_HAL_Driver\Src\stm32g4xx_ll_adc.c;Drivers\STM32G4xx_HAL_Driver\Src\stm32g4xx_hal.c;Drivers\STM32G4xx_HAL_Driver\Src\stm32g4xx_hal_rcc.c;Drivers\STM32G4xx_HAL_Driver\Src\stm32g4xx_hal_rcc_ex.c;Drivers\STM32G4xx_HAL_Driver\Src\stm32g4xx_hal_flash.c;Drivers\STM32G4xx_HAL_Driver\Src\stm32g4xx_hal_flash_ex.c;Drivers\STM32G4xx_HAL_Driver\Src\stm32g4xx_hal_flash_ramfunc.c;Drivers\STM32G4xx_HAL_Driver\Src\stm32g4xx_hal_gpio.c;Drivers\STM32G4xx_HAL_Driver\Src\stm32g4xx_hal_exti.c;Drivers\STM32G4xx_HAL_Driver\Src\stm32g4xx_hal_dma.c;Drivers\STM32G4xx_HAL_Driver\Src\stm32g4xx_hal_dma_ex.c;Drivers\STM32G4xx_HAL_Driver\Src\stm32g4xx_hal_pwr.c;Drivers\STM32G4xx_HAL_Driver\Src\stm32g4xx_hal_pwr_ex.c;Drivers\STM32G4xx_HAL_Driver\Src\stm32g4xx_hal_cortex.c;Drivers\STM32G4xx_HAL_Driver\Src\stm32g4xx_hal_fdcan.c;Drivers\STM32G4xx_HAL_Driver\Src\stm32g4xx_hal_i2c.c;Drivers\STM32G4xx_HAL_Driver\Src\stm32g4xx_hal_i2c_ex.c;Drivers\STM32G4xx_HAL_Driver\Src\stm32g4xx_hal_tim.c;Drivers\STM32G4xx_HAL_Driver\Src\stm32g4xx_hal_tim_ex.c;Drivers\CMSIS\Device\ST\STM32G4xx\Source\Templates\system_stm32g4xx.c;Core\Src\system_stm32g4xx.c;;;
HeaderPath=Drivers\STM32G4xx_HAL_Driver\Inc;Drivers\STM32G4xx_HAL_Driver\Inc\Legacy;Drivers\CMSIS\Device\ST\STM32G4xx\Include;Drivers\CMSIS\Include;Core\Inc;
CDefines=USE_HAL_DRIVER;STM32G474xx;USE_HAL_DRIVER;USE_HAL_DRIVER;
[PreviousGenFiles]
AdvancedFolderStructure=true
-HeaderFileListSize=8
+HeaderFileListSize=9
HeaderFiles#0=..\Core\Inc\gpio.h
HeaderFiles#1=..\Core\Inc\adc.h
-HeaderFiles#2=..\Core\Inc\fdcan.h
-HeaderFiles#3=..\Core\Inc\i2c.h
-HeaderFiles#4=..\Core\Inc\tim.h
-HeaderFiles#5=..\Core\Inc\stm32g4xx_it.h
-HeaderFiles#6=..\Core\Inc\stm32g4xx_hal_conf.h
-HeaderFiles#7=..\Core\Inc\main.h
+HeaderFiles#2=..\Core\Inc\dma.h
+HeaderFiles#3=..\Core\Inc\fdcan.h
+HeaderFiles#4=..\Core\Inc\i2c.h
+HeaderFiles#5=..\Core\Inc\tim.h
+HeaderFiles#6=..\Core\Inc\stm32g4xx_it.h
+HeaderFiles#7=..\Core\Inc\stm32g4xx_hal_conf.h
+HeaderFiles#8=..\Core\Inc\main.h
HeaderFolderListSize=1
HeaderPath#0=..\Core\Inc
HeaderFiles=;
-SourceFileListSize=8
+SourceFileListSize=9
SourceFiles#0=..\Core\Src\gpio.c
SourceFiles#1=..\Core\Src\adc.c
-SourceFiles#2=..\Core\Src\fdcan.c
-SourceFiles#3=..\Core\Src\i2c.c
-SourceFiles#4=..\Core\Src\tim.c
-SourceFiles#5=..\Core\Src\stm32g4xx_it.c
-SourceFiles#6=..\Core\Src\stm32g4xx_hal_msp.c
-SourceFiles#7=..\Core\Src\main.c
+SourceFiles#2=..\Core\Src\dma.c
+SourceFiles#3=..\Core\Src\fdcan.c
+SourceFiles#4=..\Core\Src\i2c.c
+SourceFiles#5=..\Core\Src\tim.c
+SourceFiles#6=..\Core\Src\stm32g4xx_it.c
+SourceFiles#7=..\Core\Src\stm32g4xx_hal_msp.c
+SourceFiles#8=..\Core\Src\main.c
SourceFolderListSize=1
SourcePath#0=..\Core\Src
SourceFiles=;
diff --git a/EnduranceTestBench/.project b/EnduranceTestBench/.project
index 75885d9..a74685d 100644
--- a/EnduranceTestBench/.project
+++ b/EnduranceTestBench/.project
@@ -33,12 +33,12 @@
NorthStar-Emotas-Stack
2
- copy_PARENT/NorthStar-Emotas-Stack
+ PARENT-1-PROJECT_LOC/NorthStar-Emotas-Stack
common
2
- copy_PARENT/common
+ PARENT-1-PARENT_LOC/common
nms_can
@@ -48,17 +48,7 @@
nms_hal
2
- copy_PROJECT_LOC/nms_hal
+ PROJECT_LOC/nms_hal
-
-
- copy_PARENT
- $%7BPARENT-3-PROJECT_LOC%7D/Documents/NorthStar-Endurance-TestBench
-
-
- copy_PROJECT_LOC
- $%7BPARENT-1-copy_PARENT%7D/NorthStar-Production-Unit-Board-Firmware/ProcessBoardV1
-
-
diff --git a/EnduranceTestBench/Core/Inc/dma.h b/EnduranceTestBench/Core/Inc/dma.h
new file mode 100644
index 0000000..493d98e
--- /dev/null
+++ b/EnduranceTestBench/Core/Inc/dma.h
@@ -0,0 +1,52 @@
+/* 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/EnduranceTestBench/Core/Inc/stm32g4xx_it.h b/EnduranceTestBench/Core/Inc/stm32g4xx_it.h
index b25abe5..8b51533 100644
--- a/EnduranceTestBench/Core/Inc/stm32g4xx_it.h
+++ b/EnduranceTestBench/Core/Inc/stm32g4xx_it.h
@@ -55,6 +55,7 @@ void SVC_Handler(void);
void DebugMon_Handler(void);
void PendSV_Handler(void);
void SysTick_Handler(void);
+void DMA1_Channel1_IRQHandler(void);
void TIM1_TRG_COM_TIM17_IRQHandler(void);
void I2C4_EV_IRQHandler(void);
void I2C4_ER_IRQHandler(void);
diff --git a/EnduranceTestBench/Core/Src/adc.c b/EnduranceTestBench/Core/Src/adc.c
index 03575a0..e0fead8 100644
--- a/EnduranceTestBench/Core/Src/adc.c
+++ b/EnduranceTestBench/Core/Src/adc.c
@@ -25,6 +25,7 @@
/* USER CODE END 0 */
ADC_HandleTypeDef hadc1;
+DMA_HandleTypeDef hdma_adc1;
/* ADC1 init function */
void MX_ADC1_Init(void)
@@ -48,11 +49,11 @@ void MX_ADC1_Init(void)
hadc1.Init.Resolution = ADC_RESOLUTION_12B;
hadc1.Init.DataAlign = ADC_DATAALIGN_RIGHT;
hadc1.Init.GainCompensation = 0;
- hadc1.Init.ScanConvMode = ADC_SCAN_DISABLE;
+ hadc1.Init.ScanConvMode = ADC_SCAN_ENABLE;
hadc1.Init.EOCSelection = ADC_EOC_SINGLE_CONV;
hadc1.Init.LowPowerAutoWait = DISABLE;
hadc1.Init.ContinuousConvMode = ENABLE;
- hadc1.Init.NbrOfConversion = 1;
+ hadc1.Init.NbrOfConversion = 9;
hadc1.Init.DiscontinuousConvMode = DISABLE;
hadc1.Init.ExternalTrigConv = ADC_SOFTWARE_START;
hadc1.Init.ExternalTrigConvEdge = ADC_EXTERNALTRIGCONVEDGE_NONE;
@@ -84,6 +85,78 @@ void MX_ADC1_Init(void)
{
Error_Handler();
}
+
+ /** Configure Regular Channel
+ */
+ sConfig.Channel = ADC_CHANNEL_2;
+ sConfig.Rank = ADC_REGULAR_RANK_2;
+ if (HAL_ADC_ConfigChannel(&hadc1, &sConfig) != HAL_OK)
+ {
+ Error_Handler();
+ }
+
+ /** Configure Regular Channel
+ */
+ sConfig.Channel = ADC_CHANNEL_3;
+ sConfig.Rank = ADC_REGULAR_RANK_3;
+ if (HAL_ADC_ConfigChannel(&hadc1, &sConfig) != HAL_OK)
+ {
+ Error_Handler();
+ }
+
+ /** Configure Regular Channel
+ */
+ sConfig.Channel = ADC_CHANNEL_4;
+ sConfig.Rank = ADC_REGULAR_RANK_4;
+ if (HAL_ADC_ConfigChannel(&hadc1, &sConfig) != HAL_OK)
+ {
+ Error_Handler();
+ }
+
+ /** Configure Regular Channel
+ */
+ sConfig.Channel = ADC_CHANNEL_5;
+ sConfig.Rank = ADC_REGULAR_RANK_5;
+ if (HAL_ADC_ConfigChannel(&hadc1, &sConfig) != HAL_OK)
+ {
+ Error_Handler();
+ }
+
+ /** Configure Regular Channel
+ */
+ sConfig.Channel = ADC_CHANNEL_6;
+ sConfig.Rank = ADC_REGULAR_RANK_6;
+ if (HAL_ADC_ConfigChannel(&hadc1, &sConfig) != HAL_OK)
+ {
+ Error_Handler();
+ }
+
+ /** Configure Regular Channel
+ */
+ sConfig.Channel = ADC_CHANNEL_7;
+ sConfig.Rank = ADC_REGULAR_RANK_7;
+ if (HAL_ADC_ConfigChannel(&hadc1, &sConfig) != HAL_OK)
+ {
+ Error_Handler();
+ }
+
+ /** Configure Regular Channel
+ */
+ sConfig.Channel = ADC_CHANNEL_8;
+ sConfig.Rank = ADC_REGULAR_RANK_8;
+ if (HAL_ADC_ConfigChannel(&hadc1, &sConfig) != HAL_OK)
+ {
+ Error_Handler();
+ }
+
+ /** Configure Regular Channel
+ */
+ sConfig.Channel = ADC_CHANNEL_9;
+ sConfig.Rank = ADC_REGULAR_RANK_9;
+ if (HAL_ADC_ConfigChannel(&hadc1, &sConfig) != HAL_OK)
+ {
+ Error_Handler();
+ }
/* USER CODE BEGIN ADC1_Init 2 */
/* USER CODE END ADC1_Init 2 */
@@ -142,6 +215,24 @@ void HAL_ADC_MspInit(ADC_HandleTypeDef* adcHandle)
GPIO_InitStruct.Pull = GPIO_NOPULL;
HAL_GPIO_Init(PMP_FB_GPIO_Port, &GPIO_InitStruct);
+ /* ADC1 DMA Init */
+ /* ADC1 Init */
+ hdma_adc1.Instance = DMA1_Channel1;
+ hdma_adc1.Init.Request = DMA_REQUEST_ADC1;
+ hdma_adc1.Init.Direction = DMA_PERIPH_TO_MEMORY;
+ hdma_adc1.Init.PeriphInc = DMA_PINC_DISABLE;
+ hdma_adc1.Init.MemInc = DMA_MINC_ENABLE;
+ hdma_adc1.Init.PeriphDataAlignment = DMA_PDATAALIGN_HALFWORD;
+ hdma_adc1.Init.MemDataAlignment = DMA_MDATAALIGN_HALFWORD;
+ hdma_adc1.Init.Mode = DMA_CIRCULAR;
+ hdma_adc1.Init.Priority = DMA_PRIORITY_LOW;
+ if (HAL_DMA_Init(&hdma_adc1) != HAL_OK)
+ {
+ Error_Handler();
+ }
+
+ __HAL_LINKDMA(adcHandle,DMA_Handle,hdma_adc1);
+
/* USER CODE BEGIN ADC1_MspInit 1 */
/* USER CODE END ADC1_MspInit 1 */
@@ -176,6 +267,8 @@ void HAL_ADC_MspDeInit(ADC_HandleTypeDef* adcHandle)
HAL_GPIO_DeInit(PMP_FB_GPIO_Port, PMP_FB_Pin);
+ /* ADC1 DMA DeInit */
+ HAL_DMA_DeInit(adcHandle->DMA_Handle);
/* USER CODE BEGIN ADC1_MspDeInit 1 */
/* USER CODE END ADC1_MspDeInit 1 */
diff --git a/EnduranceTestBench/Core/Src/dma.c b/EnduranceTestBench/Core/Src/dma.c
new file mode 100644
index 0000000..4ce0b91
--- /dev/null
+++ b/EnduranceTestBench/Core/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) 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)
+{
+
+ /* DMA controller clock enable */
+ __HAL_RCC_DMAMUX1_CLK_ENABLE();
+ __HAL_RCC_DMA1_CLK_ENABLE();
+
+ /* DMA interrupt init */
+ /* DMA1_Channel1_IRQn interrupt configuration */
+ HAL_NVIC_SetPriority(DMA1_Channel1_IRQn, 0, 0);
+ HAL_NVIC_EnableIRQ(DMA1_Channel1_IRQn);
+
+}
+
+/* USER CODE BEGIN 2 */
+
+/* USER CODE END 2 */
+
diff --git a/EnduranceTestBench/Core/Src/main.c b/EnduranceTestBench/Core/Src/main.c
index d76251c..5986bfb 100644
--- a/EnduranceTestBench/Core/Src/main.c
+++ b/EnduranceTestBench/Core/Src/main.c
@@ -19,6 +19,7 @@
/* Includes ------------------------------------------------------------------*/
#include "main.h"
#include "adc.h"
+#include "dma.h"
#include "fdcan.h"
#include "i2c.h"
#include "tim.h"
@@ -93,6 +94,7 @@ int main(void)
/* Initialize all configured peripherals */
MX_GPIO_Init();
+ MX_DMA_Init();
MX_FDCAN1_Init();
MX_TIM17_Init();
MX_FDCAN2_Init();
diff --git a/EnduranceTestBench/Core/Src/stm32g4xx_it.c b/EnduranceTestBench/Core/Src/stm32g4xx_it.c
index 987a0c9..626b189 100644
--- a/EnduranceTestBench/Core/Src/stm32g4xx_it.c
+++ b/EnduranceTestBench/Core/Src/stm32g4xx_it.c
@@ -55,6 +55,7 @@
/* USER CODE END 0 */
/* External variables --------------------------------------------------------*/
+extern DMA_HandleTypeDef hdma_adc1;
extern I2C_HandleTypeDef hi2c4;
extern TIM_HandleTypeDef htim17;
/* USER CODE BEGIN EV */
@@ -199,6 +200,20 @@ void SysTick_Handler(void)
/* please refer to the startup file (startup_stm32g4xx.s). */
/******************************************************************************/
+/**
+ * @brief This function handles DMA1 channel1 global interrupt.
+ */
+void DMA1_Channel1_IRQHandler(void)
+{
+ /* USER CODE BEGIN DMA1_Channel1_IRQn 0 */
+
+ /* USER CODE END DMA1_Channel1_IRQn 0 */
+ HAL_DMA_IRQHandler(&hdma_adc1);
+ /* USER CODE BEGIN DMA1_Channel1_IRQn 1 */
+
+ /* USER CODE END DMA1_Channel1_IRQn 1 */
+}
+
/**
* @brief This function handles TIM1 trigger and commutation interrupts and TIM17 global interrupt.
*/
diff --git a/EnduranceTestBench/EnduranceTestBench.ioc b/EnduranceTestBench/EnduranceTestBench.ioc
index 19d2376..18d0845 100644
--- a/EnduranceTestBench/EnduranceTestBench.ioc
+++ b/EnduranceTestBench/EnduranceTestBench.ioc
@@ -1,17 +1,69 @@
#MicroXplorer Configuration settings - do not modify
ADC1.Channel-0\#ChannelRegularConversion=ADC_CHANNEL_1
+ADC1.Channel-1\#ChannelRegularConversion=ADC_CHANNEL_2
+ADC1.Channel-2\#ChannelRegularConversion=ADC_CHANNEL_3
+ADC1.Channel-3\#ChannelRegularConversion=ADC_CHANNEL_4
+ADC1.Channel-4\#ChannelRegularConversion=ADC_CHANNEL_5
+ADC1.Channel-5\#ChannelRegularConversion=ADC_CHANNEL_6
+ADC1.Channel-6\#ChannelRegularConversion=ADC_CHANNEL_7
+ADC1.Channel-7\#ChannelRegularConversion=ADC_CHANNEL_8
+ADC1.Channel-8\#ChannelRegularConversion=ADC_CHANNEL_9
ADC1.CommonPathInternal=null|null|null|null
ADC1.ContinuousConvMode=ENABLE
-ADC1.IPParameters=Rank-0\#ChannelRegularConversion,Channel-0\#ChannelRegularConversion,SamplingTime-0\#ChannelRegularConversion,OffsetNumber-0\#ChannelRegularConversion,NbrOfConversionFlag,master,Overrun,ContinuousConvMode,CommonPathInternal
+ADC1.IPParameters=Rank-0\#ChannelRegularConversion,Channel-0\#ChannelRegularConversion,SamplingTime-0\#ChannelRegularConversion,OffsetNumber-0\#ChannelRegularConversion,NbrOfConversionFlag,master,Overrun,ContinuousConvMode,Rank-1\#ChannelRegularConversion,Channel-1\#ChannelRegularConversion,SamplingTime-1\#ChannelRegularConversion,OffsetNumber-1\#ChannelRegularConversion,Rank-2\#ChannelRegularConversion,Channel-2\#ChannelRegularConversion,SamplingTime-2\#ChannelRegularConversion,OffsetNumber-2\#ChannelRegularConversion,Rank-3\#ChannelRegularConversion,Channel-3\#ChannelRegularConversion,SamplingTime-3\#ChannelRegularConversion,OffsetNumber-3\#ChannelRegularConversion,Rank-4\#ChannelRegularConversion,Channel-4\#ChannelRegularConversion,SamplingTime-4\#ChannelRegularConversion,OffsetNumber-4\#ChannelRegularConversion,Rank-5\#ChannelRegularConversion,Channel-5\#ChannelRegularConversion,SamplingTime-5\#ChannelRegularConversion,OffsetNumber-5\#ChannelRegularConversion,Rank-6\#ChannelRegularConversion,Channel-6\#ChannelRegularConversion,SamplingTime-6\#ChannelRegularConversion,OffsetNumber-6\#ChannelRegularConversion,Rank-7\#ChannelRegularConversion,Channel-7\#ChannelRegularConversion,SamplingTime-7\#ChannelRegularConversion,OffsetNumber-7\#ChannelRegularConversion,Rank-8\#ChannelRegularConversion,Channel-8\#ChannelRegularConversion,SamplingTime-8\#ChannelRegularConversion,OffsetNumber-8\#ChannelRegularConversion,NbrOfConversion,CommonPathInternal
+ADC1.NbrOfConversion=9
ADC1.NbrOfConversionFlag=1
ADC1.OffsetNumber-0\#ChannelRegularConversion=ADC_OFFSET_NONE
+ADC1.OffsetNumber-1\#ChannelRegularConversion=ADC_OFFSET_NONE
+ADC1.OffsetNumber-2\#ChannelRegularConversion=ADC_OFFSET_NONE
+ADC1.OffsetNumber-3\#ChannelRegularConversion=ADC_OFFSET_NONE
+ADC1.OffsetNumber-4\#ChannelRegularConversion=ADC_OFFSET_NONE
+ADC1.OffsetNumber-5\#ChannelRegularConversion=ADC_OFFSET_NONE
+ADC1.OffsetNumber-6\#ChannelRegularConversion=ADC_OFFSET_NONE
+ADC1.OffsetNumber-7\#ChannelRegularConversion=ADC_OFFSET_NONE
+ADC1.OffsetNumber-8\#ChannelRegularConversion=ADC_OFFSET_NONE
ADC1.Overrun=ADC_OVR_DATA_OVERWRITTEN
ADC1.Rank-0\#ChannelRegularConversion=1
+ADC1.Rank-1\#ChannelRegularConversion=2
+ADC1.Rank-2\#ChannelRegularConversion=3
+ADC1.Rank-3\#ChannelRegularConversion=4
+ADC1.Rank-4\#ChannelRegularConversion=5
+ADC1.Rank-5\#ChannelRegularConversion=6
+ADC1.Rank-6\#ChannelRegularConversion=7
+ADC1.Rank-7\#ChannelRegularConversion=8
+ADC1.Rank-8\#ChannelRegularConversion=9
ADC1.SamplingTime-0\#ChannelRegularConversion=ADC_SAMPLETIME_2CYCLES_5
+ADC1.SamplingTime-1\#ChannelRegularConversion=ADC_SAMPLETIME_2CYCLES_5
+ADC1.SamplingTime-2\#ChannelRegularConversion=ADC_SAMPLETIME_2CYCLES_5
+ADC1.SamplingTime-3\#ChannelRegularConversion=ADC_SAMPLETIME_2CYCLES_5
+ADC1.SamplingTime-4\#ChannelRegularConversion=ADC_SAMPLETIME_2CYCLES_5
+ADC1.SamplingTime-5\#ChannelRegularConversion=ADC_SAMPLETIME_2CYCLES_5
+ADC1.SamplingTime-6\#ChannelRegularConversion=ADC_SAMPLETIME_2CYCLES_5
+ADC1.SamplingTime-7\#ChannelRegularConversion=ADC_SAMPLETIME_2CYCLES_5
+ADC1.SamplingTime-8\#ChannelRegularConversion=ADC_SAMPLETIME_2CYCLES_5
ADC1.master=1
CAD.formats=
CAD.pinconfig=
CAD.provider=
+Dma.ADC1.0.Direction=DMA_PERIPH_TO_MEMORY
+Dma.ADC1.0.EventEnable=DISABLE
+Dma.ADC1.0.Instance=DMA1_Channel1
+Dma.ADC1.0.MemDataAlignment=DMA_MDATAALIGN_HALFWORD
+Dma.ADC1.0.MemInc=DMA_MINC_ENABLE
+Dma.ADC1.0.Mode=DMA_CIRCULAR
+Dma.ADC1.0.PeriphDataAlignment=DMA_PDATAALIGN_HALFWORD
+Dma.ADC1.0.PeriphInc=DMA_PINC_DISABLE
+Dma.ADC1.0.Polarity=HAL_DMAMUX_REQ_GEN_RISING
+Dma.ADC1.0.Priority=DMA_PRIORITY_LOW
+Dma.ADC1.0.RequestNumber=1
+Dma.ADC1.0.RequestParameters=Instance,Direction,PeriphInc,MemInc,PeriphDataAlignment,MemDataAlignment,Mode,Priority,SignalID,Polarity,RequestNumber,SyncSignalID,SyncPolarity,SyncEnable,EventEnable,SyncRequestNumber
+Dma.ADC1.0.SignalID=NONE
+Dma.ADC1.0.SyncEnable=DISABLE
+Dma.ADC1.0.SyncPolarity=HAL_DMAMUX_SYNC_NO_EVENT
+Dma.ADC1.0.SyncRequestNumber=1
+Dma.ADC1.0.SyncSignalID=NONE
+Dma.Request0=ADC1
+Dma.RequestsNb=1
FDCAN1.AutoRetransmission=ENABLE
FDCAN1.CalculateBaudRateNominal=250000
FDCAN1.CalculateTimeBitNominal=4000
@@ -32,21 +84,22 @@ FDCAN2.IPParameters=CalculateTimeQuantumNominal,CalculateTimeBitNominal,Calculat
FDCAN2.NominalPrescaler=32
FDCAN2.NominalTimeSeg1=2
File.Version=6
-GPIO.groupedBy=
+GPIO.groupedBy=Group By Peripherals
I2C4.IPParameters=Timing
I2C4.Timing=0x00D09BE3
KeepUserPlacement=false
Mcu.CPN=STM32G474RET6
Mcu.Family=STM32G4
Mcu.IP0=ADC1
-Mcu.IP1=FDCAN1
-Mcu.IP2=FDCAN2
-Mcu.IP3=I2C4
-Mcu.IP4=NVIC
-Mcu.IP5=RCC
-Mcu.IP6=SYS
-Mcu.IP7=TIM17
-Mcu.IPNb=8
+Mcu.IP1=DMA
+Mcu.IP2=FDCAN1
+Mcu.IP3=FDCAN2
+Mcu.IP4=I2C4
+Mcu.IP5=NVIC
+Mcu.IP6=RCC
+Mcu.IP7=SYS
+Mcu.IP8=TIM17
+Mcu.IPNb=9
Mcu.Name=STM32G474R(B-C-E)Tx
Mcu.Package=LQFP64
Mcu.Pin0=PF0-OSC_IN
@@ -82,6 +135,7 @@ Mcu.UserName=STM32G474RETx
MxCube.Version=6.12.0
MxDb.Version=DB.6.0.120
NVIC.BusFault_IRQn=true\:0\:0\:false\:false\:true\:false\:false\:false
+NVIC.DMA1_Channel1_IRQn=true\:0\:0\:false\:false\:true\:false\:true\:true
NVIC.DebugMonitor_IRQn=true\:0\:0\:false\:false\:true\:false\:false\:false
NVIC.ForceEnableDMAVector=true
NVIC.HardFault_IRQn=true\:0\:0\:false\:false\:true\:false\:false\:false
@@ -218,7 +272,7 @@ ProjectManager.ToolChainLocation=
ProjectManager.UAScriptAfterPath=
ProjectManager.UAScriptBeforePath=
ProjectManager.UnderRoot=true
-ProjectManager.functionlistsort=1-SystemClock_Config-RCC-false-HAL-false,2-MX_GPIO_Init-GPIO-false-HAL-true,3-MX_FDCAN1_Init-FDCAN1-false-HAL-true,4-MX_TIM17_Init-TIM17-false-HAL-true,5-MX_FDCAN2_Init-FDCAN2-false-HAL-true,6-MX_ADC1_Init-ADC1-false-HAL-true,7-MX_I2C4_Init-I2C4-false-HAL-true
+ProjectManager.functionlistsort=1-SystemClock_Config-RCC-false-HAL-false,2-MX_GPIO_Init-GPIO-false-HAL-true,3-MX_DMA_Init-DMA-false-HAL-true,4-MX_FDCAN1_Init-FDCAN1-false-HAL-true,5-MX_TIM17_Init-TIM17-false-HAL-true,6-MX_FDCAN2_Init-FDCAN2-false-HAL-true,7-MX_ADC1_Init-ADC1-false-HAL-true,8-MX_I2C4_Init-I2C4-false-HAL-true
RCC.ADC12Freq_Value=160000000
RCC.ADC345Freq_Value=160000000
RCC.AHBFreq_Value=160000000
diff --git a/EnduranceTestBench/nehemis/enduranceTestBench.c b/EnduranceTestBench/nehemis/enduranceTestBench.c
index cdd7ff6..fe0346c 100644
--- a/EnduranceTestBench/nehemis/enduranceTestBench.c
+++ b/EnduranceTestBench/nehemis/enduranceTestBench.c
@@ -36,13 +36,13 @@
typedef enum
{
TEST_BENCH_STARTUP,
- TEST_BENCH_BATCH_WRITE, /* Write to nodes in batch */
- TEST_BENCH_BATCH_WRITE_WAIT, /* Wait between writes */
- TEST_BENCH_BATCH_READ, /* Read all nodes */
- TEST_BENCH_BATCH_READ_WAIT, /* Wait between reads */
- TEST_BENCH_BATCH_VERIFY, /* Verify all nodes */
- TEST_BENCH_CYCLE_COMPLETE, /* End of cycle, reset for next iteration */
- TEST_BENCH_IDLE /* Idle state (optional) */
+ TEST_BENCH_IDLE, /* Sets new data for the next cycle */
+ TEST_BENCH_WRITE,
+ TEST_BENCH_WRITE_WAIT,
+ TEST_BENCH_READ,
+ TEST_BENCH_READ_WAIT,
+ TEST_BENCH_VERIFY,
+ TEST_BENCH_CYCLE_COMPLETE /* End of cycle, reset for next iteration */
} SdlTestBenchState_en;
typedef enum
@@ -120,7 +120,7 @@ void EnduranceTestBenchRun(bool *testBenchStarted_pb)
}
currentNode_gu8 = 0u;
- testBenchState_en = TEST_BENCH_BATCH_WRITE;
+ testBenchState_en = TEST_BENCH_WRITE;
}
break;
@@ -164,69 +164,69 @@ void EnduranceTestBenchRun(bool *testBenchStarted_pb)
}
alternate_u8++; /* Switch to the next cycle pattern */
currentNode_gu8 = 0u;
- testBenchState_en = TEST_BENCH_BATCH_WRITE;
+ testBenchState_en = TEST_BENCH_WRITE;
}
break;
- /* -------------------- Batch Write -------------------- */
- case TEST_BENCH_BATCH_WRITE:
+ /* -------------------- Write -------------------- */
+ case TEST_BENCH_WRITE:
{
if (currentNode_gu8 < ENDURANCE_TEST_BENCH_LSS_NODE_COUNT)
{
- RET_T retVal_en = coSdoWrite(
- (currentNode_gu8 + 1),
- ENDURANCE_TEST_BENCH_POSITION_SETPOINT_INDEX,
- ENDURANCE_TEST_BENCH_POSITION_SETPOINT_SUB_INDEX,
- &testBenchData_en.targetPositions_gau8[currentNode_gu8],
- sizeof(uint8),
- CO_FALSE,
- ENDURANCE_TEST_BENCH_TIMEOUT
- );
+ RET_T retVal_en = coSdoWrite(
+ (currentNode_gu8 + 1),
+ ENDURANCE_TEST_BENCH_POSITION_SETPOINT_INDEX,
+ ENDURANCE_TEST_BENCH_POSITION_SETPOINT_SUB_INDEX,
+ &testBenchData_en.targetPositions_gau8[currentNode_gu8],
+ sizeof(uint8),
+ CO_FALSE,
+ ENDURANCE_TEST_BENCH_TIMEOUT
+ );
- if (retVal_en == RET_OK)
- {
- HalSystemGetRunTimeMs(&writeTime_u64);
- retries_u8 = 0u;
- testBenchState_en = TEST_BENCH_BATCH_WRITE_WAIT;
- }
- else
- {
- retries_u8++;
- if (retries_u8 >= ENDURANCE_TEST_BENCH_MAX_RETRY_CNT)
- {
- testBenchData_en.status_en[currentNode_gu8] = TEST_BENCH_DATA_NODE_SKIPPED;
+ if (retVal_en == RET_OK)
+ {
+ HalSystemGetRunTimeMs(&writeTime_u64);
+ retries_u8 = 0u;
+ testBenchState_en = TEST_BENCH_WRITE_WAIT;
+ }
+ else
+ {
+ retries_u8++;
+ if (retries_u8 >= ENDURANCE_TEST_BENCH_MAX_RETRY_CNT)
+ {
+ testBenchData_en.status_en[currentNode_gu8] = TEST_BENCH_DATA_NODE_SKIPPED;
- /* Mark node as skipped and move on */
- currentNode_gu8++;
- retries_u8 = 0u;
- testBenchState_en = TEST_BENCH_BATCH_WRITE;
- }
- }
- }
+ /* Mark node as skipped and move on */
+ currentNode_gu8++;
+ retries_u8 = 0u;
+ testBenchState_en = TEST_BENCH_WRITE;
+ }
+ }
+ }
else
{
/* Finished writing to all nodes */
currentNode_gu8 = 0u; /* Reset index for read phase */
- testBenchState_en = TEST_BENCH_BATCH_READ;
+ testBenchState_en = TEST_BENCH_READ;
}
break;
}
- case TEST_BENCH_BATCH_WRITE_WAIT:
+ case TEST_BENCH_WRITE_WAIT:
{
/* Wait 100ms between writes */
if ((currentTime_u64 - writeTime_u64) >= 500)
{
/* Move to next node write */
currentNode_gu8++;
- testBenchState_en = TEST_BENCH_BATCH_WRITE;
+ testBenchState_en = TEST_BENCH_WRITE;
}
break;
}
- /* -------------------- Batch Read -------------------- */
- case TEST_BENCH_BATCH_READ:
+ /* -------------------- Read -------------------- */
+ case TEST_BENCH_READ:
{
if (currentNode_gu8 < ENDURANCE_TEST_BENCH_LSS_NODE_COUNT)
{
@@ -249,7 +249,7 @@ void EnduranceTestBenchRun(bool *testBenchStarted_pb)
*/
HalSystemGetRunTimeMs(&readExecutedTime_u64);
testBenchData_en.readPosition_gau8[currentNode_gu8] = (uint8)readPosition_gu32;
- testBenchState_en = TEST_BENCH_BATCH_READ_WAIT;
+ testBenchState_en = TEST_BENCH_READ_WAIT;
}
else if (retVal_en == RET_SERVICE_BUSY && retries_u8 < ENDURANCE_TEST_BENCH_MAX_RETRY_CNT)
{
@@ -267,24 +267,24 @@ void EnduranceTestBenchRun(bool *testBenchStarted_pb)
{
/* Finished reading all nodes */
currentNode_gu8 = 0u; /* Reset for verification phase */
- testBenchState_en = TEST_BENCH_BATCH_VERIFY;
+ testBenchState_en = TEST_BENCH_VERIFY;
}
break;
}
- case TEST_BENCH_BATCH_READ_WAIT:
+ case TEST_BENCH_READ_WAIT:
{
/* Wait 100ms between node reads */
if ((currentTime_u64 - readExecutedTime_u64) >= 10)
{
currentNode_gu8++;
- testBenchState_en = TEST_BENCH_BATCH_READ;
+ testBenchState_en = TEST_BENCH_READ;
}
break;
}
/* -------------------- Batch Verify -------------------- */
- case TEST_BENCH_BATCH_VERIFY:
+ case TEST_BENCH_VERIFY:
{
if (currentNode_gu8 < ENDURANCE_TEST_BENCH_LSS_NODE_COUNT)
{
@@ -292,7 +292,7 @@ void EnduranceTestBenchRun(bool *testBenchStarted_pb)
if (testBenchData_en.status_en[currentNode_gu8] != TEST_BENCH_DATA_NODE_SKIPPED)
{
if (abs(testBenchData_en.targetPositions_gau8[currentNode_gu8] -
- testBenchData_en.readPosition_gau8[currentNode_gu8]) <= 5u) /* Accepted difference between read and write for successful operation */
+ testBenchData_en.readPosition_gau8[currentNode_gu8]) <= 2u) /* Accepted difference between read and write for successful operation */
{
testBenchData_en.status_en[currentNode_gu8] = TEST_BENCH_DATA_VERIF_SUCCESS;
}
@@ -303,7 +303,7 @@ void EnduranceTestBenchRun(bool *testBenchStarted_pb)
}
/* Move to the next node in any case */
currentNode_gu8++;
- testBenchState_en = TEST_BENCH_BATCH_VERIFY;
+ testBenchState_en = TEST_BENCH_VERIFY;
}
else
{
@@ -334,7 +334,7 @@ void EnduranceTestBenchRun(bool *testBenchStarted_pb)
default:
break;
-}
+ }
}
/******************************************************************************
diff --git a/EnduranceTestBench/nehemis/processBoard.c b/EnduranceTestBench/nehemis/processBoard.c
index 87bc756..1c44e80 100644
--- a/EnduranceTestBench/nehemis/processBoard.c
+++ b/EnduranceTestBench/nehemis/processBoard.c
@@ -189,7 +189,6 @@ static void ProcessBoardGrundfosPumpHandler(void)
if ((currentTimeMs_u64 - startTime_u64) >= PU_PUMP_SPEED_CHANGE_INTERVAL)
{
- // Update speed
if (speed_u8 < PU_PUMP_MAX_SPEED)
{
speed_u8 += 2u;
diff --git a/EnduranceTestBench/nms_can/nms_can.c b/EnduranceTestBench/nms_can/nms_can.c
index a99c762..0b5f9e3 100644
--- a/EnduranceTestBench/nms_can/nms_can.c
+++ b/EnduranceTestBench/nms_can/nms_can.c
@@ -1,17 +1,17 @@
-///**
-// * @file nms_can.c
-// *
-// * @copyright Nehemis SARL reserves all rights even in the event of industrial
-// * property rights. We reserve all rights of disposal such as
-// * copying and passing on to third parties.
-// *
-// * @brief Source code for CANOpen files abstracted for furthur use in the project.
-// *
-// */
-//
-///******************************************************************************
-// * Include Header Files
-// ******************************************************************************/
+/**
+ * @file nms_can.c
+ *
+ * @copyright Nehemis SARL reserves all rights even in the event of industrial
+ * property rights. We reserve all rights of disposal such as
+ * copying and passing on to third parties.
+ *
+ * @brief Source code for CANOpen files abstracted for furthur use in the project.
+ *
+ */
+
+/******************************************************************************
+ * Include Header Files
+ ******************************************************************************/
#include "nms_can.h"
#include "enduranceTestBench.h"
@@ -21,14 +21,14 @@
#include "co_sdo.h"
#include "co_pdo.h"
#include "co_odaccess.h"
-//
-///******************************************************************************
-// * Global Variable Declaration
-// ******************************************************************************/
-//
-///******************************************************************************
-// * Macro constant declarations
-// ******************************************************************************/
+
+/******************************************************************************
+ * Global Variable Declaration
+ ******************************************************************************/
+
+/******************************************************************************
+ * Macro constant declarations
+ ******************************************************************************/
#define NMS_CAN_CANOPEN_SLAVE_LINE 0u
#define NMS_CAN_CANOPEN_MASTER_LINE 1u
diff --git a/EnduranceTestBench/nms_hal/hal_adc.c b/EnduranceTestBench/nms_hal/hal_adc.c
new file mode 100644
index 0000000..c71f8dd
--- /dev/null
+++ b/EnduranceTestBench/nms_hal/hal_adc.c
@@ -0,0 +1,267 @@
+/**
+ * @file hal_adc.c
+ * @copyright Nehemis SARL reserves all rights even in the event of industrial
+ * property rights. We reserve all rights of disposal such as
+ * copying and passing on to third parties.
+ *
+ * @brief STM HAL layer wrapper class for ADC.
+ *
+ */
+
+/******************************************************************************
+ * Include Header Files
+ ******************************************************************************/
+#include "hal_adc.h"
+
+/* CubeMX */
+#include "adc.h"
+/******************************************************************************
+ * Macro Constant Declarations
+ ******************************************************************************/
+#define HAL_ADC_TIMEOUT 10u /* in milliseconds */
+/******************************************************************************
+ * Module Global Variable Declarations
+ ******************************************************************************/
+static uint32 (*halAdcCallbacks[MAP_HAL_ADC_NUMBER])(void);
+/******************************************************************************
+ * Extern Function Definitions
+ ******************************************************************************/
+void HalAdcCalibrate(MapHalAdcModule_en module_en)
+{
+ uint32 error_u32 = NMS_ERR_DEFAULT;
+ ADC_HandleTypeDef *targetModule_pst;
+
+ error_u32 = MapHalAdcModule(module_en, &targetModule_pst);
+ if (error_u32 == NMS_ERR_NONE)
+ {
+ HAL_ADCEx_Calibration_Start(targetModule_pst, ADC_SINGLE_ENDED);
+ }
+ else
+ {
+ /* Handle error */
+ }
+}
+
+
+uint32 HalAdcStart(MapHalAdcModule_en module_en)
+{
+ uint32 error_u32 = NMS_ERR_NONE;
+ HAL_StatusTypeDef halAdcStatus_en = HAL_OK;
+ ADC_HandleTypeDef *targetModule_pst;
+
+ error_u32 = MapHalAdcModule(module_en, &targetModule_pst);
+
+ if (error_u32 == NMS_ERR_NONE)
+ {
+ /* Start the ADC conversion */
+ halAdcStatus_en = HAL_ADC_Start(targetModule_pst);
+
+ switch (halAdcStatus_en)
+ {
+ case HAL_BUSY: error_u32 = NMS_ERR_BUSY; break;
+ case HAL_TIMEOUT: error_u32 = NMS_ERR_TIMEOUT; break;
+ case HAL_ERROR: error_u32 = NMS_ERR_INTERNAL; break;
+ case HAL_OK: error_u32 = NMS_ERR_NONE; break;
+ default: error_u32 = NMS_ERR_UNKNOWN; break;
+ }
+ }
+ return error_u32;
+}
+
+
+uint32 HalAdcRead(MapHalAdcModule_en module_en, uint32 *adcValue_pu32)
+{
+ uint32 error_u32 = NMS_ERR_NONE;
+ HAL_StatusTypeDef halAdcStatus_en = HAL_OK;
+ ADC_HandleTypeDef *targetModule_pst;
+
+ error_u32 = MapHalAdcModule(module_en, &targetModule_pst);
+
+ if (error_u32 == NMS_ERR_NONE)
+ {
+ halAdcStatus_en = HAL_ADC_PollForConversion(targetModule_pst, HAL_ADC_TIMEOUT);
+ if (halAdcStatus_en == HAL_OK)
+ {
+ *adcValue_pu32 = HAL_ADC_GetValue(targetModule_pst);
+ return NMS_ERR_NONE;
+ }
+ else
+ {
+ return NMS_ERR_UNKNOWN;
+ }
+ }
+ return error_u32;
+}
+
+
+uint32 HalAdcStop(MapHalAdcModule_en module_en)
+{
+ uint32 error_u32 = NMS_ERR_NONE;
+ HAL_StatusTypeDef halAdcStatus_en = HAL_OK;
+ ADC_HandleTypeDef * targetModule_pst;
+
+ error_u32 = MapHalAdcModule(module_en, &targetModule_pst);
+
+ if(error_u32 == NMS_ERR_NONE)
+ {
+ halAdcStatus_en = HAL_ADC_Stop(targetModule_pst);
+
+ switch(halAdcStatus_en)
+ {
+ case HAL_BUSY: error_u32 = NMS_ERR_BUSY; break;
+ case HAL_TIMEOUT: error_u32 = NMS_ERR_TIMEOUT; break;
+ case HAL_ERROR: error_u32 = NMS_ERR_INTERNAL; break;
+ case HAL_OK: error_u32 = NMS_ERR_NONE; break;
+ default: error_u32 = NMS_ERR_UNKNOWN; break;
+ }
+ }
+ return error_u32;
+}
+
+
+uint32 HalAdcStartDMA(MapHalAdcModule_en module_en, uint32 * pData_u32, uint32 length_u32)
+{
+ uint32 error_u32 = NMS_ERR_NONE;
+ HAL_StatusTypeDef halAdcStatus_en = HAL_OK;
+ ADC_HandleTypeDef * targetModule_pst;
+
+ error_u32 = MapHalAdcModule(module_en, &targetModule_pst);
+
+ if(error_u32 == NMS_ERR_NONE)
+ {
+ halAdcStatus_en = HAL_ADC_Start_DMA(targetModule_pst, pData_u32, length_u32);
+
+ switch(halAdcStatus_en)
+ {
+ case HAL_BUSY: error_u32 = NMS_ERR_BUSY; break;
+ case HAL_TIMEOUT: error_u32 = NMS_ERR_TIMEOUT; break;
+ case HAL_ERROR: error_u32 = NMS_ERR_INTERNAL; break;
+ case HAL_OK: error_u32 = NMS_ERR_NONE; break;
+ default: error_u32 = NMS_ERR_UNKNOWN; break;
+ }
+ }
+ return error_u32;
+}
+
+
+uint32 HalAdcConfigureCallback(MapHalAdcModule_en adcModule_en, uint32 (*callback_pfn)(void))
+{
+ uint32 error_u32 = NMS_ERR_DEFAULT;
+
+ if (adcModule_en < MAP_HAL_ADC_NUMBER )
+ {
+ halAdcCallbacks[adcModule_en] = callback_pfn;
+ error_u32 = NMS_ERR_NONE;
+ }
+ else
+ {
+ error_u32 = NMS_ERR_UNKNOWN;
+ }
+
+ return error_u32;
+}
+
+
+void HalAdcDeinit(MapHalAdcModule_en adcModule_en)
+{
+ uint32 error_u32 = NMS_ERR_DEFAULT;
+ ADC_HandleTypeDef * targetModule_pst;
+ uint8 index_u8;
+ uint8 startIndex_u8;
+ uint8 iteration_u8 = 1u; /* Default to 1 loop iteration (deinit one module) */
+
+ if(adcModule_en == MAP_HAL_ADC_NUMBER)
+ {
+ iteration_u8 = adcModule_en;
+ startIndex_u8 = 0u;
+ }
+ else
+ {
+ iteration_u8 += adcModule_en;
+ startIndex_u8 = adcModule_en;
+ }
+
+ for(index_u8 = startIndex_u8; index_u8 < iteration_u8; index_u8++)
+ {
+ error_u32 = MapHalAdcModule((MapHalAdcModule_en)index_u8, &targetModule_pst);
+ if(error_u32 == NMS_ERR_NONE)
+ {
+ HAL_ADC_DeInit(targetModule_pst);
+ }
+ }
+}
+/******************************************************************************
+ * Callback Function Definitions
+ ******************************************************************************/
+void HAL_ADC_ConvCpltCallback(ADC_HandleTypeDef* hadc)
+{
+ uint32 error_u32 = NMS_ERR_DEFAULT;
+ MapHalAdcModule_en adcModule_en;
+
+ error_u32 = MapHalAdcCallback(MAP_HAL_ADC_1, &adcModule_en);
+
+ if (error_u32 == NMS_ERR_NONE)
+ {
+ if (adcModule_en < MAP_HAL_ADC_NUMBER)
+ {
+ if (halAdcCallbacks[adcModule_en] != NULL)
+ {
+ halAdcCallbacks[adcModule_en]();
+ }
+ else
+ {
+ error_u32 = NMS_ERR_UNKNOWN;
+ }
+ }
+ else
+ {
+ error_u32 = NMS_ERR_INVALID_MODULE;
+ }
+ }
+ else
+ {
+ error_u32 = NMS_ERR_UNKNOWN;
+ }
+}
+
+void HAL_ADC_ErrorCallback(ADC_HandleTypeDef* hadc)
+{
+ uint32 error_u32 = NMS_ERR_DEFAULT;
+ ADC_HandleTypeDef *targetModule_pst = NULL;
+
+ error_u32 = MapHalAdcModule(MAP_HAL_ADC_1, &targetModule_pst);
+
+ if(error_u32 == NMS_ERR_NONE)
+ {
+ switch(hadc->State)
+ {
+ case HAL_ADC_STATE_RESET:
+ error_u32 = NMS_ERR_UNKNOWN;
+ break;
+
+ case HAL_ADC_STATE_BUSY:
+ error_u32 = NMS_ERR_BUSY;
+ break;
+
+ case HAL_ADC_STATE_TIMEOUT:
+ error_u32 = NMS_ERR_TIMEOUT;
+ break;
+
+ case HAL_ADC_STATE_ERROR:
+ error_u32 = NMS_ERR_BUSY;
+ break;
+
+ case HAL_ADC_STATE_READY:
+ error_u32 = NMS_ERR_NOT_RUNNING;
+ break;
+
+ default:
+ error_u32 = NMS_ERR_UNKNOWN;
+ break;
+ }
+ }
+ else
+ {
+ error_u32 = NMS_ERR_UNKNOWN;
+ }
+}
diff --git a/EnduranceTestBench/nms_hal/hal_adc.h b/EnduranceTestBench/nms_hal/hal_adc.h
new file mode 100644
index 0000000..48aa3a9
--- /dev/null
+++ b/EnduranceTestBench/nms_hal/hal_adc.h
@@ -0,0 +1,108 @@
+/**
+ * @file hal_adc.h
+ * @copyright Nehemis SARL reserves all rights even in the event of industrial
+ * property rights. We reserve all rights of disposal such as
+ * copying and passing on to third parties.
+ *
+ * @brief STM HAL ADC wrapper class.
+ */
+
+#ifndef HAL_ADC_H
+#define HAL_ADC_H
+
+/******************************************************************************
+ * Include Header Files
+ ******************************************************************************/
+#include "nms_types.h"
+#include "map_hal.h"
+
+/* CubeMX */
+#include "adc.h"
+
+/******************************************************************************
+ * Typedef
+ ******************************************************************************/
+typedef enum
+{
+ HAL_ADC_SUCCESS = 0U,
+ HAL_ADC_ERROR,
+ HAL_ADC_TIMEOUT
+} HalAdcStatus_ten;
+
+/******************************************************************************
+ * Function Declarations
+ ******************************************************************************/
+/**
+ * @brief Initializes the ADC hardware interface.
+ * This function sets up the necessary resources and configurations for the ADC.
+ *
+ * @return Error code: 0 if successful, nonzero otherwise.
+ */
+void HalAdcCalibrate(MapHalAdcModule_en module_en);
+
+/**
+ * @brief Starts the ADC conversion on the specified ADC module.
+ * This function initiates the conversion process for the given ADC module.
+ *
+ * @param module_en The ADC module to be used (based on the system configuration).
+ *
+ * @return Error code: 0 if successful, nonzero otherwise.
+ */
+uint32 HalAdcStart(MapHalAdcModule_en module_en);
+
+/**
+ * @brief Reads the ADC value from the specified ADC module.
+ *
+ * @param module_en The ADC module to read from.
+ * adcValue_pu32 Pointer to store the ADC value.
+ *
+ * @return Error code: 0 if successful, nonzero otherwise.
+ */
+uint32 HalAdcRead(MapHalAdcModule_en module_en, uint32 *adcValue_pu32);
+
+/**
+ * @brief Stops the ADC conversion for the specified ADC module.
+ *
+ * @param module_en The ADC module to stop.
+ *
+ * @return uint32_t: Status of the ADC stop operation.
+ */
+uint32 HalAdcStop(MapHalAdcModule_en module_en);
+
+/**
+ * @brief Reads the ADC value in DMA mode
+ *
+ * @param module_en The ADC module to read from.
+ * pData_u32 Pointer to store the ADC value.
+ * length_u32 Length of data.
+ *
+ * @return Error code: 0 if successful, nonzero otherwise.
+ */
+uint32 HalAdcStartDMA(MapHalAdcModule_en module_en, uint32 * pData_u32, uint32 length_u32);
+
+/**
+ * @brief Deinitializes the specified ADC module.
+ * This function frees up the resources associated with the ADC module
+ * and prepares it for shutdown or reconfiguration.
+ *
+ * @param adcModule_en The ADC module to deinitialize.
+ *
+ * @return None
+ */
+void HalAdcDeinit(MapHalAdcModule_en adcModule_en);
+
+/**
+ * @brief Configures a callback function for ADC conversion completion.
+ * This function registers a callback function that will be called
+ * once the ADC conversion is completed.
+ *
+ * @param adcModule_en The ADC module to configure the callback for.
+ * callback_pfn Pointer to the callback function that will be called
+ * after the ADC conversion is complete.
+ * The callback should return a `uint32` value.
+ *
+ * @return Error code: 0 if successful, nonzero otherwise.
+ */
+uint32 HalAdcConfigureCallback(MapHalAdcModule_en adcModule_en, uint32 (*callback_pfn)(void));
+
+#endif /* HAL_ADC_H */
diff --git a/EnduranceTestBench/nms_hal/hal_gpio.c b/EnduranceTestBench/nms_hal/hal_gpio.c
new file mode 100644
index 0000000..6c0d6f0
--- /dev/null
+++ b/EnduranceTestBench/nms_hal/hal_gpio.c
@@ -0,0 +1,331 @@
+/**
+ * @file hal_gpio.c
+ *
+ * @copyright Nehemis SARL reserves all rights even in the event of industrial
+ * property rights. We reserve all rights of disposal such as
+ * copying and passing on to third parties.
+ *
+ * @brief HAL layer for the GPIO module.
+ *
+ */
+
+/******************************************************************************
+ * Include Header Files
+ ******************************************************************************/
+#include "map_hal.h"
+#include "hal_gpio.h"
+
+/* CubeMX */
+#include "gpio.h"
+
+/******************************************************************************
+ * Macro constant declarations
+ ******************************************************************************/
+#define HAL_GET_GPIO_OUTPUT_TYPE(port, pin) \
+ ((((port)->OTYPER & (OUTPUT_TYPE << (pin))) == 0) ? GPIO_MODE_OUTPUT_PP : GPIO_MODE_OUTPUT_OD)
+
+
+#define HAL_GPIO_GET_INTERRUPT_INPUT_MODE(port, pin) \
+ (((((port)->MODER >> ((pin) * 2)) & 0x3) == GPIO_MODE_IT_RISING) || \
+ ((((port)->MODER >> ((pin) * 2)) & 0x3) == GPIO_MODE_IT_FALLING) || \
+ ((((port)->MODER >> ((pin) * 2)) & 0x3) == GPIO_MODE_IT_RISING_FALLING))
+
+#define HAL_GPIO_MODE_MASK (0x3u)
+
+/******************************************************************************
+ * Type declarations
+ ******************************************************************************/
+
+
+/******************************************************************************
+ * Module Global Variable Declarations
+ ******************************************************************************/
+static uint32 (*halGpioCallbacks[MAP_HAL_GPIO_NUMBER])(HalGpioEdgeType_en);
+
+/******************************************************************************
+ * Static Function Declarations
+ ******************************************************************************/
+
+/******************************************************************************
+ * Extern Function Definition
+ ******************************************************************************/
+uint32 HalGpioInit(void)
+{
+ return NMS_ERR_NONE;
+}
+
+
+uint32 HalGpioRead( MapHalGpioPin_en pin_en, HalGpioState_en * state_pen )
+{
+ uint32 error_u32 = NMS_ERR_DEFAULT;
+ uint16 targetPin_u16;
+ GPIO_TypeDef* targetPort_pst = NULL;
+
+ error_u32 = MapHalGpio(pin_en, &targetPin_u16, &targetPort_pst);
+
+ if(error_u32 == NMS_ERR_NONE)
+ {
+ *state_pen = (HAL_GPIO_ReadPin(targetPort_pst, targetPin_u16) == GPIO_PIN_SET)
+ ? HAL_GPIO_STATE_HIGH
+ : HAL_GPIO_STATE_LOW;
+ }
+ else
+ {
+ *state_pen = HAL_GPIO_STATE_UNKNOWN;
+ error_u32 = NMS_ERR_UNEXPECTED;
+ }
+
+ return error_u32;
+}
+
+
+uint32 HalGpioWrite( MapHalGpioPin_en pin_en, HalGpioState_en state_en )
+{
+ uint32 error_u32 = NMS_ERR_DEFAULT;
+ uint16 targetPin_u16;
+ GPIO_TypeDef* targetPort_pst = NULL;
+
+ error_u32 = MapHalGpio(pin_en, &targetPin_u16, &targetPort_pst);
+
+ if(error_u32 == NMS_ERR_NONE)
+ {
+ uint32 outpuType_u32 = HAL_GET_GPIO_OUTPUT_TYPE(targetPort_pst, pin_en);
+
+ if(outpuType_u32 == GPIO_MODE_OUTPUT_PP || outpuType_u32 == GPIO_MODE_OUTPUT_OD)
+ {
+ switch (state_en)
+ {
+ case HAL_GPIO_STATE_HIGH:
+ HAL_GPIO_WritePin(targetPort_pst, targetPin_u16, GPIO_PIN_SET); break;
+
+ case HAL_GPIO_STATE_LOW:
+ HAL_GPIO_WritePin(targetPort_pst, targetPin_u16, GPIO_PIN_RESET); break;
+
+ default:
+ error_u32 = NMS_ERR_UNKNOWN; break;
+ }
+ }
+
+ HalGpioState_en activeState_en = (HAL_GPIO_ReadPin(targetPort_pst, targetPin_u16) == GPIO_PIN_SET)
+ ? HAL_GPIO_STATE_HIGH
+ : HAL_GPIO_STATE_LOW;
+ if(activeState_en != state_en)
+ {
+ error_u32 = NMS_ERR_INVALID_CONFIG;
+ }
+
+ }
+ else
+ {
+ error_u32 = NMS_ERR_UNEXPECTED;
+ }
+
+ return error_u32;
+}
+
+
+uint32 HalGpioToggle( MapHalGpioPin_en pin_en )
+{
+ uint32 error_u32 = NMS_ERR_DEFAULT;
+ uint16 targetPin_u16;
+ GPIO_TypeDef* targetPort_pst = NULL;
+
+ error_u32 = MapHalGpio(pin_en, &targetPin_u16, &targetPort_pst);
+
+ if(error_u32 == NMS_ERR_NONE)
+ {
+ uint32 outpuType_u32 = HAL_GET_GPIO_OUTPUT_TYPE(targetPort_pst, targetPin_u16);
+
+ if(outpuType_u32 == GPIO_MODE_OUTPUT_PP || outpuType_u32 == GPIO_MODE_OUTPUT_OD)
+ {
+ HAL_GPIO_TogglePin(targetPort_pst, targetPin_u16);
+ }
+ }
+ else
+ {
+ error_u32 = NMS_ERR_UNEXPECTED;
+ }
+
+ return error_u32;
+}
+
+
+uint32 HalGpioReConfigure( MapHalGpioPin_en pin_en, HalGpioType_en type_en )
+{
+ uint32 error_u32 = NMS_ERR_DEFAULT;
+ uint16 targetPin_u16;
+ GPIO_TypeDef* targetPort_pst = NULL;
+ GPIO_InitTypeDef gpioInit_st = {0};
+
+ error_u32 = MapHalGpio(pin_en, &targetPin_u16, &targetPort_pst);
+
+ if(error_u32 == NMS_ERR_NONE)
+ {
+ gpioInit_st.Pin = targetPin_u16;
+
+ switch(type_en)
+ {
+ case HAL_GPIO_INPUT:
+ gpioInit_st.Mode = GPIO_MODE_INPUT;
+ gpioInit_st.Pull = GPIO_NOPULL;
+ error_u32 = NMS_ERR_NONE;
+ break;
+
+ case HAL_GPIO_OUTPUT_PUSH_PULL_UP:
+ gpioInit_st.Mode = GPIO_MODE_OUTPUT_PP;
+ gpioInit_st.Pull = GPIO_PULLUP;
+ error_u32 = NMS_ERR_NONE;
+ break;
+
+ case HAL_GPIO_OUTPUT_PUSH_PULL_DOWN:
+ gpioInit_st.Mode = GPIO_MODE_OUTPUT_PP;
+ gpioInit_st.Pull = GPIO_PULLDOWN;
+ error_u32 = NMS_ERR_NONE;
+ break;
+
+ case HAL_GPIO_OUTPUT_PUSH_PULL_FREE:
+ gpioInit_st.Mode = GPIO_MODE_OUTPUT_PP;
+ gpioInit_st.Pull = GPIO_NOPULL;
+ error_u32 = NMS_ERR_NONE;
+ break;
+
+ case HAL_GPIO_OUTPUT_OPEN_DRAIN_UP:
+ gpioInit_st.Mode = GPIO_MODE_OUTPUT_OD;
+ gpioInit_st.Pull = GPIO_PULLUP;
+ error_u32 = NMS_ERR_NONE;
+ break;
+
+ case HAL_GPIO_OUTPUT_OPEN_DRAIN_FREE:
+ gpioInit_st.Mode = GPIO_MODE_OUTPUT_OD;
+ gpioInit_st.Pull = GPIO_NOPULL;
+ error_u32 = NMS_ERR_NONE;
+ break;
+
+ case HAL_GPIO_ISR_RISING:
+ gpioInit_st.Mode = GPIO_MODE_IT_RISING;
+ gpioInit_st.Pull = GPIO_NOPULL;
+ error_u32 = NMS_ERR_NONE;
+ break;
+
+ case HAL_GPIO_ISR_FALLING:
+ gpioInit_st.Mode = GPIO_MODE_IT_FALLING;
+ gpioInit_st.Pull = GPIO_NOPULL;
+ error_u32 = NMS_ERR_NONE;
+ break;
+
+ default: /* HAL_GPIO_ALTERNATE or unknown state. */
+ error_u32 = NMS_ERR_INVALID_ARGUMENT;
+ break;
+ }
+ }
+
+ else
+ {
+ error_u32 = NMS_ERR_UNEXPECTED;
+ }
+
+ /* Deploy hardware modification. */
+ if(error_u32 == NMS_ERR_NONE)
+ {
+ HAL_GPIO_DeInit(targetPort_pst, targetPin_u16);
+ HAL_GPIO_Init(targetPort_pst, &gpioInit_st);
+ }
+
+ return error_u32;
+}
+
+
+uint32 HalGpioSetCallback( MapHalGpioPin_en pin_en, uint32 (*callback_pfn)(HalGpioEdgeType_en edge_en))
+{
+ uint32 error_u32 = NMS_ERR_NONE;
+
+ /* Ideal values of edge are 0 or 1 for now */
+ if ((pin_en < MAP_HAL_GPIO_NUMBER) && (callback_pfn != NULL))
+ {
+#ifdef DEBUG_ISSUE_EXTI_GPIO
+ /* The check is always false. The configuration of interruption is not set in the GPIO settings, but in EXTI setttings.
+ * This part of code need to be update to correct this feature (check the pin wanted is in interruption mode).
+ * mbarth
+ */
+ GPIO_TypeDef* targetPort_pst = NULL;
+ uint32 moder_u32 = HAL_GPIO_GET_INTERRUPT_INPUT_MODE(targetPort_pst, pin_en);
+
+ if ((moder_u32 == GPIO_MODE_IT_RISING) || (moder_u32 == GPIO_MODE_IT_FALLING) || (moder_u32 == GPIO_MODE_IT_RISING_FALLING))
+#endif
+ {
+ halGpioCallbacks[pin_en] = callback_pfn;
+ }
+ }
+ else
+ {
+ error_u32 = NMS_ERR_UNEXPECTED;
+ }
+
+ return error_u32;
+}
+
+/******************************************************************************
+ * Static Function Definitions
+ ******************************************************************************/
+
+/******************************************************************************
+ * Callback Function Definitions
+ ******************************************************************************/
+/**
+ * @brief CubeMX GPIO callback
+ *
+ * @param[in] GPIO_Pin The GPIO pin on which the interrupt occurs
+ *
+ */
+void HAL_GPIO_EXTI_Rising_Callback( uint16 GPIO_Pin )
+{
+ uint32 error_u32 = NMS_ERR_NONE;
+ MapHalGpioPin_en mappedPin_en;
+
+ error_u32 = MapHalGpioCallback(GPIO_Pin, &mappedPin_en);
+
+ if ((error_u32 == NMS_ERR_NONE) && (halGpioCallbacks[mappedPin_en] != NULL))
+ {
+ halGpioCallbacks[mappedPin_en](HAL_GPIO_EDGE_RISING);
+ }
+}
+
+
+/**
+ * @brief CubeMX GPIO falling callback
+ *
+ * @param[in] GPIO_Pin The GPIO pin on which the interrupt occurs
+ *
+ */
+void HAL_GPIO_EXTI_Falling_Callback( uint16 GPIO_Pin )
+{
+ uint32 error_u32 = NMS_ERR_DEFAULT;
+ MapHalGpioPin_en mappedPin_en;
+
+ error_u32 = MapHalGpioCallback(GPIO_Pin, &mappedPin_en);
+
+ if ((error_u32 == NMS_ERR_NONE) && (halGpioCallbacks[mappedPin_en] != NULL))
+ {
+ halGpioCallbacks[mappedPin_en](HAL_GPIO_EDGE_FALLING);
+ }
+}
+
+
+/**
+ * @brief CubeMX GPIO callback
+ *
+ * @param[in] GPIO_Pin The GPIO pin on which the interrupt occurs
+ *
+ */
+void HAL_GPIO_EXTI_Callback( uint16 GPIO_Pin )
+{
+ uint32 error_u32 = NMS_ERR_DEFAULT;
+ MapHalGpioPin_en mappedPin_en;
+
+ error_u32 = MapHalGpioCallback(GPIO_Pin, &mappedPin_en);
+
+ if ((error_u32 == NMS_ERR_NONE) && (halGpioCallbacks[mappedPin_en] != NULL))
+ {
+ halGpioCallbacks[mappedPin_en](HAL_GPIO_EDGE_NONE); /* Default value set for now*/
+ }
+}
diff --git a/EnduranceTestBench/nms_hal/hal_gpio.h b/EnduranceTestBench/nms_hal/hal_gpio.h
new file mode 100644
index 0000000..7a09ab4
--- /dev/null
+++ b/EnduranceTestBench/nms_hal/hal_gpio.h
@@ -0,0 +1,120 @@
+/**
+ * @file hal_gpio.c
+ *
+ * @copyright Nehemis SARL reserves all rights even in the event of industrial
+ * property rights. We reserve all rights of disposal such as
+ * copying and passing on to third parties.
+ *
+ * @brief HAL layer for the GPIO module.
+ *
+ */
+
+
+#ifndef HAL_TIMER_H_
+#define HAL_TIMER_H_
+
+/******************************************************************************
+ * Include Header Files
+ ******************************************************************************/
+#include "nms_types.h"
+#include "map_hal.h"
+
+/******************************************************************************
+ * Type declarations
+ ******************************************************************************/
+typedef enum
+{
+ HAL_GPIO_STATE_UNKNOWN = 0U,
+ HAL_GPIO_STATE_LOW,
+ HAL_GPIO_STATE_HIGH,
+} HalGpioState_en; /**< Enumeration used to analyze the gpio state. */
+
+typedef enum {
+ HAL_GPIO_EDGE_NONE = 0U,
+ HAL_GPIO_EDGE_RISING,
+ HAL_GPIO_EDGE_FALLING,
+ HAL_GPIO_EDGE_RISING_AND_FALLING
+} HalGpioEdgeType_en; /**< Enumeration used to analyze the edge of interrupt. */
+
+typedef enum
+{
+ HAL_GPIO_INPUT = 0U,
+ HAL_GPIO_OUTPUT_PUSH_PULL_UP,
+ HAL_GPIO_OUTPUT_PUSH_PULL_DOWN,
+ HAL_GPIO_OUTPUT_PUSH_PULL_FREE,
+ HAL_GPIO_OUTPUT_OPEN_DRAIN_UP,
+ HAL_GPIO_OUTPUT_OPEN_DRAIN_FREE,
+ HAL_GPIO_ISR_RISING,
+ HAL_GPIO_ISR_FALLING,
+ HAL_GPIO_ALTERNATE
+} HalGpioType_en; /**< Enumeration used to analyze the gpio function type. */
+
+/******************************************************************************
+ * Extern Function Declarations
+ ******************************************************************************/
+/**
+ * @brief Initializes and configures GPIO input/output pins.
+ *
+ * @note Output pins are set to predefined states during initialization.
+ *
+ * @return Pin state: HIGH, LOW, or UNKNOWN.
+ */
+uint32 HalGpioInit(void);
+
+/**
+ * @brief Reads the state of a GPIO input pin.
+ *
+ * @param pin_en GPIO pin selection.
+ * state_pen Pointer to store the read pin state.
+ *
+ * @return Error code: 0 if successful, nonzero otherwise.
+ */
+uint32 HalGpioRead(MapHalGpioPin_en pin_en, HalGpioState_en *state_pen);
+
+/**
+ * @brief Sets the state of a GPIO output pin.
+ *
+ * @param pin_en GPIO pin selection.
+ * state_pen Desired GPIO pin state.
+ *
+ * @return Error code: 0 if successful, nonzero otherwise.
+ */
+uint32 HalGpioWrite(MapHalGpioPin_en pin_en, HalGpioState_en state_pen);
+
+/**
+ * @brief Toggles the state of a GPIO pin.
+ *
+ * @param pin_en GPIO pin selection.
+ *
+ * @return Error code: 0 if successful, nonzero otherwise.
+ */
+uint32 HalGpioToggle(MapHalGpioPin_en pin_en);
+
+/**
+ * @brief Reconfigures the properties of a GPIO pin.
+ *
+ * @param pin_en GPIO pin selection.
+ * type_en GPIO pin type.
+ *
+ * @return Error code: 0 if successful, nonzero otherwise.
+ *
+ * @warning GPIO speed modification is not supported in this driver version.
+ * Future updates may include support for this feature.
+ */
+uint32 HalGpioReConfigure(MapHalGpioPin_en pin_en, HalGpioType_en type_en);
+
+/**
+ * @brief Assigns a callback function for GPIO interrupt events.
+ *
+ * @param pin_en GPIO pin selection.
+ * callback_pfn Pointer to the callback function.
+ * edge_en Interrupt trigger edge:
+ * - 1 for Rising Edge
+ * - 0 for Falling Edge (Consider using an enum for clarity).
+ *
+ * @return Error code: 0 if successful, nonzero otherwise.
+ */
+uint32 HalGpioSetCallback(MapHalGpioPin_en pin_en, uint32 (*callback_pfn)(HalGpioEdgeType_en edge_en));
+
+
+#endif /* HAL_GPIO_H_ */
diff --git a/EnduranceTestBench/nms_hal/hal_i2c.c b/EnduranceTestBench/nms_hal/hal_i2c.c
new file mode 100644
index 0000000..83da0e3
--- /dev/null
+++ b/EnduranceTestBench/nms_hal/hal_i2c.c
@@ -0,0 +1,97 @@
+/******************************************************************************
+ * @file hal_i2c.c
+ * @copyright Nehemis SARL reserves all rights even in the event of industrial
+ * property rights. We reserve all rights of disposal such as
+ * copying and passing on to third parties.
+ *
+ * @brief STM HAL layer wrapper class for I2C.
+ *
+ ******************************************************************************/
+
+/******************************************************************************
+ * Include Header Files
+ ******************************************************************************/
+#include "hal_i2c.h"
+
+/* CubeMX */
+#include "i2c.h"
+
+/******************************************************************************
+ * Function Definitions
+ ******************************************************************************/
+uint32 HalI2CInit(void)
+{
+ return NMS_ERR_NONE;
+}
+
+
+uint32 HalI2CWrite(MapHalI2cModule_en module_en, uint16 devAddr_u16, uint16 memAddr_u16, uint16 memAddrSize_u16, uint8 *pData_pu8, uint16 size_u16)
+{
+ uint32 error_u32 = NMS_ERR_NONE;
+ HAL_StatusTypeDef halStatus_en = HAL_OK;
+ I2C_HandleTypeDef *targetModule_pst;
+
+ error_u32 = MapHalI2cModule(module_en, &targetModule_pst);
+ if (error_u32 == NMS_ERR_NONE)
+ {
+ halStatus_en = HAL_I2C_Mem_Write(targetModule_pst, devAddr_u16, memAddr_u16, memAddrSize_u16, pData_pu8, size_u16, HAL_MAX_DELAY);
+
+ switch (halStatus_en)
+ {
+ case HAL_BUSY: error_u32 = NMS_ERR_BUSY; break;
+ case HAL_TIMEOUT: error_u32 = NMS_ERR_TIMEOUT; break;
+ case HAL_ERROR: error_u32 = NMS_ERR_INTERNAL; break;
+ case HAL_OK: error_u32 = NMS_ERR_NONE; break;
+ default: error_u32 = NMS_ERR_UNKNOWN; break;
+ }
+ }
+ return error_u32;
+}
+
+
+uint32 HalI2CRead(MapHalI2cModule_en module_en, uint16 devAddr_u16, uint16 memAddr_u16, uint16 memAddrSize_u16, uint8 *pData_pu8, uint16 size_u16)
+{
+ uint32 error_u32 = NMS_ERR_NONE;
+ HAL_StatusTypeDef halStatus_en = HAL_OK;
+ I2C_HandleTypeDef *targetModule_pst;
+
+ error_u32 = MapHalI2cModule(module_en, &targetModule_pst);
+ if (error_u32 == NMS_ERR_NONE)
+ {
+ halStatus_en = HAL_I2C_Mem_Read(targetModule_pst, devAddr_u16, memAddr_u16, memAddrSize_u16, pData_pu8, size_u16, HAL_MAX_DELAY);
+
+ switch (halStatus_en)
+ {
+ case HAL_BUSY: error_u32 = NMS_ERR_BUSY; break;
+ case HAL_TIMEOUT: error_u32 = NMS_ERR_TIMEOUT; break;
+ case HAL_ERROR: error_u32 = NMS_ERR_INTERNAL; break;
+ case HAL_OK: error_u32 = NMS_ERR_NONE; break;
+ default: error_u32 = NMS_ERR_UNKNOWN; break;
+ }
+ }
+ return error_u32;
+}
+
+
+uint32 HalI2CMasterTransmit(MapHalI2cModule_en module_en, uint16 devAddr_u16, uint8 *pData_pu8, uint16 size_u16)
+{
+ uint32 error_u32 = NMS_ERR_NONE;
+ HAL_StatusTypeDef halStatus_en = HAL_OK;
+ I2C_HandleTypeDef *targetModule_pst;
+
+ error_u32 = MapHalI2cModule(module_en, &targetModule_pst);
+ if (error_u32 == NMS_ERR_NONE)
+ {
+ halStatus_en = HAL_I2C_Master_Transmit(targetModule_pst, devAddr_u16, pData_pu8, size_u16, HAL_MAX_DELAY);
+
+ switch (halStatus_en)
+ {
+ case HAL_BUSY: error_u32 = NMS_ERR_BUSY; break;
+ case HAL_TIMEOUT: error_u32 = NMS_ERR_TIMEOUT; break;
+ case HAL_ERROR: error_u32 = NMS_ERR_INTERNAL; break;
+ case HAL_OK: error_u32 = NMS_ERR_NONE; break;
+ default: error_u32 = NMS_ERR_UNKNOWN; break;
+ }
+ }
+ return error_u32;
+}
diff --git a/EnduranceTestBench/nms_hal/hal_i2c.h b/EnduranceTestBench/nms_hal/hal_i2c.h
new file mode 100644
index 0000000..de3faed
--- /dev/null
+++ b/EnduranceTestBench/nms_hal/hal_i2c.h
@@ -0,0 +1,77 @@
+/******************************************************************************
+ * @file hal_i2c.h
+ * @copyright Nehemis SARL reserves all rights even in the event of industrial
+ * property rights. We reserve all rights of disposal such as
+ * copying and passing on to third parties.
+ *
+ * @brief STM HAL layer wrapper class for I2C.
+ *
+ ******************************************************************************/
+
+#ifndef HAL_I2C_H
+#define HAL_I2C_H
+
+/******************************************************************************
+ * Include Header Files
+ ******************************************************************************/
+#include "map_hal.h"
+#include "nms_types.h"
+#include "stdint.h"
+#include "i2c.h"
+/******************************************************************************
+ * Function Prototypes
+ ******************************************************************************/
+/**
+ * @brief Initializes the I2C hardware interface.
+ * This function configures the necessary resources and sets up the
+ * I2C hardware to prepare it for use.
+ *
+ * @return Error code: 0 if successful, nonzero otherwise.
+ */
+uint32 HalI2CInit(void);
+
+/**
+ * @brief Reads data from a specific memory address on an I2C device.
+ * This function sends a memory read request to the I2C device and
+ * stores the received data in a provided buffer.
+ *
+ * @param module_en The I2C module to be used (depends on the system configuration).
+ * devAddr_u16 The 7-bit address of the I2C device.
+ * memAddr_u16 The memory address within the I2C device to read from.
+ * memAddrSize_u16 The size of the memory address (e.g., 8-bit, 16-bit).
+ * pData_pu8 Pointer to the buffer where the read data will be stored.
+ * size_u16 Number of bytes to read.
+ *
+ * @return Error code: 0 if successful, nonzero otherwise.
+ */
+uint32 HalI2CRead(MapHalI2cModule_en module_en, uint16 devAddr_u16, uint16 memAddr_u16, uint16 memAddrSize_u16, uint8 *pData_pu8, uint16 size_u16);
+
+/**
+ * @brief Writes data to a specific memory address on an I2C device.
+ * This function sends a memory write request to the I2C device to
+ * write data from the provided buffer to the device's memory.
+ *
+ * @param module_en The I2C module to be used (depends on the system configuration).
+ * devAddr_u16 The 7-bit address of the I2C device.
+ * memAddr_u16 The memory address within the I2C device to read from.
+ * memAddrSize_u16 The size of the memory address (e.g., 8-bit, 16-bit).
+ * pData_pu8 Pointer to the buffer where the read data will be stored.
+ * size_u16 Number of bytes to write.
+ *
+ * @return Error code: 0 if successful, nonzero otherwise.
+ */
+uint32 HalI2CWrite(MapHalI2cModule_en module_en, uint16 devAddr_u16, uint16 memAddr_u16, uint16 memAddrSize_u16, uint8 *pData_pu8, uint16 size_u16);
+
+/**
+ * @brief Transmits in master mode an amount of data in blocking mode.
+ *
+ * @param module_en The I2C module to be used (depends on the system configuration).
+ * devAddr_u16 The 7-bit address of the I2C device.
+ * pData_pu8 Pointer to the buffer where the read data will be stored.
+ * size_u16 Number of bytes to write.
+ *
+ * @return Error code: 0 if successful, nonzero otherwise.
+ */
+uint32 HalI2CMasterTransmit(MapHalI2cModule_en module_en, uint16 devAddr_u16, uint8 *pData_pu8, uint16 size_u16);
+
+#endif /* HAL_I2C_H */
diff --git a/EnduranceTestBench/nms_hal/hal_system.c b/EnduranceTestBench/nms_hal/hal_system.c
new file mode 100644
index 0000000..336f9c9
--- /dev/null
+++ b/EnduranceTestBench/nms_hal/hal_system.c
@@ -0,0 +1,250 @@
+/**
+ * @file hal_system.c
+ * @copyright Nehemis SARL reserves all rights even in the event of industrial
+ * property rights. We reserve all rights of disposal such as
+ * copying and passing on to third parties.
+ *
+ *
+ * @brief HAL layer for the SYSTEM module.
+ * - The system reset cause such as :
+ * 1. Software reset
+ * 2. Watchdog reset
+ * 3. Power on reset
+ * 4. Optional byte load reset
+ * 5. Low power reset
+ * 6. Pin reset
+ * - The NVIC enable/disable interrupts.
+ * - The serial number of the MCU.
+ */
+
+/******************************************************************************
+ * Include Header Files
+ ******************************************************************************/
+#include "hal_system.h"
+#include "string.h"
+
+/* cubeMX */
+#include "main.h"
+/******************************************************************************
+ * Macro Constant Declarations
+ ******************************************************************************/
+#define HAL_SYSTEM_STACK_GUARD 0xCDu
+
+/******************************************************************************
+ * Module Global Variable Declarations
+ ******************************************************************************/
+static uint64 systemStepCounter_gu64;
+static uint64 systemPeriodMsToUs_gu64;
+static uint64 systemTickLoadValue_gu64;
+static uint32 resetStatusRegister_gu32;
+
+/******************************************************************************
+ * Static Function Declarations
+ ******************************************************************************/
+
+/******************************************************************************
+ * Extern Function Definitions
+ ******************************************************************************/
+uint32 HalSystemInit(void)
+{
+ uint32 error_u32 = NMS_ERR_NONE;
+
+ resetStatusRegister_gu32 = RCC->CSR;
+ RCC->CSR |= RCC_CSR_RMVF; /* RMVF = ReMoVe Flag. Reset the reset cause register for the next reboot. */
+
+ systemPeriodMsToUs_gu64 = HAL_GetTickFreq() * 1000uLL;
+ systemTickLoadValue_gu64 = (uint64)(SysTick->LOAD);
+ systemStepCounter_gu64 = 0uLL;
+
+ return error_u32;
+}
+
+
+uint32 HalSystemGetRunTimeUs(uint64 * resultUs_pu64)
+{
+ static uint64 previousTimeUs_u64 = 0uLL;
+ uint32 error_u32 = NMS_ERR_NONE;
+ uint64 timeUs_u64 = 0uLL;
+
+ /* Make a copy in case of multiple function instance at the same time */
+ uint64 copySystemStepCounter_u64 = systemStepCounter_gu64;
+
+ /* First make a copy of the systemStepCounter to be able to check rollback further on.
+ * Also copy current value of the System Tick Timer to avoid any dynamic update during calculation.
+ * Then translate in microsecond & sum both timing information (step counter + tick value) to get the most
+ * accurate resolution of the system runtime.
+ */
+ uint64 copyPreviousTimeUs_u64 = previousTimeUs_u64;
+ uint64 tickValue_u64 = (uint64)(SysTick->VAL);
+ timeUs_u64 = copySystemStepCounter_u64 * systemPeriodMsToUs_gu64;
+ timeUs_u64 += ((systemTickLoadValue_gu64 - tickValue_u64) * systemPeriodMsToUs_gu64) / systemTickLoadValue_gu64;
+
+ /* We check here if the interruption of the systick happened during our operations and correct it accordingly */
+ if(timeUs_u64 <= (uint64)(systemStepCounter_gu64 * systemPeriodMsToUs_gu64))
+ {
+ copySystemStepCounter_u64 = systemStepCounter_gu64;
+ tickValue_u64 = (uint64)(SysTick->VAL);
+ timeUs_u64 = copySystemStepCounter_u64 * systemPeriodMsToUs_gu64;
+ timeUs_u64 += ((systemTickLoadValue_gu64 - tickValue_u64) * systemPeriodMsToUs_gu64) / systemTickLoadValue_gu64;
+
+ /* The timer interruption is too fast, no time to process */
+ if(timeUs_u64 <= (uint64)(systemStepCounter_gu64 * systemPeriodMsToUs_gu64))
+ {
+ error_u32 = NMS_ERR_OVERRUN;
+ }
+ }
+
+ /* Should never happen if this timer interruption is set to highest priority */
+ if(copyPreviousTimeUs_u64 > timeUs_u64)
+ {
+ error_u32 = NMS_ERR_UNKNOWN;
+ }
+ else
+ {
+ *resultUs_pu64 = previousTimeUs_u64;
+ }
+
+ /* This condition has been added to prevent trouble overflow with interruptions
+ on the medium and high optimizations options */
+ *resultUs_pu64 = (timeUs_u64 > previousTimeUs_u64) ? timeUs_u64 : *resultUs_pu64;
+
+ return error_u32;
+}
+
+
+/* This function should not call the log, since it uses the system runtime. */
+uint32 HalSystemGetRunTimeMs(uint64 * resultMs_pu64)
+{
+ *resultMs_pu64 = systemStepCounter_gu64;
+
+ return NMS_ERR_NONE;
+}
+
+
+void HalSystemGetSerialId(uint8 * serialIdBuffer_pu8)
+{
+ uint32 serialIdW0_u32, serialIdW1_u32, serialIdW2_u32;
+
+ /* Get the three parts of the UID */
+ serialIdW0_u32 = HAL_GetUIDw0();
+ serialIdW1_u32 = HAL_GetUIDw1();
+ serialIdW2_u32 = HAL_GetUIDw2();
+
+ /* Copy the values into the serial ID buffer */
+ memcpy(&serialIdBuffer_pu8[0], &serialIdW0_u32, sizeof(serialIdW0_u32));
+ memcpy(&serialIdBuffer_pu8[4], &serialIdW1_u32, sizeof(serialIdW1_u32));
+ memcpy(&serialIdBuffer_pu8[8], &serialIdW2_u32, sizeof(serialIdW2_u32));
+}
+
+
+uint32 HalSystemGetResetCause( HalSystemResetCauseEn resetCauseSelector_en, uint32 * causes_pu32 )
+{
+ uint32 error_u32 = NMS_ERR_DEFAULT;
+ uint32 mask_u32 = 0uL;
+
+ if (causes_pu32 == NULL)
+ {
+ error_u32 = NMS_ERR_INVALID_POINTER;
+ }
+ else
+ {
+ switch(resetCauseSelector_en)
+ {
+ case HAL_SYSTEM_RESET_CAUSE_OPTION_BYTE_LOADER:
+ mask_u32 = RCC_CSR_OBLRSTF_Msk;
+ error_u32 = NMS_ERR_NONE;
+ break;
+
+ case HAL_SYSTEM_RESET_CAUSE_EXTERNAL_PIN_RESET:
+ mask_u32 = RCC_CSR_PINRSTF_Msk;
+ error_u32 = NMS_ERR_NONE;
+ break;
+
+ case HAL_SYSTEM_RESET_CAUSE_BROWNOUT_RESET:
+ mask_u32 = RCC_CSR_BORRSTF_Msk;
+ error_u32 = NMS_ERR_NONE;
+ break;
+
+ case HAL_SYSTEM_RESET_CAUSE_SOFTWARE_RESET:
+ mask_u32 = RCC_CSR_SFTRSTF_Msk;
+ error_u32 = NMS_ERR_NONE;
+ break;
+
+ case HAL_SYSTEM_RESET_CAUSE_WATCH_DOG_TIMER:
+ mask_u32 = RCC_CSR_IWDGRSTF_Msk;
+ error_u32 = NMS_ERR_NONE;
+ break;
+
+ case HAL_SYSTEM_RESET_CAUSE_WINDOW_WATCH_DOG:
+ mask_u32 = RCC_CSR_WWDGRSTF_Msk;
+ error_u32 = NMS_ERR_NONE;
+ break;
+
+ case HAL_SYSTEM_RESET_CAUSE_LOW_POWER:
+ mask_u32 = RCC_CSR_LPWRRSTF_Msk;
+ error_u32 = NMS_ERR_NONE;
+ break;
+
+ case HAL_SYSTEM_RESET_CAUSE_ALL_CAUSES:
+ mask_u32 = RCC_CSR_IWDGRSTF_Msk
+ | RCC_CSR_WWDGRSTF_Msk
+ | RCC_CSR_SFTRSTF_Msk
+ | RCC_CSR_PINRSTF_Msk
+ | RCC_CSR_LPWRRSTF_Msk
+ | RCC_CSR_BORRSTF_Msk;
+ error_u32 = NMS_ERR_NONE;
+ break;
+
+ default:
+
+ error_u32 = NMS_ERR_UNKNOWN;
+ break;
+ }
+
+ *causes_pu32 = resetStatusRegister_gu32 & mask_u32;
+ }
+
+ return error_u32;
+}
+
+
+void HalSystemDisableInterrupts(void)
+{
+ __disable_irq();
+}
+
+
+void HalSystemEnableInterrupts(void)
+{
+ __enable_irq();
+}
+
+
+void HalSystemReset(void)
+{
+ HAL_NVIC_SystemReset();
+}
+
+/******************************************************************************
+ * Callback Function Definitions
+ ******************************************************************************/
+/**
+* @brief Count the number of milliseconds that elapsed since the start
+*
+* @note Function called by low-level functions of cubeMX
+*/
+void HAL_IncTick(void)
+{
+ systemStepCounter_gu64++;
+}
+
+
+/**
+* @brief Provides a tick value in millisecond.
+*
+* @return The number of elapsed tick.
+*/
+uint32 HAL_GetTick(void)
+{
+ return (uint32)systemStepCounter_gu64;
+}
diff --git a/EnduranceTestBench/nms_hal/hal_system.h b/EnduranceTestBench/nms_hal/hal_system.h
new file mode 100644
index 0000000..daa1fc1
--- /dev/null
+++ b/EnduranceTestBench/nms_hal/hal_system.h
@@ -0,0 +1,114 @@
+/**
+ * @file hal_system.h
+ * @copyright Nehemis SARL reserves all rights even in the event of industrial
+ * property rights. We reserve all rights of disposal such as
+ * copying and passing on to third parties.
+ *
+ *
+ * @brief Header file for HAL layer for the SYSTEM module.
+ *
+ */
+
+#ifndef INCLUDED_HAL_SYSTEM_H
+#define INCLUDED_HAL_SYSTEM_H
+
+/******************************************************************************
+ * Include Header Files
+ ******************************************************************************/
+#include "nms_types.h"
+
+/******************************************************************************
+ * Macros Constant Declarations
+ ******************************************************************************/
+#define SERIAL_ID_BUFFER_SIZE 12
+
+/******************************************************************************
+ * Types Declarations
+ ******************************************************************************/
+typedef enum
+{
+ HAL_SYSTEM_RESET_CAUSE_OPTION_BYTE_LOADER,
+ HAL_SYSTEM_RESET_CAUSE_EXTERNAL_PIN_RESET,
+ HAL_SYSTEM_RESET_CAUSE_BROWNOUT_RESET,
+ HAL_SYSTEM_RESET_CAUSE_SOFTWARE_RESET,
+ HAL_SYSTEM_RESET_CAUSE_WATCH_DOG_TIMER,
+ HAL_SYSTEM_RESET_CAUSE_WINDOW_WATCH_DOG,
+ HAL_SYSTEM_RESET_CAUSE_LOW_POWER,
+ HAL_SYSTEM_RESET_CAUSE_ALL_CAUSES
+} HalSystemResetCauseEn; /**< Enumeration used to analyze the reset cause location. */
+
+/******************************************************************************
+ * Global Variables Declarations
+ ******************************************************************************/
+
+/******************************************************************************
+ * Extern Functions Declarations
+ ******************************************************************************/
+
+/**
+ * @brief Initializes the system HAL.
+ *
+ * @note CAUTION: This function must be called immediately after
+ * SystemClock_Config() in the main function to ensure correct
+ * operation and prevent potential software issues.
+ *
+ * @return Error code: 0 if successful, nonzero otherwise.
+ */
+uint32 HalSystemInit(void);
+
+/**
+ * @brief Retrieves the system runtime in microseconds.
+ *
+ * @param resultUs_pu64 Pointer to store the system runtime in microseconds.
+ *
+ * @note The tick resolution depends on the system tick frequency.
+ *
+ * @return Error code: 0 if successful, nonzero otherwise.
+ */
+uint32 HalSystemGetRunTimeUs(uint64 *resultUs_pu64);
+
+/**
+ * @brief Retrieves the system runtime in milliseconds.
+ *
+ * @param resultMs_pu64 Pointer to store the system runtime in milliseconds.
+ *
+ * @note The tick resolution depends on the system tick frequency.
+ *
+ * @return Error code: 0 if successful, nonzero otherwise.
+ */
+uint32 HalSystemGetRunTimeMs(uint64 *resultMs_pu64);
+
+/**
+ * @brief Disables all system interrupts.
+ */
+void HalSystemDisableInterrupts(void);
+
+/**
+ * @brief Enables all system interrupts.
+ */
+void HalSystemEnableInterrupts(void);
+
+/**
+ * @brief Retrieves the cause of the last system reset from the MCU registers.
+ *
+ * @param resetCauseSelector_en Enum specifying the reset cause type.
+ * causes_pu32 Pointer to store the corresponding bitmask value.
+ *
+ * @return Error code: 0 if successful, nonzero otherwise.
+ */
+uint32 HalSystemGetResetCause(HalSystemResetCauseEn resetCauseSelector_en, uint32 *causes_pu32);
+
+/**
+ * @brief Retrieves the system's unique serial ID.
+ *
+ * @param serialIdBuffer_pu8 Pointer to the buffer where the serial ID will be stored.
+ */
+void HalSystemGetSerialId(uint8 *serialIdBuffer_pu8);
+
+/**
+ * @brief Performs a software reset of the system.
+ */
+void HalSystemReset(void);
+
+
+#endif /* INCLUDED_HAL_SYSTEM_H */
diff --git a/EnduranceTestBench/nms_hal/hal_timer.c b/EnduranceTestBench/nms_hal/hal_timer.c
new file mode 100644
index 0000000..17a939f
--- /dev/null
+++ b/EnduranceTestBench/nms_hal/hal_timer.c
@@ -0,0 +1,546 @@
+/**
+ * @file hal_timer.c
+ *
+ * @copyright Nehemis SARL reserves all rights even in the event of industrial
+ * property rights. We reserve all rights of disposal such as
+ * copying and passing on to third parties.
+ *
+ * @brief HAL layer for the TIMER module.
+ *
+ */
+
+/******************************************************************************
+ * Include Header Files
+ ******************************************************************************/
+#include "map_hal.h"
+#include "hal_timer.h"
+
+/* CubeMX */
+#include "tim.h"
+
+/******************************************************************************
+ * Macro constant declarations
+ ******************************************************************************/
+#define HAL_TIMER_SEC_TO_MSEC 1000000uLL /**< Number of microseconds within a second */
+
+/******************************************************************************
+ * Type declarations
+ ******************************************************************************/
+typedef struct
+{
+ uint64 timerPeriod_u64;
+ uint64 downCounter_u64;
+} HalTimerInstance_tst;
+
+/******************************************************************************
+ * Module Global Variable Declarations
+ ******************************************************************************/
+static HalTimerInstance_tst instance_gast[MAP_HAL_TIMER_NUMBER] = {0};
+static uint32 (*halTimerCallbacks[MAP_HAL_TIMER_NUMBER])(void);
+
+/******************************************************************************
+ * Static Function Declarations
+ ******************************************************************************/
+static uint32 HalTimerComputeTimerPeriod(MapHalTimerModule_en timerModule_en, uint64 * timerPeriod_u64);
+
+/******************************************************************************
+ * Extern Function Definition
+ ******************************************************************************/
+uint32 HalTimerInit(void)
+{
+ uint32 error_u32 = NMS_ERR_NONE;
+
+ for(uint8 i_u8 = 0u; i_u8 < MAP_HAL_TIMER_NUMBER; i_u8++)
+ {
+ uint64 timerPeriod_u64 = 0uLL;
+ error_u32 = HalTimerComputeTimerPeriod((MapHalTimerModule_en)(i_u8), &timerPeriod_u64);
+
+ if (error_u32 == NMS_ERR_NONE)
+ {
+ instance_gast[i_u8].timerPeriod_u64 = timerPeriod_u64;
+ instance_gast[i_u8].downCounter_u64 = 0uLL;
+ }
+ }
+
+ return error_u32;
+}
+
+
+uint32_t HalTimerGetCounter(MapHalTimerModule_en timerModule_en)
+{
+ TIM_HandleTypeDef *targetModule_pst = NULL;
+
+ /* Get the timer handle using MapHalTimerModule */
+ if (MapHalTimerModule(timerModule_en, &targetModule_pst) != NMS_ERR_NONE || targetModule_pst == NULL)
+ {
+ return 0;
+ }
+
+ return (uint32)(targetModule_pst->Instance->CNT);
+}
+
+
+void HalTimerSetCounter(MapHalTimerModule_en timerModule_en, uint32 counter_u32)
+{
+ TIM_HandleTypeDef *targetModule_pst = NULL;
+
+ if (MapHalTimerModule(timerModule_en, &targetModule_pst) != NMS_ERR_NONE || targetModule_pst == NULL)
+ {
+ return;
+ }
+
+ targetModule_pst->Instance->CNT = counter_u32;
+}
+
+
+void HalTimerSetCompare(MapHalTimerModule_en timerModule_en, uint32 channel_u32, uint32 compareValue_32)
+{
+ TIM_HandleTypeDef *targetModule_pst = NULL;
+
+ if (MapHalTimerModule(timerModule_en, &targetModule_pst) != NMS_ERR_NONE || targetModule_pst == NULL)
+ {
+ /* Handle the error (e.g., log it or return early) */
+ return;
+ }
+ switch (channel_u32)
+ {
+ case TIM_CHANNEL_1:
+ targetModule_pst->Instance->CCR1 = compareValue_32; break;
+
+ case TIM_CHANNEL_2:
+ targetModule_pst->Instance->CCR2 = compareValue_32; break;
+
+ case TIM_CHANNEL_3:
+ targetModule_pst->Instance->CCR3 = compareValue_32; break;
+
+ case TIM_CHANNEL_4:
+ targetModule_pst->Instance->CCR4 = compareValue_32; break;
+
+ #ifdef TIM_CHANNEL_5
+ case TIM_CHANNEL_5:
+ targetModule_pst->Instance->CCR5 = compareValue_32; break;
+ #endif
+
+ #ifdef TIM_CHANNEL_6
+ case TIM_CHANNEL_6:
+ targetModule_pst->Instance->CCR6 = compareValue_32; break;
+ #endif
+
+ default:
+ /* Invalid channel case (log or handle the error) */
+ break;
+ }
+}
+
+
+uint32 HalTimerGetAutoReload(MapHalTimerModule_en timerModule_en)
+{
+ TIM_HandleTypeDef *targetModule_pst = NULL;
+
+ if (MapHalTimerModule(timerModule_en, &targetModule_pst) != NMS_ERR_NONE || targetModule_pst == NULL)
+ {
+ /* Error */
+ }
+
+ return (uint32)(targetModule_pst->Instance->ARR);
+}
+
+
+
+uint32 HalTimerEncoderStart(MapHalTimerModule_en timerModule_en)
+{
+ uint32 error_u32 = NMS_ERR_DEFAULT;
+
+ HAL_StatusTypeDef halTimerStatus_en = NMS_ERR_NONE;
+ TIM_HandleTypeDef * targetModule_pst;
+
+ error_u32 = MapHalTimerModule(timerModule_en, &targetModule_pst);
+
+ if(error_u32 == NMS_ERR_NONE)
+ {
+ /* Start the requested timer */
+ halTimerStatus_en = HAL_TIM_Encoder_Start(targetModule_pst, TIM_CHANNEL_ALL);
+
+ switch(halTimerStatus_en)
+ {
+ case HAL_BUSY: error_u32 = NMS_ERR_BUSY; break;
+ case HAL_TIMEOUT: error_u32 = NMS_ERR_TIMEOUT; break;
+ case HAL_ERROR: error_u32 = NMS_ERR_UNKNOWN; break;
+ case HAL_OK: error_u32 = NMS_ERR_NONE; break;
+ default: error_u32 = NMS_ERR_UNKNOWN; break;
+ }
+ }
+
+ return error_u32;
+}
+
+
+uint32 HalTimerEncoderStop(MapHalTimerModule_en timerModule_en)
+{
+ uint32 error_u32 = NMS_ERR_DEFAULT;
+
+ HAL_StatusTypeDef halTimerStatus_en = NMS_ERR_NONE;
+ TIM_HandleTypeDef * targetModule_pst;
+
+ error_u32 = MapHalTimerModule(timerModule_en, &targetModule_pst);
+
+ if(error_u32 == NMS_ERR_NONE)
+ {
+ /* Start the requested timer */
+ halTimerStatus_en = HAL_TIM_Encoder_Stop(targetModule_pst, TIM_CHANNEL_ALL);
+
+ switch(halTimerStatus_en)
+ {
+ case HAL_BUSY: error_u32 = NMS_ERR_BUSY; break;
+ case HAL_TIMEOUT: error_u32 = NMS_ERR_TIMEOUT; break;
+ case HAL_ERROR: error_u32 = NMS_ERR_UNKNOWN; break;
+ case HAL_OK: error_u32 = NMS_ERR_NONE; break;
+ default: error_u32 = NMS_ERR_UNKNOWN; break;
+ }
+ }
+
+ return error_u32;
+}
+
+
+uint32 HalTimerPwmStart(MapHalTimerModule_en timerModule_en, uint32 Channel_u32)
+{
+ uint32 error_u32 = NMS_ERR_DEFAULT;
+
+ HAL_StatusTypeDef halTimerStatus_en = NMS_ERR_NONE;
+ TIM_HandleTypeDef * targetModule_pst;
+
+ error_u32 = MapHalTimerModule(timerModule_en, &targetModule_pst);
+
+ if(error_u32 == NMS_ERR_NONE)
+ {
+ /* Start the requested timer */
+ halTimerStatus_en = HAL_TIM_PWM_Start(targetModule_pst, Channel_u32);
+
+ switch(halTimerStatus_en)
+ {
+ case HAL_BUSY: error_u32 = NMS_ERR_BUSY; break;
+ case HAL_TIMEOUT: error_u32 = NMS_ERR_TIMEOUT; break;
+ case HAL_ERROR: error_u32 = NMS_ERR_UNKNOWN; break;
+ case HAL_OK: error_u32 = NMS_ERR_NONE; break;
+ default: error_u32 = NMS_ERR_UNKNOWN; break;
+ }
+ }
+
+ return error_u32;
+}
+
+
+uint32 HalTimerPwmStop(MapHalTimerModule_en timerModule_en, uint32 Channel_u32)
+{
+ uint32 error_u32 = NMS_ERR_DEFAULT;
+
+ HAL_StatusTypeDef halTimerStatus_en = NMS_ERR_NONE;
+ TIM_HandleTypeDef * targetModule_pst;
+
+ error_u32 = MapHalTimerModule(timerModule_en, &targetModule_pst);
+
+ if(error_u32 == NMS_ERR_NONE)
+ {
+ /* Stop the requested timer */
+ halTimerStatus_en = HAL_TIM_PWM_Stop(targetModule_pst, Channel_u32);
+
+ switch(halTimerStatus_en)
+ {
+ case HAL_BUSY: error_u32 = NMS_ERR_BUSY; break;
+ case HAL_TIMEOUT: error_u32 = NMS_ERR_TIMEOUT; break;
+ case HAL_ERROR: error_u32 = NMS_ERR_UNKNOWN; break;
+ case HAL_OK: error_u32 = NMS_ERR_NONE; break;
+ default: error_u32 = NMS_ERR_UNKNOWN; break;
+ }
+ }
+
+ return error_u32;
+}
+
+
+uint32 HalTimerStart(MapHalTimerModule_en timerModule_en)
+{
+ uint32 error_u32 = NMS_ERR_DEFAULT;
+
+ HAL_StatusTypeDef halTimerStatus_en = NMS_ERR_NONE;
+ TIM_HandleTypeDef * targetModule_pst;
+
+ error_u32 = MapHalTimerModule(timerModule_en, &targetModule_pst);
+
+ if(error_u32 == NMS_ERR_NONE)
+ {
+ /* Start the requested timer */
+ halTimerStatus_en = HAL_TIM_Base_Start_IT(targetModule_pst);
+
+ switch(halTimerStatus_en)
+ {
+ case HAL_BUSY: error_u32 = NMS_ERR_BUSY; break;
+ case HAL_TIMEOUT: error_u32 = NMS_ERR_TIMEOUT; break;
+ case HAL_ERROR: error_u32 = NMS_ERR_UNKNOWN; break;
+ case HAL_OK: error_u32 = NMS_ERR_NONE; break;
+ default: error_u32 = NMS_ERR_UNKNOWN; break;
+ }
+ }
+
+ return error_u32;
+}
+
+
+uint32 HalTimerStop(MapHalTimerModule_en timerModule_en)
+{
+ uint32 error_u32 = NMS_ERR_DEFAULT;
+ HAL_StatusTypeDef halTimerStatus_en = NMS_ERR_NONE;
+ TIM_HandleTypeDef * targetModule_pst;
+
+ error_u32 = MapHalTimerModule(timerModule_en, &targetModule_pst);
+
+ if(error_u32 == NMS_ERR_NONE)
+ {
+ /* Stop the requested timer */
+ halTimerStatus_en = HAL_TIM_Base_Stop_IT(targetModule_pst);
+
+ switch(halTimerStatus_en)
+ {
+ case HAL_BUSY: error_u32 = NMS_ERR_BUSY; break;
+ case HAL_TIMEOUT: error_u32 = NMS_ERR_TIMEOUT; break;
+ case HAL_ERROR: error_u32 = NMS_ERR_UNKNOWN; break;
+ case HAL_OK: error_u32 = NMS_ERR_NONE; break;
+ default: error_u32 = NMS_ERR_UNKNOWN; break;
+ }
+ }
+
+ return error_u32;
+}
+
+
+uint32 HalTimerReloadUs(MapHalTimerModule_en timerModule_en, uint64 period_u64)
+{
+ uint32 error_u32 = NMS_ERR_DEFAULT;
+ TIM_HandleTypeDef * targetModule_pst;
+
+ error_u32 = MapHalTimerModule(timerModule_en, &targetModule_pst);
+
+ if(error_u32 == NMS_ERR_NONE)
+ {
+ if(period_u64 == 0uLL)
+ {
+ error_u32 = NMS_ERR_UNKNOWN;
+ }
+ else
+ {
+ /* Compute the number of step that we need to count */
+ instance_gast[timerModule_en].downCounter_u64 = period_u64 / instance_gast[timerModule_en].timerPeriod_u64;
+ if((instance_gast[timerModule_en].downCounter_u64 * instance_gast[timerModule_en].timerPeriod_u64) < period_u64)
+ {
+ instance_gast[timerModule_en].downCounter_u64++;
+ }
+ else
+ {
+ error_u32 = NMS_ERR_UNKNOWN;
+ }
+ }
+ }
+
+ return error_u32;
+}
+
+
+uint32 HalTimerGetRemainingTimeUs(MapHalTimerModule_en timerModule_en, uint64 * remainingTime_pu64)
+{
+ uint32 error_u32 = NMS_ERR_DEFAULT;
+ TIM_HandleTypeDef * targetModule_pst;
+
+ error_u32 = MapHalTimerModule(timerModule_en, &targetModule_pst);
+
+ if(error_u32 == NMS_ERR_NONE)
+ {
+ /* Add the time corresponding to the number of interruption left for this timer */
+ *remainingTime_pu64 = instance_gast[timerModule_en].downCounter_u64;
+ *remainingTime_pu64 *= instance_gast[timerModule_en].timerPeriod_u64;
+ }
+ else
+ {
+ error_u32 = NMS_ERR_UNKNOWN;
+ }
+
+ return error_u32;
+}
+
+
+uint32 HalTimerConfigureCallback(MapHalTimerModule_en timerModule_en, void (*callback_pfn)(void))
+{
+ uint32 error_u32 = NMS_ERR_DEFAULT;
+
+ if (timerModule_en < MAP_HAL_TIMER_NUMBER )
+ {
+ halTimerCallbacks[timerModule_en] = callback_pfn;
+ error_u32 = NMS_ERR_NONE;
+ }
+ else
+ {
+ error_u32 = NMS_ERR_UNKNOWN;
+ }
+
+ return error_u32;
+}
+
+void HalTimerDeinit(MapHalTimerModule_en timerModule_en)
+{
+ uint32 error_u32 = NMS_ERR_DEFAULT;
+ TIM_HandleTypeDef * targetModule_pst;
+ uint8 index_u8;
+ uint8 startIndex_u8;
+ uint8 iteration_u8 = 1u; /* Default to 1 loop iteration (deinit one module) */
+
+ if(timerModule_en == MAP_HAL_TIMER_NUMBER)
+ {
+ iteration_u8 = timerModule_en;
+ startIndex_u8 = 0u;
+ }
+ else
+ {
+ iteration_u8 += timerModule_en;
+ startIndex_u8 = timerModule_en;
+ }
+
+ for(index_u8 = startIndex_u8; index_u8 < iteration_u8; index_u8++)
+ {
+ error_u32 = MapHalTimerModule((MapHalTimerModule_en)index_u8, &targetModule_pst);
+ if(error_u32 == NMS_ERR_NONE)
+ {
+ HAL_TIM_Base_DeInit(targetModule_pst);
+ }
+ }
+}
+
+/******************************************************************************
+ * Static Function Definitions
+ ******************************************************************************/
+
+/**
+* @brief Compute the timerPeriod of the requested timer
+*
+* @param timerModule_en The timer module to use
+*
+* @return The value of the timer period. If the timer module is invalid, the
+* value returned will be 0.
+*
+* @note CAUTION : The part to compute the actual time frequency is target
+* dependant, do not forget to update it to fit your needs.
+* This affects the calculation of the timerPeriod and so
+* can change the resolution that has been computed by the
+* user in cubeMX
+*/
+static uint32 HalTimerComputeTimerPeriod(MapHalTimerModule_en timerModule_en, uint64 * timerPeriod_u64)
+{
+ uint32 error_u32 = NMS_ERR_DEFAULT;
+ uint32 timerFrequency_u32 = 0uL;
+ TIM_HandleTypeDef * targetModule_pst;
+
+ error_u32 = MapHalTimerModule(timerModule_en, &targetModule_pst);
+
+ if(error_u32 == NMS_ERR_NONE)
+ {
+ *timerPeriod_u64 = HAL_TIMER_SEC_TO_MSEC;
+ *timerPeriod_u64 *= (targetModule_pst->Instance->PSC + 1UL);
+ *timerPeriod_u64 *= (targetModule_pst->Instance->ARR + 1UL);
+ *timerPeriod_u64 /= timerFrequency_u32;
+ }
+ else
+ {
+ timerPeriod_u64 = 0uLL;
+ error_u32 = NMS_ERR_UNKNOWN;
+ }
+
+ return error_u32;
+}
+
+/******************************************************************************
+ * Callback Function Definitions
+ ******************************************************************************/
+
+/**
+ * @brief CubeMX timer period elapsed callback
+ *
+ * @param[in] htim pointer to a TIM_HandleTypeDef structure that contains
+ * the configuration information for the specified TIMER.
+ * @return Error code in case there is one during the process.
+ */
+void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)
+{
+ MapHalTimerModule_en timerModule_en;
+ uint32 error_u32 = NMS_ERR_DEFAULT;
+
+ error_u32 = MapHalTimerCallback(&htim, &timerModule_en);
+
+ if (error_u32 == NMS_ERR_NONE)
+ {
+ /* Check if we reach the interrupt enough to reach the goal counter */
+ if(instance_gast[timerModule_en].downCounter_u64 == 0uLL)
+ {
+ if(halTimerCallbacks[timerModule_en] != NULL)
+ {
+ /* Call the user callback */
+ halTimerCallbacks[timerModule_en]();
+ }
+ else
+ {
+ error_u32 = NMS_ERR_UNKNOWN;
+ }
+ }
+ else
+ {
+ instance_gast[timerModule_en].downCounter_u64--;
+ }
+ }
+ else
+ {
+ error_u32 = NMS_ERR_UNKNOWN;
+ }
+}
+
+
+/**
+ * @brief CubeMX timer error callback
+ *
+ * @param[in] htim pointer to a TIM_HandleTypeDef structure that contains
+ * the configuration information for the specified TIMER.
+ * @return Error code in case there is one during the process.
+ */
+void HAL_TIM_ErrorCallback(TIM_HandleTypeDef * htim)
+{
+ uint32 error_u32 = NMS_ERR_DEFAULT;
+ MapHalTimerModule_en timerModule_en;
+
+ error_u32 = MapHalTimerCallback(&htim, &timerModule_en);
+
+ if(error_u32 == NMS_ERR_NONE)
+ {
+ switch(htim->State)
+ {
+ case HAL_TIM_STATE_RESET:
+ error_u32 = NMS_ERR_NOT_INITIALIZED; break;
+
+ case HAL_TIM_STATE_BUSY:
+ error_u32 = NMS_ERR_BUSY;
+ break;
+
+ case HAL_TIM_STATE_TIMEOUT:
+ error_u32 = NMS_ERR_TIMEOUT; break;
+
+ case HAL_TIM_STATE_ERROR:
+ error_u32 = NMS_ERR_UNEXPECTED; break;
+
+ case HAL_TIM_STATE_READY:
+ error_u32 = NMS_ERR_NOT_RUNNING; break;
+
+ default:
+ error_u32 = NMS_ERR_UNKNOWN; break;
+ }
+ }
+ else
+ {
+ error_u32 = NMS_ERR_INVALID_ARGUMENT;
+ }
+}
diff --git a/EnduranceTestBench/nms_hal/hal_timer.h b/EnduranceTestBench/nms_hal/hal_timer.h
new file mode 100644
index 0000000..c8f439d
--- /dev/null
+++ b/EnduranceTestBench/nms_hal/hal_timer.h
@@ -0,0 +1,171 @@
+/**
+ * @file hal_timer.h
+ *
+ * @copyright Nehemis SARL reserves all rights even in the event of industrial
+ * property rights. We reserve all rights of disposal such as
+ * copying and passing on to third parties.
+ *
+ * @brief HAL layer for the TIMER module.
+ *
+ */
+
+
+#ifndef __HAL_TIMER_H_
+#define __HAL_TIMER_H_
+
+/******************************************************************************
+ * Include Header Files
+ ******************************************************************************/
+#include "nms_types.h"
+#include "map_hal.h"
+
+/******************************************************************************
+ * Type declarations
+ ******************************************************************************/
+
+/******************************************************************************
+ * Extern Function Declarations
+ ******************************************************************************/
+/**
+ * @brief Initializes the HAL timer module.
+ *
+ * @return Error code: 0 if successful, nonzero otherwise.
+ */
+uint32 HalTimerInit(void);
+
+/**
+ * @brief Retrieves the current value of the TIM counter register.
+ *
+ * @param htim Pointer to the TIM handle containing the TIM instance.
+ *
+ * @return The 16-bit or 32-bit value of the timer counter register (TIMx_CNT).
+ */
+uint32 HalTimerGetCounter(MapHalTimerModule_en timerModule_en);
+
+/**
+ * @brief Sets a specific value to the TIM counter register.
+ *
+ * @param htim Pointer to the TIM handle containing the TIM instance.
+ * @param counter_u32 Value to set in the TIM counter register.
+ */
+void HalTimerSetCounter(MapHalTimerModule_en timerModule_en, uint32 counter_u32);
+
+/**
+ * @brief Set the compare value for a given timer channel.
+ *
+ * @param timerModule_en Timer module.
+ * channel Timer channel (e.g., TIM_CHANNEL_1, TIM_CHANNEL_2).
+ * compareValue Value to set in the compare register.
+ *
+ * @note This function abstracts the STM32 HAL macro __HAL_TIM_SET_COMPARE.
+ */
+void HalTimerSetCompare(MapHalTimerModule_en timerModule_en, uint32 channel_u32, uint32 compareValue_32);
+
+/**
+ * @brief Get the Auto-Reload value of the specified timer module.
+ *
+ * @param timerModule_en Timer module selection from MapHalTimerModule_en.
+ *
+ * @return The auto-reload value of the selected timer module.
+ * Returns 0 if the timer module is invalid.
+ */
+uint32 HalTimerGetAutoReload(MapHalTimerModule_en timerModule_en);
+
+/**
+ * @brief Starts the specified timer module in encoder mode.
+ *
+ * @param timerModule_en Timer module to be started in encoder mode.
+ *
+ * @return Error code: 0 if successful, nonzero otherwise.
+ */
+uint32 HalTimerEncoderStart(MapHalTimerModule_en timerModule_en);
+
+/**
+ * @brief Stops the specified timer module in encoder mode.
+ *
+ * @param timerModule_en Timer module to be stopped in encoder mode.
+ *
+ * @return Error code: 0 if successful, nonzero otherwise.
+ */
+uint32 HalTimerEncoderStop(MapHalTimerModule_en timerModule_en);
+
+/**
+ * @brief Stops the specified timer module in PWM mode.
+ *
+ * @param timerModule_en Timer module to be stopped in encoder mode.
+ *
+ * @return Error code: 0 if successful, nonzero otherwise.
+ */
+uint32 HalTimerPwmStart(MapHalTimerModule_en timerModule_en, uint32 Channel_u32);
+
+/**
+ * @brief Stops the specified timer module in PWM mode.
+ *
+ * @param timerModule_en Timer module to be stopped in encoder mode.
+ *
+ * @return Error code: 0 if successful, nonzero otherwise.
+ */
+uint32 HalTimerPwmStop(MapHalTimerModule_en timerModule_en, uint32 Channel_u32);
+
+/**
+ * @brief Starts the specified timer module.
+ *
+ * @param timerModule_en Timer module to be started.
+ *
+ * @return Error code: 0 if successful, nonzero otherwise.
+ */
+uint32 HalTimerStart(MapHalTimerModule_en timerModule_en);
+
+/**
+ * @brief Stops the specified timer module.
+ *
+ * @param timerModule_en Timer module to be stopped.
+ *
+ * @return Error code: 0 if successful, nonzero otherwise.
+ */
+uint32 HalTimerStop(MapHalTimerModule_en timerModule_en);
+
+/**
+ * @brief Updates the timer's prescaler and counter value based on the given period.
+ *
+ * @param timerModule_en Timer module to configure.
+ * @param period_u64 Timer refresh period in microseconds.
+ * The value is rounded up to the nearest resolution divider.
+ *
+ * @note The period cannot be 0, as it would imply an immediate event.
+ * Instead, execute the event directly or call the stop function manually.
+ *
+ * @return Error code: 0 if successful, nonzero otherwise.
+ */
+uint32 HalTimerReloadUs(MapHalTimerModule_en timerModule_en, uint64 period_u64);
+
+/**
+ * @brief Retrieves the remaining time for the specified timer in microseconds.
+ *
+ * @param timerModule_en Timer module to query.
+ * @param remainingTime_u64 Pointer to store the remaining time in microseconds.
+ * The value is rounded up to the nearest resolution divider.
+ *
+ * @return Error code: 0 if successful, nonzero otherwise.
+ */
+uint32 HalTimerGetRemainingTimeUs(MapHalTimerModule_en timerModule_en, uint64 *remainingTime_u64);
+
+/**
+ * @brief Configures a callback function for the specified timer module.
+ *
+ * @param timerModule_en Timer module for which the callback is being set.
+ * @param callback_pfn Pointer to the callback function.
+ *
+ * @return Error code: 0 if successful, nonzero otherwise.
+ */
+uint32 HalTimerConfigureCallback(MapHalTimerModule_en timerModule_en, void (*callback_pfn)(void));
+
+/**
+ * @brief Deinitializes the specified timer module, stopping all active timers.
+ * This is useful for transitioning between application and bootloader.
+ *
+ * @param timerModule_en Timer module to be deinitialized.
+ */
+void HalTimerDeinit(MapHalTimerModule_en timerModule_en);
+
+#endif /* __HAL_TIMER_H_ */
diff --git a/EnduranceTestBench/nms_hal/map_hal.c b/EnduranceTestBench/nms_hal/map_hal.c
new file mode 100644
index 0000000..5499e1d
--- /dev/null
+++ b/EnduranceTestBench/nms_hal/map_hal.c
@@ -0,0 +1,208 @@
+/**
+ * @file map_hal.c
+ *
+ * @copyright Nehemis SARL reserves all rights even in the event of industrial
+ * property rights. We reserve all rights of disposal such as
+ * copying and passing on to third parties.
+ *
+ * @brief Mapping of the hardware interfaces.
+ *
+ */
+
+/******************************************************************************
+ * Include Header Files
+ ******************************************************************************/
+#include "nms_types.h"
+#include "map_hal.h"
+#include "stm32g4xx_hal_tim.h"
+/******************************************************************************
+ * Macro constant declarations
+ ******************************************************************************/
+extern TIM_HandleTypeDef htim7;
+/******************************************************************************
+ * Extern Function Declarations
+ ******************************************************************************/
+uint32 MapHalGpio( MapHalGpioPin_en pin_en, uint16* targetPin_pu16, GPIO_TypeDef** targetPort_ppst)
+{
+ uint32 error_u32 = NMS_ERR_DEFAULT;
+
+ if(targetPin_pu16 == NULL || targetPort_ppst == NULL)
+ {
+ error_u32 = NMS_ERR_UNKNOWN;
+ }
+ else
+ {
+ switch (pin_en)
+ {
+ case MAP_HAL_PMP_ENABLE:
+
+ *targetPin_pu16 = GPIO_PIN_15;
+ *targetPort_ppst = GPIOB;
+ error_u32 = NMS_ERR_NONE;
+
+ break;
+
+ default:
+
+ error_u32 = NMS_ERR_UNKNOWN;
+
+ break;
+ }
+ }
+
+ return error_u32;
+}
+
+
+uint32 MapHalGpioCallback(uint16 targetPin_u16, MapHalGpioPin_en * pin_pen)
+{
+ uint32 error_u32 = NMS_ERR_DEFAULT;
+
+ switch (targetPin_u16)
+ {
+ case GPIO_PIN_15:
+
+ *pin_pen = MAP_HAL_PMP_ENABLE;
+ error_u32 = NMS_ERR_NONE;
+
+ break;
+
+ default:
+
+ error_u32 = NMS_ERR_UNKNOWN;
+
+ break;
+ }
+
+ return error_u32;
+}
+
+
+uint32 MapHalTimerModule(MapHalTimerModule_en timer_en, TIM_HandleTypeDef ** targetModule_ppst)
+{
+ uint32 error_u32 = NMS_ERR_DEFAULT;
+
+ if(targetModule_ppst != NULL)
+ {
+ switch(timer_en)
+ {
+ case MAP_HAL_TIMER_RTOS:
+ *targetModule_ppst = &htim7;
+ error_u32 = NMS_ERR_NONE;
+ break;
+
+ default:
+ error_u32 = NMS_ERR_UNKNOWN;
+ break;
+ }
+ }
+ else
+ {
+ error_u32 = NMS_ERR_UNKNOWN;
+ }
+
+ return error_u32;
+}
+
+
+uint32 MapHalTimerCallback(TIM_HandleTypeDef ** targetModule_ppst, MapHalTimerModule_en * timer_pen)
+{
+ uint32 error_u32 = NMS_ERR_DEFAULT;
+
+ if(*targetModule_ppst != NULL)
+ {
+ if (*targetModule_ppst == &htim17)
+ {
+ *timer_pen = MAP_HAL_TIMER_RTOS;
+ error_u32 = NMS_ERR_NONE;
+ }
+
+ }
+ else
+ {
+ error_u32 = NMS_ERR_UNKNOWN;
+ }
+
+ return error_u32;
+}
+
+
+uint32 MapHalAdcModule(MapHalAdcModule_en adc_en, ADC_HandleTypeDef ** targetModule_ppst)
+{
+ uint32 error_u32 = NMS_ERR_DEFAULT;
+
+ if(targetModule_ppst != NULL)
+ {
+ switch(adc_en)
+ {
+ case MAP_HAL_ADC_1:
+ *targetModule_ppst = &hadc1;
+ error_u32 = NMS_ERR_NONE;
+ break;
+
+
+ default:
+ error_u32 = NMS_ERR_UNKNOWN;
+ break;
+ }
+ }
+ else
+ {
+ error_u32 = NMS_ERR_UNKNOWN;
+ }
+
+ return error_u32;
+}
+
+
+extern uint32 MapHalAdcCallback(ADC_HandleTypeDef *targetModule_pst, MapHalAdcModule_en *adcModule_en)
+{
+ uint32 error_u32 = NMS_ERR_DEFAULT;
+
+ if (targetModule_pst != NULL)
+ {
+ if (targetModule_pst == &hadc1)
+ {
+ *adcModule_en = MAP_HAL_ADC_1;
+ error_u32 = NMS_ERR_NONE;
+ }
+ else
+ {
+ error_u32 = NMS_ERR_UNKNOWN;
+ }
+ }
+ else
+ {
+ error_u32 = NMS_ERR_UNKNOWN;
+ }
+
+ return error_u32;
+}
+
+
+uint32 MapHalI2cModule(MapHalI2cModule_en module_en, I2C_HandleTypeDef ** targetModule_ppst)
+{
+ uint32 error_u32 = NMS_ERR_DEFAULT;
+
+ if(targetModule_ppst != NULL)
+ {
+ switch(module_en)
+ {
+ case MAP_HAL_GRUNDFOS_PMP_I2C_HANDLE:
+ *targetModule_ppst = &hi2c4;
+ error_u32 = NMS_ERR_NONE;
+ break;
+
+
+ default:
+ error_u32 = NMS_ERR_UNKNOWN;
+ break;
+ }
+ }
+ else
+ {
+ error_u32 = NMS_ERR_UNKNOWN;
+ }
+
+ return error_u32;
+}
diff --git a/EnduranceTestBench/nms_hal/map_hal.h b/EnduranceTestBench/nms_hal/map_hal.h
new file mode 100644
index 0000000..e6c4f5a
--- /dev/null
+++ b/EnduranceTestBench/nms_hal/map_hal.h
@@ -0,0 +1,136 @@
+/**
+ * @file map_hal.c
+ *
+ * @copyright Nehemis SARL reserves all rights even in the event of industrial
+ * property rights. We reserve all rights of disposal such as
+ * copying and passing on to third parties.
+ *
+ * @brief Mapping of the hardware interfaces.
+ *
+ */
+
+#ifndef MAP_HAL_H_
+#define MAP_HAL_H_
+
+/******************************************************************************
+ * Include Header Files
+ ******************************************************************************/
+#include "nms_types.h"
+
+/* CubeMX */
+#include "gpio.h"
+#include "tim.h"
+#include "adc.h"
+#include "fdcan.h"
+#include "i2c.h"
+
+/******************************************************************************
+ * Global define
+ ******************************************************************************/
+#define MOTOR_PWM_CHANNEL TIM_CHANNEL_1
+
+/******************************************************************************
+ * Type declarations
+ ******************************************************************************/
+typedef enum
+{
+ MAP_HAL_PMP_ENABLE,
+ MAP_HAL_GPIO_NUMBER
+} MapHalGpioPin_en;
+
+typedef enum
+{
+ MAP_HAL_TIMER_RTOS,
+ MAP_HAL_TIMER_NUMBER
+} MapHalTimerModule_en;
+
+typedef enum
+{
+ MAP_HAL_ADC_1,
+ MAP_HAL_ADC_NUMBER
+}MapHalAdcModule_en;
+
+typedef enum
+{
+ MAP_HAL_GRUNDFOS_PMP_I2C_HANDLE,
+ MAP_HAL_I2C_NUMBER
+}MapHalI2cModule_en;
+/******************************************************************************
+ * Extern Function Declarations
+ ******************************************************************************/
+/**
+ * @brief Maps a HAL GPIO pin to the corresponding STM32 port and pin.
+ *
+ * @param pin_en HAL GPIO pin to be mapped.
+ * @param targetPort_ppst Pointer to the corresponding STM32 port.
+ * @param targetPin_pu16 Pointer to the corresponding STM32 pin.
+ *
+ * @return Error code: 0 if successful, nonzero otherwise.
+ */
+uint32 MapHalGpio(MapHalGpioPin_en pin_en, uint16* targetPin_pu16, GPIO_TypeDef** targetPort_ppst);
+
+/**
+ * @brief Maps a specific pin callback to the corresponding STM32 pin.
+ *
+ * @param targetPin_u16 STM32 pin.
+ * @param pin_pen Pointer to the enumerator representing the HAL pin.
+ *
+ * @return Error code: 0 if successful, nonzero otherwise.
+ */
+uint32 MapHalGpioCallback(uint16 targetPin_u16, MapHalGpioPin_en* pin_pen);
+
+/**
+ * @brief Maps a HAL timer module to its corresponding STM32 timer module.
+ *
+ * @param[in] halModule_en HAL timer module (e.g., HAL_TIMER_1).
+ * @param[out] targetModule_ppst Pointer to the corresponding STM32 timer module (e.g., htim1).
+ *
+ * @return Error code:
+ * - HAL_TIM_LOG_LOCATION_4_ERROR_INVALID_ARGUMENT if the mapping fails.
+ * - LOG_ERROR_NONE if successful.
+ */
+uint32 MapHalTimerModule(MapHalTimerModule_en timer_en, TIM_HandleTypeDef** targetModule_ppst);
+
+/**
+ * @brief Retrieves the HAL timer module associated with a given STM32 timer module.
+ *
+ * @param[in] targetModule_ppst Pointer to the STM32 timer module (e.g., htim1).
+ * @param[out] timerModule_pen Pointer to store the corresponding HAL module (e.g., HAL_TIMER_1).
+ *
+ * @return Error code:
+ * - HAL_TIM_LOG_LOCATION_4_ERROR_INVALID_ARGUMENT if the mapping fails.
+ * - LOG_ERROR_NONE if successful.
+ */
+uint32 MapHalTimerCallback(TIM_HandleTypeDef** targetModule_ppst, MapHalTimerModule_en* timer_pen);
+
+/**
+ * @brief Maps a HAL ADC pin to the corresponding STM32 port and pin.
+ *
+ * @param pin_en HAL GPIO pin to be mapped.
+ * @param targetModule_ppst Pointer to the corresponding STM32 ADC module.
+ *
+ * @return Error code: 0 if successful, nonzero otherwise.
+ */
+uint32 MapHalAdcModule(MapHalAdcModule_en pin_en, ADC_HandleTypeDef** targetModule_ppst);
+
+/**
+ * @brief Maps a specific pin callback to the corresponding STM32 pin.
+ *
+ * @param targetModule_pst STM32 pin.
+ * @param adcModule_en Pointer to the enumerator representing the HAL pin.
+ *
+ * @return Error code: 0 if successful, nonzero otherwise.
+ */
+uint32 MapHalAdcCallback(ADC_HandleTypeDef *targetModule_pst, MapHalAdcModule_en *adcModule_en);
+
+/**
+ * @brief Maps a HAL I2C pin to the corresponding STM32 port and pin.
+ *
+ * @param pin_en HAL GPIO pin to be mapped.
+ * @param targetModule_ppst Pointer to the corresponding STM32 ADC module.
+ *
+ * @return Error code: 0 if successful, nonzero otherwise.
+ */
+uint32 MapHalI2cModule(MapHalI2cModule_en module_en, I2C_HandleTypeDef ** targetModule_ppst);
+
+#endif /* MAP_HAL_H_ */