From e89bfe1a94ace264822730507b6ccb4c93032b72 Mon Sep 17 00:00:00 2001 From: dzid26 Date: Tue, 16 Jul 2024 15:40:18 +0100 Subject: [PATCH 1/5] Testing with python and cffi Small c-files cleanup to help with compilation. Displays test results in Github Actions summary and PRs --- .github/workflows/build.yaml | 97 +- .gitignore | 11 +- .vscode/extensions.json | 3 +- README.md | 22 +- pyproject.toml | 31 + src/STM8S_StdPeriph_Lib/inc/stm8s.h | 6 +- src/adc.c | 1 - src/motor.c | 2 +- src/motor.h | 1 - src/uart.c | 1 - tests/conftest.py | 26 + tests/load_c_code.py | 211 +++ tests/sim/_tsdz2.cdef | 2276 +++++++++++++++++++++++++++ tests/test_diag.py | 30 + tests/test_display.py | 36 + tests/test_wheel_speed.py | 85 + 16 files changed, 2812 insertions(+), 27 deletions(-) create mode 100644 pyproject.toml create mode 100644 tests/conftest.py create mode 100644 tests/load_c_code.py create mode 100644 tests/sim/_tsdz2.cdef create mode 100644 tests/test_diag.py create mode 100644 tests/test_display.py create mode 100644 tests/test_wheel_speed.py diff --git a/.github/workflows/build.yaml b/.github/workflows/build.yaml index 76577ea4..046c4233 100644 --- a/.github/workflows/build.yaml +++ b/.github/workflows/build.yaml @@ -8,11 +8,17 @@ on: default: 'warning' push: paths: - - ".github/workflows/build.yaml" + - ".github/workflows/*" - "src/*" + - "tests/*" + - "pyproject.toml" + - "setup.py" pull_request: paths: - "src/*" + - "tests/*" + - "pyproject.toml" + - "setup.py" env: SDCC_VERSION: 4.4.0 @@ -21,33 +27,50 @@ jobs: Build_Windows: runs-on: windows-latest steps: - - name: install SDCC - run: | #install silent and then unpack missing installation libraries + # - name: Start SSH session + # uses: luchihoratiu/debug-via-ssh@main + # with: + # NGROK_AUTH_TOKEN: ${{ secrets.NGROK_AUTH_TOKEN }} + # SSH_PASS: ${{ secrets.SSH_PASS }} + - name: Install SDCC + run: | Invoke-WebRequest -UserAgent "Wget" -Uri https://sourceforge.net/projects/sdcc/files/sdcc-win64/$env:SDCC_VERSION/sdcc-$env:SDCC_VERSION-rc3-x64-setup.exe/download -OutFile sdcc_setup.exe - ls Start-Process -wait -FilePath "sdcc_setup.exe" -ArgumentList "/S", "/D=C:\Program Files\SDCC" - echo "Adding sdcc to PATH" + echo "Adding SDCC to PATH" Add-Content $env:GITHUB_PATH "C:\Program Files\SDCC\bin" - uses: actions/checkout@v4 + - name: Set up Python + uses: actions/setup-python@v5 + with: + python-version: '3.x' + # this mainly checks whether tests compile and work on windows. The actual test report runs on Ubuntu job + - name: Check testing framework + run: | + pip install -e . + rm tests/sim/_tsdz2.cdef # make sure cdef is generated from the source to check testing framework + pytest - name: Build run: | cd src - ../tools/cygwin_64/bin/make.exe clean - ../tools/cygwin_64/bin/make.exe CFLAGS=--Werror + make clean + make CFLAGS=--Werror - uses: actions/upload-artifact@v4 with: name: firmware_from_windows path: bin/main.hex - Build_Linux: - runs-on: ubuntu-22.04 + runs-on: ubuntu-latest steps: - - name: install SDCC + # - name: Start SSH session + # uses: luchihoratiu/debug-via-ssh@main + # with: + # NGROK_AUTH_TOKEN: ${{ secrets.NGROK_AUTH_TOKEN }} + # SSH_PASS: ${{ secrets.SSH_PASS }} + - name: Install SDCC run: | cd ~ - wget https://sourceforge.net/projects/sdcc/files/sdcc-linux-amd64/4.4.0/sdcc-4.4.0-amd64-unknown-linux2.5.tar.bz2/download -O sdcc-amd64.tar.bz2 - ls + wget https://sourceforge.net/projects/sdcc/files/sdcc-linux-amd64/$SDCC_VERSION/sdcc-$SDCC_VERSION-amd64-unknown-linux2.5.tar.bz2/download -O sdcc-amd64.tar.bz2 sudo tar xf sdcc-amd64.tar.bz2 cd sdcc-$SDCC_VERSION/ sudo cp -r * /usr/local @@ -65,9 +88,53 @@ jobs: path: bin/main.hex + Tests: + runs-on: ubuntu-latest + permissions: + contents: read + pull-requests: write + steps: + - uses: actions/checkout@v4 + - name: Set up Python + uses: actions/setup-python@v5 + with: + python-version: '3.x' + - name: Install dependencies + run: | + pip install -e . + pip install --upgrade pytest-md-report + - name: Run tests + env: + REPORT_OUTPUT: md_report.md + shell: bash + run: | + rm tests/sim/_tsdz2.cdef # make sure cdef is generated from the source to check testing framework + + echo "REPORT_FILE=${REPORT_OUTPUT}" >> "$GITHUB_ENV" + pytest --md-report --md-report-flavor gfm --md-report-output "$REPORT_OUTPUT" + - name: Output reports to the job summary + if: always() + shell: bash + run: | + if [ -f "$REPORT_FILE" ]; then + echo "## Test Report" >> $GITHUB_STEP_SUMMARY + echo "" >> $GITHUB_STEP_SUMMARY + cat "$REPORT_FILE" >> $GITHUB_STEP_SUMMARY + echo "" >> $GITHUB_STEP_SUMMARY + else + echo "Report file not found." + fi + - name: Render the report to the PR when tests fail + uses: marocchino/sticky-pull-request-comment@v2 + if: failure() + with: + header: test-report + recreate: true + path: ${{ env.REPORT_FILE }} + Compare_builds: needs: [Build_Windows, Build_Linux] - runs-on: ubuntu-22.04 + runs-on: ubuntu-latest steps: - name: Download Windows build uses: actions/download-artifact@v4 @@ -81,7 +148,7 @@ jobs: path: firmware_from_linux - name: Compare build files run: | - ls echo "Comparing build files" - git diff firmware_from_windows/main.hex firmware_from_linux/main.hex --word-diff=color --ignore-space-at-eol --exit-code + git diff firmware_from_windows/main.hex firmware_from_linux/main.hex --word-diff=color --ignore-space-at-eol --exit-code echo "Done comparing build files. Files are the same." + diff --git a/.gitignore b/.gitignore index 92277fbc..e9dfa54f 100644 --- a/.gitignore +++ b/.gitignore @@ -1,13 +1,18 @@ Debug - +__pycache__ **/*.launch -.vscode +.* +!.github tools/Java_Configurator_Source/ !tools/Java_Configurator_Source/src *.hex *.bin *.elf +*.dump +*.ctu-info src/Result.log bin/ experimental settings/ -releases/ \ No newline at end of file +releases/ +tests/sim/* +!_tsdz2.cdef \ No newline at end of file diff --git a/.vscode/extensions.json b/.vscode/extensions.json index 771a0969..413fb277 100644 --- a/.vscode/extensions.json +++ b/.vscode/extensions.json @@ -5,6 +5,7 @@ // List of extensions which should be recommended for users of this workspace. "recommendations": [ "ms-vscode.cpptools", - "cl.stm8-debug" + "ms-python.python", + "cl.stm8-debug", ] } \ No newline at end of file diff --git a/README.md b/README.md index 2116a30c..e40fec79 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,4 @@ -[![Build Action](../../actions/workflows/build.yaml/badge.svg)](../../actions/workflows/build.yaml) +![GitHub issues](https://img.shields.io/github/issues/emmebrusa/TSDZ2-Smart-EBike-1) [![Build Action](../../actions/workflows/build.yaml/badge.svg)](../../actions/workflows/build.yaml) This repository is updated by mbrusa. @@ -53,7 +53,27 @@ This project is being developed and maintained for free by a community of users. - install [cpptools](https://marketplace.visualstudio.com/items?itemName=ms-vscode.cpptools) - press F5 in VScode to build, flash, and debug (`STM8-gdb` profile) +## Testing +### Setup +Initialize virtual environment (optional):: + +`py -m venv .venv` + +Enable virtual environment or let VScode to do it automatically: + +`.venv\Scripts\activate` or `source .venv\Scripts\activate` + +Install dependencies: + +`pip install .` + +### Usage + +Run tests: + +`pytest` +Any changes should have a corresponding unit test added, unless unfeasible. ### Compile the firmware manually - `cd src/` and use `make` or `compile.bat` to compile the firmware. diff --git a/pyproject.toml b/pyproject.toml new file mode 100644 index 00000000..eadf8700 --- /dev/null +++ b/pyproject.toml @@ -0,0 +1,31 @@ +[build-system] +requires = ["hatchling"] +build-backend = "hatchling.build" + +[tool.hatch.build.targets.wheel] +packages = ["tests"] + +[project] +name = "TSDZ2-Smart-EBike" +version = "20.1C.6" +description = "TSDZ2 Open Source Firmware adapted to VLCD5-VLCD6-XH18 displays." +requires-python = ">=3.7" + +dependencies = [ + "pytest", + "cffi >=1.15.0", + "setuptools", + "numpy", + "hypothesis", +] + +[project.urls] +"Homepage" = "https://github.com/emmebrusa/TSDZ2-Smart-EBike-1" + +[tool.pyright] +extraPaths = ["tests"] + +[tool.pytest.ini_options] +addopts = [ + # "--ignore=tests/example", +] diff --git a/src/STM8S_StdPeriph_Lib/inc/stm8s.h b/src/STM8S_StdPeriph_Lib/inc/stm8s.h index fdc79cb9..4d35ded2 100644 --- a/src/STM8S_StdPeriph_Lib/inc/stm8s.h +++ b/src/STM8S_StdPeriph_Lib/inc/stm8s.h @@ -241,12 +241,12 @@ typedef uint16_t u16; typedef uint8_t u8; -typedef enum {RESET = 0, SET = !RESET} FlagStatus, ITStatus, BitStatus, BitAction; +typedef enum {RESET = 0, SET = 1} FlagStatus, ITStatus, BitStatus, BitAction; -typedef enum {DISABLE = 0, ENABLE = !DISABLE} FunctionalState; +typedef enum {DISABLE = 0, ENABLE = 1} FunctionalState; #define IS_FUNCTIONALSTATE_OK(STATE) (((STATE) == DISABLE) || ((STATE) == ENABLE)) -typedef enum {ERROR = 0, SUCCESS = !ERROR} ErrorStatus; +typedef enum {ERROR = 0, SUCCESS = 1} ErrorStatus; /** diff --git a/src/adc.c b/src/adc.c index 490525ee..12fb9b92 100644 --- a/src/adc.c +++ b/src/adc.c @@ -7,7 +7,6 @@ */ #include -#include #include "stm8s.h" #include "pins.h" #include "stm8s_adc1.h" diff --git a/src/motor.c b/src/motor.c index f402d896..a127c79d 100644 --- a/src/motor.c +++ b/src/motor.c @@ -554,7 +554,7 @@ void TIM1_CAP_COM_IRQHandler(void) __interrupt(TIM1_CAP_COM_IRQHANDLER) */ ld a, _ui8_temp+0 // ui8_svm_table_index is stored in ui8_temp - add a, #0x55 // ui8_temp = ui8_svm_table[(uint8_t) (ui8_svm_table_index + 85 /* 120ยบ */)]; + add a, #0x55 // ui8_temp = ui8_svm_table[(uint8_t) (ui8_svm_table_index + 85); /* 120deg */]; clrw x ld xl, a ld a, (_ui8_svm_table+0, x) diff --git a/src/motor.h b/src/motor.h index b0aca26d..3992fcc1 100644 --- a/src/motor.h +++ b/src/motor.h @@ -30,7 +30,6 @@ extern volatile uint8_t ui8_controller_duty_cycle_target; extern volatile uint16_t ui16_hall_calib_cnt[6]; extern volatile uint8_t ui8_hall_ref_angles[6]; extern volatile uint8_t ui8_hall_counter_offsets[6]; -extern volatile uint8_t ui8_hall_sensors_state; // Sensors extern volatile uint8_t ui8_brake_state; diff --git a/src/uart.c b/src/uart.c index 5805562b..e3adacbe 100644 --- a/src/uart.c +++ b/src/uart.c @@ -7,7 +7,6 @@ */ #include -#include #include "stm8s.h" #include "stm8s_uart2.h" diff --git a/tests/conftest.py b/tests/conftest.py new file mode 100644 index 00000000..b8fba28c --- /dev/null +++ b/tests/conftest.py @@ -0,0 +1,26 @@ +from load_c_code import load_code + +def pytest_sessionstart(session): + """ + Called after the Session object has been created and + before performing collection and entering the run test loop. + """ + load_code('_tsdz2') + + +def pytest_configure(config): + """ + This hook is called for every plugin and initial conftest + file after command line options have been parsed. + """ + +def pytest_sessionfinish(session, exitstatus): + """ + Called after whole test run finished, right before + returning the exit status to the system. + """ + +def pytest_unconfigure(config): + """ + called before test process is exited. + """ diff --git a/tests/load_c_code.py b/tests/load_c_code.py new file mode 100644 index 00000000..0445d0d0 --- /dev/null +++ b/tests/load_c_code.py @@ -0,0 +1,211 @@ +#!/usr/bin/python3 + +# Unit-Test C with Python: +# Based on https://cffi.readthedocs.io/en/latest/using.html + +import os +import shutil +import re +import subprocess +import cffi +from pycparser import c_ast, parse_file, c_generator, plyparser +from distutils import ccompiler +from typing import List +import importlib +import hashlib + +MOD_PATH = "sim" +LIB_DIR = 'tests/' + MOD_PATH + +source_dirs = ['src/'] # don't add hardware libraries +include_dirs = ["src/", "src/STM8S_StdPeriph_Lib/inc/"] +define_macros = ["STM8S105", "__CDT_PARSER__", ] +fake_defines = """ +#define __interrupt(x) +#define __asm__(x) +#define __trap +""" +compiler_args = ["-std=c99", "-Wall", "-Wextra"] +linker_args = [] +custom_parser = '' # actually don't use sdcpp as the cdef stdint definitions should match x86 platform + +# cffi uses the same compiler as distutils +# Adjust compiler arguments based on the detected compiler +if ccompiler.get_default_compiler() == "msvc": + compiler_args = [] # Windows msvc uses some funky flags + linker_args = [] + +class Checksum: + def __init__(self, hash_file_path, include_dirs, cdef): + self.hash_file_path = hash_file_path + self.include_dirs = include_dirs + self.cdef = cdef + + def __enter__(self): + self.previous_hash = "" + if os.path.exists(self.hash_file_path): + with open(self.hash_file_path, 'r') as f: + self.previous_hash = f.read().strip() + + sha256_hash = hashlib.sha256() + sha256_hash.update(self.cdef.encode()) + with open(__file__, "rb") as f: + sha256_hash.update(f.read()) + for include_dir in self.include_dirs: + for root, _, files in os.walk(include_dir): + for file in sorted(files): + if file.endswith(('.c', '.h')): + with open(os.path.join(root, file), "rb") as f: + for byte_block in iter(lambda: f.read(4096), b""): + sha256_hash.update(byte_block) # type: ignore + self.current_hash = sha256_hash.hexdigest() + return self.current_hash == self.previous_hash + + def __exit__(self, exc_type, exc_val, exc_tb): + if exc_type is None: + with open(self.hash_file_path, 'w') as f: + f.write(self.current_hash) + +def preprocess_ast(ast): + names = set() + for ext in ast.ext[:]: # Iterate over a copy of the list + if isinstance(ext, c_ast.Decl): + if ext.name in names: + ast.ext.remove(ext) + continue + else: + names.add(ext.name) + ext.init = None # remove initializations + if (isinstance(ext.type, c_ast.TypeDecl) or isinstance(ext.type, c_ast.PtrDecl) or isinstance(ext.type, c_ast.ArrayDecl)) and ext.storage == []: + ext.storage = ['extern'] + +class HeaderGenerator(c_generator.CGenerator): + def __init__(self, ast): + super().__init__() + self.typedef_dups = {} + self.src_ast = ast + + def visit_Decl(self, n, no_type=False): + result = super().visit_Decl(n, no_type) + if isinstance(n.type, c_ast.FuncDecl): + # Is a function declaration + if not any(isinstance(ext, c_ast.FuncDef) and ext.decl.name == n.name for ext in self.src_ast.ext): + # if not defined in source content, add Python+C decoration to allow mocking + result = 'extern "Python+C" ' + result + return result + + def visit_FuncDef(self, n): + return "" # don't generate function definitions + + def visit_Typedef(self, n, *args): + result = super().visit_Typedef(n) + # find duplicates enum typdefs and merge them into a single line, e.g: + # typedef enum {RESET = 0, SET = 1} FlagStatus, ITStatus, BitStatus; + self.typedef_dups[n.name] = [] + for ext in self.src_ast.ext: + if isinstance(ext, c_ast.Typedef): + if n.type.type == ext.type.type and n.name != ext.name: + # duplicate detected, check if it wasn't yet processed: + if not any([n.name in self.typedef_dups[type] for type in self.typedef_dups]): + self.typedef_dups[n.name].append(ext.name) + # inline the duplicate typedefs + result = result.replace(f"{'}'} {n.name}", f"{'}'} {n.name}, {ext.name}") + else: + return "" # don't generate duplicate typedefs that were already handled above + return result + +def generate_cdef(module_name, src_file): + # exceptions needed on some platforms (mingw) + skip_extensions = ["__attribute__(x)=", "__extension__=", "__MINGW_EXTENSION="] + skip_std_includes = ["_INC_STDIO", "_INC_STDDEF", "__STDDEF_H__", "_MATH_H_", "_INC_CORECRT",] + undef_macros = [] + std_include = [] + if shutil.which(custom_parser): + std_include.append(os.path.abspath(os.path.join(os.path.dirname(os.path.dirname(shutil.which(custom_parser))), "include"))) # type: ignore + cpp_path = custom_parser + else: + print("Parsing with 'cpp'") + cpp_path = 'cpp' + cpp_args = ["-xc"] + + idirs = [r'-I' + d for d in include_dirs + std_include] + ddefs = [r'-D' + d for d in define_macros + skip_std_includes + skip_extensions] + udefs = [r'-U' + d for d in undef_macros] + + args = idirs + ddefs + udefs + cpp_args + print("Parser args:", *args) + print("Generating AST...") + source_ast = parse_file(src_file, use_cpp=True, cpp_path=cpp_path, cpp_args=args) # type: ignore + print("Postporcess AST...") + preprocess_ast(source_ast) + print("generating cdef headers from AST...") + header_generator = HeaderGenerator(source_ast) + cdef = header_generator.visit(source_ast) + # remove all literal casting expressions like (uint8_t) as they are not supported by cffi.cdef + cdef = re.sub(r'\((uint8_t|uint16_t)\)\s*(\d+)', r'\2', cdef) + assert cdef != "" # cdef should not be empty + with open(os.path.join(LIB_DIR, f"{module_name}.cdef"), "w", encoding="utf8", newline="\n") as fp: + fp.write(f"// {module_name}.cdef - autogenerated by load_c_code.py\n") + fp.write("// do not commit if only system types has changed\n\n") + fp.write(cdef) + return cdef + + +def load_code(module_name, force_recompile=False): + # Load previous combined hash + hash_file_path = os.path.join(LIB_DIR, f"{module_name}.sha") + with Checksum(hash_file_path, source_dirs, module_name+"".join(define_macros)) as skip: + if not skip or force_recompile: + print("Collecting source code..") + source_content_list: List[str] = [] + source_files = [os.path.abspath(os.path.join(dir, file)) for dir in source_dirs for file in os.listdir(dir) if file.endswith('.c')] + for file_path in source_files: + print(file_path) + with open(file_path, encoding="utf8") as fp: + source_content_list.append(fp.read()) + combined_source: str = "\n".join(source_content_list) + combined_source = fake_defines + combined_source + combined_source = re.sub(r"#\s*include\s*<.*?>", r"//\g<0>", combined_source) # comment out standard includes + combined_source_file_path = os.path.join(LIB_DIR, f"{module_name}.i") + + with open(combined_source_file_path, "w", encoding="utf8") as fp: + fp.write(combined_source) + try: + cdef = generate_cdef(module_name, combined_source_file_path) + except (subprocess.CalledProcessError, RuntimeError, plyparser.ParseError) as e: + print(f"{e}\n\033[93mFailed to generate cdef using your cpp standard headers!!!\nYou may have to edit it manually. Continuing...\033[0m") + with open(os.path.join(LIB_DIR, f"{module_name}.cdef"), "r", encoding="utf8") as fp: + cdef = fp.read() + + # Create a CFFI instance + ffibuilder = cffi.FFI() + print("Processing cdefs...") + ffibuilder.cdef(cdef) + ffibuilder.set_source(module_name, combined_source, + include_dirs=[os.path.abspath(d) for d in include_dirs], + define_macros=[(macro, None) for macro in define_macros], + extra_compile_args=compiler_args, + extra_link_args=linker_args + ) + print("Compiling...") + tmpdir = os.path.abspath(LIB_DIR) + ffibuilder.compile(tmpdir=tmpdir) + else: + print("No changes found. Skipping compilation") + + + module_path = MOD_PATH + "." + module_name + print(f"Loading module: {module_path}") + try: + module = importlib.import_module(module_path) + except Exception as e: + os.remove(hash_file_path) + print(f"Failed to load module: {module_path}. Hash was cleared, so try running this script again.") + raise e + module_ffi : cffi.FFI = module.ffi # adds typing + return module.lib, module_ffi + + + +if __name__ == '__main__': + load_code("_tsdz2", force_recompile=True) diff --git a/tests/sim/_tsdz2.cdef b/tests/sim/_tsdz2.cdef new file mode 100644 index 00000000..2caa70d9 --- /dev/null +++ b/tests/sim/_tsdz2.cdef @@ -0,0 +1,2276 @@ +// _tsdz2.cdef - autogenerated by load_c_code.py +// do not commit if only system types has changed + +typedef signed char __int8_t; +typedef unsigned char __uint8_t; +typedef short int __int16_t; +typedef short unsigned int __uint16_t; +typedef int __int32_t; +typedef unsigned int __uint32_t; +typedef long int __int64_t; +typedef long unsigned int __uint64_t; +typedef signed char __int_least8_t; +typedef unsigned char __uint_least8_t; +typedef short int __int_least16_t; +typedef short unsigned int __uint_least16_t; +typedef int __int_least32_t; +typedef unsigned int __uint_least32_t; +typedef long int __int_least64_t; +typedef long unsigned int __uint_least64_t; +typedef long int __intmax_t; +typedef long unsigned int __uintmax_t; +typedef long int __intptr_t; +typedef long unsigned int __uintptr_t; +typedef __int8_t int8_t; +typedef __uint8_t uint8_t; +typedef __int16_t int16_t; +typedef __uint16_t uint16_t; +typedef __int32_t int32_t; +typedef __uint32_t uint32_t; +typedef __int64_t int64_t; +typedef __uint64_t uint64_t; +typedef __intmax_t intmax_t; +typedef __uintmax_t uintmax_t; +typedef __intptr_t intptr_t; +typedef __uintptr_t uintptr_t; +typedef __int_least8_t int_least8_t; +typedef __uint_least8_t uint_least8_t; +typedef __int_least16_t int_least16_t; +typedef __uint_least16_t uint_least16_t; +typedef __int_least32_t int_least32_t; +typedef __uint_least32_t uint_least32_t; +typedef __int_least64_t int_least64_t; +typedef __uint_least64_t uint_least64_t; +typedef signed char int_fast8_t; +typedef unsigned char uint_fast8_t; +typedef long int int_fast16_t; +typedef long unsigned int uint_fast16_t; +typedef long int int_fast32_t; +typedef long unsigned int uint_fast32_t; +typedef long int int_fast64_t; +typedef long unsigned int uint_fast64_t; +typedef int32_t s32; +typedef int16_t s16; +typedef int8_t s8; +typedef uint32_t u32; +typedef uint16_t u16; +typedef uint8_t u8; +typedef enum +{ + RESET = 0, + SET = 1 +} FlagStatus, BitAction, BitStatus, ITStatus; +; +; +; +typedef enum +{ + DISABLE = 0, + ENABLE = 1 +} FunctionalState; +typedef enum +{ + ERROR = 0, + SUCCESS = 1 +} ErrorStatus; +typedef struct GPIO_struct +{ + volatile uint8_t ODR; + volatile uint8_t IDR; + volatile uint8_t DDR; + volatile uint8_t CR1; + volatile uint8_t CR2; +} GPIO_TypeDef; +typedef struct ADC1_struct +{ + volatile uint8_t DB0RH; + volatile uint8_t DB0RL; + volatile uint8_t DB1RH; + volatile uint8_t DB1RL; + volatile uint8_t DB2RH; + volatile uint8_t DB2RL; + volatile uint8_t DB3RH; + volatile uint8_t DB3RL; + volatile uint8_t DB4RH; + volatile uint8_t DB4RL; + volatile uint8_t DB5RH; + volatile uint8_t DB5RL; + volatile uint8_t DB6RH; + volatile uint8_t DB6RL; + volatile uint8_t DB7RH; + volatile uint8_t DB7RL; + volatile uint8_t DB8RH; + volatile uint8_t DB8RL; + volatile uint8_t DB9RH; + volatile uint8_t DB9RL; + uint8_t RESERVED[12]; + volatile uint8_t CSR; + volatile uint8_t CR1; + volatile uint8_t CR2; + volatile uint8_t CR3; + volatile uint8_t DRH; + volatile uint8_t DRL; + volatile uint8_t TDRH; + volatile uint8_t TDRL; + volatile uint8_t HTRH; + volatile uint8_t HTRL; + volatile uint8_t LTRH; + volatile uint8_t LTRL; + volatile uint8_t AWSRH; + volatile uint8_t AWSRL; + volatile uint8_t AWCRH; + volatile uint8_t AWCRL; +} ADC1_TypeDef; +typedef struct AWU_struct +{ + volatile uint8_t CSR; + volatile uint8_t APR; + volatile uint8_t TBR; +} AWU_TypeDef; +typedef struct BEEP_struct +{ + volatile uint8_t CSR; +} BEEP_TypeDef; +typedef struct CLK_struct +{ + volatile uint8_t ICKR; + volatile uint8_t ECKR; + uint8_t RESERVED; + volatile uint8_t CMSR; + volatile uint8_t SWR; + volatile uint8_t SWCR; + volatile uint8_t CKDIVR; + volatile uint8_t PCKENR1; + volatile uint8_t CSSR; + volatile uint8_t CCOR; + volatile uint8_t PCKENR2; + uint8_t RESERVED1; + volatile uint8_t HSITRIMR; + volatile uint8_t SWIMCCR; +} CLK_TypeDef; +typedef struct TIM1_struct +{ + volatile uint8_t CR1; + volatile uint8_t CR2; + volatile uint8_t SMCR; + volatile uint8_t ETR; + volatile uint8_t IER; + volatile uint8_t SR1; + volatile uint8_t SR2; + volatile uint8_t EGR; + volatile uint8_t CCMR1; + volatile uint8_t CCMR2; + volatile uint8_t CCMR3; + volatile uint8_t CCMR4; + volatile uint8_t CCER1; + volatile uint8_t CCER2; + volatile uint8_t CNTRH; + volatile uint8_t CNTRL; + volatile uint8_t PSCRH; + volatile uint8_t PSCRL; + volatile uint8_t ARRH; + volatile uint8_t ARRL; + volatile uint8_t RCR; + volatile uint8_t CCR1H; + volatile uint8_t CCR1L; + volatile uint8_t CCR2H; + volatile uint8_t CCR2L; + volatile uint8_t CCR3H; + volatile uint8_t CCR3L; + volatile uint8_t CCR4H; + volatile uint8_t CCR4L; + volatile uint8_t BKR; + volatile uint8_t DTR; + volatile uint8_t OISR; +} TIM1_TypeDef; +typedef struct TIM2_struct +{ + volatile uint8_t CR1; + volatile uint8_t IER; + volatile uint8_t SR1; + volatile uint8_t SR2; + volatile uint8_t EGR; + volatile uint8_t CCMR1; + volatile uint8_t CCMR2; + volatile uint8_t CCMR3; + volatile uint8_t CCER1; + volatile uint8_t CCER2; + volatile uint8_t CNTRH; + volatile uint8_t CNTRL; + volatile uint8_t PSCR; + volatile uint8_t ARRH; + volatile uint8_t ARRL; + volatile uint8_t CCR1H; + volatile uint8_t CCR1L; + volatile uint8_t CCR2H; + volatile uint8_t CCR2L; + volatile uint8_t CCR3H; + volatile uint8_t CCR3L; +} TIM2_TypeDef; +typedef struct TIM3_struct +{ + volatile uint8_t CR1; + volatile uint8_t IER; + volatile uint8_t SR1; + volatile uint8_t SR2; + volatile uint8_t EGR; + volatile uint8_t CCMR1; + volatile uint8_t CCMR2; + volatile uint8_t CCER1; + volatile uint8_t CNTRH; + volatile uint8_t CNTRL; + volatile uint8_t PSCR; + volatile uint8_t ARRH; + volatile uint8_t ARRL; + volatile uint8_t CCR1H; + volatile uint8_t CCR1L; + volatile uint8_t CCR2H; + volatile uint8_t CCR2L; +} TIM3_TypeDef; +typedef struct TIM4_struct +{ + volatile uint8_t CR1; + volatile uint8_t IER; + volatile uint8_t SR1; + volatile uint8_t EGR; + volatile uint8_t CNTR; + volatile uint8_t PSCR; + volatile uint8_t ARR; +} TIM4_TypeDef; +typedef struct TIM5_struct +{ + volatile uint8_t CR1; + volatile uint8_t CR2; + volatile uint8_t SMCR; + volatile uint8_t IER; + volatile uint8_t SR1; + volatile uint8_t SR2; + volatile uint8_t EGR; + volatile uint8_t CCMR1; + volatile uint8_t CCMR2; + volatile uint8_t CCMR3; + volatile uint8_t CCER1; + volatile uint8_t CCER2; + volatile uint8_t CNTRH; + volatile uint8_t CNTRL; + volatile uint8_t PSCR; + volatile uint8_t ARRH; + volatile uint8_t ARRL; + volatile uint8_t CCR1H; + volatile uint8_t CCR1L; + volatile uint8_t CCR2H; + volatile uint8_t CCR2L; + volatile uint8_t CCR3H; + volatile uint8_t CCR3L; +} TIM5_TypeDef; +typedef struct TIM6_struct +{ + volatile uint8_t CR1; + volatile uint8_t CR2; + volatile uint8_t SMCR; + volatile uint8_t IER; + volatile uint8_t SR1; + volatile uint8_t EGR; + volatile uint8_t CNTR; + volatile uint8_t PSCR; + volatile uint8_t ARR; +} TIM6_TypeDef; +typedef struct I2C_struct +{ + volatile uint8_t CR1; + volatile uint8_t CR2; + volatile uint8_t FREQR; + volatile uint8_t OARL; + volatile uint8_t OARH; + uint8_t RESERVED1; + volatile uint8_t DR; + volatile uint8_t SR1; + volatile uint8_t SR2; + volatile uint8_t SR3; + volatile uint8_t ITR; + volatile uint8_t CCRL; + volatile uint8_t CCRH; + volatile uint8_t TRISER; + uint8_t RESERVED2; +} I2C_TypeDef; +typedef struct ITC_struct +{ + volatile uint8_t ISPR1; + volatile uint8_t ISPR2; + volatile uint8_t ISPR3; + volatile uint8_t ISPR4; + volatile uint8_t ISPR5; + volatile uint8_t ISPR6; + volatile uint8_t ISPR7; + volatile uint8_t ISPR8; +} ITC_TypeDef; +typedef struct EXTI_struct +{ + volatile uint8_t CR1; + volatile uint8_t CR2; +} EXTI_TypeDef; +typedef struct FLASH_struct +{ + volatile uint8_t CR1; + volatile uint8_t CR2; + volatile uint8_t NCR2; + volatile uint8_t FPR; + volatile uint8_t NFPR; + volatile uint8_t IAPSR; + uint8_t RESERVED1; + uint8_t RESERVED2; + volatile uint8_t PUKR; + uint8_t RESERVED3; + volatile uint8_t DUKR; +} FLASH_TypeDef; +typedef struct OPT_struct +{ + volatile uint8_t OPT0; + volatile uint8_t OPT1; + volatile uint8_t NOPT1; + volatile uint8_t OPT2; + volatile uint8_t NOPT2; + volatile uint8_t OPT3; + volatile uint8_t NOPT3; + volatile uint8_t OPT4; + volatile uint8_t NOPT4; + volatile uint8_t OPT5; + volatile uint8_t NOPT5; + uint8_t RESERVED1; + uint8_t RESERVED2; + volatile uint8_t OPT7; + volatile uint8_t NOPT7; +} OPT_TypeDef; +typedef struct IWDG_struct +{ + volatile uint8_t KR; + volatile uint8_t PR; + volatile uint8_t RLR; +} IWDG_TypeDef; +typedef struct WWDG_struct +{ + volatile uint8_t CR; + volatile uint8_t WR; +} WWDG_TypeDef; +typedef struct RST_struct +{ + volatile uint8_t SR; +} RST_TypeDef; +typedef struct SPI_struct +{ + volatile uint8_t CR1; + volatile uint8_t CR2; + volatile uint8_t ICR; + volatile uint8_t SR; + volatile uint8_t DR; + volatile uint8_t CRCPR; + volatile uint8_t RXCRCR; + volatile uint8_t TXCRCR; +} SPI_TypeDef; +typedef struct UART1_struct +{ + volatile uint8_t SR; + volatile uint8_t DR; + volatile uint8_t BRR1; + volatile uint8_t BRR2; + volatile uint8_t CR1; + volatile uint8_t CR2; + volatile uint8_t CR3; + volatile uint8_t CR4; + volatile uint8_t CR5; + volatile uint8_t GTR; + volatile uint8_t PSCR; +} UART1_TypeDef; +typedef struct UART2_struct +{ + volatile uint8_t SR; + volatile uint8_t DR; + volatile uint8_t BRR1; + volatile uint8_t BRR2; + volatile uint8_t CR1; + volatile uint8_t CR2; + volatile uint8_t CR3; + volatile uint8_t CR4; + volatile uint8_t CR5; + volatile uint8_t CR6; + volatile uint8_t GTR; + volatile uint8_t PSCR; +} UART2_TypeDef; +typedef struct UART3_struct +{ + volatile uint8_t SR; + volatile uint8_t DR; + volatile uint8_t BRR1; + volatile uint8_t BRR2; + volatile uint8_t CR1; + volatile uint8_t CR2; + volatile uint8_t CR3; + volatile uint8_t CR4; + uint8_t RESERVED; + volatile uint8_t CR6; +} UART3_TypeDef; +typedef struct +{ + volatile uint8_t MCR; + volatile uint8_t MSR; + volatile uint8_t TSR; + volatile uint8_t TPR; + volatile uint8_t RFR; + volatile uint8_t IER; + volatile uint8_t DGR; + volatile uint8_t PSR; + union + { + struct + { + volatile uint8_t MCSR; + volatile uint8_t MDLCR; + volatile uint8_t MIDR1; + volatile uint8_t MIDR2; + volatile uint8_t MIDR3; + volatile uint8_t MIDR4; + volatile uint8_t MDAR1; + volatile uint8_t MDAR2; + volatile uint8_t MDAR3; + volatile uint8_t MDAR4; + volatile uint8_t MDAR5; + volatile uint8_t MDAR6; + volatile uint8_t MDAR7; + volatile uint8_t MDAR8; + volatile uint8_t MTSRL; + volatile uint8_t MTSRH; + } TxMailbox; + struct + { + volatile uint8_t FR01; + volatile uint8_t FR02; + volatile uint8_t FR03; + volatile uint8_t FR04; + volatile uint8_t FR05; + volatile uint8_t FR06; + volatile uint8_t FR07; + volatile uint8_t FR08; + volatile uint8_t FR09; + volatile uint8_t FR10; + volatile uint8_t FR11; + volatile uint8_t FR12; + volatile uint8_t FR13; + volatile uint8_t FR14; + volatile uint8_t FR15; + volatile uint8_t FR16; + } Filter; + struct + { + volatile uint8_t F0R1; + volatile uint8_t F0R2; + volatile uint8_t F0R3; + volatile uint8_t F0R4; + volatile uint8_t F0R5; + volatile uint8_t F0R6; + volatile uint8_t F0R7; + volatile uint8_t F0R8; + volatile uint8_t F1R1; + volatile uint8_t F1R2; + volatile uint8_t F1R3; + volatile uint8_t F1R4; + volatile uint8_t F1R5; + volatile uint8_t F1R6; + volatile uint8_t F1R7; + volatile uint8_t F1R8; + } Filter01; + struct + { + volatile uint8_t F2R1; + volatile uint8_t F2R2; + volatile uint8_t F2R3; + volatile uint8_t F2R4; + volatile uint8_t F2R5; + volatile uint8_t F2R6; + volatile uint8_t F2R7; + volatile uint8_t F2R8; + volatile uint8_t F3R1; + volatile uint8_t F3R2; + volatile uint8_t F3R3; + volatile uint8_t F3R4; + volatile uint8_t F3R5; + volatile uint8_t F3R6; + volatile uint8_t F3R7; + volatile uint8_t F3R8; + } Filter23; + struct + { + volatile uint8_t F4R1; + volatile uint8_t F4R2; + volatile uint8_t F4R3; + volatile uint8_t F4R4; + volatile uint8_t F4R5; + volatile uint8_t F4R6; + volatile uint8_t F4R7; + volatile uint8_t F4R8; + volatile uint8_t F5R1; + volatile uint8_t F5R2; + volatile uint8_t F5R3; + volatile uint8_t F5R4; + volatile uint8_t F5R5; + volatile uint8_t F5R6; + volatile uint8_t F5R7; + volatile uint8_t F5R8; + } Filter45; + struct + { + volatile uint8_t ESR; + volatile uint8_t EIER; + volatile uint8_t TECR; + volatile uint8_t RECR; + volatile uint8_t BTR1; + volatile uint8_t BTR2; + uint8_t Reserved1[2]; + volatile uint8_t FMR1; + volatile uint8_t FMR2; + volatile uint8_t FCR1; + volatile uint8_t FCR2; + volatile uint8_t FCR3; + uint8_t Reserved2[3]; + } Config; + struct + { + volatile uint8_t MFMI; + volatile uint8_t MDLCR; + volatile uint8_t MIDR1; + volatile uint8_t MIDR2; + volatile uint8_t MIDR3; + volatile uint8_t MIDR4; + volatile uint8_t MDAR1; + volatile uint8_t MDAR2; + volatile uint8_t MDAR3; + volatile uint8_t MDAR4; + volatile uint8_t MDAR5; + volatile uint8_t MDAR6; + volatile uint8_t MDAR7; + volatile uint8_t MDAR8; + volatile uint8_t MTSRL; + volatile uint8_t MTSRH; + } RxFIFO; + } Page; +} CAN_TypeDef; +typedef struct CFG_struct +{ + volatile uint8_t GCR; +} CFG_TypeDef; +typedef enum +{ + ADC1_PRESSEL_FCPU_D2 = 0x00, + ADC1_PRESSEL_FCPU_D3 = 0x10, + ADC1_PRESSEL_FCPU_D4 = 0x20, + ADC1_PRESSEL_FCPU_D6 = 0x30, + ADC1_PRESSEL_FCPU_D8 = 0x40, + ADC1_PRESSEL_FCPU_D10 = 0x50, + ADC1_PRESSEL_FCPU_D12 = 0x60, + ADC1_PRESSEL_FCPU_D18 = 0x70 +} ADC1_PresSel_TypeDef; +typedef enum +{ + ADC1_EXTTRIG_TIM = 0x00, + ADC1_EXTTRIG_GPIO = 0x10 +} ADC1_ExtTrig_TypeDef; +typedef enum +{ + ADC1_ALIGN_LEFT = 0x00, + ADC1_ALIGN_RIGHT = 0x08 +} ADC1_Align_TypeDef; +typedef enum +{ + ADC1_IT_AWDIE = 0x010, + ADC1_IT_EOCIE = 0x020, + ADC1_IT_AWD = 0x140, + ADC1_IT_AWS0 = 0x110, + ADC1_IT_AWS1 = 0x111, + ADC1_IT_AWS2 = 0x112, + ADC1_IT_AWS3 = 0x113, + ADC1_IT_AWS4 = 0x114, + ADC1_IT_AWS5 = 0x115, + ADC1_IT_AWS6 = 0x116, + ADC1_IT_AWS7 = 0x117, + ADC1_IT_AWS8 = 0x118, + ADC1_IT_AWS9 = 0x119, + ADC1_IT_AWS12 = 0x11C, + ADC1_IT_EOC = 0x080 +} ADC1_IT_TypeDef; +typedef enum +{ + ADC1_FLAG_OVR = 0x41, + ADC1_FLAG_AWD = 0x40, + ADC1_FLAG_AWS0 = 0x10, + ADC1_FLAG_AWS1 = 0x11, + ADC1_FLAG_AWS2 = 0x12, + ADC1_FLAG_AWS3 = 0x13, + ADC1_FLAG_AWS4 = 0x14, + ADC1_FLAG_AWS5 = 0x15, + ADC1_FLAG_AWS6 = 0x16, + ADC1_FLAG_AWS7 = 0x17, + ADC1_FLAG_AWS8 = 0x18, + ADC1_FLAG_AWS9 = 0x19, + ADC1_FLAG_AWS12 = 0x1C, + ADC1_FLAG_EOC = 0x80 +} ADC1_Flag_TypeDef; +typedef enum +{ + ADC1_SCHMITTTRIG_CHANNEL0 = 0x00, + ADC1_SCHMITTTRIG_CHANNEL1 = 0x01, + ADC1_SCHMITTTRIG_CHANNEL2 = 0x02, + ADC1_SCHMITTTRIG_CHANNEL3 = 0x03, + ADC1_SCHMITTTRIG_CHANNEL4 = 0x04, + ADC1_SCHMITTTRIG_CHANNEL5 = 0x05, + ADC1_SCHMITTTRIG_CHANNEL6 = 0x06, + ADC1_SCHMITTTRIG_CHANNEL7 = 0x07, + ADC1_SCHMITTTRIG_CHANNEL8 = 0x08, + ADC1_SCHMITTTRIG_CHANNEL9 = 0x09, + ADC1_SCHMITTTRIG_CHANNEL12 = 0x0C, + ADC1_SCHMITTTRIG_ALL = 0xFF +} ADC1_SchmittTrigg_TypeDef; +typedef enum +{ + ADC1_CONVERSIONMODE_SINGLE = 0x00, + ADC1_CONVERSIONMODE_CONTINUOUS = 0x01 +} ADC1_ConvMode_TypeDef; +typedef enum +{ + ADC1_CHANNEL_0 = 0x00, + ADC1_CHANNEL_1 = 0x01, + ADC1_CHANNEL_2 = 0x02, + ADC1_CHANNEL_3 = 0x03, + ADC1_CHANNEL_4 = 0x04, + ADC1_CHANNEL_5 = 0x05, + ADC1_CHANNEL_6 = 0x06, + ADC1_CHANNEL_7 = 0x07, + ADC1_CHANNEL_8 = 0x08, + ADC1_CHANNEL_9 = 0x09, + ADC1_CHANNEL_12 = 0x0C +} ADC1_Channel_TypeDef; +extern "Python+C" void ADC1_DeInit(void); +extern "Python+C" void ADC1_Init(ADC1_ConvMode_TypeDef ADC1_ConversionMode, ADC1_Channel_TypeDef ADC1_Channel, ADC1_PresSel_TypeDef ADC1_PrescalerSelection, ADC1_ExtTrig_TypeDef ADC1_ExtTrigger, FunctionalState ADC1_ExtTriggerState, ADC1_Align_TypeDef ADC1_Align, ADC1_SchmittTrigg_TypeDef ADC1_SchmittTriggerChannel, FunctionalState ADC1_SchmittTriggerState); +extern "Python+C" void ADC1_Cmd(FunctionalState NewState); +extern "Python+C" void ADC1_ScanModeCmd(FunctionalState NewState); +extern "Python+C" void ADC1_DataBufferCmd(FunctionalState NewState); +extern "Python+C" void ADC1_ITConfig(ADC1_IT_TypeDef ADC1_IT, FunctionalState NewState); +extern "Python+C" void ADC1_PrescalerConfig(ADC1_PresSel_TypeDef ADC1_Prescaler); +extern "Python+C" void ADC1_SchmittTriggerConfig(ADC1_SchmittTrigg_TypeDef ADC1_SchmittTriggerChannel, FunctionalState NewState); +extern "Python+C" void ADC1_ConversionConfig(ADC1_ConvMode_TypeDef ADC1_ConversionMode, ADC1_Channel_TypeDef ADC1_Channel, ADC1_Align_TypeDef ADC1_Align); +extern "Python+C" void ADC1_ExternalTriggerConfig(ADC1_ExtTrig_TypeDef ADC1_ExtTrigger, FunctionalState NewState); +extern "Python+C" void ADC1_AWDChannelConfig(ADC1_Channel_TypeDef Channel, FunctionalState NewState); +extern "Python+C" void ADC1_StartConversion(void); +extern "Python+C" uint16_t ADC1_GetConversionValue(void); +extern "Python+C" void ADC1_SetHighThreshold(uint16_t Threshold); +extern "Python+C" void ADC1_SetLowThreshold(uint16_t Threshold); +extern "Python+C" uint16_t ADC1_GetBufferValue(uint8_t Buffer); +extern "Python+C" FlagStatus ADC1_GetAWDChannelStatus(ADC1_Channel_TypeDef Channel); +extern "Python+C" FlagStatus ADC1_GetFlagStatus(ADC1_Flag_TypeDef Flag); +extern "Python+C" void ADC1_ClearFlag(ADC1_Flag_TypeDef Flag); +extern "Python+C" ITStatus ADC1_GetITStatus(ADC1_IT_TypeDef ITPendingBit); +extern "Python+C" void ADC1_ClearITPendingBit(ADC1_IT_TypeDef ITPendingBit); +typedef enum +{ + AWU_TIMEBASE_NO_IT = 0, + AWU_TIMEBASE_250US = 1, + AWU_TIMEBASE_500US = 2, + AWU_TIMEBASE_1MS = 3, + AWU_TIMEBASE_2MS = 4, + AWU_TIMEBASE_4MS = 5, + AWU_TIMEBASE_8MS = 6, + AWU_TIMEBASE_16MS = 7, + AWU_TIMEBASE_32MS = 8, + AWU_TIMEBASE_64MS = 9, + AWU_TIMEBASE_128MS = 10, + AWU_TIMEBASE_256MS = 11, + AWU_TIMEBASE_512MS = 12, + AWU_TIMEBASE_1S = 13, + AWU_TIMEBASE_2S = 14, + AWU_TIMEBASE_12S = 15, + AWU_TIMEBASE_30S = 16 +} AWU_Timebase_TypeDef; +extern "Python+C" void AWU_DeInit(void); +extern "Python+C" void AWU_Init(AWU_Timebase_TypeDef AWU_TimeBase); +extern "Python+C" void AWU_Cmd(FunctionalState NewState); +extern "Python+C" void AWU_LSICalibrationConfig(uint32_t LSIFreqHz); +extern "Python+C" void AWU_IdleModeEnable(void); +extern "Python+C" FlagStatus AWU_GetFlagStatus(void); +typedef enum +{ + BEEP_FREQUENCY_1KHZ = 0x00, + BEEP_FREQUENCY_2KHZ = 0x40, + BEEP_FREQUENCY_4KHZ = 0x80 +} BEEP_Frequency_TypeDef; +extern "Python+C" void BEEP_DeInit(void); +extern "Python+C" void BEEP_Init(BEEP_Frequency_TypeDef BEEP_Frequency); +extern "Python+C" void BEEP_Cmd(FunctionalState NewState); +extern "Python+C" void BEEP_LSICalibrationConfig(uint32_t LSIFreqHz); +typedef enum +{ + CLK_SWITCHMODE_MANUAL = 0x00, + CLK_SWITCHMODE_AUTO = 0x01 +} CLK_SwitchMode_TypeDef; +typedef enum +{ + CLK_CURRENTCLOCKSTATE_DISABLE = 0x00, + CLK_CURRENTCLOCKSTATE_ENABLE = 0x01 +} CLK_CurrentClockState_TypeDef; +typedef enum +{ + CLK_CSSCONFIG_ENABLEWITHIT = 0x05, + CLK_CSSCONFIG_ENABLE = 0x01, + CLK_CSSCONFIG_DISABLE = 0x00 +} CLK_CSSConfig_TypeDef; +typedef enum +{ + CLK_SOURCE_HSI = 0xE1, + CLK_SOURCE_LSI = 0xD2, + CLK_SOURCE_HSE = 0xB4 +} CLK_Source_TypeDef; +typedef enum +{ + CLK_HSITRIMVALUE_0 = 0x00, + CLK_HSITRIMVALUE_1 = 0x01, + CLK_HSITRIMVALUE_2 = 0x02, + CLK_HSITRIMVALUE_3 = 0x03, + CLK_HSITRIMVALUE_4 = 0x04, + CLK_HSITRIMVALUE_5 = 0x05, + CLK_HSITRIMVALUE_6 = 0x06, + CLK_HSITRIMVALUE_7 = 0x07 +} CLK_HSITrimValue_TypeDef; +typedef enum +{ + CLK_OUTPUT_HSI = 0x00, + CLK_OUTPUT_LSI = 0x02, + CLK_OUTPUT_HSE = 0x04, + CLK_OUTPUT_CPU = 0x08, + CLK_OUTPUT_CPUDIV2 = 0x0A, + CLK_OUTPUT_CPUDIV4 = 0x0C, + CLK_OUTPUT_CPUDIV8 = 0x0E, + CLK_OUTPUT_CPUDIV16 = 0x10, + CLK_OUTPUT_CPUDIV32 = 0x12, + CLK_OUTPUT_CPUDIV64 = 0x14, + CLK_OUTPUT_HSIRC = 0x16, + CLK_OUTPUT_MASTER = 0x18, + CLK_OUTPUT_OTHERS = 0x1A +} CLK_Output_TypeDef; +typedef enum +{ + CLK_PERIPHERAL_I2C = 0x00, + CLK_PERIPHERAL_SPI = 0x01, + CLK_PERIPHERAL_UART1 = 0x03, + CLK_PERIPHERAL_UART2 = 0x03, + CLK_PERIPHERAL_UART3 = 0x03, + CLK_PERIPHERAL_TIMER6 = 0x04, + CLK_PERIPHERAL_TIMER4 = 0x04, + CLK_PERIPHERAL_TIMER5 = 0x05, + CLK_PERIPHERAL_TIMER2 = 0x05, + CLK_PERIPHERAL_TIMER3 = 0x06, + CLK_PERIPHERAL_TIMER1 = 0x07, + CLK_PERIPHERAL_AWU = 0x12, + CLK_PERIPHERAL_ADC = 0x13, + CLK_PERIPHERAL_CAN = 0x17 +} CLK_Peripheral_TypeDef; +typedef enum +{ + CLK_FLAG_LSIRDY = 0x0110, + CLK_FLAG_HSIRDY = 0x0102, + CLK_FLAG_HSERDY = 0x0202, + CLK_FLAG_SWIF = 0x0308, + CLK_FLAG_SWBSY = 0x0301, + CLK_FLAG_CSSD = 0x0408, + CLK_FLAG_AUX = 0x0402, + CLK_FLAG_CCOBSY = 0x0504, + CLK_FLAG_CCORDY = 0x0502 +} CLK_Flag_TypeDef; +typedef enum +{ + CLK_IT_CSSD = 0x0C, + CLK_IT_SWIF = 0x1C +} CLK_IT_TypeDef; +typedef enum +{ + CLK_PRESCALER_HSIDIV1 = 0x00, + CLK_PRESCALER_HSIDIV2 = 0x08, + CLK_PRESCALER_HSIDIV4 = 0x10, + CLK_PRESCALER_HSIDIV8 = 0x18, + CLK_PRESCALER_CPUDIV1 = 0x80, + CLK_PRESCALER_CPUDIV2 = 0x81, + CLK_PRESCALER_CPUDIV4 = 0x82, + CLK_PRESCALER_CPUDIV8 = 0x83, + CLK_PRESCALER_CPUDIV16 = 0x84, + CLK_PRESCALER_CPUDIV32 = 0x85, + CLK_PRESCALER_CPUDIV64 = 0x86, + CLK_PRESCALER_CPUDIV128 = 0x87 +} CLK_Prescaler_TypeDef; +typedef enum +{ + CLK_SWIMDIVIDER_2 = 0x00, + CLK_SWIMDIVIDER_OTHER = 0x01 +} CLK_SWIMDivider_TypeDef; +extern "Python+C" void CLK_DeInit(void); +extern "Python+C" void CLK_HSECmd(FunctionalState NewState); +extern "Python+C" void CLK_HSICmd(FunctionalState NewState); +extern "Python+C" void CLK_LSICmd(FunctionalState NewState); +extern "Python+C" void CLK_CCOCmd(FunctionalState NewState); +extern "Python+C" void CLK_ClockSwitchCmd(FunctionalState NewState); +extern "Python+C" void CLK_FastHaltWakeUpCmd(FunctionalState NewState); +extern "Python+C" void CLK_SlowActiveHaltWakeUpCmd(FunctionalState NewState); +extern "Python+C" void CLK_PeripheralClockConfig(CLK_Peripheral_TypeDef CLK_Peripheral, FunctionalState NewState); +extern "Python+C" ErrorStatus CLK_ClockSwitchConfig(CLK_SwitchMode_TypeDef CLK_SwitchMode, CLK_Source_TypeDef CLK_NewClock, FunctionalState ITState, CLK_CurrentClockState_TypeDef CLK_CurrentClockState); +extern "Python+C" void CLK_HSIPrescalerConfig(CLK_Prescaler_TypeDef HSIPrescaler); +extern "Python+C" void CLK_CCOConfig(CLK_Output_TypeDef CLK_CCO); +extern "Python+C" void CLK_ITConfig(CLK_IT_TypeDef CLK_IT, FunctionalState NewState); +extern "Python+C" void CLK_SYSCLKConfig(CLK_Prescaler_TypeDef CLK_Prescaler); +extern "Python+C" void CLK_SWIMConfig(CLK_SWIMDivider_TypeDef CLK_SWIMDivider); +extern "Python+C" void CLK_ClockSecuritySystemEnable(void); +extern "Python+C" void CLK_SYSCLKEmergencyClear(void); +extern "Python+C" void CLK_AdjustHSICalibrationValue(CLK_HSITrimValue_TypeDef CLK_HSICalibrationValue); +extern "Python+C" uint32_t CLK_GetClockFreq(void); +extern "Python+C" CLK_Source_TypeDef CLK_GetSYSCLKSource(void); +extern "Python+C" FlagStatus CLK_GetFlagStatus(CLK_Flag_TypeDef CLK_FLAG); +extern "Python+C" ITStatus CLK_GetITStatus(CLK_IT_TypeDef CLK_IT); +extern "Python+C" void CLK_ClearITPendingBit(CLK_IT_TypeDef CLK_IT); +typedef enum +{ + EXTI_SENSITIVITY_FALL_LOW = 0x00, + EXTI_SENSITIVITY_RISE_ONLY = 0x01, + EXTI_SENSITIVITY_FALL_ONLY = 0x02, + EXTI_SENSITIVITY_RISE_FALL = 0x03 +} EXTI_Sensitivity_TypeDef; +typedef enum +{ + EXTI_TLISENSITIVITY_FALL_ONLY = 0x00, + EXTI_TLISENSITIVITY_RISE_ONLY = 0x04 +} EXTI_TLISensitivity_TypeDef; +typedef enum +{ + EXTI_PORT_GPIOA = 0x00, + EXTI_PORT_GPIOB = 0x01, + EXTI_PORT_GPIOC = 0x02, + EXTI_PORT_GPIOD = 0x03, + EXTI_PORT_GPIOE = 0x04 +} EXTI_Port_TypeDef; +extern "Python+C" void EXTI_DeInit(void); +extern "Python+C" void EXTI_SetExtIntSensitivity(EXTI_Port_TypeDef Port, EXTI_Sensitivity_TypeDef SensitivityValue); +extern "Python+C" void EXTI_SetTLISensitivity(EXTI_TLISensitivity_TypeDef SensitivityValue); +extern "Python+C" EXTI_Sensitivity_TypeDef EXTI_GetExtIntSensitivity(EXTI_Port_TypeDef Port); +extern "Python+C" EXTI_TLISensitivity_TypeDef EXTI_GetTLISensitivity(void); +typedef enum +{ + FLASH_MEMTYPE_PROG = 0xFD, + FLASH_MEMTYPE_DATA = 0xF7 +} FLASH_MemType_TypeDef; +typedef enum +{ + FLASH_PROGRAMMODE_STANDARD = 0x00, + FLASH_PROGRAMMODE_FAST = 0x10 +} FLASH_ProgramMode_TypeDef; +typedef enum +{ + FLASH_PROGRAMTIME_STANDARD = 0x00, + FLASH_PROGRAMTIME_TPROG = 0x01 +} FLASH_ProgramTime_TypeDef; +typedef enum +{ + FLASH_LPMODE_POWERDOWN = 0x04, + FLASH_LPMODE_STANDBY = 0x08, + FLASH_LPMODE_POWERDOWN_STANDBY = 0x00, + FLASH_LPMODE_STANDBY_POWERDOWN = 0x0C +} FLASH_LPMode_TypeDef; +typedef enum +{ + FLASH_STATUS_END_HIGH_VOLTAGE = 0x40, + FLASH_STATUS_SUCCESSFUL_OPERATION = 0x04, + FLASH_STATUS_TIMEOUT = 0x02, + FLASH_STATUS_WRITE_PROTECTION_ERROR = 0x01 +} FLASH_Status_TypeDef; +typedef enum +{ + FLASH_FLAG_HVOFF = 0x40, + FLASH_FLAG_DUL = 0x08, + FLASH_FLAG_EOP = 0x04, + FLASH_FLAG_PUL = 0x02, + FLASH_FLAG_WR_PG_DIS = 0x01 +} FLASH_Flag_TypeDef; +extern "Python+C" void FLASH_Unlock(FLASH_MemType_TypeDef FLASH_MemType); +extern "Python+C" void FLASH_Lock(FLASH_MemType_TypeDef FLASH_MemType); +extern "Python+C" void FLASH_DeInit(void); +extern "Python+C" void FLASH_ITConfig(FunctionalState NewState); +extern "Python+C" void FLASH_EraseByte(uint32_t Address); +extern "Python+C" void FLASH_ProgramByte(uint32_t Address, uint8_t Data); +extern "Python+C" uint8_t FLASH_ReadByte(uint32_t Address); +extern "Python+C" void FLASH_ProgramWord(uint32_t Address, uint32_t Data); +extern "Python+C" uint16_t FLASH_ReadOptionByte(uint16_t Address); +extern "Python+C" void FLASH_ProgramOptionByte(uint16_t Address, uint8_t Data); +extern "Python+C" void FLASH_EraseOptionByte(uint16_t Address); +extern "Python+C" void FLASH_SetLowPowerMode(FLASH_LPMode_TypeDef FLASH_LPMode); +extern "Python+C" void FLASH_SetProgrammingTime(FLASH_ProgramTime_TypeDef FLASH_ProgTime); +extern "Python+C" FLASH_LPMode_TypeDef FLASH_GetLowPowerMode(void); +extern "Python+C" FLASH_ProgramTime_TypeDef FLASH_GetProgrammingTime(void); +extern "Python+C" uint32_t FLASH_GetBootSize(void); +extern "Python+C" FlagStatus FLASH_GetFlagStatus(FLASH_Flag_TypeDef FLASH_FLAG); +extern "Python+C" void FLASH_EraseBlock(uint16_t BlockNum, FLASH_MemType_TypeDef FLASH_MemType); +extern "Python+C" void FLASH_ProgramBlock(uint16_t BlockNum, FLASH_MemType_TypeDef FLASH_MemType, FLASH_ProgramMode_TypeDef FLASH_ProgMode, uint8_t *Buffer); +extern "Python+C" FLASH_Status_TypeDef FLASH_WaitForLastOperation(FLASH_MemType_TypeDef FLASH_MemType); +typedef enum +{ + GPIO_MODE_IN_FL_NO_IT = 0x00, + GPIO_MODE_IN_PU_NO_IT = 0x40, + GPIO_MODE_IN_FL_IT = 0x20, + GPIO_MODE_IN_PU_IT = 0x60, + GPIO_MODE_OUT_OD_LOW_FAST = 0xA0, + GPIO_MODE_OUT_PP_LOW_FAST = 0xE0, + GPIO_MODE_OUT_OD_LOW_SLOW = 0x80, + GPIO_MODE_OUT_PP_LOW_SLOW = 0xC0, + GPIO_MODE_OUT_OD_HIZ_FAST = 0xB0, + GPIO_MODE_OUT_PP_HIGH_FAST = 0xF0, + GPIO_MODE_OUT_OD_HIZ_SLOW = 0x90, + GPIO_MODE_OUT_PP_HIGH_SLOW = 0xD0 +} GPIO_Mode_TypeDef; +typedef enum +{ + GPIO_PIN_0 = 0x01, + GPIO_PIN_1 = 0x02, + GPIO_PIN_2 = 0x04, + GPIO_PIN_3 = 0x08, + GPIO_PIN_4 = 0x10, + GPIO_PIN_5 = 0x20, + GPIO_PIN_6 = 0x40, + GPIO_PIN_7 = 0x80, + GPIO_PIN_LNIB = 0x0F, + GPIO_PIN_HNIB = 0xF0, + GPIO_PIN_ALL = 0xFF +} GPIO_Pin_TypeDef; +extern "Python+C" void GPIO_DeInit(GPIO_TypeDef *GPIOx); +extern "Python+C" void GPIO_Init(GPIO_TypeDef *GPIOx, GPIO_Pin_TypeDef GPIO_Pin, GPIO_Mode_TypeDef GPIO_Mode); +extern "Python+C" void GPIO_Write(GPIO_TypeDef *GPIOx, uint8_t PortVal); +extern "Python+C" void GPIO_WriteHigh(GPIO_TypeDef *GPIOx, GPIO_Pin_TypeDef PortPins); +extern "Python+C" void GPIO_WriteLow(GPIO_TypeDef *GPIOx, GPIO_Pin_TypeDef PortPins); +extern "Python+C" void GPIO_WriteReverse(GPIO_TypeDef *GPIOx, GPIO_Pin_TypeDef PortPins); +extern "Python+C" uint8_t GPIO_ReadInputData(GPIO_TypeDef *GPIOx); +extern "Python+C" uint8_t GPIO_ReadOutputData(GPIO_TypeDef *GPIOx); +extern "Python+C" BitStatus GPIO_ReadInputPin(GPIO_TypeDef *GPIOx, GPIO_Pin_TypeDef GPIO_Pin); +extern "Python+C" void GPIO_ExternalPullUpConfig(GPIO_TypeDef *GPIOx, GPIO_Pin_TypeDef GPIO_Pin, FunctionalState NewState); +typedef enum +{ + I2C_DUTYCYCLE_2 = 0x00, + I2C_DUTYCYCLE_16_9 = 0x40 +} I2C_DutyCycle_TypeDef; +typedef enum +{ + I2C_ACK_NONE = 0x00, + I2C_ACK_CURR = 0x01, + I2C_ACK_NEXT = 0x02 +} I2C_Ack_TypeDef; +typedef enum +{ + I2C_ADDMODE_7BIT = 0x00, + I2C_ADDMODE_10BIT = 0x80 +} I2C_AddMode_TypeDef; +typedef enum +{ + I2C_IT_ERR = 0x01, + I2C_IT_EVT = 0x02, + I2C_IT_BUF = 0x04 +} I2C_IT_TypeDef; +typedef enum +{ + I2C_DIRECTION_TX = 0x00, + I2C_DIRECTION_RX = 0x01 +} I2C_Direction_TypeDef; +typedef enum +{ + I2C_FLAG_TXEMPTY = 0x0180, + I2C_FLAG_RXNOTEMPTY = 0x0140, + I2C_FLAG_STOPDETECTION = 0x0110, + I2C_FLAG_HEADERSENT = 0x0108, + I2C_FLAG_TRANSFERFINISHED = 0x0104, + I2C_FLAG_ADDRESSSENTMATCHED = 0x0102, + I2C_FLAG_STARTDETECTION = 0x0101, + I2C_FLAG_WAKEUPFROMHALT = 0x0220, + I2C_FLAG_OVERRUNUNDERRUN = 0x0208, + I2C_FLAG_ACKNOWLEDGEFAILURE = 0x0204, + I2C_FLAG_ARBITRATIONLOSS = 0x0202, + I2C_FLAG_BUSERROR = 0x0201, + I2C_FLAG_GENERALCALL = 0x0310, + I2C_FLAG_TRANSMITTERRECEIVER = 0x0304, + I2C_FLAG_BUSBUSY = 0x0302, + I2C_FLAG_MASTERSLAVE = 0x0301 +} I2C_Flag_TypeDef; +typedef enum +{ + I2C_ITPENDINGBIT_TXEMPTY = 0x1680, + I2C_ITPENDINGBIT_RXNOTEMPTY = 0x1640, + I2C_ITPENDINGBIT_STOPDETECTION = 0x1210, + I2C_ITPENDINGBIT_HEADERSENT = 0x1208, + I2C_ITPENDINGBIT_TRANSFERFINISHED = 0x1204, + I2C_ITPENDINGBIT_ADDRESSSENTMATCHED = 0x1202, + I2C_ITPENDINGBIT_STARTDETECTION = 0x1201, + I2C_ITPENDINGBIT_WAKEUPFROMHALT = 0x2220, + I2C_ITPENDINGBIT_OVERRUNUNDERRUN = 0x2108, + I2C_ITPENDINGBIT_ACKNOWLEDGEFAILURE = 0x2104, + I2C_ITPENDINGBIT_ARBITRATIONLOSS = 0x2102, + I2C_ITPENDINGBIT_BUSERROR = 0x2101 +} I2C_ITPendingBit_TypeDef; +typedef enum +{ + I2C_EVENT_MASTER_MODE_SELECT = 0x0301, + I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED = 0x0782, + I2C_EVENT_MASTER_RECEIVER_MODE_SELECTED = 0x0302, + I2C_EVENT_MASTER_MODE_ADDRESS10 = 0x0308, + I2C_EVENT_MASTER_BYTE_RECEIVED = 0x0340, + I2C_EVENT_MASTER_BYTE_TRANSMITTING = 0x0780, + I2C_EVENT_MASTER_BYTE_TRANSMITTED = 0x0784, + I2C_EVENT_SLAVE_RECEIVER_ADDRESS_MATCHED = 0x0202, + I2C_EVENT_SLAVE_TRANSMITTER_ADDRESS_MATCHED = 0x0682, + I2C_EVENT_SLAVE_GENERALCALLADDRESS_MATCHED = 0x1200, + I2C_EVENT_SLAVE_BYTE_RECEIVED = 0x0240, + I2C_EVENT_SLAVE_STOP_DETECTED = 0x0010, + I2C_EVENT_SLAVE_BYTE_TRANSMITTED = 0x0684, + I2C_EVENT_SLAVE_BYTE_TRANSMITTING = 0x0680, + I2C_EVENT_SLAVE_ACK_FAILURE = 0x0004 +} I2C_Event_TypeDef; +extern "Python+C" void I2C_DeInit(void); +extern "Python+C" void I2C_Init(uint32_t OutputClockFrequencyHz, uint16_t OwnAddress, I2C_DutyCycle_TypeDef I2C_DutyCycle, I2C_Ack_TypeDef Ack, I2C_AddMode_TypeDef AddMode, uint8_t InputClockFrequencyMHz); +extern "Python+C" void I2C_Cmd(FunctionalState NewState); +extern "Python+C" void I2C_GeneralCallCmd(FunctionalState NewState); +extern "Python+C" void I2C_GenerateSTART(FunctionalState NewState); +extern "Python+C" void I2C_GenerateSTOP(FunctionalState NewState); +extern "Python+C" void I2C_SoftwareResetCmd(FunctionalState NewState); +extern "Python+C" void I2C_StretchClockCmd(FunctionalState NewState); +extern "Python+C" void I2C_AcknowledgeConfig(I2C_Ack_TypeDef Ack); +extern "Python+C" void I2C_FastModeDutyCycleConfig(I2C_DutyCycle_TypeDef I2C_DutyCycle); +extern "Python+C" void I2C_ITConfig(I2C_IT_TypeDef I2C_IT, FunctionalState NewState); +extern "Python+C" uint8_t I2C_ReceiveData(void); +extern "Python+C" void I2C_Send7bitAddress(uint8_t Address, I2C_Direction_TypeDef Direction); +extern "Python+C" void I2C_SendData(uint8_t Data); +extern "Python+C" ErrorStatus I2C_CheckEvent(I2C_Event_TypeDef I2C_Event); +extern "Python+C" I2C_Event_TypeDef I2C_GetLastEvent(void); +extern "Python+C" FlagStatus I2C_GetFlagStatus(I2C_Flag_TypeDef I2C_Flag); +extern "Python+C" void I2C_ClearFlag(I2C_Flag_TypeDef I2C_FLAG); +extern "Python+C" ITStatus I2C_GetITStatus(I2C_ITPendingBit_TypeDef I2C_ITPendingBit); +extern "Python+C" void I2C_ClearITPendingBit(I2C_ITPendingBit_TypeDef I2C_ITPendingBit); +typedef enum +{ + ITC_IRQ_TLI = 0, + ITC_IRQ_AWU = 1, + ITC_IRQ_CLK = 2, + ITC_IRQ_PORTA = 3, + ITC_IRQ_PORTB = 4, + ITC_IRQ_PORTC = 5, + ITC_IRQ_PORTD = 6, + ITC_IRQ_PORTE = 7, + ITC_IRQ_SPI = 10, + ITC_IRQ_TIM1_OVF = 11, + ITC_IRQ_TIM1_CAPCOM = 12, + ITC_IRQ_TIM2_OVF = 13, + ITC_IRQ_TIM2_CAPCOM = 14, + ITC_IRQ_TIM3_OVF = 15, + ITC_IRQ_TIM3_CAPCOM = 16, + ITC_IRQ_I2C = 19, + ITC_IRQ_UART2_TX = 20, + ITC_IRQ_UART2_RX = 21, + ITC_IRQ_ADC1 = 22, + ITC_IRQ_TIM4_OVF = 23, + ITC_IRQ_EEPROM_EEC = 24 +} ITC_Irq_TypeDef; +typedef enum +{ + ITC_PRIORITYLEVEL_0 = 0x02, + ITC_PRIORITYLEVEL_1 = 0x01, + ITC_PRIORITYLEVEL_2 = 0x00, + ITC_PRIORITYLEVEL_3 = 0x03 +} ITC_PriorityLevel_TypeDef; +extern "Python+C" uint8_t ITC_GetCPUCC(void); +extern "Python+C" void ITC_DeInit(void); +extern "Python+C" uint8_t ITC_GetSoftIntStatus(void); +extern "Python+C" void ITC_SetSoftwarePriority(ITC_Irq_TypeDef IrqNum, ITC_PriorityLevel_TypeDef PriorityValue); +extern "Python+C" ITC_PriorityLevel_TypeDef ITC_GetSoftwarePriority(ITC_Irq_TypeDef IrqNum); +typedef enum +{ + IWDG_WriteAccess_Enable = 0x55, + IWDG_WriteAccess_Disable = 0x00 +} IWDG_WriteAccess_TypeDef; +typedef enum +{ + IWDG_Prescaler_4 = 0x00, + IWDG_Prescaler_8 = 0x01, + IWDG_Prescaler_16 = 0x02, + IWDG_Prescaler_32 = 0x03, + IWDG_Prescaler_64 = 0x04, + IWDG_Prescaler_128 = 0x05, + IWDG_Prescaler_256 = 0x06 +} IWDG_Prescaler_TypeDef; +extern "Python+C" void IWDG_WriteAccessCmd(IWDG_WriteAccess_TypeDef IWDG_WriteAccess); +extern "Python+C" void IWDG_SetPrescaler(IWDG_Prescaler_TypeDef IWDG_Prescaler); +extern "Python+C" void IWDG_SetReload(uint8_t IWDG_Reload); +extern "Python+C" void IWDG_ReloadCounter(void); +extern "Python+C" void IWDG_Enable(void); +typedef enum +{ + RST_FLAG_EMCF = 0x10, + RST_FLAG_SWIMF = 0x08, + RST_FLAG_ILLOPF = 0x04, + RST_FLAG_IWDGF = 0x02, + RST_FLAG_WWDGF = 0x01 +} RST_Flag_TypeDef; +extern "Python+C" FlagStatus RST_GetFlagStatus(RST_Flag_TypeDef RST_Flag); +extern "Python+C" void RST_ClearFlag(RST_Flag_TypeDef RST_Flag); +typedef enum +{ + SPI_DATADIRECTION_2LINES_FULLDUPLEX = 0x00, + SPI_DATADIRECTION_2LINES_RXONLY = 0x04, + SPI_DATADIRECTION_1LINE_RX = 0x80, + SPI_DATADIRECTION_1LINE_TX = 0xC0 +} SPI_DataDirection_TypeDef; +typedef enum +{ + SPI_NSS_SOFT = 0x02, + SPI_NSS_HARD = 0x00 +} SPI_NSS_TypeDef; +typedef enum +{ + SPI_DIRECTION_RX = 0x00, + SPI_DIRECTION_TX = 0x01 +} SPI_Direction_TypeDef; +typedef enum +{ + SPI_MODE_MASTER = 0x04, + SPI_MODE_SLAVE = 0x00 +} SPI_Mode_TypeDef; +typedef enum +{ + SPI_BAUDRATEPRESCALER_2 = 0x00, + SPI_BAUDRATEPRESCALER_4 = 0x08, + SPI_BAUDRATEPRESCALER_8 = 0x10, + SPI_BAUDRATEPRESCALER_16 = 0x18, + SPI_BAUDRATEPRESCALER_32 = 0x20, + SPI_BAUDRATEPRESCALER_64 = 0x28, + SPI_BAUDRATEPRESCALER_128 = 0x30, + SPI_BAUDRATEPRESCALER_256 = 0x38 +} SPI_BaudRatePrescaler_TypeDef; +typedef enum +{ + SPI_CLOCKPOLARITY_LOW = 0x00, + SPI_CLOCKPOLARITY_HIGH = 0x02 +} SPI_ClockPolarity_TypeDef; +typedef enum +{ + SPI_CLOCKPHASE_1EDGE = 0x00, + SPI_CLOCKPHASE_2EDGE = 0x01 +} SPI_ClockPhase_TypeDef; +typedef enum +{ + SPI_FIRSTBIT_MSB = 0x00, + SPI_FIRSTBIT_LSB = 0x80 +} SPI_FirstBit_TypeDef; +typedef enum +{ + SPI_CRC_RX = 0x00, + SPI_CRC_TX = 0x01 +} SPI_CRC_TypeDef; +typedef enum +{ + SPI_FLAG_BSY = 0x80, + SPI_FLAG_OVR = 0x40, + SPI_FLAG_MODF = 0x20, + SPI_FLAG_CRCERR = 0x10, + SPI_FLAG_WKUP = 0x08, + SPI_FLAG_TXE = 0x02, + SPI_FLAG_RXNE = 0x01 +} SPI_Flag_TypeDef; +typedef enum +{ + SPI_IT_WKUP = 0x34, + SPI_IT_OVR = 0x65, + SPI_IT_MODF = 0x55, + SPI_IT_CRCERR = 0x45, + SPI_IT_TXE = 0x17, + SPI_IT_RXNE = 0x06, + SPI_IT_ERR = 0x05 +} SPI_IT_TypeDef; +extern "Python+C" void SPI_DeInit(void); +extern "Python+C" void SPI_Init(SPI_FirstBit_TypeDef FirstBit, SPI_BaudRatePrescaler_TypeDef BaudRatePrescaler, SPI_Mode_TypeDef Mode, SPI_ClockPolarity_TypeDef ClockPolarity, SPI_ClockPhase_TypeDef ClockPhase, SPI_DataDirection_TypeDef Data_Direction, SPI_NSS_TypeDef Slave_Management, uint8_t CRCPolynomial); +extern "Python+C" void SPI_Cmd(FunctionalState NewState); +extern "Python+C" void SPI_ITConfig(SPI_IT_TypeDef SPI_IT, FunctionalState NewState); +extern "Python+C" void SPI_SendData(uint8_t Data); +extern "Python+C" uint8_t SPI_ReceiveData(void); +extern "Python+C" void SPI_NSSInternalSoftwareCmd(FunctionalState NewState); +extern "Python+C" void SPI_TransmitCRC(void); +extern "Python+C" void SPI_CalculateCRCCmd(FunctionalState NewState); +extern "Python+C" uint8_t SPI_GetCRC(SPI_CRC_TypeDef SPI_CRC); +extern "Python+C" void SPI_ResetCRC(void); +extern "Python+C" uint8_t SPI_GetCRCPolynomial(void); +extern "Python+C" void SPI_BiDirectionalLineConfig(SPI_Direction_TypeDef SPI_Direction); +extern "Python+C" FlagStatus SPI_GetFlagStatus(SPI_Flag_TypeDef SPI_FLAG); +extern "Python+C" void SPI_ClearFlag(SPI_Flag_TypeDef SPI_FLAG); +extern "Python+C" ITStatus SPI_GetITStatus(SPI_IT_TypeDef SPI_IT); +extern "Python+C" void SPI_ClearITPendingBit(SPI_IT_TypeDef SPI_IT); +typedef enum +{ + TIM1_OCMODE_TIMING = 0x00, + TIM1_OCMODE_ACTIVE = 0x10, + TIM1_OCMODE_INACTIVE = 0x20, + TIM1_OCMODE_TOGGLE = 0x30, + TIM1_OCMODE_PWM1 = 0x60, + TIM1_OCMODE_PWM2 = 0x70 +} TIM1_OCMode_TypeDef; +typedef enum +{ + TIM1_OPMODE_SINGLE = 0x01, + TIM1_OPMODE_REPETITIVE = 0x00 +} TIM1_OPMode_TypeDef; +typedef enum +{ + TIM1_CHANNEL_1 = 0x00, + TIM1_CHANNEL_2 = 0x01, + TIM1_CHANNEL_3 = 0x02, + TIM1_CHANNEL_4 = 0x03 +} TIM1_Channel_TypeDef; +typedef enum +{ + TIM1_COUNTERMODE_UP = 0x00, + TIM1_COUNTERMODE_DOWN = 0x10, + TIM1_COUNTERMODE_CENTERALIGNED1 = 0x20, + TIM1_COUNTERMODE_CENTERALIGNED2 = 0x40, + TIM1_COUNTERMODE_CENTERALIGNED3 = 0x60 +} TIM1_CounterMode_TypeDef; +typedef enum +{ + TIM1_OCPOLARITY_HIGH = 0x00, + TIM1_OCPOLARITY_LOW = 0x22 +} TIM1_OCPolarity_TypeDef; +typedef enum +{ + TIM1_OCNPOLARITY_HIGH = 0x00, + TIM1_OCNPOLARITY_LOW = 0x88 +} TIM1_OCNPolarity_TypeDef; +typedef enum +{ + TIM1_OUTPUTSTATE_DISABLE = 0x00, + TIM1_OUTPUTSTATE_ENABLE = 0x11 +} TIM1_OutputState_TypeDef; +typedef enum +{ + TIM1_OUTPUTNSTATE_DISABLE = 0x00, + TIM1_OUTPUTNSTATE_ENABLE = 0x44 +} TIM1_OutputNState_TypeDef; +typedef enum +{ + TIM1_BREAK_ENABLE = 0x10, + TIM1_BREAK_DISABLE = 0x00 +} TIM1_BreakState_TypeDef; +typedef enum +{ + TIM1_BREAKPOLARITY_LOW = 0x00, + TIM1_BREAKPOLARITY_HIGH = 0x20 +} TIM1_BreakPolarity_TypeDef; +typedef enum +{ + TIM1_AUTOMATICOUTPUT_ENABLE = 0x40, + TIM1_AUTOMATICOUTPUT_DISABLE = 0x00 +} TIM1_AutomaticOutput_TypeDef; +typedef enum +{ + TIM1_LOCKLEVEL_OFF = 0x00, + TIM1_LOCKLEVEL_1 = 0x01, + TIM1_LOCKLEVEL_2 = 0x02, + TIM1_LOCKLEVEL_3 = 0x03 +} TIM1_LockLevel_TypeDef; +typedef enum +{ + TIM1_OSSISTATE_ENABLE = 0x04, + TIM1_OSSISTATE_DISABLE = 0x00 +} TIM1_OSSIState_TypeDef; +typedef enum +{ + TIM1_OCIDLESTATE_SET = 0x55, + TIM1_OCIDLESTATE_RESET = 0x00 +} TIM1_OCIdleState_TypeDef; +typedef enum +{ + TIM1_OCNIDLESTATE_SET = 0x2A, + TIM1_OCNIDLESTATE_RESET = 0x00 +} TIM1_OCNIdleState_TypeDef; +typedef enum +{ + TIM1_ICPOLARITY_RISING = 0x00, + TIM1_ICPOLARITY_FALLING = 0x01 +} TIM1_ICPolarity_TypeDef; +typedef enum +{ + TIM1_ICSELECTION_DIRECTTI = 0x01, + TIM1_ICSELECTION_INDIRECTTI = 0x02, + TIM1_ICSELECTION_TRGI = 0x03 +} TIM1_ICSelection_TypeDef; +typedef enum +{ + TIM1_ICPSC_DIV1 = 0x00, + TIM1_ICPSC_DIV2 = 0x04, + TIM1_ICPSC_DIV4 = 0x08, + TIM1_ICPSC_DIV8 = 0x0C +} TIM1_ICPSC_TypeDef; +typedef enum +{ + TIM1_IT_UPDATE = 0x01, + TIM1_IT_CC1 = 0x02, + TIM1_IT_CC2 = 0x04, + TIM1_IT_CC3 = 0x08, + TIM1_IT_CC4 = 0x10, + TIM1_IT_COM = 0x20, + TIM1_IT_TRIGGER = 0x40, + TIM1_IT_BREAK = 0x80 +} TIM1_IT_TypeDef; +typedef enum +{ + TIM1_EXTTRGPSC_OFF = 0x00, + TIM1_EXTTRGPSC_DIV2 = 0x10, + TIM1_EXTTRGPSC_DIV4 = 0x20, + TIM1_EXTTRGPSC_DIV8 = 0x30 +} TIM1_ExtTRGPSC_TypeDef; +typedef enum +{ + TIM1_TS_TIM6 = 0x00, + TIM1_TS_TIM5 = 0x30, + TIM1_TS_TI1F_ED = 0x40, + TIM1_TS_TI1FP1 = 0x50, + TIM1_TS_TI2FP2 = 0x60, + TIM1_TS_ETRF = 0x70 +} TIM1_TS_TypeDef; +typedef enum +{ + TIM1_TIXEXTERNALCLK1SOURCE_TI1ED = 0x40, + TIM1_TIXEXTERNALCLK1SOURCE_TI1 = 0x50, + TIM1_TIXEXTERNALCLK1SOURCE_TI2 = 0x60 +} TIM1_TIxExternalCLK1Source_TypeDef; +typedef enum +{ + TIM1_EXTTRGPOLARITY_INVERTED = 0x80, + TIM1_EXTTRGPOLARITY_NONINVERTED = 0x00 +} TIM1_ExtTRGPolarity_TypeDef; +typedef enum +{ + TIM1_PSCRELOADMODE_UPDATE = 0x00, + TIM1_PSCRELOADMODE_IMMEDIATE = 0x01 +} TIM1_PSCReloadMode_TypeDef; +typedef enum +{ + TIM1_ENCODERMODE_TI1 = 0x01, + TIM1_ENCODERMODE_TI2 = 0x02, + TIM1_ENCODERMODE_TI12 = 0x03 +} TIM1_EncoderMode_TypeDef; +typedef enum +{ + TIM1_EVENTSOURCE_UPDATE = 0x01, + TIM1_EVENTSOURCE_CC1 = 0x02, + TIM1_EVENTSOURCE_CC2 = 0x04, + TIM1_EVENTSOURCE_CC3 = 0x08, + TIM1_EVENTSOURCE_CC4 = 0x10, + TIM1_EVENTSOURCE_COM = 0x20, + TIM1_EVENTSOURCE_TRIGGER = 0x40, + TIM1_EVENTSOURCE_BREAK = 0x80 +} TIM1_EventSource_TypeDef; +typedef enum +{ + TIM1_UPDATESOURCE_GLOBAL = 0x00, + TIM1_UPDATESOURCE_REGULAR = 0x01 +} TIM1_UpdateSource_TypeDef; +typedef enum +{ + TIM1_TRGOSOURCE_RESET = 0x00, + TIM1_TRGOSOURCE_ENABLE = 0x10, + TIM1_TRGOSOURCE_UPDATE = 0x20, + TIM1_TRGOSource_OC1 = 0x30, + TIM1_TRGOSOURCE_OC1REF = 0x40, + TIM1_TRGOSOURCE_OC2REF = 0x50, + TIM1_TRGOSOURCE_OC3REF = 0x60 +} TIM1_TRGOSource_TypeDef; +typedef enum +{ + TIM1_SLAVEMODE_RESET = 0x04, + TIM1_SLAVEMODE_GATED = 0x05, + TIM1_SLAVEMODE_TRIGGER = 0x06, + TIM1_SLAVEMODE_EXTERNAL1 = 0x07 +} TIM1_SlaveMode_TypeDef; +typedef enum +{ + TIM1_FLAG_UPDATE = 0x0001, + TIM1_FLAG_CC1 = 0x0002, + TIM1_FLAG_CC2 = 0x0004, + TIM1_FLAG_CC3 = 0x0008, + TIM1_FLAG_CC4 = 0x0010, + TIM1_FLAG_COM = 0x0020, + TIM1_FLAG_TRIGGER = 0x0040, + TIM1_FLAG_BREAK = 0x0080, + TIM1_FLAG_CC1OF = 0x0200, + TIM1_FLAG_CC2OF = 0x0400, + TIM1_FLAG_CC3OF = 0x0800, + TIM1_FLAG_CC4OF = 0x1000 +} TIM1_FLAG_TypeDef; +typedef enum +{ + TIM1_FORCEDACTION_ACTIVE = 0x50, + TIM1_FORCEDACTION_INACTIVE = 0x40 +} TIM1_ForcedAction_TypeDef; +extern "Python+C" void TIM1_DeInit(void); +extern "Python+C" void TIM1_TimeBaseInit(uint16_t TIM1_Prescaler, TIM1_CounterMode_TypeDef TIM1_CounterMode, uint16_t TIM1_Period, uint8_t TIM1_RepetitionCounter); +extern "Python+C" void TIM1_OC1Init(TIM1_OCMode_TypeDef TIM1_OCMode, TIM1_OutputState_TypeDef TIM1_OutputState, TIM1_OutputNState_TypeDef TIM1_OutputNState, uint16_t TIM1_Pulse, TIM1_OCPolarity_TypeDef TIM1_OCPolarity, TIM1_OCNPolarity_TypeDef TIM1_OCNPolarity, TIM1_OCIdleState_TypeDef TIM1_OCIdleState, TIM1_OCNIdleState_TypeDef TIM1_OCNIdleState); +extern "Python+C" void TIM1_OC2Init(TIM1_OCMode_TypeDef TIM1_OCMode, TIM1_OutputState_TypeDef TIM1_OutputState, TIM1_OutputNState_TypeDef TIM1_OutputNState, uint16_t TIM1_Pulse, TIM1_OCPolarity_TypeDef TIM1_OCPolarity, TIM1_OCNPolarity_TypeDef TIM1_OCNPolarity, TIM1_OCIdleState_TypeDef TIM1_OCIdleState, TIM1_OCNIdleState_TypeDef TIM1_OCNIdleState); +extern "Python+C" void TIM1_OC3Init(TIM1_OCMode_TypeDef TIM1_OCMode, TIM1_OutputState_TypeDef TIM1_OutputState, TIM1_OutputNState_TypeDef TIM1_OutputNState, uint16_t TIM1_Pulse, TIM1_OCPolarity_TypeDef TIM1_OCPolarity, TIM1_OCNPolarity_TypeDef TIM1_OCNPolarity, TIM1_OCIdleState_TypeDef TIM1_OCIdleState, TIM1_OCNIdleState_TypeDef TIM1_OCNIdleState); +extern "Python+C" void TIM1_OC4Init(TIM1_OCMode_TypeDef TIM1_OCMode, TIM1_OutputState_TypeDef TIM1_OutputState, uint16_t TIM1_Pulse, TIM1_OCPolarity_TypeDef TIM1_OCPolarity, TIM1_OCIdleState_TypeDef TIM1_OCIdleState); +extern "Python+C" void TIM1_BDTRConfig(TIM1_OSSIState_TypeDef TIM1_OSSIState, TIM1_LockLevel_TypeDef TIM1_LockLevel, uint8_t TIM1_DeadTime, TIM1_BreakState_TypeDef TIM1_Break, TIM1_BreakPolarity_TypeDef TIM1_BreakPolarity, TIM1_AutomaticOutput_TypeDef TIM1_AutomaticOutput); +extern "Python+C" void TIM1_ICInit(TIM1_Channel_TypeDef TIM1_Channel, TIM1_ICPolarity_TypeDef TIM1_ICPolarity, TIM1_ICSelection_TypeDef TIM1_ICSelection, TIM1_ICPSC_TypeDef TIM1_ICPrescaler, uint8_t TIM1_ICFilter); +extern "Python+C" void TIM1_PWMIConfig(TIM1_Channel_TypeDef TIM1_Channel, TIM1_ICPolarity_TypeDef TIM1_ICPolarity, TIM1_ICSelection_TypeDef TIM1_ICSelection, TIM1_ICPSC_TypeDef TIM1_ICPrescaler, uint8_t TIM1_ICFilter); +extern "Python+C" void TIM1_Cmd(FunctionalState NewState); +extern "Python+C" void TIM1_CtrlPWMOutputs(FunctionalState NewState); +extern "Python+C" void TIM1_ITConfig(TIM1_IT_TypeDef TIM1_IT, FunctionalState NewState); +extern "Python+C" void TIM1_InternalClockConfig(void); +extern "Python+C" void TIM1_ETRClockMode1Config(TIM1_ExtTRGPSC_TypeDef TIM1_ExtTRGPrescaler, TIM1_ExtTRGPolarity_TypeDef TIM1_ExtTRGPolarity, uint8_t ExtTRGFilter); +extern "Python+C" void TIM1_ETRClockMode2Config(TIM1_ExtTRGPSC_TypeDef TIM1_ExtTRGPrescaler, TIM1_ExtTRGPolarity_TypeDef TIM1_ExtTRGPolarity, uint8_t ExtTRGFilter); +extern "Python+C" void TIM1_ETRConfig(TIM1_ExtTRGPSC_TypeDef TIM1_ExtTRGPrescaler, TIM1_ExtTRGPolarity_TypeDef TIM1_ExtTRGPolarity, uint8_t ExtTRGFilter); +extern "Python+C" void TIM1_TIxExternalClockConfig(TIM1_TIxExternalCLK1Source_TypeDef TIM1_TIxExternalCLKSource, TIM1_ICPolarity_TypeDef TIM1_ICPolarity, uint8_t ICFilter); +extern "Python+C" void TIM1_SelectInputTrigger(TIM1_TS_TypeDef TIM1_InputTriggerSource); +extern "Python+C" void TIM1_UpdateDisableConfig(FunctionalState NewState); +extern "Python+C" void TIM1_UpdateRequestConfig(TIM1_UpdateSource_TypeDef TIM1_UpdateSource); +extern "Python+C" void TIM1_SelectHallSensor(FunctionalState NewState); +extern "Python+C" void TIM1_SelectOnePulseMode(TIM1_OPMode_TypeDef TIM1_OPMode); +extern "Python+C" void TIM1_SelectOutputTrigger(TIM1_TRGOSource_TypeDef TIM1_TRGOSource); +extern "Python+C" void TIM1_SelectSlaveMode(TIM1_SlaveMode_TypeDef TIM1_SlaveMode); +extern "Python+C" void TIM1_SelectMasterSlaveMode(FunctionalState NewState); +extern "Python+C" void TIM1_EncoderInterfaceConfig(TIM1_EncoderMode_TypeDef TIM1_EncoderMode, TIM1_ICPolarity_TypeDef TIM1_IC1Polarity, TIM1_ICPolarity_TypeDef TIM1_IC2Polarity); +extern "Python+C" void TIM1_PrescalerConfig(uint16_t Prescaler, TIM1_PSCReloadMode_TypeDef TIM1_PSCReloadMode); +extern "Python+C" void TIM1_CounterModeConfig(TIM1_CounterMode_TypeDef TIM1_CounterMode); +extern "Python+C" void TIM1_ForcedOC1Config(TIM1_ForcedAction_TypeDef TIM1_ForcedAction); +extern "Python+C" void TIM1_ForcedOC2Config(TIM1_ForcedAction_TypeDef TIM1_ForcedAction); +extern "Python+C" void TIM1_ForcedOC3Config(TIM1_ForcedAction_TypeDef TIM1_ForcedAction); +extern "Python+C" void TIM1_ForcedOC4Config(TIM1_ForcedAction_TypeDef TIM1_ForcedAction); +extern "Python+C" void TIM1_ARRPreloadConfig(FunctionalState NewState); +extern "Python+C" void TIM1_SelectCOM(FunctionalState NewState); +extern "Python+C" void TIM1_CCPreloadControl(FunctionalState NewState); +extern "Python+C" void TIM1_OC1PreloadConfig(FunctionalState NewState); +extern "Python+C" void TIM1_OC2PreloadConfig(FunctionalState NewState); +extern "Python+C" void TIM1_OC3PreloadConfig(FunctionalState NewState); +extern "Python+C" void TIM1_OC4PreloadConfig(FunctionalState NewState); +extern "Python+C" void TIM1_OC1FastConfig(FunctionalState NewState); +extern "Python+C" void TIM1_OC2FastConfig(FunctionalState NewState); +extern "Python+C" void TIM1_OC3FastConfig(FunctionalState NewState); +extern "Python+C" void TIM1_OC4FastConfig(FunctionalState NewState); +extern "Python+C" void TIM1_GenerateEvent(TIM1_EventSource_TypeDef TIM1_EventSource); +extern "Python+C" void TIM1_OC1PolarityConfig(TIM1_OCPolarity_TypeDef TIM1_OCPolarity); +extern "Python+C" void TIM1_OC1NPolarityConfig(TIM1_OCNPolarity_TypeDef TIM1_OCNPolarity); +extern "Python+C" void TIM1_OC2PolarityConfig(TIM1_OCPolarity_TypeDef TIM1_OCPolarity); +extern "Python+C" void TIM1_OC2NPolarityConfig(TIM1_OCNPolarity_TypeDef TIM1_OCNPolarity); +extern "Python+C" void TIM1_OC3PolarityConfig(TIM1_OCPolarity_TypeDef TIM1_OCPolarity); +extern "Python+C" void TIM1_OC3NPolarityConfig(TIM1_OCNPolarity_TypeDef TIM1_OCNPolarity); +extern "Python+C" void TIM1_OC4PolarityConfig(TIM1_OCPolarity_TypeDef TIM1_OCPolarity); +extern "Python+C" void TIM1_CCxCmd(TIM1_Channel_TypeDef TIM1_Channel, FunctionalState NewState); +extern "Python+C" void TIM1_CCxNCmd(TIM1_Channel_TypeDef TIM1_Channel, FunctionalState NewState); +extern "Python+C" void TIM1_SelectOCxM(TIM1_Channel_TypeDef TIM1_Channel, TIM1_OCMode_TypeDef TIM1_OCMode); +extern "Python+C" void TIM1_SetCounter(uint16_t Counter); +extern "Python+C" void TIM1_SetAutoreload(uint16_t Autoreload); +extern "Python+C" void TIM1_SetCompare1(uint16_t Compare1); +extern "Python+C" void TIM1_SetCompare2(uint16_t Compare2); +extern "Python+C" void TIM1_SetCompare3(uint16_t Compare3); +extern "Python+C" void TIM1_SetCompare4(uint16_t Compare4); +extern "Python+C" void TIM1_SetIC1Prescaler(TIM1_ICPSC_TypeDef TIM1_IC1Prescaler); +extern "Python+C" void TIM1_SetIC2Prescaler(TIM1_ICPSC_TypeDef TIM1_IC2Prescaler); +extern "Python+C" void TIM1_SetIC3Prescaler(TIM1_ICPSC_TypeDef TIM1_IC3Prescaler); +extern "Python+C" void TIM1_SetIC4Prescaler(TIM1_ICPSC_TypeDef TIM1_IC4Prescaler); +extern "Python+C" uint16_t TIM1_GetCapture1(void); +extern "Python+C" uint16_t TIM1_GetCapture2(void); +extern "Python+C" uint16_t TIM1_GetCapture3(void); +extern "Python+C" uint16_t TIM1_GetCapture4(void); +extern "Python+C" uint16_t TIM1_GetCounter(void); +extern "Python+C" uint16_t TIM1_GetPrescaler(void); +extern "Python+C" FlagStatus TIM1_GetFlagStatus(TIM1_FLAG_TypeDef TIM1_FLAG); +extern "Python+C" void TIM1_ClearFlag(TIM1_FLAG_TypeDef TIM1_FLAG); +extern "Python+C" ITStatus TIM1_GetITStatus(TIM1_IT_TypeDef TIM1_IT); +extern "Python+C" void TIM1_ClearITPendingBit(TIM1_IT_TypeDef TIM1_IT); +typedef enum +{ + TIM2_FORCEDACTION_ACTIVE = 0x50, + TIM2_FORCEDACTION_INACTIVE = 0x40 +} TIM2_ForcedAction_TypeDef; +typedef enum +{ + TIM2_PRESCALER_1 = 0x00, + TIM2_PRESCALER_2 = 0x01, + TIM2_PRESCALER_4 = 0x02, + TIM2_PRESCALER_8 = 0x03, + TIM2_PRESCALER_16 = 0x04, + TIM2_PRESCALER_32 = 0x05, + TIM2_PRESCALER_64 = 0x06, + TIM2_PRESCALER_128 = 0x07, + TIM2_PRESCALER_256 = 0x08, + TIM2_PRESCALER_512 = 0x09, + TIM2_PRESCALER_1024 = 0x0A, + TIM2_PRESCALER_2048 = 0x0B, + TIM2_PRESCALER_4096 = 0x0C, + TIM2_PRESCALER_8192 = 0x0D, + TIM2_PRESCALER_16384 = 0x0E, + TIM2_PRESCALER_32768 = 0x0F +} TIM2_Prescaler_TypeDef; +typedef enum +{ + TIM2_OCMODE_TIMING = 0x00, + TIM2_OCMODE_ACTIVE = 0x10, + TIM2_OCMODE_INACTIVE = 0x20, + TIM2_OCMODE_TOGGLE = 0x30, + TIM2_OCMODE_PWM1 = 0x60, + TIM2_OCMODE_PWM2 = 0x70 +} TIM2_OCMode_TypeDef; +typedef enum +{ + TIM2_OPMODE_SINGLE = 0x01, + TIM2_OPMODE_REPETITIVE = 0x00 +} TIM2_OPMode_TypeDef; +typedef enum +{ + TIM2_CHANNEL_1 = 0x00, + TIM2_CHANNEL_2 = 0x01, + TIM2_CHANNEL_3 = 0x02 +} TIM2_Channel_TypeDef; +typedef enum +{ + TIM2_OCPOLARITY_HIGH = 0x00, + TIM2_OCPOLARITY_LOW = 0x22 +} TIM2_OCPolarity_TypeDef; +typedef enum +{ + TIM2_OUTPUTSTATE_DISABLE = 0x00, + TIM2_OUTPUTSTATE_ENABLE = 0x11 +} TIM2_OutputState_TypeDef; +typedef enum +{ + TIM2_ICPOLARITY_RISING = 0x00, + TIM2_ICPOLARITY_FALLING = 0x44 +} TIM2_ICPolarity_TypeDef; +typedef enum +{ + TIM2_ICSELECTION_DIRECTTI = 0x01, + TIM2_ICSELECTION_INDIRECTTI = 0x02, + TIM2_ICSELECTION_TRGI = 0x03 +} TIM2_ICSelection_TypeDef; +typedef enum +{ + TIM2_ICPSC_DIV1 = 0x00, + TIM2_ICPSC_DIV2 = 0x04, + TIM2_ICPSC_DIV4 = 0x08, + TIM2_ICPSC_DIV8 = 0x0C +} TIM2_ICPSC_TypeDef; +typedef enum +{ + TIM2_IT_UPDATE = 0x01, + TIM2_IT_CC1 = 0x02, + TIM2_IT_CC2 = 0x04, + TIM2_IT_CC3 = 0x08 +} TIM2_IT_TypeDef; +typedef enum +{ + TIM2_PSCRELOADMODE_UPDATE = 0x00, + TIM2_PSCRELOADMODE_IMMEDIATE = 0x01 +} TIM2_PSCReloadMode_TypeDef; +typedef enum +{ + TIM2_EVENTSOURCE_UPDATE = 0x01, + TIM2_EVENTSOURCE_CC1 = 0x02, + TIM2_EVENTSOURCE_CC2 = 0x04, + TIM2_EVENTSOURCE_CC3 = 0x08 +} TIM2_EventSource_TypeDef; +typedef enum +{ + TIM2_UPDATESOURCE_GLOBAL = 0x00, + TIM2_UPDATESOURCE_REGULAR = 0x01 +} TIM2_UpdateSource_TypeDef; +typedef enum +{ + TIM2_FLAG_UPDATE = 0x0001, + TIM2_FLAG_CC1 = 0x0002, + TIM2_FLAG_CC2 = 0x0004, + TIM2_FLAG_CC3 = 0x0008, + TIM2_FLAG_CC1OF = 0x0200, + TIM2_FLAG_CC2OF = 0x0400, + TIM2_FLAG_CC3OF = 0x0800 +} TIM2_FLAG_TypeDef; +extern "Python+C" void TIM2_DeInit(void); +extern "Python+C" void TIM2_TimeBaseInit(TIM2_Prescaler_TypeDef TIM2_Prescaler, uint16_t TIM2_Period); +extern "Python+C" void TIM2_OC1Init(TIM2_OCMode_TypeDef TIM2_OCMode, TIM2_OutputState_TypeDef TIM2_OutputState, uint16_t TIM2_Pulse, TIM2_OCPolarity_TypeDef TIM2_OCPolarity); +extern "Python+C" void TIM2_OC2Init(TIM2_OCMode_TypeDef TIM2_OCMode, TIM2_OutputState_TypeDef TIM2_OutputState, uint16_t TIM2_Pulse, TIM2_OCPolarity_TypeDef TIM2_OCPolarity); +extern "Python+C" void TIM2_OC3Init(TIM2_OCMode_TypeDef TIM2_OCMode, TIM2_OutputState_TypeDef TIM2_OutputState, uint16_t TIM2_Pulse, TIM2_OCPolarity_TypeDef TIM2_OCPolarity); +extern "Python+C" void TIM2_ICInit(TIM2_Channel_TypeDef TIM2_Channel, TIM2_ICPolarity_TypeDef TIM2_ICPolarity, TIM2_ICSelection_TypeDef TIM2_ICSelection, TIM2_ICPSC_TypeDef TIM2_ICPrescaler, uint8_t TIM2_ICFilter); +extern "Python+C" void TIM2_PWMIConfig(TIM2_Channel_TypeDef TIM2_Channel, TIM2_ICPolarity_TypeDef TIM2_ICPolarity, TIM2_ICSelection_TypeDef TIM2_ICSelection, TIM2_ICPSC_TypeDef TIM2_ICPrescaler, uint8_t TIM2_ICFilter); +extern "Python+C" void TIM2_Cmd(FunctionalState NewState); +extern "Python+C" void TIM2_ITConfig(TIM2_IT_TypeDef TIM2_IT, FunctionalState NewState); +extern "Python+C" void TIM2_InternalClockConfig(void); +extern "Python+C" void TIM2_UpdateDisableConfig(FunctionalState NewState); +extern "Python+C" void TIM2_UpdateRequestConfig(TIM2_UpdateSource_TypeDef TIM2_UpdateSource); +extern "Python+C" void TIM2_SelectOnePulseMode(TIM2_OPMode_TypeDef TIM2_OPMode); +extern "Python+C" void TIM2_PrescalerConfig(TIM2_Prescaler_TypeDef Prescaler, TIM2_PSCReloadMode_TypeDef TIM2_PSCReloadMode); +extern "Python+C" void TIM2_ForcedOC1Config(TIM2_ForcedAction_TypeDef TIM2_ForcedAction); +extern "Python+C" void TIM2_ForcedOC2Config(TIM2_ForcedAction_TypeDef TIM2_ForcedAction); +extern "Python+C" void TIM2_ForcedOC3Config(TIM2_ForcedAction_TypeDef TIM2_ForcedAction); +extern "Python+C" void TIM2_ARRPreloadConfig(FunctionalState NewState); +extern "Python+C" void TIM2_CCPreloadControl(FunctionalState NewState); +extern "Python+C" void TIM2_OC1PreloadConfig(FunctionalState NewState); +extern "Python+C" void TIM2_OC2PreloadConfig(FunctionalState NewState); +extern "Python+C" void TIM2_OC3PreloadConfig(FunctionalState NewState); +extern "Python+C" void TIM2_GenerateEvent(TIM2_EventSource_TypeDef TIM2_EventSource); +extern "Python+C" void TIM2_OC1PolarityConfig(TIM2_OCPolarity_TypeDef TIM2_OCPolarity); +extern "Python+C" void TIM2_OC2PolarityConfig(TIM2_OCPolarity_TypeDef TIM2_OCPolarity); +extern "Python+C" void TIM2_OC3PolarityConfig(TIM2_OCPolarity_TypeDef TIM2_OCPolarity); +extern "Python+C" void TIM2_CCxCmd(TIM2_Channel_TypeDef TIM2_Channel, FunctionalState NewState); +extern "Python+C" void TIM2_SelectOCxM(TIM2_Channel_TypeDef TIM2_Channel, TIM2_OCMode_TypeDef TIM2_OCMode); +extern "Python+C" void TIM2_SetCounter(uint16_t Counter); +extern "Python+C" void TIM2_SetAutoreload(uint16_t Autoreload); +extern "Python+C" void TIM2_SetCompare1(uint16_t Compare1); +extern "Python+C" void TIM2_SetCompare2(uint16_t Compare2); +extern "Python+C" void TIM2_SetCompare3(uint16_t Compare3); +extern "Python+C" void TIM2_SetIC1Prescaler(TIM2_ICPSC_TypeDef TIM2_IC1Prescaler); +extern "Python+C" void TIM2_SetIC2Prescaler(TIM2_ICPSC_TypeDef TIM2_IC2Prescaler); +extern "Python+C" void TIM2_SetIC3Prescaler(TIM2_ICPSC_TypeDef TIM2_IC3Prescaler); +extern "Python+C" uint16_t TIM2_GetCapture1(void); +extern "Python+C" uint16_t TIM2_GetCapture2(void); +extern "Python+C" uint16_t TIM2_GetCapture3(void); +extern "Python+C" uint16_t TIM2_GetCounter(void); +extern "Python+C" TIM2_Prescaler_TypeDef TIM2_GetPrescaler(void); +extern "Python+C" FlagStatus TIM2_GetFlagStatus(TIM2_FLAG_TypeDef TIM2_FLAG); +extern "Python+C" void TIM2_ClearFlag(TIM2_FLAG_TypeDef TIM2_FLAG); +extern "Python+C" ITStatus TIM2_GetITStatus(TIM2_IT_TypeDef TIM2_IT); +extern "Python+C" void TIM2_ClearITPendingBit(TIM2_IT_TypeDef TIM2_IT); +typedef enum +{ + TIM3_FORCEDACTION_ACTIVE = 0x50, + TIM3_FORCEDACTION_INACTIVE = 0x40 +} TIM3_ForcedAction_TypeDef; +typedef enum +{ + TIM3_PRESCALER_1 = 0x00, + TIM3_PRESCALER_2 = 0x01, + TIM3_PRESCALER_4 = 0x02, + TIM3_PRESCALER_8 = 0x03, + TIM3_PRESCALER_16 = 0x04, + TIM3_PRESCALER_32 = 0x05, + TIM3_PRESCALER_64 = 0x06, + TIM3_PRESCALER_128 = 0x07, + TIM3_PRESCALER_256 = 0x08, + TIM3_PRESCALER_512 = 0x09, + TIM3_PRESCALER_1024 = 0x0A, + TIM3_PRESCALER_2048 = 0x0B, + TIM3_PRESCALER_4096 = 0x0C, + TIM3_PRESCALER_8192 = 0x0D, + TIM3_PRESCALER_16384 = 0x0E, + TIM3_PRESCALER_32768 = 0x0F +} TIM3_Prescaler_TypeDef; +typedef enum +{ + TIM3_OCMODE_TIMING = 0x00, + TIM3_OCMODE_ACTIVE = 0x10, + TIM3_OCMODE_INACTIVE = 0x20, + TIM3_OCMODE_TOGGLE = 0x30, + TIM3_OCMODE_PWM1 = 0x60, + TIM3_OCMODE_PWM2 = 0x70 +} TIM3_OCMode_TypeDef; +typedef enum +{ + TIM3_OPMODE_SINGLE = 0x01, + TIM3_OPMODE_REPETITIVE = 0x00 +} TIM3_OPMode_TypeDef; +typedef enum +{ + TIM3_CHANNEL_1 = 0x00, + TIM3_CHANNEL_2 = 0x01 +} TIM3_Channel_TypeDef; +typedef enum +{ + TIM3_OCPOLARITY_HIGH = 0x00, + TIM3_OCPOLARITY_LOW = 0x22 +} TIM3_OCPolarity_TypeDef; +typedef enum +{ + TIM3_OUTPUTSTATE_DISABLE = 0x00, + TIM3_OUTPUTSTATE_ENABLE = 0x11 +} TIM3_OutputState_TypeDef; +typedef enum +{ + TIM3_ICPOLARITY_RISING = 0x00, + TIM3_ICPOLARITY_FALLING = 0x44 +} TIM3_ICPolarity_TypeDef; +typedef enum +{ + TIM3_ICSELECTION_DIRECTTI = 0x01, + TIM3_ICSELECTION_INDIRECTTI = 0x02, + TIM3_ICSELECTION_TRGI = 0x03 +} TIM3_ICSelection_TypeDef; +typedef enum +{ + TIM3_ICPSC_DIV1 = 0x00, + TIM3_ICPSC_DIV2 = 0x04, + TIM3_ICPSC_DIV4 = 0x08, + TIM3_ICPSC_DIV8 = 0x0C +} TIM3_ICPSC_TypeDef; +typedef enum +{ + TIM3_IT_UPDATE = 0x01, + TIM3_IT_CC1 = 0x02, + TIM3_IT_CC2 = 0x04 +} TIM3_IT_TypeDef; +typedef enum +{ + TIM3_PSCRELOADMODE_UPDATE = 0x00, + TIM3_PSCRELOADMODE_IMMEDIATE = 0x01 +} TIM3_PSCReloadMode_TypeDef; +typedef enum +{ + TIM3_EVENTSOURCE_UPDATE = 0x01, + TIM3_EVENTSOURCE_CC1 = 0x02, + TIM3_EVENTSOURCE_CC2 = 0x04 +} TIM3_EventSource_TypeDef; +typedef enum +{ + TIM3_UPDATESOURCE_GLOBAL = 0x00, + TIM3_UPDATESOURCE_REGULAR = 0x01 +} TIM3_UpdateSource_TypeDef; +typedef enum +{ + TIM3_FLAG_UPDATE = 0x0001, + TIM3_FLAG_CC1 = 0x0002, + TIM3_FLAG_CC2 = 0x0004, + TIM3_FLAG_CC1OF = 0x0200, + TIM3_FLAG_CC2OF = 0x0400 +} TIM3_FLAG_TypeDef; +extern "Python+C" void TIM3_DeInit(void); +extern "Python+C" void TIM3_TimeBaseInit(TIM3_Prescaler_TypeDef TIM3_Prescaler, uint16_t TIM3_Period); +extern "Python+C" void TIM3_OC1Init(TIM3_OCMode_TypeDef TIM3_OCMode, TIM3_OutputState_TypeDef TIM3_OutputState, uint16_t TIM3_Pulse, TIM3_OCPolarity_TypeDef TIM3_OCPolarity); +extern "Python+C" void TIM3_OC2Init(TIM3_OCMode_TypeDef TIM3_OCMode, TIM3_OutputState_TypeDef TIM3_OutputState, uint16_t TIM3_Pulse, TIM3_OCPolarity_TypeDef TIM3_OCPolarity); +extern "Python+C" void TIM3_ICInit(TIM3_Channel_TypeDef TIM3_Channel, TIM3_ICPolarity_TypeDef TIM3_ICPolarity, TIM3_ICSelection_TypeDef TIM3_ICSelection, TIM3_ICPSC_TypeDef TIM3_ICPrescaler, uint8_t TIM3_ICFilter); +extern "Python+C" void TIM3_PWMIConfig(TIM3_Channel_TypeDef TIM3_Channel, TIM3_ICPolarity_TypeDef TIM3_ICPolarity, TIM3_ICSelection_TypeDef TIM3_ICSelection, TIM3_ICPSC_TypeDef TIM3_ICPrescaler, uint8_t TIM3_ICFilter); +extern "Python+C" void TIM3_Cmd(FunctionalState NewState); +extern "Python+C" void TIM3_ITConfig(TIM3_IT_TypeDef TIM3_IT, FunctionalState NewState); +extern "Python+C" void TIM3_InternalClockConfig(void); +extern "Python+C" void TIM3_UpdateDisableConfig(FunctionalState NewState); +extern "Python+C" void TIM3_UpdateRequestConfig(TIM3_UpdateSource_TypeDef TIM3_UpdateSource); +extern "Python+C" void TIM3_SelectOnePulseMode(TIM3_OPMode_TypeDef TIM3_OPMode); +extern "Python+C" void TIM3_PrescalerConfig(TIM3_Prescaler_TypeDef Prescaler, TIM3_PSCReloadMode_TypeDef TIM3_PSCReloadMode); +extern "Python+C" void TIM3_ForcedOC1Config(TIM3_ForcedAction_TypeDef TIM3_ForcedAction); +extern "Python+C" void TIM3_ForcedOC2Config(TIM3_ForcedAction_TypeDef TIM3_ForcedAction); +extern "Python+C" void TIM3_ARRPreloadConfig(FunctionalState NewState); +extern "Python+C" void TIM3_CCPreloadControl(FunctionalState NewState); +extern "Python+C" void TIM3_OC1PreloadConfig(FunctionalState NewState); +extern "Python+C" void TIM3_OC2PreloadConfig(FunctionalState NewState); +extern "Python+C" void TIM3_GenerateEvent(TIM3_EventSource_TypeDef TIM3_EventSource); +extern "Python+C" void TIM3_OC1PolarityConfig(TIM3_OCPolarity_TypeDef TIM3_OCPolarity); +extern "Python+C" void TIM3_OC2PolarityConfig(TIM3_OCPolarity_TypeDef TIM3_OCPolarity); +extern "Python+C" void TIM3_CCxCmd(TIM3_Channel_TypeDef TIM3_Channel, FunctionalState NewState); +extern "Python+C" void TIM3_SelectOCxM(TIM3_Channel_TypeDef TIM3_Channel, TIM3_OCMode_TypeDef TIM3_OCMode); +extern "Python+C" void TIM3_SetCounter(uint16_t Counter); +extern "Python+C" void TIM3_SetAutoreload(uint16_t Autoreload); +extern "Python+C" void TIM3_SetCompare1(uint16_t Compare1); +extern "Python+C" void TIM3_SetCompare2(uint16_t Compare2); +extern "Python+C" void TIM3_SetIC1Prescaler(TIM3_ICPSC_TypeDef TIM3_IC1Prescaler); +extern "Python+C" void TIM3_SetIC2Prescaler(TIM3_ICPSC_TypeDef TIM3_IC2Prescaler); +extern "Python+C" uint16_t TIM3_GetCapture1(void); +extern "Python+C" uint16_t TIM3_GetCapture2(void); +extern "Python+C" uint16_t TIM3_GetCounter(void); +extern "Python+C" TIM3_Prescaler_TypeDef TIM3_GetPrescaler(void); +extern "Python+C" FlagStatus TIM3_GetFlagStatus(TIM3_FLAG_TypeDef TIM3_FLAG); +extern "Python+C" void TIM3_ClearFlag(TIM3_FLAG_TypeDef TIM3_FLAG); +extern "Python+C" ITStatus TIM3_GetITStatus(TIM3_IT_TypeDef TIM3_IT); +extern "Python+C" void TIM3_ClearITPendingBit(TIM3_IT_TypeDef TIM3_IT); +typedef enum +{ + TIM4_PRESCALER_1 = 0x00, + TIM4_PRESCALER_2 = 0x01, + TIM4_PRESCALER_4 = 0x02, + TIM4_PRESCALER_8 = 0x03, + TIM4_PRESCALER_16 = 0x04, + TIM4_PRESCALER_32 = 0x05, + TIM4_PRESCALER_64 = 0x06, + TIM4_PRESCALER_128 = 0x07 +} TIM4_Prescaler_TypeDef; +typedef enum +{ + TIM4_OPMODE_SINGLE = 0x01, + TIM4_OPMODE_REPETITIVE = 0x00 +} TIM4_OPMode_TypeDef; +typedef enum +{ + TIM4_PSCRELOADMODE_UPDATE = 0x00, + TIM4_PSCRELOADMODE_IMMEDIATE = 0x01 +} TIM4_PSCReloadMode_TypeDef; +typedef enum +{ + TIM4_UPDATESOURCE_GLOBAL = 0x00, + TIM4_UPDATESOURCE_REGULAR = 0x01 +} TIM4_UpdateSource_TypeDef; +typedef enum +{ + TIM4_EVENTSOURCE_UPDATE = 0x01 +} TIM4_EventSource_TypeDef; +typedef enum +{ + TIM4_FLAG_UPDATE = 0x01 +} TIM4_FLAG_TypeDef; +typedef enum +{ + TIM4_IT_UPDATE = 0x01 +} TIM4_IT_TypeDef; +extern "Python+C" void TIM4_DeInit(void); +extern "Python+C" void TIM4_TimeBaseInit(TIM4_Prescaler_TypeDef TIM4_Prescaler, uint8_t TIM4_Period); +extern "Python+C" void TIM4_Cmd(FunctionalState NewState); +extern "Python+C" void TIM4_ITConfig(TIM4_IT_TypeDef TIM4_IT, FunctionalState NewState); +extern "Python+C" void TIM4_UpdateDisableConfig(FunctionalState NewState); +extern "Python+C" void TIM4_UpdateRequestConfig(TIM4_UpdateSource_TypeDef TIM4_UpdateSource); +extern "Python+C" void TIM4_SelectOnePulseMode(TIM4_OPMode_TypeDef TIM4_OPMode); +extern "Python+C" void TIM4_PrescalerConfig(TIM4_Prescaler_TypeDef Prescaler, TIM4_PSCReloadMode_TypeDef TIM4_PSCReloadMode); +extern "Python+C" void TIM4_ARRPreloadConfig(FunctionalState NewState); +extern "Python+C" void TIM4_GenerateEvent(TIM4_EventSource_TypeDef TIM4_EventSource); +extern "Python+C" void TIM4_SetCounter(uint8_t Counter); +extern "Python+C" void TIM4_SetAutoreload(uint8_t Autoreload); +extern "Python+C" uint8_t TIM4_GetCounter(void); +extern "Python+C" TIM4_Prescaler_TypeDef TIM4_GetPrescaler(void); +extern "Python+C" FlagStatus TIM4_GetFlagStatus(TIM4_FLAG_TypeDef TIM4_FLAG); +extern "Python+C" void TIM4_ClearFlag(TIM4_FLAG_TypeDef TIM4_FLAG); +extern "Python+C" ITStatus TIM4_GetITStatus(TIM4_IT_TypeDef TIM4_IT); +extern "Python+C" void TIM4_ClearITPendingBit(TIM4_IT_TypeDef TIM4_IT); +typedef enum +{ + UART2_IRDAMODE_NORMAL = 0x00, + UART2_IRDAMODE_LOWPOWER = 0x01 +} UART2_IrDAMode_TypeDef; +typedef enum +{ + UART2_WAKEUP_IDLELINE = 0x00, + UART2_WAKEUP_ADDRESSMARK = 0x08 +} UART2_WakeUp_TypeDef; +typedef enum +{ + UART2_LINBREAKDETECTIONLENGTH_10BITS = 0x00, + UART2_LINBREAKDETECTIONLENGTH_11BITS = 0x01 +} UART2_LINBreakDetectionLength_TypeDef; +typedef enum +{ + UART2_STOPBITS_1 = 0x00, + UART2_STOPBITS_0_5 = 0x10, + UART2_STOPBITS_2 = 0x20, + UART2_STOPBITS_1_5 = 0x30 +} UART2_StopBits_TypeDef; +typedef enum +{ + UART2_PARITY_NO = 0x00, + UART2_PARITY_EVEN = 0x04, + UART2_PARITY_ODD = 0x06 +} UART2_Parity_TypeDef; +typedef enum +{ + UART2_LIN_MODE_MASTER = 0x00, + UART2_LIN_MODE_SLAVE = 0x01 +} UART2_LinMode_TypeDef; +typedef enum +{ + UART2_LIN_AUTOSYNC_DISABLE = 0x00, + UART2_LIN_AUTOSYNC_ENABLE = 0x01 +} UART2_LinAutosync_TypeDef; +typedef enum +{ + UART2_LIN_DIVUP_LBRR1 = 0x00, + UART2_LIN_DIVUP_NEXTRXNE = 0x01 +} UART2_LinDivUp_TypeDef; +typedef enum +{ + UART2_SYNCMODE_CLOCK_DISABLE = 0x80, + UART2_SYNCMODE_CLOCK_ENABLE = 0x08, + UART2_SYNCMODE_CPOL_LOW = 0x40, + UART2_SYNCMODE_CPOL_HIGH = 0x04, + UART2_SYNCMODE_CPHA_MIDDLE = 0x20, + UART2_SYNCMODE_CPHA_BEGINING = 0x02, + UART2_SYNCMODE_LASTBIT_DISABLE = 0x10, + UART2_SYNCMODE_LASTBIT_ENABLE = 0x01 +} UART2_SyncMode_TypeDef; +typedef enum +{ + UART2_WORDLENGTH_8D = 0x00, + UART2_WORDLENGTH_9D = 0x10 +} UART2_WordLength_TypeDef; +typedef enum +{ + UART2_MODE_RX_ENABLE = 0x08, + UART2_MODE_TX_ENABLE = 0x04, + UART2_MODE_TX_DISABLE = 0x80, + UART2_MODE_RX_DISABLE = 0x40, + UART2_MODE_TXRX_ENABLE = 0x0C +} UART2_Mode_TypeDef; +typedef enum +{ + UART2_FLAG_TXE = 0x0080, + UART2_FLAG_TC = 0x0040, + UART2_FLAG_RXNE = 0x0020, + UART2_FLAG_IDLE = 0x0010, + UART2_FLAG_OR_LHE = 0x0008, + UART2_FLAG_NF = 0x0004, + UART2_FLAG_FE = 0x0002, + UART2_FLAG_PE = 0x0001, + UART2_FLAG_SBK = 0x0101, + UART2_FLAG_LBDF = 0x0210, + UART2_FLAG_LHDF = 0x0302, + UART2_FLAG_LSF = 0x0301 +} UART2_Flag_TypeDef; +typedef enum +{ + UART2_IT_TXE = 0x0277, + UART2_IT_TC = 0x0266, + UART2_IT_RXNE = 0x0255, + UART2_IT_IDLE = 0x0244, + UART2_IT_OR = 0x0235, + UART2_IT_PE = 0x0100, + UART2_IT_LBDF = 0x0346, + UART2_IT_LHDF = 0x0412, + UART2_IT_RXNE_OR = 0x0205 +} UART2_IT_TypeDef; +extern "Python+C" void UART2_DeInit(void); +extern "Python+C" void UART2_Init(uint32_t BaudRate, UART2_WordLength_TypeDef WordLength, UART2_StopBits_TypeDef StopBits, UART2_Parity_TypeDef Parity, UART2_SyncMode_TypeDef SyncMode, UART2_Mode_TypeDef Mode); +extern "Python+C" void UART2_Cmd(FunctionalState NewState); +extern "Python+C" void UART2_ITConfig(UART2_IT_TypeDef UART2_IT, FunctionalState NewState); +extern "Python+C" void UART2_HalfDuplexCmd(FunctionalState NewState); +extern "Python+C" void UART2_IrDAConfig(UART2_IrDAMode_TypeDef UART2_IrDAMode); +extern "Python+C" void UART2_IrDACmd(FunctionalState NewState); +extern "Python+C" void UART2_LINBreakDetectionConfig(UART2_LINBreakDetectionLength_TypeDef UART2_LINBreakDetectionLength); +extern "Python+C" void UART2_LINConfig(UART2_LinMode_TypeDef UART2_Mode, UART2_LinAutosync_TypeDef UART2_Autosync, UART2_LinDivUp_TypeDef UART2_DivUp); +extern "Python+C" void UART2_LINCmd(FunctionalState NewState); +extern "Python+C" void UART2_SmartCardCmd(FunctionalState NewState); +extern "Python+C" void UART2_SmartCardNACKCmd(FunctionalState NewState); +extern "Python+C" void UART2_WakeUpConfig(UART2_WakeUp_TypeDef UART2_WakeUp); +extern "Python+C" void UART2_ReceiverWakeUpCmd(FunctionalState NewState); +extern "Python+C" uint8_t UART2_ReceiveData8(void); +extern "Python+C" uint16_t UART2_ReceiveData9(void); +extern "Python+C" void UART2_SendData8(uint8_t Data); +extern "Python+C" void UART2_SendData9(uint16_t Data); +extern "Python+C" void UART2_SendBreak(void); +extern "Python+C" void UART2_SetAddress(uint8_t UART2_Address); +extern "Python+C" void UART2_SetGuardTime(uint8_t UART2_GuardTime); +extern "Python+C" void UART2_SetPrescaler(uint8_t UART2_Prescaler); +extern "Python+C" FlagStatus UART2_GetFlagStatus(UART2_Flag_TypeDef UART2_FLAG); +extern "Python+C" void UART2_ClearFlag(UART2_Flag_TypeDef UART2_FLAG); +extern "Python+C" ITStatus UART2_GetITStatus(UART2_IT_TypeDef UART2_IT); +extern "Python+C" void UART2_ClearITPendingBit(UART2_IT_TypeDef UART2_IT); +extern "Python+C" void WWDG_Init(uint8_t Counter, uint8_t WindowValue); +extern "Python+C" void WWDG_SetCounter(uint8_t Counter); +extern "Python+C" uint8_t WWDG_GetCounter(void); +extern "Python+C" void WWDG_SWReset(void); +extern "Python+C" void WWDG_SetWindowValue(uint8_t WindowValue); +int16_t map_ui16(int16_t x, int16_t in_min, int16_t in_max, int16_t out_min, int16_t out_max); +uint8_t map_ui8(uint8_t x, uint8_t in_min, uint8_t in_max, uint8_t out_max, uint8_t out_min); +uint8_t ui8_max(uint8_t value_a, uint8_t value_b); +uint8_t ui8_min(uint8_t value_a, uint8_t value_b); +uint16_t filter(uint16_t ui16_new_value, uint16_t ui16_old_value, uint8_t ui8_alpha); +void crc16(uint8_t ui8_data, uint16_t *ui16_crc); +void adc_init(void); +extern volatile uint8_t ui8_display_fault_code; +extern volatile uint8_t ui8_system_state; +extern volatile uint16_t ui16_cadence_ticks_count_min_speed_adj; +extern volatile uint16_t ui16_adc_coaster_brake_threshold; +extern volatile uint8_t ui8_adc_motor_phase_current_max; +extern volatile uint8_t ui8_motor_enabled; +typedef struct _configuration_variables +{ + uint8_t ui8_battery_current_max; + uint16_t ui16_battery_low_voltage_cut_off_x10; + uint16_t ui16_wheel_perimeter; + uint8_t ui8_wheel_speed_max; + uint8_t ui8_motor_type; + uint8_t ui8_avaiable_for_future_use; + uint8_t ui8_assist_without_pedal_rotation_enabled; + uint8_t ui8_assist_with_error_enabled; + uint8_t ui8_battery_SOC_percentage_8b; + uint8_t ui8_set_parameter_enabled; + uint8_t ui8_street_mode_enabled; + uint8_t ui8_riding_mode; + uint8_t ui8_lights_configuration; + uint8_t ui8_startup_boost_enabled; + uint8_t ui8_auto_display_data_enabled; + uint8_t ui8_torque_sensor_adv_enabled; + uint8_t ui8_soc_percent_calculation; +} struct_configuration_variables; +void ebike_app_controller(void); +struct_configuration_variables *get_configuration_variables(void); +void ebike_app_init(void); +extern volatile uint8_t ui8_controller_duty_cycle_ramp_up_inverse_step; +extern volatile uint8_t ui8_controller_duty_cycle_ramp_down_inverse_step; +extern volatile uint16_t ui16_adc_voltage_cut_off; +extern volatile uint8_t ui8_adc_battery_current_filtered; +extern volatile uint8_t ui8_controller_adc_battery_current_target; +extern volatile uint8_t ui8_g_duty_cycle; +extern volatile uint8_t ui8_fw_hall_counter_offset; +extern volatile uint8_t ui8_fw_hall_counter_offset_max; +extern volatile uint8_t ui8_field_weakening_enabled; +extern volatile uint16_t ui16_hall_counter_total; +extern volatile uint8_t ui8_controller_duty_cycle_target; +extern volatile uint16_t ui16_hall_calib_cnt[6]; +extern volatile uint8_t ui8_hall_ref_angles[6]; +extern volatile uint8_t ui8_hall_counter_offsets[6]; +extern volatile uint8_t ui8_brake_state; +extern volatile uint16_t ui16_adc_voltage; +extern volatile uint16_t ui16_adc_torque; +extern volatile uint16_t ui16_adc_throttle; +extern volatile uint16_t ui16_cadence_sensor_ticks; +extern volatile uint16_t ui16_wheel_speed_sensor_ticks; +extern volatile uint8_t ui8_battery_SOC_saved_flag; +extern volatile uint8_t ui8_battery_SOC_reset_flag; +void hall_sensor_init(void); +void motor_enable_pwm(void); +void motor_disable_pwm(void); +extern "Python+C" void TRAP_IRQHandler(void); +extern "Python+C" void TLI_IRQHandler(void); +extern "Python+C" void AWU_IRQHandler(void); +extern "Python+C" void CLK_IRQHandler(void); +extern "Python+C" void EXTI_PORTA_IRQHandler(void); +extern "Python+C" void EXTI_PORTB_IRQHandler(void); +extern "Python+C" void EXTI_PORTC_IRQHandler(void); +extern "Python+C" void EXTI_PORTD_IRQHandler(void); +extern "Python+C" void EXTI_PORTE_IRQHandler(void); +extern "Python+C" void SPI_IRQHandler(void); +extern "Python+C" void TIM1_UPD_OVF_TRG_BRK_IRQHandler(void); +void TIM1_CAP_COM_IRQHandler(void); +extern "Python+C" void TIM2_UPD_OVF_BRK_IRQHandler(void); +extern "Python+C" void TIM2_CAP_COM_IRQHandler(void); +extern "Python+C" void TIM3_UPD_OVF_BRK_IRQHandler(void); +extern "Python+C" void TIM3_CAP_COM_IRQHandler(void); +extern "Python+C" void I2C_IRQHandler(void); +extern "Python+C" void UART2_TX_IRQHandler(void); +extern "Python+C" void UART2_RX_IRQHandler(void); +extern "Python+C" void ADC1_IRQHandler(void); +extern "Python+C" void TIM4_UPD_OVF_IRQHandler(void); +extern "Python+C" void EEPROM_EEC_IRQHandler(void); +void brake_init(void); +void pwm_init(void); +void uart2_init(void); +int uart_put_char(int c); +int uart_get_char(void); +void EEPROM_init(void); +void EEPROM_controller(uint8_t ui8_operation, uint8_t ui8_byte_init); +void lights_init(void); +void lights_set_state(uint8_t ui8_state); +extern volatile struct_configuration_variables m_configuration_variables; +static uint8_t ui8_assist_level; +static uint8_t ui8_assist_level_temp; +static uint8_t ui8_assist_level_01_flag; +static uint8_t ui8_riding_mode_temp; +static uint8_t ui8_lights_flag; +static uint8_t ui8_lights_on_5s; +static uint8_t ui8_menu_flag; +static uint8_t ui8_menu_index; +static uint8_t ui8_data_index; +static uint8_t ui8_menu_counter; +static uint8_t ui8_display_function_code; +static uint8_t ui8_display_function_code_temp; +static uint8_t ui8_menu_function_enabled; +static uint8_t ui8_display_data_enabled; +static uint16_t ui16_display_data; +static uint16_t ui16_data_value; +static uint8_t ui8_auto_display_data_flag; +static uint8_t ui8_auto_display_data_status; +static uint8_t ui8_auto_data_number_display; +static uint16_t ui16_display_data_factor; +static uint8_t ui8_delay_display_function; +static uint8_t ui8_display_data_on_startup; +static uint8_t ui8_set_parameter_enabled_temp; +static uint8_t ui8_auto_display_data_enabled_temp; +static uint8_t ui8_street_mode_enabled_temp; +static uint8_t ui8_torque_sensor_adv_enabled_temp; +static uint8_t ui8_assist_without_pedal_rotation_temp; +static uint8_t ui8_walk_assist_enabled_array[2]; +static uint8_t ui8_display_battery_soc; +static uint8_t ui8_display_riding_mode; +static uint8_t ui8_display_lights_configuration; +static uint8_t ui8_display_alternative_lights_configuration; +static uint8_t ui8_display_torque_sensor_flag_1; +static uint8_t ui8_display_torque_sensor_flag_2; +static uint8_t ui8_display_torque_sensor_value; +static uint8_t ui8_display_torque_sensor_step; +static uint8_t ui8_display_function_status[3][5]; +static uint8_t ui8_lights_configuration_2; +static uint8_t ui8_lights_configuration_3; +static uint8_t ui8_lights_configuration_temp; +static uint8_t ui8_riding_mode_parameter; +static uint8_t ui8_assist_without_pedal_rotation_threshold; +static uint8_t ui8_lights_state; +static uint8_t ui8_lights_button_flag; +static uint8_t ui8_field_weakening_erps_delta; +static uint8_t ui8_optional_ADC_function; +static uint8_t ui8_walk_assist_level; +static uint16_t ui16_battery_voltage_filtered_x10; +static uint16_t ui16_battery_voltage_calibrated_x10; +extern volatile uint16_t ui16_battery_voltage_soc_filtered_x10; +static uint16_t ui16_battery_power_x10; +static uint16_t ui16_battery_power_filtered_x10; +static uint16_t ui16_actual_battery_capacity; +static uint32_t ui32_wh_x10; +static uint32_t ui32_wh_sum_x10; +extern volatile uint32_t ui32_wh_x10_offset; +static uint32_t ui32_wh_since_power_on_x10; +extern volatile uint16_t ui16_battery_SOC_percentage_x10; +extern volatile uint8_t ui8_battery_SOC_init_flag; +static uint8_t ui8_battery_state_of_charge; +static uint8_t ui8_duty_cycle_ramp_up_inverse_step; +static uint8_t ui8_duty_cycle_ramp_up_inverse_step_default; +static uint8_t ui8_duty_cycle_ramp_down_inverse_step; +static uint8_t ui8_duty_cycle_ramp_down_inverse_step_default; +static uint16_t ui16_battery_voltage_filtered_x1000; +static uint16_t ui16_battery_no_load_voltage_filtered_x10; +static uint8_t ui8_battery_current_filtered_x10; +static uint8_t ui8_adc_battery_current_max; +static uint8_t ui8_adc_battery_current_target; +static uint8_t ui8_duty_cycle_target; +static uint16_t ui16_duty_cycle_percent; +static uint8_t ui8_error_battery_overcurrent; +static uint8_t ui8_adc_battery_overcurrent; +static uint8_t ui8_adc_battery_current_max_array[2]; +static uint8_t ui8_adc_motor_phase_current_max_array[2]; +static uint8_t ui8_adc_battery_overcurrent_array[2]; +static uint16_t ui16_motor_speed_erps; +static uint8_t ui8_pedal_cadence_RPM; +static uint8_t ui8_motor_deceleration; +static uint8_t ui8_pedal_torque_per_10_bit_ADC_step_x100; +static uint8_t ui8_pedal_torque_per_10_bit_ADC_step_calc_x100; +static uint16_t ui16_adc_pedal_torque_offset; +static uint16_t ui16_adc_pedal_torque_offset_init; +static uint16_t ui16_adc_pedal_torque_offset_cal; +static uint16_t ui16_adc_pedal_torque_offset_min; +static uint16_t ui16_adc_pedal_torque_offset_max; +static uint8_t ui8_adc_pedal_torque_offset_error; +static uint16_t ui16_adc_pedal_torque; +static uint16_t ui16_adc_pedal_torque_delta; +static uint16_t ui16_adc_pedal_torque_delta_temp; +static uint16_t ui16_adc_pedal_torque_delta_no_boost; +static uint16_t ui16_pedal_torque_x100; +static uint16_t ui16_human_power_x10; +static uint16_t ui16_human_power_filtered_x10; +static uint8_t ui8_torque_sensor_calibrated; +static uint16_t ui16_pedal_weight_x100; +static uint16_t ui16_pedal_torque_step_temp; +static uint8_t ui8_torque_sensor_calibration_flag; +static uint8_t ui8_torque_sensor_calibration_started; +static uint8_t ui8_pedal_torque_per_10_bit_ADC_step_x100_array[2]; +static uint8_t ui8_eMTB_based_on_power; +static uint16_t ui16_wheel_speed_x10; +static uint8_t ui8_wheel_speed_max_array[2]; +static uint8_t ui8_display_ready_flag; +static uint8_t ui8_startup_counter; +static uint16_t ui16_oem_wheel_speed_time; +static uint8_t ui8_oem_wheel_diameter; +static uint32_t ui32_odometer_compensation_mm; +static uint8_t ui8_adc_throttle_assist; +static uint8_t ui8_throttle_adc_in; +static uint8_t ui8_throttle_mode_array[2]; +static uint8_t ui8_cruise_threshold_speed_x10_array[2]; +static uint8_t ui8_cruise_button_flag; +static uint8_t ui8_walk_assist_flag; +static uint8_t ui8_walk_assist_speed_target_x10; +static uint8_t ui8_walk_assist_duty_cycle_counter; +static uint8_t ui8_walk_assist_duty_cycle_target; +static uint8_t ui8_walk_assist_duty_cycle_max; +static uint8_t ui8_walk_assist_adj_delay; +static uint16_t ui16_walk_assist_wheel_speed_counter; +static uint16_t ui16_walk_assist_erps_target; +static uint16_t ui16_walk_assist_erps_min; +static uint16_t ui16_walk_assist_erps_max; +static uint8_t ui8_walk_assist_speed_flag; +static uint8_t ui8_startup_boost_at_zero; +static uint8_t ui8_startup_boost_flag; +static uint8_t ui8_startup_boost_enabled_temp; +static uint16_t ui16_startup_boost_factor_array[120]; +static uint8_t ui8_smooth_start_flag; +static uint8_t ui8_smooth_start_counter; +static uint8_t ui8_smooth_start_counter_set; +static uint8_t ui8_startup_assist_flag; +static uint8_t ui8_startup_assist_adc_battery_current_target; +static uint16_t ui16_adc_motor_temperature_filtered; +static uint16_t ui16_motor_temperature_filtered_x10; +static uint8_t ui8_motor_temperature_max_value_to_limit_array[2]; +static uint8_t ui8_motor_temperature_min_value_to_limit_array[2]; +extern volatile uint8_t ui8_received_package_flag; +extern volatile uint8_t ui8_rx_buffer[7]; +extern volatile uint8_t ui8_rx_counter; +extern volatile uint8_t ui8_tx_buffer[9]; +extern volatile uint8_t ui8_byte_received; +extern volatile uint8_t ui8_state_machine; +extern volatile uint8_t ui8_working_status; +static uint8_t ui8_data_index_array[6]; +static uint8_t ui8_delay_display_array[6]; +static uint8_t ui8_riding_mode_parameter_array[8][5]; +static void uart_receive_package(void); +static void uart_send_package(void); +static void get_battery_voltage(void); +static void get_pedal_torque(void); +static void calc_wheel_speed(void); +static void calc_cadence(void); +static void ebike_control_lights(void); +static void ebike_control_motor(void); +static void check_system(void); +static void set_motor_ramp(void); +static void apply_startup_boost(void); +static void apply_smooth_start(void); +static void apply_power_assist(void); +static void apply_torque_assist(void); +static void apply_cadence_assist(void); +static void apply_emtb_assist(void); +static void apply_hybrid_assist(void); +static void apply_cruise(void); +static void apply_walk_assist(void); +static void apply_throttle(void); +static void apply_temperature_limiting(void); +static void apply_speed_limit(void); +static void calc_oem_wheel_speed(void); +static void apply_torque_sensor_calibration(void); +static void check_battery_soc(void); +uint16_t read_battery_soc(void); +uint16_t calc_battery_soc_x10(uint16_t ui16_battery_soc_offset_x10, uint16_t ui16_battery_soc_step_x10, uint16_t ui16_cell_volts_max_x100, uint16_t ui16_cell_volts_min_x100); +static uint8_t ui8_default_flash_state; +static const uint8_t ui8_default_array[20]; +static uint8_t ui8_error_number; +void wheel_speed_sensor_init(void); +void pas_init(void); +extern "Python+C" void pas2_init(void); +void timers_init(void); +extern volatile uint8_t ui8_tim4_counter; +void torque_sensor_init(void); +int main(void); +void UART2_IRQHandler(void); +void TIM4_IRQHandler(void); +void HALL_SENSOR_A_PORT_IRQHandler(void); +void HALL_SENSOR_B_PORT_IRQHandler(void); +void HALL_SENSOR_C_PORT_IRQHandler(void); +static uint8_t ui8_1ms_counter; +static uint8_t ui8_ebike_app_controller_counter; +static const uint8_t ui8_svm_table[256]; +extern uint8_t ui8_hall_360_ref_valid; +extern uint8_t ui8_motor_commutation_type; +static uint8_t ui8_motor_phase_absolute_angle; +static uint8_t ui8_counter_duty_cycle_ramp_up; +static uint8_t ui8_counter_duty_cycle_ramp_down; +static uint8_t ui8_foc_angle_accumulated; +static uint8_t ui8_foc_flag; +static uint8_t ui8_g_foc_angle; +static uint8_t ui8_foc_angle_multiplier; +static uint8_t ui8_adc_foc_angle_current; +static uint8_t ui8_adc_battery_current_acc; +static uint8_t ui8_adc_motor_phase_current; +static uint16_t ui16_cadence_sensor_ticks_counter_min; +static uint8_t ui8_pas_state_old; +static uint16_t ui16_cadence_calc_counter; +static uint16_t ui16_cadence_stop_counter; +static uint8_t ui8_cadence_calc_ref_state; +static const uint8_t ui8_pas_old_valid_state[4]; +extern volatile uint16_t ui16_wheel_speed_sensor_ticks_counter_min; +extern volatile uint8_t ui8_hall_state_irq; +extern volatile uint8_t ui8_hall_60_ref_irq[2]; +static uint16_t ui16_hall_360_ref; +static uint8_t ui8_hall_sensors_state_last; +static uint16_t ui16_hall_60_ref_old; +static uint8_t ui8_hall_counter_offset; +static uint16_t ui16_a; +static uint16_t ui16_b; +static uint16_t ui16_c; +static uint8_t ui8_temp; +void timer2_init(void); +void timer3_init(void); +void timer4_init(void); diff --git a/tests/test_diag.py b/tests/test_diag.py new file mode 100644 index 00000000..e2d6e6a1 --- /dev/null +++ b/tests/test_diag.py @@ -0,0 +1,30 @@ +import pytest +from sim._tsdz2 import ffi, lib as ebike # module generated from c-code + +# Set up initial values before each test +@pytest.fixture(autouse=True) +def setup_ebike(): + # Set up initial values before each test + ebike.m_configuration_variables.ui16_wheel_perimeter = 2070 + yield + # Teardown after each test (optional) + ebike.ui16_wheel_speed_sensor_ticks = 0 + ebike.ui16_wheel_speed_x10 = 0 + +def test_battery_current_max_from_battery_power_max(): + '''Test function for the battery current maximum calculation based on the "battery power max" limits from config.h''' +# Test function for calc_wheel_speed + ebike.m_configuration_variables.ui8_battery_current_max = 255 # maxout the other limit so that battery limit is based on the battery power + ebike.ui16_battery_voltage_filtered_x1000 = 48*1000 + ebike.ebike_app_init() + result = [ + ebike.ui8_adc_battery_current_max_array[0], + ebike.ui8_adc_battery_current_max_array[1], + ] + expected = [57, 57] + assert result == expected + + +# Run the tests +if __name__ == '__main__': + pytest.main() diff --git a/tests/test_display.py b/tests/test_display.py new file mode 100644 index 00000000..3c81b27e --- /dev/null +++ b/tests/test_display.py @@ -0,0 +1,36 @@ +import pytest +from sim._tsdz2 import ffi, lib as ebike # module generated from c-code + +# Mock UART +class UART: + message = bytearray(b"\x59\x40\x00\x1C\x00\x1B\xD0") + index = 0 + + @staticmethod + @ffi.def_extern() + def UART2_GetFlagStatus(flag_key): + if flag_key in [ebike.UART2_FLAG_RXNE, ebike.UART2_FLAG_TXE]: + return 1 # ready + return 0 # unhandled + + @staticmethod + @ffi.def_extern() + def UART2_ReceiveData8(): + byte = UART.message[UART.index] + UART.index = (UART.index + 1) % len(UART.message) + return byte + +# Test the receive function +def test_receive(): + assert ebike.uart_get_char() == 0x59 + assert ebike.uart_get_char() == 0x40 + assert ebike.uart_get_char() == 0x00 + assert ebike.uart_get_char() == 0x1C + assert ebike.uart_get_char() == 0x00 + assert ebike.uart_get_char() == 0x1B + assert ebike.uart_get_char() == 0xD0 + assert ebike.uart_get_char() == 0x59 + +# Run the tests +if __name__ == '__main__': + pytest.main() diff --git a/tests/test_wheel_speed.py b/tests/test_wheel_speed.py new file mode 100644 index 00000000..fbd30028 --- /dev/null +++ b/tests/test_wheel_speed.py @@ -0,0 +1,85 @@ +import pytest +from sim._tsdz2 import ffi, lib as ebike # module generated from c-code + + +# Set up initial values before each test +@pytest.fixture(autouse=True) +def setup_ebike(): + # Set up initial values before each test + ebike.m_configuration_variables.ui16_wheel_perimeter = 2070 + yield + # Teardown after each test (optional) + ebike.ui16_wheel_speed_sensor_ticks = 0 + ebike.ui16_wheel_speed_x10 = 0 + + +# Test function for calc_wheel_speed +def test_calc_wheel_speed_simple(): + ebike.ui16_wheel_speed_sensor_ticks = 10000 + ebike.calc_wheel_speed() + result = ebike.ui16_wheel_speed_x10 + expected = 141 + assert result == expected, f'Test failed! Expected {expected} value, got {result} value' + +# Parameterized test function with different ticks values +@pytest.mark.parametrize("ticks, expected", [ + # (0, 0), + (1, 39624), + (1000, 1415), + (2000, 707), + (5000, 283), + (10000, 141), + (20000, 70), + (65535, 21) +]) +def test_calc_wheel_speed_with_various_ticks(ticks, expected): + ebike.ui16_wheel_speed_sensor_ticks = ticks + ebike.calc_wheel_speed() + result = ebike.ui16_wheel_speed_x10 + assert result == expected, f'Expected {expected/10}km/h, got {result/10}km/h' + + + + + +MOTOR_TASK_FREQ = 16000000 / (420*2) +def wheel_speed_calc_float(ui16_wheel_perimeter: int, ui16_wheel_speed_sensor_ticks: int) -> float: + rps = MOTOR_TASK_FREQ / ui16_wheel_speed_sensor_ticks + kph = rps * ui16_wheel_perimeter * ((3600 / (1000 * 1000))) + return kph + +def wheel_inch_to_mm_circumference(wheel_inch: float) -> float: + diameter_mm = wheel_inch * 25.4 + circumference_mm = diameter_mm * 3.14159 + return circumference_mm + + +@pytest.mark.parametrize("wheel_size", range(14, 30)) +def test_wheel_speed_calculation_precision_parametrized(wheel_size): + """ + Test wheel speed calculation precision for different wheel sizes + + :param ebike: An instance of the ebike with necessary attributes and methods + :param wheel_size: The wheel perimeter to test + """ + ui16_wheel_perimeter = int(wheel_inch_to_mm_circumference(wheel_size)) + ebike.m_configuration_variables.ui16_wheel_perimeter = ui16_wheel_perimeter + error = {} + for ticks in range(1000, 65535, 100): # Range from 1 to 10000 + ebike.ui16_wheel_speed_sensor_ticks = ticks + ebike.calc_wheel_speed() + result = ebike.ui16_wheel_speed_x10 / 10 + expected = wheel_speed_calc_float(ui16_wheel_perimeter, ticks) + assert result == pytest.approx(expected, rel=0.1, abs=0.1), ( + f"Test failed for wheel size {wheel_size} (perimeter {ui16_wheel_perimeter}) and tick count {ticks}! " + f"Expected {expected:.2f}, got {result:.2f}" + ) + error[ticks] = abs(result - expected) + # pytest -s to print + print(f"Biggest error: {max(error.values())}") + print(f"Average error: {sum(error.values()) / len(error)}") + + +# Run the tests +if __name__ == '__main__': + pytest.main() From 5452e26eb3940d1caf7c336bca65d22df58b9de7 Mon Sep 17 00:00:00 2001 From: dzid26 Date: Thu, 11 Jul 2024 15:28:42 +0100 Subject: [PATCH 2/5] Enable coverage calculation Added pytest --force --- .github/workflows/build.yaml | 13 ++++++++++++- README.md | 5 +++++ tests/conftest.py | 29 ++++++++++++++++++++++++++++- tests/gcovr.cfg | 10 ++++++++++ tests/load_c_code.py | 32 +++++++++++++++++++++++++------- 5 files changed, 80 insertions(+), 9 deletions(-) create mode 100644 tests/gcovr.cfg diff --git a/.github/workflows/build.yaml b/.github/workflows/build.yaml index 046c4233..093366ee 100644 --- a/.github/workflows/build.yaml +++ b/.github/workflows/build.yaml @@ -103,6 +103,7 @@ jobs: run: | pip install -e . pip install --upgrade pytest-md-report + pip install gcovr - name: Run tests env: REPORT_OUTPUT: md_report.md @@ -111,7 +112,7 @@ jobs: rm tests/sim/_tsdz2.cdef # make sure cdef is generated from the source to check testing framework echo "REPORT_FILE=${REPORT_OUTPUT}" >> "$GITHUB_ENV" - pytest --md-report --md-report-flavor gfm --md-report-output "$REPORT_OUTPUT" + pytest --coverage --md-report --md-report-flavor gfm --md-report-output "$REPORT_OUTPUT" - name: Output reports to the job summary if: always() shell: bash @@ -131,6 +132,16 @@ jobs: header: test-report recreate: true path: ${{ env.REPORT_FILE }} + - name: Collect coverage data + run: | + echo "### Coverage Report" >> $GITHUB_STEP_SUMMARY + gcovr -r tests --print-summary >> $GITHUB_STEP_SUMMARY + echo "" >> $GITHUB_STEP_SUMMARY + - uses: actions/upload-artifact@v4 + with: + name: coverage_report + path: | + tests/coverage_report.html Compare_builds: needs: [Build_Windows, Build_Linux] diff --git a/README.md b/README.md index e40fec79..31f84ca1 100644 --- a/README.md +++ b/README.md @@ -75,6 +75,11 @@ Run tests: Any changes should have a corresponding unit test added, unless unfeasible. +Calculate coverage and generate html report (probably will not work on Windows): +`pytest --coverage` + +Tests with coverage are executed in the CI as well. + ### Compile the firmware manually - `cd src/` and use `make` or `compile.bat` to compile the firmware. diff --git a/tests/conftest.py b/tests/conftest.py index b8fba28c..2aee66bc 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -1,11 +1,19 @@ +import subprocess +import importlib from load_c_code import load_code +def pytest_addoption(parser): + parser.addoption("--coverage", action="store_true", help="Enable coverage analysis with gcovr") + parser.addoption("--force", action="store_true", help="Force recompile") + def pytest_sessionstart(session): """ Called after the Session object has been created and before performing collection and entering the run test loop. """ - load_code('_tsdz2') + lib, _ = load_code('_tsdz2', coverage=session.config.option.coverage, force_recompile=session.config.option.force) + if session.config.option.coverage: + lib.__gcov_reset() def pytest_configure(config): @@ -19,6 +27,25 @@ def pytest_sessionfinish(session, exitstatus): Called after whole test run finished, right before returning the exit status to the system. """ + + if session.config.option.coverage: + try: + module = importlib.import_module("sim._tsdz2") + module.lib.__gcov_dump() + except Exception as e: + # __gcov_dump() is stil hidden ion some compilers? Failing on CI Ubuntu 22.04, but worked on 20.04 + print(f"Error dumping gcov: {e}. Try running gcovr manually after pytest process exits.") + try: + # Attempt to call gcovr with the specified arguments + subprocess.call(['gcovr', '-r', 'tests', '--print-summary']) + except FileNotFoundError: + # Handle the case where gcovr is not found (i.e., not installed) + print(" Install Gcovr to generate code coverage report.") + except Exception as e: + # E.g. gcov will fail if cffi compiled code with msvc + print(f"Error running gcovr: {e}") + # btw, if there is aerror(warning) "bgcov profiling error: ... overwriting an existing profile data with a different timestamp" + # it has to do with pytest without being called in the background by e.g. VScode without --coverage and recompiling the objects def pytest_unconfigure(config): """ diff --git a/tests/gcovr.cfg b/tests/gcovr.cfg new file mode 100644 index 00000000..85b82abb --- /dev/null +++ b/tests/gcovr.cfg @@ -0,0 +1,10 @@ +# Only show coverage for files in src/, lib/foo, or for main.cpp files. +filter = sim/ +exclude-unreachable-branches=no +exclude-noncode-lines=yes +exclude-function-lines=yes + + +html-details=coverage_report.html +html-self-contained=yes +print-summary=yes \ No newline at end of file diff --git a/tests/load_c_code.py b/tests/load_c_code.py index 0445d0d0..fd17d49c 100644 --- a/tests/load_c_code.py +++ b/tests/load_c_code.py @@ -150,12 +150,12 @@ def generate_cdef(module_name, src_file): fp.write(cdef) return cdef - -def load_code(module_name, force_recompile=False): +def load_code(module_name, coverage=False, force_recompile=False): # Load previous combined hash hash_file_path = os.path.join(LIB_DIR, f"{module_name}.sha") + # Recalculate hash if code or arguments have changed with Checksum(hash_file_path, source_dirs, module_name+"".join(define_macros)) as skip: - if not skip or force_recompile: + if not skip or force_recompile or coverage: # also recompile if coverage is enabled because backround test runners are compiling without gcov print("Collecting source code..") source_content_list: List[str] = [] source_files = [os.path.abspath(os.path.join(dir, file)) for dir in source_dirs for file in os.listdir(dir) if file.endswith('.c')] @@ -167,7 +167,6 @@ def load_code(module_name, force_recompile=False): combined_source = fake_defines + combined_source combined_source = re.sub(r"#\s*include\s*<.*?>", r"//\g<0>", combined_source) # comment out standard includes combined_source_file_path = os.path.join(LIB_DIR, f"{module_name}.i") - with open(combined_source_file_path, "w", encoding="utf8") as fp: fp.write(combined_source) try: @@ -176,7 +175,20 @@ def load_code(module_name, force_recompile=False): print(f"{e}\n\033[93mFailed to generate cdef using your cpp standard headers!!!\nYou may have to edit it manually. Continuing...\033[0m") with open(os.path.join(LIB_DIR, f"{module_name}.cdef"), "r", encoding="utf8") as fp: cdef = fp.read() - + extra_compile_args = compiler_args + extra_link_args = linker_args + # Coverage + if coverage: + # expose gcov api, (will not work with microsoft compiler) + cdef += "\n" + "extern void __gcov_reset(void);" + cdef += "\n" + "extern void __gcov_dump(void);" + # add inner coverage exclusion markers + combined_source = "extern void __gcov_reset(void);\n" + combined_source + combined_source = "extern void __gcov_dump(void);\n" + combined_source + combined_source = "// GCOVR_EXCL_STOP\n" + combined_source + "\n// GCOVR_EXCL_START" + extra_compile_args += ["--coverage"] + extra_link_args += ["--coverage"] + # Create a CFFI instance ffibuilder = cffi.FFI() print("Processing cdefs...") @@ -184,12 +196,18 @@ def load_code(module_name, force_recompile=False): ffibuilder.set_source(module_name, combined_source, include_dirs=[os.path.abspath(d) for d in include_dirs], define_macros=[(macro, None) for macro in define_macros], - extra_compile_args=compiler_args, - extra_link_args=linker_args + extra_compile_args=extra_compile_args, + extra_link_args=extra_link_args ) print("Compiling...") tmpdir = os.path.abspath(LIB_DIR) ffibuilder.compile(tmpdir=tmpdir) + if coverage: # Add outer coverage exclusion markers after generating ffi api c-code + with open(os.path.join(LIB_DIR, f"{module_name}.c"), "r+", encoding="utf8") as fp: + c = fp.readlines() # add inline comments because it may matter for gcov to keep the number of lines, idk: + c[0] = c[0].strip() + " // GCOVR_EXCL_START" + c[-1] = c[-1].strip() + " // GCOVR_EXCL_STOP" + fp.seek(0); fp.writelines(c); fp.truncate() else: print("No changes found. Skipping compilation") From df8b31d81d6daba65ef016f5c7403645a2044776 Mon Sep 17 00:00:00 2001 From: dzid26 Date: Thu, 11 Jul 2024 20:51:51 +0100 Subject: [PATCH 3/5] Enabled error on Warning in strict mode MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Fixed [-Wparentheses] parentheses around ‘-’ inside ‘<<’ BATTERY_VOLTAGE_SHUTDOWN_10_BIT Fixed [-Wdiscarded-qualifiers] return discards ‘volatile’ qualifier from pointer target type &m_configuration_variables; Fixed [-Wsign-compare] comparison of integer expressions of different signedness: ‘int’ and ‘unsigned int’ Fixed [-Wunused-but-set-variable] enable walk assist debounce code path by default Fixed [-Wunused-label] Fixed warning C4244: '=': conversion from 'int16_t' to 'uint8_t', possible loss of data --- .github/workflows/build.yaml | 7 +++++-- src/config.h | 6 +++--- src/ebike_app.c | 21 ++++++++++----------- src/main.h | 4 ++-- src/motor.c | 10 +++++----- tests/conftest.py | 5 ++++- tests/load_c_code.py | 8 +++++--- 7 files changed, 34 insertions(+), 27 deletions(-) diff --git a/.github/workflows/build.yaml b/.github/workflows/build.yaml index 093366ee..d994e6a1 100644 --- a/.github/workflows/build.yaml +++ b/.github/workflows/build.yaml @@ -89,7 +89,7 @@ jobs: Tests: - runs-on: ubuntu-latest + runs-on: ubuntu-20.04 permissions: contents: read pull-requests: write @@ -112,7 +112,10 @@ jobs: rm tests/sim/_tsdz2.cdef # make sure cdef is generated from the source to check testing framework echo "REPORT_FILE=${REPORT_OUTPUT}" >> "$GITHUB_ENV" - pytest --coverage --md-report --md-report-flavor gfm --md-report-output "$REPORT_OUTPUT" + + gcc -Wall -Wextra -Q --help=warning # print warnings that shouldbe enabled by pytest --strict + + pytest --strict --coverage --md-report --md-report-flavor gfm --md-report-output "$REPORT_OUTPUT" - name: Output reports to the job summary if: always() shell: bash diff --git a/src/config.h b/src/config.h index cc9cda47..bbc35158 100644 --- a/src/config.h +++ b/src/config.h @@ -44,7 +44,7 @@ #define WHEEL_MAX_SPEED 25 #define ENABLE_LIGHTS 1 #define ENABLE_WALK_ASSIST 1 -#define ENABLE_BRAKE_SENSOR 0 +#define ENABLE_BRAKE_SENSOR 1 #define ENABLE_THROTTLE 0 #define ENABLE_TEMPERATURE_LIMIT 0 #define ENABLE_STREET_MODE_ON_STARTUP 1 @@ -111,7 +111,7 @@ #define WALK_ASSIST_LEVEL_3 40 #define WALK_ASSIST_LEVEL_4 45 #define WALK_ASSIST_THRESHOLD_SPEED_X10 60 -#define WALK_ASSIST_DEBOUNCE_ENABLED 0 +#define WALK_ASSIST_DEBOUNCE_ENABLED 1 #define WALK_ASSIST_DEBOUNCE_TIME 60 #define CRUISE_TARGET_SPEED_LEVEL_1 15 #define CRUISE_TARGET_SPEED_LEVEL_2 18 @@ -126,7 +126,7 @@ #define ASSIST_THROTTLE_MAX_VALUE 255 #define STREET_MODE_WALK_ENABLED 1 #define DATA_DISPLAY_ON_STARTUP 1 -#define FIELD_WEAKENING_ENABLED 0 +#define FIELD_WEAKENING_ENABLED 1 #define PEDAL_TORQUE_ADC_OFFSET_ADJ 20 #define PEDAL_TORQUE_ADC_RANGE_ADJ 20 #define PEDAL_TORQUE_ADC_ANGLE_ADJ 36 diff --git a/src/ebike_app.c b/src/ebike_app.c index cf9156c8..d9bcba6d 100644 --- a/src/ebike_app.c +++ b/src/ebike_app.c @@ -752,7 +752,7 @@ static void apply_power_assist(void) ui8_adc_battery_current_target = ui8_adc_battery_current_max; } else { - ui8_adc_battery_current_target = ui16_adc_battery_current_target; + ui8_adc_battery_current_target = (uint8_t)ui16_adc_battery_current_target; } #if STARTUP_ASSIST_ENABLED @@ -815,7 +815,7 @@ static void apply_torque_assist(void) ui8_adc_battery_current_target = ui8_adc_battery_current_max; } else { - ui8_adc_battery_current_target = ui16_adc_battery_current_target_torque_assist; + ui8_adc_battery_current_target = (uint8_t)ui16_adc_battery_current_target_torque_assist; } #if STARTUP_ASSIST_ENABLED @@ -865,7 +865,7 @@ static void apply_cadence_assist(void) ui8_adc_battery_current_target = ui8_adc_battery_current_max; } else { - ui8_adc_battery_current_target = ui16_adc_battery_current_target_cadence_assist; + ui8_adc_battery_current_target = (uint8_t)ui16_adc_battery_current_target_cadence_assist; } // set duty cycle target @@ -926,7 +926,7 @@ static void apply_emtb_assist(void) ui8_adc_battery_current_target = ui8_adc_battery_current_max; } else { - ui8_adc_battery_current_target = ui16_adc_battery_current_target_eMTB_assist; + ui8_adc_battery_current_target = (uint8_t)ui16_adc_battery_current_target_eMTB_assist; } #if STARTUP_ASSIST_ENABLED @@ -1014,7 +1014,7 @@ static void apply_hybrid_assist(void) ui8_adc_battery_current_target = ui8_adc_battery_current_max; } else { - ui8_adc_battery_current_target = ui16_adc_battery_current_target; + ui8_adc_battery_current_target = (uint8_t)ui16_adc_battery_current_target; } #if STARTUP_ASSIST_ENABLED @@ -1435,7 +1435,7 @@ static void apply_temperature_limiting(void) } else { // adjust target current if motor over temperature limit - ui8_adc_battery_current_target = map_ui16((uint16_t) ui16_motor_temperature_filtered_x10, + ui8_adc_battery_current_target = (uint8_t)map_ui16((uint16_t) ui16_motor_temperature_filtered_x10, (uint16_t) ((uint8_t)ui8_motor_temperature_min_value_to_limit_array[TEMPERATURE_SENSOR_TYPE] * (uint8_t)10U), (uint16_t) ((uint8_t)ui8_motor_temperature_max_value_to_limit_array[TEMPERATURE_SENSOR_TYPE] * (uint8_t)10U), ui8_adc_battery_current_target, @@ -1448,7 +1448,7 @@ static void apply_speed_limit(void) { if (m_configuration_variables.ui8_wheel_speed_max) { // set battery current target - ui8_adc_battery_current_target = map_ui16((uint16_t) ui16_wheel_speed_x10, + ui8_adc_battery_current_target = (uint8_t)map_ui16((uint16_t) ui16_wheel_speed_x10, (uint16_t) (((uint8_t)(m_configuration_variables.ui8_wheel_speed_max) * (uint8_t)10U) - (uint8_t)20U), (uint16_t) (((uint8_t)(m_configuration_variables.ui8_wheel_speed_max) * (uint8_t)10U) + (uint8_t)20U), ui8_adc_battery_current_target, @@ -1647,9 +1647,8 @@ static void get_pedal_torque(void) } -struct_configuration_variables* get_configuration_variables(void) -{ - return &m_configuration_variables; +struct_configuration_variables* get_configuration_variables(void) { + return (struct_configuration_variables*) &m_configuration_variables; } @@ -2926,7 +2925,7 @@ static void uart_send_package(void) // reserved for VLCD5, torque sensor value TE and TE1 #if ENABLE_VLCD5 - ui8_tx_buffer[3] = ui16_adc_pedal_torque_offset_init; + ui8_tx_buffer[3] = (uint8_t)ui16_adc_pedal_torque_offset_init; if (ui16_adc_pedal_torque > ui16_adc_pedal_torque_offset_init) { ui8_tx_buffer[4] = ui16_adc_pedal_torque - ui16_adc_pedal_torque_offset_init; } diff --git a/src/main.h b/src/main.h index 03584520..822fbf7a 100644 --- a/src/main.h +++ b/src/main.h @@ -135,7 +135,7 @@ HALL_COUNTER_OFFSET_UP: 29 -> 44 #define HALL_COUNTER_OFFSET_UP (HALL_COUNTER_OFFSET_DOWN + 21) #define FW_HALL_COUNTER_OFFSET_MAX 5 // 5*4=20us max time offset -#define MOTOR_ROTOR_INTERPOLATION_MIN_ERPS 10 +#define MOTOR_ROTOR_INTERPOLATION_MIN_ERPS 10U // adc torque offset gap value for error #define ADC_TORQUE_SENSOR_OFFSET_THRESHOLD 30 @@ -372,7 +372,7 @@ HALL_COUNTER_OFFSET_UP: 29 -> 44 // battery voltage to be subtracted from the cut-off 8bit #define DIFFERENCE_CUT_OFF_SHUTDOWN_8_BIT 26 // battery voltage for saving battery capacity at shutdown -#define BATTERY_VOLTAGE_SHUTDOWN_8_BIT (uint8_t) ((uint16_t)(BATTERY_LOW_VOLTAGE_CUT_OFF * 250 / BATTERY_VOLTAGE_PER_10_BIT_ADC_STEP_X1000)) - ((uint16_t) DIFFERENCE_CUT_OFF_SHUTDOWN_8_BIT) +#define BATTERY_VOLTAGE_SHUTDOWN_8_BIT (uint8_t) ((uint16_t)((BATTERY_LOW_VOLTAGE_CUT_OFF * 250 / BATTERY_VOLTAGE_PER_10_BIT_ADC_STEP_X1000)) - ((uint16_t) DIFFERENCE_CUT_OFF_SHUTDOWN_8_BIT)) #define BATTERY_VOLTAGE_SHUTDOWN_10_BIT (uint16_t) (BATTERY_VOLTAGE_SHUTDOWN_8_BIT << 2) // max battery power div25 #define TARGET_MAX_BATTERY_POWER_DIV25 (uint8_t)(TARGET_MAX_BATTERY_POWER / 25) diff --git a/src/motor.c b/src/motor.c index a127c79d..fce58cbb 100644 --- a/src/motor.c +++ b/src/motor.c @@ -99,7 +99,7 @@ static uint16_t ui16_cadence_sensor_ticks_counter_min = CADENCE_SENSOR_CALC_COUN static uint8_t ui8_pas_state_old = 4; static uint16_t ui16_cadence_calc_counter, ui16_cadence_stop_counter; static uint8_t ui8_cadence_calc_ref_state = NO_PAS_REF; -const static uint8_t ui8_pas_old_valid_state[4] = { 0x01, 0x03, 0x00, 0x02 }; +static const uint8_t ui8_pas_old_valid_state[4] = { 0x01, 0x03, 0x00, 0x02 }; // wheel speed sensor volatile uint16_t ui16_wheel_speed_sensor_ticks = 0; @@ -355,7 +355,7 @@ void TIM1_CAP_COM_IRQHandler(void) __interrupt(TIM1_CAP_COM_IRQHANDLER) else { // Verify if rotor stopped (< 10 ERPS) // ui16_a - ui16_b = Hall counter ticks from the last Hall sensor transition; - if ((ui16_a - ui16_b) > (HALL_COUNTER_FREQ/MOTOR_ROTOR_INTERPOLATION_MIN_ERPS/6)) { + if ((uint16_t)(ui16_a - ui16_b) > (HALL_COUNTER_FREQ/MOTOR_ROTOR_INTERPOLATION_MIN_ERPS/6U)) { ui8_motor_commutation_type = BLOCK_COMMUTATION; ui8_g_foc_angle = 0; ui8_hall_360_ref_valid = 0; @@ -867,7 +867,7 @@ void TIM1_CAP_COM_IRQHandler(void) __interrupt(TIM1_CAP_COM_IRQHANDLER) else { ui16_wheel_speed_sensor_ticks_counter_min = WHEEL_SPEED_SENSOR_TICKS_COUNTER_MIN >> 3; } if (!ui8_wheel_speed_sensor_ticks_counter_started || - (ui16_wheel_speed_sensor_ticks_counter > ui16_wheel_speed_sensor_ticks_counter_min)) { + (ui16_wheel_speed_sensor_ticks_counter > ui16_wheel_speed_sensor_ticks_counter_min)) { // check if wheel speed sensor pin state has changed if (ui8_temp != ui8_wheel_speed_sensor_pin_state_old) { // update old wheel speed sensor pin state @@ -897,7 +897,7 @@ void TIM1_CAP_COM_IRQHandler(void) __interrupt(TIM1_CAP_COM_IRQHANDLER) } // increment and also limit the ticks counter - if (ui8_wheel_speed_sensor_ticks_counter_started) + if (ui8_wheel_speed_sensor_ticks_counter_started) { if (ui16_wheel_speed_sensor_ticks_counter < WHEEL_SPEED_SENSOR_TICKS_COUNTER_MIN) { ++ui16_wheel_speed_sensor_ticks_counter; } @@ -907,6 +907,7 @@ void TIM1_CAP_COM_IRQHandler(void) __interrupt(TIM1_CAP_COM_IRQHANDLER) ui16_wheel_speed_sensor_ticks_counter = 0; ui8_wheel_speed_sensor_ticks_counter_started = 0; } + } /****************************************************************************/ @@ -1018,7 +1019,6 @@ void TIM1_CAP_COM_IRQHandler(void) __interrupt(TIM1_CAP_COM_IRQHANDLER) } /****************************************************************************/ - irq_end: // clears the TIM1 interrupt TIM1_IT_UPDATE pending bit TIM1->SR1 = (uint8_t) (~(uint8_t) TIM1_IT_CC4); } diff --git a/tests/conftest.py b/tests/conftest.py index 2aee66bc..ba642fac 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -11,7 +11,10 @@ def pytest_sessionstart(session): Called after the Session object has been created and before performing collection and entering the run test loop. """ - lib, _ = load_code('_tsdz2', coverage=session.config.option.coverage, force_recompile=session.config.option.force) + lib, _ = load_code('_tsdz2', + coverage=session.config.option.coverage, + force_recompile=session.config.option.force, + strict=session.config.option.strict) if session.config.option.coverage: lib.__gcov_reset() diff --git a/tests/load_c_code.py b/tests/load_c_code.py index fd17d49c..b0f00a4b 100644 --- a/tests/load_c_code.py +++ b/tests/load_c_code.py @@ -150,12 +150,12 @@ def generate_cdef(module_name, src_file): fp.write(cdef) return cdef -def load_code(module_name, coverage=False, force_recompile=False): +def load_code(module_name, coverage=False, force_recompile=False, strict=False): # Load previous combined hash hash_file_path = os.path.join(LIB_DIR, f"{module_name}.sha") # Recalculate hash if code or arguments have changed with Checksum(hash_file_path, source_dirs, module_name+"".join(define_macros)) as skip: - if not skip or force_recompile or coverage: # also recompile if coverage is enabled because backround test runners are compiling without gcov + if not skip or force_recompile or coverage or strict: # also recompile if coverage is enabled because backround test runners are compiling without gcov print("Collecting source code..") source_content_list: List[str] = [] source_files = [os.path.abspath(os.path.join(dir, file)) for dir in source_dirs for file in os.listdir(dir) if file.endswith('.c')] @@ -188,11 +188,13 @@ def load_code(module_name, coverage=False, force_recompile=False): combined_source = "// GCOVR_EXCL_STOP\n" + combined_source + "\n// GCOVR_EXCL_START" extra_compile_args += ["--coverage"] extra_link_args += ["--coverage"] - + if strict: + extra_compile_args += ["-Werror"] # Create a CFFI instance ffibuilder = cffi.FFI() print("Processing cdefs...") ffibuilder.cdef(cdef) + print("Compiler args:", extra_compile_args, *include_dirs) ffibuilder.set_source(module_name, combined_source, include_dirs=[os.path.abspath(d) for d in include_dirs], define_macros=[(macro, None) for macro in define_macros], From 43abc9ff840ad7dbf509874b399c9b27e8db14e4 Mon Sep 17 00:00:00 2001 From: dzid26 Date: Fri, 16 Aug 2024 20:58:43 +0100 Subject: [PATCH 4/5] test final current limit value --- tests/sim/_tsdz2.cdef | 10 +++++----- tests/test_diag.py | 8 +++----- 2 files changed, 8 insertions(+), 10 deletions(-) diff --git a/tests/sim/_tsdz2.cdef b/tests/sim/_tsdz2.cdef index 2caa70d9..3c4aa8ce 100644 --- a/tests/sim/_tsdz2.cdef +++ b/tests/sim/_tsdz2.cdef @@ -1957,8 +1957,8 @@ extern "Python+C" void WWDG_SetCounter(uint8_t Counter); extern "Python+C" uint8_t WWDG_GetCounter(void); extern "Python+C" void WWDG_SWReset(void); extern "Python+C" void WWDG_SetWindowValue(uint8_t WindowValue); -int16_t map_ui16(int16_t x, int16_t in_min, int16_t in_max, int16_t out_min, int16_t out_max); -uint8_t map_ui8(uint8_t x, uint8_t in_min, uint8_t in_max, uint8_t out_max, uint8_t out_min); +uint16_t map_ui16(uint16_t in, uint16_t in_min, uint16_t in_max, uint16_t out_min, uint16_t out_max); +uint8_t map_ui8(uint8_t in, uint8_t in_min, uint8_t in_max, uint8_t out_min, uint8_t out_max); uint8_t ui8_max(uint8_t value_a, uint8_t value_b); uint8_t ui8_min(uint8_t value_a, uint8_t value_b); uint16_t filter(uint16_t ui16_new_value, uint16_t ui16_old_value, uint8_t ui8_alpha); @@ -2123,9 +2123,9 @@ static uint8_t ui8_duty_cycle_target; static uint16_t ui16_duty_cycle_percent; static uint8_t ui8_error_battery_overcurrent; static uint8_t ui8_adc_battery_overcurrent; -static uint8_t ui8_adc_battery_current_max_array[2]; -static uint8_t ui8_adc_motor_phase_current_max_array[2]; -static uint8_t ui8_adc_battery_overcurrent_array[2]; +static uint8_t ui8_adc_battery_current_max_temp_1; +static uint8_t ui8_adc_battery_current_max_temp_2; +static uint32_t ui32_adc_battery_power_max_x1000_array[2]; static uint16_t ui16_motor_speed_erps; static uint8_t ui8_pedal_cadence_RPM; static uint8_t ui8_motor_deceleration; diff --git a/tests/test_diag.py b/tests/test_diag.py index e2d6e6a1..49c302ed 100644 --- a/tests/test_diag.py +++ b/tests/test_diag.py @@ -17,11 +17,9 @@ def test_battery_current_max_from_battery_power_max(): ebike.m_configuration_variables.ui8_battery_current_max = 255 # maxout the other limit so that battery limit is based on the battery power ebike.ui16_battery_voltage_filtered_x1000 = 48*1000 ebike.ebike_app_init() - result = [ - ebike.ui8_adc_battery_current_max_array[0], - ebike.ui8_adc_battery_current_max_array[1], - ] - expected = [57, 57] + ebike.uart_receive_package() + result = ebike.ui8_adc_battery_current_max + expected = 112 assert result == expected From dcb91e5add20758b7977ff5b646843ba77ceb7e3 Mon Sep 17 00:00:00 2001 From: dzid26 Date: Fri, 16 Aug 2024 21:25:49 +0100 Subject: [PATCH 5/5] Only check the framework on windows CI. Tests will run in separate job anyway. --- .github/workflows/build.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/build.yaml b/.github/workflows/build.yaml index d994e6a1..741ccbde 100644 --- a/.github/workflows/build.yaml +++ b/.github/workflows/build.yaml @@ -48,7 +48,7 @@ jobs: run: | pip install -e . rm tests/sim/_tsdz2.cdef # make sure cdef is generated from the source to check testing framework - pytest + pytest --collect-only - name: Build run: | cd src