├── VERSION ├── .dockerignore ├── meson_options.txt ├── stm32f4.meson ├── Drivers ├── CMSIS │ ├── Device │ │ └── ST │ │ │ └── STM32F4xx │ │ │ └── Include │ │ │ ├── stm32f4xx.h │ │ │ └── system_stm32f4xx.h │ └── Include │ │ ├── cmsis_version.h │ │ ├── tz_context.h │ │ ├── cmsis_compiler.h │ │ ├── mpu_armv8.h │ │ └── mpu_armv7.h └── STM32F4xx_HAL_Driver │ ├── Inc │ ├── stm32f4xx_hal_flash_ramfunc.h │ ├── stm32f4xx_hal_dma_ex.h │ ├── stm32f4xx_hal_def.h │ ├── stm32f4xx_hal_gpio.h │ └── stm32f4xx_hal_exti.h │ └── Src │ ├── stm32f4xx_hal_flash_ramfunc.c │ └── stm32f4xx_hal_dma_ex.c ├── Project ├── projectMain.h ├── SWO.h ├── projectMain.cpp └── SWO.c ├── glob.sh ├── .vscode ├── settings.json ├── tasks.json ├── c_cpp_properties.json └── launch.json ├── debug.sh ├── .gitignore ├── gcc-arm-none-eabi.meson ├── gcc-arm-none-eabi.cmake ├── docker-compose.yml ├── Dockerfile ├── default.nix ├── Core ├── Inc │ ├── gpio.h │ ├── stm32f4xx_it.h │ └── main.h └── Src │ ├── gpio.c │ ├── stm32f4xx_hal_msp.c │ ├── main.c │ └── stm32f4xx_it.c ├── README.md ├── flake.lock ├── docs ├── build-native.md ├── tools.md ├── build-nix.md ├── build-container.md └── code-tips.md ├── Makefile ├── .clang-format ├── STM32-project-template.ioc ├── CMakeLists.txt ├── flake.nix ├── meson.build └── CubeMX ├── Makefile └── STM32F407VGTx_FLASH.ld /VERSION: -------------------------------------------------------------------------------- 1 | v1.0 2 | -------------------------------------------------------------------------------- /.dockerignore: -------------------------------------------------------------------------------- 1 | /* 2 | 3 | !Dockerfile 4 | -------------------------------------------------------------------------------- /meson_options.txt: -------------------------------------------------------------------------------- 1 | option('project_name', type: 'string', value: 'firmware', description: 'Project name') 2 | -------------------------------------------------------------------------------- /stm32f4.meson: -------------------------------------------------------------------------------- 1 | [host_machine] 2 | system = 'none' 3 | cpu_family = 'arm' 4 | cpu = 'cortex-m4' 5 | endian = 'little' 6 | -------------------------------------------------------------------------------- /Drivers/CMSIS/Device/ST/STM32F4xx/Include/stm32f4xx.h: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/prtzl/stm32/HEAD/Drivers/CMSIS/Device/ST/STM32F4xx/Include/stm32f4xx.h -------------------------------------------------------------------------------- /Project/projectMain.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #ifdef __cplusplus 4 | extern "C" 5 | { 6 | #endif 7 | 8 | void projectMain(); 9 | 10 | #ifdef __cplusplus 11 | } 12 | #endif 13 | -------------------------------------------------------------------------------- /glob.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | if [[ -f .git || -d .git ]]; then 4 | files=$(git ls-files | grep -E '\.(c|cpp)$') 5 | else 6 | files=$(find . -type f -not \( -path '*/build/*' -prune \) -name '*.c' -or -name '*.cpp') 7 | fi 8 | res=$? 9 | 10 | if [ "$res" != 0 ]; then 11 | exit 1 12 | else 13 | echo "$files" 14 | fi 15 | 16 | exit 0 17 | -------------------------------------------------------------------------------- /Project/SWO.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | 6 | #ifdef __cplusplus 7 | extern "C" 8 | { 9 | #endif 10 | 11 | void SWO_PrintChar(char const c, uint8_t const portNumber); 12 | void SWO_PrintString(char const* s, uint8_t const portNumber); 13 | void SWO_PrintDefault(char const* str); 14 | void SWO_PrintDefaultN(char const* str, size_t const len); 15 | 16 | #ifdef __cplusplus 17 | } 18 | #endif 19 | -------------------------------------------------------------------------------- /.vscode/settings.json: -------------------------------------------------------------------------------- 1 | { 2 | // Change path to your system, use `which` to find the location of the executables 3 | // Somehow, cortex-debug wants absolute path, even if the package is present in $PATH 4 | "cortex-debug.armToolchainPath": "/nix/store/6h6y6d1y8ryc56b2rsh07dq87qsym42a-gcc-arm-embedded-10.3.1/bin", 5 | "cortex-debug.JLinkGDBServerPath": "/nix/store/qi5nij6wwmr1zzbfjjmwsk96d1nlna9p-segger-jlink/bin/JLinkGDBServerCLExe", 6 | "nixEnvSelector.nixFile": "${workspaceRoot}/flake.nix" 7 | } -------------------------------------------------------------------------------- /.vscode/tasks.json: -------------------------------------------------------------------------------- 1 | { 2 | "version": "2.0.0", 3 | "tasks": [ 4 | { 5 | "label": "build", 6 | "type": "shell", 7 | "problemMatcher": "$gcc", 8 | "group": { 9 | "kind": "build", 10 | "isDefault": true 11 | }, 12 | "command": "make -j8" 13 | }, 14 | { 15 | "label": "clean", 16 | "type": "shell", 17 | "group": { 18 | "kind": "build", 19 | "isDefault": false 20 | }, 21 | "command": "make clean" 22 | } 23 | ] 24 | } -------------------------------------------------------------------------------- /debug.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | exe=$1 4 | if [ -n "$exe" ]; then 5 | echo "Provide executable path to .elf" 6 | exit 1 7 | fi 8 | 9 | JLinkGDBServerCLExe \ 10 | -device STM32F407VG \ 11 | -if SWD \ 12 | -speed 4000 \ 13 | -port 2331 > jlink.log 2>&1 & 14 | 15 | JLINK_PID=$! 16 | 17 | # Kill J-Link server when script exits 18 | trap 'kill $JLINK_PID' EXIT 19 | 20 | # Give the server a moment to start 21 | sleep 1 22 | 23 | # Start GDB interactively and run commands 24 | arm-none-eabi-gdb $exe \ 25 | -ex "layout next" \ 26 | -ex "layout next" \ 27 | -ex "target remote localhost:2331" \ 28 | -ex "load" \ 29 | -ex "break main" \ 30 | -ex "continue" 31 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | /* 2 | 3 | # GIT 4 | !.gitignore 5 | !VERSION 6 | 7 | # Guides 8 | !README.md 9 | !/docs 10 | 11 | # NIX 12 | !*.nix 13 | !flake.lock 14 | 15 | # TOOLS 16 | !Makefile 17 | !CMakeLists.txt 18 | !gcc-arm-none-eabi.cmake 19 | !.clang-format 20 | !Dockerfile 21 | !docker-compose.yml 22 | !.dockerignore 23 | 24 | # MESON 25 | !meson.build 26 | !gcc-arm-none-eabi.meson 27 | !stm32f4.meson 28 | !glob.sh 29 | 30 | # EXAMPLE 31 | !Core 32 | !Drivers 33 | !CubeMX 34 | !Project 35 | !STM32-project-template.ioc 36 | !/.vscode 37 | /.vscode/* 38 | !/.vscode/tasks.json 39 | !/.vscode/c_cpp_properties.json 40 | !/.vscode/launch.json 41 | !/.vscode/settings.json 42 | 43 | # EXTRA 44 | !debug.sh 45 | -------------------------------------------------------------------------------- /.vscode/c_cpp_properties.json: -------------------------------------------------------------------------------- 1 | { 2 | "configurations": [ 3 | { 4 | "name": "STM32F407", 5 | "includePath": [ 6 | "${workspaceFolder}/**" 7 | ], 8 | "defines": [ "USE_HAL_DRIVER", "STM32F407xx" ], 9 | "cStandard": "c11", 10 | "cppStandard": "c++20", 11 | "intelliSenseMode": "gcc-arm", 12 | // use path: ${workspaceFolder}/result/compile_commands.json for nix 13 | // use path: ${workspaceFolder}/build/compile_commands.json with makefile 14 | "compileCommands": "${workspaceFolder}/build/compile_commands.json" 15 | } 16 | ], 17 | "version": 4 18 | } 19 | -------------------------------------------------------------------------------- /gcc-arm-none-eabi.meson: -------------------------------------------------------------------------------- 1 | [constants] 2 | arch = 'arm-none-eabi' 3 | 4 | [binaries] 5 | c = arch + '-gcc' 6 | cpp = arch + '-g++' 7 | ld = arch + '-ld' 8 | ar = arch + '-ar' 9 | as = arch + '-as' 10 | size = arch + '-size' 11 | objdump = arch + '-objdump' 12 | objcopy = arch + '-objcopy' 13 | strip = arch + '-strip' 14 | gdb = arch + '-gdb' 15 | 16 | [built-in options] 17 | c_args = [ 18 | '-mthumb', 19 | '-ffunction-sections', 20 | '-fdata-sections', 21 | '--specs=nano.specs', 22 | '-Wl,--gc-sections'] 23 | 24 | cpp_args = c_args + [ 25 | '-fno-rtti', 26 | '-fno-exceptions', 27 | '-fno-threadsafe-statics'] 28 | 29 | c_link_args = c_args + [ 30 | '-lc', 31 | '-lm', 32 | '-lstdc++'] 33 | 34 | cpp_link_args = c_link_args 35 | -------------------------------------------------------------------------------- /gcc-arm-none-eabi.cmake: -------------------------------------------------------------------------------- 1 | set(CMAKE_SYSTEM_NAME Generic) 2 | set(CMAKE_SYSTEM_PROCESSOR arm) 3 | 4 | set(TOOLCHAIN_PREFIX arm-none-eabi-) 5 | set(CMAKE_C_FLAGS_INIT 6 | "-fdata-sections -ffunction-sections --specs=nano.specs -Wl,--gc-sections") 7 | set(CMAKE_CXX_FLAGS_INIT 8 | "${CMAKE_C_FLAGS_INIT} -fno-rtti -fno-exceptions -fno-threadsafe-statics") 9 | 10 | set(CMAKE_C_COMPILER ${TOOLCHAIN_PREFIX}gcc) 11 | set(CMAKE_ASM_COMPILER ${CMAKE_C_COMPILER}) 12 | set(CMAKE_CXX_COMPILER ${TOOLCHAIN_PREFIX}g++) 13 | set(CMAKE_OBJCOPY ${TOOLCHAIN_PREFIX}objcopy) 14 | set(CMAKE_SIZE ${TOOLCHAIN_PREFIX}size) 15 | set(CMAKE_OBJDUMP ${TOOLCHAIN_PREFIX}objdump) 16 | 17 | set(CMAKE_EXECUTABLE_SUFFIX_ASM ".elf") 18 | set(CMAKE_EXECUTABLE_SUFFIX_C ".elf") 19 | set(CMAKE_EXECUTABLE_SUFFIX_CXX ".elf") 20 | 21 | set(CMAKE_TRY_COMPILE_TARGET_TYPE STATIC_LIBRARY) 22 | -------------------------------------------------------------------------------- /docker-compose.yml: -------------------------------------------------------------------------------- 1 | version: '3' 2 | services: 3 | 4 | container: 5 | build: 6 | context: . 7 | dockerfile: ./Dockerfile 8 | image: fedora-arm-embedded-dev 9 | container_name: fedora-arm-embedded-dev 10 | volumes: 11 | - ${PWD}/:/workdir 12 | working_dir: /workdir 13 | hostname: fedora-arm-embedded-dev 14 | 15 | stmbuild: 16 | extends: 17 | service: container 18 | command: bash -lc 'make -j8' 19 | 20 | stmrebuild: 21 | extends: 22 | service: container 23 | command: bash -lc 'make clean && make -j8' 24 | 25 | stmclean: 26 | extends: 27 | service: container 28 | command: bash -lc 'make clean' 29 | 30 | shell: 31 | extends: 32 | service: container 33 | command: bash -l 34 | -------------------------------------------------------------------------------- /Dockerfile: -------------------------------------------------------------------------------- 1 | FROM fedora:34 2 | 3 | RUN dnf update -y && dnf install -y \ 4 | git \ 5 | wget \ 6 | lbzip2 \ 7 | make \ 8 | cmake \ 9 | glibc-locale-source \ 10 | findutils \ 11 | clang-tools-extra 12 | 13 | RUN wget -q https://developer.arm.com/-/media/Files/downloads/gnu-rm/10.3-2021.10/gcc-arm-none-eabi-10.3-2021.10-x86_64-linux.tar.bz2 -O /tmp/gcc-arm-none-eabi-10.3.tar.bz2 14 | RUN mkdir -p /opt/gcc-arm-none-eabi-10.3 15 | RUN tar -xf /tmp/gcc-arm-none-eabi-10.3.tar.bz2 -C /opt/gcc-arm-none-eabi-10.3 --strip-components=1 16 | RUN ln -s /opt/gcc-arm-none-eabi-10.3/bin/* /usr/local/bin 17 | RUN rm -rf /tmp/* 18 | 19 | ARG UID 20 | ARG GID 21 | ARG USERNAME 22 | ARG GROUPNAME 23 | RUN groupadd --gid $GID $GROUPNAME 24 | RUN useradd --uid $UID --gid $GID $USERNAME 25 | RUN usermod --append --groups $GROUPNAME $USERNAME 26 | RUN usermod --shell /bin/bash $USERNAME 27 | 28 | USER $USERNAME 29 | -------------------------------------------------------------------------------- /Project/projectMain.cpp: -------------------------------------------------------------------------------- 1 | #include "main.h" 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | 8 | struct Led 9 | { 10 | explicit Led(GPIO_TypeDef* t_gpio, uint16_t t_pin) 11 | : gpio(t_gpio) 12 | , pin(t_pin) 13 | { 14 | } 15 | void on() 16 | { 17 | HAL_GPIO_WritePin(gpio, pin, GPIO_PIN_SET); 18 | } 19 | void off() 20 | { 21 | HAL_GPIO_WritePin(gpio, pin, GPIO_PIN_RESET); 22 | } 23 | void toggle() 24 | { 25 | HAL_GPIO_TogglePin(gpio, pin); 26 | } 27 | auto state() -> bool 28 | { 29 | return HAL_GPIO_ReadPin(gpio, pin); 30 | } 31 | 32 | private: 33 | GPIO_TypeDef* gpio; 34 | uint16_t pin; 35 | }; 36 | 37 | void projectMain() 38 | { 39 | Led led(GPIOD, GPIO_PIN_15); 40 | 41 | // Newer C++ features 42 | constexpr auto arr = std::to_array({1, 2, 3, 4, 5}); 43 | auto view = std::span(arr); 44 | 45 | while (true) 46 | { 47 | led.toggle(); 48 | SWO_PrintDefault("Hello, world!\n"); 49 | HAL_Delay(1000); 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /Project/SWO.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | void SWO_PrintChar(char const c, uint8_t const portNumber) 5 | { 6 | volatile int timeout; 7 | 8 | /* Check if Trace Control Register (ITM->TCR at 0xE0000E80) is set */ 9 | /* check Trace Control Register if ITM trace is enabled*/ 10 | if ((ITM->TCR & ITM_TCR_ITMENA_Msk) == 0) 11 | { 12 | return; /* not enabled? */ 13 | } 14 | /* Check if the requested channel stimulus port (ITM->TER at 0xE0000E00) is enabled */ 15 | /* check Trace Enable Register if requested port is enabled */ 16 | if ((ITM->TER & (1ul << portNumber)) == 0) 17 | { 18 | return; /* requested port not enabled? */ 19 | } 20 | timeout = 5000; /* arbitrary timeout value */ 21 | while (ITM->PORT[0].u32 == 0) 22 | { 23 | /* Wait until STIMx is ready, then send data */ 24 | if (--timeout == 0) 25 | { 26 | return; /* not able to send */ 27 | } 28 | } 29 | ITM->PORT[0].u8 = (uint8_t)c; 30 | } 31 | 32 | void SWO_PrintString(char const* s, uint8_t const portNumber) 33 | { 34 | while (*s != '\0') 35 | { 36 | SWO_PrintChar(*s++, portNumber); 37 | } 38 | } 39 | 40 | void SWO_PrintDefault(char const* str) 41 | { 42 | SWO_PrintString(str, 0); 43 | } 44 | 45 | void SWO_PrintDefaultN(char const* str, size_t const len) 46 | { 47 | for (size_t i = 0; i < len; ++i) 48 | { 49 | SWO_PrintChar(str[i], 0); 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /default.nix: -------------------------------------------------------------------------------- 1 | { stdenv, cmake, gnumake, gcc-arm-embedded, meson, ninja, bash 2 | , buildtype ? "debug", lib }: 3 | 4 | assert buildtype == "debug" || buildtype == "release"; 5 | 6 | stdenv.mkDerivation rec { 7 | inherit buildtype; 8 | 9 | pname = "firmware"; 10 | version = lib.fileContents ./VERSION; 11 | src = ./.; 12 | 13 | # order of ninja+meson nad cmake+gnumake will impact which generator is chosen 14 | buildInputs = [ gcc-arm-embedded ninja meson cmake gnumake ]; 15 | 16 | dontFixup = 17 | true; # if you use fixupPhase (do something after build), remove this 18 | dontStrip = true; 19 | dontPatchELF = true; 20 | 21 | # Firmware/device info 22 | device = "STM32F407VG"; 23 | binary = "${pname}${buildtype}-${version}-.bin"; 24 | executable = "${pname}-${buildtype}-${version}.elf"; 25 | 26 | # cmake 27 | cmakeFlags = [ 28 | "-DPROJECT_VERSION=${version}" 29 | "-DCMAKE_BUILD_TYPE=${buildtype}" 30 | "-DDUMP_ASM=OFF" 31 | ]; 32 | 33 | # meson 34 | mesonBuildType = "${lib.strings.toLower buildtype}"; 35 | mesonFlags = [ 36 | "--cross-file=gcc-arm-none-eabi.meson" 37 | "--cross-file=stm32f4.meson" 38 | "--buildtype=${buildtype}" 39 | ]; 40 | 41 | patchPhase = '' 42 | substituteInPlace glob.sh \ 43 | --replace '/usr/bin/env bash' ${bash}/bin/bash 44 | ''; 45 | 46 | # "save" outputs 47 | installPhase = '' 48 | mkdir -p $out/bin 49 | cp *.bin *.elf *.s $out/bin 50 | cp compile_commands.json $out 51 | ''; 52 | } 53 | -------------------------------------------------------------------------------- /Core/Inc/gpio.h: -------------------------------------------------------------------------------- 1 | /** 2 | ****************************************************************************** 3 | * @file gpio.h 4 | * @brief This file contains all the function prototypes for 5 | * the gpio.c file 6 | ****************************************************************************** 7 | * @attention 8 | * 9 | *

© Copyright (c) 2022 STMicroelectronics. 10 | * All rights reserved.

11 | * 12 | * This software component is licensed by ST under BSD 3-Clause license, 13 | * the "License"; You may not use this file except in compliance with the 14 | * License. You may obtain a copy of the License at: 15 | * opensource.org/licenses/BSD-3-Clause 16 | * 17 | ****************************************************************************** 18 | */ 19 | /* Define to prevent recursive inclusion -------------------------------------*/ 20 | #ifndef __GPIO_H__ 21 | #define __GPIO_H__ 22 | 23 | #ifdef __cplusplus 24 | extern "C" 25 | { 26 | #endif 27 | 28 | /* Includes ------------------------------------------------------------------*/ 29 | #include "main.h" 30 | 31 | /* USER CODE BEGIN Includes */ 32 | 33 | /* USER CODE END Includes */ 34 | 35 | /* USER CODE BEGIN Private defines */ 36 | 37 | /* USER CODE END Private defines */ 38 | 39 | void MX_GPIO_Init(void); 40 | 41 | /* USER CODE BEGIN Prototypes */ 42 | 43 | /* USER CODE END Prototypes */ 44 | 45 | #ifdef __cplusplus 46 | } 47 | #endif 48 | #endif /*__ GPIO_H__ */ 49 | 50 | /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ 51 | -------------------------------------------------------------------------------- /.vscode/launch.json: -------------------------------------------------------------------------------- 1 | // Configure debug launch settings 2 | { 3 | "version": "0.2.0", 4 | "projectName": "test-f407vg", 5 | "configurations": [ 6 | { 7 | "name": "JLink debug", 8 | "cwd": "${workspaceRoot}", 9 | "executable": "${workspaceRoot}/build/sample-f407vg.elf", 10 | "request": "launch", 11 | "type": "cortex-debug", 12 | "servertype": "jlink", 13 | "device": "STM32F407VG", 14 | "interface": "swd", 15 | "runToEntryPoint": "main", 16 | "swoConfig": 17 | { 18 | "enabled": true, 19 | "cpuFrequency": 160000000, 20 | "swoFrequency": 4000000, 21 | "source": "probe", 22 | "decoders": 23 | [ 24 | { 25 | "label": "ITM port 0 output", 26 | "type": "console", 27 | "port": 0, 28 | "showOnStartup": true, 29 | "encoding": "ascii" 30 | } 31 | ] 32 | } 33 | }, 34 | { 35 | "name": "JLink attach", 36 | "cwd": "${workspaceRoot}", 37 | "executable": "${workspaceRoot}/build/sample-f407vg.elf", 38 | "request": "attach", 39 | "type": "cortex-debug", 40 | "servertype": "jlink", 41 | "device": "STM32F407VG", 42 | "interface": "swd", 43 | "swoConfig": 44 | { 45 | "enabled": true, 46 | "cpuFrequency": 160000000, 47 | "swoFrequency": 4000000, 48 | "source": "probe", 49 | "decoders": 50 | [ 51 | { 52 | "label": "ITM port 0 output", 53 | "type": "console", 54 | "port": 0, 55 | "showOnStartup": true, 56 | "encoding": "ascii" 57 | } 58 | ] 59 | } 60 | } 61 | ] 62 | } -------------------------------------------------------------------------------- /Core/Inc/stm32f4xx_it.h: -------------------------------------------------------------------------------- 1 | /* USER CODE BEGIN Header */ 2 | /** 3 | ****************************************************************************** 4 | * @file stm32f4xx_it.h 5 | * @brief This file contains the headers of the interrupt handlers. 6 | ****************************************************************************** 7 | * @attention 8 | * 9 | *

© Copyright (c) 2021 STMicroelectronics. 10 | * All rights reserved.

11 | * 12 | * This software component is licensed by ST under BSD 3-Clause license, 13 | * the "License"; You may not use this file except in compliance with the 14 | * License. You may obtain a copy of the License at: 15 | * opensource.org/licenses/BSD-3-Clause 16 | * 17 | ****************************************************************************** 18 | */ 19 | /* USER CODE END Header */ 20 | 21 | /* Define to prevent recursive inclusion -------------------------------------*/ 22 | #ifndef __STM32F4xx_IT_H 23 | #define __STM32F4xx_IT_H 24 | 25 | #ifdef __cplusplus 26 | extern "C" 27 | { 28 | #endif 29 | 30 | /* Private includes ----------------------------------------------------------*/ 31 | /* USER CODE BEGIN Includes */ 32 | 33 | /* USER CODE END Includes */ 34 | 35 | /* Exported types ------------------------------------------------------------*/ 36 | /* USER CODE BEGIN ET */ 37 | 38 | /* USER CODE END ET */ 39 | 40 | /* Exported constants --------------------------------------------------------*/ 41 | /* USER CODE BEGIN EC */ 42 | 43 | /* USER CODE END EC */ 44 | 45 | /* Exported macro ------------------------------------------------------------*/ 46 | /* USER CODE BEGIN EM */ 47 | 48 | /* USER CODE END EM */ 49 | 50 | /* Exported functions prototypes ---------------------------------------------*/ 51 | void NMI_Handler(void); 52 | void HardFault_Handler(void); 53 | void MemManage_Handler(void); 54 | void BusFault_Handler(void); 55 | void UsageFault_Handler(void); 56 | void SVC_Handler(void); 57 | void DebugMon_Handler(void); 58 | void PendSV_Handler(void); 59 | void SysTick_Handler(void); 60 | /* USER CODE BEGIN EFP */ 61 | 62 | /* USER CODE END EFP */ 63 | 64 | #ifdef __cplusplus 65 | } 66 | #endif 67 | 68 | #endif /* __STM32F4xx_IT_H */ 69 | 70 | /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ 71 | -------------------------------------------------------------------------------- /Core/Src/gpio.c: -------------------------------------------------------------------------------- 1 | /** 2 | ****************************************************************************** 3 | * @file gpio.c 4 | * @brief This file provides code for the configuration 5 | * of all used GPIO pins. 6 | ****************************************************************************** 7 | * @attention 8 | * 9 | *

© Copyright (c) 2022 STMicroelectronics. 10 | * All rights reserved.

11 | * 12 | * This software component is licensed by ST under BSD 3-Clause license, 13 | * the "License"; You may not use this file except in compliance with the 14 | * License. You may obtain a copy of the License at: 15 | * opensource.org/licenses/BSD-3-Clause 16 | * 17 | ****************************************************************************** 18 | */ 19 | 20 | /* Includes ------------------------------------------------------------------*/ 21 | #include "gpio.h" 22 | 23 | /* USER CODE BEGIN 0 */ 24 | 25 | /* USER CODE END 0 */ 26 | 27 | /*----------------------------------------------------------------------------*/ 28 | /* Configure GPIO */ 29 | /*----------------------------------------------------------------------------*/ 30 | /* USER CODE BEGIN 1 */ 31 | 32 | /* USER CODE END 1 */ 33 | 34 | /** Configure pins as 35 | * Analog 36 | * Input 37 | * Output 38 | * EVENT_OUT 39 | * EXTI 40 | */ 41 | void MX_GPIO_Init(void) 42 | { 43 | 44 | GPIO_InitTypeDef GPIO_InitStruct = {0}; 45 | 46 | /* GPIO Ports Clock Enable */ 47 | __HAL_RCC_GPIOH_CLK_ENABLE(); 48 | __HAL_RCC_GPIOA_CLK_ENABLE(); 49 | __HAL_RCC_GPIOD_CLK_ENABLE(); 50 | 51 | /*Configure GPIO pin Output Level */ 52 | HAL_GPIO_WritePin(LED_GPIO_Port, LED_Pin, GPIO_PIN_RESET); 53 | 54 | /*Configure GPIO pin : PtPin */ 55 | GPIO_InitStruct.Pin = BUTTON_Pin; 56 | GPIO_InitStruct.Mode = GPIO_MODE_INPUT; 57 | GPIO_InitStruct.Pull = GPIO_NOPULL; 58 | HAL_GPIO_Init(BUTTON_GPIO_Port, &GPIO_InitStruct); 59 | 60 | /*Configure GPIO pin : PtPin */ 61 | GPIO_InitStruct.Pin = LED_Pin; 62 | GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP; 63 | GPIO_InitStruct.Pull = GPIO_NOPULL; 64 | GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW; 65 | HAL_GPIO_Init(LED_GPIO_Port, &GPIO_InitStruct); 66 | } 67 | 68 | /* USER CODE BEGIN 2 */ 69 | 70 | /* USER CODE END 2 */ 71 | 72 | /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ 73 | -------------------------------------------------------------------------------- /Drivers/CMSIS/Include/cmsis_version.h: -------------------------------------------------------------------------------- 1 | /**************************************************************************/ /** 2 | * @file 3 | *cmsis_version.h 4 | * @brief CMSIS 5 | *Core(M) Version 6 | *definitions 7 | * @version V5.0.2 8 | * @date 19. 9 | *April 2017 10 | ******************************************************************************/ 11 | /* 12 | * Copyright (c) 2009-2017 ARM Limited. All rights reserved. 13 | * 14 | * SPDX-License-Identifier: Apache-2.0 15 | * 16 | * Licensed under the Apache License, Version 2.0 (the License); you may 17 | * not use this file except in compliance with the License. 18 | * You may obtain a copy of the License at 19 | * 20 | * www.apache.org/licenses/LICENSE-2.0 21 | * 22 | * Unless required by applicable law or agreed to in writing, software 23 | * distributed under the License is distributed on an AS IS BASIS, WITHOUT 24 | * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 25 | * See the License for the specific language governing permissions and 26 | * limitations under the License. 27 | */ 28 | 29 | #if defined(__ICCARM__) 30 | #pragma system_include /* treat file as system include file for MISRA check */ 31 | #elif defined(__clang__) 32 | #pragma clang system_header /* treat file as system include file */ 33 | #endif 34 | 35 | #ifndef __CMSIS_VERSION_H 36 | #define __CMSIS_VERSION_H 37 | 38 | /* CMSIS Version definitions */ 39 | #define __CM_CMSIS_VERSION_MAIN (5U) /*!< [31:16] CMSIS Core(M) main version */ 40 | #define __CM_CMSIS_VERSION_SUB (1U) /*!< [15:0] CMSIS Core(M) sub version */ 41 | #define __CM_CMSIS_VERSION \ 42 | ((__CM_CMSIS_VERSION_MAIN << 16U) \ 43 | | __CM_CMSIS_VERSION_SUB) /*!< CMSIS Core(M) version number */ 44 | #endif 45 | -------------------------------------------------------------------------------- /Core/Inc/main.h: -------------------------------------------------------------------------------- 1 | /* USER CODE BEGIN Header */ 2 | /** 3 | ****************************************************************************** 4 | * @file : main.h 5 | * @brief : Header for main.c file. 6 | * This file contains the common defines of the application. 7 | ****************************************************************************** 8 | * @attention 9 | * 10 | *

© Copyright (c) 2021 STMicroelectronics. 11 | * All rights reserved.

12 | * 13 | * This software component is licensed by ST under BSD 3-Clause license, 14 | * the "License"; You may not use this file except in compliance with the 15 | * License. You may obtain a copy of the License at: 16 | * opensource.org/licenses/BSD-3-Clause 17 | * 18 | ****************************************************************************** 19 | */ 20 | /* USER CODE END Header */ 21 | 22 | /* Define to prevent recursive inclusion -------------------------------------*/ 23 | #ifndef __MAIN_H 24 | #define __MAIN_H 25 | 26 | #ifdef __cplusplus 27 | extern "C" 28 | { 29 | #endif 30 | 31 | /* Includes ------------------------------------------------------------------*/ 32 | #include "stm32f4xx_hal.h" 33 | 34 | /* Private includes ----------------------------------------------------------*/ 35 | /* USER CODE BEGIN Includes */ 36 | 37 | /* USER CODE END Includes */ 38 | 39 | /* Exported types ------------------------------------------------------------*/ 40 | /* USER CODE BEGIN ET */ 41 | 42 | /* USER CODE END ET */ 43 | 44 | /* Exported constants --------------------------------------------------------*/ 45 | /* USER CODE BEGIN EC */ 46 | 47 | /* USER CODE END EC */ 48 | 49 | /* Exported macro ------------------------------------------------------------*/ 50 | /* USER CODE BEGIN EM */ 51 | 52 | /* USER CODE END EM */ 53 | 54 | /* Exported functions prototypes ---------------------------------------------*/ 55 | void Error_Handler(void); 56 | 57 | /* USER CODE BEGIN EFP */ 58 | 59 | /* USER CODE END EFP */ 60 | 61 | /* Private defines -----------------------------------------------------------*/ 62 | #define BUTTON_Pin GPIO_PIN_0 63 | #define BUTTON_GPIO_Port GPIOA 64 | #define LED_Pin GPIO_PIN_15 65 | #define LED_GPIO_Port GPIOD 66 | /* USER CODE BEGIN Private defines */ 67 | 68 | /* USER CODE END Private defines */ 69 | 70 | #ifdef __cplusplus 71 | } 72 | #endif 73 | 74 | #endif /* __MAIN_H */ 75 | 76 | /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ 77 | -------------------------------------------------------------------------------- /Core/Src/stm32f4xx_hal_msp.c: -------------------------------------------------------------------------------- 1 | /* USER CODE BEGIN Header */ 2 | /** 3 | ****************************************************************************** 4 | * @file stm32f4xx_hal_msp.c 5 | * @brief This file provides code for the MSP Initialization 6 | * and de-Initialization codes. 7 | ****************************************************************************** 8 | * @attention 9 | * 10 | *

© Copyright (c) 2021 STMicroelectronics. 11 | * All rights reserved.

12 | * 13 | * This software component is licensed by ST under BSD 3-Clause license, 14 | * the "License"; You may not use this file except in compliance with the 15 | * License. You may obtain a copy of the License at: 16 | * opensource.org/licenses/BSD-3-Clause 17 | * 18 | ****************************************************************************** 19 | */ 20 | /* USER CODE END Header */ 21 | 22 | /* Includes ------------------------------------------------------------------*/ 23 | #include "main.h" 24 | /* USER CODE BEGIN Includes */ 25 | 26 | /* USER CODE END Includes */ 27 | 28 | /* Private typedef -----------------------------------------------------------*/ 29 | /* USER CODE BEGIN TD */ 30 | 31 | /* USER CODE END TD */ 32 | 33 | /* Private define ------------------------------------------------------------*/ 34 | /* USER CODE BEGIN Define */ 35 | 36 | /* USER CODE END Define */ 37 | 38 | /* Private macro -------------------------------------------------------------*/ 39 | /* USER CODE BEGIN Macro */ 40 | 41 | /* USER CODE END Macro */ 42 | 43 | /* Private variables ---------------------------------------------------------*/ 44 | /* USER CODE BEGIN PV */ 45 | 46 | /* USER CODE END PV */ 47 | 48 | /* Private function prototypes -----------------------------------------------*/ 49 | /* USER CODE BEGIN PFP */ 50 | 51 | /* USER CODE END PFP */ 52 | 53 | /* External functions --------------------------------------------------------*/ 54 | /* USER CODE BEGIN ExternalFunctions */ 55 | 56 | /* USER CODE END ExternalFunctions */ 57 | 58 | /* USER CODE BEGIN 0 */ 59 | 60 | /* USER CODE END 0 */ 61 | /** 62 | * Initializes the Global MSP. 63 | */ 64 | void HAL_MspInit(void) 65 | { 66 | /* USER CODE BEGIN MspInit 0 */ 67 | 68 | /* USER CODE END MspInit 0 */ 69 | 70 | __HAL_RCC_SYSCFG_CLK_ENABLE(); 71 | __HAL_RCC_PWR_CLK_ENABLE(); 72 | 73 | /* System interrupt init*/ 74 | 75 | /* USER CODE BEGIN MspInit 1 */ 76 | 77 | /* USER CODE END MspInit 1 */ 78 | } 79 | 80 | /* USER CODE BEGIN 1 */ 81 | 82 | /* USER CODE END 1 */ 83 | 84 | /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ 85 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # STM32 project template 2 | 3 | This repository holds all the possible tools and templates for building and developing STM32 projects. 4 | Firmware is configured with CMake and can be built in multiple ways. 5 | 6 | I don't expect you to use all of the files found here or all the lines in the configuration files (Makefile, CMakeLists.txt, etc.). Make sure to read them and remove what you don't need. 7 | 8 | I will also try to make this repository as cross platform as possible. Currently I've tested it on Windows 10 and Linux (Fedora 35, Nixos, Ubuntu 20.04). Any problems regarding a specific distribution will be mentioned in the [workflows](#workflow). 9 | 10 | ## Example 11 | 12 | You can utilize everything in root of the repository. It holds an example project built around `STM32F407VG` on a discovery board. It blinks the onboard blue LED and prints "Hello, world" over SWO. 13 | 14 | ## Workflow 15 | 16 | There are a few options to build the CMake project. Approaches differ in dependency management and source control, which is important when you might work in a team or share your projects online. Pros and cons will be listed for each method in its guide. The following guides are available: 17 | 18 | [First way](docs/build-native.md) is to use the provided [Makefile](Makefile) for native development on your computer, You have to install the required dependencies on your computer, matching or exceeding the minimum required versions. 19 | 20 | [Second way](docs/build-container.md) is using a container tool like `docker` or `podman` with or without additional dependencies, like `docker-compose` or `make`. 21 | 22 | [Third way](docs/build-nix.md) is using nix with provided `flake.nix`. 23 | 24 | ## Code style 25 | 26 | Before committing code, format all source files. I have provided a set of [rules](.clang-format) for `clang-format`, which you can apply to all source files. 27 | 28 | You can do it for a specific file: `clang-format -i ` 29 | 30 | Or with a shell script: 31 | 32 | ```shell 33 | for file in $(find . -name '*.[ch]' -or -name '*.[ch]pp'); do clang-format -i $file; done 34 | ``` 35 | 36 | Or with provided makefile: 37 | 38 | `make format`: formats all source files in root using host installed clang-format. 39 | `make format-container`: formats all source files in root using container installed clang-format. 40 | 41 | ## Extra tool tips 42 | 43 | I have provided a [document](docs/tools.md), where I write about tools and commands that you can use to aid your development. 44 | 45 | ## Extra code tips 46 | 47 | I have provided a [document](docs/code-tips.md), where I write about useful options for writing and debugging code. 48 | -------------------------------------------------------------------------------- /flake.lock: -------------------------------------------------------------------------------- 1 | { 2 | "nodes": { 3 | "flake-utils": { 4 | "inputs": { 5 | "systems": "systems" 6 | }, 7 | "locked": { 8 | "lastModified": 1731533236, 9 | "narHash": "sha256-l0KFg5HjrsfsO/JpG+r7fRrqm12kzFHyUHqHCVpMMbI=", 10 | "owner": "numtide", 11 | "repo": "flake-utils", 12 | "rev": "11707dc2f618dd54ca8739b309ec4fc024de578b", 13 | "type": "github" 14 | }, 15 | "original": { 16 | "owner": "numtide", 17 | "repo": "flake-utils", 18 | "type": "github" 19 | } 20 | }, 21 | "jlink-pack": { 22 | "inputs": { 23 | "nixpkgs": "nixpkgs" 24 | }, 25 | "locked": { 26 | "lastModified": 1753658844, 27 | "narHash": "sha256-ZBczCLNS+hU4HUN0PIWuR4DbuxcyWViAWOUV9UdzRBk=", 28 | "owner": "prtzl", 29 | "repo": "jlink-nix", 30 | "rev": "26d320645361791291e8c54bf7c46dfb76a29284", 31 | "type": "github" 32 | }, 33 | "original": { 34 | "owner": "prtzl", 35 | "repo": "jlink-nix", 36 | "type": "github" 37 | } 38 | }, 39 | "nixpkgs": { 40 | "locked": { 41 | "lastModified": 1646254136, 42 | "narHash": "sha256-8nQx02tTzgYO21BP/dy5BCRopE8OwE8Drsw98j+Qoaw=", 43 | "owner": "nixos", 44 | "repo": "nixpkgs", 45 | "rev": "3e072546ea98db00c2364b81491b893673267827", 46 | "type": "github" 47 | }, 48 | "original": { 49 | "owner": "nixos", 50 | "ref": "nixos-unstable", 51 | "repo": "nixpkgs", 52 | "type": "github" 53 | } 54 | }, 55 | "nixpkgs_2": { 56 | "locked": { 57 | "lastModified": 1753429684, 58 | "narHash": "sha256-9h7+4/53cSfQ/uA3pSvCaBepmZaz/dLlLVJnbQ+SJjk=", 59 | "owner": "nixos", 60 | "repo": "nixpkgs", 61 | "rev": "7fd36ee82c0275fb545775cc5e4d30542899511d", 62 | "type": "github" 63 | }, 64 | "original": { 65 | "owner": "nixos", 66 | "ref": "nixos-unstable", 67 | "repo": "nixpkgs", 68 | "type": "github" 69 | } 70 | }, 71 | "root": { 72 | "inputs": { 73 | "flake-utils": "flake-utils", 74 | "jlink-pack": "jlink-pack", 75 | "nixpkgs": "nixpkgs_2" 76 | } 77 | }, 78 | "systems": { 79 | "locked": { 80 | "lastModified": 1681028828, 81 | "narHash": "sha256-Vy1rq5AaRuLzOxct8nz4T6wlgyUR7zLU309k9mBC768=", 82 | "owner": "nix-systems", 83 | "repo": "default", 84 | "rev": "da67096a3b9bf56a91d16901293e51ba5b49a27e", 85 | "type": "github" 86 | }, 87 | "original": { 88 | "owner": "nix-systems", 89 | "repo": "default", 90 | "type": "github" 91 | } 92 | } 93 | }, 94 | "root": "root", 95 | "version": 7 96 | } 97 | -------------------------------------------------------------------------------- /docs/build-native.md: -------------------------------------------------------------------------------- 1 | # Native build 2 | 3 | Build your project with dependencies installed on your computer, which are available in your `$PATH`. 4 | 5 | --- 6 | Pros: 7 | 8 | * Easy to use 9 | * Ready for development with IDE 10 | 11 | Cons: 12 | 13 | * Must install dependencies on your computer and have them be accessible in your `$PATH` 14 | * Versions of packages differ wildly between different operating systems and distributions. It is hard for collaborative projects where all involved have different systems. 15 | 16 | Verdict: 17 | 18 | * For the reasons above I recommend this option for individual development and solo release. 19 | 20 | --- 21 | 22 | ## Dependencies 23 | 24 | Install the following packages: 25 | 26 | * git 27 | * gnumake 28 | * cmake 29 | * gcc-arm-embedded (+ newlib and binutils if not included in the package) 30 | * clang-tools (optional) 31 | 32 | I would recommend gcc-10.3.y for latest C++20 features. Versions 9.x.y will still do C++20 but with a limited feature set. If you have newer, then go for it. 33 | 34 | You can download arm-none-eabi toolchain from [website](https://developer.arm.com/tools-and-software/open-source-software/developer-tools/gnu-toolchain/gnu-rm/downloads). It is universal for most distros. If your distribution carries it, install it with that, but mind the version and compatibility. 35 | 36 | **NOTE**. If your cmake fails to "compile a simple test program" while running the example, then you might not have `newlib` installed (one of the errors I have encountered). Some distribution packages carry the package separately. 37 | 38 | ## Workflow 39 | 40 | All actions are executed with the first part of the provided [Makefile](../Makefile). 41 | Following targets are available: 42 | 43 | `make -j`: build project. 44 | `make cmake`: (re)run cmake. 45 | `make build -j`: same as `make`. 46 | `make clean`: remove build folder. 47 | 48 | The included Makefile is used more as a helper script to avoid long repetitive commands. Plus you can add other useful targets, such as for formatting and flashing, where flashing part depends on a finished build. Quite nice. 49 | 50 | If you want to use `CMake` only, let's say for an IDE, then all you need to do is: 51 | 52 | * Generate cmake project (minimum): 53 | 54 | ```shell 55 | cmake -G "Unix Makefiles" -B build -DPROJECT_NAME=firmware -DCMAKE_TOOLCHAIN_FILE=gcc-arm-none-eabi.cmake -DCMAKE_BUILD_TYPE=Debug 56 | ``` 57 | 58 | * Compile project: 59 | 60 | ```shell 61 | # Directly with make 62 | make -C ./build -j 63 | 64 | # Indirectly with cmake 65 | cmake --build ./build -j 66 | ``` 67 | 68 | The indirect build command using cmake is convenient, as you don't need to know which build system is behind. CMake will call the one you have configured with first command. In this repository, this means `gnumake`. 69 | -------------------------------------------------------------------------------- /Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_flash_ramfunc.h: -------------------------------------------------------------------------------- 1 | /** 2 | ****************************************************************************** 3 | * @file stm32f4xx_hal_flash_ramfunc.h 4 | * @author MCD Application Team 5 | * @brief Header file of FLASH RAMFUNC driver. 6 | ****************************************************************************** 7 | * @attention 8 | * 9 | *

© Copyright (c) 2017 STMicroelectronics. 10 | * All rights reserved.

11 | * 12 | * This software component is licensed by ST under BSD 3-Clause license, 13 | * the "License"; You may not use this file except in compliance with the 14 | * License. You may obtain a copy of the License at: 15 | * opensource.org/licenses/BSD-3-Clause 16 | * 17 | ****************************************************************************** 18 | */ 19 | 20 | /* Define to prevent recursive inclusion -------------------------------------*/ 21 | #ifndef __STM32F4xx_FLASH_RAMFUNC_H 22 | #define __STM32F4xx_FLASH_RAMFUNC_H 23 | 24 | #ifdef __cplusplus 25 | extern "C" 26 | { 27 | #endif 28 | #if defined(STM32F410Tx) || defined(STM32F410Cx) || defined(STM32F410Rx) \ 29 | || defined(STM32F411xE) || defined(STM32F446xx) || defined(STM32F412Zx) \ 30 | || defined(STM32F412Vx) || defined(STM32F412Rx) || defined(STM32F412Cx) 31 | 32 | /* Includes ------------------------------------------------------------------*/ 33 | #include "stm32f4xx_hal_def.h" 34 | 35 | /** @addtogroup STM32F4xx_HAL_Driver 36 | * @{ 37 | */ 38 | 39 | /** @addtogroup FLASH_RAMFUNC 40 | * @{ 41 | */ 42 | 43 | /* Exported types ------------------------------------------------------------*/ 44 | /* Exported macro ------------------------------------------------------------*/ 45 | /* Exported functions --------------------------------------------------------*/ 46 | /** @addtogroup FLASH_RAMFUNC_Exported_Functions 47 | * @{ 48 | */ 49 | 50 | /** @addtogroup FLASH_RAMFUNC_Exported_Functions_Group1 51 | * @{ 52 | */ 53 | __RAM_FUNC HAL_StatusTypeDef HAL_FLASHEx_StopFlashInterfaceClk(void); 54 | __RAM_FUNC HAL_StatusTypeDef HAL_FLASHEx_StartFlashInterfaceClk(void); 55 | __RAM_FUNC HAL_StatusTypeDef HAL_FLASHEx_EnableFlashSleepMode(void); 56 | __RAM_FUNC HAL_StatusTypeDef HAL_FLASHEx_DisableFlashSleepMode(void); 57 | /** 58 | * @} 59 | */ 60 | 61 | /** 62 | * @} 63 | */ 64 | 65 | /** 66 | * @} 67 | */ 68 | 69 | /** 70 | * @} 71 | */ 72 | 73 | #endif /* STM32F410xx || STM32F411xE || STM32F446xx || STM32F412Zx || STM32F412Vx || \ 74 | STM32F412Rx || STM32F412Cx */ 75 | #ifdef __cplusplus 76 | } 77 | #endif 78 | 79 | #endif /* __STM32F4xx_FLASH_RAMFUNC_H */ 80 | 81 | /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ 82 | -------------------------------------------------------------------------------- /Drivers/CMSIS/Include/tz_context.h: -------------------------------------------------------------------------------- 1 | /****************************************************************************** 2 | * @file tz_context.h 3 | * @brief Context Management for Armv8-M TrustZone 4 | * @version V1.0.1 5 | * @date 10. January 2018 6 | ******************************************************************************/ 7 | /* 8 | * Copyright (c) 2017-2018 Arm Limited. All rights reserved. 9 | * 10 | * SPDX-License-Identifier: Apache-2.0 11 | * 12 | * Licensed under the Apache License, Version 2.0 (the License); you may 13 | * not use this file except in compliance with the License. 14 | * You may obtain a copy of the License at 15 | * 16 | * www.apache.org/licenses/LICENSE-2.0 17 | * 18 | * Unless required by applicable law or agreed to in writing, software 19 | * distributed under the License is distributed on an AS IS BASIS, WITHOUT 20 | * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 21 | * See the License for the specific language governing permissions and 22 | * limitations under the License. 23 | */ 24 | 25 | #if defined(__ICCARM__) 26 | #pragma system_include /* treat file as system include file for MISRA check */ 27 | #elif defined(__clang__) 28 | #pragma clang system_header /* treat file as system include file */ 29 | #endif 30 | 31 | #ifndef TZ_CONTEXT_H 32 | #define TZ_CONTEXT_H 33 | 34 | #include 35 | 36 | #ifndef TZ_MODULEID_T 37 | #define TZ_MODULEID_T 38 | /// \details Data type that identifies secure software modules called by a process. 39 | typedef uint32_t TZ_ModuleId_t; 40 | #endif 41 | 42 | /// \details TZ Memory ID identifies an allocated memory slot. 43 | typedef uint32_t TZ_MemoryId_t; 44 | 45 | /// Initialize secure context memory system 46 | /// \return execution status (1: success, 0: error) 47 | uint32_t TZ_InitContextSystem_S(void); 48 | 49 | /// Allocate context memory for calling secure software modules in TrustZone 50 | /// \param[in] module identifies software modules called from non-secure mode 51 | /// \return value != 0 id TrustZone memory slot identifier 52 | /// \return value 0 no memory available or internal error 53 | TZ_MemoryId_t TZ_AllocModuleContext_S(TZ_ModuleId_t module); 54 | 55 | /// Free context memory that was previously allocated with \ref TZ_AllocModuleContext_S 56 | /// \param[in] id TrustZone memory slot identifier 57 | /// \return execution status (1: success, 0: error) 58 | uint32_t TZ_FreeModuleContext_S(TZ_MemoryId_t id); 59 | 60 | /// Load secure context (called on RTOS thread context switch) 61 | /// \param[in] id TrustZone memory slot identifier 62 | /// \return execution status (1: success, 0: error) 63 | uint32_t TZ_LoadContext_S(TZ_MemoryId_t id); 64 | 65 | /// Store secure context (called on RTOS thread context switch) 66 | /// \param[in] id TrustZone memory slot identifier 67 | /// \return execution status (1: success, 0: error) 68 | uint32_t TZ_StoreContext_S(TZ_MemoryId_t id); 69 | 70 | #endif // TZ_CONTEXT_H 71 | -------------------------------------------------------------------------------- /Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_dma_ex.h: -------------------------------------------------------------------------------- 1 | /** 2 | ****************************************************************************** 3 | * @file stm32f4xx_hal_dma_ex.h 4 | * @author MCD Application Team 5 | * @brief Header file of DMA HAL extension module. 6 | ****************************************************************************** 7 | * @attention 8 | * 9 | *

© Copyright (c) 2017 STMicroelectronics. 10 | * All rights reserved.

11 | * 12 | * This software component is licensed by ST under BSD 3-Clause license, 13 | * the "License"; You may not use this file except in compliance with the 14 | * License. You may obtain a copy of the License at: 15 | * opensource.org/licenses/BSD-3-Clause 16 | * 17 | ****************************************************************************** 18 | */ 19 | 20 | /* Define to prevent recursive inclusion -------------------------------------*/ 21 | #ifndef __STM32F4xx_HAL_DMA_EX_H 22 | #define __STM32F4xx_HAL_DMA_EX_H 23 | 24 | #ifdef __cplusplus 25 | extern "C" 26 | { 27 | #endif 28 | 29 | /* Includes ------------------------------------------------------------------*/ 30 | #include "stm32f4xx_hal_def.h" 31 | 32 | /** @addtogroup STM32F4xx_HAL_Driver 33 | * @{ 34 | */ 35 | 36 | /** @addtogroup DMAEx 37 | * @{ 38 | */ 39 | 40 | /* Exported types ------------------------------------------------------------*/ 41 | /** @defgroup DMAEx_Exported_Types DMAEx Exported Types 42 | * @brief DMAEx Exported types 43 | * @{ 44 | */ 45 | 46 | /** 47 | * @brief HAL DMA Memory definition 48 | */ 49 | typedef enum 50 | { 51 | MEMORY0 = 0x00U, /*!< Memory 0 */ 52 | MEMORY1 = 0x01U /*!< Memory 1 */ 53 | } HAL_DMA_MemoryTypeDef; 54 | 55 | /** 56 | * @} 57 | */ 58 | 59 | /* Exported functions --------------------------------------------------------*/ 60 | /** @defgroup DMAEx_Exported_Functions DMAEx Exported Functions 61 | * @brief DMAEx Exported functions 62 | * @{ 63 | */ 64 | 65 | /** @defgroup DMAEx_Exported_Functions_Group1 Extended features functions 66 | * @brief Extended features functions 67 | * @{ 68 | */ 69 | 70 | /* IO operation functions *******************************************************/ 71 | HAL_StatusTypeDef HAL_DMAEx_MultiBufferStart( 72 | DMA_HandleTypeDef* hdma, 73 | uint32_t SrcAddress, 74 | uint32_t DstAddress, 75 | uint32_t SecondMemAddress, 76 | uint32_t DataLength); 77 | HAL_StatusTypeDef HAL_DMAEx_MultiBufferStart_IT( 78 | DMA_HandleTypeDef* hdma, 79 | uint32_t SrcAddress, 80 | uint32_t DstAddress, 81 | uint32_t SecondMemAddress, 82 | uint32_t DataLength); 83 | HAL_StatusTypeDef HAL_DMAEx_ChangeMemory( 84 | DMA_HandleTypeDef* hdma, uint32_t Address, HAL_DMA_MemoryTypeDef memory); 85 | 86 | /** 87 | * @} 88 | */ 89 | /** 90 | * @} 91 | */ 92 | 93 | /* Private functions ---------------------------------------------------------*/ 94 | /** @defgroup DMAEx_Private_Functions DMAEx Private Functions 95 | * @brief DMAEx Private functions 96 | * @{ 97 | */ 98 | /** 99 | * @} 100 | */ 101 | 102 | /** 103 | * @} 104 | */ 105 | 106 | /** 107 | * @} 108 | */ 109 | 110 | #ifdef __cplusplus 111 | } 112 | #endif 113 | 114 | #endif /*__STM32F4xx_HAL_DMA_EX_H*/ 115 | 116 | /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ 117 | -------------------------------------------------------------------------------- /docs/tools.md: -------------------------------------------------------------------------------- 1 | # Usefull build tools 2 | 3 | This documents includes some useful tools and how to use them for development and debugging. 4 | 5 | Most of these tools print output in terminal, which can be problematic if the output is large or you want to save it. 6 | 7 | For inspecting the contents and discarding the result I just pipe the output into less: 8 | 9 | ```shell 10 | | less 11 | ``` 12 | 13 | For saving file, you can redirect the output into a new file: 14 | 15 | ```shell 16 | > outputFile.txt 17 | ``` 18 | 19 | **NOTE:** `>` redirection will overwrite the file. If you want to append to it, use `>>`. 20 | 21 | ## objdump 22 | 23 | This tool is used to view contents of object files, such as `.o` and `.elf`.The arm toolchain provides `arm-none-eabi-objdump`. 24 | 25 | In context of executable `.elf`, this can be used to disassemble a section or the entire file. With this tool you can inspect the assembly and state of sections and variables. 26 | 27 | Command: 28 | 29 | ```shell 30 | arm-none-eabi-objdump 31 | ``` 32 | 33 | Options: 34 | 35 | * `-d`: disassemble all "runnable" sections (code) 36 | * `-D`: disassemble all sections (code and data) 37 | * `-j
`: used along with `-d/D` will display only a selected section 38 | * `-C`: demangle symbol names (C++) 39 | * `-h`: view only headers (used alone without other options) 40 | 41 | ### Examples 42 | 43 | **Dump a specific section (example: .rodata):** 44 | 45 | ```shell 46 | arm-none-eabi-objdump -D -j .rodata -C ./firmware.bin 47 | ``` 48 | 49 | **Dump the entire file:** 50 | 51 | ```shell 52 | arm-none-eabi-objdump -D -C ./firmware.bin 53 | ``` 54 | 55 | **View section headers:** 56 | 57 | ```shell 58 | arm-none-eabi-objdump -h ./firmware.bin 59 | ``` 60 | 61 | ## readelf 62 | 63 | This tool is similar in function to `objdump` but displays a bit more information. It is also limited to `.elf` files. The arm toolchain provides `arm-none-eabi-readelf`. 64 | 65 | Command: 66 | 67 | ```shell 68 | arm-none-eabi-readelf 69 | ``` 70 | 71 | Options: 72 | 73 | * `-h`: display ELF file header (file information) 74 | * `-S`: display sections (a bit nicer than `objdump -h`, but missing some information) 75 | * `-s`: display all symbols (functions, global variables) 76 | * `-C`: demangle symbol names (C++), used with `-s` 77 | * `-x
`: hexdumps the section contents (4 groups of 4 byte strings per line) 78 | * `-p
`: stringdumps the section contents 79 | 80 | ### Examples 81 | 82 | **View file information:** 83 | 84 | ```shell 85 | arm-none-eabi-readelf -h ./firmware.elf 86 | ``` 87 | 88 | **View sections headers:** 89 | 90 | ```shell 91 | arm-none-eabi-readelf -S -C ./firmware.elf 92 | ``` 93 | 94 | **View all symbols:** 95 | 96 | ```shell 97 | arm-none-eabi-readelf -s -C ./firmware.elf 98 | ``` 99 | 100 | **Hexdump section:** 101 | 102 | ```shell 103 | arm-none-eabi-readelf -x .rodata ./firmware.elf 104 | ``` 105 | 106 | **Stringdump section:** 107 | 108 | ```shell 109 | arm-none-eabi-readelf -p .rodata ./firmware.elf 110 | ``` 111 | 112 | ## hexdump 113 | 114 | Hexdump is used to view and filter raw contents of a file. The output format can be changed. The utility is not specific to arm toolchain and can be found on most linux distributions already installed. 115 | 116 | It doesn't do much, therefore it doesn't have as many options, so I use it mainly for viewing bin files: 117 | 118 | ```shell 119 | hexdump -C 120 | ``` 121 | 122 | This command will display output in hex (two characted per byte, 16 bytes per line) as well as ascii (similar to objdump with `-x`). 123 | -------------------------------------------------------------------------------- /docs/build-nix.md: -------------------------------------------------------------------------------- 1 | # Building with nix 2 | 3 | Nix is a combination of package manager, source control, versioning and build tool. It uses a functional expression language to describe how to build a package. Using its repository store, `default.nix` file describes all the build inputs and outputs along with the build steps. 4 | 5 | Using, currently beta, flakes, we can improve the build step by providing a simple input and output definition of the project. On first build it will create a `flake.lock` file, which holds commit hashes for all used packages. This way, this project can be built at any time with the same exact version of software to provide the same exact binary. 6 | 7 | Nix has a steep learning curve, which I'm still in the middle of, but in the long run it proves to be very powerful and convenient. In one command, one can build an STM32 project, a x86_64 application and even mix the two, to provide a certain output. Flashing and building can also be automated. 8 | 9 | ## Dependencies 10 | 11 | Nix can be install on all unix platforms. Navigate the [website](https://nixos.org/download.html) for installation instructions. For current flakes we'll need the most up-to date version on `unstable` channel. 12 | 13 | You can also install `direnv` to your shell along with `nix-direnv` and run `direnv allow` to automatically load the shell with installed dependencies. Otherwise call `nix develop`. This enables you to enter a shell with all the packages that are used to build you project and more. This is very useful for development and debugging without the need to install the packages on your computer globally. 14 | 15 | ## Workflow 16 | 17 | To build the project, run 18 | 19 | ```shell 20 | nix build # optionaly add -L to see the progress 21 | ``` 22 | 23 | Default target is currently set to be the firmware. 24 | If successful, the resulting `.bin`, `.elf` and `.s` files will be placed into symlink directory `./result/bin`. 25 | 26 | To flash the firmware you can currently use stlink or jlink. The run command depends on firmware, which will be built if missing or if the source files have been changed. 27 | 28 | ```shell 29 | # Default run target - currently jlink 30 | nix run 31 | 32 | # Run jlink flasher 33 | nix run .#flash-jlink 34 | 35 | # Run stlink flasher 36 | nix run .#flash-stlink 37 | ``` 38 | 39 | If you're using `nix-direnv`, then the first time you load up the development shell it will download all the inputs and create a cache directory `.direnv`. As long as this directory remains, nix garbage collector won't touch it. You can see the link for all such repositories in `/nix/var/nix/gcroots`, where the exsistance of a link signals nix garbage collector to leave the repository sources alone. 40 | 41 | In development mode use the provided [Makefile](../Makefile) as described in [native development](build-native.md), which generates build files along with `compile_commands.json` in `build` folder. You can use this in your IDE of choice. You can also use nix to generate those files, but make sure, that your IDE was launched from the development shell or, in case of vscode, you have nix plugins installed. 42 | 43 | --- 44 | 45 | Pros: 46 | 47 | * Dependencies are not installed system-wide and do not pollute your filesystem. 48 | * Project dependencies version is fixed with lock file and only updates on users request. 49 | * You can still use the provided [Makefile](../Makefile) as with [native development](build-native.md) as the shell loads all the dependencies. 50 | * For the above reason, you can also use your favorite IDE. 51 | 52 | Cons: 53 | 54 | * Steep learning curve with nix expression language. 55 | * Not available natively on windows. 56 | 57 | Verdict: 58 | 59 | * For the reasons above I recommend this option for everyone running linux or macOS for development and release. 60 | 61 | --- 62 | -------------------------------------------------------------------------------- /Drivers/CMSIS/Device/ST/STM32F4xx/Include/system_stm32f4xx.h: -------------------------------------------------------------------------------- 1 | /** 2 | ****************************************************************************** 3 | * @file system_stm32f4xx.h 4 | * @author MCD Application Team 5 | * @brief CMSIS Cortex-M4 Device System Source File for STM32F4xx devices. 6 | ****************************************************************************** 7 | * @attention 8 | * 9 | *

© COPYRIGHT(c) 2017 STMicroelectronics

10 | * 11 | * Redistribution and use in source and binary forms, with or without modification, 12 | * are permitted provided that the following conditions are met: 13 | * 1. Redistributions of source code must retain the above copyright notice, 14 | * this list of conditions and the following disclaimer. 15 | * 2. Redistributions in binary form must reproduce the above copyright notice, 16 | * this list of conditions and the following disclaimer in the documentation 17 | * and/or other materials provided with the distribution. 18 | * 3. Neither the name of STMicroelectronics nor the names of its contributors 19 | * may be used to endorse or promote products derived from this software 20 | * without specific prior written permission. 21 | * 22 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 23 | * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 24 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 25 | * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE 26 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 27 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 28 | * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 29 | * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 30 | * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 31 | * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 32 | * 33 | ****************************************************************************** 34 | */ 35 | 36 | /** @addtogroup CMSIS 37 | * @{ 38 | */ 39 | 40 | /** @addtogroup stm32f4xx_system 41 | * @{ 42 | */ 43 | 44 | /** 45 | * @brief Define to prevent recursive inclusion 46 | */ 47 | #ifndef __SYSTEM_STM32F4XX_H 48 | #define __SYSTEM_STM32F4XX_H 49 | 50 | #ifdef __cplusplus 51 | extern "C" 52 | { 53 | #endif 54 | 55 | /** @addtogroup STM32F4xx_System_Includes 56 | * @{ 57 | */ 58 | 59 | /** 60 | * @} 61 | */ 62 | 63 | /** @addtogroup STM32F4xx_System_Exported_types 64 | * @{ 65 | */ 66 | /* This variable is updated in three ways: 67 | 1) by calling CMSIS function SystemCoreClockUpdate() 68 | 2) by calling HAL API function HAL_RCC_GetSysClockFreq() 69 | 3) each time HAL_RCC_ClockConfig() is called to configure the system clock frequency 70 | Note: If you use this function to configure the system clock; then there 71 | is no need to call the 2 first functions listed above, since SystemCoreClock 72 | variable is updated automatically. 73 | */ 74 | extern uint32_t SystemCoreClock; /*!< System Clock Frequency (Core Clock) */ 75 | 76 | extern const uint8_t AHBPrescTable[16]; /*!< AHB prescalers table values */ 77 | extern const uint8_t APBPrescTable[8]; /*!< APB prescalers table values */ 78 | 79 | /** 80 | * @} 81 | */ 82 | 83 | /** @addtogroup STM32F4xx_System_Exported_Constants 84 | * @{ 85 | */ 86 | 87 | /** 88 | * @} 89 | */ 90 | 91 | /** @addtogroup STM32F4xx_System_Exported_Macros 92 | * @{ 93 | */ 94 | 95 | /** 96 | * @} 97 | */ 98 | 99 | /** @addtogroup STM32F4xx_System_Exported_Functions 100 | * @{ 101 | */ 102 | 103 | extern void SystemInit(void); 104 | extern void SystemCoreClockUpdate(void); 105 | /** 106 | * @} 107 | */ 108 | 109 | #ifdef __cplusplus 110 | } 111 | #endif 112 | 113 | #endif /*__SYSTEM_STM32F4XX_H */ 114 | 115 | /** 116 | * @} 117 | */ 118 | 119 | /** 120 | * @} 121 | */ 122 | /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ 123 | -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | .PHONY: all build build-container cmake format format-linux flash-stlink flash-jlink format-container shell image build-container clean clean-image clean-all 2 | ############################### Native Makefile ############################### 3 | 4 | PROJECT_NAME ?= firmware 5 | BUILD_DIR ?= build 6 | FIRMWARE := $(BUILD_DIR)/$(PROJECT_NAME).bin 7 | BUILD_TYPE ?= debug 8 | PLATFORM = $(if $(OS),$(OS),$(shell uname -s)) 9 | 10 | ifeq ($(PLATFORM),Windows_NT) 11 | BUILD_SYSTEM ?= MinGW Makefiles 12 | else 13 | ifeq ($(PLATFORM),Linux) 14 | BUILD_SYSTEM ?= Unix Makefiles 15 | else 16 | @echo "Unsuported platform" 17 | exit 1 18 | endif 19 | endif 20 | 21 | all: build 22 | 23 | build: cmake 24 | $(MAKE) -C $(BUILD_DIR) --no-print-directory 25 | 26 | cmake: $(BUILD_DIR)/Makefile 27 | 28 | $(BUILD_DIR)/Makefile: CMakeLists.txt 29 | cmake \ 30 | -G "$(BUILD_SYSTEM)" \ 31 | -B$(BUILD_DIR) \ 32 | -DPROJECT_NAME=$(PROJECT_NAME) \ 33 | -DCMAKE_BUILD_TYPE=$(BUILD_TYPE) \ 34 | -DDUMP_ASM=OFF 35 | 36 | # Formats all user modified source files (add ones that are missing) 37 | SRCS := $(shell find Project -name '*.[ch]' -or -name '*.[ch]pp') Core/Src/main.c 38 | format: $(addsuffix .format,$(SRCS)) 39 | %.format: % 40 | clang-format -i $< 41 | 42 | # Formats all CubeMX generated sources to unix style - removes \r from line endings 43 | # Add any new directories, like Middlewares and hidden files 44 | HIDDEN_FILES := .mxproject .project .cproject 45 | FOUND_HIDDEN_FILES := $(shell for f in $(HIDDEN_FILES);do if [[ -e $$f ]]; then echo $$f;fi; done) 46 | FORMAT_LINUX := $(shell find Core Drivers -name '*' -type f; find . -name '*.ioc') $(FOUND_HIDDEN_FILES) 47 | 48 | format-linux: $(addsuffix .format-linux,$(FORMAT_LINUX)) 49 | %.format-linux: % 50 | $(if $(filter $(PLATFORM),Linux),dos2unix -q $<,) 51 | 52 | # Device specific! 53 | DEVICE ?= STM32F407VG 54 | 55 | flash-st: build 56 | st-flash --reset write $(FIRMWARE) 0x08000000 57 | 58 | $(BUILD_DIR)/jlink-script: 59 | touch $@ 60 | @echo device $(DEVICE) > $@ 61 | @echo si 1 >> $@ 62 | @echo speed 4000 >> $@ 63 | @echo loadfile $(FIRMWARE),0x08000000 >> $@ 64 | @echo -e "r\ng\nqc" >> $@ 65 | 66 | flash-jlink: build | $(BUILD_DIR)/jlink-script 67 | JLinkExe -commanderScript $(BUILD_DIR)/jlink-script 68 | 69 | clean: 70 | rm -rf $(BUILD_DIR) 71 | 72 | ################################## Container ################################## 73 | 74 | UID ?= $(shell id -u) 75 | GID ?= $(shell id -g) 76 | USER ?= $(shell id -un) 77 | GROUP ?= $(if $(filter $(PLATFORM), Windows_NT),$(shell id -un),$(shell id -gn)) 78 | 79 | ifeq ($(PLATFORM),Windows_NT) 80 | WIN_PREFIX = winpty 81 | WORKDIR_PATH = "//workdir" 82 | WORKDIR_VOLUME = "/$$(pwd -W):/workdir" 83 | else 84 | WORKDIR_PATH = /workdir 85 | WORKDIR_VOLUME = "$$(pwd):/workdir" 86 | endif 87 | 88 | CONTAINER_TOOL ?= docker 89 | CONTAINER_FILE := Dockerfile 90 | IMAGE_NAME := fedora-arm-embedded-dev 91 | CONTAINER_NAME := fedora-arm-embedded-dev 92 | 93 | NEED_IMAGE = $(shell $(CONTAINER_TOOL) image inspect $(IMAGE_NAME) 2> /dev/null > /dev/null || echo image) 94 | # usefull if you have a always running container in the background: NEED_CONTAINER = $(shell $(CONTAINER_TOOL) container inspect $(CONTAINER_NAME) 2> /dev/null > /dev/null || echo container) 95 | PODMAN_ARG = $(if $(filter $(CONTAINER_TOOL), podman),--userns=keep-id,) 96 | CONTAINER_RUN = $(WIN_PREFIX) $(CONTAINER_TOOL) run \ 97 | --name $(CONTAINER_NAME) \ 98 | --rm \ 99 | -it \ 100 | $(PODMAN_ARG) \ 101 | -v $(WORKDIR_VOLUME) \ 102 | -w $(WORKDIR_PATH) \ 103 | --security-opt label=disable \ 104 | --hostname $(CONTAINER_NAME) \ 105 | $(IMAGE_NAME) 106 | 107 | build-container: $(NEED_IMAGE) 108 | $(CONTAINER_RUN) bash -lc 'make -j$(shell nproc)' 109 | 110 | format-container: 111 | $(CONTAINER_RUN) bash -lc 'make format -j$(shell nproc)' 112 | 113 | format-linux-container: 114 | $(CONTAINER_RUN) bash -lc 'make format-linux' 115 | 116 | shell: 117 | $(CONTAINER_RUN) bash -l 118 | 119 | image: $(CONTAINER_FILE) 120 | $(CONTAINER_TOOL) build \ 121 | -t $(IMAGE_NAME) \ 122 | -f=$(CONTAINER_FILE) \ 123 | --build-arg UID=$(UID) \ 124 | --build-arg GID=$(GID) \ 125 | --build-arg USERNAME=$(USER) \ 126 | --build-arg GROUPNAME=$(GROUP) \ 127 | . 128 | 129 | clean-image: 130 | $(CONTAINER_TOOL) container rm -f $(CONTAINER_NAME) 2> /dev/null > /dev/null || true 131 | $(CONTAINER_TOOL) image rmi -f $(IMAGE_NAME) 2> /dev/null > /dev/null || true 132 | 133 | clean-all: clean clean-image 134 | -------------------------------------------------------------------------------- /.clang-format: -------------------------------------------------------------------------------- 1 | --- 2 | Language: Cpp 3 | # BasedOnStyle: Microsoft 4 | AccessModifierOffset: -4 5 | AlignAfterOpenBracket: AlwaysBreak 6 | AlignConsecutiveMacros: false 7 | AlignConsecutiveAssignments: false 8 | AlignConsecutiveDeclarations: false 9 | AlignEscapedNewlines: Right 10 | AlignOperands: AlignAfterOperator 11 | AlignTrailingComments: true 12 | AllowAllArgumentsOnNextLine: true 13 | AllowAllConstructorInitializersOnNextLine: true 14 | AllowAllParametersOfDeclarationOnNextLine: true 15 | AllowShortBlocksOnASingleLine: Never 16 | AllowShortCaseLabelsOnASingleLine: false 17 | AllowShortFunctionsOnASingleLine: None 18 | AllowShortLambdasOnASingleLine: All 19 | AllowShortIfStatementsOnASingleLine: Never 20 | AllowShortLoopsOnASingleLine: false 21 | AlwaysBreakAfterDefinitionReturnType: None 22 | AlwaysBreakAfterReturnType: None 23 | AlwaysBreakBeforeMultilineStrings: true 24 | AlwaysBreakTemplateDeclarations: true 25 | BinPackArguments: false 26 | BinPackParameters: false 27 | BreakBeforeBraces: Allman 28 | BraceWrapping: 29 | AfterCaseLabel: true 30 | AfterClass: true 31 | AfterControlStatement: true 32 | AfterEnum: true 33 | AfterFunction: true 34 | AfterNamespace: true 35 | AfterObjCDeclaration: true 36 | AfterStruct: true 37 | AfterUnion: true 38 | AfterExternBlock: true 39 | BeforeCatch: true 40 | BeforeElse: true 41 | IndentBraces: false 42 | SplitEmptyFunction: true 43 | SplitEmptyRecord: true 44 | SplitEmptyNamespace: true 45 | BreakBeforeBinaryOperators: NonAssignment 46 | BreakBeforeInheritanceComma: true 47 | BreakInheritanceList: BeforeColon 48 | BreakBeforeTernaryOperators: true 49 | BreakConstructorInitializersBeforeComma: true 50 | BreakConstructorInitializers: BeforeColon 51 | BreakAfterJavaFieldAnnotations: false 52 | BreakStringLiterals: true 53 | ColumnLimit: 95 54 | CommentPragmas: '^ IWYU pragma:' 55 | CompactNamespaces: false 56 | ConstructorInitializerAllOnOneLineOrOnePerLine: false 57 | ConstructorInitializerIndentWidth: 4 58 | ContinuationIndentWidth: 4 59 | Cpp11BracedListStyle: true 60 | DeriveLineEnding: false 61 | DerivePointerAlignment: false 62 | DisableFormat: false 63 | ExperimentalAutoDetectBinPacking: false 64 | FixNamespaceComments: true 65 | ForEachMacros: 66 | - foreach 67 | - Q_FOREACH 68 | - BOOST_FOREACH 69 | IncludeBlocks: Preserve 70 | IncludeCategories: 71 | - Regex: '^"(llvm|llvm-c|clang|clang-c)/' 72 | Priority: 2 73 | SortPriority: 0 74 | - Regex: '^(<|"(gtest|gmock|isl|json)/)' 75 | Priority: 3 76 | SortPriority: 0 77 | - Regex: '.*' 78 | Priority: 1 79 | SortPriority: 0 80 | IncludeIsMainRegex: '(Test)?$' 81 | IncludeIsMainSourceRegex: '' 82 | IndentCaseLabels: false 83 | IndentGotoLabels: true 84 | IndentPPDirectives: None 85 | IndentWidth: 4 86 | IndentWrappedFunctionNames: false 87 | JavaScriptQuotes: Leave 88 | JavaScriptWrapImports: true 89 | KeepEmptyLinesAtTheStartOfBlocks: true 90 | MacroBlockBegin: '' 91 | MacroBlockEnd: '' 92 | MaxEmptyLinesToKeep: 1 93 | NamespaceIndentation: None 94 | ObjCBinPackProtocolList: Auto 95 | ObjCBlockIndentWidth: 2 96 | ObjCSpaceAfterProperty: false 97 | ObjCSpaceBeforeProtocolList: true 98 | PenaltyBreakAssignment: 2 99 | PenaltyBreakBeforeFirstCallParameter: 19 100 | PenaltyBreakComment: 300 101 | PenaltyBreakFirstLessLess: 120 102 | PenaltyBreakString: 1000 103 | PenaltyBreakTemplateDeclaration: 10 104 | PenaltyExcessCharacter: 1000000 105 | PenaltyReturnTypeOnItsOwnLine: 1000 106 | PointerAlignment: Left 107 | ReflowComments: true 108 | SortIncludes: true 109 | SortUsingDeclarations: true 110 | SpaceAfterCStyleCast: false 111 | SpaceAfterLogicalNot: false 112 | SpaceAfterTemplateKeyword: true 113 | SpaceBeforeAssignmentOperators: true 114 | SpaceBeforeCpp11BracedList: false 115 | SpaceBeforeCtorInitializerColon: true 116 | SpaceBeforeInheritanceColon: true 117 | SpaceBeforeParens: ControlStatements 118 | SpaceBeforeRangeBasedForLoopColon: true 119 | SpaceInEmptyBlock: false 120 | SpaceInEmptyParentheses: false 121 | SpacesBeforeTrailingComments: 1 122 | SpacesInAngles: false 123 | SpacesInConditionalStatement: false 124 | SpacesInContainerLiterals: true 125 | SpacesInCStyleCastParentheses: false 126 | SpacesInParentheses: false 127 | SpacesInSquareBrackets: false 128 | SpaceBeforeSquareBrackets: false 129 | Standard: Latest 130 | StatementMacros: 131 | - Q_UNUSED 132 | - QT_REQUIRE_VERSION 133 | TabWidth: 4 134 | UseCRLF: false 135 | UseTab: Never 136 | ... 137 | 138 | -------------------------------------------------------------------------------- /STM32-project-template.ioc: -------------------------------------------------------------------------------- 1 | #MicroXplorer Configuration settings - do not modify 2 | File.Version=6 3 | GPIO.groupedBy= 4 | KeepUserPlacement=false 5 | Mcu.CPN=STM32F407VGT6 6 | Mcu.Family=STM32F4 7 | Mcu.IP0=NVIC 8 | Mcu.IP1=RCC 9 | Mcu.IP2=SYS 10 | Mcu.IPNb=3 11 | Mcu.Name=STM32F407V(E-G)Tx 12 | Mcu.Package=LQFP100 13 | Mcu.Pin0=PH0-OSC_IN 14 | Mcu.Pin1=PH1-OSC_OUT 15 | Mcu.Pin2=PA0-WKUP 16 | Mcu.Pin3=PD15 17 | Mcu.Pin4=VP_SYS_VS_Systick 18 | Mcu.PinsNb=5 19 | Mcu.ThirdPartyNb=0 20 | Mcu.UserConstants= 21 | Mcu.UserName=STM32F407VGTx 22 | MxCube.Version=6.2.1 23 | MxDb.Version=DB.6.0.21 24 | NVIC.BusFault_IRQn=true\:0\:0\:false\:false\:true\:false\:false\:false 25 | NVIC.DebugMonitor_IRQn=true\:0\:0\:false\:false\:true\:false\:false\:false 26 | NVIC.ForceEnableDMAVector=true 27 | NVIC.HardFault_IRQn=true\:0\:0\:false\:false\:true\:false\:false\:false 28 | NVIC.MemoryManagement_IRQn=true\:0\:0\:false\:false\:true\:false\:false\:false 29 | NVIC.NonMaskableInt_IRQn=true\:0\:0\:false\:false\:true\:false\:false\:false 30 | NVIC.PendSV_IRQn=true\:0\:0\:false\:false\:true\:false\:false\:false 31 | NVIC.PriorityGroup=NVIC_PRIORITYGROUP_4 32 | NVIC.SVCall_IRQn=true\:0\:0\:false\:false\:true\:false\:false\:false 33 | NVIC.SysTick_IRQn=true\:0\:0\:false\:false\:true\:false\:true\:false 34 | NVIC.UsageFault_IRQn=true\:0\:0\:false\:false\:true\:false\:false\:false 35 | PA0-WKUP.GPIOParameters=GPIO_Label 36 | PA0-WKUP.GPIO_Label=BUTTON 37 | PA0-WKUP.Locked=true 38 | PA0-WKUP.Signal=GPIO_Input 39 | PD15.GPIOParameters=GPIO_Label 40 | PD15.GPIO_Label=LED 41 | PD15.Signal=GPIO_Output 42 | PH0-OSC_IN.Mode=HSE-External-Oscillator 43 | PH0-OSC_IN.Signal=RCC_OSC_IN 44 | PH1-OSC_OUT.Mode=HSE-External-Oscillator 45 | PH1-OSC_OUT.Signal=RCC_OSC_OUT 46 | PinOutPanel.RotationAngle=0 47 | ProjectManager.AskForMigrate=true 48 | ProjectManager.BackupPrevious=false 49 | ProjectManager.CompilerOptimize=6 50 | ProjectManager.ComputerToolchain=false 51 | ProjectManager.CoupleFile=true 52 | ProjectManager.CustomerFirmwarePackage= 53 | ProjectManager.DefaultFWLocation=true 54 | ProjectManager.DeletePrevious=true 55 | ProjectManager.DeviceId=STM32F407VGTx 56 | ProjectManager.FirmwarePackage=STM32Cube FW_F4 V1.26.2 57 | ProjectManager.FreePins=false 58 | ProjectManager.HalAssertFull=false 59 | ProjectManager.HeapSize=0x200 60 | ProjectManager.KeepUserCode=true 61 | ProjectManager.LastFirmware=true 62 | ProjectManager.LibraryCopy=1 63 | ProjectManager.MainLocation=Core/Src 64 | ProjectManager.NoMain=false 65 | ProjectManager.PreviousToolchain= 66 | ProjectManager.ProjectBuild=false 67 | ProjectManager.ProjectFileName=STM32-project-template.ioc 68 | ProjectManager.ProjectName=STM32-project-template 69 | ProjectManager.RegisterCallBack= 70 | ProjectManager.StackSize=0x400 71 | ProjectManager.TargetToolchain=Makefile 72 | ProjectManager.ToolChainLocation= 73 | ProjectManager.UnderRoot=false 74 | ProjectManager.functionlistsort=1-MX_GPIO_Init-GPIO-false-HAL-true,2-SystemClock_Config-RCC-false-HAL-false 75 | RCC.48MHZClocksFreq_Value=84000000 76 | RCC.AHBFreq_Value=168000000 77 | RCC.APB1CLKDivider=RCC_HCLK_DIV4 78 | RCC.APB1Freq_Value=42000000 79 | RCC.APB1TimFreq_Value=84000000 80 | RCC.APB2CLKDivider=RCC_HCLK_DIV4 81 | RCC.APB2Freq_Value=42000000 82 | RCC.APB2TimFreq_Value=84000000 83 | RCC.CortexFreq_Value=168000000 84 | RCC.EthernetFreq_Value=168000000 85 | RCC.FCLKCortexFreq_Value=168000000 86 | RCC.FamilyName=M 87 | RCC.HCLKFreq_Value=168000000 88 | RCC.HSE_VALUE=8000000 89 | RCC.HSI_VALUE=16000000 90 | RCC.I2SClocksFreq_Value=192000000 91 | RCC.IPParameters=48MHZClocksFreq_Value,AHBFreq_Value,APB1CLKDivider,APB1Freq_Value,APB1TimFreq_Value,APB2CLKDivider,APB2Freq_Value,APB2TimFreq_Value,CortexFreq_Value,EthernetFreq_Value,FCLKCortexFreq_Value,FamilyName,HCLKFreq_Value,HSE_VALUE,HSI_VALUE,I2SClocksFreq_Value,LSE_VALUE,LSI_VALUE,MCO2PinFreq_Value,PLLCLKFreq_Value,PLLM,PLLN,PLLQCLKFreq_Value,PLLSourceVirtual,RTCFreq_Value,RTCHSEDivFreq_Value,SYSCLKFreq_VALUE,SYSCLKSource,VCOI2SOutputFreq_Value,VCOInputFreq_Value,VCOOutputFreq_Value,VcooutputI2S 92 | RCC.LSE_VALUE=32768 93 | RCC.LSI_VALUE=32000 94 | RCC.MCO2PinFreq_Value=168000000 95 | RCC.PLLCLKFreq_Value=168000000 96 | RCC.PLLM=4 97 | RCC.PLLN=168 98 | RCC.PLLQCLKFreq_Value=84000000 99 | RCC.PLLSourceVirtual=RCC_PLLSOURCE_HSE 100 | RCC.RTCFreq_Value=32000 101 | RCC.RTCHSEDivFreq_Value=4000000 102 | RCC.SYSCLKFreq_VALUE=168000000 103 | RCC.SYSCLKSource=RCC_SYSCLKSOURCE_PLLCLK 104 | RCC.VCOI2SOutputFreq_Value=384000000 105 | RCC.VCOInputFreq_Value=2000000 106 | RCC.VCOOutputFreq_Value=336000000 107 | RCC.VcooutputI2S=192000000 108 | VP_SYS_VS_Systick.Mode=SysTick 109 | VP_SYS_VS_Systick.Signal=SYS_VS_Systick 110 | board=custom 111 | -------------------------------------------------------------------------------- /CMakeLists.txt: -------------------------------------------------------------------------------- 1 | # STM32 Minimal CMake project for C/C++ projects 2 | cmake_minimum_required(VERSION 3.12) 3 | ############################################################################### 4 | 5 | include(./gcc-arm-none-eabi.cmake) 6 | 7 | # Set debug mode as default 8 | if ("${CMAKE_BUILD_TYPE}" STREQUAL "") 9 | set(CMAKE_BUILD_TYPE debug) 10 | endif() 11 | message("Build type: ${CMAKE_BUILD_TYPE}") 12 | 13 | # Set project name and some defaults 14 | if ("${PROJECT_NAME}" STREQUAL "") 15 | set(PROJECT_NAME firmware) 16 | endif() 17 | if ("${PROJECT_VERSION}" STREQUAL "") 18 | set(PROJECT_VERSION 1.0) 19 | endif() 20 | 21 | project("${PROJECT_NAME}-${CMAKE_BUILD_TYPE}-${PROJECT_VERSION}") 22 | set(EXECUTABLE ${CMAKE_PROJECT_NAME}) 23 | 24 | set(CMAKE_EXPORT_COMPILE_COMMANDS ON) 25 | 26 | # Set microcontroller information 27 | set(MCU_FAMILY STM32F4xx) 28 | set(MCU_MODEL STM32F407xx) 29 | set(CPU_PARAMETERS 30 | -mcpu=cortex-m4 31 | -mthumb 32 | -mfpu=fpv4-sp-d16 33 | -mfloat-abi=hard) 34 | 35 | set(STARTUP_SCRIPT ${CMAKE_CURRENT_SOURCE_DIR}/CubeMX/startup_stm32f407xx.s) 36 | set(MCU_LINKER_SCRIPT ${CMAKE_CURRENT_SOURCE_DIR}/CubeMX/STM32F407VGTx_FLASH.ld) 37 | 38 | ############################################################################### 39 | enable_language(C CXX ASM) 40 | set(CMAKE_C_STANDARD 11) 41 | set(CMAKE_C_STANDARD_REQUIRED ON) 42 | set(CMAKE_C_EXTENSIONS ON) 43 | set(CMAKE_CXX_STANDARD 20) 44 | set(CMAKE_CXX_STANDARD_REQUIRED ON) 45 | set(CMAKE_CXX_STANDARD_INCLUDE_DIRECTORIES ${CMAKE_CXX_IMPLICIT_INCLUDE_DIRECTORIES}) 46 | set(CMAKE_CXX_EXTENSIONS ON) 47 | 48 | ############################################################################### 49 | set(STM32CUBEMX_INCLUDE_DIRECTORIES 50 | ${CMAKE_CURRENT_SOURCE_DIR}/Core/Inc 51 | ${CMAKE_CURRENT_SOURCE_DIR}/Drivers/${MCU_FAMILY}_HAL_Driver/Inc 52 | ${CMAKE_CURRENT_SOURCE_DIR}/Drivers/${MCU_FAMILY}_HAL_Driver/Inc/Legacy 53 | ${CMAKE_CURRENT_SOURCE_DIR}/Drivers/CMSIS/Device/ST/${MCU_FAMILY}/Include 54 | ${CMAKE_CURRENT_SOURCE_DIR}/Drivers/CMSIS/Include) 55 | 56 | set(PROJECT_INCLUDE_DIRECTORIES ${CMAKE_CURRENT_SOURCE_DIR}) 57 | 58 | file(GLOB_RECURSE STM32CUBEMX_SOURCES CONFIGURE_DEPENDS 59 | ${CMAKE_CURRENT_SOURCE_DIR}/Core/*.c 60 | ${CMAKE_CURRENT_SOURCE_DIR}/Drivers/*.c) 61 | 62 | set(PROJECT_DIR ${CMAKE_CURRENT_SOURCE_DIR}/Project) 63 | file(GLOB_RECURSE PROJECT_SOURCES CONFIGURE_DEPENDS 64 | ${PROJECT_DIR}/*.cpp 65 | ${PROJECT_DIR}/*.c) 66 | 67 | add_executable(${EXECUTABLE} 68 | ${STM32CUBEMX_SOURCES} 69 | ${PROJECT_SOURCES} 70 | ${STARTUP_SCRIPT}) 71 | 72 | target_compile_definitions(${EXECUTABLE} PRIVATE 73 | #$<$:DEBUG> 74 | ${MCU_MODEL} 75 | USE_HAL_DRIVER) 76 | 77 | target_include_directories(${EXECUTABLE} SYSTEM PRIVATE 78 | ${STM32CUBEMX_INCLUDE_DIRECTORIES}) 79 | 80 | target_include_directories(${EXECUTABLE} PRIVATE 81 | ${PROJECT_INCLUDE_DIRECTORIES}) 82 | 83 | ############################################################################### 84 | target_compile_options(${EXECUTABLE} PRIVATE 85 | ${CPU_PARAMETERS} 86 | -Wall 87 | -Wextra 88 | -Wpedantic 89 | -Wshadow 90 | -Wdouble-promotion 91 | -Wformat=2 -Wformat-truncation 92 | -Wundef 93 | -fno-common 94 | -Wno-unused-parameter 95 | $<$: 96 | -Wconversion 97 | -Wno-volatile 98 | -Wold-style-cast 99 | -Wuseless-cast 100 | -Wsuggest-override> 101 | $<$:-Og -g3 -ggdb> 102 | $<$:-Og -g0>) 103 | 104 | target_link_options(${EXECUTABLE} PRIVATE 105 | -T${MCU_LINKER_SCRIPT} 106 | ${CPU_PARAMETERS} 107 | -Wl,-Map=${CMAKE_PROJECT_NAME}.map 108 | $<$,10.3.1>:-Wl,--no-warn-rwx-segments> 109 | -Wl,--start-group 110 | -lc 111 | -lm 112 | -lstdc++ 113 | -Wl,--end-group 114 | -Wl,--print-memory-usage) 115 | 116 | ############################################################################### 117 | # The last command can take a couple of seconds on larger project, usefull for debugging 118 | add_custom_command( 119 | TARGET 120 | ${EXECUTABLE} 121 | POST_BUILD 122 | COMMAND ${CMAKE_SIZE} $ 123 | COMMAND ${CMAKE_OBJCOPY} -O ihex $ ${EXECUTABLE}.hex 124 | COMMAND ${CMAKE_OBJCOPY} -O binary $ ${EXECUTABLE}.bin 125 | COMMENT "Creating binaries." 126 | ) 127 | 128 | option(DUMP_ASM "Create full assembly of final executable" OFF) 129 | if (${DUMP_ASM}) 130 | add_custom_command(TARGET ${EXECUTABLE} POST_BUILD 131 | COMMAND ${CMAKE_OBJDUMP} -D -C $ > ${EXECUTABLE}.s) 132 | endif() 133 | 134 | -------------------------------------------------------------------------------- /docs/build-container.md: -------------------------------------------------------------------------------- 1 | # Building STM32 project with Container 2 | 3 | For reproducible development environment use the provided [container](../Dockerfile). It installs a specific (as the time of writing 10.3.0 is the latest) gcc-arm-embedded toolchain from ARMs website, which guarantees the same version every time. Other (less version critical) packages are installed via distribution package manager. Appropriate distribution is chosen, which holds packages with at least minimum required version in the repositories. 4 | 5 | --- 6 | Pros: 7 | 8 | * Minimal dependencies, only container tool and possibly `make` or `-compose`. 9 | * Low host system pollution. 10 | * Cross platform and cross distribution (except with podman). 11 | 12 | Cons: 13 | 14 | * Since all dependencies and tools are installed in the container, IDEs will not be able to find the system libraries. 15 | 16 | Verdict: 17 | 18 | * For the reason above I recommend this method for creating release in collaborative and solo projects. 19 | 20 | --- 21 | 22 | ## Dependencies 23 | 24 | Install `docker` or `podman` (linux only). Docker desktop will also install some tools, like `docker-compose`. You can also install `gnumake` if you want to use the same [Makefile](Makefile) for building and deploying the container. 25 | 26 | ## With Makefile 27 | 28 | The following additional targets for container are available: 29 | 30 | `make build-container`: (build) the container image, run container to build project using container. 31 | `make image`: (re)build the container image. 32 | `make shell`: run container and connect to shell, exit with `Ctrl+D` or `exit` command. 33 | `make clean-image`: remove container and image. 34 | `make clean-all`: remove build folder, remove container, remove image. 35 | 36 | Default container manager is [docker](https://www.docker.com/). Everything is also compatible with [podman](https://podman.io/) as the syntax is mostly the same. You can read on the differences between the two [here](https://phoenixnap.com/kb/podman-vs-docker). 37 | 38 | Run ` container prune` and enter `y` to remove any leftover containers (incorrectly closed or removed). 39 | 40 | ## With compose 41 | 42 | There is also a `docker-compose.yml`, which you can use if you don't have(want) `gnumake` installed, but you will need `docker-compose`. Docker for windows already installs it. 43 | 44 | First build the image: 45 | 46 | ```shell 47 | docker-compose build --build-arg UID=$(id -u) --build-arg GID=$(id -g) --build-arg USERNAME=$(id -un) --build-arg GROUPNAME=$(id -gn) container 48 | ``` 49 | 50 | On windows replace GROUPNAME parameter with username `GROUPNAME=$(id -un)`. 51 | 52 | There are several services for the `docker-compose`, which are analog to Makefile targets: 53 | 54 | `docker-compose run stmbuild`: build the project 55 | `docker-compose run stmrebuild`: rebuild the project 56 | `docker-compose run stmclean`: clean the project 57 | `docker-compose run shell`: connect to container shell 58 | 59 | Run `docker-compose down` after you're done to remove containers. 60 | 61 | **NOTE:** Syntax for `podman-compose` is similar to `docker-compose`, but as of now I'm having problems running the services with `podman-compose`. Looks like permissions thing. 62 | 63 | ## With just the container 64 | 65 | First build the image: 66 | 67 | ```shell 68 | docker build -t fedora-arm-embedded-dev --build-arg UID=`id -u` --build-arg GID=`id -g` --build-arg USERNAME=`id -un` --build-arg GROUPNAME=`id -gn` . 69 | ``` 70 | 71 | On windows replace GROUPNAME parameter with username `GROUPNAME=$(id -un)`. 72 | 73 | Build the project: 74 | 75 | ```shell 76 | # Linux 77 | docker run --rm -it -v "$(pwd):/workdir" -w/workdir fedora-arm-embedded-dev bash -lc "make -j8" 78 | 79 | # Windows 80 | winpty docker run --rm -it -v "/$(pwd -W):/workdir" -w//workdir fedora-arm-embedded-dev bash -lc "make -j8" 81 | 82 | ``` 83 | 84 | Clean project: 85 | 86 | ```shell 87 | # Linux 88 | docker run --rm -it -v "$(pwd):/workdir" -w/workdir fedora-arm-embedded-dev bash -lc "make clean" 89 | 90 | # Windows 91 | winpty docker run --rm -it -v "/$(pwd -W):/workdir" -w//workdir fedora-arm-embedded-dev bash -lc "make clean" 92 | ``` 93 | 94 | Connect to a container shell: 95 | 96 | ```shell 97 | # Linux 98 | docker run --rm -it -v "$(pwd):/workdir" -w/workdir fedora-arm-embedded-dev bash -l 99 | 100 | # Windows 101 | winpty docker run --rm -it -v "/$(pwd -W):/workdir" -w//workdir fedora-arm-embedded-dev bash -l 102 | ``` 103 | 104 | If you're using `podman`, then you also have to provide a few more arguments to **run** commands: `--userns=keep-id --security-opt label=disable`. 105 | 106 | Tested with docker (`20.10.9`), podman (`3.4.3`), docker-compose (`1.29.2`) on Fedora 35. 107 | -------------------------------------------------------------------------------- /flake.nix: -------------------------------------------------------------------------------- 1 | { 2 | inputs = { 3 | nixpkgs.url = "github:nixos/nixpkgs/nixos-unstable"; 4 | jlink-pack.url = "github:prtzl/jlink-nix"; 5 | flake-utils.url = "github:numtide/flake-utils"; 6 | }; 7 | 8 | outputs = inputs: 9 | inputs.flake-utils.lib.eachDefaultSystem (system: 10 | let 11 | pkgs = inputs.nixpkgs.legacyPackages.${system}; 12 | stdenv = pkgs.stdenv; 13 | jlink = inputs.jlink-pack.defaultPackage.${system}.overrideAttrs 14 | (attrs: { meta.license = ""; }); 15 | 16 | shellExports = '' 17 | string=${ 18 | (builtins.concatStringsSep "/bin:" firmware.debug.buildInputs) 19 | + "/bin" 20 | } 21 | export PATH=''${string}:$PATH 22 | buildir=''${1:-build} 23 | ''; 24 | 25 | meson = pkgs.writeShellScriptBin "meson" '' 26 | ${shellExports} 27 | cat meson_options.txt 28 | meson setup --cross-file=./gcc-arm-none-eabi.meson --cross-file=./stm32f4.meson -Dproject_name="${ 29 | (firmware.debug).pname 30 | }" -Dbuildtype="${(firmware.debug).buildtype}" "$buildir" 31 | ''; 32 | 33 | cmake = pkgs.writeShellScriptBin "cmake" '' 34 | ${shellExports} 35 | cmake -B$buildir -DPROJECT_NAME="${ 36 | (firmware.debug).pname 37 | }" -DPROJECT_VERSION="${ 38 | (firmware.debug).version 39 | }" -DCMAKE_BUILD_TYPE="${(firmware.debug).buildtype}" 40 | ''; 41 | 42 | mkFirmware = { buildtype }: 43 | pkgs.callPackage ./default.nix { inherit buildtype; }; 44 | firmware.debug = mkFirmware { buildtype = "debug"; }; 45 | firmware.release = mkFirmware { buildtype = "release"; }; 46 | 47 | mkFlashStlink = fw: 48 | pkgs.writeShellApplication { 49 | name = "flash-stlink-${fw.buildtype}"; 50 | text = 51 | "st-flash --reset write ${fw}/bin/${fw.binary}.bin 0x08000000"; 52 | runtimeInputs = [ pkgs.stlink ]; 53 | }; 54 | 55 | jlink-script = fw: 56 | pkgs.writeTextFile { 57 | name = "jlink-script-${fw.buildtype}"; 58 | text = '' 59 | device ${fw.device} 60 | si 1 61 | speed 4000 62 | loadfile ${fw}/bin/${fw.binary},0x08000000 63 | r 64 | g 65 | qc 66 | ''; 67 | }; 68 | 69 | mkFlashJlink = fw: 70 | pkgs.writeShellApplication { 71 | name = "flash-jlink-${fw.buildtype}"; 72 | text = "JLinkExe -commanderscript ${jlink-script fw}"; 73 | runtimeInputs = [ jlink ]; 74 | }; 75 | 76 | mkProject = fw: mkFlash: 77 | pkgs.symlinkJoin { 78 | name = "project-output"; 79 | paths = [ fw (mkFlash fw) ]; 80 | meta.mainProgram = "${(mkFlash fw).name}"; 81 | }; 82 | 83 | debug-jlink = pkgs.writeShellScriptBin "debug" '' 84 | ${shellExports} 85 | exe=${firmware.debug}/bin/${firmware.debug.executable} 86 | if [ -z "$exe" ]; then 87 | echo "Provide executable path to .elf" 88 | exit 1 89 | fi 90 | 91 | JLinkGDBServerCLExe \ 92 | -device STM32F407VG \ 93 | -if SWD \ 94 | -speed 4000 \ 95 | -port 2331 > jlink.log 2>&1 & 96 | 97 | JLINK_PID=$! 98 | 99 | # Kill J-Link server when script exits 100 | trap 'kill $JLINK_PID' EXIT 101 | 102 | # Give the server a moment to start 103 | sleep 1 104 | 105 | # Start GDB interactively and run commands 106 | arm-none-eabi-gdb $exe \ 107 | -ex "layout next" \ 108 | -ex "layout next" \ 109 | -ex "target remote localhost:2331" \ 110 | -ex "load" \ 111 | -ex "break main" \ 112 | -ex "continue" 113 | ''; 114 | in { 115 | packages = rec { 116 | inherit meson cmake; 117 | default = debug; 118 | debug = mkProject firmware.debug mkFlashJlink; 119 | release = mkProject firmware.release mkFlashJlink; 120 | debugst = mkProject firmware.debug mkFlashStlink; 121 | releasest = mkProject firmware.release mkFlashStlink; 122 | debugger = pkgs.symlinkJoin { 123 | name = "debug"; 124 | paths = [ debug-jlink firmware.debug ]; 125 | meta.mainProgram = "${debug-jlink.name}"; 126 | }; 127 | }; 128 | 129 | devShell = pkgs.mkShellNoCC { 130 | nativeBuildInputs = (firmware.debug.buildInputs or [ ]) ++ [ 131 | pkgs.clang-tools 132 | jlink 133 | pkgs.stlink 134 | pkgs.dos2unix 135 | pkgs.glibc_multi 136 | pkgs.clang 137 | ]; 138 | }; 139 | }); 140 | } 141 | -------------------------------------------------------------------------------- /meson.build: -------------------------------------------------------------------------------- 1 | project('firmware', ['c', 'cpp'], version : files('VERSION'), meson_version: '>=1.4.0') 2 | 3 | ## STM32 platform vars 4 | stm32_family = 'STM32F4xx' 5 | stm32_model = 'STM32F407xx' 6 | stm32_fpu = 'fpv4-sp-d16' 7 | 8 | ## STM32 sources and headers 9 | # This allows checking if file exists - throws if not 10 | # I could also implement this where used, but since it throws here, looks better? 11 | startupfile = files('CubeMX/startup_stm32f407xx.s')[0] 12 | linkfile = files('CubeMX/STM32F407VGTx_FLASH.ld')[0] 13 | 14 | # Default (usually STM32 core directories) 15 | stm32cube_incdirs = [] 16 | stm32cube_incdirs += include_directories('Drivers/CMSIS/Device/ST/@0@/Include'.format(stm32_family), is_system : true) 17 | stm32cube_incdirs += include_directories('Drivers/@0@_HAL_Driver/Inc'.format(stm32_family), is_system : true) 18 | stm32cube_incdirs += include_directories('Drivers/@0@_HAL_Driver/Inc/Legacy'.format(stm32_family), is_system : true) 19 | stm32cube_incdirs += include_directories('Drivers/CMSIS/Include', is_system : true) 20 | stm32cube_incdirs += include_directories('Drivers', is_system : true) 21 | stm32cube_incdirs += include_directories('Core/Inc', is_system : true) 22 | 23 | # Project include directories 24 | incdirs = [] 25 | incdirs += ['Project'] 26 | 27 | # Project sources - we'll use glob for our project 28 | srcs = [] 29 | srcs += startupfile 30 | 31 | # Glob is not evil, just re-invoke meson (or add file to the list, same amount of work to me :P) 32 | glob = run_command('glob.sh', check : true).stdout().strip().split('\n') 33 | srcs += glob 34 | 35 | ########################### GOIN TO WORK ? #################################### 36 | 37 | assert(meson.get_compiler('c').get_id() == 'gcc') 38 | 39 | ## Compiler options 40 | # CPU 41 | c_args = [] 42 | c_args += '-mcpu=@0@'.format(host_machine.cpu()) 43 | if stm32_fpu != '' 44 | c_args += '-mfpu=@0@'.format(stm32_fpu) 45 | c_args += '-mfloat-abi=hard' 46 | else 47 | c_args += '-mfloat-abi=soft' 48 | endif 49 | 50 | # Defines 51 | c_args += '-D@0@'.format(stm32_model) 52 | c_args += '-DUSE_HAL_DRIVER' 53 | 54 | # Build optimization 55 | build_type = get_option('buildtype') 56 | # Meson will still place -O0 and -g with debug, this overrides 57 | if build_type == 'debug' 58 | c_args += '-Og' 59 | c_args += '-g3' 60 | c_args += '-ggdb' 61 | # Meson will still place -O3 , this overrides 62 | elif build_type == 'release' 63 | c_args += '-Og' 64 | c_args += '-g0' 65 | endif 66 | 67 | c_args += '-Wall' 68 | c_args += '-Wextra' 69 | c_args += '-Wpedantic' 70 | c_args += '-Wshadow' 71 | c_args += '-Wdouble-promotion' 72 | c_args += '-Wformat=2' 73 | c_args += '-Wformat-truncation' 74 | c_args += '-Wundef' 75 | c_args += '-fno-common' 76 | c_args += '-Wno-unused-parameter' 77 | c_args += '-fdiagnostics-color=always' 78 | 79 | cpp_args = [] 80 | cpp_args += c_args 81 | cpp_args += '-Wconversion' 82 | cpp_args += '-Wno-volatile' 83 | cpp_args += '-Wold-style-cast' 84 | cpp_args += '-Wuseless-cast' 85 | cpp_args += '-Wsuggest-override' 86 | 87 | ## Linker options 88 | link_args = [] 89 | link_args += c_args 90 | link_args += '-Wl,-Map=main.map ' 91 | link_args += '-Wl,--print-memory-usage' 92 | # So, linker wants a full path to the file 93 | linkfilepath = linkfile.full_path() 94 | link_args += '-T' + linkfilepath 95 | 96 | if meson.get_compiler('c').version() > '10.3.1' 97 | link_args += '-Wl,--no-warn-rwx-segments' 98 | endif 99 | 100 | ## Output targets 101 | 102 | # This is also how NIX names the derivation, aka, firmware 103 | pname = meson.project_name() + '-' + get_option('buildtype') + '-' + meson.project_version() 104 | pexe = pname + '.elf' 105 | pbin = pname + '.bin' 106 | phex = pname + '.hex' 107 | psize = pname + '.size' 108 | pdump = pname + '.s' 109 | 110 | # Main target 111 | main = executable( 112 | pname, 113 | [srcs], 114 | name_suffix : 'elf', 115 | c_args : [c_args, '-std=c11'], 116 | cpp_args : [cpp_args, '-std=c++20'], 117 | link_args : link_args, 118 | dependencies : [], 119 | include_directories : [incdirs, stm32cube_incdirs]) 120 | 121 | # Post-build targets 122 | objcopy = find_program('objcopy').full_path() 123 | objdump = find_program('objdump').full_path() 124 | size = find_program('size').full_path() 125 | 126 | # binary 127 | mainbin = custom_target( 128 | pbin, 129 | output : [pbin], 130 | build_by_default : true, 131 | command : [objcopy, '-O', 'binary', pexe, pbin], 132 | depends : [main]) 133 | 134 | # hex 135 | mainbin = custom_target( 136 | phex, 137 | output : [phex], 138 | build_by_default : true, 139 | command : [objcopy, '-O', 'ihex', pexe, phex], 140 | depends : [main]) 141 | 142 | # Size output 143 | # text = all RO segments (.text, .isr_vector, .rodata, .ARM) 144 | # data = all RW segments (.data) 145 | # .bss = all runtime RW segemnts (.bss, .heap) 146 | mainsize = custom_target( 147 | 'size', 148 | capture : false, 149 | output : [psize], 150 | build_by_default : true, 151 | command : [size, '--format=berkely', pexe], 152 | depends : [main]) 153 | 154 | # objdump 155 | maindump = custom_target( 156 | 'dump', 157 | capture : true, 158 | output : pdump, 159 | build_by_default : false, 160 | command : [objdump, '-D', '-S', '-t', pexe], 161 | depends : [main]) 162 | -------------------------------------------------------------------------------- /docs/code-tips.md: -------------------------------------------------------------------------------- 1 | # Code tips 2 | 3 | This document includes various tips and options for writing and debugging code. Some of the entries are less used tools, that might be annoying to google every time I need them. This document is a common place for those as well. 4 | 5 | ## Pragmas 6 | 7 | `#pragma` is a directive specifying extra information to the compiler. With it you can print debug messages, change compilation warnings and optimizations and much more. 8 | 9 | You might be familiar with `pragma once`, which lets the compiler know to only read the file once. It is usually found on top of header files. This is so called "un-official" replacement for include guard for preventing the same header file to be included multiple times. 10 | 11 | ```c 12 | // header file 13 | #ifndef HEADER_FILE_H 14 | #define HEADER_FILE_H 15 | 16 | // contents of header file 17 | 18 | #endif 19 | ``` 20 | 21 | The old method requires that the programmer does provide a unique macro for each header file. Pragma on the other hand is trivial. 22 | 23 | Include errors, resulting in some form of re-definition, is caused by the header being included by other header files, which are then in turn included in a source file - thus multiple inclusions of the same header file. 24 | 25 | `#pragma` in itself is part of the C and C++ standard, but `#pragma once` is part of the compiler implementation, therefore it is not as universal as `#ifndef` include guards, which are based on the preprocessor standard. Still it is widely adopted in most modern compilers. 26 | 27 | The syntax for a pragma might look something like this: 28 | 29 | ```c 30 | #pragma PREFIX option value(s) 31 | ``` 32 | 33 | Pragma can source its rules and options from various packages. Those defined by the standard use a prefix `STDC`, while those used by GNU use `GCC` prefix. 34 | 35 | ### Option stacking 36 | 37 | It is important to note, that a pragma directive applies for the whole file from that point. Everything before it is unaffected. This is why, when applying certain options just for a small section, it is useful to save current options and restore them back after the said section. 38 | 39 | This is why you should use `push` and `pop` options before and after applying a pragma. Push and pop can be used as a value to an option or as part of the option as well. Here are a few examples 40 | 41 | ```c 42 | #pragma GCC diagnostic push 43 | #pragma GCC diagnostic error "-Wformat" // treat this warning as error 44 | 45 | // section affected by 46 | void foo() 47 | { 48 | ... 49 | } 50 | 51 | #pragma GCC diagnostic pop 52 | ``` 53 | 54 | ```c 55 | #define MACRO 1 56 | #pragma GCC push_macro("MACRO") // save MACRO value to stack 57 | #undef MACRO // undefine macro MACRO 58 | 59 | // section affected by 60 | void foo() 61 | { 62 | ... 63 | } 64 | 65 | #pragma GCC pop_macro("MACRO") // pop value of macro MACRO back 66 | ``` 67 | 68 | ## Code optimization 69 | 70 | For most scenarios, I stand by a rule to use the same optimization options for both `Debug` and `Release` builds. This prevents unnecessary errors and code breakage when switching builds types, where optimizer might do a too-good job and it ends up breaking the executable. Remember, build type is not just about optimization level. 71 | 72 | For my builds, as well as this template, I use option `Og` for `gcc` compiler. This is, by my estimations, the best compromise between optimized code and debug-ability. However it still isn't perfect. While it does prevent inlining of regular functions, some lambdas and trivial class methods do get inlined. Sometimes whole `if-else` blocks get optimized to a point, that you cannot put a breakpoint anywhere useful. Even if you do, some variables might get optimized and debugger will not be able to give you any information on their value. 73 | 74 | You can change the level of optimization for a whole section of functions with a pragma. 75 | 76 | ```c 77 | #pragma GCC push_options // save current compiler options 78 | #pragma GCC optimize ("-O0") // set optimization level to zero 79 | 80 | void foo(int a) 81 | { 82 | int cpy = a; 83 | return cpy + 5; 84 | } 85 | 86 | #pragma GCC pop_options // restore saved compiler options 87 | ``` 88 | 89 | In the example above, such trivial function might get optimized away. If not, stepping through it might prove useless, as variable `cpy` might get optimized so that debugger cannot see its value. Setting optimization level to zero disables any funny business from the compiler and forces it to generate expected instructions. 90 | 91 | ## System headers and warnings 92 | 93 | While inspecting compiler output when building your project, you might find that some header file paths include `-isystem` option right before. Also, in my CMake project template, I call `target_include_directories` twice. One includes `CubeMX` drivers only and has an extra `SYSTEM` option, while other includes all user generated code without the extra option. This `SYSTEM` options generates `-isystem` argument for the compiler before giving it a include path. What's up with that? 94 | 95 | In short, system paths are already pre-determined by the compiler and it's the reason, why you can just `#include ` and the compiler will find the file. It has a set of system paths where it will look for the library first. But there is more. 96 | Because such libraries might be old and/or cross platform, some *harmless* errors might be produced. If you were to use them on your project, you might get tons and tons of useless errors coming from the library and not your code. This is why system libraries get special treatment. This is why **ALL** warnings, other then `#warning` *ARE IGNORED*. 97 | 98 | The case of vendor provided libraries is much the same. They might not be developed with such strict error checking as your project; which I advise. C++ warnings regarding casting `-Wuseless-cast` and `-Wold-style-cast` dominate the warning output (try removing `SYSTEM` from include directory for CubeMX and see the output). Specifying CubeMX headers as system clears them of useless errors and allows us to use strict error checking on user code without affecting system libraries. 99 | -------------------------------------------------------------------------------- /Core/Src/main.c: -------------------------------------------------------------------------------- 1 | /* USER CODE BEGIN Header */ 2 | /** 3 | ****************************************************************************** 4 | * @file : main.c 5 | * @brief : Main program body 6 | ****************************************************************************** 7 | * @attention 8 | * 9 | *

© Copyright (c) 2021 STMicroelectronics. 10 | * All rights reserved.

11 | * 12 | * This software component is licensed by ST under BSD 3-Clause license, 13 | * the "License"; You may not use this file except in compliance with the 14 | * License. You may obtain a copy of the License at: 15 | * opensource.org/licenses/BSD-3-Clause 16 | * 17 | ****************************************************************************** 18 | */ 19 | /* USER CODE END Header */ 20 | /* Includes ------------------------------------------------------------------*/ 21 | #include "main.h" 22 | #include "gpio.h" 23 | 24 | /* Private includes ----------------------------------------------------------*/ 25 | /* USER CODE BEGIN Includes */ 26 | #include 27 | /* USER CODE END Includes */ 28 | 29 | /* Private typedef -----------------------------------------------------------*/ 30 | /* USER CODE BEGIN PTD */ 31 | 32 | /* USER CODE END PTD */ 33 | 34 | /* Private define ------------------------------------------------------------*/ 35 | /* USER CODE BEGIN PD */ 36 | /* USER CODE END PD */ 37 | 38 | /* Private macro -------------------------------------------------------------*/ 39 | /* USER CODE BEGIN PM */ 40 | 41 | /* USER CODE END PM */ 42 | 43 | /* Private variables ---------------------------------------------------------*/ 44 | 45 | /* USER CODE BEGIN PV */ 46 | 47 | /* USER CODE END PV */ 48 | 49 | /* Private function prototypes -----------------------------------------------*/ 50 | void SystemClock_Config(void); 51 | /* USER CODE BEGIN PFP */ 52 | 53 | /* USER CODE END PFP */ 54 | 55 | /* Private user code ---------------------------------------------------------*/ 56 | /* USER CODE BEGIN 0 */ 57 | 58 | /* USER CODE END 0 */ 59 | 60 | /** 61 | * @brief The application entry point. 62 | * @retval int 63 | */ 64 | int main(void) 65 | { 66 | /* USER CODE BEGIN 1 */ 67 | 68 | /* USER CODE END 1 */ 69 | 70 | /* MCU Configuration--------------------------------------------------------*/ 71 | 72 | /* Reset of all peripherals, Initializes the Flash interface and the Systick. */ 73 | HAL_Init(); 74 | 75 | /* USER CODE BEGIN Init */ 76 | 77 | /* USER CODE END Init */ 78 | 79 | /* Configure the system clock */ 80 | SystemClock_Config(); 81 | 82 | /* USER CODE BEGIN SysInit */ 83 | 84 | /* USER CODE END SysInit */ 85 | 86 | /* Initialize all configured peripherals */ 87 | MX_GPIO_Init(); 88 | /* USER CODE BEGIN 2 */ 89 | projectMain(); 90 | /* USER CODE END 2 */ 91 | 92 | /* Infinite loop */ 93 | /* USER CODE BEGIN WHILE */ 94 | while (1) 95 | { 96 | /* USER CODE END WHILE */ 97 | 98 | /* USER CODE BEGIN 3 */ 99 | } 100 | /* USER CODE END 3 */ 101 | } 102 | 103 | /** 104 | * @brief System Clock Configuration 105 | * @retval None 106 | */ 107 | void SystemClock_Config(void) 108 | { 109 | RCC_OscInitTypeDef RCC_OscInitStruct = {0}; 110 | RCC_ClkInitTypeDef RCC_ClkInitStruct = {0}; 111 | 112 | /** Configure the main internal regulator output voltage 113 | */ 114 | __HAL_RCC_PWR_CLK_ENABLE(); 115 | __HAL_PWR_VOLTAGESCALING_CONFIG(PWR_REGULATOR_VOLTAGE_SCALE1); 116 | /** Initializes the RCC Oscillators according to the specified parameters 117 | * in the RCC_OscInitTypeDef structure. 118 | */ 119 | RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSE; 120 | RCC_OscInitStruct.HSEState = RCC_HSE_ON; 121 | RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON; 122 | RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE; 123 | RCC_OscInitStruct.PLL.PLLM = 4; 124 | RCC_OscInitStruct.PLL.PLLN = 168; 125 | RCC_OscInitStruct.PLL.PLLP = RCC_PLLP_DIV2; 126 | RCC_OscInitStruct.PLL.PLLQ = 4; 127 | if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK) 128 | { 129 | Error_Handler(); 130 | } 131 | /** Initializes the CPU, AHB and APB buses clocks 132 | */ 133 | RCC_ClkInitStruct.ClockType = 134 | RCC_CLOCKTYPE_HCLK | RCC_CLOCKTYPE_SYSCLK | RCC_CLOCKTYPE_PCLK1 | RCC_CLOCKTYPE_PCLK2; 135 | RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK; 136 | RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1; 137 | RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV4; 138 | RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV4; 139 | 140 | if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_5) != HAL_OK) 141 | { 142 | Error_Handler(); 143 | } 144 | } 145 | 146 | /* USER CODE BEGIN 4 */ 147 | 148 | /* USER CODE END 4 */ 149 | 150 | /** 151 | * @brief This function is executed in case of error occurrence. 152 | * @retval None 153 | */ 154 | void Error_Handler(void) 155 | { 156 | /* USER CODE BEGIN Error_Handler_Debug */ 157 | /* User can add his own implementation to report the HAL error return state */ 158 | __disable_irq(); 159 | while (1) 160 | { 161 | } 162 | /* USER CODE END Error_Handler_Debug */ 163 | } 164 | 165 | #ifdef USE_FULL_ASSERT 166 | /** 167 | * @brief Reports the name of the source file and the source line number 168 | * where the assert_param error has occurred. 169 | * @param file: pointer to the source file name 170 | * @param line: assert_param error line source number 171 | * @retval None 172 | */ 173 | void assert_failed(uint8_t* file, uint32_t line) 174 | { 175 | /* USER CODE BEGIN 6 */ 176 | /* User can add his own implementation to report the file name and line number, 177 | ex: printf("Wrong parameters value: file %s on line %d\r\n", file, line) */ 178 | /* USER CODE END 6 */ 179 | } 180 | #endif /* USE_FULL_ASSERT */ 181 | 182 | /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ 183 | -------------------------------------------------------------------------------- /CubeMX/Makefile: -------------------------------------------------------------------------------- 1 | ########################################################################################################################## 2 | # File automatically-generated by tool: [projectgenerator] version: [3.13.0-B3] date: [Fri Dec 31 18:51:48 CET 2021] 3 | ########################################################################################################################## 4 | 5 | # ------------------------------------------------ 6 | # Generic Makefile (based on gcc) 7 | # 8 | # ChangeLog : 9 | # 2017-02-10 - Several enhancements + project update mode 10 | # 2015-07-22 - first version 11 | # ------------------------------------------------ 12 | 13 | ###################################### 14 | # target 15 | ###################################### 16 | TARGET = STM32-project-template 17 | 18 | 19 | ###################################### 20 | # building variables 21 | ###################################### 22 | # debug build? 23 | DEBUG = 1 24 | # optimization 25 | OPT = -Og 26 | 27 | 28 | ####################################### 29 | # paths 30 | ####################################### 31 | # Build path 32 | BUILD_DIR = build 33 | 34 | ###################################### 35 | # source 36 | ###################################### 37 | # C sources 38 | C_SOURCES = \ 39 | ../Core/Src/main.c \ 40 | ../Core/Src/gpio.c \ 41 | ../Core/Src/stm32f4xx_it.c \ 42 | ../Core/Src/stm32f4xx_hal_msp.c \ 43 | ../Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_tim.c \ 44 | ../Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_tim_ex.c \ 45 | ../Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_rcc.c \ 46 | ../Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_rcc_ex.c \ 47 | ../Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_flash.c \ 48 | ../Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_flash_ex.c \ 49 | ../Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_flash_ramfunc.c \ 50 | ../Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_gpio.c \ 51 | ../Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_dma_ex.c \ 52 | ../Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_dma.c \ 53 | ../Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_pwr.c \ 54 | ../Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_pwr_ex.c \ 55 | ../Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_cortex.c \ 56 | ../Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal.c \ 57 | ../Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_exti.c \ 58 | ../Core/Src/system_stm32f4xx.c 59 | 60 | # ASM sources 61 | ASM_SOURCES = \ 62 | startup_stm32f407xx.s 63 | 64 | 65 | ####################################### 66 | # binaries 67 | ####################################### 68 | PREFIX = arm-none-eabi- 69 | # The gcc compiler bin path can be either defined in make command via GCC_PATH variable (> make GCC_PATH=xxx) 70 | # either it can be added to the PATH environment variable. 71 | ifdef GCC_PATH 72 | CC = $(GCC_PATH)/$(PREFIX)gcc 73 | AS = $(GCC_PATH)/$(PREFIX)gcc -x assembler-with-cpp 74 | CP = $(GCC_PATH)/$(PREFIX)objcopy 75 | SZ = $(GCC_PATH)/$(PREFIX)size 76 | else 77 | CC = $(PREFIX)gcc 78 | AS = $(PREFIX)gcc -x assembler-with-cpp 79 | CP = $(PREFIX)objcopy 80 | SZ = $(PREFIX)size 81 | endif 82 | HEX = $(CP) -O ihex 83 | BIN = $(CP) -O binary -S 84 | 85 | ####################################### 86 | # CFLAGS 87 | ####################################### 88 | # cpu 89 | CPU = -mcpu=cortex-m4 90 | 91 | # fpu 92 | FPU = -mfpu=fpv4-sp-d16 93 | 94 | # float-abi 95 | FLOAT-ABI = -mfloat-abi=hard 96 | 97 | # mcu 98 | MCU = $(CPU) -mthumb $(FPU) $(FLOAT-ABI) 99 | 100 | # macros for gcc 101 | # AS defines 102 | AS_DEFS = 103 | 104 | # C defines 105 | C_DEFS = \ 106 | -DUSE_HAL_DRIVER \ 107 | -DSTM32F407xx 108 | 109 | 110 | # AS includes 111 | AS_INCLUDES = 112 | 113 | # C includes 114 | C_INCLUDES = \ 115 | -I../Core/Inc \ 116 | -I../Drivers/STM32F4xx_HAL_Driver/Inc \ 117 | -I../Drivers/STM32F4xx_HAL_Driver/Inc/Legacy \ 118 | -I../Drivers/CMSIS/Device/ST/STM32F4xx/Include \ 119 | -I../Drivers/CMSIS/Include 120 | 121 | 122 | # compile gcc flags 123 | ASFLAGS = $(MCU) $(AS_DEFS) $(AS_INCLUDES) $(OPT) -Wall -fdata-sections -ffunction-sections 124 | 125 | CFLAGS = $(MCU) $(C_DEFS) $(C_INCLUDES) $(OPT) -Wall -fdata-sections -ffunction-sections 126 | 127 | ifeq ($(DEBUG), 1) 128 | CFLAGS += -g -gdwarf-2 129 | endif 130 | 131 | 132 | # Generate dependency information 133 | CFLAGS += -MMD -MP -MF"$(@:%.o=%.d)" 134 | 135 | 136 | ####################################### 137 | # LDFLAGS 138 | ####################################### 139 | # link script 140 | LDSCRIPT = STM32F407VGTx_FLASH.ld 141 | 142 | # libraries 143 | LIBS = -lc -lm -lnosys 144 | LIBDIR = 145 | LDFLAGS = $(MCU) -specs=nano.specs -T$(LDSCRIPT) $(LIBDIR) $(LIBS) -Wl,-Map=$(BUILD_DIR)/$(TARGET).map,--cref -Wl,--gc-sections 146 | 147 | # default action: build all 148 | all: $(BUILD_DIR)/$(TARGET).elf $(BUILD_DIR)/$(TARGET).hex $(BUILD_DIR)/$(TARGET).bin 149 | 150 | 151 | ####################################### 152 | # build the application 153 | ####################################### 154 | # list of objects 155 | OBJECTS = $(addprefix $(BUILD_DIR)/,$(notdir $(C_SOURCES:.c=.o))) 156 | vpath %.c $(sort $(dir $(C_SOURCES))) 157 | # list of ASM program objects 158 | OBJECTS += $(addprefix $(BUILD_DIR)/,$(notdir $(ASM_SOURCES:.s=.o))) 159 | vpath %.s $(sort $(dir $(ASM_SOURCES))) 160 | 161 | $(BUILD_DIR)/%.o: %.c Makefile | $(BUILD_DIR) 162 | $(CC) -c $(CFLAGS) -Wa,-a,-ad,-alms=$(BUILD_DIR)/$(notdir $(<:.c=.lst)) $< -o $@ 163 | 164 | $(BUILD_DIR)/%.o: %.s Makefile | $(BUILD_DIR) 165 | $(AS) -c $(CFLAGS) $< -o $@ 166 | 167 | $(BUILD_DIR)/$(TARGET).elf: $(OBJECTS) Makefile 168 | $(CC) $(OBJECTS) $(LDFLAGS) -o $@ 169 | $(SZ) $@ 170 | 171 | $(BUILD_DIR)/%.hex: $(BUILD_DIR)/%.elf | $(BUILD_DIR) 172 | $(HEX) $< $@ 173 | 174 | $(BUILD_DIR)/%.bin: $(BUILD_DIR)/%.elf | $(BUILD_DIR) 175 | $(BIN) $< $@ 176 | 177 | $(BUILD_DIR): 178 | mkdir $@ 179 | 180 | ####################################### 181 | # clean up 182 | ####################################### 183 | clean: 184 | -rm -fR $(BUILD_DIR) 185 | 186 | ####################################### 187 | # dependencies 188 | ####################################### 189 | -include $(wildcard $(BUILD_DIR)/*.d) 190 | 191 | # *** EOF *** -------------------------------------------------------------------------------- /Core/Src/stm32f4xx_it.c: -------------------------------------------------------------------------------- 1 | /* USER CODE BEGIN Header */ 2 | /** 3 | ****************************************************************************** 4 | * @file stm32f4xx_it.c 5 | * @brief Interrupt Service Routines. 6 | ****************************************************************************** 7 | * @attention 8 | * 9 | *

© Copyright (c) 2021 STMicroelectronics. 10 | * All rights reserved.

11 | * 12 | * This software component is licensed by ST under BSD 3-Clause license, 13 | * the "License"; You may not use this file except in compliance with the 14 | * License. You may obtain a copy of the License at: 15 | * opensource.org/licenses/BSD-3-Clause 16 | * 17 | ****************************************************************************** 18 | */ 19 | /* USER CODE END Header */ 20 | 21 | /* Includes ------------------------------------------------------------------*/ 22 | #include "stm32f4xx_it.h" 23 | #include "main.h" 24 | /* Private includes ----------------------------------------------------------*/ 25 | /* USER CODE BEGIN Includes */ 26 | /* USER CODE END Includes */ 27 | 28 | /* Private typedef -----------------------------------------------------------*/ 29 | /* USER CODE BEGIN TD */ 30 | 31 | /* USER CODE END TD */ 32 | 33 | /* Private define ------------------------------------------------------------*/ 34 | /* USER CODE BEGIN PD */ 35 | 36 | /* USER CODE END PD */ 37 | 38 | /* Private macro -------------------------------------------------------------*/ 39 | /* USER CODE BEGIN PM */ 40 | 41 | /* USER CODE END PM */ 42 | 43 | /* Private variables ---------------------------------------------------------*/ 44 | /* USER CODE BEGIN PV */ 45 | 46 | /* USER CODE END PV */ 47 | 48 | /* Private function prototypes -----------------------------------------------*/ 49 | /* USER CODE BEGIN PFP */ 50 | 51 | /* USER CODE END PFP */ 52 | 53 | /* Private user code ---------------------------------------------------------*/ 54 | /* USER CODE BEGIN 0 */ 55 | 56 | /* USER CODE END 0 */ 57 | 58 | /* External variables --------------------------------------------------------*/ 59 | 60 | /* USER CODE BEGIN EV */ 61 | 62 | /* USER CODE END EV */ 63 | 64 | /******************************************************************************/ 65 | /* Cortex-M4 Processor Interruption and Exception Handlers */ 66 | /******************************************************************************/ 67 | /** 68 | * @brief This function handles Non maskable interrupt. 69 | */ 70 | void NMI_Handler(void) 71 | { 72 | /* USER CODE BEGIN NonMaskableInt_IRQn 0 */ 73 | 74 | /* USER CODE END NonMaskableInt_IRQn 0 */ 75 | /* USER CODE BEGIN NonMaskableInt_IRQn 1 */ 76 | while (1) 77 | { 78 | } 79 | /* USER CODE END NonMaskableInt_IRQn 1 */ 80 | } 81 | 82 | /** 83 | * @brief This function handles Hard fault interrupt. 84 | */ 85 | void HardFault_Handler(void) 86 | { 87 | /* USER CODE BEGIN HardFault_IRQn 0 */ 88 | 89 | /* USER CODE END HardFault_IRQn 0 */ 90 | while (1) 91 | { 92 | /* USER CODE BEGIN W1_HardFault_IRQn 0 */ 93 | /* USER CODE END W1_HardFault_IRQn 0 */ 94 | } 95 | } 96 | 97 | /** 98 | * @brief This function handles Memory management fault. 99 | */ 100 | void MemManage_Handler(void) 101 | { 102 | /* USER CODE BEGIN MemoryManagement_IRQn 0 */ 103 | 104 | /* USER CODE END MemoryManagement_IRQn 0 */ 105 | while (1) 106 | { 107 | /* USER CODE BEGIN W1_MemoryManagement_IRQn 0 */ 108 | /* USER CODE END W1_MemoryManagement_IRQn 0 */ 109 | } 110 | } 111 | 112 | /** 113 | * @brief This function handles Pre-fetch fault, memory access fault. 114 | */ 115 | void BusFault_Handler(void) 116 | { 117 | /* USER CODE BEGIN BusFault_IRQn 0 */ 118 | 119 | /* USER CODE END BusFault_IRQn 0 */ 120 | while (1) 121 | { 122 | /* USER CODE BEGIN W1_BusFault_IRQn 0 */ 123 | /* USER CODE END W1_BusFault_IRQn 0 */ 124 | } 125 | } 126 | 127 | /** 128 | * @brief This function handles Undefined instruction or illegal state. 129 | */ 130 | void UsageFault_Handler(void) 131 | { 132 | /* USER CODE BEGIN UsageFault_IRQn 0 */ 133 | 134 | /* USER CODE END UsageFault_IRQn 0 */ 135 | while (1) 136 | { 137 | /* USER CODE BEGIN W1_UsageFault_IRQn 0 */ 138 | /* USER CODE END W1_UsageFault_IRQn 0 */ 139 | } 140 | } 141 | 142 | /** 143 | * @brief This function handles System service call via SWI instruction. 144 | */ 145 | void SVC_Handler(void) 146 | { 147 | /* USER CODE BEGIN SVCall_IRQn 0 */ 148 | 149 | /* USER CODE END SVCall_IRQn 0 */ 150 | /* USER CODE BEGIN SVCall_IRQn 1 */ 151 | 152 | /* USER CODE END SVCall_IRQn 1 */ 153 | } 154 | 155 | /** 156 | * @brief This function handles Debug monitor. 157 | */ 158 | void DebugMon_Handler(void) 159 | { 160 | /* USER CODE BEGIN DebugMonitor_IRQn 0 */ 161 | 162 | /* USER CODE END DebugMonitor_IRQn 0 */ 163 | /* USER CODE BEGIN DebugMonitor_IRQn 1 */ 164 | 165 | /* USER CODE END DebugMonitor_IRQn 1 */ 166 | } 167 | 168 | /** 169 | * @brief This function handles Pendable request for system service. 170 | */ 171 | void PendSV_Handler(void) 172 | { 173 | /* USER CODE BEGIN PendSV_IRQn 0 */ 174 | 175 | /* USER CODE END PendSV_IRQn 0 */ 176 | /* USER CODE BEGIN PendSV_IRQn 1 */ 177 | 178 | /* USER CODE END PendSV_IRQn 1 */ 179 | } 180 | 181 | /** 182 | * @brief This function handles System tick timer. 183 | */ 184 | void SysTick_Handler(void) 185 | { 186 | /* USER CODE BEGIN SysTick_IRQn 0 */ 187 | 188 | /* USER CODE END SysTick_IRQn 0 */ 189 | HAL_IncTick(); 190 | /* USER CODE BEGIN SysTick_IRQn 1 */ 191 | 192 | /* USER CODE END SysTick_IRQn 1 */ 193 | } 194 | 195 | /******************************************************************************/ 196 | /* STM32F4xx Peripheral Interrupt Handlers */ 197 | /* Add here the Interrupt Handlers for the used peripherals. */ 198 | /* For the available peripheral interrupt handler names, */ 199 | /* please refer to the startup file (startup_stm32f4xx.s). */ 200 | /******************************************************************************/ 201 | 202 | /* USER CODE BEGIN 1 */ 203 | 204 | /* USER CODE END 1 */ 205 | /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ 206 | -------------------------------------------------------------------------------- /Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_flash_ramfunc.c: -------------------------------------------------------------------------------- 1 | /** 2 | ****************************************************************************** 3 | * @file stm32f4xx_hal_flash_ramfunc.c 4 | * @author MCD Application Team 5 | * @brief FLASH RAMFUNC module driver. 6 | * This file provides a FLASH firmware functions which should be 7 | * executed from internal SRAM 8 | * + Stop/Start the flash interface while System Run 9 | * + Enable/Disable the flash sleep while System Run 10 | @verbatim 11 | ============================================================================== 12 | ##### APIs executed from Internal RAM ##### 13 | ============================================================================== 14 | [..] 15 | *** ARM Compiler *** 16 | -------------------- 17 | [..] RAM functions are defined using the toolchain options. 18 | Functions that are be executed in RAM should reside in a separate 19 | source module. Using the 'Options for File' dialog you can simply change 20 | the 'Code / Const' area of a module to a memory space in physical RAM. 21 | Available memory areas are declared in the 'Target' tab of the 22 | Options for Target' dialog. 23 | 24 | *** ICCARM Compiler *** 25 | ----------------------- 26 | [..] RAM functions are defined using a specific toolchain keyword "__ramfunc". 27 | 28 | *** GNU Compiler *** 29 | -------------------- 30 | [..] RAM functions are defined using a specific toolchain attribute 31 | "__attribute__((section(".RamFunc")))". 32 | 33 | @endverbatim 34 | ****************************************************************************** 35 | * @attention 36 | * 37 | *

© Copyright (c) 2017 STMicroelectronics. 38 | * All rights reserved.

39 | * 40 | * This software component is licensed by ST under BSD 3-Clause license, 41 | * the "License"; You may not use this file except in compliance with the 42 | * License. You may obtain a copy of the License at: 43 | * opensource.org/licenses/BSD-3-Clause 44 | * 45 | ****************************************************************************** 46 | */ 47 | 48 | /* Includes ------------------------------------------------------------------*/ 49 | #include "stm32f4xx_hal.h" 50 | 51 | /** @addtogroup STM32F4xx_HAL_Driver 52 | * @{ 53 | */ 54 | 55 | /** @defgroup FLASH_RAMFUNC FLASH RAMFUNC 56 | * @brief FLASH functions executed from RAM 57 | * @{ 58 | */ 59 | #ifdef HAL_FLASH_MODULE_ENABLED 60 | #if defined(STM32F410Tx) || defined(STM32F410Cx) || defined(STM32F410Rx) \ 61 | || defined(STM32F411xE) || defined(STM32F446xx) || defined(STM32F412Zx) \ 62 | || defined(STM32F412Vx) || defined(STM32F412Rx) || defined(STM32F412Cx) 63 | 64 | /* Private typedef -----------------------------------------------------------*/ 65 | /* Private define ------------------------------------------------------------*/ 66 | /* Private macro -------------------------------------------------------------*/ 67 | /* Private variables ---------------------------------------------------------*/ 68 | /* Private function prototypes -----------------------------------------------*/ 69 | /* Exported functions --------------------------------------------------------*/ 70 | /** @defgroup FLASH_RAMFUNC_Exported_Functions FLASH RAMFUNC Exported Functions 71 | * @{ 72 | */ 73 | 74 | /** @defgroup FLASH_RAMFUNC_Exported_Functions_Group1 Peripheral features functions executed 75 | from internal RAM 76 | * @brief Peripheral Extended features functions 77 | * 78 | @verbatim 79 | 80 | =============================================================================== 81 | ##### ramfunc functions ##### 82 | =============================================================================== 83 | [..] 84 | This subsection provides a set of functions that should be executed from RAM 85 | transfers. 86 | 87 | @endverbatim 88 | * @{ 89 | */ 90 | 91 | /** 92 | * @brief Stop the flash interface while System Run 93 | * @note This mode is only available for STM32F41xxx/STM32F446xx devices. 94 | * @note This mode couldn't be set while executing with the flash itself. 95 | * It should be done with specific routine executed from RAM. 96 | * @retval HAL status 97 | */ 98 | __RAM_FUNC HAL_StatusTypeDef HAL_FLASHEx_StopFlashInterfaceClk(void) 99 | { 100 | /* Enable Power ctrl clock */ 101 | __HAL_RCC_PWR_CLK_ENABLE(); 102 | /* Stop the flash interface while System Run */ 103 | SET_BIT(PWR->CR, PWR_CR_FISSR); 104 | 105 | return HAL_OK; 106 | } 107 | 108 | /** 109 | * @brief Start the flash interface while System Run 110 | * @note This mode is only available for STM32F411xx/STM32F446xx devices. 111 | * @note This mode couldn't be set while executing with the flash itself. 112 | * It should be done with specific routine executed from RAM. 113 | * @retval HAL status 114 | */ 115 | __RAM_FUNC HAL_StatusTypeDef HAL_FLASHEx_StartFlashInterfaceClk(void) 116 | { 117 | /* Enable Power ctrl clock */ 118 | __HAL_RCC_PWR_CLK_ENABLE(); 119 | /* Start the flash interface while System Run */ 120 | CLEAR_BIT(PWR->CR, PWR_CR_FISSR); 121 | 122 | return HAL_OK; 123 | } 124 | 125 | /** 126 | * @brief Enable the flash sleep while System Run 127 | * @note This mode is only available for STM32F41xxx/STM32F446xx devices. 128 | * @note This mode could n't be set while executing with the flash itself. 129 | * It should be done with specific routine executed from RAM. 130 | * @retval HAL status 131 | */ 132 | __RAM_FUNC HAL_StatusTypeDef HAL_FLASHEx_EnableFlashSleepMode(void) 133 | { 134 | /* Enable Power ctrl clock */ 135 | __HAL_RCC_PWR_CLK_ENABLE(); 136 | /* Enable the flash sleep while System Run */ 137 | SET_BIT(PWR->CR, PWR_CR_FMSSR); 138 | 139 | return HAL_OK; 140 | } 141 | 142 | /** 143 | * @brief Disable the flash sleep while System Run 144 | * @note This mode is only available for STM32F41xxx/STM32F446xx devices. 145 | * @note This mode couldn't be set while executing with the flash itself. 146 | * It should be done with specific routine executed from RAM. 147 | * @retval HAL status 148 | */ 149 | __RAM_FUNC HAL_StatusTypeDef HAL_FLASHEx_DisableFlashSleepMode(void) 150 | { 151 | /* Enable Power ctrl clock */ 152 | __HAL_RCC_PWR_CLK_ENABLE(); 153 | /* Disable the flash sleep while System Run */ 154 | CLEAR_BIT(PWR->CR, PWR_CR_FMSSR); 155 | 156 | return HAL_OK; 157 | } 158 | 159 | /** 160 | * @} 161 | */ 162 | 163 | /** 164 | * @} 165 | */ 166 | 167 | #endif /* STM32F410xx || STM32F411xE || STM32F446xx || STM32F412Zx || STM32F412Vx || \ 168 | STM32F412Rx || STM32F412Cx */ 169 | #endif /* HAL_FLASH_MODULE_ENABLED */ 170 | /** 171 | * @} 172 | */ 173 | 174 | /** 175 | * @} 176 | */ 177 | 178 | /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ 179 | -------------------------------------------------------------------------------- /CubeMX/STM32F407VGTx_FLASH.ld: -------------------------------------------------------------------------------- 1 | /* Entry point to first function executed */ 2 | ENTRY(Reset_Handler) /* Reset_Handler is stored somewhere in FLASH */ 3 | 4 | /* End of stack (start) is at end of RAM, as stack grows down */ 5 | _estack = 0x20020000; /* ORIGIN (0x20000000) + LENGTH (0x20000) */ 6 | 7 | /* Generate a link error if heap and stack don't fit into RAM */ 8 | _Min_Heap_Size = 0x200; /* required amount of heap */ 9 | _Min_Stack_Size = 0x400; /* required amount of stack */ 10 | 11 | /* Specify the memory areas (datasheet) */ 12 | 13 | MEMORY 14 | { 15 | RAM (xrw) : ORIGIN = 0x20000000, LENGTH = 128K /* main memory */ 16 | CCMRAM (xrw) : ORIGIN = 0x10000000, LENGTH = 64K /* core coupled memory */ 17 | FLASH (rx) : ORIGIN = 0x8000000, LENGTH = 1024K /* flash ROM */ 18 | } 19 | 20 | /* Output sections - where is data placed */ 21 | 22 | /* 23 | ADDRESS: | 0x08000000 | 0x08000000 + (0) | 0x08000000 + (1) | 0x08000000 + (2) | 0x08000000 + (3) | 0x08000000 + (4) | 0x08000000 + (5) | ~ | 0x08000000 + (6), 0x20000000 | / | 0x20000000 + (7) | 0x20000000 + (8) 24 | SEQUENCE: | 0 | 1 | 2 | 3 | 4 | 5 | 6 | ~ | 7 | / | 8 | 9 25 | FUNCTION: | vector table | code | constants | arm data | constructors | constructors | destructors | ~ | initialized global variables | / | uninitialized global variables " | check, end of static ram data 26 | SECTIONS: | .isr_vector | .text, .text* | .rodata, .rodata* | .ARM* | .preinit_array* | .init_array* | .fini_array* | ~ | .data, .data* | / | .bss, .bss* | ._user_heap_stack 27 | REGION: | [FLASH] | [ FLASH ] | [FLASH] | [FLASH] | [FLASH] | [FLASH] | [FLASH] | ~ | [ FLASH ] -> [ RAM ] | / | [ RAM ] | [ [RAM] ] 28 | ^ ^ ^ ^ ^ ^ ^ 29 | | | | | | | | 30 | SYMBOLS: _etext _sidata _sdata _edata _sbss _ebss _end, end 31 | */ 32 | 33 | SECTIONS 34 | { 35 | /* Initial stack position, reset_handler and vector table */ 36 | .isr_vector : 37 | { 38 | . = ALIGN(4); /* All data, unless specified else, is 4B (word) aligned */ 39 | KEEP(*(.isr_vector)) /* Keep this section even if unused */ 40 | . = ALIGN(4); 41 | } >FLASH /* Store section in FLASH, LMA and VMA are the same */ 42 | 43 | /* The program code and other data*/ 44 | .text : 45 | { 46 | . = ALIGN(4); 47 | *(.text) 48 | *(.text*) 49 | *(.glue_7) /* Compiler glue/helper functions */ 50 | *(.glue_7t) /* -||- */ 51 | *(.eh_frame) /* Exception unwinding information (empty as it is disabled) */ 52 | KEEP (*(.init)) /* Support for constructors and destructors */ 53 | KEEP (*(.fini)) /* -||- */ 54 | . = ALIGN(4); 55 | _etext = .; /* define a global symbol at end of code section */ 56 | } >FLASH 57 | 58 | /* Constants*/ 59 | .rodata : 60 | { 61 | . = ALIGN(4); 62 | *(.rodata) 63 | *(.rodata*) 64 | . = ALIGN(4); 65 | } >FLASH 66 | 67 | /* ARM's stuff */ 68 | .ARM.extab : { *(.ARM.extab* .gnu.linkonce.armextab.*) } >FLASH 69 | .ARM : { 70 | __exidx_start = .; 71 | *(.ARM.exidx*) 72 | __exidx_end = .; 73 | } >FLASH 74 | 75 | /* Pre-initialization functions, only in dynamic executables (empty for us) */ 76 | .preinit_array : 77 | { 78 | PROVIDE_HIDDEN (__preinit_array_start = .); /* Same as PROVIDE but limited to current file */ 79 | KEEP (*(.preinit_array*)) 80 | PROVIDE_HIDDEN (__preinit_array_end = .); 81 | } >FLASH 82 | 83 | /* Constructor arrays */ 84 | .init_array : 85 | { 86 | PROVIDE_HIDDEN (__init_array_start = .); 87 | KEEP (*(SORT(.init_array.*))) 88 | KEEP (*(.init_array*)) 89 | PROVIDE_HIDDEN (__init_array_end = .); 90 | } >FLASH 91 | 92 | /* Destructor arrays */ 93 | .fini_array : 94 | { 95 | PROVIDE_HIDDEN (__fini_array_start = .); 96 | KEEP (*(SORT(.fini_array.*))) 97 | KEEP (*(.fini_array*)) 98 | PROVIDE_HIDDEN (__fini_array_end = .); 99 | } >FLASH 100 | 101 | /* define global symbol at beginning of initial values for global variables in FLASH for RAM */ 102 | _sidata = LOADADDR(.data); /* get absolute load memory address of section */ 103 | 104 | /* Initialized data (initialized global variables) */ 105 | .data : 106 | { 107 | . = ALIGN(4); 108 | _sdata = .; /* define a global symbol at data start */ 109 | *(.data) 110 | *(.data*) 111 | . = ALIGN(4); 112 | _edata = .; /* define a global symbol at data end */ 113 | } >RAM AT> FLASH /* AT specifies that load memory address is in FLASH, RAM is VMA*/ 114 | 115 | /* define global symbol at beginning of initial values for global variables in FLASH for CCRAM */ 116 | _siccmram = LOADADDR(.ccmram); 117 | 118 | /* CCM-RAM section 119 | Provided startup file does not initialize data in CCRAM! 120 | Implementation can be the same as for .data 121 | */ 122 | .ccmram : 123 | { 124 | . = ALIGN(4); 125 | _sccmram = .; /* define a global symbol at ccmram start */ 126 | *(.ccmram) 127 | *(.ccmram*) 128 | . = ALIGN(4); 129 | _eccmram = .; /* define a global symbol at ccmram end */ 130 | } >CCMRAM AT> FLASH 131 | 132 | /* Uninitialized data section *uninitialized global variables) */ 133 | . = ALIGN(4); 134 | .bss : 135 | { 136 | _sbss = .; /* define a global symbol at bss start */ 137 | __bss_start__ = _sbss; 138 | *(.bss) 139 | *(.bss*) 140 | . = ALIGN(4); 141 | _ebss = .; /* define a global symbol at bss end */ 142 | __bss_end__ = _ebss; 143 | } >RAM 144 | 145 | /* User_heap_stack section, used to check that there is enough RAM left */ 146 | ._user_heap_stack : 147 | { 148 | . = ALIGN(8); 149 | PROVIDE ( end = . ); /* these two sybols can be re-defined/used */ 150 | PROVIDE ( _end = . ); 151 | . = . + _Min_Heap_Size; 152 | . = . + _Min_Stack_Size; 153 | . = ALIGN(8); 154 | } >RAM 155 | 156 | /* Remove information from the standard libraries */ 157 | /DISCARD/ : 158 | { 159 | libc.a ( * ) 160 | libm.a ( * ) 161 | libgcc.a ( * ) 162 | } 163 | 164 | .ARM.attributes 0 : { *(.ARM.attributes) } 165 | } 166 | 167 | -------------------------------------------------------------------------------- /Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_def.h: -------------------------------------------------------------------------------- 1 | /** 2 | ****************************************************************************** 3 | * @file stm32f4xx_hal_def.h 4 | * @author MCD Application Team 5 | * @brief This file contains HAL common defines, enumeration, macros and 6 | * structures definitions. 7 | ****************************************************************************** 8 | * @attention 9 | * 10 | *

© Copyright (c) 2017 STMicroelectronics. 11 | * All rights reserved.

12 | * 13 | * This software component is licensed by ST under BSD 3-Clause license, 14 | * the "License"; You may not use this file except in compliance with the 15 | * License. You may obtain a copy of the License at: 16 | * opensource.org/licenses/BSD-3-Clause 17 | * 18 | ****************************************************************************** 19 | */ 20 | 21 | /* Define to prevent recursive inclusion -------------------------------------*/ 22 | #ifndef __STM32F4xx_HAL_DEF 23 | #define __STM32F4xx_HAL_DEF 24 | 25 | #ifdef __cplusplus 26 | extern "C" 27 | { 28 | #endif 29 | 30 | /* Includes ------------------------------------------------------------------*/ 31 | #include "Legacy/stm32_hal_legacy.h" 32 | #include "stm32f4xx.h" 33 | #include 34 | 35 | /* Exported types ------------------------------------------------------------*/ 36 | 37 | /** 38 | * @brief HAL Status structures definition 39 | */ 40 | typedef enum 41 | { 42 | HAL_OK = 0x00U, 43 | HAL_ERROR = 0x01U, 44 | HAL_BUSY = 0x02U, 45 | HAL_TIMEOUT = 0x03U 46 | } HAL_StatusTypeDef; 47 | 48 | /** 49 | * @brief HAL Lock structures definition 50 | */ 51 | typedef enum 52 | { 53 | HAL_UNLOCKED = 0x00U, 54 | HAL_LOCKED = 0x01U 55 | } HAL_LockTypeDef; 56 | 57 | /* Exported macro ------------------------------------------------------------*/ 58 | 59 | #define UNUSED(X) (void)X /* To avoid gcc/g++ warnings */ 60 | 61 | #define HAL_MAX_DELAY 0xFFFFFFFFU 62 | 63 | #define HAL_IS_BIT_SET(REG, BIT) (((REG) & (BIT)) == (BIT)) 64 | #define HAL_IS_BIT_CLR(REG, BIT) (((REG) & (BIT)) == 0U) 65 | 66 | #define __HAL_LINKDMA(__HANDLE__, __PPP_DMA_FIELD__, __DMA_HANDLE__) \ 67 | do \ 68 | { \ 69 | (__HANDLE__)->__PPP_DMA_FIELD__ = &(__DMA_HANDLE__); \ 70 | (__DMA_HANDLE__).Parent = (__HANDLE__); \ 71 | } while (0U) 72 | 73 | /** @brief Reset the Handle's State field. 74 | * @param __HANDLE__ specifies the Peripheral Handle. 75 | * @note This macro can be used for the following purpose: 76 | * - When the Handle is declared as local variable; before passing it as parameter 77 | * to HAL_PPP_Init() for the first time, it is mandatory to use this macro 78 | * to set to 0 the Handle's "State" field. 79 | * Otherwise, "State" field may have any random value and the first time the 80 | * function HAL_PPP_Init() is called, the low level hardware initialization will be missed 81 | * (i.e. HAL_PPP_MspInit() will not be executed). 82 | * - When there is a need to reconfigure the low level hardware: instead of calling 83 | * HAL_PPP_DeInit() then HAL_PPP_Init(), user can make a call to this macro then 84 | * HAL_PPP_Init(). In this later function, when the Handle's "State" field is set to 0, it will 85 | * execute the function HAL_PPP_MspInit() which will reconfigure the low level hardware. 86 | * @retval None 87 | */ 88 | #define __HAL_RESET_HANDLE_STATE(__HANDLE__) ((__HANDLE__)->State = 0U) 89 | 90 | #if (USE_RTOS == 1U) 91 | /* Reserved for future use */ 92 | #error "USE_RTOS should be 0 in the current HAL release" 93 | #else 94 | #define __HAL_LOCK(__HANDLE__) \ 95 | do \ 96 | { \ 97 | if ((__HANDLE__)->Lock == HAL_LOCKED) \ 98 | { \ 99 | return HAL_BUSY; \ 100 | } \ 101 | else \ 102 | { \ 103 | (__HANDLE__)->Lock = HAL_LOCKED; \ 104 | } \ 105 | } while (0U) 106 | 107 | #define __HAL_UNLOCK(__HANDLE__) \ 108 | do \ 109 | { \ 110 | (__HANDLE__)->Lock = HAL_UNLOCKED; \ 111 | } while (0U) 112 | #endif /* USE_RTOS */ 113 | 114 | #if defined(__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050) /* ARM Compiler V6 */ 115 | #ifndef __weak 116 | #define __weak __attribute__((weak)) 117 | #endif 118 | #ifndef __packed 119 | #define __packed __attribute__((packed)) 120 | #endif 121 | #elif defined(__GNUC__) && !defined(__CC_ARM) /* GNU Compiler */ 122 | #ifndef __weak 123 | #define __weak __attribute__((weak)) 124 | #endif /* __weak */ 125 | #ifndef __packed 126 | #define __packed __attribute__((__packed__)) 127 | #endif /* __packed */ 128 | #endif /* __GNUC__ */ 129 | 130 | /* Macro to get variable aligned on 4-bytes, for __ICCARM__ the directive "#pragma 131 | * data_alignment=4" must be used instead */ 132 | #if defined(__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050) /* ARM Compiler V6 */ 133 | #ifndef __ALIGN_BEGIN 134 | #define __ALIGN_BEGIN 135 | #endif 136 | #ifndef __ALIGN_END 137 | #define __ALIGN_END __attribute__((aligned(4))) 138 | #endif 139 | #elif defined(__GNUC__) && !defined(__CC_ARM) /* GNU Compiler */ 140 | #ifndef __ALIGN_END 141 | #define __ALIGN_END __attribute__((aligned(4))) 142 | #endif /* __ALIGN_END */ 143 | #ifndef __ALIGN_BEGIN 144 | #define __ALIGN_BEGIN 145 | #endif /* __ALIGN_BEGIN */ 146 | #else 147 | #ifndef __ALIGN_END 148 | #define __ALIGN_END 149 | #endif /* __ALIGN_END */ 150 | #ifndef __ALIGN_BEGIN 151 | #if defined(__CC_ARM) /* ARM Compiler V5*/ 152 | #define __ALIGN_BEGIN __align(4) 153 | #elif defined(__ICCARM__) /* IAR Compiler */ 154 | #define __ALIGN_BEGIN 155 | #endif /* __CC_ARM */ 156 | #endif /* __ALIGN_BEGIN */ 157 | #endif /* __GNUC__ */ 158 | 159 | /** 160 | * @brief __RAM_FUNC definition 161 | */ 162 | #if defined(__CC_ARM) || (defined(__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050)) 163 | /* ARM Compiler V4/V5 and V6 164 | -------------------------- 165 | RAM functions are defined using the toolchain options. 166 | Functions that are executed in RAM should reside in a separate source module. 167 | Using the 'Options for File' dialog you can simply change the 'Code / Const' 168 | area of a module to a memory space in physical RAM. 169 | Available memory areas are declared in the 'Target' tab of the 'Options for Target' 170 | dialog. 171 | */ 172 | #define __RAM_FUNC 173 | 174 | #elif defined(__ICCARM__) 175 | /* ICCARM Compiler 176 | --------------- 177 | RAM functions are defined using a specific toolchain keyword "__ramfunc". 178 | */ 179 | #define __RAM_FUNC __ramfunc 180 | 181 | #elif defined(__GNUC__) 182 | /* GNU Compiler 183 | ------------ 184 | RAM functions are defined using a specific toolchain attribute 185 | "__attribute__((section(".RamFunc")))". 186 | */ 187 | #define __RAM_FUNC __attribute__((section(".RamFunc"))) 188 | 189 | #endif 190 | 191 | /** 192 | * @brief __NOINLINE definition 193 | */ 194 | #if defined(__CC_ARM) || (defined(__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050)) \ 195 | || defined(__GNUC__) 196 | /* ARM V4/V5 and V6 & GNU Compiler 197 | ------------------------------- 198 | */ 199 | #define __NOINLINE __attribute__((noinline)) 200 | 201 | #elif defined(__ICCARM__) 202 | /* ICCARM Compiler 203 | --------------- 204 | */ 205 | #define __NOINLINE _Pragma("optimize = no_inline") 206 | 207 | #endif 208 | 209 | #ifdef __cplusplus 210 | } 211 | #endif 212 | 213 | #endif /* ___STM32F4xx_HAL_DEF */ 214 | 215 | /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ 216 | -------------------------------------------------------------------------------- /Drivers/CMSIS/Include/cmsis_compiler.h: -------------------------------------------------------------------------------- 1 | /**************************************************************************/ /** 2 | * @file 3 | *cmsis_compiler.h 4 | * @brief CMSIS 5 | *compiler generic 6 | *header file 7 | * @version V5.0.4 8 | * @date 10. 9 | *January 2018 10 | ******************************************************************************/ 11 | /* 12 | * Copyright (c) 2009-2018 Arm Limited. All rights reserved. 13 | * 14 | * SPDX-License-Identifier: Apache-2.0 15 | * 16 | * Licensed under the Apache License, Version 2.0 (the License); you may 17 | * not use this file except in compliance with the License. 18 | * You may obtain a copy of the License at 19 | * 20 | * www.apache.org/licenses/LICENSE-2.0 21 | * 22 | * Unless required by applicable law or agreed to in writing, software 23 | * distributed under the License is distributed on an AS IS BASIS, WITHOUT 24 | * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 25 | * See the License for the specific language governing permissions and 26 | * limitations under the License. 27 | */ 28 | 29 | #ifndef __CMSIS_COMPILER_H 30 | #define __CMSIS_COMPILER_H 31 | 32 | #include 33 | 34 | /* 35 | * Arm Compiler 4/5 36 | */ 37 | #if defined(__CC_ARM) 38 | #include "cmsis_armcc.h" 39 | 40 | /* 41 | * Arm Compiler 6 (armclang) 42 | */ 43 | #elif defined(__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050) 44 | #include "cmsis_armclang.h" 45 | 46 | /* 47 | * GNU Compiler 48 | */ 49 | #elif defined(__GNUC__) 50 | #include "cmsis_gcc.h" 51 | 52 | /* 53 | * IAR Compiler 54 | */ 55 | #elif defined(__ICCARM__) 56 | #include 57 | 58 | /* 59 | * TI Arm Compiler 60 | */ 61 | #elif defined(__TI_ARM__) 62 | #include 63 | 64 | #ifndef __ASM 65 | #define __ASM __asm 66 | #endif 67 | #ifndef __INLINE 68 | #define __INLINE inline 69 | #endif 70 | #ifndef __STATIC_INLINE 71 | #define __STATIC_INLINE static inline 72 | #endif 73 | #ifndef __STATIC_FORCEINLINE 74 | #define __STATIC_FORCEINLINE __STATIC_INLINE 75 | #endif 76 | #ifndef __NO_RETURN 77 | #define __NO_RETURN __attribute__((noreturn)) 78 | #endif 79 | #ifndef __USED 80 | #define __USED __attribute__((used)) 81 | #endif 82 | #ifndef __WEAK 83 | #define __WEAK __attribute__((weak)) 84 | #endif 85 | #ifndef __PACKED 86 | #define __PACKED __attribute__((packed)) 87 | #endif 88 | #ifndef __PACKED_STRUCT 89 | #define __PACKED_STRUCT struct __attribute__((packed)) 90 | #endif 91 | #ifndef __PACKED_UNION 92 | #define __PACKED_UNION union __attribute__((packed)) 93 | #endif 94 | #ifndef __UNALIGNED_UINT32 /* deprecated */ 95 | struct __attribute__((packed)) T_UINT32 96 | { 97 | uint32_t v; 98 | }; 99 | #define __UNALIGNED_UINT32(x) (((struct T_UINT32*)(x))->v) 100 | #endif 101 | #ifndef __UNALIGNED_UINT16_WRITE 102 | __PACKED_STRUCT T_UINT16_WRITE 103 | { 104 | uint16_t v; 105 | }; 106 | #define __UNALIGNED_UINT16_WRITE(addr, val) \ 107 | (void)((((struct T_UINT16_WRITE*)(void*)(addr))->v) = (val)) 108 | #endif 109 | #ifndef __UNALIGNED_UINT16_READ 110 | __PACKED_STRUCT T_UINT16_READ 111 | { 112 | uint16_t v; 113 | }; 114 | #define __UNALIGNED_UINT16_READ(addr) (((const struct T_UINT16_READ*)(const void*)(addr))->v) 115 | #endif 116 | #ifndef __UNALIGNED_UINT32_WRITE 117 | __PACKED_STRUCT T_UINT32_WRITE 118 | { 119 | uint32_t v; 120 | }; 121 | #define __UNALIGNED_UINT32_WRITE(addr, val) \ 122 | (void)((((struct T_UINT32_WRITE*)(void*)(addr))->v) = (val)) 123 | #endif 124 | #ifndef __UNALIGNED_UINT32_READ 125 | __PACKED_STRUCT T_UINT32_READ 126 | { 127 | uint32_t v; 128 | }; 129 | #define __UNALIGNED_UINT32_READ(addr) (((const struct T_UINT32_READ*)(const void*)(addr))->v) 130 | #endif 131 | #ifndef __ALIGNED 132 | #define __ALIGNED(x) __attribute__((aligned(x))) 133 | #endif 134 | #ifndef __RESTRICT 135 | #warning No compiler specific solution for __RESTRICT. __RESTRICT is ignored. 136 | #define __RESTRICT 137 | #endif 138 | 139 | /* 140 | * TASKING Compiler 141 | */ 142 | #elif defined(__TASKING__) 143 | /* 144 | * The CMSIS functions have been implemented as intrinsics in the compiler. 145 | * Please use "carm -?i" to get an up to date list of all intrinsics, 146 | * Including the CMSIS ones. 147 | */ 148 | 149 | #ifndef __ASM 150 | #define __ASM __asm 151 | #endif 152 | #ifndef __INLINE 153 | #define __INLINE inline 154 | #endif 155 | #ifndef __STATIC_INLINE 156 | #define __STATIC_INLINE static inline 157 | #endif 158 | #ifndef __STATIC_FORCEINLINE 159 | #define __STATIC_FORCEINLINE __STATIC_INLINE 160 | #endif 161 | #ifndef __NO_RETURN 162 | #define __NO_RETURN __attribute__((noreturn)) 163 | #endif 164 | #ifndef __USED 165 | #define __USED __attribute__((used)) 166 | #endif 167 | #ifndef __WEAK 168 | #define __WEAK __attribute__((weak)) 169 | #endif 170 | #ifndef __PACKED 171 | #define __PACKED __packed__ 172 | #endif 173 | #ifndef __PACKED_STRUCT 174 | #define __PACKED_STRUCT struct __packed__ 175 | #endif 176 | #ifndef __PACKED_UNION 177 | #define __PACKED_UNION union __packed__ 178 | #endif 179 | #ifndef __UNALIGNED_UINT32 /* deprecated */ 180 | struct __packed__ T_UINT32 181 | { 182 | uint32_t v; 183 | }; 184 | #define __UNALIGNED_UINT32(x) (((struct T_UINT32*)(x))->v) 185 | #endif 186 | #ifndef __UNALIGNED_UINT16_WRITE 187 | __PACKED_STRUCT T_UINT16_WRITE 188 | { 189 | uint16_t v; 190 | }; 191 | #define __UNALIGNED_UINT16_WRITE(addr, val) \ 192 | (void)((((struct T_UINT16_WRITE*)(void*)(addr))->v) = (val)) 193 | #endif 194 | #ifndef __UNALIGNED_UINT16_READ 195 | __PACKED_STRUCT T_UINT16_READ 196 | { 197 | uint16_t v; 198 | }; 199 | #define __UNALIGNED_UINT16_READ(addr) (((const struct T_UINT16_READ*)(const void*)(addr))->v) 200 | #endif 201 | #ifndef __UNALIGNED_UINT32_WRITE 202 | __PACKED_STRUCT T_UINT32_WRITE 203 | { 204 | uint32_t v; 205 | }; 206 | #define __UNALIGNED_UINT32_WRITE(addr, val) \ 207 | (void)((((struct T_UINT32_WRITE*)(void*)(addr))->v) = (val)) 208 | #endif 209 | #ifndef __UNALIGNED_UINT32_READ 210 | __PACKED_STRUCT T_UINT32_READ 211 | { 212 | uint32_t v; 213 | }; 214 | #define __UNALIGNED_UINT32_READ(addr) (((const struct T_UINT32_READ*)(const void*)(addr))->v) 215 | #endif 216 | #ifndef __ALIGNED 217 | #define __ALIGNED(x) __align(x) 218 | #endif 219 | #ifndef __RESTRICT 220 | #warning No compiler specific solution for __RESTRICT. __RESTRICT is ignored. 221 | #define __RESTRICT 222 | #endif 223 | 224 | /* 225 | * COSMIC Compiler 226 | */ 227 | #elif defined(__CSMC__) 228 | #include 229 | 230 | #ifndef __ASM 231 | #define __ASM _asm 232 | #endif 233 | #ifndef __INLINE 234 | #define __INLINE inline 235 | #endif 236 | #ifndef __STATIC_INLINE 237 | #define __STATIC_INLINE static inline 238 | #endif 239 | #ifndef __STATIC_FORCEINLINE 240 | #define __STATIC_FORCEINLINE __STATIC_INLINE 241 | #endif 242 | #ifndef __NO_RETURN 243 | // NO RETURN is automatically detected hence no warning here 244 | #define __NO_RETURN 245 | #endif 246 | #ifndef __USED 247 | #warning No compiler specific solution for __USED. __USED is ignored. 248 | #define __USED 249 | #endif 250 | #ifndef __WEAK 251 | #define __WEAK __weak 252 | #endif 253 | #ifndef __PACKED 254 | #define __PACKED @packed 255 | #endif 256 | #ifndef __PACKED_STRUCT 257 | #define __PACKED_STRUCT @packed struct 258 | #endif 259 | #ifndef __PACKED_UNION 260 | #define __PACKED_UNION @packed union 261 | #endif 262 | #ifndef __UNALIGNED_UINT32 /* deprecated */ 263 | @packed struct T_UINT32 264 | { 265 | uint32_t v; 266 | }; 267 | #define __UNALIGNED_UINT32(x) (((struct T_UINT32*)(x))->v) 268 | #endif 269 | #ifndef __UNALIGNED_UINT16_WRITE 270 | __PACKED_STRUCT T_UINT16_WRITE 271 | { 272 | uint16_t v; 273 | }; 274 | #define __UNALIGNED_UINT16_WRITE(addr, val) \ 275 | (void)((((struct T_UINT16_WRITE*)(void*)(addr))->v) = (val)) 276 | #endif 277 | #ifndef __UNALIGNED_UINT16_READ 278 | __PACKED_STRUCT T_UINT16_READ 279 | { 280 | uint16_t v; 281 | }; 282 | #define __UNALIGNED_UINT16_READ(addr) (((const struct T_UINT16_READ*)(const void*)(addr))->v) 283 | #endif 284 | #ifndef __UNALIGNED_UINT32_WRITE 285 | __PACKED_STRUCT T_UINT32_WRITE 286 | { 287 | uint32_t v; 288 | }; 289 | #define __UNALIGNED_UINT32_WRITE(addr, val) \ 290 | (void)((((struct T_UINT32_WRITE*)(void*)(addr))->v) = (val)) 291 | #endif 292 | #ifndef __UNALIGNED_UINT32_READ 293 | __PACKED_STRUCT T_UINT32_READ 294 | { 295 | uint32_t v; 296 | }; 297 | #define __UNALIGNED_UINT32_READ(addr) (((const struct T_UINT32_READ*)(const void*)(addr))->v) 298 | #endif 299 | #ifndef __ALIGNED 300 | #warning No compiler specific solution for __ALIGNED. __ALIGNED is ignored. 301 | #define __ALIGNED(x) 302 | #endif 303 | #ifndef __RESTRICT 304 | #warning No compiler specific solution for __RESTRICT. __RESTRICT is ignored. 305 | #define __RESTRICT 306 | #endif 307 | 308 | #else 309 | #error Unknown compiler. 310 | #endif 311 | 312 | #endif /* __CMSIS_COMPILER_H */ 313 | -------------------------------------------------------------------------------- /Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_dma_ex.c: -------------------------------------------------------------------------------- 1 | /** 2 | ****************************************************************************** 3 | * @file stm32f4xx_hal_dma_ex.c 4 | * @author MCD Application Team 5 | * @brief DMA Extension HAL module driver 6 | * This file provides firmware functions to manage the following 7 | * functionalities of the DMA Extension peripheral: 8 | * + Extended features functions 9 | * 10 | @verbatim 11 | ============================================================================== 12 | ##### How to use this driver ##### 13 | ============================================================================== 14 | [..] 15 | The DMA Extension HAL driver can be used as follows: 16 | (#) Start a multi buffer transfer using the HAL_DMA_MultiBufferStart() function 17 | for polling mode or HAL_DMA_MultiBufferStart_IT() for interrupt mode. 18 | 19 | -@- In Memory-to-Memory transfer mode, Multi (Double) Buffer mode is not allowed. 20 | -@- When Multi (Double) Buffer mode is enabled the, transfer is circular by default. 21 | -@- In Multi (Double) buffer mode, it is possible to update the base address for 22 | the AHB memory port on the fly (DMA_SxM0AR or DMA_SxM1AR) when the stream is enabled. 23 | 24 | @endverbatim 25 | ****************************************************************************** 26 | * @attention 27 | * 28 | *

© Copyright (c) 2017 STMicroelectronics. 29 | * All rights reserved.

30 | * 31 | * This software component is licensed by ST under BSD 3-Clause license, 32 | * the "License"; You may not use this file except in compliance with the 33 | * License. You may obtain a copy of the License at: 34 | * opensource.org/licenses/BSD-3-Clause 35 | * 36 | ****************************************************************************** 37 | */ 38 | 39 | /* Includes ------------------------------------------------------------------*/ 40 | #include "stm32f4xx_hal.h" 41 | 42 | /** @addtogroup STM32F4xx_HAL_Driver 43 | * @{ 44 | */ 45 | 46 | /** @defgroup DMAEx DMAEx 47 | * @brief DMA Extended HAL module driver 48 | * @{ 49 | */ 50 | 51 | #ifdef HAL_DMA_MODULE_ENABLED 52 | 53 | /* Private types -------------------------------------------------------------*/ 54 | /* Private variables ---------------------------------------------------------*/ 55 | /* Private Constants ---------------------------------------------------------*/ 56 | /* Private macros ------------------------------------------------------------*/ 57 | /* Private functions ---------------------------------------------------------*/ 58 | /** @addtogroup DMAEx_Private_Functions 59 | * @{ 60 | */ 61 | static void DMA_MultiBufferSetConfig( 62 | DMA_HandleTypeDef* hdma, uint32_t SrcAddress, uint32_t DstAddress, uint32_t DataLength); 63 | /** 64 | * @} 65 | */ 66 | 67 | /* Exported functions ---------------------------------------------------------*/ 68 | 69 | /** @addtogroup DMAEx_Exported_Functions 70 | * @{ 71 | */ 72 | 73 | /** @addtogroup DMAEx_Exported_Functions_Group1 74 | * 75 | @verbatim 76 | =============================================================================== 77 | ##### Extended features functions ##### 78 | =============================================================================== 79 | [..] This section provides functions allowing to: 80 | (+) Configure the source, destination address and data length and 81 | Start MultiBuffer DMA transfer 82 | (+) Configure the source, destination address and data length and 83 | Start MultiBuffer DMA transfer with interrupt 84 | (+) Change on the fly the memory0 or memory1 address. 85 | 86 | @endverbatim 87 | * @{ 88 | */ 89 | 90 | /** 91 | * @brief Starts the multi_buffer DMA Transfer. 92 | * @param hdma pointer to a DMA_HandleTypeDef structure that contains 93 | * the configuration information for the specified DMA Stream. 94 | * @param SrcAddress The source memory Buffer address 95 | * @param DstAddress The destination memory Buffer address 96 | * @param SecondMemAddress The second memory Buffer address in case of multi buffer Transfer 97 | * @param DataLength The length of data to be transferred from source to destination 98 | * @retval HAL status 99 | */ 100 | HAL_StatusTypeDef HAL_DMAEx_MultiBufferStart( 101 | DMA_HandleTypeDef* hdma, 102 | uint32_t SrcAddress, 103 | uint32_t DstAddress, 104 | uint32_t SecondMemAddress, 105 | uint32_t DataLength) 106 | { 107 | HAL_StatusTypeDef status = HAL_OK; 108 | 109 | /* Check the parameters */ 110 | assert_param(IS_DMA_BUFFER_SIZE(DataLength)); 111 | 112 | /* Memory-to-memory transfer not supported in double buffering mode */ 113 | if (hdma->Init.Direction == DMA_MEMORY_TO_MEMORY) 114 | { 115 | hdma->ErrorCode = HAL_DMA_ERROR_NOT_SUPPORTED; 116 | status = HAL_ERROR; 117 | } 118 | else 119 | { 120 | /* Process Locked */ 121 | __HAL_LOCK(hdma); 122 | 123 | if (HAL_DMA_STATE_READY == hdma->State) 124 | { 125 | /* Change DMA peripheral state */ 126 | hdma->State = HAL_DMA_STATE_BUSY; 127 | 128 | /* Enable the double buffer mode */ 129 | hdma->Instance->CR |= (uint32_t)DMA_SxCR_DBM; 130 | 131 | /* Configure DMA Stream destination address */ 132 | hdma->Instance->M1AR = SecondMemAddress; 133 | 134 | /* Configure the source, destination address and the data length */ 135 | DMA_MultiBufferSetConfig(hdma, SrcAddress, DstAddress, DataLength); 136 | 137 | /* Enable the peripheral */ 138 | __HAL_DMA_ENABLE(hdma); 139 | } 140 | else 141 | { 142 | /* Return error status */ 143 | status = HAL_BUSY; 144 | } 145 | } 146 | return status; 147 | } 148 | 149 | /** 150 | * @brief Starts the multi_buffer DMA Transfer with interrupt enabled. 151 | * @param hdma pointer to a DMA_HandleTypeDef structure that contains 152 | * the configuration information for the specified DMA Stream. 153 | * @param SrcAddress The source memory Buffer address 154 | * @param DstAddress The destination memory Buffer address 155 | * @param SecondMemAddress The second memory Buffer address in case of multi buffer Transfer 156 | * @param DataLength The length of data to be transferred from source to destination 157 | * @retval HAL status 158 | */ 159 | HAL_StatusTypeDef HAL_DMAEx_MultiBufferStart_IT( 160 | DMA_HandleTypeDef* hdma, 161 | uint32_t SrcAddress, 162 | uint32_t DstAddress, 163 | uint32_t SecondMemAddress, 164 | uint32_t DataLength) 165 | { 166 | HAL_StatusTypeDef status = HAL_OK; 167 | 168 | /* Check the parameters */ 169 | assert_param(IS_DMA_BUFFER_SIZE(DataLength)); 170 | 171 | /* Memory-to-memory transfer not supported in double buffering mode */ 172 | if (hdma->Init.Direction == DMA_MEMORY_TO_MEMORY) 173 | { 174 | hdma->ErrorCode = HAL_DMA_ERROR_NOT_SUPPORTED; 175 | return HAL_ERROR; 176 | } 177 | 178 | /* Check callback functions */ 179 | if ((NULL == hdma->XferCpltCallback) || (NULL == hdma->XferM1CpltCallback) 180 | || (NULL == hdma->XferErrorCallback)) 181 | { 182 | hdma->ErrorCode = HAL_DMA_ERROR_PARAM; 183 | return HAL_ERROR; 184 | } 185 | 186 | /* Process locked */ 187 | __HAL_LOCK(hdma); 188 | 189 | if (HAL_DMA_STATE_READY == hdma->State) 190 | { 191 | /* Change DMA peripheral state */ 192 | hdma->State = HAL_DMA_STATE_BUSY; 193 | 194 | /* Initialize the error code */ 195 | hdma->ErrorCode = HAL_DMA_ERROR_NONE; 196 | 197 | /* Enable the Double buffer mode */ 198 | hdma->Instance->CR |= (uint32_t)DMA_SxCR_DBM; 199 | 200 | /* Configure DMA Stream destination address */ 201 | hdma->Instance->M1AR = SecondMemAddress; 202 | 203 | /* Configure the source, destination address and the data length */ 204 | DMA_MultiBufferSetConfig(hdma, SrcAddress, DstAddress, DataLength); 205 | 206 | /* Clear all flags */ 207 | __HAL_DMA_CLEAR_FLAG(hdma, __HAL_DMA_GET_TC_FLAG_INDEX(hdma)); 208 | __HAL_DMA_CLEAR_FLAG(hdma, __HAL_DMA_GET_HT_FLAG_INDEX(hdma)); 209 | __HAL_DMA_CLEAR_FLAG(hdma, __HAL_DMA_GET_TE_FLAG_INDEX(hdma)); 210 | __HAL_DMA_CLEAR_FLAG(hdma, __HAL_DMA_GET_DME_FLAG_INDEX(hdma)); 211 | __HAL_DMA_CLEAR_FLAG(hdma, __HAL_DMA_GET_FE_FLAG_INDEX(hdma)); 212 | 213 | /* Enable Common interrupts*/ 214 | hdma->Instance->CR |= DMA_IT_TC | DMA_IT_TE | DMA_IT_DME; 215 | hdma->Instance->FCR |= DMA_IT_FE; 216 | 217 | if ((hdma->XferHalfCpltCallback != NULL) || (hdma->XferM1HalfCpltCallback != NULL)) 218 | { 219 | hdma->Instance->CR |= DMA_IT_HT; 220 | } 221 | 222 | /* Enable the peripheral */ 223 | __HAL_DMA_ENABLE(hdma); 224 | } 225 | else 226 | { 227 | /* Process unlocked */ 228 | __HAL_UNLOCK(hdma); 229 | 230 | /* Return error status */ 231 | status = HAL_BUSY; 232 | } 233 | return status; 234 | } 235 | 236 | /** 237 | * @brief Change the memory0 or memory1 address on the fly. 238 | * @param hdma pointer to a DMA_HandleTypeDef structure that contains 239 | * the configuration information for the specified DMA Stream. 240 | * @param Address The new address 241 | * @param memory the memory to be changed, This parameter can be one of 242 | * the following values: 243 | * MEMORY0 / 244 | * MEMORY1 245 | * @note The MEMORY0 address can be changed only when the current transfer use 246 | * MEMORY1 and the MEMORY1 address can be changed only when the current 247 | * transfer use MEMORY0. 248 | * @retval HAL status 249 | */ 250 | HAL_StatusTypeDef HAL_DMAEx_ChangeMemory( 251 | DMA_HandleTypeDef* hdma, uint32_t Address, HAL_DMA_MemoryTypeDef memory) 252 | { 253 | if (memory == MEMORY0) 254 | { 255 | /* change the memory0 address */ 256 | hdma->Instance->M0AR = Address; 257 | } 258 | else 259 | { 260 | /* change the memory1 address */ 261 | hdma->Instance->M1AR = Address; 262 | } 263 | 264 | return HAL_OK; 265 | } 266 | 267 | /** 268 | * @} 269 | */ 270 | 271 | /** 272 | * @} 273 | */ 274 | 275 | /** @addtogroup DMAEx_Private_Functions 276 | * @{ 277 | */ 278 | 279 | /** 280 | * @brief Set the DMA Transfer parameter. 281 | * @param hdma pointer to a DMA_HandleTypeDef structure that contains 282 | * the configuration information for the specified DMA Stream. 283 | * @param SrcAddress The source memory Buffer address 284 | * @param DstAddress The destination memory Buffer address 285 | * @param DataLength The length of data to be transferred from source to destination 286 | * @retval HAL status 287 | */ 288 | static void DMA_MultiBufferSetConfig( 289 | DMA_HandleTypeDef* hdma, uint32_t SrcAddress, uint32_t DstAddress, uint32_t DataLength) 290 | { 291 | /* Configure DMA Stream data length */ 292 | hdma->Instance->NDTR = DataLength; 293 | 294 | /* Peripheral to Memory */ 295 | if ((hdma->Init.Direction) == DMA_MEMORY_TO_PERIPH) 296 | { 297 | /* Configure DMA Stream destination address */ 298 | hdma->Instance->PAR = DstAddress; 299 | 300 | /* Configure DMA Stream source address */ 301 | hdma->Instance->M0AR = SrcAddress; 302 | } 303 | /* Memory to Peripheral */ 304 | else 305 | { 306 | /* Configure DMA Stream source address */ 307 | hdma->Instance->PAR = SrcAddress; 308 | 309 | /* Configure DMA Stream destination address */ 310 | hdma->Instance->M0AR = DstAddress; 311 | } 312 | } 313 | 314 | /** 315 | * @} 316 | */ 317 | 318 | #endif /* HAL_DMA_MODULE_ENABLED */ 319 | /** 320 | * @} 321 | */ 322 | 323 | /** 324 | * @} 325 | */ 326 | 327 | /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ 328 | -------------------------------------------------------------------------------- /Drivers/CMSIS/Include/mpu_armv8.h: -------------------------------------------------------------------------------- 1 | /****************************************************************************** 2 | * @file mpu_armv8.h 3 | * @brief CMSIS MPU API for Armv8-M MPU 4 | * @version V5.0.4 5 | * @date 10. January 2018 6 | ******************************************************************************/ 7 | /* 8 | * Copyright (c) 2017-2018 Arm Limited. All rights reserved. 9 | * 10 | * SPDX-License-Identifier: Apache-2.0 11 | * 12 | * Licensed under the Apache License, Version 2.0 (the License); you may 13 | * not use this file except in compliance with the License. 14 | * You may obtain a copy of the License at 15 | * 16 | * www.apache.org/licenses/LICENSE-2.0 17 | * 18 | * Unless required by applicable law or agreed to in writing, software 19 | * distributed under the License is distributed on an AS IS BASIS, WITHOUT 20 | * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 21 | * See the License for the specific language governing permissions and 22 | * limitations under the License. 23 | */ 24 | 25 | #if defined(__ICCARM__) 26 | #pragma system_include /* treat file as system include file for MISRA check */ 27 | #elif defined(__clang__) 28 | #pragma clang system_header /* treat file as system include file */ 29 | #endif 30 | 31 | #ifndef ARM_MPU_ARMV8_H 32 | #define ARM_MPU_ARMV8_H 33 | 34 | /** \brief Attribute for device memory (outer only) */ 35 | #define ARM_MPU_ATTR_DEVICE (0U) 36 | 37 | /** \brief Attribute for non-cacheable, normal memory */ 38 | #define ARM_MPU_ATTR_NON_CACHEABLE (4U) 39 | 40 | /** \brief Attribute for normal memory (outer and inner) 41 | * \param NT Non-Transient: Set to 1 for non-transient data. 42 | * \param WB Write-Back: Set to 1 to use write-back update policy. 43 | * \param RA Read Allocation: Set to 1 to use cache allocation on read miss. 44 | * \param WA Write Allocation: Set to 1 to use cache allocation on write miss. 45 | */ 46 | #define ARM_MPU_ATTR_MEMORY_(NT, WB, RA, WA) \ 47 | (((NT & 1U) << 3U) | ((WB & 1U) << 2U) | ((RA & 1U) << 1U) | (WA & 1U)) 48 | 49 | /** \brief Device memory type non Gathering, non Re-ordering, non Early Write Acknowledgement 50 | */ 51 | #define ARM_MPU_ATTR_DEVICE_nGnRnE (0U) 52 | 53 | /** \brief Device memory type non Gathering, non Re-ordering, Early Write Acknowledgement */ 54 | #define ARM_MPU_ATTR_DEVICE_nGnRE (1U) 55 | 56 | /** \brief Device memory type non Gathering, Re-ordering, Early Write Acknowledgement */ 57 | #define ARM_MPU_ATTR_DEVICE_nGRE (2U) 58 | 59 | /** \brief Device memory type Gathering, Re-ordering, Early Write Acknowledgement */ 60 | #define ARM_MPU_ATTR_DEVICE_GRE (3U) 61 | 62 | /** \brief Memory Attribute 63 | * \param O Outer memory attributes 64 | * \param I O == ARM_MPU_ATTR_DEVICE: Device memory attributes, else: Inner memory attributes 65 | */ 66 | #define ARM_MPU_ATTR(O, I) \ 67 | (((O & 0xFU) << 4U) | (((O & 0xFU) != 0U) ? (I & 0xFU) : ((I & 0x3U) << 2U))) 68 | 69 | /** \brief Normal memory non-shareable */ 70 | #define ARM_MPU_SH_NON (0U) 71 | 72 | /** \brief Normal memory outer shareable */ 73 | #define ARM_MPU_SH_OUTER (2U) 74 | 75 | /** \brief Normal memory inner shareable */ 76 | #define ARM_MPU_SH_INNER (3U) 77 | 78 | /** \brief Memory access permissions 79 | * \param RO Read-Only: Set to 1 for read-only memory. 80 | * \param NP Non-Privileged: Set to 1 for non-privileged memory. 81 | */ 82 | #define ARM_MPU_AP_(RO, NP) (((RO & 1U) << 1U) | (NP & 1U)) 83 | 84 | /** \brief Region Base Address Register value 85 | * \param BASE The base address bits [31:5] of a memory region. The value is zero extended. 86 | * Effective address gets 32 byte aligned. \param SH Defines the Shareability domain for this 87 | * memory region. \param RO Read-Only: Set to 1 for a read-only memory region. \param NP 88 | * Non-Privileged: Set to 1 for a non-privileged memory region. \oaram XN eXecute Never: Set to 89 | * 1 for a non-executable memory region. 90 | */ 91 | #define ARM_MPU_RBAR(BASE, SH, RO, NP, XN) \ 92 | ((BASE & MPU_RBAR_BASE_Msk) | ((SH << MPU_RBAR_SH_Pos) & MPU_RBAR_SH_Msk) \ 93 | | ((ARM_MPU_AP_(RO, NP) << MPU_RBAR_AP_Pos) & MPU_RBAR_AP_Msk) \ 94 | | ((XN << MPU_RBAR_XN_Pos) & MPU_RBAR_XN_Msk)) 95 | 96 | /** \brief Region Limit Address Register value 97 | * \param LIMIT The limit address bits [31:5] for this memory region. The value is one 98 | * extended. \param IDX The attribute index to be associated with this memory region. 99 | */ 100 | #define ARM_MPU_RLAR(LIMIT, IDX) \ 101 | ((LIMIT & MPU_RLAR_LIMIT_Msk) | ((IDX << MPU_RLAR_AttrIndx_Pos) & MPU_RLAR_AttrIndx_Msk) \ 102 | | (MPU_RLAR_EN_Msk)) 103 | 104 | /** 105 | * Struct for a single MPU Region 106 | */ 107 | typedef struct 108 | { 109 | uint32_t RBAR; /*!< Region Base Address Register value */ 110 | uint32_t RLAR; /*!< Region Limit Address Register value */ 111 | } ARM_MPU_Region_t; 112 | 113 | /** Enable the MPU. 114 | * \param MPU_Control Default access permissions for unconfigured regions. 115 | */ 116 | __STATIC_INLINE void ARM_MPU_Enable(uint32_t MPU_Control) 117 | { 118 | __DSB(); 119 | __ISB(); 120 | MPU->CTRL = MPU_Control | MPU_CTRL_ENABLE_Msk; 121 | #ifdef SCB_SHCSR_MEMFAULTENA_Msk 122 | SCB->SHCSR |= SCB_SHCSR_MEMFAULTENA_Msk; 123 | #endif 124 | } 125 | 126 | /** Disable the MPU. 127 | */ 128 | __STATIC_INLINE void ARM_MPU_Disable(void) 129 | { 130 | __DSB(); 131 | __ISB(); 132 | #ifdef SCB_SHCSR_MEMFAULTENA_Msk 133 | SCB->SHCSR &= ~SCB_SHCSR_MEMFAULTENA_Msk; 134 | #endif 135 | MPU->CTRL &= ~MPU_CTRL_ENABLE_Msk; 136 | } 137 | 138 | #ifdef MPU_NS 139 | /** Enable the Non-secure MPU. 140 | * \param MPU_Control Default access permissions for unconfigured regions. 141 | */ 142 | __STATIC_INLINE void ARM_MPU_Enable_NS(uint32_t MPU_Control) 143 | { 144 | __DSB(); 145 | __ISB(); 146 | MPU_NS->CTRL = MPU_Control | MPU_CTRL_ENABLE_Msk; 147 | #ifdef SCB_SHCSR_MEMFAULTENA_Msk 148 | SCB_NS->SHCSR |= SCB_SHCSR_MEMFAULTENA_Msk; 149 | #endif 150 | } 151 | 152 | /** Disable the Non-secure MPU. 153 | */ 154 | __STATIC_INLINE void ARM_MPU_Disable_NS(void) 155 | { 156 | __DSB(); 157 | __ISB(); 158 | #ifdef SCB_SHCSR_MEMFAULTENA_Msk 159 | SCB_NS->SHCSR &= ~SCB_SHCSR_MEMFAULTENA_Msk; 160 | #endif 161 | MPU_NS->CTRL &= ~MPU_CTRL_ENABLE_Msk; 162 | } 163 | #endif 164 | 165 | /** Set the memory attribute encoding to the given MPU. 166 | * \param mpu Pointer to the MPU to be configured. 167 | * \param idx The attribute index to be set [0-7] 168 | * \param attr The attribute value to be set. 169 | */ 170 | __STATIC_INLINE void ARM_MPU_SetMemAttrEx(MPU_Type* mpu, uint8_t idx, uint8_t attr) 171 | { 172 | const uint8_t reg = idx / 4U; 173 | const uint32_t pos = ((idx % 4U) * 8U); 174 | const uint32_t mask = 0xFFU << pos; 175 | 176 | if (reg >= (sizeof(mpu->MAIR) / sizeof(mpu->MAIR[0]))) 177 | { 178 | return; // invalid index 179 | } 180 | 181 | mpu->MAIR[reg] = ((mpu->MAIR[reg] & ~mask) | ((attr << pos) & mask)); 182 | } 183 | 184 | /** Set the memory attribute encoding. 185 | * \param idx The attribute index to be set [0-7] 186 | * \param attr The attribute value to be set. 187 | */ 188 | __STATIC_INLINE void ARM_MPU_SetMemAttr(uint8_t idx, uint8_t attr) 189 | { 190 | ARM_MPU_SetMemAttrEx(MPU, idx, attr); 191 | } 192 | 193 | #ifdef MPU_NS 194 | /** Set the memory attribute encoding to the Non-secure MPU. 195 | * \param idx The attribute index to be set [0-7] 196 | * \param attr The attribute value to be set. 197 | */ 198 | __STATIC_INLINE void ARM_MPU_SetMemAttr_NS(uint8_t idx, uint8_t attr) 199 | { 200 | ARM_MPU_SetMemAttrEx(MPU_NS, idx, attr); 201 | } 202 | #endif 203 | 204 | /** Clear and disable the given MPU region of the given MPU. 205 | * \param mpu Pointer to MPU to be used. 206 | * \param rnr Region number to be cleared. 207 | */ 208 | __STATIC_INLINE void ARM_MPU_ClrRegionEx(MPU_Type* mpu, uint32_t rnr) 209 | { 210 | mpu->RNR = rnr; 211 | mpu->RLAR = 0U; 212 | } 213 | 214 | /** Clear and disable the given MPU region. 215 | * \param rnr Region number to be cleared. 216 | */ 217 | __STATIC_INLINE void ARM_MPU_ClrRegion(uint32_t rnr) 218 | { 219 | ARM_MPU_ClrRegionEx(MPU, rnr); 220 | } 221 | 222 | #ifdef MPU_NS 223 | /** Clear and disable the given Non-secure MPU region. 224 | * \param rnr Region number to be cleared. 225 | */ 226 | __STATIC_INLINE void ARM_MPU_ClrRegion_NS(uint32_t rnr) 227 | { 228 | ARM_MPU_ClrRegionEx(MPU_NS, rnr); 229 | } 230 | #endif 231 | 232 | /** Configure the given MPU region of the given MPU. 233 | * \param mpu Pointer to MPU to be used. 234 | * \param rnr Region number to be configured. 235 | * \param rbar Value for RBAR register. 236 | * \param rlar Value for RLAR register. 237 | */ 238 | __STATIC_INLINE void ARM_MPU_SetRegionEx( 239 | MPU_Type* mpu, uint32_t rnr, uint32_t rbar, uint32_t rlar) 240 | { 241 | mpu->RNR = rnr; 242 | mpu->RBAR = rbar; 243 | mpu->RLAR = rlar; 244 | } 245 | 246 | /** Configure the given MPU region. 247 | * \param rnr Region number to be configured. 248 | * \param rbar Value for RBAR register. 249 | * \param rlar Value for RLAR register. 250 | */ 251 | __STATIC_INLINE void ARM_MPU_SetRegion(uint32_t rnr, uint32_t rbar, uint32_t rlar) 252 | { 253 | ARM_MPU_SetRegionEx(MPU, rnr, rbar, rlar); 254 | } 255 | 256 | #ifdef MPU_NS 257 | /** Configure the given Non-secure MPU region. 258 | * \param rnr Region number to be configured. 259 | * \param rbar Value for RBAR register. 260 | * \param rlar Value for RLAR register. 261 | */ 262 | __STATIC_INLINE void ARM_MPU_SetRegion_NS(uint32_t rnr, uint32_t rbar, uint32_t rlar) 263 | { 264 | ARM_MPU_SetRegionEx(MPU_NS, rnr, rbar, rlar); 265 | } 266 | #endif 267 | 268 | /** Memcopy with strictly ordered memory access, e.g. for register targets. 269 | * \param dst Destination data is copied to. 270 | * \param src Source data is copied from. 271 | * \param len Amount of data words to be copied. 272 | */ 273 | __STATIC_INLINE void orderedCpy( 274 | volatile uint32_t* dst, const uint32_t* __RESTRICT src, uint32_t len) 275 | { 276 | uint32_t i; 277 | for (i = 0U; i < len; ++i) 278 | { 279 | dst[i] = src[i]; 280 | } 281 | } 282 | 283 | /** Load the given number of MPU regions from a table to the given MPU. 284 | * \param mpu Pointer to the MPU registers to be used. 285 | * \param rnr First region number to be configured. 286 | * \param table Pointer to the MPU configuration table. 287 | * \param cnt Amount of regions to be configured. 288 | */ 289 | __STATIC_INLINE void ARM_MPU_LoadEx( 290 | MPU_Type* mpu, uint32_t rnr, ARM_MPU_Region_t const* table, uint32_t cnt) 291 | { 292 | const uint32_t rowWordSize = sizeof(ARM_MPU_Region_t) / 4U; 293 | if (cnt == 1U) 294 | { 295 | mpu->RNR = rnr; 296 | orderedCpy(&(mpu->RBAR), &(table->RBAR), rowWordSize); 297 | } 298 | else 299 | { 300 | uint32_t rnrBase = rnr & ~(MPU_TYPE_RALIASES - 1U); 301 | uint32_t rnrOffset = rnr % MPU_TYPE_RALIASES; 302 | 303 | mpu->RNR = rnrBase; 304 | while ((rnrOffset + cnt) > MPU_TYPE_RALIASES) 305 | { 306 | uint32_t c = MPU_TYPE_RALIASES - rnrOffset; 307 | orderedCpy(&(mpu->RBAR) + (rnrOffset * 2U), &(table->RBAR), c * rowWordSize); 308 | table += c; 309 | cnt -= c; 310 | rnrOffset = 0U; 311 | rnrBase += MPU_TYPE_RALIASES; 312 | mpu->RNR = rnrBase; 313 | } 314 | 315 | orderedCpy(&(mpu->RBAR) + (rnrOffset * 2U), &(table->RBAR), cnt * rowWordSize); 316 | } 317 | } 318 | 319 | /** Load the given number of MPU regions from a table. 320 | * \param rnr First region number to be configured. 321 | * \param table Pointer to the MPU configuration table. 322 | * \param cnt Amount of regions to be configured. 323 | */ 324 | __STATIC_INLINE void ARM_MPU_Load(uint32_t rnr, ARM_MPU_Region_t const* table, uint32_t cnt) 325 | { 326 | ARM_MPU_LoadEx(MPU, rnr, table, cnt); 327 | } 328 | 329 | #ifdef MPU_NS 330 | /** Load the given number of MPU regions from a table to the Non-secure MPU. 331 | * \param rnr First region number to be configured. 332 | * \param table Pointer to the MPU configuration table. 333 | * \param cnt Amount of regions to be configured. 334 | */ 335 | __STATIC_INLINE void ARM_MPU_Load_NS(uint32_t rnr, ARM_MPU_Region_t const* table, uint32_t cnt) 336 | { 337 | ARM_MPU_LoadEx(MPU_NS, rnr, table, cnt); 338 | } 339 | #endif 340 | 341 | #endif 342 | -------------------------------------------------------------------------------- /Drivers/CMSIS/Include/mpu_armv7.h: -------------------------------------------------------------------------------- 1 | /****************************************************************************** 2 | * @file mpu_armv7.h 3 | * @brief CMSIS MPU API for Armv7-M MPU 4 | * @version V5.0.4 5 | * @date 10. January 2018 6 | ******************************************************************************/ 7 | /* 8 | * Copyright (c) 2017-2018 Arm Limited. All rights reserved. 9 | * 10 | * SPDX-License-Identifier: Apache-2.0 11 | * 12 | * Licensed under the Apache License, Version 2.0 (the License); you may 13 | * not use this file except in compliance with the License. 14 | * You may obtain a copy of the License at 15 | * 16 | * www.apache.org/licenses/LICENSE-2.0 17 | * 18 | * Unless required by applicable law or agreed to in writing, software 19 | * distributed under the License is distributed on an AS IS BASIS, WITHOUT 20 | * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 21 | * See the License for the specific language governing permissions and 22 | * limitations under the License. 23 | */ 24 | 25 | #if defined(__ICCARM__) 26 | #pragma system_include /* treat file as system include file for MISRA check */ 27 | #elif defined(__clang__) 28 | #pragma clang system_header /* treat file as system include file */ 29 | #endif 30 | 31 | #ifndef ARM_MPU_ARMV7_H 32 | #define ARM_MPU_ARMV7_H 33 | 34 | #define ARM_MPU_REGION_SIZE_32B ((uint8_t)0x04U) ///!< MPU Region Size 32 Bytes 35 | #define ARM_MPU_REGION_SIZE_64B ((uint8_t)0x05U) ///!< MPU Region Size 64 Bytes 36 | #define ARM_MPU_REGION_SIZE_128B ((uint8_t)0x06U) ///!< MPU Region Size 128 Bytes 37 | #define ARM_MPU_REGION_SIZE_256B ((uint8_t)0x07U) ///!< MPU Region Size 256 Bytes 38 | #define ARM_MPU_REGION_SIZE_512B ((uint8_t)0x08U) ///!< MPU Region Size 512 Bytes 39 | #define ARM_MPU_REGION_SIZE_1KB ((uint8_t)0x09U) ///!< MPU Region Size 1 KByte 40 | #define ARM_MPU_REGION_SIZE_2KB ((uint8_t)0x0AU) ///!< MPU Region Size 2 KBytes 41 | #define ARM_MPU_REGION_SIZE_4KB ((uint8_t)0x0BU) ///!< MPU Region Size 4 KBytes 42 | #define ARM_MPU_REGION_SIZE_8KB ((uint8_t)0x0CU) ///!< MPU Region Size 8 KBytes 43 | #define ARM_MPU_REGION_SIZE_16KB ((uint8_t)0x0DU) ///!< MPU Region Size 16 KBytes 44 | #define ARM_MPU_REGION_SIZE_32KB ((uint8_t)0x0EU) ///!< MPU Region Size 32 KBytes 45 | #define ARM_MPU_REGION_SIZE_64KB ((uint8_t)0x0FU) ///!< MPU Region Size 64 KBytes 46 | #define ARM_MPU_REGION_SIZE_128KB ((uint8_t)0x10U) ///!< MPU Region Size 128 KBytes 47 | #define ARM_MPU_REGION_SIZE_256KB ((uint8_t)0x11U) ///!< MPU Region Size 256 KBytes 48 | #define ARM_MPU_REGION_SIZE_512KB ((uint8_t)0x12U) ///!< MPU Region Size 512 KBytes 49 | #define ARM_MPU_REGION_SIZE_1MB ((uint8_t)0x13U) ///!< MPU Region Size 1 MByte 50 | #define ARM_MPU_REGION_SIZE_2MB ((uint8_t)0x14U) ///!< MPU Region Size 2 MBytes 51 | #define ARM_MPU_REGION_SIZE_4MB ((uint8_t)0x15U) ///!< MPU Region Size 4 MBytes 52 | #define ARM_MPU_REGION_SIZE_8MB ((uint8_t)0x16U) ///!< MPU Region Size 8 MBytes 53 | #define ARM_MPU_REGION_SIZE_16MB ((uint8_t)0x17U) ///!< MPU Region Size 16 MBytes 54 | #define ARM_MPU_REGION_SIZE_32MB ((uint8_t)0x18U) ///!< MPU Region Size 32 MBytes 55 | #define ARM_MPU_REGION_SIZE_64MB ((uint8_t)0x19U) ///!< MPU Region Size 64 MBytes 56 | #define ARM_MPU_REGION_SIZE_128MB ((uint8_t)0x1AU) ///!< MPU Region Size 128 MBytes 57 | #define ARM_MPU_REGION_SIZE_256MB ((uint8_t)0x1BU) ///!< MPU Region Size 256 MBytes 58 | #define ARM_MPU_REGION_SIZE_512MB ((uint8_t)0x1CU) ///!< MPU Region Size 512 MBytes 59 | #define ARM_MPU_REGION_SIZE_1GB ((uint8_t)0x1DU) ///!< MPU Region Size 1 GByte 60 | #define ARM_MPU_REGION_SIZE_2GB ((uint8_t)0x1EU) ///!< MPU Region Size 2 GBytes 61 | #define ARM_MPU_REGION_SIZE_4GB ((uint8_t)0x1FU) ///!< MPU Region Size 4 GBytes 62 | 63 | #define ARM_MPU_AP_NONE 0U ///!< MPU Access Permission no access 64 | #define ARM_MPU_AP_PRIV 1U ///!< MPU Access Permission privileged access only 65 | #define ARM_MPU_AP_URO 2U ///!< MPU Access Permission unprivileged access read-only 66 | #define ARM_MPU_AP_FULL 3U ///!< MPU Access Permission full access 67 | #define ARM_MPU_AP_PRO 5U ///!< MPU Access Permission privileged access read-only 68 | #define ARM_MPU_AP_RO 6U ///!< MPU Access Permission read-only access 69 | 70 | /** MPU Region Base Address Register Value 71 | * 72 | * \param Region The region to be configured, number 0 to 15. 73 | * \param BaseAddress The base address for the region. 74 | */ 75 | #define ARM_MPU_RBAR(Region, BaseAddress) \ 76 | (((BaseAddress)&MPU_RBAR_ADDR_Msk) | ((Region)&MPU_RBAR_REGION_Msk) | (MPU_RBAR_VALID_Msk)) 77 | 78 | /** 79 | * MPU Memory Access Attributes 80 | * 81 | * \param TypeExtField Type extension field, allows you to configure memory access type, 82 | * for example strongly ordered, peripheral. \param IsShareable Region is shareable 83 | * between multiple bus masters. \param IsCacheable Region is cacheable, i.e. its value 84 | * may be kept in cache. \param IsBufferable Region is bufferable, i.e. using write-back 85 | * caching. Cacheable but non-bufferable regions use write-through policy. 86 | */ 87 | #define ARM_MPU_ACCESS_(TypeExtField, IsShareable, IsCacheable, IsBufferable) \ 88 | ((((TypeExtField) << MPU_RASR_TEX_Pos) & MPU_RASR_TEX_Msk) \ 89 | | (((IsShareable) << MPU_RASR_S_Pos) & MPU_RASR_S_Msk) \ 90 | | (((IsCacheable) << MPU_RASR_C_Pos) & MPU_RASR_C_Msk) \ 91 | | (((IsBufferable) << MPU_RASR_B_Pos) & MPU_RASR_B_Msk)) 92 | 93 | /** 94 | * MPU Region Attribute and Size Register Value 95 | * 96 | * \param DisableExec Instruction access disable bit, 1= disable instruction fetches. 97 | * \param AccessPermission Data access permissions, allows you to configure read/write access 98 | * for User and Privileged mode. \param AccessAttributes Memory access attribution, see \ref 99 | * ARM_MPU_ACCESS_. \param SubRegionDisable Sub-region disable field. \param Size Region size 100 | * of the region to be configured, for example 4K, 8K. 101 | */ 102 | #define ARM_MPU_RASR_EX( \ 103 | DisableExec, AccessPermission, AccessAttributes, SubRegionDisable, Size) \ 104 | ((((DisableExec) << MPU_RASR_XN_Pos) & MPU_RASR_XN_Msk) \ 105 | | (((AccessPermission) << MPU_RASR_AP_Pos) & MPU_RASR_AP_Msk) \ 106 | | (((AccessAttributes)) \ 107 | & (MPU_RASR_TEX_Msk | MPU_RASR_S_Msk | MPU_RASR_C_Msk | MPU_RASR_B_Msk))) 108 | 109 | /** 110 | * MPU Region Attribute and Size Register Value 111 | * 112 | * \param DisableExec Instruction access disable bit, 1= disable instruction fetches. 113 | * \param AccessPermission Data access permissions, allows you to configure read/write access 114 | * for User and Privileged mode. \param TypeExtField Type extension field, allows you to 115 | * configure memory access type, for example strongly ordered, peripheral. \param IsShareable 116 | * Region is shareable between multiple bus masters. \param IsCacheable Region is 117 | * cacheable, i.e. its value may be kept in cache. \param IsBufferable Region is 118 | * bufferable, i.e. using write-back caching. Cacheable but non-bufferable regions use 119 | * write-through policy. \param SubRegionDisable Sub-region disable field. \param Size Region 120 | * size of the region to be configured, for example 4K, 8K. 121 | */ 122 | #define ARM_MPU_RASR( \ 123 | DisableExec, \ 124 | AccessPermission, \ 125 | TypeExtField, \ 126 | IsShareable, \ 127 | IsCacheable, \ 128 | IsBufferable, \ 129 | SubRegionDisable, \ 130 | Size) \ 131 | ARM_MPU_RASR_EX( \ 132 | DisableExec, \ 133 | AccessPermission, \ 134 | ARM_MPU_ACCESS_(TypeExtField, IsShareable, IsCacheable, IsBufferable), \ 135 | SubRegionDisable, \ 136 | Size) 137 | 138 | /** 139 | * MPU Memory Access Attribute for strongly ordered memory. 140 | * - TEX: 000b 141 | * - Shareable 142 | * - Non-cacheable 143 | * - Non-bufferable 144 | */ 145 | #define ARM_MPU_ACCESS_ORDERED ARM_MPU_ACCESS_(0U, 1U, 0U, 0U) 146 | 147 | /** 148 | * MPU Memory Access Attribute for device memory. 149 | * - TEX: 000b (if non-shareable) or 010b (if shareable) 150 | * - Shareable or non-shareable 151 | * - Non-cacheable 152 | * - Bufferable (if shareable) or non-bufferable (if non-shareable) 153 | * 154 | * \param IsShareable Configures the device memory as shareable or non-shareable. 155 | */ 156 | #define ARM_MPU_ACCESS_DEVICE(IsShareable) \ 157 | ((IsShareable) ? ARM_MPU_ACCESS_(0U, 1U, 0U, 1U) : ARM_MPU_ACCESS_(2U, 0U, 0U, 0U)) 158 | 159 | /** 160 | * MPU Memory Access Attribute for normal memory. 161 | * - TEX: 1BBb (reflecting outer cacheability rules) 162 | * - Shareable or non-shareable 163 | * - Cacheable or non-cacheable (reflecting inner cacheability rules) 164 | * - Bufferable or non-bufferable (reflecting inner cacheability rules) 165 | * 166 | * \param OuterCp Configures the outer cache policy. 167 | * \param InnerCp Configures the inner cache policy. 168 | * \param IsShareable Configures the memory as shareable or non-shareable. 169 | */ 170 | #define ARM_MPU_ACCESS_NORMAL(OuterCp, InnerCp, IsShareable) \ 171 | ARM_MPU_ACCESS_((4U | (OuterCp)), IsShareable, ((InnerCp)&2U), ((InnerCp)&1U)) 172 | 173 | /** 174 | * MPU Memory Access Attribute non-cacheable policy. 175 | */ 176 | #define ARM_MPU_CACHEP_NOCACHE 0U 177 | 178 | /** 179 | * MPU Memory Access Attribute write-back, write and read allocate policy. 180 | */ 181 | #define ARM_MPU_CACHEP_WB_WRA 1U 182 | 183 | /** 184 | * MPU Memory Access Attribute write-through, no write allocate policy. 185 | */ 186 | #define ARM_MPU_CACHEP_WT_NWA 2U 187 | 188 | /** 189 | * MPU Memory Access Attribute write-back, no write allocate policy. 190 | */ 191 | #define ARM_MPU_CACHEP_WB_NWA 3U 192 | 193 | /** 194 | * Struct for a single MPU Region 195 | */ 196 | typedef struct 197 | { 198 | uint32_t RBAR; //!< The region base address register value (RBAR) 199 | uint32_t RASR; //!< The region attribute and size register value (RASR) \ref MPU_RASR 200 | } ARM_MPU_Region_t; 201 | 202 | /** Enable the MPU. 203 | * \param MPU_Control Default access permissions for unconfigured regions. 204 | */ 205 | __STATIC_INLINE void ARM_MPU_Enable(uint32_t MPU_Control) 206 | { 207 | __DSB(); 208 | __ISB(); 209 | MPU->CTRL = MPU_Control | MPU_CTRL_ENABLE_Msk; 210 | #ifdef SCB_SHCSR_MEMFAULTENA_Msk 211 | SCB->SHCSR |= SCB_SHCSR_MEMFAULTENA_Msk; 212 | #endif 213 | } 214 | 215 | /** Disable the MPU. 216 | */ 217 | __STATIC_INLINE void ARM_MPU_Disable(void) 218 | { 219 | __DSB(); 220 | __ISB(); 221 | #ifdef SCB_SHCSR_MEMFAULTENA_Msk 222 | SCB->SHCSR &= ~SCB_SHCSR_MEMFAULTENA_Msk; 223 | #endif 224 | MPU->CTRL &= ~MPU_CTRL_ENABLE_Msk; 225 | } 226 | 227 | /** Clear and disable the given MPU region. 228 | * \param rnr Region number to be cleared. 229 | */ 230 | __STATIC_INLINE void ARM_MPU_ClrRegion(uint32_t rnr) 231 | { 232 | MPU->RNR = rnr; 233 | MPU->RASR = 0U; 234 | } 235 | 236 | /** Configure an MPU region. 237 | * \param rbar Value for RBAR register. 238 | * \param rsar Value for RSAR register. 239 | */ 240 | __STATIC_INLINE void ARM_MPU_SetRegion(uint32_t rbar, uint32_t rasr) 241 | { 242 | MPU->RBAR = rbar; 243 | MPU->RASR = rasr; 244 | } 245 | 246 | /** Configure the given MPU region. 247 | * \param rnr Region number to be configured. 248 | * \param rbar Value for RBAR register. 249 | * \param rsar Value for RSAR register. 250 | */ 251 | __STATIC_INLINE void ARM_MPU_SetRegionEx(uint32_t rnr, uint32_t rbar, uint32_t rasr) 252 | { 253 | MPU->RNR = rnr; 254 | MPU->RBAR = rbar; 255 | MPU->RASR = rasr; 256 | } 257 | 258 | /** Memcopy with strictly ordered memory access, e.g. for register targets. 259 | * \param dst Destination data is copied to. 260 | * \param src Source data is copied from. 261 | * \param len Amount of data words to be copied. 262 | */ 263 | __STATIC_INLINE void orderedCpy( 264 | volatile uint32_t* dst, const uint32_t* __RESTRICT src, uint32_t len) 265 | { 266 | uint32_t i; 267 | for (i = 0U; i < len; ++i) 268 | { 269 | dst[i] = src[i]; 270 | } 271 | } 272 | 273 | /** Load the given number of MPU regions from a table. 274 | * \param table Pointer to the MPU configuration table. 275 | * \param cnt Amount of regions to be configured. 276 | */ 277 | __STATIC_INLINE void ARM_MPU_Load(ARM_MPU_Region_t const* table, uint32_t cnt) 278 | { 279 | const uint32_t rowWordSize = sizeof(ARM_MPU_Region_t) / 4U; 280 | while (cnt > MPU_TYPE_RALIASES) 281 | { 282 | orderedCpy(&(MPU->RBAR), &(table->RBAR), MPU_TYPE_RALIASES * rowWordSize); 283 | table += MPU_TYPE_RALIASES; 284 | cnt -= MPU_TYPE_RALIASES; 285 | } 286 | orderedCpy(&(MPU->RBAR), &(table->RBAR), cnt * rowWordSize); 287 | } 288 | 289 | #endif 290 | -------------------------------------------------------------------------------- /Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_gpio.h: -------------------------------------------------------------------------------- 1 | /** 2 | ****************************************************************************** 3 | * @file stm32f4xx_hal_gpio.h 4 | * @author MCD Application Team 5 | * @brief Header file of GPIO HAL module. 6 | ****************************************************************************** 7 | * @attention 8 | * 9 | *

© Copyright (c) 2017 STMicroelectronics. 10 | * All rights reserved.

11 | * 12 | * This software component is licensed by ST under BSD 3-Clause license, 13 | * the "License"; You may not use this file except in compliance with the 14 | * License. You may obtain a copy of the License at: 15 | * opensource.org/licenses/BSD-3-Clause 16 | * 17 | ****************************************************************************** 18 | */ 19 | 20 | /* Define to prevent recursive inclusion -------------------------------------*/ 21 | #ifndef __STM32F4xx_HAL_GPIO_H 22 | #define __STM32F4xx_HAL_GPIO_H 23 | 24 | #ifdef __cplusplus 25 | extern "C" 26 | { 27 | #endif 28 | 29 | /* Includes ------------------------------------------------------------------*/ 30 | #include "stm32f4xx_hal_def.h" 31 | 32 | /** @addtogroup STM32F4xx_HAL_Driver 33 | * @{ 34 | */ 35 | 36 | /** @addtogroup GPIO 37 | * @{ 38 | */ 39 | 40 | /* Exported types ------------------------------------------------------------*/ 41 | /** @defgroup GPIO_Exported_Types GPIO Exported Types 42 | * @{ 43 | */ 44 | 45 | /** 46 | * @brief GPIO Init structure definition 47 | */ 48 | typedef struct 49 | { 50 | uint32_t Pin; /*!< Specifies the GPIO pins to be configured. 51 | This parameter can be any value of @ref GPIO_pins_define */ 52 | 53 | uint32_t Mode; /*!< Specifies the operating mode for the selected pins. 54 | This parameter can be a value of @ref GPIO_mode_define */ 55 | 56 | uint32_t Pull; /*!< Specifies the Pull-up or Pull-Down activation for the selected 57 | pins. This parameter can be a value of @ref GPIO_pull_define */ 58 | 59 | uint32_t Speed; /*!< Specifies the speed for the selected pins. 60 | This parameter can be a value of @ref GPIO_speed_define */ 61 | 62 | uint32_t Alternate; /*!< Peripheral to be connected to the selected pins. 63 | This parameter can be a value of @ref 64 | GPIO_Alternate_function_selection */ 65 | } GPIO_InitTypeDef; 66 | 67 | /** 68 | * @brief GPIO Bit SET and Bit RESET enumeration 69 | */ 70 | typedef enum 71 | { 72 | GPIO_PIN_RESET = 0, 73 | GPIO_PIN_SET 74 | } GPIO_PinState; 75 | /** 76 | * @} 77 | */ 78 | 79 | /* Exported constants --------------------------------------------------------*/ 80 | 81 | /** @defgroup GPIO_Exported_Constants GPIO Exported Constants 82 | * @{ 83 | */ 84 | 85 | /** @defgroup GPIO_pins_define GPIO pins define 86 | * @{ 87 | */ 88 | #define GPIO_PIN_0 ((uint16_t)0x0001) /* Pin 0 selected */ 89 | #define GPIO_PIN_1 ((uint16_t)0x0002) /* Pin 1 selected */ 90 | #define GPIO_PIN_2 ((uint16_t)0x0004) /* Pin 2 selected */ 91 | #define GPIO_PIN_3 ((uint16_t)0x0008) /* Pin 3 selected */ 92 | #define GPIO_PIN_4 ((uint16_t)0x0010) /* Pin 4 selected */ 93 | #define GPIO_PIN_5 ((uint16_t)0x0020) /* Pin 5 selected */ 94 | #define GPIO_PIN_6 ((uint16_t)0x0040) /* Pin 6 selected */ 95 | #define GPIO_PIN_7 ((uint16_t)0x0080) /* Pin 7 selected */ 96 | #define GPIO_PIN_8 ((uint16_t)0x0100) /* Pin 8 selected */ 97 | #define GPIO_PIN_9 ((uint16_t)0x0200) /* Pin 9 selected */ 98 | #define GPIO_PIN_10 ((uint16_t)0x0400) /* Pin 10 selected */ 99 | #define GPIO_PIN_11 ((uint16_t)0x0800) /* Pin 11 selected */ 100 | #define GPIO_PIN_12 ((uint16_t)0x1000) /* Pin 12 selected */ 101 | #define GPIO_PIN_13 ((uint16_t)0x2000) /* Pin 13 selected */ 102 | #define GPIO_PIN_14 ((uint16_t)0x4000) /* Pin 14 selected */ 103 | #define GPIO_PIN_15 ((uint16_t)0x8000) /* Pin 15 selected */ 104 | #define GPIO_PIN_All ((uint16_t)0xFFFF) /* All pins selected */ 105 | 106 | #define GPIO_PIN_MASK 0x0000FFFFU /* PIN mask for assert test */ 107 | /** 108 | * @} 109 | */ 110 | 111 | /** @defgroup GPIO_mode_define GPIO mode define 112 | * @brief GPIO Configuration Mode 113 | * Elements values convention: 0x00WX00YZ 114 | * - W : EXTI trigger detection on 3 bits 115 | * - X : EXTI mode (IT or Event) on 2 bits 116 | * - Y : Output type (Push Pull or Open Drain) on 1 bit 117 | * - Z : GPIO mode (Input, Output, Alternate or Analog) on 2 bits 118 | * @{ 119 | */ 120 | #define GPIO_MODE_INPUT MODE_INPUT /*!< Input Floating Mode */ 121 | #define GPIO_MODE_OUTPUT_PP \ 122 | (MODE_OUTPUT | OUTPUT_PP) /*!< Output Push Pull Mode */ 123 | #define GPIO_MODE_OUTPUT_OD \ 124 | (MODE_OUTPUT | OUTPUT_OD) /*!< Output Open Drain Mode */ 125 | #define GPIO_MODE_AF_PP (MODE_AF | OUTPUT_PP) /*!< Alternate Function Push Pull Mode */ 126 | #define GPIO_MODE_AF_OD (MODE_AF | OUTPUT_OD) /*!< Alternate Function Open Drain Mode */ 127 | 128 | #define GPIO_MODE_ANALOG MODE_ANALOG /*!< Analog Mode */ 129 | 130 | #define GPIO_MODE_IT_RISING \ 131 | (MODE_INPUT | EXTI_IT \ 132 | | TRIGGER_RISING) /*!< External Interrupt Mode with Rising edge trigger detection */ 133 | #define GPIO_MODE_IT_FALLING \ 134 | (MODE_INPUT | EXTI_IT \ 135 | | TRIGGER_FALLING) /*!< External Interrupt Mode with Falling edge trigger detection */ 136 | #define GPIO_MODE_IT_RISING_FALLING \ 137 | (MODE_INPUT | EXTI_IT | TRIGGER_RISING \ 138 | | TRIGGER_FALLING) /*!< External Interrupt Mode with Rising/Falling edge trigger \ 139 | detection */ 140 | 141 | #define GPIO_MODE_EVT_RISING \ 142 | (MODE_INPUT | EXTI_EVT \ 143 | | TRIGGER_RISING) /*!< External Event Mode with Rising edge trigger detection */ 144 | #define GPIO_MODE_EVT_FALLING \ 145 | (MODE_INPUT | EXTI_EVT \ 146 | | TRIGGER_FALLING) /*!< External Event Mode with Falling edge trigger detection */ 147 | #define GPIO_MODE_EVT_RISING_FALLING \ 148 | (MODE_INPUT | EXTI_EVT | TRIGGER_RISING \ 149 | | TRIGGER_FALLING) /*!< External Event Mode with Rising/Falling edge trigger detection \ 150 | */ 151 | 152 | /** 153 | * @} 154 | */ 155 | 156 | /** @defgroup GPIO_speed_define GPIO speed define 157 | * @brief GPIO Output Maximum frequency 158 | * @{ 159 | */ 160 | #define GPIO_SPEED_FREQ_LOW \ 161 | 0x00000000U /*!< IO works at 2 MHz, please refer to the product datasheet */ 162 | #define GPIO_SPEED_FREQ_MEDIUM \ 163 | 0x00000001U /*!< range 12,5 MHz to 50 MHz, please refer to the product datasheet */ 164 | #define GPIO_SPEED_FREQ_HIGH \ 165 | 0x00000002U /*!< range 25 MHz to 100 MHz, please refer to the product datasheet */ 166 | #define GPIO_SPEED_FREQ_VERY_HIGH \ 167 | 0x00000003U /*!< range 50 MHz to 200 MHz, please refer to the product datasheet */ 168 | /** 169 | * @} 170 | */ 171 | 172 | /** @defgroup GPIO_pull_define GPIO pull define 173 | * @brief GPIO Pull-Up or Pull-Down Activation 174 | * @{ 175 | */ 176 | #define GPIO_NOPULL 0x00000000U /*!< No Pull-up or Pull-down activation */ 177 | #define GPIO_PULLUP 0x00000001U /*!< Pull-up activation */ 178 | #define GPIO_PULLDOWN 0x00000002U /*!< Pull-down activation */ 179 | /** 180 | * @} 181 | */ 182 | 183 | /** 184 | * @} 185 | */ 186 | 187 | /* Exported macro ------------------------------------------------------------*/ 188 | /** @defgroup GPIO_Exported_Macros GPIO Exported Macros 189 | * @{ 190 | */ 191 | 192 | /** 193 | * @brief Checks whether the specified EXTI line flag is set or not. 194 | * @param __EXTI_LINE__ specifies the EXTI line flag to check. 195 | * This parameter can be GPIO_PIN_x where x can be(0..15) 196 | * @retval The new state of __EXTI_LINE__ (SET or RESET). 197 | */ 198 | #define __HAL_GPIO_EXTI_GET_FLAG(__EXTI_LINE__) (EXTI->PR & (__EXTI_LINE__)) 199 | 200 | /** 201 | * @brief Clears the EXTI's line pending flags. 202 | * @param __EXTI_LINE__ specifies the EXTI lines flags to clear. 203 | * This parameter can be any combination of GPIO_PIN_x where x can be (0..15) 204 | * @retval None 205 | */ 206 | #define __HAL_GPIO_EXTI_CLEAR_FLAG(__EXTI_LINE__) (EXTI->PR = (__EXTI_LINE__)) 207 | 208 | /** 209 | * @brief Checks whether the specified EXTI line is asserted or not. 210 | * @param __EXTI_LINE__ specifies the EXTI line to check. 211 | * This parameter can be GPIO_PIN_x where x can be(0..15) 212 | * @retval The new state of __EXTI_LINE__ (SET or RESET). 213 | */ 214 | #define __HAL_GPIO_EXTI_GET_IT(__EXTI_LINE__) (EXTI->PR & (__EXTI_LINE__)) 215 | 216 | /** 217 | * @brief Clears the EXTI's line pending bits. 218 | * @param __EXTI_LINE__ specifies the EXTI lines to clear. 219 | * This parameter can be any combination of GPIO_PIN_x where x can be (0..15) 220 | * @retval None 221 | */ 222 | #define __HAL_GPIO_EXTI_CLEAR_IT(__EXTI_LINE__) (EXTI->PR = (__EXTI_LINE__)) 223 | 224 | /** 225 | * @brief Generates a Software interrupt on selected EXTI line. 226 | * @param __EXTI_LINE__ specifies the EXTI line to check. 227 | * This parameter can be GPIO_PIN_x where x can be(0..15) 228 | * @retval None 229 | */ 230 | #define __HAL_GPIO_EXTI_GENERATE_SWIT(__EXTI_LINE__) (EXTI->SWIER |= (__EXTI_LINE__)) 231 | /** 232 | * @} 233 | */ 234 | 235 | /* Include GPIO HAL Extension module */ 236 | #include "stm32f4xx_hal_gpio_ex.h" 237 | 238 | /* Exported functions --------------------------------------------------------*/ 239 | /** @addtogroup GPIO_Exported_Functions 240 | * @{ 241 | */ 242 | 243 | /** @addtogroup GPIO_Exported_Functions_Group1 244 | * @{ 245 | */ 246 | /* Initialization and de-initialization functions *****************************/ 247 | void HAL_GPIO_Init(GPIO_TypeDef* GPIOx, GPIO_InitTypeDef* GPIO_Init); 248 | void HAL_GPIO_DeInit(GPIO_TypeDef* GPIOx, uint32_t GPIO_Pin); 249 | /** 250 | * @} 251 | */ 252 | 253 | /** @addtogroup GPIO_Exported_Functions_Group2 254 | * @{ 255 | */ 256 | /* IO operation functions *****************************************************/ 257 | GPIO_PinState HAL_GPIO_ReadPin(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin); 258 | void HAL_GPIO_WritePin(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin, GPIO_PinState PinState); 259 | void HAL_GPIO_TogglePin(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin); 260 | HAL_StatusTypeDef HAL_GPIO_LockPin(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin); 261 | void HAL_GPIO_EXTI_IRQHandler(uint16_t GPIO_Pin); 262 | void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin); 263 | 264 | /** 265 | * @} 266 | */ 267 | 268 | /** 269 | * @} 270 | */ 271 | /* Private types -------------------------------------------------------------*/ 272 | /* Private variables ---------------------------------------------------------*/ 273 | /* Private constants ---------------------------------------------------------*/ 274 | /** @defgroup GPIO_Private_Constants GPIO Private Constants 275 | * @{ 276 | */ 277 | #define GPIO_MODE_Pos 0U 278 | #define GPIO_MODE (0x3UL << GPIO_MODE_Pos) 279 | #define MODE_INPUT (0x0UL << GPIO_MODE_Pos) 280 | #define MODE_OUTPUT (0x1UL << GPIO_MODE_Pos) 281 | #define MODE_AF (0x2UL << GPIO_MODE_Pos) 282 | #define MODE_ANALOG (0x3UL << GPIO_MODE_Pos) 283 | #define OUTPUT_TYPE_Pos 4U 284 | #define OUTPUT_TYPE (0x1UL << OUTPUT_TYPE_Pos) 285 | #define OUTPUT_PP (0x0UL << OUTPUT_TYPE_Pos) 286 | #define OUTPUT_OD (0x1UL << OUTPUT_TYPE_Pos) 287 | #define EXTI_MODE_Pos 16U 288 | #define EXTI_MODE (0x3UL << EXTI_MODE_Pos) 289 | #define EXTI_IT (0x1UL << EXTI_MODE_Pos) 290 | #define EXTI_EVT (0x2UL << EXTI_MODE_Pos) 291 | #define TRIGGER_MODE_Pos 20U 292 | #define TRIGGER_MODE (0x7UL << TRIGGER_MODE_Pos) 293 | #define TRIGGER_RISING (0x1UL << TRIGGER_MODE_Pos) 294 | #define TRIGGER_FALLING (0x2UL << TRIGGER_MODE_Pos) 295 | 296 | /** 297 | * @} 298 | */ 299 | 300 | /* Private macros ------------------------------------------------------------*/ 301 | /** @defgroup GPIO_Private_Macros GPIO Private Macros 302 | * @{ 303 | */ 304 | #define IS_GPIO_PIN_ACTION(ACTION) (((ACTION) == GPIO_PIN_RESET) || ((ACTION) == GPIO_PIN_SET)) 305 | #define IS_GPIO_PIN(PIN) \ 306 | (((((uint32_t)PIN) & GPIO_PIN_MASK) != 0x00U) \ 307 | && ((((uint32_t)PIN) & ~GPIO_PIN_MASK) == 0x00U)) 308 | #define IS_GPIO_MODE(MODE) \ 309 | (((MODE) == GPIO_MODE_INPUT) || ((MODE) == GPIO_MODE_OUTPUT_PP) \ 310 | || ((MODE) == GPIO_MODE_OUTPUT_OD) || ((MODE) == GPIO_MODE_AF_PP) \ 311 | || ((MODE) == GPIO_MODE_AF_OD) || ((MODE) == GPIO_MODE_IT_RISING) \ 312 | || ((MODE) == GPIO_MODE_IT_FALLING) || ((MODE) == GPIO_MODE_IT_RISING_FALLING) \ 313 | || ((MODE) == GPIO_MODE_EVT_RISING) || ((MODE) == GPIO_MODE_EVT_FALLING) \ 314 | || ((MODE) == GPIO_MODE_EVT_RISING_FALLING) || ((MODE) == GPIO_MODE_ANALOG)) 315 | #define IS_GPIO_SPEED(SPEED) \ 316 | (((SPEED) == GPIO_SPEED_FREQ_LOW) || ((SPEED) == GPIO_SPEED_FREQ_MEDIUM) \ 317 | || ((SPEED) == GPIO_SPEED_FREQ_HIGH) || ((SPEED) == GPIO_SPEED_FREQ_VERY_HIGH)) 318 | #define IS_GPIO_PULL(PULL) \ 319 | (((PULL) == GPIO_NOPULL) || ((PULL) == GPIO_PULLUP) || ((PULL) == GPIO_PULLDOWN)) 320 | /** 321 | * @} 322 | */ 323 | 324 | /* Private functions ---------------------------------------------------------*/ 325 | /** @defgroup GPIO_Private_Functions GPIO Private Functions 326 | * @{ 327 | */ 328 | 329 | /** 330 | * @} 331 | */ 332 | 333 | /** 334 | * @} 335 | */ 336 | 337 | /** 338 | * @} 339 | */ 340 | 341 | #ifdef __cplusplus 342 | } 343 | #endif 344 | 345 | #endif /* __STM32F4xx_HAL_GPIO_H */ 346 | 347 | /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ 348 | -------------------------------------------------------------------------------- /Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_exti.h: -------------------------------------------------------------------------------- 1 | /** 2 | ****************************************************************************** 3 | * @file stm32f4xx_hal_exti.h 4 | * @author MCD Application Team 5 | * @brief Header file of EXTI HAL module. 6 | ****************************************************************************** 7 | * @attention 8 | * 9 | *

© Copyright (c) 2018 STMicroelectronics. 10 | * All rights reserved.

11 | * 12 | * This software component is licensed by ST under BSD 3-Clause license, 13 | * the "License"; You may not use this file except in compliance with the 14 | * License. You may obtain a copy of the License at: 15 | * opensource.org/licenses/BSD-3-Clause 16 | * 17 | ****************************************************************************** 18 | */ 19 | 20 | /* Define to prevent recursive inclusion -------------------------------------*/ 21 | #ifndef STM32f4xx_HAL_EXTI_H 22 | #define STM32f4xx_HAL_EXTI_H 23 | 24 | #ifdef __cplusplus 25 | extern "C" 26 | { 27 | #endif 28 | 29 | /* Includes ------------------------------------------------------------------*/ 30 | #include "stm32f4xx_hal_def.h" 31 | 32 | /** @addtogroup STM32F4xx_HAL_Driver 33 | * @{ 34 | */ 35 | 36 | /** @defgroup EXTI EXTI 37 | * @brief EXTI HAL module driver 38 | * @{ 39 | */ 40 | 41 | /* Exported types ------------------------------------------------------------*/ 42 | 43 | /** @defgroup EXTI_Exported_Types EXTI Exported Types 44 | * @{ 45 | */ 46 | typedef enum 47 | { 48 | HAL_EXTI_COMMON_CB_ID = 0x00U 49 | } EXTI_CallbackIDTypeDef; 50 | 51 | /** 52 | * @brief EXTI Handle structure definition 53 | */ 54 | typedef struct 55 | { 56 | uint32_t Line; /*!< Exti line number */ 57 | void (*PendingCallback)(void); /*!< Exti pending callback */ 58 | } EXTI_HandleTypeDef; 59 | 60 | /** 61 | * @brief EXTI Configuration structure definition 62 | */ 63 | typedef struct 64 | { 65 | uint32_t Line; /*!< The Exti line to be configured. This parameter 66 | can be a value of @ref EXTI_Line */ 67 | uint32_t Mode; /*!< The Exit Mode to be configured for a core. 68 | This parameter can be a combination of @ref EXTI_Mode */ 69 | uint32_t Trigger; /*!< The Exti Trigger to be configured. This parameter 70 | can be a value of @ref EXTI_Trigger */ 71 | uint32_t GPIOSel; /*!< The Exti GPIO multiplexer selection to be configured. 72 | This parameter is only possible for line 0 to 15. It 73 | can be a value of @ref EXTI_GPIOSel */ 74 | } EXTI_ConfigTypeDef; 75 | 76 | /** 77 | * @} 78 | */ 79 | 80 | /* Exported constants --------------------------------------------------------*/ 81 | /** @defgroup EXTI_Exported_Constants EXTI Exported Constants 82 | * @{ 83 | */ 84 | 85 | /** @defgroup EXTI_Line EXTI Line 86 | * @{ 87 | */ 88 | #define EXTI_LINE_0 (EXTI_GPIO | 0x00u) /*!< External interrupt line 0 */ 89 | #define EXTI_LINE_1 (EXTI_GPIO | 0x01u) /*!< External interrupt line 1 */ 90 | #define EXTI_LINE_2 (EXTI_GPIO | 0x02u) /*!< External interrupt line 2 */ 91 | #define EXTI_LINE_3 (EXTI_GPIO | 0x03u) /*!< External interrupt line 3 */ 92 | #define EXTI_LINE_4 (EXTI_GPIO | 0x04u) /*!< External interrupt line 4 */ 93 | #define EXTI_LINE_5 (EXTI_GPIO | 0x05u) /*!< External interrupt line 5 */ 94 | #define EXTI_LINE_6 (EXTI_GPIO | 0x06u) /*!< External interrupt line 6 */ 95 | #define EXTI_LINE_7 (EXTI_GPIO | 0x07u) /*!< External interrupt line 7 */ 96 | #define EXTI_LINE_8 (EXTI_GPIO | 0x08u) /*!< External interrupt line 8 */ 97 | #define EXTI_LINE_9 (EXTI_GPIO | 0x09u) /*!< External interrupt line 9 */ 98 | #define EXTI_LINE_10 (EXTI_GPIO | 0x0Au) /*!< External interrupt line 10 */ 99 | #define EXTI_LINE_11 (EXTI_GPIO | 0x0Bu) /*!< External interrupt line 11 */ 100 | #define EXTI_LINE_12 (EXTI_GPIO | 0x0Cu) /*!< External interrupt line 12 */ 101 | #define EXTI_LINE_13 (EXTI_GPIO | 0x0Du) /*!< External interrupt line 13 */ 102 | #define EXTI_LINE_14 (EXTI_GPIO | 0x0Eu) /*!< External interrupt line 14 */ 103 | #define EXTI_LINE_15 (EXTI_GPIO | 0x0Fu) /*!< External interrupt line 15 */ 104 | #define EXTI_LINE_16 \ 105 | (EXTI_CONFIG | 0x10u) /*!< External interrupt line 16 Connected to the PVD Output */ 106 | #define EXTI_LINE_17 \ 107 | (EXTI_CONFIG | 0x11u) /*!< External interrupt line 17 Connected to the RTC Alarm event */ 108 | #if defined(EXTI_IMR_IM18) 109 | #define EXTI_LINE_18 \ 110 | (EXTI_CONFIG | 0x12u) /*!< External interrupt line 18 Connected to the USB OTG FS Wakeup \ 111 | from suspend event */ 112 | #else 113 | #define EXTI_LINE_18 (EXTI_RESERVED | 0x12u) /*!< No interrupt supported in this line */ 114 | #endif /* EXTI_IMR_IM18 */ 115 | #if defined(EXTI_IMR_IM19) 116 | #define EXTI_LINE_19 \ 117 | (EXTI_CONFIG \ 118 | | 0x13u) /*!< External interrupt line 19 Connected to the Ethernet Wakeup event */ 119 | #else 120 | #define EXTI_LINE_19 (EXTI_RESERVED | 0x13u) /*!< No interrupt supported in this line */ 121 | #endif /* EXTI_IMR_IM19 */ 122 | #if defined(EXTI_IMR_IM20) 123 | #define EXTI_LINE_20 \ 124 | (EXTI_CONFIG | 0x14u) /*!< External interrupt line 20 Connected to the USB OTG HS \ 125 | (configured in FS) Wakeup event */ 126 | #else 127 | #define EXTI_LINE_20 (EXTI_RESERVED | 0x14u) /*!< No interrupt supported in this line */ 128 | #endif /* EXTI_IMR_IM20 */ 129 | #define EXTI_LINE_21 \ 130 | (EXTI_CONFIG | 0x15u) /*!< External interrupt line 21 Connected to the RTC Tamper and \ 131 | Time Stamp events */ 132 | #define EXTI_LINE_22 \ 133 | (EXTI_CONFIG | 0x16u) /*!< External interrupt line 22 Connected to the RTC Wakeup event \ 134 | */ 135 | #if defined(EXTI_IMR_IM23) 136 | #define EXTI_LINE_23 \ 137 | (EXTI_CONFIG \ 138 | | 0x17u) /*!< External interrupt line 23 Connected to the LPTIM1 asynchronous event */ 139 | #endif /* EXTI_IMR_IM23 */ 140 | 141 | /** 142 | * @} 143 | */ 144 | 145 | /** @defgroup EXTI_Mode EXTI Mode 146 | * @{ 147 | */ 148 | #define EXTI_MODE_NONE 0x00000000u 149 | #define EXTI_MODE_INTERRUPT 0x00000001u 150 | #define EXTI_MODE_EVENT 0x00000002u 151 | /** 152 | * @} 153 | */ 154 | 155 | /** @defgroup EXTI_Trigger EXTI Trigger 156 | * @{ 157 | */ 158 | 159 | #define EXTI_TRIGGER_NONE 0x00000000u 160 | #define EXTI_TRIGGER_RISING 0x00000001u 161 | #define EXTI_TRIGGER_FALLING 0x00000002u 162 | #define EXTI_TRIGGER_RISING_FALLING (EXTI_TRIGGER_RISING | EXTI_TRIGGER_FALLING) 163 | /** 164 | * @} 165 | */ 166 | 167 | /** @defgroup EXTI_GPIOSel EXTI GPIOSel 168 | * @brief 169 | * @{ 170 | */ 171 | #define EXTI_GPIOA 0x00000000u 172 | #define EXTI_GPIOB 0x00000001u 173 | #define EXTI_GPIOC 0x00000002u 174 | #if defined(GPIOD) 175 | #define EXTI_GPIOD 0x00000003u 176 | #endif /* GPIOD */ 177 | #if defined(GPIOE) 178 | #define EXTI_GPIOE 0x00000004u 179 | #endif /* GPIOE */ 180 | #if defined(GPIOF) 181 | #define EXTI_GPIOF 0x00000005u 182 | #endif /* GPIOF */ 183 | #if defined(GPIOG) 184 | #define EXTI_GPIOG 0x00000006u 185 | #endif /* GPIOG */ 186 | #if defined(GPIOH) 187 | #define EXTI_GPIOH 0x00000007u 188 | #endif /* GPIOH */ 189 | #if defined(GPIOI) 190 | #define EXTI_GPIOI 0x00000008u 191 | #endif /* GPIOI */ 192 | #if defined(GPIOJ) 193 | #define EXTI_GPIOJ 0x00000009u 194 | #endif /* GPIOJ */ 195 | #if defined(GPIOK) 196 | #define EXTI_GPIOK 0x0000000Au 197 | #endif /* GPIOK */ 198 | 199 | /** 200 | * @} 201 | */ 202 | 203 | /** 204 | * @} 205 | */ 206 | 207 | /* Exported macro ------------------------------------------------------------*/ 208 | /** @defgroup EXTI_Exported_Macros EXTI Exported Macros 209 | * @{ 210 | */ 211 | 212 | /** 213 | * @} 214 | */ 215 | 216 | /* Private constants --------------------------------------------------------*/ 217 | /** @defgroup EXTI_Private_Constants EXTI Private Constants 218 | * @{ 219 | */ 220 | /** 221 | * @brief EXTI Line property definition 222 | */ 223 | #define EXTI_PROPERTY_SHIFT 24u 224 | #define EXTI_CONFIG (0x02uL << EXTI_PROPERTY_SHIFT) 225 | #define EXTI_GPIO ((0x04uL << EXTI_PROPERTY_SHIFT) | EXTI_CONFIG) 226 | #define EXTI_RESERVED (0x08uL << EXTI_PROPERTY_SHIFT) 227 | #define EXTI_PROPERTY_MASK (EXTI_CONFIG | EXTI_GPIO) 228 | 229 | /** 230 | * @brief EXTI bit usage 231 | */ 232 | #define EXTI_PIN_MASK 0x0000001Fu 233 | 234 | /** 235 | * @brief EXTI Mask for interrupt & event mode 236 | */ 237 | #define EXTI_MODE_MASK (EXTI_MODE_EVENT | EXTI_MODE_INTERRUPT) 238 | 239 | /** 240 | * @brief EXTI Mask for trigger possibilities 241 | */ 242 | #define EXTI_TRIGGER_MASK (EXTI_TRIGGER_RISING | EXTI_TRIGGER_FALLING) 243 | 244 | /** 245 | * @brief EXTI Line number 246 | */ 247 | #if defined(EXTI_IMR_IM23) 248 | #define EXTI_LINE_NB 24UL 249 | #else 250 | #define EXTI_LINE_NB 23UL 251 | #endif /* EXTI_IMR_IM23 */ 252 | 253 | /** 254 | * @} 255 | */ 256 | 257 | /* Private macros ------------------------------------------------------------*/ 258 | /** @defgroup EXTI_Private_Macros EXTI Private Macros 259 | * @{ 260 | */ 261 | #define IS_EXTI_LINE(__EXTI_LINE__) \ 262 | ((((__EXTI_LINE__) & ~(EXTI_PROPERTY_MASK | EXTI_PIN_MASK)) == 0x00u) \ 263 | && ((((__EXTI_LINE__)&EXTI_PROPERTY_MASK) == EXTI_CONFIG) \ 264 | || (((__EXTI_LINE__)&EXTI_PROPERTY_MASK) == EXTI_GPIO)) \ 265 | && (((__EXTI_LINE__)&EXTI_PIN_MASK) < EXTI_LINE_NB)) 266 | 267 | #define IS_EXTI_MODE(__EXTI_LINE__) \ 268 | ((((__EXTI_LINE__)&EXTI_MODE_MASK) != 0x00u) \ 269 | && (((__EXTI_LINE__) & ~EXTI_MODE_MASK) == 0x00u)) 270 | 271 | #define IS_EXTI_TRIGGER(__EXTI_LINE__) (((__EXTI_LINE__) & ~EXTI_TRIGGER_MASK) == 0x00u) 272 | 273 | #define IS_EXTI_PENDING_EDGE(__EXTI_LINE__) ((__EXTI_LINE__) == EXTI_TRIGGER_RISING_FALLING) 274 | 275 | #define IS_EXTI_CONFIG_LINE(__EXTI_LINE__) (((__EXTI_LINE__)&EXTI_CONFIG) != 0x00u) 276 | 277 | #if !defined(GPIOD) 278 | #define IS_EXTI_GPIO_PORT(__PORT__) \ 279 | (((__PORT__) == EXTI_GPIOA) || ((__PORT__) == EXTI_GPIOB) || ((__PORT__) == EXTI_GPIOC) \ 280 | || ((__PORT__) == EXTI_GPIOH)) 281 | #elif !defined(GPIOE) 282 | #define IS_EXTI_GPIO_PORT(__PORT__) \ 283 | (((__PORT__) == EXTI_GPIOA) || ((__PORT__) == EXTI_GPIOB) || ((__PORT__) == EXTI_GPIOC) \ 284 | || ((__PORT__) == EXTI_GPIOD) || ((__PORT__) == EXTI_GPIOH)) 285 | #elif !defined(GPIOF) 286 | #define IS_EXTI_GPIO_PORT(__PORT__) \ 287 | (((__PORT__) == EXTI_GPIOA) || ((__PORT__) == EXTI_GPIOB) || ((__PORT__) == EXTI_GPIOC) \ 288 | || ((__PORT__) == EXTI_GPIOD) || ((__PORT__) == EXTI_GPIOE) \ 289 | || ((__PORT__) == EXTI_GPIOH)) 290 | #elif !defined(GPIOI) 291 | #define IS_EXTI_GPIO_PORT(__PORT__) \ 292 | (((__PORT__) == EXTI_GPIOA) || ((__PORT__) == EXTI_GPIOB) || ((__PORT__) == EXTI_GPIOC) \ 293 | || ((__PORT__) == EXTI_GPIOD) || ((__PORT__) == EXTI_GPIOE) \ 294 | || ((__PORT__) == EXTI_GPIOF) || ((__PORT__) == EXTI_GPIOG) \ 295 | || ((__PORT__) == EXTI_GPIOH)) 296 | #elif !defined(GPIOJ) 297 | #define IS_EXTI_GPIO_PORT(__PORT__) \ 298 | (((__PORT__) == EXTI_GPIOA) || ((__PORT__) == EXTI_GPIOB) || ((__PORT__) == EXTI_GPIOC) \ 299 | || ((__PORT__) == EXTI_GPIOD) || ((__PORT__) == EXTI_GPIOE) \ 300 | || ((__PORT__) == EXTI_GPIOF) || ((__PORT__) == EXTI_GPIOG) \ 301 | || ((__PORT__) == EXTI_GPIOH) || ((__PORT__) == EXTI_GPIOI)) 302 | #else 303 | #define IS_EXTI_GPIO_PORT(__PORT__) \ 304 | (((__PORT__) == EXTI_GPIOA) || ((__PORT__) == EXTI_GPIOB) || ((__PORT__) == EXTI_GPIOC) \ 305 | || ((__PORT__) == EXTI_GPIOD) || ((__PORT__) == EXTI_GPIOE) \ 306 | || ((__PORT__) == EXTI_GPIOF) || ((__PORT__) == EXTI_GPIOG) \ 307 | || ((__PORT__) == EXTI_GPIOH) || ((__PORT__) == EXTI_GPIOI) \ 308 | || ((__PORT__) == EXTI_GPIOJ) || ((__PORT__) == EXTI_GPIOK)) 309 | #endif /* GPIOD */ 310 | 311 | #define IS_EXTI_GPIO_PIN(__PIN__) ((__PIN__) < 16U) 312 | /** 313 | * @} 314 | */ 315 | 316 | /* Exported functions --------------------------------------------------------*/ 317 | /** @defgroup EXTI_Exported_Functions EXTI Exported Functions 318 | * @brief EXTI Exported Functions 319 | * @{ 320 | */ 321 | 322 | /** @defgroup EXTI_Exported_Functions_Group1 Configuration functions 323 | * @brief Configuration functions 324 | * @{ 325 | */ 326 | /* Configuration functions ****************************************************/ 327 | HAL_StatusTypeDef HAL_EXTI_SetConfigLine( 328 | EXTI_HandleTypeDef* hexti, EXTI_ConfigTypeDef* pExtiConfig); 329 | HAL_StatusTypeDef HAL_EXTI_GetConfigLine( 330 | EXTI_HandleTypeDef* hexti, EXTI_ConfigTypeDef* pExtiConfig); 331 | HAL_StatusTypeDef HAL_EXTI_ClearConfigLine(EXTI_HandleTypeDef* hexti); 332 | HAL_StatusTypeDef HAL_EXTI_RegisterCallback( 333 | EXTI_HandleTypeDef* hexti, 334 | EXTI_CallbackIDTypeDef CallbackID, 335 | void (*pPendingCbfn)(void)); 336 | HAL_StatusTypeDef HAL_EXTI_GetHandle(EXTI_HandleTypeDef* hexti, uint32_t ExtiLine); 337 | /** 338 | * @} 339 | */ 340 | 341 | /** @defgroup EXTI_Exported_Functions_Group2 IO operation functions 342 | * @brief IO operation functions 343 | * @{ 344 | */ 345 | /* IO operation functions *****************************************************/ 346 | void HAL_EXTI_IRQHandler(EXTI_HandleTypeDef* hexti); 347 | uint32_t HAL_EXTI_GetPending(EXTI_HandleTypeDef* hexti, uint32_t Edge); 348 | void HAL_EXTI_ClearPending(EXTI_HandleTypeDef* hexti, uint32_t Edge); 349 | void HAL_EXTI_GenerateSWI(EXTI_HandleTypeDef* hexti); 350 | 351 | /** 352 | * @} 353 | */ 354 | 355 | /** 356 | * @} 357 | */ 358 | 359 | /** 360 | * @} 361 | */ 362 | 363 | /** 364 | * @} 365 | */ 366 | 367 | #ifdef __cplusplus 368 | } 369 | #endif 370 | 371 | #endif /* STM32f4xx_HAL_EXTI_H */ 372 | 373 | /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ 374 | --------------------------------------------------------------------------------