From 543f3f9b1bb16b030da25a3a0ac5f5032c32e4eb Mon Sep 17 00:00:00 2001 From: Joppe Blondel Date: Sat, 18 Jul 2026 16:58:49 +0200 Subject: [PATCH] spu stuff --- SW/spu/.vscode/c_cpp_properties.json | 2 +- SW/spu/.vscode/launch.json | 8 +- SW/spu/.vscode/tasks.json | 12 +- SW/spu/app/blinky/src/app_main.c | 23 -- SW/spu/app/blinky/stm32f030/.mxproject | 14 - .../blinky/stm32f030/Src/stm32f0xx_hal_msp.c | 155 -------- SW/spu/app/blinky/stm32f030/stm32f030.ioc | 124 ------ SW/spu/app/motor_control/src/app_main.c | 207 ++++++++++ .../stm32f030/.gitignore | 0 SW/spu/app/motor_control/stm32f030/.mxproject | 14 + .../stm32f030/CMakeLists.txt | 12 +- .../stm32f030/CMakePresets.json | 0 .../stm32f030/Inc/main.h | 24 +- .../stm32f030/Inc/stm32f0xx_hal_conf.h | 2 +- .../stm32f030/Inc/stm32f0xx_it.h | 2 + .../stm32f030/STM32F030XX_FLASH.ld | 0 .../stm32f030/Src/main.c | 213 ++++++++++- .../stm32f030/Src/stm32f0xx_hal_msp.c | 361 ++++++++++++++++++ .../stm32f030/Src/stm32f0xx_it.c | 35 +- .../stm32f030/Src/syscalls.c | 0 .../stm32f030/Src/sysmem.c | 0 .../stm32f030/Src/system_stm32f0xx.c | 0 .../stm32f030/cmake/gcc-arm-none-eabi.cmake | 0 .../stm32f030/cmake/starm-clang.cmake | 0 .../stm32f030/startup_stm32f030x8.s | 0 .../app/motor_control/stm32f030/stm32f030.ioc | 296 ++++++++++++++ SW/spu/scripts/plot_motor_ticks.py | 357 +++++++++++++++++ 27 files changed, 1523 insertions(+), 338 deletions(-) delete mode 100644 SW/spu/app/blinky/src/app_main.c delete mode 100644 SW/spu/app/blinky/stm32f030/.mxproject delete mode 100644 SW/spu/app/blinky/stm32f030/Src/stm32f0xx_hal_msp.c delete mode 100644 SW/spu/app/blinky/stm32f030/stm32f030.ioc create mode 100644 SW/spu/app/motor_control/src/app_main.c rename SW/spu/app/{blinky => motor_control}/stm32f030/.gitignore (100%) create mode 100644 SW/spu/app/motor_control/stm32f030/.mxproject rename SW/spu/app/{blinky => motor_control}/stm32f030/CMakeLists.txt (88%) rename SW/spu/app/{blinky => motor_control}/stm32f030/CMakePresets.json (100%) rename SW/spu/app/{blinky => motor_control}/stm32f030/Inc/main.h (73%) rename SW/spu/app/{blinky => motor_control}/stm32f030/Inc/stm32f0xx_hal_conf.h (97%) rename SW/spu/app/{blinky => motor_control}/stm32f030/Inc/stm32f0xx_it.h (92%) rename SW/spu/app/{blinky => motor_control}/stm32f030/STM32F030XX_FLASH.ld (100%) rename SW/spu/app/{blinky => motor_control}/stm32f030/Src/main.c (54%) create mode 100644 SW/spu/app/motor_control/stm32f030/Src/stm32f0xx_hal_msp.c rename SW/spu/app/{blinky => motor_control}/stm32f030/Src/stm32f0xx_it.c (80%) rename SW/spu/app/{blinky => motor_control}/stm32f030/Src/syscalls.c (100%) rename SW/spu/app/{blinky => motor_control}/stm32f030/Src/sysmem.c (100%) rename SW/spu/app/{blinky => motor_control}/stm32f030/Src/system_stm32f0xx.c (100%) rename SW/spu/app/{blinky => motor_control}/stm32f030/cmake/gcc-arm-none-eabi.cmake (100%) rename SW/spu/app/{blinky => motor_control}/stm32f030/cmake/starm-clang.cmake (100%) rename SW/spu/app/{blinky => motor_control}/stm32f030/startup_stm32f030x8.s (100%) create mode 100644 SW/spu/app/motor_control/stm32f030/stm32f030.ioc create mode 100644 SW/spu/scripts/plot_motor_ticks.py diff --git a/SW/spu/.vscode/c_cpp_properties.json b/SW/spu/.vscode/c_cpp_properties.json index 7d59b6b..98f0961 100644 --- a/SW/spu/.vscode/c_cpp_properties.json +++ b/SW/spu/.vscode/c_cpp_properties.json @@ -3,7 +3,7 @@ "configurations": [ { "name": "STM32F030", - "compileCommands": "${workspaceFolder}/app/blinky/stm32f030/build/compile_commands.json", + "compileCommands": "${workspaceFolder}/app/motor_control/stm32f030/build/compile_commands.json", "intelliSenseMode": "linux-gcc-arm", "compilerPath": "/usr/bin/arm-none-eabi-gcc" } diff --git a/SW/spu/.vscode/launch.json b/SW/spu/.vscode/launch.json index 9749ad5..5962923 100644 --- a/SW/spu/.vscode/launch.json +++ b/SW/spu/.vscode/launch.json @@ -5,13 +5,13 @@ "version": "0.2.0", "configurations": [ { - "name": "Debug blinky (J-Link)", + "name": "Debug motor_control (J-Link)", "cwd": "${workspaceFolder}", - "executable": "${workspaceFolder}/app/blinky/stm32f030/build/blinky.elf", - "preLaunchTask": "Build blinky stm32f030", + "executable": "${workspaceFolder}/app/motor_control/stm32f030/build/motor_control.elf", + "preLaunchTask": "Build motor_control stm32f030", "request": "launch", "type": "cortex-debug", - "runToEntryPoint": "app_main", + // "runToEntryPoint": "app_main", "servertype": "jlink", "device": "STM32F030C8", "interface": "swd", diff --git a/SW/spu/.vscode/tasks.json b/SW/spu/.vscode/tasks.json index e6e583e..073094b 100644 --- a/SW/spu/.vscode/tasks.json +++ b/SW/spu/.vscode/tasks.json @@ -2,14 +2,14 @@ "version": "2.0.0", "tasks": [ { - "label": "Configure blinky stm32f030", + "label": "Configure motor_control stm32f030", "type": "shell", "command": "cmake", "args": [ "-S", - "${workspaceFolder}/app/blinky/stm32f030", + "${workspaceFolder}/app/motor_control/stm32f030", "-B", - "${workspaceFolder}/app/blinky/stm32f030/build", + "${workspaceFolder}/app/motor_control/stm32f030/build", "-DCMAKE_BUILD_TYPE=Debug" ], "options": { @@ -18,18 +18,18 @@ "problemMatcher": [] }, { - "label": "Build blinky stm32f030", + "label": "Build motor_control stm32f030", "type": "shell", "command": "cmake", "args": [ "--build", - "${workspaceFolder}/app/blinky/stm32f030/build" + "${workspaceFolder}/app/motor_control/stm32f030/build" ], "options": { "cwd": "${workspaceFolder}" }, "dependsOn": [ - "Configure blinky stm32f030" + "Configure motor_control stm32f030" ], "group": { "kind": "build", diff --git a/SW/spu/app/blinky/src/app_main.c b/SW/spu/app/blinky/src/app_main.c deleted file mode 100644 index 01e69ef..0000000 --- a/SW/spu/app/blinky/src/app_main.c +++ /dev/null @@ -1,23 +0,0 @@ -#include "main.h" -#include "stm32f0xx_hal_gpio.h" -#include "stm32f0xx_hal_tim.h" -#include "stm32f0xx_hal_tim_ex.h" - -extern TIM_HandleTypeDef htim3; - -void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin){ - if(GPIO_Pin == MotRSpd_Pin){ - HAL_GPIO_TogglePin(LED_0_GPIO_Port, LED_0_Pin); - } -} - -void app_main(){ - - HAL_TIM_PWM_Start(&htim3, TIM_CHANNEL_1); - __HAL_TIM_SET_COMPARE(&htim3, TIM_CHANNEL_1, 800); - - for(;;){ - // HAL_GPIO_TogglePin(LED_0_GPIO_Port, LED_0_Pin); - HAL_Delay(500); - } -} diff --git a/SW/spu/app/blinky/stm32f030/.mxproject b/SW/spu/app/blinky/stm32f030/.mxproject deleted file mode 100644 index c186ade..0000000 --- a/SW/spu/app/blinky/stm32f030/.mxproject +++ /dev/null @@ -1,14 +0,0 @@ -[PreviousLibFiles] -LibFiles=Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_tim.h;Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_ll_tim.h;Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_tim_ex.h;Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_rcc.h;Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_ll_rcc.h;Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_rcc_ex.h;Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_ll_bus.h;Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_ll_crs.h;Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_ll_system.h;Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_ll_utils.h;Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal.h;Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_def.h;Drivers/STM32F0xx_HAL_Driver/Inc/Legacy/stm32_hal_legacy.h;Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_i2c.h;Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_i2c_ex.h;Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_gpio.h;Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_gpio_ex.h;Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_ll_gpio.h;Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_dma_ex.h;Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_dma.h;Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_ll_dma.h;Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_cortex.h;Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_ll_cortex.h;Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_pwr.h;Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_pwr_ex.h;Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_ll_pwr.h;Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_flash.h;Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_flash_ex.h;Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_exti.h;Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_ll_exti.h;Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_tim.c;Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_tim_ex.c;Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_rcc.c;Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_rcc_ex.c;Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal.c;Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_i2c.c;Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_i2c_ex.c;Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_gpio.c;Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_dma.c;Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_cortex.c;Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pwr.c;Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pwr_ex.c;Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_flash.c;Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_flash_ex.c;Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_exti.c;Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_tim.h;Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_ll_tim.h;Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_tim_ex.h;Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_rcc.h;Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_ll_rcc.h;Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_rcc_ex.h;Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_ll_bus.h;Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_ll_crs.h;Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_ll_system.h;Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_ll_utils.h;Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal.h;Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_def.h;Drivers/STM32F0xx_HAL_Driver/Inc/Legacy/stm32_hal_legacy.h;Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_i2c.h;Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_i2c_ex.h;Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_gpio.h;Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_gpio_ex.h;Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_ll_gpio.h;Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_dma_ex.h;Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_dma.h;Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_ll_dma.h;Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_cortex.h;Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_ll_cortex.h;Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_pwr.h;Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_pwr_ex.h;Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_ll_pwr.h;Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_flash.h;Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_flash_ex.h;Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_exti.h;Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_ll_exti.h;Drivers/CMSIS/Device/ST/STM32F0xx/Include/stm32f030x8.h;Drivers/CMSIS/Device/ST/STM32F0xx/Include/stm32f0xx.h;Drivers/CMSIS/Device/ST/STM32F0xx/Include/system_stm32f0xx.h;Drivers/CMSIS/Device/ST/STM32F0xx/Include/system_stm32f0xx.h;Drivers/CMSIS/Device/ST/STM32F0xx/Source/Templates/system_stm32f0xx.c;Drivers/CMSIS/Include/cmsis_gcc.h;Drivers/CMSIS/Include/core_cm7.h;Drivers/CMSIS/Include/tz_context.h;Drivers/CMSIS/Include/core_cm0plus.h;Drivers/CMSIS/Include/cmsis_armclang.h;Drivers/CMSIS/Include/cmsis_version.h;Drivers/CMSIS/Include/cmsis_compiler.h;Drivers/CMSIS/Include/core_cm23.h;Drivers/CMSIS/Include/core_cm1.h;Drivers/CMSIS/Include/mpu_armv7.h;Drivers/CMSIS/Include/cmsis_iccarm.h;Drivers/CMSIS/Include/core_armv8mbl.h;Drivers/CMSIS/Include/core_cm3.h;Drivers/CMSIS/Include/core_sc000.h;Drivers/CMSIS/Include/mpu_armv8.h;Drivers/CMSIS/Include/core_cm33.h;Drivers/CMSIS/Include/core_cm0.h;Drivers/CMSIS/Include/core_sc300.h;Drivers/CMSIS/Include/cmsis_armcc.h;Drivers/CMSIS/Include/core_armv8mml.h;Drivers/CMSIS/Include/core_cm4.h; - -[PreviousUsedCMakes] -SourceFiles=Src/main.c;Src/stm32f0xx_it.c;Src/stm32f0xx_hal_msp.c;/data/joppe/projects/RoboRob/SW/spu/vendor/STM32CubeF0/Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_tim.c;/data/joppe/projects/RoboRob/SW/spu/vendor/STM32CubeF0/Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_tim_ex.c;/data/joppe/projects/RoboRob/SW/spu/vendor/STM32CubeF0/Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_rcc.c;/data/joppe/projects/RoboRob/SW/spu/vendor/STM32CubeF0/Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_rcc_ex.c;/data/joppe/projects/RoboRob/SW/spu/vendor/STM32CubeF0/Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal.c;/data/joppe/projects/RoboRob/SW/spu/vendor/STM32CubeF0/Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_i2c.c;/data/joppe/projects/RoboRob/SW/spu/vendor/STM32CubeF0/Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_i2c_ex.c;/data/joppe/projects/RoboRob/SW/spu/vendor/STM32CubeF0/Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_gpio.c;/data/joppe/projects/RoboRob/SW/spu/vendor/STM32CubeF0/Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_dma.c;/data/joppe/projects/RoboRob/SW/spu/vendor/STM32CubeF0/Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_cortex.c;/data/joppe/projects/RoboRob/SW/spu/vendor/STM32CubeF0/Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pwr.c;/data/joppe/projects/RoboRob/SW/spu/vendor/STM32CubeF0/Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pwr_ex.c;/data/joppe/projects/RoboRob/SW/spu/vendor/STM32CubeF0/Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_flash.c;/data/joppe/projects/RoboRob/SW/spu/vendor/STM32CubeF0/Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_flash_ex.c;/data/joppe/projects/RoboRob/SW/spu/vendor/STM32CubeF0/Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_exti.c;/data/joppe/projects/RoboRob/SW/spu/vendor/STM32CubeF0/Drivers/CMSIS/Device/ST/STM32F0xx/Source/Templates/system_stm32f0xx.c;Src/system_stm32f0xx.c;/data/joppe/projects/RoboRob/SW/spu/vendor/STM32CubeF0/Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_tim.c;/data/joppe/projects/RoboRob/SW/spu/vendor/STM32CubeF0/Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_tim_ex.c;/data/joppe/projects/RoboRob/SW/spu/vendor/STM32CubeF0/Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_rcc.c;/data/joppe/projects/RoboRob/SW/spu/vendor/STM32CubeF0/Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_rcc_ex.c;/data/joppe/projects/RoboRob/SW/spu/vendor/STM32CubeF0/Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal.c;/data/joppe/projects/RoboRob/SW/spu/vendor/STM32CubeF0/Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_i2c.c;/data/joppe/projects/RoboRob/SW/spu/vendor/STM32CubeF0/Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_i2c_ex.c;/data/joppe/projects/RoboRob/SW/spu/vendor/STM32CubeF0/Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_gpio.c;/data/joppe/projects/RoboRob/SW/spu/vendor/STM32CubeF0/Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_dma.c;/data/joppe/projects/RoboRob/SW/spu/vendor/STM32CubeF0/Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_cortex.c;/data/joppe/projects/RoboRob/SW/spu/vendor/STM32CubeF0/Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pwr.c;/data/joppe/projects/RoboRob/SW/spu/vendor/STM32CubeF0/Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pwr_ex.c;/data/joppe/projects/RoboRob/SW/spu/vendor/STM32CubeF0/Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_flash.c;/data/joppe/projects/RoboRob/SW/spu/vendor/STM32CubeF0/Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_flash_ex.c;/data/joppe/projects/RoboRob/SW/spu/vendor/STM32CubeF0/Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_exti.c;/data/joppe/projects/RoboRob/SW/spu/vendor/STM32CubeF0/Drivers/CMSIS/Device/ST/STM32F0xx/Source/Templates/system_stm32f0xx.c;Src/system_stm32f0xx.c;;; -HeaderPath=/data/joppe/projects/RoboRob/SW/spu/vendor/STM32CubeF0/Drivers/STM32F0xx_HAL_Driver/Inc;/data/joppe/projects/RoboRob/SW/spu/vendor/STM32CubeF0/Drivers/STM32F0xx_HAL_Driver/Inc/Legacy;/data/joppe/projects/RoboRob/SW/spu/vendor/STM32CubeF0/Drivers/CMSIS/Device/ST/STM32F0xx/Include;/data/joppe/projects/RoboRob/SW/spu/vendor/STM32CubeF0/Drivers/CMSIS/Include;Inc; -CDefines=USE_HAL_DRIVER;STM32F030x8;USE_HAL_DRIVER;USE_HAL_DRIVER; - -[PreviousGenFiles] -HeaderPath=../Inc -HeaderFiles=stm32f0xx_it.h;stm32f0xx_hal_conf.h;main.h; -SourcePath=../Src -SourceFiles=stm32f0xx_it.c;stm32f0xx_hal_msp.c;main.c; - diff --git a/SW/spu/app/blinky/stm32f030/Src/stm32f0xx_hal_msp.c b/SW/spu/app/blinky/stm32f030/Src/stm32f0xx_hal_msp.c deleted file mode 100644 index 758b876..0000000 --- a/SW/spu/app/blinky/stm32f030/Src/stm32f0xx_hal_msp.c +++ /dev/null @@ -1,155 +0,0 @@ -/* USER CODE BEGIN Header */ -/** - ****************************************************************************** - * @file stm32f0xx_hal_msp.c - * @brief This file provides code for the MSP Initialization - * and de-Initialization codes. - ****************************************************************************** - * @attention - * - * Copyright (c) 2026 STMicroelectronics. - * All rights reserved. - * - * This software is licensed under terms that can be found in the LICENSE file - * in the root directory of this software component. - * If no LICENSE file comes with this software, it is provided AS-IS. - * - ****************************************************************************** - */ -/* USER CODE END Header */ -/* Includes ------------------------------------------------------------------*/ -#include "main.h" -/* USER CODE BEGIN Includes */ - -/* USER CODE END Includes */ - -/* Private typedef -----------------------------------------------------------*/ -/* USER CODE BEGIN TD */ - -/* USER CODE END TD */ - -/* Private define ------------------------------------------------------------*/ -/* USER CODE BEGIN Define */ - -/* USER CODE END Define */ - -/* Private macro -------------------------------------------------------------*/ -/* USER CODE BEGIN Macro */ - -/* USER CODE END Macro */ - -/* Private variables ---------------------------------------------------------*/ -/* USER CODE BEGIN PV */ - -/* USER CODE END PV */ - -/* Private function prototypes -----------------------------------------------*/ -/* USER CODE BEGIN PFP */ - -/* USER CODE END PFP */ - -/* External functions --------------------------------------------------------*/ -/* USER CODE BEGIN ExternalFunctions */ - -/* USER CODE END ExternalFunctions */ - -/* USER CODE BEGIN 0 */ - -/* USER CODE END 0 */ - -void HAL_TIM_MspPostInit(TIM_HandleTypeDef *htim); - /** - * 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 TIM_Base MSP Initialization - * This function configures the hardware resources used in this example - * @param htim_base: TIM_Base handle pointer - * @retval None - */ -void HAL_TIM_Base_MspInit(TIM_HandleTypeDef* htim_base) -{ - if(htim_base->Instance==TIM3) - { - /* USER CODE BEGIN TIM3_MspInit 0 */ - - /* USER CODE END TIM3_MspInit 0 */ - /* Peripheral clock enable */ - __HAL_RCC_TIM3_CLK_ENABLE(); - /* USER CODE BEGIN TIM3_MspInit 1 */ - - /* USER CODE END TIM3_MspInit 1 */ - - } - -} - -void HAL_TIM_MspPostInit(TIM_HandleTypeDef* htim) -{ - GPIO_InitTypeDef GPIO_InitStruct = {0}; - if(htim->Instance==TIM3) - { - /* USER CODE BEGIN TIM3_MspPostInit 0 */ - - /* USER CODE END TIM3_MspPostInit 0 */ - - __HAL_RCC_GPIOA_CLK_ENABLE(); - /**TIM3 GPIO Configuration - PA6 ------> TIM3_CH1 - PA7 ------> TIM3_CH2 - */ - GPIO_InitStruct.Pin = MotRFwd_Pin|MotRRev_Pin; - GPIO_InitStruct.Mode = GPIO_MODE_AF_PP; - GPIO_InitStruct.Pull = GPIO_NOPULL; - GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW; - GPIO_InitStruct.Alternate = GPIO_AF1_TIM3; - HAL_GPIO_Init(GPIOA, &GPIO_InitStruct); - - /* USER CODE BEGIN TIM3_MspPostInit 1 */ - - /* USER CODE END TIM3_MspPostInit 1 */ - } - -} -/** - * @brief TIM_Base MSP De-Initialization - * This function freeze the hardware resources used in this example - * @param htim_base: TIM_Base handle pointer - * @retval None - */ -void HAL_TIM_Base_MspDeInit(TIM_HandleTypeDef* htim_base) -{ - if(htim_base->Instance==TIM3) - { - /* USER CODE BEGIN TIM3_MspDeInit 0 */ - - /* USER CODE END TIM3_MspDeInit 0 */ - /* Peripheral clock disable */ - __HAL_RCC_TIM3_CLK_DISABLE(); - /* USER CODE BEGIN TIM3_MspDeInit 1 */ - - /* USER CODE END TIM3_MspDeInit 1 */ - } - -} - -/* USER CODE BEGIN 1 */ - -/* USER CODE END 1 */ diff --git a/SW/spu/app/blinky/stm32f030/stm32f030.ioc b/SW/spu/app/blinky/stm32f030/stm32f030.ioc deleted file mode 100644 index 3ff5810..0000000 --- a/SW/spu/app/blinky/stm32f030/stm32f030.ioc +++ /dev/null @@ -1,124 +0,0 @@ -#MicroXplorer Configuration settings - do not modify -CAD.formats= -CAD.pinconfig= -CAD.provider= -File.Version=6 -GPIO.groupedBy=Group By Peripherals -KeepUserPlacement=false -Mcu.CPN=STM32F030C8T6 -Mcu.Family=STM32F0 -Mcu.IP0=NVIC -Mcu.IP1=RCC -Mcu.IP2=SYS -Mcu.IP3=TIM3 -Mcu.IPNb=4 -Mcu.Name=STM32F030C8Tx -Mcu.Package=LQFP48 -Mcu.Pin0=PC13 -Mcu.Pin1=PA6 -Mcu.Pin2=PA7 -Mcu.Pin3=PB8 -Mcu.Pin4=VP_SYS_VS_Systick -Mcu.Pin5=VP_TIM3_VS_ClockSourceINT -Mcu.PinsNb=6 -Mcu.ThirdPartyNb=0 -Mcu.UserConstants= -Mcu.UserName=STM32F030C8Tx -MxCube.Version=6.17.0 -MxDb.Version=DB.6.0.170 -NVIC.EXTI4_15_IRQn=true\:0\:0\:false\:false\:true\:true\:true\:true -NVIC.ForceEnableDMAVector=true -NVIC.HardFault_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.SVC_IRQn=true\:0\:0\:false\:false\:true\:false\:false\:true -NVIC.SysTick_IRQn=true\:3\:0\:false\:false\:true\:false\:true\:false -PA6.GPIOParameters=GPIO_Label -PA6.GPIO_Label=MotRFwd -PA6.Locked=true -PA6.Signal=S_TIM3_CH1 -PA7.GPIOParameters=GPIO_Label -PA7.GPIO_Label=MotRRev -PA7.Locked=true -PA7.Signal=S_TIM3_CH2 -PB8.GPIOParameters=GPIO_Label -PB8.GPIO_Label=MotRSpd -PB8.Locked=true -PB8.Signal=GPXTI8 -PC13.GPIOParameters=GPIO_Label -PC13.GPIO_Label=LED_0 -PC13.Locked=true -PC13.Signal=GPIO_Output -PCC.Checker=false -PCC.Display=Plot\: All Steps -PCC.Line=STM32F0x0 Value Line -PCC.MCU=STM32F030C8Tx -PCC.PartNumber=STM32F030C8Tx -PCC.Series=STM32F0 -PCC.Temperature=25 -PCC.Vdd=3.6 -PinOutPanel.RotationAngle=0 -ProjectManager.AskForMigrate=true -ProjectManager.BackupPrevious=false -ProjectManager.CompilerLinker=GCC -ProjectManager.CompilerOptimize=6 -ProjectManager.ComputerToolchain=false -ProjectManager.CoupleFile=false -ProjectManager.CustomerFirmwarePackage=../../../vendor/STM32CubeF0 -ProjectManager.DefaultFWLocation=false -ProjectManager.DeletePrevious=true -ProjectManager.DeviceId=STM32F030C8Tx -ProjectManager.FirmwarePackage=STM32Cube FW_F0 V1.11.6 -ProjectManager.FreePins=false -ProjectManager.FreePinsContext= -ProjectManager.HalAssertFull=false -ProjectManager.HeapSize=0x80 -ProjectManager.KeepUserCode=true -ProjectManager.LastFirmware=true -ProjectManager.LibraryCopy=2 -ProjectManager.MainLocation=Src -ProjectManager.NoMain=false -ProjectManager.PreviousToolchain= -ProjectManager.ProjectBuild=false -ProjectManager.ProjectFileName=stm32f030.ioc -ProjectManager.ProjectName=stm32f030 -ProjectManager.ProjectStructure= -ProjectManager.RegisterCallBack= -ProjectManager.StackSize=0x400 -ProjectManager.TargetToolchain=CMake -ProjectManager.ToolChainLocation= -ProjectManager.UAScriptAfterPath= -ProjectManager.UAScriptBeforePath= -ProjectManager.UnderRoot=false -ProjectManager.functionlistsort=1-SystemClock_Config-RCC-false-HAL-false,2-MX_GPIO_Init-GPIO-false-HAL-true,3-MX_TIM3_Init-TIM3-false-HAL-true -RCC.AHBFreq_Value=48000000 -RCC.APB1Freq_Value=48000000 -RCC.APB1TimFreq_Value=48000000 -RCC.FCLKCortexFreq_Value=48000000 -RCC.FamilyName=M -RCC.HCLKFreq_Value=48000000 -RCC.IPParameters=AHBFreq_Value,APB1Freq_Value,APB1TimFreq_Value,FCLKCortexFreq_Value,FamilyName,HCLKFreq_Value,MCOFreq_Value,PLLCLKFreq_Value,PLLMCOFreq_Value,PLLMUL,SYSCLKFreq_VALUE,SYSCLKSource,TimSysFreq_Value,USART1Freq_Value -RCC.MCOFreq_Value=48000000 -RCC.PLLCLKFreq_Value=48000000 -RCC.PLLMCOFreq_Value=24000000 -RCC.PLLMUL=RCC_PLL_MUL12 -RCC.SYSCLKFreq_VALUE=48000000 -RCC.SYSCLKSource=RCC_SYSCLKSOURCE_PLLCLK -RCC.TimSysFreq_Value=48000000 -RCC.USART1Freq_Value=48000000 -SH.GPXTI8.0=GPIO_EXTI8 -SH.GPXTI8.ConfNb=1 -SH.S_TIM3_CH1.0=TIM3_CH1,PWM Generation1 CH1 -SH.S_TIM3_CH1.ConfNb=1 -SH.S_TIM3_CH2.0=TIM3_CH2,PWM Generation2 CH2 -SH.S_TIM3_CH2.ConfNb=1 -TIM3.AutoReloadPreload=TIM_AUTORELOAD_PRELOAD_ENABLE -TIM3.Channel-PWM\ Generation1\ CH1=TIM_CHANNEL_1 -TIM3.Channel-PWM\ Generation2\ CH2=TIM_CHANNEL_2 -TIM3.IPParameters=Channel-PWM Generation1 CH1,Channel-PWM Generation2 CH2,Period,AutoReloadPreload -TIM3.Period=1600 -VP_SYS_VS_Systick.Mode=SysTick -VP_SYS_VS_Systick.Signal=SYS_VS_Systick -VP_TIM3_VS_ClockSourceINT.Mode=Internal -VP_TIM3_VS_ClockSourceINT.Signal=TIM3_VS_ClockSourceINT -board=custom diff --git a/SW/spu/app/motor_control/src/app_main.c b/SW/spu/app/motor_control/src/app_main.c new file mode 100644 index 0000000..479db94 --- /dev/null +++ b/SW/spu/app/motor_control/src/app_main.c @@ -0,0 +1,207 @@ +#include "main.h" +#include "stm32f0xx_hal_tim.h" +#include "stm32f0xx_hal_tim_ex.h" +#include "stm32f0xx_hal_uart.h" + +#define PWM_MAX 3200 +#define CONTROL_PERIOD_MS 20 +#define SPEED_TIMEOUT_MS 500 +#define SPEED_FILTER_SHIFT 2 +#define TICKS_PER_REV 400 +#define UART_PRINT_PERIOD_MS 25 + +/* Simple PI gains. Output unit is PWM counts. */ +#define KP_PWM_PER_RPM 60 +#define KI_Q8 800 + +/* Positive drives CH1, negative drives CH2. */ +#define TARGET_RPM 20 + + +typedef struct { + volatile uint32_t last_edge_ms; + volatile uint32_t last_period_ms; + volatile uint32_t tick_count; +} MotorFeedback; + +static volatile uint8_t uart_tx_busy; +static uint8_t uart_tx_buf[20]; +static MotorFeedback motor_r; +static MotorFeedback motor_l; + +static void uart_send_status( + uint32_t now_ms, + uint32_t tick_r, + uint32_t target_r, + uint32_t tick_l, + uint32_t target_l +){ + if (uart_tx_busy) { + return; + } + + ((uint32_t*)uart_tx_buf)[0] = now_ms; + ((uint32_t*)uart_tx_buf)[1] = tick_r; + ((uint32_t*)uart_tx_buf)[2] = target_r; + ((uint32_t*)uart_tx_buf)[3] = tick_l; + ((uint32_t*)uart_tx_buf)[4] = target_l; + + uart_tx_busy = 1U; + if (HAL_UART_Transmit_DMA(&huart1, uart_tx_buf, sizeof(uart_tx_buf)) != HAL_OK) { + uart_tx_busy = 0U; + } +} + +static void motor_set_output( + uint32_t ch_fwd, + uint32_t ch_rev, + int32_t pwm +){ + uint32_t duty = (pwm >= 0) ? (uint32_t)pwm : (uint32_t)(-pwm); + + if (duty > PWM_MAX) { + duty = PWM_MAX; + } + + if (pwm >= 0) { + __HAL_TIM_SET_COMPARE(&htim3, ch_fwd, duty); + __HAL_TIM_SET_COMPARE(&htim3, ch_rev, 0); + } else { + __HAL_TIM_SET_COMPARE(&htim3, ch_fwd, 0); + __HAL_TIM_SET_COMPARE(&htim3, ch_rev, duty); + } +} + +void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin){ + if (GPIO_Pin == MotRSpd_Pin) { + uint32_t now = HAL_GetTick(); + + if (motor_r.last_edge_ms != 0U) { + motor_r.last_period_ms = now - motor_r.last_edge_ms; + } + + motor_r.last_edge_ms = now; + motor_r.tick_count++; + } else if (GPIO_Pin == MotLSpd_Pin) { + uint32_t now = HAL_GetTick(); + + if (motor_l.last_edge_ms != 0U) { + motor_l.last_period_ms = now - motor_l.last_edge_ms; + } + + motor_l.last_edge_ms = now; + motor_l.tick_count++; + } +} + +void HAL_UART_TxCpltCallback(UART_HandleTypeDef *huart){ + if (huart->Instance == USART1) { + uart_tx_busy = 0U; + } +} + +void app_main(void){ + int32_t speed_r_q8 = 0; + int32_t speed_l_q8 = 0; + int32_t integral_r_q8 = 0; + int32_t integral_l_q8 = 0; + uint32_t next_control_ms = HAL_GetTick(); + uint32_t next_uart_ms = next_control_ms; + uint32_t target_ticks_per_s = TARGET_RPM * TICKS_PER_REV / 60; + + HAL_TIM_PWM_Start(&htim3, TIM_CHANNEL_1); + HAL_TIM_PWM_Start(&htim3, TIM_CHANNEL_2); + HAL_TIM_PWM_Start(&htim3, TIM_CHANNEL_3); + HAL_TIM_PWM_Start(&htim3, TIM_CHANNEL_4); + + motor_set_output(TIM_CHANNEL_1, TIM_CHANNEL_2, 0); + motor_set_output(TIM_CHANNEL_3, TIM_CHANNEL_4, 0); + + for (;;) { + uint32_t now = HAL_GetTick(); + + if ((uint32_t)(now - next_control_ms) < CONTROL_PERIOD_MS) { + continue; + } + next_control_ms += CONTROL_PERIOD_MS; + + uint32_t edge_r_ms; + uint32_t period_r_ms; + uint32_t tick_r; + uint32_t edge_l_ms; + uint32_t period_l_ms; + uint32_t tick_l; + + __disable_irq(); + edge_r_ms = motor_r.last_edge_ms; + period_r_ms = motor_r.last_period_ms; + tick_r = motor_r.tick_count; + edge_l_ms = motor_l.last_edge_ms; + period_l_ms = motor_l.last_period_ms; + tick_l = motor_l.tick_count; + __enable_irq(); + + int32_t inst_r_rpm_q8 = 0; + int32_t inst_l_rpm_q8 = 0; + + /* + * One rising edge is 1/TICKS_PER_REV revolution: + * rpm = 60000 / (TICKS_PER_REV * period_ms) + */ + if ((edge_r_ms != 0U) && + ((now - edge_r_ms) < SPEED_TIMEOUT_MS) && + (period_r_ms != 0U)) { + inst_r_rpm_q8 = ((60000 / TICKS_PER_REV) << 8) / (int32_t)period_r_ms; + } + + if ((edge_l_ms != 0U) && + ((now - edge_l_ms) < SPEED_TIMEOUT_MS) && + (period_l_ms != 0U)) { + inst_l_rpm_q8 = ((60000 / TICKS_PER_REV) << 8) / (int32_t)period_l_ms; + } + + speed_r_q8 += (inst_r_rpm_q8 - speed_r_q8) >> SPEED_FILTER_SHIFT; + speed_l_q8 += (inst_l_rpm_q8 - speed_l_q8) >> SPEED_FILTER_SHIFT; + + int32_t error_r_q8 = (TARGET_RPM << 8) - speed_r_q8; + int32_t error_l_q8 = (TARGET_RPM << 8) - speed_l_q8; + integral_r_q8 += (error_r_q8 * KI_Q8) >> 8; + integral_l_q8 += (error_l_q8 * KI_Q8) >> 8; + + if (integral_r_q8 > (PWM_MAX << 8)) { + integral_r_q8 = PWM_MAX << 8; + } else if (integral_r_q8 < -(PWM_MAX << 8)) { + integral_r_q8 = -(PWM_MAX << 8); + } + + if (integral_l_q8 > (PWM_MAX << 8)) { + integral_l_q8 = PWM_MAX << 8; + } else if (integral_l_q8 < -(PWM_MAX << 8)) { + integral_l_q8 = -(PWM_MAX << 8); + } + + int32_t pwm_r = (error_r_q8 * KP_PWM_PER_RPM + integral_r_q8) >> 8; + int32_t pwm_l = (error_l_q8 * KP_PWM_PER_RPM + integral_l_q8) >> 8; + + if (pwm_r > PWM_MAX) { + pwm_r = PWM_MAX; + } else if (pwm_r < -PWM_MAX) { + pwm_r = -PWM_MAX; + } + + if (pwm_l > PWM_MAX) { + pwm_l = PWM_MAX; + } else if (pwm_l < -PWM_MAX) { + pwm_l = -PWM_MAX; + } + + motor_set_output(TIM_CHANNEL_1, TIM_CHANNEL_2, pwm_r); + motor_set_output(TIM_CHANNEL_3, TIM_CHANNEL_4, pwm_l); + + if ((uint32_t)(now - next_uart_ms) >= UART_PRINT_PERIOD_MS) { + next_uart_ms += UART_PRINT_PERIOD_MS; + uart_send_status(now, tick_r, target_ticks_per_s, tick_l, target_ticks_per_s); + HAL_GPIO_TogglePin(LED_0_GPIO_Port, LED_0_Pin); + } + } +} diff --git a/SW/spu/app/blinky/stm32f030/.gitignore b/SW/spu/app/motor_control/stm32f030/.gitignore similarity index 100% rename from SW/spu/app/blinky/stm32f030/.gitignore rename to SW/spu/app/motor_control/stm32f030/.gitignore diff --git a/SW/spu/app/motor_control/stm32f030/.mxproject b/SW/spu/app/motor_control/stm32f030/.mxproject new file mode 100644 index 0000000..a3dcae9 --- /dev/null +++ b/SW/spu/app/motor_control/stm32f030/.mxproject @@ -0,0 +1,14 @@ +[PreviousLibFiles] +LibFiles=Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_tim.h;Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_ll_tim.h;Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_tim_ex.h;Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_rcc.h;Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_ll_rcc.h;Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_rcc_ex.h;Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_ll_bus.h;Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_ll_crs.h;Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_ll_system.h;Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_ll_utils.h;Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal.h;Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_def.h;Drivers/STM32F0xx_HAL_Driver/Inc/Legacy/stm32_hal_legacy.h;Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_i2c.h;Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_i2c_ex.h;Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_gpio.h;Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_gpio_ex.h;Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_ll_gpio.h;Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_dma_ex.h;Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_dma.h;Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_ll_dma.h;Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_cortex.h;Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_ll_cortex.h;Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_pwr.h;Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_pwr_ex.h;Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_ll_pwr.h;Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_flash.h;Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_flash_ex.h;Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_exti.h;Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_ll_exti.h;Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_uart.h;Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_ll_usart.h;Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_uart_ex.h;Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_tim.c;Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_tim_ex.c;Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_rcc.c;Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_rcc_ex.c;Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal.c;Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_i2c.c;Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_i2c_ex.c;Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_gpio.c;Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_dma.c;Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_cortex.c;Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pwr.c;Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pwr_ex.c;Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_flash.c;Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_flash_ex.c;Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_exti.c;Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_uart.c;Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_uart_ex.c;Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_tim.h;Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_ll_tim.h;Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_tim_ex.h;Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_rcc.h;Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_ll_rcc.h;Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_rcc_ex.h;Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_ll_bus.h;Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_ll_crs.h;Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_ll_system.h;Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_ll_utils.h;Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal.h;Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_def.h;Drivers/STM32F0xx_HAL_Driver/Inc/Legacy/stm32_hal_legacy.h;Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_i2c.h;Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_i2c_ex.h;Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_gpio.h;Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_gpio_ex.h;Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_ll_gpio.h;Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_dma_ex.h;Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_dma.h;Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_ll_dma.h;Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_cortex.h;Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_ll_cortex.h;Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_pwr.h;Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_pwr_ex.h;Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_ll_pwr.h;Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_flash.h;Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_flash_ex.h;Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_exti.h;Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_ll_exti.h;Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_uart.h;Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_ll_usart.h;Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_uart_ex.h;Drivers/CMSIS/Device/ST/STM32F0xx/Include/stm32f030x8.h;Drivers/CMSIS/Device/ST/STM32F0xx/Include/stm32f0xx.h;Drivers/CMSIS/Device/ST/STM32F0xx/Include/system_stm32f0xx.h;Drivers/CMSIS/Device/ST/STM32F0xx/Include/system_stm32f0xx.h;Drivers/CMSIS/Device/ST/STM32F0xx/Source/Templates/system_stm32f0xx.c;Drivers/CMSIS/Include/cmsis_gcc.h;Drivers/CMSIS/Include/core_cm7.h;Drivers/CMSIS/Include/tz_context.h;Drivers/CMSIS/Include/core_cm0plus.h;Drivers/CMSIS/Include/cmsis_armclang.h;Drivers/CMSIS/Include/cmsis_version.h;Drivers/CMSIS/Include/cmsis_compiler.h;Drivers/CMSIS/Include/core_cm23.h;Drivers/CMSIS/Include/core_cm1.h;Drivers/CMSIS/Include/mpu_armv7.h;Drivers/CMSIS/Include/cmsis_iccarm.h;Drivers/CMSIS/Include/core_armv8mbl.h;Drivers/CMSIS/Include/core_cm3.h;Drivers/CMSIS/Include/core_sc000.h;Drivers/CMSIS/Include/mpu_armv8.h;Drivers/CMSIS/Include/core_cm33.h;Drivers/CMSIS/Include/core_cm0.h;Drivers/CMSIS/Include/core_sc300.h;Drivers/CMSIS/Include/cmsis_armcc.h;Drivers/CMSIS/Include/core_armv8mml.h;Drivers/CMSIS/Include/core_cm4.h; + +[PreviousUsedCMakes] +SourceFiles=Src/main.c;Src/stm32f0xx_it.c;Src/stm32f0xx_hal_msp.c;/data/joppe/projects/RoboRob/SW/spu/vendor/STM32CubeF0/Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_tim.c;/data/joppe/projects/RoboRob/SW/spu/vendor/STM32CubeF0/Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_tim_ex.c;/data/joppe/projects/RoboRob/SW/spu/vendor/STM32CubeF0/Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_rcc.c;/data/joppe/projects/RoboRob/SW/spu/vendor/STM32CubeF0/Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_rcc_ex.c;/data/joppe/projects/RoboRob/SW/spu/vendor/STM32CubeF0/Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal.c;/data/joppe/projects/RoboRob/SW/spu/vendor/STM32CubeF0/Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_i2c.c;/data/joppe/projects/RoboRob/SW/spu/vendor/STM32CubeF0/Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_i2c_ex.c;/data/joppe/projects/RoboRob/SW/spu/vendor/STM32CubeF0/Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_gpio.c;/data/joppe/projects/RoboRob/SW/spu/vendor/STM32CubeF0/Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_dma.c;/data/joppe/projects/RoboRob/SW/spu/vendor/STM32CubeF0/Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_cortex.c;/data/joppe/projects/RoboRob/SW/spu/vendor/STM32CubeF0/Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pwr.c;/data/joppe/projects/RoboRob/SW/spu/vendor/STM32CubeF0/Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pwr_ex.c;/data/joppe/projects/RoboRob/SW/spu/vendor/STM32CubeF0/Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_flash.c;/data/joppe/projects/RoboRob/SW/spu/vendor/STM32CubeF0/Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_flash_ex.c;/data/joppe/projects/RoboRob/SW/spu/vendor/STM32CubeF0/Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_exti.c;/data/joppe/projects/RoboRob/SW/spu/vendor/STM32CubeF0/Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_uart.c;/data/joppe/projects/RoboRob/SW/spu/vendor/STM32CubeF0/Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_uart_ex.c;/data/joppe/projects/RoboRob/SW/spu/vendor/STM32CubeF0/Drivers/CMSIS/Device/ST/STM32F0xx/Source/Templates/system_stm32f0xx.c;Src/system_stm32f0xx.c;/data/joppe/projects/RoboRob/SW/spu/vendor/STM32CubeF0/Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_tim.c;/data/joppe/projects/RoboRob/SW/spu/vendor/STM32CubeF0/Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_tim_ex.c;/data/joppe/projects/RoboRob/SW/spu/vendor/STM32CubeF0/Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_rcc.c;/data/joppe/projects/RoboRob/SW/spu/vendor/STM32CubeF0/Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_rcc_ex.c;/data/joppe/projects/RoboRob/SW/spu/vendor/STM32CubeF0/Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal.c;/data/joppe/projects/RoboRob/SW/spu/vendor/STM32CubeF0/Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_i2c.c;/data/joppe/projects/RoboRob/SW/spu/vendor/STM32CubeF0/Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_i2c_ex.c;/data/joppe/projects/RoboRob/SW/spu/vendor/STM32CubeF0/Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_gpio.c;/data/joppe/projects/RoboRob/SW/spu/vendor/STM32CubeF0/Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_dma.c;/data/joppe/projects/RoboRob/SW/spu/vendor/STM32CubeF0/Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_cortex.c;/data/joppe/projects/RoboRob/SW/spu/vendor/STM32CubeF0/Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pwr.c;/data/joppe/projects/RoboRob/SW/spu/vendor/STM32CubeF0/Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_pwr_ex.c;/data/joppe/projects/RoboRob/SW/spu/vendor/STM32CubeF0/Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_flash.c;/data/joppe/projects/RoboRob/SW/spu/vendor/STM32CubeF0/Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_flash_ex.c;/data/joppe/projects/RoboRob/SW/spu/vendor/STM32CubeF0/Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_exti.c;/data/joppe/projects/RoboRob/SW/spu/vendor/STM32CubeF0/Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_uart.c;/data/joppe/projects/RoboRob/SW/spu/vendor/STM32CubeF0/Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_uart_ex.c;/data/joppe/projects/RoboRob/SW/spu/vendor/STM32CubeF0/Drivers/CMSIS/Device/ST/STM32F0xx/Source/Templates/system_stm32f0xx.c;Src/system_stm32f0xx.c;;; +HeaderPath=/data/joppe/projects/RoboRob/SW/spu/vendor/STM32CubeF0/Drivers/STM32F0xx_HAL_Driver/Inc;/data/joppe/projects/RoboRob/SW/spu/vendor/STM32CubeF0/Drivers/STM32F0xx_HAL_Driver/Inc/Legacy;/data/joppe/projects/RoboRob/SW/spu/vendor/STM32CubeF0/Drivers/CMSIS/Device/ST/STM32F0xx/Include;/data/joppe/projects/RoboRob/SW/spu/vendor/STM32CubeF0/Drivers/CMSIS/Include;Inc; +CDefines=USE_HAL_DRIVER;STM32F030x8;USE_HAL_DRIVER;USE_HAL_DRIVER; + +[PreviousGenFiles] +HeaderPath=../Inc +HeaderFiles=stm32f0xx_it.h;stm32f0xx_hal_conf.h;main.h; +SourcePath=../Src +SourceFiles=stm32f0xx_it.c;stm32f0xx_hal_msp.c;main.c; + diff --git a/SW/spu/app/blinky/stm32f030/CMakeLists.txt b/SW/spu/app/motor_control/stm32f030/CMakeLists.txt similarity index 88% rename from SW/spu/app/blinky/stm32f030/CMakeLists.txt rename to SW/spu/app/motor_control/stm32f030/CMakeLists.txt index feb2da9..b0ee334 100644 --- a/SW/spu/app/blinky/stm32f030/CMakeLists.txt +++ b/SW/spu/app/motor_control/stm32f030/CMakeLists.txt @@ -10,7 +10,7 @@ endif() set(CMAKE_EXPORT_COMPILE_COMMANDS TRUE) set(CMAKE_TOOLCHAIN_FILE ${CMAKE_CURRENT_SOURCE_DIR}/cmake/gcc-arm-none-eabi.cmake) -project(blinky) +project(motor_control) enable_language(C ASM) set(CUBE_def @@ -40,6 +40,8 @@ set(CUBE_src ${CMAKE_CURRENT_SOURCE_DIR}/../../../vendor/STM32CubeF0/Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_flash.c ${CMAKE_CURRENT_SOURCE_DIR}/../../../vendor/STM32CubeF0/Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_flash_ex.c ${CMAKE_CURRENT_SOURCE_DIR}/../../../vendor/STM32CubeF0/Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_exti.c + ${CMAKE_CURRENT_SOURCE_DIR}/../../../vendor/STM32CubeF0/Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_uart.c + ${CMAKE_CURRENT_SOURCE_DIR}/../../../vendor/STM32CubeF0/Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_uart_ex.c ) set(CUBE_inc @@ -50,14 +52,14 @@ set(CUBE_inc ${CMAKE_CURRENT_SOURCE_DIR}/../../../vendor/STM32CubeF0/Drivers/CMSIS/Include ) -add_executable(blinky +add_executable(motor_control ${CUBE_src} ${CMAKE_CURRENT_SOURCE_DIR}/../src/app_main.c ) -target_include_directories(blinky PUBLIC +target_include_directories(motor_control PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/../src ${CUBE_inc} ) -target_compile_definitions(blinky PUBLIC +target_compile_definitions(motor_control PUBLIC ${CUBE_def} -) \ No newline at end of file +) diff --git a/SW/spu/app/blinky/stm32f030/CMakePresets.json b/SW/spu/app/motor_control/stm32f030/CMakePresets.json similarity index 100% rename from SW/spu/app/blinky/stm32f030/CMakePresets.json rename to SW/spu/app/motor_control/stm32f030/CMakePresets.json diff --git a/SW/spu/app/blinky/stm32f030/Inc/main.h b/SW/spu/app/motor_control/stm32f030/Inc/main.h similarity index 73% rename from SW/spu/app/blinky/stm32f030/Inc/main.h rename to SW/spu/app/motor_control/stm32f030/Inc/main.h index c9e4341..f8038e9 100644 --- a/SW/spu/app/blinky/stm32f030/Inc/main.h +++ b/SW/spu/app/motor_control/stm32f030/Inc/main.h @@ -61,16 +61,36 @@ void Error_Handler(void); /* Private defines -----------------------------------------------------------*/ #define LED_0_Pin GPIO_PIN_13 #define LED_0_GPIO_Port GPIOC +#define LED_BLUE_Pin GPIO_PIN_2 +#define LED_BLUE_GPIO_Port GPIOA +#define LED_RED_Pin GPIO_PIN_3 +#define LED_RED_GPIO_Port GPIOA +#define MotLRBrush_Pin GPIO_PIN_4 +#define MotLRBrush_GPIO_Port GPIOA +#define MotLSpd_Pin GPIO_PIN_5 +#define MotLSpd_GPIO_Port GPIOA +#define MotLSpd_EXTI_IRQn EXTI4_15_IRQn #define MotRFwd_Pin GPIO_PIN_6 #define MotRFwd_GPIO_Port GPIOA #define MotRRev_Pin GPIO_PIN_7 #define MotRRev_GPIO_Port GPIOA -#define MotRSpd_Pin GPIO_PIN_8 +#define MotLFwd_Pin GPIO_PIN_0 +#define MotLFwd_GPIO_Port GPIOB +#define MotLRev_Pin GPIO_PIN_1 +#define MotLRev_GPIO_Port GPIOB +#define MotRSpd_Pin GPIO_PIN_2 #define MotRSpd_GPIO_Port GPIOB -#define MotRSpd_EXTI_IRQn EXTI4_15_IRQn +#define TX_Pin GPIO_PIN_9 +#define TX_GPIO_Port GPIOA +#define RX_Pin GPIO_PIN_10 +#define RX_GPIO_Port GPIOA /* USER CODE BEGIN Private defines */ +#define MotPwmTimerHandle htim3 +extern TIM_HandleTypeDef htim3; +#define UartHandle huart1 +extern UART_HandleTypeDef huart1; /* USER CODE END Private defines */ #ifdef __cplusplus diff --git a/SW/spu/app/blinky/stm32f030/Inc/stm32f0xx_hal_conf.h b/SW/spu/app/motor_control/stm32f030/Inc/stm32f0xx_hal_conf.h similarity index 97% rename from SW/spu/app/blinky/stm32f030/Inc/stm32f0xx_hal_conf.h rename to SW/spu/app/motor_control/stm32f030/Inc/stm32f0xx_hal_conf.h index cf63982..1ffa392 100644 --- a/SW/spu/app/blinky/stm32f030/Inc/stm32f0xx_hal_conf.h +++ b/SW/spu/app/motor_control/stm32f030/Inc/stm32f0xx_hal_conf.h @@ -50,7 +50,7 @@ /*#define HAL_RTC_MODULE_ENABLED */ /*#define HAL_SPI_MODULE_ENABLED */ #define HAL_TIM_MODULE_ENABLED -/*#define HAL_UART_MODULE_ENABLED */ +#define HAL_UART_MODULE_ENABLED /*#define HAL_USART_MODULE_ENABLED */ /*#define HAL_IRDA_MODULE_ENABLED */ /*#define HAL_SMARTCARD_MODULE_ENABLED */ diff --git a/SW/spu/app/blinky/stm32f030/Inc/stm32f0xx_it.h b/SW/spu/app/motor_control/stm32f030/Inc/stm32f0xx_it.h similarity index 92% rename from SW/spu/app/blinky/stm32f030/Inc/stm32f0xx_it.h rename to SW/spu/app/motor_control/stm32f030/Inc/stm32f0xx_it.h index 0d5a6c8..ea0315d 100644 --- a/SW/spu/app/blinky/stm32f030/Inc/stm32f0xx_it.h +++ b/SW/spu/app/motor_control/stm32f030/Inc/stm32f0xx_it.h @@ -52,6 +52,8 @@ void SVC_Handler(void); void PendSV_Handler(void); void SysTick_Handler(void); void EXTI4_15_IRQHandler(void); +void DMA1_Channel2_3_IRQHandler(void); +void USART1_IRQHandler(void); /* USER CODE BEGIN EFP */ /* USER CODE END EFP */ diff --git a/SW/spu/app/blinky/stm32f030/STM32F030XX_FLASH.ld b/SW/spu/app/motor_control/stm32f030/STM32F030XX_FLASH.ld similarity index 100% rename from SW/spu/app/blinky/stm32f030/STM32F030XX_FLASH.ld rename to SW/spu/app/motor_control/stm32f030/STM32F030XX_FLASH.ld diff --git a/SW/spu/app/blinky/stm32f030/Src/main.c b/SW/spu/app/motor_control/stm32f030/Src/main.c similarity index 54% rename from SW/spu/app/blinky/stm32f030/Src/main.c rename to SW/spu/app/motor_control/stm32f030/Src/main.c index fdfbfaf..5fd2492 100644 --- a/SW/spu/app/blinky/stm32f030/Src/main.c +++ b/SW/spu/app/motor_control/stm32f030/Src/main.c @@ -41,6 +41,12 @@ /* Private variables ---------------------------------------------------------*/ TIM_HandleTypeDef htim3; +TIM_HandleTypeDef htim14; +TIM_HandleTypeDef htim15; + +UART_HandleTypeDef huart1; +DMA_HandleTypeDef hdma_usart1_rx; +DMA_HandleTypeDef hdma_usart1_tx; /* USER CODE BEGIN PV */ @@ -49,7 +55,11 @@ TIM_HandleTypeDef htim3; /* Private function prototypes -----------------------------------------------*/ void SystemClock_Config(void); static void MX_GPIO_Init(void); +static void MX_DMA_Init(void); static void MX_TIM3_Init(void); +static void MX_USART1_UART_Init(void); +static void MX_TIM15_Init(void); +static void MX_TIM14_Init(void); /* USER CODE BEGIN PFP */ /* USER CODE END PFP */ @@ -88,7 +98,11 @@ int main(void) /* Initialize all configured peripherals */ MX_GPIO_Init(); + MX_DMA_Init(); MX_TIM3_Init(); + MX_USART1_UART_Init(); + MX_TIM15_Init(); + MX_TIM14_Init(); /* USER CODE BEGIN 2 */ extern void app_main(); app_main(); @@ -113,6 +127,7 @@ 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. @@ -141,6 +156,12 @@ void SystemClock_Config(void) { Error_Handler(); } + PeriphClkInit.PeriphClockSelection = RCC_PERIPHCLK_USART1; + PeriphClkInit.Usart1ClockSelection = RCC_USART1CLKSOURCE_PCLK1; + if (HAL_RCCEx_PeriphCLKConfig(&PeriphClkInit) != HAL_OK) + { + Error_Handler(); + } } /** @@ -165,7 +186,7 @@ static void MX_TIM3_Init(void) htim3.Instance = TIM3; htim3.Init.Prescaler = 0; htim3.Init.CounterMode = TIM_COUNTERMODE_UP; - htim3.Init.Period = 1600; + htim3.Init.Period = 3200; htim3.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1; htim3.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_ENABLE; if (HAL_TIM_Base_Init(&htim3) != HAL_OK) @@ -199,6 +220,14 @@ static void MX_TIM3_Init(void) { Error_Handler(); } + if (HAL_TIM_PWM_ConfigChannel(&htim3, &sConfigOC, TIM_CHANNEL_3) != HAL_OK) + { + Error_Handler(); + } + if (HAL_TIM_PWM_ConfigChannel(&htim3, &sConfigOC, TIM_CHANNEL_4) != HAL_OK) + { + Error_Handler(); + } /* USER CODE BEGIN TIM3_Init 2 */ /* USER CODE END TIM3_Init 2 */ @@ -206,6 +235,182 @@ static void MX_TIM3_Init(void) } +/** + * @brief TIM14 Initialization Function + * @param None + * @retval None + */ +static void MX_TIM14_Init(void) +{ + + /* USER CODE BEGIN TIM14_Init 0 */ + + /* USER CODE END TIM14_Init 0 */ + + TIM_OC_InitTypeDef sConfigOC = {0}; + + /* USER CODE BEGIN TIM14_Init 1 */ + + /* USER CODE END TIM14_Init 1 */ + htim14.Instance = TIM14; + htim14.Init.Prescaler = 0; + htim14.Init.CounterMode = TIM_COUNTERMODE_UP; + htim14.Init.Period = 1600; + htim14.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1; + htim14.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_ENABLE; + if (HAL_TIM_Base_Init(&htim14) != HAL_OK) + { + Error_Handler(); + } + if (HAL_TIM_PWM_Init(&htim14) != HAL_OK) + { + Error_Handler(); + } + sConfigOC.OCMode = TIM_OCMODE_PWM1; + sConfigOC.Pulse = 0; + sConfigOC.OCPolarity = TIM_OCPOLARITY_HIGH; + sConfigOC.OCFastMode = TIM_OCFAST_DISABLE; + if (HAL_TIM_PWM_ConfigChannel(&htim14, &sConfigOC, TIM_CHANNEL_1) != HAL_OK) + { + Error_Handler(); + } + /* USER CODE BEGIN TIM14_Init 2 */ + + /* USER CODE END TIM14_Init 2 */ + HAL_TIM_MspPostInit(&htim14); + +} + +/** + * @brief TIM15 Initialization Function + * @param None + * @retval None + */ +static void MX_TIM15_Init(void) +{ + + /* USER CODE BEGIN TIM15_Init 0 */ + + /* USER CODE END TIM15_Init 0 */ + + TIM_ClockConfigTypeDef sClockSourceConfig = {0}; + TIM_MasterConfigTypeDef sMasterConfig = {0}; + TIM_OC_InitTypeDef sConfigOC = {0}; + TIM_BreakDeadTimeConfigTypeDef sBreakDeadTimeConfig = {0}; + + /* USER CODE BEGIN TIM15_Init 1 */ + + /* USER CODE END TIM15_Init 1 */ + htim15.Instance = TIM15; + htim15.Init.Prescaler = 0; + htim15.Init.CounterMode = TIM_COUNTERMODE_UP; + htim15.Init.Period = 1600; + htim15.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1; + htim15.Init.RepetitionCounter = 0; + htim15.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_ENABLE; + if (HAL_TIM_Base_Init(&htim15) != HAL_OK) + { + Error_Handler(); + } + sClockSourceConfig.ClockSource = TIM_CLOCKSOURCE_INTERNAL; + if (HAL_TIM_ConfigClockSource(&htim15, &sClockSourceConfig) != HAL_OK) + { + Error_Handler(); + } + if (HAL_TIM_PWM_Init(&htim15) != HAL_OK) + { + Error_Handler(); + } + sMasterConfig.MasterOutputTrigger = TIM_TRGO_RESET; + sMasterConfig.MasterSlaveMode = TIM_MASTERSLAVEMODE_DISABLE; + if (HAL_TIMEx_MasterConfigSynchronization(&htim15, &sMasterConfig) != HAL_OK) + { + Error_Handler(); + } + sConfigOC.OCMode = TIM_OCMODE_PWM1; + sConfigOC.Pulse = 0; + sConfigOC.OCPolarity = TIM_OCPOLARITY_HIGH; + sConfigOC.OCNPolarity = TIM_OCNPOLARITY_HIGH; + sConfigOC.OCFastMode = TIM_OCFAST_DISABLE; + sConfigOC.OCIdleState = TIM_OCIDLESTATE_RESET; + sConfigOC.OCNIdleState = TIM_OCNIDLESTATE_RESET; + if (HAL_TIM_PWM_ConfigChannel(&htim15, &sConfigOC, TIM_CHANNEL_1) != HAL_OK) + { + Error_Handler(); + } + if (HAL_TIM_PWM_ConfigChannel(&htim15, &sConfigOC, TIM_CHANNEL_2) != HAL_OK) + { + Error_Handler(); + } + sBreakDeadTimeConfig.OffStateRunMode = TIM_OSSR_DISABLE; + sBreakDeadTimeConfig.OffStateIDLEMode = TIM_OSSI_DISABLE; + sBreakDeadTimeConfig.LockLevel = TIM_LOCKLEVEL_OFF; + sBreakDeadTimeConfig.DeadTime = 0; + sBreakDeadTimeConfig.BreakState = TIM_BREAK_DISABLE; + sBreakDeadTimeConfig.BreakPolarity = TIM_BREAKPOLARITY_HIGH; + sBreakDeadTimeConfig.AutomaticOutput = TIM_AUTOMATICOUTPUT_DISABLE; + if (HAL_TIMEx_ConfigBreakDeadTime(&htim15, &sBreakDeadTimeConfig) != HAL_OK) + { + Error_Handler(); + } + /* USER CODE BEGIN TIM15_Init 2 */ + + /* USER CODE END TIM15_Init 2 */ + HAL_TIM_MspPostInit(&htim15); + +} + +/** + * @brief USART1 Initialization Function + * @param None + * @retval None + */ +static void MX_USART1_UART_Init(void) +{ + + /* USER CODE BEGIN USART1_Init 0 */ + + /* USER CODE END USART1_Init 0 */ + + /* USER CODE BEGIN USART1_Init 1 */ + + /* USER CODE END USART1_Init 1 */ + huart1.Instance = USART1; + huart1.Init.BaudRate = 115200; + huart1.Init.WordLength = UART_WORDLENGTH_8B; + huart1.Init.StopBits = UART_STOPBITS_1; + huart1.Init.Parity = UART_PARITY_NONE; + huart1.Init.Mode = UART_MODE_TX_RX; + huart1.Init.HwFlowCtl = UART_HWCONTROL_NONE; + huart1.Init.OverSampling = UART_OVERSAMPLING_16; + huart1.Init.OneBitSampling = UART_ONE_BIT_SAMPLE_DISABLE; + huart1.AdvancedInit.AdvFeatureInit = UART_ADVFEATURE_NO_INIT; + if (HAL_UART_Init(&huart1) != HAL_OK) + { + Error_Handler(); + } + /* USER CODE BEGIN USART1_Init 2 */ + + /* USER CODE END USART1_Init 2 */ + +} + +/** + * Enable DMA controller clock + */ +static void MX_DMA_Init(void) +{ + + /* DMA controller clock enable */ + __HAL_RCC_DMA1_CLK_ENABLE(); + + /* DMA interrupt init */ + /* DMA1_Channel2_3_IRQn interrupt configuration */ + HAL_NVIC_SetPriority(DMA1_Channel2_3_IRQn, 0, 0); + HAL_NVIC_EnableIRQ(DMA1_Channel2_3_IRQn); + +} + /** * @brief GPIO Initialization Function * @param None @@ -233,6 +438,12 @@ static void MX_GPIO_Init(void) GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW; HAL_GPIO_Init(LED_0_GPIO_Port, &GPIO_InitStruct); + /*Configure GPIO pin : MotLSpd_Pin */ + GPIO_InitStruct.Pin = MotLSpd_Pin; + GPIO_InitStruct.Mode = GPIO_MODE_IT_RISING; + GPIO_InitStruct.Pull = GPIO_NOPULL; + HAL_GPIO_Init(MotLSpd_GPIO_Port, &GPIO_InitStruct); + /*Configure GPIO pin : MotRSpd_Pin */ GPIO_InitStruct.Pin = MotRSpd_Pin; GPIO_InitStruct.Mode = GPIO_MODE_IT_RISING; diff --git a/SW/spu/app/motor_control/stm32f030/Src/stm32f0xx_hal_msp.c b/SW/spu/app/motor_control/stm32f030/Src/stm32f0xx_hal_msp.c new file mode 100644 index 0000000..3787f40 --- /dev/null +++ b/SW/spu/app/motor_control/stm32f030/Src/stm32f0xx_hal_msp.c @@ -0,0 +1,361 @@ +/* USER CODE BEGIN Header */ +/** + ****************************************************************************** + * @file stm32f0xx_hal_msp.c + * @brief This file provides code for the MSP Initialization + * and de-Initialization codes. + ****************************************************************************** + * @attention + * + * Copyright (c) 2026 STMicroelectronics. + * All rights reserved. + * + * This software is licensed under terms that can be found in the LICENSE file + * in the root directory of this software component. + * If no LICENSE file comes with this software, it is provided AS-IS. + * + ****************************************************************************** + */ +/* USER CODE END Header */ +/* Includes ------------------------------------------------------------------*/ +#include "main.h" +/* USER CODE BEGIN Includes */ + +/* USER CODE END Includes */ +extern DMA_HandleTypeDef hdma_usart1_rx; + +extern DMA_HandleTypeDef hdma_usart1_tx; + +/* 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 */ + +void HAL_TIM_MspPostInit(TIM_HandleTypeDef *htim); + /** + * 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 TIM_Base MSP Initialization + * This function configures the hardware resources used in this example + * @param htim_base: TIM_Base handle pointer + * @retval None + */ +void HAL_TIM_Base_MspInit(TIM_HandleTypeDef* htim_base) +{ + if(htim_base->Instance==TIM3) + { + /* USER CODE BEGIN TIM3_MspInit 0 */ + + /* USER CODE END TIM3_MspInit 0 */ + /* Peripheral clock enable */ + __HAL_RCC_TIM3_CLK_ENABLE(); + /* USER CODE BEGIN TIM3_MspInit 1 */ + + /* USER CODE END TIM3_MspInit 1 */ + } + else if(htim_base->Instance==TIM14) + { + /* USER CODE BEGIN TIM14_MspInit 0 */ + + /* USER CODE END TIM14_MspInit 0 */ + /* Peripheral clock enable */ + __HAL_RCC_TIM14_CLK_ENABLE(); + /* USER CODE BEGIN TIM14_MspInit 1 */ + + /* USER CODE END TIM14_MspInit 1 */ + } + else if(htim_base->Instance==TIM15) + { + /* USER CODE BEGIN TIM15_MspInit 0 */ + + /* USER CODE END TIM15_MspInit 0 */ + /* Peripheral clock enable */ + __HAL_RCC_TIM15_CLK_ENABLE(); + /* USER CODE BEGIN TIM15_MspInit 1 */ + + /* USER CODE END TIM15_MspInit 1 */ + } + +} + +void HAL_TIM_MspPostInit(TIM_HandleTypeDef* htim) +{ + GPIO_InitTypeDef GPIO_InitStruct = {0}; + if(htim->Instance==TIM3) + { + /* USER CODE BEGIN TIM3_MspPostInit 0 */ + + /* USER CODE END TIM3_MspPostInit 0 */ + __HAL_RCC_GPIOA_CLK_ENABLE(); + __HAL_RCC_GPIOB_CLK_ENABLE(); + /**TIM3 GPIO Configuration + PA6 ------> TIM3_CH1 + PA7 ------> TIM3_CH2 + PB0 ------> TIM3_CH3 + PB1 ------> TIM3_CH4 + */ + GPIO_InitStruct.Pin = MotRFwd_Pin|MotRRev_Pin; + GPIO_InitStruct.Mode = GPIO_MODE_AF_PP; + GPIO_InitStruct.Pull = GPIO_NOPULL; + GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW; + GPIO_InitStruct.Alternate = GPIO_AF1_TIM3; + HAL_GPIO_Init(GPIOA, &GPIO_InitStruct); + + GPIO_InitStruct.Pin = MotLFwd_Pin|MotLRev_Pin; + GPIO_InitStruct.Mode = GPIO_MODE_AF_PP; + GPIO_InitStruct.Pull = GPIO_NOPULL; + GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW; + GPIO_InitStruct.Alternate = GPIO_AF1_TIM3; + HAL_GPIO_Init(GPIOB, &GPIO_InitStruct); + + /* USER CODE BEGIN TIM3_MspPostInit 1 */ + + /* USER CODE END TIM3_MspPostInit 1 */ + } + else if(htim->Instance==TIM14) + { + /* USER CODE BEGIN TIM14_MspPostInit 0 */ + + /* USER CODE END TIM14_MspPostInit 0 */ + + __HAL_RCC_GPIOA_CLK_ENABLE(); + /**TIM14 GPIO Configuration + PA4 ------> TIM14_CH1 + */ + GPIO_InitStruct.Pin = MotLRBrush_Pin; + GPIO_InitStruct.Mode = GPIO_MODE_AF_PP; + GPIO_InitStruct.Pull = GPIO_NOPULL; + GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW; + GPIO_InitStruct.Alternate = GPIO_AF4_TIM14; + HAL_GPIO_Init(MotLRBrush_GPIO_Port, &GPIO_InitStruct); + + /* USER CODE BEGIN TIM14_MspPostInit 1 */ + + /* USER CODE END TIM14_MspPostInit 1 */ + } + else if(htim->Instance==TIM15) + { + /* USER CODE BEGIN TIM15_MspPostInit 0 */ + + /* USER CODE END TIM15_MspPostInit 0 */ + + __HAL_RCC_GPIOA_CLK_ENABLE(); + /**TIM15 GPIO Configuration + PA2 ------> TIM15_CH1 + PA3 ------> TIM15_CH2 + */ + GPIO_InitStruct.Pin = LED_BLUE_Pin|LED_RED_Pin; + GPIO_InitStruct.Mode = GPIO_MODE_AF_PP; + GPIO_InitStruct.Pull = GPIO_NOPULL; + GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW; + GPIO_InitStruct.Alternate = GPIO_AF0_TIM15; + HAL_GPIO_Init(GPIOA, &GPIO_InitStruct); + + /* USER CODE BEGIN TIM15_MspPostInit 1 */ + + /* USER CODE END TIM15_MspPostInit 1 */ + } + +} +/** + * @brief TIM_Base MSP De-Initialization + * This function freeze the hardware resources used in this example + * @param htim_base: TIM_Base handle pointer + * @retval None + */ +void HAL_TIM_Base_MspDeInit(TIM_HandleTypeDef* htim_base) +{ + if(htim_base->Instance==TIM3) + { + /* USER CODE BEGIN TIM3_MspDeInit 0 */ + + /* USER CODE END TIM3_MspDeInit 0 */ + /* Peripheral clock disable */ + __HAL_RCC_TIM3_CLK_DISABLE(); + /* USER CODE BEGIN TIM3_MspDeInit 1 */ + + /* USER CODE END TIM3_MspDeInit 1 */ + } + else if(htim_base->Instance==TIM14) + { + /* USER CODE BEGIN TIM14_MspDeInit 0 */ + + /* USER CODE END TIM14_MspDeInit 0 */ + /* Peripheral clock disable */ + __HAL_RCC_TIM14_CLK_DISABLE(); + /* USER CODE BEGIN TIM14_MspDeInit 1 */ + + /* USER CODE END TIM14_MspDeInit 1 */ + } + else if(htim_base->Instance==TIM15) + { + /* USER CODE BEGIN TIM15_MspDeInit 0 */ + + /* USER CODE END TIM15_MspDeInit 0 */ + /* Peripheral clock disable */ + __HAL_RCC_TIM15_CLK_DISABLE(); + /* USER CODE BEGIN TIM15_MspDeInit 1 */ + + /* USER CODE END TIM15_MspDeInit 1 */ + } + +} + +/** + * @brief UART MSP Initialization + * This function configures the hardware resources used in this example + * @param huart: UART handle pointer + * @retval None + */ +void HAL_UART_MspInit(UART_HandleTypeDef* huart) +{ + GPIO_InitTypeDef GPIO_InitStruct = {0}; + if(huart->Instance==USART1) + { + /* USER CODE BEGIN USART1_MspInit 0 */ + + /* USER CODE END USART1_MspInit 0 */ + /* Peripheral clock enable */ + __HAL_RCC_USART1_CLK_ENABLE(); + + __HAL_RCC_GPIOA_CLK_ENABLE(); + /**USART1 GPIO Configuration + PA9 ------> USART1_TX + PA10 ------> USART1_RX + */ + GPIO_InitStruct.Pin = TX_Pin|RX_Pin; + GPIO_InitStruct.Mode = GPIO_MODE_AF_PP; + GPIO_InitStruct.Pull = GPIO_NOPULL; + GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH; + GPIO_InitStruct.Alternate = GPIO_AF1_USART1; + HAL_GPIO_Init(GPIOA, &GPIO_InitStruct); + + /* USART1 DMA Init */ + /* USART1_RX Init */ + hdma_usart1_rx.Instance = DMA1_Channel3; + hdma_usart1_rx.Init.Direction = DMA_PERIPH_TO_MEMORY; + hdma_usart1_rx.Init.PeriphInc = DMA_PINC_DISABLE; + hdma_usart1_rx.Init.MemInc = DMA_MINC_ENABLE; + hdma_usart1_rx.Init.PeriphDataAlignment = DMA_PDATAALIGN_BYTE; + hdma_usart1_rx.Init.MemDataAlignment = DMA_MDATAALIGN_BYTE; + hdma_usart1_rx.Init.Mode = DMA_NORMAL; + hdma_usart1_rx.Init.Priority = DMA_PRIORITY_LOW; + if (HAL_DMA_Init(&hdma_usart1_rx) != HAL_OK) + { + Error_Handler(); + } + + __HAL_LINKDMA(huart,hdmarx,hdma_usart1_rx); + + /* USART1_TX Init */ + hdma_usart1_tx.Instance = DMA1_Channel2; + hdma_usart1_tx.Init.Direction = DMA_MEMORY_TO_PERIPH; + hdma_usart1_tx.Init.PeriphInc = DMA_PINC_DISABLE; + hdma_usart1_tx.Init.MemInc = DMA_MINC_ENABLE; + hdma_usart1_tx.Init.PeriphDataAlignment = DMA_PDATAALIGN_BYTE; + hdma_usart1_tx.Init.MemDataAlignment = DMA_MDATAALIGN_BYTE; + hdma_usart1_tx.Init.Mode = DMA_NORMAL; + hdma_usart1_tx.Init.Priority = DMA_PRIORITY_LOW; + if (HAL_DMA_Init(&hdma_usart1_tx) != HAL_OK) + { + Error_Handler(); + } + + __HAL_LINKDMA(huart,hdmatx,hdma_usart1_tx); + + /* USART1 interrupt Init */ + HAL_NVIC_SetPriority(USART1_IRQn, 0, 0); + HAL_NVIC_EnableIRQ(USART1_IRQn); + /* USER CODE BEGIN USART1_MspInit 1 */ + + /* USER CODE END USART1_MspInit 1 */ + + } + +} + +/** + * @brief UART MSP De-Initialization + * This function freeze the hardware resources used in this example + * @param huart: UART handle pointer + * @retval None + */ +void HAL_UART_MspDeInit(UART_HandleTypeDef* huart) +{ + if(huart->Instance==USART1) + { + /* USER CODE BEGIN USART1_MspDeInit 0 */ + + /* USER CODE END USART1_MspDeInit 0 */ + /* Peripheral clock disable */ + __HAL_RCC_USART1_CLK_DISABLE(); + + /**USART1 GPIO Configuration + PA9 ------> USART1_TX + PA10 ------> USART1_RX + */ + HAL_GPIO_DeInit(GPIOA, TX_Pin|RX_Pin); + + /* USART1 DMA DeInit */ + HAL_DMA_DeInit(huart->hdmarx); + HAL_DMA_DeInit(huart->hdmatx); + + /* USART1 interrupt DeInit */ + HAL_NVIC_DisableIRQ(USART1_IRQn); + /* USER CODE BEGIN USART1_MspDeInit 1 */ + + /* USER CODE END USART1_MspDeInit 1 */ + } + +} + +/* USER CODE BEGIN 1 */ + +/* USER CODE END 1 */ diff --git a/SW/spu/app/blinky/stm32f030/Src/stm32f0xx_it.c b/SW/spu/app/motor_control/stm32f030/Src/stm32f0xx_it.c similarity index 80% rename from SW/spu/app/blinky/stm32f030/Src/stm32f0xx_it.c rename to SW/spu/app/motor_control/stm32f030/Src/stm32f0xx_it.c index 05bedf9..b915d6f 100644 --- a/SW/spu/app/blinky/stm32f030/Src/stm32f0xx_it.c +++ b/SW/spu/app/motor_control/stm32f030/Src/stm32f0xx_it.c @@ -55,7 +55,9 @@ /* USER CODE END 0 */ /* External variables --------------------------------------------------------*/ - +extern DMA_HandleTypeDef hdma_usart1_rx; +extern DMA_HandleTypeDef hdma_usart1_tx; +extern UART_HandleTypeDef huart1; /* USER CODE BEGIN EV */ /* USER CODE END EV */ @@ -148,12 +150,41 @@ void EXTI4_15_IRQHandler(void) /* USER CODE BEGIN EXTI4_15_IRQn 0 */ /* USER CODE END EXTI4_15_IRQn 0 */ - HAL_GPIO_EXTI_IRQHandler(MotRSpd_Pin); + HAL_GPIO_EXTI_IRQHandler(MotLSpd_Pin); /* USER CODE BEGIN EXTI4_15_IRQn 1 */ /* USER CODE END EXTI4_15_IRQn 1 */ } +/** + * @brief This function handles DMA1 channel 2 and 3 interrupts. + */ +void DMA1_Channel2_3_IRQHandler(void) +{ + /* USER CODE BEGIN DMA1_Channel2_3_IRQn 0 */ + + /* USER CODE END DMA1_Channel2_3_IRQn 0 */ + HAL_DMA_IRQHandler(&hdma_usart1_tx); + HAL_DMA_IRQHandler(&hdma_usart1_rx); + /* USER CODE BEGIN DMA1_Channel2_3_IRQn 1 */ + + /* USER CODE END DMA1_Channel2_3_IRQn 1 */ +} + +/** + * @brief This function handles USART1 global interrupt. + */ +void USART1_IRQHandler(void) +{ + /* USER CODE BEGIN USART1_IRQn 0 */ + + /* USER CODE END USART1_IRQn 0 */ + HAL_UART_IRQHandler(&huart1); + /* USER CODE BEGIN USART1_IRQn 1 */ + + /* USER CODE END USART1_IRQn 1 */ +} + /* USER CODE BEGIN 1 */ /* USER CODE END 1 */ diff --git a/SW/spu/app/blinky/stm32f030/Src/syscalls.c b/SW/spu/app/motor_control/stm32f030/Src/syscalls.c similarity index 100% rename from SW/spu/app/blinky/stm32f030/Src/syscalls.c rename to SW/spu/app/motor_control/stm32f030/Src/syscalls.c diff --git a/SW/spu/app/blinky/stm32f030/Src/sysmem.c b/SW/spu/app/motor_control/stm32f030/Src/sysmem.c similarity index 100% rename from SW/spu/app/blinky/stm32f030/Src/sysmem.c rename to SW/spu/app/motor_control/stm32f030/Src/sysmem.c diff --git a/SW/spu/app/blinky/stm32f030/Src/system_stm32f0xx.c b/SW/spu/app/motor_control/stm32f030/Src/system_stm32f0xx.c similarity index 100% rename from SW/spu/app/blinky/stm32f030/Src/system_stm32f0xx.c rename to SW/spu/app/motor_control/stm32f030/Src/system_stm32f0xx.c diff --git a/SW/spu/app/blinky/stm32f030/cmake/gcc-arm-none-eabi.cmake b/SW/spu/app/motor_control/stm32f030/cmake/gcc-arm-none-eabi.cmake similarity index 100% rename from SW/spu/app/blinky/stm32f030/cmake/gcc-arm-none-eabi.cmake rename to SW/spu/app/motor_control/stm32f030/cmake/gcc-arm-none-eabi.cmake diff --git a/SW/spu/app/blinky/stm32f030/cmake/starm-clang.cmake b/SW/spu/app/motor_control/stm32f030/cmake/starm-clang.cmake similarity index 100% rename from SW/spu/app/blinky/stm32f030/cmake/starm-clang.cmake rename to SW/spu/app/motor_control/stm32f030/cmake/starm-clang.cmake diff --git a/SW/spu/app/blinky/stm32f030/startup_stm32f030x8.s b/SW/spu/app/motor_control/stm32f030/startup_stm32f030x8.s similarity index 100% rename from SW/spu/app/blinky/stm32f030/startup_stm32f030x8.s rename to SW/spu/app/motor_control/stm32f030/startup_stm32f030x8.s diff --git a/SW/spu/app/motor_control/stm32f030/stm32f030.ioc b/SW/spu/app/motor_control/stm32f030/stm32f030.ioc new file mode 100644 index 0000000..5363355 --- /dev/null +++ b/SW/spu/app/motor_control/stm32f030/stm32f030.ioc @@ -0,0 +1,296 @@ +#MicroXplorer Configuration settings - do not modify +CAD.formats= +CAD.pinconfig= +CAD.provider= +Dma.Request0=USART1_RX +Dma.Request1=USART1_TX +Dma.RequestsNb=2 +Dma.USART1_RX.0.Direction=DMA_PERIPH_TO_MEMORY +Dma.USART1_RX.0.Instance=DMA1_Channel3 +Dma.USART1_RX.0.MemDataAlignment=DMA_MDATAALIGN_BYTE +Dma.USART1_RX.0.MemInc=DMA_MINC_ENABLE +Dma.USART1_RX.0.Mode=DMA_NORMAL +Dma.USART1_RX.0.PeriphDataAlignment=DMA_PDATAALIGN_BYTE +Dma.USART1_RX.0.PeriphInc=DMA_PINC_DISABLE +Dma.USART1_RX.0.Priority=DMA_PRIORITY_LOW +Dma.USART1_RX.0.RequestParameters=Instance,Direction,PeriphInc,MemInc,PeriphDataAlignment,MemDataAlignment,Mode,Priority +Dma.USART1_TX.1.Direction=DMA_MEMORY_TO_PERIPH +Dma.USART1_TX.1.Instance=DMA1_Channel2 +Dma.USART1_TX.1.MemDataAlignment=DMA_MDATAALIGN_BYTE +Dma.USART1_TX.1.MemInc=DMA_MINC_ENABLE +Dma.USART1_TX.1.Mode=DMA_NORMAL +Dma.USART1_TX.1.PeriphDataAlignment=DMA_PDATAALIGN_BYTE +Dma.USART1_TX.1.PeriphInc=DMA_PINC_DISABLE +Dma.USART1_TX.1.Priority=DMA_PRIORITY_LOW +Dma.USART1_TX.1.RequestParameters=Instance,Direction,PeriphInc,MemInc,PeriphDataAlignment,MemDataAlignment,Mode,Priority +File.Version=6 +GPIO.groupedBy=Group By Peripherals +KeepUserPlacement=false +Mcu.CPN=STM32F030C8T6 +Mcu.Family=STM32F0 +Mcu.IP0=ADC +Mcu.IP1=DMA +Mcu.IP10=USART1 +Mcu.IP2=NVIC +Mcu.IP3=RCC +Mcu.IP4=SYS +Mcu.IP5=TIM3 +Mcu.IP6=TIM14 +Mcu.IP7=TIM15 +Mcu.IP8=TIM16 +Mcu.IP9=TIM17 +Mcu.IPNb=11 +Mcu.Name=STM32F030C8Tx +Mcu.Package=LQFP48 +Mcu.Pin0=PC13 +Mcu.Pin1=PA0 +Mcu.Pin10=PB1 +Mcu.Pin11=PB2 +Mcu.Pin12=PB13 +Mcu.Pin13=PA8 +Mcu.Pin14=PA9 +Mcu.Pin15=PA10 +Mcu.Pin16=PA11 +Mcu.Pin17=PA13 +Mcu.Pin18=PA14 +Mcu.Pin19=PB6 +Mcu.Pin2=PA1 +Mcu.Pin20=PB7 +Mcu.Pin21=PB8 +Mcu.Pin22=PB9 +Mcu.Pin23=VP_SYS_VS_Systick +Mcu.Pin24=VP_TIM3_VS_ClockSourceINT +Mcu.Pin25=VP_TIM14_VS_ClockSourceINT +Mcu.Pin26=VP_TIM15_VS_ClockSourceINT +Mcu.Pin27=VP_TIM16_VS_ClockSourceINT +Mcu.Pin28=VP_TIM17_VS_ClockSourceINT +Mcu.Pin3=PA2 +Mcu.Pin4=PA3 +Mcu.Pin5=PA4 +Mcu.Pin6=PA5 +Mcu.Pin7=PA6 +Mcu.Pin8=PA7 +Mcu.Pin9=PB0 +Mcu.PinsNb=29 +Mcu.ThirdPartyNb=0 +Mcu.UserConstants= +Mcu.UserName=STM32F030C8Tx +MxCube.Version=6.17.0 +MxDb.Version=DB.6.0.170 +NVIC.DMA1_Channel2_3_IRQn=true\:0\:0\:false\:false\:true\:false\:true\:true +NVIC.EXTI4_15_IRQn=true\:0\:0\:false\:false\:true\:true\:true\:true +NVIC.ForceEnableDMAVector=true +NVIC.HardFault_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.SVC_IRQn=true\:0\:0\:false\:false\:true\:false\:false\:true +NVIC.SysTick_IRQn=true\:3\:0\:false\:false\:true\:false\:true\:false +NVIC.USART1_IRQn=true\:0\:0\:false\:false\:true\:true\:true\:true +PA0.Locked=true +PA0.Mode=IN0 +PA0.Signal=ADC_IN0 +PA1.Locked=true +PA1.Mode=IN1 +PA1.Signal=ADC_IN1 +PA10.GPIOParameters=GPIO_Label +PA10.GPIO_Label=IRMR +PA10.Locked=true +PA10.Signal=GPIO_Input +PA11.GPIOParameters=GPIO_Label +PA11.GPIO_Label=IRR +PA11.Locked=true +PA11.Signal=GPIO_Input +PA13.Mode=Serial_Wire +PA13.Signal=SYS_SWDIO +PA14.Locked=true +PA14.Mode=Serial_Wire +PA14.Signal=SYS_SWCLK +PA2.GPIOParameters=GPIO_Label +PA2.GPIO_Label=LED_BLUE +PA2.Locked=true +PA2.Signal=S_TIM15_CH1 +PA3.GPIOParameters=GPIO_Label +PA3.GPIO_Label=LED_RED +PA3.Locked=true +PA3.Signal=S_TIM15_CH2 +PA4.GPIOParameters=GPIO_Label +PA4.GPIO_Label=MotLRBrush +PA4.Locked=true +PA4.Signal=S_TIM14_CH1 +PA5.GPIOParameters=GPIO_Label +PA5.GPIO_Label=MotLSpd +PA5.Locked=true +PA5.Signal=GPXTI5 +PA6.GPIOParameters=GPIO_Label +PA6.GPIO_Label=MotLFwd +PA6.Locked=true +PA6.Signal=S_TIM3_CH1 +PA7.GPIOParameters=GPIO_Label +PA7.GPIO_Label=MotLRev +PA7.Locked=true +PA7.Signal=S_TIM3_CH2 +PA8.GPIOParameters=GPIO_Label +PA8.GPIO_Label=IRL +PA8.Locked=true +PA8.Signal=GPIO_Input +PA9.GPIOParameters=GPIO_Label +PA9.GPIO_Label=IRML +PA9.Locked=true +PA9.Signal=GPIO_Input +PB0.GPIOParameters=GPIO_Label +PB0.GPIO_Label=MotRFwd +PB0.Locked=true +PB0.Signal=S_TIM3_CH3 +PB1.GPIOParameters=GPIO_Label +PB1.GPIO_Label=MotRRev +PB1.Locked=true +PB1.Signal=S_TIM3_CH4 +PB13.GPIOParameters=GPIO_Label +PB13.GPIO_Label=LED_Bumper +PB13.Locked=true +PB13.Signal=GPIO_Output +PB2.GPIOParameters=GPIO_Label +PB2.GPIO_Label=MotRSpd +PB2.Locked=true +PB2.Signal=GPXTI2 +PB6.GPIOParameters=GPIO_Label +PB6.GPIO_Label=TX +PB6.Locked=true +PB6.Mode=Asynchronous +PB6.Signal=USART1_TX +PB7.GPIOParameters=GPIO_Label +PB7.GPIO_Label=RX +PB7.Locked=true +PB7.Mode=Asynchronous +PB7.Signal=USART1_RX +PB8.GPIOParameters=GPIO_Label +PB8.GPIO_Label=MotBBrush +PB8.Locked=true +PB8.Signal=S_TIM16_CH1 +PB9.GPIOParameters=GPIO_Label +PB9.GPIO_Label=MotBlower +PB9.Locked=true +PB9.Signal=S_TIM17_CH1 +PC13.GPIOParameters=GPIO_Label +PC13.GPIO_Label=LED_0 +PC13.Locked=true +PC13.Signal=GPIO_Output +PCC.Checker=false +PCC.Display=Plot\: All Steps +PCC.Line=STM32F0x0 Value Line +PCC.MCU=STM32F030C8Tx +PCC.PartNumber=STM32F030C8Tx +PCC.Series=STM32F0 +PCC.Temperature=25 +PCC.Vdd=3.6 +PinOutPanel.RotationAngle=0 +ProjectManager.AskForMigrate=true +ProjectManager.BackupPrevious=false +ProjectManager.CompilerLinker=GCC +ProjectManager.CompilerOptimize=6 +ProjectManager.ComputerToolchain=false +ProjectManager.CoupleFile=false +ProjectManager.CustomerFirmwarePackage=../../../vendor/STM32CubeF0 +ProjectManager.DefaultFWLocation=false +ProjectManager.DeletePrevious=true +ProjectManager.DeviceId=STM32F030C8Tx +ProjectManager.FirmwarePackage=STM32Cube FW_F0 V1.11.6 +ProjectManager.FreePins=false +ProjectManager.FreePinsContext= +ProjectManager.HalAssertFull=false +ProjectManager.HeapSize=0x80 +ProjectManager.KeepUserCode=true +ProjectManager.LastFirmware=true +ProjectManager.LibraryCopy=2 +ProjectManager.MainLocation=Src +ProjectManager.NoMain=false +ProjectManager.PreviousToolchain= +ProjectManager.ProjectBuild=false +ProjectManager.ProjectFileName=stm32f030.ioc +ProjectManager.ProjectName=stm32f030 +ProjectManager.ProjectStructure= +ProjectManager.RegisterCallBack= +ProjectManager.StackSize=0x400 +ProjectManager.TargetToolchain=CMake +ProjectManager.ToolChainLocation= +ProjectManager.UAScriptAfterPath= +ProjectManager.UAScriptBeforePath= +ProjectManager.UnderRoot=false +ProjectManager.functionlistsort=1-SystemClock_Config-RCC-false-HAL-false,2-MX_GPIO_Init-GPIO-false-HAL-true,3-MX_DMA_Init-DMA-false-HAL-true,4-MX_TIM3_Init-TIM3-false-HAL-true,5-MX_USART1_UART_Init-USART1-false-HAL-true,6-MX_TIM15_Init-TIM15-false-HAL-true,7-MX_TIM14_Init-TIM14-false-HAL-true,8-MX_ADC_Init-ADC-false-HAL-true,9-MX_TIM16_Init-TIM16-false-HAL-true,10-MX_TIM17_Init-TIM17-false-HAL-true +RCC.AHBFreq_Value=48000000 +RCC.APB1Freq_Value=48000000 +RCC.APB1TimFreq_Value=48000000 +RCC.FCLKCortexFreq_Value=48000000 +RCC.FamilyName=M +RCC.HCLKFreq_Value=48000000 +RCC.IPParameters=AHBFreq_Value,APB1Freq_Value,APB1TimFreq_Value,FCLKCortexFreq_Value,FamilyName,HCLKFreq_Value,MCOFreq_Value,PLLCLKFreq_Value,PLLMCOFreq_Value,PLLMUL,SYSCLKFreq_VALUE,SYSCLKSource,TimSysFreq_Value,USART1Freq_Value +RCC.MCOFreq_Value=48000000 +RCC.PLLCLKFreq_Value=48000000 +RCC.PLLMCOFreq_Value=24000000 +RCC.PLLMUL=RCC_PLL_MUL12 +RCC.SYSCLKFreq_VALUE=48000000 +RCC.SYSCLKSource=RCC_SYSCLKSOURCE_PLLCLK +RCC.TimSysFreq_Value=48000000 +RCC.USART1Freq_Value=48000000 +SH.GPXTI2.0=GPIO_EXTI2 +SH.GPXTI2.ConfNb=1 +SH.GPXTI5.0=GPIO_EXTI5 +SH.GPXTI5.ConfNb=1 +SH.S_TIM14_CH1.0=TIM14_CH1,PWM Generation1 CH1 +SH.S_TIM14_CH1.ConfNb=1 +SH.S_TIM15_CH1.0=TIM15_CH1,PWM Generation1 CH1 +SH.S_TIM15_CH1.ConfNb=1 +SH.S_TIM15_CH2.0=TIM15_CH2,PWM Generation2 CH2 +SH.S_TIM15_CH2.ConfNb=1 +SH.S_TIM16_CH1.0=TIM16_CH1,PWM Generation1 CH1 +SH.S_TIM16_CH1.ConfNb=1 +SH.S_TIM17_CH1.0=TIM17_CH1,Output Compare1 CH1 +SH.S_TIM17_CH1.ConfNb=1 +SH.S_TIM3_CH1.0=TIM3_CH1,PWM Generation1 CH1 +SH.S_TIM3_CH1.ConfNb=1 +SH.S_TIM3_CH2.0=TIM3_CH2,PWM Generation2 CH2 +SH.S_TIM3_CH2.ConfNb=1 +SH.S_TIM3_CH3.0=TIM3_CH3,PWM Generation3 CH3 +SH.S_TIM3_CH3.ConfNb=1 +SH.S_TIM3_CH4.0=TIM3_CH4,PWM Generation4 CH4 +SH.S_TIM3_CH4.ConfNb=1 +TIM14.AutoReloadPreload=TIM_AUTORELOAD_PRELOAD_ENABLE +TIM14.Channel=TIM_CHANNEL_1 +TIM14.IPParameters=Channel,Period,AutoReloadPreload +TIM14.Period=1600 +TIM15.AutoReloadPreload=TIM_AUTORELOAD_PRELOAD_ENABLE +TIM15.Channel-PWM\ Generation1\ CH1=TIM_CHANNEL_1 +TIM15.Channel-PWM\ Generation2\ CH2=TIM_CHANNEL_2 +TIM15.IPParameters=Channel-PWM Generation1 CH1,Channel-PWM Generation2 CH2,AutoReloadPreload,Period +TIM15.Period=1600 +TIM16.AutoReloadPreload=TIM_AUTORELOAD_PRELOAD_ENABLE +TIM16.Channel=TIM_CHANNEL_1 +TIM16.IPParameters=Channel,Period,AutoReloadPreload +TIM16.Period=1600 +TIM17.AutoReloadPreload=TIM_AUTORELOAD_PRELOAD_ENABLE +TIM17.Channel=TIM_CHANNEL_1 +TIM17.IPParameters=Channel,Period,AutoReloadPreload +TIM17.Period=1600 +TIM3.AutoReloadPreload=TIM_AUTORELOAD_PRELOAD_ENABLE +TIM3.Channel-PWM\ Generation1\ CH1=TIM_CHANNEL_1 +TIM3.Channel-PWM\ Generation2\ CH2=TIM_CHANNEL_2 +TIM3.Channel-PWM\ Generation3\ CH3=TIM_CHANNEL_3 +TIM3.Channel-PWM\ Generation4\ CH4=TIM_CHANNEL_4 +TIM3.IPParameters=Channel-PWM Generation1 CH1,Channel-PWM Generation2 CH2,Period,AutoReloadPreload,Channel-PWM Generation3 CH3,Channel-PWM Generation4 CH4 +TIM3.Period=3200 +USART1.BaudRate=115200 +USART1.IPParameters=VirtualMode-Asynchronous,BaudRate +USART1.VirtualMode-Asynchronous=VM_ASYNC +VP_SYS_VS_Systick.Mode=SysTick +VP_SYS_VS_Systick.Signal=SYS_VS_Systick +VP_TIM14_VS_ClockSourceINT.Mode=Enable_Timer +VP_TIM14_VS_ClockSourceINT.Signal=TIM14_VS_ClockSourceINT +VP_TIM15_VS_ClockSourceINT.Mode=Internal +VP_TIM15_VS_ClockSourceINT.Signal=TIM15_VS_ClockSourceINT +VP_TIM16_VS_ClockSourceINT.Mode=Enable_Timer +VP_TIM16_VS_ClockSourceINT.Signal=TIM16_VS_ClockSourceINT +VP_TIM17_VS_ClockSourceINT.Mode=Enable_Timer +VP_TIM17_VS_ClockSourceINT.Signal=TIM17_VS_ClockSourceINT +VP_TIM3_VS_ClockSourceINT.Mode=Internal +VP_TIM3_VS_ClockSourceINT.Signal=TIM3_VS_ClockSourceINT +board=custom diff --git a/SW/spu/scripts/plot_motor_ticks.py b/SW/spu/scripts/plot_motor_ticks.py new file mode 100644 index 0000000..508458c --- /dev/null +++ b/SW/spu/scripts/plot_motor_ticks.py @@ -0,0 +1,357 @@ +#!/usr/bin/env python3 +import argparse +import struct +import threading +import time +from collections import deque +from queue import Empty, Queue + +try: + import pygame +except ImportError as exc: + raise SystemExit( + "Missing dependency: pygame. Install with `pip install pygame pyserial`." + ) from exc + +try: + import serial +except ImportError as exc: + raise SystemExit( + "Missing dependency: pyserial. Install with `pip install pygame pyserial`." + ) from exc + + +RECORD_STRUCT = struct.Struct(" argparse.Namespace: + parser = argparse.ArgumentParser( + description="Read binary motor samples from a serial port and draw traces live." + ) + parser.add_argument("port", help="Serial port, for example /dev/ttyUSB0 or COM3") + parser.add_argument( + "-b", + "--baudrate", + type=int, + default=115200, + help="Serial baudrate (default: 115200)", + ) + parser.add_argument( + "--history-seconds", + type=float, + default=10.0, + help="Initial visible history window in seconds (default: 10)", + ) + parser.add_argument( + "--avg-window", + type=int, + default=5, + help="Sliding average window in samples for derived traces (default: 5)", + ) + parser.add_argument( + "--max-samples", + type=int, + default=30000, + help="Maximum number of samples to keep in memory (default: 30000)", + ) + parser.add_argument( + "--width", + type=int, + default=1200, + help="Window width in pixels (default: 1200)", + ) + parser.add_argument( + "--height", + type=int, + default=700, + help="Window height in pixels (default: 700)", + ) + return parser.parse_args() + + +def serial_reader(port: str, baudrate: int, output: Queue) -> None: + try: + with serial.Serial(port, baudrate=baudrate, timeout=1) as ser: + while True: + raw = ser.read(RECORD_STRUCT.size) + if len(raw) != RECORD_STRUCT.size: + continue + values = RECORD_STRUCT.unpack(raw) + sample = dict(zip(RECORD_FIELDS, values)) + sample["wall_time"] = time.monotonic() + output.put(sample) + except serial.SerialException as exc: + output.put({"error": f"Serial error: {exc}"}) + + +def compute_speed( + raw_window: list[dict[str, float | int]], + tick_field: str, +) -> float | None: + if len(raw_window) < 2: + return None + + first = raw_window[0] + last = raw_window[-1] + dt_ms = int(last["ms"]) - int(first["ms"]) + if dt_ms <= 0: + return None + + dt_ticks = int(last[tick_field]) - int(first[tick_field]) + return (1000.0 * dt_ticks) / dt_ms + + +def update_traces( + raw_samples: deque[dict[str, float | int]], + trace_samples: dict[str, deque[tuple[float, float, dict[str, float | int]]]], + avg_window: int, +) -> None: + window = list(raw_samples)[-max(avg_window, 2):] + sample = raw_samples[-1] + + for trace in TRACE_DEFS: + value = None + if trace["kind"] == "field": + value = float(sample[trace["field"]]) + elif trace["kind"] == "derived": + value = trace["compute"](window) + + if value is not None: + trace_samples[trace["name"]].append( + (float(sample["wall_time"]), float(value), sample) + ) + + +def drain_queue( + queue: Queue, + raw_samples: deque[dict[str, float | int]], + trace_samples: dict[str, deque[tuple[float, float, dict[str, float | int]]]], + avg_window: int, +) -> str | None: + error_message = None + while True: + try: + item = queue.get_nowait() + except Empty: + return error_message + + if "error" in item: + error_message = str(item["error"]) + continue + + raw_samples.append(item) + update_traces(raw_samples, trace_samples, avg_window) + + +def draw_grid( + surface: pygame.Surface, + rect: pygame.Rect, + font: pygame.font.Font, + view_span: float, + y_max: float, +) -> None: + pygame.draw.rect(surface, GRID, rect, width=1) + + for fraction in (0.0, 0.25, 0.5, 0.75, 1.0): + y = rect.top + round(fraction * rect.height) + pygame.draw.line(surface, GRID, (rect.left, y), (rect.right, y), 1) + value = (1.0 - fraction) * y_max + text = font.render(f"{value:.1f}", True, AXIS) + surface.blit(text, (10, y - text.get_height() // 2)) + + for fraction in (0.0, 0.25, 0.5, 0.75, 1.0): + x = rect.left + round(fraction * rect.width) + pygame.draw.line(surface, GRID, (x, rect.top), (x, rect.bottom), 1) + seconds_ago = view_span * (1.0 - fraction) + label = f"-{seconds_ago:.1f}s" if seconds_ago > 0.05 else "now" + text = font.render(label, True, AXIS) + surface.blit(text, (x - text.get_width() // 2, rect.bottom + 8)) + + +def draw_trace( + surface: pygame.Surface, + rect: pygame.Rect, + samples: deque[tuple[float, float, dict[str, float | int]]], + view_span: float, + now: float, + color: tuple[int, int, int], + y_max: float, +) -> tuple[float | None, dict[str, float | int] | None]: + visible_points = [] + latest_value = None + latest_sample = None + + for timestamp, value, sample in samples: + age = now - timestamp + if age < 0 or age > view_span: + continue + x = rect.right - (age / view_span) * rect.width + y = rect.bottom - (value / y_max) * rect.height + visible_points.append((round(x), round(y))) + latest_value = value + latest_sample = sample + + if len(visible_points) >= 2: + pygame.draw.lines(surface, color, False, visible_points, 2) + elif len(visible_points) == 1: + pygame.draw.circle(surface, color, visible_points[0], 2) + + return latest_value, latest_sample + + +def zoom(view_span: float, direction: int, initial_span: float) -> float: + if direction > 0: + return max(1.0, view_span / 1.2) + return min(max(initial_span * 20.0, 60.0), view_span * 1.2) + + +def main() -> int: + args = parse_args() + raw_samples: deque[dict[str, float | int]] = deque(maxlen=args.max_samples) + trace_samples = { + trace["name"]: deque(maxlen=args.max_samples) for trace in TRACE_DEFS + } + queue: Queue = Queue() + + thread = threading.Thread( + target=serial_reader, args=(args.port, args.baudrate, queue), daemon=True + ) + thread.start() + + pygame.init() + pygame.display.set_caption(f"Motor traces: {args.port} @ {args.baudrate}") + screen = pygame.display.set_mode((args.width, args.height), pygame.RESIZABLE) + font = pygame.font.SysFont("monospace", 18) + small_font = pygame.font.SysFont("monospace", 14) + clock = pygame.time.Clock() + + view_span = max(args.history_seconds, 1.0) + error_message = None + running = True + + while running: + for event in pygame.event.get(): + if event.type == pygame.QUIT: + running = False + elif event.type == pygame.MOUSEWHEEL: + view_span = zoom(view_span, event.y, args.history_seconds) + elif event.type == pygame.MOUSEBUTTONDOWN: + if event.button == 4: + view_span = zoom(view_span, 1, args.history_seconds) + elif event.button == 5: + view_span = zoom(view_span, -1, args.history_seconds) + + queued_error = drain_queue(queue, raw_samples, trace_samples, args.avg_window) + if queued_error is not None: + error_message = queued_error + + width, height = screen.get_size() + plot_rect = pygame.Rect(70, 40, max(100, width - 100), max(100, height - 100)) + now = time.monotonic() + + y_max = 1.0 + for trace in TRACE_DEFS: + for timestamp, value, _sample in trace_samples[trace["name"]]: + age = now - timestamp + if 0 <= age <= view_span and value > y_max: + y_max = value + y_max = max(10.0, y_max * 1.2) + + screen.fill(BACKGROUND) + draw_grid(screen, plot_rect, small_font, view_span, y_max) + + latest_values: dict[str, float] = {} + latest_sample: dict[str, float | int] | None = None + + for trace in TRACE_DEFS: + value, sample = draw_trace( + screen, + plot_rect, + trace_samples[trace["name"]], + view_span, + now, + trace["color"], + y_max, + ) + if value is not None: + latest_values[trace["name"]] = value + if sample is not None: + latest_sample = sample + + header = ( + f"port={args.port} baud={args.baudrate} zoom={view_span:.1f}s " + f"avg_window={args.avg_window}" + ) + screen.blit(font.render(header, True, TEXT), (10, 8)) + screen.blit( + small_font.render("mouse wheel: zoom horizontal axis", True, AXIS), + (10, height - 24), + ) + + legend_x = 10 + for trace in TRACE_DEFS: + pygame.draw.line( + screen, + trace["color"], + (legend_x, 43), + (legend_x + 24, 43), + 3, + ) + screen.blit(small_font.render(trace["label"], True, TEXT), (legend_x + 30, 34)) + legend_x += 120 + + if error_message: + error_surface = font.render(error_message, True, ERROR) + screen.blit(error_surface, (10, 56)) + + pygame.display.flip() + clock.tick(60) + + pygame.quit() + return 0 + + +if __name__ == "__main__": + raise SystemExit(main())