Import YEEP-144 library 1.2 sources
Source-only snapshot of the 1.2 release. Drivers/ (the vendored ST HAL and CMSIS) is excluded at 173 MB; fetch it from STMicroelectronics/STM32CubeH5 to build.
This commit is contained in:
11
.clangd
Normal file
11
.clangd
Normal file
@@ -0,0 +1,11 @@
|
||||
CompileFlags:
|
||||
Add:
|
||||
- -ferror-limit=0
|
||||
- -Wno-implicit-int
|
||||
CompilationDatabase: build/Debug
|
||||
Diagnostics:
|
||||
Suppress:
|
||||
- unused-includes
|
||||
- unknown_typename
|
||||
- unknown_typename_suggest
|
||||
- typename_requires_specqual
|
||||
2
.gitattributes
vendored
Normal file
2
.gitattributes
vendored
Normal file
@@ -0,0 +1,2 @@
|
||||
# Auto detect text files and perform LF normalization
|
||||
* text=auto
|
||||
10
.gitignore
vendored
Normal file
10
.gitignore
vendored
Normal file
@@ -0,0 +1,10 @@
|
||||
build
|
||||
!.settings
|
||||
*.code-workspace
|
||||
|
||||
# Vendored ST HAL/CMSIS - not part of the YEEP library, 173 MB, of which 108 MB
|
||||
# is ST's .chm user manuals. Get it from STMicroelectronics/STM32CubeH5.
|
||||
Drivers/
|
||||
|
||||
# macOS
|
||||
.DS_Store
|
||||
290
.settings/bundles-lock.store.json
Normal file
290
.settings/bundles-lock.store.json
Normal file
@@ -0,0 +1,290 @@
|
||||
{
|
||||
"resolved": [
|
||||
{
|
||||
"name": "cmake",
|
||||
"version": "4.2.3+st.1",
|
||||
"platform": "darwin",
|
||||
"selected_by": [
|
||||
{
|
||||
"name": "cmake",
|
||||
"version": "4.2.3+st.1"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "cmake",
|
||||
"version": "4.2.3+st.1",
|
||||
"platform": "x86_64-linux",
|
||||
"selected_by": [
|
||||
{
|
||||
"name": "cmake",
|
||||
"version": "4.2.3+st.1"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "cmake",
|
||||
"version": "4.2.3+st.1",
|
||||
"platform": "x86_64-windows",
|
||||
"selected_by": [
|
||||
{
|
||||
"name": "cmake",
|
||||
"version": "4.2.3+st.1"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "gnu-gdb-for-stm32",
|
||||
"version": "14.3.1+st.2",
|
||||
"platform": "aarch64-darwin",
|
||||
"selected_by": [
|
||||
{
|
||||
"name": "gnu-gdb-for-stm32",
|
||||
"version": "14.3.1+st.2"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "gnu-gdb-for-stm32",
|
||||
"version": "14.3.1+st.2",
|
||||
"platform": "x86_64-darwin",
|
||||
"selected_by": [
|
||||
{
|
||||
"name": "gnu-gdb-for-stm32",
|
||||
"version": "14.3.1+st.2"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "gnu-gdb-for-stm32",
|
||||
"version": "14.3.1+st.2",
|
||||
"platform": "x86_64-linux",
|
||||
"selected_by": [
|
||||
{
|
||||
"name": "gnu-gdb-for-stm32",
|
||||
"version": "14.3.1+st.2"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "gnu-gdb-for-stm32",
|
||||
"version": "14.3.1+st.2",
|
||||
"platform": "x86_64-windows",
|
||||
"selected_by": [
|
||||
{
|
||||
"name": "gnu-gdb-for-stm32",
|
||||
"version": "14.3.1+st.2"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "gnu-tools-for-stm32",
|
||||
"version": "14.3.1+st.2",
|
||||
"platform": "aarch64-darwin",
|
||||
"selected_by": [
|
||||
{
|
||||
"name": "gnu-tools-for-stm32",
|
||||
"version": "14.3.1+st.2"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "gnu-tools-for-stm32",
|
||||
"version": "14.3.1+st.2",
|
||||
"platform": "x86_64-darwin",
|
||||
"selected_by": [
|
||||
{
|
||||
"name": "gnu-tools-for-stm32",
|
||||
"version": "14.3.1+st.2"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "gnu-tools-for-stm32",
|
||||
"version": "14.3.1+st.2",
|
||||
"platform": "x86_64-linux",
|
||||
"selected_by": [
|
||||
{
|
||||
"name": "gnu-tools-for-stm32",
|
||||
"version": "14.3.1+st.2"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "gnu-tools-for-stm32",
|
||||
"version": "14.3.1+st.2",
|
||||
"platform": "x86_64-windows",
|
||||
"selected_by": [
|
||||
{
|
||||
"name": "gnu-tools-for-stm32",
|
||||
"version": "14.3.1+st.2"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "gnu-tools-for-stm32-14_3_1-description",
|
||||
"version": "1.0.1+st.2",
|
||||
"platform": "all",
|
||||
"selected_by": [
|
||||
{
|
||||
"name": "gnu-tools-for-stm32-14_3_1-description",
|
||||
"version": ">=0.0.1"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "ninja",
|
||||
"version": "1.13.2+st.1",
|
||||
"platform": "darwin",
|
||||
"selected_by": [
|
||||
{
|
||||
"name": "ninja",
|
||||
"version": "1.13.2+st.1"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "ninja",
|
||||
"version": "1.13.2+st.1",
|
||||
"platform": "x86_64-linux",
|
||||
"selected_by": [
|
||||
{
|
||||
"name": "ninja",
|
||||
"version": "1.13.2+st.1"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "ninja",
|
||||
"version": "1.13.2+st.1",
|
||||
"platform": "x86_64-windows",
|
||||
"selected_by": [
|
||||
{
|
||||
"name": "ninja",
|
||||
"version": "1.13.2+st.1"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "programmer",
|
||||
"version": "2.22.0+st.1",
|
||||
"platform": "aarch64-darwin",
|
||||
"selected_by": [
|
||||
{
|
||||
"name": "programmer",
|
||||
"version": "2.22.0+st.1"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "programmer",
|
||||
"version": "2.22.0+st.1",
|
||||
"platform": "darwin",
|
||||
"selected_by": [
|
||||
{
|
||||
"name": "programmer",
|
||||
"version": "2.22.0+st.1"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "programmer",
|
||||
"version": "2.22.0+st.1",
|
||||
"platform": "x86_64-linux",
|
||||
"selected_by": [
|
||||
{
|
||||
"name": "programmer",
|
||||
"version": "2.22.0+st.1"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "programmer",
|
||||
"version": "2.22.0+st.1",
|
||||
"platform": "x86_64-windows",
|
||||
"selected_by": [
|
||||
{
|
||||
"name": "programmer",
|
||||
"version": "2.22.0+st.1"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "st-arm-clangd",
|
||||
"version": "21.1.0+st.2",
|
||||
"platform": "darwin",
|
||||
"selected_by": [
|
||||
{
|
||||
"name": "st-arm-clangd",
|
||||
"version": "21.1.0+st.2"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "st-arm-clangd",
|
||||
"version": "21.1.0+st.2",
|
||||
"platform": "x86_64-linux",
|
||||
"selected_by": [
|
||||
{
|
||||
"name": "st-arm-clangd",
|
||||
"version": "21.1.0+st.2"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "st-arm-clangd",
|
||||
"version": "21.1.0+st.2",
|
||||
"platform": "x86_64-windows",
|
||||
"selected_by": [
|
||||
{
|
||||
"name": "st-arm-clangd",
|
||||
"version": "21.1.0+st.2"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "stlink-gdbserver",
|
||||
"version": "7.13.0+st.3",
|
||||
"platform": "aarch64-darwin",
|
||||
"selected_by": [
|
||||
{
|
||||
"name": "stlink-gdbserver",
|
||||
"version": "7.13.0+st.3"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "stlink-gdbserver",
|
||||
"version": "7.13.0+st.3",
|
||||
"platform": "darwin",
|
||||
"selected_by": [
|
||||
{
|
||||
"name": "stlink-gdbserver",
|
||||
"version": "7.13.0+st.3"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "stlink-gdbserver",
|
||||
"version": "7.13.0+st.3",
|
||||
"platform": "x86_64-linux",
|
||||
"selected_by": [
|
||||
{
|
||||
"name": "stlink-gdbserver",
|
||||
"version": "7.13.0+st.3"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "stlink-gdbserver",
|
||||
"version": "7.13.0+st.3",
|
||||
"platform": "x86_64-windows",
|
||||
"selected_by": [
|
||||
{
|
||||
"name": "stlink-gdbserver",
|
||||
"version": "7.13.0+st.3"
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
32
.settings/bundles.store.json
Normal file
32
.settings/bundles.store.json
Normal file
@@ -0,0 +1,32 @@
|
||||
{
|
||||
"bundles": [
|
||||
{
|
||||
"name": "st-arm-clangd",
|
||||
"version": "21.1.0+st.2"
|
||||
},
|
||||
{
|
||||
"name": "cmake",
|
||||
"version": "4.2.3+st.1"
|
||||
},
|
||||
{
|
||||
"name": "ninja",
|
||||
"version": "1.13.2+st.1"
|
||||
},
|
||||
{
|
||||
"name": "gnu-tools-for-stm32",
|
||||
"version": "14.3.1+st.2"
|
||||
},
|
||||
{
|
||||
"name": "programmer",
|
||||
"version": "2.22.0+st.1"
|
||||
},
|
||||
{
|
||||
"name": "stlink-gdbserver",
|
||||
"version": "7.13.0+st.3"
|
||||
},
|
||||
{
|
||||
"name": "gnu-gdb-for-stm32",
|
||||
"version": "14.3.1+st.2"
|
||||
}
|
||||
]
|
||||
}
|
||||
11
.settings/ide.store.json
Normal file
11
.settings/ide.store.json
Normal file
@@ -0,0 +1,11 @@
|
||||
{
|
||||
"board": "NUCLEO-H563ZI",
|
||||
"device": "STM32H563ZIT6",
|
||||
"core": "Cortex-M33",
|
||||
"order": 0,
|
||||
"toolchain": "GCC",
|
||||
"source": {
|
||||
"sourceType": "Empty"
|
||||
},
|
||||
"tz": "TZ-disabled"
|
||||
}
|
||||
8
.vscode/c_cpp_properties.json
vendored
Normal file
8
.vscode/c_cpp_properties.json
vendored
Normal file
@@ -0,0 +1,8 @@
|
||||
{
|
||||
"configurations": [
|
||||
{
|
||||
"name": "STM32",
|
||||
"compileCommands": "${workspaceFolder}/build/Debug/compile_commands.json"
|
||||
}
|
||||
]
|
||||
}
|
||||
22
.vscode/launch.json
vendored
Normal file
22
.vscode/launch.json
vendored
Normal file
@@ -0,0 +1,22 @@
|
||||
{
|
||||
// Use IntelliSense to learn about possible attributes.
|
||||
// Hover to view descriptions of existing attributes.
|
||||
// For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
|
||||
"version": "0.2.0",
|
||||
"configurations": [
|
||||
{
|
||||
"type": "stlinkgdbtarget",
|
||||
"request": "launch",
|
||||
"name": "STM32Cube: Launch ST-Link GDB Server",
|
||||
"origin": "snippet",
|
||||
"cwd": "${workspaceFolder}",
|
||||
"preBuild": "${command:st-stm32-ide-debug-launch.build}",
|
||||
"runEntry": "main",
|
||||
"imagesAndSymbols": [
|
||||
{
|
||||
"imageFileName": "${command:st-stm32-ide-debug-launch.get-projects-binary-from-context1}"
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
15
.vscode/settings.json
vendored
Normal file
15
.vscode/settings.json
vendored
Normal file
@@ -0,0 +1,15 @@
|
||||
{
|
||||
"cmake.cmakePath": "cube-cmake",
|
||||
"cmake.configureArgs": [
|
||||
"-DCMAKE_COMMAND=cube-cmake"
|
||||
],
|
||||
"cmake.preferredGenerators": [
|
||||
"Ninja"
|
||||
],
|
||||
"stm32cube-ide-clangd.path": "cube",
|
||||
"stm32cube-ide-clangd.arguments": [
|
||||
"starm-clangd",
|
||||
"--query-driver=${env:CUBE_BUNDLE_PATH}/gnu-tools-for-stm32/14.3.1+st.2/bin/arm-none-eabi-gcc*",
|
||||
"--query-driver=${env:CUBE_BUNDLE_PATH}/gnu-tools-for-stm32/14.3.1+st.2/bin/arm-none-eabi-g++*"
|
||||
]
|
||||
}
|
||||
65
.vscode/tasks.json
vendored
Normal file
65
.vscode/tasks.json
vendored
Normal file
@@ -0,0 +1,65 @@
|
||||
{
|
||||
"version": "2.0.0",
|
||||
"tasks": [
|
||||
{
|
||||
"type": "shell",
|
||||
"label": "CubeProg: Flash project (SWD)",
|
||||
"command": "cube",
|
||||
"args": [
|
||||
"programmer",
|
||||
"--connect",
|
||||
"port=swd",
|
||||
"--download",
|
||||
"${command:cmake.launchTargetPath}",
|
||||
"-hardRst",
|
||||
"-rst",
|
||||
"--start"
|
||||
],
|
||||
"options": {
|
||||
"cwd": "${workspaceFolder}"
|
||||
},
|
||||
"problemMatcher": [],
|
||||
"presentation": {
|
||||
"showReuseMessage": false
|
||||
}
|
||||
},
|
||||
{
|
||||
"label": "Build + Flash",
|
||||
"dependsOrder": "sequence",
|
||||
"dependsOn": [
|
||||
"CMake: clean rebuild",
|
||||
"CubeProg: Flash project (SWD)"
|
||||
],
|
||||
"problemMatcher": [
|
||||
"$gcc"
|
||||
],
|
||||
"presentation": {
|
||||
"showReuseMessage": false
|
||||
}
|
||||
},
|
||||
{
|
||||
"type": "cmake",
|
||||
"label": "CMake: clean rebuild",
|
||||
"command": "cleanRebuild",
|
||||
"targets": [
|
||||
"all"
|
||||
],
|
||||
"preset": "Debug",
|
||||
"group": "build",
|
||||
"problemMatcher": [],
|
||||
"detail": "CMake template clean rebuild task"
|
||||
},
|
||||
{
|
||||
"type": "cmake",
|
||||
"label": "CMake: configure",
|
||||
"command": "configure",
|
||||
"preset": "Debug",
|
||||
"problemMatcher": [],
|
||||
"detail": "CMake template configure task"
|
||||
},
|
||||
{
|
||||
"label": "Configure and Build",
|
||||
"dependsOn": ["CMake: configure", "${command:st-stm32-ide-debug-launch.build}"],
|
||||
"dependsOrder": "sequence"}
|
||||
]
|
||||
}
|
||||
188
CMakeLists.txt
Normal file
188
CMakeLists.txt
Normal file
@@ -0,0 +1,188 @@
|
||||
# -----------------------------------------------------------------------------
|
||||
# @author Auto-generated by STM32CubeIDE for Visual Studio Code Extension
|
||||
# -----------------------------------------------------------------------------
|
||||
# @attention
|
||||
#
|
||||
# Copyright (c) 2025 STMicroelectronics.
|
||||
# All rights reserved.
|
||||
#
|
||||
# This software is licensed under terms that can be found in the LICENSE file
|
||||
# in the root directory of this software component.
|
||||
# If no LICENSE file comes with this software, it is provided AS-IS.
|
||||
#
|
||||
# -----------------------------------------------------------------------------
|
||||
|
||||
cmake_minimum_required(VERSION 3.20)
|
||||
|
||||
#
|
||||
# This file is generated only once, and is not re-generated.
|
||||
#
|
||||
# User is free to modify the file as much as necessary
|
||||
#
|
||||
|
||||
# Core project settings
|
||||
project("EEP-144_Library")
|
||||
enable_language(C CXX ASM)
|
||||
message("Build type: " ${CMAKE_BUILD_TYPE})
|
||||
|
||||
# Setup compiler settings
|
||||
set(CMAKE_C_STANDARD 11)
|
||||
set(CMAKE_C_STANDARD_REQUIRED ON)
|
||||
set(CMAKE_C_EXTENSIONS ON)
|
||||
set(CMAKE_CXX_STANDARD 20)
|
||||
set(CMAKE_CXX_STANDARD_REQUIRED ON)
|
||||
set(CMAKE_CXX_EXTENSIONS ON)
|
||||
|
||||
# Core MCU flags, CPU type, instruction set and FPU setup
|
||||
set(cpu_PARAMS
|
||||
# Other parameters
|
||||
# -mthumb
|
||||
# -mcpu, -mfloat, -mfloat-abi, ...
|
||||
)
|
||||
|
||||
# Sources
|
||||
file(GLOB_RECURSE
|
||||
sources_SRCS CONFIGURE_DEPENDS
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/src/*.c
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/YEEP144lib/src/*.c
|
||||
#${CMAKE_CURRENT_SOURCE_DIR}/Drivers/BSP/STM32H5xx_Nucleo/stm32h5xx_nucleo.c
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/Drivers/STM32H5xx_HAL_Driver/Src/*.c
|
||||
)
|
||||
|
||||
# Include directories for all compilers
|
||||
set(include_DIRS
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/include
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/YEEP144lib/include
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/Drivers/STM32H5xx_HAL_Driver/Inc
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/Drivers/STM32H5xx_HAL_Driver/Inc/Legacy
|
||||
#${CMAKE_CURRENT_SOURCE_DIR}/Drivers/BSP/STM32H5xx_Nucleo
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/Drivers/CMSIS/Device/ST/STM32H5xx/Include
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/Drivers/CMSIS/Include
|
||||
)
|
||||
|
||||
# Include directories for each compiler
|
||||
set(include_c_DIRS)
|
||||
set(include_cxx_DIRS)
|
||||
set(include_asm_DIRS)
|
||||
|
||||
# Symbols definition for all compilers
|
||||
set(symbols_SYMB
|
||||
USE_HAL_DRIVER
|
||||
STM32H563xx)
|
||||
|
||||
# Symbols definition for each compiler
|
||||
set(symbols_c_SYMB)
|
||||
set(symbols_cxx_SYMB)
|
||||
set(symbols_asm_SYMB)
|
||||
|
||||
# Link directories and names of libraries
|
||||
set(link_DIRS)
|
||||
set(link_LIBS
|
||||
m)
|
||||
|
||||
# Linker script
|
||||
set(linker_script_SRC)
|
||||
|
||||
# Compiler options
|
||||
set(compiler_OPTS)
|
||||
|
||||
# Linker options
|
||||
set(linker_OPTS)
|
||||
|
||||
# Now call generated cmake
|
||||
# This will add script generated
|
||||
# information to the project
|
||||
include("cmake/vscode_generated.cmake")
|
||||
|
||||
# Link directories setup
|
||||
# Must be before executable is added
|
||||
link_directories(${CMAKE_PROJECT_NAME} ${link_DIRS})
|
||||
|
||||
# Create an executable object type
|
||||
add_executable(${CMAKE_PROJECT_NAME})
|
||||
|
||||
# Add sources to executable
|
||||
target_sources(${CMAKE_PROJECT_NAME} PUBLIC ${sources_SRCS})
|
||||
|
||||
# Add include paths
|
||||
target_include_directories(${CMAKE_PROJECT_NAME} PRIVATE
|
||||
${include_DIRS}
|
||||
$<$<COMPILE_LANGUAGE:C>: ${include_c_DIRS}>
|
||||
$<$<COMPILE_LANGUAGE:CXX>: ${include_cxx_DIRS}>
|
||||
$<$<COMPILE_LANGUAGE:ASM>: ${include_asm_DIRS}>
|
||||
)
|
||||
|
||||
# Add project symbols (macros)
|
||||
target_compile_definitions(${CMAKE_PROJECT_NAME} PRIVATE
|
||||
${symbols_SYMB}
|
||||
$<$<COMPILE_LANGUAGE:C>: ${symbols_c_SYMB}>
|
||||
$<$<COMPILE_LANGUAGE:CXX>: ${symbols_cxx_SYMB}>
|
||||
$<$<COMPILE_LANGUAGE:ASM>: ${symbols_asm_SYMB}>
|
||||
|
||||
# Configuration specific
|
||||
$<$<CONFIG:Debug>:DEBUG>
|
||||
$<$<CONFIG:Release>: >
|
||||
)
|
||||
|
||||
# Add linked libraries
|
||||
target_link_libraries(${CMAKE_PROJECT_NAME} ${link_LIBS})
|
||||
|
||||
# Compiler options
|
||||
target_compile_options(${CMAKE_PROJECT_NAME} PRIVATE
|
||||
${cpu_PARAMS}
|
||||
${compiler_OPTS}
|
||||
-fstack-usage
|
||||
# -fcyclomatic-complexity
|
||||
-Wall
|
||||
-Wextra
|
||||
-Wpedantic
|
||||
-Wno-unused-parameter
|
||||
$<$<COMPILE_LANGUAGE:C>: >
|
||||
$<$<COMPILE_LANGUAGE:CXX>:
|
||||
|
||||
# -Wno-volatile
|
||||
# -Wold-style-cast
|
||||
# -Wuseless-cast
|
||||
# -Wsuggest-override
|
||||
>
|
||||
$<$<COMPILE_LANGUAGE:ASM>:-x assembler-with-cpp -MMD -MP>
|
||||
$<$<CONFIG:Debug>:-O0 -g3 -ggdb>
|
||||
$<$<CONFIG:Release>:-Os>
|
||||
)
|
||||
|
||||
# Linker options
|
||||
target_link_options(${CMAKE_PROJECT_NAME} PRIVATE
|
||||
-T${linker_script_SRC}
|
||||
${cpu_PARAMS}
|
||||
${linker_OPTS}
|
||||
-Wl,-Map=${CMAKE_PROJECT_NAME}.map
|
||||
-u _printf_float
|
||||
#-u _scanf_float
|
||||
--specs=nosys.specs
|
||||
-Wl,--start-group
|
||||
-lc
|
||||
-lm
|
||||
-lstdc++
|
||||
-lsupc++
|
||||
-Wl,--end-group
|
||||
-Wl,-z,max-page-size=8 # Allow good software remapping across address space (with proper GCC section making)
|
||||
-Wl,--print-memory-usage
|
||||
)
|
||||
|
||||
# Conditionally add CMSE linker options
|
||||
if(CMSIS_Dsecure STREQUAL "Secure")
|
||||
target_link_options(${CMAKE_PROJECT_NAME} PRIVATE
|
||||
-Wl,--cmse-implib
|
||||
-Wl,--out-implib=secure_nsclib.o
|
||||
)
|
||||
endif()
|
||||
|
||||
# Set linker script as a dependency to force re-link if it changes
|
||||
set_target_properties(${CMAKE_PROJECT_NAME} PROPERTIES LINK_DEPENDS ${linker_script_SRC})
|
||||
|
||||
# Execute post-build to print size, generate hex and bin
|
||||
add_custom_command(TARGET ${CMAKE_PROJECT_NAME} POST_BUILD
|
||||
COMMAND ${CMAKE_SIZE} $<TARGET_FILE:${CMAKE_PROJECT_NAME}>
|
||||
COMMAND ${CMAKE_OBJCOPY} -O ihex $<TARGET_FILE:${CMAKE_PROJECT_NAME}> ${CMAKE_PROJECT_NAME}.hex
|
||||
COMMAND ${CMAKE_OBJCOPY} -O binary $<TARGET_FILE:${CMAKE_PROJECT_NAME}> ${CMAKE_PROJECT_NAME}.bin
|
||||
)
|
||||
55
CMakePresets.json
Normal file
55
CMakePresets.json
Normal file
@@ -0,0 +1,55 @@
|
||||
{
|
||||
"version": 3,
|
||||
"configurePresets": [
|
||||
{
|
||||
"name": "default",
|
||||
"hidden": true,
|
||||
"generator": "Ninja",
|
||||
"binaryDir": "${sourceDir}/build/${presetName}",
|
||||
"toolchainFile": "${sourceDir}/cmake/gnu-tools-for-stm32.cmake",
|
||||
"cacheVariables": {
|
||||
"CMAKE_EXPORT_COMPILE_COMMANDS": "ON",
|
||||
"CMSIS_Dvendor": "STMicroelectronics:13",
|
||||
"CMSIS_Dname": "STM32H563ZIT6",
|
||||
"CMSIS_Dcore": "Cortex-M33",
|
||||
"CMSIS_Dtz": "TZ",
|
||||
"CMSIS_Dfpu": "SP_FPU",
|
||||
"CMSIS_Ddsp": "DSP",
|
||||
"CMSIS_Dmve": "NO_MVE",
|
||||
"CMSIS_Dmpu": "MPU",
|
||||
"CMSIS_Dendian": "Little-endian",
|
||||
"CMSIS_Dsecure": "TZ-disabled",
|
||||
"CMSIS_Tcompiler": "GCC"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "Debug",
|
||||
"inherits": "default",
|
||||
"cacheVariables": {
|
||||
"CMAKE_BUILD_TYPE": "Debug"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "Release",
|
||||
"inherits": "default",
|
||||
"cacheVariables": {
|
||||
"CMAKE_BUILD_TYPE": "Release"
|
||||
}
|
||||
}
|
||||
],
|
||||
"buildPresets": [
|
||||
{
|
||||
"name": "default",
|
||||
"hidden": true,
|
||||
"configurePreset": "default"
|
||||
},
|
||||
{
|
||||
"name": "Debug",
|
||||
"configurePreset": "Debug"
|
||||
},
|
||||
{
|
||||
"name": "Release",
|
||||
"configurePreset": "Release"
|
||||
}
|
||||
]
|
||||
}
|
||||
21
YEEP144lib/include/YEEP144.h
Normal file
21
YEEP144lib/include/YEEP144.h
Normal file
@@ -0,0 +1,21 @@
|
||||
#ifndef __YEEP144_H
|
||||
#define __YEEP144_H
|
||||
|
||||
#include "stm32h5xx_hal.h"
|
||||
|
||||
#define GPIO_MODE_OUTPUT GPIO_MODE_OUTPUT_PP
|
||||
|
||||
#define DEBUGUART 1
|
||||
#define BLUETOOTHUART 2
|
||||
|
||||
#define UARTSEL DEBUGUART
|
||||
|
||||
// Public Function Prototypes
|
||||
int YEEP144_Init(void);
|
||||
|
||||
void delayUS(uint32_t us);
|
||||
|
||||
void YEEP144_GPIO_Init(GPIO_TypeDef* port, uint32_t pins, uint32_t mode);
|
||||
void YEEP144_GPIO_InitAdv(GPIO_TypeDef* port, uint32_t pins, uint32_t mode, uint32_t pull, uint32_t speed, uint32_t alternate);
|
||||
|
||||
#endif
|
||||
8
YEEP144lib/include/YEEP144_ADCPot.h
Normal file
8
YEEP144lib/include/YEEP144_ADCPot.h
Normal file
@@ -0,0 +1,8 @@
|
||||
#ifndef __YEEP144_ADCPOT_H
|
||||
#define __YEEP144_ADCPOT_H
|
||||
|
||||
void YEEP144_ADCPot_Init(void);
|
||||
uint16_t YEEP144_ADCPot_GetPot1(void);
|
||||
uint16_t YEEP144_ADCPot_GetPot2(void);
|
||||
|
||||
#endif
|
||||
19
YEEP144lib/include/YEEP144_BluetoothUART.h
Normal file
19
YEEP144lib/include/YEEP144_BluetoothUART.h
Normal file
@@ -0,0 +1,19 @@
|
||||
#ifndef __YEEP144_BLUETOOTHUART_H
|
||||
#define __YEEP144_BLUETOOTHUART_H
|
||||
|
||||
#include "stm32h5xx_hal.h"
|
||||
#include "stm32h5xx_hal_uart.h"
|
||||
|
||||
// Structure for UART info
|
||||
extern UART_HandleTypeDef huart2;
|
||||
|
||||
void YEEP144_BluetoothUART_Init(void);
|
||||
int YEEP144_BluetoothUART_printf(const char * format, ...);
|
||||
|
||||
void YEEP144_BluetoothUART_EnableCharMatchIRQ(void);
|
||||
void YEEP144_BluetoothUART_DisableCharMatchIRQ(void);
|
||||
void YEEP144_BluetoothUART_SetCharMatch(char match);
|
||||
|
||||
void YEEP144_BluetoothUART_SetStatusDelimiter(char prefix, char postfix);
|
||||
|
||||
#endif
|
||||
10
YEEP144lib/include/YEEP144_Buzzer.h
Normal file
10
YEEP144lib/include/YEEP144_Buzzer.h
Normal file
@@ -0,0 +1,10 @@
|
||||
#ifndef __YEEP144_BUZZER_H
|
||||
#define __YEEP144_BUZZER_H
|
||||
|
||||
void YEEP144_Buzzer_Init(void);
|
||||
void YEEP144_Buzzer_Tone(uint32_t freq, uint32_t duration);
|
||||
void YEEP144_Buzzer_GoTone(uint32_t freq);
|
||||
void YEEP144_Buzzer_NoTone(void);
|
||||
void YEEP144_Buzzer_Daisy(void);
|
||||
|
||||
#endif
|
||||
39
YEEP144lib/include/YEEP144_DCMotor.h
Normal file
39
YEEP144lib/include/YEEP144_DCMotor.h
Normal file
@@ -0,0 +1,39 @@
|
||||
#ifndef __YEEP144_DCMOTOR_H
|
||||
#define __YEEP144_DCMOTOR_H
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
// Defines
|
||||
#define DCMOTOR1 1
|
||||
#define DCMOTOR2 2
|
||||
#define DCMOTOR3 3
|
||||
#define DCMOTOR4 4
|
||||
|
||||
#define DCMOTOR_STOP 0 // 0b00
|
||||
#define DCMOTOR_CCW 1 // 0b01
|
||||
#define DCMOTOR_CW 2 // 0b10
|
||||
#define DCMOTOR_SHORTBRAKE 3 // 0b11
|
||||
|
||||
#define DCMOTOR_MIN_SPEED 0
|
||||
#define DCMOTOR_MAX_SPEED 4095 // This corresponds to the Period of the timer
|
||||
|
||||
// Function prototypes
|
||||
|
||||
// Init functions
|
||||
void YEEP144_DCMotor_Init(void);
|
||||
void YEEP144_Encoder1_Init(void);
|
||||
void YEEP144_Encoder2_Init(void);
|
||||
void YEEP144_Encoder3_Init(void);
|
||||
void YEEP144_Encoder4_Init(void);
|
||||
|
||||
// Motor functions
|
||||
void YEEP144_DCMotor_SetSpeed(uint8_t motor, uint16_t speed);
|
||||
void YEEP144_DCMotor_SetDirection(uint8_t motor, uint8_t direction);
|
||||
|
||||
// Encoder functions
|
||||
uint16_t YEEP144_Encoder1_Get(void);
|
||||
uint16_t YEEP144_Encoder2_Get(void);
|
||||
uint16_t YEEP144_Encoder3_Get(void);
|
||||
uint16_t YEEP144_Encoder4_Get(void);
|
||||
|
||||
#endif
|
||||
17
YEEP144lib/include/YEEP144_DebugUART.h
Normal file
17
YEEP144lib/include/YEEP144_DebugUART.h
Normal file
@@ -0,0 +1,17 @@
|
||||
#ifndef __YEEP144_DEBUGUART_H
|
||||
#define __YEEP144_DEBUGUART_H
|
||||
|
||||
#include "stm32h5xx_hal.h"
|
||||
#include "stm32h5xx_hal_uart.h"
|
||||
|
||||
// Structure for UART info
|
||||
extern UART_HandleTypeDef huart3;
|
||||
|
||||
void YEEP144_DebugUART_Init(void);
|
||||
int YEEP144_DebugUART_printf(const char * format, ...);
|
||||
|
||||
void YEEP144_DebugUART_EnableCharMatchIRQ(void);
|
||||
void YEEP144_DebugUART_DisableCharMatchIRQ(void);
|
||||
void YEEP144_DebugUART_SetCharMatch(char match);
|
||||
|
||||
#endif
|
||||
10
YEEP144lib/include/YEEP144_GP2Y0E02B.h
Normal file
10
YEEP144lib/include/YEEP144_GP2Y0E02B.h
Normal file
@@ -0,0 +1,10 @@
|
||||
#ifndef __YEEP144_GP2Y0E02B_H
|
||||
#define __YEEP144_GP2Y0E02B_H
|
||||
|
||||
#define GP2Y0E02B_I2C_ADDR 0x80
|
||||
#define GP2Y0E02B_SHIFT_REG_ADDR 0x35
|
||||
#define GP2Y0E02B_DISTANCE_REG_ADDR 0x5E
|
||||
|
||||
float YEEP144_GP2Y0E02B_Read(void);
|
||||
|
||||
#endif
|
||||
29
YEEP144lib/include/YEEP144_HCSR04.h
Normal file
29
YEEP144lib/include/YEEP144_HCSR04.h
Normal file
@@ -0,0 +1,29 @@
|
||||
#ifndef __YEEP144_HCSR04_H
|
||||
#define __YEEP144_HCSR04_H
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
void YEEP144_Ultrasonic1_Init(void);
|
||||
void YEEP144_Ultrasonic2_Init(void);
|
||||
void YEEP144_Ultrasonic3_Init(void);
|
||||
void YEEP144_Ultrasonic4_Init(void);
|
||||
|
||||
uint8_t YEEP144_Ultrasonic_PingNext(void);
|
||||
float YEEP144_Ultrasonic_TickTocm(uint16_t ticks);
|
||||
|
||||
uint8_t YEEP144_Ultrasonic1_Ping(void);
|
||||
uint8_t YEEP144_Ultrasonic2_Ping(void);
|
||||
uint8_t YEEP144_Ultrasonic3_Ping(void);
|
||||
uint8_t YEEP144_Ultrasonic4_Ping(void);
|
||||
|
||||
uint16_t YEEP144_Ultrasonic1_PingBlocking(void);
|
||||
uint16_t YEEP144_Ultrasonic2_PingBlocking(void);
|
||||
uint16_t YEEP144_Ultrasonic3_PingBlocking(void);
|
||||
uint16_t YEEP144_Ultrasonic4_PingBlocking(void);
|
||||
|
||||
void YEEP144_Ultrasonic_EXTI10Handler(void);
|
||||
void YEEP144_Ultrasonic_EXTI12Handler(void);
|
||||
|
||||
extern uint16_t ultrasonicTickLen[4];
|
||||
|
||||
#endif
|
||||
13
YEEP144lib/include/YEEP144_I2C.h
Normal file
13
YEEP144lib/include/YEEP144_I2C.h
Normal file
@@ -0,0 +1,13 @@
|
||||
#ifndef __YEEP144_I2C_H
|
||||
#define __YEEP144_I2C_H
|
||||
|
||||
#include "stm32h5xx_hal.h"
|
||||
|
||||
#define I2C_MUX_ADDR 0xEE
|
||||
|
||||
extern I2C_HandleTypeDef hi2c2;
|
||||
|
||||
void YEEP144_I2C_Init(void);
|
||||
void YEEP144_I2C_MuxSelect(uint8_t busNumber);
|
||||
|
||||
#endif
|
||||
18
YEEP144lib/include/YEEP144_PiSPI.h
Normal file
18
YEEP144lib/include/YEEP144_PiSPI.h
Normal file
@@ -0,0 +1,18 @@
|
||||
#ifndef __YEEP144_PISPI_H
|
||||
#define __YEEP144_PISPI_H
|
||||
|
||||
// This value define the size of the transfer buffers.
|
||||
// It needs to match what is set on the Pi side so the correct amount of data is transferred each time
|
||||
#define PISPI_BUFFER_SIZE 256
|
||||
|
||||
// Extern the buffer arrays so they are accessible from other files
|
||||
extern uint8_t PiSPIRxBuf[PISPI_BUFFER_SIZE];
|
||||
extern uint8_t PiSPITxBuf[PISPI_BUFFER_SIZE];
|
||||
|
||||
void YEEP144_PiSPI_Init(void);
|
||||
void YEEP144_PiSPI_SetReady(void);
|
||||
void YEEP144_PiSPI_ResetReady(void);
|
||||
void YEEP144_PiSPI_LoadTx(void);
|
||||
void YEEP144_PiSPI_TxRxHandler(void);
|
||||
|
||||
#endif
|
||||
190
YEEP144lib/include/YEEP144_Pinout.h
Normal file
190
YEEP144lib/include/YEEP144_Pinout.h
Normal file
@@ -0,0 +1,190 @@
|
||||
/**
|
||||
* This file contains #defines for the ports and pins used by the EEP-144 functions
|
||||
* and is shared by all modules
|
||||
*/
|
||||
|
||||
#ifndef __YEEP144_PINOUT_H
|
||||
#define __YEEP144_PINOUT_H
|
||||
|
||||
// DC Motors
|
||||
|
||||
#define MOT1A_PORT GPIOG
|
||||
#define MOT1A_PIN GPIO_PIN_0
|
||||
#define MOT1B_PORT GPIOG
|
||||
#define MOT1B_PIN GPIO_PIN_1
|
||||
#define MOT1PWM_PORT GPIOC
|
||||
#define MOT1PWM_PIN GPIO_PIN_6
|
||||
|
||||
#define MOT2A_PORT GPIOG
|
||||
#define MOT2A_PIN GPIO_PIN_2
|
||||
#define MOT2B_PORT GPIOG
|
||||
#define MOT2B_PIN GPIO_PIN_3
|
||||
#define MOT2PWM_PORT GPIOC
|
||||
#define MOT2PWM_PIN GPIO_PIN_7
|
||||
|
||||
#define MOT3A_PORT GPIOE
|
||||
#define MOT3A_PIN GPIO_PIN_7
|
||||
#define MOT3B_PORT GPIOE
|
||||
#define MOT3B_PIN GPIO_PIN_8
|
||||
#define MOT3PWM_PORT GPIOB
|
||||
#define MOT3PWM_PIN GPIO_PIN_0
|
||||
|
||||
#define MOT4A_PORT GPIOB
|
||||
#define MOT4A_PIN GPIO_PIN_2
|
||||
#define MOT4B_PORT GPIOB
|
||||
#define MOT4B_PIN GPIO_PIN_4
|
||||
#define MOT4PWM_PORT GPIOC
|
||||
#define MOT4PWM_PIN GPIO_PIN_9
|
||||
|
||||
// DC Motor Encoders
|
||||
|
||||
#define ENC1A_PORT GPIOD
|
||||
#define ENC1A_PIN GPIO_PIN_12
|
||||
#define ENC1B_PORT GPIOD
|
||||
#define ENC1B_PIN GPIO_PIN_13
|
||||
|
||||
#define ENC2A_PORT GPIOC
|
||||
#define ENC2A_PIN GPIO_PIN_11
|
||||
#define ENC2B_PORT GPIOA
|
||||
#define ENC2B_PIN GPIO_PIN_15
|
||||
|
||||
#define ENC3A_PORT GPIOF
|
||||
#define ENC3A_PIN GPIO_PIN_2
|
||||
#define ENC3B_PORT GPIOF
|
||||
#define ENC3B_PIN GPIO_PIN_9
|
||||
|
||||
#define ENC4A_PORT GPIOB
|
||||
#define ENC4A_PIN GPIO_PIN_10
|
||||
#define ENC4B_PORT GPIOD
|
||||
#define ENC4B_PIN GPIO_PIN_11
|
||||
|
||||
// Servos
|
||||
#define SERVO1_PORT GPIOA
|
||||
#define SERVO1_PIN GPIO_PIN_0
|
||||
#define SERVO2_PORT GPIOA
|
||||
#define SERVO2_PIN GPIO_PIN_3
|
||||
#define SERVO3_PORT GPIOF
|
||||
#define SERVO3_PIN GPIO_PIN_8
|
||||
#define SERVO4_PORT GPIOF
|
||||
#define SERVO4_PIN GPIO_PIN_7
|
||||
|
||||
// Buzzer
|
||||
|
||||
#define BUZZER_PORT GPIOF
|
||||
#define BUZZER_PIN GPIO_PIN_7
|
||||
|
||||
// UART
|
||||
|
||||
#define UART2_TX_PORT GPIOD
|
||||
#define UART2_TX_PIN GPIO_PIN_5
|
||||
#define UART2_RX_PORT GPIOD
|
||||
#define UART2_RX_PIN GPIO_PIN_6
|
||||
#define UART2_RTS_PORT GPIOD
|
||||
#define UART2_RTS_PIN GPIO_PIN_4
|
||||
#define UART2_CTS_PORT GPIOD
|
||||
#define UART2_CTS_PIN GPIO_PIN_3
|
||||
|
||||
#define UART3_TX_PORT GPIOD
|
||||
#define UART3_TX_PIN GPIO_PIN_9
|
||||
#define UART3_RX_PORT GPIOD
|
||||
#define UART3_RX_PIN GPIO_PIN_8
|
||||
|
||||
#define UART4_TX_PORT GPIOD
|
||||
#define UART4_TX_PIN GPIO_PIN_1
|
||||
#define UART4_RX_PORT GPIOD
|
||||
#define UART4_RX_PIN GPIO_PIN_0
|
||||
|
||||
// I2C
|
||||
|
||||
#define I2C_SDA_PORT GPIOF
|
||||
#define I2C_SDA_PIN GPIO_PIN_0
|
||||
#define I2C_SCL_PORT GPIOF
|
||||
#define I2C_SCL_PIN GPIO_PIN_1
|
||||
|
||||
// SPI
|
||||
#define SPI_MISO_PORT GPIOE
|
||||
#define SPI_MISO_PIN GPIO_PIN_5
|
||||
#define SPI_MOSI_PORT GPIOE
|
||||
#define SPI_MOSI_PIN GPIO_PIN_6
|
||||
#define SPI_SCK_PORT GPIOE
|
||||
#define SPI_SCK_PIN GPIO_PIN_12
|
||||
#define SPI_CS_PORT GPIOE
|
||||
#define SPI_CS_PIN GPIO_PIN_4
|
||||
|
||||
// Ultrasonic Distance Sensors
|
||||
|
||||
#define USONIC1_TRIG_PORT GPIOE
|
||||
#define USONIC1_TRIG_PIN GPIO_PIN_0
|
||||
#define USONIC1_ECHO_PORT GPIOC
|
||||
#define USONIC1_ECHO_PIN GPIO_PIN_10
|
||||
#define USONIC1_ECHO_EXTI EXTI10_IRQn
|
||||
|
||||
#define USONIC2_TRIG_PORT GPIOE
|
||||
#define USONIC2_TRIG_PIN GPIO_PIN_2
|
||||
#define USONIC2_ECHO_PORT GPIOG
|
||||
#define USONIC2_ECHO_PIN GPIO_PIN_10
|
||||
#define USONIC2_ECHO_EXTI EXTI10_IRQn
|
||||
|
||||
#define USONIC3_TRIG_PORT GPIOE
|
||||
#define USONIC3_TRIG_PIN GPIO_PIN_3
|
||||
#define USONIC3_ECHO_PORT GPIOE
|
||||
#define USONIC3_ECHO_PIN GPIO_PIN_10
|
||||
#define USONIC3_ECHO_EXTI EXTI10_IRQn
|
||||
|
||||
#define USONIC4_TRIG_PORT GPIOE
|
||||
#define USONIC4_TRIG_PIN GPIO_PIN_15
|
||||
#define USONIC4_ECHO_PORT GPIOF
|
||||
#define USONIC4_ECHO_PIN GPIO_PIN_12
|
||||
#define USONIC4_ECHO_EXTI EXTI12_IRQn
|
||||
|
||||
// Pushbuttons
|
||||
|
||||
#define BUTTON_BLUE_PORT GPIOC
|
||||
#define BUTTON_BLUE_PIN GPIO_PIN_13
|
||||
#define BUTTON_BLUE_EXTI EXTI13_IRQn
|
||||
#define BUTTON_0_PORT GPIOC
|
||||
#define BUTTON_0_PIN GPIO_PIN_13
|
||||
#define BUTTON_0_EXTI EXTI13_IRQn
|
||||
|
||||
#define BUTTON_GREEN_PORT GPIOD
|
||||
#define BUTTON_GREEN_PIN GPIO_PIN_7
|
||||
#define BUTTON_GREEN_EXTI EXTI7_IRQn
|
||||
#define BUTTON_1_PORT GPIOD
|
||||
#define BUTTON_1_PIN GPIO_PIN_7
|
||||
#define BUTTON_1_EXTI EXTI7_IRQn
|
||||
|
||||
#define BUTTON_YELLOW_PORT GPIOG
|
||||
#define BUTTON_YELLOW_PIN GPIO_PIN_6
|
||||
#define BUTTON_YELLOW_EXTI EXTI6_IRQn
|
||||
#define BUTTON_2_PORT GPIOG
|
||||
#define BUTTON_2_PIN GPIO_PIN_6
|
||||
#define BUTTON_2_EXTI EXTI6_IRQn
|
||||
|
||||
#define BUTTON_RED_PORT GPIOB
|
||||
#define BUTTON_RED_PIN GPIO_PIN_12
|
||||
#define BUTTON_RED_EXTI EXTI12_IRQn
|
||||
#define BUTTON_3_PORT GPIOB
|
||||
#define BUTTON_3_PIN GPIO_PIN_12
|
||||
#define BUTTON_3_EXTI EXTI12_IRQn
|
||||
|
||||
// Potentiometers
|
||||
|
||||
#define POT1_PORT GPIOF
|
||||
#define POT1_PIN GPIO_PIN_13
|
||||
#define POT2_PORT GPIOF
|
||||
#define POT2_PIN GPIO_PIN_14
|
||||
|
||||
// SD Card
|
||||
#define SD_CK_PORT GPIOC
|
||||
#define SD_CK_PIN GPIO_PIN_12
|
||||
#define SD_CMD_PORT GPIOD
|
||||
#define SD_CMD_PIN GPIO_PIN_2
|
||||
#define SD_D0_PORT GPIOC
|
||||
#define SD_D0_PIN GPIO_PIN_8
|
||||
|
||||
// IR Beacon Receiver
|
||||
#define IR_RECEIVER_PIN GPIO_PIN_3
|
||||
#define IR_RECEIVER_PORT GPIOF
|
||||
#define IR_RECEIVER_EXTI EXTI3_IRQn
|
||||
|
||||
#endif
|
||||
14
YEEP144lib/include/YEEP144_PushButton.h
Normal file
14
YEEP144lib/include/YEEP144_PushButton.h
Normal file
@@ -0,0 +1,14 @@
|
||||
#ifndef __YEEP144_PUSHBUTTON_H
|
||||
#define __YEEP144_PUSHBUTTON_H
|
||||
|
||||
void YEEP144_PushButton_BlueInit(void);
|
||||
void YEEP144_PushButton_GreenInit(void);
|
||||
void YEEP144_PushButton_YellowInit(void);
|
||||
void YEEP144_PushButton_RedInit(void);
|
||||
|
||||
void YEEP144_PushButton_BlueHandler(void);
|
||||
void YEEP144_PushButton_GreenHandler(void);
|
||||
void YEEP144_PushButton_YellowHandler(void);
|
||||
void YEEP144_PushButton_RedHandler(void);
|
||||
|
||||
#endif
|
||||
91
YEEP144lib/include/YEEP144_RGB.h
Normal file
91
YEEP144lib/include/YEEP144_RGB.h
Normal file
@@ -0,0 +1,91 @@
|
||||
#ifndef __YEEP144_RGB_H
|
||||
#define __YEEP144_RGB_H
|
||||
|
||||
#define RGB1_RED 0x5
|
||||
#define RGB1_GREEN 0x4
|
||||
#define RGB1_BLUE 0x6
|
||||
|
||||
#define RGB2_RED 0x8
|
||||
#define RGB2_GREEN 0x7
|
||||
#define RGB2_BLUE 0x9
|
||||
|
||||
#define RGB3_RED 0xB
|
||||
#define RGB3_GREEN 0xA
|
||||
#define RGB3_BLUE 0xC
|
||||
|
||||
#define RGB4_RED 0xE
|
||||
#define RGB4_GREEN 0xD
|
||||
#define RGB4_BLUE 0xF
|
||||
|
||||
// Pure colours
|
||||
#define RGB_OFF 0x00, 0x00, 0x00
|
||||
#define RGB_RED 0xFF, 0x00, 0x00
|
||||
#define RGB_GREEN 0x00, 0x80, 0x00
|
||||
#define RGB_BLUE 0x00, 0x00, 0x00
|
||||
|
||||
// HTML standard colours
|
||||
#define RGB_WHITE 0xFF, 0xFF, 0xFF
|
||||
#define RGB_MAROON 0x80, 0x00, 0x00
|
||||
#define RGB_YELLOW 0xFF, 0xFF, 0xFF
|
||||
#define RGB_OLIVE 0x80, 0x80, 0x00
|
||||
#define RGB_LIME 0x00, 0xFF, 0x00
|
||||
#define RGB_CYAN 0x00, 0xFF, 0xFF
|
||||
#define RGB_TEAL 0x00, 0x80, 0x80
|
||||
#define RGB_NAVY 0x00, 0x00, 0x80
|
||||
#define RGB_MAGENTA 0xFF, 0x00, 0xFF
|
||||
#define RGB_PURPLE 0x80, 0x00, 0x80
|
||||
#define RGB_ORANGE 0xFF, 0xA5, 0x00
|
||||
|
||||
// Selection of HTML extended colours
|
||||
// Pinks
|
||||
#define RGB_DEEPPINK 0xFF, 0x14, 0x93
|
||||
#define RGB_HOTPINK 0xFF, 0x69, 0xB4
|
||||
#define RGB_PINK 0xFF, 0xC0, 0xCB
|
||||
|
||||
// Reds
|
||||
#define RGB_DARKRED 0x8B, 0x00, 0x00
|
||||
#define RGB_CRIMSON 0xDC, 0x14, 0x3C
|
||||
#define RGB_SALMON 0xFA, 0x80, 0x72
|
||||
|
||||
// Oranges
|
||||
#define RGB_ORANGERED 0xFF, 0x45, 0x00
|
||||
#define RGB_DARKORANGE 0xFF, 0x8C, 0x00
|
||||
#define RGB_CORAL 0xFF, 0x7F, 0x50
|
||||
|
||||
// Yellows
|
||||
#define RGB_DARKKHAKI 0xBD, 0xB7, 0x6B
|
||||
#define RGB_GOLD 0xFF, 0xD7, 0x00
|
||||
#define RGB_KHAKI 0xF0, 0xE6, 0x8C
|
||||
|
||||
// Browns
|
||||
#define RGB_BROWN 0xA5, 0x2A, 0x2A
|
||||
#define RGB_SADDLEBROWN 0x8B, 0x45, 0x13
|
||||
#define RGB_ROSYBROWN 0xBC, 0x8F, 0x8F
|
||||
|
||||
// Purples
|
||||
#define RGB_INDIGO 0x4B, 0x00, 0x82
|
||||
#define RGB_DARKORCHID 0x99, 0x32, 0xCC
|
||||
#define RGB_VIOLET 0xEE, 0x82, 0xEE
|
||||
|
||||
// Blues
|
||||
#define RGB_ROYALBLUE 0x41, 0x69, 0xE1
|
||||
#define RGB_CORNFLOWERBLUE 0x64, 0x95, 0xED
|
||||
#define RGB_SKYBLUE 0x87, 0xCE, 0xEB
|
||||
|
||||
// Cyans
|
||||
#define RGB_TURQUOISE 0x40, 0xE0, 0xD0
|
||||
#define RGB_AQUAMARINE 0x7F, 0xFF, 0xD4
|
||||
|
||||
// Greens
|
||||
#define RGB_DARKGREEN 0x00, 0x64, 0x00
|
||||
#define RGB_SEAGREEN 0x2E, 0x8B, 0x57
|
||||
#define RGB_CHARTREUSE 0x7F, 0xFF, 0x00
|
||||
|
||||
void YEEP144_RGB_Init(void);
|
||||
|
||||
void YEEP144_RGB_SetLED(uint8_t led, uint8_t value);
|
||||
void YEEP144_RGB_SetRGB(uint8_t led, uint8_t red, uint8_t green, uint8_t blue);
|
||||
|
||||
void YEEP144_RGB_WriteReg(uint16_t reg, uint8_t data);
|
||||
|
||||
#endif
|
||||
35
YEEP144lib/include/YEEP144_SSD1306.h
Normal file
35
YEEP144lib/include/YEEP144_SSD1306.h
Normal file
@@ -0,0 +1,35 @@
|
||||
#ifndef __YEEP144_SSD1306_H
|
||||
#define __YEEP144_SSD1306_H
|
||||
|
||||
#define SSD1306_BLACK 0
|
||||
#define SSD1306_WHITE 1
|
||||
#define SSD1306_INVERSE 2
|
||||
|
||||
#include <stdbool.h>
|
||||
#include <stdarg.h>
|
||||
|
||||
void YEEP144_SSD1306_Init(void);
|
||||
void YEEP144_SSD1306_Display(void);
|
||||
void YEEP144_SSD1306_ClearDisplay(void);
|
||||
void YEEP144_SSD1306_SetPixel(uint8_t x, uint8_t y, uint8_t colour);
|
||||
bool YEEP144_SSD1306_GetPixel(uint8_t x, uint8_t y);
|
||||
|
||||
void YEEP144_SSD1306_DrawLine(uint8_t x0, uint8_t y0, uint8_t x1, uint8_t y1, uint8_t colour);
|
||||
|
||||
void YEEP144_SSD1306_DrawRect(uint8_t x, uint8_t y, uint8_t w, uint8_t h, uint8_t colour);
|
||||
void YEEP144_SSD1306_DrawFillRect(uint8_t x, uint8_t y, int8_t w, int8_t h, uint8_t colour);
|
||||
|
||||
void YEEP144_SSD1306_DrawChar(uint8_t x, uint8_t y, uint8_t c, uint8_t colour, uint8_t bg, uint8_t size);
|
||||
int YEEP144_SSD1306_printf(const char * format, ...);
|
||||
void YEEP144_SSD1306_SetTextSize(uint8_t size);
|
||||
void YEEP144_SSD1306_SetTextCursor(uint8_t x, uint8_t y);
|
||||
void YEEP144_SSD1306_SetTextWrap(uint8_t wrap);
|
||||
|
||||
void YEEP144_SSD1306_DrawBitmap(uint8_t x, uint8_t y, const uint8_t bitmap[], uint8_t w, uint8_t h);
|
||||
|
||||
void YEEP144_SSD1306_InvertDisplay(bool i);
|
||||
void YEEP144_SSD1306_SendCommand(uint8_t command);
|
||||
|
||||
extern const unsigned char UOYLogo[];
|
||||
|
||||
#endif
|
||||
24
YEEP144lib/include/YEEP144_Servo.h
Normal file
24
YEEP144lib/include/YEEP144_Servo.h
Normal file
@@ -0,0 +1,24 @@
|
||||
#ifndef __YEEP144_SERVO_H
|
||||
#define __YEEP144_SERVO_H
|
||||
|
||||
void YEEP144_Servo_Init1_2(void);
|
||||
void YEEP144_Servo_Init3(void);
|
||||
void YEEP144_Servo_Init4(void);
|
||||
|
||||
void YEEP144_Servo1_SetDirect(uint16_t pulse);
|
||||
void YEEP144_Servo2_SetDirect(uint16_t pulse);
|
||||
void YEEP144_Servo3_SetDirect(uint16_t pulse);
|
||||
void YEEP144_Servo4_SetDirect(uint16_t pulse);
|
||||
|
||||
void YEEP144_Servo1_SetAngle(float angle);
|
||||
void YEEP144_Servo2_SetAngle(float angle);
|
||||
void YEEP144_Servo3_SetAngle(float angle);
|
||||
void YEEP144_Servo4_SetAngle(float angle);
|
||||
|
||||
void YEEP144_Servo_SetMinTicks(uint8_t servo, uint16_t min);
|
||||
void YEEP144_Servo_SetMaxTicks(uint8_t servo, uint16_t max);
|
||||
|
||||
void YEEP144_Servo_SetMinAngle(uint8_t servo, float min);
|
||||
void YEEP144_Servo_SetMaxAngle(uint8_t servo, float max);
|
||||
|
||||
#endif
|
||||
8
YEEP144lib/include/YEEP144_TSOP4838.h
Normal file
8
YEEP144lib/include/YEEP144_TSOP4838.h
Normal file
@@ -0,0 +1,8 @@
|
||||
#ifndef __YEEP144_TSOP4838_H
|
||||
#define __YEEP144_TSOP4838_H
|
||||
|
||||
void YEEP144_TSOP4838_Init(void);
|
||||
uint8_t YEEP144_TSOP4838_Received(void);
|
||||
uint32_t YEEP144_TSOP4838_Read(void);
|
||||
|
||||
#endif
|
||||
166
YEEP144lib/src/YEEP144.c
Normal file
166
YEEP144lib/src/YEEP144.c
Normal file
@@ -0,0 +1,166 @@
|
||||
#include "YEEP144.h"
|
||||
#include "stm32h563xx.h"
|
||||
#include "stm32h5xx_hal.h"
|
||||
#include "stm32h5xx_hal_gpio.h"
|
||||
#include "stm32h5xx_hal_rcc.h"
|
||||
#include "stm32h5xx_hal_tim.h"
|
||||
|
||||
// Private Function Prototypes
|
||||
void SystemClock_Config(void);
|
||||
void GPIO_Init(void);
|
||||
|
||||
#define SYSTICK_LOAD (SystemCoreClock/1000000U)
|
||||
#define SYSTICK_DELAY_CALIB (85)// Determined experimentally
|
||||
|
||||
/**
|
||||
* This function initialises the minimum required for basic operation
|
||||
* Each feature on top of this will be initialised by its own init function
|
||||
*/
|
||||
int YEEP144_Init(void){
|
||||
HAL_Init();
|
||||
|
||||
SystemClock_Config();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Initialises the specified GPIO with basic configuration. This assumes it will be one of the standard modes
|
||||
* with no pull-ups or pull-downs, and a low frequency output
|
||||
*/
|
||||
void YEEP144_GPIO_Init(GPIO_TypeDef* port, uint32_t pins, uint32_t mode){
|
||||
// Initialise GPIO pins
|
||||
|
||||
// Create structure to hold GPIO init data
|
||||
GPIO_InitTypeDef GPIO_InitStruct = {0};
|
||||
|
||||
GPIO_InitStruct.Pin = pins; // Pins used
|
||||
GPIO_InitStruct.Mode = mode; // Set pin mode
|
||||
GPIO_InitStruct.Pull = GPIO_NOPULL; // No pull-ups or pull-downs
|
||||
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW; // Low speed is sufficient for this task
|
||||
|
||||
// Initialise the port
|
||||
HAL_GPIO_Init(port, &GPIO_InitStruct);
|
||||
}
|
||||
|
||||
/**
|
||||
* Initialises the specified GPIO with access to all of the configuration options, allowing you to configure
|
||||
* pull-ups / pull-downs, GPIO speed, and access alternate functions such as timer IO, SPI, I2C etc
|
||||
*/
|
||||
void YEEP144_GPIO_InitAdv(GPIO_TypeDef* port, uint32_t pins, uint32_t mode, uint32_t pull, uint32_t speed, uint32_t alternate){
|
||||
// Initialise GPIO pins
|
||||
|
||||
// Create structure to hold GPIO init data
|
||||
GPIO_InitTypeDef GPIO_InitStruct = {0};
|
||||
|
||||
GPIO_InitStruct.Pin = pins; // Pins used
|
||||
GPIO_InitStruct.Mode = mode; // Set pin mode
|
||||
GPIO_InitStruct.Pull = pull; // Set pullup / pulldown
|
||||
GPIO_InitStruct.Speed = speed; // Set speed - low is good for up to 8MHz
|
||||
GPIO_InitStruct.Alternate = alternate; // Set alternate mode
|
||||
|
||||
// Initialise the port
|
||||
HAL_GPIO_Init(port, &GPIO_InitStruct);
|
||||
}
|
||||
|
||||
/**
|
||||
* Initialises and configures the system clocks for standard operation
|
||||
*
|
||||
* By default we are configured for the maximum clock speed of 250MHz on the core
|
||||
* and on the APBx peripheral and timer clocks
|
||||
*
|
||||
* As we do not have a HSE clock due to the configuration of the Nucleo board
|
||||
* all clocks are based from the internal oscillators, primarily the HSI clock
|
||||
* where possible as it should give use the most stable clock from the options available
|
||||
*
|
||||
* This code is mostly copied from an MX generated project
|
||||
*/
|
||||
void SystemClock_Config(void){
|
||||
RCC_OscInitTypeDef RCC_OscInitStruct = {0};
|
||||
RCC_ClkInitTypeDef RCC_ClkInitStruct = {0};
|
||||
|
||||
/** Configure the main internal regulator output voltage
|
||||
*/
|
||||
__HAL_PWR_VOLTAGESCALING_CONFIG(PWR_REGULATOR_VOLTAGE_SCALE0);
|
||||
|
||||
while(!__HAL_PWR_GET_FLAG(PWR_FLAG_VOSRDY)) {}
|
||||
|
||||
/** Initializes the RCC Oscillators according to the specified parameters
|
||||
* in the RCC_OscInitTypeDef structure.
|
||||
*/
|
||||
RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSI|RCC_OSCILLATORTYPE_CSI;
|
||||
RCC_OscInitStruct.HSIState = RCC_HSI_ON;
|
||||
RCC_OscInitStruct.HSIDiv = RCC_HSI_DIV1;
|
||||
RCC_OscInitStruct.HSICalibrationValue = RCC_HSICALIBRATION_DEFAULT;
|
||||
RCC_OscInitStruct.CSIState = RCC_CSI_ON;
|
||||
RCC_OscInitStruct.CSICalibrationValue = RCC_CSICALIBRATION_DEFAULT;
|
||||
RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;
|
||||
RCC_OscInitStruct.PLL.PLLSource = RCC_PLL1_SOURCE_HSI;
|
||||
RCC_OscInitStruct.PLL.PLLM = 32;
|
||||
RCC_OscInitStruct.PLL.PLLN = 250;
|
||||
RCC_OscInitStruct.PLL.PLLP = 2;
|
||||
RCC_OscInitStruct.PLL.PLLQ = 2;
|
||||
RCC_OscInitStruct.PLL.PLLR = 2;
|
||||
RCC_OscInitStruct.PLL.PLLRGE = RCC_PLL1_VCIRANGE_1;
|
||||
RCC_OscInitStruct.PLL.PLLVCOSEL = RCC_PLL1VCOWIDE;
|
||||
RCC_OscInitStruct.PLL.PLLFRACN = 0;
|
||||
if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK)
|
||||
{
|
||||
//Error_Handler();
|
||||
}
|
||||
|
||||
/** Initializes the CPU, AHB and APB buses clocks
|
||||
*/
|
||||
RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK|RCC_CLOCKTYPE_SYSCLK
|
||||
|RCC_CLOCKTYPE_PCLK1|RCC_CLOCKTYPE_PCLK2
|
||||
|RCC_CLOCKTYPE_PCLK3;
|
||||
RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;
|
||||
RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;
|
||||
RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV1;
|
||||
RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1;
|
||||
RCC_ClkInitStruct.APB3CLKDivider = RCC_HCLK_DIV1;
|
||||
|
||||
if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_5) != HAL_OK)
|
||||
{
|
||||
//Error_Handler();
|
||||
}
|
||||
|
||||
/** Configure the programming delay
|
||||
*/
|
||||
__HAL_FLASH_SET_PROGRAM_DELAY(FLASH_PROGRAMMING_DELAY_2);
|
||||
|
||||
// Enable all GPIO clocks
|
||||
__HAL_RCC_GPIOA_CLK_ENABLE();
|
||||
__HAL_RCC_GPIOB_CLK_ENABLE();
|
||||
__HAL_RCC_GPIOC_CLK_ENABLE();
|
||||
__HAL_RCC_GPIOD_CLK_ENABLE();
|
||||
__HAL_RCC_GPIOE_CLK_ENABLE();
|
||||
__HAL_RCC_GPIOF_CLK_ENABLE();
|
||||
__HAL_RCC_GPIOG_CLK_ENABLE();
|
||||
__HAL_RCC_GPIOH_CLK_ENABLE();
|
||||
__HAL_RCC_GPIOI_CLK_ENABLE();
|
||||
}
|
||||
|
||||
/**
|
||||
* This function provides a delay in uS instead of ms
|
||||
* It should only be used for small delays <1ms
|
||||
*/
|
||||
void delayUS(uint32_t us){
|
||||
uint32_t startCount = SysTick->VAL;
|
||||
uint32_t targetCount = startCount - (us * SYSTICK_LOAD) + SYSTICK_DELAY_CALIB;
|
||||
|
||||
// Handle wraparounds
|
||||
// If the targetCount is greater than the LOAD value, this means the previous subtraction
|
||||
// has underflowed
|
||||
if(targetCount > SysTick->LOAD){
|
||||
// Calculate a new targetCount taking the wraparound into account
|
||||
targetCount = SysTick->LOAD - (us * SYSTICK_LOAD) + startCount + (SYSTICK_DELAY_CALIB);
|
||||
|
||||
// Wait until the SysTick reloads
|
||||
while(SysTick->VAL < startCount);
|
||||
startCount = SysTick->LOAD;
|
||||
}
|
||||
|
||||
// Wait until we count down until the targetCount
|
||||
while((SysTick->VAL > targetCount) && (SysTick->VAL < startCount));
|
||||
}
|
||||
126
YEEP144lib/src/YEEP144_ADCPot.c
Normal file
126
YEEP144lib/src/YEEP144_ADCPot.c
Normal file
@@ -0,0 +1,126 @@
|
||||
#include "YEEP144.h"
|
||||
#include "YEEP144_Pinout.h"
|
||||
#include "YEEP144_ADCPot.h"
|
||||
|
||||
#include "stm32h5xx_hal_adc.h"
|
||||
#include "stm32h5xx_hal_gpio.h"
|
||||
|
||||
#define ADC_TIMEOUT 1000
|
||||
|
||||
ADC_HandleTypeDef hadc2;
|
||||
|
||||
/**
|
||||
* Initialise the potentiometers. This consumes ADC2, along with 2 GPIO
|
||||
*/
|
||||
void YEEP144_ADCPot_Init(void){
|
||||
|
||||
// Setup and enable the ADC peripheral clock
|
||||
RCC_PeriphCLKInitTypeDef PeriphClkInitStruct = {0};
|
||||
|
||||
PeriphClkInitStruct.PeriphClockSelection = RCC_PERIPHCLK_ADCDAC;
|
||||
PeriphClkInitStruct.AdcDacClockSelection = RCC_ADCDACCLKSOURCE_HSI; // HSI = 64MHz input clock
|
||||
if (HAL_RCCEx_PeriphCLKConfig(&PeriphClkInitStruct) != HAL_OK){
|
||||
//Error_Handler();
|
||||
}
|
||||
|
||||
__HAL_RCC_ADC_CLK_ENABLE();
|
||||
|
||||
// Configure and initialise the ADC peripheral
|
||||
|
||||
hadc2.Instance = ADC2;
|
||||
hadc2.Init.ClockPrescaler = ADC_CLOCK_ASYNC_DIV1; // No clock division = 64MHz
|
||||
hadc2.Init.Resolution = ADC_RESOLUTION_12B; // 12-bit resolution (maximum)
|
||||
hadc2.Init.DataAlign = ADC_DATAALIGN_RIGHT;
|
||||
hadc2.Init.ScanConvMode = ADC_SCAN_ENABLE;
|
||||
hadc2.Init.EOCSelection = ADC_EOC_SINGLE_CONV;
|
||||
hadc2.Init.LowPowerAutoWait = DISABLE;
|
||||
hadc2.Init.ContinuousConvMode = DISABLE;
|
||||
hadc2.Init.NbrOfConversion = 2; // 2 channels in use
|
||||
hadc2.Init.DiscontinuousConvMode = DISABLE;
|
||||
hadc2.Init.ExternalTrigConv = ADC_SOFTWARE_START; // Conversion triggered by software
|
||||
hadc2.Init.ExternalTrigConvEdge = ADC_EXTERNALTRIGCONVEDGE_NONE;
|
||||
hadc2.Init.DMAContinuousRequests = DISABLE; // No DMA
|
||||
hadc2.Init.SamplingMode = ADC_SAMPLING_MODE_NORMAL;
|
||||
hadc2.Init.Overrun = ADC_OVR_DATA_PRESERVED;
|
||||
hadc2.Init.OversamplingMode = ENABLE; // Enable oversampling
|
||||
hadc2.Init.Oversampling.Ratio = ADC_OVERSAMPLING_RATIO_256; // 256x oversampling gets us 4 extra bits of resolution
|
||||
hadc2.Init.Oversampling.RightBitShift = ADC_RIGHTBITSHIFT_8; // Shift by 8 to get us back to 12-bit output
|
||||
hadc2.Init.Oversampling.TriggeredMode = ADC_TRIGGEREDMODE_SINGLE_TRIGGER;
|
||||
hadc2.Init.Oversampling.OversamplingStopReset = ADC_REGOVERSAMPLING_CONTINUED_MODE;
|
||||
if (HAL_ADC_Init(&hadc2) != HAL_OK){
|
||||
//Error_Handler();
|
||||
}
|
||||
|
||||
// Initialise the GPIO used
|
||||
YEEP144_GPIO_Init(POT1_PORT, POT1_PIN | POT2_PIN, GPIO_MODE_ANALOG);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the current value of potentiometer 1.
|
||||
* Returns a 12-bit value in the range 0 - 4095.
|
||||
* This blocks until the conversion is complete, ~1ms
|
||||
*/
|
||||
uint16_t YEEP144_ADCPot_GetPot1(void){
|
||||
|
||||
// Configure this channel to be converted next
|
||||
ADC_ChannelConfTypeDef sConfig = {0};
|
||||
sConfig.Channel = ADC_CHANNEL_2;
|
||||
sConfig.Rank = ADC_REGULAR_RANK_1;
|
||||
sConfig.SamplingTime = ADC_SAMPLETIME_247CYCLES_5;
|
||||
// With a 64MHz clock and 256x oversampling, 247.5 cycles sample gives us a conversion time of ~1ms
|
||||
// or a maximum sample rate of ~1kHz
|
||||
sConfig.SingleDiff = ADC_SINGLE_ENDED;
|
||||
sConfig.OffsetNumber = ADC_OFFSET_NONE;
|
||||
sConfig.Offset = 0;
|
||||
if (HAL_ADC_ConfigChannel(&hadc2, &sConfig) != HAL_OK){
|
||||
//Error_Handler();
|
||||
}
|
||||
|
||||
// Start the conversion
|
||||
HAL_ADC_Start(&hadc2);
|
||||
|
||||
// Wait until the conversion is finished
|
||||
HAL_ADC_PollForConversion(&hadc2, ADC_TIMEOUT);
|
||||
|
||||
// Grab the converted value now conversion is finished
|
||||
uint16_t adcval = HAL_ADC_GetValue(&hadc2);
|
||||
|
||||
// Stop the ADC
|
||||
HAL_ADC_Stop(&hadc2);
|
||||
|
||||
return adcval;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the current value of potentiometer 2.
|
||||
* Returns a 12-bit value in the range 0 - 4095.
|
||||
* This blocks until the conversion is complete, ~1ms
|
||||
*/
|
||||
uint16_t YEEP144_ADCPot_GetPot2(void){
|
||||
ADC_ChannelConfTypeDef sConfig = {0};
|
||||
sConfig.Channel = ADC_CHANNEL_6;
|
||||
sConfig.Rank = ADC_REGULAR_RANK_1;
|
||||
sConfig.SamplingTime = ADC_SAMPLETIME_247CYCLES_5;
|
||||
// With a 64MHz clock and 256x oversampling, 247.5 cycles sample gives us a conversion time of ~1ms
|
||||
// or a maximum sample rate of ~1kHz
|
||||
sConfig.SingleDiff = ADC_SINGLE_ENDED;
|
||||
sConfig.OffsetNumber = ADC_OFFSET_NONE;
|
||||
sConfig.Offset = 0;
|
||||
if (HAL_ADC_ConfigChannel(&hadc2, &sConfig) != HAL_OK){
|
||||
//Error_Handler();
|
||||
}
|
||||
|
||||
// Start the conversion
|
||||
HAL_ADC_Start(&hadc2);
|
||||
|
||||
// Wait until the conversion is finished
|
||||
HAL_ADC_PollForConversion(&hadc2, ADC_TIMEOUT);
|
||||
|
||||
// Grab the converted value now conversion is finished
|
||||
uint16_t adcval = HAL_ADC_GetValue(&hadc2);
|
||||
|
||||
// Stop the ADC
|
||||
HAL_ADC_Stop(&hadc2);
|
||||
|
||||
return adcval;
|
||||
}
|
||||
257
YEEP144lib/src/YEEP144_BluetoothUART.c
Normal file
257
YEEP144lib/src/YEEP144_BluetoothUART.c
Normal file
@@ -0,0 +1,257 @@
|
||||
// YEEP144 includes
|
||||
#include "YEEP144.h"
|
||||
#include "YEEP144_BluetoothUART.h"
|
||||
#include "YEEP144_Pinout.h"
|
||||
|
||||
// HAL includes
|
||||
#include "stm32h563xx.h"
|
||||
#include "stm32h5xx.h"
|
||||
#include "stm32h5xx_hal.h"
|
||||
#include "stm32h5xx_hal_cortex.h"
|
||||
#include "stm32h5xx_hal_dma.h"
|
||||
#include "stm32h5xx_hal_gpio_ex.h"
|
||||
#include "stm32h5xx_hal_rcc.h"
|
||||
#include "stm32h5xx_hal_uart.h"
|
||||
#include "stm32h5xx_hal_uart_ex.h"
|
||||
|
||||
// Std includes
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <stdarg.h>
|
||||
|
||||
#define UART_POLL_TIMEOUT 1000
|
||||
|
||||
// Structure for UART info
|
||||
UART_HandleTypeDef huart2;
|
||||
|
||||
DMA_HandleTypeDef handle_GPDMA1_Channel0;
|
||||
|
||||
/**
|
||||
* Initialises USART2 for use with the Bluetooth Serial addon board
|
||||
*
|
||||
* This consumes the USART2 peripheral and all of the UART pins on the comms headers
|
||||
* as well as Channel 0 on GPDMA1
|
||||
*/
|
||||
void YEEP144_BluetoothUART_Init(void){
|
||||
|
||||
// DMA clock and interrupt
|
||||
__HAL_RCC_GPDMA1_CLK_ENABLE();
|
||||
HAL_NVIC_SetPriority(GPDMA1_Channel0_IRQn, 0, 0);
|
||||
HAL_NVIC_EnableIRQ(GPDMA1_Channel0_IRQn);
|
||||
|
||||
// Initialise and start the clock
|
||||
|
||||
// Structure to hold clock config
|
||||
RCC_PeriphCLKInitTypeDef PeriphClkInitStruct = {0};
|
||||
|
||||
PeriphClkInitStruct.PeriphClockSelection = RCC_PERIPHCLK_USART2; // Configuring USART2
|
||||
PeriphClkInitStruct.Lptim3ClockSelection = RCC_USART2CLKSOURCE_PCLK1; // Select PCLK1
|
||||
if (HAL_RCCEx_PeriphCLKConfig(&PeriphClkInitStruct) != HAL_OK){
|
||||
//Error_Handler();
|
||||
}
|
||||
|
||||
// Enable the clock
|
||||
__HAL_RCC_USART2_CLK_ENABLE();
|
||||
|
||||
// Populate the UART struct with the configuration data
|
||||
// 115200 8-N-1 with flow control
|
||||
huart2.Instance = USART2;
|
||||
huart2.Init.BaudRate = 115200; // 115200 Baud rate
|
||||
huart2.Init.WordLength = UART_WORDLENGTH_8B; // 8 bit
|
||||
huart2.Init.Parity = UART_PARITY_NONE; // None parity
|
||||
huart2.Init.StopBits = UART_STOPBITS_1; // 1 Stop bit
|
||||
huart2.Init.Mode = UART_MODE_TX_RX; // Full duplex
|
||||
huart2.Init.HwFlowCtl = UART_HWCONTROL_RTS_CTS; // Full flow control (RTS, CTS)
|
||||
huart2.Init.OverSampling = UART_OVERSAMPLING_8;
|
||||
huart2.Init.ClockPrescaler = UART_PRESCALER_DIV1;
|
||||
if(HAL_UART_Init(&huart2) != HAL_OK){
|
||||
|
||||
}
|
||||
|
||||
// Initialise GPIO pins
|
||||
YEEP144_GPIO_InitAdv(UART2_TX_PORT, UART2_RX_PIN | UART2_TX_PIN | UART2_CTS_PIN | UART2_RTS_PIN, GPIO_MODE_AF_PP, GPIO_NOPULL, GPIO_SPEED_FREQ_LOW, GPIO_AF7_USART2);
|
||||
|
||||
// Enable USART IRQs
|
||||
HAL_NVIC_SetPriority(USART2_IRQn, 0, 0);
|
||||
HAL_NVIC_EnableIRQ(USART2_IRQn);
|
||||
|
||||
HAL_UARTEx_DisableFifoMode(&huart2);
|
||||
|
||||
// Populate DMA init structure
|
||||
handle_GPDMA1_Channel0.Instance = GPDMA1_Channel0;
|
||||
handle_GPDMA1_Channel0.Init.Request = GPDMA1_REQUEST_USART2_RX;
|
||||
handle_GPDMA1_Channel0.Init.BlkHWRequest = DMA_BREQ_SINGLE_BURST;
|
||||
handle_GPDMA1_Channel0.Init.Direction = DMA_PERIPH_TO_MEMORY;
|
||||
handle_GPDMA1_Channel0.Init.SrcInc = DMA_SINC_FIXED;
|
||||
handle_GPDMA1_Channel0.Init.DestInc = DMA_DINC_INCREMENTED;
|
||||
handle_GPDMA1_Channel0.Init.SrcDataWidth = DMA_SRC_DATAWIDTH_BYTE;
|
||||
handle_GPDMA1_Channel0.Init.DestDataWidth = DMA_DEST_DATAWIDTH_BYTE;
|
||||
handle_GPDMA1_Channel0.Init.Priority = DMA_LOW_PRIORITY_LOW_WEIGHT;
|
||||
handle_GPDMA1_Channel0.Init.SrcBurstLength = 1;
|
||||
handle_GPDMA1_Channel0.Init.DestBurstLength = 1;
|
||||
handle_GPDMA1_Channel0.Init.TransferAllocatedPort = DMA_SRC_ALLOCATED_PORT0|DMA_DEST_ALLOCATED_PORT0;
|
||||
handle_GPDMA1_Channel0.Init.TransferEventMode = DMA_TCEM_BLOCK_TRANSFER;
|
||||
handle_GPDMA1_Channel0.Init.Mode = DMA_NORMAL;
|
||||
if (HAL_DMA_Init(&handle_GPDMA1_Channel0) != HAL_OK)
|
||||
{
|
||||
//Error_Handler();
|
||||
}
|
||||
|
||||
__HAL_LINKDMA(&huart2, hdmarx, handle_GPDMA1_Channel0);
|
||||
|
||||
if (HAL_DMA_ConfigChannelAttributes(&handle_GPDMA1_Channel0, DMA_CHANNEL_NPRIV) != HAL_OK)
|
||||
{
|
||||
//Error_Handler();
|
||||
}
|
||||
|
||||
// Set default character match to carriage return
|
||||
YEEP144_BluetoothUART_SetCharMatch('\n');
|
||||
|
||||
// Disable buffering on stdin. This prevents problems when using scanf with the UART redirection
|
||||
setvbuf(stdin, NULL, _IONBF, 0);
|
||||
}
|
||||
|
||||
/**
|
||||
* Prints to the Bluetooth UART, regardless of what the default UART is set to.
|
||||
* Arguments and returns are the same as the default printf
|
||||
*
|
||||
* Internally this doesn't work using a stream like default printf, but uses a buffer, so the command may
|
||||
* fail if the buffer cannot be allocated, or the output may be truncated if expanding the format specifiers causes
|
||||
* the string to expand by more than 256 bytes
|
||||
*/
|
||||
int YEEP144_BluetoothUART_printf(const char * format, ...){
|
||||
// Calculate how long the input string is, plus extra space for substitition in the format specifiers
|
||||
size_t bufSize = strlen(format) + 256;
|
||||
|
||||
// Try to allocate that buffer
|
||||
char* buffer = malloc(bufSize);
|
||||
|
||||
// If the buffer cannot be allocated, return -1
|
||||
if (buffer == NULL) return -1;
|
||||
|
||||
// Get the pointer to the variadic args
|
||||
va_list args;
|
||||
va_start (args, format);
|
||||
|
||||
// Create our final string in the buffer using vsnprintf, passing through our argument pointer
|
||||
vsnprintf(buffer, bufSize, format, args);
|
||||
|
||||
// Calulate the final size of the string
|
||||
bufSize = strlen(buffer);
|
||||
|
||||
// Transmit over UART
|
||||
HAL_UART_Transmit(&huart2, (uint8_t*)buffer, bufSize, UART_POLL_TIMEOUT);
|
||||
|
||||
// Free the memory used
|
||||
free(buffer);
|
||||
|
||||
// Return number of characters printed
|
||||
return bufSize;
|
||||
}
|
||||
|
||||
/**
|
||||
* Enables the character match IRQ. When the configured character received an interrupt is fired.
|
||||
* The current transfer will be terminated and the YEEP144_BluetoothUART_MatchCallback will be called
|
||||
*/
|
||||
void YEEP144_BluetoothUART_EnableCharMatchIRQ(void){
|
||||
__HAL_UART_ENABLE_IT(&huart2, UART_IT_CM);
|
||||
}
|
||||
|
||||
/**
|
||||
* Disables the character match IRQ
|
||||
*/
|
||||
void YEEP144_BluetoothUART_DisableCharMatchIRQ(void){
|
||||
__HAL_UART_DISABLE_IT(&huart2, UART_IT_CM);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the character match IRQ character. When the configured character received an interrupt is fired.
|
||||
* The current transfer will be terminated and the YEEP144_BluetoothUART_MatchCallback will be called
|
||||
*/
|
||||
void YEEP144_BluetoothUART_SetCharMatch(char match){
|
||||
__HAL_UART_DISABLE(&huart2);
|
||||
MODIFY_REG(huart2.Instance->CR2, USART_CR2_ADD_Msk, match<< USART_CR2_ADD_Pos);
|
||||
__HAL_UART_ENABLE(&huart2);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the pre and post delimiters for the BT status messages
|
||||
* Setting both to null disables the status messages entirely
|
||||
*/
|
||||
void YEEP144_BluetoothUART_SetStatusDelimiter(char prefix, char postfix){
|
||||
|
||||
// Save this register so we can restore character match IRQ if needed
|
||||
uint32_t config = READ_REG(huart2.Instance->CR1);
|
||||
|
||||
// Disable the character match irq so it doesn't fire during this function
|
||||
YEEP144_BluetoothUART_DisableCharMatchIRQ();
|
||||
|
||||
uint8_t rxBuf[10];
|
||||
uint16_t rxSize;
|
||||
|
||||
// Enter command mode
|
||||
HAL_UART_Transmit(&huart2, "$$$", 3, UART_POLL_TIMEOUT);
|
||||
|
||||
// Wait to receive data back from BT module
|
||||
HAL_UARTEx_ReceiveToIdle(&huart2, rxBuf, 10, &rxSize, UART_POLL_TIMEOUT);
|
||||
|
||||
// Set delimiters
|
||||
char txBuf[8] = {0};
|
||||
if(prefix == '\0' && postfix == '\0'){
|
||||
sprintf(txBuf, "SO,,%c",'\r');
|
||||
}
|
||||
else if(prefix == '\0'){
|
||||
sprintf(txBuf, "SO,,%c%c", postfix, '\r');
|
||||
}
|
||||
else if(postfix == '\0'){
|
||||
sprintf(txBuf, "SO,%c,%c", prefix, '\r');
|
||||
}
|
||||
else{
|
||||
sprintf(txBuf, "SO,%c,%c%c", prefix, postfix, '\r');
|
||||
}
|
||||
HAL_UART_Transmit(&huart2, txBuf, sizeof(rxBuf), UART_POLL_TIMEOUT);
|
||||
|
||||
// Wait to receive data back from BT module
|
||||
HAL_UARTEx_ReceiveToIdle(&huart2, rxBuf, 10, &rxSize, UART_POLL_TIMEOUT);
|
||||
|
||||
// Reboot device to make changes
|
||||
HAL_UART_Transmit(&huart2, "R,1", 3, UART_POLL_TIMEOUT);
|
||||
|
||||
// Wait to receive data back from BT module
|
||||
HAL_UARTEx_ReceiveToIdle(&huart2, rxBuf, 10, &rxSize, UART_POLL_TIMEOUT);
|
||||
|
||||
// Re-enable the character match IRQ if it previously was
|
||||
if(config & USART_CR1_CMIE){
|
||||
YEEP144_BluetoothUART_EnableCharMatchIRQ();
|
||||
}
|
||||
}
|
||||
|
||||
#if UARTSEL == BLUETOOTHUART
|
||||
/**
|
||||
* This function overrides a function from the stdio library, effectively redirecting
|
||||
* output to the UART port. This means that printf can print directly to the UART.
|
||||
*/
|
||||
int __io_putchar(int ch){
|
||||
HAL_UART_Transmit(&huart2, (uint8_t *) &ch, 1, UART_POLL_TIMEOUT);
|
||||
return ch;
|
||||
}
|
||||
|
||||
/**
|
||||
* This function overrides a function from the stdio library, effectively redirecting
|
||||
* input from the UART port. This means that scanf can read directly from the UART.
|
||||
*/
|
||||
int __io_getchar(void){
|
||||
uint8_t ch = 0;
|
||||
|
||||
/* Clear the Overrun flag just before receiving the first character */
|
||||
__HAL_UART_CLEAR_OREFLAG(&huart2);
|
||||
|
||||
/* Wait for reception of a character on the USART RX line and echo this
|
||||
* character on console */
|
||||
HAL_UART_Receive(&huart2, (uint8_t *)&ch, 1, HAL_MAX_DELAY);
|
||||
HAL_UART_Transmit(&huart2, (uint8_t *)&ch, 1, HAL_MAX_DELAY);
|
||||
return ch;
|
||||
}
|
||||
#endif
|
||||
135
YEEP144lib/src/YEEP144_Buzzer.c
Normal file
135
YEEP144lib/src/YEEP144_Buzzer.c
Normal file
@@ -0,0 +1,135 @@
|
||||
#include "YEEP144.h"
|
||||
#include "YEEP144_Pinout.h"
|
||||
#include "YEEP144_Buzzer.h"
|
||||
#include "stm32h5xx_hal.h"
|
||||
#include "stm32h5xx_hal_gpio.h"
|
||||
#include "stm32h5xx_hal_gpio_ex.h"
|
||||
#include "stm32h5xx_hal_tim.h"
|
||||
|
||||
#include <math.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
TIM_HandleTypeDef htim17buzzer;
|
||||
|
||||
/**
|
||||
* Initialises the buzzer. This consumes timer 17 and 1 GPIO. This resource is shared with servo 4 - only 1 should be initialised
|
||||
* Ensure DIP switch SW5 is correctly set to enable the buzzer output. Set both to off when using servo 4 to avoid hearing
|
||||
* the servo PWM signal through the buzzer
|
||||
*/
|
||||
void YEEP144_Buzzer_Init(void){
|
||||
// Initialise TIM17
|
||||
|
||||
// Create structures to store our timer configuration information
|
||||
TIM_OC_InitTypeDef sConfigOC = {0};
|
||||
TIM_BreakDeadTimeConfigTypeDef sBreakDeadTimeConfig = {0};
|
||||
|
||||
// Enable the clock input to TIM3
|
||||
__HAL_RCC_TIM17_CLK_ENABLE();
|
||||
|
||||
// Setup our configuration data
|
||||
// Prescaler is set so that 1 timer tick = 1us for 250MHz input clock, as the frequency calculation assumes this
|
||||
htim17buzzer.Instance = TIM17;
|
||||
htim17buzzer.Init.Prescaler = 249;
|
||||
htim17buzzer.Init.CounterMode = TIM_COUNTERMODE_UP;
|
||||
htim17buzzer.Init.Period = 65535;
|
||||
htim17buzzer.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1;
|
||||
htim17buzzer.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_ENABLE;
|
||||
|
||||
// Initialise the timer
|
||||
if (HAL_TIM_PWM_Init(&htim17buzzer) != HAL_OK){
|
||||
//Error_Handler();
|
||||
}
|
||||
|
||||
// Configure the Output Compare (OC) settings
|
||||
// This determines how the PWM signal is generated based on the count of our timer
|
||||
sConfigOC.OCMode = TIM_OCMODE_PWM1; // Edge-Aligned mode
|
||||
sConfigOC.Pulse = 0; // Default CCR value for our duty cycle
|
||||
sConfigOC.OCPolarity = TIM_OCPOLARITY_HIGH; // Non-inverted polarity
|
||||
sConfigOC.OCNPolarity = TIM_OCNPOLARITY_HIGH;
|
||||
sConfigOC.OCFastMode = TIM_OCFAST_DISABLE;
|
||||
sConfigOC.OCIdleState = TIM_OCIDLESTATE_RESET;
|
||||
sConfigOC.OCNIdleState = TIM_OCNIDLESTATE_RESET;
|
||||
|
||||
// Configure the PWM channels
|
||||
if (HAL_TIM_PWM_ConfigChannel(&htim17buzzer, &sConfigOC, TIM_CHANNEL_1) != HAL_OK){
|
||||
//Error_Handler();
|
||||
}
|
||||
|
||||
// Disable the break dead time feature as its not needed
|
||||
sBreakDeadTimeConfig.OffStateRunMode = TIM_OSSR_DISABLE;
|
||||
sBreakDeadTimeConfig.OffStateIDLEMode = TIM_OSSI_DISABLE;
|
||||
sBreakDeadTimeConfig.LockLevel = TIM_LOCKLEVEL_OFF;
|
||||
sBreakDeadTimeConfig.DeadTime = 0;
|
||||
sBreakDeadTimeConfig.BreakState = TIM_BREAK_DISABLE;
|
||||
sBreakDeadTimeConfig.BreakPolarity = TIM_BREAKPOLARITY_HIGH;
|
||||
sBreakDeadTimeConfig.BreakFilter = 0;
|
||||
sBreakDeadTimeConfig.AutomaticOutput = TIM_AUTOMATICOUTPUT_DISABLE;
|
||||
if (HAL_TIMEx_ConfigBreakDeadTime(&htim17buzzer, &sBreakDeadTimeConfig) != HAL_OK){
|
||||
//Error_Handler();
|
||||
}
|
||||
|
||||
// Setup the GPIO output from the timer
|
||||
YEEP144_GPIO_InitAdv(BUZZER_PORT, BUZZER_PIN, GPIO_MODE_AF_PP, GPIO_NOPULL, GPIO_SPEED_FREQ_LOW, GPIO_AF1_TIM17);
|
||||
|
||||
// Start PWM generation
|
||||
HAL_TIM_PWM_Start(&htim17buzzer, TIM_CHANNEL_1);
|
||||
|
||||
// Default to no tone
|
||||
YEEP144_Buzzer_NoTone();
|
||||
}
|
||||
|
||||
/**
|
||||
* Sound the buzzer at the chosen frequency (Hz) for the alloted duration (ms)
|
||||
* This is blocking as it uses HAL_Delay to wait the alloted time
|
||||
*/
|
||||
void YEEP144_Buzzer_Tone(uint32_t freq, uint32_t duration){
|
||||
YEEP144_Buzzer_GoTone(freq); // Start playing the tone
|
||||
HAL_Delay(duration); // Wait for tone duration
|
||||
YEEP144_Buzzer_NoTone(); // Cease playing the tone
|
||||
}
|
||||
|
||||
/**
|
||||
* Sound the buzzer at the chosen frequency (Hz) continuously until stopped by NoTone
|
||||
* This is non-blocking, so you can go do other things while the tone is playing
|
||||
*/
|
||||
void YEEP144_Buzzer_GoTone(uint32_t freq){
|
||||
if(freq != 0){
|
||||
TIM17->ARR = (1000000UL / freq) - 1; // Set PWM frequency
|
||||
TIM17->CCR1 = (TIM17->ARR >> 1); // Set the duty cycle to 50% by setting Capture Compare Register to half the frequency
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Stops the buzzer from sounding by setting the duty cycle to 0%
|
||||
*/
|
||||
void YEEP144_Buzzer_NoTone(void){
|
||||
TIM17->CCR1 = 0; // Set duty cycle to 0%
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Buzzer rendition of Daisy Bell taken from:
|
||||
* https://github.com/ayoungblood/daisy-bell/blob/master/arduino/daisy_basic/daisy_basic.ino
|
||||
*/
|
||||
#define A440 440 // frequency constant
|
||||
#define QUARTER 180 // quarter note length in ms
|
||||
|
||||
const uint8_t DAISY_P[] = {
|
||||
74, 71, 67, 62, 64, 66, 67, 64, 67, 62,
|
||||
69, 74, 71, 67, 64, 66, 67, 69, 71, 69,
|
||||
71, 72, 71, 69, 74, 71, 69, 67, 69, 71, 67, 64, 67, 64, 62,
|
||||
62, 67, 71, 69, 67, 71, 69, 71, 72, 74, 71, 67, 69, 62, 67
|
||||
};
|
||||
const uint8_t DAISY_T[] = {
|
||||
3, 3, 3, 3, 1, 1, 1, 2, 1, 6,
|
||||
3, 3, 3, 3, 1, 1, 1, 2, 1, 6,
|
||||
1, 1, 1, 1, 2, 1, 1, 4, 1, 2, 1, 2, 1, 1, 5,
|
||||
1, 2, 1, 2, 2, 1, 1, 1, 1, 1, 1, 1, 2, 1, 5
|
||||
};
|
||||
|
||||
void YEEP144_Buzzer_Daisy(void){
|
||||
for(int i=0; i<50; ++i){
|
||||
float freq = pow(2,(DAISY_P[i]-69)/12.0f)*A440;
|
||||
YEEP144_Buzzer_Tone((uint32_t)freq, DAISY_T[i]*QUARTER);
|
||||
}
|
||||
}
|
||||
386
YEEP144lib/src/YEEP144_DCMotor.c
Normal file
386
YEEP144lib/src/YEEP144_DCMotor.c
Normal file
@@ -0,0 +1,386 @@
|
||||
// YEEP Includes
|
||||
#include "YEEP144.h"
|
||||
#include "YEEP144_DCMotor.h"
|
||||
#include "YEEP144_Pinout.h"
|
||||
|
||||
// HAL Includes
|
||||
#include "stm32h5xx_hal.h"
|
||||
#include "stm32h5xx_hal_gpio_ex.h"
|
||||
#include "stm32h5xx_hal_rcc.h"
|
||||
#include "stm32h5xx_hal_tim.h"
|
||||
#include "stm32h5xx_hal_lptim.h"
|
||||
#include "stm32h5xx_hal_gpio.h"
|
||||
|
||||
// System Includes
|
||||
#include <stdint.h>
|
||||
|
||||
// Structs for timer handles
|
||||
// TIM3 used for all 4 DC motors
|
||||
TIM_HandleTypeDef htim3;
|
||||
|
||||
// TIM3, LPTIM2, LPTIM3, LPTIM5 used for encoders
|
||||
TIM_HandleTypeDef htim4;
|
||||
LPTIM_HandleTypeDef hlptim2;
|
||||
LPTIM_HandleTypeDef hlptim3;
|
||||
LPTIM_HandleTypeDef hlptim5;
|
||||
|
||||
/**
|
||||
* Sets the specified motors speed by altering the duty cycle of the PWM signal
|
||||
* This is done by setting the Capture and Compare Register for the relevant channel
|
||||
* to a value between 0 and the Period of the timer where CCR = 0 is 0% duty cycle and
|
||||
* CCR = Period is 100% duty cycle
|
||||
*/
|
||||
void YEEP144_DCMotor_SetSpeed(uint8_t motor, uint16_t speed){
|
||||
// Cap speed if out of bounds
|
||||
if(speed > DCMOTOR_MAX_SPEED){
|
||||
speed = DCMOTOR_MAX_SPEED;
|
||||
}
|
||||
|
||||
// Update the Capture Compare Register (CCR) for the relevant motor channel
|
||||
switch(motor){
|
||||
case DCMOTOR1:
|
||||
TIM3->CCR1 = speed;
|
||||
break;
|
||||
case DCMOTOR2:
|
||||
TIM3->CCR2 = speed;
|
||||
break;
|
||||
case DCMOTOR3:
|
||||
TIM3->CCR3 = speed;
|
||||
break;
|
||||
case DCMOTOR4:
|
||||
TIM3->CCR4 = speed;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the two direction bits for the specified motor. There are 4 valid options
|
||||
* for stopping, counter-clockwise movement, clockwise movement, and a short
|
||||
* brake. There are #defines available for these states in YEEP144_DCMotor.h
|
||||
*/
|
||||
void YEEP144_DCMotor_SetDirection(uint8_t motor, uint8_t direction){
|
||||
// Check that the inputs are valid
|
||||
if(direction > 3 || motor > 4){
|
||||
return;
|
||||
}
|
||||
|
||||
// Set the direction GPIO pins
|
||||
// Some bit manipulation is used to mask the relevant bit and shift it into the LSB position
|
||||
if(motor == DCMOTOR1){
|
||||
HAL_GPIO_WritePin(MOT1A_PORT, MOT1A_PIN, (direction>>1) & 1);
|
||||
HAL_GPIO_WritePin(MOT1B_PORT, MOT1B_PIN, direction & 1);
|
||||
}
|
||||
else if (motor == DCMOTOR2) {
|
||||
HAL_GPIO_WritePin(MOT2A_PORT, MOT2A_PIN, (direction>>1) & 1);
|
||||
HAL_GPIO_WritePin(MOT2B_PORT, MOT2B_PIN, direction & 1);
|
||||
}
|
||||
else if (motor == DCMOTOR3) {
|
||||
HAL_GPIO_WritePin(MOT3A_PORT, MOT3A_PIN, (direction>>1) & 1);
|
||||
HAL_GPIO_WritePin(MOT3B_PORT, MOT3B_PIN, direction & 1);
|
||||
}
|
||||
else if (motor == DCMOTOR4) {
|
||||
HAL_GPIO_WritePin(MOT4A_PORT, MOT4A_PIN, (direction>>1) & 1);
|
||||
HAL_GPIO_WritePin(MOT4B_PORT, MOT4B_PIN, direction & 1);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the current value of encoder 1
|
||||
*/
|
||||
uint16_t YEEP144_Encoder1_Get(void){
|
||||
return TIM4->CNT;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the current value of encoder 2
|
||||
*/
|
||||
uint16_t YEEP144_Encoder2_Get(void){
|
||||
return LPTIM3->CNT;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the current value of encoder 3
|
||||
*/
|
||||
uint16_t YEEP144_Encoder3_Get(void){
|
||||
return LPTIM5->CNT;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the current value of encoder 4
|
||||
*/
|
||||
uint16_t YEEP144_Encoder4_Get(void){
|
||||
return LPTIM2->CNT;
|
||||
}
|
||||
|
||||
/**
|
||||
* This function initialises all 4 DC motor driver channels
|
||||
* They all share TIM3 for their PWM generation
|
||||
* After initialisation the PWM will be set to 0%, and direction set to STOP
|
||||
*
|
||||
* This consumes TIM3 and the 4 GPIO it outputs on, as well as the 8 GPIO used for motor direction control
|
||||
*/
|
||||
void YEEP144_DCMotor_Init(void){
|
||||
// Initialise TIM3
|
||||
|
||||
// Create structures to store our timer configuration information
|
||||
TIM_MasterConfigTypeDef sMasterConfig = {0};
|
||||
TIM_OC_InitTypeDef sConfigOC = {0};
|
||||
|
||||
// Enable the clock input to TIM3
|
||||
__HAL_RCC_TIM3_CLK_ENABLE();
|
||||
|
||||
// Setup our configuration data
|
||||
// For an input clock of 250MHz and a Period of 4095 these setting will produce
|
||||
// a PWM signal of ~61kHz which is within the range accepted by the motor driver
|
||||
|
||||
// 4095 was chosen as the period as it maps 1-to-1 with the reading from a 12-bit ADC
|
||||
htim3.Instance = TIM3;
|
||||
htim3.Init.Prescaler = 0;
|
||||
htim3.Init.CounterMode = TIM_COUNTERMODE_UP;
|
||||
htim3.Init.Period = DCMOTOR_MAX_SPEED;
|
||||
htim3.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1;
|
||||
htim3.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_DISABLE;
|
||||
|
||||
// Initialise the timer
|
||||
if (HAL_TIM_PWM_Init(&htim3) != HAL_OK){
|
||||
//Error_Handler();
|
||||
}
|
||||
|
||||
// Configure master output
|
||||
sMasterConfig.MasterOutputTrigger = TIM_TRGO_RESET;
|
||||
sMasterConfig.MasterSlaveMode = TIM_MASTERSLAVEMODE_DISABLE;
|
||||
if (HAL_TIMEx_MasterConfigSynchronization(&htim3, &sMasterConfig) != HAL_OK){
|
||||
//Error_Handler();
|
||||
}
|
||||
|
||||
// Configure the Output Compare (OC) settings
|
||||
// This determines how the PWM signal is generated based on the count of our timer
|
||||
sConfigOC.OCMode = TIM_OCMODE_PWM1; // Edge-Aligned mode
|
||||
sConfigOC.Pulse = 0; // Default CCR value for our duty cycle
|
||||
sConfigOC.OCPolarity = TIM_OCPOLARITY_HIGH; // Non-inverted polarity
|
||||
sConfigOC.OCFastMode = TIM_OCFAST_DISABLE; // Fast mode is not required for this application
|
||||
|
||||
// Configure the PWM channels
|
||||
if (HAL_TIM_PWM_ConfigChannel(&htim3, &sConfigOC, TIM_CHANNEL_1) != HAL_OK){
|
||||
//Error_Handler();
|
||||
}
|
||||
if (HAL_TIM_PWM_ConfigChannel(&htim3, &sConfigOC, TIM_CHANNEL_2) != HAL_OK){
|
||||
//Error_Handler();
|
||||
}
|
||||
if (HAL_TIM_PWM_ConfigChannel(&htim3, &sConfigOC, TIM_CHANNEL_3) != HAL_OK){
|
||||
//Error_Handler();
|
||||
}
|
||||
if (HAL_TIM_PWM_ConfigChannel(&htim3, &sConfigOC, TIM_CHANNEL_4) != HAL_OK){
|
||||
//Error_Handler();
|
||||
}
|
||||
|
||||
// Initialise GPIO pins used for PWM output
|
||||
// 3 of our PWM pins are on port C and 1 on port B
|
||||
// We must configure each port separately
|
||||
|
||||
YEEP144_GPIO_InitAdv(MOT1PWM_PORT, MOT1PWM_PIN | MOT2PWM_PIN | MOT4PWM_PIN, GPIO_MODE_AF_PP, GPIO_NOPULL, GPIO_SPEED_FREQ_LOW, GPIO_AF2_TIM3);
|
||||
YEEP144_GPIO_InitAdv(MOT3PWM_PORT, MOT3PWM_PIN, GPIO_MODE_AF_PP, GPIO_NOPULL, GPIO_SPEED_FREQ_LOW, GPIO_AF2_TIM3);
|
||||
|
||||
// Initialise GPIO for 2-bit direction control
|
||||
// The pins used are split across 3 ports
|
||||
// Each port must be configured separately
|
||||
|
||||
YEEP144_GPIO_Init(MOT1A_PORT, MOT1A_PIN | MOT1B_PIN | MOT2A_PIN | MOT2B_PIN, GPIO_MODE_OUTPUT);
|
||||
YEEP144_GPIO_Init(MOT3A_PORT, MOT3A_PIN | MOT3B_PIN, GPIO_MODE_OUTPUT);
|
||||
YEEP144_GPIO_Init(MOT4A_PORT, MOT4A_PIN | MOT4B_PIN, GPIO_MODE_OUTPUT);
|
||||
|
||||
// Set default outputs to stop
|
||||
YEEP144_DCMotor_SetDirection(DCMOTOR1, DCMOTOR_STOP);
|
||||
YEEP144_DCMotor_SetDirection(DCMOTOR2, DCMOTOR_STOP);
|
||||
YEEP144_DCMotor_SetDirection(DCMOTOR3, DCMOTOR_STOP);
|
||||
YEEP144_DCMotor_SetDirection(DCMOTOR4, DCMOTOR_STOP);
|
||||
|
||||
// Start all the PWM channels
|
||||
HAL_TIM_PWM_Start(&htim3, TIM_CHANNEL_1);
|
||||
HAL_TIM_PWM_Start(&htim3, TIM_CHANNEL_2);
|
||||
HAL_TIM_PWM_Start(&htim3, TIM_CHANNEL_3);
|
||||
HAL_TIM_PWM_Start(&htim3, TIM_CHANNEL_4);
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* This initialises Encoder 1
|
||||
* This consumes TIM4 and the two GPIO it takes input from
|
||||
*/
|
||||
void YEEP144_Encoder1_Init(void){
|
||||
// Initialise TIM4
|
||||
|
||||
// Enable TIM4 clock
|
||||
__HAL_RCC_TIM4_CLK_ENABLE();
|
||||
|
||||
// Create structs to hold config data
|
||||
TIM_Encoder_InitTypeDef sConfig = {0};
|
||||
TIM_MasterConfigTypeDef sMasterConfig = {0};
|
||||
|
||||
htim4.Instance = TIM4;
|
||||
htim4.Init.Prescaler = 0;
|
||||
htim4.Init.CounterMode = TIM_COUNTERMODE_UP;
|
||||
htim4.Init.Period = 65535;
|
||||
htim4.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1;
|
||||
htim4.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_DISABLE;
|
||||
|
||||
// Configure encoder mode and input channels
|
||||
sConfig.EncoderMode = TIM_ENCODERMODE_TI1;
|
||||
sConfig.IC1Polarity = TIM_ICPOLARITY_RISING;
|
||||
sConfig.IC1Selection = TIM_ICSELECTION_DIRECTTI;
|
||||
sConfig.IC1Prescaler = TIM_ICPSC_DIV1;
|
||||
sConfig.IC1Filter = 0;
|
||||
sConfig.IC2Polarity = TIM_ICPOLARITY_RISING;
|
||||
sConfig.IC2Selection = TIM_ICSELECTION_DIRECTTI;
|
||||
sConfig.IC2Prescaler = TIM_ICPSC_DIV1;
|
||||
sConfig.IC2Filter = 0;
|
||||
|
||||
// Initialise the timer
|
||||
if (HAL_TIM_Encoder_Init(&htim4, &sConfig) != HAL_OK){
|
||||
//Error_Handler();
|
||||
}
|
||||
|
||||
sMasterConfig.MasterOutputTrigger = TIM_TRGO_RESET;
|
||||
sMasterConfig.MasterSlaveMode = TIM_MASTERSLAVEMODE_DISABLE;
|
||||
if (HAL_TIMEx_MasterConfigSynchronization(&htim4, &sMasterConfig) != HAL_OK){
|
||||
//Error_Handler();
|
||||
}
|
||||
|
||||
// Initialise the GPIO used for the encoder input
|
||||
YEEP144_GPIO_InitAdv(ENC1A_PORT, ENC1A_PIN | ENC1B_PIN, GPIO_MODE_AF_PP, GPIO_NOPULL, GPIO_SPEED_FREQ_LOW, GPIO_AF2_TIM4);
|
||||
|
||||
// Start the encoder counting
|
||||
HAL_TIM_Encoder_Start(&htim4, TIM_CHANNEL_ALL);
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* This initialises Encoder 2
|
||||
* This consumes LPTIM3 and the two GPIO it takes input from
|
||||
*/
|
||||
void YEEP144_Encoder2_Init(void){
|
||||
|
||||
// Setup clock for LPTIM3
|
||||
|
||||
RCC_PeriphCLKInitTypeDef PeriphClkInitStruct = {0};
|
||||
|
||||
PeriphClkInitStruct.PeriphClockSelection = RCC_PERIPHCLK_LPTIM3;
|
||||
PeriphClkInitStruct.Lptim3ClockSelection = RCC_LPTIM3CLKSOURCE_PCLK3;
|
||||
if (HAL_RCCEx_PeriphCLKConfig(&PeriphClkInitStruct) != HAL_OK){
|
||||
//Error_Handler();
|
||||
}
|
||||
|
||||
// Enable clock for LPTIM3
|
||||
__HAL_RCC_LPTIM3_CLK_ENABLE();
|
||||
|
||||
// Configure LPTIM3 for encoder input mode
|
||||
hlptim3.Instance = LPTIM3;
|
||||
hlptim3.Init.Clock.Source = LPTIM_CLOCKSOURCE_APBCLOCK_LPOSC;
|
||||
hlptim3.Init.Clock.Prescaler = LPTIM_PRESCALER_DIV1;
|
||||
hlptim3.Init.UltraLowPowerClock.Polarity = LPTIM_CLOCKPOLARITY_RISING;
|
||||
hlptim3.Init.UltraLowPowerClock.SampleTime = LPTIM_CLOCKSAMPLETIME_DIRECTTRANSITION;
|
||||
hlptim3.Init.Trigger.Source = LPTIM_TRIGSOURCE_SOFTWARE;
|
||||
hlptim3.Init.Period = 65535;
|
||||
hlptim3.Init.UpdateMode = LPTIM_UPDATE_IMMEDIATE;
|
||||
hlptim3.Init.CounterSource = LPTIM_COUNTERSOURCE_EXTERNAL;
|
||||
hlptim3.Init.Input1Source = LPTIM_INPUT1SOURCE_GPIO;
|
||||
hlptim3.Init.Input2Source = LPTIM_INPUT2SOURCE_GPIO;
|
||||
hlptim3.Init.RepetitionCounter = 0;
|
||||
if (HAL_LPTIM_Init(&hlptim3) != HAL_OK){
|
||||
//Error_Handler();
|
||||
}
|
||||
|
||||
// Initialise the GPIO used for the encoder input
|
||||
YEEP144_GPIO_InitAdv(ENC2A_PORT, ENC2A_PIN, GPIO_MODE_AF_PP, GPIO_NOPULL, GPIO_SPEED_FREQ_LOW, GPIO_AF2_LPTIM3);
|
||||
YEEP144_GPIO_InitAdv(ENC2B_PORT, ENC2B_PIN, GPIO_MODE_AF_PP, GPIO_NOPULL, GPIO_SPEED_FREQ_LOW, GPIO_AF2_LPTIM3);
|
||||
|
||||
// Start the encoder counting
|
||||
HAL_LPTIM_Encoder_Start(&hlptim3);
|
||||
}
|
||||
|
||||
/**
|
||||
* This initialises Encoder 3
|
||||
* This consumes LPTIM5 and the two GPIO it takes input from
|
||||
*/
|
||||
void YEEP144_Encoder3_Init(void){
|
||||
|
||||
// Setup clock for LPTIM5
|
||||
|
||||
RCC_PeriphCLKInitTypeDef PeriphClkInitStruct = {0};
|
||||
|
||||
PeriphClkInitStruct.PeriphClockSelection = RCC_PERIPHCLK_LPTIM5;
|
||||
PeriphClkInitStruct.Lptim3ClockSelection = RCC_LPTIM3CLKSOURCE_PCLK3;
|
||||
if (HAL_RCCEx_PeriphCLKConfig(&PeriphClkInitStruct) != HAL_OK){
|
||||
//Error_Handler();
|
||||
}
|
||||
|
||||
// Enable clock for LPTIM3
|
||||
__HAL_RCC_LPTIM5_CLK_ENABLE();
|
||||
|
||||
// Configure LPTIM5 for encoder input mode
|
||||
hlptim5.Instance = LPTIM5;
|
||||
hlptim5.Init.Clock.Source = LPTIM_CLOCKSOURCE_APBCLOCK_LPOSC;
|
||||
hlptim5.Init.Clock.Prescaler = LPTIM_PRESCALER_DIV1;
|
||||
hlptim5.Init.UltraLowPowerClock.Polarity = LPTIM_CLOCKPOLARITY_RISING;
|
||||
hlptim5.Init.UltraLowPowerClock.SampleTime = LPTIM_CLOCKSAMPLETIME_DIRECTTRANSITION;
|
||||
hlptim5.Init.Trigger.Source = LPTIM_TRIGSOURCE_SOFTWARE;
|
||||
hlptim5.Init.Period = 65535;
|
||||
hlptim5.Init.UpdateMode = LPTIM_UPDATE_IMMEDIATE;
|
||||
hlptim5.Init.CounterSource = LPTIM_COUNTERSOURCE_EXTERNAL;
|
||||
hlptim5.Init.Input1Source = LPTIM_INPUT1SOURCE_GPIO;
|
||||
hlptim5.Init.Input2Source = LPTIM_INPUT2SOURCE_GPIO;
|
||||
hlptim5.Init.RepetitionCounter = 0;
|
||||
if (HAL_LPTIM_Init(&hlptim5) != HAL_OK){
|
||||
//Error_Handler();
|
||||
}
|
||||
|
||||
// Initialise the GPIO used for the encoder input
|
||||
YEEP144_GPIO_InitAdv(ENC3A_PORT, ENC3A_PIN | ENC3B_PIN, GPIO_MODE_AF_PP, GPIO_NOPULL, GPIO_SPEED_FREQ_LOW, GPIO_AF13_LPTIM5);
|
||||
|
||||
// Start the encoder counting
|
||||
HAL_LPTIM_Encoder_Start(&hlptim5);
|
||||
}
|
||||
|
||||
/**
|
||||
* This initialises Encoder 4
|
||||
* This consumes LPTIM2 and the two GPIO it takes input from
|
||||
*/
|
||||
void YEEP144_Encoder4_Init(void){
|
||||
|
||||
// Setup clock for LPTIM2
|
||||
|
||||
RCC_PeriphCLKInitTypeDef PeriphClkInitStruct = {0};
|
||||
|
||||
PeriphClkInitStruct.PeriphClockSelection = RCC_PERIPHCLK_LPTIM2;
|
||||
PeriphClkInitStruct.Lptim3ClockSelection = RCC_LPTIM3CLKSOURCE_PCLK3;
|
||||
if (HAL_RCCEx_PeriphCLKConfig(&PeriphClkInitStruct) != HAL_OK){
|
||||
//Error_Handler();
|
||||
}
|
||||
|
||||
// Enable clock for LPTIM2
|
||||
__HAL_RCC_LPTIM2_CLK_ENABLE();
|
||||
|
||||
// Configure LPTIM2 for encoder input mode
|
||||
hlptim2.Instance = LPTIM2;
|
||||
hlptim2.Init.Clock.Source = LPTIM_CLOCKSOURCE_APBCLOCK_LPOSC;
|
||||
hlptim2.Init.Clock.Prescaler = LPTIM_PRESCALER_DIV1;
|
||||
hlptim2.Init.UltraLowPowerClock.Polarity = LPTIM_CLOCKPOLARITY_RISING;
|
||||
hlptim2.Init.UltraLowPowerClock.SampleTime = LPTIM_CLOCKSAMPLETIME_DIRECTTRANSITION;
|
||||
hlptim2.Init.Trigger.Source = LPTIM_TRIGSOURCE_SOFTWARE;
|
||||
hlptim2.Init.Period = 65535;
|
||||
hlptim2.Init.UpdateMode = LPTIM_UPDATE_IMMEDIATE;
|
||||
hlptim2.Init.CounterSource = LPTIM_COUNTERSOURCE_EXTERNAL;
|
||||
hlptim2.Init.Input1Source = LPTIM_INPUT1SOURCE_GPIO;
|
||||
hlptim2.Init.Input2Source = LPTIM_INPUT2SOURCE_GPIO;
|
||||
hlptim2.Init.RepetitionCounter = 0;
|
||||
if (HAL_LPTIM_Init(&hlptim2) != HAL_OK){
|
||||
//Error_Handler();
|
||||
}
|
||||
|
||||
// Initialise the GPIO used for the encoder input
|
||||
YEEP144_GPIO_InitAdv(ENC4A_PORT, ENC4A_PIN, GPIO_MODE_AF_PP, GPIO_NOPULL, GPIO_SPEED_FREQ_LOW, GPIO_AF3_LPTIM2);
|
||||
YEEP144_GPIO_InitAdv(ENC4B_PORT, ENC4B_PIN, GPIO_MODE_AF_PP, GPIO_NOPULL, GPIO_SPEED_FREQ_LOW, GPIO_AF3_LPTIM2);
|
||||
|
||||
// Start the encoder counting
|
||||
HAL_LPTIM_Encoder_Start(&hlptim2);
|
||||
}
|
||||
200
YEEP144lib/src/YEEP144_DebugUART.c
Normal file
200
YEEP144lib/src/YEEP144_DebugUART.c
Normal file
@@ -0,0 +1,200 @@
|
||||
// YEEP144 includes
|
||||
#include "YEEP144.h"
|
||||
#include "YEEP144_DebugUART.h"
|
||||
#include "YEEP144_Pinout.h"
|
||||
|
||||
// HAL includes
|
||||
#include "stm32h563xx.h"
|
||||
#include "stm32h5xx_hal.h"
|
||||
#include "stm32h5xx_hal_uart.h"
|
||||
|
||||
// Std includes
|
||||
#include <stdio.h>
|
||||
#include <stdarg.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#define UART_POLL_TIMEOUT 1000
|
||||
|
||||
// Structure for UART info
|
||||
UART_HandleTypeDef huart3;
|
||||
|
||||
DMA_HandleTypeDef handle_GPDMA1_Channel1;
|
||||
|
||||
/**
|
||||
* Initialises USART3 for use as a debug console output via the STLink
|
||||
* Virtual COM Port (VCP)
|
||||
*
|
||||
* This consumes the USART3 peripheral and no YEEP GPIO as it is routed internally
|
||||
* on the Nucleo board and is not broken out
|
||||
*/
|
||||
void YEEP144_DebugUART_Init(void){
|
||||
|
||||
// Initialise and start the clock
|
||||
|
||||
// DMA clock and interrupt
|
||||
__HAL_RCC_GPDMA1_CLK_ENABLE();
|
||||
HAL_NVIC_SetPriority(GPDMA1_Channel1_IRQn, 0, 0);
|
||||
HAL_NVIC_EnableIRQ(GPDMA1_Channel1_IRQn);
|
||||
|
||||
// Structure to hold clock config
|
||||
RCC_PeriphCLKInitTypeDef PeriphClkInitStruct = {0};
|
||||
|
||||
PeriphClkInitStruct.PeriphClockSelection = RCC_PERIPHCLK_USART3; // Configuring USART3
|
||||
PeriphClkInitStruct.Lptim3ClockSelection = RCC_USART3CLKSOURCE_PCLK1; // Select PCLK1
|
||||
if (HAL_RCCEx_PeriphCLKConfig(&PeriphClkInitStruct) != HAL_OK){
|
||||
//Error_Handler();
|
||||
}
|
||||
|
||||
// Enable the clock
|
||||
__HAL_RCC_USART3_CLK_ENABLE();
|
||||
|
||||
// Populate the UART struct with the configuration data
|
||||
// 115200 8-N-1
|
||||
huart3.Instance = USART3;
|
||||
huart3.Init.BaudRate = 115200; // 115200 Baud rate
|
||||
huart3.Init.WordLength = UART_WORDLENGTH_8B; // 8 bit
|
||||
huart3.Init.Parity = UART_PARITY_NONE; // None parity
|
||||
huart3.Init.StopBits = UART_STOPBITS_1; // 1 Stop bit
|
||||
huart3.Init.Mode = UART_MODE_TX_RX; // Full duplex
|
||||
huart3.Init.HwFlowCtl = UART_HWCONTROL_NONE; // No hardware flow control (RTS, CTS)
|
||||
huart3.Init.OverSampling = UART_OVERSAMPLING_8;
|
||||
huart3.Init.ClockPrescaler = UART_PRESCALER_DIV1;
|
||||
if(HAL_UART_Init(&huart3) != HAL_OK){
|
||||
|
||||
}
|
||||
|
||||
// Initialise GPIO pins
|
||||
YEEP144_GPIO_InitAdv(UART3_TX_PORT, UART3_RX_PIN | UART3_TX_PIN, GPIO_MODE_AF_PP, GPIO_NOPULL, GPIO_SPEED_FREQ_LOW, GPIO_AF7_USART3);
|
||||
|
||||
|
||||
// Enable USART IRQs
|
||||
HAL_NVIC_SetPriority(USART3_IRQn, 0, 0);
|
||||
HAL_NVIC_EnableIRQ(USART3_IRQn);
|
||||
|
||||
HAL_UARTEx_DisableFifoMode(&huart3);
|
||||
|
||||
// Populate DMA init structure
|
||||
handle_GPDMA1_Channel1.Instance = GPDMA1_Channel1;
|
||||
handle_GPDMA1_Channel1.Init.Request = GPDMA1_REQUEST_USART3_RX;
|
||||
handle_GPDMA1_Channel1.Init.BlkHWRequest = DMA_BREQ_SINGLE_BURST;
|
||||
handle_GPDMA1_Channel1.Init.Direction = DMA_PERIPH_TO_MEMORY;
|
||||
handle_GPDMA1_Channel1.Init.SrcInc = DMA_SINC_FIXED;
|
||||
handle_GPDMA1_Channel1.Init.DestInc = DMA_DINC_INCREMENTED;
|
||||
handle_GPDMA1_Channel1.Init.SrcDataWidth = DMA_SRC_DATAWIDTH_BYTE;
|
||||
handle_GPDMA1_Channel1.Init.DestDataWidth = DMA_DEST_DATAWIDTH_BYTE;
|
||||
handle_GPDMA1_Channel1.Init.Priority = DMA_LOW_PRIORITY_LOW_WEIGHT;
|
||||
handle_GPDMA1_Channel1.Init.SrcBurstLength = 1;
|
||||
handle_GPDMA1_Channel1.Init.DestBurstLength = 1;
|
||||
handle_GPDMA1_Channel1.Init.TransferAllocatedPort = DMA_SRC_ALLOCATED_PORT0|DMA_DEST_ALLOCATED_PORT0;
|
||||
handle_GPDMA1_Channel1.Init.TransferEventMode = DMA_TCEM_BLOCK_TRANSFER;
|
||||
handle_GPDMA1_Channel1.Init.Mode = DMA_NORMAL;
|
||||
if (HAL_DMA_Init(&handle_GPDMA1_Channel1) != HAL_OK)
|
||||
{
|
||||
//Error_Handler();
|
||||
}
|
||||
|
||||
__HAL_LINKDMA(&huart3, hdmarx, handle_GPDMA1_Channel1);
|
||||
|
||||
if (HAL_DMA_ConfigChannelAttributes(&handle_GPDMA1_Channel1, DMA_CHANNEL_NPRIV) != HAL_OK)
|
||||
{
|
||||
//Error_Handler();
|
||||
}
|
||||
|
||||
// Set default character match to carriage return
|
||||
YEEP144_DebugUART_SetCharMatch('\r');
|
||||
|
||||
// Disable buffering on stdin. This prevents problems when using scanf with the UART redirection
|
||||
setvbuf(stdin, NULL, _IONBF, 0);
|
||||
}
|
||||
|
||||
/**
|
||||
* Prints to the Debug UART, regardless of what the default UART is set to.
|
||||
* Arguments and returns are the same as the default printf
|
||||
*
|
||||
* Internally this doesn't work using a stream like default printf, but uses a buffer, so the command may
|
||||
* fail if the buffer cannot be allocated, or the output may be truncated if expanding the format specifiers causes
|
||||
* the string to expand by more than 256 bytes
|
||||
*/
|
||||
int YEEP144_DebugUART_printf(const char * format, ...){
|
||||
// Calculate how long the input string is, plus extra space for substitition in the format specifiers
|
||||
size_t bufSize = strlen(format) + 256;
|
||||
|
||||
// Try to allocate that buffer
|
||||
char* buffer = malloc(bufSize);
|
||||
|
||||
// If the buffer cannot be allocated, return -1
|
||||
if (buffer == NULL) return -1;
|
||||
|
||||
// Get the pointer to the variadic args
|
||||
va_list args;
|
||||
va_start (args, format);
|
||||
|
||||
// Create our final string in the buffer using vsnprintf, passing through our argument pointer
|
||||
vsnprintf(buffer, bufSize, format, args);
|
||||
|
||||
// Calulate the final size of the string
|
||||
bufSize = strlen(buffer);
|
||||
|
||||
// Transmit over UART
|
||||
HAL_UART_Transmit(&huart3, (uint8_t*)buffer, bufSize, UART_POLL_TIMEOUT);
|
||||
|
||||
// Free the memory used
|
||||
free(buffer);
|
||||
|
||||
// Return number of characters printed
|
||||
return bufSize;
|
||||
}
|
||||
|
||||
/**
|
||||
* Enables the character match IRQ. When the configured character received an interrupt is fired.
|
||||
* The current transfer will be terminated and the YEEP144_DebugUART_MatchCallback will be called
|
||||
*/
|
||||
void YEEP144_DebugUART_EnableCharMatchIRQ(void){
|
||||
__HAL_UART_ENABLE_IT(&huart3, UART_IT_CM);
|
||||
}
|
||||
|
||||
/**
|
||||
* Disables the character match IRQ
|
||||
*/
|
||||
void YEEP144_DebugUART_DisableCharMatchIRQ(void){
|
||||
__HAL_UART_DISABLE_IT(&huart3, UART_IT_CM);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the character match IRQ character. When the configured character received an interrupt is fired.
|
||||
* The current transfer will be terminated and the YEEP144_DebugUART_MatchCallback will be called
|
||||
*/
|
||||
void YEEP144_DebugUART_SetCharMatch(char match){
|
||||
__HAL_UART_DISABLE(&huart3);
|
||||
MODIFY_REG(huart3.Instance->CR2, USART_CR2_ADD_Msk, match<< USART_CR2_ADD_Pos);
|
||||
__HAL_UART_ENABLE(&huart3);
|
||||
}
|
||||
|
||||
#if UARTSEL == DEBUG
|
||||
/**
|
||||
* This function overrides a function from the stdio library, effectively redirecting
|
||||
* output to the UART port. This means that printf can print directly to the UART.
|
||||
*/
|
||||
int __io_putchar(int ch){
|
||||
HAL_UART_Transmit(&huart3, (uint8_t *) &ch, 1, UART_POLL_TIMEOUT);
|
||||
return ch;
|
||||
}
|
||||
|
||||
/**
|
||||
* This function overrides a function from the stdio library, effectively redirecting
|
||||
* input from the UART port. This means that scanf can read directly from the UART.
|
||||
*/
|
||||
int __io_getchar(void){
|
||||
uint8_t ch = 0;
|
||||
|
||||
/* Clear the Overrun flag just before receiving the first character */
|
||||
__HAL_UART_CLEAR_OREFLAG(&huart3);
|
||||
|
||||
/* Wait for reception of a character on the USART RX line and echo this
|
||||
* character on console */
|
||||
HAL_UART_Receive(&huart3, (uint8_t *)&ch, 1, HAL_MAX_DELAY);
|
||||
HAL_UART_Transmit(&huart3, (uint8_t *)&ch, 1, HAL_MAX_DELAY);
|
||||
return ch;
|
||||
}
|
||||
#endif
|
||||
18
YEEP144lib/src/YEEP144_GP2Y0E02B.c
Normal file
18
YEEP144lib/src/YEEP144_GP2Y0E02B.c
Normal file
@@ -0,0 +1,18 @@
|
||||
#include "YEEP144_GP2Y0E02B.h"
|
||||
#include "YEEP144_I2C.h"
|
||||
#include "stm32h5xx_hal_i2c.h"
|
||||
|
||||
#include <math.h>
|
||||
|
||||
#define I2C_TIMEOUT 1000
|
||||
|
||||
float YEEP144_GP2Y0E02B_Read(void){
|
||||
uint8_t IRShift;
|
||||
uint8_t IRValues[2] ={0};
|
||||
|
||||
HAL_I2C_Mem_Read(&hi2c2, GP2Y0E02B_I2C_ADDR, GP2Y0E02B_SHIFT_REG_ADDR, I2C_MEMADD_SIZE_8BIT, &IRShift, 1, I2C_TIMEOUT);
|
||||
HAL_I2C_Mem_Read(&hi2c2, GP2Y0E02B_I2C_ADDR, GP2Y0E02B_DISTANCE_REG_ADDR, I2C_MEMADD_SIZE_8BIT, IRValues, 2, I2C_TIMEOUT);
|
||||
|
||||
return ((IRValues[0]*16.0) + IRValues[1])/ 16.0 / pow(2.0, IRShift);
|
||||
|
||||
}
|
||||
596
YEEP144lib/src/YEEP144_HCSR04.c
Normal file
596
YEEP144lib/src/YEEP144_HCSR04.c
Normal file
@@ -0,0 +1,596 @@
|
||||
#include "YEEP144_HCSR04.h"
|
||||
#include "YEEP144.h"
|
||||
#include "YEEP144_Pinout.h"
|
||||
#include "stm32h5xx_hal.h"
|
||||
#include "stm32h5xx_hal_cortex.h"
|
||||
#include "stm32h5xx_hal_exti.h"
|
||||
#include "stm32h5xx_hal_gpio.h"
|
||||
#include "stm32h5xx_hal_tim.h"
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#define USONIC_PING_LEN 10
|
||||
#define BLOCKING_TIMEOUT_TICKS 1000
|
||||
|
||||
#define USONIC1_MASK (1 << 0)
|
||||
#define USONIC2_MASK (1 << 1)
|
||||
#define USONIC3_MASK (1 << 2)
|
||||
#define USONIC4_MASK (1 << 3)
|
||||
|
||||
uint8_t ultrasonicInit = 0;
|
||||
uint8_t ultrasonicTIMInit = 0;
|
||||
|
||||
uint8_t ultrasonicNextPing = USONIC1_MASK;
|
||||
uint8_t ultrasonicPing = 0;
|
||||
uint8_t ultrasonicEcho = 0;
|
||||
|
||||
uint16_t ultrasonicTickStart[4];
|
||||
uint16_t ultrasonicTickLen[4];
|
||||
|
||||
TIM_HandleTypeDef htim6;
|
||||
|
||||
EXTI_HandleTypeDef hexti12;
|
||||
EXTI_ConfigTypeDef hexti12_conf;
|
||||
|
||||
void YEEP144_Ultrasonic_TIMInit(void);
|
||||
|
||||
void YEEP144_Ultrasonic1_Callback(uint16_t ticks);
|
||||
void YEEP144_Ultrasonic2_Callback(uint16_t ticks);
|
||||
void YEEP144_Ultrasonic3_Callback(uint16_t ticks);
|
||||
void YEEP144_Ultrasonic4_Callback(uint16_t ticks);
|
||||
|
||||
|
||||
/**
|
||||
* Initialises ultrasonic sensor 1. This consumes the two GPIO assigned to that sensor,
|
||||
* TIM6 (shared by all 4 ultrasonics), and EXTI line 10 (share by the first 3 ultrasonics)
|
||||
*/
|
||||
void YEEP144_Ultrasonic1_Init(void){
|
||||
YEEP144_GPIO_Init(USONIC1_TRIG_PORT, USONIC1_TRIG_PIN, GPIO_MODE_OUTPUT);
|
||||
HAL_NVIC_SetPriority(USONIC1_ECHO_EXTI, 1, 0);
|
||||
HAL_NVIC_EnableIRQ(USONIC1_ECHO_EXTI);
|
||||
ultrasonicInit |= USONIC1_MASK;
|
||||
|
||||
// Only initialise the timer if it hasn't already
|
||||
if(ultrasonicTIMInit == 0){
|
||||
YEEP144_Ultrasonic_TIMInit();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Initialises ultrasonic sensor 2. This consumes the two GPIO assigned to that sensor,
|
||||
* TIM6 (shared by all 4 ultrasonics), and EXTI line 10 (share by the first 3 ultrasonics)
|
||||
*/
|
||||
void YEEP144_Ultrasonic2_Init(void){
|
||||
YEEP144_GPIO_Init(USONIC2_TRIG_PORT, USONIC2_TRIG_PIN, GPIO_MODE_OUTPUT);
|
||||
HAL_NVIC_SetPriority(USONIC2_ECHO_EXTI, 1, 0);
|
||||
HAL_NVIC_EnableIRQ(USONIC2_ECHO_EXTI);
|
||||
ultrasonicInit |= USONIC2_MASK;
|
||||
|
||||
// Only initialise the timer if it hasn't already
|
||||
if(ultrasonicTIMInit == 0){
|
||||
YEEP144_Ultrasonic_TIMInit();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Initialises ultrasonic sensor 3. This consumes the two GPIO assigned to that sensor,
|
||||
* TIM6 (shared by all 4 ultrasonics), and EXTI line 10 (share by the first 3 ultrasonics)
|
||||
*/
|
||||
void YEEP144_Ultrasonic3_Init(void){
|
||||
YEEP144_GPIO_Init(USONIC3_TRIG_PORT, USONIC3_TRIG_PIN, GPIO_MODE_OUTPUT);
|
||||
HAL_NVIC_SetPriority(USONIC3_ECHO_EXTI, 1, 0);
|
||||
HAL_NVIC_EnableIRQ(USONIC4_ECHO_EXTI);
|
||||
ultrasonicInit |= USONIC3_MASK;
|
||||
|
||||
// Only initialise the timer if it hasn't already
|
||||
if(ultrasonicTIMInit == 0){
|
||||
YEEP144_Ultrasonic_TIMInit();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Initialises ultrasonic sensor 4. This consumes the two GPIO assigned to that sensor,
|
||||
* TIM6 (shared by all 4 ultrasonics), and EXTI line 12 (shared with button 3 / red)
|
||||
*/
|
||||
void YEEP144_Ultrasonic4_Init(void){
|
||||
YEEP144_GPIO_Init(USONIC4_TRIG_PORT, USONIC4_TRIG_PIN, GPIO_MODE_OUTPUT);
|
||||
HAL_NVIC_SetPriority(USONIC4_ECHO_EXTI, 1, 0);
|
||||
HAL_NVIC_EnableIRQ(USONIC4_ECHO_EXTI);
|
||||
ultrasonicInit |= USONIC4_MASK;
|
||||
|
||||
// Only initialise the timer if it hasn't already
|
||||
if(ultrasonicTIMInit == 0){
|
||||
YEEP144_Ultrasonic_TIMInit();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Starts a reading on the next sensor in the sequence using the non-blocking method, skipping over any uninitialised sensors
|
||||
* Only 1 sensor can be read at a time as they (mostly) share the same EXTI line, so this function
|
||||
* checks to make sure that noting else is currently pinging.
|
||||
*
|
||||
* If no sensor is currently initialised returns 255
|
||||
* If a sensor is already pinging, return 0
|
||||
* If a new reading is successfully started, return the status byte indicating which sensor is currently pinging
|
||||
*
|
||||
* The relevant callback function will be called when pinging finishes and a new distance value is available
|
||||
*/
|
||||
uint8_t YEEP144_Ultrasonic_PingNext(void){
|
||||
|
||||
// If nothing is currently pinging
|
||||
if(!ultrasonicPing){
|
||||
// What is the next in the sequence
|
||||
switch(ultrasonicNextPing){
|
||||
case USONIC1_MASK:
|
||||
// Only start if it is enabled
|
||||
if(ultrasonicInit&USONIC1_MASK){
|
||||
// Reinitialise the pin to setup the interrupt
|
||||
YEEP144_GPIO_Init(USONIC1_ECHO_PORT, USONIC1_ECHO_PIN, GPIO_MODE_IT_RISING_FALLING);
|
||||
|
||||
// Toggle the pin on for 10uS
|
||||
HAL_GPIO_WritePin(USONIC1_TRIG_PORT, USONIC1_TRIG_PIN, GPIO_PIN_SET);
|
||||
delayUS(USONIC_PING_LEN);
|
||||
HAL_GPIO_WritePin(USONIC1_TRIG_PORT, USONIC1_TRIG_PIN, GPIO_PIN_RESET);
|
||||
|
||||
// Set the ping bit so we know this sensor is pinging
|
||||
ultrasonicPing |= USONIC1_MASK;
|
||||
|
||||
// Move to next sensor
|
||||
ultrasonicNextPing = USONIC2_MASK;
|
||||
break; // Break is within the if statement, so if a sensor is not initialised it will fall through to the next
|
||||
}
|
||||
else{
|
||||
// Move to next sensor
|
||||
ultrasonicNextPing = USONIC2_MASK;
|
||||
}
|
||||
// fallthrough
|
||||
case USONIC2_MASK:
|
||||
if(ultrasonicInit&USONIC2_MASK){
|
||||
// Reinitialise the pin to setup the interrupt
|
||||
YEEP144_GPIO_Init(USONIC2_ECHO_PORT, USONIC2_ECHO_PIN, GPIO_MODE_IT_RISING_FALLING);
|
||||
|
||||
// Toggle the pin on for 10uS
|
||||
HAL_GPIO_WritePin(USONIC2_TRIG_PORT, USONIC2_TRIG_PIN, GPIO_PIN_SET);
|
||||
delayUS(USONIC_PING_LEN);
|
||||
HAL_GPIO_WritePin(USONIC2_TRIG_PORT, USONIC2_TRIG_PIN, GPIO_PIN_RESET);
|
||||
|
||||
// Set the ping bit so we know this sensor is pinging
|
||||
ultrasonicPing |= USONIC2_MASK;
|
||||
|
||||
// Move to next sensor
|
||||
ultrasonicNextPing = USONIC3_MASK;
|
||||
break; // Break is within the if statement, so if a sensor is not initialised it will fall through to the next
|
||||
}
|
||||
else{
|
||||
// Move to next sensor
|
||||
ultrasonicNextPing = USONIC3_MASK;
|
||||
}
|
||||
// fallthrough
|
||||
case USONIC3_MASK:
|
||||
if(ultrasonicInit&USONIC3_MASK){
|
||||
// Reinitialise the pin to setup the interrupt
|
||||
YEEP144_GPIO_Init(USONIC3_ECHO_PORT, USONIC3_ECHO_PIN, GPIO_MODE_IT_RISING_FALLING);
|
||||
|
||||
// Toggle the pin on for 10uS
|
||||
HAL_GPIO_WritePin(USONIC3_TRIG_PORT, USONIC3_TRIG_PIN, GPIO_PIN_SET);
|
||||
delayUS(USONIC_PING_LEN);
|
||||
HAL_GPIO_WritePin(USONIC3_TRIG_PORT, USONIC3_TRIG_PIN, GPIO_PIN_RESET);
|
||||
|
||||
// Set the ping bit so we know this sensor is pinging
|
||||
ultrasonicPing |= USONIC3_MASK;
|
||||
|
||||
// Move to next sensor
|
||||
ultrasonicNextPing = USONIC4_MASK;
|
||||
break; // Break is within the if statement, so if a sensor is not initialised it will fall through to the next
|
||||
}
|
||||
else{
|
||||
// Move to next sensor
|
||||
ultrasonicNextPing = USONIC4_MASK;
|
||||
}
|
||||
// fallthrough
|
||||
case USONIC4_MASK:
|
||||
if(ultrasonicInit&USONIC4_MASK){
|
||||
// As the interrupt line for ultrasonic 4 is shared with pushbutton 3,
|
||||
// we want to save the EXTI configuration to restore when pinging is finished
|
||||
HAL_EXTI_GetHandle(&hexti12, EXTI_LINE_12);
|
||||
HAL_EXTI_GetConfigLine(&hexti12, &hexti12_conf);
|
||||
|
||||
// Reinitialise the pin to setup the interrupt
|
||||
YEEP144_GPIO_Init(USONIC4_ECHO_PORT, USONIC4_ECHO_PIN, GPIO_MODE_IT_RISING_FALLING);
|
||||
|
||||
// Toggle the pin on for 10uS
|
||||
HAL_GPIO_WritePin(USONIC4_TRIG_PORT, USONIC4_TRIG_PIN, GPIO_PIN_SET);
|
||||
delayUS(USONIC_PING_LEN);
|
||||
HAL_GPIO_WritePin(USONIC4_TRIG_PORT, USONIC4_TRIG_PIN, GPIO_PIN_RESET);
|
||||
|
||||
// Set the ping bit so we know this sensor is pinging
|
||||
ultrasonicPing |= USONIC4_MASK;
|
||||
|
||||
// Move to next sensor
|
||||
ultrasonicNextPing = USONIC1_MASK;
|
||||
break; // Break is within the if statement, so if a sensor is not initialised it will fall through to the next
|
||||
}
|
||||
else{
|
||||
// Move to next sensor
|
||||
ultrasonicNextPing = USONIC1_MASK;
|
||||
}
|
||||
|
||||
}
|
||||
// If a ping was successfully started return the status byte, else return 255
|
||||
if(!ultrasonicPing){
|
||||
return ultrasonicPing;
|
||||
}
|
||||
else{
|
||||
// This should only happen if this function is called with no sensor initialised
|
||||
return 255;
|
||||
}
|
||||
}
|
||||
else{
|
||||
// Returns 0 if a sensor is already pinging
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Starts a reading on ultrasonic 1 using the non-blocking method
|
||||
*
|
||||
* If no sensor is currently initialised returns 255
|
||||
* If a sensor is already pinging, return 0
|
||||
* If a new reading is successfully started, return the status byte indicating which sensor is currently pinging
|
||||
*
|
||||
* YEEP144_Ultrasonic1_Callback will be called when a new value is available
|
||||
*/
|
||||
uint8_t YEEP144_Ultrasonic1_Ping(void){
|
||||
ultrasonicNextPing = USONIC1_MASK;
|
||||
return YEEP144_Ultrasonic_PingNext();
|
||||
}
|
||||
|
||||
/**
|
||||
* Starts a reading on ultrasonic 2 using the non-blocking method
|
||||
*
|
||||
* If no sensor is currently initialised returns 255
|
||||
* If a sensor is already pinging, return 0
|
||||
* If a new reading is successfully started, return the status byte indicating which sensor is currently pinging
|
||||
*
|
||||
* YEEP144_Ultrasonic2_Callback will be called when a new value is available
|
||||
*/
|
||||
uint8_t YEEP144_Ultrasonic2_Ping(void){
|
||||
ultrasonicNextPing = USONIC2_MASK;
|
||||
return YEEP144_Ultrasonic_PingNext();
|
||||
}
|
||||
|
||||
/**
|
||||
* Starts a reading on ultrasonic 3 using the non-blocking method
|
||||
*
|
||||
* If no sensor is currently initialised returns 255
|
||||
* If a sensor is already pinging, return 0
|
||||
* If a new reading is successfully started, return the status byte indicating which sensor is currently pinging
|
||||
*
|
||||
* YEEP144_Ultrasonic3_Callback will be called when a new value is available
|
||||
*/
|
||||
uint8_t YEEP144_Ultrasonic3_Ping(void){
|
||||
ultrasonicNextPing = USONIC3_MASK;
|
||||
return YEEP144_Ultrasonic_PingNext();
|
||||
}
|
||||
|
||||
/**
|
||||
* Starts a reading on ultrasonic 4 using the non-blocking method
|
||||
*
|
||||
* If no sensor is currently initialised returns 255
|
||||
* If a sensor is already pinging, return 0
|
||||
* If a new reading is successfully started, return the status byte indicating which sensor is currently pinging
|
||||
*
|
||||
* YEEP144_Ultrasonic4_Callback will be called when a new value is available
|
||||
*/
|
||||
uint8_t YEEP144_Ultrasonic4_Ping(void){
|
||||
ultrasonicNextPing = USONIC4_MASK;
|
||||
return YEEP144_Ultrasonic_PingNext();
|
||||
}
|
||||
|
||||
/**
|
||||
* Starts a reading on ultrasonic 1 with blocking waits until the new value is available
|
||||
*
|
||||
* Returns 0 if the sensor is not initialised, or the function times out, otherwise returns the tick value
|
||||
*
|
||||
* YEEP144_Ultrasonic1_Callback will still be called when the new value is available
|
||||
*
|
||||
*/
|
||||
uint16_t YEEP144_Ultrasonic1_PingBlocking(void){
|
||||
|
||||
uint32_t blockingTimeoutStart = HAL_GetTick();
|
||||
|
||||
uint8_t pingReturn;
|
||||
// Attempt pings until successful
|
||||
// If 255 is returned, sensor is uninitialised, so fail and return 0
|
||||
// If we exceed timeout then return 0;
|
||||
do{
|
||||
pingReturn = YEEP144_Ultrasonic1_Ping();
|
||||
if(pingReturn == 255) return 0;
|
||||
if((HAL_GetTick()- blockingTimeoutStart) >= BLOCKING_TIMEOUT_TICKS) return 0;
|
||||
} while(pingReturn != USONIC1_MASK);
|
||||
|
||||
// Wait until pinging starts
|
||||
// If we exceed timeout then return 0
|
||||
while(ultrasonicPing != USONIC1_MASK){
|
||||
if((HAL_GetTick()- blockingTimeoutStart) >= BLOCKING_TIMEOUT_TICKS) return 0;
|
||||
}
|
||||
|
||||
// Wait until pinging ends
|
||||
// If we exceed timeout then return 0
|
||||
while(ultrasonicPing == USONIC1_MASK){
|
||||
if((HAL_GetTick()- blockingTimeoutStart) >= BLOCKING_TIMEOUT_TICKS) return 0;
|
||||
}
|
||||
|
||||
// Return the read value
|
||||
return ultrasonicTickLen[0];
|
||||
}
|
||||
|
||||
/**
|
||||
* Starts a reading on ultrasonic 2 with blocking waits until the new value is available
|
||||
*
|
||||
* Returns 0 if the sensor is not initialised, or the function times out, otherwise returns the tick value
|
||||
*
|
||||
* YEEP144_Ultrasonic1_Callback will still be called when the new value is available
|
||||
*
|
||||
*/
|
||||
uint16_t YEEP144_Ultrasonic2_PingBlocking(void){
|
||||
|
||||
uint32_t blockingTimeoutStart = HAL_GetTick();
|
||||
|
||||
uint8_t pingReturn;
|
||||
// Attempt pings until successful
|
||||
// If 255 is returned, sensor is uninitialised, so fail and return 0
|
||||
// If we exceed timeout then return 0;
|
||||
do{
|
||||
pingReturn = YEEP144_Ultrasonic2_Ping();
|
||||
if(pingReturn == 255) return 0;
|
||||
if((HAL_GetTick()- blockingTimeoutStart) >= BLOCKING_TIMEOUT_TICKS) return 0;
|
||||
} while(pingReturn != USONIC2_MASK);
|
||||
|
||||
// Wait until pinging starts
|
||||
// If we exceed timeout then return 0
|
||||
while(ultrasonicPing != USONIC2_MASK){
|
||||
if((HAL_GetTick()- blockingTimeoutStart) >= BLOCKING_TIMEOUT_TICKS) return 0;
|
||||
}
|
||||
|
||||
// Wait until pinging ends
|
||||
// If we exceed timeout then return 0
|
||||
while(ultrasonicPing == USONIC2_MASK){
|
||||
if((HAL_GetTick()- blockingTimeoutStart) >= BLOCKING_TIMEOUT_TICKS) return 0;
|
||||
}
|
||||
|
||||
// Return the read value
|
||||
return ultrasonicTickLen[1];
|
||||
}
|
||||
|
||||
/**
|
||||
* Starts a reading on ultrasonic 3 with blocking waits until the new value is available
|
||||
*
|
||||
* Returns 0 if the sensor is not initialised, or the function times out, otherwise returns the tick value
|
||||
*
|
||||
* YEEP144_Ultrasonic1_Callback will still be called when the new value is available
|
||||
*
|
||||
*/
|
||||
uint16_t YEEP144_Ultrasonic3_PingBlocking(void){
|
||||
|
||||
uint32_t blockingTimeoutStart = HAL_GetTick();
|
||||
|
||||
uint8_t pingReturn;
|
||||
// Attempt pings until successful
|
||||
// If 255 is returned, sensor is uninitialised, so fail and return 0
|
||||
// If we exceed timeout then return 0;
|
||||
do{
|
||||
pingReturn = YEEP144_Ultrasonic3_Ping();
|
||||
if(pingReturn == 255) return 0;
|
||||
if((HAL_GetTick()- blockingTimeoutStart) >= BLOCKING_TIMEOUT_TICKS) return 0;
|
||||
} while(pingReturn != USONIC3_MASK);
|
||||
|
||||
// Wait until pinging starts
|
||||
// If we exceed timeout then return 0
|
||||
while(ultrasonicPing != USONIC3_MASK){
|
||||
if((HAL_GetTick()- blockingTimeoutStart) >= BLOCKING_TIMEOUT_TICKS) return 0;
|
||||
}
|
||||
|
||||
// Wait until pinging ends
|
||||
// If we exceed timeout then return 0
|
||||
while(ultrasonicPing == USONIC3_MASK){
|
||||
if((HAL_GetTick()- blockingTimeoutStart) >= BLOCKING_TIMEOUT_TICKS) return 0;
|
||||
}
|
||||
|
||||
// Return the read value
|
||||
return ultrasonicTickLen[2];
|
||||
}
|
||||
|
||||
/**
|
||||
* Starts a reading on ultrasonic 4 with blocking waits until the new value is available
|
||||
*
|
||||
* Returns 0 if the sensor is not initialised, or the function times out, otherwise returns the tick value
|
||||
*
|
||||
* YEEP144_Ultrasonic1_Callback will still be called when the new value is available
|
||||
*
|
||||
*/
|
||||
uint16_t YEEP144_Ultrasonic4_PingBlocking(void){
|
||||
|
||||
uint32_t blockingTimeoutStart = HAL_GetTick();
|
||||
|
||||
uint8_t pingReturn;
|
||||
// Attempt pings until successful
|
||||
// If 255 is returned, sensor is uninitialised, so fail and return 0
|
||||
// If we exceed timeout then return 0;
|
||||
do{
|
||||
pingReturn = YEEP144_Ultrasonic4_Ping();
|
||||
if(pingReturn == 255) return 0;
|
||||
if((HAL_GetTick()- blockingTimeoutStart) >= BLOCKING_TIMEOUT_TICKS) return 0;
|
||||
} while(pingReturn != USONIC4_MASK);
|
||||
|
||||
// Wait until pinging starts
|
||||
// If we exceed timeout then return 0
|
||||
while(ultrasonicPing != USONIC4_MASK){
|
||||
if((HAL_GetTick()- blockingTimeoutStart) >= BLOCKING_TIMEOUT_TICKS) return 0;
|
||||
}
|
||||
|
||||
// Wait until pinging ends
|
||||
// If we exceed timeout then return 0
|
||||
while(ultrasonicPing == USONIC4_MASK){
|
||||
if((HAL_GetTick()- blockingTimeoutStart) >= BLOCKING_TIMEOUT_TICKS) return 0;
|
||||
}
|
||||
|
||||
// Return the read value
|
||||
return ultrasonicTickLen[3];
|
||||
}
|
||||
|
||||
/**
|
||||
* This function handles the interrupt for sensors 1, 2, and 3 connected to EXTI 10
|
||||
* This should be called from the main EXTI10 IRQ handler found in YEEP144_IRQ.c
|
||||
*/
|
||||
void YEEP144_Ultrasonic_EXTI10Handler(void){
|
||||
// Store the value from the timer at the start of the ISR to avoid execution time affecting the result
|
||||
uint16_t TIMVal = __HAL_TIM_GET_COUNTER(&htim6);
|
||||
|
||||
// Rising edge interrupt means pulse is starting
|
||||
if(__HAL_GPIO_EXTI_GET_RISING_IT(USONIC1_ECHO_PIN)){
|
||||
// Check to see which sensor is currently pinging based on the GPIO and the ping status byte
|
||||
if((HAL_GPIO_ReadPin(USONIC1_ECHO_PORT, USONIC1_ECHO_PIN) == GPIO_PIN_SET) && (ultrasonicPing & USONIC1_MASK)){
|
||||
// Store the starting timer value and set the relevant status bit
|
||||
ultrasonicTickStart[0] = TIMVal;
|
||||
ultrasonicEcho |= USONIC1_MASK;
|
||||
}
|
||||
if((HAL_GPIO_ReadPin(USONIC2_ECHO_PORT, USONIC2_ECHO_PIN) == GPIO_PIN_SET) && (ultrasonicPing & USONIC2_MASK)){
|
||||
ultrasonicTickStart[1] = TIMVal;
|
||||
ultrasonicEcho |= USONIC2_MASK;
|
||||
}
|
||||
if((HAL_GPIO_ReadPin(USONIC3_ECHO_PORT, USONIC3_ECHO_PIN) == GPIO_PIN_SET) && (ultrasonicPing & USONIC3_MASK)){
|
||||
ultrasonicTickStart[2] = TIMVal;
|
||||
ultrasonicEcho |= USONIC3_MASK;
|
||||
}
|
||||
__HAL_GPIO_EXTI_CLEAR_RISING_IT(USONIC1_ECHO_PIN); // Clear the interrupt
|
||||
return;
|
||||
}
|
||||
// Falling edge interrupt means pulse is ending
|
||||
else if(__HAL_GPIO_EXTI_GET_FALLING_IT(USONIC1_ECHO_PIN)){
|
||||
// Check which sensor is pinging based on the GPIO and status byte
|
||||
if((HAL_GPIO_ReadPin(USONIC1_ECHO_PORT, USONIC1_ECHO_PIN) == GPIO_PIN_RESET) && (ultrasonicEcho & USONIC1_MASK)){
|
||||
// Reset the status bits
|
||||
ultrasonicPing &= ~USONIC1_MASK;
|
||||
ultrasonicEcho &= ~USONIC1_MASK;
|
||||
ultrasonicTickLen[0] = TIMVal - ultrasonicTickStart[0]; // Calculate the time elapsed
|
||||
YEEP144_Ultrasonic1_Callback(ultrasonicTickLen[0]); // Call the relevant callback function to signal the reading is done
|
||||
}
|
||||
if((HAL_GPIO_ReadPin(USONIC2_ECHO_PORT, USONIC2_ECHO_PIN) == GPIO_PIN_RESET) && (ultrasonicEcho & USONIC2_MASK)){
|
||||
ultrasonicPing &= ~USONIC2_MASK;
|
||||
ultrasonicEcho &= ~USONIC2_MASK;
|
||||
ultrasonicTickLen[1] = TIMVal - ultrasonicTickStart[1];
|
||||
YEEP144_Ultrasonic2_Callback(ultrasonicTickLen[1]);
|
||||
}
|
||||
if((HAL_GPIO_ReadPin(USONIC3_ECHO_PORT, USONIC3_ECHO_PIN) == GPIO_PIN_RESET) && (ultrasonicEcho & USONIC3_MASK)){
|
||||
ultrasonicPing &= ~USONIC3_MASK;
|
||||
ultrasonicEcho &= ~USONIC3_MASK;
|
||||
ultrasonicTickLen[2] = TIMVal - ultrasonicTickStart[2];
|
||||
YEEP144_Ultrasonic3_Callback(ultrasonicTickLen[2]);
|
||||
}
|
||||
__HAL_GPIO_EXTI_CLEAR_FALLING_IT(USONIC1_ECHO_PIN); // Clear the interrupt
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* This function handles the interrupt for sensor 4 connected to EXTI 12
|
||||
* This should be called from the main EXTI12 IRQ handler found in YEEP144_IRQ.c
|
||||
*/
|
||||
void YEEP144_Ultrasonic_EXTI12Handler(void){
|
||||
// Store the value from the timer at the start of the ISR to avoid execution time affecting the result
|
||||
uint16_t TIMVal = __HAL_TIM_GET_COUNTER(&htim6);
|
||||
|
||||
// Rising edge interrupt means pulse is starting
|
||||
if(__HAL_GPIO_EXTI_GET_RISING_IT(USONIC4_ECHO_PIN)){
|
||||
// Check to see which sensor is currently pinging based on the GPIO and the ping status byte
|
||||
if((HAL_GPIO_ReadPin(USONIC4_ECHO_PORT, USONIC4_ECHO_PIN) == GPIO_PIN_SET) && (ultrasonicPing & USONIC4_MASK)){
|
||||
// Store the starting timer value and set the relevant status bit
|
||||
ultrasonicTickStart[3] = TIMVal;
|
||||
ultrasonicEcho |= USONIC4_MASK;
|
||||
}
|
||||
__HAL_GPIO_EXTI_CLEAR_RISING_IT(USONIC4_ECHO_PIN); // Clear the interrupt
|
||||
return;
|
||||
}
|
||||
// Falling edge interrupt means pulse is ending
|
||||
else if(__HAL_GPIO_EXTI_GET_FALLING_IT(USONIC4_ECHO_PIN)){
|
||||
// Check which sensor is pinging based on the GPIO and status byte
|
||||
if((HAL_GPIO_ReadPin(USONIC4_ECHO_PORT, USONIC4_ECHO_PIN) == GPIO_PIN_RESET) && (ultrasonicEcho & USONIC4_MASK)){
|
||||
// Reset the status bits
|
||||
ultrasonicPing &= ~USONIC4_MASK;
|
||||
ultrasonicEcho &= ~USONIC4_MASK;
|
||||
ultrasonicTickLen[3] = TIMVal - ultrasonicTickStart[3]; // Calculate the time elapsed
|
||||
YEEP144_Ultrasonic4_Callback(ultrasonicTickLen[3]); // Call the relevant callback function to signal the reading is done
|
||||
}
|
||||
__HAL_GPIO_EXTI_CLEAR_FALLING_IT(USONIC4_ECHO_PIN); // Clear the interrupt
|
||||
// Restore the previous exti configuration
|
||||
HAL_EXTI_GetHandle(&hexti12, EXTI_LINE_12);
|
||||
HAL_EXTI_SetConfigLine(&hexti12, &hexti12_conf);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper function to convert timer ticks to a centimeter value
|
||||
*/
|
||||
float YEEP144_Ultrasonic_TickTocm(uint16_t ticks){
|
||||
// Total number of ticks is return trip time, we halve it to get distance to object
|
||||
// Speed of sound taken as 343m/s = 34300 cm/s = 0.0343 cm/us
|
||||
return ticks/2.0 * 0.0343;
|
||||
}
|
||||
|
||||
/**
|
||||
* Internal function used to initialise the timer used for measuring the received pulses
|
||||
*/
|
||||
void YEEP144_Ultrasonic_TIMInit(void){
|
||||
|
||||
// Enable the clock to the timer
|
||||
__HAL_RCC_TIM6_CLK_ENABLE();
|
||||
|
||||
// Create empty config structure
|
||||
TIM_MasterConfigTypeDef sMasterConfig = {0};
|
||||
|
||||
// Populate config structure. The should configure it for 1uS per tick, assuming 250MHz peripheral clock
|
||||
htim6.Instance = TIM6;
|
||||
htim6.Init.Prescaler = 249;
|
||||
htim6.Init.CounterMode = TIM_COUNTERMODE_UP;
|
||||
htim6.Init.Period = 65535;
|
||||
htim6.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_DISABLE;
|
||||
if (HAL_TIM_Base_Init(&htim6) != HAL_OK){
|
||||
//Error_Handler();
|
||||
}
|
||||
sMasterConfig.MasterOutputTrigger = TIM_TRGO_RESET;
|
||||
sMasterConfig.MasterSlaveMode = TIM_MASTERSLAVEMODE_DISABLE;
|
||||
if (HAL_TIMEx_MasterConfigSynchronization(&htim6, &sMasterConfig) != HAL_OK){
|
||||
//Error_Handler();
|
||||
}
|
||||
|
||||
// Start the counting. This counter is left free running as relevant functions
|
||||
// calculate time elapsed by recording the value at the start and end of an event
|
||||
HAL_TIM_Base_Start(&htim6);
|
||||
|
||||
// Set the init flag so the timer doesn't get initialised multiple times
|
||||
ultrasonicTIMInit = 1;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* These callback functions are weakly defined so they can be overwritten by the user's
|
||||
* own callback function. They have to exist at least in weak form so that the code compiles
|
||||
* even if the user chooses not to define their own
|
||||
*/
|
||||
__weak void YEEP144_Ultrasonic1_Callback(uint16_t ticks){
|
||||
|
||||
}
|
||||
|
||||
__weak void YEEP144_Ultrasonic2_Callback(uint16_t ticks){
|
||||
|
||||
}
|
||||
|
||||
__weak void YEEP144_Ultrasonic3_Callback(uint16_t ticks){
|
||||
|
||||
}
|
||||
|
||||
__weak void YEEP144_Ultrasonic4_Callback(uint16_t ticks){
|
||||
|
||||
}
|
||||
70
YEEP144lib/src/YEEP144_I2C.c
Normal file
70
YEEP144lib/src/YEEP144_I2C.c
Normal file
@@ -0,0 +1,70 @@
|
||||
#include "YEEP144.h"
|
||||
#include "YEEP144_I2C.h"
|
||||
#include "YEEP144_Pinout.h"
|
||||
|
||||
#include "stm32h5xx_hal.h"
|
||||
#include "stm32h5xx_hal_gpio_ex.h"
|
||||
#include "stm32h5xx_hal_i2c.h"
|
||||
#include <stdint.h>
|
||||
|
||||
I2C_HandleTypeDef hi2c2;
|
||||
|
||||
void YEEP144_I2C_MuxSelect(uint8_t busNumber){
|
||||
uint8_t I2CBusSel;
|
||||
|
||||
// If busNumber is greater than 3, deselect all busses
|
||||
if(busNumber > 3){
|
||||
I2CBusSel = 0;
|
||||
}
|
||||
else{ // Else convert to 1-hot to activate bus
|
||||
I2CBusSel = 1 << busNumber;
|
||||
}
|
||||
|
||||
// Send byte to mux chip to select bus
|
||||
HAL_I2C_Master_Transmit(&hi2c2, I2C_MUX_ADDR, &I2CBusSel, 1, 1000);
|
||||
}
|
||||
|
||||
void YEEP144_I2C_Init(void){
|
||||
// Initialise and start the clock
|
||||
|
||||
// Structure to hold clock config
|
||||
RCC_PeriphCLKInitTypeDef PeriphClkInitStruct = {0};
|
||||
|
||||
PeriphClkInitStruct.PeriphClockSelection = RCC_PERIPHCLK_I2C2; // Configuring I2C2
|
||||
PeriphClkInitStruct.Lptim3ClockSelection = RCC_I2C2CLKSOURCE_PCLK1; // Select PCLK1
|
||||
if (HAL_RCCEx_PeriphCLKConfig(&PeriphClkInitStruct) != HAL_OK){
|
||||
//Error_Handler();
|
||||
}
|
||||
|
||||
// Enable the clock
|
||||
__HAL_RCC_I2C2_CLK_ENABLE();
|
||||
|
||||
// Configure the peripheral
|
||||
hi2c2.Instance = I2C2;
|
||||
hi2c2.Init.Timing = 0x60808CD3; // Magic number taken from MX for 100KHz - see Reference Manual RM0481, section 48.4.5
|
||||
|
||||
// We are not operating as a target, so the rest are just defaults
|
||||
hi2c2.Init.OwnAddress1 = 0;
|
||||
hi2c2.Init.AddressingMode = I2C_ADDRESSINGMODE_7BIT;
|
||||
hi2c2.Init.DualAddressMode = I2C_DUALADDRESS_DISABLE;
|
||||
hi2c2.Init.OwnAddress2 = 0;
|
||||
hi2c2.Init.OwnAddress2Masks = I2C_OA2_NOMASK;
|
||||
hi2c2.Init.GeneralCallMode = I2C_GENERALCALL_DISABLE;
|
||||
hi2c2.Init.NoStretchMode = I2C_NOSTRETCH_DISABLE;
|
||||
if (HAL_I2C_Init(&hi2c2) != HAL_OK){
|
||||
//Error_Handler();
|
||||
}
|
||||
|
||||
//Configure Analogue filter (Enabled, which is default)
|
||||
if (HAL_I2CEx_ConfigAnalogFilter(&hi2c2, I2C_ANALOGFILTER_ENABLE) != HAL_OK){
|
||||
//Error_Handler();
|
||||
}
|
||||
|
||||
//Configure Digital filter (Disabled, which is default)
|
||||
if (HAL_I2CEx_ConfigDigitalFilter(&hi2c2, 0) != HAL_OK){
|
||||
//Error_Handler();
|
||||
}
|
||||
|
||||
// Initialise GPIO pins
|
||||
YEEP144_GPIO_InitAdv(I2C_SDA_PORT, I2C_SDA_PIN | I2C_SCL_PIN, GPIO_MODE_AF_OD, GPIO_NOPULL, GPIO_SPEED_FREQ_LOW, GPIO_AF4_I2C2);
|
||||
}
|
||||
241
YEEP144lib/src/YEEP144_IRQ.c
Normal file
241
YEEP144lib/src/YEEP144_IRQ.c
Normal file
@@ -0,0 +1,241 @@
|
||||
/**
|
||||
* This file contains all of the IRQ handlers that are required for various parts
|
||||
* of the HAL and YEEP libraries to function. Unhandled IRQs will cause the system
|
||||
* to jump to the default handler, trapping it in an infinite loop
|
||||
*/
|
||||
|
||||
#include "YEEP144_HCSR04.h"
|
||||
#include "YEEP144_PushButton.h"
|
||||
#include "YEEP144_PiSPI.h"
|
||||
#include "stm32h563xx.h"
|
||||
#include "stm32h5xx_hal.h"
|
||||
#include "stm32h5xx_hal_dma.h"
|
||||
#include "stm32h5xx_hal_spi.h"
|
||||
#include "stm32h5xx_hal_uart.h"
|
||||
|
||||
extern DMA_HandleTypeDef handle_GPDMA1_Channel0;
|
||||
extern DMA_HandleTypeDef handle_GPDMA1_Channel1;
|
||||
extern UART_HandleTypeDef huart2;
|
||||
extern UART_HandleTypeDef huart3;
|
||||
extern SPI_HandleTypeDef hspi4;
|
||||
|
||||
void YEEP144_BluetoothUART_MatchCallback(void);
|
||||
void YEEP144_DebugUART_MatchCallback(void);
|
||||
|
||||
/**
|
||||
* Handler for the SysTick interrupt
|
||||
* The HAL configures the SysTick to generate an interrupt every 1ms
|
||||
* HAL_IncTick needs to be called in here for the HAL to function properly
|
||||
*/
|
||||
void SysTick_Handler(void){
|
||||
HAL_IncTick();
|
||||
}
|
||||
|
||||
/**
|
||||
* Handler for EXTI line 6. In the YEEP libraries this is used by the yellow pushbutton
|
||||
*/
|
||||
void EXTI6_IRQHandler(void){
|
||||
YEEP144_PushButton_YellowHandler();
|
||||
}
|
||||
|
||||
/**
|
||||
* Handler for EXTI line 7. In the YEEP libraries this is used by the green pushbutton
|
||||
*/
|
||||
void EXTI7_IRQHandler(void){
|
||||
YEEP144_PushButton_GreenHandler();
|
||||
}
|
||||
|
||||
/**
|
||||
* Handler for EXTI line 10. In the YEEP libraries this is used by ultrasonic sensors 1, 2, and 3
|
||||
*/
|
||||
void EXTI10_IRQHandler(void){
|
||||
YEEP144_Ultrasonic_EXTI10Handler();
|
||||
}
|
||||
|
||||
/**
|
||||
* Handler for EXTI line 12. In the YEEP libraries this is used by ultrasonic sensor 4, and pushbutton 3 / red
|
||||
*/
|
||||
void EXTI12_IRQHandler(void){
|
||||
YEEP144_PushButton_RedHandler();
|
||||
YEEP144_Ultrasonic_EXTI12Handler();
|
||||
}
|
||||
|
||||
/**
|
||||
* Handler for EXTI line 14. In the YEEP libraries this is used by the blue pushbutton
|
||||
*/
|
||||
void EXTI13_IRQHandler(void){
|
||||
YEEP144_PushButton_BlueHandler();
|
||||
}
|
||||
|
||||
/**
|
||||
* Handler for GPDMA1 channel 0. In the YEEP libraries this is used by the BT UART reception
|
||||
* We just call the relevant HAL handler to let it deal with it
|
||||
*/
|
||||
void GPDMA1_CH0_IRQHandler(void){
|
||||
HAL_DMA_IRQHandler(&handle_GPDMA1_Channel0);
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Handler for GPDMA1 channel 0. In the YEEP libraries this is used by the BT UART reception
|
||||
* We just call the relevant HAL handler to let it deal with it
|
||||
*/
|
||||
void GPDMA1_CH1_IRQHandler(void){
|
||||
HAL_DMA_IRQHandler(&handle_GPDMA1_Channel1);
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Handler for SPI4 IRQ. We just call the relevant HAL handler to let it deal with it
|
||||
*/
|
||||
void SPI4_IRQHandler(void){
|
||||
HAL_SPI_IRQHandler(&hspi4);
|
||||
}
|
||||
|
||||
void HAL_SPI_TxRxCpltCallback(SPI_HandleTypeDef *hspi){
|
||||
if(hspi->Instance == SPI4){
|
||||
YEEP144_PiSPI_TxRxHandler();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Handler for USART2. In the YEEP libraries this is used by the BT UART.
|
||||
* We do our own checks for the character match interrupt as this is not handled
|
||||
* by the HAL. For any other interrupt we just let the HAL handle it
|
||||
*/
|
||||
void USART2_IRQHandler(void){
|
||||
uint32_t isrflags = READ_REG(huart2.Instance->ISR);
|
||||
uint32_t cr1its = READ_REG(huart2.Instance->CR1);
|
||||
|
||||
// If the character match is enabled and character match flag raised
|
||||
if (((isrflags & USART_ISR_CMF) != 0U) && ((cr1its & USART_CR1_CMIE) != 0U)){
|
||||
__HAL_UART_CLEAR_FLAG(&huart2, UART_CLEAR_CMF); // Clear the character match flag
|
||||
HAL_DMA_Abort(huart2.hdmarx); // End the current DMA
|
||||
// Reset the state of the UART HAL
|
||||
huart2.RxState = HAL_UART_STATE_READY;
|
||||
huart2.ReceptionType = HAL_UART_RECEPTION_STANDARD;
|
||||
|
||||
// Clear the idle line bit so the reception can be rearmed
|
||||
ATOMIC_CLEAR_BIT(huart2.Instance->CR1, USART_CR1_IDLEIE);
|
||||
|
||||
// Call the match callback
|
||||
YEEP144_BluetoothUART_MatchCallback();
|
||||
return;
|
||||
}
|
||||
|
||||
// If this is not the character match IRQ, let the HAL handle it
|
||||
HAL_UART_IRQHandler(&huart2);
|
||||
}
|
||||
|
||||
/**
|
||||
* Handler for USART3. In the YEEP libraries this is used by the BT UART.
|
||||
* We do our own checks for the character match interrupt as this is not handled
|
||||
* by the HAL. For any other interrupt we just let the HAL handle it
|
||||
*/
|
||||
void USART3_IRQHandler(void){
|
||||
uint32_t isrflags = READ_REG(huart3.Instance->ISR);
|
||||
uint32_t cr1its = READ_REG(huart3.Instance->CR1);
|
||||
|
||||
// If the character match is enabled and character match flag raised
|
||||
if (((isrflags & USART_ISR_CMF) != 0U) && ((cr1its & USART_CR1_CMIE) != 0U)){
|
||||
__HAL_UART_CLEAR_FLAG(&huart3, UART_CLEAR_CMF); // Clear the character match flag
|
||||
HAL_DMA_Abort(huart3.hdmarx); // End the current DMA
|
||||
// Reset the state of the UART HAL
|
||||
huart3.RxState = HAL_UART_STATE_READY;
|
||||
huart3.ReceptionType = HAL_UART_RECEPTION_STANDARD;
|
||||
|
||||
// Clear the idle line bit so the reception can be rearmed
|
||||
ATOMIC_CLEAR_BIT(huart3.Instance->CR1, USART_CR1_IDLEIE);
|
||||
|
||||
// Call the match callback
|
||||
YEEP144_DebugUART_MatchCallback();
|
||||
return;
|
||||
}
|
||||
|
||||
// If this is not the character match IRQ, let the HAL handle it
|
||||
HAL_UART_IRQHandler(&huart3);
|
||||
}
|
||||
|
||||
/**
|
||||
* These weakly defined callback functions are here so that the code always compiles
|
||||
* You shouldn't edit these functions, but instead implement your own with the exact same name
|
||||
* in one of your own files, like main.c
|
||||
*/
|
||||
__weak void YEEP144_BluetoothUART_MatchCallback(void){
|
||||
return;
|
||||
}
|
||||
|
||||
__weak void YEEP144_DebugUART_MatchCallback(void){
|
||||
return;
|
||||
}
|
||||
|
||||
/**
|
||||
* These functions copied from STM's interrupt code to provide stubs for handling
|
||||
* the internal Cortex Processor interrupts and exceptions
|
||||
*/
|
||||
|
||||
/**
|
||||
* This function handles Non maskable interrupt.
|
||||
*/
|
||||
void NMI_Handler(void){
|
||||
while (1){
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* This function handles Hard fault interrupt.
|
||||
*/
|
||||
void HardFault_Handler(void){
|
||||
while (1){
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* This function handles Memory management fault.
|
||||
*/
|
||||
void MemManage_Handler(void){
|
||||
while (1){
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* This function handles Prefetch fault, memory access fault.
|
||||
*/
|
||||
void BusFault_Handler(void){
|
||||
while (1){
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* This function handles Undefined instruction or illegal state.
|
||||
*/
|
||||
void UsageFault_Handler(void){
|
||||
while (1){
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* This function handles System service call via SWI instruction.
|
||||
*/
|
||||
void SVC_Handler(void){
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* This function handles Debug monitor.
|
||||
*/
|
||||
void DebugMon_Handler(void){
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* This function handles Pendable request for system service.
|
||||
*/
|
||||
void PendSV_Handler(void){
|
||||
|
||||
}
|
||||
173
YEEP144lib/src/YEEP144_PiSPI.c
Normal file
173
YEEP144lib/src/YEEP144_PiSPI.c
Normal file
@@ -0,0 +1,173 @@
|
||||
#include "YEEP144_Pinout.h"
|
||||
#include "stm32h563xx.h"
|
||||
#include "stm32h5xx.h"
|
||||
#include "stm32h5xx_hal.h"
|
||||
#include "stm32h5xx_hal_cortex.h"
|
||||
#include "stm32h5xx_hal_def.h"
|
||||
#include "stm32h5xx_hal_gpio.h"
|
||||
#include "stm32h5xx_hal_gpio_ex.h"
|
||||
#include "stm32h5xx_hal_rcc.h"
|
||||
#include "stm32h5xx_hal_spi.h"
|
||||
|
||||
#include "YEEP144.h"
|
||||
#include "YEEP144_PiSPI.h"
|
||||
#include "stm32h5xx_hal_spi_ex.h"
|
||||
#include <string.h>
|
||||
|
||||
void YEEP144_PiSPI_RxCallback(void);
|
||||
|
||||
SPI_HandleTypeDef hspi4;
|
||||
|
||||
uint8_t PiSPIRxBuf[PISPI_BUFFER_SIZE];
|
||||
|
||||
uint8_t PiSPITxBuf[PISPI_BUFFER_SIZE];
|
||||
uint8_t PiSPITxBufInternal[PISPI_BUFFER_SIZE];
|
||||
|
||||
/**
|
||||
* Initialises SPI communications for use with an attached Raspberry Pi. In this configuration the Pi will act as the master
|
||||
* therefore the STM32 will be configured as a slave. This means that the master can send / ask for data at any time, and the SPI
|
||||
* peripheral must be ready to avoid under/overruns.
|
||||
*/
|
||||
void YEEP144_PiSPI_Init(void){
|
||||
|
||||
// Setup and enable clock
|
||||
RCC_PeriphCLKInitTypeDef PeriphClkInitStruct = {0};
|
||||
PeriphClkInitStruct.PeriphClockSelection = RCC_PERIPHCLK_SPI4;
|
||||
PeriphClkInitStruct.Spi4ClockSelection = RCC_SPI4CLKSOURCE_HSI; // HSI = 64MHz clock
|
||||
if (HAL_RCCEx_PeriphCLKConfig(&PeriphClkInitStruct) != HAL_OK){
|
||||
//Error_Handler();
|
||||
}
|
||||
|
||||
__HAL_RCC_SPI4_CLK_ENABLE();
|
||||
|
||||
// Setup GPIO
|
||||
YEEP144_GPIO_InitAdv(SPI_MOSI_PORT, SPI_MOSI_PIN | SPI_MISO_PIN | SPI_SCK_PIN , GPIO_MODE_AF_PP, GPIO_NOPULL, GPIO_SPEED_FREQ_LOW, GPIO_AF5_SPI4);
|
||||
YEEP144_GPIO_Init(SPI_CS_PORT, SPI_CS_PIN, GPIO_MODE_OUTPUT);
|
||||
YEEP144_PiSPI_ResetReady();
|
||||
|
||||
// Enable interrupt
|
||||
HAL_NVIC_SetPriority(SPI4_IRQn, 0, 0);
|
||||
HAL_NVIC_EnableIRQ(SPI4_IRQn);
|
||||
|
||||
hspi4.Instance = SPI4;
|
||||
hspi4.Init.Mode = SPI_MODE_SLAVE; // Slave mode
|
||||
hspi4.Init.Direction = SPI_DIRECTION_2LINES; // Full duplex transmission
|
||||
hspi4.Init.DataSize = SPI_DATASIZE_8BIT; // Standard 8-bit word size
|
||||
hspi4.Init.CLKPolarity = SPI_POLARITY_LOW; // Clock polarity and phase set for SPI mode 0
|
||||
hspi4.Init.CLKPhase = SPI_PHASE_1EDGE;
|
||||
hspi4.Init.NSS = SPI_NSS_SOFT; // Chip Select managed by software - we assume we are always selected so the CS line can be repurposed for the ready signal
|
||||
hspi4.Init.FirstBit = SPI_FIRSTBIT_MSB; // MSB first
|
||||
hspi4.Init.TIMode = SPI_TIMODE_DISABLE; // Not using TI mode
|
||||
hspi4.Init.CRCCalculation = SPI_CRCCALCULATION_DISABLE; // Not using CRC
|
||||
hspi4.Init.CRCPolynomial = 0x7;
|
||||
hspi4.Init.NSSPMode = SPI_NSS_PULSE_DISABLE; // Chip select is held not pulsed
|
||||
hspi4.Init.NSSPolarity = SPI_NSS_POLARITY_LOW; // Chip select is active low
|
||||
hspi4.Init.FifoThreshold = SPI_FIFO_THRESHOLD_04DATA; // FIFO threshold is 4-bytes which is the maximum
|
||||
hspi4.Init.MasterSSIdleness = SPI_MASTER_SS_IDLENESS_00CYCLE; // Master configuration is defaults as we aren't master
|
||||
hspi4.Init.MasterInterDataIdleness = SPI_MASTER_INTERDATA_IDLENESS_00CYCLE;
|
||||
hspi4.Init.MasterReceiverAutoSusp = SPI_MASTER_RX_AUTOSUSP_DISABLE;
|
||||
hspi4.Init.MasterKeepIOState = SPI_MASTER_KEEP_IO_STATE_DISABLE;
|
||||
hspi4.Init.IOSwap = SPI_IO_SWAP_DISABLE; // Don't need to swap IO pins
|
||||
hspi4.Init.ReadyMasterManagement = SPI_RDY_MASTER_MANAGEMENT_INTERNALLY; // We aren't using the hardware ready signal
|
||||
hspi4.Init.ReadyPolarity = SPI_RDY_POLARITY_HIGH;
|
||||
if (HAL_SPI_Init(&hspi4) != HAL_OK){
|
||||
//Error_Handler();
|
||||
}
|
||||
|
||||
// Set up our interrupt to wait for start of transfer from the master
|
||||
HAL_SPI_TransmitReceive_IT(&hspi4, PiSPITxBufInternal, PiSPIRxBuf, PISPI_BUFFER_SIZE);
|
||||
|
||||
// Set the ready flag as we are now ready to communicate
|
||||
YEEP144_PiSPI_SetReady();
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Resets the ready signal to ask the master to stop sending / requesting data
|
||||
*/
|
||||
void YEEP144_PiSPI_ResetReady(void){
|
||||
HAL_GPIO_WritePin(SPI_CS_PORT, SPI_CS_PIN, GPIO_PIN_RESET);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the ready signal to tell the master we are ready to receive data
|
||||
*/
|
||||
void YEEP144_PiSPI_SetReady(void){
|
||||
HAL_GPIO_WritePin(SPI_CS_PORT, SPI_CS_PIN, GPIO_PIN_SET);
|
||||
}
|
||||
|
||||
/**
|
||||
* Loads the latest data into the SPI peripheral. Call this function every time you change PiSPITxBuf.
|
||||
*/
|
||||
void YEEP144_PiSPI_LoadTx(void){
|
||||
/**
|
||||
* As we cannot know when the master will initiate a transfer, we must always be ready to receive and send data
|
||||
* to avoid overrun when receiving, or underrun when sending. This means that the SPI peripheral must be active
|
||||
* with a transfer pending before the master begins a transfer by begining the clock and sending data, and
|
||||
* this pending transfer must be kept active as much of the time as possible. This means that we always start a
|
||||
* transfer with HAL_SPI_TransmitReceive_IT at the end of SPI initialisation, and immediately after the previous
|
||||
* transfer has finished in the relevant ISR.
|
||||
*
|
||||
* When a transfer is started with HAL_SPI_TransmitReceive_IT, the first x bytes from the transmit buffer is
|
||||
* pre-loaded into the SPI peripheral's internal TX FIFO, with x depending on the FIFO Threshold configuration,
|
||||
* to avoid any issues with data underrun. This means that if data in the transmit buffer is changed after a
|
||||
* transfer is started, the first x bytes will remain from the state of the buffer when the transfer was started,
|
||||
* leading to messages with a mix of old and new data.
|
||||
*
|
||||
* In order to avoid this, the transmit data is double buffered, so that the user code cannot change the data while
|
||||
* a transfer is in progress, and this function aborts the transfer, which flushes the FIFO, and copies the front
|
||||
* buffer into the back buffer, before restarting the transfer, which prevents the buffer changeover from also
|
||||
* occurring mid transaction.
|
||||
*
|
||||
* This means there is a small window each time this function is called, and shortly after the end of a transfer
|
||||
* where the SPI will not be active as the data is changed over. The ready signal should be reset during this period
|
||||
* which will lead to a small delay on the master side
|
||||
*/
|
||||
|
||||
// Wait for current transfer to end
|
||||
while(((SPI4->SR & SPI_SR_CTSIZE_Msk) >> SPI_SR_CTSIZE_Pos) != PISPI_BUFFER_SIZE){}
|
||||
|
||||
// Clear the ready signal to tell the master we are no longer ready
|
||||
YEEP144_PiSPI_ResetReady();
|
||||
|
||||
// Stop the current transfer which flushes the old data from the FIFO
|
||||
HAL_SPI_Abort_IT(&hspi4);
|
||||
|
||||
// Copy the user facing buffer into the internal buffer
|
||||
memcpy(PiSPITxBufInternal, PiSPITxBuf, PISPI_BUFFER_SIZE);
|
||||
|
||||
// Restart the transfer now the buffer has been updated
|
||||
HAL_SPI_TransmitReceive_IT(&hspi4, PiSPITxBufInternal, PiSPIRxBuf, PISPI_BUFFER_SIZE);
|
||||
|
||||
// Set the ready signal to tell the master we are now ready to continue communication
|
||||
YEEP144_PiSPI_SetReady();
|
||||
}
|
||||
|
||||
/**
|
||||
* This function should be called by HAL_SPI_TxRxCpltCallback in YEEP144_IRQ to handle the end of a transfer
|
||||
* It loads the latest data into the transmit buffer, reinitialises the SPI peripheral ready for the next transfer,
|
||||
* and calls the user callback
|
||||
*/
|
||||
void YEEP144_PiSPI_TxRxHandler(void){
|
||||
|
||||
// Clear the ready signal as we are not ready to receive until the message has been handled
|
||||
YEEP144_PiSPI_ResetReady();
|
||||
|
||||
// Copy the user facing buffer into the internal buffer
|
||||
memcpy(PiSPITxBufInternal, PiSPITxBuf, PISPI_BUFFER_SIZE);
|
||||
|
||||
// Restart the transfer now the buffer has been updated
|
||||
HAL_SPI_TransmitReceive_IT(&hspi4, PiSPITxBufInternal, PiSPIRxBuf, PISPI_BUFFER_SIZE);
|
||||
|
||||
// Call the user callback function - the user will need to restore the ready signal when done
|
||||
// for more messages to be received
|
||||
YEEP144_PiSPI_RxCallback();
|
||||
}
|
||||
|
||||
/**
|
||||
* This is a weakly defined function for the RX Callback function.
|
||||
* It should be overriden by an identically named function in user code
|
||||
*/
|
||||
__weak void YEEP144_PiSPI_RxCallback(void){
|
||||
return;
|
||||
}
|
||||
111
YEEP144lib/src/YEEP144_PushButton.c
Normal file
111
YEEP144lib/src/YEEP144_PushButton.c
Normal file
@@ -0,0 +1,111 @@
|
||||
#include "YEEP144_PushButton.h"
|
||||
#include "YEEP144.h"
|
||||
#include "YEEP144_Pinout.h"
|
||||
#include "stm32h5xx_hal_cortex.h"
|
||||
#include "stm32h5xx_hal_def.h"
|
||||
#include "stm32h5xx_hal_gpio.h"
|
||||
|
||||
void YEEP144_PushButton_BlueCallback(void);
|
||||
void YEEP144_PushButton_GreenCallback(void);
|
||||
void YEEP144_PushButton_YellowCallback(void);
|
||||
void YEEP144_PushButton_RedCallback(void);
|
||||
|
||||
/**
|
||||
* Initialise the blue button. This consumes the button's GPIO and EXTI13
|
||||
*/
|
||||
void YEEP144_PushButton_BlueInit(void){
|
||||
YEEP144_GPIO_Init(BUTTON_BLUE_PORT, BUTTON_BLUE_PIN, GPIO_MODE_IT_FALLING);
|
||||
HAL_NVIC_SetPriority(BUTTON_BLUE_EXTI, 1, 0);
|
||||
HAL_NVIC_EnableIRQ(BUTTON_BLUE_EXTI);
|
||||
}
|
||||
|
||||
/**
|
||||
* Initialise the green button. This consumes the button's GPIO and EXTI7
|
||||
*/
|
||||
void YEEP144_PushButton_GreenInit(void){
|
||||
YEEP144_GPIO_Init(BUTTON_GREEN_PORT, BUTTON_GREEN_PIN, GPIO_MODE_IT_FALLING);
|
||||
HAL_NVIC_SetPriority(BUTTON_GREEN_EXTI, 1, 0);
|
||||
HAL_NVIC_EnableIRQ(BUTTON_GREEN_EXTI);
|
||||
}
|
||||
|
||||
/**
|
||||
* Initialise the yellow button. This consumes the button's GPIO and EXTI6
|
||||
*/
|
||||
void YEEP144_PushButton_YellowInit(void){
|
||||
YEEP144_GPIO_Init(BUTTON_YELLOW_PORT, BUTTON_YELLOW_PIN, GPIO_MODE_IT_FALLING);
|
||||
HAL_NVIC_SetPriority(BUTTON_YELLOW_EXTI, 1, 0);
|
||||
HAL_NVIC_EnableIRQ(BUTTON_YELLOW_EXTI);
|
||||
}
|
||||
|
||||
/**
|
||||
* Initialise the blue button. This consumes the button's GPIO and EXTI12 (shared with ultrasonic 4)
|
||||
*/
|
||||
void YEEP144_PushButton_RedInit(void){
|
||||
YEEP144_GPIO_Init(BUTTON_RED_PORT, BUTTON_RED_PIN, GPIO_MODE_IT_FALLING);
|
||||
HAL_NVIC_SetPriority(BUTTON_RED_EXTI, 1, 0);
|
||||
HAL_NVIC_EnableIRQ(BUTTON_RED_EXTI);
|
||||
}
|
||||
|
||||
/**
|
||||
* Handles the interrupt for the blue button. This should be called from the main EXTI13 handler, and in turn calls YEEP144_PushButton_BlueCallback
|
||||
*/
|
||||
void YEEP144_PushButton_BlueHandler(void){
|
||||
// Check this interrupt has been called due to the pushbutton
|
||||
if(__HAL_GPIO_EXTI_GET_IT(BUTTON_BLUE_PIN) && (HAL_GPIO_ReadPin(BUTTON_BLUE_PORT, BUTTON_BLUE_PIN) == GPIO_PIN_RESET)){
|
||||
__HAL_GPIO_EXTI_CLEAR_IT(BUTTON_BLUE_PIN); // Clear the interrupt
|
||||
YEEP144_PushButton_BlueCallback(); // Call the callback function
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Handles the interrupt for the green button. This should be called from the main EXTI7 handler, and in turn calls YEEP144_PushButton_GreenCallback
|
||||
*/
|
||||
void YEEP144_PushButton_GreenHandler(void){
|
||||
// Check this interrupt has been called due to the pushbutton
|
||||
if(__HAL_GPIO_EXTI_GET_IT(BUTTON_GREEN_PIN) && (HAL_GPIO_ReadPin(BUTTON_GREEN_PORT, BUTTON_GREEN_PIN) == GPIO_PIN_RESET)){
|
||||
__HAL_GPIO_EXTI_CLEAR_IT(BUTTON_GREEN_PIN); // Clear the interrupt
|
||||
YEEP144_PushButton_GreenCallback(); // Call the callback function
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Handles the interrupt for the yellow button. This should be called from the main EXTI6 handler, and in turn calls YEEP144_PushButton_YellowCallback
|
||||
*/
|
||||
void YEEP144_PushButton_YellowHandler(void){
|
||||
// Check this interrupt has been called due to the pushbutton
|
||||
if(__HAL_GPIO_EXTI_GET_IT(BUTTON_YELLOW_PIN) && (HAL_GPIO_ReadPin(BUTTON_YELLOW_PORT, BUTTON_YELLOW_PIN) == GPIO_PIN_RESET)){
|
||||
__HAL_GPIO_EXTI_CLEAR_IT(BUTTON_YELLOW_PIN); // Clear the interrupt
|
||||
YEEP144_PushButton_YellowCallback(); // Call the callback function
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Handles the interrupt for the red button. This should be called from the main EXTI12 handler, and in turn calls YEEP144_PushButton_RedCallback
|
||||
*/
|
||||
void YEEP144_PushButton_RedHandler(void){
|
||||
// Check this interrupt has been called due to the pushbutton
|
||||
if(__HAL_GPIO_EXTI_GET_IT(BUTTON_RED_PIN) && (HAL_GPIO_ReadPin(BUTTON_RED_PORT, BUTTON_RED_PIN) == GPIO_PIN_RESET)){
|
||||
__HAL_GPIO_EXTI_CLEAR_IT(BUTTON_RED_PIN); // Clear the interrupt
|
||||
YEEP144_PushButton_RedCallback(); // Call the callback function
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* These versions of the callback functions are weakly defined so they can be overwritten by the user's function elsewhere.
|
||||
* They need to exist so that the code will still compile even if the user hasn't defined their own.
|
||||
*/
|
||||
__weak void YEEP144_PushButton_BlueCallback(void){
|
||||
|
||||
}
|
||||
|
||||
__weak void YEEP144_PushButton_GreenCallback(void){
|
||||
|
||||
}
|
||||
|
||||
__weak void YEEP144_PushButton_YellowCallback(void){
|
||||
|
||||
}
|
||||
|
||||
__weak void YEEP144_PushButton_RedCallback(void){
|
||||
|
||||
}
|
||||
148
YEEP144lib/src/YEEP144_RGB.c
Normal file
148
YEEP144lib/src/YEEP144_RGB.c
Normal file
@@ -0,0 +1,148 @@
|
||||
#include "YEEP144.h"
|
||||
#include "YEEP144_RGB.h"
|
||||
#include "YEEP144_I2C.h"
|
||||
#include "stm32h5xx_hal_i2c.h"
|
||||
|
||||
#define RGB_ADDR 0x50
|
||||
#define RGB_CHIP_EN_REG 0x000
|
||||
#define RGB_DEV_CONFIG_0_REG 0x001
|
||||
#define RGB_DEV_CONFIG_1_REG 0x002
|
||||
#define RGB_DEV_CONFIG_2_REG 0x003
|
||||
#define RGB_DEV_CONFIG_3_REG 0x004
|
||||
#define RGB_DEV_CONFIG_4_REG 0x005
|
||||
#define RGB_DEV_CONFIG_5_REG 0x006
|
||||
#define RGB_DEV_CONFIG_6_REG 0x007
|
||||
#define RGB_DEV_CONFIG_7_REG 0x008
|
||||
#define RGB_DEV_CONFIG_8_REG 0x009
|
||||
#define RGB_DEV_CONFIG_9_REG 0x00A
|
||||
#define RGB_DEV_CONFIG_10_REG 0x00B
|
||||
#define RGB_DEV_CONFIG_11_REG 0x00C
|
||||
#define RGB_DEV_CONFIG_12_REG 0x00D
|
||||
#define RGB_CMD_UPDATE_REG 0x010
|
||||
#define RGB_CMD_START_REG 0x011
|
||||
#define RGB_CMD_STOP_REG 0x012
|
||||
#define RGB_CMD_PAUSE_REG 0x013
|
||||
#define RGB_CMD_CONTINUE_REG 0x014
|
||||
#define RGB_LED_EN_1_REG 0x020
|
||||
#define RGB_LED_EN_2_REG 0x021
|
||||
#define RGB_FAULT_CLEAR_REG 0x022
|
||||
#define RGB_RESET_REG 0x023
|
||||
#define RGB_MANUAL_DC_BASE_REG 0x030
|
||||
|
||||
#define RGB_MANUAL_DC_4_REG 0x034
|
||||
#define RGB_MANUAL_DC_5_REG 0x035
|
||||
#define RGB_MANUAL_DC_6_REG 0x036
|
||||
#define RGB_MANUAL_DC_7_REG 0x037
|
||||
#define RGB_MANUAL_DC_8_REG 0x038
|
||||
#define RGB_MANUAL_DC_9_REG 0x039
|
||||
#define RGB_MANUAL_DC_10_REG 0x03A
|
||||
#define RGB_MANUAL_DC_11_REG 0x03B
|
||||
#define RGB_MANUAL_DC_12_REG 0x03C
|
||||
#define RGB_MANUAL_DC_13_REG 0x03D
|
||||
#define RGB_MANUAL_DC_14_REG 0x03E
|
||||
#define RGB_MANUAL_DC_15_REG 0x03F
|
||||
#define RGB_MANUAL_PWM_BASE_REG 0x040
|
||||
|
||||
#define RGB_MANUAL_PWM_4_REG 0x044
|
||||
#define RGB_MANUAL_PWM_5_REG 0x045
|
||||
#define RGB_MANUAL_PWM_6_REG 0x046
|
||||
#define RGB_MANUAL_PWM_7_REG 0x047
|
||||
#define RGB_MANUAL_PWM_8_REG 0x048
|
||||
#define RGB_MANUAL_PWM_9_REG 0x049
|
||||
#define RGB_MANUAL_PWM_10_REG 0x04A
|
||||
#define RGB_MANUAL_PWM_11_REG 0x04B
|
||||
#define RGB_MANUAL_PWM_12_REG 0x04C
|
||||
#define RGB_MANUAL_PWM_13_REG 0x04D
|
||||
#define RGB_MANUAL_PWM_14_REG 0x04E
|
||||
#define RGB_MANUAL_PWM_15_REG 0x04F
|
||||
|
||||
#define I2C_Timeout 1000
|
||||
|
||||
/**
|
||||
* Initialise the RGB led driver. This requires that the I2C has already been initialised
|
||||
*/
|
||||
void YEEP144_RGB_Init(void){
|
||||
|
||||
// Reset the LP5812 - 0x66 is magic number according to datasheet
|
||||
YEEP144_RGB_WriteReg(RGB_RESET_REG, 0x66);
|
||||
|
||||
// Enable the chip
|
||||
YEEP144_RGB_WriteReg(RGB_CHIP_EN_REG, 1);
|
||||
|
||||
// Set the scan mode - 24kHz PWM, scan drive mode with 4 scans, no direct drive outputs
|
||||
YEEP144_RGB_WriteReg(RGB_DEV_CONFIG_1_REG, 0x40);
|
||||
|
||||
// Set protection options - shutdown on open LED detected, shutdown on short LED detected, short threshold 0.65 * VCC
|
||||
YEEP144_RGB_WriteReg(RGB_DEV_CONFIG_12_REG, 0x0F);
|
||||
|
||||
// Apply updated configuration - 0x55 is magic number as per datasheet
|
||||
YEEP144_RGB_WriteReg(RGB_CMD_UPDATE_REG, 0x55);
|
||||
|
||||
// Set red current limits to 50% of max 25.2mA
|
||||
YEEP144_RGB_WriteReg(RGB_MANUAL_DC_BASE_REG + RGB1_RED , 0xFF / 2);
|
||||
YEEP144_RGB_WriteReg(RGB_MANUAL_DC_BASE_REG + RGB2_RED , 0xFF / 2);
|
||||
YEEP144_RGB_WriteReg(RGB_MANUAL_DC_BASE_REG + RGB3_RED , 0xFF / 2);
|
||||
YEEP144_RGB_WriteReg(RGB_MANUAL_DC_BASE_REG + RGB4_RED , 0xFF / 2);
|
||||
|
||||
// Set green and blue current limits to 20% of max
|
||||
|
||||
YEEP144_RGB_WriteReg(RGB_MANUAL_DC_BASE_REG + RGB1_GREEN , 0xFF / 5);
|
||||
YEEP144_RGB_WriteReg(RGB_MANUAL_DC_BASE_REG + RGB1_BLUE , 0xFF / 5);
|
||||
YEEP144_RGB_WriteReg(RGB_MANUAL_DC_BASE_REG + RGB2_GREEN , 0xFF / 5);
|
||||
YEEP144_RGB_WriteReg(RGB_MANUAL_DC_BASE_REG + RGB2_BLUE , 0xFF / 5);
|
||||
YEEP144_RGB_WriteReg(RGB_MANUAL_DC_BASE_REG + RGB3_GREEN , 0xFF / 5);
|
||||
YEEP144_RGB_WriteReg(RGB_MANUAL_DC_BASE_REG + RGB3_BLUE , 0xFF / 5);
|
||||
YEEP144_RGB_WriteReg(RGB_MANUAL_DC_BASE_REG + RGB4_GREEN , 0xFF / 5);
|
||||
YEEP144_RGB_WriteReg(RGB_MANUAL_DC_BASE_REG + RGB4_BLUE , 0xFF / 5);
|
||||
|
||||
// Enable all the LEDS
|
||||
YEEP144_RGB_WriteReg(RGB_LED_EN_1_REG, 0xF0);
|
||||
YEEP144_RGB_WriteReg(RGB_LED_EN_2_REG, 0xFF);
|
||||
|
||||
// Set default colours
|
||||
YEEP144_RGB_SetRGB(1, RGB_GREEN);
|
||||
YEEP144_RGB_SetRGB(2, RGB_GOLD);
|
||||
YEEP144_RGB_SetRGB(3, RGB_RED);
|
||||
YEEP144_RGB_SetRGB(4, RGB_INDIGO);
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Individually sets the brightness of an LED. Use the defines in the header file
|
||||
* to specify which LED e.g. RGB1_GREEN
|
||||
*/
|
||||
void YEEP144_RGB_SetLED(uint8_t led, uint8_t value){
|
||||
YEEP144_RGB_WriteReg(RGB_MANUAL_PWM_BASE_REG + led, value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the brightness for all 3 elements of an RGB led at one.
|
||||
* Instead of specifiying the RGB values, you can also substitute in one of the defines e.g. RGB_GOLD
|
||||
*/
|
||||
void YEEP144_RGB_SetRGB(uint8_t led, uint8_t red, uint8_t green, uint8_t blue){
|
||||
uint8_t offset = ((led - 1) * 3);
|
||||
YEEP144_RGB_WriteReg(RGB_MANUAL_PWM_BASE_REG + RGB1_RED + offset, red);
|
||||
YEEP144_RGB_WriteReg(RGB_MANUAL_PWM_BASE_REG + RGB1_GREEN + offset, green);
|
||||
YEEP144_RGB_WriteReg(RGB_MANUAL_PWM_BASE_REG + RGB1_BLUE + offset, blue);
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper function that writes a byte to the RGB controller at the specified register address
|
||||
*/
|
||||
void YEEP144_RGB_WriteReg(uint16_t reg, uint8_t data){
|
||||
// As there are so many registers in this chip, it uses a couple of the I2C address bits as part of the register address
|
||||
// This means we need to do some bit level manipulation to build our transmission address and data
|
||||
|
||||
uint8_t I2CAddress = RGB_ADDR + (reg >> 8); // set the bottom two bits of the address to the top two bits of the register
|
||||
|
||||
// Cast the register to a uint8_t so we just get the lowest 8 bits
|
||||
uint8_t reg8Bit = (uint8_t) reg;
|
||||
|
||||
// Pack out register address and data into an array for transmission
|
||||
uint8_t RGBCommand[2];
|
||||
RGBCommand[0] = reg8Bit;
|
||||
RGBCommand[1] = data;
|
||||
|
||||
// Send out the data. The constructed I2CAddress still needs to be shifted by 1 due to 7/8-bit addressing differences
|
||||
HAL_I2C_Master_Transmit(&hi2c2, I2CAddress << 1, RGBCommand, 2, I2C_Timeout);
|
||||
}
|
||||
779
YEEP144lib/src/YEEP144_SSD1306.c
Normal file
779
YEEP144lib/src/YEEP144_SSD1306.c
Normal file
@@ -0,0 +1,779 @@
|
||||
// This code is largely inspired by the Adafruit SSD1306 and Adafruit GFX Arduino libraries
|
||||
// re-written to simplify it down to plain C rather than object based C++, optimise for STM32
|
||||
// rather than Arduino, and to focus on specifically the monochrome SSD1306 displays rather than
|
||||
// a general purpose graphics library
|
||||
|
||||
#include "stm32h5xx_hal.h"
|
||||
#include "stm32h5xx_hal_i2c.h"
|
||||
#include "YEEP144_I2C.h"
|
||||
#include "YEEP144_SSD1306.h"
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <stdarg.h>
|
||||
#include <string.h>
|
||||
#include <stdbool.h>
|
||||
#include <strings.h>
|
||||
|
||||
#define WIDTH 128
|
||||
#define HEIGHT 32
|
||||
#define SSD1306_ADDR 0x3C << 1
|
||||
#define I2C_TIMEOUT 1000
|
||||
|
||||
#define FONTWIDTH 5
|
||||
#define FONTHEIGHT 7
|
||||
#define MAXCHAR ((WIDTH / (FONTWIDTH + 1)) * (HEIGHT / (FONTHEIGHT + 1)))
|
||||
|
||||
#define SSD1306_MEMORYMODE 0x20
|
||||
#define SSD1306_COLUMNADDR 0x21
|
||||
#define SSD1306_PAGEADDR 0x22
|
||||
#define SSD1306_SETCONTRAST 0x81
|
||||
#define SSD1306_CHARGEPUMP 0x8D
|
||||
#define SSD1306_SEGREMAP 0xA0
|
||||
#define SSD1306_DISPLAYALLON_RESUME 0xA4
|
||||
#define SSD1306_DISPLAYALLON 0xA5
|
||||
#define SSD1306_NORMALDISPLAY 0xA6
|
||||
#define SSD1306_INVERTDISPLAY 0xA7
|
||||
#define SSD1306_SETMULTIPLEX 0xA8
|
||||
#define SSD1306_DISPLAYOFF 0xAE
|
||||
#define SSD1306_DISPLAYON 0xAF
|
||||
#define SSD1306_COMSCANINC 0xC0
|
||||
#define SSD1306_COMSCANDEC 0xC8
|
||||
#define SSD1306_SETDISPLAYOFFSET 0xD3
|
||||
#define SSD1306_SETDISPLAYCLOCKDIV 0xD5
|
||||
#define SSD1306_SETPRECHARGE 0xD9
|
||||
#define SSD1306_SETCOMPINS 0xDA
|
||||
#define SSD1306_SETVCOMDETECT 0xDB
|
||||
|
||||
#define SSD1306_SETLOWCOLUMN 0x00
|
||||
#define SSD1306_SETHIGHCOLUMN 0x10
|
||||
#define SSD1306_SETSTARTLINE 0x40
|
||||
|
||||
#define SSD1306_EXTERNALVCC 0x01
|
||||
#define SSD1306_SWITCHCAPVCC 0x02
|
||||
|
||||
#define SSD1306_RIGHT_HORIZONTAL_SCROLL 0x26
|
||||
#define SSD1306_LEFT_HORIZONTAL_SCROLL 0x27
|
||||
#define SSD1306_VERTICAL_AND_RIGHT_HORIZONTAL_SCROLL 0x29
|
||||
#define SSD1306_VERTICAL_AND_LEFT_HORIZONTAL_SCROLL 0x2A
|
||||
#define SSD1306_DEACTIVATE_SCROLL 0x2E
|
||||
#define SSD1306_ACTIVATE_SCROLL 0x2F
|
||||
#define SSD1306_SET_VERTICAL_SCROLL_AREA 0xA3
|
||||
|
||||
uint8_t *displayTXBuffer;
|
||||
uint8_t *displayBuffer;
|
||||
|
||||
uint8_t cursorX = 0;
|
||||
uint8_t cursorY = 0;
|
||||
uint8_t textSize = 1;
|
||||
uint8_t textColour = SSD1306_WHITE;
|
||||
uint8_t textBGColour = SSD1306_BLACK;
|
||||
uint8_t textWrap = 1;
|
||||
|
||||
void YEEP144_SSD1306_DrawFastHLine(uint8_t x, uint8_t y, int8_t w, uint8_t colour);
|
||||
void YEEP144_SSD1306_DrawFastVLine(uint8_t x, uint8_t y, int8_t h, uint8_t colour);
|
||||
void YEEP144_SSD1306_DrawLineInternal(uint8_t x0, uint8_t y0, uint8_t x1, uint8_t y1, uint8_t colour);
|
||||
|
||||
const unsigned char UOYLogo [] = {
|
||||
0x00, 0x00, 0x00, 0x30, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x60, 0x00, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0xe0, 0x00, 0x03, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x01, 0xc8, 0x18, 0x0d, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x01, 0x3c, 0x04, 0x00, 0x40, 0x69, 0x24, 0xd7, 0xb8, 0xcd, 0xe9, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x01, 0xbc, 0x00, 0x10, 0x00, 0x49, 0xa4, 0x02, 0x25, 0x08, 0x86, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x01, 0xdc, 0x01, 0x16, 0x40, 0x49, 0x64, 0x42, 0x28, 0xc8, 0x84, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0xff, 0x8f, 0xe8, 0x00, 0x49, 0x24, 0x62, 0xad, 0x48, 0x84, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x3e, 0x77, 0xf2, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x7e, 0x07, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x01, 0xf6, 0x0d, 0xcc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0xe0, 0x1c, 0xf8, 0x00, 0x00, 0x0c, 0x38, 0x03, 0x40, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x02, 0xc0, 0x86, 0xff, 0x80, 0x00, 0x14, 0x18, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x01, 0xef, 0x9f, 0xfb, 0x00, 0x00, 0x20, 0x18, 0x10, 0x00, 0x30, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x08, 0xa0, 0xfe, 0x00, 0x1e, 0x20, 0x10, 0x60, 0x00, 0x20, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x18, 0x58, 0xb6, 0x00, 0x27, 0xf8, 0x30, 0xe0, 0x00, 0x20, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0xb8, 0x3c, 0x33, 0x00, 0x4c, 0x40, 0x31, 0xc0, 0x00, 0x60, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x98, 0x7e, 0x33, 0x00, 0x84, 0xc0, 0x63, 0x86, 0x30, 0x40, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0xf8, 0xc2, 0x10, 0x00, 0x88, 0x80, 0x6b, 0x12, 0xb7, 0xc3, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x69, 0xdb, 0x1a, 0x00, 0x90, 0x80, 0xd6, 0x22, 0x38, 0x86, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x79, 0xff, 0x90, 0x00, 0xe1, 0x00, 0xec, 0x42, 0x31, 0x98, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x7b, 0xff, 0xd0, 0x00, 0x02, 0x01, 0x98, 0xc4, 0x61, 0xe0, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x6c, 0x3c, 0x2c, 0x00, 0x04, 0x01, 0x30, 0x8c, 0x43, 0x30, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x04, 0xa4, 0xa0, 0x00, 0x00, 0x00, 0x70, 0x98, 0x82, 0x18, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x07, 0xc3, 0xe0, 0x00, 0x00, 0x00, 0x60, 0xe0, 0x84, 0x0f, 0x80, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x07, 0x99, 0xc0, 0x00, 0x00, 0x00, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x03, 0x11, 0xc0, 0x00, 0x00, 0x01, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x01, 0x18, 0x80, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x1d, 0x00, 0x00, 0x80, 0x0e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x9a, 0x00, 0x00, 0x40, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x24, 0x00, 0x00, 0x30, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x07, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
|
||||
};
|
||||
|
||||
static const unsigned char font[] = {
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x3E, 0x5B, 0x4F, 0x5B, 0x3E, 0x3E, 0x6B,
|
||||
0x4F, 0x6B, 0x3E, 0x1C, 0x3E, 0x7C, 0x3E, 0x1C, 0x18, 0x3C, 0x7E, 0x3C,
|
||||
0x18, 0x1C, 0x57, 0x7D, 0x57, 0x1C, 0x1C, 0x5E, 0x7F, 0x5E, 0x1C, 0x00,
|
||||
0x18, 0x3C, 0x18, 0x00, 0xFF, 0xE7, 0xC3, 0xE7, 0xFF, 0x00, 0x18, 0x24,
|
||||
0x18, 0x00, 0xFF, 0xE7, 0xDB, 0xE7, 0xFF, 0x30, 0x48, 0x3A, 0x06, 0x0E,
|
||||
0x26, 0x29, 0x79, 0x29, 0x26, 0x40, 0x7F, 0x05, 0x05, 0x07, 0x40, 0x7F,
|
||||
0x05, 0x25, 0x3F, 0x5A, 0x3C, 0xE7, 0x3C, 0x5A, 0x7F, 0x3E, 0x1C, 0x1C,
|
||||
0x08, 0x08, 0x1C, 0x1C, 0x3E, 0x7F, 0x14, 0x22, 0x7F, 0x22, 0x14, 0x5F,
|
||||
0x5F, 0x00, 0x5F, 0x5F, 0x06, 0x09, 0x7F, 0x01, 0x7F, 0x00, 0x66, 0x89,
|
||||
0x95, 0x6A, 0x60, 0x60, 0x60, 0x60, 0x60, 0x94, 0xA2, 0xFF, 0xA2, 0x94,
|
||||
0x08, 0x04, 0x7E, 0x04, 0x08, 0x10, 0x20, 0x7E, 0x20, 0x10, 0x08, 0x08,
|
||||
0x2A, 0x1C, 0x08, 0x08, 0x1C, 0x2A, 0x08, 0x08, 0x1E, 0x10, 0x10, 0x10,
|
||||
0x10, 0x0C, 0x1E, 0x0C, 0x1E, 0x0C, 0x30, 0x38, 0x3E, 0x38, 0x30, 0x06,
|
||||
0x0E, 0x3E, 0x0E, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x5F,
|
||||
0x00, 0x00, 0x00, 0x07, 0x00, 0x07, 0x00, 0x14, 0x7F, 0x14, 0x7F, 0x14,
|
||||
0x24, 0x2A, 0x7F, 0x2A, 0x12, 0x23, 0x13, 0x08, 0x64, 0x62, 0x36, 0x49,
|
||||
0x56, 0x20, 0x50, 0x00, 0x08, 0x07, 0x03, 0x00, 0x00, 0x1C, 0x22, 0x41,
|
||||
0x00, 0x00, 0x41, 0x22, 0x1C, 0x00, 0x2A, 0x1C, 0x7F, 0x1C, 0x2A, 0x08,
|
||||
0x08, 0x3E, 0x08, 0x08, 0x00, 0x80, 0x70, 0x30, 0x00, 0x08, 0x08, 0x08,
|
||||
0x08, 0x08, 0x00, 0x00, 0x60, 0x60, 0x00, 0x20, 0x10, 0x08, 0x04, 0x02,
|
||||
0x3E, 0x51, 0x49, 0x45, 0x3E, 0x00, 0x42, 0x7F, 0x40, 0x00, 0x72, 0x49,
|
||||
0x49, 0x49, 0x46, 0x21, 0x41, 0x49, 0x4D, 0x33, 0x18, 0x14, 0x12, 0x7F,
|
||||
0x10, 0x27, 0x45, 0x45, 0x45, 0x39, 0x3C, 0x4A, 0x49, 0x49, 0x31, 0x41,
|
||||
0x21, 0x11, 0x09, 0x07, 0x36, 0x49, 0x49, 0x49, 0x36, 0x46, 0x49, 0x49,
|
||||
0x29, 0x1E, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0x40, 0x34, 0x00, 0x00,
|
||||
0x00, 0x08, 0x14, 0x22, 0x41, 0x14, 0x14, 0x14, 0x14, 0x14, 0x00, 0x41,
|
||||
0x22, 0x14, 0x08, 0x02, 0x01, 0x59, 0x09, 0x06, 0x3E, 0x41, 0x5D, 0x59,
|
||||
0x4E, 0x7C, 0x12, 0x11, 0x12, 0x7C, 0x7F, 0x49, 0x49, 0x49, 0x36, 0x3E,
|
||||
0x41, 0x41, 0x41, 0x22, 0x7F, 0x41, 0x41, 0x41, 0x3E, 0x7F, 0x49, 0x49,
|
||||
0x49, 0x41, 0x7F, 0x09, 0x09, 0x09, 0x01, 0x3E, 0x41, 0x41, 0x51, 0x73,
|
||||
0x7F, 0x08, 0x08, 0x08, 0x7F, 0x00, 0x41, 0x7F, 0x41, 0x00, 0x20, 0x40,
|
||||
0x41, 0x3F, 0x01, 0x7F, 0x08, 0x14, 0x22, 0x41, 0x7F, 0x40, 0x40, 0x40,
|
||||
0x40, 0x7F, 0x02, 0x1C, 0x02, 0x7F, 0x7F, 0x04, 0x08, 0x10, 0x7F, 0x3E,
|
||||
0x41, 0x41, 0x41, 0x3E, 0x7F, 0x09, 0x09, 0x09, 0x06, 0x3E, 0x41, 0x51,
|
||||
0x21, 0x5E, 0x7F, 0x09, 0x19, 0x29, 0x46, 0x26, 0x49, 0x49, 0x49, 0x32,
|
||||
0x03, 0x01, 0x7F, 0x01, 0x03, 0x3F, 0x40, 0x40, 0x40, 0x3F, 0x1F, 0x20,
|
||||
0x40, 0x20, 0x1F, 0x3F, 0x40, 0x38, 0x40, 0x3F, 0x63, 0x14, 0x08, 0x14,
|
||||
0x63, 0x03, 0x04, 0x78, 0x04, 0x03, 0x61, 0x59, 0x49, 0x4D, 0x43, 0x00,
|
||||
0x7F, 0x41, 0x41, 0x41, 0x02, 0x04, 0x08, 0x10, 0x20, 0x00, 0x41, 0x41,
|
||||
0x41, 0x7F, 0x04, 0x02, 0x01, 0x02, 0x04, 0x40, 0x40, 0x40, 0x40, 0x40,
|
||||
0x00, 0x03, 0x07, 0x08, 0x00, 0x20, 0x54, 0x54, 0x78, 0x40, 0x7F, 0x28,
|
||||
0x44, 0x44, 0x38, 0x38, 0x44, 0x44, 0x44, 0x28, 0x38, 0x44, 0x44, 0x28,
|
||||
0x7F, 0x38, 0x54, 0x54, 0x54, 0x18, 0x00, 0x08, 0x7E, 0x09, 0x02, 0x18,
|
||||
0xA4, 0xA4, 0x9C, 0x78, 0x7F, 0x08, 0x04, 0x04, 0x78, 0x00, 0x44, 0x7D,
|
||||
0x40, 0x00, 0x20, 0x40, 0x40, 0x3D, 0x00, 0x7F, 0x10, 0x28, 0x44, 0x00,
|
||||
0x00, 0x41, 0x7F, 0x40, 0x00, 0x7C, 0x04, 0x78, 0x04, 0x78, 0x7C, 0x08,
|
||||
0x04, 0x04, 0x78, 0x38, 0x44, 0x44, 0x44, 0x38, 0xFC, 0x18, 0x24, 0x24,
|
||||
0x18, 0x18, 0x24, 0x24, 0x18, 0xFC, 0x7C, 0x08, 0x04, 0x04, 0x08, 0x48,
|
||||
0x54, 0x54, 0x54, 0x24, 0x04, 0x04, 0x3F, 0x44, 0x24, 0x3C, 0x40, 0x40,
|
||||
0x20, 0x7C, 0x1C, 0x20, 0x40, 0x20, 0x1C, 0x3C, 0x40, 0x30, 0x40, 0x3C,
|
||||
0x44, 0x28, 0x10, 0x28, 0x44, 0x4C, 0x90, 0x90, 0x90, 0x7C, 0x44, 0x64,
|
||||
0x54, 0x4C, 0x44, 0x00, 0x08, 0x36, 0x41, 0x00, 0x00, 0x00, 0x77, 0x00,
|
||||
0x00, 0x00, 0x41, 0x36, 0x08, 0x00, 0x02, 0x01, 0x02, 0x04, 0x02, 0x3C,
|
||||
0x26, 0x23, 0x26, 0x3C, 0x1E, 0xA1, 0xA1, 0x61, 0x12, 0x3A, 0x40, 0x40,
|
||||
0x20, 0x7A, 0x38, 0x54, 0x54, 0x55, 0x59, 0x21, 0x55, 0x55, 0x79, 0x41,
|
||||
0x22, 0x54, 0x54, 0x78, 0x42, // a-umlaut
|
||||
0x21, 0x55, 0x54, 0x78, 0x40, 0x20, 0x54, 0x55, 0x79, 0x40, 0x0C, 0x1E,
|
||||
0x52, 0x72, 0x12, 0x39, 0x55, 0x55, 0x55, 0x59, 0x39, 0x54, 0x54, 0x54,
|
||||
0x59, 0x39, 0x55, 0x54, 0x54, 0x58, 0x00, 0x00, 0x45, 0x7C, 0x41, 0x00,
|
||||
0x02, 0x45, 0x7D, 0x42, 0x00, 0x01, 0x45, 0x7C, 0x40, 0x7D, 0x12, 0x11,
|
||||
0x12, 0x7D, // A-umlaut
|
||||
0xF0, 0x28, 0x25, 0x28, 0xF0, 0x7C, 0x54, 0x55, 0x45, 0x00, 0x20, 0x54,
|
||||
0x54, 0x7C, 0x54, 0x7C, 0x0A, 0x09, 0x7F, 0x49, 0x32, 0x49, 0x49, 0x49,
|
||||
0x32, 0x3A, 0x44, 0x44, 0x44, 0x3A, // o-umlaut
|
||||
0x32, 0x4A, 0x48, 0x48, 0x30, 0x3A, 0x41, 0x41, 0x21, 0x7A, 0x3A, 0x42,
|
||||
0x40, 0x20, 0x78, 0x00, 0x9D, 0xA0, 0xA0, 0x7D, 0x3D, 0x42, 0x42, 0x42,
|
||||
0x3D, // O-umlaut
|
||||
0x3D, 0x40, 0x40, 0x40, 0x3D, 0x3C, 0x24, 0xFF, 0x24, 0x24, 0x48, 0x7E,
|
||||
0x49, 0x43, 0x66, 0x2B, 0x2F, 0xFC, 0x2F, 0x2B, 0xFF, 0x09, 0x29, 0xF6,
|
||||
0x20, 0xC0, 0x88, 0x7E, 0x09, 0x03, 0x20, 0x54, 0x54, 0x79, 0x41, 0x00,
|
||||
0x00, 0x44, 0x7D, 0x41, 0x30, 0x48, 0x48, 0x4A, 0x32, 0x38, 0x40, 0x40,
|
||||
0x22, 0x7A, 0x00, 0x7A, 0x0A, 0x0A, 0x72, 0x7D, 0x0D, 0x19, 0x31, 0x7D,
|
||||
0x26, 0x29, 0x29, 0x2F, 0x28, 0x26, 0x29, 0x29, 0x29, 0x26, 0x30, 0x48,
|
||||
0x4D, 0x40, 0x20, 0x38, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08,
|
||||
0x38, 0x2F, 0x10, 0xC8, 0xAC, 0xBA, 0x2F, 0x10, 0x28, 0x34, 0xFA, 0x00,
|
||||
0x00, 0x7B, 0x00, 0x00, 0x08, 0x14, 0x2A, 0x14, 0x22, 0x22, 0x14, 0x2A,
|
||||
0x14, 0x08, 0x55, 0x00, 0x55, 0x00, 0x55, // #176 (25% block) missing in old
|
||||
// code
|
||||
0xAA, 0x55, 0xAA, 0x55, 0xAA, // 50% block
|
||||
0xFF, 0x55, 0xFF, 0x55, 0xFF, // 75% block
|
||||
0x00, 0x00, 0x00, 0xFF, 0x00, 0x10, 0x10, 0x10, 0xFF, 0x00, 0x14, 0x14,
|
||||
0x14, 0xFF, 0x00, 0x10, 0x10, 0xFF, 0x00, 0xFF, 0x10, 0x10, 0xF0, 0x10,
|
||||
0xF0, 0x14, 0x14, 0x14, 0xFC, 0x00, 0x14, 0x14, 0xF7, 0x00, 0xFF, 0x00,
|
||||
0x00, 0xFF, 0x00, 0xFF, 0x14, 0x14, 0xF4, 0x04, 0xFC, 0x14, 0x14, 0x17,
|
||||
0x10, 0x1F, 0x10, 0x10, 0x1F, 0x10, 0x1F, 0x14, 0x14, 0x14, 0x1F, 0x00,
|
||||
0x10, 0x10, 0x10, 0xF0, 0x00, 0x00, 0x00, 0x00, 0x1F, 0x10, 0x10, 0x10,
|
||||
0x10, 0x1F, 0x10, 0x10, 0x10, 0x10, 0xF0, 0x10, 0x00, 0x00, 0x00, 0xFF,
|
||||
0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0xFF, 0x10, 0x00,
|
||||
0x00, 0x00, 0xFF, 0x14, 0x00, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0x00, 0x1F,
|
||||
0x10, 0x17, 0x00, 0x00, 0xFC, 0x04, 0xF4, 0x14, 0x14, 0x17, 0x10, 0x17,
|
||||
0x14, 0x14, 0xF4, 0x04, 0xF4, 0x00, 0x00, 0xFF, 0x00, 0xF7, 0x14, 0x14,
|
||||
0x14, 0x14, 0x14, 0x14, 0x14, 0xF7, 0x00, 0xF7, 0x14, 0x14, 0x14, 0x17,
|
||||
0x14, 0x10, 0x10, 0x1F, 0x10, 0x1F, 0x14, 0x14, 0x14, 0xF4, 0x14, 0x10,
|
||||
0x10, 0xF0, 0x10, 0xF0, 0x00, 0x00, 0x1F, 0x10, 0x1F, 0x00, 0x00, 0x00,
|
||||
0x1F, 0x14, 0x00, 0x00, 0x00, 0xFC, 0x14, 0x00, 0x00, 0xF0, 0x10, 0xF0,
|
||||
0x10, 0x10, 0xFF, 0x10, 0xFF, 0x14, 0x14, 0x14, 0xFF, 0x14, 0x10, 0x10,
|
||||
0x10, 0x1F, 0x00, 0x00, 0x00, 0x00, 0xF0, 0x10, 0xFF, 0xFF, 0xFF, 0xFF,
|
||||
0xFF, 0xF0, 0xF0, 0xF0, 0xF0, 0xF0, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0xFF, 0xFF, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x38, 0x44, 0x44,
|
||||
0x38, 0x44, 0xFC, 0x4A, 0x4A, 0x4A, 0x34, // sharp-s or beta
|
||||
0x7E, 0x02, 0x02, 0x06, 0x06, 0x02, 0x7E, 0x02, 0x7E, 0x02, 0x63, 0x55,
|
||||
0x49, 0x41, 0x63, 0x38, 0x44, 0x44, 0x3C, 0x04, 0x40, 0x7E, 0x20, 0x1E,
|
||||
0x20, 0x06, 0x02, 0x7E, 0x02, 0x02, 0x99, 0xA5, 0xE7, 0xA5, 0x99, 0x1C,
|
||||
0x2A, 0x49, 0x2A, 0x1C, 0x4C, 0x72, 0x01, 0x72, 0x4C, 0x30, 0x4A, 0x4D,
|
||||
0x4D, 0x30, 0x30, 0x48, 0x78, 0x48, 0x30, 0xBC, 0x62, 0x5A, 0x46, 0x3D,
|
||||
0x3E, 0x49, 0x49, 0x49, 0x00, 0x7E, 0x01, 0x01, 0x01, 0x7E, 0x2A, 0x2A,
|
||||
0x2A, 0x2A, 0x2A, 0x44, 0x44, 0x5F, 0x44, 0x44, 0x40, 0x51, 0x4A, 0x44,
|
||||
0x40, 0x40, 0x44, 0x4A, 0x51, 0x40, 0x00, 0x00, 0xFF, 0x01, 0x03, 0xE0,
|
||||
0x80, 0xFF, 0x00, 0x00, 0x08, 0x08, 0x6B, 0x6B, 0x08, 0x36, 0x12, 0x36,
|
||||
0x24, 0x36, 0x06, 0x0F, 0x09, 0x0F, 0x06, 0x00, 0x00, 0x18, 0x18, 0x00,
|
||||
0x00, 0x00, 0x10, 0x10, 0x00, 0x30, 0x40, 0xFF, 0x01, 0x01, 0x00, 0x1F,
|
||||
0x01, 0x01, 0x1E, 0x00, 0x19, 0x1D, 0x17, 0x12, 0x00, 0x3C, 0x3C, 0x3C,
|
||||
0x3C, 0x00, 0x00, 0x00, 0x00, 0x00 // #255 NBSP
|
||||
};
|
||||
|
||||
/**
|
||||
* Initialise the SSD1306 OLED display. This requires that the I2C has already been initialised.
|
||||
*/
|
||||
void YEEP144_SSD1306_Init(void){
|
||||
|
||||
// Allocate space in memory for the framebuffer to be stored
|
||||
// As the display is monochrome we only need 1 bit per pixel, so the data is packed
|
||||
// to save on memory space - i.e. 8 pixels per byte
|
||||
// The arithmetic used ensures that the buffer size is always padded to a whole byte number
|
||||
//
|
||||
// This is also how the framebuffer is stored within the OLED chip, so it can be directly
|
||||
// copied across without additional manipulation
|
||||
//
|
||||
// We make the TX buffer 1 byte larger than needed for the display data so the value 0x40 can be prepended
|
||||
// When it comes time to send the framebuffer to the display, that initial byte is required so the data is treated
|
||||
// as display data, not commands
|
||||
displayTXBuffer = (uint8_t *)malloc((WIDTH * ((HEIGHT + 7) / 8)) + 1);
|
||||
displayTXBuffer[0] = 0x40;
|
||||
|
||||
// For programming ease we store a separate pointer offset by 1 to directly access the display data portion of the buffer
|
||||
displayBuffer = displayTXBuffer + 1;
|
||||
|
||||
// Ensure the display buffer is empty
|
||||
YEEP144_SSD1306_ClearDisplay();
|
||||
|
||||
// This list of commands sets up the display and turns it on
|
||||
uint8_t initCommandList[] = {
|
||||
0x00, // Tell the display these are commands not graphics data
|
||||
SSD1306_DISPLAYOFF,
|
||||
SSD1306_SETDISPLAYCLOCKDIV,
|
||||
0x80, // Recommended clock div
|
||||
SSD1306_SETMULTIPLEX,
|
||||
HEIGHT - 1,
|
||||
SSD1306_SETDISPLAYOFFSET,
|
||||
0x0, // No display offset
|
||||
SSD1306_SETSTARTLINE | 0x0, // Start at line 0
|
||||
SSD1306_CHARGEPUMP,
|
||||
0x14, // Enable internal charge pump
|
||||
SSD1306_MEMORYMODE,
|
||||
0x00,
|
||||
SSD1306_SEGREMAP | 0x1,
|
||||
SSD1306_COMSCANDEC,
|
||||
SSD1306_SETCOMPINS,
|
||||
0x02, // This is hardcoded for the value for a 128x32 screen
|
||||
SSD1306_SETCONTRAST,
|
||||
0x8F, // This is hardcoded for the value for a 128x32 screen
|
||||
SSD1306_SETPRECHARGE,
|
||||
0xF1, // Value for when charge pump is enabled
|
||||
SSD1306_SETVCOMDETECT,
|
||||
0x40,
|
||||
SSD1306_DISPLAYALLON_RESUME,
|
||||
SSD1306_NORMALDISPLAY,
|
||||
SSD1306_DEACTIVATE_SCROLL,
|
||||
SSD1306_DISPLAYON
|
||||
|
||||
};
|
||||
|
||||
// Send the commands
|
||||
HAL_I2C_Master_Transmit(&hi2c2, SSD1306_ADDR, initCommandList, sizeof(initCommandList), I2C_TIMEOUT);
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Update the display by transfering the contents of the display buffer to the display.
|
||||
* No changes to the displayed graphics will be made until this command is called
|
||||
*/
|
||||
void YEEP144_SSD1306_Display(void){
|
||||
// Before sending graphics data we need to define where the data goes
|
||||
// As we are always copying over the whole frame buffer, we want our transfer to fill
|
||||
// the whole graphics memory on the driver chip
|
||||
uint8_t commandList[] = {
|
||||
0x00, // Following data are commands
|
||||
SSD1306_PAGEADDR,
|
||||
0, // Starting page
|
||||
0xFF, // Ending page
|
||||
SSD1306_COLUMNADDR,
|
||||
0, // Starting column
|
||||
(WIDTH-1), // Ending column
|
||||
//0x40 // Following data will be graphics not commands
|
||||
};
|
||||
|
||||
// Send these commands
|
||||
HAL_I2C_Master_Transmit(&hi2c2, SSD1306_ADDR, commandList, sizeof(commandList), I2C_TIMEOUT);
|
||||
|
||||
// Send the graphics data. We use the TXbuffer here so it includes the additional byte at the start that tells the chip this is graphics data
|
||||
HAL_I2C_Master_Transmit(&hi2c2, SSD1306_ADDR, displayTXBuffer, (WIDTH * ((HEIGHT + 7) / 8)) + 1, I2C_TIMEOUT);
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Clears the display by clearing the display buffer
|
||||
*/
|
||||
void YEEP144_SSD1306_ClearDisplay(void){
|
||||
|
||||
// Clear the display by filling the buffer with all zeros
|
||||
memset(displayBuffer, 0, WIDTH * ((HEIGHT + 7) / 8));
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets a single pixel in the display buffer to the specified colour
|
||||
*/
|
||||
void YEEP144_SSD1306_SetPixel(uint8_t x, uint8_t y, uint8_t colour){
|
||||
|
||||
// As the data is packed with 8 pixels per byte, we need to do some bit-level
|
||||
// manipulation to set an individual pixel
|
||||
switch(colour){
|
||||
// Set the bit for white (on)
|
||||
case SSD1306_WHITE:
|
||||
displayBuffer[x + (y / 8) * WIDTH] |= (1 << (y & 7));
|
||||
break;
|
||||
// Clear the bit for black (off)
|
||||
case SSD1306_BLACK:
|
||||
displayBuffer[x + (y / 8) * WIDTH] &= ~(1 << (y & 7));
|
||||
break;
|
||||
// Invert the bit to invert the colour
|
||||
case SSD1306_INVERSE:
|
||||
displayBuffer[x + (y / 8) * WIDTH] ^= (1 << (y & 7));
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the current value of the specified pixel from the display buffer.
|
||||
* Note that this is what is currently stored in the local buffer, not
|
||||
* necessarily what is currently being displayed if Display has not been called
|
||||
*/
|
||||
bool YEEP144_SSD1306_GetPixel(uint8_t x, uint8_t y){
|
||||
// As the 1-bit pixels are packed into bytes, we need to do some bit manipulation to retrieve the individual bit
|
||||
return (displayBuffer[x + (y / 8) * WIDTH] & (1 << (y & 7)));
|
||||
}
|
||||
|
||||
/**
|
||||
* Draws a line between the specified coordinates, using the specified colour
|
||||
*/
|
||||
void YEEP144_SSD1306_DrawLine(uint8_t x0, uint8_t y0, uint8_t x1, uint8_t y1, uint8_t colour){
|
||||
// This function checks if the draw can be fufilled by one of the optimised horizontal or vertical
|
||||
// line drawing functions, if not passes to the generalised one
|
||||
if(x0 == x1){ // If both x coordinates are the same then this is vertical
|
||||
if (y0 > y1){ // Normalise direction by swapping the coords if needed
|
||||
uint8_t t = y0;
|
||||
y0 = y1;
|
||||
y1 = t;
|
||||
}
|
||||
YEEP144_SSD1306_DrawFastVLine(x0, y0, y1 - y0, colour);
|
||||
}
|
||||
else if(y0 == y1){ // If both y coordinates are the same then this is horizontal
|
||||
if(x0 > x1){ // Normalise direction by swapping the coords if needed
|
||||
uint8_t t = x0;
|
||||
x0 = x1;
|
||||
x1 = t;
|
||||
}
|
||||
YEEP144_SSD1306_DrawFastHLine(x0, y0, x1 - x0, colour);
|
||||
}
|
||||
else{
|
||||
// If this cannot be handled by either of the fast algorithms, fallback to the general one
|
||||
YEEP144_SSD1306_DrawLineInternal(x0, y0, x1, y1, colour);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Draws a line between the two specified points using Bresenham's algorithm
|
||||
* This is only used when the line is not vertical or horizontal
|
||||
* This will only be an approximation of requested line due to the limited resolution of the display
|
||||
* and the lack of options for antialiasing
|
||||
*/
|
||||
void YEEP144_SSD1306_DrawLineInternal(uint8_t x0, uint8_t y0, uint8_t x1, uint8_t y1, uint8_t colour){
|
||||
// Bresenham's algorithm only works when going in the positive direction, which would be down and right
|
||||
// for a display with (0,0) in the top left corner. So that this can be used for all cases,
|
||||
// we need to detect the direction of the requested line and transform the coordinates
|
||||
uint8_t steep = abs(y1 - y0) > abs(x1 - x0);
|
||||
|
||||
if(steep){
|
||||
uint8_t t = x0;
|
||||
x0 = y0;
|
||||
y0 = t;
|
||||
|
||||
t = x1;
|
||||
x1 = y1;
|
||||
y1 = t;
|
||||
}
|
||||
|
||||
if(x0 > x1){
|
||||
uint8_t t = x0;
|
||||
x0 = x1;
|
||||
x1 = t;
|
||||
t = y0;
|
||||
y0 = y1;
|
||||
y1 = t;
|
||||
}
|
||||
|
||||
int8_t dx = x1 - x0;
|
||||
int8_t dy = abs(y1 - y0);
|
||||
|
||||
int8_t err = dx / 2;
|
||||
int8_t ystep;
|
||||
|
||||
if(y0 < y1){
|
||||
ystep = 1;
|
||||
}
|
||||
else{
|
||||
ystep = -1;
|
||||
}
|
||||
|
||||
for(; x0 <= x1; x0++){
|
||||
if(steep){
|
||||
YEEP144_SSD1306_SetPixel(y0, x0, colour);
|
||||
}
|
||||
else{
|
||||
YEEP144_SSD1306_SetPixel(x0, y0, colour);
|
||||
}
|
||||
err -= dy;
|
||||
if(err < 0){
|
||||
y0 += ystep;
|
||||
err += dx;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Draw a purely horizontal line. This is faster than the general algorithm,
|
||||
* but only works for horizontal lines
|
||||
*/
|
||||
void YEEP144_SSD1306_DrawFastHLine(uint8_t x, uint8_t y, int8_t w, uint8_t colour){
|
||||
if (y < HEIGHT) { // Y coord in bounds?
|
||||
if ((x + w) > WIDTH) { // Clip right
|
||||
w = (WIDTH - x);
|
||||
}
|
||||
if (w > 0) { // Proceed only if width is positive
|
||||
uint8_t *pBuf = &displayBuffer[(y / 8) * WIDTH + x];
|
||||
uint8_t mask = 1 << (y & 7);
|
||||
switch (colour) {
|
||||
case SSD1306_WHITE:
|
||||
while (w--) {
|
||||
*pBuf++ |= mask;
|
||||
};
|
||||
break;
|
||||
case SSD1306_BLACK:
|
||||
mask = ~mask;
|
||||
while (w--) {
|
||||
*pBuf++ &= mask;
|
||||
};
|
||||
break;
|
||||
case SSD1306_INVERSE:
|
||||
while (w--) {
|
||||
*pBuf++ ^= mask;
|
||||
};
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Draw a purely vertical line. This is faster than the general algorithm,
|
||||
* but only works for vertical lines
|
||||
*/
|
||||
void YEEP144_SSD1306_DrawFastVLine(uint8_t x, uint8_t y, int8_t h, uint8_t colour){
|
||||
if (x < WIDTH) { // X coord in bounds?
|
||||
if ((y + h) > HEIGHT) { // Clip bottom
|
||||
h = (HEIGHT - y);
|
||||
}
|
||||
if (h > 0) { // Proceed only if height is now positive
|
||||
|
||||
uint8_t *pBuf = &displayBuffer[(y / 8) * WIDTH + x];
|
||||
|
||||
// do the first partial byte, if necessary - this requires some masking
|
||||
uint8_t mod = (y & 7);
|
||||
if (mod) {
|
||||
// mask off the high n bits we want to set
|
||||
mod = 8 - mod;
|
||||
// note - lookup table results in a nearly 10% performance
|
||||
// improvement in fill* functions
|
||||
// uint8_t mask = ~(0xFF >> mod);
|
||||
static const uint8_t premask[8] = {0x00, 0x80, 0xC0, 0xE0,
|
||||
0xF0, 0xF8, 0xFC, 0xFE};
|
||||
uint8_t mask = premask[mod];
|
||||
// adjust the mask if we're not going to reach the end of this byte
|
||||
if (h < mod)
|
||||
mask &= (0XFF >> (mod - h));
|
||||
|
||||
switch (colour) {
|
||||
case SSD1306_WHITE:
|
||||
*pBuf |= mask;
|
||||
break;
|
||||
case SSD1306_BLACK:
|
||||
*pBuf &= ~mask;
|
||||
break;
|
||||
case SSD1306_INVERSE:
|
||||
*pBuf ^= mask;
|
||||
break;
|
||||
}
|
||||
pBuf += WIDTH;
|
||||
}
|
||||
|
||||
if (h >= mod) { // More to go?
|
||||
h -= mod;
|
||||
// Write solid bytes while we can - effectively 8 rows at a time
|
||||
if (h >= 8) {
|
||||
if (colour == SSD1306_INVERSE) {
|
||||
// separate copy of the code so we don't impact performance of
|
||||
// black/white write version with an extra comparison per loop
|
||||
do {
|
||||
*pBuf ^= 0xFF; // Invert byte
|
||||
pBuf += WIDTH; // Advance pointer 8 rows
|
||||
h -= 8; // Subtract 8 rows from height
|
||||
} while (h >= 8);
|
||||
} else {
|
||||
// store a local value to work with
|
||||
uint8_t val = (colour != SSD1306_BLACK) ? 255 : 0;
|
||||
do {
|
||||
*pBuf = val; // Set byte
|
||||
pBuf += WIDTH; // Advance pointer 8 rows
|
||||
h -= 8; // Subtract 8 rows from height
|
||||
} while (h >= 8);
|
||||
}
|
||||
}
|
||||
|
||||
if (h) { // Do the final partial byte, if necessary
|
||||
mod = h & 7;
|
||||
// this time we want to mask the low bits of the byte,
|
||||
// vs the high bits we did above
|
||||
// uint8_t mask = (1 << mod) - 1;
|
||||
// note - lookup table results in a nearly 10% performance
|
||||
// improvement in fill* functions
|
||||
static const uint8_t postmask[8] = {0x00, 0x01, 0x03, 0x07,
|
||||
0x0F, 0x1F, 0x3F, 0x7F};
|
||||
uint8_t mask = postmask[mod];
|
||||
switch (colour) {
|
||||
case SSD1306_WHITE:
|
||||
*pBuf |= mask;
|
||||
break;
|
||||
case SSD1306_BLACK:
|
||||
*pBuf &= ~mask;
|
||||
break;
|
||||
case SSD1306_INVERSE:
|
||||
*pBuf ^= mask;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
} // endif positive height
|
||||
} // endif x in bounds
|
||||
}
|
||||
|
||||
/**
|
||||
* Draws an outline of a rectangle with no fill. Coordinates represent the top left corner
|
||||
*/
|
||||
void YEEP144_SSD1306_DrawRect(uint8_t x, uint8_t y, uint8_t w, uint8_t h, uint8_t colour){
|
||||
YEEP144_SSD1306_DrawFastHLine(x, y, w, colour);
|
||||
YEEP144_SSD1306_DrawFastHLine(x, y + h - 1, w, colour);
|
||||
YEEP144_SSD1306_DrawFastVLine(x, y, h, colour);
|
||||
YEEP144_SSD1306_DrawFastVLine(x + w - 1, y, h, colour);
|
||||
}
|
||||
|
||||
/**
|
||||
* Draw a filled rectangle of given width and height, with the top left corner specified
|
||||
* by the given coordinates
|
||||
*/
|
||||
void YEEP144_SSD1306_DrawFillRect(uint8_t x, uint8_t y, int8_t w, int8_t h, uint8_t colour){
|
||||
for (int16_t i = x; i < x + w; i++) {
|
||||
YEEP144_SSD1306_DrawFastVLine(i, y, h, colour);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Prints text to the screen using printf-style formatting. Cursor starting position, font size and
|
||||
* text wrapping can be controlled using the provided functions
|
||||
*/
|
||||
int YEEP144_SSD1306_printf(const char * format, ...){
|
||||
// Set the buffer size to the maximum that can fit on the screen with the smallest font
|
||||
size_t bufSize = MAXCHAR;
|
||||
|
||||
// Try to allocate that buffer
|
||||
char* buffer = malloc(bufSize);
|
||||
|
||||
// If the buffer cannot be allocated, return -1
|
||||
if (buffer == NULL) return -1;
|
||||
|
||||
// Get the pointer to the variadic args
|
||||
va_list args;
|
||||
va_start (args, format);
|
||||
|
||||
// Create our final string in the buffer using vsnprintf, passing through our argument pointer
|
||||
vsnprintf(buffer, bufSize, format, args);
|
||||
|
||||
// Calulate the final size of the string
|
||||
bufSize = strlen(buffer);
|
||||
|
||||
// Write our characters one by one to the screen
|
||||
for(size_t i = 0; i < bufSize; i++){
|
||||
char c = buffer[i];
|
||||
|
||||
if(c == '\n'){// Newline - move cursor down by 1 line, and back to start of line
|
||||
cursorX = 0;
|
||||
cursorY += textSize * (FONTHEIGHT + 1);
|
||||
}
|
||||
else if(c != '\r'){ // All other text - ignoring carriage returns
|
||||
if(textWrap && ((cursorX + textSize * (FONTWIDTH + 1)) > WIDTH)){
|
||||
// If wrapping is enabled and this character will overflow the display, move to start of next line
|
||||
cursorX = 0;
|
||||
cursorY += textSize * (FONTHEIGHT + 1);
|
||||
}
|
||||
if((cursorY + FONTHEIGHT) > HEIGHT){ // If we have reached the bottom of the screen, start back at the top
|
||||
cursorY = 0;
|
||||
cursorX = 0;
|
||||
}
|
||||
// Draw the character at the cursor coordinates
|
||||
YEEP144_SSD1306_DrawChar(cursorX, cursorY, c, textColour, textBGColour, textSize);
|
||||
|
||||
// Move the cursor forward by one character
|
||||
cursorX += (FONTWIDTH + 1) * textSize;
|
||||
}
|
||||
}
|
||||
|
||||
// Free the memory used
|
||||
free(buffer);
|
||||
|
||||
// Return number of characters printed
|
||||
return bufSize;
|
||||
}
|
||||
|
||||
/**
|
||||
* Draws a single character to the screen, with the specified coordinates being the top left of the character
|
||||
* Uses the specified text colour, background colour and size multiplier
|
||||
*/
|
||||
void YEEP144_SSD1306_DrawChar(uint8_t x, uint8_t y, uint8_t c, uint8_t colour, uint8_t bg, uint8_t size){
|
||||
|
||||
if ((x >= WIDTH) || // Clip right
|
||||
(y >= HEIGHT) || // Clip bottom
|
||||
((x + 6 * size - 1) < 0) || // Clip left
|
||||
((y + 8 * size - 1) < 0)) // Clip top
|
||||
return;
|
||||
|
||||
for (int8_t i = 0; i < 5; i++) { // Char bitmap = 5 columns
|
||||
uint8_t line = font[c * 5 + i];
|
||||
for (int8_t j = 0; j < 8; j++, line >>= 1) {
|
||||
if (line & 1) {
|
||||
if (size == 1)
|
||||
YEEP144_SSD1306_SetPixel(x + i, y + j, colour);
|
||||
else
|
||||
YEEP144_SSD1306_DrawFillRect(x + i * size, y + j * size, size, size, colour);
|
||||
} else if (bg != colour) {
|
||||
if (size == 1)
|
||||
YEEP144_SSD1306_SetPixel(x + i, y + j, bg);
|
||||
else
|
||||
YEEP144_SSD1306_DrawFillRect(x + i * size, y + j * size, size, size, bg);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (bg != colour) { // If opaque, draw vertical line for last column
|
||||
if (size == 1)
|
||||
YEEP144_SSD1306_DrawFastVLine(x + 5, y, 8, bg);
|
||||
else
|
||||
YEEP144_SSD1306_DrawFillRect(x + 5 * size, y, size, 8 * size, bg);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the text scaling.
|
||||
* 1 = Normal, 4 lines will fit on display
|
||||
* 2 = 2 lines will fit
|
||||
* 4 = 1 line will fit
|
||||
*/
|
||||
void YEEP144_SSD1306_SetTextSize(uint8_t size){
|
||||
textSize = size;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the position of the cursor
|
||||
* The coordinates defire the top left corner of the character
|
||||
*/
|
||||
void YEEP144_SSD1306_SetTextCursor(uint8_t x, uint8_t y){
|
||||
cursorX = x;
|
||||
cursorY = y;
|
||||
}
|
||||
|
||||
/**
|
||||
* Enable or disable text line wrapping
|
||||
* 0 is disabled, 1 is enabled
|
||||
*/
|
||||
void YEEP144_SSD1306_SetTextWrap(uint8_t wrap){
|
||||
textWrap = wrap;
|
||||
}
|
||||
|
||||
/**
|
||||
* Draws a 1-bit bitmap to the screen at the specified position
|
||||
*/
|
||||
void YEEP144_SSD1306_DrawBitmap(uint8_t x, uint8_t y, const uint8_t bitmap[], uint8_t w, uint8_t h){
|
||||
uint8_t byteWidth = (w + 7) / 8; // Bitmap scanline pad = whole byte
|
||||
uint8_t b = 0;
|
||||
|
||||
for (uint8_t j = 0; j < h; j++, y++) {
|
||||
for (uint8_t i = 0; i < w; i++) {
|
||||
if (i & 7){
|
||||
b <<= 1;
|
||||
}
|
||||
else{
|
||||
b = bitmap[j * byteWidth + i / 8];
|
||||
}
|
||||
YEEP144_SSD1306_SetPixel(x + i, y, (b & 0x80) ? SSD1306_WHITE : SSD1306_BLACK);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Inverts the colours of the display. Note that this happens using a hardware command to the display
|
||||
* and doesn't touch the buffer
|
||||
*/
|
||||
void YEEP144_SSD1306_InvertDisplay(bool i){
|
||||
YEEP144_SSD1306_SendCommand(i ? SSD1306_INVERTDISPLAY : SSD1306_NORMALDISPLAY);
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper function that sends a single command to the display
|
||||
*/
|
||||
void YEEP144_SSD1306_SendCommand(uint8_t command){
|
||||
|
||||
// For data to be recognised as a command, the I2C transaction must start with 0x00
|
||||
uint8_t data[] = {0x00, command};
|
||||
|
||||
// Transmit the data
|
||||
HAL_I2C_Master_Transmit(&hi2c2, SSD1306_ADDR, data, 2, I2C_TIMEOUT);
|
||||
}
|
||||
|
||||
/*
|
||||
Much of this code was taken from or inspired by the Adafruit_SSD1306 and Adafruit_GFX libraries,
|
||||
adapted for use on STM32 rather than the Arduino platform. For that code the following disclaimer applies:
|
||||
|
||||
Copyright (c) 2013 Adafruit Industries. All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are met:
|
||||
|
||||
- Redistributions of source code must retain the above copyright notice,
|
||||
this list of conditions and the following disclaimer.
|
||||
- Redistributions in binary form must reproduce the above copyright notice,
|
||||
this list of conditions and the following disclaimer in the documentation
|
||||
and/or other materials provided with the distribution.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
|
||||
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
313
YEEP144lib/src/YEEP144_Servo.c
Normal file
313
YEEP144lib/src/YEEP144_Servo.c
Normal file
@@ -0,0 +1,313 @@
|
||||
#include "YEEP144.h"
|
||||
#include "YEEP144_Servo.h"
|
||||
|
||||
#include "YEEP144_Pinout.h"
|
||||
#include "stm32h563xx.h"
|
||||
#include "stm32h5xx_hal.h"
|
||||
#include "stm32h5xx_hal_gpio.h"
|
||||
#include "stm32h5xx_hal_gpio_ex.h"
|
||||
#include "stm32h5xx_hal_rcc.h"
|
||||
#include "stm32h5xx_hal_tim.h"
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
TIM_HandleTypeDef htim5;
|
||||
TIM_HandleTypeDef htim13;
|
||||
TIM_HandleTypeDef htim17servo;
|
||||
|
||||
uint16_t servoMinTicks[4] = {2048, 2048, 2048, 2048};
|
||||
uint16_t servoMaxTicks[4] = {4095, 4095, 4095, 4095};
|
||||
float servoMinDegrees[4] = {0, 0, 0, 0};
|
||||
float servoMaxDegrees[4] = {180, 180, 180, 180};
|
||||
|
||||
uint16_t YEEP144_Servo_MapAngleToTicks(float angle, float minAngle, float maxAngle, uint16_t minTicks, uint16_t maxTicks);
|
||||
|
||||
/**
|
||||
* Initialises servos 1 and 2. This consumes timer 5 and two GPIO
|
||||
*/
|
||||
void YEEP144_Servo_Init1_2(void){
|
||||
|
||||
// Enable clock to TIM5
|
||||
__HAL_RCC_TIM5_CLK_ENABLE();
|
||||
|
||||
// Configure and initialise TIM5
|
||||
// Servo PWM is a 1ms - 2ms pulse every 20ms
|
||||
// This is done using a 50Hz PWM with a duty cycle between 5 and 10%
|
||||
// Our ARR is set to 40950, the range of the ADC is 0-4095, /2 = 2048, which represents 5% of the total range
|
||||
// Offsetting by 2048 means we cover the 5 to 10% range
|
||||
TIM_MasterConfigTypeDef sMasterConfig = {0};
|
||||
TIM_OC_InitTypeDef sConfigOC = {0};
|
||||
|
||||
htim5.Instance = TIM5;
|
||||
htim5.Init.Prescaler = 121;
|
||||
htim5.Init.CounterMode = TIM_COUNTERMODE_UP;
|
||||
htim5.Init.Period = 40950;
|
||||
htim5.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1;
|
||||
htim5.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_DISABLE;
|
||||
if (HAL_TIM_PWM_Init(&htim5) != HAL_OK){
|
||||
//Error_Handler();
|
||||
}
|
||||
|
||||
// Disable synchronisation as it is not needed
|
||||
sMasterConfig.MasterOutputTrigger = TIM_TRGO_RESET;
|
||||
sMasterConfig.MasterSlaveMode = TIM_MASTERSLAVEMODE_DISABLE;
|
||||
if (HAL_TIMEx_MasterConfigSynchronization(&htim5, &sMasterConfig) != HAL_OK){
|
||||
//Error_Handler();
|
||||
}
|
||||
|
||||
// Configure the two used PWM channels
|
||||
sConfigOC.OCMode = TIM_OCMODE_PWM1;
|
||||
sConfigOC.Pulse = 0;
|
||||
sConfigOC.OCPolarity = TIM_OCPOLARITY_HIGH;
|
||||
sConfigOC.OCFastMode = TIM_OCFAST_DISABLE;
|
||||
if (HAL_TIM_PWM_ConfigChannel(&htim5, &sConfigOC, TIM_CHANNEL_1) != HAL_OK){
|
||||
//Error_Handler();
|
||||
}
|
||||
if (HAL_TIM_PWM_ConfigChannel(&htim5, &sConfigOC, TIM_CHANNEL_4) != HAL_OK){
|
||||
//Error_Handler();
|
||||
}
|
||||
|
||||
// Configure GPIOs
|
||||
YEEP144_GPIO_InitAdv(SERVO1_PORT, SERVO1_PIN | SERVO2_PIN, GPIO_MODE_AF_PP, GPIO_NOPULL, GPIO_SPEED_FREQ_LOW, GPIO_AF2_TIM5);
|
||||
|
||||
HAL_TIM_PWM_Start(&htim5, TIM_CHANNEL_1);
|
||||
HAL_TIM_PWM_Start(&htim5, TIM_CHANNEL_4);
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Initialises servo 3. This consumes timer 13 and one GPIO
|
||||
*/
|
||||
void YEEP144_Servo_Init3(void){
|
||||
// Enable clock to TIM13
|
||||
__HAL_RCC_TIM13_CLK_ENABLE();
|
||||
|
||||
// Configure and initialise TIM13
|
||||
// Servo PWM is a 1ms - 2ms pulse every 20ms
|
||||
// This is done using a 50Hz PWM with a duty cycle between 5 and 10%
|
||||
// Our ARR is set to 40950, the range of the ADC is 0-4095, /2 = 2048, which represents 5% of the total range
|
||||
// Offsetting by 2048 means we cover the 5 to 10% range
|
||||
TIM_MasterConfigTypeDef sMasterConfig = {0};
|
||||
TIM_OC_InitTypeDef sConfigOC = {0};
|
||||
|
||||
htim13.Instance = TIM13;
|
||||
htim13.Init.Prescaler = 121;
|
||||
htim13.Init.CounterMode = TIM_COUNTERMODE_UP;
|
||||
htim13.Init.Period = 40950;
|
||||
htim13.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1;
|
||||
htim13.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_DISABLE;
|
||||
if (HAL_TIM_PWM_Init(&htim13) != HAL_OK){
|
||||
//Error_Handler();
|
||||
}
|
||||
|
||||
// Disable synchronisation as it is not needed
|
||||
sMasterConfig.MasterOutputTrigger = TIM_TRGO_RESET;
|
||||
sMasterConfig.MasterSlaveMode = TIM_MASTERSLAVEMODE_DISABLE;
|
||||
if (HAL_TIMEx_MasterConfigSynchronization(&htim13, &sMasterConfig) != HAL_OK){
|
||||
//Error_Handler();
|
||||
}
|
||||
|
||||
// Configure the two used PWM channels
|
||||
sConfigOC.OCMode = TIM_OCMODE_PWM1;
|
||||
sConfigOC.Pulse = 0;
|
||||
sConfigOC.OCPolarity = TIM_OCPOLARITY_HIGH;
|
||||
sConfigOC.OCFastMode = TIM_OCFAST_DISABLE;
|
||||
if (HAL_TIM_PWM_ConfigChannel(&htim13, &sConfigOC, TIM_CHANNEL_1) != HAL_OK){
|
||||
//Error_Handler();
|
||||
}
|
||||
|
||||
// Configure GPIOs
|
||||
YEEP144_GPIO_InitAdv(SERVO3_PORT, SERVO3_PIN, GPIO_MODE_AF_PP, GPIO_NOPULL, GPIO_SPEED_FREQ_LOW, GPIO_AF9_TIM13);
|
||||
|
||||
HAL_TIM_PWM_Start(&htim13, TIM_CHANNEL_1);
|
||||
}
|
||||
|
||||
/**
|
||||
* Initialises servo 4. This consumes timer 17 and one GPIO. These resources are share with the buzzer.
|
||||
* Ensure only one is initialised. When using servo 4, disable the buzzer using DIP switch SW5 so the
|
||||
* PWM signal is not made audible
|
||||
*/
|
||||
void YEEP144_Servo_Init4(void){
|
||||
// Enable clock to TIM17
|
||||
__HAL_RCC_TIM17_CLK_ENABLE();
|
||||
|
||||
// Configure and initialise TIM17
|
||||
// Servo PWM is a 1ms - 2ms pulse every 20ms
|
||||
// This is done using a 50Hz PWM with a duty cycle between 5 and 10%
|
||||
// Our ARR is set to 40950, the range of the ADC is 0-4095, /2 = 2048, which represents 5% of the total range
|
||||
// Offsetting by 2048 means we cover the 5 to 10% range
|
||||
TIM_MasterConfigTypeDef sMasterConfig = {0};
|
||||
TIM_OC_InitTypeDef sConfigOC = {0};
|
||||
|
||||
htim17servo.Instance = TIM17;
|
||||
htim17servo.Init.Prescaler = 121;
|
||||
htim17servo.Init.CounterMode = TIM_COUNTERMODE_UP;
|
||||
htim17servo.Init.Period = 40950;
|
||||
htim17servo.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1;
|
||||
htim17servo.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_DISABLE;
|
||||
if (HAL_TIM_PWM_Init(&htim17servo) != HAL_OK){
|
||||
//Error_Handler();
|
||||
}
|
||||
|
||||
// Disable synchronisation as it is not needed
|
||||
sMasterConfig.MasterOutputTrigger = TIM_TRGO_RESET;
|
||||
sMasterConfig.MasterSlaveMode = TIM_MASTERSLAVEMODE_DISABLE;
|
||||
if (HAL_TIMEx_MasterConfigSynchronization(&htim17servo, &sMasterConfig) != HAL_OK){
|
||||
//Error_Handler();
|
||||
}
|
||||
|
||||
// Configure the two used PWM channels
|
||||
sConfigOC.OCMode = TIM_OCMODE_PWM1;
|
||||
sConfigOC.Pulse = 0;
|
||||
sConfigOC.OCPolarity = TIM_OCPOLARITY_HIGH;
|
||||
sConfigOC.OCFastMode = TIM_OCFAST_DISABLE;
|
||||
if (HAL_TIM_PWM_ConfigChannel(&htim17servo, &sConfigOC, TIM_CHANNEL_1) != HAL_OK){
|
||||
//Error_Handler();
|
||||
}
|
||||
|
||||
// Configure GPIOs
|
||||
YEEP144_GPIO_InitAdv(SERVO4_PORT, SERVO4_PIN, GPIO_MODE_AF_PP, GPIO_NOPULL, GPIO_SPEED_FREQ_LOW, GPIO_AF1_TIM17);
|
||||
|
||||
HAL_TIM_PWM_Start(&htim17servo, TIM_CHANNEL_1);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the zero point for a given servo
|
||||
*
|
||||
* Default configuration is 2048, yielding a 5% to 10% duty cycle, or 1ms - 2ms pulse, which is the typical standard
|
||||
* Adjusting the zero offset can help account for differences in servos
|
||||
* that means 5% duty cycle does not exactly reach 0 degrees
|
||||
*
|
||||
* The offset applies to both SetDirect and SetAngle
|
||||
*/
|
||||
void YEEP144_Servo_SetMinTicks(uint8_t servo, uint16_t min){
|
||||
if(servo == 0 || servo >= 4) return;
|
||||
servoMinTicks[servo-1] = min;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the max point for a given servo
|
||||
*
|
||||
* Default configuration is 4096, yielding a 5% to 10% duty cycle, or 1ms - 2ms pulse, which is the typical standard
|
||||
* Adjusting the max offset can help account for differences in servos
|
||||
* that means 10% duty cycle does not exactly reach 180 degrees
|
||||
*
|
||||
* This only applies when using SetAngle. SetDirect has no limit on what you can set
|
||||
*/
|
||||
void YEEP144_Servo_SetMaxTicks(uint8_t servo, uint16_t max){
|
||||
if(servo == 0 || servo >= 4) return;
|
||||
servoMaxTicks[servo-1] = max;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the minimum angle range for a given servo
|
||||
*
|
||||
* Default is 0, for 0-180deg servos
|
||||
*
|
||||
* This only applies to SetAngle
|
||||
*/
|
||||
void YEEP144_Servo_SetMinAngle(uint8_t servo, float min){
|
||||
if(servo == 0 || servo >= 4) return;
|
||||
servoMinDegrees[servo-1] = min;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the maximum angle range for a given servo
|
||||
*
|
||||
* Default is 180, for 0-180deg servos
|
||||
*
|
||||
* This only applies to SetAngle
|
||||
*/
|
||||
void YEEP144_Servo_SetMaxAngle(uint8_t servo, float max){
|
||||
if(servo == 0 || servo >= 4) return;
|
||||
servoMaxDegrees[servo-1] = max;
|
||||
}
|
||||
|
||||
/**
|
||||
* Directly set the pulse value of the timer to control the position of the servo
|
||||
* Typically this should be in the range 0-2047
|
||||
* The function will accept larger pulse values, which will result in a duty cycle >10%, or a pulse of >2ms
|
||||
* This may be useful for servos who's maximum angle is not achieved at 10%
|
||||
* Along with setting the zero offset, this should account for troublesome servos, albeit with less elegant maths
|
||||
*/
|
||||
void YEEP144_Servo1_SetDirect(uint16_t pulse){
|
||||
TIM5->CCR1 = pulse + servoMinTicks[0];
|
||||
}
|
||||
|
||||
/**
|
||||
* Directly set the pulse value of the timer to control the position of the servo
|
||||
* Typically this should be in the range 0-2047
|
||||
* The function will accept larger pulse values, which will result in a duty cycle >10%, or a pulse of >2ms
|
||||
* This may be useful for servos who's maximum angle is not achieved at 10%
|
||||
* Along with setting the zero offset, this should account for troublesome servos, albeit with less elegant maths
|
||||
*/
|
||||
void YEEP144_Servo2_SetDirect(uint16_t pulse){
|
||||
TIM5->CCR4 = pulse + servoMinTicks[1];
|
||||
}
|
||||
|
||||
/**
|
||||
* Directly set the pulse value of the timer to control the position of the servo
|
||||
* Typically this should be in the range 0-2047
|
||||
* The function will accept larger pulse values, which will result in a duty cycle >10%, or a pulse of >2ms
|
||||
* This may be useful for servos who's maximum angle is not achieved at 10%
|
||||
* Along with setting the zero offset, this should account for troublesome servos, albeit with less elegant maths
|
||||
*/
|
||||
void YEEP144_Servo3_SetDirect(uint16_t pulse){
|
||||
TIM13->CCR1 = pulse + servoMinTicks[2];
|
||||
}
|
||||
|
||||
/**
|
||||
* Directly set the pulse value of the timer to control the position of the servo
|
||||
* Typically this should be in the range 0-2047
|
||||
* The function will accept larger pulse values, which will result in a duty cycle >10%, or a pulse of >2ms
|
||||
* This may be useful for servos who's maximum angle is not achieved at 10%
|
||||
* Along with setting the zero offset, this should account for troublesome servos, albeit with less elegant maths
|
||||
*/
|
||||
void YEEP144_Servo4_SetDirect(uint16_t pulse){
|
||||
TIM17->CCR1 = pulse + servoMinTicks[3];
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the servo to a specified angle. This will be based on the minimum and maximum angles set for the servo
|
||||
* By default this will work in the range 0 to 180
|
||||
*/
|
||||
void YEEP144_Servo1_SetAngle(float angle){
|
||||
if(angle < servoMinDegrees[0] || angle > servoMaxDegrees[0]) return; // If the angle is out of range, do nothing
|
||||
TIM5->CCR1 = YEEP144_Servo_MapAngleToTicks(angle, servoMinDegrees[0], servoMaxDegrees[0], servoMinTicks[0], servoMaxTicks[0]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the servo to a specified angle. This will be based on the minimum and maximum angles set for the servo
|
||||
* By default this will work in the range 0 to 180
|
||||
*/
|
||||
void YEEP144_Servo2_SetAngle(float angle){
|
||||
if(angle < servoMinDegrees[1] || angle > servoMaxDegrees[1]) return; // If the angle is out of range, do nothing
|
||||
TIM5->CCR1 = YEEP144_Servo_MapAngleToTicks(angle, servoMinDegrees[1], servoMaxDegrees[1], servoMinTicks[1], servoMaxTicks[1]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the servo to a specified angle. This will be based on the minimum and maximum angles set for the servo
|
||||
* By default this will work in the range 0 to 180
|
||||
*/
|
||||
void YEEP144_Servo3_SetAngle(float angle){
|
||||
if(angle < servoMinDegrees[0] || angle > servoMaxDegrees[0]) return; // If the angle is out of range, do nothing
|
||||
TIM5->CCR1 = YEEP144_Servo_MapAngleToTicks(angle, servoMinDegrees[0], servoMaxDegrees[0], servoMinTicks[0], servoMaxTicks[0]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the servo to a specified angle. This will be based on the minimum and maximum angles set for the servo
|
||||
* By default this will work in the range 0 to 180
|
||||
*/
|
||||
void YEEP144_Servo4_SetAngle(float angle){
|
||||
if(angle < servoMinDegrees[0] || angle > servoMaxDegrees[0]) return; // If the angle is out of range, do nothing
|
||||
TIM5->CCR1 = YEEP144_Servo_MapAngleToTicks(angle, servoMinDegrees[0], servoMaxDegrees[0], servoMinTicks[0], servoMaxTicks[0]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper function used to map a float angle to a timer tick value, based on the min and max ranges specified
|
||||
* e.g. map the angle 90 from the range 0 to 180, into the range 2048 - 4095
|
||||
*/
|
||||
uint16_t YEEP144_Servo_MapAngleToTicks(float angle, float minAngle, float maxAngle, uint16_t minTicks, uint16_t maxTicks){
|
||||
// Map the angle value into the tick range using the min and max parameters
|
||||
return (uint16_t)(( ((angle - minAngle) * (maxTicks - minTicks)) / (maxAngle - minAngle) ) + minTicks);
|
||||
}
|
||||
143
YEEP144lib/src/YEEP144_TSOP4838.c
Normal file
143
YEEP144lib/src/YEEP144_TSOP4838.c
Normal file
@@ -0,0 +1,143 @@
|
||||
#include "YEEP144.h"
|
||||
#include "YEEP144_Pinout.h"
|
||||
#include "YEEP144_DebugUART.h"
|
||||
|
||||
#define ASCII_ESC 27
|
||||
|
||||
// NEC Protocol Timing Constants (in microseconds)
|
||||
#define NEC_START_LOW 9000 // 9ms leading pulse
|
||||
#define NEC_START_HIGH 4500 // 4.5ms space
|
||||
#define NEC_BIT_LOW 560 // 560us burst
|
||||
#define NEC_BIT_ONE_HIGH 1690 // 1.69ms space for logical 1
|
||||
#define NEC_BIT_ZERO_HIGH 560 // 560us space for logical 0
|
||||
#define NEC_TOLERANCE 400 // +/- margin of error
|
||||
|
||||
// State Machine States
|
||||
typedef enum{
|
||||
IR_STATE_IDLE,
|
||||
IR_STATE_LEADER,
|
||||
IR_STATE_DATA
|
||||
} IR_State_t;
|
||||
|
||||
// Variables
|
||||
volatile IR_State_t ir_state = IR_STATE_IDLE;
|
||||
volatile uint32_t ir_last_time = 0;
|
||||
volatile uint32_t ir_raw_bits = 0;
|
||||
volatile uint8_t ir_bit_count = 0;
|
||||
volatile uint8_t ir_code_ready = 0;
|
||||
volatile uint32_t ir_code = 0;
|
||||
|
||||
// Enable hardware DWT (Data Watchpoint and Trace) cycle counter
|
||||
void DWT_Init(void) {
|
||||
CoreDebug->DEMCR |= CoreDebug_DEMCR_TRCENA_Msk;
|
||||
DWT->CYCCNT = 0;
|
||||
DWT->CTRL |= DWT_CTRL_CYCCNTENA_Msk;
|
||||
}
|
||||
|
||||
// Arduino-style microsecond measurement
|
||||
uint32_t micros(void) {
|
||||
return DWT->CYCCNT / (SystemCoreClock / 1000000);
|
||||
}
|
||||
|
||||
// This exact function name matches the STM32H563 hardware vector table entry
|
||||
void EXTI3_IRQHandler(void)
|
||||
{
|
||||
// Tells the HAL layer to clear the flag and fire your callback routine
|
||||
HAL_GPIO_EXTI_IRQHandler(IR_RECEIVER_PIN);
|
||||
}
|
||||
|
||||
void YEEP144_TSOP4838_Init(){
|
||||
GPIO_InitTypeDef GPIO_InitStruct = {0};
|
||||
|
||||
// Enable DWT for microsecond timing
|
||||
DWT_Init();
|
||||
|
||||
// Configure Pin F3 for Interrupt on Both Edges
|
||||
GPIO_InitStruct.Pin = IR_RECEIVER_PIN;
|
||||
GPIO_InitStruct.Mode = GPIO_MODE_IT_RISING_FALLING; // Triggers on rising or falling change
|
||||
GPIO_InitStruct.Pull = GPIO_NOPULL; // Uses the TSOP4838 internal pull-up
|
||||
HAL_GPIO_Init(IR_RECEIVER_PORT, &GPIO_InitStruct);
|
||||
|
||||
// Enable and set EXTI Line 3 Vector for STM32H563
|
||||
HAL_NVIC_SetPriority(IR_RECEIVER_EXTI, 2, 0);
|
||||
HAL_NVIC_EnableIRQ(IR_RECEIVER_EXTI);
|
||||
}
|
||||
|
||||
uint8_t YEEP144_TSOP4838_Received(void){
|
||||
return ir_code_ready;
|
||||
}
|
||||
|
||||
uint32_t YEEP144_TSOP4838_Read(void){
|
||||
return ir_code;
|
||||
ir_code_ready = 0;
|
||||
}
|
||||
|
||||
// These functions override the weak HAL geometric EXTI callbacks
|
||||
void HAL_GPIO_EXTI_Rising_Callback(uint16_t GPIO_Pin){
|
||||
if (GPIO_Pin == IR_RECEIVER_PIN)
|
||||
{
|
||||
uint32_t current_time = micros();
|
||||
uint32_t duration = current_time - ir_last_time;
|
||||
ir_last_time = current_time;
|
||||
switch(ir_state) {
|
||||
case IR_STATE_LEADER: // Rising edge (End of 9ms pulse)
|
||||
if (duration < (NEC_START_LOW - NEC_TOLERANCE) || duration > (NEC_START_LOW + NEC_TOLERANCE)){
|
||||
ir_state = IR_STATE_IDLE; // False start
|
||||
}
|
||||
break;
|
||||
case IR_STATE_IDLE:
|
||||
break;
|
||||
case IR_STATE_DATA:
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// For newer STM32 HAL libraries, rising and falling callbacks are separated for memory efficiency
|
||||
void HAL_GPIO_EXTI_Falling_Callback(uint16_t GPIO_Pin){
|
||||
if (GPIO_Pin == IR_RECEIVER_PIN)
|
||||
{
|
||||
uint32_t current_time = micros();
|
||||
uint32_t duration = current_time - ir_last_time;
|
||||
ir_last_time = current_time;
|
||||
switch(ir_state){
|
||||
case IR_STATE_IDLE: // Falling edge (Start of 9ms pulse)
|
||||
ir_state = IR_STATE_LEADER;
|
||||
break;
|
||||
case IR_STATE_LEADER: // Falling edge (End of 4.5ms space)
|
||||
if (duration >= (NEC_START_HIGH - NEC_TOLERANCE) && duration <= (NEC_START_HIGH + NEC_TOLERANCE)){
|
||||
ir_state = IR_STATE_DATA;
|
||||
ir_bit_count = 0;
|
||||
ir_raw_bits = 0;
|
||||
} else {
|
||||
ir_state = IR_STATE_IDLE; // Invalid preamble
|
||||
}
|
||||
break;
|
||||
case IR_STATE_DATA: // Falling edge (End of a data bit's high space)
|
||||
// The high duration determines if the bit is a 0 or a 1
|
||||
if (duration >= (NEC_BIT_ZERO_HIGH - NEC_TOLERANCE) && duration <= (NEC_BIT_ZERO_HIGH + NEC_TOLERANCE)) {
|
||||
ir_raw_bits >>= 1; // It's a 0
|
||||
ir_bit_count++;
|
||||
}
|
||||
else if (duration >= (NEC_BIT_ONE_HIGH - NEC_TOLERANCE) && duration <= (NEC_BIT_ONE_HIGH + NEC_TOLERANCE)) {
|
||||
ir_raw_bits >>= 1;
|
||||
ir_raw_bits |= 0x80000000; // It's a 1
|
||||
ir_bit_count++;
|
||||
}
|
||||
else {
|
||||
ir_state = IR_STATE_IDLE; // Timing error, reset state
|
||||
}
|
||||
|
||||
uint32_t ir_bits = 0;
|
||||
if (ir_bit_count == 32) {
|
||||
ir_bits = ir_raw_bits;
|
||||
ir_code = (ir_bits >> 16) & 0xFF;
|
||||
uint32_t command_inverse = (ir_bits >> 24) & 0xFF;
|
||||
if (ir_code == (uint8_t)(~command_inverse))
|
||||
ir_code_ready = 1;
|
||||
ir_state = IR_STATE_IDLE;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
159
cmake/gnu-tools-for-stm32.cmake
Normal file
159
cmake/gnu-tools-for-stm32.cmake
Normal file
@@ -0,0 +1,159 @@
|
||||
# -----------------------------------------------------------------------------
|
||||
# @author STM32Cube bundle system
|
||||
# -----------------------------------------------------------------------------
|
||||
# @attention
|
||||
#
|
||||
# Copyright (c) 2025 STMicroelectronics.
|
||||
# All rights reserved.
|
||||
#
|
||||
# This software is licensed under terms that can be found in the LICENSE file
|
||||
# in the root directory of this software component.
|
||||
# If no LICENSE file comes with this software, it is provided AS-IS.
|
||||
#
|
||||
# -----------------------------------------------------------------------------
|
||||
|
||||
# This file describes GNU Tools for STM32 Toolchain.
|
||||
#
|
||||
# - Applies to toolchain: GNU Tools for STM32 Toolchain 13.3.1 and greater
|
||||
|
||||
set(CMAKE_SYSTEM_NAME Generic)
|
||||
set(CMAKE_SYSTEM_PROCESSOR arm)
|
||||
|
||||
# Some target device related default GCC settings
|
||||
if(CMSIS_Dcore STREQUAL "Cortex-M0")
|
||||
set(CPU_FLAGS -mcpu=cortex-m0)
|
||||
elseif(CMSIS_Dcore STREQUAL "Cortex-M0+")
|
||||
set(CPU_FLAGS -mcpu=cortex-m0plus)
|
||||
elseif(CMSIS_Dcore STREQUAL "Cortex-M1")
|
||||
set(CPU_FLAGS -mcpu=cortex-m1)
|
||||
elseif(CMSIS_Dcore STREQUAL "Cortex-M3")
|
||||
set(CPU_FLAGS -mcpu=cortex-m3)
|
||||
elseif(CMSIS_Dcore STREQUAL "Cortex-M4")
|
||||
if(CMSIS_Dfpu STREQUAL "SP_FPU")
|
||||
set(CPU_FLAGS -mcpu=cortex-m4 -mfpu=fpv4-sp-d16 -mfloat-abi=hard)
|
||||
else()
|
||||
set(CPU_FLAGS -mcpu=cortex-m4)
|
||||
endif()
|
||||
elseif(CMSIS_Dcore STREQUAL "Cortex-M7")
|
||||
if(CMSIS_Dfpu STREQUAL "DP_FPU")
|
||||
set(CPU_FLAGS -mcpu=cortex-m7 -mfpu=fpv5-d16 -mfloat-abi=hard)
|
||||
elseif(CMSIS_Dfpu STREQUAL "SP_FPU")
|
||||
set(CPU_FLAGS -mcpu=cortex-m7 -mfpu=fpv5-sp-d16 -mfloat-abi=hard)
|
||||
else()
|
||||
set(CPU_FLAGS -mcpu=cortex-m7)
|
||||
endif()
|
||||
elseif(CMSIS_Dcore STREQUAL "Cortex-M23")
|
||||
set(CPU_FLAGS -mcpu=cortex-m23)
|
||||
elseif(CMSIS_Dcore STREQUAL "Cortex-M33")
|
||||
if(CMSIS_Dfpu STREQUAL "SP_FPU")
|
||||
if(CMSIS_Ddsp STREQUAL "DSP")
|
||||
set(CPU_FLAGS -mcpu=cortex-m33 -mfpu=fpv5-sp-d16 -mfloat-abi=hard)
|
||||
else()
|
||||
set(CPU_FLAGS -mcpu=cortex-m33+nodsp -mfpu=fpv5-sp-d16 -mfloat-abi=hard)
|
||||
endif()
|
||||
else()
|
||||
if(CMSIS_Ddsp STREQUAL "DSP")
|
||||
set(CPU_FLAGS -mcpu=cortex-m33)
|
||||
else()
|
||||
set(CPU_FLAGS -mcpu=cortex-m33+nodsp)
|
||||
endif()
|
||||
endif()
|
||||
elseif(CMSIS_Dcore STREQUAL "Cortex-M35P")
|
||||
if(CMSIS_Dfpu STREQUAL "SP_FPU")
|
||||
if(CMSIS_Ddsp STREQUAL "DSP")
|
||||
set(CPU_FLAGS -mcpu=cortex-m35p -mfpu=fpv5-sp-d16 -mfloat-abi=hard)
|
||||
else()
|
||||
set(CPU_FLAGS -mcpu=cortex-m35p+nodsp -mfpu=fpv5-sp-d16 -mfloat-abi=hard)
|
||||
endif()
|
||||
else()
|
||||
if(CMSIS_Ddsp STREQUAL "DSP")
|
||||
set(CPU_FLAGS -mcpu=cortex-m35p)
|
||||
else()
|
||||
set(CPU_FLAGS -mcpu=cortex-m35p+nodsp)
|
||||
endif()
|
||||
endif()
|
||||
elseif(CMSIS_Dcore STREQUAL "Cortex-M55")
|
||||
if(CMSIS_Dfpu STREQUAL "NO_FPU")
|
||||
if(CMSIS_Dmve STREQUAL "NO_MVE")
|
||||
set(CPU_FLAGS -mcpu=cortex-m55+nofp+nomve)
|
||||
else()
|
||||
set(CPU_FLAGS -mcpu=cortex-m55+nofp)
|
||||
endif()
|
||||
else()
|
||||
if(CMSIS_Dmve STREQUAL "NO_MVE")
|
||||
set(CPU_FLAGS -mcpu=cortex-m55+nomve -mfloat-abi=hard)
|
||||
elseif(CMSIS_Dmve STREQUAL "MVE")
|
||||
set(CPU_FLAGS -mcpu=cortex-m55+nomve.fp -mfloat-abi=hard)
|
||||
else()
|
||||
set(CPU_FLAGS -mcpu=cortex-m55 -mfloat-abi=hard)
|
||||
endif()
|
||||
endif()
|
||||
elseif(CMSIS_Dcore STREQUAL "Cortex-M85")
|
||||
if(CMSIS_Dfpu STREQUAL "NO_FPU")
|
||||
if(CMSIS_Dmve STREQUAL "NO_MVE")
|
||||
set(CPU_FLAGS -mcpu=cortex-m85+nofp+nomve)
|
||||
else()
|
||||
set(CPU_FLAGS -mcpu=cortex-m85+nofp)
|
||||
endif()
|
||||
else()
|
||||
if(CMSIS_Dmve STREQUAL "NO_MVE")
|
||||
set(CPU_FLAGS -mcpu=cortex-m85+nomve -mfloat-abi=hard)
|
||||
elseif(CMSIS_Dmve STREQUAL "MVE")
|
||||
set(CPU_FLAGS -mcpu=cortex-m85+nomve.fp -mfloat-abi=hard)
|
||||
else()
|
||||
set(CPU_FLAGS -mcpu=cortex-m85 -mfloat-abi=hard)
|
||||
endif()
|
||||
endif()
|
||||
elseif(CMSIS_Dcore STREQUAL "Cortex-A5")
|
||||
if(CMSIS_Dfpu STREQUAL "DP_FPU")
|
||||
set(CPU_FLAGS -mcpu=cortex-a5+nosimd -mfpu=auto -mfloat-abi=hard)
|
||||
else()
|
||||
set(CPU_FLAGS -mcpu=cortex-a5+nosimd+nofp)
|
||||
endif()
|
||||
elseif(CMSIS_Dcore STREQUAL "Cortex-A7")
|
||||
if(CMSIS_Dfpu STREQUAL "DP_FPU")
|
||||
set(CPU_FLAGS -mcpu=cortex-a7+nosimd -mfpu=auto -mfloat-abi=hard)
|
||||
else()
|
||||
set(CPU_FLAGS -mcpu=Cortex-a7+nosimd+nofp)
|
||||
endif()
|
||||
elseif(CMSIS_Dcore STREQUAL "Cortex-A9")
|
||||
if(CMSIS_Dfpu STREQUAL "DP_FPU")
|
||||
set(CPU_FLAGS -mcpu=cortex-a9+nosimd -mfpu=auto -mfloat-abi=hard)
|
||||
else()
|
||||
set(CPU_FLAGS -mcpu=cortex-a9+nosimd+nofp)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
if(CMSIS_Dendian STREQUAL "Little-endian")
|
||||
set(CPU_FLAGS ${CPU_FLAGS} -mlittle-endian)
|
||||
elseif(CMSIS_Dendian STREQUAL "Big-endian")
|
||||
set(CPU_FLAGS ${CPU_FLAGS} -mbig-endian)
|
||||
endif()
|
||||
|
||||
set(CPU_FLAGS ${CPU_FLAGS} -mthumb)
|
||||
|
||||
# Some C Pre-Processor related default GCC settings
|
||||
if(CMSIS_Dsecure STREQUAL "Secure" OR CMSIS_Dsecure STREQUAL "Secure-only")
|
||||
set(SECURE_FLAGS "-mcmse")
|
||||
endif()
|
||||
|
||||
# Some default GCC settings
|
||||
# arm-none-eabi- must be part of path environment
|
||||
set(TOOLCHAIN_PREFIX arm-none-eabi-)
|
||||
set(FLAGS "-fdata-sections -ffunction-sections -Wl,--gc-sections -Wno-comment")
|
||||
set(CPP_FLAGS "${FLAGS} -fno-rtti -fno-exceptions -fno-threadsafe-statics")
|
||||
|
||||
set(CMAKE_C_FLAGS ${FLAGS})
|
||||
set(CMAKE_CXX_FLAGS ${CPP_FLAGS})
|
||||
|
||||
set(CMAKE_C_COMPILER ${TOOLCHAIN_PREFIX}gcc)
|
||||
set(CMAKE_ASM_COMPILER ${CMAKE_C_COMPILER})
|
||||
set(CMAKE_CXX_COMPILER ${TOOLCHAIN_PREFIX}g++)
|
||||
set(CMAKE_OBJCOPY ${TOOLCHAIN_PREFIX}objcopy)
|
||||
set(CMAKE_SIZE ${TOOLCHAIN_PREFIX}size)
|
||||
|
||||
set(CMAKE_EXECUTABLE_SUFFIX_ASM ".elf")
|
||||
set(CMAKE_EXECUTABLE_SUFFIX_C ".elf")
|
||||
set(CMAKE_EXECUTABLE_SUFFIX_CXX ".elf")
|
||||
|
||||
set(CMAKE_TRY_COMPILE_TARGET_TYPE STATIC_LIBRARY)
|
||||
64
cmake/vscode_generated.cmake
Normal file
64
cmake/vscode_generated.cmake
Normal file
@@ -0,0 +1,64 @@
|
||||
# -----------------------------------------------------------------------------
|
||||
# @author Auto-generated by STM32CubeIDE for Visual Studio Code Extension
|
||||
# -----------------------------------------------------------------------------
|
||||
# @attention
|
||||
#
|
||||
# Copyright (c) 2025 STMicroelectronics.
|
||||
# All rights reserved.
|
||||
#
|
||||
# This software is licensed under terms that can be found in the LICENSE file
|
||||
# in the root directory of this software component.
|
||||
# If no LICENSE file comes with this software, it is provided AS-IS.
|
||||
#
|
||||
# -----------------------------------------------------------------------------
|
||||
|
||||
# This is converter generated file, and shall not be touched by user
|
||||
#
|
||||
# Use CMakeLists.txt to apply user changes
|
||||
cmake_minimum_required(VERSION 3.20)
|
||||
|
||||
# Core MCU flags, CPU, instruction set and FPU setup
|
||||
set(cpu_PARAMS ${CPU_FLAGS} ${cpu_PARAMS})
|
||||
|
||||
# Linker script
|
||||
set(linker_script_SRC ${linker_script_SRC}
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/stm32h563xi_flash.ld
|
||||
)
|
||||
|
||||
# Sources
|
||||
set(sources_SRCS ${sources_SRCS}
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/src/syscall.c
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/src/sysmem.c
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/src/startup_stm32h563xx.S
|
||||
)
|
||||
|
||||
# Include directories
|
||||
set(include_c_DIRS ${include_c_DIRS}
|
||||
)
|
||||
set(include_cxx_DIRS ${include_cxx_DIRS}
|
||||
)
|
||||
set(include_asm_DIRS ${include_asm_DIRS}
|
||||
)
|
||||
|
||||
# Symbols definition
|
||||
set(symbols_c_SYMB ${symbols_c_SYMB}
|
||||
RTE_DEVICE_STARTUP_STM32H5XX
|
||||
)
|
||||
set(symbols_cxx_SYMB ${symbols_cxx_SYMB}
|
||||
)
|
||||
set(symbols_asm_SYMB ${symbols_asm_SYMB}
|
||||
)
|
||||
|
||||
# Link directories
|
||||
set(link_DIRS ${link_DIRS}
|
||||
)
|
||||
|
||||
# Link libraries
|
||||
set(link_LIBS ${link_LIBS}
|
||||
)
|
||||
|
||||
# Compiler options
|
||||
set(compiler_OPTS ${compiler_OPTS} ${SECURE_FLAGS})
|
||||
|
||||
# Linker options
|
||||
set(linker_OPTS ${linker_OPTS})
|
||||
522
include/stm32h5xx_hal_conf.h
Normal file
522
include/stm32h5xx_hal_conf.h
Normal file
@@ -0,0 +1,522 @@
|
||||
/* USER CODE BEGIN Header */
|
||||
/**
|
||||
**********************************************************************************************************************
|
||||
|
||||
* @file stm32h5xx_hal_conf.h
|
||||
* @author MCD Application Team
|
||||
* @brief HAL configuration file.
|
||||
**********************************************************************************************************************
|
||||
|
||||
* @attention
|
||||
*
|
||||
* Copyright (c) 2023 STMicroelectronics.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This software is licensed under terms that can be found in the LICENSE file
|
||||
* in the root directory of this software component.
|
||||
* If no LICENSE file comes with this software, it is provided AS-IS.
|
||||
*
|
||||
**********************************************************************************************************************
|
||||
|
||||
*/
|
||||
/* USER CODE END Header */
|
||||
|
||||
/* Define to prevent recursive inclusion -----------------------------------------------------------------------------*/
|
||||
|
||||
#ifndef STM32H5xx_HAL_CONF_H
|
||||
#define STM32H5xx_HAL_CONF_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/* Exported types ----------------------------------------------------------------------------------------------------*/
|
||||
/* Exported constants ------------------------------------------------------------------------------------------------*/
|
||||
|
||||
/* ########################################### Module Selection ##################################################### */
|
||||
|
||||
/**
|
||||
* @brief This is the list of modules to be used in the HAL driver
|
||||
*/
|
||||
|
||||
#define HAL_MODULE_ENABLED
|
||||
/*#define HAL_CCB_MODULE_ENABLED */
|
||||
#define HAL_ADC_MODULE_ENABLED
|
||||
/*#define HAL_CEC_MODULE_ENABLED */
|
||||
/*#define HAL_COMP_MODULE_ENABLED */
|
||||
/*#define HAL_CORDIC_MODULE_ENABLED */
|
||||
/*#define HAL_CRC_MODULE_ENABLED */
|
||||
/*#define HAL_CRYP_MODULE_ENABLED */
|
||||
/*#define HAL_DAC_MODULE_ENABLED */
|
||||
/*#define HAL_DCACHE_MODULE_ENABLED */
|
||||
/*#define HAL_DCMI_MODULE_ENABLED */
|
||||
/*#define HAL_DTS_MODULE_ENABLED */
|
||||
/*#define HAL_ETH_MODULE_ENABLED */
|
||||
/*#define HAL_FDCAN_MODULE_ENABLED */
|
||||
/*#define HAL_FMAC_MODULE_ENABLED */
|
||||
/*#define HAL_GTZC_MODULE_ENABLED */
|
||||
/*#define HAL_HASH_MODULE_ENABLED */
|
||||
/*#define HAL_HCD_MODULE_ENABLED */
|
||||
/*#define HAL_IRDA_MODULE_ENABLED */
|
||||
/*#define HAL_IWDG_MODULE_ENABLED */
|
||||
#define HAL_I2C_MODULE_ENABLED
|
||||
/*#define HAL_I3C_MODULE_ENABLED */
|
||||
/*#define HAL_I2S_MODULE_ENABLED */
|
||||
#define HAL_LPTIM_MODULE_ENABLED
|
||||
/*#define HAL_NAND_MODULE_ENABLED */
|
||||
/*#define HAL_NOR_MODULE_ENABLED */
|
||||
/*#define HAL_OPAMP_MODULE_ENABLED */
|
||||
/*#define HAL_XSPI_MODULE_ENABLED */
|
||||
/*#define HAL_OTFDEC_MODULE_ENABLED */
|
||||
/*#define HAL_PKA_MODULE_ENABLED */
|
||||
/*#define HAL_RNG_MODULE_ENABLED */
|
||||
/*#define HAL_RTC_MODULE_ENABLED */
|
||||
/*#define HAL_SAI_MODULE_ENABLED */
|
||||
/*#define HAL_SD_MODULE_ENABLED */
|
||||
#define HAL_SDIO_MODULE_ENABLED
|
||||
/*#define HAL_SDRAM_MODULE_ENABLED */
|
||||
/*#define HAL_MMC_MODULE_ENABLED */
|
||||
/*#define HAL_SMARTCARD_MODULE_ENABLED */
|
||||
/*#define HAL_SMBUS_MODULE_ENABLED */
|
||||
#define HAL_SPI_MODULE_ENABLED
|
||||
/*#define HAL_SRAM_MODULE_ENABLED */
|
||||
#define HAL_TIM_MODULE_ENABLED
|
||||
/*#define HAL_RAMCFG_MODULE_ENABLED */
|
||||
#define HAL_UART_MODULE_ENABLED
|
||||
#define HAL_USART_MODULE_ENABLED
|
||||
/*#define HAL_WWDG_MODULE_ENABLED */
|
||||
/*#define HAL_PSSI_MODULE_ENABLED */
|
||||
#define HAL_ICACHE_MODULE_ENABLED
|
||||
/*#define HAL_PCD_MODULE_ENABLED */
|
||||
#define HAL_GPIO_MODULE_ENABLED
|
||||
#define HAL_EXTI_MODULE_ENABLED
|
||||
#define HAL_DMA_MODULE_ENABLED
|
||||
#define HAL_RCC_MODULE_ENABLED
|
||||
#define HAL_FLASH_MODULE_ENABLED
|
||||
#define HAL_PWR_MODULE_ENABLED
|
||||
#define HAL_CORTEX_MODULE_ENABLED
|
||||
|
||||
/* ####################################### Oscillator Values adaptation ##############################################*/
|
||||
|
||||
/**
|
||||
* @brief Adjust the value of External High Speed oscillator (HSE) used in your application.
|
||||
* This value is used by the RCC HAL module to compute the system frequency
|
||||
* (when HSE is used as system clock source, directly or through the PLL).
|
||||
*/
|
||||
#if !defined (HSE_VALUE)
|
||||
#define HSE_VALUE 8000000U /*!< Value of the External oscillator in Hz */
|
||||
#endif /* HSE_VALUE */
|
||||
|
||||
#if !defined (HSE_STARTUP_TIMEOUT)
|
||||
#define HSE_STARTUP_TIMEOUT 100U /*!< Time out for HSE start up, in ms */
|
||||
#endif /* HSE_STARTUP_TIMEOUT */
|
||||
|
||||
/**
|
||||
* @brief Internal Core Speed oscillator (CSI) default value.
|
||||
* This value is the default CSI range value after Reset.
|
||||
*/
|
||||
#if !defined (CSI_VALUE)
|
||||
#define CSI_VALUE 4000000UL /*!< Value of the Internal oscillator in Hz*/
|
||||
#endif /* CSI_VALUE */
|
||||
|
||||
/**
|
||||
* @brief Internal High Speed oscillator (HSI) value.
|
||||
* This value is used by the RCC HAL module to compute the system frequency
|
||||
* (when HSI is used as system clock source, directly or through the PLL).
|
||||
*/
|
||||
#if !defined (HSI_VALUE)
|
||||
#define HSI_VALUE 64000000UL /*!< Value of the Internal oscillator in Hz*/
|
||||
#endif /* HSI_VALUE */
|
||||
|
||||
/**
|
||||
* @brief Internal High Speed oscillator (HSI48) value for USB FS, SDMMC and RNG.
|
||||
* This internal oscillator is mainly dedicated to provide a high precision clock to
|
||||
* the USB peripheral by means of a special Clock Recovery System (CRS) circuitry.
|
||||
* When the CRS is not used, the HSI48 RC oscillator runs on it default frequency
|
||||
* which is subject to manufacturing process variations.
|
||||
*/
|
||||
#if !defined (HSI48_VALUE)
|
||||
#define HSI48_VALUE 48000000UL /*!< Value of the Internal High Speed oscillator for USB FS/SDMMC/RNG in Hz.
|
||||
The real value my vary depending on manufacturing process variations.*/
|
||||
#endif /* HSI48_VALUE */
|
||||
|
||||
/**
|
||||
* @brief Internal Low Speed oscillator (LSI) value.
|
||||
*/
|
||||
#if !defined (LSI_VALUE)
|
||||
#define LSI_VALUE 32000UL /*!< LSI Typical Value in Hz*/
|
||||
#endif /* LSI_VALUE */ /*!< Value of the Internal Low Speed oscillator in Hz
|
||||
The real value may vary depending on the variations
|
||||
in voltage and temperature.*/
|
||||
|
||||
#if !defined (LSI_STARTUP_TIME)
|
||||
#define LSI_STARTUP_TIME 130UL /*!< Time out for LSI start up, in us */
|
||||
#endif /* LSI_STARTUP_TIME */
|
||||
|
||||
/**
|
||||
* @brief External Low Speed oscillator (LSE) value.
|
||||
* This value is used by the UART, RTC HAL module to compute the system frequency
|
||||
*/
|
||||
#if !defined (LSE_VALUE)
|
||||
#define LSE_VALUE 32768UL /*!< Value of the External oscillator in Hz*/
|
||||
#endif /* LSE_VALUE */
|
||||
|
||||
#if !defined (LSE_STARTUP_TIMEOUT)
|
||||
#define LSE_STARTUP_TIMEOUT 5000UL /*!< Time out for LSE start up, in ms */
|
||||
#endif /* LSE_STARTUP_TIMEOUT */
|
||||
/**
|
||||
* @brief External clock source for SPI/SAI peripheral
|
||||
* This value is used by the SPI/SAI HAL module to compute the SPI/SAI clock source
|
||||
* frequency, this source is inserted directly through I2S_CKIN pad.
|
||||
|
||||
*/
|
||||
#if !defined (EXTERNAL_CLOCK_VALUE)
|
||||
#define EXTERNAL_CLOCK_VALUE 12288000UL /*!< Value of the External clock in Hz*/
|
||||
#endif /* EXTERNAL_CLOCK_VALUE */
|
||||
|
||||
/* Tip: To avoid modifying this file each time you need to use different HSE,
|
||||
=== you can define the HSE value in your toolchain compiler preprocessor. */
|
||||
|
||||
/* ############################################ System Configuration ################################################ */
|
||||
|
||||
/**
|
||||
* @brief This is the HAL system configuration section
|
||||
*/
|
||||
|
||||
#define VDD_VALUE 3300UL /*!< Value of VDD in mv */
|
||||
#define TICK_INT_PRIORITY (15UL) /*!< tick interrupt priority (lowest by default) */
|
||||
#define USE_RTOS 0U
|
||||
#define PREFETCH_ENABLE 0U /*!< Enable prefetch */
|
||||
|
||||
/* ############################################ Assert Selection #################################################### */
|
||||
|
||||
/**
|
||||
* @brief Uncomment the line below to expanse the "assert_param" macro in the
|
||||
* HAL drivers code
|
||||
*/
|
||||
|
||||
/* #define USE_FULL_ASSERT 1U */
|
||||
|
||||
/* ############################################ Register callback feature configuration ############################# */
|
||||
|
||||
/**
|
||||
* @brief Set below the peripheral configuration to "1U" to add the support
|
||||
* of HAL callback registration/unregistration feature for the HAL
|
||||
* driver(s). This allows user application to provide specific callback
|
||||
* functions thanks to HAL_PPP_RegisterCallback() rather than overwriting
|
||||
* the default weak callback functions (see each stm32h5xx_hal_ppp.h file
|
||||
* for possible callback identifiers defined in HAL_PPP_CallbackIDTypeDef
|
||||
* for each PPP peripheral).
|
||||
*/
|
||||
#define USE_HAL_ADC_REGISTER_CALLBACKS 0U /* ADC register callback disabled */
|
||||
#define USE_HAL_CCB_REGISTER_CALLBACKS 0U /* CCB register callback disabled */
|
||||
#define USE_HAL_CEC_REGISTER_CALLBACKS 0U /* CEC register callback disabled */
|
||||
#define USE_HAL_COMP_REGISTER_CALLBACKS 0U /* COMP register callback disabled */
|
||||
#define USE_HAL_CORDIC_REGISTER_CALLBACKS 0U /* CORDIC register callback disabled */
|
||||
#define USE_HAL_CRYP_REGISTER_CALLBACKS 0U /* CRYP register callback disabled */
|
||||
#define USE_HAL_DAC_REGISTER_CALLBACKS 0U /* DAC register callback disabled */
|
||||
#define USE_HAL_DCMI_REGISTER_CALLBACKS 0U /* DCMI register callback disabled */
|
||||
#define USE_HAL_DTS_REGISTER_CALLBACKS 0U /* DTS register callback disabled */
|
||||
#define USE_HAL_ETH_REGISTER_CALLBACKS 0U /* ETH register callback disabled */
|
||||
#define USE_HAL_FDCAN_REGISTER_CALLBACKS 0U /* FDCAN register callback disabled */
|
||||
#define USE_HAL_FMAC_REGISTER_CALLBACKS 0U /* FMAC register callback disabled */
|
||||
#define USE_HAL_NOR_REGISTER_CALLBACKS 0U /* NOR register callback disabled */
|
||||
#define USE_HAL_HASH_REGISTER_CALLBACKS 0U /* HASH register callback disabled */
|
||||
#define USE_HAL_HCD_REGISTER_CALLBACKS 0U /* HCD register callback disabled */
|
||||
#define USE_HAL_I2C_REGISTER_CALLBACKS 0U /* I2C register callback disabled */
|
||||
#define USE_HAL_I2S_REGISTER_CALLBACKS 0U /* I2S register callback disabled */
|
||||
#define USE_HAL_I3C_REGISTER_CALLBACKS 0U /* I3C register callback disabled */
|
||||
#define USE_HAL_IRDA_REGISTER_CALLBACKS 0U /* IRDA register callback disabled */
|
||||
#define USE_HAL_IWDG_REGISTER_CALLBACKS 0U /* IWDG register callback disabled */
|
||||
#define USE_HAL_LPTIM_REGISTER_CALLBACKS 0U /* LPTIM register callback disabled */
|
||||
#define USE_HAL_MMC_REGISTER_CALLBACKS 0U /* MMC register callback disabled */
|
||||
#define USE_HAL_NAND_REGISTER_CALLBACKS 0U /* NAND register callback disabled */
|
||||
#define USE_HAL_OPAMP_REGISTER_CALLBACKS 0U /* OPAMP register callback disabled */
|
||||
#define USE_HAL_OTFDEC_REGISTER_CALLBACKS 0U /* OTFDEC register callback disabled */
|
||||
#define USE_HAL_PCD_REGISTER_CALLBACKS 0U /* PCD register callback disabled */
|
||||
#define USE_HAL_PKA_REGISTER_CALLBACKS 0U /* PKA register callback disabled */
|
||||
#define USE_HAL_RAMCFG_REGISTER_CALLBACKS 0U /* RAMCFG register callback disabled */
|
||||
#define USE_HAL_RNG_REGISTER_CALLBACKS 0U /* RNG register callback disabled */
|
||||
#define USE_HAL_RTC_REGISTER_CALLBACKS 0U /* RTC register callback disabled */
|
||||
#define USE_HAL_SAI_REGISTER_CALLBACKS 0U /* SAI register callback disabled */
|
||||
#define USE_HAL_SD_REGISTER_CALLBACKS 0U /* SD register callback disabled */
|
||||
#define USE_HAL_SDIO_REGISTER_CALLBACKS 0U /* SDIO register callback disabled */
|
||||
#define USE_HAL_SDRAM_REGISTER_CALLBACKS 0U /* SDRAM register callback disabled */
|
||||
#define USE_HAL_SMARTCARD_REGISTER_CALLBACKS 0U /* SMARTCARD register callback disabled */
|
||||
#define USE_HAL_SMBUS_REGISTER_CALLBACKS 0U /* SMBUS register callback disabled */
|
||||
#define USE_HAL_SPI_REGISTER_CALLBACKS 0U /* SPI register callback disabled */
|
||||
#define USE_HAL_SRAM_REGISTER_CALLBACKS 0U /* SRAM register callback disabled */
|
||||
#define USE_HAL_TIM_REGISTER_CALLBACKS 0U /* TIM register callback disabled */
|
||||
#define USE_HAL_UART_REGISTER_CALLBACKS 0U /* UART register callback disabled */
|
||||
#define USE_HAL_USART_REGISTER_CALLBACKS 0U /* USART register callback disabled */
|
||||
#define USE_HAL_WWDG_REGISTER_CALLBACKS 0U /* WWDG register callback disabled */
|
||||
#define USE_HAL_XSPI_REGISTER_CALLBACKS 0U /* XSPI register callback disabled */
|
||||
|
||||
/* ############################################ SPI peripheral configuration ######################################## */
|
||||
|
||||
/* CRC FEATURE: Use to activate CRC feature inside HAL SPI Driver
|
||||
* Activated: CRC code is present inside driver
|
||||
* Deactivated: CRC code cleaned from driver
|
||||
*/
|
||||
#define USE_SPI_CRC 0U
|
||||
|
||||
/* ################## SDMMC peripheral configuration ######################### */
|
||||
|
||||
#define USE_SD_TRANSCEIVER 0U
|
||||
|
||||
/* ################## SDIO peripheral configuration ######################### */
|
||||
|
||||
#define USE_SDIO_TRANSCEIVER 0U
|
||||
#define SDIO_MAX_IO_NUMBER 7U
|
||||
|
||||
/* Includes ----------------------------------------------------------------------------------------------------------*/
|
||||
|
||||
/**
|
||||
* @brief Include module's header file
|
||||
*/
|
||||
|
||||
#ifdef HAL_RCC_MODULE_ENABLED
|
||||
#include "stm32h5xx_hal_rcc.h"
|
||||
#endif /* HAL_RCC_MODULE_ENABLED */
|
||||
|
||||
#ifdef HAL_GPIO_MODULE_ENABLED
|
||||
#include "stm32h5xx_hal_gpio.h"
|
||||
#endif /* HAL_GPIO_MODULE_ENABLED */
|
||||
|
||||
#ifdef HAL_ICACHE_MODULE_ENABLED
|
||||
#include "stm32h5xx_hal_icache.h"
|
||||
#endif /* HAL_ICACHE_MODULE_ENABLED */
|
||||
|
||||
#ifdef HAL_DCACHE_MODULE_ENABLED
|
||||
#include "stm32h5xx_hal_dcache.h"
|
||||
#endif /* HAL_DCACHE_MODULE_ENABLED */
|
||||
|
||||
#ifdef HAL_GTZC_MODULE_ENABLED
|
||||
#include "stm32h5xx_hal_gtzc.h"
|
||||
#endif /* HAL_GTZC_MODULE_ENABLED */
|
||||
|
||||
#ifdef HAL_DMA_MODULE_ENABLED
|
||||
#include "stm32h5xx_hal_dma.h"
|
||||
#endif /* HAL_DMA_MODULE_ENABLED */
|
||||
|
||||
#ifdef HAL_DTS_MODULE_ENABLED
|
||||
#include "stm32h5xx_hal_dts.h"
|
||||
#endif /* HAL_DTS_MODULE_ENABLED */
|
||||
|
||||
#ifdef HAL_CORTEX_MODULE_ENABLED
|
||||
#include "stm32h5xx_hal_cortex.h"
|
||||
#endif /* HAL_CORTEX_MODULE_ENABLED */
|
||||
|
||||
#ifdef HAL_PKA_MODULE_ENABLED
|
||||
#include "stm32h5xx_hal_pka.h"
|
||||
#endif /* HAL_PKA_MODULE_ENABLED */
|
||||
|
||||
#ifdef HAL_ADC_MODULE_ENABLED
|
||||
#include "stm32h5xx_hal_adc.h"
|
||||
#endif /* HAL_ADC_MODULE_ENABLED */
|
||||
|
||||
#ifdef HAL_CRC_MODULE_ENABLED
|
||||
#include "stm32h5xx_hal_crc.h"
|
||||
#endif /* HAL_CRC_MODULE_ENABLED */
|
||||
|
||||
#ifdef HAL_CRYP_MODULE_ENABLED
|
||||
#include "stm32h5xx_hal_cryp.h"
|
||||
#endif /* HAL_CRYP_MODULE_ENABLED */
|
||||
|
||||
#ifdef HAL_DAC_MODULE_ENABLED
|
||||
#include "stm32h5xx_hal_dac.h"
|
||||
#endif /* HAL_DAC_MODULE_ENABLED */
|
||||
|
||||
#ifdef HAL_FLASH_MODULE_ENABLED
|
||||
#include "stm32h5xx_hal_flash.h"
|
||||
#endif /* HAL_FLASH_MODULE_ENABLED */
|
||||
|
||||
#ifdef HAL_HASH_MODULE_ENABLED
|
||||
#include "stm32h5xx_hal_hash.h"
|
||||
#endif /* HAL_HASH_MODULE_ENABLED */
|
||||
|
||||
#ifdef HAL_SRAM_MODULE_ENABLED
|
||||
#include "stm32h5xx_hal_sram.h"
|
||||
#endif /* HAL_SRAM_MODULE_ENABLED */
|
||||
|
||||
#ifdef HAL_SDRAM_MODULE_ENABLED
|
||||
#include "stm32h5xx_hal_sdram.h"
|
||||
#endif /* HAL_SDRAM_MODULE_ENABLED */
|
||||
|
||||
#ifdef HAL_SDIO_MODULE_ENABLED
|
||||
#include "stm32h5xx_hal_sdio.h"
|
||||
#endif /* HAL_SDIO_MODULE_ENABLED */
|
||||
|
||||
#ifdef HAL_MMC_MODULE_ENABLED
|
||||
#include "stm32h5xx_hal_mmc.h"
|
||||
#endif /* HAL_MMC_MODULE_ENABLED */
|
||||
|
||||
#ifdef HAL_NOR_MODULE_ENABLED
|
||||
#include "stm32h5xx_hal_nor.h"
|
||||
#endif /* HAL_NOR_MODULE_ENABLED */
|
||||
|
||||
#ifdef HAL_NAND_MODULE_ENABLED
|
||||
#include "stm32h5xx_hal_nand.h"
|
||||
#endif /* HAL_NAND_MODULE_ENABLED */
|
||||
|
||||
#ifdef HAL_I2C_MODULE_ENABLED
|
||||
#include "stm32h5xx_hal_i2c.h"
|
||||
#endif /* HAL_I2C_MODULE_ENABLED */
|
||||
|
||||
#ifdef HAL_I2S_MODULE_ENABLED
|
||||
#include "stm32h5xx_hal_i2s.h"
|
||||
#endif /* HAL_I2S_MODULE_ENABLED */
|
||||
|
||||
#ifdef HAL_I3C_MODULE_ENABLED
|
||||
#include "stm32h5xx_hal_i3c.h"
|
||||
#endif /* HAL_I3C_MODULE_ENABLED */
|
||||
|
||||
#ifdef HAL_IWDG_MODULE_ENABLED
|
||||
#include "stm32h5xx_hal_iwdg.h"
|
||||
#endif /* HAL_IWDG_MODULE_ENABLED */
|
||||
|
||||
#ifdef HAL_LPTIM_MODULE_ENABLED
|
||||
#include "stm32h5xx_hal_lptim.h"
|
||||
#endif /* HAL_LPTIM_MODULE_ENABLED */
|
||||
|
||||
#ifdef HAL_PWR_MODULE_ENABLED
|
||||
#include "stm32h5xx_hal_pwr.h"
|
||||
#endif /* HAL_PWR_MODULE_ENABLED */
|
||||
|
||||
#ifdef HAL_XSPI_MODULE_ENABLED
|
||||
#include "stm32h5xx_hal_xspi.h"
|
||||
#endif /* HAL_XSPI_MODULE_ENABLED */
|
||||
|
||||
#ifdef HAL_RNG_MODULE_ENABLED
|
||||
#include "stm32h5xx_hal_rng.h"
|
||||
#endif /* HAL_RNG_MODULE_ENABLED */
|
||||
|
||||
#ifdef HAL_RTC_MODULE_ENABLED
|
||||
#include "stm32h5xx_hal_rtc.h"
|
||||
#endif /* HAL_RTC_MODULE_ENABLED */
|
||||
|
||||
#ifdef HAL_SAI_MODULE_ENABLED
|
||||
#include "stm32h5xx_hal_sai.h"
|
||||
#endif /* HAL_SAI_MODULE_ENABLED */
|
||||
|
||||
#ifdef HAL_SD_MODULE_ENABLED
|
||||
#include "stm32h5xx_hal_sd.h"
|
||||
#endif /* HAL_SD_MODULE_ENABLED */
|
||||
|
||||
#ifdef HAL_SMBUS_MODULE_ENABLED
|
||||
#include "stm32h5xx_hal_smbus.h"
|
||||
#endif /* HAL_SMBUS_MODULE_ENABLED */
|
||||
|
||||
#ifdef HAL_SPI_MODULE_ENABLED
|
||||
#include "stm32h5xx_hal_spi.h"
|
||||
#endif /* HAL_SPI_MODULE_ENABLED */
|
||||
|
||||
#ifdef HAL_TIM_MODULE_ENABLED
|
||||
#include "stm32h5xx_hal_tim.h"
|
||||
#endif /* HAL_TIM_MODULE_ENABLED */
|
||||
|
||||
#ifdef HAL_UART_MODULE_ENABLED
|
||||
#include "stm32h5xx_hal_uart.h"
|
||||
#endif /* HAL_UART_MODULE_ENABLED */
|
||||
|
||||
#ifdef HAL_USART_MODULE_ENABLED
|
||||
#include "stm32h5xx_hal_usart.h"
|
||||
#endif /* HAL_USART_MODULE_ENABLED */
|
||||
|
||||
#ifdef HAL_IRDA_MODULE_ENABLED
|
||||
#include "stm32h5xx_hal_irda.h"
|
||||
#endif /* HAL_IRDA_MODULE_ENABLED */
|
||||
|
||||
#ifdef HAL_SMARTCARD_MODULE_ENABLED
|
||||
#include "stm32h5xx_hal_smartcard.h"
|
||||
#endif /* HAL_SMARTCARD_MODULE_ENABLED */
|
||||
|
||||
#ifdef HAL_WWDG_MODULE_ENABLED
|
||||
#include "stm32h5xx_hal_wwdg.h"
|
||||
#endif /* HAL_WWDG_MODULE_ENABLED */
|
||||
|
||||
#ifdef HAL_PCD_MODULE_ENABLED
|
||||
#include "stm32h5xx_hal_pcd.h"
|
||||
#endif /* HAL_PCD_MODULE_ENABLED */
|
||||
|
||||
#ifdef HAL_CCB_MODULE_ENABLED
|
||||
#include "stm32h5xx_hal_ccb.h"
|
||||
#endif /* HAL_CCB_MODULE_ENABLED */
|
||||
|
||||
#ifdef HAL_HCD_MODULE_ENABLED
|
||||
#include "stm32h5xx_hal_hcd.h"
|
||||
#endif /* HAL_HCD_MODULE_ENABLED */
|
||||
|
||||
#ifdef HAL_COMP_MODULE_ENABLED
|
||||
#include "stm32h5xx_hal_comp.h"
|
||||
#endif /* HAL_COMP_MODULE_ENABLED */
|
||||
|
||||
#ifdef HAL_CORDIC_MODULE_ENABLED
|
||||
#include "stm32h5xx_hal_cordic.h"
|
||||
#endif /* HAL_CORDIC_MODULE_ENABLED */
|
||||
|
||||
#ifdef HAL_DCMI_MODULE_ENABLED
|
||||
#include "stm32h5xx_hal_dcmi.h"
|
||||
#endif /* HAL_DCMI_MODULE_ENABLED */
|
||||
|
||||
#ifdef HAL_EXTI_MODULE_ENABLED
|
||||
#include "stm32h5xx_hal_exti.h"
|
||||
#endif /* HAL_EXTI_MODULE_ENABLED */
|
||||
|
||||
#ifdef HAL_ETH_MODULE_ENABLED
|
||||
#include "stm32h5xx_hal_eth.h"
|
||||
#endif /* HAL_ETH_MODULE_ENABLED */
|
||||
|
||||
#ifdef HAL_FDCAN_MODULE_ENABLED
|
||||
#include "stm32h5xx_hal_fdcan.h"
|
||||
#endif /* HAL_FDCAN_MODULE_ENABLED */
|
||||
|
||||
#ifdef HAL_CEC_MODULE_ENABLED
|
||||
#include "stm32h5xx_hal_cec.h"
|
||||
#endif /* HAL_CEC_MODULE_ENABLED */
|
||||
|
||||
#ifdef HAL_FMAC_MODULE_ENABLED
|
||||
#include "stm32h5xx_hal_fmac.h"
|
||||
#endif /* HAL_FMAC_MODULE_ENABLED */
|
||||
|
||||
#ifdef HAL_OPAMP_MODULE_ENABLED
|
||||
#include "stm32h5xx_hal_opamp.h"
|
||||
#endif /* HAL_OPAMP_MODULE_ENABLED */
|
||||
|
||||
#ifdef HAL_OTFDEC_MODULE_ENABLED
|
||||
#include "stm32h5xx_hal_otfdec.h"
|
||||
#endif /* HAL_OTFDEC_MODULE_ENABLED */
|
||||
|
||||
#ifdef HAL_PSSI_MODULE_ENABLED
|
||||
#include "stm32h5xx_hal_pssi.h"
|
||||
#endif /* HAL_PSSI_MODULE_ENABLED */
|
||||
|
||||
#ifdef HAL_RAMCFG_MODULE_ENABLED
|
||||
#include "stm32h5xx_hal_ramcfg.h"
|
||||
#endif /* HAL_RAMCFG_MODULE_ENABLED */
|
||||
|
||||
/* Exported macro ----------------------------------------------------------------------------------------------------*/
|
||||
|
||||
#ifdef USE_FULL_ASSERT
|
||||
/**
|
||||
* @brief The assert_param macro is used for function's parameters check.
|
||||
* @param expr: If expr is false, it calls assert_failed function
|
||||
* which reports the name of the source file and the source
|
||||
* line number of the call that failed.
|
||||
* If expr is true, it returns no value.
|
||||
* @retval None
|
||||
*/
|
||||
#define assert_param(expr) ((expr) ? (void)0U : assert_failed((uint8_t *)__FILE__, __LINE__))
|
||||
/* Exported functions ----------------------------------------------------------------------------------------------- */
|
||||
|
||||
void assert_failed(uint8_t *file, uint32_t line);
|
||||
#else
|
||||
#define assert_param(expr) ((void)0U)
|
||||
#endif /* USE_FULL_ASSERT */
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* STM32H5xx_HAL_CONF_H */
|
||||
|
||||
67
include/stm32h5xx_it.h
Normal file
67
include/stm32h5xx_it.h
Normal file
@@ -0,0 +1,67 @@
|
||||
/* USER CODE BEGIN Header */
|
||||
/**
|
||||
******************************************************************************
|
||||
* @file stm32h5xx_it.h
|
||||
* @brief This file contains the headers of the interrupt handlers.
|
||||
******************************************************************************
|
||||
* @attention
|
||||
*
|
||||
* Copyright (c) 2026 STMicroelectronics.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This software is licensed under terms that can be found in the LICENSE file
|
||||
* in the root directory of this software component.
|
||||
* If no LICENSE file comes with this software, it is provided AS-IS.
|
||||
*
|
||||
******************************************************************************
|
||||
*/
|
||||
/* USER CODE END Header */
|
||||
|
||||
/* Define to prevent recursive inclusion -------------------------------------*/
|
||||
#ifndef __STM32H5xx_IT_H
|
||||
#define __STM32H5xx_IT_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/* Private includes ----------------------------------------------------------*/
|
||||
/* USER CODE BEGIN Includes */
|
||||
|
||||
/* USER CODE END Includes */
|
||||
|
||||
/* Exported types ------------------------------------------------------------*/
|
||||
/* USER CODE BEGIN ET */
|
||||
|
||||
/* USER CODE END ET */
|
||||
|
||||
/* Exported constants --------------------------------------------------------*/
|
||||
/* USER CODE BEGIN EC */
|
||||
|
||||
/* USER CODE END EC */
|
||||
|
||||
/* Exported macro ------------------------------------------------------------*/
|
||||
/* USER CODE BEGIN EM */
|
||||
|
||||
/* USER CODE END EM */
|
||||
|
||||
/* Exported functions prototypes ---------------------------------------------*/
|
||||
void NMI_Handler(void);
|
||||
void HardFault_Handler(void);
|
||||
void MemManage_Handler(void);
|
||||
void BusFault_Handler(void);
|
||||
void UsageFault_Handler(void);
|
||||
void SVC_Handler(void);
|
||||
void DebugMon_Handler(void);
|
||||
void PendSV_Handler(void);
|
||||
void SysTick_Handler(void);
|
||||
void EXTI13_IRQHandler(void);
|
||||
/* USER CODE BEGIN EFP */
|
||||
|
||||
/* USER CODE END EFP */
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* __STM32H5xx_IT_H */
|
||||
77
include/stm32h5xx_nucleo_conf.h
Normal file
77
include/stm32h5xx_nucleo_conf.h
Normal file
@@ -0,0 +1,77 @@
|
||||
|
||||
/**
|
||||
******************************************************************************
|
||||
* @file stm32h5xx_nucleo_conf.h
|
||||
* @author MCD Application Team
|
||||
* @brief STM32H5xx_Nucleo board configuration file.
|
||||
******************************************************************************
|
||||
* @attention
|
||||
*
|
||||
* Copyright (c) 2023 STMicroelectronics.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This software is licensed under terms that can be found in the LICENSE file
|
||||
* in the root directory of this software component.
|
||||
* If no LICENSE file comes with this software, it is provided AS-IS.
|
||||
*
|
||||
******************************************************************************
|
||||
*/
|
||||
|
||||
/* Define to prevent recursive inclusion -------------------------------------*/
|
||||
#ifndef STM32H5XX_NUCLEO_CONF_H
|
||||
#define STM32H5XX_NUCLEO_CONF_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/* Includes ------------------------------------------------------------------*/
|
||||
#include "stm32h5xx_hal.h"
|
||||
|
||||
/** @addtogroup BSP
|
||||
* @{
|
||||
*/
|
||||
|
||||
/** @addtogroup STM32H5XX_NUCLEO
|
||||
* @{
|
||||
*/
|
||||
|
||||
/** @defgroup STM32H5XX_NUCLEO_CONFIG Config
|
||||
* @{
|
||||
*/
|
||||
|
||||
/** @defgroup STM32H5XX_NUCLEO_CONFIG_Exported_Constants Exported Constants
|
||||
* @{
|
||||
*/
|
||||
/* Nucleo pin and part number defines */
|
||||
#define USE_NUCLEO_144
|
||||
/* #define USE_NUCLEO_64 */
|
||||
|
||||
/* COM define */
|
||||
#define USE_COM_LOG 1U
|
||||
#define USE_BSP_COM_FEATURE 1U
|
||||
|
||||
/* IRQ priorities */
|
||||
#define BSP_BUTTON_USER_IT_PRIORITY 15U
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* STM32H5XX_NUCLEO_CONF_H */
|
||||
7
src/main.c
Normal file
7
src/main.c
Normal file
@@ -0,0 +1,7 @@
|
||||
#include "YEEP144.h"
|
||||
#include "stm32h563xx.h"
|
||||
#include "stm32h5xx_hal.h"
|
||||
|
||||
int main(void){
|
||||
|
||||
}
|
||||
683
src/startup_stm32h563xx.S
Normal file
683
src/startup_stm32h563xx.S
Normal file
@@ -0,0 +1,683 @@
|
||||
/**
|
||||
******************************************************************************
|
||||
* @brief STM32H563xx device vector table for GCC toolchain.
|
||||
* This module performs:
|
||||
* - Set the initial SP
|
||||
* - Set the initial PC == Reset_Handler,
|
||||
* - Set the vector table entries with the exceptions ISR address
|
||||
* - Branches to main in the C library (which eventually
|
||||
* calls main()).
|
||||
******************************************************************************
|
||||
* @attention
|
||||
*
|
||||
* Copyright (c) 2026 STMicroelectronics.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This software is licensed under terms that can be found in the LICENSE file
|
||||
* in the root directory of this software component.
|
||||
* If no LICENSE file comes with this software, it is provided AS-IS.
|
||||
*
|
||||
******************************************************************************
|
||||
*/
|
||||
|
||||
.syntax unified
|
||||
.cpu cortex-m33
|
||||
.fpu softvfp
|
||||
.thumb
|
||||
|
||||
.global g_pfnVectors
|
||||
.global Default_Handler
|
||||
|
||||
/* start address for the initialization values of the .data section.
|
||||
defined in linker script */
|
||||
.word _sidata
|
||||
/* start address for the .data section. defined in linker script */
|
||||
.word _sdata
|
||||
/* end address for the .data section. defined in linker script */
|
||||
.word _edata
|
||||
/* start address for the .bss section. defined in linker script */
|
||||
.word _sbss
|
||||
/* end address for the .bss section. defined in linker script */
|
||||
.word _ebss
|
||||
|
||||
/**
|
||||
* @brief This is the code that gets called when the processor first
|
||||
* starts execution following a reset event. Only the absolutely
|
||||
* necessary set is performed, after which the application
|
||||
* supplied main() routine is called.
|
||||
* @param None
|
||||
* @retval : None
|
||||
*/
|
||||
|
||||
.section .text.Reset_Handler
|
||||
.weak Reset_Handler
|
||||
.type Reset_Handler, %function
|
||||
Reset_Handler:
|
||||
ldr sp, =_estack /* set stack pointer */
|
||||
ldr r0, =_sstack
|
||||
msr MSPLIM, r0 /* set stack pointer limit */
|
||||
/* Call the clock system initialization function.*/
|
||||
bl SystemInit
|
||||
|
||||
/* Copy the data segment initializers from flash to SRAM */
|
||||
ldr r0, =_sdata
|
||||
ldr r1, =_edata
|
||||
ldr r2, =_sidata
|
||||
movs r3, #0
|
||||
b LoopCopyDataInit
|
||||
|
||||
CopyDataInit:
|
||||
ldr r4, [r2, r3]
|
||||
str r4, [r0, r3]
|
||||
adds r3, r3, #4
|
||||
|
||||
LoopCopyDataInit:
|
||||
adds r4, r0, r3
|
||||
cmp r4, r1
|
||||
bcc CopyDataInit
|
||||
|
||||
/* Zero fill the bss segment. */
|
||||
ldr r2, =_sbss
|
||||
ldr r4, =_ebss
|
||||
movs r3, #0
|
||||
b LoopFillZerobss
|
||||
|
||||
FillZerobss:
|
||||
str r3, [r2]
|
||||
adds r2, r2, #4
|
||||
|
||||
LoopFillZerobss:
|
||||
cmp r2, r4
|
||||
bcc FillZerobss
|
||||
|
||||
/* Call static constructors */
|
||||
bl __libc_init_array
|
||||
/* Call the application's entry point.*/
|
||||
bl main
|
||||
|
||||
LoopForever:
|
||||
b LoopForever
|
||||
|
||||
.size Reset_Handler, .-Reset_Handler
|
||||
|
||||
/**
|
||||
* @brief This is the code that gets called when the processor receives an
|
||||
* unexpected interrupt. This simply enters an infinite loop, preserving
|
||||
* the system state for examination by a debugger.
|
||||
*
|
||||
* @param None
|
||||
* @retval : None
|
||||
*/
|
||||
.section .text.Default_Handler,"ax",%progbits
|
||||
Default_Handler:
|
||||
Infinite_Loop:
|
||||
b Infinite_Loop
|
||||
.size Default_Handler, .-Default_Handler
|
||||
|
||||
/******************************************************************************
|
||||
*
|
||||
* The STM32H563xx vector table. Note that the proper constructs
|
||||
* must be placed on this to ensure that it ends up at physical address
|
||||
* 0x0000.0000.
|
||||
*
|
||||
******************************************************************************/
|
||||
.section .isr_vector,"a",%progbits
|
||||
.type g_pfnVectors, %object
|
||||
|
||||
g_pfnVectors:
|
||||
.word _estack
|
||||
.word Reset_Handler
|
||||
.word NMI_Handler
|
||||
.word HardFault_Handler
|
||||
.word MemManage_Handler
|
||||
.word BusFault_Handler
|
||||
.word UsageFault_Handler
|
||||
.word SecureFault_Handler
|
||||
.word 0
|
||||
.word 0
|
||||
.word 0
|
||||
.word SVC_Handler
|
||||
.word DebugMon_Handler
|
||||
.word 0
|
||||
.word PendSV_Handler
|
||||
.word SysTick_Handler
|
||||
.word WWDG_IRQHandler /* Window Watchdog interrupt */
|
||||
.word 0 /* Reserved */
|
||||
.word 0 /* Reserved */
|
||||
.word 0 /* Reserved */
|
||||
.word TAMP_IRQHandler /* TAMP global interrupt */
|
||||
.word RAMCFG_IRQHandler /* RAM configuration global interrupt */
|
||||
.word FLASH_IRQHandler /* FLASH non-secure global interrupt */
|
||||
.word FLASH_S_IRQHandler /* FLASH secure global interrupt */
|
||||
.word GTZC_IRQHandler /* GTZC global interrupt */
|
||||
.word RCC_IRQHandler /* RCC non-secure global interrupt */
|
||||
.word RCC_S_IRQHandler /* RCC secure global interrupt */
|
||||
.word EXTI0_IRQHandler /* EXTI Line0 interrupt */
|
||||
.word EXTI1_IRQHandler /* EXTI Line1 interrupt */
|
||||
.word EXTI2_IRQHandler /* EXTI Line2 interrupt */
|
||||
.word EXTI3_IRQHandler /* EXTI Line3 interrupt */
|
||||
.word EXTI4_IRQHandler /* EXTI Line4 interrupt */
|
||||
.word EXTI5_IRQHandler /* EXTI Line5 interrupt */
|
||||
.word EXTI6_IRQHandler /* EXTI Line6 interrupt */
|
||||
.word EXTI7_IRQHandler /* EXTI Line7 interrupt */
|
||||
.word EXTI8_IRQHandler /* EXTI Line8 interrupt */
|
||||
.word EXTI9_IRQHandler /* EXTI Line9 interrupt */
|
||||
.word EXTI10_IRQHandler /* EXTI Line10 interrupt */
|
||||
.word EXTI11_IRQHandler /* EXTI Line11 interrupt */
|
||||
.word EXTI12_IRQHandler /* EXTI Line12 interrupt */
|
||||
.word EXTI13_IRQHandler /* EXTI Line13 interrupt */
|
||||
.word EXTI14_IRQHandler /* EXTI Line14 interrupt */
|
||||
.word EXTI15_IRQHandler /* EXTI Line15 interrupt */
|
||||
.word GPDMA1_CH0_IRQHandler /* GPDMA1 channel 0 global interrupt */
|
||||
.word GPDMA1_CH1_IRQHandler /* GPDMA1 channel 1 global interrupt */
|
||||
.word GPDMA1_CH2_IRQHandler /* GPDMA1 channel 2 global interrupt */
|
||||
.word GPDMA1_CH3_IRQHandler /* GPDMA1 channel 3 global interrupt */
|
||||
.word GPDMA1_CH4_IRQHandler /* GPDMA1 channel 4 global interrupt */
|
||||
.word GPDMA1_CH5_IRQHandler /* GPDMA1 channel 5 global interrupt */
|
||||
.word GPDMA1_CH6_IRQHandler /* GPDMA1 channel 6 global interrupt */
|
||||
.word GPDMA1_CH7_IRQHandler /* GPDMA1 channel 7 global interrupt */
|
||||
.word IWDG_IRQHandler /* IWDG interrupt */
|
||||
.word 0 /* Reserved */
|
||||
.word ADC1_IRQHandler /* ADC1 global interrupt */
|
||||
.word DAC1_IRQHandler /* DAC1 global interrupt */
|
||||
.word FDCAN1_IT0_IRQHandler /* FDCAN1 interrupt 0 */
|
||||
.word FDCAN1_IT1_IRQHandler /* FDCAN1 interrupt 1 */
|
||||
.word TIM1_BRK_TERR_IERR_IRQHandler /* TIM1 break/TIM1 transition error/TIM1 index error */
|
||||
.word TIM1_UP_IRQHandler /* TIM1 Update */
|
||||
.word TIM1_TRG_COM_DIR_IDX_IRQHandler /* TIM1 trigger and commutation/TIM1 direction change interrupt/TIM1 index */
|
||||
.word TIM1_CC_IRQHandler /* TIM1 capture compare interrupt */
|
||||
.word TIM2_IRQHandler /* TIM2 global interrupt */
|
||||
.word TIM3_IRQHandler /* TIM3 global interrupt */
|
||||
.word TIM4_IRQHandler /* TIM4 global interrupt */
|
||||
.word TIM5_IRQHandler /* TIM5 global interrupt */
|
||||
.word TIM6_IRQHandler /* TIM6 global interrupt */
|
||||
.word TIM7_IRQHandler /* TIM7 global interrupt */
|
||||
.word I2C1_EV_IRQHandler /* I2C1 event interrupt */
|
||||
.word I2C1_ER_IRQHandler /* I2C1 error interrupt */
|
||||
.word I2C2_EV_IRQHandler /* I2C2 event interrupt */
|
||||
.word I2C2_ER_IRQHandler /* I2C2 error interrupt */
|
||||
.word SPI1_IRQHandler /* SPI1 global interrupt */
|
||||
.word SPI2_IRQHandler /* SPI2 global interrupt */
|
||||
.word SPI3_IRQHandler /* SPI3 global interrupt */
|
||||
.word USART1_IRQHandler /* USART1 global interrupt */
|
||||
.word USART2_IRQHandler /* USART2 global interrupt */
|
||||
.word USART3_IRQHandler /* USART3 global interrupt */
|
||||
.word UART4_IRQHandler /* UART4 global interrupt */
|
||||
.word UART5_IRQHandler /* UART5 global interrupt */
|
||||
.word LPUART1_IRQHandler /* LPUART1 global interrupt */
|
||||
.word LPTIM1_IRQHandler /* LPTIM1 global interrupt */
|
||||
.word IM8_BRK_TERR_IERR_IRQHandler /* TIM8 break interrupt/TIM8 transition error/TIM8 index error */
|
||||
.word TIM8_UP_IRQHandler /* TIM8 update interrupt */
|
||||
.word TIM8_TRG_COM_DIR_IDX_IRQHandler /* TIM8 trigger and commutation interrupt/TIM8 direction change interrupt/TIM8 index */
|
||||
.word TIM8_CC_IRQHandler /* TIM8 capture compare interrupt */
|
||||
.word ADC2_IRQHandler /* ADC2 global interrupt */
|
||||
.word LPTIM2_IRQHandler /* LPTIM2 global interrupt */
|
||||
.word TIM15_IRQHandler /* TIM5 global interrupt */
|
||||
.word TIM16_IRQHandler /* TIM6 global interrupt */
|
||||
.word TIM17_IRQHandler /* TIM17 global interrupt */
|
||||
.word USB_FS_IRQHandler /* USB OTG FS global interrupt */
|
||||
.word CRS_IRQHandler /* Clock Recovery System global interrupt */
|
||||
.word UCPD1_IRQHandler /* UCPD1 global interrupt */
|
||||
.word FMC_IRQHandler /* FMC global interrupt */
|
||||
.word OCTOSPI1_IRQHandler /* OCTOSPI1 global interrupt */
|
||||
.word SDMMC1_IRQHandler /* SDMMC1 global interrupt */
|
||||
.word I2C3_EV_IRQHandler /* I2C3 event interrupt */
|
||||
.word I2C3_ER_IRQHandler /* I2C3 error interrupt */
|
||||
.word SPI4_IRQHandler /* SPI4 global interrupt */
|
||||
.word SPI5_IRQHandler /* SPI5 global interrupt */
|
||||
.word SPI6_IRQHandler /* SPI6 global interrupt */
|
||||
.word USART6_IRQHandler /* USART6 global interrupt */
|
||||
.word USART10_IRQHandler /* USART10 global interrupt */
|
||||
.word USART11_IRQHandler /* USART11 global interrupt */
|
||||
.word SAI1_IRQHandler /* SAI1 global interrupt */
|
||||
.word SAI2_IRQHandler /* SAI2 global interrupt */
|
||||
.word GPDMA2_CH0_IRQHandler /* GPDMA2 channel 0 global interrupt */
|
||||
.word GPDMA2_CH1_IRQHandler /* GPDMA2 channel 1 global interrupt */
|
||||
.word GPDMA2_CH2_IRQHandler /* GPDMA2 channel 2 global interrupt */
|
||||
.word GPDMA2_CH3_IRQHandler /* GPDMA2 channel 3 global interrupt */
|
||||
.word GPDMA2_CH4_IRQHandler /* GPDMA2 channel 4 global interrupt */
|
||||
.word GPDMA2_CH5_IRQHandler /* GPDMA2 channel 5 global interrupt */
|
||||
.word GPDMA2_CH6_IRQHandler /* GPDMA2 channel 6 global interrupt */
|
||||
.word GPDMA2_CH7_IRQHandler /* GPDMA2 channel 7 global interrupt */
|
||||
.word UART7_IRQHandler /* UART7 global interrupt */
|
||||
.word UART8_IRQHandler /* UART8 global interrupt */
|
||||
.word UART9_IRQHandler /* UART9 global interrupt */
|
||||
.word UART12_IRQHandler /* UART12 global interrupt */
|
||||
.word SDMMC2_IRQHandler /* SDMMC2 global interrupt */
|
||||
.word 0 /* Reserved */
|
||||
.word ICACHE_IRQHandler /* Instruction cache global interrupt */
|
||||
.word DCACHE_IRQHandler /* Data cache global interrupt */
|
||||
.word ETH_IRQHandler /* ETH interrupt */
|
||||
.word ETH_WKUP_IRQHandler /* ETHERNET wakeup interrupt through EXTI line */
|
||||
.word DCMI_PSSI_IRQHandler /* DCMI/PSSI global interrupt */
|
||||
.word FDCAN2_IT0_IRQHandler /* FDCAN2 interrupt 0 */
|
||||
.word FDCAN2_IT1_IRQHandler /* FDCAN2 interrupt 1 */
|
||||
.word Cordic_IRQHandler /* Cordic interrupt */
|
||||
.word FMAC_IRQHandler /* FMAC interrupt */
|
||||
.word DTS_WKUP_IRQHandler /* DTS interrupt or DTS AIT through EXTI line */
|
||||
.word RNG_IRQHandler /* RNG global interrupt */
|
||||
.word 0 /* Reserved */
|
||||
.word 0 /* Reserved */
|
||||
.word HASH_IRQHandler /* HASH interrupt */
|
||||
.word 0 /* Reserved */
|
||||
.word 0 /* Reserved */
|
||||
.word TIM12_IRQHandler /* TIM12 global interrupt */
|
||||
.word TIM13_IRQHandler /* TIM13 global interrupt */
|
||||
.word TIM14_IRQHandler /* TIM14 global interrupt */
|
||||
.word I3C1_EV_IRQHandler /* I3C1 event interrupt */
|
||||
.word I3C1_ER_IRQHandler /* I3C1 error interrupt */
|
||||
.word I2C4_EV_IRQHandler /* I2C4 event interrupt */
|
||||
.word I2C4_ER_IRQHandler /* I2C4 error interrupt */
|
||||
.word LPTIM3_IRQHandler /* LPTIM3 global interrupt */
|
||||
.word LPTIM4_IRQHandler /* LPTIM4 global interrupt */
|
||||
.word LPTIM5_IRQHandler /* LPTIM5 global interrupt */
|
||||
.word LPTIM6_IRQHandler /* LPTIM6 global interrupt */
|
||||
.size g_pfnVectors, .-g_pfnVectors
|
||||
|
||||
/*******************************************************************************
|
||||
*
|
||||
* Provide weak aliases for each Exception handler to the Default_Handler.
|
||||
* As they are weak aliases, any function with the same name will override
|
||||
* this definition.
|
||||
*
|
||||
*******************************************************************************/
|
||||
|
||||
.weak NMI_Handler
|
||||
.thumb_set NMI_Handler,Default_Handler
|
||||
|
||||
.weak HardFault_Handler
|
||||
.thumb_set HardFault_Handler,Default_Handler
|
||||
|
||||
.weak MemManage_Handler
|
||||
.thumb_set MemManage_Handler,Default_Handler
|
||||
|
||||
.weak BusFault_Handler
|
||||
.thumb_set BusFault_Handler,Default_Handler
|
||||
|
||||
.weak UsageFault_Handler
|
||||
.thumb_set UsageFault_Handler,Default_Handler
|
||||
|
||||
.weak SecureFault_Handler
|
||||
.thumb_set SecureFault_Handler,Default_Handler
|
||||
|
||||
.weak SVC_Handler
|
||||
.thumb_set SVC_Handler,Default_Handler
|
||||
|
||||
.weak DebugMon_Handler
|
||||
.thumb_set DebugMon_Handler,Default_Handler
|
||||
|
||||
.weak PendSV_Handler
|
||||
.thumb_set PendSV_Handler,Default_Handler
|
||||
|
||||
.weak SysTick_Handler
|
||||
.thumb_set SysTick_Handler,Default_Handler
|
||||
|
||||
.weak WWDG_IRQHandler
|
||||
.thumb_set WWDG_IRQHandler,Default_Handler
|
||||
|
||||
.weak TAMP_IRQHandler
|
||||
.thumb_set TAMP_IRQHandler,Default_Handler
|
||||
|
||||
.weak RAMCFG_IRQHandler
|
||||
.thumb_set RAMCFG_IRQHandler,Default_Handler
|
||||
|
||||
.weak FLASH_IRQHandler
|
||||
.thumb_set FLASH_IRQHandler,Default_Handler
|
||||
|
||||
.weak FLASH_S_IRQHandler
|
||||
.thumb_set FLASH_S_IRQHandler,Default_Handler
|
||||
|
||||
.weak GTZC_IRQHandler
|
||||
.thumb_set GTZC_IRQHandler,Default_Handler
|
||||
|
||||
.weak RCC_IRQHandler
|
||||
.thumb_set RCC_IRQHandler,Default_Handler
|
||||
|
||||
.weak RCC_S_IRQHandler
|
||||
.thumb_set RCC_S_IRQHandler,Default_Handler
|
||||
|
||||
.weak EXTI0_IRQHandler
|
||||
.thumb_set EXTI0_IRQHandler,Default_Handler
|
||||
|
||||
.weak EXTI1_IRQHandler
|
||||
.thumb_set EXTI1_IRQHandler,Default_Handler
|
||||
|
||||
.weak EXTI2_IRQHandler
|
||||
.thumb_set EXTI2_IRQHandler,Default_Handler
|
||||
|
||||
.weak EXTI3_IRQHandler
|
||||
.thumb_set EXTI3_IRQHandler,Default_Handler
|
||||
|
||||
.weak EXTI4_IRQHandler
|
||||
.thumb_set EXTI4_IRQHandler,Default_Handler
|
||||
|
||||
.weak EXTI5_IRQHandler
|
||||
.thumb_set EXTI5_IRQHandler,Default_Handler
|
||||
|
||||
.weak EXTI6_IRQHandler
|
||||
.thumb_set EXTI6_IRQHandler,Default_Handler
|
||||
|
||||
.weak EXTI7_IRQHandler
|
||||
.thumb_set EXTI7_IRQHandler,Default_Handler
|
||||
|
||||
.weak EXTI8_IRQHandler
|
||||
.thumb_set EXTI8_IRQHandler,Default_Handler
|
||||
|
||||
.weak EXTI9_IRQHandler
|
||||
.thumb_set EXTI9_IRQHandler,Default_Handler
|
||||
|
||||
.weak EXTI10_IRQHandler
|
||||
.thumb_set EXTI10_IRQHandler,Default_Handler
|
||||
|
||||
.weak EXTI11_IRQHandler
|
||||
.thumb_set EXTI11_IRQHandler,Default_Handler
|
||||
|
||||
.weak EXTI12_IRQHandler
|
||||
.thumb_set EXTI12_IRQHandler,Default_Handler
|
||||
|
||||
.weak EXTI13_IRQHandler
|
||||
.thumb_set EXTI13_IRQHandler,Default_Handler
|
||||
|
||||
.weak EXTI14_IRQHandler
|
||||
.thumb_set EXTI14_IRQHandler,Default_Handler
|
||||
|
||||
.weak EXTI15_IRQHandler
|
||||
.thumb_set EXTI15_IRQHandler,Default_Handler
|
||||
|
||||
.weak GPDMA1_CH0_IRQHandler
|
||||
.thumb_set GPDMA1_CH0_IRQHandler,Default_Handler
|
||||
|
||||
.weak GPDMA1_CH1_IRQHandler
|
||||
.thumb_set GPDMA1_CH1_IRQHandler,Default_Handler
|
||||
|
||||
.weak GPDMA1_CH2_IRQHandler
|
||||
.thumb_set GPDMA1_CH2_IRQHandler,Default_Handler
|
||||
|
||||
.weak GPDMA1_CH3_IRQHandler
|
||||
.thumb_set GPDMA1_CH3_IRQHandler,Default_Handler
|
||||
|
||||
.weak GPDMA1_CH4_IRQHandler
|
||||
.thumb_set GPDMA1_CH4_IRQHandler,Default_Handler
|
||||
|
||||
.weak GPDMA1_CH5_IRQHandler
|
||||
.thumb_set GPDMA1_CH5_IRQHandler,Default_Handler
|
||||
|
||||
.weak GPDMA1_CH6_IRQHandler
|
||||
.thumb_set GPDMA1_CH6_IRQHandler,Default_Handler
|
||||
|
||||
.weak GPDMA1_CH7_IRQHandler
|
||||
.thumb_set GPDMA1_CH7_IRQHandler,Default_Handler
|
||||
|
||||
.weak IWDG_IRQHandler
|
||||
.thumb_set IWDG_IRQHandler,Default_Handler
|
||||
|
||||
.weak ADC1_IRQHandler
|
||||
.thumb_set ADC1_IRQHandler,Default_Handler
|
||||
|
||||
.weak DAC1_IRQHandler
|
||||
.thumb_set DAC1_IRQHandler,Default_Handler
|
||||
|
||||
.weak FDCAN1_IT0_IRQHandler
|
||||
.thumb_set FDCAN1_IT0_IRQHandler,Default_Handler
|
||||
|
||||
.weak FDCAN1_IT1_IRQHandler
|
||||
.thumb_set FDCAN1_IT1_IRQHandler,Default_Handler
|
||||
|
||||
.weak TIM1_BRK_TERR_IERR_IRQHandler
|
||||
.thumb_set TIM1_BRK_TERR_IERR_IRQHandler,Default_Handler
|
||||
|
||||
.weak TIM1_UP_IRQHandler
|
||||
.thumb_set TIM1_UP_IRQHandler,Default_Handler
|
||||
|
||||
.weak TIM1_TRG_COM_DIR_IDX_IRQHandler
|
||||
.thumb_set TIM1_TRG_COM_DIR_IDX_IRQHandler,Default_Handler
|
||||
|
||||
.weak TIM1_CC_IRQHandler
|
||||
.thumb_set TIM1_CC_IRQHandler,Default_Handler
|
||||
|
||||
.weak TIM2_IRQHandler
|
||||
.thumb_set TIM2_IRQHandler,Default_Handler
|
||||
|
||||
.weak TIM3_IRQHandler
|
||||
.thumb_set TIM3_IRQHandler,Default_Handler
|
||||
|
||||
.weak TIM4_IRQHandler
|
||||
.thumb_set TIM4_IRQHandler,Default_Handler
|
||||
|
||||
.weak TIM5_IRQHandler
|
||||
.thumb_set TIM5_IRQHandler,Default_Handler
|
||||
|
||||
.weak TIM6_IRQHandler
|
||||
.thumb_set TIM6_IRQHandler,Default_Handler
|
||||
|
||||
.weak TIM7_IRQHandler
|
||||
.thumb_set TIM7_IRQHandler,Default_Handler
|
||||
|
||||
.weak I2C1_EV_IRQHandler
|
||||
.thumb_set I2C1_EV_IRQHandler,Default_Handler
|
||||
|
||||
.weak I2C1_ER_IRQHandler
|
||||
.thumb_set I2C1_ER_IRQHandler,Default_Handler
|
||||
|
||||
.weak I2C2_EV_IRQHandler
|
||||
.thumb_set I2C2_EV_IRQHandler,Default_Handler
|
||||
|
||||
.weak I2C2_ER_IRQHandler
|
||||
.thumb_set I2C2_ER_IRQHandler,Default_Handler
|
||||
|
||||
.weak SPI1_IRQHandler
|
||||
.thumb_set SPI1_IRQHandler,Default_Handler
|
||||
|
||||
.weak SPI2_IRQHandler
|
||||
.thumb_set SPI2_IRQHandler,Default_Handler
|
||||
|
||||
.weak SPI3_IRQHandler
|
||||
.thumb_set SPI3_IRQHandler,Default_Handler
|
||||
|
||||
.weak USART1_IRQHandler
|
||||
.thumb_set USART1_IRQHandler,Default_Handler
|
||||
|
||||
.weak USART2_IRQHandler
|
||||
.thumb_set USART2_IRQHandler,Default_Handler
|
||||
|
||||
.weak USART3_IRQHandler
|
||||
.thumb_set USART3_IRQHandler,Default_Handler
|
||||
|
||||
.weak UART4_IRQHandler
|
||||
.thumb_set UART4_IRQHandler,Default_Handler
|
||||
|
||||
.weak UART5_IRQHandler
|
||||
.thumb_set UART5_IRQHandler,Default_Handler
|
||||
|
||||
.weak LPUART1_IRQHandler
|
||||
.thumb_set LPUART1_IRQHandler,Default_Handler
|
||||
|
||||
.weak LPTIM1_IRQHandler
|
||||
.thumb_set LPTIM1_IRQHandler,Default_Handler
|
||||
|
||||
.weak IM8_BRK_TERR_IERR_IRQHandler
|
||||
.thumb_set IM8_BRK_TERR_IERR_IRQHandler,Default_Handler
|
||||
|
||||
.weak TIM8_UP_IRQHandler
|
||||
.thumb_set TIM8_UP_IRQHandler,Default_Handler
|
||||
|
||||
.weak TIM8_TRG_COM_DIR_IDX_IRQHandler
|
||||
.thumb_set TIM8_TRG_COM_DIR_IDX_IRQHandler,Default_Handler
|
||||
|
||||
.weak TIM8_CC_IRQHandler
|
||||
.thumb_set TIM8_CC_IRQHandler,Default_Handler
|
||||
|
||||
.weak ADC2_IRQHandler
|
||||
.thumb_set ADC2_IRQHandler,Default_Handler
|
||||
|
||||
.weak LPTIM2_IRQHandler
|
||||
.thumb_set LPTIM2_IRQHandler,Default_Handler
|
||||
|
||||
.weak TIM15_IRQHandler
|
||||
.thumb_set TIM15_IRQHandler,Default_Handler
|
||||
|
||||
.weak TIM16_IRQHandler
|
||||
.thumb_set TIM16_IRQHandler,Default_Handler
|
||||
|
||||
.weak TIM17_IRQHandler
|
||||
.thumb_set TIM17_IRQHandler,Default_Handler
|
||||
|
||||
.weak USB_FS_IRQHandler
|
||||
.thumb_set USB_FS_IRQHandler,Default_Handler
|
||||
|
||||
.weak CRS_IRQHandler
|
||||
.thumb_set CRS_IRQHandler,Default_Handler
|
||||
|
||||
.weak UCPD1_IRQHandler
|
||||
.thumb_set UCPD1_IRQHandler,Default_Handler
|
||||
|
||||
.weak FMC_IRQHandler
|
||||
.thumb_set FMC_IRQHandler,Default_Handler
|
||||
|
||||
.weak OCTOSPI1_IRQHandler
|
||||
.thumb_set OCTOSPI1_IRQHandler,Default_Handler
|
||||
|
||||
.weak SDMMC1_IRQHandler
|
||||
.thumb_set SDMMC1_IRQHandler,Default_Handler
|
||||
|
||||
.weak I2C3_EV_IRQHandler
|
||||
.thumb_set I2C3_EV_IRQHandler,Default_Handler
|
||||
|
||||
.weak I2C3_ER_IRQHandler
|
||||
.thumb_set I2C3_ER_IRQHandler,Default_Handler
|
||||
|
||||
.weak SPI4_IRQHandler
|
||||
.thumb_set SPI4_IRQHandler,Default_Handler
|
||||
|
||||
.weak SPI5_IRQHandler
|
||||
.thumb_set SPI5_IRQHandler,Default_Handler
|
||||
|
||||
.weak SPI6_IRQHandler
|
||||
.thumb_set SPI6_IRQHandler,Default_Handler
|
||||
|
||||
.weak USART6_IRQHandler
|
||||
.thumb_set USART6_IRQHandler,Default_Handler
|
||||
|
||||
.weak USART10_IRQHandler
|
||||
.thumb_set USART10_IRQHandler,Default_Handler
|
||||
|
||||
.weak USART11_IRQHandler
|
||||
.thumb_set USART11_IRQHandler,Default_Handler
|
||||
|
||||
.weak SAI1_IRQHandler
|
||||
.thumb_set SAI1_IRQHandler,Default_Handler
|
||||
|
||||
.weak SAI2_IRQHandler
|
||||
.thumb_set SAI2_IRQHandler,Default_Handler
|
||||
|
||||
.weak GPDMA2_CH0_IRQHandler
|
||||
.thumb_set GPDMA2_CH0_IRQHandler,Default_Handler
|
||||
|
||||
.weak GPDMA2_CH1_IRQHandler
|
||||
.thumb_set GPDMA2_CH1_IRQHandler,Default_Handler
|
||||
|
||||
.weak GPDMA2_CH2_IRQHandler
|
||||
.thumb_set GPDMA2_CH2_IRQHandler,Default_Handler
|
||||
|
||||
.weak GPDMA2_CH3_IRQHandler
|
||||
.thumb_set GPDMA2_CH3_IRQHandler,Default_Handler
|
||||
|
||||
.weak GPDMA2_CH4_IRQHandler
|
||||
.thumb_set GPDMA2_CH4_IRQHandler,Default_Handler
|
||||
|
||||
.weak GPDMA2_CH5_IRQHandler
|
||||
.thumb_set GPDMA2_CH5_IRQHandler,Default_Handler
|
||||
|
||||
.weak GPDMA2_CH6_IRQHandler
|
||||
.thumb_set GPDMA2_CH6_IRQHandler,Default_Handler
|
||||
|
||||
.weak GPDMA2_CH7_IRQHandler
|
||||
.thumb_set GPDMA2_CH7_IRQHandler,Default_Handler
|
||||
|
||||
.weak UART7_IRQHandler
|
||||
.thumb_set UART7_IRQHandler,Default_Handler
|
||||
|
||||
.weak UART8_IRQHandler
|
||||
.thumb_set UART8_IRQHandler,Default_Handler
|
||||
|
||||
.weak UART9_IRQHandler
|
||||
.thumb_set UART9_IRQHandler,Default_Handler
|
||||
|
||||
.weak UART12_IRQHandler
|
||||
.thumb_set UART12_IRQHandler,Default_Handler
|
||||
|
||||
.weak SDMMC2_IRQHandler
|
||||
.thumb_set SDMMC2_IRQHandler,Default_Handler
|
||||
|
||||
.weak ICACHE_IRQHandler
|
||||
.thumb_set ICACHE_IRQHandler,Default_Handler
|
||||
|
||||
.weak DCACHE_IRQHandler
|
||||
.thumb_set DCACHE_IRQHandler,Default_Handler
|
||||
|
||||
.weak ETH_IRQHandler
|
||||
.thumb_set ETH_IRQHandler,Default_Handler
|
||||
|
||||
.weak ETH_WKUP_IRQHandler
|
||||
.thumb_set ETH_WKUP_IRQHandler,Default_Handler
|
||||
|
||||
.weak DCMI_PSSI_IRQHandler
|
||||
.thumb_set DCMI_PSSI_IRQHandler,Default_Handler
|
||||
|
||||
.weak FDCAN2_IT0_IRQHandler
|
||||
.thumb_set FDCAN2_IT0_IRQHandler,Default_Handler
|
||||
|
||||
.weak FDCAN2_IT1_IRQHandler
|
||||
.thumb_set FDCAN2_IT1_IRQHandler,Default_Handler
|
||||
|
||||
.weak Cordic_IRQHandler
|
||||
.thumb_set Cordic_IRQHandler,Default_Handler
|
||||
|
||||
.weak FMAC_IRQHandler
|
||||
.thumb_set FMAC_IRQHandler,Default_Handler
|
||||
|
||||
.weak DTS_WKUP_IRQHandler
|
||||
.thumb_set DTS_WKUP_IRQHandler,Default_Handler
|
||||
|
||||
.weak RNG_IRQHandler
|
||||
.thumb_set RNG_IRQHandler,Default_Handler
|
||||
|
||||
.weak HASH_IRQHandler
|
||||
.thumb_set HASH_IRQHandler,Default_Handler
|
||||
|
||||
.weak TIM12_IRQHandler
|
||||
.thumb_set TIM12_IRQHandler,Default_Handler
|
||||
|
||||
.weak TIM13_IRQHandler
|
||||
.thumb_set TIM13_IRQHandler,Default_Handler
|
||||
|
||||
.weak TIM14_IRQHandler
|
||||
.thumb_set TIM14_IRQHandler,Default_Handler
|
||||
|
||||
.weak I3C1_EV_IRQHandler
|
||||
.thumb_set I3C1_EV_IRQHandler,Default_Handler
|
||||
|
||||
.weak I3C1_ER_IRQHandler
|
||||
.thumb_set I3C1_ER_IRQHandler,Default_Handler
|
||||
|
||||
.weak I2C4_EV_IRQHandler
|
||||
.thumb_set I2C4_EV_IRQHandler,Default_Handler
|
||||
|
||||
.weak I2C4_ER_IRQHandler
|
||||
.thumb_set I2C4_ER_IRQHandler,Default_Handler
|
||||
|
||||
.weak LPTIM3_IRQHandler
|
||||
.thumb_set LPTIM3_IRQHandler,Default_Handler
|
||||
|
||||
.weak LPTIM4_IRQHandler
|
||||
.thumb_set LPTIM4_IRQHandler,Default_Handler
|
||||
|
||||
.weak LPTIM5_IRQHandler
|
||||
.thumb_set LPTIM5_IRQHandler,Default_Handler
|
||||
|
||||
.weak LPTIM6_IRQHandler
|
||||
.thumb_set LPTIM6_IRQHandler,Default_Handler
|
||||
|
||||
.weak SystemInit
|
||||
|
||||
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
|
||||
244
src/syscall.c
Normal file
244
src/syscall.c
Normal file
@@ -0,0 +1,244 @@
|
||||
/**
|
||||
******************************************************************************
|
||||
* @file syscalls.c
|
||||
* @author Auto-generated by STM32CubeIDE for Visual Studio Code Extension
|
||||
* @brief Minimal System calls file
|
||||
*
|
||||
* For more information about which c-functions
|
||||
* need which of these lowlevel functions
|
||||
* please consult the Newlib or Picolibc libc-manual
|
||||
******************************************************************************
|
||||
* @attention
|
||||
*
|
||||
* Copyright (c) 2025 STMicroelectronics.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This software is licensed under terms that can be found in the LICENSE file
|
||||
* in the root directory of this software component.
|
||||
* If no LICENSE file comes with this software, it is provided AS-IS.
|
||||
*
|
||||
******************************************************************************
|
||||
*/
|
||||
|
||||
/* Includes */
|
||||
#include <sys/stat.h>
|
||||
#include <stdlib.h>
|
||||
#include <errno.h>
|
||||
#include <stdio.h>
|
||||
#include <signal.h>
|
||||
#include <time.h>
|
||||
#include <sys/time.h>
|
||||
#include <sys/times.h>
|
||||
|
||||
|
||||
/* Variables */
|
||||
extern int __io_putchar(int ch) __attribute__((weak));
|
||||
extern int __io_getchar(void) __attribute__((weak));
|
||||
|
||||
|
||||
char *__env[1] = { 0 };
|
||||
char **environ = __env;
|
||||
|
||||
|
||||
/* Functions */
|
||||
void initialise_monitor_handles(void)
|
||||
{
|
||||
}
|
||||
|
||||
int _getpid(void)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
int _kill(int pid, int sig)
|
||||
{
|
||||
(void)pid;
|
||||
(void)sig;
|
||||
errno = EINVAL;
|
||||
return -1;
|
||||
}
|
||||
|
||||
void _exit (int status)
|
||||
{
|
||||
_kill(status, -1);
|
||||
while (1) {} /* Make sure we hang here */
|
||||
}
|
||||
|
||||
__attribute__((weak)) int _read(int file, char *ptr, int len)
|
||||
{
|
||||
(void)file;
|
||||
int DataIdx;
|
||||
|
||||
for (DataIdx = 0; DataIdx < len; DataIdx++)
|
||||
{
|
||||
*ptr++ = __io_getchar();
|
||||
}
|
||||
|
||||
return len;
|
||||
}
|
||||
|
||||
__attribute__((weak)) int _write(int file, char *ptr, int len)
|
||||
{
|
||||
(void)file;
|
||||
int DataIdx;
|
||||
|
||||
for (DataIdx = 0; DataIdx < len; DataIdx++)
|
||||
{
|
||||
__io_putchar(*ptr++);
|
||||
}
|
||||
return len;
|
||||
}
|
||||
|
||||
int _close(int file)
|
||||
{
|
||||
(void)file;
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
int _fstat(int file, struct stat *st)
|
||||
{
|
||||
(void)file;
|
||||
st->st_mode = S_IFCHR;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int _isatty(int file)
|
||||
{
|
||||
(void)file;
|
||||
return 1;
|
||||
}
|
||||
|
||||
int _lseek(int file, int ptr, int dir)
|
||||
{
|
||||
(void)file;
|
||||
(void)ptr;
|
||||
(void)dir;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int _open(char *path, int flags, ...)
|
||||
{
|
||||
(void)path;
|
||||
(void)flags;
|
||||
/* Pretend like we always fail */
|
||||
return -1;
|
||||
}
|
||||
|
||||
int _wait(int *status)
|
||||
{
|
||||
(void)status;
|
||||
errno = ECHILD;
|
||||
return -1;
|
||||
}
|
||||
|
||||
int _unlink(char *name)
|
||||
{
|
||||
(void)name;
|
||||
errno = ENOENT;
|
||||
return -1;
|
||||
}
|
||||
|
||||
clock_t _times(struct tms *buf)
|
||||
{
|
||||
(void)buf;
|
||||
return -1;
|
||||
}
|
||||
|
||||
int _stat(const char *file, struct stat *st)
|
||||
{
|
||||
(void)file;
|
||||
st->st_mode = S_IFCHR;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int _link(char *old, char *new)
|
||||
{
|
||||
(void)old;
|
||||
(void)new;
|
||||
errno = EMLINK;
|
||||
return -1;
|
||||
}
|
||||
|
||||
int _fork(void)
|
||||
{
|
||||
errno = EAGAIN;
|
||||
return -1;
|
||||
}
|
||||
|
||||
int _execve(char *name, char **argv, char **env)
|
||||
{
|
||||
(void)name;
|
||||
(void)argv;
|
||||
(void)env;
|
||||
errno = ENOMEM;
|
||||
return -1;
|
||||
}
|
||||
|
||||
// --- Picolibc Specific Section ---
|
||||
#if defined(__PICOLIBC__)
|
||||
|
||||
/**
|
||||
* @brief Picolibc helper function to output a character to a FILE stream.
|
||||
* This redirects the output to the low-level __io_putchar function.
|
||||
* @param c Character to write.
|
||||
* @param file FILE stream pointer (ignored).
|
||||
* @retval int The character written.
|
||||
*/
|
||||
static int starm_putc(char c, FILE *file)
|
||||
{
|
||||
(void) file;
|
||||
__io_putchar(c);
|
||||
return c;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Picolibc helper function to input a character from a FILE stream.
|
||||
* This redirects the input from the low-level __io_getchar function.
|
||||
* @param file FILE stream pointer (ignored).
|
||||
* @retval int The character read, cast to an unsigned char then int.
|
||||
*/
|
||||
static int starm_getc(FILE *file)
|
||||
{
|
||||
unsigned char c;
|
||||
(void) file;
|
||||
c = __io_getchar();
|
||||
return c;
|
||||
}
|
||||
|
||||
// Define and initialize the standard I/O streams for Picolibc.
|
||||
// FDEV_SETUP_STREAM connects the starm_putc and starm_getc helper functions to a FILE structure.
|
||||
// _FDEV_SETUP_RW indicates the stream is for reading and writing.
|
||||
static FILE __stdio = FDEV_SETUP_STREAM(starm_putc,
|
||||
starm_getc,
|
||||
NULL,
|
||||
_FDEV_SETUP_RW);
|
||||
|
||||
// Assign the standard stream pointers (stdin, stdout, stderr) to the initialized stream.
|
||||
// Picolibc uses these pointers for standard I/O operations (printf, scanf, etc.).
|
||||
FILE *const stdin = &__stdio;
|
||||
__strong_reference(stdin, stdout);
|
||||
__strong_reference(stdin, stderr);
|
||||
|
||||
// Create strong aliases mapping standard C library function names (without underscore)
|
||||
// to the implemented system call stubs (with underscore). Picolibc uses these
|
||||
// standard names internally, so this linking is required.
|
||||
__strong_reference(_read, read);
|
||||
__strong_reference(_write, write);
|
||||
__strong_reference(_times, times);
|
||||
__strong_reference(_execve, execve);
|
||||
__strong_reference(_fork, fork);
|
||||
__strong_reference(_link, link);
|
||||
__strong_reference(_unlink, unlink);
|
||||
__strong_reference(_stat, stat);
|
||||
__strong_reference(_wait, wait);
|
||||
__strong_reference(_open, open);
|
||||
__strong_reference(_close, close);
|
||||
__strong_reference(_lseek, lseek);
|
||||
__strong_reference(_isatty, isatty);
|
||||
__strong_reference(_fstat, fstat);
|
||||
__strong_reference(_exit, exit);
|
||||
__strong_reference(_kill, kill);
|
||||
__strong_reference(_getpid, getpid);
|
||||
|
||||
#endif //__PICOLIBC__
|
||||
87
src/sysmem.c
Normal file
87
src/sysmem.c
Normal file
@@ -0,0 +1,87 @@
|
||||
/**
|
||||
******************************************************************************
|
||||
* @file sysmem.c
|
||||
* @author Auto-generated by STM32CubeIDE for Visual Studio Code Extension
|
||||
* @brief GCC System Memory calls file
|
||||
*
|
||||
* For more information about which C functions
|
||||
* need which of these lowlevel functions
|
||||
* please consult the Newlib or Picolibc libc manual
|
||||
******************************************************************************
|
||||
* @attention
|
||||
*
|
||||
* Copyright (c) 2025 STMicroelectronics.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This software is licensed under terms that can be found in the LICENSE file
|
||||
* in the root directory of this software component.
|
||||
* If no LICENSE file comes with this software, it is provided AS-IS.
|
||||
*
|
||||
******************************************************************************
|
||||
*/
|
||||
|
||||
/* Includes */
|
||||
#include <errno.h>
|
||||
#include <stdint.h>
|
||||
#include <stddef.h>
|
||||
|
||||
/**
|
||||
* Pointer to the current high watermark of the heap usage
|
||||
*/
|
||||
static uint8_t *__sbrk_heap_end = NULL;
|
||||
|
||||
/**
|
||||
* @brief _sbrk() allocates memory to the newlib heap and is used by malloc
|
||||
* and others from the C library
|
||||
*
|
||||
* @verbatim
|
||||
* ############################################################################
|
||||
* # .data # .bss # newlib heap # MSP stack #
|
||||
* # # # # Reserved by _Min_Stack_Size #
|
||||
* ############################################################################
|
||||
* ^-- RAM start ^-- _end _estack, RAM end --^
|
||||
* @endverbatim
|
||||
*
|
||||
* This implementation starts allocating at the '_end' linker symbol
|
||||
* The '_Min_Stack_Size' linker symbol reserves a memory for the MSP stack
|
||||
* The implementation considers '_estack' linker symbol to be RAM end
|
||||
* NOTE: If the MSP stack, at any point during execution, grows larger than the
|
||||
* reserved size, please increase the '_Min_Stack_Size'.
|
||||
*
|
||||
* @param incr Memory size
|
||||
* @return Pointer to allocated memory
|
||||
*/
|
||||
void *_sbrk(ptrdiff_t incr)
|
||||
{
|
||||
extern uint8_t _end; /* Symbol defined in the linker script */
|
||||
extern uint8_t _estack; /* Symbol defined in the linker script */
|
||||
extern uint32_t _Min_Stack_Size; /* Symbol defined in the linker script */
|
||||
const uint32_t stack_limit = (uint32_t)&_estack - (uint32_t)&_Min_Stack_Size;
|
||||
const uint8_t *max_heap = (uint8_t *)stack_limit;
|
||||
uint8_t *prev_heap_end;
|
||||
|
||||
/* Initialize heap end at first call */
|
||||
if (NULL == __sbrk_heap_end)
|
||||
{
|
||||
__sbrk_heap_end = &_end;
|
||||
}
|
||||
|
||||
/* Protect heap from growing into the reserved MSP stack */
|
||||
if (__sbrk_heap_end + incr > max_heap)
|
||||
{
|
||||
errno = ENOMEM;
|
||||
return (void *)-1;
|
||||
}
|
||||
|
||||
prev_heap_end = __sbrk_heap_end;
|
||||
__sbrk_heap_end += incr;
|
||||
|
||||
return (void *)prev_heap_end;
|
||||
}
|
||||
|
||||
#if defined(__PICOLIBC__)
|
||||
// Picolibc expects syscalls without the leading underscore.
|
||||
// This creates a strong alias so that
|
||||
// calls to `sbrk()` are resolved to our `_sbrk()` implementation.
|
||||
__strong_reference(_sbrk, sbrk);
|
||||
#endif
|
||||
403
src/system_stm32h5xx.c
Normal file
403
src/system_stm32h5xx.c
Normal file
@@ -0,0 +1,403 @@
|
||||
/**
|
||||
******************************************************************************
|
||||
* @file system_stm32h5xx.c
|
||||
* @author MCD Application Team
|
||||
* @brief CMSIS Cortex-M33 Device Peripheral Access Layer System Source File
|
||||
*
|
||||
******************************************************************************
|
||||
* @attention
|
||||
*
|
||||
* Copyright (c) 2023 STMicroelectronics.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This software is licensed under terms that can be found in the LICENSE file
|
||||
* in the root directory of this software component.
|
||||
* If no LICENSE file comes with this software, it is provided AS-IS.
|
||||
*
|
||||
******************************************************************************
|
||||
* This file provides two functions and one global variable to be called from
|
||||
* user application:
|
||||
* - SystemInit(): This function is called at startup just after reset and
|
||||
* before branch to main program. This call is made inside
|
||||
* the "startup_stm32h5xx.s" file.
|
||||
*
|
||||
* - SystemCoreClock variable: Contains the core clock (HCLK), it can be used
|
||||
* by the user application to setup the SysTick
|
||||
* timer or configure other parameters.
|
||||
*
|
||||
* - SystemCoreClockUpdate(): Updates the variable SystemCoreClock and must
|
||||
* be called whenever the core clock is changed
|
||||
* during program execution.
|
||||
*
|
||||
* After each device reset the HSI (64 MHz) is used as system clock source.
|
||||
* Then SystemInit() function is called, in "startup_stm32h5xx.s" file, to
|
||||
* configure the system clock before to branch to main program.
|
||||
*
|
||||
* This file configures the system clock as follows:
|
||||
*=============================================================================
|
||||
*-----------------------------------------------------------------------------
|
||||
* System Clock source | HSI
|
||||
*-----------------------------------------------------------------------------
|
||||
* SYSCLK(Hz) | 64000000
|
||||
*-----------------------------------------------------------------------------
|
||||
* HCLK(Hz) | 64000000
|
||||
*-----------------------------------------------------------------------------
|
||||
* AHB Prescaler | 1
|
||||
*-----------------------------------------------------------------------------
|
||||
* APB1 Prescaler | 1
|
||||
*-----------------------------------------------------------------------------
|
||||
* APB2 Prescaler | 1
|
||||
*-----------------------------------------------------------------------------
|
||||
* APB3 Prescaler | 1
|
||||
*-----------------------------------------------------------------------------
|
||||
* HSI Division factor | 1
|
||||
*-----------------------------------------------------------------------------
|
||||
* PLL1_SRC | No clock
|
||||
*-----------------------------------------------------------------------------
|
||||
* PLL1_M | Prescaler disabled
|
||||
*-----------------------------------------------------------------------------
|
||||
* PLL1_N | 129
|
||||
*-----------------------------------------------------------------------------
|
||||
* PLL1_P | 2
|
||||
*-----------------------------------------------------------------------------
|
||||
* PLL1_Q | 2
|
||||
*-----------------------------------------------------------------------------
|
||||
* PLL1_R | 2
|
||||
*-----------------------------------------------------------------------------
|
||||
* PLL1_FRACN | 0
|
||||
*-----------------------------------------------------------------------------
|
||||
* PLL2_SRC | No clock
|
||||
*-----------------------------------------------------------------------------
|
||||
* PLL2_M | Prescaler disabled
|
||||
*-----------------------------------------------------------------------------
|
||||
* PLL2_N | 129
|
||||
*-----------------------------------------------------------------------------
|
||||
* PLL2_P | 2
|
||||
*-----------------------------------------------------------------------------
|
||||
* PLL2_Q | 2
|
||||
*-----------------------------------------------------------------------------
|
||||
* PLL2_R | 2
|
||||
*-----------------------------------------------------------------------------
|
||||
* PLL2_FRACN | 0
|
||||
*-----------------------------------------------------------------------------
|
||||
* PLL3_SRC | No clock
|
||||
*-----------------------------------------------------------------------------
|
||||
* PLL3_M | Prescaler disabled
|
||||
*-----------------------------------------------------------------------------
|
||||
* PLL3_N | 129
|
||||
*-----------------------------------------------------------------------------
|
||||
* PLL3_P | 2
|
||||
*-----------------------------------------------------------------------------
|
||||
* PLL3_Q | 2
|
||||
*-----------------------------------------------------------------------------
|
||||
* PLL3_R | 2
|
||||
*-----------------------------------------------------------------------------
|
||||
* PLL3_FRACN | 0
|
||||
*-----------------------------------------------------------------------------
|
||||
*=============================================================================
|
||||
*/
|
||||
|
||||
/** @addtogroup CMSIS
|
||||
* @{
|
||||
*/
|
||||
|
||||
/** @addtogroup STM32H5xx_system
|
||||
* @{
|
||||
*/
|
||||
|
||||
/** @addtogroup STM32H5xx_System_Private_Includes
|
||||
* @{
|
||||
*/
|
||||
|
||||
#include "stm32h5xx.h"
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/** @addtogroup STM32H5xx_System_Private_TypesDefinitions
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/** @addtogroup STM32H5xx_System_Private_Defines
|
||||
* @{
|
||||
*/
|
||||
|
||||
#if !defined (HSE_VALUE)
|
||||
#define HSE_VALUE (25000000UL) /*!< Value of the External oscillator in Hz */
|
||||
#endif /* HSE_VALUE */
|
||||
|
||||
#if !defined (CSI_VALUE)
|
||||
#define CSI_VALUE (4000000UL) /*!< Value of the Internal oscillator in Hz*/
|
||||
#endif /* CSI_VALUE */
|
||||
|
||||
#if !defined (HSI_VALUE)
|
||||
#define HSI_VALUE (64000000UL) /*!< Value of the Internal oscillator in Hz */
|
||||
#endif /* HSI_VALUE */
|
||||
|
||||
/************************* Miscellaneous Configuration ************************/
|
||||
/*!< Uncomment the following line if you need to relocate your vector Table in
|
||||
Internal SRAM. */
|
||||
/* #define VECT_TAB_SRAM */
|
||||
#if !defined(VECT_TAB_OFFSET)
|
||||
#define VECT_TAB_OFFSET 0x00U /*!< Vector Table base offset field.
|
||||
This value must be a multiple of 0x200. */
|
||||
#endif /* VECT_TAB_OFFSET */
|
||||
/******************************************************************************/
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/** @addtogroup STM32H5xx_System_Private_Macros
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/** @addtogroup STM32H5xx_System_Private_Variables
|
||||
* @{
|
||||
*/
|
||||
/* The SystemCoreClock variable is updated in three ways:
|
||||
1) by calling CMSIS function SystemCoreClockUpdate()
|
||||
2) by calling HAL API function HAL_RCC_GetHCLKFreq()
|
||||
3) each time HAL_RCC_ClockConfig() is called to configure the system clock frequency
|
||||
Note: If you use this function to configure the system clock; then there
|
||||
is no need to call the 2 first functions listed above, since SystemCoreClock
|
||||
variable is updated automatically.
|
||||
*/
|
||||
uint32_t SystemCoreClock = 64000000U;
|
||||
|
||||
const uint8_t AHBPrescTable[16] = {0U, 0U, 0U, 0U, 0U, 0U, 0U, 0U, 1U, 2U, 3U, 4U, 6U, 7U, 8U, 9U};
|
||||
const uint8_t APBPrescTable[8] = {0U, 0U, 0U, 0U, 1U, 2U, 3U, 4U};
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/** @addtogroup STM32H5xx_System_Private_FunctionPrototypes
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/** @addtogroup STM32H5xx_System_Private_Functions
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* @brief Setup the microcontroller system.
|
||||
* @param None
|
||||
* @retval None
|
||||
*/
|
||||
|
||||
void SystemInit(void)
|
||||
{
|
||||
uint32_t reg_opsr;
|
||||
|
||||
/* FPU settings ------------------------------------------------------------*/
|
||||
#if (__FPU_PRESENT == 1) && (__FPU_USED == 1)
|
||||
SCB->CPACR |= ((3UL << 20U)|(3UL << 22U)); /* set CP10 and CP11 Full Access */
|
||||
#endif
|
||||
|
||||
/* Reset the RCC clock configuration to the default reset state ------------*/
|
||||
/* Set HSION bit while preserving the current HSIDIV value*/
|
||||
RCC->CR = (RCC->CR & RCC_CR_HSIDIV_Msk) | RCC_CR_HSION;
|
||||
|
||||
/* Reset CFGR register */
|
||||
RCC->CFGR1 = 0U;
|
||||
RCC->CFGR2 = 0U;
|
||||
|
||||
/* Reset HSEON, HSECSSON, HSEBYP, HSEEXT, HSIDIV, HSIKERON, CSION, CSIKERON, HSI48 and PLLxON bits */
|
||||
#if defined(RCC_CR_PLL3ON)
|
||||
RCC->CR &= ~(RCC_CR_HSEON | RCC_CR_HSECSSON | RCC_CR_HSEBYP | RCC_CR_HSEEXT | RCC_CR_HSIKERON | \
|
||||
RCC_CR_CSION | RCC_CR_CSIKERON |RCC_CR_HSI48ON | RCC_CR_PLL1ON | RCC_CR_PLL2ON | RCC_CR_PLL3ON);
|
||||
#else
|
||||
RCC->CR &= ~(RCC_CR_HSEON | RCC_CR_HSECSSON | RCC_CR_HSEBYP | RCC_CR_HSEEXT | RCC_CR_HSIKERON | \
|
||||
RCC_CR_CSION | RCC_CR_CSIKERON |RCC_CR_HSI48ON | RCC_CR_PLL1ON | RCC_CR_PLL2ON);
|
||||
#endif
|
||||
|
||||
/* Reset PLLxCFGR register */
|
||||
RCC->PLL1CFGR = 0U;
|
||||
RCC->PLL2CFGR = 0U;
|
||||
#if defined(RCC_CR_PLL3ON)
|
||||
RCC->PLL3CFGR = 0U;
|
||||
#endif /* RCC_CR_PLL3ON */
|
||||
|
||||
/* Reset PLL1DIVR register */
|
||||
RCC->PLL1DIVR = 0x01010280U;
|
||||
/* Reset PLL1FRACR register */
|
||||
RCC->PLL1FRACR = 0x00000000U;
|
||||
/* Reset PLL2DIVR register */
|
||||
RCC->PLL2DIVR = 0x01010280U;
|
||||
/* Reset PLL2FRACR register */
|
||||
RCC->PLL2FRACR = 0x00000000U;
|
||||
#if defined(RCC_CR_PLL3ON)
|
||||
/* Reset PLL3DIVR register */
|
||||
RCC->PLL3DIVR = 0x01010280U;
|
||||
/* Reset PLL3FRACR register */
|
||||
RCC->PLL3FRACR = 0x00000000U;
|
||||
#endif /* RCC_CR_PLL3ON */
|
||||
|
||||
/* Reset HSEBYP bit */
|
||||
RCC->CR &= ~(RCC_CR_HSEBYP);
|
||||
|
||||
/* Disable all interrupts */
|
||||
RCC->CIER = 0U;
|
||||
|
||||
/* Configure the Vector Table location add offset address ------------------*/
|
||||
#ifdef VECT_TAB_SRAM
|
||||
SCB->VTOR = SRAM1_BASE | VECT_TAB_OFFSET; /* Vector Table Relocation in Internal SRAM */
|
||||
#else
|
||||
SCB->VTOR = FLASH_BASE | VECT_TAB_OFFSET; /* Vector Table Relocation in Internal FLASH */
|
||||
#endif /* VECT_TAB_SRAM */
|
||||
|
||||
/* Check OPSR register to verify if there is an ongoing swap or option bytes update interrupted by a reset */
|
||||
reg_opsr = FLASH->OPSR & FLASH_OPSR_CODE_OP;
|
||||
if ((reg_opsr == FLASH_OPSR_CODE_OP) || (reg_opsr == (FLASH_OPSR_CODE_OP_2 | FLASH_OPSR_CODE_OP_1)))
|
||||
{
|
||||
/* Check FLASH Option Control Register access */
|
||||
if ((FLASH->OPTCR & FLASH_OPTCR_OPTLOCK) != 0U)
|
||||
{
|
||||
/* Authorizes the Option Byte registers programming */
|
||||
FLASH->OPTKEYR = 0x08192A3BU;
|
||||
FLASH->OPTKEYR = 0x4C5D6E7FU;
|
||||
}
|
||||
/* Launch the option bytes change operation */
|
||||
FLASH->OPTCR |= FLASH_OPTCR_OPTSTART;
|
||||
|
||||
/* Lock the FLASH Option Control Register access */
|
||||
FLASH->OPTCR |= FLASH_OPTCR_OPTLOCK;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Update SystemCoreClock variable according to Clock Register Values.
|
||||
* The SystemCoreClock variable contains the core clock (HCLK), it can
|
||||
* be used by the user application to setup the SysTick timer or configure
|
||||
* other parameters.
|
||||
*
|
||||
* @note Each time the core clock (HCLK) changes, this function must be called
|
||||
* to update SystemCoreClock variable value. Otherwise, any configuration
|
||||
* based on this variable will be incorrect.
|
||||
*
|
||||
* @note - The system frequency computed by this function is not the real
|
||||
* frequency in the chip. It is calculated based on the predefined
|
||||
* constant and the selected clock source:
|
||||
*
|
||||
* - If SYSCLK source is CSI, SystemCoreClock will contain the CSI_VALUE(*)
|
||||
*
|
||||
* - If SYSCLK source is HSI, SystemCoreClock will contain the HSI_VALUE(**)
|
||||
*
|
||||
* - If SYSCLK source is HSE, SystemCoreClock will contain the HSE_VALUE(***)
|
||||
*
|
||||
* - If SYSCLK source is PLL, SystemCoreClock will contain the HSE_VALUE(***)
|
||||
* or HSI_VALUE(**) or CSI_VALUE(*) multiplied/divided by the PLL factors.
|
||||
*
|
||||
* (*) CSI_VALUE is a constant defined in stm32h5xx_hal.h file (default value
|
||||
* 4 MHz) but the real value may vary depending on the variations
|
||||
* in voltage and temperature.
|
||||
*
|
||||
* (**) HSI_VALUE is a constant defined in stm32h5xx_hal.h file (default value
|
||||
* 64 MHz) but the real value may vary depending on the variations
|
||||
* in voltage and temperature.
|
||||
*
|
||||
* (***) HSE_VALUE is a constant defined in stm32h5xx_hal.h file (default value
|
||||
* 25 MHz), user has to ensure that HSE_VALUE is same as the real
|
||||
* frequency of the crystal used. Otherwise, this function may
|
||||
* have wrong result.
|
||||
*
|
||||
* - The result of this function could be not correct when using fractional
|
||||
* value for HSE crystal.
|
||||
*
|
||||
* @param None
|
||||
* @retval None
|
||||
*/
|
||||
void SystemCoreClockUpdate(void)
|
||||
{
|
||||
uint32_t pllp, pllsource, pllm, pllfracen, hsivalue, tmp;
|
||||
float_t fracn1, pllvco;
|
||||
|
||||
/* Get SYSCLK source -------------------------------------------------------*/
|
||||
switch (RCC->CFGR1 & RCC_CFGR1_SWS)
|
||||
{
|
||||
case 0x00UL: /* HSI used as system clock source */
|
||||
SystemCoreClock = (uint32_t) (HSI_VALUE >> ((RCC->CR & RCC_CR_HSIDIV)>> 3));
|
||||
break;
|
||||
|
||||
case 0x08UL: /* CSI used as system clock source */
|
||||
SystemCoreClock = CSI_VALUE;
|
||||
break;
|
||||
|
||||
case 0x10UL: /* HSE used as system clock source */
|
||||
SystemCoreClock = HSE_VALUE;
|
||||
break;
|
||||
|
||||
case 0x18UL: /* PLL1 used as system clock source */
|
||||
/* PLL_VCO = (HSE_VALUE or HSI_VALUE or CSI_VALUE/ PLLM) * PLLN
|
||||
SYSCLK = PLL_VCO / PLLR
|
||||
*/
|
||||
pllsource = (RCC->PLL1CFGR & RCC_PLL1CFGR_PLL1SRC);
|
||||
pllm = ((RCC->PLL1CFGR & RCC_PLL1CFGR_PLL1M)>> RCC_PLL1CFGR_PLL1M_Pos);
|
||||
pllfracen = ((RCC->PLL1CFGR & RCC_PLL1CFGR_PLL1FRACEN)>>RCC_PLL1CFGR_PLL1FRACEN_Pos);
|
||||
fracn1 = (float_t)(uint32_t)(pllfracen* ((RCC->PLL1FRACR & RCC_PLL1FRACR_PLL1FRACN)>> RCC_PLL1FRACR_PLL1FRACN_Pos));
|
||||
|
||||
switch (pllsource)
|
||||
{
|
||||
case 0x01UL: /* HSI used as PLL clock source */
|
||||
hsivalue = (HSI_VALUE >> ((RCC->CR & RCC_CR_HSIDIV)>> 3)) ;
|
||||
pllvco = ((float_t)hsivalue / (float_t)pllm) * ((float_t)(uint32_t)(RCC->PLL1DIVR & RCC_PLL1DIVR_PLL1N) + \
|
||||
(fracn1/(float_t)0x2000) +(float_t)1 );
|
||||
break;
|
||||
|
||||
case 0x02UL: /* CSI used as PLL clock source */
|
||||
pllvco = ((float_t)CSI_VALUE / (float_t)pllm) * ((float_t)(uint32_t)(RCC->PLL1DIVR & RCC_PLL1DIVR_PLL1N) + \
|
||||
(fracn1/(float_t)0x2000) +(float_t)1 );
|
||||
break;
|
||||
|
||||
case 0x03UL: /* HSE used as PLL clock source */
|
||||
pllvco = ((float_t)HSE_VALUE / (float_t)pllm) * ((float_t)(uint32_t)(RCC->PLL1DIVR & RCC_PLL1DIVR_PLL1N) + \
|
||||
(fracn1/(float_t)0x2000) +(float_t)1 );
|
||||
break;
|
||||
|
||||
default: /* No clock sent to PLL*/
|
||||
pllvco = (float_t) 0U;
|
||||
break;
|
||||
}
|
||||
|
||||
pllp = (((RCC->PLL1DIVR & RCC_PLL1DIVR_PLL1P) >>RCC_PLL1DIVR_PLL1P_Pos) + 1U ) ;
|
||||
SystemCoreClock = (uint32_t)(float_t)(pllvco/(float_t)pllp);
|
||||
|
||||
break;
|
||||
|
||||
default:
|
||||
SystemCoreClock = HSI_VALUE;
|
||||
break;
|
||||
}
|
||||
/* Compute HCLK clock frequency --------------------------------------------*/
|
||||
/* Get HCLK prescaler */
|
||||
tmp = AHBPrescTable[((RCC->CFGR2 & RCC_CFGR2_HPRE) >> RCC_CFGR2_HPRE_Pos)];
|
||||
/* HCLK clock frequency */
|
||||
SystemCoreClock >>= tmp;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
221
stm32h563xi_flash.ld
Normal file
221
stm32h563xi_flash.ld
Normal file
@@ -0,0 +1,221 @@
|
||||
/*
|
||||
******************************************************************************
|
||||
**
|
||||
** @brief : Linker script for STM32H563xI devices from STM32H5 series
|
||||
** 2048KBytes FLASH
|
||||
** 640KBytes RAM
|
||||
**
|
||||
** Set heap size, stack size and stack location according
|
||||
** to application requirements.
|
||||
**
|
||||
** Set memory bank area and size if external memory is used
|
||||
**
|
||||
** Target : STMicroelectronics STM32
|
||||
**
|
||||
** Distribution: The file is distributed as is, without any warranty
|
||||
** of any kind.
|
||||
**
|
||||
******************************************************************************
|
||||
** @attention
|
||||
**
|
||||
** Copyright (c) 2026 STMicroelectronics.
|
||||
** All rights reserved.
|
||||
**
|
||||
** This software is licensed under terms that can be found in the LICENSE file
|
||||
** in the root directory of this software component.
|
||||
** If no LICENSE file comes with this software, it is provided AS-IS.
|
||||
**
|
||||
******************************************************************************
|
||||
*/
|
||||
|
||||
/* Memories definition */
|
||||
MEMORY
|
||||
{
|
||||
RAM (xrw) : ORIGIN = 0x20000000, LENGTH = 640K
|
||||
FLASH (rx) : ORIGIN = 0x8000000, LENGTH = 2048K
|
||||
}
|
||||
|
||||
/* Entry Point */
|
||||
ENTRY(Reset_Handler)
|
||||
|
||||
/* Highest address of the user mode stack */
|
||||
_estack = ORIGIN(RAM) + LENGTH(RAM); /* end of "RAM" Ram type memory */
|
||||
_sstack = _estack - _Min_Stack_Size;
|
||||
|
||||
_Min_Heap_Size = 0x200; /* required amount of heap */
|
||||
_Min_Stack_Size = 0x400; /* required amount of stack */
|
||||
|
||||
/* Sections */
|
||||
SECTIONS
|
||||
{
|
||||
|
||||
/* The startup code into "FLASH" Rom type memory */
|
||||
.isr_vector :
|
||||
{
|
||||
. = ALIGN(4);
|
||||
KEEP(*(.isr_vector)) /* Startup code */
|
||||
. = ALIGN(4);
|
||||
} >FLASH
|
||||
|
||||
/* The program code and other data into "FLASH" Rom type memory */
|
||||
.text :
|
||||
{
|
||||
. = ALIGN(4);
|
||||
*(.text) /* .text sections (code) */
|
||||
*(.text*) /* .text* sections (code) */
|
||||
*(.glue_7) /* glue arm to thumb code */
|
||||
*(.glue_7t) /* glue thumb to arm code */
|
||||
*(.eh_frame)
|
||||
KEEP (*(.init))
|
||||
KEEP (*(.fini))
|
||||
. = ALIGN(4);
|
||||
_etext = .; /* define a global symbols at end of code */
|
||||
} >FLASH
|
||||
|
||||
/* Constant data into "FLASH" Rom type memory */
|
||||
.rodata :
|
||||
{
|
||||
. = ALIGN(4);
|
||||
*(.rodata) /* .rodata sections (constants, strings, etc.) */
|
||||
*(.rodata*) /* .rodata* sections (constants, strings, etc.) */
|
||||
. = ALIGN(4);
|
||||
} >FLASH
|
||||
|
||||
.ARM.extab (READONLY) : /* The "READONLY" keyword is only supported in GCC11 and later, remove it if using GCC10 or earlier. */
|
||||
{
|
||||
. = ALIGN(4);
|
||||
*(.ARM.extab* .gnu.linkonce.armextab.*)
|
||||
. = ALIGN(4);
|
||||
} >FLASH
|
||||
|
||||
.ARM (READONLY) : /* The "READONLY" keyword is only supported in GCC11 and later, remove it if using GCC10 or earlier. */
|
||||
{
|
||||
. = ALIGN(4);
|
||||
__exidx_start = .;
|
||||
*(.ARM.exidx*)
|
||||
__exidx_end = .;
|
||||
. = ALIGN(4);
|
||||
} >FLASH
|
||||
|
||||
.preinit_array (READONLY) : /* The "READONLY" keyword is only supported in GCC11 and later, remove it if using GCC10 or earlier. */
|
||||
{
|
||||
. = ALIGN(4);
|
||||
PROVIDE_HIDDEN (__preinit_array_start = .);
|
||||
KEEP (*(.preinit_array*))
|
||||
PROVIDE_HIDDEN (__preinit_array_end = .);
|
||||
. = ALIGN(4);
|
||||
} >FLASH
|
||||
|
||||
.init_array (READONLY) : /* The "READONLY" keyword is only supported in GCC11 and later, remove it if using GCC10 or earlier. */
|
||||
{
|
||||
. = ALIGN(4);
|
||||
PROVIDE_HIDDEN (__init_array_start = .);
|
||||
KEEP (*(SORT(.init_array.*)))
|
||||
KEEP (*(.init_array*))
|
||||
PROVIDE_HIDDEN (__init_array_end = .);
|
||||
. = ALIGN(4);
|
||||
} >FLASH
|
||||
|
||||
.fini_array (READONLY) : /* The "READONLY" keyword is only supported in GCC11 and later, remove it if using GCC10 or earlier. */
|
||||
{
|
||||
. = ALIGN(4);
|
||||
PROVIDE_HIDDEN (__fini_array_start = .);
|
||||
KEEP (*(SORT(.fini_array.*)))
|
||||
KEEP (*(.fini_array*))
|
||||
PROVIDE_HIDDEN (__fini_array_end = .);
|
||||
. = ALIGN(4);
|
||||
} >FLASH
|
||||
|
||||
/* Used by the startup to initialize data */
|
||||
_sidata = LOADADDR(.data);
|
||||
|
||||
/* Initialized data section */
|
||||
.data : ALIGN(4)
|
||||
{
|
||||
_sdata = .; /* create a global symbol at data start */
|
||||
*(.data) /* .data sections */
|
||||
*(.data*) /* .data* sections */
|
||||
*(.RamFunc) /* .RamFunc sections */
|
||||
*(.RamFunc*) /* .RamFunc* sections */
|
||||
. = ALIGN(4);
|
||||
} >RAM AT> FLASH
|
||||
|
||||
.tdata : ALIGN(4)
|
||||
{
|
||||
*(.tdata .tdata.* .gnu.linkonce.td.*)
|
||||
. = ALIGN(4);
|
||||
_edata = .; /* define a global symbol at data end */
|
||||
PROVIDE(__data_end = .);
|
||||
PROVIDE(__tdata_end = .);
|
||||
} >RAM AT> FLASH
|
||||
PROVIDE( __tdata_start = ADDR(.tdata) );
|
||||
PROVIDE( __tdata_size = __tdata_end - __tdata_start );
|
||||
|
||||
PROVIDE( __data_start = ADDR(.data) );
|
||||
PROVIDE( __data_size = __data_end - __data_start );
|
||||
|
||||
PROVIDE( __tdata_source = LOADADDR(.tdata) );
|
||||
PROVIDE( __tdata_source_end = LOADADDR(.tdata) + SIZEOF(.tdata) );
|
||||
PROVIDE( __tdata_source_size = __tdata_source_end - __tdata_source );
|
||||
|
||||
PROVIDE( __data_source = LOADADDR(.data) );
|
||||
PROVIDE( __data_source_end = __tdata_source_end );
|
||||
PROVIDE( __data_source_size = __data_source_end - __data_source );
|
||||
|
||||
/* Uninitialized data section */
|
||||
.tbss (NOLOAD) : ALIGN(4)
|
||||
{
|
||||
/* This is used by the startup in order to initialize the .bss and .tbss sections */
|
||||
_sbss = .; /* define a global symbol at bss start */
|
||||
__bss_start__ = _sbss;
|
||||
PROVIDE( __bss_start = . );
|
||||
*(.tbss .tbss.*)
|
||||
. = ALIGN(4);
|
||||
PROVIDE( __tbss_end = . );
|
||||
} >RAM
|
||||
PROVIDE( __tbss_start = ADDR(.tbss) );
|
||||
PROVIDE( __tbss_size = __tbss_end - __tbss_start );
|
||||
PROVIDE( __tbss_offset = ADDR(.tbss) - ADDR(.tdata) );
|
||||
|
||||
PROVIDE( __tls_base = __tdata_start );
|
||||
PROVIDE( __tls_end = __tbss_end );
|
||||
PROVIDE( __tls_size = __tls_end - __tls_base );
|
||||
PROVIDE( __tls_align = MAX(ALIGNOF(.tdata), ALIGNOF(.tbss)) );
|
||||
PROVIDE( __tls_size_align = (__tls_size + __tls_align - 1) & ~(__tls_align - 1) );
|
||||
PROVIDE( __arm32_tls_tcb_offset = MAX(8, __tls_align) );
|
||||
PROVIDE( __arm64_tls_tcb_offset = MAX(16, __tls_align) );
|
||||
|
||||
.bss (NOLOAD) : ALIGN(4)
|
||||
{
|
||||
*(.bss)
|
||||
*(.bss*)
|
||||
*(COMMON)
|
||||
. = ALIGN(4);
|
||||
_ebss = .; /* define a global symbol at bss end */
|
||||
__bss_end__ = _ebss;
|
||||
PROVIDE( __bss_end = . );
|
||||
} >RAM
|
||||
PROVIDE( __bss_size = __bss_end - __bss_start );
|
||||
PROVIDE( __non_tls_bss_start = ADDR(.bss) );
|
||||
|
||||
/* User_heap_stack section, used to check that there is enough "RAM" Ram type memory left */
|
||||
._user_heap_stack (NOLOAD) :
|
||||
{
|
||||
. = ALIGN(8);
|
||||
PROVIDE ( end = . );
|
||||
PROVIDE ( _end = . );
|
||||
. = . + _Min_Heap_Size;
|
||||
. = . + _Min_Stack_Size;
|
||||
. = ALIGN(8);
|
||||
} >RAM
|
||||
|
||||
/* Remove information from the compiler libraries */
|
||||
/DISCARD/ :
|
||||
{
|
||||
libc.a:* ( * )
|
||||
libm.a:* ( * )
|
||||
libgcc.a:* ( * )
|
||||
}
|
||||
|
||||
.ARM.attributes 0 : { *(.ARM.attributes) }
|
||||
}
|
||||
67
yeepi.py
Normal file
67
yeepi.py
Normal file
@@ -0,0 +1,67 @@
|
||||
import spidev
|
||||
import RPi.GPIO as GPIO
|
||||
|
||||
global spi
|
||||
|
||||
PISPI_BUFFER_SIZE = 256 # Buffer size must match between Pi and STM32
|
||||
|
||||
# Pin number for our CS pin repurposed as a ready pin
|
||||
ReadyPin = 8
|
||||
|
||||
# Initialise the SPI communications
|
||||
# You must pass in the pigpio handle
|
||||
# Speed is optional, defaults to 1MHz
|
||||
def YEEPiInit(speed=1000000):
|
||||
|
||||
# Global these so they can be used later
|
||||
global spi
|
||||
|
||||
spi = spidev.SpiDev() # Create SPI object
|
||||
spi.open(0,0) # Open SPI bus 0 device 0
|
||||
spi.max_speed_hz = speed # Set speed to inputted speed
|
||||
spi.mode = 0 # Set SPI mode to 0
|
||||
spi.no_cs = True # Disable chip select
|
||||
|
||||
GPIO.setmode(GPIO.BCM)
|
||||
GPIO.setup(ReadyPin, GPIO.IN, pull_up_down=GPIO.PUD_OFF)
|
||||
|
||||
|
||||
# Execute a transfer to YEEP, exchanging buffers
|
||||
# Takes a bytearray of values and returns a bytearray
|
||||
# with the received data
|
||||
#
|
||||
# Input data smaller than the buffer size will be padded to correct size
|
||||
# with null bytes. Input data larger will be truncated
|
||||
# Warnings will be printed in the cases of an array being truncated
|
||||
# or if received data is blank
|
||||
|
||||
def YEEPiTransfer(TXBuf):
|
||||
# Check that the input data is a byte array, error if not
|
||||
if not isinstance(TXBuf, bytearray):
|
||||
raise TypeError("Data must be byte array")
|
||||
|
||||
# Check if the array is larger, and delete extra entries
|
||||
if len(TXBuf) > PISPI_BUFFER_SIZE:
|
||||
print("Warning: Array larger than buffer size, truncating")
|
||||
del TXBuf[PISPI_BUFFER_SIZE:] # Delete entries beyond buffer size
|
||||
|
||||
# Pad the array to the full size if required
|
||||
TXBuf = TXBuf.ljust(PISPI_BUFFER_SIZE, b'\0') #Pad to buffer size with null bytes
|
||||
|
||||
# Wait until ready pin is asserted
|
||||
while not GPIO.input(ReadyPin):
|
||||
pass # Pass immediatly restarts the loop with no delay - we don't want to wait any longer than we have to
|
||||
|
||||
# Execute the transfer
|
||||
RXBuf = spi.xfer(TXBuf)
|
||||
|
||||
# If the received buffer is all 0, warn the user
|
||||
if sum(RXBuf) == 0:
|
||||
print("Warning: Empty message received")
|
||||
|
||||
# Convert returned list to bytearray
|
||||
return bytearray(RXBuf)
|
||||
|
||||
# This should be called when the program exits
|
||||
def YEEPiExit():
|
||||
GPIO.cleanup()
|
||||
Reference in New Issue
Block a user