diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index d979242e..4afd140b 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -898,7 +898,7 @@ jobs: for b in nucleo_f446re nucleo_f446ze; do python3 -I tools/footprint/stack_bound.py --elf "build/controller-$b/controller.elf" \ --build "build/controller-$b" --roots examples/controller/stack-roots.json \ - --system "examples/controller/generated/$b/docs/system.json" + --system "examples/controller/src/config/$b/docs/system.json" python3 -I tools/footprint/memory_report.py "build/controller-$b/controller.elf.map" \ --elf "build/controller-$b/controller.elf" done @@ -909,7 +909,7 @@ jobs: cmake --build build/controller-lto python3 -I tools/footprint/stack_bound.py --elf build/controller-lto/controller.elf \ --build build/controller-lto --roots examples/controller/stack-roots.json \ - --system examples/controller/generated/nucleo_f446re/docs/system.json + --system examples/controller/src/config/nucleo_f446re/docs/system.json - name: The controller's SBOM (REL-001, BLD-003), checked by the SPDX tools run: | python3 -m venv "$RUNNER_TEMP/spdx" @@ -994,7 +994,7 @@ jobs: run: | python3 -I tools/footprint/stack_bound.py --elf build/controller-tidy/controller.elf \ --build build/controller-tidy --roots examples/controller/stack-roots.json \ - --system examples/controller/generated/nucleo_f446re/docs/system.json + --system examples/controller/src/config/nucleo_f446re/docs/system.json - name: The Clang controller's memory report, from LLD's map run: | python3 -I tools/footprint/memory_report.py build/controller-tidy/controller.elf.map \ diff --git a/.gitignore b/.gitignore index 0446e7fe..95cd30ff 100644 --- a/.gitignore +++ b/.gitignore @@ -9,7 +9,9 @@ __pycache__/ # Build trees build/ -# but not a generated directory's build/, the board's or application's CMake (A126) +# but not a generated directory's build/, the board's or application's CMake (A126), nor an +# application's configuration folder's, src/config//build/ (A130) !**/generated/**/build/ +!**/src/config/**/build/ .venv/ .venv-docs/ diff --git a/boards/arduino/arduino_uno/generated/.base/build/board.cmake b/boards/arduino/arduino_uno/generated/.base/build/board.cmake index 3b14f416..3e2b3dfb 100644 --- a/boards/arduino/arduino_uno/generated/.base/build/board.cmake +++ b/boards/arduino/arduino_uno/generated/.base/build/board.cmake @@ -21,6 +21,8 @@ get_filename_component(EMB_BOARD_GENERATED_DIR "${CMAKE_CURRENT_LIST_DIR}/.." AB set(EMB_BOARD_CONF "${EMB_BOARD_GENERATED_DIR}/config/board.conf") set(EMB_BOARD_HW_JSON "${EMB_BOARD_GENERATED_DIR}/docs/hw.json") set(EMB_BOARD_BUILD_DIR "${CMAKE_CURRENT_LIST_DIR}") # build/CMakeLists.txt +set(EMB_BOARD_SRC_DIR "${EMB_BOARD_GENERATED_DIR}/src") # its pin table and boot block +set(EMB_BOARD_LINKER_DIR "${EMB_BOARD_GENERATED_DIR}/linker") # the SoC family's board support and drivers build this board (build/CMakeLists.txt) set(EMB_SOC_DIR "${EMB_BASE}/soc/microchip/atmega") set(EMB_BOARD_INCLUDE_DIRS "${EMB_BOARD_GENERATED_DIR}/include" "${EMB_SOC_DIR}/include") diff --git a/boards/arduino/arduino_uno/generated/.base/docs/hw.json b/boards/arduino/arduino_uno/generated/.base/docs/hw.json index 26b62d46..27b6d50a 100644 --- a/boards/arduino/arduino_uno/generated/.base/docs/hw.json +++ b/boards/arduino/arduino_uno/generated/.base/docs/hw.json @@ -80,8 +80,10 @@ "clock": { "ahb_div": 1, "bus_hz": {}, + "bus_timer_hz": {}, "bypass": false, "cpu_hz": 16000000, + "fixed_plls": {}, "hclk_hz": 16000000, "pll": null, "source": "xtal", diff --git a/boards/arduino/arduino_uno/generated/build/board.cmake b/boards/arduino/arduino_uno/generated/build/board.cmake index 3b14f416..3e2b3dfb 100644 --- a/boards/arduino/arduino_uno/generated/build/board.cmake +++ b/boards/arduino/arduino_uno/generated/build/board.cmake @@ -21,6 +21,8 @@ get_filename_component(EMB_BOARD_GENERATED_DIR "${CMAKE_CURRENT_LIST_DIR}/.." AB set(EMB_BOARD_CONF "${EMB_BOARD_GENERATED_DIR}/config/board.conf") set(EMB_BOARD_HW_JSON "${EMB_BOARD_GENERATED_DIR}/docs/hw.json") set(EMB_BOARD_BUILD_DIR "${CMAKE_CURRENT_LIST_DIR}") # build/CMakeLists.txt +set(EMB_BOARD_SRC_DIR "${EMB_BOARD_GENERATED_DIR}/src") # its pin table and boot block +set(EMB_BOARD_LINKER_DIR "${EMB_BOARD_GENERATED_DIR}/linker") # the SoC family's board support and drivers build this board (build/CMakeLists.txt) set(EMB_SOC_DIR "${EMB_BASE}/soc/microchip/atmega") set(EMB_BOARD_INCLUDE_DIRS "${EMB_BOARD_GENERATED_DIR}/include" "${EMB_SOC_DIR}/include") diff --git a/boards/arduino/arduino_uno/generated/docs/hw.json b/boards/arduino/arduino_uno/generated/docs/hw.json index 26b62d46..27b6d50a 100644 --- a/boards/arduino/arduino_uno/generated/docs/hw.json +++ b/boards/arduino/arduino_uno/generated/docs/hw.json @@ -80,8 +80,10 @@ "clock": { "ahb_div": 1, "bus_hz": {}, + "bus_timer_hz": {}, "bypass": false, "cpu_hz": 16000000, + "fixed_plls": {}, "hclk_hz": 16000000, "pll": null, "source": "xtal", diff --git a/boards/arm/mps2_an385/generated/.base/build/CMakeLists.txt b/boards/arm/mps2_an385/generated/.base/build/CMakeLists.txt index 2108434e..2701091d 100644 --- a/boards/arm/mps2_an385/generated/.base/build/CMakeLists.txt +++ b/boards/arm/mps2_an385/generated/.base/build/CMakeLists.txt @@ -11,7 +11,7 @@ # boards/arm/mps2_an385/board.yaml # a5b0b55c085af47e34d849874a2b9c5d70300eb3cd49ec418adc5b0a9bb43c08 # drivers/bindings.yaml -# d3c336ac05548e0addd1faac18f3dff70576d8069f11d89e6a761cf5c6132b49 +# c06d1a914adb21d0e314c79b3611ac6859eefeac1957d6914cccfc5531ad6ede # soc/arm/mps2/an385.yaml # a33c411be3b6ebf62765e2f39d0065dfe40520d534ebe7b83cdfa16814488a4b # soc/arm/mps2/mps2.yaml diff --git a/boards/arm/mps2_an385/generated/.base/build/board.cmake b/boards/arm/mps2_an385/generated/.base/build/board.cmake index f958066f..7667a08d 100644 --- a/boards/arm/mps2_an385/generated/.base/build/board.cmake +++ b/boards/arm/mps2_an385/generated/.base/build/board.cmake @@ -11,7 +11,7 @@ # boards/arm/mps2_an385/board.yaml # a5b0b55c085af47e34d849874a2b9c5d70300eb3cd49ec418adc5b0a9bb43c08 # drivers/bindings.yaml -# d3c336ac05548e0addd1faac18f3dff70576d8069f11d89e6a761cf5c6132b49 +# c06d1a914adb21d0e314c79b3611ac6859eefeac1957d6914cccfc5531ad6ede # soc/arm/mps2/an385.yaml # a33c411be3b6ebf62765e2f39d0065dfe40520d534ebe7b83cdfa16814488a4b # soc/arm/mps2/mps2.yaml @@ -25,6 +25,8 @@ get_filename_component(EMB_BOARD_GENERATED_DIR "${CMAKE_CURRENT_LIST_DIR}/.." AB set(EMB_BOARD_CONF "${EMB_BOARD_GENERATED_DIR}/config/board.conf") set(EMB_BOARD_HW_JSON "${EMB_BOARD_GENERATED_DIR}/docs/hw.json") set(EMB_BOARD_BUILD_DIR "${CMAKE_CURRENT_LIST_DIR}") # build/CMakeLists.txt +set(EMB_BOARD_SRC_DIR "${EMB_BOARD_GENERATED_DIR}/src") # its pin table and boot block +set(EMB_BOARD_LINKER_DIR "${EMB_BOARD_GENERATED_DIR}/linker") # the SoC family's board support and drivers build this board (build/CMakeLists.txt) set(EMB_SOC_DIR "${EMB_BASE}/soc/arm/mps2") set(EMB_BOARD_INCLUDE_DIRS "${EMB_BOARD_GENERATED_DIR}/include" "${EMB_SOC_DIR}/include") @@ -44,7 +46,7 @@ set(EMB_BOARD_DRIVER_INCLUDE_DIRS set(EMB_BOARD_HW_INPUTS "arch/cortex_m/arch.yaml=c5c8e451c09717dee1713d07f8311b6d507e3b4c66c42d93e0ce11da6ec76d6d" "boards/arm/mps2_an385/board.yaml=a5b0b55c085af47e34d849874a2b9c5d70300eb3cd49ec418adc5b0a9bb43c08" - "drivers/bindings.yaml=d3c336ac05548e0addd1faac18f3dff70576d8069f11d89e6a761cf5c6132b49" + "drivers/bindings.yaml=c06d1a914adb21d0e314c79b3611ac6859eefeac1957d6914cccfc5531ad6ede" "soc/arm/mps2/an385.yaml=a33c411be3b6ebf62765e2f39d0065dfe40520d534ebe7b83cdfa16814488a4b" "soc/arm/mps2/mps2.yaml=7bc066c165dbd50db2c6c3e35cf8a3f12ae360b7ad578cfe06983b3f807d1d71" ) diff --git a/boards/arm/mps2_an385/generated/.base/config/board.conf b/boards/arm/mps2_an385/generated/.base/config/board.conf index da192c7a..fe3e8af7 100644 --- a/boards/arm/mps2_an385/generated/.base/config/board.conf +++ b/boards/arm/mps2_an385/generated/.base/config/board.conf @@ -11,7 +11,7 @@ # boards/arm/mps2_an385/board.yaml # a5b0b55c085af47e34d849874a2b9c5d70300eb3cd49ec418adc5b0a9bb43c08 # drivers/bindings.yaml -# d3c336ac05548e0addd1faac18f3dff70576d8069f11d89e6a761cf5c6132b49 +# c06d1a914adb21d0e314c79b3611ac6859eefeac1957d6914cccfc5531ad6ede # soc/arm/mps2/an385.yaml # a33c411be3b6ebf62765e2f39d0065dfe40520d534ebe7b83cdfa16814488a4b # soc/arm/mps2/mps2.yaml diff --git a/boards/arm/mps2_an385/generated/.base/docs/board.md b/boards/arm/mps2_an385/generated/.base/docs/board.md index 8bf3a9e2..cfedaad0 100644 --- a/boards/arm/mps2_an385/generated/.base/docs/board.md +++ b/boards/arm/mps2_an385/generated/.base/docs/board.md @@ -53,6 +53,6 @@ Generated by emb-hwgen 0.1.0, schema v0, from: |---|---| | `arch/cortex_m/arch.yaml` | `c5c8e451c09717dee1713d07f8311b6d507e3b4c66c42d93e0ce11da6ec76d6d` | | `boards/arm/mps2_an385/board.yaml` | `a5b0b55c085af47e34d849874a2b9c5d70300eb3cd49ec418adc5b0a9bb43c08` | -| `drivers/bindings.yaml` | `d3c336ac05548e0addd1faac18f3dff70576d8069f11d89e6a761cf5c6132b49` | +| `drivers/bindings.yaml` | `c06d1a914adb21d0e314c79b3611ac6859eefeac1957d6914cccfc5531ad6ede` | | `soc/arm/mps2/an385.yaml` | `a33c411be3b6ebf62765e2f39d0065dfe40520d534ebe7b83cdfa16814488a4b` | | `soc/arm/mps2/mps2.yaml` | `7bc066c165dbd50db2c6c3e35cf8a3f12ae360b7ad578cfe06983b3f807d1d71` | diff --git a/boards/arm/mps2_an385/generated/.base/docs/build_report.md b/boards/arm/mps2_an385/generated/.base/docs/build_report.md index 1ae5c353..864df557 100644 --- a/boards/arm/mps2_an385/generated/.base/docs/build_report.md +++ b/boards/arm/mps2_an385/generated/.base/docs/build_report.md @@ -24,6 +24,6 @@ Generated by emb-hwgen 0.1.0, schema v0, from: |---|---| | `arch/cortex_m/arch.yaml` | `c5c8e451c09717dee1713d07f8311b6d507e3b4c66c42d93e0ce11da6ec76d6d` | | `boards/arm/mps2_an385/board.yaml` | `a5b0b55c085af47e34d849874a2b9c5d70300eb3cd49ec418adc5b0a9bb43c08` | -| `drivers/bindings.yaml` | `d3c336ac05548e0addd1faac18f3dff70576d8069f11d89e6a761cf5c6132b49` | +| `drivers/bindings.yaml` | `c06d1a914adb21d0e314c79b3611ac6859eefeac1957d6914cccfc5531ad6ede` | | `soc/arm/mps2/an385.yaml` | `a33c411be3b6ebf62765e2f39d0065dfe40520d534ebe7b83cdfa16814488a4b` | | `soc/arm/mps2/mps2.yaml` | `7bc066c165dbd50db2c6c3e35cf8a3f12ae360b7ad578cfe06983b3f807d1d71` | diff --git a/boards/arm/mps2_an385/generated/.base/docs/hw.json b/boards/arm/mps2_an385/generated/.base/docs/hw.json index dcf22648..b734c8f4 100644 --- a/boards/arm/mps2_an385/generated/.base/docs/hw.json +++ b/boards/arm/mps2_an385/generated/.base/docs/hw.json @@ -58,8 +58,10 @@ "clock": { "ahb_div": 1, "bus_hz": {}, + "bus_timer_hz": {}, "bypass": false, "cpu_hz": 25000000, + "fixed_plls": {}, "hclk_hz": 25000000, "pll": null, "source": "sysclk", @@ -166,7 +168,7 @@ }, { "path": "drivers/bindings.yaml", - "sha256": "d3c336ac05548e0addd1faac18f3dff70576d8069f11d89e6a761cf5c6132b49" + "sha256": "c06d1a914adb21d0e314c79b3611ac6859eefeac1957d6914cccfc5531ad6ede" }, { "path": "soc/arm/mps2/an385.yaml", diff --git a/boards/arm/mps2_an385/generated/.base/include/hw_config.h b/boards/arm/mps2_an385/generated/.base/include/hw_config.h index e00d797f..3e4c942f 100644 --- a/boards/arm/mps2_an385/generated/.base/include/hw_config.h +++ b/boards/arm/mps2_an385/generated/.base/include/hw_config.h @@ -17,7 +17,7 @@ * boards/arm/mps2_an385/board.yaml * a5b0b55c085af47e34d849874a2b9c5d70300eb3cd49ec418adc5b0a9bb43c08 * drivers/bindings.yaml - * d3c336ac05548e0addd1faac18f3dff70576d8069f11d89e6a761cf5c6132b49 + * c06d1a914adb21d0e314c79b3611ac6859eefeac1957d6914cccfc5531ad6ede * soc/arm/mps2/an385.yaml * a33c411be3b6ebf62765e2f39d0065dfe40520d534ebe7b83cdfa16814488a4b * soc/arm/mps2/mps2.yaml diff --git a/boards/arm/mps2_an385/generated/.base/include/soc_devices.h b/boards/arm/mps2_an385/generated/.base/include/soc_devices.h index 982f098d..29e0c643 100644 --- a/boards/arm/mps2_an385/generated/.base/include/soc_devices.h +++ b/boards/arm/mps2_an385/generated/.base/include/soc_devices.h @@ -17,7 +17,7 @@ * boards/arm/mps2_an385/board.yaml * a5b0b55c085af47e34d849874a2b9c5d70300eb3cd49ec418adc5b0a9bb43c08 * drivers/bindings.yaml - * d3c336ac05548e0addd1faac18f3dff70576d8069f11d89e6a761cf5c6132b49 + * c06d1a914adb21d0e314c79b3611ac6859eefeac1957d6914cccfc5531ad6ede * soc/arm/mps2/an385.yaml * a33c411be3b6ebf62765e2f39d0065dfe40520d534ebe7b83cdfa16814488a4b * soc/arm/mps2/mps2.yaml diff --git a/boards/arm/mps2_an385/generated/.base/linker/regions.ld b/boards/arm/mps2_an385/generated/.base/linker/regions.ld index 9fae1ba1..e7d58c76 100644 --- a/boards/arm/mps2_an385/generated/.base/linker/regions.ld +++ b/boards/arm/mps2_an385/generated/.base/linker/regions.ld @@ -18,7 +18,7 @@ * boards/arm/mps2_an385/board.yaml * a5b0b55c085af47e34d849874a2b9c5d70300eb3cd49ec418adc5b0a9bb43c08 * drivers/bindings.yaml - * d3c336ac05548e0addd1faac18f3dff70576d8069f11d89e6a761cf5c6132b49 + * c06d1a914adb21d0e314c79b3611ac6859eefeac1957d6914cccfc5531ad6ede * soc/arm/mps2/an385.yaml * a33c411be3b6ebf62765e2f39d0065dfe40520d534ebe7b83cdfa16814488a4b * soc/arm/mps2/mps2.yaml diff --git a/boards/arm/mps2_an385/generated/.base/src/soc_devices.c b/boards/arm/mps2_an385/generated/.base/src/soc_devices.c index 76565103..c02acf29 100644 --- a/boards/arm/mps2_an385/generated/.base/src/soc_devices.c +++ b/boards/arm/mps2_an385/generated/.base/src/soc_devices.c @@ -18,7 +18,7 @@ * boards/arm/mps2_an385/board.yaml * a5b0b55c085af47e34d849874a2b9c5d70300eb3cd49ec418adc5b0a9bb43c08 * drivers/bindings.yaml - * d3c336ac05548e0addd1faac18f3dff70576d8069f11d89e6a761cf5c6132b49 + * c06d1a914adb21d0e314c79b3611ac6859eefeac1957d6914cccfc5531ad6ede * soc/arm/mps2/an385.yaml * a33c411be3b6ebf62765e2f39d0065dfe40520d534ebe7b83cdfa16814488a4b * soc/arm/mps2/mps2.yaml diff --git a/boards/arm/mps2_an385/generated/build/CMakeLists.txt b/boards/arm/mps2_an385/generated/build/CMakeLists.txt index 2108434e..2701091d 100644 --- a/boards/arm/mps2_an385/generated/build/CMakeLists.txt +++ b/boards/arm/mps2_an385/generated/build/CMakeLists.txt @@ -11,7 +11,7 @@ # boards/arm/mps2_an385/board.yaml # a5b0b55c085af47e34d849874a2b9c5d70300eb3cd49ec418adc5b0a9bb43c08 # drivers/bindings.yaml -# d3c336ac05548e0addd1faac18f3dff70576d8069f11d89e6a761cf5c6132b49 +# c06d1a914adb21d0e314c79b3611ac6859eefeac1957d6914cccfc5531ad6ede # soc/arm/mps2/an385.yaml # a33c411be3b6ebf62765e2f39d0065dfe40520d534ebe7b83cdfa16814488a4b # soc/arm/mps2/mps2.yaml diff --git a/boards/arm/mps2_an385/generated/build/board.cmake b/boards/arm/mps2_an385/generated/build/board.cmake index f958066f..7667a08d 100644 --- a/boards/arm/mps2_an385/generated/build/board.cmake +++ b/boards/arm/mps2_an385/generated/build/board.cmake @@ -11,7 +11,7 @@ # boards/arm/mps2_an385/board.yaml # a5b0b55c085af47e34d849874a2b9c5d70300eb3cd49ec418adc5b0a9bb43c08 # drivers/bindings.yaml -# d3c336ac05548e0addd1faac18f3dff70576d8069f11d89e6a761cf5c6132b49 +# c06d1a914adb21d0e314c79b3611ac6859eefeac1957d6914cccfc5531ad6ede # soc/arm/mps2/an385.yaml # a33c411be3b6ebf62765e2f39d0065dfe40520d534ebe7b83cdfa16814488a4b # soc/arm/mps2/mps2.yaml @@ -25,6 +25,8 @@ get_filename_component(EMB_BOARD_GENERATED_DIR "${CMAKE_CURRENT_LIST_DIR}/.." AB set(EMB_BOARD_CONF "${EMB_BOARD_GENERATED_DIR}/config/board.conf") set(EMB_BOARD_HW_JSON "${EMB_BOARD_GENERATED_DIR}/docs/hw.json") set(EMB_BOARD_BUILD_DIR "${CMAKE_CURRENT_LIST_DIR}") # build/CMakeLists.txt +set(EMB_BOARD_SRC_DIR "${EMB_BOARD_GENERATED_DIR}/src") # its pin table and boot block +set(EMB_BOARD_LINKER_DIR "${EMB_BOARD_GENERATED_DIR}/linker") # the SoC family's board support and drivers build this board (build/CMakeLists.txt) set(EMB_SOC_DIR "${EMB_BASE}/soc/arm/mps2") set(EMB_BOARD_INCLUDE_DIRS "${EMB_BOARD_GENERATED_DIR}/include" "${EMB_SOC_DIR}/include") @@ -44,7 +46,7 @@ set(EMB_BOARD_DRIVER_INCLUDE_DIRS set(EMB_BOARD_HW_INPUTS "arch/cortex_m/arch.yaml=c5c8e451c09717dee1713d07f8311b6d507e3b4c66c42d93e0ce11da6ec76d6d" "boards/arm/mps2_an385/board.yaml=a5b0b55c085af47e34d849874a2b9c5d70300eb3cd49ec418adc5b0a9bb43c08" - "drivers/bindings.yaml=d3c336ac05548e0addd1faac18f3dff70576d8069f11d89e6a761cf5c6132b49" + "drivers/bindings.yaml=c06d1a914adb21d0e314c79b3611ac6859eefeac1957d6914cccfc5531ad6ede" "soc/arm/mps2/an385.yaml=a33c411be3b6ebf62765e2f39d0065dfe40520d534ebe7b83cdfa16814488a4b" "soc/arm/mps2/mps2.yaml=7bc066c165dbd50db2c6c3e35cf8a3f12ae360b7ad578cfe06983b3f807d1d71" ) diff --git a/boards/arm/mps2_an385/generated/config/board.conf b/boards/arm/mps2_an385/generated/config/board.conf index da192c7a..fe3e8af7 100644 --- a/boards/arm/mps2_an385/generated/config/board.conf +++ b/boards/arm/mps2_an385/generated/config/board.conf @@ -11,7 +11,7 @@ # boards/arm/mps2_an385/board.yaml # a5b0b55c085af47e34d849874a2b9c5d70300eb3cd49ec418adc5b0a9bb43c08 # drivers/bindings.yaml -# d3c336ac05548e0addd1faac18f3dff70576d8069f11d89e6a761cf5c6132b49 +# c06d1a914adb21d0e314c79b3611ac6859eefeac1957d6914cccfc5531ad6ede # soc/arm/mps2/an385.yaml # a33c411be3b6ebf62765e2f39d0065dfe40520d534ebe7b83cdfa16814488a4b # soc/arm/mps2/mps2.yaml diff --git a/boards/arm/mps2_an385/generated/docs/board.md b/boards/arm/mps2_an385/generated/docs/board.md index 8bf3a9e2..cfedaad0 100644 --- a/boards/arm/mps2_an385/generated/docs/board.md +++ b/boards/arm/mps2_an385/generated/docs/board.md @@ -53,6 +53,6 @@ Generated by emb-hwgen 0.1.0, schema v0, from: |---|---| | `arch/cortex_m/arch.yaml` | `c5c8e451c09717dee1713d07f8311b6d507e3b4c66c42d93e0ce11da6ec76d6d` | | `boards/arm/mps2_an385/board.yaml` | `a5b0b55c085af47e34d849874a2b9c5d70300eb3cd49ec418adc5b0a9bb43c08` | -| `drivers/bindings.yaml` | `d3c336ac05548e0addd1faac18f3dff70576d8069f11d89e6a761cf5c6132b49` | +| `drivers/bindings.yaml` | `c06d1a914adb21d0e314c79b3611ac6859eefeac1957d6914cccfc5531ad6ede` | | `soc/arm/mps2/an385.yaml` | `a33c411be3b6ebf62765e2f39d0065dfe40520d534ebe7b83cdfa16814488a4b` | | `soc/arm/mps2/mps2.yaml` | `7bc066c165dbd50db2c6c3e35cf8a3f12ae360b7ad578cfe06983b3f807d1d71` | diff --git a/boards/arm/mps2_an385/generated/docs/build_report.md b/boards/arm/mps2_an385/generated/docs/build_report.md index 1ae5c353..864df557 100644 --- a/boards/arm/mps2_an385/generated/docs/build_report.md +++ b/boards/arm/mps2_an385/generated/docs/build_report.md @@ -24,6 +24,6 @@ Generated by emb-hwgen 0.1.0, schema v0, from: |---|---| | `arch/cortex_m/arch.yaml` | `c5c8e451c09717dee1713d07f8311b6d507e3b4c66c42d93e0ce11da6ec76d6d` | | `boards/arm/mps2_an385/board.yaml` | `a5b0b55c085af47e34d849874a2b9c5d70300eb3cd49ec418adc5b0a9bb43c08` | -| `drivers/bindings.yaml` | `d3c336ac05548e0addd1faac18f3dff70576d8069f11d89e6a761cf5c6132b49` | +| `drivers/bindings.yaml` | `c06d1a914adb21d0e314c79b3611ac6859eefeac1957d6914cccfc5531ad6ede` | | `soc/arm/mps2/an385.yaml` | `a33c411be3b6ebf62765e2f39d0065dfe40520d534ebe7b83cdfa16814488a4b` | | `soc/arm/mps2/mps2.yaml` | `7bc066c165dbd50db2c6c3e35cf8a3f12ae360b7ad578cfe06983b3f807d1d71` | diff --git a/boards/arm/mps2_an385/generated/docs/hw.json b/boards/arm/mps2_an385/generated/docs/hw.json index dcf22648..b734c8f4 100644 --- a/boards/arm/mps2_an385/generated/docs/hw.json +++ b/boards/arm/mps2_an385/generated/docs/hw.json @@ -58,8 +58,10 @@ "clock": { "ahb_div": 1, "bus_hz": {}, + "bus_timer_hz": {}, "bypass": false, "cpu_hz": 25000000, + "fixed_plls": {}, "hclk_hz": 25000000, "pll": null, "source": "sysclk", @@ -166,7 +168,7 @@ }, { "path": "drivers/bindings.yaml", - "sha256": "d3c336ac05548e0addd1faac18f3dff70576d8069f11d89e6a761cf5c6132b49" + "sha256": "c06d1a914adb21d0e314c79b3611ac6859eefeac1957d6914cccfc5531ad6ede" }, { "path": "soc/arm/mps2/an385.yaml", diff --git a/boards/arm/mps2_an385/generated/include/hw_config.h b/boards/arm/mps2_an385/generated/include/hw_config.h index e00d797f..3e4c942f 100644 --- a/boards/arm/mps2_an385/generated/include/hw_config.h +++ b/boards/arm/mps2_an385/generated/include/hw_config.h @@ -17,7 +17,7 @@ * boards/arm/mps2_an385/board.yaml * a5b0b55c085af47e34d849874a2b9c5d70300eb3cd49ec418adc5b0a9bb43c08 * drivers/bindings.yaml - * d3c336ac05548e0addd1faac18f3dff70576d8069f11d89e6a761cf5c6132b49 + * c06d1a914adb21d0e314c79b3611ac6859eefeac1957d6914cccfc5531ad6ede * soc/arm/mps2/an385.yaml * a33c411be3b6ebf62765e2f39d0065dfe40520d534ebe7b83cdfa16814488a4b * soc/arm/mps2/mps2.yaml diff --git a/boards/arm/mps2_an385/generated/include/soc_devices.h b/boards/arm/mps2_an385/generated/include/soc_devices.h index 982f098d..29e0c643 100644 --- a/boards/arm/mps2_an385/generated/include/soc_devices.h +++ b/boards/arm/mps2_an385/generated/include/soc_devices.h @@ -17,7 +17,7 @@ * boards/arm/mps2_an385/board.yaml * a5b0b55c085af47e34d849874a2b9c5d70300eb3cd49ec418adc5b0a9bb43c08 * drivers/bindings.yaml - * d3c336ac05548e0addd1faac18f3dff70576d8069f11d89e6a761cf5c6132b49 + * c06d1a914adb21d0e314c79b3611ac6859eefeac1957d6914cccfc5531ad6ede * soc/arm/mps2/an385.yaml * a33c411be3b6ebf62765e2f39d0065dfe40520d534ebe7b83cdfa16814488a4b * soc/arm/mps2/mps2.yaml diff --git a/boards/arm/mps2_an385/generated/linker/regions.ld b/boards/arm/mps2_an385/generated/linker/regions.ld index 9fae1ba1..e7d58c76 100644 --- a/boards/arm/mps2_an385/generated/linker/regions.ld +++ b/boards/arm/mps2_an385/generated/linker/regions.ld @@ -18,7 +18,7 @@ * boards/arm/mps2_an385/board.yaml * a5b0b55c085af47e34d849874a2b9c5d70300eb3cd49ec418adc5b0a9bb43c08 * drivers/bindings.yaml - * d3c336ac05548e0addd1faac18f3dff70576d8069f11d89e6a761cf5c6132b49 + * c06d1a914adb21d0e314c79b3611ac6859eefeac1957d6914cccfc5531ad6ede * soc/arm/mps2/an385.yaml * a33c411be3b6ebf62765e2f39d0065dfe40520d534ebe7b83cdfa16814488a4b * soc/arm/mps2/mps2.yaml diff --git a/boards/arm/mps2_an385/generated/src/soc_devices.c b/boards/arm/mps2_an385/generated/src/soc_devices.c index 76565103..c02acf29 100644 --- a/boards/arm/mps2_an385/generated/src/soc_devices.c +++ b/boards/arm/mps2_an385/generated/src/soc_devices.c @@ -18,7 +18,7 @@ * boards/arm/mps2_an385/board.yaml * a5b0b55c085af47e34d849874a2b9c5d70300eb3cd49ec418adc5b0a9bb43c08 * drivers/bindings.yaml - * d3c336ac05548e0addd1faac18f3dff70576d8069f11d89e6a761cf5c6132b49 + * c06d1a914adb21d0e314c79b3611ac6859eefeac1957d6914cccfc5531ad6ede * soc/arm/mps2/an385.yaml * a33c411be3b6ebf62765e2f39d0065dfe40520d534ebe7b83cdfa16814488a4b * soc/arm/mps2/mps2.yaml diff --git a/boards/arm/mps2_an386/generated/.base/build/CMakeLists.txt b/boards/arm/mps2_an386/generated/.base/build/CMakeLists.txt index 900866fb..3f4af4fd 100644 --- a/boards/arm/mps2_an386/generated/.base/build/CMakeLists.txt +++ b/boards/arm/mps2_an386/generated/.base/build/CMakeLists.txt @@ -11,7 +11,7 @@ # boards/arm/mps2_an386/board.yaml # ce5fe8df24c5e3fafafdb5da3fb462f06fc90c651ef4db267e191b9abc344314 # drivers/bindings.yaml -# d3c336ac05548e0addd1faac18f3dff70576d8069f11d89e6a761cf5c6132b49 +# c06d1a914adb21d0e314c79b3611ac6859eefeac1957d6914cccfc5531ad6ede # soc/arm/mps2/an386.yaml # a5a883b92b845b7afba700d4d9fb3771de8eaf3131803f6dbd9f118414e07fc6 # soc/arm/mps2/mps2.yaml diff --git a/boards/arm/mps2_an386/generated/.base/build/board.cmake b/boards/arm/mps2_an386/generated/.base/build/board.cmake index afacb19b..641f2c44 100644 --- a/boards/arm/mps2_an386/generated/.base/build/board.cmake +++ b/boards/arm/mps2_an386/generated/.base/build/board.cmake @@ -11,7 +11,7 @@ # boards/arm/mps2_an386/board.yaml # ce5fe8df24c5e3fafafdb5da3fb462f06fc90c651ef4db267e191b9abc344314 # drivers/bindings.yaml -# d3c336ac05548e0addd1faac18f3dff70576d8069f11d89e6a761cf5c6132b49 +# c06d1a914adb21d0e314c79b3611ac6859eefeac1957d6914cccfc5531ad6ede # soc/arm/mps2/an386.yaml # a5a883b92b845b7afba700d4d9fb3771de8eaf3131803f6dbd9f118414e07fc6 # soc/arm/mps2/mps2.yaml @@ -25,6 +25,8 @@ get_filename_component(EMB_BOARD_GENERATED_DIR "${CMAKE_CURRENT_LIST_DIR}/.." AB set(EMB_BOARD_CONF "${EMB_BOARD_GENERATED_DIR}/config/board.conf") set(EMB_BOARD_HW_JSON "${EMB_BOARD_GENERATED_DIR}/docs/hw.json") set(EMB_BOARD_BUILD_DIR "${CMAKE_CURRENT_LIST_DIR}") # build/CMakeLists.txt +set(EMB_BOARD_SRC_DIR "${EMB_BOARD_GENERATED_DIR}/src") # its pin table and boot block +set(EMB_BOARD_LINKER_DIR "${EMB_BOARD_GENERATED_DIR}/linker") # the SoC family's board support and drivers build this board (build/CMakeLists.txt) set(EMB_SOC_DIR "${EMB_BASE}/soc/arm/mps2") set(EMB_BOARD_INCLUDE_DIRS "${EMB_BOARD_GENERATED_DIR}/include" "${EMB_SOC_DIR}/include") @@ -44,7 +46,7 @@ set(EMB_BOARD_DRIVER_INCLUDE_DIRS set(EMB_BOARD_HW_INPUTS "arch/cortex_m/arch.yaml=c5c8e451c09717dee1713d07f8311b6d507e3b4c66c42d93e0ce11da6ec76d6d" "boards/arm/mps2_an386/board.yaml=ce5fe8df24c5e3fafafdb5da3fb462f06fc90c651ef4db267e191b9abc344314" - "drivers/bindings.yaml=d3c336ac05548e0addd1faac18f3dff70576d8069f11d89e6a761cf5c6132b49" + "drivers/bindings.yaml=c06d1a914adb21d0e314c79b3611ac6859eefeac1957d6914cccfc5531ad6ede" "soc/arm/mps2/an386.yaml=a5a883b92b845b7afba700d4d9fb3771de8eaf3131803f6dbd9f118414e07fc6" "soc/arm/mps2/mps2.yaml=7bc066c165dbd50db2c6c3e35cf8a3f12ae360b7ad578cfe06983b3f807d1d71" ) diff --git a/boards/arm/mps2_an386/generated/.base/config/board.conf b/boards/arm/mps2_an386/generated/.base/config/board.conf index 849cb81e..e1627d85 100644 --- a/boards/arm/mps2_an386/generated/.base/config/board.conf +++ b/boards/arm/mps2_an386/generated/.base/config/board.conf @@ -11,7 +11,7 @@ # boards/arm/mps2_an386/board.yaml # ce5fe8df24c5e3fafafdb5da3fb462f06fc90c651ef4db267e191b9abc344314 # drivers/bindings.yaml -# d3c336ac05548e0addd1faac18f3dff70576d8069f11d89e6a761cf5c6132b49 +# c06d1a914adb21d0e314c79b3611ac6859eefeac1957d6914cccfc5531ad6ede # soc/arm/mps2/an386.yaml # a5a883b92b845b7afba700d4d9fb3771de8eaf3131803f6dbd9f118414e07fc6 # soc/arm/mps2/mps2.yaml diff --git a/boards/arm/mps2_an386/generated/.base/docs/board.md b/boards/arm/mps2_an386/generated/.base/docs/board.md index f0ef7a65..09040cbb 100644 --- a/boards/arm/mps2_an386/generated/.base/docs/board.md +++ b/boards/arm/mps2_an386/generated/.base/docs/board.md @@ -53,6 +53,6 @@ Generated by emb-hwgen 0.1.0, schema v0, from: |---|---| | `arch/cortex_m/arch.yaml` | `c5c8e451c09717dee1713d07f8311b6d507e3b4c66c42d93e0ce11da6ec76d6d` | | `boards/arm/mps2_an386/board.yaml` | `ce5fe8df24c5e3fafafdb5da3fb462f06fc90c651ef4db267e191b9abc344314` | -| `drivers/bindings.yaml` | `d3c336ac05548e0addd1faac18f3dff70576d8069f11d89e6a761cf5c6132b49` | +| `drivers/bindings.yaml` | `c06d1a914adb21d0e314c79b3611ac6859eefeac1957d6914cccfc5531ad6ede` | | `soc/arm/mps2/an386.yaml` | `a5a883b92b845b7afba700d4d9fb3771de8eaf3131803f6dbd9f118414e07fc6` | | `soc/arm/mps2/mps2.yaml` | `7bc066c165dbd50db2c6c3e35cf8a3f12ae360b7ad578cfe06983b3f807d1d71` | diff --git a/boards/arm/mps2_an386/generated/.base/docs/build_report.md b/boards/arm/mps2_an386/generated/.base/docs/build_report.md index 0c1efa38..ce38511c 100644 --- a/boards/arm/mps2_an386/generated/.base/docs/build_report.md +++ b/boards/arm/mps2_an386/generated/.base/docs/build_report.md @@ -24,6 +24,6 @@ Generated by emb-hwgen 0.1.0, schema v0, from: |---|---| | `arch/cortex_m/arch.yaml` | `c5c8e451c09717dee1713d07f8311b6d507e3b4c66c42d93e0ce11da6ec76d6d` | | `boards/arm/mps2_an386/board.yaml` | `ce5fe8df24c5e3fafafdb5da3fb462f06fc90c651ef4db267e191b9abc344314` | -| `drivers/bindings.yaml` | `d3c336ac05548e0addd1faac18f3dff70576d8069f11d89e6a761cf5c6132b49` | +| `drivers/bindings.yaml` | `c06d1a914adb21d0e314c79b3611ac6859eefeac1957d6914cccfc5531ad6ede` | | `soc/arm/mps2/an386.yaml` | `a5a883b92b845b7afba700d4d9fb3771de8eaf3131803f6dbd9f118414e07fc6` | | `soc/arm/mps2/mps2.yaml` | `7bc066c165dbd50db2c6c3e35cf8a3f12ae360b7ad578cfe06983b3f807d1d71` | diff --git a/boards/arm/mps2_an386/generated/.base/docs/hw.json b/boards/arm/mps2_an386/generated/.base/docs/hw.json index f9edbedb..841bb2f1 100644 --- a/boards/arm/mps2_an386/generated/.base/docs/hw.json +++ b/boards/arm/mps2_an386/generated/.base/docs/hw.json @@ -58,8 +58,10 @@ "clock": { "ahb_div": 1, "bus_hz": {}, + "bus_timer_hz": {}, "bypass": false, "cpu_hz": 25000000, + "fixed_plls": {}, "hclk_hz": 25000000, "pll": null, "source": "sysclk", @@ -166,7 +168,7 @@ }, { "path": "drivers/bindings.yaml", - "sha256": "d3c336ac05548e0addd1faac18f3dff70576d8069f11d89e6a761cf5c6132b49" + "sha256": "c06d1a914adb21d0e314c79b3611ac6859eefeac1957d6914cccfc5531ad6ede" }, { "path": "soc/arm/mps2/an386.yaml", diff --git a/boards/arm/mps2_an386/generated/.base/include/hw_config.h b/boards/arm/mps2_an386/generated/.base/include/hw_config.h index a01b6b04..eee2ecdd 100644 --- a/boards/arm/mps2_an386/generated/.base/include/hw_config.h +++ b/boards/arm/mps2_an386/generated/.base/include/hw_config.h @@ -17,7 +17,7 @@ * boards/arm/mps2_an386/board.yaml * ce5fe8df24c5e3fafafdb5da3fb462f06fc90c651ef4db267e191b9abc344314 * drivers/bindings.yaml - * d3c336ac05548e0addd1faac18f3dff70576d8069f11d89e6a761cf5c6132b49 + * c06d1a914adb21d0e314c79b3611ac6859eefeac1957d6914cccfc5531ad6ede * soc/arm/mps2/an386.yaml * a5a883b92b845b7afba700d4d9fb3771de8eaf3131803f6dbd9f118414e07fc6 * soc/arm/mps2/mps2.yaml diff --git a/boards/arm/mps2_an386/generated/.base/include/soc_devices.h b/boards/arm/mps2_an386/generated/.base/include/soc_devices.h index 5fb8065b..f72752fd 100644 --- a/boards/arm/mps2_an386/generated/.base/include/soc_devices.h +++ b/boards/arm/mps2_an386/generated/.base/include/soc_devices.h @@ -17,7 +17,7 @@ * boards/arm/mps2_an386/board.yaml * ce5fe8df24c5e3fafafdb5da3fb462f06fc90c651ef4db267e191b9abc344314 * drivers/bindings.yaml - * d3c336ac05548e0addd1faac18f3dff70576d8069f11d89e6a761cf5c6132b49 + * c06d1a914adb21d0e314c79b3611ac6859eefeac1957d6914cccfc5531ad6ede * soc/arm/mps2/an386.yaml * a5a883b92b845b7afba700d4d9fb3771de8eaf3131803f6dbd9f118414e07fc6 * soc/arm/mps2/mps2.yaml diff --git a/boards/arm/mps2_an386/generated/.base/linker/regions.ld b/boards/arm/mps2_an386/generated/.base/linker/regions.ld index 4e816cc2..41f9cdc0 100644 --- a/boards/arm/mps2_an386/generated/.base/linker/regions.ld +++ b/boards/arm/mps2_an386/generated/.base/linker/regions.ld @@ -18,7 +18,7 @@ * boards/arm/mps2_an386/board.yaml * ce5fe8df24c5e3fafafdb5da3fb462f06fc90c651ef4db267e191b9abc344314 * drivers/bindings.yaml - * d3c336ac05548e0addd1faac18f3dff70576d8069f11d89e6a761cf5c6132b49 + * c06d1a914adb21d0e314c79b3611ac6859eefeac1957d6914cccfc5531ad6ede * soc/arm/mps2/an386.yaml * a5a883b92b845b7afba700d4d9fb3771de8eaf3131803f6dbd9f118414e07fc6 * soc/arm/mps2/mps2.yaml diff --git a/boards/arm/mps2_an386/generated/.base/src/soc_devices.c b/boards/arm/mps2_an386/generated/.base/src/soc_devices.c index 4a6d42d5..cbb2b389 100644 --- a/boards/arm/mps2_an386/generated/.base/src/soc_devices.c +++ b/boards/arm/mps2_an386/generated/.base/src/soc_devices.c @@ -18,7 +18,7 @@ * boards/arm/mps2_an386/board.yaml * ce5fe8df24c5e3fafafdb5da3fb462f06fc90c651ef4db267e191b9abc344314 * drivers/bindings.yaml - * d3c336ac05548e0addd1faac18f3dff70576d8069f11d89e6a761cf5c6132b49 + * c06d1a914adb21d0e314c79b3611ac6859eefeac1957d6914cccfc5531ad6ede * soc/arm/mps2/an386.yaml * a5a883b92b845b7afba700d4d9fb3771de8eaf3131803f6dbd9f118414e07fc6 * soc/arm/mps2/mps2.yaml diff --git a/boards/arm/mps2_an386/generated/build/CMakeLists.txt b/boards/arm/mps2_an386/generated/build/CMakeLists.txt index 900866fb..3f4af4fd 100644 --- a/boards/arm/mps2_an386/generated/build/CMakeLists.txt +++ b/boards/arm/mps2_an386/generated/build/CMakeLists.txt @@ -11,7 +11,7 @@ # boards/arm/mps2_an386/board.yaml # ce5fe8df24c5e3fafafdb5da3fb462f06fc90c651ef4db267e191b9abc344314 # drivers/bindings.yaml -# d3c336ac05548e0addd1faac18f3dff70576d8069f11d89e6a761cf5c6132b49 +# c06d1a914adb21d0e314c79b3611ac6859eefeac1957d6914cccfc5531ad6ede # soc/arm/mps2/an386.yaml # a5a883b92b845b7afba700d4d9fb3771de8eaf3131803f6dbd9f118414e07fc6 # soc/arm/mps2/mps2.yaml diff --git a/boards/arm/mps2_an386/generated/build/board.cmake b/boards/arm/mps2_an386/generated/build/board.cmake index afacb19b..641f2c44 100644 --- a/boards/arm/mps2_an386/generated/build/board.cmake +++ b/boards/arm/mps2_an386/generated/build/board.cmake @@ -11,7 +11,7 @@ # boards/arm/mps2_an386/board.yaml # ce5fe8df24c5e3fafafdb5da3fb462f06fc90c651ef4db267e191b9abc344314 # drivers/bindings.yaml -# d3c336ac05548e0addd1faac18f3dff70576d8069f11d89e6a761cf5c6132b49 +# c06d1a914adb21d0e314c79b3611ac6859eefeac1957d6914cccfc5531ad6ede # soc/arm/mps2/an386.yaml # a5a883b92b845b7afba700d4d9fb3771de8eaf3131803f6dbd9f118414e07fc6 # soc/arm/mps2/mps2.yaml @@ -25,6 +25,8 @@ get_filename_component(EMB_BOARD_GENERATED_DIR "${CMAKE_CURRENT_LIST_DIR}/.." AB set(EMB_BOARD_CONF "${EMB_BOARD_GENERATED_DIR}/config/board.conf") set(EMB_BOARD_HW_JSON "${EMB_BOARD_GENERATED_DIR}/docs/hw.json") set(EMB_BOARD_BUILD_DIR "${CMAKE_CURRENT_LIST_DIR}") # build/CMakeLists.txt +set(EMB_BOARD_SRC_DIR "${EMB_BOARD_GENERATED_DIR}/src") # its pin table and boot block +set(EMB_BOARD_LINKER_DIR "${EMB_BOARD_GENERATED_DIR}/linker") # the SoC family's board support and drivers build this board (build/CMakeLists.txt) set(EMB_SOC_DIR "${EMB_BASE}/soc/arm/mps2") set(EMB_BOARD_INCLUDE_DIRS "${EMB_BOARD_GENERATED_DIR}/include" "${EMB_SOC_DIR}/include") @@ -44,7 +46,7 @@ set(EMB_BOARD_DRIVER_INCLUDE_DIRS set(EMB_BOARD_HW_INPUTS "arch/cortex_m/arch.yaml=c5c8e451c09717dee1713d07f8311b6d507e3b4c66c42d93e0ce11da6ec76d6d" "boards/arm/mps2_an386/board.yaml=ce5fe8df24c5e3fafafdb5da3fb462f06fc90c651ef4db267e191b9abc344314" - "drivers/bindings.yaml=d3c336ac05548e0addd1faac18f3dff70576d8069f11d89e6a761cf5c6132b49" + "drivers/bindings.yaml=c06d1a914adb21d0e314c79b3611ac6859eefeac1957d6914cccfc5531ad6ede" "soc/arm/mps2/an386.yaml=a5a883b92b845b7afba700d4d9fb3771de8eaf3131803f6dbd9f118414e07fc6" "soc/arm/mps2/mps2.yaml=7bc066c165dbd50db2c6c3e35cf8a3f12ae360b7ad578cfe06983b3f807d1d71" ) diff --git a/boards/arm/mps2_an386/generated/config/board.conf b/boards/arm/mps2_an386/generated/config/board.conf index 849cb81e..e1627d85 100644 --- a/boards/arm/mps2_an386/generated/config/board.conf +++ b/boards/arm/mps2_an386/generated/config/board.conf @@ -11,7 +11,7 @@ # boards/arm/mps2_an386/board.yaml # ce5fe8df24c5e3fafafdb5da3fb462f06fc90c651ef4db267e191b9abc344314 # drivers/bindings.yaml -# d3c336ac05548e0addd1faac18f3dff70576d8069f11d89e6a761cf5c6132b49 +# c06d1a914adb21d0e314c79b3611ac6859eefeac1957d6914cccfc5531ad6ede # soc/arm/mps2/an386.yaml # a5a883b92b845b7afba700d4d9fb3771de8eaf3131803f6dbd9f118414e07fc6 # soc/arm/mps2/mps2.yaml diff --git a/boards/arm/mps2_an386/generated/docs/board.md b/boards/arm/mps2_an386/generated/docs/board.md index f0ef7a65..09040cbb 100644 --- a/boards/arm/mps2_an386/generated/docs/board.md +++ b/boards/arm/mps2_an386/generated/docs/board.md @@ -53,6 +53,6 @@ Generated by emb-hwgen 0.1.0, schema v0, from: |---|---| | `arch/cortex_m/arch.yaml` | `c5c8e451c09717dee1713d07f8311b6d507e3b4c66c42d93e0ce11da6ec76d6d` | | `boards/arm/mps2_an386/board.yaml` | `ce5fe8df24c5e3fafafdb5da3fb462f06fc90c651ef4db267e191b9abc344314` | -| `drivers/bindings.yaml` | `d3c336ac05548e0addd1faac18f3dff70576d8069f11d89e6a761cf5c6132b49` | +| `drivers/bindings.yaml` | `c06d1a914adb21d0e314c79b3611ac6859eefeac1957d6914cccfc5531ad6ede` | | `soc/arm/mps2/an386.yaml` | `a5a883b92b845b7afba700d4d9fb3771de8eaf3131803f6dbd9f118414e07fc6` | | `soc/arm/mps2/mps2.yaml` | `7bc066c165dbd50db2c6c3e35cf8a3f12ae360b7ad578cfe06983b3f807d1d71` | diff --git a/boards/arm/mps2_an386/generated/docs/build_report.md b/boards/arm/mps2_an386/generated/docs/build_report.md index 0c1efa38..ce38511c 100644 --- a/boards/arm/mps2_an386/generated/docs/build_report.md +++ b/boards/arm/mps2_an386/generated/docs/build_report.md @@ -24,6 +24,6 @@ Generated by emb-hwgen 0.1.0, schema v0, from: |---|---| | `arch/cortex_m/arch.yaml` | `c5c8e451c09717dee1713d07f8311b6d507e3b4c66c42d93e0ce11da6ec76d6d` | | `boards/arm/mps2_an386/board.yaml` | `ce5fe8df24c5e3fafafdb5da3fb462f06fc90c651ef4db267e191b9abc344314` | -| `drivers/bindings.yaml` | `d3c336ac05548e0addd1faac18f3dff70576d8069f11d89e6a761cf5c6132b49` | +| `drivers/bindings.yaml` | `c06d1a914adb21d0e314c79b3611ac6859eefeac1957d6914cccfc5531ad6ede` | | `soc/arm/mps2/an386.yaml` | `a5a883b92b845b7afba700d4d9fb3771de8eaf3131803f6dbd9f118414e07fc6` | | `soc/arm/mps2/mps2.yaml` | `7bc066c165dbd50db2c6c3e35cf8a3f12ae360b7ad578cfe06983b3f807d1d71` | diff --git a/boards/arm/mps2_an386/generated/docs/hw.json b/boards/arm/mps2_an386/generated/docs/hw.json index f9edbedb..841bb2f1 100644 --- a/boards/arm/mps2_an386/generated/docs/hw.json +++ b/boards/arm/mps2_an386/generated/docs/hw.json @@ -58,8 +58,10 @@ "clock": { "ahb_div": 1, "bus_hz": {}, + "bus_timer_hz": {}, "bypass": false, "cpu_hz": 25000000, + "fixed_plls": {}, "hclk_hz": 25000000, "pll": null, "source": "sysclk", @@ -166,7 +168,7 @@ }, { "path": "drivers/bindings.yaml", - "sha256": "d3c336ac05548e0addd1faac18f3dff70576d8069f11d89e6a761cf5c6132b49" + "sha256": "c06d1a914adb21d0e314c79b3611ac6859eefeac1957d6914cccfc5531ad6ede" }, { "path": "soc/arm/mps2/an386.yaml", diff --git a/boards/arm/mps2_an386/generated/include/hw_config.h b/boards/arm/mps2_an386/generated/include/hw_config.h index a01b6b04..eee2ecdd 100644 --- a/boards/arm/mps2_an386/generated/include/hw_config.h +++ b/boards/arm/mps2_an386/generated/include/hw_config.h @@ -17,7 +17,7 @@ * boards/arm/mps2_an386/board.yaml * ce5fe8df24c5e3fafafdb5da3fb462f06fc90c651ef4db267e191b9abc344314 * drivers/bindings.yaml - * d3c336ac05548e0addd1faac18f3dff70576d8069f11d89e6a761cf5c6132b49 + * c06d1a914adb21d0e314c79b3611ac6859eefeac1957d6914cccfc5531ad6ede * soc/arm/mps2/an386.yaml * a5a883b92b845b7afba700d4d9fb3771de8eaf3131803f6dbd9f118414e07fc6 * soc/arm/mps2/mps2.yaml diff --git a/boards/arm/mps2_an386/generated/include/soc_devices.h b/boards/arm/mps2_an386/generated/include/soc_devices.h index 5fb8065b..f72752fd 100644 --- a/boards/arm/mps2_an386/generated/include/soc_devices.h +++ b/boards/arm/mps2_an386/generated/include/soc_devices.h @@ -17,7 +17,7 @@ * boards/arm/mps2_an386/board.yaml * ce5fe8df24c5e3fafafdb5da3fb462f06fc90c651ef4db267e191b9abc344314 * drivers/bindings.yaml - * d3c336ac05548e0addd1faac18f3dff70576d8069f11d89e6a761cf5c6132b49 + * c06d1a914adb21d0e314c79b3611ac6859eefeac1957d6914cccfc5531ad6ede * soc/arm/mps2/an386.yaml * a5a883b92b845b7afba700d4d9fb3771de8eaf3131803f6dbd9f118414e07fc6 * soc/arm/mps2/mps2.yaml diff --git a/boards/arm/mps2_an386/generated/linker/regions.ld b/boards/arm/mps2_an386/generated/linker/regions.ld index 4e816cc2..41f9cdc0 100644 --- a/boards/arm/mps2_an386/generated/linker/regions.ld +++ b/boards/arm/mps2_an386/generated/linker/regions.ld @@ -18,7 +18,7 @@ * boards/arm/mps2_an386/board.yaml * ce5fe8df24c5e3fafafdb5da3fb462f06fc90c651ef4db267e191b9abc344314 * drivers/bindings.yaml - * d3c336ac05548e0addd1faac18f3dff70576d8069f11d89e6a761cf5c6132b49 + * c06d1a914adb21d0e314c79b3611ac6859eefeac1957d6914cccfc5531ad6ede * soc/arm/mps2/an386.yaml * a5a883b92b845b7afba700d4d9fb3771de8eaf3131803f6dbd9f118414e07fc6 * soc/arm/mps2/mps2.yaml diff --git a/boards/arm/mps2_an386/generated/src/soc_devices.c b/boards/arm/mps2_an386/generated/src/soc_devices.c index 4a6d42d5..cbb2b389 100644 --- a/boards/arm/mps2_an386/generated/src/soc_devices.c +++ b/boards/arm/mps2_an386/generated/src/soc_devices.c @@ -18,7 +18,7 @@ * boards/arm/mps2_an386/board.yaml * ce5fe8df24c5e3fafafdb5da3fb462f06fc90c651ef4db267e191b9abc344314 * drivers/bindings.yaml - * d3c336ac05548e0addd1faac18f3dff70576d8069f11d89e6a761cf5c6132b49 + * c06d1a914adb21d0e314c79b3611ac6859eefeac1957d6914cccfc5531ad6ede * soc/arm/mps2/an386.yaml * a5a883b92b845b7afba700d4d9fb3771de8eaf3131803f6dbd9f118414e07fc6 * soc/arm/mps2/mps2.yaml diff --git a/boards/arm/mps2_an500/generated/.base/build/CMakeLists.txt b/boards/arm/mps2_an500/generated/.base/build/CMakeLists.txt index f9c18951..5a623ab7 100644 --- a/boards/arm/mps2_an500/generated/.base/build/CMakeLists.txt +++ b/boards/arm/mps2_an500/generated/.base/build/CMakeLists.txt @@ -11,7 +11,7 @@ # boards/arm/mps2_an500/board.yaml # 85401cc9579f569dbf39fdd796bd90d9a1e9502eef07276ba3a322c0ed3c0561 # drivers/bindings.yaml -# d3c336ac05548e0addd1faac18f3dff70576d8069f11d89e6a761cf5c6132b49 +# c06d1a914adb21d0e314c79b3611ac6859eefeac1957d6914cccfc5531ad6ede # soc/arm/mps2/an500.yaml # 6cf725200210826569b7fc32c2bbfe0a9759b6308986859af340ed1543f053f6 # soc/arm/mps2/mps2.yaml diff --git a/boards/arm/mps2_an500/generated/.base/build/board.cmake b/boards/arm/mps2_an500/generated/.base/build/board.cmake index 1b642aa6..6dfce106 100644 --- a/boards/arm/mps2_an500/generated/.base/build/board.cmake +++ b/boards/arm/mps2_an500/generated/.base/build/board.cmake @@ -11,7 +11,7 @@ # boards/arm/mps2_an500/board.yaml # 85401cc9579f569dbf39fdd796bd90d9a1e9502eef07276ba3a322c0ed3c0561 # drivers/bindings.yaml -# d3c336ac05548e0addd1faac18f3dff70576d8069f11d89e6a761cf5c6132b49 +# c06d1a914adb21d0e314c79b3611ac6859eefeac1957d6914cccfc5531ad6ede # soc/arm/mps2/an500.yaml # 6cf725200210826569b7fc32c2bbfe0a9759b6308986859af340ed1543f053f6 # soc/arm/mps2/mps2.yaml @@ -25,6 +25,8 @@ get_filename_component(EMB_BOARD_GENERATED_DIR "${CMAKE_CURRENT_LIST_DIR}/.." AB set(EMB_BOARD_CONF "${EMB_BOARD_GENERATED_DIR}/config/board.conf") set(EMB_BOARD_HW_JSON "${EMB_BOARD_GENERATED_DIR}/docs/hw.json") set(EMB_BOARD_BUILD_DIR "${CMAKE_CURRENT_LIST_DIR}") # build/CMakeLists.txt +set(EMB_BOARD_SRC_DIR "${EMB_BOARD_GENERATED_DIR}/src") # its pin table and boot block +set(EMB_BOARD_LINKER_DIR "${EMB_BOARD_GENERATED_DIR}/linker") # the SoC family's board support and drivers build this board (build/CMakeLists.txt) set(EMB_SOC_DIR "${EMB_BASE}/soc/arm/mps2") set(EMB_BOARD_INCLUDE_DIRS "${EMB_BOARD_GENERATED_DIR}/include" "${EMB_SOC_DIR}/include") @@ -44,7 +46,7 @@ set(EMB_BOARD_DRIVER_INCLUDE_DIRS set(EMB_BOARD_HW_INPUTS "arch/cortex_m/arch.yaml=c5c8e451c09717dee1713d07f8311b6d507e3b4c66c42d93e0ce11da6ec76d6d" "boards/arm/mps2_an500/board.yaml=85401cc9579f569dbf39fdd796bd90d9a1e9502eef07276ba3a322c0ed3c0561" - "drivers/bindings.yaml=d3c336ac05548e0addd1faac18f3dff70576d8069f11d89e6a761cf5c6132b49" + "drivers/bindings.yaml=c06d1a914adb21d0e314c79b3611ac6859eefeac1957d6914cccfc5531ad6ede" "soc/arm/mps2/an500.yaml=6cf725200210826569b7fc32c2bbfe0a9759b6308986859af340ed1543f053f6" "soc/arm/mps2/mps2.yaml=7bc066c165dbd50db2c6c3e35cf8a3f12ae360b7ad578cfe06983b3f807d1d71" ) diff --git a/boards/arm/mps2_an500/generated/.base/config/board.conf b/boards/arm/mps2_an500/generated/.base/config/board.conf index 7afb978d..3ee38e40 100644 --- a/boards/arm/mps2_an500/generated/.base/config/board.conf +++ b/boards/arm/mps2_an500/generated/.base/config/board.conf @@ -11,7 +11,7 @@ # boards/arm/mps2_an500/board.yaml # 85401cc9579f569dbf39fdd796bd90d9a1e9502eef07276ba3a322c0ed3c0561 # drivers/bindings.yaml -# d3c336ac05548e0addd1faac18f3dff70576d8069f11d89e6a761cf5c6132b49 +# c06d1a914adb21d0e314c79b3611ac6859eefeac1957d6914cccfc5531ad6ede # soc/arm/mps2/an500.yaml # 6cf725200210826569b7fc32c2bbfe0a9759b6308986859af340ed1543f053f6 # soc/arm/mps2/mps2.yaml diff --git a/boards/arm/mps2_an500/generated/.base/docs/board.md b/boards/arm/mps2_an500/generated/.base/docs/board.md index caf7de31..35d4d0b4 100644 --- a/boards/arm/mps2_an500/generated/.base/docs/board.md +++ b/boards/arm/mps2_an500/generated/.base/docs/board.md @@ -53,6 +53,6 @@ Generated by emb-hwgen 0.1.0, schema v0, from: |---|---| | `arch/cortex_m/arch.yaml` | `c5c8e451c09717dee1713d07f8311b6d507e3b4c66c42d93e0ce11da6ec76d6d` | | `boards/arm/mps2_an500/board.yaml` | `85401cc9579f569dbf39fdd796bd90d9a1e9502eef07276ba3a322c0ed3c0561` | -| `drivers/bindings.yaml` | `d3c336ac05548e0addd1faac18f3dff70576d8069f11d89e6a761cf5c6132b49` | +| `drivers/bindings.yaml` | `c06d1a914adb21d0e314c79b3611ac6859eefeac1957d6914cccfc5531ad6ede` | | `soc/arm/mps2/an500.yaml` | `6cf725200210826569b7fc32c2bbfe0a9759b6308986859af340ed1543f053f6` | | `soc/arm/mps2/mps2.yaml` | `7bc066c165dbd50db2c6c3e35cf8a3f12ae360b7ad578cfe06983b3f807d1d71` | diff --git a/boards/arm/mps2_an500/generated/.base/docs/build_report.md b/boards/arm/mps2_an500/generated/.base/docs/build_report.md index 0d2a436c..8964653c 100644 --- a/boards/arm/mps2_an500/generated/.base/docs/build_report.md +++ b/boards/arm/mps2_an500/generated/.base/docs/build_report.md @@ -24,6 +24,6 @@ Generated by emb-hwgen 0.1.0, schema v0, from: |---|---| | `arch/cortex_m/arch.yaml` | `c5c8e451c09717dee1713d07f8311b6d507e3b4c66c42d93e0ce11da6ec76d6d` | | `boards/arm/mps2_an500/board.yaml` | `85401cc9579f569dbf39fdd796bd90d9a1e9502eef07276ba3a322c0ed3c0561` | -| `drivers/bindings.yaml` | `d3c336ac05548e0addd1faac18f3dff70576d8069f11d89e6a761cf5c6132b49` | +| `drivers/bindings.yaml` | `c06d1a914adb21d0e314c79b3611ac6859eefeac1957d6914cccfc5531ad6ede` | | `soc/arm/mps2/an500.yaml` | `6cf725200210826569b7fc32c2bbfe0a9759b6308986859af340ed1543f053f6` | | `soc/arm/mps2/mps2.yaml` | `7bc066c165dbd50db2c6c3e35cf8a3f12ae360b7ad578cfe06983b3f807d1d71` | diff --git a/boards/arm/mps2_an500/generated/.base/docs/hw.json b/boards/arm/mps2_an500/generated/.base/docs/hw.json index 34fffd61..80e49ac6 100644 --- a/boards/arm/mps2_an500/generated/.base/docs/hw.json +++ b/boards/arm/mps2_an500/generated/.base/docs/hw.json @@ -58,8 +58,10 @@ "clock": { "ahb_div": 1, "bus_hz": {}, + "bus_timer_hz": {}, "bypass": false, "cpu_hz": 25000000, + "fixed_plls": {}, "hclk_hz": 25000000, "pll": null, "source": "sysclk", @@ -166,7 +168,7 @@ }, { "path": "drivers/bindings.yaml", - "sha256": "d3c336ac05548e0addd1faac18f3dff70576d8069f11d89e6a761cf5c6132b49" + "sha256": "c06d1a914adb21d0e314c79b3611ac6859eefeac1957d6914cccfc5531ad6ede" }, { "path": "soc/arm/mps2/an500.yaml", diff --git a/boards/arm/mps2_an500/generated/.base/include/hw_config.h b/boards/arm/mps2_an500/generated/.base/include/hw_config.h index 4b271314..7a482203 100644 --- a/boards/arm/mps2_an500/generated/.base/include/hw_config.h +++ b/boards/arm/mps2_an500/generated/.base/include/hw_config.h @@ -17,7 +17,7 @@ * boards/arm/mps2_an500/board.yaml * 85401cc9579f569dbf39fdd796bd90d9a1e9502eef07276ba3a322c0ed3c0561 * drivers/bindings.yaml - * d3c336ac05548e0addd1faac18f3dff70576d8069f11d89e6a761cf5c6132b49 + * c06d1a914adb21d0e314c79b3611ac6859eefeac1957d6914cccfc5531ad6ede * soc/arm/mps2/an500.yaml * 6cf725200210826569b7fc32c2bbfe0a9759b6308986859af340ed1543f053f6 * soc/arm/mps2/mps2.yaml diff --git a/boards/arm/mps2_an500/generated/.base/include/soc_devices.h b/boards/arm/mps2_an500/generated/.base/include/soc_devices.h index f1252519..99ad2da2 100644 --- a/boards/arm/mps2_an500/generated/.base/include/soc_devices.h +++ b/boards/arm/mps2_an500/generated/.base/include/soc_devices.h @@ -17,7 +17,7 @@ * boards/arm/mps2_an500/board.yaml * 85401cc9579f569dbf39fdd796bd90d9a1e9502eef07276ba3a322c0ed3c0561 * drivers/bindings.yaml - * d3c336ac05548e0addd1faac18f3dff70576d8069f11d89e6a761cf5c6132b49 + * c06d1a914adb21d0e314c79b3611ac6859eefeac1957d6914cccfc5531ad6ede * soc/arm/mps2/an500.yaml * 6cf725200210826569b7fc32c2bbfe0a9759b6308986859af340ed1543f053f6 * soc/arm/mps2/mps2.yaml diff --git a/boards/arm/mps2_an500/generated/.base/linker/regions.ld b/boards/arm/mps2_an500/generated/.base/linker/regions.ld index dfaae3bc..b1f80c6e 100644 --- a/boards/arm/mps2_an500/generated/.base/linker/regions.ld +++ b/boards/arm/mps2_an500/generated/.base/linker/regions.ld @@ -18,7 +18,7 @@ * boards/arm/mps2_an500/board.yaml * 85401cc9579f569dbf39fdd796bd90d9a1e9502eef07276ba3a322c0ed3c0561 * drivers/bindings.yaml - * d3c336ac05548e0addd1faac18f3dff70576d8069f11d89e6a761cf5c6132b49 + * c06d1a914adb21d0e314c79b3611ac6859eefeac1957d6914cccfc5531ad6ede * soc/arm/mps2/an500.yaml * 6cf725200210826569b7fc32c2bbfe0a9759b6308986859af340ed1543f053f6 * soc/arm/mps2/mps2.yaml diff --git a/boards/arm/mps2_an500/generated/.base/src/soc_devices.c b/boards/arm/mps2_an500/generated/.base/src/soc_devices.c index 5fe00411..8033b564 100644 --- a/boards/arm/mps2_an500/generated/.base/src/soc_devices.c +++ b/boards/arm/mps2_an500/generated/.base/src/soc_devices.c @@ -18,7 +18,7 @@ * boards/arm/mps2_an500/board.yaml * 85401cc9579f569dbf39fdd796bd90d9a1e9502eef07276ba3a322c0ed3c0561 * drivers/bindings.yaml - * d3c336ac05548e0addd1faac18f3dff70576d8069f11d89e6a761cf5c6132b49 + * c06d1a914adb21d0e314c79b3611ac6859eefeac1957d6914cccfc5531ad6ede * soc/arm/mps2/an500.yaml * 6cf725200210826569b7fc32c2bbfe0a9759b6308986859af340ed1543f053f6 * soc/arm/mps2/mps2.yaml diff --git a/boards/arm/mps2_an500/generated/build/CMakeLists.txt b/boards/arm/mps2_an500/generated/build/CMakeLists.txt index f9c18951..5a623ab7 100644 --- a/boards/arm/mps2_an500/generated/build/CMakeLists.txt +++ b/boards/arm/mps2_an500/generated/build/CMakeLists.txt @@ -11,7 +11,7 @@ # boards/arm/mps2_an500/board.yaml # 85401cc9579f569dbf39fdd796bd90d9a1e9502eef07276ba3a322c0ed3c0561 # drivers/bindings.yaml -# d3c336ac05548e0addd1faac18f3dff70576d8069f11d89e6a761cf5c6132b49 +# c06d1a914adb21d0e314c79b3611ac6859eefeac1957d6914cccfc5531ad6ede # soc/arm/mps2/an500.yaml # 6cf725200210826569b7fc32c2bbfe0a9759b6308986859af340ed1543f053f6 # soc/arm/mps2/mps2.yaml diff --git a/boards/arm/mps2_an500/generated/build/board.cmake b/boards/arm/mps2_an500/generated/build/board.cmake index 1b642aa6..6dfce106 100644 --- a/boards/arm/mps2_an500/generated/build/board.cmake +++ b/boards/arm/mps2_an500/generated/build/board.cmake @@ -11,7 +11,7 @@ # boards/arm/mps2_an500/board.yaml # 85401cc9579f569dbf39fdd796bd90d9a1e9502eef07276ba3a322c0ed3c0561 # drivers/bindings.yaml -# d3c336ac05548e0addd1faac18f3dff70576d8069f11d89e6a761cf5c6132b49 +# c06d1a914adb21d0e314c79b3611ac6859eefeac1957d6914cccfc5531ad6ede # soc/arm/mps2/an500.yaml # 6cf725200210826569b7fc32c2bbfe0a9759b6308986859af340ed1543f053f6 # soc/arm/mps2/mps2.yaml @@ -25,6 +25,8 @@ get_filename_component(EMB_BOARD_GENERATED_DIR "${CMAKE_CURRENT_LIST_DIR}/.." AB set(EMB_BOARD_CONF "${EMB_BOARD_GENERATED_DIR}/config/board.conf") set(EMB_BOARD_HW_JSON "${EMB_BOARD_GENERATED_DIR}/docs/hw.json") set(EMB_BOARD_BUILD_DIR "${CMAKE_CURRENT_LIST_DIR}") # build/CMakeLists.txt +set(EMB_BOARD_SRC_DIR "${EMB_BOARD_GENERATED_DIR}/src") # its pin table and boot block +set(EMB_BOARD_LINKER_DIR "${EMB_BOARD_GENERATED_DIR}/linker") # the SoC family's board support and drivers build this board (build/CMakeLists.txt) set(EMB_SOC_DIR "${EMB_BASE}/soc/arm/mps2") set(EMB_BOARD_INCLUDE_DIRS "${EMB_BOARD_GENERATED_DIR}/include" "${EMB_SOC_DIR}/include") @@ -44,7 +46,7 @@ set(EMB_BOARD_DRIVER_INCLUDE_DIRS set(EMB_BOARD_HW_INPUTS "arch/cortex_m/arch.yaml=c5c8e451c09717dee1713d07f8311b6d507e3b4c66c42d93e0ce11da6ec76d6d" "boards/arm/mps2_an500/board.yaml=85401cc9579f569dbf39fdd796bd90d9a1e9502eef07276ba3a322c0ed3c0561" - "drivers/bindings.yaml=d3c336ac05548e0addd1faac18f3dff70576d8069f11d89e6a761cf5c6132b49" + "drivers/bindings.yaml=c06d1a914adb21d0e314c79b3611ac6859eefeac1957d6914cccfc5531ad6ede" "soc/arm/mps2/an500.yaml=6cf725200210826569b7fc32c2bbfe0a9759b6308986859af340ed1543f053f6" "soc/arm/mps2/mps2.yaml=7bc066c165dbd50db2c6c3e35cf8a3f12ae360b7ad578cfe06983b3f807d1d71" ) diff --git a/boards/arm/mps2_an500/generated/config/board.conf b/boards/arm/mps2_an500/generated/config/board.conf index 7afb978d..3ee38e40 100644 --- a/boards/arm/mps2_an500/generated/config/board.conf +++ b/boards/arm/mps2_an500/generated/config/board.conf @@ -11,7 +11,7 @@ # boards/arm/mps2_an500/board.yaml # 85401cc9579f569dbf39fdd796bd90d9a1e9502eef07276ba3a322c0ed3c0561 # drivers/bindings.yaml -# d3c336ac05548e0addd1faac18f3dff70576d8069f11d89e6a761cf5c6132b49 +# c06d1a914adb21d0e314c79b3611ac6859eefeac1957d6914cccfc5531ad6ede # soc/arm/mps2/an500.yaml # 6cf725200210826569b7fc32c2bbfe0a9759b6308986859af340ed1543f053f6 # soc/arm/mps2/mps2.yaml diff --git a/boards/arm/mps2_an500/generated/docs/board.md b/boards/arm/mps2_an500/generated/docs/board.md index caf7de31..35d4d0b4 100644 --- a/boards/arm/mps2_an500/generated/docs/board.md +++ b/boards/arm/mps2_an500/generated/docs/board.md @@ -53,6 +53,6 @@ Generated by emb-hwgen 0.1.0, schema v0, from: |---|---| | `arch/cortex_m/arch.yaml` | `c5c8e451c09717dee1713d07f8311b6d507e3b4c66c42d93e0ce11da6ec76d6d` | | `boards/arm/mps2_an500/board.yaml` | `85401cc9579f569dbf39fdd796bd90d9a1e9502eef07276ba3a322c0ed3c0561` | -| `drivers/bindings.yaml` | `d3c336ac05548e0addd1faac18f3dff70576d8069f11d89e6a761cf5c6132b49` | +| `drivers/bindings.yaml` | `c06d1a914adb21d0e314c79b3611ac6859eefeac1957d6914cccfc5531ad6ede` | | `soc/arm/mps2/an500.yaml` | `6cf725200210826569b7fc32c2bbfe0a9759b6308986859af340ed1543f053f6` | | `soc/arm/mps2/mps2.yaml` | `7bc066c165dbd50db2c6c3e35cf8a3f12ae360b7ad578cfe06983b3f807d1d71` | diff --git a/boards/arm/mps2_an500/generated/docs/build_report.md b/boards/arm/mps2_an500/generated/docs/build_report.md index 0d2a436c..8964653c 100644 --- a/boards/arm/mps2_an500/generated/docs/build_report.md +++ b/boards/arm/mps2_an500/generated/docs/build_report.md @@ -24,6 +24,6 @@ Generated by emb-hwgen 0.1.0, schema v0, from: |---|---| | `arch/cortex_m/arch.yaml` | `c5c8e451c09717dee1713d07f8311b6d507e3b4c66c42d93e0ce11da6ec76d6d` | | `boards/arm/mps2_an500/board.yaml` | `85401cc9579f569dbf39fdd796bd90d9a1e9502eef07276ba3a322c0ed3c0561` | -| `drivers/bindings.yaml` | `d3c336ac05548e0addd1faac18f3dff70576d8069f11d89e6a761cf5c6132b49` | +| `drivers/bindings.yaml` | `c06d1a914adb21d0e314c79b3611ac6859eefeac1957d6914cccfc5531ad6ede` | | `soc/arm/mps2/an500.yaml` | `6cf725200210826569b7fc32c2bbfe0a9759b6308986859af340ed1543f053f6` | | `soc/arm/mps2/mps2.yaml` | `7bc066c165dbd50db2c6c3e35cf8a3f12ae360b7ad578cfe06983b3f807d1d71` | diff --git a/boards/arm/mps2_an500/generated/docs/hw.json b/boards/arm/mps2_an500/generated/docs/hw.json index 34fffd61..80e49ac6 100644 --- a/boards/arm/mps2_an500/generated/docs/hw.json +++ b/boards/arm/mps2_an500/generated/docs/hw.json @@ -58,8 +58,10 @@ "clock": { "ahb_div": 1, "bus_hz": {}, + "bus_timer_hz": {}, "bypass": false, "cpu_hz": 25000000, + "fixed_plls": {}, "hclk_hz": 25000000, "pll": null, "source": "sysclk", @@ -166,7 +168,7 @@ }, { "path": "drivers/bindings.yaml", - "sha256": "d3c336ac05548e0addd1faac18f3dff70576d8069f11d89e6a761cf5c6132b49" + "sha256": "c06d1a914adb21d0e314c79b3611ac6859eefeac1957d6914cccfc5531ad6ede" }, { "path": "soc/arm/mps2/an500.yaml", diff --git a/boards/arm/mps2_an500/generated/include/hw_config.h b/boards/arm/mps2_an500/generated/include/hw_config.h index 4b271314..7a482203 100644 --- a/boards/arm/mps2_an500/generated/include/hw_config.h +++ b/boards/arm/mps2_an500/generated/include/hw_config.h @@ -17,7 +17,7 @@ * boards/arm/mps2_an500/board.yaml * 85401cc9579f569dbf39fdd796bd90d9a1e9502eef07276ba3a322c0ed3c0561 * drivers/bindings.yaml - * d3c336ac05548e0addd1faac18f3dff70576d8069f11d89e6a761cf5c6132b49 + * c06d1a914adb21d0e314c79b3611ac6859eefeac1957d6914cccfc5531ad6ede * soc/arm/mps2/an500.yaml * 6cf725200210826569b7fc32c2bbfe0a9759b6308986859af340ed1543f053f6 * soc/arm/mps2/mps2.yaml diff --git a/boards/arm/mps2_an500/generated/include/soc_devices.h b/boards/arm/mps2_an500/generated/include/soc_devices.h index f1252519..99ad2da2 100644 --- a/boards/arm/mps2_an500/generated/include/soc_devices.h +++ b/boards/arm/mps2_an500/generated/include/soc_devices.h @@ -17,7 +17,7 @@ * boards/arm/mps2_an500/board.yaml * 85401cc9579f569dbf39fdd796bd90d9a1e9502eef07276ba3a322c0ed3c0561 * drivers/bindings.yaml - * d3c336ac05548e0addd1faac18f3dff70576d8069f11d89e6a761cf5c6132b49 + * c06d1a914adb21d0e314c79b3611ac6859eefeac1957d6914cccfc5531ad6ede * soc/arm/mps2/an500.yaml * 6cf725200210826569b7fc32c2bbfe0a9759b6308986859af340ed1543f053f6 * soc/arm/mps2/mps2.yaml diff --git a/boards/arm/mps2_an500/generated/linker/regions.ld b/boards/arm/mps2_an500/generated/linker/regions.ld index dfaae3bc..b1f80c6e 100644 --- a/boards/arm/mps2_an500/generated/linker/regions.ld +++ b/boards/arm/mps2_an500/generated/linker/regions.ld @@ -18,7 +18,7 @@ * boards/arm/mps2_an500/board.yaml * 85401cc9579f569dbf39fdd796bd90d9a1e9502eef07276ba3a322c0ed3c0561 * drivers/bindings.yaml - * d3c336ac05548e0addd1faac18f3dff70576d8069f11d89e6a761cf5c6132b49 + * c06d1a914adb21d0e314c79b3611ac6859eefeac1957d6914cccfc5531ad6ede * soc/arm/mps2/an500.yaml * 6cf725200210826569b7fc32c2bbfe0a9759b6308986859af340ed1543f053f6 * soc/arm/mps2/mps2.yaml diff --git a/boards/arm/mps2_an500/generated/src/soc_devices.c b/boards/arm/mps2_an500/generated/src/soc_devices.c index 5fe00411..8033b564 100644 --- a/boards/arm/mps2_an500/generated/src/soc_devices.c +++ b/boards/arm/mps2_an500/generated/src/soc_devices.c @@ -18,7 +18,7 @@ * boards/arm/mps2_an500/board.yaml * 85401cc9579f569dbf39fdd796bd90d9a1e9502eef07276ba3a322c0ed3c0561 * drivers/bindings.yaml - * d3c336ac05548e0addd1faac18f3dff70576d8069f11d89e6a761cf5c6132b49 + * c06d1a914adb21d0e314c79b3611ac6859eefeac1957d6914cccfc5531ad6ede * soc/arm/mps2/an500.yaml * 6cf725200210826569b7fc32c2bbfe0a9759b6308986859af340ed1543f053f6 * soc/arm/mps2/mps2.yaml diff --git a/boards/arm/mps2_an505/generated/.base/build/CMakeLists.txt b/boards/arm/mps2_an505/generated/.base/build/CMakeLists.txt index 778e0a2a..f92ab376 100644 --- a/boards/arm/mps2_an505/generated/.base/build/CMakeLists.txt +++ b/boards/arm/mps2_an505/generated/.base/build/CMakeLists.txt @@ -11,7 +11,7 @@ # boards/arm/mps2_an505/board.yaml # e294320434bc265e8bb036ae1c2d2f2fb520d6704fe597f587a7db006ffab05a # drivers/bindings.yaml -# d3c336ac05548e0addd1faac18f3dff70576d8069f11d89e6a761cf5c6132b49 +# c06d1a914adb21d0e314c79b3611ac6859eefeac1957d6914cccfc5531ad6ede # soc/arm/mps2/an505.yaml # d145c50a12402e61748bd8e2a58d54e9e9861d24292914ca6bb4d6b1338c06e3 # soc/arm/mps2/mps2.yaml diff --git a/boards/arm/mps2_an505/generated/.base/build/board.cmake b/boards/arm/mps2_an505/generated/.base/build/board.cmake index 0e1c00cc..248890d2 100644 --- a/boards/arm/mps2_an505/generated/.base/build/board.cmake +++ b/boards/arm/mps2_an505/generated/.base/build/board.cmake @@ -11,7 +11,7 @@ # boards/arm/mps2_an505/board.yaml # e294320434bc265e8bb036ae1c2d2f2fb520d6704fe597f587a7db006ffab05a # drivers/bindings.yaml -# d3c336ac05548e0addd1faac18f3dff70576d8069f11d89e6a761cf5c6132b49 +# c06d1a914adb21d0e314c79b3611ac6859eefeac1957d6914cccfc5531ad6ede # soc/arm/mps2/an505.yaml # d145c50a12402e61748bd8e2a58d54e9e9861d24292914ca6bb4d6b1338c06e3 # soc/arm/mps2/mps2.yaml @@ -25,6 +25,8 @@ get_filename_component(EMB_BOARD_GENERATED_DIR "${CMAKE_CURRENT_LIST_DIR}/.." AB set(EMB_BOARD_CONF "${EMB_BOARD_GENERATED_DIR}/config/board.conf") set(EMB_BOARD_HW_JSON "${EMB_BOARD_GENERATED_DIR}/docs/hw.json") set(EMB_BOARD_BUILD_DIR "${CMAKE_CURRENT_LIST_DIR}") # build/CMakeLists.txt +set(EMB_BOARD_SRC_DIR "${EMB_BOARD_GENERATED_DIR}/src") # its pin table and boot block +set(EMB_BOARD_LINKER_DIR "${EMB_BOARD_GENERATED_DIR}/linker") # the SoC family's board support and drivers build this board (build/CMakeLists.txt) set(EMB_SOC_DIR "${EMB_BASE}/soc/arm/mps2") set(EMB_BOARD_INCLUDE_DIRS "${EMB_BOARD_GENERATED_DIR}/include" "${EMB_SOC_DIR}/include") @@ -44,7 +46,7 @@ set(EMB_BOARD_DRIVER_INCLUDE_DIRS set(EMB_BOARD_HW_INPUTS "arch/cortex_m/arch.yaml=c5c8e451c09717dee1713d07f8311b6d507e3b4c66c42d93e0ce11da6ec76d6d" "boards/arm/mps2_an505/board.yaml=e294320434bc265e8bb036ae1c2d2f2fb520d6704fe597f587a7db006ffab05a" - "drivers/bindings.yaml=d3c336ac05548e0addd1faac18f3dff70576d8069f11d89e6a761cf5c6132b49" + "drivers/bindings.yaml=c06d1a914adb21d0e314c79b3611ac6859eefeac1957d6914cccfc5531ad6ede" "soc/arm/mps2/an505.yaml=d145c50a12402e61748bd8e2a58d54e9e9861d24292914ca6bb4d6b1338c06e3" "soc/arm/mps2/mps2.yaml=7bc066c165dbd50db2c6c3e35cf8a3f12ae360b7ad578cfe06983b3f807d1d71" ) diff --git a/boards/arm/mps2_an505/generated/.base/config/board.conf b/boards/arm/mps2_an505/generated/.base/config/board.conf index 6960b185..6f55594c 100644 --- a/boards/arm/mps2_an505/generated/.base/config/board.conf +++ b/boards/arm/mps2_an505/generated/.base/config/board.conf @@ -11,7 +11,7 @@ # boards/arm/mps2_an505/board.yaml # e294320434bc265e8bb036ae1c2d2f2fb520d6704fe597f587a7db006ffab05a # drivers/bindings.yaml -# d3c336ac05548e0addd1faac18f3dff70576d8069f11d89e6a761cf5c6132b49 +# c06d1a914adb21d0e314c79b3611ac6859eefeac1957d6914cccfc5531ad6ede # soc/arm/mps2/an505.yaml # d145c50a12402e61748bd8e2a58d54e9e9861d24292914ca6bb4d6b1338c06e3 # soc/arm/mps2/mps2.yaml diff --git a/boards/arm/mps2_an505/generated/.base/docs/board.md b/boards/arm/mps2_an505/generated/.base/docs/board.md index a09a5f80..51691275 100644 --- a/boards/arm/mps2_an505/generated/.base/docs/board.md +++ b/boards/arm/mps2_an505/generated/.base/docs/board.md @@ -53,6 +53,6 @@ Generated by emb-hwgen 0.1.0, schema v0, from: |---|---| | `arch/cortex_m/arch.yaml` | `c5c8e451c09717dee1713d07f8311b6d507e3b4c66c42d93e0ce11da6ec76d6d` | | `boards/arm/mps2_an505/board.yaml` | `e294320434bc265e8bb036ae1c2d2f2fb520d6704fe597f587a7db006ffab05a` | -| `drivers/bindings.yaml` | `d3c336ac05548e0addd1faac18f3dff70576d8069f11d89e6a761cf5c6132b49` | +| `drivers/bindings.yaml` | `c06d1a914adb21d0e314c79b3611ac6859eefeac1957d6914cccfc5531ad6ede` | | `soc/arm/mps2/an505.yaml` | `d145c50a12402e61748bd8e2a58d54e9e9861d24292914ca6bb4d6b1338c06e3` | | `soc/arm/mps2/mps2.yaml` | `7bc066c165dbd50db2c6c3e35cf8a3f12ae360b7ad578cfe06983b3f807d1d71` | diff --git a/boards/arm/mps2_an505/generated/.base/docs/build_report.md b/boards/arm/mps2_an505/generated/.base/docs/build_report.md index 6563999c..09b9b0ba 100644 --- a/boards/arm/mps2_an505/generated/.base/docs/build_report.md +++ b/boards/arm/mps2_an505/generated/.base/docs/build_report.md @@ -24,6 +24,6 @@ Generated by emb-hwgen 0.1.0, schema v0, from: |---|---| | `arch/cortex_m/arch.yaml` | `c5c8e451c09717dee1713d07f8311b6d507e3b4c66c42d93e0ce11da6ec76d6d` | | `boards/arm/mps2_an505/board.yaml` | `e294320434bc265e8bb036ae1c2d2f2fb520d6704fe597f587a7db006ffab05a` | -| `drivers/bindings.yaml` | `d3c336ac05548e0addd1faac18f3dff70576d8069f11d89e6a761cf5c6132b49` | +| `drivers/bindings.yaml` | `c06d1a914adb21d0e314c79b3611ac6859eefeac1957d6914cccfc5531ad6ede` | | `soc/arm/mps2/an505.yaml` | `d145c50a12402e61748bd8e2a58d54e9e9861d24292914ca6bb4d6b1338c06e3` | | `soc/arm/mps2/mps2.yaml` | `7bc066c165dbd50db2c6c3e35cf8a3f12ae360b7ad578cfe06983b3f807d1d71` | diff --git a/boards/arm/mps2_an505/generated/.base/docs/hw.json b/boards/arm/mps2_an505/generated/.base/docs/hw.json index 106d5680..08cd800b 100644 --- a/boards/arm/mps2_an505/generated/.base/docs/hw.json +++ b/boards/arm/mps2_an505/generated/.base/docs/hw.json @@ -58,8 +58,10 @@ "clock": { "ahb_div": 1, "bus_hz": {}, + "bus_timer_hz": {}, "bypass": false, "cpu_hz": 20000000, + "fixed_plls": {}, "hclk_hz": 20000000, "pll": null, "source": "sysclk", @@ -166,7 +168,7 @@ }, { "path": "drivers/bindings.yaml", - "sha256": "d3c336ac05548e0addd1faac18f3dff70576d8069f11d89e6a761cf5c6132b49" + "sha256": "c06d1a914adb21d0e314c79b3611ac6859eefeac1957d6914cccfc5531ad6ede" }, { "path": "soc/arm/mps2/an505.yaml", diff --git a/boards/arm/mps2_an505/generated/.base/include/hw_config.h b/boards/arm/mps2_an505/generated/.base/include/hw_config.h index ee86f631..6c36eeb0 100644 --- a/boards/arm/mps2_an505/generated/.base/include/hw_config.h +++ b/boards/arm/mps2_an505/generated/.base/include/hw_config.h @@ -17,7 +17,7 @@ * boards/arm/mps2_an505/board.yaml * e294320434bc265e8bb036ae1c2d2f2fb520d6704fe597f587a7db006ffab05a * drivers/bindings.yaml - * d3c336ac05548e0addd1faac18f3dff70576d8069f11d89e6a761cf5c6132b49 + * c06d1a914adb21d0e314c79b3611ac6859eefeac1957d6914cccfc5531ad6ede * soc/arm/mps2/an505.yaml * d145c50a12402e61748bd8e2a58d54e9e9861d24292914ca6bb4d6b1338c06e3 * soc/arm/mps2/mps2.yaml diff --git a/boards/arm/mps2_an505/generated/.base/include/soc_devices.h b/boards/arm/mps2_an505/generated/.base/include/soc_devices.h index e1ebcaa2..d60c171d 100644 --- a/boards/arm/mps2_an505/generated/.base/include/soc_devices.h +++ b/boards/arm/mps2_an505/generated/.base/include/soc_devices.h @@ -17,7 +17,7 @@ * boards/arm/mps2_an505/board.yaml * e294320434bc265e8bb036ae1c2d2f2fb520d6704fe597f587a7db006ffab05a * drivers/bindings.yaml - * d3c336ac05548e0addd1faac18f3dff70576d8069f11d89e6a761cf5c6132b49 + * c06d1a914adb21d0e314c79b3611ac6859eefeac1957d6914cccfc5531ad6ede * soc/arm/mps2/an505.yaml * d145c50a12402e61748bd8e2a58d54e9e9861d24292914ca6bb4d6b1338c06e3 * soc/arm/mps2/mps2.yaml diff --git a/boards/arm/mps2_an505/generated/.base/linker/regions.ld b/boards/arm/mps2_an505/generated/.base/linker/regions.ld index ace3b72a..4bbbb3bc 100644 --- a/boards/arm/mps2_an505/generated/.base/linker/regions.ld +++ b/boards/arm/mps2_an505/generated/.base/linker/regions.ld @@ -18,7 +18,7 @@ * boards/arm/mps2_an505/board.yaml * e294320434bc265e8bb036ae1c2d2f2fb520d6704fe597f587a7db006ffab05a * drivers/bindings.yaml - * d3c336ac05548e0addd1faac18f3dff70576d8069f11d89e6a761cf5c6132b49 + * c06d1a914adb21d0e314c79b3611ac6859eefeac1957d6914cccfc5531ad6ede * soc/arm/mps2/an505.yaml * d145c50a12402e61748bd8e2a58d54e9e9861d24292914ca6bb4d6b1338c06e3 * soc/arm/mps2/mps2.yaml diff --git a/boards/arm/mps2_an505/generated/.base/src/soc_devices.c b/boards/arm/mps2_an505/generated/.base/src/soc_devices.c index 5ed0dcdd..44946e0d 100644 --- a/boards/arm/mps2_an505/generated/.base/src/soc_devices.c +++ b/boards/arm/mps2_an505/generated/.base/src/soc_devices.c @@ -18,7 +18,7 @@ * boards/arm/mps2_an505/board.yaml * e294320434bc265e8bb036ae1c2d2f2fb520d6704fe597f587a7db006ffab05a * drivers/bindings.yaml - * d3c336ac05548e0addd1faac18f3dff70576d8069f11d89e6a761cf5c6132b49 + * c06d1a914adb21d0e314c79b3611ac6859eefeac1957d6914cccfc5531ad6ede * soc/arm/mps2/an505.yaml * d145c50a12402e61748bd8e2a58d54e9e9861d24292914ca6bb4d6b1338c06e3 * soc/arm/mps2/mps2.yaml diff --git a/boards/arm/mps2_an505/generated/build/CMakeLists.txt b/boards/arm/mps2_an505/generated/build/CMakeLists.txt index 778e0a2a..f92ab376 100644 --- a/boards/arm/mps2_an505/generated/build/CMakeLists.txt +++ b/boards/arm/mps2_an505/generated/build/CMakeLists.txt @@ -11,7 +11,7 @@ # boards/arm/mps2_an505/board.yaml # e294320434bc265e8bb036ae1c2d2f2fb520d6704fe597f587a7db006ffab05a # drivers/bindings.yaml -# d3c336ac05548e0addd1faac18f3dff70576d8069f11d89e6a761cf5c6132b49 +# c06d1a914adb21d0e314c79b3611ac6859eefeac1957d6914cccfc5531ad6ede # soc/arm/mps2/an505.yaml # d145c50a12402e61748bd8e2a58d54e9e9861d24292914ca6bb4d6b1338c06e3 # soc/arm/mps2/mps2.yaml diff --git a/boards/arm/mps2_an505/generated/build/board.cmake b/boards/arm/mps2_an505/generated/build/board.cmake index 0e1c00cc..248890d2 100644 --- a/boards/arm/mps2_an505/generated/build/board.cmake +++ b/boards/arm/mps2_an505/generated/build/board.cmake @@ -11,7 +11,7 @@ # boards/arm/mps2_an505/board.yaml # e294320434bc265e8bb036ae1c2d2f2fb520d6704fe597f587a7db006ffab05a # drivers/bindings.yaml -# d3c336ac05548e0addd1faac18f3dff70576d8069f11d89e6a761cf5c6132b49 +# c06d1a914adb21d0e314c79b3611ac6859eefeac1957d6914cccfc5531ad6ede # soc/arm/mps2/an505.yaml # d145c50a12402e61748bd8e2a58d54e9e9861d24292914ca6bb4d6b1338c06e3 # soc/arm/mps2/mps2.yaml @@ -25,6 +25,8 @@ get_filename_component(EMB_BOARD_GENERATED_DIR "${CMAKE_CURRENT_LIST_DIR}/.." AB set(EMB_BOARD_CONF "${EMB_BOARD_GENERATED_DIR}/config/board.conf") set(EMB_BOARD_HW_JSON "${EMB_BOARD_GENERATED_DIR}/docs/hw.json") set(EMB_BOARD_BUILD_DIR "${CMAKE_CURRENT_LIST_DIR}") # build/CMakeLists.txt +set(EMB_BOARD_SRC_DIR "${EMB_BOARD_GENERATED_DIR}/src") # its pin table and boot block +set(EMB_BOARD_LINKER_DIR "${EMB_BOARD_GENERATED_DIR}/linker") # the SoC family's board support and drivers build this board (build/CMakeLists.txt) set(EMB_SOC_DIR "${EMB_BASE}/soc/arm/mps2") set(EMB_BOARD_INCLUDE_DIRS "${EMB_BOARD_GENERATED_DIR}/include" "${EMB_SOC_DIR}/include") @@ -44,7 +46,7 @@ set(EMB_BOARD_DRIVER_INCLUDE_DIRS set(EMB_BOARD_HW_INPUTS "arch/cortex_m/arch.yaml=c5c8e451c09717dee1713d07f8311b6d507e3b4c66c42d93e0ce11da6ec76d6d" "boards/arm/mps2_an505/board.yaml=e294320434bc265e8bb036ae1c2d2f2fb520d6704fe597f587a7db006ffab05a" - "drivers/bindings.yaml=d3c336ac05548e0addd1faac18f3dff70576d8069f11d89e6a761cf5c6132b49" + "drivers/bindings.yaml=c06d1a914adb21d0e314c79b3611ac6859eefeac1957d6914cccfc5531ad6ede" "soc/arm/mps2/an505.yaml=d145c50a12402e61748bd8e2a58d54e9e9861d24292914ca6bb4d6b1338c06e3" "soc/arm/mps2/mps2.yaml=7bc066c165dbd50db2c6c3e35cf8a3f12ae360b7ad578cfe06983b3f807d1d71" ) diff --git a/boards/arm/mps2_an505/generated/config/board.conf b/boards/arm/mps2_an505/generated/config/board.conf index 6960b185..6f55594c 100644 --- a/boards/arm/mps2_an505/generated/config/board.conf +++ b/boards/arm/mps2_an505/generated/config/board.conf @@ -11,7 +11,7 @@ # boards/arm/mps2_an505/board.yaml # e294320434bc265e8bb036ae1c2d2f2fb520d6704fe597f587a7db006ffab05a # drivers/bindings.yaml -# d3c336ac05548e0addd1faac18f3dff70576d8069f11d89e6a761cf5c6132b49 +# c06d1a914adb21d0e314c79b3611ac6859eefeac1957d6914cccfc5531ad6ede # soc/arm/mps2/an505.yaml # d145c50a12402e61748bd8e2a58d54e9e9861d24292914ca6bb4d6b1338c06e3 # soc/arm/mps2/mps2.yaml diff --git a/boards/arm/mps2_an505/generated/docs/board.md b/boards/arm/mps2_an505/generated/docs/board.md index a09a5f80..51691275 100644 --- a/boards/arm/mps2_an505/generated/docs/board.md +++ b/boards/arm/mps2_an505/generated/docs/board.md @@ -53,6 +53,6 @@ Generated by emb-hwgen 0.1.0, schema v0, from: |---|---| | `arch/cortex_m/arch.yaml` | `c5c8e451c09717dee1713d07f8311b6d507e3b4c66c42d93e0ce11da6ec76d6d` | | `boards/arm/mps2_an505/board.yaml` | `e294320434bc265e8bb036ae1c2d2f2fb520d6704fe597f587a7db006ffab05a` | -| `drivers/bindings.yaml` | `d3c336ac05548e0addd1faac18f3dff70576d8069f11d89e6a761cf5c6132b49` | +| `drivers/bindings.yaml` | `c06d1a914adb21d0e314c79b3611ac6859eefeac1957d6914cccfc5531ad6ede` | | `soc/arm/mps2/an505.yaml` | `d145c50a12402e61748bd8e2a58d54e9e9861d24292914ca6bb4d6b1338c06e3` | | `soc/arm/mps2/mps2.yaml` | `7bc066c165dbd50db2c6c3e35cf8a3f12ae360b7ad578cfe06983b3f807d1d71` | diff --git a/boards/arm/mps2_an505/generated/docs/build_report.md b/boards/arm/mps2_an505/generated/docs/build_report.md index 6563999c..09b9b0ba 100644 --- a/boards/arm/mps2_an505/generated/docs/build_report.md +++ b/boards/arm/mps2_an505/generated/docs/build_report.md @@ -24,6 +24,6 @@ Generated by emb-hwgen 0.1.0, schema v0, from: |---|---| | `arch/cortex_m/arch.yaml` | `c5c8e451c09717dee1713d07f8311b6d507e3b4c66c42d93e0ce11da6ec76d6d` | | `boards/arm/mps2_an505/board.yaml` | `e294320434bc265e8bb036ae1c2d2f2fb520d6704fe597f587a7db006ffab05a` | -| `drivers/bindings.yaml` | `d3c336ac05548e0addd1faac18f3dff70576d8069f11d89e6a761cf5c6132b49` | +| `drivers/bindings.yaml` | `c06d1a914adb21d0e314c79b3611ac6859eefeac1957d6914cccfc5531ad6ede` | | `soc/arm/mps2/an505.yaml` | `d145c50a12402e61748bd8e2a58d54e9e9861d24292914ca6bb4d6b1338c06e3` | | `soc/arm/mps2/mps2.yaml` | `7bc066c165dbd50db2c6c3e35cf8a3f12ae360b7ad578cfe06983b3f807d1d71` | diff --git a/boards/arm/mps2_an505/generated/docs/hw.json b/boards/arm/mps2_an505/generated/docs/hw.json index 106d5680..08cd800b 100644 --- a/boards/arm/mps2_an505/generated/docs/hw.json +++ b/boards/arm/mps2_an505/generated/docs/hw.json @@ -58,8 +58,10 @@ "clock": { "ahb_div": 1, "bus_hz": {}, + "bus_timer_hz": {}, "bypass": false, "cpu_hz": 20000000, + "fixed_plls": {}, "hclk_hz": 20000000, "pll": null, "source": "sysclk", @@ -166,7 +168,7 @@ }, { "path": "drivers/bindings.yaml", - "sha256": "d3c336ac05548e0addd1faac18f3dff70576d8069f11d89e6a761cf5c6132b49" + "sha256": "c06d1a914adb21d0e314c79b3611ac6859eefeac1957d6914cccfc5531ad6ede" }, { "path": "soc/arm/mps2/an505.yaml", diff --git a/boards/arm/mps2_an505/generated/include/hw_config.h b/boards/arm/mps2_an505/generated/include/hw_config.h index ee86f631..6c36eeb0 100644 --- a/boards/arm/mps2_an505/generated/include/hw_config.h +++ b/boards/arm/mps2_an505/generated/include/hw_config.h @@ -17,7 +17,7 @@ * boards/arm/mps2_an505/board.yaml * e294320434bc265e8bb036ae1c2d2f2fb520d6704fe597f587a7db006ffab05a * drivers/bindings.yaml - * d3c336ac05548e0addd1faac18f3dff70576d8069f11d89e6a761cf5c6132b49 + * c06d1a914adb21d0e314c79b3611ac6859eefeac1957d6914cccfc5531ad6ede * soc/arm/mps2/an505.yaml * d145c50a12402e61748bd8e2a58d54e9e9861d24292914ca6bb4d6b1338c06e3 * soc/arm/mps2/mps2.yaml diff --git a/boards/arm/mps2_an505/generated/include/soc_devices.h b/boards/arm/mps2_an505/generated/include/soc_devices.h index e1ebcaa2..d60c171d 100644 --- a/boards/arm/mps2_an505/generated/include/soc_devices.h +++ b/boards/arm/mps2_an505/generated/include/soc_devices.h @@ -17,7 +17,7 @@ * boards/arm/mps2_an505/board.yaml * e294320434bc265e8bb036ae1c2d2f2fb520d6704fe597f587a7db006ffab05a * drivers/bindings.yaml - * d3c336ac05548e0addd1faac18f3dff70576d8069f11d89e6a761cf5c6132b49 + * c06d1a914adb21d0e314c79b3611ac6859eefeac1957d6914cccfc5531ad6ede * soc/arm/mps2/an505.yaml * d145c50a12402e61748bd8e2a58d54e9e9861d24292914ca6bb4d6b1338c06e3 * soc/arm/mps2/mps2.yaml diff --git a/boards/arm/mps2_an505/generated/linker/regions.ld b/boards/arm/mps2_an505/generated/linker/regions.ld index ace3b72a..4bbbb3bc 100644 --- a/boards/arm/mps2_an505/generated/linker/regions.ld +++ b/boards/arm/mps2_an505/generated/linker/regions.ld @@ -18,7 +18,7 @@ * boards/arm/mps2_an505/board.yaml * e294320434bc265e8bb036ae1c2d2f2fb520d6704fe597f587a7db006ffab05a * drivers/bindings.yaml - * d3c336ac05548e0addd1faac18f3dff70576d8069f11d89e6a761cf5c6132b49 + * c06d1a914adb21d0e314c79b3611ac6859eefeac1957d6914cccfc5531ad6ede * soc/arm/mps2/an505.yaml * d145c50a12402e61748bd8e2a58d54e9e9861d24292914ca6bb4d6b1338c06e3 * soc/arm/mps2/mps2.yaml diff --git a/boards/arm/mps2_an505/generated/src/soc_devices.c b/boards/arm/mps2_an505/generated/src/soc_devices.c index 5ed0dcdd..44946e0d 100644 --- a/boards/arm/mps2_an505/generated/src/soc_devices.c +++ b/boards/arm/mps2_an505/generated/src/soc_devices.c @@ -18,7 +18,7 @@ * boards/arm/mps2_an505/board.yaml * e294320434bc265e8bb036ae1c2d2f2fb520d6704fe597f587a7db006ffab05a * drivers/bindings.yaml - * d3c336ac05548e0addd1faac18f3dff70576d8069f11d89e6a761cf5c6132b49 + * c06d1a914adb21d0e314c79b3611ac6859eefeac1957d6914cccfc5531ad6ede * soc/arm/mps2/an505.yaml * d145c50a12402e61748bd8e2a58d54e9e9861d24292914ca6bb4d6b1338c06e3 * soc/arm/mps2/mps2.yaml diff --git a/boards/bbc/microbit/generated/.base/build/board.cmake b/boards/bbc/microbit/generated/.base/build/board.cmake index ff08128c..e4979808 100644 --- a/boards/bbc/microbit/generated/.base/build/board.cmake +++ b/boards/bbc/microbit/generated/.base/build/board.cmake @@ -23,6 +23,8 @@ get_filename_component(EMB_BOARD_GENERATED_DIR "${CMAKE_CURRENT_LIST_DIR}/.." AB set(EMB_BOARD_CONF "${EMB_BOARD_GENERATED_DIR}/config/board.conf") set(EMB_BOARD_HW_JSON "${EMB_BOARD_GENERATED_DIR}/docs/hw.json") set(EMB_BOARD_BUILD_DIR "${CMAKE_CURRENT_LIST_DIR}") # build/CMakeLists.txt +set(EMB_BOARD_SRC_DIR "${EMB_BOARD_GENERATED_DIR}/src") # its pin table and boot block +set(EMB_BOARD_LINKER_DIR "${EMB_BOARD_GENERATED_DIR}/linker") # the SoC family's board support and drivers build this board (build/CMakeLists.txt) set(EMB_SOC_DIR "${EMB_BASE}/soc/nordic/nrf51") set(EMB_BOARD_INCLUDE_DIRS "${EMB_BOARD_GENERATED_DIR}/include" "${EMB_SOC_DIR}/include") diff --git a/boards/bbc/microbit/generated/.base/docs/hw.json b/boards/bbc/microbit/generated/.base/docs/hw.json index 9af4c9a3..784bb488 100644 --- a/boards/bbc/microbit/generated/.base/docs/hw.json +++ b/boards/bbc/microbit/generated/.base/docs/hw.json @@ -41,8 +41,10 @@ "clock": { "ahb_div": 1, "bus_hz": {}, + "bus_timer_hz": {}, "bypass": false, "cpu_hz": 16000000, + "fixed_plls": {}, "hclk_hz": 16000000, "pll": null, "source": "hfclk", diff --git a/boards/bbc/microbit/generated/build/board.cmake b/boards/bbc/microbit/generated/build/board.cmake index ff08128c..e4979808 100644 --- a/boards/bbc/microbit/generated/build/board.cmake +++ b/boards/bbc/microbit/generated/build/board.cmake @@ -23,6 +23,8 @@ get_filename_component(EMB_BOARD_GENERATED_DIR "${CMAKE_CURRENT_LIST_DIR}/.." AB set(EMB_BOARD_CONF "${EMB_BOARD_GENERATED_DIR}/config/board.conf") set(EMB_BOARD_HW_JSON "${EMB_BOARD_GENERATED_DIR}/docs/hw.json") set(EMB_BOARD_BUILD_DIR "${CMAKE_CURRENT_LIST_DIR}") # build/CMakeLists.txt +set(EMB_BOARD_SRC_DIR "${EMB_BOARD_GENERATED_DIR}/src") # its pin table and boot block +set(EMB_BOARD_LINKER_DIR "${EMB_BOARD_GENERATED_DIR}/linker") # the SoC family's board support and drivers build this board (build/CMakeLists.txt) set(EMB_SOC_DIR "${EMB_BASE}/soc/nordic/nrf51") set(EMB_BOARD_INCLUDE_DIRS "${EMB_BOARD_GENERATED_DIR}/include" "${EMB_SOC_DIR}/include") diff --git a/boards/bbc/microbit/generated/docs/hw.json b/boards/bbc/microbit/generated/docs/hw.json index 9af4c9a3..784bb488 100644 --- a/boards/bbc/microbit/generated/docs/hw.json +++ b/boards/bbc/microbit/generated/docs/hw.json @@ -41,8 +41,10 @@ "clock": { "ahb_div": 1, "bus_hz": {}, + "bus_timer_hz": {}, "bypass": false, "cpu_hz": 16000000, + "fixed_plls": {}, "hclk_hz": 16000000, "pll": null, "source": "hfclk", diff --git a/boards/qemu/riscv32_virt/generated/.base/build/board.cmake b/boards/qemu/riscv32_virt/generated/.base/build/board.cmake index cb89f93f..1ec27121 100644 --- a/boards/qemu/riscv32_virt/generated/.base/build/board.cmake +++ b/boards/qemu/riscv32_virt/generated/.base/build/board.cmake @@ -21,6 +21,8 @@ get_filename_component(EMB_BOARD_GENERATED_DIR "${CMAKE_CURRENT_LIST_DIR}/.." AB set(EMB_BOARD_CONF "${EMB_BOARD_GENERATED_DIR}/config/board.conf") set(EMB_BOARD_HW_JSON "${EMB_BOARD_GENERATED_DIR}/docs/hw.json") set(EMB_BOARD_BUILD_DIR "${CMAKE_CURRENT_LIST_DIR}") # build/CMakeLists.txt +set(EMB_BOARD_SRC_DIR "${EMB_BOARD_GENERATED_DIR}/src") # its pin table and boot block +set(EMB_BOARD_LINKER_DIR "${EMB_BOARD_GENERATED_DIR}/linker") # the SoC family's board support and drivers build this board (build/CMakeLists.txt) set(EMB_SOC_DIR "${EMB_BASE}/soc/qemu/virt") set(EMB_BOARD_INCLUDE_DIRS "${EMB_BOARD_GENERATED_DIR}/include" "${EMB_SOC_DIR}/include") diff --git a/boards/qemu/riscv32_virt/generated/.base/docs/hw.json b/boards/qemu/riscv32_virt/generated/.base/docs/hw.json index 013d1292..3b468081 100644 --- a/boards/qemu/riscv32_virt/generated/.base/docs/hw.json +++ b/boards/qemu/riscv32_virt/generated/.base/docs/hw.json @@ -41,8 +41,10 @@ "clock": { "ahb_div": 1, "bus_hz": {}, + "bus_timer_hz": {}, "bypass": false, "cpu_hz": 10000000, + "fixed_plls": {}, "hclk_hz": 10000000, "pll": null, "source": "timebase", diff --git a/boards/qemu/riscv32_virt/generated/build/board.cmake b/boards/qemu/riscv32_virt/generated/build/board.cmake index cb89f93f..1ec27121 100644 --- a/boards/qemu/riscv32_virt/generated/build/board.cmake +++ b/boards/qemu/riscv32_virt/generated/build/board.cmake @@ -21,6 +21,8 @@ get_filename_component(EMB_BOARD_GENERATED_DIR "${CMAKE_CURRENT_LIST_DIR}/.." AB set(EMB_BOARD_CONF "${EMB_BOARD_GENERATED_DIR}/config/board.conf") set(EMB_BOARD_HW_JSON "${EMB_BOARD_GENERATED_DIR}/docs/hw.json") set(EMB_BOARD_BUILD_DIR "${CMAKE_CURRENT_LIST_DIR}") # build/CMakeLists.txt +set(EMB_BOARD_SRC_DIR "${EMB_BOARD_GENERATED_DIR}/src") # its pin table and boot block +set(EMB_BOARD_LINKER_DIR "${EMB_BOARD_GENERATED_DIR}/linker") # the SoC family's board support and drivers build this board (build/CMakeLists.txt) set(EMB_SOC_DIR "${EMB_BASE}/soc/qemu/virt") set(EMB_BOARD_INCLUDE_DIRS "${EMB_BOARD_GENERATED_DIR}/include" "${EMB_SOC_DIR}/include") diff --git a/boards/qemu/riscv32_virt/generated/docs/hw.json b/boards/qemu/riscv32_virt/generated/docs/hw.json index 013d1292..3b468081 100644 --- a/boards/qemu/riscv32_virt/generated/docs/hw.json +++ b/boards/qemu/riscv32_virt/generated/docs/hw.json @@ -41,8 +41,10 @@ "clock": { "ahb_div": 1, "bus_hz": {}, + "bus_timer_hz": {}, "bypass": false, "cpu_hz": 10000000, + "fixed_plls": {}, "hclk_hz": 10000000, "pll": null, "source": "timebase", diff --git a/boards/rpi/pico2_w/board.yaml b/boards/rpi/pico2_w/board.yaml index 10d9c3f9..12401a65 100644 --- a/boards/rpi/pico2_w/board.yaml +++ b/boards/rpi/pico2_w/board.yaml @@ -33,6 +33,9 @@ pins: spi1: { sck: GPIO10.f1, mosi: GPIO11.f1, miso: GPIO12.f1 } # pins 14, 15 and 16 i2c0: { sda: GPIO8.f3, scl: GPIO9.f3 } # pins 11 and 12 i2c1: { sda: GPIO6.f3, scl: GPIO7.f3 } # pins 9 and 10 + pwm7: { a: GPIO14.f4 } # pin 19: PWM out + pwm0: { b: GPIO17.f4 } # pin 22: PWM capture + adc: { in0: GPIO26, in1: GPIO27 } # pins 31 and 32 console: { device: uart0, baud: 115200 } # the board's devices (SPEC-016), initialized with the EARLY devices; the RP2350's blocks have # no clock gates in the description, so the order is stated @@ -49,6 +52,10 @@ devices: - { name: i2c0, deps: [io_bank0], doc: "I2C0 on GPIO8 (pin 11, SDA) and GPIO9 (pin 12, SCL); the HIL suite wires it to I2C1" } - { name: i2c1, deps: [io_bank0], doc: "I2C1 on GPIO6 (pin 9, SDA) and GPIO7 (pin 10, SCL), the HIL suite's target for I2C0" } - { name: uart1, baud: 115200, deps: [io_bank0], dma: [tx], doc: "a spare UART, its writes by DMA; the HIL suite's loopback wires GPIO4 (pin 6) to GPIO5 (pin 7)" } + - { name: timer1, doc: "TIMER1, 64 bits at 1 MHz: the counter class's (A129); TIMER0 is left for M4.4's tickless time" } + - { name: pwm7, deps: [io_bank0], doc: "slice 7, PWM out on A, GPIO14 (pin 19); the HIL suite wires it to pin 22" } + - { name: pwm0, deps: [io_bank0], doc: "slice 0, PWM capture on B, GPIO17 (pin 22)" } + - { name: adc, deps: [clocks, io_bank0], dma: [rx], doc: "the ADC on clk_adc, 48 MHz from PLL_USB: GPIO26 (pin 31, input 0) and GPIO27 (pin 32, input 1); the HIL suite wires pin 31 to 3V3 OUT and pin 32 to AGND" } # the RP2350's 4 MiB QSPI flash (W25Q32RV), behind the XIP window flash_partitions: - { name: app, base: 0x10000000, size: 4032K } # the first 4 MiB less 64 KiB diff --git a/boards/rpi/pico2_w/generated/.base/build/CMakeLists.txt b/boards/rpi/pico2_w/generated/.base/build/CMakeLists.txt index 1f978bd1..96bb1ab4 100644 --- a/boards/rpi/pico2_w/generated/.base/build/CMakeLists.txt +++ b/boards/rpi/pico2_w/generated/.base/build/CMakeLists.txt @@ -9,13 +9,13 @@ # arch/cortex_m/arch.yaml # c5c8e451c09717dee1713d07f8311b6d507e3b4c66c42d93e0ce11da6ec76d6d # boards/rpi/pico2_w/board.yaml -# dad0ef7259e41ef3bd8fa07ea1c1f36040254a443deaf30d963b4fb14b5354a0 +# 345279a53c444bc45e7fcc1a0cb5ab47b32a7699534f5484ea80d73f7a0bdf6d # drivers/bindings.yaml -# d3c336ac05548e0addd1faac18f3dff70576d8069f11d89e6a761cf5c6132b49 +# c06d1a914adb21d0e314c79b3611ac6859eefeac1957d6914cccfc5531ad6ede # soc/rpi/rp2350/rp2350.yaml -# 9e60e99ecac8782bccd69e3bd69014af1d8891d6b6fbd822acff5bd9a526d8cd +# 80773a9c9cfb1c62cd322e397111a11d7f48fce3c0febc76bf7d5571018977a5 # soc/rpi/rp2350/rp2350a.yaml -# 045cef7794c3b6c6d2ff48ba294c6308d00fe13bc65e346f2ba2ccde1cea24ff +# 22395e35ed229020b5c9c7586af50cfaa07960a09905776eb4713ff28051eb3c # The board has no C of its own: its SoC family's board support builds emb_board from # ../src/board_pins.c and ../include/hw_config.h, and links ../linker/regions.ld. add_subdirectory("${EMB_SOC_DIR}" soc) diff --git a/boards/rpi/pico2_w/generated/.base/build/board.cmake b/boards/rpi/pico2_w/generated/.base/build/board.cmake index 129da093..6487b6a6 100644 --- a/boards/rpi/pico2_w/generated/.base/build/board.cmake +++ b/boards/rpi/pico2_w/generated/.base/build/board.cmake @@ -9,13 +9,13 @@ # arch/cortex_m/arch.yaml # c5c8e451c09717dee1713d07f8311b6d507e3b4c66c42d93e0ce11da6ec76d6d # boards/rpi/pico2_w/board.yaml -# dad0ef7259e41ef3bd8fa07ea1c1f36040254a443deaf30d963b4fb14b5354a0 +# 345279a53c444bc45e7fcc1a0cb5ab47b32a7699534f5484ea80d73f7a0bdf6d # drivers/bindings.yaml -# d3c336ac05548e0addd1faac18f3dff70576d8069f11d89e6a761cf5c6132b49 +# c06d1a914adb21d0e314c79b3611ac6859eefeac1957d6914cccfc5531ad6ede # soc/rpi/rp2350/rp2350.yaml -# 9e60e99ecac8782bccd69e3bd69014af1d8891d6b6fbd822acff5bd9a526d8cd +# 80773a9c9cfb1c62cd322e397111a11d7f48fce3c0febc76bf7d5571018977a5 # soc/rpi/rp2350/rp2350a.yaml -# 045cef7794c3b6c6d2ff48ba294c6308d00fe13bc65e346f2ba2ccde1cea24ff +# 22395e35ed229020b5c9c7586af50cfaa07960a09905776eb4713ff28051eb3c # pico2_w: RP2350A, cortex-m33f at 150 MHz. set(EMB_BOARD_ARCH cortex_m) set(EMB_BOARD_VARIANT armv8m-main) @@ -25,6 +25,8 @@ get_filename_component(EMB_BOARD_GENERATED_DIR "${CMAKE_CURRENT_LIST_DIR}/.." AB set(EMB_BOARD_CONF "${EMB_BOARD_GENERATED_DIR}/config/board.conf") set(EMB_BOARD_HW_JSON "${EMB_BOARD_GENERATED_DIR}/docs/hw.json") set(EMB_BOARD_BUILD_DIR "${CMAKE_CURRENT_LIST_DIR}") # build/CMakeLists.txt +set(EMB_BOARD_SRC_DIR "${EMB_BOARD_GENERATED_DIR}/src") # its pin table and boot block +set(EMB_BOARD_LINKER_DIR "${EMB_BOARD_GENERATED_DIR}/linker") # the SoC family's board support and drivers build this board (build/CMakeLists.txt) set(EMB_SOC_DIR "${EMB_BASE}/soc/rpi/rp2350") set(EMB_BOARD_INCLUDE_DIRS "${EMB_BOARD_GENERATED_DIR}/include" "${EMB_SOC_DIR}/include") @@ -32,6 +34,7 @@ set(EMB_BOARD_RESETS_IN hil) # restart the image with RAM kept (test_crash_reset set(EMB_BOARD_UART1_DMA tx) set(EMB_BOARD_SPI1_DMA rx tx) set(EMB_BOARD_SPI1_CS_COUNT 1) +set(EMB_BOARD_ADC_DMA rx) set(EMB_BOARD_FLASH_IMAGE uf2) # what the SoC's boot ROM loads (A79) set(EMB_BOARD_UF2_FAMILY 0xE48BFF59) # the board's devices (soc_devices.c) and the drivers they use, and only those (SPEC-016 §8) @@ -47,6 +50,9 @@ set(EMB_BOARD_DRIVER_SOURCES "${EMB_BASE}/drivers/rpi/rp2350_trng.c" "${EMB_BASE}/drivers/arm/pl022.c" "${EMB_BASE}/drivers/snps/dw_i2c.c" + "${EMB_BASE}/drivers/rpi/rp2350_timer.c" + "${EMB_BASE}/drivers/rpi/rp2350_pwm.c" + "${EMB_BASE}/drivers/rpi/rp2350_adc.c" ) set(EMB_BOARD_DRIVER_INCLUDE_DIRS "${EMB_BASE}/drivers/rpi/include" @@ -56,8 +62,8 @@ set(EMB_BOARD_DRIVER_INCLUDE_DIRS # the inputs this directory was generated from, for the configure-time staleness check set(EMB_BOARD_HW_INPUTS "arch/cortex_m/arch.yaml=c5c8e451c09717dee1713d07f8311b6d507e3b4c66c42d93e0ce11da6ec76d6d" - "boards/rpi/pico2_w/board.yaml=dad0ef7259e41ef3bd8fa07ea1c1f36040254a443deaf30d963b4fb14b5354a0" - "drivers/bindings.yaml=d3c336ac05548e0addd1faac18f3dff70576d8069f11d89e6a761cf5c6132b49" - "soc/rpi/rp2350/rp2350.yaml=9e60e99ecac8782bccd69e3bd69014af1d8891d6b6fbd822acff5bd9a526d8cd" - "soc/rpi/rp2350/rp2350a.yaml=045cef7794c3b6c6d2ff48ba294c6308d00fe13bc65e346f2ba2ccde1cea24ff" + "boards/rpi/pico2_w/board.yaml=345279a53c444bc45e7fcc1a0cb5ab47b32a7699534f5484ea80d73f7a0bdf6d" + "drivers/bindings.yaml=c06d1a914adb21d0e314c79b3611ac6859eefeac1957d6914cccfc5531ad6ede" + "soc/rpi/rp2350/rp2350.yaml=80773a9c9cfb1c62cd322e397111a11d7f48fce3c0febc76bf7d5571018977a5" + "soc/rpi/rp2350/rp2350a.yaml=22395e35ed229020b5c9c7586af50cfaa07960a09905776eb4713ff28051eb3c" ) diff --git a/boards/rpi/pico2_w/generated/.base/config/board.conf b/boards/rpi/pico2_w/generated/.base/config/board.conf index c643beda..d66490f8 100644 --- a/boards/rpi/pico2_w/generated/.base/config/board.conf +++ b/boards/rpi/pico2_w/generated/.base/config/board.conf @@ -9,13 +9,13 @@ # arch/cortex_m/arch.yaml # c5c8e451c09717dee1713d07f8311b6d507e3b4c66c42d93e0ce11da6ec76d6d # boards/rpi/pico2_w/board.yaml -# dad0ef7259e41ef3bd8fa07ea1c1f36040254a443deaf30d963b4fb14b5354a0 +# 345279a53c444bc45e7fcc1a0cb5ab47b32a7699534f5484ea80d73f7a0bdf6d # drivers/bindings.yaml -# d3c336ac05548e0addd1faac18f3dff70576d8069f11d89e6a761cf5c6132b49 +# c06d1a914adb21d0e314c79b3611ac6859eefeac1957d6914cccfc5531ad6ede # soc/rpi/rp2350/rp2350.yaml -# 9e60e99ecac8782bccd69e3bd69014af1d8891d6b6fbd822acff5bd9a526d8cd +# 80773a9c9cfb1c62cd322e397111a11d7f48fce3c0febc76bf7d5571018977a5 # soc/rpi/rp2350/rp2350a.yaml -# 045cef7794c3b6c6d2ff48ba294c6308d00fe13bc65e346f2ba2ccde1cea24ff +# 22395e35ed229020b5c9c7586af50cfaa07960a09905776eb4713ff28051eb3c # Board defaults for pico2_w. Applied before the profile fragment. CONFIG_EMB_CM_CPU_HZ=150000000 CONFIG_EMB_CM_IRQ_COUNT=52 diff --git a/boards/rpi/pico2_w/generated/.base/docs/board.md b/boards/rpi/pico2_w/generated/.base/docs/board.md index 1af427ec..e50ddda6 100644 --- a/boards/rpi/pico2_w/generated/.base/docs/board.md +++ b/boards/rpi/pico2_w/generated/.base/docs/board.md @@ -41,6 +41,10 @@ The console on UART0 at 115200 baud on GPIO0 (TX, pin 1) and GPIO1 (RX, pin 2). | GPIO11 | `pins.spi1.mosi` | af1 (spi1_mosi) | | GPIO12 | `pins.spi1.miso` | af1 (spi1_miso) | | GPIO13 | `devices.spi1.cs[0]` | output | +| GPIO14 | `pins.pwm7.a` | af4 (pwm7_a) | +| GPIO17 | `pins.pwm0.b` | af4 (pwm0_b) | +| GPIO26 | `pins.adc.in0` | analog | +| GPIO27 | `pins.adc.in1` | analog | ## Devices @@ -60,11 +64,25 @@ In initialization order (SPEC-016 §4). | spi1 | `arm,pl022` | spi | KERNEL | io_bank0, dma | | i2c0 | `snps,designware-i2c` | i2c | KERNEL | io_bank0 | | i2c1 | `snps,designware-i2c` | i2c | KERNEL | io_bank0 | +| timer1 | `rpi,rp2350-timer` | counter | KERNEL | - | +| pwm7 | `rpi,rp2350-pwm` | pwm | KERNEL | io_bank0 | +| pwm0 | `rpi,rp2350-pwm` | pwm | KERNEL | io_bank0 | +| adc | `rpi,rp2350-adc` | adc | KERNEL | clocks, io_bank0, dma | ## Interrupt lines | Line | Owner | |---|---| +| 0 | timer0.alarm0 | +| 1 | timer0.alarm1 | +| 2 | timer0.alarm2 | +| 3 | timer0.alarm3 | +| 4 | timer1.alarm0 | +| 5 | timer1.alarm1 | +| 6 | timer1.alarm2 | +| 7 | timer1.alarm3 | +| 8 | pwm.wrap0 | +| 9 | pwm.wrap1 | | 10 | dma.irq0 | | 11 | dma.irq1 | | 12 | dma.irq2 | @@ -75,6 +93,7 @@ In initialization order (SPEC-016 §4). | 32 | spi1.global | | 33 | uart0.global | | 34 | uart1.global | +| 35 | adc.fifo | | 36 | i2c0.global | | 37 | i2c1.global | | 39 | trng.irq | @@ -89,7 +108,7 @@ Generated by emb-hwgen 0.1.0, schema v0, from: | Input | SHA-256 | |---|---| | `arch/cortex_m/arch.yaml` | `c5c8e451c09717dee1713d07f8311b6d507e3b4c66c42d93e0ce11da6ec76d6d` | -| `boards/rpi/pico2_w/board.yaml` | `dad0ef7259e41ef3bd8fa07ea1c1f36040254a443deaf30d963b4fb14b5354a0` | -| `drivers/bindings.yaml` | `d3c336ac05548e0addd1faac18f3dff70576d8069f11d89e6a761cf5c6132b49` | -| `soc/rpi/rp2350/rp2350.yaml` | `9e60e99ecac8782bccd69e3bd69014af1d8891d6b6fbd822acff5bd9a526d8cd` | -| `soc/rpi/rp2350/rp2350a.yaml` | `045cef7794c3b6c6d2ff48ba294c6308d00fe13bc65e346f2ba2ccde1cea24ff` | +| `boards/rpi/pico2_w/board.yaml` | `345279a53c444bc45e7fcc1a0cb5ab47b32a7699534f5484ea80d73f7a0bdf6d` | +| `drivers/bindings.yaml` | `c06d1a914adb21d0e314c79b3611ac6859eefeac1957d6914cccfc5531ad6ede` | +| `soc/rpi/rp2350/rp2350.yaml` | `80773a9c9cfb1c62cd322e397111a11d7f48fce3c0febc76bf7d5571018977a5` | +| `soc/rpi/rp2350/rp2350a.yaml` | `22395e35ed229020b5c9c7586af50cfaa07960a09905776eb4713ff28051eb3c` | diff --git a/boards/rpi/pico2_w/generated/.base/docs/build_report.md b/boards/rpi/pico2_w/generated/.base/docs/build_report.md index 0844f0ba..bddb1d98 100644 --- a/boards/rpi/pico2_w/generated/.base/docs/build_report.md +++ b/boards/rpi/pico2_w/generated/.base/docs/build_report.md @@ -4,6 +4,8 @@ xosc 12 MHz / M 1 = 12 MHz VCO input, x N 125 = 1500 MHz, / P 10 = 150 MHz. Given by the board, checked. +pll_usb: xosc 12 MHz / M 1 x N 64 = 768 MHz VCO, / 4 / 4 = 48 MHz. Solved; started by the drivers that use it. + | Bus | Frequency | Limit | |---|---|---| | sys | 150 MHz | 150 MHz | @@ -27,7 +29,7 @@ Generated by emb-hwgen 0.1.0, schema v0, from: | Input | SHA-256 | |---|---| | `arch/cortex_m/arch.yaml` | `c5c8e451c09717dee1713d07f8311b6d507e3b4c66c42d93e0ce11da6ec76d6d` | -| `boards/rpi/pico2_w/board.yaml` | `dad0ef7259e41ef3bd8fa07ea1c1f36040254a443deaf30d963b4fb14b5354a0` | -| `drivers/bindings.yaml` | `d3c336ac05548e0addd1faac18f3dff70576d8069f11d89e6a761cf5c6132b49` | -| `soc/rpi/rp2350/rp2350.yaml` | `9e60e99ecac8782bccd69e3bd69014af1d8891d6b6fbd822acff5bd9a526d8cd` | -| `soc/rpi/rp2350/rp2350a.yaml` | `045cef7794c3b6c6d2ff48ba294c6308d00fe13bc65e346f2ba2ccde1cea24ff` | +| `boards/rpi/pico2_w/board.yaml` | `345279a53c444bc45e7fcc1a0cb5ab47b32a7699534f5484ea80d73f7a0bdf6d` | +| `drivers/bindings.yaml` | `c06d1a914adb21d0e314c79b3611ac6859eefeac1957d6914cccfc5531ad6ede` | +| `soc/rpi/rp2350/rp2350.yaml` | `80773a9c9cfb1c62cd322e397111a11d7f48fce3c0febc76bf7d5571018977a5` | +| `soc/rpi/rp2350/rp2350a.yaml` | `22395e35ed229020b5c9c7586af50cfaa07960a09905776eb4713ff28051eb3c` | diff --git a/boards/rpi/pico2_w/generated/.base/docs/hw.json b/boards/rpi/pico2_w/generated/.base/docs/hw.json index 18720772..ca406a91 100644 --- a/boards/rpi/pico2_w/generated/.base/docs/hw.json +++ b/boards/rpi/pico2_w/generated/.base/docs/hw.json @@ -103,6 +103,35 @@ ], "doc": "a spare UART, its writes by DMA; the HIL suite's loopback wires GPIO4 (pin 6) to GPIO5 (pin 7)", "name": "uart1" + }, + { + "doc": "TIMER1, 64 bits at 1 MHz: the counter class's (A129); TIMER0 is left for M4.4's tickless time", + "name": "timer1" + }, + { + "deps": [ + "io_bank0" + ], + "doc": "slice 7, PWM out on A, GPIO14 (pin 19); the HIL suite wires it to pin 22", + "name": "pwm7" + }, + { + "deps": [ + "io_bank0" + ], + "doc": "slice 0, PWM capture on B, GPIO17 (pin 22)", + "name": "pwm0" + }, + { + "deps": [ + "clocks", + "io_bank0" + ], + "dma": [ + "rx" + ], + "doc": "the ADC on clk_adc, 48 MHz from PLL_USB: GPIO26 (pin 31, input 0) and GPIO27 (pin 32, input 1); the HIL suite wires pin 31 to 3V3 OUT and pin 32 to AGND", + "name": "adc" } ], "doc": "The console on UART0 at 115200 baud on GPIO0 (TX, pin 1) and GPIO1 (RX, pin 2). The CPU runs at 150 MHz from PLL_SYS (the 12 MHz crystal x 125 / 5 / 2, pico-sdk's factors), and clk_peri, the UARTs' clock, follows clk_sys. The user LED is on the CYW43439 wireless chip, which has no driver yet, so the board has no LED. Images are UF2 files, copied to the boot ROM's USB drive (hold BOOTSEL while plugging in), or loaded by picotool while the board is in BOOTSEL; a test image built for the board (EMB_TEST_EMULATOR=hil) reboots into BOOTSEL when it ends, so tools/hil/run_hil.py loads the next one without the button.", @@ -127,6 +156,10 @@ } }, "pins": { + "adc": { + "in0": "GPIO26", + "in1": "GPIO27" + }, "i2c0": { "scl": "GPIO9.f3", "sda": "GPIO8.f3" @@ -135,6 +168,12 @@ "scl": "GPIO7.f3", "sda": "GPIO6.f3" }, + "pwm0": { + "b": "GPIO17.f4" + }, + "pwm7": { + "a": "GPIO14.f4" + }, "spi1": { "miso": "GPIO12.f1", "mosi": "GPIO11.f1", @@ -168,8 +207,24 @@ "bus_hz": { "sys": 150000000 }, + "bus_timer_hz": { + "sys": 150000000 + }, "bypass": false, "cpu_hz": 150000000, + "fixed_plls": { + "pll_usb": { + "hz": 48000000, + "m": 1, + "n": 64, + "name": "pll_usb", + "p": 16, + "postdiv1": 4, + "postdiv2": 4, + "vco_hz": 768000000, + "vco_in_hz": 12000000 + } + }, "hclk_hz": 150000000, "pll": { "m": 1, @@ -414,6 +469,78 @@ "level": "kernel", "name": "i2c1", "peripheral": "i2c1" + }, + { + "class": "counter", + "compatible": "rpi,rp2350-timer", + "deps": [], + "fields": { + "base": 1074495488, + "index": 1, + "irq0": 4, + "irq1": 5, + "irq2": 6, + "irq3": 7, + "rate_hz": 1000000 + }, + "level": "kernel", + "name": "timer1", + "peripheral": "timer1" + }, + { + "class": "pwm", + "compatible": "rpi,rp2350-pwm", + "deps": [ + "io_bank0" + ], + "fields": { + "base": 1074430092, + "clock_hz": 150000000, + "index": 7 + }, + "level": "kernel", + "name": "pwm7", + "peripheral": "pwm7" + }, + { + "class": "pwm", + "compatible": "rpi,rp2350-pwm", + "deps": [ + "io_bank0" + ], + "fields": { + "base": 1074429952, + "clock_hz": 150000000, + "index": 0 + }, + "level": "kernel", + "name": "pwm0", + "peripheral": "pwm0" + }, + { + "class": "adc", + "compatible": "rpi,rp2350-adc", + "deps": [ + "clocks", + "io_bank0", + "dma" + ], + "fields": { + "base": 1074397184, + "bits": 12, + "clock_hz": 48000000, + "dma_rx": { + "dma": "dma", + "request": 48, + "stream": 3 + }, + "inputs": 4, + "temperature": 4, + "vref_mv": 3300 + }, + "level": "kernel", + "name": "adc", + "peripheral": "adc" } ], "kconfig": { @@ -578,6 +705,44 @@ "pin": "GPIO13", "port": "", "signal": "spi1_cs0" + }, + { + "af": 4, + "gpio": "io_bank0", + "mode": "af", + "number": 14, + "owner": "pins.pwm7.a", + "pin": "GPIO14", + "port": "", + "signal": "pwm7_a" + }, + { + "af": 4, + "gpio": "io_bank0", + "mode": "af", + "number": 17, + "owner": "pins.pwm0.b", + "pin": "GPIO17", + "port": "", + "signal": "pwm0_b" + }, + { + "gpio": "io_bank0", + "mode": "analog", + "number": 26, + "owner": "pins.adc.in0", + "pin": "GPIO26", + "port": "", + "signal": "adc_in0" + }, + { + "gpio": "io_bank0", + "mode": "analog", + "number": 27, + "owner": "pins.adc.in1", + "pin": "GPIO27", + "port": "", + "signal": "adc_in1" } ], "profile": "base", @@ -601,120 +766,154 @@ }, { "path": "boards/rpi/pico2_w/board.yaml", - "sha256": "dad0ef7259e41ef3bd8fa07ea1c1f36040254a443deaf30d963b4fb14b5354a0" + "sha256": "345279a53c444bc45e7fcc1a0cb5ab47b32a7699534f5484ea80d73f7a0bdf6d" }, { "path": "drivers/bindings.yaml", - "sha256": "d3c336ac05548e0addd1faac18f3dff70576d8069f11d89e6a761cf5c6132b49" + "sha256": "c06d1a914adb21d0e314c79b3611ac6859eefeac1957d6914cccfc5531ad6ede" }, { "path": "soc/rpi/rp2350/rp2350.yaml", - "sha256": "9e60e99ecac8782bccd69e3bd69014af1d8891d6b6fbd822acff5bd9a526d8cd" + "sha256": "80773a9c9cfb1c62cd322e397111a11d7f48fce3c0febc76bf7d5571018977a5" }, { "path": "soc/rpi/rp2350/rp2350a.yaml", - "sha256": "045cef7794c3b6c6d2ff48ba294c6308d00fe13bc65e346f2ba2ccde1cea24ff" + "sha256": "22395e35ed229020b5c9c7586af50cfaa07960a09905776eb4713ff28051eb3c" } ], "schema_version": 0, "soc": { "alternate_functions": { "GPIO0": { - "f2": "uart0_tx" + "f2": "uart0_tx", + "f4": "pwm0_a" }, "GPIO1": { - "f2": "uart0_rx" + "f2": "uart0_rx", + "f4": "pwm0_b" }, "GPIO10": { "f1": "spi1_sck", - "f11": "uart1_tx" + "f11": "uart1_tx", + "f4": "pwm5_a" }, "GPIO11": { "f1": "spi1_mosi", - "f11": "uart1_rx" + "f11": "uart1_rx", + "f4": "pwm5_b" }, "GPIO12": { "f1": "spi1_miso", - "f2": "uart0_tx" + "f2": "uart0_tx", + "f4": "pwm6_a" }, "GPIO13": { - "f2": "uart0_rx" + "f2": "uart0_rx", + "f4": "pwm6_b" }, "GPIO14": { - "f11": "uart0_tx" + "f11": "uart0_tx", + "f4": "pwm7_a" }, "GPIO15": { - "f11": "uart0_rx" + "f11": "uart0_rx", + "f4": "pwm7_b" }, "GPIO16": { - "f2": "uart0_tx" + "f2": "uart0_tx", + "f4": "pwm0_a" }, "GPIO17": { - "f2": "uart0_rx" + "f2": "uart0_rx", + "f4": "pwm0_b" }, "GPIO18": { - "f11": "uart0_tx" + "f11": "uart0_tx", + "f4": "pwm1_a" }, "GPIO19": { - "f11": "uart0_rx" + "f11": "uart0_rx", + "f4": "pwm1_b" }, "GPIO2": { - "f11": "uart0_tx" + "f11": "uart0_tx", + "f4": "pwm1_a" }, "GPIO20": { - "f2": "uart1_tx" + "f2": "uart1_tx", + "f4": "pwm2_a" }, "GPIO21": { - "f2": "uart1_rx" + "f2": "uart1_rx", + "f4": "pwm2_b" }, "GPIO22": { - "f11": "uart1_tx" + "f11": "uart1_tx", + "f4": "pwm3_a" }, "GPIO23": { - "f11": "uart1_rx" + "f11": "uart1_rx", + "f4": "pwm3_b" }, "GPIO24": { - "f2": "uart1_tx" + "f2": "uart1_tx", + "f4": "pwm4_a" }, "GPIO25": { - "f2": "uart1_rx" + "f2": "uart1_rx", + "f4": "pwm4_b" }, "GPIO26": { - "f11": "uart1_tx" + "analog": "adc_in0", + "f11": "uart1_tx", + "f4": "pwm5_a" }, "GPIO27": { - "f11": "uart1_rx" + "analog": "adc_in1", + "f11": "uart1_rx", + "f4": "pwm5_b" }, "GPIO28": { - "f2": "uart0_tx" + "analog": "adc_in2", + "f2": "uart0_tx", + "f4": "pwm6_a" }, "GPIO29": { - "f2": "uart0_rx" + "analog": "adc_in3", + "f2": "uart0_rx", + "f4": "pwm6_b" }, "GPIO3": { - "f11": "uart0_rx" + "f11": "uart0_rx", + "f4": "pwm1_b" }, "GPIO4": { - "f2": "uart1_tx" + "f2": "uart1_tx", + "f4": "pwm2_a" }, "GPIO5": { - "f2": "uart1_rx" + "f2": "uart1_rx", + "f4": "pwm2_b" }, "GPIO6": { "f11": "uart1_tx", - "f3": "i2c1_sda" + "f3": "i2c1_sda", + "f4": "pwm3_a" }, "GPIO7": { "f11": "uart1_rx", - "f3": "i2c1_scl" + "f3": "i2c1_scl", + "f4": "pwm3_b" }, "GPIO8": { "f2": "uart1_tx", - "f3": "i2c0_sda" + "f3": "i2c0_sda", + "f4": "pwm4_a" }, "GPIO9": { "f2": "uart1_rx", - "f3": "i2c0_scl" + "f3": "i2c0_scl", + "f4": "pwm4_b" } }, "arch": { @@ -760,6 +959,33 @@ 750000000, 1600000000 ] + }, + { + "inputs": [ + "xosc" + ], + "m": [ + 1, + 63 + ], + "n": [ + 16, + 320 + ], + "name": "pll_usb", + "output_hz": 48000000, + "postdiv": [ + 1, + 7 + ], + "vco_in_hz": [ + 5000000, + 800000000 + ], + "vco_out_hz": [ + 750000000, + 1600000000 + ] } ], "sources": [ @@ -908,6 +1134,12 @@ "name": "pll_sys", "size": 16384 }, + { + "base": 1074102272, + "compatible": "rpi,rp2350-pll", + "name": "pll_usb", + "size": 16384 + }, { "base": 1074200576, "compatible": "arm,pl011", @@ -1093,6 +1325,213 @@ "compatible": "rpi,rp2350-sio", "name": "sio", "size": 4096 + }, + { + "adc": { + "bits": 12, + "inputs": 4, + "temperature": 4 + }, + "base": 1074397184, + "clocked_by": "pll_usb", + "compatible": "rpi,rp2350-adc", + "dma_requests": { + "rx": "dma.dreq48" + }, + "irqs": [ + { + "name": "fifo", + "number": 35 + } + ], + "name": "adc", + "size": 16384 + }, + { + "base": 1074430192, + "compatible": "rpi,rp2350-pwm-irq", + "irqs": [ + { + "name": "wrap0", + "number": 8 + }, + { + "name": "wrap1", + "number": 9 + } + ], + "name": "pwm", + "size": 32 + }, + { + "base": 1074429952, + "compatible": "rpi,rp2350-pwm", + "counter_bits": 16, + "dma_requests": { + "wrap": "dma.dreq32" + }, + "name": "pwm0", + "size": 20 + }, + { + "base": 1074429972, + "compatible": "rpi,rp2350-pwm", + "counter_bits": 16, + "dma_requests": { + "wrap": "dma.dreq33" + }, + "name": "pwm1", + "size": 20 + }, + { + "base": 1074429992, + "compatible": "rpi,rp2350-pwm", + "counter_bits": 16, + "dma_requests": { + "wrap": "dma.dreq34" + }, + "name": "pwm2", + "size": 20 + }, + { + "base": 1074430012, + "compatible": "rpi,rp2350-pwm", + "counter_bits": 16, + "dma_requests": { + "wrap": "dma.dreq35" + }, + "name": "pwm3", + "size": 20 + }, + { + "base": 1074430032, + "compatible": "rpi,rp2350-pwm", + "counter_bits": 16, + "dma_requests": { + "wrap": "dma.dreq36" + }, + "name": "pwm4", + "size": 20 + }, + { + "base": 1074430052, + "compatible": "rpi,rp2350-pwm", + "counter_bits": 16, + "dma_requests": { + "wrap": "dma.dreq37" + }, + "name": "pwm5", + "size": 20 + }, + { + "base": 1074430072, + "compatible": "rpi,rp2350-pwm", + "counter_bits": 16, + "dma_requests": { + "wrap": "dma.dreq38" + }, + "name": "pwm6", + "size": 20 + }, + { + "base": 1074430092, + "compatible": "rpi,rp2350-pwm", + "counter_bits": 16, + "dma_requests": { + "wrap": "dma.dreq39" + }, + "name": "pwm7", + "size": 20 + }, + { + "base": 1074430112, + "compatible": "rpi,rp2350-pwm", + "counter_bits": 16, + "dma_requests": { + "wrap": "dma.dreq40" + }, + "name": "pwm8", + "size": 20 + }, + { + "base": 1074430132, + "compatible": "rpi,rp2350-pwm", + "counter_bits": 16, + "dma_requests": { + "wrap": "dma.dreq41" + }, + "name": "pwm9", + "size": 20 + }, + { + "base": 1074430152, + "compatible": "rpi,rp2350-pwm", + "counter_bits": 16, + "dma_requests": { + "wrap": "dma.dreq42" + }, + "name": "pwm10", + "size": 20 + }, + { + "base": 1074430172, + "compatible": "rpi,rp2350-pwm", + "counter_bits": 16, + "dma_requests": { + "wrap": "dma.dreq43" + }, + "name": "pwm11", + "size": 20 + }, + { + "base": 1074462720, + "compatible": "rpi,rp2350-timer", + "counter_bits": 64, + "irqs": [ + { + "name": "alarm0", + "number": 0 + }, + { + "name": "alarm1", + "number": 1 + }, + { + "name": "alarm2", + "number": 2 + }, + { + "name": "alarm3", + "number": 3 + } + ], + "name": "timer0", + "size": 16384 + }, + { + "base": 1074495488, + "compatible": "rpi,rp2350-timer", + "counter_bits": 64, + "irqs": [ + { + "name": "alarm0", + "number": 4 + }, + { + "name": "alarm1", + "number": 5 + }, + { + "name": "alarm2", + "number": 6 + }, + { + "name": "alarm3", + "number": 7 + } + ], + "name": "timer1", + "size": 16384 } ], "schema_version": 0, diff --git a/boards/rpi/pico2_w/generated/.base/include/hw_config.h b/boards/rpi/pico2_w/generated/.base/include/hw_config.h index a12d0367..676653de 100644 --- a/boards/rpi/pico2_w/generated/.base/include/hw_config.h +++ b/boards/rpi/pico2_w/generated/.base/include/hw_config.h @@ -15,13 +15,13 @@ * arch/cortex_m/arch.yaml * c5c8e451c09717dee1713d07f8311b6d507e3b4c66c42d93e0ce11da6ec76d6d * boards/rpi/pico2_w/board.yaml - * dad0ef7259e41ef3bd8fa07ea1c1f36040254a443deaf30d963b4fb14b5354a0 + * 345279a53c444bc45e7fcc1a0cb5ab47b32a7699534f5484ea80d73f7a0bdf6d * drivers/bindings.yaml - * d3c336ac05548e0addd1faac18f3dff70576d8069f11d89e6a761cf5c6132b49 + * c06d1a914adb21d0e314c79b3611ac6859eefeac1957d6914cccfc5531ad6ede * soc/rpi/rp2350/rp2350.yaml - * 9e60e99ecac8782bccd69e3bd69014af1d8891d6b6fbd822acff5bd9a526d8cd + * 80773a9c9cfb1c62cd322e397111a11d7f48fce3c0febc76bf7d5571018977a5 * soc/rpi/rp2350/rp2350a.yaml - * 045cef7794c3b6c6d2ff48ba294c6308d00fe13bc65e346f2ba2ccde1cea24ff + * 22395e35ed229020b5c9c7586af50cfaa07960a09905776eb4713ff28051eb3c */ #ifndef HW_CONFIG_H #define HW_CONFIG_H @@ -32,17 +32,22 @@ #define EMB_HW_SOC_PACKAGE "qfn60" /* clock tree (150 MHz) */ -#define EMB_HW_AHB_DIV 1u -#define EMB_HW_CPU_HZ 150000000u -#define EMB_HW_PLL_M 1u -#define EMB_HW_PLL_N 125u -#define EMB_HW_PLL_P 10u -#define EMB_HW_PLL_POSTDIV1 5u -#define EMB_HW_PLL_POSTDIV2 2u -#define EMB_HW_PLL_VCO_HZ 1500000000u -#define EMB_HW_SYS_HZ 150000000u -#define EMB_HW_XOSC_BYPASS 0 -#define EMB_HW_XOSC_HZ 12000000u +#define EMB_HW_AHB_DIV 1u +#define EMB_HW_CPU_HZ 150000000u +#define EMB_HW_PLL_M 1u +#define EMB_HW_PLL_N 125u +#define EMB_HW_PLL_P 10u +#define EMB_HW_PLL_POSTDIV1 5u +#define EMB_HW_PLL_POSTDIV2 2u +#define EMB_HW_PLL_USB_HZ 48000000u +#define EMB_HW_PLL_USB_M 1u +#define EMB_HW_PLL_USB_N 64u +#define EMB_HW_PLL_USB_POSTDIV1 4u +#define EMB_HW_PLL_USB_POSTDIV2 4u +#define EMB_HW_PLL_VCO_HZ 1500000000u +#define EMB_HW_SYS_HZ 150000000u +#define EMB_HW_XOSC_BYPASS 0 +#define EMB_HW_XOSC_HZ 12000000u /* memory regions */ #define EMB_HW_SRAM_BASE 0x20000000u @@ -57,6 +62,8 @@ #define EMB_HW_IRQ_PRIORITY_BITS 4u /* peripherals: register blocks, interrupt lines, clock gates */ +#define EMB_HW_ADC_BASE 0x400A0000u +#define EMB_HW_ADC_IRQ_FIFO 35u #define EMB_HW_BOOTRAM_BASE 0x400E0000u #define EMB_HW_CLOCKS_BASE 0x40010000u #define EMB_HW_CLOCKS_IRQ 30u @@ -73,9 +80,25 @@ #define EMB_HW_IO_BANK0_IRQ_BANK0 21u #define EMB_HW_PADS_BANK0_BASE 0x40038000u #define EMB_HW_PLL_SYS_BASE 0x40050000u +#define EMB_HW_PLL_USB_BASE 0x40058000u #define EMB_HW_POWMAN_BASE 0x40100000u #define EMB_HW_POWMAN_IRQ_TIMER 45u #define EMB_HW_PSM_BASE 0x40018000u +#define EMB_HW_PWM0_BASE 0x400A8000u +#define EMB_HW_PWM10_BASE 0x400A80C8u +#define EMB_HW_PWM11_BASE 0x400A80DCu +#define EMB_HW_PWM1_BASE 0x400A8014u +#define EMB_HW_PWM2_BASE 0x400A8028u +#define EMB_HW_PWM3_BASE 0x400A803Cu +#define EMB_HW_PWM4_BASE 0x400A8050u +#define EMB_HW_PWM5_BASE 0x400A8064u +#define EMB_HW_PWM6_BASE 0x400A8078u +#define EMB_HW_PWM7_BASE 0x400A808Cu +#define EMB_HW_PWM8_BASE 0x400A80A0u +#define EMB_HW_PWM9_BASE 0x400A80B4u +#define EMB_HW_PWM_BASE 0x400A80F0u +#define EMB_HW_PWM_IRQ_WRAP0 8u +#define EMB_HW_PWM_IRQ_WRAP1 9u #define EMB_HW_QMI_BASE 0x400D0000u #define EMB_HW_RESETS_BASE 0x40020000u #define EMB_HW_SIO_BASE 0xD0000000u @@ -84,6 +107,16 @@ #define EMB_HW_SPI1_BASE 0x40088000u #define EMB_HW_SPI1_IRQ 32u #define EMB_HW_TICKS_BASE 0x40108000u +#define EMB_HW_TIMER0_BASE 0x400B0000u +#define EMB_HW_TIMER0_IRQ_ALARM0 0u +#define EMB_HW_TIMER0_IRQ_ALARM1 1u +#define EMB_HW_TIMER0_IRQ_ALARM2 2u +#define EMB_HW_TIMER0_IRQ_ALARM3 3u +#define EMB_HW_TIMER1_BASE 0x400B8000u +#define EMB_HW_TIMER1_IRQ_ALARM0 4u +#define EMB_HW_TIMER1_IRQ_ALARM1 5u +#define EMB_HW_TIMER1_IRQ_ALARM2 6u +#define EMB_HW_TIMER1_IRQ_ALARM3 7u #define EMB_HW_TRNG_BASE 0x400F0000u #define EMB_HW_TRNG_IRQ_IRQ 39u #define EMB_HW_UART0_BASE 0x40070000u diff --git a/boards/rpi/pico2_w/generated/.base/include/soc_devices.h b/boards/rpi/pico2_w/generated/.base/include/soc_devices.h index 2aaa94d7..9d07d6f2 100644 --- a/boards/rpi/pico2_w/generated/.base/include/soc_devices.h +++ b/boards/rpi/pico2_w/generated/.base/include/soc_devices.h @@ -15,20 +15,20 @@ * arch/cortex_m/arch.yaml * c5c8e451c09717dee1713d07f8311b6d507e3b4c66c42d93e0ce11da6ec76d6d * boards/rpi/pico2_w/board.yaml - * dad0ef7259e41ef3bd8fa07ea1c1f36040254a443deaf30d963b4fb14b5354a0 + * 345279a53c444bc45e7fcc1a0cb5ab47b32a7699534f5484ea80d73f7a0bdf6d * drivers/bindings.yaml - * d3c336ac05548e0addd1faac18f3dff70576d8069f11d89e6a761cf5c6132b49 + * c06d1a914adb21d0e314c79b3611ac6859eefeac1957d6914cccfc5531ad6ede * soc/rpi/rp2350/rp2350.yaml - * 9e60e99ecac8782bccd69e3bd69014af1d8891d6b6fbd822acff5bd9a526d8cd + * 80773a9c9cfb1c62cd322e397111a11d7f48fce3c0febc76bf7d5571018977a5 * soc/rpi/rp2350/rp2350a.yaml - * 045cef7794c3b6c6d2ff48ba294c6308d00fe13bc65e346f2ba2ccde1cea24ff + * 22395e35ed229020b5c9c7586af50cfaa07960a09905776eb4713ff28051eb3c */ #ifndef EMB_SOC_DEVICES_H #define EMB_SOC_DEVICES_H #include -#define EMB_SOC_DEVICE_COUNT 12u +#define EMB_SOC_DEVICE_COUNT 16u #if CONFIG_EMB_DEVICE #include @@ -46,6 +46,10 @@ extern const emb_device_t emb_dev_trng; extern const emb_device_t emb_dev_spi1; extern const emb_device_t emb_dev_i2c0; extern const emb_device_t emb_dev_i2c1; +extern const emb_device_t emb_dev_timer1; +extern const emb_device_t emb_dev_pwm7; +extern const emb_device_t emb_dev_pwm0; +extern const emb_device_t emb_dev_adc; /* which devices the board has, for code that uses one only where it exists */ #define EMB_SOC_HAS_CLOCKS 1 @@ -60,6 +64,10 @@ extern const emb_device_t emb_dev_i2c1; #define EMB_SOC_HAS_SPI1 1 #define EMB_SOC_HAS_I2C0 1 #define EMB_SOC_HAS_I2C1 1 +#define EMB_SOC_HAS_TIMER1 1 +#define EMB_SOC_HAS_PWM7 1 +#define EMB_SOC_HAS_PWM0 1 +#define EMB_SOC_HAS_ADC 1 /* the board's watchdog device: the first of its class */ #define EMB_SOC_WATCHDOG_DEVICE (&emb_dev_watchdog) @@ -67,6 +75,11 @@ extern const emb_device_t emb_dev_i2c1; /* the board's RTC device: the first of its class */ #define EMB_SOC_RTC_DEVICE (&emb_dev_rtc) +/* the board's counters: the first of their class, and all of them (SPEC-017 §11a) */ +#define EMB_SOC_COUNTER_DEVICE (&emb_dev_timer1) +#define EMB_SOC_COUNTER_DEVICES &emb_dev_timer1 +#define EMB_SOC_COUNTER_COUNT 1u + /* the board's entropy source: the first of its class (SPEC-017 §11) */ #define EMB_SOC_ENTROPY_DEVICE (&emb_dev_trng) @@ -88,6 +101,7 @@ extern const emb_device_t emb_dev_i2c1; #define EMB_SOC_UART1_DMA_TX {&emb_dev_dma, 2u, 30u, {0u, 0u}} #define EMB_SOC_SPI1_DMA_RX {&emb_dev_dma, 1u, 27u, {0u, 0u}} #define EMB_SOC_SPI1_DMA_TX {&emb_dev_dma, 0u, 26u, {0u, 0u}} +#define EMB_SOC_ADC_DMA_RX {&emb_dev_dma, 3u, 48u, {0u, 0u}} /* clang-format on */ /* the SPI devices' chip selects (devices[].cs), emb_drv_gpio_line_t initializers; the pin diff --git a/boards/rpi/pico2_w/generated/.base/linker/regions.ld b/boards/rpi/pico2_w/generated/.base/linker/regions.ld index aff20354..3cf2d35e 100644 --- a/boards/rpi/pico2_w/generated/.base/linker/regions.ld +++ b/boards/rpi/pico2_w/generated/.base/linker/regions.ld @@ -16,13 +16,13 @@ * arch/cortex_m/arch.yaml * c5c8e451c09717dee1713d07f8311b6d507e3b4c66c42d93e0ce11da6ec76d6d * boards/rpi/pico2_w/board.yaml - * dad0ef7259e41ef3bd8fa07ea1c1f36040254a443deaf30d963b4fb14b5354a0 + * 345279a53c444bc45e7fcc1a0cb5ab47b32a7699534f5484ea80d73f7a0bdf6d * drivers/bindings.yaml - * d3c336ac05548e0addd1faac18f3dff70576d8069f11d89e6a761cf5c6132b49 + * c06d1a914adb21d0e314c79b3611ac6859eefeac1957d6914cccfc5531ad6ede * soc/rpi/rp2350/rp2350.yaml - * 9e60e99ecac8782bccd69e3bd69014af1d8891d6b6fbd822acff5bd9a526d8cd + * 80773a9c9cfb1c62cd322e397111a11d7f48fce3c0febc76bf7d5571018977a5 * soc/rpi/rp2350/rp2350a.yaml - * 045cef7794c3b6c6d2ff48ba294c6308d00fe13bc65e346f2ba2ccde1cea24ff + * 22395e35ed229020b5c9c7586af50cfaa07960a09905776eb4713ff28051eb3c */ ENTRY(embn_cm_reset) diff --git a/boards/rpi/pico2_w/generated/.base/src/board_pins.c b/boards/rpi/pico2_w/generated/.base/src/board_pins.c index 6c6b3c90..1b188dee 100644 --- a/boards/rpi/pico2_w/generated/.base/src/board_pins.c +++ b/boards/rpi/pico2_w/generated/.base/src/board_pins.c @@ -18,13 +18,13 @@ * arch/cortex_m/arch.yaml * c5c8e451c09717dee1713d07f8311b6d507e3b4c66c42d93e0ce11da6ec76d6d * boards/rpi/pico2_w/board.yaml - * dad0ef7259e41ef3bd8fa07ea1c1f36040254a443deaf30d963b4fb14b5354a0 + * 345279a53c444bc45e7fcc1a0cb5ab47b32a7699534f5484ea80d73f7a0bdf6d * drivers/bindings.yaml - * d3c336ac05548e0addd1faac18f3dff70576d8069f11d89e6a761cf5c6132b49 + * c06d1a914adb21d0e314c79b3611ac6859eefeac1957d6914cccfc5531ad6ede * soc/rpi/rp2350/rp2350.yaml - * 9e60e99ecac8782bccd69e3bd69014af1d8891d6b6fbd822acff5bd9a526d8cd + * 80773a9c9cfb1c62cd322e397111a11d7f48fce3c0febc76bf7d5571018977a5 * soc/rpi/rp2350/rp2350a.yaml - * 045cef7794c3b6c6d2ff48ba294c6308d00fe13bc65e346f2ba2ccde1cea24ff + * 22395e35ed229020b5c9c7586af50cfaa07960a09905776eb4713ff28051eb3c */ #include #include @@ -54,6 +54,14 @@ const emb_rp2350_pin_t emb_board_pins[] = { {12u, 1u, 1u, EMB_RP2350_PULL_RESET, EMB_RP2350_OUT_NONE}, /* GPIO13: devices.spi1.cs[0] (spi1_cs0) */ {13u, 5u, 1u, EMB_RP2350_PULL_RESET, EMB_RP2350_OUT_HIGH}, + /* GPIO14: pins.pwm7.a (pwm7_a) */ + {14u, 4u, 1u, EMB_RP2350_PULL_RESET, EMB_RP2350_OUT_NONE}, + /* GPIO17: pins.pwm0.b (pwm0_b) */ + {17u, 4u, 1u, EMB_RP2350_PULL_RESET, EMB_RP2350_OUT_NONE}, + /* GPIO26: pins.adc.in0 (adc_in0) */ + {26u, 31u, 0u, EMB_RP2350_PULL_NONE, EMB_RP2350_OUT_NONE}, + /* GPIO27: pins.adc.in1 (adc_in1) */ + {27u, 31u, 0u, EMB_RP2350_PULL_NONE, EMB_RP2350_OUT_NONE}, }; const unsigned emb_board_pin_count = (unsigned)(sizeof(emb_board_pins) / sizeof(emb_board_pins[0])); diff --git a/boards/rpi/pico2_w/generated/.base/src/boot_block.c b/boards/rpi/pico2_w/generated/.base/src/boot_block.c index b6abf30f..d464b75b 100644 --- a/boards/rpi/pico2_w/generated/.base/src/boot_block.c +++ b/boards/rpi/pico2_w/generated/.base/src/boot_block.c @@ -15,13 +15,13 @@ * arch/cortex_m/arch.yaml * c5c8e451c09717dee1713d07f8311b6d507e3b4c66c42d93e0ce11da6ec76d6d * boards/rpi/pico2_w/board.yaml - * dad0ef7259e41ef3bd8fa07ea1c1f36040254a443deaf30d963b4fb14b5354a0 + * 345279a53c444bc45e7fcc1a0cb5ab47b32a7699534f5484ea80d73f7a0bdf6d * drivers/bindings.yaml - * d3c336ac05548e0addd1faac18f3dff70576d8069f11d89e6a761cf5c6132b49 + * c06d1a914adb21d0e314c79b3611ac6859eefeac1957d6914cccfc5531ad6ede * soc/rpi/rp2350/rp2350.yaml - * 9e60e99ecac8782bccd69e3bd69014af1d8891d6b6fbd822acff5bd9a526d8cd + * 80773a9c9cfb1c62cd322e397111a11d7f48fce3c0febc76bf7d5571018977a5 * soc/rpi/rp2350/rp2350a.yaml - * 045cef7794c3b6c6d2ff48ba294c6308d00fe13bc65e346f2ba2ccde1cea24ff + * 22395e35ed229020b5c9c7586af50cfaa07960a09905776eb4713ff28051eb3c */ #include diff --git a/boards/rpi/pico2_w/generated/.base/src/soc_devices.c b/boards/rpi/pico2_w/generated/.base/src/soc_devices.c index 43f60687..6cc3b0b9 100644 --- a/boards/rpi/pico2_w/generated/.base/src/soc_devices.c +++ b/boards/rpi/pico2_w/generated/.base/src/soc_devices.c @@ -16,13 +16,13 @@ * arch/cortex_m/arch.yaml * c5c8e451c09717dee1713d07f8311b6d507e3b4c66c42d93e0ce11da6ec76d6d * boards/rpi/pico2_w/board.yaml - * dad0ef7259e41ef3bd8fa07ea1c1f36040254a443deaf30d963b4fb14b5354a0 + * 345279a53c444bc45e7fcc1a0cb5ab47b32a7699534f5484ea80d73f7a0bdf6d * drivers/bindings.yaml - * d3c336ac05548e0addd1faac18f3dff70576d8069f11d89e6a761cf5c6132b49 + * c06d1a914adb21d0e314c79b3611ac6859eefeac1957d6914cccfc5531ad6ede * soc/rpi/rp2350/rp2350.yaml - * 9e60e99ecac8782bccd69e3bd69014af1d8891d6b6fbd822acff5bd9a526d8cd + * 80773a9c9cfb1c62cd322e397111a11d7f48fce3c0febc76bf7d5571018977a5 * soc/rpi/rp2350/rp2350a.yaml - * 045cef7794c3b6c6d2ff48ba294c6308d00fe13bc65e346f2ba2ccde1cea24ff + * 22395e35ed229020b5c9c7586af50cfaa07960a09905776eb4713ff28051eb3c */ #include @@ -295,6 +295,97 @@ const emb_device_t emb_dev_i2c1 = { .dep_count = 1u, }; +/* timer1: rpi,rp2350-timer, counter, KERNEL */ +static const emb_rp2350_timer_config_t timer1_config = { + .base = 0x400B8000u, /* peripheral.base */ + .index = 1u, /* peripheral.index */ + .rate_hz = 1000000u, /* device.rate_hz, its default */ + .irq0 = 4u, /* peripheral.irqs.alarm0 */ + .irq1 = 5u, /* peripheral.irqs.alarm1 */ + .irq2 = 6u, /* peripheral.irqs.alarm2 */ + .irq3 = 7u, /* peripheral.irqs.alarm3 */ +}; +static emb_device_state_t timer1_state; +static emb_rp2350_timer_data_t timer1_data; +const emb_device_t emb_dev_timer1 = { + .name = "timer1", + .api = &emb_rp2350_timer_api.dev, + .config = &timer1_config, + .state = &timer1_state, + .data = &timer1_data, + .deps = NULL, + .class_id = EMB_DRV_CLASS_COUNTER, + .level = EMB_DEVICE_KERNEL, + .dep_count = 0u, +}; + +/* pwm7: rpi,rp2350-pwm, pwm, KERNEL */ +static const emb_rp2350_pwm_config_t pwm7_config = { + .base = 0x400A808Cu, /* peripheral.base */ + .index = 7u, /* peripheral.index */ + .clock_hz = 150000000u, /* peripheral.clock_hz */ +}; +static emb_device_state_t pwm7_state; +static emb_rp2350_pwm_data_t pwm7_data; +static const emb_device_t *const pwm7_deps[] = {&emb_dev_io_bank0}; +const emb_device_t emb_dev_pwm7 = { + .name = "pwm7", + .api = &emb_rp2350_pwm_api.dev, + .config = &pwm7_config, + .state = &pwm7_state, + .data = &pwm7_data, + .deps = pwm7_deps, + .class_id = EMB_DRV_CLASS_PWM, + .level = EMB_DEVICE_KERNEL, + .dep_count = 1u, +}; + +/* pwm0: rpi,rp2350-pwm, pwm, KERNEL */ +static const emb_rp2350_pwm_config_t pwm0_config = { + .base = 0x400A8000u, /* peripheral.base */ + .index = 0u, /* peripheral.index */ + .clock_hz = 150000000u, /* peripheral.clock_hz */ +}; +static emb_device_state_t pwm0_state; +static emb_rp2350_pwm_data_t pwm0_data; +static const emb_device_t *const pwm0_deps[] = {&emb_dev_io_bank0}; +const emb_device_t emb_dev_pwm0 = { + .name = "pwm0", + .api = &emb_rp2350_pwm_api.dev, + .config = &pwm0_config, + .state = &pwm0_state, + .data = &pwm0_data, + .deps = pwm0_deps, + .class_id = EMB_DRV_CLASS_PWM, + .level = EMB_DEVICE_KERNEL, + .dep_count = 1u, +}; + +/* adc: rpi,rp2350-adc, adc, KERNEL */ +static const emb_rp2350_adc_config_t adc_config = { + .base = 0x400A0000u, /* peripheral.base */ + .clock_hz = 48000000u, /* peripheral.clock_hz */ + .vref_mv = 3300u, /* device.vref_mv, its default */ + .bits = 12u, /* peripheral.adc.bits */ + .inputs = 4u, /* peripheral.adc.inputs */ + .temperature = 4u, /* peripheral.adc.temperature */ + .dma_rx = {&emb_dev_dma, 3u, 48u, {0u, 0u}}, /* dma.rx */ +}; +static emb_device_state_t adc_state; +static emb_rp2350_adc_data_t adc_data; +static const emb_device_t *const adc_deps[] = {&emb_dev_clocks, &emb_dev_io_bank0, &emb_dev_dma}; +const emb_device_t emb_dev_adc = { + .name = "adc", + .api = &emb_rp2350_adc_api.dev, + .config = &adc_config, + .state = &adc_state, + .data = &adc_data, + .deps = adc_deps, + .class_id = EMB_DRV_CLASS_ADC, + .level = EMB_DEVICE_KERNEL, + .dep_count = 3u, +}; + /* in initialization order */ static const emb_device_t *const devices[] = { &emb_dev_clocks, /* 0: EARLY */ @@ -309,9 +400,13 @@ static const emb_device_t *const devices[] = { &emb_dev_spi1, /* 9: KERNEL */ &emb_dev_i2c0, /* 10: KERNEL */ &emb_dev_i2c1, /* 11: KERNEL */ + &emb_dev_timer1, /* 12: KERNEL */ + &emb_dev_pwm7, /* 13: KERNEL */ + &emb_dev_pwm0, /* 14: KERNEL */ + &emb_dev_adc, /* 15: KERNEL */ }; -const emb_device_table_t emb_board_device_table = {devices, 12u, 8u}; +const emb_device_table_t emb_board_device_table = {devices, 16u, 8u}; #if CONFIG_EMB_DRV_ENTROPY /* the board's entropy source, or none: nothing stands in for one (SPEC-017 §11, SEC-012) */ diff --git a/boards/rpi/pico2_w/generated/build/CMakeLists.txt b/boards/rpi/pico2_w/generated/build/CMakeLists.txt index 1f978bd1..96bb1ab4 100644 --- a/boards/rpi/pico2_w/generated/build/CMakeLists.txt +++ b/boards/rpi/pico2_w/generated/build/CMakeLists.txt @@ -9,13 +9,13 @@ # arch/cortex_m/arch.yaml # c5c8e451c09717dee1713d07f8311b6d507e3b4c66c42d93e0ce11da6ec76d6d # boards/rpi/pico2_w/board.yaml -# dad0ef7259e41ef3bd8fa07ea1c1f36040254a443deaf30d963b4fb14b5354a0 +# 345279a53c444bc45e7fcc1a0cb5ab47b32a7699534f5484ea80d73f7a0bdf6d # drivers/bindings.yaml -# d3c336ac05548e0addd1faac18f3dff70576d8069f11d89e6a761cf5c6132b49 +# c06d1a914adb21d0e314c79b3611ac6859eefeac1957d6914cccfc5531ad6ede # soc/rpi/rp2350/rp2350.yaml -# 9e60e99ecac8782bccd69e3bd69014af1d8891d6b6fbd822acff5bd9a526d8cd +# 80773a9c9cfb1c62cd322e397111a11d7f48fce3c0febc76bf7d5571018977a5 # soc/rpi/rp2350/rp2350a.yaml -# 045cef7794c3b6c6d2ff48ba294c6308d00fe13bc65e346f2ba2ccde1cea24ff +# 22395e35ed229020b5c9c7586af50cfaa07960a09905776eb4713ff28051eb3c # The board has no C of its own: its SoC family's board support builds emb_board from # ../src/board_pins.c and ../include/hw_config.h, and links ../linker/regions.ld. add_subdirectory("${EMB_SOC_DIR}" soc) diff --git a/boards/rpi/pico2_w/generated/build/board.cmake b/boards/rpi/pico2_w/generated/build/board.cmake index 129da093..6487b6a6 100644 --- a/boards/rpi/pico2_w/generated/build/board.cmake +++ b/boards/rpi/pico2_w/generated/build/board.cmake @@ -9,13 +9,13 @@ # arch/cortex_m/arch.yaml # c5c8e451c09717dee1713d07f8311b6d507e3b4c66c42d93e0ce11da6ec76d6d # boards/rpi/pico2_w/board.yaml -# dad0ef7259e41ef3bd8fa07ea1c1f36040254a443deaf30d963b4fb14b5354a0 +# 345279a53c444bc45e7fcc1a0cb5ab47b32a7699534f5484ea80d73f7a0bdf6d # drivers/bindings.yaml -# d3c336ac05548e0addd1faac18f3dff70576d8069f11d89e6a761cf5c6132b49 +# c06d1a914adb21d0e314c79b3611ac6859eefeac1957d6914cccfc5531ad6ede # soc/rpi/rp2350/rp2350.yaml -# 9e60e99ecac8782bccd69e3bd69014af1d8891d6b6fbd822acff5bd9a526d8cd +# 80773a9c9cfb1c62cd322e397111a11d7f48fce3c0febc76bf7d5571018977a5 # soc/rpi/rp2350/rp2350a.yaml -# 045cef7794c3b6c6d2ff48ba294c6308d00fe13bc65e346f2ba2ccde1cea24ff +# 22395e35ed229020b5c9c7586af50cfaa07960a09905776eb4713ff28051eb3c # pico2_w: RP2350A, cortex-m33f at 150 MHz. set(EMB_BOARD_ARCH cortex_m) set(EMB_BOARD_VARIANT armv8m-main) @@ -25,6 +25,8 @@ get_filename_component(EMB_BOARD_GENERATED_DIR "${CMAKE_CURRENT_LIST_DIR}/.." AB set(EMB_BOARD_CONF "${EMB_BOARD_GENERATED_DIR}/config/board.conf") set(EMB_BOARD_HW_JSON "${EMB_BOARD_GENERATED_DIR}/docs/hw.json") set(EMB_BOARD_BUILD_DIR "${CMAKE_CURRENT_LIST_DIR}") # build/CMakeLists.txt +set(EMB_BOARD_SRC_DIR "${EMB_BOARD_GENERATED_DIR}/src") # its pin table and boot block +set(EMB_BOARD_LINKER_DIR "${EMB_BOARD_GENERATED_DIR}/linker") # the SoC family's board support and drivers build this board (build/CMakeLists.txt) set(EMB_SOC_DIR "${EMB_BASE}/soc/rpi/rp2350") set(EMB_BOARD_INCLUDE_DIRS "${EMB_BOARD_GENERATED_DIR}/include" "${EMB_SOC_DIR}/include") @@ -32,6 +34,7 @@ set(EMB_BOARD_RESETS_IN hil) # restart the image with RAM kept (test_crash_reset set(EMB_BOARD_UART1_DMA tx) set(EMB_BOARD_SPI1_DMA rx tx) set(EMB_BOARD_SPI1_CS_COUNT 1) +set(EMB_BOARD_ADC_DMA rx) set(EMB_BOARD_FLASH_IMAGE uf2) # what the SoC's boot ROM loads (A79) set(EMB_BOARD_UF2_FAMILY 0xE48BFF59) # the board's devices (soc_devices.c) and the drivers they use, and only those (SPEC-016 §8) @@ -47,6 +50,9 @@ set(EMB_BOARD_DRIVER_SOURCES "${EMB_BASE}/drivers/rpi/rp2350_trng.c" "${EMB_BASE}/drivers/arm/pl022.c" "${EMB_BASE}/drivers/snps/dw_i2c.c" + "${EMB_BASE}/drivers/rpi/rp2350_timer.c" + "${EMB_BASE}/drivers/rpi/rp2350_pwm.c" + "${EMB_BASE}/drivers/rpi/rp2350_adc.c" ) set(EMB_BOARD_DRIVER_INCLUDE_DIRS "${EMB_BASE}/drivers/rpi/include" @@ -56,8 +62,8 @@ set(EMB_BOARD_DRIVER_INCLUDE_DIRS # the inputs this directory was generated from, for the configure-time staleness check set(EMB_BOARD_HW_INPUTS "arch/cortex_m/arch.yaml=c5c8e451c09717dee1713d07f8311b6d507e3b4c66c42d93e0ce11da6ec76d6d" - "boards/rpi/pico2_w/board.yaml=dad0ef7259e41ef3bd8fa07ea1c1f36040254a443deaf30d963b4fb14b5354a0" - "drivers/bindings.yaml=d3c336ac05548e0addd1faac18f3dff70576d8069f11d89e6a761cf5c6132b49" - "soc/rpi/rp2350/rp2350.yaml=9e60e99ecac8782bccd69e3bd69014af1d8891d6b6fbd822acff5bd9a526d8cd" - "soc/rpi/rp2350/rp2350a.yaml=045cef7794c3b6c6d2ff48ba294c6308d00fe13bc65e346f2ba2ccde1cea24ff" + "boards/rpi/pico2_w/board.yaml=345279a53c444bc45e7fcc1a0cb5ab47b32a7699534f5484ea80d73f7a0bdf6d" + "drivers/bindings.yaml=c06d1a914adb21d0e314c79b3611ac6859eefeac1957d6914cccfc5531ad6ede" + "soc/rpi/rp2350/rp2350.yaml=80773a9c9cfb1c62cd322e397111a11d7f48fce3c0febc76bf7d5571018977a5" + "soc/rpi/rp2350/rp2350a.yaml=22395e35ed229020b5c9c7586af50cfaa07960a09905776eb4713ff28051eb3c" ) diff --git a/boards/rpi/pico2_w/generated/config/board.conf b/boards/rpi/pico2_w/generated/config/board.conf index c643beda..d66490f8 100644 --- a/boards/rpi/pico2_w/generated/config/board.conf +++ b/boards/rpi/pico2_w/generated/config/board.conf @@ -9,13 +9,13 @@ # arch/cortex_m/arch.yaml # c5c8e451c09717dee1713d07f8311b6d507e3b4c66c42d93e0ce11da6ec76d6d # boards/rpi/pico2_w/board.yaml -# dad0ef7259e41ef3bd8fa07ea1c1f36040254a443deaf30d963b4fb14b5354a0 +# 345279a53c444bc45e7fcc1a0cb5ab47b32a7699534f5484ea80d73f7a0bdf6d # drivers/bindings.yaml -# d3c336ac05548e0addd1faac18f3dff70576d8069f11d89e6a761cf5c6132b49 +# c06d1a914adb21d0e314c79b3611ac6859eefeac1957d6914cccfc5531ad6ede # soc/rpi/rp2350/rp2350.yaml -# 9e60e99ecac8782bccd69e3bd69014af1d8891d6b6fbd822acff5bd9a526d8cd +# 80773a9c9cfb1c62cd322e397111a11d7f48fce3c0febc76bf7d5571018977a5 # soc/rpi/rp2350/rp2350a.yaml -# 045cef7794c3b6c6d2ff48ba294c6308d00fe13bc65e346f2ba2ccde1cea24ff +# 22395e35ed229020b5c9c7586af50cfaa07960a09905776eb4713ff28051eb3c # Board defaults for pico2_w. Applied before the profile fragment. CONFIG_EMB_CM_CPU_HZ=150000000 CONFIG_EMB_CM_IRQ_COUNT=52 diff --git a/boards/rpi/pico2_w/generated/docs/board.md b/boards/rpi/pico2_w/generated/docs/board.md index 1af427ec..e50ddda6 100644 --- a/boards/rpi/pico2_w/generated/docs/board.md +++ b/boards/rpi/pico2_w/generated/docs/board.md @@ -41,6 +41,10 @@ The console on UART0 at 115200 baud on GPIO0 (TX, pin 1) and GPIO1 (RX, pin 2). | GPIO11 | `pins.spi1.mosi` | af1 (spi1_mosi) | | GPIO12 | `pins.spi1.miso` | af1 (spi1_miso) | | GPIO13 | `devices.spi1.cs[0]` | output | +| GPIO14 | `pins.pwm7.a` | af4 (pwm7_a) | +| GPIO17 | `pins.pwm0.b` | af4 (pwm0_b) | +| GPIO26 | `pins.adc.in0` | analog | +| GPIO27 | `pins.adc.in1` | analog | ## Devices @@ -60,11 +64,25 @@ In initialization order (SPEC-016 §4). | spi1 | `arm,pl022` | spi | KERNEL | io_bank0, dma | | i2c0 | `snps,designware-i2c` | i2c | KERNEL | io_bank0 | | i2c1 | `snps,designware-i2c` | i2c | KERNEL | io_bank0 | +| timer1 | `rpi,rp2350-timer` | counter | KERNEL | - | +| pwm7 | `rpi,rp2350-pwm` | pwm | KERNEL | io_bank0 | +| pwm0 | `rpi,rp2350-pwm` | pwm | KERNEL | io_bank0 | +| adc | `rpi,rp2350-adc` | adc | KERNEL | clocks, io_bank0, dma | ## Interrupt lines | Line | Owner | |---|---| +| 0 | timer0.alarm0 | +| 1 | timer0.alarm1 | +| 2 | timer0.alarm2 | +| 3 | timer0.alarm3 | +| 4 | timer1.alarm0 | +| 5 | timer1.alarm1 | +| 6 | timer1.alarm2 | +| 7 | timer1.alarm3 | +| 8 | pwm.wrap0 | +| 9 | pwm.wrap1 | | 10 | dma.irq0 | | 11 | dma.irq1 | | 12 | dma.irq2 | @@ -75,6 +93,7 @@ In initialization order (SPEC-016 §4). | 32 | spi1.global | | 33 | uart0.global | | 34 | uart1.global | +| 35 | adc.fifo | | 36 | i2c0.global | | 37 | i2c1.global | | 39 | trng.irq | @@ -89,7 +108,7 @@ Generated by emb-hwgen 0.1.0, schema v0, from: | Input | SHA-256 | |---|---| | `arch/cortex_m/arch.yaml` | `c5c8e451c09717dee1713d07f8311b6d507e3b4c66c42d93e0ce11da6ec76d6d` | -| `boards/rpi/pico2_w/board.yaml` | `dad0ef7259e41ef3bd8fa07ea1c1f36040254a443deaf30d963b4fb14b5354a0` | -| `drivers/bindings.yaml` | `d3c336ac05548e0addd1faac18f3dff70576d8069f11d89e6a761cf5c6132b49` | -| `soc/rpi/rp2350/rp2350.yaml` | `9e60e99ecac8782bccd69e3bd69014af1d8891d6b6fbd822acff5bd9a526d8cd` | -| `soc/rpi/rp2350/rp2350a.yaml` | `045cef7794c3b6c6d2ff48ba294c6308d00fe13bc65e346f2ba2ccde1cea24ff` | +| `boards/rpi/pico2_w/board.yaml` | `345279a53c444bc45e7fcc1a0cb5ab47b32a7699534f5484ea80d73f7a0bdf6d` | +| `drivers/bindings.yaml` | `c06d1a914adb21d0e314c79b3611ac6859eefeac1957d6914cccfc5531ad6ede` | +| `soc/rpi/rp2350/rp2350.yaml` | `80773a9c9cfb1c62cd322e397111a11d7f48fce3c0febc76bf7d5571018977a5` | +| `soc/rpi/rp2350/rp2350a.yaml` | `22395e35ed229020b5c9c7586af50cfaa07960a09905776eb4713ff28051eb3c` | diff --git a/boards/rpi/pico2_w/generated/docs/build_report.md b/boards/rpi/pico2_w/generated/docs/build_report.md index 0844f0ba..bddb1d98 100644 --- a/boards/rpi/pico2_w/generated/docs/build_report.md +++ b/boards/rpi/pico2_w/generated/docs/build_report.md @@ -4,6 +4,8 @@ xosc 12 MHz / M 1 = 12 MHz VCO input, x N 125 = 1500 MHz, / P 10 = 150 MHz. Given by the board, checked. +pll_usb: xosc 12 MHz / M 1 x N 64 = 768 MHz VCO, / 4 / 4 = 48 MHz. Solved; started by the drivers that use it. + | Bus | Frequency | Limit | |---|---|---| | sys | 150 MHz | 150 MHz | @@ -27,7 +29,7 @@ Generated by emb-hwgen 0.1.0, schema v0, from: | Input | SHA-256 | |---|---| | `arch/cortex_m/arch.yaml` | `c5c8e451c09717dee1713d07f8311b6d507e3b4c66c42d93e0ce11da6ec76d6d` | -| `boards/rpi/pico2_w/board.yaml` | `dad0ef7259e41ef3bd8fa07ea1c1f36040254a443deaf30d963b4fb14b5354a0` | -| `drivers/bindings.yaml` | `d3c336ac05548e0addd1faac18f3dff70576d8069f11d89e6a761cf5c6132b49` | -| `soc/rpi/rp2350/rp2350.yaml` | `9e60e99ecac8782bccd69e3bd69014af1d8891d6b6fbd822acff5bd9a526d8cd` | -| `soc/rpi/rp2350/rp2350a.yaml` | `045cef7794c3b6c6d2ff48ba294c6308d00fe13bc65e346f2ba2ccde1cea24ff` | +| `boards/rpi/pico2_w/board.yaml` | `345279a53c444bc45e7fcc1a0cb5ab47b32a7699534f5484ea80d73f7a0bdf6d` | +| `drivers/bindings.yaml` | `c06d1a914adb21d0e314c79b3611ac6859eefeac1957d6914cccfc5531ad6ede` | +| `soc/rpi/rp2350/rp2350.yaml` | `80773a9c9cfb1c62cd322e397111a11d7f48fce3c0febc76bf7d5571018977a5` | +| `soc/rpi/rp2350/rp2350a.yaml` | `22395e35ed229020b5c9c7586af50cfaa07960a09905776eb4713ff28051eb3c` | diff --git a/boards/rpi/pico2_w/generated/docs/hw.json b/boards/rpi/pico2_w/generated/docs/hw.json index 18720772..ca406a91 100644 --- a/boards/rpi/pico2_w/generated/docs/hw.json +++ b/boards/rpi/pico2_w/generated/docs/hw.json @@ -103,6 +103,35 @@ ], "doc": "a spare UART, its writes by DMA; the HIL suite's loopback wires GPIO4 (pin 6) to GPIO5 (pin 7)", "name": "uart1" + }, + { + "doc": "TIMER1, 64 bits at 1 MHz: the counter class's (A129); TIMER0 is left for M4.4's tickless time", + "name": "timer1" + }, + { + "deps": [ + "io_bank0" + ], + "doc": "slice 7, PWM out on A, GPIO14 (pin 19); the HIL suite wires it to pin 22", + "name": "pwm7" + }, + { + "deps": [ + "io_bank0" + ], + "doc": "slice 0, PWM capture on B, GPIO17 (pin 22)", + "name": "pwm0" + }, + { + "deps": [ + "clocks", + "io_bank0" + ], + "dma": [ + "rx" + ], + "doc": "the ADC on clk_adc, 48 MHz from PLL_USB: GPIO26 (pin 31, input 0) and GPIO27 (pin 32, input 1); the HIL suite wires pin 31 to 3V3 OUT and pin 32 to AGND", + "name": "adc" } ], "doc": "The console on UART0 at 115200 baud on GPIO0 (TX, pin 1) and GPIO1 (RX, pin 2). The CPU runs at 150 MHz from PLL_SYS (the 12 MHz crystal x 125 / 5 / 2, pico-sdk's factors), and clk_peri, the UARTs' clock, follows clk_sys. The user LED is on the CYW43439 wireless chip, which has no driver yet, so the board has no LED. Images are UF2 files, copied to the boot ROM's USB drive (hold BOOTSEL while plugging in), or loaded by picotool while the board is in BOOTSEL; a test image built for the board (EMB_TEST_EMULATOR=hil) reboots into BOOTSEL when it ends, so tools/hil/run_hil.py loads the next one without the button.", @@ -127,6 +156,10 @@ } }, "pins": { + "adc": { + "in0": "GPIO26", + "in1": "GPIO27" + }, "i2c0": { "scl": "GPIO9.f3", "sda": "GPIO8.f3" @@ -135,6 +168,12 @@ "scl": "GPIO7.f3", "sda": "GPIO6.f3" }, + "pwm0": { + "b": "GPIO17.f4" + }, + "pwm7": { + "a": "GPIO14.f4" + }, "spi1": { "miso": "GPIO12.f1", "mosi": "GPIO11.f1", @@ -168,8 +207,24 @@ "bus_hz": { "sys": 150000000 }, + "bus_timer_hz": { + "sys": 150000000 + }, "bypass": false, "cpu_hz": 150000000, + "fixed_plls": { + "pll_usb": { + "hz": 48000000, + "m": 1, + "n": 64, + "name": "pll_usb", + "p": 16, + "postdiv1": 4, + "postdiv2": 4, + "vco_hz": 768000000, + "vco_in_hz": 12000000 + } + }, "hclk_hz": 150000000, "pll": { "m": 1, @@ -414,6 +469,78 @@ "level": "kernel", "name": "i2c1", "peripheral": "i2c1" + }, + { + "class": "counter", + "compatible": "rpi,rp2350-timer", + "deps": [], + "fields": { + "base": 1074495488, + "index": 1, + "irq0": 4, + "irq1": 5, + "irq2": 6, + "irq3": 7, + "rate_hz": 1000000 + }, + "level": "kernel", + "name": "timer1", + "peripheral": "timer1" + }, + { + "class": "pwm", + "compatible": "rpi,rp2350-pwm", + "deps": [ + "io_bank0" + ], + "fields": { + "base": 1074430092, + "clock_hz": 150000000, + "index": 7 + }, + "level": "kernel", + "name": "pwm7", + "peripheral": "pwm7" + }, + { + "class": "pwm", + "compatible": "rpi,rp2350-pwm", + "deps": [ + "io_bank0" + ], + "fields": { + "base": 1074429952, + "clock_hz": 150000000, + "index": 0 + }, + "level": "kernel", + "name": "pwm0", + "peripheral": "pwm0" + }, + { + "class": "adc", + "compatible": "rpi,rp2350-adc", + "deps": [ + "clocks", + "io_bank0", + "dma" + ], + "fields": { + "base": 1074397184, + "bits": 12, + "clock_hz": 48000000, + "dma_rx": { + "dma": "dma", + "request": 48, + "stream": 3 + }, + "inputs": 4, + "temperature": 4, + "vref_mv": 3300 + }, + "level": "kernel", + "name": "adc", + "peripheral": "adc" } ], "kconfig": { @@ -578,6 +705,44 @@ "pin": "GPIO13", "port": "", "signal": "spi1_cs0" + }, + { + "af": 4, + "gpio": "io_bank0", + "mode": "af", + "number": 14, + "owner": "pins.pwm7.a", + "pin": "GPIO14", + "port": "", + "signal": "pwm7_a" + }, + { + "af": 4, + "gpio": "io_bank0", + "mode": "af", + "number": 17, + "owner": "pins.pwm0.b", + "pin": "GPIO17", + "port": "", + "signal": "pwm0_b" + }, + { + "gpio": "io_bank0", + "mode": "analog", + "number": 26, + "owner": "pins.adc.in0", + "pin": "GPIO26", + "port": "", + "signal": "adc_in0" + }, + { + "gpio": "io_bank0", + "mode": "analog", + "number": 27, + "owner": "pins.adc.in1", + "pin": "GPIO27", + "port": "", + "signal": "adc_in1" } ], "profile": "base", @@ -601,120 +766,154 @@ }, { "path": "boards/rpi/pico2_w/board.yaml", - "sha256": "dad0ef7259e41ef3bd8fa07ea1c1f36040254a443deaf30d963b4fb14b5354a0" + "sha256": "345279a53c444bc45e7fcc1a0cb5ab47b32a7699534f5484ea80d73f7a0bdf6d" }, { "path": "drivers/bindings.yaml", - "sha256": "d3c336ac05548e0addd1faac18f3dff70576d8069f11d89e6a761cf5c6132b49" + "sha256": "c06d1a914adb21d0e314c79b3611ac6859eefeac1957d6914cccfc5531ad6ede" }, { "path": "soc/rpi/rp2350/rp2350.yaml", - "sha256": "9e60e99ecac8782bccd69e3bd69014af1d8891d6b6fbd822acff5bd9a526d8cd" + "sha256": "80773a9c9cfb1c62cd322e397111a11d7f48fce3c0febc76bf7d5571018977a5" }, { "path": "soc/rpi/rp2350/rp2350a.yaml", - "sha256": "045cef7794c3b6c6d2ff48ba294c6308d00fe13bc65e346f2ba2ccde1cea24ff" + "sha256": "22395e35ed229020b5c9c7586af50cfaa07960a09905776eb4713ff28051eb3c" } ], "schema_version": 0, "soc": { "alternate_functions": { "GPIO0": { - "f2": "uart0_tx" + "f2": "uart0_tx", + "f4": "pwm0_a" }, "GPIO1": { - "f2": "uart0_rx" + "f2": "uart0_rx", + "f4": "pwm0_b" }, "GPIO10": { "f1": "spi1_sck", - "f11": "uart1_tx" + "f11": "uart1_tx", + "f4": "pwm5_a" }, "GPIO11": { "f1": "spi1_mosi", - "f11": "uart1_rx" + "f11": "uart1_rx", + "f4": "pwm5_b" }, "GPIO12": { "f1": "spi1_miso", - "f2": "uart0_tx" + "f2": "uart0_tx", + "f4": "pwm6_a" }, "GPIO13": { - "f2": "uart0_rx" + "f2": "uart0_rx", + "f4": "pwm6_b" }, "GPIO14": { - "f11": "uart0_tx" + "f11": "uart0_tx", + "f4": "pwm7_a" }, "GPIO15": { - "f11": "uart0_rx" + "f11": "uart0_rx", + "f4": "pwm7_b" }, "GPIO16": { - "f2": "uart0_tx" + "f2": "uart0_tx", + "f4": "pwm0_a" }, "GPIO17": { - "f2": "uart0_rx" + "f2": "uart0_rx", + "f4": "pwm0_b" }, "GPIO18": { - "f11": "uart0_tx" + "f11": "uart0_tx", + "f4": "pwm1_a" }, "GPIO19": { - "f11": "uart0_rx" + "f11": "uart0_rx", + "f4": "pwm1_b" }, "GPIO2": { - "f11": "uart0_tx" + "f11": "uart0_tx", + "f4": "pwm1_a" }, "GPIO20": { - "f2": "uart1_tx" + "f2": "uart1_tx", + "f4": "pwm2_a" }, "GPIO21": { - "f2": "uart1_rx" + "f2": "uart1_rx", + "f4": "pwm2_b" }, "GPIO22": { - "f11": "uart1_tx" + "f11": "uart1_tx", + "f4": "pwm3_a" }, "GPIO23": { - "f11": "uart1_rx" + "f11": "uart1_rx", + "f4": "pwm3_b" }, "GPIO24": { - "f2": "uart1_tx" + "f2": "uart1_tx", + "f4": "pwm4_a" }, "GPIO25": { - "f2": "uart1_rx" + "f2": "uart1_rx", + "f4": "pwm4_b" }, "GPIO26": { - "f11": "uart1_tx" + "analog": "adc_in0", + "f11": "uart1_tx", + "f4": "pwm5_a" }, "GPIO27": { - "f11": "uart1_rx" + "analog": "adc_in1", + "f11": "uart1_rx", + "f4": "pwm5_b" }, "GPIO28": { - "f2": "uart0_tx" + "analog": "adc_in2", + "f2": "uart0_tx", + "f4": "pwm6_a" }, "GPIO29": { - "f2": "uart0_rx" + "analog": "adc_in3", + "f2": "uart0_rx", + "f4": "pwm6_b" }, "GPIO3": { - "f11": "uart0_rx" + "f11": "uart0_rx", + "f4": "pwm1_b" }, "GPIO4": { - "f2": "uart1_tx" + "f2": "uart1_tx", + "f4": "pwm2_a" }, "GPIO5": { - "f2": "uart1_rx" + "f2": "uart1_rx", + "f4": "pwm2_b" }, "GPIO6": { "f11": "uart1_tx", - "f3": "i2c1_sda" + "f3": "i2c1_sda", + "f4": "pwm3_a" }, "GPIO7": { "f11": "uart1_rx", - "f3": "i2c1_scl" + "f3": "i2c1_scl", + "f4": "pwm3_b" }, "GPIO8": { "f2": "uart1_tx", - "f3": "i2c0_sda" + "f3": "i2c0_sda", + "f4": "pwm4_a" }, "GPIO9": { "f2": "uart1_rx", - "f3": "i2c0_scl" + "f3": "i2c0_scl", + "f4": "pwm4_b" } }, "arch": { @@ -760,6 +959,33 @@ 750000000, 1600000000 ] + }, + { + "inputs": [ + "xosc" + ], + "m": [ + 1, + 63 + ], + "n": [ + 16, + 320 + ], + "name": "pll_usb", + "output_hz": 48000000, + "postdiv": [ + 1, + 7 + ], + "vco_in_hz": [ + 5000000, + 800000000 + ], + "vco_out_hz": [ + 750000000, + 1600000000 + ] } ], "sources": [ @@ -908,6 +1134,12 @@ "name": "pll_sys", "size": 16384 }, + { + "base": 1074102272, + "compatible": "rpi,rp2350-pll", + "name": "pll_usb", + "size": 16384 + }, { "base": 1074200576, "compatible": "arm,pl011", @@ -1093,6 +1325,213 @@ "compatible": "rpi,rp2350-sio", "name": "sio", "size": 4096 + }, + { + "adc": { + "bits": 12, + "inputs": 4, + "temperature": 4 + }, + "base": 1074397184, + "clocked_by": "pll_usb", + "compatible": "rpi,rp2350-adc", + "dma_requests": { + "rx": "dma.dreq48" + }, + "irqs": [ + { + "name": "fifo", + "number": 35 + } + ], + "name": "adc", + "size": 16384 + }, + { + "base": 1074430192, + "compatible": "rpi,rp2350-pwm-irq", + "irqs": [ + { + "name": "wrap0", + "number": 8 + }, + { + "name": "wrap1", + "number": 9 + } + ], + "name": "pwm", + "size": 32 + }, + { + "base": 1074429952, + "compatible": "rpi,rp2350-pwm", + "counter_bits": 16, + "dma_requests": { + "wrap": "dma.dreq32" + }, + "name": "pwm0", + "size": 20 + }, + { + "base": 1074429972, + "compatible": "rpi,rp2350-pwm", + "counter_bits": 16, + "dma_requests": { + "wrap": "dma.dreq33" + }, + "name": "pwm1", + "size": 20 + }, + { + "base": 1074429992, + "compatible": "rpi,rp2350-pwm", + "counter_bits": 16, + "dma_requests": { + "wrap": "dma.dreq34" + }, + "name": "pwm2", + "size": 20 + }, + { + "base": 1074430012, + "compatible": "rpi,rp2350-pwm", + "counter_bits": 16, + "dma_requests": { + "wrap": "dma.dreq35" + }, + "name": "pwm3", + "size": 20 + }, + { + "base": 1074430032, + "compatible": "rpi,rp2350-pwm", + "counter_bits": 16, + "dma_requests": { + "wrap": "dma.dreq36" + }, + "name": "pwm4", + "size": 20 + }, + { + "base": 1074430052, + "compatible": "rpi,rp2350-pwm", + "counter_bits": 16, + "dma_requests": { + "wrap": "dma.dreq37" + }, + "name": "pwm5", + "size": 20 + }, + { + "base": 1074430072, + "compatible": "rpi,rp2350-pwm", + "counter_bits": 16, + "dma_requests": { + "wrap": "dma.dreq38" + }, + "name": "pwm6", + "size": 20 + }, + { + "base": 1074430092, + "compatible": "rpi,rp2350-pwm", + "counter_bits": 16, + "dma_requests": { + "wrap": "dma.dreq39" + }, + "name": "pwm7", + "size": 20 + }, + { + "base": 1074430112, + "compatible": "rpi,rp2350-pwm", + "counter_bits": 16, + "dma_requests": { + "wrap": "dma.dreq40" + }, + "name": "pwm8", + "size": 20 + }, + { + "base": 1074430132, + "compatible": "rpi,rp2350-pwm", + "counter_bits": 16, + "dma_requests": { + "wrap": "dma.dreq41" + }, + "name": "pwm9", + "size": 20 + }, + { + "base": 1074430152, + "compatible": "rpi,rp2350-pwm", + "counter_bits": 16, + "dma_requests": { + "wrap": "dma.dreq42" + }, + "name": "pwm10", + "size": 20 + }, + { + "base": 1074430172, + "compatible": "rpi,rp2350-pwm", + "counter_bits": 16, + "dma_requests": { + "wrap": "dma.dreq43" + }, + "name": "pwm11", + "size": 20 + }, + { + "base": 1074462720, + "compatible": "rpi,rp2350-timer", + "counter_bits": 64, + "irqs": [ + { + "name": "alarm0", + "number": 0 + }, + { + "name": "alarm1", + "number": 1 + }, + { + "name": "alarm2", + "number": 2 + }, + { + "name": "alarm3", + "number": 3 + } + ], + "name": "timer0", + "size": 16384 + }, + { + "base": 1074495488, + "compatible": "rpi,rp2350-timer", + "counter_bits": 64, + "irqs": [ + { + "name": "alarm0", + "number": 4 + }, + { + "name": "alarm1", + "number": 5 + }, + { + "name": "alarm2", + "number": 6 + }, + { + "name": "alarm3", + "number": 7 + } + ], + "name": "timer1", + "size": 16384 } ], "schema_version": 0, diff --git a/boards/rpi/pico2_w/generated/include/hw_config.h b/boards/rpi/pico2_w/generated/include/hw_config.h index a12d0367..676653de 100644 --- a/boards/rpi/pico2_w/generated/include/hw_config.h +++ b/boards/rpi/pico2_w/generated/include/hw_config.h @@ -15,13 +15,13 @@ * arch/cortex_m/arch.yaml * c5c8e451c09717dee1713d07f8311b6d507e3b4c66c42d93e0ce11da6ec76d6d * boards/rpi/pico2_w/board.yaml - * dad0ef7259e41ef3bd8fa07ea1c1f36040254a443deaf30d963b4fb14b5354a0 + * 345279a53c444bc45e7fcc1a0cb5ab47b32a7699534f5484ea80d73f7a0bdf6d * drivers/bindings.yaml - * d3c336ac05548e0addd1faac18f3dff70576d8069f11d89e6a761cf5c6132b49 + * c06d1a914adb21d0e314c79b3611ac6859eefeac1957d6914cccfc5531ad6ede * soc/rpi/rp2350/rp2350.yaml - * 9e60e99ecac8782bccd69e3bd69014af1d8891d6b6fbd822acff5bd9a526d8cd + * 80773a9c9cfb1c62cd322e397111a11d7f48fce3c0febc76bf7d5571018977a5 * soc/rpi/rp2350/rp2350a.yaml - * 045cef7794c3b6c6d2ff48ba294c6308d00fe13bc65e346f2ba2ccde1cea24ff + * 22395e35ed229020b5c9c7586af50cfaa07960a09905776eb4713ff28051eb3c */ #ifndef HW_CONFIG_H #define HW_CONFIG_H @@ -32,17 +32,22 @@ #define EMB_HW_SOC_PACKAGE "qfn60" /* clock tree (150 MHz) */ -#define EMB_HW_AHB_DIV 1u -#define EMB_HW_CPU_HZ 150000000u -#define EMB_HW_PLL_M 1u -#define EMB_HW_PLL_N 125u -#define EMB_HW_PLL_P 10u -#define EMB_HW_PLL_POSTDIV1 5u -#define EMB_HW_PLL_POSTDIV2 2u -#define EMB_HW_PLL_VCO_HZ 1500000000u -#define EMB_HW_SYS_HZ 150000000u -#define EMB_HW_XOSC_BYPASS 0 -#define EMB_HW_XOSC_HZ 12000000u +#define EMB_HW_AHB_DIV 1u +#define EMB_HW_CPU_HZ 150000000u +#define EMB_HW_PLL_M 1u +#define EMB_HW_PLL_N 125u +#define EMB_HW_PLL_P 10u +#define EMB_HW_PLL_POSTDIV1 5u +#define EMB_HW_PLL_POSTDIV2 2u +#define EMB_HW_PLL_USB_HZ 48000000u +#define EMB_HW_PLL_USB_M 1u +#define EMB_HW_PLL_USB_N 64u +#define EMB_HW_PLL_USB_POSTDIV1 4u +#define EMB_HW_PLL_USB_POSTDIV2 4u +#define EMB_HW_PLL_VCO_HZ 1500000000u +#define EMB_HW_SYS_HZ 150000000u +#define EMB_HW_XOSC_BYPASS 0 +#define EMB_HW_XOSC_HZ 12000000u /* memory regions */ #define EMB_HW_SRAM_BASE 0x20000000u @@ -57,6 +62,8 @@ #define EMB_HW_IRQ_PRIORITY_BITS 4u /* peripherals: register blocks, interrupt lines, clock gates */ +#define EMB_HW_ADC_BASE 0x400A0000u +#define EMB_HW_ADC_IRQ_FIFO 35u #define EMB_HW_BOOTRAM_BASE 0x400E0000u #define EMB_HW_CLOCKS_BASE 0x40010000u #define EMB_HW_CLOCKS_IRQ 30u @@ -73,9 +80,25 @@ #define EMB_HW_IO_BANK0_IRQ_BANK0 21u #define EMB_HW_PADS_BANK0_BASE 0x40038000u #define EMB_HW_PLL_SYS_BASE 0x40050000u +#define EMB_HW_PLL_USB_BASE 0x40058000u #define EMB_HW_POWMAN_BASE 0x40100000u #define EMB_HW_POWMAN_IRQ_TIMER 45u #define EMB_HW_PSM_BASE 0x40018000u +#define EMB_HW_PWM0_BASE 0x400A8000u +#define EMB_HW_PWM10_BASE 0x400A80C8u +#define EMB_HW_PWM11_BASE 0x400A80DCu +#define EMB_HW_PWM1_BASE 0x400A8014u +#define EMB_HW_PWM2_BASE 0x400A8028u +#define EMB_HW_PWM3_BASE 0x400A803Cu +#define EMB_HW_PWM4_BASE 0x400A8050u +#define EMB_HW_PWM5_BASE 0x400A8064u +#define EMB_HW_PWM6_BASE 0x400A8078u +#define EMB_HW_PWM7_BASE 0x400A808Cu +#define EMB_HW_PWM8_BASE 0x400A80A0u +#define EMB_HW_PWM9_BASE 0x400A80B4u +#define EMB_HW_PWM_BASE 0x400A80F0u +#define EMB_HW_PWM_IRQ_WRAP0 8u +#define EMB_HW_PWM_IRQ_WRAP1 9u #define EMB_HW_QMI_BASE 0x400D0000u #define EMB_HW_RESETS_BASE 0x40020000u #define EMB_HW_SIO_BASE 0xD0000000u @@ -84,6 +107,16 @@ #define EMB_HW_SPI1_BASE 0x40088000u #define EMB_HW_SPI1_IRQ 32u #define EMB_HW_TICKS_BASE 0x40108000u +#define EMB_HW_TIMER0_BASE 0x400B0000u +#define EMB_HW_TIMER0_IRQ_ALARM0 0u +#define EMB_HW_TIMER0_IRQ_ALARM1 1u +#define EMB_HW_TIMER0_IRQ_ALARM2 2u +#define EMB_HW_TIMER0_IRQ_ALARM3 3u +#define EMB_HW_TIMER1_BASE 0x400B8000u +#define EMB_HW_TIMER1_IRQ_ALARM0 4u +#define EMB_HW_TIMER1_IRQ_ALARM1 5u +#define EMB_HW_TIMER1_IRQ_ALARM2 6u +#define EMB_HW_TIMER1_IRQ_ALARM3 7u #define EMB_HW_TRNG_BASE 0x400F0000u #define EMB_HW_TRNG_IRQ_IRQ 39u #define EMB_HW_UART0_BASE 0x40070000u diff --git a/boards/rpi/pico2_w/generated/include/soc_devices.h b/boards/rpi/pico2_w/generated/include/soc_devices.h index 2aaa94d7..9d07d6f2 100644 --- a/boards/rpi/pico2_w/generated/include/soc_devices.h +++ b/boards/rpi/pico2_w/generated/include/soc_devices.h @@ -15,20 +15,20 @@ * arch/cortex_m/arch.yaml * c5c8e451c09717dee1713d07f8311b6d507e3b4c66c42d93e0ce11da6ec76d6d * boards/rpi/pico2_w/board.yaml - * dad0ef7259e41ef3bd8fa07ea1c1f36040254a443deaf30d963b4fb14b5354a0 + * 345279a53c444bc45e7fcc1a0cb5ab47b32a7699534f5484ea80d73f7a0bdf6d * drivers/bindings.yaml - * d3c336ac05548e0addd1faac18f3dff70576d8069f11d89e6a761cf5c6132b49 + * c06d1a914adb21d0e314c79b3611ac6859eefeac1957d6914cccfc5531ad6ede * soc/rpi/rp2350/rp2350.yaml - * 9e60e99ecac8782bccd69e3bd69014af1d8891d6b6fbd822acff5bd9a526d8cd + * 80773a9c9cfb1c62cd322e397111a11d7f48fce3c0febc76bf7d5571018977a5 * soc/rpi/rp2350/rp2350a.yaml - * 045cef7794c3b6c6d2ff48ba294c6308d00fe13bc65e346f2ba2ccde1cea24ff + * 22395e35ed229020b5c9c7586af50cfaa07960a09905776eb4713ff28051eb3c */ #ifndef EMB_SOC_DEVICES_H #define EMB_SOC_DEVICES_H #include -#define EMB_SOC_DEVICE_COUNT 12u +#define EMB_SOC_DEVICE_COUNT 16u #if CONFIG_EMB_DEVICE #include @@ -46,6 +46,10 @@ extern const emb_device_t emb_dev_trng; extern const emb_device_t emb_dev_spi1; extern const emb_device_t emb_dev_i2c0; extern const emb_device_t emb_dev_i2c1; +extern const emb_device_t emb_dev_timer1; +extern const emb_device_t emb_dev_pwm7; +extern const emb_device_t emb_dev_pwm0; +extern const emb_device_t emb_dev_adc; /* which devices the board has, for code that uses one only where it exists */ #define EMB_SOC_HAS_CLOCKS 1 @@ -60,6 +64,10 @@ extern const emb_device_t emb_dev_i2c1; #define EMB_SOC_HAS_SPI1 1 #define EMB_SOC_HAS_I2C0 1 #define EMB_SOC_HAS_I2C1 1 +#define EMB_SOC_HAS_TIMER1 1 +#define EMB_SOC_HAS_PWM7 1 +#define EMB_SOC_HAS_PWM0 1 +#define EMB_SOC_HAS_ADC 1 /* the board's watchdog device: the first of its class */ #define EMB_SOC_WATCHDOG_DEVICE (&emb_dev_watchdog) @@ -67,6 +75,11 @@ extern const emb_device_t emb_dev_i2c1; /* the board's RTC device: the first of its class */ #define EMB_SOC_RTC_DEVICE (&emb_dev_rtc) +/* the board's counters: the first of their class, and all of them (SPEC-017 §11a) */ +#define EMB_SOC_COUNTER_DEVICE (&emb_dev_timer1) +#define EMB_SOC_COUNTER_DEVICES &emb_dev_timer1 +#define EMB_SOC_COUNTER_COUNT 1u + /* the board's entropy source: the first of its class (SPEC-017 §11) */ #define EMB_SOC_ENTROPY_DEVICE (&emb_dev_trng) @@ -88,6 +101,7 @@ extern const emb_device_t emb_dev_i2c1; #define EMB_SOC_UART1_DMA_TX {&emb_dev_dma, 2u, 30u, {0u, 0u}} #define EMB_SOC_SPI1_DMA_RX {&emb_dev_dma, 1u, 27u, {0u, 0u}} #define EMB_SOC_SPI1_DMA_TX {&emb_dev_dma, 0u, 26u, {0u, 0u}} +#define EMB_SOC_ADC_DMA_RX {&emb_dev_dma, 3u, 48u, {0u, 0u}} /* clang-format on */ /* the SPI devices' chip selects (devices[].cs), emb_drv_gpio_line_t initializers; the pin diff --git a/boards/rpi/pico2_w/generated/linker/regions.ld b/boards/rpi/pico2_w/generated/linker/regions.ld index aff20354..3cf2d35e 100644 --- a/boards/rpi/pico2_w/generated/linker/regions.ld +++ b/boards/rpi/pico2_w/generated/linker/regions.ld @@ -16,13 +16,13 @@ * arch/cortex_m/arch.yaml * c5c8e451c09717dee1713d07f8311b6d507e3b4c66c42d93e0ce11da6ec76d6d * boards/rpi/pico2_w/board.yaml - * dad0ef7259e41ef3bd8fa07ea1c1f36040254a443deaf30d963b4fb14b5354a0 + * 345279a53c444bc45e7fcc1a0cb5ab47b32a7699534f5484ea80d73f7a0bdf6d * drivers/bindings.yaml - * d3c336ac05548e0addd1faac18f3dff70576d8069f11d89e6a761cf5c6132b49 + * c06d1a914adb21d0e314c79b3611ac6859eefeac1957d6914cccfc5531ad6ede * soc/rpi/rp2350/rp2350.yaml - * 9e60e99ecac8782bccd69e3bd69014af1d8891d6b6fbd822acff5bd9a526d8cd + * 80773a9c9cfb1c62cd322e397111a11d7f48fce3c0febc76bf7d5571018977a5 * soc/rpi/rp2350/rp2350a.yaml - * 045cef7794c3b6c6d2ff48ba294c6308d00fe13bc65e346f2ba2ccde1cea24ff + * 22395e35ed229020b5c9c7586af50cfaa07960a09905776eb4713ff28051eb3c */ ENTRY(embn_cm_reset) diff --git a/boards/rpi/pico2_w/generated/src/board_pins.c b/boards/rpi/pico2_w/generated/src/board_pins.c index 6c6b3c90..1b188dee 100644 --- a/boards/rpi/pico2_w/generated/src/board_pins.c +++ b/boards/rpi/pico2_w/generated/src/board_pins.c @@ -18,13 +18,13 @@ * arch/cortex_m/arch.yaml * c5c8e451c09717dee1713d07f8311b6d507e3b4c66c42d93e0ce11da6ec76d6d * boards/rpi/pico2_w/board.yaml - * dad0ef7259e41ef3bd8fa07ea1c1f36040254a443deaf30d963b4fb14b5354a0 + * 345279a53c444bc45e7fcc1a0cb5ab47b32a7699534f5484ea80d73f7a0bdf6d * drivers/bindings.yaml - * d3c336ac05548e0addd1faac18f3dff70576d8069f11d89e6a761cf5c6132b49 + * c06d1a914adb21d0e314c79b3611ac6859eefeac1957d6914cccfc5531ad6ede * soc/rpi/rp2350/rp2350.yaml - * 9e60e99ecac8782bccd69e3bd69014af1d8891d6b6fbd822acff5bd9a526d8cd + * 80773a9c9cfb1c62cd322e397111a11d7f48fce3c0febc76bf7d5571018977a5 * soc/rpi/rp2350/rp2350a.yaml - * 045cef7794c3b6c6d2ff48ba294c6308d00fe13bc65e346f2ba2ccde1cea24ff + * 22395e35ed229020b5c9c7586af50cfaa07960a09905776eb4713ff28051eb3c */ #include #include @@ -54,6 +54,14 @@ const emb_rp2350_pin_t emb_board_pins[] = { {12u, 1u, 1u, EMB_RP2350_PULL_RESET, EMB_RP2350_OUT_NONE}, /* GPIO13: devices.spi1.cs[0] (spi1_cs0) */ {13u, 5u, 1u, EMB_RP2350_PULL_RESET, EMB_RP2350_OUT_HIGH}, + /* GPIO14: pins.pwm7.a (pwm7_a) */ + {14u, 4u, 1u, EMB_RP2350_PULL_RESET, EMB_RP2350_OUT_NONE}, + /* GPIO17: pins.pwm0.b (pwm0_b) */ + {17u, 4u, 1u, EMB_RP2350_PULL_RESET, EMB_RP2350_OUT_NONE}, + /* GPIO26: pins.adc.in0 (adc_in0) */ + {26u, 31u, 0u, EMB_RP2350_PULL_NONE, EMB_RP2350_OUT_NONE}, + /* GPIO27: pins.adc.in1 (adc_in1) */ + {27u, 31u, 0u, EMB_RP2350_PULL_NONE, EMB_RP2350_OUT_NONE}, }; const unsigned emb_board_pin_count = (unsigned)(sizeof(emb_board_pins) / sizeof(emb_board_pins[0])); diff --git a/boards/rpi/pico2_w/generated/src/boot_block.c b/boards/rpi/pico2_w/generated/src/boot_block.c index b6abf30f..d464b75b 100644 --- a/boards/rpi/pico2_w/generated/src/boot_block.c +++ b/boards/rpi/pico2_w/generated/src/boot_block.c @@ -15,13 +15,13 @@ * arch/cortex_m/arch.yaml * c5c8e451c09717dee1713d07f8311b6d507e3b4c66c42d93e0ce11da6ec76d6d * boards/rpi/pico2_w/board.yaml - * dad0ef7259e41ef3bd8fa07ea1c1f36040254a443deaf30d963b4fb14b5354a0 + * 345279a53c444bc45e7fcc1a0cb5ab47b32a7699534f5484ea80d73f7a0bdf6d * drivers/bindings.yaml - * d3c336ac05548e0addd1faac18f3dff70576d8069f11d89e6a761cf5c6132b49 + * c06d1a914adb21d0e314c79b3611ac6859eefeac1957d6914cccfc5531ad6ede * soc/rpi/rp2350/rp2350.yaml - * 9e60e99ecac8782bccd69e3bd69014af1d8891d6b6fbd822acff5bd9a526d8cd + * 80773a9c9cfb1c62cd322e397111a11d7f48fce3c0febc76bf7d5571018977a5 * soc/rpi/rp2350/rp2350a.yaml - * 045cef7794c3b6c6d2ff48ba294c6308d00fe13bc65e346f2ba2ccde1cea24ff + * 22395e35ed229020b5c9c7586af50cfaa07960a09905776eb4713ff28051eb3c */ #include diff --git a/boards/rpi/pico2_w/generated/src/soc_devices.c b/boards/rpi/pico2_w/generated/src/soc_devices.c index 43f60687..6cc3b0b9 100644 --- a/boards/rpi/pico2_w/generated/src/soc_devices.c +++ b/boards/rpi/pico2_w/generated/src/soc_devices.c @@ -16,13 +16,13 @@ * arch/cortex_m/arch.yaml * c5c8e451c09717dee1713d07f8311b6d507e3b4c66c42d93e0ce11da6ec76d6d * boards/rpi/pico2_w/board.yaml - * dad0ef7259e41ef3bd8fa07ea1c1f36040254a443deaf30d963b4fb14b5354a0 + * 345279a53c444bc45e7fcc1a0cb5ab47b32a7699534f5484ea80d73f7a0bdf6d * drivers/bindings.yaml - * d3c336ac05548e0addd1faac18f3dff70576d8069f11d89e6a761cf5c6132b49 + * c06d1a914adb21d0e314c79b3611ac6859eefeac1957d6914cccfc5531ad6ede * soc/rpi/rp2350/rp2350.yaml - * 9e60e99ecac8782bccd69e3bd69014af1d8891d6b6fbd822acff5bd9a526d8cd + * 80773a9c9cfb1c62cd322e397111a11d7f48fce3c0febc76bf7d5571018977a5 * soc/rpi/rp2350/rp2350a.yaml - * 045cef7794c3b6c6d2ff48ba294c6308d00fe13bc65e346f2ba2ccde1cea24ff + * 22395e35ed229020b5c9c7586af50cfaa07960a09905776eb4713ff28051eb3c */ #include @@ -295,6 +295,97 @@ const emb_device_t emb_dev_i2c1 = { .dep_count = 1u, }; +/* timer1: rpi,rp2350-timer, counter, KERNEL */ +static const emb_rp2350_timer_config_t timer1_config = { + .base = 0x400B8000u, /* peripheral.base */ + .index = 1u, /* peripheral.index */ + .rate_hz = 1000000u, /* device.rate_hz, its default */ + .irq0 = 4u, /* peripheral.irqs.alarm0 */ + .irq1 = 5u, /* peripheral.irqs.alarm1 */ + .irq2 = 6u, /* peripheral.irqs.alarm2 */ + .irq3 = 7u, /* peripheral.irqs.alarm3 */ +}; +static emb_device_state_t timer1_state; +static emb_rp2350_timer_data_t timer1_data; +const emb_device_t emb_dev_timer1 = { + .name = "timer1", + .api = &emb_rp2350_timer_api.dev, + .config = &timer1_config, + .state = &timer1_state, + .data = &timer1_data, + .deps = NULL, + .class_id = EMB_DRV_CLASS_COUNTER, + .level = EMB_DEVICE_KERNEL, + .dep_count = 0u, +}; + +/* pwm7: rpi,rp2350-pwm, pwm, KERNEL */ +static const emb_rp2350_pwm_config_t pwm7_config = { + .base = 0x400A808Cu, /* peripheral.base */ + .index = 7u, /* peripheral.index */ + .clock_hz = 150000000u, /* peripheral.clock_hz */ +}; +static emb_device_state_t pwm7_state; +static emb_rp2350_pwm_data_t pwm7_data; +static const emb_device_t *const pwm7_deps[] = {&emb_dev_io_bank0}; +const emb_device_t emb_dev_pwm7 = { + .name = "pwm7", + .api = &emb_rp2350_pwm_api.dev, + .config = &pwm7_config, + .state = &pwm7_state, + .data = &pwm7_data, + .deps = pwm7_deps, + .class_id = EMB_DRV_CLASS_PWM, + .level = EMB_DEVICE_KERNEL, + .dep_count = 1u, +}; + +/* pwm0: rpi,rp2350-pwm, pwm, KERNEL */ +static const emb_rp2350_pwm_config_t pwm0_config = { + .base = 0x400A8000u, /* peripheral.base */ + .index = 0u, /* peripheral.index */ + .clock_hz = 150000000u, /* peripheral.clock_hz */ +}; +static emb_device_state_t pwm0_state; +static emb_rp2350_pwm_data_t pwm0_data; +static const emb_device_t *const pwm0_deps[] = {&emb_dev_io_bank0}; +const emb_device_t emb_dev_pwm0 = { + .name = "pwm0", + .api = &emb_rp2350_pwm_api.dev, + .config = &pwm0_config, + .state = &pwm0_state, + .data = &pwm0_data, + .deps = pwm0_deps, + .class_id = EMB_DRV_CLASS_PWM, + .level = EMB_DEVICE_KERNEL, + .dep_count = 1u, +}; + +/* adc: rpi,rp2350-adc, adc, KERNEL */ +static const emb_rp2350_adc_config_t adc_config = { + .base = 0x400A0000u, /* peripheral.base */ + .clock_hz = 48000000u, /* peripheral.clock_hz */ + .vref_mv = 3300u, /* device.vref_mv, its default */ + .bits = 12u, /* peripheral.adc.bits */ + .inputs = 4u, /* peripheral.adc.inputs */ + .temperature = 4u, /* peripheral.adc.temperature */ + .dma_rx = {&emb_dev_dma, 3u, 48u, {0u, 0u}}, /* dma.rx */ +}; +static emb_device_state_t adc_state; +static emb_rp2350_adc_data_t adc_data; +static const emb_device_t *const adc_deps[] = {&emb_dev_clocks, &emb_dev_io_bank0, &emb_dev_dma}; +const emb_device_t emb_dev_adc = { + .name = "adc", + .api = &emb_rp2350_adc_api.dev, + .config = &adc_config, + .state = &adc_state, + .data = &adc_data, + .deps = adc_deps, + .class_id = EMB_DRV_CLASS_ADC, + .level = EMB_DEVICE_KERNEL, + .dep_count = 3u, +}; + /* in initialization order */ static const emb_device_t *const devices[] = { &emb_dev_clocks, /* 0: EARLY */ @@ -309,9 +400,13 @@ static const emb_device_t *const devices[] = { &emb_dev_spi1, /* 9: KERNEL */ &emb_dev_i2c0, /* 10: KERNEL */ &emb_dev_i2c1, /* 11: KERNEL */ + &emb_dev_timer1, /* 12: KERNEL */ + &emb_dev_pwm7, /* 13: KERNEL */ + &emb_dev_pwm0, /* 14: KERNEL */ + &emb_dev_adc, /* 15: KERNEL */ }; -const emb_device_table_t emb_board_device_table = {devices, 12u, 8u}; +const emb_device_table_t emb_board_device_table = {devices, 16u, 8u}; #if CONFIG_EMB_DRV_ENTROPY /* the board's entropy source, or none: nothing stands in for one (SPEC-017 §11, SEC-012) */ diff --git a/boards/st/nucleo_f446re/board.yaml b/boards/st/nucleo_f446re/board.yaml index 3f2fb6de..1061dec8 100644 --- a/boards/st/nucleo_f446re/board.yaml +++ b/boards/st/nucleo_f446re/board.yaml @@ -31,6 +31,9 @@ pins: spi2: { sck: PB13.af5, miso: PB14.af5, mosi: PB15.af5 } # CN10-30, -28 and -26 i2c1: { scl: PB8.af4, sda: PB9.af4 } # D15 and D14 i2c2: { scl: PB10.af4, sda: PB3.af4 } # D6 and D3 + tim3: { ch1: PA6.af2 } # D12: PWM out + tim4: { ch1: PB6.af2 } # D10: PWM capture + adc1: { in4: PA4, in8: PB0 } # A2 and A3 console: { device: usart2, baud: 115200 } # the board's devices (SPEC-016), initialized with the EARLY devices: the clock tree, the # GPIO ports in use and the console @@ -41,6 +44,7 @@ devices: - { name: rtc, doc: "the RTC on the LSE crystal (X2); no battery on VBAT, so lost with power" } - { name: flash, peripheral: flash_if, doc: "the 512 KiB flash: its storage partition is the tests' (sector 7)" } - { name: dma1, doc: "DMA1: SPI2's transfers, and the console's writes" } + - { name: dma2, doc: "DMA2: ADC1's samples" } - { name: gpiob, doc: "SPI2's chip select, PB12" } - { name: gpioc, doc: B1 } - { name: usart2, baud: 115200, dma: [tx], doc: "the console, the ST-LINK's virtual COM port; its writes by DMA1 stream 6" } @@ -48,6 +52,11 @@ devices: - { name: i2c1, doc: "I2C1 on D15 (PB8, SCL) and D14 (PB9, SDA); the HIL suite wires it to I2C2" } - { name: i2c2, doc: "I2C2 on D6 (PB10, SCL) and D3 (PB3, SDA), the HIL suite's target for I2C1" } - { name: uart4, baud: 115200, doc: "a spare UART; the HIL suite's loopback wires A0 (PA0, TX) to A1 (PA1, RX)" } + - { name: tim5, class: counter, doc: "TIM5, 32 bits at 1 MHz: the counter class's (A129); TIM2 stays the controller's ADC trigger" } + - { name: tim9, class: counter, doc: "TIM9, 16 bits at 1 MHz: it wraps every 65.5 ms, so its tests widen the count on the board" } + - { name: tim3, class: pwm, doc: "TIM3, PWM out on channel 1, D12 (PA6); the HIL suite wires it to D10" } + - { name: tim4, class: pwm, doc: "TIM4, PWM capture on channel 1, D10 (PB6)" } + - { name: adc1, trigger: tim2, common: adc_common, cal: factory_cal, dma: [rx], doc: "ADC1, paced by TIM2 (the controller's trigger, which it drives by hand), A2 (PA4, input 4) and A3 (PB0, input 8); the HIL suite wires A2 to 3V3 and A3 to GND" } leds: [ { name: user, gpio: PA5, active: high, doc: LD2 } ] buttons: [ { name: user, gpio: PC13, active: low, doc: B1 } ] flash_partitions: @@ -64,4 +73,6 @@ simulation: - { device: uart4, ports: [A0, A1] } - { device: spi2, ports: [CN10_26, CN10_28] } # PB15 (MOSI) to PB14 (MISO) - { device: i2c1, peer: i2c2, nets: [[D15, D6], [D14, D3]] } # SCL to SCL, SDA to SDA + - { device: tim3, peer: tim4, channels: [0, 0], ports: [D12, D10] } # PA6 (TIM3 CH1) to PB6 (TIM4 CH1) + - { device: adc1, channels: [4, 8], nets: [[A2, 3V3], [A3, GND]] } # PA4 high, PB0 low defaults: { CONFIG_EMB_PROFILE: base, CONFIG_EMB_TICK_NS: 1000000 } diff --git a/boards/st/nucleo_f446re/generated/.base/build/CMakeLists.txt b/boards/st/nucleo_f446re/generated/.base/build/CMakeLists.txt index 4895624b..fdcb8017 100644 --- a/boards/st/nucleo_f446re/generated/.base/build/CMakeLists.txt +++ b/boards/st/nucleo_f446re/generated/.base/build/CMakeLists.txt @@ -9,13 +9,13 @@ # arch/cortex_m/arch.yaml # c5c8e451c09717dee1713d07f8311b6d507e3b4c66c42d93e0ce11da6ec76d6d # boards/st/nucleo_f446re/board.yaml -# d756f3a7f19dc7da82ee3afc168dc54946312c5a9990720953c0fedcdece54ea +# 551c524379751d359bdd87501269d6cab33edf84d212d2f6632ffe9567ec71d0 # drivers/bindings.yaml -# d3c336ac05548e0addd1faac18f3dff70576d8069f11d89e6a761cf5c6132b49 +# c06d1a914adb21d0e314c79b3611ac6859eefeac1957d6914cccfc5531ad6ede # soc/st/stm32f4/stm32f4.yaml -# 3db4a0a65c9624d865d4ed7fc6354bf95054d0c465b76a2091f06aeac3d7375f +# 796886c294250aa81151a620d80d0e43b5ee8e1bf53a07d1d7e2c62e95214dbd # soc/st/stm32f4/stm32f446.yaml -# 0d5cc7f5fce4c51be71678987720c85c6e76e05473ff8a78ea5035394316c055 +# f0c9a37f6017c87d0efe215a3561f65494ba52383f2d0c10419b0ab5035f77f2 # soc/st/stm32f4/stm32f446re.yaml # b9a88d0a94aa17ee83317a3a56f7c194ec1b3107dfb3e82e453122dc1c48f6d4 # The board has no C of its own: its SoC family's board support builds emb_board from diff --git a/boards/st/nucleo_f446re/generated/.base/build/board.cmake b/boards/st/nucleo_f446re/generated/.base/build/board.cmake index 3a9f3a9e..ad6b7bc2 100644 --- a/boards/st/nucleo_f446re/generated/.base/build/board.cmake +++ b/boards/st/nucleo_f446re/generated/.base/build/board.cmake @@ -9,13 +9,13 @@ # arch/cortex_m/arch.yaml # c5c8e451c09717dee1713d07f8311b6d507e3b4c66c42d93e0ce11da6ec76d6d # boards/st/nucleo_f446re/board.yaml -# d756f3a7f19dc7da82ee3afc168dc54946312c5a9990720953c0fedcdece54ea +# 551c524379751d359bdd87501269d6cab33edf84d212d2f6632ffe9567ec71d0 # drivers/bindings.yaml -# d3c336ac05548e0addd1faac18f3dff70576d8069f11d89e6a761cf5c6132b49 +# c06d1a914adb21d0e314c79b3611ac6859eefeac1957d6914cccfc5531ad6ede # soc/st/stm32f4/stm32f4.yaml -# 3db4a0a65c9624d865d4ed7fc6354bf95054d0c465b76a2091f06aeac3d7375f +# 796886c294250aa81151a620d80d0e43b5ee8e1bf53a07d1d7e2c62e95214dbd # soc/st/stm32f4/stm32f446.yaml -# 0d5cc7f5fce4c51be71678987720c85c6e76e05473ff8a78ea5035394316c055 +# f0c9a37f6017c87d0efe215a3561f65494ba52383f2d0c10419b0ab5035f77f2 # soc/st/stm32f4/stm32f446re.yaml # b9a88d0a94aa17ee83317a3a56f7c194ec1b3107dfb3e82e453122dc1c48f6d4 # nucleo_f446re: STM32F446RE, cortex-m4f at 180 MHz. @@ -27,6 +27,8 @@ get_filename_component(EMB_BOARD_GENERATED_DIR "${CMAKE_CURRENT_LIST_DIR}/.." AB set(EMB_BOARD_CONF "${EMB_BOARD_GENERATED_DIR}/config/board.conf") set(EMB_BOARD_HW_JSON "${EMB_BOARD_GENERATED_DIR}/docs/hw.json") set(EMB_BOARD_BUILD_DIR "${CMAKE_CURRENT_LIST_DIR}") # build/CMakeLists.txt +set(EMB_BOARD_SRC_DIR "${EMB_BOARD_GENERATED_DIR}/src") # its pin table and boot block +set(EMB_BOARD_LINKER_DIR "${EMB_BOARD_GENERATED_DIR}/linker") # the SoC family's board support and drivers build this board (build/CMakeLists.txt) set(EMB_SOC_DIR "${EMB_BASE}/soc/st/stm32f4") set(EMB_BOARD_INCLUDE_DIRS "${EMB_BOARD_GENERATED_DIR}/include" "${EMB_SOC_DIR}/include") @@ -35,9 +37,12 @@ set(EMB_BOARD_EMBSIM_TARGET emblink/nucleo_f446re) # EMB_TEST_EMULATOR=embsim set(EMB_BOARD_USART2_DMA tx) set(EMB_BOARD_SPI2_DMA rx tx) set(EMB_BOARD_SPI2_CS_COUNT 1) +set(EMB_BOARD_ADC1_DMA rx) set(EMB_BOARD_EMBSIM_UART_LOOP uart4 "A0,A1") set(EMB_BOARD_EMBSIM_SPI_LOOP spi2 "CN10_26,CN10_28") set(EMB_BOARD_EMBSIM_I2C_LOOP i2c1 i2c2 "D15,D6" "D14,D3") +set(EMB_BOARD_EMBSIM_PWM_LOOP "tim3:0,tim4:0" "D12,D10") +set(EMB_BOARD_EMBSIM_ADC_LOOP "adc1:4,8" "A2,3V3" "A3,GND") # the board's devices (soc_devices.c) and the drivers they use, and only those (SPEC-016 §8) set(EMB_BOARD_DRIVER_SOURCES "${EMB_BOARD_GENERATED_DIR}/src/soc_devices.c" @@ -49,6 +54,9 @@ set(EMB_BOARD_DRIVER_SOURCES "${EMB_BASE}/drivers/st/stm32_uart.c" "${EMB_BASE}/drivers/st/stm32_spi.c" "${EMB_BASE}/drivers/st/stm32_i2c.c" + "${EMB_BASE}/drivers/st/stm32_tim_counter.c" + "${EMB_BASE}/drivers/st/stm32_tim_pwm.c" + "${EMB_BASE}/drivers/st/stm32_adc.c" ) set(EMB_BOARD_DRIVER_INCLUDE_DIRS "${EMB_BASE}/drivers/st/include" @@ -56,9 +64,9 @@ set(EMB_BOARD_DRIVER_INCLUDE_DIRS # the inputs this directory was generated from, for the configure-time staleness check set(EMB_BOARD_HW_INPUTS "arch/cortex_m/arch.yaml=c5c8e451c09717dee1713d07f8311b6d507e3b4c66c42d93e0ce11da6ec76d6d" - "boards/st/nucleo_f446re/board.yaml=d756f3a7f19dc7da82ee3afc168dc54946312c5a9990720953c0fedcdece54ea" - "drivers/bindings.yaml=d3c336ac05548e0addd1faac18f3dff70576d8069f11d89e6a761cf5c6132b49" - "soc/st/stm32f4/stm32f4.yaml=3db4a0a65c9624d865d4ed7fc6354bf95054d0c465b76a2091f06aeac3d7375f" - "soc/st/stm32f4/stm32f446.yaml=0d5cc7f5fce4c51be71678987720c85c6e76e05473ff8a78ea5035394316c055" + "boards/st/nucleo_f446re/board.yaml=551c524379751d359bdd87501269d6cab33edf84d212d2f6632ffe9567ec71d0" + "drivers/bindings.yaml=c06d1a914adb21d0e314c79b3611ac6859eefeac1957d6914cccfc5531ad6ede" + "soc/st/stm32f4/stm32f4.yaml=796886c294250aa81151a620d80d0e43b5ee8e1bf53a07d1d7e2c62e95214dbd" + "soc/st/stm32f4/stm32f446.yaml=f0c9a37f6017c87d0efe215a3561f65494ba52383f2d0c10419b0ab5035f77f2" "soc/st/stm32f4/stm32f446re.yaml=b9a88d0a94aa17ee83317a3a56f7c194ec1b3107dfb3e82e453122dc1c48f6d4" ) diff --git a/boards/st/nucleo_f446re/generated/.base/config/board.conf b/boards/st/nucleo_f446re/generated/.base/config/board.conf index 96c260ee..993a8337 100644 --- a/boards/st/nucleo_f446re/generated/.base/config/board.conf +++ b/boards/st/nucleo_f446re/generated/.base/config/board.conf @@ -9,13 +9,13 @@ # arch/cortex_m/arch.yaml # c5c8e451c09717dee1713d07f8311b6d507e3b4c66c42d93e0ce11da6ec76d6d # boards/st/nucleo_f446re/board.yaml -# d756f3a7f19dc7da82ee3afc168dc54946312c5a9990720953c0fedcdece54ea +# 551c524379751d359bdd87501269d6cab33edf84d212d2f6632ffe9567ec71d0 # drivers/bindings.yaml -# d3c336ac05548e0addd1faac18f3dff70576d8069f11d89e6a761cf5c6132b49 +# c06d1a914adb21d0e314c79b3611ac6859eefeac1957d6914cccfc5531ad6ede # soc/st/stm32f4/stm32f4.yaml -# 3db4a0a65c9624d865d4ed7fc6354bf95054d0c465b76a2091f06aeac3d7375f +# 796886c294250aa81151a620d80d0e43b5ee8e1bf53a07d1d7e2c62e95214dbd # soc/st/stm32f4/stm32f446.yaml -# 0d5cc7f5fce4c51be71678987720c85c6e76e05473ff8a78ea5035394316c055 +# f0c9a37f6017c87d0efe215a3561f65494ba52383f2d0c10419b0ab5035f77f2 # soc/st/stm32f4/stm32f446re.yaml # b9a88d0a94aa17ee83317a3a56f7c194ec1b3107dfb3e82e453122dc1c48f6d4 # Board defaults for nucleo_f446re. Applied before the profile fragment. diff --git a/boards/st/nucleo_f446re/generated/.base/docs/board.md b/boards/st/nucleo_f446re/generated/.base/docs/board.md index d0dbb777..9ff5ae67 100644 --- a/boards/st/nucleo_f446re/generated/.base/docs/board.md +++ b/boards/st/nucleo_f446re/generated/.base/docs/board.md @@ -35,8 +35,12 @@ The STM32F446RE at 180 MHz from the PLL, its input the ST-LINK's 8 MHz MCO on PH | PA1 | `pins.uart4.rx` | af8 (uart4_rx) | | PA2 | `pins.usart2.tx` | af7 (usart2_tx) | | PA3 | `pins.usart2.rx` | af7 (usart2_rx) | +| PA4 | `pins.adc1.in4` | analog | | PA5 | `leds.user` | output | +| PA6 | `pins.tim3.ch1` | af2 (tim3_ch1) | +| PB0 | `pins.adc1.in8` | analog | | PB3 | `pins.i2c2.sda` | af4 (i2c2_sda) | +| PB6 | `pins.tim4.ch1` | af2 (tim4_ch1) | | PB8 | `pins.i2c1.scl` | af4 (i2c1_scl) | | PB9 | `pins.i2c1.sda` | af4 (i2c1_sda) | | PB10 | `pins.i2c2.scl` | af4 (i2c2_scl) | @@ -58,6 +62,7 @@ In initialization order (SPEC-016 §4). | rtc | `st,stm32f4-rtc` | rtc | EARLY | - | | flash | `st,stm32f4-flash (flash_if)` | flash | EARLY | - | | dma1 | `st,stm32-dma` | dma | EARLY | rcc | +| dma2 | `st,stm32-dma` | dma | EARLY | rcc | | gpiob | `st,stm32-gpio` | gpio | EARLY | rcc | | gpioc | `st,stm32-gpio` | gpio | EARLY | rcc | | usart2 | `st,stm32-usart` | uart | EARLY | dma1, rcc | @@ -65,6 +70,11 @@ In initialization order (SPEC-016 §4). | spi2 | `st,stm32-spi` | spi | KERNEL | dma1, rcc | | i2c1 | `st,stm32-i2c` | i2c | KERNEL | rcc | | i2c2 | `st,stm32-i2c` | i2c | KERNEL | rcc | +| tim5 | `st,stm32-tim` | counter | KERNEL | rcc | +| tim9 | `st,stm32-tim` | counter | KERNEL | rcc | +| tim3 | `st,stm32-tim` | pwm | KERNEL | rcc | +| tim4 | `st,stm32-tim` | pwm | KERNEL | rcc | +| adc1 | `st,stm32f4-adc` | adc | KERNEL | dma2, rcc | ## Interrupt lines @@ -81,7 +91,10 @@ In initialization order (SPEC-016 §4). | 16 | dma1.s5 | | 17 | dma1.s6 | | 18 | adc1.global | +| 24 | tim9.global | | 28 | tim2.global | +| 29 | tim3.global | +| 30 | tim4.global | | 31 | i2c1.ev | | 32 | i2c1.er | | 33 | i2c2.ev | @@ -92,6 +105,7 @@ In initialization order (SPEC-016 §4). | 39 | usart3.global | | 41 | rtc.alarm | | 47 | dma1.s7 | +| 50 | tim5.global | | 52 | uart4.global | | 53 | uart5.global | | 56 | dma2.s0 | @@ -115,8 +129,8 @@ Generated by emb-hwgen 0.1.0, schema v0, from: | Input | SHA-256 | |---|---| | `arch/cortex_m/arch.yaml` | `c5c8e451c09717dee1713d07f8311b6d507e3b4c66c42d93e0ce11da6ec76d6d` | -| `boards/st/nucleo_f446re/board.yaml` | `d756f3a7f19dc7da82ee3afc168dc54946312c5a9990720953c0fedcdece54ea` | -| `drivers/bindings.yaml` | `d3c336ac05548e0addd1faac18f3dff70576d8069f11d89e6a761cf5c6132b49` | -| `soc/st/stm32f4/stm32f4.yaml` | `3db4a0a65c9624d865d4ed7fc6354bf95054d0c465b76a2091f06aeac3d7375f` | -| `soc/st/stm32f4/stm32f446.yaml` | `0d5cc7f5fce4c51be71678987720c85c6e76e05473ff8a78ea5035394316c055` | +| `boards/st/nucleo_f446re/board.yaml` | `551c524379751d359bdd87501269d6cab33edf84d212d2f6632ffe9567ec71d0` | +| `drivers/bindings.yaml` | `c06d1a914adb21d0e314c79b3611ac6859eefeac1957d6914cccfc5531ad6ede` | +| `soc/st/stm32f4/stm32f4.yaml` | `796886c294250aa81151a620d80d0e43b5ee8e1bf53a07d1d7e2c62e95214dbd` | +| `soc/st/stm32f4/stm32f446.yaml` | `f0c9a37f6017c87d0efe215a3561f65494ba52383f2d0c10419b0ab5035f77f2` | | `soc/st/stm32f4/stm32f446re.yaml` | `b9a88d0a94aa17ee83317a3a56f7c194ec1b3107dfb3e82e453122dc1c48f6d4` | diff --git a/boards/st/nucleo_f446re/generated/.base/docs/build_report.md b/boards/st/nucleo_f446re/generated/.base/docs/build_report.md index a594e35f..f550d8c1 100644 --- a/boards/st/nucleo_f446re/generated/.base/docs/build_report.md +++ b/boards/st/nucleo_f446re/generated/.base/docs/build_report.md @@ -31,8 +31,8 @@ Generated by emb-hwgen 0.1.0, schema v0, from: | Input | SHA-256 | |---|---| | `arch/cortex_m/arch.yaml` | `c5c8e451c09717dee1713d07f8311b6d507e3b4c66c42d93e0ce11da6ec76d6d` | -| `boards/st/nucleo_f446re/board.yaml` | `d756f3a7f19dc7da82ee3afc168dc54946312c5a9990720953c0fedcdece54ea` | -| `drivers/bindings.yaml` | `d3c336ac05548e0addd1faac18f3dff70576d8069f11d89e6a761cf5c6132b49` | -| `soc/st/stm32f4/stm32f4.yaml` | `3db4a0a65c9624d865d4ed7fc6354bf95054d0c465b76a2091f06aeac3d7375f` | -| `soc/st/stm32f4/stm32f446.yaml` | `0d5cc7f5fce4c51be71678987720c85c6e76e05473ff8a78ea5035394316c055` | +| `boards/st/nucleo_f446re/board.yaml` | `551c524379751d359bdd87501269d6cab33edf84d212d2f6632ffe9567ec71d0` | +| `drivers/bindings.yaml` | `c06d1a914adb21d0e314c79b3611ac6859eefeac1957d6914cccfc5531ad6ede` | +| `soc/st/stm32f4/stm32f4.yaml` | `796886c294250aa81151a620d80d0e43b5ee8e1bf53a07d1d7e2c62e95214dbd` | +| `soc/st/stm32f4/stm32f446.yaml` | `f0c9a37f6017c87d0efe215a3561f65494ba52383f2d0c10419b0ab5035f77f2` | | `soc/st/stm32f4/stm32f446re.yaml` | `b9a88d0a94aa17ee83317a3a56f7c194ec1b3107dfb3e82e453122dc1c48f6d4` | diff --git a/boards/st/nucleo_f446re/generated/.base/docs/hw.json b/boards/st/nucleo_f446re/generated/.base/docs/hw.json index f22030ac..8faced20 100644 --- a/boards/st/nucleo_f446re/generated/.base/docs/hw.json +++ b/boards/st/nucleo_f446re/generated/.base/docs/hw.json @@ -57,6 +57,10 @@ "doc": "DMA1: SPI2's transfers, and the console's writes", "name": "dma1" }, + { + "doc": "DMA2: ADC1's samples", + "name": "dma2" + }, { "doc": "SPI2's chip select, PB12", "name": "gpiob" @@ -96,6 +100,36 @@ "baud": 115200, "doc": "a spare UART; the HIL suite's loopback wires A0 (PA0, TX) to A1 (PA1, RX)", "name": "uart4" + }, + { + "class": "counter", + "doc": "TIM5, 32 bits at 1 MHz: the counter class's (A129); TIM2 stays the controller's ADC trigger", + "name": "tim5" + }, + { + "class": "counter", + "doc": "TIM9, 16 bits at 1 MHz: it wraps every 65.5 ms, so its tests widen the count on the board", + "name": "tim9" + }, + { + "class": "pwm", + "doc": "TIM3, PWM out on channel 1, D12 (PA6); the HIL suite wires it to D10", + "name": "tim3" + }, + { + "class": "pwm", + "doc": "TIM4, PWM capture on channel 1, D10 (PB6)", + "name": "tim4" + }, + { + "cal": "factory_cal", + "common": "adc_common", + "dma": [ + "rx" + ], + "doc": "ADC1, paced by TIM2 (the controller's trigger, which it drives by hand), A2 (PA4, input 4) and A3 (PB0, input 8); the HIL suite wires A2 to 3V3 and A3 to GND", + "name": "adc1", + "trigger": "tim2" } ], "doc": "The STM32F446RE at 180 MHz from the PLL, its input the ST-LINK's 8 MHz MCO on PH0 in HSE bypass (solder bridges SB16 and SB50 as shipped). The console is USART2, which the ST-LINK carries as its virtual COM port.", @@ -132,6 +166,10 @@ } }, "pins": { + "adc1": { + "in4": "PA4", + "in8": "PB0" + }, "i2c1": { "scl": "PB8.af4", "sda": "PB9.af4" @@ -145,6 +183,12 @@ "mosi": "PB15.af5", "sck": "PB13.af5" }, + "tim3": { + "ch1": "PA6.af2" + }, + "tim4": { + "ch1": "PB6.af2" + }, "uart4": { "rx": "PA1.af8", "tx": "PA0.af8" @@ -186,6 +230,35 @@ ] ], "peer": "i2c2" + }, + { + "channels": [ + 0, + 0 + ], + "device": "tim3", + "peer": "tim4", + "ports": [ + "D12", + "D10" + ] + }, + { + "channels": [ + 4, + 8 + ], + "device": "adc1", + "nets": [ + [ + "A2", + "3V3" + ], + [ + "A3", + "GND" + ] + ] } ], "resets_in": [ @@ -208,8 +281,14 @@ "apb1": 45000000, "apb2": 90000000 }, + "bus_timer_hz": { + "ahb1": 180000000, + "apb1": 90000000, + "apb2": 180000000 + }, "bypass": true, "cpu_hz": 180000000, + "fixed_plls": {}, "flash_wait_states": 5, "hclk_hz": 180000000, "pclk1_div": 4, @@ -357,6 +436,30 @@ "name": "dma1", "peripheral": "dma1" }, + { + "class": "dma", + "compatible": "st,stm32-dma", + "deps": [ + "rcc" + ], + "fields": { + "base": 1073898496, + "clken_bit": 22, + "clken_offset": 48, + "irq0": 56, + "irq1": 57, + "irq2": 58, + "irq3": 59, + "irq4": 60, + "irq5": 68, + "irq6": 69, + "irq7": 70, + "memory": true + }, + "level": "early", + "name": "dma2", + "peripheral": "dma2" + }, { "class": "gpio", "compatible": "st,stm32-gpio", @@ -519,6 +622,119 @@ "level": "kernel", "name": "i2c2", "peripheral": "i2c2" + }, + { + "class": "counter", + "compatible": "st,stm32-tim", + "deps": [ + "rcc" + ], + "fields": { + "base": 1073744896, + "bits": 32, + "channels": 4, + "clken_bit": 3, + "clken_offset": 64, + "clock_hz": 90000000, + "irq": 50, + "rate_hz": 1000000 + }, + "level": "kernel", + "name": "tim5", + "peripheral": "tim5" + }, + { + "class": "counter", + "compatible": "st,stm32-tim", + "deps": [ + "rcc" + ], + "fields": { + "base": 1073823744, + "bits": 16, + "channels": 2, + "clken_bit": 16, + "clken_offset": 68, + "clock_hz": 180000000, + "irq": 24, + "rate_hz": 1000000 + }, + "level": "kernel", + "name": "tim9", + "peripheral": "tim9" + }, + { + "class": "pwm", + "compatible": "st,stm32-tim", + "deps": [ + "rcc" + ], + "fields": { + "base": 1073742848, + "bits": 16, + "channels": 4, + "clken_bit": 1, + "clken_offset": 64, + "clock_hz": 90000000, + "irq": 29 + }, + "level": "kernel", + "name": "tim3", + "peripheral": "tim3" + }, + { + "class": "pwm", + "compatible": "st,stm32-tim", + "deps": [ + "rcc" + ], + "fields": { + "base": 1073743872, + "bits": 16, + "channels": 4, + "clken_bit": 2, + "clken_offset": 64, + "clock_hz": 90000000, + "irq": 30 + }, + "level": "kernel", + "name": "tim4", + "peripheral": "tim4" + }, + { + "class": "adc", + "compatible": "st,stm32f4-adc", + "deps": [ + "dma2", + "rcc" + ], + "fields": { + "base": 1073815552, + "bits": 12, + "calibration": 536836650, + "clken_bit": 8, + "clken_offset": 68, + "clock_hz": 90000000, + "common": 1073816320, + "dma_rx": { + "dma": "dma2", + "request": 0, + "stream": 0 + }, + "inputs": 16, + "irq": 18, + "temperature": 18, + "trigger": 1073741824, + "trigger_clken_bit": 0, + "trigger_clken_offset": 64, + "trigger_hz": 90000000, + "trigger_select": 6, + "vref_mv": 3300, + "vrefint": 17 + }, + "level": "kernel", + "name": "adc1", + "peripheral": "adc1" } ], "kconfig": { @@ -608,6 +824,15 @@ "port": "A", "signal": "usart2_rx" }, + { + "gpio": "gpioa", + "mode": "analog", + "number": 4, + "owner": "pins.adc1.in4", + "pin": "PA4", + "port": "A", + "signal": "adc1_in4" + }, { "gpio": "gpioa", "mode": "output", @@ -616,6 +841,25 @@ "pin": "PA5", "port": "A" }, + { + "af": 2, + "gpio": "gpioa", + "mode": "af", + "number": 6, + "owner": "pins.tim3.ch1", + "pin": "PA6", + "port": "A", + "signal": "tim3_ch1" + }, + { + "gpio": "gpiob", + "mode": "analog", + "number": 0, + "owner": "pins.adc1.in8", + "pin": "PB0", + "port": "B", + "signal": "adc1_in8" + }, { "af": 4, "gpio": "gpiob", @@ -626,6 +870,16 @@ "port": "B", "signal": "i2c2_sda" }, + { + "af": 2, + "gpio": "gpiob", + "mode": "af", + "number": 6, + "owner": "pins.tim4.ch1", + "pin": "PB6", + "port": "B", + "signal": "tim4_ch1" + }, { "af": 4, "gpio": "gpiob", @@ -726,19 +980,19 @@ }, { "path": "boards/st/nucleo_f446re/board.yaml", - "sha256": "d756f3a7f19dc7da82ee3afc168dc54946312c5a9990720953c0fedcdece54ea" + "sha256": "551c524379751d359bdd87501269d6cab33edf84d212d2f6632ffe9567ec71d0" }, { "path": "drivers/bindings.yaml", - "sha256": "d3c336ac05548e0addd1faac18f3dff70576d8069f11d89e6a761cf5c6132b49" + "sha256": "c06d1a914adb21d0e314c79b3611ac6859eefeac1957d6914cccfc5531ad6ede" }, { "path": "soc/st/stm32f4/stm32f4.yaml", - "sha256": "3db4a0a65c9624d865d4ed7fc6354bf95054d0c465b76a2091f06aeac3d7375f" + "sha256": "796886c294250aa81151a620d80d0e43b5ee8e1bf53a07d1d7e2c62e95214dbd" }, { "path": "soc/st/stm32f4/stm32f446.yaml", - "sha256": "0d5cc7f5fce4c51be71678987720c85c6e76e05473ff8a78ea5035394316c055" + "sha256": "f0c9a37f6017c87d0efe215a3561f65494ba52383f2d0c10419b0ab5035f77f2" }, { "path": "soc/st/stm32f4/stm32f446re.yaml", @@ -749,19 +1003,49 @@ "soc": { "alternate_functions": { "PA0": { - "af8": "uart4_tx" + "af1": "tim2_ch1", + "af2": "tim5_ch1", + "af8": "uart4_tx", + "analog": "adc1_in0" }, "PA1": { - "af8": "uart4_rx" + "af1": "tim2_ch2", + "af2": "tim5_ch2", + "af8": "uart4_rx", + "analog": "adc1_in1" }, "PA10": { "af7": "usart1_rx" }, + "PA15": { + "af1": "tim2_ch1" + }, "PA2": { - "af7": "usart2_tx" + "af1": "tim2_ch3", + "af2": "tim5_ch3", + "af7": "usart2_tx", + "analog": "adc1_in2" }, "PA3": { - "af7": "usart2_rx" + "af1": "tim2_ch4", + "af2": "tim5_ch4", + "af7": "usart2_rx", + "analog": "adc1_in3" + }, + "PA4": { + "analog": "adc1_in4" + }, + "PA5": { + "af1": "tim2_ch1", + "analog": "adc1_in5" + }, + "PA6": { + "af2": "tim3_ch1", + "analog": "adc1_in6" + }, + "PA7": { + "af2": "tim3_ch2", + "analog": "adc1_in7" }, "PA8": { "af4": "i2c3_scl" @@ -769,7 +1053,16 @@ "PA9": { "af7": "usart1_tx" }, + "PB0": { + "af2": "tim3_ch3", + "analog": "adc1_in8" + }, + "PB1": { + "af2": "tim3_ch4", + "analog": "adc1_in9" + }, "PB10": { + "af1": "tim2_ch3", "af4": "i2c2_scl", "af7": "usart3_tx" }, @@ -782,26 +1075,46 @@ "PB15": { "af5": "spi2_mosi" }, + "PB2": { + "af1": "tim2_ch4" + }, "PB3": { + "af1": "tim2_ch2", "af4": "i2c2_sda" }, "PB4": { + "af2": "tim3_ch1", "af4": "i2c3_sda" }, + "PB5": { + "af2": "tim3_ch2" + }, "PB6": { + "af2": "tim4_ch1", "af4": "i2c1_scl", "af7": "usart1_tx" }, "PB7": { + "af2": "tim4_ch2", "af4": "i2c1_sda", "af7": "usart1_rx" }, "PB8": { + "af1": "tim2_ch1", + "af2": "tim4_ch3", "af4": "i2c1_scl" }, "PB9": { + "af1": "tim2_ch2", + "af2": "tim4_ch4", "af4": "i2c1_sda" }, + "PC0": { + "analog": "adc1_in10" + }, + "PC1": { + "analog": "adc1_in11" + }, "PC10": { "af7": "usart3_tx", "af8": "uart4_tx" @@ -814,16 +1127,32 @@ "af4": "i2c2_sda", "af8": "uart5_tx" }, + "PC2": { + "analog": "adc1_in12" + }, + "PC3": { + "analog": "adc1_in13" + }, + "PC4": { + "analog": "adc1_in14" + }, "PC5": { - "af7": "usart3_rx" + "af7": "usart3_rx", + "analog": "adc1_in15" }, "PC6": { + "af2": "tim3_ch1", "af8": "usart6_tx" }, "PC7": { + "af2": "tim3_ch2", "af8": "usart6_rx" }, + "PC8": { + "af2": "tim3_ch3" + }, "PC9": { + "af2": "tim3_ch4", "af4": "i2c3_sda" }, "PD2": { @@ -952,6 +1281,7 @@ "name": "lse" } ], + "timers_double_when_divided": true, "voltage_scales": [ { "max_hz": 120000000, @@ -1093,12 +1423,24 @@ "part": "STM32F446RE", "peripherals": [ { + "adc": { + "bits": 12, + "inputs": 16, + "temperature": 18, + "vrefint": 17 + }, "base": 1073815552, "clock": { "bit": 8, "bus": "apb2" }, "compatible": "st,stm32f4-adc", + "dma_requests": { + "rx": [ + "dma2.s0c0", + "dma2.s4c0" + ] + }, "irqs": [ { "name": "global", @@ -1273,12 +1615,14 @@ "size": 1024 }, { + "adc_trigger": 6, "base": 1073741824, "clock": { "bit": 0, "bus": "apb1" }, "compatible": "st,stm32-tim", + "counter_bits": 32, "irqs": [ { "name": "global", @@ -1288,6 +1632,76 @@ "name": "tim2", "size": 1024 }, + { + "adc_trigger": 8, + "base": 1073742848, + "clock": { + "bit": 1, + "bus": "apb1" + }, + "compatible": "st,stm32-tim", + "counter_bits": 16, + "irqs": [ + { + "name": "global", + "number": 29 + } + ], + "name": "tim3", + "size": 1024 + }, + { + "base": 1073743872, + "clock": { + "bit": 2, + "bus": "apb1" + }, + "compatible": "st,stm32-tim", + "counter_bits": 16, + "irqs": [ + { + "name": "global", + "number": 30 + } + ], + "name": "tim4", + "size": 1024 + }, + { + "base": 1073744896, + "clock": { + "bit": 3, + "bus": "apb1" + }, + "compatible": "st,stm32-tim", + "counter_bits": 32, + "irqs": [ + { + "name": "global", + "number": 50 + } + ], + "name": "tim5", + "size": 1024 + }, + { + "base": 1073823744, + "clock": { + "bit": 16, + "bus": "apb2" + }, + "compatible": "st,stm32-tim", + "counter_bits": 16, + "irqs": [ + { + "name": "global", + "number": 24 + } + ], + "name": "tim9", + "size": 1024, + "timer_channels": 2 + }, { "base": 1073897472, "clock": { diff --git a/boards/st/nucleo_f446re/generated/.base/include/hw_config.h b/boards/st/nucleo_f446re/generated/.base/include/hw_config.h index 4804660c..ea3f51da 100644 --- a/boards/st/nucleo_f446re/generated/.base/include/hw_config.h +++ b/boards/st/nucleo_f446re/generated/.base/include/hw_config.h @@ -15,13 +15,13 @@ * arch/cortex_m/arch.yaml * c5c8e451c09717dee1713d07f8311b6d507e3b4c66c42d93e0ce11da6ec76d6d * boards/st/nucleo_f446re/board.yaml - * d756f3a7f19dc7da82ee3afc168dc54946312c5a9990720953c0fedcdece54ea + * 551c524379751d359bdd87501269d6cab33edf84d212d2f6632ffe9567ec71d0 * drivers/bindings.yaml - * d3c336ac05548e0addd1faac18f3dff70576d8069f11d89e6a761cf5c6132b49 + * c06d1a914adb21d0e314c79b3611ac6859eefeac1957d6914cccfc5531ad6ede * soc/st/stm32f4/stm32f4.yaml - * 3db4a0a65c9624d865d4ed7fc6354bf95054d0c465b76a2091f06aeac3d7375f + * 796886c294250aa81151a620d80d0e43b5ee8e1bf53a07d1d7e2c62e95214dbd * soc/st/stm32f4/stm32f446.yaml - * 0d5cc7f5fce4c51be71678987720c85c6e76e05473ff8a78ea5035394316c055 + * f0c9a37f6017c87d0efe215a3561f65494ba52383f2d0c10419b0ab5035f77f2 * soc/st/stm32f4/stm32f446re.yaml * b9a88d0a94aa17ee83317a3a56f7c194ec1b3107dfb3e82e453122dc1c48f6d4 */ @@ -164,6 +164,22 @@ #define EMB_HW_TIM2_CLKEN_BIT 0u #define EMB_HW_TIM2_CLKEN_OFFSET 0x40u #define EMB_HW_TIM2_IRQ 28u +#define EMB_HW_TIM3_BASE 0x40000400u +#define EMB_HW_TIM3_CLKEN_BIT 1u +#define EMB_HW_TIM3_CLKEN_OFFSET 0x40u +#define EMB_HW_TIM3_IRQ 29u +#define EMB_HW_TIM4_BASE 0x40000800u +#define EMB_HW_TIM4_CLKEN_BIT 2u +#define EMB_HW_TIM4_CLKEN_OFFSET 0x40u +#define EMB_HW_TIM4_IRQ 30u +#define EMB_HW_TIM5_BASE 0x40000C00u +#define EMB_HW_TIM5_CLKEN_BIT 3u +#define EMB_HW_TIM5_CLKEN_OFFSET 0x40u +#define EMB_HW_TIM5_IRQ 50u +#define EMB_HW_TIM9_BASE 0x40014000u +#define EMB_HW_TIM9_CLKEN_BIT 16u +#define EMB_HW_TIM9_CLKEN_OFFSET 0x44u +#define EMB_HW_TIM9_IRQ 24u #define EMB_HW_UART4_BASE 0x40004C00u #define EMB_HW_UART4_CLKEN_BIT 19u #define EMB_HW_UART4_CLKEN_OFFSET 0x40u diff --git a/boards/st/nucleo_f446re/generated/.base/include/soc_devices.h b/boards/st/nucleo_f446re/generated/.base/include/soc_devices.h index 1ac8076c..8ab9a5d1 100644 --- a/boards/st/nucleo_f446re/generated/.base/include/soc_devices.h +++ b/boards/st/nucleo_f446re/generated/.base/include/soc_devices.h @@ -15,13 +15,13 @@ * arch/cortex_m/arch.yaml * c5c8e451c09717dee1713d07f8311b6d507e3b4c66c42d93e0ce11da6ec76d6d * boards/st/nucleo_f446re/board.yaml - * d756f3a7f19dc7da82ee3afc168dc54946312c5a9990720953c0fedcdece54ea + * 551c524379751d359bdd87501269d6cab33edf84d212d2f6632ffe9567ec71d0 * drivers/bindings.yaml - * d3c336ac05548e0addd1faac18f3dff70576d8069f11d89e6a761cf5c6132b49 + * c06d1a914adb21d0e314c79b3611ac6859eefeac1957d6914cccfc5531ad6ede * soc/st/stm32f4/stm32f4.yaml - * 3db4a0a65c9624d865d4ed7fc6354bf95054d0c465b76a2091f06aeac3d7375f + * 796886c294250aa81151a620d80d0e43b5ee8e1bf53a07d1d7e2c62e95214dbd * soc/st/stm32f4/stm32f446.yaml - * 0d5cc7f5fce4c51be71678987720c85c6e76e05473ff8a78ea5035394316c055 + * f0c9a37f6017c87d0efe215a3561f65494ba52383f2d0c10419b0ab5035f77f2 * soc/st/stm32f4/stm32f446re.yaml * b9a88d0a94aa17ee83317a3a56f7c194ec1b3107dfb3e82e453122dc1c48f6d4 */ @@ -30,7 +30,7 @@ #include -#define EMB_SOC_DEVICE_COUNT 13u +#define EMB_SOC_DEVICE_COUNT 19u #if CONFIG_EMB_DEVICE #include @@ -42,6 +42,7 @@ extern const emb_device_t emb_dev_iwdg; extern const emb_device_t emb_dev_rtc; extern const emb_device_t emb_dev_flash; extern const emb_device_t emb_dev_dma1; +extern const emb_device_t emb_dev_dma2; extern const emb_device_t emb_dev_gpiob; extern const emb_device_t emb_dev_gpioc; extern const emb_device_t emb_dev_usart2; @@ -49,6 +50,11 @@ extern const emb_device_t emb_dev_uart4; extern const emb_device_t emb_dev_spi2; extern const emb_device_t emb_dev_i2c1; extern const emb_device_t emb_dev_i2c2; +extern const emb_device_t emb_dev_tim5; +extern const emb_device_t emb_dev_tim9; +extern const emb_device_t emb_dev_tim3; +extern const emb_device_t emb_dev_tim4; +extern const emb_device_t emb_dev_adc1; /* which devices the board has, for code that uses one only where it exists */ #define EMB_SOC_HAS_RCC 1 @@ -57,6 +63,7 @@ extern const emb_device_t emb_dev_i2c2; #define EMB_SOC_HAS_RTC 1 #define EMB_SOC_HAS_FLASH 1 #define EMB_SOC_HAS_DMA1 1 +#define EMB_SOC_HAS_DMA2 1 #define EMB_SOC_HAS_GPIOB 1 #define EMB_SOC_HAS_GPIOC 1 #define EMB_SOC_HAS_USART2 1 @@ -64,6 +71,11 @@ extern const emb_device_t emb_dev_i2c2; #define EMB_SOC_HAS_SPI2 1 #define EMB_SOC_HAS_I2C1 1 #define EMB_SOC_HAS_I2C2 1 +#define EMB_SOC_HAS_TIM5 1 +#define EMB_SOC_HAS_TIM9 1 +#define EMB_SOC_HAS_TIM3 1 +#define EMB_SOC_HAS_TIM4 1 +#define EMB_SOC_HAS_ADC1 1 /* the board's watchdog device: the first of its class */ #define EMB_SOC_WATCHDOG_DEVICE (&emb_dev_iwdg) @@ -71,6 +83,11 @@ extern const emb_device_t emb_dev_i2c2; /* the board's RTC device: the first of its class */ #define EMB_SOC_RTC_DEVICE (&emb_dev_rtc) +/* the board's counters: the first of their class, and all of them (SPEC-017 §11a) */ +#define EMB_SOC_COUNTER_DEVICE (&emb_dev_tim5) +#define EMB_SOC_COUNTER_DEVICES &emb_dev_tim5, &emb_dev_tim9 +#define EMB_SOC_COUNTER_COUNT 2u + /* the console's UART device (the board's console:) */ #define EMB_SOC_CONSOLE_DEVICE (&emb_dev_usart2) /* its writes' DMA channel (devices[].dma, A119) */ @@ -93,6 +110,7 @@ extern const emb_device_t emb_dev_i2c2; #define EMB_SOC_USART2_DMA_TX {&emb_dev_dma1, 6u, 4u, {0u, 0u}} #define EMB_SOC_SPI2_DMA_RX {&emb_dev_dma1, 3u, 0u, {0u, 0u}} #define EMB_SOC_SPI2_DMA_TX {&emb_dev_dma1, 4u, 0u, {0u, 0u}} +#define EMB_SOC_ADC1_DMA_RX {&emb_dev_dma2, 0u, 0u, {0u, 0u}} /* clang-format on */ /* the SPI devices' chip selects (devices[].cs), emb_drv_gpio_line_t initializers; the pin diff --git a/boards/st/nucleo_f446re/generated/.base/linker/regions.ld b/boards/st/nucleo_f446re/generated/.base/linker/regions.ld index ca94b4b4..2ed8fa16 100644 --- a/boards/st/nucleo_f446re/generated/.base/linker/regions.ld +++ b/boards/st/nucleo_f446re/generated/.base/linker/regions.ld @@ -17,13 +17,13 @@ * arch/cortex_m/arch.yaml * c5c8e451c09717dee1713d07f8311b6d507e3b4c66c42d93e0ce11da6ec76d6d * boards/st/nucleo_f446re/board.yaml - * d756f3a7f19dc7da82ee3afc168dc54946312c5a9990720953c0fedcdece54ea + * 551c524379751d359bdd87501269d6cab33edf84d212d2f6632ffe9567ec71d0 * drivers/bindings.yaml - * d3c336ac05548e0addd1faac18f3dff70576d8069f11d89e6a761cf5c6132b49 + * c06d1a914adb21d0e314c79b3611ac6859eefeac1957d6914cccfc5531ad6ede * soc/st/stm32f4/stm32f4.yaml - * 3db4a0a65c9624d865d4ed7fc6354bf95054d0c465b76a2091f06aeac3d7375f + * 796886c294250aa81151a620d80d0e43b5ee8e1bf53a07d1d7e2c62e95214dbd * soc/st/stm32f4/stm32f446.yaml - * 0d5cc7f5fce4c51be71678987720c85c6e76e05473ff8a78ea5035394316c055 + * f0c9a37f6017c87d0efe215a3561f65494ba52383f2d0c10419b0ab5035f77f2 * soc/st/stm32f4/stm32f446re.yaml * b9a88d0a94aa17ee83317a3a56f7c194ec1b3107dfb3e82e453122dc1c48f6d4 */ diff --git a/boards/st/nucleo_f446re/generated/.base/src/board_pins.c b/boards/st/nucleo_f446re/generated/.base/src/board_pins.c index 6b64b344..5605d5fc 100644 --- a/boards/st/nucleo_f446re/generated/.base/src/board_pins.c +++ b/boards/st/nucleo_f446re/generated/.base/src/board_pins.c @@ -16,13 +16,13 @@ * arch/cortex_m/arch.yaml * c5c8e451c09717dee1713d07f8311b6d507e3b4c66c42d93e0ce11da6ec76d6d * boards/st/nucleo_f446re/board.yaml - * d756f3a7f19dc7da82ee3afc168dc54946312c5a9990720953c0fedcdece54ea + * 551c524379751d359bdd87501269d6cab33edf84d212d2f6632ffe9567ec71d0 * drivers/bindings.yaml - * d3c336ac05548e0addd1faac18f3dff70576d8069f11d89e6a761cf5c6132b49 + * c06d1a914adb21d0e314c79b3611ac6859eefeac1957d6914cccfc5531ad6ede * soc/st/stm32f4/stm32f4.yaml - * 3db4a0a65c9624d865d4ed7fc6354bf95054d0c465b76a2091f06aeac3d7375f + * 796886c294250aa81151a620d80d0e43b5ee8e1bf53a07d1d7e2c62e95214dbd * soc/st/stm32f4/stm32f446.yaml - * 0d5cc7f5fce4c51be71678987720c85c6e76e05473ff8a78ea5035394316c055 + * f0c9a37f6017c87d0efe215a3561f65494ba52383f2d0c10419b0ab5035f77f2 * soc/st/stm32f4/stm32f446re.yaml * b9a88d0a94aa17ee83317a3a56f7c194ec1b3107dfb3e82e453122dc1c48f6d4 */ @@ -38,10 +38,18 @@ const emb_stm32_pin_t emb_board_pins[] = { {EMB_STM32_PORT(A), 2u, EMB_STM32_PIN_AF, 7u, 0u, 0u}, /* PA3: pins.usart2.rx (usart2_rx) */ {EMB_STM32_PORT(A), 3u, EMB_STM32_PIN_AF, 7u, 0u, 0u}, + /* PA4: pins.adc1.in4 (adc1_in4) */ + {EMB_STM32_PORT(A), 4u, EMB_STM32_PIN_ANALOG, 0u, 0u, 0u}, /* PA5: leds.user (output) */ {EMB_STM32_PORT(A), 5u, EMB_STM32_PIN_OUTPUT, 0u, 0u, 0u}, + /* PA6: pins.tim3.ch1 (tim3_ch1) */ + {EMB_STM32_PORT(A), 6u, EMB_STM32_PIN_AF, 2u, 0u, 0u}, + /* PB0: pins.adc1.in8 (adc1_in8) */ + {EMB_STM32_PORT(B), 0u, EMB_STM32_PIN_ANALOG, 0u, 0u, 0u}, /* PB3: pins.i2c2.sda (i2c2_sda) */ {EMB_STM32_PORT(B), 3u, EMB_STM32_PIN_AF, 4u, 0u, EMB_STM32_PIN_I2C}, + /* PB6: pins.tim4.ch1 (tim4_ch1) */ + {EMB_STM32_PORT(B), 6u, EMB_STM32_PIN_AF, 2u, 0u, 0u}, /* PB8: pins.i2c1.scl (i2c1_scl) */ {EMB_STM32_PORT(B), 8u, EMB_STM32_PIN_AF, 4u, 0u, EMB_STM32_PIN_I2C}, /* PB9: pins.i2c1.sda (i2c1_sda) */ diff --git a/boards/st/nucleo_f446re/generated/.base/src/soc_devices.c b/boards/st/nucleo_f446re/generated/.base/src/soc_devices.c index 4ea7d019..ab473020 100644 --- a/boards/st/nucleo_f446re/generated/.base/src/soc_devices.c +++ b/boards/st/nucleo_f446re/generated/.base/src/soc_devices.c @@ -16,13 +16,13 @@ * arch/cortex_m/arch.yaml * c5c8e451c09717dee1713d07f8311b6d507e3b4c66c42d93e0ce11da6ec76d6d * boards/st/nucleo_f446re/board.yaml - * d756f3a7f19dc7da82ee3afc168dc54946312c5a9990720953c0fedcdece54ea + * 551c524379751d359bdd87501269d6cab33edf84d212d2f6632ffe9567ec71d0 * drivers/bindings.yaml - * d3c336ac05548e0addd1faac18f3dff70576d8069f11d89e6a761cf5c6132b49 + * c06d1a914adb21d0e314c79b3611ac6859eefeac1957d6914cccfc5531ad6ede * soc/st/stm32f4/stm32f4.yaml - * 3db4a0a65c9624d865d4ed7fc6354bf95054d0c465b76a2091f06aeac3d7375f + * 796886c294250aa81151a620d80d0e43b5ee8e1bf53a07d1d7e2c62e95214dbd * soc/st/stm32f4/stm32f446.yaml - * 0d5cc7f5fce4c51be71678987720c85c6e76e05473ff8a78ea5035394316c055 + * f0c9a37f6017c87d0efe215a3561f65494ba52383f2d0c10419b0ab5035f77f2 * soc/st/stm32f4/stm32f446re.yaml * b9a88d0a94aa17ee83317a3a56f7c194ec1b3107dfb3e82e453122dc1c48f6d4 */ @@ -166,6 +166,36 @@ const emb_device_t emb_dev_dma1 = { .dep_count = 1u, }; +/* dma2: st,stm32-dma, dma, EARLY */ +static const emb_stm32_dma_config_t dma2_config = { + .base = 0x40026400u, /* peripheral.base */ + .clken_offset = 0x00000030u, /* peripheral.clock.enable_offset */ + .clken_bit = 22u, /* peripheral.clock.bit */ + .irq0 = 56u, /* peripheral.irqs.s0 */ + .irq1 = 57u, /* peripheral.irqs.s1 */ + .irq2 = 58u, /* peripheral.irqs.s2 */ + .irq3 = 59u, /* peripheral.irqs.s3 */ + .irq4 = 60u, /* peripheral.irqs.s4 */ + .irq5 = 68u, /* peripheral.irqs.s5 */ + .irq6 = 69u, /* peripheral.irqs.s6 */ + .irq7 = 70u, /* peripheral.irqs.s7 */ + .memory = true, /* peripheral.dma.memory */ +}; +static emb_device_state_t dma2_state; +static emb_stm32_dma_data_t dma2_data; +static const emb_device_t *const dma2_deps[] = {&emb_dev_rcc}; +const emb_device_t emb_dev_dma2 = { + .name = "dma2", + .api = &emb_stm32_dma_api.dev, + .config = &dma2_config, + .state = &dma2_state, + .data = &dma2_data, + .deps = dma2_deps, + .class_id = EMB_DRV_CLASS_DMA, + .level = EMB_DEVICE_EARLY, + .dep_count = 1u, +}; + /* gpiob: st,stm32-gpio, gpio, EARLY */ static const emb_stm32_gpio_config_t gpiob_config = { .base = 0x40020400u, /* peripheral.base */ @@ -339,6 +369,144 @@ const emb_device_t emb_dev_i2c2 = { .dep_count = 1u, }; +/* tim5: st,stm32-tim, counter, KERNEL */ +static const emb_stm32_tim_config_t tim5_config = { + .base = 0x40000C00u, /* peripheral.base */ + .clock_hz = 90000000u, /* peripheral.timer_clock_hz */ + .rate_hz = 1000000u, /* device.rate_hz, its default */ + .clken_offset = 0x00000040u, /* peripheral.clock.enable_offset */ + .clken_bit = 3u, /* peripheral.clock.bit */ + .irq = 50u, /* peripheral.irqs.global */ + .bits = 32u, /* peripheral.counter_bits */ + .channels = 4u, /* peripheral.timer_channels, its default */ +}; +static emb_device_state_t tim5_state; +static emb_stm32_counter_data_t tim5_data; +static const emb_device_t *const tim5_deps[] = {&emb_dev_rcc}; +const emb_device_t emb_dev_tim5 = { + .name = "tim5", + .api = &emb_stm32_counter_api.dev, + .config = &tim5_config, + .state = &tim5_state, + .data = &tim5_data, + .deps = tim5_deps, + .class_id = EMB_DRV_CLASS_COUNTER, + .level = EMB_DEVICE_KERNEL, + .dep_count = 1u, +}; + +/* tim9: st,stm32-tim, counter, KERNEL */ +static const emb_stm32_tim_config_t tim9_config = { + .base = 0x40014000u, /* peripheral.base */ + .clock_hz = 180000000u, /* peripheral.timer_clock_hz */ + .rate_hz = 1000000u, /* device.rate_hz, its default */ + .clken_offset = 0x00000044u, /* peripheral.clock.enable_offset */ + .clken_bit = 16u, /* peripheral.clock.bit */ + .irq = 24u, /* peripheral.irqs.global */ + .bits = 16u, /* peripheral.counter_bits */ + .channels = 2u, /* peripheral.timer_channels */ +}; +static emb_device_state_t tim9_state; +static emb_stm32_counter_data_t tim9_data; +static const emb_device_t *const tim9_deps[] = {&emb_dev_rcc}; +const emb_device_t emb_dev_tim9 = { + .name = "tim9", + .api = &emb_stm32_counter_api.dev, + .config = &tim9_config, + .state = &tim9_state, + .data = &tim9_data, + .deps = tim9_deps, + .class_id = EMB_DRV_CLASS_COUNTER, + .level = EMB_DEVICE_KERNEL, + .dep_count = 1u, +}; + +/* tim3: st,stm32-tim, pwm, KERNEL */ +static const emb_stm32_tim_config_t tim3_config = { + .base = 0x40000400u, /* peripheral.base */ + .clock_hz = 90000000u, /* peripheral.timer_clock_hz */ + .clken_offset = 0x00000040u, /* peripheral.clock.enable_offset */ + .clken_bit = 1u, /* peripheral.clock.bit */ + .irq = 29u, /* peripheral.irqs.global */ + .bits = 16u, /* peripheral.counter_bits */ + .channels = 4u, /* peripheral.timer_channels, its default */ +}; +static emb_device_state_t tim3_state; +static emb_stm32_pwm_data_t tim3_data; +static const emb_device_t *const tim3_deps[] = {&emb_dev_rcc}; +const emb_device_t emb_dev_tim3 = { + .name = "tim3", + .api = &emb_stm32_pwm_api.dev, + .config = &tim3_config, + .state = &tim3_state, + .data = &tim3_data, + .deps = tim3_deps, + .class_id = EMB_DRV_CLASS_PWM, + .level = EMB_DEVICE_KERNEL, + .dep_count = 1u, +}; + +/* tim4: st,stm32-tim, pwm, KERNEL */ +static const emb_stm32_tim_config_t tim4_config = { + .base = 0x40000800u, /* peripheral.base */ + .clock_hz = 90000000u, /* peripheral.timer_clock_hz */ + .clken_offset = 0x00000040u, /* peripheral.clock.enable_offset */ + .clken_bit = 2u, /* peripheral.clock.bit */ + .irq = 30u, /* peripheral.irqs.global */ + .bits = 16u, /* peripheral.counter_bits */ + .channels = 4u, /* peripheral.timer_channels, its default */ +}; +static emb_device_state_t tim4_state; +static emb_stm32_pwm_data_t tim4_data; +static const emb_device_t *const tim4_deps[] = {&emb_dev_rcc}; +const emb_device_t emb_dev_tim4 = { + .name = "tim4", + .api = &emb_stm32_pwm_api.dev, + .config = &tim4_config, + .state = &tim4_state, + .data = &tim4_data, + .deps = tim4_deps, + .class_id = EMB_DRV_CLASS_PWM, + .level = EMB_DEVICE_KERNEL, + .dep_count = 1u, +}; + +/* adc1: st,stm32f4-adc, adc, KERNEL */ +static const emb_stm32_adc_config_t adc1_config = { + .base = 0x40012000u, /* peripheral.base */ + .common = 0x40012300u, /* takes.common.base */ + .calibration = 0x1FFF7A2Au, /* takes.cal.base */ + .trigger = 0x40000000u, /* takes.trigger.base */ + .trigger_hz = 90000000u, /* takes.trigger.timer_clock_hz */ + .trigger_clken_offset = 0x00000040u, /* takes.trigger.clock.enable_offset */ + .trigger_clken_bit = 0u, /* takes.trigger.clock.bit */ + .trigger_select = 6u, /* takes.trigger.adc_trigger */ + .clock_hz = 90000000u, /* peripheral.clock_hz */ + .clken_offset = 0x00000044u, /* peripheral.clock.enable_offset */ + .clken_bit = 8u, /* peripheral.clock.bit */ + .irq = 18u, /* peripheral.irqs.global */ + .vref_mv = 3300u, /* device.vref_mv, its default */ + .bits = 12u, /* peripheral.adc.bits */ + .inputs = 16u, /* peripheral.adc.inputs */ + .temperature = 18u, /* peripheral.adc.temperature */ + .vrefint = 17u, /* peripheral.adc.vrefint */ + .dma_rx = {&emb_dev_dma2, 0u, 0u, {0u, 0u}}, /* dma.rx */ +}; +static emb_device_state_t adc1_state; +static emb_stm32_adc_data_t adc1_data; +static const emb_device_t *const adc1_deps[] = {&emb_dev_dma2, &emb_dev_rcc}; +const emb_device_t emb_dev_adc1 = { + .name = "adc1", + .api = &emb_stm32_adc_api.dev, + .config = &adc1_config, + .state = &adc1_state, + .data = &adc1_data, + .deps = adc1_deps, + .class_id = EMB_DRV_CLASS_ADC, + .level = EMB_DEVICE_KERNEL, + .dep_count = 2u, +}; + /* in initialization order */ static const emb_device_t *const devices[] = { &emb_dev_rcc, /* 0: EARLY */ @@ -347,16 +515,22 @@ static const emb_device_t *const devices[] = { &emb_dev_rtc, /* 3: EARLY */ &emb_dev_flash, /* 4: EARLY */ &emb_dev_dma1, /* 5: EARLY */ - &emb_dev_gpiob, /* 6: EARLY */ - &emb_dev_gpioc, /* 7: EARLY */ - &emb_dev_usart2, /* 8: EARLY */ - &emb_dev_uart4, /* 9: EARLY */ - &emb_dev_spi2, /* 10: KERNEL */ - &emb_dev_i2c1, /* 11: KERNEL */ - &emb_dev_i2c2, /* 12: KERNEL */ + &emb_dev_dma2, /* 6: EARLY */ + &emb_dev_gpiob, /* 7: EARLY */ + &emb_dev_gpioc, /* 8: EARLY */ + &emb_dev_usart2, /* 9: EARLY */ + &emb_dev_uart4, /* 10: EARLY */ + &emb_dev_spi2, /* 11: KERNEL */ + &emb_dev_i2c1, /* 12: KERNEL */ + &emb_dev_i2c2, /* 13: KERNEL */ + &emb_dev_tim5, /* 14: KERNEL */ + &emb_dev_tim9, /* 15: KERNEL */ + &emb_dev_tim3, /* 16: KERNEL */ + &emb_dev_tim4, /* 17: KERNEL */ + &emb_dev_adc1, /* 18: KERNEL */ }; -const emb_device_table_t emb_board_device_table = {devices, 13u, 10u}; +const emb_device_table_t emb_board_device_table = {devices, 19u, 11u}; #if CONFIG_EMB_DRV_ENTROPY /* the board's entropy source, or none: nothing stands in for one (SPEC-017 §11, SEC-012) */ diff --git a/boards/st/nucleo_f446re/generated/build/CMakeLists.txt b/boards/st/nucleo_f446re/generated/build/CMakeLists.txt index 4895624b..fdcb8017 100644 --- a/boards/st/nucleo_f446re/generated/build/CMakeLists.txt +++ b/boards/st/nucleo_f446re/generated/build/CMakeLists.txt @@ -9,13 +9,13 @@ # arch/cortex_m/arch.yaml # c5c8e451c09717dee1713d07f8311b6d507e3b4c66c42d93e0ce11da6ec76d6d # boards/st/nucleo_f446re/board.yaml -# d756f3a7f19dc7da82ee3afc168dc54946312c5a9990720953c0fedcdece54ea +# 551c524379751d359bdd87501269d6cab33edf84d212d2f6632ffe9567ec71d0 # drivers/bindings.yaml -# d3c336ac05548e0addd1faac18f3dff70576d8069f11d89e6a761cf5c6132b49 +# c06d1a914adb21d0e314c79b3611ac6859eefeac1957d6914cccfc5531ad6ede # soc/st/stm32f4/stm32f4.yaml -# 3db4a0a65c9624d865d4ed7fc6354bf95054d0c465b76a2091f06aeac3d7375f +# 796886c294250aa81151a620d80d0e43b5ee8e1bf53a07d1d7e2c62e95214dbd # soc/st/stm32f4/stm32f446.yaml -# 0d5cc7f5fce4c51be71678987720c85c6e76e05473ff8a78ea5035394316c055 +# f0c9a37f6017c87d0efe215a3561f65494ba52383f2d0c10419b0ab5035f77f2 # soc/st/stm32f4/stm32f446re.yaml # b9a88d0a94aa17ee83317a3a56f7c194ec1b3107dfb3e82e453122dc1c48f6d4 # The board has no C of its own: its SoC family's board support builds emb_board from diff --git a/boards/st/nucleo_f446re/generated/build/board.cmake b/boards/st/nucleo_f446re/generated/build/board.cmake index 3a9f3a9e..ad6b7bc2 100644 --- a/boards/st/nucleo_f446re/generated/build/board.cmake +++ b/boards/st/nucleo_f446re/generated/build/board.cmake @@ -9,13 +9,13 @@ # arch/cortex_m/arch.yaml # c5c8e451c09717dee1713d07f8311b6d507e3b4c66c42d93e0ce11da6ec76d6d # boards/st/nucleo_f446re/board.yaml -# d756f3a7f19dc7da82ee3afc168dc54946312c5a9990720953c0fedcdece54ea +# 551c524379751d359bdd87501269d6cab33edf84d212d2f6632ffe9567ec71d0 # drivers/bindings.yaml -# d3c336ac05548e0addd1faac18f3dff70576d8069f11d89e6a761cf5c6132b49 +# c06d1a914adb21d0e314c79b3611ac6859eefeac1957d6914cccfc5531ad6ede # soc/st/stm32f4/stm32f4.yaml -# 3db4a0a65c9624d865d4ed7fc6354bf95054d0c465b76a2091f06aeac3d7375f +# 796886c294250aa81151a620d80d0e43b5ee8e1bf53a07d1d7e2c62e95214dbd # soc/st/stm32f4/stm32f446.yaml -# 0d5cc7f5fce4c51be71678987720c85c6e76e05473ff8a78ea5035394316c055 +# f0c9a37f6017c87d0efe215a3561f65494ba52383f2d0c10419b0ab5035f77f2 # soc/st/stm32f4/stm32f446re.yaml # b9a88d0a94aa17ee83317a3a56f7c194ec1b3107dfb3e82e453122dc1c48f6d4 # nucleo_f446re: STM32F446RE, cortex-m4f at 180 MHz. @@ -27,6 +27,8 @@ get_filename_component(EMB_BOARD_GENERATED_DIR "${CMAKE_CURRENT_LIST_DIR}/.." AB set(EMB_BOARD_CONF "${EMB_BOARD_GENERATED_DIR}/config/board.conf") set(EMB_BOARD_HW_JSON "${EMB_BOARD_GENERATED_DIR}/docs/hw.json") set(EMB_BOARD_BUILD_DIR "${CMAKE_CURRENT_LIST_DIR}") # build/CMakeLists.txt +set(EMB_BOARD_SRC_DIR "${EMB_BOARD_GENERATED_DIR}/src") # its pin table and boot block +set(EMB_BOARD_LINKER_DIR "${EMB_BOARD_GENERATED_DIR}/linker") # the SoC family's board support and drivers build this board (build/CMakeLists.txt) set(EMB_SOC_DIR "${EMB_BASE}/soc/st/stm32f4") set(EMB_BOARD_INCLUDE_DIRS "${EMB_BOARD_GENERATED_DIR}/include" "${EMB_SOC_DIR}/include") @@ -35,9 +37,12 @@ set(EMB_BOARD_EMBSIM_TARGET emblink/nucleo_f446re) # EMB_TEST_EMULATOR=embsim set(EMB_BOARD_USART2_DMA tx) set(EMB_BOARD_SPI2_DMA rx tx) set(EMB_BOARD_SPI2_CS_COUNT 1) +set(EMB_BOARD_ADC1_DMA rx) set(EMB_BOARD_EMBSIM_UART_LOOP uart4 "A0,A1") set(EMB_BOARD_EMBSIM_SPI_LOOP spi2 "CN10_26,CN10_28") set(EMB_BOARD_EMBSIM_I2C_LOOP i2c1 i2c2 "D15,D6" "D14,D3") +set(EMB_BOARD_EMBSIM_PWM_LOOP "tim3:0,tim4:0" "D12,D10") +set(EMB_BOARD_EMBSIM_ADC_LOOP "adc1:4,8" "A2,3V3" "A3,GND") # the board's devices (soc_devices.c) and the drivers they use, and only those (SPEC-016 §8) set(EMB_BOARD_DRIVER_SOURCES "${EMB_BOARD_GENERATED_DIR}/src/soc_devices.c" @@ -49,6 +54,9 @@ set(EMB_BOARD_DRIVER_SOURCES "${EMB_BASE}/drivers/st/stm32_uart.c" "${EMB_BASE}/drivers/st/stm32_spi.c" "${EMB_BASE}/drivers/st/stm32_i2c.c" + "${EMB_BASE}/drivers/st/stm32_tim_counter.c" + "${EMB_BASE}/drivers/st/stm32_tim_pwm.c" + "${EMB_BASE}/drivers/st/stm32_adc.c" ) set(EMB_BOARD_DRIVER_INCLUDE_DIRS "${EMB_BASE}/drivers/st/include" @@ -56,9 +64,9 @@ set(EMB_BOARD_DRIVER_INCLUDE_DIRS # the inputs this directory was generated from, for the configure-time staleness check set(EMB_BOARD_HW_INPUTS "arch/cortex_m/arch.yaml=c5c8e451c09717dee1713d07f8311b6d507e3b4c66c42d93e0ce11da6ec76d6d" - "boards/st/nucleo_f446re/board.yaml=d756f3a7f19dc7da82ee3afc168dc54946312c5a9990720953c0fedcdece54ea" - "drivers/bindings.yaml=d3c336ac05548e0addd1faac18f3dff70576d8069f11d89e6a761cf5c6132b49" - "soc/st/stm32f4/stm32f4.yaml=3db4a0a65c9624d865d4ed7fc6354bf95054d0c465b76a2091f06aeac3d7375f" - "soc/st/stm32f4/stm32f446.yaml=0d5cc7f5fce4c51be71678987720c85c6e76e05473ff8a78ea5035394316c055" + "boards/st/nucleo_f446re/board.yaml=551c524379751d359bdd87501269d6cab33edf84d212d2f6632ffe9567ec71d0" + "drivers/bindings.yaml=c06d1a914adb21d0e314c79b3611ac6859eefeac1957d6914cccfc5531ad6ede" + "soc/st/stm32f4/stm32f4.yaml=796886c294250aa81151a620d80d0e43b5ee8e1bf53a07d1d7e2c62e95214dbd" + "soc/st/stm32f4/stm32f446.yaml=f0c9a37f6017c87d0efe215a3561f65494ba52383f2d0c10419b0ab5035f77f2" "soc/st/stm32f4/stm32f446re.yaml=b9a88d0a94aa17ee83317a3a56f7c194ec1b3107dfb3e82e453122dc1c48f6d4" ) diff --git a/boards/st/nucleo_f446re/generated/config/board.conf b/boards/st/nucleo_f446re/generated/config/board.conf index 96c260ee..993a8337 100644 --- a/boards/st/nucleo_f446re/generated/config/board.conf +++ b/boards/st/nucleo_f446re/generated/config/board.conf @@ -9,13 +9,13 @@ # arch/cortex_m/arch.yaml # c5c8e451c09717dee1713d07f8311b6d507e3b4c66c42d93e0ce11da6ec76d6d # boards/st/nucleo_f446re/board.yaml -# d756f3a7f19dc7da82ee3afc168dc54946312c5a9990720953c0fedcdece54ea +# 551c524379751d359bdd87501269d6cab33edf84d212d2f6632ffe9567ec71d0 # drivers/bindings.yaml -# d3c336ac05548e0addd1faac18f3dff70576d8069f11d89e6a761cf5c6132b49 +# c06d1a914adb21d0e314c79b3611ac6859eefeac1957d6914cccfc5531ad6ede # soc/st/stm32f4/stm32f4.yaml -# 3db4a0a65c9624d865d4ed7fc6354bf95054d0c465b76a2091f06aeac3d7375f +# 796886c294250aa81151a620d80d0e43b5ee8e1bf53a07d1d7e2c62e95214dbd # soc/st/stm32f4/stm32f446.yaml -# 0d5cc7f5fce4c51be71678987720c85c6e76e05473ff8a78ea5035394316c055 +# f0c9a37f6017c87d0efe215a3561f65494ba52383f2d0c10419b0ab5035f77f2 # soc/st/stm32f4/stm32f446re.yaml # b9a88d0a94aa17ee83317a3a56f7c194ec1b3107dfb3e82e453122dc1c48f6d4 # Board defaults for nucleo_f446re. Applied before the profile fragment. diff --git a/boards/st/nucleo_f446re/generated/docs/board.md b/boards/st/nucleo_f446re/generated/docs/board.md index d0dbb777..9ff5ae67 100644 --- a/boards/st/nucleo_f446re/generated/docs/board.md +++ b/boards/st/nucleo_f446re/generated/docs/board.md @@ -35,8 +35,12 @@ The STM32F446RE at 180 MHz from the PLL, its input the ST-LINK's 8 MHz MCO on PH | PA1 | `pins.uart4.rx` | af8 (uart4_rx) | | PA2 | `pins.usart2.tx` | af7 (usart2_tx) | | PA3 | `pins.usart2.rx` | af7 (usart2_rx) | +| PA4 | `pins.adc1.in4` | analog | | PA5 | `leds.user` | output | +| PA6 | `pins.tim3.ch1` | af2 (tim3_ch1) | +| PB0 | `pins.adc1.in8` | analog | | PB3 | `pins.i2c2.sda` | af4 (i2c2_sda) | +| PB6 | `pins.tim4.ch1` | af2 (tim4_ch1) | | PB8 | `pins.i2c1.scl` | af4 (i2c1_scl) | | PB9 | `pins.i2c1.sda` | af4 (i2c1_sda) | | PB10 | `pins.i2c2.scl` | af4 (i2c2_scl) | @@ -58,6 +62,7 @@ In initialization order (SPEC-016 §4). | rtc | `st,stm32f4-rtc` | rtc | EARLY | - | | flash | `st,stm32f4-flash (flash_if)` | flash | EARLY | - | | dma1 | `st,stm32-dma` | dma | EARLY | rcc | +| dma2 | `st,stm32-dma` | dma | EARLY | rcc | | gpiob | `st,stm32-gpio` | gpio | EARLY | rcc | | gpioc | `st,stm32-gpio` | gpio | EARLY | rcc | | usart2 | `st,stm32-usart` | uart | EARLY | dma1, rcc | @@ -65,6 +70,11 @@ In initialization order (SPEC-016 §4). | spi2 | `st,stm32-spi` | spi | KERNEL | dma1, rcc | | i2c1 | `st,stm32-i2c` | i2c | KERNEL | rcc | | i2c2 | `st,stm32-i2c` | i2c | KERNEL | rcc | +| tim5 | `st,stm32-tim` | counter | KERNEL | rcc | +| tim9 | `st,stm32-tim` | counter | KERNEL | rcc | +| tim3 | `st,stm32-tim` | pwm | KERNEL | rcc | +| tim4 | `st,stm32-tim` | pwm | KERNEL | rcc | +| adc1 | `st,stm32f4-adc` | adc | KERNEL | dma2, rcc | ## Interrupt lines @@ -81,7 +91,10 @@ In initialization order (SPEC-016 §4). | 16 | dma1.s5 | | 17 | dma1.s6 | | 18 | adc1.global | +| 24 | tim9.global | | 28 | tim2.global | +| 29 | tim3.global | +| 30 | tim4.global | | 31 | i2c1.ev | | 32 | i2c1.er | | 33 | i2c2.ev | @@ -92,6 +105,7 @@ In initialization order (SPEC-016 §4). | 39 | usart3.global | | 41 | rtc.alarm | | 47 | dma1.s7 | +| 50 | tim5.global | | 52 | uart4.global | | 53 | uart5.global | | 56 | dma2.s0 | @@ -115,8 +129,8 @@ Generated by emb-hwgen 0.1.0, schema v0, from: | Input | SHA-256 | |---|---| | `arch/cortex_m/arch.yaml` | `c5c8e451c09717dee1713d07f8311b6d507e3b4c66c42d93e0ce11da6ec76d6d` | -| `boards/st/nucleo_f446re/board.yaml` | `d756f3a7f19dc7da82ee3afc168dc54946312c5a9990720953c0fedcdece54ea` | -| `drivers/bindings.yaml` | `d3c336ac05548e0addd1faac18f3dff70576d8069f11d89e6a761cf5c6132b49` | -| `soc/st/stm32f4/stm32f4.yaml` | `3db4a0a65c9624d865d4ed7fc6354bf95054d0c465b76a2091f06aeac3d7375f` | -| `soc/st/stm32f4/stm32f446.yaml` | `0d5cc7f5fce4c51be71678987720c85c6e76e05473ff8a78ea5035394316c055` | +| `boards/st/nucleo_f446re/board.yaml` | `551c524379751d359bdd87501269d6cab33edf84d212d2f6632ffe9567ec71d0` | +| `drivers/bindings.yaml` | `c06d1a914adb21d0e314c79b3611ac6859eefeac1957d6914cccfc5531ad6ede` | +| `soc/st/stm32f4/stm32f4.yaml` | `796886c294250aa81151a620d80d0e43b5ee8e1bf53a07d1d7e2c62e95214dbd` | +| `soc/st/stm32f4/stm32f446.yaml` | `f0c9a37f6017c87d0efe215a3561f65494ba52383f2d0c10419b0ab5035f77f2` | | `soc/st/stm32f4/stm32f446re.yaml` | `b9a88d0a94aa17ee83317a3a56f7c194ec1b3107dfb3e82e453122dc1c48f6d4` | diff --git a/boards/st/nucleo_f446re/generated/docs/build_report.md b/boards/st/nucleo_f446re/generated/docs/build_report.md index a594e35f..f550d8c1 100644 --- a/boards/st/nucleo_f446re/generated/docs/build_report.md +++ b/boards/st/nucleo_f446re/generated/docs/build_report.md @@ -31,8 +31,8 @@ Generated by emb-hwgen 0.1.0, schema v0, from: | Input | SHA-256 | |---|---| | `arch/cortex_m/arch.yaml` | `c5c8e451c09717dee1713d07f8311b6d507e3b4c66c42d93e0ce11da6ec76d6d` | -| `boards/st/nucleo_f446re/board.yaml` | `d756f3a7f19dc7da82ee3afc168dc54946312c5a9990720953c0fedcdece54ea` | -| `drivers/bindings.yaml` | `d3c336ac05548e0addd1faac18f3dff70576d8069f11d89e6a761cf5c6132b49` | -| `soc/st/stm32f4/stm32f4.yaml` | `3db4a0a65c9624d865d4ed7fc6354bf95054d0c465b76a2091f06aeac3d7375f` | -| `soc/st/stm32f4/stm32f446.yaml` | `0d5cc7f5fce4c51be71678987720c85c6e76e05473ff8a78ea5035394316c055` | +| `boards/st/nucleo_f446re/board.yaml` | `551c524379751d359bdd87501269d6cab33edf84d212d2f6632ffe9567ec71d0` | +| `drivers/bindings.yaml` | `c06d1a914adb21d0e314c79b3611ac6859eefeac1957d6914cccfc5531ad6ede` | +| `soc/st/stm32f4/stm32f4.yaml` | `796886c294250aa81151a620d80d0e43b5ee8e1bf53a07d1d7e2c62e95214dbd` | +| `soc/st/stm32f4/stm32f446.yaml` | `f0c9a37f6017c87d0efe215a3561f65494ba52383f2d0c10419b0ab5035f77f2` | | `soc/st/stm32f4/stm32f446re.yaml` | `b9a88d0a94aa17ee83317a3a56f7c194ec1b3107dfb3e82e453122dc1c48f6d4` | diff --git a/boards/st/nucleo_f446re/generated/docs/hw.json b/boards/st/nucleo_f446re/generated/docs/hw.json index f22030ac..8faced20 100644 --- a/boards/st/nucleo_f446re/generated/docs/hw.json +++ b/boards/st/nucleo_f446re/generated/docs/hw.json @@ -57,6 +57,10 @@ "doc": "DMA1: SPI2's transfers, and the console's writes", "name": "dma1" }, + { + "doc": "DMA2: ADC1's samples", + "name": "dma2" + }, { "doc": "SPI2's chip select, PB12", "name": "gpiob" @@ -96,6 +100,36 @@ "baud": 115200, "doc": "a spare UART; the HIL suite's loopback wires A0 (PA0, TX) to A1 (PA1, RX)", "name": "uart4" + }, + { + "class": "counter", + "doc": "TIM5, 32 bits at 1 MHz: the counter class's (A129); TIM2 stays the controller's ADC trigger", + "name": "tim5" + }, + { + "class": "counter", + "doc": "TIM9, 16 bits at 1 MHz: it wraps every 65.5 ms, so its tests widen the count on the board", + "name": "tim9" + }, + { + "class": "pwm", + "doc": "TIM3, PWM out on channel 1, D12 (PA6); the HIL suite wires it to D10", + "name": "tim3" + }, + { + "class": "pwm", + "doc": "TIM4, PWM capture on channel 1, D10 (PB6)", + "name": "tim4" + }, + { + "cal": "factory_cal", + "common": "adc_common", + "dma": [ + "rx" + ], + "doc": "ADC1, paced by TIM2 (the controller's trigger, which it drives by hand), A2 (PA4, input 4) and A3 (PB0, input 8); the HIL suite wires A2 to 3V3 and A3 to GND", + "name": "adc1", + "trigger": "tim2" } ], "doc": "The STM32F446RE at 180 MHz from the PLL, its input the ST-LINK's 8 MHz MCO on PH0 in HSE bypass (solder bridges SB16 and SB50 as shipped). The console is USART2, which the ST-LINK carries as its virtual COM port.", @@ -132,6 +166,10 @@ } }, "pins": { + "adc1": { + "in4": "PA4", + "in8": "PB0" + }, "i2c1": { "scl": "PB8.af4", "sda": "PB9.af4" @@ -145,6 +183,12 @@ "mosi": "PB15.af5", "sck": "PB13.af5" }, + "tim3": { + "ch1": "PA6.af2" + }, + "tim4": { + "ch1": "PB6.af2" + }, "uart4": { "rx": "PA1.af8", "tx": "PA0.af8" @@ -186,6 +230,35 @@ ] ], "peer": "i2c2" + }, + { + "channels": [ + 0, + 0 + ], + "device": "tim3", + "peer": "tim4", + "ports": [ + "D12", + "D10" + ] + }, + { + "channels": [ + 4, + 8 + ], + "device": "adc1", + "nets": [ + [ + "A2", + "3V3" + ], + [ + "A3", + "GND" + ] + ] } ], "resets_in": [ @@ -208,8 +281,14 @@ "apb1": 45000000, "apb2": 90000000 }, + "bus_timer_hz": { + "ahb1": 180000000, + "apb1": 90000000, + "apb2": 180000000 + }, "bypass": true, "cpu_hz": 180000000, + "fixed_plls": {}, "flash_wait_states": 5, "hclk_hz": 180000000, "pclk1_div": 4, @@ -357,6 +436,30 @@ "name": "dma1", "peripheral": "dma1" }, + { + "class": "dma", + "compatible": "st,stm32-dma", + "deps": [ + "rcc" + ], + "fields": { + "base": 1073898496, + "clken_bit": 22, + "clken_offset": 48, + "irq0": 56, + "irq1": 57, + "irq2": 58, + "irq3": 59, + "irq4": 60, + "irq5": 68, + "irq6": 69, + "irq7": 70, + "memory": true + }, + "level": "early", + "name": "dma2", + "peripheral": "dma2" + }, { "class": "gpio", "compatible": "st,stm32-gpio", @@ -519,6 +622,119 @@ "level": "kernel", "name": "i2c2", "peripheral": "i2c2" + }, + { + "class": "counter", + "compatible": "st,stm32-tim", + "deps": [ + "rcc" + ], + "fields": { + "base": 1073744896, + "bits": 32, + "channels": 4, + "clken_bit": 3, + "clken_offset": 64, + "clock_hz": 90000000, + "irq": 50, + "rate_hz": 1000000 + }, + "level": "kernel", + "name": "tim5", + "peripheral": "tim5" + }, + { + "class": "counter", + "compatible": "st,stm32-tim", + "deps": [ + "rcc" + ], + "fields": { + "base": 1073823744, + "bits": 16, + "channels": 2, + "clken_bit": 16, + "clken_offset": 68, + "clock_hz": 180000000, + "irq": 24, + "rate_hz": 1000000 + }, + "level": "kernel", + "name": "tim9", + "peripheral": "tim9" + }, + { + "class": "pwm", + "compatible": "st,stm32-tim", + "deps": [ + "rcc" + ], + "fields": { + "base": 1073742848, + "bits": 16, + "channels": 4, + "clken_bit": 1, + "clken_offset": 64, + "clock_hz": 90000000, + "irq": 29 + }, + "level": "kernel", + "name": "tim3", + "peripheral": "tim3" + }, + { + "class": "pwm", + "compatible": "st,stm32-tim", + "deps": [ + "rcc" + ], + "fields": { + "base": 1073743872, + "bits": 16, + "channels": 4, + "clken_bit": 2, + "clken_offset": 64, + "clock_hz": 90000000, + "irq": 30 + }, + "level": "kernel", + "name": "tim4", + "peripheral": "tim4" + }, + { + "class": "adc", + "compatible": "st,stm32f4-adc", + "deps": [ + "dma2", + "rcc" + ], + "fields": { + "base": 1073815552, + "bits": 12, + "calibration": 536836650, + "clken_bit": 8, + "clken_offset": 68, + "clock_hz": 90000000, + "common": 1073816320, + "dma_rx": { + "dma": "dma2", + "request": 0, + "stream": 0 + }, + "inputs": 16, + "irq": 18, + "temperature": 18, + "trigger": 1073741824, + "trigger_clken_bit": 0, + "trigger_clken_offset": 64, + "trigger_hz": 90000000, + "trigger_select": 6, + "vref_mv": 3300, + "vrefint": 17 + }, + "level": "kernel", + "name": "adc1", + "peripheral": "adc1" } ], "kconfig": { @@ -608,6 +824,15 @@ "port": "A", "signal": "usart2_rx" }, + { + "gpio": "gpioa", + "mode": "analog", + "number": 4, + "owner": "pins.adc1.in4", + "pin": "PA4", + "port": "A", + "signal": "adc1_in4" + }, { "gpio": "gpioa", "mode": "output", @@ -616,6 +841,25 @@ "pin": "PA5", "port": "A" }, + { + "af": 2, + "gpio": "gpioa", + "mode": "af", + "number": 6, + "owner": "pins.tim3.ch1", + "pin": "PA6", + "port": "A", + "signal": "tim3_ch1" + }, + { + "gpio": "gpiob", + "mode": "analog", + "number": 0, + "owner": "pins.adc1.in8", + "pin": "PB0", + "port": "B", + "signal": "adc1_in8" + }, { "af": 4, "gpio": "gpiob", @@ -626,6 +870,16 @@ "port": "B", "signal": "i2c2_sda" }, + { + "af": 2, + "gpio": "gpiob", + "mode": "af", + "number": 6, + "owner": "pins.tim4.ch1", + "pin": "PB6", + "port": "B", + "signal": "tim4_ch1" + }, { "af": 4, "gpio": "gpiob", @@ -726,19 +980,19 @@ }, { "path": "boards/st/nucleo_f446re/board.yaml", - "sha256": "d756f3a7f19dc7da82ee3afc168dc54946312c5a9990720953c0fedcdece54ea" + "sha256": "551c524379751d359bdd87501269d6cab33edf84d212d2f6632ffe9567ec71d0" }, { "path": "drivers/bindings.yaml", - "sha256": "d3c336ac05548e0addd1faac18f3dff70576d8069f11d89e6a761cf5c6132b49" + "sha256": "c06d1a914adb21d0e314c79b3611ac6859eefeac1957d6914cccfc5531ad6ede" }, { "path": "soc/st/stm32f4/stm32f4.yaml", - "sha256": "3db4a0a65c9624d865d4ed7fc6354bf95054d0c465b76a2091f06aeac3d7375f" + "sha256": "796886c294250aa81151a620d80d0e43b5ee8e1bf53a07d1d7e2c62e95214dbd" }, { "path": "soc/st/stm32f4/stm32f446.yaml", - "sha256": "0d5cc7f5fce4c51be71678987720c85c6e76e05473ff8a78ea5035394316c055" + "sha256": "f0c9a37f6017c87d0efe215a3561f65494ba52383f2d0c10419b0ab5035f77f2" }, { "path": "soc/st/stm32f4/stm32f446re.yaml", @@ -749,19 +1003,49 @@ "soc": { "alternate_functions": { "PA0": { - "af8": "uart4_tx" + "af1": "tim2_ch1", + "af2": "tim5_ch1", + "af8": "uart4_tx", + "analog": "adc1_in0" }, "PA1": { - "af8": "uart4_rx" + "af1": "tim2_ch2", + "af2": "tim5_ch2", + "af8": "uart4_rx", + "analog": "adc1_in1" }, "PA10": { "af7": "usart1_rx" }, + "PA15": { + "af1": "tim2_ch1" + }, "PA2": { - "af7": "usart2_tx" + "af1": "tim2_ch3", + "af2": "tim5_ch3", + "af7": "usart2_tx", + "analog": "adc1_in2" }, "PA3": { - "af7": "usart2_rx" + "af1": "tim2_ch4", + "af2": "tim5_ch4", + "af7": "usart2_rx", + "analog": "adc1_in3" + }, + "PA4": { + "analog": "adc1_in4" + }, + "PA5": { + "af1": "tim2_ch1", + "analog": "adc1_in5" + }, + "PA6": { + "af2": "tim3_ch1", + "analog": "adc1_in6" + }, + "PA7": { + "af2": "tim3_ch2", + "analog": "adc1_in7" }, "PA8": { "af4": "i2c3_scl" @@ -769,7 +1053,16 @@ "PA9": { "af7": "usart1_tx" }, + "PB0": { + "af2": "tim3_ch3", + "analog": "adc1_in8" + }, + "PB1": { + "af2": "tim3_ch4", + "analog": "adc1_in9" + }, "PB10": { + "af1": "tim2_ch3", "af4": "i2c2_scl", "af7": "usart3_tx" }, @@ -782,26 +1075,46 @@ "PB15": { "af5": "spi2_mosi" }, + "PB2": { + "af1": "tim2_ch4" + }, "PB3": { + "af1": "tim2_ch2", "af4": "i2c2_sda" }, "PB4": { + "af2": "tim3_ch1", "af4": "i2c3_sda" }, + "PB5": { + "af2": "tim3_ch2" + }, "PB6": { + "af2": "tim4_ch1", "af4": "i2c1_scl", "af7": "usart1_tx" }, "PB7": { + "af2": "tim4_ch2", "af4": "i2c1_sda", "af7": "usart1_rx" }, "PB8": { + "af1": "tim2_ch1", + "af2": "tim4_ch3", "af4": "i2c1_scl" }, "PB9": { + "af1": "tim2_ch2", + "af2": "tim4_ch4", "af4": "i2c1_sda" }, + "PC0": { + "analog": "adc1_in10" + }, + "PC1": { + "analog": "adc1_in11" + }, "PC10": { "af7": "usart3_tx", "af8": "uart4_tx" @@ -814,16 +1127,32 @@ "af4": "i2c2_sda", "af8": "uart5_tx" }, + "PC2": { + "analog": "adc1_in12" + }, + "PC3": { + "analog": "adc1_in13" + }, + "PC4": { + "analog": "adc1_in14" + }, "PC5": { - "af7": "usart3_rx" + "af7": "usart3_rx", + "analog": "adc1_in15" }, "PC6": { + "af2": "tim3_ch1", "af8": "usart6_tx" }, "PC7": { + "af2": "tim3_ch2", "af8": "usart6_rx" }, + "PC8": { + "af2": "tim3_ch3" + }, "PC9": { + "af2": "tim3_ch4", "af4": "i2c3_sda" }, "PD2": { @@ -952,6 +1281,7 @@ "name": "lse" } ], + "timers_double_when_divided": true, "voltage_scales": [ { "max_hz": 120000000, @@ -1093,12 +1423,24 @@ "part": "STM32F446RE", "peripherals": [ { + "adc": { + "bits": 12, + "inputs": 16, + "temperature": 18, + "vrefint": 17 + }, "base": 1073815552, "clock": { "bit": 8, "bus": "apb2" }, "compatible": "st,stm32f4-adc", + "dma_requests": { + "rx": [ + "dma2.s0c0", + "dma2.s4c0" + ] + }, "irqs": [ { "name": "global", @@ -1273,12 +1615,14 @@ "size": 1024 }, { + "adc_trigger": 6, "base": 1073741824, "clock": { "bit": 0, "bus": "apb1" }, "compatible": "st,stm32-tim", + "counter_bits": 32, "irqs": [ { "name": "global", @@ -1288,6 +1632,76 @@ "name": "tim2", "size": 1024 }, + { + "adc_trigger": 8, + "base": 1073742848, + "clock": { + "bit": 1, + "bus": "apb1" + }, + "compatible": "st,stm32-tim", + "counter_bits": 16, + "irqs": [ + { + "name": "global", + "number": 29 + } + ], + "name": "tim3", + "size": 1024 + }, + { + "base": 1073743872, + "clock": { + "bit": 2, + "bus": "apb1" + }, + "compatible": "st,stm32-tim", + "counter_bits": 16, + "irqs": [ + { + "name": "global", + "number": 30 + } + ], + "name": "tim4", + "size": 1024 + }, + { + "base": 1073744896, + "clock": { + "bit": 3, + "bus": "apb1" + }, + "compatible": "st,stm32-tim", + "counter_bits": 32, + "irqs": [ + { + "name": "global", + "number": 50 + } + ], + "name": "tim5", + "size": 1024 + }, + { + "base": 1073823744, + "clock": { + "bit": 16, + "bus": "apb2" + }, + "compatible": "st,stm32-tim", + "counter_bits": 16, + "irqs": [ + { + "name": "global", + "number": 24 + } + ], + "name": "tim9", + "size": 1024, + "timer_channels": 2 + }, { "base": 1073897472, "clock": { diff --git a/boards/st/nucleo_f446re/generated/include/hw_config.h b/boards/st/nucleo_f446re/generated/include/hw_config.h index 4804660c..ea3f51da 100644 --- a/boards/st/nucleo_f446re/generated/include/hw_config.h +++ b/boards/st/nucleo_f446re/generated/include/hw_config.h @@ -15,13 +15,13 @@ * arch/cortex_m/arch.yaml * c5c8e451c09717dee1713d07f8311b6d507e3b4c66c42d93e0ce11da6ec76d6d * boards/st/nucleo_f446re/board.yaml - * d756f3a7f19dc7da82ee3afc168dc54946312c5a9990720953c0fedcdece54ea + * 551c524379751d359bdd87501269d6cab33edf84d212d2f6632ffe9567ec71d0 * drivers/bindings.yaml - * d3c336ac05548e0addd1faac18f3dff70576d8069f11d89e6a761cf5c6132b49 + * c06d1a914adb21d0e314c79b3611ac6859eefeac1957d6914cccfc5531ad6ede * soc/st/stm32f4/stm32f4.yaml - * 3db4a0a65c9624d865d4ed7fc6354bf95054d0c465b76a2091f06aeac3d7375f + * 796886c294250aa81151a620d80d0e43b5ee8e1bf53a07d1d7e2c62e95214dbd * soc/st/stm32f4/stm32f446.yaml - * 0d5cc7f5fce4c51be71678987720c85c6e76e05473ff8a78ea5035394316c055 + * f0c9a37f6017c87d0efe215a3561f65494ba52383f2d0c10419b0ab5035f77f2 * soc/st/stm32f4/stm32f446re.yaml * b9a88d0a94aa17ee83317a3a56f7c194ec1b3107dfb3e82e453122dc1c48f6d4 */ @@ -164,6 +164,22 @@ #define EMB_HW_TIM2_CLKEN_BIT 0u #define EMB_HW_TIM2_CLKEN_OFFSET 0x40u #define EMB_HW_TIM2_IRQ 28u +#define EMB_HW_TIM3_BASE 0x40000400u +#define EMB_HW_TIM3_CLKEN_BIT 1u +#define EMB_HW_TIM3_CLKEN_OFFSET 0x40u +#define EMB_HW_TIM3_IRQ 29u +#define EMB_HW_TIM4_BASE 0x40000800u +#define EMB_HW_TIM4_CLKEN_BIT 2u +#define EMB_HW_TIM4_CLKEN_OFFSET 0x40u +#define EMB_HW_TIM4_IRQ 30u +#define EMB_HW_TIM5_BASE 0x40000C00u +#define EMB_HW_TIM5_CLKEN_BIT 3u +#define EMB_HW_TIM5_CLKEN_OFFSET 0x40u +#define EMB_HW_TIM5_IRQ 50u +#define EMB_HW_TIM9_BASE 0x40014000u +#define EMB_HW_TIM9_CLKEN_BIT 16u +#define EMB_HW_TIM9_CLKEN_OFFSET 0x44u +#define EMB_HW_TIM9_IRQ 24u #define EMB_HW_UART4_BASE 0x40004C00u #define EMB_HW_UART4_CLKEN_BIT 19u #define EMB_HW_UART4_CLKEN_OFFSET 0x40u diff --git a/boards/st/nucleo_f446re/generated/include/soc_devices.h b/boards/st/nucleo_f446re/generated/include/soc_devices.h index 1ac8076c..8ab9a5d1 100644 --- a/boards/st/nucleo_f446re/generated/include/soc_devices.h +++ b/boards/st/nucleo_f446re/generated/include/soc_devices.h @@ -15,13 +15,13 @@ * arch/cortex_m/arch.yaml * c5c8e451c09717dee1713d07f8311b6d507e3b4c66c42d93e0ce11da6ec76d6d * boards/st/nucleo_f446re/board.yaml - * d756f3a7f19dc7da82ee3afc168dc54946312c5a9990720953c0fedcdece54ea + * 551c524379751d359bdd87501269d6cab33edf84d212d2f6632ffe9567ec71d0 * drivers/bindings.yaml - * d3c336ac05548e0addd1faac18f3dff70576d8069f11d89e6a761cf5c6132b49 + * c06d1a914adb21d0e314c79b3611ac6859eefeac1957d6914cccfc5531ad6ede * soc/st/stm32f4/stm32f4.yaml - * 3db4a0a65c9624d865d4ed7fc6354bf95054d0c465b76a2091f06aeac3d7375f + * 796886c294250aa81151a620d80d0e43b5ee8e1bf53a07d1d7e2c62e95214dbd * soc/st/stm32f4/stm32f446.yaml - * 0d5cc7f5fce4c51be71678987720c85c6e76e05473ff8a78ea5035394316c055 + * f0c9a37f6017c87d0efe215a3561f65494ba52383f2d0c10419b0ab5035f77f2 * soc/st/stm32f4/stm32f446re.yaml * b9a88d0a94aa17ee83317a3a56f7c194ec1b3107dfb3e82e453122dc1c48f6d4 */ @@ -30,7 +30,7 @@ #include -#define EMB_SOC_DEVICE_COUNT 13u +#define EMB_SOC_DEVICE_COUNT 19u #if CONFIG_EMB_DEVICE #include @@ -42,6 +42,7 @@ extern const emb_device_t emb_dev_iwdg; extern const emb_device_t emb_dev_rtc; extern const emb_device_t emb_dev_flash; extern const emb_device_t emb_dev_dma1; +extern const emb_device_t emb_dev_dma2; extern const emb_device_t emb_dev_gpiob; extern const emb_device_t emb_dev_gpioc; extern const emb_device_t emb_dev_usart2; @@ -49,6 +50,11 @@ extern const emb_device_t emb_dev_uart4; extern const emb_device_t emb_dev_spi2; extern const emb_device_t emb_dev_i2c1; extern const emb_device_t emb_dev_i2c2; +extern const emb_device_t emb_dev_tim5; +extern const emb_device_t emb_dev_tim9; +extern const emb_device_t emb_dev_tim3; +extern const emb_device_t emb_dev_tim4; +extern const emb_device_t emb_dev_adc1; /* which devices the board has, for code that uses one only where it exists */ #define EMB_SOC_HAS_RCC 1 @@ -57,6 +63,7 @@ extern const emb_device_t emb_dev_i2c2; #define EMB_SOC_HAS_RTC 1 #define EMB_SOC_HAS_FLASH 1 #define EMB_SOC_HAS_DMA1 1 +#define EMB_SOC_HAS_DMA2 1 #define EMB_SOC_HAS_GPIOB 1 #define EMB_SOC_HAS_GPIOC 1 #define EMB_SOC_HAS_USART2 1 @@ -64,6 +71,11 @@ extern const emb_device_t emb_dev_i2c2; #define EMB_SOC_HAS_SPI2 1 #define EMB_SOC_HAS_I2C1 1 #define EMB_SOC_HAS_I2C2 1 +#define EMB_SOC_HAS_TIM5 1 +#define EMB_SOC_HAS_TIM9 1 +#define EMB_SOC_HAS_TIM3 1 +#define EMB_SOC_HAS_TIM4 1 +#define EMB_SOC_HAS_ADC1 1 /* the board's watchdog device: the first of its class */ #define EMB_SOC_WATCHDOG_DEVICE (&emb_dev_iwdg) @@ -71,6 +83,11 @@ extern const emb_device_t emb_dev_i2c2; /* the board's RTC device: the first of its class */ #define EMB_SOC_RTC_DEVICE (&emb_dev_rtc) +/* the board's counters: the first of their class, and all of them (SPEC-017 §11a) */ +#define EMB_SOC_COUNTER_DEVICE (&emb_dev_tim5) +#define EMB_SOC_COUNTER_DEVICES &emb_dev_tim5, &emb_dev_tim9 +#define EMB_SOC_COUNTER_COUNT 2u + /* the console's UART device (the board's console:) */ #define EMB_SOC_CONSOLE_DEVICE (&emb_dev_usart2) /* its writes' DMA channel (devices[].dma, A119) */ @@ -93,6 +110,7 @@ extern const emb_device_t emb_dev_i2c2; #define EMB_SOC_USART2_DMA_TX {&emb_dev_dma1, 6u, 4u, {0u, 0u}} #define EMB_SOC_SPI2_DMA_RX {&emb_dev_dma1, 3u, 0u, {0u, 0u}} #define EMB_SOC_SPI2_DMA_TX {&emb_dev_dma1, 4u, 0u, {0u, 0u}} +#define EMB_SOC_ADC1_DMA_RX {&emb_dev_dma2, 0u, 0u, {0u, 0u}} /* clang-format on */ /* the SPI devices' chip selects (devices[].cs), emb_drv_gpio_line_t initializers; the pin diff --git a/boards/st/nucleo_f446re/generated/linker/regions.ld b/boards/st/nucleo_f446re/generated/linker/regions.ld index ca94b4b4..2ed8fa16 100644 --- a/boards/st/nucleo_f446re/generated/linker/regions.ld +++ b/boards/st/nucleo_f446re/generated/linker/regions.ld @@ -17,13 +17,13 @@ * arch/cortex_m/arch.yaml * c5c8e451c09717dee1713d07f8311b6d507e3b4c66c42d93e0ce11da6ec76d6d * boards/st/nucleo_f446re/board.yaml - * d756f3a7f19dc7da82ee3afc168dc54946312c5a9990720953c0fedcdece54ea + * 551c524379751d359bdd87501269d6cab33edf84d212d2f6632ffe9567ec71d0 * drivers/bindings.yaml - * d3c336ac05548e0addd1faac18f3dff70576d8069f11d89e6a761cf5c6132b49 + * c06d1a914adb21d0e314c79b3611ac6859eefeac1957d6914cccfc5531ad6ede * soc/st/stm32f4/stm32f4.yaml - * 3db4a0a65c9624d865d4ed7fc6354bf95054d0c465b76a2091f06aeac3d7375f + * 796886c294250aa81151a620d80d0e43b5ee8e1bf53a07d1d7e2c62e95214dbd * soc/st/stm32f4/stm32f446.yaml - * 0d5cc7f5fce4c51be71678987720c85c6e76e05473ff8a78ea5035394316c055 + * f0c9a37f6017c87d0efe215a3561f65494ba52383f2d0c10419b0ab5035f77f2 * soc/st/stm32f4/stm32f446re.yaml * b9a88d0a94aa17ee83317a3a56f7c194ec1b3107dfb3e82e453122dc1c48f6d4 */ diff --git a/boards/st/nucleo_f446re/generated/src/board_pins.c b/boards/st/nucleo_f446re/generated/src/board_pins.c index 6b64b344..5605d5fc 100644 --- a/boards/st/nucleo_f446re/generated/src/board_pins.c +++ b/boards/st/nucleo_f446re/generated/src/board_pins.c @@ -16,13 +16,13 @@ * arch/cortex_m/arch.yaml * c5c8e451c09717dee1713d07f8311b6d507e3b4c66c42d93e0ce11da6ec76d6d * boards/st/nucleo_f446re/board.yaml - * d756f3a7f19dc7da82ee3afc168dc54946312c5a9990720953c0fedcdece54ea + * 551c524379751d359bdd87501269d6cab33edf84d212d2f6632ffe9567ec71d0 * drivers/bindings.yaml - * d3c336ac05548e0addd1faac18f3dff70576d8069f11d89e6a761cf5c6132b49 + * c06d1a914adb21d0e314c79b3611ac6859eefeac1957d6914cccfc5531ad6ede * soc/st/stm32f4/stm32f4.yaml - * 3db4a0a65c9624d865d4ed7fc6354bf95054d0c465b76a2091f06aeac3d7375f + * 796886c294250aa81151a620d80d0e43b5ee8e1bf53a07d1d7e2c62e95214dbd * soc/st/stm32f4/stm32f446.yaml - * 0d5cc7f5fce4c51be71678987720c85c6e76e05473ff8a78ea5035394316c055 + * f0c9a37f6017c87d0efe215a3561f65494ba52383f2d0c10419b0ab5035f77f2 * soc/st/stm32f4/stm32f446re.yaml * b9a88d0a94aa17ee83317a3a56f7c194ec1b3107dfb3e82e453122dc1c48f6d4 */ @@ -38,10 +38,18 @@ const emb_stm32_pin_t emb_board_pins[] = { {EMB_STM32_PORT(A), 2u, EMB_STM32_PIN_AF, 7u, 0u, 0u}, /* PA3: pins.usart2.rx (usart2_rx) */ {EMB_STM32_PORT(A), 3u, EMB_STM32_PIN_AF, 7u, 0u, 0u}, + /* PA4: pins.adc1.in4 (adc1_in4) */ + {EMB_STM32_PORT(A), 4u, EMB_STM32_PIN_ANALOG, 0u, 0u, 0u}, /* PA5: leds.user (output) */ {EMB_STM32_PORT(A), 5u, EMB_STM32_PIN_OUTPUT, 0u, 0u, 0u}, + /* PA6: pins.tim3.ch1 (tim3_ch1) */ + {EMB_STM32_PORT(A), 6u, EMB_STM32_PIN_AF, 2u, 0u, 0u}, + /* PB0: pins.adc1.in8 (adc1_in8) */ + {EMB_STM32_PORT(B), 0u, EMB_STM32_PIN_ANALOG, 0u, 0u, 0u}, /* PB3: pins.i2c2.sda (i2c2_sda) */ {EMB_STM32_PORT(B), 3u, EMB_STM32_PIN_AF, 4u, 0u, EMB_STM32_PIN_I2C}, + /* PB6: pins.tim4.ch1 (tim4_ch1) */ + {EMB_STM32_PORT(B), 6u, EMB_STM32_PIN_AF, 2u, 0u, 0u}, /* PB8: pins.i2c1.scl (i2c1_scl) */ {EMB_STM32_PORT(B), 8u, EMB_STM32_PIN_AF, 4u, 0u, EMB_STM32_PIN_I2C}, /* PB9: pins.i2c1.sda (i2c1_sda) */ diff --git a/boards/st/nucleo_f446re/generated/src/soc_devices.c b/boards/st/nucleo_f446re/generated/src/soc_devices.c index 4ea7d019..ab473020 100644 --- a/boards/st/nucleo_f446re/generated/src/soc_devices.c +++ b/boards/st/nucleo_f446re/generated/src/soc_devices.c @@ -16,13 +16,13 @@ * arch/cortex_m/arch.yaml * c5c8e451c09717dee1713d07f8311b6d507e3b4c66c42d93e0ce11da6ec76d6d * boards/st/nucleo_f446re/board.yaml - * d756f3a7f19dc7da82ee3afc168dc54946312c5a9990720953c0fedcdece54ea + * 551c524379751d359bdd87501269d6cab33edf84d212d2f6632ffe9567ec71d0 * drivers/bindings.yaml - * d3c336ac05548e0addd1faac18f3dff70576d8069f11d89e6a761cf5c6132b49 + * c06d1a914adb21d0e314c79b3611ac6859eefeac1957d6914cccfc5531ad6ede * soc/st/stm32f4/stm32f4.yaml - * 3db4a0a65c9624d865d4ed7fc6354bf95054d0c465b76a2091f06aeac3d7375f + * 796886c294250aa81151a620d80d0e43b5ee8e1bf53a07d1d7e2c62e95214dbd * soc/st/stm32f4/stm32f446.yaml - * 0d5cc7f5fce4c51be71678987720c85c6e76e05473ff8a78ea5035394316c055 + * f0c9a37f6017c87d0efe215a3561f65494ba52383f2d0c10419b0ab5035f77f2 * soc/st/stm32f4/stm32f446re.yaml * b9a88d0a94aa17ee83317a3a56f7c194ec1b3107dfb3e82e453122dc1c48f6d4 */ @@ -166,6 +166,36 @@ const emb_device_t emb_dev_dma1 = { .dep_count = 1u, }; +/* dma2: st,stm32-dma, dma, EARLY */ +static const emb_stm32_dma_config_t dma2_config = { + .base = 0x40026400u, /* peripheral.base */ + .clken_offset = 0x00000030u, /* peripheral.clock.enable_offset */ + .clken_bit = 22u, /* peripheral.clock.bit */ + .irq0 = 56u, /* peripheral.irqs.s0 */ + .irq1 = 57u, /* peripheral.irqs.s1 */ + .irq2 = 58u, /* peripheral.irqs.s2 */ + .irq3 = 59u, /* peripheral.irqs.s3 */ + .irq4 = 60u, /* peripheral.irqs.s4 */ + .irq5 = 68u, /* peripheral.irqs.s5 */ + .irq6 = 69u, /* peripheral.irqs.s6 */ + .irq7 = 70u, /* peripheral.irqs.s7 */ + .memory = true, /* peripheral.dma.memory */ +}; +static emb_device_state_t dma2_state; +static emb_stm32_dma_data_t dma2_data; +static const emb_device_t *const dma2_deps[] = {&emb_dev_rcc}; +const emb_device_t emb_dev_dma2 = { + .name = "dma2", + .api = &emb_stm32_dma_api.dev, + .config = &dma2_config, + .state = &dma2_state, + .data = &dma2_data, + .deps = dma2_deps, + .class_id = EMB_DRV_CLASS_DMA, + .level = EMB_DEVICE_EARLY, + .dep_count = 1u, +}; + /* gpiob: st,stm32-gpio, gpio, EARLY */ static const emb_stm32_gpio_config_t gpiob_config = { .base = 0x40020400u, /* peripheral.base */ @@ -339,6 +369,144 @@ const emb_device_t emb_dev_i2c2 = { .dep_count = 1u, }; +/* tim5: st,stm32-tim, counter, KERNEL */ +static const emb_stm32_tim_config_t tim5_config = { + .base = 0x40000C00u, /* peripheral.base */ + .clock_hz = 90000000u, /* peripheral.timer_clock_hz */ + .rate_hz = 1000000u, /* device.rate_hz, its default */ + .clken_offset = 0x00000040u, /* peripheral.clock.enable_offset */ + .clken_bit = 3u, /* peripheral.clock.bit */ + .irq = 50u, /* peripheral.irqs.global */ + .bits = 32u, /* peripheral.counter_bits */ + .channels = 4u, /* peripheral.timer_channels, its default */ +}; +static emb_device_state_t tim5_state; +static emb_stm32_counter_data_t tim5_data; +static const emb_device_t *const tim5_deps[] = {&emb_dev_rcc}; +const emb_device_t emb_dev_tim5 = { + .name = "tim5", + .api = &emb_stm32_counter_api.dev, + .config = &tim5_config, + .state = &tim5_state, + .data = &tim5_data, + .deps = tim5_deps, + .class_id = EMB_DRV_CLASS_COUNTER, + .level = EMB_DEVICE_KERNEL, + .dep_count = 1u, +}; + +/* tim9: st,stm32-tim, counter, KERNEL */ +static const emb_stm32_tim_config_t tim9_config = { + .base = 0x40014000u, /* peripheral.base */ + .clock_hz = 180000000u, /* peripheral.timer_clock_hz */ + .rate_hz = 1000000u, /* device.rate_hz, its default */ + .clken_offset = 0x00000044u, /* peripheral.clock.enable_offset */ + .clken_bit = 16u, /* peripheral.clock.bit */ + .irq = 24u, /* peripheral.irqs.global */ + .bits = 16u, /* peripheral.counter_bits */ + .channels = 2u, /* peripheral.timer_channels */ +}; +static emb_device_state_t tim9_state; +static emb_stm32_counter_data_t tim9_data; +static const emb_device_t *const tim9_deps[] = {&emb_dev_rcc}; +const emb_device_t emb_dev_tim9 = { + .name = "tim9", + .api = &emb_stm32_counter_api.dev, + .config = &tim9_config, + .state = &tim9_state, + .data = &tim9_data, + .deps = tim9_deps, + .class_id = EMB_DRV_CLASS_COUNTER, + .level = EMB_DEVICE_KERNEL, + .dep_count = 1u, +}; + +/* tim3: st,stm32-tim, pwm, KERNEL */ +static const emb_stm32_tim_config_t tim3_config = { + .base = 0x40000400u, /* peripheral.base */ + .clock_hz = 90000000u, /* peripheral.timer_clock_hz */ + .clken_offset = 0x00000040u, /* peripheral.clock.enable_offset */ + .clken_bit = 1u, /* peripheral.clock.bit */ + .irq = 29u, /* peripheral.irqs.global */ + .bits = 16u, /* peripheral.counter_bits */ + .channels = 4u, /* peripheral.timer_channels, its default */ +}; +static emb_device_state_t tim3_state; +static emb_stm32_pwm_data_t tim3_data; +static const emb_device_t *const tim3_deps[] = {&emb_dev_rcc}; +const emb_device_t emb_dev_tim3 = { + .name = "tim3", + .api = &emb_stm32_pwm_api.dev, + .config = &tim3_config, + .state = &tim3_state, + .data = &tim3_data, + .deps = tim3_deps, + .class_id = EMB_DRV_CLASS_PWM, + .level = EMB_DEVICE_KERNEL, + .dep_count = 1u, +}; + +/* tim4: st,stm32-tim, pwm, KERNEL */ +static const emb_stm32_tim_config_t tim4_config = { + .base = 0x40000800u, /* peripheral.base */ + .clock_hz = 90000000u, /* peripheral.timer_clock_hz */ + .clken_offset = 0x00000040u, /* peripheral.clock.enable_offset */ + .clken_bit = 2u, /* peripheral.clock.bit */ + .irq = 30u, /* peripheral.irqs.global */ + .bits = 16u, /* peripheral.counter_bits */ + .channels = 4u, /* peripheral.timer_channels, its default */ +}; +static emb_device_state_t tim4_state; +static emb_stm32_pwm_data_t tim4_data; +static const emb_device_t *const tim4_deps[] = {&emb_dev_rcc}; +const emb_device_t emb_dev_tim4 = { + .name = "tim4", + .api = &emb_stm32_pwm_api.dev, + .config = &tim4_config, + .state = &tim4_state, + .data = &tim4_data, + .deps = tim4_deps, + .class_id = EMB_DRV_CLASS_PWM, + .level = EMB_DEVICE_KERNEL, + .dep_count = 1u, +}; + +/* adc1: st,stm32f4-adc, adc, KERNEL */ +static const emb_stm32_adc_config_t adc1_config = { + .base = 0x40012000u, /* peripheral.base */ + .common = 0x40012300u, /* takes.common.base */ + .calibration = 0x1FFF7A2Au, /* takes.cal.base */ + .trigger = 0x40000000u, /* takes.trigger.base */ + .trigger_hz = 90000000u, /* takes.trigger.timer_clock_hz */ + .trigger_clken_offset = 0x00000040u, /* takes.trigger.clock.enable_offset */ + .trigger_clken_bit = 0u, /* takes.trigger.clock.bit */ + .trigger_select = 6u, /* takes.trigger.adc_trigger */ + .clock_hz = 90000000u, /* peripheral.clock_hz */ + .clken_offset = 0x00000044u, /* peripheral.clock.enable_offset */ + .clken_bit = 8u, /* peripheral.clock.bit */ + .irq = 18u, /* peripheral.irqs.global */ + .vref_mv = 3300u, /* device.vref_mv, its default */ + .bits = 12u, /* peripheral.adc.bits */ + .inputs = 16u, /* peripheral.adc.inputs */ + .temperature = 18u, /* peripheral.adc.temperature */ + .vrefint = 17u, /* peripheral.adc.vrefint */ + .dma_rx = {&emb_dev_dma2, 0u, 0u, {0u, 0u}}, /* dma.rx */ +}; +static emb_device_state_t adc1_state; +static emb_stm32_adc_data_t adc1_data; +static const emb_device_t *const adc1_deps[] = {&emb_dev_dma2, &emb_dev_rcc}; +const emb_device_t emb_dev_adc1 = { + .name = "adc1", + .api = &emb_stm32_adc_api.dev, + .config = &adc1_config, + .state = &adc1_state, + .data = &adc1_data, + .deps = adc1_deps, + .class_id = EMB_DRV_CLASS_ADC, + .level = EMB_DEVICE_KERNEL, + .dep_count = 2u, +}; + /* in initialization order */ static const emb_device_t *const devices[] = { &emb_dev_rcc, /* 0: EARLY */ @@ -347,16 +515,22 @@ static const emb_device_t *const devices[] = { &emb_dev_rtc, /* 3: EARLY */ &emb_dev_flash, /* 4: EARLY */ &emb_dev_dma1, /* 5: EARLY */ - &emb_dev_gpiob, /* 6: EARLY */ - &emb_dev_gpioc, /* 7: EARLY */ - &emb_dev_usart2, /* 8: EARLY */ - &emb_dev_uart4, /* 9: EARLY */ - &emb_dev_spi2, /* 10: KERNEL */ - &emb_dev_i2c1, /* 11: KERNEL */ - &emb_dev_i2c2, /* 12: KERNEL */ + &emb_dev_dma2, /* 6: EARLY */ + &emb_dev_gpiob, /* 7: EARLY */ + &emb_dev_gpioc, /* 8: EARLY */ + &emb_dev_usart2, /* 9: EARLY */ + &emb_dev_uart4, /* 10: EARLY */ + &emb_dev_spi2, /* 11: KERNEL */ + &emb_dev_i2c1, /* 12: KERNEL */ + &emb_dev_i2c2, /* 13: KERNEL */ + &emb_dev_tim5, /* 14: KERNEL */ + &emb_dev_tim9, /* 15: KERNEL */ + &emb_dev_tim3, /* 16: KERNEL */ + &emb_dev_tim4, /* 17: KERNEL */ + &emb_dev_adc1, /* 18: KERNEL */ }; -const emb_device_table_t emb_board_device_table = {devices, 13u, 10u}; +const emb_device_table_t emb_board_device_table = {devices, 19u, 11u}; #if CONFIG_EMB_DRV_ENTROPY /* the board's entropy source, or none: nothing stands in for one (SPEC-017 §11, SEC-012) */ diff --git a/boards/st/nucleo_f446ze/generated/.base/build/CMakeLists.txt b/boards/st/nucleo_f446ze/generated/.base/build/CMakeLists.txt index 1d85f37a..08001baf 100644 --- a/boards/st/nucleo_f446ze/generated/.base/build/CMakeLists.txt +++ b/boards/st/nucleo_f446ze/generated/.base/build/CMakeLists.txt @@ -11,11 +11,11 @@ # boards/st/nucleo_f446ze/board.yaml # 1525ea206692663af174039e30776d6a9a9b30275c9e5c9bdabf14ac0b70aa19 # drivers/bindings.yaml -# d3c336ac05548e0addd1faac18f3dff70576d8069f11d89e6a761cf5c6132b49 +# c06d1a914adb21d0e314c79b3611ac6859eefeac1957d6914cccfc5531ad6ede # soc/st/stm32f4/stm32f4.yaml -# 3db4a0a65c9624d865d4ed7fc6354bf95054d0c465b76a2091f06aeac3d7375f +# 796886c294250aa81151a620d80d0e43b5ee8e1bf53a07d1d7e2c62e95214dbd # soc/st/stm32f4/stm32f446.yaml -# 0d5cc7f5fce4c51be71678987720c85c6e76e05473ff8a78ea5035394316c055 +# f0c9a37f6017c87d0efe215a3561f65494ba52383f2d0c10419b0ab5035f77f2 # soc/st/stm32f4/stm32f446ze.yaml # dabae95e9e4bc984c1a33275966665e0252068e929fe3b430d06589da6bdb6c9 # The board has no C of its own: its SoC family's board support builds emb_board from diff --git a/boards/st/nucleo_f446ze/generated/.base/build/board.cmake b/boards/st/nucleo_f446ze/generated/.base/build/board.cmake index 2bbce080..67fa81ea 100644 --- a/boards/st/nucleo_f446ze/generated/.base/build/board.cmake +++ b/boards/st/nucleo_f446ze/generated/.base/build/board.cmake @@ -11,11 +11,11 @@ # boards/st/nucleo_f446ze/board.yaml # 1525ea206692663af174039e30776d6a9a9b30275c9e5c9bdabf14ac0b70aa19 # drivers/bindings.yaml -# d3c336ac05548e0addd1faac18f3dff70576d8069f11d89e6a761cf5c6132b49 +# c06d1a914adb21d0e314c79b3611ac6859eefeac1957d6914cccfc5531ad6ede # soc/st/stm32f4/stm32f4.yaml -# 3db4a0a65c9624d865d4ed7fc6354bf95054d0c465b76a2091f06aeac3d7375f +# 796886c294250aa81151a620d80d0e43b5ee8e1bf53a07d1d7e2c62e95214dbd # soc/st/stm32f4/stm32f446.yaml -# 0d5cc7f5fce4c51be71678987720c85c6e76e05473ff8a78ea5035394316c055 +# f0c9a37f6017c87d0efe215a3561f65494ba52383f2d0c10419b0ab5035f77f2 # soc/st/stm32f4/stm32f446ze.yaml # dabae95e9e4bc984c1a33275966665e0252068e929fe3b430d06589da6bdb6c9 # nucleo_f446ze: STM32F446ZE, cortex-m4f at 180 MHz. @@ -27,6 +27,8 @@ get_filename_component(EMB_BOARD_GENERATED_DIR "${CMAKE_CURRENT_LIST_DIR}/.." AB set(EMB_BOARD_CONF "${EMB_BOARD_GENERATED_DIR}/config/board.conf") set(EMB_BOARD_HW_JSON "${EMB_BOARD_GENERATED_DIR}/docs/hw.json") set(EMB_BOARD_BUILD_DIR "${CMAKE_CURRENT_LIST_DIR}") # build/CMakeLists.txt +set(EMB_BOARD_SRC_DIR "${EMB_BOARD_GENERATED_DIR}/src") # its pin table and boot block +set(EMB_BOARD_LINKER_DIR "${EMB_BOARD_GENERATED_DIR}/linker") # the SoC family's board support and drivers build this board (build/CMakeLists.txt) set(EMB_SOC_DIR "${EMB_BASE}/soc/st/stm32f4") set(EMB_BOARD_INCLUDE_DIRS "${EMB_BOARD_GENERATED_DIR}/include" "${EMB_SOC_DIR}/include") @@ -45,8 +47,8 @@ set(EMB_BOARD_DRIVER_INCLUDE_DIRS set(EMB_BOARD_HW_INPUTS "arch/cortex_m/arch.yaml=c5c8e451c09717dee1713d07f8311b6d507e3b4c66c42d93e0ce11da6ec76d6d" "boards/st/nucleo_f446ze/board.yaml=1525ea206692663af174039e30776d6a9a9b30275c9e5c9bdabf14ac0b70aa19" - "drivers/bindings.yaml=d3c336ac05548e0addd1faac18f3dff70576d8069f11d89e6a761cf5c6132b49" - "soc/st/stm32f4/stm32f4.yaml=3db4a0a65c9624d865d4ed7fc6354bf95054d0c465b76a2091f06aeac3d7375f" - "soc/st/stm32f4/stm32f446.yaml=0d5cc7f5fce4c51be71678987720c85c6e76e05473ff8a78ea5035394316c055" + "drivers/bindings.yaml=c06d1a914adb21d0e314c79b3611ac6859eefeac1957d6914cccfc5531ad6ede" + "soc/st/stm32f4/stm32f4.yaml=796886c294250aa81151a620d80d0e43b5ee8e1bf53a07d1d7e2c62e95214dbd" + "soc/st/stm32f4/stm32f446.yaml=f0c9a37f6017c87d0efe215a3561f65494ba52383f2d0c10419b0ab5035f77f2" "soc/st/stm32f4/stm32f446ze.yaml=dabae95e9e4bc984c1a33275966665e0252068e929fe3b430d06589da6bdb6c9" ) diff --git a/boards/st/nucleo_f446ze/generated/.base/config/board.conf b/boards/st/nucleo_f446ze/generated/.base/config/board.conf index 0f706d76..00f89d0d 100644 --- a/boards/st/nucleo_f446ze/generated/.base/config/board.conf +++ b/boards/st/nucleo_f446ze/generated/.base/config/board.conf @@ -11,11 +11,11 @@ # boards/st/nucleo_f446ze/board.yaml # 1525ea206692663af174039e30776d6a9a9b30275c9e5c9bdabf14ac0b70aa19 # drivers/bindings.yaml -# d3c336ac05548e0addd1faac18f3dff70576d8069f11d89e6a761cf5c6132b49 +# c06d1a914adb21d0e314c79b3611ac6859eefeac1957d6914cccfc5531ad6ede # soc/st/stm32f4/stm32f4.yaml -# 3db4a0a65c9624d865d4ed7fc6354bf95054d0c465b76a2091f06aeac3d7375f +# 796886c294250aa81151a620d80d0e43b5ee8e1bf53a07d1d7e2c62e95214dbd # soc/st/stm32f4/stm32f446.yaml -# 0d5cc7f5fce4c51be71678987720c85c6e76e05473ff8a78ea5035394316c055 +# f0c9a37f6017c87d0efe215a3561f65494ba52383f2d0c10419b0ab5035f77f2 # soc/st/stm32f4/stm32f446ze.yaml # dabae95e9e4bc984c1a33275966665e0252068e929fe3b430d06589da6bdb6c9 # Board defaults for nucleo_f446ze. Applied before the profile fragment. diff --git a/boards/st/nucleo_f446ze/generated/.base/docs/board.md b/boards/st/nucleo_f446ze/generated/.base/docs/board.md index 3cd9f9e6..d4873d21 100644 --- a/boards/st/nucleo_f446ze/generated/.base/docs/board.md +++ b/boards/st/nucleo_f446ze/generated/.base/docs/board.md @@ -64,7 +64,10 @@ In initialization order (SPEC-016 §4). | 16 | dma1.s5 | | 17 | dma1.s6 | | 18 | adc1.global | +| 24 | tim9.global | | 28 | tim2.global | +| 29 | tim3.global | +| 30 | tim4.global | | 31 | i2c1.ev | | 32 | i2c1.er | | 33 | i2c2.ev | @@ -75,6 +78,7 @@ In initialization order (SPEC-016 §4). | 39 | usart3.global | | 41 | rtc.alarm | | 47 | dma1.s7 | +| 50 | tim5.global | | 52 | uart4.global | | 53 | uart5.global | | 56 | dma2.s0 | @@ -99,7 +103,7 @@ Generated by emb-hwgen 0.1.0, schema v0, from: |---|---| | `arch/cortex_m/arch.yaml` | `c5c8e451c09717dee1713d07f8311b6d507e3b4c66c42d93e0ce11da6ec76d6d` | | `boards/st/nucleo_f446ze/board.yaml` | `1525ea206692663af174039e30776d6a9a9b30275c9e5c9bdabf14ac0b70aa19` | -| `drivers/bindings.yaml` | `d3c336ac05548e0addd1faac18f3dff70576d8069f11d89e6a761cf5c6132b49` | -| `soc/st/stm32f4/stm32f4.yaml` | `3db4a0a65c9624d865d4ed7fc6354bf95054d0c465b76a2091f06aeac3d7375f` | -| `soc/st/stm32f4/stm32f446.yaml` | `0d5cc7f5fce4c51be71678987720c85c6e76e05473ff8a78ea5035394316c055` | +| `drivers/bindings.yaml` | `c06d1a914adb21d0e314c79b3611ac6859eefeac1957d6914cccfc5531ad6ede` | +| `soc/st/stm32f4/stm32f4.yaml` | `796886c294250aa81151a620d80d0e43b5ee8e1bf53a07d1d7e2c62e95214dbd` | +| `soc/st/stm32f4/stm32f446.yaml` | `f0c9a37f6017c87d0efe215a3561f65494ba52383f2d0c10419b0ab5035f77f2` | | `soc/st/stm32f4/stm32f446ze.yaml` | `dabae95e9e4bc984c1a33275966665e0252068e929fe3b430d06589da6bdb6c9` | diff --git a/boards/st/nucleo_f446ze/generated/.base/docs/build_report.md b/boards/st/nucleo_f446ze/generated/.base/docs/build_report.md index 14263ab1..b448b886 100644 --- a/boards/st/nucleo_f446ze/generated/.base/docs/build_report.md +++ b/boards/st/nucleo_f446ze/generated/.base/docs/build_report.md @@ -34,7 +34,7 @@ Generated by emb-hwgen 0.1.0, schema v0, from: |---|---| | `arch/cortex_m/arch.yaml` | `c5c8e451c09717dee1713d07f8311b6d507e3b4c66c42d93e0ce11da6ec76d6d` | | `boards/st/nucleo_f446ze/board.yaml` | `1525ea206692663af174039e30776d6a9a9b30275c9e5c9bdabf14ac0b70aa19` | -| `drivers/bindings.yaml` | `d3c336ac05548e0addd1faac18f3dff70576d8069f11d89e6a761cf5c6132b49` | -| `soc/st/stm32f4/stm32f4.yaml` | `3db4a0a65c9624d865d4ed7fc6354bf95054d0c465b76a2091f06aeac3d7375f` | -| `soc/st/stm32f4/stm32f446.yaml` | `0d5cc7f5fce4c51be71678987720c85c6e76e05473ff8a78ea5035394316c055` | +| `drivers/bindings.yaml` | `c06d1a914adb21d0e314c79b3611ac6859eefeac1957d6914cccfc5531ad6ede` | +| `soc/st/stm32f4/stm32f4.yaml` | `796886c294250aa81151a620d80d0e43b5ee8e1bf53a07d1d7e2c62e95214dbd` | +| `soc/st/stm32f4/stm32f446.yaml` | `f0c9a37f6017c87d0efe215a3561f65494ba52383f2d0c10419b0ab5035f77f2` | | `soc/st/stm32f4/stm32f446ze.yaml` | `dabae95e9e4bc984c1a33275966665e0252068e929fe3b430d06589da6bdb6c9` | diff --git a/boards/st/nucleo_f446ze/generated/.base/docs/hw.json b/boards/st/nucleo_f446ze/generated/.base/docs/hw.json index e59cbc85..82df30c2 100644 --- a/boards/st/nucleo_f446ze/generated/.base/docs/hw.json +++ b/boards/st/nucleo_f446ze/generated/.base/docs/hw.json @@ -116,8 +116,14 @@ "apb1": 45000000, "apb2": 90000000 }, + "bus_timer_hz": { + "ahb1": 180000000, + "apb1": 90000000, + "apb2": 180000000 + }, "bypass": true, "cpu_hz": 180000000, + "fixed_plls": {}, "flash_wait_states": 5, "hclk_hz": 180000000, "pclk1_div": 4, @@ -357,15 +363,15 @@ }, { "path": "drivers/bindings.yaml", - "sha256": "d3c336ac05548e0addd1faac18f3dff70576d8069f11d89e6a761cf5c6132b49" + "sha256": "c06d1a914adb21d0e314c79b3611ac6859eefeac1957d6914cccfc5531ad6ede" }, { "path": "soc/st/stm32f4/stm32f4.yaml", - "sha256": "3db4a0a65c9624d865d4ed7fc6354bf95054d0c465b76a2091f06aeac3d7375f" + "sha256": "796886c294250aa81151a620d80d0e43b5ee8e1bf53a07d1d7e2c62e95214dbd" }, { "path": "soc/st/stm32f4/stm32f446.yaml", - "sha256": "0d5cc7f5fce4c51be71678987720c85c6e76e05473ff8a78ea5035394316c055" + "sha256": "f0c9a37f6017c87d0efe215a3561f65494ba52383f2d0c10419b0ab5035f77f2" }, { "path": "soc/st/stm32f4/stm32f446ze.yaml", @@ -376,19 +382,49 @@ "soc": { "alternate_functions": { "PA0": { - "af8": "uart4_tx" + "af1": "tim2_ch1", + "af2": "tim5_ch1", + "af8": "uart4_tx", + "analog": "adc1_in0" }, "PA1": { - "af8": "uart4_rx" + "af1": "tim2_ch2", + "af2": "tim5_ch2", + "af8": "uart4_rx", + "analog": "adc1_in1" }, "PA10": { "af7": "usart1_rx" }, + "PA15": { + "af1": "tim2_ch1" + }, "PA2": { - "af7": "usart2_tx" + "af1": "tim2_ch3", + "af2": "tim5_ch3", + "af7": "usart2_tx", + "analog": "adc1_in2" }, "PA3": { - "af7": "usart2_rx" + "af1": "tim2_ch4", + "af2": "tim5_ch4", + "af7": "usart2_rx", + "analog": "adc1_in3" + }, + "PA4": { + "analog": "adc1_in4" + }, + "PA5": { + "af1": "tim2_ch1", + "analog": "adc1_in5" + }, + "PA6": { + "af2": "tim3_ch1", + "analog": "adc1_in6" + }, + "PA7": { + "af2": "tim3_ch2", + "analog": "adc1_in7" }, "PA8": { "af4": "i2c3_scl" @@ -396,7 +432,16 @@ "PA9": { "af7": "usart1_tx" }, + "PB0": { + "af2": "tim3_ch3", + "analog": "adc1_in8" + }, + "PB1": { + "af2": "tim3_ch4", + "analog": "adc1_in9" + }, "PB10": { + "af1": "tim2_ch3", "af4": "i2c2_scl", "af7": "usart3_tx" }, @@ -409,26 +454,46 @@ "PB15": { "af5": "spi2_mosi" }, + "PB2": { + "af1": "tim2_ch4" + }, "PB3": { + "af1": "tim2_ch2", "af4": "i2c2_sda" }, "PB4": { + "af2": "tim3_ch1", "af4": "i2c3_sda" }, + "PB5": { + "af2": "tim3_ch2" + }, "PB6": { + "af2": "tim4_ch1", "af4": "i2c1_scl", "af7": "usart1_tx" }, "PB7": { + "af2": "tim4_ch2", "af4": "i2c1_sda", "af7": "usart1_rx" }, "PB8": { + "af1": "tim2_ch1", + "af2": "tim4_ch3", "af4": "i2c1_scl" }, "PB9": { + "af1": "tim2_ch2", + "af2": "tim4_ch4", "af4": "i2c1_sda" }, + "PC0": { + "analog": "adc1_in10" + }, + "PC1": { + "analog": "adc1_in11" + }, "PC10": { "af7": "usart3_tx", "af8": "uart4_tx" @@ -441,16 +506,32 @@ "af4": "i2c2_sda", "af8": "uart5_tx" }, + "PC2": { + "analog": "adc1_in12" + }, + "PC3": { + "analog": "adc1_in13" + }, + "PC4": { + "analog": "adc1_in14" + }, "PC5": { - "af7": "usart3_rx" + "af7": "usart3_rx", + "analog": "adc1_in15" }, "PC6": { + "af2": "tim3_ch1", "af8": "usart6_tx" }, "PC7": { + "af2": "tim3_ch2", "af8": "usart6_rx" }, + "PC8": { + "af2": "tim3_ch3" + }, "PC9": { + "af2": "tim3_ch4", "af4": "i2c3_sda" }, "PD2": { @@ -579,6 +660,7 @@ "name": "lse" } ], + "timers_double_when_divided": true, "voltage_scales": [ { "max_hz": 120000000, @@ -723,12 +805,24 @@ "part": "STM32F446ZE", "peripherals": [ { + "adc": { + "bits": 12, + "inputs": 16, + "temperature": 18, + "vrefint": 17 + }, "base": 1073815552, "clock": { "bit": 8, "bus": "apb2" }, "compatible": "st,stm32f4-adc", + "dma_requests": { + "rx": [ + "dma2.s0c0", + "dma2.s4c0" + ] + }, "irqs": [ { "name": "global", @@ -903,12 +997,14 @@ "size": 1024 }, { + "adc_trigger": 6, "base": 1073741824, "clock": { "bit": 0, "bus": "apb1" }, "compatible": "st,stm32-tim", + "counter_bits": 32, "irqs": [ { "name": "global", @@ -918,6 +1014,76 @@ "name": "tim2", "size": 1024 }, + { + "adc_trigger": 8, + "base": 1073742848, + "clock": { + "bit": 1, + "bus": "apb1" + }, + "compatible": "st,stm32-tim", + "counter_bits": 16, + "irqs": [ + { + "name": "global", + "number": 29 + } + ], + "name": "tim3", + "size": 1024 + }, + { + "base": 1073743872, + "clock": { + "bit": 2, + "bus": "apb1" + }, + "compatible": "st,stm32-tim", + "counter_bits": 16, + "irqs": [ + { + "name": "global", + "number": 30 + } + ], + "name": "tim4", + "size": 1024 + }, + { + "base": 1073744896, + "clock": { + "bit": 3, + "bus": "apb1" + }, + "compatible": "st,stm32-tim", + "counter_bits": 32, + "irqs": [ + { + "name": "global", + "number": 50 + } + ], + "name": "tim5", + "size": 1024 + }, + { + "base": 1073823744, + "clock": { + "bit": 16, + "bus": "apb2" + }, + "compatible": "st,stm32-tim", + "counter_bits": 16, + "irqs": [ + { + "name": "global", + "number": 24 + } + ], + "name": "tim9", + "size": 1024, + "timer_channels": 2 + }, { "base": 1073897472, "clock": { diff --git a/boards/st/nucleo_f446ze/generated/.base/include/hw_config.h b/boards/st/nucleo_f446ze/generated/.base/include/hw_config.h index 582285e7..1a33077b 100644 --- a/boards/st/nucleo_f446ze/generated/.base/include/hw_config.h +++ b/boards/st/nucleo_f446ze/generated/.base/include/hw_config.h @@ -17,11 +17,11 @@ * boards/st/nucleo_f446ze/board.yaml * 1525ea206692663af174039e30776d6a9a9b30275c9e5c9bdabf14ac0b70aa19 * drivers/bindings.yaml - * d3c336ac05548e0addd1faac18f3dff70576d8069f11d89e6a761cf5c6132b49 + * c06d1a914adb21d0e314c79b3611ac6859eefeac1957d6914cccfc5531ad6ede * soc/st/stm32f4/stm32f4.yaml - * 3db4a0a65c9624d865d4ed7fc6354bf95054d0c465b76a2091f06aeac3d7375f + * 796886c294250aa81151a620d80d0e43b5ee8e1bf53a07d1d7e2c62e95214dbd * soc/st/stm32f4/stm32f446.yaml - * 0d5cc7f5fce4c51be71678987720c85c6e76e05473ff8a78ea5035394316c055 + * f0c9a37f6017c87d0efe215a3561f65494ba52383f2d0c10419b0ab5035f77f2 * soc/st/stm32f4/stm32f446ze.yaml * dabae95e9e4bc984c1a33275966665e0252068e929fe3b430d06589da6bdb6c9 */ @@ -164,6 +164,22 @@ #define EMB_HW_TIM2_CLKEN_BIT 0u #define EMB_HW_TIM2_CLKEN_OFFSET 0x40u #define EMB_HW_TIM2_IRQ 28u +#define EMB_HW_TIM3_BASE 0x40000400u +#define EMB_HW_TIM3_CLKEN_BIT 1u +#define EMB_HW_TIM3_CLKEN_OFFSET 0x40u +#define EMB_HW_TIM3_IRQ 29u +#define EMB_HW_TIM4_BASE 0x40000800u +#define EMB_HW_TIM4_CLKEN_BIT 2u +#define EMB_HW_TIM4_CLKEN_OFFSET 0x40u +#define EMB_HW_TIM4_IRQ 30u +#define EMB_HW_TIM5_BASE 0x40000C00u +#define EMB_HW_TIM5_CLKEN_BIT 3u +#define EMB_HW_TIM5_CLKEN_OFFSET 0x40u +#define EMB_HW_TIM5_IRQ 50u +#define EMB_HW_TIM9_BASE 0x40014000u +#define EMB_HW_TIM9_CLKEN_BIT 16u +#define EMB_HW_TIM9_CLKEN_OFFSET 0x44u +#define EMB_HW_TIM9_IRQ 24u #define EMB_HW_UART4_BASE 0x40004C00u #define EMB_HW_UART4_CLKEN_BIT 19u #define EMB_HW_UART4_CLKEN_OFFSET 0x40u diff --git a/boards/st/nucleo_f446ze/generated/.base/include/soc_devices.h b/boards/st/nucleo_f446ze/generated/.base/include/soc_devices.h index 4c03b851..b45b953a 100644 --- a/boards/st/nucleo_f446ze/generated/.base/include/soc_devices.h +++ b/boards/st/nucleo_f446ze/generated/.base/include/soc_devices.h @@ -17,11 +17,11 @@ * boards/st/nucleo_f446ze/board.yaml * 1525ea206692663af174039e30776d6a9a9b30275c9e5c9bdabf14ac0b70aa19 * drivers/bindings.yaml - * d3c336ac05548e0addd1faac18f3dff70576d8069f11d89e6a761cf5c6132b49 + * c06d1a914adb21d0e314c79b3611ac6859eefeac1957d6914cccfc5531ad6ede * soc/st/stm32f4/stm32f4.yaml - * 3db4a0a65c9624d865d4ed7fc6354bf95054d0c465b76a2091f06aeac3d7375f + * 796886c294250aa81151a620d80d0e43b5ee8e1bf53a07d1d7e2c62e95214dbd * soc/st/stm32f4/stm32f446.yaml - * 0d5cc7f5fce4c51be71678987720c85c6e76e05473ff8a78ea5035394316c055 + * f0c9a37f6017c87d0efe215a3561f65494ba52383f2d0c10419b0ab5035f77f2 * soc/st/stm32f4/stm32f446ze.yaml * dabae95e9e4bc984c1a33275966665e0252068e929fe3b430d06589da6bdb6c9 */ diff --git a/boards/st/nucleo_f446ze/generated/.base/linker/regions.ld b/boards/st/nucleo_f446ze/generated/.base/linker/regions.ld index 49ba192d..be64b58d 100644 --- a/boards/st/nucleo_f446ze/generated/.base/linker/regions.ld +++ b/boards/st/nucleo_f446ze/generated/.base/linker/regions.ld @@ -19,11 +19,11 @@ * boards/st/nucleo_f446ze/board.yaml * 1525ea206692663af174039e30776d6a9a9b30275c9e5c9bdabf14ac0b70aa19 * drivers/bindings.yaml - * d3c336ac05548e0addd1faac18f3dff70576d8069f11d89e6a761cf5c6132b49 + * c06d1a914adb21d0e314c79b3611ac6859eefeac1957d6914cccfc5531ad6ede * soc/st/stm32f4/stm32f4.yaml - * 3db4a0a65c9624d865d4ed7fc6354bf95054d0c465b76a2091f06aeac3d7375f + * 796886c294250aa81151a620d80d0e43b5ee8e1bf53a07d1d7e2c62e95214dbd * soc/st/stm32f4/stm32f446.yaml - * 0d5cc7f5fce4c51be71678987720c85c6e76e05473ff8a78ea5035394316c055 + * f0c9a37f6017c87d0efe215a3561f65494ba52383f2d0c10419b0ab5035f77f2 * soc/st/stm32f4/stm32f446ze.yaml * dabae95e9e4bc984c1a33275966665e0252068e929fe3b430d06589da6bdb6c9 */ diff --git a/boards/st/nucleo_f446ze/generated/.base/src/board_pins.c b/boards/st/nucleo_f446ze/generated/.base/src/board_pins.c index 50713493..54cc19fb 100644 --- a/boards/st/nucleo_f446ze/generated/.base/src/board_pins.c +++ b/boards/st/nucleo_f446ze/generated/.base/src/board_pins.c @@ -18,11 +18,11 @@ * boards/st/nucleo_f446ze/board.yaml * 1525ea206692663af174039e30776d6a9a9b30275c9e5c9bdabf14ac0b70aa19 * drivers/bindings.yaml - * d3c336ac05548e0addd1faac18f3dff70576d8069f11d89e6a761cf5c6132b49 + * c06d1a914adb21d0e314c79b3611ac6859eefeac1957d6914cccfc5531ad6ede * soc/st/stm32f4/stm32f4.yaml - * 3db4a0a65c9624d865d4ed7fc6354bf95054d0c465b76a2091f06aeac3d7375f + * 796886c294250aa81151a620d80d0e43b5ee8e1bf53a07d1d7e2c62e95214dbd * soc/st/stm32f4/stm32f446.yaml - * 0d5cc7f5fce4c51be71678987720c85c6e76e05473ff8a78ea5035394316c055 + * f0c9a37f6017c87d0efe215a3561f65494ba52383f2d0c10419b0ab5035f77f2 * soc/st/stm32f4/stm32f446ze.yaml * dabae95e9e4bc984c1a33275966665e0252068e929fe3b430d06589da6bdb6c9 */ diff --git a/boards/st/nucleo_f446ze/generated/.base/src/soc_devices.c b/boards/st/nucleo_f446ze/generated/.base/src/soc_devices.c index 3072f2e5..496c10e1 100644 --- a/boards/st/nucleo_f446ze/generated/.base/src/soc_devices.c +++ b/boards/st/nucleo_f446ze/generated/.base/src/soc_devices.c @@ -18,11 +18,11 @@ * boards/st/nucleo_f446ze/board.yaml * 1525ea206692663af174039e30776d6a9a9b30275c9e5c9bdabf14ac0b70aa19 * drivers/bindings.yaml - * d3c336ac05548e0addd1faac18f3dff70576d8069f11d89e6a761cf5c6132b49 + * c06d1a914adb21d0e314c79b3611ac6859eefeac1957d6914cccfc5531ad6ede * soc/st/stm32f4/stm32f4.yaml - * 3db4a0a65c9624d865d4ed7fc6354bf95054d0c465b76a2091f06aeac3d7375f + * 796886c294250aa81151a620d80d0e43b5ee8e1bf53a07d1d7e2c62e95214dbd * soc/st/stm32f4/stm32f446.yaml - * 0d5cc7f5fce4c51be71678987720c85c6e76e05473ff8a78ea5035394316c055 + * f0c9a37f6017c87d0efe215a3561f65494ba52383f2d0c10419b0ab5035f77f2 * soc/st/stm32f4/stm32f446ze.yaml * dabae95e9e4bc984c1a33275966665e0252068e929fe3b430d06589da6bdb6c9 */ diff --git a/boards/st/nucleo_f446ze/generated/build/CMakeLists.txt b/boards/st/nucleo_f446ze/generated/build/CMakeLists.txt index 1d85f37a..08001baf 100644 --- a/boards/st/nucleo_f446ze/generated/build/CMakeLists.txt +++ b/boards/st/nucleo_f446ze/generated/build/CMakeLists.txt @@ -11,11 +11,11 @@ # boards/st/nucleo_f446ze/board.yaml # 1525ea206692663af174039e30776d6a9a9b30275c9e5c9bdabf14ac0b70aa19 # drivers/bindings.yaml -# d3c336ac05548e0addd1faac18f3dff70576d8069f11d89e6a761cf5c6132b49 +# c06d1a914adb21d0e314c79b3611ac6859eefeac1957d6914cccfc5531ad6ede # soc/st/stm32f4/stm32f4.yaml -# 3db4a0a65c9624d865d4ed7fc6354bf95054d0c465b76a2091f06aeac3d7375f +# 796886c294250aa81151a620d80d0e43b5ee8e1bf53a07d1d7e2c62e95214dbd # soc/st/stm32f4/stm32f446.yaml -# 0d5cc7f5fce4c51be71678987720c85c6e76e05473ff8a78ea5035394316c055 +# f0c9a37f6017c87d0efe215a3561f65494ba52383f2d0c10419b0ab5035f77f2 # soc/st/stm32f4/stm32f446ze.yaml # dabae95e9e4bc984c1a33275966665e0252068e929fe3b430d06589da6bdb6c9 # The board has no C of its own: its SoC family's board support builds emb_board from diff --git a/boards/st/nucleo_f446ze/generated/build/board.cmake b/boards/st/nucleo_f446ze/generated/build/board.cmake index 2bbce080..67fa81ea 100644 --- a/boards/st/nucleo_f446ze/generated/build/board.cmake +++ b/boards/st/nucleo_f446ze/generated/build/board.cmake @@ -11,11 +11,11 @@ # boards/st/nucleo_f446ze/board.yaml # 1525ea206692663af174039e30776d6a9a9b30275c9e5c9bdabf14ac0b70aa19 # drivers/bindings.yaml -# d3c336ac05548e0addd1faac18f3dff70576d8069f11d89e6a761cf5c6132b49 +# c06d1a914adb21d0e314c79b3611ac6859eefeac1957d6914cccfc5531ad6ede # soc/st/stm32f4/stm32f4.yaml -# 3db4a0a65c9624d865d4ed7fc6354bf95054d0c465b76a2091f06aeac3d7375f +# 796886c294250aa81151a620d80d0e43b5ee8e1bf53a07d1d7e2c62e95214dbd # soc/st/stm32f4/stm32f446.yaml -# 0d5cc7f5fce4c51be71678987720c85c6e76e05473ff8a78ea5035394316c055 +# f0c9a37f6017c87d0efe215a3561f65494ba52383f2d0c10419b0ab5035f77f2 # soc/st/stm32f4/stm32f446ze.yaml # dabae95e9e4bc984c1a33275966665e0252068e929fe3b430d06589da6bdb6c9 # nucleo_f446ze: STM32F446ZE, cortex-m4f at 180 MHz. @@ -27,6 +27,8 @@ get_filename_component(EMB_BOARD_GENERATED_DIR "${CMAKE_CURRENT_LIST_DIR}/.." AB set(EMB_BOARD_CONF "${EMB_BOARD_GENERATED_DIR}/config/board.conf") set(EMB_BOARD_HW_JSON "${EMB_BOARD_GENERATED_DIR}/docs/hw.json") set(EMB_BOARD_BUILD_DIR "${CMAKE_CURRENT_LIST_DIR}") # build/CMakeLists.txt +set(EMB_BOARD_SRC_DIR "${EMB_BOARD_GENERATED_DIR}/src") # its pin table and boot block +set(EMB_BOARD_LINKER_DIR "${EMB_BOARD_GENERATED_DIR}/linker") # the SoC family's board support and drivers build this board (build/CMakeLists.txt) set(EMB_SOC_DIR "${EMB_BASE}/soc/st/stm32f4") set(EMB_BOARD_INCLUDE_DIRS "${EMB_BOARD_GENERATED_DIR}/include" "${EMB_SOC_DIR}/include") @@ -45,8 +47,8 @@ set(EMB_BOARD_DRIVER_INCLUDE_DIRS set(EMB_BOARD_HW_INPUTS "arch/cortex_m/arch.yaml=c5c8e451c09717dee1713d07f8311b6d507e3b4c66c42d93e0ce11da6ec76d6d" "boards/st/nucleo_f446ze/board.yaml=1525ea206692663af174039e30776d6a9a9b30275c9e5c9bdabf14ac0b70aa19" - "drivers/bindings.yaml=d3c336ac05548e0addd1faac18f3dff70576d8069f11d89e6a761cf5c6132b49" - "soc/st/stm32f4/stm32f4.yaml=3db4a0a65c9624d865d4ed7fc6354bf95054d0c465b76a2091f06aeac3d7375f" - "soc/st/stm32f4/stm32f446.yaml=0d5cc7f5fce4c51be71678987720c85c6e76e05473ff8a78ea5035394316c055" + "drivers/bindings.yaml=c06d1a914adb21d0e314c79b3611ac6859eefeac1957d6914cccfc5531ad6ede" + "soc/st/stm32f4/stm32f4.yaml=796886c294250aa81151a620d80d0e43b5ee8e1bf53a07d1d7e2c62e95214dbd" + "soc/st/stm32f4/stm32f446.yaml=f0c9a37f6017c87d0efe215a3561f65494ba52383f2d0c10419b0ab5035f77f2" "soc/st/stm32f4/stm32f446ze.yaml=dabae95e9e4bc984c1a33275966665e0252068e929fe3b430d06589da6bdb6c9" ) diff --git a/boards/st/nucleo_f446ze/generated/config/board.conf b/boards/st/nucleo_f446ze/generated/config/board.conf index 0f706d76..00f89d0d 100644 --- a/boards/st/nucleo_f446ze/generated/config/board.conf +++ b/boards/st/nucleo_f446ze/generated/config/board.conf @@ -11,11 +11,11 @@ # boards/st/nucleo_f446ze/board.yaml # 1525ea206692663af174039e30776d6a9a9b30275c9e5c9bdabf14ac0b70aa19 # drivers/bindings.yaml -# d3c336ac05548e0addd1faac18f3dff70576d8069f11d89e6a761cf5c6132b49 +# c06d1a914adb21d0e314c79b3611ac6859eefeac1957d6914cccfc5531ad6ede # soc/st/stm32f4/stm32f4.yaml -# 3db4a0a65c9624d865d4ed7fc6354bf95054d0c465b76a2091f06aeac3d7375f +# 796886c294250aa81151a620d80d0e43b5ee8e1bf53a07d1d7e2c62e95214dbd # soc/st/stm32f4/stm32f446.yaml -# 0d5cc7f5fce4c51be71678987720c85c6e76e05473ff8a78ea5035394316c055 +# f0c9a37f6017c87d0efe215a3561f65494ba52383f2d0c10419b0ab5035f77f2 # soc/st/stm32f4/stm32f446ze.yaml # dabae95e9e4bc984c1a33275966665e0252068e929fe3b430d06589da6bdb6c9 # Board defaults for nucleo_f446ze. Applied before the profile fragment. diff --git a/boards/st/nucleo_f446ze/generated/docs/board.md b/boards/st/nucleo_f446ze/generated/docs/board.md index 3cd9f9e6..d4873d21 100644 --- a/boards/st/nucleo_f446ze/generated/docs/board.md +++ b/boards/st/nucleo_f446ze/generated/docs/board.md @@ -64,7 +64,10 @@ In initialization order (SPEC-016 §4). | 16 | dma1.s5 | | 17 | dma1.s6 | | 18 | adc1.global | +| 24 | tim9.global | | 28 | tim2.global | +| 29 | tim3.global | +| 30 | tim4.global | | 31 | i2c1.ev | | 32 | i2c1.er | | 33 | i2c2.ev | @@ -75,6 +78,7 @@ In initialization order (SPEC-016 §4). | 39 | usart3.global | | 41 | rtc.alarm | | 47 | dma1.s7 | +| 50 | tim5.global | | 52 | uart4.global | | 53 | uart5.global | | 56 | dma2.s0 | @@ -99,7 +103,7 @@ Generated by emb-hwgen 0.1.0, schema v0, from: |---|---| | `arch/cortex_m/arch.yaml` | `c5c8e451c09717dee1713d07f8311b6d507e3b4c66c42d93e0ce11da6ec76d6d` | | `boards/st/nucleo_f446ze/board.yaml` | `1525ea206692663af174039e30776d6a9a9b30275c9e5c9bdabf14ac0b70aa19` | -| `drivers/bindings.yaml` | `d3c336ac05548e0addd1faac18f3dff70576d8069f11d89e6a761cf5c6132b49` | -| `soc/st/stm32f4/stm32f4.yaml` | `3db4a0a65c9624d865d4ed7fc6354bf95054d0c465b76a2091f06aeac3d7375f` | -| `soc/st/stm32f4/stm32f446.yaml` | `0d5cc7f5fce4c51be71678987720c85c6e76e05473ff8a78ea5035394316c055` | +| `drivers/bindings.yaml` | `c06d1a914adb21d0e314c79b3611ac6859eefeac1957d6914cccfc5531ad6ede` | +| `soc/st/stm32f4/stm32f4.yaml` | `796886c294250aa81151a620d80d0e43b5ee8e1bf53a07d1d7e2c62e95214dbd` | +| `soc/st/stm32f4/stm32f446.yaml` | `f0c9a37f6017c87d0efe215a3561f65494ba52383f2d0c10419b0ab5035f77f2` | | `soc/st/stm32f4/stm32f446ze.yaml` | `dabae95e9e4bc984c1a33275966665e0252068e929fe3b430d06589da6bdb6c9` | diff --git a/boards/st/nucleo_f446ze/generated/docs/build_report.md b/boards/st/nucleo_f446ze/generated/docs/build_report.md index 14263ab1..b448b886 100644 --- a/boards/st/nucleo_f446ze/generated/docs/build_report.md +++ b/boards/st/nucleo_f446ze/generated/docs/build_report.md @@ -34,7 +34,7 @@ Generated by emb-hwgen 0.1.0, schema v0, from: |---|---| | `arch/cortex_m/arch.yaml` | `c5c8e451c09717dee1713d07f8311b6d507e3b4c66c42d93e0ce11da6ec76d6d` | | `boards/st/nucleo_f446ze/board.yaml` | `1525ea206692663af174039e30776d6a9a9b30275c9e5c9bdabf14ac0b70aa19` | -| `drivers/bindings.yaml` | `d3c336ac05548e0addd1faac18f3dff70576d8069f11d89e6a761cf5c6132b49` | -| `soc/st/stm32f4/stm32f4.yaml` | `3db4a0a65c9624d865d4ed7fc6354bf95054d0c465b76a2091f06aeac3d7375f` | -| `soc/st/stm32f4/stm32f446.yaml` | `0d5cc7f5fce4c51be71678987720c85c6e76e05473ff8a78ea5035394316c055` | +| `drivers/bindings.yaml` | `c06d1a914adb21d0e314c79b3611ac6859eefeac1957d6914cccfc5531ad6ede` | +| `soc/st/stm32f4/stm32f4.yaml` | `796886c294250aa81151a620d80d0e43b5ee8e1bf53a07d1d7e2c62e95214dbd` | +| `soc/st/stm32f4/stm32f446.yaml` | `f0c9a37f6017c87d0efe215a3561f65494ba52383f2d0c10419b0ab5035f77f2` | | `soc/st/stm32f4/stm32f446ze.yaml` | `dabae95e9e4bc984c1a33275966665e0252068e929fe3b430d06589da6bdb6c9` | diff --git a/boards/st/nucleo_f446ze/generated/docs/hw.json b/boards/st/nucleo_f446ze/generated/docs/hw.json index e59cbc85..82df30c2 100644 --- a/boards/st/nucleo_f446ze/generated/docs/hw.json +++ b/boards/st/nucleo_f446ze/generated/docs/hw.json @@ -116,8 +116,14 @@ "apb1": 45000000, "apb2": 90000000 }, + "bus_timer_hz": { + "ahb1": 180000000, + "apb1": 90000000, + "apb2": 180000000 + }, "bypass": true, "cpu_hz": 180000000, + "fixed_plls": {}, "flash_wait_states": 5, "hclk_hz": 180000000, "pclk1_div": 4, @@ -357,15 +363,15 @@ }, { "path": "drivers/bindings.yaml", - "sha256": "d3c336ac05548e0addd1faac18f3dff70576d8069f11d89e6a761cf5c6132b49" + "sha256": "c06d1a914adb21d0e314c79b3611ac6859eefeac1957d6914cccfc5531ad6ede" }, { "path": "soc/st/stm32f4/stm32f4.yaml", - "sha256": "3db4a0a65c9624d865d4ed7fc6354bf95054d0c465b76a2091f06aeac3d7375f" + "sha256": "796886c294250aa81151a620d80d0e43b5ee8e1bf53a07d1d7e2c62e95214dbd" }, { "path": "soc/st/stm32f4/stm32f446.yaml", - "sha256": "0d5cc7f5fce4c51be71678987720c85c6e76e05473ff8a78ea5035394316c055" + "sha256": "f0c9a37f6017c87d0efe215a3561f65494ba52383f2d0c10419b0ab5035f77f2" }, { "path": "soc/st/stm32f4/stm32f446ze.yaml", @@ -376,19 +382,49 @@ "soc": { "alternate_functions": { "PA0": { - "af8": "uart4_tx" + "af1": "tim2_ch1", + "af2": "tim5_ch1", + "af8": "uart4_tx", + "analog": "adc1_in0" }, "PA1": { - "af8": "uart4_rx" + "af1": "tim2_ch2", + "af2": "tim5_ch2", + "af8": "uart4_rx", + "analog": "adc1_in1" }, "PA10": { "af7": "usart1_rx" }, + "PA15": { + "af1": "tim2_ch1" + }, "PA2": { - "af7": "usart2_tx" + "af1": "tim2_ch3", + "af2": "tim5_ch3", + "af7": "usart2_tx", + "analog": "adc1_in2" }, "PA3": { - "af7": "usart2_rx" + "af1": "tim2_ch4", + "af2": "tim5_ch4", + "af7": "usart2_rx", + "analog": "adc1_in3" + }, + "PA4": { + "analog": "adc1_in4" + }, + "PA5": { + "af1": "tim2_ch1", + "analog": "adc1_in5" + }, + "PA6": { + "af2": "tim3_ch1", + "analog": "adc1_in6" + }, + "PA7": { + "af2": "tim3_ch2", + "analog": "adc1_in7" }, "PA8": { "af4": "i2c3_scl" @@ -396,7 +432,16 @@ "PA9": { "af7": "usart1_tx" }, + "PB0": { + "af2": "tim3_ch3", + "analog": "adc1_in8" + }, + "PB1": { + "af2": "tim3_ch4", + "analog": "adc1_in9" + }, "PB10": { + "af1": "tim2_ch3", "af4": "i2c2_scl", "af7": "usart3_tx" }, @@ -409,26 +454,46 @@ "PB15": { "af5": "spi2_mosi" }, + "PB2": { + "af1": "tim2_ch4" + }, "PB3": { + "af1": "tim2_ch2", "af4": "i2c2_sda" }, "PB4": { + "af2": "tim3_ch1", "af4": "i2c3_sda" }, + "PB5": { + "af2": "tim3_ch2" + }, "PB6": { + "af2": "tim4_ch1", "af4": "i2c1_scl", "af7": "usart1_tx" }, "PB7": { + "af2": "tim4_ch2", "af4": "i2c1_sda", "af7": "usart1_rx" }, "PB8": { + "af1": "tim2_ch1", + "af2": "tim4_ch3", "af4": "i2c1_scl" }, "PB9": { + "af1": "tim2_ch2", + "af2": "tim4_ch4", "af4": "i2c1_sda" }, + "PC0": { + "analog": "adc1_in10" + }, + "PC1": { + "analog": "adc1_in11" + }, "PC10": { "af7": "usart3_tx", "af8": "uart4_tx" @@ -441,16 +506,32 @@ "af4": "i2c2_sda", "af8": "uart5_tx" }, + "PC2": { + "analog": "adc1_in12" + }, + "PC3": { + "analog": "adc1_in13" + }, + "PC4": { + "analog": "adc1_in14" + }, "PC5": { - "af7": "usart3_rx" + "af7": "usart3_rx", + "analog": "adc1_in15" }, "PC6": { + "af2": "tim3_ch1", "af8": "usart6_tx" }, "PC7": { + "af2": "tim3_ch2", "af8": "usart6_rx" }, + "PC8": { + "af2": "tim3_ch3" + }, "PC9": { + "af2": "tim3_ch4", "af4": "i2c3_sda" }, "PD2": { @@ -579,6 +660,7 @@ "name": "lse" } ], + "timers_double_when_divided": true, "voltage_scales": [ { "max_hz": 120000000, @@ -723,12 +805,24 @@ "part": "STM32F446ZE", "peripherals": [ { + "adc": { + "bits": 12, + "inputs": 16, + "temperature": 18, + "vrefint": 17 + }, "base": 1073815552, "clock": { "bit": 8, "bus": "apb2" }, "compatible": "st,stm32f4-adc", + "dma_requests": { + "rx": [ + "dma2.s0c0", + "dma2.s4c0" + ] + }, "irqs": [ { "name": "global", @@ -903,12 +997,14 @@ "size": 1024 }, { + "adc_trigger": 6, "base": 1073741824, "clock": { "bit": 0, "bus": "apb1" }, "compatible": "st,stm32-tim", + "counter_bits": 32, "irqs": [ { "name": "global", @@ -918,6 +1014,76 @@ "name": "tim2", "size": 1024 }, + { + "adc_trigger": 8, + "base": 1073742848, + "clock": { + "bit": 1, + "bus": "apb1" + }, + "compatible": "st,stm32-tim", + "counter_bits": 16, + "irqs": [ + { + "name": "global", + "number": 29 + } + ], + "name": "tim3", + "size": 1024 + }, + { + "base": 1073743872, + "clock": { + "bit": 2, + "bus": "apb1" + }, + "compatible": "st,stm32-tim", + "counter_bits": 16, + "irqs": [ + { + "name": "global", + "number": 30 + } + ], + "name": "tim4", + "size": 1024 + }, + { + "base": 1073744896, + "clock": { + "bit": 3, + "bus": "apb1" + }, + "compatible": "st,stm32-tim", + "counter_bits": 32, + "irqs": [ + { + "name": "global", + "number": 50 + } + ], + "name": "tim5", + "size": 1024 + }, + { + "base": 1073823744, + "clock": { + "bit": 16, + "bus": "apb2" + }, + "compatible": "st,stm32-tim", + "counter_bits": 16, + "irqs": [ + { + "name": "global", + "number": 24 + } + ], + "name": "tim9", + "size": 1024, + "timer_channels": 2 + }, { "base": 1073897472, "clock": { diff --git a/boards/st/nucleo_f446ze/generated/include/hw_config.h b/boards/st/nucleo_f446ze/generated/include/hw_config.h index 582285e7..1a33077b 100644 --- a/boards/st/nucleo_f446ze/generated/include/hw_config.h +++ b/boards/st/nucleo_f446ze/generated/include/hw_config.h @@ -17,11 +17,11 @@ * boards/st/nucleo_f446ze/board.yaml * 1525ea206692663af174039e30776d6a9a9b30275c9e5c9bdabf14ac0b70aa19 * drivers/bindings.yaml - * d3c336ac05548e0addd1faac18f3dff70576d8069f11d89e6a761cf5c6132b49 + * c06d1a914adb21d0e314c79b3611ac6859eefeac1957d6914cccfc5531ad6ede * soc/st/stm32f4/stm32f4.yaml - * 3db4a0a65c9624d865d4ed7fc6354bf95054d0c465b76a2091f06aeac3d7375f + * 796886c294250aa81151a620d80d0e43b5ee8e1bf53a07d1d7e2c62e95214dbd * soc/st/stm32f4/stm32f446.yaml - * 0d5cc7f5fce4c51be71678987720c85c6e76e05473ff8a78ea5035394316c055 + * f0c9a37f6017c87d0efe215a3561f65494ba52383f2d0c10419b0ab5035f77f2 * soc/st/stm32f4/stm32f446ze.yaml * dabae95e9e4bc984c1a33275966665e0252068e929fe3b430d06589da6bdb6c9 */ @@ -164,6 +164,22 @@ #define EMB_HW_TIM2_CLKEN_BIT 0u #define EMB_HW_TIM2_CLKEN_OFFSET 0x40u #define EMB_HW_TIM2_IRQ 28u +#define EMB_HW_TIM3_BASE 0x40000400u +#define EMB_HW_TIM3_CLKEN_BIT 1u +#define EMB_HW_TIM3_CLKEN_OFFSET 0x40u +#define EMB_HW_TIM3_IRQ 29u +#define EMB_HW_TIM4_BASE 0x40000800u +#define EMB_HW_TIM4_CLKEN_BIT 2u +#define EMB_HW_TIM4_CLKEN_OFFSET 0x40u +#define EMB_HW_TIM4_IRQ 30u +#define EMB_HW_TIM5_BASE 0x40000C00u +#define EMB_HW_TIM5_CLKEN_BIT 3u +#define EMB_HW_TIM5_CLKEN_OFFSET 0x40u +#define EMB_HW_TIM5_IRQ 50u +#define EMB_HW_TIM9_BASE 0x40014000u +#define EMB_HW_TIM9_CLKEN_BIT 16u +#define EMB_HW_TIM9_CLKEN_OFFSET 0x44u +#define EMB_HW_TIM9_IRQ 24u #define EMB_HW_UART4_BASE 0x40004C00u #define EMB_HW_UART4_CLKEN_BIT 19u #define EMB_HW_UART4_CLKEN_OFFSET 0x40u diff --git a/boards/st/nucleo_f446ze/generated/include/soc_devices.h b/boards/st/nucleo_f446ze/generated/include/soc_devices.h index 4c03b851..b45b953a 100644 --- a/boards/st/nucleo_f446ze/generated/include/soc_devices.h +++ b/boards/st/nucleo_f446ze/generated/include/soc_devices.h @@ -17,11 +17,11 @@ * boards/st/nucleo_f446ze/board.yaml * 1525ea206692663af174039e30776d6a9a9b30275c9e5c9bdabf14ac0b70aa19 * drivers/bindings.yaml - * d3c336ac05548e0addd1faac18f3dff70576d8069f11d89e6a761cf5c6132b49 + * c06d1a914adb21d0e314c79b3611ac6859eefeac1957d6914cccfc5531ad6ede * soc/st/stm32f4/stm32f4.yaml - * 3db4a0a65c9624d865d4ed7fc6354bf95054d0c465b76a2091f06aeac3d7375f + * 796886c294250aa81151a620d80d0e43b5ee8e1bf53a07d1d7e2c62e95214dbd * soc/st/stm32f4/stm32f446.yaml - * 0d5cc7f5fce4c51be71678987720c85c6e76e05473ff8a78ea5035394316c055 + * f0c9a37f6017c87d0efe215a3561f65494ba52383f2d0c10419b0ab5035f77f2 * soc/st/stm32f4/stm32f446ze.yaml * dabae95e9e4bc984c1a33275966665e0252068e929fe3b430d06589da6bdb6c9 */ diff --git a/boards/st/nucleo_f446ze/generated/linker/regions.ld b/boards/st/nucleo_f446ze/generated/linker/regions.ld index 49ba192d..be64b58d 100644 --- a/boards/st/nucleo_f446ze/generated/linker/regions.ld +++ b/boards/st/nucleo_f446ze/generated/linker/regions.ld @@ -19,11 +19,11 @@ * boards/st/nucleo_f446ze/board.yaml * 1525ea206692663af174039e30776d6a9a9b30275c9e5c9bdabf14ac0b70aa19 * drivers/bindings.yaml - * d3c336ac05548e0addd1faac18f3dff70576d8069f11d89e6a761cf5c6132b49 + * c06d1a914adb21d0e314c79b3611ac6859eefeac1957d6914cccfc5531ad6ede * soc/st/stm32f4/stm32f4.yaml - * 3db4a0a65c9624d865d4ed7fc6354bf95054d0c465b76a2091f06aeac3d7375f + * 796886c294250aa81151a620d80d0e43b5ee8e1bf53a07d1d7e2c62e95214dbd * soc/st/stm32f4/stm32f446.yaml - * 0d5cc7f5fce4c51be71678987720c85c6e76e05473ff8a78ea5035394316c055 + * f0c9a37f6017c87d0efe215a3561f65494ba52383f2d0c10419b0ab5035f77f2 * soc/st/stm32f4/stm32f446ze.yaml * dabae95e9e4bc984c1a33275966665e0252068e929fe3b430d06589da6bdb6c9 */ diff --git a/boards/st/nucleo_f446ze/generated/src/board_pins.c b/boards/st/nucleo_f446ze/generated/src/board_pins.c index 50713493..54cc19fb 100644 --- a/boards/st/nucleo_f446ze/generated/src/board_pins.c +++ b/boards/st/nucleo_f446ze/generated/src/board_pins.c @@ -18,11 +18,11 @@ * boards/st/nucleo_f446ze/board.yaml * 1525ea206692663af174039e30776d6a9a9b30275c9e5c9bdabf14ac0b70aa19 * drivers/bindings.yaml - * d3c336ac05548e0addd1faac18f3dff70576d8069f11d89e6a761cf5c6132b49 + * c06d1a914adb21d0e314c79b3611ac6859eefeac1957d6914cccfc5531ad6ede * soc/st/stm32f4/stm32f4.yaml - * 3db4a0a65c9624d865d4ed7fc6354bf95054d0c465b76a2091f06aeac3d7375f + * 796886c294250aa81151a620d80d0e43b5ee8e1bf53a07d1d7e2c62e95214dbd * soc/st/stm32f4/stm32f446.yaml - * 0d5cc7f5fce4c51be71678987720c85c6e76e05473ff8a78ea5035394316c055 + * f0c9a37f6017c87d0efe215a3561f65494ba52383f2d0c10419b0ab5035f77f2 * soc/st/stm32f4/stm32f446ze.yaml * dabae95e9e4bc984c1a33275966665e0252068e929fe3b430d06589da6bdb6c9 */ diff --git a/boards/st/nucleo_f446ze/generated/src/soc_devices.c b/boards/st/nucleo_f446ze/generated/src/soc_devices.c index 3072f2e5..496c10e1 100644 --- a/boards/st/nucleo_f446ze/generated/src/soc_devices.c +++ b/boards/st/nucleo_f446ze/generated/src/soc_devices.c @@ -18,11 +18,11 @@ * boards/st/nucleo_f446ze/board.yaml * 1525ea206692663af174039e30776d6a9a9b30275c9e5c9bdabf14ac0b70aa19 * drivers/bindings.yaml - * d3c336ac05548e0addd1faac18f3dff70576d8069f11d89e6a761cf5c6132b49 + * c06d1a914adb21d0e314c79b3611ac6859eefeac1957d6914cccfc5531ad6ede * soc/st/stm32f4/stm32f4.yaml - * 3db4a0a65c9624d865d4ed7fc6354bf95054d0c465b76a2091f06aeac3d7375f + * 796886c294250aa81151a620d80d0e43b5ee8e1bf53a07d1d7e2c62e95214dbd * soc/st/stm32f4/stm32f446.yaml - * 0d5cc7f5fce4c51be71678987720c85c6e76e05473ff8a78ea5035394316c055 + * f0c9a37f6017c87d0efe215a3561f65494ba52383f2d0c10419b0ab5035f77f2 * soc/st/stm32f4/stm32f446ze.yaml * dabae95e9e4bc984c1a33275966665e0252068e929fe3b430d06589da6bdb6c9 */ diff --git a/changes/feat-m4.2b-adc-timers.md b/changes/feat-m4.2b-adc-timers.md new file mode 100644 index 00000000..eece4493 --- /dev/null +++ b/changes/feat-m4.2b-adc-timers.md @@ -0,0 +1,33 @@ +### Added (the counter, PWM and ADC classes' descriptions, 2026-11-13) + +- The STM32F446's description gains TIM3, TIM4 and TIM5 and their channels' pins, its ADC1's inputs, temperature sensor, internal reference and DMA2 streams, and the analog function of PA0 to PA7, PB0, PB1 and PC0 to PC5. The RP2350's gains its ADC, the PWM block's twelve slices, TIMER0 and TIMER1, PLL_USB at 48 MHz for clk_adc, each line's PWM function and the ADC's inputs on GPIO26 to GPIO29 ([A129](docs/specs/AMENDMENTS-M4.md)). +- The generator takes a binding per class for a peripheral several classes can drive, keyed `compatible:class`, and a board device's `class:` picks one; it computes the STM32F4 timers' doubled clock, solves a PLL of a fixed rate, configures analog pins, and reads a timer's `counter_bits` and an ADC's `adc:` facts ([hwgen](docs/engineering/hwgen.md)). + +### Added (the counter class, 2026-11-13) + +- ``, behind `CONFIG_EMB_DRV_COUNTER` (SPEC-017 §11a, [A129](docs/specs/AMENDMENTS-M4.md)): a free-running counter at a known rate, widened to 64 bits; one-shot alarms on its channels at an absolute count, never early, `EMB_EPAST` for one already passed; and periodic callbacks without drift, late periods skipped. Each callback runs in the counter's interrupt. +- Drivers: the STM32's general-purpose timers (`drivers/st/stm32_tim_counter.c`; the NUCLEO-F446RE's TIM5, 32 bits, and TIM9, 16), and the RP2350's TIMER0 and TIMER1 (`drivers/rpi/rp2350_timer.c`; the Pico 2 W's TIMER1). +- The status codes of the counter and PWM classes: `EMB_EPAST` (−96) and `EMB_ENOSIGNAL` (−100). +- The NUCLEO-F446RE's description gains TIM9, two channels (`timer_channels:`), and a binding's fields read a peripheral's number, `peripheral.index` (TIMER1's tick generator). + +### Added (the PWM class, 2026-11-13) + +- ``, behind `CONFIG_EMB_DRV_PWM` (SPEC-017 §11b, [A129](docs/specs/AMENDMENTS-M4.md)): a device's output channels set by period and pulse in nanoseconds, rounded to the nearest the hardware makes and reported back, sharing the device's period, inverted on request; and an input's period and pulse captured, `EMB_ENOSIGNAL` when no whole cycle comes. +- Drivers: the STM32's general-purpose timers (`drivers/st/stm32_tim_pwm.c`: PWM mode 1, one cycle captured exactly in PWM input mode; the NUCLEO-F446RE's TIM3 out on D12 and TIM4 in on D10) and the RP2350's slices (`drivers/rpi/rp2350_pwm.c`: A and B out, B averaged over a gate; the Pico 2 W's slice 7 out on GPIO14 and slice 0 in on GPIO17). +- `test_pwm_loop`, an output wired to a capture input, configured by `EMB_TEST_PWM_LOOP`. + +### Added (the ADC class, and circular DMA, 2026-11-13) + +- ``, behind `CONFIG_EMB_DRV_ADC` (SPEC-017 §11c, [A129](docs/specs/AMENDMENTS-M4.md)): one conversion, waiting or polled from any context; a count's millivolts against the board's reference; the internal temperature sensor; and a sequence of inputs sampled at a rate into a buffer by DMA, a callback at each half, `EMB_EOVERRUN` when the hardware loses samples. +- Drivers: the STM32F4's ADC1 (`drivers/st/stm32_adc.c`: paced by TIM2's TRGO, moved by DMA2, its temperature from the factory calibration, set up by each request so the reference controller keeps driving it by hand) and the RP2350's ADC (`drivers/rpi/rp2350_adc.c`: on clk_adc, 48 MHz from PLL_USB, a round robin drained through its FIFO by DMA). +- The DMA class's circular jobs (`EMB_DRV_DMA_CIRCULAR`, SPEC-017 §7): the STM32's circular mode, and on the RP2350 one channel that triggers itself again over its address ring. +- The board's devices: the NUCLEO-F446RE's ADC1 on A2 and A3 and DMA2; the Pico 2 W's ADC on GPIO26 and GPIO27. `test_adc_board`, configured by `EMB_TEST_ADC_LOOP`. +- EmbSIM runs the PWM loop (D12 to D10) and the ADC's inputs (A2 to 3V3, A3 to GND) on the NUCLEO-F446RE in CI: `simulation.loopbacks` takes a PWM pair and an ADC's rails. +- The benchmarks read the board's `hw.json` from its `docs/`, where A126 put it. + +### Changed (applications in MPLAB Harmony's form, 2026-11-13) + +- An application's generated files follow MPLAB Harmony v3 ([A130](docs/specs/AMENDMENTS-M4.md)). Each board's are in Harmony's configuration folder, `src/config//`: `definitions.h`, `configuration.h`, `initialization.c` with `SYS_Initialize()`, `tasks.c` with the tasks and `SYS_Tasks()`, `interrupts.c`, and the board's own outputs under `peripheral/`, `linker/`, `build/` and `docs/`. `system.h`, `system.c` and `tasks.h` are gone. +- `src/main.c` calls `SYS_Initialize(NULL)` and then `SYS_Tasks()`, and each task is `src/.c` and `.h` in Harmony's template, with its banner, sections and function blocks, and Harmony's names: `DOOR_STATES`, `DOOR_EVENTS`, `DOOR_DATA doorData`, `DOOR_Initialize()`, `DOOR_OnOpen()`. A periodic task is Harmony's `BLINK_Tasks()` switch, run every period without drift; an event task keeps a handler per state. A task's `data:` is gone: its data is its `_DATA`. +- A system's `interrupts:` lists the application's own interrupt handlers, by line number, by `.` or by board, each checked against the SoC, the devices' lines and the port's levels. `examples/tasks` raises one, a spare line on each SoC, and its handler opens the door. +- `examples/tasks` and `examples/controller` are regenerated; the tasks example ran on the NUCLEO-F446RE and the Pico 2 W, the door opening by the interrupt every 4 s and closing itself 2 s later. The naming check is relaxed for applications' files alone (`examples/.clang-tidy`). diff --git a/cmake/emb_config.cmake b/cmake/emb_config.cmake index 8497af45..fca11664 100644 --- a/cmake/emb_config.cmake +++ b/cmake/emb_config.cmake @@ -24,17 +24,17 @@ foreach(_r ${EMB_BOARD_ROOT}) list(APPEND _emb_roots "${_r}") endforeach() # An application with a system description (SPEC-014 §5, A125): its board is one of the -# system's, generated with the system's settings into generated// beside it; EMB_BOARD -# picks it, the system's first board by default. +# system's, generated with the system's settings into src/config// beside it (A130); +# EMB_BOARD picks it, the system's first board by default. set(EMB_SYSTEM "" CACHE FILEPATH "The application's system.yaml (SPEC-014 §5), relative to its source tree") set(_emb_board_cmake "") set(_all "") if(EMB_SYSTEM) get_filename_component(EMB_SYSTEM "${EMB_SYSTEM}" ABSOLUTE BASE_DIR "${CMAKE_SOURCE_DIR}") get_filename_component(EMB_SYSTEM_DIR "${EMB_SYSTEM}" DIRECTORY) - file(GLOB _sys_json "${EMB_SYSTEM_DIR}/generated/*/docs/system.json") + file(GLOB _sys_json "${EMB_SYSTEM_DIR}/src/config/*/docs/system.json") if(NOT _sys_json) - message(FATAL_ERROR "EMB_SYSTEM: ${EMB_SYSTEM} has no generated//; " + message(FATAL_ERROR "EMB_SYSTEM: ${EMB_SYSTEM} has no src/config//; " "run python3 -I hw/gen/emb-hwgen.py generate --system ${EMB_SYSTEM}") endif() list(GET _sys_json 0 _one) @@ -53,9 +53,9 @@ if(EMB_SYSTEM) string(REPLACE ";" " " _names "${_sys_boards}") message(FATAL_ERROR "EMB_BOARD='${EMB_BOARD}' is not one of the system's boards: ${_names}") endif() - set(_emb_board_cmake "${EMB_SYSTEM_DIR}/generated/${EMB_BOARD}/build/board.cmake") + set(_emb_board_cmake "${EMB_SYSTEM_DIR}/src/config/${EMB_BOARD}/build/board.cmake") if(NOT EXISTS "${_emb_board_cmake}") - message(FATAL_ERROR "EMB_SYSTEM: no generated/${EMB_BOARD}/; " + message(FATAL_ERROR "EMB_SYSTEM: no src/config/${EMB_BOARD}/; " "run python3 -I hw/gen/emb-hwgen.py generate --system ${EMB_SYSTEM}") endif() set(_emb_roots "") @@ -97,6 +97,14 @@ endif() if(NOT DEFINED EMB_BOARD_BUILD_DIR) set(EMB_BOARD_BUILD_DIR "${EMB_BOARD_DIR}") endif() +# a generated board's pin table and linker script: src/ and linker/ in a board's own +# generated/ (A126), peripheral/ and linker/ in an application's src/config// (A130) +if(NOT DEFINED EMB_BOARD_SRC_DIR) + set(EMB_BOARD_SRC_DIR "${EMB_BOARD_DIR}/src") +endif() +if(NOT DEFINED EMB_BOARD_LINKER_DIR) + set(EMB_BOARD_LINKER_DIR "${EMB_BOARD_DIR}/linker") +endif() if(DEFINED EMB_BOARD_HW_INPUTS) # a generated board: refuse outputs older than their descriptions (HW-003), and reconfigure # when a description changes diff --git a/cmake/emb_target.cmake b/cmake/emb_target.cmake index 7c30b092..c676431b 100644 --- a/cmake/emb_target.cmake +++ b/cmake/emb_target.cmake @@ -16,12 +16,13 @@ set(EMB_STACK_ROOTS "" CACHE FILEPATH "The application's stack-roots.json, for t function(emb_add_executable name) _emb_add_image(${name} ${ARGN}) if(EMB_SYSTEM) - # the system's static definitions and targets (SPEC-014 §5.1), and its headers' directory - target_sources(${name} PRIVATE "${EMB_BOARD_DIR}/src/system.c") - if(EXISTS "${EMB_BOARD_DIR}/src/tasks.c") - target_sources(${name} PRIVATE "${EMB_BOARD_DIR}/src/tasks.c") # the system's tasks (SPEC-020) + # the system's configuration folder (A130): SYS_Initialize() and the system's objects, the + # tasks and SYS_Tasks(), the application's interrupts, and definitions.h and configuration.h + target_sources(${name} PRIVATE "${EMB_BOARD_DIR}/initialization.c" "${EMB_BOARD_DIR}/tasks.c") + if(EXISTS "${EMB_BOARD_DIR}/interrupts.c") + target_sources(${name} PRIVATE "${EMB_BOARD_DIR}/interrupts.c") endif() - target_include_directories(${name} PRIVATE "${EMB_BOARD_DIR}/include" "${EMB_SYSTEM_DIR}" "${EMB_SYSTEM_DIR}/src") + target_include_directories(${name} PRIVATE "${EMB_BOARD_DIR}" "${EMB_SYSTEM_DIR}/src" "${EMB_SYSTEM_DIR}") _emb_stack_check(${name}) endif() if(CONFIG_EMB_ARCH STREQUAL "native") diff --git a/docs/engineering/hwgen.md b/docs/engineering/hwgen.md index 8411c856..73627d32 100644 --- a/docs/engineering/hwgen.md +++ b/docs/engineering/hwgen.md @@ -99,6 +99,8 @@ Each output is sorted and carries no timestamp. It names the generator version, 2. Then N ascending, then P ascending. The first exact match wins. 3. Q is the divider closest to 48 MHz without exceeding it. - **Buses.** Each APB divider is the smallest that keeps its bus within its limit. +- **Timers.** Where the SoC says `timers_double_when_divided` (the STM32F4, RM0390 §6.2), the timers on an APB bus whose divider is not 1 run at twice its clock: the NUCLEO-F446RE's APB1 runs at 45 MHz and its timers at 90 MHz. A binding reads the rate as `peripheral.timer_clock_hz` (A129). +- **PLLs of a fixed rate.** A PLL with an `output_hz` is not the CPU's: it is solved for exactly that rate from the board's clock source, with the same search, whatever the CPU runs at. The RP2350's PLL_USB makes the 48 MHz of clk_adc and clk_usb this way. `hw_config.h` gets `EMB_HW__M`, `_N`, `_POSTDIV1`, `_POSTDIV2` and `_HZ`, and the driver that needs the PLL starts it. A peripheral clocked by it says `clocked_by: `, and its `peripheral.clock_hz` is the PLL's rate (A129). - **Flash.** Wait states follow the SoC's table. - **Regulator.** The scale is the lowest-power one that covers HCLK without over-drive. Failing that, the solver uses the first that covers it with over-drive. @@ -194,7 +196,11 @@ devices: - { name: sensor, compatible: "bosch,bme280", bus: i2c1, address: 0x76 } ``` -- **Binding.** Each device's `compatible`, its own or its peripheral's, must be in `drivers/bindings.yaml`, or in the board root's `drivers/bindings.yaml` for a board outside the tree (A84); a compatible bound in both is refused. A binding's `fields` map the configuration structure's members to `peripheral.` (the SoC node: `base`, `irqs.`, `clock.bus`, `clock.bit`, `clock.enable_offset`, and `clock_hz`, the frequency it runs at), `device.` (the board entry; `device.bus` is the bus device's address) or `board.`. A binding's `buffers` are RAM the generator gives each device, sized by a device property or the binding's default, such as a UART's receive ring (`buffers: { rx: { size: device.rx_buffer, default: 64 } }`); the configuration receives each buffer and its size as `` and `_size`. +- **Binding.** Each device's `compatible`, its own or its peripheral's, must be in `drivers/bindings.yaml`, or in the board root's `drivers/bindings.yaml` for a board outside the tree (A84); a compatible bound in both is refused. A binding's `fields` map the configuration structure's members to `peripheral.` (the SoC node: `base`, `irqs.`, `clock.bus`, `clock.bit`, `clock.enable_offset`, and `clock_hz`, the frequency it runs at), `device.` (the board entry; `device.bus` is the bus device's address) or `board.`. A binding's `buffers` are RAM the generator gives each device, sized by a device property or the binding's default, such as a UART's receive ring (`buffers: { rx: { size: device.rx_buffer, default: 64 } }`); the configuration receives each buffer and its size as `` and `_size`. A field may have a default, for a device that does not give it: `rate_hz: { from: device.rate_hz, default: 1000000 }` (A129). +- **Peripherals a device takes.** A binding's `takes:` names peripherals a device uses besides its own, by the device key that names each and the compatible it must have: the STM32 ADC's pacing timer, `takes: { trigger: "st,stm32-tim" }`, with the board's `- { name: adc1, trigger: tim2 }`. The generator checks that the peripheral exists, has that compatible and is no other device, reserves it, orders the device after the clock tree when the taken peripheral has a clock gate, and offers it to the fields as `takes..` (`takes.trigger.base`, `takes.trigger.timer_clock_hz`) (A129). +- **A binding per class.** A peripheral that drivers of several classes can drive, a timer that is a counter or PWM, has a binding for each, keyed `:` (`st,stm32-tim:counter`, `st,stm32-tim:pwm`). Its board device names the one it wants with `class:` (`- { name: tim5, class: counter }`); without it the device is refused (`st,stm32-tim has drivers for counter and pwm: say which with class:`). A compatible with one binding needs no `class:` (A129). +- **Counters and ADCs in the SoC.** A timer's node gives its counter width, `counter_bits` (16, 24, 32 or 64), and an ADC's its `adc: { bits, inputs, temperature, vrefint }`: its resolution, its external inputs, and the inputs of its temperature sensor and internal reference. Bindings read them as `peripheral.counter_bits` and `peripheral.adc.`. A package file completes what depends on the package: the RP2350A's ADC has four inputs and the temperature sensor on the fifth (A129). +- **Analog pins.** A pin the SoC lists as `analog: ` (`PA4: { analog: adc1_in4 }`) is an ADC's input, named without a function: `adc1: { in4: PA4 }`. It is configured in its analog mode, its digital input off: MODER 11 on the STM32, function NULL with no pull and the pad's input off on the RP2350 (A129). - **Loopbacks on EmbSIM.** A board's `simulation.loopbacks` names a UART device and two EmbSIM board ports to wire together, as the bench's loopback wire does (the NUCLEO-F446RE: `uart4`, A0 to A1). `board.cmake` passes them on, and an EmbSIM build runs `test_uart_loop` inside a project with that wire (`tools/embsim/run_embsim.py --net`). - **Names for code.** `soc_devices.h` defines `EMB_SOC_HAS_` for each device, and `EMB_SOC_CONSOLE_DEVICE` when the board's console is a UART device, so code and tests can use a device only where the board has it. - **Order.** EARLY devices come first, then KERNEL ones. Within a level, each device follows its `deps`, its `bus` and, for a peripheral with a clock gate, the board's clock-class devices. Ties keep the description's order, so the order is deterministic (DRV-001). @@ -272,14 +278,14 @@ The draft is the package file's `gpio.ports` and the `alternate_functions` of th ## Applications: the system description -An application's `system.yaml` (SPEC-014 §5, A125) names its boards, Kconfig fragments, threads, kernel objects, device settings, SPI and I2C targets and watchdog. `generate --system` resolves it on each of its boards and writes `generated//` beside it. The board's outputs are rendered again with the system's device settings, and `system.h`, `system.c`, `system.json` and `system.md` are added. `check` finds every `system.yaml` in the tree, outside build directories, and compares each board's directory as it does a board's. +An application's `system.yaml` (SPEC-014 §5, A125) names its boards, Kconfig fragments, threads, tasks, kernel objects, device settings, SPI and I2C targets, watchdog and interrupt handlers. `generate --system` resolves it on each of its boards and writes MPLAB Harmony's configuration folder, `src/config//`, beside it (A130): `definitions.h`, `configuration.h`, `initialization.c` (`SYS_Initialize()` and the static definitions), `tasks.c` (the tasks and `SYS_Tasks()`), and `interrupts.h` and `interrupts.c` when the system has interrupt handlers. The board's outputs are rendered again with the system's device settings under `peripheral/`, `linker/`, `build/` and `docs/`, beside `system.json` and `system.md`; `board.cmake` gives their folders to the SoC's build (`EMB_BOARD_SRC_DIR`, `EMB_BOARD_LINKER_DIR`). The application's own files, `CMakeLists.txt`, `src/main.c`, each task's `src/.c` and `.h` and `src/interrupt_handlers.c`, are written in Harmony's templates and names (`emit_system.py`). A generate that finds A126's `generated/` or `src/tasks/` beside the system warns that their edits are to be moved. `check` finds every `system.yaml` in the tree, outside build directories, and compares each board's folder as it does a board's. - **Device settings:** the system's settings replace the board description's values before the board is resolved, each keeping its own line. An error about one therefore names `system.yaml`. - **Configuration:** comes from `tools/kconfig/embconfig.py`, run over the board's fragment, the profile's and the system's, as the build runs it. - **Limits:** the target and watchdog checks read `limits:` in `drivers/bindings.yaml`, the figures each driver enforces. - **Several boards:** with more than one board, an error found on one names it. -The build takes the system with `EMB_SYSTEM`, picks a board with `EMB_BOARD` (the first of `system.json`'s `boards` by default), compiles `system.c` with the application, and, with `EMB_STACK_ROOTS` on Cortex-M, runs `stack_bound.py --system` after the link. The tests are `hw/gen/test_system.py`. +The build takes the system with `EMB_SYSTEM`, picks a board with `EMB_BOARD` (the first of `system.json`'s `boards` by default), compiles `initialization.c`, `tasks.c` and `interrupts.c` with the application, and, with `EMB_STACK_ROOTS` on Cortex-M, runs `stack_bound.py --system` after the link. The tests are `hw/gen/test_system.py`. ## A board outside the tree diff --git a/docs/engineering/resource-bounds.json b/docs/engineering/resource-bounds.json index b0f2c4e8..86503a62 100644 --- a/docs/engineering/resource-bounds.json +++ b/docs/engineering/resource-bounds.json @@ -293,6 +293,16 @@ "profiles": "base with CONFIG_EMB_DRV_ENTROPY; the read waits for each block on the driver's semaphore", "evidence": "SPEC-017 \u00a711, A124; test_entropy, test_entropy_board" }, + { + "id": "pwm_input", + "input": "the cycles of one captured input", + "bound": "the caller's timeout: one cycle and a part where the driver captures edges, the gate time, a quarter of the timeout from 4 to 50 ms, where it averages", + "limit": "application", + "enforcement": "application", + "masked": false, + "profiles": "base with CONFIG_EMB_DRV_PWM; the STM32 waits for the input's edges on the driver's semaphore, the RP2350 sleeps through its gate and polls for a count's change at each end", + "evidence": "SPEC-017 \u00a711b, A129; test_pwm, test_pwm_loop" + }, { "id": "task_handlers", "input": "a task's state handlers, entry and exit handlers", @@ -889,6 +899,15 @@ "emb_trace_dump": [ "trace_ring", "console_line" + ], + "emb_drv_counter_fired": [ + "callbacks" + ], + "emb_drv_pwm_capture": [ + "pwm_input" + ], + "emb_drv_adc_sampled": [ + "callbacks" ] } } diff --git a/docs/engineering/resource-bounds.md b/docs/engineering/resource-bounds.md index ab626f49..66344640 100644 --- a/docs/engineering/resource-bounds.md +++ b/docs/engineering/resource-bounds.md @@ -35,6 +35,7 @@ Every cost input named by a public function's `@time` annotation, with how it is | **flash_sectors**: the sectors of one erase, and the geometry's sectors a lookup walks | the description's: 8 on the STM32F446, 1024 of 4 KiB on the Pico 2 W's flash; an erase holds interrupts off one sector at a time, up to 4 s for a 128 KiB sector of the STM32F446 and some 45 ms for one of the RP2350's | the board's description | configuration | yes | base with CONFIG_EMB_DRV_FLASH; the clock catches up after each sector (A122) | SPEC-017 §9, A122; test_flash, test_flash_board | | **rtc_oscillator**: an RTC set: the wait for its oscillator after power-up, and for the hardware to take a fraction of a second | 3 s for the oscillator, in 10 ms sleeps: the STM32F446's LSE starts within 2 s (its datasheet), and the RP2350's tick is the crystal's, already running; 100 ms for the STM32F446's shift of the subseconds, in 1 ms sleeps, measured at some 23 ms | the driver's wait | structural | no | base with CONFIG_EMB_DRV_RTC; the caller sleeps between checks | SPEC-017 §10, A123; test_rtc_board | | **entropy_bytes**: bytes of one entropy read | the caller's: the length it passes, read a block at a time within its timeout; a block the source's health test fails ends the read | application | application | no | base with CONFIG_EMB_DRV_ENTROPY; the read waits for each block on the driver's semaphore | SPEC-017 §11, A124; test_entropy, test_entropy_board | +| **pwm_input**: the cycles of one captured input | the caller's timeout: one cycle and a part where the driver captures edges, the gate time, a quarter of the timeout from 4 to 50 ms, where it averages | application | application | no | base with CONFIG_EMB_DRV_PWM; the STM32 waits for the input's edges on the driver's semaphore, the RP2350 sleeps through its gate and polls for a count's change at each end | SPEC-017 §11b, A129; test_pwm, test_pwm_loop | | **task_handlers**: a task's state handlers, entry and exit handlers | the application's: each runs to completion, one at a time (KRN-TSK-001) | the application's handlers; the task's thread priority bounds what they delay | application | no | base, isolated: the task runtime (CONFIG_EMB_TASK); tiny: none | SPEC-020 §4, §5; tests/conformance/test_task.c | | **frame_bytes**: bytes of one frame: the payload encoded, or the frame decoded | the caller's: the payload it passes to emb_frame_encode(), and for a decoded frame the decoder's buffer, past which the frame is dropped | application: the buffers the caller gives | admission | no | every profile; the CRC is bitwise, eight steps a byte | SPEC-015 §7; OBS-019; test_frame | | **console_line**: the console's line time: bytes written polled at its baud rate | the frame's bytes, each one character time (87 us at 115200 baud) | application: what it sends, and the board's console rate | application | no | every profile; a thread holds the console's mutex while it writes a frame, so other threads' frames wait (A127) | SPEC-015 §7; A127 | @@ -57,8 +58,10 @@ Every cost input named by a public function's `@time` annotation, with how it is | `emb_device_init_list()` | O(count) plus the drivers' init | devices, device_deps, drivers | | `emb_device_resume()` | O(1) plus the driver's resume | drivers | | `emb_device_suspend()` | O(1) plus the driver's suspend | drivers | +| `emb_drv_adc_sampled()` | O(1) plus the callback | callbacks | | `emb_drv_cancel()` | O(queued requests) plus the driver's stop | device_queue, drivers | | `emb_drv_complete()` | O(1) plus the next request's start | drivers | +| `emb_drv_counter_fired()` | O(1) plus the callback | callbacks | | `emb_drv_dma_start()` | O(regions): the memory checked against the board's DMA regions | dma_regions, drivers | | `emb_drv_dma_stop()` | O(1); the controller's own stop, a few bus cycles | dma_regions, drivers | | `emb_drv_entropy_lock_init()` | O(1); O(active mutexes) list lookup with CONFIG_EMB_OBJ_LIST | active_objects | @@ -80,6 +83,7 @@ Every cost input named by a public function's `@time` annotation, with how it is | `emb_drv_i2c_submit()` | O(segments) plus the driver's start when its lane was idle | i2c_bytes, drivers | | `emb_drv_i2c_transfer()` | O(bytes) on the bus after any wait for it; bounded by the timeout and the driver's stop | i2c_bytes, drivers, owned, waiters, pi_depth, timeouts, reschedule | | `emb_drv_i2c_write_read()` | O(bytes) on the bus after any wait for it; bounded by the timeout and the driver's stop | i2c_bytes, drivers, owned, waiters, pi_depth, timeouts, reschedule | +| `emb_drv_pwm_capture()` | O(1) plus the input's cycles: one and a part, or the gate time an averaging driver takes, up to @timeout | pwm_input | | `emb_drv_rtc_alarm_fired()` | O(1) plus the callback | callbacks | | `emb_drv_rtc_set()` | O(1); the first set after power-up waits for the oscillator, up to 3 s, and a set with a fraction of a second waits for the hardware to take it, up to 100 ms | rtc_oscillator, drivers | | `emb_drv_spi_acquire()` | O(1) plus the mutex's priority inheritance | owned, waiters, pi_depth, timeouts | diff --git a/docs/specs/AMENDMENTS-M4.md b/docs/specs/AMENDMENTS-M4.md index e1231d76..3bd06b8d 100644 --- a/docs/specs/AMENDMENTS-M4.md +++ b/docs/specs/AMENDMENTS-M4.md @@ -27,5 +27,7 @@ Changes M4 makes to accepted specifications and requirements, where an accepted | A126 | SPEC-014 §5, §6, HW-003, SPEC-020 | **Tasks, editable outputs, and the layout of the generated files.** SPEC-014 §5.3 is added. A system declares `tasks:`, threads written as state machines (SPEC-020: event or periodic, chosen per task). Every generated file becomes editable: the generator keeps its last output as a committed baseline (`generated/.base/`) and, on regeneration, leaves a file whose generated text did not change untouched, rewrites one that was not edited, and three-way merges one that was, conflict markers only where both changed the same lines; there are no `USER CODE` regions. `check` compares the baseline with the descriptions and refuses an unresolved conflict; the tree's boards are checked strictly. The outputs are laid out by kind, for applications and boards alike: `config/`, `include/`, `src/`, `linker/`, `build/` and `docs/` under `generated//`, and the application's own `CMakeLists.txt`, `src/main.c` and `src/tasks/` beside `system.yaml`, generated and editable. HW-003's "never edited" becomes "never lost": a generated file may be edited, and regeneration keeps the edit. *Proposed and accepted by the project owner on 2026-11-13 ("accept as written"), from the owner's decisions that day: tasks as state machines with both models, editable generated files regenerated only where the change touches them, merged rather than regions, and the layout split by kind for boards too.* | `hw/gen/emb_hwgen/` (merge, layout, tasks), `kernel/task/` (SPEC-020), `cmake/`, every board's `generated/` (configurator phase) | | A127 | SPEC-015 §2, §7, §9, §12 decision 2, OBS-002, OBS-003, OBS-013, OBS-021, 08 Q13 | **Logging, its ring and the console.** **Call sites (§2.1):** a module is defined once with `EMB_LOG_MODULE_DEFINE(name, level)` and declared in its other files with `EMB_LOG_MODULE_DECLARE(name, level)`; §2.1 had only the declaration, which cannot both define the module and serve a module whose calls span files. `EMB_LOG_ERR`, `_WRN`, `_INF` and `_DBG(name, format, ...)` take at most eight arguments, and the compiler checks each format against its arguments as it checks printf's. A call above its file's level for the module, or above `CONFIG_EMB_LOG_LEVEL_MAX`, compiles to nothing; one above the module's run-time level (`emb_log_level_set()`) returns after one comparison. **One record, two backends (§2.3, §2.4, Q13):** every call packs its arguments into the record of §2.3 in the caller, typed by a signature the compiler computes from their C types with C11's `_Generic` (int, long, long long and their unsigned forms, double, string, pointer). The deferred backend (ADR-009) sends the record and the host formats it; the plain-text backend formats the same record on the target, in the log thread. Neither formats in the caller, so a call costs the same in an interrupt with either backend. **Identifiers (§2.2):** a call site's metadata (format, file, line, level, module, signature) is placed in the section `emb_log`, which the generated linker scripts lay at address 0 as a non-allocated (`INFO`) section. Its bytes stay in the ELF for the decoder and never reach the image. §2.2's `NOLOAD` would drop them from the ELF too. The identifier is the metadata's offset in the section plus 8, so identifiers 0 to 7 are the stream's own: 0 synchronization, 1 `dropped(u16 count)`, 2 `start(build_id[20], tick_ns u32)`, the first record in the ring, which says which image the stream comes from and how long a tick is. It is 16 bits when the section is under 64 KiB minus 8, else 32. The target computes the width from the section's bounds, so it is fixed at link time, and the decoder computes it from the ELF's section, with no ELF note. A linker without the script places the section as ordinary data, with the same identifiers. The plain-text backend's metadata is ordinary read-only data, and its record carries the metadata's address. **Timestamp:** the kernel clock's ticks, their low 32 bits, each tick as long as the start record says. §2.3 used the trace clock, which wraps within seconds on a fast part, while logs can be minutes apart. **The ring (§2.3, §2.5, §12 decision 2):** one ring per CPU, a power-of-two array of `CONFIG_EMB_LOG_RING_SIZE` bytes. *Reservation* is a critical section of a bounded number of instructions: it checks the free space, advances the head by the record's size and writes the record's two-byte header (its length, not yet committed). The producer then copies its record with interrupts enabled and *commits* it by setting the header's committed bit, one byte store after a barrier. *Nested producers:* an interrupt that preempts a producer reserves after it, so records keep the order in which they were reserved. *Publication:* the log thread takes records from the tail in order and stops at the first uncommitted one, and the records after it wait, committed or not, until it is committed. *A preempted record* holds back those after it until its producer runs again; meanwhile the ring fills and later records are dropped. Nothing is overwritten and nothing waits. *Overflow:* a record that does not fit is dropped and counted, and the next record that fits is preceded by the `dropped` record, in the same reservation, so the count stands where the loss was. *Consumer progress:* only the log thread advances the tail, inside the same critical section, since a 16-bit store is not atomic on AVR. A record is at most `EMB_LOG_RECORD_MAX` bytes: strings are cut at `CONFIG_EMB_LOG_STR_MAX` and hexdumps at `CONFIG_EMB_LOG_HEXDUMP_MAX`. This replaces §12 decision 2's lock-free ring. Cortex-M0 and AVR have no compare-and-swap for a lock-free reservation, and one design verified on every port is worth more than a second one. The critical section is bounded by constants, which is what OBS-003 asks. The ring does not survive a reset; `emb_log_flush()` writes out what is committed, polled, from any context, and the fault path calls it. **The log thread (§2.4):** a thread of its own (`CONFIG_EMB_LOG_THREAD_PRIORITY`, by default the lowest application priority, and `CONFIG_EMB_LOG_THREAD_STACK`), woken by a semaphore given when a record lands in an empty ring. It is not the system work queue, whose other items a slow console would hold up. On the table scheduler (tiny), whose priorities hold one thread each, there is no log thread by default (`CONFIG_EMB_LOG_THREAD`): the application sends the records with `emb_log_flush()` from a thread of its own. **The console (§7):** a board writes raw bytes with `emb_board_write()`, and `emb_board_puts()` becomes common code. By default the console is plain text: the board's prints and the plain-text backend's lines. With `CONFIG_EMB_CONSOLE_FRAMED` everything on it travels in A113's frames: the board's text on channel 3, the shell's, buffered by line; log records on channel 0; trace on 1; crash records on 2. A frame holds whole records, so each frame's start is a synchronization point, and the synchronization record is left to unframed transports (SWO, the memory channel), which M4.3 does not implement. A thread's frame is written whole under the console's mutex. Text printed from an interrupt, a fault or before the kernel starts is framed and written at once, without the mutex, and can cut a thread's frame; the decoder then drops that frame and counts it. A zero precedes every frame, so bytes that are not a frame (a boot ROM's text, a cut frame) end before it, and `emb monitor` shows them as raw text. The deferred backend needs the framed console; without it the plain-text backend is the one built. **Profiles (§9, Q13):** `CONFIG_EMB_LOG` is on by default and costs nothing until an image calls it: the ring, the thread and the formatter are in `log.c`, which only a call links in, as the system work queue is (ADR-048). The backend is the deferred one where the console is framed and the plain-text one elsewhere, and always the plain-text one on tiny, where `%f` is not formatted on the target by default (`CONFIG_EMB_LOG_FLOAT`). Logging is not offered on AVR in M4.3: the plain-text formatter and its stack do not fit the Uno's 2 KB of RAM beside the test framework, though its metadata and formats are already read from program memory. **OBS-013** reads: "…the identifier being the offset of the call site's metadata in a non-allocated section, plus 8 (16 bits when it fits, else 32)…; over a framed transport each frame starts with a record; the plain-text backend shall share the call sites and the record." *Proposed 2026-11-13 with M4.3's logging. The project owner chose on 2026-11-13 the ring's critical-section reservation over a lock-free one, both backends with the deferred one the default, and the framed console as an option; the rest is for their review.* | `include/emb/log.h`, `include/emb/console.h`, `subsys/logging/log.c`, `subsys/console/console.c`, the boards' `emb_board_write()`, `hw/gen/emb_hwgen/` (the section), `tools/logdec/` (M4.3) | | A128 | SPEC-015 §3, §12 decisions 2 and 3, OBS-005, OBS-006, OBS-007, OBS-014, OBS-015, 08 Q12 | **The trace ring, and CTF written on the host.** As the project owner chose for Q12, the target keeps compact records and the host writes CTF. **The ring (§3.2):** with `CONFIG_EMB_TRACE_RING`, `emb_trace_start()` makes a RAM ring the trace sink (`emb_trace_set_sink()`), and the image links the ring only when it calls that. Each kernel event becomes a 20-byte record (time, id, CPU, context, three 32-bit arguments), written in the critical section the event happens in. The ring keeps the newest `CONFIG_EMB_TRACE_RING_EVENTS`, a full ring overwriting the oldest: a snapshot, the flight recorder's shape. Events are numbered from the start, event *n* in slot *n* modulo the size, so a reader knows what it missed. `emb_trace_stop()` freezes it for a dump. This replaces §3.2's packets on the target and §12 decision 2's lock-free ring: one store under the critical section the event is already in costs less than reserving. **The clock (§3.4):** `emb_arch_cycles()`, the port's cycle counter, its low 32 bits. The host extends it across its wraps, so two consecutive events must be less than half its period apart (11.9 s at 180 MHz); the periodic clock's tick events keep them so. Tickless Cortex-M (M4.4) adds a clock record before that bound. **On the line (§3.3):** `emb_trace_dump()` sends the ring, oldest first, on the framed console's channel 1 (A127). The streaming option (`CONFIG_EMB_TRACE_STREAM`) has a thread send the new events every `CONFIG_EMB_TRACE_STREAM_MS`. Its own sending is traced too, and the period bounds it; events the ring overwrote before they were sent are counted. A packet is a 16-byte header (version 1, kind, count, the first event's number, the counter's rate in Hz, the events lost so far) and whole events. Another kind carries the threads' indexes and names, sent first from a thread. **The host (§3.5, OBS-006):** `tools/trace/trace.py` extends the times and writes a CTF 1.8 trace (TSDL metadata with the counter as its clock, and one stream whose packets carry `events_discarded`), which Babeltrace 2 reads in CI. It also writes Chrome's JSON for Perfetto: a track per thread from the switches, one for interrupts, the rest as instant events. **The catalogue (§3.1, OBS-014):** stays the `emb_trace_id` enum in `include/emb/trace.h`, whose names and notes the tool reads; `hw/trace_events.yaml`, classes and generated emitters remain for the full catalogue. *Proposed 2026-11-13 with M4.3's trace. The project owner chose on 2026-11-13 compact records on the target and CTF written on the host; the rest is for their review.* | `include/emb/trace.h`, `subsys/trace/ring.c`, `tools/trace/trace.py`, `examples/tracing` (M4.3) | +| A129 | SPEC-017 §1, §3, §7 (new §11a, §11b, §11c), SPEC-014 §3, 07 M4 | **The counter, PWM and ADC classes, and the DMA class's ring.** The project owner chose on 2026-11-13 to add them to M4 before M4.4, on the STM32F446 and the RP2350: timers that drive PWM, capture signals and raise alarms, and an ADC that converts once or samples into a buffer by DMA, with loop wires on the bench. **§1:** timers stop being only the boards' functions, and the ADC becomes a class. **§3:** the counter class takes −96 to −99 (`EMB_EPAST` −96: an alarm's count has already passed), PWM −100 to −103 (`EMB_ENOSIGNAL` −100: no signal to capture before the timeout), the ADC −104 to −107 (none yet: samples lost because the buffer was not taken in time are `EMB_EOVERRUN`, the UART's code, with the same meaning). **§11a, the counter class (``).** A free-running counter at a known rate: `emb_drv_counter_rate()`, and `emb_drv_counter_now()`, the count widened to 64 bits by the driver. One-shot alarms on its channels at an absolute count: `emb_drv_counter_alarm_set()` and `_alarm_cancel()`, with `EMB_EPAST` for a count already passed. And a periodic callback: `emb_drv_counter_periodic()`, without drift, and `_periodic_stop()`. Each callback runs in the counter's interrupt. The STM32F446's general-purpose timers are counters at 1 MHz unless the device sets `rate_hz` (TIM2 and TIM5 32 bits, the others 16, each widened by its update interrupt; TIM9 and TIM12 have two channels, which the SoC's description gives as `timer_channels`); the RP2350's TIMER0 and TIMER1 count microseconds in 64 bits, with four alarms each. `emb_drv_counter_channels()` gives a device's channels. The class is named counter so it is not taken for the kernel's software timers. M4.4's tickless time will run on one of its devices (ADR-059), so the boards' devices take TIM5 and TIM9, whose 16 bits wrap every 65.5 ms and so check the widening on the board, and TIMER1, and leave TIM2, the controller's ADC trigger, and TIMER0. **§11b, the PWM class (``).** A device's output channels are set by period and pulse in nanoseconds (`emb_drv_pwm_set()`), rounded to the nearest the hardware makes, which is reported back, with a polarity flag. The channels of one device share its period. `emb_drv_pwm_capture()` measures an input's period and pulse, waiting up to a timeout. The STM32's timers capture one cycle exactly, two channels on one input as in PWM input mode, each edge timestamped on a free-running counter its wraps extend. The RP2350's slices count edges and high-level cycles over a gate time, an average over many cycles, which the capability `EMB_DRV_PWM_CAP_CAPTURE_AVERAGED` says. **§11c, the ADC class (``).** One conversion: `emb_drv_adc_read()`, and a polled form for any context. A count's millivolts against the board's reference: `emb_drv_adc_to_mv()`. The internal temperature sensor: `emb_drv_adc_temperature()`, calibrated where the part stores calibration (the STM32F446's TS_CAL1 and TS_CAL2), and the STM32's internal reference. And a sequence of channels sampled at a rate into a caller's buffer by DMA, with a callback per half buffer: `emb_drv_adc_sample_start()` and `_stop()`. The STM32's ADC1 is paced by a timer's trigger output, a timer the device takes (`trigger: tim2`), and its results moved by DMA2; its driver sets ADC1 up at each request, not at initialization, so the reference controller, which drives ADC1 and TIM2 by hand, keeps them. The RP2350's ADC is paced by its own clock divider, round robin over the channels in ascending order (`CAP_ASCENDING`), drained by DREQ_ADC, on clk_adc's 48 MHz from PLL_USB, a PLL of a fixed rate the generator solves (`output_hz`). A binding may take peripherals besides its own (`takes:`) and give a field a default; the PWM and ADC loops run under EmbSIM in CI too (`simulation.loopbacks`). **§7, the DMA class:** a job may be circular (`EMB_DRV_DMA_CIRCULAR`), its callback called at each half. On the STM32 that is the stream's circular mode with its half- and full-transfer interrupts; on the RP2350, one channel that triggers itself again at each end (`TRANS_COUNT`'s TRIGGER_SELF mode), half the job at a time, its memory wrapped by the address ring, so its memory is a power of two bytes, at most 32 KiB, aligned to its size: no gap between the halves, and no second channel to assign. The first version of this amendment had two channels chained to each other; the RP2350's own mode does it with one. **SPEC-014 §3:** the RP2350's description gains its ADC, PWM, TIMER0 and TIMER1, and the STM32F446's its TIM3 to TIM5, each with its interrupt, clock and pins. **Bench:** on the NUCLEO-F446RE, D12 (PA6, TIM3_CH1, PWM) to D10 (PB6, TIM4_CH1, capture), A2 (PA4) to 3V3, and A3 (PB0) to GND. On the Pico 2 W, pin 19 (GPIO14, PWM7 A) to pin 22 (GPIO17, PWM0 B), pin 31 (GPIO26) to 3V3 OUT, and pin 32 (GPIO27) to AGND. The logic analyzer is on both PWM outputs. EmbSIM's NUCLEO-F446RE models the timers and the ADC, so the STM32's drivers run in CI as well. *Proposed 2026-11-13 for M4.2b. The project owner chose the classes, their scope, the order and the bench on 2026-11-13; the rest is for their review.* | `include/emb/drv_counter.h`, `drv_pwm.h`, `drv_adc.h`, `kernel/device/{counter,pwm,adc}.c`, `drivers/st/stm32_tim_{counter,pwm}.c`, `drivers/st/stm32_adc.c`, `drivers/rpi/rp2350_{timer,pwm,adc}.c`, `drivers/*/…_dma.c`, `soc/*/*.yaml`, `drivers/bindings.yaml`, `hw/gen/emb_hwgen/` (M4.2b) | +| A130 | SPEC-014 §5, §5.3, SPEC-020 §2, §4, §6, A126 | **Applications in MPLAB Harmony's form.** The project owner chose on 2026-11-13 that an application's generated files follow MPLAB Harmony v3's layout, templates and names, as the owner's own Harmony projects have them. **Layout (§5.3):** an application's per-board files move from `generated//` to Harmony's configuration folder, `src/config//`: `definitions.h`, the one header the application includes (the kernel's API, the board's devices, the system's handles, every task's header, the device's name, family and CPU clock, and `SYS_Initialize()` and `SYS_Tasks()`); `configuration.h`, the system's settings as macros (the board, the clock and the tick, each task's priority, stack, period, queue and timeouts, the devices' settings, the watchdog's timeout); `initialization.c`, the system's static definitions and `SYS_Initialize()` (the board, the kernel, the application's interrupts, then each task's `_Initialize()`); `tasks.c`, each task's queue, dispatch, description and thread, and `SYS_Tasks()`, which starts the kernel and does not return; and `interrupts.h` and `interrupts.c`, the application's interrupt handlers, connected at their levels by `SYS_Initialize()`, beside a table of the lines the devices use. The board's outputs for the application go under `peripheral/` (`hw_config.h`, `soc_devices.h`, `soc_devices.c`, `board_pins.c`, `boot_block.c`), `linker/`, `build/` (with `board.conf`) and `docs/`, and the baseline under `src/config/.base/`. `system.h`, `system.c` and `tasks.h` go: what they held is in the files above. A board's own `generated/` keeps A126's layout. **The application's own files:** `src/main.c` calls `SYS_Initialize(NULL)`, then `SYS_Tasks()`, as Harmony's does; each task is `src/.c` and `src/.h` (A126's `src/tasks/` goes), and the application's interrupt handlers are in `src/interrupt_handlers.c`. They are written in Harmony's application template: the file's banner, `Section:` headings, a block for each function (Summary, Description, Precondition, Parameters, Returns, Example, Remarks) and `TODO` markers, under the project's notice: no Microchip text is reproduced. **Names:** an application's code takes Harmony's: `_STATES` with `_STATE_`, `_EVENTS` with `_EVENT_`, `_DATA` and its instance `Data`, `_Initialize()`, `_Tasks()`, `SYS_Initialize()` and `SYS_Tasks()`. The kernel, the drivers and the generated internals keep `emb_` and lower case, and the naming check is relaxed for the applications' files alone (`examples/.clang-tidy`). **Both models, behind Harmony's face (SPEC-020 §4):** a periodic task is Harmony's: `_Tasks()`, a `switch` on `Data.state` that the application writes, which its thread calls every period without drift, an overrun counted. It has no entry, exit or timeout lists, which the generator refuses. An event task keeps SPEC-020's model in the same template: a handler per state, `_STATES _On(const emb_task_event_t *event)` returning the next state, `_Enter()` and `_Exit()` for the states listed, timeouts per state, and `Data.state` the state whose handler runs. Both have `_Initialize()`, which `SYS_Initialize()` calls before the kernel starts their threads, and `_TASK`, the handle events are posted to. States stay declared in `system.yaml`, as SPEC-020 has it: the generator writes the enumerations from it, and `tasks.c` checks with static assertions that their values are the runtime's numbers. SPEC-020's `data:` goes: a task's data is its `_DATA`. **Interrupts (§5):** a system's `interrupts:` lists the application's own handlers, `- { name, irq, handler, level }`, `irq` a line's number or a SoC peripheral's `.`. The generator refuses a line the SoC does not have, one a board device's driver connects, and a level beyond the SoC's priority bits. *Proposed 2026-11-13 for the project owner's review. The owner chose the layout and the templates, Harmony's names in applications, both models behind Harmony's face, and making it on M4.2b's branch on 2026-11-13; the rest is for their review.* | `hw/gen/emb_hwgen/` (system, tasks), `hw/schemas/system.schema.json`, `cmake/`, `soc/*/*/CMakeLists.txt`, `examples/tasks`, `examples/controller`, `examples/.clang-tidy` (M4.2b) | **Not an amendment:** writing the vector table base (VTOR) at reset is already `emb_arch_early_init()`'s duty in SPEC-011 §4. The Cortex-M port has not done it, because every image so far boots from the boot base; M4.5 implements it for images in a slot (SPEC-019 §3). diff --git a/docs/specs/SPEC-014-hardware-description-schema.md b/docs/specs/SPEC-014-hardware-description-schema.md index 6eb6b9b3..0ac3964b 100644 --- a/docs/specs/SPEC-014-hardware-description-schema.md +++ b/docs/specs/SPEC-014-hardware-description-schema.md @@ -211,28 +211,34 @@ After the link, the build compares each thread's `stack` with the worst case the There are no `USER CODE` regions. `check` verifies that the baseline is what the descriptions give now, and that no conflict is left. The tree's own boards are checked strictly in CI (`check --strict`): their files must equal the baseline, since a board's facts belong in its description. -**The layout.** An application's files: +**The layout.** An application's files, in MPLAB Harmony v3's form ([A130](AMENDMENTS-M4.md), which replaced A126's `generated//` and `src/tasks/`): ```text my_app/ system.yaml CMakeLists.txt the application's build: generated, editable src/ - main.c generated, editable: the board and kernel start, the tasks' start - tasks/.c, .h generated, editable: each task's handlers - generated/ - .base/ the baseline: what the generator last wrote (do not edit) - / - config/ board.conf - include/ system.h, tasks.h, hw_config.h, soc_devices.h - src/ system.c, tasks.c, soc_devices.c, board_pins.c, boot_block.c - linker/ regions.ld, embld.opts - build/ board.cmake, CMakeLists.txt - docs/ board.md, system.md, build_report.md, hw.json, system.json + main.c generated, editable: SYS_Initialize(NULL), then SYS_Tasks() + .c, .h generated, editable: each task in Harmony's application template + interrupt_handlers.c generated, editable: the application's interrupt handlers + config/ + .base/ the baseline: what the generator last wrote (do not edit) + / Harmony's configuration folder, one per board + definitions.h the one header the application includes + configuration.h the system's settings as macros + initialization.c SYS_Initialize(), and the system's static definitions + tasks.c the tasks' threads, queues and dispatch, and SYS_Tasks() + interrupts.h, .c SYS_INT_Initialize(), and the interrupt lines in use + peripheral/ hw_config.h, soc_devices.h, soc_devices.c, board_pins.c, boot_block.c + linker/ regions.ld, embld.opts + build/ board.cmake, CMakeLists.txt, board.conf + docs/ board.md, system.md, build_report.md, hw.json, system.json ``` -- **Shared files:** `main.c`, the task files and `CMakeLists.txt` serve every board. -- **Per board:** `generated//` holds each board's own outputs. +- **Shared files:** `main.c`, the task files, `interrupt_handlers.c` and `CMakeLists.txt` serve every board. +- **Per board:** `src/config//` holds each board's own outputs. +- **Templates and names (A130):** the files carry Harmony's banner, `Section:` headings and a block for each function. Application code takes Harmony's names: `SYS_Initialize()`, `SYS_Tasks()`, `_Initialize()`, `_Tasks()`, `_STATES`, `_EVENTS`, `_DATA` and its instance `Data`. +- **Interrupts (A130):** a system's `interrupts:` lists the application's own handlers, `- { name, irq, handler, level }`. `irq` is a line's number, a SoC peripheral's `.`, or either by board name for a system on several SoCs. The generator refuses a line the SoC lacks, one a board device's driver connects, and a level the port does not implement. - **Boards:** a board's own `generated/` has the same six folders (`boards///generated/config/` and so on). ## 6. Generated outputs diff --git a/docs/specs/SPEC-017-driver-classes.md b/docs/specs/SPEC-017-driver-classes.md index 0e2df419..91ce1633 100644 --- a/docs/specs/SPEC-017-driver-classes.md +++ b/docs/specs/SPEC-017-driver-classes.md @@ -44,6 +44,9 @@ The driver range is −64 to −127 (API-010). M4's classes take −64 to −95, | Flash | −84 to −87 | `EMB_EWRPROT` −84, `EMB_EVERIFY` −85 | | RTC | −88 to −91 | `EMB_ENOTSET` −88, `EMB_EOSCFAIL` −89 | | Entropy | −92 to −95 | `EMB_EHEALTH` −92 | +| Counter | −96 to −99 | `EMB_EPAST` −96 | +| PWM | −100 to −103 | `EMB_ENOSIGNAL` −100 | +| ADC | −104 to −107 | none yet; samples lost are `EMB_EOVERRUN` | The common codes of SPEC-016 §10 (`EMB_ESTATE`, `EMB_EIO`, `EMB_ETIMEDOUT`, `EMB_ECANCELED`, `EMB_EBUSY`, `EMB_ENOTSUP`, `EMB_EINVAL`) serve every class. @@ -123,7 +126,7 @@ The common codes of SPEC-016 §10 (`EMB_ESTATE`, `EMB_EIO`, `EMB_ETIMEDOUT`, `EM | Dependencies | its clock | | Requests | not used by applications directly. A device's channels are given at generation (A119): its binding's `dma.` fields, `emb_drv_dma_chan_t`. Its driver starts a job on one, `emb_drv_dma_start()`: memory to peripheral, peripheral to memory or memory to memory, of 1, 2 or 4-byte items, the memory side advancing or fixed (a fill, a sink). Channels run at once, each its own, so a job does not go through the device's request queue | | Blocking | none; the client driver's own request is what blocks | -| Interrupts | a job's end, its status and the items moved, delivered to the client driver's callback in the DMA interrupt | +| Interrupts | a job's end, its status and the items moved, delivered to the client driver's callback in the DMA interrupt. A circular job (`EMB_DRV_DMA_CIRCULAR`, A129) runs until stopped, between a peripheral and advancing memory in two halves: its callback runs at the end of each half, `count / 2` and then `count`, and a bus error ends it | | DMA ownership | while a transfer runs, its buffer belongs to the hardware: the client must not touch it until completion. Buffers must be in a region the description marks `dma` (SPEC-014 §3); the driver refuses others with `EMB_EINVAL`. No cache maintenance on the M4F and M33 (A109) | | Concurrency | channels are assigned at generation from `dma_requests`; two devices never share a channel. Starting a running channel is refused with `EMB_EBUSY` | | Timeouts | `emb_drv_dma_stop()` stops the channel and gives the items moved, the partial data in memory up to it (DRV-006); no end is delivered after it returns. A client's own cancel stops its transmit job, lets the data already sent arrive, then stops its receive job: an SPI transfer canceled by DMA ends after whole frames | @@ -131,7 +134,7 @@ The common codes of SPEC-016 §10 (`EMB_ESTATE`, `EMB_EIO`, `EMB_ETIMEDOUT`, `EM | Errors | `EMB_EXFER` (a bus error during the transfer) | | Capabilities | `MEM_TO_MEM`, `CIRCULAR` | -**Drivers:** `drivers/st/stm32_dma.c` (DMA1 and DMA2, a job per stream, direct mode for a peripheral and the FIFO for memory to memory, which only DMA2 does); `drivers/rpi/rp2350_dma.c` (16 channels, DREQ pacing, what moved counted from the advancing address, which an abort leaves as it was). **Clients:** the SPI drivers run transfers of 16 frames and more by DMA where the board gives the device channels and the buffers are where DMA reaches, and by interrupt otherwise; the UART drivers do the same for writes of 16 bytes and more, their reads staying with the interrupt and the class's ring. **Evidence:** the class's fake on the host; EmbSIM's NUCLEO-F446RE, SPI2 over DMA1 in CI; on both boards, SPI over DMA through the loop wire, with a cancel in the middle of a transfer; UART writes by DMA, the NUCLEO-F446RE's console's and the Pico 2 W's loop UART's, one canceled part-way. +**Drivers:** `drivers/st/stm32_dma.c` (DMA1 and DMA2, a job per stream, direct mode for a peripheral and the FIFO for memory to memory, which only DMA2 does; a circular job in the stream's circular mode, its half- and full-transfer interrupts); `drivers/rpi/rp2350_dma.c` (16 channels, DREQ pacing, what moved counted from the advancing address, which an abort leaves as it was; a circular job on one channel that triggers itself again at each end, `TRANS_COUNT`'s TRIGGER_SELF mode, half the job at a time, its memory side wrapped by the address ring, so its memory is a power of two bytes, at most 32 KiB, aligned to its size). **Clients:** the SPI drivers run transfers of 16 frames and more by DMA where the board gives the device channels and the buffers are where DMA reaches, and by interrupt otherwise; the UART drivers do the same for writes of 16 bytes and more, their reads staying with the interrupt and the class's ring. **Evidence:** the class's fake on the host; EmbSIM's NUCLEO-F446RE, SPI2 over DMA1 in CI; on both boards, SPI over DMA through the loop wire, with a cancel in the middle of a transfer; UART writes by DMA, the NUCLEO-F446RE's console's and the Pico 2 W's loop UART's, one canceled part-way. ## 8. Watchdog @@ -228,6 +231,57 @@ The first run found the raw blocks failing the byte chi-square and the runs test These are sanity checks of the driver and of gross faults in the source, not a certification of the source. +## 11a. Counter (A129) + +| Checklist | | +|---|---| +| Dependencies | its timer's clock: the STM32F4's timer kernel clock, twice a divided APB bus's (A129), divided by the prescaler; the RP2350's tick generator in the TICKS block, from the crystal | +| Requests | `emb_drv_counter_now()`, the count since the device started, widened to 64 bits; `emb_drv_counter_rate()`, its counts per second; `emb_drv_counter_channels()`; `emb_drv_counter_alarm_set()` at an absolute count and `_alarm_cancel()`; `emb_drv_counter_periodic()` and `_periodic_stop()` | +| Blocking | none: every request is immediate, and may be made from an interrupt | +| Interrupts | each callback runs in the counter's interrupt: the STM32 timer's global interrupt, for its update and its compare channels; the RP2350's alarm interrupt, one line per alarm | +| DMA | none | +| Concurrency | one alarm per channel, one-shot or periodic: arming one already armed is refused with `EMB_EBUSY`. A one-shot alarm is disarmed before its callback runs, which may arm it again; a periodic one is armed for its next period first, and its callback may stop it | +| Timeouts | an alarm never fires before its count. A periodic callback's next period is due one period after the last was due, not after it ran, so it does not drift; periods passed while the interrupt was held off are skipped, and the callback's count shows the gap. A period the counter cannot keep, its next count passed every time it is armed, stops after four tries | +| Width | the STM32F446's TIM2 and TIM5 count 32 bits and TIM3, TIM4 and TIM9 16, widened by the update interrupt's count of wraps; an alarm is programmed once its count falls in the current wrap, and fires only at its whole count. The RP2350's timers count 64 bits, and their alarms compare the low 32: one more than 2^32 counts away matches early, and its interrupt arms it again | +| Errors | `EMB_EPAST` (the alarm's count has already passed, now or while it was armed: nothing is armed), `EMB_EINVAL` (no such channel; a period of 0 or 1; at initialization, a rate the hardware cannot make exactly), `EMB_EBUSY` | +| Capabilities | `64BIT`: the hardware counts 64 bits | + +**Drivers:** `drivers/st/stm32_tim_counter.c`: TIM2 to TIM5, and TIM9 to TIM14 with their fewer channels (`timer_channels:` in the SoC's description), at the device's `rate_hz`, 1 MHz by default, which the prescaler must make exactly. Their compare channels drive no pin. `drivers/rpi/rp2350_timer.c`: TIMER0 and TIMER1, each on its tick generator at the device's rate, 1 MHz by default, which the crystal must divide exactly. M4.4's tickless time will take one counter of each board; the boards' devices leave TIM2, the controller's ADC trigger, and TIMER0 free. **Evidence:** the class's fake on the host. On EmbSIM's NUCLEO-F446RE in CI and on both boards, for every counter the board has (TIM5 and TIM9; TIMER1): its rate against the kernel's clock; its count rising, across TIM9's wraps; one-shot alarms 0.5 ms, 3 ms and 200 ms ahead, never early and at most 200 counts late; every channel in order; a passed count refused; a canceled alarm; a periodic callback over 100 periods of 1 ms, each a period after the last. + +## 11b. PWM (A129) + +| Checklist | | +|---|---| +| Dependencies | its timer's clock: the STM32F4's timer kernel clock; the RP2350's clk_sys; its pins, an output's and an input's alternate function (`pins:`) | +| Requests | `emb_drv_pwm_set()`, a channel's period and pulse in nanoseconds with a polarity flag (`EMB_DRV_PWM_INVERTED`), rounded to the nearest the hardware makes and reported back; `emb_drv_pwm_stop()`; `emb_drv_pwm_capture()`, an input's period and pulse; `emb_drv_pwm_channels()` | +| Blocking | `set` and `stop` are immediate, from a thread or an interrupt; `capture` blocks its thread for the input's cycles, up to its timeout, under the device's lock | +| Interrupts | the STM32's capture: the timer's interrupt, at each edge and wrap, until a cycle is whole. The RP2350's needs none | +| DMA | none | +| Concurrency | a device's running channels share its period: a `set` at another period while another channel runs is refused with `EMB_EBUSY`; alone, a channel takes the new period at once. A running channel takes a new pulse at its next period, without a glitch. A channel outputs or captures, not both; the STM32's capture resets its timer's counter, so it is refused while any of its timer's channels outputs | +| Timeouts | a capture with no whole cycle before its timeout gives `EMB_ENOSIGNAL`: a steady input, high or low, has none | +| Resolution | an output's pulse in steps of its timer's clock through the smallest prescaler that brings the period within the counter: 11 ns on the STM32F446's TIM3 at 90 MHz for periods to 728 µs, 6.7 ns on the RP2350's slices for periods to 437 µs, coarser beyond. The STM32 captures one cycle exactly at the timer's clock, each edge timestamped on a counter its wraps extend (A129). The RP2350 averages over a gate (`CAP_CAPTURE_AVERAGED`): edges counted between two of its counter's changes, timed by the CPU's cycle counter, for the period, and clk_sys counted while the input is high, over exactly that many periods, for the pulse; the gate is a quarter of the timeout, from 4 to 50 ms | +| Errors | `EMB_ENOSIGNAL`, `EMB_ENOTSUP` (no capture on the channel: the STM32 captures on channels 0 and 1, the RP2350 on B, channel 1), `EMB_EBUSY`, `EMB_EINVAL` (a period of 0, beyond the hardware's reach or shorter than two counts, or a pulse longer than its period) | +| Capabilities | `CAPTURE`, `CAPTURE_AVERAGED` | + +**Drivers:** `drivers/st/stm32_tim_pwm.c`: a general-purpose timer's channels in PWM mode 1, the period and compares preloaded; a stopped channel forced to its inactive level, which its polarity sets. Its capture pairs channels 0 and 1 on one input, as PWM input mode does, the rising edge captured on the input's own channel and the falling edge on the other, on a counter that runs free, its wraps counted by the update interrupt: each edge is timestamped, a cycle is a rising edge, a falling edge and the next rising edge, and a late interrupt cannot move its start, as resetting the counter at the edge would. `drivers/rpi/rp2350_pwm.c`: a slice's A and B, its divider in sixteenths, the compares and TOP double-buffered; B its input. **Evidence:** the class's fake on the host. On both boards, an output wired to a capture input (the NUCLEO-F446RE's TIM3 channel 1 on D12 to TIM4 channel 1 on D10; the Pico 2 W's slice 7 A on GPIO14 to slice 0 B on GPIO17): waves from 50 kHz to 100 Hz captured back within a thousandth of the period and 60 ns, inverted too; a steady output with no cycle; a running output not captured. The logic analyzer records both outputs. + +## 11c. ADC (A129) + +| Checklist | | +|---|---| +| Dependencies | its clock: the STM32F446's PCLK2, through the ADC's prescaler to 36 MHz at most; the RP2350's clk_adc, 48 MHz from PLL_USB, which its driver starts; its analog pins (`pins:`, `adc1: { in4: PA4 }`); the STM32's pacing timer and the ADCs' common registers and factory calibration, which the device takes (`trigger: tim2`, `common:`, `cal:`); a DMA channel for sampling (`dma: [rx]`) | +| Requests | `emb_drv_adc_read()`, one conversion of an input, waiting for the device, and `emb_drv_adc_read_polled()` from any context; `emb_drv_adc_to_mv()`, a count against the board's reference (`vref_mv`, 3300 unless the device says), full scale 2^bits − 1; `emb_drv_adc_temperature()`, in thousandths of a degree; `emb_drv_adc_sample_start()` and `_stop()`: a sequence of up to 8 inputs converted in turn at a rate, by DMA into the caller's buffer, a callback at each half. Inputs are the ADC's own numbers, and `EMB_DRV_ADC_TEMPERATURE` and `EMB_DRV_ADC_VREFINT` its internal ones | +| Blocking | a read waits for the device, then converts in under 30 µs, polled; the polled form only converts | +| Interrupts | a sampling's halves, in the DMA interrupt; the STM32's overrun, in the ADC's | +| DMA | a sampling is a circular job (§7): a half is the callback's to read until the other is full; the RP2350's buffer is its DMA ring's, a power of two bytes, at most 32 KiB, aligned to its size | +| Concurrency | the device is a conversion's or a sampling's: a read during either, or a sampling during a read, is refused with `EMB_EBUSY`; readers queue on the device's lock | +| Timeouts | a stopped sampling calls nothing more; one the hardware ended, its samples lost, calls its callback a last time with `EMB_EOVERRUN` | +| Resolution | 12 bits on both. The STM32F446 samples external inputs for 84 cycles and internal ones for 480, the temperature sensor's 10 µs; a sequence's sample time is the longest that fits its period. The RP2350 converts in 96 clocks, 500 kS/s at most, its rate set by its divider in 256ths | +| Errors | `EMB_EOVERRUN`, `EMB_EBUSY`, `EMB_EINVAL` (an input it does not have; a sequence of 0 or more than 8 inputs, out of order where `ASCENDING`; a rate it cannot make; a buffer whose halves hold no whole number of sequences), `EMB_EIO` (a conversion that never ended, or failed; no calibration) | +| Capabilities | `TEMPERATURE`, `CALIBRATED` (from the part's factory calibration), `VREFINT`, `SAMPLE`, `ASCENDING` (a sequence's inputs in ascending order, each once: the RP2350's round robin) | + +**Drivers:** `drivers/st/stm32_adc.c`: ADC1, set up by each request rather than at initialization, which gates its clock only, so an application that drives ADC1 by hand, as the reference controller does, keeps it as it set it until it uses the class. A sampling is a scanned regular sequence started by its timer's TRGO (`adc_trigger:`, the timer's EXTSEL code, in the SoC's description) and moved by DMA2. The temperature is read between the factory calibration's two points, the count first scaled to the 3.3 V they were taken at. `drivers/rpi/rp2350_adc.c`: the ADC on clk_adc, a sampling START_MANY round robin over the sequence's inputs, paced by its divider and drained through its FIFO by DMA, an overflow of the FIFO ending it; the temperature from the datasheet's typical 706 mV at 27 °C and −1.721 mV/°C. **Evidence:** the class's fake on the host. On EmbSIM's NUCLEO-F446RE in CI and on both boards, an input wired to the 3.3 V rail and one to ground (the NUCLEO-F446RE's A2 and A3; the Pico 2 W's GPIO26 and GPIO27): each converted and in millivolts; the temperature sensor in a room's range; the internal reference at 1.21 V where there is one; both sampled in turn at 1 kHz, every sample in its order, the halves on time and none after the stop. + ## 12. Optional parts Drivers for external parts on these classes, written once the class is in: `drivers/sensor/bme280.c` on I2C (EmbSIM models it) and `drivers/flash/jedec_spi_nor.c` on SPI. A part is a device with a `bus:` (SPEC-014 §4) and its own `compatible`. diff --git a/docs/specs/SPEC-020-tasks.md b/docs/specs/SPEC-020-tasks.md index 61b3d4bf..4ec71aad 100644 --- a/docs/specs/SPEC-020-tasks.md +++ b/docs/specs/SPEC-020-tasks.md @@ -33,7 +33,6 @@ tasks: entry: [measuring] # states with an entry handler exit: [measuring] # states with an exit handler timeout: { measuring: 100ms } # a state left with no event for this long gets EMB_EV_TIMEOUT - data: sensor_data_t # the task's own data, a C type; optional event: null # a C type replacing emb_task_event_t for this task; optional - name: blink model: periodic @@ -44,7 +43,7 @@ tasks: initial: off ``` -Every name is a C identifier, unique among the system's threads, objects, tasks and targets. A task's states, events, entry and exit lists name its own states and events, each once. `initial` is one of its states. `queue` and `events` belong to the event model, `period` to the periodic one. Its priority and stack are checked as a thread's are (A125). +Every name is a C identifier, unique among the system's threads, objects, tasks, targets and interrupts. A task's states, events, entry and exit lists name its own states and events, each once. `initial` is one of its states. `queue`, `events`, `timeout`, `entry` and `exit` belong to the event model, `period` to the periodic one. Its priority and stack are checked as a thread's are (A125). A task's data is its `_DATA` in its own header ([A130](AMENDMENTS-M4.md)); the first version's `data:` is gone. ## 3. Events @@ -56,22 +55,52 @@ typedef struct emb_task_event { ``` - The ids below `EMB_EV_USER` (16) are the runtime's: `EMB_EV_ENTRY`, `EMB_EV_EXIT` and `EMB_EV_TIMEOUT`. -- A task's own events are numbered from `EMB_EV_USER` in the order the system lists them, as `_EV_` (`SENSOR_EV_TICK`). +- A task's own events are numbered from `EMB_EV_USER` in the order the system lists them, as `_EVENT_` (`SENSOR_EVENT_TICK`, A130). - An event is copied into the task's queue, and nothing points into the poster's memory. - A task that declares `event:` has events of that type instead. Its first member must be a `uint32_t id`, which the generator checks with a static assertion. ## 4. States and handlers -The generator writes, for each task, `_` constants (`SENSOR_IDLE`), the task's type `_t` (its runtime part, then its `data`), and declarations of the handlers the application defines: +*Amended by [A130](AMENDMENTS-M4.md): the names and the files are MPLAB Harmony's.* + +Each task's header, `src/.h`, written from the system description and then the application's, holds its states and events as enumerations, in the order the system lists them, and its data: ```c -emb_state_t sensor_on_idle(sensor_t *self, const emb_task_event_t *ev); /* event model: per event */ -emb_state_t blink_on_on(blink_t *self); /* periodic model: per period */ -void sensor_enter_measuring(sensor_t *self); /* listed in entry: */ -void sensor_exit_measuring(sensor_t *self); /* listed in exit: */ +typedef enum { + SENSOR_STATE_INIT = 0, /* the runtime's numbers: tasks.c checks them */ + SENSOR_STATE_IDLE, + SENSOR_STATE_MEASURING, + SENSOR_STATE_ERROR, +} SENSOR_STATES; + +typedef enum { + SENSOR_EVENT_TICK = EMB_EV_USER, + SENSOR_EVENT_SAMPLE, + SENSOR_EVENT_FAULT, +} SENSOR_EVENTS; + +typedef struct { + SENSOR_STATES state; /* the task's current state */ + /* the application's own data */ +} SENSOR_DATA; + +extern SENSOR_DATA sensorData; ``` -A handler returns the next state: its own state to stay, another to move. Moving runs the old state's exit handler, if it has one, then the new state's entry handler, if it has one, then re-arms the new state's timeout. The task starts by running its initial state's entry handler. A handler runs to completion: one event or one period at a time, no event lost while it runs, since posted events wait in the queue. +Both models have `_Initialize()`, which `SYS_Initialize()` calls before the kernel starts the task's thread, and the handle `_TASK`. Then: + +- **event model**, a handler per state, and an action for each state its `entry` and `exit` lists name: + + ```c + SENSOR_STATES SENSOR_OnIdle(const emb_task_event_t *event); + void SENSOR_EnterMeasuring(void); + void SENSOR_ExitMeasuring(void); + ``` + + A handler returns the next state: its own state to stay, another to move. Moving runs the old state's exit action, if it has one, then the new state's entry action, if it has one, then re-arms the new state's timeout. The task starts by running its initial state's entry action. `sensorData.state` is the state whose handler or action runs. +- **periodic model**, Harmony's: `void BLINK_Tasks(void)`, a `switch` on `blinkData.state` that the application writes, which moves the task by setting `blinkData.state`. A periodic task has no entry, exit or timeout lists. + +A handler runs to completion: one event or one period at a time, no event lost while it runs, since posted events wait in the queue (KRN-TSK-001). States are declared in `system.yaml`: a handler returning a state the task does not have faults in a checked build. A handler the application has not written is a link error naming it. The declarations are generated. @@ -92,17 +121,18 @@ emb_status_t emb_task_stats_get(const emb_task_t *task, emb_task_stats_t *out); - **Stopping a task:** cancel its thread (`emb_thread_cancel()`, SPEC-008 §7). The wait ends with `EMB_ECANCELED`, the current state's exit handler runs, and `emb_task_run()` returns, so the thread ends. - **A full queue:** `emb_task_post()` from an ISR or with no wait returns `EMB_EAGAIN` and counts a drop. Events are never silently lost. -- **Handles:** each task is reached by its generated handle, `&sensor.task` or the macro `SENSOR_TASK`. +- **Handles:** each task is reached by its generated handle, `&sensor_task` or the macro `SENSOR_TASK`. - **Calling contracts:** the API's tags follow SPEC-001 §9. ## 6. What is generated, and where -Under A126's layout: -- `generated//include/tasks.h`: the event and state constants, the task types, the handlers' declarations and the handles. -- `generated//src/tasks.c`: the queues, the dispatch tables, the threads (`EMB_THREAD_DEFINE`) and their entries. -- `src/tasks/.c` and `src/tasks/.h`: a skeleton with every handler written, returning its own state. +Under [A130](AMENDMENTS-M4.md)'s layout: +- `src/config//tasks.c`: each task's queue, dispatch, description and thread (`EMB_THREAD_DEFINE`), the static assertions that its enumerations are the runtime's numbers, and `SYS_Tasks()`. +- `src/config//configuration.h`: each task's priority, stack, period, queue and timeouts, `_PRIORITY` and so on. +- `src/config//definitions.h`: the tasks' handles, `_TASK`, and their headers. +- `src/.c` and `src/.h`: Harmony's application template, with every handler, or `_Tasks()`'s `switch`, written to stay in its state. -All three are editable, and regeneration merges (A126). Adding a state in `system.yaml` adds its constant and declaration, and merges a new handler into the task's file. +All are editable, and regeneration merges (A126). Adding a state in `system.yaml` adds it to the enumeration, and merges a new handler, or a new `case`, into the task's file. ## 7. Configuration diff --git a/docs/user/application.md b/docs/user/application.md index 7858b6dc..2e352691 100644 --- a/docs/user/application.md +++ b/docs/user/application.md @@ -69,7 +69,7 @@ Everything `emb_add_executable()` makes sits next to the image: on a board, `app ## Threads, tasks and objects from a system description -Instead of writing `EMB_THREAD_DEFINE` and the other definition macros in C, describe the application in a `system.yaml`. It holds threads, tasks (threads written as state machines), kernel objects, device settings, SPI and I2C targets and the watchdog. The generator turns it into C and checks it before anything compiles (SPEC-014 §5, SPEC-020). `examples/tasks/system.yaml` is a complete one: +Instead of writing `EMB_THREAD_DEFINE` and the other definition macros in C, describe the application in a `system.yaml`. It holds threads, tasks (threads written as state machines), kernel objects, device settings, SPI and I2C targets, the watchdog and your own interrupt handlers. The generator turns it into C in MPLAB Harmony's form and checks it before anything compiles (SPEC-014 §5, SPEC-020, A130). `examples/tasks/system.yaml` is a complete one: ```yaml schema_version: 0 @@ -78,7 +78,7 @@ name: my_app boards: [st/nucleo_f446re, rpi/pico2_w] tasks: - name: door - model: event # waits on its own queue + model: event # waits on its own queue: a handler per state priority: 5 stack: 1K events: [open, close] @@ -87,32 +87,50 @@ tasks: exit: [open] timeout: { open: 2s } # no event for 2 s: the handler gets EMB_EV_TIMEOUT - name: blink - model: periodic + model: periodic # Harmony's BLINK_Tasks(), every period period: 500ms priority: 2 stack: 512 states: [dark, lit] initial: dark +interrupts: # your own handlers, optional + - { name: wake, irq: 61, handler: WAKE_InterruptHandler, level: 1 } ``` ```sh python3 -I $HOME/EmbLinkRTOS/hw/gen/emb-hwgen.py generate --system system.yaml ``` -This writes: +This writes, as MPLAB Harmony v3 lays out a project: ```text my_app/ system.yaml - CMakeLists.txt yours: generated once, editable - src/main.c yours - src/tasks/door.c, blink.c yours: one handler per state, each returning the next state - generated/ - .base/ what the generator last wrote, for merging (commit it, do not edit) - nucleo_f446re/ per board: config/ include/ src/ linker/ build/ docs/ + CMakeLists.txt yours: generated, editable + src/ + main.c yours: SYS_Initialize(NULL), then SYS_Tasks() + door.c, door.h yours: DOOR_STATES, DOOR_EVENTS, DOOR_DATA, DOOR_Initialize() + and a handler per state, DOOR_OnOpen() ... + blink.c, blink.h yours: BLINK_STATES, BLINK_DATA, BLINK_Initialize() and + BLINK_Tasks(), a switch on blinkData.state + interrupt_handlers.c yours: WAKE_InterruptHandler() + config/ + .base/ what the generator last wrote, for merging (commit it, do not edit) + nucleo_f446re/ per board: + definitions.h the one header to include: the API, the devices, the handles + configuration.h the settings as macros: DOOR_PRIORITY, BLINK_PERIOD_MS ... + initialization.c SYS_Initialize(), and the threads and objects + tasks.c the tasks' threads and SYS_Tasks() + interrupts.c, .h SYS_INT_Initialize(), and every interrupt line in use + peripheral/ the board's: hw_config.h, soc_devices.c and .h, board_pins.c + linker/ build/ docs/ ``` -- **Your code:** write each task's behaviour in its handlers, for example `emb_state_t door_on_open(door_t *self, const emb_task_event_t *ev)`. Post events with `emb_task_post(DOOR_TASK, DOOR_EV_OPEN, value)`, from a thread or an interrupt. +- **Your code:** each file is Harmony's template, with its banner, `Section:` headings, a block for each function and `TODO` markers. + - An **event task** handles each event in its state's handler, which returns the next state: `DOOR_STATES DOOR_OnOpen(const emb_task_event_t *event)`. Its entry and exit actions are `DOOR_EnterOpen()` and `DOOR_ExitOpen()`. + - A **periodic task** is Harmony's: `BLINK_Tasks()` switches on `blinkData.state` and moves by setting it, and its thread calls it every period without drift. + - Post an event with `emb_task_post(DOOR_TASK, DOOR_EVENT_OPEN, value)`, from a thread or an interrupt. + - Declare states and events in `system.yaml`: the generator writes the enumerations from it, and checks their values at compile time. - **Every generated file is editable.** When you change `system.yaml` and generate again: - a file whose generated text did not change is left as it is; - a file you did not edit is rewritten; @@ -121,12 +139,13 @@ my_app/ Only where you and the generator changed the same lines does `generate` report a conflict (`<<<<<<< yours` ... `>>>>>>> generated now`), and `check` fails until you resolve it. - **Checked at generation**, each refusal naming its line: - priorities; - - tasks' states, events and timeouts; + - tasks' states, events and timeouts, and a periodic task given entry or exit actions; - object types the configuration leaves out; - device options and baud rates; - - SPI clocks, I2C addresses and the watchdog timeout. + - SPI clocks, I2C addresses and the watchdog timeout; + - an interrupt on a line the SoC lacks or a device's driver connects, or at a level the port lacks. - **After the link**, with a `stack-roots.json`, a stack below its worst case fails the build. -- **C definitions** still work beside the file. An application with hand-written sources sets `scaffold: false`, and the generator then writes only `generated/`. +- **C definitions** still work beside the file. An application with hand-written sources sets `scaffold: false`, and the generator then writes only `src/config/`; its own C includes `definitions.h`. ## What the build checks diff --git a/docs/user/interrupts.md b/docs/user/interrupts.md index baf8d1ee..5fe90627 100644 --- a/docs/user/interrupts.md +++ b/docs/user/interrupts.md @@ -45,7 +45,7 @@ Calling anything else from a handler is misuse: in a checked build it faults wit -147 functions, from the headers' `@ctx` tags. +162 functions, from the headers' `@ctx` tags. | Function | Header | Blocks | |---|---|---| @@ -57,8 +57,20 @@ Calling anything else from a handler is misuse: in a checked build it faults wit | `emb_device_ready()` | `` | no | | `emb_device_state()` | `` | no | | `emb_device_status()` | `` | no | +| `emb_drv_adc_read_polled()` | `` | no | +| `emb_drv_adc_sample_stop()` | `` | no | +| `emb_drv_adc_sampled()` | `` | no | +| `emb_drv_adc_to_mv()` | `` | no | | `emb_drv_cancel()` | `` | no | | `emb_drv_complete()` | `` | no | +| `emb_drv_counter_alarm_cancel()` | `` | no | +| `emb_drv_counter_alarm_set()` | `` | no | +| `emb_drv_counter_channels()` | `` | no | +| `emb_drv_counter_fired()` | `` | no | +| `emb_drv_counter_now()` | `` | no | +| `emb_drv_counter_periodic()` | `` | no | +| `emb_drv_counter_periodic_stop()` | `` | no | +| `emb_drv_counter_rate()` | `` | no | | `emb_drv_dma_start()` | `` | no | | `emb_drv_dma_stop()` | `` | no | | `emb_drv_entropy_board()` | `` | no | @@ -75,6 +87,9 @@ Calling anything else from a handler is misuse: in a checked build it faults wit | `emb_drv_on_notify()` | `` | no | | `emb_drv_on_sem()` | `` | no | | `emb_drv_on_work()` | `` | no | +| `emb_drv_pwm_channels()` | `` | no | +| `emb_drv_pwm_set()` | `` | no | +| `emb_drv_pwm_stop()` | `` | no | | `emb_drv_request_init()` | `` | no | | `emb_drv_rtc_alarm_cancel()` | `` | no | | `emb_drv_rtc_alarm_fired()` | `` | no | diff --git a/drivers/bindings.yaml b/drivers/bindings.yaml index a4217d14..cfce914b 100644 --- a/drivers/bindings.yaml +++ b/drivers/bindings.yaml @@ -13,7 +13,10 @@ # clock.enable_offset, and clock_hz, the frequency it is clocked at), device. (the board # device's own properties; device.bus is a reference to the bus device), board. or # soc. (the SoC description's own facts: soc.gpio.lines), or pins. (the GPIO line -# carrying the device's pin: an I2C bus's SCL and SDA, which its recovery drives by hand). +# carrying the device's pin: an I2C bus's SCL and SDA, which its recovery drives by hand), or +# takes.. (a peripheral the device takes besides its own: an ADC's pacing timer). A +# field may have a default, { from: , default: }. A peripheral several +# classes can drive has a binding for each, keyed : (A129). schema_version: 0 kind: bindings bindings: @@ -72,6 +75,73 @@ bindings: dma_tx: dma.tx buffers: { rx: { size: device.rx_buffer, default: 64 } } doc: the console, polled, with the UART class's requests to come (SPEC-017 §4) + st,stm32f4-adc: + class: adc + level: kernel + sources: [drivers/st/stm32_adc.c] + include: drivers/st/include + header: emb_stm32_devices.h + api: emb_stm32_adc_api.dev + config: emb_stm32_adc_config_t + data: emb_stm32_adc_data_t + takes: { trigger: "st,stm32-tim", common: "st,stm32f4-adc-common", cal: "st,stm32f4-factory-cal" } + fields: + base: peripheral.base + common: takes.common.base + calibration: takes.cal.base + trigger: takes.trigger.base + trigger_hz: takes.trigger.timer_clock_hz + trigger_clken_offset: takes.trigger.clock.enable_offset + trigger_clken_bit: takes.trigger.clock.bit + trigger_select: takes.trigger.adc_trigger + clock_hz: peripheral.clock_hz + clken_offset: peripheral.clock.enable_offset + clken_bit: peripheral.clock.bit + irq: peripheral.irqs.global + vref_mv: { from: device.vref_mv, default: 3300 } + bits: peripheral.adc.bits + inputs: peripheral.adc.inputs + temperature: peripheral.adc.temperature + vrefint: peripheral.adc.vrefint + dma_rx: dma.rx + doc: ADC1, its conversions and temperature sensor, sequences paced by a timer's TRGO and moved by DMA (SPEC-017 §11c, A129) + st,stm32-tim:counter: + class: counter + level: kernel + sources: [drivers/st/stm32_tim_counter.c] + include: drivers/st/include + header: emb_stm32_devices.h + api: emb_stm32_counter_api.dev + config: emb_stm32_tim_config_t + data: emb_stm32_counter_data_t + fields: + base: peripheral.base + clock_hz: peripheral.timer_clock_hz + rate_hz: { from: device.rate_hz, default: 1000000 } + clken_offset: peripheral.clock.enable_offset + clken_bit: peripheral.clock.bit + irq: peripheral.irqs.global + bits: peripheral.counter_bits + channels: { from: peripheral.timer_channels, default: 4 } + doc: general-purpose timers as counters, widened to 64 bits, an alarm on each compare channel (SPEC-017 §11a, A129) + st,stm32-tim:pwm: + class: pwm + level: kernel + sources: [drivers/st/stm32_tim_pwm.c] + include: drivers/st/include + header: emb_stm32_devices.h + api: emb_stm32_pwm_api.dev + config: emb_stm32_tim_config_t + data: emb_stm32_pwm_data_t + fields: + base: peripheral.base + clock_hz: peripheral.timer_clock_hz + clken_offset: peripheral.clock.enable_offset + clken_bit: peripheral.clock.bit + irq: peripheral.irqs.global + bits: peripheral.counter_bits + channels: { from: peripheral.timer_channels, default: 4 } + doc: general-purpose timers' channels in PWM mode 1, and one cycle of an input captured exactly (SPEC-017 §11b, A129) arm,pl011: class: uart level: early @@ -267,6 +337,53 @@ bindings: data: emb_rp2350_trng_data_t fields: { base: peripheral.base, irq: peripheral.irqs.irq, sample_count: device.sample_count } doc: the RP2350's TRNG (SPEC-017 §11), every health test on; KERNEL, as its read waits on a semaphore + rpi,rp2350-timer: + class: counter + level: kernel + sources: [drivers/rpi/rp2350_timer.c] + include: drivers/rpi/include + header: emb_rp2350_devices.h + api: emb_rp2350_timer_api.dev + config: emb_rp2350_timer_config_t + data: emb_rp2350_timer_data_t + fields: + base: peripheral.base + index: peripheral.index + rate_hz: { from: device.rate_hz, default: 1000000 } + irq0: peripheral.irqs.alarm0 + irq1: peripheral.irqs.alarm1 + irq2: peripheral.irqs.alarm2 + irq3: peripheral.irqs.alarm3 + doc: TIMER0 and TIMER1 as counters, 64 bits of their tick, an alarm on each of the four (SPEC-017 §11a, A129) + rpi,rp2350-adc: + class: adc + level: kernel + sources: [drivers/rpi/rp2350_adc.c] + include: drivers/rpi/include + header: emb_rp2350_devices.h + api: emb_rp2350_adc_api.dev + config: emb_rp2350_adc_config_t + data: emb_rp2350_adc_data_t + fields: + base: peripheral.base + clock_hz: peripheral.clock_hz + vref_mv: { from: device.vref_mv, default: 3300 } + bits: peripheral.adc.bits + inputs: peripheral.adc.inputs + temperature: peripheral.adc.temperature + dma_rx: dma.rx + doc: the ADC, its conversions and temperature sensor, round robins paced by its divider and drained by DMA (SPEC-017 §11c, A129) + rpi,rp2350-pwm: + class: pwm + level: kernel + sources: [drivers/rpi/rp2350_pwm.c] + include: drivers/rpi/include + header: emb_rp2350_devices.h + api: emb_rp2350_pwm_api.dev + config: emb_rp2350_pwm_config_t + data: emb_rp2350_pwm_data_t + fields: { base: peripheral.base, index: peripheral.index, clock_hz: peripheral.clock_hz } + doc: a PWM slice's outputs A and B, and its input B averaged over a gate time (SPEC-017 §11b, A129) rpi,rp2350-qmi: class: flash level: early diff --git a/drivers/rpi/include/emb_rp2350_devices.h b/drivers/rpi/include/emb_rp2350_devices.h index 0b0d4f7c..753a8e54 100644 --- a/drivers/rpi/include/emb_rp2350_devices.h +++ b/drivers/rpi/include/emb_rp2350_devices.h @@ -27,16 +27,17 @@ #if CONFIG_EMB_DEVICE #include +#include +#include #include #include #include +#include #include #include #include #endif -#if CONFIG_EMB_DRV_DMA -#include -#endif +#include /* a device's DMA channel is in its configuration, DMA or not */ #ifdef __cplusplus extern "C" { @@ -54,6 +55,70 @@ typedef struct emb_rp2350_io_bank_config { uint32_t lines; /* GPIO0 to GPIO: 30 on the RP2350A */ } emb_rp2350_io_bank_config_t; +/* TIMER0 or TIMER1 (datasheet §12.8): its registers, its tick generator in the TICKS block + * (index), its rate, and its four alarms' interrupts (A129). */ +typedef struct emb_rp2350_timer_config { + uintptr_t base; + uint32_t index; + uint32_t rate_hz; /* counts per second: 1 MHz unless the board says */ + uint32_t irq0; + uint32_t irq1; + uint32_t irq2; + uint32_t irq3; +} emb_rp2350_timer_config_t; + +/* The ADC (datasheet §12.4): its registers, clk_adc, the board's reference, its inputs and the + * temperature sensor's; its samples by DMA where the board gives a channel (dma: [rx]). */ +typedef struct emb_rp2350_adc_config { + uintptr_t base; + uint32_t clock_hz; /* clk_adc, PLL_USB's 48 MHz */ + uint32_t vref_mv; + uint32_t bits; + uint32_t inputs; + uint32_t temperature; + emb_drv_dma_chan_t dma_rx; +} emb_rp2350_adc_config_t; + +#if CONFIG_EMB_DEVICE && CONFIG_EMB_DRV_ADC +/* Its RAM: the class's, first. */ +typedef struct emb_rp2350_adc_data { + emb_drv_adc_data_t adc; + const emb_device_t *dev; +} emb_rp2350_adc_data_t; +#endif + +/* A PWM slice (datasheet §12.5): its five registers, its number, and clk_sys, which it counts. */ +typedef struct emb_rp2350_pwm_config { + uintptr_t base; + uint32_t index; + uint32_t clock_hz; +} emb_rp2350_pwm_config_t; + +#if CONFIG_EMB_DEVICE && CONFIG_EMB_DRV_PWM +/* A slice's RAM: the class's, first; the divider its two outputs share, in sixteenths. */ +typedef struct emb_rp2350_pwm_data { + emb_drv_pwm_data_t pwm; + uint32_t div16; +} emb_rp2350_pwm_data_t; +#endif + +#if CONFIG_EMB_DEVICE && CONFIG_EMB_DRV_COUNTER +/* An alarm's interrupt: its timer and its number. */ +typedef struct emb_rp2350_alarm { + const emb_device_t *dev; + uint8_t channel; + uint8_t reserved_[3]; +} emb_rp2350_alarm_t; + +/* A timer's RAM: the class's, first; each alarm's whole count, the hardware comparing the low + * 32 bits; each alarm interrupt's argument. */ +typedef struct emb_rp2350_timer_data { + emb_drv_counter_data_t counter; + uint64_t target[EMB_DRV_COUNTER_CHANNELS_MAX]; + emb_rp2350_alarm_t alarm[EMB_DRV_COUNTER_CHANNELS_MAX]; +} emb_rp2350_timer_data_t; +#endif + #if CONFIG_EMB_DEVICE && CONFIG_EMB_DRV_ENTROPY /* The TRNG (datasheet §12.12): its registers, its interrupt, and the clocks between samples. */ typedef struct emb_rp2350_trng_config { @@ -129,6 +194,8 @@ typedef struct emb_rp2350_dma_channel { uint8_t width; uint8_t side; /* which side advances: 0 none, 1 the read, 2 the write */ uint8_t running; + uint8_t circular; /* the job repeats: its halves reported (A129) */ + uint8_t half; /* a circular job's half under way: 0 the first, 1 the second */ } emb_rp2350_dma_channel_t; /* The DMA controller's RAM. */ @@ -148,6 +215,24 @@ extern const emb_drv_dma_api_t emb_rp2350_dma_api; extern const emb_drv_wdt_api_t emb_rp2350_watchdog_api; #endif +#if CONFIG_EMB_DRV_ADC +/* The ADC class's operations (SPEC-017 §11c): one conversion; the temperature sensor from the + * datasheet's slope; a round robin of ascending inputs paced by its own divider, drained by DMA. */ +extern const emb_drv_adc_api_t emb_rp2350_adc_api; +#endif + +#if CONFIG_EMB_DRV_PWM +/* The PWM class's operations (SPEC-017 §11b): a slice's outputs A and B (channels 0 and 1), and + * its input B measured as an average over a gate time (CAP_CAPTURE_AVERAGED). */ +extern const emb_drv_pwm_api_t emb_rp2350_pwm_api; +#endif + +#if CONFIG_EMB_DRV_COUNTER +/* The counter class's operations (SPEC-017 §11a): TIMER0 or TIMER1, 64-bit counts of their + * tick, an alarm on each of the four alarms. */ +extern const emb_drv_counter_api_t emb_rp2350_timer_api; +#endif + #if CONFIG_EMB_DRV_ENTROPY /* The entropy class's operations (SPEC-017 §11): 192-bit blocks from the TRNG, each through its * health tests, a failed one discarded. */ diff --git a/drivers/rpi/include/emb_rp2350_drivers.h b/drivers/rpi/include/emb_rp2350_drivers.h index 9aa7477c..30255ca0 100644 --- a/drivers/rpi/include/emb_rp2350_drivers.h +++ b/drivers/rpi/include/emb_rp2350_drivers.h @@ -41,11 +41,19 @@ extern "C" { #define EMB_RP2350_RESET_UART0 (1u << 26) #define EMB_RP2350_RESET_UART1 (1u << 27) #define EMB_RP2350_RESET_TRNG ((uint32_t)1u << 25) +#define EMB_RP2350_RESET_ADC ((uint32_t)1u << 0) +#define EMB_RP2350_RESET_PLL_USB ((uint32_t)1u << 15) +#define EMB_RP2350_RESET_PWM ((uint32_t)1u << 16) +#define EMB_RP2350_RESET_TIMER0 ((uint32_t)1u << 23) +#define EMB_RP2350_RESET_TIMER1 ((uint32_t)1u << 24) /* clk_ref from the crystal, clk_sys from clk_ref and then, where the board asks for more, * from PLL_SYS at EMB_HW_CPU_HZ, the flash interface slowed first; clk_peri follows clk_sys. * Zero once done; nonzero when the crystal or the PLL never became ready. */ int emb_rp2350_clock_init(void); +/* Starts PLL_USB at its solved rate (EMB_HW_PLL_USB_HZ, 48 MHz) and clk_adc from it, once; what + * the ADC needs (A129). Zero once running; nonzero when the PLL never locked. */ +int emb_rp2350_clk_adc_start(void); /* Takes the blocks out of reset and waits, bounded, until they are. Zero once they are. */ int emb_rp2350_unreset(uint32_t blocks); /* Applies the board's pin table: each line's function, then its pad out of isolation. */ diff --git a/drivers/rpi/rp2350_adc.c b/drivers/rpi/rp2350_adc.c new file mode 100644 index 00000000..17b57529 --- /dev/null +++ b/drivers/rpi/rp2350_adc.c @@ -0,0 +1,258 @@ +/* SPDX-License-Identifier: Apache-2.0 */ +/* Copyright 2026 Junior Deogracias */ +/* + * This file is part of EmbLinkRTOS, a deterministic real-time kernel for microcontrollers. + * Licensed under the Apache License, Version 2.0; see the LICENSE file at the repository root. + */ + +/** + * @file rp2350_adc.c + * @brief The RP2350's ADC (datasheet §12.4; SPEC-017 §11c, A129). + * + * @details + * A 12-bit SAR converter on clk_adc, which PLL_USB makes at 48 MHz: 96 clocks a conversion, + * 500 kS/s at most. A conversion is START_ONCE, polled. A sampling is START_MANY, paced by the + * ADC's own divider, round robin over the sequence's inputs, which therefore are in ascending + * order (CAP_ASCENDING); its results go through the FIFO to a circular DMA job, and a FIFO + * overflow ends it. The temperature sensor is read against the datasheet's typical slope. + * + * @author teo1747 + * @date 2026-11-13 (created) + */ +#include +#include + +#include +#include + +#if CONFIG_EMB_DRV_ADC + +#define REG32(a) (*(volatile uint32_t *)(uintptr_t)(a)) + +#define ADC_CS 0x00u +#define ADC_RESULT 0x04u +#define ADC_FCS 0x08u +#define ADC_FIFO 0x0Cu +#define ADC_DIV 0x10u /* INT bits 23:8, FRAC bits 7:0 */ + +#define CS_EN ((uint32_t)1u << 0) +#define CS_TS_EN ((uint32_t)1u << 1) +#define CS_START_ONCE ((uint32_t)1u << 2) +#define CS_START_MANY ((uint32_t)1u << 3) +#define CS_READY ((uint32_t)1u << 8) +#define CS_ERR ((uint32_t)1u << 9) +#define CS_AINSEL 12u +#define CS_RROBIN 16u +#define FCS_EN ((uint32_t)1u << 0) +#define FCS_DREQ_EN ((uint32_t)1u << 3) +#define FCS_EMPTY ((uint32_t)1u << 8) +#define FCS_UNDER ((uint32_t)1u << 10) +#define FCS_OVER ((uint32_t)1u << 11) +#define FCS_THRESH 24u +#define RESULT_MASK 0xFFFu +#define CONVERSION 96u /* clk_adc cycles */ +#define POLL_LIMIT 100000u /* bounded: a conversion's 2 us, many times over */ +#define DRAIN_LIMIT 16u /* the FIFO's 8, twice */ +#define TEMP_MV_27 706u /* the sensor at 27 C (datasheet §12.4.6) */ +#define TEMP_UV_PER_C 1721u /* its slope, falling */ + +/* MISRA Dev CS-12: rules 11.3 and 11.5, a device's configuration and RAM by its driver's type. */ +static const emb_rp2350_adc_config_t *rp2350_adc_cfg(const emb_device_t *dev) +{ + return (const emb_rp2350_adc_config_t *)dev->config; +} + +static emb_rp2350_adc_data_t *rp2350_adc_ram(const emb_device_t *dev) +{ + return (emb_rp2350_adc_data_t *)dev->data; +} + +/* An input's AINSEL; false for one it does not have. */ +static bool adc_ainsel(const emb_rp2350_adc_config_t *cfg, uint8_t input, uint32_t *ainsel) +{ + if (input == EMB_DRV_ADC_TEMPERATURE) { + *ainsel = cfg->temperature; + return true; + } + *ainsel = input; + return input < cfg->inputs; +} + +static bool adc_ready(uintptr_t base) +{ + uint32_t n; + for (n = 0u; n < POLL_LIMIT; n++) { /* bounded */ + if ((REG32(base + ADC_CS) & CS_READY) != 0u) { + return true; + } + } + return false; +} + +static void adc_drain(uintptr_t base) +{ + uint32_t n; + for (n = 0u; (n < DRAIN_LIMIT) && ((REG32(base + ADC_FCS) & FCS_EMPTY) == 0u); n++) { + (void)REG32(base + ADC_FIFO); /* bounded: the FIFO's depth */ + } + REG32(base + ADC_FCS) |= FCS_OVER | FCS_UNDER; /* write one to clear */ +} + +static emb_status_t rp2350_adc_init(const emb_device_t *dev) +{ + const emb_rp2350_adc_config_t *cfg = rp2350_adc_cfg(dev); + emb_rp2350_adc_data_t *d = rp2350_adc_ram(dev); + d->dev = dev; + if ((emb_rp2350_clk_adc_start() != 0) || (emb_rp2350_unreset(EMB_RP2350_RESET_ADC) != 0)) { + return EMB_EIO; + } + REG32(cfg->base + ADC_FCS) = 0u; + REG32(cfg->base + ADC_CS) = CS_EN; + if (!adc_ready(cfg->base)) { + return EMB_EIO; + } + return emb_drv_adc_started(dev); +} + +static emb_status_t rp2350_adc_read(const emb_device_t *dev, uint8_t input, uint16_t *count) +{ + const emb_rp2350_adc_config_t *cfg = rp2350_adc_cfg(dev); + uintptr_t base = cfg->base; + uint32_t ainsel = 0u; + uint32_t cs; + if (!adc_ainsel(cfg, input, &ainsel)) { + return EMB_EINVAL; + } + cs = CS_EN | (ainsel << CS_AINSEL) | ((input == EMB_DRV_ADC_TEMPERATURE) ? CS_TS_EN : 0u); + REG32(base + ADC_CS) = cs; + REG32(base + ADC_CS) = cs | CS_START_ONCE; + if (!adc_ready(base)) { + return EMB_EIO; + } + if ((REG32(base + ADC_CS) & CS_ERR) != 0u) { + return EMB_EIO; /* the conversion's own error flag */ + } + *count = (uint16_t)(REG32(base + ADC_RESULT) & RESULT_MASK); + return EMB_OK; +} + +static void rp2350_adc_sample_stop(const emb_device_t *dev); + +static void rp2350_adc_dma_done(void *arg, emb_status_t status, uint32_t moved) +{ + emb_rp2350_adc_data_t *d = (emb_rp2350_adc_data_t *)arg; + uintptr_t base = rp2350_adc_cfg(d->dev)->base; + emb_status_t ended = status; + if ((ended == EMB_OK) && ((REG32(base + ADC_FCS) & FCS_OVER) != 0u)) { + ended = EMB_EOVERRUN; /* the FIFO overflowed: samples lost */ + } + if (ended != EMB_OK) { + rp2350_adc_sample_stop(d->dev); + (void)emb_drv_adc_sampled(d->dev, 0u, ended); + return; + } + (void)emb_drv_adc_sampled(d->dev, (moved == d->adc.length) ? 1u : 0u, EMB_OK); +} + +static emb_status_t rp2350_adc_sample_start(const emb_device_t *dev, + const emb_drv_adc_sampling_t *s) +{ + const emb_rp2350_adc_config_t *cfg = rp2350_adc_cfg(dev); + emb_rp2350_adc_data_t *d = rp2350_adc_ram(dev); + uintptr_t base = cfg->base; + uint32_t mask = 0u; + uint32_t first = 0u; + uint32_t last = 0u; + uint64_t total = (uint64_t)s->rate_hz * s->count; /* conversions a second */ + uint64_t div256; + bool temperature = false; + emb_drv_dma_job_t job; + emb_status_t st; + uint32_t i; + if (cfg->dma_rx.dma == NULL) { + return EMB_EINVAL; /* the board gives it no DMA channel */ + } + for (i = 0u; i < s->count; i++) { /* bounded: EMB_DRV_ADC_SEQUENCE_MAX */ + uint32_t ainsel = 0u; + if (!adc_ainsel(cfg, s->inputs[i], &ainsel) || ((i != 0u) && (ainsel <= last))) { + return EMB_EINVAL; /* one it does not have, or out of the round robin's order */ + } + if (i == 0u) { + first = ainsel; + } + last = ainsel; + mask |= (uint32_t)1u << ainsel; + temperature = temperature || (s->inputs[i] == EMB_DRV_ADC_TEMPERATURE); + } + /* a conversion every clock_hz / total cycles: DIV is that, less one, in 256ths */ + if ((total == 0u) || (((uint64_t)cfg->clock_hz / total) < CONVERSION)) { + return EMB_EINVAL; /* faster than it converts */ + } + div256 = ((((uint64_t)cfg->clock_hz * 256u) + (total / 2u)) / total) - 256u; + if (div256 > 0xFFFFFFu) { + return EMB_EINVAL; /* slower than its divider reaches */ + } + REG32(base + ADC_CS) = CS_EN; + adc_drain(base); + REG32(base + ADC_DIV) = (uint32_t)div256; + REG32(base + ADC_FCS) = FCS_EN | FCS_DREQ_EN | ((uint32_t)1u << FCS_THRESH); + job.src = base + ADC_FIFO; + job.dst = (uintptr_t)s->buffer; + job.count = s->length; + job.dir = EMB_DRV_DMA_FROM_PERIPH; + job.width = 2u; + job.flags = EMB_DRV_DMA_CIRCULAR; + job.reserved_ = 0u; + st = emb_drv_dma_start(&cfg->dma_rx, &job, rp2350_adc_dma_done, d); + if (st != EMB_OK) { + REG32(base + ADC_FCS) = 0u; + return st; + } + REG32(base + ADC_CS) = CS_EN | (temperature ? CS_TS_EN : 0u) | (first << CS_AINSEL) | + ((s->count > 1u) ? (mask << CS_RROBIN) : 0u) | CS_START_MANY; + return EMB_OK; +} + +/* Interrupts locked by the class; or in the DMA's interrupt, which ends the sampling. */ +static void rp2350_adc_sample_stop(const emb_device_t *dev) +{ + const emb_rp2350_adc_config_t *cfg = rp2350_adc_cfg(dev); + uintptr_t base = cfg->base; + uint32_t moved = 0u; + REG32(base + ADC_CS) = CS_EN; /* START_MANY off: the conversion in flight ends */ + (void)adc_ready(base); + (void)emb_drv_dma_stop(&cfg->dma_rx, &moved); + REG32(base + ADC_FCS) = 0u; + adc_drain(base); +} + +/* V = count x reference / 4095; T = 27 - (V - 0.706 V) / 1.721 mV (datasheet §12.4.6). */ +static emb_status_t rp2350_adc_to_mdegc(const emb_device_t *dev, uint16_t count, int32_t *mdegc) +{ + int64_t uv = ((int64_t)count * rp2350_adc_cfg(dev)->vref_mv * 1000) / (int64_t)RESULT_MASK; + *mdegc = + (int32_t)(27000 - (((uv - ((int64_t)TEMP_MV_27 * 1000)) * 1000) / (int64_t)TEMP_UV_PER_C)); + return EMB_OK; +} + +static uint32_t rp2350_adc_vref_mv(const emb_device_t *dev) +{ + return rp2350_adc_cfg(dev)->vref_mv; +} + +const emb_drv_adc_api_t emb_rp2350_adc_api = { + {rp2350_adc_init, NULL, NULL, NULL, NULL, + EMB_DRV_ADC_CAP_TEMPERATURE | EMB_DRV_ADC_CAP_SAMPLE | EMB_DRV_ADC_CAP_ASCENDING}, + rp2350_adc_read, + rp2350_adc_sample_start, + rp2350_adc_sample_stop, + rp2350_adc_to_mdegc, + rp2350_adc_vref_mv, + 12u, + {0u, 0u, 0u}, +}; + +#else +/* ISO C: a translation unit declares something */ +typedef int emb_rp2350_adc_off_t; +#endif diff --git a/drivers/rpi/rp2350_clocks.c b/drivers/rpi/rp2350_clocks.c index bfa658b1..744c4111 100644 --- a/drivers/rpi/rp2350_clocks.c +++ b/drivers/rpi/rp2350_clocks.c @@ -140,3 +140,40 @@ int emb_rp2350_clock_init(void) REG(CLK_PERI_CTRL) = CLK_PERI_ENABLE; return 0; } + +#ifdef EMB_HW_PLL_USB_M +/* ---- PLL_USB and clk_adc (datasheet §8.1, §8.6; A129) ------------------------------------ */ +#define PLLU_CS (EMB_HW_PLL_USB_BASE + 0x00u) +#define PLLU_PWR (EMB_HW_PLL_USB_BASE + 0x04u) +#define PLLU_FBDIV_INT (EMB_HW_PLL_USB_BASE + 0x08u) +#define PLLU_PRIM (EMB_HW_PLL_USB_BASE + 0x0Cu) +#define CLK_ADC_CTRL (EMB_HW_CLOCKS_BASE + 0x6Cu) +#define CLK_ADC_DIV (EMB_HW_CLOCKS_BASE + 0x70u) +#define CLK_ADC_ENABLE ((uint32_t)1u << 11) /* AUXSRC 0: clksrc_pll_usb */ + +int emb_rp2350_clk_adc_start(void) +{ + if (((REG(CLK_ADC_CTRL) & CLK_ADC_ENABLE) != 0u) && ((REG(PLLU_CS) & PLL_CS_LOCK) != 0u)) { + return 0; /* already running: another driver started it */ + } + REG(CLK_ADC_CTRL) = 0u; /* off while its source changes */ + REG(RESETS_RESET + SET_ALIAS) = EMB_RP2350_RESET_PLL_USB; + REG(RESETS_RESET + CLR_ALIAS) = EMB_RP2350_RESET_PLL_USB; + if (poll_set(RESETS_RESET_DONE, EMB_RP2350_RESET_PLL_USB, EMB_RP2350_RESET_PLL_USB) != 0) { + return -1; + } + /* as PLL_SYS is started: the VCO locked, then the post-dividers */ + REG(PLLU_CS) = EMB_HW_PLL_USB_M; + REG(PLLU_FBDIV_INT) = EMB_HW_PLL_USB_N; + REG(PLLU_PWR + CLR_ALIAS) = PLL_PWR_PD | PLL_PWR_VCOPD; + if (poll_set(PLLU_CS, PLL_CS_LOCK, PLL_CS_LOCK) != 0) { + return -1; + } + REG(PLLU_PRIM) = ((uint32_t)EMB_HW_PLL_USB_POSTDIV1 << PLL_PRIM_POSTDIV1) | + ((uint32_t)EMB_HW_PLL_USB_POSTDIV2 << PLL_PRIM_POSTDIV2); + REG(PLLU_PWR + CLR_ALIAS) = PLL_PWR_POSTDIVPD; + REG(CLK_ADC_DIV) = CLK_DIV_ONE; + REG(CLK_ADC_CTRL) = CLK_ADC_ENABLE; + return 0; +} +#endif diff --git a/drivers/rpi/rp2350_dma.c b/drivers/rpi/rp2350_dma.c index 93543035..424a88dd 100644 --- a/drivers/rpi/rp2350_dma.c +++ b/drivers/rpi/rp2350_dma.c @@ -33,19 +33,23 @@ #define INTS0 0x40Cu #define CHAN_ABORT 0x464u -#define CTRL_EN (1u << 0) -#define CTRL_DATA_SIZE 2u -#define CTRL_INCR_READ (1u << 4) -#define CTRL_INCR_WRITE (1u << 6) -#define CTRL_CHAIN_TO 13u -#define CTRL_TREQ_SEL 17u -#define CTRL_BUSY (1u << 26) -#define CTRL_WRITE_ERROR (1u << 29) -#define CTRL_READ_ERROR (1u << 30) -#define CTRL_AHB_ERROR (1u << 31) -#define COUNT_MASK ((1u << 28) - 1u) /* TRANS_COUNT's count, its low 28 bits */ -#define TREQ_FORCE 63u /* always ready: memory to memory */ -#define ABORT_POLL 100000u /* bounded: the transfers in flight retire */ +#define CTRL_EN (1u << 0) +#define CTRL_DATA_SIZE 2u +#define CTRL_INCR_READ (1u << 4) +#define CTRL_INCR_WRITE (1u << 6) +#define CTRL_RING_SIZE 8u /* the ring: 2^n bytes, its address's low n bits */ +#define CTRL_RING_WRITE (1u << 12) /* RING_SEL: the ring is the write address's */ +#define CTRL_CHAIN_TO 13u +#define CTRL_TREQ_SEL 17u +#define CTRL_BUSY (1u << 26) +#define CTRL_WRITE_ERROR (1u << 29) +#define CTRL_READ_ERROR (1u << 30) +#define CTRL_AHB_ERROR (1u << 31) +#define COUNT_MASK ((1u << 28) - 1u) /* TRANS_COUNT's count, its low 28 bits */ +#define MODE_TRIGGER_SELF ((uint32_t)1u << 28) /* TRANS_COUNT's mode: it triggers itself again */ +#define RING_MAX 15u /* 32 KiB */ +#define TREQ_FORCE 63u /* always ready: memory to memory */ +#define ABORT_POLL 100000u /* bounded: the transfers in flight retire */ static const emb_rp2350_dma_config_t *rp2350_dma_config(const emb_device_t *dev) { @@ -62,14 +66,14 @@ static emb_rp2350_dma_data_t *rp2350_dma_data(const emb_device_t *dev) #define SIDE_WRITE 2u /* The items a channel moved: by how far its advancing address got, which an abort leaves as - * it was; by its count when neither side advances. */ + * it was, within its ring for a circular job; by its count when neither side advances. */ static uint32_t rp2350_dma_moved(uintptr_t r, const emb_rp2350_dma_channel_t *ch) { if (ch->side == SIDE_WRITE) { - return (REG32(r + WRITE_ADDR) - ch->start) / ch->width; + return ((REG32(r + WRITE_ADDR) - ch->start) / ch->width) % ch->count; } if (ch->side == SIDE_READ) { - return (REG32(r + READ_ADDR) - ch->start) / ch->width; + return ((REG32(r + READ_ADDR) - ch->start) / ch->width) % ch->count; } return ch->count - (REG32(r + TRANS_COUNT) & COUNT_MASK); } @@ -89,6 +93,12 @@ static void rp2350_dma_isr(void *arg) continue; } ctrl = REG32(r + CTRL_TRIG); + if ((ch->circular != 0u) && ((ctrl & CTRL_AHB_ERROR) == 0u)) { + /* a circular job goes on, triggering itself: the half it just finished */ + ch->half ^= 1u; + ch->done(ch->arg, EMB_OK, (ch->half != 0u) ? (ch->count / 2u) : ch->count); + continue; + } if ((ctrl & CTRL_AHB_ERROR) != 0u) { REG32(r + CTRL_TRIG) = ctrl & ~CTRL_EN; /* stopped, its error bits cleared */ } @@ -131,9 +141,22 @@ static emb_status_t rp2350_dma_start(const emb_device_t *dev, const emb_drv_dma_ uint32_t ctrl; bool fixed = (job->flags & EMB_DRV_DMA_FIXED_MEM) != 0u; emb_irq_key_t key; + uint32_t ring = 0u; + bool circular = (job->flags & EMB_DRV_DMA_CIRCULAR) != 0u; if ((c >= EMB_RP2350_DMA_CHANNELS) || (job->count > COUNT_MASK)) { return EMB_EINVAL; } + if (circular) { + /* its memory a power of two bytes, aligned to its size: the address ring wraps it */ + uint32_t bytes = job->count * job->width; + uintptr_t mem = (job->dir == EMB_DRV_DMA_FROM_PERIPH) ? job->dst : job->src; + while ((ring < RING_MAX) && (((uint32_t)1u << ring) < bytes)) { /* bounded: RING_MAX */ + ring++; + } + if ((((uint32_t)1u << ring) != bytes) || ((mem & (bytes - 1u)) != 0u)) { + return EMB_EINVAL; + } + } r = cfg->base + (CH_STEP * c); ctrl = CTRL_EN | (rp2350_dma_size(job->width) << CTRL_DATA_SIZE) | (c << CTRL_CHAIN_TO); /* no chain */ @@ -144,6 +167,10 @@ static emb_status_t rp2350_dma_start(const emb_device_t *dev, const emb_drv_dma_ } else { ctrl |= (fixed ? 0u : CTRL_INCR_WRITE) | ((uint32_t)ch->request << CTRL_TREQ_SEL); } + if (circular) { + ctrl |= (ring << CTRL_RING_SIZE) | + ((job->dir == EMB_DRV_DMA_FROM_PERIPH) ? CTRL_RING_WRITE : 0u); + } key = emb_irq_lock(); if (d->channels[c].running != 0u) { emb_irq_unlock(key); @@ -164,9 +191,12 @@ static emb_status_t rp2350_dma_start(const emb_device_t *dev, const emb_drv_dma_ d->channels[c].start = 0u; } d->channels[c].running = 1u; + d->channels[c].circular = circular ? 1u : 0u; + d->channels[c].half = 0u; REG32(r + READ_ADDR) = (uint32_t)job->src; REG32(r + WRITE_ADDR) = (uint32_t)job->dst; - REG32(r + TRANS_COUNT) = job->count; /* mode 0: once */ + /* once (mode 0); a circular job a half at a time, triggering itself again at each end */ + REG32(r + TRANS_COUNT) = circular ? (MODE_TRIGGER_SELF | (job->count / 2u)) : job->count; REG32(cfg->base + INTS0) = 1u << c; REG32(cfg->base + INTE0) |= 1u << c; REG32(r + CTRL_TRIG) = ctrl; /* the trigger: it starts */ @@ -209,7 +239,8 @@ static emb_status_t rp2350_dma_stop(const emb_device_t *dev, const emb_drv_dma_c } const emb_drv_dma_api_t emb_rp2350_dma_api = { - {rp2350_dma_init, NULL, NULL, NULL, NULL, EMB_DRV_DMA_CAP_MEM_TO_MEM}, + {rp2350_dma_init, NULL, NULL, NULL, NULL, + EMB_DRV_DMA_CAP_MEM_TO_MEM | EMB_DRV_DMA_CAP_CIRCULAR}, rp2350_dma_start, rp2350_dma_stop, }; diff --git a/drivers/rpi/rp2350_gpio.c b/drivers/rpi/rp2350_gpio.c index 2feb90a7..5465896e 100644 --- a/drivers/rpi/rp2350_gpio.c +++ b/drivers/rpi/rp2350_gpio.c @@ -27,6 +27,7 @@ #define PADS_GPIO(n) (EMB_HW_PADS_BANK0_BASE + 0x04u + 4u * (n)) #define PAD_ISO (1u << 8) #define PAD_OD (1u << 7) +#define FUNCSEL_NULL 31u /* IO_BANK0 GPIOn_CTRL: no function, an analog input */ #define PAD_IE (1u << 6) #define PAD_PUE (1u << 3) #define PAD_PDE (1u << 2) @@ -57,8 +58,18 @@ void emb_rp2350_pins_apply(const emb_rp2350_pin_t *pins, unsigned count) } REG(IO_GPIO_CTRL(p->gpio)) = p->funcsel; uint32_t pad = REG(PADS_GPIO(p->gpio)) & ~(PAD_ISO | PAD_OD | PAD_IE); - if (p->pull == EMB_RP2350_PULL_UP) { + switch (p->pull) { + case EMB_RP2350_PULL_UP: pad = (pad & ~PAD_PDE) | PAD_PUE; + break; + case EMB_RP2350_PULL_NONE: + pad &= ~(PAD_PDE | PAD_PUE); + break; + default: /* the pad's reset pull-down stays */ + break; + } + if (p->funcsel == FUNCSEL_NULL) { + pad |= PAD_OD; /* an analog input: no digital output either, as the ADC chapter asks */ } REG(PADS_GPIO(p->gpio)) = pad | ((p->input_en != 0u) ? PAD_IE : 0u); /* then out of isolation */ diff --git a/drivers/rpi/rp2350_pwm.c b/drivers/rpi/rp2350_pwm.c new file mode 100644 index 00000000..36fb475a --- /dev/null +++ b/drivers/rpi/rp2350_pwm.c @@ -0,0 +1,309 @@ +/* SPDX-License-Identifier: Apache-2.0 */ +/* Copyright 2026 Junior Deogracias */ +/* + * This file is part of EmbLinkRTOS, a deterministic real-time kernel for microcontrollers. + * Licensed under the Apache License, Version 2.0; see the LICENSE file at the repository root. + */ + +/** + * @file rp2350_pwm.c + * @brief The RP2350's PWM slices (datasheet §12.5; SPEC-017 §11b, A129). + * + * @details + * Outputs: a slice's A and B, channels 0 and 1, count clk_sys through its fractional divider + * up to TOP, and are high while the count is below their compare. TOP and the compares are + * double-buffered: a change takes effect at the next wrap, without a glitch. The divider is the + * smallest that brings the period within TOP's 16 bits, in sixteenths. + * + * Capture: the slice's B input, averaged over a gate time, the slice having no capture + * register. First the period: the counter counts B's rising edges, through a divider that keeps + * the gate's count within 16 bits, and the gate starts and ends at a count's change, timed by + * the CPU's cycle counter, so it holds a whole number of edges. Then the pulse: the counter + * counts clk_sys while B is high, over a gate of exactly a whole number of the periods just + * measured, wherever it starts, so the high time it holds is that many pulses. + * + * @author teo1747 + * @date 2026-11-13 (created) + */ +#include +#include +#include + +#include +#include + +#if CONFIG_EMB_DRV_PWM + +#define REG32(a) (*(volatile uint32_t *)(uintptr_t)(a)) + +#define PWM_CSR 0x00u +#define PWM_DIV 0x04u /* INT bits 11:4, FRAC bits 3:0: sixteenths */ +#define PWM_CTR 0x08u +#define PWM_CC 0x0Cu /* A bits 15:0, B bits 31:16 */ +#define PWM_TOP 0x10u + +#define CSR_EN ((uint32_t)1u << 0) +#define CSR_A_INV ((uint32_t)1u << 2) +#define CSR_B_INV ((uint32_t)1u << 3) +#define CSR_LEVEL ((uint32_t)1u << 4) /* DIVMODE 01: count while B is high */ +#define CSR_RISE (2u << 4) /* DIVMODE 10: count B's rising edges */ +#define DIV16_MIN 16u /* 1.0 */ +#define DIV16_MAX 4095u /* 255 and 15/16 */ +#define COUNT_MAX 65536u /* TOP's 16 bits */ +#define GATE_MIN_MS 4u +#define GATE_MAX_MS 50u +#define PROBE_US 500u /* the first, short count of edges, which sizes the divider */ +#define POLL_SLACK 200u /* cycles: a poll longer than this was preempted, and not trusted */ +#define NS 1000000000u + +/* MISRA Dev CS-12: rules 11.3 and 11.5, a device's configuration and RAM by its driver's type. */ +static const emb_rp2350_pwm_config_t *pwm_config(const emb_device_t *dev) +{ + return (const emb_rp2350_pwm_config_t *)dev->config; +} + +static emb_rp2350_pwm_data_t *pwm_data(const emb_device_t *dev) +{ + return (emb_rp2350_pwm_data_t *)dev->data; +} + +static uint64_t clocks_of(uint32_t ns, uint32_t hz) +{ + return (((uint64_t)ns * hz) + (NS / 2u)) / NS; +} + +static uint32_t ns_of(uint64_t clocks, uint64_t hz) +{ + uint64_t ns = ((clocks * NS) + (hz / 2u)) / hz; + return (ns > UINT32_MAX) ? UINT32_MAX : (uint32_t)ns; +} + +static emb_status_t rp2350_pwm_init(const emb_device_t *dev) +{ + const emb_rp2350_pwm_config_t *cfg = pwm_config(dev); + emb_rp2350_pwm_data_t *d = pwm_data(dev); + if (emb_rp2350_unreset(EMB_RP2350_RESET_PWM) != 0) { + return EMB_EIO; + } + d->div16 = DIV16_MIN; + REG32(cfg->base + PWM_CSR) = 0u; + REG32(cfg->base + PWM_CC) = 0u; + return emb_drv_pwm_started(dev, 2u); +} + +/* Interrupts are locked by the class. Alone, the slice takes the new period's divider and TOP; + * with the other output running, it keeps theirs and changes the compare alone. */ +static emb_status_t rp2350_pwm_set(const emb_device_t *dev, uint8_t channel, uint32_t period_ns, + uint32_t pulse_ns, uint32_t flags, emb_drv_pwm_wave_t *got) +{ + const emb_rp2350_pwm_config_t *cfg = pwm_config(dev); + emb_rp2350_pwm_data_t *d = pwm_data(dev); + uintptr_t base = cfg->base; + bool alone = (d->pwm.running & (uint8_t) ~((uint32_t)1u << channel)) == 0u; + uint32_t div16 = d->div16; + uint64_t top; + uint64_t compare; + uint32_t inv = (channel == 0u) ? CSR_A_INV : CSR_B_INV; + uint32_t inverted = flags & EMB_DRV_PWM_INVERTED; + uint32_t shift = 16u * (uint32_t)channel; + if (alone) { + uint64_t sixteenths = clocks_of(period_ns, cfg->clock_hz) * 16u; + div16 = (uint32_t)((sixteenths + COUNT_MAX - 1u) / COUNT_MAX); + if (div16 < DIV16_MIN) { + div16 = DIV16_MIN; + } + if ((div16 > DIV16_MAX) || (((sixteenths + (div16 / 2u)) / div16) < 2u)) { + return EMB_EINVAL; /* longer than the divider reaches, or shorter than two counts */ + } + top = (sixteenths + (div16 / 2u)) / div16; + } else { + top = (uint64_t)REG32(base + PWM_TOP) + 1u; + } + compare = (pulse_ns >= period_ns) + ? top + : (((clocks_of(pulse_ns, cfg->clock_hz) * 16u) + (div16 / 2u)) / div16); + if (compare > top) { + compare = top; + } + REG32(base + PWM_CC) = + (REG32(base + PWM_CC) & ~(0xFFFFu << shift)) | + ((uint32_t)((compare >= COUNT_MAX) ? (COUNT_MAX - 1u) : compare) << shift); + if (compare >= COUNT_MAX) { + /* high throughout at the longest TOP: the compare cannot pass it, so invert a low */ + REG32(base + PWM_CC) &= ~(0xFFFFu << shift); + inverted ^= EMB_DRV_PWM_INVERTED; + } + if (alone) { + d->div16 = div16; + REG32(base + PWM_CSR) = 0u; /* a capture's mode, gone */ + REG32(base + PWM_DIV) = div16; + REG32(base + PWM_TOP) = (uint32_t)(top - 1u); + REG32(base + PWM_CTR) = 0u; + } + REG32(base + PWM_CSR) = (REG32(base + PWM_CSR) & ~inv) | ((inverted != 0u) ? inv : 0u) | CSR_EN; + if (got != NULL) { + got->period_ns = ns_of((top * div16) / 16u, cfg->clock_hz); + got->pulse_ns = ns_of((compare * div16) / 16u, cfg->clock_hz); + } + return EMB_OK; +} + +static void rp2350_pwm_stop(const emb_device_t *dev, uint8_t channel) +{ + uintptr_t base = pwm_config(dev)->base; + REG32(base + PWM_CC) &= ~(0xFFFFu << (16u * (uint32_t)channel)); /* low: or high, inverted */ +} + +/* The count's next change after @from, polled, before @limit cycles from @start: its value in + * @value and the cycle count it was seen at, within a poll, in @at. A poll a preemption + * stretched is not trusted: the change after the next is waited for instead. */ +static bool next_change(uintptr_t base, uint32_t from, emb_cycle_t start, uint32_t limit, + uint32_t *value, emb_cycle_t *at) +{ + uint32_t last = from; + emb_cycle_t before = emb_arch_cycles(); + while ((emb_cycle_t)(before - start) < limit) { /* bounded: limit cycles */ + uint32_t v = REG32(base + PWM_CTR); + emb_cycle_t after = emb_arch_cycles(); + if (v != last) { + if ((emb_cycle_t)(after - before) <= POLL_SLACK) { + *value = v; + *at = after; + return true; + } + last = v; /* preempted around it: wait for the next */ + } + before = after; + } + return false; +} + +/* Spin for @cycles of the CPU's counter. */ +static void pwm_spin(uint32_t cycles) +{ + emb_cycle_t start = emb_arch_cycles(); + while ((emb_cycle_t)(emb_arch_cycles() - start) < cycles) { /* bounded: cycles */ + } +} + +/* A divider, in sixteenths, of whole steps, that keeps @count's worth within 16 bits. */ +static uint32_t divider_for(uint64_t count) +{ + uint32_t div16 = (uint32_t)((count + (COUNT_MAX - 2u)) / (COUNT_MAX - 1u)) * 16u; + if (div16 < DIV16_MIN) { + return DIV16_MIN; + } + return (div16 > (DIV16_MAX & ~15u)) ? (DIV16_MAX & ~15u) : div16; +} + +/* Run the slice in @mode with @div16 from zero. */ +static void count_from_zero(uintptr_t base, uint32_t mode, uint32_t div16) +{ + REG32(base + PWM_CSR) = 0u; + REG32(base + PWM_DIV) = div16; + REG32(base + PWM_TOP) = COUNT_MAX - 1u; + REG32(base + PWM_CTR) = 0u; + REG32(base + PWM_CSR) = mode | CSR_EN; +} + +/* Under the device's lock. B only: A is an output alone. */ +static emb_status_t rp2350_pwm_capture(const emb_device_t *dev, uint8_t channel, + emb_drv_pwm_wave_t *wave, emb_timeout_t timeout) +{ + const emb_rp2350_pwm_config_t *cfg = pwm_config(dev); + emb_rp2350_pwm_data_t *d = pwm_data(dev); + uintptr_t base = cfg->base; + uint32_t cps = emb_arch_cycles_hz(); + uint32_t wait_ms = EMB_TIMEOUT_IS_FOREVER(timeout) ? UINT32_MAX : 0u; + uint32_t gate_ms; + uint32_t limit; + uint32_t v0 = 0u; + uint32_t v1 = 0u; + uint32_t div16; + uint64_t edges; + uint64_t span; + uint64_t gate; + uint64_t periods; + uint64_t high; + emb_cycle_t t0 = 0u; + emb_cycle_t t1 = 0u; + emb_irq_key_t key; + if (channel != 1u) { + return EMB_ENOTSUP; + } + if ((d->pwm.running != 0u) || (cps == 0u)) { + return EMB_EBUSY; /* the slice outputs; or no cycle counter to time a gate with */ + } + if (wait_ms == 0u) { + wait_ms = (uint32_t)((timeout.ticks * (uint64_t)CONFIG_EMB_TICK_NS) / 1000000u); + } + gate_ms = wait_ms / 4u; + gate_ms = (gate_ms > GATE_MAX_MS) ? GATE_MAX_MS : gate_ms; + if (gate_ms < GATE_MIN_MS) { + return EMB_ENOSIGNAL; /* no time for a gate */ + } + limit = (uint32_t)(((uint64_t)cps * gate_ms) / 1000u); /* an edge's longest wait */ + /* the edges in a short probe size the divider, so that the gate's count fits in 16 bits */ + count_from_zero(base, CSR_RISE, DIV16_MIN); + pwm_spin((uint32_t)(((uint64_t)cps * PROBE_US) / 1000000u)); + edges = REG32(base + PWM_CTR); + div16 = divider_for(edges * ((gate_ms * 1000u) / PROBE_US) * 2u); /* twice: a margin */ + /* the period: whole counts of edges between two of the counter's changes */ + count_from_zero(base, CSR_RISE, div16); + if (!next_change(base, 0u, emb_arch_cycles(), limit, &v0, &t0)) { + REG32(base + PWM_CSR) = 0u; + return EMB_ENOSIGNAL; + } + (void)emb_thread_sleep(EMB_MS(gate_ms)); + if (!next_change(base, REG32(base + PWM_CTR), emb_arch_cycles(), limit, &v1, &t1)) { + REG32(base + PWM_CSR) = 0u; + return EMB_ENOSIGNAL; + } + edges = (uint64_t)((v1 - v0) & (COUNT_MAX - 1u)) * (div16 / 16u); + span = (emb_cycle_t)(t1 - t0); /* CPU cycles */ + if (edges == 0u) { + REG32(base + PWM_CSR) = 0u; + return EMB_ENOSIGNAL; + } + /* the pulse: clk_sys counted while B is high, over exactly a whole number of periods */ + periods = edges; + gate = span; /* those same periods, in CPU cycles */ + div16 = divider_for(((uint64_t)cfg->clock_hz * gate) / cps); /* high throughout, at most */ + REG32(base + PWM_CSR) = 0u; + REG32(base + PWM_DIV) = div16; + REG32(base + PWM_TOP) = COUNT_MAX - 1u; + REG32(base + PWM_CTR) = 0u; + key = emb_irq_lock(); + REG32(base + PWM_CSR) = CSR_LEVEL | CSR_EN; + t0 = emb_arch_cycles(); + emb_irq_unlock(key); + if (((gate * NS) / cps) > (3u * (uint64_t)CONFIG_EMB_TICK_NS)) { /* sleep all but the end */ + (void)emb_thread_sleep(EMB_TICKS((((gate * NS) / cps) / CONFIG_EMB_TICK_NS) - 2u)); + } + key = emb_irq_lock(); + while ((emb_cycle_t)(emb_arch_cycles() - t0) < gate) { /* bounded: the gate's end */ + } + REG32(base + PWM_CSR) = CSR_LEVEL; /* stopped at the gate's end */ + emb_irq_unlock(key); + high = (uint64_t)REG32(base + PWM_CTR) * div16 / 16u; /* clk_sys cycles while high */ + REG32(base + PWM_CSR) = 0u; + /* period: the gate's CPU cycles over its edges; pulse: the high clocks over those periods */ + wave->period_ns = ns_of(span, cps * periods); + wave->pulse_ns = ns_of(high, cfg->clock_hz * periods); + return EMB_OK; +} + +const emb_drv_pwm_api_t emb_rp2350_pwm_api = { + {rp2350_pwm_init, NULL, NULL, NULL, NULL, + EMB_DRV_PWM_CAP_CAPTURE | EMB_DRV_PWM_CAP_CAPTURE_AVERAGED}, + rp2350_pwm_set, + rp2350_pwm_stop, + rp2350_pwm_capture, + 2u, + {0u, 0u, 0u}, +}; + +#else +/* ISO C: a translation unit declares something */ +typedef int emb_rp2350_pwm_off_t; +#endif diff --git a/drivers/rpi/rp2350_timer.c b/drivers/rpi/rp2350_timer.c new file mode 100644 index 00000000..2a75a662 --- /dev/null +++ b/drivers/rpi/rp2350_timer.c @@ -0,0 +1,201 @@ +/* SPDX-License-Identifier: Apache-2.0 */ +/* Copyright 2026 Junior Deogracias */ +/* + * This file is part of EmbLinkRTOS, a deterministic real-time kernel for microcontrollers. + * Licensed under the Apache License, Version 2.0; see the LICENSE file at the repository root. + */ + +/** + * @file rp2350_timer.c + * @brief The RP2350's TIMER0 and TIMER1 as counters (datasheet §12.8; SPEC-017 §11a, A129). + * + * @details + * Each timer counts the ticks of its generator in the TICKS block, 1 MHz from the crystal + * unless the board asks another rate, in 64 bits. Its four alarms compare the count's low 32 + * bits: an alarm more than 2^32 counts away matches early, and its interrupt arms it again + * until the whole count is reached. Each alarm has its own interrupt line. + * + * @author teo1747 + * @date 2026-11-13 (created) + */ +#include + +#include +#include +#include + +#if CONFIG_EMB_DRV_COUNTER + +#define REG32(a) (*(volatile uint32_t *)(uintptr_t)(a)) +/* every peripheral has atomic aliases: write ones to set (+0x2000) or clear (+0x3000) bits */ +#define SET_ALIAS 0x2000u +#define CLR_ALIAS 0x3000u + +#define TIMER_ALARM0 0x10u /* ALARM1 to ALARM3 follow, 4 bytes apart */ +#define TIMER_ARMED 0x20u /* write 1 to disarm */ +#define TIMER_TIMERAWH 0x24u +#define TIMER_TIMERAWL 0x28u +#define TIMER_PAUSE 0x30u +#define TIMER_SOURCE 0x38u /* 0: the tick */ +#define TIMER_INTR 0x3Cu /* write 1 to clear */ +#define TIMER_INTE 0x40u + +/* the TICKS block's generators: TIMER0's at 0x18, TIMER1's 0x0C after */ +#define TICKS_TIMER0_CTRL 0x18u +#define TICKS_STRIDE 0x0Cu +#define TICKS_CYCLES 0x04u /* after its CTRL */ +#define TICKS_ENABLE 1u +#define TICKS_CYCLES_MAX 511u +#define CHANNELS 4u +#define ALL_ALARMS 0xFu + +/* MISRA Dev CS-12: rules 11.3 and 11.5, a device's configuration and RAM by its driver's type. */ +static const emb_rp2350_timer_config_t *timer_config(const emb_device_t *dev) +{ + return (const emb_rp2350_timer_config_t *)dev->config; +} + +static emb_rp2350_timer_data_t *timer_data(const emb_device_t *dev) +{ + return (emb_rp2350_timer_data_t *)dev->data; +} + +/* The count: its high word read again after the low one, and the low again if it moved. */ +static uint64_t count_of(uintptr_t base) +{ + uint32_t high = REG32(base + TIMER_TIMERAWH); + uint32_t low = REG32(base + TIMER_TIMERAWL); + uint32_t again = REG32(base + TIMER_TIMERAWH); + /* two reads of a volatile register, which a carry between them makes differ */ + /* cppcheck-suppress knownConditionTrueFalse */ + if (again != high) { + low = REG32(base + TIMER_TIMERAWL); + high = again; + } + return ((uint64_t)high << 32) | low; +} + +/* the interrupt's handler, whose argument is emb_isr_fn_t's */ +/* cppcheck-suppress constParameterCallback */ +static void rp2350_alarm_isr(void *arg) +{ + const emb_rp2350_alarm_t *alarm = (const emb_rp2350_alarm_t *)arg; + const emb_rp2350_timer_config_t *cfg = timer_config(alarm->dev); + emb_rp2350_timer_data_t *d = timer_data(alarm->dev); + uint32_t bit = (uint32_t)1u << alarm->channel; + bool due = false; + emb_irq_key_t key = emb_irq_lock(); /* an alarm armed from a higher interrupt waits */ + REG32(cfg->base + TIMER_INTR) = bit; + if ((REG32(cfg->base + TIMER_INTE) & bit) != 0u) { + if (count_of(cfg->base) >= d->target[alarm->channel]) { + REG32(cfg->base + TIMER_INTE + CLR_ALIAS) = bit; + due = true; + } else { /* its low 32 bits matched a wrap early: again, at the next */ + REG32(cfg->base + TIMER_ALARM0 + (4u * (uint32_t)alarm->channel)) = + (uint32_t)d->target[alarm->channel]; + } + } + emb_irq_unlock(key); + if (due) { + (void)emb_drv_counter_fired(alarm->dev, alarm->channel); + } +} + +static emb_status_t rp2350_timer_init(const emb_device_t *dev) +{ + const emb_rp2350_timer_config_t *cfg = timer_config(dev); + emb_rp2350_timer_data_t *d = timer_data(dev); + const uint32_t irqs[CHANNELS] = {cfg->irq0, cfg->irq1, cfg->irq2, cfg->irq3}; + uintptr_t tick = EMB_HW_TICKS_BASE + TICKS_TIMER0_CTRL + (TICKS_STRIDE * cfg->index); + uint32_t cycles; + uint8_t ch; + if ((cfg->rate_hz == 0u) || ((EMB_HW_XOSC_HZ % cfg->rate_hz) != 0u) || + ((EMB_HW_XOSC_HZ / cfg->rate_hz) > TICKS_CYCLES_MAX) || (cfg->index > 1u)) { + return EMB_EINVAL; /* a rate the tick generator cannot make from clk_ref, the crystal */ + } + cycles = EMB_HW_XOSC_HZ / cfg->rate_hz; + if (emb_rp2350_unreset((cfg->index == 0u) ? EMB_RP2350_RESET_TIMER0 + : EMB_RP2350_RESET_TIMER1) != 0) { + return EMB_EIO; + } + /* its tick, left as it is when it already runs at the rate: the count goes on */ + if (((REG32(tick) & TICKS_ENABLE) == 0u) || (REG32(tick + TICKS_CYCLES) != cycles)) { + REG32(tick) = 0u; + REG32(tick + TICKS_CYCLES) = cycles; + REG32(tick) = TICKS_ENABLE; + } + REG32(cfg->base + TIMER_SOURCE) = 0u; + REG32(cfg->base + TIMER_PAUSE) = 0u; + REG32(cfg->base + TIMER_INTE) = 0u; + REG32(cfg->base + TIMER_ARMED) = ALL_ALARMS; + REG32(cfg->base + TIMER_INTR) = ALL_ALARMS; + for (ch = 0u; ch < CHANNELS; ch++) { /* bounded */ + d->alarm[ch].dev = dev; + d->alarm[ch].channel = ch; + d->target[ch] = 0u; + if ((emb_irq_connect((emb_irq_t)irqs[ch], rp2350_alarm_isr, &d->alarm[ch]) != EMB_OK) || + (emb_irq_enable((emb_irq_t)irqs[ch]) != EMB_OK)) { + return EMB_EINVAL; + } + } + return emb_drv_counter_started(dev, 0u); +} + +static uint64_t rp2350_timer_now(const emb_device_t *dev) +{ + return count_of(timer_config(dev)->base); +} + +static uint32_t rp2350_timer_rate(const emb_device_t *dev) +{ + return timer_config(dev)->rate_hz; +} + +static void disarm_alarm(uintptr_t base, uint8_t channel) +{ + uint32_t bit = (uint32_t)1u << channel; + REG32(base + TIMER_INTE + CLR_ALIAS) = bit; + REG32(base + TIMER_ARMED) = bit; + REG32(base + TIMER_INTR) = bit; +} + +/* Interrupts are locked by the class. Armed, then checked: a count that passed before the alarm + * was armed is refused, as it would match only at the next wrap of the low 32 bits; one that + * matched meanwhile fires. */ +static emb_status_t rp2350_timer_arm(const emb_device_t *dev, uint8_t channel, uint64_t at) +{ + uintptr_t base = timer_config(dev)->base; + uint32_t bit = (uint32_t)1u << channel; + timer_data(dev)->target[channel] = at; + REG32(base + TIMER_INTR) = bit; + REG32(base + TIMER_INTE + SET_ALIAS) = bit; + REG32(base + TIMER_ALARM0 + (4u * (uint32_t)channel)) = (uint32_t)at; /* arms it */ + if (count_of(base) >= at) { + if (((REG32(base + TIMER_ARMED) & bit) == 0u) && ((REG32(base + TIMER_INTR) & bit) != 0u)) { + return EMB_OK; /* matched as it was armed: the interrupt fires it */ + } + disarm_alarm(base, channel); + return EMB_EPAST; + } + return EMB_OK; +} + +static void rp2350_timer_disarm(const emb_device_t *dev, uint8_t channel) +{ + disarm_alarm(timer_config(dev)->base, channel); +} + +const emb_drv_counter_api_t emb_rp2350_timer_api = { + {rp2350_timer_init, NULL, NULL, NULL, NULL, EMB_DRV_COUNTER_CAP_64BIT}, + rp2350_timer_now, + rp2350_timer_rate, + rp2350_timer_arm, + rp2350_timer_disarm, + (uint8_t)CHANNELS, + {0u, 0u, 0u}, +}; + +#else +/* ISO C: a translation unit declares something */ +typedef int emb_rp2350_timer_off_t; +#endif diff --git a/drivers/st/include/emb_stm32_devices.h b/drivers/st/include/emb_stm32_devices.h index a029503f..581c3e9e 100644 --- a/drivers/st/include/emb_stm32_devices.h +++ b/drivers/st/include/emb_stm32_devices.h @@ -22,11 +22,15 @@ #include #include +#include +#include #include #include #include +#include #include #include +#include #include #include @@ -104,6 +108,91 @@ typedef struct emb_stm32_spi_data { } emb_stm32_spi_data_t; #endif +/* A general-purpose timer, TIM2 to TIM5 (RM0390 §17) or TIM9 to TIM14 (§18): a counter's or + * PWM's (A129). */ +typedef struct emb_stm32_tim_config { + uintptr_t base; + uint32_t clock_hz; /* its kernel clock: twice its APB bus's when that is divided */ + uint32_t rate_hz; /* a counter's counts per second: 1 MHz unless the board says */ + uint32_t clken_offset; + uint32_t clken_bit; + uint32_t irq; + uint32_t bits; /* its counter's width: 32 (TIM2, TIM5) or 16 */ + uint32_t channels; /* 4 on TIM2 to TIM5, 2 on TIM9 and TIM12, 1 on TIM10, 11, 13 and 14 */ +} emb_stm32_tim_config_t; + +#if CONFIG_EMB_DRV_COUNTER +/* A counter's RAM: the class's, first; the counts of the overflows so far, which widen the + * hardware's to 64 bits; and each channel's count, those not yet in the counter's epoch + * pending until it is. */ +typedef struct emb_stm32_counter_data { + emb_drv_counter_data_t counter; + const emb_device_t *dev; /* for the interrupt handler */ + uint64_t high; + uint64_t target[EMB_DRV_COUNTER_CHANNELS_MAX]; + uint8_t pending; + uint8_t reserved_[7]; +} emb_stm32_counter_data_t; +#endif + +#if CONFIG_EMB_DRV_PWM +/* A PWM device's RAM: the class's, first; the prescaler its outputs share; and a capture's + * state: the semaphore its interrupt gives, the counter's wraps, which extend its count, the last + * rising edge's and the falling edge's extended counts, and the cycle measured, in timer clocks. */ +typedef struct emb_stm32_pwm_data { + emb_drv_pwm_data_t pwm; + emb_sem_storage_t done_storage; + emb_sem_t done; + const emb_device_t *dev; /* for the interrupt handler */ + uint32_t prescale; + uint64_t wraps; + uint64_t rise_at; + uint64_t fall_at; + uint64_t period; + uint64_t pulse; + uint8_t rises; /* a rising edge seen: the cycle's start */ + uint8_t fallen; /* a falling edge since it */ + uint8_t input; /* the channel captured: 0 or 1 */ + uint8_t reserved_[5]; +} emb_stm32_pwm_data_t; +#endif + +/* ADC1 (RM0390 §13) as the ADC class's (A129): its registers, the ADCs' common ones, the + * factory calibration, the timer whose update paces a sampling and its trigger select, its + * clock, its interrupt for overruns, the board's reference, and its inputs; its samples by DMA + * where the board gives a channel (dma: [rx]). */ +typedef struct emb_stm32_adc_config { + uintptr_t base; + uintptr_t common; + uintptr_t calibration; + uintptr_t trigger; + uint32_t trigger_hz; /* the timer's kernel clock */ + uint32_t trigger_clken_offset; + uint32_t trigger_clken_bit; + uint32_t trigger_select; /* CR2.EXTSEL for the timer's TRGO */ + uint32_t clock_hz; /* PCLK2, before the ADC's prescaler */ + uint32_t clken_offset; + uint32_t clken_bit; + uint32_t irq; + uint32_t vref_mv; + uint32_t bits; + uint32_t inputs; + uint32_t temperature; /* the sensor's input */ + uint32_t vrefint; /* the internal reference's */ + emb_drv_dma_chan_t dma_rx; +} emb_stm32_adc_config_t; + +#if CONFIG_EMB_DRV_ADC +/* Its RAM: the class's, first; whether its interrupt is connected, which a sampling does. */ +typedef struct emb_stm32_adc_data { + emb_drv_adc_data_t adc; + const emb_device_t *dev; + uint8_t connected; + uint8_t sensors_on; /* the temperature sensor and VREFINT powered, settled */ + uint8_t reserved_[6]; +} emb_stm32_adc_data_t; +#endif + /* The independent watchdog (RM0390 §19), clocked by the LSI: no clock gate. */ typedef struct emb_stm32_iwdg_config { uintptr_t base; @@ -160,6 +249,7 @@ typedef struct emb_stm32_dma_stream { uint32_t count; uint8_t index; uint8_t running; + uint8_t circular; /* the job repeats: its halves reported (A129) */ } emb_stm32_dma_stream_t; /* A DMA controller's RAM. */ @@ -221,6 +311,24 @@ extern const emb_device_api_t emb_stm32_spi_api; * the timeout needs, and the reset's cause from RCC_CSR (emb_stm32f4_reset_flags_take()). */ extern const emb_drv_wdt_api_t emb_stm32_iwdg_api; #endif +#if CONFIG_EMB_DRV_ADC +/* The ADC class's operations (SPEC-017 §11c): ADC1's conversions, its temperature sensor from + * the factory calibration, and sequences paced by a timer's TRGO, their samples by DMA. */ +extern const emb_drv_adc_api_t emb_stm32_adc_api; +#endif + +#if CONFIG_EMB_DRV_COUNTER +/* The counter class's operations (SPEC-017 §11a): a general-purpose timer at its rate, widened + * to 64 bits by the update interrupt, an alarm on each of its compare channels. */ +extern const emb_drv_counter_api_t emb_stm32_counter_api; +#endif + +#if CONFIG_EMB_DRV_PWM +/* The PWM class's operations (SPEC-017 §11b): a general-purpose timer's channels in PWM mode 1, + * and one cycle of an input on channel 0 or 1 captured exactly in PWM input mode. */ +extern const emb_drv_pwm_api_t emb_stm32_pwm_api; +#endif + #if CONFIG_EMB_DRV_RTC /* The RTC class's operations (SPEC-017 §10): the calendar in the backup domain on the LSE, * alarm A, the 20 backup registers. */ diff --git a/drivers/st/stm32_adc.c b/drivers/st/stm32_adc.c new file mode 100644 index 00000000..28fe0c34 --- /dev/null +++ b/drivers/st/stm32_adc.c @@ -0,0 +1,351 @@ +/* SPDX-License-Identifier: Apache-2.0 */ +/* Copyright 2026 Junior Deogracias */ +/* + * This file is part of EmbLinkRTOS, a deterministic real-time kernel for microcontrollers. + * Licensed under the Apache License, Version 2.0; see the LICENSE file at the repository root. + */ + +/** + * @file stm32_adc.c + * @brief The STM32F4's ADC1 as the ADC class's (RM0390 Rev 6 §13; SPEC-017 §11c, A129). + * + * @details + * Each request sets the hardware up for itself: initialization only gates the clock, so an + * application that drives ADC1 by hand (the reference controller) keeps it as it set it, until + * it uses the class. A conversion is one regular conversion started by software and polled. A + * sampling is a regular sequence, scanned, started by a timer's TRGO at the rate, its results + * moved by a circular DMA job; an overrun ends it. The temperature sensor is read against the + * factory calibration, its count scaled first to the 3.3 V the calibration was taken at. + * + * @author teo1747 + * @date 2026-11-13 (created) + */ +#include +#include +#include + +#include +#include + +#if CONFIG_EMB_DRV_ADC + +#define REG32(a) (*(volatile uint32_t *)(uintptr_t)(a)) + +#define ADC_SR 0x00u +#define ADC_CR1 0x04u +#define ADC_CR2 0x08u +#define ADC_SMPR1 0x0Cu /* channels 10 to 18 */ +#define ADC_SMPR2 0x10u /* channels 0 to 9 */ +#define ADC_SQR1 0x2Cu /* the sequence's length, SQ13 to SQ16 */ +#define ADC_SQR2 0x30u /* SQ7 to SQ12 */ +#define ADC_SQR3 0x34u /* SQ1 to SQ6 */ +#define ADC_DR 0x4Cu +#define ADC_CCR 0x04u /* in the common block */ + +#define SR_EOC ((uint32_t)1u << 1) +#define SR_OVR ((uint32_t)1u << 5) +#define CR1_SCAN ((uint32_t)1u << 8) +#define CR1_OVRIE ((uint32_t)1u << 26) +#define CR2_ADON ((uint32_t)1u << 0) +#define CR2_DMA ((uint32_t)1u << 8) +#define CR2_DDS ((uint32_t)1u << 9) /* DMA requests go on: the circular job's */ +#define CR2_EXTSEL 24u +#define CR2_EXTEN ((uint32_t)1u << 28) /* the trigger's rising edge */ +#define CR2_START ((uint32_t)1u << 30) /* SWSTART */ +#define CCR_PRE 16u /* ADCPRE: PCLK2 / 2, 4, 6 or 8 */ +#define CCR_TSVREF ((uint32_t)1u << 23) /* the temperature sensor and VREFINT on */ +#define CCR_VBAT ((uint32_t)1u << 22) /* off: the sensor shares its input with VBAT */ +#define ADC_MAX_HZ 36000000u /* the ADC's clock, at most (DS10693 Table 74) */ +#define SMP_LONG 7u /* 480 cycles: the internal inputs' 10 us at least */ +#define SMP_EXT 4u /* 84 cycles: an external input's, at a few kilohms */ +#define CONV_EXTRA 12u /* cycles a conversion takes beyond its sampling */ +#define POLL_LIMIT 200000u /* bounded: a conversion's 22 us, many times over */ +#define SETTLE_US 10u /* the sensor's start-up (DS10693 §6.3.22) */ +#define CAL_MV 3300u /* the calibration's VDDA */ + +/* the timer's registers, for the trigger alone */ +#define TIM_CR1 0x00u +#define TIM_CR2 0x04u +#define TIM_SR 0x10u +#define TIM_EGR 0x14u +#define TIM_PSC 0x28u +#define TIM_ARR 0x2Cu +#define TIM_CEN ((uint32_t)1u << 0) +#define TIM_MMS ((uint32_t)2u << 4) /* the update event as TRGO */ +#define TIM_UG ((uint32_t)1u << 0) +#define TIM_SPAN 65536u /* a 16-bit timer's reload and prescaler: what every one takes */ + +/* A sampling's sample times, in cycles, by SMP code. */ +static const uint16_t smp_cycles[8] = {3u, 15u, 28u, 56u, 84u, 112u, 144u, 480u}; + +/* MISRA Dev CS-12: rules 11.3 and 11.5, a device's configuration and RAM by its driver's type. */ +static const emb_stm32_adc_config_t *stm32_adc_cfg(const emb_device_t *dev) +{ + return (const emb_stm32_adc_config_t *)dev->config; +} + +static emb_stm32_adc_data_t *stm32_adc_ram(const emb_device_t *dev) +{ + return (emb_stm32_adc_data_t *)dev->data; +} + +/* The ADC's clock divider: the smallest that keeps it within ADC_MAX_HZ. */ +static uint32_t adc_prescaler(uint32_t pclk_hz, uint32_t *code) +{ + uint32_t div; + for (div = 2u; div < 8u; div += 2u) { /* bounded: 2, 4, 6 */ + if ((pclk_hz / div) <= ADC_MAX_HZ) { + break; + } + } + *code = (div / 2u) - 1u; + return div; +} + +/* An input's channel, and whether it is an internal one; false for one it does not have. */ +static bool adc_channel(const emb_stm32_adc_config_t *cfg, uint8_t input, uint32_t *ch, + bool *internal) +{ + *internal = (input == EMB_DRV_ADC_TEMPERATURE) || (input == EMB_DRV_ADC_VREFINT); + if (input == EMB_DRV_ADC_TEMPERATURE) { + *ch = cfg->temperature; + } else if (input == EMB_DRV_ADC_VREFINT) { + *ch = cfg->vrefint; + } else { + *ch = input; + } + return *internal || (input < cfg->inputs); +} + +static void adc_sample_time(uintptr_t base, uint32_t ch, uint32_t code) +{ + uintptr_t reg = base + ((ch >= 10u) ? ADC_SMPR1 : ADC_SMPR2); + uint32_t shift = 3u * ((ch >= 10u) ? (ch - 10u) : ch); + REG32(reg) = (REG32(reg) & ~((uint32_t)7u << shift)) | (code << shift); +} + +/* The common block: the prescaler, and the internal inputs powered, settled once. */ +static void adc_power(const emb_stm32_adc_config_t *cfg, emb_stm32_adc_data_t *d, bool internal) +{ + uint32_t code = 0u; + (void)adc_prescaler(cfg->clock_hz, &code); + if (internal) { + REG32(cfg->common + ADC_CCR) = + (REG32(cfg->common + ADC_CCR) & ~((uint32_t)3u << CCR_PRE) & ~CCR_VBAT) | + (code << CCR_PRE) | CCR_TSVREF; + if (d->sensors_on == 0u) { + uint32_t cps = emb_arch_cycles_hz(); + emb_cycle_t start = emb_arch_cycles(); + while ((emb_cycle_t)(emb_arch_cycles() - start) < ((cps / 1000000u) * SETTLE_US)) { + /* bounded: the sensor's start-up */ + } + d->sensors_on = 1u; + } + } else { + REG32(cfg->common + ADC_CCR) = (REG32(cfg->common + ADC_CCR) & ~((uint32_t)3u << CCR_PRE)) | + (code << CCR_PRE); + } +} + +static void stm32_adc_sample_stop(const emb_device_t *dev); + +static void stm32_adc_isr(void *arg) +{ + emb_stm32_adc_data_t *d = (emb_stm32_adc_data_t *)arg; + const emb_stm32_adc_config_t *cfg = stm32_adc_cfg(d->dev); + if ((REG32(cfg->base + ADC_SR) & SR_OVR) == 0u) { + return; /* ADC2's or ADC3's, which share the line */ + } + REG32(cfg->base + ADC_SR) = ~SR_OVR; + stm32_adc_sample_stop(d->dev); /* the hardware lost samples: stopped, then the class told */ + (void)emb_drv_adc_sampled(d->dev, 0u, EMB_EOVERRUN); +} + +static void stm32_adc_dma_done(void *arg, emb_status_t status, uint32_t moved) +{ + emb_stm32_adc_data_t *d = (emb_stm32_adc_data_t *)arg; + if (status != EMB_OK) { + stm32_adc_sample_stop(d->dev); + (void)emb_drv_adc_sampled(d->dev, 0u, status); + return; + } + (void)emb_drv_adc_sampled(d->dev, (moved == d->adc.length) ? 1u : 0u, EMB_OK); +} + +static emb_status_t stm32_adc_init(const emb_device_t *dev) +{ + const emb_stm32_adc_config_t *cfg = stm32_adc_cfg(dev); + emb_stm32_adc_data_t *d = stm32_adc_ram(dev); + d->dev = dev; + d->connected = 0u; + d->sensors_on = 0u; + emb_stm32_clock_enable(cfg->clken_offset, cfg->clken_bit); /* the registers left as they are */ + return emb_drv_adc_started(dev); +} + +static emb_status_t stm32_adc_read(const emb_device_t *dev, uint8_t input, uint16_t *count) +{ + const emb_stm32_adc_config_t *cfg = stm32_adc_cfg(dev); + uintptr_t base = cfg->base; + uint32_t ch = 0u; + uint32_t n; + bool internal = false; + if (!adc_channel(cfg, input, &ch, &internal)) { + return EMB_EINVAL; + } + adc_power(cfg, stm32_adc_ram(dev), internal); + REG32(base + ADC_CR1) = 0u; /* 12 bits, one conversion */ + REG32(base + ADC_CR2) = CR2_ADON; + adc_sample_time(base, ch, internal ? SMP_LONG : SMP_EXT); + REG32(base + ADC_SQR1) = 0u; + REG32(base + ADC_SQR3) = ch; + REG32(base + ADC_SR) = 0u; + REG32(base + ADC_CR2) = CR2_ADON | CR2_START; + for (n = 0u; n < POLL_LIMIT; n++) { /* bounded */ + if ((REG32(base + ADC_SR) & SR_EOC) != 0u) { + *count = (uint16_t)REG32(base + ADC_DR); /* the read clears EOC */ + return EMB_OK; + } + } + return EMB_EIO; +} + +/* The pacing timer at the rate, nearest: its update event, TRGO, starts each sequence. */ +static void adc_trigger_at(const emb_stm32_adc_config_t *cfg, uint32_t rate_hz) +{ + uint64_t ticks = ((uint64_t)cfg->trigger_hz + (rate_hz / 2u)) / rate_hz; + uint64_t psc = (ticks + TIM_SPAN - 1u) / TIM_SPAN; + uint64_t arr; + if (psc == 0u) { + psc = 1u; + } + arr = (ticks + (psc / 2u)) / psc; + emb_stm32_clock_enable(cfg->trigger_clken_offset, cfg->trigger_clken_bit); + REG32(cfg->trigger + TIM_CR1) = 0u; + REG32(cfg->trigger + TIM_PSC) = (uint32_t)(psc - 1u); + REG32(cfg->trigger + TIM_ARR) = (uint32_t)((arr > 1u) ? (arr - 1u) : 1u); + REG32(cfg->trigger + TIM_CR2) = TIM_MMS; + REG32(cfg->trigger + TIM_EGR) = TIM_UG; + REG32(cfg->trigger + TIM_SR) = 0u; +} + +static emb_status_t stm32_adc_sample_start(const emb_device_t *dev, const emb_drv_adc_sampling_t *s) +{ + const emb_stm32_adc_config_t *cfg = stm32_adc_cfg(dev); + emb_stm32_adc_data_t *d = stm32_adc_ram(dev); + uintptr_t base = cfg->base; + uint32_t code = 0u; + uint32_t adc_hz = cfg->clock_hz / adc_prescaler(cfg->clock_hz, &code); + uint32_t smp = 7u; + uint32_t sq[3] = {0u, 0u, 0u}; /* SQR3, SQR2, SQR1 */ + bool internal_any = false; + emb_drv_dma_job_t job; + emb_status_t st; + uint32_t i; + if (cfg->dma_rx.dma == NULL) { + return EMB_EINVAL; /* the board gives it no DMA channel */ + } + /* the longest sample time whose sequence fits a period, with a tenth to spare */ + while ((smp > 0u) && (((uint64_t)s->count * (smp_cycles[smp] + CONV_EXTRA) * s->rate_hz * 10u) > + ((uint64_t)adc_hz * 9u))) { /* bounded: eight codes */ + smp--; + } + if (((uint64_t)s->count * (smp_cycles[smp] + CONV_EXTRA) * s->rate_hz) > adc_hz) { + return EMB_EINVAL; /* faster than the ADC converts */ + } + for (i = 0u; i < s->count; i++) { /* bounded: EMB_DRV_ADC_SEQUENCE_MAX */ + uint32_t ch = 0u; + bool internal = false; + if (!adc_channel(cfg, s->inputs[i], &ch, &internal)) { + return EMB_EINVAL; + } + internal_any = internal_any || internal; + sq[i / 6u] |= ch << (5u * (i % 6u)); + } + adc_power(cfg, d, internal_any); + if (d->connected == 0u) { /* the line taken now, not at initialization (the controller's) */ + if ((emb_irq_connect((emb_irq_t)cfg->irq, stm32_adc_isr, d) != EMB_OK) || + (emb_irq_enable((emb_irq_t)cfg->irq) != EMB_OK)) { + return EMB_EINVAL; + } + d->connected = 1u; + } + REG32(base + ADC_CR2) = 0u; + for (i = 0u; i < s->count; i++) { /* bounded */ + uint32_t ch = 0u; + bool internal = false; + (void)adc_channel(cfg, s->inputs[i], &ch, &internal); + adc_sample_time(base, ch, smp); + } + REG32(base + ADC_SQR3) = sq[0]; + REG32(base + ADC_SQR2) = sq[1]; + REG32(base + ADC_SQR1) = sq[2] | (((uint32_t)s->count - 1u) << 20); /* L */ + REG32(base + ADC_CR1) = ((s->count > 1u) ? CR1_SCAN : 0u) | CR1_OVRIE; + REG32(base + ADC_SR) = 0u; + job.src = base + ADC_DR; + job.dst = (uintptr_t)s->buffer; + job.count = s->length; + job.dir = EMB_DRV_DMA_FROM_PERIPH; + job.width = 2u; + job.flags = EMB_DRV_DMA_CIRCULAR; + job.reserved_ = 0u; + st = emb_drv_dma_start(&cfg->dma_rx, &job, stm32_adc_dma_done, d); + if (st != EMB_OK) { + return st; + } + adc_trigger_at(cfg, s->rate_hz); + REG32(base + ADC_CR2) = CR2_ADON | CR2_DMA | CR2_DDS | CR2_EXTEN | + ((cfg->trigger_select & 15u) << CR2_EXTSEL); + REG32(cfg->trigger + TIM_CR1) = TIM_CEN; + return EMB_OK; +} + +/* Interrupts locked by the class; or in the driver's own interrupt, which ends the sampling. */ +static void stm32_adc_sample_stop(const emb_device_t *dev) +{ + const emb_stm32_adc_config_t *cfg = stm32_adc_cfg(dev); + uint32_t moved = 0u; + REG32(cfg->trigger + TIM_CR1) = 0u; + REG32(cfg->base + ADC_CR2) = CR2_ADON; /* no trigger, no DMA */ + (void)emb_drv_dma_stop(&cfg->dma_rx, &moved); + REG32(cfg->base + ADC_CR1) = 0u; + REG32(cfg->base + ADC_SR) = 0u; +} + +/* The sensor's count at the board's VDDA, scaled to the calibration's 3.3 V, then between the + * two calibration points (emb_stm32f4_temp_mc(): 30 and 110 C). */ +static emb_status_t stm32_adc_to_mdegc(const emb_device_t *dev, uint16_t count, int32_t *mdegc) +{ + const emb_stm32_adc_config_t *cfg = stm32_adc_cfg(dev); + uint32_t at_calibration = (((uint32_t)count * cfg->vref_mv) + (CAL_MV / 2u)) / CAL_MV; + int32_t t = emb_stm32f4_temp_mc( + (uint16_t)((at_calibration > 0xFFFFu) ? 0xFFFFu : at_calibration), cfg->calibration); + if (t == INT32_MIN) { + return EMB_EIO; /* no calibration */ + } + *mdegc = t; + return EMB_OK; +} + +static uint32_t stm32_adc_vref_mv(const emb_device_t *dev) +{ + return stm32_adc_cfg(dev)->vref_mv; +} + +const emb_drv_adc_api_t emb_stm32_adc_api = { + {stm32_adc_init, NULL, NULL, NULL, NULL, + EMB_DRV_ADC_CAP_TEMPERATURE | EMB_DRV_ADC_CAP_CALIBRATED | EMB_DRV_ADC_CAP_VREFINT | + EMB_DRV_ADC_CAP_SAMPLE}, + stm32_adc_read, + stm32_adc_sample_start, + stm32_adc_sample_stop, + stm32_adc_to_mdegc, + stm32_adc_vref_mv, + 12u, + {0u, 0u, 0u}, +}; + +#else +/* ISO C: a translation unit declares something */ +typedef int emb_stm32_adc_off_t; +#endif diff --git a/drivers/st/stm32_dma.c b/drivers/st/stm32_dma.c index d2777e03..296ece86 100644 --- a/drivers/st/stm32_dma.c +++ b/drivers/st/stm32_dma.c @@ -37,10 +37,12 @@ #define CR_EN (1u << 0) #define CR_DMEIE (1u << 1) +#define CR_HTIE ((uint32_t)1u << 3) #define CR_TEIE (1u << 2) #define CR_TCIE (1u << 4) #define CR_DIR_M2P (1u << 6) #define CR_DIR_M2M (2u << 6) +#define CR_CIRC ((uint32_t)1u << 8) #define CR_PINC (1u << 9) #define CR_MINC (1u << 10) #define CR_PSIZE 11u @@ -113,9 +115,22 @@ static void stm32_dma_isr(void *arg) emb_status_t status; uint32_t moved; stm32_dma_clear(base, st->index); - if ((st->running == 0u) || ((flags & (FLAG_TC | FLAG_TE | FLAG_DME)) == 0u)) { + if ((st->running == 0u) || ((flags & (FLAG_TC | FLAG_HT | FLAG_TE | FLAG_DME)) == 0u)) { return; /* a flag of a job already stopped, or a FIFO note in direct mode */ } + if ((st->circular == 0u) && ((flags & (FLAG_TC | FLAG_TE | FLAG_DME)) == 0u)) { + return; /* a half, which only a circular job reports */ + } + if ((st->circular != 0u) && ((flags & (FLAG_TE | FLAG_DME)) == 0u)) { + /* a circular job goes on: each half's end, in order, the first before the second */ + if ((flags & FLAG_HT) != 0u) { + st->done(st->arg, EMB_OK, st->count / 2u); + } + if ((flags & FLAG_TC) != 0u) { + st->done(st->arg, EMB_OK, st->count); + } + return; + } status = ((flags & (FLAG_TE | FLAG_DME)) != 0u) ? EMB_EXFER : EMB_OK; moved = st->count - REG32(stream + SXNDTR); stm32_dma_disable(stream); @@ -192,8 +207,12 @@ static emb_status_t stm32_dma_start(const emb_device_t *dev, const emb_drv_dma_c REG32(stream + SXM0AR) = (uint32_t)(to_periph ? job->src : job->dst); REG32(stream + SXFCR) = 0u; /* direct mode */ } + if ((job->flags & EMB_DRV_DMA_CIRCULAR) != 0u) { + cr |= CR_CIRC | CR_HTIE; /* NDTR reloads at the end, and each half interrupts */ + } REG32(stream + SXNDTR) = job->count; stm32_dma_clear(cfg->base, ch->channel); + st->circular = ((job->flags & EMB_DRV_DMA_CIRCULAR) != 0u) ? 1u : 0u; st->done = done; st->arg = arg; st->count = job->count; @@ -231,7 +250,7 @@ static emb_status_t stm32_dma_stop(const emb_device_t *dev, const emb_drv_dma_ch } const emb_drv_dma_api_t emb_stm32_dma_api = { - {stm32_dma_init, NULL, NULL, NULL, NULL, EMB_DRV_DMA_CAP_MEM_TO_MEM}, + {stm32_dma_init, NULL, NULL, NULL, NULL, EMB_DRV_DMA_CAP_MEM_TO_MEM | EMB_DRV_DMA_CAP_CIRCULAR}, stm32_dma_start, stm32_dma_stop, }; diff --git a/drivers/st/stm32_tim.c b/drivers/st/stm32_tim.c index 5c88139e..b28b8c83 100644 --- a/drivers/st/stm32_tim.c +++ b/drivers/st/stm32_tim.c @@ -7,7 +7,7 @@ /** * @file stm32_tim.c - * @brief STM32 general-purpose timer as a periodic trigger (RM0390 Rev 6 §18). + * @brief STM32 general-purpose timer as a periodic trigger (RM0390 Rev 6 §17). * * @details * Its update event drives TRGO, which another peripheral (ADC1's regular conversions) takes as its diff --git a/drivers/st/stm32_tim_counter.c b/drivers/st/stm32_tim_counter.c new file mode 100644 index 00000000..be689943 --- /dev/null +++ b/drivers/st/stm32_tim_counter.c @@ -0,0 +1,240 @@ +/* SPDX-License-Identifier: Apache-2.0 */ +/* Copyright 2026 Junior Deogracias */ +/* + * This file is part of EmbLinkRTOS, a deterministic real-time kernel for microcontrollers. + * Licensed under the Apache License, Version 2.0; see the LICENSE file at the repository root. + */ + +/** + * @file stm32_tim_counter.c + * @brief STM32 general-purpose timers as counters (RM0390 Rev 6 §17, §18; SPEC-017 §11a, A129). + * + * @details + * TIM2 to TIM5, and TIM9 to TIM14 with their fewer channels, count up at the device's rate from + * its kernel clock, divided by the prescaler, and wrap at their width: 32 bits on TIM2 and TIM5, + * 16 on the others. The update interrupt + * counts the wraps, which widen the count to 64 bits. Each compare channel is an alarm: its + * count is programmed once it falls in the counter's current wrap, its epoch, and the + * interrupt checks the whole count before it fires, so an alarm many wraps away fires only at + * its own. The channels drive no pin. + * + * @author teo1747 + * @date 2026-11-13 (created) + */ +#include + +#include +#include + +#if CONFIG_EMB_DRV_COUNTER + +#define REG32(a) (*(volatile uint32_t *)(uintptr_t)(a)) + +#define TIM_CR1 0x00u +#define TIM_DIER 0x0Cu +#define TIM_SR 0x10u +#define TIM_EGR 0x14u +#define TIM_CCMR1 0x18u +#define TIM_CCMR2 0x1Cu +#define TIM_CCER 0x20u +#define TIM_CNT 0x24u +#define TIM_PSC 0x28u +#define TIM_ARR 0x2Cu +#define TIM_CCR1 0x34u /* CCR2 to CCR4 follow, 4 bytes apart */ + +#define CR1_CEN ((uint32_t)1u << 0) +#define CR1_URS ((uint32_t)1u << 2) /* only an overflow raises the update interrupt, not UG */ +#define UPDATE ((uint32_t)1u << 0) /* DIER.UIE, SR.UIF */ +#define EGR_UG ((uint32_t)1u << 0) +#define PSC_MAX 65536u /* the prescaler divides by 1 to 65536 */ +#define CHANNELS 4u /* the most: TIM2 to TIM5's */ + +/* A channel's bit in DIER (CCxIE) and in SR (CCxIF), the same: bits 1 to 4. */ +static uint32_t counter_cc_bit(uint8_t channel) +{ + return (uint32_t)1u << (1u + (uint32_t)channel); +} + +/* MISRA Dev CS-12: rules 11.3 and 11.5, a device's configuration and RAM by its driver's type. */ +static const emb_stm32_tim_config_t *counter_tim_config(const emb_device_t *dev) +{ + return (const emb_stm32_tim_config_t *)dev->config; +} + +static emb_stm32_counter_data_t *counter_data(const emb_device_t *dev) +{ + return (emb_stm32_counter_data_t *)dev->data; +} + +/* The counts in one wrap of the hardware's counter. */ +static uint64_t counter_span(const emb_stm32_tim_config_t *cfg) +{ + return (uint64_t)1u << ((cfg->bits >= 32u) ? 32u : cfg->bits); +} + +/* The count, interrupts locked: an overflow not yet counted by the update interrupt is counted + * here, and the counter read again after it. */ +static uint64_t now_locked(const emb_stm32_tim_config_t *cfg, const emb_stm32_counter_data_t *d) +{ + uint64_t high = d->high; + uint32_t count = REG32(cfg->base + TIM_CNT); + if ((REG32(cfg->base + TIM_SR) & UPDATE) != 0u) { + count = REG32(cfg->base + TIM_CNT); + high += counter_span(cfg); + } + return high + count; +} + +/* A pending channel's compare, programmed once its count is in the counter's current epoch, + * interrupts locked. */ +static void counter_program(const emb_stm32_tim_config_t *cfg, emb_stm32_counter_data_t *d, + uint8_t channel) +{ + uint64_t at = d->target[channel]; + uint8_t bit = (uint8_t)((uint32_t)1u << channel); + if (((d->pending & bit) == 0u) || (at >= (d->high + counter_span(cfg)))) { + return; /* not pending, or in a later epoch */ + } + REG32(cfg->base + TIM_CCR1 + (4u * (uint32_t)channel)) = + (at > d->high) ? (uint32_t)(at - d->high) : 0u; + REG32(cfg->base + TIM_SR) = ~counter_cc_bit(channel); /* rc_w0: the other flags stay */ + REG32(cfg->base + TIM_DIER) |= counter_cc_bit(channel); + d->pending &= (uint8_t)~bit; +} + +static void counter_cc_disarm(const emb_stm32_tim_config_t *cfg, emb_stm32_counter_data_t *d, + uint8_t channel) +{ + REG32(cfg->base + TIM_DIER) &= ~counter_cc_bit(channel); + REG32(cfg->base + TIM_SR) = ~counter_cc_bit(channel); + d->pending &= (uint8_t) ~((uint32_t)1u << channel); +} + +/* Whether a programmed channel's count is counter_reached: its compare has matched, or the count is + * past it (the match came before it was programmed, in the update interrupt). */ +static bool counter_reached(const emb_stm32_tim_config_t *cfg, const emb_stm32_counter_data_t *d, + uint8_t channel) +{ + return ((d->pending & ((uint32_t)1u << channel)) == 0u) && + ((REG32(cfg->base + TIM_DIER) & counter_cc_bit(channel)) != 0u) && + (now_locked(cfg, d) >= d->target[channel]); +} + +static void stm32_counter_isr(void *arg) +{ + emb_stm32_counter_data_t *d = (emb_stm32_counter_data_t *)arg; + const emb_stm32_tim_config_t *cfg = counter_tim_config(d->dev); + uint32_t due = 0u; + uint8_t ch; + emb_irq_key_t key = emb_irq_lock(); /* an alarm armed from a higher interrupt waits */ + uint32_t flags = REG32(cfg->base + TIM_SR) & REG32(cfg->base + TIM_DIER); + if ((flags & UPDATE) != 0u) { + REG32(cfg->base + TIM_SR) = ~UPDATE; + d->high += counter_span(cfg); + for (ch = 0u; ch < d->counter.channels; ch++) { /* bounded by CHANNELS */ + counter_program(cfg, d, ch); /* those whose epoch begins */ + } + } + for (ch = 0u; ch < d->counter.channels; ch++) { /* bounded by CHANNELS */ + if ((flags & counter_cc_bit(ch)) != 0u) { + REG32(cfg->base + TIM_SR) = ~counter_cc_bit(ch); + } + if (counter_reached(cfg, d, ch)) { + REG32(cfg->base + TIM_DIER) &= ~counter_cc_bit(ch); + due |= counter_cc_bit(ch); + } + } + emb_irq_unlock(key); + for (ch = 0u; ch < CHANNELS; ch++) { /* bounded */ + if ((due & counter_cc_bit(ch)) != 0u) { + (void)emb_drv_counter_fired(d->dev, ch); + } + } +} + +static emb_status_t stm32_counter_init(const emb_device_t *dev) +{ + const emb_stm32_tim_config_t *cfg = counter_tim_config(dev); + emb_stm32_counter_data_t *d = counter_data(dev); + uintptr_t base = cfg->base; + if ((cfg->rate_hz == 0u) || ((cfg->clock_hz % cfg->rate_hz) != 0u) || + ((cfg->clock_hz / cfg->rate_hz) > PSC_MAX)) { + return EMB_EINVAL; /* a rate the prescaler cannot make exactly */ + } + d->dev = dev; + d->high = 0u; + d->pending = 0u; + emb_stm32_clock_enable(cfg->clken_offset, cfg->clken_bit); + REG32(base + TIM_CR1) = CR1_URS; + REG32(base + TIM_DIER) = 0u; + REG32(base + TIM_CCMR1) = 0u; /* the channels compare, frozen: no output */ + if (cfg->channels > 2u) { + REG32(base + TIM_CCMR2) = 0u; /* channels 3 and 4: TIM2 to TIM5 alone */ + } + REG32(base + TIM_CCER) = 0u; + REG32(base + TIM_PSC) = (cfg->clock_hz / cfg->rate_hz) - 1u; + REG32(base + TIM_ARR) = (uint32_t)(counter_span(cfg) - 1u); + REG32(base + TIM_CNT) = 0u; + REG32(base + TIM_EGR) = EGR_UG; /* the prescaler loaded now */ + REG32(base + TIM_SR) = 0u; + REG32(base + TIM_DIER) = UPDATE; + if ((emb_irq_connect((emb_irq_t)cfg->irq, stm32_counter_isr, d) != EMB_OK) || + (emb_irq_enable((emb_irq_t)cfg->irq) != EMB_OK)) { + return EMB_EINVAL; + } + REG32(base + TIM_CR1) = CR1_URS | CR1_CEN; + return emb_drv_counter_started(dev, (uint8_t)cfg->channels); +} + +static uint64_t stm32_counter_now(const emb_device_t *dev) +{ + emb_irq_key_t key = emb_irq_lock(); + uint64_t count = now_locked(counter_tim_config(dev), counter_data(dev)); + emb_irq_unlock(key); + return count; +} + +static uint32_t stm32_counter_rate(const emb_device_t *dev) +{ + return counter_tim_config(dev)->rate_hz; +} + +/* Interrupts are locked by the class. Armed, then checked: a count that passed before its + * compare was programmed is refused; one whose compare matched meanwhile fires. */ +static emb_status_t stm32_counter_arm(const emb_device_t *dev, uint8_t channel, uint64_t at) +{ + const emb_stm32_tim_config_t *cfg = counter_tim_config(dev); + emb_stm32_counter_data_t *d = counter_data(dev); + d->target[channel] = at; + d->pending |= (uint8_t)((uint32_t)1u << channel); + counter_program(cfg, d, channel); + if (now_locked(cfg, d) >= at) { + if (((d->pending & ((uint32_t)1u << channel)) == 0u) && + ((REG32(cfg->base + TIM_SR) & counter_cc_bit(channel)) != 0u)) { + return EMB_OK; /* matched as it was armed: the interrupt fires it */ + } + counter_cc_disarm(cfg, d, channel); + return EMB_EPAST; + } + return EMB_OK; +} + +static void stm32_counter_disarm(const emb_device_t *dev, uint8_t channel) +{ + counter_cc_disarm(counter_tim_config(dev), counter_data(dev), channel); +} + +const emb_drv_counter_api_t emb_stm32_counter_api = { + {stm32_counter_init, NULL, NULL, NULL, NULL, 0u}, + stm32_counter_now, + stm32_counter_rate, + stm32_counter_arm, + stm32_counter_disarm, + (uint8_t)CHANNELS, + {0u, 0u, 0u}, +}; + +#else +/* ISO C: a translation unit declares something */ +typedef int emb_stm32_tim_counter_off_t; +#endif diff --git a/drivers/st/stm32_tim_pwm.c b/drivers/st/stm32_tim_pwm.c new file mode 100644 index 00000000..daef3690 --- /dev/null +++ b/drivers/st/stm32_tim_pwm.c @@ -0,0 +1,333 @@ +/* SPDX-License-Identifier: Apache-2.0 */ +/* Copyright 2026 Junior Deogracias */ +/* + * This file is part of EmbLinkRTOS, a deterministic real-time kernel for microcontrollers. + * Licensed under the Apache License, Version 2.0; see the LICENSE file at the repository root. + */ + +/** + * @file stm32_tim_pwm.c + * @brief STM32 general-purpose timers as PWM (RM0390 Rev 6 §17, §18; SPEC-017 §11b, A129). + * + * @details + * Outputs: each channel in PWM mode 1, its compare and the period preloaded, so a change takes + * effect at the next period without a glitch. The prescaler is the smallest that brings the + * period within the counter's width, so the pulse has the finest steps. A stopped channel is + * forced to its inactive level, which its polarity sets. + * + * Capture: channel 0's or channel 1's pin on both channels, as PWM input mode pairs them: its + * rising edge captured on its own channel, its falling edge on the other. The counter runs free, + * the update interrupt counting its wraps, which extend each capture to a count that never + * wraps; a cycle is a rising edge, a falling edge and the next rising edge, measured exactly at + * the timer's clock, however long. Timestamping each edge, rather than resetting the counter at + * one, keeps a late interrupt from moving the cycle's start. + * + * @author teo1747 + * @date 2026-11-13 (created) + */ +#include + +#include +#include + +#if CONFIG_EMB_DRV_PWM + +#define REG32(a) (*(volatile uint32_t *)(uintptr_t)(a)) + +#define TIM_CR1 0x00u +#define TIM_SMCR 0x08u +#define TIM_DIER 0x0Cu +#define TIM_SR 0x10u +#define TIM_EGR 0x14u +#define TIM_CCMR1 0x18u /* CCMR2 at 0x1C: channels 2 and 3 */ +#define TIM_CCER 0x20u +#define TIM_PSC 0x28u +#define TIM_ARR 0x2Cu +#define TIM_CCR1 0x34u /* CCR2 to CCR4 follow, 4 bytes apart */ + +#define CR1_CEN ((uint32_t)1u << 0) +#define CR1_URS \ + ((uint32_t)1u << 2) /* only an overflow raises the update interrupt: not a slave reset */ +#define CR1_ARPE ((uint32_t)1u << 7) +#define UPDATE ((uint32_t)1u << 0) /* DIER.UIE, SR.UIF */ +#define EGR_UG ((uint32_t)1u << 0) +#define OC_MASK ((uint32_t)0xFFu) /* a channel's byte in CCMRx: CCxS, OCxFE, OCxPE, OCxM, OCxCE */ +#define OC_PWM1 ((uint32_t)6u << 4) /* OCxM 110 */ +#define OC_INACT ((uint32_t)4u << 4) /* OCxM 100: forced to the inactive level */ +#define OC_PRELOAD ((uint32_t)1u << 3) /* OCxPE */ +#define IC_DIRECT ((uint32_t)1u) /* CCxS 01: the channel's own input */ +#define IC_OTHER ((uint32_t)2u) /* CCxS 10: the paired channel's input */ +#define PSC_MAX 65536u +#define NS 1000000000u + +/* A channel's bit in DIER (CCxIE) and in SR (CCxIF): bits 1 to 4. */ +static uint32_t pwm_cc_bit(uint8_t channel) +{ + return (uint32_t)1u << (1u + (uint32_t)channel); +} + +/* MISRA Dev CS-12: rules 11.3 and 11.5, a device's configuration and RAM by its driver's type. */ +static const emb_stm32_tim_config_t *pwm_tim_config(const emb_device_t *dev) +{ + return (const emb_stm32_tim_config_t *)dev->config; +} + +static emb_stm32_pwm_data_t *pwm_data(const emb_device_t *dev) +{ + return (emb_stm32_pwm_data_t *)dev->data; +} + +/* The counts in one wrap of the counter. */ +static uint64_t pwm_span(const emb_stm32_tim_config_t *cfg) +{ + return (uint64_t)1u << ((cfg->bits >= 32u) ? 32u : cfg->bits); +} + +static uint64_t clocks_of(uint32_t ns, uint32_t hz) +{ + return (((uint64_t)ns * hz) + (NS / 2u)) / NS; +} + +static uint32_t ns_of(uint64_t clocks, uint32_t hz) +{ + uint64_t ns = ((clocks * NS) + (hz / 2u)) / hz; + return (ns > UINT32_MAX) ? UINT32_MAX : (uint32_t)ns; +} + +/* A channel's output mode, its byte in CCMR1 or CCMR2. */ +static void pwm_oc_mode(uintptr_t base, uint8_t channel, uint32_t mode) +{ + uintptr_t reg = base + TIM_CCMR1 + (4u * ((uint32_t)channel >> 1)); + uint32_t shift = 8u * ((uint32_t)channel & 1u); + REG32(reg) = (REG32(reg) & ~(OC_MASK << shift)) | (mode << shift); +} + +/* An edge's capture, extended by the wraps: a wrap the interrupt has not counted yet came before + * the edge when the edge's count is in the counter's lower half. */ +static uint64_t pwm_extended(const emb_stm32_pwm_data_t *d, uint64_t wrap, bool wrapped, uint32_t v) +{ + return ((d->wraps + ((wrapped && ((uint64_t)v < (wrap / 2u))) ? 1u : 0u)) * wrap) + v; +} + +static void pwm_falling(emb_stm32_pwm_data_t *d, uint64_t at) +{ + if ((d->rises != 0u) && (at > d->rise_at)) { + d->fall_at = at; + d->fallen = 1u; + } +} + +static void pwm_rising(emb_stm32_pwm_data_t *d, const emb_stm32_tim_config_t *cfg, uint64_t at) +{ + if ((d->rises != 0u) && (d->fallen != 0u)) { /* a whole cycle: rise, fall, rise */ + d->period = at - d->rise_at; + d->pulse = d->fall_at - d->rise_at; + REG32(cfg->base + TIM_DIER) = 0u; + (void)emb_sem_give(d->done); + } + d->rise_at = at; + d->rises = 1u; + d->fallen = 0u; +} + +static void stm32_pwm_isr(void *arg) +{ + emb_stm32_pwm_data_t *d = (emb_stm32_pwm_data_t *)arg; + const emb_stm32_tim_config_t *cfg = pwm_tim_config(d->dev); + uintptr_t base = cfg->base; + uint8_t rise_ch = d->input; + uint8_t fall_ch = (uint8_t)(1u - d->input); + uint32_t flags = REG32(base + TIM_SR) & REG32(base + TIM_DIER); + bool wrapped = (flags & UPDATE) != 0u; + bool falling = (flags & pwm_cc_bit(fall_ch)) != 0u; + bool rising = (flags & pwm_cc_bit(rise_ch)) != 0u; + uint64_t wrap = pwm_span(cfg); + uint64_t fall_at = 0u; + uint64_t rise_at = 0u; + if (falling) { + fall_at = pwm_extended(d, wrap, wrapped, REG32(base + TIM_CCR1 + (4u * (uint32_t)fall_ch))); + } + if (rising) { + rise_at = pwm_extended(d, wrap, wrapped, REG32(base + TIM_CCR1 + (4u * (uint32_t)rise_ch))); + } + /* both edges at once, the interrupt late: taken in the order they came */ + if (falling && rising && (fall_at > rise_at)) { + pwm_rising(d, cfg, rise_at); + pwm_falling(d, fall_at); + } else { + if (falling) { + pwm_falling(d, fall_at); + } + if (rising) { + pwm_rising(d, cfg, rise_at); + } + } + if (wrapped) { + REG32(base + TIM_SR) = ~UPDATE; + d->wraps++; + } +} + +static emb_status_t stm32_pwm_init(const emb_device_t *dev) +{ + const emb_stm32_tim_config_t *cfg = pwm_tim_config(dev); + emb_stm32_pwm_data_t *d = pwm_data(dev); + emb_sem_attr_t attr; + emb_status_t st; + d->dev = dev; + d->prescale = 1u; + emb_stm32_clock_enable(cfg->clken_offset, cfg->clken_bit); + REG32(cfg->base + TIM_CR1) = CR1_URS; + REG32(cfg->base + TIM_SMCR) = 0u; + REG32(cfg->base + TIM_DIER) = 0u; + REG32(cfg->base + TIM_CCER) = 0u; + st = emb_drv_pwm_started(dev, (uint8_t)cfg->channels); + if (st != EMB_OK) { + return st; + } + emb_sem_attr_default(&attr); + attr.name = dev->name; + attr.initial = 0u; + attr.max = 1u; + attr.flags = EMB_SEM_SATURATE; + st = emb_sem_init(&d->done_storage, &attr, &d->done); + if (st != EMB_OK) { + return st; + } + if ((emb_irq_connect((emb_irq_t)cfg->irq, stm32_pwm_isr, d) != EMB_OK) || + (emb_irq_enable((emb_irq_t)cfg->irq) != EMB_OK)) { + return EMB_EINVAL; + } + return EMB_OK; +} + +/* Interrupts are locked by the class. With no other channel running, the period is the new one: + * the prescaler and the reload, loaded at once. With one, it is theirs, and only the pulse + * changes, at the next period. */ +static emb_status_t stm32_pwm_set(const emb_device_t *dev, uint8_t channel, uint32_t period_ns, + uint32_t pulse_ns, uint32_t flags, emb_drv_pwm_wave_t *got) +{ + const emb_stm32_tim_config_t *cfg = pwm_tim_config(dev); + emb_stm32_pwm_data_t *d = pwm_data(dev); + uintptr_t base = cfg->base; + bool alone = (d->pwm.running & (uint8_t) ~((uint32_t)1u << channel)) == 0u; + uint32_t prescale = d->prescale; + uint64_t top; + uint64_t compare; + uint32_t polarity = 2u << (4u * (uint32_t)channel); /* CCxP */ + if (alone) { + uint64_t clocks = clocks_of(period_ns, cfg->clock_hz); + prescale = (uint32_t)((clocks + pwm_span(cfg) - 1u) / pwm_span(cfg)); + if (prescale == 0u) { + prescale = 1u; + } + if ((prescale > PSC_MAX) || (((clocks + (prescale / 2u)) / prescale) < 2u)) { + return EMB_EINVAL; /* longer than the counter reaches, or shorter than two counts */ + } + top = (clocks + (prescale / 2u)) / prescale; + } else { + top = (uint64_t)REG32(base + TIM_ARR) + 1u; + } + compare = (pulse_ns >= period_ns) + ? top + : ((clocks_of(pulse_ns, cfg->clock_hz) + (prescale / 2u)) / prescale); + if (compare > top) { + compare = top; + } + REG32(base + TIM_CCR1 + (4u * (uint32_t)channel)) = (uint32_t)compare; + pwm_oc_mode(base, channel, OC_PWM1 | OC_PRELOAD); + REG32(base + TIM_CCER) = (REG32(base + TIM_CCER) & ~(polarity)) | + (((flags & EMB_DRV_PWM_INVERTED) != 0u) ? polarity : 0u) | + ((uint32_t)1u << (4u * (uint32_t)channel)); /* CCxE */ + if (alone) { + d->prescale = prescale; + REG32(base + TIM_SMCR) = 0u; /* a capture's slave reset, gone */ + REG32(base + TIM_PSC) = prescale - 1u; + REG32(base + TIM_ARR) = (uint32_t)(top - 1u); + REG32(base + TIM_CR1) = CR1_URS | CR1_ARPE; + REG32(base + TIM_EGR) = EGR_UG; /* all loaded now */ + REG32(base + TIM_CR1) = CR1_URS | CR1_ARPE | CR1_CEN; + } + if (got != NULL) { + got->period_ns = ns_of(top * prescale, cfg->clock_hz); + got->pulse_ns = ns_of(compare * prescale, cfg->clock_hz); + } + return EMB_OK; +} + +static void stm32_pwm_stop(const emb_device_t *dev, uint8_t channel) +{ + pwm_oc_mode(pwm_tim_config(dev)->base, channel, OC_INACT); /* its polarity still applies */ +} + +/* Under the device's lock; no channel of the device outputs, as the capture resets the counter. */ +static emb_status_t stm32_pwm_capture(const emb_device_t *dev, uint8_t channel, + emb_drv_pwm_wave_t *wave, emb_timeout_t timeout) +{ + const emb_stm32_tim_config_t *cfg = pwm_tim_config(dev); + emb_stm32_pwm_data_t *d = pwm_data(dev); + uintptr_t base = cfg->base; + emb_irq_key_t key; + emb_status_t st; + if (channel > 1u) { + return EMB_ENOTSUP; /* PWM input mode pairs channels 0 and 1 */ + } + key = emb_irq_lock(); + if (d->pwm.running != 0u) { + emb_irq_unlock(key); + return EMB_EBUSY; + } + REG32(base + TIM_CR1) = CR1_URS; + REG32(base + TIM_DIER) = 0u; + REG32(base + TIM_CCER) = 0u; /* the inputs chosen with their channels off */ + REG32(base + TIM_CCMR1) = (channel == 0u) ? (IC_DIRECT | (IC_OTHER << 8)) + : (IC_OTHER | (IC_DIRECT << 8)); + /* the rising edge on the input's own channel, the falling edge on the other: CCxP */ + REG32(base + TIM_CCER) = + (channel == 0u) ? (((uint32_t)1u << 0) | ((uint32_t)1u << 4) | ((uint32_t)1u << 5)) + : (((uint32_t)1u << 0) | ((uint32_t)1u << 1) | ((uint32_t)1u << 4)); + REG32(base + TIM_SMCR) = 0u; /* the counter runs free: each edge is timestamped */ + REG32(base + TIM_PSC) = 0u; + REG32(base + TIM_ARR) = (uint32_t)(pwm_span(cfg) - 1u); + REG32(base + TIM_EGR) = EGR_UG; + REG32(base + TIM_SR) = 0u; + d->prescale = 1u; + d->input = channel; + d->rises = 0u; + d->fallen = 0u; + d->wraps = 0u; + d->rise_at = 0u; + d->fall_at = 0u; + (void)emb_sem_take(d->done, EMB_NO_WAIT); /* a give a timed-out capture left */ + REG32(base + TIM_DIER) = UPDATE | pwm_cc_bit(0u) | pwm_cc_bit(1u); + REG32(base + TIM_CR1) = CR1_URS | CR1_CEN; + emb_irq_unlock(key); + st = emb_sem_take(d->done, timeout); + key = emb_irq_lock(); + REG32(base + TIM_DIER) = 0u; + REG32(base + TIM_CR1) = CR1_URS; + REG32(base + TIM_SMCR) = 0u; + REG32(base + TIM_CCER) = 0u; + REG32(base + TIM_CCMR1) = 0u; + emb_irq_unlock(key); + if (st != EMB_OK) { + return (st == EMB_ETIMEDOUT) ? EMB_ENOSIGNAL : st; + } + wave->period_ns = ns_of(d->period, cfg->clock_hz); + wave->pulse_ns = ns_of(d->pulse, cfg->clock_hz); + return EMB_OK; +} + +const emb_drv_pwm_api_t emb_stm32_pwm_api = { + {stm32_pwm_init, NULL, NULL, NULL, NULL, EMB_DRV_PWM_CAP_CAPTURE}, + stm32_pwm_set, + stm32_pwm_stop, + stm32_pwm_capture, + 4u, + {0u, 0u, 0u}, +}; + +#else +/* ISO C: a translation unit declares something */ +typedef int emb_stm32_tim_pwm_off_t; +#endif diff --git a/drivers/st/stm32f4_adc.c b/drivers/st/stm32f4_adc.c index 72408ba1..d97d1106 100644 --- a/drivers/st/stm32f4_adc.c +++ b/drivers/st/stm32f4_adc.c @@ -34,7 +34,7 @@ #define CR1_EOCIE (1u << 5) #define CR1_OVRIE (1u << 26) #define CR2_ADON (1u << 0) -#define CR2_EXTSEL_T2 (6u << 24) /* TIM2 TRGO (RM0390 Table 69) */ +#define CR2_EXTSEL_T2 (6u << 24) /* TIM2 TRGO (RM0390 §13.13.3, ADC_CR2's EXTSEL) */ #define CR2_EXTEN_RISE (1u << 28) #define CCR_ADCPRE_4 (1u << 16) /* PCLK2 / 4: 22.5 MHz from 90 MHz, under the 36 MHz limit */ #define CCR_TSVREFE (1u << 23) /* the temperature sensor and VREFINT on */ diff --git a/examples/.clang-tidy b/examples/.clang-tidy new file mode 100644 index 00000000..2475d1fb --- /dev/null +++ b/examples/.clang-tidy @@ -0,0 +1,11 @@ +# SPDX-License-Identifier: Apache-2.0 +# Copyright 2026 Junior Deogracias +# +# This file is part of EmbLinkRTOS, a deterministic real-time kernel for microcontrollers. +# Licensed under the Apache License, Version 2.0; see the LICENSE file at the repository root. + +# Applications (A130): their files take MPLAB Harmony's names (SYS_Initialize(), DOOR_Tasks(), +# DOOR_DATA, doorData), so the naming rules are the kernel's and the drivers' alone. Every other +# check is the root's. +InheritParentConfig: true +Checks: '-readability-identifier-naming' diff --git a/examples/controller/generated/.base/nucleo_f446re/include/system.h b/examples/controller/generated/.base/nucleo_f446re/include/system.h deleted file mode 100644 index 6d787af1..00000000 --- a/examples/controller/generated/.base/nucleo_f446re/include/system.h +++ /dev/null @@ -1,61 +0,0 @@ -/* SPDX-License-Identifier: Apache-2.0 */ -/* - * This file is part of EmbLinkRTOS, a deterministic real-time kernel for microcontrollers. - * Licensed under the Apache License, Version 2.0; see the LICENSE file at the repository root. - */ - -/** - * @file system.h - * @brief The system controller's threads, objects, targets and watchdog for the application's - * sources (SPEC-014 §5, A125). - * - * @details - * Generated by emb-hwgen 0.1.0, schema v0. Do not edit: change the - * description and run hw/gen/emb-hwgen.py generate --system examples/controller/system.yaml (HW-003). - * Inputs (SHA-256): - * arch/cortex_m/arch.yaml - * c5c8e451c09717dee1713d07f8311b6d507e3b4c66c42d93e0ce11da6ec76d6d - * boards/st/nucleo_f446re/board.yaml - * d756f3a7f19dc7da82ee3afc168dc54946312c5a9990720953c0fedcdece54ea - * drivers/bindings.yaml - * d3c336ac05548e0addd1faac18f3dff70576d8069f11d89e6a761cf5c6132b49 - * examples/controller/controller.conf - * f7354e5137f5ea50fbd1d5829ff4f5eb88a044100d871d6a8fd7d976339a75f1 - * examples/controller/system.yaml - * 2a91f71f1de638aa1ffaa18f0f76fc3ccde44d2560aef98a9a48120775773af3 - * soc/st/stm32f4/stm32f4.yaml - * 3db4a0a65c9624d865d4ed7fc6354bf95054d0c465b76a2091f06aeac3d7375f - * soc/st/stm32f4/stm32f446.yaml - * 0d5cc7f5fce4c51be71678987720c85c6e76e05473ff8a78ea5035394316c055 - * soc/st/stm32f4/stm32f446re.yaml - * b9a88d0a94aa17ee83317a3a56f7c194ec1b3107dfb3e82e453122dc1c48f6d4 - */ -#ifndef EMB_SYSTEM_H -#define EMB_SYSTEM_H - -#include - -#include "controller.h" - -#ifdef __cplusplus -extern "C" { -#endif - -/* threads: their entries, which the application defines, and their handles */ -void command(void *arg); -void control(void *arg); -void telemetry(void *arg); -extern emb_thread_t control_thread; -extern emb_thread_t command_thread; -extern emb_thread_t telemetry_thread; - -/* objects */ -extern emb_msgq_t samples; -extern emb_msgq_t rx_bytes; -extern emb_mutex_t console; - -#ifdef __cplusplus -} -#endif - -#endif /* EMB_SYSTEM_H */ diff --git a/examples/controller/generated/.base/nucleo_f446re/src/system.c b/examples/controller/generated/.base/nucleo_f446re/src/system.c deleted file mode 100644 index 2acb4bc3..00000000 --- a/examples/controller/generated/.base/nucleo_f446re/src/system.c +++ /dev/null @@ -1,40 +0,0 @@ -/* SPDX-License-Identifier: Apache-2.0 */ -/* - * This file is part of EmbLinkRTOS, a deterministic real-time kernel for microcontrollers. - * Licensed under the Apache License, Version 2.0; see the LICENSE file at the repository root. - */ - -/** - * @file system.c - * @brief The system controller's static definitions: the kernel creates each from its - * initialization table (SPEC-001 §6.4, SPEC-014 §5, A125). - * - * @details - * Generated by emb-hwgen 0.1.0, schema v0. Do not edit: change the - * description and run hw/gen/emb-hwgen.py generate --system examples/controller/system.yaml (HW-003). - * Inputs (SHA-256): - * arch/cortex_m/arch.yaml - * c5c8e451c09717dee1713d07f8311b6d507e3b4c66c42d93e0ce11da6ec76d6d - * boards/st/nucleo_f446re/board.yaml - * d756f3a7f19dc7da82ee3afc168dc54946312c5a9990720953c0fedcdece54ea - * drivers/bindings.yaml - * d3c336ac05548e0addd1faac18f3dff70576d8069f11d89e6a761cf5c6132b49 - * examples/controller/controller.conf - * f7354e5137f5ea50fbd1d5829ff4f5eb88a044100d871d6a8fd7d976339a75f1 - * examples/controller/system.yaml - * 2a91f71f1de638aa1ffaa18f0f76fc3ccde44d2560aef98a9a48120775773af3 - * soc/st/stm32f4/stm32f4.yaml - * 3db4a0a65c9624d865d4ed7fc6354bf95054d0c465b76a2091f06aeac3d7375f - * soc/st/stm32f4/stm32f446.yaml - * 0d5cc7f5fce4c51be71678987720c85c6e76e05473ff8a78ea5035394316c055 - * soc/st/stm32f4/stm32f446re.yaml - * b9a88d0a94aa17ee83317a3a56f7c194ec1b3107dfb3e82e453122dc1c48f6d4 - */ -#include "system.h" - -EMB_THREAD_DEFINE(control_thread, control, NULL, 6u, 1024u, 0u); -EMB_THREAD_DEFINE(command_thread, command, NULL, 4u, 1024u, 0u); -EMB_THREAD_DEFINE(telemetry_thread, telemetry, NULL, 2u, 1024u, 0u); -EMB_MSGQ_DEFINE(samples, sizeof(sample_t), 8u, 0u); -EMB_MSGQ_DEFINE(rx_bytes, 1u, 64u, 0u); -EMB_MUTEX_DEFINE(console, EMB_MUTEX_INHERIT, 0u, 0u); diff --git a/examples/controller/generated/.base/nucleo_f446ze/include/system.h b/examples/controller/generated/.base/nucleo_f446ze/include/system.h deleted file mode 100644 index f43f70e0..00000000 --- a/examples/controller/generated/.base/nucleo_f446ze/include/system.h +++ /dev/null @@ -1,61 +0,0 @@ -/* SPDX-License-Identifier: Apache-2.0 */ -/* - * This file is part of EmbLinkRTOS, a deterministic real-time kernel for microcontrollers. - * Licensed under the Apache License, Version 2.0; see the LICENSE file at the repository root. - */ - -/** - * @file system.h - * @brief The system controller's threads, objects, targets and watchdog for the application's - * sources (SPEC-014 §5, A125). - * - * @details - * Generated by emb-hwgen 0.1.0, schema v0. Do not edit: change the - * description and run hw/gen/emb-hwgen.py generate --system examples/controller/system.yaml (HW-003). - * Inputs (SHA-256): - * arch/cortex_m/arch.yaml - * c5c8e451c09717dee1713d07f8311b6d507e3b4c66c42d93e0ce11da6ec76d6d - * boards/st/nucleo_f446ze/board.yaml - * 1525ea206692663af174039e30776d6a9a9b30275c9e5c9bdabf14ac0b70aa19 - * drivers/bindings.yaml - * d3c336ac05548e0addd1faac18f3dff70576d8069f11d89e6a761cf5c6132b49 - * examples/controller/controller.conf - * f7354e5137f5ea50fbd1d5829ff4f5eb88a044100d871d6a8fd7d976339a75f1 - * examples/controller/system.yaml - * 2a91f71f1de638aa1ffaa18f0f76fc3ccde44d2560aef98a9a48120775773af3 - * soc/st/stm32f4/stm32f4.yaml - * 3db4a0a65c9624d865d4ed7fc6354bf95054d0c465b76a2091f06aeac3d7375f - * soc/st/stm32f4/stm32f446.yaml - * 0d5cc7f5fce4c51be71678987720c85c6e76e05473ff8a78ea5035394316c055 - * soc/st/stm32f4/stm32f446ze.yaml - * dabae95e9e4bc984c1a33275966665e0252068e929fe3b430d06589da6bdb6c9 - */ -#ifndef EMB_SYSTEM_H -#define EMB_SYSTEM_H - -#include - -#include "controller.h" - -#ifdef __cplusplus -extern "C" { -#endif - -/* threads: their entries, which the application defines, and their handles */ -void command(void *arg); -void control(void *arg); -void telemetry(void *arg); -extern emb_thread_t control_thread; -extern emb_thread_t command_thread; -extern emb_thread_t telemetry_thread; - -/* objects */ -extern emb_msgq_t samples; -extern emb_msgq_t rx_bytes; -extern emb_mutex_t console; - -#ifdef __cplusplus -} -#endif - -#endif /* EMB_SYSTEM_H */ diff --git a/examples/controller/generated/.base/nucleo_f446ze/src/system.c b/examples/controller/generated/.base/nucleo_f446ze/src/system.c deleted file mode 100644 index 0260c0ab..00000000 --- a/examples/controller/generated/.base/nucleo_f446ze/src/system.c +++ /dev/null @@ -1,40 +0,0 @@ -/* SPDX-License-Identifier: Apache-2.0 */ -/* - * This file is part of EmbLinkRTOS, a deterministic real-time kernel for microcontrollers. - * Licensed under the Apache License, Version 2.0; see the LICENSE file at the repository root. - */ - -/** - * @file system.c - * @brief The system controller's static definitions: the kernel creates each from its - * initialization table (SPEC-001 §6.4, SPEC-014 §5, A125). - * - * @details - * Generated by emb-hwgen 0.1.0, schema v0. Do not edit: change the - * description and run hw/gen/emb-hwgen.py generate --system examples/controller/system.yaml (HW-003). - * Inputs (SHA-256): - * arch/cortex_m/arch.yaml - * c5c8e451c09717dee1713d07f8311b6d507e3b4c66c42d93e0ce11da6ec76d6d - * boards/st/nucleo_f446ze/board.yaml - * 1525ea206692663af174039e30776d6a9a9b30275c9e5c9bdabf14ac0b70aa19 - * drivers/bindings.yaml - * d3c336ac05548e0addd1faac18f3dff70576d8069f11d89e6a761cf5c6132b49 - * examples/controller/controller.conf - * f7354e5137f5ea50fbd1d5829ff4f5eb88a044100d871d6a8fd7d976339a75f1 - * examples/controller/system.yaml - * 2a91f71f1de638aa1ffaa18f0f76fc3ccde44d2560aef98a9a48120775773af3 - * soc/st/stm32f4/stm32f4.yaml - * 3db4a0a65c9624d865d4ed7fc6354bf95054d0c465b76a2091f06aeac3d7375f - * soc/st/stm32f4/stm32f446.yaml - * 0d5cc7f5fce4c51be71678987720c85c6e76e05473ff8a78ea5035394316c055 - * soc/st/stm32f4/stm32f446ze.yaml - * dabae95e9e4bc984c1a33275966665e0252068e929fe3b430d06589da6bdb6c9 - */ -#include "system.h" - -EMB_THREAD_DEFINE(control_thread, control, NULL, 6u, 1024u, 0u); -EMB_THREAD_DEFINE(command_thread, command, NULL, 4u, 1024u, 0u); -EMB_THREAD_DEFINE(telemetry_thread, telemetry, NULL, 2u, 1024u, 0u); -EMB_MSGQ_DEFINE(samples, sizeof(sample_t), 8u, 0u); -EMB_MSGQ_DEFINE(rx_bytes, 1u, 64u, 0u); -EMB_MUTEX_DEFINE(console, EMB_MUTEX_INHERIT, 0u, 0u); diff --git a/examples/controller/generated/nucleo_f446re/include/system.h b/examples/controller/generated/nucleo_f446re/include/system.h deleted file mode 100644 index 6d787af1..00000000 --- a/examples/controller/generated/nucleo_f446re/include/system.h +++ /dev/null @@ -1,61 +0,0 @@ -/* SPDX-License-Identifier: Apache-2.0 */ -/* - * This file is part of EmbLinkRTOS, a deterministic real-time kernel for microcontrollers. - * Licensed under the Apache License, Version 2.0; see the LICENSE file at the repository root. - */ - -/** - * @file system.h - * @brief The system controller's threads, objects, targets and watchdog for the application's - * sources (SPEC-014 §5, A125). - * - * @details - * Generated by emb-hwgen 0.1.0, schema v0. Do not edit: change the - * description and run hw/gen/emb-hwgen.py generate --system examples/controller/system.yaml (HW-003). - * Inputs (SHA-256): - * arch/cortex_m/arch.yaml - * c5c8e451c09717dee1713d07f8311b6d507e3b4c66c42d93e0ce11da6ec76d6d - * boards/st/nucleo_f446re/board.yaml - * d756f3a7f19dc7da82ee3afc168dc54946312c5a9990720953c0fedcdece54ea - * drivers/bindings.yaml - * d3c336ac05548e0addd1faac18f3dff70576d8069f11d89e6a761cf5c6132b49 - * examples/controller/controller.conf - * f7354e5137f5ea50fbd1d5829ff4f5eb88a044100d871d6a8fd7d976339a75f1 - * examples/controller/system.yaml - * 2a91f71f1de638aa1ffaa18f0f76fc3ccde44d2560aef98a9a48120775773af3 - * soc/st/stm32f4/stm32f4.yaml - * 3db4a0a65c9624d865d4ed7fc6354bf95054d0c465b76a2091f06aeac3d7375f - * soc/st/stm32f4/stm32f446.yaml - * 0d5cc7f5fce4c51be71678987720c85c6e76e05473ff8a78ea5035394316c055 - * soc/st/stm32f4/stm32f446re.yaml - * b9a88d0a94aa17ee83317a3a56f7c194ec1b3107dfb3e82e453122dc1c48f6d4 - */ -#ifndef EMB_SYSTEM_H -#define EMB_SYSTEM_H - -#include - -#include "controller.h" - -#ifdef __cplusplus -extern "C" { -#endif - -/* threads: their entries, which the application defines, and their handles */ -void command(void *arg); -void control(void *arg); -void telemetry(void *arg); -extern emb_thread_t control_thread; -extern emb_thread_t command_thread; -extern emb_thread_t telemetry_thread; - -/* objects */ -extern emb_msgq_t samples; -extern emb_msgq_t rx_bytes; -extern emb_mutex_t console; - -#ifdef __cplusplus -} -#endif - -#endif /* EMB_SYSTEM_H */ diff --git a/examples/controller/generated/nucleo_f446re/src/system.c b/examples/controller/generated/nucleo_f446re/src/system.c deleted file mode 100644 index 2acb4bc3..00000000 --- a/examples/controller/generated/nucleo_f446re/src/system.c +++ /dev/null @@ -1,40 +0,0 @@ -/* SPDX-License-Identifier: Apache-2.0 */ -/* - * This file is part of EmbLinkRTOS, a deterministic real-time kernel for microcontrollers. - * Licensed under the Apache License, Version 2.0; see the LICENSE file at the repository root. - */ - -/** - * @file system.c - * @brief The system controller's static definitions: the kernel creates each from its - * initialization table (SPEC-001 §6.4, SPEC-014 §5, A125). - * - * @details - * Generated by emb-hwgen 0.1.0, schema v0. Do not edit: change the - * description and run hw/gen/emb-hwgen.py generate --system examples/controller/system.yaml (HW-003). - * Inputs (SHA-256): - * arch/cortex_m/arch.yaml - * c5c8e451c09717dee1713d07f8311b6d507e3b4c66c42d93e0ce11da6ec76d6d - * boards/st/nucleo_f446re/board.yaml - * d756f3a7f19dc7da82ee3afc168dc54946312c5a9990720953c0fedcdece54ea - * drivers/bindings.yaml - * d3c336ac05548e0addd1faac18f3dff70576d8069f11d89e6a761cf5c6132b49 - * examples/controller/controller.conf - * f7354e5137f5ea50fbd1d5829ff4f5eb88a044100d871d6a8fd7d976339a75f1 - * examples/controller/system.yaml - * 2a91f71f1de638aa1ffaa18f0f76fc3ccde44d2560aef98a9a48120775773af3 - * soc/st/stm32f4/stm32f4.yaml - * 3db4a0a65c9624d865d4ed7fc6354bf95054d0c465b76a2091f06aeac3d7375f - * soc/st/stm32f4/stm32f446.yaml - * 0d5cc7f5fce4c51be71678987720c85c6e76e05473ff8a78ea5035394316c055 - * soc/st/stm32f4/stm32f446re.yaml - * b9a88d0a94aa17ee83317a3a56f7c194ec1b3107dfb3e82e453122dc1c48f6d4 - */ -#include "system.h" - -EMB_THREAD_DEFINE(control_thread, control, NULL, 6u, 1024u, 0u); -EMB_THREAD_DEFINE(command_thread, command, NULL, 4u, 1024u, 0u); -EMB_THREAD_DEFINE(telemetry_thread, telemetry, NULL, 2u, 1024u, 0u); -EMB_MSGQ_DEFINE(samples, sizeof(sample_t), 8u, 0u); -EMB_MSGQ_DEFINE(rx_bytes, 1u, 64u, 0u); -EMB_MUTEX_DEFINE(console, EMB_MUTEX_INHERIT, 0u, 0u); diff --git a/examples/controller/generated/nucleo_f446ze/include/system.h b/examples/controller/generated/nucleo_f446ze/include/system.h deleted file mode 100644 index f43f70e0..00000000 --- a/examples/controller/generated/nucleo_f446ze/include/system.h +++ /dev/null @@ -1,61 +0,0 @@ -/* SPDX-License-Identifier: Apache-2.0 */ -/* - * This file is part of EmbLinkRTOS, a deterministic real-time kernel for microcontrollers. - * Licensed under the Apache License, Version 2.0; see the LICENSE file at the repository root. - */ - -/** - * @file system.h - * @brief The system controller's threads, objects, targets and watchdog for the application's - * sources (SPEC-014 §5, A125). - * - * @details - * Generated by emb-hwgen 0.1.0, schema v0. Do not edit: change the - * description and run hw/gen/emb-hwgen.py generate --system examples/controller/system.yaml (HW-003). - * Inputs (SHA-256): - * arch/cortex_m/arch.yaml - * c5c8e451c09717dee1713d07f8311b6d507e3b4c66c42d93e0ce11da6ec76d6d - * boards/st/nucleo_f446ze/board.yaml - * 1525ea206692663af174039e30776d6a9a9b30275c9e5c9bdabf14ac0b70aa19 - * drivers/bindings.yaml - * d3c336ac05548e0addd1faac18f3dff70576d8069f11d89e6a761cf5c6132b49 - * examples/controller/controller.conf - * f7354e5137f5ea50fbd1d5829ff4f5eb88a044100d871d6a8fd7d976339a75f1 - * examples/controller/system.yaml - * 2a91f71f1de638aa1ffaa18f0f76fc3ccde44d2560aef98a9a48120775773af3 - * soc/st/stm32f4/stm32f4.yaml - * 3db4a0a65c9624d865d4ed7fc6354bf95054d0c465b76a2091f06aeac3d7375f - * soc/st/stm32f4/stm32f446.yaml - * 0d5cc7f5fce4c51be71678987720c85c6e76e05473ff8a78ea5035394316c055 - * soc/st/stm32f4/stm32f446ze.yaml - * dabae95e9e4bc984c1a33275966665e0252068e929fe3b430d06589da6bdb6c9 - */ -#ifndef EMB_SYSTEM_H -#define EMB_SYSTEM_H - -#include - -#include "controller.h" - -#ifdef __cplusplus -extern "C" { -#endif - -/* threads: their entries, which the application defines, and their handles */ -void command(void *arg); -void control(void *arg); -void telemetry(void *arg); -extern emb_thread_t control_thread; -extern emb_thread_t command_thread; -extern emb_thread_t telemetry_thread; - -/* objects */ -extern emb_msgq_t samples; -extern emb_msgq_t rx_bytes; -extern emb_mutex_t console; - -#ifdef __cplusplus -} -#endif - -#endif /* EMB_SYSTEM_H */ diff --git a/examples/controller/generated/nucleo_f446ze/src/system.c b/examples/controller/generated/nucleo_f446ze/src/system.c deleted file mode 100644 index 0260c0ab..00000000 --- a/examples/controller/generated/nucleo_f446ze/src/system.c +++ /dev/null @@ -1,40 +0,0 @@ -/* SPDX-License-Identifier: Apache-2.0 */ -/* - * This file is part of EmbLinkRTOS, a deterministic real-time kernel for microcontrollers. - * Licensed under the Apache License, Version 2.0; see the LICENSE file at the repository root. - */ - -/** - * @file system.c - * @brief The system controller's static definitions: the kernel creates each from its - * initialization table (SPEC-001 §6.4, SPEC-014 §5, A125). - * - * @details - * Generated by emb-hwgen 0.1.0, schema v0. Do not edit: change the - * description and run hw/gen/emb-hwgen.py generate --system examples/controller/system.yaml (HW-003). - * Inputs (SHA-256): - * arch/cortex_m/arch.yaml - * c5c8e451c09717dee1713d07f8311b6d507e3b4c66c42d93e0ce11da6ec76d6d - * boards/st/nucleo_f446ze/board.yaml - * 1525ea206692663af174039e30776d6a9a9b30275c9e5c9bdabf14ac0b70aa19 - * drivers/bindings.yaml - * d3c336ac05548e0addd1faac18f3dff70576d8069f11d89e6a761cf5c6132b49 - * examples/controller/controller.conf - * f7354e5137f5ea50fbd1d5829ff4f5eb88a044100d871d6a8fd7d976339a75f1 - * examples/controller/system.yaml - * 2a91f71f1de638aa1ffaa18f0f76fc3ccde44d2560aef98a9a48120775773af3 - * soc/st/stm32f4/stm32f4.yaml - * 3db4a0a65c9624d865d4ed7fc6354bf95054d0c465b76a2091f06aeac3d7375f - * soc/st/stm32f4/stm32f446.yaml - * 0d5cc7f5fce4c51be71678987720c85c6e76e05473ff8a78ea5035394316c055 - * soc/st/stm32f4/stm32f446ze.yaml - * dabae95e9e4bc984c1a33275966665e0252068e929fe3b430d06589da6bdb6c9 - */ -#include "system.h" - -EMB_THREAD_DEFINE(control_thread, control, NULL, 6u, 1024u, 0u); -EMB_THREAD_DEFINE(command_thread, command, NULL, 4u, 1024u, 0u); -EMB_THREAD_DEFINE(telemetry_thread, telemetry, NULL, 2u, 1024u, 0u); -EMB_MSGQ_DEFINE(samples, sizeof(sample_t), 8u, 0u); -EMB_MSGQ_DEFINE(rx_bytes, 1u, 64u, 0u); -EMB_MUTEX_DEFINE(console, EMB_MUTEX_INHERIT, 0u, 0u); diff --git a/examples/controller/main.c b/examples/controller/main.c index 4eee9916..aacf8d2d 100644 --- a/examples/controller/main.c +++ b/examples/controller/main.c @@ -36,11 +36,11 @@ * @author Junior Deogracias * @date 2026-11-07 (created) */ +#include "definitions.h" + #include #include -#include "system.h" - #include #include #include @@ -77,7 +77,7 @@ static const emb_stm32_pin_t markers[] = { /* What the threads and the handlers share. Each field has one writer; the readers take a * snapshot, and a torn read of a counter is at most one update old. */ static volatile struct { - uint32_t samples; /* processed by the control thread */ + uint32_t processed; /* samples processed by the control thread */ uint32_t missed; /* receive timeouts: no sample for three periods */ uint32_t deadline_miss; /* processing ended after the next sample was due */ uint32_t shed; /* samples skipped in degraded mode */ @@ -253,7 +253,7 @@ void control(void *arg) if (done - s.cycles > st.proc_max) { st.proc_max = done - s.cycles; } - st.samples++; + st.processed++; /* the deadline: the next processed sample's arrival, one period away (two when degraded) */ if (done - s.cycles > period * (st.degraded != 0u ? 2u : 1u)) { st.deadline_miss++; @@ -441,7 +441,7 @@ void telemetry(void *arg) out(" heater="); out_u32(st.heater); out(" samples="); - out_u32(st.samples); + out_u32(st.processed); out(" missed="); out_u32(st.missed); out(" deadline_miss="); diff --git a/examples/controller/generated/.base/nucleo_f446re/build/CMakeLists.txt b/examples/controller/src/config/.base/nucleo_f446re/build/CMakeLists.txt similarity index 67% rename from examples/controller/generated/.base/nucleo_f446re/build/CMakeLists.txt rename to examples/controller/src/config/.base/nucleo_f446re/build/CMakeLists.txt index dcfece83..fce90e43 100644 --- a/examples/controller/generated/.base/nucleo_f446re/build/CMakeLists.txt +++ b/examples/controller/src/config/.base/nucleo_f446re/build/CMakeLists.txt @@ -4,24 +4,26 @@ # Licensed under the Apache License, Version 2.0; see the LICENSE file at the repository root. # # Generated by emb-hwgen 0.1.0, schema v0. Do not edit: change the -# description and run hw/gen/emb-hwgen.py generate --system examples/controller/system.yaml (HW-003). +# description and run +# hw/gen/emb-hwgen.py generate --system examples/controller/system.yaml +# (HW-003). # Inputs (SHA-256): # arch/cortex_m/arch.yaml # c5c8e451c09717dee1713d07f8311b6d507e3b4c66c42d93e0ce11da6ec76d6d # boards/st/nucleo_f446re/board.yaml -# d756f3a7f19dc7da82ee3afc168dc54946312c5a9990720953c0fedcdece54ea +# 551c524379751d359bdd87501269d6cab33edf84d212d2f6632ffe9567ec71d0 # drivers/bindings.yaml -# d3c336ac05548e0addd1faac18f3dff70576d8069f11d89e6a761cf5c6132b49 +# c06d1a914adb21d0e314c79b3611ac6859eefeac1957d6914cccfc5531ad6ede # examples/controller/controller.conf # f7354e5137f5ea50fbd1d5829ff4f5eb88a044100d871d6a8fd7d976339a75f1 # examples/controller/system.yaml # 2a91f71f1de638aa1ffaa18f0f76fc3ccde44d2560aef98a9a48120775773af3 # soc/st/stm32f4/stm32f4.yaml -# 3db4a0a65c9624d865d4ed7fc6354bf95054d0c465b76a2091f06aeac3d7375f +# 796886c294250aa81151a620d80d0e43b5ee8e1bf53a07d1d7e2c62e95214dbd # soc/st/stm32f4/stm32f446.yaml -# 0d5cc7f5fce4c51be71678987720c85c6e76e05473ff8a78ea5035394316c055 +# f0c9a37f6017c87d0efe215a3561f65494ba52383f2d0c10419b0ab5035f77f2 # soc/st/stm32f4/stm32f446re.yaml # b9a88d0a94aa17ee83317a3a56f7c194ec1b3107dfb3e82e453122dc1c48f6d4 # The board has no C of its own: its SoC family's board support builds emb_board from -# ../src/board_pins.c and ../include/hw_config.h, and links ../linker/regions.ld. +# ../peripheral/board_pins.c and ../peripheral/hw_config.h, and links ../linker/regions.ld. add_subdirectory("${EMB_SOC_DIR}" soc) diff --git a/examples/controller/generated/.base/nucleo_f446re/build/board.cmake b/examples/controller/src/config/.base/nucleo_f446re/build/board.cmake similarity index 66% rename from examples/controller/generated/.base/nucleo_f446re/build/board.cmake rename to examples/controller/src/config/.base/nucleo_f446re/build/board.cmake index 6ced6ea5..14cfd5e9 100644 --- a/examples/controller/generated/.base/nucleo_f446re/build/board.cmake +++ b/examples/controller/src/config/.base/nucleo_f446re/build/board.cmake @@ -4,22 +4,24 @@ # Licensed under the Apache License, Version 2.0; see the LICENSE file at the repository root. # # Generated by emb-hwgen 0.1.0, schema v0. Do not edit: change the -# description and run hw/gen/emb-hwgen.py generate --system examples/controller/system.yaml (HW-003). +# description and run +# hw/gen/emb-hwgen.py generate --system examples/controller/system.yaml +# (HW-003). # Inputs (SHA-256): # arch/cortex_m/arch.yaml # c5c8e451c09717dee1713d07f8311b6d507e3b4c66c42d93e0ce11da6ec76d6d # boards/st/nucleo_f446re/board.yaml -# d756f3a7f19dc7da82ee3afc168dc54946312c5a9990720953c0fedcdece54ea +# 551c524379751d359bdd87501269d6cab33edf84d212d2f6632ffe9567ec71d0 # drivers/bindings.yaml -# d3c336ac05548e0addd1faac18f3dff70576d8069f11d89e6a761cf5c6132b49 +# c06d1a914adb21d0e314c79b3611ac6859eefeac1957d6914cccfc5531ad6ede # examples/controller/controller.conf # f7354e5137f5ea50fbd1d5829ff4f5eb88a044100d871d6a8fd7d976339a75f1 # examples/controller/system.yaml # 2a91f71f1de638aa1ffaa18f0f76fc3ccde44d2560aef98a9a48120775773af3 # soc/st/stm32f4/stm32f4.yaml -# 3db4a0a65c9624d865d4ed7fc6354bf95054d0c465b76a2091f06aeac3d7375f +# 796886c294250aa81151a620d80d0e43b5ee8e1bf53a07d1d7e2c62e95214dbd # soc/st/stm32f4/stm32f446.yaml -# 0d5cc7f5fce4c51be71678987720c85c6e76e05473ff8a78ea5035394316c055 +# f0c9a37f6017c87d0efe215a3561f65494ba52383f2d0c10419b0ab5035f77f2 # soc/st/stm32f4/stm32f446re.yaml # b9a88d0a94aa17ee83317a3a56f7c194ec1b3107dfb3e82e453122dc1c48f6d4 # nucleo_f446re: STM32F446RE, cortex-m4f at 180 MHz. @@ -28,23 +30,28 @@ set(EMB_BOARD_VARIANT armv7em) set(EMB_BOARD_DEFAULT_PROFILE base) set(EMB_BOARD_C_FLAGS -mcpu=cortex-m4 -mfpu=fpv4-sp-d16 -mfloat-abi=hard) get_filename_component(EMB_BOARD_GENERATED_DIR "${CMAKE_CURRENT_LIST_DIR}/.." ABSOLUTE) -set(EMB_BOARD_CONF "${EMB_BOARD_GENERATED_DIR}/config/board.conf") +set(EMB_BOARD_CONF "${EMB_BOARD_GENERATED_DIR}/build/board.conf") set(EMB_BOARD_HW_JSON "${EMB_BOARD_GENERATED_DIR}/docs/hw.json") set(EMB_BOARD_BUILD_DIR "${CMAKE_CURRENT_LIST_DIR}") # build/CMakeLists.txt +set(EMB_BOARD_SRC_DIR "${EMB_BOARD_GENERATED_DIR}/peripheral") # its pin table and boot block +set(EMB_BOARD_LINKER_DIR "${EMB_BOARD_GENERATED_DIR}/linker") # the SoC family's board support and drivers build this board (build/CMakeLists.txt) set(EMB_SOC_DIR "${EMB_BASE}/soc/st/stm32f4") -set(EMB_BOARD_INCLUDE_DIRS "${EMB_BOARD_GENERATED_DIR}/include" "${EMB_SOC_DIR}/include") +set(EMB_BOARD_INCLUDE_DIRS "${EMB_BOARD_GENERATED_DIR}/peripheral" "${EMB_SOC_DIR}/include") set(EMB_BOARD_RESETS_IN embsim hil) # restart the image with RAM kept (test_crash_reset) set(EMB_BOARD_EMBSIM_TARGET emblink/nucleo_f446re) # EMB_TEST_EMULATOR=embsim set(EMB_BOARD_USART2_DMA tx) set(EMB_BOARD_SPI2_DMA rx tx) set(EMB_BOARD_SPI2_CS_COUNT 1) +set(EMB_BOARD_ADC1_DMA rx) set(EMB_BOARD_EMBSIM_UART_LOOP uart4 "A0,A1") set(EMB_BOARD_EMBSIM_SPI_LOOP spi2 "CN10_26,CN10_28") set(EMB_BOARD_EMBSIM_I2C_LOOP i2c1 i2c2 "D15,D6" "D14,D3") +set(EMB_BOARD_EMBSIM_PWM_LOOP "tim3:0,tim4:0" "D12,D10") +set(EMB_BOARD_EMBSIM_ADC_LOOP "adc1:4,8" "A2,3V3" "A3,GND") # the board's devices (soc_devices.c) and the drivers they use, and only those (SPEC-016 §8) set(EMB_BOARD_DRIVER_SOURCES - "${EMB_BOARD_GENERATED_DIR}/src/soc_devices.c" + "${EMB_BOARD_GENERATED_DIR}/peripheral/soc_devices.c" "${EMB_BASE}/drivers/st/stm32_devices.c" "${EMB_BASE}/drivers/st/stm32_iwdg.c" "${EMB_BASE}/drivers/st/stm32_rtc.c" @@ -53,6 +60,9 @@ set(EMB_BOARD_DRIVER_SOURCES "${EMB_BASE}/drivers/st/stm32_uart.c" "${EMB_BASE}/drivers/st/stm32_spi.c" "${EMB_BASE}/drivers/st/stm32_i2c.c" + "${EMB_BASE}/drivers/st/stm32_tim_counter.c" + "${EMB_BASE}/drivers/st/stm32_tim_pwm.c" + "${EMB_BASE}/drivers/st/stm32_adc.c" ) set(EMB_BOARD_DRIVER_INCLUDE_DIRS "${EMB_BASE}/drivers/st/include" @@ -60,11 +70,11 @@ set(EMB_BOARD_DRIVER_INCLUDE_DIRS # the inputs this directory was generated from, for the configure-time staleness check set(EMB_BOARD_HW_INPUTS "arch/cortex_m/arch.yaml=c5c8e451c09717dee1713d07f8311b6d507e3b4c66c42d93e0ce11da6ec76d6d" - "boards/st/nucleo_f446re/board.yaml=d756f3a7f19dc7da82ee3afc168dc54946312c5a9990720953c0fedcdece54ea" - "drivers/bindings.yaml=d3c336ac05548e0addd1faac18f3dff70576d8069f11d89e6a761cf5c6132b49" + "boards/st/nucleo_f446re/board.yaml=551c524379751d359bdd87501269d6cab33edf84d212d2f6632ffe9567ec71d0" + "drivers/bindings.yaml=c06d1a914adb21d0e314c79b3611ac6859eefeac1957d6914cccfc5531ad6ede" "examples/controller/controller.conf=f7354e5137f5ea50fbd1d5829ff4f5eb88a044100d871d6a8fd7d976339a75f1" "examples/controller/system.yaml=2a91f71f1de638aa1ffaa18f0f76fc3ccde44d2560aef98a9a48120775773af3" - "soc/st/stm32f4/stm32f4.yaml=3db4a0a65c9624d865d4ed7fc6354bf95054d0c465b76a2091f06aeac3d7375f" - "soc/st/stm32f4/stm32f446.yaml=0d5cc7f5fce4c51be71678987720c85c6e76e05473ff8a78ea5035394316c055" + "soc/st/stm32f4/stm32f4.yaml=796886c294250aa81151a620d80d0e43b5ee8e1bf53a07d1d7e2c62e95214dbd" + "soc/st/stm32f4/stm32f446.yaml=f0c9a37f6017c87d0efe215a3561f65494ba52383f2d0c10419b0ab5035f77f2" "soc/st/stm32f4/stm32f446re.yaml=b9a88d0a94aa17ee83317a3a56f7c194ec1b3107dfb3e82e453122dc1c48f6d4" ) diff --git a/examples/controller/generated/.base/nucleo_f446re/config/board.conf b/examples/controller/src/config/.base/nucleo_f446re/build/board.conf similarity index 73% rename from examples/controller/generated/.base/nucleo_f446re/config/board.conf rename to examples/controller/src/config/.base/nucleo_f446re/build/board.conf index 8fdfcf26..9c5e7ddb 100644 --- a/examples/controller/generated/.base/nucleo_f446re/config/board.conf +++ b/examples/controller/src/config/.base/nucleo_f446re/build/board.conf @@ -4,22 +4,24 @@ # Licensed under the Apache License, Version 2.0; see the LICENSE file at the repository root. # # Generated by emb-hwgen 0.1.0, schema v0. Do not edit: change the -# description and run hw/gen/emb-hwgen.py generate --system examples/controller/system.yaml (HW-003). +# description and run +# hw/gen/emb-hwgen.py generate --system examples/controller/system.yaml +# (HW-003). # Inputs (SHA-256): # arch/cortex_m/arch.yaml # c5c8e451c09717dee1713d07f8311b6d507e3b4c66c42d93e0ce11da6ec76d6d # boards/st/nucleo_f446re/board.yaml -# d756f3a7f19dc7da82ee3afc168dc54946312c5a9990720953c0fedcdece54ea +# 551c524379751d359bdd87501269d6cab33edf84d212d2f6632ffe9567ec71d0 # drivers/bindings.yaml -# d3c336ac05548e0addd1faac18f3dff70576d8069f11d89e6a761cf5c6132b49 +# c06d1a914adb21d0e314c79b3611ac6859eefeac1957d6914cccfc5531ad6ede # examples/controller/controller.conf # f7354e5137f5ea50fbd1d5829ff4f5eb88a044100d871d6a8fd7d976339a75f1 # examples/controller/system.yaml # 2a91f71f1de638aa1ffaa18f0f76fc3ccde44d2560aef98a9a48120775773af3 # soc/st/stm32f4/stm32f4.yaml -# 3db4a0a65c9624d865d4ed7fc6354bf95054d0c465b76a2091f06aeac3d7375f +# 796886c294250aa81151a620d80d0e43b5ee8e1bf53a07d1d7e2c62e95214dbd # soc/st/stm32f4/stm32f446.yaml -# 0d5cc7f5fce4c51be71678987720c85c6e76e05473ff8a78ea5035394316c055 +# f0c9a37f6017c87d0efe215a3561f65494ba52383f2d0c10419b0ab5035f77f2 # soc/st/stm32f4/stm32f446re.yaml # b9a88d0a94aa17ee83317a3a56f7c194ec1b3107dfb3e82e453122dc1c48f6d4 # Board defaults for nucleo_f446re. Applied before the profile fragment. diff --git a/examples/controller/src/config/.base/nucleo_f446re/configuration.h b/examples/controller/src/config/.base/nucleo_f446re/configuration.h new file mode 100644 index 00000000..e03b316a --- /dev/null +++ b/examples/controller/src/config/.base/nucleo_f446re/configuration.h @@ -0,0 +1,108 @@ +/* SPDX-License-Identifier: Apache-2.0 */ +/* + * This file is part of EmbLinkRTOS, a deterministic real-time kernel for microcontrollers. + * Licensed under the Apache License, Version 2.0; see the LICENSE file at the repository root. + */ + +/******************************************************************************* + System Configuration Header + + File Name: + configuration.h + + Summary: + The build-time configuration of controller on the nucleo_f446re. + + Description: + The system's settings as macros: the board and its clock, the devices' + settings, each task's and thread's priority and stack, the tasks' periods, + queues and timeouts, and the application's interrupts. The kernel's own + options are 's CONFIG_EMB_*, and the board's hardware + 's EMB_HW_*. + + Generated by emb-hwgen 0.1.0, schema v0, from the system description and the + nucleo_f446re's. Yours to edit: regenerating merges its changes with yours + (A126): + hw/gen/emb-hwgen.py generate --system examples/controller/system.yaml + + Inputs (SHA-256): + arch/cortex_m/arch.yaml + c5c8e451c09717dee1713d07f8311b6d507e3b4c66c42d93e0ce11da6ec76d6d + boards/st/nucleo_f446re/board.yaml + 551c524379751d359bdd87501269d6cab33edf84d212d2f6632ffe9567ec71d0 + drivers/bindings.yaml + c06d1a914adb21d0e314c79b3611ac6859eefeac1957d6914cccfc5531ad6ede + examples/controller/controller.conf + f7354e5137f5ea50fbd1d5829ff4f5eb88a044100d871d6a8fd7d976339a75f1 + examples/controller/system.yaml + 2a91f71f1de638aa1ffaa18f0f76fc3ccde44d2560aef98a9a48120775773af3 + soc/st/stm32f4/stm32f4.yaml + 796886c294250aa81151a620d80d0e43b5ee8e1bf53a07d1d7e2c62e95214dbd + soc/st/stm32f4/stm32f446.yaml + f0c9a37f6017c87d0efe215a3561f65494ba52383f2d0c10419b0ab5035f77f2 + soc/st/stm32f4/stm32f446re.yaml + b9a88d0a94aa17ee83317a3a56f7c194ec1b3107dfb3e82e453122dc1c48f6d4 + *******************************************************************************/ + +#ifndef CONFIGURATION_H +#define CONFIGURATION_H + +// ***************************************************************************** +// ***************************************************************************** +// Section: Included Files +// ***************************************************************************** +// ***************************************************************************** + +#include + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +// ***************************************************************************** +// ***************************************************************************** +// Section: System Configuration +// ***************************************************************************** +// ***************************************************************************** + +#define SYS_CPU_CLOCK_HZ 180000000u +#define SYS_TICK_NS CONFIG_EMB_TICK_NS +#define SYS_PRIORITY_COUNT CONFIG_EMB_PRIORITY_COUNT + +// ***************************************************************************** +// ***************************************************************************** +// Section: Driver Configuration +// ***************************************************************************** +// ***************************************************************************** + +#define DRV_USART2_BAUD 115200u +#define DRV_UART4_BAUD 115200u + +// ***************************************************************************** +// ***************************************************************************** +// Section: Application Configuration +// ***************************************************************************** +// ***************************************************************************** + +/* control_thread: a thread */ +#define CONTROL_THREAD_PRIORITY 6u +#define CONTROL_THREAD_STACK_SIZE 1024u + +/* command_thread: a thread */ +#define COMMAND_THREAD_PRIORITY 4u +#define COMMAND_THREAD_STACK_SIZE 1024u + +/* telemetry_thread: a thread */ +#define TELEMETRY_THREAD_PRIORITY 2u +#define TELEMETRY_THREAD_STACK_SIZE 1024u + +#ifdef __cplusplus +} +#endif + +#endif /* CONFIGURATION_H */ +/******************************************************************************* + End of File +*/ diff --git a/examples/controller/src/config/.base/nucleo_f446re/definitions.h b/examples/controller/src/config/.base/nucleo_f446re/definitions.h new file mode 100644 index 00000000..9bee12bf --- /dev/null +++ b/examples/controller/src/config/.base/nucleo_f446re/definitions.h @@ -0,0 +1,180 @@ +/* SPDX-License-Identifier: Apache-2.0 */ +/* + * This file is part of EmbLinkRTOS, a deterministic real-time kernel for microcontrollers. + * Licensed under the Apache License, Version 2.0; see the LICENSE file at the repository root. + */ + +/******************************************************************************* + System Definitions + + File Name: + definitions.h + + Summary: + controller's system definitions on the nucleo_f446re. + + Description: + The one header the application includes: the kernel's API, the board's + devices, the system's configuration and handles, every task's header, and + the system's two functions, SYS_Initialize() and SYS_Tasks(). + + Generated by emb-hwgen 0.1.0, schema v0, from the system description and the + nucleo_f446re's. Yours to edit: regenerating merges its changes with yours + (A126): + hw/gen/emb-hwgen.py generate --system examples/controller/system.yaml + + Inputs (SHA-256): + arch/cortex_m/arch.yaml + c5c8e451c09717dee1713d07f8311b6d507e3b4c66c42d93e0ce11da6ec76d6d + boards/st/nucleo_f446re/board.yaml + 551c524379751d359bdd87501269d6cab33edf84d212d2f6632ffe9567ec71d0 + drivers/bindings.yaml + c06d1a914adb21d0e314c79b3611ac6859eefeac1957d6914cccfc5531ad6ede + examples/controller/controller.conf + f7354e5137f5ea50fbd1d5829ff4f5eb88a044100d871d6a8fd7d976339a75f1 + examples/controller/system.yaml + 2a91f71f1de638aa1ffaa18f0f76fc3ccde44d2560aef98a9a48120775773af3 + soc/st/stm32f4/stm32f4.yaml + 796886c294250aa81151a620d80d0e43b5ee8e1bf53a07d1d7e2c62e95214dbd + soc/st/stm32f4/stm32f446.yaml + f0c9a37f6017c87d0efe215a3561f65494ba52383f2d0c10419b0ab5035f77f2 + soc/st/stm32f4/stm32f446re.yaml + b9a88d0a94aa17ee83317a3a56f7c194ec1b3107dfb3e82e453122dc1c48f6d4 + *******************************************************************************/ + +#ifndef DEFINITIONS_H +#define DEFINITIONS_H + +// ***************************************************************************** +// ***************************************************************************** +// Section: Included Files +// ***************************************************************************** +// ***************************************************************************** + +#include "configuration.h" +#include "controller.h" + +#include + +#include +#include +#include + +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/* Device Information */ +#define DEVICE_NAME "STM32F446RE" +#define DEVICE_ARCH "cortex-m4f" +#define DEVICE_FAMILY "stm32f4" +#define BOARD_NAME "nucleo_f446re" + +/* CPU clock frequency */ +#define CPU_CLOCK_FREQUENCY 180000000u + +// ***************************************************************************** +// ***************************************************************************** +// Section: System Functions +// ***************************************************************************** +// ***************************************************************************** + +/******************************************************************************* + Function: + void SYS_Initialize ( void *data ) + + Summary: + Initializes the board, the kernel and every task. + + Description: + This function initializes the board (its clocks, pins and console), then the + kernel (its objects and the EARLY devices), then the application's + interrupts, then each task, in its initial state. The KERNEL devices start + with the kernel, in SYS_Tasks(). + + Precondition: + None. + + Parameters: + data - Unused; NULL. + + Returns: + None. + + Example: + + SYS_Initialize(NULL); + while (true) { + SYS_Tasks(); + } + + + Remarks: + This function is called once, after reset, from main(). +*/ +void SYS_Initialize(void *data); + +/******************************************************************************* + Function: + void SYS_Tasks ( void ) + + Summary: + Starts the kernel: the threads and the tasks run from here. + + Description: + This function starts the KERNEL devices, then the scheduler, which runs the + system's threads and each task's thread. It does not return. + + Precondition: + SYS_Initialize() has run. + + Parameters: + None. + + Returns: + It does not return. + + Example: + + SYS_Initialize(NULL); + while (true) { + SYS_Tasks(); + } + + + Remarks: + Harmony calls its SYS_Tasks() in a loop; this one runs the scheduler and + never comes back. +*/ +void SYS_Tasks(void); + +// ***************************************************************************** +// ***************************************************************************** +// Section: System Objects +// ***************************************************************************** +// ***************************************************************************** + +/* threads: their entries, which the application defines, and their handles */ +void command(void *arg); +void control(void *arg); +void telemetry(void *arg); +extern emb_thread_t control_thread; +extern emb_thread_t command_thread; +extern emb_thread_t telemetry_thread; + +/* objects */ +extern emb_msgq_t samples; +extern emb_msgq_t rx_bytes; +extern emb_mutex_t console; + +#ifdef __cplusplus +} +#endif + +#endif /* DEFINITIONS_H */ +/******************************************************************************* + End of File +*/ diff --git a/examples/controller/generated/nucleo_f446re/docs/board.md b/examples/controller/src/config/.base/nucleo_f446re/docs/board.md similarity index 79% rename from examples/controller/generated/nucleo_f446re/docs/board.md rename to examples/controller/src/config/.base/nucleo_f446re/docs/board.md index e10ce1cd..10b4c634 100644 --- a/examples/controller/generated/nucleo_f446re/docs/board.md +++ b/examples/controller/src/config/.base/nucleo_f446re/docs/board.md @@ -35,8 +35,12 @@ The STM32F446RE at 180 MHz from the PLL, its input the ST-LINK's 8 MHz MCO on PH | PA1 | `pins.uart4.rx` | af8 (uart4_rx) | | PA2 | `pins.usart2.tx` | af7 (usart2_tx) | | PA3 | `pins.usart2.rx` | af7 (usart2_rx) | +| PA4 | `pins.adc1.in4` | analog | | PA5 | `leds.user` | output | +| PA6 | `pins.tim3.ch1` | af2 (tim3_ch1) | +| PB0 | `pins.adc1.in8` | analog | | PB3 | `pins.i2c2.sda` | af4 (i2c2_sda) | +| PB6 | `pins.tim4.ch1` | af2 (tim4_ch1) | | PB8 | `pins.i2c1.scl` | af4 (i2c1_scl) | | PB9 | `pins.i2c1.sda` | af4 (i2c1_sda) | | PB10 | `pins.i2c2.scl` | af4 (i2c2_scl) | @@ -58,6 +62,7 @@ In initialization order (SPEC-016 §4). | rtc | `st,stm32f4-rtc` | rtc | EARLY | - | | flash | `st,stm32f4-flash (flash_if)` | flash | EARLY | - | | dma1 | `st,stm32-dma` | dma | EARLY | rcc | +| dma2 | `st,stm32-dma` | dma | EARLY | rcc | | gpiob | `st,stm32-gpio` | gpio | EARLY | rcc | | gpioc | `st,stm32-gpio` | gpio | EARLY | rcc | | usart2 | `st,stm32-usart` | uart | EARLY | dma1, rcc | @@ -65,6 +70,11 @@ In initialization order (SPEC-016 §4). | spi2 | `st,stm32-spi` | spi | KERNEL | dma1, rcc | | i2c1 | `st,stm32-i2c` | i2c | KERNEL | rcc | | i2c2 | `st,stm32-i2c` | i2c | KERNEL | rcc | +| tim5 | `st,stm32-tim` | counter | KERNEL | rcc | +| tim9 | `st,stm32-tim` | counter | KERNEL | rcc | +| tim3 | `st,stm32-tim` | pwm | KERNEL | rcc | +| tim4 | `st,stm32-tim` | pwm | KERNEL | rcc | +| adc1 | `st,stm32f4-adc` | adc | KERNEL | dma2, rcc | ## Interrupt lines @@ -81,7 +91,10 @@ In initialization order (SPEC-016 §4). | 16 | dma1.s5 | | 17 | dma1.s6 | | 18 | adc1.global | +| 24 | tim9.global | | 28 | tim2.global | +| 29 | tim3.global | +| 30 | tim4.global | | 31 | i2c1.ev | | 32 | i2c1.er | | 33 | i2c2.ev | @@ -92,6 +105,7 @@ In initialization order (SPEC-016 §4). | 39 | usart3.global | | 41 | rtc.alarm | | 47 | dma1.s7 | +| 50 | tim5.global | | 52 | uart4.global | | 53 | uart5.global | | 56 | dma2.s0 | @@ -115,10 +129,10 @@ Generated by emb-hwgen 0.1.0, schema v0, from: | Input | SHA-256 | |---|---| | `arch/cortex_m/arch.yaml` | `c5c8e451c09717dee1713d07f8311b6d507e3b4c66c42d93e0ce11da6ec76d6d` | -| `boards/st/nucleo_f446re/board.yaml` | `d756f3a7f19dc7da82ee3afc168dc54946312c5a9990720953c0fedcdece54ea` | -| `drivers/bindings.yaml` | `d3c336ac05548e0addd1faac18f3dff70576d8069f11d89e6a761cf5c6132b49` | +| `boards/st/nucleo_f446re/board.yaml` | `551c524379751d359bdd87501269d6cab33edf84d212d2f6632ffe9567ec71d0` | +| `drivers/bindings.yaml` | `c06d1a914adb21d0e314c79b3611ac6859eefeac1957d6914cccfc5531ad6ede` | | `examples/controller/controller.conf` | `f7354e5137f5ea50fbd1d5829ff4f5eb88a044100d871d6a8fd7d976339a75f1` | | `examples/controller/system.yaml` | `2a91f71f1de638aa1ffaa18f0f76fc3ccde44d2560aef98a9a48120775773af3` | -| `soc/st/stm32f4/stm32f4.yaml` | `3db4a0a65c9624d865d4ed7fc6354bf95054d0c465b76a2091f06aeac3d7375f` | -| `soc/st/stm32f4/stm32f446.yaml` | `0d5cc7f5fce4c51be71678987720c85c6e76e05473ff8a78ea5035394316c055` | +| `soc/st/stm32f4/stm32f4.yaml` | `796886c294250aa81151a620d80d0e43b5ee8e1bf53a07d1d7e2c62e95214dbd` | +| `soc/st/stm32f4/stm32f446.yaml` | `f0c9a37f6017c87d0efe215a3561f65494ba52383f2d0c10419b0ab5035f77f2` | | `soc/st/stm32f4/stm32f446re.yaml` | `b9a88d0a94aa17ee83317a3a56f7c194ec1b3107dfb3e82e453122dc1c48f6d4` | diff --git a/examples/controller/generated/.base/nucleo_f446re/docs/build_report.md b/examples/controller/src/config/.base/nucleo_f446re/docs/build_report.md similarity index 72% rename from examples/controller/generated/.base/nucleo_f446re/docs/build_report.md rename to examples/controller/src/config/.base/nucleo_f446re/docs/build_report.md index 7dcfaf8d..9aafeb41 100644 --- a/examples/controller/generated/.base/nucleo_f446re/docs/build_report.md +++ b/examples/controller/src/config/.base/nucleo_f446re/docs/build_report.md @@ -31,10 +31,10 @@ Generated by emb-hwgen 0.1.0, schema v0, from: | Input | SHA-256 | |---|---| | `arch/cortex_m/arch.yaml` | `c5c8e451c09717dee1713d07f8311b6d507e3b4c66c42d93e0ce11da6ec76d6d` | -| `boards/st/nucleo_f446re/board.yaml` | `d756f3a7f19dc7da82ee3afc168dc54946312c5a9990720953c0fedcdece54ea` | -| `drivers/bindings.yaml` | `d3c336ac05548e0addd1faac18f3dff70576d8069f11d89e6a761cf5c6132b49` | +| `boards/st/nucleo_f446re/board.yaml` | `551c524379751d359bdd87501269d6cab33edf84d212d2f6632ffe9567ec71d0` | +| `drivers/bindings.yaml` | `c06d1a914adb21d0e314c79b3611ac6859eefeac1957d6914cccfc5531ad6ede` | | `examples/controller/controller.conf` | `f7354e5137f5ea50fbd1d5829ff4f5eb88a044100d871d6a8fd7d976339a75f1` | | `examples/controller/system.yaml` | `2a91f71f1de638aa1ffaa18f0f76fc3ccde44d2560aef98a9a48120775773af3` | -| `soc/st/stm32f4/stm32f4.yaml` | `3db4a0a65c9624d865d4ed7fc6354bf95054d0c465b76a2091f06aeac3d7375f` | -| `soc/st/stm32f4/stm32f446.yaml` | `0d5cc7f5fce4c51be71678987720c85c6e76e05473ff8a78ea5035394316c055` | +| `soc/st/stm32f4/stm32f4.yaml` | `796886c294250aa81151a620d80d0e43b5ee8e1bf53a07d1d7e2c62e95214dbd` | +| `soc/st/stm32f4/stm32f446.yaml` | `f0c9a37f6017c87d0efe215a3561f65494ba52383f2d0c10419b0ab5035f77f2` | | `soc/st/stm32f4/stm32f446re.yaml` | `b9a88d0a94aa17ee83317a3a56f7c194ec1b3107dfb3e82e453122dc1c48f6d4` | diff --git a/examples/controller/generated/.base/nucleo_f446re/docs/hw.json b/examples/controller/src/config/.base/nucleo_f446re/docs/hw.json similarity index 77% rename from examples/controller/generated/.base/nucleo_f446re/docs/hw.json rename to examples/controller/src/config/.base/nucleo_f446re/docs/hw.json index fab062e8..5276124d 100644 --- a/examples/controller/generated/.base/nucleo_f446re/docs/hw.json +++ b/examples/controller/src/config/.base/nucleo_f446re/docs/hw.json @@ -57,6 +57,10 @@ "doc": "DMA1: SPI2's transfers, and the console's writes", "name": "dma1" }, + { + "doc": "DMA2: ADC1's samples", + "name": "dma2" + }, { "doc": "SPI2's chip select, PB12", "name": "gpiob" @@ -96,6 +100,36 @@ "baud": 115200, "doc": "a spare UART; the HIL suite's loopback wires A0 (PA0, TX) to A1 (PA1, RX)", "name": "uart4" + }, + { + "class": "counter", + "doc": "TIM5, 32 bits at 1 MHz: the counter class's (A129); TIM2 stays the controller's ADC trigger", + "name": "tim5" + }, + { + "class": "counter", + "doc": "TIM9, 16 bits at 1 MHz: it wraps every 65.5 ms, so its tests widen the count on the board", + "name": "tim9" + }, + { + "class": "pwm", + "doc": "TIM3, PWM out on channel 1, D12 (PA6); the HIL suite wires it to D10", + "name": "tim3" + }, + { + "class": "pwm", + "doc": "TIM4, PWM capture on channel 1, D10 (PB6)", + "name": "tim4" + }, + { + "cal": "factory_cal", + "common": "adc_common", + "dma": [ + "rx" + ], + "doc": "ADC1, paced by TIM2 (the controller's trigger, which it drives by hand), A2 (PA4, input 4) and A3 (PB0, input 8); the HIL suite wires A2 to 3V3 and A3 to GND", + "name": "adc1", + "trigger": "tim2" } ], "doc": "The STM32F446RE at 180 MHz from the PLL, its input the ST-LINK's 8 MHz MCO on PH0 in HSE bypass (solder bridges SB16 and SB50 as shipped). The console is USART2, which the ST-LINK carries as its virtual COM port.", @@ -132,6 +166,10 @@ } }, "pins": { + "adc1": { + "in4": "PA4", + "in8": "PB0" + }, "i2c1": { "scl": "PB8.af4", "sda": "PB9.af4" @@ -145,6 +183,12 @@ "mosi": "PB15.af5", "sck": "PB13.af5" }, + "tim3": { + "ch1": "PA6.af2" + }, + "tim4": { + "ch1": "PB6.af2" + }, "uart4": { "rx": "PA1.af8", "tx": "PA0.af8" @@ -186,6 +230,35 @@ ] ], "peer": "i2c2" + }, + { + "channels": [ + 0, + 0 + ], + "device": "tim3", + "peer": "tim4", + "ports": [ + "D12", + "D10" + ] + }, + { + "channels": [ + 4, + 8 + ], + "device": "adc1", + "nets": [ + [ + "A2", + "3V3" + ], + [ + "A3", + "GND" + ] + ] } ], "resets_in": [ @@ -208,8 +281,14 @@ "apb1": 45000000, "apb2": 90000000 }, + "bus_timer_hz": { + "ahb1": 180000000, + "apb1": 90000000, + "apb2": 180000000 + }, "bypass": true, "cpu_hz": 180000000, + "fixed_plls": {}, "flash_wait_states": 5, "hclk_hz": 180000000, "pclk1_div": 4, @@ -357,6 +436,30 @@ "name": "dma1", "peripheral": "dma1" }, + { + "class": "dma", + "compatible": "st,stm32-dma", + "deps": [ + "rcc" + ], + "fields": { + "base": 1073898496, + "clken_bit": 22, + "clken_offset": 48, + "irq0": 56, + "irq1": 57, + "irq2": 58, + "irq3": 59, + "irq4": 60, + "irq5": 68, + "irq6": 69, + "irq7": 70, + "memory": true + }, + "level": "early", + "name": "dma2", + "peripheral": "dma2" + }, { "class": "gpio", "compatible": "st,stm32-gpio", @@ -519,6 +622,119 @@ "level": "kernel", "name": "i2c2", "peripheral": "i2c2" + }, + { + "class": "counter", + "compatible": "st,stm32-tim", + "deps": [ + "rcc" + ], + "fields": { + "base": 1073744896, + "bits": 32, + "channels": 4, + "clken_bit": 3, + "clken_offset": 64, + "clock_hz": 90000000, + "irq": 50, + "rate_hz": 1000000 + }, + "level": "kernel", + "name": "tim5", + "peripheral": "tim5" + }, + { + "class": "counter", + "compatible": "st,stm32-tim", + "deps": [ + "rcc" + ], + "fields": { + "base": 1073823744, + "bits": 16, + "channels": 2, + "clken_bit": 16, + "clken_offset": 68, + "clock_hz": 180000000, + "irq": 24, + "rate_hz": 1000000 + }, + "level": "kernel", + "name": "tim9", + "peripheral": "tim9" + }, + { + "class": "pwm", + "compatible": "st,stm32-tim", + "deps": [ + "rcc" + ], + "fields": { + "base": 1073742848, + "bits": 16, + "channels": 4, + "clken_bit": 1, + "clken_offset": 64, + "clock_hz": 90000000, + "irq": 29 + }, + "level": "kernel", + "name": "tim3", + "peripheral": "tim3" + }, + { + "class": "pwm", + "compatible": "st,stm32-tim", + "deps": [ + "rcc" + ], + "fields": { + "base": 1073743872, + "bits": 16, + "channels": 4, + "clken_bit": 2, + "clken_offset": 64, + "clock_hz": 90000000, + "irq": 30 + }, + "level": "kernel", + "name": "tim4", + "peripheral": "tim4" + }, + { + "class": "adc", + "compatible": "st,stm32f4-adc", + "deps": [ + "dma2", + "rcc" + ], + "fields": { + "base": 1073815552, + "bits": 12, + "calibration": 536836650, + "clken_bit": 8, + "clken_offset": 68, + "clock_hz": 90000000, + "common": 1073816320, + "dma_rx": { + "dma": "dma2", + "request": 0, + "stream": 0 + }, + "inputs": 16, + "irq": 18, + "temperature": 18, + "trigger": 1073741824, + "trigger_clken_bit": 0, + "trigger_clken_offset": 64, + "trigger_hz": 90000000, + "trigger_select": 6, + "vref_mv": 3300, + "vrefint": 17 + }, + "level": "kernel", + "name": "adc1", + "peripheral": "adc1" } ], "kconfig": { @@ -608,6 +824,15 @@ "port": "A", "signal": "usart2_rx" }, + { + "gpio": "gpioa", + "mode": "analog", + "number": 4, + "owner": "pins.adc1.in4", + "pin": "PA4", + "port": "A", + "signal": "adc1_in4" + }, { "gpio": "gpioa", "mode": "output", @@ -616,6 +841,25 @@ "pin": "PA5", "port": "A" }, + { + "af": 2, + "gpio": "gpioa", + "mode": "af", + "number": 6, + "owner": "pins.tim3.ch1", + "pin": "PA6", + "port": "A", + "signal": "tim3_ch1" + }, + { + "gpio": "gpiob", + "mode": "analog", + "number": 0, + "owner": "pins.adc1.in8", + "pin": "PB0", + "port": "B", + "signal": "adc1_in8" + }, { "af": 4, "gpio": "gpiob", @@ -626,6 +870,16 @@ "port": "B", "signal": "i2c2_sda" }, + { + "af": 2, + "gpio": "gpiob", + "mode": "af", + "number": 6, + "owner": "pins.tim4.ch1", + "pin": "PB6", + "port": "B", + "signal": "tim4_ch1" + }, { "af": 4, "gpio": "gpiob", @@ -726,11 +980,11 @@ }, { "path": "boards/st/nucleo_f446re/board.yaml", - "sha256": "d756f3a7f19dc7da82ee3afc168dc54946312c5a9990720953c0fedcdece54ea" + "sha256": "551c524379751d359bdd87501269d6cab33edf84d212d2f6632ffe9567ec71d0" }, { "path": "drivers/bindings.yaml", - "sha256": "d3c336ac05548e0addd1faac18f3dff70576d8069f11d89e6a761cf5c6132b49" + "sha256": "c06d1a914adb21d0e314c79b3611ac6859eefeac1957d6914cccfc5531ad6ede" }, { "path": "examples/controller/controller.conf", @@ -742,11 +996,11 @@ }, { "path": "soc/st/stm32f4/stm32f4.yaml", - "sha256": "3db4a0a65c9624d865d4ed7fc6354bf95054d0c465b76a2091f06aeac3d7375f" + "sha256": "796886c294250aa81151a620d80d0e43b5ee8e1bf53a07d1d7e2c62e95214dbd" }, { "path": "soc/st/stm32f4/stm32f446.yaml", - "sha256": "0d5cc7f5fce4c51be71678987720c85c6e76e05473ff8a78ea5035394316c055" + "sha256": "f0c9a37f6017c87d0efe215a3561f65494ba52383f2d0c10419b0ab5035f77f2" }, { "path": "soc/st/stm32f4/stm32f446re.yaml", @@ -757,19 +1011,49 @@ "soc": { "alternate_functions": { "PA0": { - "af8": "uart4_tx" + "af1": "tim2_ch1", + "af2": "tim5_ch1", + "af8": "uart4_tx", + "analog": "adc1_in0" }, "PA1": { - "af8": "uart4_rx" + "af1": "tim2_ch2", + "af2": "tim5_ch2", + "af8": "uart4_rx", + "analog": "adc1_in1" }, "PA10": { "af7": "usart1_rx" }, + "PA15": { + "af1": "tim2_ch1" + }, "PA2": { - "af7": "usart2_tx" + "af1": "tim2_ch3", + "af2": "tim5_ch3", + "af7": "usart2_tx", + "analog": "adc1_in2" }, "PA3": { - "af7": "usart2_rx" + "af1": "tim2_ch4", + "af2": "tim5_ch4", + "af7": "usart2_rx", + "analog": "adc1_in3" + }, + "PA4": { + "analog": "adc1_in4" + }, + "PA5": { + "af1": "tim2_ch1", + "analog": "adc1_in5" + }, + "PA6": { + "af2": "tim3_ch1", + "analog": "adc1_in6" + }, + "PA7": { + "af2": "tim3_ch2", + "analog": "adc1_in7" }, "PA8": { "af4": "i2c3_scl" @@ -777,7 +1061,16 @@ "PA9": { "af7": "usart1_tx" }, + "PB0": { + "af2": "tim3_ch3", + "analog": "adc1_in8" + }, + "PB1": { + "af2": "tim3_ch4", + "analog": "adc1_in9" + }, "PB10": { + "af1": "tim2_ch3", "af4": "i2c2_scl", "af7": "usart3_tx" }, @@ -790,26 +1083,46 @@ "PB15": { "af5": "spi2_mosi" }, + "PB2": { + "af1": "tim2_ch4" + }, "PB3": { + "af1": "tim2_ch2", "af4": "i2c2_sda" }, "PB4": { + "af2": "tim3_ch1", "af4": "i2c3_sda" }, + "PB5": { + "af2": "tim3_ch2" + }, "PB6": { + "af2": "tim4_ch1", "af4": "i2c1_scl", "af7": "usart1_tx" }, "PB7": { + "af2": "tim4_ch2", "af4": "i2c1_sda", "af7": "usart1_rx" }, "PB8": { + "af1": "tim2_ch1", + "af2": "tim4_ch3", "af4": "i2c1_scl" }, "PB9": { + "af1": "tim2_ch2", + "af2": "tim4_ch4", "af4": "i2c1_sda" }, + "PC0": { + "analog": "adc1_in10" + }, + "PC1": { + "analog": "adc1_in11" + }, "PC10": { "af7": "usart3_tx", "af8": "uart4_tx" @@ -822,16 +1135,32 @@ "af4": "i2c2_sda", "af8": "uart5_tx" }, + "PC2": { + "analog": "adc1_in12" + }, + "PC3": { + "analog": "adc1_in13" + }, + "PC4": { + "analog": "adc1_in14" + }, "PC5": { - "af7": "usart3_rx" + "af7": "usart3_rx", + "analog": "adc1_in15" }, "PC6": { + "af2": "tim3_ch1", "af8": "usart6_tx" }, "PC7": { + "af2": "tim3_ch2", "af8": "usart6_rx" }, + "PC8": { + "af2": "tim3_ch3" + }, "PC9": { + "af2": "tim3_ch4", "af4": "i2c3_sda" }, "PD2": { @@ -960,6 +1289,7 @@ "name": "lse" } ], + "timers_double_when_divided": true, "voltage_scales": [ { "max_hz": 120000000, @@ -1101,12 +1431,24 @@ "part": "STM32F446RE", "peripherals": [ { + "adc": { + "bits": 12, + "inputs": 16, + "temperature": 18, + "vrefint": 17 + }, "base": 1073815552, "clock": { "bit": 8, "bus": "apb2" }, "compatible": "st,stm32f4-adc", + "dma_requests": { + "rx": [ + "dma2.s0c0", + "dma2.s4c0" + ] + }, "irqs": [ { "name": "global", @@ -1281,12 +1623,14 @@ "size": 1024 }, { + "adc_trigger": 6, "base": 1073741824, "clock": { "bit": 0, "bus": "apb1" }, "compatible": "st,stm32-tim", + "counter_bits": 32, "irqs": [ { "name": "global", @@ -1296,6 +1640,76 @@ "name": "tim2", "size": 1024 }, + { + "adc_trigger": 8, + "base": 1073742848, + "clock": { + "bit": 1, + "bus": "apb1" + }, + "compatible": "st,stm32-tim", + "counter_bits": 16, + "irqs": [ + { + "name": "global", + "number": 29 + } + ], + "name": "tim3", + "size": 1024 + }, + { + "base": 1073743872, + "clock": { + "bit": 2, + "bus": "apb1" + }, + "compatible": "st,stm32-tim", + "counter_bits": 16, + "irqs": [ + { + "name": "global", + "number": 30 + } + ], + "name": "tim4", + "size": 1024 + }, + { + "base": 1073744896, + "clock": { + "bit": 3, + "bus": "apb1" + }, + "compatible": "st,stm32-tim", + "counter_bits": 32, + "irqs": [ + { + "name": "global", + "number": 50 + } + ], + "name": "tim5", + "size": 1024 + }, + { + "base": 1073823744, + "clock": { + "bit": 16, + "bus": "apb2" + }, + "compatible": "st,stm32-tim", + "counter_bits": 16, + "irqs": [ + { + "name": "global", + "number": 24 + } + ], + "name": "tim9", + "size": 1024, + "timer_channels": 2 + }, { "base": 1073897472, "clock": { diff --git a/examples/controller/generated/.base/nucleo_f446re/docs/system.json b/examples/controller/src/config/.base/nucleo_f446re/docs/system.json similarity index 88% rename from examples/controller/generated/.base/nucleo_f446re/docs/system.json rename to examples/controller/src/config/.base/nucleo_f446re/docs/system.json index 49f25147..7e15d7f8 100644 --- a/examples/controller/generated/.base/nucleo_f446re/docs/system.json +++ b/examples/controller/src/config/.base/nucleo_f446re/docs/system.json @@ -29,11 +29,11 @@ }, { "path": "boards/st/nucleo_f446re/board.yaml", - "sha256": "d756f3a7f19dc7da82ee3afc168dc54946312c5a9990720953c0fedcdece54ea" + "sha256": "551c524379751d359bdd87501269d6cab33edf84d212d2f6632ffe9567ec71d0" }, { "path": "drivers/bindings.yaml", - "sha256": "d3c336ac05548e0addd1faac18f3dff70576d8069f11d89e6a761cf5c6132b49" + "sha256": "c06d1a914adb21d0e314c79b3611ac6859eefeac1957d6914cccfc5531ad6ede" }, { "path": "examples/controller/controller.conf", @@ -45,17 +45,18 @@ }, { "path": "soc/st/stm32f4/stm32f4.yaml", - "sha256": "3db4a0a65c9624d865d4ed7fc6354bf95054d0c465b76a2091f06aeac3d7375f" + "sha256": "796886c294250aa81151a620d80d0e43b5ee8e1bf53a07d1d7e2c62e95214dbd" }, { "path": "soc/st/stm32f4/stm32f446.yaml", - "sha256": "0d5cc7f5fce4c51be71678987720c85c6e76e05473ff8a78ea5035394316c055" + "sha256": "f0c9a37f6017c87d0efe215a3561f65494ba52383f2d0c10419b0ab5035f77f2" }, { "path": "soc/st/stm32f4/stm32f446re.yaml", "sha256": "b9a88d0a94aa17ee83317a3a56f7c194ec1b3107dfb3e82e453122dc1c48f6d4" } ], + "interrupts": [], "name": "controller", "objects": [ { diff --git a/examples/controller/generated/nucleo_f446re/docs/system.md b/examples/controller/src/config/.base/nucleo_f446re/docs/system.md similarity index 67% rename from examples/controller/generated/nucleo_f446re/docs/system.md rename to examples/controller/src/config/.base/nucleo_f446re/docs/system.md index a5e5dc33..0a683ded 100644 --- a/examples/controller/generated/nucleo_f446re/docs/system.md +++ b/examples/controller/src/config/.base/nucleo_f446re/docs/system.md @@ -1,6 +1,6 @@ # controller: the system on nucleo_f446re -Generated from `examples/controller/system.yaml` (SPEC-014 §5, A125). Profile base, 32 priorities, a minimum stack of 256 bytes. +Generated from `examples/controller/system.yaml` (SPEC-014 §5, A125, A130). Profile base, 32 priorities, a minimum stack of 256 bytes. ## Threads @@ -25,10 +25,10 @@ Generated by emb-hwgen 0.1.0, schema v0, from: | Input | SHA-256 | |---|---| | `arch/cortex_m/arch.yaml` | `c5c8e451c09717dee1713d07f8311b6d507e3b4c66c42d93e0ce11da6ec76d6d` | -| `boards/st/nucleo_f446re/board.yaml` | `d756f3a7f19dc7da82ee3afc168dc54946312c5a9990720953c0fedcdece54ea` | -| `drivers/bindings.yaml` | `d3c336ac05548e0addd1faac18f3dff70576d8069f11d89e6a761cf5c6132b49` | +| `boards/st/nucleo_f446re/board.yaml` | `551c524379751d359bdd87501269d6cab33edf84d212d2f6632ffe9567ec71d0` | +| `drivers/bindings.yaml` | `c06d1a914adb21d0e314c79b3611ac6859eefeac1957d6914cccfc5531ad6ede` | | `examples/controller/controller.conf` | `f7354e5137f5ea50fbd1d5829ff4f5eb88a044100d871d6a8fd7d976339a75f1` | | `examples/controller/system.yaml` | `2a91f71f1de638aa1ffaa18f0f76fc3ccde44d2560aef98a9a48120775773af3` | -| `soc/st/stm32f4/stm32f4.yaml` | `3db4a0a65c9624d865d4ed7fc6354bf95054d0c465b76a2091f06aeac3d7375f` | -| `soc/st/stm32f4/stm32f446.yaml` | `0d5cc7f5fce4c51be71678987720c85c6e76e05473ff8a78ea5035394316c055` | +| `soc/st/stm32f4/stm32f4.yaml` | `796886c294250aa81151a620d80d0e43b5ee8e1bf53a07d1d7e2c62e95214dbd` | +| `soc/st/stm32f4/stm32f446.yaml` | `f0c9a37f6017c87d0efe215a3561f65494ba52383f2d0c10419b0ab5035f77f2` | | `soc/st/stm32f4/stm32f446re.yaml` | `b9a88d0a94aa17ee83317a3a56f7c194ec1b3107dfb3e82e453122dc1c48f6d4` | diff --git a/examples/controller/src/config/.base/nucleo_f446re/initialization.c b/examples/controller/src/config/.base/nucleo_f446re/initialization.c new file mode 100644 index 00000000..55ad3ffb --- /dev/null +++ b/examples/controller/src/config/.base/nucleo_f446re/initialization.c @@ -0,0 +1,97 @@ +/* SPDX-License-Identifier: Apache-2.0 */ +/* + * This file is part of EmbLinkRTOS, a deterministic real-time kernel for microcontrollers. + * Licensed under the Apache License, Version 2.0; see the LICENSE file at the repository root. + */ + +/******************************************************************************* + System Initialization File + + File Name: + initialization.c + + Summary: + controller's initialization on the nucleo_f446re: SYS_Initialize(), and the + system's objects. + + Description: + The system's static definitions, which the kernel creates from its + initialization table when emb_kernel_init() runs (SPEC-001 §6.4), and + SYS_Initialize(), which brings up the board, the kernel, the application's + interrupts and the tasks. + + Generated by emb-hwgen 0.1.0, schema v0, from the system description and the + nucleo_f446re's. Yours to edit: regenerating merges its changes with yours + (A126): + hw/gen/emb-hwgen.py generate --system examples/controller/system.yaml + + Inputs (SHA-256): + arch/cortex_m/arch.yaml + c5c8e451c09717dee1713d07f8311b6d507e3b4c66c42d93e0ce11da6ec76d6d + boards/st/nucleo_f446re/board.yaml + 551c524379751d359bdd87501269d6cab33edf84d212d2f6632ffe9567ec71d0 + drivers/bindings.yaml + c06d1a914adb21d0e314c79b3611ac6859eefeac1957d6914cccfc5531ad6ede + examples/controller/controller.conf + f7354e5137f5ea50fbd1d5829ff4f5eb88a044100d871d6a8fd7d976339a75f1 + examples/controller/system.yaml + 2a91f71f1de638aa1ffaa18f0f76fc3ccde44d2560aef98a9a48120775773af3 + soc/st/stm32f4/stm32f4.yaml + 796886c294250aa81151a620d80d0e43b5ee8e1bf53a07d1d7e2c62e95214dbd + soc/st/stm32f4/stm32f446.yaml + f0c9a37f6017c87d0efe215a3561f65494ba52383f2d0c10419b0ab5035f77f2 + soc/st/stm32f4/stm32f446re.yaml + b9a88d0a94aa17ee83317a3a56f7c194ec1b3107dfb3e82e453122dc1c48f6d4 + *******************************************************************************/ + +// ***************************************************************************** +// ***************************************************************************** +// Section: Included Files +// ***************************************************************************** +// ***************************************************************************** + +#include "definitions.h" + +// ***************************************************************************** +// ***************************************************************************** +// Section: System Objects +// ***************************************************************************** +// ***************************************************************************** + +/* the kernel creates each when emb_kernel_init() runs (SPEC-001 §6.4) */ +EMB_THREAD_DEFINE(control_thread, control, NULL, CONTROL_THREAD_PRIORITY, CONTROL_THREAD_STACK_SIZE, + 0u); +EMB_THREAD_DEFINE(command_thread, command, NULL, COMMAND_THREAD_PRIORITY, COMMAND_THREAD_STACK_SIZE, + 0u); +EMB_THREAD_DEFINE(telemetry_thread, telemetry, NULL, TELEMETRY_THREAD_PRIORITY, + TELEMETRY_THREAD_STACK_SIZE, 0u); +EMB_MSGQ_DEFINE(samples, sizeof(sample_t), 8u, 0u); +EMB_MSGQ_DEFINE(rx_bytes, 1u, 64u, 0u); +EMB_MUTEX_DEFINE(console, EMB_MUTEX_INHERIT, 0u, 0u); + +// ***************************************************************************** +// ***************************************************************************** +// Section: System Initialization +// ***************************************************************************** +// ***************************************************************************** + +/******************************************************************************* + Function: + void SYS_Initialize ( void *data ) + + Remarks: + See prototype in definitions.h. + */ +void SYS_Initialize(void *data) +{ + (void)data; + + /* The board: its clocks, pins and console */ + emb_board_init(); + + /* The kernel: its objects, and the EARLY devices */ + emb_kernel_init(); +} +/******************************************************************************* + End of File +*/ diff --git a/examples/controller/generated/.base/nucleo_f446re/linker/regions.ld b/examples/controller/src/config/.base/nucleo_f446re/linker/regions.ld similarity index 90% rename from examples/controller/generated/.base/nucleo_f446re/linker/regions.ld rename to examples/controller/src/config/.base/nucleo_f446re/linker/regions.ld index f9c6cae1..7297204a 100644 --- a/examples/controller/generated/.base/nucleo_f446re/linker/regions.ld +++ b/examples/controller/src/config/.base/nucleo_f446re/linker/regions.ld @@ -12,22 +12,24 @@ * * @details * Generated by emb-hwgen 0.1.0, schema v0. Do not edit: change the - * description and run hw/gen/emb-hwgen.py generate --system examples/controller/system.yaml (HW-003). + * description and run + * hw/gen/emb-hwgen.py generate --system examples/controller/system.yaml + * (HW-003). * Inputs (SHA-256): * arch/cortex_m/arch.yaml * c5c8e451c09717dee1713d07f8311b6d507e3b4c66c42d93e0ce11da6ec76d6d * boards/st/nucleo_f446re/board.yaml - * d756f3a7f19dc7da82ee3afc168dc54946312c5a9990720953c0fedcdece54ea + * 551c524379751d359bdd87501269d6cab33edf84d212d2f6632ffe9567ec71d0 * drivers/bindings.yaml - * d3c336ac05548e0addd1faac18f3dff70576d8069f11d89e6a761cf5c6132b49 + * c06d1a914adb21d0e314c79b3611ac6859eefeac1957d6914cccfc5531ad6ede * examples/controller/controller.conf * f7354e5137f5ea50fbd1d5829ff4f5eb88a044100d871d6a8fd7d976339a75f1 * examples/controller/system.yaml * 2a91f71f1de638aa1ffaa18f0f76fc3ccde44d2560aef98a9a48120775773af3 * soc/st/stm32f4/stm32f4.yaml - * 3db4a0a65c9624d865d4ed7fc6354bf95054d0c465b76a2091f06aeac3d7375f + * 796886c294250aa81151a620d80d0e43b5ee8e1bf53a07d1d7e2c62e95214dbd * soc/st/stm32f4/stm32f446.yaml - * 0d5cc7f5fce4c51be71678987720c85c6e76e05473ff8a78ea5035394316c055 + * f0c9a37f6017c87d0efe215a3561f65494ba52383f2d0c10419b0ab5035f77f2 * soc/st/stm32f4/stm32f446re.yaml * b9a88d0a94aa17ee83317a3a56f7c194ec1b3107dfb3e82e453122dc1c48f6d4 */ diff --git a/examples/controller/generated/nucleo_f446re/src/board_pins.c b/examples/controller/src/config/.base/nucleo_f446re/peripheral/board_pins.c similarity index 76% rename from examples/controller/generated/nucleo_f446re/src/board_pins.c rename to examples/controller/src/config/.base/nucleo_f446re/peripheral/board_pins.c index b951f740..259594e9 100644 --- a/examples/controller/generated/nucleo_f446re/src/board_pins.c +++ b/examples/controller/src/config/.base/nucleo_f446re/peripheral/board_pins.c @@ -11,22 +11,24 @@ * * @details * Generated by emb-hwgen 0.1.0, schema v0. Do not edit: change the - * description and run hw/gen/emb-hwgen.py generate --system examples/controller/system.yaml (HW-003). + * description and run + * hw/gen/emb-hwgen.py generate --system examples/controller/system.yaml + * (HW-003). * Inputs (SHA-256): * arch/cortex_m/arch.yaml * c5c8e451c09717dee1713d07f8311b6d507e3b4c66c42d93e0ce11da6ec76d6d * boards/st/nucleo_f446re/board.yaml - * d756f3a7f19dc7da82ee3afc168dc54946312c5a9990720953c0fedcdece54ea + * 551c524379751d359bdd87501269d6cab33edf84d212d2f6632ffe9567ec71d0 * drivers/bindings.yaml - * d3c336ac05548e0addd1faac18f3dff70576d8069f11d89e6a761cf5c6132b49 + * c06d1a914adb21d0e314c79b3611ac6859eefeac1957d6914cccfc5531ad6ede * examples/controller/controller.conf * f7354e5137f5ea50fbd1d5829ff4f5eb88a044100d871d6a8fd7d976339a75f1 * examples/controller/system.yaml * 2a91f71f1de638aa1ffaa18f0f76fc3ccde44d2560aef98a9a48120775773af3 * soc/st/stm32f4/stm32f4.yaml - * 3db4a0a65c9624d865d4ed7fc6354bf95054d0c465b76a2091f06aeac3d7375f + * 796886c294250aa81151a620d80d0e43b5ee8e1bf53a07d1d7e2c62e95214dbd * soc/st/stm32f4/stm32f446.yaml - * 0d5cc7f5fce4c51be71678987720c85c6e76e05473ff8a78ea5035394316c055 + * f0c9a37f6017c87d0efe215a3561f65494ba52383f2d0c10419b0ab5035f77f2 * soc/st/stm32f4/stm32f446re.yaml * b9a88d0a94aa17ee83317a3a56f7c194ec1b3107dfb3e82e453122dc1c48f6d4 */ @@ -42,10 +44,18 @@ const emb_stm32_pin_t emb_board_pins[] = { {EMB_STM32_PORT(A), 2u, EMB_STM32_PIN_AF, 7u, 0u, 0u}, /* PA3: pins.usart2.rx (usart2_rx) */ {EMB_STM32_PORT(A), 3u, EMB_STM32_PIN_AF, 7u, 0u, 0u}, + /* PA4: pins.adc1.in4 (adc1_in4) */ + {EMB_STM32_PORT(A), 4u, EMB_STM32_PIN_ANALOG, 0u, 0u, 0u}, /* PA5: leds.user (output) */ {EMB_STM32_PORT(A), 5u, EMB_STM32_PIN_OUTPUT, 0u, 0u, 0u}, + /* PA6: pins.tim3.ch1 (tim3_ch1) */ + {EMB_STM32_PORT(A), 6u, EMB_STM32_PIN_AF, 2u, 0u, 0u}, + /* PB0: pins.adc1.in8 (adc1_in8) */ + {EMB_STM32_PORT(B), 0u, EMB_STM32_PIN_ANALOG, 0u, 0u, 0u}, /* PB3: pins.i2c2.sda (i2c2_sda) */ {EMB_STM32_PORT(B), 3u, EMB_STM32_PIN_AF, 4u, 0u, EMB_STM32_PIN_I2C}, + /* PB6: pins.tim4.ch1 (tim4_ch1) */ + {EMB_STM32_PORT(B), 6u, EMB_STM32_PIN_AF, 2u, 0u, 0u}, /* PB8: pins.i2c1.scl (i2c1_scl) */ {EMB_STM32_PORT(B), 8u, EMB_STM32_PIN_AF, 4u, 0u, EMB_STM32_PIN_I2C}, /* PB9: pins.i2c1.sda (i2c1_sda) */ diff --git a/examples/controller/generated/.base/nucleo_f446re/include/hw_config.h b/examples/controller/src/config/.base/nucleo_f446re/peripheral/hw_config.h similarity index 89% rename from examples/controller/generated/.base/nucleo_f446re/include/hw_config.h rename to examples/controller/src/config/.base/nucleo_f446re/peripheral/hw_config.h index 0d1d80dc..88c9c738 100644 --- a/examples/controller/generated/.base/nucleo_f446re/include/hw_config.h +++ b/examples/controller/src/config/.base/nucleo_f446re/peripheral/hw_config.h @@ -10,22 +10,24 @@ * * @details * Generated by emb-hwgen 0.1.0, schema v0. Do not edit: change the - * description and run hw/gen/emb-hwgen.py generate --system examples/controller/system.yaml (HW-003). + * description and run + * hw/gen/emb-hwgen.py generate --system examples/controller/system.yaml + * (HW-003). * Inputs (SHA-256): * arch/cortex_m/arch.yaml * c5c8e451c09717dee1713d07f8311b6d507e3b4c66c42d93e0ce11da6ec76d6d * boards/st/nucleo_f446re/board.yaml - * d756f3a7f19dc7da82ee3afc168dc54946312c5a9990720953c0fedcdece54ea + * 551c524379751d359bdd87501269d6cab33edf84d212d2f6632ffe9567ec71d0 * drivers/bindings.yaml - * d3c336ac05548e0addd1faac18f3dff70576d8069f11d89e6a761cf5c6132b49 + * c06d1a914adb21d0e314c79b3611ac6859eefeac1957d6914cccfc5531ad6ede * examples/controller/controller.conf * f7354e5137f5ea50fbd1d5829ff4f5eb88a044100d871d6a8fd7d976339a75f1 * examples/controller/system.yaml * 2a91f71f1de638aa1ffaa18f0f76fc3ccde44d2560aef98a9a48120775773af3 * soc/st/stm32f4/stm32f4.yaml - * 3db4a0a65c9624d865d4ed7fc6354bf95054d0c465b76a2091f06aeac3d7375f + * 796886c294250aa81151a620d80d0e43b5ee8e1bf53a07d1d7e2c62e95214dbd * soc/st/stm32f4/stm32f446.yaml - * 0d5cc7f5fce4c51be71678987720c85c6e76e05473ff8a78ea5035394316c055 + * f0c9a37f6017c87d0efe215a3561f65494ba52383f2d0c10419b0ab5035f77f2 * soc/st/stm32f4/stm32f446re.yaml * b9a88d0a94aa17ee83317a3a56f7c194ec1b3107dfb3e82e453122dc1c48f6d4 */ @@ -168,6 +170,22 @@ #define EMB_HW_TIM2_CLKEN_BIT 0u #define EMB_HW_TIM2_CLKEN_OFFSET 0x40u #define EMB_HW_TIM2_IRQ 28u +#define EMB_HW_TIM3_BASE 0x40000400u +#define EMB_HW_TIM3_CLKEN_BIT 1u +#define EMB_HW_TIM3_CLKEN_OFFSET 0x40u +#define EMB_HW_TIM3_IRQ 29u +#define EMB_HW_TIM4_BASE 0x40000800u +#define EMB_HW_TIM4_CLKEN_BIT 2u +#define EMB_HW_TIM4_CLKEN_OFFSET 0x40u +#define EMB_HW_TIM4_IRQ 30u +#define EMB_HW_TIM5_BASE 0x40000C00u +#define EMB_HW_TIM5_CLKEN_BIT 3u +#define EMB_HW_TIM5_CLKEN_OFFSET 0x40u +#define EMB_HW_TIM5_IRQ 50u +#define EMB_HW_TIM9_BASE 0x40014000u +#define EMB_HW_TIM9_CLKEN_BIT 16u +#define EMB_HW_TIM9_CLKEN_OFFSET 0x44u +#define EMB_HW_TIM9_IRQ 24u #define EMB_HW_UART4_BASE 0x40004C00u #define EMB_HW_UART4_CLKEN_BIT 19u #define EMB_HW_UART4_CLKEN_OFFSET 0x40u diff --git a/examples/controller/generated/.base/nucleo_f446re/src/soc_devices.c b/examples/controller/src/config/.base/nucleo_f446re/peripheral/soc_devices.c similarity index 63% rename from examples/controller/generated/.base/nucleo_f446re/src/soc_devices.c rename to examples/controller/src/config/.base/nucleo_f446re/peripheral/soc_devices.c index 2f624384..8268a2a8 100644 --- a/examples/controller/generated/.base/nucleo_f446re/src/soc_devices.c +++ b/examples/controller/src/config/.base/nucleo_f446re/peripheral/soc_devices.c @@ -11,22 +11,24 @@ * * @details * Generated by emb-hwgen 0.1.0, schema v0. Do not edit: change the - * description and run hw/gen/emb-hwgen.py generate --system examples/controller/system.yaml (HW-003). + * description and run + * hw/gen/emb-hwgen.py generate --system examples/controller/system.yaml + * (HW-003). * Inputs (SHA-256): * arch/cortex_m/arch.yaml * c5c8e451c09717dee1713d07f8311b6d507e3b4c66c42d93e0ce11da6ec76d6d * boards/st/nucleo_f446re/board.yaml - * d756f3a7f19dc7da82ee3afc168dc54946312c5a9990720953c0fedcdece54ea + * 551c524379751d359bdd87501269d6cab33edf84d212d2f6632ffe9567ec71d0 * drivers/bindings.yaml - * d3c336ac05548e0addd1faac18f3dff70576d8069f11d89e6a761cf5c6132b49 + * c06d1a914adb21d0e314c79b3611ac6859eefeac1957d6914cccfc5531ad6ede * examples/controller/controller.conf * f7354e5137f5ea50fbd1d5829ff4f5eb88a044100d871d6a8fd7d976339a75f1 * examples/controller/system.yaml * 2a91f71f1de638aa1ffaa18f0f76fc3ccde44d2560aef98a9a48120775773af3 * soc/st/stm32f4/stm32f4.yaml - * 3db4a0a65c9624d865d4ed7fc6354bf95054d0c465b76a2091f06aeac3d7375f + * 796886c294250aa81151a620d80d0e43b5ee8e1bf53a07d1d7e2c62e95214dbd * soc/st/stm32f4/stm32f446.yaml - * 0d5cc7f5fce4c51be71678987720c85c6e76e05473ff8a78ea5035394316c055 + * f0c9a37f6017c87d0efe215a3561f65494ba52383f2d0c10419b0ab5035f77f2 * soc/st/stm32f4/stm32f446re.yaml * b9a88d0a94aa17ee83317a3a56f7c194ec1b3107dfb3e82e453122dc1c48f6d4 */ @@ -170,6 +172,36 @@ const emb_device_t emb_dev_dma1 = { .dep_count = 1u, }; +/* dma2: st,stm32-dma, dma, EARLY */ +static const emb_stm32_dma_config_t dma2_config = { + .base = 0x40026400u, /* peripheral.base */ + .clken_offset = 0x00000030u, /* peripheral.clock.enable_offset */ + .clken_bit = 22u, /* peripheral.clock.bit */ + .irq0 = 56u, /* peripheral.irqs.s0 */ + .irq1 = 57u, /* peripheral.irqs.s1 */ + .irq2 = 58u, /* peripheral.irqs.s2 */ + .irq3 = 59u, /* peripheral.irqs.s3 */ + .irq4 = 60u, /* peripheral.irqs.s4 */ + .irq5 = 68u, /* peripheral.irqs.s5 */ + .irq6 = 69u, /* peripheral.irqs.s6 */ + .irq7 = 70u, /* peripheral.irqs.s7 */ + .memory = true, /* peripheral.dma.memory */ +}; +static emb_device_state_t dma2_state; +static emb_stm32_dma_data_t dma2_data; +static const emb_device_t *const dma2_deps[] = {&emb_dev_rcc}; +const emb_device_t emb_dev_dma2 = { + .name = "dma2", + .api = &emb_stm32_dma_api.dev, + .config = &dma2_config, + .state = &dma2_state, + .data = &dma2_data, + .deps = dma2_deps, + .class_id = EMB_DRV_CLASS_DMA, + .level = EMB_DEVICE_EARLY, + .dep_count = 1u, +}; + /* gpiob: st,stm32-gpio, gpio, EARLY */ static const emb_stm32_gpio_config_t gpiob_config = { .base = 0x40020400u, /* peripheral.base */ @@ -343,6 +375,144 @@ const emb_device_t emb_dev_i2c2 = { .dep_count = 1u, }; +/* tim5: st,stm32-tim, counter, KERNEL */ +static const emb_stm32_tim_config_t tim5_config = { + .base = 0x40000C00u, /* peripheral.base */ + .clock_hz = 90000000u, /* peripheral.timer_clock_hz */ + .rate_hz = 1000000u, /* device.rate_hz, its default */ + .clken_offset = 0x00000040u, /* peripheral.clock.enable_offset */ + .clken_bit = 3u, /* peripheral.clock.bit */ + .irq = 50u, /* peripheral.irqs.global */ + .bits = 32u, /* peripheral.counter_bits */ + .channels = 4u, /* peripheral.timer_channels, its default */ +}; +static emb_device_state_t tim5_state; +static emb_stm32_counter_data_t tim5_data; +static const emb_device_t *const tim5_deps[] = {&emb_dev_rcc}; +const emb_device_t emb_dev_tim5 = { + .name = "tim5", + .api = &emb_stm32_counter_api.dev, + .config = &tim5_config, + .state = &tim5_state, + .data = &tim5_data, + .deps = tim5_deps, + .class_id = EMB_DRV_CLASS_COUNTER, + .level = EMB_DEVICE_KERNEL, + .dep_count = 1u, +}; + +/* tim9: st,stm32-tim, counter, KERNEL */ +static const emb_stm32_tim_config_t tim9_config = { + .base = 0x40014000u, /* peripheral.base */ + .clock_hz = 180000000u, /* peripheral.timer_clock_hz */ + .rate_hz = 1000000u, /* device.rate_hz, its default */ + .clken_offset = 0x00000044u, /* peripheral.clock.enable_offset */ + .clken_bit = 16u, /* peripheral.clock.bit */ + .irq = 24u, /* peripheral.irqs.global */ + .bits = 16u, /* peripheral.counter_bits */ + .channels = 2u, /* peripheral.timer_channels */ +}; +static emb_device_state_t tim9_state; +static emb_stm32_counter_data_t tim9_data; +static const emb_device_t *const tim9_deps[] = {&emb_dev_rcc}; +const emb_device_t emb_dev_tim9 = { + .name = "tim9", + .api = &emb_stm32_counter_api.dev, + .config = &tim9_config, + .state = &tim9_state, + .data = &tim9_data, + .deps = tim9_deps, + .class_id = EMB_DRV_CLASS_COUNTER, + .level = EMB_DEVICE_KERNEL, + .dep_count = 1u, +}; + +/* tim3: st,stm32-tim, pwm, KERNEL */ +static const emb_stm32_tim_config_t tim3_config = { + .base = 0x40000400u, /* peripheral.base */ + .clock_hz = 90000000u, /* peripheral.timer_clock_hz */ + .clken_offset = 0x00000040u, /* peripheral.clock.enable_offset */ + .clken_bit = 1u, /* peripheral.clock.bit */ + .irq = 29u, /* peripheral.irqs.global */ + .bits = 16u, /* peripheral.counter_bits */ + .channels = 4u, /* peripheral.timer_channels, its default */ +}; +static emb_device_state_t tim3_state; +static emb_stm32_pwm_data_t tim3_data; +static const emb_device_t *const tim3_deps[] = {&emb_dev_rcc}; +const emb_device_t emb_dev_tim3 = { + .name = "tim3", + .api = &emb_stm32_pwm_api.dev, + .config = &tim3_config, + .state = &tim3_state, + .data = &tim3_data, + .deps = tim3_deps, + .class_id = EMB_DRV_CLASS_PWM, + .level = EMB_DEVICE_KERNEL, + .dep_count = 1u, +}; + +/* tim4: st,stm32-tim, pwm, KERNEL */ +static const emb_stm32_tim_config_t tim4_config = { + .base = 0x40000800u, /* peripheral.base */ + .clock_hz = 90000000u, /* peripheral.timer_clock_hz */ + .clken_offset = 0x00000040u, /* peripheral.clock.enable_offset */ + .clken_bit = 2u, /* peripheral.clock.bit */ + .irq = 30u, /* peripheral.irqs.global */ + .bits = 16u, /* peripheral.counter_bits */ + .channels = 4u, /* peripheral.timer_channels, its default */ +}; +static emb_device_state_t tim4_state; +static emb_stm32_pwm_data_t tim4_data; +static const emb_device_t *const tim4_deps[] = {&emb_dev_rcc}; +const emb_device_t emb_dev_tim4 = { + .name = "tim4", + .api = &emb_stm32_pwm_api.dev, + .config = &tim4_config, + .state = &tim4_state, + .data = &tim4_data, + .deps = tim4_deps, + .class_id = EMB_DRV_CLASS_PWM, + .level = EMB_DEVICE_KERNEL, + .dep_count = 1u, +}; + +/* adc1: st,stm32f4-adc, adc, KERNEL */ +static const emb_stm32_adc_config_t adc1_config = { + .base = 0x40012000u, /* peripheral.base */ + .common = 0x40012300u, /* takes.common.base */ + .calibration = 0x1FFF7A2Au, /* takes.cal.base */ + .trigger = 0x40000000u, /* takes.trigger.base */ + .trigger_hz = 90000000u, /* takes.trigger.timer_clock_hz */ + .trigger_clken_offset = 0x00000040u, /* takes.trigger.clock.enable_offset */ + .trigger_clken_bit = 0u, /* takes.trigger.clock.bit */ + .trigger_select = 6u, /* takes.trigger.adc_trigger */ + .clock_hz = 90000000u, /* peripheral.clock_hz */ + .clken_offset = 0x00000044u, /* peripheral.clock.enable_offset */ + .clken_bit = 8u, /* peripheral.clock.bit */ + .irq = 18u, /* peripheral.irqs.global */ + .vref_mv = 3300u, /* device.vref_mv, its default */ + .bits = 12u, /* peripheral.adc.bits */ + .inputs = 16u, /* peripheral.adc.inputs */ + .temperature = 18u, /* peripheral.adc.temperature */ + .vrefint = 17u, /* peripheral.adc.vrefint */ + .dma_rx = {&emb_dev_dma2, 0u, 0u, {0u, 0u}}, /* dma.rx */ +}; +static emb_device_state_t adc1_state; +static emb_stm32_adc_data_t adc1_data; +static const emb_device_t *const adc1_deps[] = {&emb_dev_dma2, &emb_dev_rcc}; +const emb_device_t emb_dev_adc1 = { + .name = "adc1", + .api = &emb_stm32_adc_api.dev, + .config = &adc1_config, + .state = &adc1_state, + .data = &adc1_data, + .deps = adc1_deps, + .class_id = EMB_DRV_CLASS_ADC, + .level = EMB_DEVICE_KERNEL, + .dep_count = 2u, +}; + /* in initialization order */ static const emb_device_t *const devices[] = { &emb_dev_rcc, /* 0: EARLY */ @@ -351,16 +521,22 @@ static const emb_device_t *const devices[] = { &emb_dev_rtc, /* 3: EARLY */ &emb_dev_flash, /* 4: EARLY */ &emb_dev_dma1, /* 5: EARLY */ - &emb_dev_gpiob, /* 6: EARLY */ - &emb_dev_gpioc, /* 7: EARLY */ - &emb_dev_usart2, /* 8: EARLY */ - &emb_dev_uart4, /* 9: EARLY */ - &emb_dev_spi2, /* 10: KERNEL */ - &emb_dev_i2c1, /* 11: KERNEL */ - &emb_dev_i2c2, /* 12: KERNEL */ + &emb_dev_dma2, /* 6: EARLY */ + &emb_dev_gpiob, /* 7: EARLY */ + &emb_dev_gpioc, /* 8: EARLY */ + &emb_dev_usart2, /* 9: EARLY */ + &emb_dev_uart4, /* 10: EARLY */ + &emb_dev_spi2, /* 11: KERNEL */ + &emb_dev_i2c1, /* 12: KERNEL */ + &emb_dev_i2c2, /* 13: KERNEL */ + &emb_dev_tim5, /* 14: KERNEL */ + &emb_dev_tim9, /* 15: KERNEL */ + &emb_dev_tim3, /* 16: KERNEL */ + &emb_dev_tim4, /* 17: KERNEL */ + &emb_dev_adc1, /* 18: KERNEL */ }; -const emb_device_table_t emb_board_device_table = {devices, 13u, 10u}; +const emb_device_table_t emb_board_device_table = {devices, 19u, 11u}; #if CONFIG_EMB_DRV_ENTROPY /* the board's entropy source, or none: nothing stands in for one (SPEC-017 §11, SEC-012) */ diff --git a/examples/controller/generated/nucleo_f446re/include/soc_devices.h b/examples/controller/src/config/.base/nucleo_f446re/peripheral/soc_devices.h similarity index 78% rename from examples/controller/generated/nucleo_f446re/include/soc_devices.h rename to examples/controller/src/config/.base/nucleo_f446re/peripheral/soc_devices.h index e33f77bb..85805dc4 100644 --- a/examples/controller/generated/nucleo_f446re/include/soc_devices.h +++ b/examples/controller/src/config/.base/nucleo_f446re/peripheral/soc_devices.h @@ -10,22 +10,24 @@ * * @details * Generated by emb-hwgen 0.1.0, schema v0. Do not edit: change the - * description and run hw/gen/emb-hwgen.py generate --system examples/controller/system.yaml (HW-003). + * description and run + * hw/gen/emb-hwgen.py generate --system examples/controller/system.yaml + * (HW-003). * Inputs (SHA-256): * arch/cortex_m/arch.yaml * c5c8e451c09717dee1713d07f8311b6d507e3b4c66c42d93e0ce11da6ec76d6d * boards/st/nucleo_f446re/board.yaml - * d756f3a7f19dc7da82ee3afc168dc54946312c5a9990720953c0fedcdece54ea + * 551c524379751d359bdd87501269d6cab33edf84d212d2f6632ffe9567ec71d0 * drivers/bindings.yaml - * d3c336ac05548e0addd1faac18f3dff70576d8069f11d89e6a761cf5c6132b49 + * c06d1a914adb21d0e314c79b3611ac6859eefeac1957d6914cccfc5531ad6ede * examples/controller/controller.conf * f7354e5137f5ea50fbd1d5829ff4f5eb88a044100d871d6a8fd7d976339a75f1 * examples/controller/system.yaml * 2a91f71f1de638aa1ffaa18f0f76fc3ccde44d2560aef98a9a48120775773af3 * soc/st/stm32f4/stm32f4.yaml - * 3db4a0a65c9624d865d4ed7fc6354bf95054d0c465b76a2091f06aeac3d7375f + * 796886c294250aa81151a620d80d0e43b5ee8e1bf53a07d1d7e2c62e95214dbd * soc/st/stm32f4/stm32f446.yaml - * 0d5cc7f5fce4c51be71678987720c85c6e76e05473ff8a78ea5035394316c055 + * f0c9a37f6017c87d0efe215a3561f65494ba52383f2d0c10419b0ab5035f77f2 * soc/st/stm32f4/stm32f446re.yaml * b9a88d0a94aa17ee83317a3a56f7c194ec1b3107dfb3e82e453122dc1c48f6d4 */ @@ -34,7 +36,7 @@ #include -#define EMB_SOC_DEVICE_COUNT 13u +#define EMB_SOC_DEVICE_COUNT 19u #if CONFIG_EMB_DEVICE #include @@ -46,6 +48,7 @@ extern const emb_device_t emb_dev_iwdg; extern const emb_device_t emb_dev_rtc; extern const emb_device_t emb_dev_flash; extern const emb_device_t emb_dev_dma1; +extern const emb_device_t emb_dev_dma2; extern const emb_device_t emb_dev_gpiob; extern const emb_device_t emb_dev_gpioc; extern const emb_device_t emb_dev_usart2; @@ -53,6 +56,11 @@ extern const emb_device_t emb_dev_uart4; extern const emb_device_t emb_dev_spi2; extern const emb_device_t emb_dev_i2c1; extern const emb_device_t emb_dev_i2c2; +extern const emb_device_t emb_dev_tim5; +extern const emb_device_t emb_dev_tim9; +extern const emb_device_t emb_dev_tim3; +extern const emb_device_t emb_dev_tim4; +extern const emb_device_t emb_dev_adc1; /* which devices the board has, for code that uses one only where it exists */ #define EMB_SOC_HAS_RCC 1 @@ -61,6 +69,7 @@ extern const emb_device_t emb_dev_i2c2; #define EMB_SOC_HAS_RTC 1 #define EMB_SOC_HAS_FLASH 1 #define EMB_SOC_HAS_DMA1 1 +#define EMB_SOC_HAS_DMA2 1 #define EMB_SOC_HAS_GPIOB 1 #define EMB_SOC_HAS_GPIOC 1 #define EMB_SOC_HAS_USART2 1 @@ -68,6 +77,11 @@ extern const emb_device_t emb_dev_i2c2; #define EMB_SOC_HAS_SPI2 1 #define EMB_SOC_HAS_I2C1 1 #define EMB_SOC_HAS_I2C2 1 +#define EMB_SOC_HAS_TIM5 1 +#define EMB_SOC_HAS_TIM9 1 +#define EMB_SOC_HAS_TIM3 1 +#define EMB_SOC_HAS_TIM4 1 +#define EMB_SOC_HAS_ADC1 1 /* the board's watchdog device: the first of its class */ #define EMB_SOC_WATCHDOG_DEVICE (&emb_dev_iwdg) @@ -75,6 +89,11 @@ extern const emb_device_t emb_dev_i2c2; /* the board's RTC device: the first of its class */ #define EMB_SOC_RTC_DEVICE (&emb_dev_rtc) +/* the board's counters: the first of their class, and all of them (SPEC-017 §11a) */ +#define EMB_SOC_COUNTER_DEVICE (&emb_dev_tim5) +#define EMB_SOC_COUNTER_DEVICES &emb_dev_tim5, &emb_dev_tim9 +#define EMB_SOC_COUNTER_COUNT 2u + /* the console's UART device (the board's console:) */ #define EMB_SOC_CONSOLE_DEVICE (&emb_dev_usart2) /* its writes' DMA channel (devices[].dma, A119) */ @@ -97,6 +116,7 @@ extern const emb_device_t emb_dev_i2c2; #define EMB_SOC_USART2_DMA_TX {&emb_dev_dma1, 6u, 4u, {0u, 0u}} #define EMB_SOC_SPI2_DMA_RX {&emb_dev_dma1, 3u, 0u, {0u, 0u}} #define EMB_SOC_SPI2_DMA_TX {&emb_dev_dma1, 4u, 0u, {0u, 0u}} +#define EMB_SOC_ADC1_DMA_RX {&emb_dev_dma2, 0u, 0u, {0u, 0u}} /* clang-format on */ /* the SPI devices' chip selects (devices[].cs), emb_drv_gpio_line_t initializers; the pin diff --git a/examples/controller/src/config/.base/nucleo_f446re/tasks.c b/examples/controller/src/config/.base/nucleo_f446re/tasks.c new file mode 100644 index 00000000..b27fc5f9 --- /dev/null +++ b/examples/controller/src/config/.base/nucleo_f446re/tasks.c @@ -0,0 +1,74 @@ +/* SPDX-License-Identifier: Apache-2.0 */ +/* + * This file is part of EmbLinkRTOS, a deterministic real-time kernel for microcontrollers. + * Licensed under the Apache License, Version 2.0; see the LICENSE file at the repository root. + */ + +/******************************************************************************* + System Tasks File + + File Name: + tasks.c + + Summary: + controller's tasks on the nucleo_f446re, and SYS_Tasks(). + + Description: + Each task's thread, queue, dispatch and description: the thread runs the + task runtime, emb_task_run() (SPEC-020), which calls an event task's handler + for each event, and a periodic task's _Tasks() every period, without drift. + SYS_Tasks() starts the kernel. + + Generated by emb-hwgen 0.1.0, schema v0, from the system description and the + nucleo_f446re's. Yours to edit: regenerating merges its changes with yours + (A126): + hw/gen/emb-hwgen.py generate --system examples/controller/system.yaml + + Inputs (SHA-256): + arch/cortex_m/arch.yaml + c5c8e451c09717dee1713d07f8311b6d507e3b4c66c42d93e0ce11da6ec76d6d + boards/st/nucleo_f446re/board.yaml + 551c524379751d359bdd87501269d6cab33edf84d212d2f6632ffe9567ec71d0 + drivers/bindings.yaml + c06d1a914adb21d0e314c79b3611ac6859eefeac1957d6914cccfc5531ad6ede + examples/controller/controller.conf + f7354e5137f5ea50fbd1d5829ff4f5eb88a044100d871d6a8fd7d976339a75f1 + examples/controller/system.yaml + 2a91f71f1de638aa1ffaa18f0f76fc3ccde44d2560aef98a9a48120775773af3 + soc/st/stm32f4/stm32f4.yaml + 796886c294250aa81151a620d80d0e43b5ee8e1bf53a07d1d7e2c62e95214dbd + soc/st/stm32f4/stm32f446.yaml + f0c9a37f6017c87d0efe215a3561f65494ba52383f2d0c10419b0ab5035f77f2 + soc/st/stm32f4/stm32f446re.yaml + b9a88d0a94aa17ee83317a3a56f7c194ec1b3107dfb3e82e453122dc1c48f6d4 + *******************************************************************************/ + +// ***************************************************************************** +// ***************************************************************************** +// Section: Included Files +// ***************************************************************************** +// ***************************************************************************** + +#include "definitions.h" + +// ***************************************************************************** +// ***************************************************************************** +// Section: System "Tasks" Routine +// ***************************************************************************** +// ***************************************************************************** + +/******************************************************************************* + Function: + void SYS_Tasks ( void ) + + Remarks: + See prototype in definitions.h. + */ +void SYS_Tasks(void) +{ + /* Start the kernel: the threads and the tasks run from here. It does not return. */ + emb_kernel_start(); +} +/******************************************************************************* + End of File +*/ diff --git a/examples/controller/generated/nucleo_f446ze/build/CMakeLists.txt b/examples/controller/src/config/.base/nucleo_f446ze/build/CMakeLists.txt similarity index 72% rename from examples/controller/generated/nucleo_f446ze/build/CMakeLists.txt rename to examples/controller/src/config/.base/nucleo_f446ze/build/CMakeLists.txt index dc6477a2..29239f62 100644 --- a/examples/controller/generated/nucleo_f446ze/build/CMakeLists.txt +++ b/examples/controller/src/config/.base/nucleo_f446ze/build/CMakeLists.txt @@ -4,24 +4,26 @@ # Licensed under the Apache License, Version 2.0; see the LICENSE file at the repository root. # # Generated by emb-hwgen 0.1.0, schema v0. Do not edit: change the -# description and run hw/gen/emb-hwgen.py generate --system examples/controller/system.yaml (HW-003). +# description and run +# hw/gen/emb-hwgen.py generate --system examples/controller/system.yaml +# (HW-003). # Inputs (SHA-256): # arch/cortex_m/arch.yaml # c5c8e451c09717dee1713d07f8311b6d507e3b4c66c42d93e0ce11da6ec76d6d # boards/st/nucleo_f446ze/board.yaml # 1525ea206692663af174039e30776d6a9a9b30275c9e5c9bdabf14ac0b70aa19 # drivers/bindings.yaml -# d3c336ac05548e0addd1faac18f3dff70576d8069f11d89e6a761cf5c6132b49 +# c06d1a914adb21d0e314c79b3611ac6859eefeac1957d6914cccfc5531ad6ede # examples/controller/controller.conf # f7354e5137f5ea50fbd1d5829ff4f5eb88a044100d871d6a8fd7d976339a75f1 # examples/controller/system.yaml # 2a91f71f1de638aa1ffaa18f0f76fc3ccde44d2560aef98a9a48120775773af3 # soc/st/stm32f4/stm32f4.yaml -# 3db4a0a65c9624d865d4ed7fc6354bf95054d0c465b76a2091f06aeac3d7375f +# 796886c294250aa81151a620d80d0e43b5ee8e1bf53a07d1d7e2c62e95214dbd # soc/st/stm32f4/stm32f446.yaml -# 0d5cc7f5fce4c51be71678987720c85c6e76e05473ff8a78ea5035394316c055 +# f0c9a37f6017c87d0efe215a3561f65494ba52383f2d0c10419b0ab5035f77f2 # soc/st/stm32f4/stm32f446ze.yaml # dabae95e9e4bc984c1a33275966665e0252068e929fe3b430d06589da6bdb6c9 # The board has no C of its own: its SoC family's board support builds emb_board from -# ../src/board_pins.c and ../include/hw_config.h, and links ../linker/regions.ld. +# ../peripheral/board_pins.c and ../peripheral/hw_config.h, and links ../linker/regions.ld. add_subdirectory("${EMB_SOC_DIR}" soc) diff --git a/examples/controller/generated/nucleo_f446ze/build/board.cmake b/examples/controller/src/config/.base/nucleo_f446ze/build/board.cmake similarity index 72% rename from examples/controller/generated/nucleo_f446ze/build/board.cmake rename to examples/controller/src/config/.base/nucleo_f446ze/build/board.cmake index be3efdcf..472587b8 100644 --- a/examples/controller/generated/nucleo_f446ze/build/board.cmake +++ b/examples/controller/src/config/.base/nucleo_f446ze/build/board.cmake @@ -4,22 +4,24 @@ # Licensed under the Apache License, Version 2.0; see the LICENSE file at the repository root. # # Generated by emb-hwgen 0.1.0, schema v0. Do not edit: change the -# description and run hw/gen/emb-hwgen.py generate --system examples/controller/system.yaml (HW-003). +# description and run +# hw/gen/emb-hwgen.py generate --system examples/controller/system.yaml +# (HW-003). # Inputs (SHA-256): # arch/cortex_m/arch.yaml # c5c8e451c09717dee1713d07f8311b6d507e3b4c66c42d93e0ce11da6ec76d6d # boards/st/nucleo_f446ze/board.yaml # 1525ea206692663af174039e30776d6a9a9b30275c9e5c9bdabf14ac0b70aa19 # drivers/bindings.yaml -# d3c336ac05548e0addd1faac18f3dff70576d8069f11d89e6a761cf5c6132b49 +# c06d1a914adb21d0e314c79b3611ac6859eefeac1957d6914cccfc5531ad6ede # examples/controller/controller.conf # f7354e5137f5ea50fbd1d5829ff4f5eb88a044100d871d6a8fd7d976339a75f1 # examples/controller/system.yaml # 2a91f71f1de638aa1ffaa18f0f76fc3ccde44d2560aef98a9a48120775773af3 # soc/st/stm32f4/stm32f4.yaml -# 3db4a0a65c9624d865d4ed7fc6354bf95054d0c465b76a2091f06aeac3d7375f +# 796886c294250aa81151a620d80d0e43b5ee8e1bf53a07d1d7e2c62e95214dbd # soc/st/stm32f4/stm32f446.yaml -# 0d5cc7f5fce4c51be71678987720c85c6e76e05473ff8a78ea5035394316c055 +# f0c9a37f6017c87d0efe215a3561f65494ba52383f2d0c10419b0ab5035f77f2 # soc/st/stm32f4/stm32f446ze.yaml # dabae95e9e4bc984c1a33275966665e0252068e929fe3b430d06589da6bdb6c9 # nucleo_f446ze: STM32F446ZE, cortex-m4f at 180 MHz. @@ -28,17 +30,19 @@ set(EMB_BOARD_VARIANT armv7em) set(EMB_BOARD_DEFAULT_PROFILE base) set(EMB_BOARD_C_FLAGS -mcpu=cortex-m4 -mfpu=fpv4-sp-d16 -mfloat-abi=hard) get_filename_component(EMB_BOARD_GENERATED_DIR "${CMAKE_CURRENT_LIST_DIR}/.." ABSOLUTE) -set(EMB_BOARD_CONF "${EMB_BOARD_GENERATED_DIR}/config/board.conf") +set(EMB_BOARD_CONF "${EMB_BOARD_GENERATED_DIR}/build/board.conf") set(EMB_BOARD_HW_JSON "${EMB_BOARD_GENERATED_DIR}/docs/hw.json") set(EMB_BOARD_BUILD_DIR "${CMAKE_CURRENT_LIST_DIR}") # build/CMakeLists.txt +set(EMB_BOARD_SRC_DIR "${EMB_BOARD_GENERATED_DIR}/peripheral") # its pin table and boot block +set(EMB_BOARD_LINKER_DIR "${EMB_BOARD_GENERATED_DIR}/linker") # the SoC family's board support and drivers build this board (build/CMakeLists.txt) set(EMB_SOC_DIR "${EMB_BASE}/soc/st/stm32f4") -set(EMB_BOARD_INCLUDE_DIRS "${EMB_BOARD_GENERATED_DIR}/include" "${EMB_SOC_DIR}/include") +set(EMB_BOARD_INCLUDE_DIRS "${EMB_BOARD_GENERATED_DIR}/peripheral" "${EMB_SOC_DIR}/include") set(EMB_BOARD_RESETS_IN embsim) # restart the image with RAM kept (test_crash_reset) set(EMB_BOARD_EMBSIM_TARGET emblink/nucleo_f446ze) # EMB_TEST_EMULATOR=embsim # the board's devices (soc_devices.c) and the drivers they use, and only those (SPEC-016 §8) set(EMB_BOARD_DRIVER_SOURCES - "${EMB_BOARD_GENERATED_DIR}/src/soc_devices.c" + "${EMB_BOARD_GENERATED_DIR}/peripheral/soc_devices.c" "${EMB_BASE}/drivers/st/stm32_devices.c" "${EMB_BASE}/drivers/st/stm32_uart.c" ) @@ -49,10 +53,10 @@ set(EMB_BOARD_DRIVER_INCLUDE_DIRS set(EMB_BOARD_HW_INPUTS "arch/cortex_m/arch.yaml=c5c8e451c09717dee1713d07f8311b6d507e3b4c66c42d93e0ce11da6ec76d6d" "boards/st/nucleo_f446ze/board.yaml=1525ea206692663af174039e30776d6a9a9b30275c9e5c9bdabf14ac0b70aa19" - "drivers/bindings.yaml=d3c336ac05548e0addd1faac18f3dff70576d8069f11d89e6a761cf5c6132b49" + "drivers/bindings.yaml=c06d1a914adb21d0e314c79b3611ac6859eefeac1957d6914cccfc5531ad6ede" "examples/controller/controller.conf=f7354e5137f5ea50fbd1d5829ff4f5eb88a044100d871d6a8fd7d976339a75f1" "examples/controller/system.yaml=2a91f71f1de638aa1ffaa18f0f76fc3ccde44d2560aef98a9a48120775773af3" - "soc/st/stm32f4/stm32f4.yaml=3db4a0a65c9624d865d4ed7fc6354bf95054d0c465b76a2091f06aeac3d7375f" - "soc/st/stm32f4/stm32f446.yaml=0d5cc7f5fce4c51be71678987720c85c6e76e05473ff8a78ea5035394316c055" + "soc/st/stm32f4/stm32f4.yaml=796886c294250aa81151a620d80d0e43b5ee8e1bf53a07d1d7e2c62e95214dbd" + "soc/st/stm32f4/stm32f446.yaml=f0c9a37f6017c87d0efe215a3561f65494ba52383f2d0c10419b0ab5035f77f2" "soc/st/stm32f4/stm32f446ze.yaml=dabae95e9e4bc984c1a33275966665e0252068e929fe3b430d06589da6bdb6c9" ) diff --git a/examples/controller/generated/nucleo_f446ze/config/board.conf b/examples/controller/src/config/.base/nucleo_f446ze/build/board.conf similarity index 77% rename from examples/controller/generated/nucleo_f446ze/config/board.conf rename to examples/controller/src/config/.base/nucleo_f446ze/build/board.conf index 724fc1bd..0a489073 100644 --- a/examples/controller/generated/nucleo_f446ze/config/board.conf +++ b/examples/controller/src/config/.base/nucleo_f446ze/build/board.conf @@ -4,22 +4,24 @@ # Licensed under the Apache License, Version 2.0; see the LICENSE file at the repository root. # # Generated by emb-hwgen 0.1.0, schema v0. Do not edit: change the -# description and run hw/gen/emb-hwgen.py generate --system examples/controller/system.yaml (HW-003). +# description and run +# hw/gen/emb-hwgen.py generate --system examples/controller/system.yaml +# (HW-003). # Inputs (SHA-256): # arch/cortex_m/arch.yaml # c5c8e451c09717dee1713d07f8311b6d507e3b4c66c42d93e0ce11da6ec76d6d # boards/st/nucleo_f446ze/board.yaml # 1525ea206692663af174039e30776d6a9a9b30275c9e5c9bdabf14ac0b70aa19 # drivers/bindings.yaml -# d3c336ac05548e0addd1faac18f3dff70576d8069f11d89e6a761cf5c6132b49 +# c06d1a914adb21d0e314c79b3611ac6859eefeac1957d6914cccfc5531ad6ede # examples/controller/controller.conf # f7354e5137f5ea50fbd1d5829ff4f5eb88a044100d871d6a8fd7d976339a75f1 # examples/controller/system.yaml # 2a91f71f1de638aa1ffaa18f0f76fc3ccde44d2560aef98a9a48120775773af3 # soc/st/stm32f4/stm32f4.yaml -# 3db4a0a65c9624d865d4ed7fc6354bf95054d0c465b76a2091f06aeac3d7375f +# 796886c294250aa81151a620d80d0e43b5ee8e1bf53a07d1d7e2c62e95214dbd # soc/st/stm32f4/stm32f446.yaml -# 0d5cc7f5fce4c51be71678987720c85c6e76e05473ff8a78ea5035394316c055 +# f0c9a37f6017c87d0efe215a3561f65494ba52383f2d0c10419b0ab5035f77f2 # soc/st/stm32f4/stm32f446ze.yaml # dabae95e9e4bc984c1a33275966665e0252068e929fe3b430d06589da6bdb6c9 # Board defaults for nucleo_f446ze. Applied before the profile fragment. diff --git a/examples/controller/src/config/.base/nucleo_f446ze/configuration.h b/examples/controller/src/config/.base/nucleo_f446ze/configuration.h new file mode 100644 index 00000000..36c10b3b --- /dev/null +++ b/examples/controller/src/config/.base/nucleo_f446ze/configuration.h @@ -0,0 +1,107 @@ +/* SPDX-License-Identifier: Apache-2.0 */ +/* + * This file is part of EmbLinkRTOS, a deterministic real-time kernel for microcontrollers. + * Licensed under the Apache License, Version 2.0; see the LICENSE file at the repository root. + */ + +/******************************************************************************* + System Configuration Header + + File Name: + configuration.h + + Summary: + The build-time configuration of controller on the nucleo_f446ze. + + Description: + The system's settings as macros: the board and its clock, the devices' + settings, each task's and thread's priority and stack, the tasks' periods, + queues and timeouts, and the application's interrupts. The kernel's own + options are 's CONFIG_EMB_*, and the board's hardware + 's EMB_HW_*. + + Generated by emb-hwgen 0.1.0, schema v0, from the system description and the + nucleo_f446ze's. Yours to edit: regenerating merges its changes with yours + (A126): + hw/gen/emb-hwgen.py generate --system examples/controller/system.yaml + + Inputs (SHA-256): + arch/cortex_m/arch.yaml + c5c8e451c09717dee1713d07f8311b6d507e3b4c66c42d93e0ce11da6ec76d6d + boards/st/nucleo_f446ze/board.yaml + 1525ea206692663af174039e30776d6a9a9b30275c9e5c9bdabf14ac0b70aa19 + drivers/bindings.yaml + c06d1a914adb21d0e314c79b3611ac6859eefeac1957d6914cccfc5531ad6ede + examples/controller/controller.conf + f7354e5137f5ea50fbd1d5829ff4f5eb88a044100d871d6a8fd7d976339a75f1 + examples/controller/system.yaml + 2a91f71f1de638aa1ffaa18f0f76fc3ccde44d2560aef98a9a48120775773af3 + soc/st/stm32f4/stm32f4.yaml + 796886c294250aa81151a620d80d0e43b5ee8e1bf53a07d1d7e2c62e95214dbd + soc/st/stm32f4/stm32f446.yaml + f0c9a37f6017c87d0efe215a3561f65494ba52383f2d0c10419b0ab5035f77f2 + soc/st/stm32f4/stm32f446ze.yaml + dabae95e9e4bc984c1a33275966665e0252068e929fe3b430d06589da6bdb6c9 + *******************************************************************************/ + +#ifndef CONFIGURATION_H +#define CONFIGURATION_H + +// ***************************************************************************** +// ***************************************************************************** +// Section: Included Files +// ***************************************************************************** +// ***************************************************************************** + +#include + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +// ***************************************************************************** +// ***************************************************************************** +// Section: System Configuration +// ***************************************************************************** +// ***************************************************************************** + +#define SYS_CPU_CLOCK_HZ 180000000u +#define SYS_TICK_NS CONFIG_EMB_TICK_NS +#define SYS_PRIORITY_COUNT CONFIG_EMB_PRIORITY_COUNT + +// ***************************************************************************** +// ***************************************************************************** +// Section: Driver Configuration +// ***************************************************************************** +// ***************************************************************************** + +#define DRV_USART3_BAUD 115200u + +// ***************************************************************************** +// ***************************************************************************** +// Section: Application Configuration +// ***************************************************************************** +// ***************************************************************************** + +/* control_thread: a thread */ +#define CONTROL_THREAD_PRIORITY 6u +#define CONTROL_THREAD_STACK_SIZE 1024u + +/* command_thread: a thread */ +#define COMMAND_THREAD_PRIORITY 4u +#define COMMAND_THREAD_STACK_SIZE 1024u + +/* telemetry_thread: a thread */ +#define TELEMETRY_THREAD_PRIORITY 2u +#define TELEMETRY_THREAD_STACK_SIZE 1024u + +#ifdef __cplusplus +} +#endif + +#endif /* CONFIGURATION_H */ +/******************************************************************************* + End of File +*/ diff --git a/examples/controller/src/config/.base/nucleo_f446ze/definitions.h b/examples/controller/src/config/.base/nucleo_f446ze/definitions.h new file mode 100644 index 00000000..6877cf57 --- /dev/null +++ b/examples/controller/src/config/.base/nucleo_f446ze/definitions.h @@ -0,0 +1,180 @@ +/* SPDX-License-Identifier: Apache-2.0 */ +/* + * This file is part of EmbLinkRTOS, a deterministic real-time kernel for microcontrollers. + * Licensed under the Apache License, Version 2.0; see the LICENSE file at the repository root. + */ + +/******************************************************************************* + System Definitions + + File Name: + definitions.h + + Summary: + controller's system definitions on the nucleo_f446ze. + + Description: + The one header the application includes: the kernel's API, the board's + devices, the system's configuration and handles, every task's header, and + the system's two functions, SYS_Initialize() and SYS_Tasks(). + + Generated by emb-hwgen 0.1.0, schema v0, from the system description and the + nucleo_f446ze's. Yours to edit: regenerating merges its changes with yours + (A126): + hw/gen/emb-hwgen.py generate --system examples/controller/system.yaml + + Inputs (SHA-256): + arch/cortex_m/arch.yaml + c5c8e451c09717dee1713d07f8311b6d507e3b4c66c42d93e0ce11da6ec76d6d + boards/st/nucleo_f446ze/board.yaml + 1525ea206692663af174039e30776d6a9a9b30275c9e5c9bdabf14ac0b70aa19 + drivers/bindings.yaml + c06d1a914adb21d0e314c79b3611ac6859eefeac1957d6914cccfc5531ad6ede + examples/controller/controller.conf + f7354e5137f5ea50fbd1d5829ff4f5eb88a044100d871d6a8fd7d976339a75f1 + examples/controller/system.yaml + 2a91f71f1de638aa1ffaa18f0f76fc3ccde44d2560aef98a9a48120775773af3 + soc/st/stm32f4/stm32f4.yaml + 796886c294250aa81151a620d80d0e43b5ee8e1bf53a07d1d7e2c62e95214dbd + soc/st/stm32f4/stm32f446.yaml + f0c9a37f6017c87d0efe215a3561f65494ba52383f2d0c10419b0ab5035f77f2 + soc/st/stm32f4/stm32f446ze.yaml + dabae95e9e4bc984c1a33275966665e0252068e929fe3b430d06589da6bdb6c9 + *******************************************************************************/ + +#ifndef DEFINITIONS_H +#define DEFINITIONS_H + +// ***************************************************************************** +// ***************************************************************************** +// Section: Included Files +// ***************************************************************************** +// ***************************************************************************** + +#include "configuration.h" +#include "controller.h" + +#include + +#include +#include +#include + +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/* Device Information */ +#define DEVICE_NAME "STM32F446ZE" +#define DEVICE_ARCH "cortex-m4f" +#define DEVICE_FAMILY "stm32f4" +#define BOARD_NAME "nucleo_f446ze" + +/* CPU clock frequency */ +#define CPU_CLOCK_FREQUENCY 180000000u + +// ***************************************************************************** +// ***************************************************************************** +// Section: System Functions +// ***************************************************************************** +// ***************************************************************************** + +/******************************************************************************* + Function: + void SYS_Initialize ( void *data ) + + Summary: + Initializes the board, the kernel and every task. + + Description: + This function initializes the board (its clocks, pins and console), then the + kernel (its objects and the EARLY devices), then the application's + interrupts, then each task, in its initial state. The KERNEL devices start + with the kernel, in SYS_Tasks(). + + Precondition: + None. + + Parameters: + data - Unused; NULL. + + Returns: + None. + + Example: + + SYS_Initialize(NULL); + while (true) { + SYS_Tasks(); + } + + + Remarks: + This function is called once, after reset, from main(). +*/ +void SYS_Initialize(void *data); + +/******************************************************************************* + Function: + void SYS_Tasks ( void ) + + Summary: + Starts the kernel: the threads and the tasks run from here. + + Description: + This function starts the KERNEL devices, then the scheduler, which runs the + system's threads and each task's thread. It does not return. + + Precondition: + SYS_Initialize() has run. + + Parameters: + None. + + Returns: + It does not return. + + Example: + + SYS_Initialize(NULL); + while (true) { + SYS_Tasks(); + } + + + Remarks: + Harmony calls its SYS_Tasks() in a loop; this one runs the scheduler and + never comes back. +*/ +void SYS_Tasks(void); + +// ***************************************************************************** +// ***************************************************************************** +// Section: System Objects +// ***************************************************************************** +// ***************************************************************************** + +/* threads: their entries, which the application defines, and their handles */ +void command(void *arg); +void control(void *arg); +void telemetry(void *arg); +extern emb_thread_t control_thread; +extern emb_thread_t command_thread; +extern emb_thread_t telemetry_thread; + +/* objects */ +extern emb_msgq_t samples; +extern emb_msgq_t rx_bytes; +extern emb_mutex_t console; + +#ifdef __cplusplus +} +#endif + +#endif /* DEFINITIONS_H */ +/******************************************************************************* + End of File +*/ diff --git a/examples/controller/generated/nucleo_f446ze/docs/board.md b/examples/controller/src/config/.base/nucleo_f446ze/docs/board.md similarity index 88% rename from examples/controller/generated/nucleo_f446ze/docs/board.md rename to examples/controller/src/config/.base/nucleo_f446ze/docs/board.md index 7d14ec71..076209ea 100644 --- a/examples/controller/generated/nucleo_f446ze/docs/board.md +++ b/examples/controller/src/config/.base/nucleo_f446ze/docs/board.md @@ -64,7 +64,10 @@ In initialization order (SPEC-016 §4). | 16 | dma1.s5 | | 17 | dma1.s6 | | 18 | adc1.global | +| 24 | tim9.global | | 28 | tim2.global | +| 29 | tim3.global | +| 30 | tim4.global | | 31 | i2c1.ev | | 32 | i2c1.er | | 33 | i2c2.ev | @@ -75,6 +78,7 @@ In initialization order (SPEC-016 §4). | 39 | usart3.global | | 41 | rtc.alarm | | 47 | dma1.s7 | +| 50 | tim5.global | | 52 | uart4.global | | 53 | uart5.global | | 56 | dma2.s0 | @@ -99,9 +103,9 @@ Generated by emb-hwgen 0.1.0, schema v0, from: |---|---| | `arch/cortex_m/arch.yaml` | `c5c8e451c09717dee1713d07f8311b6d507e3b4c66c42d93e0ce11da6ec76d6d` | | `boards/st/nucleo_f446ze/board.yaml` | `1525ea206692663af174039e30776d6a9a9b30275c9e5c9bdabf14ac0b70aa19` | -| `drivers/bindings.yaml` | `d3c336ac05548e0addd1faac18f3dff70576d8069f11d89e6a761cf5c6132b49` | +| `drivers/bindings.yaml` | `c06d1a914adb21d0e314c79b3611ac6859eefeac1957d6914cccfc5531ad6ede` | | `examples/controller/controller.conf` | `f7354e5137f5ea50fbd1d5829ff4f5eb88a044100d871d6a8fd7d976339a75f1` | | `examples/controller/system.yaml` | `2a91f71f1de638aa1ffaa18f0f76fc3ccde44d2560aef98a9a48120775773af3` | -| `soc/st/stm32f4/stm32f4.yaml` | `3db4a0a65c9624d865d4ed7fc6354bf95054d0c465b76a2091f06aeac3d7375f` | -| `soc/st/stm32f4/stm32f446.yaml` | `0d5cc7f5fce4c51be71678987720c85c6e76e05473ff8a78ea5035394316c055` | +| `soc/st/stm32f4/stm32f4.yaml` | `796886c294250aa81151a620d80d0e43b5ee8e1bf53a07d1d7e2c62e95214dbd` | +| `soc/st/stm32f4/stm32f446.yaml` | `f0c9a37f6017c87d0efe215a3561f65494ba52383f2d0c10419b0ab5035f77f2` | | `soc/st/stm32f4/stm32f446ze.yaml` | `dabae95e9e4bc984c1a33275966665e0252068e929fe3b430d06589da6bdb6c9` | diff --git a/examples/controller/generated/.base/nucleo_f446ze/docs/build_report.md b/examples/controller/src/config/.base/nucleo_f446ze/docs/build_report.md similarity index 82% rename from examples/controller/generated/.base/nucleo_f446ze/docs/build_report.md rename to examples/controller/src/config/.base/nucleo_f446ze/docs/build_report.md index 34e912cc..feedea47 100644 --- a/examples/controller/generated/.base/nucleo_f446ze/docs/build_report.md +++ b/examples/controller/src/config/.base/nucleo_f446ze/docs/build_report.md @@ -34,9 +34,9 @@ Generated by emb-hwgen 0.1.0, schema v0, from: |---|---| | `arch/cortex_m/arch.yaml` | `c5c8e451c09717dee1713d07f8311b6d507e3b4c66c42d93e0ce11da6ec76d6d` | | `boards/st/nucleo_f446ze/board.yaml` | `1525ea206692663af174039e30776d6a9a9b30275c9e5c9bdabf14ac0b70aa19` | -| `drivers/bindings.yaml` | `d3c336ac05548e0addd1faac18f3dff70576d8069f11d89e6a761cf5c6132b49` | +| `drivers/bindings.yaml` | `c06d1a914adb21d0e314c79b3611ac6859eefeac1957d6914cccfc5531ad6ede` | | `examples/controller/controller.conf` | `f7354e5137f5ea50fbd1d5829ff4f5eb88a044100d871d6a8fd7d976339a75f1` | | `examples/controller/system.yaml` | `2a91f71f1de638aa1ffaa18f0f76fc3ccde44d2560aef98a9a48120775773af3` | -| `soc/st/stm32f4/stm32f4.yaml` | `3db4a0a65c9624d865d4ed7fc6354bf95054d0c465b76a2091f06aeac3d7375f` | -| `soc/st/stm32f4/stm32f446.yaml` | `0d5cc7f5fce4c51be71678987720c85c6e76e05473ff8a78ea5035394316c055` | +| `soc/st/stm32f4/stm32f4.yaml` | `796886c294250aa81151a620d80d0e43b5ee8e1bf53a07d1d7e2c62e95214dbd` | +| `soc/st/stm32f4/stm32f446.yaml` | `f0c9a37f6017c87d0efe215a3561f65494ba52383f2d0c10419b0ab5035f77f2` | | `soc/st/stm32f4/stm32f446ze.yaml` | `dabae95e9e4bc984c1a33275966665e0252068e929fe3b430d06589da6bdb6c9` | diff --git a/examples/controller/generated/nucleo_f446ze/docs/hw.json b/examples/controller/src/config/.base/nucleo_f446ze/docs/hw.json similarity index 86% rename from examples/controller/generated/nucleo_f446ze/docs/hw.json rename to examples/controller/src/config/.base/nucleo_f446ze/docs/hw.json index ac762ccf..7806af6a 100644 --- a/examples/controller/generated/nucleo_f446ze/docs/hw.json +++ b/examples/controller/src/config/.base/nucleo_f446ze/docs/hw.json @@ -116,8 +116,14 @@ "apb1": 45000000, "apb2": 90000000 }, + "bus_timer_hz": { + "ahb1": 180000000, + "apb1": 90000000, + "apb2": 180000000 + }, "bypass": true, "cpu_hz": 180000000, + "fixed_plls": {}, "flash_wait_states": 5, "hclk_hz": 180000000, "pclk1_div": 4, @@ -357,7 +363,7 @@ }, { "path": "drivers/bindings.yaml", - "sha256": "d3c336ac05548e0addd1faac18f3dff70576d8069f11d89e6a761cf5c6132b49" + "sha256": "c06d1a914adb21d0e314c79b3611ac6859eefeac1957d6914cccfc5531ad6ede" }, { "path": "examples/controller/controller.conf", @@ -369,11 +375,11 @@ }, { "path": "soc/st/stm32f4/stm32f4.yaml", - "sha256": "3db4a0a65c9624d865d4ed7fc6354bf95054d0c465b76a2091f06aeac3d7375f" + "sha256": "796886c294250aa81151a620d80d0e43b5ee8e1bf53a07d1d7e2c62e95214dbd" }, { "path": "soc/st/stm32f4/stm32f446.yaml", - "sha256": "0d5cc7f5fce4c51be71678987720c85c6e76e05473ff8a78ea5035394316c055" + "sha256": "f0c9a37f6017c87d0efe215a3561f65494ba52383f2d0c10419b0ab5035f77f2" }, { "path": "soc/st/stm32f4/stm32f446ze.yaml", @@ -384,19 +390,49 @@ "soc": { "alternate_functions": { "PA0": { - "af8": "uart4_tx" + "af1": "tim2_ch1", + "af2": "tim5_ch1", + "af8": "uart4_tx", + "analog": "adc1_in0" }, "PA1": { - "af8": "uart4_rx" + "af1": "tim2_ch2", + "af2": "tim5_ch2", + "af8": "uart4_rx", + "analog": "adc1_in1" }, "PA10": { "af7": "usart1_rx" }, + "PA15": { + "af1": "tim2_ch1" + }, "PA2": { - "af7": "usart2_tx" + "af1": "tim2_ch3", + "af2": "tim5_ch3", + "af7": "usart2_tx", + "analog": "adc1_in2" }, "PA3": { - "af7": "usart2_rx" + "af1": "tim2_ch4", + "af2": "tim5_ch4", + "af7": "usart2_rx", + "analog": "adc1_in3" + }, + "PA4": { + "analog": "adc1_in4" + }, + "PA5": { + "af1": "tim2_ch1", + "analog": "adc1_in5" + }, + "PA6": { + "af2": "tim3_ch1", + "analog": "adc1_in6" + }, + "PA7": { + "af2": "tim3_ch2", + "analog": "adc1_in7" }, "PA8": { "af4": "i2c3_scl" @@ -404,7 +440,16 @@ "PA9": { "af7": "usart1_tx" }, + "PB0": { + "af2": "tim3_ch3", + "analog": "adc1_in8" + }, + "PB1": { + "af2": "tim3_ch4", + "analog": "adc1_in9" + }, "PB10": { + "af1": "tim2_ch3", "af4": "i2c2_scl", "af7": "usart3_tx" }, @@ -417,26 +462,46 @@ "PB15": { "af5": "spi2_mosi" }, + "PB2": { + "af1": "tim2_ch4" + }, "PB3": { + "af1": "tim2_ch2", "af4": "i2c2_sda" }, "PB4": { + "af2": "tim3_ch1", "af4": "i2c3_sda" }, + "PB5": { + "af2": "tim3_ch2" + }, "PB6": { + "af2": "tim4_ch1", "af4": "i2c1_scl", "af7": "usart1_tx" }, "PB7": { + "af2": "tim4_ch2", "af4": "i2c1_sda", "af7": "usart1_rx" }, "PB8": { + "af1": "tim2_ch1", + "af2": "tim4_ch3", "af4": "i2c1_scl" }, "PB9": { + "af1": "tim2_ch2", + "af2": "tim4_ch4", "af4": "i2c1_sda" }, + "PC0": { + "analog": "adc1_in10" + }, + "PC1": { + "analog": "adc1_in11" + }, "PC10": { "af7": "usart3_tx", "af8": "uart4_tx" @@ -449,16 +514,32 @@ "af4": "i2c2_sda", "af8": "uart5_tx" }, + "PC2": { + "analog": "adc1_in12" + }, + "PC3": { + "analog": "adc1_in13" + }, + "PC4": { + "analog": "adc1_in14" + }, "PC5": { - "af7": "usart3_rx" + "af7": "usart3_rx", + "analog": "adc1_in15" }, "PC6": { + "af2": "tim3_ch1", "af8": "usart6_tx" }, "PC7": { + "af2": "tim3_ch2", "af8": "usart6_rx" }, + "PC8": { + "af2": "tim3_ch3" + }, "PC9": { + "af2": "tim3_ch4", "af4": "i2c3_sda" }, "PD2": { @@ -587,6 +668,7 @@ "name": "lse" } ], + "timers_double_when_divided": true, "voltage_scales": [ { "max_hz": 120000000, @@ -731,12 +813,24 @@ "part": "STM32F446ZE", "peripherals": [ { + "adc": { + "bits": 12, + "inputs": 16, + "temperature": 18, + "vrefint": 17 + }, "base": 1073815552, "clock": { "bit": 8, "bus": "apb2" }, "compatible": "st,stm32f4-adc", + "dma_requests": { + "rx": [ + "dma2.s0c0", + "dma2.s4c0" + ] + }, "irqs": [ { "name": "global", @@ -911,12 +1005,14 @@ "size": 1024 }, { + "adc_trigger": 6, "base": 1073741824, "clock": { "bit": 0, "bus": "apb1" }, "compatible": "st,stm32-tim", + "counter_bits": 32, "irqs": [ { "name": "global", @@ -926,6 +1022,76 @@ "name": "tim2", "size": 1024 }, + { + "adc_trigger": 8, + "base": 1073742848, + "clock": { + "bit": 1, + "bus": "apb1" + }, + "compatible": "st,stm32-tim", + "counter_bits": 16, + "irqs": [ + { + "name": "global", + "number": 29 + } + ], + "name": "tim3", + "size": 1024 + }, + { + "base": 1073743872, + "clock": { + "bit": 2, + "bus": "apb1" + }, + "compatible": "st,stm32-tim", + "counter_bits": 16, + "irqs": [ + { + "name": "global", + "number": 30 + } + ], + "name": "tim4", + "size": 1024 + }, + { + "base": 1073744896, + "clock": { + "bit": 3, + "bus": "apb1" + }, + "compatible": "st,stm32-tim", + "counter_bits": 32, + "irqs": [ + { + "name": "global", + "number": 50 + } + ], + "name": "tim5", + "size": 1024 + }, + { + "base": 1073823744, + "clock": { + "bit": 16, + "bus": "apb2" + }, + "compatible": "st,stm32-tim", + "counter_bits": 16, + "irqs": [ + { + "name": "global", + "number": 24 + } + ], + "name": "tim9", + "size": 1024, + "timer_channels": 2 + }, { "base": 1073897472, "clock": { diff --git a/examples/controller/generated/nucleo_f446ze/docs/system.json b/examples/controller/src/config/.base/nucleo_f446ze/docs/system.json similarity index 91% rename from examples/controller/generated/nucleo_f446ze/docs/system.json rename to examples/controller/src/config/.base/nucleo_f446ze/docs/system.json index 85d3ccfb..b6c86084 100644 --- a/examples/controller/generated/nucleo_f446ze/docs/system.json +++ b/examples/controller/src/config/.base/nucleo_f446ze/docs/system.json @@ -33,7 +33,7 @@ }, { "path": "drivers/bindings.yaml", - "sha256": "d3c336ac05548e0addd1faac18f3dff70576d8069f11d89e6a761cf5c6132b49" + "sha256": "c06d1a914adb21d0e314c79b3611ac6859eefeac1957d6914cccfc5531ad6ede" }, { "path": "examples/controller/controller.conf", @@ -45,17 +45,18 @@ }, { "path": "soc/st/stm32f4/stm32f4.yaml", - "sha256": "3db4a0a65c9624d865d4ed7fc6354bf95054d0c465b76a2091f06aeac3d7375f" + "sha256": "796886c294250aa81151a620d80d0e43b5ee8e1bf53a07d1d7e2c62e95214dbd" }, { "path": "soc/st/stm32f4/stm32f446.yaml", - "sha256": "0d5cc7f5fce4c51be71678987720c85c6e76e05473ff8a78ea5035394316c055" + "sha256": "f0c9a37f6017c87d0efe215a3561f65494ba52383f2d0c10419b0ab5035f77f2" }, { "path": "soc/st/stm32f4/stm32f446ze.yaml", "sha256": "dabae95e9e4bc984c1a33275966665e0252068e929fe3b430d06589da6bdb6c9" } ], + "interrupts": [], "name": "controller", "objects": [ { diff --git a/examples/controller/generated/.base/nucleo_f446ze/docs/system.md b/examples/controller/src/config/.base/nucleo_f446ze/docs/system.md similarity index 74% rename from examples/controller/generated/.base/nucleo_f446ze/docs/system.md rename to examples/controller/src/config/.base/nucleo_f446ze/docs/system.md index 52d6716d..40ac80b9 100644 --- a/examples/controller/generated/.base/nucleo_f446ze/docs/system.md +++ b/examples/controller/src/config/.base/nucleo_f446ze/docs/system.md @@ -1,6 +1,6 @@ # controller: the system on nucleo_f446ze -Generated from `examples/controller/system.yaml` (SPEC-014 §5, A125). Profile base, 32 priorities, a minimum stack of 256 bytes. +Generated from `examples/controller/system.yaml` (SPEC-014 §5, A125, A130). Profile base, 32 priorities, a minimum stack of 256 bytes. ## Threads @@ -26,9 +26,9 @@ Generated by emb-hwgen 0.1.0, schema v0, from: |---|---| | `arch/cortex_m/arch.yaml` | `c5c8e451c09717dee1713d07f8311b6d507e3b4c66c42d93e0ce11da6ec76d6d` | | `boards/st/nucleo_f446ze/board.yaml` | `1525ea206692663af174039e30776d6a9a9b30275c9e5c9bdabf14ac0b70aa19` | -| `drivers/bindings.yaml` | `d3c336ac05548e0addd1faac18f3dff70576d8069f11d89e6a761cf5c6132b49` | +| `drivers/bindings.yaml` | `c06d1a914adb21d0e314c79b3611ac6859eefeac1957d6914cccfc5531ad6ede` | | `examples/controller/controller.conf` | `f7354e5137f5ea50fbd1d5829ff4f5eb88a044100d871d6a8fd7d976339a75f1` | | `examples/controller/system.yaml` | `2a91f71f1de638aa1ffaa18f0f76fc3ccde44d2560aef98a9a48120775773af3` | -| `soc/st/stm32f4/stm32f4.yaml` | `3db4a0a65c9624d865d4ed7fc6354bf95054d0c465b76a2091f06aeac3d7375f` | -| `soc/st/stm32f4/stm32f446.yaml` | `0d5cc7f5fce4c51be71678987720c85c6e76e05473ff8a78ea5035394316c055` | +| `soc/st/stm32f4/stm32f4.yaml` | `796886c294250aa81151a620d80d0e43b5ee8e1bf53a07d1d7e2c62e95214dbd` | +| `soc/st/stm32f4/stm32f446.yaml` | `f0c9a37f6017c87d0efe215a3561f65494ba52383f2d0c10419b0ab5035f77f2` | | `soc/st/stm32f4/stm32f446ze.yaml` | `dabae95e9e4bc984c1a33275966665e0252068e929fe3b430d06589da6bdb6c9` | diff --git a/examples/controller/src/config/.base/nucleo_f446ze/initialization.c b/examples/controller/src/config/.base/nucleo_f446ze/initialization.c new file mode 100644 index 00000000..eeca5ffa --- /dev/null +++ b/examples/controller/src/config/.base/nucleo_f446ze/initialization.c @@ -0,0 +1,97 @@ +/* SPDX-License-Identifier: Apache-2.0 */ +/* + * This file is part of EmbLinkRTOS, a deterministic real-time kernel for microcontrollers. + * Licensed under the Apache License, Version 2.0; see the LICENSE file at the repository root. + */ + +/******************************************************************************* + System Initialization File + + File Name: + initialization.c + + Summary: + controller's initialization on the nucleo_f446ze: SYS_Initialize(), and the + system's objects. + + Description: + The system's static definitions, which the kernel creates from its + initialization table when emb_kernel_init() runs (SPEC-001 §6.4), and + SYS_Initialize(), which brings up the board, the kernel, the application's + interrupts and the tasks. + + Generated by emb-hwgen 0.1.0, schema v0, from the system description and the + nucleo_f446ze's. Yours to edit: regenerating merges its changes with yours + (A126): + hw/gen/emb-hwgen.py generate --system examples/controller/system.yaml + + Inputs (SHA-256): + arch/cortex_m/arch.yaml + c5c8e451c09717dee1713d07f8311b6d507e3b4c66c42d93e0ce11da6ec76d6d + boards/st/nucleo_f446ze/board.yaml + 1525ea206692663af174039e30776d6a9a9b30275c9e5c9bdabf14ac0b70aa19 + drivers/bindings.yaml + c06d1a914adb21d0e314c79b3611ac6859eefeac1957d6914cccfc5531ad6ede + examples/controller/controller.conf + f7354e5137f5ea50fbd1d5829ff4f5eb88a044100d871d6a8fd7d976339a75f1 + examples/controller/system.yaml + 2a91f71f1de638aa1ffaa18f0f76fc3ccde44d2560aef98a9a48120775773af3 + soc/st/stm32f4/stm32f4.yaml + 796886c294250aa81151a620d80d0e43b5ee8e1bf53a07d1d7e2c62e95214dbd + soc/st/stm32f4/stm32f446.yaml + f0c9a37f6017c87d0efe215a3561f65494ba52383f2d0c10419b0ab5035f77f2 + soc/st/stm32f4/stm32f446ze.yaml + dabae95e9e4bc984c1a33275966665e0252068e929fe3b430d06589da6bdb6c9 + *******************************************************************************/ + +// ***************************************************************************** +// ***************************************************************************** +// Section: Included Files +// ***************************************************************************** +// ***************************************************************************** + +#include "definitions.h" + +// ***************************************************************************** +// ***************************************************************************** +// Section: System Objects +// ***************************************************************************** +// ***************************************************************************** + +/* the kernel creates each when emb_kernel_init() runs (SPEC-001 §6.4) */ +EMB_THREAD_DEFINE(control_thread, control, NULL, CONTROL_THREAD_PRIORITY, CONTROL_THREAD_STACK_SIZE, + 0u); +EMB_THREAD_DEFINE(command_thread, command, NULL, COMMAND_THREAD_PRIORITY, COMMAND_THREAD_STACK_SIZE, + 0u); +EMB_THREAD_DEFINE(telemetry_thread, telemetry, NULL, TELEMETRY_THREAD_PRIORITY, + TELEMETRY_THREAD_STACK_SIZE, 0u); +EMB_MSGQ_DEFINE(samples, sizeof(sample_t), 8u, 0u); +EMB_MSGQ_DEFINE(rx_bytes, 1u, 64u, 0u); +EMB_MUTEX_DEFINE(console, EMB_MUTEX_INHERIT, 0u, 0u); + +// ***************************************************************************** +// ***************************************************************************** +// Section: System Initialization +// ***************************************************************************** +// ***************************************************************************** + +/******************************************************************************* + Function: + void SYS_Initialize ( void *data ) + + Remarks: + See prototype in definitions.h. + */ +void SYS_Initialize(void *data) +{ + (void)data; + + /* The board: its clocks, pins and console */ + emb_board_init(); + + /* The kernel: its objects, and the EARLY devices */ + emb_kernel_init(); +} +/******************************************************************************* + End of File +*/ diff --git a/examples/controller/generated/.base/nucleo_f446ze/linker/regions.ld b/examples/controller/src/config/.base/nucleo_f446ze/linker/regions.ld similarity index 92% rename from examples/controller/generated/.base/nucleo_f446ze/linker/regions.ld rename to examples/controller/src/config/.base/nucleo_f446ze/linker/regions.ld index 56cec41f..7387746c 100644 --- a/examples/controller/generated/.base/nucleo_f446ze/linker/regions.ld +++ b/examples/controller/src/config/.base/nucleo_f446ze/linker/regions.ld @@ -12,22 +12,24 @@ * * @details * Generated by emb-hwgen 0.1.0, schema v0. Do not edit: change the - * description and run hw/gen/emb-hwgen.py generate --system examples/controller/system.yaml (HW-003). + * description and run + * hw/gen/emb-hwgen.py generate --system examples/controller/system.yaml + * (HW-003). * Inputs (SHA-256): * arch/cortex_m/arch.yaml * c5c8e451c09717dee1713d07f8311b6d507e3b4c66c42d93e0ce11da6ec76d6d * boards/st/nucleo_f446ze/board.yaml * 1525ea206692663af174039e30776d6a9a9b30275c9e5c9bdabf14ac0b70aa19 * drivers/bindings.yaml - * d3c336ac05548e0addd1faac18f3dff70576d8069f11d89e6a761cf5c6132b49 + * c06d1a914adb21d0e314c79b3611ac6859eefeac1957d6914cccfc5531ad6ede * examples/controller/controller.conf * f7354e5137f5ea50fbd1d5829ff4f5eb88a044100d871d6a8fd7d976339a75f1 * examples/controller/system.yaml * 2a91f71f1de638aa1ffaa18f0f76fc3ccde44d2560aef98a9a48120775773af3 * soc/st/stm32f4/stm32f4.yaml - * 3db4a0a65c9624d865d4ed7fc6354bf95054d0c465b76a2091f06aeac3d7375f + * 796886c294250aa81151a620d80d0e43b5ee8e1bf53a07d1d7e2c62e95214dbd * soc/st/stm32f4/stm32f446.yaml - * 0d5cc7f5fce4c51be71678987720c85c6e76e05473ff8a78ea5035394316c055 + * f0c9a37f6017c87d0efe215a3561f65494ba52383f2d0c10419b0ab5035f77f2 * soc/st/stm32f4/stm32f446ze.yaml * dabae95e9e4bc984c1a33275966665e0252068e929fe3b430d06589da6bdb6c9 */ diff --git a/examples/controller/generated/nucleo_f446ze/src/board_pins.c b/examples/controller/src/config/.base/nucleo_f446ze/peripheral/board_pins.c similarity index 85% rename from examples/controller/generated/nucleo_f446ze/src/board_pins.c rename to examples/controller/src/config/.base/nucleo_f446ze/peripheral/board_pins.c index d72b67cd..686965ed 100644 --- a/examples/controller/generated/nucleo_f446ze/src/board_pins.c +++ b/examples/controller/src/config/.base/nucleo_f446ze/peripheral/board_pins.c @@ -11,22 +11,24 @@ * * @details * Generated by emb-hwgen 0.1.0, schema v0. Do not edit: change the - * description and run hw/gen/emb-hwgen.py generate --system examples/controller/system.yaml (HW-003). + * description and run + * hw/gen/emb-hwgen.py generate --system examples/controller/system.yaml + * (HW-003). * Inputs (SHA-256): * arch/cortex_m/arch.yaml * c5c8e451c09717dee1713d07f8311b6d507e3b4c66c42d93e0ce11da6ec76d6d * boards/st/nucleo_f446ze/board.yaml * 1525ea206692663af174039e30776d6a9a9b30275c9e5c9bdabf14ac0b70aa19 * drivers/bindings.yaml - * d3c336ac05548e0addd1faac18f3dff70576d8069f11d89e6a761cf5c6132b49 + * c06d1a914adb21d0e314c79b3611ac6859eefeac1957d6914cccfc5531ad6ede * examples/controller/controller.conf * f7354e5137f5ea50fbd1d5829ff4f5eb88a044100d871d6a8fd7d976339a75f1 * examples/controller/system.yaml * 2a91f71f1de638aa1ffaa18f0f76fc3ccde44d2560aef98a9a48120775773af3 * soc/st/stm32f4/stm32f4.yaml - * 3db4a0a65c9624d865d4ed7fc6354bf95054d0c465b76a2091f06aeac3d7375f + * 796886c294250aa81151a620d80d0e43b5ee8e1bf53a07d1d7e2c62e95214dbd * soc/st/stm32f4/stm32f446.yaml - * 0d5cc7f5fce4c51be71678987720c85c6e76e05473ff8a78ea5035394316c055 + * f0c9a37f6017c87d0efe215a3561f65494ba52383f2d0c10419b0ab5035f77f2 * soc/st/stm32f4/stm32f446ze.yaml * dabae95e9e4bc984c1a33275966665e0252068e929fe3b430d06589da6bdb6c9 */ diff --git a/examples/controller/generated/.base/nucleo_f446ze/include/hw_config.h b/examples/controller/src/config/.base/nucleo_f446ze/peripheral/hw_config.h similarity index 90% rename from examples/controller/generated/.base/nucleo_f446ze/include/hw_config.h rename to examples/controller/src/config/.base/nucleo_f446ze/peripheral/hw_config.h index 55805a63..bd493226 100644 --- a/examples/controller/generated/.base/nucleo_f446ze/include/hw_config.h +++ b/examples/controller/src/config/.base/nucleo_f446ze/peripheral/hw_config.h @@ -10,22 +10,24 @@ * * @details * Generated by emb-hwgen 0.1.0, schema v0. Do not edit: change the - * description and run hw/gen/emb-hwgen.py generate --system examples/controller/system.yaml (HW-003). + * description and run + * hw/gen/emb-hwgen.py generate --system examples/controller/system.yaml + * (HW-003). * Inputs (SHA-256): * arch/cortex_m/arch.yaml * c5c8e451c09717dee1713d07f8311b6d507e3b4c66c42d93e0ce11da6ec76d6d * boards/st/nucleo_f446ze/board.yaml * 1525ea206692663af174039e30776d6a9a9b30275c9e5c9bdabf14ac0b70aa19 * drivers/bindings.yaml - * d3c336ac05548e0addd1faac18f3dff70576d8069f11d89e6a761cf5c6132b49 + * c06d1a914adb21d0e314c79b3611ac6859eefeac1957d6914cccfc5531ad6ede * examples/controller/controller.conf * f7354e5137f5ea50fbd1d5829ff4f5eb88a044100d871d6a8fd7d976339a75f1 * examples/controller/system.yaml * 2a91f71f1de638aa1ffaa18f0f76fc3ccde44d2560aef98a9a48120775773af3 * soc/st/stm32f4/stm32f4.yaml - * 3db4a0a65c9624d865d4ed7fc6354bf95054d0c465b76a2091f06aeac3d7375f + * 796886c294250aa81151a620d80d0e43b5ee8e1bf53a07d1d7e2c62e95214dbd * soc/st/stm32f4/stm32f446.yaml - * 0d5cc7f5fce4c51be71678987720c85c6e76e05473ff8a78ea5035394316c055 + * f0c9a37f6017c87d0efe215a3561f65494ba52383f2d0c10419b0ab5035f77f2 * soc/st/stm32f4/stm32f446ze.yaml * dabae95e9e4bc984c1a33275966665e0252068e929fe3b430d06589da6bdb6c9 */ @@ -168,6 +170,22 @@ #define EMB_HW_TIM2_CLKEN_BIT 0u #define EMB_HW_TIM2_CLKEN_OFFSET 0x40u #define EMB_HW_TIM2_IRQ 28u +#define EMB_HW_TIM3_BASE 0x40000400u +#define EMB_HW_TIM3_CLKEN_BIT 1u +#define EMB_HW_TIM3_CLKEN_OFFSET 0x40u +#define EMB_HW_TIM3_IRQ 29u +#define EMB_HW_TIM4_BASE 0x40000800u +#define EMB_HW_TIM4_CLKEN_BIT 2u +#define EMB_HW_TIM4_CLKEN_OFFSET 0x40u +#define EMB_HW_TIM4_IRQ 30u +#define EMB_HW_TIM5_BASE 0x40000C00u +#define EMB_HW_TIM5_CLKEN_BIT 3u +#define EMB_HW_TIM5_CLKEN_OFFSET 0x40u +#define EMB_HW_TIM5_IRQ 50u +#define EMB_HW_TIM9_BASE 0x40014000u +#define EMB_HW_TIM9_CLKEN_BIT 16u +#define EMB_HW_TIM9_CLKEN_OFFSET 0x44u +#define EMB_HW_TIM9_IRQ 24u #define EMB_HW_UART4_BASE 0x40004C00u #define EMB_HW_UART4_CLKEN_BIT 19u #define EMB_HW_UART4_CLKEN_OFFSET 0x40u diff --git a/examples/controller/generated/nucleo_f446ze/src/soc_devices.c b/examples/controller/src/config/.base/nucleo_f446ze/peripheral/soc_devices.c similarity index 94% rename from examples/controller/generated/nucleo_f446ze/src/soc_devices.c rename to examples/controller/src/config/.base/nucleo_f446ze/peripheral/soc_devices.c index 3a0e078a..b31b092e 100644 --- a/examples/controller/generated/nucleo_f446ze/src/soc_devices.c +++ b/examples/controller/src/config/.base/nucleo_f446ze/peripheral/soc_devices.c @@ -11,22 +11,24 @@ * * @details * Generated by emb-hwgen 0.1.0, schema v0. Do not edit: change the - * description and run hw/gen/emb-hwgen.py generate --system examples/controller/system.yaml (HW-003). + * description and run + * hw/gen/emb-hwgen.py generate --system examples/controller/system.yaml + * (HW-003). * Inputs (SHA-256): * arch/cortex_m/arch.yaml * c5c8e451c09717dee1713d07f8311b6d507e3b4c66c42d93e0ce11da6ec76d6d * boards/st/nucleo_f446ze/board.yaml * 1525ea206692663af174039e30776d6a9a9b30275c9e5c9bdabf14ac0b70aa19 * drivers/bindings.yaml - * d3c336ac05548e0addd1faac18f3dff70576d8069f11d89e6a761cf5c6132b49 + * c06d1a914adb21d0e314c79b3611ac6859eefeac1957d6914cccfc5531ad6ede * examples/controller/controller.conf * f7354e5137f5ea50fbd1d5829ff4f5eb88a044100d871d6a8fd7d976339a75f1 * examples/controller/system.yaml * 2a91f71f1de638aa1ffaa18f0f76fc3ccde44d2560aef98a9a48120775773af3 * soc/st/stm32f4/stm32f4.yaml - * 3db4a0a65c9624d865d4ed7fc6354bf95054d0c465b76a2091f06aeac3d7375f + * 796886c294250aa81151a620d80d0e43b5ee8e1bf53a07d1d7e2c62e95214dbd * soc/st/stm32f4/stm32f446.yaml - * 0d5cc7f5fce4c51be71678987720c85c6e76e05473ff8a78ea5035394316c055 + * f0c9a37f6017c87d0efe215a3561f65494ba52383f2d0c10419b0ab5035f77f2 * soc/st/stm32f4/stm32f446ze.yaml * dabae95e9e4bc984c1a33275966665e0252068e929fe3b430d06589da6bdb6c9 */ diff --git a/examples/controller/generated/nucleo_f446ze/include/soc_devices.h b/examples/controller/src/config/.base/nucleo_f446ze/peripheral/soc_devices.h similarity index 84% rename from examples/controller/generated/nucleo_f446ze/include/soc_devices.h rename to examples/controller/src/config/.base/nucleo_f446ze/peripheral/soc_devices.h index 2bf9c2ac..f59d84b8 100644 --- a/examples/controller/generated/nucleo_f446ze/include/soc_devices.h +++ b/examples/controller/src/config/.base/nucleo_f446ze/peripheral/soc_devices.h @@ -10,22 +10,24 @@ * * @details * Generated by emb-hwgen 0.1.0, schema v0. Do not edit: change the - * description and run hw/gen/emb-hwgen.py generate --system examples/controller/system.yaml (HW-003). + * description and run + * hw/gen/emb-hwgen.py generate --system examples/controller/system.yaml + * (HW-003). * Inputs (SHA-256): * arch/cortex_m/arch.yaml * c5c8e451c09717dee1713d07f8311b6d507e3b4c66c42d93e0ce11da6ec76d6d * boards/st/nucleo_f446ze/board.yaml * 1525ea206692663af174039e30776d6a9a9b30275c9e5c9bdabf14ac0b70aa19 * drivers/bindings.yaml - * d3c336ac05548e0addd1faac18f3dff70576d8069f11d89e6a761cf5c6132b49 + * c06d1a914adb21d0e314c79b3611ac6859eefeac1957d6914cccfc5531ad6ede * examples/controller/controller.conf * f7354e5137f5ea50fbd1d5829ff4f5eb88a044100d871d6a8fd7d976339a75f1 * examples/controller/system.yaml * 2a91f71f1de638aa1ffaa18f0f76fc3ccde44d2560aef98a9a48120775773af3 * soc/st/stm32f4/stm32f4.yaml - * 3db4a0a65c9624d865d4ed7fc6354bf95054d0c465b76a2091f06aeac3d7375f + * 796886c294250aa81151a620d80d0e43b5ee8e1bf53a07d1d7e2c62e95214dbd * soc/st/stm32f4/stm32f446.yaml - * 0d5cc7f5fce4c51be71678987720c85c6e76e05473ff8a78ea5035394316c055 + * f0c9a37f6017c87d0efe215a3561f65494ba52383f2d0c10419b0ab5035f77f2 * soc/st/stm32f4/stm32f446ze.yaml * dabae95e9e4bc984c1a33275966665e0252068e929fe3b430d06589da6bdb6c9 */ diff --git a/examples/controller/src/config/.base/nucleo_f446ze/tasks.c b/examples/controller/src/config/.base/nucleo_f446ze/tasks.c new file mode 100644 index 00000000..44f2a58a --- /dev/null +++ b/examples/controller/src/config/.base/nucleo_f446ze/tasks.c @@ -0,0 +1,74 @@ +/* SPDX-License-Identifier: Apache-2.0 */ +/* + * This file is part of EmbLinkRTOS, a deterministic real-time kernel for microcontrollers. + * Licensed under the Apache License, Version 2.0; see the LICENSE file at the repository root. + */ + +/******************************************************************************* + System Tasks File + + File Name: + tasks.c + + Summary: + controller's tasks on the nucleo_f446ze, and SYS_Tasks(). + + Description: + Each task's thread, queue, dispatch and description: the thread runs the + task runtime, emb_task_run() (SPEC-020), which calls an event task's handler + for each event, and a periodic task's _Tasks() every period, without drift. + SYS_Tasks() starts the kernel. + + Generated by emb-hwgen 0.1.0, schema v0, from the system description and the + nucleo_f446ze's. Yours to edit: regenerating merges its changes with yours + (A126): + hw/gen/emb-hwgen.py generate --system examples/controller/system.yaml + + Inputs (SHA-256): + arch/cortex_m/arch.yaml + c5c8e451c09717dee1713d07f8311b6d507e3b4c66c42d93e0ce11da6ec76d6d + boards/st/nucleo_f446ze/board.yaml + 1525ea206692663af174039e30776d6a9a9b30275c9e5c9bdabf14ac0b70aa19 + drivers/bindings.yaml + c06d1a914adb21d0e314c79b3611ac6859eefeac1957d6914cccfc5531ad6ede + examples/controller/controller.conf + f7354e5137f5ea50fbd1d5829ff4f5eb88a044100d871d6a8fd7d976339a75f1 + examples/controller/system.yaml + 2a91f71f1de638aa1ffaa18f0f76fc3ccde44d2560aef98a9a48120775773af3 + soc/st/stm32f4/stm32f4.yaml + 796886c294250aa81151a620d80d0e43b5ee8e1bf53a07d1d7e2c62e95214dbd + soc/st/stm32f4/stm32f446.yaml + f0c9a37f6017c87d0efe215a3561f65494ba52383f2d0c10419b0ab5035f77f2 + soc/st/stm32f4/stm32f446ze.yaml + dabae95e9e4bc984c1a33275966665e0252068e929fe3b430d06589da6bdb6c9 + *******************************************************************************/ + +// ***************************************************************************** +// ***************************************************************************** +// Section: Included Files +// ***************************************************************************** +// ***************************************************************************** + +#include "definitions.h" + +// ***************************************************************************** +// ***************************************************************************** +// Section: System "Tasks" Routine +// ***************************************************************************** +// ***************************************************************************** + +/******************************************************************************* + Function: + void SYS_Tasks ( void ) + + Remarks: + See prototype in definitions.h. + */ +void SYS_Tasks(void) +{ + /* Start the kernel: the threads and the tasks run from here. It does not return. */ + emb_kernel_start(); +} +/******************************************************************************* + End of File +*/ diff --git a/examples/controller/generated/nucleo_f446re/build/CMakeLists.txt b/examples/controller/src/config/nucleo_f446re/build/CMakeLists.txt similarity index 67% rename from examples/controller/generated/nucleo_f446re/build/CMakeLists.txt rename to examples/controller/src/config/nucleo_f446re/build/CMakeLists.txt index dcfece83..fce90e43 100644 --- a/examples/controller/generated/nucleo_f446re/build/CMakeLists.txt +++ b/examples/controller/src/config/nucleo_f446re/build/CMakeLists.txt @@ -4,24 +4,26 @@ # Licensed under the Apache License, Version 2.0; see the LICENSE file at the repository root. # # Generated by emb-hwgen 0.1.0, schema v0. Do not edit: change the -# description and run hw/gen/emb-hwgen.py generate --system examples/controller/system.yaml (HW-003). +# description and run +# hw/gen/emb-hwgen.py generate --system examples/controller/system.yaml +# (HW-003). # Inputs (SHA-256): # arch/cortex_m/arch.yaml # c5c8e451c09717dee1713d07f8311b6d507e3b4c66c42d93e0ce11da6ec76d6d # boards/st/nucleo_f446re/board.yaml -# d756f3a7f19dc7da82ee3afc168dc54946312c5a9990720953c0fedcdece54ea +# 551c524379751d359bdd87501269d6cab33edf84d212d2f6632ffe9567ec71d0 # drivers/bindings.yaml -# d3c336ac05548e0addd1faac18f3dff70576d8069f11d89e6a761cf5c6132b49 +# c06d1a914adb21d0e314c79b3611ac6859eefeac1957d6914cccfc5531ad6ede # examples/controller/controller.conf # f7354e5137f5ea50fbd1d5829ff4f5eb88a044100d871d6a8fd7d976339a75f1 # examples/controller/system.yaml # 2a91f71f1de638aa1ffaa18f0f76fc3ccde44d2560aef98a9a48120775773af3 # soc/st/stm32f4/stm32f4.yaml -# 3db4a0a65c9624d865d4ed7fc6354bf95054d0c465b76a2091f06aeac3d7375f +# 796886c294250aa81151a620d80d0e43b5ee8e1bf53a07d1d7e2c62e95214dbd # soc/st/stm32f4/stm32f446.yaml -# 0d5cc7f5fce4c51be71678987720c85c6e76e05473ff8a78ea5035394316c055 +# f0c9a37f6017c87d0efe215a3561f65494ba52383f2d0c10419b0ab5035f77f2 # soc/st/stm32f4/stm32f446re.yaml # b9a88d0a94aa17ee83317a3a56f7c194ec1b3107dfb3e82e453122dc1c48f6d4 # The board has no C of its own: its SoC family's board support builds emb_board from -# ../src/board_pins.c and ../include/hw_config.h, and links ../linker/regions.ld. +# ../peripheral/board_pins.c and ../peripheral/hw_config.h, and links ../linker/regions.ld. add_subdirectory("${EMB_SOC_DIR}" soc) diff --git a/examples/controller/generated/nucleo_f446re/build/board.cmake b/examples/controller/src/config/nucleo_f446re/build/board.cmake similarity index 66% rename from examples/controller/generated/nucleo_f446re/build/board.cmake rename to examples/controller/src/config/nucleo_f446re/build/board.cmake index 6ced6ea5..14cfd5e9 100644 --- a/examples/controller/generated/nucleo_f446re/build/board.cmake +++ b/examples/controller/src/config/nucleo_f446re/build/board.cmake @@ -4,22 +4,24 @@ # Licensed under the Apache License, Version 2.0; see the LICENSE file at the repository root. # # Generated by emb-hwgen 0.1.0, schema v0. Do not edit: change the -# description and run hw/gen/emb-hwgen.py generate --system examples/controller/system.yaml (HW-003). +# description and run +# hw/gen/emb-hwgen.py generate --system examples/controller/system.yaml +# (HW-003). # Inputs (SHA-256): # arch/cortex_m/arch.yaml # c5c8e451c09717dee1713d07f8311b6d507e3b4c66c42d93e0ce11da6ec76d6d # boards/st/nucleo_f446re/board.yaml -# d756f3a7f19dc7da82ee3afc168dc54946312c5a9990720953c0fedcdece54ea +# 551c524379751d359bdd87501269d6cab33edf84d212d2f6632ffe9567ec71d0 # drivers/bindings.yaml -# d3c336ac05548e0addd1faac18f3dff70576d8069f11d89e6a761cf5c6132b49 +# c06d1a914adb21d0e314c79b3611ac6859eefeac1957d6914cccfc5531ad6ede # examples/controller/controller.conf # f7354e5137f5ea50fbd1d5829ff4f5eb88a044100d871d6a8fd7d976339a75f1 # examples/controller/system.yaml # 2a91f71f1de638aa1ffaa18f0f76fc3ccde44d2560aef98a9a48120775773af3 # soc/st/stm32f4/stm32f4.yaml -# 3db4a0a65c9624d865d4ed7fc6354bf95054d0c465b76a2091f06aeac3d7375f +# 796886c294250aa81151a620d80d0e43b5ee8e1bf53a07d1d7e2c62e95214dbd # soc/st/stm32f4/stm32f446.yaml -# 0d5cc7f5fce4c51be71678987720c85c6e76e05473ff8a78ea5035394316c055 +# f0c9a37f6017c87d0efe215a3561f65494ba52383f2d0c10419b0ab5035f77f2 # soc/st/stm32f4/stm32f446re.yaml # b9a88d0a94aa17ee83317a3a56f7c194ec1b3107dfb3e82e453122dc1c48f6d4 # nucleo_f446re: STM32F446RE, cortex-m4f at 180 MHz. @@ -28,23 +30,28 @@ set(EMB_BOARD_VARIANT armv7em) set(EMB_BOARD_DEFAULT_PROFILE base) set(EMB_BOARD_C_FLAGS -mcpu=cortex-m4 -mfpu=fpv4-sp-d16 -mfloat-abi=hard) get_filename_component(EMB_BOARD_GENERATED_DIR "${CMAKE_CURRENT_LIST_DIR}/.." ABSOLUTE) -set(EMB_BOARD_CONF "${EMB_BOARD_GENERATED_DIR}/config/board.conf") +set(EMB_BOARD_CONF "${EMB_BOARD_GENERATED_DIR}/build/board.conf") set(EMB_BOARD_HW_JSON "${EMB_BOARD_GENERATED_DIR}/docs/hw.json") set(EMB_BOARD_BUILD_DIR "${CMAKE_CURRENT_LIST_DIR}") # build/CMakeLists.txt +set(EMB_BOARD_SRC_DIR "${EMB_BOARD_GENERATED_DIR}/peripheral") # its pin table and boot block +set(EMB_BOARD_LINKER_DIR "${EMB_BOARD_GENERATED_DIR}/linker") # the SoC family's board support and drivers build this board (build/CMakeLists.txt) set(EMB_SOC_DIR "${EMB_BASE}/soc/st/stm32f4") -set(EMB_BOARD_INCLUDE_DIRS "${EMB_BOARD_GENERATED_DIR}/include" "${EMB_SOC_DIR}/include") +set(EMB_BOARD_INCLUDE_DIRS "${EMB_BOARD_GENERATED_DIR}/peripheral" "${EMB_SOC_DIR}/include") set(EMB_BOARD_RESETS_IN embsim hil) # restart the image with RAM kept (test_crash_reset) set(EMB_BOARD_EMBSIM_TARGET emblink/nucleo_f446re) # EMB_TEST_EMULATOR=embsim set(EMB_BOARD_USART2_DMA tx) set(EMB_BOARD_SPI2_DMA rx tx) set(EMB_BOARD_SPI2_CS_COUNT 1) +set(EMB_BOARD_ADC1_DMA rx) set(EMB_BOARD_EMBSIM_UART_LOOP uart4 "A0,A1") set(EMB_BOARD_EMBSIM_SPI_LOOP spi2 "CN10_26,CN10_28") set(EMB_BOARD_EMBSIM_I2C_LOOP i2c1 i2c2 "D15,D6" "D14,D3") +set(EMB_BOARD_EMBSIM_PWM_LOOP "tim3:0,tim4:0" "D12,D10") +set(EMB_BOARD_EMBSIM_ADC_LOOP "adc1:4,8" "A2,3V3" "A3,GND") # the board's devices (soc_devices.c) and the drivers they use, and only those (SPEC-016 §8) set(EMB_BOARD_DRIVER_SOURCES - "${EMB_BOARD_GENERATED_DIR}/src/soc_devices.c" + "${EMB_BOARD_GENERATED_DIR}/peripheral/soc_devices.c" "${EMB_BASE}/drivers/st/stm32_devices.c" "${EMB_BASE}/drivers/st/stm32_iwdg.c" "${EMB_BASE}/drivers/st/stm32_rtc.c" @@ -53,6 +60,9 @@ set(EMB_BOARD_DRIVER_SOURCES "${EMB_BASE}/drivers/st/stm32_uart.c" "${EMB_BASE}/drivers/st/stm32_spi.c" "${EMB_BASE}/drivers/st/stm32_i2c.c" + "${EMB_BASE}/drivers/st/stm32_tim_counter.c" + "${EMB_BASE}/drivers/st/stm32_tim_pwm.c" + "${EMB_BASE}/drivers/st/stm32_adc.c" ) set(EMB_BOARD_DRIVER_INCLUDE_DIRS "${EMB_BASE}/drivers/st/include" @@ -60,11 +70,11 @@ set(EMB_BOARD_DRIVER_INCLUDE_DIRS # the inputs this directory was generated from, for the configure-time staleness check set(EMB_BOARD_HW_INPUTS "arch/cortex_m/arch.yaml=c5c8e451c09717dee1713d07f8311b6d507e3b4c66c42d93e0ce11da6ec76d6d" - "boards/st/nucleo_f446re/board.yaml=d756f3a7f19dc7da82ee3afc168dc54946312c5a9990720953c0fedcdece54ea" - "drivers/bindings.yaml=d3c336ac05548e0addd1faac18f3dff70576d8069f11d89e6a761cf5c6132b49" + "boards/st/nucleo_f446re/board.yaml=551c524379751d359bdd87501269d6cab33edf84d212d2f6632ffe9567ec71d0" + "drivers/bindings.yaml=c06d1a914adb21d0e314c79b3611ac6859eefeac1957d6914cccfc5531ad6ede" "examples/controller/controller.conf=f7354e5137f5ea50fbd1d5829ff4f5eb88a044100d871d6a8fd7d976339a75f1" "examples/controller/system.yaml=2a91f71f1de638aa1ffaa18f0f76fc3ccde44d2560aef98a9a48120775773af3" - "soc/st/stm32f4/stm32f4.yaml=3db4a0a65c9624d865d4ed7fc6354bf95054d0c465b76a2091f06aeac3d7375f" - "soc/st/stm32f4/stm32f446.yaml=0d5cc7f5fce4c51be71678987720c85c6e76e05473ff8a78ea5035394316c055" + "soc/st/stm32f4/stm32f4.yaml=796886c294250aa81151a620d80d0e43b5ee8e1bf53a07d1d7e2c62e95214dbd" + "soc/st/stm32f4/stm32f446.yaml=f0c9a37f6017c87d0efe215a3561f65494ba52383f2d0c10419b0ab5035f77f2" "soc/st/stm32f4/stm32f446re.yaml=b9a88d0a94aa17ee83317a3a56f7c194ec1b3107dfb3e82e453122dc1c48f6d4" ) diff --git a/examples/controller/generated/nucleo_f446re/config/board.conf b/examples/controller/src/config/nucleo_f446re/build/board.conf similarity index 73% rename from examples/controller/generated/nucleo_f446re/config/board.conf rename to examples/controller/src/config/nucleo_f446re/build/board.conf index 8fdfcf26..9c5e7ddb 100644 --- a/examples/controller/generated/nucleo_f446re/config/board.conf +++ b/examples/controller/src/config/nucleo_f446re/build/board.conf @@ -4,22 +4,24 @@ # Licensed under the Apache License, Version 2.0; see the LICENSE file at the repository root. # # Generated by emb-hwgen 0.1.0, schema v0. Do not edit: change the -# description and run hw/gen/emb-hwgen.py generate --system examples/controller/system.yaml (HW-003). +# description and run +# hw/gen/emb-hwgen.py generate --system examples/controller/system.yaml +# (HW-003). # Inputs (SHA-256): # arch/cortex_m/arch.yaml # c5c8e451c09717dee1713d07f8311b6d507e3b4c66c42d93e0ce11da6ec76d6d # boards/st/nucleo_f446re/board.yaml -# d756f3a7f19dc7da82ee3afc168dc54946312c5a9990720953c0fedcdece54ea +# 551c524379751d359bdd87501269d6cab33edf84d212d2f6632ffe9567ec71d0 # drivers/bindings.yaml -# d3c336ac05548e0addd1faac18f3dff70576d8069f11d89e6a761cf5c6132b49 +# c06d1a914adb21d0e314c79b3611ac6859eefeac1957d6914cccfc5531ad6ede # examples/controller/controller.conf # f7354e5137f5ea50fbd1d5829ff4f5eb88a044100d871d6a8fd7d976339a75f1 # examples/controller/system.yaml # 2a91f71f1de638aa1ffaa18f0f76fc3ccde44d2560aef98a9a48120775773af3 # soc/st/stm32f4/stm32f4.yaml -# 3db4a0a65c9624d865d4ed7fc6354bf95054d0c465b76a2091f06aeac3d7375f +# 796886c294250aa81151a620d80d0e43b5ee8e1bf53a07d1d7e2c62e95214dbd # soc/st/stm32f4/stm32f446.yaml -# 0d5cc7f5fce4c51be71678987720c85c6e76e05473ff8a78ea5035394316c055 +# f0c9a37f6017c87d0efe215a3561f65494ba52383f2d0c10419b0ab5035f77f2 # soc/st/stm32f4/stm32f446re.yaml # b9a88d0a94aa17ee83317a3a56f7c194ec1b3107dfb3e82e453122dc1c48f6d4 # Board defaults for nucleo_f446re. Applied before the profile fragment. diff --git a/examples/controller/src/config/nucleo_f446re/configuration.h b/examples/controller/src/config/nucleo_f446re/configuration.h new file mode 100644 index 00000000..e03b316a --- /dev/null +++ b/examples/controller/src/config/nucleo_f446re/configuration.h @@ -0,0 +1,108 @@ +/* SPDX-License-Identifier: Apache-2.0 */ +/* + * This file is part of EmbLinkRTOS, a deterministic real-time kernel for microcontrollers. + * Licensed under the Apache License, Version 2.0; see the LICENSE file at the repository root. + */ + +/******************************************************************************* + System Configuration Header + + File Name: + configuration.h + + Summary: + The build-time configuration of controller on the nucleo_f446re. + + Description: + The system's settings as macros: the board and its clock, the devices' + settings, each task's and thread's priority and stack, the tasks' periods, + queues and timeouts, and the application's interrupts. The kernel's own + options are 's CONFIG_EMB_*, and the board's hardware + 's EMB_HW_*. + + Generated by emb-hwgen 0.1.0, schema v0, from the system description and the + nucleo_f446re's. Yours to edit: regenerating merges its changes with yours + (A126): + hw/gen/emb-hwgen.py generate --system examples/controller/system.yaml + + Inputs (SHA-256): + arch/cortex_m/arch.yaml + c5c8e451c09717dee1713d07f8311b6d507e3b4c66c42d93e0ce11da6ec76d6d + boards/st/nucleo_f446re/board.yaml + 551c524379751d359bdd87501269d6cab33edf84d212d2f6632ffe9567ec71d0 + drivers/bindings.yaml + c06d1a914adb21d0e314c79b3611ac6859eefeac1957d6914cccfc5531ad6ede + examples/controller/controller.conf + f7354e5137f5ea50fbd1d5829ff4f5eb88a044100d871d6a8fd7d976339a75f1 + examples/controller/system.yaml + 2a91f71f1de638aa1ffaa18f0f76fc3ccde44d2560aef98a9a48120775773af3 + soc/st/stm32f4/stm32f4.yaml + 796886c294250aa81151a620d80d0e43b5ee8e1bf53a07d1d7e2c62e95214dbd + soc/st/stm32f4/stm32f446.yaml + f0c9a37f6017c87d0efe215a3561f65494ba52383f2d0c10419b0ab5035f77f2 + soc/st/stm32f4/stm32f446re.yaml + b9a88d0a94aa17ee83317a3a56f7c194ec1b3107dfb3e82e453122dc1c48f6d4 + *******************************************************************************/ + +#ifndef CONFIGURATION_H +#define CONFIGURATION_H + +// ***************************************************************************** +// ***************************************************************************** +// Section: Included Files +// ***************************************************************************** +// ***************************************************************************** + +#include + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +// ***************************************************************************** +// ***************************************************************************** +// Section: System Configuration +// ***************************************************************************** +// ***************************************************************************** + +#define SYS_CPU_CLOCK_HZ 180000000u +#define SYS_TICK_NS CONFIG_EMB_TICK_NS +#define SYS_PRIORITY_COUNT CONFIG_EMB_PRIORITY_COUNT + +// ***************************************************************************** +// ***************************************************************************** +// Section: Driver Configuration +// ***************************************************************************** +// ***************************************************************************** + +#define DRV_USART2_BAUD 115200u +#define DRV_UART4_BAUD 115200u + +// ***************************************************************************** +// ***************************************************************************** +// Section: Application Configuration +// ***************************************************************************** +// ***************************************************************************** + +/* control_thread: a thread */ +#define CONTROL_THREAD_PRIORITY 6u +#define CONTROL_THREAD_STACK_SIZE 1024u + +/* command_thread: a thread */ +#define COMMAND_THREAD_PRIORITY 4u +#define COMMAND_THREAD_STACK_SIZE 1024u + +/* telemetry_thread: a thread */ +#define TELEMETRY_THREAD_PRIORITY 2u +#define TELEMETRY_THREAD_STACK_SIZE 1024u + +#ifdef __cplusplus +} +#endif + +#endif /* CONFIGURATION_H */ +/******************************************************************************* + End of File +*/ diff --git a/examples/controller/src/config/nucleo_f446re/definitions.h b/examples/controller/src/config/nucleo_f446re/definitions.h new file mode 100644 index 00000000..9bee12bf --- /dev/null +++ b/examples/controller/src/config/nucleo_f446re/definitions.h @@ -0,0 +1,180 @@ +/* SPDX-License-Identifier: Apache-2.0 */ +/* + * This file is part of EmbLinkRTOS, a deterministic real-time kernel for microcontrollers. + * Licensed under the Apache License, Version 2.0; see the LICENSE file at the repository root. + */ + +/******************************************************************************* + System Definitions + + File Name: + definitions.h + + Summary: + controller's system definitions on the nucleo_f446re. + + Description: + The one header the application includes: the kernel's API, the board's + devices, the system's configuration and handles, every task's header, and + the system's two functions, SYS_Initialize() and SYS_Tasks(). + + Generated by emb-hwgen 0.1.0, schema v0, from the system description and the + nucleo_f446re's. Yours to edit: regenerating merges its changes with yours + (A126): + hw/gen/emb-hwgen.py generate --system examples/controller/system.yaml + + Inputs (SHA-256): + arch/cortex_m/arch.yaml + c5c8e451c09717dee1713d07f8311b6d507e3b4c66c42d93e0ce11da6ec76d6d + boards/st/nucleo_f446re/board.yaml + 551c524379751d359bdd87501269d6cab33edf84d212d2f6632ffe9567ec71d0 + drivers/bindings.yaml + c06d1a914adb21d0e314c79b3611ac6859eefeac1957d6914cccfc5531ad6ede + examples/controller/controller.conf + f7354e5137f5ea50fbd1d5829ff4f5eb88a044100d871d6a8fd7d976339a75f1 + examples/controller/system.yaml + 2a91f71f1de638aa1ffaa18f0f76fc3ccde44d2560aef98a9a48120775773af3 + soc/st/stm32f4/stm32f4.yaml + 796886c294250aa81151a620d80d0e43b5ee8e1bf53a07d1d7e2c62e95214dbd + soc/st/stm32f4/stm32f446.yaml + f0c9a37f6017c87d0efe215a3561f65494ba52383f2d0c10419b0ab5035f77f2 + soc/st/stm32f4/stm32f446re.yaml + b9a88d0a94aa17ee83317a3a56f7c194ec1b3107dfb3e82e453122dc1c48f6d4 + *******************************************************************************/ + +#ifndef DEFINITIONS_H +#define DEFINITIONS_H + +// ***************************************************************************** +// ***************************************************************************** +// Section: Included Files +// ***************************************************************************** +// ***************************************************************************** + +#include "configuration.h" +#include "controller.h" + +#include + +#include +#include +#include + +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/* Device Information */ +#define DEVICE_NAME "STM32F446RE" +#define DEVICE_ARCH "cortex-m4f" +#define DEVICE_FAMILY "stm32f4" +#define BOARD_NAME "nucleo_f446re" + +/* CPU clock frequency */ +#define CPU_CLOCK_FREQUENCY 180000000u + +// ***************************************************************************** +// ***************************************************************************** +// Section: System Functions +// ***************************************************************************** +// ***************************************************************************** + +/******************************************************************************* + Function: + void SYS_Initialize ( void *data ) + + Summary: + Initializes the board, the kernel and every task. + + Description: + This function initializes the board (its clocks, pins and console), then the + kernel (its objects and the EARLY devices), then the application's + interrupts, then each task, in its initial state. The KERNEL devices start + with the kernel, in SYS_Tasks(). + + Precondition: + None. + + Parameters: + data - Unused; NULL. + + Returns: + None. + + Example: + + SYS_Initialize(NULL); + while (true) { + SYS_Tasks(); + } + + + Remarks: + This function is called once, after reset, from main(). +*/ +void SYS_Initialize(void *data); + +/******************************************************************************* + Function: + void SYS_Tasks ( void ) + + Summary: + Starts the kernel: the threads and the tasks run from here. + + Description: + This function starts the KERNEL devices, then the scheduler, which runs the + system's threads and each task's thread. It does not return. + + Precondition: + SYS_Initialize() has run. + + Parameters: + None. + + Returns: + It does not return. + + Example: + + SYS_Initialize(NULL); + while (true) { + SYS_Tasks(); + } + + + Remarks: + Harmony calls its SYS_Tasks() in a loop; this one runs the scheduler and + never comes back. +*/ +void SYS_Tasks(void); + +// ***************************************************************************** +// ***************************************************************************** +// Section: System Objects +// ***************************************************************************** +// ***************************************************************************** + +/* threads: their entries, which the application defines, and their handles */ +void command(void *arg); +void control(void *arg); +void telemetry(void *arg); +extern emb_thread_t control_thread; +extern emb_thread_t command_thread; +extern emb_thread_t telemetry_thread; + +/* objects */ +extern emb_msgq_t samples; +extern emb_msgq_t rx_bytes; +extern emb_mutex_t console; + +#ifdef __cplusplus +} +#endif + +#endif /* DEFINITIONS_H */ +/******************************************************************************* + End of File +*/ diff --git a/examples/controller/generated/.base/nucleo_f446re/docs/board.md b/examples/controller/src/config/nucleo_f446re/docs/board.md similarity index 79% rename from examples/controller/generated/.base/nucleo_f446re/docs/board.md rename to examples/controller/src/config/nucleo_f446re/docs/board.md index e10ce1cd..10b4c634 100644 --- a/examples/controller/generated/.base/nucleo_f446re/docs/board.md +++ b/examples/controller/src/config/nucleo_f446re/docs/board.md @@ -35,8 +35,12 @@ The STM32F446RE at 180 MHz from the PLL, its input the ST-LINK's 8 MHz MCO on PH | PA1 | `pins.uart4.rx` | af8 (uart4_rx) | | PA2 | `pins.usart2.tx` | af7 (usart2_tx) | | PA3 | `pins.usart2.rx` | af7 (usart2_rx) | +| PA4 | `pins.adc1.in4` | analog | | PA5 | `leds.user` | output | +| PA6 | `pins.tim3.ch1` | af2 (tim3_ch1) | +| PB0 | `pins.adc1.in8` | analog | | PB3 | `pins.i2c2.sda` | af4 (i2c2_sda) | +| PB6 | `pins.tim4.ch1` | af2 (tim4_ch1) | | PB8 | `pins.i2c1.scl` | af4 (i2c1_scl) | | PB9 | `pins.i2c1.sda` | af4 (i2c1_sda) | | PB10 | `pins.i2c2.scl` | af4 (i2c2_scl) | @@ -58,6 +62,7 @@ In initialization order (SPEC-016 §4). | rtc | `st,stm32f4-rtc` | rtc | EARLY | - | | flash | `st,stm32f4-flash (flash_if)` | flash | EARLY | - | | dma1 | `st,stm32-dma` | dma | EARLY | rcc | +| dma2 | `st,stm32-dma` | dma | EARLY | rcc | | gpiob | `st,stm32-gpio` | gpio | EARLY | rcc | | gpioc | `st,stm32-gpio` | gpio | EARLY | rcc | | usart2 | `st,stm32-usart` | uart | EARLY | dma1, rcc | @@ -65,6 +70,11 @@ In initialization order (SPEC-016 §4). | spi2 | `st,stm32-spi` | spi | KERNEL | dma1, rcc | | i2c1 | `st,stm32-i2c` | i2c | KERNEL | rcc | | i2c2 | `st,stm32-i2c` | i2c | KERNEL | rcc | +| tim5 | `st,stm32-tim` | counter | KERNEL | rcc | +| tim9 | `st,stm32-tim` | counter | KERNEL | rcc | +| tim3 | `st,stm32-tim` | pwm | KERNEL | rcc | +| tim4 | `st,stm32-tim` | pwm | KERNEL | rcc | +| adc1 | `st,stm32f4-adc` | adc | KERNEL | dma2, rcc | ## Interrupt lines @@ -81,7 +91,10 @@ In initialization order (SPEC-016 §4). | 16 | dma1.s5 | | 17 | dma1.s6 | | 18 | adc1.global | +| 24 | tim9.global | | 28 | tim2.global | +| 29 | tim3.global | +| 30 | tim4.global | | 31 | i2c1.ev | | 32 | i2c1.er | | 33 | i2c2.ev | @@ -92,6 +105,7 @@ In initialization order (SPEC-016 §4). | 39 | usart3.global | | 41 | rtc.alarm | | 47 | dma1.s7 | +| 50 | tim5.global | | 52 | uart4.global | | 53 | uart5.global | | 56 | dma2.s0 | @@ -115,10 +129,10 @@ Generated by emb-hwgen 0.1.0, schema v0, from: | Input | SHA-256 | |---|---| | `arch/cortex_m/arch.yaml` | `c5c8e451c09717dee1713d07f8311b6d507e3b4c66c42d93e0ce11da6ec76d6d` | -| `boards/st/nucleo_f446re/board.yaml` | `d756f3a7f19dc7da82ee3afc168dc54946312c5a9990720953c0fedcdece54ea` | -| `drivers/bindings.yaml` | `d3c336ac05548e0addd1faac18f3dff70576d8069f11d89e6a761cf5c6132b49` | +| `boards/st/nucleo_f446re/board.yaml` | `551c524379751d359bdd87501269d6cab33edf84d212d2f6632ffe9567ec71d0` | +| `drivers/bindings.yaml` | `c06d1a914adb21d0e314c79b3611ac6859eefeac1957d6914cccfc5531ad6ede` | | `examples/controller/controller.conf` | `f7354e5137f5ea50fbd1d5829ff4f5eb88a044100d871d6a8fd7d976339a75f1` | | `examples/controller/system.yaml` | `2a91f71f1de638aa1ffaa18f0f76fc3ccde44d2560aef98a9a48120775773af3` | -| `soc/st/stm32f4/stm32f4.yaml` | `3db4a0a65c9624d865d4ed7fc6354bf95054d0c465b76a2091f06aeac3d7375f` | -| `soc/st/stm32f4/stm32f446.yaml` | `0d5cc7f5fce4c51be71678987720c85c6e76e05473ff8a78ea5035394316c055` | +| `soc/st/stm32f4/stm32f4.yaml` | `796886c294250aa81151a620d80d0e43b5ee8e1bf53a07d1d7e2c62e95214dbd` | +| `soc/st/stm32f4/stm32f446.yaml` | `f0c9a37f6017c87d0efe215a3561f65494ba52383f2d0c10419b0ab5035f77f2` | | `soc/st/stm32f4/stm32f446re.yaml` | `b9a88d0a94aa17ee83317a3a56f7c194ec1b3107dfb3e82e453122dc1c48f6d4` | diff --git a/examples/controller/generated/nucleo_f446re/docs/build_report.md b/examples/controller/src/config/nucleo_f446re/docs/build_report.md similarity index 72% rename from examples/controller/generated/nucleo_f446re/docs/build_report.md rename to examples/controller/src/config/nucleo_f446re/docs/build_report.md index 7dcfaf8d..9aafeb41 100644 --- a/examples/controller/generated/nucleo_f446re/docs/build_report.md +++ b/examples/controller/src/config/nucleo_f446re/docs/build_report.md @@ -31,10 +31,10 @@ Generated by emb-hwgen 0.1.0, schema v0, from: | Input | SHA-256 | |---|---| | `arch/cortex_m/arch.yaml` | `c5c8e451c09717dee1713d07f8311b6d507e3b4c66c42d93e0ce11da6ec76d6d` | -| `boards/st/nucleo_f446re/board.yaml` | `d756f3a7f19dc7da82ee3afc168dc54946312c5a9990720953c0fedcdece54ea` | -| `drivers/bindings.yaml` | `d3c336ac05548e0addd1faac18f3dff70576d8069f11d89e6a761cf5c6132b49` | +| `boards/st/nucleo_f446re/board.yaml` | `551c524379751d359bdd87501269d6cab33edf84d212d2f6632ffe9567ec71d0` | +| `drivers/bindings.yaml` | `c06d1a914adb21d0e314c79b3611ac6859eefeac1957d6914cccfc5531ad6ede` | | `examples/controller/controller.conf` | `f7354e5137f5ea50fbd1d5829ff4f5eb88a044100d871d6a8fd7d976339a75f1` | | `examples/controller/system.yaml` | `2a91f71f1de638aa1ffaa18f0f76fc3ccde44d2560aef98a9a48120775773af3` | -| `soc/st/stm32f4/stm32f4.yaml` | `3db4a0a65c9624d865d4ed7fc6354bf95054d0c465b76a2091f06aeac3d7375f` | -| `soc/st/stm32f4/stm32f446.yaml` | `0d5cc7f5fce4c51be71678987720c85c6e76e05473ff8a78ea5035394316c055` | +| `soc/st/stm32f4/stm32f4.yaml` | `796886c294250aa81151a620d80d0e43b5ee8e1bf53a07d1d7e2c62e95214dbd` | +| `soc/st/stm32f4/stm32f446.yaml` | `f0c9a37f6017c87d0efe215a3561f65494ba52383f2d0c10419b0ab5035f77f2` | | `soc/st/stm32f4/stm32f446re.yaml` | `b9a88d0a94aa17ee83317a3a56f7c194ec1b3107dfb3e82e453122dc1c48f6d4` | diff --git a/examples/controller/generated/nucleo_f446re/docs/hw.json b/examples/controller/src/config/nucleo_f446re/docs/hw.json similarity index 77% rename from examples/controller/generated/nucleo_f446re/docs/hw.json rename to examples/controller/src/config/nucleo_f446re/docs/hw.json index fab062e8..5276124d 100644 --- a/examples/controller/generated/nucleo_f446re/docs/hw.json +++ b/examples/controller/src/config/nucleo_f446re/docs/hw.json @@ -57,6 +57,10 @@ "doc": "DMA1: SPI2's transfers, and the console's writes", "name": "dma1" }, + { + "doc": "DMA2: ADC1's samples", + "name": "dma2" + }, { "doc": "SPI2's chip select, PB12", "name": "gpiob" @@ -96,6 +100,36 @@ "baud": 115200, "doc": "a spare UART; the HIL suite's loopback wires A0 (PA0, TX) to A1 (PA1, RX)", "name": "uart4" + }, + { + "class": "counter", + "doc": "TIM5, 32 bits at 1 MHz: the counter class's (A129); TIM2 stays the controller's ADC trigger", + "name": "tim5" + }, + { + "class": "counter", + "doc": "TIM9, 16 bits at 1 MHz: it wraps every 65.5 ms, so its tests widen the count on the board", + "name": "tim9" + }, + { + "class": "pwm", + "doc": "TIM3, PWM out on channel 1, D12 (PA6); the HIL suite wires it to D10", + "name": "tim3" + }, + { + "class": "pwm", + "doc": "TIM4, PWM capture on channel 1, D10 (PB6)", + "name": "tim4" + }, + { + "cal": "factory_cal", + "common": "adc_common", + "dma": [ + "rx" + ], + "doc": "ADC1, paced by TIM2 (the controller's trigger, which it drives by hand), A2 (PA4, input 4) and A3 (PB0, input 8); the HIL suite wires A2 to 3V3 and A3 to GND", + "name": "adc1", + "trigger": "tim2" } ], "doc": "The STM32F446RE at 180 MHz from the PLL, its input the ST-LINK's 8 MHz MCO on PH0 in HSE bypass (solder bridges SB16 and SB50 as shipped). The console is USART2, which the ST-LINK carries as its virtual COM port.", @@ -132,6 +166,10 @@ } }, "pins": { + "adc1": { + "in4": "PA4", + "in8": "PB0" + }, "i2c1": { "scl": "PB8.af4", "sda": "PB9.af4" @@ -145,6 +183,12 @@ "mosi": "PB15.af5", "sck": "PB13.af5" }, + "tim3": { + "ch1": "PA6.af2" + }, + "tim4": { + "ch1": "PB6.af2" + }, "uart4": { "rx": "PA1.af8", "tx": "PA0.af8" @@ -186,6 +230,35 @@ ] ], "peer": "i2c2" + }, + { + "channels": [ + 0, + 0 + ], + "device": "tim3", + "peer": "tim4", + "ports": [ + "D12", + "D10" + ] + }, + { + "channels": [ + 4, + 8 + ], + "device": "adc1", + "nets": [ + [ + "A2", + "3V3" + ], + [ + "A3", + "GND" + ] + ] } ], "resets_in": [ @@ -208,8 +281,14 @@ "apb1": 45000000, "apb2": 90000000 }, + "bus_timer_hz": { + "ahb1": 180000000, + "apb1": 90000000, + "apb2": 180000000 + }, "bypass": true, "cpu_hz": 180000000, + "fixed_plls": {}, "flash_wait_states": 5, "hclk_hz": 180000000, "pclk1_div": 4, @@ -357,6 +436,30 @@ "name": "dma1", "peripheral": "dma1" }, + { + "class": "dma", + "compatible": "st,stm32-dma", + "deps": [ + "rcc" + ], + "fields": { + "base": 1073898496, + "clken_bit": 22, + "clken_offset": 48, + "irq0": 56, + "irq1": 57, + "irq2": 58, + "irq3": 59, + "irq4": 60, + "irq5": 68, + "irq6": 69, + "irq7": 70, + "memory": true + }, + "level": "early", + "name": "dma2", + "peripheral": "dma2" + }, { "class": "gpio", "compatible": "st,stm32-gpio", @@ -519,6 +622,119 @@ "level": "kernel", "name": "i2c2", "peripheral": "i2c2" + }, + { + "class": "counter", + "compatible": "st,stm32-tim", + "deps": [ + "rcc" + ], + "fields": { + "base": 1073744896, + "bits": 32, + "channels": 4, + "clken_bit": 3, + "clken_offset": 64, + "clock_hz": 90000000, + "irq": 50, + "rate_hz": 1000000 + }, + "level": "kernel", + "name": "tim5", + "peripheral": "tim5" + }, + { + "class": "counter", + "compatible": "st,stm32-tim", + "deps": [ + "rcc" + ], + "fields": { + "base": 1073823744, + "bits": 16, + "channels": 2, + "clken_bit": 16, + "clken_offset": 68, + "clock_hz": 180000000, + "irq": 24, + "rate_hz": 1000000 + }, + "level": "kernel", + "name": "tim9", + "peripheral": "tim9" + }, + { + "class": "pwm", + "compatible": "st,stm32-tim", + "deps": [ + "rcc" + ], + "fields": { + "base": 1073742848, + "bits": 16, + "channels": 4, + "clken_bit": 1, + "clken_offset": 64, + "clock_hz": 90000000, + "irq": 29 + }, + "level": "kernel", + "name": "tim3", + "peripheral": "tim3" + }, + { + "class": "pwm", + "compatible": "st,stm32-tim", + "deps": [ + "rcc" + ], + "fields": { + "base": 1073743872, + "bits": 16, + "channels": 4, + "clken_bit": 2, + "clken_offset": 64, + "clock_hz": 90000000, + "irq": 30 + }, + "level": "kernel", + "name": "tim4", + "peripheral": "tim4" + }, + { + "class": "adc", + "compatible": "st,stm32f4-adc", + "deps": [ + "dma2", + "rcc" + ], + "fields": { + "base": 1073815552, + "bits": 12, + "calibration": 536836650, + "clken_bit": 8, + "clken_offset": 68, + "clock_hz": 90000000, + "common": 1073816320, + "dma_rx": { + "dma": "dma2", + "request": 0, + "stream": 0 + }, + "inputs": 16, + "irq": 18, + "temperature": 18, + "trigger": 1073741824, + "trigger_clken_bit": 0, + "trigger_clken_offset": 64, + "trigger_hz": 90000000, + "trigger_select": 6, + "vref_mv": 3300, + "vrefint": 17 + }, + "level": "kernel", + "name": "adc1", + "peripheral": "adc1" } ], "kconfig": { @@ -608,6 +824,15 @@ "port": "A", "signal": "usart2_rx" }, + { + "gpio": "gpioa", + "mode": "analog", + "number": 4, + "owner": "pins.adc1.in4", + "pin": "PA4", + "port": "A", + "signal": "adc1_in4" + }, { "gpio": "gpioa", "mode": "output", @@ -616,6 +841,25 @@ "pin": "PA5", "port": "A" }, + { + "af": 2, + "gpio": "gpioa", + "mode": "af", + "number": 6, + "owner": "pins.tim3.ch1", + "pin": "PA6", + "port": "A", + "signal": "tim3_ch1" + }, + { + "gpio": "gpiob", + "mode": "analog", + "number": 0, + "owner": "pins.adc1.in8", + "pin": "PB0", + "port": "B", + "signal": "adc1_in8" + }, { "af": 4, "gpio": "gpiob", @@ -626,6 +870,16 @@ "port": "B", "signal": "i2c2_sda" }, + { + "af": 2, + "gpio": "gpiob", + "mode": "af", + "number": 6, + "owner": "pins.tim4.ch1", + "pin": "PB6", + "port": "B", + "signal": "tim4_ch1" + }, { "af": 4, "gpio": "gpiob", @@ -726,11 +980,11 @@ }, { "path": "boards/st/nucleo_f446re/board.yaml", - "sha256": "d756f3a7f19dc7da82ee3afc168dc54946312c5a9990720953c0fedcdece54ea" + "sha256": "551c524379751d359bdd87501269d6cab33edf84d212d2f6632ffe9567ec71d0" }, { "path": "drivers/bindings.yaml", - "sha256": "d3c336ac05548e0addd1faac18f3dff70576d8069f11d89e6a761cf5c6132b49" + "sha256": "c06d1a914adb21d0e314c79b3611ac6859eefeac1957d6914cccfc5531ad6ede" }, { "path": "examples/controller/controller.conf", @@ -742,11 +996,11 @@ }, { "path": "soc/st/stm32f4/stm32f4.yaml", - "sha256": "3db4a0a65c9624d865d4ed7fc6354bf95054d0c465b76a2091f06aeac3d7375f" + "sha256": "796886c294250aa81151a620d80d0e43b5ee8e1bf53a07d1d7e2c62e95214dbd" }, { "path": "soc/st/stm32f4/stm32f446.yaml", - "sha256": "0d5cc7f5fce4c51be71678987720c85c6e76e05473ff8a78ea5035394316c055" + "sha256": "f0c9a37f6017c87d0efe215a3561f65494ba52383f2d0c10419b0ab5035f77f2" }, { "path": "soc/st/stm32f4/stm32f446re.yaml", @@ -757,19 +1011,49 @@ "soc": { "alternate_functions": { "PA0": { - "af8": "uart4_tx" + "af1": "tim2_ch1", + "af2": "tim5_ch1", + "af8": "uart4_tx", + "analog": "adc1_in0" }, "PA1": { - "af8": "uart4_rx" + "af1": "tim2_ch2", + "af2": "tim5_ch2", + "af8": "uart4_rx", + "analog": "adc1_in1" }, "PA10": { "af7": "usart1_rx" }, + "PA15": { + "af1": "tim2_ch1" + }, "PA2": { - "af7": "usart2_tx" + "af1": "tim2_ch3", + "af2": "tim5_ch3", + "af7": "usart2_tx", + "analog": "adc1_in2" }, "PA3": { - "af7": "usart2_rx" + "af1": "tim2_ch4", + "af2": "tim5_ch4", + "af7": "usart2_rx", + "analog": "adc1_in3" + }, + "PA4": { + "analog": "adc1_in4" + }, + "PA5": { + "af1": "tim2_ch1", + "analog": "adc1_in5" + }, + "PA6": { + "af2": "tim3_ch1", + "analog": "adc1_in6" + }, + "PA7": { + "af2": "tim3_ch2", + "analog": "adc1_in7" }, "PA8": { "af4": "i2c3_scl" @@ -777,7 +1061,16 @@ "PA9": { "af7": "usart1_tx" }, + "PB0": { + "af2": "tim3_ch3", + "analog": "adc1_in8" + }, + "PB1": { + "af2": "tim3_ch4", + "analog": "adc1_in9" + }, "PB10": { + "af1": "tim2_ch3", "af4": "i2c2_scl", "af7": "usart3_tx" }, @@ -790,26 +1083,46 @@ "PB15": { "af5": "spi2_mosi" }, + "PB2": { + "af1": "tim2_ch4" + }, "PB3": { + "af1": "tim2_ch2", "af4": "i2c2_sda" }, "PB4": { + "af2": "tim3_ch1", "af4": "i2c3_sda" }, + "PB5": { + "af2": "tim3_ch2" + }, "PB6": { + "af2": "tim4_ch1", "af4": "i2c1_scl", "af7": "usart1_tx" }, "PB7": { + "af2": "tim4_ch2", "af4": "i2c1_sda", "af7": "usart1_rx" }, "PB8": { + "af1": "tim2_ch1", + "af2": "tim4_ch3", "af4": "i2c1_scl" }, "PB9": { + "af1": "tim2_ch2", + "af2": "tim4_ch4", "af4": "i2c1_sda" }, + "PC0": { + "analog": "adc1_in10" + }, + "PC1": { + "analog": "adc1_in11" + }, "PC10": { "af7": "usart3_tx", "af8": "uart4_tx" @@ -822,16 +1135,32 @@ "af4": "i2c2_sda", "af8": "uart5_tx" }, + "PC2": { + "analog": "adc1_in12" + }, + "PC3": { + "analog": "adc1_in13" + }, + "PC4": { + "analog": "adc1_in14" + }, "PC5": { - "af7": "usart3_rx" + "af7": "usart3_rx", + "analog": "adc1_in15" }, "PC6": { + "af2": "tim3_ch1", "af8": "usart6_tx" }, "PC7": { + "af2": "tim3_ch2", "af8": "usart6_rx" }, + "PC8": { + "af2": "tim3_ch3" + }, "PC9": { + "af2": "tim3_ch4", "af4": "i2c3_sda" }, "PD2": { @@ -960,6 +1289,7 @@ "name": "lse" } ], + "timers_double_when_divided": true, "voltage_scales": [ { "max_hz": 120000000, @@ -1101,12 +1431,24 @@ "part": "STM32F446RE", "peripherals": [ { + "adc": { + "bits": 12, + "inputs": 16, + "temperature": 18, + "vrefint": 17 + }, "base": 1073815552, "clock": { "bit": 8, "bus": "apb2" }, "compatible": "st,stm32f4-adc", + "dma_requests": { + "rx": [ + "dma2.s0c0", + "dma2.s4c0" + ] + }, "irqs": [ { "name": "global", @@ -1281,12 +1623,14 @@ "size": 1024 }, { + "adc_trigger": 6, "base": 1073741824, "clock": { "bit": 0, "bus": "apb1" }, "compatible": "st,stm32-tim", + "counter_bits": 32, "irqs": [ { "name": "global", @@ -1296,6 +1640,76 @@ "name": "tim2", "size": 1024 }, + { + "adc_trigger": 8, + "base": 1073742848, + "clock": { + "bit": 1, + "bus": "apb1" + }, + "compatible": "st,stm32-tim", + "counter_bits": 16, + "irqs": [ + { + "name": "global", + "number": 29 + } + ], + "name": "tim3", + "size": 1024 + }, + { + "base": 1073743872, + "clock": { + "bit": 2, + "bus": "apb1" + }, + "compatible": "st,stm32-tim", + "counter_bits": 16, + "irqs": [ + { + "name": "global", + "number": 30 + } + ], + "name": "tim4", + "size": 1024 + }, + { + "base": 1073744896, + "clock": { + "bit": 3, + "bus": "apb1" + }, + "compatible": "st,stm32-tim", + "counter_bits": 32, + "irqs": [ + { + "name": "global", + "number": 50 + } + ], + "name": "tim5", + "size": 1024 + }, + { + "base": 1073823744, + "clock": { + "bit": 16, + "bus": "apb2" + }, + "compatible": "st,stm32-tim", + "counter_bits": 16, + "irqs": [ + { + "name": "global", + "number": 24 + } + ], + "name": "tim9", + "size": 1024, + "timer_channels": 2 + }, { "base": 1073897472, "clock": { diff --git a/examples/controller/generated/nucleo_f446re/docs/system.json b/examples/controller/src/config/nucleo_f446re/docs/system.json similarity index 88% rename from examples/controller/generated/nucleo_f446re/docs/system.json rename to examples/controller/src/config/nucleo_f446re/docs/system.json index 49f25147..7e15d7f8 100644 --- a/examples/controller/generated/nucleo_f446re/docs/system.json +++ b/examples/controller/src/config/nucleo_f446re/docs/system.json @@ -29,11 +29,11 @@ }, { "path": "boards/st/nucleo_f446re/board.yaml", - "sha256": "d756f3a7f19dc7da82ee3afc168dc54946312c5a9990720953c0fedcdece54ea" + "sha256": "551c524379751d359bdd87501269d6cab33edf84d212d2f6632ffe9567ec71d0" }, { "path": "drivers/bindings.yaml", - "sha256": "d3c336ac05548e0addd1faac18f3dff70576d8069f11d89e6a761cf5c6132b49" + "sha256": "c06d1a914adb21d0e314c79b3611ac6859eefeac1957d6914cccfc5531ad6ede" }, { "path": "examples/controller/controller.conf", @@ -45,17 +45,18 @@ }, { "path": "soc/st/stm32f4/stm32f4.yaml", - "sha256": "3db4a0a65c9624d865d4ed7fc6354bf95054d0c465b76a2091f06aeac3d7375f" + "sha256": "796886c294250aa81151a620d80d0e43b5ee8e1bf53a07d1d7e2c62e95214dbd" }, { "path": "soc/st/stm32f4/stm32f446.yaml", - "sha256": "0d5cc7f5fce4c51be71678987720c85c6e76e05473ff8a78ea5035394316c055" + "sha256": "f0c9a37f6017c87d0efe215a3561f65494ba52383f2d0c10419b0ab5035f77f2" }, { "path": "soc/st/stm32f4/stm32f446re.yaml", "sha256": "b9a88d0a94aa17ee83317a3a56f7c194ec1b3107dfb3e82e453122dc1c48f6d4" } ], + "interrupts": [], "name": "controller", "objects": [ { diff --git a/examples/controller/generated/.base/nucleo_f446re/docs/system.md b/examples/controller/src/config/nucleo_f446re/docs/system.md similarity index 67% rename from examples/controller/generated/.base/nucleo_f446re/docs/system.md rename to examples/controller/src/config/nucleo_f446re/docs/system.md index a5e5dc33..0a683ded 100644 --- a/examples/controller/generated/.base/nucleo_f446re/docs/system.md +++ b/examples/controller/src/config/nucleo_f446re/docs/system.md @@ -1,6 +1,6 @@ # controller: the system on nucleo_f446re -Generated from `examples/controller/system.yaml` (SPEC-014 §5, A125). Profile base, 32 priorities, a minimum stack of 256 bytes. +Generated from `examples/controller/system.yaml` (SPEC-014 §5, A125, A130). Profile base, 32 priorities, a minimum stack of 256 bytes. ## Threads @@ -25,10 +25,10 @@ Generated by emb-hwgen 0.1.0, schema v0, from: | Input | SHA-256 | |---|---| | `arch/cortex_m/arch.yaml` | `c5c8e451c09717dee1713d07f8311b6d507e3b4c66c42d93e0ce11da6ec76d6d` | -| `boards/st/nucleo_f446re/board.yaml` | `d756f3a7f19dc7da82ee3afc168dc54946312c5a9990720953c0fedcdece54ea` | -| `drivers/bindings.yaml` | `d3c336ac05548e0addd1faac18f3dff70576d8069f11d89e6a761cf5c6132b49` | +| `boards/st/nucleo_f446re/board.yaml` | `551c524379751d359bdd87501269d6cab33edf84d212d2f6632ffe9567ec71d0` | +| `drivers/bindings.yaml` | `c06d1a914adb21d0e314c79b3611ac6859eefeac1957d6914cccfc5531ad6ede` | | `examples/controller/controller.conf` | `f7354e5137f5ea50fbd1d5829ff4f5eb88a044100d871d6a8fd7d976339a75f1` | | `examples/controller/system.yaml` | `2a91f71f1de638aa1ffaa18f0f76fc3ccde44d2560aef98a9a48120775773af3` | -| `soc/st/stm32f4/stm32f4.yaml` | `3db4a0a65c9624d865d4ed7fc6354bf95054d0c465b76a2091f06aeac3d7375f` | -| `soc/st/stm32f4/stm32f446.yaml` | `0d5cc7f5fce4c51be71678987720c85c6e76e05473ff8a78ea5035394316c055` | +| `soc/st/stm32f4/stm32f4.yaml` | `796886c294250aa81151a620d80d0e43b5ee8e1bf53a07d1d7e2c62e95214dbd` | +| `soc/st/stm32f4/stm32f446.yaml` | `f0c9a37f6017c87d0efe215a3561f65494ba52383f2d0c10419b0ab5035f77f2` | | `soc/st/stm32f4/stm32f446re.yaml` | `b9a88d0a94aa17ee83317a3a56f7c194ec1b3107dfb3e82e453122dc1c48f6d4` | diff --git a/examples/controller/src/config/nucleo_f446re/initialization.c b/examples/controller/src/config/nucleo_f446re/initialization.c new file mode 100644 index 00000000..55ad3ffb --- /dev/null +++ b/examples/controller/src/config/nucleo_f446re/initialization.c @@ -0,0 +1,97 @@ +/* SPDX-License-Identifier: Apache-2.0 */ +/* + * This file is part of EmbLinkRTOS, a deterministic real-time kernel for microcontrollers. + * Licensed under the Apache License, Version 2.0; see the LICENSE file at the repository root. + */ + +/******************************************************************************* + System Initialization File + + File Name: + initialization.c + + Summary: + controller's initialization on the nucleo_f446re: SYS_Initialize(), and the + system's objects. + + Description: + The system's static definitions, which the kernel creates from its + initialization table when emb_kernel_init() runs (SPEC-001 §6.4), and + SYS_Initialize(), which brings up the board, the kernel, the application's + interrupts and the tasks. + + Generated by emb-hwgen 0.1.0, schema v0, from the system description and the + nucleo_f446re's. Yours to edit: regenerating merges its changes with yours + (A126): + hw/gen/emb-hwgen.py generate --system examples/controller/system.yaml + + Inputs (SHA-256): + arch/cortex_m/arch.yaml + c5c8e451c09717dee1713d07f8311b6d507e3b4c66c42d93e0ce11da6ec76d6d + boards/st/nucleo_f446re/board.yaml + 551c524379751d359bdd87501269d6cab33edf84d212d2f6632ffe9567ec71d0 + drivers/bindings.yaml + c06d1a914adb21d0e314c79b3611ac6859eefeac1957d6914cccfc5531ad6ede + examples/controller/controller.conf + f7354e5137f5ea50fbd1d5829ff4f5eb88a044100d871d6a8fd7d976339a75f1 + examples/controller/system.yaml + 2a91f71f1de638aa1ffaa18f0f76fc3ccde44d2560aef98a9a48120775773af3 + soc/st/stm32f4/stm32f4.yaml + 796886c294250aa81151a620d80d0e43b5ee8e1bf53a07d1d7e2c62e95214dbd + soc/st/stm32f4/stm32f446.yaml + f0c9a37f6017c87d0efe215a3561f65494ba52383f2d0c10419b0ab5035f77f2 + soc/st/stm32f4/stm32f446re.yaml + b9a88d0a94aa17ee83317a3a56f7c194ec1b3107dfb3e82e453122dc1c48f6d4 + *******************************************************************************/ + +// ***************************************************************************** +// ***************************************************************************** +// Section: Included Files +// ***************************************************************************** +// ***************************************************************************** + +#include "definitions.h" + +// ***************************************************************************** +// ***************************************************************************** +// Section: System Objects +// ***************************************************************************** +// ***************************************************************************** + +/* the kernel creates each when emb_kernel_init() runs (SPEC-001 §6.4) */ +EMB_THREAD_DEFINE(control_thread, control, NULL, CONTROL_THREAD_PRIORITY, CONTROL_THREAD_STACK_SIZE, + 0u); +EMB_THREAD_DEFINE(command_thread, command, NULL, COMMAND_THREAD_PRIORITY, COMMAND_THREAD_STACK_SIZE, + 0u); +EMB_THREAD_DEFINE(telemetry_thread, telemetry, NULL, TELEMETRY_THREAD_PRIORITY, + TELEMETRY_THREAD_STACK_SIZE, 0u); +EMB_MSGQ_DEFINE(samples, sizeof(sample_t), 8u, 0u); +EMB_MSGQ_DEFINE(rx_bytes, 1u, 64u, 0u); +EMB_MUTEX_DEFINE(console, EMB_MUTEX_INHERIT, 0u, 0u); + +// ***************************************************************************** +// ***************************************************************************** +// Section: System Initialization +// ***************************************************************************** +// ***************************************************************************** + +/******************************************************************************* + Function: + void SYS_Initialize ( void *data ) + + Remarks: + See prototype in definitions.h. + */ +void SYS_Initialize(void *data) +{ + (void)data; + + /* The board: its clocks, pins and console */ + emb_board_init(); + + /* The kernel: its objects, and the EARLY devices */ + emb_kernel_init(); +} +/******************************************************************************* + End of File +*/ diff --git a/examples/controller/generated/nucleo_f446re/linker/regions.ld b/examples/controller/src/config/nucleo_f446re/linker/regions.ld similarity index 90% rename from examples/controller/generated/nucleo_f446re/linker/regions.ld rename to examples/controller/src/config/nucleo_f446re/linker/regions.ld index f9c6cae1..7297204a 100644 --- a/examples/controller/generated/nucleo_f446re/linker/regions.ld +++ b/examples/controller/src/config/nucleo_f446re/linker/regions.ld @@ -12,22 +12,24 @@ * * @details * Generated by emb-hwgen 0.1.0, schema v0. Do not edit: change the - * description and run hw/gen/emb-hwgen.py generate --system examples/controller/system.yaml (HW-003). + * description and run + * hw/gen/emb-hwgen.py generate --system examples/controller/system.yaml + * (HW-003). * Inputs (SHA-256): * arch/cortex_m/arch.yaml * c5c8e451c09717dee1713d07f8311b6d507e3b4c66c42d93e0ce11da6ec76d6d * boards/st/nucleo_f446re/board.yaml - * d756f3a7f19dc7da82ee3afc168dc54946312c5a9990720953c0fedcdece54ea + * 551c524379751d359bdd87501269d6cab33edf84d212d2f6632ffe9567ec71d0 * drivers/bindings.yaml - * d3c336ac05548e0addd1faac18f3dff70576d8069f11d89e6a761cf5c6132b49 + * c06d1a914adb21d0e314c79b3611ac6859eefeac1957d6914cccfc5531ad6ede * examples/controller/controller.conf * f7354e5137f5ea50fbd1d5829ff4f5eb88a044100d871d6a8fd7d976339a75f1 * examples/controller/system.yaml * 2a91f71f1de638aa1ffaa18f0f76fc3ccde44d2560aef98a9a48120775773af3 * soc/st/stm32f4/stm32f4.yaml - * 3db4a0a65c9624d865d4ed7fc6354bf95054d0c465b76a2091f06aeac3d7375f + * 796886c294250aa81151a620d80d0e43b5ee8e1bf53a07d1d7e2c62e95214dbd * soc/st/stm32f4/stm32f446.yaml - * 0d5cc7f5fce4c51be71678987720c85c6e76e05473ff8a78ea5035394316c055 + * f0c9a37f6017c87d0efe215a3561f65494ba52383f2d0c10419b0ab5035f77f2 * soc/st/stm32f4/stm32f446re.yaml * b9a88d0a94aa17ee83317a3a56f7c194ec1b3107dfb3e82e453122dc1c48f6d4 */ diff --git a/examples/controller/generated/.base/nucleo_f446re/src/board_pins.c b/examples/controller/src/config/nucleo_f446re/peripheral/board_pins.c similarity index 76% rename from examples/controller/generated/.base/nucleo_f446re/src/board_pins.c rename to examples/controller/src/config/nucleo_f446re/peripheral/board_pins.c index b951f740..259594e9 100644 --- a/examples/controller/generated/.base/nucleo_f446re/src/board_pins.c +++ b/examples/controller/src/config/nucleo_f446re/peripheral/board_pins.c @@ -11,22 +11,24 @@ * * @details * Generated by emb-hwgen 0.1.0, schema v0. Do not edit: change the - * description and run hw/gen/emb-hwgen.py generate --system examples/controller/system.yaml (HW-003). + * description and run + * hw/gen/emb-hwgen.py generate --system examples/controller/system.yaml + * (HW-003). * Inputs (SHA-256): * arch/cortex_m/arch.yaml * c5c8e451c09717dee1713d07f8311b6d507e3b4c66c42d93e0ce11da6ec76d6d * boards/st/nucleo_f446re/board.yaml - * d756f3a7f19dc7da82ee3afc168dc54946312c5a9990720953c0fedcdece54ea + * 551c524379751d359bdd87501269d6cab33edf84d212d2f6632ffe9567ec71d0 * drivers/bindings.yaml - * d3c336ac05548e0addd1faac18f3dff70576d8069f11d89e6a761cf5c6132b49 + * c06d1a914adb21d0e314c79b3611ac6859eefeac1957d6914cccfc5531ad6ede * examples/controller/controller.conf * f7354e5137f5ea50fbd1d5829ff4f5eb88a044100d871d6a8fd7d976339a75f1 * examples/controller/system.yaml * 2a91f71f1de638aa1ffaa18f0f76fc3ccde44d2560aef98a9a48120775773af3 * soc/st/stm32f4/stm32f4.yaml - * 3db4a0a65c9624d865d4ed7fc6354bf95054d0c465b76a2091f06aeac3d7375f + * 796886c294250aa81151a620d80d0e43b5ee8e1bf53a07d1d7e2c62e95214dbd * soc/st/stm32f4/stm32f446.yaml - * 0d5cc7f5fce4c51be71678987720c85c6e76e05473ff8a78ea5035394316c055 + * f0c9a37f6017c87d0efe215a3561f65494ba52383f2d0c10419b0ab5035f77f2 * soc/st/stm32f4/stm32f446re.yaml * b9a88d0a94aa17ee83317a3a56f7c194ec1b3107dfb3e82e453122dc1c48f6d4 */ @@ -42,10 +44,18 @@ const emb_stm32_pin_t emb_board_pins[] = { {EMB_STM32_PORT(A), 2u, EMB_STM32_PIN_AF, 7u, 0u, 0u}, /* PA3: pins.usart2.rx (usart2_rx) */ {EMB_STM32_PORT(A), 3u, EMB_STM32_PIN_AF, 7u, 0u, 0u}, + /* PA4: pins.adc1.in4 (adc1_in4) */ + {EMB_STM32_PORT(A), 4u, EMB_STM32_PIN_ANALOG, 0u, 0u, 0u}, /* PA5: leds.user (output) */ {EMB_STM32_PORT(A), 5u, EMB_STM32_PIN_OUTPUT, 0u, 0u, 0u}, + /* PA6: pins.tim3.ch1 (tim3_ch1) */ + {EMB_STM32_PORT(A), 6u, EMB_STM32_PIN_AF, 2u, 0u, 0u}, + /* PB0: pins.adc1.in8 (adc1_in8) */ + {EMB_STM32_PORT(B), 0u, EMB_STM32_PIN_ANALOG, 0u, 0u, 0u}, /* PB3: pins.i2c2.sda (i2c2_sda) */ {EMB_STM32_PORT(B), 3u, EMB_STM32_PIN_AF, 4u, 0u, EMB_STM32_PIN_I2C}, + /* PB6: pins.tim4.ch1 (tim4_ch1) */ + {EMB_STM32_PORT(B), 6u, EMB_STM32_PIN_AF, 2u, 0u, 0u}, /* PB8: pins.i2c1.scl (i2c1_scl) */ {EMB_STM32_PORT(B), 8u, EMB_STM32_PIN_AF, 4u, 0u, EMB_STM32_PIN_I2C}, /* PB9: pins.i2c1.sda (i2c1_sda) */ diff --git a/examples/controller/generated/nucleo_f446re/include/hw_config.h b/examples/controller/src/config/nucleo_f446re/peripheral/hw_config.h similarity index 89% rename from examples/controller/generated/nucleo_f446re/include/hw_config.h rename to examples/controller/src/config/nucleo_f446re/peripheral/hw_config.h index 0d1d80dc..88c9c738 100644 --- a/examples/controller/generated/nucleo_f446re/include/hw_config.h +++ b/examples/controller/src/config/nucleo_f446re/peripheral/hw_config.h @@ -10,22 +10,24 @@ * * @details * Generated by emb-hwgen 0.1.0, schema v0. Do not edit: change the - * description and run hw/gen/emb-hwgen.py generate --system examples/controller/system.yaml (HW-003). + * description and run + * hw/gen/emb-hwgen.py generate --system examples/controller/system.yaml + * (HW-003). * Inputs (SHA-256): * arch/cortex_m/arch.yaml * c5c8e451c09717dee1713d07f8311b6d507e3b4c66c42d93e0ce11da6ec76d6d * boards/st/nucleo_f446re/board.yaml - * d756f3a7f19dc7da82ee3afc168dc54946312c5a9990720953c0fedcdece54ea + * 551c524379751d359bdd87501269d6cab33edf84d212d2f6632ffe9567ec71d0 * drivers/bindings.yaml - * d3c336ac05548e0addd1faac18f3dff70576d8069f11d89e6a761cf5c6132b49 + * c06d1a914adb21d0e314c79b3611ac6859eefeac1957d6914cccfc5531ad6ede * examples/controller/controller.conf * f7354e5137f5ea50fbd1d5829ff4f5eb88a044100d871d6a8fd7d976339a75f1 * examples/controller/system.yaml * 2a91f71f1de638aa1ffaa18f0f76fc3ccde44d2560aef98a9a48120775773af3 * soc/st/stm32f4/stm32f4.yaml - * 3db4a0a65c9624d865d4ed7fc6354bf95054d0c465b76a2091f06aeac3d7375f + * 796886c294250aa81151a620d80d0e43b5ee8e1bf53a07d1d7e2c62e95214dbd * soc/st/stm32f4/stm32f446.yaml - * 0d5cc7f5fce4c51be71678987720c85c6e76e05473ff8a78ea5035394316c055 + * f0c9a37f6017c87d0efe215a3561f65494ba52383f2d0c10419b0ab5035f77f2 * soc/st/stm32f4/stm32f446re.yaml * b9a88d0a94aa17ee83317a3a56f7c194ec1b3107dfb3e82e453122dc1c48f6d4 */ @@ -168,6 +170,22 @@ #define EMB_HW_TIM2_CLKEN_BIT 0u #define EMB_HW_TIM2_CLKEN_OFFSET 0x40u #define EMB_HW_TIM2_IRQ 28u +#define EMB_HW_TIM3_BASE 0x40000400u +#define EMB_HW_TIM3_CLKEN_BIT 1u +#define EMB_HW_TIM3_CLKEN_OFFSET 0x40u +#define EMB_HW_TIM3_IRQ 29u +#define EMB_HW_TIM4_BASE 0x40000800u +#define EMB_HW_TIM4_CLKEN_BIT 2u +#define EMB_HW_TIM4_CLKEN_OFFSET 0x40u +#define EMB_HW_TIM4_IRQ 30u +#define EMB_HW_TIM5_BASE 0x40000C00u +#define EMB_HW_TIM5_CLKEN_BIT 3u +#define EMB_HW_TIM5_CLKEN_OFFSET 0x40u +#define EMB_HW_TIM5_IRQ 50u +#define EMB_HW_TIM9_BASE 0x40014000u +#define EMB_HW_TIM9_CLKEN_BIT 16u +#define EMB_HW_TIM9_CLKEN_OFFSET 0x44u +#define EMB_HW_TIM9_IRQ 24u #define EMB_HW_UART4_BASE 0x40004C00u #define EMB_HW_UART4_CLKEN_BIT 19u #define EMB_HW_UART4_CLKEN_OFFSET 0x40u diff --git a/examples/controller/generated/nucleo_f446re/src/soc_devices.c b/examples/controller/src/config/nucleo_f446re/peripheral/soc_devices.c similarity index 63% rename from examples/controller/generated/nucleo_f446re/src/soc_devices.c rename to examples/controller/src/config/nucleo_f446re/peripheral/soc_devices.c index 2f624384..8268a2a8 100644 --- a/examples/controller/generated/nucleo_f446re/src/soc_devices.c +++ b/examples/controller/src/config/nucleo_f446re/peripheral/soc_devices.c @@ -11,22 +11,24 @@ * * @details * Generated by emb-hwgen 0.1.0, schema v0. Do not edit: change the - * description and run hw/gen/emb-hwgen.py generate --system examples/controller/system.yaml (HW-003). + * description and run + * hw/gen/emb-hwgen.py generate --system examples/controller/system.yaml + * (HW-003). * Inputs (SHA-256): * arch/cortex_m/arch.yaml * c5c8e451c09717dee1713d07f8311b6d507e3b4c66c42d93e0ce11da6ec76d6d * boards/st/nucleo_f446re/board.yaml - * d756f3a7f19dc7da82ee3afc168dc54946312c5a9990720953c0fedcdece54ea + * 551c524379751d359bdd87501269d6cab33edf84d212d2f6632ffe9567ec71d0 * drivers/bindings.yaml - * d3c336ac05548e0addd1faac18f3dff70576d8069f11d89e6a761cf5c6132b49 + * c06d1a914adb21d0e314c79b3611ac6859eefeac1957d6914cccfc5531ad6ede * examples/controller/controller.conf * f7354e5137f5ea50fbd1d5829ff4f5eb88a044100d871d6a8fd7d976339a75f1 * examples/controller/system.yaml * 2a91f71f1de638aa1ffaa18f0f76fc3ccde44d2560aef98a9a48120775773af3 * soc/st/stm32f4/stm32f4.yaml - * 3db4a0a65c9624d865d4ed7fc6354bf95054d0c465b76a2091f06aeac3d7375f + * 796886c294250aa81151a620d80d0e43b5ee8e1bf53a07d1d7e2c62e95214dbd * soc/st/stm32f4/stm32f446.yaml - * 0d5cc7f5fce4c51be71678987720c85c6e76e05473ff8a78ea5035394316c055 + * f0c9a37f6017c87d0efe215a3561f65494ba52383f2d0c10419b0ab5035f77f2 * soc/st/stm32f4/stm32f446re.yaml * b9a88d0a94aa17ee83317a3a56f7c194ec1b3107dfb3e82e453122dc1c48f6d4 */ @@ -170,6 +172,36 @@ const emb_device_t emb_dev_dma1 = { .dep_count = 1u, }; +/* dma2: st,stm32-dma, dma, EARLY */ +static const emb_stm32_dma_config_t dma2_config = { + .base = 0x40026400u, /* peripheral.base */ + .clken_offset = 0x00000030u, /* peripheral.clock.enable_offset */ + .clken_bit = 22u, /* peripheral.clock.bit */ + .irq0 = 56u, /* peripheral.irqs.s0 */ + .irq1 = 57u, /* peripheral.irqs.s1 */ + .irq2 = 58u, /* peripheral.irqs.s2 */ + .irq3 = 59u, /* peripheral.irqs.s3 */ + .irq4 = 60u, /* peripheral.irqs.s4 */ + .irq5 = 68u, /* peripheral.irqs.s5 */ + .irq6 = 69u, /* peripheral.irqs.s6 */ + .irq7 = 70u, /* peripheral.irqs.s7 */ + .memory = true, /* peripheral.dma.memory */ +}; +static emb_device_state_t dma2_state; +static emb_stm32_dma_data_t dma2_data; +static const emb_device_t *const dma2_deps[] = {&emb_dev_rcc}; +const emb_device_t emb_dev_dma2 = { + .name = "dma2", + .api = &emb_stm32_dma_api.dev, + .config = &dma2_config, + .state = &dma2_state, + .data = &dma2_data, + .deps = dma2_deps, + .class_id = EMB_DRV_CLASS_DMA, + .level = EMB_DEVICE_EARLY, + .dep_count = 1u, +}; + /* gpiob: st,stm32-gpio, gpio, EARLY */ static const emb_stm32_gpio_config_t gpiob_config = { .base = 0x40020400u, /* peripheral.base */ @@ -343,6 +375,144 @@ const emb_device_t emb_dev_i2c2 = { .dep_count = 1u, }; +/* tim5: st,stm32-tim, counter, KERNEL */ +static const emb_stm32_tim_config_t tim5_config = { + .base = 0x40000C00u, /* peripheral.base */ + .clock_hz = 90000000u, /* peripheral.timer_clock_hz */ + .rate_hz = 1000000u, /* device.rate_hz, its default */ + .clken_offset = 0x00000040u, /* peripheral.clock.enable_offset */ + .clken_bit = 3u, /* peripheral.clock.bit */ + .irq = 50u, /* peripheral.irqs.global */ + .bits = 32u, /* peripheral.counter_bits */ + .channels = 4u, /* peripheral.timer_channels, its default */ +}; +static emb_device_state_t tim5_state; +static emb_stm32_counter_data_t tim5_data; +static const emb_device_t *const tim5_deps[] = {&emb_dev_rcc}; +const emb_device_t emb_dev_tim5 = { + .name = "tim5", + .api = &emb_stm32_counter_api.dev, + .config = &tim5_config, + .state = &tim5_state, + .data = &tim5_data, + .deps = tim5_deps, + .class_id = EMB_DRV_CLASS_COUNTER, + .level = EMB_DEVICE_KERNEL, + .dep_count = 1u, +}; + +/* tim9: st,stm32-tim, counter, KERNEL */ +static const emb_stm32_tim_config_t tim9_config = { + .base = 0x40014000u, /* peripheral.base */ + .clock_hz = 180000000u, /* peripheral.timer_clock_hz */ + .rate_hz = 1000000u, /* device.rate_hz, its default */ + .clken_offset = 0x00000044u, /* peripheral.clock.enable_offset */ + .clken_bit = 16u, /* peripheral.clock.bit */ + .irq = 24u, /* peripheral.irqs.global */ + .bits = 16u, /* peripheral.counter_bits */ + .channels = 2u, /* peripheral.timer_channels */ +}; +static emb_device_state_t tim9_state; +static emb_stm32_counter_data_t tim9_data; +static const emb_device_t *const tim9_deps[] = {&emb_dev_rcc}; +const emb_device_t emb_dev_tim9 = { + .name = "tim9", + .api = &emb_stm32_counter_api.dev, + .config = &tim9_config, + .state = &tim9_state, + .data = &tim9_data, + .deps = tim9_deps, + .class_id = EMB_DRV_CLASS_COUNTER, + .level = EMB_DEVICE_KERNEL, + .dep_count = 1u, +}; + +/* tim3: st,stm32-tim, pwm, KERNEL */ +static const emb_stm32_tim_config_t tim3_config = { + .base = 0x40000400u, /* peripheral.base */ + .clock_hz = 90000000u, /* peripheral.timer_clock_hz */ + .clken_offset = 0x00000040u, /* peripheral.clock.enable_offset */ + .clken_bit = 1u, /* peripheral.clock.bit */ + .irq = 29u, /* peripheral.irqs.global */ + .bits = 16u, /* peripheral.counter_bits */ + .channels = 4u, /* peripheral.timer_channels, its default */ +}; +static emb_device_state_t tim3_state; +static emb_stm32_pwm_data_t tim3_data; +static const emb_device_t *const tim3_deps[] = {&emb_dev_rcc}; +const emb_device_t emb_dev_tim3 = { + .name = "tim3", + .api = &emb_stm32_pwm_api.dev, + .config = &tim3_config, + .state = &tim3_state, + .data = &tim3_data, + .deps = tim3_deps, + .class_id = EMB_DRV_CLASS_PWM, + .level = EMB_DEVICE_KERNEL, + .dep_count = 1u, +}; + +/* tim4: st,stm32-tim, pwm, KERNEL */ +static const emb_stm32_tim_config_t tim4_config = { + .base = 0x40000800u, /* peripheral.base */ + .clock_hz = 90000000u, /* peripheral.timer_clock_hz */ + .clken_offset = 0x00000040u, /* peripheral.clock.enable_offset */ + .clken_bit = 2u, /* peripheral.clock.bit */ + .irq = 30u, /* peripheral.irqs.global */ + .bits = 16u, /* peripheral.counter_bits */ + .channels = 4u, /* peripheral.timer_channels, its default */ +}; +static emb_device_state_t tim4_state; +static emb_stm32_pwm_data_t tim4_data; +static const emb_device_t *const tim4_deps[] = {&emb_dev_rcc}; +const emb_device_t emb_dev_tim4 = { + .name = "tim4", + .api = &emb_stm32_pwm_api.dev, + .config = &tim4_config, + .state = &tim4_state, + .data = &tim4_data, + .deps = tim4_deps, + .class_id = EMB_DRV_CLASS_PWM, + .level = EMB_DEVICE_KERNEL, + .dep_count = 1u, +}; + +/* adc1: st,stm32f4-adc, adc, KERNEL */ +static const emb_stm32_adc_config_t adc1_config = { + .base = 0x40012000u, /* peripheral.base */ + .common = 0x40012300u, /* takes.common.base */ + .calibration = 0x1FFF7A2Au, /* takes.cal.base */ + .trigger = 0x40000000u, /* takes.trigger.base */ + .trigger_hz = 90000000u, /* takes.trigger.timer_clock_hz */ + .trigger_clken_offset = 0x00000040u, /* takes.trigger.clock.enable_offset */ + .trigger_clken_bit = 0u, /* takes.trigger.clock.bit */ + .trigger_select = 6u, /* takes.trigger.adc_trigger */ + .clock_hz = 90000000u, /* peripheral.clock_hz */ + .clken_offset = 0x00000044u, /* peripheral.clock.enable_offset */ + .clken_bit = 8u, /* peripheral.clock.bit */ + .irq = 18u, /* peripheral.irqs.global */ + .vref_mv = 3300u, /* device.vref_mv, its default */ + .bits = 12u, /* peripheral.adc.bits */ + .inputs = 16u, /* peripheral.adc.inputs */ + .temperature = 18u, /* peripheral.adc.temperature */ + .vrefint = 17u, /* peripheral.adc.vrefint */ + .dma_rx = {&emb_dev_dma2, 0u, 0u, {0u, 0u}}, /* dma.rx */ +}; +static emb_device_state_t adc1_state; +static emb_stm32_adc_data_t adc1_data; +static const emb_device_t *const adc1_deps[] = {&emb_dev_dma2, &emb_dev_rcc}; +const emb_device_t emb_dev_adc1 = { + .name = "adc1", + .api = &emb_stm32_adc_api.dev, + .config = &adc1_config, + .state = &adc1_state, + .data = &adc1_data, + .deps = adc1_deps, + .class_id = EMB_DRV_CLASS_ADC, + .level = EMB_DEVICE_KERNEL, + .dep_count = 2u, +}; + /* in initialization order */ static const emb_device_t *const devices[] = { &emb_dev_rcc, /* 0: EARLY */ @@ -351,16 +521,22 @@ static const emb_device_t *const devices[] = { &emb_dev_rtc, /* 3: EARLY */ &emb_dev_flash, /* 4: EARLY */ &emb_dev_dma1, /* 5: EARLY */ - &emb_dev_gpiob, /* 6: EARLY */ - &emb_dev_gpioc, /* 7: EARLY */ - &emb_dev_usart2, /* 8: EARLY */ - &emb_dev_uart4, /* 9: EARLY */ - &emb_dev_spi2, /* 10: KERNEL */ - &emb_dev_i2c1, /* 11: KERNEL */ - &emb_dev_i2c2, /* 12: KERNEL */ + &emb_dev_dma2, /* 6: EARLY */ + &emb_dev_gpiob, /* 7: EARLY */ + &emb_dev_gpioc, /* 8: EARLY */ + &emb_dev_usart2, /* 9: EARLY */ + &emb_dev_uart4, /* 10: EARLY */ + &emb_dev_spi2, /* 11: KERNEL */ + &emb_dev_i2c1, /* 12: KERNEL */ + &emb_dev_i2c2, /* 13: KERNEL */ + &emb_dev_tim5, /* 14: KERNEL */ + &emb_dev_tim9, /* 15: KERNEL */ + &emb_dev_tim3, /* 16: KERNEL */ + &emb_dev_tim4, /* 17: KERNEL */ + &emb_dev_adc1, /* 18: KERNEL */ }; -const emb_device_table_t emb_board_device_table = {devices, 13u, 10u}; +const emb_device_table_t emb_board_device_table = {devices, 19u, 11u}; #if CONFIG_EMB_DRV_ENTROPY /* the board's entropy source, or none: nothing stands in for one (SPEC-017 §11, SEC-012) */ diff --git a/examples/controller/generated/.base/nucleo_f446re/include/soc_devices.h b/examples/controller/src/config/nucleo_f446re/peripheral/soc_devices.h similarity index 78% rename from examples/controller/generated/.base/nucleo_f446re/include/soc_devices.h rename to examples/controller/src/config/nucleo_f446re/peripheral/soc_devices.h index e33f77bb..85805dc4 100644 --- a/examples/controller/generated/.base/nucleo_f446re/include/soc_devices.h +++ b/examples/controller/src/config/nucleo_f446re/peripheral/soc_devices.h @@ -10,22 +10,24 @@ * * @details * Generated by emb-hwgen 0.1.0, schema v0. Do not edit: change the - * description and run hw/gen/emb-hwgen.py generate --system examples/controller/system.yaml (HW-003). + * description and run + * hw/gen/emb-hwgen.py generate --system examples/controller/system.yaml + * (HW-003). * Inputs (SHA-256): * arch/cortex_m/arch.yaml * c5c8e451c09717dee1713d07f8311b6d507e3b4c66c42d93e0ce11da6ec76d6d * boards/st/nucleo_f446re/board.yaml - * d756f3a7f19dc7da82ee3afc168dc54946312c5a9990720953c0fedcdece54ea + * 551c524379751d359bdd87501269d6cab33edf84d212d2f6632ffe9567ec71d0 * drivers/bindings.yaml - * d3c336ac05548e0addd1faac18f3dff70576d8069f11d89e6a761cf5c6132b49 + * c06d1a914adb21d0e314c79b3611ac6859eefeac1957d6914cccfc5531ad6ede * examples/controller/controller.conf * f7354e5137f5ea50fbd1d5829ff4f5eb88a044100d871d6a8fd7d976339a75f1 * examples/controller/system.yaml * 2a91f71f1de638aa1ffaa18f0f76fc3ccde44d2560aef98a9a48120775773af3 * soc/st/stm32f4/stm32f4.yaml - * 3db4a0a65c9624d865d4ed7fc6354bf95054d0c465b76a2091f06aeac3d7375f + * 796886c294250aa81151a620d80d0e43b5ee8e1bf53a07d1d7e2c62e95214dbd * soc/st/stm32f4/stm32f446.yaml - * 0d5cc7f5fce4c51be71678987720c85c6e76e05473ff8a78ea5035394316c055 + * f0c9a37f6017c87d0efe215a3561f65494ba52383f2d0c10419b0ab5035f77f2 * soc/st/stm32f4/stm32f446re.yaml * b9a88d0a94aa17ee83317a3a56f7c194ec1b3107dfb3e82e453122dc1c48f6d4 */ @@ -34,7 +36,7 @@ #include -#define EMB_SOC_DEVICE_COUNT 13u +#define EMB_SOC_DEVICE_COUNT 19u #if CONFIG_EMB_DEVICE #include @@ -46,6 +48,7 @@ extern const emb_device_t emb_dev_iwdg; extern const emb_device_t emb_dev_rtc; extern const emb_device_t emb_dev_flash; extern const emb_device_t emb_dev_dma1; +extern const emb_device_t emb_dev_dma2; extern const emb_device_t emb_dev_gpiob; extern const emb_device_t emb_dev_gpioc; extern const emb_device_t emb_dev_usart2; @@ -53,6 +56,11 @@ extern const emb_device_t emb_dev_uart4; extern const emb_device_t emb_dev_spi2; extern const emb_device_t emb_dev_i2c1; extern const emb_device_t emb_dev_i2c2; +extern const emb_device_t emb_dev_tim5; +extern const emb_device_t emb_dev_tim9; +extern const emb_device_t emb_dev_tim3; +extern const emb_device_t emb_dev_tim4; +extern const emb_device_t emb_dev_adc1; /* which devices the board has, for code that uses one only where it exists */ #define EMB_SOC_HAS_RCC 1 @@ -61,6 +69,7 @@ extern const emb_device_t emb_dev_i2c2; #define EMB_SOC_HAS_RTC 1 #define EMB_SOC_HAS_FLASH 1 #define EMB_SOC_HAS_DMA1 1 +#define EMB_SOC_HAS_DMA2 1 #define EMB_SOC_HAS_GPIOB 1 #define EMB_SOC_HAS_GPIOC 1 #define EMB_SOC_HAS_USART2 1 @@ -68,6 +77,11 @@ extern const emb_device_t emb_dev_i2c2; #define EMB_SOC_HAS_SPI2 1 #define EMB_SOC_HAS_I2C1 1 #define EMB_SOC_HAS_I2C2 1 +#define EMB_SOC_HAS_TIM5 1 +#define EMB_SOC_HAS_TIM9 1 +#define EMB_SOC_HAS_TIM3 1 +#define EMB_SOC_HAS_TIM4 1 +#define EMB_SOC_HAS_ADC1 1 /* the board's watchdog device: the first of its class */ #define EMB_SOC_WATCHDOG_DEVICE (&emb_dev_iwdg) @@ -75,6 +89,11 @@ extern const emb_device_t emb_dev_i2c2; /* the board's RTC device: the first of its class */ #define EMB_SOC_RTC_DEVICE (&emb_dev_rtc) +/* the board's counters: the first of their class, and all of them (SPEC-017 §11a) */ +#define EMB_SOC_COUNTER_DEVICE (&emb_dev_tim5) +#define EMB_SOC_COUNTER_DEVICES &emb_dev_tim5, &emb_dev_tim9 +#define EMB_SOC_COUNTER_COUNT 2u + /* the console's UART device (the board's console:) */ #define EMB_SOC_CONSOLE_DEVICE (&emb_dev_usart2) /* its writes' DMA channel (devices[].dma, A119) */ @@ -97,6 +116,7 @@ extern const emb_device_t emb_dev_i2c2; #define EMB_SOC_USART2_DMA_TX {&emb_dev_dma1, 6u, 4u, {0u, 0u}} #define EMB_SOC_SPI2_DMA_RX {&emb_dev_dma1, 3u, 0u, {0u, 0u}} #define EMB_SOC_SPI2_DMA_TX {&emb_dev_dma1, 4u, 0u, {0u, 0u}} +#define EMB_SOC_ADC1_DMA_RX {&emb_dev_dma2, 0u, 0u, {0u, 0u}} /* clang-format on */ /* the SPI devices' chip selects (devices[].cs), emb_drv_gpio_line_t initializers; the pin diff --git a/examples/controller/src/config/nucleo_f446re/tasks.c b/examples/controller/src/config/nucleo_f446re/tasks.c new file mode 100644 index 00000000..b27fc5f9 --- /dev/null +++ b/examples/controller/src/config/nucleo_f446re/tasks.c @@ -0,0 +1,74 @@ +/* SPDX-License-Identifier: Apache-2.0 */ +/* + * This file is part of EmbLinkRTOS, a deterministic real-time kernel for microcontrollers. + * Licensed under the Apache License, Version 2.0; see the LICENSE file at the repository root. + */ + +/******************************************************************************* + System Tasks File + + File Name: + tasks.c + + Summary: + controller's tasks on the nucleo_f446re, and SYS_Tasks(). + + Description: + Each task's thread, queue, dispatch and description: the thread runs the + task runtime, emb_task_run() (SPEC-020), which calls an event task's handler + for each event, and a periodic task's _Tasks() every period, without drift. + SYS_Tasks() starts the kernel. + + Generated by emb-hwgen 0.1.0, schema v0, from the system description and the + nucleo_f446re's. Yours to edit: regenerating merges its changes with yours + (A126): + hw/gen/emb-hwgen.py generate --system examples/controller/system.yaml + + Inputs (SHA-256): + arch/cortex_m/arch.yaml + c5c8e451c09717dee1713d07f8311b6d507e3b4c66c42d93e0ce11da6ec76d6d + boards/st/nucleo_f446re/board.yaml + 551c524379751d359bdd87501269d6cab33edf84d212d2f6632ffe9567ec71d0 + drivers/bindings.yaml + c06d1a914adb21d0e314c79b3611ac6859eefeac1957d6914cccfc5531ad6ede + examples/controller/controller.conf + f7354e5137f5ea50fbd1d5829ff4f5eb88a044100d871d6a8fd7d976339a75f1 + examples/controller/system.yaml + 2a91f71f1de638aa1ffaa18f0f76fc3ccde44d2560aef98a9a48120775773af3 + soc/st/stm32f4/stm32f4.yaml + 796886c294250aa81151a620d80d0e43b5ee8e1bf53a07d1d7e2c62e95214dbd + soc/st/stm32f4/stm32f446.yaml + f0c9a37f6017c87d0efe215a3561f65494ba52383f2d0c10419b0ab5035f77f2 + soc/st/stm32f4/stm32f446re.yaml + b9a88d0a94aa17ee83317a3a56f7c194ec1b3107dfb3e82e453122dc1c48f6d4 + *******************************************************************************/ + +// ***************************************************************************** +// ***************************************************************************** +// Section: Included Files +// ***************************************************************************** +// ***************************************************************************** + +#include "definitions.h" + +// ***************************************************************************** +// ***************************************************************************** +// Section: System "Tasks" Routine +// ***************************************************************************** +// ***************************************************************************** + +/******************************************************************************* + Function: + void SYS_Tasks ( void ) + + Remarks: + See prototype in definitions.h. + */ +void SYS_Tasks(void) +{ + /* Start the kernel: the threads and the tasks run from here. It does not return. */ + emb_kernel_start(); +} +/******************************************************************************* + End of File +*/ diff --git a/examples/controller/generated/.base/nucleo_f446ze/build/CMakeLists.txt b/examples/controller/src/config/nucleo_f446ze/build/CMakeLists.txt similarity index 72% rename from examples/controller/generated/.base/nucleo_f446ze/build/CMakeLists.txt rename to examples/controller/src/config/nucleo_f446ze/build/CMakeLists.txt index dc6477a2..29239f62 100644 --- a/examples/controller/generated/.base/nucleo_f446ze/build/CMakeLists.txt +++ b/examples/controller/src/config/nucleo_f446ze/build/CMakeLists.txt @@ -4,24 +4,26 @@ # Licensed under the Apache License, Version 2.0; see the LICENSE file at the repository root. # # Generated by emb-hwgen 0.1.0, schema v0. Do not edit: change the -# description and run hw/gen/emb-hwgen.py generate --system examples/controller/system.yaml (HW-003). +# description and run +# hw/gen/emb-hwgen.py generate --system examples/controller/system.yaml +# (HW-003). # Inputs (SHA-256): # arch/cortex_m/arch.yaml # c5c8e451c09717dee1713d07f8311b6d507e3b4c66c42d93e0ce11da6ec76d6d # boards/st/nucleo_f446ze/board.yaml # 1525ea206692663af174039e30776d6a9a9b30275c9e5c9bdabf14ac0b70aa19 # drivers/bindings.yaml -# d3c336ac05548e0addd1faac18f3dff70576d8069f11d89e6a761cf5c6132b49 +# c06d1a914adb21d0e314c79b3611ac6859eefeac1957d6914cccfc5531ad6ede # examples/controller/controller.conf # f7354e5137f5ea50fbd1d5829ff4f5eb88a044100d871d6a8fd7d976339a75f1 # examples/controller/system.yaml # 2a91f71f1de638aa1ffaa18f0f76fc3ccde44d2560aef98a9a48120775773af3 # soc/st/stm32f4/stm32f4.yaml -# 3db4a0a65c9624d865d4ed7fc6354bf95054d0c465b76a2091f06aeac3d7375f +# 796886c294250aa81151a620d80d0e43b5ee8e1bf53a07d1d7e2c62e95214dbd # soc/st/stm32f4/stm32f446.yaml -# 0d5cc7f5fce4c51be71678987720c85c6e76e05473ff8a78ea5035394316c055 +# f0c9a37f6017c87d0efe215a3561f65494ba52383f2d0c10419b0ab5035f77f2 # soc/st/stm32f4/stm32f446ze.yaml # dabae95e9e4bc984c1a33275966665e0252068e929fe3b430d06589da6bdb6c9 # The board has no C of its own: its SoC family's board support builds emb_board from -# ../src/board_pins.c and ../include/hw_config.h, and links ../linker/regions.ld. +# ../peripheral/board_pins.c and ../peripheral/hw_config.h, and links ../linker/regions.ld. add_subdirectory("${EMB_SOC_DIR}" soc) diff --git a/examples/controller/generated/.base/nucleo_f446ze/build/board.cmake b/examples/controller/src/config/nucleo_f446ze/build/board.cmake similarity index 72% rename from examples/controller/generated/.base/nucleo_f446ze/build/board.cmake rename to examples/controller/src/config/nucleo_f446ze/build/board.cmake index be3efdcf..472587b8 100644 --- a/examples/controller/generated/.base/nucleo_f446ze/build/board.cmake +++ b/examples/controller/src/config/nucleo_f446ze/build/board.cmake @@ -4,22 +4,24 @@ # Licensed under the Apache License, Version 2.0; see the LICENSE file at the repository root. # # Generated by emb-hwgen 0.1.0, schema v0. Do not edit: change the -# description and run hw/gen/emb-hwgen.py generate --system examples/controller/system.yaml (HW-003). +# description and run +# hw/gen/emb-hwgen.py generate --system examples/controller/system.yaml +# (HW-003). # Inputs (SHA-256): # arch/cortex_m/arch.yaml # c5c8e451c09717dee1713d07f8311b6d507e3b4c66c42d93e0ce11da6ec76d6d # boards/st/nucleo_f446ze/board.yaml # 1525ea206692663af174039e30776d6a9a9b30275c9e5c9bdabf14ac0b70aa19 # drivers/bindings.yaml -# d3c336ac05548e0addd1faac18f3dff70576d8069f11d89e6a761cf5c6132b49 +# c06d1a914adb21d0e314c79b3611ac6859eefeac1957d6914cccfc5531ad6ede # examples/controller/controller.conf # f7354e5137f5ea50fbd1d5829ff4f5eb88a044100d871d6a8fd7d976339a75f1 # examples/controller/system.yaml # 2a91f71f1de638aa1ffaa18f0f76fc3ccde44d2560aef98a9a48120775773af3 # soc/st/stm32f4/stm32f4.yaml -# 3db4a0a65c9624d865d4ed7fc6354bf95054d0c465b76a2091f06aeac3d7375f +# 796886c294250aa81151a620d80d0e43b5ee8e1bf53a07d1d7e2c62e95214dbd # soc/st/stm32f4/stm32f446.yaml -# 0d5cc7f5fce4c51be71678987720c85c6e76e05473ff8a78ea5035394316c055 +# f0c9a37f6017c87d0efe215a3561f65494ba52383f2d0c10419b0ab5035f77f2 # soc/st/stm32f4/stm32f446ze.yaml # dabae95e9e4bc984c1a33275966665e0252068e929fe3b430d06589da6bdb6c9 # nucleo_f446ze: STM32F446ZE, cortex-m4f at 180 MHz. @@ -28,17 +30,19 @@ set(EMB_BOARD_VARIANT armv7em) set(EMB_BOARD_DEFAULT_PROFILE base) set(EMB_BOARD_C_FLAGS -mcpu=cortex-m4 -mfpu=fpv4-sp-d16 -mfloat-abi=hard) get_filename_component(EMB_BOARD_GENERATED_DIR "${CMAKE_CURRENT_LIST_DIR}/.." ABSOLUTE) -set(EMB_BOARD_CONF "${EMB_BOARD_GENERATED_DIR}/config/board.conf") +set(EMB_BOARD_CONF "${EMB_BOARD_GENERATED_DIR}/build/board.conf") set(EMB_BOARD_HW_JSON "${EMB_BOARD_GENERATED_DIR}/docs/hw.json") set(EMB_BOARD_BUILD_DIR "${CMAKE_CURRENT_LIST_DIR}") # build/CMakeLists.txt +set(EMB_BOARD_SRC_DIR "${EMB_BOARD_GENERATED_DIR}/peripheral") # its pin table and boot block +set(EMB_BOARD_LINKER_DIR "${EMB_BOARD_GENERATED_DIR}/linker") # the SoC family's board support and drivers build this board (build/CMakeLists.txt) set(EMB_SOC_DIR "${EMB_BASE}/soc/st/stm32f4") -set(EMB_BOARD_INCLUDE_DIRS "${EMB_BOARD_GENERATED_DIR}/include" "${EMB_SOC_DIR}/include") +set(EMB_BOARD_INCLUDE_DIRS "${EMB_BOARD_GENERATED_DIR}/peripheral" "${EMB_SOC_DIR}/include") set(EMB_BOARD_RESETS_IN embsim) # restart the image with RAM kept (test_crash_reset) set(EMB_BOARD_EMBSIM_TARGET emblink/nucleo_f446ze) # EMB_TEST_EMULATOR=embsim # the board's devices (soc_devices.c) and the drivers they use, and only those (SPEC-016 §8) set(EMB_BOARD_DRIVER_SOURCES - "${EMB_BOARD_GENERATED_DIR}/src/soc_devices.c" + "${EMB_BOARD_GENERATED_DIR}/peripheral/soc_devices.c" "${EMB_BASE}/drivers/st/stm32_devices.c" "${EMB_BASE}/drivers/st/stm32_uart.c" ) @@ -49,10 +53,10 @@ set(EMB_BOARD_DRIVER_INCLUDE_DIRS set(EMB_BOARD_HW_INPUTS "arch/cortex_m/arch.yaml=c5c8e451c09717dee1713d07f8311b6d507e3b4c66c42d93e0ce11da6ec76d6d" "boards/st/nucleo_f446ze/board.yaml=1525ea206692663af174039e30776d6a9a9b30275c9e5c9bdabf14ac0b70aa19" - "drivers/bindings.yaml=d3c336ac05548e0addd1faac18f3dff70576d8069f11d89e6a761cf5c6132b49" + "drivers/bindings.yaml=c06d1a914adb21d0e314c79b3611ac6859eefeac1957d6914cccfc5531ad6ede" "examples/controller/controller.conf=f7354e5137f5ea50fbd1d5829ff4f5eb88a044100d871d6a8fd7d976339a75f1" "examples/controller/system.yaml=2a91f71f1de638aa1ffaa18f0f76fc3ccde44d2560aef98a9a48120775773af3" - "soc/st/stm32f4/stm32f4.yaml=3db4a0a65c9624d865d4ed7fc6354bf95054d0c465b76a2091f06aeac3d7375f" - "soc/st/stm32f4/stm32f446.yaml=0d5cc7f5fce4c51be71678987720c85c6e76e05473ff8a78ea5035394316c055" + "soc/st/stm32f4/stm32f4.yaml=796886c294250aa81151a620d80d0e43b5ee8e1bf53a07d1d7e2c62e95214dbd" + "soc/st/stm32f4/stm32f446.yaml=f0c9a37f6017c87d0efe215a3561f65494ba52383f2d0c10419b0ab5035f77f2" "soc/st/stm32f4/stm32f446ze.yaml=dabae95e9e4bc984c1a33275966665e0252068e929fe3b430d06589da6bdb6c9" ) diff --git a/examples/controller/generated/.base/nucleo_f446ze/config/board.conf b/examples/controller/src/config/nucleo_f446ze/build/board.conf similarity index 77% rename from examples/controller/generated/.base/nucleo_f446ze/config/board.conf rename to examples/controller/src/config/nucleo_f446ze/build/board.conf index 724fc1bd..0a489073 100644 --- a/examples/controller/generated/.base/nucleo_f446ze/config/board.conf +++ b/examples/controller/src/config/nucleo_f446ze/build/board.conf @@ -4,22 +4,24 @@ # Licensed under the Apache License, Version 2.0; see the LICENSE file at the repository root. # # Generated by emb-hwgen 0.1.0, schema v0. Do not edit: change the -# description and run hw/gen/emb-hwgen.py generate --system examples/controller/system.yaml (HW-003). +# description and run +# hw/gen/emb-hwgen.py generate --system examples/controller/system.yaml +# (HW-003). # Inputs (SHA-256): # arch/cortex_m/arch.yaml # c5c8e451c09717dee1713d07f8311b6d507e3b4c66c42d93e0ce11da6ec76d6d # boards/st/nucleo_f446ze/board.yaml # 1525ea206692663af174039e30776d6a9a9b30275c9e5c9bdabf14ac0b70aa19 # drivers/bindings.yaml -# d3c336ac05548e0addd1faac18f3dff70576d8069f11d89e6a761cf5c6132b49 +# c06d1a914adb21d0e314c79b3611ac6859eefeac1957d6914cccfc5531ad6ede # examples/controller/controller.conf # f7354e5137f5ea50fbd1d5829ff4f5eb88a044100d871d6a8fd7d976339a75f1 # examples/controller/system.yaml # 2a91f71f1de638aa1ffaa18f0f76fc3ccde44d2560aef98a9a48120775773af3 # soc/st/stm32f4/stm32f4.yaml -# 3db4a0a65c9624d865d4ed7fc6354bf95054d0c465b76a2091f06aeac3d7375f +# 796886c294250aa81151a620d80d0e43b5ee8e1bf53a07d1d7e2c62e95214dbd # soc/st/stm32f4/stm32f446.yaml -# 0d5cc7f5fce4c51be71678987720c85c6e76e05473ff8a78ea5035394316c055 +# f0c9a37f6017c87d0efe215a3561f65494ba52383f2d0c10419b0ab5035f77f2 # soc/st/stm32f4/stm32f446ze.yaml # dabae95e9e4bc984c1a33275966665e0252068e929fe3b430d06589da6bdb6c9 # Board defaults for nucleo_f446ze. Applied before the profile fragment. diff --git a/examples/controller/src/config/nucleo_f446ze/configuration.h b/examples/controller/src/config/nucleo_f446ze/configuration.h new file mode 100644 index 00000000..36c10b3b --- /dev/null +++ b/examples/controller/src/config/nucleo_f446ze/configuration.h @@ -0,0 +1,107 @@ +/* SPDX-License-Identifier: Apache-2.0 */ +/* + * This file is part of EmbLinkRTOS, a deterministic real-time kernel for microcontrollers. + * Licensed under the Apache License, Version 2.0; see the LICENSE file at the repository root. + */ + +/******************************************************************************* + System Configuration Header + + File Name: + configuration.h + + Summary: + The build-time configuration of controller on the nucleo_f446ze. + + Description: + The system's settings as macros: the board and its clock, the devices' + settings, each task's and thread's priority and stack, the tasks' periods, + queues and timeouts, and the application's interrupts. The kernel's own + options are 's CONFIG_EMB_*, and the board's hardware + 's EMB_HW_*. + + Generated by emb-hwgen 0.1.0, schema v0, from the system description and the + nucleo_f446ze's. Yours to edit: regenerating merges its changes with yours + (A126): + hw/gen/emb-hwgen.py generate --system examples/controller/system.yaml + + Inputs (SHA-256): + arch/cortex_m/arch.yaml + c5c8e451c09717dee1713d07f8311b6d507e3b4c66c42d93e0ce11da6ec76d6d + boards/st/nucleo_f446ze/board.yaml + 1525ea206692663af174039e30776d6a9a9b30275c9e5c9bdabf14ac0b70aa19 + drivers/bindings.yaml + c06d1a914adb21d0e314c79b3611ac6859eefeac1957d6914cccfc5531ad6ede + examples/controller/controller.conf + f7354e5137f5ea50fbd1d5829ff4f5eb88a044100d871d6a8fd7d976339a75f1 + examples/controller/system.yaml + 2a91f71f1de638aa1ffaa18f0f76fc3ccde44d2560aef98a9a48120775773af3 + soc/st/stm32f4/stm32f4.yaml + 796886c294250aa81151a620d80d0e43b5ee8e1bf53a07d1d7e2c62e95214dbd + soc/st/stm32f4/stm32f446.yaml + f0c9a37f6017c87d0efe215a3561f65494ba52383f2d0c10419b0ab5035f77f2 + soc/st/stm32f4/stm32f446ze.yaml + dabae95e9e4bc984c1a33275966665e0252068e929fe3b430d06589da6bdb6c9 + *******************************************************************************/ + +#ifndef CONFIGURATION_H +#define CONFIGURATION_H + +// ***************************************************************************** +// ***************************************************************************** +// Section: Included Files +// ***************************************************************************** +// ***************************************************************************** + +#include + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +// ***************************************************************************** +// ***************************************************************************** +// Section: System Configuration +// ***************************************************************************** +// ***************************************************************************** + +#define SYS_CPU_CLOCK_HZ 180000000u +#define SYS_TICK_NS CONFIG_EMB_TICK_NS +#define SYS_PRIORITY_COUNT CONFIG_EMB_PRIORITY_COUNT + +// ***************************************************************************** +// ***************************************************************************** +// Section: Driver Configuration +// ***************************************************************************** +// ***************************************************************************** + +#define DRV_USART3_BAUD 115200u + +// ***************************************************************************** +// ***************************************************************************** +// Section: Application Configuration +// ***************************************************************************** +// ***************************************************************************** + +/* control_thread: a thread */ +#define CONTROL_THREAD_PRIORITY 6u +#define CONTROL_THREAD_STACK_SIZE 1024u + +/* command_thread: a thread */ +#define COMMAND_THREAD_PRIORITY 4u +#define COMMAND_THREAD_STACK_SIZE 1024u + +/* telemetry_thread: a thread */ +#define TELEMETRY_THREAD_PRIORITY 2u +#define TELEMETRY_THREAD_STACK_SIZE 1024u + +#ifdef __cplusplus +} +#endif + +#endif /* CONFIGURATION_H */ +/******************************************************************************* + End of File +*/ diff --git a/examples/controller/src/config/nucleo_f446ze/definitions.h b/examples/controller/src/config/nucleo_f446ze/definitions.h new file mode 100644 index 00000000..6877cf57 --- /dev/null +++ b/examples/controller/src/config/nucleo_f446ze/definitions.h @@ -0,0 +1,180 @@ +/* SPDX-License-Identifier: Apache-2.0 */ +/* + * This file is part of EmbLinkRTOS, a deterministic real-time kernel for microcontrollers. + * Licensed under the Apache License, Version 2.0; see the LICENSE file at the repository root. + */ + +/******************************************************************************* + System Definitions + + File Name: + definitions.h + + Summary: + controller's system definitions on the nucleo_f446ze. + + Description: + The one header the application includes: the kernel's API, the board's + devices, the system's configuration and handles, every task's header, and + the system's two functions, SYS_Initialize() and SYS_Tasks(). + + Generated by emb-hwgen 0.1.0, schema v0, from the system description and the + nucleo_f446ze's. Yours to edit: regenerating merges its changes with yours + (A126): + hw/gen/emb-hwgen.py generate --system examples/controller/system.yaml + + Inputs (SHA-256): + arch/cortex_m/arch.yaml + c5c8e451c09717dee1713d07f8311b6d507e3b4c66c42d93e0ce11da6ec76d6d + boards/st/nucleo_f446ze/board.yaml + 1525ea206692663af174039e30776d6a9a9b30275c9e5c9bdabf14ac0b70aa19 + drivers/bindings.yaml + c06d1a914adb21d0e314c79b3611ac6859eefeac1957d6914cccfc5531ad6ede + examples/controller/controller.conf + f7354e5137f5ea50fbd1d5829ff4f5eb88a044100d871d6a8fd7d976339a75f1 + examples/controller/system.yaml + 2a91f71f1de638aa1ffaa18f0f76fc3ccde44d2560aef98a9a48120775773af3 + soc/st/stm32f4/stm32f4.yaml + 796886c294250aa81151a620d80d0e43b5ee8e1bf53a07d1d7e2c62e95214dbd + soc/st/stm32f4/stm32f446.yaml + f0c9a37f6017c87d0efe215a3561f65494ba52383f2d0c10419b0ab5035f77f2 + soc/st/stm32f4/stm32f446ze.yaml + dabae95e9e4bc984c1a33275966665e0252068e929fe3b430d06589da6bdb6c9 + *******************************************************************************/ + +#ifndef DEFINITIONS_H +#define DEFINITIONS_H + +// ***************************************************************************** +// ***************************************************************************** +// Section: Included Files +// ***************************************************************************** +// ***************************************************************************** + +#include "configuration.h" +#include "controller.h" + +#include + +#include +#include +#include + +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/* Device Information */ +#define DEVICE_NAME "STM32F446ZE" +#define DEVICE_ARCH "cortex-m4f" +#define DEVICE_FAMILY "stm32f4" +#define BOARD_NAME "nucleo_f446ze" + +/* CPU clock frequency */ +#define CPU_CLOCK_FREQUENCY 180000000u + +// ***************************************************************************** +// ***************************************************************************** +// Section: System Functions +// ***************************************************************************** +// ***************************************************************************** + +/******************************************************************************* + Function: + void SYS_Initialize ( void *data ) + + Summary: + Initializes the board, the kernel and every task. + + Description: + This function initializes the board (its clocks, pins and console), then the + kernel (its objects and the EARLY devices), then the application's + interrupts, then each task, in its initial state. The KERNEL devices start + with the kernel, in SYS_Tasks(). + + Precondition: + None. + + Parameters: + data - Unused; NULL. + + Returns: + None. + + Example: + + SYS_Initialize(NULL); + while (true) { + SYS_Tasks(); + } + + + Remarks: + This function is called once, after reset, from main(). +*/ +void SYS_Initialize(void *data); + +/******************************************************************************* + Function: + void SYS_Tasks ( void ) + + Summary: + Starts the kernel: the threads and the tasks run from here. + + Description: + This function starts the KERNEL devices, then the scheduler, which runs the + system's threads and each task's thread. It does not return. + + Precondition: + SYS_Initialize() has run. + + Parameters: + None. + + Returns: + It does not return. + + Example: + + SYS_Initialize(NULL); + while (true) { + SYS_Tasks(); + } + + + Remarks: + Harmony calls its SYS_Tasks() in a loop; this one runs the scheduler and + never comes back. +*/ +void SYS_Tasks(void); + +// ***************************************************************************** +// ***************************************************************************** +// Section: System Objects +// ***************************************************************************** +// ***************************************************************************** + +/* threads: their entries, which the application defines, and their handles */ +void command(void *arg); +void control(void *arg); +void telemetry(void *arg); +extern emb_thread_t control_thread; +extern emb_thread_t command_thread; +extern emb_thread_t telemetry_thread; + +/* objects */ +extern emb_msgq_t samples; +extern emb_msgq_t rx_bytes; +extern emb_mutex_t console; + +#ifdef __cplusplus +} +#endif + +#endif /* DEFINITIONS_H */ +/******************************************************************************* + End of File +*/ diff --git a/examples/controller/generated/.base/nucleo_f446ze/docs/board.md b/examples/controller/src/config/nucleo_f446ze/docs/board.md similarity index 88% rename from examples/controller/generated/.base/nucleo_f446ze/docs/board.md rename to examples/controller/src/config/nucleo_f446ze/docs/board.md index 7d14ec71..076209ea 100644 --- a/examples/controller/generated/.base/nucleo_f446ze/docs/board.md +++ b/examples/controller/src/config/nucleo_f446ze/docs/board.md @@ -64,7 +64,10 @@ In initialization order (SPEC-016 §4). | 16 | dma1.s5 | | 17 | dma1.s6 | | 18 | adc1.global | +| 24 | tim9.global | | 28 | tim2.global | +| 29 | tim3.global | +| 30 | tim4.global | | 31 | i2c1.ev | | 32 | i2c1.er | | 33 | i2c2.ev | @@ -75,6 +78,7 @@ In initialization order (SPEC-016 §4). | 39 | usart3.global | | 41 | rtc.alarm | | 47 | dma1.s7 | +| 50 | tim5.global | | 52 | uart4.global | | 53 | uart5.global | | 56 | dma2.s0 | @@ -99,9 +103,9 @@ Generated by emb-hwgen 0.1.0, schema v0, from: |---|---| | `arch/cortex_m/arch.yaml` | `c5c8e451c09717dee1713d07f8311b6d507e3b4c66c42d93e0ce11da6ec76d6d` | | `boards/st/nucleo_f446ze/board.yaml` | `1525ea206692663af174039e30776d6a9a9b30275c9e5c9bdabf14ac0b70aa19` | -| `drivers/bindings.yaml` | `d3c336ac05548e0addd1faac18f3dff70576d8069f11d89e6a761cf5c6132b49` | +| `drivers/bindings.yaml` | `c06d1a914adb21d0e314c79b3611ac6859eefeac1957d6914cccfc5531ad6ede` | | `examples/controller/controller.conf` | `f7354e5137f5ea50fbd1d5829ff4f5eb88a044100d871d6a8fd7d976339a75f1` | | `examples/controller/system.yaml` | `2a91f71f1de638aa1ffaa18f0f76fc3ccde44d2560aef98a9a48120775773af3` | -| `soc/st/stm32f4/stm32f4.yaml` | `3db4a0a65c9624d865d4ed7fc6354bf95054d0c465b76a2091f06aeac3d7375f` | -| `soc/st/stm32f4/stm32f446.yaml` | `0d5cc7f5fce4c51be71678987720c85c6e76e05473ff8a78ea5035394316c055` | +| `soc/st/stm32f4/stm32f4.yaml` | `796886c294250aa81151a620d80d0e43b5ee8e1bf53a07d1d7e2c62e95214dbd` | +| `soc/st/stm32f4/stm32f446.yaml` | `f0c9a37f6017c87d0efe215a3561f65494ba52383f2d0c10419b0ab5035f77f2` | | `soc/st/stm32f4/stm32f446ze.yaml` | `dabae95e9e4bc984c1a33275966665e0252068e929fe3b430d06589da6bdb6c9` | diff --git a/examples/controller/generated/nucleo_f446ze/docs/build_report.md b/examples/controller/src/config/nucleo_f446ze/docs/build_report.md similarity index 82% rename from examples/controller/generated/nucleo_f446ze/docs/build_report.md rename to examples/controller/src/config/nucleo_f446ze/docs/build_report.md index 34e912cc..feedea47 100644 --- a/examples/controller/generated/nucleo_f446ze/docs/build_report.md +++ b/examples/controller/src/config/nucleo_f446ze/docs/build_report.md @@ -34,9 +34,9 @@ Generated by emb-hwgen 0.1.0, schema v0, from: |---|---| | `arch/cortex_m/arch.yaml` | `c5c8e451c09717dee1713d07f8311b6d507e3b4c66c42d93e0ce11da6ec76d6d` | | `boards/st/nucleo_f446ze/board.yaml` | `1525ea206692663af174039e30776d6a9a9b30275c9e5c9bdabf14ac0b70aa19` | -| `drivers/bindings.yaml` | `d3c336ac05548e0addd1faac18f3dff70576d8069f11d89e6a761cf5c6132b49` | +| `drivers/bindings.yaml` | `c06d1a914adb21d0e314c79b3611ac6859eefeac1957d6914cccfc5531ad6ede` | | `examples/controller/controller.conf` | `f7354e5137f5ea50fbd1d5829ff4f5eb88a044100d871d6a8fd7d976339a75f1` | | `examples/controller/system.yaml` | `2a91f71f1de638aa1ffaa18f0f76fc3ccde44d2560aef98a9a48120775773af3` | -| `soc/st/stm32f4/stm32f4.yaml` | `3db4a0a65c9624d865d4ed7fc6354bf95054d0c465b76a2091f06aeac3d7375f` | -| `soc/st/stm32f4/stm32f446.yaml` | `0d5cc7f5fce4c51be71678987720c85c6e76e05473ff8a78ea5035394316c055` | +| `soc/st/stm32f4/stm32f4.yaml` | `796886c294250aa81151a620d80d0e43b5ee8e1bf53a07d1d7e2c62e95214dbd` | +| `soc/st/stm32f4/stm32f446.yaml` | `f0c9a37f6017c87d0efe215a3561f65494ba52383f2d0c10419b0ab5035f77f2` | | `soc/st/stm32f4/stm32f446ze.yaml` | `dabae95e9e4bc984c1a33275966665e0252068e929fe3b430d06589da6bdb6c9` | diff --git a/examples/controller/generated/.base/nucleo_f446ze/docs/hw.json b/examples/controller/src/config/nucleo_f446ze/docs/hw.json similarity index 86% rename from examples/controller/generated/.base/nucleo_f446ze/docs/hw.json rename to examples/controller/src/config/nucleo_f446ze/docs/hw.json index ac762ccf..7806af6a 100644 --- a/examples/controller/generated/.base/nucleo_f446ze/docs/hw.json +++ b/examples/controller/src/config/nucleo_f446ze/docs/hw.json @@ -116,8 +116,14 @@ "apb1": 45000000, "apb2": 90000000 }, + "bus_timer_hz": { + "ahb1": 180000000, + "apb1": 90000000, + "apb2": 180000000 + }, "bypass": true, "cpu_hz": 180000000, + "fixed_plls": {}, "flash_wait_states": 5, "hclk_hz": 180000000, "pclk1_div": 4, @@ -357,7 +363,7 @@ }, { "path": "drivers/bindings.yaml", - "sha256": "d3c336ac05548e0addd1faac18f3dff70576d8069f11d89e6a761cf5c6132b49" + "sha256": "c06d1a914adb21d0e314c79b3611ac6859eefeac1957d6914cccfc5531ad6ede" }, { "path": "examples/controller/controller.conf", @@ -369,11 +375,11 @@ }, { "path": "soc/st/stm32f4/stm32f4.yaml", - "sha256": "3db4a0a65c9624d865d4ed7fc6354bf95054d0c465b76a2091f06aeac3d7375f" + "sha256": "796886c294250aa81151a620d80d0e43b5ee8e1bf53a07d1d7e2c62e95214dbd" }, { "path": "soc/st/stm32f4/stm32f446.yaml", - "sha256": "0d5cc7f5fce4c51be71678987720c85c6e76e05473ff8a78ea5035394316c055" + "sha256": "f0c9a37f6017c87d0efe215a3561f65494ba52383f2d0c10419b0ab5035f77f2" }, { "path": "soc/st/stm32f4/stm32f446ze.yaml", @@ -384,19 +390,49 @@ "soc": { "alternate_functions": { "PA0": { - "af8": "uart4_tx" + "af1": "tim2_ch1", + "af2": "tim5_ch1", + "af8": "uart4_tx", + "analog": "adc1_in0" }, "PA1": { - "af8": "uart4_rx" + "af1": "tim2_ch2", + "af2": "tim5_ch2", + "af8": "uart4_rx", + "analog": "adc1_in1" }, "PA10": { "af7": "usart1_rx" }, + "PA15": { + "af1": "tim2_ch1" + }, "PA2": { - "af7": "usart2_tx" + "af1": "tim2_ch3", + "af2": "tim5_ch3", + "af7": "usart2_tx", + "analog": "adc1_in2" }, "PA3": { - "af7": "usart2_rx" + "af1": "tim2_ch4", + "af2": "tim5_ch4", + "af7": "usart2_rx", + "analog": "adc1_in3" + }, + "PA4": { + "analog": "adc1_in4" + }, + "PA5": { + "af1": "tim2_ch1", + "analog": "adc1_in5" + }, + "PA6": { + "af2": "tim3_ch1", + "analog": "adc1_in6" + }, + "PA7": { + "af2": "tim3_ch2", + "analog": "adc1_in7" }, "PA8": { "af4": "i2c3_scl" @@ -404,7 +440,16 @@ "PA9": { "af7": "usart1_tx" }, + "PB0": { + "af2": "tim3_ch3", + "analog": "adc1_in8" + }, + "PB1": { + "af2": "tim3_ch4", + "analog": "adc1_in9" + }, "PB10": { + "af1": "tim2_ch3", "af4": "i2c2_scl", "af7": "usart3_tx" }, @@ -417,26 +462,46 @@ "PB15": { "af5": "spi2_mosi" }, + "PB2": { + "af1": "tim2_ch4" + }, "PB3": { + "af1": "tim2_ch2", "af4": "i2c2_sda" }, "PB4": { + "af2": "tim3_ch1", "af4": "i2c3_sda" }, + "PB5": { + "af2": "tim3_ch2" + }, "PB6": { + "af2": "tim4_ch1", "af4": "i2c1_scl", "af7": "usart1_tx" }, "PB7": { + "af2": "tim4_ch2", "af4": "i2c1_sda", "af7": "usart1_rx" }, "PB8": { + "af1": "tim2_ch1", + "af2": "tim4_ch3", "af4": "i2c1_scl" }, "PB9": { + "af1": "tim2_ch2", + "af2": "tim4_ch4", "af4": "i2c1_sda" }, + "PC0": { + "analog": "adc1_in10" + }, + "PC1": { + "analog": "adc1_in11" + }, "PC10": { "af7": "usart3_tx", "af8": "uart4_tx" @@ -449,16 +514,32 @@ "af4": "i2c2_sda", "af8": "uart5_tx" }, + "PC2": { + "analog": "adc1_in12" + }, + "PC3": { + "analog": "adc1_in13" + }, + "PC4": { + "analog": "adc1_in14" + }, "PC5": { - "af7": "usart3_rx" + "af7": "usart3_rx", + "analog": "adc1_in15" }, "PC6": { + "af2": "tim3_ch1", "af8": "usart6_tx" }, "PC7": { + "af2": "tim3_ch2", "af8": "usart6_rx" }, + "PC8": { + "af2": "tim3_ch3" + }, "PC9": { + "af2": "tim3_ch4", "af4": "i2c3_sda" }, "PD2": { @@ -587,6 +668,7 @@ "name": "lse" } ], + "timers_double_when_divided": true, "voltage_scales": [ { "max_hz": 120000000, @@ -731,12 +813,24 @@ "part": "STM32F446ZE", "peripherals": [ { + "adc": { + "bits": 12, + "inputs": 16, + "temperature": 18, + "vrefint": 17 + }, "base": 1073815552, "clock": { "bit": 8, "bus": "apb2" }, "compatible": "st,stm32f4-adc", + "dma_requests": { + "rx": [ + "dma2.s0c0", + "dma2.s4c0" + ] + }, "irqs": [ { "name": "global", @@ -911,12 +1005,14 @@ "size": 1024 }, { + "adc_trigger": 6, "base": 1073741824, "clock": { "bit": 0, "bus": "apb1" }, "compatible": "st,stm32-tim", + "counter_bits": 32, "irqs": [ { "name": "global", @@ -926,6 +1022,76 @@ "name": "tim2", "size": 1024 }, + { + "adc_trigger": 8, + "base": 1073742848, + "clock": { + "bit": 1, + "bus": "apb1" + }, + "compatible": "st,stm32-tim", + "counter_bits": 16, + "irqs": [ + { + "name": "global", + "number": 29 + } + ], + "name": "tim3", + "size": 1024 + }, + { + "base": 1073743872, + "clock": { + "bit": 2, + "bus": "apb1" + }, + "compatible": "st,stm32-tim", + "counter_bits": 16, + "irqs": [ + { + "name": "global", + "number": 30 + } + ], + "name": "tim4", + "size": 1024 + }, + { + "base": 1073744896, + "clock": { + "bit": 3, + "bus": "apb1" + }, + "compatible": "st,stm32-tim", + "counter_bits": 32, + "irqs": [ + { + "name": "global", + "number": 50 + } + ], + "name": "tim5", + "size": 1024 + }, + { + "base": 1073823744, + "clock": { + "bit": 16, + "bus": "apb2" + }, + "compatible": "st,stm32-tim", + "counter_bits": 16, + "irqs": [ + { + "name": "global", + "number": 24 + } + ], + "name": "tim9", + "size": 1024, + "timer_channels": 2 + }, { "base": 1073897472, "clock": { diff --git a/examples/controller/generated/.base/nucleo_f446ze/docs/system.json b/examples/controller/src/config/nucleo_f446ze/docs/system.json similarity index 91% rename from examples/controller/generated/.base/nucleo_f446ze/docs/system.json rename to examples/controller/src/config/nucleo_f446ze/docs/system.json index 85d3ccfb..b6c86084 100644 --- a/examples/controller/generated/.base/nucleo_f446ze/docs/system.json +++ b/examples/controller/src/config/nucleo_f446ze/docs/system.json @@ -33,7 +33,7 @@ }, { "path": "drivers/bindings.yaml", - "sha256": "d3c336ac05548e0addd1faac18f3dff70576d8069f11d89e6a761cf5c6132b49" + "sha256": "c06d1a914adb21d0e314c79b3611ac6859eefeac1957d6914cccfc5531ad6ede" }, { "path": "examples/controller/controller.conf", @@ -45,17 +45,18 @@ }, { "path": "soc/st/stm32f4/stm32f4.yaml", - "sha256": "3db4a0a65c9624d865d4ed7fc6354bf95054d0c465b76a2091f06aeac3d7375f" + "sha256": "796886c294250aa81151a620d80d0e43b5ee8e1bf53a07d1d7e2c62e95214dbd" }, { "path": "soc/st/stm32f4/stm32f446.yaml", - "sha256": "0d5cc7f5fce4c51be71678987720c85c6e76e05473ff8a78ea5035394316c055" + "sha256": "f0c9a37f6017c87d0efe215a3561f65494ba52383f2d0c10419b0ab5035f77f2" }, { "path": "soc/st/stm32f4/stm32f446ze.yaml", "sha256": "dabae95e9e4bc984c1a33275966665e0252068e929fe3b430d06589da6bdb6c9" } ], + "interrupts": [], "name": "controller", "objects": [ { diff --git a/examples/controller/generated/nucleo_f446ze/docs/system.md b/examples/controller/src/config/nucleo_f446ze/docs/system.md similarity index 74% rename from examples/controller/generated/nucleo_f446ze/docs/system.md rename to examples/controller/src/config/nucleo_f446ze/docs/system.md index 52d6716d..40ac80b9 100644 --- a/examples/controller/generated/nucleo_f446ze/docs/system.md +++ b/examples/controller/src/config/nucleo_f446ze/docs/system.md @@ -1,6 +1,6 @@ # controller: the system on nucleo_f446ze -Generated from `examples/controller/system.yaml` (SPEC-014 §5, A125). Profile base, 32 priorities, a minimum stack of 256 bytes. +Generated from `examples/controller/system.yaml` (SPEC-014 §5, A125, A130). Profile base, 32 priorities, a minimum stack of 256 bytes. ## Threads @@ -26,9 +26,9 @@ Generated by emb-hwgen 0.1.0, schema v0, from: |---|---| | `arch/cortex_m/arch.yaml` | `c5c8e451c09717dee1713d07f8311b6d507e3b4c66c42d93e0ce11da6ec76d6d` | | `boards/st/nucleo_f446ze/board.yaml` | `1525ea206692663af174039e30776d6a9a9b30275c9e5c9bdabf14ac0b70aa19` | -| `drivers/bindings.yaml` | `d3c336ac05548e0addd1faac18f3dff70576d8069f11d89e6a761cf5c6132b49` | +| `drivers/bindings.yaml` | `c06d1a914adb21d0e314c79b3611ac6859eefeac1957d6914cccfc5531ad6ede` | | `examples/controller/controller.conf` | `f7354e5137f5ea50fbd1d5829ff4f5eb88a044100d871d6a8fd7d976339a75f1` | | `examples/controller/system.yaml` | `2a91f71f1de638aa1ffaa18f0f76fc3ccde44d2560aef98a9a48120775773af3` | -| `soc/st/stm32f4/stm32f4.yaml` | `3db4a0a65c9624d865d4ed7fc6354bf95054d0c465b76a2091f06aeac3d7375f` | -| `soc/st/stm32f4/stm32f446.yaml` | `0d5cc7f5fce4c51be71678987720c85c6e76e05473ff8a78ea5035394316c055` | +| `soc/st/stm32f4/stm32f4.yaml` | `796886c294250aa81151a620d80d0e43b5ee8e1bf53a07d1d7e2c62e95214dbd` | +| `soc/st/stm32f4/stm32f446.yaml` | `f0c9a37f6017c87d0efe215a3561f65494ba52383f2d0c10419b0ab5035f77f2` | | `soc/st/stm32f4/stm32f446ze.yaml` | `dabae95e9e4bc984c1a33275966665e0252068e929fe3b430d06589da6bdb6c9` | diff --git a/examples/controller/src/config/nucleo_f446ze/initialization.c b/examples/controller/src/config/nucleo_f446ze/initialization.c new file mode 100644 index 00000000..eeca5ffa --- /dev/null +++ b/examples/controller/src/config/nucleo_f446ze/initialization.c @@ -0,0 +1,97 @@ +/* SPDX-License-Identifier: Apache-2.0 */ +/* + * This file is part of EmbLinkRTOS, a deterministic real-time kernel for microcontrollers. + * Licensed under the Apache License, Version 2.0; see the LICENSE file at the repository root. + */ + +/******************************************************************************* + System Initialization File + + File Name: + initialization.c + + Summary: + controller's initialization on the nucleo_f446ze: SYS_Initialize(), and the + system's objects. + + Description: + The system's static definitions, which the kernel creates from its + initialization table when emb_kernel_init() runs (SPEC-001 §6.4), and + SYS_Initialize(), which brings up the board, the kernel, the application's + interrupts and the tasks. + + Generated by emb-hwgen 0.1.0, schema v0, from the system description and the + nucleo_f446ze's. Yours to edit: regenerating merges its changes with yours + (A126): + hw/gen/emb-hwgen.py generate --system examples/controller/system.yaml + + Inputs (SHA-256): + arch/cortex_m/arch.yaml + c5c8e451c09717dee1713d07f8311b6d507e3b4c66c42d93e0ce11da6ec76d6d + boards/st/nucleo_f446ze/board.yaml + 1525ea206692663af174039e30776d6a9a9b30275c9e5c9bdabf14ac0b70aa19 + drivers/bindings.yaml + c06d1a914adb21d0e314c79b3611ac6859eefeac1957d6914cccfc5531ad6ede + examples/controller/controller.conf + f7354e5137f5ea50fbd1d5829ff4f5eb88a044100d871d6a8fd7d976339a75f1 + examples/controller/system.yaml + 2a91f71f1de638aa1ffaa18f0f76fc3ccde44d2560aef98a9a48120775773af3 + soc/st/stm32f4/stm32f4.yaml + 796886c294250aa81151a620d80d0e43b5ee8e1bf53a07d1d7e2c62e95214dbd + soc/st/stm32f4/stm32f446.yaml + f0c9a37f6017c87d0efe215a3561f65494ba52383f2d0c10419b0ab5035f77f2 + soc/st/stm32f4/stm32f446ze.yaml + dabae95e9e4bc984c1a33275966665e0252068e929fe3b430d06589da6bdb6c9 + *******************************************************************************/ + +// ***************************************************************************** +// ***************************************************************************** +// Section: Included Files +// ***************************************************************************** +// ***************************************************************************** + +#include "definitions.h" + +// ***************************************************************************** +// ***************************************************************************** +// Section: System Objects +// ***************************************************************************** +// ***************************************************************************** + +/* the kernel creates each when emb_kernel_init() runs (SPEC-001 §6.4) */ +EMB_THREAD_DEFINE(control_thread, control, NULL, CONTROL_THREAD_PRIORITY, CONTROL_THREAD_STACK_SIZE, + 0u); +EMB_THREAD_DEFINE(command_thread, command, NULL, COMMAND_THREAD_PRIORITY, COMMAND_THREAD_STACK_SIZE, + 0u); +EMB_THREAD_DEFINE(telemetry_thread, telemetry, NULL, TELEMETRY_THREAD_PRIORITY, + TELEMETRY_THREAD_STACK_SIZE, 0u); +EMB_MSGQ_DEFINE(samples, sizeof(sample_t), 8u, 0u); +EMB_MSGQ_DEFINE(rx_bytes, 1u, 64u, 0u); +EMB_MUTEX_DEFINE(console, EMB_MUTEX_INHERIT, 0u, 0u); + +// ***************************************************************************** +// ***************************************************************************** +// Section: System Initialization +// ***************************************************************************** +// ***************************************************************************** + +/******************************************************************************* + Function: + void SYS_Initialize ( void *data ) + + Remarks: + See prototype in definitions.h. + */ +void SYS_Initialize(void *data) +{ + (void)data; + + /* The board: its clocks, pins and console */ + emb_board_init(); + + /* The kernel: its objects, and the EARLY devices */ + emb_kernel_init(); +} +/******************************************************************************* + End of File +*/ diff --git a/examples/controller/generated/nucleo_f446ze/linker/regions.ld b/examples/controller/src/config/nucleo_f446ze/linker/regions.ld similarity index 92% rename from examples/controller/generated/nucleo_f446ze/linker/regions.ld rename to examples/controller/src/config/nucleo_f446ze/linker/regions.ld index 56cec41f..7387746c 100644 --- a/examples/controller/generated/nucleo_f446ze/linker/regions.ld +++ b/examples/controller/src/config/nucleo_f446ze/linker/regions.ld @@ -12,22 +12,24 @@ * * @details * Generated by emb-hwgen 0.1.0, schema v0. Do not edit: change the - * description and run hw/gen/emb-hwgen.py generate --system examples/controller/system.yaml (HW-003). + * description and run + * hw/gen/emb-hwgen.py generate --system examples/controller/system.yaml + * (HW-003). * Inputs (SHA-256): * arch/cortex_m/arch.yaml * c5c8e451c09717dee1713d07f8311b6d507e3b4c66c42d93e0ce11da6ec76d6d * boards/st/nucleo_f446ze/board.yaml * 1525ea206692663af174039e30776d6a9a9b30275c9e5c9bdabf14ac0b70aa19 * drivers/bindings.yaml - * d3c336ac05548e0addd1faac18f3dff70576d8069f11d89e6a761cf5c6132b49 + * c06d1a914adb21d0e314c79b3611ac6859eefeac1957d6914cccfc5531ad6ede * examples/controller/controller.conf * f7354e5137f5ea50fbd1d5829ff4f5eb88a044100d871d6a8fd7d976339a75f1 * examples/controller/system.yaml * 2a91f71f1de638aa1ffaa18f0f76fc3ccde44d2560aef98a9a48120775773af3 * soc/st/stm32f4/stm32f4.yaml - * 3db4a0a65c9624d865d4ed7fc6354bf95054d0c465b76a2091f06aeac3d7375f + * 796886c294250aa81151a620d80d0e43b5ee8e1bf53a07d1d7e2c62e95214dbd * soc/st/stm32f4/stm32f446.yaml - * 0d5cc7f5fce4c51be71678987720c85c6e76e05473ff8a78ea5035394316c055 + * f0c9a37f6017c87d0efe215a3561f65494ba52383f2d0c10419b0ab5035f77f2 * soc/st/stm32f4/stm32f446ze.yaml * dabae95e9e4bc984c1a33275966665e0252068e929fe3b430d06589da6bdb6c9 */ diff --git a/examples/controller/generated/.base/nucleo_f446ze/src/board_pins.c b/examples/controller/src/config/nucleo_f446ze/peripheral/board_pins.c similarity index 85% rename from examples/controller/generated/.base/nucleo_f446ze/src/board_pins.c rename to examples/controller/src/config/nucleo_f446ze/peripheral/board_pins.c index d72b67cd..686965ed 100644 --- a/examples/controller/generated/.base/nucleo_f446ze/src/board_pins.c +++ b/examples/controller/src/config/nucleo_f446ze/peripheral/board_pins.c @@ -11,22 +11,24 @@ * * @details * Generated by emb-hwgen 0.1.0, schema v0. Do not edit: change the - * description and run hw/gen/emb-hwgen.py generate --system examples/controller/system.yaml (HW-003). + * description and run + * hw/gen/emb-hwgen.py generate --system examples/controller/system.yaml + * (HW-003). * Inputs (SHA-256): * arch/cortex_m/arch.yaml * c5c8e451c09717dee1713d07f8311b6d507e3b4c66c42d93e0ce11da6ec76d6d * boards/st/nucleo_f446ze/board.yaml * 1525ea206692663af174039e30776d6a9a9b30275c9e5c9bdabf14ac0b70aa19 * drivers/bindings.yaml - * d3c336ac05548e0addd1faac18f3dff70576d8069f11d89e6a761cf5c6132b49 + * c06d1a914adb21d0e314c79b3611ac6859eefeac1957d6914cccfc5531ad6ede * examples/controller/controller.conf * f7354e5137f5ea50fbd1d5829ff4f5eb88a044100d871d6a8fd7d976339a75f1 * examples/controller/system.yaml * 2a91f71f1de638aa1ffaa18f0f76fc3ccde44d2560aef98a9a48120775773af3 * soc/st/stm32f4/stm32f4.yaml - * 3db4a0a65c9624d865d4ed7fc6354bf95054d0c465b76a2091f06aeac3d7375f + * 796886c294250aa81151a620d80d0e43b5ee8e1bf53a07d1d7e2c62e95214dbd * soc/st/stm32f4/stm32f446.yaml - * 0d5cc7f5fce4c51be71678987720c85c6e76e05473ff8a78ea5035394316c055 + * f0c9a37f6017c87d0efe215a3561f65494ba52383f2d0c10419b0ab5035f77f2 * soc/st/stm32f4/stm32f446ze.yaml * dabae95e9e4bc984c1a33275966665e0252068e929fe3b430d06589da6bdb6c9 */ diff --git a/examples/controller/generated/nucleo_f446ze/include/hw_config.h b/examples/controller/src/config/nucleo_f446ze/peripheral/hw_config.h similarity index 90% rename from examples/controller/generated/nucleo_f446ze/include/hw_config.h rename to examples/controller/src/config/nucleo_f446ze/peripheral/hw_config.h index 55805a63..bd493226 100644 --- a/examples/controller/generated/nucleo_f446ze/include/hw_config.h +++ b/examples/controller/src/config/nucleo_f446ze/peripheral/hw_config.h @@ -10,22 +10,24 @@ * * @details * Generated by emb-hwgen 0.1.0, schema v0. Do not edit: change the - * description and run hw/gen/emb-hwgen.py generate --system examples/controller/system.yaml (HW-003). + * description and run + * hw/gen/emb-hwgen.py generate --system examples/controller/system.yaml + * (HW-003). * Inputs (SHA-256): * arch/cortex_m/arch.yaml * c5c8e451c09717dee1713d07f8311b6d507e3b4c66c42d93e0ce11da6ec76d6d * boards/st/nucleo_f446ze/board.yaml * 1525ea206692663af174039e30776d6a9a9b30275c9e5c9bdabf14ac0b70aa19 * drivers/bindings.yaml - * d3c336ac05548e0addd1faac18f3dff70576d8069f11d89e6a761cf5c6132b49 + * c06d1a914adb21d0e314c79b3611ac6859eefeac1957d6914cccfc5531ad6ede * examples/controller/controller.conf * f7354e5137f5ea50fbd1d5829ff4f5eb88a044100d871d6a8fd7d976339a75f1 * examples/controller/system.yaml * 2a91f71f1de638aa1ffaa18f0f76fc3ccde44d2560aef98a9a48120775773af3 * soc/st/stm32f4/stm32f4.yaml - * 3db4a0a65c9624d865d4ed7fc6354bf95054d0c465b76a2091f06aeac3d7375f + * 796886c294250aa81151a620d80d0e43b5ee8e1bf53a07d1d7e2c62e95214dbd * soc/st/stm32f4/stm32f446.yaml - * 0d5cc7f5fce4c51be71678987720c85c6e76e05473ff8a78ea5035394316c055 + * f0c9a37f6017c87d0efe215a3561f65494ba52383f2d0c10419b0ab5035f77f2 * soc/st/stm32f4/stm32f446ze.yaml * dabae95e9e4bc984c1a33275966665e0252068e929fe3b430d06589da6bdb6c9 */ @@ -168,6 +170,22 @@ #define EMB_HW_TIM2_CLKEN_BIT 0u #define EMB_HW_TIM2_CLKEN_OFFSET 0x40u #define EMB_HW_TIM2_IRQ 28u +#define EMB_HW_TIM3_BASE 0x40000400u +#define EMB_HW_TIM3_CLKEN_BIT 1u +#define EMB_HW_TIM3_CLKEN_OFFSET 0x40u +#define EMB_HW_TIM3_IRQ 29u +#define EMB_HW_TIM4_BASE 0x40000800u +#define EMB_HW_TIM4_CLKEN_BIT 2u +#define EMB_HW_TIM4_CLKEN_OFFSET 0x40u +#define EMB_HW_TIM4_IRQ 30u +#define EMB_HW_TIM5_BASE 0x40000C00u +#define EMB_HW_TIM5_CLKEN_BIT 3u +#define EMB_HW_TIM5_CLKEN_OFFSET 0x40u +#define EMB_HW_TIM5_IRQ 50u +#define EMB_HW_TIM9_BASE 0x40014000u +#define EMB_HW_TIM9_CLKEN_BIT 16u +#define EMB_HW_TIM9_CLKEN_OFFSET 0x44u +#define EMB_HW_TIM9_IRQ 24u #define EMB_HW_UART4_BASE 0x40004C00u #define EMB_HW_UART4_CLKEN_BIT 19u #define EMB_HW_UART4_CLKEN_OFFSET 0x40u diff --git a/examples/controller/generated/.base/nucleo_f446ze/src/soc_devices.c b/examples/controller/src/config/nucleo_f446ze/peripheral/soc_devices.c similarity index 94% rename from examples/controller/generated/.base/nucleo_f446ze/src/soc_devices.c rename to examples/controller/src/config/nucleo_f446ze/peripheral/soc_devices.c index 3a0e078a..b31b092e 100644 --- a/examples/controller/generated/.base/nucleo_f446ze/src/soc_devices.c +++ b/examples/controller/src/config/nucleo_f446ze/peripheral/soc_devices.c @@ -11,22 +11,24 @@ * * @details * Generated by emb-hwgen 0.1.0, schema v0. Do not edit: change the - * description and run hw/gen/emb-hwgen.py generate --system examples/controller/system.yaml (HW-003). + * description and run + * hw/gen/emb-hwgen.py generate --system examples/controller/system.yaml + * (HW-003). * Inputs (SHA-256): * arch/cortex_m/arch.yaml * c5c8e451c09717dee1713d07f8311b6d507e3b4c66c42d93e0ce11da6ec76d6d * boards/st/nucleo_f446ze/board.yaml * 1525ea206692663af174039e30776d6a9a9b30275c9e5c9bdabf14ac0b70aa19 * drivers/bindings.yaml - * d3c336ac05548e0addd1faac18f3dff70576d8069f11d89e6a761cf5c6132b49 + * c06d1a914adb21d0e314c79b3611ac6859eefeac1957d6914cccfc5531ad6ede * examples/controller/controller.conf * f7354e5137f5ea50fbd1d5829ff4f5eb88a044100d871d6a8fd7d976339a75f1 * examples/controller/system.yaml * 2a91f71f1de638aa1ffaa18f0f76fc3ccde44d2560aef98a9a48120775773af3 * soc/st/stm32f4/stm32f4.yaml - * 3db4a0a65c9624d865d4ed7fc6354bf95054d0c465b76a2091f06aeac3d7375f + * 796886c294250aa81151a620d80d0e43b5ee8e1bf53a07d1d7e2c62e95214dbd * soc/st/stm32f4/stm32f446.yaml - * 0d5cc7f5fce4c51be71678987720c85c6e76e05473ff8a78ea5035394316c055 + * f0c9a37f6017c87d0efe215a3561f65494ba52383f2d0c10419b0ab5035f77f2 * soc/st/stm32f4/stm32f446ze.yaml * dabae95e9e4bc984c1a33275966665e0252068e929fe3b430d06589da6bdb6c9 */ diff --git a/examples/controller/generated/.base/nucleo_f446ze/include/soc_devices.h b/examples/controller/src/config/nucleo_f446ze/peripheral/soc_devices.h similarity index 84% rename from examples/controller/generated/.base/nucleo_f446ze/include/soc_devices.h rename to examples/controller/src/config/nucleo_f446ze/peripheral/soc_devices.h index 2bf9c2ac..f59d84b8 100644 --- a/examples/controller/generated/.base/nucleo_f446ze/include/soc_devices.h +++ b/examples/controller/src/config/nucleo_f446ze/peripheral/soc_devices.h @@ -10,22 +10,24 @@ * * @details * Generated by emb-hwgen 0.1.0, schema v0. Do not edit: change the - * description and run hw/gen/emb-hwgen.py generate --system examples/controller/system.yaml (HW-003). + * description and run + * hw/gen/emb-hwgen.py generate --system examples/controller/system.yaml + * (HW-003). * Inputs (SHA-256): * arch/cortex_m/arch.yaml * c5c8e451c09717dee1713d07f8311b6d507e3b4c66c42d93e0ce11da6ec76d6d * boards/st/nucleo_f446ze/board.yaml * 1525ea206692663af174039e30776d6a9a9b30275c9e5c9bdabf14ac0b70aa19 * drivers/bindings.yaml - * d3c336ac05548e0addd1faac18f3dff70576d8069f11d89e6a761cf5c6132b49 + * c06d1a914adb21d0e314c79b3611ac6859eefeac1957d6914cccfc5531ad6ede * examples/controller/controller.conf * f7354e5137f5ea50fbd1d5829ff4f5eb88a044100d871d6a8fd7d976339a75f1 * examples/controller/system.yaml * 2a91f71f1de638aa1ffaa18f0f76fc3ccde44d2560aef98a9a48120775773af3 * soc/st/stm32f4/stm32f4.yaml - * 3db4a0a65c9624d865d4ed7fc6354bf95054d0c465b76a2091f06aeac3d7375f + * 796886c294250aa81151a620d80d0e43b5ee8e1bf53a07d1d7e2c62e95214dbd * soc/st/stm32f4/stm32f446.yaml - * 0d5cc7f5fce4c51be71678987720c85c6e76e05473ff8a78ea5035394316c055 + * f0c9a37f6017c87d0efe215a3561f65494ba52383f2d0c10419b0ab5035f77f2 * soc/st/stm32f4/stm32f446ze.yaml * dabae95e9e4bc984c1a33275966665e0252068e929fe3b430d06589da6bdb6c9 */ diff --git a/examples/controller/src/config/nucleo_f446ze/tasks.c b/examples/controller/src/config/nucleo_f446ze/tasks.c new file mode 100644 index 00000000..44f2a58a --- /dev/null +++ b/examples/controller/src/config/nucleo_f446ze/tasks.c @@ -0,0 +1,74 @@ +/* SPDX-License-Identifier: Apache-2.0 */ +/* + * This file is part of EmbLinkRTOS, a deterministic real-time kernel for microcontrollers. + * Licensed under the Apache License, Version 2.0; see the LICENSE file at the repository root. + */ + +/******************************************************************************* + System Tasks File + + File Name: + tasks.c + + Summary: + controller's tasks on the nucleo_f446ze, and SYS_Tasks(). + + Description: + Each task's thread, queue, dispatch and description: the thread runs the + task runtime, emb_task_run() (SPEC-020), which calls an event task's handler + for each event, and a periodic task's _Tasks() every period, without drift. + SYS_Tasks() starts the kernel. + + Generated by emb-hwgen 0.1.0, schema v0, from the system description and the + nucleo_f446ze's. Yours to edit: regenerating merges its changes with yours + (A126): + hw/gen/emb-hwgen.py generate --system examples/controller/system.yaml + + Inputs (SHA-256): + arch/cortex_m/arch.yaml + c5c8e451c09717dee1713d07f8311b6d507e3b4c66c42d93e0ce11da6ec76d6d + boards/st/nucleo_f446ze/board.yaml + 1525ea206692663af174039e30776d6a9a9b30275c9e5c9bdabf14ac0b70aa19 + drivers/bindings.yaml + c06d1a914adb21d0e314c79b3611ac6859eefeac1957d6914cccfc5531ad6ede + examples/controller/controller.conf + f7354e5137f5ea50fbd1d5829ff4f5eb88a044100d871d6a8fd7d976339a75f1 + examples/controller/system.yaml + 2a91f71f1de638aa1ffaa18f0f76fc3ccde44d2560aef98a9a48120775773af3 + soc/st/stm32f4/stm32f4.yaml + 796886c294250aa81151a620d80d0e43b5ee8e1bf53a07d1d7e2c62e95214dbd + soc/st/stm32f4/stm32f446.yaml + f0c9a37f6017c87d0efe215a3561f65494ba52383f2d0c10419b0ab5035f77f2 + soc/st/stm32f4/stm32f446ze.yaml + dabae95e9e4bc984c1a33275966665e0252068e929fe3b430d06589da6bdb6c9 + *******************************************************************************/ + +// ***************************************************************************** +// ***************************************************************************** +// Section: Included Files +// ***************************************************************************** +// ***************************************************************************** + +#include "definitions.h" + +// ***************************************************************************** +// ***************************************************************************** +// Section: System "Tasks" Routine +// ***************************************************************************** +// ***************************************************************************** + +/******************************************************************************* + Function: + void SYS_Tasks ( void ) + + Remarks: + See prototype in definitions.h. + */ +void SYS_Tasks(void) +{ + /* Start the kernel: the threads and the tasks run from here. It does not return. */ + emb_kernel_start(); +} +/******************************************************************************* + End of File +*/ diff --git a/examples/tasks/CMakeLists.txt b/examples/tasks/CMakeLists.txt index a2205051..75ef94b1 100644 --- a/examples/tasks/CMakeLists.txt +++ b/examples/tasks/CMakeLists.txt @@ -17,4 +17,4 @@ find_package(EmbLinkRTOS REQUIRED) project(tasks_demo LANGUAGES C) emb_kernel() -emb_add_executable(tasks_demo src/main.c src/tasks/door.c src/tasks/blink.c) +emb_add_executable(tasks_demo src/main.c src/door.c src/blink.c src/interrupt_handlers.c) diff --git a/examples/tasks/generated/.base/_app/src/main.c b/examples/tasks/generated/.base/_app/src/main.c deleted file mode 100644 index 0743c6a0..00000000 --- a/examples/tasks/generated/.base/_app/src/main.c +++ /dev/null @@ -1,25 +0,0 @@ -/* SPDX-License-Identifier: Apache-2.0 */ -/* - * This file is part of EmbLinkRTOS, a deterministic real-time kernel for microcontrollers. - * Licensed under the Apache License, Version 2.0; see the LICENSE file at the repository root. - */ - -/** - * @file main.c - * @brief tasks_demo: the board, the kernel, then the threads and tasks of system.yaml. - * - * @details - * Generated by emb-hwgen from system.yaml; yours to edit: regeneration merges its changes (A126). - */ -#include - -#include - -#include "system.h" - -int main(void) -{ - emb_board_init(); - emb_kernel_init(); - emb_kernel_start(); /* the threads and tasks run from here: it does not return */ -} diff --git a/examples/tasks/generated/.base/_app/src/tasks/blink.c b/examples/tasks/generated/.base/_app/src/tasks/blink.c deleted file mode 100644 index 26267caf..00000000 --- a/examples/tasks/generated/.base/_app/src/tasks/blink.c +++ /dev/null @@ -1,26 +0,0 @@ -/* SPDX-License-Identifier: Apache-2.0 */ -/* - * This file is part of EmbLinkRTOS, a deterministic real-time kernel for microcontrollers. - * Licensed under the Apache License, Version 2.0; see the LICENSE file at the repository root. - */ - -/** - * @file blink.c - * @brief The blink task's handlers (SPEC-020): each state's returns the state to be in next. - * - * @details - * Generated by emb-hwgen from system.yaml; yours to edit: regeneration merges its changes (A126). - */ -#include "tasks.h" - -emb_state_t blink_on_dark(blink_t *self) -{ - (void)self; - return BLINK_DARK; -} - -emb_state_t blink_on_lit(blink_t *self) -{ - (void)self; - return BLINK_LIT; -} diff --git a/examples/tasks/generated/.base/_app/src/tasks/door.c b/examples/tasks/generated/.base/_app/src/tasks/door.c deleted file mode 100644 index 47bd8f38..00000000 --- a/examples/tasks/generated/.base/_app/src/tasks/door.c +++ /dev/null @@ -1,45 +0,0 @@ -/* SPDX-License-Identifier: Apache-2.0 */ -/* - * This file is part of EmbLinkRTOS, a deterministic real-time kernel for microcontrollers. - * Licensed under the Apache License, Version 2.0; see the LICENSE file at the repository root. - */ - -/** - * @file door.c - * @brief The door task's handlers (SPEC-020): each state's returns the state to be in next. - * - * @details - * Generated by emb-hwgen from system.yaml; yours to edit: regeneration merges its changes (A126). - */ -#include "tasks.h" - -emb_state_t door_on_closed(door_t *self, const emb_task_event_t *ev) -{ - (void)self; - (void)ev; - return DOOR_CLOSED; -} - -emb_state_t door_on_open(door_t *self, const emb_task_event_t *ev) -{ - (void)self; - (void)ev; - return DOOR_OPEN; -} - -emb_state_t door_on_jammed(door_t *self, const emb_task_event_t *ev) -{ - (void)self; - (void)ev; - return DOOR_JAMMED; -} - -void door_enter_open(door_t *self) -{ - (void)self; -} - -void door_exit_open(door_t *self) -{ - (void)self; -} diff --git a/examples/tasks/generated/.base/_app/src/tasks/door.h b/examples/tasks/generated/.base/_app/src/tasks/door.h deleted file mode 100644 index 6828e6ec..00000000 --- a/examples/tasks/generated/.base/_app/src/tasks/door.h +++ /dev/null @@ -1,23 +0,0 @@ -/* SPDX-License-Identifier: Apache-2.0 */ -/* - * This file is part of EmbLinkRTOS, a deterministic real-time kernel for microcontrollers. - * Licensed under the Apache License, Version 2.0; see the LICENSE file at the repository root. - */ - -/** - * @file door.h - * @brief The door task's own types: its data. - * - * @details - * Generated by emb-hwgen from system.yaml; yours to edit: regeneration merges its changes (A126). - */ -#ifndef TASK_DOOR_H -#define TASK_DOOR_H - -#include - -typedef struct door_data { - uint32_t count; /* the task's own state: change it */ -} door_data_t; - -#endif /* TASK_DOOR_H */ diff --git a/examples/tasks/generated/.base/nucleo_f446re/docs/system.md b/examples/tasks/generated/.base/nucleo_f446re/docs/system.md deleted file mode 100644 index cf4e0183..00000000 --- a/examples/tasks/generated/.base/nucleo_f446re/docs/system.md +++ /dev/null @@ -1,24 +0,0 @@ -# tasks_demo: the system on nucleo_f446re - -Generated from `examples/tasks/system.yaml` (SPEC-014 §5, A125). Profile base, 32 priorities, a minimum stack of 256 bytes. - -## Tasks - -| Task | Model | Priority | Stack | States (initial first) | Events | -|---|---|---|---|---|---| -| `door` | event, queue 8 | 5 | 1024 | closed, open, jammed | open, close, jam | -| `blink` | periodic, 500 ms | 2 | 512 | dark, lit | — | - ---- - -Generated by emb-hwgen 0.1.0, schema v0, from: - -| Input | SHA-256 | -|---|---| -| `arch/cortex_m/arch.yaml` | `c5c8e451c09717dee1713d07f8311b6d507e3b4c66c42d93e0ce11da6ec76d6d` | -| `boards/st/nucleo_f446re/board.yaml` | `d756f3a7f19dc7da82ee3afc168dc54946312c5a9990720953c0fedcdece54ea` | -| `drivers/bindings.yaml` | `d3c336ac05548e0addd1faac18f3dff70576d8069f11d89e6a761cf5c6132b49` | -| `examples/tasks/system.yaml` | `3dd9de88918f06e4b3a41232cb716a9e7d1c4b74ad18e71fd51644ae394ebf9c` | -| `soc/st/stm32f4/stm32f4.yaml` | `3db4a0a65c9624d865d4ed7fc6354bf95054d0c465b76a2091f06aeac3d7375f` | -| `soc/st/stm32f4/stm32f446.yaml` | `0d5cc7f5fce4c51be71678987720c85c6e76e05473ff8a78ea5035394316c055` | -| `soc/st/stm32f4/stm32f446re.yaml` | `b9a88d0a94aa17ee83317a3a56f7c194ec1b3107dfb3e82e453122dc1c48f6d4` | diff --git a/examples/tasks/generated/.base/nucleo_f446re/include/system.h b/examples/tasks/generated/.base/nucleo_f446re/include/system.h deleted file mode 100644 index 4c1c4099..00000000 --- a/examples/tasks/generated/.base/nucleo_f446re/include/system.h +++ /dev/null @@ -1,46 +0,0 @@ -/* SPDX-License-Identifier: Apache-2.0 */ -/* - * This file is part of EmbLinkRTOS, a deterministic real-time kernel for microcontrollers. - * Licensed under the Apache License, Version 2.0; see the LICENSE file at the repository root. - */ - -/** - * @file system.h - * @brief The system tasks_demo's threads, objects, targets and watchdog for the application's - * sources (SPEC-014 §5, A125). - * - * @details - * Generated by emb-hwgen 0.1.0, schema v0. Do not edit: change the - * description and run hw/gen/emb-hwgen.py generate --system examples/tasks/system.yaml (HW-003). - * Inputs (SHA-256): - * arch/cortex_m/arch.yaml - * c5c8e451c09717dee1713d07f8311b6d507e3b4c66c42d93e0ce11da6ec76d6d - * boards/st/nucleo_f446re/board.yaml - * d756f3a7f19dc7da82ee3afc168dc54946312c5a9990720953c0fedcdece54ea - * drivers/bindings.yaml - * d3c336ac05548e0addd1faac18f3dff70576d8069f11d89e6a761cf5c6132b49 - * examples/tasks/system.yaml - * 3dd9de88918f06e4b3a41232cb716a9e7d1c4b74ad18e71fd51644ae394ebf9c - * soc/st/stm32f4/stm32f4.yaml - * 3db4a0a65c9624d865d4ed7fc6354bf95054d0c465b76a2091f06aeac3d7375f - * soc/st/stm32f4/stm32f446.yaml - * 0d5cc7f5fce4c51be71678987720c85c6e76e05473ff8a78ea5035394316c055 - * soc/st/stm32f4/stm32f446re.yaml - * b9a88d0a94aa17ee83317a3a56f7c194ec1b3107dfb3e82e453122dc1c48f6d4 - */ -#ifndef EMB_SYSTEM_H -#define EMB_SYSTEM_H - -#include - -#include "tasks.h" - -#ifdef __cplusplus -extern "C" { -#endif - -#ifdef __cplusplus -} -#endif - -#endif /* EMB_SYSTEM_H */ diff --git a/examples/tasks/generated/.base/nucleo_f446re/include/tasks.h b/examples/tasks/generated/.base/nucleo_f446re/include/tasks.h deleted file mode 100644 index a0a491d9..00000000 --- a/examples/tasks/generated/.base/nucleo_f446re/include/tasks.h +++ /dev/null @@ -1,80 +0,0 @@ -/* SPDX-License-Identifier: Apache-2.0 */ -/* - * This file is part of EmbLinkRTOS, a deterministic real-time kernel for microcontrollers. - * Licensed under the Apache License, Version 2.0; see the LICENSE file at the repository root. - */ - -/** - * @file tasks.h - * @brief The system tasks_demo's tasks: their states, events, types, handlers and handles - * (SPEC-020). - * - * @details - * Generated by emb-hwgen 0.1.0, schema v0. Do not edit: change the - * description and run hw/gen/emb-hwgen.py generate --system examples/tasks/system.yaml (HW-003). - * Inputs (SHA-256): - * arch/cortex_m/arch.yaml - * c5c8e451c09717dee1713d07f8311b6d507e3b4c66c42d93e0ce11da6ec76d6d - * boards/st/nucleo_f446re/board.yaml - * d756f3a7f19dc7da82ee3afc168dc54946312c5a9990720953c0fedcdece54ea - * drivers/bindings.yaml - * d3c336ac05548e0addd1faac18f3dff70576d8069f11d89e6a761cf5c6132b49 - * examples/tasks/system.yaml - * 3dd9de88918f06e4b3a41232cb716a9e7d1c4b74ad18e71fd51644ae394ebf9c - * soc/st/stm32f4/stm32f4.yaml - * 3db4a0a65c9624d865d4ed7fc6354bf95054d0c465b76a2091f06aeac3d7375f - * soc/st/stm32f4/stm32f446.yaml - * 0d5cc7f5fce4c51be71678987720c85c6e76e05473ff8a78ea5035394316c055 - * soc/st/stm32f4/stm32f446re.yaml - * b9a88d0a94aa17ee83317a3a56f7c194ec1b3107dfb3e82e453122dc1c48f6d4 - */ -#ifndef EMB_TASKS_H -#define EMB_TASKS_H - -#include - -#include - -#include "tasks/door.h" - -#ifdef __cplusplus -extern "C" { -#endif - -/* door: event */ -#define DOOR_CLOSED ((emb_state_t)0u) -#define DOOR_OPEN ((emb_state_t)1u) -#define DOOR_JAMMED ((emb_state_t)2u) -#define DOOR_STATE_COUNT ((emb_state_t)3u) -#define DOOR_EV_OPEN (EMB_EV_USER + 0u) -#define DOOR_EV_CLOSE (EMB_EV_USER + 1u) -#define DOOR_EV_JAM (EMB_EV_USER + 2u) -typedef struct door { - emb_task_t task; /* first: the runtime's */ - door_data_t data; -} door_t; -extern door_t door; -#define DOOR_TASK (&door.task) -emb_state_t door_on_closed(door_t *self, const emb_task_event_t *ev); -emb_state_t door_on_open(door_t *self, const emb_task_event_t *ev); -emb_state_t door_on_jammed(door_t *self, const emb_task_event_t *ev); -void door_enter_open(door_t *self); -void door_exit_open(door_t *self); - -/* blink: periodic, every 500 ms */ -#define BLINK_DARK ((emb_state_t)0u) -#define BLINK_LIT ((emb_state_t)1u) -#define BLINK_STATE_COUNT ((emb_state_t)2u) -typedef struct blink { - emb_task_t task; /* first: the runtime's */ -} blink_t; -extern blink_t blink; -#define BLINK_TASK (&blink.task) -emb_state_t blink_on_dark(blink_t *self); -emb_state_t blink_on_lit(blink_t *self); - -#ifdef __cplusplus -} -#endif - -#endif /* EMB_TASKS_H */ diff --git a/examples/tasks/generated/.base/nucleo_f446re/src/system.c b/examples/tasks/generated/.base/nucleo_f446re/src/system.c deleted file mode 100644 index 580f0cf5..00000000 --- a/examples/tasks/generated/.base/nucleo_f446re/src/system.c +++ /dev/null @@ -1,31 +0,0 @@ -/* SPDX-License-Identifier: Apache-2.0 */ -/* - * This file is part of EmbLinkRTOS, a deterministic real-time kernel for microcontrollers. - * Licensed under the Apache License, Version 2.0; see the LICENSE file at the repository root. - */ - -/** - * @file system.c - * @brief The system tasks_demo's static definitions: the kernel creates each from its - * initialization table (SPEC-001 §6.4, SPEC-014 §5, A125). - * - * @details - * Generated by emb-hwgen 0.1.0, schema v0. Do not edit: change the - * description and run hw/gen/emb-hwgen.py generate --system examples/tasks/system.yaml (HW-003). - * Inputs (SHA-256): - * arch/cortex_m/arch.yaml - * c5c8e451c09717dee1713d07f8311b6d507e3b4c66c42d93e0ce11da6ec76d6d - * boards/st/nucleo_f446re/board.yaml - * d756f3a7f19dc7da82ee3afc168dc54946312c5a9990720953c0fedcdece54ea - * drivers/bindings.yaml - * d3c336ac05548e0addd1faac18f3dff70576d8069f11d89e6a761cf5c6132b49 - * examples/tasks/system.yaml - * 3dd9de88918f06e4b3a41232cb716a9e7d1c4b74ad18e71fd51644ae394ebf9c - * soc/st/stm32f4/stm32f4.yaml - * 3db4a0a65c9624d865d4ed7fc6354bf95054d0c465b76a2091f06aeac3d7375f - * soc/st/stm32f4/stm32f446.yaml - * 0d5cc7f5fce4c51be71678987720c85c6e76e05473ff8a78ea5035394316c055 - * soc/st/stm32f4/stm32f446re.yaml - * b9a88d0a94aa17ee83317a3a56f7c194ec1b3107dfb3e82e453122dc1c48f6d4 - */ -#include "system.h" diff --git a/examples/tasks/generated/.base/nucleo_f446re/src/tasks.c b/examples/tasks/generated/.base/nucleo_f446re/src/tasks.c deleted file mode 100644 index f895ba09..00000000 --- a/examples/tasks/generated/.base/nucleo_f446re/src/tasks.c +++ /dev/null @@ -1,128 +0,0 @@ -/* SPDX-License-Identifier: Apache-2.0 */ -/* - * This file is part of EmbLinkRTOS, a deterministic real-time kernel for microcontrollers. - * Licensed under the Apache License, Version 2.0; see the LICENSE file at the repository root. - */ - -/** - * @file tasks.c - * @brief The system tasks_demo's tasks: each one's queue, dispatch, description and thread - * (SPEC-020); the runtime is emb_task_run(). - * - * @details - * Generated by emb-hwgen 0.1.0, schema v0. Do not edit: change the - * description and run hw/gen/emb-hwgen.py generate --system examples/tasks/system.yaml (HW-003). - * Inputs (SHA-256): - * arch/cortex_m/arch.yaml - * c5c8e451c09717dee1713d07f8311b6d507e3b4c66c42d93e0ce11da6ec76d6d - * boards/st/nucleo_f446re/board.yaml - * d756f3a7f19dc7da82ee3afc168dc54946312c5a9990720953c0fedcdece54ea - * drivers/bindings.yaml - * d3c336ac05548e0addd1faac18f3dff70576d8069f11d89e6a761cf5c6132b49 - * examples/tasks/system.yaml - * 3dd9de88918f06e4b3a41232cb716a9e7d1c4b74ad18e71fd51644ae394ebf9c - * soc/st/stm32f4/stm32f4.yaml - * 3db4a0a65c9624d865d4ed7fc6354bf95054d0c465b76a2091f06aeac3d7375f - * soc/st/stm32f4/stm32f446.yaml - * 0d5cc7f5fce4c51be71678987720c85c6e76e05473ff8a78ea5035394316c055 - * soc/st/stm32f4/stm32f446re.yaml - * b9a88d0a94aa17ee83317a3a56f7c194ec1b3107dfb3e82e453122dc1c48f6d4 - */ -#include "tasks.h" - -/* ---- door ---- */ -static emb_task_event_t door_event; -EMB_MSGQ_DEFINE(door_task_queue, sizeof(emb_task_event_t), 8u, 0u); -static const uint32_t door_timeouts[3] = {0u, 2000u, 0u}; - -static emb_state_t door_dispatch(emb_state_t state, uint8_t why) -{ - emb_state_t next; - if (why == EMB_TASK_WHY_TIMEOUT) { - door_event.id = EMB_EV_TIMEOUT; - door_event.value = 0u; - } - switch (state) { - case DOOR_CLOSED: - next = door_on_closed(&door, &door_event); - break; - case DOOR_OPEN: - next = door_on_open(&door, &door_event); - break; - case DOOR_JAMMED: - next = door_on_jammed(&door, &door_event); - break; - default: - next = state; - break; - } - return next; -} - -static void door_enter(emb_state_t state) -{ - switch (state) { - case DOOR_OPEN: - door_enter_open(&door); - break; - default: - break; - } -} - -static void door_exit(emb_state_t state) -{ - switch (state) { - case DOOR_OPEN: - door_exit_open(&door); - break; - default: - break; - } -} - -static const emb_task_desc_t door_desc = {"door", door_dispatch, door_enter, door_exit, &door_event, &door_task_queue, - door_timeouts, 0u, (uint16_t)sizeof(emb_task_event_t), DOOR_CLOSED, - DOOR_STATE_COUNT, EMB_TASK_EVENT, 0u}; -door_t door = {.task = {.desc = &door_desc, .state = DOOR_CLOSED}}; - -static void door_main(void *arg) -{ - (void)arg; - emb_task_run(&door.task); -} - -EMB_THREAD_DEFINE(door_thread, door_main, NULL, 5u, 1024u, 0u); - -/* ---- blink ---- */ - -static emb_state_t blink_dispatch(emb_state_t state, uint8_t why) -{ - emb_state_t next; - (void)why; - switch (state) { - case BLINK_DARK: - next = blink_on_dark(&blink); - break; - case BLINK_LIT: - next = blink_on_lit(&blink); - break; - default: - next = state; - break; - } - return next; -} - -static const emb_task_desc_t blink_desc = {"blink", blink_dispatch, NULL, NULL, NULL, NULL, - NULL, 500u, 0u, BLINK_DARK, - BLINK_STATE_COUNT, EMB_TASK_PERIODIC, 0u}; -blink_t blink = {.task = {.desc = &blink_desc, .state = BLINK_DARK}}; - -static void blink_main(void *arg) -{ - (void)arg; - emb_task_run(&blink.task); -} - -EMB_THREAD_DEFINE(blink_thread, blink_main, NULL, 2u, 512u, 0u); diff --git a/examples/tasks/generated/.base/pico2_w/docs/system.md b/examples/tasks/generated/.base/pico2_w/docs/system.md deleted file mode 100644 index 09fb54fc..00000000 --- a/examples/tasks/generated/.base/pico2_w/docs/system.md +++ /dev/null @@ -1,23 +0,0 @@ -# tasks_demo: the system on pico2_w - -Generated from `examples/tasks/system.yaml` (SPEC-014 §5, A125). Profile base, 32 priorities, a minimum stack of 256 bytes. - -## Tasks - -| Task | Model | Priority | Stack | States (initial first) | Events | -|---|---|---|---|---|---| -| `door` | event, queue 8 | 5 | 1024 | closed, open, jammed | open, close, jam | -| `blink` | periodic, 500 ms | 2 | 512 | dark, lit | — | - ---- - -Generated by emb-hwgen 0.1.0, schema v0, from: - -| Input | SHA-256 | -|---|---| -| `arch/cortex_m/arch.yaml` | `c5c8e451c09717dee1713d07f8311b6d507e3b4c66c42d93e0ce11da6ec76d6d` | -| `boards/rpi/pico2_w/board.yaml` | `dad0ef7259e41ef3bd8fa07ea1c1f36040254a443deaf30d963b4fb14b5354a0` | -| `drivers/bindings.yaml` | `d3c336ac05548e0addd1faac18f3dff70576d8069f11d89e6a761cf5c6132b49` | -| `examples/tasks/system.yaml` | `3dd9de88918f06e4b3a41232cb716a9e7d1c4b74ad18e71fd51644ae394ebf9c` | -| `soc/rpi/rp2350/rp2350.yaml` | `9e60e99ecac8782bccd69e3bd69014af1d8891d6b6fbd822acff5bd9a526d8cd` | -| `soc/rpi/rp2350/rp2350a.yaml` | `045cef7794c3b6c6d2ff48ba294c6308d00fe13bc65e346f2ba2ccde1cea24ff` | diff --git a/examples/tasks/generated/.base/pico2_w/include/system.h b/examples/tasks/generated/.base/pico2_w/include/system.h deleted file mode 100644 index 43ef92cb..00000000 --- a/examples/tasks/generated/.base/pico2_w/include/system.h +++ /dev/null @@ -1,44 +0,0 @@ -/* SPDX-License-Identifier: Apache-2.0 */ -/* - * This file is part of EmbLinkRTOS, a deterministic real-time kernel for microcontrollers. - * Licensed under the Apache License, Version 2.0; see the LICENSE file at the repository root. - */ - -/** - * @file system.h - * @brief The system tasks_demo's threads, objects, targets and watchdog for the application's - * sources (SPEC-014 §5, A125). - * - * @details - * Generated by emb-hwgen 0.1.0, schema v0. Do not edit: change the - * description and run hw/gen/emb-hwgen.py generate --system examples/tasks/system.yaml (HW-003). - * Inputs (SHA-256): - * arch/cortex_m/arch.yaml - * c5c8e451c09717dee1713d07f8311b6d507e3b4c66c42d93e0ce11da6ec76d6d - * boards/rpi/pico2_w/board.yaml - * dad0ef7259e41ef3bd8fa07ea1c1f36040254a443deaf30d963b4fb14b5354a0 - * drivers/bindings.yaml - * d3c336ac05548e0addd1faac18f3dff70576d8069f11d89e6a761cf5c6132b49 - * examples/tasks/system.yaml - * 3dd9de88918f06e4b3a41232cb716a9e7d1c4b74ad18e71fd51644ae394ebf9c - * soc/rpi/rp2350/rp2350.yaml - * 9e60e99ecac8782bccd69e3bd69014af1d8891d6b6fbd822acff5bd9a526d8cd - * soc/rpi/rp2350/rp2350a.yaml - * 045cef7794c3b6c6d2ff48ba294c6308d00fe13bc65e346f2ba2ccde1cea24ff - */ -#ifndef EMB_SYSTEM_H -#define EMB_SYSTEM_H - -#include - -#include "tasks.h" - -#ifdef __cplusplus -extern "C" { -#endif - -#ifdef __cplusplus -} -#endif - -#endif /* EMB_SYSTEM_H */ diff --git a/examples/tasks/generated/.base/pico2_w/include/tasks.h b/examples/tasks/generated/.base/pico2_w/include/tasks.h deleted file mode 100644 index 72857c28..00000000 --- a/examples/tasks/generated/.base/pico2_w/include/tasks.h +++ /dev/null @@ -1,78 +0,0 @@ -/* SPDX-License-Identifier: Apache-2.0 */ -/* - * This file is part of EmbLinkRTOS, a deterministic real-time kernel for microcontrollers. - * Licensed under the Apache License, Version 2.0; see the LICENSE file at the repository root. - */ - -/** - * @file tasks.h - * @brief The system tasks_demo's tasks: their states, events, types, handlers and handles - * (SPEC-020). - * - * @details - * Generated by emb-hwgen 0.1.0, schema v0. Do not edit: change the - * description and run hw/gen/emb-hwgen.py generate --system examples/tasks/system.yaml (HW-003). - * Inputs (SHA-256): - * arch/cortex_m/arch.yaml - * c5c8e451c09717dee1713d07f8311b6d507e3b4c66c42d93e0ce11da6ec76d6d - * boards/rpi/pico2_w/board.yaml - * dad0ef7259e41ef3bd8fa07ea1c1f36040254a443deaf30d963b4fb14b5354a0 - * drivers/bindings.yaml - * d3c336ac05548e0addd1faac18f3dff70576d8069f11d89e6a761cf5c6132b49 - * examples/tasks/system.yaml - * 3dd9de88918f06e4b3a41232cb716a9e7d1c4b74ad18e71fd51644ae394ebf9c - * soc/rpi/rp2350/rp2350.yaml - * 9e60e99ecac8782bccd69e3bd69014af1d8891d6b6fbd822acff5bd9a526d8cd - * soc/rpi/rp2350/rp2350a.yaml - * 045cef7794c3b6c6d2ff48ba294c6308d00fe13bc65e346f2ba2ccde1cea24ff - */ -#ifndef EMB_TASKS_H -#define EMB_TASKS_H - -#include - -#include - -#include "tasks/door.h" - -#ifdef __cplusplus -extern "C" { -#endif - -/* door: event */ -#define DOOR_CLOSED ((emb_state_t)0u) -#define DOOR_OPEN ((emb_state_t)1u) -#define DOOR_JAMMED ((emb_state_t)2u) -#define DOOR_STATE_COUNT ((emb_state_t)3u) -#define DOOR_EV_OPEN (EMB_EV_USER + 0u) -#define DOOR_EV_CLOSE (EMB_EV_USER + 1u) -#define DOOR_EV_JAM (EMB_EV_USER + 2u) -typedef struct door { - emb_task_t task; /* first: the runtime's */ - door_data_t data; -} door_t; -extern door_t door; -#define DOOR_TASK (&door.task) -emb_state_t door_on_closed(door_t *self, const emb_task_event_t *ev); -emb_state_t door_on_open(door_t *self, const emb_task_event_t *ev); -emb_state_t door_on_jammed(door_t *self, const emb_task_event_t *ev); -void door_enter_open(door_t *self); -void door_exit_open(door_t *self); - -/* blink: periodic, every 500 ms */ -#define BLINK_DARK ((emb_state_t)0u) -#define BLINK_LIT ((emb_state_t)1u) -#define BLINK_STATE_COUNT ((emb_state_t)2u) -typedef struct blink { - emb_task_t task; /* first: the runtime's */ -} blink_t; -extern blink_t blink; -#define BLINK_TASK (&blink.task) -emb_state_t blink_on_dark(blink_t *self); -emb_state_t blink_on_lit(blink_t *self); - -#ifdef __cplusplus -} -#endif - -#endif /* EMB_TASKS_H */ diff --git a/examples/tasks/generated/.base/pico2_w/src/system.c b/examples/tasks/generated/.base/pico2_w/src/system.c deleted file mode 100644 index 04ec721b..00000000 --- a/examples/tasks/generated/.base/pico2_w/src/system.c +++ /dev/null @@ -1,29 +0,0 @@ -/* SPDX-License-Identifier: Apache-2.0 */ -/* - * This file is part of EmbLinkRTOS, a deterministic real-time kernel for microcontrollers. - * Licensed under the Apache License, Version 2.0; see the LICENSE file at the repository root. - */ - -/** - * @file system.c - * @brief The system tasks_demo's static definitions: the kernel creates each from its - * initialization table (SPEC-001 §6.4, SPEC-014 §5, A125). - * - * @details - * Generated by emb-hwgen 0.1.0, schema v0. Do not edit: change the - * description and run hw/gen/emb-hwgen.py generate --system examples/tasks/system.yaml (HW-003). - * Inputs (SHA-256): - * arch/cortex_m/arch.yaml - * c5c8e451c09717dee1713d07f8311b6d507e3b4c66c42d93e0ce11da6ec76d6d - * boards/rpi/pico2_w/board.yaml - * dad0ef7259e41ef3bd8fa07ea1c1f36040254a443deaf30d963b4fb14b5354a0 - * drivers/bindings.yaml - * d3c336ac05548e0addd1faac18f3dff70576d8069f11d89e6a761cf5c6132b49 - * examples/tasks/system.yaml - * 3dd9de88918f06e4b3a41232cb716a9e7d1c4b74ad18e71fd51644ae394ebf9c - * soc/rpi/rp2350/rp2350.yaml - * 9e60e99ecac8782bccd69e3bd69014af1d8891d6b6fbd822acff5bd9a526d8cd - * soc/rpi/rp2350/rp2350a.yaml - * 045cef7794c3b6c6d2ff48ba294c6308d00fe13bc65e346f2ba2ccde1cea24ff - */ -#include "system.h" diff --git a/examples/tasks/generated/.base/pico2_w/src/tasks.c b/examples/tasks/generated/.base/pico2_w/src/tasks.c deleted file mode 100644 index 200639be..00000000 --- a/examples/tasks/generated/.base/pico2_w/src/tasks.c +++ /dev/null @@ -1,126 +0,0 @@ -/* SPDX-License-Identifier: Apache-2.0 */ -/* - * This file is part of EmbLinkRTOS, a deterministic real-time kernel for microcontrollers. - * Licensed under the Apache License, Version 2.0; see the LICENSE file at the repository root. - */ - -/** - * @file tasks.c - * @brief The system tasks_demo's tasks: each one's queue, dispatch, description and thread - * (SPEC-020); the runtime is emb_task_run(). - * - * @details - * Generated by emb-hwgen 0.1.0, schema v0. Do not edit: change the - * description and run hw/gen/emb-hwgen.py generate --system examples/tasks/system.yaml (HW-003). - * Inputs (SHA-256): - * arch/cortex_m/arch.yaml - * c5c8e451c09717dee1713d07f8311b6d507e3b4c66c42d93e0ce11da6ec76d6d - * boards/rpi/pico2_w/board.yaml - * dad0ef7259e41ef3bd8fa07ea1c1f36040254a443deaf30d963b4fb14b5354a0 - * drivers/bindings.yaml - * d3c336ac05548e0addd1faac18f3dff70576d8069f11d89e6a761cf5c6132b49 - * examples/tasks/system.yaml - * 3dd9de88918f06e4b3a41232cb716a9e7d1c4b74ad18e71fd51644ae394ebf9c - * soc/rpi/rp2350/rp2350.yaml - * 9e60e99ecac8782bccd69e3bd69014af1d8891d6b6fbd822acff5bd9a526d8cd - * soc/rpi/rp2350/rp2350a.yaml - * 045cef7794c3b6c6d2ff48ba294c6308d00fe13bc65e346f2ba2ccde1cea24ff - */ -#include "tasks.h" - -/* ---- door ---- */ -static emb_task_event_t door_event; -EMB_MSGQ_DEFINE(door_task_queue, sizeof(emb_task_event_t), 8u, 0u); -static const uint32_t door_timeouts[3] = {0u, 2000u, 0u}; - -static emb_state_t door_dispatch(emb_state_t state, uint8_t why) -{ - emb_state_t next; - if (why == EMB_TASK_WHY_TIMEOUT) { - door_event.id = EMB_EV_TIMEOUT; - door_event.value = 0u; - } - switch (state) { - case DOOR_CLOSED: - next = door_on_closed(&door, &door_event); - break; - case DOOR_OPEN: - next = door_on_open(&door, &door_event); - break; - case DOOR_JAMMED: - next = door_on_jammed(&door, &door_event); - break; - default: - next = state; - break; - } - return next; -} - -static void door_enter(emb_state_t state) -{ - switch (state) { - case DOOR_OPEN: - door_enter_open(&door); - break; - default: - break; - } -} - -static void door_exit(emb_state_t state) -{ - switch (state) { - case DOOR_OPEN: - door_exit_open(&door); - break; - default: - break; - } -} - -static const emb_task_desc_t door_desc = {"door", door_dispatch, door_enter, door_exit, &door_event, &door_task_queue, - door_timeouts, 0u, (uint16_t)sizeof(emb_task_event_t), DOOR_CLOSED, - DOOR_STATE_COUNT, EMB_TASK_EVENT, 0u}; -door_t door = {.task = {.desc = &door_desc, .state = DOOR_CLOSED}}; - -static void door_main(void *arg) -{ - (void)arg; - emb_task_run(&door.task); -} - -EMB_THREAD_DEFINE(door_thread, door_main, NULL, 5u, 1024u, 0u); - -/* ---- blink ---- */ - -static emb_state_t blink_dispatch(emb_state_t state, uint8_t why) -{ - emb_state_t next; - (void)why; - switch (state) { - case BLINK_DARK: - next = blink_on_dark(&blink); - break; - case BLINK_LIT: - next = blink_on_lit(&blink); - break; - default: - next = state; - break; - } - return next; -} - -static const emb_task_desc_t blink_desc = {"blink", blink_dispatch, NULL, NULL, NULL, NULL, - NULL, 500u, 0u, BLINK_DARK, - BLINK_STATE_COUNT, EMB_TASK_PERIODIC, 0u}; -blink_t blink = {.task = {.desc = &blink_desc, .state = BLINK_DARK}}; - -static void blink_main(void *arg) -{ - (void)arg; - emb_task_run(&blink.task); -} - -EMB_THREAD_DEFINE(blink_thread, blink_main, NULL, 2u, 512u, 0u); diff --git a/examples/tasks/generated/nucleo_f446re/docs/system.md b/examples/tasks/generated/nucleo_f446re/docs/system.md deleted file mode 100644 index cf4e0183..00000000 --- a/examples/tasks/generated/nucleo_f446re/docs/system.md +++ /dev/null @@ -1,24 +0,0 @@ -# tasks_demo: the system on nucleo_f446re - -Generated from `examples/tasks/system.yaml` (SPEC-014 §5, A125). Profile base, 32 priorities, a minimum stack of 256 bytes. - -## Tasks - -| Task | Model | Priority | Stack | States (initial first) | Events | -|---|---|---|---|---|---| -| `door` | event, queue 8 | 5 | 1024 | closed, open, jammed | open, close, jam | -| `blink` | periodic, 500 ms | 2 | 512 | dark, lit | — | - ---- - -Generated by emb-hwgen 0.1.0, schema v0, from: - -| Input | SHA-256 | -|---|---| -| `arch/cortex_m/arch.yaml` | `c5c8e451c09717dee1713d07f8311b6d507e3b4c66c42d93e0ce11da6ec76d6d` | -| `boards/st/nucleo_f446re/board.yaml` | `d756f3a7f19dc7da82ee3afc168dc54946312c5a9990720953c0fedcdece54ea` | -| `drivers/bindings.yaml` | `d3c336ac05548e0addd1faac18f3dff70576d8069f11d89e6a761cf5c6132b49` | -| `examples/tasks/system.yaml` | `3dd9de88918f06e4b3a41232cb716a9e7d1c4b74ad18e71fd51644ae394ebf9c` | -| `soc/st/stm32f4/stm32f4.yaml` | `3db4a0a65c9624d865d4ed7fc6354bf95054d0c465b76a2091f06aeac3d7375f` | -| `soc/st/stm32f4/stm32f446.yaml` | `0d5cc7f5fce4c51be71678987720c85c6e76e05473ff8a78ea5035394316c055` | -| `soc/st/stm32f4/stm32f446re.yaml` | `b9a88d0a94aa17ee83317a3a56f7c194ec1b3107dfb3e82e453122dc1c48f6d4` | diff --git a/examples/tasks/generated/nucleo_f446re/include/system.h b/examples/tasks/generated/nucleo_f446re/include/system.h deleted file mode 100644 index 4c1c4099..00000000 --- a/examples/tasks/generated/nucleo_f446re/include/system.h +++ /dev/null @@ -1,46 +0,0 @@ -/* SPDX-License-Identifier: Apache-2.0 */ -/* - * This file is part of EmbLinkRTOS, a deterministic real-time kernel for microcontrollers. - * Licensed under the Apache License, Version 2.0; see the LICENSE file at the repository root. - */ - -/** - * @file system.h - * @brief The system tasks_demo's threads, objects, targets and watchdog for the application's - * sources (SPEC-014 §5, A125). - * - * @details - * Generated by emb-hwgen 0.1.0, schema v0. Do not edit: change the - * description and run hw/gen/emb-hwgen.py generate --system examples/tasks/system.yaml (HW-003). - * Inputs (SHA-256): - * arch/cortex_m/arch.yaml - * c5c8e451c09717dee1713d07f8311b6d507e3b4c66c42d93e0ce11da6ec76d6d - * boards/st/nucleo_f446re/board.yaml - * d756f3a7f19dc7da82ee3afc168dc54946312c5a9990720953c0fedcdece54ea - * drivers/bindings.yaml - * d3c336ac05548e0addd1faac18f3dff70576d8069f11d89e6a761cf5c6132b49 - * examples/tasks/system.yaml - * 3dd9de88918f06e4b3a41232cb716a9e7d1c4b74ad18e71fd51644ae394ebf9c - * soc/st/stm32f4/stm32f4.yaml - * 3db4a0a65c9624d865d4ed7fc6354bf95054d0c465b76a2091f06aeac3d7375f - * soc/st/stm32f4/stm32f446.yaml - * 0d5cc7f5fce4c51be71678987720c85c6e76e05473ff8a78ea5035394316c055 - * soc/st/stm32f4/stm32f446re.yaml - * b9a88d0a94aa17ee83317a3a56f7c194ec1b3107dfb3e82e453122dc1c48f6d4 - */ -#ifndef EMB_SYSTEM_H -#define EMB_SYSTEM_H - -#include - -#include "tasks.h" - -#ifdef __cplusplus -extern "C" { -#endif - -#ifdef __cplusplus -} -#endif - -#endif /* EMB_SYSTEM_H */ diff --git a/examples/tasks/generated/nucleo_f446re/include/tasks.h b/examples/tasks/generated/nucleo_f446re/include/tasks.h deleted file mode 100644 index a0a491d9..00000000 --- a/examples/tasks/generated/nucleo_f446re/include/tasks.h +++ /dev/null @@ -1,80 +0,0 @@ -/* SPDX-License-Identifier: Apache-2.0 */ -/* - * This file is part of EmbLinkRTOS, a deterministic real-time kernel for microcontrollers. - * Licensed under the Apache License, Version 2.0; see the LICENSE file at the repository root. - */ - -/** - * @file tasks.h - * @brief The system tasks_demo's tasks: their states, events, types, handlers and handles - * (SPEC-020). - * - * @details - * Generated by emb-hwgen 0.1.0, schema v0. Do not edit: change the - * description and run hw/gen/emb-hwgen.py generate --system examples/tasks/system.yaml (HW-003). - * Inputs (SHA-256): - * arch/cortex_m/arch.yaml - * c5c8e451c09717dee1713d07f8311b6d507e3b4c66c42d93e0ce11da6ec76d6d - * boards/st/nucleo_f446re/board.yaml - * d756f3a7f19dc7da82ee3afc168dc54946312c5a9990720953c0fedcdece54ea - * drivers/bindings.yaml - * d3c336ac05548e0addd1faac18f3dff70576d8069f11d89e6a761cf5c6132b49 - * examples/tasks/system.yaml - * 3dd9de88918f06e4b3a41232cb716a9e7d1c4b74ad18e71fd51644ae394ebf9c - * soc/st/stm32f4/stm32f4.yaml - * 3db4a0a65c9624d865d4ed7fc6354bf95054d0c465b76a2091f06aeac3d7375f - * soc/st/stm32f4/stm32f446.yaml - * 0d5cc7f5fce4c51be71678987720c85c6e76e05473ff8a78ea5035394316c055 - * soc/st/stm32f4/stm32f446re.yaml - * b9a88d0a94aa17ee83317a3a56f7c194ec1b3107dfb3e82e453122dc1c48f6d4 - */ -#ifndef EMB_TASKS_H -#define EMB_TASKS_H - -#include - -#include - -#include "tasks/door.h" - -#ifdef __cplusplus -extern "C" { -#endif - -/* door: event */ -#define DOOR_CLOSED ((emb_state_t)0u) -#define DOOR_OPEN ((emb_state_t)1u) -#define DOOR_JAMMED ((emb_state_t)2u) -#define DOOR_STATE_COUNT ((emb_state_t)3u) -#define DOOR_EV_OPEN (EMB_EV_USER + 0u) -#define DOOR_EV_CLOSE (EMB_EV_USER + 1u) -#define DOOR_EV_JAM (EMB_EV_USER + 2u) -typedef struct door { - emb_task_t task; /* first: the runtime's */ - door_data_t data; -} door_t; -extern door_t door; -#define DOOR_TASK (&door.task) -emb_state_t door_on_closed(door_t *self, const emb_task_event_t *ev); -emb_state_t door_on_open(door_t *self, const emb_task_event_t *ev); -emb_state_t door_on_jammed(door_t *self, const emb_task_event_t *ev); -void door_enter_open(door_t *self); -void door_exit_open(door_t *self); - -/* blink: periodic, every 500 ms */ -#define BLINK_DARK ((emb_state_t)0u) -#define BLINK_LIT ((emb_state_t)1u) -#define BLINK_STATE_COUNT ((emb_state_t)2u) -typedef struct blink { - emb_task_t task; /* first: the runtime's */ -} blink_t; -extern blink_t blink; -#define BLINK_TASK (&blink.task) -emb_state_t blink_on_dark(blink_t *self); -emb_state_t blink_on_lit(blink_t *self); - -#ifdef __cplusplus -} -#endif - -#endif /* EMB_TASKS_H */ diff --git a/examples/tasks/generated/nucleo_f446re/src/system.c b/examples/tasks/generated/nucleo_f446re/src/system.c deleted file mode 100644 index 580f0cf5..00000000 --- a/examples/tasks/generated/nucleo_f446re/src/system.c +++ /dev/null @@ -1,31 +0,0 @@ -/* SPDX-License-Identifier: Apache-2.0 */ -/* - * This file is part of EmbLinkRTOS, a deterministic real-time kernel for microcontrollers. - * Licensed under the Apache License, Version 2.0; see the LICENSE file at the repository root. - */ - -/** - * @file system.c - * @brief The system tasks_demo's static definitions: the kernel creates each from its - * initialization table (SPEC-001 §6.4, SPEC-014 §5, A125). - * - * @details - * Generated by emb-hwgen 0.1.0, schema v0. Do not edit: change the - * description and run hw/gen/emb-hwgen.py generate --system examples/tasks/system.yaml (HW-003). - * Inputs (SHA-256): - * arch/cortex_m/arch.yaml - * c5c8e451c09717dee1713d07f8311b6d507e3b4c66c42d93e0ce11da6ec76d6d - * boards/st/nucleo_f446re/board.yaml - * d756f3a7f19dc7da82ee3afc168dc54946312c5a9990720953c0fedcdece54ea - * drivers/bindings.yaml - * d3c336ac05548e0addd1faac18f3dff70576d8069f11d89e6a761cf5c6132b49 - * examples/tasks/system.yaml - * 3dd9de88918f06e4b3a41232cb716a9e7d1c4b74ad18e71fd51644ae394ebf9c - * soc/st/stm32f4/stm32f4.yaml - * 3db4a0a65c9624d865d4ed7fc6354bf95054d0c465b76a2091f06aeac3d7375f - * soc/st/stm32f4/stm32f446.yaml - * 0d5cc7f5fce4c51be71678987720c85c6e76e05473ff8a78ea5035394316c055 - * soc/st/stm32f4/stm32f446re.yaml - * b9a88d0a94aa17ee83317a3a56f7c194ec1b3107dfb3e82e453122dc1c48f6d4 - */ -#include "system.h" diff --git a/examples/tasks/generated/nucleo_f446re/src/tasks.c b/examples/tasks/generated/nucleo_f446re/src/tasks.c deleted file mode 100644 index f895ba09..00000000 --- a/examples/tasks/generated/nucleo_f446re/src/tasks.c +++ /dev/null @@ -1,128 +0,0 @@ -/* SPDX-License-Identifier: Apache-2.0 */ -/* - * This file is part of EmbLinkRTOS, a deterministic real-time kernel for microcontrollers. - * Licensed under the Apache License, Version 2.0; see the LICENSE file at the repository root. - */ - -/** - * @file tasks.c - * @brief The system tasks_demo's tasks: each one's queue, dispatch, description and thread - * (SPEC-020); the runtime is emb_task_run(). - * - * @details - * Generated by emb-hwgen 0.1.0, schema v0. Do not edit: change the - * description and run hw/gen/emb-hwgen.py generate --system examples/tasks/system.yaml (HW-003). - * Inputs (SHA-256): - * arch/cortex_m/arch.yaml - * c5c8e451c09717dee1713d07f8311b6d507e3b4c66c42d93e0ce11da6ec76d6d - * boards/st/nucleo_f446re/board.yaml - * d756f3a7f19dc7da82ee3afc168dc54946312c5a9990720953c0fedcdece54ea - * drivers/bindings.yaml - * d3c336ac05548e0addd1faac18f3dff70576d8069f11d89e6a761cf5c6132b49 - * examples/tasks/system.yaml - * 3dd9de88918f06e4b3a41232cb716a9e7d1c4b74ad18e71fd51644ae394ebf9c - * soc/st/stm32f4/stm32f4.yaml - * 3db4a0a65c9624d865d4ed7fc6354bf95054d0c465b76a2091f06aeac3d7375f - * soc/st/stm32f4/stm32f446.yaml - * 0d5cc7f5fce4c51be71678987720c85c6e76e05473ff8a78ea5035394316c055 - * soc/st/stm32f4/stm32f446re.yaml - * b9a88d0a94aa17ee83317a3a56f7c194ec1b3107dfb3e82e453122dc1c48f6d4 - */ -#include "tasks.h" - -/* ---- door ---- */ -static emb_task_event_t door_event; -EMB_MSGQ_DEFINE(door_task_queue, sizeof(emb_task_event_t), 8u, 0u); -static const uint32_t door_timeouts[3] = {0u, 2000u, 0u}; - -static emb_state_t door_dispatch(emb_state_t state, uint8_t why) -{ - emb_state_t next; - if (why == EMB_TASK_WHY_TIMEOUT) { - door_event.id = EMB_EV_TIMEOUT; - door_event.value = 0u; - } - switch (state) { - case DOOR_CLOSED: - next = door_on_closed(&door, &door_event); - break; - case DOOR_OPEN: - next = door_on_open(&door, &door_event); - break; - case DOOR_JAMMED: - next = door_on_jammed(&door, &door_event); - break; - default: - next = state; - break; - } - return next; -} - -static void door_enter(emb_state_t state) -{ - switch (state) { - case DOOR_OPEN: - door_enter_open(&door); - break; - default: - break; - } -} - -static void door_exit(emb_state_t state) -{ - switch (state) { - case DOOR_OPEN: - door_exit_open(&door); - break; - default: - break; - } -} - -static const emb_task_desc_t door_desc = {"door", door_dispatch, door_enter, door_exit, &door_event, &door_task_queue, - door_timeouts, 0u, (uint16_t)sizeof(emb_task_event_t), DOOR_CLOSED, - DOOR_STATE_COUNT, EMB_TASK_EVENT, 0u}; -door_t door = {.task = {.desc = &door_desc, .state = DOOR_CLOSED}}; - -static void door_main(void *arg) -{ - (void)arg; - emb_task_run(&door.task); -} - -EMB_THREAD_DEFINE(door_thread, door_main, NULL, 5u, 1024u, 0u); - -/* ---- blink ---- */ - -static emb_state_t blink_dispatch(emb_state_t state, uint8_t why) -{ - emb_state_t next; - (void)why; - switch (state) { - case BLINK_DARK: - next = blink_on_dark(&blink); - break; - case BLINK_LIT: - next = blink_on_lit(&blink); - break; - default: - next = state; - break; - } - return next; -} - -static const emb_task_desc_t blink_desc = {"blink", blink_dispatch, NULL, NULL, NULL, NULL, - NULL, 500u, 0u, BLINK_DARK, - BLINK_STATE_COUNT, EMB_TASK_PERIODIC, 0u}; -blink_t blink = {.task = {.desc = &blink_desc, .state = BLINK_DARK}}; - -static void blink_main(void *arg) -{ - (void)arg; - emb_task_run(&blink.task); -} - -EMB_THREAD_DEFINE(blink_thread, blink_main, NULL, 2u, 512u, 0u); diff --git a/examples/tasks/generated/pico2_w/docs/system.md b/examples/tasks/generated/pico2_w/docs/system.md deleted file mode 100644 index 09fb54fc..00000000 --- a/examples/tasks/generated/pico2_w/docs/system.md +++ /dev/null @@ -1,23 +0,0 @@ -# tasks_demo: the system on pico2_w - -Generated from `examples/tasks/system.yaml` (SPEC-014 §5, A125). Profile base, 32 priorities, a minimum stack of 256 bytes. - -## Tasks - -| Task | Model | Priority | Stack | States (initial first) | Events | -|---|---|---|---|---|---| -| `door` | event, queue 8 | 5 | 1024 | closed, open, jammed | open, close, jam | -| `blink` | periodic, 500 ms | 2 | 512 | dark, lit | — | - ---- - -Generated by emb-hwgen 0.1.0, schema v0, from: - -| Input | SHA-256 | -|---|---| -| `arch/cortex_m/arch.yaml` | `c5c8e451c09717dee1713d07f8311b6d507e3b4c66c42d93e0ce11da6ec76d6d` | -| `boards/rpi/pico2_w/board.yaml` | `dad0ef7259e41ef3bd8fa07ea1c1f36040254a443deaf30d963b4fb14b5354a0` | -| `drivers/bindings.yaml` | `d3c336ac05548e0addd1faac18f3dff70576d8069f11d89e6a761cf5c6132b49` | -| `examples/tasks/system.yaml` | `3dd9de88918f06e4b3a41232cb716a9e7d1c4b74ad18e71fd51644ae394ebf9c` | -| `soc/rpi/rp2350/rp2350.yaml` | `9e60e99ecac8782bccd69e3bd69014af1d8891d6b6fbd822acff5bd9a526d8cd` | -| `soc/rpi/rp2350/rp2350a.yaml` | `045cef7794c3b6c6d2ff48ba294c6308d00fe13bc65e346f2ba2ccde1cea24ff` | diff --git a/examples/tasks/generated/pico2_w/include/system.h b/examples/tasks/generated/pico2_w/include/system.h deleted file mode 100644 index 43ef92cb..00000000 --- a/examples/tasks/generated/pico2_w/include/system.h +++ /dev/null @@ -1,44 +0,0 @@ -/* SPDX-License-Identifier: Apache-2.0 */ -/* - * This file is part of EmbLinkRTOS, a deterministic real-time kernel for microcontrollers. - * Licensed under the Apache License, Version 2.0; see the LICENSE file at the repository root. - */ - -/** - * @file system.h - * @brief The system tasks_demo's threads, objects, targets and watchdog for the application's - * sources (SPEC-014 §5, A125). - * - * @details - * Generated by emb-hwgen 0.1.0, schema v0. Do not edit: change the - * description and run hw/gen/emb-hwgen.py generate --system examples/tasks/system.yaml (HW-003). - * Inputs (SHA-256): - * arch/cortex_m/arch.yaml - * c5c8e451c09717dee1713d07f8311b6d507e3b4c66c42d93e0ce11da6ec76d6d - * boards/rpi/pico2_w/board.yaml - * dad0ef7259e41ef3bd8fa07ea1c1f36040254a443deaf30d963b4fb14b5354a0 - * drivers/bindings.yaml - * d3c336ac05548e0addd1faac18f3dff70576d8069f11d89e6a761cf5c6132b49 - * examples/tasks/system.yaml - * 3dd9de88918f06e4b3a41232cb716a9e7d1c4b74ad18e71fd51644ae394ebf9c - * soc/rpi/rp2350/rp2350.yaml - * 9e60e99ecac8782bccd69e3bd69014af1d8891d6b6fbd822acff5bd9a526d8cd - * soc/rpi/rp2350/rp2350a.yaml - * 045cef7794c3b6c6d2ff48ba294c6308d00fe13bc65e346f2ba2ccde1cea24ff - */ -#ifndef EMB_SYSTEM_H -#define EMB_SYSTEM_H - -#include - -#include "tasks.h" - -#ifdef __cplusplus -extern "C" { -#endif - -#ifdef __cplusplus -} -#endif - -#endif /* EMB_SYSTEM_H */ diff --git a/examples/tasks/generated/pico2_w/include/tasks.h b/examples/tasks/generated/pico2_w/include/tasks.h deleted file mode 100644 index 72857c28..00000000 --- a/examples/tasks/generated/pico2_w/include/tasks.h +++ /dev/null @@ -1,78 +0,0 @@ -/* SPDX-License-Identifier: Apache-2.0 */ -/* - * This file is part of EmbLinkRTOS, a deterministic real-time kernel for microcontrollers. - * Licensed under the Apache License, Version 2.0; see the LICENSE file at the repository root. - */ - -/** - * @file tasks.h - * @brief The system tasks_demo's tasks: their states, events, types, handlers and handles - * (SPEC-020). - * - * @details - * Generated by emb-hwgen 0.1.0, schema v0. Do not edit: change the - * description and run hw/gen/emb-hwgen.py generate --system examples/tasks/system.yaml (HW-003). - * Inputs (SHA-256): - * arch/cortex_m/arch.yaml - * c5c8e451c09717dee1713d07f8311b6d507e3b4c66c42d93e0ce11da6ec76d6d - * boards/rpi/pico2_w/board.yaml - * dad0ef7259e41ef3bd8fa07ea1c1f36040254a443deaf30d963b4fb14b5354a0 - * drivers/bindings.yaml - * d3c336ac05548e0addd1faac18f3dff70576d8069f11d89e6a761cf5c6132b49 - * examples/tasks/system.yaml - * 3dd9de88918f06e4b3a41232cb716a9e7d1c4b74ad18e71fd51644ae394ebf9c - * soc/rpi/rp2350/rp2350.yaml - * 9e60e99ecac8782bccd69e3bd69014af1d8891d6b6fbd822acff5bd9a526d8cd - * soc/rpi/rp2350/rp2350a.yaml - * 045cef7794c3b6c6d2ff48ba294c6308d00fe13bc65e346f2ba2ccde1cea24ff - */ -#ifndef EMB_TASKS_H -#define EMB_TASKS_H - -#include - -#include - -#include "tasks/door.h" - -#ifdef __cplusplus -extern "C" { -#endif - -/* door: event */ -#define DOOR_CLOSED ((emb_state_t)0u) -#define DOOR_OPEN ((emb_state_t)1u) -#define DOOR_JAMMED ((emb_state_t)2u) -#define DOOR_STATE_COUNT ((emb_state_t)3u) -#define DOOR_EV_OPEN (EMB_EV_USER + 0u) -#define DOOR_EV_CLOSE (EMB_EV_USER + 1u) -#define DOOR_EV_JAM (EMB_EV_USER + 2u) -typedef struct door { - emb_task_t task; /* first: the runtime's */ - door_data_t data; -} door_t; -extern door_t door; -#define DOOR_TASK (&door.task) -emb_state_t door_on_closed(door_t *self, const emb_task_event_t *ev); -emb_state_t door_on_open(door_t *self, const emb_task_event_t *ev); -emb_state_t door_on_jammed(door_t *self, const emb_task_event_t *ev); -void door_enter_open(door_t *self); -void door_exit_open(door_t *self); - -/* blink: periodic, every 500 ms */ -#define BLINK_DARK ((emb_state_t)0u) -#define BLINK_LIT ((emb_state_t)1u) -#define BLINK_STATE_COUNT ((emb_state_t)2u) -typedef struct blink { - emb_task_t task; /* first: the runtime's */ -} blink_t; -extern blink_t blink; -#define BLINK_TASK (&blink.task) -emb_state_t blink_on_dark(blink_t *self); -emb_state_t blink_on_lit(blink_t *self); - -#ifdef __cplusplus -} -#endif - -#endif /* EMB_TASKS_H */ diff --git a/examples/tasks/generated/pico2_w/src/system.c b/examples/tasks/generated/pico2_w/src/system.c deleted file mode 100644 index 04ec721b..00000000 --- a/examples/tasks/generated/pico2_w/src/system.c +++ /dev/null @@ -1,29 +0,0 @@ -/* SPDX-License-Identifier: Apache-2.0 */ -/* - * This file is part of EmbLinkRTOS, a deterministic real-time kernel for microcontrollers. - * Licensed under the Apache License, Version 2.0; see the LICENSE file at the repository root. - */ - -/** - * @file system.c - * @brief The system tasks_demo's static definitions: the kernel creates each from its - * initialization table (SPEC-001 §6.4, SPEC-014 §5, A125). - * - * @details - * Generated by emb-hwgen 0.1.0, schema v0. Do not edit: change the - * description and run hw/gen/emb-hwgen.py generate --system examples/tasks/system.yaml (HW-003). - * Inputs (SHA-256): - * arch/cortex_m/arch.yaml - * c5c8e451c09717dee1713d07f8311b6d507e3b4c66c42d93e0ce11da6ec76d6d - * boards/rpi/pico2_w/board.yaml - * dad0ef7259e41ef3bd8fa07ea1c1f36040254a443deaf30d963b4fb14b5354a0 - * drivers/bindings.yaml - * d3c336ac05548e0addd1faac18f3dff70576d8069f11d89e6a761cf5c6132b49 - * examples/tasks/system.yaml - * 3dd9de88918f06e4b3a41232cb716a9e7d1c4b74ad18e71fd51644ae394ebf9c - * soc/rpi/rp2350/rp2350.yaml - * 9e60e99ecac8782bccd69e3bd69014af1d8891d6b6fbd822acff5bd9a526d8cd - * soc/rpi/rp2350/rp2350a.yaml - * 045cef7794c3b6c6d2ff48ba294c6308d00fe13bc65e346f2ba2ccde1cea24ff - */ -#include "system.h" diff --git a/examples/tasks/generated/pico2_w/src/tasks.c b/examples/tasks/generated/pico2_w/src/tasks.c deleted file mode 100644 index 200639be..00000000 --- a/examples/tasks/generated/pico2_w/src/tasks.c +++ /dev/null @@ -1,126 +0,0 @@ -/* SPDX-License-Identifier: Apache-2.0 */ -/* - * This file is part of EmbLinkRTOS, a deterministic real-time kernel for microcontrollers. - * Licensed under the Apache License, Version 2.0; see the LICENSE file at the repository root. - */ - -/** - * @file tasks.c - * @brief The system tasks_demo's tasks: each one's queue, dispatch, description and thread - * (SPEC-020); the runtime is emb_task_run(). - * - * @details - * Generated by emb-hwgen 0.1.0, schema v0. Do not edit: change the - * description and run hw/gen/emb-hwgen.py generate --system examples/tasks/system.yaml (HW-003). - * Inputs (SHA-256): - * arch/cortex_m/arch.yaml - * c5c8e451c09717dee1713d07f8311b6d507e3b4c66c42d93e0ce11da6ec76d6d - * boards/rpi/pico2_w/board.yaml - * dad0ef7259e41ef3bd8fa07ea1c1f36040254a443deaf30d963b4fb14b5354a0 - * drivers/bindings.yaml - * d3c336ac05548e0addd1faac18f3dff70576d8069f11d89e6a761cf5c6132b49 - * examples/tasks/system.yaml - * 3dd9de88918f06e4b3a41232cb716a9e7d1c4b74ad18e71fd51644ae394ebf9c - * soc/rpi/rp2350/rp2350.yaml - * 9e60e99ecac8782bccd69e3bd69014af1d8891d6b6fbd822acff5bd9a526d8cd - * soc/rpi/rp2350/rp2350a.yaml - * 045cef7794c3b6c6d2ff48ba294c6308d00fe13bc65e346f2ba2ccde1cea24ff - */ -#include "tasks.h" - -/* ---- door ---- */ -static emb_task_event_t door_event; -EMB_MSGQ_DEFINE(door_task_queue, sizeof(emb_task_event_t), 8u, 0u); -static const uint32_t door_timeouts[3] = {0u, 2000u, 0u}; - -static emb_state_t door_dispatch(emb_state_t state, uint8_t why) -{ - emb_state_t next; - if (why == EMB_TASK_WHY_TIMEOUT) { - door_event.id = EMB_EV_TIMEOUT; - door_event.value = 0u; - } - switch (state) { - case DOOR_CLOSED: - next = door_on_closed(&door, &door_event); - break; - case DOOR_OPEN: - next = door_on_open(&door, &door_event); - break; - case DOOR_JAMMED: - next = door_on_jammed(&door, &door_event); - break; - default: - next = state; - break; - } - return next; -} - -static void door_enter(emb_state_t state) -{ - switch (state) { - case DOOR_OPEN: - door_enter_open(&door); - break; - default: - break; - } -} - -static void door_exit(emb_state_t state) -{ - switch (state) { - case DOOR_OPEN: - door_exit_open(&door); - break; - default: - break; - } -} - -static const emb_task_desc_t door_desc = {"door", door_dispatch, door_enter, door_exit, &door_event, &door_task_queue, - door_timeouts, 0u, (uint16_t)sizeof(emb_task_event_t), DOOR_CLOSED, - DOOR_STATE_COUNT, EMB_TASK_EVENT, 0u}; -door_t door = {.task = {.desc = &door_desc, .state = DOOR_CLOSED}}; - -static void door_main(void *arg) -{ - (void)arg; - emb_task_run(&door.task); -} - -EMB_THREAD_DEFINE(door_thread, door_main, NULL, 5u, 1024u, 0u); - -/* ---- blink ---- */ - -static emb_state_t blink_dispatch(emb_state_t state, uint8_t why) -{ - emb_state_t next; - (void)why; - switch (state) { - case BLINK_DARK: - next = blink_on_dark(&blink); - break; - case BLINK_LIT: - next = blink_on_lit(&blink); - break; - default: - next = state; - break; - } - return next; -} - -static const emb_task_desc_t blink_desc = {"blink", blink_dispatch, NULL, NULL, NULL, NULL, - NULL, 500u, 0u, BLINK_DARK, - BLINK_STATE_COUNT, EMB_TASK_PERIODIC, 0u}; -blink_t blink = {.task = {.desc = &blink_desc, .state = BLINK_DARK}}; - -static void blink_main(void *arg) -{ - (void)arg; - emb_task_run(&blink.task); -} - -EMB_THREAD_DEFINE(blink_thread, blink_main, NULL, 2u, 512u, 0u); diff --git a/examples/tasks/src/blink.c b/examples/tasks/src/blink.c new file mode 100644 index 00000000..f6acf6f9 --- /dev/null +++ b/examples/tasks/src/blink.c @@ -0,0 +1,122 @@ +/* SPDX-License-Identifier: Apache-2.0 */ +/* + * This file is part of EmbLinkRTOS, a deterministic real-time kernel for microcontrollers. + * Licensed under the Apache License, Version 2.0; see the LICENSE file at the repository root. + */ + +/******************************************************************************* + blink: a periodic task, every 500 ms + + File Name: + blink.c + + Summary: + The blink task's state machine. + + Description: + This file holds the blink task's data and BLINK_Tasks(), the switch on its + state that its thread runs every 500 ms (SPEC-020). + + Generated by emb-hwgen from system.yaml, then yours to edit: regeneration + merges its changes with yours (A126, A130). + *******************************************************************************/ + +// ***************************************************************************** +// ***************************************************************************** +// Section: Included Files +// ***************************************************************************** +// ***************************************************************************** + +#include "definitions.h" + +// ***************************************************************************** +// ***************************************************************************** +// Section: Global Data Definitions +// ***************************************************************************** +// ***************************************************************************** + +/* Application Data + + Summary: + Holds the blink task's data. + + Description: + This structure holds the task's data. + + Remarks: + BLINK_Initialize() starts it, and the task's BLINK_Tasks() uses it. +*/ +BLINK_DATA blinkData; + +// ***************************************************************************** +// ***************************************************************************** +// Section: Application Callback Functions +// ***************************************************************************** +// ***************************************************************************** + +/* TODO: Add any necessary callback functions. */ + +// ***************************************************************************** +// ***************************************************************************** +// Section: Application Local Functions +// ***************************************************************************** +// ***************************************************************************** + +/* TODO: Add any necessary local functions. */ + +// ***************************************************************************** +// ***************************************************************************** +// Section: Application Initialization and State Machine Functions +// ***************************************************************************** +// ***************************************************************************** + +/******************************************************************************* + Function: + void BLINK_Initialize ( void ) + + Remarks: + See prototype in blink.h. + */ +void BLINK_Initialize(void) +{ + /* Place the task in its initial state. */ + blinkData.state = BLINK_STATE_DARK; + blinkData.blinks = 0u; +} + +/******************************************************************************* + Function: + void BLINK_Tasks ( void ) + + Remarks: + See prototype in blink.h. + */ +void BLINK_Tasks(void) +{ + /* Check the task's current state. */ + switch (blinkData.state) { + /* The task's initial state. */ + case BLINK_STATE_DARK: { + emb_board_led_toggle(); + blinkData.state = BLINK_STATE_LIT; + break; + } + case BLINK_STATE_LIT: { + emb_board_led_toggle(); + blinkData.blinks++; + if ((blinkData.blinks % 4u) == 0u) { /* every fourth blink: wake, and the door opens */ + (void)emb_irq_pend(WAKE_IRQ); + } + blinkData.state = BLINK_STATE_DARK; + break; + } + /* The default state should never be executed. */ + default: { + /* TODO: Handle error in the task's state machine. */ + break; + } + } +} +/******************************************************************************* + End of File +*/ diff --git a/examples/tasks/src/blink.h b/examples/tasks/src/blink.h new file mode 100644 index 00000000..2a6f9f27 --- /dev/null +++ b/examples/tasks/src/blink.h @@ -0,0 +1,165 @@ +/* SPDX-License-Identifier: Apache-2.0 */ +/* + * This file is part of EmbLinkRTOS, a deterministic real-time kernel for microcontrollers. + * Licensed under the Apache License, Version 2.0; see the LICENSE file at the repository root. + */ + +/******************************************************************************* + blink: a periodic task, every 500 ms + + File Name: + blink.h + + Summary: + The blink task's states, data and functions. + + Description: + This header declares what the blink task's own file defines: its states, its + data, BLINK_Initialize() and BLINK_Tasks(), which the task's thread calls + every 500 ms, without drift (SPEC-020). + + Generated by emb-hwgen from system.yaml, then yours to edit: regeneration + merges its changes with yours (A126, A130). + *******************************************************************************/ + +#ifndef BLINK_H +#define BLINK_H + +// ***************************************************************************** +// ***************************************************************************** +// Section: Included Files +// ***************************************************************************** +// ***************************************************************************** + +#include "configuration.h" + +#include + +#include +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +// ***************************************************************************** +// ***************************************************************************** +// Section: Type Definitions +// ***************************************************************************** +// ***************************************************************************** + +/* Application states + + Summary: + The blink task's states. + + Description: + The states system.yaml declares for the task, in its order: they are the + task runtime's numbers, which tasks.c checks. Declare a state in + system.yaml, and regeneration adds it here, with its case in BLINK_Tasks(). +*/ +typedef enum { + /* The task's initial state. */ + BLINK_STATE_DARK = 0, + BLINK_STATE_LIT, +} BLINK_STATES; + +/* Application Data + + Summary: + Holds the blink task's data. + + Description: + This structure holds the task's data: only the task's thread runs its + BLINK_Tasks(). + + Remarks: + BLINK_Tasks() moves the task by setting state. +*/ +typedef struct { + /* The task's current state */ + BLINK_STATES state; + + /* The blinks so far */ + uint32_t blinks; +} BLINK_DATA; + +extern BLINK_DATA blinkData; + +// ***************************************************************************** +// ***************************************************************************** +// Section: Application Initialization and State Machine Functions +// ***************************************************************************** +// ***************************************************************************** + +/******************************************************************************* + Function: + void BLINK_Initialize ( void ) + + Summary: + The blink task's initialization. + + Description: + This function puts the task in its initial state, BLINK_STATE_DARK, and + prepares its data, before the kernel starts its thread. + + Precondition: + The board and the kernel are initialized. The KERNEL devices are not ready + yet: use them from the task's states. + + Parameters: + None. + + Returns: + None. + + Example: + + BLINK_Initialize(); + + + Remarks: + SYS_Initialize() calls it. +*/ +void BLINK_Initialize(void); + +/******************************************************************************* + Function: + void BLINK_Tasks ( void ) + + Summary: + The blink task's state machine. + + Description: + This function runs the task's current state, blinkData.state, once: its + thread calls it every 500 ms. + + Precondition: + BLINK_Initialize() has run. + + Parameters: + None. + + Returns: + None. + + Example: + + BLINK_Tasks(); + + + Remarks: + Its thread calls it on a period that does not drift; a period it overruns is + counted, not run twice (KRN-TSK-004). +*/ +void BLINK_Tasks(void); + +#ifdef __cplusplus +} +#endif + +#endif /* BLINK_H */ +/******************************************************************************* + End of File +*/ diff --git a/examples/tasks/generated/.base/_app/CMakeLists.txt b/examples/tasks/src/config/.base/_app/CMakeLists.txt similarity index 91% rename from examples/tasks/generated/.base/_app/CMakeLists.txt rename to examples/tasks/src/config/.base/_app/CMakeLists.txt index a2205051..75ef94b1 100644 --- a/examples/tasks/generated/.base/_app/CMakeLists.txt +++ b/examples/tasks/src/config/.base/_app/CMakeLists.txt @@ -17,4 +17,4 @@ find_package(EmbLinkRTOS REQUIRED) project(tasks_demo LANGUAGES C) emb_kernel() -emb_add_executable(tasks_demo src/main.c src/tasks/door.c src/tasks/blink.c) +emb_add_executable(tasks_demo src/main.c src/door.c src/blink.c src/interrupt_handlers.c) diff --git a/examples/tasks/src/config/.base/_app/src/blink.c b/examples/tasks/src/config/.base/_app/src/blink.c new file mode 100644 index 00000000..1f2918bc --- /dev/null +++ b/examples/tasks/src/config/.base/_app/src/blink.c @@ -0,0 +1,117 @@ +/* SPDX-License-Identifier: Apache-2.0 */ +/* + * This file is part of EmbLinkRTOS, a deterministic real-time kernel for microcontrollers. + * Licensed under the Apache License, Version 2.0; see the LICENSE file at the repository root. + */ + +/******************************************************************************* + blink: a periodic task, every 500 ms + + File Name: + blink.c + + Summary: + The blink task's state machine. + + Description: + This file holds the blink task's data and BLINK_Tasks(), the switch on its + state that its thread runs every 500 ms (SPEC-020). + + Generated by emb-hwgen from system.yaml, then yours to edit: regeneration + merges its changes with yours (A126, A130). + *******************************************************************************/ + +// ***************************************************************************** +// ***************************************************************************** +// Section: Included Files +// ***************************************************************************** +// ***************************************************************************** + +#include "definitions.h" + +// ***************************************************************************** +// ***************************************************************************** +// Section: Global Data Definitions +// ***************************************************************************** +// ***************************************************************************** + +/* Application Data + + Summary: + Holds the blink task's data. + + Description: + This structure holds the task's data. + + Remarks: + BLINK_Initialize() starts it, and the task's BLINK_Tasks() uses it. +*/ +BLINK_DATA blinkData; + +// ***************************************************************************** +// ***************************************************************************** +// Section: Application Callback Functions +// ***************************************************************************** +// ***************************************************************************** + +/* TODO: Add any necessary callback functions. */ + +// ***************************************************************************** +// ***************************************************************************** +// Section: Application Local Functions +// ***************************************************************************** +// ***************************************************************************** + +/* TODO: Add any necessary local functions. */ + +// ***************************************************************************** +// ***************************************************************************** +// Section: Application Initialization and State Machine Functions +// ***************************************************************************** +// ***************************************************************************** + +/******************************************************************************* + Function: + void BLINK_Initialize ( void ) + + Remarks: + See prototype in blink.h. + */ +void BLINK_Initialize(void) +{ + /* Place the task in its initial state. */ + blinkData.state = BLINK_STATE_DARK; + + /* TODO: Initialize the task's data. */ +} + +/******************************************************************************* + Function: + void BLINK_Tasks ( void ) + + Remarks: + See prototype in blink.h. + */ +void BLINK_Tasks(void) +{ + /* Check the task's current state. */ + switch (blinkData.state) { + /* The task's initial state. */ + case BLINK_STATE_DARK: { + /* TODO: Do this state's work; set blinkData.state to move. */ + break; + } + case BLINK_STATE_LIT: { + /* TODO: Do this state's work; set blinkData.state to move. */ + break; + } + /* The default state should never be executed. */ + default: { + /* TODO: Handle error in the task's state machine. */ + break; + } + } +} +/******************************************************************************* + End of File +*/ diff --git a/examples/tasks/src/config/.base/_app/src/blink.h b/examples/tasks/src/config/.base/_app/src/blink.h new file mode 100644 index 00000000..ab3fea25 --- /dev/null +++ b/examples/tasks/src/config/.base/_app/src/blink.h @@ -0,0 +1,164 @@ +/* SPDX-License-Identifier: Apache-2.0 */ +/* + * This file is part of EmbLinkRTOS, a deterministic real-time kernel for microcontrollers. + * Licensed under the Apache License, Version 2.0; see the LICENSE file at the repository root. + */ + +/******************************************************************************* + blink: a periodic task, every 500 ms + + File Name: + blink.h + + Summary: + The blink task's states, data and functions. + + Description: + This header declares what the blink task's own file defines: its states, its + data, BLINK_Initialize() and BLINK_Tasks(), which the task's thread calls + every 500 ms, without drift (SPEC-020). + + Generated by emb-hwgen from system.yaml, then yours to edit: regeneration + merges its changes with yours (A126, A130). + *******************************************************************************/ + +#ifndef BLINK_H +#define BLINK_H + +// ***************************************************************************** +// ***************************************************************************** +// Section: Included Files +// ***************************************************************************** +// ***************************************************************************** + +#include "configuration.h" + +#include + +#include +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +// ***************************************************************************** +// ***************************************************************************** +// Section: Type Definitions +// ***************************************************************************** +// ***************************************************************************** + +/* Application states + + Summary: + The blink task's states. + + Description: + The states system.yaml declares for the task, in its order: they are the + task runtime's numbers, which tasks.c checks. Declare a state in + system.yaml, and regeneration adds it here, with its case in BLINK_Tasks(). +*/ +typedef enum { + /* The task's initial state. */ + BLINK_STATE_DARK = 0, + BLINK_STATE_LIT, +} BLINK_STATES; + +/* Application Data + + Summary: + Holds the blink task's data. + + Description: + This structure holds the task's data: only the task's thread runs its + BLINK_Tasks(). + + Remarks: + BLINK_Tasks() moves the task by setting state. +*/ +typedef struct { + /* The task's current state */ + BLINK_STATES state; + + /* TODO: Define any additional data used by the task. */ +} BLINK_DATA; + +extern BLINK_DATA blinkData; + +// ***************************************************************************** +// ***************************************************************************** +// Section: Application Initialization and State Machine Functions +// ***************************************************************************** +// ***************************************************************************** + +/******************************************************************************* + Function: + void BLINK_Initialize ( void ) + + Summary: + The blink task's initialization. + + Description: + This function puts the task in its initial state, BLINK_STATE_DARK, and + prepares its data, before the kernel starts its thread. + + Precondition: + The board and the kernel are initialized. The KERNEL devices are not ready + yet: use them from the task's states. + + Parameters: + None. + + Returns: + None. + + Example: + + BLINK_Initialize(); + + + Remarks: + SYS_Initialize() calls it. +*/ +void BLINK_Initialize(void); + +/******************************************************************************* + Function: + void BLINK_Tasks ( void ) + + Summary: + The blink task's state machine. + + Description: + This function runs the task's current state, blinkData.state, once: its + thread calls it every 500 ms. + + Precondition: + BLINK_Initialize() has run. + + Parameters: + None. + + Returns: + None. + + Example: + + BLINK_Tasks(); + + + Remarks: + Its thread calls it on a period that does not drift; a period it overruns is + counted, not run twice (KRN-TSK-004). +*/ +void BLINK_Tasks(void); + +#ifdef __cplusplus +} +#endif + +#endif /* BLINK_H */ +/******************************************************************************* + End of File +*/ diff --git a/examples/tasks/src/config/.base/_app/src/door.c b/examples/tasks/src/config/.base/_app/src/door.c new file mode 100644 index 00000000..c9c3ffe9 --- /dev/null +++ b/examples/tasks/src/config/.base/_app/src/door.c @@ -0,0 +1,155 @@ +/* SPDX-License-Identifier: Apache-2.0 */ +/* + * This file is part of EmbLinkRTOS, a deterministic real-time kernel for microcontrollers. + * Licensed under the Apache License, Version 2.0; see the LICENSE file at the repository root. + */ + +/******************************************************************************* + door: an event task, its queue 8 deep + + File Name: + door.c + + Summary: + The door task's handlers. + + Description: + This file holds the door task's data and its handlers, one per state, each + returning the state to be in next (SPEC-020). + + Generated by emb-hwgen from system.yaml, then yours to edit: regeneration + merges its changes with yours (A126, A130). + *******************************************************************************/ + +// ***************************************************************************** +// ***************************************************************************** +// Section: Included Files +// ***************************************************************************** +// ***************************************************************************** + +#include "definitions.h" + +// ***************************************************************************** +// ***************************************************************************** +// Section: Global Data Definitions +// ***************************************************************************** +// ***************************************************************************** + +/* Application Data + + Summary: + Holds the door task's data. + + Description: + This structure holds the task's data. + + Remarks: + DOOR_Initialize() starts it, and the task's handlers use it. +*/ +DOOR_DATA doorData; + +// ***************************************************************************** +// ***************************************************************************** +// Section: Application Callback Functions +// ***************************************************************************** +// ***************************************************************************** + +/* TODO: Add any necessary callback functions. */ + +// ***************************************************************************** +// ***************************************************************************** +// Section: Application Local Functions +// ***************************************************************************** +// ***************************************************************************** + +/* TODO: Add any necessary local functions. */ + +// ***************************************************************************** +// ***************************************************************************** +// Section: Application Initialization and State Machine Functions +// ***************************************************************************** +// ***************************************************************************** + +/******************************************************************************* + Function: + void DOOR_Initialize ( void ) + + Remarks: + See prototype in door.h. + */ +void DOOR_Initialize(void) +{ + /* Place the task in its initial state. */ + doorData.state = DOOR_STATE_CLOSED; + + /* TODO: Initialize the task's data. */ +} + +/******************************************************************************* + Function: + DOOR_STATES DOOR_OnClosed ( const emb_task_event_t *event ) + + Remarks: + See prototype in door.h. + */ +DOOR_STATES DOOR_OnClosed(const emb_task_event_t *event) +{ + /* TODO: Handle the event; return the state to be in next. */ + (void)event; + return DOOR_STATE_CLOSED; +} + +/******************************************************************************* + Function: + DOOR_STATES DOOR_OnOpen ( const emb_task_event_t *event ) + + Remarks: + See prototype in door.h. + */ +DOOR_STATES DOOR_OnOpen(const emb_task_event_t *event) +{ + /* TODO: Handle the event; return the state to be in next. */ + (void)event; + return DOOR_STATE_OPEN; +} + +/******************************************************************************* + Function: + DOOR_STATES DOOR_OnJammed ( const emb_task_event_t *event ) + + Remarks: + See prototype in door.h. + */ +DOOR_STATES DOOR_OnJammed(const emb_task_event_t *event) +{ + /* TODO: Handle the event; return the state to be in next. */ + (void)event; + return DOOR_STATE_JAMMED; +} + +/******************************************************************************* + Function: + void DOOR_EnterOpen ( void ) + + Remarks: + See prototype in door.h. + */ +void DOOR_EnterOpen(void) +{ + /* TODO: The state's enter action. */ +} + +/******************************************************************************* + Function: + void DOOR_ExitOpen ( void ) + + Remarks: + See prototype in door.h. + */ +void DOOR_ExitOpen(void) +{ + /* TODO: The state's exit action. */ +} +/******************************************************************************* + End of File +*/ diff --git a/examples/tasks/src/config/.base/_app/src/door.h b/examples/tasks/src/config/.base/_app/src/door.h new file mode 100644 index 00000000..d5f65117 --- /dev/null +++ b/examples/tasks/src/config/.base/_app/src/door.h @@ -0,0 +1,305 @@ +/* SPDX-License-Identifier: Apache-2.0 */ +/* + * This file is part of EmbLinkRTOS, a deterministic real-time kernel for microcontrollers. + * Licensed under the Apache License, Version 2.0; see the LICENSE file at the repository root. + */ + +/******************************************************************************* + door: an event task, its queue 8 deep + + File Name: + door.h + + Summary: + The door task's states, events, data and functions. + + Description: + This header declares what the door task's own file defines: its states, its + events, its data, DOOR_Initialize() and a handler for each state, which the + task's thread runs for each event (SPEC-020). + + Generated by emb-hwgen from system.yaml, then yours to edit: regeneration + merges its changes with yours (A126, A130). + *******************************************************************************/ + +#ifndef DOOR_H +#define DOOR_H + +// ***************************************************************************** +// ***************************************************************************** +// Section: Included Files +// ***************************************************************************** +// ***************************************************************************** + +#include "configuration.h" + +#include + +#include +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +// ***************************************************************************** +// ***************************************************************************** +// Section: Type Definitions +// ***************************************************************************** +// ***************************************************************************** + +/* Application states + + Summary: + The door task's states. + + Description: + The states system.yaml declares for the task, in its order: they are the + task runtime's numbers, which tasks.c checks. Declare a state in + system.yaml, and regeneration adds it here, with its handler. +*/ +typedef enum { + /* The task's initial state. */ + DOOR_STATE_CLOSED = 0, + DOOR_STATE_OPEN, + DOOR_STATE_JAMMED, +} DOOR_STATES; + +/* Application events + + Summary: + The door task's own events. + + Description: + Numbered from EMB_EV_USER, as system.yaml lists them; the runtime's own, + such as EMB_EV_TIMEOUT, are below it. Post one with emb_task_post(DOOR_TASK, + DOOR_EVENT_, value). +*/ +typedef enum { + DOOR_EVENT_OPEN = EMB_EV_USER, + DOOR_EVENT_CLOSE, + DOOR_EVENT_JAM, +} DOOR_EVENTS; + +/* Application Data + + Summary: + Holds the door task's data. + + Description: + This structure holds the task's data: only the task's thread runs its + handlers. + + Remarks: + state is the state whose handler runs; the runtime keeps it + (emb_task_state(DOOR_TASK)). +*/ +typedef struct { + /* The task's current state */ + DOOR_STATES state; + + /* TODO: Define any additional data used by the task. */ +} DOOR_DATA; + +extern DOOR_DATA doorData; + +// ***************************************************************************** +// ***************************************************************************** +// Section: Application Initialization and State Machine Functions +// ***************************************************************************** +// ***************************************************************************** + +/******************************************************************************* + Function: + void DOOR_Initialize ( void ) + + Summary: + The door task's initialization. + + Description: + This function puts the task in its initial state, DOOR_STATE_CLOSED, and + prepares its data, before the kernel starts its thread. + + Precondition: + The board and the kernel are initialized. The KERNEL devices are not ready + yet: use them from the task's states. + + Parameters: + None. + + Returns: + None. + + Example: + + DOOR_Initialize(); + + + Remarks: + SYS_Initialize() calls it. +*/ +void DOOR_Initialize(void); + +/******************************************************************************* + Function: + DOOR_STATES DOOR_OnClosed ( const emb_task_event_t *event ) + + Summary: + The door task's closed state: one event. + + Description: + This function runs for each event the task receives in DOOR_STATE_CLOSED. It + returns the state to be in next: DOOR_STATE_CLOSED to stay. + + Precondition: + DOOR_Initialize() has run; the kernel runs the task's thread. + + Parameters: + event - The event: its id and its value. + + Returns: + The next state. + + Example: + + return (event->id == DOOR_EVENT_OPEN) ? DOOR_STATE_OPEN : DOOR_STATE_CLOSED; + + + Remarks: + The task's thread calls it, one event at a time; no event is lost meanwhile + (KRN-TSK-001). +*/ +DOOR_STATES DOOR_OnClosed(const emb_task_event_t *event); + +/******************************************************************************* + Function: + DOOR_STATES DOOR_OnOpen ( const emb_task_event_t *event ) + + Summary: + The door task's open state: one event. + + Description: + This function runs for each event the task receives in DOOR_STATE_OPEN, and + with EMB_EV_TIMEOUT when the state's timeout passes. It returns the state to + be in next: DOOR_STATE_OPEN to stay. + + Precondition: + DOOR_Initialize() has run; the kernel runs the task's thread. + + Parameters: + event - The event: its id and its value. + + Returns: + The next state. + + Example: + + return (event->id == DOOR_EVENT_OPEN) ? DOOR_STATE_JAMMED : DOOR_STATE_OPEN; + + + Remarks: + The task's thread calls it, one event at a time; no event is lost meanwhile + (KRN-TSK-001). +*/ +DOOR_STATES DOOR_OnOpen(const emb_task_event_t *event); + +/******************************************************************************* + Function: + DOOR_STATES DOOR_OnJammed ( const emb_task_event_t *event ) + + Summary: + The door task's jammed state: one event. + + Description: + This function runs for each event the task receives in DOOR_STATE_JAMMED. It + returns the state to be in next: DOOR_STATE_JAMMED to stay. + + Precondition: + DOOR_Initialize() has run; the kernel runs the task's thread. + + Parameters: + event - The event: its id and its value. + + Returns: + The next state. + + Example: + + return (event->id == DOOR_EVENT_OPEN) ? DOOR_STATE_CLOSED : DOOR_STATE_JAMMED; + + + Remarks: + The task's thread calls it, one event at a time; no event is lost meanwhile + (KRN-TSK-001). +*/ +DOOR_STATES DOOR_OnJammed(const emb_task_event_t *event); + +/******************************************************************************* + Function: + void DOOR_EnterOpen ( void ) + + Summary: + The door task's open state: its entry action. + + Description: + This function runs as the task enters DOOR_STATE_OPEN, after the old state's + exit action. + + Precondition: + DOOR_Initialize() has run. + + Parameters: + None. + + Returns: + None. + + Example: + + DOOR_EnterOpen(); + + + Remarks: + The task's thread calls it (KRN-TSK-002). +*/ +void DOOR_EnterOpen(void); + +/******************************************************************************* + Function: + void DOOR_ExitOpen ( void ) + + Summary: + The door task's open state: its exit action. + + Description: + This function runs as the task leaves DOOR_STATE_OPEN, before the new + state's entry action. + + Precondition: + DOOR_Initialize() has run. + + Parameters: + None. + + Returns: + None. + + Example: + + DOOR_ExitOpen(); + + + Remarks: + The task's thread calls it (KRN-TSK-002). +*/ +void DOOR_ExitOpen(void); + +#ifdef __cplusplus +} +#endif + +#endif /* DOOR_H */ +/******************************************************************************* + End of File +*/ diff --git a/examples/tasks/src/config/.base/_app/src/interrupt_handlers.c b/examples/tasks/src/config/.base/_app/src/interrupt_handlers.c new file mode 100644 index 00000000..2ab758b4 --- /dev/null +++ b/examples/tasks/src/config/.base/_app/src/interrupt_handlers.c @@ -0,0 +1,55 @@ +/* SPDX-License-Identifier: Apache-2.0 */ +/* + * This file is part of EmbLinkRTOS, a deterministic real-time kernel for microcontrollers. + * Licensed under the Apache License, Version 2.0; see the LICENSE file at the repository root. + */ + +/******************************************************************************* + Interrupt Handlers + + File Name: + interrupt_handlers.c + + Summary: + tasks_demo's interrupt handlers. + + Description: + This file holds the application's interrupt handlers, which + SYS_INT_Initialize() connects (src/config//interrupts.c). Each runs + in interrupt context: keep it short, and hand the work to a task with + emb_task_post(). + + Generated by emb-hwgen from system.yaml, then yours to edit: regeneration + merges its changes with yours (A126, A130). + *******************************************************************************/ + +// ***************************************************************************** +// ***************************************************************************** +// Section: Included Files +// ***************************************************************************** +// ***************************************************************************** + +#include "definitions.h" + +// ***************************************************************************** +// ***************************************************************************** +// Section: Handler Routines +// ***************************************************************************** +// ***************************************************************************** + +/******************************************************************************* + Function: + void WAKE_InterruptHandler ( void *arg ) + + Remarks: + See prototype in interrupts.h. + */ +void WAKE_InterruptHandler(void *arg) +{ + (void)arg; + + /* TODO: Handle the wake interrupt. */ +} +/******************************************************************************* + End of File +*/ diff --git a/examples/tasks/src/config/.base/_app/src/main.c b/examples/tasks/src/config/.base/_app/src/main.c new file mode 100644 index 00000000..3357eef8 --- /dev/null +++ b/examples/tasks/src/config/.base/_app/src/main.c @@ -0,0 +1,58 @@ +/* SPDX-License-Identifier: Apache-2.0 */ +/* + * This file is part of EmbLinkRTOS, a deterministic real-time kernel for microcontrollers. + * Licensed under the Apache License, Version 2.0; see the LICENSE file at the repository root. + */ + +/******************************************************************************* + Main Source File + + File Name: + main.c + + Summary: + tasks_demo's entry point. + + Description: + This file holds main(): it initializes the system, the board, the kernel and + the tasks (SYS_Initialize()), then starts the kernel (SYS_Tasks()), from + which the threads and the tasks run. + + Generated by emb-hwgen from system.yaml, then yours to edit: regeneration + merges its changes with yours (A126, A130). + *******************************************************************************/ + +// ***************************************************************************** +// ***************************************************************************** +// Section: Included Files +// ***************************************************************************** +// ***************************************************************************** + +#include "definitions.h" + +#include +#include +#include + +// ***************************************************************************** +// ***************************************************************************** +// Section: Main Entry Point +// ***************************************************************************** +// ***************************************************************************** + +int main(void) +{ + /* Initialize all modules */ + SYS_Initialize(NULL); + + while (true) { + /* Start the kernel: the threads and the tasks run from here. It does not return. */ + SYS_Tasks(); + } + + /* Execution should not come here during normal operation */ + return EXIT_FAILURE; +} +/******************************************************************************* + End of File +*/ diff --git a/examples/tasks/generated/nucleo_f446re/build/CMakeLists.txt b/examples/tasks/src/config/.base/nucleo_f446re/build/CMakeLists.txt similarity index 66% rename from examples/tasks/generated/nucleo_f446re/build/CMakeLists.txt rename to examples/tasks/src/config/.base/nucleo_f446re/build/CMakeLists.txt index 43d8ef4f..65590fc0 100644 --- a/examples/tasks/generated/nucleo_f446re/build/CMakeLists.txt +++ b/examples/tasks/src/config/.base/nucleo_f446re/build/CMakeLists.txt @@ -9,17 +9,17 @@ # arch/cortex_m/arch.yaml # c5c8e451c09717dee1713d07f8311b6d507e3b4c66c42d93e0ce11da6ec76d6d # boards/st/nucleo_f446re/board.yaml -# d756f3a7f19dc7da82ee3afc168dc54946312c5a9990720953c0fedcdece54ea +# 551c524379751d359bdd87501269d6cab33edf84d212d2f6632ffe9567ec71d0 # drivers/bindings.yaml -# d3c336ac05548e0addd1faac18f3dff70576d8069f11d89e6a761cf5c6132b49 +# c06d1a914adb21d0e314c79b3611ac6859eefeac1957d6914cccfc5531ad6ede # examples/tasks/system.yaml -# 3dd9de88918f06e4b3a41232cb716a9e7d1c4b74ad18e71fd51644ae394ebf9c +# 202cff4815e97ab763dc14c61b0b694ee9381307eb46687f9caaea3465a913da # soc/st/stm32f4/stm32f4.yaml -# 3db4a0a65c9624d865d4ed7fc6354bf95054d0c465b76a2091f06aeac3d7375f +# 796886c294250aa81151a620d80d0e43b5ee8e1bf53a07d1d7e2c62e95214dbd # soc/st/stm32f4/stm32f446.yaml -# 0d5cc7f5fce4c51be71678987720c85c6e76e05473ff8a78ea5035394316c055 +# f0c9a37f6017c87d0efe215a3561f65494ba52383f2d0c10419b0ab5035f77f2 # soc/st/stm32f4/stm32f446re.yaml # b9a88d0a94aa17ee83317a3a56f7c194ec1b3107dfb3e82e453122dc1c48f6d4 # The board has no C of its own: its SoC family's board support builds emb_board from -# ../src/board_pins.c and ../include/hw_config.h, and links ../linker/regions.ld. +# ../peripheral/board_pins.c and ../peripheral/hw_config.h, and links ../linker/regions.ld. add_subdirectory("${EMB_SOC_DIR}" soc) diff --git a/examples/tasks/generated/.base/nucleo_f446re/build/board.cmake b/examples/tasks/src/config/.base/nucleo_f446re/build/board.cmake similarity index 63% rename from examples/tasks/generated/.base/nucleo_f446re/build/board.cmake rename to examples/tasks/src/config/.base/nucleo_f446re/build/board.cmake index 4f3676d2..24e51cfd 100644 --- a/examples/tasks/generated/.base/nucleo_f446re/build/board.cmake +++ b/examples/tasks/src/config/.base/nucleo_f446re/build/board.cmake @@ -9,15 +9,15 @@ # arch/cortex_m/arch.yaml # c5c8e451c09717dee1713d07f8311b6d507e3b4c66c42d93e0ce11da6ec76d6d # boards/st/nucleo_f446re/board.yaml -# d756f3a7f19dc7da82ee3afc168dc54946312c5a9990720953c0fedcdece54ea +# 551c524379751d359bdd87501269d6cab33edf84d212d2f6632ffe9567ec71d0 # drivers/bindings.yaml -# d3c336ac05548e0addd1faac18f3dff70576d8069f11d89e6a761cf5c6132b49 +# c06d1a914adb21d0e314c79b3611ac6859eefeac1957d6914cccfc5531ad6ede # examples/tasks/system.yaml -# 3dd9de88918f06e4b3a41232cb716a9e7d1c4b74ad18e71fd51644ae394ebf9c +# 202cff4815e97ab763dc14c61b0b694ee9381307eb46687f9caaea3465a913da # soc/st/stm32f4/stm32f4.yaml -# 3db4a0a65c9624d865d4ed7fc6354bf95054d0c465b76a2091f06aeac3d7375f +# 796886c294250aa81151a620d80d0e43b5ee8e1bf53a07d1d7e2c62e95214dbd # soc/st/stm32f4/stm32f446.yaml -# 0d5cc7f5fce4c51be71678987720c85c6e76e05473ff8a78ea5035394316c055 +# f0c9a37f6017c87d0efe215a3561f65494ba52383f2d0c10419b0ab5035f77f2 # soc/st/stm32f4/stm32f446re.yaml # b9a88d0a94aa17ee83317a3a56f7c194ec1b3107dfb3e82e453122dc1c48f6d4 # nucleo_f446re: STM32F446RE, cortex-m4f at 180 MHz. @@ -26,23 +26,28 @@ set(EMB_BOARD_VARIANT armv7em) set(EMB_BOARD_DEFAULT_PROFILE base) set(EMB_BOARD_C_FLAGS -mcpu=cortex-m4 -mfpu=fpv4-sp-d16 -mfloat-abi=hard) get_filename_component(EMB_BOARD_GENERATED_DIR "${CMAKE_CURRENT_LIST_DIR}/.." ABSOLUTE) -set(EMB_BOARD_CONF "${EMB_BOARD_GENERATED_DIR}/config/board.conf") +set(EMB_BOARD_CONF "${EMB_BOARD_GENERATED_DIR}/build/board.conf") set(EMB_BOARD_HW_JSON "${EMB_BOARD_GENERATED_DIR}/docs/hw.json") set(EMB_BOARD_BUILD_DIR "${CMAKE_CURRENT_LIST_DIR}") # build/CMakeLists.txt +set(EMB_BOARD_SRC_DIR "${EMB_BOARD_GENERATED_DIR}/peripheral") # its pin table and boot block +set(EMB_BOARD_LINKER_DIR "${EMB_BOARD_GENERATED_DIR}/linker") # the SoC family's board support and drivers build this board (build/CMakeLists.txt) set(EMB_SOC_DIR "${EMB_BASE}/soc/st/stm32f4") -set(EMB_BOARD_INCLUDE_DIRS "${EMB_BOARD_GENERATED_DIR}/include" "${EMB_SOC_DIR}/include") +set(EMB_BOARD_INCLUDE_DIRS "${EMB_BOARD_GENERATED_DIR}/peripheral" "${EMB_SOC_DIR}/include") set(EMB_BOARD_RESETS_IN embsim hil) # restart the image with RAM kept (test_crash_reset) set(EMB_BOARD_EMBSIM_TARGET emblink/nucleo_f446re) # EMB_TEST_EMULATOR=embsim set(EMB_BOARD_USART2_DMA tx) set(EMB_BOARD_SPI2_DMA rx tx) set(EMB_BOARD_SPI2_CS_COUNT 1) +set(EMB_BOARD_ADC1_DMA rx) set(EMB_BOARD_EMBSIM_UART_LOOP uart4 "A0,A1") set(EMB_BOARD_EMBSIM_SPI_LOOP spi2 "CN10_26,CN10_28") set(EMB_BOARD_EMBSIM_I2C_LOOP i2c1 i2c2 "D15,D6" "D14,D3") +set(EMB_BOARD_EMBSIM_PWM_LOOP "tim3:0,tim4:0" "D12,D10") +set(EMB_BOARD_EMBSIM_ADC_LOOP "adc1:4,8" "A2,3V3" "A3,GND") # the board's devices (soc_devices.c) and the drivers they use, and only those (SPEC-016 §8) set(EMB_BOARD_DRIVER_SOURCES - "${EMB_BOARD_GENERATED_DIR}/src/soc_devices.c" + "${EMB_BOARD_GENERATED_DIR}/peripheral/soc_devices.c" "${EMB_BASE}/drivers/st/stm32_devices.c" "${EMB_BASE}/drivers/st/stm32_iwdg.c" "${EMB_BASE}/drivers/st/stm32_rtc.c" @@ -51,6 +56,9 @@ set(EMB_BOARD_DRIVER_SOURCES "${EMB_BASE}/drivers/st/stm32_uart.c" "${EMB_BASE}/drivers/st/stm32_spi.c" "${EMB_BASE}/drivers/st/stm32_i2c.c" + "${EMB_BASE}/drivers/st/stm32_tim_counter.c" + "${EMB_BASE}/drivers/st/stm32_tim_pwm.c" + "${EMB_BASE}/drivers/st/stm32_adc.c" ) set(EMB_BOARD_DRIVER_INCLUDE_DIRS "${EMB_BASE}/drivers/st/include" @@ -58,10 +66,10 @@ set(EMB_BOARD_DRIVER_INCLUDE_DIRS # the inputs this directory was generated from, for the configure-time staleness check set(EMB_BOARD_HW_INPUTS "arch/cortex_m/arch.yaml=c5c8e451c09717dee1713d07f8311b6d507e3b4c66c42d93e0ce11da6ec76d6d" - "boards/st/nucleo_f446re/board.yaml=d756f3a7f19dc7da82ee3afc168dc54946312c5a9990720953c0fedcdece54ea" - "drivers/bindings.yaml=d3c336ac05548e0addd1faac18f3dff70576d8069f11d89e6a761cf5c6132b49" - "examples/tasks/system.yaml=3dd9de88918f06e4b3a41232cb716a9e7d1c4b74ad18e71fd51644ae394ebf9c" - "soc/st/stm32f4/stm32f4.yaml=3db4a0a65c9624d865d4ed7fc6354bf95054d0c465b76a2091f06aeac3d7375f" - "soc/st/stm32f4/stm32f446.yaml=0d5cc7f5fce4c51be71678987720c85c6e76e05473ff8a78ea5035394316c055" + "boards/st/nucleo_f446re/board.yaml=551c524379751d359bdd87501269d6cab33edf84d212d2f6632ffe9567ec71d0" + "drivers/bindings.yaml=c06d1a914adb21d0e314c79b3611ac6859eefeac1957d6914cccfc5531ad6ede" + "examples/tasks/system.yaml=202cff4815e97ab763dc14c61b0b694ee9381307eb46687f9caaea3465a913da" + "soc/st/stm32f4/stm32f4.yaml=796886c294250aa81151a620d80d0e43b5ee8e1bf53a07d1d7e2c62e95214dbd" + "soc/st/stm32f4/stm32f446.yaml=f0c9a37f6017c87d0efe215a3561f65494ba52383f2d0c10419b0ab5035f77f2" "soc/st/stm32f4/stm32f446re.yaml=b9a88d0a94aa17ee83317a3a56f7c194ec1b3107dfb3e82e453122dc1c48f6d4" ) diff --git a/examples/tasks/generated/nucleo_f446re/config/board.conf b/examples/tasks/src/config/.base/nucleo_f446re/build/board.conf similarity index 73% rename from examples/tasks/generated/nucleo_f446re/config/board.conf rename to examples/tasks/src/config/.base/nucleo_f446re/build/board.conf index e26f1083..aece92f0 100644 --- a/examples/tasks/generated/nucleo_f446re/config/board.conf +++ b/examples/tasks/src/config/.base/nucleo_f446re/build/board.conf @@ -9,15 +9,15 @@ # arch/cortex_m/arch.yaml # c5c8e451c09717dee1713d07f8311b6d507e3b4c66c42d93e0ce11da6ec76d6d # boards/st/nucleo_f446re/board.yaml -# d756f3a7f19dc7da82ee3afc168dc54946312c5a9990720953c0fedcdece54ea +# 551c524379751d359bdd87501269d6cab33edf84d212d2f6632ffe9567ec71d0 # drivers/bindings.yaml -# d3c336ac05548e0addd1faac18f3dff70576d8069f11d89e6a761cf5c6132b49 +# c06d1a914adb21d0e314c79b3611ac6859eefeac1957d6914cccfc5531ad6ede # examples/tasks/system.yaml -# 3dd9de88918f06e4b3a41232cb716a9e7d1c4b74ad18e71fd51644ae394ebf9c +# 202cff4815e97ab763dc14c61b0b694ee9381307eb46687f9caaea3465a913da # soc/st/stm32f4/stm32f4.yaml -# 3db4a0a65c9624d865d4ed7fc6354bf95054d0c465b76a2091f06aeac3d7375f +# 796886c294250aa81151a620d80d0e43b5ee8e1bf53a07d1d7e2c62e95214dbd # soc/st/stm32f4/stm32f446.yaml -# 0d5cc7f5fce4c51be71678987720c85c6e76e05473ff8a78ea5035394316c055 +# f0c9a37f6017c87d0efe215a3561f65494ba52383f2d0c10419b0ab5035f77f2 # soc/st/stm32f4/stm32f446re.yaml # b9a88d0a94aa17ee83317a3a56f7c194ec1b3107dfb3e82e453122dc1c48f6d4 # Board defaults for nucleo_f446re. Applied before the profile fragment. diff --git a/examples/tasks/src/config/.base/nucleo_f446re/configuration.h b/examples/tasks/src/config/.base/nucleo_f446re/configuration.h new file mode 100644 index 00000000..9d6571be --- /dev/null +++ b/examples/tasks/src/config/.base/nucleo_f446re/configuration.h @@ -0,0 +1,109 @@ +/* SPDX-License-Identifier: Apache-2.0 */ +/* + * This file is part of EmbLinkRTOS, a deterministic real-time kernel for microcontrollers. + * Licensed under the Apache License, Version 2.0; see the LICENSE file at the repository root. + */ + +/******************************************************************************* + System Configuration Header + + File Name: + configuration.h + + Summary: + The build-time configuration of tasks_demo on the nucleo_f446re. + + Description: + The system's settings as macros: the board and its clock, the devices' + settings, each task's and thread's priority and stack, the tasks' periods, + queues and timeouts, and the application's interrupts. The kernel's own + options are 's CONFIG_EMB_*, and the board's hardware + 's EMB_HW_*. + + Generated by emb-hwgen 0.1.0, schema v0, from the system description and the + nucleo_f446re's. Yours to edit: regenerating merges its changes with yours + (A126): + hw/gen/emb-hwgen.py generate --system examples/tasks/system.yaml + + Inputs (SHA-256): + arch/cortex_m/arch.yaml + c5c8e451c09717dee1713d07f8311b6d507e3b4c66c42d93e0ce11da6ec76d6d + boards/st/nucleo_f446re/board.yaml + 551c524379751d359bdd87501269d6cab33edf84d212d2f6632ffe9567ec71d0 + drivers/bindings.yaml + c06d1a914adb21d0e314c79b3611ac6859eefeac1957d6914cccfc5531ad6ede + examples/tasks/system.yaml + 202cff4815e97ab763dc14c61b0b694ee9381307eb46687f9caaea3465a913da + soc/st/stm32f4/stm32f4.yaml + 796886c294250aa81151a620d80d0e43b5ee8e1bf53a07d1d7e2c62e95214dbd + soc/st/stm32f4/stm32f446.yaml + f0c9a37f6017c87d0efe215a3561f65494ba52383f2d0c10419b0ab5035f77f2 + soc/st/stm32f4/stm32f446re.yaml + b9a88d0a94aa17ee83317a3a56f7c194ec1b3107dfb3e82e453122dc1c48f6d4 + *******************************************************************************/ + +#ifndef CONFIGURATION_H +#define CONFIGURATION_H + +// ***************************************************************************** +// ***************************************************************************** +// Section: Included Files +// ***************************************************************************** +// ***************************************************************************** + +#include + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +// ***************************************************************************** +// ***************************************************************************** +// Section: System Configuration +// ***************************************************************************** +// ***************************************************************************** + +#define SYS_CPU_CLOCK_HZ 180000000u +#define SYS_TICK_NS CONFIG_EMB_TICK_NS +#define SYS_PRIORITY_COUNT CONFIG_EMB_PRIORITY_COUNT + +// ***************************************************************************** +// ***************************************************************************** +// Section: Driver Configuration +// ***************************************************************************** +// ***************************************************************************** + +#define DRV_USART2_BAUD 115200u +#define DRV_UART4_BAUD 115200u + +// ***************************************************************************** +// ***************************************************************************** +// Section: Application Configuration +// ***************************************************************************** +// ***************************************************************************** + +/* door: an event task, its queue 8 deep */ +#define DOOR_PRIORITY 5u +#define DOOR_STACK_SIZE 1024u +#define DOOR_QUEUE_LENGTH 8u +#define DOOR_OPEN_TIMEOUT_MS 2000u + +/* blink: a periodic task, every 500 ms */ +#define BLINK_PRIORITY 2u +#define BLINK_STACK_SIZE 512u +#define BLINK_PERIOD_MS 500u + +/* wake: an interrupt, WAKE_InterruptHandler() */ +#define WAKE_IRQ 61u +#define WAKE_IRQ_LEVEL 1u + +#ifdef __cplusplus +} +#endif + +#endif /* CONFIGURATION_H */ +/******************************************************************************* + End of File +*/ diff --git a/examples/tasks/src/config/.base/nucleo_f446re/definitions.h b/examples/tasks/src/config/.base/nucleo_f446re/definitions.h new file mode 100644 index 00000000..f785939d --- /dev/null +++ b/examples/tasks/src/config/.base/nucleo_f446re/definitions.h @@ -0,0 +1,173 @@ +/* SPDX-License-Identifier: Apache-2.0 */ +/* + * This file is part of EmbLinkRTOS, a deterministic real-time kernel for microcontrollers. + * Licensed under the Apache License, Version 2.0; see the LICENSE file at the repository root. + */ + +/******************************************************************************* + System Definitions + + File Name: + definitions.h + + Summary: + tasks_demo's system definitions on the nucleo_f446re. + + Description: + The one header the application includes: the kernel's API, the board's + devices, the system's configuration and handles, every task's header, and + the system's two functions, SYS_Initialize() and SYS_Tasks(). + + Generated by emb-hwgen 0.1.0, schema v0, from the system description and the + nucleo_f446re's. Yours to edit: regenerating merges its changes with yours + (A126): + hw/gen/emb-hwgen.py generate --system examples/tasks/system.yaml + + Inputs (SHA-256): + arch/cortex_m/arch.yaml + c5c8e451c09717dee1713d07f8311b6d507e3b4c66c42d93e0ce11da6ec76d6d + boards/st/nucleo_f446re/board.yaml + 551c524379751d359bdd87501269d6cab33edf84d212d2f6632ffe9567ec71d0 + drivers/bindings.yaml + c06d1a914adb21d0e314c79b3611ac6859eefeac1957d6914cccfc5531ad6ede + examples/tasks/system.yaml + 202cff4815e97ab763dc14c61b0b694ee9381307eb46687f9caaea3465a913da + soc/st/stm32f4/stm32f4.yaml + 796886c294250aa81151a620d80d0e43b5ee8e1bf53a07d1d7e2c62e95214dbd + soc/st/stm32f4/stm32f446.yaml + f0c9a37f6017c87d0efe215a3561f65494ba52383f2d0c10419b0ab5035f77f2 + soc/st/stm32f4/stm32f446re.yaml + b9a88d0a94aa17ee83317a3a56f7c194ec1b3107dfb3e82e453122dc1c48f6d4 + *******************************************************************************/ + +#ifndef DEFINITIONS_H +#define DEFINITIONS_H + +// ***************************************************************************** +// ***************************************************************************** +// Section: Included Files +// ***************************************************************************** +// ***************************************************************************** + +#include "blink.h" +#include "configuration.h" +#include "door.h" +#include "interrupts.h" + +#include + +#include +#include +#include + +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/* Device Information */ +#define DEVICE_NAME "STM32F446RE" +#define DEVICE_ARCH "cortex-m4f" +#define DEVICE_FAMILY "stm32f4" +#define BOARD_NAME "nucleo_f446re" + +/* CPU clock frequency */ +#define CPU_CLOCK_FREQUENCY 180000000u + +// ***************************************************************************** +// ***************************************************************************** +// Section: System Functions +// ***************************************************************************** +// ***************************************************************************** + +/******************************************************************************* + Function: + void SYS_Initialize ( void *data ) + + Summary: + Initializes the board, the kernel and every task. + + Description: + This function initializes the board (its clocks, pins and console), then the + kernel (its objects and the EARLY devices), then the application's + interrupts, then each task, in its initial state. The KERNEL devices start + with the kernel, in SYS_Tasks(). + + Precondition: + None. + + Parameters: + data - Unused; NULL. + + Returns: + None. + + Example: + + SYS_Initialize(NULL); + while (true) { + SYS_Tasks(); + } + + + Remarks: + This function is called once, after reset, from main(). +*/ +void SYS_Initialize(void *data); + +/******************************************************************************* + Function: + void SYS_Tasks ( void ) + + Summary: + Starts the kernel: the threads and the tasks run from here. + + Description: + This function starts the KERNEL devices, then the scheduler, which runs the + system's threads and each task's thread. It does not return. + + Precondition: + SYS_Initialize() has run. + + Parameters: + None. + + Returns: + It does not return. + + Example: + + SYS_Initialize(NULL); + while (true) { + SYS_Tasks(); + } + + + Remarks: + Harmony calls its SYS_Tasks() in a loop; this one runs the scheduler and + never comes back. +*/ +void SYS_Tasks(void); + +// ***************************************************************************** +// ***************************************************************************** +// Section: Tasks +// ***************************************************************************** +// ***************************************************************************** + +/* each task's handle, for emb_task_post() (SPEC-020) */ +extern emb_task_t door_task; +extern emb_task_t blink_task; +#define DOOR_TASK (&door_task) +#define BLINK_TASK (&blink_task) + +#ifdef __cplusplus +} +#endif + +#endif /* DEFINITIONS_H */ +/******************************************************************************* + End of File +*/ diff --git a/examples/tasks/generated/.base/nucleo_f446re/docs/board.md b/examples/tasks/src/config/.base/nucleo_f446re/docs/board.md similarity index 76% rename from examples/tasks/generated/.base/nucleo_f446re/docs/board.md rename to examples/tasks/src/config/.base/nucleo_f446re/docs/board.md index 2416e35b..2b19732f 100644 --- a/examples/tasks/generated/.base/nucleo_f446re/docs/board.md +++ b/examples/tasks/src/config/.base/nucleo_f446re/docs/board.md @@ -35,8 +35,12 @@ The STM32F446RE at 180 MHz from the PLL, its input the ST-LINK's 8 MHz MCO on PH | PA1 | `pins.uart4.rx` | af8 (uart4_rx) | | PA2 | `pins.usart2.tx` | af7 (usart2_tx) | | PA3 | `pins.usart2.rx` | af7 (usart2_rx) | +| PA4 | `pins.adc1.in4` | analog | | PA5 | `leds.user` | output | +| PA6 | `pins.tim3.ch1` | af2 (tim3_ch1) | +| PB0 | `pins.adc1.in8` | analog | | PB3 | `pins.i2c2.sda` | af4 (i2c2_sda) | +| PB6 | `pins.tim4.ch1` | af2 (tim4_ch1) | | PB8 | `pins.i2c1.scl` | af4 (i2c1_scl) | | PB9 | `pins.i2c1.sda` | af4 (i2c1_sda) | | PB10 | `pins.i2c2.scl` | af4 (i2c2_scl) | @@ -58,6 +62,7 @@ In initialization order (SPEC-016 §4). | rtc | `st,stm32f4-rtc` | rtc | EARLY | - | | flash | `st,stm32f4-flash (flash_if)` | flash | EARLY | - | | dma1 | `st,stm32-dma` | dma | EARLY | rcc | +| dma2 | `st,stm32-dma` | dma | EARLY | rcc | | gpiob | `st,stm32-gpio` | gpio | EARLY | rcc | | gpioc | `st,stm32-gpio` | gpio | EARLY | rcc | | usart2 | `st,stm32-usart` | uart | EARLY | dma1, rcc | @@ -65,6 +70,11 @@ In initialization order (SPEC-016 §4). | spi2 | `st,stm32-spi` | spi | KERNEL | dma1, rcc | | i2c1 | `st,stm32-i2c` | i2c | KERNEL | rcc | | i2c2 | `st,stm32-i2c` | i2c | KERNEL | rcc | +| tim5 | `st,stm32-tim` | counter | KERNEL | rcc | +| tim9 | `st,stm32-tim` | counter | KERNEL | rcc | +| tim3 | `st,stm32-tim` | pwm | KERNEL | rcc | +| tim4 | `st,stm32-tim` | pwm | KERNEL | rcc | +| adc1 | `st,stm32f4-adc` | adc | KERNEL | dma2, rcc | ## Interrupt lines @@ -81,7 +91,10 @@ In initialization order (SPEC-016 §4). | 16 | dma1.s5 | | 17 | dma1.s6 | | 18 | adc1.global | +| 24 | tim9.global | | 28 | tim2.global | +| 29 | tim3.global | +| 30 | tim4.global | | 31 | i2c1.ev | | 32 | i2c1.er | | 33 | i2c2.ev | @@ -92,6 +105,7 @@ In initialization order (SPEC-016 §4). | 39 | usart3.global | | 41 | rtc.alarm | | 47 | dma1.s7 | +| 50 | tim5.global | | 52 | uart4.global | | 53 | uart5.global | | 56 | dma2.s0 | @@ -115,9 +129,9 @@ Generated by emb-hwgen 0.1.0, schema v0, from: | Input | SHA-256 | |---|---| | `arch/cortex_m/arch.yaml` | `c5c8e451c09717dee1713d07f8311b6d507e3b4c66c42d93e0ce11da6ec76d6d` | -| `boards/st/nucleo_f446re/board.yaml` | `d756f3a7f19dc7da82ee3afc168dc54946312c5a9990720953c0fedcdece54ea` | -| `drivers/bindings.yaml` | `d3c336ac05548e0addd1faac18f3dff70576d8069f11d89e6a761cf5c6132b49` | -| `examples/tasks/system.yaml` | `3dd9de88918f06e4b3a41232cb716a9e7d1c4b74ad18e71fd51644ae394ebf9c` | -| `soc/st/stm32f4/stm32f4.yaml` | `3db4a0a65c9624d865d4ed7fc6354bf95054d0c465b76a2091f06aeac3d7375f` | -| `soc/st/stm32f4/stm32f446.yaml` | `0d5cc7f5fce4c51be71678987720c85c6e76e05473ff8a78ea5035394316c055` | +| `boards/st/nucleo_f446re/board.yaml` | `551c524379751d359bdd87501269d6cab33edf84d212d2f6632ffe9567ec71d0` | +| `drivers/bindings.yaml` | `c06d1a914adb21d0e314c79b3611ac6859eefeac1957d6914cccfc5531ad6ede` | +| `examples/tasks/system.yaml` | `202cff4815e97ab763dc14c61b0b694ee9381307eb46687f9caaea3465a913da` | +| `soc/st/stm32f4/stm32f4.yaml` | `796886c294250aa81151a620d80d0e43b5ee8e1bf53a07d1d7e2c62e95214dbd` | +| `soc/st/stm32f4/stm32f446.yaml` | `f0c9a37f6017c87d0efe215a3561f65494ba52383f2d0c10419b0ab5035f77f2` | | `soc/st/stm32f4/stm32f446re.yaml` | `b9a88d0a94aa17ee83317a3a56f7c194ec1b3107dfb3e82e453122dc1c48f6d4` | diff --git a/examples/tasks/generated/.base/nucleo_f446re/docs/build_report.md b/examples/tasks/src/config/.base/nucleo_f446re/docs/build_report.md similarity index 63% rename from examples/tasks/generated/.base/nucleo_f446re/docs/build_report.md rename to examples/tasks/src/config/.base/nucleo_f446re/docs/build_report.md index a253a004..540274b1 100644 --- a/examples/tasks/generated/.base/nucleo_f446re/docs/build_report.md +++ b/examples/tasks/src/config/.base/nucleo_f446re/docs/build_report.md @@ -31,9 +31,9 @@ Generated by emb-hwgen 0.1.0, schema v0, from: | Input | SHA-256 | |---|---| | `arch/cortex_m/arch.yaml` | `c5c8e451c09717dee1713d07f8311b6d507e3b4c66c42d93e0ce11da6ec76d6d` | -| `boards/st/nucleo_f446re/board.yaml` | `d756f3a7f19dc7da82ee3afc168dc54946312c5a9990720953c0fedcdece54ea` | -| `drivers/bindings.yaml` | `d3c336ac05548e0addd1faac18f3dff70576d8069f11d89e6a761cf5c6132b49` | -| `examples/tasks/system.yaml` | `3dd9de88918f06e4b3a41232cb716a9e7d1c4b74ad18e71fd51644ae394ebf9c` | -| `soc/st/stm32f4/stm32f4.yaml` | `3db4a0a65c9624d865d4ed7fc6354bf95054d0c465b76a2091f06aeac3d7375f` | -| `soc/st/stm32f4/stm32f446.yaml` | `0d5cc7f5fce4c51be71678987720c85c6e76e05473ff8a78ea5035394316c055` | +| `boards/st/nucleo_f446re/board.yaml` | `551c524379751d359bdd87501269d6cab33edf84d212d2f6632ffe9567ec71d0` | +| `drivers/bindings.yaml` | `c06d1a914adb21d0e314c79b3611ac6859eefeac1957d6914cccfc5531ad6ede` | +| `examples/tasks/system.yaml` | `202cff4815e97ab763dc14c61b0b694ee9381307eb46687f9caaea3465a913da` | +| `soc/st/stm32f4/stm32f4.yaml` | `796886c294250aa81151a620d80d0e43b5ee8e1bf53a07d1d7e2c62e95214dbd` | +| `soc/st/stm32f4/stm32f446.yaml` | `f0c9a37f6017c87d0efe215a3561f65494ba52383f2d0c10419b0ab5035f77f2` | | `soc/st/stm32f4/stm32f446re.yaml` | `b9a88d0a94aa17ee83317a3a56f7c194ec1b3107dfb3e82e453122dc1c48f6d4` | diff --git a/examples/tasks/generated/.base/nucleo_f446re/docs/hw.json b/examples/tasks/src/config/.base/nucleo_f446re/docs/hw.json similarity index 77% rename from examples/tasks/generated/.base/nucleo_f446re/docs/hw.json rename to examples/tasks/src/config/.base/nucleo_f446re/docs/hw.json index 40ff8551..30955a18 100644 --- a/examples/tasks/generated/.base/nucleo_f446re/docs/hw.json +++ b/examples/tasks/src/config/.base/nucleo_f446re/docs/hw.json @@ -57,6 +57,10 @@ "doc": "DMA1: SPI2's transfers, and the console's writes", "name": "dma1" }, + { + "doc": "DMA2: ADC1's samples", + "name": "dma2" + }, { "doc": "SPI2's chip select, PB12", "name": "gpiob" @@ -96,6 +100,36 @@ "baud": 115200, "doc": "a spare UART; the HIL suite's loopback wires A0 (PA0, TX) to A1 (PA1, RX)", "name": "uart4" + }, + { + "class": "counter", + "doc": "TIM5, 32 bits at 1 MHz: the counter class's (A129); TIM2 stays the controller's ADC trigger", + "name": "tim5" + }, + { + "class": "counter", + "doc": "TIM9, 16 bits at 1 MHz: it wraps every 65.5 ms, so its tests widen the count on the board", + "name": "tim9" + }, + { + "class": "pwm", + "doc": "TIM3, PWM out on channel 1, D12 (PA6); the HIL suite wires it to D10", + "name": "tim3" + }, + { + "class": "pwm", + "doc": "TIM4, PWM capture on channel 1, D10 (PB6)", + "name": "tim4" + }, + { + "cal": "factory_cal", + "common": "adc_common", + "dma": [ + "rx" + ], + "doc": "ADC1, paced by TIM2 (the controller's trigger, which it drives by hand), A2 (PA4, input 4) and A3 (PB0, input 8); the HIL suite wires A2 to 3V3 and A3 to GND", + "name": "adc1", + "trigger": "tim2" } ], "doc": "The STM32F446RE at 180 MHz from the PLL, its input the ST-LINK's 8 MHz MCO on PH0 in HSE bypass (solder bridges SB16 and SB50 as shipped). The console is USART2, which the ST-LINK carries as its virtual COM port.", @@ -132,6 +166,10 @@ } }, "pins": { + "adc1": { + "in4": "PA4", + "in8": "PB0" + }, "i2c1": { "scl": "PB8.af4", "sda": "PB9.af4" @@ -145,6 +183,12 @@ "mosi": "PB15.af5", "sck": "PB13.af5" }, + "tim3": { + "ch1": "PA6.af2" + }, + "tim4": { + "ch1": "PB6.af2" + }, "uart4": { "rx": "PA1.af8", "tx": "PA0.af8" @@ -186,6 +230,35 @@ ] ], "peer": "i2c2" + }, + { + "channels": [ + 0, + 0 + ], + "device": "tim3", + "peer": "tim4", + "ports": [ + "D12", + "D10" + ] + }, + { + "channels": [ + 4, + 8 + ], + "device": "adc1", + "nets": [ + [ + "A2", + "3V3" + ], + [ + "A3", + "GND" + ] + ] } ], "resets_in": [ @@ -208,8 +281,14 @@ "apb1": 45000000, "apb2": 90000000 }, + "bus_timer_hz": { + "ahb1": 180000000, + "apb1": 90000000, + "apb2": 180000000 + }, "bypass": true, "cpu_hz": 180000000, + "fixed_plls": {}, "flash_wait_states": 5, "hclk_hz": 180000000, "pclk1_div": 4, @@ -357,6 +436,30 @@ "name": "dma1", "peripheral": "dma1" }, + { + "class": "dma", + "compatible": "st,stm32-dma", + "deps": [ + "rcc" + ], + "fields": { + "base": 1073898496, + "clken_bit": 22, + "clken_offset": 48, + "irq0": 56, + "irq1": 57, + "irq2": 58, + "irq3": 59, + "irq4": 60, + "irq5": 68, + "irq6": 69, + "irq7": 70, + "memory": true + }, + "level": "early", + "name": "dma2", + "peripheral": "dma2" + }, { "class": "gpio", "compatible": "st,stm32-gpio", @@ -519,6 +622,119 @@ "level": "kernel", "name": "i2c2", "peripheral": "i2c2" + }, + { + "class": "counter", + "compatible": "st,stm32-tim", + "deps": [ + "rcc" + ], + "fields": { + "base": 1073744896, + "bits": 32, + "channels": 4, + "clken_bit": 3, + "clken_offset": 64, + "clock_hz": 90000000, + "irq": 50, + "rate_hz": 1000000 + }, + "level": "kernel", + "name": "tim5", + "peripheral": "tim5" + }, + { + "class": "counter", + "compatible": "st,stm32-tim", + "deps": [ + "rcc" + ], + "fields": { + "base": 1073823744, + "bits": 16, + "channels": 2, + "clken_bit": 16, + "clken_offset": 68, + "clock_hz": 180000000, + "irq": 24, + "rate_hz": 1000000 + }, + "level": "kernel", + "name": "tim9", + "peripheral": "tim9" + }, + { + "class": "pwm", + "compatible": "st,stm32-tim", + "deps": [ + "rcc" + ], + "fields": { + "base": 1073742848, + "bits": 16, + "channels": 4, + "clken_bit": 1, + "clken_offset": 64, + "clock_hz": 90000000, + "irq": 29 + }, + "level": "kernel", + "name": "tim3", + "peripheral": "tim3" + }, + { + "class": "pwm", + "compatible": "st,stm32-tim", + "deps": [ + "rcc" + ], + "fields": { + "base": 1073743872, + "bits": 16, + "channels": 4, + "clken_bit": 2, + "clken_offset": 64, + "clock_hz": 90000000, + "irq": 30 + }, + "level": "kernel", + "name": "tim4", + "peripheral": "tim4" + }, + { + "class": "adc", + "compatible": "st,stm32f4-adc", + "deps": [ + "dma2", + "rcc" + ], + "fields": { + "base": 1073815552, + "bits": 12, + "calibration": 536836650, + "clken_bit": 8, + "clken_offset": 68, + "clock_hz": 90000000, + "common": 1073816320, + "dma_rx": { + "dma": "dma2", + "request": 0, + "stream": 0 + }, + "inputs": 16, + "irq": 18, + "temperature": 18, + "trigger": 1073741824, + "trigger_clken_bit": 0, + "trigger_clken_offset": 64, + "trigger_hz": 90000000, + "trigger_select": 6, + "vref_mv": 3300, + "vrefint": 17 + }, + "level": "kernel", + "name": "adc1", + "peripheral": "adc1" } ], "kconfig": { @@ -608,6 +824,15 @@ "port": "A", "signal": "usart2_rx" }, + { + "gpio": "gpioa", + "mode": "analog", + "number": 4, + "owner": "pins.adc1.in4", + "pin": "PA4", + "port": "A", + "signal": "adc1_in4" + }, { "gpio": "gpioa", "mode": "output", @@ -616,6 +841,25 @@ "pin": "PA5", "port": "A" }, + { + "af": 2, + "gpio": "gpioa", + "mode": "af", + "number": 6, + "owner": "pins.tim3.ch1", + "pin": "PA6", + "port": "A", + "signal": "tim3_ch1" + }, + { + "gpio": "gpiob", + "mode": "analog", + "number": 0, + "owner": "pins.adc1.in8", + "pin": "PB0", + "port": "B", + "signal": "adc1_in8" + }, { "af": 4, "gpio": "gpiob", @@ -626,6 +870,16 @@ "port": "B", "signal": "i2c2_sda" }, + { + "af": 2, + "gpio": "gpiob", + "mode": "af", + "number": 6, + "owner": "pins.tim4.ch1", + "pin": "PB6", + "port": "B", + "signal": "tim4_ch1" + }, { "af": 4, "gpio": "gpiob", @@ -726,23 +980,23 @@ }, { "path": "boards/st/nucleo_f446re/board.yaml", - "sha256": "d756f3a7f19dc7da82ee3afc168dc54946312c5a9990720953c0fedcdece54ea" + "sha256": "551c524379751d359bdd87501269d6cab33edf84d212d2f6632ffe9567ec71d0" }, { "path": "drivers/bindings.yaml", - "sha256": "d3c336ac05548e0addd1faac18f3dff70576d8069f11d89e6a761cf5c6132b49" + "sha256": "c06d1a914adb21d0e314c79b3611ac6859eefeac1957d6914cccfc5531ad6ede" }, { "path": "examples/tasks/system.yaml", - "sha256": "3dd9de88918f06e4b3a41232cb716a9e7d1c4b74ad18e71fd51644ae394ebf9c" + "sha256": "202cff4815e97ab763dc14c61b0b694ee9381307eb46687f9caaea3465a913da" }, { "path": "soc/st/stm32f4/stm32f4.yaml", - "sha256": "3db4a0a65c9624d865d4ed7fc6354bf95054d0c465b76a2091f06aeac3d7375f" + "sha256": "796886c294250aa81151a620d80d0e43b5ee8e1bf53a07d1d7e2c62e95214dbd" }, { "path": "soc/st/stm32f4/stm32f446.yaml", - "sha256": "0d5cc7f5fce4c51be71678987720c85c6e76e05473ff8a78ea5035394316c055" + "sha256": "f0c9a37f6017c87d0efe215a3561f65494ba52383f2d0c10419b0ab5035f77f2" }, { "path": "soc/st/stm32f4/stm32f446re.yaml", @@ -753,19 +1007,49 @@ "soc": { "alternate_functions": { "PA0": { - "af8": "uart4_tx" + "af1": "tim2_ch1", + "af2": "tim5_ch1", + "af8": "uart4_tx", + "analog": "adc1_in0" }, "PA1": { - "af8": "uart4_rx" + "af1": "tim2_ch2", + "af2": "tim5_ch2", + "af8": "uart4_rx", + "analog": "adc1_in1" }, "PA10": { "af7": "usart1_rx" }, + "PA15": { + "af1": "tim2_ch1" + }, "PA2": { - "af7": "usart2_tx" + "af1": "tim2_ch3", + "af2": "tim5_ch3", + "af7": "usart2_tx", + "analog": "adc1_in2" }, "PA3": { - "af7": "usart2_rx" + "af1": "tim2_ch4", + "af2": "tim5_ch4", + "af7": "usart2_rx", + "analog": "adc1_in3" + }, + "PA4": { + "analog": "adc1_in4" + }, + "PA5": { + "af1": "tim2_ch1", + "analog": "adc1_in5" + }, + "PA6": { + "af2": "tim3_ch1", + "analog": "adc1_in6" + }, + "PA7": { + "af2": "tim3_ch2", + "analog": "adc1_in7" }, "PA8": { "af4": "i2c3_scl" @@ -773,7 +1057,16 @@ "PA9": { "af7": "usart1_tx" }, + "PB0": { + "af2": "tim3_ch3", + "analog": "adc1_in8" + }, + "PB1": { + "af2": "tim3_ch4", + "analog": "adc1_in9" + }, "PB10": { + "af1": "tim2_ch3", "af4": "i2c2_scl", "af7": "usart3_tx" }, @@ -786,26 +1079,46 @@ "PB15": { "af5": "spi2_mosi" }, + "PB2": { + "af1": "tim2_ch4" + }, "PB3": { + "af1": "tim2_ch2", "af4": "i2c2_sda" }, "PB4": { + "af2": "tim3_ch1", "af4": "i2c3_sda" }, + "PB5": { + "af2": "tim3_ch2" + }, "PB6": { + "af2": "tim4_ch1", "af4": "i2c1_scl", "af7": "usart1_tx" }, "PB7": { + "af2": "tim4_ch2", "af4": "i2c1_sda", "af7": "usart1_rx" }, "PB8": { + "af1": "tim2_ch1", + "af2": "tim4_ch3", "af4": "i2c1_scl" }, "PB9": { + "af1": "tim2_ch2", + "af2": "tim4_ch4", "af4": "i2c1_sda" }, + "PC0": { + "analog": "adc1_in10" + }, + "PC1": { + "analog": "adc1_in11" + }, "PC10": { "af7": "usart3_tx", "af8": "uart4_tx" @@ -818,16 +1131,32 @@ "af4": "i2c2_sda", "af8": "uart5_tx" }, + "PC2": { + "analog": "adc1_in12" + }, + "PC3": { + "analog": "adc1_in13" + }, + "PC4": { + "analog": "adc1_in14" + }, "PC5": { - "af7": "usart3_rx" + "af7": "usart3_rx", + "analog": "adc1_in15" }, "PC6": { + "af2": "tim3_ch1", "af8": "usart6_tx" }, "PC7": { + "af2": "tim3_ch2", "af8": "usart6_rx" }, + "PC8": { + "af2": "tim3_ch3" + }, "PC9": { + "af2": "tim3_ch4", "af4": "i2c3_sda" }, "PD2": { @@ -956,6 +1285,7 @@ "name": "lse" } ], + "timers_double_when_divided": true, "voltage_scales": [ { "max_hz": 120000000, @@ -1097,12 +1427,24 @@ "part": "STM32F446RE", "peripherals": [ { + "adc": { + "bits": 12, + "inputs": 16, + "temperature": 18, + "vrefint": 17 + }, "base": 1073815552, "clock": { "bit": 8, "bus": "apb2" }, "compatible": "st,stm32f4-adc", + "dma_requests": { + "rx": [ + "dma2.s0c0", + "dma2.s4c0" + ] + }, "irqs": [ { "name": "global", @@ -1277,12 +1619,14 @@ "size": 1024 }, { + "adc_trigger": 6, "base": 1073741824, "clock": { "bit": 0, "bus": "apb1" }, "compatible": "st,stm32-tim", + "counter_bits": 32, "irqs": [ { "name": "global", @@ -1292,6 +1636,76 @@ "name": "tim2", "size": 1024 }, + { + "adc_trigger": 8, + "base": 1073742848, + "clock": { + "bit": 1, + "bus": "apb1" + }, + "compatible": "st,stm32-tim", + "counter_bits": 16, + "irqs": [ + { + "name": "global", + "number": 29 + } + ], + "name": "tim3", + "size": 1024 + }, + { + "base": 1073743872, + "clock": { + "bit": 2, + "bus": "apb1" + }, + "compatible": "st,stm32-tim", + "counter_bits": 16, + "irqs": [ + { + "name": "global", + "number": 30 + } + ], + "name": "tim4", + "size": 1024 + }, + { + "base": 1073744896, + "clock": { + "bit": 3, + "bus": "apb1" + }, + "compatible": "st,stm32-tim", + "counter_bits": 32, + "irqs": [ + { + "name": "global", + "number": 50 + } + ], + "name": "tim5", + "size": 1024 + }, + { + "base": 1073823744, + "clock": { + "bit": 16, + "bus": "apb2" + }, + "compatible": "st,stm32-tim", + "counter_bits": 16, + "irqs": [ + { + "name": "global", + "number": 24 + } + ], + "name": "tim9", + "size": 1024, + "timer_channels": 2 + }, { "base": 1073897472, "clock": { diff --git a/examples/tasks/generated/nucleo_f446re/docs/system.json b/examples/tasks/src/config/.base/nucleo_f446re/docs/system.json similarity index 77% rename from examples/tasks/generated/nucleo_f446re/docs/system.json rename to examples/tasks/src/config/.base/nucleo_f446re/docs/system.json index ac0af49a..70f65362 100644 --- a/examples/tasks/generated/nucleo_f446re/docs/system.json +++ b/examples/tasks/src/config/.base/nucleo_f446re/docs/system.json @@ -25,29 +25,39 @@ }, { "path": "boards/st/nucleo_f446re/board.yaml", - "sha256": "d756f3a7f19dc7da82ee3afc168dc54946312c5a9990720953c0fedcdece54ea" + "sha256": "551c524379751d359bdd87501269d6cab33edf84d212d2f6632ffe9567ec71d0" }, { "path": "drivers/bindings.yaml", - "sha256": "d3c336ac05548e0addd1faac18f3dff70576d8069f11d89e6a761cf5c6132b49" + "sha256": "c06d1a914adb21d0e314c79b3611ac6859eefeac1957d6914cccfc5531ad6ede" }, { "path": "examples/tasks/system.yaml", - "sha256": "3dd9de88918f06e4b3a41232cb716a9e7d1c4b74ad18e71fd51644ae394ebf9c" + "sha256": "202cff4815e97ab763dc14c61b0b694ee9381307eb46687f9caaea3465a913da" }, { "path": "soc/st/stm32f4/stm32f4.yaml", - "sha256": "3db4a0a65c9624d865d4ed7fc6354bf95054d0c465b76a2091f06aeac3d7375f" + "sha256": "796886c294250aa81151a620d80d0e43b5ee8e1bf53a07d1d7e2c62e95214dbd" }, { "path": "soc/st/stm32f4/stm32f446.yaml", - "sha256": "0d5cc7f5fce4c51be71678987720c85c6e76e05473ff8a78ea5035394316c055" + "sha256": "f0c9a37f6017c87d0efe215a3561f65494ba52383f2d0c10419b0ab5035f77f2" }, { "path": "soc/st/stm32f4/stm32f446re.yaml", "sha256": "b9a88d0a94aa17ee83317a3a56f7c194ec1b3107dfb3e82e453122dc1c48f6d4" } ], + "interrupts": [ + { + "doc": "", + "handler": "WAKE_InterruptHandler", + "irq": 61, + "level": 1, + "name": "wake", + "source": null + } + ], "name": "tasks_demo", "objects": [], "profile": "base", @@ -56,7 +66,6 @@ "spi_targets": [], "tasks": [ { - "data": "door_data_t", "doc": "", "entry": [ "open" @@ -87,7 +96,6 @@ } }, { - "data": null, "doc": "", "entry": [], "event": null, diff --git a/examples/tasks/src/config/.base/nucleo_f446re/docs/system.md b/examples/tasks/src/config/.base/nucleo_f446re/docs/system.md new file mode 100644 index 00000000..cbd31305 --- /dev/null +++ b/examples/tasks/src/config/.base/nucleo_f446re/docs/system.md @@ -0,0 +1,30 @@ +# tasks_demo: the system on nucleo_f446re + +Generated from `examples/tasks/system.yaml` (SPEC-014 §5, A125, A130). Profile base, 32 priorities, a minimum stack of 256 bytes. + +## Tasks + +| Task | Model | Priority | Stack | States (initial first) | Events | +|---|---|---|---|---|---| +| `door` | event, queue 8 | 5 | 1024 | closed, open, jammed | open, close, jam | +| `blink` | periodic, 500 ms | 2 | 512 | dark, lit | — | + +## Interrupts + +| Interrupt | Line | Handler | Level | +|---|---|---|---| +| `wake` | 61 | `WAKE_InterruptHandler` | 1 | + +--- + +Generated by emb-hwgen 0.1.0, schema v0, from: + +| Input | SHA-256 | +|---|---| +| `arch/cortex_m/arch.yaml` | `c5c8e451c09717dee1713d07f8311b6d507e3b4c66c42d93e0ce11da6ec76d6d` | +| `boards/st/nucleo_f446re/board.yaml` | `551c524379751d359bdd87501269d6cab33edf84d212d2f6632ffe9567ec71d0` | +| `drivers/bindings.yaml` | `c06d1a914adb21d0e314c79b3611ac6859eefeac1957d6914cccfc5531ad6ede` | +| `examples/tasks/system.yaml` | `202cff4815e97ab763dc14c61b0b694ee9381307eb46687f9caaea3465a913da` | +| `soc/st/stm32f4/stm32f4.yaml` | `796886c294250aa81151a620d80d0e43b5ee8e1bf53a07d1d7e2c62e95214dbd` | +| `soc/st/stm32f4/stm32f446.yaml` | `f0c9a37f6017c87d0efe215a3561f65494ba52383f2d0c10419b0ab5035f77f2` | +| `soc/st/stm32f4/stm32f446re.yaml` | `b9a88d0a94aa17ee83317a3a56f7c194ec1b3107dfb3e82e453122dc1c48f6d4` | diff --git a/examples/tasks/src/config/.base/nucleo_f446re/initialization.c b/examples/tasks/src/config/.base/nucleo_f446re/initialization.c new file mode 100644 index 00000000..45e6f898 --- /dev/null +++ b/examples/tasks/src/config/.base/nucleo_f446re/initialization.c @@ -0,0 +1,85 @@ +/* SPDX-License-Identifier: Apache-2.0 */ +/* + * This file is part of EmbLinkRTOS, a deterministic real-time kernel for microcontrollers. + * Licensed under the Apache License, Version 2.0; see the LICENSE file at the repository root. + */ + +/******************************************************************************* + System Initialization File + + File Name: + initialization.c + + Summary: + tasks_demo's initialization on the nucleo_f446re: SYS_Initialize(), and the + system's objects. + + Description: + The system's static definitions, which the kernel creates from its + initialization table when emb_kernel_init() runs (SPEC-001 §6.4), and + SYS_Initialize(), which brings up the board, the kernel, the application's + interrupts and the tasks. + + Generated by emb-hwgen 0.1.0, schema v0, from the system description and the + nucleo_f446re's. Yours to edit: regenerating merges its changes with yours + (A126): + hw/gen/emb-hwgen.py generate --system examples/tasks/system.yaml + + Inputs (SHA-256): + arch/cortex_m/arch.yaml + c5c8e451c09717dee1713d07f8311b6d507e3b4c66c42d93e0ce11da6ec76d6d + boards/st/nucleo_f446re/board.yaml + 551c524379751d359bdd87501269d6cab33edf84d212d2f6632ffe9567ec71d0 + drivers/bindings.yaml + c06d1a914adb21d0e314c79b3611ac6859eefeac1957d6914cccfc5531ad6ede + examples/tasks/system.yaml + 202cff4815e97ab763dc14c61b0b694ee9381307eb46687f9caaea3465a913da + soc/st/stm32f4/stm32f4.yaml + 796886c294250aa81151a620d80d0e43b5ee8e1bf53a07d1d7e2c62e95214dbd + soc/st/stm32f4/stm32f446.yaml + f0c9a37f6017c87d0efe215a3561f65494ba52383f2d0c10419b0ab5035f77f2 + soc/st/stm32f4/stm32f446re.yaml + b9a88d0a94aa17ee83317a3a56f7c194ec1b3107dfb3e82e453122dc1c48f6d4 + *******************************************************************************/ + +// ***************************************************************************** +// ***************************************************************************** +// Section: Included Files +// ***************************************************************************** +// ***************************************************************************** + +#include "definitions.h" + +// ***************************************************************************** +// ***************************************************************************** +// Section: System Initialization +// ***************************************************************************** +// ***************************************************************************** + +/******************************************************************************* + Function: + void SYS_Initialize ( void *data ) + + Remarks: + See prototype in definitions.h. + */ +void SYS_Initialize(void *data) +{ + (void)data; + + /* The board: its clocks, pins and console */ + emb_board_init(); + + /* The kernel: its objects, and the EARLY devices */ + emb_kernel_init(); + + /* The application's interrupts */ + SYS_INT_Initialize(); + + /* The tasks, each in its initial state */ + DOOR_Initialize(); + BLINK_Initialize(); +} +/******************************************************************************* + End of File +*/ diff --git a/examples/tasks/src/config/.base/nucleo_f446re/interrupts.c b/examples/tasks/src/config/.base/nucleo_f446re/interrupts.c new file mode 100644 index 00000000..d884d59f --- /dev/null +++ b/examples/tasks/src/config/.base/nucleo_f446re/interrupts.c @@ -0,0 +1,114 @@ +/* SPDX-License-Identifier: Apache-2.0 */ +/* + * This file is part of EmbLinkRTOS, a deterministic real-time kernel for microcontrollers. + * Licensed under the Apache License, Version 2.0; see the LICENSE file at the repository root. + */ + +/******************************************************************************* + Interrupt Handlers + + File Name: + interrupts.c + + Summary: + tasks_demo's interrupts on the nucleo_f446re: the lines in use, and + SYS_INT_Initialize(). + + Description: + The table of every interrupt line in use, the devices' and the + application's, and SYS_INT_Initialize(), which connects the application's + handlers. The checks were made when it was generated: each line is the + SoC's, no device's driver connects it, and its level is the port's. + + Generated by emb-hwgen 0.1.0, schema v0, from the system description and the + nucleo_f446re's. Yours to edit: regenerating merges its changes with yours + (A126): + hw/gen/emb-hwgen.py generate --system examples/tasks/system.yaml + + Inputs (SHA-256): + arch/cortex_m/arch.yaml + c5c8e451c09717dee1713d07f8311b6d507e3b4c66c42d93e0ce11da6ec76d6d + boards/st/nucleo_f446re/board.yaml + 551c524379751d359bdd87501269d6cab33edf84d212d2f6632ffe9567ec71d0 + drivers/bindings.yaml + c06d1a914adb21d0e314c79b3611ac6859eefeac1957d6914cccfc5531ad6ede + examples/tasks/system.yaml + 202cff4815e97ab763dc14c61b0b694ee9381307eb46687f9caaea3465a913da + soc/st/stm32f4/stm32f4.yaml + 796886c294250aa81151a620d80d0e43b5ee8e1bf53a07d1d7e2c62e95214dbd + soc/st/stm32f4/stm32f446.yaml + f0c9a37f6017c87d0efe215a3561f65494ba52383f2d0c10419b0ab5035f77f2 + soc/st/stm32f4/stm32f446re.yaml + b9a88d0a94aa17ee83317a3a56f7c194ec1b3107dfb3e82e453122dc1c48f6d4 + *******************************************************************************/ + +// ***************************************************************************** +// ***************************************************************************** +// Section: Included Files +// ***************************************************************************** +// ***************************************************************************** + +#include "definitions.h" + +// ***************************************************************************** +// ***************************************************************************** +// Section: Interrupt Lines +// ***************************************************************************** +// ***************************************************************************** + +/* The lines in use on the nucleo_f446re: + * 11 dma1, its driver (peripheral.irqs.s0) + * 12 dma1, its driver (peripheral.irqs.s1) + * 13 dma1, its driver (peripheral.irqs.s2) + * 14 dma1, its driver (peripheral.irqs.s3) + * 15 dma1, its driver (peripheral.irqs.s4) + * 16 dma1, its driver (peripheral.irqs.s5) + * 17 dma1, its driver (peripheral.irqs.s6) + * 18 adc1, its driver (peripheral.irqs.global) + * 24 tim9, its driver (peripheral.irqs.global) + * 29 tim3, its driver (peripheral.irqs.global) + * 30 tim4, its driver (peripheral.irqs.global) + * 31 i2c1, its driver (peripheral.irqs.ev) + * 32 i2c1, its driver (peripheral.irqs.er) + * 33 i2c2, its driver (peripheral.irqs.ev) + * 34 i2c2, its driver (peripheral.irqs.er) + * 36 spi2, its driver (peripheral.irqs.global) + * 38 usart2, its driver (peripheral.irqs.global) + * 41 rtc, its driver (peripheral.irqs.alarm) + * 47 dma1, its driver (peripheral.irqs.s7) + * 50 tim5, its driver (peripheral.irqs.global) + * 52 uart4, its driver (peripheral.irqs.global) + * 56 dma2, its driver (peripheral.irqs.s0) + * 57 dma2, its driver (peripheral.irqs.s1) + * 58 dma2, its driver (peripheral.irqs.s2) + * 59 dma2, its driver (peripheral.irqs.s3) + * 60 dma2, its driver (peripheral.irqs.s4) + * 61 wake, the application's WAKE_InterruptHandler() + * 68 dma2, its driver (peripheral.irqs.s5) + * 69 dma2, its driver (peripheral.irqs.s6) + * 70 dma2, its driver (peripheral.irqs.s7) + */ + +// ***************************************************************************** +// ***************************************************************************** +// Section: Interrupt Initialization +// ***************************************************************************** +// ***************************************************************************** + +/******************************************************************************* + Function: + void SYS_INT_Initialize ( void ) + + Remarks: + See prototype in interrupts.h. + */ +void SYS_INT_Initialize(void) +{ + /* wake: line 61 */ + (void)emb_irq_connect(WAKE_IRQ, WAKE_InterruptHandler, NULL); + (void)emb_irq_set_level(WAKE_IRQ, WAKE_IRQ_LEVEL); + (void)emb_irq_enable(WAKE_IRQ); +} +/******************************************************************************* + End of File +*/ diff --git a/examples/tasks/src/config/.base/nucleo_f446re/interrupts.h b/examples/tasks/src/config/.base/nucleo_f446re/interrupts.h new file mode 100644 index 00000000..4a1ef2f0 --- /dev/null +++ b/examples/tasks/src/config/.base/nucleo_f446re/interrupts.h @@ -0,0 +1,133 @@ +/* SPDX-License-Identifier: Apache-2.0 */ +/* + * This file is part of EmbLinkRTOS, a deterministic real-time kernel for microcontrollers. + * Licensed under the Apache License, Version 2.0; see the LICENSE file at the repository root. + */ + +/******************************************************************************* + Interrupt Handlers + + File Name: + interrupts.h + + Summary: + tasks_demo's interrupt handlers on the nucleo_f446re. + + Description: + The application's own interrupt handlers, which it defines + (src/interrupt_handlers.c), and SYS_INT_Initialize(), which connects each at + its level and enables it. The board's devices connect their own: + interrupts.c lists every line in use. + + Generated by emb-hwgen 0.1.0, schema v0, from the system description and the + nucleo_f446re's. Yours to edit: regenerating merges its changes with yours + (A126): + hw/gen/emb-hwgen.py generate --system examples/tasks/system.yaml + + Inputs (SHA-256): + arch/cortex_m/arch.yaml + c5c8e451c09717dee1713d07f8311b6d507e3b4c66c42d93e0ce11da6ec76d6d + boards/st/nucleo_f446re/board.yaml + 551c524379751d359bdd87501269d6cab33edf84d212d2f6632ffe9567ec71d0 + drivers/bindings.yaml + c06d1a914adb21d0e314c79b3611ac6859eefeac1957d6914cccfc5531ad6ede + examples/tasks/system.yaml + 202cff4815e97ab763dc14c61b0b694ee9381307eb46687f9caaea3465a913da + soc/st/stm32f4/stm32f4.yaml + 796886c294250aa81151a620d80d0e43b5ee8e1bf53a07d1d7e2c62e95214dbd + soc/st/stm32f4/stm32f446.yaml + f0c9a37f6017c87d0efe215a3561f65494ba52383f2d0c10419b0ab5035f77f2 + soc/st/stm32f4/stm32f446re.yaml + b9a88d0a94aa17ee83317a3a56f7c194ec1b3107dfb3e82e453122dc1c48f6d4 + *******************************************************************************/ + +#ifndef INTERRUPTS_H +#define INTERRUPTS_H + +// ***************************************************************************** +// ***************************************************************************** +// Section: Included Files +// ***************************************************************************** +// ***************************************************************************** + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +// ***************************************************************************** +// ***************************************************************************** +// Section: Handler Routines +// ***************************************************************************** +// ***************************************************************************** + +/******************************************************************************* + Function: + void WAKE_InterruptHandler ( void *arg ) + + Summary: + The wake interrupt's handler. + + Description: + This function runs in interrupt context when line 61 is raised at level 1: a + kernel-aware handler, which may post to a task (emb_task_post()) but not + wait. + + Precondition: + SYS_INT_Initialize() has connected it. + + Parameters: + arg - Unused; NULL. + + Returns: + None. + + Example: + + emb_irq_pend(WAKE_IRQ); + + + Remarks: + The application defines it. Keep it short: hand the work to a task. +*/ +void WAKE_InterruptHandler(void *arg); + +/******************************************************************************* + Function: + void SYS_INT_Initialize ( void ) + + Summary: + Connects the application's interrupt handlers. + + Description: + This function connects each of the application's handlers to its line, sets + its level and enables it. + + Precondition: + The kernel is initialized (emb_kernel_init()). + + Parameters: + None. + + Returns: + None. + + Example: + + SYS_INT_Initialize(); + + + Remarks: + SYS_Initialize() calls it. +*/ +void SYS_INT_Initialize(void); + +#ifdef __cplusplus +} +#endif + +#endif /* INTERRUPTS_H */ +/******************************************************************************* + End of File +*/ diff --git a/examples/tasks/generated/.base/nucleo_f446re/linker/regions.ld b/examples/tasks/src/config/.base/nucleo_f446re/linker/regions.ld similarity index 91% rename from examples/tasks/generated/.base/nucleo_f446re/linker/regions.ld rename to examples/tasks/src/config/.base/nucleo_f446re/linker/regions.ld index d4165395..b2d8c609 100644 --- a/examples/tasks/generated/.base/nucleo_f446re/linker/regions.ld +++ b/examples/tasks/src/config/.base/nucleo_f446re/linker/regions.ld @@ -17,15 +17,15 @@ * arch/cortex_m/arch.yaml * c5c8e451c09717dee1713d07f8311b6d507e3b4c66c42d93e0ce11da6ec76d6d * boards/st/nucleo_f446re/board.yaml - * d756f3a7f19dc7da82ee3afc168dc54946312c5a9990720953c0fedcdece54ea + * 551c524379751d359bdd87501269d6cab33edf84d212d2f6632ffe9567ec71d0 * drivers/bindings.yaml - * d3c336ac05548e0addd1faac18f3dff70576d8069f11d89e6a761cf5c6132b49 + * c06d1a914adb21d0e314c79b3611ac6859eefeac1957d6914cccfc5531ad6ede * examples/tasks/system.yaml - * 3dd9de88918f06e4b3a41232cb716a9e7d1c4b74ad18e71fd51644ae394ebf9c + * 202cff4815e97ab763dc14c61b0b694ee9381307eb46687f9caaea3465a913da * soc/st/stm32f4/stm32f4.yaml - * 3db4a0a65c9624d865d4ed7fc6354bf95054d0c465b76a2091f06aeac3d7375f + * 796886c294250aa81151a620d80d0e43b5ee8e1bf53a07d1d7e2c62e95214dbd * soc/st/stm32f4/stm32f446.yaml - * 0d5cc7f5fce4c51be71678987720c85c6e76e05473ff8a78ea5035394316c055 + * f0c9a37f6017c87d0efe215a3561f65494ba52383f2d0c10419b0ab5035f77f2 * soc/st/stm32f4/stm32f446re.yaml * b9a88d0a94aa17ee83317a3a56f7c194ec1b3107dfb3e82e453122dc1c48f6d4 */ diff --git a/examples/tasks/generated/.base/nucleo_f446re/src/board_pins.c b/examples/tasks/src/config/.base/nucleo_f446re/peripheral/board_pins.c similarity index 77% rename from examples/tasks/generated/.base/nucleo_f446re/src/board_pins.c rename to examples/tasks/src/config/.base/nucleo_f446re/peripheral/board_pins.c index 8410a389..d26df417 100644 --- a/examples/tasks/generated/.base/nucleo_f446re/src/board_pins.c +++ b/examples/tasks/src/config/.base/nucleo_f446re/peripheral/board_pins.c @@ -16,15 +16,15 @@ * arch/cortex_m/arch.yaml * c5c8e451c09717dee1713d07f8311b6d507e3b4c66c42d93e0ce11da6ec76d6d * boards/st/nucleo_f446re/board.yaml - * d756f3a7f19dc7da82ee3afc168dc54946312c5a9990720953c0fedcdece54ea + * 551c524379751d359bdd87501269d6cab33edf84d212d2f6632ffe9567ec71d0 * drivers/bindings.yaml - * d3c336ac05548e0addd1faac18f3dff70576d8069f11d89e6a761cf5c6132b49 + * c06d1a914adb21d0e314c79b3611ac6859eefeac1957d6914cccfc5531ad6ede * examples/tasks/system.yaml - * 3dd9de88918f06e4b3a41232cb716a9e7d1c4b74ad18e71fd51644ae394ebf9c + * 202cff4815e97ab763dc14c61b0b694ee9381307eb46687f9caaea3465a913da * soc/st/stm32f4/stm32f4.yaml - * 3db4a0a65c9624d865d4ed7fc6354bf95054d0c465b76a2091f06aeac3d7375f + * 796886c294250aa81151a620d80d0e43b5ee8e1bf53a07d1d7e2c62e95214dbd * soc/st/stm32f4/stm32f446.yaml - * 0d5cc7f5fce4c51be71678987720c85c6e76e05473ff8a78ea5035394316c055 + * f0c9a37f6017c87d0efe215a3561f65494ba52383f2d0c10419b0ab5035f77f2 * soc/st/stm32f4/stm32f446re.yaml * b9a88d0a94aa17ee83317a3a56f7c194ec1b3107dfb3e82e453122dc1c48f6d4 */ @@ -40,10 +40,18 @@ const emb_stm32_pin_t emb_board_pins[] = { {EMB_STM32_PORT(A), 2u, EMB_STM32_PIN_AF, 7u, 0u, 0u}, /* PA3: pins.usart2.rx (usart2_rx) */ {EMB_STM32_PORT(A), 3u, EMB_STM32_PIN_AF, 7u, 0u, 0u}, + /* PA4: pins.adc1.in4 (adc1_in4) */ + {EMB_STM32_PORT(A), 4u, EMB_STM32_PIN_ANALOG, 0u, 0u, 0u}, /* PA5: leds.user (output) */ {EMB_STM32_PORT(A), 5u, EMB_STM32_PIN_OUTPUT, 0u, 0u, 0u}, + /* PA6: pins.tim3.ch1 (tim3_ch1) */ + {EMB_STM32_PORT(A), 6u, EMB_STM32_PIN_AF, 2u, 0u, 0u}, + /* PB0: pins.adc1.in8 (adc1_in8) */ + {EMB_STM32_PORT(B), 0u, EMB_STM32_PIN_ANALOG, 0u, 0u, 0u}, /* PB3: pins.i2c2.sda (i2c2_sda) */ {EMB_STM32_PORT(B), 3u, EMB_STM32_PIN_AF, 4u, 0u, EMB_STM32_PIN_I2C}, + /* PB6: pins.tim4.ch1 (tim4_ch1) */ + {EMB_STM32_PORT(B), 6u, EMB_STM32_PIN_AF, 2u, 0u, 0u}, /* PB8: pins.i2c1.scl (i2c1_scl) */ {EMB_STM32_PORT(B), 8u, EMB_STM32_PIN_AF, 4u, 0u, EMB_STM32_PIN_I2C}, /* PB9: pins.i2c1.sda (i2c1_sda) */ diff --git a/examples/tasks/generated/.base/nucleo_f446re/include/hw_config.h b/examples/tasks/src/config/.base/nucleo_f446re/peripheral/hw_config.h similarity index 89% rename from examples/tasks/generated/.base/nucleo_f446re/include/hw_config.h rename to examples/tasks/src/config/.base/nucleo_f446re/peripheral/hw_config.h index b68e5325..8bc74ae4 100644 --- a/examples/tasks/generated/.base/nucleo_f446re/include/hw_config.h +++ b/examples/tasks/src/config/.base/nucleo_f446re/peripheral/hw_config.h @@ -15,15 +15,15 @@ * arch/cortex_m/arch.yaml * c5c8e451c09717dee1713d07f8311b6d507e3b4c66c42d93e0ce11da6ec76d6d * boards/st/nucleo_f446re/board.yaml - * d756f3a7f19dc7da82ee3afc168dc54946312c5a9990720953c0fedcdece54ea + * 551c524379751d359bdd87501269d6cab33edf84d212d2f6632ffe9567ec71d0 * drivers/bindings.yaml - * d3c336ac05548e0addd1faac18f3dff70576d8069f11d89e6a761cf5c6132b49 + * c06d1a914adb21d0e314c79b3611ac6859eefeac1957d6914cccfc5531ad6ede * examples/tasks/system.yaml - * 3dd9de88918f06e4b3a41232cb716a9e7d1c4b74ad18e71fd51644ae394ebf9c + * 202cff4815e97ab763dc14c61b0b694ee9381307eb46687f9caaea3465a913da * soc/st/stm32f4/stm32f4.yaml - * 3db4a0a65c9624d865d4ed7fc6354bf95054d0c465b76a2091f06aeac3d7375f + * 796886c294250aa81151a620d80d0e43b5ee8e1bf53a07d1d7e2c62e95214dbd * soc/st/stm32f4/stm32f446.yaml - * 0d5cc7f5fce4c51be71678987720c85c6e76e05473ff8a78ea5035394316c055 + * f0c9a37f6017c87d0efe215a3561f65494ba52383f2d0c10419b0ab5035f77f2 * soc/st/stm32f4/stm32f446re.yaml * b9a88d0a94aa17ee83317a3a56f7c194ec1b3107dfb3e82e453122dc1c48f6d4 */ @@ -166,6 +166,22 @@ #define EMB_HW_TIM2_CLKEN_BIT 0u #define EMB_HW_TIM2_CLKEN_OFFSET 0x40u #define EMB_HW_TIM2_IRQ 28u +#define EMB_HW_TIM3_BASE 0x40000400u +#define EMB_HW_TIM3_CLKEN_BIT 1u +#define EMB_HW_TIM3_CLKEN_OFFSET 0x40u +#define EMB_HW_TIM3_IRQ 29u +#define EMB_HW_TIM4_BASE 0x40000800u +#define EMB_HW_TIM4_CLKEN_BIT 2u +#define EMB_HW_TIM4_CLKEN_OFFSET 0x40u +#define EMB_HW_TIM4_IRQ 30u +#define EMB_HW_TIM5_BASE 0x40000C00u +#define EMB_HW_TIM5_CLKEN_BIT 3u +#define EMB_HW_TIM5_CLKEN_OFFSET 0x40u +#define EMB_HW_TIM5_IRQ 50u +#define EMB_HW_TIM9_BASE 0x40014000u +#define EMB_HW_TIM9_CLKEN_BIT 16u +#define EMB_HW_TIM9_CLKEN_OFFSET 0x44u +#define EMB_HW_TIM9_IRQ 24u #define EMB_HW_UART4_BASE 0x40004C00u #define EMB_HW_UART4_CLKEN_BIT 19u #define EMB_HW_UART4_CLKEN_OFFSET 0x40u diff --git a/examples/tasks/generated/.base/nucleo_f446re/src/soc_devices.c b/examples/tasks/src/config/.base/nucleo_f446re/peripheral/soc_devices.c similarity index 63% rename from examples/tasks/generated/.base/nucleo_f446re/src/soc_devices.c rename to examples/tasks/src/config/.base/nucleo_f446re/peripheral/soc_devices.c index daf00c71..be35801d 100644 --- a/examples/tasks/generated/.base/nucleo_f446re/src/soc_devices.c +++ b/examples/tasks/src/config/.base/nucleo_f446re/peripheral/soc_devices.c @@ -16,15 +16,15 @@ * arch/cortex_m/arch.yaml * c5c8e451c09717dee1713d07f8311b6d507e3b4c66c42d93e0ce11da6ec76d6d * boards/st/nucleo_f446re/board.yaml - * d756f3a7f19dc7da82ee3afc168dc54946312c5a9990720953c0fedcdece54ea + * 551c524379751d359bdd87501269d6cab33edf84d212d2f6632ffe9567ec71d0 * drivers/bindings.yaml - * d3c336ac05548e0addd1faac18f3dff70576d8069f11d89e6a761cf5c6132b49 + * c06d1a914adb21d0e314c79b3611ac6859eefeac1957d6914cccfc5531ad6ede * examples/tasks/system.yaml - * 3dd9de88918f06e4b3a41232cb716a9e7d1c4b74ad18e71fd51644ae394ebf9c + * 202cff4815e97ab763dc14c61b0b694ee9381307eb46687f9caaea3465a913da * soc/st/stm32f4/stm32f4.yaml - * 3db4a0a65c9624d865d4ed7fc6354bf95054d0c465b76a2091f06aeac3d7375f + * 796886c294250aa81151a620d80d0e43b5ee8e1bf53a07d1d7e2c62e95214dbd * soc/st/stm32f4/stm32f446.yaml - * 0d5cc7f5fce4c51be71678987720c85c6e76e05473ff8a78ea5035394316c055 + * f0c9a37f6017c87d0efe215a3561f65494ba52383f2d0c10419b0ab5035f77f2 * soc/st/stm32f4/stm32f446re.yaml * b9a88d0a94aa17ee83317a3a56f7c194ec1b3107dfb3e82e453122dc1c48f6d4 */ @@ -168,6 +168,36 @@ const emb_device_t emb_dev_dma1 = { .dep_count = 1u, }; +/* dma2: st,stm32-dma, dma, EARLY */ +static const emb_stm32_dma_config_t dma2_config = { + .base = 0x40026400u, /* peripheral.base */ + .clken_offset = 0x00000030u, /* peripheral.clock.enable_offset */ + .clken_bit = 22u, /* peripheral.clock.bit */ + .irq0 = 56u, /* peripheral.irqs.s0 */ + .irq1 = 57u, /* peripheral.irqs.s1 */ + .irq2 = 58u, /* peripheral.irqs.s2 */ + .irq3 = 59u, /* peripheral.irqs.s3 */ + .irq4 = 60u, /* peripheral.irqs.s4 */ + .irq5 = 68u, /* peripheral.irqs.s5 */ + .irq6 = 69u, /* peripheral.irqs.s6 */ + .irq7 = 70u, /* peripheral.irqs.s7 */ + .memory = true, /* peripheral.dma.memory */ +}; +static emb_device_state_t dma2_state; +static emb_stm32_dma_data_t dma2_data; +static const emb_device_t *const dma2_deps[] = {&emb_dev_rcc}; +const emb_device_t emb_dev_dma2 = { + .name = "dma2", + .api = &emb_stm32_dma_api.dev, + .config = &dma2_config, + .state = &dma2_state, + .data = &dma2_data, + .deps = dma2_deps, + .class_id = EMB_DRV_CLASS_DMA, + .level = EMB_DEVICE_EARLY, + .dep_count = 1u, +}; + /* gpiob: st,stm32-gpio, gpio, EARLY */ static const emb_stm32_gpio_config_t gpiob_config = { .base = 0x40020400u, /* peripheral.base */ @@ -341,6 +371,144 @@ const emb_device_t emb_dev_i2c2 = { .dep_count = 1u, }; +/* tim5: st,stm32-tim, counter, KERNEL */ +static const emb_stm32_tim_config_t tim5_config = { + .base = 0x40000C00u, /* peripheral.base */ + .clock_hz = 90000000u, /* peripheral.timer_clock_hz */ + .rate_hz = 1000000u, /* device.rate_hz, its default */ + .clken_offset = 0x00000040u, /* peripheral.clock.enable_offset */ + .clken_bit = 3u, /* peripheral.clock.bit */ + .irq = 50u, /* peripheral.irqs.global */ + .bits = 32u, /* peripheral.counter_bits */ + .channels = 4u, /* peripheral.timer_channels, its default */ +}; +static emb_device_state_t tim5_state; +static emb_stm32_counter_data_t tim5_data; +static const emb_device_t *const tim5_deps[] = {&emb_dev_rcc}; +const emb_device_t emb_dev_tim5 = { + .name = "tim5", + .api = &emb_stm32_counter_api.dev, + .config = &tim5_config, + .state = &tim5_state, + .data = &tim5_data, + .deps = tim5_deps, + .class_id = EMB_DRV_CLASS_COUNTER, + .level = EMB_DEVICE_KERNEL, + .dep_count = 1u, +}; + +/* tim9: st,stm32-tim, counter, KERNEL */ +static const emb_stm32_tim_config_t tim9_config = { + .base = 0x40014000u, /* peripheral.base */ + .clock_hz = 180000000u, /* peripheral.timer_clock_hz */ + .rate_hz = 1000000u, /* device.rate_hz, its default */ + .clken_offset = 0x00000044u, /* peripheral.clock.enable_offset */ + .clken_bit = 16u, /* peripheral.clock.bit */ + .irq = 24u, /* peripheral.irqs.global */ + .bits = 16u, /* peripheral.counter_bits */ + .channels = 2u, /* peripheral.timer_channels */ +}; +static emb_device_state_t tim9_state; +static emb_stm32_counter_data_t tim9_data; +static const emb_device_t *const tim9_deps[] = {&emb_dev_rcc}; +const emb_device_t emb_dev_tim9 = { + .name = "tim9", + .api = &emb_stm32_counter_api.dev, + .config = &tim9_config, + .state = &tim9_state, + .data = &tim9_data, + .deps = tim9_deps, + .class_id = EMB_DRV_CLASS_COUNTER, + .level = EMB_DEVICE_KERNEL, + .dep_count = 1u, +}; + +/* tim3: st,stm32-tim, pwm, KERNEL */ +static const emb_stm32_tim_config_t tim3_config = { + .base = 0x40000400u, /* peripheral.base */ + .clock_hz = 90000000u, /* peripheral.timer_clock_hz */ + .clken_offset = 0x00000040u, /* peripheral.clock.enable_offset */ + .clken_bit = 1u, /* peripheral.clock.bit */ + .irq = 29u, /* peripheral.irqs.global */ + .bits = 16u, /* peripheral.counter_bits */ + .channels = 4u, /* peripheral.timer_channels, its default */ +}; +static emb_device_state_t tim3_state; +static emb_stm32_pwm_data_t tim3_data; +static const emb_device_t *const tim3_deps[] = {&emb_dev_rcc}; +const emb_device_t emb_dev_tim3 = { + .name = "tim3", + .api = &emb_stm32_pwm_api.dev, + .config = &tim3_config, + .state = &tim3_state, + .data = &tim3_data, + .deps = tim3_deps, + .class_id = EMB_DRV_CLASS_PWM, + .level = EMB_DEVICE_KERNEL, + .dep_count = 1u, +}; + +/* tim4: st,stm32-tim, pwm, KERNEL */ +static const emb_stm32_tim_config_t tim4_config = { + .base = 0x40000800u, /* peripheral.base */ + .clock_hz = 90000000u, /* peripheral.timer_clock_hz */ + .clken_offset = 0x00000040u, /* peripheral.clock.enable_offset */ + .clken_bit = 2u, /* peripheral.clock.bit */ + .irq = 30u, /* peripheral.irqs.global */ + .bits = 16u, /* peripheral.counter_bits */ + .channels = 4u, /* peripheral.timer_channels, its default */ +}; +static emb_device_state_t tim4_state; +static emb_stm32_pwm_data_t tim4_data; +static const emb_device_t *const tim4_deps[] = {&emb_dev_rcc}; +const emb_device_t emb_dev_tim4 = { + .name = "tim4", + .api = &emb_stm32_pwm_api.dev, + .config = &tim4_config, + .state = &tim4_state, + .data = &tim4_data, + .deps = tim4_deps, + .class_id = EMB_DRV_CLASS_PWM, + .level = EMB_DEVICE_KERNEL, + .dep_count = 1u, +}; + +/* adc1: st,stm32f4-adc, adc, KERNEL */ +static const emb_stm32_adc_config_t adc1_config = { + .base = 0x40012000u, /* peripheral.base */ + .common = 0x40012300u, /* takes.common.base */ + .calibration = 0x1FFF7A2Au, /* takes.cal.base */ + .trigger = 0x40000000u, /* takes.trigger.base */ + .trigger_hz = 90000000u, /* takes.trigger.timer_clock_hz */ + .trigger_clken_offset = 0x00000040u, /* takes.trigger.clock.enable_offset */ + .trigger_clken_bit = 0u, /* takes.trigger.clock.bit */ + .trigger_select = 6u, /* takes.trigger.adc_trigger */ + .clock_hz = 90000000u, /* peripheral.clock_hz */ + .clken_offset = 0x00000044u, /* peripheral.clock.enable_offset */ + .clken_bit = 8u, /* peripheral.clock.bit */ + .irq = 18u, /* peripheral.irqs.global */ + .vref_mv = 3300u, /* device.vref_mv, its default */ + .bits = 12u, /* peripheral.adc.bits */ + .inputs = 16u, /* peripheral.adc.inputs */ + .temperature = 18u, /* peripheral.adc.temperature */ + .vrefint = 17u, /* peripheral.adc.vrefint */ + .dma_rx = {&emb_dev_dma2, 0u, 0u, {0u, 0u}}, /* dma.rx */ +}; +static emb_device_state_t adc1_state; +static emb_stm32_adc_data_t adc1_data; +static const emb_device_t *const adc1_deps[] = {&emb_dev_dma2, &emb_dev_rcc}; +const emb_device_t emb_dev_adc1 = { + .name = "adc1", + .api = &emb_stm32_adc_api.dev, + .config = &adc1_config, + .state = &adc1_state, + .data = &adc1_data, + .deps = adc1_deps, + .class_id = EMB_DRV_CLASS_ADC, + .level = EMB_DEVICE_KERNEL, + .dep_count = 2u, +}; + /* in initialization order */ static const emb_device_t *const devices[] = { &emb_dev_rcc, /* 0: EARLY */ @@ -349,16 +517,22 @@ static const emb_device_t *const devices[] = { &emb_dev_rtc, /* 3: EARLY */ &emb_dev_flash, /* 4: EARLY */ &emb_dev_dma1, /* 5: EARLY */ - &emb_dev_gpiob, /* 6: EARLY */ - &emb_dev_gpioc, /* 7: EARLY */ - &emb_dev_usart2, /* 8: EARLY */ - &emb_dev_uart4, /* 9: EARLY */ - &emb_dev_spi2, /* 10: KERNEL */ - &emb_dev_i2c1, /* 11: KERNEL */ - &emb_dev_i2c2, /* 12: KERNEL */ + &emb_dev_dma2, /* 6: EARLY */ + &emb_dev_gpiob, /* 7: EARLY */ + &emb_dev_gpioc, /* 8: EARLY */ + &emb_dev_usart2, /* 9: EARLY */ + &emb_dev_uart4, /* 10: EARLY */ + &emb_dev_spi2, /* 11: KERNEL */ + &emb_dev_i2c1, /* 12: KERNEL */ + &emb_dev_i2c2, /* 13: KERNEL */ + &emb_dev_tim5, /* 14: KERNEL */ + &emb_dev_tim9, /* 15: KERNEL */ + &emb_dev_tim3, /* 16: KERNEL */ + &emb_dev_tim4, /* 17: KERNEL */ + &emb_dev_adc1, /* 18: KERNEL */ }; -const emb_device_table_t emb_board_device_table = {devices, 13u, 10u}; +const emb_device_table_t emb_board_device_table = {devices, 19u, 11u}; #if CONFIG_EMB_DRV_ENTROPY /* the board's entropy source, or none: nothing stands in for one (SPEC-017 §11, SEC-012) */ diff --git a/examples/tasks/generated/.base/nucleo_f446re/include/soc_devices.h b/examples/tasks/src/config/.base/nucleo_f446re/peripheral/soc_devices.h similarity index 78% rename from examples/tasks/generated/.base/nucleo_f446re/include/soc_devices.h rename to examples/tasks/src/config/.base/nucleo_f446re/peripheral/soc_devices.h index af292944..86c11042 100644 --- a/examples/tasks/generated/.base/nucleo_f446re/include/soc_devices.h +++ b/examples/tasks/src/config/.base/nucleo_f446re/peripheral/soc_devices.h @@ -15,15 +15,15 @@ * arch/cortex_m/arch.yaml * c5c8e451c09717dee1713d07f8311b6d507e3b4c66c42d93e0ce11da6ec76d6d * boards/st/nucleo_f446re/board.yaml - * d756f3a7f19dc7da82ee3afc168dc54946312c5a9990720953c0fedcdece54ea + * 551c524379751d359bdd87501269d6cab33edf84d212d2f6632ffe9567ec71d0 * drivers/bindings.yaml - * d3c336ac05548e0addd1faac18f3dff70576d8069f11d89e6a761cf5c6132b49 + * c06d1a914adb21d0e314c79b3611ac6859eefeac1957d6914cccfc5531ad6ede * examples/tasks/system.yaml - * 3dd9de88918f06e4b3a41232cb716a9e7d1c4b74ad18e71fd51644ae394ebf9c + * 202cff4815e97ab763dc14c61b0b694ee9381307eb46687f9caaea3465a913da * soc/st/stm32f4/stm32f4.yaml - * 3db4a0a65c9624d865d4ed7fc6354bf95054d0c465b76a2091f06aeac3d7375f + * 796886c294250aa81151a620d80d0e43b5ee8e1bf53a07d1d7e2c62e95214dbd * soc/st/stm32f4/stm32f446.yaml - * 0d5cc7f5fce4c51be71678987720c85c6e76e05473ff8a78ea5035394316c055 + * f0c9a37f6017c87d0efe215a3561f65494ba52383f2d0c10419b0ab5035f77f2 * soc/st/stm32f4/stm32f446re.yaml * b9a88d0a94aa17ee83317a3a56f7c194ec1b3107dfb3e82e453122dc1c48f6d4 */ @@ -32,7 +32,7 @@ #include -#define EMB_SOC_DEVICE_COUNT 13u +#define EMB_SOC_DEVICE_COUNT 19u #if CONFIG_EMB_DEVICE #include @@ -44,6 +44,7 @@ extern const emb_device_t emb_dev_iwdg; extern const emb_device_t emb_dev_rtc; extern const emb_device_t emb_dev_flash; extern const emb_device_t emb_dev_dma1; +extern const emb_device_t emb_dev_dma2; extern const emb_device_t emb_dev_gpiob; extern const emb_device_t emb_dev_gpioc; extern const emb_device_t emb_dev_usart2; @@ -51,6 +52,11 @@ extern const emb_device_t emb_dev_uart4; extern const emb_device_t emb_dev_spi2; extern const emb_device_t emb_dev_i2c1; extern const emb_device_t emb_dev_i2c2; +extern const emb_device_t emb_dev_tim5; +extern const emb_device_t emb_dev_tim9; +extern const emb_device_t emb_dev_tim3; +extern const emb_device_t emb_dev_tim4; +extern const emb_device_t emb_dev_adc1; /* which devices the board has, for code that uses one only where it exists */ #define EMB_SOC_HAS_RCC 1 @@ -59,6 +65,7 @@ extern const emb_device_t emb_dev_i2c2; #define EMB_SOC_HAS_RTC 1 #define EMB_SOC_HAS_FLASH 1 #define EMB_SOC_HAS_DMA1 1 +#define EMB_SOC_HAS_DMA2 1 #define EMB_SOC_HAS_GPIOB 1 #define EMB_SOC_HAS_GPIOC 1 #define EMB_SOC_HAS_USART2 1 @@ -66,6 +73,11 @@ extern const emb_device_t emb_dev_i2c2; #define EMB_SOC_HAS_SPI2 1 #define EMB_SOC_HAS_I2C1 1 #define EMB_SOC_HAS_I2C2 1 +#define EMB_SOC_HAS_TIM5 1 +#define EMB_SOC_HAS_TIM9 1 +#define EMB_SOC_HAS_TIM3 1 +#define EMB_SOC_HAS_TIM4 1 +#define EMB_SOC_HAS_ADC1 1 /* the board's watchdog device: the first of its class */ #define EMB_SOC_WATCHDOG_DEVICE (&emb_dev_iwdg) @@ -73,6 +85,11 @@ extern const emb_device_t emb_dev_i2c2; /* the board's RTC device: the first of its class */ #define EMB_SOC_RTC_DEVICE (&emb_dev_rtc) +/* the board's counters: the first of their class, and all of them (SPEC-017 §11a) */ +#define EMB_SOC_COUNTER_DEVICE (&emb_dev_tim5) +#define EMB_SOC_COUNTER_DEVICES &emb_dev_tim5, &emb_dev_tim9 +#define EMB_SOC_COUNTER_COUNT 2u + /* the console's UART device (the board's console:) */ #define EMB_SOC_CONSOLE_DEVICE (&emb_dev_usart2) /* its writes' DMA channel (devices[].dma, A119) */ @@ -95,6 +112,7 @@ extern const emb_device_t emb_dev_i2c2; #define EMB_SOC_USART2_DMA_TX {&emb_dev_dma1, 6u, 4u, {0u, 0u}} #define EMB_SOC_SPI2_DMA_RX {&emb_dev_dma1, 3u, 0u, {0u, 0u}} #define EMB_SOC_SPI2_DMA_TX {&emb_dev_dma1, 4u, 0u, {0u, 0u}} +#define EMB_SOC_ADC1_DMA_RX {&emb_dev_dma2, 0u, 0u, {0u, 0u}} /* clang-format on */ /* the SPI devices' chip selects (devices[].cs), emb_drv_gpio_line_t initializers; the pin diff --git a/examples/tasks/src/config/.base/nucleo_f446re/tasks.c b/examples/tasks/src/config/.base/nucleo_f446re/tasks.c new file mode 100644 index 00000000..16a7a716 --- /dev/null +++ b/examples/tasks/src/config/.base/nucleo_f446re/tasks.c @@ -0,0 +1,206 @@ +/* SPDX-License-Identifier: Apache-2.0 */ +/* + * This file is part of EmbLinkRTOS, a deterministic real-time kernel for microcontrollers. + * Licensed under the Apache License, Version 2.0; see the LICENSE file at the repository root. + */ + +/******************************************************************************* + System Tasks File + + File Name: + tasks.c + + Summary: + tasks_demo's tasks on the nucleo_f446re, and SYS_Tasks(). + + Description: + Each task's thread, queue, dispatch and description: the thread runs the + task runtime, emb_task_run() (SPEC-020), which calls an event task's handler + for each event, and a periodic task's _Tasks() every period, without drift. + SYS_Tasks() starts the kernel. + + Generated by emb-hwgen 0.1.0, schema v0, from the system description and the + nucleo_f446re's. Yours to edit: regenerating merges its changes with yours + (A126): + hw/gen/emb-hwgen.py generate --system examples/tasks/system.yaml + + Inputs (SHA-256): + arch/cortex_m/arch.yaml + c5c8e451c09717dee1713d07f8311b6d507e3b4c66c42d93e0ce11da6ec76d6d + boards/st/nucleo_f446re/board.yaml + 551c524379751d359bdd87501269d6cab33edf84d212d2f6632ffe9567ec71d0 + drivers/bindings.yaml + c06d1a914adb21d0e314c79b3611ac6859eefeac1957d6914cccfc5531ad6ede + examples/tasks/system.yaml + 202cff4815e97ab763dc14c61b0b694ee9381307eb46687f9caaea3465a913da + soc/st/stm32f4/stm32f4.yaml + 796886c294250aa81151a620d80d0e43b5ee8e1bf53a07d1d7e2c62e95214dbd + soc/st/stm32f4/stm32f446.yaml + f0c9a37f6017c87d0efe215a3561f65494ba52383f2d0c10419b0ab5035f77f2 + soc/st/stm32f4/stm32f446re.yaml + b9a88d0a94aa17ee83317a3a56f7c194ec1b3107dfb3e82e453122dc1c48f6d4 + *******************************************************************************/ + +// ***************************************************************************** +// ***************************************************************************** +// Section: Included Files +// ***************************************************************************** +// ***************************************************************************** + +#include "definitions.h" + +// ***************************************************************************** +// ***************************************************************************** +// Section: RTOS "Tasks" Routine +// ***************************************************************************** +// ***************************************************************************** + +/* ---- door: an event task, its queue 8 deep (SPEC-020) ---- */ + +_Static_assert(DOOR_STATE_CLOSED == 0, "door.h: DOOR_STATES are system.yaml's states, in order"); +_Static_assert(DOOR_STATE_OPEN == 1, "door.h: DOOR_STATES are system.yaml's states, in order"); +_Static_assert(DOOR_STATE_JAMMED == 2, "door.h: DOOR_STATES are system.yaml's states, in order"); +_Static_assert(DOOR_EVENT_OPEN == EMB_EV_USER + 0u, + "door.h: DOOR_EVENTS are system.yaml's events, in order"); +_Static_assert(DOOR_EVENT_CLOSE == EMB_EV_USER + 1u, + "door.h: DOOR_EVENTS are system.yaml's events, in order"); +_Static_assert(DOOR_EVENT_JAM == EMB_EV_USER + 2u, + "door.h: DOOR_EVENTS are system.yaml's events, in order"); + +static emb_task_event_t door_event; +EMB_MSGQ_DEFINE(door_task_queue, sizeof(emb_task_event_t), DOOR_QUEUE_LENGTH, 0u); +static const uint32_t door_timeouts[3] = {0u, DOOR_OPEN_TIMEOUT_MS, 0u}; + +static emb_state_t door_dispatch(emb_state_t state, uint8_t why) +{ + emb_state_t next = state; /* a state the task lacks stays: the runtime faults on it */ + if (why == EMB_TASK_WHY_TIMEOUT) { + door_event.id = EMB_EV_TIMEOUT; + door_event.value = 0u; + } + switch (state) { + case DOOR_STATE_CLOSED: + doorData.state = DOOR_STATE_CLOSED; + next = (emb_state_t)DOOR_OnClosed(&door_event); + break; + case DOOR_STATE_OPEN: + doorData.state = DOOR_STATE_OPEN; + next = (emb_state_t)DOOR_OnOpen(&door_event); + break; + case DOOR_STATE_JAMMED: + doorData.state = DOOR_STATE_JAMMED; + next = (emb_state_t)DOOR_OnJammed(&door_event); + break; + default: + break; + } + return next; +} + +static void door_enter(emb_state_t state) +{ + switch (state) { + case DOOR_STATE_CLOSED: + doorData.state = DOOR_STATE_CLOSED; + break; + case DOOR_STATE_OPEN: + doorData.state = DOOR_STATE_OPEN; + DOOR_EnterOpen(); + break; + case DOOR_STATE_JAMMED: + doorData.state = DOOR_STATE_JAMMED; + break; + default: + break; + } +} + +static void door_exit(emb_state_t state) +{ + if (state == DOOR_STATE_OPEN) { + DOOR_ExitOpen(); + } +} + +static const emb_task_desc_t door_desc = { + .name = "door", + .dispatch = door_dispatch, + .enter = door_enter, + .leave = door_exit, + .event = &door_event, + .queue = &door_task_queue, + .timeout_ms = door_timeouts, + .period_ms = 0u, + .event_size = (uint16_t)sizeof(emb_task_event_t), + .initial = (emb_state_t)DOOR_STATE_CLOSED, + .count = 3u, + .model = EMB_TASK_EVENT, +}; +emb_task_t door_task = {.desc = &door_desc, .state = (emb_state_t)DOOR_STATE_CLOSED}; + +static void door_main(void *arg) +{ + (void)arg; + emb_task_run(&door_task); +} + +EMB_THREAD_DEFINE(door_thread, door_main, NULL, DOOR_PRIORITY, DOOR_STACK_SIZE, 0u); + +/* ---- blink: a periodic task, every 500 ms (SPEC-020) ---- */ + +_Static_assert(BLINK_STATE_DARK == 0, "blink.h: BLINK_STATES are system.yaml's states, in order"); +_Static_assert(BLINK_STATE_LIT == 1, "blink.h: BLINK_STATES are system.yaml's states, in order"); + +static emb_state_t blink_dispatch(emb_state_t state, uint8_t why) +{ + (void)state; + (void)why; + BLINK_Tasks(); + return (emb_state_t)blinkData.state; +} + +static const emb_task_desc_t blink_desc = { + .name = "blink", + .dispatch = blink_dispatch, + .enter = NULL, + .leave = NULL, + .event = NULL, + .queue = NULL, + .timeout_ms = NULL, + .period_ms = BLINK_PERIOD_MS, + .event_size = 0u, + .initial = (emb_state_t)BLINK_STATE_DARK, + .count = 2u, + .model = EMB_TASK_PERIODIC, +}; +emb_task_t blink_task = {.desc = &blink_desc, .state = (emb_state_t)BLINK_STATE_DARK}; + +static void blink_main(void *arg) +{ + (void)arg; + emb_task_run(&blink_task); +} + +EMB_THREAD_DEFINE(blink_thread, blink_main, NULL, BLINK_PRIORITY, BLINK_STACK_SIZE, 0u); + +// ***************************************************************************** +// ***************************************************************************** +// Section: System "Tasks" Routine +// ***************************************************************************** +// ***************************************************************************** + +/******************************************************************************* + Function: + void SYS_Tasks ( void ) + + Remarks: + See prototype in definitions.h. + */ +void SYS_Tasks(void) +{ + /* Start the kernel: the threads and the tasks run from here. It does not return. */ + emb_kernel_start(); +} +/******************************************************************************* + End of File +*/ diff --git a/examples/tasks/generated/pico2_w/build/CMakeLists.txt b/examples/tasks/src/config/.base/pico2_w/build/CMakeLists.txt similarity index 63% rename from examples/tasks/generated/pico2_w/build/CMakeLists.txt rename to examples/tasks/src/config/.base/pico2_w/build/CMakeLists.txt index 7a1b34e1..55e1769d 100644 --- a/examples/tasks/generated/pico2_w/build/CMakeLists.txt +++ b/examples/tasks/src/config/.base/pico2_w/build/CMakeLists.txt @@ -9,15 +9,15 @@ # arch/cortex_m/arch.yaml # c5c8e451c09717dee1713d07f8311b6d507e3b4c66c42d93e0ce11da6ec76d6d # boards/rpi/pico2_w/board.yaml -# dad0ef7259e41ef3bd8fa07ea1c1f36040254a443deaf30d963b4fb14b5354a0 +# 345279a53c444bc45e7fcc1a0cb5ab47b32a7699534f5484ea80d73f7a0bdf6d # drivers/bindings.yaml -# d3c336ac05548e0addd1faac18f3dff70576d8069f11d89e6a761cf5c6132b49 +# c06d1a914adb21d0e314c79b3611ac6859eefeac1957d6914cccfc5531ad6ede # examples/tasks/system.yaml -# 3dd9de88918f06e4b3a41232cb716a9e7d1c4b74ad18e71fd51644ae394ebf9c +# 202cff4815e97ab763dc14c61b0b694ee9381307eb46687f9caaea3465a913da # soc/rpi/rp2350/rp2350.yaml -# 9e60e99ecac8782bccd69e3bd69014af1d8891d6b6fbd822acff5bd9a526d8cd +# 80773a9c9cfb1c62cd322e397111a11d7f48fce3c0febc76bf7d5571018977a5 # soc/rpi/rp2350/rp2350a.yaml -# 045cef7794c3b6c6d2ff48ba294c6308d00fe13bc65e346f2ba2ccde1cea24ff +# 22395e35ed229020b5c9c7586af50cfaa07960a09905776eb4713ff28051eb3c # The board has no C of its own: its SoC family's board support builds emb_board from -# ../src/board_pins.c and ../include/hw_config.h, and links ../linker/regions.ld. +# ../peripheral/board_pins.c and ../peripheral/hw_config.h, and links ../linker/regions.ld. add_subdirectory("${EMB_SOC_DIR}" soc) diff --git a/examples/tasks/generated/pico2_w/build/board.cmake b/examples/tasks/src/config/.base/pico2_w/build/board.cmake similarity index 63% rename from examples/tasks/generated/pico2_w/build/board.cmake rename to examples/tasks/src/config/.base/pico2_w/build/board.cmake index 4441989e..822453b3 100644 --- a/examples/tasks/generated/pico2_w/build/board.cmake +++ b/examples/tasks/src/config/.base/pico2_w/build/board.cmake @@ -9,36 +9,39 @@ # arch/cortex_m/arch.yaml # c5c8e451c09717dee1713d07f8311b6d507e3b4c66c42d93e0ce11da6ec76d6d # boards/rpi/pico2_w/board.yaml -# dad0ef7259e41ef3bd8fa07ea1c1f36040254a443deaf30d963b4fb14b5354a0 +# 345279a53c444bc45e7fcc1a0cb5ab47b32a7699534f5484ea80d73f7a0bdf6d # drivers/bindings.yaml -# d3c336ac05548e0addd1faac18f3dff70576d8069f11d89e6a761cf5c6132b49 +# c06d1a914adb21d0e314c79b3611ac6859eefeac1957d6914cccfc5531ad6ede # examples/tasks/system.yaml -# 3dd9de88918f06e4b3a41232cb716a9e7d1c4b74ad18e71fd51644ae394ebf9c +# 202cff4815e97ab763dc14c61b0b694ee9381307eb46687f9caaea3465a913da # soc/rpi/rp2350/rp2350.yaml -# 9e60e99ecac8782bccd69e3bd69014af1d8891d6b6fbd822acff5bd9a526d8cd +# 80773a9c9cfb1c62cd322e397111a11d7f48fce3c0febc76bf7d5571018977a5 # soc/rpi/rp2350/rp2350a.yaml -# 045cef7794c3b6c6d2ff48ba294c6308d00fe13bc65e346f2ba2ccde1cea24ff +# 22395e35ed229020b5c9c7586af50cfaa07960a09905776eb4713ff28051eb3c # pico2_w: RP2350A, cortex-m33f at 150 MHz. set(EMB_BOARD_ARCH cortex_m) set(EMB_BOARD_VARIANT armv8m-main) set(EMB_BOARD_DEFAULT_PROFILE base) set(EMB_BOARD_C_FLAGS -mcpu=cortex-m33 -mfpu=fpv5-sp-d16 -mfloat-abi=hard) get_filename_component(EMB_BOARD_GENERATED_DIR "${CMAKE_CURRENT_LIST_DIR}/.." ABSOLUTE) -set(EMB_BOARD_CONF "${EMB_BOARD_GENERATED_DIR}/config/board.conf") +set(EMB_BOARD_CONF "${EMB_BOARD_GENERATED_DIR}/build/board.conf") set(EMB_BOARD_HW_JSON "${EMB_BOARD_GENERATED_DIR}/docs/hw.json") set(EMB_BOARD_BUILD_DIR "${CMAKE_CURRENT_LIST_DIR}") # build/CMakeLists.txt +set(EMB_BOARD_SRC_DIR "${EMB_BOARD_GENERATED_DIR}/peripheral") # its pin table and boot block +set(EMB_BOARD_LINKER_DIR "${EMB_BOARD_GENERATED_DIR}/linker") # the SoC family's board support and drivers build this board (build/CMakeLists.txt) set(EMB_SOC_DIR "${EMB_BASE}/soc/rpi/rp2350") -set(EMB_BOARD_INCLUDE_DIRS "${EMB_BOARD_GENERATED_DIR}/include" "${EMB_SOC_DIR}/include") +set(EMB_BOARD_INCLUDE_DIRS "${EMB_BOARD_GENERATED_DIR}/peripheral" "${EMB_SOC_DIR}/include") set(EMB_BOARD_RESETS_IN hil) # restart the image with RAM kept (test_crash_reset) set(EMB_BOARD_UART1_DMA tx) set(EMB_BOARD_SPI1_DMA rx tx) set(EMB_BOARD_SPI1_CS_COUNT 1) +set(EMB_BOARD_ADC_DMA rx) set(EMB_BOARD_FLASH_IMAGE uf2) # what the SoC's boot ROM loads (A79) set(EMB_BOARD_UF2_FAMILY 0xE48BFF59) # the board's devices (soc_devices.c) and the drivers they use, and only those (SPEC-016 §8) set(EMB_BOARD_DRIVER_SOURCES - "${EMB_BOARD_GENERATED_DIR}/src/soc_devices.c" + "${EMB_BOARD_GENERATED_DIR}/peripheral/soc_devices.c" "${EMB_BASE}/drivers/rpi/rp2350_devices.c" "${EMB_BASE}/drivers/rpi/rp2350_gpio.c" "${EMB_BASE}/drivers/rpi/rp2350_watchdog.c" @@ -49,6 +52,9 @@ set(EMB_BOARD_DRIVER_SOURCES "${EMB_BASE}/drivers/rpi/rp2350_trng.c" "${EMB_BASE}/drivers/arm/pl022.c" "${EMB_BASE}/drivers/snps/dw_i2c.c" + "${EMB_BASE}/drivers/rpi/rp2350_timer.c" + "${EMB_BASE}/drivers/rpi/rp2350_pwm.c" + "${EMB_BASE}/drivers/rpi/rp2350_adc.c" ) set(EMB_BOARD_DRIVER_INCLUDE_DIRS "${EMB_BASE}/drivers/rpi/include" @@ -58,9 +64,9 @@ set(EMB_BOARD_DRIVER_INCLUDE_DIRS # the inputs this directory was generated from, for the configure-time staleness check set(EMB_BOARD_HW_INPUTS "arch/cortex_m/arch.yaml=c5c8e451c09717dee1713d07f8311b6d507e3b4c66c42d93e0ce11da6ec76d6d" - "boards/rpi/pico2_w/board.yaml=dad0ef7259e41ef3bd8fa07ea1c1f36040254a443deaf30d963b4fb14b5354a0" - "drivers/bindings.yaml=d3c336ac05548e0addd1faac18f3dff70576d8069f11d89e6a761cf5c6132b49" - "examples/tasks/system.yaml=3dd9de88918f06e4b3a41232cb716a9e7d1c4b74ad18e71fd51644ae394ebf9c" - "soc/rpi/rp2350/rp2350.yaml=9e60e99ecac8782bccd69e3bd69014af1d8891d6b6fbd822acff5bd9a526d8cd" - "soc/rpi/rp2350/rp2350a.yaml=045cef7794c3b6c6d2ff48ba294c6308d00fe13bc65e346f2ba2ccde1cea24ff" + "boards/rpi/pico2_w/board.yaml=345279a53c444bc45e7fcc1a0cb5ab47b32a7699534f5484ea80d73f7a0bdf6d" + "drivers/bindings.yaml=c06d1a914adb21d0e314c79b3611ac6859eefeac1957d6914cccfc5531ad6ede" + "examples/tasks/system.yaml=202cff4815e97ab763dc14c61b0b694ee9381307eb46687f9caaea3465a913da" + "soc/rpi/rp2350/rp2350.yaml=80773a9c9cfb1c62cd322e397111a11d7f48fce3c0febc76bf7d5571018977a5" + "soc/rpi/rp2350/rp2350a.yaml=22395e35ed229020b5c9c7586af50cfaa07960a09905776eb4713ff28051eb3c" ) diff --git a/examples/tasks/generated/pico2_w/config/board.conf b/examples/tasks/src/config/.base/pico2_w/build/board.conf similarity index 70% rename from examples/tasks/generated/pico2_w/config/board.conf rename to examples/tasks/src/config/.base/pico2_w/build/board.conf index 970e867a..5053d50e 100644 --- a/examples/tasks/generated/pico2_w/config/board.conf +++ b/examples/tasks/src/config/.base/pico2_w/build/board.conf @@ -9,15 +9,15 @@ # arch/cortex_m/arch.yaml # c5c8e451c09717dee1713d07f8311b6d507e3b4c66c42d93e0ce11da6ec76d6d # boards/rpi/pico2_w/board.yaml -# dad0ef7259e41ef3bd8fa07ea1c1f36040254a443deaf30d963b4fb14b5354a0 +# 345279a53c444bc45e7fcc1a0cb5ab47b32a7699534f5484ea80d73f7a0bdf6d # drivers/bindings.yaml -# d3c336ac05548e0addd1faac18f3dff70576d8069f11d89e6a761cf5c6132b49 +# c06d1a914adb21d0e314c79b3611ac6859eefeac1957d6914cccfc5531ad6ede # examples/tasks/system.yaml -# 3dd9de88918f06e4b3a41232cb716a9e7d1c4b74ad18e71fd51644ae394ebf9c +# 202cff4815e97ab763dc14c61b0b694ee9381307eb46687f9caaea3465a913da # soc/rpi/rp2350/rp2350.yaml -# 9e60e99ecac8782bccd69e3bd69014af1d8891d6b6fbd822acff5bd9a526d8cd +# 80773a9c9cfb1c62cd322e397111a11d7f48fce3c0febc76bf7d5571018977a5 # soc/rpi/rp2350/rp2350a.yaml -# 045cef7794c3b6c6d2ff48ba294c6308d00fe13bc65e346f2ba2ccde1cea24ff +# 22395e35ed229020b5c9c7586af50cfaa07960a09905776eb4713ff28051eb3c # Board defaults for pico2_w. Applied before the profile fragment. CONFIG_EMB_CM_CPU_HZ=150000000 CONFIG_EMB_CM_IRQ_COUNT=52 diff --git a/examples/tasks/src/config/.base/pico2_w/configuration.h b/examples/tasks/src/config/.base/pico2_w/configuration.h new file mode 100644 index 00000000..faf92355 --- /dev/null +++ b/examples/tasks/src/config/.base/pico2_w/configuration.h @@ -0,0 +1,108 @@ +/* SPDX-License-Identifier: Apache-2.0 */ +/* + * This file is part of EmbLinkRTOS, a deterministic real-time kernel for microcontrollers. + * Licensed under the Apache License, Version 2.0; see the LICENSE file at the repository root. + */ + +/******************************************************************************* + System Configuration Header + + File Name: + configuration.h + + Summary: + The build-time configuration of tasks_demo on the pico2_w. + + Description: + The system's settings as macros: the board and its clock, the devices' + settings, each task's and thread's priority and stack, the tasks' periods, + queues and timeouts, and the application's interrupts. The kernel's own + options are 's CONFIG_EMB_*, and the board's hardware + 's EMB_HW_*. + + Generated by emb-hwgen 0.1.0, schema v0, from the system description and the + pico2_w's. Yours to edit: regenerating merges its changes with yours (A126): + hw/gen/emb-hwgen.py generate --system examples/tasks/system.yaml + + Inputs (SHA-256): + arch/cortex_m/arch.yaml + c5c8e451c09717dee1713d07f8311b6d507e3b4c66c42d93e0ce11da6ec76d6d + boards/rpi/pico2_w/board.yaml + 345279a53c444bc45e7fcc1a0cb5ab47b32a7699534f5484ea80d73f7a0bdf6d + drivers/bindings.yaml + c06d1a914adb21d0e314c79b3611ac6859eefeac1957d6914cccfc5531ad6ede + examples/tasks/system.yaml + 202cff4815e97ab763dc14c61b0b694ee9381307eb46687f9caaea3465a913da + soc/rpi/rp2350/rp2350.yaml + 80773a9c9cfb1c62cd322e397111a11d7f48fce3c0febc76bf7d5571018977a5 + soc/rpi/rp2350/rp2350a.yaml + 22395e35ed229020b5c9c7586af50cfaa07960a09905776eb4713ff28051eb3c + *******************************************************************************/ + +#ifndef CONFIGURATION_H +#define CONFIGURATION_H + +// ***************************************************************************** +// ***************************************************************************** +// Section: Included Files +// ***************************************************************************** +// ***************************************************************************** + +#include + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +// ***************************************************************************** +// ***************************************************************************** +// Section: System Configuration +// ***************************************************************************** +// ***************************************************************************** + +#define SYS_CPU_CLOCK_HZ 150000000u +#define SYS_TICK_NS CONFIG_EMB_TICK_NS +#define SYS_PRIORITY_COUNT CONFIG_EMB_PRIORITY_COUNT + +// ***************************************************************************** +// ***************************************************************************** +// Section: Driver Configuration +// ***************************************************************************** +// ***************************************************************************** + +#define DRV_FLASH_SIZE 4194304u +#define DRV_UART0_BAUD 115200u +#define DRV_UART1_BAUD 115200u +#define DRV_TRNG_SAMPLE_COUNT 200u + +// ***************************************************************************** +// ***************************************************************************** +// Section: Application Configuration +// ***************************************************************************** +// ***************************************************************************** + +/* door: an event task, its queue 8 deep */ +#define DOOR_PRIORITY 5u +#define DOOR_STACK_SIZE 1024u +#define DOOR_QUEUE_LENGTH 8u +#define DOOR_OPEN_TIMEOUT_MS 2000u + +/* blink: a periodic task, every 500 ms */ +#define BLINK_PRIORITY 2u +#define BLINK_STACK_SIZE 512u +#define BLINK_PERIOD_MS 500u + +/* wake: an interrupt, WAKE_InterruptHandler() */ +#define WAKE_IRQ 46u +#define WAKE_IRQ_LEVEL 1u + +#ifdef __cplusplus +} +#endif + +#endif /* CONFIGURATION_H */ +/******************************************************************************* + End of File +*/ diff --git a/examples/tasks/src/config/.base/pico2_w/definitions.h b/examples/tasks/src/config/.base/pico2_w/definitions.h new file mode 100644 index 00000000..a8ac7c45 --- /dev/null +++ b/examples/tasks/src/config/.base/pico2_w/definitions.h @@ -0,0 +1,170 @@ +/* SPDX-License-Identifier: Apache-2.0 */ +/* + * This file is part of EmbLinkRTOS, a deterministic real-time kernel for microcontrollers. + * Licensed under the Apache License, Version 2.0; see the LICENSE file at the repository root. + */ + +/******************************************************************************* + System Definitions + + File Name: + definitions.h + + Summary: + tasks_demo's system definitions on the pico2_w. + + Description: + The one header the application includes: the kernel's API, the board's + devices, the system's configuration and handles, every task's header, and + the system's two functions, SYS_Initialize() and SYS_Tasks(). + + Generated by emb-hwgen 0.1.0, schema v0, from the system description and the + pico2_w's. Yours to edit: regenerating merges its changes with yours (A126): + hw/gen/emb-hwgen.py generate --system examples/tasks/system.yaml + + Inputs (SHA-256): + arch/cortex_m/arch.yaml + c5c8e451c09717dee1713d07f8311b6d507e3b4c66c42d93e0ce11da6ec76d6d + boards/rpi/pico2_w/board.yaml + 345279a53c444bc45e7fcc1a0cb5ab47b32a7699534f5484ea80d73f7a0bdf6d + drivers/bindings.yaml + c06d1a914adb21d0e314c79b3611ac6859eefeac1957d6914cccfc5531ad6ede + examples/tasks/system.yaml + 202cff4815e97ab763dc14c61b0b694ee9381307eb46687f9caaea3465a913da + soc/rpi/rp2350/rp2350.yaml + 80773a9c9cfb1c62cd322e397111a11d7f48fce3c0febc76bf7d5571018977a5 + soc/rpi/rp2350/rp2350a.yaml + 22395e35ed229020b5c9c7586af50cfaa07960a09905776eb4713ff28051eb3c + *******************************************************************************/ + +#ifndef DEFINITIONS_H +#define DEFINITIONS_H + +// ***************************************************************************** +// ***************************************************************************** +// Section: Included Files +// ***************************************************************************** +// ***************************************************************************** + +#include "blink.h" +#include "configuration.h" +#include "door.h" +#include "interrupts.h" + +#include + +#include +#include +#include + +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/* Device Information */ +#define DEVICE_NAME "RP2350A" +#define DEVICE_ARCH "cortex-m33f" +#define DEVICE_FAMILY "rp2350" +#define BOARD_NAME "pico2_w" + +/* CPU clock frequency */ +#define CPU_CLOCK_FREQUENCY 150000000u + +// ***************************************************************************** +// ***************************************************************************** +// Section: System Functions +// ***************************************************************************** +// ***************************************************************************** + +/******************************************************************************* + Function: + void SYS_Initialize ( void *data ) + + Summary: + Initializes the board, the kernel and every task. + + Description: + This function initializes the board (its clocks, pins and console), then the + kernel (its objects and the EARLY devices), then the application's + interrupts, then each task, in its initial state. The KERNEL devices start + with the kernel, in SYS_Tasks(). + + Precondition: + None. + + Parameters: + data - Unused; NULL. + + Returns: + None. + + Example: + + SYS_Initialize(NULL); + while (true) { + SYS_Tasks(); + } + + + Remarks: + This function is called once, after reset, from main(). +*/ +void SYS_Initialize(void *data); + +/******************************************************************************* + Function: + void SYS_Tasks ( void ) + + Summary: + Starts the kernel: the threads and the tasks run from here. + + Description: + This function starts the KERNEL devices, then the scheduler, which runs the + system's threads and each task's thread. It does not return. + + Precondition: + SYS_Initialize() has run. + + Parameters: + None. + + Returns: + It does not return. + + Example: + + SYS_Initialize(NULL); + while (true) { + SYS_Tasks(); + } + + + Remarks: + Harmony calls its SYS_Tasks() in a loop; this one runs the scheduler and + never comes back. +*/ +void SYS_Tasks(void); + +// ***************************************************************************** +// ***************************************************************************** +// Section: Tasks +// ***************************************************************************** +// ***************************************************************************** + +/* each task's handle, for emb_task_post() (SPEC-020) */ +extern emb_task_t door_task; +extern emb_task_t blink_task; +#define DOOR_TASK (&door_task) +#define BLINK_TASK (&blink_task) + +#ifdef __cplusplus +} +#endif + +#endif /* DEFINITIONS_H */ +/******************************************************************************* + End of File +*/ diff --git a/examples/tasks/generated/.base/pico2_w/docs/board.md b/examples/tasks/src/config/.base/pico2_w/docs/board.md similarity index 74% rename from examples/tasks/generated/.base/pico2_w/docs/board.md rename to examples/tasks/src/config/.base/pico2_w/docs/board.md index 31205aec..4ed4c03d 100644 --- a/examples/tasks/generated/.base/pico2_w/docs/board.md +++ b/examples/tasks/src/config/.base/pico2_w/docs/board.md @@ -41,6 +41,10 @@ The console on UART0 at 115200 baud on GPIO0 (TX, pin 1) and GPIO1 (RX, pin 2). | GPIO11 | `pins.spi1.mosi` | af1 (spi1_mosi) | | GPIO12 | `pins.spi1.miso` | af1 (spi1_miso) | | GPIO13 | `devices.spi1.cs[0]` | output | +| GPIO14 | `pins.pwm7.a` | af4 (pwm7_a) | +| GPIO17 | `pins.pwm0.b` | af4 (pwm0_b) | +| GPIO26 | `pins.adc.in0` | analog | +| GPIO27 | `pins.adc.in1` | analog | ## Devices @@ -60,11 +64,25 @@ In initialization order (SPEC-016 §4). | spi1 | `arm,pl022` | spi | KERNEL | io_bank0, dma | | i2c0 | `snps,designware-i2c` | i2c | KERNEL | io_bank0 | | i2c1 | `snps,designware-i2c` | i2c | KERNEL | io_bank0 | +| timer1 | `rpi,rp2350-timer` | counter | KERNEL | - | +| pwm7 | `rpi,rp2350-pwm` | pwm | KERNEL | io_bank0 | +| pwm0 | `rpi,rp2350-pwm` | pwm | KERNEL | io_bank0 | +| adc | `rpi,rp2350-adc` | adc | KERNEL | clocks, io_bank0, dma | ## Interrupt lines | Line | Owner | |---|---| +| 0 | timer0.alarm0 | +| 1 | timer0.alarm1 | +| 2 | timer0.alarm2 | +| 3 | timer0.alarm3 | +| 4 | timer1.alarm0 | +| 5 | timer1.alarm1 | +| 6 | timer1.alarm2 | +| 7 | timer1.alarm3 | +| 8 | pwm.wrap0 | +| 9 | pwm.wrap1 | | 10 | dma.irq0 | | 11 | dma.irq1 | | 12 | dma.irq2 | @@ -75,6 +93,7 @@ In initialization order (SPEC-016 §4). | 32 | spi1.global | | 33 | uart0.global | | 34 | uart1.global | +| 35 | adc.fifo | | 36 | i2c0.global | | 37 | i2c1.global | | 39 | trng.irq | @@ -89,8 +108,8 @@ Generated by emb-hwgen 0.1.0, schema v0, from: | Input | SHA-256 | |---|---| | `arch/cortex_m/arch.yaml` | `c5c8e451c09717dee1713d07f8311b6d507e3b4c66c42d93e0ce11da6ec76d6d` | -| `boards/rpi/pico2_w/board.yaml` | `dad0ef7259e41ef3bd8fa07ea1c1f36040254a443deaf30d963b4fb14b5354a0` | -| `drivers/bindings.yaml` | `d3c336ac05548e0addd1faac18f3dff70576d8069f11d89e6a761cf5c6132b49` | -| `examples/tasks/system.yaml` | `3dd9de88918f06e4b3a41232cb716a9e7d1c4b74ad18e71fd51644ae394ebf9c` | -| `soc/rpi/rp2350/rp2350.yaml` | `9e60e99ecac8782bccd69e3bd69014af1d8891d6b6fbd822acff5bd9a526d8cd` | -| `soc/rpi/rp2350/rp2350a.yaml` | `045cef7794c3b6c6d2ff48ba294c6308d00fe13bc65e346f2ba2ccde1cea24ff` | +| `boards/rpi/pico2_w/board.yaml` | `345279a53c444bc45e7fcc1a0cb5ab47b32a7699534f5484ea80d73f7a0bdf6d` | +| `drivers/bindings.yaml` | `c06d1a914adb21d0e314c79b3611ac6859eefeac1957d6914cccfc5531ad6ede` | +| `examples/tasks/system.yaml` | `202cff4815e97ab763dc14c61b0b694ee9381307eb46687f9caaea3465a913da` | +| `soc/rpi/rp2350/rp2350.yaml` | `80773a9c9cfb1c62cd322e397111a11d7f48fce3c0febc76bf7d5571018977a5` | +| `soc/rpi/rp2350/rp2350a.yaml` | `22395e35ed229020b5c9c7586af50cfaa07960a09905776eb4713ff28051eb3c` | diff --git a/examples/tasks/generated/pico2_w/docs/build_report.md b/examples/tasks/src/config/.base/pico2_w/docs/build_report.md similarity index 54% rename from examples/tasks/generated/pico2_w/docs/build_report.md rename to examples/tasks/src/config/.base/pico2_w/docs/build_report.md index eb1d7bfc..c94c0d83 100644 --- a/examples/tasks/generated/pico2_w/docs/build_report.md +++ b/examples/tasks/src/config/.base/pico2_w/docs/build_report.md @@ -4,6 +4,8 @@ xosc 12 MHz / M 1 = 12 MHz VCO input, x N 125 = 1500 MHz, / P 10 = 150 MHz. Given by the board, checked. +pll_usb: xosc 12 MHz / M 1 x N 64 = 768 MHz VCO, / 4 / 4 = 48 MHz. Solved; started by the drivers that use it. + | Bus | Frequency | Limit | |---|---|---| | sys | 150 MHz | 150 MHz | @@ -27,8 +29,8 @@ Generated by emb-hwgen 0.1.0, schema v0, from: | Input | SHA-256 | |---|---| | `arch/cortex_m/arch.yaml` | `c5c8e451c09717dee1713d07f8311b6d507e3b4c66c42d93e0ce11da6ec76d6d` | -| `boards/rpi/pico2_w/board.yaml` | `dad0ef7259e41ef3bd8fa07ea1c1f36040254a443deaf30d963b4fb14b5354a0` | -| `drivers/bindings.yaml` | `d3c336ac05548e0addd1faac18f3dff70576d8069f11d89e6a761cf5c6132b49` | -| `examples/tasks/system.yaml` | `3dd9de88918f06e4b3a41232cb716a9e7d1c4b74ad18e71fd51644ae394ebf9c` | -| `soc/rpi/rp2350/rp2350.yaml` | `9e60e99ecac8782bccd69e3bd69014af1d8891d6b6fbd822acff5bd9a526d8cd` | -| `soc/rpi/rp2350/rp2350a.yaml` | `045cef7794c3b6c6d2ff48ba294c6308d00fe13bc65e346f2ba2ccde1cea24ff` | +| `boards/rpi/pico2_w/board.yaml` | `345279a53c444bc45e7fcc1a0cb5ab47b32a7699534f5484ea80d73f7a0bdf6d` | +| `drivers/bindings.yaml` | `c06d1a914adb21d0e314c79b3611ac6859eefeac1957d6914cccfc5531ad6ede` | +| `examples/tasks/system.yaml` | `202cff4815e97ab763dc14c61b0b694ee9381307eb46687f9caaea3465a913da` | +| `soc/rpi/rp2350/rp2350.yaml` | `80773a9c9cfb1c62cd322e397111a11d7f48fce3c0febc76bf7d5571018977a5` | +| `soc/rpi/rp2350/rp2350a.yaml` | `22395e35ed229020b5c9c7586af50cfaa07960a09905776eb4713ff28051eb3c` | diff --git a/examples/tasks/generated/pico2_w/docs/hw.json b/examples/tasks/src/config/.base/pico2_w/docs/hw.json similarity index 67% rename from examples/tasks/generated/pico2_w/docs/hw.json rename to examples/tasks/src/config/.base/pico2_w/docs/hw.json index 9c355b27..d3926c90 100644 --- a/examples/tasks/generated/pico2_w/docs/hw.json +++ b/examples/tasks/src/config/.base/pico2_w/docs/hw.json @@ -103,6 +103,35 @@ ], "doc": "a spare UART, its writes by DMA; the HIL suite's loopback wires GPIO4 (pin 6) to GPIO5 (pin 7)", "name": "uart1" + }, + { + "doc": "TIMER1, 64 bits at 1 MHz: the counter class's (A129); TIMER0 is left for M4.4's tickless time", + "name": "timer1" + }, + { + "deps": [ + "io_bank0" + ], + "doc": "slice 7, PWM out on A, GPIO14 (pin 19); the HIL suite wires it to pin 22", + "name": "pwm7" + }, + { + "deps": [ + "io_bank0" + ], + "doc": "slice 0, PWM capture on B, GPIO17 (pin 22)", + "name": "pwm0" + }, + { + "deps": [ + "clocks", + "io_bank0" + ], + "dma": [ + "rx" + ], + "doc": "the ADC on clk_adc, 48 MHz from PLL_USB: GPIO26 (pin 31, input 0) and GPIO27 (pin 32, input 1); the HIL suite wires pin 31 to 3V3 OUT and pin 32 to AGND", + "name": "adc" } ], "doc": "The console on UART0 at 115200 baud on GPIO0 (TX, pin 1) and GPIO1 (RX, pin 2). The CPU runs at 150 MHz from PLL_SYS (the 12 MHz crystal x 125 / 5 / 2, pico-sdk's factors), and clk_peri, the UARTs' clock, follows clk_sys. The user LED is on the CYW43439 wireless chip, which has no driver yet, so the board has no LED. Images are UF2 files, copied to the boot ROM's USB drive (hold BOOTSEL while plugging in), or loaded by picotool while the board is in BOOTSEL; a test image built for the board (EMB_TEST_EMULATOR=hil) reboots into BOOTSEL when it ends, so tools/hil/run_hil.py loads the next one without the button.", @@ -127,6 +156,10 @@ } }, "pins": { + "adc": { + "in0": "GPIO26", + "in1": "GPIO27" + }, "i2c0": { "scl": "GPIO9.f3", "sda": "GPIO8.f3" @@ -135,6 +168,12 @@ "scl": "GPIO7.f3", "sda": "GPIO6.f3" }, + "pwm0": { + "b": "GPIO17.f4" + }, + "pwm7": { + "a": "GPIO14.f4" + }, "spi1": { "miso": "GPIO12.f1", "mosi": "GPIO11.f1", @@ -168,8 +207,24 @@ "bus_hz": { "sys": 150000000 }, + "bus_timer_hz": { + "sys": 150000000 + }, "bypass": false, "cpu_hz": 150000000, + "fixed_plls": { + "pll_usb": { + "hz": 48000000, + "m": 1, + "n": 64, + "name": "pll_usb", + "p": 16, + "postdiv1": 4, + "postdiv2": 4, + "vco_hz": 768000000, + "vco_in_hz": 12000000 + } + }, "hclk_hz": 150000000, "pll": { "m": 1, @@ -414,6 +469,78 @@ "level": "kernel", "name": "i2c1", "peripheral": "i2c1" + }, + { + "class": "counter", + "compatible": "rpi,rp2350-timer", + "deps": [], + "fields": { + "base": 1074495488, + "index": 1, + "irq0": 4, + "irq1": 5, + "irq2": 6, + "irq3": 7, + "rate_hz": 1000000 + }, + "level": "kernel", + "name": "timer1", + "peripheral": "timer1" + }, + { + "class": "pwm", + "compatible": "rpi,rp2350-pwm", + "deps": [ + "io_bank0" + ], + "fields": { + "base": 1074430092, + "clock_hz": 150000000, + "index": 7 + }, + "level": "kernel", + "name": "pwm7", + "peripheral": "pwm7" + }, + { + "class": "pwm", + "compatible": "rpi,rp2350-pwm", + "deps": [ + "io_bank0" + ], + "fields": { + "base": 1074429952, + "clock_hz": 150000000, + "index": 0 + }, + "level": "kernel", + "name": "pwm0", + "peripheral": "pwm0" + }, + { + "class": "adc", + "compatible": "rpi,rp2350-adc", + "deps": [ + "clocks", + "io_bank0", + "dma" + ], + "fields": { + "base": 1074397184, + "bits": 12, + "clock_hz": 48000000, + "dma_rx": { + "dma": "dma", + "request": 48, + "stream": 3 + }, + "inputs": 4, + "temperature": 4, + "vref_mv": 3300 + }, + "level": "kernel", + "name": "adc", + "peripheral": "adc" } ], "kconfig": { @@ -578,6 +705,44 @@ "pin": "GPIO13", "port": "", "signal": "spi1_cs0" + }, + { + "af": 4, + "gpio": "io_bank0", + "mode": "af", + "number": 14, + "owner": "pins.pwm7.a", + "pin": "GPIO14", + "port": "", + "signal": "pwm7_a" + }, + { + "af": 4, + "gpio": "io_bank0", + "mode": "af", + "number": 17, + "owner": "pins.pwm0.b", + "pin": "GPIO17", + "port": "", + "signal": "pwm0_b" + }, + { + "gpio": "io_bank0", + "mode": "analog", + "number": 26, + "owner": "pins.adc.in0", + "pin": "GPIO26", + "port": "", + "signal": "adc_in0" + }, + { + "gpio": "io_bank0", + "mode": "analog", + "number": 27, + "owner": "pins.adc.in1", + "pin": "GPIO27", + "port": "", + "signal": "adc_in1" } ], "profile": "base", @@ -601,124 +766,158 @@ }, { "path": "boards/rpi/pico2_w/board.yaml", - "sha256": "dad0ef7259e41ef3bd8fa07ea1c1f36040254a443deaf30d963b4fb14b5354a0" + "sha256": "345279a53c444bc45e7fcc1a0cb5ab47b32a7699534f5484ea80d73f7a0bdf6d" }, { "path": "drivers/bindings.yaml", - "sha256": "d3c336ac05548e0addd1faac18f3dff70576d8069f11d89e6a761cf5c6132b49" + "sha256": "c06d1a914adb21d0e314c79b3611ac6859eefeac1957d6914cccfc5531ad6ede" }, { "path": "examples/tasks/system.yaml", - "sha256": "3dd9de88918f06e4b3a41232cb716a9e7d1c4b74ad18e71fd51644ae394ebf9c" + "sha256": "202cff4815e97ab763dc14c61b0b694ee9381307eb46687f9caaea3465a913da" }, { "path": "soc/rpi/rp2350/rp2350.yaml", - "sha256": "9e60e99ecac8782bccd69e3bd69014af1d8891d6b6fbd822acff5bd9a526d8cd" + "sha256": "80773a9c9cfb1c62cd322e397111a11d7f48fce3c0febc76bf7d5571018977a5" }, { "path": "soc/rpi/rp2350/rp2350a.yaml", - "sha256": "045cef7794c3b6c6d2ff48ba294c6308d00fe13bc65e346f2ba2ccde1cea24ff" + "sha256": "22395e35ed229020b5c9c7586af50cfaa07960a09905776eb4713ff28051eb3c" } ], "schema_version": 0, "soc": { "alternate_functions": { "GPIO0": { - "f2": "uart0_tx" + "f2": "uart0_tx", + "f4": "pwm0_a" }, "GPIO1": { - "f2": "uart0_rx" + "f2": "uart0_rx", + "f4": "pwm0_b" }, "GPIO10": { "f1": "spi1_sck", - "f11": "uart1_tx" + "f11": "uart1_tx", + "f4": "pwm5_a" }, "GPIO11": { "f1": "spi1_mosi", - "f11": "uart1_rx" + "f11": "uart1_rx", + "f4": "pwm5_b" }, "GPIO12": { "f1": "spi1_miso", - "f2": "uart0_tx" + "f2": "uart0_tx", + "f4": "pwm6_a" }, "GPIO13": { - "f2": "uart0_rx" + "f2": "uart0_rx", + "f4": "pwm6_b" }, "GPIO14": { - "f11": "uart0_tx" + "f11": "uart0_tx", + "f4": "pwm7_a" }, "GPIO15": { - "f11": "uart0_rx" + "f11": "uart0_rx", + "f4": "pwm7_b" }, "GPIO16": { - "f2": "uart0_tx" + "f2": "uart0_tx", + "f4": "pwm0_a" }, "GPIO17": { - "f2": "uart0_rx" + "f2": "uart0_rx", + "f4": "pwm0_b" }, "GPIO18": { - "f11": "uart0_tx" + "f11": "uart0_tx", + "f4": "pwm1_a" }, "GPIO19": { - "f11": "uart0_rx" + "f11": "uart0_rx", + "f4": "pwm1_b" }, "GPIO2": { - "f11": "uart0_tx" + "f11": "uart0_tx", + "f4": "pwm1_a" }, "GPIO20": { - "f2": "uart1_tx" + "f2": "uart1_tx", + "f4": "pwm2_a" }, "GPIO21": { - "f2": "uart1_rx" + "f2": "uart1_rx", + "f4": "pwm2_b" }, "GPIO22": { - "f11": "uart1_tx" + "f11": "uart1_tx", + "f4": "pwm3_a" }, "GPIO23": { - "f11": "uart1_rx" + "f11": "uart1_rx", + "f4": "pwm3_b" }, "GPIO24": { - "f2": "uart1_tx" + "f2": "uart1_tx", + "f4": "pwm4_a" }, "GPIO25": { - "f2": "uart1_rx" + "f2": "uart1_rx", + "f4": "pwm4_b" }, "GPIO26": { - "f11": "uart1_tx" + "analog": "adc_in0", + "f11": "uart1_tx", + "f4": "pwm5_a" }, "GPIO27": { - "f11": "uart1_rx" + "analog": "adc_in1", + "f11": "uart1_rx", + "f4": "pwm5_b" }, "GPIO28": { - "f2": "uart0_tx" + "analog": "adc_in2", + "f2": "uart0_tx", + "f4": "pwm6_a" }, "GPIO29": { - "f2": "uart0_rx" + "analog": "adc_in3", + "f2": "uart0_rx", + "f4": "pwm6_b" }, "GPIO3": { - "f11": "uart0_rx" + "f11": "uart0_rx", + "f4": "pwm1_b" }, "GPIO4": { - "f2": "uart1_tx" + "f2": "uart1_tx", + "f4": "pwm2_a" }, "GPIO5": { - "f2": "uart1_rx" + "f2": "uart1_rx", + "f4": "pwm2_b" }, "GPIO6": { "f11": "uart1_tx", - "f3": "i2c1_sda" + "f3": "i2c1_sda", + "f4": "pwm3_a" }, "GPIO7": { "f11": "uart1_rx", - "f3": "i2c1_scl" + "f3": "i2c1_scl", + "f4": "pwm3_b" }, "GPIO8": { "f2": "uart1_tx", - "f3": "i2c0_sda" + "f3": "i2c0_sda", + "f4": "pwm4_a" }, "GPIO9": { "f2": "uart1_rx", - "f3": "i2c0_scl" + "f3": "i2c0_scl", + "f4": "pwm4_b" } }, "arch": { @@ -764,6 +963,33 @@ 750000000, 1600000000 ] + }, + { + "inputs": [ + "xosc" + ], + "m": [ + 1, + 63 + ], + "n": [ + 16, + 320 + ], + "name": "pll_usb", + "output_hz": 48000000, + "postdiv": [ + 1, + 7 + ], + "vco_in_hz": [ + 5000000, + 800000000 + ], + "vco_out_hz": [ + 750000000, + 1600000000 + ] } ], "sources": [ @@ -912,6 +1138,12 @@ "name": "pll_sys", "size": 16384 }, + { + "base": 1074102272, + "compatible": "rpi,rp2350-pll", + "name": "pll_usb", + "size": 16384 + }, { "base": 1074200576, "compatible": "arm,pl011", @@ -1097,6 +1329,213 @@ "compatible": "rpi,rp2350-sio", "name": "sio", "size": 4096 + }, + { + "adc": { + "bits": 12, + "inputs": 4, + "temperature": 4 + }, + "base": 1074397184, + "clocked_by": "pll_usb", + "compatible": "rpi,rp2350-adc", + "dma_requests": { + "rx": "dma.dreq48" + }, + "irqs": [ + { + "name": "fifo", + "number": 35 + } + ], + "name": "adc", + "size": 16384 + }, + { + "base": 1074430192, + "compatible": "rpi,rp2350-pwm-irq", + "irqs": [ + { + "name": "wrap0", + "number": 8 + }, + { + "name": "wrap1", + "number": 9 + } + ], + "name": "pwm", + "size": 32 + }, + { + "base": 1074429952, + "compatible": "rpi,rp2350-pwm", + "counter_bits": 16, + "dma_requests": { + "wrap": "dma.dreq32" + }, + "name": "pwm0", + "size": 20 + }, + { + "base": 1074429972, + "compatible": "rpi,rp2350-pwm", + "counter_bits": 16, + "dma_requests": { + "wrap": "dma.dreq33" + }, + "name": "pwm1", + "size": 20 + }, + { + "base": 1074429992, + "compatible": "rpi,rp2350-pwm", + "counter_bits": 16, + "dma_requests": { + "wrap": "dma.dreq34" + }, + "name": "pwm2", + "size": 20 + }, + { + "base": 1074430012, + "compatible": "rpi,rp2350-pwm", + "counter_bits": 16, + "dma_requests": { + "wrap": "dma.dreq35" + }, + "name": "pwm3", + "size": 20 + }, + { + "base": 1074430032, + "compatible": "rpi,rp2350-pwm", + "counter_bits": 16, + "dma_requests": { + "wrap": "dma.dreq36" + }, + "name": "pwm4", + "size": 20 + }, + { + "base": 1074430052, + "compatible": "rpi,rp2350-pwm", + "counter_bits": 16, + "dma_requests": { + "wrap": "dma.dreq37" + }, + "name": "pwm5", + "size": 20 + }, + { + "base": 1074430072, + "compatible": "rpi,rp2350-pwm", + "counter_bits": 16, + "dma_requests": { + "wrap": "dma.dreq38" + }, + "name": "pwm6", + "size": 20 + }, + { + "base": 1074430092, + "compatible": "rpi,rp2350-pwm", + "counter_bits": 16, + "dma_requests": { + "wrap": "dma.dreq39" + }, + "name": "pwm7", + "size": 20 + }, + { + "base": 1074430112, + "compatible": "rpi,rp2350-pwm", + "counter_bits": 16, + "dma_requests": { + "wrap": "dma.dreq40" + }, + "name": "pwm8", + "size": 20 + }, + { + "base": 1074430132, + "compatible": "rpi,rp2350-pwm", + "counter_bits": 16, + "dma_requests": { + "wrap": "dma.dreq41" + }, + "name": "pwm9", + "size": 20 + }, + { + "base": 1074430152, + "compatible": "rpi,rp2350-pwm", + "counter_bits": 16, + "dma_requests": { + "wrap": "dma.dreq42" + }, + "name": "pwm10", + "size": 20 + }, + { + "base": 1074430172, + "compatible": "rpi,rp2350-pwm", + "counter_bits": 16, + "dma_requests": { + "wrap": "dma.dreq43" + }, + "name": "pwm11", + "size": 20 + }, + { + "base": 1074462720, + "compatible": "rpi,rp2350-timer", + "counter_bits": 64, + "irqs": [ + { + "name": "alarm0", + "number": 0 + }, + { + "name": "alarm1", + "number": 1 + }, + { + "name": "alarm2", + "number": 2 + }, + { + "name": "alarm3", + "number": 3 + } + ], + "name": "timer0", + "size": 16384 + }, + { + "base": 1074495488, + "compatible": "rpi,rp2350-timer", + "counter_bits": 64, + "irqs": [ + { + "name": "alarm0", + "number": 4 + }, + { + "name": "alarm1", + "number": 5 + }, + { + "name": "alarm2", + "number": 6 + }, + { + "name": "alarm3", + "number": 7 + } + ], + "name": "timer1", + "size": 16384 } ], "schema_version": 0, diff --git a/examples/tasks/generated/.base/pico2_w/docs/system.json b/examples/tasks/src/config/.base/pico2_w/docs/system.json similarity index 75% rename from examples/tasks/generated/.base/pico2_w/docs/system.json rename to examples/tasks/src/config/.base/pico2_w/docs/system.json index 40bd8a2a..76b805df 100644 --- a/examples/tasks/generated/.base/pico2_w/docs/system.json +++ b/examples/tasks/src/config/.base/pico2_w/docs/system.json @@ -25,23 +25,33 @@ }, { "path": "boards/rpi/pico2_w/board.yaml", - "sha256": "dad0ef7259e41ef3bd8fa07ea1c1f36040254a443deaf30d963b4fb14b5354a0" + "sha256": "345279a53c444bc45e7fcc1a0cb5ab47b32a7699534f5484ea80d73f7a0bdf6d" }, { "path": "drivers/bindings.yaml", - "sha256": "d3c336ac05548e0addd1faac18f3dff70576d8069f11d89e6a761cf5c6132b49" + "sha256": "c06d1a914adb21d0e314c79b3611ac6859eefeac1957d6914cccfc5531ad6ede" }, { "path": "examples/tasks/system.yaml", - "sha256": "3dd9de88918f06e4b3a41232cb716a9e7d1c4b74ad18e71fd51644ae394ebf9c" + "sha256": "202cff4815e97ab763dc14c61b0b694ee9381307eb46687f9caaea3465a913da" }, { "path": "soc/rpi/rp2350/rp2350.yaml", - "sha256": "9e60e99ecac8782bccd69e3bd69014af1d8891d6b6fbd822acff5bd9a526d8cd" + "sha256": "80773a9c9cfb1c62cd322e397111a11d7f48fce3c0febc76bf7d5571018977a5" }, { "path": "soc/rpi/rp2350/rp2350a.yaml", - "sha256": "045cef7794c3b6c6d2ff48ba294c6308d00fe13bc65e346f2ba2ccde1cea24ff" + "sha256": "22395e35ed229020b5c9c7586af50cfaa07960a09905776eb4713ff28051eb3c" + } + ], + "interrupts": [ + { + "doc": "", + "handler": "WAKE_InterruptHandler", + "irq": 46, + "level": 1, + "name": "wake", + "source": null } ], "name": "tasks_demo", @@ -52,7 +62,6 @@ "spi_targets": [], "tasks": [ { - "data": "door_data_t", "doc": "", "entry": [ "open" @@ -83,7 +92,6 @@ } }, { - "data": null, "doc": "", "entry": [], "event": null, diff --git a/examples/tasks/src/config/.base/pico2_w/docs/system.md b/examples/tasks/src/config/.base/pico2_w/docs/system.md new file mode 100644 index 00000000..af25c2e2 --- /dev/null +++ b/examples/tasks/src/config/.base/pico2_w/docs/system.md @@ -0,0 +1,29 @@ +# tasks_demo: the system on pico2_w + +Generated from `examples/tasks/system.yaml` (SPEC-014 §5, A125, A130). Profile base, 32 priorities, a minimum stack of 256 bytes. + +## Tasks + +| Task | Model | Priority | Stack | States (initial first) | Events | +|---|---|---|---|---|---| +| `door` | event, queue 8 | 5 | 1024 | closed, open, jammed | open, close, jam | +| `blink` | periodic, 500 ms | 2 | 512 | dark, lit | — | + +## Interrupts + +| Interrupt | Line | Handler | Level | +|---|---|---|---| +| `wake` | 46 | `WAKE_InterruptHandler` | 1 | + +--- + +Generated by emb-hwgen 0.1.0, schema v0, from: + +| Input | SHA-256 | +|---|---| +| `arch/cortex_m/arch.yaml` | `c5c8e451c09717dee1713d07f8311b6d507e3b4c66c42d93e0ce11da6ec76d6d` | +| `boards/rpi/pico2_w/board.yaml` | `345279a53c444bc45e7fcc1a0cb5ab47b32a7699534f5484ea80d73f7a0bdf6d` | +| `drivers/bindings.yaml` | `c06d1a914adb21d0e314c79b3611ac6859eefeac1957d6914cccfc5531ad6ede` | +| `examples/tasks/system.yaml` | `202cff4815e97ab763dc14c61b0b694ee9381307eb46687f9caaea3465a913da` | +| `soc/rpi/rp2350/rp2350.yaml` | `80773a9c9cfb1c62cd322e397111a11d7f48fce3c0febc76bf7d5571018977a5` | +| `soc/rpi/rp2350/rp2350a.yaml` | `22395e35ed229020b5c9c7586af50cfaa07960a09905776eb4713ff28051eb3c` | diff --git a/examples/tasks/src/config/.base/pico2_w/initialization.c b/examples/tasks/src/config/.base/pico2_w/initialization.c new file mode 100644 index 00000000..9f7d62fd --- /dev/null +++ b/examples/tasks/src/config/.base/pico2_w/initialization.c @@ -0,0 +1,82 @@ +/* SPDX-License-Identifier: Apache-2.0 */ +/* + * This file is part of EmbLinkRTOS, a deterministic real-time kernel for microcontrollers. + * Licensed under the Apache License, Version 2.0; see the LICENSE file at the repository root. + */ + +/******************************************************************************* + System Initialization File + + File Name: + initialization.c + + Summary: + tasks_demo's initialization on the pico2_w: SYS_Initialize(), and the + system's objects. + + Description: + The system's static definitions, which the kernel creates from its + initialization table when emb_kernel_init() runs (SPEC-001 §6.4), and + SYS_Initialize(), which brings up the board, the kernel, the application's + interrupts and the tasks. + + Generated by emb-hwgen 0.1.0, schema v0, from the system description and the + pico2_w's. Yours to edit: regenerating merges its changes with yours (A126): + hw/gen/emb-hwgen.py generate --system examples/tasks/system.yaml + + Inputs (SHA-256): + arch/cortex_m/arch.yaml + c5c8e451c09717dee1713d07f8311b6d507e3b4c66c42d93e0ce11da6ec76d6d + boards/rpi/pico2_w/board.yaml + 345279a53c444bc45e7fcc1a0cb5ab47b32a7699534f5484ea80d73f7a0bdf6d + drivers/bindings.yaml + c06d1a914adb21d0e314c79b3611ac6859eefeac1957d6914cccfc5531ad6ede + examples/tasks/system.yaml + 202cff4815e97ab763dc14c61b0b694ee9381307eb46687f9caaea3465a913da + soc/rpi/rp2350/rp2350.yaml + 80773a9c9cfb1c62cd322e397111a11d7f48fce3c0febc76bf7d5571018977a5 + soc/rpi/rp2350/rp2350a.yaml + 22395e35ed229020b5c9c7586af50cfaa07960a09905776eb4713ff28051eb3c + *******************************************************************************/ + +// ***************************************************************************** +// ***************************************************************************** +// Section: Included Files +// ***************************************************************************** +// ***************************************************************************** + +#include "definitions.h" + +// ***************************************************************************** +// ***************************************************************************** +// Section: System Initialization +// ***************************************************************************** +// ***************************************************************************** + +/******************************************************************************* + Function: + void SYS_Initialize ( void *data ) + + Remarks: + See prototype in definitions.h. + */ +void SYS_Initialize(void *data) +{ + (void)data; + + /* The board: its clocks, pins and console */ + emb_board_init(); + + /* The kernel: its objects, and the EARLY devices */ + emb_kernel_init(); + + /* The application's interrupts */ + SYS_INT_Initialize(); + + /* The tasks, each in its initial state */ + DOOR_Initialize(); + BLINK_Initialize(); +} +/******************************************************************************* + End of File +*/ diff --git a/examples/tasks/src/config/.base/pico2_w/interrupts.c b/examples/tasks/src/config/.base/pico2_w/interrupts.c new file mode 100644 index 00000000..f4ddfbd1 --- /dev/null +++ b/examples/tasks/src/config/.base/pico2_w/interrupts.c @@ -0,0 +1,94 @@ +/* SPDX-License-Identifier: Apache-2.0 */ +/* + * This file is part of EmbLinkRTOS, a deterministic real-time kernel for microcontrollers. + * Licensed under the Apache License, Version 2.0; see the LICENSE file at the repository root. + */ + +/******************************************************************************* + Interrupt Handlers + + File Name: + interrupts.c + + Summary: + tasks_demo's interrupts on the pico2_w: the lines in use, and + SYS_INT_Initialize(). + + Description: + The table of every interrupt line in use, the devices' and the + application's, and SYS_INT_Initialize(), which connects the application's + handlers. The checks were made when it was generated: each line is the + SoC's, no device's driver connects it, and its level is the port's. + + Generated by emb-hwgen 0.1.0, schema v0, from the system description and the + pico2_w's. Yours to edit: regenerating merges its changes with yours (A126): + hw/gen/emb-hwgen.py generate --system examples/tasks/system.yaml + + Inputs (SHA-256): + arch/cortex_m/arch.yaml + c5c8e451c09717dee1713d07f8311b6d507e3b4c66c42d93e0ce11da6ec76d6d + boards/rpi/pico2_w/board.yaml + 345279a53c444bc45e7fcc1a0cb5ab47b32a7699534f5484ea80d73f7a0bdf6d + drivers/bindings.yaml + c06d1a914adb21d0e314c79b3611ac6859eefeac1957d6914cccfc5531ad6ede + examples/tasks/system.yaml + 202cff4815e97ab763dc14c61b0b694ee9381307eb46687f9caaea3465a913da + soc/rpi/rp2350/rp2350.yaml + 80773a9c9cfb1c62cd322e397111a11d7f48fce3c0febc76bf7d5571018977a5 + soc/rpi/rp2350/rp2350a.yaml + 22395e35ed229020b5c9c7586af50cfaa07960a09905776eb4713ff28051eb3c + *******************************************************************************/ + +// ***************************************************************************** +// ***************************************************************************** +// Section: Included Files +// ***************************************************************************** +// ***************************************************************************** + +#include "definitions.h" + +// ***************************************************************************** +// ***************************************************************************** +// Section: Interrupt Lines +// ***************************************************************************** +// ***************************************************************************** + +/* The lines in use on the pico2_w: + * 4 timer1, its driver (peripheral.irqs.alarm0) + * 5 timer1, its driver (peripheral.irqs.alarm1) + * 6 timer1, its driver (peripheral.irqs.alarm2) + * 7 timer1, its driver (peripheral.irqs.alarm3) + * 10 dma, its driver (peripheral.irqs.irq0) + * 32 spi1, its driver (peripheral.irqs.global) + * 33 uart0, its driver (peripheral.irqs.global) + * 34 uart1, its driver (peripheral.irqs.global) + * 36 i2c0, its driver (peripheral.irqs.global) + * 37 i2c1, its driver (peripheral.irqs.global) + * 39 trng, its driver (peripheral.irqs.irq) + * 45 rtc, its driver (peripheral.irqs.timer) + * 46 wake, the application's WAKE_InterruptHandler() + */ + +// ***************************************************************************** +// ***************************************************************************** +// Section: Interrupt Initialization +// ***************************************************************************** +// ***************************************************************************** + +/******************************************************************************* + Function: + void SYS_INT_Initialize ( void ) + + Remarks: + See prototype in interrupts.h. + */ +void SYS_INT_Initialize(void) +{ + /* wake: line 46 */ + (void)emb_irq_connect(WAKE_IRQ, WAKE_InterruptHandler, NULL); + (void)emb_irq_set_level(WAKE_IRQ, WAKE_IRQ_LEVEL); + (void)emb_irq_enable(WAKE_IRQ); +} +/******************************************************************************* + End of File +*/ diff --git a/examples/tasks/src/config/.base/pico2_w/interrupts.h b/examples/tasks/src/config/.base/pico2_w/interrupts.h new file mode 100644 index 00000000..f36963b4 --- /dev/null +++ b/examples/tasks/src/config/.base/pico2_w/interrupts.h @@ -0,0 +1,130 @@ +/* SPDX-License-Identifier: Apache-2.0 */ +/* + * This file is part of EmbLinkRTOS, a deterministic real-time kernel for microcontrollers. + * Licensed under the Apache License, Version 2.0; see the LICENSE file at the repository root. + */ + +/******************************************************************************* + Interrupt Handlers + + File Name: + interrupts.h + + Summary: + tasks_demo's interrupt handlers on the pico2_w. + + Description: + The application's own interrupt handlers, which it defines + (src/interrupt_handlers.c), and SYS_INT_Initialize(), which connects each at + its level and enables it. The board's devices connect their own: + interrupts.c lists every line in use. + + Generated by emb-hwgen 0.1.0, schema v0, from the system description and the + pico2_w's. Yours to edit: regenerating merges its changes with yours (A126): + hw/gen/emb-hwgen.py generate --system examples/tasks/system.yaml + + Inputs (SHA-256): + arch/cortex_m/arch.yaml + c5c8e451c09717dee1713d07f8311b6d507e3b4c66c42d93e0ce11da6ec76d6d + boards/rpi/pico2_w/board.yaml + 345279a53c444bc45e7fcc1a0cb5ab47b32a7699534f5484ea80d73f7a0bdf6d + drivers/bindings.yaml + c06d1a914adb21d0e314c79b3611ac6859eefeac1957d6914cccfc5531ad6ede + examples/tasks/system.yaml + 202cff4815e97ab763dc14c61b0b694ee9381307eb46687f9caaea3465a913da + soc/rpi/rp2350/rp2350.yaml + 80773a9c9cfb1c62cd322e397111a11d7f48fce3c0febc76bf7d5571018977a5 + soc/rpi/rp2350/rp2350a.yaml + 22395e35ed229020b5c9c7586af50cfaa07960a09905776eb4713ff28051eb3c + *******************************************************************************/ + +#ifndef INTERRUPTS_H +#define INTERRUPTS_H + +// ***************************************************************************** +// ***************************************************************************** +// Section: Included Files +// ***************************************************************************** +// ***************************************************************************** + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +// ***************************************************************************** +// ***************************************************************************** +// Section: Handler Routines +// ***************************************************************************** +// ***************************************************************************** + +/******************************************************************************* + Function: + void WAKE_InterruptHandler ( void *arg ) + + Summary: + The wake interrupt's handler. + + Description: + This function runs in interrupt context when line 46 is raised at level 1: a + kernel-aware handler, which may post to a task (emb_task_post()) but not + wait. + + Precondition: + SYS_INT_Initialize() has connected it. + + Parameters: + arg - Unused; NULL. + + Returns: + None. + + Example: + + emb_irq_pend(WAKE_IRQ); + + + Remarks: + The application defines it. Keep it short: hand the work to a task. +*/ +void WAKE_InterruptHandler(void *arg); + +/******************************************************************************* + Function: + void SYS_INT_Initialize ( void ) + + Summary: + Connects the application's interrupt handlers. + + Description: + This function connects each of the application's handlers to its line, sets + its level and enables it. + + Precondition: + The kernel is initialized (emb_kernel_init()). + + Parameters: + None. + + Returns: + None. + + Example: + + SYS_INT_Initialize(); + + + Remarks: + SYS_Initialize() calls it. +*/ +void SYS_INT_Initialize(void); + +#ifdef __cplusplus +} +#endif + +#endif /* INTERRUPTS_H */ +/******************************************************************************* + End of File +*/ diff --git a/examples/tasks/generated/.base/pico2_w/linker/regions.ld b/examples/tasks/src/config/.base/pico2_w/linker/regions.ld similarity index 90% rename from examples/tasks/generated/.base/pico2_w/linker/regions.ld rename to examples/tasks/src/config/.base/pico2_w/linker/regions.ld index bb8a8d44..49f1e7d0 100644 --- a/examples/tasks/generated/.base/pico2_w/linker/regions.ld +++ b/examples/tasks/src/config/.base/pico2_w/linker/regions.ld @@ -16,15 +16,15 @@ * arch/cortex_m/arch.yaml * c5c8e451c09717dee1713d07f8311b6d507e3b4c66c42d93e0ce11da6ec76d6d * boards/rpi/pico2_w/board.yaml - * dad0ef7259e41ef3bd8fa07ea1c1f36040254a443deaf30d963b4fb14b5354a0 + * 345279a53c444bc45e7fcc1a0cb5ab47b32a7699534f5484ea80d73f7a0bdf6d * drivers/bindings.yaml - * d3c336ac05548e0addd1faac18f3dff70576d8069f11d89e6a761cf5c6132b49 + * c06d1a914adb21d0e314c79b3611ac6859eefeac1957d6914cccfc5531ad6ede * examples/tasks/system.yaml - * 3dd9de88918f06e4b3a41232cb716a9e7d1c4b74ad18e71fd51644ae394ebf9c + * 202cff4815e97ab763dc14c61b0b694ee9381307eb46687f9caaea3465a913da * soc/rpi/rp2350/rp2350.yaml - * 9e60e99ecac8782bccd69e3bd69014af1d8891d6b6fbd822acff5bd9a526d8cd + * 80773a9c9cfb1c62cd322e397111a11d7f48fce3c0febc76bf7d5571018977a5 * soc/rpi/rp2350/rp2350a.yaml - * 045cef7794c3b6c6d2ff48ba294c6308d00fe13bc65e346f2ba2ccde1cea24ff + * 22395e35ed229020b5c9c7586af50cfaa07960a09905776eb4713ff28051eb3c */ ENTRY(embn_cm_reset) diff --git a/examples/tasks/generated/pico2_w/src/board_pins.c b/examples/tasks/src/config/.base/pico2_w/peripheral/board_pins.c similarity index 76% rename from examples/tasks/generated/pico2_w/src/board_pins.c rename to examples/tasks/src/config/.base/pico2_w/peripheral/board_pins.c index 6dcaebc6..dd5fde39 100644 --- a/examples/tasks/generated/pico2_w/src/board_pins.c +++ b/examples/tasks/src/config/.base/pico2_w/peripheral/board_pins.c @@ -18,15 +18,15 @@ * arch/cortex_m/arch.yaml * c5c8e451c09717dee1713d07f8311b6d507e3b4c66c42d93e0ce11da6ec76d6d * boards/rpi/pico2_w/board.yaml - * dad0ef7259e41ef3bd8fa07ea1c1f36040254a443deaf30d963b4fb14b5354a0 + * 345279a53c444bc45e7fcc1a0cb5ab47b32a7699534f5484ea80d73f7a0bdf6d * drivers/bindings.yaml - * d3c336ac05548e0addd1faac18f3dff70576d8069f11d89e6a761cf5c6132b49 + * c06d1a914adb21d0e314c79b3611ac6859eefeac1957d6914cccfc5531ad6ede * examples/tasks/system.yaml - * 3dd9de88918f06e4b3a41232cb716a9e7d1c4b74ad18e71fd51644ae394ebf9c + * 202cff4815e97ab763dc14c61b0b694ee9381307eb46687f9caaea3465a913da * soc/rpi/rp2350/rp2350.yaml - * 9e60e99ecac8782bccd69e3bd69014af1d8891d6b6fbd822acff5bd9a526d8cd + * 80773a9c9cfb1c62cd322e397111a11d7f48fce3c0febc76bf7d5571018977a5 * soc/rpi/rp2350/rp2350a.yaml - * 045cef7794c3b6c6d2ff48ba294c6308d00fe13bc65e346f2ba2ccde1cea24ff + * 22395e35ed229020b5c9c7586af50cfaa07960a09905776eb4713ff28051eb3c */ #include #include @@ -56,6 +56,14 @@ const emb_rp2350_pin_t emb_board_pins[] = { {12u, 1u, 1u, EMB_RP2350_PULL_RESET, EMB_RP2350_OUT_NONE}, /* GPIO13: devices.spi1.cs[0] (spi1_cs0) */ {13u, 5u, 1u, EMB_RP2350_PULL_RESET, EMB_RP2350_OUT_HIGH}, + /* GPIO14: pins.pwm7.a (pwm7_a) */ + {14u, 4u, 1u, EMB_RP2350_PULL_RESET, EMB_RP2350_OUT_NONE}, + /* GPIO17: pins.pwm0.b (pwm0_b) */ + {17u, 4u, 1u, EMB_RP2350_PULL_RESET, EMB_RP2350_OUT_NONE}, + /* GPIO26: pins.adc.in0 (adc_in0) */ + {26u, 31u, 0u, EMB_RP2350_PULL_NONE, EMB_RP2350_OUT_NONE}, + /* GPIO27: pins.adc.in1 (adc_in1) */ + {27u, 31u, 0u, EMB_RP2350_PULL_NONE, EMB_RP2350_OUT_NONE}, }; const unsigned emb_board_pin_count = (unsigned)(sizeof(emb_board_pins) / sizeof(emb_board_pins[0])); diff --git a/examples/tasks/generated/pico2_w/src/boot_block.c b/examples/tasks/src/config/.base/pico2_w/peripheral/boot_block.c similarity index 77% rename from examples/tasks/generated/pico2_w/src/boot_block.c rename to examples/tasks/src/config/.base/pico2_w/peripheral/boot_block.c index 10766db0..f0932ecd 100644 --- a/examples/tasks/generated/pico2_w/src/boot_block.c +++ b/examples/tasks/src/config/.base/pico2_w/peripheral/boot_block.c @@ -15,15 +15,15 @@ * arch/cortex_m/arch.yaml * c5c8e451c09717dee1713d07f8311b6d507e3b4c66c42d93e0ce11da6ec76d6d * boards/rpi/pico2_w/board.yaml - * dad0ef7259e41ef3bd8fa07ea1c1f36040254a443deaf30d963b4fb14b5354a0 + * 345279a53c444bc45e7fcc1a0cb5ab47b32a7699534f5484ea80d73f7a0bdf6d * drivers/bindings.yaml - * d3c336ac05548e0addd1faac18f3dff70576d8069f11d89e6a761cf5c6132b49 + * c06d1a914adb21d0e314c79b3611ac6859eefeac1957d6914cccfc5531ad6ede * examples/tasks/system.yaml - * 3dd9de88918f06e4b3a41232cb716a9e7d1c4b74ad18e71fd51644ae394ebf9c + * 202cff4815e97ab763dc14c61b0b694ee9381307eb46687f9caaea3465a913da * soc/rpi/rp2350/rp2350.yaml - * 9e60e99ecac8782bccd69e3bd69014af1d8891d6b6fbd822acff5bd9a526d8cd + * 80773a9c9cfb1c62cd322e397111a11d7f48fce3c0febc76bf7d5571018977a5 * soc/rpi/rp2350/rp2350a.yaml - * 045cef7794c3b6c6d2ff48ba294c6308d00fe13bc65e346f2ba2ccde1cea24ff + * 22395e35ed229020b5c9c7586af50cfaa07960a09905776eb4713ff28051eb3c */ #include diff --git a/examples/tasks/generated/pico2_w/include/hw_config.h b/examples/tasks/src/config/.base/pico2_w/peripheral/hw_config.h similarity index 60% rename from examples/tasks/generated/pico2_w/include/hw_config.h rename to examples/tasks/src/config/.base/pico2_w/peripheral/hw_config.h index 724d5355..a2fe180e 100644 --- a/examples/tasks/generated/pico2_w/include/hw_config.h +++ b/examples/tasks/src/config/.base/pico2_w/peripheral/hw_config.h @@ -15,15 +15,15 @@ * arch/cortex_m/arch.yaml * c5c8e451c09717dee1713d07f8311b6d507e3b4c66c42d93e0ce11da6ec76d6d * boards/rpi/pico2_w/board.yaml - * dad0ef7259e41ef3bd8fa07ea1c1f36040254a443deaf30d963b4fb14b5354a0 + * 345279a53c444bc45e7fcc1a0cb5ab47b32a7699534f5484ea80d73f7a0bdf6d * drivers/bindings.yaml - * d3c336ac05548e0addd1faac18f3dff70576d8069f11d89e6a761cf5c6132b49 + * c06d1a914adb21d0e314c79b3611ac6859eefeac1957d6914cccfc5531ad6ede * examples/tasks/system.yaml - * 3dd9de88918f06e4b3a41232cb716a9e7d1c4b74ad18e71fd51644ae394ebf9c + * 202cff4815e97ab763dc14c61b0b694ee9381307eb46687f9caaea3465a913da * soc/rpi/rp2350/rp2350.yaml - * 9e60e99ecac8782bccd69e3bd69014af1d8891d6b6fbd822acff5bd9a526d8cd + * 80773a9c9cfb1c62cd322e397111a11d7f48fce3c0febc76bf7d5571018977a5 * soc/rpi/rp2350/rp2350a.yaml - * 045cef7794c3b6c6d2ff48ba294c6308d00fe13bc65e346f2ba2ccde1cea24ff + * 22395e35ed229020b5c9c7586af50cfaa07960a09905776eb4713ff28051eb3c */ #ifndef HW_CONFIG_H #define HW_CONFIG_H @@ -34,17 +34,22 @@ #define EMB_HW_SOC_PACKAGE "qfn60" /* clock tree (150 MHz) */ -#define EMB_HW_AHB_DIV 1u -#define EMB_HW_CPU_HZ 150000000u -#define EMB_HW_PLL_M 1u -#define EMB_HW_PLL_N 125u -#define EMB_HW_PLL_P 10u -#define EMB_HW_PLL_POSTDIV1 5u -#define EMB_HW_PLL_POSTDIV2 2u -#define EMB_HW_PLL_VCO_HZ 1500000000u -#define EMB_HW_SYS_HZ 150000000u -#define EMB_HW_XOSC_BYPASS 0 -#define EMB_HW_XOSC_HZ 12000000u +#define EMB_HW_AHB_DIV 1u +#define EMB_HW_CPU_HZ 150000000u +#define EMB_HW_PLL_M 1u +#define EMB_HW_PLL_N 125u +#define EMB_HW_PLL_P 10u +#define EMB_HW_PLL_POSTDIV1 5u +#define EMB_HW_PLL_POSTDIV2 2u +#define EMB_HW_PLL_USB_HZ 48000000u +#define EMB_HW_PLL_USB_M 1u +#define EMB_HW_PLL_USB_N 64u +#define EMB_HW_PLL_USB_POSTDIV1 4u +#define EMB_HW_PLL_USB_POSTDIV2 4u +#define EMB_HW_PLL_VCO_HZ 1500000000u +#define EMB_HW_SYS_HZ 150000000u +#define EMB_HW_XOSC_BYPASS 0 +#define EMB_HW_XOSC_HZ 12000000u /* memory regions */ #define EMB_HW_SRAM_BASE 0x20000000u @@ -59,6 +64,8 @@ #define EMB_HW_IRQ_PRIORITY_BITS 4u /* peripherals: register blocks, interrupt lines, clock gates */ +#define EMB_HW_ADC_BASE 0x400A0000u +#define EMB_HW_ADC_IRQ_FIFO 35u #define EMB_HW_BOOTRAM_BASE 0x400E0000u #define EMB_HW_CLOCKS_BASE 0x40010000u #define EMB_HW_CLOCKS_IRQ 30u @@ -75,9 +82,25 @@ #define EMB_HW_IO_BANK0_IRQ_BANK0 21u #define EMB_HW_PADS_BANK0_BASE 0x40038000u #define EMB_HW_PLL_SYS_BASE 0x40050000u +#define EMB_HW_PLL_USB_BASE 0x40058000u #define EMB_HW_POWMAN_BASE 0x40100000u #define EMB_HW_POWMAN_IRQ_TIMER 45u #define EMB_HW_PSM_BASE 0x40018000u +#define EMB_HW_PWM0_BASE 0x400A8000u +#define EMB_HW_PWM10_BASE 0x400A80C8u +#define EMB_HW_PWM11_BASE 0x400A80DCu +#define EMB_HW_PWM1_BASE 0x400A8014u +#define EMB_HW_PWM2_BASE 0x400A8028u +#define EMB_HW_PWM3_BASE 0x400A803Cu +#define EMB_HW_PWM4_BASE 0x400A8050u +#define EMB_HW_PWM5_BASE 0x400A8064u +#define EMB_HW_PWM6_BASE 0x400A8078u +#define EMB_HW_PWM7_BASE 0x400A808Cu +#define EMB_HW_PWM8_BASE 0x400A80A0u +#define EMB_HW_PWM9_BASE 0x400A80B4u +#define EMB_HW_PWM_BASE 0x400A80F0u +#define EMB_HW_PWM_IRQ_WRAP0 8u +#define EMB_HW_PWM_IRQ_WRAP1 9u #define EMB_HW_QMI_BASE 0x400D0000u #define EMB_HW_RESETS_BASE 0x40020000u #define EMB_HW_SIO_BASE 0xD0000000u @@ -86,6 +109,16 @@ #define EMB_HW_SPI1_BASE 0x40088000u #define EMB_HW_SPI1_IRQ 32u #define EMB_HW_TICKS_BASE 0x40108000u +#define EMB_HW_TIMER0_BASE 0x400B0000u +#define EMB_HW_TIMER0_IRQ_ALARM0 0u +#define EMB_HW_TIMER0_IRQ_ALARM1 1u +#define EMB_HW_TIMER0_IRQ_ALARM2 2u +#define EMB_HW_TIMER0_IRQ_ALARM3 3u +#define EMB_HW_TIMER1_BASE 0x400B8000u +#define EMB_HW_TIMER1_IRQ_ALARM0 4u +#define EMB_HW_TIMER1_IRQ_ALARM1 5u +#define EMB_HW_TIMER1_IRQ_ALARM2 6u +#define EMB_HW_TIMER1_IRQ_ALARM3 7u #define EMB_HW_TRNG_BASE 0x400F0000u #define EMB_HW_TRNG_IRQ_IRQ 39u #define EMB_HW_UART0_BASE 0x40070000u diff --git a/examples/tasks/generated/pico2_w/src/soc_devices.c b/examples/tasks/src/config/.base/pico2_w/peripheral/soc_devices.c similarity index 74% rename from examples/tasks/generated/pico2_w/src/soc_devices.c rename to examples/tasks/src/config/.base/pico2_w/peripheral/soc_devices.c index f9c244af..6ebd6f57 100644 --- a/examples/tasks/generated/pico2_w/src/soc_devices.c +++ b/examples/tasks/src/config/.base/pico2_w/peripheral/soc_devices.c @@ -16,15 +16,15 @@ * arch/cortex_m/arch.yaml * c5c8e451c09717dee1713d07f8311b6d507e3b4c66c42d93e0ce11da6ec76d6d * boards/rpi/pico2_w/board.yaml - * dad0ef7259e41ef3bd8fa07ea1c1f36040254a443deaf30d963b4fb14b5354a0 + * 345279a53c444bc45e7fcc1a0cb5ab47b32a7699534f5484ea80d73f7a0bdf6d * drivers/bindings.yaml - * d3c336ac05548e0addd1faac18f3dff70576d8069f11d89e6a761cf5c6132b49 + * c06d1a914adb21d0e314c79b3611ac6859eefeac1957d6914cccfc5531ad6ede * examples/tasks/system.yaml - * 3dd9de88918f06e4b3a41232cb716a9e7d1c4b74ad18e71fd51644ae394ebf9c + * 202cff4815e97ab763dc14c61b0b694ee9381307eb46687f9caaea3465a913da * soc/rpi/rp2350/rp2350.yaml - * 9e60e99ecac8782bccd69e3bd69014af1d8891d6b6fbd822acff5bd9a526d8cd + * 80773a9c9cfb1c62cd322e397111a11d7f48fce3c0febc76bf7d5571018977a5 * soc/rpi/rp2350/rp2350a.yaml - * 045cef7794c3b6c6d2ff48ba294c6308d00fe13bc65e346f2ba2ccde1cea24ff + * 22395e35ed229020b5c9c7586af50cfaa07960a09905776eb4713ff28051eb3c */ #include @@ -297,6 +297,97 @@ const emb_device_t emb_dev_i2c1 = { .dep_count = 1u, }; +/* timer1: rpi,rp2350-timer, counter, KERNEL */ +static const emb_rp2350_timer_config_t timer1_config = { + .base = 0x400B8000u, /* peripheral.base */ + .index = 1u, /* peripheral.index */ + .rate_hz = 1000000u, /* device.rate_hz, its default */ + .irq0 = 4u, /* peripheral.irqs.alarm0 */ + .irq1 = 5u, /* peripheral.irqs.alarm1 */ + .irq2 = 6u, /* peripheral.irqs.alarm2 */ + .irq3 = 7u, /* peripheral.irqs.alarm3 */ +}; +static emb_device_state_t timer1_state; +static emb_rp2350_timer_data_t timer1_data; +const emb_device_t emb_dev_timer1 = { + .name = "timer1", + .api = &emb_rp2350_timer_api.dev, + .config = &timer1_config, + .state = &timer1_state, + .data = &timer1_data, + .deps = NULL, + .class_id = EMB_DRV_CLASS_COUNTER, + .level = EMB_DEVICE_KERNEL, + .dep_count = 0u, +}; + +/* pwm7: rpi,rp2350-pwm, pwm, KERNEL */ +static const emb_rp2350_pwm_config_t pwm7_config = { + .base = 0x400A808Cu, /* peripheral.base */ + .index = 7u, /* peripheral.index */ + .clock_hz = 150000000u, /* peripheral.clock_hz */ +}; +static emb_device_state_t pwm7_state; +static emb_rp2350_pwm_data_t pwm7_data; +static const emb_device_t *const pwm7_deps[] = {&emb_dev_io_bank0}; +const emb_device_t emb_dev_pwm7 = { + .name = "pwm7", + .api = &emb_rp2350_pwm_api.dev, + .config = &pwm7_config, + .state = &pwm7_state, + .data = &pwm7_data, + .deps = pwm7_deps, + .class_id = EMB_DRV_CLASS_PWM, + .level = EMB_DEVICE_KERNEL, + .dep_count = 1u, +}; + +/* pwm0: rpi,rp2350-pwm, pwm, KERNEL */ +static const emb_rp2350_pwm_config_t pwm0_config = { + .base = 0x400A8000u, /* peripheral.base */ + .index = 0u, /* peripheral.index */ + .clock_hz = 150000000u, /* peripheral.clock_hz */ +}; +static emb_device_state_t pwm0_state; +static emb_rp2350_pwm_data_t pwm0_data; +static const emb_device_t *const pwm0_deps[] = {&emb_dev_io_bank0}; +const emb_device_t emb_dev_pwm0 = { + .name = "pwm0", + .api = &emb_rp2350_pwm_api.dev, + .config = &pwm0_config, + .state = &pwm0_state, + .data = &pwm0_data, + .deps = pwm0_deps, + .class_id = EMB_DRV_CLASS_PWM, + .level = EMB_DEVICE_KERNEL, + .dep_count = 1u, +}; + +/* adc: rpi,rp2350-adc, adc, KERNEL */ +static const emb_rp2350_adc_config_t adc_config = { + .base = 0x400A0000u, /* peripheral.base */ + .clock_hz = 48000000u, /* peripheral.clock_hz */ + .vref_mv = 3300u, /* device.vref_mv, its default */ + .bits = 12u, /* peripheral.adc.bits */ + .inputs = 4u, /* peripheral.adc.inputs */ + .temperature = 4u, /* peripheral.adc.temperature */ + .dma_rx = {&emb_dev_dma, 3u, 48u, {0u, 0u}}, /* dma.rx */ +}; +static emb_device_state_t adc_state; +static emb_rp2350_adc_data_t adc_data; +static const emb_device_t *const adc_deps[] = {&emb_dev_clocks, &emb_dev_io_bank0, &emb_dev_dma}; +const emb_device_t emb_dev_adc = { + .name = "adc", + .api = &emb_rp2350_adc_api.dev, + .config = &adc_config, + .state = &adc_state, + .data = &adc_data, + .deps = adc_deps, + .class_id = EMB_DRV_CLASS_ADC, + .level = EMB_DEVICE_KERNEL, + .dep_count = 3u, +}; + /* in initialization order */ static const emb_device_t *const devices[] = { &emb_dev_clocks, /* 0: EARLY */ @@ -311,9 +402,13 @@ static const emb_device_t *const devices[] = { &emb_dev_spi1, /* 9: KERNEL */ &emb_dev_i2c0, /* 10: KERNEL */ &emb_dev_i2c1, /* 11: KERNEL */ + &emb_dev_timer1, /* 12: KERNEL */ + &emb_dev_pwm7, /* 13: KERNEL */ + &emb_dev_pwm0, /* 14: KERNEL */ + &emb_dev_adc, /* 15: KERNEL */ }; -const emb_device_table_t emb_board_device_table = {devices, 12u, 8u}; +const emb_device_table_t emb_board_device_table = {devices, 16u, 8u}; #if CONFIG_EMB_DRV_ENTROPY /* the board's entropy source, or none: nothing stands in for one (SPEC-017 §11, SEC-012) */ diff --git a/examples/tasks/generated/pico2_w/include/soc_devices.h b/examples/tasks/src/config/.base/pico2_w/peripheral/soc_devices.h similarity index 79% rename from examples/tasks/generated/pico2_w/include/soc_devices.h rename to examples/tasks/src/config/.base/pico2_w/peripheral/soc_devices.h index babc37ae..3956ddeb 100644 --- a/examples/tasks/generated/pico2_w/include/soc_devices.h +++ b/examples/tasks/src/config/.base/pico2_w/peripheral/soc_devices.h @@ -15,22 +15,22 @@ * arch/cortex_m/arch.yaml * c5c8e451c09717dee1713d07f8311b6d507e3b4c66c42d93e0ce11da6ec76d6d * boards/rpi/pico2_w/board.yaml - * dad0ef7259e41ef3bd8fa07ea1c1f36040254a443deaf30d963b4fb14b5354a0 + * 345279a53c444bc45e7fcc1a0cb5ab47b32a7699534f5484ea80d73f7a0bdf6d * drivers/bindings.yaml - * d3c336ac05548e0addd1faac18f3dff70576d8069f11d89e6a761cf5c6132b49 + * c06d1a914adb21d0e314c79b3611ac6859eefeac1957d6914cccfc5531ad6ede * examples/tasks/system.yaml - * 3dd9de88918f06e4b3a41232cb716a9e7d1c4b74ad18e71fd51644ae394ebf9c + * 202cff4815e97ab763dc14c61b0b694ee9381307eb46687f9caaea3465a913da * soc/rpi/rp2350/rp2350.yaml - * 9e60e99ecac8782bccd69e3bd69014af1d8891d6b6fbd822acff5bd9a526d8cd + * 80773a9c9cfb1c62cd322e397111a11d7f48fce3c0febc76bf7d5571018977a5 * soc/rpi/rp2350/rp2350a.yaml - * 045cef7794c3b6c6d2ff48ba294c6308d00fe13bc65e346f2ba2ccde1cea24ff + * 22395e35ed229020b5c9c7586af50cfaa07960a09905776eb4713ff28051eb3c */ #ifndef EMB_SOC_DEVICES_H #define EMB_SOC_DEVICES_H #include -#define EMB_SOC_DEVICE_COUNT 12u +#define EMB_SOC_DEVICE_COUNT 16u #if CONFIG_EMB_DEVICE #include @@ -48,6 +48,10 @@ extern const emb_device_t emb_dev_trng; extern const emb_device_t emb_dev_spi1; extern const emb_device_t emb_dev_i2c0; extern const emb_device_t emb_dev_i2c1; +extern const emb_device_t emb_dev_timer1; +extern const emb_device_t emb_dev_pwm7; +extern const emb_device_t emb_dev_pwm0; +extern const emb_device_t emb_dev_adc; /* which devices the board has, for code that uses one only where it exists */ #define EMB_SOC_HAS_CLOCKS 1 @@ -62,6 +66,10 @@ extern const emb_device_t emb_dev_i2c1; #define EMB_SOC_HAS_SPI1 1 #define EMB_SOC_HAS_I2C0 1 #define EMB_SOC_HAS_I2C1 1 +#define EMB_SOC_HAS_TIMER1 1 +#define EMB_SOC_HAS_PWM7 1 +#define EMB_SOC_HAS_PWM0 1 +#define EMB_SOC_HAS_ADC 1 /* the board's watchdog device: the first of its class */ #define EMB_SOC_WATCHDOG_DEVICE (&emb_dev_watchdog) @@ -69,6 +77,11 @@ extern const emb_device_t emb_dev_i2c1; /* the board's RTC device: the first of its class */ #define EMB_SOC_RTC_DEVICE (&emb_dev_rtc) +/* the board's counters: the first of their class, and all of them (SPEC-017 §11a) */ +#define EMB_SOC_COUNTER_DEVICE (&emb_dev_timer1) +#define EMB_SOC_COUNTER_DEVICES &emb_dev_timer1 +#define EMB_SOC_COUNTER_COUNT 1u + /* the board's entropy source: the first of its class (SPEC-017 §11) */ #define EMB_SOC_ENTROPY_DEVICE (&emb_dev_trng) @@ -90,6 +103,7 @@ extern const emb_device_t emb_dev_i2c1; #define EMB_SOC_UART1_DMA_TX {&emb_dev_dma, 2u, 30u, {0u, 0u}} #define EMB_SOC_SPI1_DMA_RX {&emb_dev_dma, 1u, 27u, {0u, 0u}} #define EMB_SOC_SPI1_DMA_TX {&emb_dev_dma, 0u, 26u, {0u, 0u}} +#define EMB_SOC_ADC_DMA_RX {&emb_dev_dma, 3u, 48u, {0u, 0u}} /* clang-format on */ /* the SPI devices' chip selects (devices[].cs), emb_drv_gpio_line_t initializers; the pin diff --git a/examples/tasks/src/config/.base/pico2_w/tasks.c b/examples/tasks/src/config/.base/pico2_w/tasks.c new file mode 100644 index 00000000..6031753e --- /dev/null +++ b/examples/tasks/src/config/.base/pico2_w/tasks.c @@ -0,0 +1,203 @@ +/* SPDX-License-Identifier: Apache-2.0 */ +/* + * This file is part of EmbLinkRTOS, a deterministic real-time kernel for microcontrollers. + * Licensed under the Apache License, Version 2.0; see the LICENSE file at the repository root. + */ + +/******************************************************************************* + System Tasks File + + File Name: + tasks.c + + Summary: + tasks_demo's tasks on the pico2_w, and SYS_Tasks(). + + Description: + Each task's thread, queue, dispatch and description: the thread runs the + task runtime, emb_task_run() (SPEC-020), which calls an event task's handler + for each event, and a periodic task's _Tasks() every period, without drift. + SYS_Tasks() starts the kernel. + + Generated by emb-hwgen 0.1.0, schema v0, from the system description and the + pico2_w's. Yours to edit: regenerating merges its changes with yours (A126): + hw/gen/emb-hwgen.py generate --system examples/tasks/system.yaml + + Inputs (SHA-256): + arch/cortex_m/arch.yaml + c5c8e451c09717dee1713d07f8311b6d507e3b4c66c42d93e0ce11da6ec76d6d + boards/rpi/pico2_w/board.yaml + 345279a53c444bc45e7fcc1a0cb5ab47b32a7699534f5484ea80d73f7a0bdf6d + drivers/bindings.yaml + c06d1a914adb21d0e314c79b3611ac6859eefeac1957d6914cccfc5531ad6ede + examples/tasks/system.yaml + 202cff4815e97ab763dc14c61b0b694ee9381307eb46687f9caaea3465a913da + soc/rpi/rp2350/rp2350.yaml + 80773a9c9cfb1c62cd322e397111a11d7f48fce3c0febc76bf7d5571018977a5 + soc/rpi/rp2350/rp2350a.yaml + 22395e35ed229020b5c9c7586af50cfaa07960a09905776eb4713ff28051eb3c + *******************************************************************************/ + +// ***************************************************************************** +// ***************************************************************************** +// Section: Included Files +// ***************************************************************************** +// ***************************************************************************** + +#include "definitions.h" + +// ***************************************************************************** +// ***************************************************************************** +// Section: RTOS "Tasks" Routine +// ***************************************************************************** +// ***************************************************************************** + +/* ---- door: an event task, its queue 8 deep (SPEC-020) ---- */ + +_Static_assert(DOOR_STATE_CLOSED == 0, "door.h: DOOR_STATES are system.yaml's states, in order"); +_Static_assert(DOOR_STATE_OPEN == 1, "door.h: DOOR_STATES are system.yaml's states, in order"); +_Static_assert(DOOR_STATE_JAMMED == 2, "door.h: DOOR_STATES are system.yaml's states, in order"); +_Static_assert(DOOR_EVENT_OPEN == EMB_EV_USER + 0u, + "door.h: DOOR_EVENTS are system.yaml's events, in order"); +_Static_assert(DOOR_EVENT_CLOSE == EMB_EV_USER + 1u, + "door.h: DOOR_EVENTS are system.yaml's events, in order"); +_Static_assert(DOOR_EVENT_JAM == EMB_EV_USER + 2u, + "door.h: DOOR_EVENTS are system.yaml's events, in order"); + +static emb_task_event_t door_event; +EMB_MSGQ_DEFINE(door_task_queue, sizeof(emb_task_event_t), DOOR_QUEUE_LENGTH, 0u); +static const uint32_t door_timeouts[3] = {0u, DOOR_OPEN_TIMEOUT_MS, 0u}; + +static emb_state_t door_dispatch(emb_state_t state, uint8_t why) +{ + emb_state_t next = state; /* a state the task lacks stays: the runtime faults on it */ + if (why == EMB_TASK_WHY_TIMEOUT) { + door_event.id = EMB_EV_TIMEOUT; + door_event.value = 0u; + } + switch (state) { + case DOOR_STATE_CLOSED: + doorData.state = DOOR_STATE_CLOSED; + next = (emb_state_t)DOOR_OnClosed(&door_event); + break; + case DOOR_STATE_OPEN: + doorData.state = DOOR_STATE_OPEN; + next = (emb_state_t)DOOR_OnOpen(&door_event); + break; + case DOOR_STATE_JAMMED: + doorData.state = DOOR_STATE_JAMMED; + next = (emb_state_t)DOOR_OnJammed(&door_event); + break; + default: + break; + } + return next; +} + +static void door_enter(emb_state_t state) +{ + switch (state) { + case DOOR_STATE_CLOSED: + doorData.state = DOOR_STATE_CLOSED; + break; + case DOOR_STATE_OPEN: + doorData.state = DOOR_STATE_OPEN; + DOOR_EnterOpen(); + break; + case DOOR_STATE_JAMMED: + doorData.state = DOOR_STATE_JAMMED; + break; + default: + break; + } +} + +static void door_exit(emb_state_t state) +{ + if (state == DOOR_STATE_OPEN) { + DOOR_ExitOpen(); + } +} + +static const emb_task_desc_t door_desc = { + .name = "door", + .dispatch = door_dispatch, + .enter = door_enter, + .leave = door_exit, + .event = &door_event, + .queue = &door_task_queue, + .timeout_ms = door_timeouts, + .period_ms = 0u, + .event_size = (uint16_t)sizeof(emb_task_event_t), + .initial = (emb_state_t)DOOR_STATE_CLOSED, + .count = 3u, + .model = EMB_TASK_EVENT, +}; +emb_task_t door_task = {.desc = &door_desc, .state = (emb_state_t)DOOR_STATE_CLOSED}; + +static void door_main(void *arg) +{ + (void)arg; + emb_task_run(&door_task); +} + +EMB_THREAD_DEFINE(door_thread, door_main, NULL, DOOR_PRIORITY, DOOR_STACK_SIZE, 0u); + +/* ---- blink: a periodic task, every 500 ms (SPEC-020) ---- */ + +_Static_assert(BLINK_STATE_DARK == 0, "blink.h: BLINK_STATES are system.yaml's states, in order"); +_Static_assert(BLINK_STATE_LIT == 1, "blink.h: BLINK_STATES are system.yaml's states, in order"); + +static emb_state_t blink_dispatch(emb_state_t state, uint8_t why) +{ + (void)state; + (void)why; + BLINK_Tasks(); + return (emb_state_t)blinkData.state; +} + +static const emb_task_desc_t blink_desc = { + .name = "blink", + .dispatch = blink_dispatch, + .enter = NULL, + .leave = NULL, + .event = NULL, + .queue = NULL, + .timeout_ms = NULL, + .period_ms = BLINK_PERIOD_MS, + .event_size = 0u, + .initial = (emb_state_t)BLINK_STATE_DARK, + .count = 2u, + .model = EMB_TASK_PERIODIC, +}; +emb_task_t blink_task = {.desc = &blink_desc, .state = (emb_state_t)BLINK_STATE_DARK}; + +static void blink_main(void *arg) +{ + (void)arg; + emb_task_run(&blink_task); +} + +EMB_THREAD_DEFINE(blink_thread, blink_main, NULL, BLINK_PRIORITY, BLINK_STACK_SIZE, 0u); + +// ***************************************************************************** +// ***************************************************************************** +// Section: System "Tasks" Routine +// ***************************************************************************** +// ***************************************************************************** + +/******************************************************************************* + Function: + void SYS_Tasks ( void ) + + Remarks: + See prototype in definitions.h. + */ +void SYS_Tasks(void) +{ + /* Start the kernel: the threads and the tasks run from here. It does not return. */ + emb_kernel_start(); +} +/******************************************************************************* + End of File +*/ diff --git a/examples/tasks/generated/.base/nucleo_f446re/build/CMakeLists.txt b/examples/tasks/src/config/nucleo_f446re/build/CMakeLists.txt similarity index 66% rename from examples/tasks/generated/.base/nucleo_f446re/build/CMakeLists.txt rename to examples/tasks/src/config/nucleo_f446re/build/CMakeLists.txt index 43d8ef4f..65590fc0 100644 --- a/examples/tasks/generated/.base/nucleo_f446re/build/CMakeLists.txt +++ b/examples/tasks/src/config/nucleo_f446re/build/CMakeLists.txt @@ -9,17 +9,17 @@ # arch/cortex_m/arch.yaml # c5c8e451c09717dee1713d07f8311b6d507e3b4c66c42d93e0ce11da6ec76d6d # boards/st/nucleo_f446re/board.yaml -# d756f3a7f19dc7da82ee3afc168dc54946312c5a9990720953c0fedcdece54ea +# 551c524379751d359bdd87501269d6cab33edf84d212d2f6632ffe9567ec71d0 # drivers/bindings.yaml -# d3c336ac05548e0addd1faac18f3dff70576d8069f11d89e6a761cf5c6132b49 +# c06d1a914adb21d0e314c79b3611ac6859eefeac1957d6914cccfc5531ad6ede # examples/tasks/system.yaml -# 3dd9de88918f06e4b3a41232cb716a9e7d1c4b74ad18e71fd51644ae394ebf9c +# 202cff4815e97ab763dc14c61b0b694ee9381307eb46687f9caaea3465a913da # soc/st/stm32f4/stm32f4.yaml -# 3db4a0a65c9624d865d4ed7fc6354bf95054d0c465b76a2091f06aeac3d7375f +# 796886c294250aa81151a620d80d0e43b5ee8e1bf53a07d1d7e2c62e95214dbd # soc/st/stm32f4/stm32f446.yaml -# 0d5cc7f5fce4c51be71678987720c85c6e76e05473ff8a78ea5035394316c055 +# f0c9a37f6017c87d0efe215a3561f65494ba52383f2d0c10419b0ab5035f77f2 # soc/st/stm32f4/stm32f446re.yaml # b9a88d0a94aa17ee83317a3a56f7c194ec1b3107dfb3e82e453122dc1c48f6d4 # The board has no C of its own: its SoC family's board support builds emb_board from -# ../src/board_pins.c and ../include/hw_config.h, and links ../linker/regions.ld. +# ../peripheral/board_pins.c and ../peripheral/hw_config.h, and links ../linker/regions.ld. add_subdirectory("${EMB_SOC_DIR}" soc) diff --git a/examples/tasks/generated/nucleo_f446re/build/board.cmake b/examples/tasks/src/config/nucleo_f446re/build/board.cmake similarity index 63% rename from examples/tasks/generated/nucleo_f446re/build/board.cmake rename to examples/tasks/src/config/nucleo_f446re/build/board.cmake index 4f3676d2..24e51cfd 100644 --- a/examples/tasks/generated/nucleo_f446re/build/board.cmake +++ b/examples/tasks/src/config/nucleo_f446re/build/board.cmake @@ -9,15 +9,15 @@ # arch/cortex_m/arch.yaml # c5c8e451c09717dee1713d07f8311b6d507e3b4c66c42d93e0ce11da6ec76d6d # boards/st/nucleo_f446re/board.yaml -# d756f3a7f19dc7da82ee3afc168dc54946312c5a9990720953c0fedcdece54ea +# 551c524379751d359bdd87501269d6cab33edf84d212d2f6632ffe9567ec71d0 # drivers/bindings.yaml -# d3c336ac05548e0addd1faac18f3dff70576d8069f11d89e6a761cf5c6132b49 +# c06d1a914adb21d0e314c79b3611ac6859eefeac1957d6914cccfc5531ad6ede # examples/tasks/system.yaml -# 3dd9de88918f06e4b3a41232cb716a9e7d1c4b74ad18e71fd51644ae394ebf9c +# 202cff4815e97ab763dc14c61b0b694ee9381307eb46687f9caaea3465a913da # soc/st/stm32f4/stm32f4.yaml -# 3db4a0a65c9624d865d4ed7fc6354bf95054d0c465b76a2091f06aeac3d7375f +# 796886c294250aa81151a620d80d0e43b5ee8e1bf53a07d1d7e2c62e95214dbd # soc/st/stm32f4/stm32f446.yaml -# 0d5cc7f5fce4c51be71678987720c85c6e76e05473ff8a78ea5035394316c055 +# f0c9a37f6017c87d0efe215a3561f65494ba52383f2d0c10419b0ab5035f77f2 # soc/st/stm32f4/stm32f446re.yaml # b9a88d0a94aa17ee83317a3a56f7c194ec1b3107dfb3e82e453122dc1c48f6d4 # nucleo_f446re: STM32F446RE, cortex-m4f at 180 MHz. @@ -26,23 +26,28 @@ set(EMB_BOARD_VARIANT armv7em) set(EMB_BOARD_DEFAULT_PROFILE base) set(EMB_BOARD_C_FLAGS -mcpu=cortex-m4 -mfpu=fpv4-sp-d16 -mfloat-abi=hard) get_filename_component(EMB_BOARD_GENERATED_DIR "${CMAKE_CURRENT_LIST_DIR}/.." ABSOLUTE) -set(EMB_BOARD_CONF "${EMB_BOARD_GENERATED_DIR}/config/board.conf") +set(EMB_BOARD_CONF "${EMB_BOARD_GENERATED_DIR}/build/board.conf") set(EMB_BOARD_HW_JSON "${EMB_BOARD_GENERATED_DIR}/docs/hw.json") set(EMB_BOARD_BUILD_DIR "${CMAKE_CURRENT_LIST_DIR}") # build/CMakeLists.txt +set(EMB_BOARD_SRC_DIR "${EMB_BOARD_GENERATED_DIR}/peripheral") # its pin table and boot block +set(EMB_BOARD_LINKER_DIR "${EMB_BOARD_GENERATED_DIR}/linker") # the SoC family's board support and drivers build this board (build/CMakeLists.txt) set(EMB_SOC_DIR "${EMB_BASE}/soc/st/stm32f4") -set(EMB_BOARD_INCLUDE_DIRS "${EMB_BOARD_GENERATED_DIR}/include" "${EMB_SOC_DIR}/include") +set(EMB_BOARD_INCLUDE_DIRS "${EMB_BOARD_GENERATED_DIR}/peripheral" "${EMB_SOC_DIR}/include") set(EMB_BOARD_RESETS_IN embsim hil) # restart the image with RAM kept (test_crash_reset) set(EMB_BOARD_EMBSIM_TARGET emblink/nucleo_f446re) # EMB_TEST_EMULATOR=embsim set(EMB_BOARD_USART2_DMA tx) set(EMB_BOARD_SPI2_DMA rx tx) set(EMB_BOARD_SPI2_CS_COUNT 1) +set(EMB_BOARD_ADC1_DMA rx) set(EMB_BOARD_EMBSIM_UART_LOOP uart4 "A0,A1") set(EMB_BOARD_EMBSIM_SPI_LOOP spi2 "CN10_26,CN10_28") set(EMB_BOARD_EMBSIM_I2C_LOOP i2c1 i2c2 "D15,D6" "D14,D3") +set(EMB_BOARD_EMBSIM_PWM_LOOP "tim3:0,tim4:0" "D12,D10") +set(EMB_BOARD_EMBSIM_ADC_LOOP "adc1:4,8" "A2,3V3" "A3,GND") # the board's devices (soc_devices.c) and the drivers they use, and only those (SPEC-016 §8) set(EMB_BOARD_DRIVER_SOURCES - "${EMB_BOARD_GENERATED_DIR}/src/soc_devices.c" + "${EMB_BOARD_GENERATED_DIR}/peripheral/soc_devices.c" "${EMB_BASE}/drivers/st/stm32_devices.c" "${EMB_BASE}/drivers/st/stm32_iwdg.c" "${EMB_BASE}/drivers/st/stm32_rtc.c" @@ -51,6 +56,9 @@ set(EMB_BOARD_DRIVER_SOURCES "${EMB_BASE}/drivers/st/stm32_uart.c" "${EMB_BASE}/drivers/st/stm32_spi.c" "${EMB_BASE}/drivers/st/stm32_i2c.c" + "${EMB_BASE}/drivers/st/stm32_tim_counter.c" + "${EMB_BASE}/drivers/st/stm32_tim_pwm.c" + "${EMB_BASE}/drivers/st/stm32_adc.c" ) set(EMB_BOARD_DRIVER_INCLUDE_DIRS "${EMB_BASE}/drivers/st/include" @@ -58,10 +66,10 @@ set(EMB_BOARD_DRIVER_INCLUDE_DIRS # the inputs this directory was generated from, for the configure-time staleness check set(EMB_BOARD_HW_INPUTS "arch/cortex_m/arch.yaml=c5c8e451c09717dee1713d07f8311b6d507e3b4c66c42d93e0ce11da6ec76d6d" - "boards/st/nucleo_f446re/board.yaml=d756f3a7f19dc7da82ee3afc168dc54946312c5a9990720953c0fedcdece54ea" - "drivers/bindings.yaml=d3c336ac05548e0addd1faac18f3dff70576d8069f11d89e6a761cf5c6132b49" - "examples/tasks/system.yaml=3dd9de88918f06e4b3a41232cb716a9e7d1c4b74ad18e71fd51644ae394ebf9c" - "soc/st/stm32f4/stm32f4.yaml=3db4a0a65c9624d865d4ed7fc6354bf95054d0c465b76a2091f06aeac3d7375f" - "soc/st/stm32f4/stm32f446.yaml=0d5cc7f5fce4c51be71678987720c85c6e76e05473ff8a78ea5035394316c055" + "boards/st/nucleo_f446re/board.yaml=551c524379751d359bdd87501269d6cab33edf84d212d2f6632ffe9567ec71d0" + "drivers/bindings.yaml=c06d1a914adb21d0e314c79b3611ac6859eefeac1957d6914cccfc5531ad6ede" + "examples/tasks/system.yaml=202cff4815e97ab763dc14c61b0b694ee9381307eb46687f9caaea3465a913da" + "soc/st/stm32f4/stm32f4.yaml=796886c294250aa81151a620d80d0e43b5ee8e1bf53a07d1d7e2c62e95214dbd" + "soc/st/stm32f4/stm32f446.yaml=f0c9a37f6017c87d0efe215a3561f65494ba52383f2d0c10419b0ab5035f77f2" "soc/st/stm32f4/stm32f446re.yaml=b9a88d0a94aa17ee83317a3a56f7c194ec1b3107dfb3e82e453122dc1c48f6d4" ) diff --git a/examples/tasks/generated/.base/nucleo_f446re/config/board.conf b/examples/tasks/src/config/nucleo_f446re/build/board.conf similarity index 73% rename from examples/tasks/generated/.base/nucleo_f446re/config/board.conf rename to examples/tasks/src/config/nucleo_f446re/build/board.conf index e26f1083..aece92f0 100644 --- a/examples/tasks/generated/.base/nucleo_f446re/config/board.conf +++ b/examples/tasks/src/config/nucleo_f446re/build/board.conf @@ -9,15 +9,15 @@ # arch/cortex_m/arch.yaml # c5c8e451c09717dee1713d07f8311b6d507e3b4c66c42d93e0ce11da6ec76d6d # boards/st/nucleo_f446re/board.yaml -# d756f3a7f19dc7da82ee3afc168dc54946312c5a9990720953c0fedcdece54ea +# 551c524379751d359bdd87501269d6cab33edf84d212d2f6632ffe9567ec71d0 # drivers/bindings.yaml -# d3c336ac05548e0addd1faac18f3dff70576d8069f11d89e6a761cf5c6132b49 +# c06d1a914adb21d0e314c79b3611ac6859eefeac1957d6914cccfc5531ad6ede # examples/tasks/system.yaml -# 3dd9de88918f06e4b3a41232cb716a9e7d1c4b74ad18e71fd51644ae394ebf9c +# 202cff4815e97ab763dc14c61b0b694ee9381307eb46687f9caaea3465a913da # soc/st/stm32f4/stm32f4.yaml -# 3db4a0a65c9624d865d4ed7fc6354bf95054d0c465b76a2091f06aeac3d7375f +# 796886c294250aa81151a620d80d0e43b5ee8e1bf53a07d1d7e2c62e95214dbd # soc/st/stm32f4/stm32f446.yaml -# 0d5cc7f5fce4c51be71678987720c85c6e76e05473ff8a78ea5035394316c055 +# f0c9a37f6017c87d0efe215a3561f65494ba52383f2d0c10419b0ab5035f77f2 # soc/st/stm32f4/stm32f446re.yaml # b9a88d0a94aa17ee83317a3a56f7c194ec1b3107dfb3e82e453122dc1c48f6d4 # Board defaults for nucleo_f446re. Applied before the profile fragment. diff --git a/examples/tasks/src/config/nucleo_f446re/configuration.h b/examples/tasks/src/config/nucleo_f446re/configuration.h new file mode 100644 index 00000000..9d6571be --- /dev/null +++ b/examples/tasks/src/config/nucleo_f446re/configuration.h @@ -0,0 +1,109 @@ +/* SPDX-License-Identifier: Apache-2.0 */ +/* + * This file is part of EmbLinkRTOS, a deterministic real-time kernel for microcontrollers. + * Licensed under the Apache License, Version 2.0; see the LICENSE file at the repository root. + */ + +/******************************************************************************* + System Configuration Header + + File Name: + configuration.h + + Summary: + The build-time configuration of tasks_demo on the nucleo_f446re. + + Description: + The system's settings as macros: the board and its clock, the devices' + settings, each task's and thread's priority and stack, the tasks' periods, + queues and timeouts, and the application's interrupts. The kernel's own + options are 's CONFIG_EMB_*, and the board's hardware + 's EMB_HW_*. + + Generated by emb-hwgen 0.1.0, schema v0, from the system description and the + nucleo_f446re's. Yours to edit: regenerating merges its changes with yours + (A126): + hw/gen/emb-hwgen.py generate --system examples/tasks/system.yaml + + Inputs (SHA-256): + arch/cortex_m/arch.yaml + c5c8e451c09717dee1713d07f8311b6d507e3b4c66c42d93e0ce11da6ec76d6d + boards/st/nucleo_f446re/board.yaml + 551c524379751d359bdd87501269d6cab33edf84d212d2f6632ffe9567ec71d0 + drivers/bindings.yaml + c06d1a914adb21d0e314c79b3611ac6859eefeac1957d6914cccfc5531ad6ede + examples/tasks/system.yaml + 202cff4815e97ab763dc14c61b0b694ee9381307eb46687f9caaea3465a913da + soc/st/stm32f4/stm32f4.yaml + 796886c294250aa81151a620d80d0e43b5ee8e1bf53a07d1d7e2c62e95214dbd + soc/st/stm32f4/stm32f446.yaml + f0c9a37f6017c87d0efe215a3561f65494ba52383f2d0c10419b0ab5035f77f2 + soc/st/stm32f4/stm32f446re.yaml + b9a88d0a94aa17ee83317a3a56f7c194ec1b3107dfb3e82e453122dc1c48f6d4 + *******************************************************************************/ + +#ifndef CONFIGURATION_H +#define CONFIGURATION_H + +// ***************************************************************************** +// ***************************************************************************** +// Section: Included Files +// ***************************************************************************** +// ***************************************************************************** + +#include + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +// ***************************************************************************** +// ***************************************************************************** +// Section: System Configuration +// ***************************************************************************** +// ***************************************************************************** + +#define SYS_CPU_CLOCK_HZ 180000000u +#define SYS_TICK_NS CONFIG_EMB_TICK_NS +#define SYS_PRIORITY_COUNT CONFIG_EMB_PRIORITY_COUNT + +// ***************************************************************************** +// ***************************************************************************** +// Section: Driver Configuration +// ***************************************************************************** +// ***************************************************************************** + +#define DRV_USART2_BAUD 115200u +#define DRV_UART4_BAUD 115200u + +// ***************************************************************************** +// ***************************************************************************** +// Section: Application Configuration +// ***************************************************************************** +// ***************************************************************************** + +/* door: an event task, its queue 8 deep */ +#define DOOR_PRIORITY 5u +#define DOOR_STACK_SIZE 1024u +#define DOOR_QUEUE_LENGTH 8u +#define DOOR_OPEN_TIMEOUT_MS 2000u + +/* blink: a periodic task, every 500 ms */ +#define BLINK_PRIORITY 2u +#define BLINK_STACK_SIZE 512u +#define BLINK_PERIOD_MS 500u + +/* wake: an interrupt, WAKE_InterruptHandler() */ +#define WAKE_IRQ 61u +#define WAKE_IRQ_LEVEL 1u + +#ifdef __cplusplus +} +#endif + +#endif /* CONFIGURATION_H */ +/******************************************************************************* + End of File +*/ diff --git a/examples/tasks/src/config/nucleo_f446re/definitions.h b/examples/tasks/src/config/nucleo_f446re/definitions.h new file mode 100644 index 00000000..f785939d --- /dev/null +++ b/examples/tasks/src/config/nucleo_f446re/definitions.h @@ -0,0 +1,173 @@ +/* SPDX-License-Identifier: Apache-2.0 */ +/* + * This file is part of EmbLinkRTOS, a deterministic real-time kernel for microcontrollers. + * Licensed under the Apache License, Version 2.0; see the LICENSE file at the repository root. + */ + +/******************************************************************************* + System Definitions + + File Name: + definitions.h + + Summary: + tasks_demo's system definitions on the nucleo_f446re. + + Description: + The one header the application includes: the kernel's API, the board's + devices, the system's configuration and handles, every task's header, and + the system's two functions, SYS_Initialize() and SYS_Tasks(). + + Generated by emb-hwgen 0.1.0, schema v0, from the system description and the + nucleo_f446re's. Yours to edit: regenerating merges its changes with yours + (A126): + hw/gen/emb-hwgen.py generate --system examples/tasks/system.yaml + + Inputs (SHA-256): + arch/cortex_m/arch.yaml + c5c8e451c09717dee1713d07f8311b6d507e3b4c66c42d93e0ce11da6ec76d6d + boards/st/nucleo_f446re/board.yaml + 551c524379751d359bdd87501269d6cab33edf84d212d2f6632ffe9567ec71d0 + drivers/bindings.yaml + c06d1a914adb21d0e314c79b3611ac6859eefeac1957d6914cccfc5531ad6ede + examples/tasks/system.yaml + 202cff4815e97ab763dc14c61b0b694ee9381307eb46687f9caaea3465a913da + soc/st/stm32f4/stm32f4.yaml + 796886c294250aa81151a620d80d0e43b5ee8e1bf53a07d1d7e2c62e95214dbd + soc/st/stm32f4/stm32f446.yaml + f0c9a37f6017c87d0efe215a3561f65494ba52383f2d0c10419b0ab5035f77f2 + soc/st/stm32f4/stm32f446re.yaml + b9a88d0a94aa17ee83317a3a56f7c194ec1b3107dfb3e82e453122dc1c48f6d4 + *******************************************************************************/ + +#ifndef DEFINITIONS_H +#define DEFINITIONS_H + +// ***************************************************************************** +// ***************************************************************************** +// Section: Included Files +// ***************************************************************************** +// ***************************************************************************** + +#include "blink.h" +#include "configuration.h" +#include "door.h" +#include "interrupts.h" + +#include + +#include +#include +#include + +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/* Device Information */ +#define DEVICE_NAME "STM32F446RE" +#define DEVICE_ARCH "cortex-m4f" +#define DEVICE_FAMILY "stm32f4" +#define BOARD_NAME "nucleo_f446re" + +/* CPU clock frequency */ +#define CPU_CLOCK_FREQUENCY 180000000u + +// ***************************************************************************** +// ***************************************************************************** +// Section: System Functions +// ***************************************************************************** +// ***************************************************************************** + +/******************************************************************************* + Function: + void SYS_Initialize ( void *data ) + + Summary: + Initializes the board, the kernel and every task. + + Description: + This function initializes the board (its clocks, pins and console), then the + kernel (its objects and the EARLY devices), then the application's + interrupts, then each task, in its initial state. The KERNEL devices start + with the kernel, in SYS_Tasks(). + + Precondition: + None. + + Parameters: + data - Unused; NULL. + + Returns: + None. + + Example: + + SYS_Initialize(NULL); + while (true) { + SYS_Tasks(); + } + + + Remarks: + This function is called once, after reset, from main(). +*/ +void SYS_Initialize(void *data); + +/******************************************************************************* + Function: + void SYS_Tasks ( void ) + + Summary: + Starts the kernel: the threads and the tasks run from here. + + Description: + This function starts the KERNEL devices, then the scheduler, which runs the + system's threads and each task's thread. It does not return. + + Precondition: + SYS_Initialize() has run. + + Parameters: + None. + + Returns: + It does not return. + + Example: + + SYS_Initialize(NULL); + while (true) { + SYS_Tasks(); + } + + + Remarks: + Harmony calls its SYS_Tasks() in a loop; this one runs the scheduler and + never comes back. +*/ +void SYS_Tasks(void); + +// ***************************************************************************** +// ***************************************************************************** +// Section: Tasks +// ***************************************************************************** +// ***************************************************************************** + +/* each task's handle, for emb_task_post() (SPEC-020) */ +extern emb_task_t door_task; +extern emb_task_t blink_task; +#define DOOR_TASK (&door_task) +#define BLINK_TASK (&blink_task) + +#ifdef __cplusplus +} +#endif + +#endif /* DEFINITIONS_H */ +/******************************************************************************* + End of File +*/ diff --git a/examples/tasks/generated/nucleo_f446re/docs/board.md b/examples/tasks/src/config/nucleo_f446re/docs/board.md similarity index 76% rename from examples/tasks/generated/nucleo_f446re/docs/board.md rename to examples/tasks/src/config/nucleo_f446re/docs/board.md index 2416e35b..2b19732f 100644 --- a/examples/tasks/generated/nucleo_f446re/docs/board.md +++ b/examples/tasks/src/config/nucleo_f446re/docs/board.md @@ -35,8 +35,12 @@ The STM32F446RE at 180 MHz from the PLL, its input the ST-LINK's 8 MHz MCO on PH | PA1 | `pins.uart4.rx` | af8 (uart4_rx) | | PA2 | `pins.usart2.tx` | af7 (usart2_tx) | | PA3 | `pins.usart2.rx` | af7 (usart2_rx) | +| PA4 | `pins.adc1.in4` | analog | | PA5 | `leds.user` | output | +| PA6 | `pins.tim3.ch1` | af2 (tim3_ch1) | +| PB0 | `pins.adc1.in8` | analog | | PB3 | `pins.i2c2.sda` | af4 (i2c2_sda) | +| PB6 | `pins.tim4.ch1` | af2 (tim4_ch1) | | PB8 | `pins.i2c1.scl` | af4 (i2c1_scl) | | PB9 | `pins.i2c1.sda` | af4 (i2c1_sda) | | PB10 | `pins.i2c2.scl` | af4 (i2c2_scl) | @@ -58,6 +62,7 @@ In initialization order (SPEC-016 §4). | rtc | `st,stm32f4-rtc` | rtc | EARLY | - | | flash | `st,stm32f4-flash (flash_if)` | flash | EARLY | - | | dma1 | `st,stm32-dma` | dma | EARLY | rcc | +| dma2 | `st,stm32-dma` | dma | EARLY | rcc | | gpiob | `st,stm32-gpio` | gpio | EARLY | rcc | | gpioc | `st,stm32-gpio` | gpio | EARLY | rcc | | usart2 | `st,stm32-usart` | uart | EARLY | dma1, rcc | @@ -65,6 +70,11 @@ In initialization order (SPEC-016 §4). | spi2 | `st,stm32-spi` | spi | KERNEL | dma1, rcc | | i2c1 | `st,stm32-i2c` | i2c | KERNEL | rcc | | i2c2 | `st,stm32-i2c` | i2c | KERNEL | rcc | +| tim5 | `st,stm32-tim` | counter | KERNEL | rcc | +| tim9 | `st,stm32-tim` | counter | KERNEL | rcc | +| tim3 | `st,stm32-tim` | pwm | KERNEL | rcc | +| tim4 | `st,stm32-tim` | pwm | KERNEL | rcc | +| adc1 | `st,stm32f4-adc` | adc | KERNEL | dma2, rcc | ## Interrupt lines @@ -81,7 +91,10 @@ In initialization order (SPEC-016 §4). | 16 | dma1.s5 | | 17 | dma1.s6 | | 18 | adc1.global | +| 24 | tim9.global | | 28 | tim2.global | +| 29 | tim3.global | +| 30 | tim4.global | | 31 | i2c1.ev | | 32 | i2c1.er | | 33 | i2c2.ev | @@ -92,6 +105,7 @@ In initialization order (SPEC-016 §4). | 39 | usart3.global | | 41 | rtc.alarm | | 47 | dma1.s7 | +| 50 | tim5.global | | 52 | uart4.global | | 53 | uart5.global | | 56 | dma2.s0 | @@ -115,9 +129,9 @@ Generated by emb-hwgen 0.1.0, schema v0, from: | Input | SHA-256 | |---|---| | `arch/cortex_m/arch.yaml` | `c5c8e451c09717dee1713d07f8311b6d507e3b4c66c42d93e0ce11da6ec76d6d` | -| `boards/st/nucleo_f446re/board.yaml` | `d756f3a7f19dc7da82ee3afc168dc54946312c5a9990720953c0fedcdece54ea` | -| `drivers/bindings.yaml` | `d3c336ac05548e0addd1faac18f3dff70576d8069f11d89e6a761cf5c6132b49` | -| `examples/tasks/system.yaml` | `3dd9de88918f06e4b3a41232cb716a9e7d1c4b74ad18e71fd51644ae394ebf9c` | -| `soc/st/stm32f4/stm32f4.yaml` | `3db4a0a65c9624d865d4ed7fc6354bf95054d0c465b76a2091f06aeac3d7375f` | -| `soc/st/stm32f4/stm32f446.yaml` | `0d5cc7f5fce4c51be71678987720c85c6e76e05473ff8a78ea5035394316c055` | +| `boards/st/nucleo_f446re/board.yaml` | `551c524379751d359bdd87501269d6cab33edf84d212d2f6632ffe9567ec71d0` | +| `drivers/bindings.yaml` | `c06d1a914adb21d0e314c79b3611ac6859eefeac1957d6914cccfc5531ad6ede` | +| `examples/tasks/system.yaml` | `202cff4815e97ab763dc14c61b0b694ee9381307eb46687f9caaea3465a913da` | +| `soc/st/stm32f4/stm32f4.yaml` | `796886c294250aa81151a620d80d0e43b5ee8e1bf53a07d1d7e2c62e95214dbd` | +| `soc/st/stm32f4/stm32f446.yaml` | `f0c9a37f6017c87d0efe215a3561f65494ba52383f2d0c10419b0ab5035f77f2` | | `soc/st/stm32f4/stm32f446re.yaml` | `b9a88d0a94aa17ee83317a3a56f7c194ec1b3107dfb3e82e453122dc1c48f6d4` | diff --git a/examples/tasks/generated/nucleo_f446re/docs/build_report.md b/examples/tasks/src/config/nucleo_f446re/docs/build_report.md similarity index 63% rename from examples/tasks/generated/nucleo_f446re/docs/build_report.md rename to examples/tasks/src/config/nucleo_f446re/docs/build_report.md index a253a004..540274b1 100644 --- a/examples/tasks/generated/nucleo_f446re/docs/build_report.md +++ b/examples/tasks/src/config/nucleo_f446re/docs/build_report.md @@ -31,9 +31,9 @@ Generated by emb-hwgen 0.1.0, schema v0, from: | Input | SHA-256 | |---|---| | `arch/cortex_m/arch.yaml` | `c5c8e451c09717dee1713d07f8311b6d507e3b4c66c42d93e0ce11da6ec76d6d` | -| `boards/st/nucleo_f446re/board.yaml` | `d756f3a7f19dc7da82ee3afc168dc54946312c5a9990720953c0fedcdece54ea` | -| `drivers/bindings.yaml` | `d3c336ac05548e0addd1faac18f3dff70576d8069f11d89e6a761cf5c6132b49` | -| `examples/tasks/system.yaml` | `3dd9de88918f06e4b3a41232cb716a9e7d1c4b74ad18e71fd51644ae394ebf9c` | -| `soc/st/stm32f4/stm32f4.yaml` | `3db4a0a65c9624d865d4ed7fc6354bf95054d0c465b76a2091f06aeac3d7375f` | -| `soc/st/stm32f4/stm32f446.yaml` | `0d5cc7f5fce4c51be71678987720c85c6e76e05473ff8a78ea5035394316c055` | +| `boards/st/nucleo_f446re/board.yaml` | `551c524379751d359bdd87501269d6cab33edf84d212d2f6632ffe9567ec71d0` | +| `drivers/bindings.yaml` | `c06d1a914adb21d0e314c79b3611ac6859eefeac1957d6914cccfc5531ad6ede` | +| `examples/tasks/system.yaml` | `202cff4815e97ab763dc14c61b0b694ee9381307eb46687f9caaea3465a913da` | +| `soc/st/stm32f4/stm32f4.yaml` | `796886c294250aa81151a620d80d0e43b5ee8e1bf53a07d1d7e2c62e95214dbd` | +| `soc/st/stm32f4/stm32f446.yaml` | `f0c9a37f6017c87d0efe215a3561f65494ba52383f2d0c10419b0ab5035f77f2` | | `soc/st/stm32f4/stm32f446re.yaml` | `b9a88d0a94aa17ee83317a3a56f7c194ec1b3107dfb3e82e453122dc1c48f6d4` | diff --git a/examples/tasks/generated/nucleo_f446re/docs/hw.json b/examples/tasks/src/config/nucleo_f446re/docs/hw.json similarity index 77% rename from examples/tasks/generated/nucleo_f446re/docs/hw.json rename to examples/tasks/src/config/nucleo_f446re/docs/hw.json index 40ff8551..30955a18 100644 --- a/examples/tasks/generated/nucleo_f446re/docs/hw.json +++ b/examples/tasks/src/config/nucleo_f446re/docs/hw.json @@ -57,6 +57,10 @@ "doc": "DMA1: SPI2's transfers, and the console's writes", "name": "dma1" }, + { + "doc": "DMA2: ADC1's samples", + "name": "dma2" + }, { "doc": "SPI2's chip select, PB12", "name": "gpiob" @@ -96,6 +100,36 @@ "baud": 115200, "doc": "a spare UART; the HIL suite's loopback wires A0 (PA0, TX) to A1 (PA1, RX)", "name": "uart4" + }, + { + "class": "counter", + "doc": "TIM5, 32 bits at 1 MHz: the counter class's (A129); TIM2 stays the controller's ADC trigger", + "name": "tim5" + }, + { + "class": "counter", + "doc": "TIM9, 16 bits at 1 MHz: it wraps every 65.5 ms, so its tests widen the count on the board", + "name": "tim9" + }, + { + "class": "pwm", + "doc": "TIM3, PWM out on channel 1, D12 (PA6); the HIL suite wires it to D10", + "name": "tim3" + }, + { + "class": "pwm", + "doc": "TIM4, PWM capture on channel 1, D10 (PB6)", + "name": "tim4" + }, + { + "cal": "factory_cal", + "common": "adc_common", + "dma": [ + "rx" + ], + "doc": "ADC1, paced by TIM2 (the controller's trigger, which it drives by hand), A2 (PA4, input 4) and A3 (PB0, input 8); the HIL suite wires A2 to 3V3 and A3 to GND", + "name": "adc1", + "trigger": "tim2" } ], "doc": "The STM32F446RE at 180 MHz from the PLL, its input the ST-LINK's 8 MHz MCO on PH0 in HSE bypass (solder bridges SB16 and SB50 as shipped). The console is USART2, which the ST-LINK carries as its virtual COM port.", @@ -132,6 +166,10 @@ } }, "pins": { + "adc1": { + "in4": "PA4", + "in8": "PB0" + }, "i2c1": { "scl": "PB8.af4", "sda": "PB9.af4" @@ -145,6 +183,12 @@ "mosi": "PB15.af5", "sck": "PB13.af5" }, + "tim3": { + "ch1": "PA6.af2" + }, + "tim4": { + "ch1": "PB6.af2" + }, "uart4": { "rx": "PA1.af8", "tx": "PA0.af8" @@ -186,6 +230,35 @@ ] ], "peer": "i2c2" + }, + { + "channels": [ + 0, + 0 + ], + "device": "tim3", + "peer": "tim4", + "ports": [ + "D12", + "D10" + ] + }, + { + "channels": [ + 4, + 8 + ], + "device": "adc1", + "nets": [ + [ + "A2", + "3V3" + ], + [ + "A3", + "GND" + ] + ] } ], "resets_in": [ @@ -208,8 +281,14 @@ "apb1": 45000000, "apb2": 90000000 }, + "bus_timer_hz": { + "ahb1": 180000000, + "apb1": 90000000, + "apb2": 180000000 + }, "bypass": true, "cpu_hz": 180000000, + "fixed_plls": {}, "flash_wait_states": 5, "hclk_hz": 180000000, "pclk1_div": 4, @@ -357,6 +436,30 @@ "name": "dma1", "peripheral": "dma1" }, + { + "class": "dma", + "compatible": "st,stm32-dma", + "deps": [ + "rcc" + ], + "fields": { + "base": 1073898496, + "clken_bit": 22, + "clken_offset": 48, + "irq0": 56, + "irq1": 57, + "irq2": 58, + "irq3": 59, + "irq4": 60, + "irq5": 68, + "irq6": 69, + "irq7": 70, + "memory": true + }, + "level": "early", + "name": "dma2", + "peripheral": "dma2" + }, { "class": "gpio", "compatible": "st,stm32-gpio", @@ -519,6 +622,119 @@ "level": "kernel", "name": "i2c2", "peripheral": "i2c2" + }, + { + "class": "counter", + "compatible": "st,stm32-tim", + "deps": [ + "rcc" + ], + "fields": { + "base": 1073744896, + "bits": 32, + "channels": 4, + "clken_bit": 3, + "clken_offset": 64, + "clock_hz": 90000000, + "irq": 50, + "rate_hz": 1000000 + }, + "level": "kernel", + "name": "tim5", + "peripheral": "tim5" + }, + { + "class": "counter", + "compatible": "st,stm32-tim", + "deps": [ + "rcc" + ], + "fields": { + "base": 1073823744, + "bits": 16, + "channels": 2, + "clken_bit": 16, + "clken_offset": 68, + "clock_hz": 180000000, + "irq": 24, + "rate_hz": 1000000 + }, + "level": "kernel", + "name": "tim9", + "peripheral": "tim9" + }, + { + "class": "pwm", + "compatible": "st,stm32-tim", + "deps": [ + "rcc" + ], + "fields": { + "base": 1073742848, + "bits": 16, + "channels": 4, + "clken_bit": 1, + "clken_offset": 64, + "clock_hz": 90000000, + "irq": 29 + }, + "level": "kernel", + "name": "tim3", + "peripheral": "tim3" + }, + { + "class": "pwm", + "compatible": "st,stm32-tim", + "deps": [ + "rcc" + ], + "fields": { + "base": 1073743872, + "bits": 16, + "channels": 4, + "clken_bit": 2, + "clken_offset": 64, + "clock_hz": 90000000, + "irq": 30 + }, + "level": "kernel", + "name": "tim4", + "peripheral": "tim4" + }, + { + "class": "adc", + "compatible": "st,stm32f4-adc", + "deps": [ + "dma2", + "rcc" + ], + "fields": { + "base": 1073815552, + "bits": 12, + "calibration": 536836650, + "clken_bit": 8, + "clken_offset": 68, + "clock_hz": 90000000, + "common": 1073816320, + "dma_rx": { + "dma": "dma2", + "request": 0, + "stream": 0 + }, + "inputs": 16, + "irq": 18, + "temperature": 18, + "trigger": 1073741824, + "trigger_clken_bit": 0, + "trigger_clken_offset": 64, + "trigger_hz": 90000000, + "trigger_select": 6, + "vref_mv": 3300, + "vrefint": 17 + }, + "level": "kernel", + "name": "adc1", + "peripheral": "adc1" } ], "kconfig": { @@ -608,6 +824,15 @@ "port": "A", "signal": "usart2_rx" }, + { + "gpio": "gpioa", + "mode": "analog", + "number": 4, + "owner": "pins.adc1.in4", + "pin": "PA4", + "port": "A", + "signal": "adc1_in4" + }, { "gpio": "gpioa", "mode": "output", @@ -616,6 +841,25 @@ "pin": "PA5", "port": "A" }, + { + "af": 2, + "gpio": "gpioa", + "mode": "af", + "number": 6, + "owner": "pins.tim3.ch1", + "pin": "PA6", + "port": "A", + "signal": "tim3_ch1" + }, + { + "gpio": "gpiob", + "mode": "analog", + "number": 0, + "owner": "pins.adc1.in8", + "pin": "PB0", + "port": "B", + "signal": "adc1_in8" + }, { "af": 4, "gpio": "gpiob", @@ -626,6 +870,16 @@ "port": "B", "signal": "i2c2_sda" }, + { + "af": 2, + "gpio": "gpiob", + "mode": "af", + "number": 6, + "owner": "pins.tim4.ch1", + "pin": "PB6", + "port": "B", + "signal": "tim4_ch1" + }, { "af": 4, "gpio": "gpiob", @@ -726,23 +980,23 @@ }, { "path": "boards/st/nucleo_f446re/board.yaml", - "sha256": "d756f3a7f19dc7da82ee3afc168dc54946312c5a9990720953c0fedcdece54ea" + "sha256": "551c524379751d359bdd87501269d6cab33edf84d212d2f6632ffe9567ec71d0" }, { "path": "drivers/bindings.yaml", - "sha256": "d3c336ac05548e0addd1faac18f3dff70576d8069f11d89e6a761cf5c6132b49" + "sha256": "c06d1a914adb21d0e314c79b3611ac6859eefeac1957d6914cccfc5531ad6ede" }, { "path": "examples/tasks/system.yaml", - "sha256": "3dd9de88918f06e4b3a41232cb716a9e7d1c4b74ad18e71fd51644ae394ebf9c" + "sha256": "202cff4815e97ab763dc14c61b0b694ee9381307eb46687f9caaea3465a913da" }, { "path": "soc/st/stm32f4/stm32f4.yaml", - "sha256": "3db4a0a65c9624d865d4ed7fc6354bf95054d0c465b76a2091f06aeac3d7375f" + "sha256": "796886c294250aa81151a620d80d0e43b5ee8e1bf53a07d1d7e2c62e95214dbd" }, { "path": "soc/st/stm32f4/stm32f446.yaml", - "sha256": "0d5cc7f5fce4c51be71678987720c85c6e76e05473ff8a78ea5035394316c055" + "sha256": "f0c9a37f6017c87d0efe215a3561f65494ba52383f2d0c10419b0ab5035f77f2" }, { "path": "soc/st/stm32f4/stm32f446re.yaml", @@ -753,19 +1007,49 @@ "soc": { "alternate_functions": { "PA0": { - "af8": "uart4_tx" + "af1": "tim2_ch1", + "af2": "tim5_ch1", + "af8": "uart4_tx", + "analog": "adc1_in0" }, "PA1": { - "af8": "uart4_rx" + "af1": "tim2_ch2", + "af2": "tim5_ch2", + "af8": "uart4_rx", + "analog": "adc1_in1" }, "PA10": { "af7": "usart1_rx" }, + "PA15": { + "af1": "tim2_ch1" + }, "PA2": { - "af7": "usart2_tx" + "af1": "tim2_ch3", + "af2": "tim5_ch3", + "af7": "usart2_tx", + "analog": "adc1_in2" }, "PA3": { - "af7": "usart2_rx" + "af1": "tim2_ch4", + "af2": "tim5_ch4", + "af7": "usart2_rx", + "analog": "adc1_in3" + }, + "PA4": { + "analog": "adc1_in4" + }, + "PA5": { + "af1": "tim2_ch1", + "analog": "adc1_in5" + }, + "PA6": { + "af2": "tim3_ch1", + "analog": "adc1_in6" + }, + "PA7": { + "af2": "tim3_ch2", + "analog": "adc1_in7" }, "PA8": { "af4": "i2c3_scl" @@ -773,7 +1057,16 @@ "PA9": { "af7": "usart1_tx" }, + "PB0": { + "af2": "tim3_ch3", + "analog": "adc1_in8" + }, + "PB1": { + "af2": "tim3_ch4", + "analog": "adc1_in9" + }, "PB10": { + "af1": "tim2_ch3", "af4": "i2c2_scl", "af7": "usart3_tx" }, @@ -786,26 +1079,46 @@ "PB15": { "af5": "spi2_mosi" }, + "PB2": { + "af1": "tim2_ch4" + }, "PB3": { + "af1": "tim2_ch2", "af4": "i2c2_sda" }, "PB4": { + "af2": "tim3_ch1", "af4": "i2c3_sda" }, + "PB5": { + "af2": "tim3_ch2" + }, "PB6": { + "af2": "tim4_ch1", "af4": "i2c1_scl", "af7": "usart1_tx" }, "PB7": { + "af2": "tim4_ch2", "af4": "i2c1_sda", "af7": "usart1_rx" }, "PB8": { + "af1": "tim2_ch1", + "af2": "tim4_ch3", "af4": "i2c1_scl" }, "PB9": { + "af1": "tim2_ch2", + "af2": "tim4_ch4", "af4": "i2c1_sda" }, + "PC0": { + "analog": "adc1_in10" + }, + "PC1": { + "analog": "adc1_in11" + }, "PC10": { "af7": "usart3_tx", "af8": "uart4_tx" @@ -818,16 +1131,32 @@ "af4": "i2c2_sda", "af8": "uart5_tx" }, + "PC2": { + "analog": "adc1_in12" + }, + "PC3": { + "analog": "adc1_in13" + }, + "PC4": { + "analog": "adc1_in14" + }, "PC5": { - "af7": "usart3_rx" + "af7": "usart3_rx", + "analog": "adc1_in15" }, "PC6": { + "af2": "tim3_ch1", "af8": "usart6_tx" }, "PC7": { + "af2": "tim3_ch2", "af8": "usart6_rx" }, + "PC8": { + "af2": "tim3_ch3" + }, "PC9": { + "af2": "tim3_ch4", "af4": "i2c3_sda" }, "PD2": { @@ -956,6 +1285,7 @@ "name": "lse" } ], + "timers_double_when_divided": true, "voltage_scales": [ { "max_hz": 120000000, @@ -1097,12 +1427,24 @@ "part": "STM32F446RE", "peripherals": [ { + "adc": { + "bits": 12, + "inputs": 16, + "temperature": 18, + "vrefint": 17 + }, "base": 1073815552, "clock": { "bit": 8, "bus": "apb2" }, "compatible": "st,stm32f4-adc", + "dma_requests": { + "rx": [ + "dma2.s0c0", + "dma2.s4c0" + ] + }, "irqs": [ { "name": "global", @@ -1277,12 +1619,14 @@ "size": 1024 }, { + "adc_trigger": 6, "base": 1073741824, "clock": { "bit": 0, "bus": "apb1" }, "compatible": "st,stm32-tim", + "counter_bits": 32, "irqs": [ { "name": "global", @@ -1292,6 +1636,76 @@ "name": "tim2", "size": 1024 }, + { + "adc_trigger": 8, + "base": 1073742848, + "clock": { + "bit": 1, + "bus": "apb1" + }, + "compatible": "st,stm32-tim", + "counter_bits": 16, + "irqs": [ + { + "name": "global", + "number": 29 + } + ], + "name": "tim3", + "size": 1024 + }, + { + "base": 1073743872, + "clock": { + "bit": 2, + "bus": "apb1" + }, + "compatible": "st,stm32-tim", + "counter_bits": 16, + "irqs": [ + { + "name": "global", + "number": 30 + } + ], + "name": "tim4", + "size": 1024 + }, + { + "base": 1073744896, + "clock": { + "bit": 3, + "bus": "apb1" + }, + "compatible": "st,stm32-tim", + "counter_bits": 32, + "irqs": [ + { + "name": "global", + "number": 50 + } + ], + "name": "tim5", + "size": 1024 + }, + { + "base": 1073823744, + "clock": { + "bit": 16, + "bus": "apb2" + }, + "compatible": "st,stm32-tim", + "counter_bits": 16, + "irqs": [ + { + "name": "global", + "number": 24 + } + ], + "name": "tim9", + "size": 1024, + "timer_channels": 2 + }, { "base": 1073897472, "clock": { diff --git a/examples/tasks/generated/.base/nucleo_f446re/docs/system.json b/examples/tasks/src/config/nucleo_f446re/docs/system.json similarity index 77% rename from examples/tasks/generated/.base/nucleo_f446re/docs/system.json rename to examples/tasks/src/config/nucleo_f446re/docs/system.json index ac0af49a..70f65362 100644 --- a/examples/tasks/generated/.base/nucleo_f446re/docs/system.json +++ b/examples/tasks/src/config/nucleo_f446re/docs/system.json @@ -25,29 +25,39 @@ }, { "path": "boards/st/nucleo_f446re/board.yaml", - "sha256": "d756f3a7f19dc7da82ee3afc168dc54946312c5a9990720953c0fedcdece54ea" + "sha256": "551c524379751d359bdd87501269d6cab33edf84d212d2f6632ffe9567ec71d0" }, { "path": "drivers/bindings.yaml", - "sha256": "d3c336ac05548e0addd1faac18f3dff70576d8069f11d89e6a761cf5c6132b49" + "sha256": "c06d1a914adb21d0e314c79b3611ac6859eefeac1957d6914cccfc5531ad6ede" }, { "path": "examples/tasks/system.yaml", - "sha256": "3dd9de88918f06e4b3a41232cb716a9e7d1c4b74ad18e71fd51644ae394ebf9c" + "sha256": "202cff4815e97ab763dc14c61b0b694ee9381307eb46687f9caaea3465a913da" }, { "path": "soc/st/stm32f4/stm32f4.yaml", - "sha256": "3db4a0a65c9624d865d4ed7fc6354bf95054d0c465b76a2091f06aeac3d7375f" + "sha256": "796886c294250aa81151a620d80d0e43b5ee8e1bf53a07d1d7e2c62e95214dbd" }, { "path": "soc/st/stm32f4/stm32f446.yaml", - "sha256": "0d5cc7f5fce4c51be71678987720c85c6e76e05473ff8a78ea5035394316c055" + "sha256": "f0c9a37f6017c87d0efe215a3561f65494ba52383f2d0c10419b0ab5035f77f2" }, { "path": "soc/st/stm32f4/stm32f446re.yaml", "sha256": "b9a88d0a94aa17ee83317a3a56f7c194ec1b3107dfb3e82e453122dc1c48f6d4" } ], + "interrupts": [ + { + "doc": "", + "handler": "WAKE_InterruptHandler", + "irq": 61, + "level": 1, + "name": "wake", + "source": null + } + ], "name": "tasks_demo", "objects": [], "profile": "base", @@ -56,7 +66,6 @@ "spi_targets": [], "tasks": [ { - "data": "door_data_t", "doc": "", "entry": [ "open" @@ -87,7 +96,6 @@ } }, { - "data": null, "doc": "", "entry": [], "event": null, diff --git a/examples/tasks/src/config/nucleo_f446re/docs/system.md b/examples/tasks/src/config/nucleo_f446re/docs/system.md new file mode 100644 index 00000000..cbd31305 --- /dev/null +++ b/examples/tasks/src/config/nucleo_f446re/docs/system.md @@ -0,0 +1,30 @@ +# tasks_demo: the system on nucleo_f446re + +Generated from `examples/tasks/system.yaml` (SPEC-014 §5, A125, A130). Profile base, 32 priorities, a minimum stack of 256 bytes. + +## Tasks + +| Task | Model | Priority | Stack | States (initial first) | Events | +|---|---|---|---|---|---| +| `door` | event, queue 8 | 5 | 1024 | closed, open, jammed | open, close, jam | +| `blink` | periodic, 500 ms | 2 | 512 | dark, lit | — | + +## Interrupts + +| Interrupt | Line | Handler | Level | +|---|---|---|---| +| `wake` | 61 | `WAKE_InterruptHandler` | 1 | + +--- + +Generated by emb-hwgen 0.1.0, schema v0, from: + +| Input | SHA-256 | +|---|---| +| `arch/cortex_m/arch.yaml` | `c5c8e451c09717dee1713d07f8311b6d507e3b4c66c42d93e0ce11da6ec76d6d` | +| `boards/st/nucleo_f446re/board.yaml` | `551c524379751d359bdd87501269d6cab33edf84d212d2f6632ffe9567ec71d0` | +| `drivers/bindings.yaml` | `c06d1a914adb21d0e314c79b3611ac6859eefeac1957d6914cccfc5531ad6ede` | +| `examples/tasks/system.yaml` | `202cff4815e97ab763dc14c61b0b694ee9381307eb46687f9caaea3465a913da` | +| `soc/st/stm32f4/stm32f4.yaml` | `796886c294250aa81151a620d80d0e43b5ee8e1bf53a07d1d7e2c62e95214dbd` | +| `soc/st/stm32f4/stm32f446.yaml` | `f0c9a37f6017c87d0efe215a3561f65494ba52383f2d0c10419b0ab5035f77f2` | +| `soc/st/stm32f4/stm32f446re.yaml` | `b9a88d0a94aa17ee83317a3a56f7c194ec1b3107dfb3e82e453122dc1c48f6d4` | diff --git a/examples/tasks/src/config/nucleo_f446re/initialization.c b/examples/tasks/src/config/nucleo_f446re/initialization.c new file mode 100644 index 00000000..45e6f898 --- /dev/null +++ b/examples/tasks/src/config/nucleo_f446re/initialization.c @@ -0,0 +1,85 @@ +/* SPDX-License-Identifier: Apache-2.0 */ +/* + * This file is part of EmbLinkRTOS, a deterministic real-time kernel for microcontrollers. + * Licensed under the Apache License, Version 2.0; see the LICENSE file at the repository root. + */ + +/******************************************************************************* + System Initialization File + + File Name: + initialization.c + + Summary: + tasks_demo's initialization on the nucleo_f446re: SYS_Initialize(), and the + system's objects. + + Description: + The system's static definitions, which the kernel creates from its + initialization table when emb_kernel_init() runs (SPEC-001 §6.4), and + SYS_Initialize(), which brings up the board, the kernel, the application's + interrupts and the tasks. + + Generated by emb-hwgen 0.1.0, schema v0, from the system description and the + nucleo_f446re's. Yours to edit: regenerating merges its changes with yours + (A126): + hw/gen/emb-hwgen.py generate --system examples/tasks/system.yaml + + Inputs (SHA-256): + arch/cortex_m/arch.yaml + c5c8e451c09717dee1713d07f8311b6d507e3b4c66c42d93e0ce11da6ec76d6d + boards/st/nucleo_f446re/board.yaml + 551c524379751d359bdd87501269d6cab33edf84d212d2f6632ffe9567ec71d0 + drivers/bindings.yaml + c06d1a914adb21d0e314c79b3611ac6859eefeac1957d6914cccfc5531ad6ede + examples/tasks/system.yaml + 202cff4815e97ab763dc14c61b0b694ee9381307eb46687f9caaea3465a913da + soc/st/stm32f4/stm32f4.yaml + 796886c294250aa81151a620d80d0e43b5ee8e1bf53a07d1d7e2c62e95214dbd + soc/st/stm32f4/stm32f446.yaml + f0c9a37f6017c87d0efe215a3561f65494ba52383f2d0c10419b0ab5035f77f2 + soc/st/stm32f4/stm32f446re.yaml + b9a88d0a94aa17ee83317a3a56f7c194ec1b3107dfb3e82e453122dc1c48f6d4 + *******************************************************************************/ + +// ***************************************************************************** +// ***************************************************************************** +// Section: Included Files +// ***************************************************************************** +// ***************************************************************************** + +#include "definitions.h" + +// ***************************************************************************** +// ***************************************************************************** +// Section: System Initialization +// ***************************************************************************** +// ***************************************************************************** + +/******************************************************************************* + Function: + void SYS_Initialize ( void *data ) + + Remarks: + See prototype in definitions.h. + */ +void SYS_Initialize(void *data) +{ + (void)data; + + /* The board: its clocks, pins and console */ + emb_board_init(); + + /* The kernel: its objects, and the EARLY devices */ + emb_kernel_init(); + + /* The application's interrupts */ + SYS_INT_Initialize(); + + /* The tasks, each in its initial state */ + DOOR_Initialize(); + BLINK_Initialize(); +} +/******************************************************************************* + End of File +*/ diff --git a/examples/tasks/src/config/nucleo_f446re/interrupts.c b/examples/tasks/src/config/nucleo_f446re/interrupts.c new file mode 100644 index 00000000..d884d59f --- /dev/null +++ b/examples/tasks/src/config/nucleo_f446re/interrupts.c @@ -0,0 +1,114 @@ +/* SPDX-License-Identifier: Apache-2.0 */ +/* + * This file is part of EmbLinkRTOS, a deterministic real-time kernel for microcontrollers. + * Licensed under the Apache License, Version 2.0; see the LICENSE file at the repository root. + */ + +/******************************************************************************* + Interrupt Handlers + + File Name: + interrupts.c + + Summary: + tasks_demo's interrupts on the nucleo_f446re: the lines in use, and + SYS_INT_Initialize(). + + Description: + The table of every interrupt line in use, the devices' and the + application's, and SYS_INT_Initialize(), which connects the application's + handlers. The checks were made when it was generated: each line is the + SoC's, no device's driver connects it, and its level is the port's. + + Generated by emb-hwgen 0.1.0, schema v0, from the system description and the + nucleo_f446re's. Yours to edit: regenerating merges its changes with yours + (A126): + hw/gen/emb-hwgen.py generate --system examples/tasks/system.yaml + + Inputs (SHA-256): + arch/cortex_m/arch.yaml + c5c8e451c09717dee1713d07f8311b6d507e3b4c66c42d93e0ce11da6ec76d6d + boards/st/nucleo_f446re/board.yaml + 551c524379751d359bdd87501269d6cab33edf84d212d2f6632ffe9567ec71d0 + drivers/bindings.yaml + c06d1a914adb21d0e314c79b3611ac6859eefeac1957d6914cccfc5531ad6ede + examples/tasks/system.yaml + 202cff4815e97ab763dc14c61b0b694ee9381307eb46687f9caaea3465a913da + soc/st/stm32f4/stm32f4.yaml + 796886c294250aa81151a620d80d0e43b5ee8e1bf53a07d1d7e2c62e95214dbd + soc/st/stm32f4/stm32f446.yaml + f0c9a37f6017c87d0efe215a3561f65494ba52383f2d0c10419b0ab5035f77f2 + soc/st/stm32f4/stm32f446re.yaml + b9a88d0a94aa17ee83317a3a56f7c194ec1b3107dfb3e82e453122dc1c48f6d4 + *******************************************************************************/ + +// ***************************************************************************** +// ***************************************************************************** +// Section: Included Files +// ***************************************************************************** +// ***************************************************************************** + +#include "definitions.h" + +// ***************************************************************************** +// ***************************************************************************** +// Section: Interrupt Lines +// ***************************************************************************** +// ***************************************************************************** + +/* The lines in use on the nucleo_f446re: + * 11 dma1, its driver (peripheral.irqs.s0) + * 12 dma1, its driver (peripheral.irqs.s1) + * 13 dma1, its driver (peripheral.irqs.s2) + * 14 dma1, its driver (peripheral.irqs.s3) + * 15 dma1, its driver (peripheral.irqs.s4) + * 16 dma1, its driver (peripheral.irqs.s5) + * 17 dma1, its driver (peripheral.irqs.s6) + * 18 adc1, its driver (peripheral.irqs.global) + * 24 tim9, its driver (peripheral.irqs.global) + * 29 tim3, its driver (peripheral.irqs.global) + * 30 tim4, its driver (peripheral.irqs.global) + * 31 i2c1, its driver (peripheral.irqs.ev) + * 32 i2c1, its driver (peripheral.irqs.er) + * 33 i2c2, its driver (peripheral.irqs.ev) + * 34 i2c2, its driver (peripheral.irqs.er) + * 36 spi2, its driver (peripheral.irqs.global) + * 38 usart2, its driver (peripheral.irqs.global) + * 41 rtc, its driver (peripheral.irqs.alarm) + * 47 dma1, its driver (peripheral.irqs.s7) + * 50 tim5, its driver (peripheral.irqs.global) + * 52 uart4, its driver (peripheral.irqs.global) + * 56 dma2, its driver (peripheral.irqs.s0) + * 57 dma2, its driver (peripheral.irqs.s1) + * 58 dma2, its driver (peripheral.irqs.s2) + * 59 dma2, its driver (peripheral.irqs.s3) + * 60 dma2, its driver (peripheral.irqs.s4) + * 61 wake, the application's WAKE_InterruptHandler() + * 68 dma2, its driver (peripheral.irqs.s5) + * 69 dma2, its driver (peripheral.irqs.s6) + * 70 dma2, its driver (peripheral.irqs.s7) + */ + +// ***************************************************************************** +// ***************************************************************************** +// Section: Interrupt Initialization +// ***************************************************************************** +// ***************************************************************************** + +/******************************************************************************* + Function: + void SYS_INT_Initialize ( void ) + + Remarks: + See prototype in interrupts.h. + */ +void SYS_INT_Initialize(void) +{ + /* wake: line 61 */ + (void)emb_irq_connect(WAKE_IRQ, WAKE_InterruptHandler, NULL); + (void)emb_irq_set_level(WAKE_IRQ, WAKE_IRQ_LEVEL); + (void)emb_irq_enable(WAKE_IRQ); +} +/******************************************************************************* + End of File +*/ diff --git a/examples/tasks/src/config/nucleo_f446re/interrupts.h b/examples/tasks/src/config/nucleo_f446re/interrupts.h new file mode 100644 index 00000000..4a1ef2f0 --- /dev/null +++ b/examples/tasks/src/config/nucleo_f446re/interrupts.h @@ -0,0 +1,133 @@ +/* SPDX-License-Identifier: Apache-2.0 */ +/* + * This file is part of EmbLinkRTOS, a deterministic real-time kernel for microcontrollers. + * Licensed under the Apache License, Version 2.0; see the LICENSE file at the repository root. + */ + +/******************************************************************************* + Interrupt Handlers + + File Name: + interrupts.h + + Summary: + tasks_demo's interrupt handlers on the nucleo_f446re. + + Description: + The application's own interrupt handlers, which it defines + (src/interrupt_handlers.c), and SYS_INT_Initialize(), which connects each at + its level and enables it. The board's devices connect their own: + interrupts.c lists every line in use. + + Generated by emb-hwgen 0.1.0, schema v0, from the system description and the + nucleo_f446re's. Yours to edit: regenerating merges its changes with yours + (A126): + hw/gen/emb-hwgen.py generate --system examples/tasks/system.yaml + + Inputs (SHA-256): + arch/cortex_m/arch.yaml + c5c8e451c09717dee1713d07f8311b6d507e3b4c66c42d93e0ce11da6ec76d6d + boards/st/nucleo_f446re/board.yaml + 551c524379751d359bdd87501269d6cab33edf84d212d2f6632ffe9567ec71d0 + drivers/bindings.yaml + c06d1a914adb21d0e314c79b3611ac6859eefeac1957d6914cccfc5531ad6ede + examples/tasks/system.yaml + 202cff4815e97ab763dc14c61b0b694ee9381307eb46687f9caaea3465a913da + soc/st/stm32f4/stm32f4.yaml + 796886c294250aa81151a620d80d0e43b5ee8e1bf53a07d1d7e2c62e95214dbd + soc/st/stm32f4/stm32f446.yaml + f0c9a37f6017c87d0efe215a3561f65494ba52383f2d0c10419b0ab5035f77f2 + soc/st/stm32f4/stm32f446re.yaml + b9a88d0a94aa17ee83317a3a56f7c194ec1b3107dfb3e82e453122dc1c48f6d4 + *******************************************************************************/ + +#ifndef INTERRUPTS_H +#define INTERRUPTS_H + +// ***************************************************************************** +// ***************************************************************************** +// Section: Included Files +// ***************************************************************************** +// ***************************************************************************** + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +// ***************************************************************************** +// ***************************************************************************** +// Section: Handler Routines +// ***************************************************************************** +// ***************************************************************************** + +/******************************************************************************* + Function: + void WAKE_InterruptHandler ( void *arg ) + + Summary: + The wake interrupt's handler. + + Description: + This function runs in interrupt context when line 61 is raised at level 1: a + kernel-aware handler, which may post to a task (emb_task_post()) but not + wait. + + Precondition: + SYS_INT_Initialize() has connected it. + + Parameters: + arg - Unused; NULL. + + Returns: + None. + + Example: + + emb_irq_pend(WAKE_IRQ); + + + Remarks: + The application defines it. Keep it short: hand the work to a task. +*/ +void WAKE_InterruptHandler(void *arg); + +/******************************************************************************* + Function: + void SYS_INT_Initialize ( void ) + + Summary: + Connects the application's interrupt handlers. + + Description: + This function connects each of the application's handlers to its line, sets + its level and enables it. + + Precondition: + The kernel is initialized (emb_kernel_init()). + + Parameters: + None. + + Returns: + None. + + Example: + + SYS_INT_Initialize(); + + + Remarks: + SYS_Initialize() calls it. +*/ +void SYS_INT_Initialize(void); + +#ifdef __cplusplus +} +#endif + +#endif /* INTERRUPTS_H */ +/******************************************************************************* + End of File +*/ diff --git a/examples/tasks/generated/nucleo_f446re/linker/regions.ld b/examples/tasks/src/config/nucleo_f446re/linker/regions.ld similarity index 91% rename from examples/tasks/generated/nucleo_f446re/linker/regions.ld rename to examples/tasks/src/config/nucleo_f446re/linker/regions.ld index d4165395..b2d8c609 100644 --- a/examples/tasks/generated/nucleo_f446re/linker/regions.ld +++ b/examples/tasks/src/config/nucleo_f446re/linker/regions.ld @@ -17,15 +17,15 @@ * arch/cortex_m/arch.yaml * c5c8e451c09717dee1713d07f8311b6d507e3b4c66c42d93e0ce11da6ec76d6d * boards/st/nucleo_f446re/board.yaml - * d756f3a7f19dc7da82ee3afc168dc54946312c5a9990720953c0fedcdece54ea + * 551c524379751d359bdd87501269d6cab33edf84d212d2f6632ffe9567ec71d0 * drivers/bindings.yaml - * d3c336ac05548e0addd1faac18f3dff70576d8069f11d89e6a761cf5c6132b49 + * c06d1a914adb21d0e314c79b3611ac6859eefeac1957d6914cccfc5531ad6ede * examples/tasks/system.yaml - * 3dd9de88918f06e4b3a41232cb716a9e7d1c4b74ad18e71fd51644ae394ebf9c + * 202cff4815e97ab763dc14c61b0b694ee9381307eb46687f9caaea3465a913da * soc/st/stm32f4/stm32f4.yaml - * 3db4a0a65c9624d865d4ed7fc6354bf95054d0c465b76a2091f06aeac3d7375f + * 796886c294250aa81151a620d80d0e43b5ee8e1bf53a07d1d7e2c62e95214dbd * soc/st/stm32f4/stm32f446.yaml - * 0d5cc7f5fce4c51be71678987720c85c6e76e05473ff8a78ea5035394316c055 + * f0c9a37f6017c87d0efe215a3561f65494ba52383f2d0c10419b0ab5035f77f2 * soc/st/stm32f4/stm32f446re.yaml * b9a88d0a94aa17ee83317a3a56f7c194ec1b3107dfb3e82e453122dc1c48f6d4 */ diff --git a/examples/tasks/generated/nucleo_f446re/src/board_pins.c b/examples/tasks/src/config/nucleo_f446re/peripheral/board_pins.c similarity index 77% rename from examples/tasks/generated/nucleo_f446re/src/board_pins.c rename to examples/tasks/src/config/nucleo_f446re/peripheral/board_pins.c index 8410a389..d26df417 100644 --- a/examples/tasks/generated/nucleo_f446re/src/board_pins.c +++ b/examples/tasks/src/config/nucleo_f446re/peripheral/board_pins.c @@ -16,15 +16,15 @@ * arch/cortex_m/arch.yaml * c5c8e451c09717dee1713d07f8311b6d507e3b4c66c42d93e0ce11da6ec76d6d * boards/st/nucleo_f446re/board.yaml - * d756f3a7f19dc7da82ee3afc168dc54946312c5a9990720953c0fedcdece54ea + * 551c524379751d359bdd87501269d6cab33edf84d212d2f6632ffe9567ec71d0 * drivers/bindings.yaml - * d3c336ac05548e0addd1faac18f3dff70576d8069f11d89e6a761cf5c6132b49 + * c06d1a914adb21d0e314c79b3611ac6859eefeac1957d6914cccfc5531ad6ede * examples/tasks/system.yaml - * 3dd9de88918f06e4b3a41232cb716a9e7d1c4b74ad18e71fd51644ae394ebf9c + * 202cff4815e97ab763dc14c61b0b694ee9381307eb46687f9caaea3465a913da * soc/st/stm32f4/stm32f4.yaml - * 3db4a0a65c9624d865d4ed7fc6354bf95054d0c465b76a2091f06aeac3d7375f + * 796886c294250aa81151a620d80d0e43b5ee8e1bf53a07d1d7e2c62e95214dbd * soc/st/stm32f4/stm32f446.yaml - * 0d5cc7f5fce4c51be71678987720c85c6e76e05473ff8a78ea5035394316c055 + * f0c9a37f6017c87d0efe215a3561f65494ba52383f2d0c10419b0ab5035f77f2 * soc/st/stm32f4/stm32f446re.yaml * b9a88d0a94aa17ee83317a3a56f7c194ec1b3107dfb3e82e453122dc1c48f6d4 */ @@ -40,10 +40,18 @@ const emb_stm32_pin_t emb_board_pins[] = { {EMB_STM32_PORT(A), 2u, EMB_STM32_PIN_AF, 7u, 0u, 0u}, /* PA3: pins.usart2.rx (usart2_rx) */ {EMB_STM32_PORT(A), 3u, EMB_STM32_PIN_AF, 7u, 0u, 0u}, + /* PA4: pins.adc1.in4 (adc1_in4) */ + {EMB_STM32_PORT(A), 4u, EMB_STM32_PIN_ANALOG, 0u, 0u, 0u}, /* PA5: leds.user (output) */ {EMB_STM32_PORT(A), 5u, EMB_STM32_PIN_OUTPUT, 0u, 0u, 0u}, + /* PA6: pins.tim3.ch1 (tim3_ch1) */ + {EMB_STM32_PORT(A), 6u, EMB_STM32_PIN_AF, 2u, 0u, 0u}, + /* PB0: pins.adc1.in8 (adc1_in8) */ + {EMB_STM32_PORT(B), 0u, EMB_STM32_PIN_ANALOG, 0u, 0u, 0u}, /* PB3: pins.i2c2.sda (i2c2_sda) */ {EMB_STM32_PORT(B), 3u, EMB_STM32_PIN_AF, 4u, 0u, EMB_STM32_PIN_I2C}, + /* PB6: pins.tim4.ch1 (tim4_ch1) */ + {EMB_STM32_PORT(B), 6u, EMB_STM32_PIN_AF, 2u, 0u, 0u}, /* PB8: pins.i2c1.scl (i2c1_scl) */ {EMB_STM32_PORT(B), 8u, EMB_STM32_PIN_AF, 4u, 0u, EMB_STM32_PIN_I2C}, /* PB9: pins.i2c1.sda (i2c1_sda) */ diff --git a/examples/tasks/generated/nucleo_f446re/include/hw_config.h b/examples/tasks/src/config/nucleo_f446re/peripheral/hw_config.h similarity index 89% rename from examples/tasks/generated/nucleo_f446re/include/hw_config.h rename to examples/tasks/src/config/nucleo_f446re/peripheral/hw_config.h index b68e5325..8bc74ae4 100644 --- a/examples/tasks/generated/nucleo_f446re/include/hw_config.h +++ b/examples/tasks/src/config/nucleo_f446re/peripheral/hw_config.h @@ -15,15 +15,15 @@ * arch/cortex_m/arch.yaml * c5c8e451c09717dee1713d07f8311b6d507e3b4c66c42d93e0ce11da6ec76d6d * boards/st/nucleo_f446re/board.yaml - * d756f3a7f19dc7da82ee3afc168dc54946312c5a9990720953c0fedcdece54ea + * 551c524379751d359bdd87501269d6cab33edf84d212d2f6632ffe9567ec71d0 * drivers/bindings.yaml - * d3c336ac05548e0addd1faac18f3dff70576d8069f11d89e6a761cf5c6132b49 + * c06d1a914adb21d0e314c79b3611ac6859eefeac1957d6914cccfc5531ad6ede * examples/tasks/system.yaml - * 3dd9de88918f06e4b3a41232cb716a9e7d1c4b74ad18e71fd51644ae394ebf9c + * 202cff4815e97ab763dc14c61b0b694ee9381307eb46687f9caaea3465a913da * soc/st/stm32f4/stm32f4.yaml - * 3db4a0a65c9624d865d4ed7fc6354bf95054d0c465b76a2091f06aeac3d7375f + * 796886c294250aa81151a620d80d0e43b5ee8e1bf53a07d1d7e2c62e95214dbd * soc/st/stm32f4/stm32f446.yaml - * 0d5cc7f5fce4c51be71678987720c85c6e76e05473ff8a78ea5035394316c055 + * f0c9a37f6017c87d0efe215a3561f65494ba52383f2d0c10419b0ab5035f77f2 * soc/st/stm32f4/stm32f446re.yaml * b9a88d0a94aa17ee83317a3a56f7c194ec1b3107dfb3e82e453122dc1c48f6d4 */ @@ -166,6 +166,22 @@ #define EMB_HW_TIM2_CLKEN_BIT 0u #define EMB_HW_TIM2_CLKEN_OFFSET 0x40u #define EMB_HW_TIM2_IRQ 28u +#define EMB_HW_TIM3_BASE 0x40000400u +#define EMB_HW_TIM3_CLKEN_BIT 1u +#define EMB_HW_TIM3_CLKEN_OFFSET 0x40u +#define EMB_HW_TIM3_IRQ 29u +#define EMB_HW_TIM4_BASE 0x40000800u +#define EMB_HW_TIM4_CLKEN_BIT 2u +#define EMB_HW_TIM4_CLKEN_OFFSET 0x40u +#define EMB_HW_TIM4_IRQ 30u +#define EMB_HW_TIM5_BASE 0x40000C00u +#define EMB_HW_TIM5_CLKEN_BIT 3u +#define EMB_HW_TIM5_CLKEN_OFFSET 0x40u +#define EMB_HW_TIM5_IRQ 50u +#define EMB_HW_TIM9_BASE 0x40014000u +#define EMB_HW_TIM9_CLKEN_BIT 16u +#define EMB_HW_TIM9_CLKEN_OFFSET 0x44u +#define EMB_HW_TIM9_IRQ 24u #define EMB_HW_UART4_BASE 0x40004C00u #define EMB_HW_UART4_CLKEN_BIT 19u #define EMB_HW_UART4_CLKEN_OFFSET 0x40u diff --git a/examples/tasks/generated/nucleo_f446re/src/soc_devices.c b/examples/tasks/src/config/nucleo_f446re/peripheral/soc_devices.c similarity index 63% rename from examples/tasks/generated/nucleo_f446re/src/soc_devices.c rename to examples/tasks/src/config/nucleo_f446re/peripheral/soc_devices.c index daf00c71..be35801d 100644 --- a/examples/tasks/generated/nucleo_f446re/src/soc_devices.c +++ b/examples/tasks/src/config/nucleo_f446re/peripheral/soc_devices.c @@ -16,15 +16,15 @@ * arch/cortex_m/arch.yaml * c5c8e451c09717dee1713d07f8311b6d507e3b4c66c42d93e0ce11da6ec76d6d * boards/st/nucleo_f446re/board.yaml - * d756f3a7f19dc7da82ee3afc168dc54946312c5a9990720953c0fedcdece54ea + * 551c524379751d359bdd87501269d6cab33edf84d212d2f6632ffe9567ec71d0 * drivers/bindings.yaml - * d3c336ac05548e0addd1faac18f3dff70576d8069f11d89e6a761cf5c6132b49 + * c06d1a914adb21d0e314c79b3611ac6859eefeac1957d6914cccfc5531ad6ede * examples/tasks/system.yaml - * 3dd9de88918f06e4b3a41232cb716a9e7d1c4b74ad18e71fd51644ae394ebf9c + * 202cff4815e97ab763dc14c61b0b694ee9381307eb46687f9caaea3465a913da * soc/st/stm32f4/stm32f4.yaml - * 3db4a0a65c9624d865d4ed7fc6354bf95054d0c465b76a2091f06aeac3d7375f + * 796886c294250aa81151a620d80d0e43b5ee8e1bf53a07d1d7e2c62e95214dbd * soc/st/stm32f4/stm32f446.yaml - * 0d5cc7f5fce4c51be71678987720c85c6e76e05473ff8a78ea5035394316c055 + * f0c9a37f6017c87d0efe215a3561f65494ba52383f2d0c10419b0ab5035f77f2 * soc/st/stm32f4/stm32f446re.yaml * b9a88d0a94aa17ee83317a3a56f7c194ec1b3107dfb3e82e453122dc1c48f6d4 */ @@ -168,6 +168,36 @@ const emb_device_t emb_dev_dma1 = { .dep_count = 1u, }; +/* dma2: st,stm32-dma, dma, EARLY */ +static const emb_stm32_dma_config_t dma2_config = { + .base = 0x40026400u, /* peripheral.base */ + .clken_offset = 0x00000030u, /* peripheral.clock.enable_offset */ + .clken_bit = 22u, /* peripheral.clock.bit */ + .irq0 = 56u, /* peripheral.irqs.s0 */ + .irq1 = 57u, /* peripheral.irqs.s1 */ + .irq2 = 58u, /* peripheral.irqs.s2 */ + .irq3 = 59u, /* peripheral.irqs.s3 */ + .irq4 = 60u, /* peripheral.irqs.s4 */ + .irq5 = 68u, /* peripheral.irqs.s5 */ + .irq6 = 69u, /* peripheral.irqs.s6 */ + .irq7 = 70u, /* peripheral.irqs.s7 */ + .memory = true, /* peripheral.dma.memory */ +}; +static emb_device_state_t dma2_state; +static emb_stm32_dma_data_t dma2_data; +static const emb_device_t *const dma2_deps[] = {&emb_dev_rcc}; +const emb_device_t emb_dev_dma2 = { + .name = "dma2", + .api = &emb_stm32_dma_api.dev, + .config = &dma2_config, + .state = &dma2_state, + .data = &dma2_data, + .deps = dma2_deps, + .class_id = EMB_DRV_CLASS_DMA, + .level = EMB_DEVICE_EARLY, + .dep_count = 1u, +}; + /* gpiob: st,stm32-gpio, gpio, EARLY */ static const emb_stm32_gpio_config_t gpiob_config = { .base = 0x40020400u, /* peripheral.base */ @@ -341,6 +371,144 @@ const emb_device_t emb_dev_i2c2 = { .dep_count = 1u, }; +/* tim5: st,stm32-tim, counter, KERNEL */ +static const emb_stm32_tim_config_t tim5_config = { + .base = 0x40000C00u, /* peripheral.base */ + .clock_hz = 90000000u, /* peripheral.timer_clock_hz */ + .rate_hz = 1000000u, /* device.rate_hz, its default */ + .clken_offset = 0x00000040u, /* peripheral.clock.enable_offset */ + .clken_bit = 3u, /* peripheral.clock.bit */ + .irq = 50u, /* peripheral.irqs.global */ + .bits = 32u, /* peripheral.counter_bits */ + .channels = 4u, /* peripheral.timer_channels, its default */ +}; +static emb_device_state_t tim5_state; +static emb_stm32_counter_data_t tim5_data; +static const emb_device_t *const tim5_deps[] = {&emb_dev_rcc}; +const emb_device_t emb_dev_tim5 = { + .name = "tim5", + .api = &emb_stm32_counter_api.dev, + .config = &tim5_config, + .state = &tim5_state, + .data = &tim5_data, + .deps = tim5_deps, + .class_id = EMB_DRV_CLASS_COUNTER, + .level = EMB_DEVICE_KERNEL, + .dep_count = 1u, +}; + +/* tim9: st,stm32-tim, counter, KERNEL */ +static const emb_stm32_tim_config_t tim9_config = { + .base = 0x40014000u, /* peripheral.base */ + .clock_hz = 180000000u, /* peripheral.timer_clock_hz */ + .rate_hz = 1000000u, /* device.rate_hz, its default */ + .clken_offset = 0x00000044u, /* peripheral.clock.enable_offset */ + .clken_bit = 16u, /* peripheral.clock.bit */ + .irq = 24u, /* peripheral.irqs.global */ + .bits = 16u, /* peripheral.counter_bits */ + .channels = 2u, /* peripheral.timer_channels */ +}; +static emb_device_state_t tim9_state; +static emb_stm32_counter_data_t tim9_data; +static const emb_device_t *const tim9_deps[] = {&emb_dev_rcc}; +const emb_device_t emb_dev_tim9 = { + .name = "tim9", + .api = &emb_stm32_counter_api.dev, + .config = &tim9_config, + .state = &tim9_state, + .data = &tim9_data, + .deps = tim9_deps, + .class_id = EMB_DRV_CLASS_COUNTER, + .level = EMB_DEVICE_KERNEL, + .dep_count = 1u, +}; + +/* tim3: st,stm32-tim, pwm, KERNEL */ +static const emb_stm32_tim_config_t tim3_config = { + .base = 0x40000400u, /* peripheral.base */ + .clock_hz = 90000000u, /* peripheral.timer_clock_hz */ + .clken_offset = 0x00000040u, /* peripheral.clock.enable_offset */ + .clken_bit = 1u, /* peripheral.clock.bit */ + .irq = 29u, /* peripheral.irqs.global */ + .bits = 16u, /* peripheral.counter_bits */ + .channels = 4u, /* peripheral.timer_channels, its default */ +}; +static emb_device_state_t tim3_state; +static emb_stm32_pwm_data_t tim3_data; +static const emb_device_t *const tim3_deps[] = {&emb_dev_rcc}; +const emb_device_t emb_dev_tim3 = { + .name = "tim3", + .api = &emb_stm32_pwm_api.dev, + .config = &tim3_config, + .state = &tim3_state, + .data = &tim3_data, + .deps = tim3_deps, + .class_id = EMB_DRV_CLASS_PWM, + .level = EMB_DEVICE_KERNEL, + .dep_count = 1u, +}; + +/* tim4: st,stm32-tim, pwm, KERNEL */ +static const emb_stm32_tim_config_t tim4_config = { + .base = 0x40000800u, /* peripheral.base */ + .clock_hz = 90000000u, /* peripheral.timer_clock_hz */ + .clken_offset = 0x00000040u, /* peripheral.clock.enable_offset */ + .clken_bit = 2u, /* peripheral.clock.bit */ + .irq = 30u, /* peripheral.irqs.global */ + .bits = 16u, /* peripheral.counter_bits */ + .channels = 4u, /* peripheral.timer_channels, its default */ +}; +static emb_device_state_t tim4_state; +static emb_stm32_pwm_data_t tim4_data; +static const emb_device_t *const tim4_deps[] = {&emb_dev_rcc}; +const emb_device_t emb_dev_tim4 = { + .name = "tim4", + .api = &emb_stm32_pwm_api.dev, + .config = &tim4_config, + .state = &tim4_state, + .data = &tim4_data, + .deps = tim4_deps, + .class_id = EMB_DRV_CLASS_PWM, + .level = EMB_DEVICE_KERNEL, + .dep_count = 1u, +}; + +/* adc1: st,stm32f4-adc, adc, KERNEL */ +static const emb_stm32_adc_config_t adc1_config = { + .base = 0x40012000u, /* peripheral.base */ + .common = 0x40012300u, /* takes.common.base */ + .calibration = 0x1FFF7A2Au, /* takes.cal.base */ + .trigger = 0x40000000u, /* takes.trigger.base */ + .trigger_hz = 90000000u, /* takes.trigger.timer_clock_hz */ + .trigger_clken_offset = 0x00000040u, /* takes.trigger.clock.enable_offset */ + .trigger_clken_bit = 0u, /* takes.trigger.clock.bit */ + .trigger_select = 6u, /* takes.trigger.adc_trigger */ + .clock_hz = 90000000u, /* peripheral.clock_hz */ + .clken_offset = 0x00000044u, /* peripheral.clock.enable_offset */ + .clken_bit = 8u, /* peripheral.clock.bit */ + .irq = 18u, /* peripheral.irqs.global */ + .vref_mv = 3300u, /* device.vref_mv, its default */ + .bits = 12u, /* peripheral.adc.bits */ + .inputs = 16u, /* peripheral.adc.inputs */ + .temperature = 18u, /* peripheral.adc.temperature */ + .vrefint = 17u, /* peripheral.adc.vrefint */ + .dma_rx = {&emb_dev_dma2, 0u, 0u, {0u, 0u}}, /* dma.rx */ +}; +static emb_device_state_t adc1_state; +static emb_stm32_adc_data_t adc1_data; +static const emb_device_t *const adc1_deps[] = {&emb_dev_dma2, &emb_dev_rcc}; +const emb_device_t emb_dev_adc1 = { + .name = "adc1", + .api = &emb_stm32_adc_api.dev, + .config = &adc1_config, + .state = &adc1_state, + .data = &adc1_data, + .deps = adc1_deps, + .class_id = EMB_DRV_CLASS_ADC, + .level = EMB_DEVICE_KERNEL, + .dep_count = 2u, +}; + /* in initialization order */ static const emb_device_t *const devices[] = { &emb_dev_rcc, /* 0: EARLY */ @@ -349,16 +517,22 @@ static const emb_device_t *const devices[] = { &emb_dev_rtc, /* 3: EARLY */ &emb_dev_flash, /* 4: EARLY */ &emb_dev_dma1, /* 5: EARLY */ - &emb_dev_gpiob, /* 6: EARLY */ - &emb_dev_gpioc, /* 7: EARLY */ - &emb_dev_usart2, /* 8: EARLY */ - &emb_dev_uart4, /* 9: EARLY */ - &emb_dev_spi2, /* 10: KERNEL */ - &emb_dev_i2c1, /* 11: KERNEL */ - &emb_dev_i2c2, /* 12: KERNEL */ + &emb_dev_dma2, /* 6: EARLY */ + &emb_dev_gpiob, /* 7: EARLY */ + &emb_dev_gpioc, /* 8: EARLY */ + &emb_dev_usart2, /* 9: EARLY */ + &emb_dev_uart4, /* 10: EARLY */ + &emb_dev_spi2, /* 11: KERNEL */ + &emb_dev_i2c1, /* 12: KERNEL */ + &emb_dev_i2c2, /* 13: KERNEL */ + &emb_dev_tim5, /* 14: KERNEL */ + &emb_dev_tim9, /* 15: KERNEL */ + &emb_dev_tim3, /* 16: KERNEL */ + &emb_dev_tim4, /* 17: KERNEL */ + &emb_dev_adc1, /* 18: KERNEL */ }; -const emb_device_table_t emb_board_device_table = {devices, 13u, 10u}; +const emb_device_table_t emb_board_device_table = {devices, 19u, 11u}; #if CONFIG_EMB_DRV_ENTROPY /* the board's entropy source, or none: nothing stands in for one (SPEC-017 §11, SEC-012) */ diff --git a/examples/tasks/generated/nucleo_f446re/include/soc_devices.h b/examples/tasks/src/config/nucleo_f446re/peripheral/soc_devices.h similarity index 78% rename from examples/tasks/generated/nucleo_f446re/include/soc_devices.h rename to examples/tasks/src/config/nucleo_f446re/peripheral/soc_devices.h index af292944..86c11042 100644 --- a/examples/tasks/generated/nucleo_f446re/include/soc_devices.h +++ b/examples/tasks/src/config/nucleo_f446re/peripheral/soc_devices.h @@ -15,15 +15,15 @@ * arch/cortex_m/arch.yaml * c5c8e451c09717dee1713d07f8311b6d507e3b4c66c42d93e0ce11da6ec76d6d * boards/st/nucleo_f446re/board.yaml - * d756f3a7f19dc7da82ee3afc168dc54946312c5a9990720953c0fedcdece54ea + * 551c524379751d359bdd87501269d6cab33edf84d212d2f6632ffe9567ec71d0 * drivers/bindings.yaml - * d3c336ac05548e0addd1faac18f3dff70576d8069f11d89e6a761cf5c6132b49 + * c06d1a914adb21d0e314c79b3611ac6859eefeac1957d6914cccfc5531ad6ede * examples/tasks/system.yaml - * 3dd9de88918f06e4b3a41232cb716a9e7d1c4b74ad18e71fd51644ae394ebf9c + * 202cff4815e97ab763dc14c61b0b694ee9381307eb46687f9caaea3465a913da * soc/st/stm32f4/stm32f4.yaml - * 3db4a0a65c9624d865d4ed7fc6354bf95054d0c465b76a2091f06aeac3d7375f + * 796886c294250aa81151a620d80d0e43b5ee8e1bf53a07d1d7e2c62e95214dbd * soc/st/stm32f4/stm32f446.yaml - * 0d5cc7f5fce4c51be71678987720c85c6e76e05473ff8a78ea5035394316c055 + * f0c9a37f6017c87d0efe215a3561f65494ba52383f2d0c10419b0ab5035f77f2 * soc/st/stm32f4/stm32f446re.yaml * b9a88d0a94aa17ee83317a3a56f7c194ec1b3107dfb3e82e453122dc1c48f6d4 */ @@ -32,7 +32,7 @@ #include -#define EMB_SOC_DEVICE_COUNT 13u +#define EMB_SOC_DEVICE_COUNT 19u #if CONFIG_EMB_DEVICE #include @@ -44,6 +44,7 @@ extern const emb_device_t emb_dev_iwdg; extern const emb_device_t emb_dev_rtc; extern const emb_device_t emb_dev_flash; extern const emb_device_t emb_dev_dma1; +extern const emb_device_t emb_dev_dma2; extern const emb_device_t emb_dev_gpiob; extern const emb_device_t emb_dev_gpioc; extern const emb_device_t emb_dev_usart2; @@ -51,6 +52,11 @@ extern const emb_device_t emb_dev_uart4; extern const emb_device_t emb_dev_spi2; extern const emb_device_t emb_dev_i2c1; extern const emb_device_t emb_dev_i2c2; +extern const emb_device_t emb_dev_tim5; +extern const emb_device_t emb_dev_tim9; +extern const emb_device_t emb_dev_tim3; +extern const emb_device_t emb_dev_tim4; +extern const emb_device_t emb_dev_adc1; /* which devices the board has, for code that uses one only where it exists */ #define EMB_SOC_HAS_RCC 1 @@ -59,6 +65,7 @@ extern const emb_device_t emb_dev_i2c2; #define EMB_SOC_HAS_RTC 1 #define EMB_SOC_HAS_FLASH 1 #define EMB_SOC_HAS_DMA1 1 +#define EMB_SOC_HAS_DMA2 1 #define EMB_SOC_HAS_GPIOB 1 #define EMB_SOC_HAS_GPIOC 1 #define EMB_SOC_HAS_USART2 1 @@ -66,6 +73,11 @@ extern const emb_device_t emb_dev_i2c2; #define EMB_SOC_HAS_SPI2 1 #define EMB_SOC_HAS_I2C1 1 #define EMB_SOC_HAS_I2C2 1 +#define EMB_SOC_HAS_TIM5 1 +#define EMB_SOC_HAS_TIM9 1 +#define EMB_SOC_HAS_TIM3 1 +#define EMB_SOC_HAS_TIM4 1 +#define EMB_SOC_HAS_ADC1 1 /* the board's watchdog device: the first of its class */ #define EMB_SOC_WATCHDOG_DEVICE (&emb_dev_iwdg) @@ -73,6 +85,11 @@ extern const emb_device_t emb_dev_i2c2; /* the board's RTC device: the first of its class */ #define EMB_SOC_RTC_DEVICE (&emb_dev_rtc) +/* the board's counters: the first of their class, and all of them (SPEC-017 §11a) */ +#define EMB_SOC_COUNTER_DEVICE (&emb_dev_tim5) +#define EMB_SOC_COUNTER_DEVICES &emb_dev_tim5, &emb_dev_tim9 +#define EMB_SOC_COUNTER_COUNT 2u + /* the console's UART device (the board's console:) */ #define EMB_SOC_CONSOLE_DEVICE (&emb_dev_usart2) /* its writes' DMA channel (devices[].dma, A119) */ @@ -95,6 +112,7 @@ extern const emb_device_t emb_dev_i2c2; #define EMB_SOC_USART2_DMA_TX {&emb_dev_dma1, 6u, 4u, {0u, 0u}} #define EMB_SOC_SPI2_DMA_RX {&emb_dev_dma1, 3u, 0u, {0u, 0u}} #define EMB_SOC_SPI2_DMA_TX {&emb_dev_dma1, 4u, 0u, {0u, 0u}} +#define EMB_SOC_ADC1_DMA_RX {&emb_dev_dma2, 0u, 0u, {0u, 0u}} /* clang-format on */ /* the SPI devices' chip selects (devices[].cs), emb_drv_gpio_line_t initializers; the pin diff --git a/examples/tasks/src/config/nucleo_f446re/tasks.c b/examples/tasks/src/config/nucleo_f446re/tasks.c new file mode 100644 index 00000000..16a7a716 --- /dev/null +++ b/examples/tasks/src/config/nucleo_f446re/tasks.c @@ -0,0 +1,206 @@ +/* SPDX-License-Identifier: Apache-2.0 */ +/* + * This file is part of EmbLinkRTOS, a deterministic real-time kernel for microcontrollers. + * Licensed under the Apache License, Version 2.0; see the LICENSE file at the repository root. + */ + +/******************************************************************************* + System Tasks File + + File Name: + tasks.c + + Summary: + tasks_demo's tasks on the nucleo_f446re, and SYS_Tasks(). + + Description: + Each task's thread, queue, dispatch and description: the thread runs the + task runtime, emb_task_run() (SPEC-020), which calls an event task's handler + for each event, and a periodic task's _Tasks() every period, without drift. + SYS_Tasks() starts the kernel. + + Generated by emb-hwgen 0.1.0, schema v0, from the system description and the + nucleo_f446re's. Yours to edit: regenerating merges its changes with yours + (A126): + hw/gen/emb-hwgen.py generate --system examples/tasks/system.yaml + + Inputs (SHA-256): + arch/cortex_m/arch.yaml + c5c8e451c09717dee1713d07f8311b6d507e3b4c66c42d93e0ce11da6ec76d6d + boards/st/nucleo_f446re/board.yaml + 551c524379751d359bdd87501269d6cab33edf84d212d2f6632ffe9567ec71d0 + drivers/bindings.yaml + c06d1a914adb21d0e314c79b3611ac6859eefeac1957d6914cccfc5531ad6ede + examples/tasks/system.yaml + 202cff4815e97ab763dc14c61b0b694ee9381307eb46687f9caaea3465a913da + soc/st/stm32f4/stm32f4.yaml + 796886c294250aa81151a620d80d0e43b5ee8e1bf53a07d1d7e2c62e95214dbd + soc/st/stm32f4/stm32f446.yaml + f0c9a37f6017c87d0efe215a3561f65494ba52383f2d0c10419b0ab5035f77f2 + soc/st/stm32f4/stm32f446re.yaml + b9a88d0a94aa17ee83317a3a56f7c194ec1b3107dfb3e82e453122dc1c48f6d4 + *******************************************************************************/ + +// ***************************************************************************** +// ***************************************************************************** +// Section: Included Files +// ***************************************************************************** +// ***************************************************************************** + +#include "definitions.h" + +// ***************************************************************************** +// ***************************************************************************** +// Section: RTOS "Tasks" Routine +// ***************************************************************************** +// ***************************************************************************** + +/* ---- door: an event task, its queue 8 deep (SPEC-020) ---- */ + +_Static_assert(DOOR_STATE_CLOSED == 0, "door.h: DOOR_STATES are system.yaml's states, in order"); +_Static_assert(DOOR_STATE_OPEN == 1, "door.h: DOOR_STATES are system.yaml's states, in order"); +_Static_assert(DOOR_STATE_JAMMED == 2, "door.h: DOOR_STATES are system.yaml's states, in order"); +_Static_assert(DOOR_EVENT_OPEN == EMB_EV_USER + 0u, + "door.h: DOOR_EVENTS are system.yaml's events, in order"); +_Static_assert(DOOR_EVENT_CLOSE == EMB_EV_USER + 1u, + "door.h: DOOR_EVENTS are system.yaml's events, in order"); +_Static_assert(DOOR_EVENT_JAM == EMB_EV_USER + 2u, + "door.h: DOOR_EVENTS are system.yaml's events, in order"); + +static emb_task_event_t door_event; +EMB_MSGQ_DEFINE(door_task_queue, sizeof(emb_task_event_t), DOOR_QUEUE_LENGTH, 0u); +static const uint32_t door_timeouts[3] = {0u, DOOR_OPEN_TIMEOUT_MS, 0u}; + +static emb_state_t door_dispatch(emb_state_t state, uint8_t why) +{ + emb_state_t next = state; /* a state the task lacks stays: the runtime faults on it */ + if (why == EMB_TASK_WHY_TIMEOUT) { + door_event.id = EMB_EV_TIMEOUT; + door_event.value = 0u; + } + switch (state) { + case DOOR_STATE_CLOSED: + doorData.state = DOOR_STATE_CLOSED; + next = (emb_state_t)DOOR_OnClosed(&door_event); + break; + case DOOR_STATE_OPEN: + doorData.state = DOOR_STATE_OPEN; + next = (emb_state_t)DOOR_OnOpen(&door_event); + break; + case DOOR_STATE_JAMMED: + doorData.state = DOOR_STATE_JAMMED; + next = (emb_state_t)DOOR_OnJammed(&door_event); + break; + default: + break; + } + return next; +} + +static void door_enter(emb_state_t state) +{ + switch (state) { + case DOOR_STATE_CLOSED: + doorData.state = DOOR_STATE_CLOSED; + break; + case DOOR_STATE_OPEN: + doorData.state = DOOR_STATE_OPEN; + DOOR_EnterOpen(); + break; + case DOOR_STATE_JAMMED: + doorData.state = DOOR_STATE_JAMMED; + break; + default: + break; + } +} + +static void door_exit(emb_state_t state) +{ + if (state == DOOR_STATE_OPEN) { + DOOR_ExitOpen(); + } +} + +static const emb_task_desc_t door_desc = { + .name = "door", + .dispatch = door_dispatch, + .enter = door_enter, + .leave = door_exit, + .event = &door_event, + .queue = &door_task_queue, + .timeout_ms = door_timeouts, + .period_ms = 0u, + .event_size = (uint16_t)sizeof(emb_task_event_t), + .initial = (emb_state_t)DOOR_STATE_CLOSED, + .count = 3u, + .model = EMB_TASK_EVENT, +}; +emb_task_t door_task = {.desc = &door_desc, .state = (emb_state_t)DOOR_STATE_CLOSED}; + +static void door_main(void *arg) +{ + (void)arg; + emb_task_run(&door_task); +} + +EMB_THREAD_DEFINE(door_thread, door_main, NULL, DOOR_PRIORITY, DOOR_STACK_SIZE, 0u); + +/* ---- blink: a periodic task, every 500 ms (SPEC-020) ---- */ + +_Static_assert(BLINK_STATE_DARK == 0, "blink.h: BLINK_STATES are system.yaml's states, in order"); +_Static_assert(BLINK_STATE_LIT == 1, "blink.h: BLINK_STATES are system.yaml's states, in order"); + +static emb_state_t blink_dispatch(emb_state_t state, uint8_t why) +{ + (void)state; + (void)why; + BLINK_Tasks(); + return (emb_state_t)blinkData.state; +} + +static const emb_task_desc_t blink_desc = { + .name = "blink", + .dispatch = blink_dispatch, + .enter = NULL, + .leave = NULL, + .event = NULL, + .queue = NULL, + .timeout_ms = NULL, + .period_ms = BLINK_PERIOD_MS, + .event_size = 0u, + .initial = (emb_state_t)BLINK_STATE_DARK, + .count = 2u, + .model = EMB_TASK_PERIODIC, +}; +emb_task_t blink_task = {.desc = &blink_desc, .state = (emb_state_t)BLINK_STATE_DARK}; + +static void blink_main(void *arg) +{ + (void)arg; + emb_task_run(&blink_task); +} + +EMB_THREAD_DEFINE(blink_thread, blink_main, NULL, BLINK_PRIORITY, BLINK_STACK_SIZE, 0u); + +// ***************************************************************************** +// ***************************************************************************** +// Section: System "Tasks" Routine +// ***************************************************************************** +// ***************************************************************************** + +/******************************************************************************* + Function: + void SYS_Tasks ( void ) + + Remarks: + See prototype in definitions.h. + */ +void SYS_Tasks(void) +{ + /* Start the kernel: the threads and the tasks run from here. It does not return. */ + emb_kernel_start(); +} +/******************************************************************************* + End of File +*/ diff --git a/examples/tasks/generated/.base/pico2_w/build/CMakeLists.txt b/examples/tasks/src/config/pico2_w/build/CMakeLists.txt similarity index 63% rename from examples/tasks/generated/.base/pico2_w/build/CMakeLists.txt rename to examples/tasks/src/config/pico2_w/build/CMakeLists.txt index 7a1b34e1..55e1769d 100644 --- a/examples/tasks/generated/.base/pico2_w/build/CMakeLists.txt +++ b/examples/tasks/src/config/pico2_w/build/CMakeLists.txt @@ -9,15 +9,15 @@ # arch/cortex_m/arch.yaml # c5c8e451c09717dee1713d07f8311b6d507e3b4c66c42d93e0ce11da6ec76d6d # boards/rpi/pico2_w/board.yaml -# dad0ef7259e41ef3bd8fa07ea1c1f36040254a443deaf30d963b4fb14b5354a0 +# 345279a53c444bc45e7fcc1a0cb5ab47b32a7699534f5484ea80d73f7a0bdf6d # drivers/bindings.yaml -# d3c336ac05548e0addd1faac18f3dff70576d8069f11d89e6a761cf5c6132b49 +# c06d1a914adb21d0e314c79b3611ac6859eefeac1957d6914cccfc5531ad6ede # examples/tasks/system.yaml -# 3dd9de88918f06e4b3a41232cb716a9e7d1c4b74ad18e71fd51644ae394ebf9c +# 202cff4815e97ab763dc14c61b0b694ee9381307eb46687f9caaea3465a913da # soc/rpi/rp2350/rp2350.yaml -# 9e60e99ecac8782bccd69e3bd69014af1d8891d6b6fbd822acff5bd9a526d8cd +# 80773a9c9cfb1c62cd322e397111a11d7f48fce3c0febc76bf7d5571018977a5 # soc/rpi/rp2350/rp2350a.yaml -# 045cef7794c3b6c6d2ff48ba294c6308d00fe13bc65e346f2ba2ccde1cea24ff +# 22395e35ed229020b5c9c7586af50cfaa07960a09905776eb4713ff28051eb3c # The board has no C of its own: its SoC family's board support builds emb_board from -# ../src/board_pins.c and ../include/hw_config.h, and links ../linker/regions.ld. +# ../peripheral/board_pins.c and ../peripheral/hw_config.h, and links ../linker/regions.ld. add_subdirectory("${EMB_SOC_DIR}" soc) diff --git a/examples/tasks/generated/.base/pico2_w/build/board.cmake b/examples/tasks/src/config/pico2_w/build/board.cmake similarity index 63% rename from examples/tasks/generated/.base/pico2_w/build/board.cmake rename to examples/tasks/src/config/pico2_w/build/board.cmake index 4441989e..822453b3 100644 --- a/examples/tasks/generated/.base/pico2_w/build/board.cmake +++ b/examples/tasks/src/config/pico2_w/build/board.cmake @@ -9,36 +9,39 @@ # arch/cortex_m/arch.yaml # c5c8e451c09717dee1713d07f8311b6d507e3b4c66c42d93e0ce11da6ec76d6d # boards/rpi/pico2_w/board.yaml -# dad0ef7259e41ef3bd8fa07ea1c1f36040254a443deaf30d963b4fb14b5354a0 +# 345279a53c444bc45e7fcc1a0cb5ab47b32a7699534f5484ea80d73f7a0bdf6d # drivers/bindings.yaml -# d3c336ac05548e0addd1faac18f3dff70576d8069f11d89e6a761cf5c6132b49 +# c06d1a914adb21d0e314c79b3611ac6859eefeac1957d6914cccfc5531ad6ede # examples/tasks/system.yaml -# 3dd9de88918f06e4b3a41232cb716a9e7d1c4b74ad18e71fd51644ae394ebf9c +# 202cff4815e97ab763dc14c61b0b694ee9381307eb46687f9caaea3465a913da # soc/rpi/rp2350/rp2350.yaml -# 9e60e99ecac8782bccd69e3bd69014af1d8891d6b6fbd822acff5bd9a526d8cd +# 80773a9c9cfb1c62cd322e397111a11d7f48fce3c0febc76bf7d5571018977a5 # soc/rpi/rp2350/rp2350a.yaml -# 045cef7794c3b6c6d2ff48ba294c6308d00fe13bc65e346f2ba2ccde1cea24ff +# 22395e35ed229020b5c9c7586af50cfaa07960a09905776eb4713ff28051eb3c # pico2_w: RP2350A, cortex-m33f at 150 MHz. set(EMB_BOARD_ARCH cortex_m) set(EMB_BOARD_VARIANT armv8m-main) set(EMB_BOARD_DEFAULT_PROFILE base) set(EMB_BOARD_C_FLAGS -mcpu=cortex-m33 -mfpu=fpv5-sp-d16 -mfloat-abi=hard) get_filename_component(EMB_BOARD_GENERATED_DIR "${CMAKE_CURRENT_LIST_DIR}/.." ABSOLUTE) -set(EMB_BOARD_CONF "${EMB_BOARD_GENERATED_DIR}/config/board.conf") +set(EMB_BOARD_CONF "${EMB_BOARD_GENERATED_DIR}/build/board.conf") set(EMB_BOARD_HW_JSON "${EMB_BOARD_GENERATED_DIR}/docs/hw.json") set(EMB_BOARD_BUILD_DIR "${CMAKE_CURRENT_LIST_DIR}") # build/CMakeLists.txt +set(EMB_BOARD_SRC_DIR "${EMB_BOARD_GENERATED_DIR}/peripheral") # its pin table and boot block +set(EMB_BOARD_LINKER_DIR "${EMB_BOARD_GENERATED_DIR}/linker") # the SoC family's board support and drivers build this board (build/CMakeLists.txt) set(EMB_SOC_DIR "${EMB_BASE}/soc/rpi/rp2350") -set(EMB_BOARD_INCLUDE_DIRS "${EMB_BOARD_GENERATED_DIR}/include" "${EMB_SOC_DIR}/include") +set(EMB_BOARD_INCLUDE_DIRS "${EMB_BOARD_GENERATED_DIR}/peripheral" "${EMB_SOC_DIR}/include") set(EMB_BOARD_RESETS_IN hil) # restart the image with RAM kept (test_crash_reset) set(EMB_BOARD_UART1_DMA tx) set(EMB_BOARD_SPI1_DMA rx tx) set(EMB_BOARD_SPI1_CS_COUNT 1) +set(EMB_BOARD_ADC_DMA rx) set(EMB_BOARD_FLASH_IMAGE uf2) # what the SoC's boot ROM loads (A79) set(EMB_BOARD_UF2_FAMILY 0xE48BFF59) # the board's devices (soc_devices.c) and the drivers they use, and only those (SPEC-016 §8) set(EMB_BOARD_DRIVER_SOURCES - "${EMB_BOARD_GENERATED_DIR}/src/soc_devices.c" + "${EMB_BOARD_GENERATED_DIR}/peripheral/soc_devices.c" "${EMB_BASE}/drivers/rpi/rp2350_devices.c" "${EMB_BASE}/drivers/rpi/rp2350_gpio.c" "${EMB_BASE}/drivers/rpi/rp2350_watchdog.c" @@ -49,6 +52,9 @@ set(EMB_BOARD_DRIVER_SOURCES "${EMB_BASE}/drivers/rpi/rp2350_trng.c" "${EMB_BASE}/drivers/arm/pl022.c" "${EMB_BASE}/drivers/snps/dw_i2c.c" + "${EMB_BASE}/drivers/rpi/rp2350_timer.c" + "${EMB_BASE}/drivers/rpi/rp2350_pwm.c" + "${EMB_BASE}/drivers/rpi/rp2350_adc.c" ) set(EMB_BOARD_DRIVER_INCLUDE_DIRS "${EMB_BASE}/drivers/rpi/include" @@ -58,9 +64,9 @@ set(EMB_BOARD_DRIVER_INCLUDE_DIRS # the inputs this directory was generated from, for the configure-time staleness check set(EMB_BOARD_HW_INPUTS "arch/cortex_m/arch.yaml=c5c8e451c09717dee1713d07f8311b6d507e3b4c66c42d93e0ce11da6ec76d6d" - "boards/rpi/pico2_w/board.yaml=dad0ef7259e41ef3bd8fa07ea1c1f36040254a443deaf30d963b4fb14b5354a0" - "drivers/bindings.yaml=d3c336ac05548e0addd1faac18f3dff70576d8069f11d89e6a761cf5c6132b49" - "examples/tasks/system.yaml=3dd9de88918f06e4b3a41232cb716a9e7d1c4b74ad18e71fd51644ae394ebf9c" - "soc/rpi/rp2350/rp2350.yaml=9e60e99ecac8782bccd69e3bd69014af1d8891d6b6fbd822acff5bd9a526d8cd" - "soc/rpi/rp2350/rp2350a.yaml=045cef7794c3b6c6d2ff48ba294c6308d00fe13bc65e346f2ba2ccde1cea24ff" + "boards/rpi/pico2_w/board.yaml=345279a53c444bc45e7fcc1a0cb5ab47b32a7699534f5484ea80d73f7a0bdf6d" + "drivers/bindings.yaml=c06d1a914adb21d0e314c79b3611ac6859eefeac1957d6914cccfc5531ad6ede" + "examples/tasks/system.yaml=202cff4815e97ab763dc14c61b0b694ee9381307eb46687f9caaea3465a913da" + "soc/rpi/rp2350/rp2350.yaml=80773a9c9cfb1c62cd322e397111a11d7f48fce3c0febc76bf7d5571018977a5" + "soc/rpi/rp2350/rp2350a.yaml=22395e35ed229020b5c9c7586af50cfaa07960a09905776eb4713ff28051eb3c" ) diff --git a/examples/tasks/generated/.base/pico2_w/config/board.conf b/examples/tasks/src/config/pico2_w/build/board.conf similarity index 70% rename from examples/tasks/generated/.base/pico2_w/config/board.conf rename to examples/tasks/src/config/pico2_w/build/board.conf index 970e867a..5053d50e 100644 --- a/examples/tasks/generated/.base/pico2_w/config/board.conf +++ b/examples/tasks/src/config/pico2_w/build/board.conf @@ -9,15 +9,15 @@ # arch/cortex_m/arch.yaml # c5c8e451c09717dee1713d07f8311b6d507e3b4c66c42d93e0ce11da6ec76d6d # boards/rpi/pico2_w/board.yaml -# dad0ef7259e41ef3bd8fa07ea1c1f36040254a443deaf30d963b4fb14b5354a0 +# 345279a53c444bc45e7fcc1a0cb5ab47b32a7699534f5484ea80d73f7a0bdf6d # drivers/bindings.yaml -# d3c336ac05548e0addd1faac18f3dff70576d8069f11d89e6a761cf5c6132b49 +# c06d1a914adb21d0e314c79b3611ac6859eefeac1957d6914cccfc5531ad6ede # examples/tasks/system.yaml -# 3dd9de88918f06e4b3a41232cb716a9e7d1c4b74ad18e71fd51644ae394ebf9c +# 202cff4815e97ab763dc14c61b0b694ee9381307eb46687f9caaea3465a913da # soc/rpi/rp2350/rp2350.yaml -# 9e60e99ecac8782bccd69e3bd69014af1d8891d6b6fbd822acff5bd9a526d8cd +# 80773a9c9cfb1c62cd322e397111a11d7f48fce3c0febc76bf7d5571018977a5 # soc/rpi/rp2350/rp2350a.yaml -# 045cef7794c3b6c6d2ff48ba294c6308d00fe13bc65e346f2ba2ccde1cea24ff +# 22395e35ed229020b5c9c7586af50cfaa07960a09905776eb4713ff28051eb3c # Board defaults for pico2_w. Applied before the profile fragment. CONFIG_EMB_CM_CPU_HZ=150000000 CONFIG_EMB_CM_IRQ_COUNT=52 diff --git a/examples/tasks/src/config/pico2_w/configuration.h b/examples/tasks/src/config/pico2_w/configuration.h new file mode 100644 index 00000000..faf92355 --- /dev/null +++ b/examples/tasks/src/config/pico2_w/configuration.h @@ -0,0 +1,108 @@ +/* SPDX-License-Identifier: Apache-2.0 */ +/* + * This file is part of EmbLinkRTOS, a deterministic real-time kernel for microcontrollers. + * Licensed under the Apache License, Version 2.0; see the LICENSE file at the repository root. + */ + +/******************************************************************************* + System Configuration Header + + File Name: + configuration.h + + Summary: + The build-time configuration of tasks_demo on the pico2_w. + + Description: + The system's settings as macros: the board and its clock, the devices' + settings, each task's and thread's priority and stack, the tasks' periods, + queues and timeouts, and the application's interrupts. The kernel's own + options are 's CONFIG_EMB_*, and the board's hardware + 's EMB_HW_*. + + Generated by emb-hwgen 0.1.0, schema v0, from the system description and the + pico2_w's. Yours to edit: regenerating merges its changes with yours (A126): + hw/gen/emb-hwgen.py generate --system examples/tasks/system.yaml + + Inputs (SHA-256): + arch/cortex_m/arch.yaml + c5c8e451c09717dee1713d07f8311b6d507e3b4c66c42d93e0ce11da6ec76d6d + boards/rpi/pico2_w/board.yaml + 345279a53c444bc45e7fcc1a0cb5ab47b32a7699534f5484ea80d73f7a0bdf6d + drivers/bindings.yaml + c06d1a914adb21d0e314c79b3611ac6859eefeac1957d6914cccfc5531ad6ede + examples/tasks/system.yaml + 202cff4815e97ab763dc14c61b0b694ee9381307eb46687f9caaea3465a913da + soc/rpi/rp2350/rp2350.yaml + 80773a9c9cfb1c62cd322e397111a11d7f48fce3c0febc76bf7d5571018977a5 + soc/rpi/rp2350/rp2350a.yaml + 22395e35ed229020b5c9c7586af50cfaa07960a09905776eb4713ff28051eb3c + *******************************************************************************/ + +#ifndef CONFIGURATION_H +#define CONFIGURATION_H + +// ***************************************************************************** +// ***************************************************************************** +// Section: Included Files +// ***************************************************************************** +// ***************************************************************************** + +#include + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +// ***************************************************************************** +// ***************************************************************************** +// Section: System Configuration +// ***************************************************************************** +// ***************************************************************************** + +#define SYS_CPU_CLOCK_HZ 150000000u +#define SYS_TICK_NS CONFIG_EMB_TICK_NS +#define SYS_PRIORITY_COUNT CONFIG_EMB_PRIORITY_COUNT + +// ***************************************************************************** +// ***************************************************************************** +// Section: Driver Configuration +// ***************************************************************************** +// ***************************************************************************** + +#define DRV_FLASH_SIZE 4194304u +#define DRV_UART0_BAUD 115200u +#define DRV_UART1_BAUD 115200u +#define DRV_TRNG_SAMPLE_COUNT 200u + +// ***************************************************************************** +// ***************************************************************************** +// Section: Application Configuration +// ***************************************************************************** +// ***************************************************************************** + +/* door: an event task, its queue 8 deep */ +#define DOOR_PRIORITY 5u +#define DOOR_STACK_SIZE 1024u +#define DOOR_QUEUE_LENGTH 8u +#define DOOR_OPEN_TIMEOUT_MS 2000u + +/* blink: a periodic task, every 500 ms */ +#define BLINK_PRIORITY 2u +#define BLINK_STACK_SIZE 512u +#define BLINK_PERIOD_MS 500u + +/* wake: an interrupt, WAKE_InterruptHandler() */ +#define WAKE_IRQ 46u +#define WAKE_IRQ_LEVEL 1u + +#ifdef __cplusplus +} +#endif + +#endif /* CONFIGURATION_H */ +/******************************************************************************* + End of File +*/ diff --git a/examples/tasks/src/config/pico2_w/definitions.h b/examples/tasks/src/config/pico2_w/definitions.h new file mode 100644 index 00000000..a8ac7c45 --- /dev/null +++ b/examples/tasks/src/config/pico2_w/definitions.h @@ -0,0 +1,170 @@ +/* SPDX-License-Identifier: Apache-2.0 */ +/* + * This file is part of EmbLinkRTOS, a deterministic real-time kernel for microcontrollers. + * Licensed under the Apache License, Version 2.0; see the LICENSE file at the repository root. + */ + +/******************************************************************************* + System Definitions + + File Name: + definitions.h + + Summary: + tasks_demo's system definitions on the pico2_w. + + Description: + The one header the application includes: the kernel's API, the board's + devices, the system's configuration and handles, every task's header, and + the system's two functions, SYS_Initialize() and SYS_Tasks(). + + Generated by emb-hwgen 0.1.0, schema v0, from the system description and the + pico2_w's. Yours to edit: regenerating merges its changes with yours (A126): + hw/gen/emb-hwgen.py generate --system examples/tasks/system.yaml + + Inputs (SHA-256): + arch/cortex_m/arch.yaml + c5c8e451c09717dee1713d07f8311b6d507e3b4c66c42d93e0ce11da6ec76d6d + boards/rpi/pico2_w/board.yaml + 345279a53c444bc45e7fcc1a0cb5ab47b32a7699534f5484ea80d73f7a0bdf6d + drivers/bindings.yaml + c06d1a914adb21d0e314c79b3611ac6859eefeac1957d6914cccfc5531ad6ede + examples/tasks/system.yaml + 202cff4815e97ab763dc14c61b0b694ee9381307eb46687f9caaea3465a913da + soc/rpi/rp2350/rp2350.yaml + 80773a9c9cfb1c62cd322e397111a11d7f48fce3c0febc76bf7d5571018977a5 + soc/rpi/rp2350/rp2350a.yaml + 22395e35ed229020b5c9c7586af50cfaa07960a09905776eb4713ff28051eb3c + *******************************************************************************/ + +#ifndef DEFINITIONS_H +#define DEFINITIONS_H + +// ***************************************************************************** +// ***************************************************************************** +// Section: Included Files +// ***************************************************************************** +// ***************************************************************************** + +#include "blink.h" +#include "configuration.h" +#include "door.h" +#include "interrupts.h" + +#include + +#include +#include +#include + +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/* Device Information */ +#define DEVICE_NAME "RP2350A" +#define DEVICE_ARCH "cortex-m33f" +#define DEVICE_FAMILY "rp2350" +#define BOARD_NAME "pico2_w" + +/* CPU clock frequency */ +#define CPU_CLOCK_FREQUENCY 150000000u + +// ***************************************************************************** +// ***************************************************************************** +// Section: System Functions +// ***************************************************************************** +// ***************************************************************************** + +/******************************************************************************* + Function: + void SYS_Initialize ( void *data ) + + Summary: + Initializes the board, the kernel and every task. + + Description: + This function initializes the board (its clocks, pins and console), then the + kernel (its objects and the EARLY devices), then the application's + interrupts, then each task, in its initial state. The KERNEL devices start + with the kernel, in SYS_Tasks(). + + Precondition: + None. + + Parameters: + data - Unused; NULL. + + Returns: + None. + + Example: + + SYS_Initialize(NULL); + while (true) { + SYS_Tasks(); + } + + + Remarks: + This function is called once, after reset, from main(). +*/ +void SYS_Initialize(void *data); + +/******************************************************************************* + Function: + void SYS_Tasks ( void ) + + Summary: + Starts the kernel: the threads and the tasks run from here. + + Description: + This function starts the KERNEL devices, then the scheduler, which runs the + system's threads and each task's thread. It does not return. + + Precondition: + SYS_Initialize() has run. + + Parameters: + None. + + Returns: + It does not return. + + Example: + + SYS_Initialize(NULL); + while (true) { + SYS_Tasks(); + } + + + Remarks: + Harmony calls its SYS_Tasks() in a loop; this one runs the scheduler and + never comes back. +*/ +void SYS_Tasks(void); + +// ***************************************************************************** +// ***************************************************************************** +// Section: Tasks +// ***************************************************************************** +// ***************************************************************************** + +/* each task's handle, for emb_task_post() (SPEC-020) */ +extern emb_task_t door_task; +extern emb_task_t blink_task; +#define DOOR_TASK (&door_task) +#define BLINK_TASK (&blink_task) + +#ifdef __cplusplus +} +#endif + +#endif /* DEFINITIONS_H */ +/******************************************************************************* + End of File +*/ diff --git a/examples/tasks/generated/pico2_w/docs/board.md b/examples/tasks/src/config/pico2_w/docs/board.md similarity index 74% rename from examples/tasks/generated/pico2_w/docs/board.md rename to examples/tasks/src/config/pico2_w/docs/board.md index 31205aec..4ed4c03d 100644 --- a/examples/tasks/generated/pico2_w/docs/board.md +++ b/examples/tasks/src/config/pico2_w/docs/board.md @@ -41,6 +41,10 @@ The console on UART0 at 115200 baud on GPIO0 (TX, pin 1) and GPIO1 (RX, pin 2). | GPIO11 | `pins.spi1.mosi` | af1 (spi1_mosi) | | GPIO12 | `pins.spi1.miso` | af1 (spi1_miso) | | GPIO13 | `devices.spi1.cs[0]` | output | +| GPIO14 | `pins.pwm7.a` | af4 (pwm7_a) | +| GPIO17 | `pins.pwm0.b` | af4 (pwm0_b) | +| GPIO26 | `pins.adc.in0` | analog | +| GPIO27 | `pins.adc.in1` | analog | ## Devices @@ -60,11 +64,25 @@ In initialization order (SPEC-016 §4). | spi1 | `arm,pl022` | spi | KERNEL | io_bank0, dma | | i2c0 | `snps,designware-i2c` | i2c | KERNEL | io_bank0 | | i2c1 | `snps,designware-i2c` | i2c | KERNEL | io_bank0 | +| timer1 | `rpi,rp2350-timer` | counter | KERNEL | - | +| pwm7 | `rpi,rp2350-pwm` | pwm | KERNEL | io_bank0 | +| pwm0 | `rpi,rp2350-pwm` | pwm | KERNEL | io_bank0 | +| adc | `rpi,rp2350-adc` | adc | KERNEL | clocks, io_bank0, dma | ## Interrupt lines | Line | Owner | |---|---| +| 0 | timer0.alarm0 | +| 1 | timer0.alarm1 | +| 2 | timer0.alarm2 | +| 3 | timer0.alarm3 | +| 4 | timer1.alarm0 | +| 5 | timer1.alarm1 | +| 6 | timer1.alarm2 | +| 7 | timer1.alarm3 | +| 8 | pwm.wrap0 | +| 9 | pwm.wrap1 | | 10 | dma.irq0 | | 11 | dma.irq1 | | 12 | dma.irq2 | @@ -75,6 +93,7 @@ In initialization order (SPEC-016 §4). | 32 | spi1.global | | 33 | uart0.global | | 34 | uart1.global | +| 35 | adc.fifo | | 36 | i2c0.global | | 37 | i2c1.global | | 39 | trng.irq | @@ -89,8 +108,8 @@ Generated by emb-hwgen 0.1.0, schema v0, from: | Input | SHA-256 | |---|---| | `arch/cortex_m/arch.yaml` | `c5c8e451c09717dee1713d07f8311b6d507e3b4c66c42d93e0ce11da6ec76d6d` | -| `boards/rpi/pico2_w/board.yaml` | `dad0ef7259e41ef3bd8fa07ea1c1f36040254a443deaf30d963b4fb14b5354a0` | -| `drivers/bindings.yaml` | `d3c336ac05548e0addd1faac18f3dff70576d8069f11d89e6a761cf5c6132b49` | -| `examples/tasks/system.yaml` | `3dd9de88918f06e4b3a41232cb716a9e7d1c4b74ad18e71fd51644ae394ebf9c` | -| `soc/rpi/rp2350/rp2350.yaml` | `9e60e99ecac8782bccd69e3bd69014af1d8891d6b6fbd822acff5bd9a526d8cd` | -| `soc/rpi/rp2350/rp2350a.yaml` | `045cef7794c3b6c6d2ff48ba294c6308d00fe13bc65e346f2ba2ccde1cea24ff` | +| `boards/rpi/pico2_w/board.yaml` | `345279a53c444bc45e7fcc1a0cb5ab47b32a7699534f5484ea80d73f7a0bdf6d` | +| `drivers/bindings.yaml` | `c06d1a914adb21d0e314c79b3611ac6859eefeac1957d6914cccfc5531ad6ede` | +| `examples/tasks/system.yaml` | `202cff4815e97ab763dc14c61b0b694ee9381307eb46687f9caaea3465a913da` | +| `soc/rpi/rp2350/rp2350.yaml` | `80773a9c9cfb1c62cd322e397111a11d7f48fce3c0febc76bf7d5571018977a5` | +| `soc/rpi/rp2350/rp2350a.yaml` | `22395e35ed229020b5c9c7586af50cfaa07960a09905776eb4713ff28051eb3c` | diff --git a/examples/tasks/generated/.base/pico2_w/docs/build_report.md b/examples/tasks/src/config/pico2_w/docs/build_report.md similarity index 54% rename from examples/tasks/generated/.base/pico2_w/docs/build_report.md rename to examples/tasks/src/config/pico2_w/docs/build_report.md index eb1d7bfc..c94c0d83 100644 --- a/examples/tasks/generated/.base/pico2_w/docs/build_report.md +++ b/examples/tasks/src/config/pico2_w/docs/build_report.md @@ -4,6 +4,8 @@ xosc 12 MHz / M 1 = 12 MHz VCO input, x N 125 = 1500 MHz, / P 10 = 150 MHz. Given by the board, checked. +pll_usb: xosc 12 MHz / M 1 x N 64 = 768 MHz VCO, / 4 / 4 = 48 MHz. Solved; started by the drivers that use it. + | Bus | Frequency | Limit | |---|---|---| | sys | 150 MHz | 150 MHz | @@ -27,8 +29,8 @@ Generated by emb-hwgen 0.1.0, schema v0, from: | Input | SHA-256 | |---|---| | `arch/cortex_m/arch.yaml` | `c5c8e451c09717dee1713d07f8311b6d507e3b4c66c42d93e0ce11da6ec76d6d` | -| `boards/rpi/pico2_w/board.yaml` | `dad0ef7259e41ef3bd8fa07ea1c1f36040254a443deaf30d963b4fb14b5354a0` | -| `drivers/bindings.yaml` | `d3c336ac05548e0addd1faac18f3dff70576d8069f11d89e6a761cf5c6132b49` | -| `examples/tasks/system.yaml` | `3dd9de88918f06e4b3a41232cb716a9e7d1c4b74ad18e71fd51644ae394ebf9c` | -| `soc/rpi/rp2350/rp2350.yaml` | `9e60e99ecac8782bccd69e3bd69014af1d8891d6b6fbd822acff5bd9a526d8cd` | -| `soc/rpi/rp2350/rp2350a.yaml` | `045cef7794c3b6c6d2ff48ba294c6308d00fe13bc65e346f2ba2ccde1cea24ff` | +| `boards/rpi/pico2_w/board.yaml` | `345279a53c444bc45e7fcc1a0cb5ab47b32a7699534f5484ea80d73f7a0bdf6d` | +| `drivers/bindings.yaml` | `c06d1a914adb21d0e314c79b3611ac6859eefeac1957d6914cccfc5531ad6ede` | +| `examples/tasks/system.yaml` | `202cff4815e97ab763dc14c61b0b694ee9381307eb46687f9caaea3465a913da` | +| `soc/rpi/rp2350/rp2350.yaml` | `80773a9c9cfb1c62cd322e397111a11d7f48fce3c0febc76bf7d5571018977a5` | +| `soc/rpi/rp2350/rp2350a.yaml` | `22395e35ed229020b5c9c7586af50cfaa07960a09905776eb4713ff28051eb3c` | diff --git a/examples/tasks/generated/.base/pico2_w/docs/hw.json b/examples/tasks/src/config/pico2_w/docs/hw.json similarity index 67% rename from examples/tasks/generated/.base/pico2_w/docs/hw.json rename to examples/tasks/src/config/pico2_w/docs/hw.json index 9c355b27..d3926c90 100644 --- a/examples/tasks/generated/.base/pico2_w/docs/hw.json +++ b/examples/tasks/src/config/pico2_w/docs/hw.json @@ -103,6 +103,35 @@ ], "doc": "a spare UART, its writes by DMA; the HIL suite's loopback wires GPIO4 (pin 6) to GPIO5 (pin 7)", "name": "uart1" + }, + { + "doc": "TIMER1, 64 bits at 1 MHz: the counter class's (A129); TIMER0 is left for M4.4's tickless time", + "name": "timer1" + }, + { + "deps": [ + "io_bank0" + ], + "doc": "slice 7, PWM out on A, GPIO14 (pin 19); the HIL suite wires it to pin 22", + "name": "pwm7" + }, + { + "deps": [ + "io_bank0" + ], + "doc": "slice 0, PWM capture on B, GPIO17 (pin 22)", + "name": "pwm0" + }, + { + "deps": [ + "clocks", + "io_bank0" + ], + "dma": [ + "rx" + ], + "doc": "the ADC on clk_adc, 48 MHz from PLL_USB: GPIO26 (pin 31, input 0) and GPIO27 (pin 32, input 1); the HIL suite wires pin 31 to 3V3 OUT and pin 32 to AGND", + "name": "adc" } ], "doc": "The console on UART0 at 115200 baud on GPIO0 (TX, pin 1) and GPIO1 (RX, pin 2). The CPU runs at 150 MHz from PLL_SYS (the 12 MHz crystal x 125 / 5 / 2, pico-sdk's factors), and clk_peri, the UARTs' clock, follows clk_sys. The user LED is on the CYW43439 wireless chip, which has no driver yet, so the board has no LED. Images are UF2 files, copied to the boot ROM's USB drive (hold BOOTSEL while plugging in), or loaded by picotool while the board is in BOOTSEL; a test image built for the board (EMB_TEST_EMULATOR=hil) reboots into BOOTSEL when it ends, so tools/hil/run_hil.py loads the next one without the button.", @@ -127,6 +156,10 @@ } }, "pins": { + "adc": { + "in0": "GPIO26", + "in1": "GPIO27" + }, "i2c0": { "scl": "GPIO9.f3", "sda": "GPIO8.f3" @@ -135,6 +168,12 @@ "scl": "GPIO7.f3", "sda": "GPIO6.f3" }, + "pwm0": { + "b": "GPIO17.f4" + }, + "pwm7": { + "a": "GPIO14.f4" + }, "spi1": { "miso": "GPIO12.f1", "mosi": "GPIO11.f1", @@ -168,8 +207,24 @@ "bus_hz": { "sys": 150000000 }, + "bus_timer_hz": { + "sys": 150000000 + }, "bypass": false, "cpu_hz": 150000000, + "fixed_plls": { + "pll_usb": { + "hz": 48000000, + "m": 1, + "n": 64, + "name": "pll_usb", + "p": 16, + "postdiv1": 4, + "postdiv2": 4, + "vco_hz": 768000000, + "vco_in_hz": 12000000 + } + }, "hclk_hz": 150000000, "pll": { "m": 1, @@ -414,6 +469,78 @@ "level": "kernel", "name": "i2c1", "peripheral": "i2c1" + }, + { + "class": "counter", + "compatible": "rpi,rp2350-timer", + "deps": [], + "fields": { + "base": 1074495488, + "index": 1, + "irq0": 4, + "irq1": 5, + "irq2": 6, + "irq3": 7, + "rate_hz": 1000000 + }, + "level": "kernel", + "name": "timer1", + "peripheral": "timer1" + }, + { + "class": "pwm", + "compatible": "rpi,rp2350-pwm", + "deps": [ + "io_bank0" + ], + "fields": { + "base": 1074430092, + "clock_hz": 150000000, + "index": 7 + }, + "level": "kernel", + "name": "pwm7", + "peripheral": "pwm7" + }, + { + "class": "pwm", + "compatible": "rpi,rp2350-pwm", + "deps": [ + "io_bank0" + ], + "fields": { + "base": 1074429952, + "clock_hz": 150000000, + "index": 0 + }, + "level": "kernel", + "name": "pwm0", + "peripheral": "pwm0" + }, + { + "class": "adc", + "compatible": "rpi,rp2350-adc", + "deps": [ + "clocks", + "io_bank0", + "dma" + ], + "fields": { + "base": 1074397184, + "bits": 12, + "clock_hz": 48000000, + "dma_rx": { + "dma": "dma", + "request": 48, + "stream": 3 + }, + "inputs": 4, + "temperature": 4, + "vref_mv": 3300 + }, + "level": "kernel", + "name": "adc", + "peripheral": "adc" } ], "kconfig": { @@ -578,6 +705,44 @@ "pin": "GPIO13", "port": "", "signal": "spi1_cs0" + }, + { + "af": 4, + "gpio": "io_bank0", + "mode": "af", + "number": 14, + "owner": "pins.pwm7.a", + "pin": "GPIO14", + "port": "", + "signal": "pwm7_a" + }, + { + "af": 4, + "gpio": "io_bank0", + "mode": "af", + "number": 17, + "owner": "pins.pwm0.b", + "pin": "GPIO17", + "port": "", + "signal": "pwm0_b" + }, + { + "gpio": "io_bank0", + "mode": "analog", + "number": 26, + "owner": "pins.adc.in0", + "pin": "GPIO26", + "port": "", + "signal": "adc_in0" + }, + { + "gpio": "io_bank0", + "mode": "analog", + "number": 27, + "owner": "pins.adc.in1", + "pin": "GPIO27", + "port": "", + "signal": "adc_in1" } ], "profile": "base", @@ -601,124 +766,158 @@ }, { "path": "boards/rpi/pico2_w/board.yaml", - "sha256": "dad0ef7259e41ef3bd8fa07ea1c1f36040254a443deaf30d963b4fb14b5354a0" + "sha256": "345279a53c444bc45e7fcc1a0cb5ab47b32a7699534f5484ea80d73f7a0bdf6d" }, { "path": "drivers/bindings.yaml", - "sha256": "d3c336ac05548e0addd1faac18f3dff70576d8069f11d89e6a761cf5c6132b49" + "sha256": "c06d1a914adb21d0e314c79b3611ac6859eefeac1957d6914cccfc5531ad6ede" }, { "path": "examples/tasks/system.yaml", - "sha256": "3dd9de88918f06e4b3a41232cb716a9e7d1c4b74ad18e71fd51644ae394ebf9c" + "sha256": "202cff4815e97ab763dc14c61b0b694ee9381307eb46687f9caaea3465a913da" }, { "path": "soc/rpi/rp2350/rp2350.yaml", - "sha256": "9e60e99ecac8782bccd69e3bd69014af1d8891d6b6fbd822acff5bd9a526d8cd" + "sha256": "80773a9c9cfb1c62cd322e397111a11d7f48fce3c0febc76bf7d5571018977a5" }, { "path": "soc/rpi/rp2350/rp2350a.yaml", - "sha256": "045cef7794c3b6c6d2ff48ba294c6308d00fe13bc65e346f2ba2ccde1cea24ff" + "sha256": "22395e35ed229020b5c9c7586af50cfaa07960a09905776eb4713ff28051eb3c" } ], "schema_version": 0, "soc": { "alternate_functions": { "GPIO0": { - "f2": "uart0_tx" + "f2": "uart0_tx", + "f4": "pwm0_a" }, "GPIO1": { - "f2": "uart0_rx" + "f2": "uart0_rx", + "f4": "pwm0_b" }, "GPIO10": { "f1": "spi1_sck", - "f11": "uart1_tx" + "f11": "uart1_tx", + "f4": "pwm5_a" }, "GPIO11": { "f1": "spi1_mosi", - "f11": "uart1_rx" + "f11": "uart1_rx", + "f4": "pwm5_b" }, "GPIO12": { "f1": "spi1_miso", - "f2": "uart0_tx" + "f2": "uart0_tx", + "f4": "pwm6_a" }, "GPIO13": { - "f2": "uart0_rx" + "f2": "uart0_rx", + "f4": "pwm6_b" }, "GPIO14": { - "f11": "uart0_tx" + "f11": "uart0_tx", + "f4": "pwm7_a" }, "GPIO15": { - "f11": "uart0_rx" + "f11": "uart0_rx", + "f4": "pwm7_b" }, "GPIO16": { - "f2": "uart0_tx" + "f2": "uart0_tx", + "f4": "pwm0_a" }, "GPIO17": { - "f2": "uart0_rx" + "f2": "uart0_rx", + "f4": "pwm0_b" }, "GPIO18": { - "f11": "uart0_tx" + "f11": "uart0_tx", + "f4": "pwm1_a" }, "GPIO19": { - "f11": "uart0_rx" + "f11": "uart0_rx", + "f4": "pwm1_b" }, "GPIO2": { - "f11": "uart0_tx" + "f11": "uart0_tx", + "f4": "pwm1_a" }, "GPIO20": { - "f2": "uart1_tx" + "f2": "uart1_tx", + "f4": "pwm2_a" }, "GPIO21": { - "f2": "uart1_rx" + "f2": "uart1_rx", + "f4": "pwm2_b" }, "GPIO22": { - "f11": "uart1_tx" + "f11": "uart1_tx", + "f4": "pwm3_a" }, "GPIO23": { - "f11": "uart1_rx" + "f11": "uart1_rx", + "f4": "pwm3_b" }, "GPIO24": { - "f2": "uart1_tx" + "f2": "uart1_tx", + "f4": "pwm4_a" }, "GPIO25": { - "f2": "uart1_rx" + "f2": "uart1_rx", + "f4": "pwm4_b" }, "GPIO26": { - "f11": "uart1_tx" + "analog": "adc_in0", + "f11": "uart1_tx", + "f4": "pwm5_a" }, "GPIO27": { - "f11": "uart1_rx" + "analog": "adc_in1", + "f11": "uart1_rx", + "f4": "pwm5_b" }, "GPIO28": { - "f2": "uart0_tx" + "analog": "adc_in2", + "f2": "uart0_tx", + "f4": "pwm6_a" }, "GPIO29": { - "f2": "uart0_rx" + "analog": "adc_in3", + "f2": "uart0_rx", + "f4": "pwm6_b" }, "GPIO3": { - "f11": "uart0_rx" + "f11": "uart0_rx", + "f4": "pwm1_b" }, "GPIO4": { - "f2": "uart1_tx" + "f2": "uart1_tx", + "f4": "pwm2_a" }, "GPIO5": { - "f2": "uart1_rx" + "f2": "uart1_rx", + "f4": "pwm2_b" }, "GPIO6": { "f11": "uart1_tx", - "f3": "i2c1_sda" + "f3": "i2c1_sda", + "f4": "pwm3_a" }, "GPIO7": { "f11": "uart1_rx", - "f3": "i2c1_scl" + "f3": "i2c1_scl", + "f4": "pwm3_b" }, "GPIO8": { "f2": "uart1_tx", - "f3": "i2c0_sda" + "f3": "i2c0_sda", + "f4": "pwm4_a" }, "GPIO9": { "f2": "uart1_rx", - "f3": "i2c0_scl" + "f3": "i2c0_scl", + "f4": "pwm4_b" } }, "arch": { @@ -764,6 +963,33 @@ 750000000, 1600000000 ] + }, + { + "inputs": [ + "xosc" + ], + "m": [ + 1, + 63 + ], + "n": [ + 16, + 320 + ], + "name": "pll_usb", + "output_hz": 48000000, + "postdiv": [ + 1, + 7 + ], + "vco_in_hz": [ + 5000000, + 800000000 + ], + "vco_out_hz": [ + 750000000, + 1600000000 + ] } ], "sources": [ @@ -912,6 +1138,12 @@ "name": "pll_sys", "size": 16384 }, + { + "base": 1074102272, + "compatible": "rpi,rp2350-pll", + "name": "pll_usb", + "size": 16384 + }, { "base": 1074200576, "compatible": "arm,pl011", @@ -1097,6 +1329,213 @@ "compatible": "rpi,rp2350-sio", "name": "sio", "size": 4096 + }, + { + "adc": { + "bits": 12, + "inputs": 4, + "temperature": 4 + }, + "base": 1074397184, + "clocked_by": "pll_usb", + "compatible": "rpi,rp2350-adc", + "dma_requests": { + "rx": "dma.dreq48" + }, + "irqs": [ + { + "name": "fifo", + "number": 35 + } + ], + "name": "adc", + "size": 16384 + }, + { + "base": 1074430192, + "compatible": "rpi,rp2350-pwm-irq", + "irqs": [ + { + "name": "wrap0", + "number": 8 + }, + { + "name": "wrap1", + "number": 9 + } + ], + "name": "pwm", + "size": 32 + }, + { + "base": 1074429952, + "compatible": "rpi,rp2350-pwm", + "counter_bits": 16, + "dma_requests": { + "wrap": "dma.dreq32" + }, + "name": "pwm0", + "size": 20 + }, + { + "base": 1074429972, + "compatible": "rpi,rp2350-pwm", + "counter_bits": 16, + "dma_requests": { + "wrap": "dma.dreq33" + }, + "name": "pwm1", + "size": 20 + }, + { + "base": 1074429992, + "compatible": "rpi,rp2350-pwm", + "counter_bits": 16, + "dma_requests": { + "wrap": "dma.dreq34" + }, + "name": "pwm2", + "size": 20 + }, + { + "base": 1074430012, + "compatible": "rpi,rp2350-pwm", + "counter_bits": 16, + "dma_requests": { + "wrap": "dma.dreq35" + }, + "name": "pwm3", + "size": 20 + }, + { + "base": 1074430032, + "compatible": "rpi,rp2350-pwm", + "counter_bits": 16, + "dma_requests": { + "wrap": "dma.dreq36" + }, + "name": "pwm4", + "size": 20 + }, + { + "base": 1074430052, + "compatible": "rpi,rp2350-pwm", + "counter_bits": 16, + "dma_requests": { + "wrap": "dma.dreq37" + }, + "name": "pwm5", + "size": 20 + }, + { + "base": 1074430072, + "compatible": "rpi,rp2350-pwm", + "counter_bits": 16, + "dma_requests": { + "wrap": "dma.dreq38" + }, + "name": "pwm6", + "size": 20 + }, + { + "base": 1074430092, + "compatible": "rpi,rp2350-pwm", + "counter_bits": 16, + "dma_requests": { + "wrap": "dma.dreq39" + }, + "name": "pwm7", + "size": 20 + }, + { + "base": 1074430112, + "compatible": "rpi,rp2350-pwm", + "counter_bits": 16, + "dma_requests": { + "wrap": "dma.dreq40" + }, + "name": "pwm8", + "size": 20 + }, + { + "base": 1074430132, + "compatible": "rpi,rp2350-pwm", + "counter_bits": 16, + "dma_requests": { + "wrap": "dma.dreq41" + }, + "name": "pwm9", + "size": 20 + }, + { + "base": 1074430152, + "compatible": "rpi,rp2350-pwm", + "counter_bits": 16, + "dma_requests": { + "wrap": "dma.dreq42" + }, + "name": "pwm10", + "size": 20 + }, + { + "base": 1074430172, + "compatible": "rpi,rp2350-pwm", + "counter_bits": 16, + "dma_requests": { + "wrap": "dma.dreq43" + }, + "name": "pwm11", + "size": 20 + }, + { + "base": 1074462720, + "compatible": "rpi,rp2350-timer", + "counter_bits": 64, + "irqs": [ + { + "name": "alarm0", + "number": 0 + }, + { + "name": "alarm1", + "number": 1 + }, + { + "name": "alarm2", + "number": 2 + }, + { + "name": "alarm3", + "number": 3 + } + ], + "name": "timer0", + "size": 16384 + }, + { + "base": 1074495488, + "compatible": "rpi,rp2350-timer", + "counter_bits": 64, + "irqs": [ + { + "name": "alarm0", + "number": 4 + }, + { + "name": "alarm1", + "number": 5 + }, + { + "name": "alarm2", + "number": 6 + }, + { + "name": "alarm3", + "number": 7 + } + ], + "name": "timer1", + "size": 16384 } ], "schema_version": 0, diff --git a/examples/tasks/generated/pico2_w/docs/system.json b/examples/tasks/src/config/pico2_w/docs/system.json similarity index 75% rename from examples/tasks/generated/pico2_w/docs/system.json rename to examples/tasks/src/config/pico2_w/docs/system.json index 40bd8a2a..76b805df 100644 --- a/examples/tasks/generated/pico2_w/docs/system.json +++ b/examples/tasks/src/config/pico2_w/docs/system.json @@ -25,23 +25,33 @@ }, { "path": "boards/rpi/pico2_w/board.yaml", - "sha256": "dad0ef7259e41ef3bd8fa07ea1c1f36040254a443deaf30d963b4fb14b5354a0" + "sha256": "345279a53c444bc45e7fcc1a0cb5ab47b32a7699534f5484ea80d73f7a0bdf6d" }, { "path": "drivers/bindings.yaml", - "sha256": "d3c336ac05548e0addd1faac18f3dff70576d8069f11d89e6a761cf5c6132b49" + "sha256": "c06d1a914adb21d0e314c79b3611ac6859eefeac1957d6914cccfc5531ad6ede" }, { "path": "examples/tasks/system.yaml", - "sha256": "3dd9de88918f06e4b3a41232cb716a9e7d1c4b74ad18e71fd51644ae394ebf9c" + "sha256": "202cff4815e97ab763dc14c61b0b694ee9381307eb46687f9caaea3465a913da" }, { "path": "soc/rpi/rp2350/rp2350.yaml", - "sha256": "9e60e99ecac8782bccd69e3bd69014af1d8891d6b6fbd822acff5bd9a526d8cd" + "sha256": "80773a9c9cfb1c62cd322e397111a11d7f48fce3c0febc76bf7d5571018977a5" }, { "path": "soc/rpi/rp2350/rp2350a.yaml", - "sha256": "045cef7794c3b6c6d2ff48ba294c6308d00fe13bc65e346f2ba2ccde1cea24ff" + "sha256": "22395e35ed229020b5c9c7586af50cfaa07960a09905776eb4713ff28051eb3c" + } + ], + "interrupts": [ + { + "doc": "", + "handler": "WAKE_InterruptHandler", + "irq": 46, + "level": 1, + "name": "wake", + "source": null } ], "name": "tasks_demo", @@ -52,7 +62,6 @@ "spi_targets": [], "tasks": [ { - "data": "door_data_t", "doc": "", "entry": [ "open" @@ -83,7 +92,6 @@ } }, { - "data": null, "doc": "", "entry": [], "event": null, diff --git a/examples/tasks/src/config/pico2_w/docs/system.md b/examples/tasks/src/config/pico2_w/docs/system.md new file mode 100644 index 00000000..af25c2e2 --- /dev/null +++ b/examples/tasks/src/config/pico2_w/docs/system.md @@ -0,0 +1,29 @@ +# tasks_demo: the system on pico2_w + +Generated from `examples/tasks/system.yaml` (SPEC-014 §5, A125, A130). Profile base, 32 priorities, a minimum stack of 256 bytes. + +## Tasks + +| Task | Model | Priority | Stack | States (initial first) | Events | +|---|---|---|---|---|---| +| `door` | event, queue 8 | 5 | 1024 | closed, open, jammed | open, close, jam | +| `blink` | periodic, 500 ms | 2 | 512 | dark, lit | — | + +## Interrupts + +| Interrupt | Line | Handler | Level | +|---|---|---|---| +| `wake` | 46 | `WAKE_InterruptHandler` | 1 | + +--- + +Generated by emb-hwgen 0.1.0, schema v0, from: + +| Input | SHA-256 | +|---|---| +| `arch/cortex_m/arch.yaml` | `c5c8e451c09717dee1713d07f8311b6d507e3b4c66c42d93e0ce11da6ec76d6d` | +| `boards/rpi/pico2_w/board.yaml` | `345279a53c444bc45e7fcc1a0cb5ab47b32a7699534f5484ea80d73f7a0bdf6d` | +| `drivers/bindings.yaml` | `c06d1a914adb21d0e314c79b3611ac6859eefeac1957d6914cccfc5531ad6ede` | +| `examples/tasks/system.yaml` | `202cff4815e97ab763dc14c61b0b694ee9381307eb46687f9caaea3465a913da` | +| `soc/rpi/rp2350/rp2350.yaml` | `80773a9c9cfb1c62cd322e397111a11d7f48fce3c0febc76bf7d5571018977a5` | +| `soc/rpi/rp2350/rp2350a.yaml` | `22395e35ed229020b5c9c7586af50cfaa07960a09905776eb4713ff28051eb3c` | diff --git a/examples/tasks/src/config/pico2_w/initialization.c b/examples/tasks/src/config/pico2_w/initialization.c new file mode 100644 index 00000000..9f7d62fd --- /dev/null +++ b/examples/tasks/src/config/pico2_w/initialization.c @@ -0,0 +1,82 @@ +/* SPDX-License-Identifier: Apache-2.0 */ +/* + * This file is part of EmbLinkRTOS, a deterministic real-time kernel for microcontrollers. + * Licensed under the Apache License, Version 2.0; see the LICENSE file at the repository root. + */ + +/******************************************************************************* + System Initialization File + + File Name: + initialization.c + + Summary: + tasks_demo's initialization on the pico2_w: SYS_Initialize(), and the + system's objects. + + Description: + The system's static definitions, which the kernel creates from its + initialization table when emb_kernel_init() runs (SPEC-001 §6.4), and + SYS_Initialize(), which brings up the board, the kernel, the application's + interrupts and the tasks. + + Generated by emb-hwgen 0.1.0, schema v0, from the system description and the + pico2_w's. Yours to edit: regenerating merges its changes with yours (A126): + hw/gen/emb-hwgen.py generate --system examples/tasks/system.yaml + + Inputs (SHA-256): + arch/cortex_m/arch.yaml + c5c8e451c09717dee1713d07f8311b6d507e3b4c66c42d93e0ce11da6ec76d6d + boards/rpi/pico2_w/board.yaml + 345279a53c444bc45e7fcc1a0cb5ab47b32a7699534f5484ea80d73f7a0bdf6d + drivers/bindings.yaml + c06d1a914adb21d0e314c79b3611ac6859eefeac1957d6914cccfc5531ad6ede + examples/tasks/system.yaml + 202cff4815e97ab763dc14c61b0b694ee9381307eb46687f9caaea3465a913da + soc/rpi/rp2350/rp2350.yaml + 80773a9c9cfb1c62cd322e397111a11d7f48fce3c0febc76bf7d5571018977a5 + soc/rpi/rp2350/rp2350a.yaml + 22395e35ed229020b5c9c7586af50cfaa07960a09905776eb4713ff28051eb3c + *******************************************************************************/ + +// ***************************************************************************** +// ***************************************************************************** +// Section: Included Files +// ***************************************************************************** +// ***************************************************************************** + +#include "definitions.h" + +// ***************************************************************************** +// ***************************************************************************** +// Section: System Initialization +// ***************************************************************************** +// ***************************************************************************** + +/******************************************************************************* + Function: + void SYS_Initialize ( void *data ) + + Remarks: + See prototype in definitions.h. + */ +void SYS_Initialize(void *data) +{ + (void)data; + + /* The board: its clocks, pins and console */ + emb_board_init(); + + /* The kernel: its objects, and the EARLY devices */ + emb_kernel_init(); + + /* The application's interrupts */ + SYS_INT_Initialize(); + + /* The tasks, each in its initial state */ + DOOR_Initialize(); + BLINK_Initialize(); +} +/******************************************************************************* + End of File +*/ diff --git a/examples/tasks/src/config/pico2_w/interrupts.c b/examples/tasks/src/config/pico2_w/interrupts.c new file mode 100644 index 00000000..f4ddfbd1 --- /dev/null +++ b/examples/tasks/src/config/pico2_w/interrupts.c @@ -0,0 +1,94 @@ +/* SPDX-License-Identifier: Apache-2.0 */ +/* + * This file is part of EmbLinkRTOS, a deterministic real-time kernel for microcontrollers. + * Licensed under the Apache License, Version 2.0; see the LICENSE file at the repository root. + */ + +/******************************************************************************* + Interrupt Handlers + + File Name: + interrupts.c + + Summary: + tasks_demo's interrupts on the pico2_w: the lines in use, and + SYS_INT_Initialize(). + + Description: + The table of every interrupt line in use, the devices' and the + application's, and SYS_INT_Initialize(), which connects the application's + handlers. The checks were made when it was generated: each line is the + SoC's, no device's driver connects it, and its level is the port's. + + Generated by emb-hwgen 0.1.0, schema v0, from the system description and the + pico2_w's. Yours to edit: regenerating merges its changes with yours (A126): + hw/gen/emb-hwgen.py generate --system examples/tasks/system.yaml + + Inputs (SHA-256): + arch/cortex_m/arch.yaml + c5c8e451c09717dee1713d07f8311b6d507e3b4c66c42d93e0ce11da6ec76d6d + boards/rpi/pico2_w/board.yaml + 345279a53c444bc45e7fcc1a0cb5ab47b32a7699534f5484ea80d73f7a0bdf6d + drivers/bindings.yaml + c06d1a914adb21d0e314c79b3611ac6859eefeac1957d6914cccfc5531ad6ede + examples/tasks/system.yaml + 202cff4815e97ab763dc14c61b0b694ee9381307eb46687f9caaea3465a913da + soc/rpi/rp2350/rp2350.yaml + 80773a9c9cfb1c62cd322e397111a11d7f48fce3c0febc76bf7d5571018977a5 + soc/rpi/rp2350/rp2350a.yaml + 22395e35ed229020b5c9c7586af50cfaa07960a09905776eb4713ff28051eb3c + *******************************************************************************/ + +// ***************************************************************************** +// ***************************************************************************** +// Section: Included Files +// ***************************************************************************** +// ***************************************************************************** + +#include "definitions.h" + +// ***************************************************************************** +// ***************************************************************************** +// Section: Interrupt Lines +// ***************************************************************************** +// ***************************************************************************** + +/* The lines in use on the pico2_w: + * 4 timer1, its driver (peripheral.irqs.alarm0) + * 5 timer1, its driver (peripheral.irqs.alarm1) + * 6 timer1, its driver (peripheral.irqs.alarm2) + * 7 timer1, its driver (peripheral.irqs.alarm3) + * 10 dma, its driver (peripheral.irqs.irq0) + * 32 spi1, its driver (peripheral.irqs.global) + * 33 uart0, its driver (peripheral.irqs.global) + * 34 uart1, its driver (peripheral.irqs.global) + * 36 i2c0, its driver (peripheral.irqs.global) + * 37 i2c1, its driver (peripheral.irqs.global) + * 39 trng, its driver (peripheral.irqs.irq) + * 45 rtc, its driver (peripheral.irqs.timer) + * 46 wake, the application's WAKE_InterruptHandler() + */ + +// ***************************************************************************** +// ***************************************************************************** +// Section: Interrupt Initialization +// ***************************************************************************** +// ***************************************************************************** + +/******************************************************************************* + Function: + void SYS_INT_Initialize ( void ) + + Remarks: + See prototype in interrupts.h. + */ +void SYS_INT_Initialize(void) +{ + /* wake: line 46 */ + (void)emb_irq_connect(WAKE_IRQ, WAKE_InterruptHandler, NULL); + (void)emb_irq_set_level(WAKE_IRQ, WAKE_IRQ_LEVEL); + (void)emb_irq_enable(WAKE_IRQ); +} +/******************************************************************************* + End of File +*/ diff --git a/examples/tasks/src/config/pico2_w/interrupts.h b/examples/tasks/src/config/pico2_w/interrupts.h new file mode 100644 index 00000000..f36963b4 --- /dev/null +++ b/examples/tasks/src/config/pico2_w/interrupts.h @@ -0,0 +1,130 @@ +/* SPDX-License-Identifier: Apache-2.0 */ +/* + * This file is part of EmbLinkRTOS, a deterministic real-time kernel for microcontrollers. + * Licensed under the Apache License, Version 2.0; see the LICENSE file at the repository root. + */ + +/******************************************************************************* + Interrupt Handlers + + File Name: + interrupts.h + + Summary: + tasks_demo's interrupt handlers on the pico2_w. + + Description: + The application's own interrupt handlers, which it defines + (src/interrupt_handlers.c), and SYS_INT_Initialize(), which connects each at + its level and enables it. The board's devices connect their own: + interrupts.c lists every line in use. + + Generated by emb-hwgen 0.1.0, schema v0, from the system description and the + pico2_w's. Yours to edit: regenerating merges its changes with yours (A126): + hw/gen/emb-hwgen.py generate --system examples/tasks/system.yaml + + Inputs (SHA-256): + arch/cortex_m/arch.yaml + c5c8e451c09717dee1713d07f8311b6d507e3b4c66c42d93e0ce11da6ec76d6d + boards/rpi/pico2_w/board.yaml + 345279a53c444bc45e7fcc1a0cb5ab47b32a7699534f5484ea80d73f7a0bdf6d + drivers/bindings.yaml + c06d1a914adb21d0e314c79b3611ac6859eefeac1957d6914cccfc5531ad6ede + examples/tasks/system.yaml + 202cff4815e97ab763dc14c61b0b694ee9381307eb46687f9caaea3465a913da + soc/rpi/rp2350/rp2350.yaml + 80773a9c9cfb1c62cd322e397111a11d7f48fce3c0febc76bf7d5571018977a5 + soc/rpi/rp2350/rp2350a.yaml + 22395e35ed229020b5c9c7586af50cfaa07960a09905776eb4713ff28051eb3c + *******************************************************************************/ + +#ifndef INTERRUPTS_H +#define INTERRUPTS_H + +// ***************************************************************************** +// ***************************************************************************** +// Section: Included Files +// ***************************************************************************** +// ***************************************************************************** + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +// ***************************************************************************** +// ***************************************************************************** +// Section: Handler Routines +// ***************************************************************************** +// ***************************************************************************** + +/******************************************************************************* + Function: + void WAKE_InterruptHandler ( void *arg ) + + Summary: + The wake interrupt's handler. + + Description: + This function runs in interrupt context when line 46 is raised at level 1: a + kernel-aware handler, which may post to a task (emb_task_post()) but not + wait. + + Precondition: + SYS_INT_Initialize() has connected it. + + Parameters: + arg - Unused; NULL. + + Returns: + None. + + Example: + + emb_irq_pend(WAKE_IRQ); + + + Remarks: + The application defines it. Keep it short: hand the work to a task. +*/ +void WAKE_InterruptHandler(void *arg); + +/******************************************************************************* + Function: + void SYS_INT_Initialize ( void ) + + Summary: + Connects the application's interrupt handlers. + + Description: + This function connects each of the application's handlers to its line, sets + its level and enables it. + + Precondition: + The kernel is initialized (emb_kernel_init()). + + Parameters: + None. + + Returns: + None. + + Example: + + SYS_INT_Initialize(); + + + Remarks: + SYS_Initialize() calls it. +*/ +void SYS_INT_Initialize(void); + +#ifdef __cplusplus +} +#endif + +#endif /* INTERRUPTS_H */ +/******************************************************************************* + End of File +*/ diff --git a/examples/tasks/generated/pico2_w/linker/regions.ld b/examples/tasks/src/config/pico2_w/linker/regions.ld similarity index 90% rename from examples/tasks/generated/pico2_w/linker/regions.ld rename to examples/tasks/src/config/pico2_w/linker/regions.ld index bb8a8d44..49f1e7d0 100644 --- a/examples/tasks/generated/pico2_w/linker/regions.ld +++ b/examples/tasks/src/config/pico2_w/linker/regions.ld @@ -16,15 +16,15 @@ * arch/cortex_m/arch.yaml * c5c8e451c09717dee1713d07f8311b6d507e3b4c66c42d93e0ce11da6ec76d6d * boards/rpi/pico2_w/board.yaml - * dad0ef7259e41ef3bd8fa07ea1c1f36040254a443deaf30d963b4fb14b5354a0 + * 345279a53c444bc45e7fcc1a0cb5ab47b32a7699534f5484ea80d73f7a0bdf6d * drivers/bindings.yaml - * d3c336ac05548e0addd1faac18f3dff70576d8069f11d89e6a761cf5c6132b49 + * c06d1a914adb21d0e314c79b3611ac6859eefeac1957d6914cccfc5531ad6ede * examples/tasks/system.yaml - * 3dd9de88918f06e4b3a41232cb716a9e7d1c4b74ad18e71fd51644ae394ebf9c + * 202cff4815e97ab763dc14c61b0b694ee9381307eb46687f9caaea3465a913da * soc/rpi/rp2350/rp2350.yaml - * 9e60e99ecac8782bccd69e3bd69014af1d8891d6b6fbd822acff5bd9a526d8cd + * 80773a9c9cfb1c62cd322e397111a11d7f48fce3c0febc76bf7d5571018977a5 * soc/rpi/rp2350/rp2350a.yaml - * 045cef7794c3b6c6d2ff48ba294c6308d00fe13bc65e346f2ba2ccde1cea24ff + * 22395e35ed229020b5c9c7586af50cfaa07960a09905776eb4713ff28051eb3c */ ENTRY(embn_cm_reset) diff --git a/examples/tasks/generated/.base/pico2_w/src/board_pins.c b/examples/tasks/src/config/pico2_w/peripheral/board_pins.c similarity index 76% rename from examples/tasks/generated/.base/pico2_w/src/board_pins.c rename to examples/tasks/src/config/pico2_w/peripheral/board_pins.c index 6dcaebc6..dd5fde39 100644 --- a/examples/tasks/generated/.base/pico2_w/src/board_pins.c +++ b/examples/tasks/src/config/pico2_w/peripheral/board_pins.c @@ -18,15 +18,15 @@ * arch/cortex_m/arch.yaml * c5c8e451c09717dee1713d07f8311b6d507e3b4c66c42d93e0ce11da6ec76d6d * boards/rpi/pico2_w/board.yaml - * dad0ef7259e41ef3bd8fa07ea1c1f36040254a443deaf30d963b4fb14b5354a0 + * 345279a53c444bc45e7fcc1a0cb5ab47b32a7699534f5484ea80d73f7a0bdf6d * drivers/bindings.yaml - * d3c336ac05548e0addd1faac18f3dff70576d8069f11d89e6a761cf5c6132b49 + * c06d1a914adb21d0e314c79b3611ac6859eefeac1957d6914cccfc5531ad6ede * examples/tasks/system.yaml - * 3dd9de88918f06e4b3a41232cb716a9e7d1c4b74ad18e71fd51644ae394ebf9c + * 202cff4815e97ab763dc14c61b0b694ee9381307eb46687f9caaea3465a913da * soc/rpi/rp2350/rp2350.yaml - * 9e60e99ecac8782bccd69e3bd69014af1d8891d6b6fbd822acff5bd9a526d8cd + * 80773a9c9cfb1c62cd322e397111a11d7f48fce3c0febc76bf7d5571018977a5 * soc/rpi/rp2350/rp2350a.yaml - * 045cef7794c3b6c6d2ff48ba294c6308d00fe13bc65e346f2ba2ccde1cea24ff + * 22395e35ed229020b5c9c7586af50cfaa07960a09905776eb4713ff28051eb3c */ #include #include @@ -56,6 +56,14 @@ const emb_rp2350_pin_t emb_board_pins[] = { {12u, 1u, 1u, EMB_RP2350_PULL_RESET, EMB_RP2350_OUT_NONE}, /* GPIO13: devices.spi1.cs[0] (spi1_cs0) */ {13u, 5u, 1u, EMB_RP2350_PULL_RESET, EMB_RP2350_OUT_HIGH}, + /* GPIO14: pins.pwm7.a (pwm7_a) */ + {14u, 4u, 1u, EMB_RP2350_PULL_RESET, EMB_RP2350_OUT_NONE}, + /* GPIO17: pins.pwm0.b (pwm0_b) */ + {17u, 4u, 1u, EMB_RP2350_PULL_RESET, EMB_RP2350_OUT_NONE}, + /* GPIO26: pins.adc.in0 (adc_in0) */ + {26u, 31u, 0u, EMB_RP2350_PULL_NONE, EMB_RP2350_OUT_NONE}, + /* GPIO27: pins.adc.in1 (adc_in1) */ + {27u, 31u, 0u, EMB_RP2350_PULL_NONE, EMB_RP2350_OUT_NONE}, }; const unsigned emb_board_pin_count = (unsigned)(sizeof(emb_board_pins) / sizeof(emb_board_pins[0])); diff --git a/examples/tasks/generated/.base/pico2_w/src/boot_block.c b/examples/tasks/src/config/pico2_w/peripheral/boot_block.c similarity index 77% rename from examples/tasks/generated/.base/pico2_w/src/boot_block.c rename to examples/tasks/src/config/pico2_w/peripheral/boot_block.c index 10766db0..f0932ecd 100644 --- a/examples/tasks/generated/.base/pico2_w/src/boot_block.c +++ b/examples/tasks/src/config/pico2_w/peripheral/boot_block.c @@ -15,15 +15,15 @@ * arch/cortex_m/arch.yaml * c5c8e451c09717dee1713d07f8311b6d507e3b4c66c42d93e0ce11da6ec76d6d * boards/rpi/pico2_w/board.yaml - * dad0ef7259e41ef3bd8fa07ea1c1f36040254a443deaf30d963b4fb14b5354a0 + * 345279a53c444bc45e7fcc1a0cb5ab47b32a7699534f5484ea80d73f7a0bdf6d * drivers/bindings.yaml - * d3c336ac05548e0addd1faac18f3dff70576d8069f11d89e6a761cf5c6132b49 + * c06d1a914adb21d0e314c79b3611ac6859eefeac1957d6914cccfc5531ad6ede * examples/tasks/system.yaml - * 3dd9de88918f06e4b3a41232cb716a9e7d1c4b74ad18e71fd51644ae394ebf9c + * 202cff4815e97ab763dc14c61b0b694ee9381307eb46687f9caaea3465a913da * soc/rpi/rp2350/rp2350.yaml - * 9e60e99ecac8782bccd69e3bd69014af1d8891d6b6fbd822acff5bd9a526d8cd + * 80773a9c9cfb1c62cd322e397111a11d7f48fce3c0febc76bf7d5571018977a5 * soc/rpi/rp2350/rp2350a.yaml - * 045cef7794c3b6c6d2ff48ba294c6308d00fe13bc65e346f2ba2ccde1cea24ff + * 22395e35ed229020b5c9c7586af50cfaa07960a09905776eb4713ff28051eb3c */ #include diff --git a/examples/tasks/generated/.base/pico2_w/include/hw_config.h b/examples/tasks/src/config/pico2_w/peripheral/hw_config.h similarity index 60% rename from examples/tasks/generated/.base/pico2_w/include/hw_config.h rename to examples/tasks/src/config/pico2_w/peripheral/hw_config.h index 724d5355..a2fe180e 100644 --- a/examples/tasks/generated/.base/pico2_w/include/hw_config.h +++ b/examples/tasks/src/config/pico2_w/peripheral/hw_config.h @@ -15,15 +15,15 @@ * arch/cortex_m/arch.yaml * c5c8e451c09717dee1713d07f8311b6d507e3b4c66c42d93e0ce11da6ec76d6d * boards/rpi/pico2_w/board.yaml - * dad0ef7259e41ef3bd8fa07ea1c1f36040254a443deaf30d963b4fb14b5354a0 + * 345279a53c444bc45e7fcc1a0cb5ab47b32a7699534f5484ea80d73f7a0bdf6d * drivers/bindings.yaml - * d3c336ac05548e0addd1faac18f3dff70576d8069f11d89e6a761cf5c6132b49 + * c06d1a914adb21d0e314c79b3611ac6859eefeac1957d6914cccfc5531ad6ede * examples/tasks/system.yaml - * 3dd9de88918f06e4b3a41232cb716a9e7d1c4b74ad18e71fd51644ae394ebf9c + * 202cff4815e97ab763dc14c61b0b694ee9381307eb46687f9caaea3465a913da * soc/rpi/rp2350/rp2350.yaml - * 9e60e99ecac8782bccd69e3bd69014af1d8891d6b6fbd822acff5bd9a526d8cd + * 80773a9c9cfb1c62cd322e397111a11d7f48fce3c0febc76bf7d5571018977a5 * soc/rpi/rp2350/rp2350a.yaml - * 045cef7794c3b6c6d2ff48ba294c6308d00fe13bc65e346f2ba2ccde1cea24ff + * 22395e35ed229020b5c9c7586af50cfaa07960a09905776eb4713ff28051eb3c */ #ifndef HW_CONFIG_H #define HW_CONFIG_H @@ -34,17 +34,22 @@ #define EMB_HW_SOC_PACKAGE "qfn60" /* clock tree (150 MHz) */ -#define EMB_HW_AHB_DIV 1u -#define EMB_HW_CPU_HZ 150000000u -#define EMB_HW_PLL_M 1u -#define EMB_HW_PLL_N 125u -#define EMB_HW_PLL_P 10u -#define EMB_HW_PLL_POSTDIV1 5u -#define EMB_HW_PLL_POSTDIV2 2u -#define EMB_HW_PLL_VCO_HZ 1500000000u -#define EMB_HW_SYS_HZ 150000000u -#define EMB_HW_XOSC_BYPASS 0 -#define EMB_HW_XOSC_HZ 12000000u +#define EMB_HW_AHB_DIV 1u +#define EMB_HW_CPU_HZ 150000000u +#define EMB_HW_PLL_M 1u +#define EMB_HW_PLL_N 125u +#define EMB_HW_PLL_P 10u +#define EMB_HW_PLL_POSTDIV1 5u +#define EMB_HW_PLL_POSTDIV2 2u +#define EMB_HW_PLL_USB_HZ 48000000u +#define EMB_HW_PLL_USB_M 1u +#define EMB_HW_PLL_USB_N 64u +#define EMB_HW_PLL_USB_POSTDIV1 4u +#define EMB_HW_PLL_USB_POSTDIV2 4u +#define EMB_HW_PLL_VCO_HZ 1500000000u +#define EMB_HW_SYS_HZ 150000000u +#define EMB_HW_XOSC_BYPASS 0 +#define EMB_HW_XOSC_HZ 12000000u /* memory regions */ #define EMB_HW_SRAM_BASE 0x20000000u @@ -59,6 +64,8 @@ #define EMB_HW_IRQ_PRIORITY_BITS 4u /* peripherals: register blocks, interrupt lines, clock gates */ +#define EMB_HW_ADC_BASE 0x400A0000u +#define EMB_HW_ADC_IRQ_FIFO 35u #define EMB_HW_BOOTRAM_BASE 0x400E0000u #define EMB_HW_CLOCKS_BASE 0x40010000u #define EMB_HW_CLOCKS_IRQ 30u @@ -75,9 +82,25 @@ #define EMB_HW_IO_BANK0_IRQ_BANK0 21u #define EMB_HW_PADS_BANK0_BASE 0x40038000u #define EMB_HW_PLL_SYS_BASE 0x40050000u +#define EMB_HW_PLL_USB_BASE 0x40058000u #define EMB_HW_POWMAN_BASE 0x40100000u #define EMB_HW_POWMAN_IRQ_TIMER 45u #define EMB_HW_PSM_BASE 0x40018000u +#define EMB_HW_PWM0_BASE 0x400A8000u +#define EMB_HW_PWM10_BASE 0x400A80C8u +#define EMB_HW_PWM11_BASE 0x400A80DCu +#define EMB_HW_PWM1_BASE 0x400A8014u +#define EMB_HW_PWM2_BASE 0x400A8028u +#define EMB_HW_PWM3_BASE 0x400A803Cu +#define EMB_HW_PWM4_BASE 0x400A8050u +#define EMB_HW_PWM5_BASE 0x400A8064u +#define EMB_HW_PWM6_BASE 0x400A8078u +#define EMB_HW_PWM7_BASE 0x400A808Cu +#define EMB_HW_PWM8_BASE 0x400A80A0u +#define EMB_HW_PWM9_BASE 0x400A80B4u +#define EMB_HW_PWM_BASE 0x400A80F0u +#define EMB_HW_PWM_IRQ_WRAP0 8u +#define EMB_HW_PWM_IRQ_WRAP1 9u #define EMB_HW_QMI_BASE 0x400D0000u #define EMB_HW_RESETS_BASE 0x40020000u #define EMB_HW_SIO_BASE 0xD0000000u @@ -86,6 +109,16 @@ #define EMB_HW_SPI1_BASE 0x40088000u #define EMB_HW_SPI1_IRQ 32u #define EMB_HW_TICKS_BASE 0x40108000u +#define EMB_HW_TIMER0_BASE 0x400B0000u +#define EMB_HW_TIMER0_IRQ_ALARM0 0u +#define EMB_HW_TIMER0_IRQ_ALARM1 1u +#define EMB_HW_TIMER0_IRQ_ALARM2 2u +#define EMB_HW_TIMER0_IRQ_ALARM3 3u +#define EMB_HW_TIMER1_BASE 0x400B8000u +#define EMB_HW_TIMER1_IRQ_ALARM0 4u +#define EMB_HW_TIMER1_IRQ_ALARM1 5u +#define EMB_HW_TIMER1_IRQ_ALARM2 6u +#define EMB_HW_TIMER1_IRQ_ALARM3 7u #define EMB_HW_TRNG_BASE 0x400F0000u #define EMB_HW_TRNG_IRQ_IRQ 39u #define EMB_HW_UART0_BASE 0x40070000u diff --git a/examples/tasks/generated/.base/pico2_w/src/soc_devices.c b/examples/tasks/src/config/pico2_w/peripheral/soc_devices.c similarity index 74% rename from examples/tasks/generated/.base/pico2_w/src/soc_devices.c rename to examples/tasks/src/config/pico2_w/peripheral/soc_devices.c index f9c244af..6ebd6f57 100644 --- a/examples/tasks/generated/.base/pico2_w/src/soc_devices.c +++ b/examples/tasks/src/config/pico2_w/peripheral/soc_devices.c @@ -16,15 +16,15 @@ * arch/cortex_m/arch.yaml * c5c8e451c09717dee1713d07f8311b6d507e3b4c66c42d93e0ce11da6ec76d6d * boards/rpi/pico2_w/board.yaml - * dad0ef7259e41ef3bd8fa07ea1c1f36040254a443deaf30d963b4fb14b5354a0 + * 345279a53c444bc45e7fcc1a0cb5ab47b32a7699534f5484ea80d73f7a0bdf6d * drivers/bindings.yaml - * d3c336ac05548e0addd1faac18f3dff70576d8069f11d89e6a761cf5c6132b49 + * c06d1a914adb21d0e314c79b3611ac6859eefeac1957d6914cccfc5531ad6ede * examples/tasks/system.yaml - * 3dd9de88918f06e4b3a41232cb716a9e7d1c4b74ad18e71fd51644ae394ebf9c + * 202cff4815e97ab763dc14c61b0b694ee9381307eb46687f9caaea3465a913da * soc/rpi/rp2350/rp2350.yaml - * 9e60e99ecac8782bccd69e3bd69014af1d8891d6b6fbd822acff5bd9a526d8cd + * 80773a9c9cfb1c62cd322e397111a11d7f48fce3c0febc76bf7d5571018977a5 * soc/rpi/rp2350/rp2350a.yaml - * 045cef7794c3b6c6d2ff48ba294c6308d00fe13bc65e346f2ba2ccde1cea24ff + * 22395e35ed229020b5c9c7586af50cfaa07960a09905776eb4713ff28051eb3c */ #include @@ -297,6 +297,97 @@ const emb_device_t emb_dev_i2c1 = { .dep_count = 1u, }; +/* timer1: rpi,rp2350-timer, counter, KERNEL */ +static const emb_rp2350_timer_config_t timer1_config = { + .base = 0x400B8000u, /* peripheral.base */ + .index = 1u, /* peripheral.index */ + .rate_hz = 1000000u, /* device.rate_hz, its default */ + .irq0 = 4u, /* peripheral.irqs.alarm0 */ + .irq1 = 5u, /* peripheral.irqs.alarm1 */ + .irq2 = 6u, /* peripheral.irqs.alarm2 */ + .irq3 = 7u, /* peripheral.irqs.alarm3 */ +}; +static emb_device_state_t timer1_state; +static emb_rp2350_timer_data_t timer1_data; +const emb_device_t emb_dev_timer1 = { + .name = "timer1", + .api = &emb_rp2350_timer_api.dev, + .config = &timer1_config, + .state = &timer1_state, + .data = &timer1_data, + .deps = NULL, + .class_id = EMB_DRV_CLASS_COUNTER, + .level = EMB_DEVICE_KERNEL, + .dep_count = 0u, +}; + +/* pwm7: rpi,rp2350-pwm, pwm, KERNEL */ +static const emb_rp2350_pwm_config_t pwm7_config = { + .base = 0x400A808Cu, /* peripheral.base */ + .index = 7u, /* peripheral.index */ + .clock_hz = 150000000u, /* peripheral.clock_hz */ +}; +static emb_device_state_t pwm7_state; +static emb_rp2350_pwm_data_t pwm7_data; +static const emb_device_t *const pwm7_deps[] = {&emb_dev_io_bank0}; +const emb_device_t emb_dev_pwm7 = { + .name = "pwm7", + .api = &emb_rp2350_pwm_api.dev, + .config = &pwm7_config, + .state = &pwm7_state, + .data = &pwm7_data, + .deps = pwm7_deps, + .class_id = EMB_DRV_CLASS_PWM, + .level = EMB_DEVICE_KERNEL, + .dep_count = 1u, +}; + +/* pwm0: rpi,rp2350-pwm, pwm, KERNEL */ +static const emb_rp2350_pwm_config_t pwm0_config = { + .base = 0x400A8000u, /* peripheral.base */ + .index = 0u, /* peripheral.index */ + .clock_hz = 150000000u, /* peripheral.clock_hz */ +}; +static emb_device_state_t pwm0_state; +static emb_rp2350_pwm_data_t pwm0_data; +static const emb_device_t *const pwm0_deps[] = {&emb_dev_io_bank0}; +const emb_device_t emb_dev_pwm0 = { + .name = "pwm0", + .api = &emb_rp2350_pwm_api.dev, + .config = &pwm0_config, + .state = &pwm0_state, + .data = &pwm0_data, + .deps = pwm0_deps, + .class_id = EMB_DRV_CLASS_PWM, + .level = EMB_DEVICE_KERNEL, + .dep_count = 1u, +}; + +/* adc: rpi,rp2350-adc, adc, KERNEL */ +static const emb_rp2350_adc_config_t adc_config = { + .base = 0x400A0000u, /* peripheral.base */ + .clock_hz = 48000000u, /* peripheral.clock_hz */ + .vref_mv = 3300u, /* device.vref_mv, its default */ + .bits = 12u, /* peripheral.adc.bits */ + .inputs = 4u, /* peripheral.adc.inputs */ + .temperature = 4u, /* peripheral.adc.temperature */ + .dma_rx = {&emb_dev_dma, 3u, 48u, {0u, 0u}}, /* dma.rx */ +}; +static emb_device_state_t adc_state; +static emb_rp2350_adc_data_t adc_data; +static const emb_device_t *const adc_deps[] = {&emb_dev_clocks, &emb_dev_io_bank0, &emb_dev_dma}; +const emb_device_t emb_dev_adc = { + .name = "adc", + .api = &emb_rp2350_adc_api.dev, + .config = &adc_config, + .state = &adc_state, + .data = &adc_data, + .deps = adc_deps, + .class_id = EMB_DRV_CLASS_ADC, + .level = EMB_DEVICE_KERNEL, + .dep_count = 3u, +}; + /* in initialization order */ static const emb_device_t *const devices[] = { &emb_dev_clocks, /* 0: EARLY */ @@ -311,9 +402,13 @@ static const emb_device_t *const devices[] = { &emb_dev_spi1, /* 9: KERNEL */ &emb_dev_i2c0, /* 10: KERNEL */ &emb_dev_i2c1, /* 11: KERNEL */ + &emb_dev_timer1, /* 12: KERNEL */ + &emb_dev_pwm7, /* 13: KERNEL */ + &emb_dev_pwm0, /* 14: KERNEL */ + &emb_dev_adc, /* 15: KERNEL */ }; -const emb_device_table_t emb_board_device_table = {devices, 12u, 8u}; +const emb_device_table_t emb_board_device_table = {devices, 16u, 8u}; #if CONFIG_EMB_DRV_ENTROPY /* the board's entropy source, or none: nothing stands in for one (SPEC-017 §11, SEC-012) */ diff --git a/examples/tasks/generated/.base/pico2_w/include/soc_devices.h b/examples/tasks/src/config/pico2_w/peripheral/soc_devices.h similarity index 79% rename from examples/tasks/generated/.base/pico2_w/include/soc_devices.h rename to examples/tasks/src/config/pico2_w/peripheral/soc_devices.h index babc37ae..3956ddeb 100644 --- a/examples/tasks/generated/.base/pico2_w/include/soc_devices.h +++ b/examples/tasks/src/config/pico2_w/peripheral/soc_devices.h @@ -15,22 +15,22 @@ * arch/cortex_m/arch.yaml * c5c8e451c09717dee1713d07f8311b6d507e3b4c66c42d93e0ce11da6ec76d6d * boards/rpi/pico2_w/board.yaml - * dad0ef7259e41ef3bd8fa07ea1c1f36040254a443deaf30d963b4fb14b5354a0 + * 345279a53c444bc45e7fcc1a0cb5ab47b32a7699534f5484ea80d73f7a0bdf6d * drivers/bindings.yaml - * d3c336ac05548e0addd1faac18f3dff70576d8069f11d89e6a761cf5c6132b49 + * c06d1a914adb21d0e314c79b3611ac6859eefeac1957d6914cccfc5531ad6ede * examples/tasks/system.yaml - * 3dd9de88918f06e4b3a41232cb716a9e7d1c4b74ad18e71fd51644ae394ebf9c + * 202cff4815e97ab763dc14c61b0b694ee9381307eb46687f9caaea3465a913da * soc/rpi/rp2350/rp2350.yaml - * 9e60e99ecac8782bccd69e3bd69014af1d8891d6b6fbd822acff5bd9a526d8cd + * 80773a9c9cfb1c62cd322e397111a11d7f48fce3c0febc76bf7d5571018977a5 * soc/rpi/rp2350/rp2350a.yaml - * 045cef7794c3b6c6d2ff48ba294c6308d00fe13bc65e346f2ba2ccde1cea24ff + * 22395e35ed229020b5c9c7586af50cfaa07960a09905776eb4713ff28051eb3c */ #ifndef EMB_SOC_DEVICES_H #define EMB_SOC_DEVICES_H #include -#define EMB_SOC_DEVICE_COUNT 12u +#define EMB_SOC_DEVICE_COUNT 16u #if CONFIG_EMB_DEVICE #include @@ -48,6 +48,10 @@ extern const emb_device_t emb_dev_trng; extern const emb_device_t emb_dev_spi1; extern const emb_device_t emb_dev_i2c0; extern const emb_device_t emb_dev_i2c1; +extern const emb_device_t emb_dev_timer1; +extern const emb_device_t emb_dev_pwm7; +extern const emb_device_t emb_dev_pwm0; +extern const emb_device_t emb_dev_adc; /* which devices the board has, for code that uses one only where it exists */ #define EMB_SOC_HAS_CLOCKS 1 @@ -62,6 +66,10 @@ extern const emb_device_t emb_dev_i2c1; #define EMB_SOC_HAS_SPI1 1 #define EMB_SOC_HAS_I2C0 1 #define EMB_SOC_HAS_I2C1 1 +#define EMB_SOC_HAS_TIMER1 1 +#define EMB_SOC_HAS_PWM7 1 +#define EMB_SOC_HAS_PWM0 1 +#define EMB_SOC_HAS_ADC 1 /* the board's watchdog device: the first of its class */ #define EMB_SOC_WATCHDOG_DEVICE (&emb_dev_watchdog) @@ -69,6 +77,11 @@ extern const emb_device_t emb_dev_i2c1; /* the board's RTC device: the first of its class */ #define EMB_SOC_RTC_DEVICE (&emb_dev_rtc) +/* the board's counters: the first of their class, and all of them (SPEC-017 §11a) */ +#define EMB_SOC_COUNTER_DEVICE (&emb_dev_timer1) +#define EMB_SOC_COUNTER_DEVICES &emb_dev_timer1 +#define EMB_SOC_COUNTER_COUNT 1u + /* the board's entropy source: the first of its class (SPEC-017 §11) */ #define EMB_SOC_ENTROPY_DEVICE (&emb_dev_trng) @@ -90,6 +103,7 @@ extern const emb_device_t emb_dev_i2c1; #define EMB_SOC_UART1_DMA_TX {&emb_dev_dma, 2u, 30u, {0u, 0u}} #define EMB_SOC_SPI1_DMA_RX {&emb_dev_dma, 1u, 27u, {0u, 0u}} #define EMB_SOC_SPI1_DMA_TX {&emb_dev_dma, 0u, 26u, {0u, 0u}} +#define EMB_SOC_ADC_DMA_RX {&emb_dev_dma, 3u, 48u, {0u, 0u}} /* clang-format on */ /* the SPI devices' chip selects (devices[].cs), emb_drv_gpio_line_t initializers; the pin diff --git a/examples/tasks/src/config/pico2_w/tasks.c b/examples/tasks/src/config/pico2_w/tasks.c new file mode 100644 index 00000000..6031753e --- /dev/null +++ b/examples/tasks/src/config/pico2_w/tasks.c @@ -0,0 +1,203 @@ +/* SPDX-License-Identifier: Apache-2.0 */ +/* + * This file is part of EmbLinkRTOS, a deterministic real-time kernel for microcontrollers. + * Licensed under the Apache License, Version 2.0; see the LICENSE file at the repository root. + */ + +/******************************************************************************* + System Tasks File + + File Name: + tasks.c + + Summary: + tasks_demo's tasks on the pico2_w, and SYS_Tasks(). + + Description: + Each task's thread, queue, dispatch and description: the thread runs the + task runtime, emb_task_run() (SPEC-020), which calls an event task's handler + for each event, and a periodic task's _Tasks() every period, without drift. + SYS_Tasks() starts the kernel. + + Generated by emb-hwgen 0.1.0, schema v0, from the system description and the + pico2_w's. Yours to edit: regenerating merges its changes with yours (A126): + hw/gen/emb-hwgen.py generate --system examples/tasks/system.yaml + + Inputs (SHA-256): + arch/cortex_m/arch.yaml + c5c8e451c09717dee1713d07f8311b6d507e3b4c66c42d93e0ce11da6ec76d6d + boards/rpi/pico2_w/board.yaml + 345279a53c444bc45e7fcc1a0cb5ab47b32a7699534f5484ea80d73f7a0bdf6d + drivers/bindings.yaml + c06d1a914adb21d0e314c79b3611ac6859eefeac1957d6914cccfc5531ad6ede + examples/tasks/system.yaml + 202cff4815e97ab763dc14c61b0b694ee9381307eb46687f9caaea3465a913da + soc/rpi/rp2350/rp2350.yaml + 80773a9c9cfb1c62cd322e397111a11d7f48fce3c0febc76bf7d5571018977a5 + soc/rpi/rp2350/rp2350a.yaml + 22395e35ed229020b5c9c7586af50cfaa07960a09905776eb4713ff28051eb3c + *******************************************************************************/ + +// ***************************************************************************** +// ***************************************************************************** +// Section: Included Files +// ***************************************************************************** +// ***************************************************************************** + +#include "definitions.h" + +// ***************************************************************************** +// ***************************************************************************** +// Section: RTOS "Tasks" Routine +// ***************************************************************************** +// ***************************************************************************** + +/* ---- door: an event task, its queue 8 deep (SPEC-020) ---- */ + +_Static_assert(DOOR_STATE_CLOSED == 0, "door.h: DOOR_STATES are system.yaml's states, in order"); +_Static_assert(DOOR_STATE_OPEN == 1, "door.h: DOOR_STATES are system.yaml's states, in order"); +_Static_assert(DOOR_STATE_JAMMED == 2, "door.h: DOOR_STATES are system.yaml's states, in order"); +_Static_assert(DOOR_EVENT_OPEN == EMB_EV_USER + 0u, + "door.h: DOOR_EVENTS are system.yaml's events, in order"); +_Static_assert(DOOR_EVENT_CLOSE == EMB_EV_USER + 1u, + "door.h: DOOR_EVENTS are system.yaml's events, in order"); +_Static_assert(DOOR_EVENT_JAM == EMB_EV_USER + 2u, + "door.h: DOOR_EVENTS are system.yaml's events, in order"); + +static emb_task_event_t door_event; +EMB_MSGQ_DEFINE(door_task_queue, sizeof(emb_task_event_t), DOOR_QUEUE_LENGTH, 0u); +static const uint32_t door_timeouts[3] = {0u, DOOR_OPEN_TIMEOUT_MS, 0u}; + +static emb_state_t door_dispatch(emb_state_t state, uint8_t why) +{ + emb_state_t next = state; /* a state the task lacks stays: the runtime faults on it */ + if (why == EMB_TASK_WHY_TIMEOUT) { + door_event.id = EMB_EV_TIMEOUT; + door_event.value = 0u; + } + switch (state) { + case DOOR_STATE_CLOSED: + doorData.state = DOOR_STATE_CLOSED; + next = (emb_state_t)DOOR_OnClosed(&door_event); + break; + case DOOR_STATE_OPEN: + doorData.state = DOOR_STATE_OPEN; + next = (emb_state_t)DOOR_OnOpen(&door_event); + break; + case DOOR_STATE_JAMMED: + doorData.state = DOOR_STATE_JAMMED; + next = (emb_state_t)DOOR_OnJammed(&door_event); + break; + default: + break; + } + return next; +} + +static void door_enter(emb_state_t state) +{ + switch (state) { + case DOOR_STATE_CLOSED: + doorData.state = DOOR_STATE_CLOSED; + break; + case DOOR_STATE_OPEN: + doorData.state = DOOR_STATE_OPEN; + DOOR_EnterOpen(); + break; + case DOOR_STATE_JAMMED: + doorData.state = DOOR_STATE_JAMMED; + break; + default: + break; + } +} + +static void door_exit(emb_state_t state) +{ + if (state == DOOR_STATE_OPEN) { + DOOR_ExitOpen(); + } +} + +static const emb_task_desc_t door_desc = { + .name = "door", + .dispatch = door_dispatch, + .enter = door_enter, + .leave = door_exit, + .event = &door_event, + .queue = &door_task_queue, + .timeout_ms = door_timeouts, + .period_ms = 0u, + .event_size = (uint16_t)sizeof(emb_task_event_t), + .initial = (emb_state_t)DOOR_STATE_CLOSED, + .count = 3u, + .model = EMB_TASK_EVENT, +}; +emb_task_t door_task = {.desc = &door_desc, .state = (emb_state_t)DOOR_STATE_CLOSED}; + +static void door_main(void *arg) +{ + (void)arg; + emb_task_run(&door_task); +} + +EMB_THREAD_DEFINE(door_thread, door_main, NULL, DOOR_PRIORITY, DOOR_STACK_SIZE, 0u); + +/* ---- blink: a periodic task, every 500 ms (SPEC-020) ---- */ + +_Static_assert(BLINK_STATE_DARK == 0, "blink.h: BLINK_STATES are system.yaml's states, in order"); +_Static_assert(BLINK_STATE_LIT == 1, "blink.h: BLINK_STATES are system.yaml's states, in order"); + +static emb_state_t blink_dispatch(emb_state_t state, uint8_t why) +{ + (void)state; + (void)why; + BLINK_Tasks(); + return (emb_state_t)blinkData.state; +} + +static const emb_task_desc_t blink_desc = { + .name = "blink", + .dispatch = blink_dispatch, + .enter = NULL, + .leave = NULL, + .event = NULL, + .queue = NULL, + .timeout_ms = NULL, + .period_ms = BLINK_PERIOD_MS, + .event_size = 0u, + .initial = (emb_state_t)BLINK_STATE_DARK, + .count = 2u, + .model = EMB_TASK_PERIODIC, +}; +emb_task_t blink_task = {.desc = &blink_desc, .state = (emb_state_t)BLINK_STATE_DARK}; + +static void blink_main(void *arg) +{ + (void)arg; + emb_task_run(&blink_task); +} + +EMB_THREAD_DEFINE(blink_thread, blink_main, NULL, BLINK_PRIORITY, BLINK_STACK_SIZE, 0u); + +// ***************************************************************************** +// ***************************************************************************** +// Section: System "Tasks" Routine +// ***************************************************************************** +// ***************************************************************************** + +/******************************************************************************* + Function: + void SYS_Tasks ( void ) + + Remarks: + See prototype in definitions.h. + */ +void SYS_Tasks(void) +{ + /* Start the kernel: the threads and the tasks run from here. It does not return. */ + emb_kernel_start(); +} +/******************************************************************************* + End of File +*/ diff --git a/examples/tasks/src/door.c b/examples/tasks/src/door.c new file mode 100644 index 00000000..ba2116f4 --- /dev/null +++ b/examples/tasks/src/door.c @@ -0,0 +1,156 @@ +/* SPDX-License-Identifier: Apache-2.0 */ +/* + * This file is part of EmbLinkRTOS, a deterministic real-time kernel for microcontrollers. + * Licensed under the Apache License, Version 2.0; see the LICENSE file at the repository root. + */ + +/******************************************************************************* + door: an event task, its queue 8 deep + + File Name: + door.c + + Summary: + The door task's handlers. + + Description: + This file holds the door task's data and its handlers, one per state, each + returning the state to be in next (SPEC-020). + + Generated by emb-hwgen from system.yaml, then yours to edit: regeneration + merges its changes with yours (A126, A130). + *******************************************************************************/ + +// ***************************************************************************** +// ***************************************************************************** +// Section: Included Files +// ***************************************************************************** +// ***************************************************************************** + +#include "definitions.h" + +// ***************************************************************************** +// ***************************************************************************** +// Section: Global Data Definitions +// ***************************************************************************** +// ***************************************************************************** + +/* Application Data + + Summary: + Holds the door task's data. + + Description: + This structure holds the task's data. + + Remarks: + DOOR_Initialize() starts it, and the task's handlers use it. +*/ +DOOR_DATA doorData; + +// ***************************************************************************** +// ***************************************************************************** +// Section: Application Callback Functions +// ***************************************************************************** +// ***************************************************************************** + +/* TODO: Add any necessary callback functions. */ + +// ***************************************************************************** +// ***************************************************************************** +// Section: Application Local Functions +// ***************************************************************************** +// ***************************************************************************** + +/* TODO: Add any necessary local functions. */ + +// ***************************************************************************** +// ***************************************************************************** +// Section: Application Initialization and State Machine Functions +// ***************************************************************************** +// ***************************************************************************** + +/******************************************************************************* + Function: + void DOOR_Initialize ( void ) + + Remarks: + See prototype in door.h. + */ +void DOOR_Initialize(void) +{ + /* Place the task in its initial state. */ + doorData.state = DOOR_STATE_CLOSED; + doorData.opened = 0u; +} + +/******************************************************************************* + Function: + DOOR_STATES DOOR_OnClosed ( const emb_task_event_t *event ) + + Remarks: + See prototype in door.h. + */ +DOOR_STATES DOOR_OnClosed(const emb_task_event_t *event) +{ + return (event->id == DOOR_EVENT_OPEN) ? DOOR_STATE_OPEN : DOOR_STATE_CLOSED; +} + +/******************************************************************************* + Function: + DOOR_STATES DOOR_OnOpen ( const emb_task_event_t *event ) + + Remarks: + See prototype in door.h. + */ +DOOR_STATES DOOR_OnOpen(const emb_task_event_t *event) +{ + if (event->id == EMB_EV_TIMEOUT) { /* open for its two seconds: it closes itself */ + emb_board_puts("door: closing by itself\n"); + return DOOR_STATE_CLOSED; + } + if (event->id == DOOR_EVENT_JAM) { + return DOOR_STATE_JAMMED; + } + return (event->id == DOOR_EVENT_CLOSE) ? DOOR_STATE_CLOSED : DOOR_STATE_OPEN; +} + +/******************************************************************************* + Function: + DOOR_STATES DOOR_OnJammed ( const emb_task_event_t *event ) + + Remarks: + See prototype in door.h. + */ +DOOR_STATES DOOR_OnJammed(const emb_task_event_t *event) +{ + return (event->id == DOOR_EVENT_CLOSE) ? DOOR_STATE_CLOSED : DOOR_STATE_JAMMED; +} + +/******************************************************************************* + Function: + void DOOR_EnterOpen ( void ) + + Remarks: + See prototype in door.h. + */ +void DOOR_EnterOpen(void) +{ + doorData.opened++; + emb_board_puts("door: open\n"); +} + +/******************************************************************************* + Function: + void DOOR_ExitOpen ( void ) + + Remarks: + See prototype in door.h. + */ +void DOOR_ExitOpen(void) +{ + emb_board_puts("door: closed\n"); +} +/******************************************************************************* + End of File +*/ diff --git a/examples/tasks/src/door.h b/examples/tasks/src/door.h new file mode 100644 index 00000000..74ae1646 --- /dev/null +++ b/examples/tasks/src/door.h @@ -0,0 +1,306 @@ +/* SPDX-License-Identifier: Apache-2.0 */ +/* + * This file is part of EmbLinkRTOS, a deterministic real-time kernel for microcontrollers. + * Licensed under the Apache License, Version 2.0; see the LICENSE file at the repository root. + */ + +/******************************************************************************* + door: an event task, its queue 8 deep + + File Name: + door.h + + Summary: + The door task's states, events, data and functions. + + Description: + This header declares what the door task's own file defines: its states, its + events, its data, DOOR_Initialize() and a handler for each state, which the + task's thread runs for each event (SPEC-020). + + Generated by emb-hwgen from system.yaml, then yours to edit: regeneration + merges its changes with yours (A126, A130). + *******************************************************************************/ + +#ifndef DOOR_H +#define DOOR_H + +// ***************************************************************************** +// ***************************************************************************** +// Section: Included Files +// ***************************************************************************** +// ***************************************************************************** + +#include "configuration.h" + +#include + +#include +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +// ***************************************************************************** +// ***************************************************************************** +// Section: Type Definitions +// ***************************************************************************** +// ***************************************************************************** + +/* Application states + + Summary: + The door task's states. + + Description: + The states system.yaml declares for the task, in its order: they are the + task runtime's numbers, which tasks.c checks. Declare a state in + system.yaml, and regeneration adds it here, with its handler. +*/ +typedef enum { + /* The task's initial state. */ + DOOR_STATE_CLOSED = 0, + DOOR_STATE_OPEN, + DOOR_STATE_JAMMED, +} DOOR_STATES; + +/* Application events + + Summary: + The door task's own events. + + Description: + Numbered from EMB_EV_USER, as system.yaml lists them; the runtime's own, + such as EMB_EV_TIMEOUT, are below it. Post one with emb_task_post(DOOR_TASK, + DOOR_EVENT_, value). +*/ +typedef enum { + DOOR_EVENT_OPEN = EMB_EV_USER, + DOOR_EVENT_CLOSE, + DOOR_EVENT_JAM, +} DOOR_EVENTS; + +/* Application Data + + Summary: + Holds the door task's data. + + Description: + This structure holds the task's data: only the task's thread runs its + handlers. + + Remarks: + state is the state whose handler runs; the runtime keeps it + (emb_task_state(DOOR_TASK)). +*/ +typedef struct { + /* The task's current state */ + DOOR_STATES state; + + /* The times the door opened */ + uint32_t opened; +} DOOR_DATA; + +extern DOOR_DATA doorData; + +// ***************************************************************************** +// ***************************************************************************** +// Section: Application Initialization and State Machine Functions +// ***************************************************************************** +// ***************************************************************************** + +/******************************************************************************* + Function: + void DOOR_Initialize ( void ) + + Summary: + The door task's initialization. + + Description: + This function puts the task in its initial state, DOOR_STATE_CLOSED, and + prepares its data, before the kernel starts its thread. + + Precondition: + The board and the kernel are initialized. The KERNEL devices are not ready + yet: use them from the task's states. + + Parameters: + None. + + Returns: + None. + + Example: + + DOOR_Initialize(); + + + Remarks: + SYS_Initialize() calls it. +*/ +void DOOR_Initialize(void); + +/******************************************************************************* + Function: + DOOR_STATES DOOR_OnClosed ( const emb_task_event_t *event ) + + Summary: + The door task's closed state: one event. + + Description: + This function runs for each event the task receives in DOOR_STATE_CLOSED. It + returns the state to be in next: DOOR_STATE_CLOSED to stay. + + Precondition: + DOOR_Initialize() has run; the kernel runs the task's thread. + + Parameters: + event - The event: its id and its value. + + Returns: + The next state. + + Example: + + return (event->id == DOOR_EVENT_OPEN) ? DOOR_STATE_OPEN : DOOR_STATE_CLOSED; + + + Remarks: + The task's thread calls it, one event at a time; no event is lost meanwhile + (KRN-TSK-001). +*/ +DOOR_STATES DOOR_OnClosed(const emb_task_event_t *event); + +/******************************************************************************* + Function: + DOOR_STATES DOOR_OnOpen ( const emb_task_event_t *event ) + + Summary: + The door task's open state: one event. + + Description: + This function runs for each event the task receives in DOOR_STATE_OPEN, and + with EMB_EV_TIMEOUT when the state's timeout passes. It returns the state to + be in next: DOOR_STATE_OPEN to stay. + + Precondition: + DOOR_Initialize() has run; the kernel runs the task's thread. + + Parameters: + event - The event: its id and its value. + + Returns: + The next state. + + Example: + + return (event->id == DOOR_EVENT_OPEN) ? DOOR_STATE_JAMMED : DOOR_STATE_OPEN; + + + Remarks: + The task's thread calls it, one event at a time; no event is lost meanwhile + (KRN-TSK-001). +*/ +DOOR_STATES DOOR_OnOpen(const emb_task_event_t *event); + +/******************************************************************************* + Function: + DOOR_STATES DOOR_OnJammed ( const emb_task_event_t *event ) + + Summary: + The door task's jammed state: one event. + + Description: + This function runs for each event the task receives in DOOR_STATE_JAMMED. It + returns the state to be in next: DOOR_STATE_JAMMED to stay. + + Precondition: + DOOR_Initialize() has run; the kernel runs the task's thread. + + Parameters: + event - The event: its id and its value. + + Returns: + The next state. + + Example: + + return (event->id == DOOR_EVENT_OPEN) ? DOOR_STATE_CLOSED : DOOR_STATE_JAMMED; + + + Remarks: + The task's thread calls it, one event at a time; no event is lost meanwhile + (KRN-TSK-001). +*/ +DOOR_STATES DOOR_OnJammed(const emb_task_event_t *event); + +/******************************************************************************* + Function: + void DOOR_EnterOpen ( void ) + + Summary: + The door task's open state: its entry action. + + Description: + This function runs as the task enters DOOR_STATE_OPEN, after the old state's + exit action. + + Precondition: + DOOR_Initialize() has run. + + Parameters: + None. + + Returns: + None. + + Example: + + DOOR_EnterOpen(); + + + Remarks: + The task's thread calls it (KRN-TSK-002). +*/ +void DOOR_EnterOpen(void); + +/******************************************************************************* + Function: + void DOOR_ExitOpen ( void ) + + Summary: + The door task's open state: its exit action. + + Description: + This function runs as the task leaves DOOR_STATE_OPEN, before the new + state's entry action. + + Precondition: + DOOR_Initialize() has run. + + Parameters: + None. + + Returns: + None. + + Example: + + DOOR_ExitOpen(); + + + Remarks: + The task's thread calls it (KRN-TSK-002). +*/ +void DOOR_ExitOpen(void); + +#ifdef __cplusplus +} +#endif + +#endif /* DOOR_H */ +/******************************************************************************* + End of File +*/ diff --git a/examples/tasks/src/interrupt_handlers.c b/examples/tasks/src/interrupt_handlers.c new file mode 100644 index 00000000..91cbe0f7 --- /dev/null +++ b/examples/tasks/src/interrupt_handlers.c @@ -0,0 +1,56 @@ +/* SPDX-License-Identifier: Apache-2.0 */ +/* + * This file is part of EmbLinkRTOS, a deterministic real-time kernel for microcontrollers. + * Licensed under the Apache License, Version 2.0; see the LICENSE file at the repository root. + */ + +/******************************************************************************* + Interrupt Handlers + + File Name: + interrupt_handlers.c + + Summary: + tasks_demo's interrupt handlers. + + Description: + This file holds the application's interrupt handlers, which + SYS_INT_Initialize() connects (src/config//interrupts.c). Each runs + in interrupt context: keep it short, and hand the work to a task with + emb_task_post(). + + Generated by emb-hwgen from system.yaml, then yours to edit: regeneration + merges its changes with yours (A126, A130). + *******************************************************************************/ + +// ***************************************************************************** +// ***************************************************************************** +// Section: Included Files +// ***************************************************************************** +// ***************************************************************************** + +#include "definitions.h" + +// ***************************************************************************** +// ***************************************************************************** +// Section: Handler Routines +// ***************************************************************************** +// ***************************************************************************** + +/******************************************************************************* + Function: + void WAKE_InterruptHandler ( void *arg ) + + Remarks: + See prototype in interrupts.h. + */ +void WAKE_InterruptHandler(void *arg) +{ + static uint32_t wakes; /* this handler's own */ + (void)arg; + wakes++; + (void)emb_task_post(DOOR_TASK, DOOR_EVENT_OPEN, wakes); /* from an interrupt: no wait */ +} +/******************************************************************************* + End of File +*/ diff --git a/examples/tasks/src/main.c b/examples/tasks/src/main.c index 0743c6a0..3357eef8 100644 --- a/examples/tasks/src/main.c +++ b/examples/tasks/src/main.c @@ -4,22 +4,55 @@ * Licensed under the Apache License, Version 2.0; see the LICENSE file at the repository root. */ -/** - * @file main.c - * @brief tasks_demo: the board, the kernel, then the threads and tasks of system.yaml. - * - * @details - * Generated by emb-hwgen from system.yaml; yours to edit: regeneration merges its changes (A126). - */ -#include +/******************************************************************************* + Main Source File + + File Name: + main.c + + Summary: + tasks_demo's entry point. + + Description: + This file holds main(): it initializes the system, the board, the kernel and + the tasks (SYS_Initialize()), then starts the kernel (SYS_Tasks()), from + which the threads and the tasks run. + + Generated by emb-hwgen from system.yaml, then yours to edit: regeneration + merges its changes with yours (A126, A130). + *******************************************************************************/ -#include +// ***************************************************************************** +// ***************************************************************************** +// Section: Included Files +// ***************************************************************************** +// ***************************************************************************** -#include "system.h" +#include "definitions.h" + +#include +#include +#include + +// ***************************************************************************** +// ***************************************************************************** +// Section: Main Entry Point +// ***************************************************************************** +// ***************************************************************************** int main(void) { - emb_board_init(); - emb_kernel_init(); - emb_kernel_start(); /* the threads and tasks run from here: it does not return */ + /* Initialize all modules */ + SYS_Initialize(NULL); + + while (true) { + /* Start the kernel: the threads and the tasks run from here. It does not return. */ + SYS_Tasks(); + } + + /* Execution should not come here during normal operation */ + return EXIT_FAILURE; } +/******************************************************************************* + End of File +*/ diff --git a/examples/tasks/src/tasks/blink.c b/examples/tasks/src/tasks/blink.c deleted file mode 100644 index a2a0c38d..00000000 --- a/examples/tasks/src/tasks/blink.c +++ /dev/null @@ -1,36 +0,0 @@ -/* SPDX-License-Identifier: Apache-2.0 */ -/* - * This file is part of EmbLinkRTOS, a deterministic real-time kernel for microcontrollers. - * Licensed under the Apache License, Version 2.0; see the LICENSE file at the repository root. - */ - -/** - * @file blink.c - * @brief The blink task's handlers (SPEC-020): each state's returns the state to be in next. - * - * @details - * Generated by emb-hwgen from system.yaml; yours to edit: regeneration merges its changes (A126). - */ -#include "tasks.h" - -#include - -static uint32_t blinks; /* this task's own: only its thread touches it */ - -emb_state_t blink_on_dark(blink_t *self) -{ - (void)self; - emb_board_led_toggle(); - return BLINK_LIT; -} - -emb_state_t blink_on_lit(blink_t *self) -{ - (void)self; - emb_board_led_toggle(); - blinks++; - if ((blinks % 4u) == 0u) { /* every fourth blink, two seconds: the door opens */ - (void)emb_task_post(DOOR_TASK, DOOR_EV_OPEN, blinks); - } - return BLINK_DARK; -} diff --git a/examples/tasks/src/tasks/door.c b/examples/tasks/src/tasks/door.c deleted file mode 100644 index 3969543d..00000000 --- a/examples/tasks/src/tasks/door.c +++ /dev/null @@ -1,53 +0,0 @@ -/* SPDX-License-Identifier: Apache-2.0 */ -/* - * This file is part of EmbLinkRTOS, a deterministic real-time kernel for microcontrollers. - * Licensed under the Apache License, Version 2.0; see the LICENSE file at the repository root. - */ - -/** - * @file door.c - * @brief The door task's handlers (SPEC-020): each state's returns the state to be in next. - * - * @details - * Generated by emb-hwgen from system.yaml; yours to edit: regeneration merges its changes (A126). - */ -#include "tasks.h" - -#include - -emb_state_t door_on_closed(door_t *self, const emb_task_event_t *ev) -{ - (void)self; - return (ev->id == DOOR_EV_OPEN) ? DOOR_OPEN : DOOR_CLOSED; -} - -emb_state_t door_on_open(door_t *self, const emb_task_event_t *ev) -{ - (void)self; - if (ev->id == EMB_EV_TIMEOUT) { /* open for its two seconds: it closes itself */ - emb_board_puts("door: closing by itself\n"); - return DOOR_CLOSED; - } - if (ev->id == DOOR_EV_JAM) { - return DOOR_JAMMED; - } - return (ev->id == DOOR_EV_CLOSE) ? DOOR_CLOSED : DOOR_OPEN; -} - -emb_state_t door_on_jammed(door_t *self, const emb_task_event_t *ev) -{ - (void)self; - return (ev->id == DOOR_EV_CLOSE) ? DOOR_CLOSED : DOOR_JAMMED; -} - -void door_enter_open(door_t *self) -{ - self->data.count++; - emb_board_puts("door: open\n"); -} - -void door_exit_open(door_t *self) -{ - (void)self; - emb_board_puts("door: closed\n"); -} diff --git a/examples/tasks/src/tasks/door.h b/examples/tasks/src/tasks/door.h deleted file mode 100644 index 6828e6ec..00000000 --- a/examples/tasks/src/tasks/door.h +++ /dev/null @@ -1,23 +0,0 @@ -/* SPDX-License-Identifier: Apache-2.0 */ -/* - * This file is part of EmbLinkRTOS, a deterministic real-time kernel for microcontrollers. - * Licensed under the Apache License, Version 2.0; see the LICENSE file at the repository root. - */ - -/** - * @file door.h - * @brief The door task's own types: its data. - * - * @details - * Generated by emb-hwgen from system.yaml; yours to edit: regeneration merges its changes (A126). - */ -#ifndef TASK_DOOR_H -#define TASK_DOOR_H - -#include - -typedef struct door_data { - uint32_t count; /* the task's own state: change it */ -} door_data_t; - -#endif /* TASK_DOOR_H */ diff --git a/examples/tasks/system.yaml b/examples/tasks/system.yaml index 53d6b117..d1c53123 100644 --- a/examples/tasks/system.yaml +++ b/examples/tasks/system.yaml @@ -4,9 +4,10 @@ # This file is part of EmbLinkRTOS, a deterministic real-time kernel for microcontrollers. # Licensed under the Apache License, Version 2.0; see the LICENSE file at the repository root. -# Tasks (SPEC-020): a door, driven by events with a state's timeout, and a blinker, by its -# period. hw/gen/emb-hwgen.py generate --system examples/tasks/system.yaml writes the -# application's CMakeLists.txt, src/main.c and src/tasks/, then generated//. +# Tasks (SPEC-020) in MPLAB Harmony's form (A130): a door, driven by events with a state's +# timeout, and a blinker, by its period. hw/gen/emb-hwgen.py generate --system +# examples/tasks/system.yaml writes the application's CMakeLists.txt, src/main.c and each task's +# src/.c and .h, then each board's configuration folder, src/config//. schema_version: 0 kind: system name: tasks_demo @@ -23,7 +24,6 @@ tasks: entry: [open] exit: [open] timeout: { open: 2s } - data: door_data_t - name: blink model: periodic period: 500ms @@ -31,3 +31,11 @@ tasks: stack: 512 states: [dark, lit] initial: dark +# the application's own interrupt (A130): a line no peripheral raises on either SoC (the F446's +# 61, the RP2350's SPAREIRQ_IRQ_0); the blinker raises it every fourth blink, and its handler +# opens the door +interrupts: + - name: wake + irq: { nucleo_f446re: 61, pico2_w: 46 } + handler: WAKE_InterruptHandler + level: 1 diff --git a/hw/gen/emb-hwgen.py b/hw/gen/emb-hwgen.py index 2485374a..4f4d0668 100644 --- a/hw/gen/emb-hwgen.py +++ b/hw/gen/emb-hwgen.py @@ -58,10 +58,15 @@ def _board_placements(board, files, out=None): return [(gen / name, text, gen / ".base" / name) for name, text in sorted(files.items())] +def _system_config(system): + """An application's configuration folder, Harmony's src/config/ (A130).""" + return system.parent / "src" / "config" + + def _system_placements(system, per_board, out=None): - """[(path, text, baseline path)] for a system's outputs: generated// for each board, the - baseline under generated/.base// (A126).""" - gen = Path(out) if out else system.parent / "generated" + """[(path, text, baseline path)] for a system's outputs: src/config// for each board, the + baseline under src/config/.base// (A126, A130).""" + gen = Path(out) if out else _system_config(system) out_list = [] for board, files in sorted(per_board.items()): for name, text in sorted(files.items()): @@ -77,6 +82,11 @@ def _target(args): if args.system: system = Path(args.system) per_board, warnings = generate.generate_system(system, ROOT) + # A126's folders, which A130 replaced: the application's edits there are its author's to move + for old, now in (("generated", "src/config//"), ("src/tasks", "src/.c and .h")): + if (system.parent / old).is_dir(): + warnings.append(f"{os.path.relpath(system.parent / old, ROOT)}/: A130 moved these files to {now}; " + "move your edits there, then remove it") return _system_placements(system, per_board, getattr(args, "out", None)), warnings, system board = Path(args.board) files, warnings = generate.generate(board, ROOT) @@ -133,7 +143,7 @@ def cmd_check(args): f"--board {os.path.relpath(b, ROOT)}", args.strict)) for s in systems: per_board, _ = generate.generate_system(s, ROOT) - jobs.append((s.parent / "generated", _system_placements(s, per_board), f"--system {os.path.relpath(s, ROOT)}", False)) + jobs.append((_system_config(s), _system_placements(s, per_board), f"--system {os.path.relpath(s, ROOT)}", False)) for gen, placements, how, strict in jobs: expected = {path for path, _, _ in placements} for path, text, base in placements: diff --git a/hw/gen/emb_hwgen/clock.py b/hw/gen/emb_hwgen/clock.py index 6b892470..cedc3480 100644 --- a/hw/gen/emb_hwgen/clock.py +++ b/hw/gen/emb_hwgen/clock.py @@ -64,7 +64,8 @@ def solve(soc, board, fail): out["bypass"] = False out["source_hz"] = in_hz - pll_spec = (clocks.get("plls") or [None])[0] + plls = clocks.get("plls") or [] + pll_spec = next((s for s in plls if "output_hz" not in s), None) # the CPU's given = board["clocks"].get("pll") if want == in_hz and given is None: out["pll"] = None @@ -84,6 +85,24 @@ def solve(soc, board, fail): out["pll"] = pll sysclk = want + # the PLLs with an output of their own (A129): each solved for its rate from the clock source, + # started by the first driver that needs it + out["fixed_plls"] = {} + for spec in plls: + if "output_hz" not in spec: + continue + rate = spec["output_hz"] + if src_name not in spec["inputs"]: + fail("clocks.source", f"{src_name} cannot feed {spec['name']}, which makes {_mhz(rate)} (inputs: " + f"{', '.join(spec['inputs'])})") + return None + rec = _search(spec, in_hz, rate) + if rec is None: + fail("clocks.source", f"no {spec['name']} setting reaches exactly {_mhz(rate)} from {_mhz(in_hz)}") + return None + rec["hz"] = rate + out["fixed_plls"][spec["name"]] = rec + buses = {b["name"]: b for b in clocks.get("buses", [])} ahb_max = min((b["max_hz"] for b in buses.values() if b["from"] == "hclk"), default=None) if ahb_max is not None and sysclk > ahb_max: @@ -104,6 +123,10 @@ def solve(soc, board, fail): out[f"{which}_div"] = div rates[which] = hclk // div out["bus_hz"] = {name: rates[b["from"]] for name, b in sorted(buses.items())} + # the timers' kernel clock on each bus: twice a divided APB clock on the STM32F4 (A129) + double = bool(clocks.get("timers_double_when_divided")) + out["bus_timer_hz"] = {name: rates[b["from"]] * (2 if double and out.get(f"{b['from']}_div", 1) > 1 else 1) + for name, b in sorted(buses.items())} out["hclk_hz"] = hclk for which in ("pclk1", "pclk2"): if which in rates: diff --git a/hw/gen/emb_hwgen/devices.py b/hw/gen/emb_hwgen/devices.py index b6a1ca2a..e6a88c89 100644 --- a/hw/gen/emb_hwgen/devices.py +++ b/hw/gen/emb_hwgen/devices.py @@ -18,18 +18,20 @@ LEVELS = ("early", "kernel") # EMB_DRV_CLASS_* in , numbered from 1 in this order (0 is no class) -CLASSES = ("uart", "spi", "i2c", "dma", "watchdog", "flash", "rtc", "entropy", "clock", "gpio") +CLASSES = ("uart", "spi", "i2c", "dma", "watchdog", "flash", "rtc", "entropy", "clock", "gpio", "counter", "pwm", "adc") COMPATIBLE = re.compile(r"^[a-z0-9-]+,[a-z0-9-]+$") # the keys of a board device that are not its properties -DEVICE_KEYS = ("name", "peripheral", "compatible", "bus", "deps", "level", "doc") +DEVICE_KEYS = ("name", "peripheral", "compatible", "class", "bus", "deps", "level", "doc") class Bindings: """drivers/bindings.yaml in the tree, and the board root's own (A84), merged: a - compatible is bound once.""" + compatible is bound once for each class. A peripheral that more than one class can drive + (a timer: a counter or PWM, A129) has a binding per class, keyed `compatible:class`, and a + board device names the one it wants with `class:`.""" def __init__(self, files, err_at): - self.table = {} # compatible -> (binding, model, origin) + self.table = {} # compatible -> {class: (binding, model, origin)} self.models = [] for path, origin in files: m = load.flatten(path, path.parent.parent) @@ -40,21 +42,43 @@ def __init__(self, files, err_at): if not ok: continue self.models.append(m) - for compat, b in m.data["bindings"].items(): - where = f"bindings.{compat}" + for key, b in m.data["bindings"].items(): + where = f"bindings.{key}" + compat, _, cls = key.partition(":") if not COMPATIBLE.match(compat): err_at(m, where, f"{compat!r} is not a compatible: vendor,name") - elif compat in self.table: - err_at(m, where, f"{compat} is already bound in {self.table[compat][1].leaf.name}") + elif cls and cls != b["class"]: + err_at(m, where, f"the key names the class {cls}, the binding {b['class']}") + elif b["class"] in self.table.get(compat, {}): + err_at(m, where, f"{compat} is already bound for the {b['class']} class in " + f"{self.table[compat][b['class']][1].leaf.name}") else: - self.table[compat] = (b, m, origin) + self.table.setdefault(compat, {})[b["class"]] = (b, m, origin) + + def lookup(self, compat, cls=None): + """(binding, model, origin) for a compatible, or the reason there is none: a device whose + compatible several classes drive names its class.""" + by_class = self.table.get(compat) + if not by_class: + return None, f"no driver binds {compat} (drivers/bindings.yaml)" + if cls is not None: + if cls not in by_class: + return None, f"no {cls} driver binds {compat}: it has {', '.join(sorted(by_class))}" + return by_class[cls], None + if len(by_class) > 1: + return None, f"{compat} has drivers for {' and '.join(sorted(by_class))}: say which with class:" + return next(iter(by_class.values())), None def _peripheral_view(p, soc, clk): """What a binding's `peripheral.*` fields read: the SoC node, its interrupts by name, its - clock gate with the bus's enable register, and the frequency it is clocked at.""" + clock gate with the bus's enable register, and the frequency it is clocked at: its bus's, a + timer's on its bus (timer_clock_hz), or the PLL's it names in clocked_by.""" view = {k: v for k, v in p.items() if k not in ("irqs", "clock", "doc", "curated")} view["irqs"] = {i["name"]: i["number"] for i in p.get("irqs", [])} + index = re.search(r"(\d+)$", p["name"]) + if index: # its number among its kind: timer1's 1, a PWM slice's (A129) + view["index"] = int(index.group(1)) gate = p.get("clock") if gate is not None: bus = next((b for b in soc.get("clocks", {}).get("buses", []) if b["name"] == gate["bus"]), {}) @@ -63,6 +87,11 @@ def _peripheral_view(p, soc, clk): view["clock"]["enable_offset"] = bus["enable_offset"] if clk is not None: view["clock_hz"] = clk["bus_hz"].get(gate["bus"], clk["hclk_hz"]) if gate else clk["hclk_hz"] + timer = clk.get("bus_timer_hz", {}) + view["timer_clock_hz"] = timer.get(gate["bus"], view["clock_hz"]) if gate else view["clock_hz"] + fixed = clk.get("fixed_plls", {}).get(p.get("clocked_by")) + if fixed is not None: # a kernel clock of its own, a PLL's fixed output (A129) + view["clock_hz"] = view["timer_clock_hz"] = fixed["hz"] return view @@ -237,13 +266,29 @@ def resolve(board, soc, clk, bindings, err, pins=None): continue used[pname] = e["name"] compat = p["compatible"] - bound = bindings.table.get(compat) + bound, why = bindings.lookup(compat, e.get("class")) if bound is None: - err(at, f"no driver binds {compat} (drivers/bindings.yaml)") + err(at, why) continue b, _, origin = bound + takes = {} + for key, want in sorted(b.get("takes", {}).items()): # its other peripherals (A129) + tname = e.get(key) + if not isinstance(tname, str): + err(at, f"the {compat} binding takes a {want} peripheral as {key}: name one ({key}: )") + continue + tp = periph.get(tname) + if tp is None: + err(f"{at}.{key}", f"unresolved reference: the SoC has no peripheral {tname!r}") + elif tp["compatible"] != want: + err(f"{at}.{key}", f"{tname} is a {tp['compatible']}, not the {want} the {compat} binding takes") + elif tname in used: + err(f"{at}.{key}", f"{tname} is already the device {used[tname]}") + else: + used[tname] = f"{e['name']} (its {key})" + takes[key] = tp devs[e["name"]] = {"index": i, "entry": e, "peripheral": p, "compatible": compat, "binding": b, - "origin": origin, "level": e.get("level", b["level"])} + "origin": origin, "level": e.get("level", b["level"]), "takes": takes} _dma_assign(devs, sorted(devs, key=lambda n: devs[n]["index"]), err) clock_devs = [n for n in names if n in devs and devs[n]["binding"]["class"] == "clock"] @@ -253,8 +298,9 @@ def resolve(board, soc, clk, bindings, err, pins=None): if "bus" in e: deps.append(e["bus"]) deps += sorted({c["dma"] for c in d["dma"].values()}) # its DMA controllers first - if d["peripheral"] is not None and d["peripheral"].get("clock") and d["binding"]["class"] != "clock": - deps += clock_devs # the clock tree first: it gates this one (SPEC-016 §4) + gated = [x for x in [d["peripheral"]] + list(d["takes"].values()) if x is not None and x.get("clock")] + if gated and d["binding"]["class"] != "clock": + deps += clock_devs # the clock tree first: it gates this one, or what it takes (SPEC-016 §4) d["deps"] = [] for dep in deps: if dep not in names: @@ -299,11 +345,16 @@ def resolve(board, soc, clk, bindings, err, pins=None): ctx["flash"] = {"geometry": _flash_geometry(n, e, soc.data, err)} if d["peripheral"] is not None: ctx["peripheral"] = _peripheral_view(d["peripheral"], soc.data, clk) + ctx["takes"] = {k: _peripheral_view(tp, soc.data, clk) for k, tp in d["takes"].items()} if "bus" in e: ctx["device"]["bus"] = {"device": e["bus"]} fields = [] - for field, expr in b.get("fields", {}).items(): + for field, spec in b.get("fields", {}).items(): + expr, default = (spec, None) if isinstance(spec, str) else (spec["from"], spec["default"]) v = _lookup(ctx, expr) + defaulted = v is None and default is not None + if defaulted: + v = default # the device does not give it (A129) if v is None and expr.startswith("dma."): v = {"dma": None} # a request the board gives no channel: none if v is None and expr.startswith("pins."): @@ -313,7 +364,8 @@ def resolve(board, soc, clk, bindings, err, pins=None): if v is None or isinstance(v, (list,)) or (isinstance(v, dict) and not ({"device", "line", "dma", "flash_geometry"} & set(v))): err(f"devices.{n}", f"the {d['compatible']} binding's field {field} reads {expr}, which this device does not have") continue - fields.append({"field": field, "expr": expr, "value": v, "c": c_value(v, expr)}) + fields.append({"field": field, "expr": expr, "value": v, "c": c_value(v, expr)} + | ({"default": True} if defaulted else {})) buffers = [] for bname, spec in b.get("buffers", {}).items(): size = _lookup(ctx, spec["size"]) @@ -350,7 +402,8 @@ def resolve(board, soc, clk, bindings, err, pins=None): # what a system description may set (A125): the options the binding reads from the # device, and the limits its driver states for targets and timeouts "options": sorted({x[len("device."):].split(".")[0] for x in - list(b.get("fields", {}).values()) + [v["size"] for v in b.get("buffers", {}).values()] + [s if isinstance(s, str) else s["from"] for s in b.get("fields", {}).values()] + + [v["size"] for v in b.get("buffers", {}).values()] if x.startswith("device.") and x != "device.bus"}), "limits": b.get("limits", {}), }) diff --git a/hw/gen/emb_hwgen/diagnostics.py b/hw/gen/emb_hwgen/diagnostics.py index e943bdec..3c6f81a2 100644 --- a/hw/gen/emb_hwgen/diagnostics.py +++ b/hw/gen/emb_hwgen/diagnostics.py @@ -20,9 +20,9 @@ FORMAT = 1 # the document's own version: a field added keeps it, one changed or removed bumps it # a Windows drive is part of the file name; a node path has no spaces, and its segments may be -# compatibles (bindings.st,stm32f4-iwdg.class) +# compatibles (bindings.st,stm32f4-iwdg.class), with a class (bindings.st,stm32-tim:pwm, A129) _LINE = re.compile(r"^(?P(?:[A-Za-z]:)?[^:\n]+?)(?::(?P\d+))?: " - r"(?:(?P\(root\)|\(file\)|[A-Za-z_][\w,+-]*(?:\.[\w,+-]+|\[\d+\])*): )?" + r"(?:(?P\(root\)|\(file\)|[A-Za-z_][\w,+-]*(?:\.[\w,+:-]+|\[\d+\])*): )?" r"(?P.+)$", re.S) _FACT = re.compile(r"^(?P(?:[A-Za-z]:)?[^:\n]+?)(?::(?P\d+))?: (?P.+)$", re.S) diff --git a/hw/gen/emb_hwgen/emit.py b/hw/gen/emb_hwgen/emit.py index 1d485d44..55151d13 100644 --- a/hw/gen/emb_hwgen/emit.py +++ b/hw/gen/emb_hwgen/emit.py @@ -32,8 +32,10 @@ def _hex(v): def _stamp_lines(r, cmd): - lines = [f"Generated by emb-hwgen {VERSION}, schema v{SCHEMA_VERSION}. Do not edit: change the", - f"description and run {cmd} (HW-003).", + run = f"description and run {cmd} (HW-003)." + # a long command (an application's) on a line of its own, within the 100 columns + runs = [run] if len(run) <= 96 else ["description and run", f" {cmd}", "(HW-003)."] + lines = [f"Generated by emb-hwgen {VERSION}, schema v{SCHEMA_VERSION}. Do not edit: change the", *runs, "Inputs (SHA-256):"] for i in r["inputs"]: lines += [f" {i['path']}", f" {i['sha256']}"] @@ -103,6 +105,11 @@ def hw_config_h(r): if f in pll: clocks[f"EMB_HW_PLL_{f.upper()}"] = f"{pll[f]}u" clocks["EMB_HW_PLL_VCO_HZ"] = f"{int(pll['vco_hz'])}u" + for name, pll in sorted(clk.get("fixed_plls", {}).items()): # A129: a PLL of a fixed rate + for f in ("m", "n", "postdiv1", "postdiv2"): + if f in pll: + clocks[f"EMB_HW_{_sym(name)}_{f.upper()}"] = f"{pll[f]}u" + clocks[f"EMB_HW_{_sym(name)}_HZ"] = f"{pll['hz']}u" buses = soc.get("clocks", {}).get("buses", []) if buses: clocks["EMB_HW_AHB_DIV"] = f"{clk['ahb_div']}u" @@ -197,7 +204,7 @@ def hw_config_h(r): # --------------------------------------------------------------------------- board_pins.c def board_pins_c(r): - mode = {"af": "EMB_STM32_PIN_AF", "output": "EMB_STM32_PIN_OUTPUT"} + mode = {"af": "EMB_STM32_PIN_AF", "output": "EMB_STM32_PIN_OUTPUT", "analog": "EMB_STM32_PIN_ANALOG"} out = "/* SPDX-License-Identifier: Apache-2.0 */\n" out += _c_comment(r, _cmd(r)) out += ("/* The pins board initialization configures, by port and number. Inputs left at their\n" @@ -459,12 +466,14 @@ def board_cmake(r): out += f"set(EMB_BOARD_DEFAULT_PROFILE {r['profile']})\n" if soc["cpu"].get("cflags"): out += f"set(EMB_BOARD_C_FLAGS {' '.join(soc['cpu']['cflags'])})\n" - # the generated directory's layout (A126): this file is in build/, beside config/, include/, - # src/, linker/ and docs/ + # the generated directory's layout (A126; an application's, A130): this file is in build/ + lay = _layout(r) out += "get_filename_component(EMB_BOARD_GENERATED_DIR \"${CMAKE_CURRENT_LIST_DIR}/..\" ABSOLUTE)\n" - out += "set(EMB_BOARD_CONF \"${EMB_BOARD_GENERATED_DIR}/config/board.conf\")\n" - out += "set(EMB_BOARD_HW_JSON \"${EMB_BOARD_GENERATED_DIR}/docs/hw.json\")\n" + out += f"set(EMB_BOARD_CONF \"{_gen_path(r, 'board.conf')}\")\n" + out += f"set(EMB_BOARD_HW_JSON \"{_gen_path(r, 'hw.json')}\")\n" out += "set(EMB_BOARD_BUILD_DIR \"${CMAKE_CURRENT_LIST_DIR}\") # build/CMakeLists.txt\n" + out += f"set(EMB_BOARD_SRC_DIR \"${{EMB_BOARD_GENERATED_DIR}}/{lay['board_pins.c']}\") # its pin table and boot block\n" + out += f"set(EMB_BOARD_LINKER_DIR \"${{EMB_BOARD_GENERATED_DIR}}/{lay['regions.ld']}\")\n" out += "# the SoC family's board support and drivers build this board (build/CMakeLists.txt)\n" if r.get("soc_in_board_root"): # the project's own SoC family, beside its boards (A84): the generated directory is @@ -472,7 +481,7 @@ def board_cmake(r): out += f"get_filename_component(EMB_SOC_DIR \"${{EMB_BOARD_GENERATED_DIR}}/../../../../{soc_dir}\" ABSOLUTE)\n" else: out += f"set(EMB_SOC_DIR \"${{EMB_BASE}}/{soc_dir}\")\n" - out += "set(EMB_BOARD_INCLUDE_DIRS \"${EMB_BOARD_GENERATED_DIR}/include\" \"${EMB_SOC_DIR}/include\")\n" + out += f"set(EMB_BOARD_INCLUDE_DIRS \"${{EMB_BOARD_GENERATED_DIR}}/{lay['hw_config.h']}\" \"${{EMB_SOC_DIR}}/include\")\n" qemu = r["board"].get("simulation", {}).get("qemu") if qemu: out += f"set(EMB_BOARD_QEMU_ARGS {' '.join(qemu)})\n" @@ -489,8 +498,17 @@ def board_cmake(r): if d.get("cs"): # its chip selects, EMB_SOC__CS in soc_devices.h out += f"set(EMB_BOARD_{d['name'].upper()}_CS_COUNT {len(d['cs'])})\n" for loop in r["board"].get("simulation", {}).get("loopbacks", []): - cls = classes[loop["device"]].upper() # checked by the resolver: a UART, SPI or I2C device - if "nets" in loop: + cls = classes[loop["device"]].upper() # checked by the resolver: its class's shape + if cls == "PWM": + # an output wired to a capture input: their channels, and the two ports (A129) + ch = loop["channels"] + out += (f"set(EMB_BOARD_EMBSIM_PWM_LOOP \"{loop['device']}:{ch[0]},{loop['peer']}:{ch[1]}\" " + f"\"{','.join(loop['ports'])}\")\n") + elif cls == "ADC": + # an input wired high and one low: their numbers, and each one's net to a rail (A129) + nets = " ".join(f'"{a},{b}"' for a, b in loop["nets"]) + out += f"set(EMB_BOARD_EMBSIM_ADC_LOOP \"{loop['device']}:{loop['channels'][0]},{loop['channels'][1]}\" {nets})\n" + elif "nets" in loop: # two I2C controllers joined line to line, for the class's loop test nets = " ".join(f'"{a},{b}"' for a, b in loop["nets"]) out += f"set(EMB_BOARD_EMBSIM_{cls}_LOOP {loop['device']} {loop['peer']} {nets})\n" @@ -534,7 +552,7 @@ def _device_sources(r): if path not in includes: includes.append(path) out = "# the board's devices (soc_devices.c) and the drivers they use, and only those (SPEC-016 §8)\n" - out += "set(EMB_BOARD_DRIVER_SOURCES\n \"${EMB_BOARD_GENERATED_DIR}/src/soc_devices.c\"\n" + out += f"set(EMB_BOARD_DRIVER_SOURCES\n \"{_gen_path(r, 'soc_devices.c')}\"\n" out += "".join(f" \"{s}\"\n" for s in sources) + ")\n" if includes: out += "set(EMB_BOARD_DRIVER_INCLUDE_DIRS\n" + "".join(f" \"{i}\"\n" for i in includes) + ")\n" @@ -544,7 +562,8 @@ def _device_sources(r): def cmakelists_txt(r): out = "# SPDX-License-Identifier: Apache-2.0\n" + _hash_comment(r, _cmd(r)) out += "# The board has no C of its own: its SoC family's board support builds emb_board from\n" - out += "# ../src/board_pins.c and ../include/hw_config.h, and links ../linker/regions.ld.\n" + out += (f"# ../{placed('board_pins.c', _layout(r))} and ../{placed('hw_config.h', _layout(r))}, and links " + f"../{placed('regions.ld', _layout(r))}.\n") out += "add_subdirectory(\"${EMB_SOC_DIR}\" soc)\n" return out @@ -654,6 +673,10 @@ def build_report_md(r): f"{'Given by the board, checked' if 'pll' in r['board']['clocks'] else 'Solved'}.\n\n") else: out += f"{clk['source']} {_mhz(clk['source_hz'])}, used directly.\n\n" + for name, p in sorted(clk.get("fixed_plls", {}).items()): + post = f"/ {p['postdiv1']} / {p['postdiv2']}" if "postdiv1" in p else f"/ P {p['p']}" + out += (f"{name}: {clk['source']} {_mhz(clk['source_hz'])} / M {p['m']} x N {p['n']} = {_mhz(p['vco_hz'])} " + f"VCO, {post} = {_mhz(p['hz'])}. Solved; started by the drivers that use it.\n\n") buses = soc.get("clocks", {}).get("buses", []) if buses: out += "| Bus | Frequency | Limit |\n|---|---|---|\n" @@ -695,17 +718,21 @@ def rp2350_pins_c(r): " * state need no entry. */\n") out += "#include \n#include \n\n" out += "const emb_rp2350_pin_t emb_board_pins[] = {\n" - entries = [e for e in r["pins"] if e["mode"] in ("af", "output")] + entries = [e for e in r["pins"] if e["mode"] in ("af", "output", "analog")] for e in entries: what = e.get("signal", e["mode"]) - funcsel = e["af"] if e["mode"] == "af" else 5 - # a peripheral's pad reads its line too, and a chip select's, so a read shows its level + # an ADC's input takes no function (NULL, 31), as the datasheet asks (A129) + funcsel = e["af"] if e["mode"] == "af" else (31 if e["mode"] == "analog" else 5) + # a peripheral's pad reads its line too, and a chip select's, so a read shows its level; + # an analog input's digital input is off, so it draws nothing is_input = 1 if e["mode"] == "af" or "level" in e else 0 # a UART's receive and an I2C line idle high: pulled up, so a line left open does not - # read as a break, and a bus without resistors still works at 100 kHz - pull = "EMB_RP2350_PULL_UP" if str(what).endswith(("_rx", "_scl", "_sda")) else "EMB_RP2350_PULL_RESET" + # read as a break, and a bus without resistors still works at 100 kHz; an analog input + # is pulled neither way + pull = ("EMB_RP2350_PULL_NONE" if e["mode"] == "analog" + else "EMB_RP2350_PULL_UP" if str(what).endswith(("_rx", "_scl", "_sda")) else "EMB_RP2350_PULL_RESET") out += f" /* {e['pin']}: {e['owner']} ({what}) */\n" - drive = "EMB_RP2350_OUT_NONE" if e["mode"] == "af" else ("EMB_RP2350_OUT_HIGH" if e.get("level") else "EMB_RP2350_OUT_LOW") + drive = "EMB_RP2350_OUT_NONE" if e["mode"] in ("af", "analog") else ("EMB_RP2350_OUT_HIGH" if e.get("level") else "EMB_RP2350_OUT_LOW") out += f" {{{e['number']}u, {funcsel}u, {is_input}u, {pull}, {drive}}},\n" out += "};\n\n" out += "const unsigned emb_board_pin_count = (unsigned)(sizeof(emb_board_pins) / sizeof(emb_board_pins[0]));\n" @@ -770,6 +797,12 @@ def soc_devices_h(r): if rtc is not None: out += "\n/* the board's RTC device: the first of its class */\n" out += f"#define EMB_SOC_RTC_DEVICE (&emb_dev_{rtc['name']})\n" + counters = [d for d in r["devices"] if d["class"] == "counter"] + if counters: + out += "\n/* the board's counters: the first of their class, and all of them (SPEC-017 §11a) */\n" + out += f"#define EMB_SOC_COUNTER_DEVICE (&emb_dev_{counters[0]['name']})\n" + out += "#define EMB_SOC_COUNTER_DEVICES " + ", ".join(f"&emb_dev_{d['name']}" for d in counters) + "\n" + out += f"#define EMB_SOC_COUNTER_COUNT {len(counters)}u\n" ent = next((d for d in r["devices"] if d["class"] == "entropy"), None) if ent is not None: out += "\n/* the board's entropy source: the first of its class (SPEC-017 §11) */\n" @@ -856,7 +889,7 @@ def soc_devices_c(r): width = max(len(f".{f['field']} = {f['c']},") for f in d["fields"]) for f in d["fields"]: init = f".{f['field']} = {f['c']}," - out += f" {init.ljust(width)} /* {f['expr']} */\n" + out += f" {init.ljust(width)} /* {f['expr']}{', its default' if f.get('default') else ''} */\n" out += "};\n" if geometry: out += "/* clang-format on */\n" @@ -932,17 +965,39 @@ def soc_devices_c(r): # build/ and docs/. LAYOUT = { "board.conf": "config", - "hw_config.h": "include", "soc_devices.h": "include", "system.h": "include", "tasks.h": "include", - "soc_devices.c": "src", "board_pins.c": "src", "boot_block.c": "src", "system.c": "src", "tasks.c": "src", + "hw_config.h": "include", "soc_devices.h": "include", + "soc_devices.c": "src", "board_pins.c": "src", "boot_block.c": "src", + "regions.ld": "linker", "embld.opts": "linker", + "board.cmake": "build", "CMakeLists.txt": "build", + "board.md": "docs", "build_report.md": "docs", "hw.json": "docs", +} + +# Where each output goes in an application's configuration folder, src/config//, in +# MPLAB Harmony's form (A130): the system's files at its top, the board's C under peripheral/. +APP_LAYOUT = { + "board.conf": "build", + "hw_config.h": "peripheral", "soc_devices.h": "peripheral", + "soc_devices.c": "peripheral", "board_pins.c": "peripheral", "boot_block.c": "peripheral", "regions.ld": "linker", "embld.opts": "linker", "board.cmake": "build", "CMakeLists.txt": "build", "board.md": "docs", "build_report.md": "docs", "hw.json": "docs", "system.md": "docs", "system.json": "docs", + "definitions.h": "", "configuration.h": "", "initialization.c": "", "tasks.c": "", + "interrupts.h": "", "interrupts.c": "", } -def placed(name): +def _layout(r): + return APP_LAYOUT if "system" in r else LAYOUT + + +def placed(name, layout=LAYOUT): """An output's path in the generated directory.""" - return f"{LAYOUT[name]}/{name}" + return f"{layout[name]}/{name}" if layout[name] else name + + +def _gen_path(r, name): + """An output's path from board.cmake, as CMake reads it.""" + return "${EMB_BOARD_GENERATED_DIR}/" + placed(name, _layout(r)) # The notice every C, assembly and linker source carries (CS-11.1; tools/dev/file_headers.py @@ -996,14 +1051,12 @@ def render(resolved): outputs.update(FAMILY_OUTPUTS.get(resolved["soc"]["family"], {})) outputs.update(PORT_OUTPUTS.get(resolved["soc"]["arch"]["port"], {})) outputs.update(DEVICE_OUTPUTS) # every board defines its device table, empty or not - if "system" in resolved: # an application's outputs: the board's with its settings, and the system's (A125) + if "system" in resolved: # an application's: the board's with its settings, and the system's (A125, A130) from . import emit_system - c = _c_comment(resolved, _cmd(resolved)) - outputs.update({"system.h": lambda r: emit_system.system_h(r, c), - "system.c": lambda r: emit_system.system_c(r, c), - "system.json": emit_system.system_json, + outputs.update(emit_system.SYSTEM_OUTPUTS) + outputs.update({"system.json": emit_system.system_json, "system.md": lambda r: emit_system.system_md(r, _md_stamp(r))}) - if resolved["system"]["tasks"]: # SPEC-020 - outputs.update({"tasks.h": lambda r: emit_system.tasks_h(r, c), - "tasks.c": lambda r: emit_system.tasks_c(r, c)}) - return {placed(name): _file_header(name, fn(resolved)) for name, fn in sorted(outputs.items())} + if resolved["system"]["interrupts"]: + outputs.update(emit_system.INTERRUPT_OUTPUTS) + layout = _layout(resolved) + return {placed(name, layout): _file_header(name, fn(resolved)) for name, fn in sorted(outputs.items())} diff --git a/hw/gen/emb_hwgen/emit_system.py b/hw/gen/emb_hwgen/emit_system.py index 0fa73ddd..eedfa055 100644 --- a/hw/gen/emb_hwgen/emit_system.py +++ b/hw/gen/emb_hwgen/emit_system.py @@ -4,9 +4,16 @@ # This file is part of EmbLinkRTOS, a deterministic real-time kernel for microcontrollers. # Licensed under the Apache License, Version 2.0; see the LICENSE file at the repository root. -"""A system description's outputs (SPEC-014 §5.1, A125): system.h, system.c, system.json and -system.md. Data and macro calls only: the code they set in motion is the kernel's (the static -definition macros, SPEC-001 §6.4) and the drivers'.""" +"""A system description's outputs (SPEC-014 §5.1, A125), in MPLAB Harmony v3's form (A130). + +For each board, in the application's configuration folder src/config//: definitions.h, +configuration.h, initialization.c (SYS_Initialize()), tasks.c (the tasks' threads and +SYS_Tasks()), interrupts.h and interrupts.c, beside the board's own outputs and system.json and +system.md. For the application, beside system.yaml: CMakeLists.txt, src/main.c, each task's +src/.c and src/.h in Harmony's application template, and src/interrupt_handlers.c. +The code they set in motion is the kernel's (the static definition macros, SPEC-001 §6.4, and +the task runtime, SPEC-020) and the drivers'. +""" import json import textwrap @@ -17,92 +24,493 @@ PROTOCOL = {"inherit": "EMB_MUTEX_INHERIT", "ceiling": "EMB_MUTEX_CEILING", "none": "EMB_MUTEX_NONE"} SPEED = {"standard": "EMB_DRV_I2C_STANDARD", "fast": "EMB_DRV_I2C_FAST", "fast_plus": "EMB_DRV_I2C_FAST_PLUS"} +# The notice of a source in the tree (CS-11.1); an application outside it is its author's, and +# its files carry Harmony's banner alone. +SPDX = "/* SPDX-License-Identifier: Apache-2.0 */\n" +NOTICE = ("/*\n" + " * This file is part of EmbLinkRTOS, a deterministic real-time kernel for microcontrollers.\n" + " * Licensed under the Apache License, Version 2.0; see the LICENSE file at the repository root.\n" + " */\n") +STARS = "*" * 79 +BAR = "// " + "*" * 77 +END_OF_FILE = f"/{STARS}\n End of File\n*/\n" + def _sym(name): return name.upper().replace("-", "_") -def _intro(r, cmd_comment, what): - lines = textwrap.wrap(what, 96) - text = "/* " + "\n * ".join(lines) + " */\n" - return "/* SPDX-License-Identifier: Apache-2.0 */\n" + cmd_comment + text +def _pascal(name): + """A state's name in a function's: waiting_ack -> WaitingAck.""" + return "".join(part[:1].upper() + part[1:] for part in name.split("_") if part) -def system_h(r, c_comment): - s = r["system"] - out = _intro(r, c_comment, f"The system {s['name']}'s threads, objects, targets and watchdog for the application's " - "sources (SPEC-014 §5, A125).") - out += "#ifndef EMB_SYSTEM_H\n#define EMB_SYSTEM_H\n\n" - # the API, and the storage types the static definition macros take () - out += "#include \n" - if s["includes"]: - out += "\n" + "".join(f'#include "{h}"\n' for h in s["includes"]) - if s["tasks"]: - out += '\n#include "tasks.h"\n' - out += "\n#ifdef __cplusplus\nextern \"C\" {\n#endif\n" +def _data(t): + """A task's data instance, Harmony's Data.""" + return f"{t['name']}Data" + + +def _event_type(t): + return t["event"] or "emb_task_event_t" + + +# --------------------------------------------------------------------------- Harmony's templates + +def _wrap(text, indent=4, width=80): + return [" " * indent + line for line in textwrap.wrap(text, width - indent, break_on_hyphens=False)] or [""] + + +def _head(r, name, title, summary, description): + """A file's notice, where it is in the tree, then Harmony's banner: its title, its name, its + summary and its description, a list of paragraphs.""" + lines = [f"/{STARS}", f" {title}", "", " File Name:", f" {name}", "", " Summary:"] + lines += _wrap(summary) + lines += ["", " Description:"] + for i, para in enumerate(description): + if i: + lines.append("") + lines += para if isinstance(para, list) else _wrap(para) + lines.append(f" {STARS}/") + notice = SPDX + NOTICE + "\n" if r["system"]["in_tree"] else "" + return notice + "\n".join(lines) + "\n" + + +def _stamp(r, what): + """The generator's paragraph in a configuration file's banner: what wrote it, from which + inputs, and that regeneration merges its edits (A126).""" + lines = _wrap(f"Generated by emb-hwgen {VERSION}, schema v{SCHEMA_VERSION}, {what}. Yours to edit: " + "regenerating merges its changes with yours (A126):") + lines += [f" hw/gen/emb-hwgen.py generate --system {r['system_path']}", "", " Inputs (SHA-256):"] + for i in r["inputs"]: + lines += [f" {i['path']}", f" {i['sha256']}"] + return lines + + +def _section(title): + return f"\n{BAR}\n{BAR}\n// Section: {title}\n{BAR}\n{BAR}\n\n" + + +def _doc(signature, summary, description, precondition, parameters, returns, example, remarks): + """A function's block in a header, as Harmony writes them.""" + lines = [f"/{STARS}", " Function:", f" {signature}", "", " Summary:"] + lines += _wrap(summary, 5) + lines += ["", " Description:"] + _wrap(description) + lines += ["", " Precondition:"] + _wrap(precondition) + lines += ["", " Parameters:"] + lines += [f" {p}" for p in parameters] if parameters else [" None."] + lines += ["", " Returns:"] + _wrap(returns) + lines += ["", " Example:", " "] + [f" {e}" for e in example] + [" "] + lines += ["", " Remarks:"] + _wrap(remarks) + return "\n".join(lines) + "\n*/\n" + + +def _see(signature, header): + """A function's block in a source: where its prototype is.""" + return f"/{STARS}\n Function:\n {signature}\n\n Remarks:\n See prototype in {header}.\n */\n" + + +def _comment_block(title, summary, description, remarks=None): + """A type's or a datum's block, as Harmony writes them.""" + lines = [f"/* {title}", "", " Summary:"] + _wrap(summary) + ["", " Description:"] + _wrap(description) + if remarks: + lines += ["", " Remarks:"] + _wrap(remarks) + return "\n".join(lines) + "\n*/\n" + + +def _defines(defs): + """Macros, in order, their values aligned as clang-format aligns consecutive ones.""" + if not defs: + return "" + width = max(len(k) for k, _ in defs) + return "".join(f"#define {k.ljust(width)} {v}\n" for k, v in defs) + + +def _call(name, args, end=");"): + """A macro's or function's call, its arguments packed into lines of 100 columns and aligned + after the parenthesis, as clang-format packs them.""" + lines, line = [], f"{name}(" + for i, a in enumerate(args): + piece = a + (end if i == len(args) - 1 else ",") + if line.endswith(("(", ",")) and len(line) + len(piece) + (0 if line.endswith("(") else 1) <= 100: + line += ("" if line.endswith("(") else " ") + piece + else: + lines.append(line) + line = " " * (len(name) + 1) + piece + return "\n".join(lines + [line]) + + +def _cases(subject, cases): + """A switch on subject, at a function's indentation; a lone case is an if, as clang-tidy asks.""" + if len(cases) == 1: + value, body = cases[0] + return f" if ({subject} == {value}) {{\n" + "".join(f" {s}\n" for s in body) + " }\n" + out = f" switch ({subject}) {{\n" + for value, body in cases: + out += f" case {value}:\n" + "".join(f" {s}\n" for s in body) + " break;\n" + return out + " default:\n break;\n }\n" + + +def _cpp_open(): + return "#ifdef __cplusplus\nextern \"C\" {\n#endif\n" + + +def _cpp_close(): + return "#ifdef __cplusplus\n}\n#endif\n" + + +# --------------------------------------------------------------------------- src/config// + +def _task_what(t): + return f"an event task, its queue {t['queue']} deep" if t["model"] == "event" else \ + f"a periodic task, every {t['period_ms']} ms" + + +def definitions_h(r): + s, b, soc = r["system"], r["board"], r["soc"] + out = _head(r, "definitions.h", "System Definitions", + f"{s['name']}'s system definitions on the {b['name']}.", + ["The one header the application includes: the kernel's API, the board's devices, the system's " + "configuration and handles, every task's header, and the system's two functions, " + "SYS_Initialize() and SYS_Tasks().", + _stamp(r, f"from the system description and the {b['name']}'s")]) + out += "\n#ifndef DEFINITIONS_H\n#define DEFINITIONS_H\n" + out += _section("Included Files") + quoted = ["configuration.h"] + (["interrupts.h"] if s["interrupts"] else []) + list(s["includes"]) + if s["scaffold"]: + quoted += [f"{t['name']}.h" for t in s["tasks"]] + out += "".join(f'#include "{h}"\n' for h in sorted(set(quoted))) + out += "\n#include \n\n#include \n#include \n#include \n" + out += "\n#include \n#include \n\n" + out += _cpp_open() + out += "\n/* Device Information */\n" + out += _defines([("DEVICE_NAME", f'"{soc.get("part", soc["name"])}"'), ("DEVICE_ARCH", f'"{soc["cpu"]["core"]}"'), + ("DEVICE_FAMILY", f'"{soc["family"]}"'), ("BOARD_NAME", f'"{b["name"]}"')]) + out += "\n/* CPU clock frequency */\n" + _defines([("CPU_CLOCK_FREQUENCY", f"{r['clock']['hclk_hz']}u")]) + out += _section("System Functions") + out += _doc("void SYS_Initialize ( void *data )", "Initializes the board, the kernel and every task.", + "This function initializes the board (its clocks, pins and console), then the kernel (its objects " + "and the EARLY devices), then the application's interrupts, then each task, in its initial state. " + "The KERNEL devices start with the kernel, in SYS_Tasks().", + "None.", ["data - Unused; NULL."], "None.", + ["SYS_Initialize(NULL);", "while (true) {", " SYS_Tasks();", "}"], + "This function is called once, after reset, from main().") + out += "void SYS_Initialize(void *data);\n\n" + out += _doc("void SYS_Tasks ( void )", "Starts the kernel: the threads and the tasks run from here.", + "This function starts the KERNEL devices, then the scheduler, which runs the system's threads and " + "each task's thread. It does not return.", + "SYS_Initialize() has run.", [], "It does not return.", + ["SYS_Initialize(NULL);", "while (true) {", " SYS_Tasks();", "}"], + "Harmony calls its SYS_Tasks() in a loop; this one runs the scheduler and never comes back.") + out += "void SYS_Tasks(void);\n" + if s["threads"] or s["objects"] or s["spi_targets"] or s["i2c_targets"]: + out += _section("System Objects") if s["threads"]: - out += "\n/* threads: their entries, which the application defines, and their handles */\n" + out += "/* threads: their entries, which the application defines, and their handles */\n" for entry in sorted({t["entry"] for t in s["threads"]}): out += f"void {entry}(void *arg);\n" for t in s["threads"]: out += f"extern emb_thread_t {t['name']};\n" timers = [o for o in s["objects"] if o["type"] == "timer"] if s["objects"]: - out += "\n/* objects */\n" + out += ("\n" if s["threads"] else "") + "/* objects */\n" for cb in sorted({o["callback"] for o in timers}): out += f"void {cb}(emb_timer_t timer, void *arg);\n" for o in s["objects"]: out += f"extern {HANDLE[o['type']]} {o['name']};\n" if s["spi_targets"] or s["i2c_targets"]: - out += "\n/* bus targets, for the class's calls */\n" + out += ("\n" if s["threads"] or s["objects"] else "") + "/* bus targets, for the classes' calls */\n" for t in s["spi_targets"]: out += f"extern const emb_drv_spi_target_t {t['name']};\n" for t in s["i2c_targets"]: out += f"extern const emb_drv_i2c_target_t {t['name']};\n" + if s["tasks"]: + out += _section("Tasks") + out += "/* each task's handle, for emb_task_post() (SPEC-020) */\n" + for t in s["tasks"]: + out += f"extern emb_task_t {t['name']}_task;\n" + out += _defines([(f"{_sym(t['name'])}_TASK", f"(&{t['name']}_task)") for t in s["tasks"]]) + out += "\n" + _cpp_close() + "\n#endif /* DEFINITIONS_H */\n" + END_OF_FILE + return out + + +def _driver_settings(r): + """Each device's own settings, scalars only: what the application may read as DRV__.""" + out = [] + for d in r["devices"]: + for k, v in sorted(d["props"].items()): + if isinstance(v, bool): + out.append((d["name"], k, "true" if v else "false")) + elif isinstance(v, int): + out.append((d["name"], k, f"{v}u")) + return out + + +def configuration_h(r): + s, b = r["system"], r["board"] + out = _head(r, "configuration.h", "System Configuration Header", + f"The build-time configuration of {s['name']} on the {b['name']}.", + ["The system's settings as macros: the board and its clock, the devices' settings, each task's and " + "thread's priority and stack, the tasks' periods, queues and timeouts, and the application's " + "interrupts. The kernel's own options are 's CONFIG_EMB_*, and the board's hardware " + "'s EMB_HW_*.", + _stamp(r, f"from the system description and the {b['name']}'s")]) + out += "\n#ifndef CONFIGURATION_H\n#define CONFIGURATION_H\n" + out += _section("Included Files") + out += "#include \n\n#include \n\n" + _cpp_open() + out += _section("System Configuration") + sysdefs = [("SYS_CPU_CLOCK_HZ", f"{r['clock']['hclk_hz']}u"), ("SYS_TICK_NS", "CONFIG_EMB_TICK_NS"), + ("SYS_PRIORITY_COUNT", "CONFIG_EMB_PRIORITY_COUNT")] + if s["watchdog"]: + sysdefs.append(("SYS_WATCHDOG_TIMEOUT_MS", f"{s['watchdog']['timeout_ms']}u")) + out += _defines(sysdefs) if s["watchdog"]: - w = s["watchdog"] - out += (f"\n/* the watchdog: emb_drv_wdt_start(EMB_DEVICE({w['device']}), EMB_SYSTEM_WATCHDOG_TIMEOUT_MS) */\n" - f"#define EMB_SYSTEM_WATCHDOG_TIMEOUT_MS {w['timeout_ms']}u\n") - out += "\n#ifdef __cplusplus\n}\n#endif\n\n#endif /* EMB_SYSTEM_H */\n" + out += f"/* the watchdog: emb_drv_wdt_start(EMB_DEVICE({s['watchdog']['device']}), SYS_WATCHDOG_TIMEOUT_MS) */\n" + settings = _driver_settings(r) + if settings: + out += _section("Driver Configuration") + out += _defines([(f"DRV_{_sym(dev)}_{_sym(k)}", v) for dev, k, v in settings]) + if s["tasks"] or s["threads"] or s["interrupts"]: + out += _section("Application Configuration") + blocks = [] + for t in s["tasks"]: + N = _sym(t["name"]) + defs = [(f"{N}_PRIORITY", f"{t['priority']}u"), (f"{N}_STACK_SIZE", f"{t['stack']}u")] + if t["model"] == "periodic": + defs.append((f"{N}_PERIOD_MS", f"{t['period_ms']}u")) + else: + defs.append((f"{N}_QUEUE_LENGTH", f"{t['queue']}u")) + defs += [(f"{N}_{_sym(st)}_TIMEOUT_MS", f"{ms}u") for st, ms in sorted(t["timeouts"].items())] + blocks.append(f"/* {t['name']}: {_task_what(t)} */\n" + _defines(defs)) + for t in s["threads"]: + N = _sym(t["name"]) + blocks.append(f"/* {t['name']}: a thread */\n" + + _defines([(f"{N}_PRIORITY", f"{t['priority']}u"), (f"{N}_STACK_SIZE", f"{t['stack']}u")])) + for i in s["interrupts"]: + N = _sym(i["name"]) + defs = [(f"{N}_IRQ", f"{i['irq']}u")] + ([(f"{N}_IRQ_LEVEL", f"{i['level']}u")] if i["level"] is not None else []) + blocks.append(f"/* {i['name']}: an interrupt, {i['handler']}() */\n" + _defines(defs)) + out += "\n".join(blocks) + out += "\n" + _cpp_close() + "\n#endif /* CONFIGURATION_H */\n" + END_OF_FILE return out -def system_c(r, c_comment): - s = r["system"] - out = _intro(r, c_comment, f"The system {s['name']}'s static definitions: the kernel creates each from its " - "initialization table (SPEC-001 §6.4, SPEC-014 §5, A125).") - out += '#include "system.h"\n' - if s["spi_targets"]: - out += "\n#include \n" +def initialization_c(r): + s, b = r["system"], r["board"] + out = _head(r, "initialization.c", "System Initialization File", + f"{s['name']}'s initialization on the {b['name']}: SYS_Initialize(), and the system's objects.", + ["The system's static definitions, which the kernel creates from its initialization table when " + "emb_kernel_init() runs (SPEC-001 §6.4), and SYS_Initialize(), which brings up the board, the " + "kernel, the application's interrupts and the tasks.", + _stamp(r, f"from the system description and the {b['name']}'s")]) + out += _section("Included Files") + out += '#include "definitions.h"\n' + defs = [] for t in s["threads"]: flags = " | ".join(t["flags"]) if t["flags"] else "0u" - out += (f"\nEMB_THREAD_DEFINE({t['name']}, {t['entry']}, {t['arg']}, {t['priority']}u, {t['stack']}u, {flags});") + N = _sym(t["name"]) + defs.append(_call("EMB_THREAD_DEFINE", [t["name"], t["entry"], t["arg"], f"{N}_PRIORITY", f"{N}_STACK_SIZE", flags])) for o in s["objects"]: n, k = o["name"], o["type"] if k == "mutex": - out += f"\nEMB_MUTEX_DEFINE({n}, {PROTOCOL[o['protocol']]}, {o.get('ceiling', 0)}u, 0u);" + defs.append(f"EMB_MUTEX_DEFINE({n}, {PROTOCOL[o['protocol']]}, {o.get('ceiling', 0)}u, 0u);") elif k == "sem": - out += f"\nEMB_SEM_DEFINE({n}, {o['initial']}u, {o['max']}u);" + defs.append(f"EMB_SEM_DEFINE({n}, {o['initial']}u, {o['max']}u);") elif k == "cond": - out += f"\nEMB_COND_DEFINE({n}, 0u);" + defs.append(f"EMB_COND_DEFINE({n}, 0u);") elif k == "event": - out += f"\nEMB_EVENT_DEFINE({n}, {o['initial']}u, 0u);" + defs.append(f"EMB_EVENT_DEFINE({n}, {o['initial']}u, 0u);") elif k == "msgq": size = f"sizeof({o['item']})" if o["item"] else f"{o['item_size']}u" - out += f"\nEMB_MSGQ_DEFINE({n}, {size}, {o['capacity']}u, 0u);" + defs.append(f"EMB_MSGQ_DEFINE({n}, {size}, {o['capacity']}u, 0u);") elif k == "timer": - out += f"\nEMB_TIMER_DEFINE({n}, {o['callback']}, {o['arg']});" + defs.append(f"EMB_TIMER_DEFINE({n}, {o['callback']}, {o['arg']});") elif k == "workq": - out += f"\nEMB_WORKQ_DEFINE({n}, {o['priority']}u, {o['stack']}u);" - if s["threads"] or s["objects"]: - out += "\n" - for t in s["spi_targets"]: - cs = f"EMB_SOC_{_sym(t['bus'])}_CS{t['cs']}" if t["cs"] is not None else "{NULL, 0u, 0u, {0u, 0u}}" - out += (f"\n/* {t['bus']}: at most {t['hz']} Hz, mode {t['mode']} */\n" - f"const emb_drv_spi_target_t {t['name']} = {{{t['hz']}u, EMB_DRV_SPI_MODE_{t['mode']}, {t['bits']}u, 0u, 0u, {cs}}};\n") + defs.append(f"EMB_WORKQ_DEFINE({n}, {o['priority']}u, {o['stack']}u);") + targets = "" + for t in s["spi_targets"]: # designated: the flags and the chip select's absence start at zero + cs = [("cs", f"EMB_SOC_{_sym(t['bus'])}_CS{t['cs']}")] if t["cs"] is not None else [] + members = [("hz", f"{t['hz']}u"), ("mode", f"EMB_DRV_SPI_MODE_{t['mode']}"), ("bits", f"{t['bits']}u")] + cs + targets += (f"\n/* {t['bus']}: at most {t['hz']} Hz, mode {t['mode']} */\n" + f"const emb_drv_spi_target_t {t['name']} = {{\n" + "".join(f" .{k} = {v},\n" for k, v in members) + + "};\n") for t in s["i2c_targets"]: - out += (f"\n/* {t['bus']}: address 0x{t['address']:02X}, {t['speed'].replace('_', ' ')} mode */\n" - f"const emb_drv_i2c_target_t {t['name']} = {{{SPEED[t['speed']]}, 0x{t['address']:02X}u, {{0u, 0u}}}};\n") + members = [("hz", SPEED[t["speed"]]), ("address", f"0x{t['address']:02X}u")] + targets += (f"\n/* {t['bus']}: address 0x{t['address']:02X}, {t['speed'].replace('_', ' ')} mode */\n" + f"const emb_drv_i2c_target_t {t['name']} = {{\n" + "".join(f" .{k} = {v},\n" for k, v in members) + + "};\n") + if defs or targets: + out += _section("System Objects") + if defs: + out += "/* the kernel creates each when emb_kernel_init() runs (SPEC-001 §6.4) */\n" + out += "\n".join(defs) + "\n" + out += targets + out += _section("System Initialization") + out += _see("void SYS_Initialize ( void *data )", "definitions.h") + out += "void SYS_Initialize(void *data)\n{\n (void)data;\n\n" + out += " /* The board: its clocks, pins and console */\n emb_board_init();\n\n" + out += " /* The kernel: its objects, and the EARLY devices */\n emb_kernel_init();\n" + if s["interrupts"]: + out += "\n /* The application's interrupts */\n SYS_INT_Initialize();\n" + if s["tasks"] and s["scaffold"]: + out += "\n /* The tasks, each in its initial state */\n" + out += "".join(f" {_sym(t['name'])}_Initialize();\n" for t in s["tasks"]) + out += "}\n" + END_OF_FILE + return out + + +def _task_desc(t): + """A task's queue, dispatch, entry and exit switches, description, handle and thread.""" + n, N = t["name"], _sym(t["name"]) + event, ev_t, data = t["model"] == "event", _event_type(t), _data(t) + out = f"\n/* ---- {n}: {_task_what(t)} (SPEC-020) ---- */\n\n" + # the enumerations are the application's (A130), their values the runtime's numbers + for i, st in enumerate(t["states"]): + out += f'_Static_assert({N}_STATE_{_sym(st)} == {i}, "{n}.h: {N}_STATES are system.yaml\'s states, in order");\n' + for i, ev in enumerate(t["events"]): + out += (f'_Static_assert({N}_EVENT_{_sym(ev)} == EMB_EV_USER + {i}u,\n' + f' "{n}.h: {N}_EVENTS are system.yaml\'s events, in order");\n') + if t["event"]: + out += f'_Static_assert(offsetof({ev_t}, id) == 0u, "{ev_t}: its first member is its id");\n' + if event: + out += f"\nstatic {ev_t} {n}_event;\n" + out += f"EMB_MSGQ_DEFINE({n}_task_queue, sizeof({ev_t}), {N}_QUEUE_LENGTH, 0u);\n" + if t["timeouts"]: + vals = ", ".join(f"{N}_{_sym(st)}_TIMEOUT_MS" if st in t["timeouts"] else "0u" for st in t["states"]) + out += f"static const uint32_t {n}_timeouts[{len(t['states'])}] = {{{vals}}};\n" + out += f"\nstatic emb_state_t {n}_dispatch(emb_state_t state, uint8_t why)\n{{\n" + if not event: # Harmony's: the application's switch makes the moves (A130) + out += f" (void)state;\n (void)why;\n {N}_Tasks();\n return (emb_state_t){data}.state;\n}}\n" + else: + # each case names its state: no number is cast back to the enumeration + out += " emb_state_t next = state; /* a state the task lacks stays: the runtime faults on it */\n" + if t["timeouts"]: + out += f" if (why == EMB_TASK_WHY_TIMEOUT) {{\n {n}_event.id = EMB_EV_TIMEOUT;\n" + if not t["event"]: + out += f" {n}_event.value = 0u;\n" + out += " }\n" + else: + out += " (void)why;\n" + out += _cases("state", [(f"{N}_STATE_{_sym(st)}", + [f"{data}.state = {N}_STATE_{_sym(st)};", + f"next = (emb_state_t){N}_On{_pascal(st)}(&{n}_event);"]) for st in t["states"]]) + out += " return next;\n}\n" + if t["entry"]: # every state's case: the data shows the state entered + out += f"\nstatic void {n}_enter(emb_state_t state)\n{{\n" + out += _cases("state", [(f"{N}_STATE_{_sym(st)}", + [f"{data}.state = {N}_STATE_{_sym(st)};"] + + ([f"{N}_Enter{_pascal(st)}();"] if st in t["entry"] else [])) for st in t["states"]]) + out += "}\n" + if t["exit"]: + out += f"\nstatic void {n}_exit(emb_state_t state)\n{{\n" + out += _cases("state", [(f"{N}_STATE_{_sym(st)}", [f"{N}_Exit{_pascal(st)}();"]) for st in t["exit"]]) + out += "}\n" + enter = f"{n}_enter" if t["entry"] else "NULL" + leave = f"{n}_exit" if t["exit"] else "NULL" + evbuf = f"&{n}_event" if event else "NULL" + queue = f"&{n}_task_queue" if event else "NULL" + timeouts = f"{n}_timeouts" if (event and t["timeouts"]) else "NULL" + size = f"(uint16_t)sizeof({ev_t})" if event else "0u" + period = f"{N}_PERIOD_MS" if not event else "0u" + model = "EMB_TASK_EVENT" if event else "EMB_TASK_PERIODIC" + initial = f"(emb_state_t){N}_STATE_{_sym(t['initial'])}" + fields = [("name", f'"{n}"'), ("dispatch", f"{n}_dispatch"), ("enter", enter), ("leave", leave), + ("event", evbuf), ("queue", queue), ("timeout_ms", timeouts), ("period_ms", period), + ("event_size", size), ("initial", initial), ("count", f"{len(t['states'])}u"), ("model", model)] + out += f"\nstatic const emb_task_desc_t {n}_desc = {{\n" + "".join(f" .{k} = {v},\n" for k, v in fields) + "};\n" + out += f"emb_task_t {n}_task = {{.desc = &{n}_desc, .state = {initial}}};\n" + out += f"\nstatic void {n}_main(void *arg)\n{{\n (void)arg;\n emb_task_run(&{n}_task);\n}}\n" + out += "\n" + _call("EMB_THREAD_DEFINE", [f"{n}_thread", f"{n}_main", "NULL", f"{N}_PRIORITY", f"{N}_STACK_SIZE", "0u"]) + "\n" + return out + + +def tasks_c(r): + s, b = r["system"], r["board"] + out = _head(r, "tasks.c", "System Tasks File", + f"{s['name']}'s tasks on the {b['name']}, and SYS_Tasks().", + ["Each task's thread, queue, dispatch and description: the thread runs the task runtime, " + "emb_task_run() (SPEC-020), which calls an event task's handler for each event, and a periodic " + "task's _Tasks() every period, without drift. SYS_Tasks() starts the kernel.", + _stamp(r, f"from the system description and the {b['name']}'s")]) + out += _section("Included Files") + out += '#include "definitions.h"\n' + if s["tasks"]: + out += _section('RTOS "Tasks" Routine') + out += "".join(_task_desc(t) for t in s["tasks"]).lstrip("\n") + out += _section('System "Tasks" Routine') + out += _see("void SYS_Tasks ( void )", "definitions.h") + out += ("void SYS_Tasks(void)\n{\n /* Start the kernel: the threads and the tasks run from here. It does not return. */\n" + " emb_kernel_start();\n}\n") + return out + END_OF_FILE + + +def _irq_lines(r): + """Every interrupt line in use on the board: (number, who).""" + lines = [] + for d in r["devices"]: + for f in d["fields"]: + if ".irqs." in str(f["expr"]) and isinstance(f["value"], int): + lines.append((f["value"], f"{d['name']}, its driver ({f['expr']})")) + for i in r["system"]["interrupts"]: + lines.append((i["irq"], f"{i['name']}, the application's {i['handler']}()")) + return sorted(set(lines)) + + +def interrupts_h(r): + s, b = r["system"], r["board"] + out = _head(r, "interrupts.h", "Interrupt Handlers", + f"{s['name']}'s interrupt handlers on the {b['name']}.", + ["The application's own interrupt handlers, which it defines (src/interrupt_handlers.c), and " + "SYS_INT_Initialize(), which connects each at its level and enables it. The board's devices " + "connect their own: interrupts.c lists every line in use.", + _stamp(r, f"from the system description and the {b['name']}'s")]) + out += "\n#ifndef INTERRUPTS_H\n#define INTERRUPTS_H\n" + out += _section("Included Files") + out += "#include \n\n" + _cpp_open() + out += _section("Handler Routines") + for i in s["interrupts"]: + level = f" at level {i['level']}" if i["level"] is not None else "" + out += _doc(f"void {i['handler']} ( void *arg )", f"The {i['name']} interrupt's handler.", + f"This function runs in interrupt context when line {i['irq']} is raised{level}: a " + "kernel-aware handler, which may post to a task (emb_task_post()) but not wait.", + "SYS_INT_Initialize() has connected it.", ["arg - Unused; NULL."], "None.", + [f"emb_irq_pend({_sym(i['name'])}_IRQ);"], + "The application defines it. Keep it short: hand the work to a task.") + out += f"void {i['handler']}(void *arg);\n\n" + out += _doc("void SYS_INT_Initialize ( void )", "Connects the application's interrupt handlers.", + "This function connects each of the application's handlers to its line, sets its level and " + "enables it.", + "The kernel is initialized (emb_kernel_init()).", [], "None.", ["SYS_INT_Initialize();"], + "SYS_Initialize() calls it.") + out += "void SYS_INT_Initialize(void);\n\n" + _cpp_close() + "\n#endif /* INTERRUPTS_H */\n" + END_OF_FILE + return out + + +def interrupts_c(r): + s, b = r["system"], r["board"] + out = _head(r, "interrupts.c", "Interrupt Handlers", + f"{s['name']}'s interrupts on the {b['name']}: the lines in use, and SYS_INT_Initialize().", + ["The table of every interrupt line in use, the devices' and the application's, and " + "SYS_INT_Initialize(), which connects the application's handlers. The checks were made when it " + "was generated: each line is the SoC's, no device's driver connects it, and its level is the " + "port's.", + _stamp(r, f"from the system description and the {b['name']}'s")]) + out += _section("Included Files") + out += '#include "definitions.h"\n' + out += _section("Interrupt Lines") + out += f"/* The lines in use on the {b['name']}:\n" + width = max(len(str(n)) for n, _ in _irq_lines(r)) + out += "".join(f" * {str(n).rjust(width)} {who}\n" for n, who in _irq_lines(r)) + " */\n" + out += _section("Interrupt Initialization") + out += _see("void SYS_INT_Initialize ( void )", "interrupts.h") + out += "void SYS_INT_Initialize(void)\n{\n" + for k, i in enumerate(s["interrupts"]): + N = _sym(i["name"]) + out += ("\n" if k else "") + f" /* {i['name']}: line {i['irq']} */\n" + out += f" (void)emb_irq_connect({N}_IRQ, {i['handler']}, NULL);\n" + if i["level"] is not None: + out += f" (void)emb_irq_set_level({N}_IRQ, {N}_IRQ_LEVEL);\n" + out += f" (void)emb_irq_enable({N}_IRQ);\n" + out += "}\n" + END_OF_FILE return out @@ -111,14 +519,14 @@ def system_json(r): doc = {"generator": {"name": "emb-hwgen", "version": VERSION}, "schema_version": SCHEMA_VERSION, "inputs": r["inputs"], "board": r["board"]["name"], "profile": r["profile"]} doc.update({k: s[k] for k in ("name", "boards", "threads", "tasks", "objects", "devices", "spi_targets", - "i2c_targets", "watchdog", "config", "includes", "conf", "scaffold")}) + "i2c_targets", "watchdog", "interrupts", "config", "includes", "conf", "scaffold")}) return json.dumps(doc, indent=2, sort_keys=True) + "\n" def system_md(r, stamp): s = r["system"] out = f"# {s['name']}: the system on {r['board']['name']}\n\n" - out += (f"Generated from `{s['path']}` (SPEC-014 §5, A125). Profile {r['profile']}, " + out += (f"Generated from `{s['path']}` (SPEC-014 §5, A125, A130). Profile {r['profile']}, " f"{s['config'].get('CONFIG_EMB_PRIORITY_COUNT', '?')} priorities, a minimum stack of " f"{s['config'].get('CONFIG_EMB_ARCH_STACK_MIN', '?')} bytes.\n") if s["threads"]: @@ -150,6 +558,12 @@ def system_md(r, stamp): else: what = "" out += f"| `{o['name']}` | {o['type']} | {what} |\n" + if s["interrupts"]: + out += "\n## Interrupts\n\n| Interrupt | Line | Handler | Level |\n|---|---|---|---|\n" + for i in s["interrupts"]: + line = f"{i['irq']} (`{i['source']}`)" if i["source"] else str(i["irq"]) + level = "the port's" if i["level"] is None else str(i["level"]) + out += f"| `{i['name']}` | {line} | `{i['handler']}` | {level} |\n" if s["devices"]: out += "\n## Device settings\n\n| Device | Option | Value | The board's |\n|---|---|---|---|\n" for dev, opts in s["devices"].items(): @@ -168,165 +582,206 @@ def system_md(r, stamp): return out + stamp -# --------------------------------------------------------------------------- tasks (SPEC-020) +# The system's own outputs in its configuration folder, beside the board's (A130). +SYSTEM_OUTPUTS = {"definitions.h": definitions_h, "configuration.h": configuration_h, + "initialization.c": initialization_c, "tasks.c": tasks_c} +INTERRUPT_OUTPUTS = {"interrupts.h": interrupts_h, "interrupts.c": interrupts_c} -def _up(name): - return name.upper() +# --------------------------------------------------------------------------- the application's own files -def _event_type(t): - return t["event"] or "emb_task_event_t" +def _app_desc(paragraph): + return [paragraph, "Generated by emb-hwgen from system.yaml, then yours to edit: regeneration merges its " + "changes with yours (A126, A130)."] -def _handler_decls(t): - """The handlers a task's application file defines, as declarations.""" - n, out = t["name"], [] - for st in t["states"]: - if t["model"] == "periodic": - out.append(f"emb_state_t {n}_on_{st}({n}_t *self);") - else: - out.append(f"emb_state_t {n}_on_{st}({n}_t *self, const {_event_type(t)} *ev);") - out += [f"void {n}_enter_{st}({n}_t *self);" for st in t["entry"]] - out += [f"void {n}_exit_{st}({n}_t *self);" for st in t["exit"]] - return out +def main_c(r): + s = r["system"] + out = _head(r, "main.c", "Main Source File", f"{s['name']}'s entry point.", + _app_desc("This file holds main(): it initializes the system, the board, the kernel and the tasks " + "(SYS_Initialize()), then starts the kernel (SYS_Tasks()), from which the threads and the " + "tasks run.")) + out += _section("Included Files") + out += '#include "definitions.h"\n\n#include \n#include \n#include \n' + out += _section("Main Entry Point") + out += ("int main(void)\n{\n /* Initialize all modules */\n SYS_Initialize(NULL);\n\n while (true) {\n" + " /* Start the kernel: the threads and the tasks run from here. It does not return. */\n" + " SYS_Tasks();\n }\n\n /* Execution should not come here during normal operation */\n" + " return EXIT_FAILURE;\n}\n") + return out + END_OF_FILE + + +def _states_enum(t): + N = _sym(t["name"]) + out = _comment_block("Application states", f"The {t['name']} task's states.", + f"The states system.yaml declares for the task, in its order: they are the task runtime's " + f"numbers, which tasks.c checks. Declare a state in system.yaml, and regeneration adds it " + f"here{', with its case in ' + N + '_Tasks()' if t['model'] == 'periodic' else ', with its handler'}.") + out += "typedef enum {\n" + for i, st in enumerate(t["states"]): + if st == t["initial"]: + out += " /* The task's initial state. */\n" + out += f" {N}_STATE_{_sym(st)}" + (" = 0" if i == 0 else "") + ",\n" + return out + f"}} {N}_STATES;\n" -def tasks_h(r, c_comment): - s = r["system"] - out = _intro(r, c_comment, f"The system {s['name']}'s tasks: their states, events, types, handlers and handles " - "(SPEC-020).") - out += "#ifndef EMB_TASKS_H\n#define EMB_TASKS_H\n\n#include \n\n#include \n" - own = [t for t in s["tasks"] if s["scaffold"] and (t["data"] or t["event"])] - if own or s["includes"]: - out += "\n" + "".join(f'#include "{h}"\n' for h in s["includes"]) - out += "".join(f'#include "tasks/{t["name"]}.h"\n' for t in own) - out += "\n#ifdef __cplusplus\nextern \"C\" {\n#endif\n" - for t in s["tasks"]: - n, N = t["name"], _up(t["name"]) - out += f"\n/* {n}: {t['model']}" + (f", every {t['period_ms']} ms" if t["model"] == "periodic" else "") + " */\n" - for i, st in enumerate(t["states"]): # typed: a handler's ternary of two states stays an emb_state_t - out += f"#define {N}_{_up(st)} ((emb_state_t){i}u)\n" - out += f"#define {N}_STATE_COUNT ((emb_state_t){len(t['states'])}u)\n" +def task_h(r, t): + n, N = t["name"], _sym(t["name"]) + event = t["model"] == "event" + out = _head(r, f"{n}.h", f"{n}: {_task_what(t)}", f"The {n} task's states, " + ("events, " if event else "") + + "data and functions.", + _app_desc(f"This header declares what the {n} task's own file defines: its states, " + + ("its events, " if event else "") + f"its data, {N}_Initialize() and " + + (f"a handler for each state, which the task's thread runs for each event (SPEC-020)." + if event else f"{N}_Tasks(), which the task's thread calls every {t['period_ms']} ms, " + "without drift (SPEC-020)."))) + out += f"\n#ifndef {N}_H\n#define {N}_H\n" + out += _section("Included Files") + out += '#include "configuration.h"\n\n#include \n\n#include \n#include \n' + out += "#include \n\n" + _cpp_open() + out += _section("Type Definitions") + out += _states_enum(t) + if t["events"]: + out += "\n" + _comment_block("Application events", f"The {n} task's own events.", + "Numbered from EMB_EV_USER, as system.yaml lists them; the runtime's own, such " + "as EMB_EV_TIMEOUT, are below it. Post one with emb_task_post(" + f"{N}_TASK, {N}_EVENT_, value).") + out += "typedef enum {\n" for i, ev in enumerate(t["events"]): - out += f"#define {N}_EV_{_up(ev)} (EMB_EV_USER + {i}u)\n" - out += f"typedef struct {n} {{\n emb_task_t task; /* first: the runtime's */\n" - if t["data"]: - out += f" {t['data']} data;\n" - out += f"}} {n}_t;\n" - out += f"extern {n}_t {n};\n#define {N}_TASK (&{n}.task)\n" - if t["event"]: - out += (f"_Static_assert(offsetof({t['event']}, id) == 0u, \"{t['event']}: its first member is its id\");\n") - out += "".join(d + "\n" for d in _handler_decls(t)) - out += "\n#ifdef __cplusplus\n}\n#endif\n\n#endif /* EMB_TASKS_H */\n" + out += f" {N}_EVENT_{_sym(ev)}" + (" = EMB_EV_USER" if i == 0 else "") + ",\n" + out += f"}} {N}_EVENTS;\n" + if t["event"]: + out += "\n" + _comment_block("Application event", f"The {n} task's own event type.", + "The events posted to the task (emb_task_post_event()): the runtime reads its " + "first member, the id.") + out += (f"typedef struct {{\n uint32_t id; /* first: {N}_EVENTS, or the runtime's EMB_EV_* */\n" + f" uint32_t value;\n\n /* TODO: Define the event's data. */\n}} {t['event']};\n") + remarks = (f"state is the state whose handler runs; the runtime keeps it (emb_task_state({N}_TASK))." if event + else f"{N}_Tasks() moves the task by setting state.") + out += "\n" + _comment_block("Application Data", f"Holds the {n} task's data.", + "This structure holds the task's data: only the task's thread runs its " + + ("handlers." if event else f"{N}_Tasks()."), remarks) + out += (f"typedef struct {{\n /* The task's current state */\n {N}_STATES state;\n\n" + f" /* TODO: Define any additional data used by the task. */\n}} {N}_DATA;\n\n" + f"extern {N}_DATA {_data(t)};\n") + out += _section("Application Initialization and State Machine Functions") + out += _doc(f"void {N}_Initialize ( void )", f"The {n} task's initialization.", + f"This function puts the task in its initial state, {N}_STATE_{_sym(t['initial'])}, and prepares its " + "data, before the kernel starts its thread.", + "The board and the kernel are initialized. The KERNEL devices are not ready yet: use them from the " + "task's states.", [], "None.", [f"{N}_Initialize();"], "SYS_Initialize() calls it.") + out += f"void {N}_Initialize(void);\n" + if not event: + out += "\n" + _doc(f"void {N}_Tasks ( void )", f"The {n} task's state machine.", + f"This function runs the task's current state, {_data(t)}.state, once: its thread calls it " + f"every {t['period_ms']} ms.", + f"{N}_Initialize() has run.", [], "None.", [f"{N}_Tasks();"], + "Its thread calls it on a period that does not drift; a period it overruns is counted, not " + "run twice (KRN-TSK-004).") + out += f"void {N}_Tasks(void);\n" + else: + ev_t = _event_type(t) + for k, st in enumerate(t["states"]): + S = _pascal(st) + other = t["states"][(k + 1) % len(t["states"])] + example = ([f"return (event->id == {N}_EVENT_{_sym(t['events'][0])}) ? {N}_STATE_{_sym(other)} : " + f"{N}_STATE_{_sym(st)};"] if t["events"] else [f"return {N}_STATE_{_sym(st)};"]) + out += "\n" + _doc(f"{N}_STATES {N}_On{S} ( const {ev_t} *event )", + f"The {n} task's {st} state: one event.", + f"This function runs for each event the task receives in {N}_STATE_{_sym(st)}" + + (", and with EMB_EV_TIMEOUT when the state's timeout passes" + if st in t["timeouts"] else "") + ". It returns the state to be in next: " + f"{N}_STATE_{_sym(st)} to stay.", + f"{N}_Initialize() has run; the kernel runs the task's thread.", + ["event - The event: its id and its value."], "The next state.", example, + "The task's thread calls it, one event at a time; no event is lost meanwhile " + "(KRN-TSK-001).") + out += f"{N}_STATES {N}_On{S}(const {ev_t} *event);\n" + for kind, names, word in (("entry", t["entry"], "Enter"), ("exit", t["exit"], "Exit")): + for st in names: + S = _pascal(st) + out += "\n" + _doc(f"void {N}_{word}{S} ( void )", + f"The {n} task's {st} state: its {kind} action.", + f"This function runs as the task {'enters' if kind == 'entry' else 'leaves'} " + f"{N}_STATE_{_sym(st)}" + (", after the old state's exit action" if kind == "entry" + else ", before the new state's entry action") + ".", + f"{N}_Initialize() has run.", [], "None.", [f"{N}_{word}{S}();"], + "The task's thread calls it (KRN-TSK-002).") + out += f"void {N}_{word}{S}(void);\n" + out += "\n" + _cpp_close() + f"\n#endif /* {N}_H */\n" + END_OF_FILE return out -def tasks_c(r, c_comment): - s = r["system"] - out = _intro(r, c_comment, f"The system {s['name']}'s tasks: each one's queue, dispatch, description and thread " - "(SPEC-020); the runtime is emb_task_run().") - out += '#include "tasks.h"\n' - for t in s["tasks"]: - n, N, ev_t = t["name"], _up(t["name"]), _event_type(t) - event = t["model"] == "event" - out += f"\n/* ---- {n} ---- */\n" - if event: - out += f"static {ev_t} {n}_event;\n" - out += f"EMB_MSGQ_DEFINE({n}_task_queue, sizeof({ev_t}), {t['queue']}u, 0u);\n" - if t["timeouts"]: - vals = ", ".join(f"{t['timeouts'].get(st, 0)}u" for st in t["states"]) - out += f"static const uint32_t {n}_timeouts[{len(t['states'])}] = {{{vals}}};\n" - out += f"\nstatic emb_state_t {n}_dispatch(emb_state_t state, uint8_t why)\n{{\n" - out += " emb_state_t next;\n" - if event and t["timeouts"]: - out += f" if (why == EMB_TASK_WHY_TIMEOUT) {{\n {n}_event.id = EMB_EV_TIMEOUT;\n" - if not t["event"]: - out += f" {n}_event.value = 0u;\n" - out += " }\n" - else: - out += " (void)why;\n" - out += " switch (state) {\n" +def task_c(r, t): + n, N = t["name"], _sym(t["name"]) + event, data = t["model"] == "event", _data(t) + out = _head(r, f"{n}.c", f"{n}: {_task_what(t)}", f"The {n} task's " + + ("handlers." if event else "state machine."), + _app_desc(f"This file holds the {n} task's data and " + + ("its handlers, one per state, each returning the state to be in next (SPEC-020)." + if event else f"{N}_Tasks(), the switch on its state that its thread runs every " + f"{t['period_ms']} ms (SPEC-020)."))) + out += _section("Included Files") + out += '#include "definitions.h"\n' + out += _section("Global Data Definitions") + out += _comment_block("Application Data", f"Holds the {n} task's data.", "This structure holds the task's data.", + f"{N}_Initialize() starts it, and the task's " + + ("handlers use it." if event else f"{N}_Tasks() uses it.")) + out += f"{N}_DATA {data};\n" + out += _section("Application Callback Functions") + out += "/* TODO: Add any necessary callback functions. */\n" + out += _section("Application Local Functions") + out += "/* TODO: Add any necessary local functions. */\n" + out += _section("Application Initialization and State Machine Functions") + out += _see(f"void {N}_Initialize ( void )", f"{n}.h") + out += (f"void {N}_Initialize(void)\n{{\n /* Place the task in its initial state. */\n" + f" {data}.state = {N}_STATE_{_sym(t['initial'])};\n\n /* TODO: Initialize the task's data. */\n}}\n") + if not event: + out += "\n" + _see(f"void {N}_Tasks ( void )", f"{n}.h") + out += f"void {N}_Tasks(void)\n{{\n /* Check the task's current state. */\n switch ({data}.state) {{\n" + for st in t["states"]: + if st == t["initial"]: + out += " /* The task's initial state. */\n" + out += f" case {N}_STATE_{_sym(st)}: {{\n /* TODO: Do this state's work; set {data}.state to move. */\n" + out += " break;\n }\n" + out += (" /* The default state should never be executed. */\n default: {\n" + " /* TODO: Handle error in the task's state machine. */\n break;\n }\n }\n}\n") + else: + ev_t = _event_type(t) for st in t["states"]: - call = f"{n}_on_{st}(&{n})" if not event else f"{n}_on_{st}(&{n}, &{n}_event)" - out += f" case {N}_{_up(st)}:\n next = {call};\n break;\n" - out += " default:\n next = state;\n break;\n }\n return next;\n}\n" - for kind, names in (("enter", t["entry"]), ("exit", t["exit"])): - if not names: - continue - out += f"\nstatic void {n}_{kind}(emb_state_t state)\n{{\n switch (state) {{\n" + S = _pascal(st) + out += "\n" + _see(f"{N}_STATES {N}_On{S} ( const {ev_t} *event )", f"{n}.h") + out += (f"{N}_STATES {N}_On{S}(const {ev_t} *event)\n{{\n" + " /* TODO: Handle the event; return the state to be in next. */\n" + f" (void)event;\n return {N}_STATE_{_sym(st)};\n}}\n") + for names, word in ((t["entry"], "Enter"), (t["exit"], "Exit")): for st in names: - out += f" case {N}_{_up(st)}:\n {n}_{kind}_{st}(&{n});\n break;\n" - out += " default:\n break;\n }\n}\n" - enter = f"{n}_enter" if t["entry"] else "NULL" - leave = f"{n}_exit" if t["exit"] else "NULL" - evbuf = f"&{n}_event" if event else "NULL" - queue = f"&{n}_task_queue" if event else "NULL" - timeouts = f"{n}_timeouts" if (event and t["timeouts"]) else "NULL" - size = f"(uint16_t)sizeof({ev_t})" if event else "0u" - model = "EMB_TASK_EVENT" if event else "EMB_TASK_PERIODIC" - out += (f"\nstatic const emb_task_desc_t {n}_desc = {{\"{n}\", {n}_dispatch, {enter}, {leave}, {evbuf}, {queue},\n" - f" {timeouts}, {t['period_ms']}u, {size}, {N}_{_up(t['initial'])},\n" - f" {N}_STATE_COUNT, {model}, 0u}};\n") - # designated: the counters, and the task's data, start at zero - out += f"{n}_t {n} = {{.task = {{.desc = &{n}_desc, .state = {N}_{_up(t['initial'])}}}}};\n" - out += f"\nstatic void {n}_main(void *arg)\n{{\n (void)arg;\n emb_task_run(&{n}.task);\n}}\n" - out += f"\nEMB_THREAD_DEFINE({n}_thread, {n}_main, NULL, {t['priority']}u, {t['stack']}u, 0u);\n" - return out - + S = _pascal(st) + out += "\n" + _see(f"void {N}_{word}{S} ( void )", f"{n}.h") + out += f"void {N}_{word}{S}(void)\n{{\n /* TODO: The state's {word.lower()} action. */\n}}\n" + return out + END_OF_FILE -# --------------------------------------------------------------------------- the application's own files (A126) -def _app_note(system_path, kind): - """The note an application's own files carry: stable, so editing system.yaml does not touch it.""" - text = f"Generated by emb-hwgen from {system_path}; yours to edit: regeneration merges its changes (A126)." - if kind == "hash": - return "# SPDX-License-Identifier: Apache-2.0\n# " + text + "\n" - return "/* SPDX-License-Identifier: Apache-2.0 */\n/*\n * " + text + "\n */\n" - - -def main_c(r): +def interrupt_handlers_c(r): s = r["system"] - out = _app_note("system.yaml", "c") - out += f"/* {s['name']}: the board, the kernel, then the threads and tasks of system.yaml. */\n" - out += "#include \n\n#include \n\n#include \"system.h\"\n\n" - out += "int main(void)\n{\n emb_board_init();\n emb_kernel_init();\n" - out += " emb_kernel_start(); /* the threads and tasks run from here: it does not return */\n}\n" - return out - - -def task_c(r, t): - n = t["name"] - out = _app_note("system.yaml", "c") - out += f"/* The {n} task's handlers (SPEC-020): each state's returns the state to be in next. */\n" - out += '#include "tasks.h"\n' - for st in t["states"]: - if t["model"] == "periodic": - out += f"\nemb_state_t {n}_on_{st}({n}_t *self)\n{{\n (void)self;\n return {_up(n)}_{_up(st)};\n}}\n" - else: - out += (f"\nemb_state_t {n}_on_{st}({n}_t *self, const {_event_type(t)} *ev)\n{{\n (void)self;\n" - f" (void)ev;\n return {_up(n)}_{_up(st)};\n}}\n") - for kind, names in (("enter", t["entry"]), ("exit", t["exit"])): - for st in names: - out += f"\nvoid {n}_{kind}_{st}({n}_t *self)\n{{\n (void)self;\n}}\n" - return out - - -def task_h(r, t): - n = t["name"] - out = _app_note("system.yaml", "c") - out += f"/* The {n} task's own types: its data" + (" and its event" if t["event"] else "") + ". */\n" - guard = f"TASK_{_up(n)}_H" - out += f"#ifndef {guard}\n#define {guard}\n\n#include \n" - if t["data"]: - out += f"\ntypedef struct {n}_data {{\n uint32_t count; /* the task's own state: change it */\n}} {t['data']};\n" - if t["event"]: - out += f"\ntypedef struct {n}_event {{\n uint32_t id; /* first: the runtime reads it */\n uint32_t value;\n}} {t['event']};\n" - return out + f"\n#endif /* {guard} */\n" + out = _head(r, "interrupt_handlers.c", "Interrupt Handlers", f"{s['name']}'s interrupt handlers.", + _app_desc("This file holds the application's interrupt handlers, which SYS_INT_Initialize() " + "connects (src/config//interrupts.c). Each runs in interrupt context: keep it " + "short, and hand the work to a task with emb_task_post().")) + out += _section("Included Files") + out += '#include "definitions.h"\n' + out += _section("Handler Routines") + for k, i in enumerate(s["interrupts"]): + out += ("\n" if k else "") + _see(f"void {i['handler']} ( void *arg )", "interrupts.h") + out += (f"void {i['handler']}(void *arg)\n{{\n (void)arg;\n\n" + f" /* TODO: Handle the {i['name']} interrupt. */\n}}\n") + return out + END_OF_FILE def app_cmakelists(r, rtos_cmake): s = r["system"] - out = _app_note("system.yaml", "hash") + out = "# SPDX-License-Identifier: Apache-2.0\n" if s["in_tree"] else "" + out += "# Generated by emb-hwgen from system.yaml; yours to edit: regeneration merges its changes (A126).\n" out += f"# {s['name']}'s build: the RTOS's package, its system description and its sources.\n" out += "cmake_minimum_required(VERSION 3.20)\n\n" out += f"set(EmbLinkRTOS_DIR \"{rtos_cmake}\" CACHE PATH \"The RTOS's cmake/ directory\")\n" @@ -339,7 +794,9 @@ def app_cmakelists(r, rtos_cmake): "endif()\n") out += "find_package(EmbLinkRTOS REQUIRED)\n\n" out += f"project({s['name']} LANGUAGES C)\n\nemb_kernel()\n" - sources = ["src/main.c"] + [f"src/tasks/{t['name']}.c" for t in s["tasks"]] + sources = ["src/main.c"] + [f"src/{t['name']}.c" for t in s["tasks"]] + if s["interrupts"]: + sources.append("src/interrupt_handlers.c") out += f"emb_add_executable({s['name']} {' '.join(sources)})\n" return out @@ -349,7 +806,8 @@ def app_files(r, rtos_cmake): s = r["system"] files = {"CMakeLists.txt": app_cmakelists(r, rtos_cmake), "src/main.c": main_c(r)} for t in s["tasks"]: - files[f"src/tasks/{t['name']}.c"] = task_c(r, t) - if t["data"] or t["event"]: - files[f"src/tasks/{t['name']}.h"] = task_h(r, t) + files[f"src/{t['name']}.c"] = task_c(r, t) + files[f"src/{t['name']}.h"] = task_h(r, t) + if s["interrupts"]: + files["src/interrupt_handlers.c"] = interrupt_handlers_c(r) return files diff --git a/hw/gen/emb_hwgen/generate.py b/hw/gen/emb_hwgen/generate.py index 5de2b2ff..2a00e630 100644 --- a/hw/gen/emb_hwgen/generate.py +++ b/hw/gen/emb_hwgen/generate.py @@ -35,7 +35,7 @@ def portable(w): def generate_system(system_path, root): """({board name: {file name: text}}, [warning]) for a system description (A125): on each of its boards, that board's outputs with the system's device settings, and the system's own, - written to generated// beside it. Every board's errors are reported together.""" + written to src/config// beside it (A130). Every board's errors are reported together.""" out, warnings, errors = {}, [], [] for ref in system.boards(system_path, root): try: diff --git a/hw/gen/emb_hwgen/model.py b/hw/gen/emb_hwgen/model.py index 5cdc693a..85c4c77a 100644 --- a/hw/gen/emb_hwgen/model.py +++ b/hw/gen/emb_hwgen/model.py @@ -297,6 +297,11 @@ def _soc_rules(self, soc): clk = p.get("clock") if clk is not None and clk["bus"] not in buses: self.err(soc, f"{where}.clock.bus", f"unresolved reference: no bus {clk['bus']!r}") + if "clocked_by" in p: # a PLL of a fixed rate (A129) + fixed = {s["name"] for s in d.get("clocks", {}).get("plls", []) if "output_hz" in s} + if p["clocked_by"] not in fixed: + self.err(soc, f"{where}.clocked_by", f"unresolved reference: no PLL {p['clocked_by']!r} with an " + f"output_hz (it has {', '.join(sorted(fixed)) or 'none'})") for irq in p.get("irqs", []): n = irq["number"] at = f"{where}.irqs.{irq['name']}" @@ -327,10 +332,11 @@ def _soc_rules(self, soc): if bank and parsed["number"] >= d["gpio"]["lines"]: self.err(soc, f"alternate_functions.{pin}", f"beyond the bank's {d['gpio']['lines']} lines") for af in sorted(afs): - ok = r"f([12][0-9]|3[01]|[0-9])" if bank else r"af(1[0-5]|[0-9])|fixed" + ok = r"f([12][0-9]|3[01]|[0-9])|analog" if bank else r"af(1[0-5]|[0-9])|fixed|analog" if not re.fullmatch(ok, af): self.err(soc, f"alternate_functions.{pin}.{af}", - "not a function select (f0 to f31)" if bank else "not an alternate function (af0 to af15, or fixed)") + "not a function select (f0 to f31, or analog)" if bank + else "not an alternate function (af0 to af15, fixed or analog)") fl = d.get("flash") if fl is not None: @@ -396,6 +402,10 @@ def claim(text, at, mode, signal=None, level=None): entry.update({"mode": "fixed", "signal": signal}) # taken over when the peripheral is on out.append(entry) return + if pin["af"] is None and offered.get("analog") == signal: + entry.update({"mode": "analog", "signal": signal}) # an ADC's input (A129) + out.append(entry) + return if pin["af"] is None: self.err(board, at, f"{pin['name']} needs its alternate function: {pin['name']}.{af_key(pin, '')}") return @@ -455,17 +465,28 @@ def _devices(self, board, soc, clk, pins=None): return devs, [d for m in table.models for d in m.docs] def _loopbacks(self, board, devs): - """simulation.loopbacks: a UART or SPI device wired by two ports or looped inside, or an - I2C device wired to a peer by two nets, SCL to SCL and SDA to SDA.""" + """simulation.loopbacks: a UART or SPI device wired by two ports or looped inside; an I2C + device wired to a peer by two nets, SCL to SCL and SDA to SDA; a PWM output wired to a + peer's capture input, their channels and the two ports (A129); an ADC's input wired high + and one low, their numbers and each one's net to a rail (A129).""" classes = {d["name"]: d["class"] for d in devs} for i, loop in enumerate(board.data.get("simulation", {}).get("loopbacks", [])): at = f"simulation.loopbacks[{i}]" cls = classes.get(loop["device"]) - if cls == "i2c": + if cls == "pwm": + if (classes.get(loop.get("peer")) != "pwm" or "ports" not in loop or "channels" not in loop + or "nets" in loop or "internal" in loop): + self.err(board, at, "a PWM loopback names its peer, the capture's PWM device, the two channels " + "and the two ports wired") + elif cls == "adc": + if "channels" not in loop or "nets" not in loop or "peer" in loop or "ports" in loop or "internal" in loop: + self.err(board, at, "an ADC loopback names its inputs, high then low, and two nets: each one's " + "port to a rail") + elif cls == "i2c": if classes.get(loop.get("peer")) != "i2c" or "nets" not in loop or "ports" in loop or "internal" in loop: self.err(board, at, "an I2C loopback names its peer, another I2C device, and two nets") elif cls not in ("uart", "spi"): - self.err(board, at, f"{loop['device']} is not a UART, SPI or I2C device of the board") + self.err(board, at, f"{loop['device']} is not a UART, SPI, I2C, PWM or ADC device of the board") elif ("ports" in loop) == ("internal" in loop) or "peer" in loop or "nets" in loop: self.err(board, at, "a loopback names two ports or internal: true, one of them") diff --git a/hw/gen/emb_hwgen/system.py b/hw/gen/emb_hwgen/system.py index 09785830..9940f1ec 100644 --- a/hw/gen/emb_hwgen/system.py +++ b/hw/gen/emb_hwgen/system.py @@ -114,7 +114,8 @@ def resolve(self, system_path): spi = self._spi_targets(r, devices) i2c = self._i2c_targets(devices) wdog = self._watchdog(devices) - self._names(threads, objects, spi, i2c, tasks) + irqs = self._interrupts(r, cfg) + self._names(threads, objects, spi, i2c, tasks, irqs) if self.errors: raise HwError(self.errors) r["system"] = { @@ -128,11 +129,13 @@ def resolve(self, system_path): "threads": threads, "tasks": tasks, "scaffold": s.get("scaffold", True), + "in_tree": load.inside(system_path, self.root), # its files carry the tree's notice (A130) "objects": objects, "devices": self._settings(r), "spi_targets": spi, "i2c_targets": i2c, "watchdog": wdog, + "interrupts": irqs, "config": {k: cfg[k] for k in sorted(cfg) if k in _CONFIG_SHOWN}, } stamps = [system_path] + [self.dir / c for c in s.get("conf", [])] @@ -317,20 +320,71 @@ def _tasks(self, cfg): for key in ("queue", "events", "timeout", "event"): if key in t: self.err(f"{at}.{key}", f"a periodic task takes no {key}: it runs by its period, not by events") + for key in ("entry", "exit"): # Harmony's _Tasks(): its switch moves between states (A130) + if key in t: + self.err(f"{at}.{key}", f"a periodic task takes no {key} list: its {t['name'].upper()}_Tasks() " + "switch makes its own moves") elif "period" in t: self.err(f"{at}.period", "an event task takes no period: model: periodic for one") out.append({"name": t["name"], "model": model, "priority": t["priority"], "stack": t["stack"], "queue": t.get("queue", 8), "events": events, "states": states, "initial": t["initial"], "entry": t.get("entry", []), "exit": t.get("exit", []), "timeouts": timeouts, "period_ms": duration_ms(t["period"]) if "period" in t else 0, - "data": t.get("data"), "event": t.get("event"), "doc": t.get("doc", "")}) + "event": t.get("event"), "doc": t.get("doc", "")}) + return out + + def _interrupts(self, r, cfg): + """The application's own interrupt handlers (A130): each on a line the SoC has and no device's + driver connects, at a level the port implements.""" + ints = r["soc"]["interrupts"] + by_name = {(p["name"], i["name"]): i["number"] for p in r["soc"]["peripherals"] for i in p.get("irqs", [])} + # the lines the board's devices connect: their fields' peripheral.irqs., and their taken peripherals' + taken = {f["value"]: d["name"] for d in r["devices"] for f in d["fields"] + if ".irqs." in str(f["expr"]) and isinstance(f["value"], int)} + out, used = [], {} + for i, e in enumerate(self.model.data.get("interrupts", [])): + at = f"interrupts.{e['name']}" + irq = e["irq"] + if isinstance(irq, dict): # by board: a system on several SoCs + board = r["board"]["name"] + if board not in irq: + self.err(f"{at}.irq", f"no line for {board}: give one by its name ({board}: )") + continue + irq = irq[board] + if isinstance(irq, str): + periph, _, line = irq.partition(".") + number = by_name.get((periph, line)) + if number is None: + self.err(f"{at}.irq", f"unresolved reference: the SoC has no interrupt {irq!r} (.)") + continue + else: + number = irq + if number >= ints["count"]: + self.err(f"{at}.irq", f"line {number} is beyond the SoC's {ints['count']} interrupt lines") + continue + if number in taken: + self.err(f"{at}.irq", f"line {number} is the device {taken[number]}'s: its driver connects it") + continue + if number in used: + self.err(f"{at}.irq", f"line {number} is already the interrupt {used[number]}'s") + continue + used[number] = e["name"] + level_max = cfg.get("CONFIG_EMB_IRQ_LEVEL_MAX") + if "level" in e and isinstance(level_max, int) and e["level"] > level_max: + self.err(f"{at}.level", f"level {e['level']} is beyond the port's levels, 0 to {level_max} " + "(EMB_IRQ_LEVEL_MAX)") + if cfg.get("CONFIG_EMB_IRQ_DYNAMIC") is not True: + self.err(at, "an application's interrupt needs CONFIG_EMB_IRQ_DYNAMIC (emb_irq_connect()), which the " + "configuration leaves out") + out.append({"name": e["name"], "irq": number, "source": irq if isinstance(irq, str) else None, + "handler": e["handler"], "level": e.get("level"), "doc": e.get("doc", "")}) return out - def _names(self, threads, objects, spi, i2c, tasks=()): + def _names(self, threads, objects, spi, i2c, tasks=(), irqs=()): """Every name becomes a C symbol: one of each in the file.""" seen = {} for section, items in (("threads", threads), ("objects", objects), ("spi_targets", spi), ("i2c_targets", i2c), - ("tasks", tasks)): + ("tasks", tasks), ("interrupts", irqs)): for item in items: if item["name"] in seen: self.err(f"{section}.{item['name']}", f"{item['name']!r} is already the name of {seen[item['name']]}") diff --git a/hw/gen/test_hwgen.py b/hw/gen/test_hwgen.py index 6f38fb33..9233cf0f 100644 --- a/hw/gen/test_hwgen.py +++ b/hw/gen/test_hwgen.py @@ -462,6 +462,29 @@ def test_pin_table(self): self.assertIn("set(EMB_BOARD_UF2_FAMILY 0xE48BFF59)", files["build/board.cmake"]) self.assertIn("0x10210142u, /* item IMAGE_TYPE (0x42), one word: 0x1021 */", files["src/boot_block.c"]) + def test_counters_on_both_boards(self): + """A129: the counter class's devices, a peripheral's index (timer1's 1, for its tick + generator), a field's default marked, and the board's counters for its tests.""" + pico, _ = generate.generate(ROOT / PICO, ROOT) + c = pico["src/soc_devices.c"] + self.assertIn(" .index = 1u, /* peripheral.index */", c) + self.assertIn(" .rate_hz = 1000000u, /* device.rate_hz, its default */", c) + self.assertIn(" .irq3 = 7u, /* peripheral.irqs.alarm3 */", c) + self.assertIn("#define EMB_SOC_COUNTER_DEVICES &emb_dev_timer1", pico["include/soc_devices.h"]) + nucleo, _ = generate.generate(ROOT / BOARD, ROOT) + h = nucleo["include/soc_devices.h"] + self.assertIn("#define EMB_SOC_COUNTER_DEVICE (&emb_dev_tim5)", h) + self.assertIn("#define EMB_SOC_COUNTER_DEVICES &emb_dev_tim5, &emb_dev_tim9", h) + self.assertIn("#define EMB_SOC_COUNTER_COUNT 2u", h) + c = nucleo["src/soc_devices.c"] + self.assertIn(" .clock_hz = 180000000u, /* peripheral.timer_clock_hz */", c) # TIM9 on APB2 + self.assertIn(" .channels = 2u, /* peripheral.timer_channels */", c) + self.assertIn(" .channels = 4u, /* peripheral.timer_channels, its default */", c) # TIM5 + cmake = nucleo["build/board.cmake"] # the PWM loop and the ADC's rails under EmbSIM (A129) + self.assertIn('set(EMB_BOARD_EMBSIM_PWM_LOOP "tim3:0,tim4:0" "D12,D10")', cmake) + self.assertIn('set(EMB_BOARD_EMBSIM_ADC_LOOP "adc1:4,8" "A2,3V3" "A3,GND")', cmake) + self.assertIn(" .trigger_select = 6u, /* takes.trigger.adc_trigger */", c) + def test_line_beyond_the_bank(self): f = f"{PICO}/board.yaml" self.root.edit(f, "tx: GPIO0.f2", "tx: GPIO30.f2") @@ -470,7 +493,7 @@ def test_line_beyond_the_bank(self): def test_wrong_function_select(self): f = f"{PICO}/board.yaml" self.root.edit(f, "tx: GPIO0.f2", "tx: GPIO0.f11") - self.expect(PICO, f, "tx: GPIO0.f11", "pins.uart0.tx", r"GPIO0 f11 is not uart0_tx \(GPIO0 offers f2 uart0_tx\)") + self.expect(PICO, f, "tx: GPIO0.f11", "pins.uart0.tx", r"GPIO0 f11 is not uart0_tx \(GPIO0 offers f2 uart0_tx, f4 pwm0_a\)") def test_function_select_needed(self): f = f"{PICO}/board.yaml" @@ -487,13 +510,28 @@ def test_pin_styles_do_not_mix(self): def test_bank_soc_rules(self): die = "soc/rpi/rp2350/rp2350.yaml" - self.root.edit(die, " GPIO29: { f2: uart0_rx }", " GPIO31: { f2: uart0_rx }") - self.root.edit(die, " GPIO28: { f2: uart0_tx }", " GPIO28: { af2: uart0_tx }") + self.root.edit(die, " GPIO29: { f2: uart0_rx,", " GPIO31: { f2: uart0_rx,") + self.root.edit(die, " GPIO28: { f2: uart0_tx,", " GPIO28: { af2: uart0_tx,") with self.assertRaises(HwError) as cm: self.root.resolve(PICO) text = "\n".join(cm.exception.errors) self.assertIn("alternate_functions.GPIO31: beyond the bank's 30 lines", text) - self.assertIn("alternate_functions.GPIO28.af2: not a function select (f0 to f31)", text) + self.assertIn("alternate_functions.GPIO28.af2: not a function select (f0 to f31, or analog)", text) + + def test_analog_pin(self): + """A129: an ADC's input is claimed by its signal alone (GPIO26, adc_in0), the pad's input + and digital function off, no pull.""" + f = f"{PICO}/board.yaml" # the board's own: adc: { in0: GPIO26, in1: GPIO27 } + files, _ = generate.generate(self.root.dir / PICO, self.root.dir) + self.assertIn("{26u, 31u, 0u, EMB_RP2350_PULL_NONE, EMB_RP2350_OUT_NONE},", files["src/board_pins.c"]) + self.root.edit(f, "in0: GPIO26", "in0: GPIO26.f4") + self.expect(PICO, f, "in0: GPIO26.f4", "pins.adc.in0", r"GPIO26 f4 is not adc_in0") + + def test_clocked_by_names_a_fixed_pll(self): + die = "soc/rpi/rp2350/rp2350.yaml" + self.root.edit(die, "clocked_by: pll_usb", "clocked_by: pll_sys") + self.expect(PICO, die, "clocked_by: pll_sys", "peripherals.adc.clocked_by", + r"no PLL 'pll_sys' with an output_hz \(it has pll_usb\)") def test_ports_and_lines_exclude_each_other(self): part = "soc/rpi/rp2350/rp2350a.yaml" @@ -700,6 +738,87 @@ def test_outputs(self): def test_deterministic(self): self.assertEqual(self.files(), self.files()) + TIM_BINDINGS = ( + " st,stm32-tim:counter: { class: counter, level: kernel, sources: [drivers/st/tim_counter.c], header: tim.h,\n" + " api: tim_counter_api, config: tim_config_t,\n" + " fields: { base: peripheral.base, clock_hz: peripheral.timer_clock_hz,\n" + " bits: peripheral.counter_bits } }\n" + " st,stm32-tim:pwm: { class: pwm, level: kernel, sources: [drivers/st/tim_pwm.c], header: tim.h,\n" + " api: tim_pwm_api, config: tim_config_t, fields: { base: peripheral.base } }\n" + " acme,part:") + + def test_class_picks_the_binding(self): + """A129: a timer is a counter or PWM, a binding for each, keyed compatible:class; a board + device names its class, and only its class's driver is built. A timer on APB1 runs at + twice the divided bus: 90 MHz beside APB1's 45.""" + self.root.edit("drivers/bindings.yaml", " acme,part:", self.TIM_BINDINGS) + self.root.edit(f"{BOARD}/board.yaml", "{ name: rcc }", + "{ name: rcc }\n - { name: tim5, class: counter }\n - { name: tim3, class: pwm }") + devs = {d["name"]: d for d in self.root.resolve()["devices"]} + self.assertEqual({f["field"]: f["c"] for f in devs["tim5"]["fields"]}, + {"base": "0x40000C00u", "clock_hz": "90000000u", "bits": "32u"}) + self.assertEqual(devs["tim5"]["deps"], ["rcc"]) # its clock gate + files = self.files() + self.assertIn(" .class_id = EMB_DRV_CLASS_COUNTER,\n", files["src/soc_devices.c"]) + self.assertIn(" .class_id = EMB_DRV_CLASS_PWM,\n", files["src/soc_devices.c"]) + cmake = files["build/board.cmake"] + self.assertIn("drivers/st/tim_counter.c", cmake) + self.assertIn("drivers/st/tim_pwm.c", cmake) + self.assertNotIn("unused_tim.c", cmake) + + def test_class_needed_where_several_bind(self): + self.root.edit("drivers/bindings.yaml", " acme,part:", self.TIM_BINDINGS) + self.root.edit(f"{BOARD}/board.yaml", "{ name: rcc }", "{ name: rcc }\n - { name: tim5 }") + self.expect(r"st,stm32-tim has drivers for clock and counter and pwm: say which with class:", + needle="name: tim5", path="devices.tim5") + + def test_class_with_no_binding(self): + self.root.edit("drivers/bindings.yaml", " acme,part:", self.TIM_BINDINGS) + self.root.edit(f"{BOARD}/board.yaml", "{ name: rcc }", "{ name: rcc }\n - { name: tim5, class: adc }") + self.expect(r"no adc driver binds st,stm32-tim: it has clock, counter, pwm", needle="name: tim5", + path="devices.tim5") + + def test_binding_key_names_its_class(self): + self.root.edit("drivers/bindings.yaml", " acme,part:", + self.TIM_BINDINGS.replace("st,stm32-tim:pwm: { class: pwm", "st,stm32-tim:pwm: { class: adc")) + self.expect(r"the key names the class pwm, the binding adc", file="drivers/bindings.yaml", + needle="st,stm32-tim:pwm:", path="bindings.st,stm32-tim:pwm") + + ADC_BINDING = ( + " st,stm32f4-adc: { class: adc, level: kernel, sources: [drivers/st/adc.c], header: adc.h, api: adc_api,\n" + " config: adc_config_t, takes: { trigger: \"st,stm32-tim\" },\n" + " fields: { base: peripheral.base, trigger: takes.trigger.base,\n" + " trigger_hz: takes.trigger.timer_clock_hz, trigger_bit: takes.trigger.clock.bit,\n" + " vref_mv: { from: device.vref_mv, default: 3300 } } }\n" + " acme,part:") + + def test_taken_peripheral_and_field_default(self): + """A129: an ADC takes its pacing timer, named by the device (trigger: tim2), and its + fields read it; a field with a default takes it where the device gives none.""" + self.root.edit("drivers/bindings.yaml", " acme,part:", self.ADC_BINDING) + self.root.edit(f"{BOARD}/board.yaml", "{ name: rcc }", "{ name: rcc }\n - { name: adc1, trigger: tim2 }") + devs = {d["name"]: d for d in self.root.resolve()["devices"]} + self.assertEqual({f["field"]: f["c"] for f in devs["adc1"]["fields"]}, + {"base": "0x40012000u", "trigger": "0x40000000u", "trigger_hz": "90000000u", + "trigger_bit": "0u", "vref_mv": "3300u"}) + self.assertEqual(devs["adc1"]["deps"], ["rcc"]) + self.assertEqual(devs["adc1"]["options"], ["vref_mv"]) # what a system may set + self.root.edit(f"{BOARD}/board.yaml", "trigger: tim2 }", "trigger: tim2, vref_mv: 3000 }") + devs = {d["name"]: d for d in self.root.resolve()["devices"]} + self.assertIn({"field": "vref_mv", "expr": "device.vref_mv", "value": 3000, "c": "3000u"}, devs["adc1"]["fields"]) + + def test_taken_peripheral_checked(self): + self.root.edit("drivers/bindings.yaml", " acme,part:", self.ADC_BINDING) + f = f"{BOARD}/board.yaml" + self.root.edit(f, "{ name: rcc }", "{ name: rcc }\n - { name: adc1 }") + self.expect(r"the st,stm32f4-adc binding takes a st,stm32-tim peripheral as trigger: name one", + needle="name: adc1", path="devices.adc1") + self.root.edit(f, "{ name: adc1 }", "{ name: adc1, trigger: usart2 }") + self.expect(r"usart2 is a st,stm32-usart, not the st,stm32-tim the st,stm32f4-adc binding takes", + needle="name: adc1", path="devices.adc1.trigger") + self.root.edit(f, "trigger: usart2 }", "trigger: tim2 }\n - { name: tim2 }") + self.expect(r"tim2 is already the device adc1 \(its trigger\)", needle="name: tim2", path="devices.tim2") + def test_buffers(self): """A binding's buffers: sized by a device property or the binding's default, emitted as RAM beside the configuration, which names them and their sizes.""" @@ -722,7 +841,18 @@ def test_loopbacks(self): self.root.edit(f"{BOARD}/board.yaml", "{ device: console, ports: [A0, A1] }", "{ device: console, internal: true }") self.assertIn("set(EMB_BOARD_UART_LOOP_INTERNAL console)", self.files()["build/board.cmake"]) self.root.edit(f"{BOARD}/board.yaml", "{ device: console, internal: true }", "{ device: rcc, internal: true }") - self.expect(r"rcc is not a UART, SPI or I2C device", needle="device: rcc", path="simulation.loopbacks[0]") + self.expect(r"rcc is not a UART, SPI, I2C, PWM or ADC device", needle="device: rcc", path="simulation.loopbacks[0]") + + def test_pwm_and_adc_loopbacks_checked(self): + """A129: a PWM loop names its peer, its channels and its ports; an ADC's, its inputs and + their nets to the rails.""" + Path(self.root.dir / "drivers" / "bindings.yaml").write_text( + (ROOT / "drivers" / "bindings.yaml").read_text(encoding="utf-8"), encoding="utf-8") + f = f"{BOARD}/board.yaml" + self.root.edit(f, "{ name: rcc }", "{ name: rcc }\n - { name: tim3, class: pwm }\n - { name: tim4, class: pwm }") + self.root.edit(f, "simulation:\n", "simulation:\n loopbacks: [ { device: tim3, peer: tim4, ports: [D12, D10] } ]\n") + self.expect(r"a PWM loopback names its peer, the capture's PWM device, the two channels and the two ports", + needle="device: tim3, peer", path="simulation.loopbacks[0]") def test_loopback_names_one_way(self): self.root.edit(f"{BOARD}/board.yaml", "simulation:\n", "simulation:\n loopbacks: [ { device: console } ]\n") @@ -962,7 +1092,7 @@ def test_check_stale_with_its_diff(self): def test_a_system_validated_and_generated(self): """--system takes --format json too (A125): an application's description, its warnings, the - files written beside it and under generated//.""" + files written beside it and under src/config// (A130).""" doc = self.run_json("validate", "--system", str(ROOT / "examples/tasks/system.yaml")) self.assertEqual((doc["status"], doc["command"]), ("ok", "validate")) d = Path(tempfile.mkdtemp(prefix="hwgen-diag-sys-")) @@ -972,7 +1102,7 @@ def test_a_system_validated_and_generated(self): doc = self.run_json("generate", "--system", str(system)) self.assertEqual(doc["status"], "ok") names = {Path(f).name for f in doc["files"]} - self.assertTrue({"system.h", "main.c"} <= names, names) + self.assertTrue({"definitions.h", "initialization.c", "main.c", "door.c"} <= names, names) self.assertEqual(self.run_json("generate", "--system", str(system))["files"], []) # unchanged def test_generate_reports_a_merge_conflict(self): @@ -1266,6 +1396,35 @@ def test_above_the_bus_limit_refused(self): _, problems = self.solve(200_000_000, {"m": 1, "n": 100, "p": 6}) self.assertIn("clocks.cpu_hz", [w for w, _ in problems]) + def with_usb(self, rate): + usb = dict(self.SOC["clocks"]["plls"][0], name="pll_usb", output_hz=rate) + return {"clocks": dict(self.SOC["clocks"], plls=[usb] + self.SOC["clocks"]["plls"])} + + def test_fixed_pll_solved_from_the_crystal(self): + """A129: a PLL with an output_hz (PLL_USB's 48 MHz) is solved from the board's source, + whatever the CPU runs at; the CPU's PLL is the one without, wherever it is listed.""" + from emb_hwgen import clock + board = {"oscillators": {"xosc": {"hz": 12_000_000, "source": "external_crystal"}}, + "clocks": {"cpu_hz": 150_000_000, "source": "xosc"}} + problems = [] + c = clock.solve(self.with_usb(48_000_000), board, lambda w, m: problems.append((w, m))) + self.assertEqual(problems, []) + usb = c["fixed_plls"]["pll_usb"] + self.assertEqual(usb["hz"], 48_000_000) + self.assertEqual(usb["vco_hz"] // (usb["postdiv1"] * usb["postdiv2"]), 48_000_000) + self.assertEqual(c["pll"]["name"], "pll_sys") + board["clocks"]["cpu_hz"] = 12_000_000 # the CPU on the crystal: PLL_USB still solved + c = clock.solve(self.with_usb(48_000_000), board, lambda w, m: problems.append((w, m))) + self.assertEqual((problems, c["pll"], c["fixed_plls"]["pll_usb"]["hz"]), ([], None, 48_000_000)) + + def test_fixed_pll_out_of_reach_refused(self): + from emb_hwgen import clock + board = {"oscillators": {"xosc": {"hz": 12_000_000, "source": "external_crystal"}}, + "clocks": {"cpu_hz": 150_000_000, "source": "xosc"}} + problems = [] + clock.solve(self.with_usb(1_000_000), board, lambda w, m: problems.append((w, m))) # under the VCO's floor + self.assertIn(("clocks.source", "no pll_usb setting reaches exactly 1 MHz from 12 MHz"), problems) + class Loader(unittest.TestCase): def test_units(self): diff --git a/hw/gen/test_system.py b/hw/gen/test_system.py index 7443506b..0e56da48 100644 --- a/hw/gen/test_system.py +++ b/hw/gen/test_system.py @@ -135,9 +135,12 @@ def test_each_board_resolved_and_generated(self): for name, files in per_board.items(): if name == "_app": continue - self.assertIn("EMB_THREAD_DEFINE(blink_thread, blink, NULL, 3u, 512u, 0u);", files["src/system.c"]) - self.assertIn("EMB_SEM_DEFINE(ticks, 0u, 10u);", files["src/system.c"]) + c = files["initialization.c"] + self.assertIn("EMB_THREAD_DEFINE(blink_thread, blink, NULL, BLINK_THREAD_PRIORITY, BLINK_THREAD_STACK_SIZE, 0u);", c) + self.assertIn("EMB_SEM_DEFINE(ticks, 0u, 10u);", c) + self.assertIn("#define BLINK_THREAD_STACK_SIZE 512u", files["configuration.h"]) self.assertIn(f'"board": "{name}"', files["docs/system.json"]) + self.assertIn(f'#define BOARD_NAME "{name}"', files["definitions.h"]) def test_an_error_names_its_board(self): self.text = MINIMAL.replace(" max: 10", " max: 10") + "devices:\n usart2: { baud: 57600 }\n" @@ -156,25 +159,46 @@ def test_board_and_boards_both(self): class Outputs(Base): - def test_system_c_and_h(self): + """A130: the configuration folder in MPLAB Harmony's form.""" + + def test_definitions_configuration_and_initialization(self): self.text = self.text.replace("conf: [app.conf]", "conf: [app.conf]\nincludes: [app.h]") path = self.dir / "system.yaml" path.write_text(self.text, encoding="utf-8") - files = generate.generate_system(path, ROOT)[0]["nucleo_f446re"] - c, h = files["src/system.c"], files["include/system.h"] - self.assertIn("EMB_THREAD_DEFINE(telemetry_thread, telemetry, NULL, 2u, 1024u, EMB_THREAD_NO_AUTOSTART);", c) + per_board = generate.generate_system(path, ROOT)[0] + files = per_board["nucleo_f446re"] + self.assertEqual(sorted(n for n in files if "/" not in n), + ["configuration.h", "definitions.h", "initialization.c", "tasks.c"]) + self.assertTrue({"peripheral/hw_config.h", "peripheral/soc_devices.c", "peripheral/board_pins.c", + "build/board.conf", "build/board.cmake", "linker/regions.ld"} <= set(files)) + c, h, cfg = files["initialization.c"], files["definitions.h"], files["configuration.h"] + self.assertIn("EMB_THREAD_DEFINE(telemetry_thread, telemetry, NULL, TELEMETRY_THREAD_PRIORITY,", c) + self.assertIn("#define TELEMETRY_THREAD_STACK_SIZE 1024u", cfg) + self.assertIn("void SYS_Initialize(void *data)\n{\n (void)data;\n", c) + self.assertIn("emb_board_init();", c) + self.assertIn("emb_kernel_start();", files["tasks.c"]) + self.assertIn("void SYS_Initialize(void *data);", h) + self.assertIn("void SYS_Tasks(void);", h) + self.assertIn('#define DEVICE_NAME "STM32F446RE"', h) + self.assertIn("#define CPU_CLOCK_FREQUENCY 180000000u", h) + self.assertIn(" File Name:\n definitions.h\n", h) # Harmony's banner + self.assertIn("// Section: System Functions", h) + self.assertNotIn("SPDX", h) # an application outside the tree is its author's + self.assertIn("#define DRV_USART2_BAUD", cfg) + self.assertIn("build/board.conf", files["build/board.cmake"]) + self.assertIn('set(EMB_BOARD_SRC_DIR "${EMB_BOARD_GENERATED_DIR}/peripheral")', files["build/board.cmake"]) self.assertIn("EMB_MSGQ_DEFINE(samples, sizeof(sample_t), 8u, 0u);", c) self.assertIn("EMB_MUTEX_DEFINE(bus_lock, EMB_MUTEX_CEILING, 6u, 0u);", c) - self.assertIn("const emb_drv_spi_target_t flash_chip = {8000000u, EMB_DRV_SPI_MODE_3, 8u, 0u, 0u, EMB_SOC_SPI2_CS0};", c) - self.assertIn("const emb_drv_i2c_target_t env = {EMB_DRV_I2C_FAST, 0x76u, {0u, 0u}};", c) + self.assertIn("const emb_drv_spi_target_t flash_chip = {\n .hz = 8000000u,\n .mode = EMB_DRV_SPI_MODE_3,\n .bits = 8u,\n .cs = EMB_SOC_SPI2_CS0,\n};", c) + self.assertIn("const emb_drv_i2c_target_t env = {\n .hz = EMB_DRV_I2C_FAST,\n .address = 0x76u,\n};", c) self.assertIn("void control(void *arg);", h) self.assertIn("extern emb_mutex_t bus_lock;", h) self.assertIn('#include "app.h"', h) - self.assertIn("#define EMB_SYSTEM_WATCHDOG_TIMEOUT_MS 500u", h) + self.assertIn("#define SYS_WATCHDOG_TIMEOUT_MS 500u", cfg) self.assertIn("generate --system /", c) # no path of this machine (HW-013) self.assertIn("| usart2 | baud | 57600 | 115200 |", files["docs/system.md"]) # the board's outputs carry the system's settings - self.assertIn("57600", files["include/hw_config.h"]) + self.assertIn("57600", files["peripheral/hw_config.h"]) class Regenerate(Base): @@ -198,9 +222,10 @@ def test_an_edit_survives_a_change_of_the_description(self): path = self.dir / "system.yaml" path.write_text(self.text, encoding="utf-8") self.assertEqual(self.cli("generate", "--system", str(path))[0], 0) - c = self.dir / "generated/nucleo_f446re/src/system.c" - self.assertTrue((self.dir / "generated/.base/nucleo_f446re/src/system.c").is_file()) - c.write_text(c.read_text(encoding="utf-8").replace('#include "system.h"\n', '#include "system.h"\n/* my note */\n'), + c = self.dir / "src/config/nucleo_f446re/initialization.c" + self.assertTrue((self.dir / "src/config/.base/nucleo_f446re/initialization.c").is_file()) + c.write_text(c.read_text(encoding="utf-8").replace('#include "definitions.h"\n', + '#include "definitions.h"\n/* my note */\n'), encoding="utf-8") # the description changes: one more object path.write_text(self.text + " - { name: done, type: sem, initial: 0, max: 1 }\n", encoding="utf-8") @@ -216,8 +241,8 @@ def test_a_conflict_is_reported_and_refused(self): path = self.dir / "system.yaml" path.write_text(self.text, encoding="utf-8") self.cli("generate", "--system", str(path)) - c = self.dir / "generated/nucleo_f446re/src/system.c" - c.write_text(c.read_text(encoding="utf-8").replace("3u, 512u", "3u, 600u"), encoding="utf-8") + c = self.dir / "src/config/nucleo_f446re/configuration.h" + c.write_text(c.read_text(encoding="utf-8").replace("STACK_SIZE 512u", "STACK_SIZE 600u"), encoding="utf-8") path.write_text(self.text.replace("stack: 512", "stack: 768"), encoding="utf-8") code, out = self.cli("generate", "--system", str(path)) self.assertEqual(code, 1) @@ -241,7 +266,6 @@ def test_a_conflict_is_reported_and_refused(self): entry: [open] exit: [open] timeout: { open: 2s } - data: door_data_t - name: blink model: periodic period: 500ms @@ -266,30 +290,54 @@ def generate(self): return generate.generate_system(path, ROOT)[0] def test_tables_and_threads(self): - files = self.generate() - h, c = files["nucleo_f446re"]["include/tasks.h"], files["nucleo_f446re"]["src/tasks.c"] - self.assertIn("#define DOOR_OPEN ((emb_state_t)1u)", h) - self.assertIn("#define DOOR_EV_CLOSE (EMB_EV_USER + 1u)", h) - self.assertIn("door_data_t data;", h) - self.assertIn("emb_state_t door_on_open(door_t *self, const emb_task_event_t *ev);", h) - self.assertIn("emb_state_t blink_on_lit(blink_t *self);", h) - self.assertIn("void door_exit_open(door_t *self);", h) - self.assertIn('#include "tasks/door.h"', h) - self.assertIn("static const uint32_t door_timeouts[2] = {0u, 2000u};", c) - self.assertIn("EMB_THREAD_DEFINE(blink_thread, blink_main, NULL, 2u, 512u, 0u);", c) - self.assertIn("next = door_on_open(&door, &door_event);", c) - self.assertIn('#include "tasks.h"', files["nucleo_f446re"]["include/system.h"]) + """A130: each task's table in tasks.c, its settings in configuration.h, its handle in + definitions.h, its _Initialize() in SYS_Initialize().""" + files = self.generate()["nucleo_f446re"] + c, h, cfg = files["tasks.c"], files["definitions.h"], files["configuration.h"] + self.assertIn('_Static_assert(DOOR_STATE_OPEN == 1, "door.h: DOOR_STATES are system.yaml\'s states, in order");', c) + self.assertIn("_Static_assert(DOOR_EVENT_CLOSE == EMB_EV_USER + 1u,", c) + self.assertIn("static const uint32_t door_timeouts[2] = {0u, DOOR_OPEN_TIMEOUT_MS};", c) + self.assertIn("next = (emb_state_t)DOOR_OnOpen(&door_event);", c) + self.assertIn("DOOR_EnterOpen();", c) + self.assertIn(" case DOOR_STATE_OPEN:\n doorData.state = DOOR_STATE_OPEN;\n DOOR_EnterOpen();\n", c) + self.assertIn(" if (state == DOOR_STATE_OPEN) {\n DOOR_ExitOpen();\n }\n", c) # a lone case + self.assertIn(" BLINK_Tasks();\n return (emb_state_t)blinkData.state;", c) # Harmony's periodic task + self.assertIn(" .period_ms = BLINK_PERIOD_MS,\n", c) + self.assertIn("EMB_THREAD_DEFINE(blink_thread, blink_main, NULL, BLINK_PRIORITY, BLINK_STACK_SIZE, 0u);", c) + self.assertIn("#define DOOR_OPEN_TIMEOUT_MS 2000u", cfg) + self.assertIn("#define BLINK_PERIOD_MS 500u", cfg) + self.assertIn('#include "door.h"', h) + self.assertIn("#define DOOR_TASK (&door_task)", h) + self.assertIn(" DOOR_Initialize();\n BLINK_Initialize();\n", files["initialization.c"]) def test_the_application_files(self): + """A130: main.c, and each task's file and header in Harmony's application template.""" app = self.generate()["_app"] - self.assertEqual(sorted(app), ["CMakeLists.txt", "src/main.c", "src/tasks/blink.c", "src/tasks/door.c", - "src/tasks/door.h"]) - self.assertIn("emb_add_executable(tasks_demo src/main.c src/tasks/door.c src/tasks/blink.c)", app["CMakeLists.txt"]) + self.assertEqual(sorted(app), ["CMakeLists.txt", "src/blink.c", "src/blink.h", "src/door.c", "src/door.h", + "src/main.c"]) + self.assertIn("emb_add_executable(tasks_demo src/main.c src/door.c src/blink.c)", app["CMakeLists.txt"]) self.assertIn('set(EMB_SYSTEM "${CMAKE_CURRENT_LIST_DIR}/system.yaml"', app["CMakeLists.txt"]) self.assertIn("$ENV{EMBLINKRTOS}/cmake", app["CMakeLists.txt"]) # outside the tree: no machine path - self.assertIn("emb_kernel_start();", app["src/main.c"]) - self.assertIn("return DOOR_OPEN;", app["src/tasks/door.c"]) - self.assertIn("door_data_t;", app["src/tasks/door.h"]) + self.assertIn(" SYS_Initialize(NULL);\n", app["src/main.c"]) + self.assertIn(" SYS_Tasks();\n", app["src/main.c"]) + self.assertTrue(app["src/main.c"].startswith("/" + "*" * 79 + "\n Main Source File\n")) + door_h, door_c, blink_c = app["src/door.h"], app["src/door.c"], app["src/blink.c"] + self.assertIn(" DOOR_STATE_CLOSED = 0,\n DOOR_STATE_OPEN,\n} DOOR_STATES;", door_h) + self.assertIn(" DOOR_EVENT_OPEN = EMB_EV_USER,\n DOOR_EVENT_CLOSE,\n} DOOR_EVENTS;", door_h) + self.assertIn("} DOOR_DATA;\n\nextern DOOR_DATA doorData;", door_h) + self.assertIn("DOOR_STATES DOOR_OnOpen(const emb_task_event_t *event);", door_h) + self.assertIn("void DOOR_ExitOpen(void);", door_h) + self.assertIn(" Precondition:", door_h) # Harmony's function blocks + self.assertIn("DOOR_DATA doorData;", door_c) + self.assertIn(" return DOOR_STATE_OPEN;\n}", door_c) + self.assertIn("// Section: Application Local Functions", door_c) + self.assertIn(" switch (blinkData.state) {\n /* The task's initial state. */\n case BLINK_STATE_DARK: {", + blink_c) + self.assertIn("void BLINK_Tasks(void);", app["src/blink.h"]) + + def test_periodic_takes_no_entry(self): + self.expect_task((" initial: dark", " initial: dark\n entry: [lit]"), "entry: [lit]", + "tasks.blink.entry", r"a periodic task takes no entry list: its BLINK_Tasks\(\) switch") def test_no_scaffold(self): self.text = TASKS.replace("board: st/nucleo_f446re", "board: st/nucleo_f446re\nscaffold: false") @@ -323,6 +371,74 @@ def test_yaml_booleans_are_explained(self): "states: [off, on]", "tasks.blink.states[0]", "quote the name") +class Interrupts(Base): + """A130: the application's own interrupt handlers, each on a line the SoC has and no device's + driver connects, connected by SYS_INT_Initialize().""" + + def setUp(self): + super().setUp() + self.text = MINIMAL + ("interrupts:\n - { name: wake, irq: { nucleo_f446re: 61, nucleo_f446ze: 62 }, " + "handler: WAKE_InterruptHandler, level: 1 }\n") + + def generate(self): + path = self.dir / "system.yaml" + path.write_text(self.text, encoding="utf-8") + return generate.generate_system(path, ROOT)[0] + + def test_a_line_by_board_connected(self): + out = self.generate() + re_, ze = out["nucleo_f446re"], out["nucleo_f446ze"] + self.assertIn("#define WAKE_IRQ 61u", re_["configuration.h"]) + self.assertIn("#define WAKE_IRQ 62u", ze["configuration.h"]) + self.assertIn("#define WAKE_IRQ_LEVEL 1u", re_["configuration.h"]) + self.assertIn("void WAKE_InterruptHandler(void *arg);", re_["interrupts.h"]) + c = re_["interrupts.c"] + self.assertIn(" (void)emb_irq_connect(WAKE_IRQ, WAKE_InterruptHandler, NULL);\n" + " (void)emb_irq_set_level(WAKE_IRQ, WAKE_IRQ_LEVEL);\n (void)emb_irq_enable(WAKE_IRQ);\n", c) + self.assertRegex(c, r" \* 38 usart2, its driver \(peripheral\.irqs\.global\)") # the devices' lines too + self.assertRegex(c, r" \* 61 wake, the application's WAKE_InterruptHandler\(\)") + self.assertIn(" SYS_INT_Initialize();\n", re_["initialization.c"]) + self.assertIn('#include "interrupts.h"', re_["definitions.h"]) + app = out["_app"] + self.assertIn("void WAKE_InterruptHandler(void *arg)\n{", app["src/interrupt_handlers.c"]) + self.assertIn("src/interrupt_handlers.c)", app["CMakeLists.txt"]) + self.assertIn("| `wake` | 61 | `WAKE_InterruptHandler` | 1 |", re_["docs/system.md"]) + + def test_a_peripherals_line(self): + """.: here a line no board device takes, the RTC's on the F446ZE.""" + self.edit("irq: { nucleo_f446re: 61, nucleo_f446ze: 62 }", "irq: { nucleo_f446re: 61, nucleo_f446ze: rtc.alarm }") + self.assertIn("#define WAKE_IRQ 41u", self.generate()["nucleo_f446ze"]["configuration.h"]) + + def expect_irq(self, new, board, message): + self.edit("{ nucleo_f446re: 61, nucleo_f446ze: 62 }", new) + path = self.dir / "system.yaml" + path.write_text(self.text, encoding="utf-8") + with self.assertRaises(HwError) as cm: + system.resolve(path, ROOT, board) + self.assertTrue(any(re.search(message, e) for e in cm.exception.errors), cm.exception.errors) + + def test_a_line_a_device_connects(self): + self.expect_irq("38", "st/nucleo_f446re", r"interrupts\.wake\.irq: line 38 is the device usart2's: its driver connects it") + + def test_a_line_beyond_the_soc(self): + self.expect_irq("97", "st/nucleo_f446re", r"line 97 is beyond the SoC's 97 interrupt lines") + + def test_no_such_interrupt(self): + self.expect_irq("rtc.wakeup", "st/nucleo_f446re", r"the SoC has no interrupt 'rtc\.wakeup'") + + def test_no_line_for_a_board(self): + self.expect_irq("{ nucleo_f446re: 61 }", "st/nucleo_f446ze", r"no line for nucleo_f446ze: give one by its name") + + def test_a_level_beyond_the_ports(self): + self.edit("level: 1", "level: 200") + path = self.dir / "system.yaml" + path.write_text(self.text, encoding="utf-8") + with self.assertRaises(HwError) as cm: + system.resolve(path, ROOT, "st/nucleo_f446re") + self.assertTrue(any("interrupts.wake.level: level 200 is beyond the port's levels" in e + for e in cm.exception.errors), cm.exception.errors) + + class Negative(Base): def test_unknown_key(self): self.edit("name: controller", "name: controller\nflavour: lemon") diff --git a/hw/schemas/bindings.schema.json b/hw/schemas/bindings.schema.json index a1da60ae..3f63bbb2 100644 --- a/hw/schemas/bindings.schema.json +++ b/hw/schemas/bindings.schema.json @@ -17,12 +17,13 @@ }, "$defs": { "c_ident": { "type": "string", "pattern": "^[A-Za-z_][A-Za-z0-9_]*$" }, + "expr": { "type": "string", "pattern": "^(peripheral|device|board|soc|pins|dma|flash|takes)(\\.[A-Za-z0-9_]+)+$" }, "binding": { "type": "object", "required": ["class", "level", "sources", "header", "api", "config"], "additionalProperties": false, "properties": { - "class": { "enum": ["uart", "spi", "i2c", "dma", "watchdog", "flash", "rtc", "entropy", "clock", "gpio"] }, + "class": { "enum": ["uart", "spi", "i2c", "dma", "watchdog", "flash", "rtc", "entropy", "clock", "gpio", "counter", "pwm", "adc"] }, "level": { "enum": ["early", "kernel"] }, "sources": { "type": "array", @@ -36,7 +37,24 @@ "data": { "$ref": "#/$defs/c_ident" }, "fields": { "type": "object", - "additionalProperties": { "type": "string", "pattern": "^(peripheral|device|board|soc|pins|dma|flash)(\\.[A-Za-z0-9_]+)+$" } + "additionalProperties": { "oneOf": [ + { "$ref": "#/$defs/expr" }, + { + "description": "a field with a default, for a device that does not give it (A129)", + "type": "object", + "required": ["from", "default"], + "additionalProperties": false, + "properties": { + "from": { "$ref": "#/$defs/expr" }, + "default": { "type": ["integer", "boolean"] } + } + } + ] } + }, + "takes": { + "description": "peripherals a device takes for itself besides its own, by the device key that names each, with the compatible it must have: an ADC's pacing timer (trigger: tim2, A129); a field reads one as takes..", + "type": "object", + "additionalProperties": { "type": "string" } }, "buffers": { "type": "object", @@ -45,7 +63,7 @@ "required": ["size"], "additionalProperties": false, "properties": { - "size": { "type": "string", "pattern": "^(peripheral|device|board|soc|pins|dma|flash)(\\.[A-Za-z0-9_]+)+$" }, + "size": { "type": "string", "pattern": "^(peripheral|device|board|soc|pins|dma|flash|takes)(\\.[A-Za-z0-9_]+)+$" }, "default": { "type": "integer", "minimum": 1, "maximum": 65535 } } } diff --git a/hw/schemas/board.schema.json b/hw/schemas/board.schema.json index 4ab3b791..a5612e67 100644 --- a/hw/schemas/board.schema.json +++ b/hw/schemas/board.schema.json @@ -71,6 +71,10 @@ "name": { "type": "string", "pattern": "^[a-z][a-z0-9_]*$" }, "peripheral": { "$ref": "#/$defs/ident" }, "compatible": { "type": "string", "pattern": "^[a-z0-9-]+,[a-z0-9-]+$" }, + "class": { + "description": "the driver class, for a peripheral more than one class can drive (a timer: counter or pwm, A129)", + "enum": ["uart", "spi", "i2c", "dma", "watchdog", "flash", "rtc", "entropy", "clock", "gpio", "counter", "pwm", "adc"] + }, "bus": { "type": "string", "pattern": "^[a-z][a-z0-9_]*$" }, "deps": { "type": "array", "items": { "type": "string", "pattern": "^[a-z][a-z0-9_]*$" } }, "level": { "enum": ["early", "kernel"] }, @@ -144,7 +148,7 @@ "properties": { "device": { "type": "string", "pattern": "^[a-z][a-z0-9_]*$" }, "ports": { "type": "array", "minItems": 2, "maxItems": 2, "items": { "type": "string", "pattern": "^[A-Za-z0-9_]+$" } }, - "internal": { "const": true }, + "internal": { "const": true }, "channels": {"type": "array", "minItems": 2, "maxItems": 2, "items": {"type": "integer", "minimum": 0, "maximum": 31}, "description": "a PWM loop's output and capture channels, or an ADC loop's inputs, high then low (A129)"}, "peer": { "type": "string", "pattern": "^[a-z][a-z0-9_]*$" }, "nets": { "type": "array", "minItems": 2, "maxItems": 2, "items": { "type": "array", "minItems": 2, "maxItems": 2, "items": { "type": "string", "pattern": "^[A-Za-z0-9_]+$" } } } diff --git a/hw/schemas/hw.schema.json b/hw/schemas/hw.schema.json index 640cccaf..6bee9766 100644 --- a/hw/schemas/hw.schema.json +++ b/hw/schemas/hw.schema.json @@ -97,8 +97,8 @@ "properties": { "pin": { "type": "string" }, "port": { "type": "string" }, - "number": { "type": "integer", "minimum": 0, "maximum": 15 }, - "mode": { "enum": ["af", "fixed", "output", "input"] }, + "number": { "type": "integer", "minimum": 0, "maximum": 63, "description": "its line in its port (0 to 15) or bank (the RP2350's 0 to 47)" }, + "mode": { "enum": ["af", "fixed", "output", "input", "analog"] }, "owner": { "type": "string" }, "gpio": { "type": "string" }, "af": { "type": "integer" }, diff --git a/hw/schemas/soc.schema.json b/hw/schemas/soc.schema.json index f8bc9344..45e40f62 100644 --- a/hw/schemas/soc.schema.json +++ b/hw/schemas/soc.schema.json @@ -107,10 +107,15 @@ "postdiv": { "$ref": "#/$defs/range" }, "vco_in_hz": { "$ref": "#/$defs/range" }, "vco_out_hz": { "$ref": "#/$defs/range" }, + "output_hz": { "type": "integer", "minimum": 1, "description": "a PLL with an output of its own, not the CPU's: solved for exactly this rate from the board's clock source (A129); a peripheral clocked by it names it in clocked_by" }, "doc": { "type": "string" } } } }, + "timers_double_when_divided": { + "type": "boolean", + "description": "the timers on an APB bus run at twice its clock when its prescaler is not 1 (the STM32F4: RM0390 \u00a76.2); a binding reads the rate as peripheral.timer_clock_hz" + }, "prescalers": { "type": "object", "additionalProperties": false, @@ -227,6 +232,38 @@ { "type": "array", "minItems": 1, "items": { "$ref": "#/$defs/dma_request" } } ] } }, + "counter_bits": { + "description": "a timer's counter width in bits (A129): the counter, PWM and ADC classes' drivers widen and scale by it", + "enum": [16, 24, 32, 64] + }, + "timer_channels": { + "description": "a timer's capture and compare channels, where it has fewer than four (A129): TIM9 and TIM12's 2", + "type": "integer", + "minimum": 1, + "maximum": 4 + }, + "adc_trigger": { + "description": "a timer's TRGO as the ADC's external trigger: its EXTSEL code (A129), which an ADC device that takes it as its trigger reads", + "type": "integer", + "minimum": 0, + "maximum": 15 + }, + "clocked_by": { + "$ref": "#/$defs/ident", + "description": "the PLL with an output_hz its kernel clock comes from, where that is not its bus (A129): a binding reads the rate as peripheral.clock_hz" + }, + "adc": { + "description": "an ADC (A129): its resolution in bits, its external inputs, and the inputs its temperature sensor and internal reference are on, where it has them", + "type": "object", + "required": ["bits"], + "additionalProperties": false, + "properties": { + "bits": { "type": "integer", "minimum": 1, "maximum": 32 }, + "inputs": { "type": "integer", "minimum": 1 }, + "temperature": { "type": "integer", "minimum": 0 }, + "vrefint": { "type": "integer", "minimum": 0 } + } + }, "curated": { "type": "boolean" }, "doc": { "type": "string" } } diff --git a/hw/schemas/system.schema.json b/hw/schemas/system.schema.json index a8ed062c..1fbcfc1c 100644 --- a/hw/schemas/system.schema.json +++ b/hw/schemas/system.schema.json @@ -118,6 +118,49 @@ "$ref": "#/$defs/i2c_target" } }, + "interrupts": { + "type": "array", + "description": "the application's own interrupt handlers (A130), connected by SYS_Initialize()", + "items": { + "type": "object", + "required": [ + "name", + "irq", + "handler" + ], + "additionalProperties": false, + "properties": { + "name": { + "$ref": "#/$defs/c_ident" + }, + "irq": { + "description": "the line: its number, a SoC peripheral's ., or either by board name, for a system on several SoCs", + "oneOf": [ + { + "$ref": "#/$defs/irq_line" + }, + { + "type": "object", + "additionalProperties": { + "$ref": "#/$defs/irq_line" + } + } + ] + }, + "handler": { + "$ref": "#/$defs/c_ident" + }, + "level": { + "type": "integer", + "minimum": 0, + "description": "its priority level (emb_irq_set_level()); default: the port's" + }, + "doc": { + "type": "string" + } + } + } + }, "watchdog": { "type": "object", "required": [ @@ -139,6 +182,18 @@ } }, "$defs": { + "irq_line": { + "oneOf": [ + { + "type": "integer", + "minimum": 0 + }, + { + "type": "string", + "pattern": "^[A-Za-z_][A-Za-z0-9_]*\\.[A-Za-z_][A-Za-z0-9_]*$" + } + ] + }, "c_ident": { "type": "string", "pattern": "^[A-Za-z_][A-Za-z0-9_]*$" @@ -444,10 +499,6 @@ "$ref": "#/$defs/duration", "description": "the periodic model's period" }, - "data": { - "$ref": "#/$defs/c_ident", - "description": "the task's own data, a C type in its header" - }, "event": { "$ref": "#/$defs/c_ident", "description": "an event type of its own, its first member a uint32_t id" diff --git a/include/emb/api_ids.h b/include/emb/api_ids.h index 5ada3d9c..c1caf2c1 100644 --- a/include/emb/api_ids.h +++ b/include/emb/api_ids.h @@ -261,5 +261,27 @@ #define EMB_API_ID_TRACE_STOP 0x0102u #define EMB_API_ID_TRACE_DUMP 0x0103u #define EMB_API_ID_TRACE_STATS_GET 0x0104u +#define EMB_API_ID_DRV_COUNTER_NOW 0x0105u +#define EMB_API_ID_DRV_COUNTER_RATE 0x0106u +#define EMB_API_ID_DRV_COUNTER_CHANNELS 0x0107u +#define EMB_API_ID_DRV_COUNTER_ALARM_SET 0x0108u +#define EMB_API_ID_DRV_COUNTER_ALARM_CANCEL 0x0109u +#define EMB_API_ID_DRV_COUNTER_PERIODIC 0x010Au +#define EMB_API_ID_DRV_COUNTER_PERIODIC_STOP 0x010Bu +#define EMB_API_ID_DRV_COUNTER_STARTED 0x010Cu +#define EMB_API_ID_DRV_COUNTER_FIRED 0x010Du +#define EMB_API_ID_DRV_PWM_SET 0x010Eu +#define EMB_API_ID_DRV_PWM_STOP 0x010Fu +#define EMB_API_ID_DRV_PWM_CAPTURE 0x0110u +#define EMB_API_ID_DRV_PWM_CHANNELS 0x0111u +#define EMB_API_ID_DRV_PWM_STARTED 0x0112u +#define EMB_API_ID_DRV_ADC_READ 0x0113u +#define EMB_API_ID_DRV_ADC_READ_POLLED 0x0114u +#define EMB_API_ID_DRV_ADC_TO_MV 0x0115u +#define EMB_API_ID_DRV_ADC_TEMPERATURE 0x0116u +#define EMB_API_ID_DRV_ADC_SAMPLE_START 0x0117u +#define EMB_API_ID_DRV_ADC_SAMPLE_STOP 0x0118u +#define EMB_API_ID_DRV_ADC_STARTED 0x0119u +#define EMB_API_ID_DRV_ADC_SAMPLED 0x011Au #endif /* EMB_API_IDS_H */ diff --git a/include/emb/device.h b/include/emb/device.h index ec5c72ef..a0b36805 100644 --- a/include/emb/device.h +++ b/include/emb/device.h @@ -59,6 +59,9 @@ extern "C" { #define EMB_DRV_CLASS_ENTROPY 8u #define EMB_DRV_CLASS_CLOCK 9u #define EMB_DRV_CLASS_GPIO 10u +#define EMB_DRV_CLASS_COUNTER 11u /* A129 */ +#define EMB_DRV_CLASS_PWM 12u +#define EMB_DRV_CLASS_ADC 13u struct emb_device; struct emb_drv_request; diff --git a/include/emb/drv_adc.h b/include/emb/drv_adc.h new file mode 100644 index 00000000..61422e80 --- /dev/null +++ b/include/emb/drv_adc.h @@ -0,0 +1,278 @@ +/* SPDX-License-Identifier: Apache-2.0 */ +/* Copyright 2026 Junior Deogracias */ +/* + * This file is part of EmbLinkRTOS, a deterministic real-time kernel for microcontrollers. + * Licensed under the Apache License, Version 2.0; see the LICENSE file at the repository root. + */ + +/** + * @file drv_adc.h + * @brief The ADC class (SPEC-017 §11c, A129). + * + * @details + * One conversion of an input, waiting for the device or polled from any context; a count's + * millivolts against the board's reference; the internal temperature sensor, calibrated where + * the part stores calibration; and a sequence of inputs sampled at a rate into the caller's + * buffer by DMA, a callback at each half of it. + * + * @author teo1747 + * @date 2026-11-13 (created) + */ +#ifndef EMB_DRV_ADC_H +#define EMB_DRV_ADC_H + +#include +#include +#include + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/* Inputs: an ADC's own numbers (adc1_in4 is 4), and its internal ones. */ +#define EMB_DRV_ADC_TEMPERATURE 0xFEu /* the internal temperature sensor (CAP_TEMPERATURE) */ +#define EMB_DRV_ADC_VREFINT 0xFDu /* the internal reference (CAP_VREFINT) */ + +/* The most inputs a sampled sequence has. */ +#define EMB_DRV_ADC_SEQUENCE_MAX 8u + +/* Capabilities (emb_device_caps()). */ +#define EMB_DRV_ADC_CAP_TEMPERATURE 0x01u /* an internal temperature sensor */ +#define EMB_DRV_ADC_CAP_CALIBRATED 0x02u /* its temperature from the part's factory calibration */ +#define EMB_DRV_ADC_CAP_VREFINT 0x04u /* an internal reference to read */ +#define EMB_DRV_ADC_CAP_SAMPLE 0x08u /* sequences sampled into a buffer by DMA */ +#define EMB_DRV_ADC_CAP_ASCENDING 0x10u /* a sequence's inputs taken in ascending order only */ + +/* A half of a sampling buffer filled, in the DMA interrupt: its samples, the sequence's inputs + * in turn, a whole number of sequences; or the sampling's end, EMB_EOVERRUN when the hardware + * lost samples, with no samples. */ +typedef void (*emb_drv_adc_fn_t)(void *arg, const uint16_t *samples, uint32_t count, + emb_status_t status); + +/* A sampling: a sequence of inputs, converted in turn rate_hz times a second, into buffer, its + * length samples a whole number of sequences in each half; fn is called at each half. The + * buffer belongs to the hardware until the sampling stops; a half is the callback's to read + * until the other half is full. */ +typedef struct emb_drv_adc_sampling { + const uint8_t *inputs; + uint16_t *buffer; + uint32_t length; + uint32_t rate_hz; + emb_drv_adc_fn_t fn; + void *arg; + uint8_t count; /* inputs in the sequence: 1 to EMB_DRV_ADC_SEQUENCE_MAX */ + uint8_t reserved_[3]; +} emb_drv_adc_sampling_t; + +/* The class's part of a driver's RAM, its first members: the device's lock, which queues + * readers; whether a conversion or a sampling holds the hardware; the sampling's buffer and + * callback. */ +typedef struct emb_drv_adc_data { + emb_drv_bus_t lock; + emb_drv_adc_fn_t fn; + void *arg; + uint16_t *buffer; + uint32_t length; + uint8_t busy; + uint8_t sampling; + uint8_t reserved_[2]; +} emb_drv_adc_data_t; + +/* An ADC driver's operations: the device's, then one conversion, polled and bounded; a sampling + * started and stopped; the temperature sensor's count in thousandths of a degree Celsius; and + * the board's reference, in millivolts. read() refuses an input it does not have with + * EMB_EINVAL; sample_start() a sampling it cannot make (an input, the rate, the buffer) with + * EMB_EINVAL, and calls emb_drv_adc_sampled() at each half. Each runs with the hardware the + * class's: read() and sample_start() never at once. */ +typedef struct emb_drv_adc_api { + emb_device_api_t dev; + emb_status_t (*read)(const emb_device_t *dev, uint8_t input, uint16_t *count); + emb_status_t (*sample_start)(const emb_device_t *dev, const emb_drv_adc_sampling_t *s); + void (*sample_stop)(const emb_device_t *dev); + emb_status_t (*to_mdegc)(const emb_device_t *dev, uint16_t count, int32_t *mdegc); + uint32_t (*vref_mv)(const emb_device_t *dev); + uint8_t bits; /* a count's width */ + uint8_t reserved_[3]; +} emb_drv_adc_api_t; + +/** + * emb_drv_adc_read() - Convert an input once. + * @dev: A device of the ADC class. + * @input: Its number, or EMB_DRV_ADC_TEMPERATURE, EMB_DRV_ADC_VREFINT. + * @count: Receives the conversion, 0 to 2^bits - 1. + * @timeout: How long to wait for the device. + * + * @ctx thread + * @blocks yes + * @time O(1) + * @owns none + * @config CONFIG_EMB_DRV_ADC + * @req DRV-001 + * @since 0.3 + * @stable no + * + * It waits for the device, up to @timeout, then converts in under 30 us, polled. + * + * Return: EMB_OK; EMB_ETIMEDOUT (the device stayed taken); EMB_EBUSY (it samples); EMB_EINVAL + * (no such input); EMB_EIO (the conversion failed); EMB_ESTATE (not READY). + */ +emb_status_t emb_drv_adc_read(const emb_device_t *dev, uint8_t input, uint16_t *count, + emb_timeout_t timeout); + +/** + * emb_drv_adc_read_polled() - Convert an input once, from any context. + * @dev: A device of the ADC class. + * @input: Its number, or EMB_DRV_ADC_TEMPERATURE, EMB_DRV_ADC_VREFINT. + * @count: Receives the conversion. + * + * @ctx thread isr prekernel + * @blocks no + * @time O(1) + * @owns none + * @config CONFIG_EMB_DRV_ADC + * @req DRV-001 DRV-007 + * @since 0.3 + * @stable no + * + * Return: EMB_OK; EMB_EBUSY (a conversion or a sampling holds the device); EMB_EINVAL (no such + * input); EMB_EIO; EMB_ESTATE (not READY). + */ +emb_status_t emb_drv_adc_read_polled(const emb_device_t *dev, uint8_t input, uint16_t *count); + +/** + * emb_drv_adc_to_mv() - A count's millivolts, against the board's reference. + * @dev: A device of the ADC class. + * @count: A conversion. + * @mv: Receives count x reference / (2^bits - 1), rounded. + * + * @ctx thread isr prekernel + * @blocks no + * @time O(1) + * @owns none + * @config CONFIG_EMB_DRV_ADC + * @req DRV-001 + * @since 0.3 + * @stable no + * + * The reference is the board's (the device's vref_mv: 3300 unless it says). + * + * Return: EMB_OK; EMB_EINVAL (a count beyond the ADC's width). + */ +emb_status_t emb_drv_adc_to_mv(const emb_device_t *dev, uint16_t count, uint32_t *mv); + +/** + * emb_drv_adc_temperature() - The internal temperature sensor's reading. + * @dev: A device of the ADC class with CAP_TEMPERATURE. + * @mdegc: Receives the temperature, in thousandths of a degree Celsius. + * @timeout: How long to wait for the device. + * + * @ctx thread + * @blocks yes + * @time O(1) + * @owns none + * @config CONFIG_EMB_DRV_ADC + * @req DRV-001 + * @since 0.3 + * @stable no + * + * With CAP_CALIBRATED, from the part's two calibration points; otherwise from the datasheet's + * typical slope, a few degrees off. + * + * Return: EMB_OK; EMB_ENOTSUP (no sensor); EMB_EIO (no calibration, or the conversion failed); + * and emb_drv_adc_read()'s. + */ +emb_status_t emb_drv_adc_temperature(const emb_device_t *dev, int32_t *mdegc, + emb_timeout_t timeout); + +/** + * emb_drv_adc_sample_start() - Sample a sequence of inputs into a buffer, by DMA. + * @dev: A device of the ADC class with CAP_SAMPLE. + * @s: The sampling; copied: it may be on the caller's stack. + * + * @ctx thread + * @blocks no + * @time O(1) + * @owns none + * @config CONFIG_EMB_DRV_ADC + * @req DRV-001 DRV-004 + * @since 0.3 + * @stable no + * + * It runs until emb_drv_adc_sample_stop(), or until the hardware loses samples, which ends it + * with a last call of @s's fn with EMB_EOVERRUN. Meanwhile the device is the sampling's: a read + * is refused with EMB_EBUSY. With CAP_ASCENDING, a sequence's inputs are in ascending order, + * each once. The RP2350's buffer is a power of two bytes, at most 32 KiB, aligned to its size + * (its DMA's ring, A129). + * + * Return: EMB_OK; EMB_EBUSY (it samples, or converts); EMB_ENOTSUP (no sampling); EMB_EINVAL (a + * sequence of 0 or more than EMB_DRV_ADC_SEQUENCE_MAX inputs, an input it does not have, a rate + * it cannot make, or a buffer of another shape); EMB_ESTATE (not READY). + */ +emb_status_t emb_drv_adc_sample_start(const emb_device_t *dev, const emb_drv_adc_sampling_t *s); + +/** + * emb_drv_adc_sample_stop() - Stop a sampling. + * @dev: A device of the ADC class. + * + * @ctx thread isr + * @blocks no + * @time O(1) + * @owns none + * @config CONFIG_EMB_DRV_ADC + * @req DRV-001 DRV-006 + * @since 0.3 + * @stable no + * + * No callback runs after it returns; the buffer is the caller's again. + * + * Return: EMB_OK; EMB_ESTATE (it was not sampling). + */ +emb_status_t emb_drv_adc_sample_stop(const emb_device_t *dev); + +/** + * emb_drv_adc_started() - For drivers, at the end of init(): the class's part of the RAM made + * ready, its lock made. + * @dev: A device of the ADC class. + * + * @ctx thread + * @blocks no + * @time O(1) + * @owns none + * @config CONFIG_EMB_DRV_ADC + * @req DRV-001 + * @since 0.3 + * @stable no + * + * Return: EMB_OK; what making the lock returns otherwise. + */ +emb_status_t emb_drv_adc_started(const emb_device_t *dev); + +/** + * emb_drv_adc_sampled() - For drivers, in the DMA interrupt: a half of the buffer filled, or the + * sampling ended by the hardware. + * @dev: A device of the ADC class. + * @half: 0 for the buffer's first half, 1 for its second. + * @status: EMB_OK; or EMB_EOVERRUN, the driver having stopped the hardware. + * + * @ctx isr + * @blocks no + * @time O(1) plus the callback + * @owns none + * @config CONFIG_EMB_DRV_ADC + * @req DRV-001 + * @since 0.3 + * @stable no + * + * Nothing runs after a stop. + * + * Return: EMB_OK; EMB_ESTATE (not sampling). + */ +emb_status_t emb_drv_adc_sampled(const emb_device_t *dev, uint8_t half, emb_status_t status); + +#ifdef __cplusplus +} +#endif + +#endif /* EMB_DRV_ADC_H */ diff --git a/include/emb/drv_counter.h b/include/emb/drv_counter.h new file mode 100644 index 00000000..1fcc916a --- /dev/null +++ b/include/emb/drv_counter.h @@ -0,0 +1,268 @@ +/* SPDX-License-Identifier: Apache-2.0 */ +/* Copyright 2026 Junior Deogracias */ +/* + * This file is part of EmbLinkRTOS, a deterministic real-time kernel for microcontrollers. + * Licensed under the Apache License, Version 2.0; see the LICENSE file at the repository root. + */ + +/** + * @file drv_counter.h + * @brief The counter class (SPEC-017 §11a, A129). + * + * @details + * A free-running counter at a known rate, its count widened to 64 bits by the driver; one-shot + * alarms on its channels at an absolute count; and periodic callbacks without drift. Each + * callback runs in the counter's interrupt. The class is named counter so that it is not taken + * for the kernel's software timers (). + * + * @author teo1747 + * @date 2026-11-13 (created) + */ +#ifndef EMB_DRV_COUNTER_H +#define EMB_DRV_COUNTER_H + +#include + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/* The most channels a counter has: the STM32's four compare channels, the RP2350's four alarms. */ +#define EMB_DRV_COUNTER_CHANNELS_MAX 4u + +/* Capabilities (emb_device_caps()). */ +#define EMB_DRV_COUNTER_CAP_64BIT 0x01u /* the hardware counts 64 bits: nothing to widen */ + +/* A callback, in the counter's interrupt: the count it was due at, which a periodic callback + * advances by whole periods, so the gap between two is the periods a late one skipped. */ +typedef void (*emb_drv_counter_fn_t)(void *arg, uint64_t at); + +/* One channel's alarm, one-shot or periodic. */ +typedef struct emb_drv_counter_alarm { + emb_drv_counter_fn_t fn; + void *arg; + uint64_t at; /* the count it fires at next */ + uint64_t period; /* 0 for a one-shot */ + uint8_t armed; + uint8_t reserved_[7]; +} emb_drv_counter_alarm_t; + +/* The class's part of a driver's RAM, its first member: each channel's alarm, and the device's + * channels, which emb_drv_counter_started() sets. */ +typedef struct emb_drv_counter_data { + emb_drv_counter_alarm_t alarm[EMB_DRV_COUNTER_CHANNELS_MAX]; + uint8_t channels; + uint8_t reserved_[7]; +} emb_drv_counter_data_t; + +/* A counter driver's operations: the device's, then the count, its rate, and a channel's + * hardware alarm armed at a full 64-bit count and disarmed. arm() and disarm() run with + * interrupts locked. arm() refuses a count that has already passed with EMB_EPAST, checked + * after it is armed so that a count passing meanwhile is not missed; it fires only once the + * whole count is reached, whatever the hardware's width. A driver's interrupt calls + * emb_drv_counter_fired() for each channel whose count was reached. */ +typedef struct emb_drv_counter_api { + emb_device_api_t dev; + uint64_t (*now)(const emb_device_t *dev); + uint32_t (*rate)(const emb_device_t *dev); + emb_status_t (*arm)(const emb_device_t *dev, uint8_t channel, uint64_t at); + void (*disarm)(const emb_device_t *dev, uint8_t channel); + uint8_t channels; /* the most a device of the driver has */ + uint8_t reserved_[3]; +} emb_drv_counter_api_t; + +/** + * emb_drv_counter_now() - The counter's count. + * @dev: A device of the counter class. + * @count: Receives the count since the device started, widened to 64 bits. + * + * @ctx thread isr prekernel + * @blocks no + * @time O(1) + * @owns none + * @config CONFIG_EMB_DRV_COUNTER + * @req DRV-001 + * @since 0.3 + * @stable no + * + * Return: EMB_OK; EMB_ESTATE (not READY). + */ +emb_status_t emb_drv_counter_now(const emb_device_t *dev, uint64_t *count); + +/** + * emb_drv_counter_rate() - The counter's rate. + * @dev: A device of the counter class. + * @hz: Receives its counts per second. + * + * @ctx thread isr prekernel + * @blocks no + * @time O(1) + * @owns none + * @config CONFIG_EMB_DRV_COUNTER + * @req DRV-001 + * @since 0.3 + * @stable no + * + * Return: EMB_OK; EMB_ESTATE (not READY). + */ +emb_status_t emb_drv_counter_rate(const emb_device_t *dev, uint32_t *hz); + +/** + * emb_drv_counter_channels() - The counter's alarm channels. + * @dev: A device of the counter class. + * @count: Receives how many; channels are numbered from 0. + * + * @ctx thread isr prekernel + * @blocks no + * @time O(1) + * @owns none + * @config CONFIG_EMB_DRV_COUNTER + * @req DRV-001 + * @since 0.3 + * @stable no + * + * Return: EMB_OK. + */ +emb_status_t emb_drv_counter_channels(const emb_device_t *dev, uint8_t *count); + +/** + * emb_drv_counter_alarm_set() - Arm a channel's one-shot alarm. + * @dev: A device of the counter class. + * @channel: Which, from 0. + * @at: The count it fires at, after the count now. + * @fn: Called in the counter's interrupt when the count reaches @at. + * @arg: Passed to @fn. + * + * @ctx thread isr + * @blocks no + * @time O(1) + * @owns none + * @config CONFIG_EMB_DRV_COUNTER + * @req DRV-001 + * @since 0.3 + * @stable no + * + * It fires once, never before @at; @fn may arm it again. + * + * Return: EMB_OK; EMB_EPAST (@at has already passed, now or while it was armed: nothing is + * armed); EMB_EBUSY (the channel is armed); EMB_EINVAL (no such channel); EMB_ESTATE (not + * READY). + */ +emb_status_t emb_drv_counter_alarm_set(const emb_device_t *dev, uint8_t channel, uint64_t at, + emb_drv_counter_fn_t fn, void *arg); + +/** + * emb_drv_counter_alarm_cancel() - Disarm a channel's one-shot alarm. + * @dev: A device of the counter class. + * @channel: Which. + * + * @ctx thread isr + * @blocks no + * @time O(1) + * @owns none + * @config CONFIG_EMB_DRV_COUNTER + * @req DRV-001 + * @since 0.3 + * @stable no + * + * No callback runs after it returns. + * + * Return: EMB_OK; EMB_ESTATE (no one-shot alarm armed: it fired, was never armed, or the channel + * is periodic); EMB_EINVAL (no such channel). + */ +emb_status_t emb_drv_counter_alarm_cancel(const emb_device_t *dev, uint8_t channel); + +/** + * emb_drv_counter_periodic() - Call a function every period, without drift. + * @dev: A device of the counter class. + * @channel: Which, from 0. + * @period: In counts; at least 2. + * @fn: Called in the counter's interrupt at each period's end. + * @arg: Passed to @fn. + * + * @ctx thread isr + * @blocks no + * @time O(1) + * @owns none + * @config CONFIG_EMB_DRV_COUNTER + * @req DRV-001 + * @since 0.3 + * @stable no + * + * The first call is one period from now. Each next one is due one period after the last was + * due, not after it ran, so the periods do not drift; one due while the counter's interrupt was + * held off past it is skipped, and @fn's @at shows the gap. + * + * Return: EMB_OK; EMB_EBUSY (the channel is armed); EMB_EINVAL (no such channel, or a period of + * 0 or 1); EMB_ESTATE (not READY). + */ +emb_status_t emb_drv_counter_periodic(const emb_device_t *dev, uint8_t channel, uint64_t period, + emb_drv_counter_fn_t fn, void *arg); + +/** + * emb_drv_counter_periodic_stop() - Stop a channel's periodic callback. + * @dev: A device of the counter class. + * @channel: Which. + * + * @ctx thread isr + * @blocks no + * @time O(1) + * @owns none + * @config CONFIG_EMB_DRV_COUNTER + * @req DRV-001 + * @since 0.3 + * @stable no + * + * No callback runs after it returns; the callback may stop itself. + * + * Return: EMB_OK; EMB_ESTATE (the channel is not periodic); EMB_EINVAL (no such channel). + */ +emb_status_t emb_drv_counter_periodic_stop(const emb_device_t *dev, uint8_t channel); + +/** + * emb_drv_counter_started() - For drivers, at the end of init(): the class's part of the RAM made + * ready, no alarm armed. + * @dev: A device of the counter class. + * @channels: The device's channels; 0 for the driver's most (its operations' channels). + * + * @ctx prekernel thread + * @blocks no + * @time O(1) + * @owns none + * @config CONFIG_EMB_DRV_COUNTER + * @req DRV-001 + * @since 0.3 + * @stable no + * + * Return: EMB_OK. + */ +emb_status_t emb_drv_counter_started(const emb_device_t *dev, uint8_t channels); + +/** + * emb_drv_counter_fired() - For drivers, in the counter's interrupt: a channel's count reached. + * @dev: A device of the counter class. + * @channel: The channel whose hardware alarm fired, the whole count reached. + * + * @ctx isr + * @blocks no + * @time O(1) plus the callback + * @owns none + * @config CONFIG_EMB_DRV_COUNTER + * @req DRV-001 + * @since 0.3 + * @stable no + * + * A one-shot alarm is disarmed first, so its callback may arm it again; a periodic one is armed + * for its next period first, skipping any already passed. Nothing runs if it was canceled. + * + * Return: EMB_OK; EMB_ESTATE (none armed); EMB_EINVAL (no such channel). + */ +emb_status_t emb_drv_counter_fired(const emb_device_t *dev, uint8_t channel); + +#ifdef __cplusplus +} +#endif + +#endif /* EMB_DRV_COUNTER_H */ diff --git a/include/emb/drv_dma.h b/include/emb/drv_dma.h index 4735daca..a26acba3 100644 --- a/include/emb/drv_dma.h +++ b/include/emb/drv_dma.h @@ -37,6 +37,8 @@ extern "C" { /* A job's flags. */ #define EMB_DRV_DMA_FIXED_MEM \ 0x01u /* the memory side stays: a fill, or a sink; memory to memory, the source */ +#define EMB_DRV_DMA_CIRCULAR \ + 0x02u /* the job repeats over its memory until stopped, its end at each half (A129) */ /* Capabilities (emb_device_caps()). */ #define EMB_DRV_DMA_CAP_MEM_TO_MEM 0x01u @@ -65,7 +67,9 @@ typedef struct emb_drv_dma_job { } emb_drv_dma_job_t; /* A job's end, in the DMA interrupt: EMB_OK with count moved, or EMB_EXFER (a bus error) - * with what moved before it. */ + * with what moved before it. A circular job's is each half of its memory, filled or sent: + * EMB_OK with count / 2 for the first half, count for the second, and the job goes on; a bus + * error ends it, EMB_EXFER. */ typedef void (*emb_drv_dma_done_t)(void *arg, emb_status_t status, uint32_t moved); /* A DMA driver's operations: the device's, then a channel's job started and stopped. start() @@ -109,9 +113,14 @@ extern const unsigned emb_board_dma_region_count; * emb_drv_dma_stop() returns: the caller must not touch it meanwhile. No cache maintenance is * done (A109). * - * Return: EMB_OK; EMB_EINVAL (memory outside the board's DMA regions, or a count the - * controller cannot take); EMB_ENOTSUP (memory to memory on a controller without it); - * EMB_EBUSY (the channel is running); EMB_ESTATE (the controller is not READY). + * A circular job (EMB_DRV_DMA_CIRCULAR) runs until emb_drv_dma_stop(), between a peripheral and + * memory that advances, over an even count. The RP2350 wraps it by its address ring: its memory + * is a power of two bytes, at most 32 KiB, aligned to its size. + * + * Return: EMB_OK; EMB_EINVAL (memory outside the board's DMA regions, a count the controller + * cannot take, or a circular job of another shape); EMB_ENOTSUP (memory to memory, or a circular + * job, on a controller without it); EMB_EBUSY (the channel is running); EMB_ESTATE (the + * controller is not READY). */ emb_status_t emb_drv_dma_start(const emb_drv_dma_chan_t *ch, const emb_drv_dma_job_t *job, emb_drv_dma_done_t done, void *arg); diff --git a/include/emb/drv_pwm.h b/include/emb/drv_pwm.h new file mode 100644 index 00000000..0bf82dbf --- /dev/null +++ b/include/emb/drv_pwm.h @@ -0,0 +1,198 @@ +/* SPDX-License-Identifier: Apache-2.0 */ +/* Copyright 2026 Junior Deogracias */ +/* + * This file is part of EmbLinkRTOS, a deterministic real-time kernel for microcontrollers. + * Licensed under the Apache License, Version 2.0; see the LICENSE file at the repository root. + */ + +/** + * @file drv_pwm.h + * @brief The PWM class (SPEC-017 §11b, A129). + * + * @details + * A device's output channels, each a pulse of a width within a period, in nanoseconds, rounded + * to the nearest the hardware makes, which is reported back; the channels of one device share + * its period. And an input's period and pulse measured, waiting up to a timeout: one cycle + * exactly where the hardware captures edges, an average over many where it counts them + * (CAP_CAPTURE_AVERAGED). + * + * @author teo1747 + * @date 2026-11-13 (created) + */ +#ifndef EMB_DRV_PWM_H +#define EMB_DRV_PWM_H + +#include +#include +#include + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/* The most channels a device has: the STM32's four, the RP2350 slice's two (A and B). */ +#define EMB_DRV_PWM_CHANNELS_MAX 4u + +/* An output's flags. */ +#define EMB_DRV_PWM_INVERTED 0x01u /* low for the pulse, high for the rest of the period */ + +/* Capabilities (emb_device_caps()). */ +#define EMB_DRV_PWM_CAP_CAPTURE 0x01u /* it measures an input */ +#define EMB_DRV_PWM_CAP_CAPTURE_AVERAGED 0x02u /* averaged over many cycles, not one exactly */ + +/* A wave: its period, and the width of its pulse, the time it is high. */ +typedef struct emb_drv_pwm_wave { + uint32_t period_ns; + uint32_t pulse_ns; +} emb_drv_pwm_wave_t; + +/* The class's part of a driver's RAM, its first members: the device's lock, held for a + * capture; the period its channels share while one runs; the channels running and those + * capturing, a bit each; the device's channels, which emb_drv_pwm_started() sets. */ +typedef struct emb_drv_pwm_data { + emb_drv_bus_t lock; + uint32_t period_ns; + uint8_t running; + uint8_t capturing; + uint8_t channels; + uint8_t reserved_; +} emb_drv_pwm_data_t; + +/* A PWM driver's operations: the device's, then a channel's output set at a period and a pulse, + * rounded to the nearest the hardware makes and reported in @got, its output stopped, and an + * input captured. set() and stop() run with interrupts locked; set() refuses a period beyond + * the hardware's reach with EMB_EINVAL. capture() runs in the caller's thread under the + * device's lock, NULL where the driver captures nothing; it refuses a channel it cannot capture + * on with EMB_ENOTSUP, and gives EMB_ENOSIGNAL when no whole cycle came within @timeout. */ +typedef struct emb_drv_pwm_api { + emb_device_api_t dev; + emb_status_t (*set)(const emb_device_t *dev, uint8_t channel, uint32_t period_ns, + uint32_t pulse_ns, uint32_t flags, emb_drv_pwm_wave_t *got); + void (*stop)(const emb_device_t *dev, uint8_t channel); + emb_status_t (*capture)(const emb_device_t *dev, uint8_t channel, emb_drv_pwm_wave_t *wave, + emb_timeout_t timeout); + uint8_t channels; /* the most a device of the driver has */ + uint8_t reserved_[3]; +} emb_drv_pwm_api_t; + +/** + * emb_drv_pwm_set() - Output a pulse on a channel, every period. + * @dev: A device of the PWM class. + * @channel: Which, from 0. + * @period_ns: The period; the device's other running channels' too. + * @pulse_ns: The pulse's width, at most the period: 0 for a low output, the period for a high + * one (inverted, the reverse). + * @flags: EMB_DRV_PWM_INVERTED, or 0. + * @got: Receives the period and pulse the hardware makes, the nearest to those asked; + * may be NULL. + * + * @ctx thread isr + * @blocks no + * @time O(1) + * @owns none + * @config CONFIG_EMB_DRV_PWM + * @req DRV-001 + * @since 0.3 + * @stable no + * + * A running channel takes the new pulse at its next period, without a glitch. + * + * Return: EMB_OK; EMB_EBUSY (another channel runs at another period, or the channel captures); + * EMB_EINVAL (no such channel, a period of 0 or beyond the hardware's reach, or a pulse longer + * than the period); EMB_ESTATE (not READY). + */ +emb_status_t emb_drv_pwm_set(const emb_device_t *dev, uint8_t channel, uint32_t period_ns, + uint32_t pulse_ns, uint32_t flags, emb_drv_pwm_wave_t *got); + +/** + * emb_drv_pwm_stop() - Stop a channel's output. + * @dev: A device of the PWM class. + * @channel: Which. + * + * @ctx thread isr + * @blocks no + * @time O(1) + * @owns none + * @config CONFIG_EMB_DRV_PWM + * @req DRV-001 + * @since 0.3 + * @stable no + * + * Its pin is left at its inactive level: low, or high where it was inverted. + * + * Return: EMB_OK; EMB_ESTATE (it was not running); EMB_EINVAL (no such channel). + */ +emb_status_t emb_drv_pwm_stop(const emb_device_t *dev, uint8_t channel); + +/** + * emb_drv_pwm_capture() - Measure an input's period and pulse. + * @dev: A device of the PWM class with CAP_CAPTURE. + * @channel: The input's channel. + * @wave: Receives its period and the width of its high pulse. + * @timeout: How long to wait for the device and for whole cycles of the input. + * + * @ctx thread + * @blocks yes + * @time O(1) plus the input's cycles: one and a part, or the gate time an averaging driver + * takes, up to @timeout + * @owns none + * @config CONFIG_EMB_DRV_PWM + * @req DRV-001 + * @since 0.3 + * @stable no + * + * Without CAP_CAPTURE_AVERAGED one cycle is measured exactly, at the timer's clock. With it, the + * period and the pulse are averages over the cycles that fit in the driver's gate time, a + * fraction of @timeout. An input that stays high or low has no cycle. + * + * Return: EMB_OK; EMB_ENOSIGNAL (no whole cycle came within @timeout); EMB_ETIMEDOUT (the device + * stayed taken); EMB_ENOTSUP (no capture, or not on this channel); EMB_EBUSY (the channel + * outputs); EMB_EINVAL (no such channel); EMB_ESTATE (not READY). + */ +emb_status_t emb_drv_pwm_capture(const emb_device_t *dev, uint8_t channel, emb_drv_pwm_wave_t *wave, + emb_timeout_t timeout); + +/** + * emb_drv_pwm_channels() - The device's channels. + * @dev: A device of the PWM class. + * @count: Receives how many; channels are numbered from 0. + * + * @ctx thread isr prekernel + * @blocks no + * @time O(1) + * @owns none + * @config CONFIG_EMB_DRV_PWM + * @req DRV-001 + * @since 0.3 + * @stable no + * + * Return: EMB_OK. + */ +emb_status_t emb_drv_pwm_channels(const emb_device_t *dev, uint8_t *count); + +/** + * emb_drv_pwm_started() - For drivers, at the end of init(): the class's part of the RAM made + * ready, its lock made, no channel running. + * @dev: A device of the PWM class. + * @channels: The device's channels; 0 for the driver's most (its operations' channels). + * + * @ctx thread + * @blocks no + * @time O(1) + * @owns none + * @config CONFIG_EMB_DRV_PWM + * @req DRV-001 + * @since 0.3 + * @stable no + * + * Return: EMB_OK; what making the lock returns otherwise. + */ +emb_status_t emb_drv_pwm_started(const emb_device_t *dev, uint8_t channels); + +#ifdef __cplusplus +} +#endif + +#endif /* EMB_DRV_PWM_H */ diff --git a/include/emb/emb.h b/include/emb/emb.h index bc4d18d0..42e1846f 100644 --- a/include/emb/emb.h +++ b/include/emb/emb.h @@ -29,11 +29,14 @@ #include #endif #if CONFIG_EMB_DRV_SPI +#include +#include #include #include #include #include #include +#include #include #include #include diff --git a/include/emb/status.h b/include/emb/status.h index 64cd417d..786c9996 100644 --- a/include/emb/status.h +++ b/include/emb/status.h @@ -47,7 +47,7 @@ enum emb_status_code { EMB_EINTR = -17, /* reserved; not returned in 1.0 */ EMB_EDEADLK = -32, /* the lock would complete a cycle; first kernel-reserved code (SPEC-005 §3.1) */ - /* the driver classes' codes, four per class (SPEC-017 §3, DRV-008); -96 to -127 later */ + /* the driver classes' codes, four per class (SPEC-017 §3, DRV-008); -108 to -127 later */ EMB_EFRAMING = -64, /* UART: a character without its stop bit */ EMB_EPARITY = -65, /* UART: a parity error */ EMB_EOVERRUN = -66, /* UART: bytes lost, the receiver or its ring full */ @@ -63,6 +63,8 @@ enum emb_status_code { EMB_ENOTSET = -88, /* RTC: the time was never set since power-up */ EMB_EOSCFAIL = -89, /* RTC: its oscillator stopped */ EMB_EHEALTH = -92, /* entropy: the source failed its health test */ + EMB_EPAST = -96, /* counter: the alarm's count has already passed (A129) */ + EMB_ENOSIGNAL = -100, /* PWM: no signal to capture before the timeout (A129) */ EMB_EAPP_BASE = -128 /* application-defined codes from here down to -255 */ }; diff --git a/include/emb/task.h b/include/emb/task.h index a3f48986..3a0f9f57 100644 --- a/include/emb/task.h +++ b/include/emb/task.h @@ -83,7 +83,7 @@ typedef struct emb_task_desc { uint8_t reserved_; } emb_task_desc_t; -/* A task's own state, first in the generated _t. */ +/* A task's own state: the generated _task, its handle _TASK (A130). */ typedef struct emb_task { const emb_task_desc_t *desc; emb_task_stats_t stats; /* lock domain: the critical section */ diff --git a/kernel/CMakeLists.txt b/kernel/CMakeLists.txt index 644a7103..46d33c33 100644 --- a/kernel/CMakeLists.txt +++ b/kernel/CMakeLists.txt @@ -75,6 +75,15 @@ if(CONFIG_EMB_DEVICE) if(CONFIG_EMB_DRV_ENTROPY) list(APPEND EMB_KERNEL_SOURCES device/entropy.c device/sha256.c) # conditioned by SHA-256 endif() + if(CONFIG_EMB_DRV_ADC) + list(APPEND EMB_KERNEL_SOURCES device/adc.c) + endif() + if(CONFIG_EMB_DRV_COUNTER) + list(APPEND EMB_KERNEL_SOURCES device/counter.c) + endif() + if(CONFIG_EMB_DRV_PWM) + list(APPEND EMB_KERNEL_SOURCES device/pwm.c) + endif() if(CONFIG_EMB_DRV_RTC) list(APPEND EMB_KERNEL_SOURCES device/rtc.c) endif() diff --git a/kernel/Kconfig b/kernel/Kconfig index 6268cd9e..70faf802 100644 --- a/kernel/Kconfig +++ b/kernel/Kconfig @@ -329,6 +329,33 @@ config EMB_DRV_RTC alarm, and backup registers where the part has them. With the wall clock, a set RTC seeds it when the device starts. +config EMB_DRV_COUNTER + bool "The counter class (SPEC-017 §11a, A129)" + depends on EMB_DEVICE + default y + help + A free-running counter at a known rate, widened to 64 bits: one-shot + alarms on its channels and periodic callbacks without drift, each in + the counter's interrupt. + +config EMB_DRV_PWM + bool "The PWM class (SPEC-017 §11b, A129)" + depends on EMB_DEVICE + default y + help + Output channels set by period and pulse in nanoseconds, the channels + of a device sharing its period; and an input's period and pulse + measured, one cycle exactly or averaged over many. + +config EMB_DRV_ADC + bool "The ADC class (SPEC-017 §11c, A129)" + depends on EMB_DEVICE + default y + help + One conversion of an input, its millivolts against the board's + reference, the internal temperature sensor; and a sequence of inputs + sampled at a rate into a buffer by DMA, a callback at each half. + config EMB_DRV_ENTROPY bool "The entropy class (SPEC-017 §11)" depends on EMB_DEVICE diff --git a/kernel/device/adc.c b/kernel/device/adc.c new file mode 100644 index 00000000..89612a9b --- /dev/null +++ b/kernel/device/adc.c @@ -0,0 +1,242 @@ +/* SPDX-License-Identifier: Apache-2.0 */ +/* Copyright 2026 Junior Deogracias */ +/* + * This file is part of EmbLinkRTOS, a deterministic real-time kernel for microcontrollers. + * Licensed under the Apache License, Version 2.0; see the LICENSE file at the repository root. + */ + +/** + * @file adc.c + * @brief The ADC class (SPEC-017 §11c, A129). + * + * @details + * Its checks over a driver's operations: the hardware a conversion's or a sampling's, never both; + * readers queued on the device's lock; a count's millivolts; a sampling's halves handed to its + * callback. + * + * @author teo1747 + * @date 2026-11-13 (created) + */ +#include + +#include +#include + +static bool is_adc(const emb_device_t *dev) +{ + return (dev != NULL) && (dev->api != NULL) && (dev->class_id == EMB_DRV_CLASS_ADC) && + (dev->data != NULL); +} + +/* The class's operations: the device's first. MISRA Dev CS-12: rule 11.3. */ +static const emb_drv_adc_api_t *adc_api(const emb_device_t *dev) +{ + return (const emb_drv_adc_api_t *)(const void *)dev->api; +} + +/* The class's part of the driver's RAM, its first member. MISRA Dev CS-12: rule 11.5. */ +static emb_drv_adc_data_t *adc_part(const emb_device_t *dev) +{ + return (emb_drv_adc_data_t *)dev->data; +} + +/* The hardware taken for one conversion: refused while another converts or a sampling runs. */ +static emb_status_t adc_claim(emb_drv_adc_data_t *d) +{ + emb_status_t st = EMB_OK; + emb_irq_key_t key = embk_irq_lock(); + if ((d->busy != 0u) || (d->sampling != 0u)) { + st = EMB_EBUSY; + } else { + d->busy = 1u; + } + embk_irq_unlock(key); + return st; +} + +static void adc_release(emb_drv_adc_data_t *d) +{ + emb_irq_key_t key = embk_irq_lock(); + d->busy = 0u; + embk_irq_unlock(key); +} + +static emb_status_t adc_convert(const emb_device_t *dev, uint8_t input, uint16_t *count) +{ + emb_drv_adc_data_t *d = adc_part(dev); + emb_status_t st = adc_claim(d); + if (st == EMB_OK) { + st = adc_api(dev)->read(dev, input, count); + adc_release(d); + } + return st; +} + +emb_status_t emb_drv_adc_read(const emb_device_t *dev, uint8_t input, uint16_t *count, + emb_timeout_t timeout) +{ + emb_drv_adc_data_t *d; + emb_status_t st; + EMBK_API_REQUIRE(EMB_API_ID_DRV_ADC_READ, is_adc(dev) && (count != NULL), + EMB_FAULT_API_ARGUMENT, EMB_EINVAL, 1u); + EMBK_API_REQUIRE_THREAD(EMB_API_ID_DRV_ADC_READ); + if (!emb_device_ready(dev)) { + return EMB_ESTATE; + } + d = adc_part(dev); + st = embk_bus_enter(&d->lock, NULL, timeout); /* readers queue here */ + if (st != EMB_OK) { + return st; + } + st = adc_convert(dev, input, count); + embk_bus_exit(&d->lock); + return st; +} + +emb_status_t emb_drv_adc_read_polled(const emb_device_t *dev, uint8_t input, uint16_t *count) +{ + EMBK_API_REQUIRE(EMB_API_ID_DRV_ADC_READ_POLLED, is_adc(dev) && (count != NULL), + EMB_FAULT_API_ARGUMENT, EMB_EINVAL, 1u); + if (!emb_device_ready(dev)) { + return EMB_ESTATE; + } + return adc_convert(dev, input, count); +} + +emb_status_t emb_drv_adc_to_mv(const emb_device_t *dev, uint16_t count, uint32_t *mv) +{ + uint32_t top; + EMBK_API_REQUIRE(EMB_API_ID_DRV_ADC_TO_MV, is_adc(dev) && (mv != NULL), EMB_FAULT_API_ARGUMENT, + EMB_EINVAL, 1u); + top = ((uint32_t)1u << adc_api(dev)->bits) - 1u; + if (count > top) { + return EMB_EINVAL; + } + *mv = (uint32_t)((((uint64_t)count * adc_api(dev)->vref_mv(dev)) + (top / 2u)) / top); + return EMB_OK; +} + +emb_status_t emb_drv_adc_temperature(const emb_device_t *dev, int32_t *mdegc, emb_timeout_t timeout) +{ + uint16_t count = 0u; + emb_status_t st; + EMBK_API_REQUIRE(EMB_API_ID_DRV_ADC_TEMPERATURE, is_adc(dev) && (mdegc != NULL), + EMB_FAULT_API_ARGUMENT, EMB_EINVAL, 1u); + EMBK_API_REQUIRE_THREAD(EMB_API_ID_DRV_ADC_TEMPERATURE); + if (((emb_device_caps(dev) & EMB_DRV_ADC_CAP_TEMPERATURE) == 0u) || + (adc_api(dev)->to_mdegc == NULL)) { + return EMB_ENOTSUP; + } + st = emb_drv_adc_read(dev, EMB_DRV_ADC_TEMPERATURE, &count, timeout); + if (st == EMB_OK) { + st = adc_api(dev)->to_mdegc(dev, count, mdegc); + } + return st; +} + +emb_status_t emb_drv_adc_sample_start(const emb_device_t *dev, const emb_drv_adc_sampling_t *s) +{ + emb_drv_adc_data_t *d; + emb_irq_key_t key; + emb_status_t st = EMB_OK; + EMBK_API_REQUIRE(EMB_API_ID_DRV_ADC_SAMPLE_START, + is_adc(dev) && (s != NULL) && (s->fn != NULL) && (s->buffer != NULL) && + (s->inputs != NULL), + EMB_FAULT_API_ARGUMENT, EMB_EINVAL, 1u); + EMBK_API_REQUIRE_THREAD(EMB_API_ID_DRV_ADC_SAMPLE_START); + if (!emb_device_ready(dev)) { + return EMB_ESTATE; + } + if (((emb_device_caps(dev) & EMB_DRV_ADC_CAP_SAMPLE) == 0u) || + (adc_api(dev)->sample_start == NULL)) { + return EMB_ENOTSUP; + } + if ((s->count == 0u) || (s->count > EMB_DRV_ADC_SEQUENCE_MAX) || (s->rate_hz == 0u) || + (s->length < (2u * s->count)) || ((s->length % (2u * (uint32_t)s->count)) != 0u)) { + return EMB_EINVAL; /* each half a whole number of sequences */ + } + d = adc_part(dev); + key = embk_irq_lock(); + if ((d->busy != 0u) || (d->sampling != 0u)) { + st = EMB_EBUSY; + } else { + d->fn = s->fn; + d->arg = s->arg; + d->buffer = s->buffer; + d->length = s->length; + d->sampling = 1u; + } + embk_irq_unlock(key); + if (st == EMB_OK) { + st = adc_api(dev)->sample_start(dev, s); + if (st != EMB_OK) { + key = embk_irq_lock(); + d->sampling = 0u; + embk_irq_unlock(key); + } + } + return st; +} + +emb_status_t emb_drv_adc_sample_stop(const emb_device_t *dev) +{ + emb_drv_adc_data_t *d; + emb_irq_key_t key; + emb_status_t st = EMB_ESTATE; + EMBK_API_REQUIRE(EMB_API_ID_DRV_ADC_SAMPLE_STOP, is_adc(dev), EMB_FAULT_API_ARGUMENT, + EMB_EINVAL, 1u); + d = adc_part(dev); + key = embk_irq_lock(); + if (d->sampling != 0u) { + d->sampling = 0u; /* first: a half reported meanwhile is dropped */ + adc_api(dev)->sample_stop(dev); + st = EMB_OK; + } + embk_irq_unlock(key); + return st; +} + +emb_status_t emb_drv_adc_started(const emb_device_t *dev) +{ + emb_drv_adc_data_t *d; + EMBK_API_REQUIRE(EMB_API_ID_DRV_ADC_STARTED, is_adc(dev), EMB_FAULT_API_ARGUMENT, EMB_EINVAL, + 1u); + d = adc_part(dev); + d->fn = NULL; + d->arg = NULL; + d->buffer = NULL; + d->length = 0u; + d->busy = 0u; + d->sampling = 0u; + return embk_bus_init(&d->lock, dev->name); +} + +emb_status_t emb_drv_adc_sampled(const emb_device_t *dev, uint8_t half, emb_status_t status) +{ + emb_drv_adc_data_t *d; + emb_drv_adc_fn_t fn = NULL; + void *arg = NULL; + const uint16_t *samples = NULL; + uint32_t count = 0u; + emb_irq_key_t key; + EMBK_API_REQUIRE(EMB_API_ID_DRV_ADC_SAMPLED, is_adc(dev) && (half <= 1u), + EMB_FAULT_API_ARGUMENT, EMB_EINVAL, 1u); + d = adc_part(dev); + key = embk_irq_lock(); + if (d->sampling != 0u) { + fn = d->fn; + arg = d->arg; + if (status == EMB_OK) { + count = d->length / 2u; + samples = &d->buffer[(half != 0u) ? count : 0u]; + } else { + d->sampling = 0u; /* the hardware ended it */ + } + } + embk_irq_unlock(key); + if (fn == NULL) { + return EMB_ESTATE; + } + fn(arg, samples, count, status); + return EMB_OK; +} diff --git a/kernel/device/counter.c b/kernel/device/counter.c new file mode 100644 index 00000000..60b3b006 --- /dev/null +++ b/kernel/device/counter.c @@ -0,0 +1,247 @@ +/* SPDX-License-Identifier: Apache-2.0 */ +/* Copyright 2026 Junior Deogracias */ +/* + * This file is part of EmbLinkRTOS, a deterministic real-time kernel for microcontrollers. + * Licensed under the Apache License, Version 2.0; see the LICENSE file at the repository root. + */ + +/** + * @file counter.c + * @brief The counter class (SPEC-017 §11a, A129). + * + * @details + * Its checks over a driver's operations, each channel's one-shot or periodic alarm, and a + * periodic alarm's next period armed without drift. + * + * @author teo1747 + * @date 2026-11-13 (created) + */ +#include + +#include + +/* The tries at arming a periodic alarm's next period, each a period later, before it stops: a + * period shorter than the counter's interrupt takes cannot be kept. */ +#define PERIODIC_TRIES 4u + +static bool is_counter(const emb_device_t *dev) +{ + return (dev != NULL) && (dev->api != NULL) && (dev->class_id == EMB_DRV_CLASS_COUNTER) && + (dev->data != NULL); +} + +/* The class's operations: the device's first. MISRA Dev CS-12: rule 11.3. */ +static const emb_drv_counter_api_t *counter_api(const emb_device_t *dev) +{ + return (const emb_drv_counter_api_t *)(const void *)dev->api; +} + +/* The class's part of the driver's RAM, its first member. MISRA Dev CS-12: rule 11.5. */ +static emb_drv_counter_data_t *counter_part(const emb_device_t *dev) +{ + return (emb_drv_counter_data_t *)dev->data; +} + +static bool counter_has_channel(const emb_device_t *dev, uint8_t channel) +{ + return channel < counter_part(dev)->channels; +} + +/* Arm a channel's alarm, interrupts locked: its callback, its count and its period. */ +static emb_status_t counter_arm_locked(const emb_device_t *dev, uint8_t channel, uint64_t at, + uint64_t period, emb_drv_counter_fn_t fn, void *arg) +{ + emb_drv_counter_alarm_t *a = &counter_part(dev)->alarm[channel]; + emb_status_t st; + if (a->armed != 0u) { + return EMB_EBUSY; + } + a->fn = fn; + a->arg = arg; + a->at = at; + a->period = period; + a->armed = 1u; + st = counter_api(dev)->arm(dev, channel, at); + if (st != EMB_OK) { + a->armed = 0u; + } + return st; +} + +/* A periodic alarm's next period, interrupts locked: one period after the last was due, or the + * first still to come when the counter's interrupt was held off past some. */ +static void periodic_next(const emb_device_t *dev, uint8_t channel, emb_drv_counter_alarm_t *a) +{ + const emb_drv_counter_api_t *api = counter_api(dev); + uint64_t now = api->now(dev); + uint64_t next = a->at + a->period; + uint32_t tries; + if (next <= now) { + next += (((now - next) / a->period) + 1u) * a->period; /* the periods passed: skipped */ + } + for (tries = 0u; tries < PERIODIC_TRIES; tries++) { /* bounded */ + if (api->arm(dev, channel, next) == EMB_OK) { + a->at = next; + return; + } + next += a->period; /* it passed while it was armed */ + } + a->armed = 0u; /* a period the counter cannot keep: it stops */ +} + +emb_status_t emb_drv_counter_now(const emb_device_t *dev, uint64_t *count) +{ + EMBK_API_REQUIRE(EMB_API_ID_DRV_COUNTER_NOW, is_counter(dev) && (count != NULL), + EMB_FAULT_API_ARGUMENT, EMB_EINVAL, 1u); + if (!emb_device_ready(dev)) { + return EMB_ESTATE; + } + *count = counter_api(dev)->now(dev); + return EMB_OK; +} + +emb_status_t emb_drv_counter_rate(const emb_device_t *dev, uint32_t *hz) +{ + EMBK_API_REQUIRE(EMB_API_ID_DRV_COUNTER_RATE, is_counter(dev) && (hz != NULL), + EMB_FAULT_API_ARGUMENT, EMB_EINVAL, 1u); + if (!emb_device_ready(dev)) { + return EMB_ESTATE; + } + *hz = counter_api(dev)->rate(dev); + return EMB_OK; +} + +emb_status_t emb_drv_counter_channels(const emb_device_t *dev, uint8_t *count) +{ + EMBK_API_REQUIRE(EMB_API_ID_DRV_COUNTER_CHANNELS, is_counter(dev) && (count != NULL), + EMB_FAULT_API_ARGUMENT, EMB_EINVAL, 1u); + *count = counter_part(dev)->channels; + return EMB_OK; +} + +emb_status_t emb_drv_counter_alarm_set(const emb_device_t *dev, uint8_t channel, uint64_t at, + emb_drv_counter_fn_t fn, void *arg) +{ + emb_irq_key_t key; + emb_status_t st; + EMBK_API_REQUIRE(EMB_API_ID_DRV_COUNTER_ALARM_SET, is_counter(dev) && (fn != NULL), + EMB_FAULT_API_ARGUMENT, EMB_EINVAL, 1u); + if (!emb_device_ready(dev)) { + return EMB_ESTATE; + } + if (!counter_has_channel(dev, channel)) { + return EMB_EINVAL; + } + key = embk_irq_lock(); + st = counter_arm_locked(dev, channel, at, 0u, fn, arg); + embk_irq_unlock(key); + return st; +} + +emb_status_t emb_drv_counter_periodic(const emb_device_t *dev, uint8_t channel, uint64_t period, + emb_drv_counter_fn_t fn, void *arg) +{ + emb_irq_key_t key; + emb_status_t st; + EMBK_API_REQUIRE(EMB_API_ID_DRV_COUNTER_PERIODIC, is_counter(dev) && (fn != NULL), + EMB_FAULT_API_ARGUMENT, EMB_EINVAL, 1u); + if (!emb_device_ready(dev)) { + return EMB_ESTATE; + } + if (!counter_has_channel(dev, channel) || (period < 2u)) { + return EMB_EINVAL; + } + key = embk_irq_lock(); + st = counter_arm_locked(dev, channel, counter_api(dev)->now(dev) + period, period, fn, arg); + embk_irq_unlock(key); + return st; +} + +/* Disarm a channel's alarm of one kind: one-shot (periodic false) or periodic. */ +static emb_status_t counter_disarm(const emb_device_t *dev, uint8_t channel, bool periodic) +{ + emb_drv_counter_alarm_t *a; + emb_irq_key_t key; + emb_status_t st = EMB_ESTATE; + if (!counter_has_channel(dev, channel)) { + return EMB_EINVAL; + } + a = &counter_part(dev)->alarm[channel]; + key = embk_irq_lock(); + if ((a->armed != 0u) && (periodic ? (a->period != 0u) : (a->period == 0u))) { + a->armed = 0u; + counter_api(dev)->disarm(dev, channel); + st = EMB_OK; + } + embk_irq_unlock(key); + return st; +} + +emb_status_t emb_drv_counter_alarm_cancel(const emb_device_t *dev, uint8_t channel) +{ + EMBK_API_REQUIRE(EMB_API_ID_DRV_COUNTER_ALARM_CANCEL, is_counter(dev), EMB_FAULT_API_ARGUMENT, + EMB_EINVAL, 1u); + return counter_disarm(dev, channel, false); +} + +emb_status_t emb_drv_counter_periodic_stop(const emb_device_t *dev, uint8_t channel) +{ + EMBK_API_REQUIRE(EMB_API_ID_DRV_COUNTER_PERIODIC_STOP, is_counter(dev), EMB_FAULT_API_ARGUMENT, + EMB_EINVAL, 1u); + return counter_disarm(dev, channel, true); +} + +emb_status_t emb_drv_counter_started(const emb_device_t *dev, uint8_t channels) +{ + emb_drv_counter_data_t *d; + uint8_t most; + uint32_t i; + EMBK_API_REQUIRE(EMB_API_ID_DRV_COUNTER_STARTED, is_counter(dev), EMB_FAULT_API_ARGUMENT, + EMB_EINVAL, 1u); + d = counter_part(dev); + most = counter_api(dev)->channels; + if (most > EMB_DRV_COUNTER_CHANNELS_MAX) { + most = (uint8_t)EMB_DRV_COUNTER_CHANNELS_MAX; + } + d->channels = ((channels == 0u) || (channels > most)) ? most : channels; + for (i = 0u; i < EMB_DRV_COUNTER_CHANNELS_MAX; i++) { /* bounded */ + d->alarm[i].fn = NULL; + d->alarm[i].arg = NULL; + d->alarm[i].at = 0u; + d->alarm[i].period = 0u; + d->alarm[i].armed = 0u; + } + return EMB_OK; +} + +emb_status_t emb_drv_counter_fired(const emb_device_t *dev, uint8_t channel) +{ + emb_drv_counter_alarm_t *a; + emb_drv_counter_fn_t fn = NULL; + void *arg = NULL; + uint64_t at = 0u; + emb_irq_key_t key; + EMBK_API_REQUIRE(EMB_API_ID_DRV_COUNTER_FIRED, is_counter(dev), EMB_FAULT_API_ARGUMENT, + EMB_EINVAL, 1u); + if (!counter_has_channel(dev, channel)) { + return EMB_EINVAL; + } + a = &counter_part(dev)->alarm[channel]; + key = embk_irq_lock(); + if (a->armed != 0u) { + fn = a->fn; + arg = a->arg; + at = a->at; + if (a->period == 0u) { + a->armed = 0u; /* first: the callback may arm it again */ + } else { + periodic_next(dev, channel, a); /* first: the callback may stop it */ + } + } + embk_irq_unlock(key); + if (fn == NULL) { + return EMB_ESTATE; + } + fn(arg, at); + return EMB_OK; +} diff --git a/kernel/device/dma.c b/kernel/device/dma.c index a16c7194..3d7cde51 100644 --- a/kernel/device/dma.c +++ b/kernel/device/dma.c @@ -81,6 +81,15 @@ emb_status_t emb_drv_dma_start(const emb_drv_dma_chan_t *ch, const emb_drv_dma_j ((emb_device_caps(ch->dma) & EMB_DRV_DMA_CAP_MEM_TO_MEM) == 0u)) { return EMB_ENOTSUP; } + if ((job->flags & EMB_DRV_DMA_CIRCULAR) != 0u) { /* A129 */ + if ((emb_device_caps(ch->dma) & EMB_DRV_DMA_CAP_CIRCULAR) == 0u) { + return EMB_ENOTSUP; + } + if ((job->dir == EMB_DRV_DMA_MEM_TO_MEM) || ((job->flags & EMB_DRV_DMA_FIXED_MEM) != 0u) || + (job->count < 2u) || ((job->count % 2u) != 0u)) { + return EMB_EINVAL; /* a peripheral's and memory that advances, in two halves */ + } + } if (!memory_ok(job)) { return EMB_EINVAL; /* the hardware cannot reach it, or must not (SPEC-017 §7) */ } diff --git a/kernel/device/pwm.c b/kernel/device/pwm.c new file mode 100644 index 00000000..d426e4d8 --- /dev/null +++ b/kernel/device/pwm.c @@ -0,0 +1,166 @@ +/* SPDX-License-Identifier: Apache-2.0 */ +/* Copyright 2026 Junior Deogracias */ +/* + * This file is part of EmbLinkRTOS, a deterministic real-time kernel for microcontrollers. + * Licensed under the Apache License, Version 2.0; see the LICENSE file at the repository root. + */ + +/** + * @file pwm.c + * @brief The PWM class (SPEC-017 §11b, A129). + * + * @details + * Its checks over a driver's operations: the period a device's running channels share, a + * channel outputting or capturing but not both, and a capture under the device's lock. + * + * @author teo1747 + * @date 2026-11-13 (created) + */ +#include + +#include +#include + +static bool is_pwm(const emb_device_t *dev) +{ + return (dev != NULL) && (dev->api != NULL) && (dev->class_id == EMB_DRV_CLASS_PWM) && + (dev->data != NULL); +} + +/* The class's operations: the device's first. MISRA Dev CS-12: rule 11.3. */ +static const emb_drv_pwm_api_t *pwm_api(const emb_device_t *dev) +{ + return (const emb_drv_pwm_api_t *)(const void *)dev->api; +} + +/* The class's part of the driver's RAM, its first member. MISRA Dev CS-12: rule 11.5. */ +static emb_drv_pwm_data_t *pwm_part(const emb_device_t *dev) +{ + return (emb_drv_pwm_data_t *)dev->data; +} + +static uint8_t bit_of(uint8_t channel) +{ + return (uint8_t)((uint32_t)1u << channel); +} + +emb_status_t emb_drv_pwm_set(const emb_device_t *dev, uint8_t channel, uint32_t period_ns, + uint32_t pulse_ns, uint32_t flags, emb_drv_pwm_wave_t *got) +{ + emb_drv_pwm_data_t *d; + emb_irq_key_t key; + emb_status_t st; + EMBK_API_REQUIRE(EMB_API_ID_DRV_PWM_SET, + is_pwm(dev) && ((flags & ~(uint32_t)EMB_DRV_PWM_INVERTED) == 0u), + EMB_FAULT_API_ARGUMENT, EMB_EINVAL, 1u); + if (!emb_device_ready(dev)) { + return EMB_ESTATE; + } + d = pwm_part(dev); + if ((channel >= d->channels) || (period_ns == 0u) || (pulse_ns > period_ns)) { + return EMB_EINVAL; + } + key = embk_irq_lock(); + /* the device's period is its running channels'; a capturing channel cannot output */ + if ((((d->running & (uint8_t)~bit_of(channel)) != 0u) && (period_ns != d->period_ns)) || + ((d->capturing & bit_of(channel)) != 0u)) { + st = EMB_EBUSY; + } else { + st = pwm_api(dev)->set(dev, channel, period_ns, pulse_ns, flags, got); + if (st == EMB_OK) { + d->running |= bit_of(channel); + d->period_ns = period_ns; + } + } + embk_irq_unlock(key); + return st; +} + +emb_status_t emb_drv_pwm_stop(const emb_device_t *dev, uint8_t channel) +{ + emb_drv_pwm_data_t *d; + emb_irq_key_t key; + emb_status_t st = EMB_ESTATE; + EMBK_API_REQUIRE(EMB_API_ID_DRV_PWM_STOP, is_pwm(dev), EMB_FAULT_API_ARGUMENT, EMB_EINVAL, 1u); + d = pwm_part(dev); + if (channel >= d->channels) { + return EMB_EINVAL; + } + key = embk_irq_lock(); + if ((d->running & bit_of(channel)) != 0u) { + pwm_api(dev)->stop(dev, channel); + d->running &= (uint8_t)~bit_of(channel); + st = EMB_OK; + } + embk_irq_unlock(key); + return st; +} + +emb_status_t emb_drv_pwm_capture(const emb_device_t *dev, uint8_t channel, emb_drv_pwm_wave_t *wave, + emb_timeout_t timeout) +{ + emb_drv_pwm_data_t *d; + emb_instant_t start; + emb_irq_key_t key; + emb_status_t st; + EMBK_API_REQUIRE(EMB_API_ID_DRV_PWM_CAPTURE, is_pwm(dev) && (wave != NULL), + EMB_FAULT_API_ARGUMENT, EMB_EINVAL, 1u); + EMBK_API_REQUIRE_THREAD(EMB_API_ID_DRV_PWM_CAPTURE); + if (!emb_device_ready(dev)) { + return EMB_ESTATE; + } + d = pwm_part(dev); + if (channel >= d->channels) { + return EMB_EINVAL; + } + if ((pwm_api(dev)->capture == NULL) || + ((emb_device_caps(dev) & EMB_DRV_PWM_CAP_CAPTURE) == 0u)) { + return EMB_ENOTSUP; + } + start = emb_time_now(); + st = embk_bus_enter(&d->lock, NULL, timeout); + if (st != EMB_OK) { + return st; + } + key = embk_irq_lock(); + if ((d->running & bit_of(channel)) != 0u) { + st = EMB_EBUSY; /* it outputs */ + } else { + d->capturing |= bit_of(channel); + } + embk_irq_unlock(key); + if (st == EMB_OK) { + st = pwm_api(dev)->capture(dev, channel, wave, embk_bus_time_left(timeout, start)); + key = embk_irq_lock(); + d->capturing &= (uint8_t)~bit_of(channel); + embk_irq_unlock(key); + } + embk_bus_exit(&d->lock); + return st; +} + +emb_status_t emb_drv_pwm_channels(const emb_device_t *dev, uint8_t *count) +{ + EMBK_API_REQUIRE(EMB_API_ID_DRV_PWM_CHANNELS, is_pwm(dev) && (count != NULL), + EMB_FAULT_API_ARGUMENT, EMB_EINVAL, 1u); + *count = pwm_part(dev)->channels; + return EMB_OK; +} + +emb_status_t emb_drv_pwm_started(const emb_device_t *dev, uint8_t channels) +{ + emb_drv_pwm_data_t *d; + uint8_t most; + EMBK_API_REQUIRE(EMB_API_ID_DRV_PWM_STARTED, is_pwm(dev), EMB_FAULT_API_ARGUMENT, EMB_EINVAL, + 1u); + d = pwm_part(dev); + most = pwm_api(dev)->channels; + if (most > EMB_DRV_PWM_CHANNELS_MAX) { + most = (uint8_t)EMB_DRV_PWM_CHANNELS_MAX; + } + d->channels = ((channels == 0u) || (channels > most)) ? most : channels; + d->period_ns = 0u; + d->running = 0u; + d->capturing = 0u; + return embk_bus_init(&d->lock, dev->name); +} diff --git a/kernel/exec/exec.c b/kernel/exec/exec.c index 92f506a7..fa81c490 100644 --- a/kernel/exec/exec.c +++ b/kernel/exec/exec.c @@ -352,24 +352,27 @@ const char *emb_status_name(emb_status_t status) if (status <= 0 && status >= -17) { return names[-status]; } + /* four codes a class, a row each */ + /* clang-format off */ static const char *const drivers[] = { - /* -64 to -95, SPEC-017 §3; NULL where no class has a code yet */ - "EMB_EFRAMING", "EMB_EPARITY", "EMB_EOVERRUN", - NULL, "EMB_ECRC", "EMB_EMODEFAULT", - NULL, NULL, "EMB_ENACK", - "EMB_EARBLOST", "EMB_EBUSERR", NULL, - "EMB_EXFER", NULL, NULL, - NULL, "EMB_EWINDOW", NULL, - NULL, NULL, "EMB_EWRPROT", - "EMB_EVERIFY", NULL, NULL, - "EMB_ENOTSET", "EMB_EOSCFAIL", NULL, - NULL, "EMB_EHEALTH", NULL, - NULL, NULL, + /* -64 to -107, SPEC-017 §3; NULL where no class has a code yet */ + "EMB_EFRAMING", "EMB_EPARITY", "EMB_EOVERRUN", NULL, /* UART */ + "EMB_ECRC", "EMB_EMODEFAULT", NULL, NULL, /* SPI */ + "EMB_ENACK", "EMB_EARBLOST", "EMB_EBUSERR", NULL, /* I2C */ + "EMB_EXFER", NULL, NULL, NULL, /* DMA */ + "EMB_EWINDOW", NULL, NULL, NULL, /* watchdog */ + "EMB_EWRPROT", "EMB_EVERIFY", NULL, NULL, /* flash */ + "EMB_ENOTSET", "EMB_EOSCFAIL", NULL, NULL, /* RTC */ + "EMB_EHEALTH", NULL, NULL, NULL, /* entropy */ + "EMB_EPAST", NULL, NULL, NULL, /* counter */ + "EMB_ENOSIGNAL", NULL, NULL, NULL, /* PWM */ + NULL, NULL, NULL, NULL, /* ADC */ }; + /* clang-format on */ if (status == EMB_EDEADLK) { return "EMB_EDEADLK"; } - if (status <= -64 && status >= -95 && drivers[-status - 64] != NULL) { + if (status <= -64 && status >= -107 && drivers[-status - 64] != NULL) { return drivers[-status - 64]; } return "EMB_E?"; diff --git a/soc/arm/mps2/CMakeLists.txt b/soc/arm/mps2/CMakeLists.txt index f0d9bb28..928e8b88 100644 --- a/soc/arm/mps2/CMakeLists.txt +++ b/soc/arm/mps2/CMakeLists.txt @@ -12,5 +12,5 @@ add_library(emb_board STATIC board.c "${EMB_BASE}/drivers/arm/cmsdk_uart.c" ${EM target_include_directories(emb_board PUBLIC ${EMB_BOARD_INCLUDE_DIRS} "${EMB_BASE}/drivers/arm/include" ${EMB_BOARD_DRIVER_INCLUDE_DIRS}) target_link_libraries(emb_board PUBLIC emb_api PRIVATE emb_flags INTERFACE emb_arch) # the semihosting exit -set(EMB_BOARD_LINKER_SCRIPT "${EMB_BOARD_DIR}/linker/regions.ld" CACHE INTERNAL "board linker script") +set(EMB_BOARD_LINKER_SCRIPT "${EMB_BOARD_LINKER_DIR}/regions.ld" CACHE INTERNAL "board linker script") target_link_options(emb_board INTERFACE "-T${EMB_BOARD_LINKER_SCRIPT}") diff --git a/soc/microchip/atmega/CMakeLists.txt b/soc/microchip/atmega/CMakeLists.txt index 2ed04483..9c6fd2af 100644 --- a/soc/microchip/atmega/CMakeLists.txt +++ b/soc/microchip/atmega/CMakeLists.txt @@ -6,11 +6,12 @@ # emb_board for an ATmega board described in YAML (SPEC-014): the family's board support and # drivers, compiled against the board's generated hw_config.h, with its generated linker script. -# EMB_BOARD_DIR is the board's generated/ directory (A126: src/, linker/). +# EMB_BOARD_DIR is the board's generated/ directory (A126: src/, linker/; an application's +# src/config//, A130: EMB_BOARD_SRC_DIR, EMB_BOARD_LINKER_DIR). add_library(emb_board STATIC board.c ${EMB_BOARD_DRIVER_SOURCES}) # its drivers are inline (drivers/microchip/include) target_include_directories(emb_board PUBLIC ${EMB_BOARD_INCLUDE_DIRS} ${EMB_BOARD_DRIVER_INCLUDE_DIRS} PRIVATE "${EMB_BASE}/drivers/microchip/include") target_link_libraries(emb_board PUBLIC emb_api PRIVATE emb_flags) # The generated linker script brackets the kernel's flash tables (SPEC-012 §8). -set(EMB_BOARD_LINKER_SCRIPT "${EMB_BOARD_DIR}/linker/regions.ld" CACHE INTERNAL "board linker script") +set(EMB_BOARD_LINKER_SCRIPT "${EMB_BOARD_LINKER_DIR}/regions.ld" CACHE INTERNAL "board linker script") target_link_options(emb_board INTERFACE "-T${EMB_BOARD_LINKER_SCRIPT}") diff --git a/soc/nordic/nrf51/CMakeLists.txt b/soc/nordic/nrf51/CMakeLists.txt index 19f75f0d..4623c233 100644 --- a/soc/nordic/nrf51/CMakeLists.txt +++ b/soc/nordic/nrf51/CMakeLists.txt @@ -4,11 +4,12 @@ # This file is part of EmbLinkRTOS, a deterministic real-time kernel for microcontrollers. # Licensed under the Apache License, Version 2.0; see the LICENSE file at the repository root. -# emb_board for an nRF51 board described in YAML (A86): the family's board support, compiled -# against the board's generated hw_config.h, with its generated linker script. -# EMB_BOARD_DIR is the board's generated/ directory (A126: src/, linker/). +# emb_board for an nRF51 board described in YAML (A86): the family's board support, compiled against +# the board's generated hw_config.h, with its generated linker script. EMB_BOARD_DIR is the board's +# generated/ directory (A126: src/, linker/; an application's src/config//, A130: +# EMB_BOARD_SRC_DIR, EMB_BOARD_LINKER_DIR). add_library(emb_board STATIC board.c ${EMB_BOARD_DRIVER_SOURCES}) # the board's devices (SPEC-016 §8) target_include_directories(emb_board PUBLIC ${EMB_BOARD_INCLUDE_DIRS} ${EMB_BOARD_DRIVER_INCLUDE_DIRS}) target_link_libraries(emb_board PUBLIC emb_api PRIVATE emb_flags INTERFACE emb_arch) # semihosting -set(EMB_BOARD_LINKER_SCRIPT "${EMB_BOARD_DIR}/linker/regions.ld" CACHE INTERNAL "board linker script") +set(EMB_BOARD_LINKER_SCRIPT "${EMB_BOARD_LINKER_DIR}/regions.ld" CACHE INTERNAL "board linker script") target_link_options(emb_board INTERFACE "-T${EMB_BOARD_LINKER_SCRIPT}") diff --git a/soc/qemu/virt/CMakeLists.txt b/soc/qemu/virt/CMakeLists.txt index 6f2f28cb..16ee2038 100644 --- a/soc/qemu/virt/CMakeLists.txt +++ b/soc/qemu/virt/CMakeLists.txt @@ -4,11 +4,12 @@ # This file is part of EmbLinkRTOS, a deterministic real-time kernel for microcontrollers. # Licensed under the Apache License, Version 2.0; see the LICENSE file at the repository root. -# emb_board for a QEMU RISC-V virt board described in YAML (SPEC-014): the board support, -# compiled against the board's generated hw_config.h, with its generated linker script. -# EMB_BOARD_DIR is the board's generated/ directory (A126: src/, linker/). +# emb_board for a QEMU RISC-V virt board described in YAML (SPEC-014): the board support, compiled +# against the board's generated hw_config.h, with its generated linker script. EMB_BOARD_DIR is the +# board's generated/ directory (A126: src/, linker/; an application's src/config//, A130: +# EMB_BOARD_SRC_DIR, EMB_BOARD_LINKER_DIR). add_library(emb_board STATIC board.c ${EMB_BOARD_DRIVER_SOURCES}) # the board's devices (SPEC-016 §8) target_include_directories(emb_board PUBLIC ${EMB_BOARD_INCLUDE_DIRS} ${EMB_BOARD_DRIVER_INCLUDE_DIRS}) target_link_libraries(emb_board PUBLIC emb_api PRIVATE emb_flags ) -set(EMB_BOARD_LINKER_SCRIPT "${EMB_BOARD_DIR}/linker/regions.ld" CACHE INTERNAL "board linker script") +set(EMB_BOARD_LINKER_SCRIPT "${EMB_BOARD_LINKER_DIR}/regions.ld" CACHE INTERNAL "board linker script") target_link_options(emb_board INTERFACE "-T${EMB_BOARD_LINKER_SCRIPT}") diff --git a/soc/rpi/rp2350/CMakeLists.txt b/soc/rpi/rp2350/CMakeLists.txt index c0835dce..b3b6016d 100644 --- a/soc/rpi/rp2350/CMakeLists.txt +++ b/soc/rpi/rp2350/CMakeLists.txt @@ -4,21 +4,22 @@ # This file is part of EmbLinkRTOS, a deterministic real-time kernel for microcontrollers. # Licensed under the Apache License, Version 2.0; see the LICENSE file at the repository root. -# emb_board for an RP2350 board described in YAML (A79): the family's board support over the -# RP2350 drivers and the PL011's, compiled against the board's generated hw_config.h, with its -# generated pin table and linker script, and the board's devices with the drivers they use -# (SPEC-016 §8). EMB_BOARD_DIR is the board's generated/ directory (A126: src/, linker/). +# emb_board for an RP2350 board described in YAML (A79): the family's board support over the RP2350 +# drivers and the PL011's, compiled against the board's generated hw_config.h, with its generated +# pin table and linker script, and the board's devices with the drivers they use (SPEC-016 §8). +# EMB_BOARD_DIR is the board's generated/ directory (A126: src/, linker/; an application's +# src/config//, A130: EMB_BOARD_SRC_DIR, EMB_BOARD_LINKER_DIR). add_library(emb_board STATIC board.c "${EMB_BASE}/drivers/rpi/rp2350_clocks.c" "${EMB_BASE}/drivers/rpi/rp2350_gpio.c" "${EMB_BASE}/drivers/arm/pl011.c" - "${EMB_BOARD_DIR}/src/board_pins.c" - "${EMB_BOARD_DIR}/src/boot_block.c" + "${EMB_BOARD_SRC_DIR}/board_pins.c" + "${EMB_BOARD_SRC_DIR}/boot_block.c" ${EMB_BOARD_DRIVER_SOURCES}) target_include_directories(emb_board PUBLIC ${EMB_BOARD_INCLUDE_DIRS} "${EMB_BASE}/drivers/rpi/include" "${EMB_BASE}/drivers/arm/include" ${EMB_BOARD_DRIVER_INCLUDE_DIRS}) target_link_libraries(emb_board PUBLIC emb_api PRIVATE emb_flags INTERFACE emb_arch) # emb_cm_halt -set(EMB_BOARD_LINKER_SCRIPT "${EMB_BOARD_DIR}/linker/regions.ld" CACHE INTERNAL "board linker script") +set(EMB_BOARD_LINKER_SCRIPT "${EMB_BOARD_LINKER_DIR}/regions.ld" CACHE INTERNAL "board linker script") target_link_options(emb_board INTERFACE "-T${EMB_BOARD_LINKER_SCRIPT}") # a test image on the board reboots into BOOTSEL when it ends, for picotool's next load if(EMB_TEST_EMULATOR STREQUAL "hil") diff --git a/soc/rpi/rp2350/include/emb_rp2350_pins.h b/soc/rpi/rp2350/include/emb_rp2350_pins.h index 4ba7005c..adec0a57 100644 --- a/soc/rpi/rp2350/include/emb_rp2350_pins.h +++ b/soc/rpi/rp2350/include/emb_rp2350_pins.h @@ -27,7 +27,7 @@ extern "C" { typedef struct emb_rp2350_pin { uint8_t gpio; /* GPIO line, 0 to 29 on the RP2350A */ - uint8_t funcsel; /* IO_BANK0 GPIOn_CTRL.FUNCSEL: 2 UART, 5 SIO, 11 UART_AUX, ... */ + uint8_t funcsel; /* IO_BANK0 GPIOn_CTRL.FUNCSEL: 2 UART, 4 PWM, 5 SIO, 11 UART_AUX, 31 none */ uint8_t input_en; /* PADS_BANK0 GPIOn.IE */ uint8_t pull; /* EMB_RP2350_PULL_*: the pad's reset pull-down, or a pull-up */ uint8_t out; /* EMB_RP2350_OUT_*: an SIO output and its level at boot */ @@ -35,6 +35,7 @@ typedef struct emb_rp2350_pin { #define EMB_RP2350_PULL_RESET 0u /* as the pad comes out of reset: pulled down */ #define EMB_RP2350_PULL_UP 1u /* a line that idles high: a UART's receive, I2C */ +#define EMB_RP2350_PULL_NONE 2u /* neither: an analog input (A129) */ #define EMB_RP2350_OUT_NONE 0u /* a peripheral's pin: its function drives it */ #define EMB_RP2350_OUT_LOW 1u /* an SIO output starting low (an LED) */ diff --git a/soc/rpi/rp2350/rp2350.yaml b/soc/rpi/rp2350/rp2350.yaml index 667c92cd..103de48e 100644 --- a/soc/rpi/rp2350/rp2350.yaml +++ b/soc/rpi/rp2350/rp2350.yaml @@ -39,6 +39,10 @@ clocks: # (N, 16 to 320), 750 to 1600 MHz; clk_sys = VCO / (POSTDIV1 x POSTDIV2), each 1 to 7 - { name: pll_sys, inputs: [xosc], m: [1, 63], n: [16, 320], postdiv: [1, 7], vco_in_hz: [5MHz, 800MHz], vco_out_hz: [750MHz, 1600MHz] } + # PLL_USB, the same PLL, for clk_usb and clk_adc, which run at 48 MHz (§8.1, §12.4.2): solved + # from the crystal like PLL_SYS, and started by the first driver that needs it (A129) + - { name: pll_usb, inputs: [xosc], m: [1, 63], n: [16, 320], postdiv: [1, 7], + vco_in_hz: [5MHz, 800MHz], vco_out_hz: [750MHz, 1600MHz], output_hz: 48MHz } buses: # clk_sys: the processors and the bus fabric, 150 MHz at the default core voltage (§1.2) - { name: sys, from: hclk, max_hz: 150MHz } @@ -56,6 +60,7 @@ peripherals: - { name: pads_bank0, compatible: "rpi,rp2350-pads", base: 0x40038000, size: 0x4000 } - { name: xosc, compatible: "rpi,rp2350-xosc", base: 0x40048000, size: 0x4000 } - { name: pll_sys, compatible: "rpi,rp2350-pll", base: 0x40050000, size: 0x4000 } + - { name: pll_usb, compatible: "rpi,rp2350-pll", base: 0x40058000, size: 0x4000 } - { name: uart0, compatible: "arm,pl011", base: 0x40070000, size: 0x4000, irqs: [{ name: global, number: 33 }], dma_requests: { tx: dma.dreq28, rx: dma.dreq29 } } - { name: uart1, compatible: "arm,pl011", base: 0x40078000, size: 0x4000, irqs: [{ name: global, number: 34 }], @@ -93,40 +98,81 @@ peripherals: # boot RAM (datasheet §5.4.1): the boot ROM leaves its XIP setup function in the first 256 bytes - { name: bootram, compatible: "rpi,rp2350-bootram", base: 0x400E0000, size: 0x400 } - { name: sio, compatible: "rpi,rp2350-sio", base: 0xD0000000, size: 0x1000 } + # the ADC (datasheet §12.4): 12 bits, 500 kS/s at clk_adc's 48 MHz, its result FIFO drained by + # DREQ_ADC; the inputs and the temperature sensor's depend on the package + - { name: adc, compatible: "rpi,rp2350-adc", base: 0x400A0000, size: 0x4000, clocked_by: pll_usb, + adc: { bits: 12 }, irqs: [ { name: fifo, number: 35 } ], dma_requests: { rx: dma.dreq48 } } + # the PWM block (datasheet §12.5): twelve slices of five registers each (CSR, DIV, CTR, CC, TOP, + # 0x14 apart), each a 16-bit counter with two outputs, A and B, B also an input that gates or + # clocks the counter; their DREQs are DREQ_PWM_WRAP0 to 11. The slices' shared registers follow + # them: EN, INTR and the two interrupts' enables, forces and status, PWM_IRQ_WRAP_0 and _1 + - { name: pwm, compatible: "rpi,rp2350-pwm-irq", base: 0x400A80F0, size: 0x20, + irqs: [ { name: wrap0, number: 8 }, { name: wrap1, number: 9 } ] } + - { name: pwm0, compatible: "rpi,rp2350-pwm", base: 0x400A8000, size: 0x14, counter_bits: 16, + dma_requests: { wrap: dma.dreq32 } } + - { name: pwm1, compatible: "rpi,rp2350-pwm", base: 0x400A8014, size: 0x14, counter_bits: 16, + dma_requests: { wrap: dma.dreq33 } } + - { name: pwm2, compatible: "rpi,rp2350-pwm", base: 0x400A8028, size: 0x14, counter_bits: 16, + dma_requests: { wrap: dma.dreq34 } } + - { name: pwm3, compatible: "rpi,rp2350-pwm", base: 0x400A803C, size: 0x14, counter_bits: 16, + dma_requests: { wrap: dma.dreq35 } } + - { name: pwm4, compatible: "rpi,rp2350-pwm", base: 0x400A8050, size: 0x14, counter_bits: 16, + dma_requests: { wrap: dma.dreq36 } } + - { name: pwm5, compatible: "rpi,rp2350-pwm", base: 0x400A8064, size: 0x14, counter_bits: 16, + dma_requests: { wrap: dma.dreq37 } } + - { name: pwm6, compatible: "rpi,rp2350-pwm", base: 0x400A8078, size: 0x14, counter_bits: 16, + dma_requests: { wrap: dma.dreq38 } } + - { name: pwm7, compatible: "rpi,rp2350-pwm", base: 0x400A808C, size: 0x14, counter_bits: 16, + dma_requests: { wrap: dma.dreq39 } } + - { name: pwm8, compatible: "rpi,rp2350-pwm", base: 0x400A80A0, size: 0x14, counter_bits: 16, + dma_requests: { wrap: dma.dreq40 } } + - { name: pwm9, compatible: "rpi,rp2350-pwm", base: 0x400A80B4, size: 0x14, counter_bits: 16, + dma_requests: { wrap: dma.dreq41 } } + - { name: pwm10, compatible: "rpi,rp2350-pwm", base: 0x400A80C8, size: 0x14, counter_bits: 16, + dma_requests: { wrap: dma.dreq42 } } + - { name: pwm11, compatible: "rpi,rp2350-pwm", base: 0x400A80DC, size: 0x14, counter_bits: 16, + dma_requests: { wrap: dma.dreq43 } } + # the timers (datasheet §12.8): 64-bit counts of the TICKS block's microseconds, four alarms + # each on the counter's low 32 bits, an interrupt per alarm + - { name: timer0, compatible: "rpi,rp2350-timer", base: 0x400B0000, size: 0x4000, counter_bits: 64, + irqs: [ { name: alarm0, number: 0 }, { name: alarm1, number: 1 }, { name: alarm2, number: 2 }, { name: alarm3, number: 3 } ] } + - { name: timer1, compatible: "rpi,rp2350-timer", base: 0x400B8000, size: 0x4000, counter_bits: 64, + irqs: [ { name: alarm0, number: 4 }, { name: alarm1, number: 5 }, { name: alarm2, number: 6 }, { name: alarm3, number: 7 } ] } # The UARTs' function selects (pico-sdk 2.1.1, hardware/regs/io_bank0.h): f2, and f11 (UART_AUX); # SPI1's, f1, on the lines of its first bank the Pico 2 W brings out; I2C0's and I2C1's, f3, on -# GPIO6 to GPIO9 +# GPIO6 to GPIO9; PWM's, f4, slice (n / 2) mod 8, A on the even lines and B on the odd; the ADC's +# inputs 0 to 3 on GPIO26 to GPIO29 (datasheet §9.4, §12.4.3) alternate_functions: - GPIO0: { f2: uart0_tx } - GPIO1: { f2: uart0_rx } - GPIO2: { f11: uart0_tx } - GPIO3: { f11: uart0_rx } - GPIO4: { f2: uart1_tx } - GPIO5: { f2: uart1_rx } - GPIO6: { f3: i2c1_sda, f11: uart1_tx } - GPIO7: { f3: i2c1_scl, f11: uart1_rx } - GPIO8: { f2: uart1_tx, f3: i2c0_sda } - GPIO9: { f2: uart1_rx, f3: i2c0_scl } - GPIO10: { f1: spi1_sck, f11: uart1_tx } - GPIO11: { f1: spi1_mosi, f11: uart1_rx } - GPIO12: { f1: spi1_miso, f2: uart0_tx } - GPIO13: { f2: uart0_rx } - GPIO14: { f11: uart0_tx } - GPIO15: { f11: uart0_rx } - GPIO16: { f2: uart0_tx } - GPIO17: { f2: uart0_rx } - GPIO18: { f11: uart0_tx } - GPIO19: { f11: uart0_rx } - GPIO20: { f2: uart1_tx } - GPIO21: { f2: uart1_rx } - GPIO22: { f11: uart1_tx } - GPIO23: { f11: uart1_rx } - GPIO24: { f2: uart1_tx } - GPIO25: { f2: uart1_rx } - GPIO26: { f11: uart1_tx } - GPIO27: { f11: uart1_rx } - GPIO28: { f2: uart0_tx } - GPIO29: { f2: uart0_rx } + GPIO0: { f2: uart0_tx, f4: pwm0_a } + GPIO1: { f2: uart0_rx, f4: pwm0_b } + GPIO2: { f4: pwm1_a, f11: uart0_tx } + GPIO3: { f4: pwm1_b, f11: uart0_rx } + GPIO4: { f2: uart1_tx, f4: pwm2_a } + GPIO5: { f2: uart1_rx, f4: pwm2_b } + GPIO6: { f3: i2c1_sda, f4: pwm3_a, f11: uart1_tx } + GPIO7: { f3: i2c1_scl, f4: pwm3_b, f11: uart1_rx } + GPIO8: { f2: uart1_tx, f3: i2c0_sda, f4: pwm4_a } + GPIO9: { f2: uart1_rx, f3: i2c0_scl, f4: pwm4_b } + GPIO10: { f1: spi1_sck, f4: pwm5_a, f11: uart1_tx } + GPIO11: { f1: spi1_mosi, f4: pwm5_b, f11: uart1_rx } + GPIO12: { f1: spi1_miso, f2: uart0_tx, f4: pwm6_a } + GPIO13: { f2: uart0_rx, f4: pwm6_b } + GPIO14: { f4: pwm7_a, f11: uart0_tx } + GPIO15: { f4: pwm7_b, f11: uart0_rx } + GPIO16: { f2: uart0_tx, f4: pwm0_a } + GPIO17: { f2: uart0_rx, f4: pwm0_b } + GPIO18: { f4: pwm1_a, f11: uart0_tx } + GPIO19: { f4: pwm1_b, f11: uart0_rx } + GPIO20: { f2: uart1_tx, f4: pwm2_a } + GPIO21: { f2: uart1_rx, f4: pwm2_b } + GPIO22: { f4: pwm3_a, f11: uart1_tx } + GPIO23: { f4: pwm3_b, f11: uart1_rx } + GPIO24: { f2: uart1_tx, f4: pwm4_a } + GPIO25: { f2: uart1_rx, f4: pwm4_b } + GPIO26: { f4: pwm5_a, f11: uart1_tx, analog: adc_in0 } + GPIO27: { f4: pwm5_b, f11: uart1_rx, analog: adc_in1 } + GPIO28: { f2: uart0_tx, f4: pwm6_a, analog: adc_in2 } + GPIO29: { f2: uart0_rx, f4: pwm6_b, analog: adc_in3 } # The boot ROM boots a flash image with a valid IMAGE_DEF block in its first 4 KiB (datasheet # §5.9); image_type 0x1021 says EXE, SECURITY_S, CPU_ARM, CHIP_RP2350 (pico-sdk's picobin.h). # The UF2 family ID is the ROM's for Arm Secure images. diff --git a/soc/rpi/rp2350/rp2350a.yaml b/soc/rpi/rp2350/rp2350a.yaml index 145cc4fb..b73af158 100644 --- a/soc/rpi/rp2350/rp2350a.yaml +++ b/soc/rpi/rp2350/rp2350a.yaml @@ -16,3 +16,7 @@ part: RP2350A package: qfn60 curated: true gpio: { lines: 30, controller: io_bank0 } +# the ADC's inputs on this package: GPIO26 to GPIO29, then the temperature sensor (datasheet +# §12.4.1; the RP2350B's are GPIO40 to GPIO47 and 8) +peripherals: + - { name: adc, adc: { inputs: 4, temperature: 4 } } diff --git a/soc/st/stm32f4/CMakeLists.txt b/soc/st/stm32f4/CMakeLists.txt index b2fe0385..a76227c5 100644 --- a/soc/st/stm32f4/CMakeLists.txt +++ b/soc/st/stm32f4/CMakeLists.txt @@ -6,7 +6,8 @@ # emb_board for an STM32F4 board described in YAML (SPEC-014): the family's board support and # drivers, compiled against the board's generated hw_config.h, with its generated pin table and -# linker script. EMB_BOARD_DIR is the board's generated/ directory (A126: src/, linker/). +# linker script. EMB_BOARD_DIR is the board's generated/ directory (A126: src/, linker/; an +# application's src/config//, A130: EMB_BOARD_SRC_DIR, EMB_BOARD_LINKER_DIR). add_library(emb_board STATIC board.c "${EMB_BASE}/drivers/st/stm32f4_rcc.c" @@ -15,12 +16,12 @@ add_library(emb_board STATIC "${EMB_BASE}/drivers/st/stm32_tim.c" "${EMB_BASE}/drivers/st/stm32f4_adc.c" "${EMB_BASE}/drivers/st/stm32f4_iwdg.c" - "${EMB_BOARD_DIR}/src/board_pins.c" + "${EMB_BOARD_SRC_DIR}/board_pins.c" ${EMB_BOARD_DRIVER_SOURCES}) # the board's devices and their drivers (SPEC-016 §8) # the drivers' header is public: an application on the board drives its peripherals with them target_include_directories(emb_board PUBLIC ${EMB_BOARD_INCLUDE_DIRS} "${EMB_BASE}/drivers/st/include" ${EMB_BOARD_DRIVER_INCLUDE_DIRS}) target_link_libraries(emb_board PUBLIC emb_api PRIVATE emb_flags INTERFACE emb_arch) # emb_cm_halt # The generated linker script brackets the kernel's flash tables (SPEC-012 §8). -set(EMB_BOARD_LINKER_SCRIPT "${EMB_BOARD_DIR}/linker/regions.ld" CACHE INTERNAL "board linker script") +set(EMB_BOARD_LINKER_SCRIPT "${EMB_BOARD_LINKER_DIR}/regions.ld" CACHE INTERNAL "board linker script") target_link_options(emb_board INTERFACE "-T${EMB_BOARD_LINKER_SCRIPT}") diff --git a/soc/st/stm32f4/include/emb_stm32_pins.h b/soc/st/stm32f4/include/emb_stm32_pins.h index 1779a5d8..e5ac5936 100644 --- a/soc/st/stm32f4/include/emb_stm32_pins.h +++ b/soc/st/stm32f4/include/emb_stm32_pins.h @@ -23,6 +23,7 @@ extern "C" { #define EMB_STM32_PIN_OUTPUT 1u /* GPIOx_MODER: general-purpose output */ #define EMB_STM32_PIN_AF 2u /* GPIOx_MODER: alternate function, AFRL/AFRH selects which */ +#define EMB_STM32_PIN_ANALOG 3u /* GPIOx_MODER: analog, an ADC's input (A129) */ /* A pin's flags: an I2C line is open drain, pulled up where the board has no resistors. */ #define EMB_STM32_PIN_OPEN_DRAIN 0x01u /* GPIOx_OTYPER */ diff --git a/soc/st/stm32f4/stm32f4.yaml b/soc/st/stm32f4/stm32f4.yaml index d1378728..b9a9fe69 100644 --- a/soc/st/stm32f4/stm32f4.yaml +++ b/soc/st/stm32f4/stm32f4.yaml @@ -35,6 +35,8 @@ clocks: - { name: pll, inputs: [hsi, hse], m: [2, 63], n: [50, 432], p: [2, 4, 6, 8], q: [2, 15], r: [2, 7], vco_in_hz: [1MHz, 2MHz], vco_out_hz: [100MHz, 432MHz] } prescalers: { ahb: [1, 2, 4, 8, 16, 64, 128, 256, 512], apb: [1, 2, 4, 8, 16] } + # RM0390 §6.2: a timer on an APB bus divided from HCLK counts at twice the bus's clock + timers_double_when_divided: true # RM0390 Table 5, 2.7 to 3.6 V: one wait state per 30 MHz of HCLK flash_latency: { hz_per_wait_state: 30MHz, max_wait_states: 15 } interrupts: diff --git a/soc/st/stm32f4/stm32f446.yaml b/soc/st/stm32f4/stm32f446.yaml index ae9dd842..9e9abee4 100644 --- a/soc/st/stm32f4/stm32f446.yaml +++ b/soc/st/stm32f4/stm32f446.yaml @@ -37,9 +37,13 @@ interrupts: # vector lines with no peripheral behind them (RM0390 Table 38): free for software use reserved: [61, 62, 79, 80, 81, 82, 83, 85, 86, 88, 89, 90] peripherals: - # ADC1 (RM0390 §13): its global interrupt line is shared by ADC1 to ADC3 + # ADC1 (RM0390 §13): 12 bits, inputs 0 to 15 on pins, the temperature sensor on 18 and VREFINT + # on 17 (§13.10, §13.11); its global interrupt line is shared by ADC1 to ADC3; its results by + # DMA2 stream 0 or 4, channel 0 (Table 29) - { name: adc1, compatible: "st,stm32f4-adc", base: 0x40012000, size: 0x100, clock: { bus: apb2, bit: 8 }, - irqs: [ { name: global, number: 18 } ] } + adc: { bits: 12, inputs: 16, temperature: 18, vrefint: 17 }, + irqs: [ { name: global, number: 18 } ], + dma_requests: { rx: [dma2.s0c0, dma2.s4c0] } } # the ADCs' common registers (RM0390 §13.13.16): the prescaler, the temperature sensor's enable - { name: adc_common, compatible: "st,stm32f4-adc-common", base: 0x40012300, size: 0x100 } # factory calibration in system memory (DS10693 §6.3.22, §6.3.23): VREFINT_CAL at +0, the @@ -68,9 +72,27 @@ peripherals: irqs: [ { name: pvd, number: 1 } ] } - { name: rcc, compatible: "st,stm32f4-rcc", base: 0x40023800, size: 0x400, irqs: [ { name: global, number: 5 } ] } - # TIM2, a 32-bit general-purpose timer on APB1 (RM0390 §18): its update event is ADC1's trigger - - { name: tim2, compatible: "st,stm32-tim", base: 0x40000000, size: 0x400, clock: { bus: apb1, bit: 0 }, + # TIM2, a 32-bit general-purpose timer on APB1 (RM0390 §17): its update event, as TRGO, is + # ADC1's trigger, EXTSEL 0110 (§13.13.3); TIM3's is 1000 + - { name: tim2, compatible: "st,stm32-tim", base: 0x40000000, size: 0x400, counter_bits: 32, + adc_trigger: 6, clock: { bus: apb1, bit: 0 }, irqs: [ { name: global, number: 28 } ] } + # TIM3 and TIM4, 16-bit, and TIM5, 32-bit, the same general-purpose timers on APB1 (RM0390 §17, + # Table 38): four channels each, for PWM, capture and compare + - { name: tim3, compatible: "st,stm32-tim", base: 0x40000400, size: 0x400, counter_bits: 16, + adc_trigger: 8, clock: { bus: apb1, bit: 1 }, + irqs: [ { name: global, number: 29 } ] } + - { name: tim4, compatible: "st,stm32-tim", base: 0x40000800, size: 0x400, counter_bits: 16, + clock: { bus: apb1, bit: 2 }, + irqs: [ { name: global, number: 30 } ] } + - { name: tim5, compatible: "st,stm32-tim", base: 0x40000C00, size: 0x400, counter_bits: 32, + clock: { bus: apb1, bit: 3 }, + irqs: [ { name: global, number: 50 } ] } + # TIM9, a 16-bit general-purpose timer on APB2 with two channels (RM0390 §18): the same + # registers as TIM2's but CCMR2, CCR3 and CCR4; its interrupt is shared with TIM1's break + - { name: tim9, compatible: "st,stm32-tim", base: 0x40014000, size: 0x400, counter_bits: 16, + timer_channels: 2, clock: { bus: apb2, bit: 16 }, + irqs: [ { name: global, number: 24 } ] } # the DMA controllers (RM0390 §9), on AHB1, an interrupt per stream (SVD 1.9): each request on # the streams Tables 28 and 29 list it on, with its channel select (dma_requests: A119, the # tables cross-checked with EmbSIM's STM32F446 model); DMA2 alone copies memory to memory @@ -118,27 +140,42 @@ peripherals: # (STM32F446R(C-E)Tx.xml and GPIO-STM32F446_gpio_v1_0_Modes.xml, the I2C pins' AF4 among them); # PD5, PD6, PD8 and PD9 from DS10693 Table 11. alternate_functions: - PA0: { af8: uart4_tx } - PA1: { af8: uart4_rx } - PA2: { af7: usart2_tx } - PA3: { af7: usart2_rx } + PA0: { af1: tim2_ch1, af2: tim5_ch1, af8: uart4_tx, analog: adc1_in0 } + PA1: { af1: tim2_ch2, af2: tim5_ch2, af8: uart4_rx, analog: adc1_in1 } + PA2: { af1: tim2_ch3, af2: tim5_ch3, af7: usart2_tx, analog: adc1_in2 } + PA3: { af1: tim2_ch4, af2: tim5_ch4, af7: usart2_rx, analog: adc1_in3 } + PA4: { analog: adc1_in4 } + PA5: { af1: tim2_ch1, analog: adc1_in5 } + PA6: { af2: tim3_ch1, analog: adc1_in6 } + PA7: { af2: tim3_ch2, analog: adc1_in7 } PA8: { af4: i2c3_scl } PA9: { af7: usart1_tx } PA10: { af7: usart1_rx } - PB3: { af4: i2c2_sda } - PB4: { af4: i2c3_sda } - PB6: { af4: i2c1_scl, af7: usart1_tx } - PB7: { af4: i2c1_sda, af7: usart1_rx } - PB8: { af4: i2c1_scl } - PB9: { af4: i2c1_sda } - PB10: { af4: i2c2_scl, af7: usart3_tx } + PA15: { af1: tim2_ch1 } + PB0: { af2: tim3_ch3, analog: adc1_in8 } + PB1: { af2: tim3_ch4, analog: adc1_in9 } + PB2: { af1: tim2_ch4 } + PB3: { af1: tim2_ch2, af4: i2c2_sda } + PB4: { af2: tim3_ch1, af4: i2c3_sda } + PB5: { af2: tim3_ch2 } + PB6: { af2: tim4_ch1, af4: i2c1_scl, af7: usart1_tx } + PB7: { af2: tim4_ch2, af4: i2c1_sda, af7: usart1_rx } + PB8: { af1: tim2_ch1, af2: tim4_ch3, af4: i2c1_scl } + PB9: { af1: tim2_ch2, af2: tim4_ch4, af4: i2c1_sda } + PB10: { af1: tim2_ch3, af4: i2c2_scl, af7: usart3_tx } PB13: { af5: spi2_sck } PB14: { af5: spi2_miso } PB15: { af5: spi2_mosi } - PC5: { af7: usart3_rx } - PC6: { af8: usart6_tx } - PC7: { af8: usart6_rx } - PC9: { af4: i2c3_sda } + PC0: { analog: adc1_in10 } + PC1: { analog: adc1_in11 } + PC2: { analog: adc1_in12 } + PC3: { analog: adc1_in13 } + PC4: { analog: adc1_in14 } + PC5: { af7: usart3_rx, analog: adc1_in15 } + PC6: { af2: tim3_ch1, af8: usart6_tx } + PC7: { af2: tim3_ch2, af8: usart6_rx } + PC8: { af2: tim3_ch3 } + PC9: { af2: tim3_ch4, af4: i2c3_sda } PC10: { af7: usart3_tx, af8: uart4_tx } PC11: { af7: usart3_rx, af8: uart4_rx } PC12: { af4: i2c2_sda, af8: uart5_tx } diff --git a/tests/benchmarks/CMakeLists.txt b/tests/benchmarks/CMakeLists.txt index 15969a1c..4615bb1c 100644 --- a/tests/benchmarks/CMakeLists.txt +++ b/tests/benchmarks/CMakeLists.txt @@ -19,7 +19,7 @@ if(EMB_TEST_EMULATOR STREQUAL "hil" AND EMB_HIL_PORT) foreach(_bench bench_switch bench_irq bench_compare) if(TARGET ${_bench}) add_test(NAME ${_bench} COMMAND "${Python3_EXECUTABLE}" -I "${EMB_BASE}/tools/hil/run_hil.py" - --hw-json "${EMB_BOARD_DIR}/hw.json" --port "${EMB_HIL_PORT}" --until BENCH_END --bench + --hw-json "${EMB_BOARD_HW_JSON}" --port "${EMB_HIL_PORT}" --until BENCH_END --bench --log "${CMAKE_CURRENT_BINARY_DIR}/${_bench}.console.log" --archive "${EMB_HIL_ARCHIVE}" $) set_tests_properties(${_bench} PROPERTIES RUN_SERIAL TRUE LABELS bench TIMEOUT 300) diff --git a/tests/conformance/CMakeLists.txt b/tests/conformance/CMakeLists.txt index 1fee79fe..2cbebd25 100644 --- a/tests/conformance/CMakeLists.txt +++ b/tests/conformance/CMakeLists.txt @@ -116,6 +116,64 @@ if(CONFIG_EMB_DEVICE) endif() endif() endif() + if(CONFIG_EMB_DRV_ADC) + emb_add_test(test_adc test_adc.c) # SPEC-017 §11c + # an ADC with one input wired to the 3.3 V rail and one to ground: on the bench + # (EMB_TEST_ADC_LOOP=:,: adc1:4,8 on the NUCLEO-F446RE, adc:0,1 on the Pico + # 2 W), or the board's EmbSIM nets to its rails + set(EMB_TEST_ADC_LOOP "" CACHE STRING "An ADC's input wired high and one low, for test_adc_board") + set(_emb_adc_loop "${EMB_TEST_ADC_LOOP}") + if(NOT _emb_adc_loop AND EMB_TEST_EMULATOR STREQUAL "embsim" AND EMB_BOARD_EMBSIM_ADC_LOOP) + list(GET EMB_BOARD_EMBSIM_ADC_LOOP 0 _emb_adc_loop) + list(GET EMB_BOARD_EMBSIM_ADC_LOOP 1 _emb_adc_net0) + list(GET EMB_BOARD_EMBSIM_ADC_LOOP 2 _emb_adc_net1) + set(EMB_EMBSIM_ARGS_test_adc_board --net "${_emb_adc_net0}" --net "${_emb_adc_net1}" --until 3s) + endif() + if(_emb_adc_loop) + string(REGEX MATCH "^([a-z0-9_]+):([0-9]+),([0-9]+)$" _emb_adc_ok "${_emb_adc_loop}") + if(NOT _emb_adc_ok) + message(FATAL_ERROR "EMB_TEST_ADC_LOOP='${_emb_adc_loop}': :,, such as adc1:4,8") + endif() + emb_add_test(test_adc_board test_adc_board.c) + target_compile_definitions(test_adc_board PRIVATE "EMB_TEST_ADC=(&emb_dev_${CMAKE_MATCH_1})" + "EMB_TEST_ADC_HIGH=${CMAKE_MATCH_2}u" + "EMB_TEST_ADC_LOW=${CMAKE_MATCH_3}u") + endif() + endif() + if(CONFIG_EMB_DRV_COUNTER) + emb_add_test(test_counter test_counter.c) # SPEC-017 §11a + # the board's own counters: every one it has + if(EXISTS "${EMB_BOARD_DIR}/include/soc_devices.h") + file(STRINGS "${EMB_BOARD_DIR}/include/soc_devices.h" _emb_counter REGEX "EMB_SOC_COUNTER_DEVICES") + if(_emb_counter) + emb_add_test(test_counter_board test_counter_board.c) + endif() + endif() + endif() + if(CONFIG_EMB_DRV_PWM) + emb_add_test(test_pwm test_pwm.c) # SPEC-017 §11b + # a PWM output wired to a capture input: on the bench (EMB_TEST_PWM_LOOP=:, + # :: tim3:0,tim4:0 on the NUCLEO-F446RE, pwm7:0,pwm0:1 on the Pico 2 W), or the + # board's EmbSIM wire + set(EMB_TEST_PWM_LOOP "" CACHE STRING "A PWM output wired to a capture input, for test_pwm_loop") + set(_emb_pwm_loop "${EMB_TEST_PWM_LOOP}") + if(NOT _emb_pwm_loop AND EMB_TEST_EMULATOR STREQUAL "embsim" AND EMB_BOARD_EMBSIM_PWM_LOOP) + list(GET EMB_BOARD_EMBSIM_PWM_LOOP 0 _emb_pwm_loop) + list(GET EMB_BOARD_EMBSIM_PWM_LOOP 1 _emb_pwm_net) + set(EMB_EMBSIM_ARGS_test_pwm_loop --net "${_emb_pwm_net}" --until 3s) + endif() + if(_emb_pwm_loop) + string(REGEX MATCH "^([a-z0-9_]+):([0-9]),([a-z0-9_]+):([0-9])$" _emb_pwm_ok "${_emb_pwm_loop}") + if(NOT _emb_pwm_ok) + message(FATAL_ERROR "EMB_TEST_PWM_LOOP='${_emb_pwm_loop}': :,:, such as tim3:0,tim4:0") + endif() + emb_add_test(test_pwm_loop test_pwm_loop.c) + target_compile_definitions(test_pwm_loop PRIVATE "EMB_TEST_PWM_OUT=(&emb_dev_${CMAKE_MATCH_1})" + "EMB_TEST_PWM_OUT_CH=${CMAKE_MATCH_2}u" + "EMB_TEST_PWM_IN=(&emb_dev_${CMAKE_MATCH_3})" + "EMB_TEST_PWM_IN_CH=${CMAKE_MATCH_4}u") + endif() + endif() if(CONFIG_EMB_DRV_RTC) emb_add_test(test_rtc test_rtc.c) # SPEC-017 §10 # the board's own RTC: its time, its alarm, across a reset diff --git a/tests/conformance/test_adc.c b/tests/conformance/test_adc.c new file mode 100644 index 00000000..acb767db --- /dev/null +++ b/tests/conformance/test_adc.c @@ -0,0 +1,217 @@ +/* SPDX-License-Identifier: Apache-2.0 */ +/* Copyright 2026 Junior Deogracias */ +/* + * This file is part of EmbLinkRTOS, a deterministic real-time kernel for microcontrollers. + * Licensed under the Apache License, Version 2.0; see the LICENSE file at the repository root. + */ + +/** + * @file test_adc.c + * @brief The ADC class (SPEC-017 §11c, A129). + * + * @details + * Its checks over a driver's operations, through a fake whose inputs hold set counts: a + * conversion waiting and polled; millivolts; the temperature; a sampling's halves handed to its + * callback, the device the sampling's meanwhile, an overrun ending it; a stop. + * + * @author teo1747 + * @date 2026-11-13 (created) + */ +#include +#include + +typedef struct fake_adc { + emb_drv_adc_data_t adc; /* the class's, first */ + uint16_t value[4]; /* each input's count */ + bool sampling; + uint8_t first; /* the sampling's first input */ +} fake_adc_t; + +static fake_adc_t fake; +static emb_device_state_t adc_state; + +static emb_status_t fake_init(const emb_device_t *dev) +{ + return emb_drv_adc_started(dev); +} + +static emb_status_t fake_read(const emb_device_t *dev, uint8_t input, uint16_t *count) +{ + (void)dev; + if (input == EMB_DRV_ADC_TEMPERATURE) { + *count = 2500u; + return EMB_OK; + } + if (input >= 4u) { + return EMB_EINVAL; + } + *count = fake.value[input]; + return EMB_OK; +} + +static emb_status_t fake_sample_start(const emb_device_t *dev, const emb_drv_adc_sampling_t *s) +{ + (void)dev; + if (s->inputs[0] >= 4u) { + return EMB_EINVAL; + } + fake.first = s->inputs[0]; + fake.sampling = true; + return EMB_OK; +} + +static void fake_sample_stop(const emb_device_t *dev) +{ + (void)dev; + fake.sampling = false; +} + +static emb_status_t fake_to_mdegc(const emb_device_t *dev, uint16_t count, int32_t *mdegc) +{ + (void)dev; + *mdegc = (int32_t)count * 10; /* 2500: 25 C */ + return EMB_OK; +} + +static uint32_t fake_vref(const emb_device_t *dev) +{ + (void)dev; + return 3300u; +} + +static const emb_drv_adc_api_t fake_api = { + {fake_init, NULL, NULL, NULL, NULL, EMB_DRV_ADC_CAP_TEMPERATURE | EMB_DRV_ADC_CAP_SAMPLE}, + fake_read, + fake_sample_start, + fake_sample_stop, + fake_to_mdegc, + fake_vref, + 12u, + {0u, 0u, 0u}, +}; +static const emb_device_t adc_dev = { + "adc", &fake_api.dev, NULL, &adc_state, &fake, NULL, EMB_DRV_CLASS_ADC, EMB_DEVICE_KERNEL, 0u}; + +static uint16_t buffer[8]; +static unsigned halves; +static const uint16_t *last; +static uint32_t last_count; +static emb_status_t last_status; + +static void on_half(void *arg, const uint16_t *samples, uint32_t count, emb_status_t status) +{ + (void)arg; + halves++; + last = samples; + last_count = count; + last_status = status; +} + +/* The device started once, as at boot: its lock is made once; the fake reset each case. */ +static void ready(void) +{ + static bool started; + if (!started) { + emb_device_state_t idle = {EMB_DEVICE_UNINIT, 0u, 0u, 0u, EMB_OK, + {NULL, NULL}, {NULL, NULL}}; + adc_state = idle; + EMB_ASSERT_OK(emb_device_init(&adc_dev)); + started = true; + } + (void)emb_drv_adc_sample_stop(&adc_dev); + (void)memset((uint8_t *)&fake + sizeof(fake.adc), 0, sizeof(fake) - sizeof(fake.adc)); + halves = 0u; + last = NULL; + last_count = 0u; + last_status = EMB_OK; +} + +EMB_TEST(adc_read_millivolts_and_temperature) +{ + uint16_t count = 0u; + uint32_t mv = 0u; + int32_t mdegc = 0; + EMB_TEST_REQ("DRV-001"); + ready(); + fake.value[2] = 4095u; + EMB_ASSERT_OK(emb_drv_adc_read(&adc_dev, 2u, &count, EMB_TIMEOUT(EMB_MS(10)))); + EMB_ASSERT_EQ(count, 4095u); + EMB_ASSERT_OK(emb_drv_adc_read_polled(&adc_dev, 2u, &count)); + EMB_ASSERT_STATUS(emb_drv_adc_read(&adc_dev, 9u, &count, EMB_NO_WAIT), EMB_EINVAL); + EMB_ASSERT_OK(emb_drv_adc_to_mv(&adc_dev, 4095u, &mv)); + EMB_ASSERT_EQ(mv, 3300u); /* full scale: the reference */ + EMB_ASSERT_OK(emb_drv_adc_to_mv(&adc_dev, 2048u, &mv)); + EMB_ASSERT_EQ(mv, 1650u); + EMB_ASSERT_OK(emb_drv_adc_to_mv(&adc_dev, 0u, &mv)); + EMB_ASSERT_EQ(mv, 0u); + EMB_ASSERT_STATUS(emb_drv_adc_to_mv(&adc_dev, 4096u, &mv), EMB_EINVAL); /* past 12 bits */ + EMB_ASSERT_OK(emb_drv_adc_temperature(&adc_dev, &mdegc, EMB_NO_WAIT)); + EMB_ASSERT_TRUE(mdegc == 25000); +} + +EMB_TEST(adc_sampling_halves_and_stop) +{ + static const uint8_t inputs[2] = {0u, 1u}; + emb_drv_adc_sampling_t s = {inputs, buffer, 8u, 1000u, on_half, NULL, 2u, {0u, 0u, 0u}}; + uint16_t count = 0u; + EMB_TEST_REQ("DRV-001"); + ready(); + EMB_ASSERT_OK(emb_drv_adc_sample_start(&adc_dev, &s)); + EMB_ASSERT_TRUE(fake.sampling); + EMB_ASSERT_STATUS(emb_drv_adc_sample_start(&adc_dev, &s), EMB_EBUSY); + EMB_ASSERT_STATUS(emb_drv_adc_read(&adc_dev, 0u, &count, EMB_NO_WAIT), EMB_EBUSY); + EMB_ASSERT_STATUS(emb_drv_adc_read_polled(&adc_dev, 0u, &count), EMB_EBUSY); + EMB_ASSERT_OK(emb_drv_adc_sampled(&adc_dev, 0u, EMB_OK)); + EMB_ASSERT_TRUE((halves == 1u) && (last == &buffer[0]) && (last_count == 4u)); + EMB_ASSERT_OK(emb_drv_adc_sampled(&adc_dev, 1u, EMB_OK)); + EMB_ASSERT_TRUE((halves == 2u) && (last == &buffer[4]) && (last_count == 4u)); + EMB_ASSERT_OK(emb_drv_adc_sample_stop(&adc_dev)); + EMB_ASSERT_TRUE(!fake.sampling); + EMB_ASSERT_STATUS(emb_drv_adc_sampled(&adc_dev, 0u, EMB_OK), EMB_ESTATE); /* nothing after */ + EMB_ASSERT_EQ(halves, 2u); + EMB_ASSERT_STATUS(emb_drv_adc_sample_stop(&adc_dev), EMB_ESTATE); + EMB_ASSERT_OK(emb_drv_adc_read(&adc_dev, 0u, &count, EMB_NO_WAIT)); /* the device's again */ +} + +EMB_TEST(adc_sampling_overrun_and_its_shape) +{ + static const uint8_t inputs[3] = {0u, 1u, 9u}; + emb_drv_adc_sampling_t s = {inputs, buffer, 8u, 1000u, on_half, NULL, 2u, {0u, 0u, 0u}}; + EMB_TEST_REQ("DRV-001"); + ready(); + EMB_ASSERT_OK(emb_drv_adc_sample_start(&adc_dev, &s)); + fake.sampling = false; /* a driver stops its hardware, then reports the overrun */ + EMB_ASSERT_OK(emb_drv_adc_sampled(&adc_dev, 0u, EMB_EOVERRUN)); + EMB_ASSERT_TRUE((halves == 1u) && (last == NULL) && (last_status == EMB_EOVERRUN)); + EMB_ASSERT_STATUS(emb_drv_adc_sample_stop(&adc_dev), EMB_ESTATE); + s.length = 6u; /* halves of one and a half sequences */ + EMB_ASSERT_STATUS(emb_drv_adc_sample_start(&adc_dev, &s), EMB_EINVAL); + s.length = 8u; + s.count = 0u; + EMB_ASSERT_STATUS(emb_drv_adc_sample_start(&adc_dev, &s), EMB_EINVAL); + s.count = (uint8_t)(EMB_DRV_ADC_SEQUENCE_MAX + 1u); + EMB_ASSERT_STATUS(emb_drv_adc_sample_start(&adc_dev, &s), EMB_EINVAL); + s.count = 1u; + s.rate_hz = 0u; + EMB_ASSERT_STATUS(emb_drv_adc_sample_start(&adc_dev, &s), EMB_EINVAL); + s.rate_hz = 1000u; + s.inputs = &inputs[2]; /* the driver refuses an input it lacks */ + EMB_ASSERT_STATUS(emb_drv_adc_sample_start(&adc_dev, &s), EMB_EINVAL); + EMB_ASSERT_TRUE(!fake.sampling); + s.inputs = inputs; + EMB_ASSERT_OK(emb_drv_adc_sample_start(&adc_dev, &s)); /* the refusal took nothing */ +} + +EMB_TEST(adc_misuse) +{ + uint16_t count = 0u; + uint32_t mv = 0u; + EMB_TEST_REQ("DRV-001"); + ready(); + EMB_ASSERT_FAULTS((void)emb_drv_adc_read(&adc_dev, 0u, NULL, EMB_NO_WAIT)); + EMB_ASSERT_FAULTS((void)emb_drv_adc_read_polled(NULL, 0u, &count)); + EMB_ASSERT_FAULTS((void)emb_drv_adc_to_mv(&adc_dev, 0u, NULL)); + EMB_ASSERT_FAULTS((void)emb_drv_adc_sample_start(&adc_dev, NULL)); + EMB_ASSERT_FAULTS((void)emb_drv_adc_sampled(&adc_dev, 2u, EMB_OK)); /* no third half */ + (void)mv; +} diff --git a/tests/conformance/test_adc_board.c b/tests/conformance/test_adc_board.c new file mode 100644 index 00000000..9e319c9b --- /dev/null +++ b/tests/conformance/test_adc_board.c @@ -0,0 +1,119 @@ +/* SPDX-License-Identifier: Apache-2.0 */ +/* Copyright 2026 Junior Deogracias */ +/* + * This file is part of EmbLinkRTOS, a deterministic real-time kernel for microcontrollers. + * Licensed under the Apache License, Version 2.0; see the LICENSE file at the repository root. + */ + +/** + * @file test_adc_board.c + * @brief The board's ADC, an input wired high and one low (SPEC-017 §11c, A129). + * + * @details + * EMB_TEST_ADC's input EMB_TEST_ADC_HIGH is wired to the 3.3 V rail, EMB_TEST_ADC_LOW to ground: + * one conversion of each, and their millivolts; the internal temperature sensor in a room's + * range; the internal reference where it has one; and both sampled in turn by DMA at 1 kHz, every + * half's samples in their order, the halves on time, none after the stop. Bench: the + * NUCLEO-F446RE's A2 (PA4, input 4) to 3V3 and A3 (PB0, input 8) to GND; the Pico 2 W's pin 31 + * (GPIO26, input 0) to 3V3 OUT and pin 32 (GPIO27, input 1) to AGND. + * + * @author teo1747 + * @date 2026-11-13 (created) + */ +#include +#include + +#define ADC EMB_TEST_ADC +#define HIGH EMB_TEST_ADC_HIGH +#define LOW EMB_TEST_ADC_LOW +#define WAIT EMB_TIMEOUT(EMB_MS(100u)) +#define RAIL_MV 3300u +#define SLACK 100u /* mV: the rail's tolerance and the converter's offset */ +#define RATE 1000u +#define SAMPLES 64u /* 32 sequences: 16 a half, one each 16 ms at RATE */ + +/* a power of two bytes, aligned to its size: the RP2350's DMA ring wraps it */ +static EMB_ALIGNED(128) uint16_t buffer[SAMPLES]; +static volatile unsigned halves; +static volatile unsigned wrong; /* samples out of their order: high where low is, or the reverse */ +static volatile emb_status_t ended; + +static void on_half(void *arg, const uint16_t *samples, uint32_t count, emb_status_t status) +{ + uint32_t i; + (void)arg; + if (status != EMB_OK) { + ended = status; + return; + } + for (i = 0u; i < count; i += 2u) { /* bounded: a half */ + if ((samples[i] < 3500u) || (samples[i + 1u] > 300u)) { + wrong++; + } + } + halves++; +} + +static uint32_t mv_of(uint8_t input) +{ + uint16_t count = 0u; + uint32_t mv = 0u; + EMB_ASSERT_OK(emb_drv_adc_read(ADC, input, &count, WAIT)); + EMB_ASSERT_OK(emb_drv_adc_to_mv(ADC, count, &mv)); + return mv; +} + +EMB_TEST(adc_board_high_and_low) +{ + uint32_t high; + uint32_t low; + uint16_t count = 0u; + EMB_TEST_REQ("DRV-001"); + EMB_ASSERT_TRUE(emb_device_ready(ADC)); + high = mv_of(HIGH); + low = mv_of(LOW); + EMB_ASSERT_TRUE((high + SLACK) >= RAIL_MV); + EMB_ASSERT_TRUE(low <= SLACK); + EMB_ASSERT_OK(emb_drv_adc_read_polled(ADC, LOW, &count)); + EMB_ASSERT_TRUE(count < 200u); +} + +EMB_TEST(adc_board_internal_inputs) +{ + int32_t mdegc = 0; + uint16_t count = 0u; + uint32_t mv = 0u; + EMB_TEST_REQ("DRV-001"); + EMB_ASSERT_OK(emb_drv_adc_temperature(ADC, &mdegc, WAIT)); + EMB_ASSERT_TRUE((mdegc > 5000) && (mdegc < 70000)); /* a bench's room, and the part's warmth */ + if ((emb_device_caps(ADC) & EMB_DRV_ADC_CAP_VREFINT) != 0u) { + EMB_ASSERT_OK(emb_drv_adc_read(ADC, EMB_DRV_ADC_VREFINT, &count, WAIT)); + EMB_ASSERT_OK(emb_drv_adc_to_mv(ADC, count, &mv)); + EMB_ASSERT_TRUE((mv >= 1150u) && (mv <= 1250u)); /* 1.21 V, typically (DS10693) */ + } else { + EMB_ASSERT_STATUS(emb_drv_adc_read(ADC, EMB_DRV_ADC_VREFINT, &count, WAIT), EMB_EINVAL); + } +} + +EMB_TEST(adc_board_sampled_in_turn) +{ + static const uint8_t inputs[2] = {HIGH, LOW}; + emb_drv_adc_sampling_t s = {inputs, buffer, SAMPLES, RATE, on_half, NULL, 2u, {0u, 0u, 0u}}; + uint16_t count = 0u; + unsigned seen; + EMB_TEST_REQ("DRV-001"); + halves = 0u; + wrong = 0u; + ended = EMB_OK; + EMB_ASSERT_OK(emb_drv_adc_sample_start(ADC, &s)); + EMB_ASSERT_STATUS(emb_drv_adc_read(ADC, LOW, &count, EMB_NO_WAIT), EMB_EBUSY); + (void)emb_thread_sleep(EMB_MS(200u)); /* twelve and a half halves */ + EMB_ASSERT_OK(emb_drv_adc_sample_stop(ADC)); + seen = halves; + EMB_ASSERT_TRUE((seen >= 11u) && (seen <= 13u)); /* on time: a half each 16 ms */ + EMB_ASSERT_EQ(wrong, 0u); /* each sequence high, then low */ + EMB_ASSERT_TRUE(ended == EMB_OK); /* no overrun */ + (void)emb_thread_sleep(EMB_MS(40u)); + EMB_ASSERT_EQ(halves, seen); /* none after the stop */ + EMB_ASSERT_TRUE(mv_of(HIGH) + SLACK >= RAIL_MV); /* the device's again */ +} diff --git a/tests/conformance/test_counter.c b/tests/conformance/test_counter.c new file mode 100644 index 00000000..fb89f25e --- /dev/null +++ b/tests/conformance/test_counter.c @@ -0,0 +1,255 @@ +/* SPDX-License-Identifier: Apache-2.0 */ +/* Copyright 2026 Junior Deogracias */ +/* + * This file is part of EmbLinkRTOS, a deterministic real-time kernel for microcontrollers. + * Licensed under the Apache License, Version 2.0; see the LICENSE file at the repository root. + */ + +/** + * @file test_counter.c + * @brief The counter class (SPEC-017 §11a, A129). + * + * @details + * Its checks over a driver's operations, through a fake counter whose count the test moves and + * whose alarms it fires: one-shot alarms, one passed, one armed from its own callback, canceled; + * periodic alarms without drift, late ones skipped, one stopped from its callback, one the + * counter cannot keep; the channels a device has. + * + * @author teo1747 + * @date 2026-11-13 (created) + */ +#include +#include + +typedef struct fake_counter { + emb_drv_counter_data_t counter; /* the class's, first */ + uint64_t now; + uint64_t target[EMB_DRV_COUNTER_CHANNELS_MAX]; + bool armed[EMB_DRV_COUNTER_CHANNELS_MAX]; + bool refuse; /* every arm refused as passed: a period it cannot keep */ + unsigned arms; +} fake_counter_t; + +static fake_counter_t fake; +static emb_device_state_t counter_state; + +static emb_status_t fake_init(const emb_device_t *dev) +{ + return emb_drv_counter_started(dev, 3u); /* fewer than the driver's most */ +} + +static uint64_t fake_now(const emb_device_t *dev) +{ + (void)dev; + return fake.now; +} + +static uint32_t fake_rate(const emb_device_t *dev) +{ + (void)dev; + return 1000000u; +} + +static emb_status_t fake_arm(const emb_device_t *dev, uint8_t channel, uint64_t at) +{ + (void)dev; + fake.arms++; + if (fake.refuse || (at <= fake.now)) { + return EMB_EPAST; + } + fake.target[channel] = at; + fake.armed[channel] = true; + return EMB_OK; +} + +static void fake_disarm(const emb_device_t *dev, uint8_t channel) +{ + (void)dev; + fake.armed[channel] = false; +} + +static const emb_drv_counter_api_t fake_api = { + {fake_init, NULL, NULL, NULL, NULL, 0u}, + fake_now, + fake_rate, + fake_arm, + fake_disarm, + 4u, + {0u, 0u, 0u}, +}; +static const emb_device_t counter_dev = {"counter", + &fake_api.dev, + NULL, + &counter_state, + &fake, + NULL, + EMB_DRV_CLASS_COUNTER, + EMB_DEVICE_KERNEL, + 0u}; + +static const emb_device_api_t plain_api = {NULL, NULL, NULL, NULL, NULL, 0u}; +static uint8_t plain_data; +static emb_device_state_t plain_state; +static const emb_device_t plain_dev = { + "plain", &plain_api, NULL, &plain_state, &plain_data, NULL, EMB_DRV_CLASS_GPIO, + EMB_DEVICE_KERNEL, 0u}; + +static unsigned fired; +static uint64_t last_at; +static bool again; +static bool stop; + +static void on_alarm(void *arg, uint64_t at) +{ + uint8_t channel = *(const uint8_t *)arg; + fired++; + last_at = at; + if (again) { + again = false; + (void)emb_drv_counter_alarm_set(&counter_dev, channel, fake.now + 50u, on_alarm, arg); + } + if (stop) { + (void)emb_drv_counter_periodic_stop(&counter_dev, channel); + } +} + +static uint8_t ch0 = 0u; +static uint8_t ch1 = 1u; + +/* The fake reaches a channel's count: the hardware's alarm is spent, and its interrupt runs. */ +static void reach(uint8_t channel) +{ + fake.now = fake.target[channel]; + fake.armed[channel] = false; + (void)emb_drv_counter_fired(&counter_dev, channel); +} + +static void ready(void) +{ + emb_device_state_t idle = {EMB_DEVICE_UNINIT, 0u, 0u, 0u, EMB_OK, {NULL, NULL}, {NULL, NULL}}; + (void)memset(&fake, 0, sizeof(fake)); + fake.now = 1000u; + counter_state = idle; + fired = 0u; + last_at = 0u; + again = false; + stop = false; + EMB_ASSERT_OK(emb_device_init(&counter_dev)); +} + +EMB_TEST(counter_count_rate_and_channels) +{ + uint64_t count = 0u; + uint32_t hz = 0u; + uint8_t n = 0u; + EMB_TEST_REQ("DRV-001"); + ready(); + EMB_ASSERT_OK(emb_drv_counter_now(&counter_dev, &count)); + EMB_ASSERT_TRUE(count == 1000u); + EMB_ASSERT_OK(emb_drv_counter_rate(&counter_dev, &hz)); + EMB_ASSERT_EQ(hz, 1000000u); + EMB_ASSERT_OK(emb_drv_counter_channels(&counter_dev, &n)); + EMB_ASSERT_EQ(n, 3u); /* the device's, fewer than the driver's four */ + EMB_ASSERT_STATUS(emb_drv_counter_alarm_set(&counter_dev, 3u, 2000u, on_alarm, &ch0), + EMB_EINVAL); +} + +EMB_TEST(counter_alarm_once_never_early) +{ + EMB_TEST_REQ("DRV-001"); + ready(); + EMB_ASSERT_OK(emb_drv_counter_alarm_set(&counter_dev, 0u, 1500u, on_alarm, &ch0)); + EMB_ASSERT_TRUE(fake.armed[0] && (fake.target[0] == 1500u)); + EMB_ASSERT_STATUS(emb_drv_counter_alarm_set(&counter_dev, 0u, 1600u, on_alarm, &ch0), + EMB_EBUSY); + EMB_ASSERT_OK(emb_drv_counter_alarm_set(&counter_dev, 1u, 1700u, on_alarm, &ch1)); /* another */ + reach(0u); + EMB_ASSERT_EQ(fired, 1u); + EMB_ASSERT_TRUE(last_at == 1500u); + EMB_ASSERT_STATUS(emb_drv_counter_fired(&counter_dev, 0u), EMB_ESTATE); /* a stray one */ + EMB_ASSERT_EQ(fired, 1u); + EMB_ASSERT_STATUS(emb_drv_counter_alarm_cancel(&counter_dev, 0u), EMB_ESTATE); /* it fired */ + EMB_ASSERT_OK(emb_drv_counter_alarm_cancel(&counter_dev, 1u)); + EMB_ASSERT_TRUE(!fake.armed[1]); + reach(1u); + EMB_ASSERT_EQ(fired, 1u); /* nothing after a cancel */ +} + +EMB_TEST(counter_alarm_passed_and_again) +{ + EMB_TEST_REQ("DRV-001"); + ready(); + EMB_ASSERT_STATUS(emb_drv_counter_alarm_set(&counter_dev, 0u, 1000u, on_alarm, &ch0), + EMB_EPAST); + EMB_ASSERT_STATUS(emb_drv_counter_alarm_set(&counter_dev, 0u, 10u, on_alarm, &ch0), EMB_EPAST); + EMB_ASSERT_STATUS(emb_drv_counter_alarm_cancel(&counter_dev, 0u), EMB_ESTATE); /* none armed */ + EMB_ASSERT_OK(emb_drv_counter_alarm_set(&counter_dev, 0u, 1100u, on_alarm, &ch0)); + again = true; + reach(0u); + EMB_ASSERT_EQ(fired, 1u); + EMB_ASSERT_TRUE(fake.armed[0] && (fake.target[0] == 1150u)); /* armed from its callback */ + reach(0u); + EMB_ASSERT_EQ(fired, 2u); +} + +EMB_TEST(counter_periodic_without_drift) +{ + EMB_TEST_REQ("DRV-001"); + ready(); + EMB_ASSERT_STATUS(emb_drv_counter_periodic(&counter_dev, 0u, 1u, on_alarm, &ch0), EMB_EINVAL); + EMB_ASSERT_OK(emb_drv_counter_periodic(&counter_dev, 0u, 1000u, on_alarm, &ch0)); + EMB_ASSERT_TRUE(fake.target[0] == 2000u); /* a period from now */ + EMB_ASSERT_STATUS(emb_drv_counter_alarm_cancel(&counter_dev, 0u), EMB_ESTATE); /* periodic */ + reach(0u); + EMB_ASSERT_TRUE((last_at == 2000u) && (fake.target[0] == 3000u)); + fake.now = 3040u; /* its interrupt 40 counts late: the next is still due at 4000 */ + (void)emb_drv_counter_fired(&counter_dev, 0u); + EMB_ASSERT_TRUE((last_at == 3000u) && (fake.target[0] == 4000u)); + fake.now = 6500u; /* held off past two periods: they are skipped, the next is 7000 */ + (void)emb_drv_counter_fired(&counter_dev, 0u); + EMB_ASSERT_TRUE((last_at == 4000u) && (fake.target[0] == 7000u)); + EMB_ASSERT_EQ(fired, 3u); + stop = true; /* it stops itself */ + reach(0u); + EMB_ASSERT_EQ(fired, 4u); + EMB_ASSERT_TRUE(!fake.armed[0]); + EMB_ASSERT_STATUS(emb_drv_counter_periodic_stop(&counter_dev, 0u), EMB_ESTATE); + EMB_ASSERT_STATUS(emb_drv_counter_fired(&counter_dev, 0u), EMB_ESTATE); + EMB_ASSERT_EQ(fired, 4u); +} + +EMB_TEST(counter_periodic_the_counter_cannot_keep) +{ + unsigned arms; + EMB_TEST_REQ("DRV-001"); + ready(); + EMB_ASSERT_OK(emb_drv_counter_periodic(&counter_dev, 1u, 2u, on_alarm, &ch1)); + fake.refuse = true; /* every next period has passed by the time it is armed */ + arms = fake.arms; + reach(1u); + EMB_ASSERT_EQ(fired, 1u); /* the period due still runs */ + EMB_ASSERT_EQ(fake.arms - arms, 4u); /* a bounded number of tries */ + EMB_ASSERT_STATUS(emb_drv_counter_periodic_stop(&counter_dev, 1u), EMB_ESTATE); /* stopped */ + fake.refuse = false; + EMB_ASSERT_OK(emb_drv_counter_alarm_set(&counter_dev, 1u, fake.now + 10u, on_alarm, &ch1)); +} + +EMB_TEST(counter_not_ready_and_misuse) +{ + uint64_t count = 0u; + uint32_t hz = 0u; + emb_device_state_t idle = {EMB_DEVICE_UNINIT, 0u, 0u, 0u, EMB_OK, {NULL, NULL}, {NULL, NULL}}; + EMB_TEST_REQ("DRV-001"); + counter_state = idle; + EMB_ASSERT_STATUS(emb_drv_counter_now(&counter_dev, &count), EMB_ESTATE); + EMB_ASSERT_STATUS(emb_drv_counter_rate(&counter_dev, &hz), EMB_ESTATE); + EMB_ASSERT_STATUS(emb_drv_counter_alarm_set(&counter_dev, 0u, 5000u, on_alarm, &ch0), + EMB_ESTATE); + EMB_ASSERT_STATUS(emb_drv_counter_periodic(&counter_dev, 0u, 100u, on_alarm, &ch0), EMB_ESTATE); + ready(); + EMB_ASSERT_FAULTS((void)emb_drv_counter_now(&plain_dev, &count)); /* not a counter */ + EMB_ASSERT_FAULTS((void)emb_drv_counter_now(&counter_dev, NULL)); + EMB_ASSERT_FAULTS((void)emb_drv_counter_alarm_set(&counter_dev, 0u, 5000u, NULL, NULL)); + EMB_ASSERT_FAULTS((void)emb_drv_counter_periodic(NULL, 0u, 100u, on_alarm, &ch0)); + EMB_ASSERT_FAULTS((void)emb_drv_counter_alarm_cancel(NULL, 0u)); +} diff --git a/tests/conformance/test_counter_board.c b/tests/conformance/test_counter_board.c new file mode 100644 index 00000000..c2f20894 --- /dev/null +++ b/tests/conformance/test_counter_board.c @@ -0,0 +1,217 @@ +/* SPDX-License-Identifier: Apache-2.0 */ +/* Copyright 2026 Junior Deogracias */ +/* + * This file is part of EmbLinkRTOS, a deterministic real-time kernel for microcontrollers. + * Licensed under the Apache License, Version 2.0; see the LICENSE file at the repository root. + */ + +/** + * @file test_counter_board.c + * @brief The board's counters (SPEC-017 §11a, A129): every device of the class it has. + * + * @details + * Each counter's rate against the kernel's clock; its count rising, across the wraps of a + * 16-bit timer (TIM9 on the NUCLEO-F446RE wraps every 65.5 ms); one-shot alarms, near and many + * wraps away, never early and at most LATE counts late; every channel; a passed count refused; + * a periodic callback whose periods are exact. + * + * @author teo1747 + * @date 2026-11-13 (created) + */ +#include +#include + +#define TICK_NS ((uint64_t)CONFIG_EMB_TICK_NS) +#define LATE 200u /* counts: an interrupt's latency, under an emulator too; a wrap is 65536 */ +#define PERIODS 100u +#define WAIT_MS 1u + +static const emb_device_t *const counters[] = {EMB_SOC_COUNTER_DEVICES}; + +static volatile unsigned fired; +static volatile uint64_t fired_count; /* the count when the callback ran */ +static volatile uint64_t fired_at; /* the count it was due at */ +static volatile uint64_t gaps; /* periodic: the periods between two calls, other than one */ +static volatile uint64_t worst; /* periodic: the latest a call ran after it was due */ +static const emb_device_t *current; +static uint64_t period; + +static void on_alarm(void *arg, uint64_t at) +{ + uint64_t count = 0u; + (void)arg; + (void)emb_drv_counter_now(current, &count); + fired_count = count; + fired_at = at; + fired++; +} + +static void on_period(void *arg, uint64_t at) +{ + uint64_t count = 0u; + uint8_t channel = *(const uint8_t *)arg; + (void)emb_drv_counter_now(current, &count); + if ((fired != 0u) && (at != fired_at + period)) { + gaps++; + } + if ((count - at) > worst) { + worst = count - at; + } + fired_at = at; + fired++; + if (fired == PERIODS) { + (void)emb_drv_counter_periodic_stop(current, channel); + } +} + +/* Wait, sleeping, until the callbacks have run n times or limit_ms passed. */ +static void wait_fired(unsigned n, uint32_t limit_ms) +{ + uint32_t ms; + for (ms = 0u; (ms < limit_ms) && (fired < n); ms += WAIT_MS) { /* bounded */ + (void)emb_thread_sleep(EMB_MS(WAIT_MS)); + } +} + +static uint64_t count_of(const emb_device_t *dev) +{ + uint64_t count = 0u; + EMB_ASSERT_OK(emb_drv_counter_now(dev, &count)); + return count; +} + +EMB_TEST(counter_board_rate_against_the_kernel_clock) +{ + unsigned i; + EMB_TEST_REQ("DRV-001"); + for (i = 0u; i < sizeof(counters) / sizeof(counters[0]); i++) { /* bounded */ + const emb_device_t *dev = counters[i]; + uint32_t hz = 0u; + uint64_t c0; + uint64_t c1; + uint64_t t0; + uint64_t t1; + uint64_t want; + uint64_t slack; + EMB_ASSERT_TRUE(emb_device_ready(dev)); + EMB_ASSERT_OK(emb_drv_counter_rate(dev, &hz)); + EMB_ASSERT_TRUE(hz > 0u); + (void)emb_thread_sleep(EMB_MS(1u)); /* start on a tick */ + t0 = emb_time_now().ticks; + c0 = count_of(dev); + (void)emb_thread_sleep(EMB_MS(150u)); /* two wraps of a 16-bit counter at 1 MHz */ + c1 = count_of(dev); + t1 = emb_time_now().ticks; + want = ((t1 - t0) * TICK_NS * hz) / 1000000000u; + slack = (2u * TICK_NS * hz) / 1000000000u + LATE; /* a tick at each end */ + EMB_ASSERT_TRUE(c1 > c0); + EMB_ASSERT_TRUE(((c1 - c0) + slack >= want) && ((c1 - c0) <= want + slack)); + } +} + +EMB_TEST(counter_board_count_rises_across_wraps) +{ + unsigned i; + EMB_TEST_REQ("DRV-001"); + for (i = 0u; i < sizeof(counters) / sizeof(counters[0]); i++) { /* bounded */ + const emb_device_t *dev = counters[i]; + uint64_t last = count_of(dev); + uint32_t n; + bool rising = true; + for (n = 0u; n < 200u; n++) { /* bounded: 200 ms, three wraps of a 16-bit counter */ + uint32_t k; + for (k = 0u; k < 100u; k++) { /* bounded: reads back to back */ + uint64_t c = count_of(dev); + rising = rising && (c >= last); + last = c; + } + (void)emb_thread_sleep(EMB_MS(1u)); + } + EMB_ASSERT_TRUE(rising); + } +} + +EMB_TEST(counter_board_alarms_never_early) +{ + static const uint32_t after[] = {500u, 3000u, 200000u}; /* the last, three wraps away */ + unsigned i; + unsigned k; + EMB_TEST_REQ("DRV-001"); + for (i = 0u; i < sizeof(counters) / sizeof(counters[0]); i++) { /* bounded */ + const emb_device_t *dev = counters[i]; + uint32_t hz = 0u; + current = dev; + EMB_ASSERT_OK(emb_drv_counter_rate(dev, &hz)); + for (k = 0u; k < sizeof(after) / sizeof(after[0]); k++) { /* bounded */ + uint64_t at = count_of(dev) + ((uint64_t)after[k] * hz / 1000000u); + fired = 0u; + EMB_ASSERT_OK(emb_drv_counter_alarm_set(dev, 0u, at, on_alarm, NULL)); + wait_fired(1u, (after[k] / 1000u) + 100u); + EMB_ASSERT_EQ(fired, 1u); + EMB_ASSERT_TRUE(fired_at == at); + EMB_ASSERT_TRUE(fired_count >= at); /* never early */ + EMB_ASSERT_TRUE(fired_count - at <= LATE); /* nor a wrap late */ + } + } +} + +EMB_TEST(counter_board_every_channel_and_a_passed_count) +{ + static uint8_t chans[EMB_DRV_COUNTER_CHANNELS_MAX] = {0u, 1u, 2u, 3u}; + unsigned i; + EMB_TEST_REQ("DRV-001"); + for (i = 0u; i < sizeof(counters) / sizeof(counters[0]); i++) { /* bounded */ + const emb_device_t *dev = counters[i]; + uint8_t n = 0u; + uint8_t ch; + uint64_t now; + current = dev; + EMB_ASSERT_OK(emb_drv_counter_channels(dev, &n)); + EMB_ASSERT_TRUE((n >= 1u) && (n <= EMB_DRV_COUNTER_CHANNELS_MAX)); + now = count_of(dev); + EMB_ASSERT_STATUS(emb_drv_counter_alarm_set(dev, 0u, now, on_alarm, NULL), EMB_EPAST); + EMB_ASSERT_STATUS(emb_drv_counter_alarm_set(dev, n, now + 1000u, on_alarm, NULL), + EMB_EINVAL); + fired = 0u; + now = count_of(dev); + for (ch = 0u; ch < n; ch++) { /* bounded */ + EMB_ASSERT_OK(emb_drv_counter_alarm_set(dev, ch, now + 2000u + (1000u * ch), on_alarm, + &chans[ch])); + } + EMB_ASSERT_STATUS(emb_drv_counter_alarm_set(dev, 0u, now + 9000u, on_alarm, NULL), + EMB_EBUSY); + wait_fired(n, 100u); + EMB_ASSERT_EQ(fired, (unsigned)n); + EMB_ASSERT_TRUE(fired_at == now + 2000u + (1000u * (n - 1u))); /* in order, the last last */ + EMB_ASSERT_OK(emb_drv_counter_alarm_set(dev, 0u, count_of(dev) + 50000u, on_alarm, NULL)); + EMB_ASSERT_OK(emb_drv_counter_alarm_cancel(dev, 0u)); + fired = 0u; + (void)emb_thread_sleep(EMB_MS(80u)); + EMB_ASSERT_EQ(fired, 0u); /* nothing after a cancel */ + } +} + +EMB_TEST(counter_board_periodic_exact_periods) +{ + static uint8_t ch0 = 0u; + unsigned i; + EMB_TEST_REQ("DRV-001"); + for (i = 0u; i < sizeof(counters) / sizeof(counters[0]); i++) { /* bounded */ + const emb_device_t *dev = counters[i]; + uint32_t hz = 0u; + current = dev; + EMB_ASSERT_OK(emb_drv_counter_rate(dev, &hz)); + period = hz / 1000u; /* a millisecond */ + fired = 0u; + gaps = 0u; + worst = 0u; + EMB_ASSERT_OK(emb_drv_counter_periodic(dev, 0u, period, on_period, &ch0)); + wait_fired(PERIODS, (PERIODS * 2u) + 100u); + EMB_ASSERT_EQ(fired, PERIODS); + EMB_ASSERT_TRUE(gaps == 0u); /* each a period after the last was due */ + EMB_ASSERT_TRUE(worst <= LATE); /* and run soon after */ + (void)emb_thread_sleep(EMB_MS(5u)); + EMB_ASSERT_EQ(fired, PERIODS); /* stopped from its own callback */ + EMB_ASSERT_STATUS(emb_drv_counter_periodic_stop(dev, 0u), EMB_ESTATE); + } +} diff --git a/tests/conformance/test_device.c b/tests/conformance/test_device.c index 71ba8112..54ab78a0 100644 --- a/tests/conformance/test_device.c +++ b/tests/conformance/test_device.c @@ -522,20 +522,22 @@ EMB_TEST(drv_status_codes_are_named_in_their_ranges) {EMB_EXFER, "EMB_EXFER"}, {EMB_EWINDOW, "EMB_EWINDOW"}, {EMB_EWRPROT, "EMB_EWRPROT"}, {EMB_EVERIFY, "EMB_EVERIFY"}, {EMB_ENOTSET, "EMB_ENOTSET"}, {EMB_EOSCFAIL, "EMB_EOSCFAIL"}, - {EMB_EHEALTH, "EMB_EHEALTH"}, + {EMB_EHEALTH, "EMB_EHEALTH"}, {EMB_EPAST, "EMB_EPAST"}, + {EMB_ENOSIGNAL, "EMB_ENOSIGNAL"}, }; unsigned i; EMB_TEST_REQ("DRV-008"); for (i = 0u; i < sizeof(codes) / sizeof(codes[0]); i++) { /* bounded by the table */ /* in the driver range, each class's four codes apart from the others' */ - EMB_ASSERT_TRUE(codes[i].code <= -64 && codes[i].code >= -95); + EMB_ASSERT_TRUE(codes[i].code <= -64 && codes[i].code >= -107); EMB_ASSERT_TRUE(i == 0u || codes[i].code < codes[i - 1u].code); #if CONFIG_EMB_STATUS_NAMES EMB_ASSERT_TRUE(strcmp(emb_status_name(codes[i].code), codes[i].name) == 0); #endif } #if CONFIG_EMB_STATUS_NAMES - EMB_ASSERT_TRUE(strcmp(emb_status_name(-67), "EMB_E?") == 0); /* the UART's spare code */ - EMB_ASSERT_TRUE(strcmp(emb_status_name(-96), "EMB_E?") == 0); /* past M4's classes */ + EMB_ASSERT_TRUE(strcmp(emb_status_name(-67), "EMB_E?") == 0); /* the UART's spare code */ + EMB_ASSERT_TRUE(strcmp(emb_status_name(-104), "EMB_E?") == 0); /* the ADC's, none yet */ + EMB_ASSERT_TRUE(strcmp(emb_status_name(-108), "EMB_E?") == 0); /* past M4's classes */ #endif } diff --git a/tests/conformance/test_pwm.c b/tests/conformance/test_pwm.c new file mode 100644 index 00000000..8eb623d5 --- /dev/null +++ b/tests/conformance/test_pwm.c @@ -0,0 +1,201 @@ +/* SPDX-License-Identifier: Apache-2.0 */ +/* Copyright 2026 Junior Deogracias */ +/* + * This file is part of EmbLinkRTOS, a deterministic real-time kernel for microcontrollers. + * Licensed under the Apache License, Version 2.0; see the LICENSE file at the repository root. + */ + +/** + * @file test_pwm.c + * @brief The PWM class (SPEC-017 §11b, A129). + * + * @details + * Its checks over a driver's operations, through a fake whose steps are 100 ns: an output set, + * rounded and reported; the period a device's running channels share; a stop; a capture, and a + * channel that outputs or captures but not both; a driver that captures nothing. + * + * @author teo1747 + * @date 2026-11-13 (created) + */ +#include +#include + +#define STEP 100u /* the fake's resolution, ns */ + +typedef struct fake_pwm { + emb_drv_pwm_data_t pwm; /* the class's, first */ + uint32_t period[EMB_DRV_PWM_CHANNELS_MAX]; + uint32_t pulse[EMB_DRV_PWM_CHANNELS_MAX]; + uint32_t flags[EMB_DRV_PWM_CHANNELS_MAX]; + bool on[EMB_DRV_PWM_CHANNELS_MAX]; + emb_drv_pwm_wave_t input; /* what a capture measures */ + emb_status_t capture_status; + emb_status_t set_during_capture; +} fake_pwm_t; + +static fake_pwm_t fake; +static emb_device_state_t pwm_state; +static emb_device_state_t plain_state; + +static emb_status_t fake_init(const emb_device_t *dev) +{ + return emb_drv_pwm_started(dev, 2u); +} + +static uint32_t nearest(uint32_t ns) +{ + return ((ns + (STEP / 2u)) / STEP) * STEP; +} + +static emb_status_t fake_set(const emb_device_t *dev, uint8_t channel, uint32_t period_ns, + uint32_t pulse_ns, uint32_t flags, emb_drv_pwm_wave_t *got) +{ + (void)dev; + if (period_ns > 1000000000u) { + return EMB_EINVAL; /* beyond its reach */ + } + fake.period[channel] = nearest(period_ns); + fake.pulse[channel] = nearest(pulse_ns); + fake.flags[channel] = flags; + fake.on[channel] = true; + if (got != NULL) { + got->period_ns = fake.period[channel]; + got->pulse_ns = fake.pulse[channel]; + } + return EMB_OK; +} + +static void fake_stop(const emb_device_t *dev, uint8_t channel) +{ + (void)dev; + fake.on[channel] = false; +} + +static const emb_device_t pwm_dev; + +static emb_status_t fake_capture(const emb_device_t *dev, uint8_t channel, emb_drv_pwm_wave_t *wave, + emb_timeout_t timeout) +{ + (void)dev; + (void)timeout; + /* while it captures, the channel cannot output */ + fake.set_during_capture = emb_drv_pwm_set(&pwm_dev, channel, 1000u, 500u, 0u, NULL); + if (fake.capture_status == EMB_OK) { + *wave = fake.input; + } + return fake.capture_status; +} + +static const emb_drv_pwm_api_t fake_api = { + {fake_init, NULL, NULL, NULL, NULL, EMB_DRV_PWM_CAP_CAPTURE}, + fake_set, + fake_stop, + fake_capture, + 4u, + {0u, 0u, 0u}, +}; +static const emb_device_t pwm_dev = { + "pwm", &fake_api.dev, NULL, &pwm_state, &fake, NULL, EMB_DRV_CLASS_PWM, EMB_DEVICE_KERNEL, 0u}; + +/* a driver with outputs alone */ +static fake_pwm_t plain; +static const emb_drv_pwm_api_t plain_api = { + {fake_init, NULL, NULL, NULL, NULL, 0u}, fake_set, fake_stop, NULL, 4u, {0u, 0u, 0u}, +}; +static const emb_device_t plain_dev = { + "plain", &plain_api.dev, NULL, &plain_state, &plain, NULL, + EMB_DRV_CLASS_PWM, EMB_DEVICE_KERNEL, 0u}; + +/* The device started once, as at boot: its lock is made once. Each case after resets the fake + * and stops what the last one left running. */ +static void ready(void) +{ + static bool started; + uint8_t ch; + if (!started) { + emb_device_state_t idle = {EMB_DEVICE_UNINIT, 0u, 0u, 0u, EMB_OK, + {NULL, NULL}, {NULL, NULL}}; + pwm_state = idle; + EMB_ASSERT_OK(emb_device_init(&pwm_dev)); + started = true; + } + for (ch = 0u; ch < 2u; ch++) { /* bounded */ + (void)emb_drv_pwm_stop(&pwm_dev, ch); + } + (void)memset((uint8_t *)&fake + sizeof(fake.pwm), 0, sizeof(fake) - sizeof(fake.pwm)); +} + +EMB_TEST(pwm_set_rounded_and_reported) +{ + emb_drv_pwm_wave_t got = {0u, 0u}; + uint8_t n = 0u; + EMB_TEST_REQ("DRV-001"); + ready(); + EMB_ASSERT_OK(emb_drv_pwm_channels(&pwm_dev, &n)); + EMB_ASSERT_EQ(n, 2u); /* the device's, fewer than the driver's four */ + EMB_ASSERT_OK(emb_drv_pwm_set(&pwm_dev, 0u, 1000040u, 250060u, 0u, &got)); + EMB_ASSERT_EQ(got.period_ns, 1000000u); + EMB_ASSERT_EQ(got.pulse_ns, 250100u); + EMB_ASSERT_TRUE(fake.on[0]); + EMB_ASSERT_OK(emb_drv_pwm_set(&pwm_dev, 0u, 1000040u, 500000u, EMB_DRV_PWM_INVERTED, NULL)); + EMB_ASSERT_EQ(fake.flags[0], EMB_DRV_PWM_INVERTED); /* a running channel takes a new pulse */ + EMB_ASSERT_STATUS(emb_drv_pwm_set(&pwm_dev, 0u, 1000u, 1001u, 0u, NULL), EMB_EINVAL); + EMB_ASSERT_STATUS(emb_drv_pwm_set(&pwm_dev, 0u, 0u, 0u, 0u, NULL), EMB_EINVAL); + EMB_ASSERT_STATUS(emb_drv_pwm_set(&pwm_dev, 2u, 1000u, 500u, 0u, NULL), EMB_EINVAL); + EMB_ASSERT_OK(emb_drv_pwm_stop(&pwm_dev, 0u)); /* alone: the period is the driver's to refuse */ + EMB_ASSERT_STATUS(emb_drv_pwm_set(&pwm_dev, 1u, 2000000000u, 0u, 0u, NULL), EMB_EINVAL); + EMB_ASSERT_TRUE(!fake.on[1]); /* the driver's refusal: nothing runs */ +} + +EMB_TEST(pwm_channels_share_the_period) +{ + EMB_TEST_REQ("DRV-001"); + ready(); + EMB_ASSERT_OK(emb_drv_pwm_set(&pwm_dev, 0u, 20000u, 5000u, 0u, NULL)); + EMB_ASSERT_STATUS(emb_drv_pwm_set(&pwm_dev, 1u, 30000u, 5000u, 0u, NULL), EMB_EBUSY); + EMB_ASSERT_OK(emb_drv_pwm_set(&pwm_dev, 1u, 20000u, 15000u, 0u, NULL)); /* the same period */ + EMB_ASSERT_STATUS(emb_drv_pwm_set(&pwm_dev, 0u, 30000u, 5000u, 0u, NULL), EMB_EBUSY); + EMB_ASSERT_OK(emb_drv_pwm_stop(&pwm_dev, 1u)); + EMB_ASSERT_TRUE(!fake.on[1]); + EMB_ASSERT_STATUS(emb_drv_pwm_stop(&pwm_dev, 1u), EMB_ESTATE); /* not running */ + EMB_ASSERT_OK(emb_drv_pwm_set(&pwm_dev, 0u, 30000u, 5000u, 0u, NULL)); /* alone: its own */ +} + +EMB_TEST(pwm_capture_and_its_channel) +{ + emb_drv_pwm_wave_t wave = {0u, 0u}; + EMB_TEST_REQ("DRV-001"); + ready(); + fake.input.period_ns = 1000000u; + fake.input.pulse_ns = 250000u; + EMB_ASSERT_OK(emb_drv_pwm_capture(&pwm_dev, 1u, &wave, EMB_TIMEOUT(EMB_MS(100)))); + EMB_ASSERT_EQ(wave.period_ns, 1000000u); + EMB_ASSERT_EQ(wave.pulse_ns, 250000u); + EMB_ASSERT_STATUS(fake.set_during_capture, EMB_EBUSY); /* it captured: no output meanwhile */ + EMB_ASSERT_OK(emb_drv_pwm_set(&pwm_dev, 1u, 1000u, 500u, 0u, NULL)); /* free again after */ + EMB_ASSERT_STATUS(emb_drv_pwm_capture(&pwm_dev, 1u, &wave, EMB_NO_WAIT), + EMB_EBUSY); /* it outputs */ + EMB_ASSERT_OK(emb_drv_pwm_stop(&pwm_dev, 1u)); + fake.capture_status = EMB_ENOSIGNAL; + EMB_ASSERT_STATUS(emb_drv_pwm_capture(&pwm_dev, 1u, &wave, EMB_TIMEOUT(EMB_MS(10))), + EMB_ENOSIGNAL); + EMB_ASSERT_STATUS(emb_drv_pwm_capture(&pwm_dev, 2u, &wave, EMB_NO_WAIT), EMB_EINVAL); +} + +EMB_TEST(pwm_without_capture_and_misuse) +{ + emb_drv_pwm_wave_t wave = {0u, 0u}; + emb_device_state_t idle = {EMB_DEVICE_UNINIT, 0u, 0u, 0u, EMB_OK, {NULL, NULL}, {NULL, NULL}}; + EMB_TEST_REQ("DRV-001"); + plain_state = idle; + EMB_ASSERT_STATUS(emb_drv_pwm_set(&plain_dev, 0u, 1000u, 500u, 0u, NULL), + EMB_ESTATE); /* not READY */ + EMB_ASSERT_OK(emb_device_init(&plain_dev)); + EMB_ASSERT_STATUS(emb_drv_pwm_capture(&plain_dev, 0u, &wave, EMB_NO_WAIT), EMB_ENOTSUP); + EMB_ASSERT_OK(emb_drv_pwm_set(&plain_dev, 0u, 1000u, 500u, 0u, NULL)); + ready(); + EMB_ASSERT_FAULTS((void)emb_drv_pwm_set(&pwm_dev, 0u, 1000u, 500u, 0x80u, NULL)); /* a flag */ + EMB_ASSERT_FAULTS((void)emb_drv_pwm_capture(&pwm_dev, 0u, NULL, EMB_NO_WAIT)); + EMB_ASSERT_FAULTS((void)emb_drv_pwm_stop(NULL, 0u)); + EMB_ASSERT_FAULTS((void)emb_drv_pwm_channels(&pwm_dev, NULL)); +} diff --git a/tests/conformance/test_pwm_loop.c b/tests/conformance/test_pwm_loop.c new file mode 100644 index 00000000..0b37a735 --- /dev/null +++ b/tests/conformance/test_pwm_loop.c @@ -0,0 +1,132 @@ +/* SPDX-License-Identifier: Apache-2.0 */ +/* Copyright 2026 Junior Deogracias */ +/* + * This file is part of EmbLinkRTOS, a deterministic real-time kernel for microcontrollers. + * Licensed under the Apache License, Version 2.0; see the LICENSE file at the repository root. + */ + +/** + * @file test_pwm_loop.c + * @brief A PWM output wired to a capture input (SPEC-017 §11b, A129). + * + * @details + * EMB_TEST_PWM_OUT's channel drives EMB_TEST_PWM_IN's: each wave set is captured back within + * TOLERANCE of what the hardware reported making, from 50 kHz to 100 Hz; inverted, the pulse is + * the rest of the period; a steady output has no cycle; a running output is not captured. + * Bench: the NUCLEO-F446RE's D12 (PA6, TIM3 channel 1) to D10 (PB6, TIM4 channel 1); the Pico 2 + * W's pin 19 (GPIO14, slice 7 A) to pin 22 (GPIO17, slice 0 B). + * + * @author teo1747 + * @date 2026-11-13 (created) + */ +#include +#include +#include + +#define OUT EMB_TEST_PWM_OUT +#define OUT_CH EMB_TEST_PWM_OUT_CH +#define IN EMB_TEST_PWM_IN +#define IN_CH EMB_TEST_PWM_IN_CH +#define WAIT EMB_TIMEOUT(EMB_MS(400u)) + +/* A capture's error: a thousandth of the period, and 60 ns, a few clocks of either timer. */ +static uint32_t tolerance(uint32_t period_ns) +{ + return (period_ns / 1000u) + 60u; +} + +static bool near(uint32_t a, uint32_t b, uint32_t tol) +{ + return ((a > b) ? (a - b) : (b - a)) <= tol; +} + +/* A number on the console, for the record of what each wave measured. */ +static void put_u32(uint32_t v) +{ + char text[11]; + unsigned n = 0u; + char out[12]; + unsigned i; + do { /* bounded: ten digits */ + text[n] = (char)('0' + (char)(v % 10u)); + n++; + v /= 10u; + } while ((v != 0u) && (n < sizeof(text))); + for (i = 0u; i < n; i++) { /* bounded */ + out[i] = text[n - 1u - i]; + } + out[n] = '\0'; + emb_board_puts(out); +} + +/* "PWM : made , captured ", in ns */ +static void note(uint32_t period_ns, uint32_t pulse_ns, const emb_drv_pwm_wave_t *got, + const emb_drv_pwm_wave_t *wave) +{ + emb_board_puts("PWM "); + put_u32(period_ns); + emb_board_puts(" "); + put_u32(pulse_ns); + emb_board_puts(": made "); + put_u32(got->period_ns); + emb_board_puts(" "); + put_u32(got->pulse_ns); + emb_board_puts(", captured "); + put_u32(wave->period_ns); + emb_board_puts(" "); + put_u32(wave->pulse_ns); + emb_board_puts("\n"); +} + +static void loop_once(uint32_t period_ns, uint32_t pulse_ns, uint32_t flags) +{ + emb_drv_pwm_wave_t got = {0u, 0u}; + emb_drv_pwm_wave_t wave = {0u, 0u}; + uint32_t high; + EMB_ASSERT_OK(emb_drv_pwm_set(OUT, OUT_CH, period_ns, pulse_ns, flags, &got)); + EMB_ASSERT_TRUE(near(got.period_ns, period_ns, tolerance(period_ns))); /* its nearest */ + (void)emb_thread_sleep(EMB_MS(2u)); /* a few periods out */ + EMB_ASSERT_OK(emb_drv_pwm_capture(IN, IN_CH, &wave, WAIT)); + note(period_ns, pulse_ns, &got, &wave); + high = ((flags & EMB_DRV_PWM_INVERTED) != 0u) ? (got.period_ns - got.pulse_ns) : got.pulse_ns; + EMB_ASSERT_TRUE(near(wave.period_ns, got.period_ns, tolerance(got.period_ns))); + EMB_ASSERT_TRUE(near(wave.pulse_ns, high, tolerance(got.period_ns))); + EMB_ASSERT_OK(emb_drv_pwm_stop(OUT, OUT_CH)); +} + +EMB_TEST(pwm_loop_waves_captured_back) +{ + EMB_TEST_REQ("DRV-001"); + EMB_ASSERT_TRUE(emb_device_ready(OUT) && emb_device_ready(IN)); + loop_once(1000000u, 250000u, 0u); /* 1 kHz, a quarter */ + loop_once(100000u, 50000u, 0u); /* 10 kHz, a half */ +} + +EMB_TEST(pwm_loop_fast_and_slow) +{ + EMB_TEST_REQ("DRV-001"); + loop_once(20000u, 15000u, 0u); /* 50 kHz, three quarters */ + loop_once(10000000u, 1000000u, 0u); /* 100 Hz, a tenth: 13 wraps of a 16-bit counter */ +} + +EMB_TEST(pwm_loop_inverted) +{ + EMB_TEST_REQ("DRV-001"); + loop_once(1000000u, 250000u, EMB_DRV_PWM_INVERTED); /* high for three quarters */ +} + +EMB_TEST(pwm_loop_steady_and_busy) +{ + emb_drv_pwm_wave_t wave = {0u, 0u}; + EMB_TEST_REQ("DRV-001"); + EMB_ASSERT_OK(emb_drv_pwm_set(OUT, OUT_CH, 1000000u, 0u, 0u, NULL)); /* low throughout */ + EMB_ASSERT_STATUS(emb_drv_pwm_capture(IN, IN_CH, &wave, EMB_TIMEOUT(EMB_MS(100u))), + EMB_ENOSIGNAL); + EMB_ASSERT_OK(emb_drv_pwm_set(OUT, OUT_CH, 1000000u, 1000000u, 0u, NULL)); /* high throughout */ + EMB_ASSERT_STATUS(emb_drv_pwm_capture(IN, IN_CH, &wave, EMB_TIMEOUT(EMB_MS(100u))), + EMB_ENOSIGNAL); + EMB_ASSERT_STATUS(emb_drv_pwm_capture(OUT, OUT_CH, &wave, EMB_NO_WAIT), + EMB_EBUSY); /* it outputs */ + EMB_ASSERT_OK(emb_drv_pwm_stop(OUT, OUT_CH)); + EMB_ASSERT_STATUS(emb_drv_pwm_stop(OUT, OUT_CH), EMB_ESTATE); +} diff --git a/tools/dev/file_headers.py b/tools/dev/file_headers.py index 9137d536..e4978929 100644 --- a/tools/dev/file_headers.py +++ b/tools/dev/file_headers.py @@ -32,7 +32,9 @@ Not touched: third-party code, archived evidence (its sources are records of a run), and files under another licence. Generated files are the generator's to write: `--check` only checks that -they carry the same notice and an @file block, without an author or a date. +they carry the same notice and an @file block, without an author or a date. An application's +files in MPLAB Harmony's form (A130) carry the notice and then Harmony's banner, which names the +file under "File Name:". """ import argparse import datetime @@ -77,9 +79,13 @@ def sources(): lines = path.read_text(encoding="utf-8").split("\n") except (UnicodeDecodeError, ValueError): continue # not text - gen = "/generated/" in rel # the generator writes it (hw/gen/emb_hwgen/emit.py) + # the generator writes it (hw/gen/emb_hwgen/emit.py): a board's generated/, an + # application's configuration folder (A130) + gen = "/generated/" in rel or "/src/config/" in rel if rel.endswith(SUFFIXES) and len(lines) > 1 and lines[0] == SPDX: - if gen: + if harmony(lines): + yield rel, path, lines, "harmony" + elif gen: yield rel, path, lines, "c-gen" elif lines[1].startswith("/* Copyright "): yield rel, path, lines, "c" @@ -281,6 +287,32 @@ def hash_problems(rel, lines): return ["no EmbLinkRTOS notice after the copyright lines (tools/dev/file_headers.py --write)"] +HARMONY_BANNER = "/" + "*" * 79 + + +def harmony(lines): + """An application's file in MPLAB Harmony's form (A130): the notice, then Harmony's banner.""" + at = 1 + len(NOTICE) + return lines[1:at] == NOTICE and lines[at:at + 2] == ["", HARMONY_BANNER] + + +def harmony_problems(rel, lines): + """Harmony's banner names the file under "File Name:", and closes.""" + at = 2 + len(NOTICE) + banner = [] + for line in lines[at + 1:at + 200]: + if line.endswith("*/"): + break + banner.append(line) + else: + return ["Harmony's banner does not close"] + name = pathlib.PurePosixPath(rel).name + if " File Name:" not in banner or banner.index(" File Name:") + 1 >= len(banner) \ + or banner[banner.index(" File Name:") + 1].strip() != name: + return [f"Harmony's banner does not name {name} under File Name:"] + return [] + + def hash_generated_problems(rel, lines): if lines[1:1 + len(HASH_NOTICE)] == HASH_NOTICE: return [] @@ -331,7 +363,7 @@ def main(): names = [rel for rel, _, _, kind in every if kind == "c"] chosen = [s for s in every if not args.files or s[0] in set(args.files)] checks = {"c": problems, "c-gen": generated_problems, "hash": hash_problems, - "hash-gen": hash_generated_problems} + "hash-gen": hash_generated_problems, "harmony": harmony_problems} failed = changed = 0 for rel, path, lines, kind in chosen: if args.check: @@ -339,8 +371,8 @@ def main(): print(f"{rel}: {p}") failed += 1 continue - if kind.endswith("-gen"): - continue # the generator's to write + if kind.endswith("-gen") or kind == "harmony": + continue # the generator's to write, or Harmony's form (A130) if kind == "hash": if not hash_converted(lines): path.write_text("\n".join(hash_convert(lines)), encoding="utf-8") diff --git a/tools/dev/test_file_headers.py b/tools/dev/test_file_headers.py index d5196762..8ae7c6e7 100644 --- a/tools/dev/test_file_headers.py +++ b/tools/dev/test_file_headers.py @@ -112,8 +112,21 @@ def test_generated_file(self): def test_the_generator_writes_the_same_notice(self): sys.path.insert(0, str(fh.ROOT / "hw/gen")) - from emb_hwgen import emit + from emb_hwgen import emit, emit_system self.assertEqual(emit.NOTICE, "\n".join(fh.NOTICE) + "\n") + self.assertEqual(emit_system.NOTICE, emit.NOTICE) # A130's Harmony files carry it too + + def test_harmony_file(self): + """A130: an application's file in Harmony's form, its banner naming the file.""" + good = [fh.SPDX] + fh.NOTICE + ["", fh.HARMONY_BANNER, " Main Source File", "", " File Name:", + " main.c", "", " Summary:", " The entry point.", + " " + "*" * 79 + "/", "", "int main(void);"] + self.assertTrue(fh.harmony(good)) + self.assertEqual(fh.harmony_problems("examples/x/src/main.c", good), []) + self.assertEqual(fh.harmony_problems("examples/x/src/other.c", good), + ["Harmony's banner does not name other.c under File Name:"]) + self.assertEqual(fh.harmony_problems("examples/x/src/main.c", good[:9]), ["Harmony's banner does not close"]) + self.assertFalse(fh.harmony([fh.SPDX] + fh.NOTICE + ["", "/**"])) class Hash(unittest.TestCase): diff --git a/tools/fault/api-ids.json b/tools/fault/api-ids.json index 293d0860..10b4ccbb 100644 --- a/tools/fault/api-ids.json +++ b/tools/fault/api-ids.json @@ -1543,6 +1543,138 @@ "name": "emb_trace_stats_get", "header": "trace.h", "state": "active" + }, + { + "id": 261, + "name": "emb_drv_counter_now", + "header": "drv_counter.h", + "state": "active" + }, + { + "id": 262, + "name": "emb_drv_counter_rate", + "header": "drv_counter.h", + "state": "active" + }, + { + "id": 263, + "name": "emb_drv_counter_channels", + "header": "drv_counter.h", + "state": "active" + }, + { + "id": 264, + "name": "emb_drv_counter_alarm_set", + "header": "drv_counter.h", + "state": "active" + }, + { + "id": 265, + "name": "emb_drv_counter_alarm_cancel", + "header": "drv_counter.h", + "state": "active" + }, + { + "id": 266, + "name": "emb_drv_counter_periodic", + "header": "drv_counter.h", + "state": "active" + }, + { + "id": 267, + "name": "emb_drv_counter_periodic_stop", + "header": "drv_counter.h", + "state": "active" + }, + { + "id": 268, + "name": "emb_drv_counter_started", + "header": "drv_counter.h", + "state": "active" + }, + { + "id": 269, + "name": "emb_drv_counter_fired", + "header": "drv_counter.h", + "state": "active" + }, + { + "id": 270, + "name": "emb_drv_pwm_set", + "header": "drv_pwm.h", + "state": "active" + }, + { + "id": 271, + "name": "emb_drv_pwm_stop", + "header": "drv_pwm.h", + "state": "active" + }, + { + "id": 272, + "name": "emb_drv_pwm_capture", + "header": "drv_pwm.h", + "state": "active" + }, + { + "id": 273, + "name": "emb_drv_pwm_channels", + "header": "drv_pwm.h", + "state": "active" + }, + { + "id": 274, + "name": "emb_drv_pwm_started", + "header": "drv_pwm.h", + "state": "active" + }, + { + "id": 275, + "name": "emb_drv_adc_read", + "header": "drv_adc.h", + "state": "active" + }, + { + "id": 276, + "name": "emb_drv_adc_read_polled", + "header": "drv_adc.h", + "state": "active" + }, + { + "id": 277, + "name": "emb_drv_adc_to_mv", + "header": "drv_adc.h", + "state": "active" + }, + { + "id": 278, + "name": "emb_drv_adc_temperature", + "header": "drv_adc.h", + "state": "active" + }, + { + "id": 279, + "name": "emb_drv_adc_sample_start", + "header": "drv_adc.h", + "state": "active" + }, + { + "id": 280, + "name": "emb_drv_adc_sample_stop", + "header": "drv_adc.h", + "state": "active" + }, + { + "id": 281, + "name": "emb_drv_adc_started", + "header": "drv_adc.h", + "state": "active" + }, + { + "id": 282, + "name": "emb_drv_adc_sampled", + "header": "drv_adc.h", + "state": "active" } ] } diff --git a/tools/fault/api-registry.json b/tools/fault/api-registry.json index 3ba9016f..2056d0eb 100644 --- a/tools/fault/api-registry.json +++ b/tools/fault/api-registry.json @@ -1542,6 +1542,138 @@ "name": "emb_trace_stats_get", "header": "trace.h", "state": "active" + }, + { + "id": 261, + "name": "emb_drv_counter_now", + "header": "drv_counter.h", + "state": "active" + }, + { + "id": 262, + "name": "emb_drv_counter_rate", + "header": "drv_counter.h", + "state": "active" + }, + { + "id": 263, + "name": "emb_drv_counter_channels", + "header": "drv_counter.h", + "state": "active" + }, + { + "id": 264, + "name": "emb_drv_counter_alarm_set", + "header": "drv_counter.h", + "state": "active" + }, + { + "id": 265, + "name": "emb_drv_counter_alarm_cancel", + "header": "drv_counter.h", + "state": "active" + }, + { + "id": 266, + "name": "emb_drv_counter_periodic", + "header": "drv_counter.h", + "state": "active" + }, + { + "id": 267, + "name": "emb_drv_counter_periodic_stop", + "header": "drv_counter.h", + "state": "active" + }, + { + "id": 268, + "name": "emb_drv_counter_started", + "header": "drv_counter.h", + "state": "active" + }, + { + "id": 269, + "name": "emb_drv_counter_fired", + "header": "drv_counter.h", + "state": "active" + }, + { + "id": 270, + "name": "emb_drv_pwm_set", + "header": "drv_pwm.h", + "state": "active" + }, + { + "id": 271, + "name": "emb_drv_pwm_stop", + "header": "drv_pwm.h", + "state": "active" + }, + { + "id": 272, + "name": "emb_drv_pwm_capture", + "header": "drv_pwm.h", + "state": "active" + }, + { + "id": 273, + "name": "emb_drv_pwm_channels", + "header": "drv_pwm.h", + "state": "active" + }, + { + "id": 274, + "name": "emb_drv_pwm_started", + "header": "drv_pwm.h", + "state": "active" + }, + { + "id": 275, + "name": "emb_drv_adc_read", + "header": "drv_adc.h", + "state": "active" + }, + { + "id": 276, + "name": "emb_drv_adc_read_polled", + "header": "drv_adc.h", + "state": "active" + }, + { + "id": 277, + "name": "emb_drv_adc_to_mv", + "header": "drv_adc.h", + "state": "active" + }, + { + "id": 278, + "name": "emb_drv_adc_temperature", + "header": "drv_adc.h", + "state": "active" + }, + { + "id": 279, + "name": "emb_drv_adc_sample_start", + "header": "drv_adc.h", + "state": "active" + }, + { + "id": 280, + "name": "emb_drv_adc_sample_stop", + "header": "drv_adc.h", + "state": "active" + }, + { + "id": 281, + "name": "emb_drv_adc_started", + "header": "drv_adc.h", + "state": "active" + }, + { + "id": 282, + "name": "emb_drv_adc_sampled", + "header": "drv_adc.h", + "state": "active" } ] } diff --git a/tools/footprint/stack_bound.py b/tools/footprint/stack_bound.py index 9074683b..96aa6802 100644 --- a/tools/footprint/stack_bound.py +++ b/tools/footprint/stack_bound.py @@ -9,7 +9,7 @@ stack_bound.py --elf build/controller/controller.elf --build build/controller \\ --roots examples/controller/stack-roots.json [--objdump arm-none-eabi-objdump] \\ - [--system examples/controller/generated/nucleo_f446re/system.json] [--json out.json] + [--system examples/controller/src/config/nucleo_f446re/docs/system.json] [--json out.json] With --system, the threads a system description declares (SPEC-014 §5, A125) are taken from its generated system.json, each with its entry and its stack: the roots file then lists only