diff --git a/BMS_Testbench/BMS_Software_V1/.cproject b/BMS_Testbench/BMS_Software_V1/.cproject
new file mode 100644
index 0000000..96da51a
--- /dev/null
+++ b/BMS_Testbench/BMS_Software_V1/.cproject
@@ -0,0 +1,329 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/BMS_Testbench/BMS_Software_V1/.mxproject b/BMS_Testbench/BMS_Software_V1/.mxproject
new file mode 100644
index 0000000..9d0b942
--- /dev/null
+++ b/BMS_Testbench/BMS_Software_V1/.mxproject
@@ -0,0 +1,25 @@
+[PreviousLibFiles]
+LibFiles=Drivers\STM32F3xx_HAL_Driver\Inc\stm32f3xx_hal_can.h;Drivers\STM32F3xx_HAL_Driver\Inc\Legacy\stm32_hal_legacy.h;Drivers\STM32F3xx_HAL_Driver\Inc\stm32f3xx_hal.h;Drivers\STM32F3xx_HAL_Driver\Inc\stm32f3xx_hal_def.h;Drivers\STM32F3xx_HAL_Driver\Inc\stm32f3xx_hal_rcc.h;Drivers\STM32F3xx_HAL_Driver\Inc\stm32f3xx_hal_rcc_ex.h;Drivers\STM32F3xx_HAL_Driver\Inc\stm32f3xx_ll_bus.h;Drivers\STM32F3xx_HAL_Driver\Inc\stm32f3xx_ll_rcc.h;Drivers\STM32F3xx_HAL_Driver\Inc\stm32f3xx_ll_crs.h;Drivers\STM32F3xx_HAL_Driver\Inc\stm32f3xx_ll_system.h;Drivers\STM32F3xx_HAL_Driver\Inc\stm32f3xx_ll_utils.h;Drivers\STM32F3xx_HAL_Driver\Inc\stm32f3xx_hal_gpio.h;Drivers\STM32F3xx_HAL_Driver\Inc\stm32f3xx_hal_gpio_ex.h;Drivers\STM32F3xx_HAL_Driver\Inc\stm32f3xx_ll_gpio.h;Drivers\STM32F3xx_HAL_Driver\Inc\stm32f3xx_hal_dma_ex.h;Drivers\STM32F3xx_HAL_Driver\Inc\stm32f3xx_hal_dma.h;Drivers\STM32F3xx_HAL_Driver\Inc\stm32f3xx_ll_dma.h;Drivers\STM32F3xx_HAL_Driver\Inc\stm32f3xx_hal_cortex.h;Drivers\STM32F3xx_HAL_Driver\Inc\stm32f3xx_ll_cortex.h;Drivers\STM32F3xx_HAL_Driver\Inc\stm32f3xx_hal_pwr.h;Drivers\STM32F3xx_HAL_Driver\Inc\stm32f3xx_hal_pwr_ex.h;Drivers\STM32F3xx_HAL_Driver\Inc\stm32f3xx_ll_pwr.h;Drivers\STM32F3xx_HAL_Driver\Inc\stm32f3xx_hal_flash.h;Drivers\STM32F3xx_HAL_Driver\Inc\stm32f3xx_hal_flash_ex.h;Drivers\STM32F3xx_HAL_Driver\Inc\stm32f3xx_hal_i2c.h;Drivers\STM32F3xx_HAL_Driver\Inc\stm32f3xx_hal_i2c_ex.h;Drivers\STM32F3xx_HAL_Driver\Inc\stm32f3xx_hal_exti.h;Drivers\STM32F3xx_HAL_Driver\Inc\stm32f3xx_ll_exti.h;Drivers\STM32F3xx_HAL_Driver\Inc\stm32f3xx_ll_i2c.h;Drivers\STM32F3xx_HAL_Driver\Inc\stm32f3xx_hal_spi.h;Drivers\STM32F3xx_HAL_Driver\Inc\stm32f3xx_hal_spi_ex.h;Drivers\STM32F3xx_HAL_Driver\Inc\stm32f3xx_hal_tim.h;Drivers\STM32F3xx_HAL_Driver\Inc\stm32f3xx_hal_tim_ex.h;Drivers\STM32F3xx_HAL_Driver\Src\stm32f3xx_hal_can.c;Drivers\STM32F3xx_HAL_Driver\Src\stm32f3xx_hal.c;Drivers\STM32F3xx_HAL_Driver\Src\stm32f3xx_hal_rcc.c;Drivers\STM32F3xx_HAL_Driver\Src\stm32f3xx_hal_rcc_ex.c;Drivers\STM32F3xx_HAL_Driver\Src\stm32f3xx_hal_gpio.c;Drivers\STM32F3xx_HAL_Driver\Src\stm32f3xx_hal_dma.c;Drivers\STM32F3xx_HAL_Driver\Src\stm32f3xx_hal_cortex.c;Drivers\STM32F3xx_HAL_Driver\Src\stm32f3xx_hal_pwr.c;Drivers\STM32F3xx_HAL_Driver\Src\stm32f3xx_hal_pwr_ex.c;Drivers\STM32F3xx_HAL_Driver\Src\stm32f3xx_hal_flash.c;Drivers\STM32F3xx_HAL_Driver\Src\stm32f3xx_hal_flash_ex.c;Drivers\STM32F3xx_HAL_Driver\Src\stm32f3xx_hal_i2c.c;Drivers\STM32F3xx_HAL_Driver\Src\stm32f3xx_hal_i2c_ex.c;Drivers\STM32F3xx_HAL_Driver\Src\stm32f3xx_hal_exti.c;Drivers\STM32F3xx_HAL_Driver\Src\stm32f3xx_hal_spi.c;Drivers\STM32F3xx_HAL_Driver\Src\stm32f3xx_hal_spi_ex.c;Drivers\STM32F3xx_HAL_Driver\Src\stm32f3xx_hal_tim.c;Drivers\STM32F3xx_HAL_Driver\Src\stm32f3xx_hal_tim_ex.c;Drivers\STM32F3xx_HAL_Driver\Inc\stm32f3xx_hal_can.h;Drivers\STM32F3xx_HAL_Driver\Inc\Legacy\stm32_hal_legacy.h;Drivers\STM32F3xx_HAL_Driver\Inc\stm32f3xx_hal.h;Drivers\STM32F3xx_HAL_Driver\Inc\stm32f3xx_hal_def.h;Drivers\STM32F3xx_HAL_Driver\Inc\stm32f3xx_hal_rcc.h;Drivers\STM32F3xx_HAL_Driver\Inc\stm32f3xx_hal_rcc_ex.h;Drivers\STM32F3xx_HAL_Driver\Inc\stm32f3xx_ll_bus.h;Drivers\STM32F3xx_HAL_Driver\Inc\stm32f3xx_ll_rcc.h;Drivers\STM32F3xx_HAL_Driver\Inc\stm32f3xx_ll_crs.h;Drivers\STM32F3xx_HAL_Driver\Inc\stm32f3xx_ll_system.h;Drivers\STM32F3xx_HAL_Driver\Inc\stm32f3xx_ll_utils.h;Drivers\STM32F3xx_HAL_Driver\Inc\stm32f3xx_hal_gpio.h;Drivers\STM32F3xx_HAL_Driver\Inc\stm32f3xx_hal_gpio_ex.h;Drivers\STM32F3xx_HAL_Driver\Inc\stm32f3xx_ll_gpio.h;Drivers\STM32F3xx_HAL_Driver\Inc\stm32f3xx_hal_dma_ex.h;Drivers\STM32F3xx_HAL_Driver\Inc\stm32f3xx_hal_dma.h;Drivers\STM32F3xx_HAL_Driver\Inc\stm32f3xx_ll_dma.h;Drivers\STM32F3xx_HAL_Driver\Inc\stm32f3xx_hal_cortex.h;Drivers\STM32F3xx_HAL_Driver\Inc\stm32f3xx_ll_cortex.h;Drivers\STM32F3xx_HAL_Driver\Inc\stm32f3xx_hal_pwr.h;Drivers\STM32F3xx_HAL_Driver\Inc\stm32f3xx_hal_pwr_ex.h;Drivers\STM32F3xx_HAL_Driver\Inc\stm32f3xx_ll_pwr.h;Drivers\STM32F3xx_HAL_Driver\Inc\stm32f3xx_hal_flash.h;Drivers\STM32F3xx_HAL_Driver\Inc\stm32f3xx_hal_flash_ex.h;Drivers\STM32F3xx_HAL_Driver\Inc\stm32f3xx_hal_i2c.h;Drivers\STM32F3xx_HAL_Driver\Inc\stm32f3xx_hal_i2c_ex.h;Drivers\STM32F3xx_HAL_Driver\Inc\stm32f3xx_hal_exti.h;Drivers\STM32F3xx_HAL_Driver\Inc\stm32f3xx_ll_exti.h;Drivers\STM32F3xx_HAL_Driver\Inc\stm32f3xx_ll_i2c.h;Drivers\STM32F3xx_HAL_Driver\Inc\stm32f3xx_hal_spi.h;Drivers\STM32F3xx_HAL_Driver\Inc\stm32f3xx_hal_spi_ex.h;Drivers\STM32F3xx_HAL_Driver\Inc\stm32f3xx_hal_tim.h;Drivers\STM32F3xx_HAL_Driver\Inc\stm32f3xx_hal_tim_ex.h;Drivers\CMSIS\Device\ST\STM32F3xx\Include\stm32f302xc.h;Drivers\CMSIS\Device\ST\STM32F3xx\Include\stm32f3xx.h;Drivers\CMSIS\Device\ST\STM32F3xx\Include\system_stm32f3xx.h;Drivers\CMSIS\Device\ST\STM32F3xx\Source\Templates\system_stm32f3xx.c;Drivers\CMSIS\Include\cmsis_armcc.h;Drivers\CMSIS\Include\cmsis_armclang.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_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_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\stm32f3xx_it.c;Core\Src\stm32f3xx_hal_msp.c;Drivers\STM32F3xx_HAL_Driver\Src\stm32f3xx_hal_can.c;Drivers\STM32F3xx_HAL_Driver\Src\stm32f3xx_hal.c;Drivers\STM32F3xx_HAL_Driver\Src\stm32f3xx_hal_rcc.c;Drivers\STM32F3xx_HAL_Driver\Src\stm32f3xx_hal_rcc_ex.c;Drivers\STM32F3xx_HAL_Driver\Src\stm32f3xx_hal_gpio.c;Drivers\STM32F3xx_HAL_Driver\Src\stm32f3xx_hal_dma.c;Drivers\STM32F3xx_HAL_Driver\Src\stm32f3xx_hal_cortex.c;Drivers\STM32F3xx_HAL_Driver\Src\stm32f3xx_hal_pwr.c;Drivers\STM32F3xx_HAL_Driver\Src\stm32f3xx_hal_pwr_ex.c;Drivers\STM32F3xx_HAL_Driver\Src\stm32f3xx_hal_flash.c;Drivers\STM32F3xx_HAL_Driver\Src\stm32f3xx_hal_flash_ex.c;Drivers\STM32F3xx_HAL_Driver\Src\stm32f3xx_hal_i2c.c;Drivers\STM32F3xx_HAL_Driver\Src\stm32f3xx_hal_i2c_ex.c;Drivers\STM32F3xx_HAL_Driver\Src\stm32f3xx_hal_exti.c;Drivers\STM32F3xx_HAL_Driver\Src\stm32f3xx_hal_spi.c;Drivers\STM32F3xx_HAL_Driver\Src\stm32f3xx_hal_spi_ex.c;Drivers\STM32F3xx_HAL_Driver\Src\stm32f3xx_hal_tim.c;Drivers\STM32F3xx_HAL_Driver\Src\stm32f3xx_hal_tim_ex.c;Drivers\CMSIS\Device\ST\STM32F3xx\Source\Templates\system_stm32f3xx.c;Core\Src\system_stm32f3xx.c;Drivers\STM32F3xx_HAL_Driver\Src\stm32f3xx_hal_can.c;Drivers\STM32F3xx_HAL_Driver\Src\stm32f3xx_hal.c;Drivers\STM32F3xx_HAL_Driver\Src\stm32f3xx_hal_rcc.c;Drivers\STM32F3xx_HAL_Driver\Src\stm32f3xx_hal_rcc_ex.c;Drivers\STM32F3xx_HAL_Driver\Src\stm32f3xx_hal_gpio.c;Drivers\STM32F3xx_HAL_Driver\Src\stm32f3xx_hal_dma.c;Drivers\STM32F3xx_HAL_Driver\Src\stm32f3xx_hal_cortex.c;Drivers\STM32F3xx_HAL_Driver\Src\stm32f3xx_hal_pwr.c;Drivers\STM32F3xx_HAL_Driver\Src\stm32f3xx_hal_pwr_ex.c;Drivers\STM32F3xx_HAL_Driver\Src\stm32f3xx_hal_flash.c;Drivers\STM32F3xx_HAL_Driver\Src\stm32f3xx_hal_flash_ex.c;Drivers\STM32F3xx_HAL_Driver\Src\stm32f3xx_hal_i2c.c;Drivers\STM32F3xx_HAL_Driver\Src\stm32f3xx_hal_i2c_ex.c;Drivers\STM32F3xx_HAL_Driver\Src\stm32f3xx_hal_exti.c;Drivers\STM32F3xx_HAL_Driver\Src\stm32f3xx_hal_spi.c;Drivers\STM32F3xx_HAL_Driver\Src\stm32f3xx_hal_spi_ex.c;Drivers\STM32F3xx_HAL_Driver\Src\stm32f3xx_hal_tim.c;Drivers\STM32F3xx_HAL_Driver\Src\stm32f3xx_hal_tim_ex.c;Drivers\CMSIS\Device\ST\STM32F3xx\Source\Templates\system_stm32f3xx.c;Core\Src\system_stm32f3xx.c;;;
+HeaderPath=Drivers\STM32F3xx_HAL_Driver\Inc;Drivers\STM32F3xx_HAL_Driver\Inc\Legacy;Drivers\CMSIS\Device\ST\STM32F3xx\Include;Drivers\CMSIS\Include;Core\Inc;
+CDefines=USE_HAL_DRIVER;STM32F302xC;USE_HAL_DRIVER;USE_HAL_DRIVER;
+
+[PreviousGenFiles]
+AdvancedFolderStructure=true
+HeaderFileListSize=3
+HeaderFiles#0=..\Core\Inc\stm32f3xx_it.h
+HeaderFiles#1=..\Core\Inc\stm32f3xx_hal_conf.h
+HeaderFiles#2=..\Core\Inc\main.h
+HeaderFolderListSize=1
+HeaderPath#0=..\Core\Inc
+HeaderFiles=;
+SourceFileListSize=3
+SourceFiles#0=..\Core\Src\stm32f3xx_it.c
+SourceFiles#1=..\Core\Src\stm32f3xx_hal_msp.c
+SourceFiles#2=..\Core\Src\main.c
+SourceFolderListSize=1
+SourcePath#0=..\Core\Src
+SourceFiles=;
+
diff --git a/BMS_Testbench/BMS_Software_V1/.project b/BMS_Testbench/BMS_Software_V1/.project
new file mode 100644
index 0000000..5aaff8f
--- /dev/null
+++ b/BMS_Testbench/BMS_Software_V1/.project
@@ -0,0 +1,32 @@
+
+
+ BMS_Software
+
+
+
+
+
+ org.eclipse.cdt.managedbuilder.core.genmakebuilder
+ clean,full,incremental,
+
+
+
+
+ org.eclipse.cdt.managedbuilder.core.ScannerConfigBuilder
+ full,incremental,
+
+
+
+
+
+ com.st.stm32cube.ide.mcu.MCUProjectNature
+ com.st.stm32cube.ide.mcu.MCUCubeProjectNature
+ org.eclipse.cdt.core.cnature
+ com.st.stm32cube.ide.mcu.MCUCubeIdeServicesRevAev2ProjectNature
+ com.st.stm32cube.ide.mcu.MCUAdvancedStructureProjectNature
+ com.st.stm32cube.ide.mcu.MCUSingleCpuProjectNature
+ com.st.stm32cube.ide.mcu.MCURootProjectNature
+ org.eclipse.cdt.managedbuilder.core.managedBuildNature
+ org.eclipse.cdt.managedbuilder.core.ScannerConfigNature
+
+
diff --git a/BMS_Testbench/BMS_Software_V1/.settings/com.st.stm32cube.ide.mcu.sfrview.prefs b/BMS_Testbench/BMS_Software_V1/.settings/com.st.stm32cube.ide.mcu.sfrview.prefs
new file mode 100644
index 0000000..9a16796
--- /dev/null
+++ b/BMS_Testbench/BMS_Software_V1/.settings/com.st.stm32cube.ide.mcu.sfrview.prefs
@@ -0,0 +1,2 @@
+eclipse.preferences.version=1
+sfrviewstate={"fFavorites"\:{"fLists"\:{}},"fProperties"\:{"fNodeProperties"\:{}}}
diff --git a/BMS_Testbench/BMS_Software_V1/.settings/language.settings.xml b/BMS_Testbench/BMS_Software_V1/.settings/language.settings.xml
new file mode 100644
index 0000000..d7b202f
--- /dev/null
+++ b/BMS_Testbench/BMS_Software_V1/.settings/language.settings.xml
@@ -0,0 +1,47 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/BMS_Testbench/BMS_Software_V1/.settings/stm32cubeide.project.prefs b/BMS_Testbench/BMS_Software_V1/.settings/stm32cubeide.project.prefs
new file mode 100644
index 0000000..57775d1
--- /dev/null
+++ b/BMS_Testbench/BMS_Software_V1/.settings/stm32cubeide.project.prefs
@@ -0,0 +1,4 @@
+66BE74F758C12D739921AEA421D593D3=0
+8DF89ED150041C4CBC7CB9A9CAA90856=0331FDAB209A428E438CDF6850F54DEA
+DC22A860405A8BF2F2C095E5B6529F12=0331FDAB209A428E438CDF6850F54DEA
+eclipse.preferences.version=1
diff --git a/BMS_Testbench/BMS_Software_V1/.vscode/c_cpp_properties.json b/BMS_Testbench/BMS_Software_V1/.vscode/c_cpp_properties.json
new file mode 100644
index 0000000..2e9f878
--- /dev/null
+++ b/BMS_Testbench/BMS_Software_V1/.vscode/c_cpp_properties.json
@@ -0,0 +1,20 @@
+{
+ "configurations": [
+ {
+ "name": "STM32",
+ "includePath": [
+ "Core/Inc",
+ "Drivers/CMSIS/Device/ST/STM32F3xx/Include",
+ "Drivers/CMSIS/Include",
+ "Drivers/STM32F3xx_HAL_Driver/Inc",
+ "Drivers/STM32F3xx_HAL_Driver/Inc/Legacy"
+ ],
+ "defines": [
+ "STM32F302xC",
+ "USE_HAL_DRIVER"
+ ],
+ "compilerPath": "/home/david/.config/Code/User/globalStorage/bmd.stm32-for-vscode/@xpack-dev-tools/arm-none-eabi-gcc/12.2.1-1.2.1/.content/bin/arm-none-eabi-gcc"
+ }
+ ],
+ "version": 4
+}
\ No newline at end of file
diff --git a/BMS_Testbench/BMS_Software_V1/.vscode/launch.json b/BMS_Testbench/BMS_Software_V1/.vscode/launch.json
new file mode 100644
index 0000000..57753fd
--- /dev/null
+++ b/BMS_Testbench/BMS_Software_V1/.vscode/launch.json
@@ -0,0 +1,34 @@
+{
+ "configurations": [
+ {
+ "showDevDebugOutput": "parsed",
+ "cwd": "${workspaceRoot}",
+ "executable": "./build/ams-slave-23.elf",
+ "name": "Debug STM32",
+ "request": "launch",
+ "type": "cortex-debug",
+ "servertype": "openocd",
+ "preLaunchTask": "Build STM",
+ "device": "stm32f302xc.s",
+ "configFiles": [
+ "openocd.cfg"
+ ],
+ "svdFile": "STM32F102xx.svd"
+ },
+ {
+ "showDevDebugOutput": "parsed",
+ "cwd": "${workspaceRoot}",
+ "executable": "./build/ams-slave-23.elf",
+ "name": "Attach STM32",
+ "request": "attach",
+ "type": "cortex-debug",
+ "servertype": "openocd",
+ "preLaunchTask": "Build STM",
+ "device": "stm32f302xc.s",
+ "configFiles": [
+ "openocd.cfg"
+ ],
+ "svdFile": "STM32F102xx.svd"
+ }
+ ]
+}
\ No newline at end of file
diff --git a/BMS_Testbench/BMS_Software_V1/.vscode/settings.json b/BMS_Testbench/BMS_Software_V1/.vscode/settings.json
new file mode 100644
index 0000000..93579b3
--- /dev/null
+++ b/BMS_Testbench/BMS_Software_V1/.vscode/settings.json
@@ -0,0 +1,4 @@
+{
+ "cortex-debug.armToolchainPath": "/home/david/.config/Code/User/globalStorage/bmd.stm32-for-vscode/@xpack-dev-tools/arm-none-eabi-gcc/12.2.1-1.2.1/.content/bin",
+ "cortex-debug.openocdPath": "/home/david/.config/Code/User/globalStorage/bmd.stm32-for-vscode/@xpack-dev-tools/openocd/0.12.0-1.1/.content/bin/openocd"
+}
\ No newline at end of file
diff --git a/BMS_Testbench/BMS_Software_V1/.vscode/tasks.json b/BMS_Testbench/BMS_Software_V1/.vscode/tasks.json
new file mode 100644
index 0000000..39d8d34
--- /dev/null
+++ b/BMS_Testbench/BMS_Software_V1/.vscode/tasks.json
@@ -0,0 +1,50 @@
+{
+ "version": "2.0.0",
+ "tasks": [
+ {
+ "label": "Build STM",
+ "type": "process",
+ "command": "${command:stm32-for-vscode.build}",
+ "options": {
+ "cwd": "${workspaceRoot}"
+ },
+ "group": {
+ "kind": "build",
+ "isDefault": true
+ },
+ "problemMatcher": [
+ "$gcc"
+ ]
+ },
+ {
+ "label": "Build Clean STM",
+ "type": "process",
+ "command": "${command:stm32-for-vscode.cleanBuild}",
+ "options": {
+ "cwd": "${workspaceRoot}"
+ },
+ "group": {
+ "kind": "build",
+ "isDefault": true
+ },
+ "problemMatcher": [
+ "$gcc"
+ ]
+ },
+ {
+ "label": "Flash STM",
+ "type": "process",
+ "command": "${command:stm32-for-vscode.flash}",
+ "options": {
+ "cwd": "${workspaceRoot}"
+ },
+ "group": {
+ "kind": "build",
+ "isDefault": true
+ },
+ "problemMatcher": [
+ "$gcc"
+ ]
+ }
+ ]
+}
\ No newline at end of file
diff --git a/BMS_Testbench/BMS_Software_V1/BMS_Software Debug.launch b/BMS_Testbench/BMS_Software_V1/BMS_Software Debug.launch
new file mode 100644
index 0000000..336dc5c
--- /dev/null
+++ b/BMS_Testbench/BMS_Software_V1/BMS_Software Debug.launch
@@ -0,0 +1,78 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/BMS_Testbench/BMS_Software_V1/BMS_Software.ioc b/BMS_Testbench/BMS_Software_V1/BMS_Software.ioc
new file mode 100644
index 0000000..fb83f0c
--- /dev/null
+++ b/BMS_Testbench/BMS_Software_V1/BMS_Software.ioc
@@ -0,0 +1,199 @@
+#MicroXplorer Configuration settings - do not modify
+CAD.formats=
+CAD.pinconfig=
+CAD.provider=
+CAN.ABOM=ENABLE
+CAN.BS1=CAN_BS1_13TQ
+CAN.BS2=CAN_BS2_2TQ
+CAN.CalculateBaudRate=500000
+CAN.CalculateTimeBit=2000
+CAN.CalculateTimeQuantum=125.0
+CAN.IPParameters=CalculateTimeQuantum,CalculateTimeBit,CalculateBaudRate,BS1,BS2,Prescaler,NART,ABOM
+CAN.NART=ENABLE
+CAN.Prescaler=2
+File.Version=6
+KeepUserPlacement=false
+Mcu.CPN=STM32F302CCT6
+Mcu.Family=STM32F3
+Mcu.IP0=CAN
+Mcu.IP1=I2C1
+Mcu.IP2=I2C2
+Mcu.IP3=NVIC
+Mcu.IP4=RCC
+Mcu.IP5=SPI1
+Mcu.IP6=SYS
+Mcu.IPNb=7
+Mcu.Name=STM32F302C(B-C)Tx
+Mcu.Package=LQFP48
+Mcu.Pin0=PF0-OSC_IN
+Mcu.Pin1=PF1-OSC_OUT
+Mcu.Pin10=PA9
+Mcu.Pin11=PA10
+Mcu.Pin12=PA11
+Mcu.Pin13=PA12
+Mcu.Pin14=PA13
+Mcu.Pin15=PA14
+Mcu.Pin16=PA15
+Mcu.Pin17=PB3
+Mcu.Pin18=PB7
+Mcu.Pin2=PA4
+Mcu.Pin3=PA5
+Mcu.Pin4=PA6
+Mcu.Pin5=PA7
+Mcu.Pin6=PB13
+Mcu.Pin7=PB14
+Mcu.Pin8=PB15
+Mcu.Pin9=PA8
+Mcu.PinsNb=19
+Mcu.ThirdPartyNb=0
+Mcu.UserConstants=
+Mcu.UserName=STM32F302CCTx
+MxCube.Version=6.7.0
+MxDb.Version=DB.6.0.70
+NVIC.BusFault_IRQn=true\:0\:0\:false\:false\:true\:false\:false\:false
+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
+NVIC.MemoryManagement_IRQn=true\:0\:0\:false\:false\:true\:false\:false\:false
+NVIC.NonMaskableInt_IRQn=true\:0\:0\:false\:false\:true\:false\:false\:false
+NVIC.PendSV_IRQn=true\:0\:0\:false\:false\:true\:false\:false\:false
+NVIC.PriorityGroup=NVIC_PRIORITYGROUP_4
+NVIC.SVCall_IRQn=true\:0\:0\:false\:false\:true\:false\:false\:false
+NVIC.SysTick_IRQn=true\:15\:0\:false\:false\:true\:false\:true\:false
+NVIC.USB_LP_CAN_RX0_IRQn=true\:0\:0\:false\:false\:true\:true\:true\:true
+NVIC.UsageFault_IRQn=true\:0\:0\:false\:false\:true\:false\:false\:false
+PA10.Locked=true
+PA10.Mode=I2C
+PA10.Signal=I2C2_SDA
+PA11.Locked=true
+PA11.Mode=CAN_Activate
+PA11.Signal=CAN_RX
+PA12.Locked=true
+PA12.Mode=CAN_Activate
+PA12.Signal=CAN_TX
+PA13.Locked=true
+PA13.Mode=Trace_Asynchronous_SW
+PA13.Signal=SYS_JTMS-SWDIO
+PA14.Locked=true
+PA14.Mode=Trace_Asynchronous_SW
+PA14.Signal=SYS_JTCK-SWCLK
+PA15.GPIOParameters=GPIO_Label
+PA15.GPIO_Label=TMP_SCL
+PA15.Locked=true
+PA15.Mode=I2C
+PA15.Signal=I2C1_SCL
+PA4.GPIOParameters=GPIO_Label
+PA4.GPIO_Label=CSB
+PA4.Locked=true
+PA4.Signal=GPIO_Output
+PA5.Locked=true
+PA5.Mode=Full_Duplex_Master
+PA5.Signal=SPI1_SCK
+PA6.Locked=true
+PA6.Mode=Full_Duplex_Master
+PA6.Signal=SPI1_MISO
+PA7.Locked=true
+PA7.Mode=Full_Duplex_Master
+PA7.Signal=SPI1_MOSI
+PA8.GPIOParameters=GPIO_Label
+PA8.GPIO_Label=Status_3
+PA8.Locked=true
+PA8.Signal=GPIO_Output
+PA9.Locked=true
+PA9.Mode=I2C
+PA9.Signal=I2C2_SCL
+PB13.GPIOParameters=GPIO_Label
+PB13.GPIO_Label=Status_0
+PB13.Locked=true
+PB13.Signal=GPIO_Output
+PB14.GPIOParameters=GPIO_Label
+PB14.GPIO_Label=Status_1
+PB14.Locked=true
+PB14.Signal=GPIO_Output
+PB15.GPIOParameters=GPIO_Label
+PB15.GPIO_Label=Status_2
+PB15.Locked=true
+PB15.Signal=GPIO_Output
+PB3.Mode=Trace_Asynchronous_SW
+PB3.Signal=SYS_JTDO-TRACESWO
+PB7.GPIOParameters=GPIO_Label
+PB7.GPIO_Label=TMP_SDA
+PB7.Locked=true
+PB7.Mode=I2C
+PB7.Signal=I2C1_SDA
+PF0-OSC_IN.Mode=HSE-External-Oscillator
+PF0-OSC_IN.Signal=RCC_OSC_IN
+PF1-OSC_OUT.Mode=HSE-External-Oscillator
+PF1-OSC_OUT.Signal=RCC_OSC_OUT
+PinOutPanel.RotationAngle=0
+ProjectManager.AskForMigrate=true
+ProjectManager.BackupPrevious=false
+ProjectManager.CompilerOptimize=6
+ProjectManager.ComputerToolchain=false
+ProjectManager.CoupleFile=false
+ProjectManager.CustomerFirmwarePackage=
+ProjectManager.DefaultFWLocation=true
+ProjectManager.DeletePrevious=true
+ProjectManager.DeviceId=STM32F302CCTx
+ProjectManager.FirmwarePackage=STM32Cube FW_F3 V1.11.3
+ProjectManager.FreePins=false
+ProjectManager.HalAssertFull=false
+ProjectManager.HeapSize=0x200
+ProjectManager.KeepUserCode=true
+ProjectManager.LastFirmware=false
+ProjectManager.LibraryCopy=1
+ProjectManager.MainLocation=Core/Src
+ProjectManager.NoMain=false
+ProjectManager.PreviousToolchain=STM32CubeIDE
+ProjectManager.ProjectBuild=false
+ProjectManager.ProjectFileName=BMS_Software.ioc
+ProjectManager.ProjectName=BMS_Software
+ProjectManager.RegisterCallBack=
+ProjectManager.StackSize=0x400
+ProjectManager.TargetToolchain=STM32CubeIDE
+ProjectManager.ToolChainLocation=
+ProjectManager.UnderRoot=true
+ProjectManager.functionlistsort=1-SystemClock_Config-RCC-false-HAL-false,2-MX_GPIO_Init-GPIO-false-HAL-true,3-MX_CAN_Init-CAN-false-HAL-true,4-MX_I2C1_Init-I2C1-false-HAL-true,5-MX_I2C2_Init-I2C2-false-HAL-true,6-MX_SPI1_Init-SPI1-false-HAL-true
+RCC.ADC12outputFreq_Value=32000000
+RCC.AHBFreq_Value=16000000
+RCC.APB1Freq_Value=16000000
+RCC.APB1TimFreq_Value=16000000
+RCC.APB2Freq_Value=16000000
+RCC.APB2TimFreq_Value=16000000
+RCC.CortexFreq_Value=16000000
+RCC.FCLKCortexFreq_Value=16000000
+RCC.FamilyName=M
+RCC.HCLKFreq_Value=16000000
+RCC.HSEPLLFreq_Value=16000000
+RCC.HSE_VALUE=16000000
+RCC.HSIPLLFreq_Value=4000000
+RCC.HSI_VALUE=8000000
+RCC.I2C1Freq_Value=8000000
+RCC.I2C2Freq_Value=8000000
+RCC.IPParameters=ADC12outputFreq_Value,AHBFreq_Value,APB1Freq_Value,APB1TimFreq_Value,APB2Freq_Value,APB2TimFreq_Value,CortexFreq_Value,FCLKCortexFreq_Value,FamilyName,HCLKFreq_Value,HSEPLLFreq_Value,HSE_VALUE,HSIPLLFreq_Value,HSI_VALUE,I2C1Freq_Value,I2C2Freq_Value,LSE_VALUE,LSI_VALUE,MCOFreq_Value,PLLCLKFreq_Value,PLLMCOFreq_Value,PLLSourceVirtual,RTCFreq_Value,RTCHSEDivFreq_Value,SYSCLKFreq_VALUE,SYSCLKSourceVirtual,TIM1Freq_Value,TIM2Freq_Value,USART1Freq_Value,USART2Freq_Value,USART3Freq_Value,USBFreq_Value,VCOOutput2Freq_Value
+RCC.LSE_VALUE=32768
+RCC.LSI_VALUE=40000
+RCC.MCOFreq_Value=16000000
+RCC.PLLCLKFreq_Value=32000000
+RCC.PLLMCOFreq_Value=16000000
+RCC.PLLSourceVirtual=RCC_PLLSOURCE_HSE
+RCC.RTCFreq_Value=40000
+RCC.RTCHSEDivFreq_Value=500000
+RCC.SYSCLKFreq_VALUE=16000000
+RCC.SYSCLKSourceVirtual=RCC_SYSCLKSOURCE_HSE
+RCC.TIM1Freq_Value=16000000
+RCC.TIM2Freq_Value=16000000
+RCC.USART1Freq_Value=16000000
+RCC.USART2Freq_Value=16000000
+RCC.USART3Freq_Value=16000000
+RCC.USBFreq_Value=32000000
+RCC.VCOOutput2Freq_Value=16000000
+SPI1.BaudRatePrescaler=SPI_BAUDRATEPRESCALER_32
+SPI1.CalculateBaudRate=500.0 KBits/s
+SPI1.DataSize=SPI_DATASIZE_8BIT
+SPI1.Direction=SPI_DIRECTION_2LINES
+SPI1.IPParameters=VirtualType,Mode,Direction,CalculateBaudRate,BaudRatePrescaler,DataSize
+SPI1.Mode=SPI_MODE_MASTER
+SPI1.VirtualType=VM_MASTER
+board=custom
+isbadioc=false
diff --git a/BMS_Testbench/BMS_Software_V1/Core/Inc/ADBMS_Abstraction.h b/BMS_Testbench/BMS_Software_V1/Core/Inc/ADBMS_Abstraction.h
new file mode 100644
index 0000000..ecbe692
--- /dev/null
+++ b/BMS_Testbench/BMS_Software_V1/Core/Inc/ADBMS_Abstraction.h
@@ -0,0 +1,82 @@
+/*
+ * ADBMS_Abstraction.h
+ *
+ * Created on: 14.07.2022
+ * Author: max
+ */
+
+#ifndef INC_ADBMS_ABSTRACTION_H_
+#define INC_ADBMS_ABSTRACTION_H_
+
+#include "ADBMS_LL_Driver.h"
+#include "ADBMS_CMD_MAKROS.h"
+#include "main.h"
+
+#define MAXIMUM_CELL_VOLTAGES 18
+#define MAXIMUM_AUX_VOLTAGES 10
+#define MAXIMUM_GPIO 10
+
+#define DEFAULT_UV 1562//(VUV + 1)*16*100uV Default Setting 2.5V
+#define DEFAULT_OV 2625//(VOV)*16*100uV Default Setting 4.2V
+
+typedef struct
+{
+ uint16 cellVoltages[MAXIMUM_CELL_VOLTAGES];
+ uint16 auxVoltages[MAXIMUM_AUX_VOLTAGES];
+
+ uint16 internalDieTemp;
+ uint16 analogSupplyVoltage;
+ uint16 digitalSupplyVoltage;
+ uint16 sumOfCellMeasurements;
+ uint16 refVoltage;
+
+ uint16 GPIO_Values[MAXIMUM_GPIO];
+
+ uint32 overVoltage;
+ uint32 underVoltage;
+
+} Cell_Module;
+
+
+
+uint8 initAMS(SPI_HandleTypeDef* hspi, uint8 numofcells, uint8 numofaux);
+uint8 amsWakeUp();
+
+uint8 amsCellMeasurement(Cell_Module *module);
+uint8 amsConfigCellMeasurement(uint8 numberofChannels);
+
+uint8 amsAuxMeasurement(Cell_Module *module);
+uint8 amsConfigAuxMeasurement(uint16 Channels);
+
+uint8 amsInternalStatusMeasurement(Cell_Module *module);
+
+uint8 amsConfigGPIO(uint16 gpios);
+uint8 amsSetGPIO(uint16 gpios);
+uint8 readGPIO(Cell_Module* module);
+
+uint8 amsConfigBalancing(uint32 Channels);
+uint8 amsStartBalancing(uint8 dutyCycle);
+uint8 amsStopBalancing();
+
+uint8 amsSelfTest();
+
+uint8 amsConfigUnderVoltage(uint16 underVoltage);
+
+uint8 amsCheckUnderOverVoltage(Cell_Module *module);
+uint8 amsConfigOverVoltage(uint16 overVoltage);
+
+uint8 amscheckOpenCellWire(Cell_Module *module);
+
+uint8 amsClearStatus();
+uint8 amsClearAux();
+uint8 amsClearCells();
+
+uint8 amsSendWarning();
+uint8 amsSendError();
+
+uint8 amsClearWarning();
+uint8 amsClearError();
+
+uint8 amsReadCellVoltages(Cell_Module *module);
+
+#endif /* INC_ADBMS_ABSTRACTION_H_ */
diff --git a/BMS_Testbench/BMS_Software_V1/Core/Inc/ADBMS_CMD_MAKROS.h b/BMS_Testbench/BMS_Software_V1/Core/Inc/ADBMS_CMD_MAKROS.h
new file mode 100644
index 0000000..9589e5c
--- /dev/null
+++ b/BMS_Testbench/BMS_Software_V1/Core/Inc/ADBMS_CMD_MAKROS.h
@@ -0,0 +1,191 @@
+/*
+ * ADBMS_CMD_MAKROS.h
+ *
+ * Created on: 14.07.2022
+ * Author: max
+ */
+
+#ifndef INC_ADBMS_CMD_MAKROS_H_
+#define INC_ADBMS_CMD_MAKROS_H_
+
+#define WRCFGA 0x0001 //Write Configuration Register Group A
+#define RDCFGA 0x0002 //Read Configuration Register Group A
+#define WRCFGB 0x0024 //Write Configuration Register Group B
+#define RDCFGB 0x0026 //Read Configuration Register Group B
+
+#define RDCVA 0x0004 //Read Cell Voltage Register Group A
+#define RDCVB 0x0006 //Read Cell Voltage Register Group B
+#define RDCVC 0x0008 //Read Cell Voltage Register Group C
+#define RDCVD 0x000A //Read Cell Voltage Register Group D
+#define RDCVE 0x0009 //Read Cell Voltage Register Group E
+#define RDCVF 0x000B //Read Cell Voltage Register Group F
+
+#define RDAUXA 0x000C //Read Auxilliary Register Group A
+#define RDAUXB 0x000E //Read Auxilliary Register Group B
+#define RDAUXC 0x000D //Read Auxilliary Register Group C
+#define RDAUXD 0x000F //Read Auxilliary Register Group D
+
+#define RDSTATA 0x0010//Read Status Register Group A
+#define RDSTATB 0x0012//Read Status Register Group B
+
+#define WRSCTRL 0x0014 //Write S Control Register Group
+#define WRPWM 0x0020//Write PWM Register Group
+#define WRPSB 0x001A //Write PWM/S Control Register Group
+#define RDSCTRL 0x0016 //Read S Control Register Group
+#define RDPWM 0x0022//Read PWM Register Group
+#define RDPSB 0x001E //Read PWM/S Control Register Group B
+#define STSCTRL 0x0019 //Start S Control Pulsing and Poll Status
+#define CLRSCTRL 0x0018 //Clear S Control Register Group
+
+#define ADCV 0x0260 //Start Cell Voltage Conversion
+#define ADOW 0x0228 //Start Open Wire ADC Conversion and Poll Status
+#define CVST 0x0207//Start Self Test Cell Voltage Conversion and Poll Status
+#define ADOL 0x201//Start Overlap Measurement of Cell 7 and 13 Voltages
+#define ADAX 0x460 //Start GPIOs ADC Conversion and Poll Status
+#define ADAXD 0x400 //Start GPIOs ADC Conversion with Digital Redundancy and Poll Status
+#define AXOW 0x410 //Start GPIOs Open Wire ADC Conversion and Poll Status
+#define AXST 0x407 //Start Self Test GPIOs Conversion and Poll Status
+#define ADSTAT 0x468 //Start Status Group ADC Conversion and Poll Status
+#define ADSTATD 0x408//Start Status Group ADC Conversion with Digital Redundany and Poll Status
+#define STATST 0x40F //Start Self Test Status Group Conversion and Poll Status
+#define ADCVAX 0x46F//Start Combiinden Cell Voltage and GPIO 1, GPIO2, Conversion and Poll Status
+#define ADCVSC 0x467//Start Combined Cell Voltage and SC Conversion and Poll Status
+
+#define CLRCELL 0x711//Clear Cell Voltage Register Groups
+#define CLRAUX 0x712//Clear Auxiliary Register Groups
+#define CLRSTAT 0x713//Clear Status Register Groups
+#define PLADC 0x714//Poll ADC Conversion Status
+#define DIAGN 0x715//Diagnos MUX and Poll Status
+#define WRCOMM 0x721//Write COMM Register Group
+#define RDCOMM 0x722//Read COMM Register Group
+#define STCOMM 0x723//Start I2C/SPI Communication
+#define MUTE 0x28//Mute Discharge
+#define UNMUTE 0x29//Unmute Discharge
+
+
+/*ADC Modes
+ * ADCOPT(CFGAR0,Bit 0) = 0 ADCOPT(CFGAR0,Bit 0) = 1
+ * 00 422Hz mode 1kHz mode
+ * 01 27kHz mode (fast) 14kHz mode
+ * 10 7kHz mode (normal) 3kHz mode
+ * 11 26Hz mode (filtered) 2kHz mode
+ */
+#define MD00 (0x00<<7)
+#define MD01 (0x01<<7)
+#define MD10 (0x02<<7)
+#define MD11 (0x03<<7)
+
+//Discharge Permitted if DCP = 1
+#define DCP (0x01<<4)
+
+/*Cell Selection for ADC Conversion
+ * 000: All Cells
+ * 001: Cells 1,7,13
+ * 010: Cells 2,8,14
+ * 011: Cells 3,9,15
+ * 100: Cells 4,10,16
+ * 101: Cells 5,11,17
+ * 110: Cells 6,12,18
+ */
+#define CH000 (0x00)
+#define CH001 (0x01)
+#define CH010 (0x02)
+#define CH011 (0x03)
+#define CH100 (0x04)
+#define CH101 (0x05)
+#define CH110 (0x06)
+
+
+/* Pull-Up/Pull-Down Current for Open Wire Conversion
+ * 0 Pull down current
+ * 1 Pull up current
+ */
+#define PUP (0x01<<6)
+
+
+/*Self Test Mode Selection
+ * ST01 for Self Test 1
+ * ST02 for Self Test 2
+ * for value consultate Datasheet
+ */
+#define ST01 (0x01<<5)
+#define ST10 (0x02<<5)
+
+/* GPIO Selection for ADC Converion
+ * 000: GPIO1 to 5, 2nd Reference, GPIO 6 to 9
+ * 001: GPIO1 and GPIO6
+ * 010 GPIO2 and GPIO7
+ * 011 GPIO3 and GPIO8
+ * 100 GPIO4 and GPIO9
+ * 101 GPIO5
+ * 110 2nd Reference
+ */
+
+#define CHG000 (0x00)
+#define CHG001 (0x01)
+#define CHG010 (0x02)
+#define CHG011 (0x03)
+#define CHG100 (0x04)
+#define CHG101 (0x05)
+#define CHG110 (0x06)
+
+/* Status Group Selection
+ * 000: SC,ITMP,VA,VD
+ * 001: SC
+ * 010: ITMP
+ * 011: VA
+ * 100: VD
+ */
+
+#define CHST000 (0x00)
+#define CHST001 (0x01)
+#define CHST010 (0x02)
+#define CHST011 (0x03)
+#define CHST100 (0x04)
+
+#define PEC_FIELD_SIZE 2
+
+#define CFG_GROUP_A_SIZE 6
+#define CFG_GROUP_B_SIZE 6
+#define CV_GROUP_A_SIZE 6
+#define CV_GROUP_B_SIZE 6
+#define CV_GROUP_C_SIZE 6
+#define CV_GROUP_D_SIZE 6
+#define CV_GROUP_E_SIZE 6
+#define CV_GROUP_F_SIZE 6
+
+#define AUX_GROUP_A_SIZE 6
+#define AUX_GROUP_B_SIZE 6
+#define AUX_GROUP_C_SIZE 6
+#define AUX_GROUP_D_SIZE 6
+
+#define STATUS_GROUP_A_SIZE 6
+#define STATUS_GROUP_B_SIZE 6
+#define COMM_GROUP_SIZE 6
+#define S_CONTROL_GROUP_SIZE 6
+#define PWM_GROUP_SIZE 6
+#define PWM_S_CONTROL_GROUP_B_SIZE 6
+
+#define CFG_GROUP_A_ID 1
+#define CFG_GROUP_B_ID 2
+#define CV_GROUP_A_ID 3
+#define CV_GROUP_B_ID 4
+#define CV_GROUP_C_ID 5
+#define CV_GROUP_D_ID 6
+#define CV_GROUP_E_ID 7
+#define CV_GROUP_F_ID 8
+
+#define AUX_GROUP_A_ID 9
+#define AUX_GROUP_B_ID 10
+#define AUX_GROUP_C_ID 11
+#define AUX_GROUP_D_ID 12
+
+#define STATUS_GROUP_A_ID 13
+#define STATUS_GROUP_B_ID 14
+#define COMM_GROUP_ID 15
+#define S_CONTROL_GROUP_ID 16
+#define PWM_GROUP_ID 17
+#define PWM_S_CONTROL_GROUP_B_ID 18
+
+
+#endif /* INC_ADBMS_CMD_MAKROS_H_ */
diff --git a/BMS_Testbench/BMS_Software_V1/Core/Inc/ADBMS_LL_Driver.h b/BMS_Testbench/BMS_Software_V1/Core/Inc/ADBMS_LL_Driver.h
new file mode 100644
index 0000000..d8834b3
--- /dev/null
+++ b/BMS_Testbench/BMS_Software_V1/Core/Inc/ADBMS_LL_Driver.h
@@ -0,0 +1,44 @@
+/*
+ * ADBMS_LL_Driver.h
+ *
+ * Created on: 05.06.2022
+ * Author: max
+ */
+
+#ifndef ADBMS_LL_DRIVER_H_
+#define ADBMS_LL_DRIVER_H_
+
+#define TARGET_STM32
+
+
+
+#include "main.h"
+
+
+#ifdef TARGET_STM32
+ typedef uint8_t uint8;
+ typedef uint16_t uint16;
+ typedef uint32_t uint32;
+#endif
+
+
+uint8 adbmsDriverInit();
+uint8 calculatePEC(uint8* data, uint8 datalen);
+uint16 updatePEC(uint16 currentPEC, uint8 din);
+uint8 checkPEC(uint8* data, uint8 datalen);
+
+uint8 writeCMD(uint16 command, uint8* args, uint8 arglen);
+uint8 readCMD(uint16 command, uint8* buffer, uint8 buflen);
+
+void mcuAdbmsCSLow();
+void mcuAdbmsCSHigh();
+
+uint8 mcuSPITransmit(uint8* buffer, uint8 buffersize);
+uint8 mcuSPIReceive(uint8* buffer, uint8 buffersize);
+uint8 mcuSPITransmitReceive(uint8* rxbuffer, uint8* txbuffer, uint8 buffersize);
+
+uint8 wakeUpCmd();
+void mcuDelay(uint16 delay);
+
+
+#endif /* ADBMS_LL_DRIVER_H_ */
diff --git a/BMS_Testbench/BMS_Software_V1/Core/Inc/AMS_CAN.h b/BMS_Testbench/BMS_Software_V1/Core/Inc/AMS_CAN.h
new file mode 100644
index 0000000..76c2ade
--- /dev/null
+++ b/BMS_Testbench/BMS_Software_V1/Core/Inc/AMS_CAN.h
@@ -0,0 +1,49 @@
+/*
+ * AMS_CAN.h
+ *
+ * Created on: Mar 19, 2022
+ * Author: jasper
+ */
+
+#ifndef INC_AMS_CAN_H_
+#define INC_AMS_CAN_H_
+
+#include "main.h"
+
+#include "stm32f3xx_hal.h"
+#include "stm32f3xx_hal_can.h"
+#include "stm32f3xx_hal_def.h"
+
+#include
+
+#define CAN_ID_SLAVE_ERROR 0x001
+#define CAN_ID_CLOCK_SYNC 0x002
+#define CAN_ID_MASTER_HEARTBEAT 0x010
+#define CAN_ID_AMS_SLAVE_HEARTBEAT_BASE 0x600
+#define CAN_HEARTBEAT_TX_TIMEOUT 10
+/* ms */
+#define BMS_IN_TEST_MODE 1 // set to test the BMS use < sudo ip link set can0 up type can bitrate 500000 > // Use for Test Mode only for reducing weight of the handler
+#define BMS_TEST_ID 0
+
+extern CAN_HandleTypeDef* ams_can_handle;
+
+void ams_can_init(CAN_HandleTypeDef* ams, CAN_HandleTypeDef* car);
+
+void ams_can_handle_ams_msg(CAN_RxHeaderTypeDef* header, uint8_t* data);
+
+void ams_can_send_heartbeat();
+/**
+ * @brief Send an AMS Error via CAN.
+ *
+ * @param error_code The kind of error
+ * @param transmission_timeout How long to wait for the transmission to complete
+ * after starting it (in ms). Set to 0 for no wait.
+ */
+/*void ams_can_send_error(AMS_ErrorCode error_code,
+ uint32_t transmission_timeout);*/
+
+HAL_StatusTypeDef ams_can_wait_for_free_mailboxes(CAN_HandleTypeDef* handle,
+ int num_mailboxes,
+ uint32_t timeout);
+
+#endif /* INC_AMS_CAN_H_ */
diff --git a/BMS_Testbench/BMS_Software_V1/Core/Inc/AMS_HighLevel.h b/BMS_Testbench/BMS_Software_V1/Core/Inc/AMS_HighLevel.h
new file mode 100644
index 0000000..91f6245
--- /dev/null
+++ b/BMS_Testbench/BMS_Software_V1/Core/Inc/AMS_HighLevel.h
@@ -0,0 +1,46 @@
+/*
+ * AMS_HighLevel.h
+ *
+ * Created on: 20.07.2022
+ * Author: max
+ */
+
+#ifndef INC_AMS_HIGHLEVEL_H_
+#define INC_AMS_HIGHLEVEL_H_
+
+#include "ADBMS_Abstraction.h"
+#include "ADBMS_LL_Driver.h"
+#include "ADBMS_CMD_MAKROS.h"
+
+
+
+typedef enum {AMSDEACTIVE, AMSIDLE, AMSCHARGING, AMSIDLEBALANCING, AMSDISCHARGING, AMSWARNING, AMSERROR} amsState;
+
+extern amsState currentAMSState;
+extern Cell_Module module;
+extern uint32_t balancedCells;
+extern uint8_t BalancingActive;
+extern uint8_t stateofcharge;
+
+extern uint8_t amserrorcode;
+extern uint8_t amswarningcode;
+
+extern uint8_t numberofCells;
+extern uint8_t numberofAux;
+
+
+void AMS_Init();
+void AMS_Loop();
+
+uint8_t AMS_Balancing_Loop();
+uint8_t AMS_Idle_Loop();
+uint8_t AMS_Warning_Loop();
+uint8_t AMS_Error_Loop();
+uint8_t AMS_Charging_Loop();
+uint8_t AMS_Discharging_Loop();
+
+uint8_t writeWarningLog(uint8_t warningCode);
+uint8_t writeErrorLog(uint8_t errorCode);
+uint8_t integrateCurrent();
+
+#endif /* INC_AMS_HIGHLEVEL_H_ */
diff --git a/BMS_Testbench/BMS_Software_V1/Core/Inc/Testbench.h b/BMS_Testbench/BMS_Software_V1/Core/Inc/Testbench.h
new file mode 100644
index 0000000..a358abc
--- /dev/null
+++ b/BMS_Testbench/BMS_Software_V1/Core/Inc/Testbench.h
@@ -0,0 +1,32 @@
+/*
+ * Testbench.h
+ *
+ * Created on: 13.03.2023
+ * Author: david
+ */
+
+#ifndef SRC_TESTBENCH_H_
+#define SRC_TESTBENCH_H_
+
+#include "main.h"
+
+#include "stm32f3xx_hal.h"
+#include "stm32f3xx_hal_can.h"
+#include "stm32f3xx_hal_def.h"
+#include "ADBMS_Abstraction.h"
+
+#include
+
+extern Cell_Module module;
+
+#define CAN_TEST 0x1
+#define VOLTAGE_TEST 0x2
+#define TEMP_TEST 0x3
+#define EPROM_TEST 0x4
+#define BALANCING_TEST 0x5
+
+
+
+void testLoop(uint8_t* action);
+
+#endif /* SRC_TESTBENCH_H_ */
diff --git a/BMS_Testbench/BMS_Software_V1/Core/Inc/common_defs.h b/BMS_Testbench/BMS_Software_V1/Core/Inc/common_defs.h
new file mode 100644
index 0000000..4e9ac5f
--- /dev/null
+++ b/BMS_Testbench/BMS_Software_V1/Core/Inc/common_defs.h
@@ -0,0 +1,13 @@
+/*
+ * common_defs.h
+ *
+ * Created on: 23 Mar 2022
+ * Author: Jasper
+ */
+
+#ifndef INC_COMMON_DEFS_H_
+#define INC_COMMON_DEFS_H_
+
+#define N_CELLS 17
+
+#endif /* INC_COMMON_DEFS_H_ */
diff --git a/BMS_Testbench/BMS_Software_V1/Core/Inc/main.h b/BMS_Testbench/BMS_Software_V1/Core/Inc/main.h
new file mode 100644
index 0000000..6ea45f8
--- /dev/null
+++ b/BMS_Testbench/BMS_Software_V1/Core/Inc/main.h
@@ -0,0 +1,83 @@
+/* USER CODE BEGIN Header */
+/**
+ ******************************************************************************
+ * @file : main.h
+ * @brief : Header for main.c file.
+ * This file contains the common defines of the application.
+ ******************************************************************************
+ * @attention
+ *
+ * Copyright (c) 2023 STMicroelectronics.
+ * All rights reserved.
+ *
+ * This software is licensed under terms that can be found in the LICENSE file
+ * in the root directory of this software component.
+ * If no LICENSE file comes with this software, it is provided AS-IS.
+ *
+ ******************************************************************************
+ */
+/* USER CODE END Header */
+
+/* Define to prevent recursive inclusion -------------------------------------*/
+#ifndef __MAIN_H
+#define __MAIN_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* Includes ------------------------------------------------------------------*/
+#include "stm32f3xx_hal.h"
+
+/* Private includes ----------------------------------------------------------*/
+/* USER CODE BEGIN Includes */
+
+/* USER CODE END Includes */
+
+/* Exported types ------------------------------------------------------------*/
+/* USER CODE BEGIN ET */
+
+/* USER CODE END ET */
+
+/* Exported constants --------------------------------------------------------*/
+/* USER CODE BEGIN EC */
+
+/* USER CODE END EC */
+
+/* Exported macro ------------------------------------------------------------*/
+/* USER CODE BEGIN EM */
+
+/* USER CODE END EM */
+
+/* Exported functions prototypes ---------------------------------------------*/
+void Error_Handler(void);
+
+/* USER CODE BEGIN EFP */
+
+/* USER CODE END EFP */
+
+/* Private defines -----------------------------------------------------------*/
+#define CSB_Pin GPIO_PIN_4
+#define CSB_GPIO_Port GPIOA
+#define Status_0_Pin GPIO_PIN_13
+#define Status_0_GPIO_Port GPIOB
+#define Status_1_Pin GPIO_PIN_14
+#define Status_1_GPIO_Port GPIOB
+#define Status_2_Pin GPIO_PIN_15
+#define Status_2_GPIO_Port GPIOB
+#define Status_3_Pin GPIO_PIN_8
+#define Status_3_GPIO_Port GPIOA
+#define TMP_SCL_Pin GPIO_PIN_15
+#define TMP_SCL_GPIO_Port GPIOA
+#define TMP_SDA_Pin GPIO_PIN_7
+#define TMP_SDA_GPIO_Port GPIOB
+
+/* USER CODE BEGIN Private defines */
+
+/* USER CODE END Private defines */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __MAIN_H */
diff --git a/BMS_Testbench/BMS_Software_V1/Core/Inc/stm32f3xx_hal_conf.h b/BMS_Testbench/BMS_Software_V1/Core/Inc/stm32f3xx_hal_conf.h
new file mode 100644
index 0000000..d2b6f92
--- /dev/null
+++ b/BMS_Testbench/BMS_Software_V1/Core/Inc/stm32f3xx_hal_conf.h
@@ -0,0 +1,359 @@
+/* USER CODE BEGIN Header */
+/**
+ ******************************************************************************
+ * @file stm32f3xx_hal_conf.h
+ * @brief HAL configuration file.
+ ******************************************************************************
+ * @attention
+ *
+ * Copyright (c) 2016 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 __STM32F3xx_HAL_CONF_H
+#define __STM32F3xx_HAL_CONF_H
+
+#ifdef __cplusplus
+ extern "C" {
+#endif
+
+/* Exported types ------------------------------------------------------------*/
+/* Exported constants --------------------------------------------------------*/
+
+/* ########################## Module Selection ############################## */
+/**
+ * @brief This is the list of modules to be used in the HAL driver
+ */
+
+#define HAL_MODULE_ENABLED
+ /*#define HAL_ADC_MODULE_ENABLED */
+/*#define HAL_CRYP_MODULE_ENABLED */
+#define HAL_CAN_MODULE_ENABLED
+/*#define HAL_CEC_MODULE_ENABLED */
+/*#define HAL_NAND_MODULE_ENABLED */
+/*#define HAL_NOR_MODULE_ENABLED */
+/*#define HAL_PCCARD_MODULE_ENABLED */
+/*#define HAL_SRAM_MODULE_ENABLED */
+/*#define HAL_HRTIM_MODULE_ENABLED */
+/*#define HAL_OPAMP_MODULE_ENABLED */
+/*#define HAL_SDADC_MODULE_ENABLED */
+/*#define HAL_TSC_MODULE_ENABLED */
+/*#define HAL_COMP_MODULE_ENABLED */
+/*#define HAL_CRC_MODULE_ENABLED */
+/*#define HAL_CRYP_MODULE_ENABLED */
+/*#define HAL_DAC_MODULE_ENABLED */
+/*#define HAL_I2S_MODULE_ENABLED */
+/*#define HAL_IWDG_MODULE_ENABLED */
+/*#define HAL_LCD_MODULE_ENABLED */
+/*#define HAL_LPTIM_MODULE_ENABLED */
+/*#define HAL_RNG_MODULE_ENABLED */
+/*#define HAL_RTC_MODULE_ENABLED */
+#define HAL_SPI_MODULE_ENABLED
+/*#define HAL_TIM_MODULE_ENABLED */
+/*#define HAL_UART_MODULE_ENABLED */
+/*#define HAL_USART_MODULE_ENABLED */
+/*#define HAL_IRDA_MODULE_ENABLED */
+/*#define HAL_SMARTCARD_MODULE_ENABLED */
+/*#define HAL_SMBUS_MODULE_ENABLED */
+/*#define HAL_WWDG_MODULE_ENABLED */
+/*#define HAL_PCD_MODULE_ENABLED */
+#define HAL_GPIO_MODULE_ENABLED
+#define HAL_EXTI_MODULE_ENABLED
+/* #define HAL_CAN_LEGACY_MODULE_ENABLED */
+#define HAL_DMA_MODULE_ENABLED
+#define HAL_RCC_MODULE_ENABLED
+#define HAL_FLASH_MODULE_ENABLED
+#define HAL_PWR_MODULE_ENABLED
+#define HAL_CORTEX_MODULE_ENABLED
+#define HAL_I2C_MODULE_ENABLED
+/* ########################## HSE/HSI Values adaptation ##################### */
+/**
+ * @brief Adjust the value of External High Speed oscillator (HSE) used in your application.
+ * This value is used by the RCC HAL module to compute the system frequency
+ * (when HSE is used as system clock source, directly or through the PLL).
+ */
+#if !defined (HSE_VALUE)
+ #define HSE_VALUE ((uint32_t)16000000) /*!< Value of the External oscillator in Hz */
+#endif /* HSE_VALUE */
+
+/**
+ * @brief In the following line adjust the External High Speed oscillator (HSE) Startup
+ * Timeout value
+ */
+#if !defined (HSE_STARTUP_TIMEOUT)
+ #define HSE_STARTUP_TIMEOUT ((uint32_t)100) /*!< Time out for HSE start up, in ms */
+#endif /* HSE_STARTUP_TIMEOUT */
+
+/**
+ * @brief Internal High Speed oscillator (HSI) value.
+ * This value is used by the RCC HAL module to compute the system frequency
+ * (when HSI is used as system clock source, directly or through the PLL).
+ */
+#if !defined (HSI_VALUE)
+ #define HSI_VALUE ((uint32_t)8000000) /*!< Value of the Internal oscillator in Hz*/
+#endif /* HSI_VALUE */
+
+/**
+ * @brief In the following line adjust the Internal High Speed oscillator (HSI) Startup
+ * Timeout value
+ */
+#if !defined (HSI_STARTUP_TIMEOUT)
+ #define HSI_STARTUP_TIMEOUT ((uint32_t)5000) /*!< Time out for HSI start up */
+#endif /* HSI_STARTUP_TIMEOUT */
+
+/**
+ * @brief Internal Low Speed oscillator (LSI) value.
+ */
+#if !defined (LSI_VALUE)
+ #define LSI_VALUE ((uint32_t)40000)
+#endif /* LSI_VALUE */ /*!< Value of the Internal Low Speed oscillator in Hz
+ The real value may vary depending on the variations
+ in voltage and temperature. */
+/**
+ * @brief External Low Speed oscillator (LSE) value.
+ */
+#if !defined (LSE_VALUE)
+ #define LSE_VALUE ((uint32_t)32768) /*!< Value of the External Low Speed oscillator in Hz */
+#endif /* LSE_VALUE */
+
+/**
+ * @brief Time out for LSE start up value in ms.
+ */
+#if !defined (LSE_STARTUP_TIMEOUT)
+ #define LSE_STARTUP_TIMEOUT ((uint32_t)5000) /*!< Time out for LSE start up, in ms */
+#endif /* LSE_STARTUP_TIMEOUT */
+
+/**
+ * @brief External clock source for I2S peripheral
+ * This value is used by the I2S HAL module to compute the I2S clock source
+ * frequency, this source is inserted directly through I2S_CKIN pad.
+ * - External clock generated through external PLL component on EVAL 303 (based on MCO or crystal)
+ * - External clock not generated on EVAL 373
+ */
+#if !defined (EXTERNAL_CLOCK_VALUE)
+ #define EXTERNAL_CLOCK_VALUE ((uint32_t)8000000) /*!< Value of the External oscillator in Hz*/
+#endif /* EXTERNAL_CLOCK_VALUE */
+
+/* Tip: To avoid modifying this file each time you need to use different HSE,
+ === you can define the HSE value in your toolchain compiler preprocessor. */
+
+/* ########################### System Configuration ######################### */
+/**
+ * @brief This is the HAL system configuration section
+ */
+
+#define VDD_VALUE ((uint32_t)3300) /*!< Value of VDD in mv */
+#define TICK_INT_PRIORITY ((uint32_t)15) /*!< tick interrupt priority (lowest by default) */
+#define USE_RTOS 0
+#define PREFETCH_ENABLE 1
+#define INSTRUCTION_CACHE_ENABLE 0
+#define DATA_CACHE_ENABLE 0
+#define USE_SPI_CRC 0U
+
+#define USE_HAL_ADC_REGISTER_CALLBACKS 0U /* ADC register callback disabled */
+#define USE_HAL_CAN_REGISTER_CALLBACKS 0U /* CAN register callback disabled */
+#define USE_HAL_COMP_REGISTER_CALLBACKS 0U /* COMP register callback disabled */
+#define USE_HAL_CEC_REGISTER_CALLBACKS 0U /* CEC register callback disabled */
+#define USE_HAL_DAC_REGISTER_CALLBACKS 0U /* DAC register callback disabled */
+#define USE_HAL_SRAM_REGISTER_CALLBACKS 0U /* SRAM register callback disabled */
+#define USE_HAL_SMBUS_REGISTER_CALLBACKS 0U /* SMBUS register callback disabled */
+#define USE_HAL_NAND_REGISTER_CALLBACKS 0U /* NAND register callback disabled */
+#define USE_HAL_NOR_REGISTER_CALLBACKS 0U /* NOR register callback disabled */
+#define USE_HAL_PCCARD_REGISTER_CALLBACKS 0U /* PCCARD register callback disabled */
+#define USE_HAL_HRTIM_REGISTER_CALLBACKS 0U /* HRTIM register callback disabled */
+#define USE_HAL_I2C_REGISTER_CALLBACKS 0U /* I2C register callback disabled */
+#define USE_HAL_UART_REGISTER_CALLBACKS 0U /* UART register callback disabled */
+#define USE_HAL_USART_REGISTER_CALLBACKS 0U /* USART register callback disabled */
+#define USE_HAL_IRDA_REGISTER_CALLBACKS 0U /* IRDA register callback disabled */
+#define USE_HAL_SMARTCARD_REGISTER_CALLBACKS 0U /* SMARTCARD register callback disabled */
+#define USE_HAL_WWDG_REGISTER_CALLBACKS 0U /* WWDG register callback disabled */
+#define USE_HAL_OPAMP_REGISTER_CALLBACKS 0U /* OPAMP register callback disabled */
+#define USE_HAL_RTC_REGISTER_CALLBACKS 0U /* RTC register callback disabled */
+#define USE_HAL_SPI_REGISTER_CALLBACKS 0U /* SPI register callback disabled */
+#define USE_HAL_I2S_REGISTER_CALLBACKS 0U /* I2S register callback disabled */
+#define USE_HAL_TIM_REGISTER_CALLBACKS 0U /* TIM register callback disabled */
+#define USE_HAL_TSC_REGISTER_CALLBACKS 0U /* TSC register callback disabled */
+#define USE_HAL_PCD_REGISTER_CALLBACKS 0U /* PCD register callback disabled */
+
+/* ########################## Assert Selection ############################## */
+/**
+ * @brief Uncomment the line below to expanse the "assert_param" macro in the
+ * HAL drivers code
+ */
+/* #define USE_FULL_ASSERT 1U */
+
+/* Includes ------------------------------------------------------------------*/
+/**
+ * @brief Include module's header file
+ */
+
+#ifdef HAL_RCC_MODULE_ENABLED
+ #include "stm32f3xx_hal_rcc.h"
+#endif /* HAL_RCC_MODULE_ENABLED */
+
+#ifdef HAL_GPIO_MODULE_ENABLED
+ #include "stm32f3xx_hal_gpio.h"
+#endif /* HAL_GPIO_MODULE_ENABLED */
+
+#ifdef HAL_EXTI_MODULE_ENABLED
+ #include "stm32f3xx_hal_exti.h"
+#endif /* HAL_EXTI_MODULE_ENABLED */
+
+#ifdef HAL_DMA_MODULE_ENABLED
+ #include "stm32f3xx_hal_dma.h"
+#endif /* HAL_DMA_MODULE_ENABLED */
+
+#ifdef HAL_CORTEX_MODULE_ENABLED
+ #include "stm32f3xx_hal_cortex.h"
+#endif /* HAL_CORTEX_MODULE_ENABLED */
+
+#ifdef HAL_ADC_MODULE_ENABLED
+ #include "stm32f3xx_hal_adc.h"
+#endif /* HAL_ADC_MODULE_ENABLED */
+
+#ifdef HAL_CAN_MODULE_ENABLED
+ #include "stm32f3xx_hal_can.h"
+#endif /* HAL_CAN_MODULE_ENABLED */
+
+#ifdef HAL_CAN_LEGACY_MODULE_ENABLED
+ #include "stm32f3xx_hal_can_legacy.h"
+#endif /* HAL_CAN_LEGACY_MODULE_ENABLED */
+
+#ifdef HAL_CEC_MODULE_ENABLED
+ #include "stm32f3xx_hal_cec.h"
+#endif /* HAL_CEC_MODULE_ENABLED */
+
+#ifdef HAL_COMP_MODULE_ENABLED
+ #include "stm32f3xx_hal_comp.h"
+#endif /* HAL_COMP_MODULE_ENABLED */
+
+#ifdef HAL_CRC_MODULE_ENABLED
+ #include "stm32f3xx_hal_crc.h"
+#endif /* HAL_CRC_MODULE_ENABLED */
+
+#ifdef HAL_DAC_MODULE_ENABLED
+ #include "stm32f3xx_hal_dac.h"
+#endif /* HAL_DAC_MODULE_ENABLED */
+
+#ifdef HAL_FLASH_MODULE_ENABLED
+ #include "stm32f3xx_hal_flash.h"
+#endif /* HAL_FLASH_MODULE_ENABLED */
+
+#ifdef HAL_SRAM_MODULE_ENABLED
+ #include "stm32f3xx_hal_sram.h"
+#endif /* HAL_SRAM_MODULE_ENABLED */
+
+#ifdef HAL_NOR_MODULE_ENABLED
+ #include "stm32f3xx_hal_nor.h"
+#endif /* HAL_NOR_MODULE_ENABLED */
+
+#ifdef HAL_NAND_MODULE_ENABLED
+ #include "stm32f3xx_hal_nand.h"
+#endif /* HAL_NAND_MODULE_ENABLED */
+
+#ifdef HAL_PCCARD_MODULE_ENABLED
+ #include "stm32f3xx_hal_pccard.h"
+#endif /* HAL_PCCARD_MODULE_ENABLED */
+
+#ifdef HAL_HRTIM_MODULE_ENABLED
+ #include "stm32f3xx_hal_hrtim.h"
+#endif /* HAL_HRTIM_MODULE_ENABLED */
+
+#ifdef HAL_I2C_MODULE_ENABLED
+ #include "stm32f3xx_hal_i2c.h"
+#endif /* HAL_I2C_MODULE_ENABLED */
+
+#ifdef HAL_I2S_MODULE_ENABLED
+ #include "stm32f3xx_hal_i2s.h"
+#endif /* HAL_I2S_MODULE_ENABLED */
+
+#ifdef HAL_IRDA_MODULE_ENABLED
+ #include "stm32f3xx_hal_irda.h"
+#endif /* HAL_IRDA_MODULE_ENABLED */
+
+#ifdef HAL_IWDG_MODULE_ENABLED
+ #include "stm32f3xx_hal_iwdg.h"
+#endif /* HAL_IWDG_MODULE_ENABLED */
+
+#ifdef HAL_OPAMP_MODULE_ENABLED
+ #include "stm32f3xx_hal_opamp.h"
+#endif /* HAL_OPAMP_MODULE_ENABLED */
+
+#ifdef HAL_PCD_MODULE_ENABLED
+ #include "stm32f3xx_hal_pcd.h"
+#endif /* HAL_PCD_MODULE_ENABLED */
+
+#ifdef HAL_PWR_MODULE_ENABLED
+ #include "stm32f3xx_hal_pwr.h"
+#endif /* HAL_PWR_MODULE_ENABLED */
+
+#ifdef HAL_RTC_MODULE_ENABLED
+ #include "stm32f3xx_hal_rtc.h"
+#endif /* HAL_RTC_MODULE_ENABLED */
+
+#ifdef HAL_SDADC_MODULE_ENABLED
+ #include "stm32f3xx_hal_sdadc.h"
+#endif /* HAL_SDADC_MODULE_ENABLED */
+
+#ifdef HAL_SMARTCARD_MODULE_ENABLED
+ #include "stm32f3xx_hal_smartcard.h"
+#endif /* HAL_SMARTCARD_MODULE_ENABLED */
+
+#ifdef HAL_SMBUS_MODULE_ENABLED
+ #include "stm32f3xx_hal_smbus.h"
+#endif /* HAL_SMBUS_MODULE_ENABLED */
+
+#ifdef HAL_SPI_MODULE_ENABLED
+ #include "stm32f3xx_hal_spi.h"
+#endif /* HAL_SPI_MODULE_ENABLED */
+
+#ifdef HAL_TIM_MODULE_ENABLED
+ #include "stm32f3xx_hal_tim.h"
+#endif /* HAL_TIM_MODULE_ENABLED */
+
+#ifdef HAL_TSC_MODULE_ENABLED
+ #include "stm32f3xx_hal_tsc.h"
+#endif /* HAL_TSC_MODULE_ENABLED */
+
+#ifdef HAL_UART_MODULE_ENABLED
+ #include "stm32f3xx_hal_uart.h"
+#endif /* HAL_UART_MODULE_ENABLED */
+
+#ifdef HAL_USART_MODULE_ENABLED
+ #include "stm32f3xx_hal_usart.h"
+#endif /* HAL_USART_MODULE_ENABLED */
+
+#ifdef HAL_WWDG_MODULE_ENABLED
+ #include "stm32f3xx_hal_wwdg.h"
+#endif /* HAL_WWDG_MODULE_ENABLED */
+
+/* Exported macro ------------------------------------------------------------*/
+#ifdef USE_FULL_ASSERT
+/**
+ * @brief The assert_param macro is used for function's parameters check.
+ * @param expr If expr is false, it calls assert_failed function
+ * which reports the name of the source file and the source
+ * line number of the call that failed.
+ * If expr is true, it returns no value.
+ * @retval None
+ */
+ #define assert_param(expr) ((expr) ? (void)0U : assert_failed((uint8_t *)__FILE__, __LINE__))
+/* Exported functions ------------------------------------------------------- */
+ void assert_failed(uint8_t* file, uint32_t line);
+#else
+ #define assert_param(expr) ((void)0U)
+#endif /* USE_FULL_ASSERT */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __STM32F3xx_HAL_CONF_H */
diff --git a/BMS_Testbench/BMS_Software_V1/Core/Inc/stm32f3xx_it.h b/BMS_Testbench/BMS_Software_V1/Core/Inc/stm32f3xx_it.h
new file mode 100644
index 0000000..ba25618
--- /dev/null
+++ b/BMS_Testbench/BMS_Software_V1/Core/Inc/stm32f3xx_it.h
@@ -0,0 +1,67 @@
+/* USER CODE BEGIN Header */
+/**
+ ******************************************************************************
+ * @file stm32f3xx_it.h
+ * @brief This file contains the headers of the interrupt handlers.
+ ******************************************************************************
+ * @attention
+ *
+ * Copyright (c) 2023 STMicroelectronics.
+ * All rights reserved.
+ *
+ * This software is licensed under terms that can be found in the LICENSE file
+ * in the root directory of this software component.
+ * If no LICENSE file comes with this software, it is provided AS-IS.
+ *
+ ******************************************************************************
+ */
+/* USER CODE END Header */
+
+/* Define to prevent recursive inclusion -------------------------------------*/
+#ifndef __STM32F3xx_IT_H
+#define __STM32F3xx_IT_H
+
+#ifdef __cplusplus
+ extern "C" {
+#endif
+
+/* Private includes ----------------------------------------------------------*/
+/* USER CODE BEGIN Includes */
+
+/* USER CODE END Includes */
+
+/* Exported types ------------------------------------------------------------*/
+/* USER CODE BEGIN ET */
+
+/* USER CODE END ET */
+
+/* Exported constants --------------------------------------------------------*/
+/* USER CODE BEGIN EC */
+
+/* USER CODE END EC */
+
+/* Exported macro ------------------------------------------------------------*/
+/* USER CODE BEGIN EM */
+
+/* USER CODE END EM */
+
+/* Exported functions prototypes ---------------------------------------------*/
+void NMI_Handler(void);
+void HardFault_Handler(void);
+void MemManage_Handler(void);
+void BusFault_Handler(void);
+void UsageFault_Handler(void);
+void SVC_Handler(void);
+void DebugMon_Handler(void);
+void PendSV_Handler(void);
+void SysTick_Handler(void);
+void USB_LP_CAN_RX0_IRQHandler(void);
+/* USER CODE BEGIN EFP */
+
+/* USER CODE END EFP */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __STM32F3xx_IT_H */
diff --git a/BMS_Testbench/BMS_Software_V1/Core/Src/ADBMS_Abstraction.c b/BMS_Testbench/BMS_Software_V1/Core/Src/ADBMS_Abstraction.c
new file mode 100644
index 0000000..607810e
--- /dev/null
+++ b/BMS_Testbench/BMS_Software_V1/Core/Src/ADBMS_Abstraction.c
@@ -0,0 +1,422 @@
+/*
+ * ADBMS_Abstraction.c
+ *
+ * Created on: 14.07.2022
+ * Author: max
+ */
+
+#include "ADBMS_Abstraction.h"
+
+
+
+uint8 numberofcells;
+uint8 numberofauxchannels;
+
+uint8 initAMS(SPI_HandleTypeDef* hspi, uint8 numofcells, uint8 numofaux)
+{
+ adbmsDriverInit(hspi);
+ numberofcells = numofcells;
+ numberofauxchannels = numofaux;
+
+
+ amsWakeUp();
+ amsStopBalancing();
+ amsConfigOverVoltage(DEFAULT_OV);
+ amsConfigUnderVoltage(DEFAULT_UV);
+ amsConfigAuxMeasurement(0xFFFF);
+
+ return 0;
+}
+
+uint8 amsWakeUp()
+{
+ uint8 buf[6];
+ readCMD(RDCFGA, buf, 6);
+ return 0;
+}
+
+uint8 amsCellMeasurement(Cell_Module *module)
+{
+ uint8_t rxbuffer[CV_GROUP_A_SIZE];
+ writeCMD((ADCV | CH000 | MD10), rxbuffer, 0);
+ mcuDelay(5);
+ amsReadCellVoltages(module);
+ return 0;
+}
+
+uint8 amsConfigCellMeasurement(uint8 numberofChannels)
+{
+ numberofcells = numberofChannels;
+ return 0;
+}
+
+uint8 amsAuxMeasurement(Cell_Module *module)
+{
+ uint8 args;
+ uint8 rxbuf[AUX_GROUP_A_SIZE];
+ writeCMD(ADAX | MD01 | CHG000, &args, 0);
+
+ mcuDelay(5);
+
+ readCMD(RDAUXA, rxbuf, AUX_GROUP_A_SIZE);
+
+ module->auxVoltages[0] = rxbuf[0] | (rxbuf[1]<<8);
+ module->auxVoltages[1] = rxbuf[2] | (rxbuf[3]<<8);
+ module->auxVoltages[2] = rxbuf[4] | (rxbuf[5]<<8);
+
+ readCMD(RDAUXB, rxbuf, AUX_GROUP_A_SIZE);
+
+ module->auxVoltages[3] = rxbuf[0] | (rxbuf[1]<<8);
+ module->auxVoltages[4] = rxbuf[2] | (rxbuf[3]<<8);
+ module->refVoltage = rxbuf[4] | (rxbuf[5]<<8);
+
+ readCMD(RDAUXC, rxbuf, AUX_GROUP_A_SIZE);
+
+ module->auxVoltages[5] = rxbuf[0] | (rxbuf[1]<<8);
+ module->auxVoltages[6] = rxbuf[2] | (rxbuf[3]<<8);
+ module->auxVoltages[7] = rxbuf[4] | (rxbuf[5]<<8);
+
+ readCMD(RDAUXD, rxbuf, AUX_GROUP_A_SIZE);
+
+ module->auxVoltages[8] = rxbuf[0] | (rxbuf[1]<<8);
+
+ return 0;
+}
+
+uint8 amsInternalStatusMeasurement(Cell_Module *module)
+{
+ uint8 rxbuffer[STATUS_GROUP_A_SIZE];
+ writeCMD(ADSTAT | MD01 | CHST000, rxbuffer, STATUS_GROUP_A_SIZE);
+ mcuDelay(5);
+
+ readCMD(RDSTATA, rxbuffer, STATUS_GROUP_A_SIZE);
+
+ module->sumOfCellMeasurements = rxbuffer[0] | (rxbuffer[1]<<8);
+ module->internalDieTemp = rxbuffer[2] | (rxbuffer[3]<<8);
+ module->analogSupplyVoltage = rxbuffer[4] | (rxbuffer[5]<<8);
+
+ readCMD(RDSTATB, rxbuffer, STATUS_GROUP_B_SIZE);
+ module->digitalSupplyVoltage = rxbuffer[0] | (rxbuffer[1]<<8);
+
+
+ return 0;
+}
+
+uint8 amsConfigAuxMeasurement(uint16 Channels)
+{
+ uint8 buf[CFG_GROUP_A_SIZE];
+
+ readCMD(RDCFGA, buf, CFG_GROUP_A_SIZE);
+ buf[0] |= 0xF8;
+ writeCMD(WRCFGA, buf, CFG_GROUP_A_SIZE);
+
+ readCMD(RDCFGB, buf, CFG_GROUP_B_SIZE);
+ buf[0] |= 0x0F;
+ writeCMD(WRCFGB, buf, CFG_GROUP_B_SIZE);
+ return 0;
+}
+
+uint8 amsConfigGPIO(uint16 gpios)
+{
+ return 0;
+}
+
+uint8 amsSetGPIO(uint16 gpios)
+{
+ return 0;
+}
+
+uint8 readGPIO(Cell_Module* module)
+{
+ return 0;
+}
+
+uint8 amsConfigBalancing(uint32 Channels)
+{
+
+ uint8 regbuffer[CFG_GROUP_A_SIZE];
+ readCMD(RDCFGA, regbuffer, CFG_GROUP_A_SIZE);
+
+ regbuffer[4] = Channels & 0xFF;
+ regbuffer[5] &= 0xF0;
+ regbuffer[5] |= (Channels>>8) & 0x0F;
+ writeCMD(WRCFGA, regbuffer, CFG_GROUP_A_SIZE);
+
+ readCMD(RDCFGB, regbuffer, CFG_GROUP_B_SIZE);
+ regbuffer[0] &= 0x0F;
+ regbuffer[0] |= (Channels>>8) & 0xF0;
+ regbuffer[1] &= 0xFC;
+ regbuffer[1] |= 0x03 & (Channels>>16);
+ writeCMD(WRCFGB, regbuffer, CFG_GROUP_B_SIZE);
+
+ return 0;
+}
+
+uint8 amsStartBalancing(uint8 dutyCycle)
+{
+ writeCMD(UNMUTE, NULL, 0);
+ return 0;
+}
+
+uint8 amsStopBalancing()
+{
+ writeCMD(MUTE, NULL, 0);
+ return 0;
+}
+
+uint8 amsSelfTest()
+{
+ return 0;
+}
+
+
+
+uint8 amsConfigUnderVoltage(uint16 underVoltage)
+{
+ uint8 buffer[CFG_GROUP_A_SIZE];
+ readCMD(RDCFGA, buffer, CFG_GROUP_A_SIZE);
+
+ buffer[1] = (uint8) underVoltage & 0xFF;
+ uint8 ovuv = buffer[2] & 0xF0;
+ ovuv |= (uint8) (underVoltage >> 8) & 0x0F;
+ buffer[2] = ovuv;
+
+ writeCMD(WRCFGA, buffer, CFG_GROUP_A_SIZE);
+
+ return 0;
+}
+
+uint8 amsCheckUnderOverVoltage(Cell_Module *module)
+{
+ uint8 regbuffer[STATUS_GROUP_B_SIZE];
+ uint32 overundervoltages = 0;
+ readCMD(RDSTATB, regbuffer, STATUS_GROUP_B_SIZE);
+ overundervoltages = regbuffer[2] | (regbuffer[3]<<8) | (regbuffer[4]<<16);
+ module->overVoltage = 0;
+ module->underVoltage = 0;
+ for(uint8 n = 0; n < 12; n++)
+ {
+ uint8 overvolt = (overundervoltages>>(2*n+1)) & 0x01;
+ uint8 undervolt = (overundervoltages>>(2*n))&0x01;
+
+ module->overVoltage |= overvolt<underVoltage |= undervolt<>(2*n+1)) & 0x01;
+ uint8 undervolt = (overundervoltages>>(2*n))&0x01;
+
+ module->overVoltage |= (uint32) overvolt<<(n+12);
+ module->underVoltage |= (uint32) undervolt<<(n+12);
+ }
+
+
+ return 0;
+}
+
+uint8 amsConfigOverVoltage(uint16 overVoltage)
+{
+ uint8 buffer[CFG_GROUP_B_SIZE];
+
+ readCMD(RDCFGA, buffer, CFG_GROUP_A_SIZE);
+ buffer[2] &= 0x0F;
+ buffer[2] |= (uint8) overVoltage << 4;
+ buffer[3] = (uint8)(overVoltage>>4);
+
+ writeCMD(WRCFGA, buffer, CFG_GROUP_A_SIZE);
+
+ return 0;
+}
+
+/*
+void dumpRegister(UART_HandleTypeDef *huart, uint8 RegID, uint8* buffer)
+{
+ switch(RegID)
+ {
+ case CFG_GROUP_A_ID:
+ readCMD(RDCFGA, buffer, CFG_GROUP_A_SIZE);
+ break;
+ case CFG_GROUP_B_ID:
+ readCMD(RDCFGB, buffer, CFG_GROUP_A_SIZE);
+ break;
+ case CV_GROUP_A_ID:
+ readCMD(RDCVA, buffer, CFG_GROUP_A_SIZE);
+ break;
+ case CV_GROUP_B_ID:
+ readCMD(RDCVB, buffer, CFG_GROUP_A_SIZE);
+ break;
+ case CV_GROUP_C_ID:
+ readCMD(RDCVC, buffer, CFG_GROUP_A_SIZE);
+ break;
+ case CV_GROUP_D_ID:
+ readCMD(RDCVD, buffer, CFG_GROUP_A_SIZE);
+ break;
+ case CV_GROUP_E_ID:
+ readCMD(RDCVE, buffer, CFG_GROUP_A_SIZE);
+ break;
+ case CV_GROUP_F_ID:
+ readCMD(RDCVF, buffer, CFG_GROUP_A_SIZE);
+ break;
+ case AUX_GROUP_A_ID:
+ readCMD(RDAUXA, buffer, CFG_GROUP_A_SIZE);
+ break;
+ case AUX_GROUP_B_ID:
+ readCMD(RDAUXB, buffer, CFG_GROUP_A_SIZE);
+ break;
+ case AUX_GROUP_C_ID:
+ readCMD(RDAUXC, buffer, CFG_GROUP_A_SIZE);
+ break;
+ case AUX_GROUP_D_ID:
+ readCMD(RDAUXD, buffer, CFG_GROUP_A_SIZE);
+ break;
+ case STATUS_GROUP_A_ID:
+ readCMD(RDSTATA, buffer, CFG_GROUP_A_SIZE);
+ break;
+ case STATUS_GROUP_B_ID:
+ readCMD(RDSTATB, buffer, CFG_GROUP_A_SIZE);
+ break;
+ case COMM_GROUP_ID:
+ readCMD(RDCOMM, buffer, CFG_GROUP_A_SIZE);
+ break;
+ case S_CONTROL_GROUP_ID:
+ readCMD(RDSCTRL, buffer, CFG_GROUP_A_SIZE);
+ break;
+ case PWM_GROUP_ID:
+ readCMD(RDPWM, buffer, CFG_GROUP_A_SIZE);
+ break;
+ case PWM_S_CONTROL_GROUP_B_ID:
+ readCMD(RDPSB, buffer, CFG_GROUP_A_SIZE);
+ break;
+ }
+}
+*/
+
+uint8 amsClearStatus()
+{
+ uint8 buffer[6];
+ writeCMD(CLRSTAT, buffer, 0);
+ return 0;
+}
+uint8 amsClearAux()
+{
+ uint8 buffer[6];
+ writeCMD(CLRAUX, buffer, 0);
+ return 0;
+}
+uint8 amsClearCells()
+{
+ uint8 buffer[6];
+ writeCMD(CLRCELL, buffer, 0);
+ return 0;
+}
+
+uint8 amsSendWarning()
+{
+ //HAL_GPIO_WritePin(AMS_Warning_GPIO_Port, AMS_Warning_Pin, GPIO_PIN_SET);
+ return 0;
+}
+
+uint8 amsSendError()
+{
+ //HAL_GPIO_WritePin(AMS_Error_GPIO_Port, AMS_Error_Pin, GPIO_PIN_SET);
+ return 0;
+}
+
+uint8 amsClearWarning()
+{
+ //HAL_GPIO_WritePin(AMS_Warning_GPIO_Port, AMS_Warning_Pin, GPIO_PIN_RESET);
+ return 0;
+}
+
+uint8 amsClearError()
+{
+ //HAL_GPIO_WritePin(AMS_Error_GPIO_Port, AMS_Error_Pin, GPIO_PIN_RESET);
+ return 0;
+}
+
+uint8 amscheckOpenCellWire(Cell_Module *module)
+{
+ uint8 args;
+ uint16 cellspu[18];
+
+ writeCMD(ADOW |MD01|CH000|PUP , &args, 0); //run Pull Up at least Twice
+ HAL_Delay(5);
+ writeCMD(ADOW |MD01|CH000|PUP , &args, 0); //run Pull Up at least Twice
+ HAL_Delay(5);
+
+ amsReadCellVoltages(module);
+
+ for(uint8_t n = 0; n cellVoltages[n];
+ }
+
+
+ writeCMD(ADOW |MD01|CH000, &args, 0); //run Pull Up at least Twice
+ HAL_Delay(5);
+ writeCMD(ADOW |MD01|CH000, &args, 0); //run Pull Up at least Twice
+ HAL_Delay(5);
+
+ amsReadCellVoltages(module);
+
+ for(uint8 n = 1; n < numberofcells; n++)
+ {
+ int dv = cellspu[n]-module->cellVoltages[n];
+ if(dv < -4000)
+ {
+ return (1+n);
+ }
+ }
+ if((cellspu[0] == 0) || (cellspu[0] == 0xFFFF))
+ {
+ return 1;
+ }
+ if(module->cellVoltages[numberofcells-1] == 0)
+ {
+ return 19;
+ }
+
+ return 0;
+}
+
+uint8 amsReadCellVoltages(Cell_Module *module)
+{
+ uint8 rxbuffer[CV_GROUP_A_SIZE];
+ readCMD(RDCVA, rxbuffer, CV_GROUP_A_SIZE);
+ module->cellVoltages[0] = rxbuffer[0] | (rxbuffer[1]<<8);
+ module->cellVoltages[1] = rxbuffer[2] | (rxbuffer[3]<<8);
+ module->cellVoltages[2] = rxbuffer[4] | (rxbuffer[5]<<8);
+
+ readCMD(RDCVB, rxbuffer, CV_GROUP_A_SIZE);
+ module->cellVoltages[3] = rxbuffer[0] | (rxbuffer[1]<<8);
+ module->cellVoltages[4] = rxbuffer[2] | (rxbuffer[3]<<8);
+ module->cellVoltages[5] = rxbuffer[4] | (rxbuffer[5]<<8);
+
+ readCMD(RDCVC, rxbuffer, CV_GROUP_A_SIZE);
+ module->cellVoltages[6] = rxbuffer[0] | (rxbuffer[1]<<8);
+ module->cellVoltages[7] = rxbuffer[2] | (rxbuffer[3]<<8);
+ module->cellVoltages[8] = rxbuffer[4] | (rxbuffer[5]<<8);
+
+ readCMD(RDCVD, rxbuffer, CV_GROUP_A_SIZE);
+ module->cellVoltages[9] = rxbuffer[0] | (rxbuffer[1]<<8);
+ module->cellVoltages[10] = rxbuffer[2] | (rxbuffer[3]<<8);
+ module->cellVoltages[11] = rxbuffer[4] | (rxbuffer[5]<<8);
+
+ readCMD(RDCVE, rxbuffer, CV_GROUP_A_SIZE);
+ module->cellVoltages[12] = rxbuffer[0] | (rxbuffer[1]<<8);
+ module->cellVoltages[13] = rxbuffer[2] | (rxbuffer[3]<<8);
+ module->cellVoltages[14] = rxbuffer[4] | (rxbuffer[5]<<8);
+
+ readCMD(RDCVF, rxbuffer, CV_GROUP_A_SIZE);
+ module->cellVoltages[15] = rxbuffer[0] | (rxbuffer[1]<<8);
+ module->cellVoltages[16] = rxbuffer[2] | (rxbuffer[3]<<8);
+ module->cellVoltages[17] = rxbuffer[4] | (rxbuffer[5]<<8);
+
+ return 0;
+}
diff --git a/BMS_Testbench/BMS_Software_V1/Core/Src/ADBMS_LL_Driver.c b/BMS_Testbench/BMS_Software_V1/Core/Src/ADBMS_LL_Driver.c
new file mode 100644
index 0000000..0c0faeb
--- /dev/null
+++ b/BMS_Testbench/BMS_Software_V1/Core/Src/ADBMS_LL_Driver.c
@@ -0,0 +1,230 @@
+/*
+ * ADBMS_LL_Driver.c
+ *
+ * Created on: 05.06.2022
+ * Author: max
+ */
+#include "ADBMS_LL_Driver.h"
+
+
+#define INITAL_PEC 0x0010
+#define ADBMS_SPI_TIMEOUT 1000 //Timeout in ms
+
+SPI_HandleTypeDef* adbmsspi;
+
+uint8 adbmsDriverInit(SPI_HandleTypeDef* hspi)
+{
+ mcuAdbmsCSLow();
+ HAL_Delay(1);
+ mcuAdbmsCSHigh();
+ adbmsspi = hspi;
+ return 0;
+}
+
+uint8 calculatePEC(uint8_t* data, uint8_t datalen)
+{
+ uint16 currentpec = INITAL_PEC;
+ if(datalen >= 3)
+ {
+ for(int i = 0; i < (datalen-2); i++)
+ {
+ for(int n = 0; n < 8;n++)
+ {
+ uint8 din = data[i] << (n);
+ currentpec = updatePEC(currentpec, din);
+ }
+ }
+
+ data[datalen-2] = (currentpec>>7) & 0xFF;
+ data[datalen-1] = (currentpec<<1) & 0xFF;
+ return 0;
+ }
+
+ else
+ {
+ return 1;
+ }
+}
+
+uint8 checkPEC(uint8* data, uint8 datalen)
+{
+ if(datalen <= 3)
+ {
+ return 255;
+ }
+
+ uint16 currentpec = INITAL_PEC;
+
+ for(int i = 0; i < (datalen-2); i++)
+ {
+ for(int n = 0; n < 8;n++)
+ {
+ uint8 din = data[i] << (n);
+ currentpec = updatePEC(currentpec, din);
+ }
+ }
+
+ uint8 pechigh = (currentpec>>7) & 0xFF;
+ uint8 peclow = (currentpec<<1) & 0xFF;
+
+ if((pechigh == data[datalen-2]) && (peclow == data[datalen-1]))
+ {
+ return 0;
+ }
+
+ return 1;
+
+}
+
+uint16 updatePEC(uint16 currentPEC, uint8 din)
+{
+ din = (din>>7) & 0x01;
+ uint8 in0 = din ^ ((currentPEC >> 14) &0x01);
+ uint8 in3 = in0 ^ ((currentPEC >> 2) &0x01);
+ uint8 in4 = in0 ^ ((currentPEC >> 3) &0x01);
+ uint8 in7 = in0 ^ ((currentPEC >> 6) &0x01);
+ uint8 in8 = in0 ^ ((currentPEC >> 7) &0x01);
+ uint8 in10 = in0 ^ ((currentPEC >> 9) &0x01);
+ uint8 in14 = in0 ^ ((currentPEC >> 13) &0x01);
+
+ uint16 newPEC = 0;
+
+ newPEC |= in14<<14;
+ newPEC |= (currentPEC & (0x01<<12))<<1;
+ newPEC |= (currentPEC & (0x01<<11))<<1;
+ newPEC |= (currentPEC & (0x01<<10))<<1;
+ newPEC |= in10<<10;
+ newPEC |= (currentPEC & (0x01<<8))<<1;
+ newPEC |= in8<<8;
+ newPEC |= in7<<7;
+ newPEC |= (currentPEC & (0x01<<5))<<1;
+ newPEC |= (currentPEC & (0x01<<4))<<1;
+ newPEC |= in4<<4;
+ newPEC |= in3<<3;
+ newPEC |= (currentPEC & (0x01<<1))<<1;
+ newPEC |= (currentPEC & (0x01))<<1;
+ newPEC |= in0;
+
+
+ return newPEC;
+}
+
+uint8 writeCMD(uint16 command, uint8* args, uint8 arglen)
+{
+ if(arglen > 0)
+ {
+ uint8 buffer[6+arglen];
+ buffer[0] = (command >> 8) & 0xFF;
+ buffer[1] = (command) & 0xFF;
+ calculatePEC(buffer, 4);
+ for(uint8 i = 0; i < arglen; i++)
+ {
+ buffer[4+i] = args[i];
+ }
+
+ calculatePEC(&buffer[4], arglen+2); //Calculate PEC of Data Part with offset of 4 Bytes for CMD and CMD PEC
+
+ mcuAdbmsCSLow();
+ mcuSPITransmit(buffer, 6+arglen);
+ mcuAdbmsCSHigh();
+
+ }
+ else
+ {
+ uint8 buffer[4];
+ buffer[0] = (command >> 8) & 0xFF;
+ buffer[1] = (command) & 0xFF;
+ calculatePEC(buffer, 4);
+
+ mcuAdbmsCSLow();
+
+ mcuSPITransmit(buffer, 4);
+
+ mcuAdbmsCSHigh();
+ }
+
+ return 0;
+}
+
+uint8 readCMD(uint16 command, uint8* buffer, uint8 buflen)
+{
+ //uint8* txbuffer = (uint8*) malloc(6+buflen);
+ //uint8* rxbuffer = (uint8*) malloc(6+buflen);
+ uint8 txbuffer[6+buflen];
+ uint8 rxbuffer[6+buflen];
+
+ txbuffer[0] = (command >> 8) & 0xFF;
+ txbuffer[1] = (command) & 0xFF;
+ calculatePEC(txbuffer, 4);
+
+ mcuAdbmsCSLow();
+ mcuSPITransmitReceive(rxbuffer, txbuffer, 6+buflen);
+ mcuAdbmsCSHigh();
+
+
+ for(uint8 i = 0; i 100) {
+ Error_Handler();
+ } else {
+ return 1;
+ }
+ }
+
+}
+
+void mcuAdbmsCSLow()
+{
+ HAL_GPIO_WritePin(CSB_GPIO_Port, CSB_Pin, GPIO_PIN_RESET);
+}
+
+void mcuAdbmsCSHigh()
+{
+ HAL_GPIO_WritePin(CSB_GPIO_Port, CSB_Pin, GPIO_PIN_SET);
+}
+
+uint8 mcuSPITransmit(uint8* buffer, uint8 buffersize)
+{
+ HAL_StatusTypeDef status;
+ //status = HAL_SPI_Transmit(adbmsspi, buffer, buffersize, ADBMS_SPI_TIMEOUT);
+ //uint8 *rxbuf = (uint8*) malloc(buffersize);
+ uint8 rxbuf[buffersize];
+ status = HAL_SPI_TransmitReceive(adbmsspi, buffer, rxbuf, buffersize, ADBMS_SPI_TIMEOUT);
+ __HAL_SPI_CLEAR_OVRFLAG(adbmsspi);
+ //free(rxbuf);
+ return status;
+}
+
+uint8 mcuSPIReceive(uint8* buffer, uint8 buffersize)
+{
+ HAL_StatusTypeDef status;
+ status = HAL_SPI_Receive(adbmsspi, buffer, buffersize, ADBMS_SPI_TIMEOUT);
+ return status;
+}
+
+uint8 mcuSPITransmitReceive(uint8* rxbuffer, uint8* txbuffer, uint8 buffersize)
+{
+ HAL_StatusTypeDef status;
+ status = HAL_SPI_TransmitReceive(adbmsspi, txbuffer, rxbuffer, buffersize, ADBMS_SPI_TIMEOUT);
+ return status;
+}
+
+inline void mcuDelay(uint16 delay)
+{
+ HAL_Delay(delay);
+}
+
+
diff --git a/BMS_Testbench/BMS_Software_V1/Core/Src/AMS_CAN.c b/BMS_Testbench/BMS_Software_V1/Core/Src/AMS_CAN.c
new file mode 100644
index 0000000..0fa145c
--- /dev/null
+++ b/BMS_Testbench/BMS_Software_V1/Core/Src/AMS_CAN.c
@@ -0,0 +1,193 @@
+/*
+ * AMS_CAN.c
+ *
+ * Created on: Mar 19, 2022
+ * Author: jasper
+ */
+
+#include "AMS_CAN.h"
+
+#include "ADBMS_Abstraction.h"
+
+
+#include "common_defs.h"
+#include "main.h"
+#include "AMS_HighLevel.h"
+#include "stm32f3xx.h"
+#include "stm32f3xx_hal.h"
+#include "stm32f3xx_hal_can.h"
+
+#include
+
+int PENDING_MESSAGE_HANDLE = 0;
+uint8_t canTestData[8] = {0,0,0,0,0,0,0,0};
+
+
+CAN_HandleTypeDef* ams_can_handle;
+
+void ams_can_init(CAN_HandleTypeDef* ams_handle,
+ CAN_HandleTypeDef* car_handle) {
+ ams_can_handle = ams_handle;
+
+ // Start peripheral
+ if (HAL_CAN_Start(ams_can_handle) != HAL_OK) {
+ ams_can_handle = car_handle;
+ if (HAL_CAN_Start(ams_can_handle) != HAL_OK) {
+ Error_Handler();
+ }
+ }
+
+ // Config filter
+ CAN_FilterTypeDef can_filter;
+ can_filter.FilterActivation = CAN_FILTER_ENABLE;
+ can_filter.FilterBank = 0;
+ can_filter.FilterFIFOAssignment = CAN_FILTER_FIFO0;
+ /* Message ID is in the MSBs of the FilterId register */
+ can_filter.FilterIdHigh = CAN_ID_CLOCK_SYNC << (16 - 11);
+ can_filter.FilterIdLow = 0;
+ /* Filter the 11 MSBs (i.e. a StdId) */
+
+ if(BMS_IN_TEST_MODE == 1){
+ can_filter.FilterMaskIdHigh = BMS_TEST_ID; // alleNachrichtenIds werden akzeptiert
+ }else{
+ can_filter.FilterMaskIdHigh = 0xFFE0;
+ }
+
+ can_filter.FilterMaskIdLow = 0;
+ can_filter.FilterMode = CAN_FILTERMODE_IDMASK;
+ can_filter.FilterScale = CAN_FILTERSCALE_32BIT;
+ can_filter.SlaveStartFilterBank = 0;
+ if (HAL_CAN_ConfigFilter(ams_can_handle, &can_filter) != HAL_OK) {
+ Error_Handler();
+ }
+ can_filter.FilterBank++;
+ can_filter.FilterIdHigh = CAN_ID_MASTER_HEARTBEAT << (16 - 11);
+ can_filter.FilterIdLow = 0;
+ if (HAL_CAN_ConfigFilter(ams_can_handle, &can_filter) != HAL_OK) {
+ Error_Handler();
+ }
+
+ // Activate RX notifications
+ if (HAL_CAN_ActivateNotification(ams_can_handle,
+ CAN_IT_RX_FIFO0_MSG_PENDING) != HAL_OK) {
+ Error_Handler();
+ }
+}
+
+static int cb_triggered = 0;
+
+void HAL_CAN_RxFifo0MsgPendingCallback(CAN_HandleTypeDef* handle) {
+ static CAN_RxHeaderTypeDef header;
+ static uint8_t data[8];
+ cb_triggered = 1;
+
+ if (HAL_CAN_GetRxMessage(handle, CAN_RX_FIFO0, &header, data) != HAL_OK) {
+ Error_Handler();
+ }
+
+ if (handle == ams_can_handle) {
+ ams_can_handle_ams_msg(&header, data);
+ } else {
+ Error_Handler();
+ }
+}
+
+void ams_can_handle_ams_msg(CAN_RxHeaderTypeDef* header, uint8_t* data) {
+
+ if(BMS_IN_TEST_MODE == 1){
+ PENDING_MESSAGE_HANDLE = 1;
+ for(int i = 0; i < 8; i++){
+ canTestData[i] = data[i];
+ }
+ return;
+ }
+
+
+ if (header->IDE != CAN_ID_STD) {
+ return;
+ }
+
+ switch (header->StdId) {
+ case CAN_ID_CLOCK_SYNC:
+// clock_sync_handle_clock_sync_frame(data[0]);
+ break;
+ case CAN_ID_MASTER_HEARTBEAT:
+// clock_sync_handle_master_heartbeat();
+ break;
+ }
+}
+
+void ams_can_send_heartbeat() {
+ static CAN_TxHeaderTypeDef header;
+ static uint8_t data[8];
+
+ header.IDE = CAN_ID_STD;
+ header.DLC = 8;
+ header.RTR = CAN_RTR_DATA;
+ header.TransmitGlobalTime = DISABLE;
+
+ // Send voltages
+ for (int msg_id = 0; msg_id < 5; msg_id++) {
+ header.StdId = CAN_ID_AMS_SLAVE_HEARTBEAT_BASE | (0 << 4) | msg_id; //TODO: Use slave_id/new format
+ for (int i = 0; i < 4; i++) {
+ int cell = msg_id * 4 + i;
+ uint16_t v = (cell < N_CELLS) ? module.cellVoltages[cell] : 0;
+ data[2 * i + 0] = v & 0xFF;
+ data[2 * i + 1] = v >> 8;
+ }
+ if (ams_can_wait_for_free_mailboxes(ams_can_handle, 1,
+ CAN_HEARTBEAT_TX_TIMEOUT) == HAL_OK) {
+ uint32_t mailbox;
+ HAL_CAN_AddTxMessage(ams_can_handle, &header, data, &mailbox);
+ }
+ }
+
+ // Send temperatures
+ /*for (int temp_msg_id = 0; temp_msg_id < 8; temp_msg_id++) {
+ int msg_id = temp_msg_id + 3;
+ header.StdId = CAN_ID_AMS_SLAVE_HEARTBEAT_BASE | (slave_id << 4) | msg_id;
+ for (int i = 0; i < 4; i++) {
+ int sensor = temp_msg_id * 4 + i;
+ uint16_t temp = temperatures[sensor];
+ data[2 * i + 0] = temp & 0xFF;
+ data[2 * i + 1] = temp >> 8;
+ }
+ if (ams_can_wait_for_free_mailboxes(ams_can_handle, 1,
+ CAN_HEARTBEAT_TX_TIMEOUT) == HAL_OK) {
+ uint32_t mailbox;
+ HAL_CAN_AddTxMessage(ams_can_handle, &header, data, &mailbox);
+ }
+ }*/
+}
+
+/*void ams_can_send_error(AMS_ErrorCode error_code,
+ uint32_t transmission_timeout) {
+ static CAN_TxHeaderTypeDef header;
+ header.IDE = CAN_ID_STD;
+ header.DLC = 8;
+ header.RTR = CAN_RTR_DATA;
+ header.TransmitGlobalTime = DISABLE;
+ header.StdId = CAN_ID_SLAVE_ERROR;
+
+ static uint8_t data[8];
+ data[0] = slave_id;
+ data[1] = error_code;
+
+ HAL_CAN_AbortTxRequest(ams_can_handle,
+ CAN_TX_MAILBOX0 | CAN_TX_MAILBOX1 | CAN_TX_MAILBOX2);
+ uint32_t mailbox;
+ HAL_CAN_AddTxMessage(ams_can_handle, &header, data, &mailbox);
+ ams_can_wait_for_free_mailboxes(ams_can_handle, 3, transmission_timeout);
+}*/
+
+HAL_StatusTypeDef ams_can_wait_for_free_mailboxes(CAN_HandleTypeDef* handle,
+ int num_mailboxes,
+ uint32_t timeout) {
+ uint32_t end = HAL_GetTick() + timeout;
+ while (HAL_GetTick() < end) {
+ if (HAL_CAN_GetTxMailboxesFreeLevel(handle) >= num_mailboxes) {
+ return HAL_OK;
+ }
+ }
+ return HAL_TIMEOUT;
+}
diff --git a/BMS_Testbench/BMS_Software_V1/Core/Src/AMS_HighLevel.c b/BMS_Testbench/BMS_Software_V1/Core/Src/AMS_HighLevel.c
new file mode 100644
index 0000000..a1aa56e
--- /dev/null
+++ b/BMS_Testbench/BMS_Software_V1/Core/Src/AMS_HighLevel.c
@@ -0,0 +1,304 @@
+/*
+ * AMS_HighLevel.c
+ *
+ * Created on: 20.07.2022
+ * Author: max
+ */
+
+
+#include "AMS_HighLevel.h"
+
+Cell_Module module;
+uint32_t balancedCells = 0;
+uint8_t BalancingActive = 0;
+uint8_t stateofcharge = 100;
+int64_t currentintegrator = 0;
+uint32_t lastticks = 0;
+uint32_t currenttick = 0;
+uint8_t eepromconfigured = 0;
+
+uint8_t internalbalancingalgo = 1;
+uint16_t startbalancingthreshold = 41000;
+uint16_t stopbalancingthreshold = 30000;
+uint16_t balancingvoltagedelta = 10;
+
+
+uint16_t amsuv = 0;
+uint16_t amsov = 0;
+
+uint8_t amserrorcode = 0;
+uint8_t amswarningcode = 0;
+
+uint8_t numberofCells = 17;
+uint8_t numberofAux = 0;
+
+
+amsState currentAMSState = AMSDEACTIVE;
+amsState lastAMSState = AMSDEACTIVE;
+
+void AMS_Init(SPI_HandleTypeDef *hspi)
+{
+ if(eepromconfigured == 1)
+ {
+ /*amsov = eepromcellovervoltage>>4;
+ amsuv = (eepromcellundervoltage-1)>>4;
+ numberofCells = eepromnumofcells;
+ numberofAux = eepromnumofaux;
+ initAMS(hspi, eepromnumofcells, eepromnumofaux);*/
+ amsConfigOverVoltage(amsov);
+ amsConfigUnderVoltage(amsuv);
+ }
+ else
+ {
+ initAMS(hspi, numberofCells, numberofAux);
+ amsov = DEFAULT_OV;
+ amsuv = DEFAULT_UV;
+ }
+
+
+ currentAMSState = AMSIDLE;
+
+
+}
+
+void AMS_Loop()
+{
+
+ //On Transition Functions called ones if the State Changed
+
+ if(currentAMSState != lastAMSState)
+ {
+ switch(currentAMSState)
+ {
+ case AMSIDLE:
+ break;
+ case AMSDEACTIVE:
+ break;
+ case AMSCHARGING:
+ break;
+ case AMSIDLEBALANCING:
+ break;
+ case AMSDISCHARGING:
+ break;
+ case AMSWARNING:
+ writeWarningLog(0x01);
+ break;
+ case AMSERROR:
+ writeErrorLog(amserrorcode);
+ break;
+ }
+ lastAMSState = currentAMSState;
+ }
+
+ //Main Loops for different AMS States
+
+ switch(currentAMSState)
+ {
+ case AMSIDLE:
+ AMS_Idle_Loop();
+ break;
+ case AMSDEACTIVE:
+ break;
+ case AMSCHARGING:
+ break;
+ case AMSIDLEBALANCING:
+ AMS_Idle_Loop();
+ break;
+ case AMSDISCHARGING:
+ break;
+ case AMSWARNING:
+ AMS_Warning_Loop();
+ break;
+ case AMSERROR:
+ break;
+ }
+}
+
+uint8_t AMS_Idle_Loop()
+{
+ amsWakeUp();
+ amsConfigOverVoltage(amsov);
+ amsConfigUnderVoltage(amsuv);
+ amsConfigAuxMeasurement(0xFFFF);
+ amsClearAux();
+ amsCellMeasurement(&module);
+ amsInternalStatusMeasurement(&module);
+ amsAuxMeasurement(&module);
+ amsCheckUnderOverVoltage(&module);
+ integrateCurrent();
+
+ static uint32_t channelstobalance = 1;
+
+ channelstobalance = 0x1FFFF;
+ /* if(channelstobalance & 0x20000){
+ channelstobalance = 1;
+ }*/
+
+ amsConfigBalancing(channelstobalance);
+ amsStartBalancing(100);
+
+ if((module.overVoltage | module.underVoltage))
+ {
+ //amsSendWarning();
+ // currentAMSState = AMSWARNING;
+ }
+
+ // AMS_Balancing_Loop();
+
+ /* if(BalancingActive)
+ {
+ amsStartBalancing(100);
+ }
+ else
+ {
+ amsStopBalancing();
+ }*/
+ //amsConfigBalancing(balancedCells);
+ //volatile amscheck = amscheckOpenCellWire(&module);
+ return 0;
+}
+
+uint8_t AMS_Warning_Loop()
+{
+
+ amsWakeUp();
+ amsConfigOverVoltage(amsov);
+ amsConfigUnderVoltage(amsuv);
+ amsConfigAuxMeasurement(0xFFFF);
+ amsClearAux();
+ amsCellMeasurement(&module);
+ amsInternalStatusMeasurement(&module);
+ amsAuxMeasurement(&module);
+ amsCheckUnderOverVoltage(&module);
+
+ if(!(module.overVoltage | module.underVoltage))
+ {
+ currentAMSState = AMSIDLE;
+ amsClearWarning();
+ }
+ amsStopBalancing();
+
+ return 0;
+}
+
+uint8_t AMS_Error_Loop()
+{
+ return 0;
+}
+
+uint8_t AMS_Charging_Loop()
+{
+ return 0;
+}
+
+uint8_t AMS_Discharging_Loop()
+{
+ return 0;
+}
+
+uint8_t AMS_Balancing_Loop()
+{
+ uint8_t balancingdone = 1;
+ if((eepromconfigured == 1) && (internalbalancingalgo == 1) && (module.internalDieTemp<28000/*Thermal Protection 93°C*/)) //If the EEPROM is configured and the internal Balancing Algorithm should be used
+ {
+ uint16_t highestcellvoltage = module.cellVoltages[0];
+ uint16_t lowestcellvoltage = module.cellVoltages[0];
+ uint8_t highestcell = 0;
+ uint8_t lowestcell = 0;
+
+ for(uint8_t n = 0; n < numberofCells; n++)
+ {
+ if(module.cellVoltages[n] > highestcellvoltage)
+ {
+ highestcellvoltage = module.cellVoltages[n];
+ highestcell = n;
+ }
+ if(module.cellVoltages[n] < lowestcellvoltage)
+ {
+ lowestcellvoltage = module.cellVoltages[n];
+ lowestcell = n;
+ }
+ }
+
+ if(currentAMSState == AMSCHARGING) //Balancing is only Active if the BMS is in Charging Mode
+ {
+
+ uint32_t channelstobalance = 0;
+
+ if(highestcellvoltage > startbalancingthreshold)
+ {
+ for(uint8_t n = 0; n < numberofCells; n++)
+ {
+ if(module.cellVoltages[n] > stopbalancingthreshold)
+ {
+ uint16_t dv = module.cellVoltages[n]-lowestcellvoltage;
+ if(dv > (balancingvoltagedelta*1000))
+ {
+ balancingdone = 0;
+ channelstobalance |= 1< balancingvoltagedelta)
+ {
+ balancingdone = 0;
+ channelstobalance |= 1<
+#include "ADBMS_Abstraction.h"
+#include "main.h"
+
+
+void canTestSendTemperatures(uint16_t* data){
+ static CAN_TxHeaderTypeDef header;
+
+ header.IDE = CAN_ID_STD;
+ header.DLC = 8;
+ header.RTR = CAN_RTR_DATA;
+ header.TransmitGlobalTime = DISABLE;
+ uint8_t buffer[24];
+ uint8_t tmp[8];
+
+ for(int i = 0; i < 12; i++){
+ buffer[((i*2)+1)] = data[i] >> 8;
+ buffer[(i*2)] = data[i];
+ }
+
+ for(int i = 0; i < 8; i++){
+ tmp[i] = buffer[i];
+ }
+ if (ams_can_wait_for_free_mailboxes(ams_can_handle, 1, CAN_HEARTBEAT_TX_TIMEOUT) == HAL_OK) {
+ uint32_t mailbox;
+ HAL_CAN_AddTxMessage(ams_can_handle, &header, tmp, &mailbox);
+ }
+
+ int m = 0;
+ for(int i = 8; i < 16; i++){
+ tmp[m] = buffer[i];
+ m++;
+ }
+
+ if (ams_can_wait_for_free_mailboxes(ams_can_handle, 1, CAN_HEARTBEAT_TX_TIMEOUT) == HAL_OK) {
+ uint32_t mailbox;
+ HAL_CAN_AddTxMessage(ams_can_handle, &header, tmp, &mailbox);
+ }
+ m = 0;
+ for(int i = 16; i < 24; i++){
+ tmp[m] = buffer[i];
+ m++;
+ }
+
+ if (ams_can_wait_for_free_mailboxes(ams_can_handle, 1, CAN_HEARTBEAT_TX_TIMEOUT) == HAL_OK) {
+ uint32_t mailbox;
+ HAL_CAN_AddTxMessage(ams_can_handle, &header, tmp, &mailbox);
+ }
+}
+
+void canTestSendAnswer(uint8_t* data){
+ static CAN_TxHeaderTypeDef header;
+
+ header.IDE = CAN_ID_STD;
+ header.DLC = 8;
+ header.RTR = CAN_RTR_DATA;
+ header.TransmitGlobalTime = DISABLE;
+
+ if (ams_can_wait_for_free_mailboxes(ams_can_handle, 1,
+ CAN_HEARTBEAT_TX_TIMEOUT) == HAL_OK) {
+ uint32_t mailbox;
+ HAL_CAN_AddTxMessage(ams_can_handle, &header, data, &mailbox);
+ }
+}
+
+void resetData(uint8_t* data){
+ for(int i = 0; i < 8; i++){
+ data[0] = 0;
+ }
+
+}
+void readTemperatures(){
+ uint8_t last_error = 0;
+ int N_SENSORS = 12;
+ uint16_t temperatures[N_SENSORS];
+ for (int i = 0; i < N_SENSORS; i++) {
+ if (sensor_read(i, &temperatures[i]) != HAL_OK) {
+ sensor_init(i);
+ last_error = HAL_GetTick();
+ }
+ }
+ canTestSendTemperatures(temperatures);
+}
+
+void testLoop(uint8_t* data){
+ uint8_t action = data[0];
+ switch(action){
+ case CAN_TEST:
+ HAL_Delay(100);
+ canTestSendAnswer(data);
+ break;
+ case VOLTAGE_TEST:
+ HAL_Delay(100);
+ amsReadCellVoltages(&module);
+ ams_can_send_heartbeat();
+ break;
+ case TEMP_TEST:
+ HAL_Delay(1000);
+ readTemperatures();
+ break;
+ case EPROM_TEST:
+ HAL_Delay(1000);
+ for(uint16_t i = 1; i < 9; i++ ){
+ if(i == 4){
+ writeeeprom(i*3, 0x42);
+ }else{
+ writeeeprom(i*3, 0x69);
+ }
+ }
+
+ HAL_Delay(1000);
+ for(uint16_t i = 1; i < 9; i++ ){
+ data[i-1] = readeeprom(i*3);
+ }
+ canTestSendAnswer(data);
+ break;
+ case BALANCING_TEST:
+ HAL_Delay(1000);
+ for(int i = 0; i < 17; i++){
+ amsConfigBalancing(0x00001<CCR1 = 0x01FF;
+// HAL_TIM_Base_Start(&htim2);
+ /* USER CODE END 2 */
+
+ /* Infinite loop */
+ /* USER CODE BEGIN WHILE */
+ writeeeprom(1, 69);
+ uint16_t temperatures[N_SENSORS];
+ AMS_Loop();
+ while (1){
+ if(BMS_IN_TEST_MODE == 1 ){ ////&& PENDING_MESSAGE_HANDLE == 1
+ testLoop(&canTestData);
+ /* USER CODE END WHILE */
+ /* USER CODE BEGIN 3 */
+
+ for (int i = 0; i < N_SENSORS; i++) {
+ if (sensor_read(i, &temperatures[i]) != HAL_OK) {
+ sensor_init(i);
+ last_error = HAL_GetTick();
+ }
+ }
+ if(BMS_IN_TEST_MODE != 1){
+ ams_can_send_heartbeat(); //for testing
+ }
+ }
+ }
+
+ /* USER CODE END 3 */
+}
+
+/**
+ * @brief System Clock Configuration
+ * @retval None
+ */
+void SystemClock_Config(void)
+{
+ RCC_OscInitTypeDef RCC_OscInitStruct = {0};
+ RCC_ClkInitTypeDef RCC_ClkInitStruct = {0};
+ RCC_PeriphCLKInitTypeDef PeriphClkInit = {0};
+
+ /** Initializes the RCC Oscillators according to the specified parameters
+ * in the RCC_OscInitTypeDef structure.
+ */
+ RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSI|RCC_OSCILLATORTYPE_HSE;
+ RCC_OscInitStruct.HSEState = RCC_HSE_ON;
+ RCC_OscInitStruct.HSIState = RCC_HSI_ON;
+ RCC_OscInitStruct.HSICalibrationValue = RCC_HSICALIBRATION_DEFAULT;
+ RCC_OscInitStruct.PLL.PLLState = RCC_PLL_NONE;
+ if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK)
+ {
+ Error_Handler();
+ }
+
+ /** Initializes the CPU, AHB and APB buses clocks
+ */
+ RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK|RCC_CLOCKTYPE_SYSCLK
+ |RCC_CLOCKTYPE_PCLK1|RCC_CLOCKTYPE_PCLK2;
+ RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_HSE;
+ RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;
+ RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV1;
+ RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1;
+
+ if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_0) != HAL_OK)
+ {
+ Error_Handler();
+ }
+ PeriphClkInit.PeriphClockSelection = RCC_PERIPHCLK_I2C1|RCC_PERIPHCLK_I2C2;
+ PeriphClkInit.I2c1ClockSelection = RCC_I2C1CLKSOURCE_HSI;
+ PeriphClkInit.I2c2ClockSelection = RCC_I2C2CLKSOURCE_HSI;
+ if (HAL_RCCEx_PeriphCLKConfig(&PeriphClkInit) != HAL_OK)
+ {
+ Error_Handler();
+ }
+}
+
+/**
+ * @brief CAN Initialization Function
+ * @param None
+ * @retval None
+ */
+static void MX_CAN_Init(void)
+{
+
+ /* USER CODE BEGIN CAN_Init 0 */
+
+ /* USER CODE END CAN_Init 0 */
+
+ /* USER CODE BEGIN CAN_Init 1 */
+
+ /* USER CODE END CAN_Init 1 */
+ hcan.Instance = CAN;
+ hcan.Init.Prescaler = 2;
+ hcan.Init.Mode = CAN_MODE_NORMAL;
+ hcan.Init.SyncJumpWidth = CAN_SJW_1TQ;
+ hcan.Init.TimeSeg1 = CAN_BS1_13TQ;
+ hcan.Init.TimeSeg2 = CAN_BS2_2TQ;
+ hcan.Init.TimeTriggeredMode = DISABLE;
+ hcan.Init.AutoBusOff = ENABLE;
+ hcan.Init.AutoWakeUp = DISABLE;
+ hcan.Init.AutoRetransmission = ENABLE;
+ hcan.Init.ReceiveFifoLocked = DISABLE;
+ hcan.Init.TransmitFifoPriority = DISABLE;
+ if (HAL_CAN_Init(&hcan) != HAL_OK)
+ {
+ Error_Handler();
+ }
+ /* USER CODE BEGIN CAN_Init 2 */
+
+ /* USER CODE END CAN_Init 2 */
+
+}
+
+/**
+ * @brief I2C1 Initialization Function
+ * @param None
+ * @retval None
+ */
+static void MX_I2C1_Init(void)
+{
+
+ /* USER CODE BEGIN I2C1_Init 0 */
+
+ /* USER CODE END I2C1_Init 0 */
+
+ /* USER CODE BEGIN I2C1_Init 1 */
+
+ /* USER CODE END I2C1_Init 1 */
+ hi2c1.Instance = I2C1;
+ hi2c1.Init.Timing = 0x2000090E;
+ hi2c1.Init.OwnAddress1 = 0;
+ hi2c1.Init.AddressingMode = I2C_ADDRESSINGMODE_7BIT;
+ hi2c1.Init.DualAddressMode = I2C_DUALADDRESS_DISABLE;
+ hi2c1.Init.OwnAddress2 = 0;
+ hi2c1.Init.OwnAddress2Masks = I2C_OA2_NOMASK;
+ hi2c1.Init.GeneralCallMode = I2C_GENERALCALL_DISABLE;
+ hi2c1.Init.NoStretchMode = I2C_NOSTRETCH_DISABLE;
+ if (HAL_I2C_Init(&hi2c1) != HAL_OK)
+ {
+ Error_Handler();
+ }
+
+ /** Configure Analogue filter
+ */
+ if (HAL_I2CEx_ConfigAnalogFilter(&hi2c1, I2C_ANALOGFILTER_ENABLE) != HAL_OK)
+ {
+ Error_Handler();
+ }
+
+ /** Configure Digital filter
+ */
+ if (HAL_I2CEx_ConfigDigitalFilter(&hi2c1, 0) != HAL_OK)
+ {
+ Error_Handler();
+ }
+ /* USER CODE BEGIN I2C1_Init 2 */
+
+ /* USER CODE END I2C1_Init 2 */
+
+}
+
+/**
+ * @brief I2C2 Initialization Function
+ * @param None
+ * @retval None
+ */
+static void MX_I2C2_Init(void)
+{
+
+ /* USER CODE BEGIN I2C2_Init 0 */
+
+ /* USER CODE END I2C2_Init 0 */
+
+ /* USER CODE BEGIN I2C2_Init 1 */
+
+ /* USER CODE END I2C2_Init 1 */
+ hi2c2.Instance = I2C2;
+ hi2c2.Init.Timing = 0x2000090E;
+ hi2c2.Init.OwnAddress1 = 0;
+ hi2c2.Init.AddressingMode = I2C_ADDRESSINGMODE_7BIT;
+ hi2c2.Init.DualAddressMode = I2C_DUALADDRESS_DISABLE;
+ hi2c2.Init.OwnAddress2 = 0;
+ hi2c2.Init.OwnAddress2Masks = I2C_OA2_NOMASK;
+ hi2c2.Init.GeneralCallMode = I2C_GENERALCALL_DISABLE;
+ hi2c2.Init.NoStretchMode = I2C_NOSTRETCH_DISABLE;
+ if (HAL_I2C_Init(&hi2c2) != HAL_OK)
+ {
+ Error_Handler();
+ }
+
+ /** Configure Analogue filter
+ */
+ if (HAL_I2CEx_ConfigAnalogFilter(&hi2c2, I2C_ANALOGFILTER_ENABLE) != HAL_OK)
+ {
+ Error_Handler();
+ }
+
+ /** Configure Digital filter
+ */
+ if (HAL_I2CEx_ConfigDigitalFilter(&hi2c2, 0) != HAL_OK)
+ {
+ Error_Handler();
+ }
+ /* USER CODE BEGIN I2C2_Init 2 */
+
+ /* USER CODE END I2C2_Init 2 */
+
+}
+
+/**
+ * @brief SPI1 Initialization Function
+ * @param None
+ * @retval None
+ */
+static void MX_SPI1_Init(void)
+{
+
+ /* USER CODE BEGIN SPI1_Init 0 */
+
+ /* USER CODE END SPI1_Init 0 */
+
+ /* USER CODE BEGIN SPI1_Init 1 */
+
+ /* USER CODE END SPI1_Init 1 */
+ /* SPI1 parameter configuration*/
+ hspi1.Instance = SPI1;
+ hspi1.Init.Mode = SPI_MODE_MASTER;
+ hspi1.Init.Direction = SPI_DIRECTION_2LINES;
+ hspi1.Init.DataSize = SPI_DATASIZE_8BIT;
+ hspi1.Init.CLKPolarity = SPI_POLARITY_LOW;
+ hspi1.Init.CLKPhase = SPI_PHASE_1EDGE;
+ hspi1.Init.NSS = SPI_NSS_SOFT;
+ hspi1.Init.BaudRatePrescaler = SPI_BAUDRATEPRESCALER_32;
+ hspi1.Init.FirstBit = SPI_FIRSTBIT_MSB;
+ hspi1.Init.TIMode = SPI_TIMODE_DISABLE;
+ hspi1.Init.CRCCalculation = SPI_CRCCALCULATION_DISABLE;
+ hspi1.Init.CRCPolynomial = 7;
+ hspi1.Init.CRCLength = SPI_CRC_LENGTH_DATASIZE;
+ hspi1.Init.NSSPMode = SPI_NSS_PULSE_ENABLE;
+ if (HAL_SPI_Init(&hspi1) != HAL_OK)
+ {
+ Error_Handler();
+ }
+ /* USER CODE BEGIN SPI1_Init 2 */
+
+ /* USER CODE END SPI1_Init 2 */
+
+}
+
+/**
+ * @brief GPIO Initialization Function
+ * @param None
+ * @retval None
+ */
+static void MX_GPIO_Init(void)
+{
+ GPIO_InitTypeDef GPIO_InitStruct = {0};
+
+ /* GPIO Ports Clock Enable */
+ __HAL_RCC_GPIOF_CLK_ENABLE();
+ __HAL_RCC_GPIOA_CLK_ENABLE();
+ __HAL_RCC_GPIOB_CLK_ENABLE();
+
+ /*Configure GPIO pin Output Level */
+ HAL_GPIO_WritePin(GPIOA, CSB_Pin|Status_3_Pin, GPIO_PIN_RESET);
+
+ /*Configure GPIO pin Output Level */
+ HAL_GPIO_WritePin(GPIOB, Status_0_Pin|Status_1_Pin|Status_2_Pin, GPIO_PIN_RESET);
+
+ /*Configure GPIO pins : CSB_Pin Status_3_Pin */
+ GPIO_InitStruct.Pin = CSB_Pin|Status_3_Pin;
+ GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
+ GPIO_InitStruct.Pull = GPIO_NOPULL;
+ GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
+ HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
+
+ /*Configure GPIO pins : Status_0_Pin Status_1_Pin Status_2_Pin */
+ GPIO_InitStruct.Pin = Status_0_Pin|Status_1_Pin|Status_2_Pin;
+ GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
+ GPIO_InitStruct.Pull = GPIO_NOPULL;
+ GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
+ HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);
+
+}
+
+/* USER CODE BEGIN 4 */
+HAL_StatusTypeDef sensor_init(int n) {
+ uint16_t addr = (0b1000000 | n) << 1;
+ uint8_t data[] = {0};
+ return HAL_I2C_Master_Transmit(&hi2c1, addr, data, sizeof(data), 100);
+}
+
+HAL_StatusTypeDef sensor_read(int n, uint16_t *res) {
+ uint16_t addr = (0b1000000 | n) << 1;
+ addr |= 1; // Read
+ uint8_t result[2];
+ HAL_StatusTypeDef status =
+ HAL_I2C_Master_Receive(&hi2c1, addr, result, sizeof(result), 100);
+ if (status == HAL_OK) {
+ *res = (result[0] << 8) | result[1];
+ }
+ return status;
+}
+
+uint8_t readeeprom(uint16_t address){
+ uint8_t data = 0;
+ //uint8_t* address2 = (uint8_t*) &address;
+ //HAL_I2C_Master_Transmit(&hi2c2, 0xA0, address2, 2, 1000);
+ //HAL_I2C_Master_Receive(&hi2c2, 0xA0, &data, 1, 1000);
+ HAL_I2C_Mem_Read(&hi2c2, 0xA0, address, 2, &data, 1 , 1000);
+ //HAL_I2C_Mem_Read(I2C_HandleTypeDef *hi2c, uint16_t DevAddress, uint16_t MemAddress,
+ // uint16_t MemAddSize, uint8_t *pData, uint16_t Size, uint32_t Timeout)
+ return data;
+}
+
+void writeeeprom(uint16_t address, uint8_t data){
+ HAL_I2C_Mem_Write(&hi2c2, 0xA0, address, 2, &data, 1, 1000);
+ HAL_Delay(5);
+}
+/* USER CODE END 4 */
+
+/**
+ * @brief This function is executed in case of error occurrence.
+ * @retval None
+ */
+void Error_Handler(void)
+{
+ /* USER CODE BEGIN Error_Handler_Debug */
+ /* User can add his own implementation to report the HAL error return state */
+ __disable_irq();
+ while (1)
+ {
+ }
+ /* USER CODE END Error_Handler_Debug */
+}
+
+#ifdef USE_FULL_ASSERT
+/**
+ * @brief Reports the name of the source file and the source line number
+ * where the assert_param error has occurred.
+ * @param file: pointer to the source file name
+ * @param line: assert_param error line source number
+ * @retval None
+ */
+void assert_failed(uint8_t *file, uint32_t line)
+{
+ /* USER CODE BEGIN 6 */
+ /* User can add his own implementation to report the file name and line number,
+ ex: printf("Wrong parameters value: file %s on line %d\r\n", file, line) */
+ /* USER CODE END 6 */
+}
+#endif /* USE_FULL_ASSERT */
diff --git a/BMS_Testbench/BMS_Software_V1/Core/Src/stm32f3xx_hal_msp.c b/BMS_Testbench/BMS_Software_V1/Core/Src/stm32f3xx_hal_msp.c
new file mode 100644
index 0000000..d1d6933
--- /dev/null
+++ b/BMS_Testbench/BMS_Software_V1/Core/Src/stm32f3xx_hal_msp.c
@@ -0,0 +1,337 @@
+/* USER CODE BEGIN Header */
+/**
+ ******************************************************************************
+ * @file stm32f3xx_hal_msp.c
+ * @brief This file provides code for the MSP Initialization
+ * and de-Initialization codes.
+ ******************************************************************************
+ * @attention
+ *
+ * Copyright (c) 2023 STMicroelectronics.
+ * All rights reserved.
+ *
+ * This software is licensed under terms that can be found in the LICENSE file
+ * in the root directory of this software component.
+ * If no LICENSE file comes with this software, it is provided AS-IS.
+ *
+ ******************************************************************************
+ */
+/* USER CODE END Header */
+
+/* Includes ------------------------------------------------------------------*/
+#include "main.h"
+/* USER CODE BEGIN Includes */
+
+/* USER CODE END Includes */
+
+/* Private typedef -----------------------------------------------------------*/
+/* USER CODE BEGIN TD */
+
+/* USER CODE END TD */
+
+/* Private define ------------------------------------------------------------*/
+/* USER CODE BEGIN Define */
+
+/* USER CODE END Define */
+
+/* Private macro -------------------------------------------------------------*/
+/* USER CODE BEGIN Macro */
+
+/* USER CODE END Macro */
+
+/* Private variables ---------------------------------------------------------*/
+/* USER CODE BEGIN PV */
+
+/* USER CODE END PV */
+
+/* Private function prototypes -----------------------------------------------*/
+/* USER CODE BEGIN PFP */
+
+/* USER CODE END PFP */
+
+/* External functions --------------------------------------------------------*/
+/* USER CODE BEGIN ExternalFunctions */
+
+/* USER CODE END ExternalFunctions */
+
+/* USER CODE BEGIN 0 */
+
+/* USER CODE END 0 */
+/**
+ * Initializes the Global MSP.
+ */
+void HAL_MspInit(void)
+{
+ /* USER CODE BEGIN MspInit 0 */
+
+ /* USER CODE END MspInit 0 */
+
+ __HAL_RCC_SYSCFG_CLK_ENABLE();
+ __HAL_RCC_PWR_CLK_ENABLE();
+
+ /* System interrupt init*/
+
+ /* USER CODE BEGIN MspInit 1 */
+
+ /* USER CODE END MspInit 1 */
+}
+
+/**
+* @brief CAN MSP Initialization
+* This function configures the hardware resources used in this example
+* @param hcan: CAN handle pointer
+* @retval None
+*/
+void HAL_CAN_MspInit(CAN_HandleTypeDef* hcan)
+{
+ GPIO_InitTypeDef GPIO_InitStruct = {0};
+ if(hcan->Instance==CAN)
+ {
+ /* USER CODE BEGIN CAN_MspInit 0 */
+
+ /* USER CODE END CAN_MspInit 0 */
+ /* Peripheral clock enable */
+ __HAL_RCC_CAN1_CLK_ENABLE();
+
+ __HAL_RCC_GPIOA_CLK_ENABLE();
+ /**CAN GPIO Configuration
+ PA11 ------> CAN_RX
+ PA12 ------> CAN_TX
+ */
+ GPIO_InitStruct.Pin = GPIO_PIN_11|GPIO_PIN_12;
+ GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
+ GPIO_InitStruct.Pull = GPIO_NOPULL;
+ GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;
+ GPIO_InitStruct.Alternate = GPIO_AF9_CAN;
+ HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
+
+ /* CAN interrupt Init */
+ HAL_NVIC_SetPriority(USB_LP_CAN_RX0_IRQn, 0, 0);
+ HAL_NVIC_EnableIRQ(USB_LP_CAN_RX0_IRQn);
+ /* USER CODE BEGIN CAN_MspInit 1 */
+
+ /* USER CODE END CAN_MspInit 1 */
+ }
+
+}
+
+/**
+* @brief CAN MSP De-Initialization
+* This function freeze the hardware resources used in this example
+* @param hcan: CAN handle pointer
+* @retval None
+*/
+void HAL_CAN_MspDeInit(CAN_HandleTypeDef* hcan)
+{
+ if(hcan->Instance==CAN)
+ {
+ /* USER CODE BEGIN CAN_MspDeInit 0 */
+
+ /* USER CODE END CAN_MspDeInit 0 */
+ /* Peripheral clock disable */
+ __HAL_RCC_CAN1_CLK_DISABLE();
+
+ /**CAN GPIO Configuration
+ PA11 ------> CAN_RX
+ PA12 ------> CAN_TX
+ */
+ HAL_GPIO_DeInit(GPIOA, GPIO_PIN_11|GPIO_PIN_12);
+
+ /* CAN interrupt DeInit */
+ HAL_NVIC_DisableIRQ(USB_LP_CAN_RX0_IRQn);
+ /* USER CODE BEGIN CAN_MspDeInit 1 */
+
+ /* USER CODE END CAN_MspDeInit 1 */
+ }
+
+}
+
+/**
+* @brief I2C MSP Initialization
+* This function configures the hardware resources used in this example
+* @param hi2c: I2C handle pointer
+* @retval None
+*/
+void HAL_I2C_MspInit(I2C_HandleTypeDef* hi2c)
+{
+ GPIO_InitTypeDef GPIO_InitStruct = {0};
+ if(hi2c->Instance==I2C1)
+ {
+ /* USER CODE BEGIN I2C1_MspInit 0 */
+
+ /* USER CODE END I2C1_MspInit 0 */
+
+ __HAL_RCC_GPIOA_CLK_ENABLE();
+ __HAL_RCC_GPIOB_CLK_ENABLE();
+ /**I2C1 GPIO Configuration
+ PA15 ------> I2C1_SCL
+ PB7 ------> I2C1_SDA
+ */
+ GPIO_InitStruct.Pin = TMP_SCL_Pin;
+ GPIO_InitStruct.Mode = GPIO_MODE_AF_OD;
+ GPIO_InitStruct.Pull = GPIO_NOPULL;
+ GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;
+ GPIO_InitStruct.Alternate = GPIO_AF4_I2C1;
+ HAL_GPIO_Init(TMP_SCL_GPIO_Port, &GPIO_InitStruct);
+
+ GPIO_InitStruct.Pin = TMP_SDA_Pin;
+ GPIO_InitStruct.Mode = GPIO_MODE_AF_OD;
+ GPIO_InitStruct.Pull = GPIO_NOPULL;
+ GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;
+ GPIO_InitStruct.Alternate = GPIO_AF4_I2C1;
+ HAL_GPIO_Init(TMP_SDA_GPIO_Port, &GPIO_InitStruct);
+
+ /* Peripheral clock enable */
+ __HAL_RCC_I2C1_CLK_ENABLE();
+ /* USER CODE BEGIN I2C1_MspInit 1 */
+
+ /* USER CODE END I2C1_MspInit 1 */
+ }
+ else if(hi2c->Instance==I2C2)
+ {
+ /* USER CODE BEGIN I2C2_MspInit 0 */
+
+ /* USER CODE END I2C2_MspInit 0 */
+
+ __HAL_RCC_GPIOA_CLK_ENABLE();
+ /**I2C2 GPIO Configuration
+ PA9 ------> I2C2_SCL
+ PA10 ------> I2C2_SDA
+ */
+ GPIO_InitStruct.Pin = GPIO_PIN_9|GPIO_PIN_10;
+ GPIO_InitStruct.Mode = GPIO_MODE_AF_OD;
+ GPIO_InitStruct.Pull = GPIO_NOPULL;
+ GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;
+ GPIO_InitStruct.Alternate = GPIO_AF4_I2C2;
+ HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
+
+ /* Peripheral clock enable */
+ __HAL_RCC_I2C2_CLK_ENABLE();
+ /* USER CODE BEGIN I2C2_MspInit 1 */
+
+ /* USER CODE END I2C2_MspInit 1 */
+ }
+
+}
+
+/**
+* @brief I2C MSP De-Initialization
+* This function freeze the hardware resources used in this example
+* @param hi2c: I2C handle pointer
+* @retval None
+*/
+void HAL_I2C_MspDeInit(I2C_HandleTypeDef* hi2c)
+{
+ if(hi2c->Instance==I2C1)
+ {
+ /* USER CODE BEGIN I2C1_MspDeInit 0 */
+
+ /* USER CODE END I2C1_MspDeInit 0 */
+ /* Peripheral clock disable */
+ __HAL_RCC_I2C1_CLK_DISABLE();
+
+ /**I2C1 GPIO Configuration
+ PA15 ------> I2C1_SCL
+ PB7 ------> I2C1_SDA
+ */
+ HAL_GPIO_DeInit(TMP_SCL_GPIO_Port, TMP_SCL_Pin);
+
+ HAL_GPIO_DeInit(TMP_SDA_GPIO_Port, TMP_SDA_Pin);
+
+ /* USER CODE BEGIN I2C1_MspDeInit 1 */
+
+ /* USER CODE END I2C1_MspDeInit 1 */
+ }
+ else if(hi2c->Instance==I2C2)
+ {
+ /* USER CODE BEGIN I2C2_MspDeInit 0 */
+
+ /* USER CODE END I2C2_MspDeInit 0 */
+ /* Peripheral clock disable */
+ __HAL_RCC_I2C2_CLK_DISABLE();
+
+ /**I2C2 GPIO Configuration
+ PA9 ------> I2C2_SCL
+ PA10 ------> I2C2_SDA
+ */
+ HAL_GPIO_DeInit(GPIOA, GPIO_PIN_9);
+
+ HAL_GPIO_DeInit(GPIOA, GPIO_PIN_10);
+
+ /* USER CODE BEGIN I2C2_MspDeInit 1 */
+
+ /* USER CODE END I2C2_MspDeInit 1 */
+ }
+
+}
+
+/**
+* @brief SPI MSP Initialization
+* This function configures the hardware resources used in this example
+* @param hspi: SPI handle pointer
+* @retval None
+*/
+void HAL_SPI_MspInit(SPI_HandleTypeDef* hspi)
+{
+ GPIO_InitTypeDef GPIO_InitStruct = {0};
+ if(hspi->Instance==SPI1)
+ {
+ /* USER CODE BEGIN SPI1_MspInit 0 */
+
+ /* USER CODE END SPI1_MspInit 0 */
+ /* Peripheral clock enable */
+ __HAL_RCC_SPI1_CLK_ENABLE();
+
+ __HAL_RCC_GPIOA_CLK_ENABLE();
+ /**SPI1 GPIO Configuration
+ PA5 ------> SPI1_SCK
+ PA6 ------> SPI1_MISO
+ PA7 ------> SPI1_MOSI
+ */
+ GPIO_InitStruct.Pin = GPIO_PIN_5|GPIO_PIN_6|GPIO_PIN_7;
+ GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
+ GPIO_InitStruct.Pull = GPIO_NOPULL;
+ GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;
+ GPIO_InitStruct.Alternate = GPIO_AF5_SPI1;
+ HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
+
+ /* USER CODE BEGIN SPI1_MspInit 1 */
+
+ /* USER CODE END SPI1_MspInit 1 */
+ }
+
+}
+
+/**
+* @brief SPI MSP De-Initialization
+* This function freeze the hardware resources used in this example
+* @param hspi: SPI handle pointer
+* @retval None
+*/
+void HAL_SPI_MspDeInit(SPI_HandleTypeDef* hspi)
+{
+ if(hspi->Instance==SPI1)
+ {
+ /* USER CODE BEGIN SPI1_MspDeInit 0 */
+
+ /* USER CODE END SPI1_MspDeInit 0 */
+ /* Peripheral clock disable */
+ __HAL_RCC_SPI1_CLK_DISABLE();
+
+ /**SPI1 GPIO Configuration
+ PA5 ------> SPI1_SCK
+ PA6 ------> SPI1_MISO
+ PA7 ------> SPI1_MOSI
+ */
+ HAL_GPIO_DeInit(GPIOA, GPIO_PIN_5|GPIO_PIN_6|GPIO_PIN_7);
+
+ /* USER CODE BEGIN SPI1_MspDeInit 1 */
+
+ /* USER CODE END SPI1_MspDeInit 1 */
+ }
+
+}
+
+/* USER CODE BEGIN 1 */
+
+/* USER CODE END 1 */
diff --git a/BMS_Testbench/BMS_Software_V1/Core/Src/stm32f3xx_it.c b/BMS_Testbench/BMS_Software_V1/Core/Src/stm32f3xx_it.c
new file mode 100644
index 0000000..182abcb
--- /dev/null
+++ b/BMS_Testbench/BMS_Software_V1/Core/Src/stm32f3xx_it.c
@@ -0,0 +1,217 @@
+/* USER CODE BEGIN Header */
+/**
+ ******************************************************************************
+ * @file stm32f3xx_it.c
+ * @brief Interrupt Service Routines.
+ ******************************************************************************
+ * @attention
+ *
+ * Copyright (c) 2023 STMicroelectronics.
+ * All rights reserved.
+ *
+ * This software is licensed under terms that can be found in the LICENSE file
+ * in the root directory of this software component.
+ * If no LICENSE file comes with this software, it is provided AS-IS.
+ *
+ ******************************************************************************
+ */
+/* USER CODE END Header */
+
+/* Includes ------------------------------------------------------------------*/
+#include "main.h"
+#include "stm32f3xx_it.h"
+/* Private includes ----------------------------------------------------------*/
+/* USER CODE BEGIN Includes */
+/* USER CODE END Includes */
+
+/* Private typedef -----------------------------------------------------------*/
+/* USER CODE BEGIN TD */
+
+/* USER CODE END TD */
+
+/* Private define ------------------------------------------------------------*/
+/* USER CODE BEGIN PD */
+
+/* USER CODE END PD */
+
+/* Private macro -------------------------------------------------------------*/
+/* USER CODE BEGIN PM */
+
+/* USER CODE END PM */
+
+/* Private variables ---------------------------------------------------------*/
+/* USER CODE BEGIN PV */
+
+/* USER CODE END PV */
+
+/* Private function prototypes -----------------------------------------------*/
+/* USER CODE BEGIN PFP */
+
+/* USER CODE END PFP */
+
+/* Private user code ---------------------------------------------------------*/
+/* USER CODE BEGIN 0 */
+
+/* USER CODE END 0 */
+
+/* External variables --------------------------------------------------------*/
+extern CAN_HandleTypeDef hcan;
+/* USER CODE BEGIN EV */
+
+/* USER CODE END EV */
+
+/******************************************************************************/
+/* Cortex-M4 Processor Interruption and Exception Handlers */
+/******************************************************************************/
+/**
+ * @brief This function handles Non maskable interrupt.
+ */
+void NMI_Handler(void)
+{
+ /* USER CODE BEGIN NonMaskableInt_IRQn 0 */
+
+ /* USER CODE END NonMaskableInt_IRQn 0 */
+ /* USER CODE BEGIN NonMaskableInt_IRQn 1 */
+ while (1)
+ {
+ }
+ /* USER CODE END NonMaskableInt_IRQn 1 */
+}
+
+/**
+ * @brief This function handles Hard fault interrupt.
+ */
+void HardFault_Handler(void)
+{
+ /* USER CODE BEGIN HardFault_IRQn 0 */
+
+ /* USER CODE END HardFault_IRQn 0 */
+ while (1)
+ {
+ /* USER CODE BEGIN W1_HardFault_IRQn 0 */
+ /* USER CODE END W1_HardFault_IRQn 0 */
+ }
+}
+
+/**
+ * @brief This function handles Memory management fault.
+ */
+void MemManage_Handler(void)
+{
+ /* USER CODE BEGIN MemoryManagement_IRQn 0 */
+
+ /* USER CODE END MemoryManagement_IRQn 0 */
+ while (1)
+ {
+ /* USER CODE BEGIN W1_MemoryManagement_IRQn 0 */
+ /* USER CODE END W1_MemoryManagement_IRQn 0 */
+ }
+}
+
+/**
+ * @brief This function handles Pre-fetch fault, memory access fault.
+ */
+void BusFault_Handler(void)
+{
+ /* USER CODE BEGIN BusFault_IRQn 0 */
+
+ /* USER CODE END BusFault_IRQn 0 */
+ while (1)
+ {
+ /* USER CODE BEGIN W1_BusFault_IRQn 0 */
+ /* USER CODE END W1_BusFault_IRQn 0 */
+ }
+}
+
+/**
+ * @brief This function handles Undefined instruction or illegal state.
+ */
+void UsageFault_Handler(void)
+{
+ /* USER CODE BEGIN UsageFault_IRQn 0 */
+
+ /* USER CODE END UsageFault_IRQn 0 */
+ while (1)
+ {
+ /* USER CODE BEGIN W1_UsageFault_IRQn 0 */
+ /* USER CODE END W1_UsageFault_IRQn 0 */
+ }
+}
+
+/**
+ * @brief This function handles System service call via SWI instruction.
+ */
+void SVC_Handler(void)
+{
+ /* USER CODE BEGIN SVCall_IRQn 0 */
+
+ /* USER CODE END SVCall_IRQn 0 */
+ /* USER CODE BEGIN SVCall_IRQn 1 */
+
+ /* USER CODE END SVCall_IRQn 1 */
+}
+
+/**
+ * @brief This function handles Debug monitor.
+ */
+void DebugMon_Handler(void)
+{
+ /* USER CODE BEGIN DebugMonitor_IRQn 0 */
+
+ /* USER CODE END DebugMonitor_IRQn 0 */
+ /* USER CODE BEGIN DebugMonitor_IRQn 1 */
+
+ /* USER CODE END DebugMonitor_IRQn 1 */
+}
+
+/**
+ * @brief This function handles Pendable request for system service.
+ */
+void PendSV_Handler(void)
+{
+ /* USER CODE BEGIN PendSV_IRQn 0 */
+
+ /* USER CODE END PendSV_IRQn 0 */
+ /* USER CODE BEGIN PendSV_IRQn 1 */
+
+ /* USER CODE END PendSV_IRQn 1 */
+}
+
+/**
+ * @brief This function handles System tick timer.
+ */
+void SysTick_Handler(void)
+{
+ /* USER CODE BEGIN SysTick_IRQn 0 */
+
+ /* USER CODE END SysTick_IRQn 0 */
+ HAL_IncTick();
+ /* USER CODE BEGIN SysTick_IRQn 1 */
+
+ /* USER CODE END SysTick_IRQn 1 */
+}
+
+/******************************************************************************/
+/* STM32F3xx Peripheral Interrupt Handlers */
+/* Add here the Interrupt Handlers for the used peripherals. */
+/* For the available peripheral interrupt handler names, */
+/* please refer to the startup file (startup_stm32f3xx.s). */
+/******************************************************************************/
+
+/**
+ * @brief This function handles USB low priority or CAN_RX0 interrupts.
+ */
+void USB_LP_CAN_RX0_IRQHandler(void)
+{
+ /* USER CODE BEGIN USB_LP_CAN_RX0_IRQn 0 */
+
+ /* USER CODE END USB_LP_CAN_RX0_IRQn 0 */
+ HAL_CAN_IRQHandler(&hcan);
+ /* USER CODE BEGIN USB_LP_CAN_RX0_IRQn 1 */
+
+ /* USER CODE END USB_LP_CAN_RX0_IRQn 1 */
+}
+
+/* USER CODE BEGIN 1 */
+
+/* USER CODE END 1 */
diff --git a/BMS_Testbench/BMS_Software_V1/Core/Src/syscalls.c b/BMS_Testbench/BMS_Software_V1/Core/Src/syscalls.c
new file mode 100644
index 0000000..f4278b7
--- /dev/null
+++ b/BMS_Testbench/BMS_Software_V1/Core/Src/syscalls.c
@@ -0,0 +1,176 @@
+/**
+ ******************************************************************************
+ * @file syscalls.c
+ * @author Auto-generated by STM32CubeIDE
+ * @brief STM32CubeIDE Minimal System calls file
+ *
+ * For more information about which c-functions
+ * need which of these lowlevel functions
+ * please consult the Newlib libc-manual
+ ******************************************************************************
+ * @attention
+ *
+ * Copyright (c) 2020-2022 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.
+ *
+ ******************************************************************************
+ */
+
+/* Includes */
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+
+
+/* Variables */
+extern int __io_putchar(int ch) __attribute__((weak));
+extern int __io_getchar(void) __attribute__((weak));
+
+
+char *__env[1] = { 0 };
+char **environ = __env;
+
+
+/* Functions */
+void initialise_monitor_handles()
+{
+}
+
+int _getpid(void)
+{
+ return 1;
+}
+
+int _kill(int pid, int sig)
+{
+ (void)pid;
+ (void)sig;
+ errno = EINVAL;
+ return -1;
+}
+
+void _exit (int status)
+{
+ _kill(status, -1);
+ while (1) {} /* Make sure we hang here */
+}
+
+__attribute__((weak)) int _read(int file, char *ptr, int len)
+{
+ (void)file;
+ int DataIdx;
+
+ for (DataIdx = 0; DataIdx < len; DataIdx++)
+ {
+ *ptr++ = __io_getchar();
+ }
+
+ return len;
+}
+
+__attribute__((weak)) int _write(int file, char *ptr, int len)
+{
+ (void)file;
+ int DataIdx;
+
+ for (DataIdx = 0; DataIdx < len; DataIdx++)
+ {
+ __io_putchar(*ptr++);
+ }
+ return len;
+}
+
+int _close(int file)
+{
+ (void)file;
+ return -1;
+}
+
+
+int _fstat(int file, struct stat *st)
+{
+ (void)file;
+ st->st_mode = S_IFCHR;
+ return 0;
+}
+
+int _isatty(int file)
+{
+ (void)file;
+ return 1;
+}
+
+int _lseek(int file, int ptr, int dir)
+{
+ (void)file;
+ (void)ptr;
+ (void)dir;
+ return 0;
+}
+
+int _open(char *path, int flags, ...)
+{
+ (void)path;
+ (void)flags;
+ /* Pretend like we always fail */
+ return -1;
+}
+
+int _wait(int *status)
+{
+ (void)status;
+ errno = ECHILD;
+ return -1;
+}
+
+int _unlink(char *name)
+{
+ (void)name;
+ errno = ENOENT;
+ return -1;
+}
+
+int _times(struct tms *buf)
+{
+ (void)buf;
+ return -1;
+}
+
+int _stat(char *file, struct stat *st)
+{
+ (void)file;
+ st->st_mode = S_IFCHR;
+ return 0;
+}
+
+int _link(char *old, char *new)
+{
+ (void)old;
+ (void)new;
+ errno = EMLINK;
+ return -1;
+}
+
+int _fork(void)
+{
+ errno = EAGAIN;
+ return -1;
+}
+
+int _execve(char *name, char **argv, char **env)
+{
+ (void)name;
+ (void)argv;
+ (void)env;
+ errno = ENOMEM;
+ return -1;
+}
diff --git a/BMS_Testbench/BMS_Software_V1/Core/Src/sysmem.c b/BMS_Testbench/BMS_Software_V1/Core/Src/sysmem.c
new file mode 100644
index 0000000..54081ac
--- /dev/null
+++ b/BMS_Testbench/BMS_Software_V1/Core/Src/sysmem.c
@@ -0,0 +1,79 @@
+/**
+ ******************************************************************************
+ * @file sysmem.c
+ * @author Generated by STM32CubeIDE
+ * @brief STM32CubeIDE System Memory calls file
+ *
+ * For more information about which C functions
+ * need which of these lowlevel functions
+ * please consult the newlib libc manual
+ ******************************************************************************
+ * @attention
+ *
+ * Copyright (c) 2022 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.
+ *
+ ******************************************************************************
+ */
+
+/* Includes */
+#include
+#include
+
+/**
+ * Pointer to the current high watermark of the heap usage
+ */
+static uint8_t *__sbrk_heap_end = NULL;
+
+/**
+ * @brief _sbrk() allocates memory to the newlib heap and is used by malloc
+ * and others from the C library
+ *
+ * @verbatim
+ * ############################################################################
+ * # .data # .bss # newlib heap # MSP stack #
+ * # # # # Reserved by _Min_Stack_Size #
+ * ############################################################################
+ * ^-- RAM start ^-- _end _estack, RAM end --^
+ * @endverbatim
+ *
+ * This implementation starts allocating at the '_end' linker symbol
+ * The '_Min_Stack_Size' linker symbol reserves a memory for the MSP stack
+ * The implementation considers '_estack' linker symbol to be RAM end
+ * NOTE: If the MSP stack, at any point during execution, grows larger than the
+ * reserved size, please increase the '_Min_Stack_Size'.
+ *
+ * @param incr Memory size
+ * @return Pointer to allocated memory
+ */
+void *_sbrk(ptrdiff_t incr)
+{
+ extern uint8_t _end; /* Symbol defined in the linker script */
+ extern uint8_t _estack; /* Symbol defined in the linker script */
+ extern uint32_t _Min_Stack_Size; /* Symbol defined in the linker script */
+ const uint32_t stack_limit = (uint32_t)&_estack - (uint32_t)&_Min_Stack_Size;
+ const uint8_t *max_heap = (uint8_t *)stack_limit;
+ uint8_t *prev_heap_end;
+
+ /* Initialize heap end at first call */
+ if (NULL == __sbrk_heap_end)
+ {
+ __sbrk_heap_end = &_end;
+ }
+
+ /* Protect heap from growing into the reserved MSP stack */
+ if (__sbrk_heap_end + incr > max_heap)
+ {
+ errno = ENOMEM;
+ return (void *)-1;
+ }
+
+ prev_heap_end = __sbrk_heap_end;
+ __sbrk_heap_end += incr;
+
+ return (void *)prev_heap_end;
+}
diff --git a/BMS_Testbench/BMS_Software_V1/Core/Src/system_stm32f3xx.c b/BMS_Testbench/BMS_Software_V1/Core/Src/system_stm32f3xx.c
new file mode 100644
index 0000000..495dd8d
--- /dev/null
+++ b/BMS_Testbench/BMS_Software_V1/Core/Src/system_stm32f3xx.c
@@ -0,0 +1,291 @@
+/**
+ ******************************************************************************
+ * @file system_stm32f3xx.c
+ * @author MCD Application Team
+ * @brief CMSIS Cortex-M4 Device Peripheral Access Layer System Source File.
+ *
+ * 1. This file provides two functions and one global variable to be called from
+ * user application:
+ * - SystemInit(): This function is called at startup just after reset and
+ * before branch to main program. This call is made inside
+ * the "startup_stm32f3xx.s" file.
+ *
+ * - SystemCoreClock variable: Contains the core clock (HCLK), it can be used
+ * by the user application to setup the SysTick
+ * timer or configure other parameters.
+ *
+ * - SystemCoreClockUpdate(): Updates the variable SystemCoreClock and must
+ * be called whenever the core clock is changed
+ * during program execution.
+ *
+ * 2. After each device reset the HSI (8 MHz) is used as system clock source.
+ * Then SystemInit() function is called, in "startup_stm32f3xx.s" file, to
+ * configure the system clock before to branch to main program.
+ *
+ * 3. This file configures the system clock as follows:
+ *=============================================================================
+ * Supported STM32F3xx device
+ *-----------------------------------------------------------------------------
+ * System Clock source | HSI
+ *-----------------------------------------------------------------------------
+ * SYSCLK(Hz) | 8000000
+ *-----------------------------------------------------------------------------
+ * HCLK(Hz) | 8000000
+ *-----------------------------------------------------------------------------
+ * AHB Prescaler | 1
+ *-----------------------------------------------------------------------------
+ * APB2 Prescaler | 1
+ *-----------------------------------------------------------------------------
+ * APB1 Prescaler | 1
+ *-----------------------------------------------------------------------------
+ * USB Clock | DISABLE
+ *-----------------------------------------------------------------------------
+ *=============================================================================
+ ******************************************************************************
+ * @attention
+ *
+ * © Copyright (c) 2016 STMicroelectronics.
+ * All rights reserved.
+ *
+ * This software component is licensed by ST under BSD 3-Clause license,
+ * the "License"; You may not use this file except in compliance with the
+ * License. You may obtain a copy of the License at:
+ * opensource.org/licenses/BSD-3-Clause
+ *
+ ******************************************************************************
+ */
+
+/** @addtogroup CMSIS
+ * @{
+ */
+
+/** @addtogroup stm32f3xx_system
+ * @{
+ */
+
+/** @addtogroup STM32F3xx_System_Private_Includes
+ * @{
+ */
+
+#include "stm32f3xx.h"
+
+/**
+ * @}
+ */
+
+/** @addtogroup STM32F3xx_System_Private_TypesDefinitions
+ * @{
+ */
+
+/**
+ * @}
+ */
+
+/** @addtogroup STM32F3xx_System_Private_Defines
+ * @{
+ */
+#if !defined (HSE_VALUE)
+ #define HSE_VALUE ((uint32_t)8000000) /*!< Default value of the External oscillator in Hz.
+ This value can be provided and adapted by the user application. */
+#endif /* HSE_VALUE */
+
+#if !defined (HSI_VALUE)
+ #define HSI_VALUE ((uint32_t)8000000) /*!< Default value of the Internal oscillator in Hz.
+ This value can be provided and adapted by the user application. */
+#endif /* HSI_VALUE */
+
+/* Note: Following vector table addresses must be defined in line with linker
+ configuration. */
+/*!< Uncomment the following line if you need to relocate the vector table
+ anywhere in Flash or Sram, else the vector table is kept at the automatic
+ remap of boot address selected */
+/* #define USER_VECT_TAB_ADDRESS */
+
+#if defined(USER_VECT_TAB_ADDRESS)
+/*!< Uncomment the following line if you need to relocate your vector Table
+ in Sram else user remap will be done in Flash. */
+/* #define VECT_TAB_SRAM */
+#if defined(VECT_TAB_SRAM)
+#define VECT_TAB_BASE_ADDRESS SRAM_BASE /*!< Vector Table base address field.
+ This value must be a multiple of 0x200. */
+#define VECT_TAB_OFFSET 0x00000000U /*!< Vector Table base offset field.
+ This value must be a multiple of 0x200. */
+#else
+#define VECT_TAB_BASE_ADDRESS FLASH_BASE /*!< Vector Table base address field.
+ This value must be a multiple of 0x200. */
+#define VECT_TAB_OFFSET 0x00000000U /*!< Vector Table base offset field.
+ This value must be a multiple of 0x200. */
+#endif /* VECT_TAB_SRAM */
+#endif /* USER_VECT_TAB_ADDRESS */
+
+/******************************************************************************/
+/**
+ * @}
+ */
+
+/** @addtogroup STM32F3xx_System_Private_Macros
+ * @{
+ */
+
+/**
+ * @}
+ */
+
+/** @addtogroup STM32F3xx_System_Private_Variables
+ * @{
+ */
+ /* This variable is updated in three ways:
+ 1) by calling CMSIS function SystemCoreClockUpdate()
+ 2) by calling HAL API function HAL_RCC_GetHCLKFreq()
+ 3) each time HAL_RCC_ClockConfig() is called to configure the system clock frequency
+ Note: If you use this function to configure the system clock there is no need to
+ call the 2 first functions listed above, since SystemCoreClock variable is
+ updated automatically.
+ */
+uint32_t SystemCoreClock = 8000000;
+
+const uint8_t AHBPrescTable[16] = {0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 3, 4, 6, 7, 8, 9};
+const uint8_t APBPrescTable[8] = {0, 0, 0, 0, 1, 2, 3, 4};
+
+/**
+ * @}
+ */
+
+/** @addtogroup STM32F3xx_System_Private_FunctionPrototypes
+ * @{
+ */
+
+/**
+ * @}
+ */
+
+/** @addtogroup STM32F3xx_System_Private_Functions
+ * @{
+ */
+
+/**
+ * @brief Setup the microcontroller system
+ * @param None
+ * @retval None
+ */
+void SystemInit(void)
+{
+/* FPU settings --------------------------------------------------------------*/
+#if (__FPU_PRESENT == 1) && (__FPU_USED == 1)
+ SCB->CPACR |= ((3UL << 10*2)|(3UL << 11*2)); /* set CP10 and CP11 Full Access */
+#endif
+
+ /* Configure the Vector Table location -------------------------------------*/
+#if defined(USER_VECT_TAB_ADDRESS)
+ SCB->VTOR = VECT_TAB_BASE_ADDRESS | VECT_TAB_OFFSET; /* Vector Table Relocation in Internal SRAM */
+#endif /* USER_VECT_TAB_ADDRESS */
+}
+
+/**
+ * @brief Update SystemCoreClock variable according to Clock Register Values.
+ * The SystemCoreClock variable contains the core clock (HCLK), it can
+ * be used by the user application to setup the SysTick timer or configure
+ * other parameters.
+ *
+ * @note Each time the core clock (HCLK) changes, this function must be called
+ * to update SystemCoreClock variable value. Otherwise, any configuration
+ * based on this variable will be incorrect.
+ *
+ * @note - The system frequency computed by this function is not the real
+ * frequency in the chip. It is calculated based on the predefined
+ * constant and the selected clock source:
+ *
+ * - If SYSCLK source is HSI, SystemCoreClock will contain the HSI_VALUE(*)
+ *
+ * - If SYSCLK source is HSE, SystemCoreClock will contain the HSE_VALUE(**)
+ *
+ * - If SYSCLK source is PLL, SystemCoreClock will contain the HSE_VALUE(**)
+ * or HSI_VALUE(*) multiplied/divided by the PLL factors.
+ *
+ * (*) HSI_VALUE is a constant defined in stm32f3xx_hal.h file (default value
+ * 8 MHz) but the real value may vary depending on the variations
+ * in voltage and temperature.
+ *
+ * (**) HSE_VALUE is a constant defined in stm32f3xx_hal.h file (default value
+ * 8 MHz), user has to ensure that HSE_VALUE is same as the real
+ * frequency of the crystal used. Otherwise, this function may
+ * have wrong result.
+ *
+ * - The result of this function could be not correct when using fractional
+ * value for HSE crystal.
+ *
+ * @param None
+ * @retval None
+ */
+void SystemCoreClockUpdate (void)
+{
+ uint32_t tmp = 0, pllmull = 0, pllsource = 0, predivfactor = 0;
+
+ /* Get SYSCLK source -------------------------------------------------------*/
+ tmp = RCC->CFGR & RCC_CFGR_SWS;
+
+ switch (tmp)
+ {
+ case RCC_CFGR_SWS_HSI: /* HSI used as system clock */
+ SystemCoreClock = HSI_VALUE;
+ break;
+ case RCC_CFGR_SWS_HSE: /* HSE used as system clock */
+ SystemCoreClock = HSE_VALUE;
+ break;
+ case RCC_CFGR_SWS_PLL: /* PLL used as system clock */
+ /* Get PLL clock source and multiplication factor ----------------------*/
+ pllmull = RCC->CFGR & RCC_CFGR_PLLMUL;
+ pllsource = RCC->CFGR & RCC_CFGR_PLLSRC;
+ pllmull = ( pllmull >> 18) + 2;
+
+#if defined (STM32F302xE) || defined (STM32F303xE) || defined (STM32F398xx)
+ predivfactor = (RCC->CFGR2 & RCC_CFGR2_PREDIV) + 1;
+ if (pllsource == RCC_CFGR_PLLSRC_HSE_PREDIV)
+ {
+ /* HSE oscillator clock selected as PREDIV1 clock entry */
+ SystemCoreClock = (HSE_VALUE / predivfactor) * pllmull;
+ }
+ else
+ {
+ /* HSI oscillator clock selected as PREDIV1 clock entry */
+ SystemCoreClock = (HSI_VALUE / predivfactor) * pllmull;
+ }
+#else
+ if (pllsource == RCC_CFGR_PLLSRC_HSI_DIV2)
+ {
+ /* HSI oscillator clock divided by 2 selected as PLL clock entry */
+ SystemCoreClock = (HSI_VALUE >> 1) * pllmull;
+ }
+ else
+ {
+ predivfactor = (RCC->CFGR2 & RCC_CFGR2_PREDIV) + 1;
+ /* HSE oscillator clock selected as PREDIV1 clock entry */
+ SystemCoreClock = (HSE_VALUE / predivfactor) * pllmull;
+ }
+#endif /* STM32F302xE || STM32F303xE || STM32F398xx */
+ break;
+ default: /* HSI used as system clock */
+ SystemCoreClock = HSI_VALUE;
+ break;
+ }
+ /* Compute HCLK clock frequency ----------------*/
+ /* Get HCLK prescaler */
+ tmp = AHBPrescTable[((RCC->CFGR & RCC_CFGR_HPRE) >> 4)];
+ /* HCLK clock frequency */
+ SystemCoreClock >>= tmp;
+}
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
+
diff --git a/BMS_Testbench/BMS_Software_V1/Core/Startup/startup_stm32f302cctx.s b/BMS_Testbench/BMS_Software_V1/Core/Startup/startup_stm32f302cctx.s
new file mode 100644
index 0000000..d946fff
--- /dev/null
+++ b/BMS_Testbench/BMS_Software_V1/Core/Startup/startup_stm32f302cctx.s
@@ -0,0 +1,441 @@
+/**
+ ******************************************************************************
+ * @file startup_stm32f302xc.s
+ * @author MCD Application Team
+ * @brief STM32F302xB/STM32F302xC devices vector table for GCC toolchain.
+ * This module performs:
+ * - Set the initial SP
+ * - Set the initial PC == Reset_Handler,
+ * - Set the vector table entries with the exceptions ISR address,
+ * - Configure the clock system
+ * - Branches to main in the C library (which eventually
+ * calls main()).
+ * After Reset the Cortex-M4 processor is in Thread mode,
+ * priority is Privileged, and the Stack is set to Main.
+ ******************************************************************************
+ * @attention
+ *
+ * © Copyright (c) 2016 STMicroelectronics.
+ * All rights reserved.
+ *
+ * This software component is licensed by ST under BSD 3-Clause license,
+ * the "License"; You may not use this file except in compliance with the
+ * License. You may obtain a copy of the License at:
+ * opensource.org/licenses/BSD-3-Clause
+ *
+ ******************************************************************************
+ */
+
+ .syntax unified
+ .cpu cortex-m4
+ .fpu softvfp
+ .thumb
+
+.global g_pfnVectors
+.global Default_Handler
+
+/* start address for the initialization values of the .data section.
+defined in linker script */
+.word _sidata
+/* start address for the .data section. defined in linker script */
+.word _sdata
+/* end address for the .data section. defined in linker script */
+.word _edata
+/* start address for the .bss section. defined in linker script */
+.word _sbss
+/* end address for the .bss section. defined in linker script */
+.word _ebss
+
+.equ BootRAM, 0xF1E0F85F
+/**
+ * @brief This is the code that gets called when the processor first
+ * starts execution following a reset event. Only the absolutely
+ * necessary set is performed, after which the application
+ * supplied main() routine is called.
+ * @param None
+ * @retval : None
+*/
+
+ .section .text.Reset_Handler
+ .weak Reset_Handler
+ .type Reset_Handler, %function
+Reset_Handler:
+ ldr sp, =_estack /* Atollic update: set stack pointer */
+
+/* Copy the data segment initializers from flash to SRAM */
+ ldr r0, =_sdata
+ ldr r1, =_edata
+ ldr r2, =_sidata
+ movs r3, #0
+ b LoopCopyDataInit
+
+CopyDataInit:
+ ldr r4, [r2, r3]
+ str r4, [r0, r3]
+ adds r3, r3, #4
+
+LoopCopyDataInit:
+ adds r4, r0, r3
+ cmp r4, r1
+ bcc CopyDataInit
+
+/* Zero fill the bss segment. */
+ ldr r2, =_sbss
+ ldr r4, =_ebss
+ movs r3, #0
+ b LoopFillZerobss
+
+FillZerobss:
+ str r3, [r2]
+ adds r2, r2, #4
+
+LoopFillZerobss:
+ cmp r2, r4
+ bcc FillZerobss
+
+/* Call the clock system intitialization function.*/
+ bl SystemInit
+/* Call static constructors */
+ bl __libc_init_array
+/* Call the application's entry point.*/
+ bl main
+
+LoopForever:
+ b LoopForever
+
+.size Reset_Handler, .-Reset_Handler
+
+/**
+ * @brief This is the code that gets called when the processor receives an
+ * unexpected interrupt. This simply enters an infinite loop, preserving
+ * the system state for examination by a debugger.
+ *
+ * @param None
+ * @retval : None
+*/
+ .section .text.Default_Handler,"ax",%progbits
+Default_Handler:
+Infinite_Loop:
+ b Infinite_Loop
+ .size Default_Handler, .-Default_Handler
+/******************************************************************************
+*
+* The minimal vector table for a Cortex-M4. Note that the proper constructs
+* must be placed on this to ensure that it ends up at physical address
+* 0x0000.0000.
+*
+******************************************************************************/
+ .section .isr_vector,"a",%progbits
+ .type g_pfnVectors, %object
+ .size g_pfnVectors, .-g_pfnVectors
+
+
+g_pfnVectors:
+ .word _estack
+ .word Reset_Handler
+ .word NMI_Handler
+ .word HardFault_Handler
+ .word MemManage_Handler
+ .word BusFault_Handler
+ .word UsageFault_Handler
+ .word 0
+ .word 0
+ .word 0
+ .word 0
+ .word SVC_Handler
+ .word DebugMon_Handler
+ .word 0
+ .word PendSV_Handler
+ .word SysTick_Handler
+ .word WWDG_IRQHandler
+ .word PVD_IRQHandler
+ .word TAMP_STAMP_IRQHandler
+ .word RTC_WKUP_IRQHandler
+ .word FLASH_IRQHandler
+ .word RCC_IRQHandler
+ .word EXTI0_IRQHandler
+ .word EXTI1_IRQHandler
+ .word EXTI2_TSC_IRQHandler
+ .word EXTI3_IRQHandler
+ .word EXTI4_IRQHandler
+ .word DMA1_Channel1_IRQHandler
+ .word DMA1_Channel2_IRQHandler
+ .word DMA1_Channel3_IRQHandler
+ .word DMA1_Channel4_IRQHandler
+ .word DMA1_Channel5_IRQHandler
+ .word DMA1_Channel6_IRQHandler
+ .word DMA1_Channel7_IRQHandler
+ .word ADC1_2_IRQHandler
+ .word USB_HP_CAN_TX_IRQHandler
+ .word USB_LP_CAN_RX0_IRQHandler
+ .word CAN_RX1_IRQHandler
+ .word CAN_SCE_IRQHandler
+ .word EXTI9_5_IRQHandler
+ .word TIM1_BRK_TIM15_IRQHandler
+ .word TIM1_UP_TIM16_IRQHandler
+ .word TIM1_TRG_COM_TIM17_IRQHandler
+ .word TIM1_CC_IRQHandler
+ .word TIM2_IRQHandler
+ .word TIM3_IRQHandler
+ .word TIM4_IRQHandler
+ .word I2C1_EV_IRQHandler
+ .word I2C1_ER_IRQHandler
+ .word I2C2_EV_IRQHandler
+ .word I2C2_ER_IRQHandler
+ .word SPI1_IRQHandler
+ .word SPI2_IRQHandler
+ .word USART1_IRQHandler
+ .word USART2_IRQHandler
+ .word USART3_IRQHandler
+ .word EXTI15_10_IRQHandler
+ .word RTC_Alarm_IRQHandler
+ .word USBWakeUp_IRQHandler
+ .word 0
+ .word 0
+ .word 0
+ .word 0
+ .word 0
+ .word 0
+ .word 0
+ .word 0
+ .word SPI3_IRQHandler
+ .word UART4_IRQHandler
+ .word UART5_IRQHandler
+ .word TIM6_DAC_IRQHandler
+ .word 0
+ .word DMA2_Channel1_IRQHandler
+ .word DMA2_Channel2_IRQHandler
+ .word DMA2_Channel3_IRQHandler
+ .word DMA2_Channel4_IRQHandler
+ .word DMA2_Channel5_IRQHandler
+ .word 0
+ .word 0
+ .word 0
+ .word COMP1_2_IRQHandler
+ .word COMP4_6_IRQHandler
+ .word 0
+ .word 0
+ .word 0
+ .word 0
+ .word 0
+ .word 0
+ .word 0
+ .word 0
+ .word USB_HP_IRQHandler
+ .word USB_LP_IRQHandler
+ .word USBWakeUp_RMP_IRQHandler
+ .word 0
+ .word 0
+ .word 0
+ .word 0
+ .word FPU_IRQHandler
+
+/*******************************************************************************
+*
+* Provide weak aliases for each Exception handler to the Default_Handler.
+* As they are weak aliases, any function with the same name will override
+* this definition.
+*
+*******************************************************************************/
+
+ .weak NMI_Handler
+ .thumb_set NMI_Handler,Default_Handler
+
+ .weak HardFault_Handler
+ .thumb_set HardFault_Handler,Default_Handler
+
+ .weak MemManage_Handler
+ .thumb_set MemManage_Handler,Default_Handler
+
+ .weak BusFault_Handler
+ .thumb_set BusFault_Handler,Default_Handler
+
+ .weak UsageFault_Handler
+ .thumb_set UsageFault_Handler,Default_Handler
+
+ .weak SVC_Handler
+ .thumb_set SVC_Handler,Default_Handler
+
+ .weak DebugMon_Handler
+ .thumb_set DebugMon_Handler,Default_Handler
+
+ .weak PendSV_Handler
+ .thumb_set PendSV_Handler,Default_Handler
+
+ .weak SysTick_Handler
+ .thumb_set SysTick_Handler,Default_Handler
+
+ .weak WWDG_IRQHandler
+ .thumb_set WWDG_IRQHandler,Default_Handler
+
+ .weak PVD_IRQHandler
+ .thumb_set PVD_IRQHandler,Default_Handler
+
+ .weak TAMP_STAMP_IRQHandler
+ .thumb_set TAMP_STAMP_IRQHandler,Default_Handler
+
+ .weak RTC_WKUP_IRQHandler
+ .thumb_set RTC_WKUP_IRQHandler,Default_Handler
+
+ .weak FLASH_IRQHandler
+ .thumb_set FLASH_IRQHandler,Default_Handler
+
+ .weak RCC_IRQHandler
+ .thumb_set RCC_IRQHandler,Default_Handler
+
+ .weak EXTI0_IRQHandler
+ .thumb_set EXTI0_IRQHandler,Default_Handler
+
+ .weak EXTI1_IRQHandler
+ .thumb_set EXTI1_IRQHandler,Default_Handler
+
+ .weak EXTI2_TSC_IRQHandler
+ .thumb_set EXTI2_TSC_IRQHandler,Default_Handler
+
+ .weak EXTI3_IRQHandler
+ .thumb_set EXTI3_IRQHandler,Default_Handler
+
+ .weak EXTI4_IRQHandler
+ .thumb_set EXTI4_IRQHandler,Default_Handler
+
+ .weak DMA1_Channel1_IRQHandler
+ .thumb_set DMA1_Channel1_IRQHandler,Default_Handler
+
+ .weak DMA1_Channel2_IRQHandler
+ .thumb_set DMA1_Channel2_IRQHandler,Default_Handler
+
+ .weak DMA1_Channel3_IRQHandler
+ .thumb_set DMA1_Channel3_IRQHandler,Default_Handler
+
+ .weak DMA1_Channel4_IRQHandler
+ .thumb_set DMA1_Channel4_IRQHandler,Default_Handler
+
+ .weak DMA1_Channel5_IRQHandler
+ .thumb_set DMA1_Channel5_IRQHandler,Default_Handler
+
+ .weak DMA1_Channel6_IRQHandler
+ .thumb_set DMA1_Channel6_IRQHandler,Default_Handler
+
+ .weak DMA1_Channel7_IRQHandler
+ .thumb_set DMA1_Channel7_IRQHandler,Default_Handler
+
+ .weak ADC1_2_IRQHandler
+ .thumb_set ADC1_2_IRQHandler,Default_Handler
+
+ .weak USB_HP_CAN_TX_IRQHandler
+ .thumb_set USB_HP_CAN_TX_IRQHandler,Default_Handler
+
+ .weak USB_LP_CAN_RX0_IRQHandler
+ .thumb_set USB_LP_CAN_RX0_IRQHandler,Default_Handler
+
+ .weak CAN_RX1_IRQHandler
+ .thumb_set CAN_RX1_IRQHandler,Default_Handler
+
+ .weak CAN_SCE_IRQHandler
+ .thumb_set CAN_SCE_IRQHandler,Default_Handler
+
+ .weak EXTI9_5_IRQHandler
+ .thumb_set EXTI9_5_IRQHandler,Default_Handler
+
+ .weak TIM1_BRK_TIM15_IRQHandler
+ .thumb_set TIM1_BRK_TIM15_IRQHandler,Default_Handler
+
+ .weak TIM1_UP_TIM16_IRQHandler
+ .thumb_set TIM1_UP_TIM16_IRQHandler,Default_Handler
+
+ .weak TIM1_TRG_COM_TIM17_IRQHandler
+ .thumb_set TIM1_TRG_COM_TIM17_IRQHandler,Default_Handler
+
+ .weak TIM1_CC_IRQHandler
+ .thumb_set TIM1_CC_IRQHandler,Default_Handler
+
+ .weak TIM2_IRQHandler
+ .thumb_set TIM2_IRQHandler,Default_Handler
+
+ .weak TIM3_IRQHandler
+ .thumb_set TIM3_IRQHandler,Default_Handler
+
+ .weak TIM4_IRQHandler
+ .thumb_set TIM4_IRQHandler,Default_Handler
+
+ .weak I2C1_EV_IRQHandler
+ .thumb_set I2C1_EV_IRQHandler,Default_Handler
+
+ .weak I2C1_ER_IRQHandler
+ .thumb_set I2C1_ER_IRQHandler,Default_Handler
+
+ .weak I2C2_EV_IRQHandler
+ .thumb_set I2C2_EV_IRQHandler,Default_Handler
+
+ .weak I2C2_ER_IRQHandler
+ .thumb_set I2C2_ER_IRQHandler,Default_Handler
+
+ .weak SPI1_IRQHandler
+ .thumb_set SPI1_IRQHandler,Default_Handler
+
+ .weak SPI2_IRQHandler
+ .thumb_set SPI2_IRQHandler,Default_Handler
+
+ .weak USART1_IRQHandler
+ .thumb_set USART1_IRQHandler,Default_Handler
+
+ .weak USART2_IRQHandler
+ .thumb_set USART2_IRQHandler,Default_Handler
+
+ .weak USART3_IRQHandler
+ .thumb_set USART3_IRQHandler,Default_Handler
+
+ .weak EXTI15_10_IRQHandler
+ .thumb_set EXTI15_10_IRQHandler,Default_Handler
+
+ .weak RTC_Alarm_IRQHandler
+ .thumb_set RTC_Alarm_IRQHandler,Default_Handler
+
+ .weak USBWakeUp_IRQHandler
+ .thumb_set USBWakeUp_IRQHandler,Default_Handler
+
+ .weak SPI3_IRQHandler
+ .thumb_set SPI3_IRQHandler,Default_Handler
+
+ .weak UART4_IRQHandler
+ .thumb_set UART4_IRQHandler,Default_Handler
+
+ .weak UART5_IRQHandler
+ .thumb_set UART5_IRQHandler,Default_Handler
+
+ .weak TIM6_DAC_IRQHandler
+ .thumb_set TIM6_DAC_IRQHandler,Default_Handler
+
+ .weak DMA2_Channel1_IRQHandler
+ .thumb_set DMA2_Channel1_IRQHandler,Default_Handler
+
+ .weak DMA2_Channel2_IRQHandler
+ .thumb_set DMA2_Channel2_IRQHandler,Default_Handler
+
+ .weak DMA2_Channel3_IRQHandler
+ .thumb_set DMA2_Channel3_IRQHandler,Default_Handler
+
+ .weak DMA2_Channel4_IRQHandler
+ .thumb_set DMA2_Channel4_IRQHandler,Default_Handler
+
+ .weak DMA2_Channel5_IRQHandler
+ .thumb_set DMA2_Channel5_IRQHandler,Default_Handler
+
+ .weak COMP1_2_IRQHandler
+ .thumb_set COMP1_2_IRQHandler,Default_Handler
+
+ .weak COMP4_6_IRQHandler
+ .thumb_set COMP4_6_IRQHandler,Default_Handler
+
+ .weak USB_HP_IRQHandler
+ .thumb_set USB_HP_IRQHandler,Default_Handler
+
+ .weak USB_LP_IRQHandler
+ .thumb_set USB_LP_IRQHandler,Default_Handler
+
+ .weak USBWakeUp_RMP_IRQHandler
+ .thumb_set USBWakeUp_RMP_IRQHandler,Default_Handler
+
+ .weak FPU_IRQHandler
+ .thumb_set FPU_IRQHandler,Default_Handler
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
diff --git a/BMS_Testbench/BMS_Software_V1/Debug/BMS_Software.elf b/BMS_Testbench/BMS_Software_V1/Debug/BMS_Software.elf
new file mode 100755
index 0000000..b53aa16
Binary files /dev/null and b/BMS_Testbench/BMS_Software_V1/Debug/BMS_Software.elf differ
diff --git a/BMS_Testbench/BMS_Software_V1/Debug/BMS_Software.list b/BMS_Testbench/BMS_Software_V1/Debug/BMS_Software.list
new file mode 100644
index 0000000..49fca06
--- /dev/null
+++ b/BMS_Testbench/BMS_Software_V1/Debug/BMS_Software.list
@@ -0,0 +1,16215 @@
+
+BMS_Software.elf: file format elf32-littlearm
+
+Sections:
+Idx Name Size VMA LMA File off Algn
+ 0 .isr_vector 00000188 08000000 08000000 00010000 2**0
+ CONTENTS, ALLOC, LOAD, READONLY, DATA
+ 1 .text 00006358 08000188 08000188 00010188 2**2
+ CONTENTS, ALLOC, LOAD, READONLY, CODE
+ 2 .rodata 00000030 080064e0 080064e0 000164e0 2**2
+ CONTENTS, ALLOC, LOAD, READONLY, DATA
+ 3 .ARM.extab 00000000 08006510 08006510 00020014 2**0
+ CONTENTS
+ 4 .ARM 00000000 08006510 08006510 00020014 2**0
+ CONTENTS
+ 5 .preinit_array 00000000 08006510 08006510 00020014 2**0
+ CONTENTS, ALLOC, LOAD, DATA
+ 6 .init_array 00000004 08006510 08006510 00016510 2**2
+ CONTENTS, ALLOC, LOAD, DATA
+ 7 .fini_array 00000004 08006514 08006514 00016514 2**2
+ CONTENTS, ALLOC, LOAD, DATA
+ 8 .data 00000014 20000000 08006518 00020000 2**2
+ CONTENTS, ALLOC, LOAD, DATA
+ 9 .bss 00000258 20000018 0800652c 00020018 2**3
+ ALLOC
+ 10 ._user_heap_stack 00000600 20000270 0800652c 00020270 2**0
+ ALLOC
+ 11 .ARM.attributes 00000030 00000000 00000000 00020014 2**0
+ CONTENTS, READONLY
+ 12 .debug_info 0000f54c 00000000 00000000 00020044 2**0
+ CONTENTS, READONLY, DEBUGGING, OCTETS
+ 13 .debug_abbrev 00002965 00000000 00000000 0002f590 2**0
+ CONTENTS, READONLY, DEBUGGING, OCTETS
+ 14 .debug_aranges 00000cc8 00000000 00000000 00031ef8 2**3
+ CONTENTS, READONLY, DEBUGGING, OCTETS
+ 15 .debug_ranges 00000bf0 00000000 00000000 00032bc0 2**3
+ CONTENTS, READONLY, DEBUGGING, OCTETS
+ 16 .debug_macro 0001c25c 00000000 00000000 000337b0 2**0
+ CONTENTS, READONLY, DEBUGGING, OCTETS
+ 17 .debug_line 0000feb9 00000000 00000000 0004fa0c 2**0
+ CONTENTS, READONLY, DEBUGGING, OCTETS
+ 18 .debug_str 000a2242 00000000 00000000 0005f8c5 2**0
+ CONTENTS, READONLY, DEBUGGING, OCTETS
+ 19 .comment 00000050 00000000 00000000 00101b07 2**0
+ CONTENTS, READONLY
+ 20 .debug_frame 000033cc 00000000 00000000 00101b58 2**2
+ CONTENTS, READONLY, DEBUGGING, OCTETS
+
+Disassembly of section .text:
+
+08000188 <__do_global_dtors_aux>:
+ 8000188: b510 push {r4, lr}
+ 800018a: 4c05 ldr r4, [pc, #20] ; (80001a0 <__do_global_dtors_aux+0x18>)
+ 800018c: 7823 ldrb r3, [r4, #0]
+ 800018e: b933 cbnz r3, 800019e <__do_global_dtors_aux+0x16>
+ 8000190: 4b04 ldr r3, [pc, #16] ; (80001a4 <__do_global_dtors_aux+0x1c>)
+ 8000192: b113 cbz r3, 800019a <__do_global_dtors_aux+0x12>
+ 8000194: 4804 ldr r0, [pc, #16] ; (80001a8 <__do_global_dtors_aux+0x20>)
+ 8000196: f3af 8000 nop.w
+ 800019a: 2301 movs r3, #1
+ 800019c: 7023 strb r3, [r4, #0]
+ 800019e: bd10 pop {r4, pc}
+ 80001a0: 20000018 .word 0x20000018
+ 80001a4: 00000000 .word 0x00000000
+ 80001a8: 080064c8 .word 0x080064c8
+
+080001ac :
+ 80001ac: b508 push {r3, lr}
+ 80001ae: 4b03 ldr r3, [pc, #12] ; (80001bc )
+ 80001b0: b11b cbz r3, 80001ba
+ 80001b2: 4903 ldr r1, [pc, #12] ; (80001c0 )
+ 80001b4: 4803 ldr r0, [pc, #12] ; (80001c4 )
+ 80001b6: f3af 8000 nop.w
+ 80001ba: bd08 pop {r3, pc}
+ 80001bc: 00000000 .word 0x00000000
+ 80001c0: 2000001c .word 0x2000001c
+ 80001c4: 080064c8 .word 0x080064c8
+
+080001c8 :
+
+uint8 numberofcells;
+uint8 numberofauxchannels;
+
+uint8 initAMS(SPI_HandleTypeDef* hspi, uint8 numofcells, uint8 numofaux)
+{
+ 80001c8: b580 push {r7, lr}
+ 80001ca: b082 sub sp, #8
+ 80001cc: af00 add r7, sp, #0
+ 80001ce: 6078 str r0, [r7, #4]
+ 80001d0: 460b mov r3, r1
+ 80001d2: 70fb strb r3, [r7, #3]
+ 80001d4: 4613 mov r3, r2
+ 80001d6: 70bb strb r3, [r7, #2]
+ adbmsDriverInit(hspi);
+ 80001d8: 6878 ldr r0, [r7, #4]
+ 80001da: f000 fba7 bl 800092c
+ numberofcells = numofcells;
+ 80001de: 4a0d ldr r2, [pc, #52] ; (8000214 )
+ 80001e0: 78fb ldrb r3, [r7, #3]
+ 80001e2: 7013 strb r3, [r2, #0]
+ numberofauxchannels = numofaux;
+ 80001e4: 4a0c ldr r2, [pc, #48] ; (8000218 )
+ 80001e6: 78bb ldrb r3, [r7, #2]
+ 80001e8: 7013 strb r3, [r2, #0]
+
+
+ amsWakeUp();
+ 80001ea: f000 f817 bl 800021c
+ amsStopBalancing();
+ 80001ee: f000 f9ad bl 800054c
+ amsConfigOverVoltage(DEFAULT_OV);
+ 80001f2: f640 2041 movw r0, #2625 ; 0xa41
+ 80001f6: f000 fa6e bl 80006d6
+ amsConfigUnderVoltage(DEFAULT_UV);
+ 80001fa: f240 601a movw r0, #1562 ; 0x61a
+ 80001fe: f000 f9af bl 8000560
+ amsConfigAuxMeasurement(0xFFFF);
+ 8000202: f64f 70ff movw r0, #65535 ; 0xffff
+ 8000206: f000 f90d bl 8000424
+
+ return 0;
+ 800020a: 2300 movs r3, #0
+}
+ 800020c: 4618 mov r0, r3
+ 800020e: 3708 adds r7, #8
+ 8000210: 46bd mov sp, r7
+ 8000212: bd80 pop {r7, pc}
+ 8000214: 20000034 .word 0x20000034
+ 8000218: 20000035 .word 0x20000035
+
+0800021c :
+
+uint8 amsWakeUp()
+{
+ 800021c: b580 push {r7, lr}
+ 800021e: b082 sub sp, #8
+ 8000220: af00 add r7, sp, #0
+ uint8 buf[6];
+ readCMD(RDCFGA, buf, 6);
+ 8000222: 463b mov r3, r7
+ 8000224: 2206 movs r2, #6
+ 8000226: 4619 mov r1, r3
+ 8000228: 2002 movs r0, #2
+ 800022a: f000 fdab bl 8000d84
+ return 0;
+ 800022e: 2300 movs r3, #0
+}
+ 8000230: 4618 mov r0, r3
+ 8000232: 3708 adds r7, #8
+ 8000234: 46bd mov sp, r7
+ 8000236: bd80 pop {r7, pc}
+
+08000238 :
+
+uint8 amsCellMeasurement(Cell_Module *module)
+{
+ 8000238: b580 push {r7, lr}
+ 800023a: b084 sub sp, #16
+ 800023c: af00 add r7, sp, #0
+ 800023e: 6078 str r0, [r7, #4]
+ uint8_t rxbuffer[CV_GROUP_A_SIZE];
+ writeCMD((ADCV | CH000 | MD10), rxbuffer, 0);
+ 8000240: f107 0308 add.w r3, r7, #8
+ 8000244: 2200 movs r2, #0
+ 8000246: 4619 mov r1, r3
+ 8000248: f44f 7058 mov.w r0, #864 ; 0x360
+ 800024c: f000 fd11 bl 8000c72
+ mcuDelay(5);
+ 8000250: 2005 movs r0, #5
+ 8000252: f000 fecd bl 8000ff0
+ amsReadCellVoltages(module);
+ 8000256: 6878 ldr r0, [r7, #4]
+ 8000258: f000 fa80 bl 800075c
+ return 0;
+ 800025c: 2300 movs r3, #0
+}
+ 800025e: 4618 mov r0, r3
+ 8000260: 3710 adds r7, #16
+ 8000262: 46bd mov sp, r7
+ 8000264: bd80 pop {r7, pc}
+
+08000266 :
+ numberofcells = numberofChannels;
+ return 0;
+}
+
+uint8 amsAuxMeasurement(Cell_Module *module)
+{
+ 8000266: b580 push {r7, lr}
+ 8000268: b084 sub sp, #16
+ 800026a: af00 add r7, sp, #0
+ 800026c: 6078 str r0, [r7, #4]
+ uint8 args;
+ uint8 rxbuf[AUX_GROUP_A_SIZE];
+ writeCMD(ADAX | MD01 | CHG000, &args, 0);
+ 800026e: f107 030f add.w r3, r7, #15
+ 8000272: 2200 movs r2, #0
+ 8000274: 4619 mov r1, r3
+ 8000276: f44f 609c mov.w r0, #1248 ; 0x4e0
+ 800027a: f000 fcfa bl 8000c72
+
+ mcuDelay(5);
+ 800027e: 2005 movs r0, #5
+ 8000280: f000 feb6 bl 8000ff0
+
+ readCMD(RDAUXA, rxbuf, AUX_GROUP_A_SIZE);
+ 8000284: f107 0308 add.w r3, r7, #8
+ 8000288: 2206 movs r2, #6
+ 800028a: 4619 mov r1, r3
+ 800028c: 200c movs r0, #12
+ 800028e: f000 fd79 bl 8000d84
+
+ module->auxVoltages[0] = rxbuf[0] | (rxbuf[1]<<8);
+ 8000292: 7a3b ldrb r3, [r7, #8]
+ 8000294: b21a sxth r2, r3
+ 8000296: 7a7b ldrb r3, [r7, #9]
+ 8000298: 021b lsls r3, r3, #8
+ 800029a: b21b sxth r3, r3
+ 800029c: 4313 orrs r3, r2
+ 800029e: b21b sxth r3, r3
+ 80002a0: b29a uxth r2, r3
+ 80002a2: 687b ldr r3, [r7, #4]
+ 80002a4: 849a strh r2, [r3, #36] ; 0x24
+ module->auxVoltages[1] = rxbuf[2] | (rxbuf[3]<<8);
+ 80002a6: 7abb ldrb r3, [r7, #10]
+ 80002a8: b21a sxth r2, r3
+ 80002aa: 7afb ldrb r3, [r7, #11]
+ 80002ac: 021b lsls r3, r3, #8
+ 80002ae: b21b sxth r3, r3
+ 80002b0: 4313 orrs r3, r2
+ 80002b2: b21b sxth r3, r3
+ 80002b4: b29a uxth r2, r3
+ 80002b6: 687b ldr r3, [r7, #4]
+ 80002b8: 84da strh r2, [r3, #38] ; 0x26
+ module->auxVoltages[2] = rxbuf[4] | (rxbuf[5]<<8);
+ 80002ba: 7b3b ldrb r3, [r7, #12]
+ 80002bc: b21a sxth r2, r3
+ 80002be: 7b7b ldrb r3, [r7, #13]
+ 80002c0: 021b lsls r3, r3, #8
+ 80002c2: b21b sxth r3, r3
+ 80002c4: 4313 orrs r3, r2
+ 80002c6: b21b sxth r3, r3
+ 80002c8: b29a uxth r2, r3
+ 80002ca: 687b ldr r3, [r7, #4]
+ 80002cc: 851a strh r2, [r3, #40] ; 0x28
+
+ readCMD(RDAUXB, rxbuf, AUX_GROUP_A_SIZE);
+ 80002ce: f107 0308 add.w r3, r7, #8
+ 80002d2: 2206 movs r2, #6
+ 80002d4: 4619 mov r1, r3
+ 80002d6: 200e movs r0, #14
+ 80002d8: f000 fd54 bl 8000d84
+
+ module->auxVoltages[3] = rxbuf[0] | (rxbuf[1]<<8);
+ 80002dc: 7a3b ldrb r3, [r7, #8]
+ 80002de: b21a sxth r2, r3
+ 80002e0: 7a7b ldrb r3, [r7, #9]
+ 80002e2: 021b lsls r3, r3, #8
+ 80002e4: b21b sxth r3, r3
+ 80002e6: 4313 orrs r3, r2
+ 80002e8: b21b sxth r3, r3
+ 80002ea: b29a uxth r2, r3
+ 80002ec: 687b ldr r3, [r7, #4]
+ 80002ee: 855a strh r2, [r3, #42] ; 0x2a
+ module->auxVoltages[4] = rxbuf[2] | (rxbuf[3]<<8);
+ 80002f0: 7abb ldrb r3, [r7, #10]
+ 80002f2: b21a sxth r2, r3
+ 80002f4: 7afb ldrb r3, [r7, #11]
+ 80002f6: 021b lsls r3, r3, #8
+ 80002f8: b21b sxth r3, r3
+ 80002fa: 4313 orrs r3, r2
+ 80002fc: b21b sxth r3, r3
+ 80002fe: b29a uxth r2, r3
+ 8000300: 687b ldr r3, [r7, #4]
+ 8000302: 859a strh r2, [r3, #44] ; 0x2c
+ module->refVoltage = rxbuf[4] | (rxbuf[5]<<8);
+ 8000304: 7b3b ldrb r3, [r7, #12]
+ 8000306: b21a sxth r2, r3
+ 8000308: 7b7b ldrb r3, [r7, #13]
+ 800030a: 021b lsls r3, r3, #8
+ 800030c: b21b sxth r3, r3
+ 800030e: 4313 orrs r3, r2
+ 8000310: b21b sxth r3, r3
+ 8000312: b29a uxth r2, r3
+ 8000314: 687b ldr r3, [r7, #4]
+ 8000316: f8a3 2040 strh.w r2, [r3, #64] ; 0x40
+
+ readCMD(RDAUXC, rxbuf, AUX_GROUP_A_SIZE);
+ 800031a: f107 0308 add.w r3, r7, #8
+ 800031e: 2206 movs r2, #6
+ 8000320: 4619 mov r1, r3
+ 8000322: 200d movs r0, #13
+ 8000324: f000 fd2e bl 8000d84
+
+ module->auxVoltages[5] = rxbuf[0] | (rxbuf[1]<<8);
+ 8000328: 7a3b ldrb r3, [r7, #8]
+ 800032a: b21a sxth r2, r3
+ 800032c: 7a7b ldrb r3, [r7, #9]
+ 800032e: 021b lsls r3, r3, #8
+ 8000330: b21b sxth r3, r3
+ 8000332: 4313 orrs r3, r2
+ 8000334: b21b sxth r3, r3
+ 8000336: b29a uxth r2, r3
+ 8000338: 687b ldr r3, [r7, #4]
+ 800033a: 85da strh r2, [r3, #46] ; 0x2e
+ module->auxVoltages[6] = rxbuf[2] | (rxbuf[3]<<8);
+ 800033c: 7abb ldrb r3, [r7, #10]
+ 800033e: b21a sxth r2, r3
+ 8000340: 7afb ldrb r3, [r7, #11]
+ 8000342: 021b lsls r3, r3, #8
+ 8000344: b21b sxth r3, r3
+ 8000346: 4313 orrs r3, r2
+ 8000348: b21b sxth r3, r3
+ 800034a: b29a uxth r2, r3
+ 800034c: 687b ldr r3, [r7, #4]
+ 800034e: 861a strh r2, [r3, #48] ; 0x30
+ module->auxVoltages[7] = rxbuf[4] | (rxbuf[5]<<8);
+ 8000350: 7b3b ldrb r3, [r7, #12]
+ 8000352: b21a sxth r2, r3
+ 8000354: 7b7b ldrb r3, [r7, #13]
+ 8000356: 021b lsls r3, r3, #8
+ 8000358: b21b sxth r3, r3
+ 800035a: 4313 orrs r3, r2
+ 800035c: b21b sxth r3, r3
+ 800035e: b29a uxth r2, r3
+ 8000360: 687b ldr r3, [r7, #4]
+ 8000362: 865a strh r2, [r3, #50] ; 0x32
+
+ readCMD(RDAUXD, rxbuf, AUX_GROUP_A_SIZE);
+ 8000364: f107 0308 add.w r3, r7, #8
+ 8000368: 2206 movs r2, #6
+ 800036a: 4619 mov r1, r3
+ 800036c: 200f movs r0, #15
+ 800036e: f000 fd09 bl 8000d84
+
+ module->auxVoltages[8] = rxbuf[0] | (rxbuf[1]<<8);
+ 8000372: 7a3b ldrb r3, [r7, #8]
+ 8000374: b21a sxth r2, r3
+ 8000376: 7a7b ldrb r3, [r7, #9]
+ 8000378: 021b lsls r3, r3, #8
+ 800037a: b21b sxth r3, r3
+ 800037c: 4313 orrs r3, r2
+ 800037e: b21b sxth r3, r3
+ 8000380: b29a uxth r2, r3
+ 8000382: 687b ldr r3, [r7, #4]
+ 8000384: 869a strh r2, [r3, #52] ; 0x34
+
+ return 0;
+ 8000386: 2300 movs r3, #0
+}
+ 8000388: 4618 mov r0, r3
+ 800038a: 3710 adds r7, #16
+ 800038c: 46bd mov sp, r7
+ 800038e: bd80 pop {r7, pc}
+
+08000390 :
+
+uint8 amsInternalStatusMeasurement(Cell_Module *module)
+{
+ 8000390: b580 push {r7, lr}
+ 8000392: b084 sub sp, #16
+ 8000394: af00 add r7, sp, #0
+ 8000396: 6078 str r0, [r7, #4]
+ uint8 rxbuffer[STATUS_GROUP_A_SIZE];
+ writeCMD(ADSTAT | MD01 | CHST000, rxbuffer, STATUS_GROUP_A_SIZE);
+ 8000398: f107 0308 add.w r3, r7, #8
+ 800039c: 2206 movs r2, #6
+ 800039e: 4619 mov r1, r3
+ 80003a0: f44f 609d mov.w r0, #1256 ; 0x4e8
+ 80003a4: f000 fc65 bl 8000c72
+ mcuDelay(5);
+ 80003a8: 2005 movs r0, #5
+ 80003aa: f000 fe21 bl 8000ff0
+
+ readCMD(RDSTATA, rxbuffer, STATUS_GROUP_A_SIZE);
+ 80003ae: f107 0308 add.w r3, r7, #8
+ 80003b2: 2206 movs r2, #6
+ 80003b4: 4619 mov r1, r3
+ 80003b6: 2010 movs r0, #16
+ 80003b8: f000 fce4 bl 8000d84
+
+ module->sumOfCellMeasurements = rxbuffer[0] | (rxbuffer[1]<<8);
+ 80003bc: 7a3b ldrb r3, [r7, #8]
+ 80003be: b21a sxth r2, r3
+ 80003c0: 7a7b ldrb r3, [r7, #9]
+ 80003c2: 021b lsls r3, r3, #8
+ 80003c4: b21b sxth r3, r3
+ 80003c6: 4313 orrs r3, r2
+ 80003c8: b21b sxth r3, r3
+ 80003ca: b29a uxth r2, r3
+ 80003cc: 687b ldr r3, [r7, #4]
+ 80003ce: 87da strh r2, [r3, #62] ; 0x3e
+ module->internalDieTemp = rxbuffer[2] | (rxbuffer[3]<<8);
+ 80003d0: 7abb ldrb r3, [r7, #10]
+ 80003d2: b21a sxth r2, r3
+ 80003d4: 7afb ldrb r3, [r7, #11]
+ 80003d6: 021b lsls r3, r3, #8
+ 80003d8: b21b sxth r3, r3
+ 80003da: 4313 orrs r3, r2
+ 80003dc: b21b sxth r3, r3
+ 80003de: b29a uxth r2, r3
+ 80003e0: 687b ldr r3, [r7, #4]
+ 80003e2: 871a strh r2, [r3, #56] ; 0x38
+ module->analogSupplyVoltage = rxbuffer[4] | (rxbuffer[5]<<8);
+ 80003e4: 7b3b ldrb r3, [r7, #12]
+ 80003e6: b21a sxth r2, r3
+ 80003e8: 7b7b ldrb r3, [r7, #13]
+ 80003ea: 021b lsls r3, r3, #8
+ 80003ec: b21b sxth r3, r3
+ 80003ee: 4313 orrs r3, r2
+ 80003f0: b21b sxth r3, r3
+ 80003f2: b29a uxth r2, r3
+ 80003f4: 687b ldr r3, [r7, #4]
+ 80003f6: 875a strh r2, [r3, #58] ; 0x3a
+
+ readCMD(RDSTATB, rxbuffer, STATUS_GROUP_B_SIZE);
+ 80003f8: f107 0308 add.w r3, r7, #8
+ 80003fc: 2206 movs r2, #6
+ 80003fe: 4619 mov r1, r3
+ 8000400: 2012 movs r0, #18
+ 8000402: f000 fcbf bl 8000d84
+ module->digitalSupplyVoltage = rxbuffer[0] | (rxbuffer[1]<<8);
+ 8000406: 7a3b ldrb r3, [r7, #8]
+ 8000408: b21a sxth r2, r3
+ 800040a: 7a7b ldrb r3, [r7, #9]
+ 800040c: 021b lsls r3, r3, #8
+ 800040e: b21b sxth r3, r3
+ 8000410: 4313 orrs r3, r2
+ 8000412: b21b sxth r3, r3
+ 8000414: b29a uxth r2, r3
+ 8000416: 687b ldr r3, [r7, #4]
+ 8000418: 879a strh r2, [r3, #60] ; 0x3c
+
+
+ return 0;
+ 800041a: 2300 movs r3, #0
+}
+ 800041c: 4618 mov r0, r3
+ 800041e: 3710 adds r7, #16
+ 8000420: 46bd mov sp, r7
+ 8000422: bd80 pop {r7, pc}
+
+08000424 :
+
+uint8 amsConfigAuxMeasurement(uint16 Channels)
+{
+ 8000424: b580 push {r7, lr}
+ 8000426: b084 sub sp, #16
+ 8000428: af00 add r7, sp, #0
+ 800042a: 4603 mov r3, r0
+ 800042c: 80fb strh r3, [r7, #6]
+ uint8 buf[CFG_GROUP_A_SIZE];
+
+ readCMD(RDCFGA, buf, CFG_GROUP_A_SIZE);
+ 800042e: f107 0308 add.w r3, r7, #8
+ 8000432: 2206 movs r2, #6
+ 8000434: 4619 mov r1, r3
+ 8000436: 2002 movs r0, #2
+ 8000438: f000 fca4 bl 8000d84
+ buf[0] |= 0xF8;
+ 800043c: 7a3b ldrb r3, [r7, #8]
+ 800043e: f063 0307 orn r3, r3, #7
+ 8000442: b2db uxtb r3, r3
+ 8000444: 723b strb r3, [r7, #8]
+ writeCMD(WRCFGA, buf, CFG_GROUP_A_SIZE);
+ 8000446: f107 0308 add.w r3, r7, #8
+ 800044a: 2206 movs r2, #6
+ 800044c: 4619 mov r1, r3
+ 800044e: 2001 movs r0, #1
+ 8000450: f000 fc0f bl 8000c72
+
+ readCMD(RDCFGB, buf, CFG_GROUP_B_SIZE);
+ 8000454: f107 0308 add.w r3, r7, #8
+ 8000458: 2206 movs r2, #6
+ 800045a: 4619 mov r1, r3
+ 800045c: 2026 movs r0, #38 ; 0x26
+ 800045e: f000 fc91 bl 8000d84
+ buf[0] |= 0x0F;
+ 8000462: 7a3b ldrb r3, [r7, #8]
+ 8000464: f043 030f orr.w r3, r3, #15
+ 8000468: b2db uxtb r3, r3
+ 800046a: 723b strb r3, [r7, #8]
+ writeCMD(WRCFGB, buf, CFG_GROUP_B_SIZE);
+ 800046c: f107 0308 add.w r3, r7, #8
+ 8000470: 2206 movs r2, #6
+ 8000472: 4619 mov r1, r3
+ 8000474: 2024 movs r0, #36 ; 0x24
+ 8000476: f000 fbfc bl 8000c72
+ return 0;
+ 800047a: 2300 movs r3, #0
+}
+ 800047c: 4618 mov r0, r3
+ 800047e: 3710 adds r7, #16
+ 8000480: 46bd mov sp, r7
+ 8000482: bd80 pop {r7, pc}
+
+08000484 :
+{
+ return 0;
+}
+
+uint8 amsConfigBalancing(uint32 Channels)
+{
+ 8000484: b580 push {r7, lr}
+ 8000486: b084 sub sp, #16
+ 8000488: af00 add r7, sp, #0
+ 800048a: 6078 str r0, [r7, #4]
+
+ uint8 regbuffer[CFG_GROUP_A_SIZE];
+ readCMD(RDCFGA, regbuffer, CFG_GROUP_A_SIZE);
+ 800048c: f107 0308 add.w r3, r7, #8
+ 8000490: 2206 movs r2, #6
+ 8000492: 4619 mov r1, r3
+ 8000494: 2002 movs r0, #2
+ 8000496: f000 fc75 bl 8000d84
+
+ regbuffer[4] = Channels & 0xFF;
+ 800049a: 687b ldr r3, [r7, #4]
+ 800049c: b2db uxtb r3, r3
+ 800049e: 733b strb r3, [r7, #12]
+ regbuffer[5] &= 0xF0;
+ 80004a0: 7b7b ldrb r3, [r7, #13]
+ 80004a2: f023 030f bic.w r3, r3, #15
+ 80004a6: b2db uxtb r3, r3
+ 80004a8: 737b strb r3, [r7, #13]
+ regbuffer[5] |= (Channels>>8) & 0x0F;
+ 80004aa: 7b7a ldrb r2, [r7, #13]
+ 80004ac: 687b ldr r3, [r7, #4]
+ 80004ae: 0a1b lsrs r3, r3, #8
+ 80004b0: b2db uxtb r3, r3
+ 80004b2: f003 030f and.w r3, r3, #15
+ 80004b6: b2db uxtb r3, r3
+ 80004b8: 4313 orrs r3, r2
+ 80004ba: b2db uxtb r3, r3
+ 80004bc: 737b strb r3, [r7, #13]
+ writeCMD(WRCFGA, regbuffer, CFG_GROUP_A_SIZE);
+ 80004be: f107 0308 add.w r3, r7, #8
+ 80004c2: 2206 movs r2, #6
+ 80004c4: 4619 mov r1, r3
+ 80004c6: 2001 movs r0, #1
+ 80004c8: f000 fbd3 bl 8000c72
+
+ readCMD(RDCFGB, regbuffer, CFG_GROUP_B_SIZE);
+ 80004cc: f107 0308 add.w r3, r7, #8
+ 80004d0: 2206 movs r2, #6
+ 80004d2: 4619 mov r1, r3
+ 80004d4: 2026 movs r0, #38 ; 0x26
+ 80004d6: f000 fc55 bl 8000d84
+ regbuffer[0] &= 0x0F;
+ 80004da: 7a3b ldrb r3, [r7, #8]
+ 80004dc: f003 030f and.w r3, r3, #15
+ 80004e0: b2db uxtb r3, r3
+ 80004e2: 723b strb r3, [r7, #8]
+ regbuffer[0] |= (Channels>>8) & 0xF0;
+ 80004e4: 7a3a ldrb r2, [r7, #8]
+ 80004e6: 687b ldr r3, [r7, #4]
+ 80004e8: 0a1b lsrs r3, r3, #8
+ 80004ea: b2db uxtb r3, r3
+ 80004ec: f023 030f bic.w r3, r3, #15
+ 80004f0: b2db uxtb r3, r3
+ 80004f2: 4313 orrs r3, r2
+ 80004f4: b2db uxtb r3, r3
+ 80004f6: 723b strb r3, [r7, #8]
+ regbuffer[1] &= 0xFC;
+ 80004f8: 7a7b ldrb r3, [r7, #9]
+ 80004fa: f023 0303 bic.w r3, r3, #3
+ 80004fe: b2db uxtb r3, r3
+ 8000500: 727b strb r3, [r7, #9]
+ regbuffer[1] |= 0x03 & (Channels>>16);
+ 8000502: 7a7a ldrb r2, [r7, #9]
+ 8000504: 687b ldr r3, [r7, #4]
+ 8000506: 0c1b lsrs r3, r3, #16
+ 8000508: b2db uxtb r3, r3
+ 800050a: f003 0303 and.w r3, r3, #3
+ 800050e: b2db uxtb r3, r3
+ 8000510: 4313 orrs r3, r2
+ 8000512: b2db uxtb r3, r3
+ 8000514: 727b strb r3, [r7, #9]
+ writeCMD(WRCFGB, regbuffer, CFG_GROUP_B_SIZE);
+ 8000516: f107 0308 add.w r3, r7, #8
+ 800051a: 2206 movs r2, #6
+ 800051c: 4619 mov r1, r3
+ 800051e: 2024 movs r0, #36 ; 0x24
+ 8000520: f000 fba7 bl 8000c72
+
+ return 0;
+ 8000524: 2300 movs r3, #0
+}
+ 8000526: 4618 mov r0, r3
+ 8000528: 3710 adds r7, #16
+ 800052a: 46bd mov sp, r7
+ 800052c: bd80 pop {r7, pc}
+
+0800052e :
+
+uint8 amsStartBalancing(uint8 dutyCycle)
+{
+ 800052e: b580 push {r7, lr}
+ 8000530: b082 sub sp, #8
+ 8000532: af00 add r7, sp, #0
+ 8000534: 4603 mov r3, r0
+ 8000536: 71fb strb r3, [r7, #7]
+ writeCMD(UNMUTE, NULL, 0);
+ 8000538: 2200 movs r2, #0
+ 800053a: 2100 movs r1, #0
+ 800053c: 2029 movs r0, #41 ; 0x29
+ 800053e: f000 fb98 bl 8000c72
+ return 0;
+ 8000542: 2300 movs r3, #0
+}
+ 8000544: 4618 mov r0, r3
+ 8000546: 3708 adds r7, #8
+ 8000548: 46bd mov sp, r7
+ 800054a: bd80 pop {r7, pc}
+
+0800054c :
+
+uint8 amsStopBalancing()
+{
+ 800054c: b580 push {r7, lr}
+ 800054e: af00 add r7, sp, #0
+ writeCMD(MUTE, NULL, 0);
+ 8000550: 2200 movs r2, #0
+ 8000552: 2100 movs r1, #0
+ 8000554: 2028 movs r0, #40 ; 0x28
+ 8000556: f000 fb8c bl 8000c72
+ return 0;
+ 800055a: 2300 movs r3, #0
+}
+ 800055c: 4618 mov r0, r3
+ 800055e: bd80 pop {r7, pc}
+
+08000560 :
+}
+
+
+
+uint8 amsConfigUnderVoltage(uint16 underVoltage)
+{
+ 8000560: b580 push {r7, lr}
+ 8000562: b084 sub sp, #16
+ 8000564: af00 add r7, sp, #0
+ 8000566: 4603 mov r3, r0
+ 8000568: 80fb strh r3, [r7, #6]
+ uint8 buffer[CFG_GROUP_A_SIZE];
+ readCMD(RDCFGA, buffer, CFG_GROUP_A_SIZE);
+ 800056a: f107 0308 add.w r3, r7, #8
+ 800056e: 2206 movs r2, #6
+ 8000570: 4619 mov r1, r3
+ 8000572: 2002 movs r0, #2
+ 8000574: f000 fc06 bl 8000d84
+
+ buffer[1] = (uint8) underVoltage & 0xFF;
+ 8000578: 88fb ldrh r3, [r7, #6]
+ 800057a: b2db uxtb r3, r3
+ 800057c: 727b strb r3, [r7, #9]
+ uint8 ovuv = buffer[2] & 0xF0;
+ 800057e: 7abb ldrb r3, [r7, #10]
+ 8000580: f023 030f bic.w r3, r3, #15
+ 8000584: 73fb strb r3, [r7, #15]
+ ovuv |= (uint8) (underVoltage >> 8) & 0x0F;
+ 8000586: 88fb ldrh r3, [r7, #6]
+ 8000588: 0a1b lsrs r3, r3, #8
+ 800058a: b29b uxth r3, r3
+ 800058c: b25b sxtb r3, r3
+ 800058e: f003 030f and.w r3, r3, #15
+ 8000592: b25a sxtb r2, r3
+ 8000594: f997 300f ldrsb.w r3, [r7, #15]
+ 8000598: 4313 orrs r3, r2
+ 800059a: b25b sxtb r3, r3
+ 800059c: 73fb strb r3, [r7, #15]
+ buffer[2] = ovuv;
+ 800059e: 7bfb ldrb r3, [r7, #15]
+ 80005a0: 72bb strb r3, [r7, #10]
+
+ writeCMD(WRCFGA, buffer, CFG_GROUP_A_SIZE);
+ 80005a2: f107 0308 add.w r3, r7, #8
+ 80005a6: 2206 movs r2, #6
+ 80005a8: 4619 mov r1, r3
+ 80005aa: 2001 movs r0, #1
+ 80005ac: f000 fb61 bl 8000c72
+
+ return 0;
+ 80005b0: 2300 movs r3, #0
+}
+ 80005b2: 4618 mov r0, r3
+ 80005b4: 3710 adds r7, #16
+ 80005b6: 46bd mov sp, r7
+ 80005b8: bd80 pop {r7, pc}
+
+080005ba :
+
+uint8 amsCheckUnderOverVoltage(Cell_Module *module)
+{
+ 80005ba: b580 push {r7, lr}
+ 80005bc: b088 sub sp, #32
+ 80005be: af00 add r7, sp, #0
+ 80005c0: 6078 str r0, [r7, #4]
+ uint8 regbuffer[STATUS_GROUP_B_SIZE];
+ uint32 overundervoltages = 0;
+ 80005c2: 2300 movs r3, #0
+ 80005c4: 61bb str r3, [r7, #24]
+ readCMD(RDSTATB, regbuffer, STATUS_GROUP_B_SIZE);
+ 80005c6: f107 030c add.w r3, r7, #12
+ 80005ca: 2206 movs r2, #6
+ 80005cc: 4619 mov r1, r3
+ 80005ce: 2012 movs r0, #18
+ 80005d0: f000 fbd8 bl 8000d84
+ overundervoltages = regbuffer[2] | (regbuffer[3]<<8) | (regbuffer[4]<<16);
+ 80005d4: 7bbb ldrb r3, [r7, #14]
+ 80005d6: 461a mov r2, r3
+ 80005d8: 7bfb ldrb r3, [r7, #15]
+ 80005da: 021b lsls r3, r3, #8
+ 80005dc: 431a orrs r2, r3
+ 80005de: 7c3b ldrb r3, [r7, #16]
+ 80005e0: 041b lsls r3, r3, #16
+ 80005e2: 4313 orrs r3, r2
+ 80005e4: 61bb str r3, [r7, #24]
+ module->overVoltage = 0;
+ 80005e6: 687b ldr r3, [r7, #4]
+ 80005e8: 2200 movs r2, #0
+ 80005ea: 659a str r2, [r3, #88] ; 0x58
+ module->underVoltage = 0;
+ 80005ec: 687b ldr r3, [r7, #4]
+ 80005ee: 2200 movs r2, #0
+ 80005f0: 65da str r2, [r3, #92] ; 0x5c
+ for(uint8 n = 0; n < 12; n++)
+ 80005f2: 2300 movs r3, #0
+ 80005f4: 77fb strb r3, [r7, #31]
+ 80005f6: e027 b.n 8000648
+ {
+ uint8 overvolt = (overundervoltages>>(2*n+1)) & 0x01;
+ 80005f8: 7ffb ldrb r3, [r7, #31]
+ 80005fa: 005b lsls r3, r3, #1
+ 80005fc: 3301 adds r3, #1
+ 80005fe: 69ba ldr r2, [r7, #24]
+ 8000600: fa22 f303 lsr.w r3, r2, r3
+ 8000604: b2db uxtb r3, r3
+ 8000606: f003 0301 and.w r3, r3, #1
+ 800060a: 757b strb r3, [r7, #21]
+ uint8 undervolt = (overundervoltages>>(2*n))&0x01;
+ 800060c: 7ffb ldrb r3, [r7, #31]
+ 800060e: 005b lsls r3, r3, #1
+ 8000610: 69ba ldr r2, [r7, #24]
+ 8000612: fa22 f303 lsr.w r3, r2, r3
+ 8000616: b2db uxtb r3, r3
+ 8000618: f003 0301 and.w r3, r3, #1
+ 800061c: 753b strb r3, [r7, #20]
+
+ module->overVoltage |= overvolt<underVoltage |= undervolt<
+ }
+
+ readCMD(RDAUXD,regbuffer,AUX_GROUP_D_SIZE);
+ 800064e: f107 030c add.w r3, r7, #12
+ 8000652: 2206 movs r2, #6
+ 8000654: 4619 mov r1, r3
+ 8000656: 200f movs r0, #15
+ 8000658: f000 fb94 bl 8000d84
+ overundervoltages = 0;
+ 800065c: 2300 movs r3, #0
+ 800065e: 61bb str r3, [r7, #24]
+ overundervoltages = regbuffer[4] | (regbuffer[5]<<8);
+ 8000660: 7c3b ldrb r3, [r7, #16]
+ 8000662: 461a mov r2, r3
+ 8000664: 7c7b ldrb r3, [r7, #17]
+ 8000666: 021b lsls r3, r3, #8
+ 8000668: 4313 orrs r3, r2
+ 800066a: 61bb str r3, [r7, #24]
+
+ for(uint8 n = 0; n < 6; n++)
+ 800066c: 2300 movs r3, #0
+ 800066e: 77bb strb r3, [r7, #30]
+ 8000670: e029 b.n 80006c6
+ {
+ uint8 overvolt = (overundervoltages>>(2*n+1)) & 0x01;
+ 8000672: 7fbb ldrb r3, [r7, #30]
+ 8000674: 005b lsls r3, r3, #1
+ 8000676: 3301 adds r3, #1
+ 8000678: 69ba ldr r2, [r7, #24]
+ 800067a: fa22 f303 lsr.w r3, r2, r3
+ 800067e: b2db uxtb r3, r3
+ 8000680: f003 0301 and.w r3, r3, #1
+ 8000684: 75fb strb r3, [r7, #23]
+ uint8 undervolt = (overundervoltages>>(2*n))&0x01;
+ 8000686: 7fbb ldrb r3, [r7, #30]
+ 8000688: 005b lsls r3, r3, #1
+ 800068a: 69ba ldr r2, [r7, #24]
+ 800068c: fa22 f303 lsr.w r3, r2, r3
+ 8000690: b2db uxtb r3, r3
+ 8000692: f003 0301 and.w r3, r3, #1
+ 8000696: 75bb strb r3, [r7, #22]
+
+ module->overVoltage |= (uint32) overvolt<<(n+12);
+ 8000698: 687b ldr r3, [r7, #4]
+ 800069a: 6d9a ldr r2, [r3, #88] ; 0x58
+ 800069c: 7df9 ldrb r1, [r7, #23]
+ 800069e: 7fbb ldrb r3, [r7, #30]
+ 80006a0: 330c adds r3, #12
+ 80006a2: fa01 f303 lsl.w r3, r1, r3
+ 80006a6: 431a orrs r2, r3
+ 80006a8: 687b ldr r3, [r7, #4]
+ 80006aa: 659a str r2, [r3, #88] ; 0x58
+ module->underVoltage |= (uint32) undervolt<<(n+12);
+ 80006ac: 687b ldr r3, [r7, #4]
+ 80006ae: 6dda ldr r2, [r3, #92] ; 0x5c
+ 80006b0: 7db9 ldrb r1, [r7, #22]
+ 80006b2: 7fbb ldrb r3, [r7, #30]
+ 80006b4: 330c adds r3, #12
+ 80006b6: fa01 f303 lsl.w r3, r1, r3
+ 80006ba: 431a orrs r2, r3
+ 80006bc: 687b ldr r3, [r7, #4]
+ 80006be: 65da str r2, [r3, #92] ; 0x5c
+ for(uint8 n = 0; n < 6; n++)
+ 80006c0: 7fbb ldrb r3, [r7, #30]
+ 80006c2: 3301 adds r3, #1
+ 80006c4: 77bb strb r3, [r7, #30]
+ 80006c6: 7fbb ldrb r3, [r7, #30]
+ 80006c8: 2b05 cmp r3, #5
+ 80006ca: d9d2 bls.n 8000672
+ }
+
+
+ return 0;
+ 80006cc: 2300 movs r3, #0
+}
+ 80006ce: 4618 mov r0, r3
+ 80006d0: 3720 adds r7, #32
+ 80006d2: 46bd mov sp, r7
+ 80006d4: bd80 pop {r7, pc}
+
+080006d6 :
+
+uint8 amsConfigOverVoltage(uint16 overVoltage)
+{
+ 80006d6: b580 push {r7, lr}
+ 80006d8: b084 sub sp, #16
+ 80006da: af00 add r7, sp, #0
+ 80006dc: 4603 mov r3, r0
+ 80006de: 80fb strh r3, [r7, #6]
+ uint8 buffer[CFG_GROUP_B_SIZE];
+
+ readCMD(RDCFGA, buffer, CFG_GROUP_A_SIZE);
+ 80006e0: f107 0308 add.w r3, r7, #8
+ 80006e4: 2206 movs r2, #6
+ 80006e6: 4619 mov r1, r3
+ 80006e8: 2002 movs r0, #2
+ 80006ea: f000 fb4b bl 8000d84
+ buffer[2] &= 0x0F;
+ 80006ee: 7abb ldrb r3, [r7, #10]
+ 80006f0: f003 030f and.w r3, r3, #15
+ 80006f4: b2db uxtb r3, r3
+ 80006f6: 72bb strb r3, [r7, #10]
+ buffer[2] |= (uint8) overVoltage << 4;
+ 80006f8: 7abb ldrb r3, [r7, #10]
+ 80006fa: b25a sxtb r2, r3
+ 80006fc: 88fb ldrh r3, [r7, #6]
+ 80006fe: b2db uxtb r3, r3
+ 8000700: 011b lsls r3, r3, #4
+ 8000702: b25b sxtb r3, r3
+ 8000704: 4313 orrs r3, r2
+ 8000706: b25b sxtb r3, r3
+ 8000708: b2db uxtb r3, r3
+ 800070a: 72bb strb r3, [r7, #10]
+ buffer[3] = (uint8)(overVoltage>>4);
+ 800070c: 88fb ldrh r3, [r7, #6]
+ 800070e: 091b lsrs r3, r3, #4
+ 8000710: b29b uxth r3, r3
+ 8000712: b2db uxtb r3, r3
+ 8000714: 72fb strb r3, [r7, #11]
+
+ writeCMD(WRCFGA, buffer, CFG_GROUP_A_SIZE);
+ 8000716: f107 0308 add.w r3, r7, #8
+ 800071a: 2206 movs r2, #6
+ 800071c: 4619 mov r1, r3
+ 800071e: 2001 movs r0, #1
+ 8000720: f000 faa7 bl 8000c72
+
+ return 0;
+ 8000724: 2300 movs r3, #0
+}
+ 8000726: 4618 mov r0, r3
+ 8000728: 3710 adds r7, #16
+ 800072a: 46bd mov sp, r7
+ 800072c: bd80 pop {r7, pc}
+
+0800072e :
+ uint8 buffer[6];
+ writeCMD(CLRSTAT, buffer, 0);
+ return 0;
+}
+uint8 amsClearAux()
+{
+ 800072e: b580 push {r7, lr}
+ 8000730: b082 sub sp, #8
+ 8000732: af00 add r7, sp, #0
+ uint8 buffer[6];
+ writeCMD(CLRAUX, buffer, 0);
+ 8000734: 463b mov r3, r7
+ 8000736: 2200 movs r2, #0
+ 8000738: 4619 mov r1, r3
+ 800073a: f240 7012 movw r0, #1810 ; 0x712
+ 800073e: f000 fa98 bl 8000c72
+ return 0;
+ 8000742: 2300 movs r3, #0
+}
+ 8000744: 4618 mov r0, r3
+ 8000746: 3708 adds r7, #8
+ 8000748: 46bd mov sp, r7
+ 800074a: bd80 pop {r7, pc}
+
+0800074c :
+ //HAL_GPIO_WritePin(AMS_Error_GPIO_Port, AMS_Error_Pin, GPIO_PIN_SET);
+ return 0;
+}
+
+uint8 amsClearWarning()
+{
+ 800074c: b480 push {r7}
+ 800074e: af00 add r7, sp, #0
+ //HAL_GPIO_WritePin(AMS_Warning_GPIO_Port, AMS_Warning_Pin, GPIO_PIN_RESET);
+ return 0;
+ 8000750: 2300 movs r3, #0
+}
+ 8000752: 4618 mov r0, r3
+ 8000754: 46bd mov sp, r7
+ 8000756: f85d 7b04 ldr.w r7, [sp], #4
+ 800075a: 4770 bx lr
+
+0800075c :
+
+ return 0;
+}
+
+uint8 amsReadCellVoltages(Cell_Module *module)
+{
+ 800075c: b580 push {r7, lr}
+ 800075e: b084 sub sp, #16
+ 8000760: af00 add r7, sp, #0
+ 8000762: 6078 str r0, [r7, #4]
+ uint8 rxbuffer[CV_GROUP_A_SIZE];
+ readCMD(RDCVA, rxbuffer, CV_GROUP_A_SIZE);
+ 8000764: f107 0308 add.w r3, r7, #8
+ 8000768: 2206 movs r2, #6
+ 800076a: 4619 mov r1, r3
+ 800076c: 2004 movs r0, #4
+ 800076e: f000 fb09 bl 8000d84
+ module->cellVoltages[0] = rxbuffer[0] | (rxbuffer[1]<<8);
+ 8000772: 7a3b ldrb r3, [r7, #8]
+ 8000774: b21a sxth r2, r3
+ 8000776: 7a7b ldrb r3, [r7, #9]
+ 8000778: 021b lsls r3, r3, #8
+ 800077a: b21b sxth r3, r3
+ 800077c: 4313 orrs r3, r2
+ 800077e: b21b sxth r3, r3
+ 8000780: b29a uxth r2, r3
+ 8000782: 687b ldr r3, [r7, #4]
+ 8000784: 801a strh r2, [r3, #0]
+ module->cellVoltages[1] = rxbuffer[2] | (rxbuffer[3]<<8);
+ 8000786: 7abb ldrb r3, [r7, #10]
+ 8000788: b21a sxth r2, r3
+ 800078a: 7afb ldrb r3, [r7, #11]
+ 800078c: 021b lsls r3, r3, #8
+ 800078e: b21b sxth r3, r3
+ 8000790: 4313 orrs r3, r2
+ 8000792: b21b sxth r3, r3
+ 8000794: b29a uxth r2, r3
+ 8000796: 687b ldr r3, [r7, #4]
+ 8000798: 805a strh r2, [r3, #2]
+ module->cellVoltages[2] = rxbuffer[4] | (rxbuffer[5]<<8);
+ 800079a: 7b3b ldrb r3, [r7, #12]
+ 800079c: b21a sxth r2, r3
+ 800079e: 7b7b ldrb r3, [r7, #13]
+ 80007a0: 021b lsls r3, r3, #8
+ 80007a2: b21b sxth r3, r3
+ 80007a4: 4313 orrs r3, r2
+ 80007a6: b21b sxth r3, r3
+ 80007a8: b29a uxth r2, r3
+ 80007aa: 687b ldr r3, [r7, #4]
+ 80007ac: 809a strh r2, [r3, #4]
+
+ readCMD(RDCVB, rxbuffer, CV_GROUP_A_SIZE);
+ 80007ae: f107 0308 add.w r3, r7, #8
+ 80007b2: 2206 movs r2, #6
+ 80007b4: 4619 mov r1, r3
+ 80007b6: 2006 movs r0, #6
+ 80007b8: f000 fae4 bl 8000d84
+ module->cellVoltages[3] = rxbuffer[0] | (rxbuffer[1]<<8);
+ 80007bc: 7a3b ldrb r3, [r7, #8]
+ 80007be: b21a sxth r2, r3
+ 80007c0: 7a7b ldrb r3, [r7, #9]
+ 80007c2: 021b lsls r3, r3, #8
+ 80007c4: b21b sxth r3, r3
+ 80007c6: 4313 orrs r3, r2
+ 80007c8: b21b sxth r3, r3
+ 80007ca: b29a uxth r2, r3
+ 80007cc: 687b ldr r3, [r7, #4]
+ 80007ce: 80da strh r2, [r3, #6]
+ module->cellVoltages[4] = rxbuffer[2] | (rxbuffer[3]<<8);
+ 80007d0: 7abb ldrb r3, [r7, #10]
+ 80007d2: b21a sxth r2, r3
+ 80007d4: 7afb ldrb r3, [r7, #11]
+ 80007d6: 021b lsls r3, r3, #8
+ 80007d8: b21b sxth r3, r3
+ 80007da: 4313 orrs r3, r2
+ 80007dc: b21b sxth r3, r3
+ 80007de: b29a uxth r2, r3
+ 80007e0: 687b ldr r3, [r7, #4]
+ 80007e2: 811a strh r2, [r3, #8]
+ module->cellVoltages[5] = rxbuffer[4] | (rxbuffer[5]<<8);
+ 80007e4: 7b3b ldrb r3, [r7, #12]
+ 80007e6: b21a sxth r2, r3
+ 80007e8: 7b7b ldrb r3, [r7, #13]
+ 80007ea: 021b lsls r3, r3, #8
+ 80007ec: b21b sxth r3, r3
+ 80007ee: 4313 orrs r3, r2
+ 80007f0: b21b sxth r3, r3
+ 80007f2: b29a uxth r2, r3
+ 80007f4: 687b ldr r3, [r7, #4]
+ 80007f6: 815a strh r2, [r3, #10]
+
+ readCMD(RDCVC, rxbuffer, CV_GROUP_A_SIZE);
+ 80007f8: f107 0308 add.w r3, r7, #8
+ 80007fc: 2206 movs r2, #6
+ 80007fe: 4619 mov r1, r3
+ 8000800: 2008 movs r0, #8
+ 8000802: f000 fabf bl 8000d84
+ module->cellVoltages[6] = rxbuffer[0] | (rxbuffer[1]<<8);
+ 8000806: 7a3b ldrb r3, [r7, #8]
+ 8000808: b21a sxth r2, r3
+ 800080a: 7a7b ldrb r3, [r7, #9]
+ 800080c: 021b lsls r3, r3, #8
+ 800080e: b21b sxth r3, r3
+ 8000810: 4313 orrs r3, r2
+ 8000812: b21b sxth r3, r3
+ 8000814: b29a uxth r2, r3
+ 8000816: 687b ldr r3, [r7, #4]
+ 8000818: 819a strh r2, [r3, #12]
+ module->cellVoltages[7] = rxbuffer[2] | (rxbuffer[3]<<8);
+ 800081a: 7abb ldrb r3, [r7, #10]
+ 800081c: b21a sxth r2, r3
+ 800081e: 7afb ldrb r3, [r7, #11]
+ 8000820: 021b lsls r3, r3, #8
+ 8000822: b21b sxth r3, r3
+ 8000824: 4313 orrs r3, r2
+ 8000826: b21b sxth r3, r3
+ 8000828: b29a uxth r2, r3
+ 800082a: 687b ldr r3, [r7, #4]
+ 800082c: 81da strh r2, [r3, #14]
+ module->cellVoltages[8] = rxbuffer[4] | (rxbuffer[5]<<8);
+ 800082e: 7b3b ldrb r3, [r7, #12]
+ 8000830: b21a sxth r2, r3
+ 8000832: 7b7b ldrb r3, [r7, #13]
+ 8000834: 021b lsls r3, r3, #8
+ 8000836: b21b sxth r3, r3
+ 8000838: 4313 orrs r3, r2
+ 800083a: b21b sxth r3, r3
+ 800083c: b29a uxth r2, r3
+ 800083e: 687b ldr r3, [r7, #4]
+ 8000840: 821a strh r2, [r3, #16]
+
+ readCMD(RDCVD, rxbuffer, CV_GROUP_A_SIZE);
+ 8000842: f107 0308 add.w r3, r7, #8
+ 8000846: 2206 movs r2, #6
+ 8000848: 4619 mov r1, r3
+ 800084a: 200a movs r0, #10
+ 800084c: f000 fa9a bl 8000d84
+ module->cellVoltages[9] = rxbuffer[0] | (rxbuffer[1]<<8);
+ 8000850: 7a3b ldrb r3, [r7, #8]
+ 8000852: b21a sxth r2, r3
+ 8000854: 7a7b ldrb r3, [r7, #9]
+ 8000856: 021b lsls r3, r3, #8
+ 8000858: b21b sxth r3, r3
+ 800085a: 4313 orrs r3, r2
+ 800085c: b21b sxth r3, r3
+ 800085e: b29a uxth r2, r3
+ 8000860: 687b ldr r3, [r7, #4]
+ 8000862: 825a strh r2, [r3, #18]
+ module->cellVoltages[10] = rxbuffer[2] | (rxbuffer[3]<<8);
+ 8000864: 7abb ldrb r3, [r7, #10]
+ 8000866: b21a sxth r2, r3
+ 8000868: 7afb ldrb r3, [r7, #11]
+ 800086a: 021b lsls r3, r3, #8
+ 800086c: b21b sxth r3, r3
+ 800086e: 4313 orrs r3, r2
+ 8000870: b21b sxth r3, r3
+ 8000872: b29a uxth r2, r3
+ 8000874: 687b ldr r3, [r7, #4]
+ 8000876: 829a strh r2, [r3, #20]
+ module->cellVoltages[11] = rxbuffer[4] | (rxbuffer[5]<<8);
+ 8000878: 7b3b ldrb r3, [r7, #12]
+ 800087a: b21a sxth r2, r3
+ 800087c: 7b7b ldrb r3, [r7, #13]
+ 800087e: 021b lsls r3, r3, #8
+ 8000880: b21b sxth r3, r3
+ 8000882: 4313 orrs r3, r2
+ 8000884: b21b sxth r3, r3
+ 8000886: b29a uxth r2, r3
+ 8000888: 687b ldr r3, [r7, #4]
+ 800088a: 82da strh r2, [r3, #22]
+
+ readCMD(RDCVE, rxbuffer, CV_GROUP_A_SIZE);
+ 800088c: f107 0308 add.w r3, r7, #8
+ 8000890: 2206 movs r2, #6
+ 8000892: 4619 mov r1, r3
+ 8000894: 2009 movs r0, #9
+ 8000896: f000 fa75 bl 8000d84
+ module->cellVoltages[12] = rxbuffer[0] | (rxbuffer[1]<<8);
+ 800089a: 7a3b ldrb r3, [r7, #8]
+ 800089c: b21a sxth r2, r3
+ 800089e: 7a7b ldrb r3, [r7, #9]
+ 80008a0: 021b lsls r3, r3, #8
+ 80008a2: b21b sxth r3, r3
+ 80008a4: 4313 orrs r3, r2
+ 80008a6: b21b sxth r3, r3
+ 80008a8: b29a uxth r2, r3
+ 80008aa: 687b ldr r3, [r7, #4]
+ 80008ac: 831a strh r2, [r3, #24]
+ module->cellVoltages[13] = rxbuffer[2] | (rxbuffer[3]<<8);
+ 80008ae: 7abb ldrb r3, [r7, #10]
+ 80008b0: b21a sxth r2, r3
+ 80008b2: 7afb ldrb r3, [r7, #11]
+ 80008b4: 021b lsls r3, r3, #8
+ 80008b6: b21b sxth r3, r3
+ 80008b8: 4313 orrs r3, r2
+ 80008ba: b21b sxth r3, r3
+ 80008bc: b29a uxth r2, r3
+ 80008be: 687b ldr r3, [r7, #4]
+ 80008c0: 835a strh r2, [r3, #26]
+ module->cellVoltages[14] = rxbuffer[4] | (rxbuffer[5]<<8);
+ 80008c2: 7b3b ldrb r3, [r7, #12]
+ 80008c4: b21a sxth r2, r3
+ 80008c6: 7b7b ldrb r3, [r7, #13]
+ 80008c8: 021b lsls r3, r3, #8
+ 80008ca: b21b sxth r3, r3
+ 80008cc: 4313 orrs r3, r2
+ 80008ce: b21b sxth r3, r3
+ 80008d0: b29a uxth r2, r3
+ 80008d2: 687b ldr r3, [r7, #4]
+ 80008d4: 839a strh r2, [r3, #28]
+
+ readCMD(RDCVF, rxbuffer, CV_GROUP_A_SIZE);
+ 80008d6: f107 0308 add.w r3, r7, #8
+ 80008da: 2206 movs r2, #6
+ 80008dc: 4619 mov r1, r3
+ 80008de: 200b movs r0, #11
+ 80008e0: f000 fa50 bl 8000d84
+ module->cellVoltages[15] = rxbuffer[0] | (rxbuffer[1]<<8);
+ 80008e4: 7a3b ldrb r3, [r7, #8]
+ 80008e6: b21a sxth r2, r3
+ 80008e8: 7a7b ldrb r3, [r7, #9]
+ 80008ea: 021b lsls r3, r3, #8
+ 80008ec: b21b sxth r3, r3
+ 80008ee: 4313 orrs r3, r2
+ 80008f0: b21b sxth r3, r3
+ 80008f2: b29a uxth r2, r3
+ 80008f4: 687b ldr r3, [r7, #4]
+ 80008f6: 83da strh r2, [r3, #30]
+ module->cellVoltages[16] = rxbuffer[2] | (rxbuffer[3]<<8);
+ 80008f8: 7abb ldrb r3, [r7, #10]
+ 80008fa: b21a sxth r2, r3
+ 80008fc: 7afb ldrb r3, [r7, #11]
+ 80008fe: 021b lsls r3, r3, #8
+ 8000900: b21b sxth r3, r3
+ 8000902: 4313 orrs r3, r2
+ 8000904: b21b sxth r3, r3
+ 8000906: b29a uxth r2, r3
+ 8000908: 687b ldr r3, [r7, #4]
+ 800090a: 841a strh r2, [r3, #32]
+ module->cellVoltages[17] = rxbuffer[4] | (rxbuffer[5]<<8);
+ 800090c: 7b3b ldrb r3, [r7, #12]
+ 800090e: b21a sxth r2, r3
+ 8000910: 7b7b ldrb r3, [r7, #13]
+ 8000912: 021b lsls r3, r3, #8
+ 8000914: b21b sxth r3, r3
+ 8000916: 4313 orrs r3, r2
+ 8000918: b21b sxth r3, r3
+ 800091a: b29a uxth r2, r3
+ 800091c: 687b ldr r3, [r7, #4]
+ 800091e: 845a strh r2, [r3, #34] ; 0x22
+
+ return 0;
+ 8000920: 2300 movs r3, #0
+}
+ 8000922: 4618 mov r0, r3
+ 8000924: 3710 adds r7, #16
+ 8000926: 46bd mov sp, r7
+ 8000928: bd80 pop {r7, pc}
+ ...
+
+0800092c :
+#define ADBMS_SPI_TIMEOUT 1000 //Timeout in ms
+
+SPI_HandleTypeDef* adbmsspi;
+
+uint8 adbmsDriverInit(SPI_HandleTypeDef* hspi)
+{
+ 800092c: b580 push {r7, lr}
+ 800092e: b082 sub sp, #8
+ 8000930: af00 add r7, sp, #0
+ 8000932: 6078 str r0, [r7, #4]
+ mcuAdbmsCSLow();
+ 8000934: f000 fad8 bl 8000ee8
+ HAL_Delay(1);
+ 8000938: 2001 movs r0, #1
+ 800093a: f001 fc9f bl 800227c
+ mcuAdbmsCSHigh();
+ 800093e: f000 fadd bl 8000efc
+ adbmsspi = hspi;
+ 8000942: 4a04 ldr r2, [pc, #16] ; (8000954 )
+ 8000944: 687b ldr r3, [r7, #4]
+ 8000946: 6013 str r3, [r2, #0]
+ return 0;
+ 8000948: 2300 movs r3, #0
+}
+ 800094a: 4618 mov r0, r3
+ 800094c: 3708 adds r7, #8
+ 800094e: 46bd mov sp, r7
+ 8000950: bd80 pop {r7, pc}
+ 8000952: bf00 nop
+ 8000954: 20000038 .word 0x20000038
+
+08000958 :
+
+uint8 calculatePEC(uint8_t* data, uint8_t datalen)
+{
+ 8000958: b580 push {r7, lr}
+ 800095a: b086 sub sp, #24
+ 800095c: af00 add r7, sp, #0
+ 800095e: 6078 str r0, [r7, #4]
+ 8000960: 460b mov r3, r1
+ 8000962: 70fb strb r3, [r7, #3]
+ uint16 currentpec = INITAL_PEC;
+ 8000964: 2310 movs r3, #16
+ 8000966: 82fb strh r3, [r7, #22]
+ if(datalen >= 3)
+ 8000968: 78fb ldrb r3, [r7, #3]
+ 800096a: 2b02 cmp r3, #2
+ 800096c: d937 bls.n 80009de
+ {
+ for(int i = 0; i < (datalen-2); i++)
+ 800096e: 2300 movs r3, #0
+ 8000970: 613b str r3, [r7, #16]
+ 8000972: e01c b.n 80009ae
+ {
+ for(int n = 0; n < 8;n++)
+ 8000974: 2300 movs r3, #0
+ 8000976: 60fb str r3, [r7, #12]
+ 8000978: e013 b.n 80009a2
+ {
+ uint8 din = data[i] << (n);
+ 800097a: 693b ldr r3, [r7, #16]
+ 800097c: 687a ldr r2, [r7, #4]
+ 800097e: 4413 add r3, r2
+ 8000980: 781b ldrb r3, [r3, #0]
+ 8000982: 461a mov r2, r3
+ 8000984: 68fb ldr r3, [r7, #12]
+ 8000986: fa02 f303 lsl.w r3, r2, r3
+ 800098a: 72fb strb r3, [r7, #11]
+ currentpec = updatePEC(currentpec, din);
+ 800098c: 7afa ldrb r2, [r7, #11]
+ 800098e: 8afb ldrh r3, [r7, #22]
+ 8000990: 4611 mov r1, r2
+ 8000992: 4618 mov r0, r3
+ 8000994: f000 f878 bl 8000a88
+ 8000998: 4603 mov r3, r0
+ 800099a: 82fb strh r3, [r7, #22]
+ for(int n = 0; n < 8;n++)
+ 800099c: 68fb ldr r3, [r7, #12]
+ 800099e: 3301 adds r3, #1
+ 80009a0: 60fb str r3, [r7, #12]
+ 80009a2: 68fb ldr r3, [r7, #12]
+ 80009a4: 2b07 cmp r3, #7
+ 80009a6: dde8 ble.n 800097a
+ for(int i = 0; i < (datalen-2); i++)
+ 80009a8: 693b ldr r3, [r7, #16]
+ 80009aa: 3301 adds r3, #1
+ 80009ac: 613b str r3, [r7, #16]
+ 80009ae: 78fb ldrb r3, [r7, #3]
+ 80009b0: 3b02 subs r3, #2
+ 80009b2: 693a ldr r2, [r7, #16]
+ 80009b4: 429a cmp r2, r3
+ 80009b6: dbdd blt.n 8000974
+ }
+ }
+
+ data[datalen-2] = (currentpec>>7) & 0xFF;
+ 80009b8: 8afb ldrh r3, [r7, #22]
+ 80009ba: 09db lsrs r3, r3, #7
+ 80009bc: b299 uxth r1, r3
+ 80009be: 78fb ldrb r3, [r7, #3]
+ 80009c0: 3b02 subs r3, #2
+ 80009c2: 687a ldr r2, [r7, #4]
+ 80009c4: 4413 add r3, r2
+ 80009c6: b2ca uxtb r2, r1
+ 80009c8: 701a strb r2, [r3, #0]
+ data[datalen-1] = (currentpec<<1) & 0xFF;
+ 80009ca: 8afb ldrh r3, [r7, #22]
+ 80009cc: 0059 lsls r1, r3, #1
+ 80009ce: 78fb ldrb r3, [r7, #3]
+ 80009d0: 3b01 subs r3, #1
+ 80009d2: 687a ldr r2, [r7, #4]
+ 80009d4: 4413 add r3, r2
+ 80009d6: b2ca uxtb r2, r1
+ 80009d8: 701a strb r2, [r3, #0]
+ return 0;
+ 80009da: 2300 movs r3, #0
+ 80009dc: e000 b.n 80009e0
+ }
+
+ else
+ {
+ return 1;
+ 80009de: 2301 movs r3, #1
+ }
+}
+ 80009e0: 4618 mov r0, r3
+ 80009e2: 3718 adds r7, #24
+ 80009e4: 46bd mov sp, r7
+ 80009e6: bd80 pop {r7, pc}
+
+080009e8 :
+
+uint8 checkPEC(uint8* data, uint8 datalen)
+{
+ 80009e8: b580 push {r7, lr}
+ 80009ea: b086 sub sp, #24
+ 80009ec: af00 add r7, sp, #0
+ 80009ee: 6078 str r0, [r7, #4]
+ 80009f0: 460b mov r3, r1
+ 80009f2: 70fb strb r3, [r7, #3]
+ if(datalen <= 3)
+ 80009f4: 78fb ldrb r3, [r7, #3]
+ 80009f6: 2b03 cmp r3, #3
+ 80009f8: d801 bhi.n 80009fe
+ {
+ return 255;
+ 80009fa: 23ff movs r3, #255 ; 0xff
+ 80009fc: e040 b.n 8000a80
+ }
+
+ uint16 currentpec = INITAL_PEC;
+ 80009fe: 2310 movs r3, #16
+ 8000a00: 82fb strh r3, [r7, #22]
+
+ for(int i = 0; i < (datalen-2); i++)
+ 8000a02: 2300 movs r3, #0
+ 8000a04: 613b str r3, [r7, #16]
+ 8000a06: e01c b.n 8000a42
+ {
+ for(int n = 0; n < 8;n++)
+ 8000a08: 2300 movs r3, #0
+ 8000a0a: 60fb str r3, [r7, #12]
+ 8000a0c: e013 b.n 8000a36
+ {
+ uint8 din = data[i] << (n);
+ 8000a0e: 693b ldr r3, [r7, #16]
+ 8000a10: 687a ldr r2, [r7, #4]
+ 8000a12: 4413 add r3, r2
+ 8000a14: 781b ldrb r3, [r3, #0]
+ 8000a16: 461a mov r2, r3
+ 8000a18: 68fb ldr r3, [r7, #12]
+ 8000a1a: fa02 f303 lsl.w r3, r2, r3
+ 8000a1e: 727b strb r3, [r7, #9]
+ currentpec = updatePEC(currentpec, din);
+ 8000a20: 7a7a ldrb r2, [r7, #9]
+ 8000a22: 8afb ldrh r3, [r7, #22]
+ 8000a24: 4611 mov r1, r2
+ 8000a26: 4618 mov r0, r3
+ 8000a28: f000 f82e bl 8000a88
+ 8000a2c: 4603 mov r3, r0
+ 8000a2e: 82fb strh r3, [r7, #22]
+ for(int n = 0; n < 8;n++)
+ 8000a30: 68fb ldr r3, [r7, #12]
+ 8000a32: 3301 adds r3, #1
+ 8000a34: 60fb str r3, [r7, #12]
+ 8000a36: 68fb ldr r3, [r7, #12]
+ 8000a38: 2b07 cmp r3, #7
+ 8000a3a: dde8 ble.n 8000a0e
+ for(int i = 0; i < (datalen-2); i++)
+ 8000a3c: 693b ldr r3, [r7, #16]
+ 8000a3e: 3301 adds r3, #1
+ 8000a40: 613b str r3, [r7, #16]
+ 8000a42: 78fb ldrb r3, [r7, #3]
+ 8000a44: 3b02 subs r3, #2
+ 8000a46: 693a ldr r2, [r7, #16]
+ 8000a48: 429a cmp r2, r3
+ 8000a4a: dbdd blt.n 8000a08
+ }
+ }
+
+ uint8 pechigh = (currentpec>>7) & 0xFF;
+ 8000a4c: 8afb ldrh r3, [r7, #22]
+ 8000a4e: 09db lsrs r3, r3, #7
+ 8000a50: b29b uxth r3, r3
+ 8000a52: 72fb strb r3, [r7, #11]
+ uint8 peclow = (currentpec<<1) & 0xFF;
+ 8000a54: 8afb ldrh r3, [r7, #22]
+ 8000a56: 005b lsls r3, r3, #1
+ 8000a58: 72bb strb r3, [r7, #10]
+
+ if((pechigh == data[datalen-2]) && (peclow == data[datalen-1]))
+ 8000a5a: 78fb ldrb r3, [r7, #3]
+ 8000a5c: 3b02 subs r3, #2
+ 8000a5e: 687a ldr r2, [r7, #4]
+ 8000a60: 4413 add r3, r2
+ 8000a62: 781b ldrb r3, [r3, #0]
+ 8000a64: 7afa ldrb r2, [r7, #11]
+ 8000a66: 429a cmp r2, r3
+ 8000a68: d109 bne.n 8000a7e
+ 8000a6a: 78fb ldrb r3, [r7, #3]
+ 8000a6c: 3b01 subs r3, #1
+ 8000a6e: 687a ldr r2, [r7, #4]
+ 8000a70: 4413 add r3, r2
+ 8000a72: 781b ldrb r3, [r3, #0]
+ 8000a74: 7aba ldrb r2, [r7, #10]
+ 8000a76: 429a cmp r2, r3
+ 8000a78: d101 bne.n 8000a7e
+ {
+ return 0;
+ 8000a7a: 2300 movs r3, #0
+ 8000a7c: e000 b.n 8000a80
+ }
+
+ return 1;
+ 8000a7e: 2301 movs r3, #1
+
+}
+ 8000a80: 4618 mov r0, r3
+ 8000a82: 3718 adds r7, #24
+ 8000a84: 46bd mov sp, r7
+ 8000a86: bd80 pop {r7, pc}
+
+08000a88 :
+
+uint16 updatePEC(uint16 currentPEC, uint8 din)
+{
+ 8000a88: b480 push {r7}
+ 8000a8a: b087 sub sp, #28
+ 8000a8c: af00 add r7, sp, #0
+ 8000a8e: 4603 mov r3, r0
+ 8000a90: 460a mov r2, r1
+ 8000a92: 80fb strh r3, [r7, #6]
+ 8000a94: 4613 mov r3, r2
+ 8000a96: 717b strb r3, [r7, #5]
+ din = (din>>7) & 0x01;
+ 8000a98: 797b ldrb r3, [r7, #5]
+ 8000a9a: 09db lsrs r3, r3, #7
+ 8000a9c: 717b strb r3, [r7, #5]
+ uint8 in0 = din ^ ((currentPEC >> 14) &0x01);
+ 8000a9e: 88fb ldrh r3, [r7, #6]
+ 8000aa0: 0b9b lsrs r3, r3, #14
+ 8000aa2: b29b uxth r3, r3
+ 8000aa4: b25b sxtb r3, r3
+ 8000aa6: f003 0301 and.w r3, r3, #1
+ 8000aaa: b25a sxtb r2, r3
+ 8000aac: f997 3005 ldrsb.w r3, [r7, #5]
+ 8000ab0: 4053 eors r3, r2
+ 8000ab2: b25b sxtb r3, r3
+ 8000ab4: 75fb strb r3, [r7, #23]
+ uint8 in3 = in0 ^ ((currentPEC >> 2) &0x01);
+ 8000ab6: 88fb ldrh r3, [r7, #6]
+ 8000ab8: 089b lsrs r3, r3, #2
+ 8000aba: b29b uxth r3, r3
+ 8000abc: b25b sxtb r3, r3
+ 8000abe: f003 0301 and.w r3, r3, #1
+ 8000ac2: b25a sxtb r2, r3
+ 8000ac4: f997 3017 ldrsb.w r3, [r7, #23]
+ 8000ac8: 4053 eors r3, r2
+ 8000aca: b25b sxtb r3, r3
+ 8000acc: 75bb strb r3, [r7, #22]
+ uint8 in4 = in0 ^ ((currentPEC >> 3) &0x01);
+ 8000ace: 88fb ldrh r3, [r7, #6]
+ 8000ad0: 08db lsrs r3, r3, #3
+ 8000ad2: b29b uxth r3, r3
+ 8000ad4: b25b sxtb r3, r3
+ 8000ad6: f003 0301 and.w r3, r3, #1
+ 8000ada: b25a sxtb r2, r3
+ 8000adc: f997 3017 ldrsb.w r3, [r7, #23]
+ 8000ae0: 4053 eors r3, r2
+ 8000ae2: b25b sxtb r3, r3
+ 8000ae4: 757b strb r3, [r7, #21]
+ uint8 in7 = in0 ^ ((currentPEC >> 6) &0x01);
+ 8000ae6: 88fb ldrh r3, [r7, #6]
+ 8000ae8: 099b lsrs r3, r3, #6
+ 8000aea: b29b uxth r3, r3
+ 8000aec: b25b sxtb r3, r3
+ 8000aee: f003 0301 and.w r3, r3, #1
+ 8000af2: b25a sxtb r2, r3
+ 8000af4: f997 3017 ldrsb.w r3, [r7, #23]
+ 8000af8: 4053 eors r3, r2
+ 8000afa: b25b sxtb r3, r3
+ 8000afc: 753b strb r3, [r7, #20]
+ uint8 in8 = in0 ^ ((currentPEC >> 7) &0x01);
+ 8000afe: 88fb ldrh r3, [r7, #6]
+ 8000b00: 09db lsrs r3, r3, #7
+ 8000b02: b29b uxth r3, r3
+ 8000b04: b25b sxtb r3, r3
+ 8000b06: f003 0301 and.w r3, r3, #1
+ 8000b0a: b25a sxtb r2, r3
+ 8000b0c: f997 3017 ldrsb.w r3, [r7, #23]
+ 8000b10: 4053 eors r3, r2
+ 8000b12: b25b sxtb r3, r3
+ 8000b14: 74fb strb r3, [r7, #19]
+ uint8 in10 = in0 ^ ((currentPEC >> 9) &0x01);
+ 8000b16: 88fb ldrh r3, [r7, #6]
+ 8000b18: 0a5b lsrs r3, r3, #9
+ 8000b1a: b29b uxth r3, r3
+ 8000b1c: b25b sxtb r3, r3
+ 8000b1e: f003 0301 and.w r3, r3, #1
+ 8000b22: b25a sxtb r2, r3
+ 8000b24: f997 3017 ldrsb.w r3, [r7, #23]
+ 8000b28: 4053 eors r3, r2
+ 8000b2a: b25b sxtb r3, r3
+ 8000b2c: 74bb strb r3, [r7, #18]
+ uint8 in14 = in0 ^ ((currentPEC >> 13) &0x01);
+ 8000b2e: 88fb ldrh r3, [r7, #6]
+ 8000b30: 0b5b lsrs r3, r3, #13
+ 8000b32: b29b uxth r3, r3
+ 8000b34: b25b sxtb r3, r3
+ 8000b36: f003 0301 and.w r3, r3, #1
+ 8000b3a: b25a sxtb r2, r3
+ 8000b3c: f997 3017 ldrsb.w r3, [r7, #23]
+ 8000b40: 4053 eors r3, r2
+ 8000b42: b25b sxtb r3, r3
+ 8000b44: 747b strb r3, [r7, #17]
+
+ uint16 newPEC = 0;
+ 8000b46: 2300 movs r3, #0
+ 8000b48: 81fb strh r3, [r7, #14]
+
+ newPEC |= in14<<14;
+ 8000b4a: 7c7b ldrb r3, [r7, #17]
+ 8000b4c: 039b lsls r3, r3, #14
+ 8000b4e: b21a sxth r2, r3
+ 8000b50: f9b7 300e ldrsh.w r3, [r7, #14]
+ 8000b54: 4313 orrs r3, r2
+ 8000b56: b21b sxth r3, r3
+ 8000b58: 81fb strh r3, [r7, #14]
+ newPEC |= (currentPEC & (0x01<<12))<<1;
+ 8000b5a: 88fb ldrh r3, [r7, #6]
+ 8000b5c: 005b lsls r3, r3, #1
+ 8000b5e: b21b sxth r3, r3
+ 8000b60: f403 5300 and.w r3, r3, #8192 ; 0x2000
+ 8000b64: b21a sxth r2, r3
+ 8000b66: f9b7 300e ldrsh.w r3, [r7, #14]
+ 8000b6a: 4313 orrs r3, r2
+ 8000b6c: b21b sxth r3, r3
+ 8000b6e: 81fb strh r3, [r7, #14]
+ newPEC |= (currentPEC & (0x01<<11))<<1;
+ 8000b70: 88fb ldrh r3, [r7, #6]
+ 8000b72: 005b lsls r3, r3, #1
+ 8000b74: b21b sxth r3, r3
+ 8000b76: f403 5380 and.w r3, r3, #4096 ; 0x1000
+ 8000b7a: b21a sxth r2, r3
+ 8000b7c: f9b7 300e ldrsh.w r3, [r7, #14]
+ 8000b80: 4313 orrs r3, r2
+ 8000b82: b21b sxth r3, r3
+ 8000b84: 81fb strh r3, [r7, #14]
+ newPEC |= (currentPEC & (0x01<<10))<<1;
+ 8000b86: 88fb ldrh r3, [r7, #6]
+ 8000b88: 005b lsls r3, r3, #1
+ 8000b8a: b21b sxth r3, r3
+ 8000b8c: f403 6300 and.w r3, r3, #2048 ; 0x800
+ 8000b90: b21a sxth r2, r3
+ 8000b92: f9b7 300e ldrsh.w r3, [r7, #14]
+ 8000b96: 4313 orrs r3, r2
+ 8000b98: b21b sxth r3, r3
+ 8000b9a: 81fb strh r3, [r7, #14]
+ newPEC |= in10<<10;
+ 8000b9c: 7cbb ldrb r3, [r7, #18]
+ 8000b9e: 029b lsls r3, r3, #10
+ 8000ba0: b21a sxth r2, r3
+ 8000ba2: f9b7 300e ldrsh.w r3, [r7, #14]
+ 8000ba6: 4313 orrs r3, r2
+ 8000ba8: b21b sxth r3, r3
+ 8000baa: 81fb strh r3, [r7, #14]
+ newPEC |= (currentPEC & (0x01<<8))<<1;
+ 8000bac: 88fb ldrh r3, [r7, #6]
+ 8000bae: 005b lsls r3, r3, #1
+ 8000bb0: b21b sxth r3, r3
+ 8000bb2: f403 7300 and.w r3, r3, #512 ; 0x200
+ 8000bb6: b21a sxth r2, r3
+ 8000bb8: f9b7 300e ldrsh.w r3, [r7, #14]
+ 8000bbc: 4313 orrs r3, r2
+ 8000bbe: b21b sxth r3, r3
+ 8000bc0: 81fb strh r3, [r7, #14]
+ newPEC |= in8<<8;
+ 8000bc2: 7cfb ldrb r3, [r7, #19]
+ 8000bc4: 021b lsls r3, r3, #8
+ 8000bc6: b21a sxth r2, r3
+ 8000bc8: f9b7 300e ldrsh.w r3, [r7, #14]
+ 8000bcc: 4313 orrs r3, r2
+ 8000bce: b21b sxth r3, r3
+ 8000bd0: 81fb strh r3, [r7, #14]
+ newPEC |= in7<<7;
+ 8000bd2: 7d3b ldrb r3, [r7, #20]
+ 8000bd4: 01db lsls r3, r3, #7
+ 8000bd6: b21a sxth r2, r3
+ 8000bd8: f9b7 300e ldrsh.w r3, [r7, #14]
+ 8000bdc: 4313 orrs r3, r2
+ 8000bde: b21b sxth r3, r3
+ 8000be0: 81fb strh r3, [r7, #14]
+ newPEC |= (currentPEC & (0x01<<5))<<1;
+ 8000be2: 88fb ldrh r3, [r7, #6]
+ 8000be4: 005b lsls r3, r3, #1
+ 8000be6: b21b sxth r3, r3
+ 8000be8: f003 0340 and.w r3, r3, #64 ; 0x40
+ 8000bec: b21a sxth r2, r3
+ 8000bee: f9b7 300e ldrsh.w r3, [r7, #14]
+ 8000bf2: 4313 orrs r3, r2
+ 8000bf4: b21b sxth r3, r3
+ 8000bf6: 81fb strh r3, [r7, #14]
+ newPEC |= (currentPEC & (0x01<<4))<<1;
+ 8000bf8: 88fb ldrh r3, [r7, #6]
+ 8000bfa: 005b lsls r3, r3, #1
+ 8000bfc: b21b sxth r3, r3
+ 8000bfe: f003 0320 and.w r3, r3, #32
+ 8000c02: b21a sxth r2, r3
+ 8000c04: f9b7 300e ldrsh.w r3, [r7, #14]
+ 8000c08: 4313 orrs r3, r2
+ 8000c0a: b21b sxth r3, r3
+ 8000c0c: 81fb strh r3, [r7, #14]
+ newPEC |= in4<<4;
+ 8000c0e: 7d7b ldrb r3, [r7, #21]
+ 8000c10: 011b lsls r3, r3, #4
+ 8000c12: b21a sxth r2, r3
+ 8000c14: f9b7 300e ldrsh.w r3, [r7, #14]
+ 8000c18: 4313 orrs r3, r2
+ 8000c1a: b21b sxth r3, r3
+ 8000c1c: 81fb strh r3, [r7, #14]
+ newPEC |= in3<<3;
+ 8000c1e: 7dbb ldrb r3, [r7, #22]
+ 8000c20: 00db lsls r3, r3, #3
+ 8000c22: b21a sxth r2, r3
+ 8000c24: f9b7 300e ldrsh.w r3, [r7, #14]
+ 8000c28: 4313 orrs r3, r2
+ 8000c2a: b21b sxth r3, r3
+ 8000c2c: 81fb strh r3, [r7, #14]
+ newPEC |= (currentPEC & (0x01<<1))<<1;
+ 8000c2e: 88fb ldrh r3, [r7, #6]
+ 8000c30: 005b lsls r3, r3, #1
+ 8000c32: b21b sxth r3, r3
+ 8000c34: f003 0304 and.w r3, r3, #4
+ 8000c38: b21a sxth r2, r3
+ 8000c3a: f9b7 300e ldrsh.w r3, [r7, #14]
+ 8000c3e: 4313 orrs r3, r2
+ 8000c40: b21b sxth r3, r3
+ 8000c42: 81fb strh r3, [r7, #14]
+ newPEC |= (currentPEC & (0x01))<<1;
+ 8000c44: 88fb ldrh r3, [r7, #6]
+ 8000c46: 005b lsls r3, r3, #1
+ 8000c48: b21b sxth r3, r3
+ 8000c4a: f003 0302 and.w r3, r3, #2
+ 8000c4e: b21a sxth r2, r3
+ 8000c50: f9b7 300e ldrsh.w r3, [r7, #14]
+ 8000c54: 4313 orrs r3, r2
+ 8000c56: b21b sxth r3, r3
+ 8000c58: 81fb strh r3, [r7, #14]
+ newPEC |= in0;
+ 8000c5a: 7dfb ldrb r3, [r7, #23]
+ 8000c5c: b29a uxth r2, r3
+ 8000c5e: 89fb ldrh r3, [r7, #14]
+ 8000c60: 4313 orrs r3, r2
+ 8000c62: 81fb strh r3, [r7, #14]
+
+
+ return newPEC;
+ 8000c64: 89fb ldrh r3, [r7, #14]
+}
+ 8000c66: 4618 mov r0, r3
+ 8000c68: 371c adds r7, #28
+ 8000c6a: 46bd mov sp, r7
+ 8000c6c: f85d 7b04 ldr.w r7, [sp], #4
+ 8000c70: 4770 bx lr
+
+08000c72 :
+
+uint8 writeCMD(uint16 command, uint8* args, uint8 arglen)
+{
+ 8000c72: e92d 43f0 stmdb sp!, {r4, r5, r6, r7, r8, r9, lr}
+ 8000c76: b087 sub sp, #28
+ 8000c78: af00 add r7, sp, #0
+ 8000c7a: 4603 mov r3, r0
+ 8000c7c: 6039 str r1, [r7, #0]
+ 8000c7e: 80fb strh r3, [r7, #6]
+ 8000c80: 4613 mov r3, r2
+ 8000c82: 717b strb r3, [r7, #5]
+ if(arglen > 0)
+ 8000c84: 797b ldrb r3, [r7, #5]
+ 8000c86: 2b00 cmp r3, #0
+ 8000c88: d05e beq.n 8000d48
+ {
+ 8000c8a: 466b mov r3, sp
+ 8000c8c: 461e mov r6, r3
+ uint8 buffer[6+arglen];
+ 8000c8e: 797b ldrb r3, [r7, #5]
+ 8000c90: 1d99 adds r1, r3, #6
+ 8000c92: 1e4b subs r3, r1, #1
+ 8000c94: 613b str r3, [r7, #16]
+ 8000c96: 460a mov r2, r1
+ 8000c98: 2300 movs r3, #0
+ 8000c9a: 4690 mov r8, r2
+ 8000c9c: 4699 mov r9, r3
+ 8000c9e: f04f 0200 mov.w r2, #0
+ 8000ca2: f04f 0300 mov.w r3, #0
+ 8000ca6: ea4f 03c9 mov.w r3, r9, lsl #3
+ 8000caa: ea43 7358 orr.w r3, r3, r8, lsr #29
+ 8000cae: ea4f 02c8 mov.w r2, r8, lsl #3
+ 8000cb2: 460a mov r2, r1
+ 8000cb4: 2300 movs r3, #0
+ 8000cb6: 4614 mov r4, r2
+ 8000cb8: 461d mov r5, r3
+ 8000cba: f04f 0200 mov.w r2, #0
+ 8000cbe: f04f 0300 mov.w r3, #0
+ 8000cc2: 00eb lsls r3, r5, #3
+ 8000cc4: ea43 7354 orr.w r3, r3, r4, lsr #29
+ 8000cc8: 00e2 lsls r2, r4, #3
+ 8000cca: 460b mov r3, r1
+ 8000ccc: 3307 adds r3, #7
+ 8000cce: 08db lsrs r3, r3, #3
+ 8000cd0: 00db lsls r3, r3, #3
+ 8000cd2: ebad 0d03 sub.w sp, sp, r3
+ 8000cd6: 466b mov r3, sp
+ 8000cd8: 3300 adds r3, #0
+ 8000cda: 60fb str r3, [r7, #12]
+ buffer[0] = (command >> 8) & 0xFF;
+ 8000cdc: 88fb ldrh r3, [r7, #6]
+ 8000cde: 0a1b lsrs r3, r3, #8
+ 8000ce0: b29b uxth r3, r3
+ 8000ce2: b2da uxtb r2, r3
+ 8000ce4: 68fb ldr r3, [r7, #12]
+ 8000ce6: 701a strb r2, [r3, #0]
+ buffer[1] = (command) & 0xFF;
+ 8000ce8: 88fb ldrh r3, [r7, #6]
+ 8000cea: b2da uxtb r2, r3
+ 8000cec: 68fb ldr r3, [r7, #12]
+ 8000cee: 705a strb r2, [r3, #1]
+ calculatePEC(buffer, 4);
+ 8000cf0: 2104 movs r1, #4
+ 8000cf2: 68f8 ldr r0, [r7, #12]
+ 8000cf4: f7ff fe30 bl 8000958
+ for(uint8 i = 0; i < arglen; i++)
+ 8000cf8: 2300 movs r3, #0
+ 8000cfa: 75fb strb r3, [r7, #23]
+ 8000cfc: e00a b.n 8000d14
+ {
+ buffer[4+i] = args[i];
+ 8000cfe: 7dfb ldrb r3, [r7, #23]
+ 8000d00: 683a ldr r2, [r7, #0]
+ 8000d02: 441a add r2, r3
+ 8000d04: 7dfb ldrb r3, [r7, #23]
+ 8000d06: 3304 adds r3, #4
+ 8000d08: 7811 ldrb r1, [r2, #0]
+ 8000d0a: 68fa ldr r2, [r7, #12]
+ 8000d0c: 54d1 strb r1, [r2, r3]
+ for(uint8 i = 0; i < arglen; i++)
+ 8000d0e: 7dfb ldrb r3, [r7, #23]
+ 8000d10: 3301 adds r3, #1
+ 8000d12: 75fb strb r3, [r7, #23]
+ 8000d14: 7dfa ldrb r2, [r7, #23]
+ 8000d16: 797b ldrb r3, [r7, #5]
+ 8000d18: 429a cmp r2, r3
+ 8000d1a: d3f0 bcc.n 8000cfe
+ }
+
+ calculatePEC(&buffer[4], arglen+2); //Calculate PEC of Data Part with offset of 4 Bytes for CMD and CMD PEC
+ 8000d1c: 68fb ldr r3, [r7, #12]
+ 8000d1e: 1d1a adds r2, r3, #4
+ 8000d20: 797b ldrb r3, [r7, #5]
+ 8000d22: 3302 adds r3, #2
+ 8000d24: b2db uxtb r3, r3
+ 8000d26: 4619 mov r1, r3
+ 8000d28: 4610 mov r0, r2
+ 8000d2a: f7ff fe15 bl 8000958
+
+ mcuAdbmsCSLow();
+ 8000d2e: f000 f8db bl 8000ee8
+ mcuSPITransmit(buffer, 6+arglen);
+ 8000d32: 797b ldrb r3, [r7, #5]
+ 8000d34: 3306 adds r3, #6
+ 8000d36: b2db uxtb r3, r3
+ 8000d38: 4619 mov r1, r3
+ 8000d3a: 68f8 ldr r0, [r7, #12]
+ 8000d3c: f000 f8e8 bl 8000f10
+ mcuAdbmsCSHigh();
+ 8000d40: f000 f8dc bl 8000efc
+ 8000d44: 46b5 mov sp, r6
+ 8000d46: e017 b.n 8000d78
+
+ }
+ else
+ {
+ uint8 buffer[4];
+ buffer[0] = (command >> 8) & 0xFF;
+ 8000d48: 88fb ldrh r3, [r7, #6]
+ 8000d4a: 0a1b lsrs r3, r3, #8
+ 8000d4c: b29b uxth r3, r3
+ 8000d4e: b2db uxtb r3, r3
+ 8000d50: 723b strb r3, [r7, #8]
+ buffer[1] = (command) & 0xFF;
+ 8000d52: 88fb ldrh r3, [r7, #6]
+ 8000d54: b2db uxtb r3, r3
+ 8000d56: 727b strb r3, [r7, #9]
+ calculatePEC(buffer, 4);
+ 8000d58: f107 0308 add.w r3, r7, #8
+ 8000d5c: 2104 movs r1, #4
+ 8000d5e: 4618 mov r0, r3
+ 8000d60: f7ff fdfa bl 8000958
+
+ mcuAdbmsCSLow();
+ 8000d64: f000 f8c0 bl 8000ee8
+
+ mcuSPITransmit(buffer, 4);
+ 8000d68: f107 0308 add.w r3, r7, #8
+ 8000d6c: 2104 movs r1, #4
+ 8000d6e: 4618 mov r0, r3
+ 8000d70: f000 f8ce bl 8000f10
+
+ mcuAdbmsCSHigh();
+ 8000d74: f000 f8c2 bl 8000efc
+ }
+
+ return 0;
+ 8000d78: 2300 movs r3, #0
+}
+ 8000d7a: 4618 mov r0, r3
+ 8000d7c: 371c adds r7, #28
+ 8000d7e: 46bd mov sp, r7
+ 8000d80: e8bd 83f0 ldmia.w sp!, {r4, r5, r6, r7, r8, r9, pc}
+
+08000d84 :
+
+uint8 readCMD(uint16 command, uint8* buffer, uint8 buflen)
+{
+ 8000d84: e92d 4ff0 stmdb sp!, {r4, r5, r6, r7, r8, r9, sl, fp, lr}
+ 8000d88: b08b sub sp, #44 ; 0x2c
+ 8000d8a: af00 add r7, sp, #0
+ 8000d8c: 4603 mov r3, r0
+ 8000d8e: 60b9 str r1, [r7, #8]
+ 8000d90: 81fb strh r3, [r7, #14]
+ 8000d92: 4613 mov r3, r2
+ 8000d94: 737b strb r3, [r7, #13]
+ 8000d96: 466b mov r3, sp
+ 8000d98: 461e mov r6, r3
+ //uint8* txbuffer = (uint8*) malloc(6+buflen);
+ //uint8* rxbuffer = (uint8*) malloc(6+buflen);
+ uint8 txbuffer[6+buflen];
+ 8000d9a: 7b7b ldrb r3, [r7, #13]
+ 8000d9c: 1d99 adds r1, r3, #6
+ 8000d9e: 1e4b subs r3, r1, #1
+ 8000da0: 627b str r3, [r7, #36] ; 0x24
+ 8000da2: 460a mov r2, r1
+ 8000da4: 2300 movs r3, #0
+ 8000da6: 603a str r2, [r7, #0]
+ 8000da8: 607b str r3, [r7, #4]
+ 8000daa: f04f 0200 mov.w r2, #0
+ 8000dae: f04f 0300 mov.w r3, #0
+ 8000db2: 6878 ldr r0, [r7, #4]
+ 8000db4: 00c3 lsls r3, r0, #3
+ 8000db6: 6838 ldr r0, [r7, #0]
+ 8000db8: ea43 7350 orr.w r3, r3, r0, lsr #29
+ 8000dbc: 6838 ldr r0, [r7, #0]
+ 8000dbe: 00c2 lsls r2, r0, #3
+ 8000dc0: 460a mov r2, r1
+ 8000dc2: 2300 movs r3, #0
+ 8000dc4: 4692 mov sl, r2
+ 8000dc6: 469b mov fp, r3
+ 8000dc8: f04f 0200 mov.w r2, #0
+ 8000dcc: f04f 0300 mov.w r3, #0
+ 8000dd0: ea4f 03cb mov.w r3, fp, lsl #3
+ 8000dd4: ea43 735a orr.w r3, r3, sl, lsr #29
+ 8000dd8: ea4f 02ca mov.w r2, sl, lsl #3
+ 8000ddc: 460b mov r3, r1
+ 8000dde: 3307 adds r3, #7
+ 8000de0: 08db lsrs r3, r3, #3
+ 8000de2: 00db lsls r3, r3, #3
+ 8000de4: ebad 0d03 sub.w sp, sp, r3
+ 8000de8: 466b mov r3, sp
+ 8000dea: 3300 adds r3, #0
+ 8000dec: 61fb str r3, [r7, #28]
+ uint8 rxbuffer[6+buflen];
+ 8000dee: 7b7b ldrb r3, [r7, #13]
+ 8000df0: 1d99 adds r1, r3, #6
+ 8000df2: 1e4b subs r3, r1, #1
+ 8000df4: 61bb str r3, [r7, #24]
+ 8000df6: 460a mov r2, r1
+ 8000df8: 2300 movs r3, #0
+ 8000dfa: 4690 mov r8, r2
+ 8000dfc: 4699 mov r9, r3
+ 8000dfe: f04f 0200 mov.w r2, #0
+ 8000e02: f04f 0300 mov.w r3, #0
+ 8000e06: ea4f 03c9 mov.w r3, r9, lsl #3
+ 8000e0a: ea43 7358 orr.w r3, r3, r8, lsr #29
+ 8000e0e: ea4f 02c8 mov.w r2, r8, lsl #3
+ 8000e12: 460a mov r2, r1
+ 8000e14: 2300 movs r3, #0
+ 8000e16: 4614 mov r4, r2
+ 8000e18: 461d mov r5, r3
+ 8000e1a: f04f 0200 mov.w r2, #0
+ 8000e1e: f04f 0300 mov.w r3, #0
+ 8000e22: 00eb lsls r3, r5, #3
+ 8000e24: ea43 7354 orr.w r3, r3, r4, lsr #29
+ 8000e28: 00e2 lsls r2, r4, #3
+ 8000e2a: 460b mov r3, r1
+ 8000e2c: 3307 adds r3, #7
+ 8000e2e: 08db lsrs r3, r3, #3
+ 8000e30: 00db lsls r3, r3, #3
+ 8000e32: ebad 0d03 sub.w sp, sp, r3
+ 8000e36: 466b mov r3, sp
+ 8000e38: 3300 adds r3, #0
+ 8000e3a: 617b str r3, [r7, #20]
+
+ txbuffer[0] = (command >> 8) & 0xFF;
+ 8000e3c: 89fb ldrh r3, [r7, #14]
+ 8000e3e: 0a1b lsrs r3, r3, #8
+ 8000e40: b29b uxth r3, r3
+ 8000e42: b2da uxtb r2, r3
+ 8000e44: 69fb ldr r3, [r7, #28]
+ 8000e46: 701a strb r2, [r3, #0]
+ txbuffer[1] = (command) & 0xFF;
+ 8000e48: 89fb ldrh r3, [r7, #14]
+ 8000e4a: b2da uxtb r2, r3
+ 8000e4c: 69fb ldr r3, [r7, #28]
+ 8000e4e: 705a strb r2, [r3, #1]
+ calculatePEC(txbuffer, 4);
+ 8000e50: 2104 movs r1, #4
+ 8000e52: 69f8 ldr r0, [r7, #28]
+ 8000e54: f7ff fd80 bl 8000958
+
+ mcuAdbmsCSLow();
+ 8000e58: f000 f846 bl 8000ee8
+ mcuSPITransmitReceive(rxbuffer, txbuffer, 6+buflen);
+ 8000e5c: 7b7b ldrb r3, [r7, #13]
+ 8000e5e: 3306 adds r3, #6
+ 8000e60: b2db uxtb r3, r3
+ 8000e62: 461a mov r2, r3
+ 8000e64: 69f9 ldr r1, [r7, #28]
+ 8000e66: 6978 ldr r0, [r7, #20]
+ 8000e68: f000 f8a6 bl 8000fb8
+ mcuAdbmsCSHigh();
+ 8000e6c: f000 f846 bl 8000efc
+
+
+ for(uint8 i = 0; i
+ {
+ buffer[i] = rxbuffer[i+4];
+ 8000e78: f897 3023 ldrb.w r3, [r7, #35] ; 0x23
+ 8000e7c: 1d1a adds r2, r3, #4
+ 8000e7e: f897 3023 ldrb.w r3, [r7, #35] ; 0x23
+ 8000e82: 68b9 ldr r1, [r7, #8]
+ 8000e84: 440b add r3, r1
+ 8000e86: 6979 ldr r1, [r7, #20]
+ 8000e88: 5c8a ldrb r2, [r1, r2]
+ 8000e8a: 701a strb r2, [r3, #0]
+ for(uint8 i = 0; i
+ }
+
+ uint8 peccheck = checkPEC(&rxbuffer[4], buflen+2);
+ 8000ea0: 697b ldr r3, [r7, #20]
+ 8000ea2: 1d1a adds r2, r3, #4
+ 8000ea4: 7b7b ldrb r3, [r7, #13]
+ 8000ea6: 3302 adds r3, #2
+ 8000ea8: b2db uxtb r3, r3
+ 8000eaa: 4619 mov r1, r3
+ 8000eac: 4610 mov r0, r2
+ 8000eae: f7ff fd9b bl 80009e8
+ 8000eb2: 4603 mov r3, r0
+ 8000eb4: 74fb strb r3, [r7, #19]
+
+ //free(txbuffer);
+ //free(rxbuffer);
+
+ if(peccheck == 0)
+ 8000eb6: 7cfb ldrb r3, [r7, #19]
+ 8000eb8: 2b00 cmp r3, #0
+ 8000eba: d101 bne.n 8000ec0
+ return 0;
+ 8000ebc: 2300 movs r3, #0
+ 8000ebe: e00b b.n 8000ed8
+ else
+ {
+ static int err_cnt = 0;
+ if (err_cnt++ > 100) {
+ 8000ec0: 4b08 ldr r3, [pc, #32] ; (8000ee4 )
+ 8000ec2: 681b ldr r3, [r3, #0]
+ 8000ec4: 1c5a adds r2, r3, #1
+ 8000ec6: 4907 ldr r1, [pc, #28] ; (8000ee4 )
+ 8000ec8: 600a str r2, [r1, #0]
+ 8000eca: 2b64 cmp r3, #100 ; 0x64
+ 8000ecc: dd03 ble.n 8000ed6
+ Error_Handler();
+ 8000ece: f000 ffb3 bl 8001e38
+ 8000ed2: 46b5 mov sp, r6
+ } else {
+ return 1;
+ }
+ }
+
+}
+ 8000ed4: e001 b.n 8000eda
+ return 1;
+ 8000ed6: 2301 movs r3, #1
+ 8000ed8: 46b5 mov sp, r6
+}
+ 8000eda: 4618 mov r0, r3
+ 8000edc: 372c adds r7, #44 ; 0x2c
+ 8000ede: 46bd mov sp, r7
+ 8000ee0: e8bd 8ff0 ldmia.w sp!, {r4, r5, r6, r7, r8, r9, sl, fp, pc}
+ 8000ee4: 2000003c .word 0x2000003c
+
+08000ee8 :
+
+void mcuAdbmsCSLow()
+{
+ 8000ee8: b580 push {r7, lr}
+ 8000eea: af00 add r7, sp, #0
+ HAL_GPIO_WritePin(CSB_GPIO_Port, CSB_Pin, GPIO_PIN_RESET);
+ 8000eec: 2200 movs r2, #0
+ 8000eee: 2110 movs r1, #16
+ 8000ef0: f04f 4090 mov.w r0, #1207959552 ; 0x48000000
+ 8000ef4: f002 faf2 bl 80034dc
+}
+ 8000ef8: bf00 nop
+ 8000efa: bd80 pop {r7, pc}
+
+08000efc :
+
+void mcuAdbmsCSHigh()
+{
+ 8000efc: b580 push {r7, lr}
+ 8000efe: af00 add r7, sp, #0
+ HAL_GPIO_WritePin(CSB_GPIO_Port, CSB_Pin, GPIO_PIN_SET);
+ 8000f00: 2201 movs r2, #1
+ 8000f02: 2110 movs r1, #16
+ 8000f04: f04f 4090 mov.w r0, #1207959552 ; 0x48000000
+ 8000f08: f002 fae8 bl 80034dc
+}
+ 8000f0c: bf00 nop
+ 8000f0e: bd80 pop {r7, pc}
+
+08000f10 :
+
+uint8 mcuSPITransmit(uint8* buffer, uint8 buffersize)
+{
+ 8000f10: e92d 43f0 stmdb sp!, {r4, r5, r6, r7, r8, r9, lr}
+ 8000f14: b089 sub sp, #36 ; 0x24
+ 8000f16: af02 add r7, sp, #8
+ 8000f18: 6078 str r0, [r7, #4]
+ 8000f1a: 460b mov r3, r1
+ 8000f1c: 70fb strb r3, [r7, #3]
+ 8000f1e: 466b mov r3, sp
+ 8000f20: 461e mov r6, r3
+ HAL_StatusTypeDef status;
+ //status = HAL_SPI_Transmit(adbmsspi, buffer, buffersize, ADBMS_SPI_TIMEOUT);
+ //uint8 *rxbuf = (uint8*) malloc(buffersize);
+ uint8 rxbuf[buffersize];
+ 8000f22: 78f9 ldrb r1, [r7, #3]
+ 8000f24: 460b mov r3, r1
+ 8000f26: 3b01 subs r3, #1
+ 8000f28: 617b str r3, [r7, #20]
+ 8000f2a: b2cb uxtb r3, r1
+ 8000f2c: 2200 movs r2, #0
+ 8000f2e: 4698 mov r8, r3
+ 8000f30: 4691 mov r9, r2
+ 8000f32: f04f 0200 mov.w r2, #0
+ 8000f36: f04f 0300 mov.w r3, #0
+ 8000f3a: ea4f 03c9 mov.w r3, r9, lsl #3
+ 8000f3e: ea43 7358 orr.w r3, r3, r8, lsr #29
+ 8000f42: ea4f 02c8 mov.w r2, r8, lsl #3
+ 8000f46: b2cb uxtb r3, r1
+ 8000f48: 2200 movs r2, #0
+ 8000f4a: 461c mov r4, r3
+ 8000f4c: 4615 mov r5, r2
+ 8000f4e: f04f 0200 mov.w r2, #0
+ 8000f52: f04f 0300 mov.w r3, #0
+ 8000f56: 00eb lsls r3, r5, #3
+ 8000f58: ea43 7354 orr.w r3, r3, r4, lsr #29
+ 8000f5c: 00e2 lsls r2, r4, #3
+ 8000f5e: 460b mov r3, r1
+ 8000f60: 3307 adds r3, #7
+ 8000f62: 08db lsrs r3, r3, #3
+ 8000f64: 00db lsls r3, r3, #3
+ 8000f66: ebad 0d03 sub.w sp, sp, r3
+ 8000f6a: ab02 add r3, sp, #8
+ 8000f6c: 3300 adds r3, #0
+ 8000f6e: 613b str r3, [r7, #16]
+ status = HAL_SPI_TransmitReceive(adbmsspi, buffer, rxbuf, buffersize, ADBMS_SPI_TIMEOUT);
+ 8000f70: 4b10 ldr r3, [pc, #64] ; (8000fb4 )
+ 8000f72: 6818 ldr r0, [r3, #0]
+ 8000f74: 78fb ldrb r3, [r7, #3]
+ 8000f76: b29b uxth r3, r3
+ 8000f78: f44f 727a mov.w r2, #1000 ; 0x3e8
+ 8000f7c: 9200 str r2, [sp, #0]
+ 8000f7e: 693a ldr r2, [r7, #16]
+ 8000f80: 6879 ldr r1, [r7, #4]
+ 8000f82: f004 fefe bl 8005d82
+ 8000f86: 4603 mov r3, r0
+ 8000f88: 73fb strb r3, [r7, #15]
+ __HAL_SPI_CLEAR_OVRFLAG(adbmsspi);
+ 8000f8a: 2300 movs r3, #0
+ 8000f8c: 60bb str r3, [r7, #8]
+ 8000f8e: 4b09 ldr r3, [pc, #36] ; (8000fb4 )
+ 8000f90: 681b ldr r3, [r3, #0]
+ 8000f92: 681b ldr r3, [r3, #0]
+ 8000f94: 68db ldr r3, [r3, #12]
+ 8000f96: 60bb str r3, [r7, #8]
+ 8000f98: 4b06 ldr r3, [pc, #24] ; (8000fb4 )
+ 8000f9a: 681b ldr r3, [r3, #0]
+ 8000f9c: 681b ldr r3, [r3, #0]
+ 8000f9e: 689b ldr r3, [r3, #8]
+ 8000fa0: 60bb str r3, [r7, #8]
+ 8000fa2: 68bb ldr r3, [r7, #8]
+ //free(rxbuf);
+ return status;
+ 8000fa4: 7bfb ldrb r3, [r7, #15]
+ 8000fa6: 46b5 mov sp, r6
+}
+ 8000fa8: 4618 mov r0, r3
+ 8000faa: 371c adds r7, #28
+ 8000fac: 46bd mov sp, r7
+ 8000fae: e8bd 83f0 ldmia.w sp!, {r4, r5, r6, r7, r8, r9, pc}
+ 8000fb2: bf00 nop
+ 8000fb4: 20000038 .word 0x20000038
+
+08000fb8 :
+ status = HAL_SPI_Receive(adbmsspi, buffer, buffersize, ADBMS_SPI_TIMEOUT);
+ return status;
+}
+
+uint8 mcuSPITransmitReceive(uint8* rxbuffer, uint8* txbuffer, uint8 buffersize)
+{
+ 8000fb8: b580 push {r7, lr}
+ 8000fba: b088 sub sp, #32
+ 8000fbc: af02 add r7, sp, #8
+ 8000fbe: 60f8 str r0, [r7, #12]
+ 8000fc0: 60b9 str r1, [r7, #8]
+ 8000fc2: 4613 mov r3, r2
+ 8000fc4: 71fb strb r3, [r7, #7]
+ HAL_StatusTypeDef status;
+ status = HAL_SPI_TransmitReceive(adbmsspi, txbuffer, rxbuffer, buffersize, ADBMS_SPI_TIMEOUT);
+ 8000fc6: 4b09 ldr r3, [pc, #36] ; (8000fec )
+ 8000fc8: 6818 ldr r0, [r3, #0]
+ 8000fca: 79fb ldrb r3, [r7, #7]
+ 8000fcc: b29b uxth r3, r3
+ 8000fce: f44f 727a mov.w r2, #1000 ; 0x3e8
+ 8000fd2: 9200 str r2, [sp, #0]
+ 8000fd4: 68fa ldr r2, [r7, #12]
+ 8000fd6: 68b9 ldr r1, [r7, #8]
+ 8000fd8: f004 fed3 bl 8005d82
+ 8000fdc: 4603 mov r3, r0
+ 8000fde: 75fb strb r3, [r7, #23]
+ return status;
+ 8000fe0: 7dfb ldrb r3, [r7, #23]
+}
+ 8000fe2: 4618 mov r0, r3
+ 8000fe4: 3718 adds r7, #24
+ 8000fe6: 46bd mov sp, r7
+ 8000fe8: bd80 pop {r7, pc}
+ 8000fea: bf00 nop
+ 8000fec: 20000038 .word 0x20000038
+
+08000ff0 :
+
+inline void mcuDelay(uint16 delay)
+{
+ 8000ff0: b580 push {r7, lr}
+ 8000ff2: b082 sub sp, #8
+ 8000ff4: af00 add r7, sp, #0
+ 8000ff6: 4603 mov r3, r0
+ 8000ff8: 80fb strh r3, [r7, #6]
+ HAL_Delay(delay);
+ 8000ffa: 88fb ldrh r3, [r7, #6]
+ 8000ffc: 4618 mov r0, r3
+ 8000ffe: f001 f93d bl 800227c
+}
+ 8001002: bf00 nop
+ 8001004: 3708 adds r7, #8
+ 8001006: 46bd mov sp, r7
+ 8001008: bd80 pop {r7, pc}
+ ...
+
+0800100c :
+
+
+CAN_HandleTypeDef* ams_can_handle;
+
+void ams_can_init(CAN_HandleTypeDef* ams_handle,
+ CAN_HandleTypeDef* car_handle) {
+ 800100c: b580 push {r7, lr}
+ 800100e: b08c sub sp, #48 ; 0x30
+ 8001010: af00 add r7, sp, #0
+ 8001012: 6078 str r0, [r7, #4]
+ 8001014: 6039 str r1, [r7, #0]
+ ams_can_handle = ams_handle;
+ 8001016: 4a2e ldr r2, [pc, #184] ; (80010d0 )
+ 8001018: 687b ldr r3, [r7, #4]
+ 800101a: 6013 str r3, [r2, #0]
+
+ // Start peripheral
+ if (HAL_CAN_Start(ams_can_handle) != HAL_OK) {
+ 800101c: 4b2c ldr r3, [pc, #176] ; (80010d0 )
+ 800101e: 681b ldr r3, [r3, #0]
+ 8001020: 4618 mov r0, r3
+ 8001022: f001 fb14 bl 800264e
+ 8001026: 4603 mov r3, r0
+ 8001028: 2b00 cmp r3, #0
+ 800102a: d00c beq.n 8001046
+ ams_can_handle = car_handle;
+ 800102c: 4a28 ldr r2, [pc, #160] ; (80010d0 )
+ 800102e: 683b ldr r3, [r7, #0]
+ 8001030: 6013 str r3, [r2, #0]
+ if (HAL_CAN_Start(ams_can_handle) != HAL_OK) {
+ 8001032: 4b27 ldr r3, [pc, #156] ; (80010d0 )
+ 8001034: 681b ldr r3, [r3, #0]
+ 8001036: 4618 mov r0, r3
+ 8001038: f001 fb09 bl 800264e
+ 800103c: 4603 mov r3, r0
+ 800103e: 2b00 cmp r3, #0
+ 8001040: d001 beq.n 8001046
+ Error_Handler();
+ 8001042: f000 fef9 bl 8001e38
+ }
+ }
+
+ // Config filter
+ CAN_FilterTypeDef can_filter;
+ can_filter.FilterActivation = CAN_FILTER_ENABLE;
+ 8001046: 2301 movs r3, #1
+ 8001048: 62bb str r3, [r7, #40] ; 0x28
+ can_filter.FilterBank = 0;
+ 800104a: 2300 movs r3, #0
+ 800104c: 61fb str r3, [r7, #28]
+ can_filter.FilterFIFOAssignment = CAN_FILTER_FIFO0;
+ 800104e: 2300 movs r3, #0
+ 8001050: 61bb str r3, [r7, #24]
+ /* Message ID is in the MSBs of the FilterId register */
+ can_filter.FilterIdHigh = CAN_ID_CLOCK_SYNC << (16 - 11);
+ 8001052: 2340 movs r3, #64 ; 0x40
+ 8001054: 60bb str r3, [r7, #8]
+ can_filter.FilterIdLow = 0;
+ 8001056: 2300 movs r3, #0
+ 8001058: 60fb str r3, [r7, #12]
+ /* Filter the 11 MSBs (i.e. a StdId) */
+
+ if(BMS_IN_TEST_MODE == 1){
+ can_filter.FilterMaskIdHigh = BMS_TEST_ID; // alleNachrichtenIds werden akzeptiert
+ 800105a: 2300 movs r3, #0
+ 800105c: 613b str r3, [r7, #16]
+ }else{
+ can_filter.FilterMaskIdHigh = 0xFFE0;
+ }
+
+ can_filter.FilterMaskIdLow = 0;
+ 800105e: 2300 movs r3, #0
+ 8001060: 617b str r3, [r7, #20]
+ can_filter.FilterMode = CAN_FILTERMODE_IDMASK;
+ 8001062: 2300 movs r3, #0
+ 8001064: 623b str r3, [r7, #32]
+ can_filter.FilterScale = CAN_FILTERSCALE_32BIT;
+ 8001066: 2301 movs r3, #1
+ 8001068: 627b str r3, [r7, #36] ; 0x24
+ can_filter.SlaveStartFilterBank = 0;
+ 800106a: 2300 movs r3, #0
+ 800106c: 62fb str r3, [r7, #44] ; 0x2c
+ if (HAL_CAN_ConfigFilter(ams_can_handle, &can_filter) != HAL_OK) {
+ 800106e: 4b18 ldr r3, [pc, #96] ; (80010d0 )
+ 8001070: 681b ldr r3, [r3, #0]
+ 8001072: f107 0208 add.w r2, r7, #8
+ 8001076: 4611 mov r1, r2
+ 8001078: 4618 mov r0, r3
+ 800107a: f001 fa1e bl 80024ba
+ 800107e: 4603 mov r3, r0
+ 8001080: 2b00 cmp r3, #0
+ 8001082: d001 beq.n 8001088
+ Error_Handler();
+ 8001084: f000 fed8 bl 8001e38
+ }
+ can_filter.FilterBank++;
+ 8001088: 69fb ldr r3, [r7, #28]
+ 800108a: 3301 adds r3, #1
+ 800108c: 61fb str r3, [r7, #28]
+ can_filter.FilterIdHigh = CAN_ID_MASTER_HEARTBEAT << (16 - 11);
+ 800108e: f44f 7300 mov.w r3, #512 ; 0x200
+ 8001092: 60bb str r3, [r7, #8]
+ can_filter.FilterIdLow = 0;
+ 8001094: 2300 movs r3, #0
+ 8001096: 60fb str r3, [r7, #12]
+ if (HAL_CAN_ConfigFilter(ams_can_handle, &can_filter) != HAL_OK) {
+ 8001098: 4b0d ldr r3, [pc, #52] ; (80010d0 )
+ 800109a: 681b ldr r3, [r3, #0]
+ 800109c: f107 0208 add.w r2, r7, #8
+ 80010a0: 4611 mov r1, r2
+ 80010a2: 4618 mov r0, r3
+ 80010a4: f001 fa09 bl 80024ba
+ 80010a8: 4603 mov r3, r0
+ 80010aa: 2b00 cmp r3, #0
+ 80010ac: d001 beq.n 80010b2
+ Error_Handler();
+ 80010ae: f000 fec3 bl 8001e38
+ }
+
+ // Activate RX notifications
+ if (HAL_CAN_ActivateNotification(ams_can_handle,
+ 80010b2: 4b07 ldr r3, [pc, #28] ; (80010d0 )
+ 80010b4: 681b ldr r3, [r3, #0]
+ 80010b6: 2102 movs r1, #2
+ 80010b8: 4618 mov r0, r3
+ 80010ba: f001 fd2e bl 8002b1a
+ 80010be: 4603 mov r3, r0
+ 80010c0: 2b00 cmp r3, #0
+ 80010c2: d001 beq.n 80010c8
+ CAN_IT_RX_FIFO0_MSG_PENDING) != HAL_OK) {
+ Error_Handler();
+ 80010c4: f000 feb8 bl 8001e38
+ }
+}
+ 80010c8: bf00 nop
+ 80010ca: 3730 adds r7, #48 ; 0x30
+ 80010cc: 46bd mov sp, r7
+ 80010ce: bd80 pop {r7, pc}
+ 80010d0: 2000004c .word 0x2000004c
+
+080010d4 :
+
+static int cb_triggered = 0;
+
+void HAL_CAN_RxFifo0MsgPendingCallback(CAN_HandleTypeDef* handle) {
+ 80010d4: b580 push {r7, lr}
+ 80010d6: b082 sub sp, #8
+ 80010d8: af00 add r7, sp, #0
+ 80010da: 6078 str r0, [r7, #4]
+ static CAN_RxHeaderTypeDef header;
+ static uint8_t data[8];
+ cb_triggered = 1;
+ 80010dc: 4b0e ldr r3, [pc, #56] ; (8001118 )
+ 80010de: 2201 movs r2, #1
+ 80010e0: 601a str r2, [r3, #0]
+
+ if (HAL_CAN_GetRxMessage(handle, CAN_RX_FIFO0, &header, data) != HAL_OK) {
+ 80010e2: 4b0e ldr r3, [pc, #56] ; (800111c )
+ 80010e4: 4a0e ldr r2, [pc, #56] ; (8001120 )
+ 80010e6: 2100 movs r1, #0
+ 80010e8: 6878 ldr r0, [r7, #4]
+ 80010ea: f001 fc04 bl 80028f6
+ 80010ee: 4603 mov r3, r0
+ 80010f0: 2b00 cmp r3, #0
+ 80010f2: d001 beq.n 80010f8
+ Error_Handler();
+ 80010f4: f000 fea0 bl 8001e38
+ }
+
+ if (handle == ams_can_handle) {
+ 80010f8: 4b0a ldr r3, [pc, #40] ; (8001124 )
+ 80010fa: 681b ldr r3, [r3, #0]
+ 80010fc: 687a ldr r2, [r7, #4]
+ 80010fe: 429a cmp r2, r3
+ 8001100: d104 bne.n 800110c
+ ams_can_handle_ams_msg(&header, data);
+ 8001102: 4906 ldr r1, [pc, #24] ; (800111c )
+ 8001104: 4806 ldr r0, [pc, #24] ; (8001120 )
+ 8001106: f000 f80f bl 8001128
+ } else {
+ Error_Handler();
+ }
+}
+ 800110a: e001 b.n 8001110
+ Error_Handler();
+ 800110c: f000 fe94 bl 8001e38
+}
+ 8001110: bf00 nop
+ 8001112: 3708 adds r7, #8
+ 8001114: 46bd mov sp, r7
+ 8001116: bd80 pop {r7, pc}
+ 8001118: 20000050 .word 0x20000050
+ 800111c: 20000070 .word 0x20000070
+ 8001120: 20000054 .word 0x20000054
+ 8001124: 2000004c .word 0x2000004c
+
+08001128 :
+
+void ams_can_handle_ams_msg(CAN_RxHeaderTypeDef* header, uint8_t* data) {
+ 8001128: b480 push {r7}
+ 800112a: b085 sub sp, #20
+ 800112c: af00 add r7, sp, #0
+ 800112e: 6078 str r0, [r7, #4]
+ 8001130: 6039 str r1, [r7, #0]
+
+ if(BMS_IN_TEST_MODE == 1){
+ PENDING_MESSAGE_HANDLE = 1;
+ 8001132: 4b0e ldr r3, [pc, #56] ; (800116c )
+ 8001134: 2201 movs r2, #1
+ 8001136: 601a str r2, [r3, #0]
+ for(int i = 0; i < 8; i++){
+ 8001138: 2300 movs r3, #0
+ 800113a: 60fb str r3, [r7, #12]
+ 800113c: e00b b.n 8001156
+ canTestData[i] = data[i];
+ 800113e: 68fb ldr r3, [r7, #12]
+ 8001140: 683a ldr r2, [r7, #0]
+ 8001142: 4413 add r3, r2
+ 8001144: 7819 ldrb r1, [r3, #0]
+ 8001146: 4a0a ldr r2, [pc, #40] ; (8001170 )
+ 8001148: 68fb ldr r3, [r7, #12]
+ 800114a: 4413 add r3, r2
+ 800114c: 460a mov r2, r1
+ 800114e: 701a strb r2, [r3, #0]
+ for(int i = 0; i < 8; i++){
+ 8001150: 68fb ldr r3, [r7, #12]
+ 8001152: 3301 adds r3, #1
+ 8001154: 60fb str r3, [r7, #12]
+ 8001156: 68fb ldr r3, [r7, #12]
+ 8001158: 2b07 cmp r3, #7
+ 800115a: ddf0 ble.n 800113e
+ }
+ return;
+ 800115c: bf00 nop
+ 800115e: bf00 nop
+ break;
+ case CAN_ID_MASTER_HEARTBEAT:
+// clock_sync_handle_master_heartbeat();
+ break;
+ }
+}
+ 8001160: 3714 adds r7, #20
+ 8001162: 46bd mov sp, r7
+ 8001164: f85d 7b04 ldr.w r7, [sp], #4
+ 8001168: 4770 bx lr
+ 800116a: bf00 nop
+ 800116c: 20000040 .word 0x20000040
+ 8001170: 20000044 .word 0x20000044
+
+08001174 :
+
+void ams_can_send_heartbeat() {
+ 8001174: b580 push {r7, lr}
+ 8001176: b086 sub sp, #24
+ 8001178: af00 add r7, sp, #0
+ static CAN_TxHeaderTypeDef header;
+ static uint8_t data[8];
+
+ header.IDE = CAN_ID_STD;
+ 800117a: 4b2c ldr r3, [pc, #176] ; (800122c )
+ 800117c: 2200 movs r2, #0
+ 800117e: 609a str r2, [r3, #8]
+ header.DLC = 8;
+ 8001180: 4b2a ldr r3, [pc, #168] ; (800122c )
+ 8001182: 2208 movs r2, #8
+ 8001184: 611a str r2, [r3, #16]
+ header.RTR = CAN_RTR_DATA;
+ 8001186: 4b29 ldr r3, [pc, #164] ; (800122c )
+ 8001188: 2200 movs r2, #0
+ 800118a: 60da str r2, [r3, #12]
+ header.TransmitGlobalTime = DISABLE;
+ 800118c: 4b27 ldr r3, [pc, #156] ; (800122c )
+ 800118e: 2200 movs r2, #0
+ 8001190: 751a strb r2, [r3, #20]
+
+ // Send voltages
+ for (int msg_id = 0; msg_id < 5; msg_id++) {
+ 8001192: 2300 movs r3, #0
+ 8001194: 617b str r3, [r7, #20]
+ 8001196: e040 b.n 800121a
+ header.StdId = CAN_ID_AMS_SLAVE_HEARTBEAT_BASE | (0 << 4) | msg_id; //TODO: Use slave_id/new format
+ 8001198: 697b ldr r3, [r7, #20]
+ 800119a: f443 63c0 orr.w r3, r3, #1536 ; 0x600
+ 800119e: 461a mov r2, r3
+ 80011a0: 4b22 ldr r3, [pc, #136] ; (800122c )
+ 80011a2: 601a str r2, [r3, #0]
+ for (int i = 0; i < 4; i++) {
+ 80011a4: 2300 movs r3, #0
+ 80011a6: 613b str r3, [r7, #16]
+ 80011a8: e020 b.n 80011ec
+ int cell = msg_id * 4 + i;
+ 80011aa: 697b ldr r3, [r7, #20]
+ 80011ac: 009b lsls r3, r3, #2
+ 80011ae: 693a ldr r2, [r7, #16]
+ 80011b0: 4413 add r3, r2
+ 80011b2: 60fb str r3, [r7, #12]
+ uint16_t v = (cell < N_CELLS) ? module.cellVoltages[cell] : 0;
+ 80011b4: 68fb ldr r3, [r7, #12]
+ 80011b6: 2b10 cmp r3, #16
+ 80011b8: dc04 bgt.n 80011c4
+ 80011ba: 4a1d ldr r2, [pc, #116] ; (8001230 )
+ 80011bc: 68fb ldr r3, [r7, #12]
+ 80011be: f832 3013 ldrh.w r3, [r2, r3, lsl #1]
+ 80011c2: e000 b.n 80011c6
+ 80011c4: 2300 movs r3, #0
+ 80011c6: 817b strh r3, [r7, #10]
+ data[2 * i + 0] = v & 0xFF;
+ 80011c8: 693b ldr r3, [r7, #16]
+ 80011ca: 005b lsls r3, r3, #1
+ 80011cc: 897a ldrh r2, [r7, #10]
+ 80011ce: b2d1 uxtb r1, r2
+ 80011d0: 4a18 ldr r2, [pc, #96] ; (8001234 )
+ 80011d2: 54d1 strb r1, [r2, r3]
+ data[2 * i + 1] = v >> 8;
+ 80011d4: 897b ldrh r3, [r7, #10]
+ 80011d6: 0a1b lsrs r3, r3, #8
+ 80011d8: b29a uxth r2, r3
+ 80011da: 693b ldr r3, [r7, #16]
+ 80011dc: 005b lsls r3, r3, #1
+ 80011de: 3301 adds r3, #1
+ 80011e0: b2d1 uxtb r1, r2
+ 80011e2: 4a14 ldr r2, [pc, #80] ; (8001234 )
+ 80011e4: 54d1 strb r1, [r2, r3]
+ for (int i = 0; i < 4; i++) {
+ 80011e6: 693b ldr r3, [r7, #16]
+ 80011e8: 3301 adds r3, #1
+ 80011ea: 613b str r3, [r7, #16]
+ 80011ec: 693b ldr r3, [r7, #16]
+ 80011ee: 2b03 cmp r3, #3
+ 80011f0: dddb ble.n 80011aa
+ }
+ if (ams_can_wait_for_free_mailboxes(ams_can_handle, 1,
+ 80011f2: 4b11 ldr r3, [pc, #68] ; (8001238 )
+ 80011f4: 681b ldr r3, [r3, #0]
+ 80011f6: 220a movs r2, #10
+ 80011f8: 2101 movs r1, #1
+ 80011fa: 4618 mov r0, r3
+ 80011fc: f000 f81e bl 800123c
+ 8001200: 4603 mov r3, r0
+ 8001202: 2b00 cmp r3, #0
+ 8001204: d106 bne.n 8001214
+ CAN_HEARTBEAT_TX_TIMEOUT) == HAL_OK) {
+ uint32_t mailbox;
+ HAL_CAN_AddTxMessage(ams_can_handle, &header, data, &mailbox);
+ 8001206: 4b0c ldr r3, [pc, #48] ; (8001238 )
+ 8001208: 6818 ldr r0, [r3, #0]
+ 800120a: 1d3b adds r3, r7, #4
+ 800120c: 4a09 ldr r2, [pc, #36] ; (8001234 )
+ 800120e: 4907 ldr r1, [pc, #28] ; (800122c )
+ 8001210: f001 fa61 bl 80026d6
+ for (int msg_id = 0; msg_id < 5; msg_id++) {
+ 8001214: 697b ldr r3, [r7, #20]
+ 8001216: 3301 adds r3, #1
+ 8001218: 617b str r3, [r7, #20]
+ 800121a: 697b ldr r3, [r7, #20]
+ 800121c: 2b04 cmp r3, #4
+ 800121e: ddbb ble.n 8001198
+ CAN_HEARTBEAT_TX_TIMEOUT) == HAL_OK) {
+ uint32_t mailbox;
+ HAL_CAN_AddTxMessage(ams_can_handle, &header, data, &mailbox);
+ }
+ }*/
+}
+ 8001220: bf00 nop
+ 8001222: bf00 nop
+ 8001224: 3718 adds r7, #24
+ 8001226: 46bd mov sp, r7
+ 8001228: bd80 pop {r7, pc}
+ 800122a: bf00 nop
+ 800122c: 20000078 .word 0x20000078
+ 8001230: 20000098 .word 0x20000098
+ 8001234: 20000090 .word 0x20000090
+ 8001238: 2000004c .word 0x2000004c
+
+0800123c :
+ ams_can_wait_for_free_mailboxes(ams_can_handle, 3, transmission_timeout);
+}*/
+
+HAL_StatusTypeDef ams_can_wait_for_free_mailboxes(CAN_HandleTypeDef* handle,
+ int num_mailboxes,
+ uint32_t timeout) {
+ 800123c: b580 push {r7, lr}
+ 800123e: b086 sub sp, #24
+ 8001240: af00 add r7, sp, #0
+ 8001242: 60f8 str r0, [r7, #12]
+ 8001244: 60b9 str r1, [r7, #8]
+ 8001246: 607a str r2, [r7, #4]
+ uint32_t end = HAL_GetTick() + timeout;
+ 8001248: f001 f80c bl 8002264
+ 800124c: 4602 mov r2, r0
+ 800124e: 687b ldr r3, [r7, #4]
+ 8001250: 4413 add r3, r2
+ 8001252: 617b str r3, [r7, #20]
+ while (HAL_GetTick() < end) {
+ 8001254: e008 b.n 8001268
+ if (HAL_CAN_GetTxMailboxesFreeLevel(handle) >= num_mailboxes) {
+ 8001256: 68f8 ldr r0, [r7, #12]
+ 8001258: f001 fb18 bl 800288c
+ 800125c: 4602 mov r2, r0
+ 800125e: 68bb ldr r3, [r7, #8]
+ 8001260: 429a cmp r2, r3
+ 8001262: d301 bcc.n 8001268
+ return HAL_OK;
+ 8001264: 2300 movs r3, #0
+ 8001266: e006 b.n 8001276
+ while (HAL_GetTick() < end) {
+ 8001268: f000 fffc bl 8002264
+ 800126c: 4602 mov r2, r0
+ 800126e: 697b ldr r3, [r7, #20]
+ 8001270: 4293 cmp r3, r2
+ 8001272: d8f0 bhi.n 8001256
+ }
+ }
+ return HAL_TIMEOUT;
+ 8001274: 2303 movs r3, #3
+}
+ 8001276: 4618 mov r0, r3
+ 8001278: 3718 adds r7, #24
+ 800127a: 46bd mov sp, r7
+ 800127c: bd80 pop {r7, pc}
+ ...
+
+08001280 :
+
+amsState currentAMSState = AMSDEACTIVE;
+amsState lastAMSState = AMSDEACTIVE;
+
+void AMS_Init(SPI_HandleTypeDef *hspi)
+{
+ 8001280: b580 push {r7, lr}
+ 8001282: b082 sub sp, #8
+ 8001284: af00 add r7, sp, #0
+ 8001286: 6078 str r0, [r7, #4]
+ if(eepromconfigured == 1)
+ 8001288: 4b12 ldr r3, [pc, #72] ; (80012d4 )
+ 800128a: 781b ldrb r3, [r3, #0]
+ 800128c: 2b01 cmp r3, #1
+ 800128e: d10a bne.n 80012a6
+ /*amsov = eepromcellovervoltage>>4;
+ amsuv = (eepromcellundervoltage-1)>>4;
+ numberofCells = eepromnumofcells;
+ numberofAux = eepromnumofaux;
+ initAMS(hspi, eepromnumofcells, eepromnumofaux);*/
+ amsConfigOverVoltage(amsov);
+ 8001290: 4b11 ldr r3, [pc, #68] ; (80012d8 )
+ 8001292: 881b ldrh r3, [r3, #0]
+ 8001294: 4618 mov r0, r3
+ 8001296: f7ff fa1e bl 80006d6
+ amsConfigUnderVoltage(amsuv);
+ 800129a: 4b10 ldr r3, [pc, #64] ; (80012dc )
+ 800129c: 881b ldrh r3, [r3, #0]
+ 800129e: 4618 mov r0, r3
+ 80012a0: f7ff f95e bl 8000560
+ 80012a4: e00f b.n 80012c6
+ }
+ else
+ {
+ initAMS(hspi, numberofCells, numberofAux);
+ 80012a6: 4b0e ldr r3, [pc, #56] ; (80012e0 )
+ 80012a8: 781b ldrb r3, [r3, #0]
+ 80012aa: 4a0e ldr r2, [pc, #56] ; (80012e4 )
+ 80012ac: 7812 ldrb r2, [r2, #0]
+ 80012ae: 4619 mov r1, r3
+ 80012b0: 6878 ldr r0, [r7, #4]
+ 80012b2: f7fe ff89 bl 80001c8
+ amsov = DEFAULT_OV;
+ 80012b6: 4b08 ldr r3, [pc, #32] ; (80012d8 )
+ 80012b8: f640 2241 movw r2, #2625 ; 0xa41
+ 80012bc: 801a strh r2, [r3, #0]
+ amsuv = DEFAULT_UV;
+ 80012be: 4b07 ldr r3, [pc, #28] ; (80012dc )
+ 80012c0: f240 621a movw r2, #1562 ; 0x61a
+ 80012c4: 801a strh r2, [r3, #0]
+ }
+
+
+ currentAMSState = AMSIDLE;
+ 80012c6: 4b08 ldr r3, [pc, #32] ; (80012e8 )
+ 80012c8: 2201 movs r2, #1
+ 80012ca: 701a strb r2, [r3, #0]
+
+
+}
+ 80012cc: bf00 nop
+ 80012ce: 3708 adds r7, #8
+ 80012d0: 46bd mov sp, r7
+ 80012d2: bd80 pop {r7, pc}
+ 80012d4: 20000108 .word 0x20000108
+ 80012d8: 2000010c .word 0x2000010c
+ 80012dc: 2000010a .word 0x2000010a
+ 80012e0: 20000000 .word 0x20000000
+ 80012e4: 2000010f .word 0x2000010f
+ 80012e8: 20000110 .word 0x20000110
+
+080012ec :
+
+void AMS_Loop()
+{
+ 80012ec: b580 push {r7, lr}
+ 80012ee: af00 add r7, sp, #0
+
+ //On Transition Functions called ones if the State Changed
+
+ if(currentAMSState != lastAMSState)
+ 80012f0: 4b25 ldr r3, [pc, #148] ; (8001388 )
+ 80012f2: 781a ldrb r2, [r3, #0]
+ 80012f4: 4b25 ldr r3, [pc, #148] ; (800138c )
+ 80012f6: 781b ldrb r3, [r3, #0]
+ 80012f8: 429a cmp r2, r3
+ 80012fa: d023 beq.n 8001344
+ {
+ switch(currentAMSState)
+ 80012fc: 4b22 ldr r3, [pc, #136] ; (8001388 )
+ 80012fe: 781b ldrb r3, [r3, #0]
+ 8001300: 2b06 cmp r3, #6
+ 8001302: d81b bhi.n 800133c
+ 8001304: a201 add r2, pc, #4 ; (adr r2, 800130c )
+ 8001306: f852 f023 ldr.w pc, [r2, r3, lsl #2]
+ 800130a: bf00 nop
+ 800130c: 0800133d .word 0x0800133d
+ 8001310: 0800133d .word 0x0800133d
+ 8001314: 0800133d .word 0x0800133d
+ 8001318: 0800133d .word 0x0800133d
+ 800131c: 0800133d .word 0x0800133d
+ 8001320: 08001329 .word 0x08001329
+ 8001324: 08001331 .word 0x08001331
+ case AMSIDLEBALANCING:
+ break;
+ case AMSDISCHARGING:
+ break;
+ case AMSWARNING:
+ writeWarningLog(0x01);
+ 8001328: 2001 movs r0, #1
+ 800132a: f000 f8a7 bl 800147c
+ break;
+ 800132e: e005 b.n 800133c
+ case AMSERROR:
+ writeErrorLog(amserrorcode);
+ 8001330: 4b17 ldr r3, [pc, #92] ; (8001390 )
+ 8001332: 781b ldrb r3, [r3, #0]
+ 8001334: 4618 mov r0, r3
+ 8001336: f000 f8ad bl 8001494
+ break;
+ 800133a: bf00 nop
+ }
+ lastAMSState = currentAMSState;
+ 800133c: 4b12 ldr r3, [pc, #72] ; (8001388