Compare commits

...

7 Commits

24 changed files with 411 additions and 167 deletions

3
.gitignore vendored
View File

@ -1 +1,2 @@
/.out/
.idea/
/build/

8
.idea/.gitignore generated vendored
View File

@ -1,8 +0,0 @@
# Default ignored files
/shelf/
/workspace.xml
# Editor-based HTTP Client requests
/httpRequests/
# Datasource local storage ignored files
/dataSources/
/dataSources.local.xml

1
.idea/.name generated
View File

@ -1 +0,0 @@
FloatPUMP

11
.idea/cmake.xml generated
View File

@ -1,11 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="CMakeSharedSettings">
<configurations>
<configuration PROFILE_NAME="Debug-fw" ENABLED="true" GENERATION_DIR=".out/fw-debug" CONFIG_NAME="Debug" TOOLCHAIN_NAME="dev-arm-stm32" NO_GENERATOR="true" />
<configuration PROFILE_NAME="Release-fw" ENABLED="true" GENERATION_DIR=".out/fw-release" CONFIG_NAME="Release" TOOLCHAIN_NAME="dev-arm-stm32" NO_GENERATOR="true" />
<configuration PROFILE_NAME="RelWithDebInfo-fw" ENABLED="true" GENERATION_DIR=".out/fw-relwithdebinfo" CONFIG_NAME="RelWithDebInfo" TOOLCHAIN_NAME="dev-arm-stm32" NO_GENERATOR="true" />
<configuration PROFILE_NAME="MinSizeRel-fw" ENABLED="true" GENERATION_DIR=".out/fw-minsizerel" CONFIG_NAME="MinSizeRel" TOOLCHAIN_NAME="dev-arm-stm32" NO_GENERATOR="true" />
</configurations>
</component>
</project>

View File

@ -1,2 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<module classpath="CMake" type="CPP_MODULE" version="4" />

4
.idea/misc.xml generated
View File

@ -1,4 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="CMakeWorkspace" PROJECT_DIR="$PROJECT_DIR$" />
</project>

8
.idea/modules.xml generated
View File

@ -1,8 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="ProjectModuleManager">
<modules>
<module fileurl="file://$PROJECT_DIR$/.idea/floatpump-firmware.iml" filepath="$PROJECT_DIR$/.idea/floatpump-firmware.iml" />
</modules>
</component>
</project>

6
.idea/vcs.xml generated
View File

@ -1,6 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="VcsDirectoryMappings">
<mapping directory="$PROJECT_DIR$" vcs="Git" />
</component>
</project>

View File

@ -1,115 +1,22 @@
#THIS FILE IS AUTO GENERATED FROM THE TEMPLATE! DO NOT CHANGE!
set(CMAKE_SYSTEM_NAME Generic)
set(CMAKE_SYSTEM_VERSION 1)
cmake_minimum_required(VERSION 3.2)
# General project settings
cmake_minimum_required(VERSION 3.22)
project(FloatPUMP VERSION 2.0.0 LANGUAGES C CXX ASM)
# specify cross-compilers and tools
set(CMAKE_C_COMPILER arm-none-eabi-gcc)
set(CMAKE_CXX_COMPILER arm-none-eabi-g++)
set(CMAKE_ASM_COMPILER arm-none-eabi-gcc)
set(CMAKE_AR arm-none-eabi-ar)
set(CMAKE_OBJCOPY arm-none-eabi-objcopy)
set(CMAKE_OBJDUMP arm-none-eabi-objdump)
set(SIZE arm-none-eabi-size)
set(CMAKE_TRY_COMPILE_TARGET_TYPE STATIC_LIBRARY)
# Custom options
option(ENABLE_UNITTESTS "Activates the unittesting framework" OFF)
# project settings
project(FloatPUMP C CXX ASM)
# General language considerations
set(CMAKE_CXX_STANDARD 17)
set(CMAKE_C_STANDARD 11)
# custom options
#execute_process(
# COMMAND git log -1 --format=%h
# WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}
# OUTPUT_VARIABLE GIT_HASH
# OUTPUT_STRIP_TRAILING_WHITESPACE
#)
#
#add_definitions(-DGIT_HASH=${GIT_HASH})
set(GIT_HASH "undefined")
find_package(Git QUIET)
if(GIT_FOUND)
execute_process(
COMMAND ${GIT_EXECUTABLE} log -1 --pretty=format:%h
OUTPUT_VARIABLE GIT_HASH
OUTPUT_STRIP_TRAILING_WHITESPACE
ERROR_QUIET
)
endif()
message(STATUS "Burning in git hash: ${GIT_HASH}")
add_definitions("-DGIT_HASH=\"${GIT_HASH}\"")
#Uncomment for hardware floating point
#add_compile_definitions(ARM_MATH_CM4;ARM_MATH_MATRIX_CHECK;ARM_MATH_ROUNDING)
#add_compile_options(-mfloat-abi=hard -mfpu=fpv4-sp-d16)
#add_link_options(-mfloat-abi=hard -mfpu=fpv4-sp-d16)
#Uncomment for software floating point
#add_compile_options(-mfloat-abi=soft)
add_compile_options(-mcpu=cortex-m4 -mthumb -mthumb-interwork)
add_compile_options(-ffunction-sections -fdata-sections -fno-common -fmessage-length=0)
# uncomment to mitigate c++17 absolute addresses warnings
#set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wno-register")
# Enable assembler files preprocessing
add_compile_options($<$<COMPILE_LANGUAGE:ASM>:-x$<SEMICOLON>assembler-with-cpp>)
if ("${CMAKE_BUILD_TYPE}" STREQUAL "Release")
message(STATUS "Maximum optimization for speed")
add_compile_options(-Ofast)
elseif ("${CMAKE_BUILD_TYPE}" STREQUAL "RelWithDebInfo")
message(STATUS "Maximum optimization for speed, debug info included")
add_compile_options(-Ofast -g)
elseif ("${CMAKE_BUILD_TYPE}" STREQUAL "MinSizeRel")
message(STATUS "Maximum optimization for size")
add_compile_options(-Os)
else ()
message(STATUS "Minimal optimization, debug info included")
add_compile_options(-Og -g)
# General Project
if(NOT ENABLE_UNITTESTS)
add_subdirectory(floatpump)
endif ()
add_definitions(-DDEBUG -DUSE_HAL_DRIVER -DSTM32F411xE)
include_directories(
floatpump/USB_DEVICE/App
floatpump/USB_DEVICE/Target
floatpump/Core/Inc
floatpump/Drivers/STM32F4xx_HAL_Driver/Inc
floatpump/Drivers/STM32F4xx_HAL_Driver/Inc/Legacy
floatpump/Middlewares/ST/STM32_USB_Device_Library/Core/Inc
floatpump/Middlewares/ST/STM32_USB_Device_Library/Class/CDC/Inc
floatpump/Drivers/CMSIS/Device/ST/STM32F4xx/Include floatpump/Drivers/CMSIS/Include
floatpump/Middlewares/floatpump/Inc
)
file(GLOB_RECURSE SOURCES
"floatpump/Core/*.*"
"floatpump/Middlewares/*.*"
"floatpump/Drivers/*.*"
"floatpump/USB_DEVICE/*.*"
)
set(LINKER_SCRIPT ${CMAKE_SOURCE_DIR}/STM32F411CEUX_FLASH.ld)
add_link_options(-Wl,-gc-sections,--print-memory-usage,-Map=${PROJECT_BINARY_DIR}/${PROJECT_NAME}.map)
add_link_options(-mcpu=cortex-m4 -mthumb -mthumb-interwork)
add_link_options(-T ${LINKER_SCRIPT})
add_executable(${PROJECT_NAME}.elf ${SOURCES} ${LINKER_SCRIPT})
set(HEX_FILE ${PROJECT_BINARY_DIR}/${PROJECT_NAME}.hex)
set(BIN_FILE ${PROJECT_BINARY_DIR}/${PROJECT_NAME}.bin)
add_custom_command(TARGET ${PROJECT_NAME}.elf POST_BUILD
COMMAND ${CMAKE_OBJCOPY} -Oihex $<TARGET_FILE:${PROJECT_NAME}.elf> ${HEX_FILE}
COMMAND ${CMAKE_OBJCOPY} -Obinary $<TARGET_FILE:${PROJECT_NAME}.elf> ${BIN_FILE}
COMMENT "Building ${HEX_FILE}
Building ${BIN_FILE}")
# Testing Project
if(ENABLE_UNITTESTS)
message(STATUS "Enabled Unit Tests")
add_subdirectory(Catch2)
add_subdirectory(Tests)
endif()

75
CMakePresets.json Normal file
View File

@ -0,0 +1,75 @@
{
"version": 10,
"cmakeMinimumRequired": {
"major": 3,
"minor": 22
},
"configurePresets": [
{
"name": "debug@firmware",
"description": "Firmware Debug Build",
"generator": "Ninja",
"cacheVariables": {
"CMAKE_TOOLCHAIN_FILE": "toolchain/arm-none-eabi-stm32f411ceu6-toolchain.cmake",
"CMAKE_BUILD_TYPE": "Debug"
},
"binaryDir": "build/debug@firmware"
},
{
"name": "release@firmware",
"description": "Firmware Release Build",
"generator": "Ninja",
"cacheVariables": {
"CMAKE_TOOLCHAIN_FILE": "toolchain/arm-none-eabi-stm32f411ceu6-toolchain.cmake",
"CMAKE_BUILD_TYPE": "Release"
},
"binaryDir": "build/release@firmware"
},
{
"name": "minrelease@firmware",
"description": "Firmware Minimized Release Build",
"inherits": ["release@firmware"],
"cacheVariables": {
"CMAKE_BUILD_TYPE": "MinSizeRel"
},
"binaryDir": "build/minrelease@firmware"
},
{
"name": "debug@tests",
"description": "UnitTests Debug Build",
"generator": "Ninja",
"cacheVariables": {
"ENABLE_UNITTESTS": "ON"
},
"binaryDir": "build/debug@tests"
}
],
"buildPresets": [
{
"name": "build-debug",
"description": "Builds the debugging firmware",
"cleanFirst": false,
"configurePreset": "debug@firmware",
"targets": [
"FloatPUMP.elf"
]
},
{
"name": "build-release",
"description": "Builds the normal release firmware",
"cleanFirst": true,
"configurePreset": "minrelease@firmware",
"targets": [
"FloatPUMP.elf"
]
},
{
"name": "build-tests",
"description": "Creates a debug build of all tests",
"configurePreset": "debug@tests",
"targets": [
"testtests"
]
}
]
}

29
Tests/CMakeLists.txt Normal file
View File

@ -0,0 +1,29 @@
# Catch 2 is already loaded from the main CMakeLists.txt as a subdirectory
add_executable(testtests experiments/example-test.cpp)
target_link_libraries(testtests PRIVATE Catch2::Catch2WithMain)
# Firmware modules tests
file(GLOB_RECURSE FWMODULES_SOURCES
"${CMAKE_SOURCE_DIR}/floatpump/Modules/*.cpp"
)
add_executable(fwmodules
${FWMODULES_SOURCES}
modules.cpp
)
target_include_directories(fwmodules PUBLIC
${CMAKE_SOURCE_DIR}/floatpump/Modules
)
target_link_libraries(fwmodules PRIVATE Catch2::Catch2WithMain)
# General catch configuration
include(CTest)
include(Catch)
catch_discover_tests(testtests)

View File

@ -0,0 +1,14 @@
#include <catch2/catch_test_macros.hpp>
#include <cstdint>
uint32_t factorial( uint32_t number ) {
return number <= 1 ? number : factorial(number-1) * number;
}
TEST_CASE( "Factorials are computed", "[factorial]" ) {
REQUIRE( factorial( 1) == 1 );
REQUIRE( factorial( 2) == 2 );
REQUIRE( factorial( 3) == 6 );
REQUIRE( factorial(10) == 3'628'800 );
}

33
Tests/modules.cpp Normal file
View File

@ -0,0 +1,33 @@
#include <catch2/catch_test_macros.hpp>
#include "filter_fir_crude.h"
#include "ICalibrator.h"
TEST_CASE("Filter Modules", "[filter]")
{
SECTION("FIR Filter Crude Implementation")
{
float coeffs[] = {1,1,1};
FilterFIRCrude filter1(coeffs, 3);
filter1.process(10);
filter1.process(10);
auto res = filter1.process(10);
REQUIRE(res == 10);
}
SECTION("Linear Calibration")
{
std::pair<double, double> p1 (1, 1);
std::pair<double, double> p2 (10, 10);
auto pc = std::make_pair(p1, p2);
floatpump::Calibrator<floatpump::LinearCalibrator> calibrator (pc);
REQUIRE(calibrator.translate(1) == 1);
REQUIRE(calibrator.translate(5) == 5);
REQUIRE(calibrator.translate(10) == 10);
}
}

View File

@ -4,23 +4,20 @@ FROM ubuntu:22.04
ENV TZ=Europe/Berlin
RUN ln -snf /usr/share/zoneinfo/$TZ /etc/localtime && echo $TZ > /etc/timezone
RUN apt-get -y update && apt -y upgrade
RUN --mount=type=cache,target=/var/lib/apt \
apt-get -y update && \
apt-get upgrade -y && \
apt-get install -y --no-install-recommends \
python3 python3-pip lsb-release software-properties-common rename wget git \
ninja-build make gdb gdbserver pkg-config \
gperf linux-tools-generic linux-tools-common valgrind \
clang \
gcc-arm-none-eabi libnewlib-arm-none-eabi libstdc++-arm-none-eabi-newlib\
cmake \
catch2 \
zsh
# Build Env
RUN apt-get -y install python3 python3-pip lsb-release software-properties-common rename wget git
RUN apt-get -y install ninja-build make gdb gdbserver pkg-config
RUN useradd -U \
developer
# Profiling
RUN apt-get -y install gperf linux-tools-generic linux-tools-common valgrind
# Clang
RUN apt-get -y install clang
# ARM Gcc
RUN apt-get -y install gcc-arm-none-eabi
# CMake
RUN apt-get -y install cmake
RUN apt-get clean
USER developer:developer

View File

@ -0,0 +1,6 @@
services:
stm32-dev:
build:
dockerfile: Dockerfile
tags:
- stm-32-dev

View File

@ -0,0 +1,14 @@
# Obtain the short git hash for burning it into the firmware
set(GIT_HASH "undefined")
find_package(Git QUIET)
if(GIT_FOUND)
execute_process(
COMMAND ${GIT_EXECUTABLE} log -1 --pretty=format:%h
OUTPUT_VARIABLE GIT_HASH
OUTPUT_STRIP_TRAILING_WHITESPACE
ERROR_QUIET
)
message(STATUS "Burning in git hash: ${GIT_HASH}")
else ()
message(WARNING "Cannot obtain git hash for burning into firmware")
endif()

43
floatpump/CMakeLists.txt Normal file
View File

@ -0,0 +1,43 @@
include(CMake/githash.cmake)
# All required source definitions
file(GLOB_RECURSE SOURCES
"Core/*.*"
"Middlewares/*.*"
"Drivers/*.*"
"USB_DEVICE/*.*"
)
# Check if the correct toolchain was used and the LINKER_SCRIPT is defined
if(NOT DEFINED LINKER_SCRIPT)
message(FATAL_ERROR "You need to define the LINKER_SCRIPT variable from within the toolchain for the correct MCU")
endif()
add_executable(FloatPUMP.elf ${SOURCES} ${LINKER_SCRIPT})
# Custom target options
target_compile_definitions(FloatPUMP.elf PUBLIC
"-DGIT_HASH=\"${GIT_HASH}\""
)
target_include_directories(${PROJECT_NAME}.elf PUBLIC
USB_DEVICE/App
USB_DEVICE/Target
Core/Inc
Drivers/STM32F4xx_HAL_Driver/Inc
Drivers/STM32F4xx_HAL_Driver/Inc/Legacy
Middlewares/ST/STM32_USB_Device_Library/Core/Inc
Middlewares/ST/STM32_USB_Device_Library/Class/CDC/Inc
Drivers/CMSIS/Device/ST/STM32F4xx/Include
Drivers/CMSIS/Include
Middlewares/floatpump/Inc
)
set(HEX_FILE ${PROJECT_BINARY_DIR}/${PROJECT_NAME}.hex)
set(BIN_FILE ${PROJECT_BINARY_DIR}/${PROJECT_NAME}.bin)
add_custom_command(TARGET ${PROJECT_NAME}.elf POST_BUILD
COMMAND ${CMAKE_OBJCOPY} -Oihex $<TARGET_FILE:${PROJECT_NAME}.elf> ${HEX_FILE}
COMMAND ${CMAKE_OBJCOPY} -Obinary $<TARGET_FILE:${PROJECT_NAME}.elf> ${BIN_FILE}
COMMENT "Building ${HEX_FILE}
Building ${BIN_FILE}")

View File

@ -0,0 +1,43 @@
#pragma once
#include <bits/unique_ptr.h>
namespace floatpump {
struct ICalibrator {
virtual ~ICalibrator() = default;
virtual auto translate(double measurand) -> double = 0;
};
struct LinearCalibrator
{
LinearCalibrator(std::pair<std::pair<double, double>, std::pair<double, double>>);
auto translate(double measurand) -> double;
private:
std::pair<std::pair<double, double>, std::pair<double, double>> _calibration_points;
double _a;
double _b;
};
template<typename T>
class Calibrator : public ICalibrator
{
public:
template<typename ...As>
explicit Calibrator(As&&... args)
{
_internal_calibrator = std::make_unique<T>(std::forward<As>(args)...);
}
double translate(double measurand) override
{
return _internal_calibrator->translate(measurand);
}
private:
std::unique_ptr<T> _internal_calibrator;
};
}

View File

@ -0,0 +1,20 @@
//
// Created by robtor on 6/18/25.
//
#include "ICalibrator.h"
namespace floatpump {
LinearCalibrator::LinearCalibrator(std::pair<std::pair<double, double>, std::pair<double, double>> points)
{
_a = 1.0 * (points.second.second - points.first.second) / (points.second.first - points.first.first);
_b = points.first.second - (_a * points.first.first);
_calibration_points = std::move(points);
}
auto LinearCalibrator::translate(double measurand) -> double
{
return _a * measurand + _b;
}
} // floatpump

View File

@ -0,0 +1,30 @@
#include "filter_fir_crude.h"
FilterFIRCrude::FilterFIRCrude(const float* coeffs, size_t numTaps) :
_coeffs(coeffs), _histsize(numTaps), _index(0)
{
_history = new float[_histsize];
std::memset(_history, 0 , numTaps*sizeof(float));
}
float FilterFIRCrude::process(float input)
{
_history[_index] = input;
float result = 0.0f;
size_t idx = _index;
for (size_t i = 0; i < _histsize; ++i)
{
result += _coeffs[i] * _history[idx];
if (idx == 0)
{
idx = _histsize - 1;
} else
{
--idx;
}
_index = (_index + 1) % _histsize;
}
return result;
}

View File

@ -0,0 +1,19 @@
#pragma once
#include <cstdint>
#include <cstring>
#include <cstddef>
class FilterFIRCrude
{
public:
FilterFIRCrude(const float* coeffs, size_t numTaps);
float process(float input);
private:
const float* _coeffs;
size_t _histsize;
float* _history;
size_t _index;
};

View File

@ -0,0 +1,53 @@
set(CMAKE_SYSTEM_NAME Generic)
set(CMAKE_SYSTEM_VERSION 1)
# specify cross-compilers and tools
set(CMAKE_C_COMPILER arm-none-eabi-gcc)
set(CMAKE_CXX_COMPILER arm-none-eabi-g++)
set(CMAKE_ASM_COMPILER arm-none-eabi-gcc)
set(CMAKE_AR arm-none-eabi-ar)
set(CMAKE_OBJCOPY arm-none-eabi-objcopy)
set(CMAKE_OBJDUMP arm-none-eabi-objdump)
set(SIZE arm-none-eabi-size)
set(CMAKE_TRY_COMPILE_TARGET_TYPE STATIC_LIBRARY)
#Uncomment for hardware floating point
#add_compile_definitions(ARM_MATH_CM4;ARM_MATH_MATRIX_CHECK;ARM_MATH_ROUNDING)
#add_compile_options(-mfloat-abi=hard -mfpu=fpv4-sp-d16)
#add_link_options(-mfloat-abi=hard -mfpu=fpv4-sp-d16)
#Uncomment for software floating point
#add_compile_options(-mfloat-abi=soft)
# Enable assembler files preprocessing
add_compile_options($<$<COMPILE_LANGUAGE:ASM>:-x$<SEMICOLON>assembler-with-cpp>)
if ("${CMAKE_BUILD_TYPE}" STREQUAL "Release")
message(STATUS "Maximum optimization for speed")
add_compile_options(-Ofast)
elseif ("${CMAKE_BUILD_TYPE}" STREQUAL "RelWithDebInfo")
message(STATUS "Maximum optimization for speed, debug info included")
add_compile_options(-Ofast -g)
elseif ("${CMAKE_BUILD_TYPE}" STREQUAL "MinSizeRel")
message(STATUS "Maximum optimization for size")
add_compile_options(-Os)
else ()
message(STATUS "Minimal optimization, debug info included")
add_compile_options(-Og -g)
endif ()
add_compile_options(-mcpu=cortex-m4 -mthumb -mthumb-interwork)
add_compile_options(-ffunction-sections -fdata-sections -fno-common -fmessage-length=0)
add_definitions(-DDEBUG -DUSE_HAL_DRIVER -DSTM32F411xE)
set(LINKER_SCRIPT ${CMAKE_SOURCE_DIR}/toolchain/STM32F411CEUX_FLASH.ld CACHE FILEPATH "STM specific linker script")
add_link_options(-Wl,-gc-sections,--print-memory-usage,-Map=${PROJECT_BINARY_DIR}/${PROJECT_NAME}.map)
add_link_options(-mcpu=cortex-m4 -mthumb -mthumb-interwork)
add_link_options(-T ${LINKER_SCRIPT})