diff --git a/.github/.wordlist.txt b/.github/.wordlist.txt index e572827bac80d2..05a46e2da0395e 100644 --- a/.github/.wordlist.txt +++ b/.github/.wordlist.txt @@ -1276,6 +1276,9 @@ StatusCode stderr stdout sterm +stmicroelectronics +stm +stlink storagepath str strcpy @@ -1352,6 +1355,7 @@ ThreadNetworkDiagnostics threadOperationalDataset ThreadStackManager ThreadStackManagerImpl +thread ths Thunderboard timedInteractionTimeoutMs diff --git a/.github/workflows/examples-stm32.yaml b/.github/workflows/examples-stm32.yaml new file mode 100644 index 00000000000000..15f80dd84350be --- /dev/null +++ b/.github/workflows/examples-stm32.yaml @@ -0,0 +1,71 @@ +# Copyright (c) 2020-2021 Project CHIP Authors +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +name: Build example - stm32 + +on: + push: + pull_request: + merge_group: + +concurrency: + group: ${{ github.ref }}-${{ github.workflow }}-${{ (github.event_name == 'pull_request' && github.event.number) || (github.event_name == 'workflow_dispatch' && github.run_number) || github.sha }} + cancel-in-progress: true + +env: + CHIP_NO_LOG_TIMESTAMPS: true + +jobs: + stm32: + name: stm32 + timeout-minutes: 60 + + env: + BUILD_TYPE: gn_stm32 + + runs-on: ubuntu-latest + if: github.actor != 'restyled-io[bot]' + + container: + image: ghcr.io/project-chip/chip-build:1 + volumes: + - "/tmp/bloat_reports:/tmp/bloat_reports" + steps: + - name: Checkout + uses: actions/checkout@v3 + - name: Checkout submodules & Bootstrap + uses: ./.github/actions/checkout-submodules-and-bootstrap + with: + platform: stm32 + + - name: Set up environment for size reports + uses: ./.github/actions/setup-size-reports + if: ${{ !env.ACT }} + with: + gh-context: ${{ toJson(github) }} + + - name: Build stm32 example apps + timeout-minutes: 20 + run: | + ./scripts/run_in_build_env.sh \ + "./scripts/build/build_examples.py \ + --target stm32-STM32WB5MM-DK-light build \ + " + + - name: Uploading Size Reports + uses: ./.github/actions/upload-size-reports + if: ${{ !env.ACT }} + with: + platform-name: stm32 + diff --git a/.gitmodules b/.gitmodules index f9050a0595cd6a..6a98ceb1c26ec4 100644 --- a/.gitmodules +++ b/.gitmodules @@ -319,3 +319,9 @@ url = https://github.com/SiliconLabs/wiseconnect branch = master platforms = efr32 +[submodule "third_party/st/STM32CubeWB"] + path = third_party/st/STM32CubeWB + url = https://github.com/STMicroelectronics/STM32CubeWB.git + branch = v1.17.0 + platform = stm32 + diff --git a/BUILD.gn b/BUILD.gn index 5b3a9e480b6336..8c7c5bd4f32c7c 100644 --- a/BUILD.gn +++ b/BUILD.gn @@ -276,6 +276,9 @@ if (current_toolchain != "${dir_pw_toolchain}/default:default") { # Set this to true to enable genio builds by default. enable_genio_builds = false + + # Set this to true to enable stm32 builds by default. + enable_stm32_builds = false } # Pigweed does not provide a clang in some configurations. diff --git a/build_overrides/stm32_sdk.gni b/build_overrides/stm32_sdk.gni new file mode 100644 index 00000000000000..e9942b843942f1 --- /dev/null +++ b/build_overrides/stm32_sdk.gni @@ -0,0 +1,18 @@ +# Copyright (c) 2023 Project CHIP Authors +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +declare_args() { + # Root directory for stm32 SDK build files. + stm32_sdk_build_root = "//third_party/st" +} diff --git a/config/stm32/toolchain/BUILD.gn b/config/stm32/toolchain/BUILD.gn new file mode 100644 index 00000000000000..8ce717c45ea888 --- /dev/null +++ b/config/stm32/toolchain/BUILD.gn @@ -0,0 +1,25 @@ +# Copyright (c) 2023 Project CHIP Authors +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +import("//build_overrides/build.gni") +import("//build_overrides/chip.gni") + +import("${build_root}/toolchain/arm_gcc/arm_toolchain.gni") + +arm_toolchain("stm32_lighting_app") { + toolchain_args = { + current_os = "freertos" + import("${chip_root}/examples/lighting-app/stm32/args.gni") + } +} diff --git a/docs/guides/README.md b/docs/guides/README.md index 552f3a30772327..da96c5a8eb7b20 100644 --- a/docs/guides/README.md +++ b/docs/guides/README.md @@ -22,6 +22,7 @@ - [Silicon Labs - Documentation](https://github.com/SiliconLabs/matter#readme) - [Silicon Labs - Building](./silabs_efr32_building.md) - [Silicon Labs - Software Update](./silabs_efr32_software_update.md) +- [STMicroelectronics (STM32)](./stm32_getting_started_guide.md) - [TI - Platform Overview](./ti_platform_overview.md) - [Open IoT SDK - Platform Overview](./openiotsdk_platform_overview.md) - [Open IoT SDK - Examples](./openiotsdk_examples.md) diff --git a/docs/guides/stm32_getting_started_guide.md b/docs/guides/stm32_getting_started_guide.md new file mode 100644 index 00000000000000..55f856cbc0e872 --- /dev/null +++ b/docs/guides/stm32_getting_started_guide.md @@ -0,0 +1,103 @@ +# STM32 Getting Started Guide + +The stm32 platform uses +[Matter](https://github.com/project-chip/connectedhomeip) sdk with FreeRTOS. + +--- + +- [stm32 Getting Started Guide](#stm32-getting-started-guide) + - [Supported Chips](#supported-chips) + - [Matter Example Applications](#matter-example-applications) + - [Building the Example Application](#building-the-example-application) + - [Commissioning](#commissioning) + - [BLE-Thread mode](#ble-thread-mode) + +--- + +## Supported Chips + +The stm32 platform is supported on: + +- [STM32WB5MM-DK](https://www.st.com/en/evaluation-tools/stm32wb5mm-dk.html) + +## Matter Example Applications + +Sample Matter applications are provided for the stm32 platform. They can be used +to speed up development. You can find them in the samples with `/stm32` +subfolder. + +## Building the Example Application + +- [Set Up Matter Environment](./BUILDING.md) + +- Set up STLINK tools + + ``` + apt-get install stlink-tools + ``` + +- Building the Application + + If the lighting example is to be built: + + ``` + ./scripts/build/build_examples.py --target stm32-$stm32_BOARD-lighting build + ``` + +- The output image files are stored in the subdirectories under `out`, the + subdirectory name is the same as the argument specified after the option + `--target` when build the examples. + +- After building the application, `ST-LINK` tool is used to flash it to the + board. Before flashing the application, you will need to flash the fuse and + the co processor binary. The co processor binary and fuse are available + [here](https://github.com/stm32-hotspot/stm32wb-matter-device-over-thread/tree/main/Projects/STM32WB_Copro_Wireless_Binaries/STM32WB5x) + Dynamic Concurrent Mode BLE Thread for Matter (Supports Full BLE Stack 5.2 + certified and Minimal Thread Device ready v1.3) + + ``` + sudo st-flash write chip-stm32-lighting-example.bin 0x08000000 + + ``` + +## Commissioning + +There is one commissioning modes supported by stm32 platform: + +### BLE-Thread mode + +1. Build and Flash +2. The example will run automatically after booting the stm32 board. +3. Restore factory settings using B1 button by pressing at least 10 seconds +4. Commissioning with + [Chip-Tool](https://github.com/project-chip/connectedhomeip/tree/master/examples/chip-tool),for + example: + + ``` + ./chip-tool pairing ble-thread + ``` + +### Bluetooth LE advertising + +In this example, to commission the device onto a Matter network, it must be +discoverable over Bluetooth LE. After powering up the device, the device will +advertise automatically for 30 seconds. After this delay, you will need to reset +the device to start the commissioning procedure. + +### Bluetooth LE rendezvous + +In Matter, the commissioning procedure is done over Bluetooth LE between a +Matter device and the Matter controller(, where the controller has the +commissioner role. + +To start the rendezvous, the controller must get the commissioning information +from the Matter device. The data payload is encoded within a QR code, printed to +the UART console. + +### Thread provisioning + +The provisioning operation, which is the Last part of the rendezvous procedure, +involves sending the Thread network credentials from the Matter controller to +the Matter device. As a result, the device joins the Thread network via a +OpenThread border Router (OTBR) and can communicate with other devices in the +network. diff --git a/examples/build_overrides/stm32_sdk.gni b/examples/build_overrides/stm32_sdk.gni new file mode 100644 index 00000000000000..f9b5048472f6cb --- /dev/null +++ b/examples/build_overrides/stm32_sdk.gni @@ -0,0 +1,18 @@ +# Copyright (c) 2020 Project CHIP Authors +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +declare_args() { + # Root directory for stm32 SDK. + stm32_sdk_build_root = "//third_party/connectedhomeip/third_party/st" +} diff --git a/examples/lighting-app/stm32/.gn b/examples/lighting-app/stm32/.gn new file mode 100644 index 00000000000000..3d48789e30ab3d --- /dev/null +++ b/examples/lighting-app/stm32/.gn @@ -0,0 +1,28 @@ +# Copyright (c) 2020 Project CHIP Authors +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +import("//build_overrides/build.gni") + +# The location of the build configuration file. +buildconfig = "${build_root}/config/BUILDCONFIG.gn" + +# CHIP uses angle bracket includes. +check_system_includes = true + +default_args = { + target_cpu = "arm" + target_os = "freertos" + + import("//args.gni") +} diff --git a/examples/lighting-app/stm32/BUILD.gn b/examples/lighting-app/stm32/BUILD.gn new file mode 100644 index 00000000000000..6adecf2d04c1f5 --- /dev/null +++ b/examples/lighting-app/stm32/BUILD.gn @@ -0,0 +1,173 @@ +# # Copyright (c) 2023 Project CHIP Authors +# # +# # Licensed under the Apache License, Version 2.0 (the "License"); +# # you may not use this file except in compliance with the License. +# # You may obtain a copy of the License at +# # +# # http://www.apache.org/licenses/LICENSE-2.0 +# # +# # Unless required by applicable law or agreed to in writing, software +# # distributed under the License is distributed on an "AS IS" BASIS, +# # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# # See the License for the specific language governing permissions and +# # limitations under the License. + +import("//build_overrides/build.gni") +import("//build_overrides/chip.gni") +import("//build_overrides/stm32_sdk.gni") + +import("${build_root}/config/defaults.gni") +import("${chip_root}/src/platform/device.gni") +import("${stm32_sdk_build_root}/stm32_executable.gni") +import("${stm32_sdk_build_root}/stm32_sdk.gni") + +assert(current_os == "freertos") + +stm32_project_dir = "${chip_root}/examples/lighting-app/stm32" +examples_plat_dir = "${chip_root}/examples/platform/stm32" +stm32_board_src = "${chip_root}/examples/platform/stm32/common/STM32WB5MM-DK" + +declare_args() { + # Dump memory usage at link time. + chip_print_memory_usage = false + + # PIN code for PASE session establishment. + setupPinCode = 20202021 + setupDiscriminator = 3840 + + # Monitor & log memory usage at runtime. + enable_heap_monitoring = false + + # Enable Sleepy end device + enable_sleepy_device = false + + # OTA timeout in seconds + OTA_periodic_query_timeout = 86400 +} + +# Sanity check +assert(!(chip_enable_wifi && chip_enable_openthread)) + +# ThunderBoards and Explorer Kit +if (stm32_board == "STM32WB5MM-DK") { + chip_enable_openthread = true +} + +stm32_sdk("sdk") { + if (stm32_board == "STM32WB5MM-DK") { + sources = [ + "${examples_plat_dir}/config_files/STM32WB5/FreeRTOSConfig.h", + "${examples_plat_dir}/config_files/STM32WB5/matter_config.h", + "${stm32_project_dir}/include/STM32WB5/CHIPProjectConfig.h", + ] + } + + include_dirs = [ + "${chip_root}/src/platform/stm32", + "${examples_plat_dir}", + "${chip_root}/src/lib", + ] + + if (stm32_board == "STM32WB5MM-DK") { + include_dirs += [ + "${stm32_project_dir}/include/STM32WB5", + "${examples_plat_dir}/config_files/STM32WB5", + "${chip_root}/src/include", + ] + } + + defines = [ + "BOARD_ID=${stm32_board}", + "CHIP_DEVICE_CONFIG_USE_TEST_SETUP_PIN_CODE=${setupPinCode}", + "CHIP_DEVICE_CONFIG_USE_TEST_SETUP_DISCRIMINATOR=${setupDiscriminator}", + "OTA_PERIODIC_TIMEOUT=${OTA_periodic_query_timeout}", + "STM32STORE_MAX_KEY_SIZE=75", + ] +} + +stm32_executable("lighting_app") { + if (stm32_board == "STM32WB5MM-DK") { + output_name = "chip-stm32-lighting-example.elf" + include_dirs = [ + "${chip_root}/examples/platform/stm32/config_files/STM32WB5/", + "${chip_root}/examples/platform/stm32/common/STM32WB5MM-DK/Inc", + "${chip_root}/src/include/", + ] + defines = [] + + sources = [ + "${stm32_board_src}/STM32_WPAN/App/app_ble.c", + "${stm32_board_src}/STM32_WPAN/App/app_matter.c", + "${stm32_board_src}/STM32_WPAN/App/app_thread.c", + "${stm32_board_src}/STM32_WPAN/App/custom_stm.c", + "${stm32_board_src}/Src/app_entry.cpp", + "${stm32_board_src}/Src/main.cpp", + "src/STM32WB5/AppTask.cpp", + "src/STM32WB5/LightingManager.cpp", + "src/STM32WB5/ZclCallbacks.cpp", + ] + } + + # Add the startup file to the target + sources += [ "${examples_plat_dir}/startup_files/startup_${stm32_mcu}.s" ] + + deps = [ + ":sdk", + "${chip_root}/examples/lighting-app/lighting-common", + "${chip_root}/examples/providers:device_info_provider", + "${chip_root}/src/lib", + "${chip_root}/src/setup_payload", + ] + + defines += [ + "DEBUG", + "USE_HAL_DRIVER", + ] + + # OpenThread Settings + if (chip_enable_openthread) { + deps += [ + "${chip_root}/third_party/openthread:openthread", + "${chip_root}/third_party/openthread:openthread-platform", + ] + } + + if (chip_enable_ota_requestor) { + defines += [ "STM32_OTA_ENABLED" ] + sources += [ "${examples_plat_dir}/OTAConfig.cpp" ] + } + + ldscript = "${examples_plat_dir}/ldscripts/${stm32_mcu}_FLASH.ld" + + inputs = [ ldscript ] + + ldflags = [ + "-T" + rebase_path(ldscript, root_build_dir), + + # other linker flags ... + "-static", + "-Wl,--cref", + "-Wl,--start-group", + "-lc", + "-lm", + "-lstdc++", + "-lsupc++", + "-Wl,--no-warn-rwx-segments", + "-Wl,--end-group", + ] + if (chip_print_memory_usage) { + ldflags += [ + "-Wl,--print-memory-usage", + "-fstack-usage", + ] + } + + output_dir = root_out_dir +} +group("stm32") { + deps = [ ":lighting_app" ] +} + +group("default") { + deps = [ ":stm32" ] +} diff --git a/examples/lighting-app/stm32/README.md b/examples/lighting-app/stm32/README.md new file mode 100644 index 00000000000000..26a6051d1a963e --- /dev/null +++ b/examples/lighting-app/stm32/README.md @@ -0,0 +1,50 @@ +# Matter STM32 Lighting Example over thread + +This example demonstrates the Matter Lighting application on stm32 platform. + +--- + +- [Matter STM32 Lighting Example over thread](#matter-stm32-lighting-example-over-thread) + - [Building and Commissioning](#building-and-commissioning) + - [Cluster Control](#cluster-control) + - [Indicate current state of lightbulb](#indicate-current-state-of-lightbulb) + +--- + +## Building and Commissioning + +Please refer +[Building and Commissioning](../../../docs/guides/stm32_getting_started_guide.md#building-the-example-application) +guides to get started + +``` +./scripts/build/build_examples.py --target stm32-$stm32_BOARD-lighting build +``` + +## Cluster Control + +After successful commissioning, use `chip-tool` to control the board + +- OnOff Cluster + ``` + ./chip-tool onoff on 1 + ./chip-tool onoff off 1 + ./chip-tool onoff toggle 1 + ``` +- LevelControl Cluster + + ``` + ./chip-tool levelcontrol move-to-level 128 10 0 0 1 + ``` + +- ColorControl Cluster + ``` + ./chip-tool colorcontrol move-to-hue-and-saturation 240 100 0 0 0 1 + ``` + +## Indicate current state of lightbulb + +The LCD screen displays "BLE connected" when the BLE rendezvous started. The LCD +screen displays "Network Join" when the board joins thread network. The LCD +screen displays "LED ON" + the light level when the controller enable the light +ON and the line is erased when the controller disable the light. diff --git a/examples/lighting-app/stm32/args.gni b/examples/lighting-app/stm32/args.gni new file mode 100644 index 00000000000000..3fb288dbacef01 --- /dev/null +++ b/examples/lighting-app/stm32/args.gni @@ -0,0 +1,31 @@ +# Copyright (c) 2023 Project CHIP Authors +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +import("//build_overrides/chip.gni") +import("${chip_root}/config/standalone/args.gni") +import("${chip_root}/src/platform/stm32/args.gni") + +stm32_sdk_target = get_label_info(":sdk", "label_no_toolchain") + +# Size Optimizations +optimize_debug_level = "s" + +chip_enable_ota_requestor = false +chip_project_config_include_dirs = + [ "${chip_root}/examples/lighting-app/stm32/include/STM32WB5" ] +chip_enable_openthread = true +chip_enable_ble = true +chip_config_enable_arg_parser = false +chip_openthread_ftd = false +chip_detail_logging = false diff --git a/examples/lighting-app/stm32/build_overrides b/examples/lighting-app/stm32/build_overrides new file mode 120000 index 00000000000000..e578e73312ebd1 --- /dev/null +++ b/examples/lighting-app/stm32/build_overrides @@ -0,0 +1 @@ +../../build_overrides \ No newline at end of file diff --git a/examples/lighting-app/stm32/include/STM32WB5/AppEvent.h b/examples/lighting-app/stm32/include/STM32WB5/AppEvent.h new file mode 100644 index 00000000000000..ccb5c3fa9a5b20 --- /dev/null +++ b/examples/lighting-app/stm32/include/STM32WB5/AppEvent.h @@ -0,0 +1,64 @@ +/* + * + * Copyright (c) 2018 Nest Labs, Inc. + * All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include +#include +#include +#include +#include + +#ifndef APP_EVENT_H +#define APP_EVENT_H + +struct AppEvent; +typedef void (*EventHandler)(AppEvent *); + +struct AppEvent +{ + enum AppEventTypes + { + kEventType_Button = 0, + kEventType_Timer, + kEventType_Level, + kEventType_Install, + }; + + uint16_t Type; + + union + { + struct + { + uint8_t ButtonIdx; + uint8_t Action; + } ButtonEvent; + struct + { + void * Context; + } TimerEvent; + struct + { + uint8_t Action; + int32_t Color; + } LightingEvent; + }; + + EventHandler Handler; +}; + +#endif // APP_EVENT_H diff --git a/examples/lighting-app/stm32/include/STM32WB5/AppTask.h b/examples/lighting-app/stm32/include/STM32WB5/AppTask.h new file mode 100644 index 00000000000000..5c0344cc8c687a --- /dev/null +++ b/examples/lighting-app/stm32/include/STM32WB5/AppTask.h @@ -0,0 +1,87 @@ +/* + * + * Copyright (c) 2020 Project CHIP Authors + * All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef APP_TASK_H +#define APP_TASK_H + +#include +#include + +#include "AppEvent.h" +#include "LightingManager.h" +#include "app_entry.h" + +#include +#include +#define APP_NAME "Lighting-app" + +class AppTask +{ + +public: + CHIP_ERROR StartAppTask(); + CHIP_ERROR Init(); + static void AppTaskMain(void * pvParameter); + void PostLightActionRequest(int32_t aActor, LightingManager::Action_t aAction); + void PostEvent(const AppEvent * event); + void UpdateClusterState(); + CHIP_ERROR InitMatter(void); + static void ButtonEventHandler(Push_Button_st * Button); + +protected: + TaskHandle_t mAppTask = NULL; + +private: + friend AppTask & GetAppTask(void); + static void ActionInitiated(LightingManager::Action_t aAction); + static void ActionCompleted(LightingManager::Action_t aAction); + void CancelTimer(void); + void DispatchEvent(AppEvent * event); + static void FunctionHandler(AppEvent * aEvent); + static void LightingActionEventHandler(AppEvent * aEvent); + static void TimerEventHandler(TimerHandle_t xTimer); + static void DelayNvmHandler(TimerHandle_t xTimer); + static void MatterEventHandler(const chip::DeviceLayer::ChipDeviceEvent * event, intptr_t arg); + static void UpdateLCD(void); + static void UpdateNvmEventHandler(AppEvent * aEvent); + + enum Function_t + { + kFunction_NoneSelected = 0, + kFunction_SoftwareUpdate = 0, + kFunction_Joiner = 1, + kFunction_SaveNvm = 2, + kFunction_FactoryReset = 3, + + kFunction_Invalid + } Function; + + Function_t mFunction; + bool mFunctionTimerActive; + bool mSyncClusterToButtonAction; + // chip::Ble::BLEEndPoint * mBLEEndPoint; + + static AppTask sAppTask; +}; + +inline AppTask & GetAppTask(void) +{ + return AppTask::sAppTask; +} + +#endif // APP_TASK_H diff --git a/examples/lighting-app/stm32/include/STM32WB5/CHIPProjectConfig.h b/examples/lighting-app/stm32/include/STM32WB5/CHIPProjectConfig.h new file mode 100644 index 00000000000000..a911c565e95a1b --- /dev/null +++ b/examples/lighting-app/stm32/include/STM32WB5/CHIPProjectConfig.h @@ -0,0 +1,154 @@ +/* + * + * Copyright (c) 2020 Project CHIP Authors + * All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * @file + * CHIP project configuration for stm32wb builds. + * + */ +#ifndef CHIPPROJECTCONFIG_H +#define CHIPPROJECTCONFIG_H + +// Use a default pairing code if one hasn't been provisioned in flash. +#ifndef CHIP_DEVICE_CONFIG_USE_TEST_SETUP_PIN_CODE +#define CHIP_DEVICE_CONFIG_USE_TEST_SETUP_PIN_CODE 20202021 +#endif + +#ifndef CHIP_DEVICE_CONFIG_USE_TEST_SETUP_DISCRIMINATOR +#define CHIP_DEVICE_CONFIG_USE_TEST_SETUP_DISCRIMINATOR 0xF00 +#endif + +/** + * CHIP_DEVICE_CONFIG_DEVICE_VENDOR_ID + * + * 0xFFF1: Test vendor + */ +#define CHIP_DEVICE_CONFIG_DEVICE_VENDOR_ID 0xFFF1 + +/** + * CHIP_DEVICE_CONFIG_DEVICE_PRODUCT_ID + * + * 0x8004: example lighting app + */ +#define CHIP_DEVICE_CONFIG_DEVICE_PRODUCT_ID 0x8004 + +/* define Device type based on the application */ +#define CHIP_DEVICE_CONFIG_DEVICE_TYPE 257 // 0x0101 Dimmable Bulb + +/** + * CHIP_DEVICE_CONFIG_TEST_SERIAL_NUMBER + * + * Enables the use of a hard-coded default serial number if none + * is found in Chip NV storage. + */ +#define CHIP_DEVICE_CONFIG_TEST_SERIAL_NUMBER "TEST_SN" + +/** + * CHIP_CONFIG_EVENT_LOGGING_UTC_TIMESTAMPS + * + * Enable recording UTC timestamps. + */ +#define CHIP_CONFIG_EVENT_LOGGING_UTC_TIMESTAMPS 1 + +/** + * CHIP_DEVICE_CONFIG_ENABLE_CHIP_TIME_SERVICE_TIME_SYNC + * + * Enables synchronizing the device's real time clock with a remote Chip Time service + * using the Chip Time Sync protocol. + */ +#define CHIP_DEVICE_CONFIG_ENABLE_CHIP_TIME_SERVICE_TIME_SYNC 0 + +/** + * CHIP_DEVICE_CONFIG_DEVICE_SOFTWARE_VERSION_STRING + * + * A string identifying the software version running on the device. + * CHIP service currently expects the software version to be in the format + * {MAJOR_VERSION}.0d{MINOR_VERSION} + */ +#ifndef CHIP_DEVICE_CONFIG_DEVICE_SOFTWARE_VERSION_STRING +#define CHIP_DEVICE_CONFIG_DEVICE_SOFTWARE_VERSION_STRING "1.1" +#endif + +/** + * CHIP_DEVICE_CONFIG_DEVICE_PRODUCT_REVISION + * + * The product revision number assigned to device or product by the device vendor. This + * number is scoped to the device product id, and typically corresponds to a revision of the + * physical device, a change to its packaging, and/or a change to its marketing presentation. + * This value is generally *not* incremented for device software revisions. + */ +#define CHIP_DEVICE_CONFIG_DEVICE_PRODUCT_REVISION 1 + +/** + * CHIP_DEVICE_CONFIG_DEVICE_FIRMWARE_REVISION_STRING + * + * A string identifying the firmware revision running on the device. + * CHIP service currently expects the firmware version to be in the format + * {MAJOR_VERSION}.0d{MINOR_VERSION} + */ +#ifndef CHIP_DEVICE_CONFIG_DEVICE_FIRMWARE_REVISION_STRING +#define CHIP_DEVICE_CONFIG_DEVICE_FIRMWARE_REVISION_STRING "1.17" +#endif + +/** + * CHIP_DEVICE_CONFIG_DEVICE_HARDWARE_VERSION + * + * The hardware version number assigned to device or product by the device vendor. This + * number is scoped to the device product id, and typically corresponds to a revision of the + * physical device, a change to its packaging, and/or a change to its marketing presentation. + * This value is generally *not* incremented for device software versions. + */ +#define CHIP_DEVICE_CONFIG_DEVICE_HARDWARE_VERSION 1 + +/** + * CHIP_DETAIL_LOGGING + * + * Show detail log in terminal + */ +#define CHIP_DETAIL_LOGGING 0 + +/** + * CHIP_ERROR_LOGGING + * + * Show error log in terminal + */ +#define CHIP_ERROR_LOGGING 1 + +/** + * CHIP_PROGRESS_LOGGING + * + * Show progress log in terminal + */ +#define CHIP_PROGRESS_LOGGING 1 + +/** + * CHIP_AUTOMATION_LOGGING + * + * Show automation log in terminal + */ +#define CHIP_AUTOMATION_LOGGING 1 + +#define CHIP_DEVICE_CONFIG_MAX_DISCOVERED_IP_ADDRESSES 5 +/** + * HIGHWATERMARK + * + * define freertos marker + */ +#define HIGHWATERMARK 0 + +#endif /* CHIPPROJECTCONFIG_H */ diff --git a/examples/lighting-app/stm32/include/STM32WB5/FreeRTOSConfig.h b/examples/lighting-app/stm32/include/STM32WB5/FreeRTOSConfig.h new file mode 100644 index 00000000000000..5423994ea0bc12 --- /dev/null +++ b/examples/lighting-app/stm32/include/STM32WB5/FreeRTOSConfig.h @@ -0,0 +1,191 @@ +/* USER CODE BEGIN Header */ +/* + * FreeRTOS Kernel V10.0.1 + * Copyright (C) 2017 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy of + * this software and associated documentation files (the "Software"), to deal in + * the Software without restriction, including without limitation the rights to + * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of + * the Software, and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS + * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR + * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER + * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + * http://www.FreeRTOS.org + * http://aws.amazon.com/freertos + * + * 1 tab == 4 spaces! + */ +/* USER CODE END Header */ + +#ifndef FREERTOS_CONFIG_H +#define FREERTOS_CONFIG_H + +/*----------------------------------------------------------- + * Application specific definitions. + * + * These definitions should be adjusted for your particular hardware and + * application requirements. + * + * These parameters and more are described within the 'configuration' section of the + * FreeRTOS API documentation available on the FreeRTOS.org web site. + * + * See http://www.freertos.org/a00110.html + *----------------------------------------------------------*/ + +/* USER CODE BEGIN Includes */ +/* Section where include file can be added */ +/* USER CODE END Includes */ + +/* Ensure definitions are only used by the compiler, and not by the assembler. */ +#if defined(__ICCARM__) || defined(__CC_ARM) || defined(__GNUC__) +#include +extern uint32_t SystemCoreClock; +#endif +#ifndef CMSIS_device_header +#define CMSIS_device_header "stm32wbxx.h" +#endif /* CMSIS_device_header */ + +#define configENABLE_FPU 0 +#define configENABLE_MPU 0 + +#define configUSE_PREEMPTION 1 +#define configSUPPORT_STATIC_ALLOCATION 1 +#define configSUPPORT_DYNAMIC_ALLOCATION 1 +#define configUSE_IDLE_HOOK 0 +#define configUSE_TICK_HOOK 0 +#define configCPU_CLOCK_HZ (SystemCoreClock) +#define configTICK_RATE_HZ ((TickType_t) 1000) +#define configMAX_PRIORITIES (56) +#define configMINIMAL_STACK_SIZE ((uint16_t) 128) +#define configTOTAL_HEAP_SIZE ((size_t) 1024 * 25) +#define configMAX_TASK_NAME_LEN (32) +#define configUSE_TRACE_FACILITY 1 +#define configUSE_16_BIT_TICKS 0 +#define configUSE_MUTEXES 1 +#define configQUEUE_REGISTRY_SIZE 8 +#define configUSE_RECURSIVE_MUTEXES 1 +#define configUSE_COUNTING_SEMAPHORES 1 +#define configUSE_PORT_OPTIMISED_TASK_SELECTION 0 +#define configUSE_TICKLESS_IDLE 0 +/* USER CODE BEGIN MESSAGE_BUFFER_LENGTH_TYPE */ +/* Defaults to size_t for backward compatibility, but can be changed + if lengths will always be less than the number of bytes in a size_t. */ +#define configMESSAGE_BUFFER_LENGTH_TYPE size_t +/* USER CODE END MESSAGE_BUFFER_LENGTH_TYPE */ + +/* Co-routine definitions. */ +#define configUSE_CO_ROUTINES 0 +#define configMAX_CO_ROUTINE_PRIORITIES (2) + +/* Software timer definitions. */ +#define configUSE_TIMERS 1 +#define configTIMER_TASK_PRIORITY (2) +#define configTIMER_QUEUE_LENGTH 10 +#define configTIMER_TASK_STACK_DEPTH 256 + +/* CMSIS-RTOS V2 flags */ +#define configUSE_OS2_THREAD_SUSPEND_RESUME 1 +#define configUSE_OS2_THREAD_ENUMERATE 1 +#define configUSE_OS2_EVENTFLAGS_FROM_ISR 1 +#define configUSE_OS2_THREAD_FLAGS 1 +#define configUSE_OS2_TIMER 1 +#define configUSE_OS2_MUTEX 1 + +/* Set the following definitions to 1 to include the API function, or zero +to exclude the API function. */ +#define INCLUDE_vTaskPrioritySet 1 +#define INCLUDE_uxTaskPriorityGet 1 +#define INCLUDE_vTaskDelete 1 +#define INCLUDE_vTaskCleanUpResources 0 +#define INCLUDE_vTaskSuspend 1 +#define INCLUDE_vTaskDelayUntil 1 +#define INCLUDE_vTaskDelay 1 +#define INCLUDE_xTaskGetSchedulerState 1 +#define INCLUDE_xTimerPendFunctionCall 1 +#define INCLUDE_xQueueGetMutexHolder 1 +#define INCLUDE_uxTaskGetStackHighWaterMark 1 +#define INCLUDE_xTaskGetCurrentTaskHandle 1 +#define INCLUDE_eTaskGetState 1 + +/* + * The CMSIS-RTOS V2 FreeRTOS wrapper is dependent on the heap implementation used + * by the application thus the correct define need to be enabled below + */ +#define USE_FreeRTOS_HEAP_4 + +/* Cortex-M specific definitions. */ +#ifdef __NVIC_PRIO_BITS +/* __BVIC_PRIO_BITS will be specified when CMSIS is being used. */ +#define configPRIO_BITS __NVIC_PRIO_BITS +#else +#define configPRIO_BITS 4 +#endif + +/* The lowest interrupt priority that can be used in a call to a "set priority" +function. */ +#define configLIBRARY_LOWEST_INTERRUPT_PRIORITY 15 + +/* The highest interrupt priority that can be used by any interrupt service +routine that makes calls to interrupt safe FreeRTOS API functions. DO NOT CALL +INTERRUPT SAFE FREERTOS API FUNCTIONS FROM ANY INTERRUPT THAT HAS A HIGHER +PRIORITY THAN THIS! (higher priorities are lower numeric values. */ +#define configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY 5 + +/* Interrupt priorities used by the kernel port layer itself. These are generic +to all Cortex-M ports, and do not rely on any particular library functions. */ +#define configKERNEL_INTERRUPT_PRIORITY (configLIBRARY_LOWEST_INTERRUPT_PRIORITY << (8 - configPRIO_BITS)) +/* !!!! configMAX_SYSCALL_INTERRUPT_PRIORITY must not be set to zero !!!! +See http://www.FreeRTOS.org/RTOS-Cortex-M3-M4.html. */ +#define configMAX_SYSCALL_INTERRUPT_PRIORITY (configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY << (8 - configPRIO_BITS)) + +/* Normal assert() semantics without relying on the provision of an assert.h +header file. */ +/* USER CODE BEGIN 1 */ +#define configASSERT(x) \ + if ((x) == 0) \ + { \ + taskDISABLE_INTERRUPTS(); \ + for (;;) \ + ; \ + } +/* USER CODE END 1 */ + +/* Definitions that map the FreeRTOS port interrupt handlers to their CMSIS +standard names. */ +#define vPortSVCHandler SVC_Handler +#define xPortPendSVHandler PendSV_Handler + +/* IMPORTANT: After 10.3.1 update, Systick_Handler comes from NVIC (if SYS timebase = systick), otherwise from cmsis_os2.c */ + +#define USE_CUSTOM_SYSTICK_HANDLER_IMPLEMENTATION 0 + +/* USER CODE BEGIN Defines */ +/* Section where parameter definitions can be added (for instance, to override default ones in FreeRTOS.h) */ +//#define configOVERRIDE_DEFAULT_TICK_CONFIGURATION 1 /* required only for Keil but does not hurt otherwise */ +#define configGENERATE_RUN_TIME_STATS 1 + +#if (configGENERATE_RUN_TIME_STATS == 1) + +extern void RTOS_AppConfigureTimerForRuntimeStats(); + +extern uint32_t RTOS_AppGetRuntimeCounterValueFromISR(); + +#define portCONFIGURE_TIMER_FOR_RUN_TIME_STATS() RTOS_AppConfigureTimerForRuntimeStats() + +#define portGET_RUN_TIME_COUNTER_VALUE() RTOS_AppGetRuntimeCounterValueFromISR() + +#endif + +/* USER CODE END Defines */ + +#endif /* FREERTOS_CONFIG_H */ diff --git a/examples/lighting-app/stm32/include/STM32WB5/LightingManager.h b/examples/lighting-app/stm32/include/STM32WB5/LightingManager.h new file mode 100644 index 00000000000000..ae3222ce045433 --- /dev/null +++ b/examples/lighting-app/stm32/include/STM32WB5/LightingManager.h @@ -0,0 +1,74 @@ +/* + * + * Copyright (c) 2021 Project CHIP Authors + * All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#pragma once + +#include +#include + +#include + +#include + +class LightingManager +{ +public: + enum Action_t + { + ON_ACTION = 0, + OFF_ACTION, + LEVEL_ACTION, + COLOR_ACTION_XY, + COLOR_ACTION_HSV, + INVALID_ACTION + } Action; + + enum State_t + { + kState_On = 0, + kState_Off, + } State; + + CHIP_ERROR Init(); + bool IsTurnedOn(); + uint8_t GetLevel(); + bool InitiateAction(Action_t aAction, int32_t aActor, uint16_t size, uint8_t * value); + + using LightingCallback_fn = std::function; + + void SetCallbacks(LightingCallback_fn aActionInitiated_CB, LightingCallback_fn aActionCompleted_CB); + +private: + friend LightingManager & LightingMgr(void); + State_t mState; + uint8_t mLevel; + + LightingCallback_fn mActionInitiated_CB; + LightingCallback_fn mActionCompleted_CB; + + void Set(bool aOn); + void SetLevel(uint8_t aLevel); + void UpdateLight(); + + static LightingManager sLight; +}; + +inline LightingManager & LightingMgr(void) +{ + return LightingManager::sLight; +} diff --git a/examples/lighting-app/stm32/src/STM32WB5/AppTask.cpp b/examples/lighting-app/stm32/src/STM32WB5/AppTask.cpp new file mode 100644 index 00000000000000..4b9d5427adc8f4 --- /dev/null +++ b/examples/lighting-app/stm32/src/STM32WB5/AppTask.cpp @@ -0,0 +1,591 @@ +/* + * + * Copyright (c) 2020 Project CHIP Authors + * All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/*STM32 includes*/ +#include "AppTask.h" +#include "AppEvent.h" +#include "app_common.h" +#include "app_thread.h" +#include "cmsis_os.h" +#include "dbg_trace.h" +#include "flash_wb.h" +#include "ssd1315.h" +#include "stm32_lcd.h" +#include "stm32_lpm.h" +#include "stm32wb5mm_dk_lcd.h" + +#include "stm_logging.h" +#if HIGHWATERMARK +#include "memory_buffer_alloc.h" +#endif + +/*Matter includes*/ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#if CHIP_ENABLE_OPENTHREAD +#include +#include +#endif + +using namespace ::chip; +using namespace ::chip::app; +using namespace chip::TLV; +using namespace chip::Credentials; +using namespace chip::DeviceLayer; +using namespace ::chip::Platform; +using namespace ::chip::Credentials; +using namespace ::chip::app::Clusters; +using chip::DeviceLayer::PersistedStorage::KeyValueStoreMgr; + +AppTask AppTask::sAppTask; +chip::DeviceLayer::FactoryDataProvider mFactoryDataProvider; + +#define APP_FUNCTION_BUTTON BUTTON_USER1 +#define STM32ThreadDataSet "STM32DataSet" +#define APP_EVENT_QUEUE_SIZE 10 +#define NVM_TIMEOUT 1000 // timer to handle PB to save data in nvm or do a factory reset +#define DELAY_NVM 5000 // save data in nvm after commissioning with a delay of 5 sec +#define STM32_LIGHT_ENDPOINT_ID 1 + +static QueueHandle_t sAppEventQueue; +TimerHandle_t sPushButtonTimeoutTimer; +TimerHandle_t DelayNvmTimer; +const osThreadAttr_t AppTask_attr = { .name = APPTASK_NAME, + .attr_bits = APP_ATTR_BITS, + .cb_mem = APP_CB_MEM, + .cb_size = APP_CB_SIZE, + .stack_mem = APP_STACK_MEM, + .stack_size = APP_STACK_SIZE, + .priority = APP_PRIORITY }; + +static bool sIsThreadProvisioned = false; +static bool sIsThreadEnabled = false; +static bool sHaveBLEConnections = false; +static bool sFabricNeedSaved = false; +static bool sFailCommissioning = false; +static bool sHaveFabric = false; +static uint8_t NvmTimerCpt = 0; +static uint8_t NvmButtonStateCpt = 0; + +CHIP_ERROR AppTask::StartAppTask() +{ + sAppEventQueue = xQueueCreate(APP_EVENT_QUEUE_SIZE, sizeof(AppEvent)); + if (sAppEventQueue == NULL) + { + APP_DBG("Failed to allocate app event queue"); + return CHIP_ERROR_NO_MEMORY; + } + + // Start App task. + osThreadNew(AppTaskMain, NULL, &AppTask_attr); + + return CHIP_NO_ERROR; +} + +void LockOpenThreadTask(void) +{ + chip::DeviceLayer::ThreadStackMgr().LockThreadStack(); +} + +void UnlockOpenThreadTask(void) +{ + chip::DeviceLayer::ThreadStackMgr().UnlockThreadStack(); +} + +CHIP_ERROR AppTask::Init() +{ + + CHIP_ERROR err = CHIP_NO_ERROR; + ChipLogProgress(NotSpecified, "Current Software Version: %s", CHIP_DEVICE_CONFIG_DEVICE_SOFTWARE_VERSION_STRING); + + // Setup button handler + APP_ENTRY_PBSetReceiveCallback(ButtonEventHandler); + + // Create FreeRTOS sw timer for Push button timeouts. + sPushButtonTimeoutTimer = xTimerCreate("PushButtonTimer", // Just a text name, not used by the RTOS kernel + pdMS_TO_TICKS(NVM_TIMEOUT), // == default timer period (mS) + true, // no timer reload (==one-shot) + (void *) this, // init timer id + TimerEventHandler // timer callback handler + ); + + DelayNvmTimer = xTimerCreate("Delay_NVM", // Just a text name, not used by the RTOS kernel + DELAY_NVM, // == default timer period (mS) + pdFALSE, // timer reload + 0, // init timer + DelayNvmHandler // timer callback handler + ); + + ThreadStackMgr().InitThreadStack(); + + ConnectivityMgr().SetThreadDeviceType(ConnectivityManager::kThreadDeviceType_Router); + + PlatformMgr().AddEventHandler(MatterEventHandler, 0); + + err = LightingMgr().Init(); + if (err != CHIP_NO_ERROR) + { + APP_DBG("LightingMgr().Init() failed"); + return err; + } + LightingMgr().SetCallbacks(ActionInitiated, ActionCompleted); + +#if CHIP_DEVICE_CONFIG_ENABLE_EXTENDED_DISCOVERY + chip::app::DnssdServer::Instance().SetExtendedDiscoveryTimeoutSecs(extDiscTimeoutSecs); +#endif + + // Init ZCL Data Model + static chip::CommonCaseDeviceServerInitParams initParams; + (void) initParams.InitializeStaticResourcesBeforeServerInit(); + ReturnErrorOnFailure(mFactoryDataProvider.Init()); + SetDeviceInstanceInfoProvider(&mFactoryDataProvider); + SetCommissionableDataProvider(&mFactoryDataProvider); + SetDeviceAttestationCredentialsProvider(&mFactoryDataProvider); + + chip::Inet::EndPointStateOpenThread::OpenThreadEndpointInitParam nativeParams; + nativeParams.lockCb = LockOpenThreadTask; + nativeParams.unlockCb = UnlockOpenThreadTask; + nativeParams.openThreadInstancePtr = chip::DeviceLayer::ThreadStackMgrImpl().OTInstance(); + initParams.endpointNativeParams = static_cast(&nativeParams); + chip::Server::GetInstance().Init(initParams); + + ConfigurationMgr().LogDeviceConfig(); + + // Open commissioning after boot if no fabric was available + if (chip::Server::GetInstance().GetFabricTable().FabricCount() == 0) + { + PrintOnboardingCodes(chip::RendezvousInformationFlags(chip::RendezvousInformationFlag::kBLE)); + // Enable BLE advertisements + chip::Server::GetInstance().GetCommissioningWindowManager().OpenBasicCommissioningWindow(); + APP_DBG("BLE advertising started. Waiting for Pairing."); + } + else + { // try to attach to the thread network + uint8_t datasetBytes[Thread::kSizeOperationalDataset]; + size_t datasetLength = 0; + char Message[20]; + snprintf(Message, sizeof(Message), "Fabric Found: %d", chip::Server::GetInstance().GetFabricTable().FabricCount()); + APP_BLE_Init_Dyn_3(); + UTIL_LCD_DisplayStringAt(0, LINE(1), (uint8_t *) Message, LEFT_MODE); + BSP_LCD_Refresh(0); + CHIP_ERROR error = KeyValueStoreMgr().Get(STM32ThreadDataSet, datasetBytes, sizeof(datasetBytes), &datasetLength); + if (error == CHIP_NO_ERROR) + { + ThreadStackMgr().SetThreadProvision(ByteSpan(datasetBytes, datasetLength)); + ThreadStackMgr().SetThreadEnabled(true); + } + else + { + APP_DBG("Thread network Data set was not found"); + } + } + + err = PlatformMgr().StartEventLoopTask(); + if (err != CHIP_NO_ERROR) + { + APP_DBG("PlatformMgr().StartEventLoopTask() failed"); + } + + return err; +} + +CHIP_ERROR AppTask::InitMatter() +{ + CHIP_ERROR err = CHIP_NO_ERROR; + + err = chip::Platform::MemoryInit(); + if (err != CHIP_NO_ERROR) + { + APP_DBG("Platform::MemoryInit() failed"); + } + else + { + APP_DBG("Init CHIP stack"); + err = PlatformMgr().InitChipStack(); + if (err != CHIP_NO_ERROR) + { + APP_DBG("PlatformMgr().InitChipStack() failed"); + } + } + return err; +} + +void AppTask::AppTaskMain(void * pvParameter) +{ + AppEvent event; + + CHIP_ERROR err = sAppTask.Init(); +#if HIGHWATERMARK + UBaseType_t uxHighWaterMark; + HeapStats_t HeapStatsInfo; + size_t max_used; + size_t max_blocks; +#endif // endif HIGHWATERMARK + if (err != CHIP_NO_ERROR) + { + APP_DBG("App task init failled "); + } + + APP_DBG("App Task started"); + while (true) + { + + BaseType_t eventReceived = xQueueReceive(sAppEventQueue, &event, pdMS_TO_TICKS(10)); + while (eventReceived == pdTRUE) + { + sAppTask.DispatchEvent(&event); + eventReceived = xQueueReceive(sAppEventQueue, &event, 0); + } +#if HIGHWATERMARK + uxHighWaterMark = uxTaskGetStackHighWaterMark(NULL); + vPortGetHeapStats(&HeapStatsInfo); + mbedtls_memory_buffer_alloc_max_get(&max_used, &max_blocks); + +#endif // endif HIGHWATERMARK + } +} + +void AppTask::LightingActionEventHandler(AppEvent * aEvent) +{ + LightingManager::Action_t action; + + if (aEvent->Type == AppEvent::kEventType_Button) + { + // Toggle light + if (LightingMgr().IsTurnedOn()) + { + action = LightingManager::OFF_ACTION; + } + else + { + action = LightingManager::ON_ACTION; + } + + sAppTask.mSyncClusterToButtonAction = true; + LightingMgr().InitiateAction(action, 0, 0, 0); + } + if (aEvent->Type == AppEvent::kEventType_Level && aEvent->ButtonEvent.Action != 0) + { + // Toggle Dimming of light between 2 fixed levels + uint8_t val = 0x0; + val = LightingMgr().GetLevel() == 0x7f ? 0x1 : 0x7f; + action = LightingManager::LEVEL_ACTION; + + sAppTask.mSyncClusterToButtonAction = true; + LightingMgr().InitiateAction(action, 0, 1, &val); + } +} + +void AppTask::ButtonEventHandler(Push_Button_st * Button) +{ + + AppEvent button_event = {}; + button_event.Type = AppEvent::kEventType_Button; + button_event.ButtonEvent.ButtonIdx = Button->Pushed_Button; + button_event.ButtonEvent.Action = Button->State; + + if (Button->Pushed_Button == APP_FUNCTION_BUTTON) + { + // Hand off to Functionality handler - depends on duration of press + button_event.Handler = FunctionHandler; + } + else + { + return; + } + + sAppTask.PostEvent(&button_event); +} + +void AppTask::TimerEventHandler(TimerHandle_t xTimer) +{ + + NvmTimerCpt++; + if (BSP_PB_GetState(BUTTON_USER1) == 0) + { + NvmButtonStateCpt++; + } + if (NvmTimerCpt >= 10) + { + xTimerStop(sPushButtonTimeoutTimer, 0); + if (NvmButtonStateCpt >= 9) + { + AppEvent event; + event.Type = AppEvent::kEventType_Timer; + event.Handler = UpdateNvmEventHandler; + sAppTask.mFunction = kFunction_FactoryReset; + sAppTask.PostEvent(&event); + } + } + else if ((NvmTimerCpt > NvmButtonStateCpt) && (NvmTimerCpt <= 2)) + { + AppEvent event; + event.Type = AppEvent::kEventType_Timer; + event.Handler = UpdateNvmEventHandler; + xTimerStop(sPushButtonTimeoutTimer, 0); + sAppTask.mFunction = kFunction_SaveNvm; + sAppTask.PostEvent(&event); + } +} + +void AppTask::FunctionHandler(AppEvent * aEvent) +{ + if (xTimerIsTimerActive(sPushButtonTimeoutTimer) == 0) + { + xTimerStart(sPushButtonTimeoutTimer, 0); + NvmTimerCpt = 0; + NvmButtonStateCpt = 0; + } +} + +void AppTask::ActionInitiated(LightingManager::Action_t aAction) +{ + // Placeholder for light action + UTIL_LCD_ClearStringLine(2); + if (aAction == LightingManager::ON_ACTION) + { + APP_DBG("Light goes on"); + char Message[11]; + snprintf(Message, sizeof(Message), "LED ON %d", LightingMgr().GetLevel()); + UTIL_LCD_DisplayStringAt(0, LINE(2), (uint8_t *) Message, CENTER_MODE); + } + else if (aAction == LightingManager::OFF_ACTION) + { + APP_DBG("Light goes off "); + UTIL_LCD_ClearStringLine(2); + } + else if (aAction == LightingManager::LEVEL_ACTION) + { + if (LightingMgr().IsTurnedOn()) + { + char Message[11]; + snprintf(Message, sizeof(Message), "LED ON %d", LightingMgr().GetLevel()); + UTIL_LCD_DisplayStringAt(0, LINE(2), (uint8_t *) Message, CENTER_MODE); + APP_DBG("Update level control %d", LightingMgr().GetLevel()); + } + } + BSP_LCD_Refresh(0); +} + +void AppTask::ActionCompleted(LightingManager::Action_t aAction) +{ + // Placeholder for light action completed + if (aAction == LightingManager::ON_ACTION) + { + APP_DBG("Light action on completed"); + } + else if (aAction == LightingManager::OFF_ACTION) + { + APP_DBG("Light action off completed"); + } + if (sAppTask.mSyncClusterToButtonAction) + { + sAppTask.UpdateClusterState(); + sAppTask.mSyncClusterToButtonAction = false; + } +} + +void AppTask::PostEvent(const AppEvent * aEvent) +{ + if (sAppEventQueue != NULL) + { + if (!xQueueSend(sAppEventQueue, aEvent, 1)) + { + ChipLogError(NotSpecified, "Failed to post event to app task event queue"); + } + } + else + { + ChipLogError(NotSpecified, "Event Queue is NULL should never happen"); + } +} + +void AppTask::DispatchEvent(AppEvent * aEvent) +{ + if (aEvent->Handler) + { + aEvent->Handler(aEvent); + } + else + { + ChipLogError(NotSpecified, "Event received with no handler. Dropping event."); + } +} + +/** + * Update cluster status after application level changes + */ +void AppTask::UpdateClusterState(void) +{ + ChipLogProgress(NotSpecified, "UpdateClusterState"); + // Write the new on/off value + EmberAfStatus status = Clusters::OnOff::Attributes::OnOff::Set(STM32_LIGHT_ENDPOINT_ID, LightingMgr().IsTurnedOn()); + if (status != EMBER_ZCL_STATUS_SUCCESS) + { + ChipLogError(NotSpecified, "ERR: updating on/off %x", status); + } + + // Write new level value + status = Clusters::LevelControl::Attributes::CurrentLevel::Set(STM32_LIGHT_ENDPOINT_ID, LightingMgr().GetLevel()); + if (status != EMBER_ZCL_STATUS_SUCCESS) + { + ChipLogError(NotSpecified, "ERR: updating level %x", status); + } +} + +void AppTask::DelayNvmHandler(TimerHandle_t xTimer) +{ + AppEvent event; + event.Type = AppEvent::kEventType_Timer; + event.Handler = UpdateNvmEventHandler; + sAppTask.mFunction = kFunction_SaveNvm; + sAppTask.PostEvent(&event); +} + +void AppTask::UpdateLCD(void) +{ + if (sIsThreadProvisioned && sIsThreadEnabled) + { + UTIL_LCD_DisplayStringAt(0, LINE(4), (uint8_t *) "Network Joined", LEFT_MODE); + } + else if ((sIsThreadProvisioned == false) || (sIsThreadEnabled == false)) + { + UTIL_LCD_ClearStringLine(4); + } + if (sHaveBLEConnections) + { + UTIL_LCD_ClearStringLine(1); + BSP_LCD_Refresh(0); + UTIL_LCD_DisplayStringAt(0, LINE(1), (uint8_t *) "BLE Connected", LEFT_MODE); + } + if (sHaveFabric) + { + UTIL_LCD_ClearStringLine(1); + BSP_LCD_Refresh(0); + UTIL_LCD_DisplayStringAt(0, LINE(1), (uint8_t *) "Fabric Created", LEFT_MODE); + } + if (sFailCommissioning == true) + { + UTIL_LCD_DisplayStringAt(0, LINE(1), (uint8_t *) "", LEFT_MODE); + BSP_LCD_Refresh(0); + UTIL_LCD_DisplayStringAt(0, LINE(1), (uint8_t *) "Fabric Failed", LEFT_MODE); + } + BSP_LCD_Refresh(0); +} + +void AppTask::UpdateNvmEventHandler(AppEvent * aEvent) +{ + uint8_t err = 0; + + if (sAppTask.mFunction == kFunction_SaveNvm) + { + if (sIsThreadProvisioned && sIsThreadEnabled) + { + chip::Thread::OperationalDataset dataset{}; + DeviceLayer::ThreadStackMgrImpl().GetThreadProvision(dataset); + ByteSpan datasetbyte = dataset.AsByteSpan(); + KeyValueStoreMgr().Put(STM32ThreadDataSet, datasetbyte.data(), datasetbyte.size()); + } + err = NM_Dump(); + if (err == 0) + { + APP_DBG("SAVE NVM"); + } + else + { + APP_DBG("Failed to SAVE NVM"); + // restart timer to save nvm later + xTimerStart(DelayNvmTimer, 0); + } + } + else if (sAppTask.mFunction == kFunction_FactoryReset) + { + APP_DBG("FACTORY RESET"); + NM_ResetFactory(); + } +} + +void AppTask::MatterEventHandler(const ChipDeviceEvent * event, intptr_t) +{ + switch (event->Type) + { + case DeviceEventType::kServiceProvisioningChange: { + sIsThreadProvisioned = event->ServiceProvisioningChange.IsServiceProvisioned; + UpdateLCD(); + break; + } + + case DeviceEventType::kThreadConnectivityChange: { + sIsThreadEnabled = (event->ThreadConnectivityChange.Result == kConnectivity_Established); + UpdateLCD(); + break; + } + + case DeviceEventType::kCHIPoBLEConnectionEstablished: { + sHaveBLEConnections = true; + APP_DBG("kCHIPoBLEConnectionEstablished"); + UpdateLCD(); + break; + } + + case DeviceEventType::kCHIPoBLEConnectionClosed: { + sHaveBLEConnections = false; + APP_DBG("kCHIPoBLEConnectionClosed"); + UpdateLCD(); + if (sFabricNeedSaved) + { + APP_DBG("Start timer to save nvm after commissioning finish"); + // timer is used to avoid to much traffic on m0 side after the end of a commissioning + xTimerStart(DelayNvmTimer, 0); + sFabricNeedSaved = false; + } + break; + } + + case DeviceEventType::kCommissioningComplete: { + sFabricNeedSaved = true; + sHaveFabric = true; + // check if ble is on, since before save in nvm we need to stop m0, Better to write in nvm when m0 is less busy + if (sHaveBLEConnections == false) + { + APP_DBG("Start timer to save nvm after commissioning finish"); + xTimerStart(DelayNvmTimer, 0); + sFabricNeedSaved = false; // put to false to avoid save in nvm 2 times + } + UpdateLCD(); + break; + } + case DeviceEventType::kFailSafeTimerExpired: { + UpdateLCD(); + sFailCommissioning = true; + break; + } + default: + break; + } +} diff --git a/examples/lighting-app/stm32/src/STM32WB5/LightingManager.cpp b/examples/lighting-app/stm32/src/STM32WB5/LightingManager.cpp new file mode 100644 index 00000000000000..4b8018d7252cfb --- /dev/null +++ b/examples/lighting-app/stm32/src/STM32WB5/LightingManager.cpp @@ -0,0 +1,140 @@ +/* + * + * Copyright (c) 2021 Project CHIP Authors + * Copyright (c) 2019 Google LLC. + * All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "LightingManager.h" +#include + +// default initialization value for the light level after start +constexpr uint8_t kDefaultLevel = 64; + +LightingManager LightingManager::sLight; + +CHIP_ERROR LightingManager::Init() +{ + mState = kState_Off; + mLevel = kDefaultLevel; + + return CHIP_NO_ERROR; +} + +bool LightingManager::IsTurnedOn() +{ + return mState == kState_On; +} + +uint8_t LightingManager::GetLevel() +{ + return mLevel; +} + +void LightingManager::SetCallbacks(LightingCallback_fn aActionInitiated_CB, LightingCallback_fn aActionCompleted_CB) +{ + mActionInitiated_CB = aActionInitiated_CB; + mActionCompleted_CB = aActionCompleted_CB; +} + +bool LightingManager::InitiateAction(Action_t aAction, int32_t aActor, uint16_t size, uint8_t * value) +{ + bool action_initiated = false; + State_t new_state = kState_Off; + + switch (aAction) + { + case ON_ACTION: + ChipLogProgress(NotSpecified, "LightMgr:ON: %s->ON", mState == kState_On ? "ON" : "OFF"); + break; + case OFF_ACTION: + ChipLogProgress(NotSpecified, "LightMgr:OFF: %s->OFF", mState == kState_On ? "ON" : "OFF"); + break; + case LEVEL_ACTION: + ChipLogProgress(NotSpecified, "LightMgr:LEVEL: lev:%u->%u", mLevel, *value); + break; + default: + ChipLogProgress(NotSpecified, "LightMgr:Unknown"); + break; + } + + // Initiate On/Off Action only when the previous one is complete. + if (mState == kState_Off && aAction == ON_ACTION) + { + action_initiated = true; + new_state = kState_On; + } + else if (mState == kState_On && aAction == OFF_ACTION) + { + action_initiated = true; + new_state = kState_Off; + } + else if (aAction == LEVEL_ACTION && *value != mLevel) + { + action_initiated = true; + if (*value == 0) + { + new_state = kState_Off; + } + else + { + new_state = kState_On; + } + } + if (aAction == LEVEL_ACTION) + { + SetLevel(*value); + } + else + { + Set(new_state == kState_On); + } + if (action_initiated) + { + if (mActionInitiated_CB) + { + mActionInitiated_CB(aAction); + } + + if (mActionCompleted_CB) + { + mActionCompleted_CB(aAction); + } + } + + return action_initiated; +} + +void LightingManager::SetLevel(uint8_t aLevel) +{ + mLevel = aLevel; + + UpdateLight(); +} + +void LightingManager::Set(bool aOn) +{ + if (aOn) + { + mState = kState_On; + } + else + { + mState = kState_Off; + } + UpdateLight(); +} + +void LightingManager::UpdateLight() {} diff --git a/examples/lighting-app/stm32/src/STM32WB5/ZclCallbacks.cpp b/examples/lighting-app/stm32/src/STM32WB5/ZclCallbacks.cpp new file mode 100644 index 00000000000000..762ad402274cf6 --- /dev/null +++ b/examples/lighting-app/stm32/src/STM32WB5/ZclCallbacks.cpp @@ -0,0 +1,47 @@ +/* + * + * Copyright (c) 2021 Project CHIP Authors + * Copyright (c) 2019 Google LLC. + * All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "AppTask.h" +#include "LightingManager.h" + +#include +#include +#include +#include + +using namespace chip; +using namespace chip::app::Clusters; + +void MatterPostAttributeChangeCallback(const chip::app::ConcreteAttributePath & attributePath, uint8_t type, uint16_t size, + uint8_t * value) +{ + ClusterId clusterId = attributePath.mClusterId; + AttributeId attributeId = attributePath.mAttributeId; + + if (clusterId == OnOff::Id && attributeId == OnOff::Attributes::OnOff::Id) + { + LightingMgr().InitiateAction(*value ? LightingManager::ON_ACTION : LightingManager::OFF_ACTION, 0, size, value); + } + else if (clusterId == LevelControl::Id && attributeId == LevelControl::Attributes::CurrentLevel::Id) + { + LightingMgr().InitiateAction(LightingManager::LEVEL_ACTION, 0, size, value); + } +} + +void emberAfOnOffClusterInitCallback(EndpointId endpoint) {} diff --git a/examples/lighting-app/stm32/third_party/connectedhomeip b/examples/lighting-app/stm32/third_party/connectedhomeip new file mode 120000 index 00000000000000..c866b86874994d --- /dev/null +++ b/examples/lighting-app/stm32/third_party/connectedhomeip @@ -0,0 +1 @@ +../../../.. \ No newline at end of file diff --git a/examples/platform/stm32/BUILD.gn b/examples/platform/stm32/BUILD.gn new file mode 100644 index 00000000000000..cd843ec196c2df --- /dev/null +++ b/examples/platform/stm32/BUILD.gn @@ -0,0 +1,82 @@ +# Copyright (c) 2023 Project CHIP Authors +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +import("//build_overrides/chip.gni") +import("//build_overrides/stm32_sdk.gni") +import("${chip_root}/src/lib/lib.gni") +import("${chip_root}/src/platform/device.gni") +import("${srm32_sdk_build_root}/stm32_board.gni") +import("${stm32_sdk_build_root}/stm32_sdk.gni") + +config("chip_examples_project_config") { + include_dirs = [ "project_include" ] + + # Link options that provide a replacement for dynamic memory operations in standard + # library with the FreeRTOS malloc in platform code. + ldflags = [ + # memory allocation -- these must be re-entrant and do locking + #"-Wl,--wrap=malloc", + #"-Wl,--wrap=free", + #"-Wl,--wrap=realloc", + #"-Wl,--wrap=calloc", + #"-Wl,--wrap=MemoryAlloc", + # Wrap these in case internal newlib call them (e.g. strdup will) + # directly call _malloc_r) + #"-Wl,--wrap=_malloc_r", + #"-Wl,--wrap=_realloc_r", + #"-Wl,--wrap=_free_r", + #"-Wl,--wrap=_calloc_r", + ] +} + +source_set("openthread_core_config_stm32_chip_examples") { + if (chip_enable_openthread) { + sources = [ + # "project_include/OpenThreadConfig.h" + ] + + public_deps = [ "${stm32_sdk_build_root}:stm32_sdk" ] + + if (use_st_thread_lib) { + public_deps += [ "${stm32_sdk_build_root}:openthread_core_config_stm32" ] + } else { + public_deps += [ "${chip_root}/third_party/openthread/platforms/stm32:openthread_core_config_stm32" ] + } + + public_configs = [ ":chip_examples_project_config" ] + } +} + +config("attestation-credentials-config") { + include_dirs = [ "${chip_root}" ] + + defines = [ + # Set to 1 to enable stm32 attestation credentials + "STM32_ATTESTATION_CREDENTIALS", + ] +} + +source_set("stm32-attestation-credentials") { + sources = [ + # "stm32DeviceAttestationCreds.cpp", + # "stm32DeviceAttestationCreds.h", + ] + + public_deps = [ + "${chip_root}/src/credentials", + "${chip_root}/src/platform:platform_base", + ] + + public_configs = [ ":attestation-credentials-config" ] +} diff --git a/examples/platform/stm32/args.gni b/examples/platform/stm32/args.gni new file mode 100644 index 00000000000000..53604116cd174f --- /dev/null +++ b/examples/platform/stm32/args.gni @@ -0,0 +1,21 @@ +# Copyright (c) 2023 Project CHIP Authors +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +import("//build_overrides/chip.gni") + +chip_ble_project_config_include = "" +chip_device_project_config_include = "" +chip_project_config_include = "" +chip_inet_project_config_include = "" +chip_system_project_config_include = "" diff --git a/examples/platform/stm32/common/STM32WB5MM-DK/Inc/app_common.h b/examples/platform/stm32/common/STM32WB5MM-DK/Inc/app_common.h new file mode 100644 index 00000000000000..63b2af6ae8a23b --- /dev/null +++ b/examples/platform/stm32/common/STM32WB5MM-DK/Inc/app_common.h @@ -0,0 +1,138 @@ +/** + ****************************************************************************** + * @file app_common.h + * @author MCD Application Team + * @brief Common + ****************************************************************************** + * @attention + * + * Copyright (c) 2019-2021 STMicroelectronics. + * All rights reserved. + * + * This software is licensed under terms that can be found in the LICENSE file + * in the root directory of this software component. + * If no LICENSE file comes with this software, it is provided AS-IS. + * + ****************************************************************************** + */ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef __APP_COMMON_H +#define __APP_COMMON_H + +#ifdef __cplusplus +extern "C" { +#endif + +#include "app_conf.h" +#include "stm_logging.h" +#include +#include +#include +#include +#include + +/* -------------------------------- * + * Basic definitions * + * -------------------------------- */ + +#undef NULL +#define NULL 0 + +#undef FALSE +#define FALSE 0 + +#undef TRUE +#define TRUE (!0) + +/*SECTION*/ + +#define section_text __attribute__((section(".extendtext"), noinline)) + +/* -------------------------------- * + * Critical Section definition * + * -------------------------------- */ +#define BACKUP_PRIMASK() uint32_t primask_bit = __get_PRIMASK() +#define DISABLE_IRQ() __disable_irq() +#define RESTORE_PRIMASK() __set_PRIMASK(primask_bit) + +/* -------------------------------- * + * Macro delimiters * + * -------------------------------- */ + +#define M_BEGIN \ + do \ + { + +#define M_END \ + } \ + while (0) + +/* -------------------------------- * + * Some useful macro definitions * + * -------------------------------- */ + +#ifndef MAX +#define MAX(x, y) (((x) > (y)) ? (x) : (y)) +#endif + +#ifndef MIN +#define MIN(x, y) (((x) < (y)) ? (x) : (y)) +#endif + +#define MODINC(a, m) \ + M_BEGIN(a)++; \ + if ((a) >= (m)) \ + (a) = 0; \ + M_END + +#define MODDEC(a, m) \ + M_BEGIN if ((a) == 0)(a) = (m); \ + (a)--; \ + M_END + +#define MODADD(a, b, m) \ + M_BEGIN(a) += (b); \ + if ((a) >= (m)) \ + (a) -= (m); \ + M_END + +#define MODSUB(a, b, m) MODADD(a, (m) - (b), m) + +#define PAUSE(t) \ + M_BEGIN \ + volatile int _i; \ + for (_i = t; _i > 0; _i--) \ + ; \ + M_END + +#define DIVF(x, y) ((x) / (y)) + +#define DIVC(x, y) (((x) + (y) -1) / (y)) + +#define DIVR(x, y) (((x) + ((y) / 2)) / (y)) + +#define SHRR(x, n) ((((x) >> ((n) -1)) + 1) >> 1) + +#define BITN(w, n) (((w)[(n) / 32] >> ((n) % 32)) & 1) + +#define BITNSET(w, n, b) \ + M_BEGIN(w)[(n) / 32] |= ((U32)(b)) << ((n) % 32); \ + M_END + +/* -------------------------------- * + * Compiler * + * -------------------------------- */ +#define PLACE_IN_SECTION(__x__) __attribute__((section(__x__))) + +#ifdef WIN32 +#define ALIGN(n) +#else +#define ALIGN(n) __attribute__((aligned(n))) +#endif + +#ifdef __cplusplus +} +#endif + +#endif /*__APP_COMMON_H */ diff --git a/examples/platform/stm32/common/STM32WB5MM-DK/Inc/app_conf.h b/examples/platform/stm32/common/STM32WB5MM-DK/Inc/app_conf.h new file mode 100644 index 00000000000000..fe6e3b2aa16a29 --- /dev/null +++ b/examples/platform/stm32/common/STM32WB5MM-DK/Inc/app_conf.h @@ -0,0 +1,667 @@ +/** + ****************************************************************************** + * File Name : app_conf.h + * Description : Application configuration file for STM32WPAN middleWare. + ****************************************************************************** + * @attention + * + * Copyright (c) 2019-2021 STMicroelectronics. + * All rights reserved. + * + * This software is licensed under terms that can be found in the LICENSE file + * in the root directory of this software component. + * If no LICENSE file comes with this software, it is provided AS-IS. + * + ****************************************************************************** + */ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef APP_CONF_H +#define APP_CONF_H + +#ifdef __cplusplus +extern "C" { +#endif + +#include "hw.h" +#include "hw_conf.h" +#include "hw_if.h" + +/****************************************************************************** + * Application Config + ******************************************************************************/ + +/**< generic parameters */ + +/** + * + * Define Tx Power + */ +#define CFG_TX_POWER (0x18) /**< 0dbm */ + +/** + * Define Advertising parameters + */ +#define CFG_ADV_BD_ADDRESS (0x7257acd87a6c) +#define CFG_FAST_CONN_ADV_INTERVAL_MIN (0x80) /**< 80ms */ +#define CFG_FAST_CONN_ADV_INTERVAL_MAX (0xa0) /**< 100ms */ +#define CFG_LP_CONN_ADV_INTERVAL_MIN (0x640) /**< 1s */ +#define CFG_LP_CONN_ADV_INTERVAL_MAX (0xfa0) /**< 2.5s */ + +/** + * Define IO Authentication + */ +#define CFG_BONDING_MODE (1) +#define CFG_FIXED_PIN (111111) +#define CFG_USED_FIXED_PIN (0) +#define CFG_ENCRYPTION_KEY_SIZE_MAX (16) +#define CFG_ENCRYPTION_KEY_SIZE_MIN (8) + +/** + * Define IO capabilities + */ +#define CFG_IO_CAPABILITY_DISPLAY_ONLY (0x00) +#define CFG_IO_CAPABILITY_DISPLAY_YES_NO (0x01) +#define CFG_IO_CAPABILITY_KEYBOARD_ONLY (0x02) +#define CFG_IO_CAPABILITY_NO_INPUT_NO_OUTPUT (0x03) +#define CFG_IO_CAPABILITY_KEYBOARD_DISPLAY (0x04) + +#define CFG_IO_CAPABILITY CFG_IO_CAPABILITY_DISPLAY_YES_NO + +/** + * Define MITM modes + */ +#define CFG_MITM_PROTECTION_NOT_REQUIRED (0x00) +#define CFG_MITM_PROTECTION_REQUIRED (0x01) + +#define CFG_MITM_PROTECTION CFG_MITM_PROTECTION_REQUIRED + +/** + * Define PHY + */ +#define ALL_PHYS_PREFERENCE 0x00 +#define RX_2M_PREFERRED 0x02 +#define TX_2M_PREFERRED 0x02 +#define TX_1M 0x01 +#define TX_2M 0x02 +#define RX_1M 0x01 +#define RX_2M 0x02 + +/* freertos defines */ +#define CFG_SHCI_USER_EVT_PROCESS_NAME "SHCI_USER_EVT_PROCESS" +#define CFG_SHCI_USER_EVT_PROCESS_ATTR_BITS (0) +#define CFG_SHCI_USER_EVT_PROCESS_CB_MEM (0) +#define CFG_SHCI_USER_EVT_PROCESS_CB_SIZE (0) +#define CFG_SHCI_USER_EVT_PROCESS_STACK_MEM (0) +#define CFG_SHCI_USER_EVT_PROCESS_PRIORITY osPriorityNormal +#define CFG_SHCI_USER_EVT_PROCESS_STACK_SIZE (128 * 20) + +#define CFG_PUSH_BUTTON_EVT_PROCESS_NAME "PUSH_BUTTON_EVT_PROCESS" +#define CFG_PUSH_BUTTON_EVT_PROCESS_ATTR_BITS (0) +#define CFG_PUSH_BUTTON_EVT_PROCESS_CB_MEM (0) +#define CFG_PUSH_BUTTON_EVT_PROCESS_CB_SIZE (0) +#define CFG_PUSH_BUTTON_EVT_PROCESS_STACK_MEM (0) +#define CFG_PUSH_BUTTON_EVT_PROCESS_PRIORITY osPriorityNormal +#define CFG_PUSH_BUTTON_EVT_PROCESS_STACK_SIZE (128 * 4) + +#define CFG_SEND_COAP_NAME "SEND_COAP_EVT_PROCESS" + +#define CFG_SWITCH_PROTOCOL_EVT_PROCESS_NAME "SWITCH_PROTCOL_EVT_PROCESS" +#define CFG_SWITCH_PROTOCOL_EVT_PROCESS_ATTR_BITS (0) +#define CFG_SWITCH_PROTOCOL_EVT_PROCESS_CB_MEM (0) +#define CFG_SWITCH_PROTOCOL_EVT_PROCESS_CB_SIZE (0) +#define CFG_SWITCH_PROTOCOL_EVT_PROCESS_STACK_MEM (0) +#define CFG_SWITCH_PROTOCOL_EVT_PROCESS_PRIORITY osPriorityNormal +#define CFG_SWITCH_PROTOCOL_EVT_PROCESS_STACK_SIZE (128 * 8) + +#define CFG_THREAD_MSG_M0_TO_M4_PROCESS_NAME "THREAD_MSG_M0_TO_M4_PROCESS" +#define CFG_THREAD_MSG_M0_TO_M4_PROCESS_ATTR_BITS (0) +#define CFG_THREAD_MSG_M0_TO_M4_PROCESS_CB_MEM (0) +#define CFG_THREAD_MSG_M0_TO_M4_PROCESS_CB_SIZE (0) +#define CFG_THREAD_MSG_M0_TO_M4_PROCESS_STACK_MEM (0) +#define CFG_THREAD_MSG_M0_TO_M4_PROCESS_PRIORITY osPriorityNormal +#define CFG_THREAD_MSG_M0_TO_M4_PROCESS_STACK_SIZE (128 * 8) + +#define CFG_THREAD_CLI_PROCESS_NAME "THREAD_CLI_PROCESS" +#define CFG_THREAD_CLI_PROCESS_ATTR_BITS (0) +#define CFG_THREAD_CLI_PROCESS_CB_MEM (0) +#define CFG_THREAD_CLI_PROCESS_CB_SIZE (0) +#define CFG_THREAD_CLI_PROCESS_STACK_MEM (0) +#define CFG_THREAD_CLI_PROCESS_PRIORITY osPriorityNormal +#define CFG_THREAD_CLI_PROCESS_STACK_SIZE (128 * 8) + +#define CFG_THREAD_SEND_COAP_MSG_PROCESS_NAME "THREAD_SEND_COAP_MSG_PROCESS" +#define CFG_THREAD_SEND_COAP_MSG_PROCESS_ATTR_BITS (0) +#define CFG_THREAD_SEND_COAP_MSG_PROCESS_CB_MEM (0) +#define CFG_THREAD_SEND_COAP_MSG_PROCESS_CB_SIZE (0) +#define CFG_THREAD_SEND_COAP_MSG_PROCESS_STACK_MEM (0) +#define CFG_THREAD_SEND_COAP_MSG_PROCESS_PRIORITY osPriorityNormal +#define CFG_THREAD_SEND_COAP_MSG_PROCESS_STACk_SIZE (128 * 8) + +#define CFG_THREAD_SET_SED_MODE_PROCESS_NAME "THREAD_SET_SED_MODE_PROCESS" +#define CFG_THREAD_SET_SED_MODE_PROCESS_ATTR_BITS (0) +#define CFG_THREAD_SET_SED_MODE_PROCESS_CB_MEM (0) +#define CFG_THREAD_SET_SED_MODE_PROCESS_CB_SIZE (0) +#define CFG_THREAD_SET_SED_MODE_PROCESS_STACK_MEM (0) +#define CFG_THREAD_SET_SED_MODE_PROCESS_PRIORITY osPriorityNormal +#define CFG_THREAD_SET_SED_MODE_PROCESS_STACk_SIZE (128 * 8) + +#define CFG_HCI_USER_EVT_PROCESS_NAME "HCI_USER_EVT_PROCESS" +#define CFG_HCI_USER_EVT_PROCESS_ATTR_BITS (0) +#define CFG_HCI_USER_EVT_PROCESS_CB_MEM (0) +#define CFG_HCI_USER_EVT_PROCESS_CB_SIZE (0) +#define CFG_HCI_USER_EVT_PROCESS_STACK_MEM (0) +#define CFG_HCI_USER_EVT_PROCESS_PRIORITY osPriorityNormal +#define CFG_HCI_USER_EVT_PROCESS_STACK_SIZE (128 * 40) + +#define CFG_ADV_UPDATE_PROCESS_NAME "ADV_UPDATE_PROCESS" +#define CFG_ADV_UPDATE_PROCESS_ATTR_BITS (0) +#define CFG_ADV_UPDATE_PROCESS_CB_MEM (0) +#define CFG_ADV_UPDATE_PROCESS_CB_SIZE (0) +#define CFG_ADV_UPDATE_PROCESS_STACK_MEM (0) +#define CFG_ADV_UPDATE_PROCESS_PRIORITY osPriorityNormal +#define CFG_ADV_UPDATE_PROCESS_STACK_SIZE (128 * 20) + +#define CFG_P2P_SERVER_PROCESS_NAME "P2P_SERVER_PROCESS" +#define CFG_P2P_SERVER_PROCESS_ATTR_BITS (0) +#define CFG_P2P_SERVER_PROCESS_CB_MEM (0) +#define CFG_P2P_SERVER_PROCESS_CB_SIZE (0) +#define CFG_P2P_SERVER_PROCESS_STACK_MEM (0) +#define CFG_P2P_SERVER_PROCESS_PRIORITY osPriorityNormal +#define CFG_P2P_SERVER_PROCESS_STACK_SIZE (128 * 20) + +#define LED_PROCESS_NAME "LED_CUBE_PROCESS" +#define LED_PROCESS_ATTR_BITS (0) +#define LED_PROCESS_CB_MEM (0) +#define LED_PROCESS_CB_SIZE (0) +#define LED_PROCESS_STACK_MEM (0) +#define LED_PROCESS_PRIORITY osPriorityNormal +#define LED_PROCESS_STACK_SIZE (128 * 10) + +#define APPTASK_NAME "APPTASK" +#define APP_ATTR_BITS (0) +#define APP_CB_MEM (0) +#define APP_CB_SIZE (0) +#define APP_STACK_MEM (0) +#define APP_PRIORITY osPriorityNormal +#define APP_STACK_SIZE (1024 * 6) + +/** + * Identity root key used to derive LTK and CSRK + */ +#define CFG_BLE_IRK \ + { \ + 0x12, 0x34, 0x56, 0x78, 0x9a, 0xbc, 0xde, 0xf0, 0x12, 0x34, 0x56, 0x78, 0x9a, 0xbc, 0xde, 0xf0 \ + } + +/** + * Encryption root key used to derive LTK and CSRK + */ +#define CFG_BLE_ERK \ + { \ + 0xfe, 0xdc, 0xba, 0x09, 0x87, 0x65, 0x43, 0x21, 0xfe, 0xdc, 0xba, 0x09, 0x87, 0x65, 0x43, 0x21 \ + } + +/* USER CODE BEGIN Generic_Parameters */ +/** + * SMPS supply + * SMPS not used when Set to 0 + * SMPS used when Set to 1 + */ +#define CFG_USE_SMPS 1 +/* USER CODE END Generic_Parameters */ + +/**< specific parameters */ +/*****************************************************/ +#define PUSH_BUTTON_SW1_EXTI_IRQHandler EXTI4_IRQHandler +#define PUSH_BUTTON_SW2_EXTI_IRQHandler EXTI0_IRQHandler +#define PUSH_BUTTON_SW3_EXTI_IRQHandler EXTI1_IRQHandler + +#define P2P_SERVER1 1 /*1 = Device is Peripherique*/ + +#define CFG_DEV_ID_P2P_SERVER1 (0x83) + +#define RADIO_ACTIVITY_EVENT 1 /* 1 for OOB Demo */ + +/** + * AD Element - Group B Feature + */ +/* LSB - First Byte */ +#define CFG_FEATURE_THREAD_SWITCH (0x40) + +/* LSB - Second Byte */ +#define CFG_FEATURE_OTA_REBOOT (0x20) + +#define CONN_L(x) ((int) ((x) / 0.625f)) +#define CONN_P(x) ((int) ((x) / 1.25f)) + +/* L2CAP Connection Update request parameters used for test only with smart Phone */ +#define L2CAP_REQUEST_NEW_CONN_PARAM 1 + +#define L2CAP_INTERVAL_MIN CONN_P(1000) /* 1s */ +#define L2CAP_INTERVAL_MAX CONN_P(1000) /* 1s */ +#define L2CAP_SLAVE_LATENCY 0x0000 +#define L2CAP_TIMEOUT_MULTIPLIER 0x1F4 + +/****************************************************************************** + * BLE Stack + ******************************************************************************/ +/** + * Maximum number of simultaneous connections that the device will support. + * Valid values are from 1 to 8 + */ +#define CFG_BLE_NUM_LINK 8 + +/** + * Maximum number of Services that can be stored in the GATT database. + * Note that the GAP and GATT services are automatically added so this parameter should be 2 plus the number of user services + */ +#define CFG_BLE_NUM_GATT_SERVICES 8 + +/** + * Maximum number of Attributes + * (i.e. the number of characteristic + the number of characteristic values + the number of descriptors, excluding the services) + * that can be stored in the GATT database. + * Note that certain characteristics and relative descriptors are added automatically during device initialization + * so this parameters should be 9 plus the number of user Attributes + */ +#define CFG_BLE_NUM_GATT_ATTRIBUTES 68 + +/** + * Maximum supported ATT_MTU size + */ +#define CFG_BLE_MAX_ATT_MTU (251) + +/** + * Size of the storage area for Attribute values + * This value depends on the number of attributes used by application. In particular the sum of the following quantities (in + * octets) should be made for each attribute: + * - attribute value length + * - 5, if UUID is 16 bit; 19, if UUID is 128 bit + * - 2, if server configuration descriptor is used + * - 2*DTM_NUM_LINK, if client configuration descriptor is used + * - 2, if extended properties is used + * The total amount of memory needed is the sum of the above quantities for each attribute. + */ +#define CFG_BLE_ATT_VALUE_ARRAY_SIZE (1344) + +/** + * Prepare Write List size in terms of number of packet with ATT_MTU=23 bytes + */ +#define CFG_BLE_PREPARE_WRITE_LIST_SIZE BLE_PREP_WRITE_X_ATT(CFG_BLE_MAX_ATT_MTU) + +/** + * Number of allocated memory blocks + */ +#define CFG_BLE_MBLOCK_COUNT (BLE_MBLOCKS_CALC(CFG_BLE_PREPARE_WRITE_LIST_SIZE, CFG_BLE_MAX_ATT_MTU, CFG_BLE_NUM_LINK)) + +/** + * Enable or disable the Extended Packet length feature. Valid values are 0 or 1. + */ +#define CFG_BLE_DATA_LENGTH_EXTENSION 1 + +/** + * Sleep clock accuracy in Slave mode (ppm value) + */ +#define CFG_BLE_SLAVE_SCA 500 + +/** + * Sleep clock accuracy in Master mode + * 0 : 251 ppm to 500 ppm + * 1 : 151 ppm to 250 ppm + * 2 : 101 ppm to 150 ppm + * 3 : 76 ppm to 100 ppm + * 4 : 51 ppm to 75 ppm + * 5 : 31 ppm to 50 ppm + * 6 : 21 ppm to 30 ppm + * 7 : 0 ppm to 20 ppm + */ +#define CFG_BLE_MASTER_SCA 0 + +/** + * Source for the 32 kHz slow speed clock + * 1 : internal RO + * 0 : external crystal ( no calibration ) + */ +#define CFG_BLE_LSE_SOURCE 0 + +/** + * Start up time of the high speed (16 or 32 MHz) crystal oscillator in units of 625/256 us (~2.44 us) + */ +#define CFG_BLE_HSE_STARTUP_TIME 0x148 + +/** + * Maximum duration of the connection event when the device is in Slave mode in units of 625/256 us (~2.44 us) + */ +#define CFG_BLE_MAX_CONN_EVENT_LENGTH (0xFFFFFFFF) + +/** + * Viterbi Mode + * 1 : enabled + * 0 : disabled + */ +#define CFG_BLE_VITERBI_MODE 1 + +/** + * BLE stack Options flags to be configured with: + * - SHCI_C2_BLE_INIT_OPTIONS_LL_ONLY + * - SHCI_C2_BLE_INIT_OPTIONS_LL_HOST + * - SHCI_C2_BLE_INIT_OPTIONS_NO_SVC_CHANGE_DESC + * - SHCI_C2_BLE_INIT_OPTIONS_WITH_SVC_CHANGE_DESC + * - SHCI_C2_BLE_INIT_OPTIONS_DEVICE_NAME_RO + * - SHCI_C2_BLE_INIT_OPTIONS_DEVICE_NAME_RW + * - SHCI_C2_BLE_INIT_OPTIONS_POWER_CLASS_1 + * - SHCI_C2_BLE_INIT_OPTIONS_POWER_CLASS_2_3 + * which are used to set following configuration bits: + * (bit 0): 1: LL only + * 0: LL + host + * (bit 1): 1: no service change desc. + * 0: with service change desc. + * (bit 2): 1: device name Read-Only + * 0: device name R/W + * (bit 7): 1: LE Power Class 1 + * 0: LE Power Class 2-3 + * other bits: reserved (shall be set to 0) + */ +#define CFG_BLE_OPTIONS SHCI_C2_BLE_INIT_OPTIONS_LL_HOST + +#define CFG_BLE_MAX_COC_INITIATOR_NBR (32) + +#define CFG_BLE_MIN_TX_POWER (0) + +#define CFG_BLE_MAX_TX_POWER (0) +/****************************************************************************** + * Transport Layer + ******************************************************************************/ +/** + * Queue length of BLE Event + * This parameter defines the number of asynchronous events that can be stored in the HCI layer before + * being reported to the application. When a command is sent to the BLE core coprocessor, the HCI layer + * is waiting for the event with the Num_HCI_Command_Packets set to 1. The receive queue shall be large + * enough to store all asynchronous events received in between. + * When CFG_TLBLE_MOST_EVENT_PAYLOAD_SIZE is set to 27, this allow to store three 255 bytes long asynchronous events + * between the HCI command and its event. + * This parameter depends on the value given to CFG_TLBLE_MOST_EVENT_PAYLOAD_SIZE. When the queue size is to small, + * the system may hang if the queue is full with asynchronous events and the HCI layer is still waiting + * for a CC/CS event, In that case, the notification TL_BLE_HCI_ToNot() is called to indicate + * to the application a HCI command did not receive its command event within 30s (Default HCI Timeout). + */ +#define CFG_TLBLE_EVT_QUEUE_LENGTH 5 + +/** + * This parameter should be set to fit most events received by the HCI layer. It defines the buffer size of each element + * allocated in the queue of received events and can be used to optimize the amount of RAM allocated by the Memory Manager. + * It should not exceed 255 which is the maximum HCI packet payload size (a greater value is a lost of memory as it will + * never be used) + * It shall be at least 4 to receive the command status event in one frame. + * The default value is set to 27 to allow receiving an event of MTU size in a single buffer. This value maybe reduced + * further depending on the application. + * + */ +#define CFG_TLBLE_MOST_EVENT_PAYLOAD_SIZE 255 /**< Set to 255 with the memory manager and the mailbox */ + +#define TL_BLE_EVENT_FRAME_SIZE (TL_EVT_HDR_SIZE + CFG_TLBLE_MOST_EVENT_PAYLOAD_SIZE) + +/****************************************************************************** + * UART interfaces + ******************************************************************************/ +#define CFG_DEBUG_TRACE_UART hw_uart1 +#define CFG_CLI_UART hw_lpuart1 + +/****************************************************************************** + * USB interface + ******************************************************************************/ + +/** + * Enable/Disable USB interface + */ +#define CFG_USB_INTERFACE_ENABLE 0 + +/****************************************************************************** + * Low Power + * + * When CFG_FULL_LOW_POWER is set to 1, the system is configured in full + * low power mode. It means that all what can have an impact on the consumptions + * are powered down.(For instance LED, Access to Debugger, Etc.) + * + * When CFG_FULL_LOW_POWER is set to 0, the low power mode is not activated + * + ******************************************************************************/ + +#define CFG_FULL_LOW_POWER 0 + +#if (CFG_FULL_LOW_POWER == 1) +#undef CFG_LPM_SUPPORTED +#define CFG_LPM_SUPPORTED 1 +#endif /* CFG_FULL_LOW_POWER */ + +/* FOR DEBUGGING ONLY ! */ +//#define CFG_LPM_SUPPORTED 1 + +/****************************************************************************** + * Timer Server + ******************************************************************************/ +/** + * CFG_RTC_WUCKSEL_DIVIDER: This sets the RTCCLK divider to the wakeup timer. + * The higher is the value, the better is the power consumption and the accuracy of the timerserver + * The lower is the value, the finest is the granularity + * + * CFG_RTC_ASYNCH_PRESCALER: This sets the asynchronous prescaler of the RTC. It should as high as possible ( to output + * clock as low as possible) but the output clock should be equal or higher frequency compare to the clock feeding + * the wakeup timer. A lower clock speed would impact the accuracy of the timer server. + * + * CFG_RTC_SYNCH_PRESCALER: This sets the synchronous prescaler of the RTC. + * When the 1Hz calendar clock is required, it shall be sets according to other settings + * When the 1Hz calendar clock is not needed, CFG_RTC_SYNCH_PRESCALER should be set to 0x7FFF (MAX VALUE) + * + * CFG_RTCCLK_DIVIDER_CONF: + * Shall be set to either 0,2,4,8,16 + * When set to either 2,4,8,16, the 1Hhz calendar is supported + * When set to 0, the user sets its own configuration + * + * The following settings are computed with LSI as input to the RTC + */ +#define CFG_RTCCLK_DIVIDER_CONF 0 + +#if (CFG_RTCCLK_DIVIDER_CONF == 0) +/** + * Custom configuration + * It does not support 1Hz calendar + * It divides the RTC CLK by 16 + */ +#define CFG_RTCCLK_DIV (16) +#define CFG_RTC_WUCKSEL_DIVIDER (0) +#define CFG_RTC_ASYNCH_PRESCALER (CFG_RTCCLK_DIV - 1) +#define CFG_RTC_SYNCH_PRESCALER (0x7FFF) + +#else + +#if (CFG_RTCCLK_DIVIDER_CONF == 2) +/** + * It divides the RTC CLK by 2 + */ +#define CFG_RTC_WUCKSEL_DIVIDER (3) +#endif + +#if (CFG_RTCCLK_DIVIDER_CONF == 4) +/** + * It divides the RTC CLK by 4 + */ +#define CFG_RTC_WUCKSEL_DIVIDER (2) +#endif + +#if (CFG_RTCCLK_DIVIDER_CONF == 8) +/** + * It divides the RTC CLK by 8 + */ +#define CFG_RTC_WUCKSEL_DIVIDER (1) +#endif + +#if (CFG_RTCCLK_DIVIDER_CONF == 16) +/** + * It divides the RTC CLK by 16 + */ +#define CFG_RTC_WUCKSEL_DIVIDER (0) +#endif + +#define CFG_RTCCLK_DIV CFG_RTCCLK_DIVIDER_CONF +#define CFG_RTC_ASYNCH_PRESCALER (CFG_RTCCLK_DIV - 1) +#define CFG_RTC_SYNCH_PRESCALER (DIVR(LSE_VALUE, (CFG_RTC_ASYNCH_PRESCALER + 1)) - 1) + +#endif + +/** tick timer value in us */ +#define CFG_TS_TICK_VAL DIVR((CFG_RTCCLK_DIV * 1000000), LSE_VALUE) + +typedef enum +{ + CFG_TIM_PROC_ID_ISR, +} CFG_TimProcID_t; + +/****************************************************************************** + * Debug + ******************************************************************************/ +/** + * When set, this resets some hw resources to set the device in the same state than the power up + * The FW resets only register that may prevent the FW to run properly + * + * This shall be set to 0 in a final product + * + */ +#define CFG_HW_RESET_BY_FW 1 + +/** + * keep debugger enabled while in any low power mode when set to 1 + * should be set to 0 in production + */ +#define CFG_DEBUGGER_SUPPORTED 1 + +#if (CFG_FULL_LOW_POWER == 1) +#undef CFG_DEBUGGER_SUPPORTED +#define CFG_DEBUGGER_SUPPORTED 0 +#endif /* CFG_FULL_LOW_POWER */ + +/***************************************************************************** + * Traces + * Enable or Disable traces in application + * When CFG_DEBUG_TRACE is set, traces are activated + * + * Note : Refer to utilities_conf.h file in order to details + * the level of traces : CFG_DEBUG_TRACE_FULL or CFG_DEBUG_TRACE_LIGHT + *****************************************************************************/ + +/** + * When set to 1, the traces are enabled in the BLE services + */ +#define CFG_DEBUG_BLE_TRACE 1 + +/** + * Enable or Disable traces in application + */ +#define CFG_DEBUG_APP_TRACE 1 + +#if (CFG_DEBUG_APP_TRACE != 0) +#define APP_DBG_MSG PRINT_MESG_DBG +#else +#define APP_DBG_MSG PRINT_NO_MESG +#endif +#if ((CFG_DEBUG_BLE_TRACE != 0) || (CFG_DEBUG_APP_TRACE != 0)) +#define CFG_DEBUG_TRACE 1 +#endif + +#if (CFG_FULL_LOW_POWER == 1) +#undef CFG_DEBUG_TRACE +#define CFG_DEBUG_TRACE 0 +#endif /* CFG_FULL_LOW_POWER */ + +/** + * When CFG_DEBUG_TRACE_FULL is set to 1, the trace are output with the API name, the file name and the line number + * When CFG_DEBUG_TRACE_LIGHT is set to 1, only the debug message is output + * + * When both are set to 0, no trace are output + * When both are set to 1, CFG_DEBUG_TRACE_FULL is selected + */ +#define CFG_DEBUG_TRACE_LIGHT 1 +#define CFG_DEBUG_TRACE_FULL 0 + +#if ((CFG_DEBUG_TRACE != 0) && (CFG_DEBUG_TRACE_LIGHT == 0) && (CFG_DEBUG_TRACE_FULL == 0)) +#undef CFG_DEBUG_TRACE_FULL +#undef CFG_DEBUG_TRACE_LIGHT +#define CFG_DEBUG_TRACE_FULL 0 +#define CFG_DEBUG_TRACE_LIGHT 1 +#endif + +#if (CFG_DEBUG_TRACE == 0) +#undef CFG_DEBUG_TRACE_FULL +#undef CFG_DEBUG_TRACE_LIGHT +#define CFG_DEBUG_TRACE_FULL 0 +#define CFG_DEBUG_TRACE_LIGHT 0 +#endif + +/** + * When not set, the traces is looping on sending the trace over UART + */ +#define DBG_TRACE_USE_CIRCULAR_QUEUE 1 + +/** + * max buffer Size to queue data traces and max data trace allowed. + * Only Used if DBG_TRACE_USE_CIRCULAR_QUEUE is defined + */ +#define DBG_TRACE_MSG_QUEUE_SIZE (1024 * 5) +#define MAX_DBG_TRACE_MSG_SIZE 1024 + +/****************************************************************************** + * Configure Log level for Application + ******************************************************************************/ +#define APPLI_CONFIG_LOG_LEVEL LOG_LEVEL_INFO +#define APPLI_PRINT_FILE_FUNC_LINE 0 + +/* USER CODE BEGIN Defines */ +/****************************************************************************** + * User interaction + * When CFG_LED_SUPPORTED is set, LEDS are activated if requested + * When CFG_BUTTON_SUPPORTED is set, the push button are activated if requested + ******************************************************************************/ +#if (CFG_FULL_LOW_POWER == 1) +#define CFG_LED_SUPPORTED 0 +#define CFG_BUTTON_SUPPORTED 0 +#else +#define CFG_LED_SUPPORTED 1 +#define CFG_BUTTON_SUPPORTED 1 +#endif /* CFG_FULL_LOW_POWER */ +/* USER CODE END Defines */ + +/****************************************************************************** + * LOW POWER + ******************************************************************************/ +/** + * Supported requester to the MCU Low Power Manager - can be increased up to 32 + * It lists a bit mapping of all user of the Low Power Manager + */ +typedef enum +{ + CFG_LPM_APP, + CFG_LPM_APP_BLE, + CFG_LPM_APP_THREAD + /* USER CODE BEGIN CFG_LPM_Id_t */ + + /* USER CODE END CFG_LPM_Id_t */ +} CFG_LPM_Id_t; + +/****************************************************************************** + * OTP manager + ******************************************************************************/ +#define CFG_OTP_BASE_ADDRESS OTP_AREA_BASE + +#define CFG_OTP_END_ADDRESS OTP_AREA_END_ADDR + +typedef enum +{ + BUTTON_1 = 0x1, +} button_type_t; + +#ifdef __cplusplus +} /* extern "C" */ +#endif + +#endif /* APP_CONF_H */ diff --git a/examples/platform/stm32/common/STM32WB5MM-DK/Inc/app_entry.h b/examples/platform/stm32/common/STM32WB5MM-DK/Inc/app_entry.h new file mode 100644 index 00000000000000..9d0378c18792c1 --- /dev/null +++ b/examples/platform/stm32/common/STM32WB5MM-DK/Inc/app_entry.h @@ -0,0 +1,57 @@ + +/** + ****************************************************************************** + * @file app_entry.h + * @author MCD Application Team + * @brief Interface to the application + ****************************************************************************** + * @attention + * + * Copyright (c) 2019-2021 STMicroelectronics. + * All rights reserved. + * + * This software is licensed under terms that can be found in the LICENSE file + * in the root directory of this software component. + * If no LICENSE file comes with this software, it is provided AS-IS. + * + ****************************************************************************** + */ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef __APP_ENTRY_H +#define __APP_ENTRY_H + +#include "stm32wbxx_hal.h" +#include "tl.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/* Includes ------------------------------------------------------------------*/ +/* Exported types ------------------------------------------------------------*/ +/* Exported constants --------------------------------------------------------*/ +/* External variables --------------------------------------------------------*/ +typedef struct +{ + uint8_t Pushed_Button; + uint8_t State; // 1 pushed +} Push_Button_st; + +typedef void (*PushButtonCallback)(Push_Button_st * aMessage); + +/* Exported macros -----------------------------------------------------------*/ +/* Exported functions ------------------------------------------------------- */ +void APPE_Init(void); +void APP_ENTRY_RegisterCmdBuffer(TL_CmdPacket_t * p_buffer); +void APP_ENTRY_ProcessMsgM0ToM4(void); +void APP_ENTRY_Init_CFG_CLI_UART(void); +void APP_ENTRY_TL_THREAD_INIT(void); +void APP_ENTRY_PBSetReceiveCallback(PushButtonCallback aCallback); +void APP_ENTRY_LedBlink(uint8_t LedStatus); + +#ifdef __cplusplus +} +#endif + +#endif /* __APP_ENTRY_H */ diff --git a/examples/platform/stm32/common/STM32WB5MM-DK/Inc/flash_driver.h b/examples/platform/stm32/common/STM32WB5MM-DK/Inc/flash_driver.h new file mode 100644 index 00000000000000..24f4cfc6253572 --- /dev/null +++ b/examples/platform/stm32/common/STM32WB5MM-DK/Inc/flash_driver.h @@ -0,0 +1,181 @@ +/* USER CODE BEGIN Header */ +/** + ****************************************************************************** + * @file flash_driver.h + * @author MCD Application Team + * @brief Dual core Flash driver interface + ****************************************************************************** + * @attention + * + * Copyright (c) 2020-2021 STMicroelectronics. + * All rights reserved. + * + * This software is licensed under terms that can be found in the LICENSE file + * in the root directory of this software component. + * If no LICENSE file comes with this software, it is provided AS-IS. + * + ****************************************************************************** + */ +/* USER CODE END Header */ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef FLASH_DRIVER_H +#define FLASH_DRIVER_H + +#ifdef __cplusplus +extern "C" { +#endif + +/* Includes ------------------------------------------------------------------*/ +#include +/* Private includes ----------------------------------------------------------*/ +/* USER CODE BEGIN Includes */ + +/* USER CODE END Includes */ + +/* Exported types ------------------------------------------------------------*/ +typedef enum +{ + SINGLE_FLASH_OPERATION_DONE, + SINGLE_FLASH_OPERATION_NOT_EXECUTED, +} SingleFlashOperationStatus_t; + +typedef enum +{ + WAITED_SEM_BUSY, + WAITED_SEM_FREE, +} WaitedSemStatus_t; + +typedef enum +{ + WAIT_FOR_SEM_BLOCK_FLASH_REQ_BY_CPU1, + WAIT_FOR_SEM_BLOCK_FLASH_REQ_BY_CPU2, +} WaitedSemId_t; + +typedef enum +{ + ReadyToWrite, + NotReadyToWrite, + +} StatusReadyToWrite; +/* Exported functions ------------------------------------------------------- */ + +/** + * @brief Implements the Dual core algorithm to erase multiple sectors in flash with CPU1 + * It calls for each sector to be erased the API FD_EraseSingleSector() + * + * @param FirstSector: The first sector to be erased + * This parameter must be a value between 0 and (SFSA - 1) + * @param NbrOfSectors: The number of sectors to erase + * This parameter must be a value between 1 and (SFSA - FirstSector) + * @retval Number of sectors not erased: + * Depending on the implementation of FD_WaitForSemAvailable(), + * it may still have some sectors not erased when the timing protection has been + * enabled by either CPU1 or CPU2. When the value returned is not 0, the application + * should wait until both timing protection before retrying to erase the last missing sectors. + * + * In addition, When the returned value is not 0: + * - The Sem2 is NOT released + * - The FLASH is NOT locked + * - SHCI_C2_FLASH_EraseActivity(ERASE_ACTIVITY_OFF) is NOT called + * It is expected that the user will call one more time this function to finish the process + */ +uint32_t FD_EraseSectors(uint32_t FirstSector, uint32_t NbrOfSectors); + +/** + * @brief Implements the Dual core algorithm to write multiple 64bits data in flash with CPU1 + * The user shall first make sure the location to be written has been first erase. + * Otherwise, the API will loop for ever as it will be not able to write in flash + * The only value that can be written even though the destination is not erased is 0. + * It calls for each 64bits to be written the API FD_WriteSingleData() + * + * @param DestAddress: Address of the flash to write the first data. It shall be 64bits aligned + * @param pSrcBuffer: Address of the buffer holding the 64bits data to be written in flash + * @param NbrOfData: Number of 64bits data to be written + * @retval Number of 64bits data not written: + * Depending on the implementation of FD_WaitForSemAvailable(), + * it may still have 64bits data not written when the timing protection has been + * enabled by either CPU1 or CPU2. When the value returned is not 0, the application + * should wait until both timing protection before retrying to write the last missing 64bits data. + * + * In addition, When the returned value is not 0: + * - The Sem2 is NOT released + * - The FLASH is NOT locked + * It is expected that the user will call one more time this function to finish the process + */ +uint32_t FD_WriteData(uint32_t DestAddress, uint64_t * pSrcBuffer, uint32_t NbrOfData); + +/** + * @brief Implements the Dual core algorithm to erase one sector in flash with CPU1 + * + * It expects the following point before calling this API: + * - The Sem2 is taken + * - The FLASH is unlocked + * - SHCI_C2_FLASH_EraseActivity(ERASE_ACTIVITY_ON) has been called + * It expects the following point to be done when no more sectors need to be erased + * - The Sem2 is released + * - The FLASH is locked + * - SHCI_C2_FLASH_EraseActivity(ERASE_ACTIVITY_OFF) is called + * + * The two point above are implemented in FD_EraseSectors() + * This API needs to be used instead of FD_EraseSectors() in case a provided library is taking + * care of these two points and request only a single operation. + * + * @param FirstSector: The sector to be erased + * This parameter must be a value between 0 and (SFSA - 1) + * @retval: SINGLE_FLASH_OPERATION_DONE -> The data has been written + * SINGLE_FLASH_OPERATION_NOT_EXECUTED -> The data has not been written due to timing protection + * from either CPU1 or CPU2. On a failure status, the user should check + * both timing protection before retrying. + */ +SingleFlashOperationStatus_t FD_EraseSingleSector(uint32_t SectorNumber); + +/** + * @brief Implements the Dual core algorithm to write one 64bits data in flash with CPU1 + * The user shall first make sure the location to be written has been first erase. + * Otherwise, the API will loop for ever as it will be not able to write in flash + * The only value that can be written even though the destination is not erased is 0. + * + * It expects the following point before calling this API: + * - The Sem2 is taken + * - The FLASH is unlocked + * It expects the following point to be done when no more sectors need to be erased + * - The Sem2 is released + * - The FLASH is locked + * + * The two point above are implemented in FD_WriteData() + * This API needs to be used instead of FD_WriteData() in case a provided library is taking + * care of these two points and request only a single operation. + * + * @param DestAddress: Address of the flash to write the data. It shall be 64bits aligned + * @param Data: 64bits Data to be written + * @retval: SINGLE_FLASH_OPERATION_DONE -> The data has been written + * SINGLE_FLASH_OPERATION_NOT_EXECUTED -> The data has not been written due to timing protection + * from either CPU1 or CPU2. On a failure status, the user should check + * both timing protection before retrying. + */ +SingleFlashOperationStatus_t FD_WriteSingleData(uint32_t DestAddress, uint64_t Data); + +/** + * By default, this function is implemented weakly in flash_driver.c to return WAITED_SEM_BUSY. + * When the semaphore is busy, this will result in either FD_WriteSingleData() or FD_EraseSingleSector() + * to loop until the semaphore is free. + * + * This function may be implemented so that when using either an OS or the UTIL_SEQ_WaitEvt() API from the sequencer, + * it could possible to run other tasks or enter idle mode until the waited semaphore is free. + * This function shall not take the waited semaphore but just return when it is free. + * + * @param WaitedSemId: The semaphore ID this function should not return until it is free + * @retval: WAITED_SEM_BUSY -> The function returned before waiting for the semaphore to be free. This will exit the loop + * from either FD_EraseSingleSector() or FD_WriteSingleData() and the number of actions left to + * be processed are reported to the user + * WAITED_SEM_FREE -> The semaphore has been checked as free. Both FD_EraseSingleSector() and FD_WriteSingleData() + * try again to process one more time the flash. + */ +WaitedSemStatus_t FD_WaitForSemAvailable(WaitedSemId_t WaitedSemId); + +#ifdef __cplusplus +} +#endif + +#endif /*FLASH_DRIVER_H */ diff --git a/examples/platform/stm32/common/STM32WB5MM-DK/Inc/flash_wb.h b/examples/platform/stm32/common/STM32WB5MM-DK/Inc/flash_wb.h new file mode 100644 index 00000000000000..5a866b3edf7fbe --- /dev/null +++ b/examples/platform/stm32/common/STM32WB5MM-DK/Inc/flash_wb.h @@ -0,0 +1,116 @@ +/* USER CODE BEGIN Header */ +/** + ****************************************************************************** + * @file flash_wb.h + * @author MCD Application Team + * @brief Header file for flash_wb.c + ****************************************************************************** + * @attention + * + * Copyright (c) 2023 STMicroelectronics. + * All rights reserved. + * + * This software is licensed under terms that can be found in the LICENSE file + * in the root directory of this software component. + * If no LICENSE file comes with this software, it is provided AS-IS. + * + ****************************************************************************** + */ +/* USER CODE END Header */ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef FLASH_NVM_H +#define FLASH_NVM_H + +/* Includes ------------------------------------------------------------------*/ +#include "stm32wbxx_hal.h" + +#ifdef __cplusplus +extern "C" { +#endif + +typedef enum +{ + NVM_OK, + NVM_KEY_NOT_FOUND, + NVM_WRITE_FAILED, + NVM_READ_FAILED, + NVM_DELETE_FAILED, + NVM_SIZE_FULL, + NVM_BLOCK_SIZE_OVERFLOW, + NVM_ERROR_BLOCK_ALIGN, + NVM_FLASH_CORRUPTION, + NVM_BUFFER_TOO_SMALL +} NVM_StatusTypeDef; + +typedef enum +{ + SECTOR_DEFAULT = 0, + SECTOR_NO_SECURE, + SECTOR_SECURE + +} NVM_Sector; + +/* Exported functions ------------------------------------------------------- */ + +/** + * @brief Copy Flash to RAM NVM + */ + +void NM_Init(void); + +/** + * @brief Copy RAM NVM to Flash + */ +NVM_StatusTypeDef NM_Dump(void); + +/** + * @brief check the nvm if it s corrupted or not + * @retval return NVM_OK if nvm is empty or NVM_FLASH_CORRUPTION if it s not empty + */ +NVM_StatusTypeDef NM_Check_Validity(void); + +/** + * @brief Get KeyName in RAM NVM and return the value of Key in KeyValue + * + * @param KeyValue: Address of the buffer changed in this function if the key found + * @param KeyName: Name of Key needed + * @param KeySize: size of KeyValue + * @param read_by_size: return size of KeyValue found + * @retval return state of function + */ +NVM_StatusTypeDef NM_GetKeyValue(void * KeyValue, const char * KeyName, uint32_t KeySize, size_t * read_by_size, NVM_Sector sector); + +/** + * @brief Set KeyName and value in RAM NVM + * + * @param KeyValue: Address of the buffer + * @param KeyName: Name of Key needed + * @param KeyAddr: TODO DELETED this param + * @param KeySize: size of KeyValue + * @param read_by_size: return size of KeyValue found + * @retval return state of function + */ + +NVM_StatusTypeDef NM_SetKeyValue(char * KeyValue, char * KeyName, uint32_t KeySize, NVM_Sector sector); + +/** + * @brief Delete Key in RAM NVM + * @param KeyName: Name of Key needed + * @retval return state of function + */ + +NVM_StatusTypeDef NM_DeleteKey(const char * Keyname, NVM_Sector sector); + +/** + * @brief Erase all persistent and reboot program + */ + +void NM_ResetFactory(void); +void NM_FullErase(void); + +#ifdef __cplusplus +} +#endif + +#endif /*FLASH_NVM_H */ diff --git a/examples/platform/stm32/common/STM32WB5MM-DK/Inc/hw_conf.h b/examples/platform/stm32/common/STM32WB5MM-DK/Inc/hw_conf.h new file mode 100644 index 00000000000000..109084d298637f --- /dev/null +++ b/examples/platform/stm32/common/STM32WB5MM-DK/Inc/hw_conf.h @@ -0,0 +1,255 @@ +/** + ****************************************************************************** + * @file hw_conf.h + * @author MCD Application Team + * @brief Configuration of hardware interface + ****************************************************************************** + * @attention + * + * Copyright (c) 2019-2021 STMicroelectronics. + * All rights reserved. + * + * This software is licensed under terms that can be found in the LICENSE file + * in the root directory of this software component. + * If no LICENSE file comes with this software, it is provided AS-IS. + * + ****************************************************************************** + */ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef __HW_CONF_H +#define __HW_CONF_H + +/****************************************************************************** + * Semaphores + * THIS SHALL NO BE CHANGED AS THESE SEMAPHORES ARE USED AS WELL ON THE CM0+ + *****************************************************************************/ +/** + * Index of the semaphore used by CPU2 to prevent the CPU1 to either write or erase data in flash + * The CPU1 shall not either write or erase in flash when this semaphore is taken by the CPU2 + * When the CPU1 needs to either write or erase in flash, it shall first get the semaphore and release it just + * after writing a raw (64bits data) or erasing one sector. + * On v1.4.0 and older CPU2 wireless firmware, this semaphore is unused and CPU2 is using PES bit. + * By default, CPU2 is using the PES bit to protect its timing. The CPU1 may request the CPU2 to use the semaphore + * instead of the PES bit by sending the system command SHCI_C2_SetFlashActivityControl() + */ +#define CFG_HW_BLOCK_FLASH_REQ_BY_CPU2_SEMID 7 + +/** + * Index of the semaphore used by CPU1 to prevent the CPU2 to either write or erase data in flash + * In order to protect its timing, the CPU1 may get this semaphore to prevent the CPU2 to either + * write or erase in flash (as this will stall both CPUs) + * The PES bit shall not be used as this may stall the CPU2 in some cases. + */ +#define CFG_HW_BLOCK_FLASH_REQ_BY_CPU1_SEMID 6 + +/** + * Index of the semaphore used to manage the CLK48 clock configuration + * When the USB is required, this semaphore shall be taken before configuring te CLK48 for USB + * and should be released after the application switch OFF the clock when the USB is not used anymore + * When using the RNG, it is good enough to use CFG_HW_RNG_SEMID to control CLK48. + * More details in AN5289 + */ +#define CFG_HW_CLK48_CONFIG_SEMID 5 + +/* Index of the semaphore used to manage the entry Stop Mode procedure */ +#define CFG_HW_ENTRY_STOP_MODE_SEMID 4 + +/* Index of the semaphore used to access the RCC */ +#define CFG_HW_RCC_SEMID 3 + +/* Index of the semaphore used to access the FLASH */ +#define CFG_HW_FLASH_SEMID 2 + +/* Index of the semaphore used to access the PKA */ +#define CFG_HW_PKA_SEMID 1 + +/* Index of the semaphore used to access the RNG */ +#define CFG_HW_RNG_SEMID 0 + +/****************************************************************************** + * HW TIMER SERVER + *****************************************************************************/ +/** + * The user may define the maximum number of virtual timers supported. + * It shall not exceed 255 + */ +#define CFG_HW_TS_MAX_NBR_CONCURRENT_TIMER 6 + +/** + * The user may define the priority in the NVIC of the RTC_WKUP interrupt handler that is used to manage the + * wakeup timer. + * This setting is the preemptpriority part of the NVIC. + */ +#define CFG_HW_TS_NVIC_RTC_WAKEUP_IT_PREEMPTPRIO 3 + +/** + * The user may define the priority in the NVIC of the RTC_WKUP interrupt handler that is used to manage the + * wakeup timer. + * This setting is the subpriority part of the NVIC. It does not exist on all processors. When it is not supported + * on the CPU, the setting is ignored + */ +#define CFG_HW_TS_NVIC_RTC_WAKEUP_IT_SUBPRIO 0 + +/** + * Define a critical section in the Timer server + * The Timer server does not support the API to be nested + * The Application shall either: + * a) Ensure this will never happen + * b) Define the critical section + * The default implementations is masking all interrupts using the PRIMASK bit + * The TimerServer driver uses critical sections to avoid context corruption. This is achieved with the macro + * TIMER_ENTER_CRITICAL_SECTION and TIMER_EXIT_CRITICAL_SECTION. When CFG_HW_TS_USE_PRIMASK_AS_CRITICAL_SECTION is set + * to 1, all STM32 interrupts are masked with the PRIMASK bit of the CortexM CPU. It is possible to use the BASEPRI + * register of the CortexM CPU to keep allowed some interrupts with high priority. In that case, the user shall + * re-implement TIMER_ENTER_CRITICAL_SECTION and TIMER_EXIT_CRITICAL_SECTION and shall make sure that no TimerServer + * API are called when the TIMER critical section is entered + */ +#define CFG_HW_TS_USE_PRIMASK_AS_CRITICAL_SECTION 1 + +/** + * This value shall reflect the maximum delay there could be in the application between the time the RTC interrupt + * is generated by the Hardware and the time when the RTC interrupt handler is called. This time is measured in + * number of RTCCLK ticks. + * A relaxed timing would be 10ms + * When the value is too short, the timerserver will not be able to count properly and all timeout may be random. + * When the value is too long, the device may wake up more often than the most optimal configuration. However, the + * impact on power consumption would be marginal (unless the value selected is extremely too long). It is strongly + * recommended to select a value large enough to make sure it is not too short to ensure reliability of the system + * as this will have marginal impact on low power mode + */ +#define CFG_HW_TS_RTC_HANDLER_MAX_DELAY (10 * (LSI_VALUE / 1000)) + +/** + * Interrupt ID in the NVIC of the RTC Wakeup interrupt handler + * It shall be type of IRQn_Type + */ +#define CFG_HW_TS_RTC_WAKEUP_HANDLER_ID RTC_WKUP_IRQn + +/****************************************************************************** + * HW UART + *****************************************************************************/ +/* For release: set to 1 CFG_HW_LPUART1_ENABLED and CFG_HW_LPUART1_DMA_TX_SUPPORTED */ +#define CFG_HW_LPUART1_ENABLED 1 +#define CFG_HW_LPUART1_DMA_TX_SUPPORTED 1 + +#define CFG_HW_USART1_ENABLED 1 +#define CFG_HW_USART1_DMA_TX_SUPPORTED 1 + +/** + * LPUART1 + */ +#define CFG_HW_LPUART1_PREEMPTPRIORITY 0x0F +#define CFG_HW_LPUART1_SUBPRIORITY 0 + +/** < The application shall check the selected source clock is enable */ +#define CFG_HW_LPUART1_SOURCE_CLOCK RCC_LPUART1CLKSOURCE_SYSCLK + +#define CFG_HW_LPUART1_BAUDRATE 115200 +#define CFG_HW_LPUART1_WORDLENGTH UART_WORDLENGTH_8B +#define CFG_HW_LPUART1_STOPBITS UART_STOPBITS_1 +#define CFG_HW_LPUART1_PARITY UART_PARITY_NONE +#define CFG_HW_LPUART1_HWFLOWCTL UART_HWCONTROL_NONE +#define CFG_HW_LPUART1_MODE UART_MODE_TX_RX +#define CFG_HW_LPUART1_ADVFEATUREINIT UART_ADVFEATURE_NO_INIT +#define CFG_HW_LPUART1_OVERSAMPLING UART_OVERSAMPLING_8 + +#define CFG_HW_LPUART1_TX_PORT_CLK_ENABLE __HAL_RCC_GPIOA_CLK_ENABLE +#define CFG_HW_LPUART1_TX_PORT GPIOA +#define CFG_HW_LPUART1_TX_PIN GPIO_PIN_2 +#define CFG_HW_LPUART1_TX_MODE GPIO_MODE_AF_PP +#define CFG_HW_LPUART1_TX_PULL GPIO_NOPULL +#define CFG_HW_LPUART1_TX_SPEED GPIO_SPEED_FREQ_VERY_HIGH +#define CFG_HW_LPUART1_TX_ALTERNATE GPIO_AF8_LPUART1 + +#define CFG_HW_LPUART1_RX_PORT_CLK_ENABLE __HAL_RCC_GPIOA_CLK_ENABLE +#define CFG_HW_LPUART1_RX_PORT GPIOA +#define CFG_HW_LPUART1_RX_PIN GPIO_PIN_3 +#define CFG_HW_LPUART1_RX_MODE GPIO_MODE_AF_PP +#define CFG_HW_LPUART1_RX_PULL GPIO_NOPULL +#define CFG_HW_LPUART1_RX_SPEED GPIO_SPEED_FREQ_VERY_HIGH +#define CFG_HW_LPUART1_RX_ALTERNATE GPIO_AF8_LPUART1 + +#define CFG_HW_LPUART1_CTS_PORT_CLK_ENABLE __HAL_RCC_GPIOA_CLK_ENABLE +#define CFG_HW_LPUART1_CTS_PORT GPIOA +#define CFG_HW_LPUART1_CTS_PIN GPIO_PIN_6 +#define CFG_HW_LPUART1_CTS_MODE GPIO_MODE_AF_PP +#define CFG_HW_LPUART1_CTS_PULL GPIO_PULLDOWN +#define CFG_HW_LPUART1_CTS_SPEED GPIO_SPEED_FREQ_VERY_HIGH +#define CFG_HW_LPUART1_CTS_ALTERNATE GPIO_AF8_LPUART1 + +#define CFG_HW_LPUART1_DMA_TX_PREEMPTPRIORITY 0x0F +#define CFG_HW_LPUART1_DMA_TX_SUBPRIORITY 0 + +#define CFG_HW_LPUART1_DMAMUX_CLK_ENABLE __HAL_RCC_DMAMUX1_CLK_ENABLE +#define CFG_HW_LPUART1_DMA_CLK_ENABLE __HAL_RCC_DMA1_CLK_ENABLE +#define CFG_HW_LPUART1_TX_DMA_REQ DMA_REQUEST_LPUART1_TX +#define CFG_HW_LPUART1_TX_DMA_CHANNEL DMA1_Channel4 +#define CFG_HW_LPUART1_TX_DMA_IRQn DMA1_Channel4_IRQn +#define CFG_HW_LPUART1_DMA_TX_IRQHandler DMA1_Channel4_IRQHandler + +/** + * UART1 + */ +#define CFG_HW_USART1_PREEMPTPRIORITY 0x0F +#define CFG_HW_USART1_SUBPRIORITY 0 + +/** < The application shall check the selected source clock is enable */ +#define CFG_HW_USART1_SOURCE_CLOCK RCC_USART1CLKSOURCE_SYSCLK + +#define CFG_HW_USART1_BAUDRATE 115200 +#define CFG_HW_USART1_WORDLENGTH UART_WORDLENGTH_8B +#define CFG_HW_USART1_STOPBITS UART_STOPBITS_1 +#define CFG_HW_USART1_PARITY UART_PARITY_NONE +#define CFG_HW_USART1_HWFLOWCTL UART_HWCONTROL_NONE +#define CFG_HW_USART1_MODE UART_MODE_TX_RX +#define CFG_HW_USART1_ADVFEATUREINIT UART_ADVFEATURE_NO_INIT +#define CFG_HW_USART1_OVERSAMPLING UART_OVERSAMPLING_8 + +#define CFG_HW_USART1_TX_PORT_CLK_ENABLE __HAL_RCC_GPIOB_CLK_ENABLE +#define CFG_HW_USART1_TX_PORT GPIOB +#define CFG_HW_USART1_TX_PIN GPIO_PIN_6 +#define CFG_HW_USART1_TX_MODE GPIO_MODE_AF_PP +#define CFG_HW_USART1_TX_PULL GPIO_NOPULL +#define CFG_HW_USART1_TX_SPEED GPIO_SPEED_FREQ_VERY_HIGH +#define CFG_HW_USART1_TX_ALTERNATE GPIO_AF7_USART1 + +#define CFG_HW_USART1_RX_PORT_CLK_ENABLE __HAL_RCC_GPIOB_CLK_ENABLE +#define CFG_HW_USART1_RX_PORT GPIOB +#define CFG_HW_USART1_RX_PIN GPIO_PIN_7 +#define CFG_HW_USART1_RX_MODE GPIO_MODE_AF_PP +#define CFG_HW_USART1_RX_PULL GPIO_NOPULL +#define CFG_HW_USART1_RX_SPEED GPIO_SPEED_FREQ_VERY_HIGH +#define CFG_HW_USART1_RX_ALTERNATE GPIO_AF7_USART1 + +#define CFG_HW_USART1_CTS_PORT_CLK_ENABLE __HAL_RCC_GPIOA_CLK_ENABLE +#define CFG_HW_USART1_CTS_PORT GPIOA +#define CFG_HW_USART1_CTS_PIN GPIO_PIN_11 +#define CFG_HW_USART1_CTS_MODE GPIO_MODE_AF_PP +#define CFG_HW_USART1_CTS_PULL GPIO_PULLDOWN +#define CFG_HW_USART1_CTS_SPEED GPIO_SPEED_FREQ_VERY_HIGH +#define CFG_HW_USART1_CTS_ALTERNATE GPIO_AF7_USART1 + +#define CFG_HW_USART1_DMA_TX_PREEMPTPRIORITY 0x0F +#define CFG_HW_USART1_DMA_TX_SUBPRIORITY 0 + +#define CFG_HW_USART1_DMAMUX_CLK_ENABLE __HAL_RCC_DMAMUX1_CLK_ENABLE +#define CFG_HW_USART1_DMA_CLK_ENABLE __HAL_RCC_DMA2_CLK_ENABLE +#define CFG_HW_USART1_TX_DMA_REQ DMA_REQUEST_USART1_TX +#define CFG_HW_USART1_TX_DMA_CHANNEL DMA2_Channel4 +#define CFG_HW_USART1_TX_DMA_IRQn DMA2_Channel4_IRQn +#define CFG_HW_USART1_DMA_TX_IRQHandler DMA2_Channel4_IRQHandler + +/****************************************************************************** + * External PA + *****************************************************************************/ +#define CFG_HW_EXTPA_ENABLED 0 + +// External PA enable pin is chosen by user +#define GPIO_EXT_PA_EN_PIN GPIO_PIN_9 +#define GPIO_EXT_PA_EN_PORT GPIOB + +// External PA TX/RX pin is fixed by the chip +#define GPIO_EXT_PA_TX_PIN GPIO_PIN_0 +#define GPIO_EXT_PA_TX_PORT GPIOB +#endif /*__HW_CONF_H */ diff --git a/examples/platform/stm32/common/STM32WB5MM-DK/Inc/hw_if.h b/examples/platform/stm32/common/STM32WB5MM-DK/Inc/hw_if.h new file mode 100644 index 00000000000000..b2a79590e9238a --- /dev/null +++ b/examples/platform/stm32/common/STM32WB5MM-DK/Inc/hw_if.h @@ -0,0 +1,251 @@ +/* USER CODE BEGIN Header */ +/** + ****************************************************************************** + * @file hw_if.h + * @author MCD Application Team + * @brief Hardware Interface + ****************************************************************************** + * @attention + * + * Copyright (c) 2019-2021 STMicroelectronics. + * All rights reserved. + * + * This software is licensed under terms that can be found in the LICENSE file + * in the root directory of this software component. + * If no LICENSE file comes with this software, it is provided AS-IS. + * + ****************************************************************************** + */ +/* USER CODE END Header */ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef HW_IF_H +#define HW_IF_H + +#ifdef __cplusplus +extern "C" { +#endif + +/* Includes ------------------------------------------------------------------*/ +#include "stm32wbxx.h" +#include "stm32wbxx_ll_bus.h" +#include "stm32wbxx_ll_cortex.h" +#include "stm32wbxx_ll_exti.h" +#include "stm32wbxx_ll_gpio.h" +#include "stm32wbxx_ll_hsem.h" +#include "stm32wbxx_ll_ipcc.h" +#include "stm32wbxx_ll_pwr.h" +#include "stm32wbxx_ll_rcc.h" +#include "stm32wbxx_ll_rtc.h" +#include "stm32wbxx_ll_system.h" +#include "stm32wbxx_ll_utils.h" + +#ifdef USE_STM32WBXX_USB_DONGLE +#include "stm32wbxx_usb_dongle.h" +#endif +#ifdef USE_STM32WBXX_NUCLEO +#include "stm32wbxx_nucleo.h" +#endif +#ifdef USE_X_NUCLEO_EPD +#include "x_nucleo_epd.h" +#endif +#ifdef USE_STM32WB5M_DK +#include "stm32wb5mm_dk.h" +#endif + +/* Private includes ----------------------------------------------------------*/ +/* USER CODE BEGIN Includes */ + +/* USER CODE END Includes */ + +/****************************************************************************** + * HW UART + ******************************************************************************/ +typedef enum +{ + hw_uart1, + hw_uart2, + hw_lpuart1, +} hw_uart_id_t; + +typedef enum +{ + hw_uart_ok, + hw_uart_error, + hw_uart_busy, + hw_uart_to, +} hw_status_t; + +void HW_UART_Init(hw_uart_id_t hw_uart_id); +void HW_UART_Receive_IT(hw_uart_id_t hw_uart_id, uint8_t * pData, uint16_t Size, void (*Callback)(void)); +void HW_UART_Transmit_IT(hw_uart_id_t hw_uart_id, uint8_t * pData, uint16_t Size, void (*Callback)(void)); +hw_status_t HW_UART_Transmit(hw_uart_id_t hw_uart_id, uint8_t * p_data, uint16_t size, uint32_t timeout); +hw_status_t HW_UART_Transmit_DMA(hw_uart_id_t hw_uart_id, uint8_t * p_data, uint16_t size, void (*Callback)(void)); +void HW_UART_Interrupt_Handler(hw_uart_id_t hw_uart_id); +void HW_UART_DMA_Interrupt_Handler(hw_uart_id_t hw_uart_id); + +/****************************************************************************** + * HW TimerServer + ******************************************************************************/ +/* Exported types ------------------------------------------------------------*/ +/** + * This setting is used when standby mode is supported. + * hw_ts_InitMode_Limited should be used when the device restarts from Standby Mode. In that case, the Timer Server does + * not re-initialized its context. Only the Hardware register which content has been lost is reconfigured + * Otherwise, hw_ts_InitMode_Full should be requested (Start from Power ON) and everything is re-initialized. + */ +typedef enum +{ + hw_ts_InitMode_Full, + hw_ts_InitMode_Limited, +} HW_TS_InitMode_t; + +/** + * When a Timer is created as a SingleShot timer, it is not automatically restarted when the timeout occurs. However, + * the timer is kept reserved in the list and could be restarted at anytime with HW_TS_Start() + * + * When a Timer is created as a Repeated timer, it is automatically restarted when the timeout occurs. + */ +typedef enum +{ + hw_ts_SingleShot, + hw_ts_Repeated +} HW_TS_Mode_t; + +/** + * hw_ts_Successful is returned when a Timer has been successfully created with HW_TS_Create(). Otherwise, hw_ts_Failed + * is returned. When hw_ts_Failed is returned, that means there are not enough free slots in the list to create a + * Timer. In that case, CFG_HW_TS_MAX_NBR_CONCURRENT_TIMER should be increased + */ +typedef enum +{ + hw_ts_Successful, + hw_ts_Failed, +} HW_TS_ReturnStatus_t; + +typedef void (*HW_TS_pTimerCb_t)(void); + +/** + * @brief Initialize the timer server + * This API shall be called by the application before any timer is requested to the timer server. It + * configures the RTC module to be connected to the LSI input clock. + * + * @param TimerInitMode: When the device restarts from Standby, it should request hw_ts_InitMode_Limited so that the + * Timer context is not re-initialized. Otherwise, hw_ts_InitMode_Full should be requested + * @param hrtc: RTC Handle + * @retval None + */ +void HW_TS_Init(HW_TS_InitMode_t TimerInitMode, RTC_HandleTypeDef * hrtc); + +/** + * @brief Interface to create a virtual timer + * The user shall call this API to create a timer. Once created, the timer is reserved to the module until it + * has been deleted. When creating a timer, the user shall specify the mode (single shot or repeated), the + * callback to be notified when the timer expires and a module ID to identify in the timer interrupt handler + * which module is concerned. In return, the user gets a timer ID to handle it. + * + * @param TimerProcessID: This is an identifier provided by the user and returned in the callback to allow + * identification of the requester + * @param pTimerId: Timer Id returned to the user to request operation (start, stop, delete) + * @param TimerMode: Mode of the virtual timer (Single shot or repeated) + * @param pTimerCallBack: Callback when the virtual timer expires + * @retval HW_TS_ReturnStatus_t: Return whether the creation is successful or not + */ +HW_TS_ReturnStatus_t HW_TS_Create(uint32_t TimerProcessID, uint8_t * pTimerId, HW_TS_Mode_t TimerMode, + HW_TS_pTimerCb_t pTimerCallBack); + +/** + * @brief Stop a virtual timer + * This API may be used to stop a running timer. A timer which is stopped is move to the pending state. + * A pending timer may be restarted at any time with a different timeout value but the mode cannot be changed. + * Nothing is done when it is called to stop a timer which has been already stopped + * + * @param TimerID: Id of the timer to stop + * @retval None + */ +void HW_TS_Stop(uint8_t TimerID); + +/** + * @brief Start a virtual timer + * This API shall be used to start a timer. The timeout value is specified and may be different each time. + * When the timer is in the single shot mode, it will move to the pending state when it expires. The user may + * restart it at any time with a different timeout value. When the timer is in the repeated mode, it always + * stay in the running state. When the timer expires, it will be restarted with the same timeout value. + * This API shall not be called on a running timer. + * + * @param TimerID: The ID Id of the timer to start + * @param timeout_ticks: Number of ticks of the virtual timer (Maximum value is (0xFFFFFFFF-0xFFFF = 0xFFFF0000) + * @retval None + */ +void HW_TS_Start(uint8_t TimerID, uint32_t timeout_ticks); + +/** + * @brief Delete a virtual timer from the list + * This API should be used when a timer is not needed anymore by the user. A deleted timer is removed from + * the timer list managed by the timer server. It cannot be restarted again. The user has to go with the + * creation of a new timer if required and may get a different timer id + * + * @param TimerID: The ID of the timer to remove from the list + * @retval None + */ +void HW_TS_Delete(uint8_t TimerID); + +/** + * @brief Schedule the timer list on the timer interrupt handler + * This interrupt handler shall be called by the application in the RTC interrupt handler. This handler takes + * care of clearing all status flag required in the RTC and EXTI peripherals + * + * @param None + * @retval None + */ +void HW_TS_RTC_Wakeup_Handler(void); + +/** + * @brief Return the number of ticks to count before the interrupt + * This API returns the number of ticks left to be counted before an interrupt is generated by the + * Timer Server. This API may be used by the application for power management optimization. When the system + * enters low power mode, the mode selection is a tradeoff between the wakeup time where the CPU is running + * and the time while the CPU will be kept in low power mode before next wakeup. The deeper is the + * low power mode used, the longer is the wakeup time. The low power mode management considering wakeup time + * versus time in low power mode is implementation specific + * When the timer is disabled (No timer in the list), it returns 0xFFFF + * + * @param None + * @retval The number of ticks left to count + */ +uint16_t HW_TS_RTC_ReadLeftTicksToCount(void); + +/** + * @brief Notify the application that a registered timer has expired + * This API shall be implemented by the user application. + * This API notifies the application that a timer expires. This API is running in the RTC Wakeup interrupt + * context. The application may implement an Operating System to change the context priority where the timer + * callback may be handled. This API provides the module ID to identify which module is concerned and to allow + * sending the information to the correct task + * + * @param TimerProcessID: The TimerProcessId associated with the timer when it has been created + * @param TimerID: The TimerID of the expired timer + * @param pTimerCallBack: The Callback associated with the timer when it has been created + * @retval None + */ +void HW_TS_RTC_Int_AppNot(uint32_t TimerProcessID, uint8_t TimerID, HW_TS_pTimerCb_t pTimerCallBack); + +/** + * @brief Notify the application that the wakeupcounter has been updated + * This API should be implemented by the user application + * This API notifies the application that the counter has been updated. This is expected to be used along + * with the HW_TS_RTC_ReadLeftTicksToCount () API. It could be that the counter has been updated since the + * last call of HW_TS_RTC_ReadLeftTicksToCount () and before entering low power mode. This notification + * provides a way to the application to solve that race condition to reevaluate the counter value before + * entering low power mode + * + * @param None + * @retval None + */ +void HW_TS_RTC_CountUpdated_AppNot(void); + +#ifdef __cplusplus +} +#endif + +#endif /*HW_IF_H */ diff --git a/examples/platform/stm32/common/STM32WB5MM-DK/Inc/main.h b/examples/platform/stm32/common/STM32WB5MM-DK/Inc/main.h new file mode 100644 index 00000000000000..6ea2f076e6a8ae --- /dev/null +++ b/examples/platform/stm32/common/STM32WB5MM-DK/Inc/main.h @@ -0,0 +1,65 @@ +/** + ****************************************************************************** + * @file main.h + * @author MCD Application Team + * @brief Header for main.c module + ****************************************************************************** + * @attention + * + * Copyright (c) 2019-2021 STMicroelectronics. + * All rights reserved. + * + * This software is licensed under terms that can be found in the LICENSE file + * in the root directory of this software component. + * If no LICENSE file comes with this software, it is provided AS-IS. + * + ****************************************************************************** + */ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef __MAIN_H +#define __MAIN_H + +/* Includes ------------------------------------------------------------------*/ +#include "stm32wbxx_hal.h" + +/* Private includes ----------------------------------------------------------*/ +/* USER CODE BEGIN Includes */ +#ifdef USE_STM32WBXX_USB_DONGLE +#include "stm32wbxx_usb_dongle.h" +#endif +#ifdef USE_STM32WBXX_NUCLEO +#include "stm32wbxx_nucleo.h" +#endif +#ifdef USE_X_NUCLEO_EPD +#include "x_nucleo_epd.h" +#endif +#ifdef USE_STM32WB5M_DK +#include "./../../../../../Drivers/BSP/STM32WB5MM-DK/stm32wb5mm_dk.h" + +#endif + +/* Exported types ------------------------------------------------------------*/ +/* Exported constants --------------------------------------------------------*/ +/* Exported variables --------------------------------------------------------*/ +extern RTC_HandleTypeDef hrtc; /**< RTC handler declaration */ +extern RNG_HandleTypeDef hrng; + +/* Exported macro ------------------------------------------------------------*/ +/* Exported functions ------------------------------------------------------- */ + +/* USER CODE END EM */ + +/* Exported functions prototypes ---------------------------------------------*/ +void Error_Handler(void); + +/* USER CODE BEGIN EFP */ + +/* USER CODE END EFP */ + +/* Private defines -----------------------------------------------------------*/ +/* USER CODE BEGIN Private defines */ + +/* USER CODE END Private defines */ + +#endif /* __MAIN_H */ diff --git a/examples/platform/stm32/common/STM32WB5MM-DK/Inc/otp.h b/examples/platform/stm32/common/STM32WB5MM-DK/Inc/otp.h new file mode 100644 index 00000000000000..d6b24d42b93bc1 --- /dev/null +++ b/examples/platform/stm32/common/STM32WB5MM-DK/Inc/otp.h @@ -0,0 +1,63 @@ +/** + ****************************************************************************** + * @file otp.h + * @author MCD Application Team + * @brief OTP manager interface + ****************************************************************************** + * @attention + * + * Copyright (c) 2018-2021 STMicroelectronics. + * All rights reserved. + * + * This software is licensed under terms that can be found in the LICENSE file + * in the root directory of this software component. + * If no LICENSE file comes with this software, it is provided AS-IS. + * + ****************************************************************************** + */ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef __OTP_H +#define __OTP_H + +#ifdef __cplusplus +extern "C" { +#endif + +/* Includes ------------------------------------------------------------------*/ +#include "utilities_common.h" + +/* Exported types ------------------------------------------------------------*/ +typedef PACKED_STRUCT +{ + uint8_t bd_address[6]; + uint8_t hse_tuning; + uint8_t id; +} +OTP_ID0_t; + +/* Exported constants --------------------------------------------------------*/ +/* External variables --------------------------------------------------------*/ +/* Exported macros -----------------------------------------------------------*/ +/* Exported functions ------------------------------------------------------- */ + +/** + * @brief This API return the address (64 bits aligned) of the ID parameter in the OTP + * It returns the first ID declaration found from the higher address down to the base address + * The user shall fill the OTP from the base address to the top of the OTP so that the more recent + * declaration is returned by the API + * The OTP manager handles only 64bits parameter + * | Id | Parameter | + * | 8bits | 58bits | + * | MSB | LSB | + * + * @param id: ID of the parameter to read from OTP + * @retval Address of the ID in the OTP - returns 0 when no ID found + */ +uint8_t * OTP_Read(uint8_t id); + +#ifdef __cplusplus +} +#endif + +#endif /*__OTP_H */ diff --git a/examples/platform/stm32/common/STM32WB5MM-DK/Inc/stm32_lpm_if.h b/examples/platform/stm32/common/STM32WB5MM-DK/Inc/stm32_lpm_if.h new file mode 100644 index 00000000000000..6c5dacb2f8c15c --- /dev/null +++ b/examples/platform/stm32/common/STM32WB5MM-DK/Inc/stm32_lpm_if.h @@ -0,0 +1,78 @@ +/* USER CODE BEGIN Header */ +/** + ****************************************************************************** + * @file stm32_lpm_if.h + * @brief Header for stm32_lpm_if.c module (device specific LP management) + ****************************************************************************** + * @attention + * + * Copyright (c) 2019-2021 STMicroelectronics. + * All rights reserved. + * + * This software is licensed under terms that can be found in the LICENSE file + * in the root directory of this software component. + * If no LICENSE file comes with this software, it is provided AS-IS. + * + ****************************************************************************** + */ +/* USER CODE END Header */ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef __STM32_LPM_IF_H +#define __STM32_LPM_IF_H + +#ifdef __cplusplus +extern "C" { +#endif + +/* Includes ------------------------------------------------------------------*/ + +/** + * @brief Enters Low Power Off Mode + * @param none + * @retval none + */ +void PWR_EnterOffMode(void); +/** + * @brief Exits Low Power Off Mode + * @param none + * @retval none + */ +void PWR_ExitOffMode(void); + +/** + * @brief Enters Low Power Stop Mode + * @note ARM exists the function when waking up + * @param none + * @retval none + */ +void PWR_EnterStopMode(void); +/** + * @brief Exits Low Power Stop Mode + * @note Enable the pll at 32MHz + * @param none + * @retval none + */ +void PWR_ExitStopMode(void); + +/** + * @brief Enters Low Power Sleep Mode + * @note ARM exits the function when waking up + * @param none + * @retval none + */ +void PWR_EnterSleepMode(void); + +/** + * @brief Exits Low Power Sleep Mode + * @note ARM exits the function when waking up + * @param none + * @retval none + */ +void PWR_ExitSleepMode(void); + +#ifdef __cplusplus +} +#endif + +#endif /*__STM32_LPM_IF_H */ diff --git a/examples/platform/stm32/common/STM32WB5MM-DK/Inc/stm32wb5mm_dk_conf.h b/examples/platform/stm32/common/STM32WB5MM-DK/Inc/stm32wb5mm_dk_conf.h new file mode 100644 index 00000000000000..7c387dd27e1bb8 --- /dev/null +++ b/examples/platform/stm32/common/STM32WB5MM-DK/Inc/stm32wb5mm_dk_conf.h @@ -0,0 +1,101 @@ +/** + ****************************************************************************** + * @file stm32wb5mm_dk_conf_template.h + * @author MCD Application Team + * @brief configuration file. + * This file should be copied to the application folder and renamed + * to stm32wb5mm_dk_conf.h + ****************************************************************************** + * @attention + * + * Copyright (c) 2019-2021 STMicroelectronics. + * All rights reserved. + * + * This software is licensed under terms that can be found in the LICENSE file + * in the root directory of this software component. + * If no LICENSE file comes with this software, it is provided AS-IS. + * + ****************************************************************************** + */ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef STM32WB5MM_DK_CONF_H +#define STM32WB5MM_DK_CONF_H + +#ifdef __cplusplus +extern "C" { +#endif + +/* Includes ------------------------------------------------------------------*/ +#include "stm32wbxx_hal.h" + +/* Environmental Sensors usage */ +#define USE_ENV_SENSOR_HTS221_0 0U +#define USE_ENV_SENSOR_LPS22HH_0 0U + +/* Motion Sensors usage */ +#define USE_MOTION_SENSOR_ISM330DLC_0 0U +#define USE_MOTION_SENSOR_IIS2MDC_0 0U + +/* COM port usage */ +#define USE_BSP_COM_FEATURE 0U +#define USE_COM_LOG 0U + +#define USE_LCD_CTRL_SSD1315 1U +#define ENV_TEMPERATURE 0U +#define USE_MOTION_SENSOR_ISM330DHCX_0 0U +#define ENV_PRESSURE 0U +#define ENV_HUMIDITY 0U + +/* IRQ priorities */ +#define BSP_BUTTON_USERx_IT_PRIORITY 0x05UL +#define PWM_LED_CLOCK_IT_PRIORITY 0x03UL + +/* I2C3 Frequency in Hz */ +#define BUS_I2C3_FREQUENCY 100000UL /* Frequency of I2C3 = 100 KHz*/ + +/* Indicates whether or not TCXO is supported by the board + * 0: TCXO not supported + * 1: TCXO supported + */ +#define IS_TCXO_SUPPORTED 0U + +/* Indicates whether or not DCDC is supported by the board + * 0: DCDC not supported + * 1: DCDC supported + */ +#define IS_DCDC_SUPPORTED 1U + +#define STM32WB5MM_DK_I2C_Init BSP_I2C3_Init +#define STM32WB5MM_DK_I2C_DeInit BSP_I2C3_DeInit +#define STM32WB5MM_DK_I2C_ReadReg BSP_I2C3_ReadReg +#define STM32WB5MM_DK_I2C_WriteReg BSP_I2C3_WriteReg + +#define STM32WB5MM_DK_GetTick BSP_GetTick + +/*Number of millisecond of audio at each DMA interrupt*/ +#define N_MS_PER_INTERRUPT (20U) + +#define AUDIO_IN_CHANNELS 1 +#define AUDIO_IN_SAMPLING_FREQUENCY 16000 + +#define AUDIO_CHANNELS_OUT 1 +#define AUDIO_OUT_SAMPLING_FREQUENCY 16000 + +#define AUDIO_IN_BUFFER_SIZE DEFAULT_AUDIO_IN_BUFFER_SIZE + +#if (AUDIO_IN_SAMPLING_FREQUENCY == 8000) +#define MAX_DECIMATION_FACTOR 160 +#else +#define MAX_DECIMATION_FACTOR 128 +#endif + +#define MAX_MIC_FREQ 1280 /*kHz - Maximum PDM clock */ +#define MAX_AUDIO_IN_CHANNEL_NBR_PER_IF 1 /* Maximum number of microphones channels for peripheral interface */ +#define MAX_AUDIO_IN_CHANNEL_NBR_TOTAL 1 + +#ifdef __cplusplus +} +#endif + +#endif /* STM32WB5MM_DK_CONF_H */ diff --git a/examples/platform/stm32/common/STM32WB5MM-DK/Inc/stm32wbxx_hal_conf.h b/examples/platform/stm32/common/STM32WB5MM-DK/Inc/stm32wbxx_hal_conf.h new file mode 100644 index 00000000000000..4a78560dcf6a2f --- /dev/null +++ b/examples/platform/stm32/common/STM32WB5MM-DK/Inc/stm32wbxx_hal_conf.h @@ -0,0 +1,352 @@ +/* USER CODE BEGIN Header */ +/** + ****************************************************************************** + * @file stm32wbxx_hal_conf.h + * @author MCD Application Team + * @brief HAL configuration file. + ****************************************************************************** + * @attention + * + * Copyright (c) 2019 STMicroelectronics. + * All rights reserved. + * + * This software is licensed under terms that can be found in the LICENSE file + * in the root directory of this software component. + * If no LICENSE file comes with this software, it is provided AS-IS. + * + ****************************************************************************** + */ +/* USER CODE END Header */ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef __STM32WBxx_HAL_CONF_H +#define __STM32WBxx_HAL_CONF_H + +#ifdef __cplusplus +extern "C" { +#endif + +/* Exported types ------------------------------------------------------------*/ +/* Exported constants --------------------------------------------------------*/ + +/* ########################## Module Selection ############################## */ +/** + * @brief This is the list of modules to be used in the HAL driver + */ +#define HAL_MODULE_ENABLED +/*#define HAL_ADC_MODULE_ENABLED */ +/*#define HAL_CRYP_MODULE_ENABLED */ +/*#define HAL_COMP_MODULE_ENABLED */ +/*#define HAL_CRC_MODULE_ENABLED */ +#define HAL_HSEM_MODULE_ENABLED +#define HAL_I2C_MODULE_ENABLED +#define HAL_IPCC_MODULE_ENABLED +/*#define HAL_IRDA_MODULE_ENABLED */ +/*#define HAL_IWDG_MODULE_ENABLED */ +/*#define HAL_LCD_MODULE_ENABLED */ +/*#define HAL_LPTIM_MODULE_ENABLED */ +/*#define HAL_PCD_MODULE_ENABLED */ +/*#define HAL_PKA_MODULE_ENABLED */ +#define HAL_QSPI_MODULE_ENABLED +#define HAL_RNG_MODULE_ENABLED +#define HAL_RTC_MODULE_ENABLED +/*#define HAL_SAI_MODULE_ENABLED */ +/*#define HAL_SMBUS_MODULE_ENABLED */ +/*#define HAL_SMARTCARD_MODULE_ENABLED */ +#define HAL_SPI_MODULE_ENABLED +#define HAL_TIM_MODULE_ENABLED +/*#define HAL_TSC_MODULE_ENABLED */ +#define HAL_UART_MODULE_ENABLED +/*#define HAL_USART_MODULE_ENABLED */ +/*#define HAL_WWDG_MODULE_ENABLED */ +#define HAL_EXTI_MODULE_ENABLED +#define HAL_CORTEX_MODULE_ENABLED +#define HAL_DMA_MODULE_ENABLED +#define HAL_FLASH_MODULE_ENABLED +#define HAL_GPIO_MODULE_ENABLED +#define HAL_PWR_MODULE_ENABLED +#define HAL_RCC_MODULE_ENABLED + +#define USE_HAL_ADC_REGISTER_CALLBACKS 0u +#define USE_HAL_COMP_REGISTER_CALLBACKS 0u +#define USE_HAL_CRYP_REGISTER_CALLBACKS 0u +#define USE_HAL_I2C_REGISTER_CALLBACKS 0u +#define USE_HAL_IRDA_REGISTER_CALLBACKS 0u +#define USE_HAL_LPTIM_REGISTER_CALLBACKS 0u +#define USE_HAL_PCD_REGISTER_CALLBACKS 0u +#define USE_HAL_PKA_REGISTER_CALLBACKS 0u +#define USE_HAL_QSPI_REGISTER_CALLBACKS 0u +#define USE_HAL_RNG_REGISTER_CALLBACKS 0u +#define USE_HAL_RTC_REGISTER_CALLBACKS 0u +#define USE_HAL_SAI_REGISTER_CALLBACKS 0u +#define USE_HAL_SMARTCARD_REGISTER_CALLBACKS 0u +#define USE_HAL_SMBUS_REGISTER_CALLBACKS 0u +#define USE_HAL_SPI_REGISTER_CALLBACKS 0u +#define USE_HAL_TIM_REGISTER_CALLBACKS 0u +#define USE_HAL_TSC_REGISTER_CALLBACKS 0u +#define USE_HAL_UART_REGISTER_CALLBACKS 0u +#define USE_HAL_USART_REGISTER_CALLBACKS 0u +#define USE_HAL_WWDG_REGISTER_CALLBACKS 0u + +/* ########################## Oscillator Values adaptation ####################*/ +/** + * @brief Adjust the value of External High Speed oscillator (HSE) used in your application. + * This value is used by the RCC HAL module to compute the system frequency + * (when HSE is used as system clock source, directly or through the PLL). + */ +#if !defined(HSE_VALUE) +#define HSE_VALUE 32000000U /*!< Value of the External oscillator in Hz */ +#endif /* HSE_VALUE */ + +#if !defined(HSE_STARTUP_TIMEOUT) +#define HSE_STARTUP_TIMEOUT ((uint32_t) 100) /*!< Time out for HSE start up, in ms */ +#endif /* HSE_STARTUP_TIMEOUT */ + +/** + * @brief Internal Multiple Speed oscillator (MSI) default value. + * This value is the default MSI range value after Reset. + */ +#if !defined(MSI_VALUE) +#define MSI_VALUE ((uint32_t) 4000000) /*!< Value of the Internal oscillator in Hz*/ +#endif /* MSI_VALUE */ + +/** + * @brief Internal High Speed oscillator (HSI) value. + * This value is used by the RCC HAL module to compute the system frequency + * (when HSI is used as system clock source, directly or through the PLL). + */ +#if !defined(HSI_VALUE) +#define HSI_VALUE 16000000U /*!< Value of the Internal oscillator in Hz*/ +#endif /* HSI_VALUE */ + +/** + * @brief Internal Low Speed oscillator (LSI1) value. + */ +#if !defined(LSI1_VALUE) +#define LSI1_VALUE ((uint32_t) 32000) /*!< LSI1 Typical Value in Hz*/ +#endif /* LSI1_VALUE */ /*!< Value of the Internal Low Speed oscillator in Hz \ + The real value may vary depending on the variations \ + in voltage and temperature.*/ +/** + * @brief Internal Low Speed oscillator (LSI2) value. + */ +#if !defined(LSI2_VALUE) +#define LSI2_VALUE ((uint32_t) 32000) /*!< LSI2 Typical Value in Hz*/ +#endif /* LSI2_VALUE */ /*!< Value of the Internal Low Speed oscillator in Hz \ + The real value may vary depending on the variations \ + in voltage and temperature.*/ + +/** + * @brief External Low Speed oscillator (LSE) value. + * This value is used by the UART, RTC HAL module to compute the system frequency + */ +#if !defined(LSE_VALUE) +#define LSE_VALUE 32768U /*!< Value of the External oscillator in Hz*/ +#endif /* LSE_VALUE */ + +/** + * @brief Internal Multiple Speed oscillator (HSI48) default value. + * This value is the default HSI48 range value after Reset. + */ +#if !defined(HSI48_VALUE) +#define HSI48_VALUE ((uint32_t) 48000000) /*!< Value of the Internal oscillator in Hz*/ +#endif /* HSI48_VALUE */ + +#if !defined(LSE_STARTUP_TIMEOUT) +#define LSE_STARTUP_TIMEOUT 5000U /*!< Time out for LSE start up, in ms */ +#endif /* LSE_STARTUP_TIMEOUT */ + +/** + * @brief External clock source for SAI1 peripheral + * This value is used by the RCC HAL module to compute the SAI1 & SAI2 clock source + * frequency. + */ +#if !defined(EXTERNAL_SAI1_CLOCK_VALUE) +#define EXTERNAL_SAI1_CLOCK_VALUE ((uint32_t) 2097000) /*!< Value of the SAI1 External clock source in Hz*/ +#endif /* EXTERNAL_SAI1_CLOCK_VALUE */ + +/* Tip: To avoid modifying this file each time you need to use different HSE, + === you can define the HSE value in your toolchain compiler preprocessor. */ + +/* ########################### System Configuration ######################### */ +/** + * @brief This is the HAL system configuration section + */ + +#define VDD_VALUE 3300U /*!< Value of VDD in mv */ +#define TICK_INT_PRIORITY 0U /*!< tick interrupt priority */ +#define USE_RTOS 0U +#define PREFETCH_ENABLE 1U +#define INSTRUCTION_CACHE_ENABLE 1U +#define DATA_CACHE_ENABLE 1U + +/* ########################## Assert Selection ############################## */ +/** + * @brief Uncomment the line below to expanse the "assert_param" macro in the + * HAL drivers code + */ +/* #define USE_FULL_ASSERT 1U */ + +/* ################## SPI peripheral configuration ########################## */ + +/* CRC FEATURE: Use to activate CRC feature inside HAL SPI Driver + * Activated: CRC code is present inside driver + * Deactivated: CRC code cleaned from driver + */ + +#define USE_SPI_CRC 0U + +/* Includes ------------------------------------------------------------------*/ +/** + * @brief Include module's header file + */ +#ifdef HAL_DMA_MODULE_ENABLED +#include "stm32wbxx_hal_dma.h" +#endif /* HAL_DMA_MODULE_ENABLED */ + +#ifdef HAL_ADC_MODULE_ENABLED +#include "stm32wbxx_hal_adc.h" +#endif /* HAL_ADC_MODULE_ENABLED */ + +#ifdef HAL_COMP_MODULE_ENABLED +#include "stm32wbxx_hal_comp.h" +#endif /* HAL_COMP_MODULE_ENABLED */ + +#ifdef HAL_CORTEX_MODULE_ENABLED +#include "stm32wbxx_hal_cortex.h" +#endif /* HAL_CORTEX_MODULE_ENABLED */ + +#ifdef HAL_CRC_MODULE_ENABLED +#include "stm32wbxx_hal_crc.h" +#endif /* HAL_CRC_MODULE_ENABLED */ + +#ifdef HAL_CRYP_MODULE_ENABLED +#include "stm32wbxx_hal_cryp.h" +#endif /* HAL_CRYP_MODULE_ENABLED */ + +#ifdef HAL_EXTI_MODULE_ENABLED +#include "stm32wbxx_hal_exti.h" +#endif /* HAL_EXTI_MODULE_ENABLED */ + +#ifdef HAL_FLASH_MODULE_ENABLED +#include "stm32wbxx_hal_flash.h" +#endif /* HAL_FLASH_MODULE_ENABLED */ + +#ifdef HAL_GPIO_MODULE_ENABLED +#include "stm32wbxx_hal_gpio.h" +#endif /* HAL_GPIO_MODULE_ENABLED */ + +#ifdef HAL_HSEM_MODULE_ENABLED +#include "stm32wbxx_hal_hsem.h" +#endif /* HAL_HSEM_MODULE_ENABLED */ + +#ifdef HAL_I2C_MODULE_ENABLED +#include "stm32wbxx_hal_i2c.h" +#endif /* HAL_I2C_MODULE_ENABLED */ + +#ifdef HAL_IPCC_MODULE_ENABLED +#include "stm32wbxx_hal_ipcc.h" +#endif /* HAL_IPCC_MODULE_ENABLED */ + +#ifdef HAL_IRDA_MODULE_ENABLED +#include "stm32wbxx_hal_irda.h" +#endif /* HAL_IRDA_MODULE_ENABLED */ + +#ifdef HAL_IWDG_MODULE_ENABLED +#include "stm32wbxx_hal_iwdg.h" +#endif /* HAL_IWDG_MODULE_ENABLED */ + +#ifdef HAL_LCD_MODULE_ENABLED +#include "stm32wbxx_hal_lcd.h" +#endif /* HAL_LCD_MODULE_ENABLED */ + +#ifdef HAL_LPTIM_MODULE_ENABLED +#include "stm32wbxx_hal_lptim.h" +#endif /* HAL_LPTIM_MODULE_ENABLED */ + +#ifdef HAL_PCD_MODULE_ENABLED +#include "stm32wbxx_hal_pcd.h" +#endif /* HAL_PCD_MODULE_ENABLED */ + +#ifdef HAL_PKA_MODULE_ENABLED +#include "stm32wbxx_hal_pka.h" +#endif /* HAL_PKA_MODULE_ENABLED */ + +#ifdef HAL_PWR_MODULE_ENABLED +#include "stm32wbxx_hal_pwr.h" +#endif /* HAL_PWR_MODULE_ENABLED */ + +#ifdef HAL_QSPI_MODULE_ENABLED +#include "stm32wbxx_hal_qspi.h" +#endif /* HAL_QSPI_MODULE_ENABLED */ + +#ifdef HAL_RCC_MODULE_ENABLED +#include "stm32wbxx_hal_rcc.h" +#endif /* HAL_RCC_MODULE_ENABLED */ + +#ifdef HAL_RNG_MODULE_ENABLED +#include "stm32wbxx_hal_rng.h" +#endif /* HAL_RNG_MODULE_ENABLED */ + +#ifdef HAL_RTC_MODULE_ENABLED +#include "stm32wbxx_hal_rtc.h" +#endif /* HAL_RTC_MODULE_ENABLED */ + +#ifdef HAL_SAI_MODULE_ENABLED +#include "stm32wbxx_hal_sai.h" +#endif /* HAL_SAI_MODULE_ENABLED */ + +#ifdef HAL_SMARTCARD_MODULE_ENABLED +#include "stm32wbxx_hal_smartcard.h" +#endif /* HAL_SMARTCARD_MODULE_ENABLED */ + +#ifdef HAL_SMBUS_MODULE_ENABLED +#include "stm32wbxx_hal_smbus.h" +#endif /* HAL_SMBUS_MODULE_ENABLED */ + +#ifdef HAL_SPI_MODULE_ENABLED +#include "stm32wbxx_hal_spi.h" +#endif /* HAL_SPI_MODULE_ENABLED */ + +#ifdef HAL_TIM_MODULE_ENABLED +#include "stm32wbxx_hal_tim.h" +#endif /* HAL_TIM_MODULE_ENABLED */ + +#ifdef HAL_TSC_MODULE_ENABLED +#include "stm32wbxx_hal_tsc.h" +#endif /* HAL_TSC_MODULE_ENABLED */ + +#ifdef HAL_UART_MODULE_ENABLED +#include "stm32wbxx_hal_uart.h" +#endif /* HAL_UART_MODULE_ENABLED */ + +#ifdef HAL_USART_MODULE_ENABLED +#include "stm32wbxx_hal_usart.h" +#endif /* HAL_USART_MODULE_ENABLED */ + +#ifdef HAL_WWDG_MODULE_ENABLED +#include "stm32wbxx_hal_wwdg.h" +#endif /* HAL_WWDG_MODULE_ENABLED */ + +/* Exported macro ------------------------------------------------------------*/ +#ifdef USE_FULL_ASSERT +/** + * @brief The assert_param macro is used for function's parameters check. + * @param expr If expr is false, it calls assert_failed function + * which reports the name of the source file and the source + * line number of the call that failed. + * If expr is true, it returns no value. + * @retval None + */ +#define assert_param(expr) ((expr) ? (void) 0U : assert_failed((uint8_t *) __FILE__, __LINE__)) +/* Exported functions ------------------------------------------------------- */ +void assert_failed(uint8_t * file, uint32_t line); +#else +#define assert_param(expr) ((void) 0U) +#endif /* USE_FULL_ASSERT */ + +#ifdef __cplusplus +} +#endif + +#endif /* __STM32WBxx_HAL_CONF_H */ diff --git a/examples/platform/stm32/common/STM32WB5MM-DK/Inc/stm32wbxx_it.h b/examples/platform/stm32/common/STM32WB5MM-DK/Inc/stm32wbxx_it.h new file mode 100644 index 00000000000000..fbba7c4af75667 --- /dev/null +++ b/examples/platform/stm32/common/STM32WB5MM-DK/Inc/stm32wbxx_it.h @@ -0,0 +1,59 @@ +/** + ****************************************************************************** + * @file stm32wbxx_it.h + * @author MCD Application Team + * @brief This file contains the headers of the interrupt handlers. + ****************************************************************************** + * @attention + * + * Copyright (c) 2019-2021 STMicroelectronics. + * All rights reserved. + * + * This software is licensed under terms that can be found in the LICENSE file + * in the root directory of this software component. + * If no LICENSE file comes with this software, it is provided AS-IS. + * + ****************************************************************************** + */ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef __STM32WBxx_IT_H +#define __STM32WBxx_IT_H + +#ifdef __cplusplus +extern "C" { +#endif + +/* Includes ------------------------------------------------------------------*/ +/* Exported types ------------------------------------------------------------*/ +/* Exported constants --------------------------------------------------------*/ +/* Exported macro ------------------------------------------------------------*/ +/* Exported functions ------------------------------------------------------- */ + +void NMI_Handler(void); +void HardFault_Handler(void); +void MemManage_Handler(void); +void BusFault_Handler(void); +void UsageFault_Handler(void); +void SVC_Handler(void); +void DebugMon_Handler(void); +void PendSV_Handler(void); +void SysTick_Handler(void); +void IPCC_C1_RX_IRQHandler(void); +void IPCC_C1_TX_IRQHandler(void); +void EXTI4_IRQHandler(void); +void EXTI0_IRQHandler(void); +void EXTI1_IRQHandler(void); +void USART1_IRQHandler(void); +void DMA2_Channel4_IRQHandler(void); +void CFG_HW_USART1_DMA_TX_IRQHandler(void); +void RTC_WKUP_IRQHandler(void); +void LPUART1_IRQHandler(void); +void DMA1_Channel4_IRQHandler(void); +void QUADSPI_IRQHandler(void); + +#ifdef __cplusplus +} +#endif + +#endif /* __STM32WBxx_IT_H */ diff --git a/examples/platform/stm32/common/STM32WB5MM-DK/Inc/stm_logging.h b/examples/platform/stm32/common/STM32WB5MM-DK/Inc/stm_logging.h new file mode 100644 index 00000000000000..21400abd1df463 --- /dev/null +++ b/examples/platform/stm32/common/STM32WB5MM-DK/Inc/stm_logging.h @@ -0,0 +1,71 @@ +/* USER CODE BEGIN Header */ +/** + ****************************************************************************** + * File Name : stm_logging.h + * Description : Application header file for logging + ****************************************************************************** + * @attention + * + * Copyright (c) 2019-2021 STMicroelectronics. + * All rights reserved. + * + * This software is licensed under terms that can be found in the LICENSE file + * in the root directory of this software component. + * If no LICENSE file comes with this software, it is provided AS-IS. + * + ****************************************************************************** + */ +/* USER CODE END Header */ + +#ifndef STM_LOGGING_H_ +#define STM_LOGGING_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +#define LOG_LEVEL_NONE 0 /* None */ +#define LOG_LEVEL_CRIT 1U /* Critical */ +#define LOG_LEVEL_WARN 2U /* Warning */ +#define LOG_LEVEL_INFO 3U /* Info */ +#define LOG_LEVEL_DEBG 4U /* Debug */ + +#define APP_DBG_FULL(level, region, ...) \ + { \ + if (APPLI_PRINT_FILE_FUNC_LINE == 1U) \ + { \ + printf("\r\n[%s][%s][%d] ", DbgTraceGetFileName(__FILE__), __FUNCTION__, __LINE__); \ + } \ + logApplication(level, region, __VA_ARGS__); \ + } + +#define APP_DBG(...) \ + { \ + if (APPLI_PRINT_FILE_FUNC_LINE == 1U) \ + { \ + printf("\r\n[%s][%s][%d] ", DbgTraceGetFileName(__FILE__), __FUNCTION__, __LINE__); \ + } \ + logApplication(LOG_LEVEL_NONE, APPLI_LOG_REGION_GENERAL, __VA_ARGS__); \ + } + +/** + * This enumeration represents log regions. + * + */ +typedef enum +{ + APPLI_LOG_REGION_GENERAL = 1U, /* General */ + APPLI_LOG_REGION_OPENTHREAD_API = 2U, /* OpenThread API */ + APPLI_LOG_REGION_OT_API_LINK = 3U, /* OpenThread Link API */ + APPLI_LOG_REGION_OT_API_INSTANCE = 4U, /* OpenThread Instance API */ + APPLI_LOG_REGION_OT_API_MESSAGE = 5U /* OpenThread Message API */ +} appliLogRegion_t; + +typedef uint8_t appliLogLevel_t; + +void logApplication(appliLogLevel_t aLogLevel, appliLogRegion_t aLogRegion, const char * aFormat, ...); + +#ifdef __cplusplus +} /* extern "C" */ +#endif +#endif /* STM_LOGGING_H_ */ diff --git a/examples/platform/stm32/common/STM32WB5MM-DK/Inc/utilities_conf.h b/examples/platform/stm32/common/STM32WB5MM-DK/Inc/utilities_conf.h new file mode 100644 index 00000000000000..8fb35a2edc5d0f --- /dev/null +++ b/examples/platform/stm32/common/STM32WB5MM-DK/Inc/utilities_conf.h @@ -0,0 +1,66 @@ +/* USER CODE BEGIN Header */ +/** + ****************************************************************************** + * File Name : utilities_conf.h + * Description : Configuration file for STM32 Utilities. + * + ****************************************************************************** + * @attention + * + * Copyright (c) 2019-2021 STMicroelectronics. + * All rights reserved. + * + * This software is licensed under terms that can be found in the LICENSE file + * in the root directory of this software component. + * If no LICENSE file comes with this software, it is provided AS-IS. + * + ****************************************************************************** + */ +/* USER CODE END Header */ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef UTILITIES_CONF_H +#define UTILITIES_CONF_H + +#ifdef __cplusplus +extern "C" { +#endif + +#include "cmsis_compiler.h" +#include "string.h" + +/****************************************************************************** + * common + ******************************************************************************/ +#define UTILS_ENTER_CRITICAL_SECTION() \ + uint32_t primask_bit = __get_PRIMASK(); \ + __disable_irq() + +#define UTILS_EXIT_CRITICAL_SECTION() __set_PRIMASK(primask_bit) + +#define UTILS_MEMSET8(dest, value, size) memset(dest, value, size); + +/****************************************************************************** + * tiny low power manager + * (any macro that does not need to be modified can be removed) + ******************************************************************************/ +#define UTIL_LPM_INIT_CRITICAL_SECTION() +#define UTIL_LPM_ENTER_CRITICAL_SECTION() UTILS_ENTER_CRITICAL_SECTION() +#define UTIL_LPM_EXIT_CRITICAL_SECTION() UTILS_EXIT_CRITICAL_SECTION() + +/****************************************************************************** + * sequencer + * (any macro that does not need to be modified can be removed) + ******************************************************************************/ +#define UTIL_SEQ_INIT_CRITICAL_SECTION() +#define UTIL_SEQ_ENTER_CRITICAL_SECTION() UTILS_ENTER_CRITICAL_SECTION() +#define UTIL_SEQ_EXIT_CRITICAL_SECTION() UTILS_EXIT_CRITICAL_SECTION() +#define UTIL_SEQ_CONF_TASK_NBR (32) +#define UTIL_SEQ_CONF_PRIO_NBR (2) +#define UTIL_SEQ_MEMSET8(dest, value, size) UTILS_MEMSET8(dest, value, size) + +#ifdef __cplusplus +} +#endif + +#endif /*UTILITIES_CONF_H */ diff --git a/examples/platform/stm32/common/STM32WB5MM-DK/STM32_WPAN/App/app_ble.c b/examples/platform/stm32/common/STM32WB5MM-DK/STM32_WPAN/App/app_ble.c new file mode 100644 index 00000000000000..65b870a9ba1e5e --- /dev/null +++ b/examples/platform/stm32/common/STM32WB5MM-DK/STM32_WPAN/App/app_ble.c @@ -0,0 +1,958 @@ +/* USER CODE BEGIN Header */ +/** + ****************************************************************************** + * @file app_ble.c + * @author MCD Application Team + * @brief BLE Application + ****************************************************************************** + * @attention + * + * Copyright (c) 2019-2021 STMicroelectronics. + * All rights reserved. + * + * This software is licensed under terms that can be found in the LICENSE file + * in the root directory of this software component. + * If no LICENSE file comes with this software, it is provided AS-IS. + * + ****************************************************************************** + */ +/* USER CODE END Header */ + +/* Includes ------------------------------------------------------------------*/ +#include "app_common.h" + +#include "app_ble.h" +#include "ble.h" +#include "dbg_trace.h" +#include "tl.h" + +#include "app_matter.h" +#include "cmsis_os.h" +#include "otp.h" +#include "shci.h" +#include "stm32_lpm.h" +#include "timers.h" + +/* Private includes ----------------------------------------------------------*/ +/* USER CODE BEGIN Includes */ + +/* USER CODE END Includes */ + +/* Private typedef -----------------------------------------------------------*/ + +/** + * security parameters structure + */ +typedef struct _tSecurityParams +{ + /** + * IO capability of the device + */ + uint8_t ioCapability; + + /** + * Authentication requirement of the device + * Man In the Middle protection required? + */ + uint8_t mitm_mode; + + /** + * bonding mode of the device + */ + uint8_t bonding_mode; + + /** + * Flag to tell whether OOB data has + * to be used during the pairing process + */ + uint8_t OOB_Data_Present; + + /** + * OOB data to be used in the pairing process if + * OOB_Data_Present is set to TRUE + */ + uint8_t OOB_Data[16]; + + /** + * this variable indicates whether to use a fixed pin + * during the pairing process or a passkey has to be + * requested to the application during the pairing process + * 0 implies use fixed pin and 1 implies request for passkey + */ + uint8_t Use_Fixed_Pin; + + /** + * minimum encryption key size requirement + */ + uint8_t encryptionKeySizeMin; + + /** + * maximum encryption key size requirement + */ + uint8_t encryptionKeySizeMax; + + /** + * fixed pin to be used in the pairing process if + * Use_Fixed_Pin is set to 1 + */ + uint32_t Fixed_Pin; + + /** + * this flag indicates whether the host has to initiate + * the security, wait for pairing or does not have any security + * requirements.\n + * 0x00 : no security required + * 0x01 : host should initiate security by sending the slave security + * request command + * 0x02 : host need not send the clave security request but it + * has to wait for paiirng to complete before doing any other + * processing + */ + uint8_t initiateSecurity; +} tSecurityParams; + +/** + * global context + * contains the variables common to all + * services + */ +typedef struct _tBLEProfileGlobalContext +{ + + /** + * security requirements of the host + */ + tSecurityParams bleSecurityParam; + + /** + * gap service handle + */ + uint16_t gapServiceHandle; + + /** + * device name characteristic handle + */ + uint16_t devNameCharHandle; + + /** + * appearance characteristic handle + */ + uint16_t appearanceCharHandle; + + /** + * connection handle of the current active connection + * When not in connection, the handle is set to 0xFFFF + */ + uint16_t connectionHandle; + + /** + * length of the UUID list to be used while advertising + */ + uint8_t advtServUUIDlen; + + /** + * the UUID list to be used while advertising + */ + uint8_t advtServUUID[100]; + +} BleGlobalContext_t; + +typedef struct +{ + BleGlobalContext_t BleApplicationContext_legacy; + APP_BLE_ConnStatus_t Device_Connection_Status; + /** + * ID of the Advertising Timeout + */ + uint8_t Advertising_mgr_timer_Id; + + uint8_t SwitchOffGPIO_timer_Id; +} BleApplicationContext_t; +/* USER CODE BEGIN PTD */ + +/* USER CODE END PTD */ + +/* Private defines -----------------------------------------------------------*/ +#define APPBLE_GAP_DEVICE_NAME_LENGTH 7 +#define FAST_ADV_TIMEOUT (30 * 1000 * 1000 / CFG_TS_TICK_VAL) /**< 30s */ +#define INITIAL_ADV_TIMEOUT (60 * 1000 * 1000 / CFG_TS_TICK_VAL) /**< 60s */ + +#define BD_ADDR_SIZE_LOCAL 6 + +/* USER CODE BEGIN PD */ +#define LED_ON_TIMEOUT (0.005 * 1000 * 1000 / CFG_TS_TICK_VAL) /**< 5ms */ +/* USER CODE END PD */ + +/* Private macro -------------------------------------------------------------*/ +/* USER CODE BEGIN PM */ + +/* USER CODE END PM */ + +osMutexId_t MtxHciId; +osSemaphoreId_t SemHciId; +osThreadId_t HciUserEvtProcessId; +// FreeeRTOS sw timer +TimerHandle_t sbleWorkaroundAdvTimeoutTimer; + +const osThreadAttr_t HciUserEvtProcess_attr = { .name = CFG_HCI_USER_EVT_PROCESS_NAME, + .attr_bits = CFG_HCI_USER_EVT_PROCESS_ATTR_BITS, + .cb_mem = CFG_HCI_USER_EVT_PROCESS_CB_MEM, + .cb_size = CFG_HCI_USER_EVT_PROCESS_CB_SIZE, + .stack_mem = CFG_HCI_USER_EVT_PROCESS_STACK_MEM, + .priority = CFG_HCI_USER_EVT_PROCESS_PRIORITY, + .stack_size = CFG_HCI_USER_EVT_PROCESS_STACK_SIZE }; + +/* Private variables ---------------------------------------------------------*/ +PLACE_IN_SECTION("MB_MEM1") ALIGN(4) static TL_CmdPacket_t BleCmdBuffer; + +static const uint8_t M_bd_addr[BD_ADDR_SIZE_LOCAL] = { + (uint8_t)((CFG_ADV_BD_ADDRESS & 0x0000000000FF)), (uint8_t)((CFG_ADV_BD_ADDRESS & 0x00000000FF00) >> 8), + (uint8_t)((CFG_ADV_BD_ADDRESS & 0x000000FF0000) >> 16), (uint8_t)((CFG_ADV_BD_ADDRESS & 0x0000FF000000) >> 24), + (uint8_t)((CFG_ADV_BD_ADDRESS & 0x00FF00000000) >> 32), (uint8_t)((CFG_ADV_BD_ADDRESS & 0xFF0000000000) >> 40) +}; +static uint8_t bd_addr_udn[BD_ADDR_SIZE_LOCAL]; + +/** + * Identity root key used to derive LTK and CSRK + */ +static const uint8_t BLE_CFG_IR_VALUE[16] = CFG_BLE_IRK; + +/** + * Encryption root key used to derive LTK and CSRK + */ +static const uint8_t BLE_CFG_ER_VALUE[16] = CFG_BLE_ERK; + +PLACE_IN_SECTION("BLE_APP_CONTEXT") static BleApplicationContext_t BleApplicationContext; +PLACE_IN_SECTION("BLE_APP_CONTEXT") static uint16_t AdvIntervalMin, AdvIntervalMax; + +MATTER_App_Notification_evt_t handleNotification; + +#if L2CAP_REQUEST_NEW_CONN_PARAM != 0 +#define SIZE_TAB_CONN_INT 2 +float tab_conn_interval[SIZE_TAB_CONN_INT] = { 50, 1000 }; /* ms */ +uint8_t index_con_int, mutex; +#endif + +/** + * Advertising Data + */ +static const char local_name[] = { AD_TYPE_COMPLETE_LOCAL_NAME, 'S', 'T', 'D', 'K', 'M', 'A', 'T', 'T', 'E', 'R' }; +uint8_t manuf_data[15] = { + 0x02, 0x01, 0x06, 0x0B, 0x16, 0xF6, 0xFF, 0x00, 0x00, 0x0F, 0xF1, 0xFF, 0x04, 0x80, 0x00, +}; + +/* USER CODE BEGIN PV */ + +/* USER CODE END PV */ + +/* Private function prototypes -----------------------------------------------*/ +static void BLE_UserEvtRx(void * pPayload); +static void BLE_StatusNot(HCI_TL_CmdStatus_t status); +static void Ble_Tl_Init(void); +static void Ble_Hci_Gap_Gatt_Init(void); +static const uint8_t * BleGetBdAddress(void); +static void Switch_OFF_GPIO(void); +#if (L2CAP_REQUEST_NEW_CONN_PARAM != 0) +static void BLE_SVC_L2CAP_Conn_Update(uint16_t Connection_Handle); +#endif +static void HciUserEvtProcess(void * argument); +void BleAdvWorkaroundTimeoutHandler(TimerHandle_t xTimer); +/* USER CODE BEGIN PFP */ + +/* USER CODE END PFP */ + +/* Functions Definition ------------------------------------------------------*/ +void APP_BLE_Init_Dyn_1(void) +{ + /* USER CODE BEGIN APP_BLE_Init_1 */ + + /* USER CODE END APP_BLE_Init_1 */ + SHCI_C2_Ble_Init_Cmd_Packet_t ble_init_cmd_packet = { { { 0, 0, 0 } }, /**< Header unused */ + { 0, /** pBleBufferAddress not used */ + 0, /** BleBufferSize not used */ + CFG_BLE_NUM_GATT_ATTRIBUTES, + CFG_BLE_NUM_GATT_SERVICES, + CFG_BLE_ATT_VALUE_ARRAY_SIZE, + CFG_BLE_NUM_LINK, + CFG_BLE_DATA_LENGTH_EXTENSION, + CFG_BLE_PREPARE_WRITE_LIST_SIZE, + CFG_BLE_MBLOCK_COUNT, + CFG_BLE_MAX_ATT_MTU, + CFG_BLE_SLAVE_SCA, + CFG_BLE_MASTER_SCA, + CFG_BLE_LSE_SOURCE, + CFG_BLE_MAX_CONN_EVENT_LENGTH, + CFG_BLE_HSE_STARTUP_TIME, + CFG_BLE_VITERBI_MODE, + CFG_BLE_OPTIONS, + 0, + CFG_BLE_MAX_COC_INITIATOR_NBR, + CFG_BLE_MIN_TX_POWER, + CFG_BLE_MAX_TX_POWER } }; + + /** + * Initialize Ble Transport Layer + */ + Ble_Tl_Init(); + + /** + * Do not allow standby in the application + */ + UTIL_LPM_SetOffMode(1 << CFG_LPM_APP_BLE, UTIL_LPM_DISABLE); + + MtxHciId = osMutexNew(NULL); + SemHciId = osSemaphoreNew(1, 0, NULL); /*< Create the semaphore and make it busy at initialization */ + /** + * Register the hci transport layer to handle BLE User Asynchronous Events + */ + HciUserEvtProcessId = osThreadNew(HciUserEvtProcess, NULL, &HciUserEvtProcess_attr); + + /** + * Starts the BLE Stack on CPU2 + */ + SHCI_C2_BLE_Init(&ble_init_cmd_packet); + + /** + * Initialization of HCI & GATT & GAP layer + */ + Ble_Hci_Gap_Gatt_Init(); + + /** + * Initialization of the BLE Services + */ + SVCCTL_Init(); + + /** + * Initialization of the BLE App Context + */ + BleApplicationContext.Device_Connection_Status = APP_BLE_IDLE; + BleApplicationContext.BleApplicationContext_legacy.connectionHandle = 0xFFFF; + /** + * Initialization of ADV - Ad Manufacturer Element - Support OTA Bit Mask + */ + +#if (RADIO_ACTIVITY_EVENT != 0) + aci_hal_set_radio_activity_mask(0x0006); +#endif + +#if (L2CAP_REQUEST_NEW_CONN_PARAM != 0) + index_con_int = 0; + mutex = 1; +#endif + /** + * Initialize P2P Server Application + */ + APP_MATTER_Init(); + + /** + * Create timer to handle the Led Switch OFF + */ + HW_TS_Create(CFG_TIM_PROC_ID_ISR, &(BleApplicationContext.SwitchOffGPIO_timer_Id), hw_ts_SingleShot, Switch_OFF_GPIO); +} + +void APP_BLE_Init_Dyn_2(void) +{ + /** + * Make device discoverable + */ + BleApplicationContext.BleApplicationContext_legacy.advtServUUID[0] = NULL; + BleApplicationContext.BleApplicationContext_legacy.advtServUUIDlen = 0; + /* Initialize intervals for reconnexion without intervals update */ + AdvIntervalMin = CFG_FAST_CONN_ADV_INTERVAL_MIN; + AdvIntervalMax = CFG_FAST_CONN_ADV_INTERVAL_MAX; + + /* USER CODE BEGIN APP_BLE_Init_2 */ + + /* USER CODE END APP_BLE_Init_2 */ +} + +void APP_BLE_Init_Dyn_3(void) +{ + + sbleWorkaroundAdvTimeoutTimer = xTimerCreate("BleAdvWorkaroundTimer", // Just a text name, not used by the RTOS kernel + pdMS_TO_TICKS(2000), // == default timer period (mS) + 0, // no timer reload (==one-shot) + NULL, // init timer id = ble obj context + BleAdvWorkaroundTimeoutHandler // timer callback handler + ); + if (xTimerStart(sbleWorkaroundAdvTimeoutTimer, 0) != pdPASS) + { + /* The timer could not be set into the Active + state. */ + } + APP_BLE_Adv_Request(APP_BLE_FAST_ADV); +} + +SVCCTL_UserEvtFlowStatus_t SVCCTL_App_Notification(void * pckt) +{ + hci_event_pckt * event_pckt; + evt_le_meta_event * meta_evt; + event_pckt = (hci_event_pckt *) ((hci_uart_pckt *) pckt)->data; + + switch (event_pckt->evt) + { + case HCI_DISCONNECTION_COMPLETE_EVT_CODE: { + hci_disconnection_complete_event_rp0 * disconnection_complete_event; + disconnection_complete_event = (hci_disconnection_complete_event_rp0 *) event_pckt->data; + + if (disconnection_complete_event->Connection_Handle == BleApplicationContext.BleApplicationContext_legacy.connectionHandle) + { + BleApplicationContext.BleApplicationContext_legacy.connectionHandle = 0; + BleApplicationContext.Device_Connection_Status = APP_BLE_IDLE; + APP_DBG_MSG("\r\n\r** DISCONNECTION EVENT WITH CLIENT \n"); + } + /* + * SPECIFIC to P2P Server APP + */ + handleNotification.P2P_Evt_Opcode = MATTER_STM_PEER_DISCON_HANDLE_EVT; + handleNotification.ConnectionHandle = disconnection_complete_event->Connection_Handle; + APP_MATTER_Notification(&handleNotification); + + /* USER CODE BEGIN EVT_DISCONN_COMPLETE */ + + /* USER CODE END EVT_DISCONN_COMPLETE */ + } + + break; /* EVT_DISCONN_COMPLETE */ + + case HCI_LE_META_EVT_CODE: { + meta_evt = (evt_le_meta_event *) event_pckt->data; + /* USER CODE BEGIN EVT_LE_META_EVENT */ + + /* USER CODE END EVT_LE_META_EVENT */ + switch (meta_evt->subevent) + { + case HCI_LE_CONNECTION_UPDATE_COMPLETE_SUBEVT_CODE: + APP_DBG_MSG("\r\n\r** CONNECTION UPDATE EVENT WITH CLIENT \n"); + + /** + * The connection is done, there is no need anymore to schedule the LP ADV + */ + break; + case HCI_LE_CONNECTION_COMPLETE_SUBEVT_CODE: { + hci_le_connection_complete_event_rp0 * connection_complete_event; + + /** + * The connection is done, there is no need anymore to schedule the LP ADV + */ + connection_complete_event = (hci_le_connection_complete_event_rp0 *) meta_evt->data; + + // HW_TS_Stop(BleApplicationContext.Advertising_mgr_timer_Id); + + APP_DBG_MSG("EVT_LE_CONN_COMPLETE for connection handle 0x%x\n", connection_complete_event->Connection_Handle); + + if (BleApplicationContext.Device_Connection_Status == APP_BLE_LP_CONNECTING) + { + /* Connection as client */ + BleApplicationContext.Device_Connection_Status = APP_BLE_CONNECTED_CLIENT; + } + else + { + /* Connection as server */ + BleApplicationContext.Device_Connection_Status = APP_BLE_CONNECTED_SERVER; + } + + BleApplicationContext.BleApplicationContext_legacy.connectionHandle = connection_complete_event->Connection_Handle; + + /** SPECIFIC to P2P Server APP*/ + hci_le_set_data_length(BleApplicationContext.BleApplicationContext_legacy.connectionHandle, 251, 2120); + handleNotification.P2P_Evt_Opcode = MATTER_STM_PEER_CONN_HANDLE_EVT; + handleNotification.ConnectionHandle = BleApplicationContext.BleApplicationContext_legacy.connectionHandle; + APP_MATTER_Notification(&handleNotification); + /**/ + /* USER CODE END HCI_EVT_LE_CONN_COMPLETE */ + } + break; /* HCI_EVT_LE_CONN_COMPLETE */ + + default: + /* USER CODE BEGIN SUBEVENT_DEFAULT */ + /* USER CODE END SUBEVENT_DEFAULT */ + break; + } + } + break; /* HCI_EVT_LE_META_EVENT */ + default: + /* USER CODE BEGIN ECODE_DEFAULT*/ + + /* USER CODE END ECODE_DEFAULT*/ + break; + } + + return (SVCCTL_UserEvtFlowEnable); +} + +APP_BLE_ConnStatus_t APP_BLE_Get_Server_Connection_Status(void) +{ + return BleApplicationContext.Device_Connection_Status; +} + +void APP_BLE_Key_Button2_Action(void) +{ +#if (L2CAP_REQUEST_NEW_CONN_PARAM != 0) + if (BleApplicationContext.Device_Connection_Status != APP_BLE_FAST_ADV && + BleApplicationContext.Device_Connection_Status != APP_BLE_IDLE) + { + BLE_SVC_L2CAP_Conn_Update(BleApplicationContext.BleApplicationContext_legacy.connectionHandle); + } + return; +#endif +} + +void APP_BLE_Key_Button3_Action(void) {} + +void APP_BLE_Stop(void) +{ + /* Stop Advertising Timer */ + // HW_TS_Stop(BleApplicationContext.Advertising_mgr_timer_Id); + // HW_TS_Delete(BleApplicationContext.Advertising_mgr_timer_Id); + /* BLE STOP Procedure */ + aci_hal_stack_reset(); +} +/* USER CODE END FD*/ +/************************************************************* + * + * LOCAL FUNCTIONS + * + *************************************************************/ +static void Ble_Tl_Init(void) +{ + HCI_TL_HciInitConf_t Hci_Tl_Init_Conf; + + Hci_Tl_Init_Conf.p_cmdbuffer = (uint8_t *) &BleCmdBuffer; + Hci_Tl_Init_Conf.StatusNotCallBack = BLE_StatusNot; + hci_init(BLE_UserEvtRx, (void *) &Hci_Tl_Init_Conf); + + return; +} + +static void Ble_Hci_Gap_Gatt_Init(void) +{ + + uint8_t role; + uint8_t index; + uint16_t gap_service_handle, gap_dev_name_char_handle, gap_appearance_char_handle; + const uint8_t * bd_addr; + uint32_t srd_bd_addr[2]; + uint16_t appearance[1] = { BLE_CFG_GAP_APPEARANCE }; + + /** + * Initialize HCI layer + */ + /*HCI Reset to synchronise BLE Stack*/ + hci_reset(); + + /** + * Write the BD Address + */ + + bd_addr = BleGetBdAddress(); + aci_hal_write_config_data(CONFIG_DATA_PUBADDR_OFFSET, CONFIG_DATA_PUBADDR_LEN, (uint8_t *) bd_addr); + + /* BLE MAC in ADV Packet */ + // manuf_data[ sizeof(manuf_data)-6] = bd_addr[5]; + // manuf_data[ sizeof(manuf_data)-5] = bd_addr[4]; + // manuf_data[ sizeof(manuf_data)-4] = bd_addr[3]; + // manuf_data[ sizeof(manuf_data)-3] = bd_addr[2]; + // manuf_data[ sizeof(manuf_data)-2] = bd_addr[1]; + // manuf_data[ sizeof(manuf_data)-1] = bd_addr[0]; + // + /** + * Static random Address + * The two upper bits shall be set to 1 + * The lowest 32bits is read from the UDN to differentiate between devices + * The RNG may be used to provide a random number on each power on + */ + srd_bd_addr[1] = 0x0000ED6E; + srd_bd_addr[0] = LL_FLASH_GetUDN(); + aci_hal_write_config_data(CONFIG_DATA_RANDOM_ADDRESS_OFFSET, CONFIG_DATA_RANDOM_ADDRESS_LEN, (uint8_t *) srd_bd_addr); + + /** + * Write Identity root key used to derive LTK and CSRK + */ + aci_hal_write_config_data(CONFIG_DATA_IR_OFFSET, CONFIG_DATA_IR_LEN, (uint8_t *) BLE_CFG_IR_VALUE); + + /** + * Write Encryption root key used to derive LTK and CSRK + */ + aci_hal_write_config_data(CONFIG_DATA_ER_OFFSET, CONFIG_DATA_ER_LEN, (uint8_t *) BLE_CFG_ER_VALUE); + + /** + * Set TX Power to 0dBm. + */ + aci_hal_set_tx_power_level(1, CFG_TX_POWER); + + /** + * Initialize GATT interface + */ + aci_gatt_init(); + + /** + * Initialize GAP interface + */ + role = 0; + +#if (BLE_CFG_PERIPHERAL == 1) + role |= GAP_PERIPHERAL_ROLE; +#endif + +#if (BLE_CFG_CENTRAL == 1) + role |= GAP_CENTRAL_ROLE; +#endif + + if (role > 0) + { + const char * name = "STM32WB"; + aci_gap_init(role, 0, APPBLE_GAP_DEVICE_NAME_LENGTH, &gap_service_handle, &gap_dev_name_char_handle, + &gap_appearance_char_handle); + + if (aci_gatt_update_char_value(gap_service_handle, gap_dev_name_char_handle, 0, strlen(name), (uint8_t *) name)) + { + BLE_DBG_SVCCTL_MSG("Device Name aci_gatt_update_char_value failed.\n"); + } + } + + if (aci_gatt_update_char_value(gap_service_handle, gap_appearance_char_handle, 0, 2, (uint8_t *) &appearance)) + { + BLE_DBG_SVCCTL_MSG("Appearance aci_gatt_update_char_value failed.\n"); + } + /** + * Initialize Default PHY + */ + hci_le_set_default_phy(ALL_PHYS_PREFERENCE, TX_2M_PREFERRED, RX_2M_PREFERRED); + + /** + * Initialize IO capability + */ + BleApplicationContext.BleApplicationContext_legacy.bleSecurityParam.ioCapability = CFG_IO_CAPABILITY; + aci_gap_set_io_capability(BleApplicationContext.BleApplicationContext_legacy.bleSecurityParam.ioCapability); + + /** + * Initialize authentication + */ + BleApplicationContext.BleApplicationContext_legacy.bleSecurityParam.mitm_mode = CFG_MITM_PROTECTION; + BleApplicationContext.BleApplicationContext_legacy.bleSecurityParam.OOB_Data_Present = 0; + BleApplicationContext.BleApplicationContext_legacy.bleSecurityParam.encryptionKeySizeMin = 8; + BleApplicationContext.BleApplicationContext_legacy.bleSecurityParam.encryptionKeySizeMax = 16; + BleApplicationContext.BleApplicationContext_legacy.bleSecurityParam.Use_Fixed_Pin = 1; + BleApplicationContext.BleApplicationContext_legacy.bleSecurityParam.Fixed_Pin = 111111; + BleApplicationContext.BleApplicationContext_legacy.bleSecurityParam.bonding_mode = 1; + for (index = 0; index < 16; index++) + { + BleApplicationContext.BleApplicationContext_legacy.bleSecurityParam.OOB_Data[index] = (uint8_t) index; + } + + aci_gap_set_authentication_requirement(BleApplicationContext.BleApplicationContext_legacy.bleSecurityParam.bonding_mode, + BleApplicationContext.BleApplicationContext_legacy.bleSecurityParam.mitm_mode, 1, 0, + BleApplicationContext.BleApplicationContext_legacy.bleSecurityParam.encryptionKeySizeMin, + BleApplicationContext.BleApplicationContext_legacy.bleSecurityParam.encryptionKeySizeMax, + BleApplicationContext.BleApplicationContext_legacy.bleSecurityParam.Use_Fixed_Pin, + BleApplicationContext.BleApplicationContext_legacy.bleSecurityParam.Fixed_Pin, 0); + + /** + * Initialize whitelist + */ + if (BleApplicationContext.BleApplicationContext_legacy.bleSecurityParam.bonding_mode) + { + aci_gap_configure_whitelist(); + } +} + +void APP_BLE_Adv_Request(APP_BLE_ConnStatus_t New_Status) +{ + tBleStatus ret = BLE_STATUS_INVALID_PARAMS; + uint16_t Min_Inter, Max_Inter; + + if (New_Status == APP_BLE_FAST_ADV) + { + Min_Inter = AdvIntervalMin; + Max_Inter = AdvIntervalMax; + } + else + { + Min_Inter = CFG_LP_CONN_ADV_INTERVAL_MIN; + Max_Inter = CFG_LP_CONN_ADV_INTERVAL_MAX; + } + + APP_DBG_MSG("First index in %d state \n", BleApplicationContext.Device_Connection_Status); + + if ((New_Status == APP_BLE_LP_ADV) && + ((BleApplicationContext.Device_Connection_Status == APP_BLE_FAST_ADV) || + (BleApplicationContext.Device_Connection_Status == APP_BLE_LP_ADV))) + { + /* Connection in ADVERTISE mode have to stop the current advertising */ + ret = aci_gap_set_non_discoverable(); + if (ret == BLE_STATUS_SUCCESS) + { + APP_DBG_MSG("Successfully Stopped Advertising"); + } + else + { + APP_DBG_MSG("Stop Advertising Failed , result: %d \n", ret); + } + } + + BleApplicationContext.Device_Connection_Status = New_Status; + /* Start Fast or Low Power Advertising */ + ret = aci_gap_set_discoverable(ADV_IND, Min_Inter, Max_Inter, GAP_PUBLIC_ADDR, NO_WHITE_LIST_USE, /* use white list */ + sizeof(local_name), (uint8_t *) &local_name, + BleApplicationContext.BleApplicationContext_legacy.advtServUUIDlen, + BleApplicationContext.BleApplicationContext_legacy.advtServUUID, 0, 0); + /* Update Advertising data */ + ret = aci_gap_update_adv_data(sizeof(manuf_data), (uint8_t *) manuf_data); + + APP_DBG_MSG("check set discoverable , result: %d \n", ret); + if (ret == BLE_STATUS_SUCCESS) + { + if (New_Status == APP_BLE_FAST_ADV) + { + APP_DBG_MSG("Successfully Start Fast Advertising \n"); + } + else + { + APP_DBG_MSG("Successfully Start Low Power Advertising \n"); + } + } + else + { + if (New_Status == APP_BLE_FAST_ADV) + { + APP_DBG_MSG("Start Fast Advertising Failed , result: %d \n", ret); + } + else + { + APP_DBG_MSG("Start Low Power Advertising Failed , result: %d \n", ret); + } + } + + return; +} + +const uint8_t * BleGetBdAddress(void) +{ + uint8_t * otp_addr; + const uint8_t * bd_addr; + uint32_t udn; + uint32_t company_id; + uint32_t device_id; + + udn = LL_FLASH_GetUDN(); + + if (udn != 0xFFFFFFFF) + { + company_id = LL_FLASH_GetSTCompanyID(); + device_id = LL_FLASH_GetDeviceID(); + + /** + * Public Address with the ST company ID + * bit[47:24] : 24bits (OUI) equal to the company ID + * bit[23:16] : Device ID. + * bit[15:0] : The last 16bits from the UDN + * Note: In order to use the Public Address in a final product, a dedicated + * 24bits company ID (OUI) shall be bought. + */ + bd_addr_udn[0] = (uint8_t)(udn & 0x000000FF); + bd_addr_udn[1] = (uint8_t)((udn & 0x0000FF00) >> 8); + bd_addr_udn[2] = (uint8_t) device_id; + bd_addr_udn[3] = (uint8_t)(company_id & 0x000000FF); + ; + bd_addr_udn[4] = (uint8_t)((company_id & 0x0000FF00) >> 8); + bd_addr_udn[5] = (uint8_t)((company_id & 0x00FF0000) >> 16); + + bd_addr = (const uint8_t *) bd_addr_udn; + } + else + { + otp_addr = OTP_Read(0); + if (otp_addr) + { + bd_addr = ((OTP_ID0_t *) otp_addr)->bd_address; + } + else + { + bd_addr = M_bd_addr; + } + } + + return bd_addr; +} + +/* USER CODE BEGIN FD_LOCAL_FUNCTION */ + +/* USER CODE END FD_LOCAL_FUNCTION */ + +/************************************************************* + * + *SPECIFIC FUNCTIONS FOR P2P SERVER + * + *************************************************************/ +void BleAdvWorkaroundTimeoutHandler(TimerHandle_t xTimer) +{ + APP_BLE_Adv_Cancel(); +} + +void APP_BLE_Adv_Cancel(void) +{ + /* USER CODE BEGIN Adv_Cancel_1 */ + // BSP_LED_Off(LED_GREEN); + /* USER CODE END Adv_Cancel_1 */ + + if (BleApplicationContext.Device_Connection_Status != APP_BLE_CONNECTED_SERVER) + + { + + tBleStatus result = 0x00; + + result = aci_gap_set_non_discoverable(); + + BleApplicationContext.Device_Connection_Status = APP_BLE_IDLE; + if (result == BLE_STATUS_SUCCESS) + { + APP_DBG_MSG(" \r\n\r"); + APP_DBG_MSG("** STOP ADVERTISING ** \r\n\r"); + } + else + { + APP_DBG_MSG("** STOP ADVERTISING ** Failed \r\n\r"); + } + } + + /* USER CODE BEGIN Adv_Cancel_2 */ + + /* USER CODE END Adv_Cancel_2 */ + return; +} + +static void Switch_OFF_GPIO() +{ + /* USER CODE BEGIN Switch_OFF_GPIO */ + // BSP_LED_Off(LED_GREEN); + /* USER CODE END Switch_OFF_GPIO */ +} + +#if (L2CAP_REQUEST_NEW_CONN_PARAM != 0) +void BLE_SVC_L2CAP_Conn_Update(uint16_t Connection_Handle) +{ + /* USER CODE BEGIN BLE_SVC_L2CAP_Conn_Update_1 */ + + /* USER CODE END BLE_SVC_L2CAP_Conn_Update_1 */ + if (mutex == 1) + { + mutex = 0; + index_con_int = (index_con_int + 1) % SIZE_TAB_CONN_INT; + uint16_t interval_min = CONN_P(tab_conn_interval[index_con_int]); + uint16_t interval_max = CONN_P(tab_conn_interval[index_con_int]); + uint16_t slave_latency = L2CAP_SLAVE_LATENCY; + uint16_t timeout_multiplier = L2CAP_TIMEOUT_MULTIPLIER; + tBleStatus result; + + result = aci_l2cap_connection_parameter_update_req(BleApplicationContext.BleApplicationContext_legacy.connectionHandle, + interval_min, interval_max, slave_latency, timeout_multiplier); + if (result == BLE_STATUS_SUCCESS) + { + APP_DBG_MSG("BLE_SVC_L2CAP_Conn_Update(), Successfully \r\n\r"); + } + else + { + APP_DBG_MSG("BLE_SVC_L2CAP_Conn_Update(), Failed \r\n\r"); + } + } + /* USER CODE BEGIN BLE_SVC_L2CAP_Conn_Update_2 */ + + /* USER CODE END BLE_SVC_L2CAP_Conn_Update_2 */ + return; +} +#endif + +/* USER CODE BEGIN FD_SPECIFIC_FUNCTIONS */ + +/* USER CODE END FD_SPECIFIC_FUNCTIONS */ +/************************************************************* + * + * WRAP FUNCTIONS + * + *************************************************************/ + +static void HciUserEvtProcess(void * argument) +{ + UNUSED(argument); + + for (;;) + { + osThreadFlagsWait(1, osFlagsWaitAny, osWaitForever); + hci_user_evt_proc(); + } +} + +void hci_notify_asynch_evt(void * pdata) +{ + osThreadFlagsSet(HciUserEvtProcessId, 1); + return; +} + +void hci_cmd_resp_release(uint32_t flag) +{ + osSemaphoreRelease(SemHciId); + return; +} + +void hci_cmd_resp_wait(uint32_t timeout) +{ + osSemaphoreAcquire(SemHciId, osWaitForever); + return; +} + +static void BLE_UserEvtRx(void * pPayload) +{ + SVCCTL_UserEvtFlowStatus_t svctl_return_status; + tHCI_UserEvtRxParam * pParam; + + pParam = (tHCI_UserEvtRxParam *) pPayload; + + svctl_return_status = SVCCTL_UserEvtRx((void *) &(pParam->pckt->evtserial)); + if (svctl_return_status != SVCCTL_UserEvtFlowDisable) + { + pParam->status = HCI_TL_UserEventFlow_Enable; + } + else + { + pParam->status = HCI_TL_UserEventFlow_Disable; + } +} + +static void BLE_StatusNot(HCI_TL_CmdStatus_t status) +{ + switch (status) + { + case HCI_TL_CmdBusy: + /** + * All tasks that may send an aci/hci commands shall be listed here + * This is to prevent a new command is sent while one is already pending + */ + osMutexAcquire(MtxHciId, osWaitForever); + + break; + + case HCI_TL_CmdAvailable: + /** + * All tasks that may send an aci/hci commands shall be listed here + * This is to prevent a new command is sent while one is already pending + */ + osMutexRelease(MtxHciId); + + break; + + default: + break; + } + return; +} + +void SVCCTL_ResumeUserEventFlow(void) +{ + hci_resume_flow(); + return; +} + +/* USER CODE BEGIN FD_WRAP_FUNCTIONS */ + +/* USER CODE END FD_WRAP_FUNCTIONS */ diff --git a/examples/platform/stm32/common/STM32WB5MM-DK/STM32_WPAN/App/app_ble.h b/examples/platform/stm32/common/STM32WB5MM-DK/STM32_WPAN/App/app_ble.h new file mode 100644 index 00000000000000..cb0b80a25628f6 --- /dev/null +++ b/examples/platform/stm32/common/STM32WB5MM-DK/STM32_WPAN/App/app_ble.h @@ -0,0 +1,88 @@ +/* USER CODE BEGIN Header */ +/** + ****************************************************************************** + * @file app_ble.h + * @author MCD Application Team + * @brief Header for ble application + ****************************************************************************** + * @attention + * + * Copyright (c) 2019-2021 STMicroelectronics. + * All rights reserved. + * + * This software is licensed under terms that can be found in the LICENSE file + * in the root directory of this software component. + * If no LICENSE file comes with this software, it is provided AS-IS. + * + ****************************************************************************** + */ +/* USER CODE END Header */ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef APP_BLE_H +#define APP_BLE_H + +#ifdef __cplusplus +extern "C" { +#endif + +/* Includes ------------------------------------------------------------------*/ +#include "hci_tl.h" + +/* Private includes ----------------------------------------------------------*/ +/* USER CODE BEGIN Includes */ + +/* USER CODE END Includes */ + +/* Exported types ------------------------------------------------------------*/ +typedef enum +{ + APP_BLE_IDLE, + APP_BLE_FAST_ADV, + APP_BLE_LP_ADV, + APP_BLE_SCAN, + APP_BLE_LP_CONNECTING, + APP_BLE_CONNECTED_SERVER, + APP_BLE_CONNECTED_CLIENT +} APP_BLE_ConnStatus_t; + +/* USER CODE BEGIN ET */ + +/* USER CODE END ET */ + +/* Exported constants --------------------------------------------------------*/ +/* USER CODE BEGIN EC */ + +/* USER CODE END EC */ + +/* External variables --------------------------------------------------------*/ +/* USER CODE BEGIN EV */ + +/* USER CODE END EV */ + +/* Exported macro ------------------------------------------------------------*/ +/* USER CODE BEGIN EM */ + +/* USER CODE END EM */ + +/* Exported functions ---------------------------------------------*/ +void APP_BLE_Init_Dyn_1(void); +void APP_BLE_Init_Dyn_2(void); +void APP_BLE_Init_Dyn_3(void); + +APP_BLE_ConnStatus_t APP_BLE_Get_Server_Connection_Status(void); + +/* USER CODE BEGIN EF */ +void APP_BLE_Key_Button1_Action(void); +void APP_BLE_Key_Button2_Action(void); +void APP_BLE_Key_Button3_Action(void); +void APP_BLE_Stop(void); +void APP_BLE_Adv_Request(APP_BLE_ConnStatus_t New_Status); +void APP_BLE_Adv_Cancel(void); +/* USER CODE END EF */ + +#ifdef __cplusplus +} +#endif + +#endif /*APP_BLE_H */ diff --git a/examples/platform/stm32/common/STM32WB5MM-DK/STM32_WPAN/App/app_matter.c b/examples/platform/stm32/common/STM32WB5MM-DK/STM32_WPAN/App/app_matter.c new file mode 100644 index 00000000000000..49881b1bcfa2df --- /dev/null +++ b/examples/platform/stm32/common/STM32WB5MM-DK/STM32_WPAN/App/app_matter.c @@ -0,0 +1,236 @@ +/* USER CODE BEGIN Header */ +/** + ****************************************************************************** + * @file app_matter.c + * @author MCD Application Team + * @brief matter application to handle ble between matter api and stm32 world + ****************************************************************************** + * @attention + * + * Copyright (c) 2019-2021 STMicroelectronics. + * All rights reserved. + * + * This software is licensed under terms that can be found in the LICENSE file + * in the root directory of this software component. + * If no LICENSE file comes with this software, it is provided AS-IS. + * + ****************************************************************************** + */ +/* USER CODE END Header */ + +/* Includes ------------------------------------------------------------------*/ +#include "app_matter.h" +#include "app_common.h" +#include "app_conf.h" +#include "app_entry.h" +#include "ble.h" +#include "cmsis_os.h" +#include "custom_stm.h" +#include "dbg_trace.h" + +/* Private includes ----------------------------------------------------------*/ +/* USER CODE BEGIN Includes */ + +/* USER CODE END Includes */ + +/* Private typedef -----------------------------------------------------------*/ +/* USER CODE BEGIN PTD */ +typedef struct +{ + uint8_t Device_Led_Selection; + uint8_t Led1; +} P2P_LedCharValue_t; + +typedef struct +{ + uint8_t Device_Button_Selection; + uint8_t ButtonStatus; +} P2P_ButtonCharValue_t; + +typedef struct +{ + uint8_t Notification_Status; /* used to check if P2P Server is enabled to Notify */ + P2P_LedCharValue_t LedControl; + P2P_ButtonCharValue_t ButtonControl; + uint16_t ConnectionHandle; +} P2P_Server_App_Context_t; +/* USER CODE END PTD */ + +/* Private defines ------------------------------------------------------------*/ +/* USER CODE BEGIN PD */ + +/* USER CODE END PD */ + +/* Private macros -------------------------------------------------------------*/ +/* USER CODE BEGIN PM */ + +/* USER CODE END PM */ + +/* Private variables ---------------------------------------------------------*/ +/* USER CODE BEGIN PV */ +/** + * START of Section BLE_APP_CONTEXT + */ + +PLACE_IN_SECTION("BLE_APP_CONTEXT") static P2P_Server_App_Context_t P2P_Server_App_Context; + +BLEReceiveCallback BLEReceiveCb = NULL; +BLETXCharCCCDWriteCallback BLETXCharCCCDWriteCb = NULL; +BLEConnectionCallback BLEConnectionCb = NULL; +BLEDisconnectionCallback BLEDisconnectionCb = NULL; +BLEDAckCallback BLEAckCb = NULL; + +/** + * END of Section BLE_APP_CONTEXT + */ +/* USER CODE END PV */ + +/* Private function prototypes -----------------------------------------------*/ +/* USER CODE BEGIN PFP */ +/* USER CODE END PFP */ + +void APP_MATTER_BLE_Set_Receive_Callback(BLEReceiveCallback aCallback) +{ + BLEReceiveCb = aCallback; +} + +void APP_MATTER_BLE_Set_TXCharCCCDWrite_Callback(BLETXCharCCCDWriteCallback aCallback) +{ + BLETXCharCCCDWriteCb = aCallback; +} + +void APP_MATTER_BLE_Set_Connection_Callback(BLEConnectionCallback aCallback) +{ + BLEConnectionCb = aCallback; +} + +void APP_MATTER_BLE_Set_Disconnection_Callback(BLEDisconnectionCallback aCallback) +{ + BLEDisconnectionCb = aCallback; +} + +void APP_MATTER_BLE_Set_Ack_After_Indicate_Callback(BLEDAckCallback aCallback) +{ + BLEAckCb = aCallback; +} + +/* Functions Definition ------------------------------------------------------*/ +void APP_MATTER_Notification(MATTER_App_Notification_evt_t * pNotification) +{ + /* USER CODE BEGIN APP_MATTER_Notification */ + BLE_Matter_TXCharCCCD message; + /* USER CODE END APP_MATTER_Notification */ + switch (pNotification->P2P_Evt_Opcode) + { + /* USER CODE BEGIN APP_MATTER_Notification */ + /* USER CODE END APP_MATTER_Notification */ + + case MATTER_STM_PEER_CONN_HANDLE_EVT: + /* USER CODE BEGIN PEER_CONN_HANDLE_EVT */ + BLEConnectionCb(); + /* USER CODE END PEER_CONN_HANDLE_EVT */ + break; + + case MATTER_STM_PEER_DISCON_HANDLE_EVT: + /* USER CODE BEGIN PEER_DISCON_HANDLE_EVT */ + BLEDisconnectionCb(&pNotification->ConnectionHandle); + /* USER CODE END PEER_DISCON_HANDLE_EVT */ + break; + + case MATTER_STM_ACK_INDICATE_EVT: + /* USER CODE BEGIN PEER_DISCON_HANDLE_EVT */ + BLEAckCb(&pNotification->ConnectionHandle); + /* USER CODE END PEER_DISCON_HANDLE_EVT */ + break; + + case MATTER_STM_INDICATE_ENABLED_EVT: + /* USER CODE BEGIN P2PS_STM__NOTIFY_ENABLED_EVT */ + message.connid = pNotification->ConnectionHandle; + message.notif = 1; + P2P_Server_App_Context.Notification_Status = 1; + APP_DBG_MSG("-- Matter APPLICATION SERVER : INDICATE ENABLED\n"); + APP_DBG_MSG(" \n\r"); + BLETXCharCCCDWriteCb(&message); + /* USER CODE END P2PS_STM__NOTIFY_ENABLED_EVT */ + break; + + case MATTER_STM_INDICATE_DISABLED_EVT: + /* USER CODE BEGIN P2PS_STM_NOTIFY_DISABLED_EVT */ + message.connid = pNotification->ConnectionHandle; + message.notif = 0; + P2P_Server_App_Context.Notification_Status = 0; + APP_DBG_MSG("-- Matter APPLICATION SERVER : INDICATE DISABLED\n"); + APP_DBG_MSG(" \n\r"); + BLETXCharCCCDWriteCb(&message); + /* USER CODE END P2PS_STM_NOTIFY_DISABLED_EVT */ + break; + + case MATTER_STM_WRITE_EVT:; + BLE_Matter_RX Message; + Message.Length = pNotification->DataTransfered.Length; + Message.Payload = pNotification->DataTransfered.pPayload; + Message.connid = pNotification->ConnectionHandle; + BLEReceiveCb(&Message); // call matter callback + /* USER CODE BEGIN MATTER_STM_WRITE_EVT */ + + /* USER CODE END MATTER_STM_WRITE_EVT */ + break; + + default: + /* USER CODE BEGIN APP_MATTER_Notification */ + + /* USER CODE END APP_MATTER_Notification */ + break; + } + /* USER CODE BEGIN APP_MATTER_Notification */ + + /* USER CODE END APP_MATTER_Notification */ + return; +} + +void APP_MATTER_Init(void) +{ + /* USER CODE BEGIN APP_MATTER_Init */ + + /** + * Initialize LedButton Service + */ + P2P_Server_App_Context.Notification_Status = 0; + /* USER CODE END APP_MATTER_Init */ + return; +} + +/* USER CODE END FD */ + +/************************************************************* + * + * LOCAL FUNCTIONS + * + *************************************************************/ + +/* USER CODE BEGIN FD_LOCAL_FUNCTIONS*/ +void APP_MATTER_Send_Notification(uint16_t datalength, uint8_t * data) +{ + + if (P2P_Server_App_Context.ButtonControl.ButtonStatus == 0x00) + { + P2P_Server_App_Context.ButtonControl.ButtonStatus = 0x01; + } + else + { + P2P_Server_App_Context.ButtonControl.ButtonStatus = 0x00; + } + + if (P2P_Server_App_Context.Notification_Status) + { + CUSTOM_STM_App_Update_Char(P2P_NOTIFY_CHAR_UUID, (uint8_t *) data, datalength); + } + else + { + APP_DBG_MSG("-- Matter APPLICATION SERVER : CAN'T INFORM CLIENT - NOTIFICATION DISABLED\n "); + } + + return; +} + +/* USER CODE END FD_LOCAL_FUNCTIONS*/ diff --git a/examples/platform/stm32/common/STM32WB5MM-DK/STM32_WPAN/App/app_matter.h b/examples/platform/stm32/common/STM32WB5MM-DK/STM32_WPAN/App/app_matter.h new file mode 100644 index 00000000000000..c3dccc8e142133 --- /dev/null +++ b/examples/platform/stm32/common/STM32WB5MM-DK/STM32_WPAN/App/app_matter.h @@ -0,0 +1,116 @@ +/* USER CODE BEGIN */ +/** + ****************************************************************************** + * File Name : App/app_matter.h + * Description : Header for p2p_server_app.c module + ****************************************************************************** + * @attention + * + * Copyright (c) 2019-2021 STMicroelectronics. + * All rights reserved. + * + * This software is licensed under terms that can be found in the LICENSE file + * in the root directory of this software component. + * If no LICENSE file comes with this software, it is provided AS-IS. + * + ****************************************************************************** + */ +/* USER CODE END Header */ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef __APP_MATTER_H +#define __APP_MATTER_H + +#ifdef __cplusplus +extern "C" { +#endif + +/* Includes ------------------------------------------------------------------*/ +#include +/* Private includes ----------------------------------------------------------*/ +/* USER CODE BEGIN Includes */ + +/* USER CODE END Includes */ + +/* Exported types ------------------------------------------------------------*/ + +typedef enum +{ + MATTER_STM_PEER_CONN_HANDLE_EVT, + MATTER_STM_PEER_DISCON_HANDLE_EVT, + MATTER_STM_ACK_INDICATE_EVT, + MATTER_STM_INDICATE_ENABLED_EVT, + MATTER_STM_INDICATE_DISABLED_EVT, + MATTER_STM_READ_EVT, + MATTER_STM_WRITE_EVT, + MATTER_STM_BOOT_REQUEST_EVT, +} MATTER_STM_Opcode_evt_t; + +typedef struct +{ + uint8_t * pPayload; + uint8_t Length; +} MATTER_STM_Data_t; + +typedef struct +{ + MATTER_STM_Opcode_evt_t P2P_Evt_Opcode; + MATTER_STM_Data_t DataTransfered; + uint16_t ConnectionHandle; + uint8_t ServiceInstance; +} MATTER_App_Notification_evt_t; + +typedef struct +{ + uint8_t * Payload; + uint16_t Length; + uint16_t connid; +} BLE_Matter_RX; + +typedef struct +{ + uint16_t connid; + uint8_t notif; +} BLE_Matter_TXCharCCCD; + +typedef void (*BLEReceiveCallback)(BLE_Matter_RX * aMessage); +typedef void (*BLETXCharCCCDWriteCallback)(BLE_Matter_TXCharCCCD * aMessage); +typedef void (*BLEConnectionCallback)(void); +typedef void (*BLEDisconnectionCallback)(uint16_t * connid); +typedef void (*BLEDAckCallback)(uint16_t * connid); + +/* USER CODE END ET */ + +/* Exported constants --------------------------------------------------------*/ +/* USER CODE BEGIN EC */ + +/* USER CODE END EC */ + +/* External variables --------------------------------------------------------*/ +/* USER CODE BEGIN EV */ + +/* USER CODE END EV */ + +/* Exported macros ------------------------------------------------------------*/ +/* USER CODE BEGIN EM */ + +/* USER CODE END EM */ + +/* Exported functions ---------------------------------------------*/ +/* USER CODE BEGIN EF */ +void APP_MATTER_Init(void); +void APP_MATTER_Send_Notification(uint16_t datalength, uint8_t * data); +void APP_MATTER_Notification(MATTER_App_Notification_evt_t * pNotification); + +void APP_MATTER_BLE_Set_Connection_Callback(BLEConnectionCallback aCallback); +void APP_MATTER_BLE_Set_Disconnection_Callback(BLEDisconnectionCallback aCallback); +void APP_MATTER_BLE_Set_Receive_Callback(BLEReceiveCallback aCallback); +void APP_MATTER_BLE_Set_TXCharCCCDWrite_Callback(BLETXCharCCCDWriteCallback aCallback); +void APP_MATTER_BLE_Set_Ack_After_Indicate_Callback(BLEDAckCallback aCallback); +/* USER CODE END EF */ + +#ifdef __cplusplus +} +#endif + +#endif /*__APP_MATTER_H */ diff --git a/examples/platform/stm32/common/STM32WB5MM-DK/STM32_WPAN/App/app_thread.c b/examples/platform/stm32/common/STM32WB5MM-DK/STM32_WPAN/App/app_thread.c new file mode 100644 index 00000000000000..f917b8542fc4bf --- /dev/null +++ b/examples/platform/stm32/common/STM32WB5MM-DK/STM32_WPAN/App/app_thread.c @@ -0,0 +1,665 @@ +/* USER CODE BEGIN Header */ +/** + ****************************************************************************** + * File Name : App/app_thread.c + * Description : Thread Application. + ****************************************************************************** + * @attention + * + * Copyright (c) 2019-2021 STMicroelectronics. + * All rights reserved. + * + * This software is licensed under terms that can be found in the LICENSE file + * in the root directory of this software component. + * If no LICENSE file comes with this software, it is provided AS-IS. + * + ****************************************************************************** + */ +/* USER CODE END Header */ + +/* Includes ------------------------------------------------------------------*/ +#include "app_thread.h" +#include "app_common.h" +#include "app_conf.h" +#include "app_entry.h" +#include "cmsis_os.h" +#include "dbg_trace.h" +#include "openthread_api_wb.h" +#include "queue.h" +#include "shci.h" +#include "stm32_lpm.h" +#include "stm32wbxx_core_interface_def.h" +#include "stm_logging.h" +#include "utilities_common.h" + +/* Private includes -----------------------------------------------------------*/ +/* USER CODE BEGIN Includes */ + +/* USER CODE END Includes */ + +/* Private typedef -----------------------------------------------------------*/ +/* USER CODE BEGIN PTD */ + +/* USER CODE END PTD */ + +/* Private defines -----------------------------------------------------------*/ +#define C_SIZE_CMD_STRING 256U +#define MO_NOTIF_QUEUE_SIZE 10 + +/* USER CODE BEGIN PD */ + +/* USER CODE END PD */ + +static osSemaphoreId_t TransferToM0Semaphore; +static osMutexId_t MtxThreadId; + +/* FreeRtos stacks attributes */ +const osThreadAttr_t ThreadMsgM0ToM4Process_attr = { .name = CFG_THREAD_MSG_M0_TO_M4_PROCESS_NAME, + .attr_bits = CFG_THREAD_MSG_M0_TO_M4_PROCESS_ATTR_BITS, + .cb_mem = CFG_THREAD_MSG_M0_TO_M4_PROCESS_CB_MEM, + .cb_size = CFG_THREAD_MSG_M0_TO_M4_PROCESS_CB_SIZE, + .stack_mem = CFG_THREAD_MSG_M0_TO_M4_PROCESS_STACK_MEM, + .priority = CFG_THREAD_MSG_M0_TO_M4_PROCESS_PRIORITY, + .stack_size = CFG_THREAD_MSG_M0_TO_M4_PROCESS_STACK_SIZE }; + +const osThreadAttr_t ThreadCliProcess_attr = { .name = CFG_THREAD_CLI_PROCESS_NAME, + .attr_bits = CFG_THREAD_CLI_PROCESS_ATTR_BITS, + .cb_mem = CFG_THREAD_CLI_PROCESS_CB_MEM, + .cb_size = CFG_THREAD_CLI_PROCESS_CB_SIZE, + .stack_mem = CFG_THREAD_CLI_PROCESS_STACK_MEM, + .priority = CFG_THREAD_CLI_PROCESS_PRIORITY, + .stack_size = CFG_THREAD_CLI_PROCESS_STACK_SIZE }; + +static volatile int FlagReceiveAckFromM0 = 0; +/* Private macros ------------------------------------------------------------*/ +/* USER CODE BEGIN PM */ + +/* USER CODE END PM */ + +/* Private function prototypes -----------------------------------------------*/ +static void APP_THREAD_CheckWirelessFirmwareInfo(void); +static void APP_THREAD_TraceError(const char * pMess, uint32_t ErrCode); +#if (CFG_FULL_LOW_POWER == 0) +static void Send_CLI_To_M0(void); +#endif /* (CFG_FULL_LOW_POWER == 0) */ +static void Send_CLI_Ack_For_OT(void); +static void HostTxCb(void); +static void Wait_Getting_Ack_From_M0(void); +static void Receive_Ack_From_M0(void); +static void Receive_Notification_From_M0(void); +static void APP_THREAD_FreeRTOSProcessMsgM0ToM4Task(void * argument); +static void Ot_Cmd_Transfer_Common(void); +#if (CFG_FULL_LOW_POWER == 0) +static void APP_THREAD_FreeRTOSSendCLIToM0Task(void * argument); +#endif /* (CFG_FULL_LOW_POWER == 0) */ +#if (CFG_FULL_LOW_POWER == 0) +static void RxCpltCallback(void); +#endif /* (CFG_FULL_LOW_POWER == 0) */ + +/* USER CODE BEGIN PFP */ +/* USER CODE END PFP */ + +/* Private variables ---------------------------------------------------------*/ +#if (CFG_FULL_LOW_POWER == 0) +static uint8_t aRxBuffer[C_SIZE_CMD_STRING]; +#endif /* (CFG_FULL_LOW_POWER == 0) */ + +#if (CFG_FULL_LOW_POWER == 0) +static uint8_t CommandString[C_SIZE_CMD_STRING]; +#endif /* (CFG_FULL_LOW_POWER == 0) */ +static __IO uint16_t indexReceiveChar = 0; +static __IO uint16_t CptReceiveCmdFromUser = 0; + +static TL_CmdPacket_t * p_thread_otcmdbuffer; +static TL_EvtPacket_t * p_thread_notif_M0_to_M4; +PLACE_IN_SECTION("MB_MEM1") ALIGN(4) static TL_TH_Config_t ThreadConfigBuffer; +PLACE_IN_SECTION("MB_MEM2") ALIGN(4) static TL_CmdPacket_t ThreadOtCmdBuffer; +PLACE_IN_SECTION("MB_MEM2") ALIGN(4) static uint8_t ThreadNotifRspEvtBuffer[sizeof(TL_PacketHeader_t) + TL_EVT_HDR_SIZE + 255U]; +PLACE_IN_SECTION("MB_MEM2") ALIGN(4) static TL_CmdPacket_t ThreadCliCmdBuffer; +PLACE_IN_SECTION("MB_MEM2") ALIGN(4) static TL_CmdPacket_t ThreadCliNotBuffer; +extern uint8_t g_ot_notification_allowed; + +/* USER CODE BEGIN PV */ +static QueueHandle_t MoNotifQueue; +static osThreadId_t OsTaskMsgM0ToM4Id; /* Task managing the M0 to M4 messaging */ +#if (CFG_FULL_LOW_POWER == 0) +static osThreadId_t OsTaskCliId; /* Task used to manage CLI command */ +#endif /* (CFG_FULL_LOW_POWER == 0) */ +/* Debug */ +/* USER CODE END PV */ + +/* Functions Definition ------------------------------------------------------*/ + +void APP_THREAD_Init(void) +{ + /* USER CODE BEGIN APP_THREAD_INIT_1 */ + /* Do not allow stop mode before Thread is initialized */ + UTIL_LPM_SetStopMode(1 << CFG_LPM_APP_THREAD, UTIL_LPM_DISABLE); + /* USER CODE END APP_THREAD_INIT_1 */ + + SHCI_CmdStatus_t ThreadInitStatus; + + /* Check the compatibility with the Coprocessor Wireless Firmware loaded */ + APP_THREAD_CheckWirelessFirmwareInfo(); + + /* Register cmdbuffer */ + APP_THREAD_RegisterCmdBuffer(&ThreadOtCmdBuffer); + + /** + * Do not allow standby in the application + */ + UTIL_LPM_SetOffMode(1 << CFG_LPM_APP_THREAD, UTIL_LPM_DISABLE); + + /* Init config buffer and call TL_THREAD_Init */ + APP_THREAD_TL_THREAD_INIT(); + + /* Configure UART for sending CLI command from M4 */ + // APP_THREAD_Init_UART_CLI(); Conflict with qspi gpio + /* Send Thread start system cmd to M0 */ + ThreadInitStatus = SHCI_C2_THREAD_Init(); + + /* Prevent unused argument(s) compilation warning */ + UNUSED(ThreadInitStatus); + + /* Semaphore */ + TransferToM0Semaphore = osSemaphoreNew(1, 0, NULL); + /* Initialize the mutex */ + MtxThreadId = osMutexNew(NULL); + + MoNotifQueue = xQueueCreate(MO_NOTIF_QUEUE_SIZE, sizeof(uint8_t)); + if (MoNotifQueue == NULL) + { + APP_DBG("Failed to allocate M0 notification queue"); + } + + /* Create the different FreeRTOS tasks requested to run this Thread application*/ + OsTaskMsgM0ToM4Id = osThreadNew(APP_THREAD_FreeRTOSProcessMsgM0ToM4Task, NULL, &ThreadMsgM0ToM4Process_attr); + + /* USER CODE BEGIN APP_THREAD_INIT_FREERTOS */ + /* USER CODE END APP_THREAD_INIT_FREERTOS */ + /* USER CODE BEGIN APP_THREAD_INIT_2 */ + /* USER CODE END APP_THREAD_INIT_2 */ +} + +/** + * @brief Trace the error or the warning reported. + * @param ErrId : + * @param ErrCode + * @retval None + */ +void APP_THREAD_Error(uint32_t ErrId, uint32_t ErrCode) +{ + /* USER CODE BEGIN APP_THREAD_Error_1 */ + + /* USER CODE END APP_THREAD_Error_1 */ + switch (ErrId) + { + case ERR_REC_MULTI_MSG_FROM_M0: + APP_THREAD_TraceError("ERROR : ERR_REC_MULTI_MSG_FROM_M0 ", ErrCode); + break; + case ERR_THREAD_SET_STATE_CB: + APP_THREAD_TraceError("ERROR : ERR_THREAD_SET_STATE_CB ", ErrCode); + break; + case ERR_THREAD_SET_CHANNEL: + APP_THREAD_TraceError("ERROR : ERR_THREAD_SET_CHANNEL ", ErrCode); + break; + case ERR_THREAD_SET_PANID: + APP_THREAD_TraceError("ERROR : ERR_THREAD_SET_PANID ", ErrCode); + break; + case ERR_THREAD_IPV6_ENABLE: + APP_THREAD_TraceError("ERROR : ERR_THREAD_IPV6_ENABLE ", ErrCode); + break; + case ERR_THREAD_START: + APP_THREAD_TraceError("ERROR: ERR_THREAD_START ", ErrCode); + break; + case ERR_THREAD_ERASE_PERSISTENT_INFO: + APP_THREAD_TraceError("ERROR : ERR_THREAD_ERASE_PERSISTENT_INFO ", ErrCode); + break; + case ERR_THREAD_CHECK_WIRELESS: + APP_THREAD_TraceError("ERROR : ERR_THREAD_CHECK_WIRELESS ", ErrCode); + break; + /* USER CODE BEGIN APP_THREAD_Error_2 */ + case ERR_THREAD_COAP_START: + APP_THREAD_TraceError("ERROR : ERR_THREAD_COAP_START ", ErrCode); + break; + case ERR_THREAD_COAP_ADD_RESSOURCE: + APP_THREAD_TraceError("ERROR : ERR_THREAD_COAP_ADD_RESSOURCE ", ErrCode); + break; + case ERR_THREAD_MESSAGE_READ: + APP_THREAD_TraceError("ERROR : ERR_THREAD_MESSAGE_READ ", ErrCode); + break; + case ERR_THREAD_COAP_SEND_RESPONSE: + APP_THREAD_TraceError("ERROR : ERR_THREAD_COAP_SEND_RESPONSE ", ErrCode); + break; + case ERR_THREAD_COAP_APPEND: + APP_THREAD_TraceError("ERROR : ERR_THREAD_COAP_APPEND ", ErrCode); + break; + case ERR_THREAD_COAP_SEND_REQUEST: + APP_THREAD_TraceError("ERROR : ERR_THREAD_COAP_SEND_REQUEST ", ErrCode); + break; + case ERR_TIMER_INIT: + APP_THREAD_TraceError("ERROR : ERR_TIMER_INIT ", ErrCode); + break; + case ERR_TIMER_START: + APP_THREAD_TraceError("ERROR : ERR_TIMER_START ", ErrCode); + break; + /* USER CODE END APP_THREAD_Error_2 */ + default: + APP_THREAD_TraceError("ERROR Unknown ", 0); + break; + } +} + +/** + * @brief Perform initialization of CLI UART interface. + * @param None + * @retval None + */ +void APP_THREAD_Init_UART_CLI(void) +{ +#if (CFG_FULL_LOW_POWER == 0) + OsTaskCliId = osThreadNew(APP_THREAD_FreeRTOSSendCLIToM0Task, NULL, &ThreadCliProcess_attr); +#endif /* (CFG_FULL_LOW_POWER == 0) */ + +#if (CFG_FULL_LOW_POWER == 0) + HW_UART_Init(CFG_CLI_UART); + HW_UART_Receive_IT(CFG_CLI_UART, aRxBuffer, 1, RxCpltCallback); +#endif /* (CFG_FULL_LOW_POWER == 0) */ +} + +/** + * @brief Perform initialization of TL for THREAD. + * @param None + * @retval None + */ +void APP_THREAD_TL_THREAD_INIT(void) +{ + ThreadConfigBuffer.p_ThreadOtCmdRspBuffer = (uint8_t *) &ThreadOtCmdBuffer; + ThreadConfigBuffer.p_ThreadNotAckBuffer = (uint8_t *) ThreadNotifRspEvtBuffer; + ThreadConfigBuffer.p_ThreadCliRspBuffer = (uint8_t *) &ThreadCliCmdBuffer; + ThreadConfigBuffer.p_ThreadCliNotBuffer = (uint8_t *) &ThreadCliNotBuffer; + + TL_THREAD_Init(&ThreadConfigBuffer); +} + +/** + * @brief This function is used to transfer the Ot commands from the + * M4 to the M0. + * + * @param None + * @return None + */ +void Ot_Cmd_Transfer(void) +{ + Ot_Cmd_Transfer_Common(); +} + +/** + * @brief This function is used to transfer the Ot commands from the + * M4 to the M0 with Notification M0 to M4 allowed. + * + * @param None + * @return None + */ +void Ot_Cmd_TransferWithNotif(void) +{ + /* Flag to specify to UTIL_SEQ_EvtIdle that M0 to M4 notifications are allowed */ + g_ot_notification_allowed = 1U; + + Ot_Cmd_Transfer_Common(); +} + +/** + * @brief This function is called when acknowledge from OT command is received from the M0+. + * + * @param Otbuffer : a pointer to TL_EvtPacket_t + * @return None + */ +void TL_OT_CmdEvtReceived(TL_EvtPacket_t * Otbuffer) +{ + /* Prevent unused argument(s) compilation warning */ + UNUSED(Otbuffer); + + Receive_Ack_From_M0(); + + /* Does not allow OpenThread M0 to M4 notification */ + g_ot_notification_allowed = 0U; +} + +/** + * @brief This function is called when notification from M0+ is received. + * + * @param Notbuffer : a pointer to TL_EvtPacket_t + * @return None + */ +void TL_THREAD_NotReceived(TL_EvtPacket_t * Notbuffer) +{ + p_thread_notif_M0_to_M4 = Notbuffer; + + Receive_Notification_From_M0(); +} + +/** + * @brief This function is called when notification on CLI TL Channel from M0+ is received. + * + * @param Notbuffer : a pointer to TL_EvtPacket_t + * @return None + */ +void TL_THREAD_CliNotReceived(TL_EvtPacket_t * Notbuffer) +{ + TL_CmdPacket_t * l_CliBuffer = (TL_CmdPacket_t *) Notbuffer; + uint8_t l_size = l_CliBuffer->cmdserial.cmd.plen; + + /* WORKAROUND: if string to output is "> " then respond directly to M0 and do not output it */ + if (strcmp((const char *) l_CliBuffer->cmdserial.cmd.payload, "> ") != 0) + { + /* Write to CLI UART */ + HW_UART_Transmit_IT(CFG_CLI_UART, l_CliBuffer->cmdserial.cmd.payload, l_size, HostTxCb); + } + else + { + Send_CLI_Ack_For_OT(); + } +} + +/** + * @brief This function is called before sending any ot command to the M0 + * core. The purpose of this function is to be able to check if + * there are no notifications coming from the M0 core which are + * pending before sending a new ot command. + * @param None + * @retval None + */ +void Pre_OtCmdProcessing(void) +{ + osMutexAcquire(MtxThreadId, osWaitForever); +} + +void APP_THREAD_RegisterCmdBuffer(TL_CmdPacket_t * p_buffer) +{ + p_thread_otcmdbuffer = p_buffer; +} + +Thread_OT_Cmd_Request_t * THREAD_Get_OTCmdPayloadBuffer(void) +{ + return (Thread_OT_Cmd_Request_t *) p_thread_otcmdbuffer->cmdserial.cmd.payload; +} + +Thread_OT_Cmd_Request_t * THREAD_Get_OTCmdRspPayloadBuffer(void) +{ + return (Thread_OT_Cmd_Request_t *) ((TL_EvtPacket_t *) p_thread_otcmdbuffer)->evtserial.evt.payload; +} + +Thread_OT_Cmd_Request_t * THREAD_Get_NotificationPayloadBuffer(void) +{ + return (Thread_OT_Cmd_Request_t *) (p_thread_notif_M0_to_M4)->evtserial.evt.payload; +} + +/************************************************************* + * + * LOCAL FUNCTIONS + * + *************************************************************/ + +/** + * @brief Warn the user that an error has occurred.In this case, + * the LEDs on the Board will start blinking. + * + * @param pMess : Message associated to the error. + * @param ErrCode: Error code associated to the module (OpenThread or other module if any) + * @retval None + */ +static void APP_THREAD_TraceError(const char * pMess, uint32_t ErrCode) +{ + /* USER CODE BEGIN TRACE_ERROR */ + APP_DBG("**** Fatal error = %s (Err = %d)", pMess, ErrCode); + while (1U == 1U) + { + HAL_Delay(500U); + } + /* USER CODE END TRACE_ERROR */ +} + +/** + * @brief Check if the Coprocessor Wireless Firmware loaded supports Thread + * and display associated information + * @param None + * @retval None + */ +static void APP_THREAD_CheckWirelessFirmwareInfo(void) +{ + WirelessFwInfo_t wireless_info_instance; + WirelessFwInfo_t * p_wireless_info = &wireless_info_instance; + + if (SHCI_GetWirelessFwInfo(p_wireless_info) != SHCI_Success) + { + APP_THREAD_Error((uint32_t) ERR_THREAD_CHECK_WIRELESS, (uint32_t) ERR_INTERFACE_FATAL); + } + else + { + APP_DBG("**********************************************************"); + APP_DBG("WIRELESS COPROCESSOR FW:"); + /* Print version */ + APP_DBG("VERSION ID = %d.%d.%d", p_wireless_info->VersionMajor, p_wireless_info->VersionMinor, p_wireless_info->VersionSub); + + switch (p_wireless_info->StackType) + { + case INFO_STACK_TYPE_THREAD_FTD: + APP_DBG("FW Type : Thread FTD"); + break; + case INFO_STACK_TYPE_THREAD_MTD: + APP_DBG("FW Type : Thread MTD"); + break; + case INFO_STACK_TYPE_BLE_THREAD_FTD_DYAMIC: + APP_DBG("FW Type : Dynamic Concurrent Mode BLE/Thread"); + break; + // case INFO_STACK_TYPE_BLE_THREAD_FOR_MATTER: + // APP_DBG("FW Type : Dynamic Concurrent Mode BLE/Thread for Matter ") + // ; + // break; + default: + /* No Thread device supported ! */ + APP_THREAD_Error((uint32_t) ERR_THREAD_CHECK_WIRELESS, (uint32_t) ERR_INTERFACE_FATAL); + break; + } + APP_DBG("**********************************************************"); + } +} + +/************************************************************* + * + * FREERTOS WRAPPER FUNCTIONS + * + *************************************************************/ +static void APP_THREAD_FreeRTOSProcessMsgM0ToM4Task(void * argument) +{ + UNUSED(argument); + uint8_t NotUsed = 0; + for (;;) + { + /* USER CODE BEGIN APP_THREAD_FREERTOS_PROCESS_MSG_M0_TO_M4_1 */ + + /* USER END END APP_THREAD_FREERTOS_PROCESS_MSG_M0_TO_M4_1 */ + xQueueReceive(MoNotifQueue, &NotUsed, portMAX_DELAY); + + if (uxQueueMessagesWaiting(MoNotifQueue) > 1U) + { + APP_THREAD_Error(ERR_REC_MULTI_MSG_FROM_M0, 0); + } + else + { + OpenThread_CallBack_Processing(); + } + /* USER CODE BEGIN APP_THREAD_FREERTOS_PROCESS_MSG_M0_TO_M4_2 */ + + /* USER END END APP_THREAD_FREERTOS_PROCESS_MSG_M0_TO_M4_2 */ + } +} + +#if (CFG_FULL_LOW_POWER == 0) +static void APP_THREAD_FreeRTOSSendCLIToM0Task(void * argument) +{ + UNUSED(argument); + for (;;) + { + /* USER CODE BEGIN APP_THREAD_FREERTOS_SEND_CLI_TO_M0_1 */ + + /* USER END END APP_THREAD_FREERTOS_SEND_CLI_TO_M0_1 */ + osThreadFlagsWait(1, osFlagsWaitAll, osWaitForever); + Send_CLI_To_M0(); + /* USER CODE BEGIN APP_THREAD_FREERTOS_SEND_CLI_TO_M0_2 */ + + /* USER END END APP_THREAD_FREERTOS_SEND_CLI_TO_M0_2 */ + } +} +#endif /* (CFG_FULL_LOW_POWER == 0) */ + +/* USER CODE BEGIN FREERTOS_WRAPPER_FUNCTIONS */ +/* USER CODE END FREERTOS_WRAPPER_FUNCTIONS */ + +/* USER CODE BEGIN FD_LOCAL_FUNCTIONS */ + +/* USER CODE END FD_LOCAL_FUNCTIONS */ + +/************************************************************* + * + * WRAP FUNCTIONS + * + *************************************************************/ +static void Ot_Cmd_Transfer_Common(void) +{ + /* OpenThread OT command cmdcode range 0x280 .. 0x3DF = 352 */ + p_thread_otcmdbuffer->cmdserial.cmd.cmdcode = 0x280U; + /* Size = otCmdBuffer->Size (Number of OT cmd arguments : 1 arg = 32bits so multiply by 4 to get size in bytes) + * + ID (4 bytes) + Size (4 bytes) */ + uint32_t l_size = ((Thread_OT_Cmd_Request_t *) (p_thread_otcmdbuffer->cmdserial.cmd.payload))->Size * 4U + 8U; + p_thread_otcmdbuffer->cmdserial.cmd.plen = l_size; + + TL_OT_SendCmd(); + + /* Wait completion of cmd */ + Wait_Getting_Ack_From_M0(); +} + +/** + * @brief This function waits for getting an acknowledgment from the M0. + * + * @param None + * @retval None + */ +static void Wait_Getting_Ack_From_M0(void) +{ + while (FlagReceiveAckFromM0 == 0) + { + } + FlagReceiveAckFromM0 = 0; + osMutexRelease(MtxThreadId); + // osSemaphoreAcquire( TransferToM0Semaphore, osWaitForever ); +} + +/** + * @brief Receive an acknowledgment from the M0+ core. + * Each command send by the M4 to the M0 are acknowledged. + * This function is called under interrupt. + * @param None + * @retval None + */ +static void Receive_Ack_From_M0(void) +{ + FlagReceiveAckFromM0 = 1; + // osSemaphoreRelease( TransferToM0Semaphore); +} + +/** + * @brief Receive a notification from the M0+ through the IPCC. + * This function is called under interrupt. + * @param None + * @retval None + */ +static void Receive_Notification_From_M0(void) +{ + /* The xHigherPriorityTaskWoken parameter must be initialized to pdFALSE as + it will get set to pdTRUE inside the interrupt safe API function if a + context switch is required. */ + BaseType_t xHigherPriorityTaskWoken = pdFALSE; + + uint8_t NotUsed = 0; + xQueueSendToFrontFromISR(MoNotifQueue, &NotUsed, &xHigherPriorityTaskWoken); + + /* Pass the xHigherPriorityTaskWoken value into portEND_SWITCHING_ISR(). If + xHigherPriorityTaskWoken was set to pdTRUE inside xSemaphoreGiveFromISR() + then calling portEND_SWITCHING_ISR() will request a context switch. If + xHigherPriorityTaskWoken is still pdFALSE then calling + portEND_SWITCHING_ISR() will have no effect */ + portEND_SWITCHING_ISR(xHigherPriorityTaskWoken); +} + +#if (CFG_FULL_LOW_POWER == 0) +static void RxCpltCallback(void) +{ + /* Filling buffer and wait for '\r' char */ + if (indexReceiveChar < C_SIZE_CMD_STRING) + { + CommandString[indexReceiveChar++] = aRxBuffer[0]; + if (aRxBuffer[0] == '\r') + { + CptReceiveCmdFromUser = 1U; + + /* UART task scheduling*/ + osThreadFlagsSet(OsTaskCliId, 1); + } + } + + /* Once a character has been sent, put back the device in reception mode */ + HW_UART_Receive_IT(CFG_CLI_UART, aRxBuffer, 1U, RxCpltCallback); +} +#endif /* (CFG_FULL_LOW_POWER == 0) */ + +#if (CFG_FULL_LOW_POWER == 0) +/** + * @brief Process sends receive CLI command to M0. + * @param None + * @retval None + */ +static void Send_CLI_To_M0(void) +{ + memset(ThreadCliCmdBuffer.cmdserial.cmd.payload, 0x0U, 255U); + memcpy(ThreadCliCmdBuffer.cmdserial.cmd.payload, CommandString, indexReceiveChar); + ThreadCliCmdBuffer.cmdserial.cmd.plen = indexReceiveChar; + ThreadCliCmdBuffer.cmdserial.cmd.cmdcode = 0x0; + + /* Clear receive buffer, character counter and command complete */ + CptReceiveCmdFromUser = 0; + indexReceiveChar = 0; + memset(CommandString, 0, C_SIZE_CMD_STRING); + + TL_CLI_SendCmd(); +} +#endif /* (CFG_FULL_LOW_POWER == 0) */ + +/** + * @brief Send notification for CLI TL Channel. + * @param None + * @retval None + */ +static void Send_CLI_Ack_For_OT(void) +{ + + /* Notify M0 that characters have been sent to UART */ + TL_THREAD_CliSendAck(); +} + +/** + * @brief End of transfer callback for CLI UART sending. + * + * @param Notbuffer : a pointer to TL_EvtPacket_t + * @return None + */ +static void HostTxCb(void) +{ + Send_CLI_Ack_For_OT(); +} + +/* USER CODE BEGIN FD_WRAP_FUNCTIONS */ + +/* USER CODE END FD_WRAP_FUNCTIONS */ diff --git a/examples/platform/stm32/common/STM32WB5MM-DK/STM32_WPAN/App/app_thread.h b/examples/platform/stm32/common/STM32WB5MM-DK/STM32_WPAN/App/app_thread.h new file mode 100644 index 00000000000000..512b3bcd544538 --- /dev/null +++ b/examples/platform/stm32/common/STM32WB5MM-DK/STM32_WPAN/App/app_thread.h @@ -0,0 +1,132 @@ +/* USER CODE BEGIN Header */ +/** + ****************************************************************************** + * File Name : App/app_thread.h + * Description : Header for Thread Application. + ****************************************************************************** + * @attention + * + * Copyright (c) 2019-2021 STMicroelectronics. + * All rights reserved. + * + * This software is licensed under terms that can be found in the LICENSE file + * in the root directory of this software component. + * If no LICENSE file comes with this software, it is provided AS-IS. + * + ****************************************************************************** + */ +/* USER CODE END Header */ +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef APP_THREAD_H +#define APP_THREAD_H + +#ifdef __cplusplus +extern "C" { +#endif + +/* Includes ------------------------------------------------------------------*/ +/* Private includes ----------------------------------------------------------*/ +#include "stm32wbxx_core_interface_def.h" +#include "tl.h" +#include "tl_thread_hci.h" + +/* OpenThread Library */ +#include OPENTHREAD_CONFIG_FILE + +/* USER CODE BEGIN Includes */ + +/* USER CODE END Includes */ + +/* Exported types ------------------------------------------------------------*/ + +/* Thread application generic defines */ +/*------------------------------------*/ +typedef enum +{ + APP_THREAD_LIMITED, + APP_THREAD_FULL, +} APP_THREAD_InitMode_t; + +/* ipv6-addressing defines */ +/*------------------------------------*/ +/* Key Point: A major difference between FTDs and MTDs are that FTDs subscribe to the ff03::2 multicast address. + * MTDs do not. */ + +#define MULICAST_FTD_MED "ff03::1" +#define MULICAST_FTD_BORDER_ROUTER "ff03::2" + +/* Application errors */ +/*------------------------------------*/ + +/* + * List of all errors tracked by the Thread application + * running on M4. Some of these errors may be fatal + * or just warnings + */ +typedef enum +{ + ERR_REC_MULTI_MSG_FROM_M0, + ERR_THREAD_SET_STATE_CB, + ERR_THREAD_SET_CHANNEL, + ERR_THREAD_SET_PANID, + ERR_THREAD_IPV6_ENABLE, + ERR_THREAD_START, + ERR_THREAD_ERASE_PERSISTENT_INFO, + ERR_THREAD_SET_NETWORK_KEY, + /* USER CODE BEGIN ERROR_APPLI_ENUM */ + ERR_THREAD_COAP_START, + ERR_THREAD_COAP_ADD_RESSOURCE, + ERR_THREAD_MESSAGE_READ, + ERR_THREAD_COAP_SEND_RESPONSE, + ERR_THREAD_COAP_APPEND, + ERR_THREAD_COAP_SEND_REQUEST, + ERR_THREAD_SETUP, + ERR_THREAD_LINK_MODE, + ERR_TIMER_INIT, + ERR_TIMER_START, + ERR_THREAD_COAP_NEW_MSG, + ERR_THREAD_COAP_ADDRESS_NOT_DEFINED, + ERR_THREAD_STOP, + /* USER CODE END ERROR_APPLI_ENUM */ + ERR_THREAD_CHECK_WIRELESS +} ErrAppliIdEnum_t; +/* USER CODE BEGIN ET */ + +/* USER CODE END ET */ + +/* Exported constants --------------------------------------------------------*/ +/* USER CODE BEGIN EC */ + +/* USER CODE END EC */ + +/* External variables --------------------------------------------------------*/ +/* USER CODE BEGIN EV */ + +/* USER CODE END EV */ + +/* Exported macros ------------------------------------------------------------*/ +/* USER CODE BEGIN EM */ + +/* USER CODE END EM */ + +/* Exported functions ------------------------------------------------------- */ +void APP_THREAD_Init(void); +void APP_THREAD_Error(uint32_t ErrId, uint32_t ErrCode); +void APP_THREAD_RegisterCmdBuffer(TL_CmdPacket_t * p_buffer); +void APP_THREAD_ProcessMsgM0ToM4(void); +void APP_THREAD_Init_UART_CLI(void); +void APP_THREAD_TL_THREAD_INIT(void); +void APP_THREAD_SEND_MSG(void); +/* **** */ +void APP_THREAD_Stop(void); +void APP_THREAD_CleanCallbacks(void); + +/* USER CODE BEGIN EF */ + +/* USER CODE END EF */ + +#ifdef __cplusplus +} /* extern "C" */ +#endif + +#endif /* APP_THREAD_H */ diff --git a/examples/platform/stm32/common/STM32WB5MM-DK/STM32_WPAN/App/ble_conf.h b/examples/platform/stm32/common/STM32WB5MM-DK/STM32_WPAN/App/ble_conf.h new file mode 100644 index 00000000000000..9cdee1a82cc217 --- /dev/null +++ b/examples/platform/stm32/common/STM32WB5MM-DK/STM32_WPAN/App/ble_conf.h @@ -0,0 +1,68 @@ +/** + ****************************************************************************** + * File Name : App/ble_conf.h + * Description : Configuration file for BLE Middleware. + * + ****************************************************************************** + * @attention + * + * Copyright (c) 2019-2021 STMicroelectronics. + * All rights reserved. + * + * This software is licensed under terms that can be found in the LICENSE file + * in the root directory of this software component. + * If no LICENSE file comes with this software, it is provided AS-IS. + * + ****************************************************************************** + */ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef BLE_CONF_H +#define BLE_CONF_H + +#include "app_conf.h" + +/****************************************************************************** + * + * BLE SERVICES CONFIGURATION + * blesvc + * + ******************************************************************************/ + +/** + * This setting shall be set to '1' if the device needs to support the Peripheral Role + * In the MS configuration, both BLE_CFG_PERIPHERAL and BLE_CFG_CENTRAL shall be set to '1' + */ +#define BLE_CFG_PERIPHERAL 1 + +/** + * This setting shall be set to '1' if the device needs to support the Central Role + * In the MS configuration, both BLE_CFG_PERIPHERAL and BLE_CFG_CENTRAL shall be set to '1' + */ +#define BLE_CFG_CENTRAL 0 + +/** + * There is one handler per service enabled + * Note: There is no handler for the Device Information Service + * + * This shall take into account all registered handlers + * (from either the provided services or the custom services) + */ +#define BLE_CFG_SVC_MAX_NBR_CB 3 + +#define BLE_CFG_CLT_MAX_NBR_CB 0 + +/****************************************************************************** + * GAP Service - Appearance + ******************************************************************************/ + +#define BLE_CFG_UNKNOWN_APPEARANCE (0) +#define BLE_CFG_HR_SENSOR_APPEARANCE (832) +#define BLE_CFG_GAP_APPEARANCE (BLE_CFG_UNKNOWN_APPEARANCE) + +/****************************************************************************** + * Over The Air Feature (OTA) - STM Proprietary + ******************************************************************************/ +#define BLE_CFG_OTA_REBOOT_CHAR 0 /**< REBOOT OTA MODE CHARACTERISTIC */ + +#endif /*BLE_CONF_H */ diff --git a/examples/platform/stm32/common/STM32WB5MM-DK/STM32_WPAN/App/ble_dbg_conf.h b/examples/platform/stm32/common/STM32WB5MM-DK/STM32_WPAN/App/ble_dbg_conf.h new file mode 100644 index 00000000000000..0951cc1372a405 --- /dev/null +++ b/examples/platform/stm32/common/STM32WB5MM-DK/STM32_WPAN/App/ble_dbg_conf.h @@ -0,0 +1,196 @@ +/** + ****************************************************************************** + * File Name : App/ble_dbg_conf.h + * Description : Debug configuration file for BLE Middleware. + * + ****************************************************************************** + * @attention + * + * Copyright (c) 2019-2021 STMicroelectronics. + * All rights reserved. + * + * This software is licensed under terms that can be found in the LICENSE file + * in the root directory of this software component. + * If no LICENSE file comes with this software, it is provided AS-IS. + * + ****************************************************************************** + */ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef __BLE_DBG_CONF_H +#define __BLE_DBG_CONF_H + +/** + * Enable or Disable traces from BLE + */ + +#define BLE_DBG_APP_EN 0 +#define BLE_DBG_DIS_EN 0 +#define BLE_DBG_HRS_EN 0 +#define BLE_DBG_SVCCTL_EN 0 +#define BLE_DBG_BLS_EN 0 +#define BLE_DBG_HTS_EN 0 +#define BLE_DBG_P2P_STM_EN 1 + +/** + * Macro definition + */ +#if (BLE_DBG_APP_EN != 0) +#define BLE_DBG_APP_MSG PRINT_MESG_DBG +#else +#define BLE_DBG_APP_MSG PRINT_NO_MESG +#endif + +#if (BLE_DBG_DIS_EN != 0) +#define BLE_DBG_DIS_MSG PRINT_MESG_DBG +#else +#define BLE_DBG_DIS_MSG PRINT_NO_MESG +#endif + +#if (BLE_DBG_HRS_EN != 0) +#define BLE_DBG_HRS_MSG PRINT_MESG_DBG +#else +#define BLE_DBG_HRS_MSG PRINT_NO_MESG +#endif + +#if (BLE_DBG_P2P_STM_EN != 0) +#define BLE_DBG_P2P_STM_MSG PRINT_MESG_DBG +#else +#define BLE_DBG_P2P_STM_MSG PRINT_NO_MESG +#endif + +#if (BLE_DBG_TEMPLATE_STM_EN != 0) +#define BLE_DBG_TEMPLATE_STM_MSG PRINT_MESG_DBG +#else +#define BLE_DBG_TEMPLATE_STM_MSG PRINT_NO_MESG +#endif + +#if (BLE_DBG_EDS_STM_EN != 0) +#define BLE_DBG_EDS_STM_MSG PRINT_MESG_DBG +#else +#define BLE_DBG_EDS_STM_MSG PRINT_NO_MESG +#endif + +#if (BLE_DBG_LBS_STM_EN != 0) +#define BLE_DBG_LBS_STM_MSG PRINT_MESG_DBG +#else +#define BLE_DBG_LBS_STM_MSG PRINT_NO_MESG +#endif + +#if (BLE_DBG_SVCCTL_EN != 0) +#define BLE_DBG_SVCCTL_MSG PRINT_MESG_DBG +#else +#define BLE_DBG_SVCCTL_MSG PRINT_NO_MESG +#endif + +#if (BLE_DBG_CTS_EN != 0) +#define BLE_DBG_CTS_MSG PRINT_MESG_DBG +#else +#define BLE_DBG_CTS_MSG PRINT_NO_MESG +#endif + +#if (BLE_DBG_HIDS_EN != 0) +#define BLE_DBG_HIDS_MSG PRINT_MESG_DBG +#else +#define BLE_DBG_HIDS_MSG PRINT_NO_MESG +#endif + +#if (BLE_DBG_PASS_EN != 0) +#define BLE_DBG_PASS_MSG PRINT_MESG_DBG +#else +#define BLE_DBG_PASS_MSG PRINT_NO_MESG +#endif + +#if (BLE_DBG_BLS_EN != 0) +#define BLE_DBG_BLS_MSG PRINT_MESG_DBG +#else +#define BLE_DBG_BLS_MSG PRINT_NO_MESG +#endif + +#if (BLE_DBG_HTS_EN != 0) +#define BLE_DBG_HTS_MSG PRINT_MESG_DBG +#else +#define BLE_DBG_HTS_MSG PRINT_NO_MESG +#endif + +#if (BLE_DBG_ANS_EN != 0) +#define BLE_DBG_ANS_MSG PRINT_MESG_DBG +#else +#define BLE_DBG_ANS_MSG PRINT_NO_MESG +#endif + +#if (BLE_DBG_ESS_EN != 0) +#define BLE_DBG_ESS_MSG PRINT_MESG_DBG +#else +#define BLE_DBG_ESS_MSG PRINT_NO_MESG +#endif + +#if (BLE_DBG_GLS_EN != 0) +#define BLE_DBG_GLS_MSG PRINT_MESG_DBG +#else +#define BLE_DBG_GLS_MSG PRINT_NO_MESG +#endif + +#if (BLE_DBG_BAS_EN != 0) +#define BLE_DBG_BAS_MSG PRINT_MESG_DBG +#else +#define BLE_DBG_BAS_MSG PRINT_NO_MESG +#endif + +#if (BLE_DBG_RTUS_EN != 0) +#define BLE_DBG_RTUS_MSG PRINT_MESG_DBG +#else +#define BLE_DBG_RTUS_MSG PRINT_NO_MESG +#endif + +#if (BLE_DBG_HPS_EN != 0) +#define BLE_DBG_HPS_MSG PRINT_MESG_DBG +#else +#define BLE_DBG_HPS_MSG PRINT_NO_MESG +#endif + +#if (BLE_DBG_TPS_EN != 0) +#define BLE_DBG_TPS_MSG PRINT_MESG_DBG +#else +#define BLE_DBG_TPS_MSG PRINT_NO_MESG +#endif + +#if (BLE_DBG_LLS_EN != 0) +#define BLE_DBG_LLS_MSG PRINT_MESG_DBG +#else +#define BLE_DBG_LLS_MSG PRINT_NO_MESG +#endif + +#if (BLE_DBG_IAS_EN != 0) +#define BLE_DBG_IAS_MSG PRINT_MESG_DBG +#else +#define BLE_DBG_IAS_MSG PRINT_NO_MESG +#endif + +#if (BLE_DBG_WSS_EN != 0) +#define BLE_DBG_WSS_MSG PRINT_MESG_DBG +#else +#define BLE_DBG_WSS_MSG PRINT_NO_MESG +#endif + +#if (BLE_DBG_LNS_EN != 0) +#define BLE_DBG_LNS_MSG PRINT_MESG_DBG +#else +#define BLE_DBG_LNS_MSG PRINT_NO_MESG +#endif + +#if (BLE_DBG_SCPS_EN != 0) +#define BLE_DBG_SCPS_MSG PRINT_MESG_DBG +#else +#define BLE_DBG_SCPS_MSG PRINT_NO_MESG +#endif + +#if (BLE_DBG_DTS_EN != 0) +#define BLE_DBG_DTS_MSG PRINT_MESG_DBG +#define BLE_DBG_DTS_BUF PRINT_LOG_BUFF_DBG +#else +#define BLE_DBG_DTS_MSG PRINT_NO_MESG +#define BLE_DBG_DTS_BUF PRINT_NO_MESG +#endif + +#endif /*__BLE_DBG_CONF_H */ diff --git a/examples/platform/stm32/common/STM32WB5MM-DK/STM32_WPAN/App/custom_stm.c b/examples/platform/stm32/common/STM32WB5MM-DK/STM32_WPAN/App/custom_stm.c new file mode 100644 index 00000000000000..a4e4a492cbc360 --- /dev/null +++ b/examples/platform/stm32/common/STM32WB5MM-DK/STM32_WPAN/App/custom_stm.c @@ -0,0 +1,261 @@ +/** + ****************************************************************************** + * @file custom_stm.c + * @author MCD Application Team + * @brief matter Service using gatt(Custom STM) + ****************************************************************************** + * @attention + * + * Copyright (c) 2018-2021 STMicroelectronics. + * All rights reserved. + * + * This software is licensed under terms that can be found in the LICENSE file + * in the root directory of this software component. + * If no LICENSE file comes with this software, it is provided AS-IS. + * + ****************************************************************************** + */ + +/* Includes ------------------------------------------------------------------*/ +#include "app_matter.h" +#include "common_blesvc.h" + +/* Private typedef -----------------------------------------------------------*/ +typedef struct +{ + uint16_t PeerToPeerSvcHdle; /**< Service handle */ + uint16_t P2PWriteClientToServerCharHdle; /**< Characteristic handle */ + uint16_t P2PNotifyServerToClientCharHdle; /**< Characteristic handle */ +} PeerToPeerContext_t; + +/* Private defines -----------------------------------------------------------*/ +#define UUID_128_SUPPORTED 1 + +#if (UUID_128_SUPPORTED == 1) +#define BM_UUID_LENGTH UUID_TYPE_128 +#else +#define BM_UUID_LENGTH UUID_TYPE_16 +#endif + +#define BM_REQ_CHAR_SIZE (3) + +/* Private macros ------------------------------------------------------------*/ + +/* Private variables ---------------------------------------------------------*/ + +MATTER_App_Notification_evt_t Notification; + +/** + * START of Section BLE_DRIVER_CONTEXT + */ +PLACE_IN_SECTION("BLE_DRIVER_CONTEXT") static PeerToPeerContext_t aPeerToPeerContext; + +/** + * END of Section BLE_DRIVER_CONTEXT + */ +/* Private function prototypes -----------------------------------------------*/ +static SVCCTL_EvtAckStatus_t Matter_Event_Handler(void * Event); + +/* Functions Definition ------------------------------------------------------*/ +/* Private functions ----------------------------------------------------------*/ + +#define COPY_UUID_128(uuid_struct, uuid_15, uuid_14, uuid_13, uuid_12, uuid_11, uuid_10, uuid_9, uuid_8, uuid_7, uuid_6, uuid_5, \ + uuid_4, uuid_3, uuid_2, uuid_1, uuid_0) \ + do \ + { \ + uuid_struct[0] = uuid_0; \ + uuid_struct[1] = uuid_1; \ + uuid_struct[2] = uuid_2; \ + uuid_struct[3] = uuid_3; \ + uuid_struct[4] = uuid_4; \ + uuid_struct[5] = uuid_5; \ + uuid_struct[6] = uuid_6; \ + uuid_struct[7] = uuid_7; \ + uuid_struct[8] = uuid_8; \ + uuid_struct[9] = uuid_9; \ + uuid_struct[10] = uuid_10; \ + uuid_struct[11] = uuid_11; \ + uuid_struct[12] = uuid_12; \ + uuid_struct[13] = uuid_13; \ + uuid_struct[14] = uuid_14; \ + uuid_struct[15] = uuid_15; \ + } while (0) + +/* Hardware Characteristics Service */ + +#define MATTER_SERVICE_UUID (0xFFF6) +#define COPY_CHAR_RX_UUID(uuid_struct) \ + COPY_UUID_128(uuid_struct, 0x18, 0xEE, 0x2E, 0xF5, 0x26, 0x3D, 0x45, 0x59, 0x95, 0x9F, 0x4F, 0x9C, 0x42, 0x9F, 0x9D, 0x11) +#define COPY_CHAR_TX_UUID(uuid_struct) \ + COPY_UUID_128(uuid_struct, 0x18, 0xEE, 0x2E, 0xF5, 0x26, 0x3D, 0x45, 0x59, 0x95, 0x9F, 0x4F, 0x9C, 0x42, 0x9F, 0x9D, 0x12) +#define COPY_CHAR_ADDCOMMISSIONING_UUID(uuid_struct) \ + COPY_UUID_128(uuid_struct, 0x64, 0x63, 0x02, 0x38, 0x87, 0x72, 0x45, 0xF2, 0xB8, 0x7D, 0x74, 0x8A, 0x83, 0x21, 0x8F, 0x04) + +/* Public functions ----------------------------------------------------------*/ +/** + * @brief Service initialization + * @param None + * @retval None + */ +void SVCCTL_InitCustomSvc(void) +{ + + Char_UUID_t uuid16; + + /** + * Register the event handler to the BLE controller + */ + SVCCTL_RegisterSvcHandler(Matter_Event_Handler); + + /** + * Peer To Peer Service + * + * Max_Attribute_Records = 2*no_of_char + 1 + * service_max_attribute_record = 1 for Peer To Peer service + + * 2 for P2P Write characteristic + + * 2 for P2P Notify characteristic + + * 1 for client char configuration descriptor + + * + */ + + uint16_t uuid = MATTER_SERVICE_UUID; + + aci_gatt_add_service(UUID_TYPE_16, (Service_UUID_t *) &uuid, PRIMARY_SERVICE, 8, &(aPeerToPeerContext.PeerToPeerSvcHdle)); + + /** + * Add RX Characteristic + */ + COPY_CHAR_RX_UUID(uuid16.Char_UUID_128); + aci_gatt_add_char(aPeerToPeerContext.PeerToPeerSvcHdle, UUID_TYPE_128, &uuid16, 247, CHAR_PROP_WRITE, ATTR_PERMISSION_NONE, + GATT_NOTIFY_ATTRIBUTE_WRITE | GATT_NOTIFY_WRITE_REQ_AND_WAIT_FOR_APPL_RESP, /* gattEvtMask */ + 10, /* encryKeySize */ + 1, /* isVariable */ + &(aPeerToPeerContext.P2PWriteClientToServerCharHdle)); + + /** + * Add notification Characteristic + */ + + COPY_CHAR_TX_UUID(uuid16.Char_UUID_128); + aci_gatt_add_char(aPeerToPeerContext.PeerToPeerSvcHdle, UUID_TYPE_128, &uuid16, 247, CHAR_PROP_INDICATE, ATTR_PERMISSION_NONE, + GATT_NOTIFY_ATTRIBUTE_WRITE, /* gattEvtMask */ + 10, /* encryKeySize */ + 1, /* isVariable: 1 */ + &(aPeerToPeerContext.P2PNotifyServerToClientCharHdle)); + + return; +} + +/** + * @brief Characteristic update + * @param UUID: UUID of the characteristic + * @param Service_Instance: Instance of the service to which the characteristic belongs + * + */ +tBleStatus CUSTOM_STM_App_Update_Char(uint16_t UUID, uint8_t * pPayload, uint16_t Length) +{ + tBleStatus result = BLE_STATUS_INVALID_PARAMS; + switch (UUID) + { + case P2P_NOTIFY_CHAR_UUID: + + result = aci_gatt_update_char_value(aPeerToPeerContext.PeerToPeerSvcHdle, + aPeerToPeerContext.P2PNotifyServerToClientCharHdle, 0, /* charValOffset */ + Length, /* charValueLen */ + (uint8_t *) pPayload); + + break; + + default: + break; + } + + return result; +} + +/* Private functions ----------------------------------------------------------*/ + +/** + * @brief Event handler + * @param Event: Address of the buffer holding the Event + * @retval Ack: Return whether the Event has been managed or not + */ +static SVCCTL_EvtAckStatus_t Matter_Event_Handler(void * Event) +{ + SVCCTL_EvtAckStatus_t return_value; + hci_event_pckt * event_pckt; + evt_blecore_aci * blecore_evt; + aci_gatt_attribute_modified_event_rp0 * attribute_modified; + + return_value = SVCCTL_EvtNotAck; + event_pckt = (hci_event_pckt *) (((hci_uart_pckt *) Event)->data); + + switch (event_pckt->evt) + { + case HCI_VENDOR_SPECIFIC_DEBUG_EVT_CODE: { + blecore_evt = (evt_blecore_aci *) event_pckt->data; + switch (blecore_evt->ecode) + { + case ACI_GATT_SERVER_CONFIRMATION_VSEVT_CODE: { + attribute_modified = (aci_gatt_attribute_modified_event_rp0 *) blecore_evt->data; + Notification.P2P_Evt_Opcode = MATTER_STM_ACK_INDICATE_EVT; + Notification.ConnectionHandle = attribute_modified->Connection_Handle; + APP_MATTER_Notification(&Notification); + } + case ACI_GATT_ATTRIBUTE_MODIFIED_VSEVT_CODE: { + attribute_modified = (aci_gatt_attribute_modified_event_rp0 *) blecore_evt->data; + if (attribute_modified->Attr_Handle == (aPeerToPeerContext.P2PNotifyServerToClientCharHdle + 2)) + { + /** + * Descriptor handle + */ + return_value = SVCCTL_EvtAckFlowEnable; + APP_DBG_MSG("Subscribe for c2 notification\n"); + /** + * Indicate to application + */ + if (attribute_modified->Attr_Data[0] & COMSVC_Indication) + { + Notification.P2P_Evt_Opcode = MATTER_STM_INDICATE_ENABLED_EVT; + Notification.ConnectionHandle = attribute_modified->Connection_Handle; + APP_MATTER_Notification(&Notification); + } + else + { + Notification.P2P_Evt_Opcode = MATTER_STM_INDICATE_DISABLED_EVT; + Notification.ConnectionHandle = attribute_modified->Connection_Handle; + APP_MATTER_Notification(&Notification); + } + } + + else if (attribute_modified->Attr_Handle == (aPeerToPeerContext.P2PWriteClientToServerCharHdle + 1)) + { + Notification.P2P_Evt_Opcode = MATTER_STM_WRITE_EVT; + Notification.DataTransfered.Length = attribute_modified->Attr_Data_Length; + Notification.DataTransfered.pPayload = attribute_modified->Attr_Data; + Notification.ConnectionHandle = attribute_modified->Connection_Handle; + APP_MATTER_Notification(&Notification); + } + } + break; + case ACI_GATT_WRITE_PERMIT_REQ_VSEVT_CODE: { + aci_gatt_write_permit_req_event_rp0 * write_perm_req; + write_perm_req = (aci_gatt_write_permit_req_event_rp0 *) blecore_evt->data; + aci_gatt_write_resp(write_perm_req->Connection_Handle, write_perm_req->Attribute_Handle, + 0x00, /* write_status = 0 (no error))*/ + 0x00, /* err_code */ + write_perm_req->Data_Length, (uint8_t *) &(write_perm_req->Data[0])); + } + break; + default: + break; + } + } + break; /* HCI_HCI_VENDOR_SPECIFIC_DEBUG_EVT_CODE_SPECIFIC */ + + default: + break; + } + + return (return_value); +} /* end SVCCTL_EvtAckStatus_t */ diff --git a/examples/platform/stm32/common/STM32WB5MM-DK/STM32_WPAN/App/custom_stm.h b/examples/platform/stm32/common/STM32WB5MM-DK/STM32_WPAN/App/custom_stm.h new file mode 100644 index 00000000000000..a4627c05ae9223 --- /dev/null +++ b/examples/platform/stm32/common/STM32WB5MM-DK/STM32_WPAN/App/custom_stm.h @@ -0,0 +1,134 @@ +/* USER CODE BEGIN Header */ +/** + ****************************************************************************** + * @file custom_stm.h + * @author MCD Application Team + * @brief Header for custom_stm.c module. + ****************************************************************************** + * @attention + * + * Copyright (c) 2020-2021 STMicroelectronics. + * All rights reserved. + * + * This software is licensed under terms that can be found in the LICENSE file + * in the root directory of this software component. + * If no LICENSE file comes with this software, it is provided AS-IS. + * + ****************************************************************************** + */ +/* USER CODE END Header */ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef CUSTOM_STM_H +#define CUSTOM_STM_H + +#ifdef __cplusplus +extern "C" { +#endif + +/* Includes ------------------------------------------------------------------*/ +/* USER CODE BEGIN Includes */ +#include +/* USER CODE END Includes */ + +/* Exported types ------------------------------------------------------------*/ +typedef enum +{ + /* My_P2P_Server */ + CUSTOM_STM_LED_C, + CUSTOM_STM_SWITCH_C, + /* My_Heart_Rate */ + CUSTOM_STM_HRS_M, + CUSTOM_STM_HRS_SL, + CUSTOM_STM_HRS_CTRLP, +} Custom_STM_Char_Opcode_t; + +typedef enum +{ + /* My_LED_Char */ + CUSTOM_STM_LED_C_READ_EVT, + CUSTOM_STM_LED_C_WRITE_NO_RESP_EVT, + /* My_Switch_Char */ + CUSTOM_STM_SWITCH_C_NOTIFY_ENABLED_EVT, + CUSTOM_STM_SWITCH_C_NOTIFY_DISABLED_EVT, + /* My_HRS_Meas */ + CUSTOM_STM_HRS_M_NOTIFY_ENABLED_EVT, + CUSTOM_STM_HRS_M_NOTIFY_DISABLED_EVT, + /* My_Sensor_Loc */ + CUSTOM_STM_HRS_SL_READ_EVT, + /* My_HRS_CTRL_Point */ + CUSTOM_STM_HRS_CTRLP_WRITE_EVT, + + CUSTOM_STM_BOOT_REQUEST_EVT +} Custom_STM_Opcode_evt_t; + +typedef struct +{ + uint8_t * pPayload; + uint8_t Length; +} Custom_STM_Data_t; + +typedef struct +{ + Custom_STM_Opcode_evt_t Custom_Evt_Opcode; + Custom_STM_Data_t DataTransfered; + uint16_t ConnectionHandle; + uint8_t ServiceInstance; +} Custom_STM_App_Notification_evt_t; + +/* USER CODE BEGIN ET */ +typedef enum +{ + CUSTOM_STM_HRS_HRM_VALUE_FORMAT_UINT16 = 1, + CUSTOM_STM_HRS_HRM_SENSOR_CONTACTS_PRESENT = 2, + CUSTOM_STM_HRS_HRM_SENSOR_CONTACTS_SUPPORTED = 4, + CUSTOM_STM_HRS_HRM_ENERGY_EXPENDED_PRESENT = 8, + CUSTOM_STM_HRS_HRM_RR_INTERVAL_PRESENT = 0x10 +} Custom_STM_HRS_HrmFlags_t; + +typedef enum +{ + CUSTOM_STM_HRS_BODY_SENSOR_LOCATION_OTHER = 0, + CUSTOM_STM_HRS_BODY_SENSOR_LOCATION_CHEST = 1, + CUSTOM_STM_HRS_BODY_SENSOR_LOCATION_WRIST = 2, + CUSTOM_STM_HRS_BODY_SENSOR_LOCATION_FINGER = 3, + CUSTOM_STM_HRS_BODY_SENSOR_LOCATION_HAND = 4, + CUSTOM_STM_HRS_BODY_SENSOR_LOCATION_EAR_LOBE = 5, + CUSTOM_STM_HRS_BODY_SENSOR_LOCATION_FOOT = 6 +} Custom_STM_HRS_BodySensorLocation_t; + +/* USER CODE END ET */ + +/* Exported constants --------------------------------------------------------*/ +extern uint8_t SizeLed_C; +extern uint8_t SizeSwitch_C; +extern uint8_t SizeHrs_M; +extern uint8_t SizeHrs_Sl; +extern uint8_t SizeHrs_Ctrlp; + +/* USER CODE BEGIN EC */ + +/* USER CODE END EC */ + +/* External variables --------------------------------------------------------*/ +/* USER CODE BEGIN EV */ + +/* USER CODE END EV */ + +/* Exported macros -----------------------------------------------------------*/ +/* USER CODE BEGIN EM */ + +/* USER CODE END EM */ + +/* Exported functions ------------------------------------------------------- */ +void SVCCTL_InitCustomSvc(void); +tBleStatus CUSTOM_STM_App_Update_Char(uint16_t UUID, uint8_t * pPayload, uint16_t Length); +/* USER CODE BEGIN EF */ + +/* USER CODE END EF */ + +#ifdef __cplusplus +} +#endif + +#endif /*CUSTOM_STM_H */ diff --git a/examples/platform/stm32/common/STM32WB5MM-DK/STM32_WPAN/App/tl_dbg_conf.h b/examples/platform/stm32/common/STM32WB5MM-DK/STM32_WPAN/App/tl_dbg_conf.h new file mode 100644 index 00000000000000..4a56cfea5fc562 --- /dev/null +++ b/examples/platform/stm32/common/STM32WB5MM-DK/STM32_WPAN/App/tl_dbg_conf.h @@ -0,0 +1,123 @@ +/** + ****************************************************************************** + * File Name : tl_dbg_conf.h + * Description : Debug configuration file for stm32wpan transport layer interface. + * + ****************************************************************************** + * @attention + * + * Copyright (c) 2019-2021 STMicroelectronics. + * All rights reserved. + * + * This software is licensed under terms that can be found in the LICENSE file + * in the root directory of this software component. + * If no LICENSE file comes with this software, it is provided AS-IS. + * + ****************************************************************************** + */ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef __TL_DBG_CONF_H +#define __TL_DBG_CONF_H + +/* USER CODE BEGIN Tl_Conf */ + +/* Includes ------------------------------------------------------------------*/ +#include "app_conf.h" /* required as some configuration used in dbg_trace.h are set there */ +#include "dbg_trace.h" +#include "hw_if.h" + +/** + * Enable or Disable traces + * The raw data output is the hci binary packet format as specified by the BT specification * + */ +#define TL_SHCI_CMD_DBG_EN 0 /* Reports System commands sent to CPU2 and the command response */ +#define TL_SHCI_CMD_DBG_RAW_EN 0 /* Reports raw data System commands sent to CPU2 and the command response */ +#define TL_SHCI_EVT_DBG_EN 0 /* Reports System Asynchronous Events received from CPU2 */ +#define TL_SHCI_EVT_DBG_RAW_EN 0 /* Reports raw data System Asynchronous Events received from CPU2 */ + +#define TL_HCI_CMD_DBG_EN 0 /* Reports BLE command sent to CPU2 and the command response */ +#define TL_HCI_CMD_DBG_RAW_EN 0 /* Reports raw data BLE command sent to CPU2 and the command response */ +#define TL_HCI_EVT_DBG_EN 0 /* Reports BLE Asynchronous Events received from CPU2 */ +#define TL_HCI_EVT_DBG_RAW_EN 0 /* Reports raw data BLE Asynchronous Events received from CPU2 */ + +#define TL_MM_DBG_EN 0 /* Reports the information of the buffer released to CPU2 */ + +/** + * Macro definition + */ + +/** + * System Transport Layer + */ +#if (TL_SHCI_CMD_DBG_EN != 0) +#define TL_SHCI_CMD_DBG_MSG PRINT_MESG_DBG +#define TL_SHCI_CMD_DBG_BUF PRINT_LOG_BUFF_DBG +#else +#define TL_SHCI_CMD_DBG_MSG(...) +#define TL_SHCI_CMD_DBG_BUF(...) +#endif + +#if (TL_SHCI_CMD_DBG_RAW_EN != 0) +#define TL_SHCI_CMD_DBG_RAW(_PDATA_, _SIZE_) HW_UART_Transmit(hw_uart1, (uint8_t *) _PDATA_, _SIZE_, (~0)) +#else +#define TL_SHCI_CMD_DBG_RAW(...) +#endif + +#if (TL_SHCI_EVT_DBG_EN != 0) +#define TL_SHCI_EVT_DBG_MSG PRINT_MESG_DBG +#define TL_SHCI_EVT_DBG_BUF PRINT_LOG_BUFF_DBG +#else +#define TL_SHCI_EVT_DBG_MSG(...) +#define TL_SHCI_EVT_DBG_BUF(...) +#endif + +#if (TL_SHCI_EVT_DBG_RAW_EN != 0) +#define TL_SHCI_EVT_DBG_RAW(_PDATA_, _SIZE_) HW_UART_Transmit(hw_uart1, (uint8_t *) _PDATA_, _SIZE_, (~0)) +#else +#define TL_SHCI_EVT_DBG_RAW(...) +#endif + +/** + * BLE Transport Layer + */ +#if (TL_HCI_CMD_DBG_EN != 0) +#define TL_HCI_CMD_DBG_MSG PRINT_MESG_DBG +#define TL_HCI_CMD_DBG_BUF PRINT_LOG_BUFF_DBG +#else +#define TL_HCI_CMD_DBG_MSG(...) +#define TL_HCI_CMD_DBG_BUF(...) +#endif + +#if (TL_HCI_CMD_DBG_RAW_EN != 0) +#define TL_HCI_CMD_DBG_RAW(_PDATA_, _SIZE_) HW_UART_Transmit(hw_uart1, (uint8_t *) _PDATA_, _SIZE_, (~0)) +#else +#define TL_HCI_CMD_DBG_RAW(...) +#endif + +#if (TL_HCI_EVT_DBG_EN != 0) +#define TL_HCI_EVT_DBG_MSG PRINT_MESG_DBG +#define TL_HCI_EVT_DBG_BUF PRINT_LOG_BUFF_DBG +#else +#define TL_HCI_EVT_DBG_MSG(...) +#define TL_HCI_EVT_DBG_BUF(...) +#endif + +#if (TL_HCI_EVT_DBG_RAW_EN != 0) +#define TL_HCI_EVT_DBG_RAW(_PDATA_, _SIZE_) HW_UART_Transmit(hw_uart1, (uint8_t *) _PDATA_, _SIZE_, (~0)) +#else +#define TL_HCI_EVT_DBG_RAW(...) +#endif + +/** + * Memory Manager - Released buffer tracing + */ +#if (TL_MM_DBG_EN != 0) +#define TL_MM_DBG_MSG PRINT_MESG_DBG +#else +#define TL_MM_DBG_MSG(...) +#endif + +/* USER CODE END Tl_Conf */ + +#endif /*__TL_DBG_CONF_H */ diff --git a/examples/platform/stm32/common/STM32WB5MM-DK/STM32_WPAN/Target/hw_ipcc.c b/examples/platform/stm32/common/STM32WB5MM-DK/STM32_WPAN/Target/hw_ipcc.c new file mode 100644 index 00000000000000..7e1f5d5d43348f --- /dev/null +++ b/examples/platform/stm32/common/STM32WB5MM-DK/STM32_WPAN/Target/hw_ipcc.c @@ -0,0 +1,667 @@ +/** + ****************************************************************************** + * File Name : Target/hw_ipcc.c + * Description : Hardware IPCC source file for STM32WPAN Middleware. + * + ****************************************************************************** + * @attention + * + * Copyright (c) 2019-2021 STMicroelectronics. + * All rights reserved. + * + * This software is licensed under terms that can be found in the LICENSE file + * in the root directory of this software component. + * If no LICENSE file comes with this software, it is provided AS-IS. + * + ****************************************************************************** + */ + +/* Includes ------------------------------------------------------------------*/ +#include "app_common.h" +#include "mbox_def.h" + +/* Global variables ---------------------------------------------------------*/ +/* Private defines -----------------------------------------------------------*/ +#define HW_IPCC_TX_PENDING(channel) (!(LL_C1_IPCC_IsActiveFlag_CHx(IPCC, channel))) && (((~(IPCC->C1MR)) & (channel << 16U))) +#define HW_IPCC_RX_PENDING(channel) (LL_C2_IPCC_IsActiveFlag_CHx(IPCC, channel)) && (((~(IPCC->C1MR)) & (channel << 0U))) + +/* Private macros ------------------------------------------------------------*/ +/* Private typedef -----------------------------------------------------------*/ +/* Private variables ---------------------------------------------------------*/ +static void (*FreeBufCb)(void); + +/* Private function prototypes -----------------------------------------------*/ +static void HW_IPCC_BLE_EvtHandler(void); +static void HW_IPCC_BLE_AclDataEvtHandler(void); +static void HW_IPCC_MM_FreeBufHandler(void); +static void HW_IPCC_SYS_CmdEvtHandler(void); +static void HW_IPCC_SYS_EvtHandler(void); +static void HW_IPCC_TRACES_EvtHandler(void); + +#ifdef THREAD_WB +static void HW_IPCC_OT_CmdEvtHandler(void); +static void HW_IPCC_THREAD_NotEvtHandler(void); +static void HW_IPCC_THREAD_CliNotEvtHandler(void); +#endif + +#ifdef LLD_TESTS_WB +static void HW_IPCC_LLDTESTS_ReceiveCliRspHandler(void); +static void HW_IPCC_LLDTESTS_ReceiveM0CmdHandler(void); +#endif +#ifdef LLD_BLE_WB +/*static void HW_IPCC_LLD_BLE_ReceiveCliRspHandler( void );*/ +static void HW_IPCC_LLD_BLE_ReceiveRspHandler(void); +static void HW_IPCC_LLD_BLE_ReceiveM0CmdHandler(void); +#endif + +#ifdef MAC_802_15_4_WB +static void HW_IPCC_MAC_802_15_4_CmdEvtHandler(void); +static void HW_IPCC_MAC_802_15_4_NotEvtHandler(void); +#endif + +#ifdef ZIGBEE_WB +static void HW_IPCC_ZIGBEE_CmdEvtHandler(void); +static void HW_IPCC_ZIGBEE_StackNotifEvtHandler(void); +static void HW_IPCC_ZIGBEE_StackM0RequestHandler(void); +#endif + +/* Public function definition -----------------------------------------------*/ + +/****************************************************************************** + * INTERRUPT HANDLER + ******************************************************************************/ +void HW_IPCC_Rx_Handler(void) +{ + if (HW_IPCC_RX_PENDING(HW_IPCC_SYSTEM_EVENT_CHANNEL)) + { + HW_IPCC_SYS_EvtHandler(); + } +#ifdef MAC_802_15_4_WB + else if (HW_IPCC_RX_PENDING(HW_IPCC_MAC_802_15_4_NOTIFICATION_ACK_CHANNEL)) + { + HW_IPCC_MAC_802_15_4_NotEvtHandler(); + } +#endif /* MAC_802_15_4_WB */ +#ifdef THREAD_WB + else if (HW_IPCC_RX_PENDING(HW_IPCC_THREAD_NOTIFICATION_ACK_CHANNEL)) + { + HW_IPCC_THREAD_NotEvtHandler(); + } + else if (HW_IPCC_RX_PENDING(HW_IPCC_THREAD_CLI_NOTIFICATION_ACK_CHANNEL)) + { + HW_IPCC_THREAD_CliNotEvtHandler(); + } +#endif /* THREAD_WB */ +#ifdef LLD_TESTS_WB + else if (HW_IPCC_RX_PENDING(HW_IPCC_LLDTESTS_CLI_RSP_CHANNEL)) + { + HW_IPCC_LLDTESTS_ReceiveCliRspHandler(); + } + else if (HW_IPCC_RX_PENDING(HW_IPCC_LLDTESTS_M0_CMD_CHANNEL)) + { + HW_IPCC_LLDTESTS_ReceiveM0CmdHandler(); + } +#endif /* LLD_TESTS_WB */ +#ifdef LLD_BLE_WB + else if (HW_IPCC_RX_PENDING(HW_IPCC_LLD_BLE_RSP_CHANNEL)) + { + HW_IPCC_LLD_BLE_ReceiveRspHandler(); + } + else if (HW_IPCC_RX_PENDING(HW_IPCC_LLD_BLE_M0_CMD_CHANNEL)) + { + HW_IPCC_LLD_BLE_ReceiveM0CmdHandler(); + } +#endif /* LLD_TESTS_WB */ +#ifdef ZIGBEE_WB + else if (HW_IPCC_RX_PENDING(HW_IPCC_ZIGBEE_APPLI_NOTIF_ACK_CHANNEL)) + { + HW_IPCC_ZIGBEE_StackNotifEvtHandler(); + } + else if (HW_IPCC_RX_PENDING(HW_IPCC_ZIGBEE_M0_REQUEST_CHANNEL)) + { + HW_IPCC_ZIGBEE_StackM0RequestHandler(); + } +#endif /* ZIGBEE_WB */ + else if (HW_IPCC_RX_PENDING(HW_IPCC_BLE_EVENT_CHANNEL)) + { + HW_IPCC_BLE_EvtHandler(); + } + else if (HW_IPCC_RX_PENDING(HW_IPCC_TRACES_CHANNEL)) + { + HW_IPCC_TRACES_EvtHandler(); + } + + return; +} + +void HW_IPCC_Tx_Handler(void) +{ + if (HW_IPCC_TX_PENDING(HW_IPCC_SYSTEM_CMD_RSP_CHANNEL)) + { + HW_IPCC_SYS_CmdEvtHandler(); + } +#ifdef MAC_802_15_4_WB + else if (HW_IPCC_TX_PENDING(HW_IPCC_MAC_802_15_4_CMD_RSP_CHANNEL)) + { + HW_IPCC_MAC_802_15_4_CmdEvtHandler(); + } +#endif /* MAC_802_15_4_WB */ +#ifdef THREAD_WB + else if (HW_IPCC_TX_PENDING(HW_IPCC_THREAD_OT_CMD_RSP_CHANNEL)) + { + HW_IPCC_OT_CmdEvtHandler(); + } +#endif /* THREAD_WB */ +#ifdef LLD_TESTS_WB +// No TX handler for LLD tests +#endif /* LLD_TESTS_WB */ +#ifdef ZIGBEE_WB + if (HW_IPCC_TX_PENDING(HW_IPCC_ZIGBEE_CMD_APPLI_CHANNEL)) + { + HW_IPCC_ZIGBEE_CmdEvtHandler(); + } +#endif /* ZIGBEE_WB */ + + else if (HW_IPCC_TX_PENDING(HW_IPCC_MM_RELEASE_BUFFER_CHANNEL)) + { + HW_IPCC_MM_FreeBufHandler(); + } + else if (HW_IPCC_TX_PENDING(HW_IPCC_HCI_ACL_DATA_CHANNEL)) + { + HW_IPCC_BLE_AclDataEvtHandler(); + } + + return; +} +/****************************************************************************** + * GENERAL + ******************************************************************************/ +void HW_IPCC_Enable(void) +{ + /** + * Such as IPCC IP available to the CPU2, it is required to keep the IPCC clock running + when FUS is running on CPU2 and CPU1 enters deep sleep mode + */ + LL_C2_AHB3_GRP1_EnableClock(LL_C2_AHB3_GRP1_PERIPH_IPCC); + + /** + * When the device is out of standby, it is required to use the EXTI mechanism to wakeup CPU2 + */ + LL_C2_EXTI_EnableEvent_32_63(LL_EXTI_LINE_41); + LL_EXTI_EnableRisingTrig_32_63(LL_EXTI_LINE_41); + + /** + * In case the SBSFU is implemented, it may have already set the C2BOOT bit to startup the CPU2. + * In that case, to keep the mechanism transparent to the user application, it shall call the system command + * SHCI_C2_Reinit( ) before jumping to the application. + * When the CPU2 receives that command, it waits for its event input to be set to restart the CPU2 firmware. + * This is required because once C2BOOT has been set once, a clear/set on C2BOOT has no effect. + * When SHCI_C2_Reinit( ) is not called, generating an event to the CPU2 does not have any effect + * So, by default, the application shall both set the event flag and set the C2BOOT bit. + */ + __SEV(); /* Set the internal event flag and send an event to the CPU2 */ + __WFE(); /* Clear the internal event flag */ + LL_PWR_EnableBootC2(); + + return; +} + +void HW_IPCC_Init(void) +{ + LL_AHB3_GRP1_EnableClock(LL_AHB3_GRP1_PERIPH_IPCC); + + LL_C1_IPCC_EnableIT_RXO(IPCC); + LL_C1_IPCC_EnableIT_TXF(IPCC); + + HAL_NVIC_EnableIRQ(IPCC_C1_RX_IRQn); + HAL_NVIC_EnableIRQ(IPCC_C1_TX_IRQn); + + return; +} + +/****************************************************************************** + * BLE + ******************************************************************************/ +void HW_IPCC_BLE_Init(void) +{ + LL_C1_IPCC_EnableReceiveChannel(IPCC, HW_IPCC_BLE_EVENT_CHANNEL); + + return; +} + +void HW_IPCC_BLE_SendCmd(void) +{ + LL_C1_IPCC_SetFlag_CHx(IPCC, HW_IPCC_BLE_CMD_CHANNEL); + + return; +} + +static void HW_IPCC_BLE_EvtHandler(void) +{ + HW_IPCC_BLE_RxEvtNot(); + + LL_C1_IPCC_ClearFlag_CHx(IPCC, HW_IPCC_BLE_EVENT_CHANNEL); + + return; +} + +void HW_IPCC_BLE_SendAclData(void) +{ + LL_C1_IPCC_SetFlag_CHx(IPCC, HW_IPCC_HCI_ACL_DATA_CHANNEL); + LL_C1_IPCC_EnableTransmitChannel(IPCC, HW_IPCC_HCI_ACL_DATA_CHANNEL); + + return; +} + +static void HW_IPCC_BLE_AclDataEvtHandler(void) +{ + LL_C1_IPCC_DisableTransmitChannel(IPCC, HW_IPCC_HCI_ACL_DATA_CHANNEL); + + HW_IPCC_BLE_AclDataAckNot(); + + return; +} + +__weak void HW_IPCC_BLE_AclDataAckNot(void){}; +__weak void HW_IPCC_BLE_RxEvtNot(void){}; + +/****************************************************************************** + * SYSTEM + ******************************************************************************/ +void HW_IPCC_SYS_Init(void) +{ + LL_C1_IPCC_EnableReceiveChannel(IPCC, HW_IPCC_SYSTEM_EVENT_CHANNEL); + + return; +} + +void HW_IPCC_SYS_SendCmd(void) +{ + LL_C1_IPCC_SetFlag_CHx(IPCC, HW_IPCC_SYSTEM_CMD_RSP_CHANNEL); + LL_C1_IPCC_EnableTransmitChannel(IPCC, HW_IPCC_SYSTEM_CMD_RSP_CHANNEL); + + return; +} + +static void HW_IPCC_SYS_CmdEvtHandler(void) +{ + LL_C1_IPCC_DisableTransmitChannel(IPCC, HW_IPCC_SYSTEM_CMD_RSP_CHANNEL); + + HW_IPCC_SYS_CmdEvtNot(); + + return; +} + +static void HW_IPCC_SYS_EvtHandler(void) +{ + HW_IPCC_SYS_EvtNot(); + + LL_C1_IPCC_ClearFlag_CHx(IPCC, HW_IPCC_SYSTEM_EVENT_CHANNEL); + + return; +} + +__weak void HW_IPCC_SYS_CmdEvtNot(void){}; +__weak void HW_IPCC_SYS_EvtNot(void){}; + +/****************************************************************************** + * MAC 802.15.4 + ******************************************************************************/ +#ifdef MAC_802_15_4_WB +void HW_IPCC_MAC_802_15_4_Init(void) +{ + LL_C1_IPCC_EnableReceiveChannel(IPCC, HW_IPCC_MAC_802_15_4_NOTIFICATION_ACK_CHANNEL); + + return; +} + +void HW_IPCC_MAC_802_15_4_SendCmd(void) +{ + LL_C1_IPCC_SetFlag_CHx(IPCC, HW_IPCC_MAC_802_15_4_CMD_RSP_CHANNEL); + LL_C1_IPCC_EnableTransmitChannel(IPCC, HW_IPCC_MAC_802_15_4_CMD_RSP_CHANNEL); + + return; +} + +void HW_IPCC_MAC_802_15_4_SendAck(void) +{ + LL_C1_IPCC_ClearFlag_CHx(IPCC, HW_IPCC_MAC_802_15_4_NOTIFICATION_ACK_CHANNEL); + LL_C1_IPCC_EnableReceiveChannel(IPCC, HW_IPCC_MAC_802_15_4_NOTIFICATION_ACK_CHANNEL); + + return; +} + +static void HW_IPCC_MAC_802_15_4_CmdEvtHandler(void) +{ + LL_C1_IPCC_DisableTransmitChannel(IPCC, HW_IPCC_MAC_802_15_4_CMD_RSP_CHANNEL); + + HW_IPCC_MAC_802_15_4_CmdEvtNot(); + + return; +} + +static void HW_IPCC_MAC_802_15_4_NotEvtHandler(void) +{ + LL_C1_IPCC_DisableReceiveChannel(IPCC, HW_IPCC_MAC_802_15_4_NOTIFICATION_ACK_CHANNEL); + + HW_IPCC_MAC_802_15_4_EvtNot(); + + return; +} +__weak void HW_IPCC_MAC_802_15_4_CmdEvtNot(void){}; +__weak void HW_IPCC_MAC_802_15_4_EvtNot(void){}; +#endif + +/****************************************************************************** + * THREAD + ******************************************************************************/ +#ifdef THREAD_WB +void HW_IPCC_THREAD_Init(void) +{ + LL_C1_IPCC_EnableReceiveChannel(IPCC, HW_IPCC_THREAD_NOTIFICATION_ACK_CHANNEL); + LL_C1_IPCC_EnableReceiveChannel(IPCC, HW_IPCC_THREAD_CLI_NOTIFICATION_ACK_CHANNEL); + + return; +} + +void HW_IPCC_OT_SendCmd(void) +{ + LL_C1_IPCC_SetFlag_CHx(IPCC, HW_IPCC_THREAD_OT_CMD_RSP_CHANNEL); + LL_C1_IPCC_EnableTransmitChannel(IPCC, HW_IPCC_THREAD_OT_CMD_RSP_CHANNEL); + + return; +} + +void HW_IPCC_CLI_SendCmd(void) +{ + LL_C1_IPCC_SetFlag_CHx(IPCC, HW_IPCC_THREAD_CLI_CMD_CHANNEL); + + return; +} + +void HW_IPCC_THREAD_SendAck(void) +{ + LL_C1_IPCC_ClearFlag_CHx(IPCC, HW_IPCC_THREAD_NOTIFICATION_ACK_CHANNEL); + LL_C1_IPCC_EnableReceiveChannel(IPCC, HW_IPCC_THREAD_NOTIFICATION_ACK_CHANNEL); + + return; +} + +void HW_IPCC_THREAD_CliSendAck(void) +{ + LL_C1_IPCC_ClearFlag_CHx(IPCC, HW_IPCC_THREAD_CLI_NOTIFICATION_ACK_CHANNEL); + LL_C1_IPCC_EnableReceiveChannel(IPCC, HW_IPCC_THREAD_CLI_NOTIFICATION_ACK_CHANNEL); + + return; +} + +static void HW_IPCC_OT_CmdEvtHandler(void) +{ + LL_C1_IPCC_DisableTransmitChannel(IPCC, HW_IPCC_THREAD_OT_CMD_RSP_CHANNEL); + + HW_IPCC_OT_CmdEvtNot(); + + return; +} + +static void HW_IPCC_THREAD_NotEvtHandler(void) +{ + LL_C1_IPCC_DisableReceiveChannel(IPCC, HW_IPCC_THREAD_NOTIFICATION_ACK_CHANNEL); + + HW_IPCC_THREAD_EvtNot(); + + return; +} + +static void HW_IPCC_THREAD_CliNotEvtHandler(void) +{ + LL_C1_IPCC_DisableReceiveChannel(IPCC, HW_IPCC_THREAD_CLI_NOTIFICATION_ACK_CHANNEL); + + HW_IPCC_THREAD_CliEvtNot(); + + return; +} + +__weak void HW_IPCC_OT_CmdEvtNot(void){}; +__weak void HW_IPCC_CLI_CmdEvtNot(void){}; +__weak void HW_IPCC_THREAD_EvtNot(void){}; + +#endif /* THREAD_WB */ + +/****************************************************************************** + * LLD TESTS + ******************************************************************************/ +#ifdef LLD_TESTS_WB +void HW_IPCC_LLDTESTS_Init(void) +{ + LL_C1_IPCC_EnableReceiveChannel(IPCC, HW_IPCC_LLDTESTS_CLI_RSP_CHANNEL); + LL_C1_IPCC_EnableReceiveChannel(IPCC, HW_IPCC_LLDTESTS_M0_CMD_CHANNEL); + return; +} + +void HW_IPCC_LLDTESTS_SendCliCmd(void) +{ + LL_C1_IPCC_SetFlag_CHx(IPCC, HW_IPCC_LLDTESTS_CLI_CMD_CHANNEL); + return; +} + +static void HW_IPCC_LLDTESTS_ReceiveCliRspHandler(void) +{ + LL_C1_IPCC_DisableReceiveChannel(IPCC, HW_IPCC_LLDTESTS_CLI_RSP_CHANNEL); + HW_IPCC_LLDTESTS_ReceiveCliRsp(); + return; +} + +void HW_IPCC_LLDTESTS_SendCliRspAck(void) +{ + LL_C1_IPCC_ClearFlag_CHx(IPCC, HW_IPCC_LLDTESTS_CLI_RSP_CHANNEL); + LL_C1_IPCC_EnableReceiveChannel(IPCC, HW_IPCC_LLDTESTS_CLI_RSP_CHANNEL); + return; +} + +static void HW_IPCC_LLDTESTS_ReceiveM0CmdHandler(void) +{ + LL_C1_IPCC_DisableReceiveChannel(IPCC, HW_IPCC_LLDTESTS_M0_CMD_CHANNEL); + HW_IPCC_LLDTESTS_ReceiveM0Cmd(); + return; +} + +void HW_IPCC_LLDTESTS_SendM0CmdAck(void) +{ + LL_C1_IPCC_ClearFlag_CHx(IPCC, HW_IPCC_LLDTESTS_M0_CMD_CHANNEL); + LL_C1_IPCC_EnableReceiveChannel(IPCC, HW_IPCC_LLDTESTS_M0_CMD_CHANNEL); + return; +} +__weak void HW_IPCC_LLDTESTS_ReceiveCliRsp(void){}; +__weak void HW_IPCC_LLDTESTS_ReceiveM0Cmd(void){}; +#endif /* LLD_TESTS_WB */ + +/****************************************************************************** + * LLD BLE + ******************************************************************************/ +#ifdef LLD_BLE_WB +void HW_IPCC_LLD_BLE_Init(void) +{ + LL_C1_IPCC_EnableReceiveChannel(IPCC, HW_IPCC_LLD_BLE_RSP_CHANNEL); + LL_C1_IPCC_EnableReceiveChannel(IPCC, HW_IPCC_LLD_BLE_M0_CMD_CHANNEL); + return; +} + +void HW_IPCC_LLD_BLE_SendCliCmd(void) +{ + LL_C1_IPCC_SetFlag_CHx(IPCC, HW_IPCC_LLD_BLE_CLI_CMD_CHANNEL); + return; +} + +/*static void HW_IPCC_LLD_BLE_ReceiveCliRspHandler( void ) +{ + LL_C1_IPCC_DisableReceiveChannel( IPCC, HW_IPCC_LLD_BLE_CLI_RSP_CHANNEL ); + HW_IPCC_LLD_BLE_ReceiveCliRsp(); + return; +}*/ + +void HW_IPCC_LLD_BLE_SendCliRspAck(void) +{ + LL_C1_IPCC_ClearFlag_CHx(IPCC, HW_IPCC_LLD_BLE_CLI_RSP_CHANNEL); + LL_C1_IPCC_EnableReceiveChannel(IPCC, HW_IPCC_LLD_BLE_CLI_RSP_CHANNEL); + return; +} + +static void HW_IPCC_LLD_BLE_ReceiveM0CmdHandler(void) +{ + // LL_C1_IPCC_DisableReceiveChannel( IPCC, HW_IPCC_LLD_BLE_M0_CMD_CHANNEL ); + HW_IPCC_LLD_BLE_ReceiveM0Cmd(); + return; +} + +void HW_IPCC_LLD_BLE_SendM0CmdAck(void) +{ + LL_C1_IPCC_ClearFlag_CHx(IPCC, HW_IPCC_LLD_BLE_M0_CMD_CHANNEL); + // LL_C1_IPCC_EnableReceiveChannel( IPCC, HW_IPCC_LLD_BLE_M0_CMD_CHANNEL ); + return; +} +__weak void HW_IPCC_LLD_BLE_ReceiveCliRsp(void){}; +__weak void HW_IPCC_LLD_BLE_ReceiveM0Cmd(void){}; + +/* Transparent Mode */ +void HW_IPCC_LLD_BLE_SendCmd(void) +{ + LL_C1_IPCC_SetFlag_CHx(IPCC, HW_IPCC_LLD_BLE_CMD_CHANNEL); + return; +} + +static void HW_IPCC_LLD_BLE_ReceiveRspHandler(void) +{ + LL_C1_IPCC_DisableReceiveChannel(IPCC, HW_IPCC_LLD_BLE_RSP_CHANNEL); + HW_IPCC_LLD_BLE_ReceiveRsp(); + return; +} + +void HW_IPCC_LLD_BLE_SendRspAck(void) +{ + LL_C1_IPCC_ClearFlag_CHx(IPCC, HW_IPCC_LLD_BLE_RSP_CHANNEL); + LL_C1_IPCC_EnableReceiveChannel(IPCC, HW_IPCC_LLD_BLE_RSP_CHANNEL); + return; +} + +#endif /* LLD_BLE_WB */ + +/****************************************************************************** + * ZIGBEE + ******************************************************************************/ +#ifdef ZIGBEE_WB +void HW_IPCC_ZIGBEE_Init(void) +{ + LL_C1_IPCC_EnableReceiveChannel(IPCC, HW_IPCC_ZIGBEE_APPLI_NOTIF_ACK_CHANNEL); + LL_C1_IPCC_EnableReceiveChannel(IPCC, HW_IPCC_ZIGBEE_M0_REQUEST_CHANNEL); + + return; +} + +void HW_IPCC_ZIGBEE_SendM4RequestToM0(void) +{ + LL_C1_IPCC_SetFlag_CHx(IPCC, HW_IPCC_ZIGBEE_CMD_APPLI_CHANNEL); + LL_C1_IPCC_EnableTransmitChannel(IPCC, HW_IPCC_ZIGBEE_CMD_APPLI_CHANNEL); + + return; +} + +void HW_IPCC_ZIGBEE_SendM4AckToM0Notify(void) +{ + LL_C1_IPCC_ClearFlag_CHx(IPCC, HW_IPCC_ZIGBEE_APPLI_NOTIF_ACK_CHANNEL); + LL_C1_IPCC_EnableReceiveChannel(IPCC, HW_IPCC_ZIGBEE_APPLI_NOTIF_ACK_CHANNEL); + + return; +} + +static void HW_IPCC_ZIGBEE_CmdEvtHandler(void) +{ + LL_C1_IPCC_DisableTransmitChannel(IPCC, HW_IPCC_ZIGBEE_CMD_APPLI_CHANNEL); + + HW_IPCC_ZIGBEE_RecvAppliAckFromM0(); + + return; +} + +static void HW_IPCC_ZIGBEE_StackNotifEvtHandler(void) +{ + LL_C1_IPCC_DisableReceiveChannel(IPCC, HW_IPCC_ZIGBEE_APPLI_NOTIF_ACK_CHANNEL); + + HW_IPCC_ZIGBEE_RecvM0NotifyToM4(); + + return; +} + +static void HW_IPCC_ZIGBEE_StackM0RequestHandler(void) +{ + LL_C1_IPCC_DisableReceiveChannel(IPCC, HW_IPCC_ZIGBEE_M0_REQUEST_CHANNEL); + + HW_IPCC_ZIGBEE_RecvM0RequestToM4(); + + return; +} + +void HW_IPCC_ZIGBEE_SendM4AckToM0Request(void) +{ + LL_C1_IPCC_ClearFlag_CHx(IPCC, HW_IPCC_ZIGBEE_M0_REQUEST_CHANNEL); + LL_C1_IPCC_EnableReceiveChannel(IPCC, HW_IPCC_ZIGBEE_M0_REQUEST_CHANNEL); + + return; +} + +__weak void HW_IPCC_ZIGBEE_RecvAppliAckFromM0(void){}; +__weak void HW_IPCC_ZIGBEE_RecvM0NotifyToM4(void){}; +__weak void HW_IPCC_ZIGBEE_RecvM0RequestToM4(void){}; +#endif /* ZIGBEE_WB */ + +/****************************************************************************** + * MEMORY MANAGER + ******************************************************************************/ +void HW_IPCC_MM_SendFreeBuf(void (*cb)(void)) +{ + if (LL_C1_IPCC_IsActiveFlag_CHx(IPCC, HW_IPCC_MM_RELEASE_BUFFER_CHANNEL)) + { + FreeBufCb = cb; + LL_C1_IPCC_EnableTransmitChannel(IPCC, HW_IPCC_MM_RELEASE_BUFFER_CHANNEL); + } + else + { + cb(); + + LL_C1_IPCC_SetFlag_CHx(IPCC, HW_IPCC_MM_RELEASE_BUFFER_CHANNEL); + } + + return; +} + +static void HW_IPCC_MM_FreeBufHandler(void) +{ + LL_C1_IPCC_DisableTransmitChannel(IPCC, HW_IPCC_MM_RELEASE_BUFFER_CHANNEL); + + FreeBufCb(); + + LL_C1_IPCC_SetFlag_CHx(IPCC, HW_IPCC_MM_RELEASE_BUFFER_CHANNEL); + + return; +} + +/****************************************************************************** + * TRACES + ******************************************************************************/ +void HW_IPCC_TRACES_Init(void) +{ + LL_C1_IPCC_EnableReceiveChannel(IPCC, HW_IPCC_TRACES_CHANNEL); + + return; +} + +static void HW_IPCC_TRACES_EvtHandler(void) +{ + HW_IPCC_TRACES_EvtNot(); + + LL_C1_IPCC_ClearFlag_CHx(IPCC, HW_IPCC_TRACES_CHANNEL); + + return; +} + +__weak void HW_IPCC_TRACES_EvtNot(void){}; diff --git a/examples/platform/stm32/common/STM32WB5MM-DK/Src/app_entry.cpp b/examples/platform/stm32/common/STM32WB5MM-DK/Src/app_entry.cpp new file mode 100644 index 00000000000000..4d828c6cd4ffee --- /dev/null +++ b/examples/platform/stm32/common/STM32WB5MM-DK/Src/app_entry.cpp @@ -0,0 +1,583 @@ +/* USER CODE BEGIN Header */ +/** + ****************************************************************************** + * File Name : app_entry.c + * Description : Entry application source file for STM32WPAN Middleware. + ****************************************************************************** + * @attention + * + * Copyright (c) 2019-2021 STMicroelectronics. + * All rights reserved. + * + * This software is licensed under terms that can be found in the LICENSE file + * in the root directory of this software component. + * If no LICENSE file comes with this software, it is provided AS-IS. + * + ****************************************************************************** + */ +/* USER CODE END Header */ + +/* Includes ------------------------------------------------------------------*/ +#include "app_entry.h" +#include "app_ble.h" +#include "app_common.h" +#include "app_conf.h" +#include "app_thread.h" +#include "cmsis_os.h" +#include "dbg_trace.h" +#include "hw_conf.h" +#include "main.h" +#include "shci.h" +#include "shci_tl.h" +#include "ssd1315.h" +#include "stm32_lcd.h" +#include "stm32_lpm.h" +#include "stm32wb5mm_dk_lcd.h" +#include "stm_logging.h" + +#include "AppTask.h" +/* Private includes -----------------------------------------------------------*/ +/* USER CODE BEGIN Includes */ + +/* USER CODE END Includes */ + +/* Private typedef -----------------------------------------------------------*/ +/* USER CODE BEGIN PTD */ + +/* USER CODE END PTD */ + +/* Private defines -----------------------------------------------------------*/ +/* POOL_SIZE = 2(TL_PacketHeader_t) + 258 (3(TL_EVT_HDR_SIZE) + 255(Payload size)) */ +#define POOL_SIZE (CFG_TLBLE_EVT_QUEUE_LENGTH * 4 * DIVC((sizeof(TL_PacketHeader_t) + TL_BLE_EVENT_FRAME_SIZE), 4)) +/* USER CODE BEGIN PD */ + +/* USER CODE END PD */ + +/* Private macros ------------------------------------------------------------*/ +/* USER CODE BEGIN PM */ + +/* USER CODE END PM */ + +/* Private variables ---------------------------------------------------------*/ + +extern RTC_HandleTypeDef hrtc; /**< RTC handler declaration */ +#ifdef __cplusplus +extern "C" { +#endif + +PLACE_IN_SECTION("MB_MEM2") ALIGN(4) static uint8_t EvtPool[POOL_SIZE]; +PLACE_IN_SECTION("MB_MEM2") ALIGN(4) static TL_CmdPacket_t SystemCmdBuffer; +PLACE_IN_SECTION("MB_MEM2") ALIGN(4) static uint8_t SystemSpareEvtBuffer[sizeof(TL_PacketHeader_t) + TL_EVT_HDR_SIZE + 255]; +PLACE_IN_SECTION("MB_MEM2") ALIGN(4) static uint8_t BleSpareEvtBuffer[sizeof(TL_PacketHeader_t) + TL_EVT_HDR_SIZE + 255]; +uint8_t g_ot_notification_allowed = 0U; +/* Global variables ----------------------------------------------------------*/ + +/* Global function prototypes -----------------------------------------------*/ +#if (CFG_DEBUG_TRACE != 0) +size_t DbgTraceWrite(int handle, const unsigned char * buf, size_t bufSize); +#endif + +/* USER CODE BEGIN GFP */ +osSemaphoreId_t SemShciId; +osSemaphoreId_t SemShciUserEvtProcessId; +osThreadId_t OsShciUserEvtProcessId; +osThreadId_t OsPushButtonProcessId; + +const osThreadAttr_t ShciUserEvtProcess_attr = { .name = CFG_SHCI_USER_EVT_PROCESS_NAME, + .attr_bits = CFG_SHCI_USER_EVT_PROCESS_ATTR_BITS, + .cb_mem = CFG_SHCI_USER_EVT_PROCESS_CB_MEM, + .cb_size = CFG_SHCI_USER_EVT_PROCESS_CB_SIZE, + .stack_mem = CFG_SHCI_USER_EVT_PROCESS_STACK_MEM, + .stack_size = CFG_SHCI_USER_EVT_PROCESS_STACK_SIZE, + .priority = CFG_SHCI_USER_EVT_PROCESS_PRIORITY }; + +const osThreadAttr_t PushButtonProcess_attr = { .name = CFG_PUSH_BUTTON_EVT_PROCESS_NAME, + .attr_bits = CFG_PUSH_BUTTON_EVT_PROCESS_ATTR_BITS, + .cb_mem = CFG_PUSH_BUTTON_EVT_PROCESS_CB_MEM, + .cb_size = CFG_PUSH_BUTTON_EVT_PROCESS_CB_SIZE, + .stack_mem = CFG_PUSH_BUTTON_EVT_PROCESS_STACK_MEM, + .stack_size = CFG_PUSH_BUTTON_EVT_PROCESS_STACK_SIZE, + .priority = CFG_PUSH_BUTTON_EVT_PROCESS_PRIORITY }; + +/* USER CODE END GFP */ + +/* Private functions prototypes-----------------------------------------------*/ +static void SystemPower_Config(void); +static void Init_Debug(void); +static void APPE_SysStatusNot(SHCI_TL_CmdStatus_t status); +static void APPE_SysUserEvtRx(void * pPayload); +static void APPE_SysEvtReadyProcessing(void); +static void APPE_SysEvtError(SCHI_SystemErrCode_t ErrorCode); +static void appe_Tl_Init(void); +/* USER CODE BEGIN PFP */ +static void Led_Init(void); +static void Button_Init(void); +#if (CFG_HW_EXTPA_ENABLED == 1) +static void ExtPA_Init(void); +#endif +static void ShciUserEvtProcess(void * argument); +static void PushButtonEvtProcess(void * argument); +/* USER CODE END PFP */ + +static void displayConcurrentMode(void); + +// Callback function to handle pushbutton to apptask +PushButtonCallback PbCb = NULL; + +void APP_ENTRY_PBSetReceiveCallback(PushButtonCallback aCallback) +{ + PbCb = aCallback; +} + +/* Functions Definition ------------------------------------------------------*/ +void APPE_Init(void) +{ + /* Configure the system Power Mode */ + SystemPower_Config(); + + /* Initialize the TimerServer */ + HW_TS_Init(hw_ts_InitMode_Full, &hrtc); + + /* USER CODE BEGIN APPE_Init_1 */ + /* initialize debugger module if supported and debug trace if activated */ + Init_Debug(); + + /* Display Dynamic concurrent mode (BLE and Thread) */ + displayConcurrentMode(); + + /** + * The Standby mode should not be entered before the initialization is over + * The default state of the Low Power Manager is to allow the Standby Mode so an request is needed here + */ + UTIL_LPM_SetOffMode(1 << CFG_LPM_APP, UTIL_LPM_DISABLE); + + /** init freertos semaphore */ + SemShciId = osSemaphoreNew(1, 0, NULL); /*< Create the semaphore and make it busy at initialization */ + SemShciUserEvtProcessId = osSemaphoreNew(1, 0, NULL); /*< Create the semaphore and make it busy at initialization */ + OsShciUserEvtProcessId = osThreadNew(ShciUserEvtProcess, NULL, &ShciUserEvtProcess_attr); + OsPushButtonProcessId = osThreadNew(PushButtonEvtProcess, NULL, &PushButtonProcess_attr); + + Led_Init(); + Button_Init(); + + /* USER CODE END APPE_Init_1 */ + /* Initialize all transport layers and start CPU2 which will send back a ready event to CPU1 */ + appe_Tl_Init(); + + BSP_LCD_Init(0, LCD_ORIENTATION_LANDSCAPE); + /* Set LCD Foreground Layer */ + UTIL_LCD_SetFuncDriver(&LCD_Driver); /* SetFunc before setting device */ + UTIL_LCD_SetDevice(0); /* SetDevice after funcDriver is set */ + BSP_LCD_Clear(0, SSD1315_COLOR_BLACK); + BSP_LCD_DisplayOn(0); + BSP_LCD_Refresh(0); + UTIL_LCD_SetFont(&Font12); + /* Set the LCD Text Color */ + UTIL_LCD_SetTextColor(SSD1315_COLOR_WHITE); + UTIL_LCD_SetBackColor(SSD1315_COLOR_BLACK); + BSP_LCD_Clear(0, SSD1315_COLOR_BLACK); + BSP_LCD_Refresh(0); + UTIL_LCD_DisplayStringAt(0, 0, (uint8_t *) "Matter LightingApp", CENTER_MODE); + BSP_LCD_Refresh(0); + + /** + * From now, the application is waiting for the ready event ( VS_HCI_C2_Ready ) + * received on the system channel before starting the Stack + * This system event is received with APPE_SysUserEvtRx() + */ + /* USER CODE BEGIN APPE_Init_2 */ +#if (CFG_HW_EXTPA_ENABLED == 1) + ExtPA_Init(); +#endif + + /* USER CODE END APPE_Init_2 */ + return; +} + +static void displayConcurrentMode() +{ + APP_DBG("Matter Over Thread Lighting-App starting..."); +} + +/************************************************************* + * + * LOCAL FUNCTIONS + * + *************************************************************/ +static void Init_Debug(void) +{ +#if (CFG_DEBUGGER_SUPPORTED == 1) + /** + * Keep debugger enabled while in any low power mode + */ + HAL_DBGMCU_EnableDBGSleepMode(); + + /* Enable debugger EXTI lines */ + LL_EXTI_EnableIT_32_63(LL_EXTI_LINE_48); + LL_C2_EXTI_EnableIT_32_63(LL_EXTI_LINE_48); + +#else + /* Disable debugger EXTI lines */ + LL_EXTI_DisableIT_32_63(LL_EXTI_LINE_48); + LL_C2_EXTI_DisableIT_32_63(LL_EXTI_LINE_48); + + GPIO_InitTypeDef gpio_config = { 0 }; + + gpio_config.Pull = GPIO_NOPULL; + gpio_config.Mode = GPIO_MODE_ANALOG; + + gpio_config.Pin = GPIO_PIN_15 | GPIO_PIN_14 | GPIO_PIN_13; + __HAL_RCC_GPIOA_CLK_ENABLE(); + HAL_GPIO_Init(GPIOA, &gpio_config); + __HAL_RCC_GPIOA_CLK_DISABLE(); + + gpio_config.Pin = GPIO_PIN_4 | GPIO_PIN_3; + __HAL_RCC_GPIOB_CLK_ENABLE(); + HAL_GPIO_Init(GPIOB, &gpio_config); + __HAL_RCC_GPIOB_CLK_DISABLE(); + + /** + * Do not keep debugger enabled while in any low power mode + */ + HAL_DBGMCU_DisableDBGSleepMode(); + HAL_DBGMCU_DisableDBGStopMode(); + HAL_DBGMCU_DisableDBGStandbyMode(); +#endif /* (CFG_DEBUGGER_SUPPORTED == 1) */ + +#if (CFG_DEBUG_TRACE != 0) + DbgTraceInit(); +#endif + + return; +} + +/** + * @brief Configure the system for power optimization + * + * @note This API configures the system to be ready for low power mode + * + * @param None + * @retval None + */ +static void SystemPower_Config(void) +{ + // Before going to stop or standby modes, do the settings so that system clock and IP80215.4 clock + // start on HSI automatically + LL_RCC_HSI_EnableAutoFromStop(); + + /** + * Select HSI as system clock source after Wake Up from Stop mode + */ + LL_RCC_SetClkAfterWakeFromStop(LL_RCC_STOP_WAKEUPCLOCK_HSI); + + /* Initialize low power manager */ + UTIL_LPM_Init(); + + /* Disable low power mode until INIT is complete */ + UTIL_LPM_SetOffMode(1 << CFG_LPM_APP, UTIL_LPM_DISABLE); + UTIL_LPM_SetStopMode(1 << CFG_LPM_APP, UTIL_LPM_DISABLE); + + /* Enable RAM1 (because OT instance.o is located here for Concurrent Mode */ + LL_C2_AHB1_GRP1_EnableClock(LL_C2_AHB1_GRP1_PERIPH_SRAM1); + LL_C2_AHB1_GRP1_EnableClockSleep(LL_C2_AHB1_GRP1_PERIPH_SRAM1); + + return; +} + +static void appe_Tl_Init(void) +{ + TL_MM_Config_t tl_mm_config; + SHCI_TL_HciInitConf_t SHci_Tl_Init_Conf; + + /**< Reference table initialization */ + TL_Init(); + + /**< System channel initialization */ + SHci_Tl_Init_Conf.p_cmdbuffer = (uint8_t *) &SystemCmdBuffer; + SHci_Tl_Init_Conf.StatusNotCallBack = APPE_SysStatusNot; + shci_init(APPE_SysUserEvtRx, (void *) &SHci_Tl_Init_Conf); + + /**< Memory Manager channel initialization */ + tl_mm_config.p_BleSpareEvtBuffer = BleSpareEvtBuffer; + tl_mm_config.p_SystemSpareEvtBuffer = SystemSpareEvtBuffer; + tl_mm_config.p_AsynchEvtPool = EvtPool; + tl_mm_config.AsynchEvtPoolSize = POOL_SIZE; + TL_MM_Init(&tl_mm_config); + + TL_Enable(); + + return; +} + +static void APPE_SysStatusNot(SHCI_TL_CmdStatus_t status) +{ + UNUSED(status); + return; +} + +/** + * The type of the payload for a system user event is tSHCI_UserEvtRxParam + * When the system event is both : + * - a ready event (subevtcode = SHCI_SUB_EVT_CODE_READY) + * - reported by the FUS (sysevt_ready_rsp == FUS_FW_RUNNING) + * The buffer shall not be released + * ( eg ((tSHCI_UserEvtRxParam*)pPayload)->status shall be set to SHCI_TL_UserEventFlow_Disable ) + * When the status is not filled, the buffer is released by default + */ +static void APPE_SysUserEvtRx(void * pPayload) +{ + TL_AsynchEvt_t * p_sys_event; + p_sys_event = (TL_AsynchEvt_t *) (((tSHCI_UserEvtRxParam *) pPayload)->pckt->evtserial.evt.payload); + + switch (p_sys_event->subevtcode) + { + case SHCI_SUB_EVT_CODE_READY: + APPE_SysEvtReadyProcessing(); + break; + + case SHCI_SUB_EVT_ERROR_NOTIF: + APPE_SysEvtError((SCHI_SystemErrCode_t)(p_sys_event->payload[0])); + break; + + default: + break; + } + return; +} + +/** + * @brief Notify a system error coming from the M0 firmware + * @param ErrorCode : errorCode detected by the M0 firmware + * + * @retval None + */ +static void APPE_SysEvtError(SCHI_SystemErrCode_t ErrorCode) +{ + switch (ErrorCode) + { + case ERR_THREAD_LLD_FATAL_ERROR: + APP_DBG("** ERR_THREAD : LLD_FATAL_ERROR \n"); + break; + + case ERR_THREAD_UNKNOWN_CMD: + APP_DBG("** ERR_THREAD : UNKNOWN_CMD \n"); + break; + + default: + APP_DBG("** ERR_THREAD : ErroCode=%d \n", ErrorCode); + break; + } + return; +} + +static void APPE_SysEvtReadyProcessing(void) +{ + /* Traces channel initialization */ + TL_TRACES_Init(); + + /* In the Context of Dynamic Concurrent mode, the Init and start of each stack must be split and executed + * in the following order : + * APP_BLE_Init : BLE Stack Init until it's ready to start ADV + * APP_THREAD_Init_Dyn_1() : Thread Stack Init until it's ready to be configured (default channel, PID, etc...) + */ + APP_DBG("1- Initialisation of BLE Stack..."); + APP_BLE_Init_Dyn_1(); + APP_DBG("2- Initialisation of OpenThread Stack. FW info :"); + APP_THREAD_Init(); + APP_BLE_Init_Dyn_2(); + + APP_DBG("Start init matter"); + GetAppTask().StartAppTask(); + +#if (CFG_LPM_SUPPORTED == 1) + /* Thread stack is initialized, low power mode can be enabled */ + UTIL_LPM_SetOffMode(1U << CFG_LPM_APP, UTIL_LPM_ENABLE); + UTIL_LPM_SetStopMode(1U << CFG_LPM_APP, UTIL_LPM_ENABLE); +#endif + + return; +} + +static void Led_Init(void) +{ +#if (CFG_LED_SUPPORTED == 1U) + /** + * Leds Initialization + */ + +#endif + + return; +} + +static void Button_Init(void) +{ + +#if (CFG_BUTTON_SUPPORTED == 1U) + /** + * Button Initialization + */ + + BSP_PB_Init(BUTTON_USER1, BUTTON_MODE_EXTI); +#endif + + return; +} + +#if (CFG_HW_EXTPA_ENABLED == 1) +static void ExtPA_Init(void) +{ + GPIO_InitTypeDef GPIO_InitStruct; + + // configure the GPIO PB0 in AF6 to be used as RF_TX_MOD_EXT_PA + GPIO_InitStruct.Pull = GPIO_NOPULL; + GPIO_InitStruct.Mode = GPIO_MODE_AF_PP; + GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH; + GPIO_InitStruct.Alternate = GPIO_AF6_RF_DTB0; + GPIO_InitStruct.Pin = GPIO_EXT_PA_TX_PIN; + HAL_GPIO_Init(GPIO_EXT_PA_TX_PORT, &GPIO_InitStruct); + + // configure the GPIO which will be managed by M0 stack to enable Ext PA + GPIO_InitStruct.Pull = GPIO_NOPULL; + GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP; + GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH; + GPIO_InitStruct.Pin = GPIO_EXT_PA_EN_PIN; + HAL_GPIO_Init(GPIO_EXT_PA_EN_PORT, &GPIO_InitStruct); + + // Indicate to M0 which GPIO must be managed + SHCI_C2_ExtpaConfig((uint32_t) GPIO_EXT_PA_EN_PORT, GPIO_EXT_PA_EN_PIN, EXT_PA_ENABLED_HIGH, EXT_PA_ENABLED); +} +#endif /* CFG_HW_EXTPA_ENABLED */ + +/************************************************************* + * + * WRAP FUNCTIONS + * + *************************************************************/ +static void PushButtonEvtProcess(void * argument) +{ + UNUSED(argument); + for (;;) + { + /* USER CODE BEGIN SHCI_USER_EVT_PROCESS_1 */ + + /* USER CODE END SHCI_USER_EVT_PROCESS_1 */ + osThreadFlagsWait(1, osFlagsWaitAny, osWaitForever); + Push_Button_st Message; + Message.Pushed_Button = BUTTON_USER1; + Message.State = 1; + PbCb(&Message); // call matter callback to handle push button + /* USER CODE BEGIN SHCI_USER_EVT_PROCESS_2 */ + + /* USER CODE END SHCI_USER_EVT_PROCESS_2 */ + } +} + +static void ShciUserEvtProcess(void * argument) +{ + UNUSED(argument); + for (;;) + { + /* USER CODE BEGIN SHCI_USER_EVT_PROCESS_1 */ + + /* USER CODE END SHCI_USER_EVT_PROCESS_1 */ + // osThreadFlagsWait(1, osFlagsWaitAny, osWaitForever); + osSemaphoreAcquire(SemShciUserEvtProcessId, osWaitForever); + shci_user_evt_proc(); + /* USER CODE BEGIN SHCI_USER_EVT_PROCESS_2 */ + + /* USER CODE END SHCI_USER_EVT_PROCESS_2 */ + } +} + +void shci_notify_asynch_evt(void * pdata) +{ + UNUSED(pdata); + osSemaphoreRelease(SemShciUserEvtProcessId); + return; +} + +void shci_cmd_resp_release(uint32_t flag) +{ + UNUSED(flag); + osSemaphoreRelease(SemShciId); + return; +} + +void shci_cmd_resp_wait(uint32_t timeout) +{ + UNUSED(timeout); + osSemaphoreAcquire(SemShciId, osWaitForever); + return; +} + +/* Received trace buffer from M0 */ +void TL_TRACES_EvtReceived(TL_EvtPacket_t * hcievt) +{ +#if (CFG_DEBUG_TRACE != 0) + /* Call write/print function using DMA from dbg_trace */ + /* - Cast to TL_AsynchEvt_t* to get "real" payload (without Sub Evt code 2bytes), + - (-2) to size to remove Sub Evt Code */ + DbgTraceWrite(1U, (const unsigned char *) ((TL_AsynchEvt_t *) (hcievt->evtserial.evt.payload))->payload, + hcievt->evtserial.evt.plen - 2U); +#endif /* CFG_DEBUG_TRACE */ + /* Release buffer */ + TL_MM_EvtDone(hcievt); +} +/** + * @brief Initialization of the trace mechanism + * @param None + * @retval None + */ +#if (CFG_DEBUG_TRACE != 0) +void DbgOutputInit(void) +{ +#if (CFG_HW_USART1_ENABLED == 1) + HW_UART_Init(CFG_DEBUG_TRACE_UART); +#endif + return; +} + +/** + * @brief Management of the traces + * @param p_data : data + * @param size : size + * @param call-back : + * @retval None + */ +void DbgOutputTraces(uint8_t * p_data, uint16_t size, void (*cb)(void)) +{ + HW_UART_Transmit_DMA(CFG_DEBUG_TRACE_UART, p_data, size, cb); + + return; +} +#endif + +/** + * @brief This function manage the Push button action + * @param GPIO_Pin : GPIO pin which has been activated + * @retval None + */ +void BSP_PB_Callback(Button_TypeDef Button) +{ + switch (Button) + { + case BUTTON_USER1: + APP_DBG("BUTTON 1 PUSHED !"); + osThreadFlagsSet(OsPushButtonProcessId, 1); + break; + + case BUTTON_USER2: + APP_DBG("BUTTON 2 PUSHED !"); + /* Set "Switch Protocol" Task */ + break; + + default: + break; + } + + return; +} +#ifdef __cplusplus +} +#endif diff --git a/examples/platform/stm32/common/STM32WB5MM-DK/Src/entropy_hardware_poll.c b/examples/platform/stm32/common/STM32WB5MM-DK/Src/entropy_hardware_poll.c new file mode 100644 index 00000000000000..db25dccdf97cf0 --- /dev/null +++ b/examples/platform/stm32/common/STM32WB5MM-DK/Src/entropy_hardware_poll.c @@ -0,0 +1,76 @@ + +/* USER CODE BEGIN Header */ +/** + ****************************************************************************** + * File Name : entropy_hardware_poll.c + * Description : This file provides code for the entropy collector. + * author :MCD Application Team + ****************************************************************************** + * @attention + * + * Copyright (c) 2019-2021 STMicroelectronics. + * All rights reserved. + * + * This software is licensed under terms that can be found in the LICENSE file + * in the root directory of this software component. + * If no LICENSE file comes with this software, it is provided AS-IS. + * + ****************************************************************************** + */ +/* USER CODE END Header */ + +#include "main.h" +#include "stm32wbxx_hal.h" +#include "stm32wbxx_ll_hsem.h" +#include + +int mbedtls_hardware_poll(void * data, unsigned char * output, size_t len, size_t * olen); + +int mbedtls_hardware_poll(void * data, unsigned char * output, size_t len, size_t * olen) +{ + HAL_StatusTypeDef status = HAL_OK; + uint32_t random_number = 0; + /** + * Static random Address + * The two upper bits shall be set to 1 + * The lowest 32bits is read from the UDN to differentiate between devices + * The RNG may be used to provide a random number on each power on + */ + /* Get RNG semaphore */ + while (LL_HSEM_1StepLock(HSEM, 0)) + ; + + /* Enable RNG */ + __HAL_RNG_ENABLE(&hrng); + + /* Enable HSI48 oscillator */ + LL_RCC_HSI48_Enable(); + /* Wait until HSI48 is ready */ + while (!LL_RCC_HSI48_IsReady()) + ; + + if (HAL_RNG_GenerateRandomNumber(&hrng, &random_number) != HAL_OK) + { + } + + /* Disable HSI48 oscillator */ + LL_RCC_HSI48_Disable(); + + /* Disable RNG */ + __HAL_RNG_DISABLE(&hrng); + + /* Release RNG semaphore */ + LL_HSEM_ReleaseLock(HSEM, 0, 0); + ((void) data); + *olen = 0; + + if ((len < sizeof(uint32_t)) || (HAL_OK != status)) + { + return 0; + } + + memcpy(output, &random_number, sizeof(uint32_t)); + *olen = sizeof(uint32_t); + + return 0; +} diff --git a/examples/platform/stm32/common/STM32WB5MM-DK/Src/flash_driver.c b/examples/platform/stm32/common/STM32WB5MM-DK/Src/flash_driver.c new file mode 100644 index 00000000000000..fcf4534a327003 --- /dev/null +++ b/examples/platform/stm32/common/STM32WB5MM-DK/Src/flash_driver.c @@ -0,0 +1,322 @@ +/** + ****************************************************************************** + * @file : flash_driver.c + * @author : MCD Application Team + * @brief : Dual core Flash driver + ****************************************************************************** + * @attention + * + * Copyright (c) 2019-2021 STMicroelectronics. + * All rights reserved. + * + * This software is licensed under terms that can be found in the LICENSE file + * in the root directory of this software component. + * If no LICENSE file comes with this software, it is provided AS-IS. + * + ****************************************************************************** + */ + +/* Includes ------------------------------------------------------------------*/ +#include "flash_driver.h" +#include "app_common.h" +#include "main.h" +#include "shci.h" +#include "utilities_conf.h" + +/* Private typedef -----------------------------------------------------------*/ +typedef enum +{ + SEM_LOCK_SUCCESSFUL, + SEM_LOCK_BUSY, +} SemStatus_t; + +typedef enum +{ + FLASH_ERASE, + FLASH_WRITE, +} FlashOperationType_t; + +/* Private defines -----------------------------------------------------------*/ +/* Private macros ------------------------------------------------------------*/ +/* Private variables ---------------------------------------------------------*/ +/* Global variables ----------------------------------------------------------*/ +/* Private function prototypes -----------------------------------------------*/ +static SingleFlashOperationStatus_t ProcessSingleFlashOperation(FlashOperationType_t FlashOperationType, + uint32_t SectorNumberOrDestAddress, uint64_t Data); +/* Public functions ----------------------------------------------------------*/ +uint32_t FD_EraseSectors(uint32_t FirstSector, uint32_t NbrOfSectors) +{ + uint32_t loop_flash; + uint32_t return_value; + SingleFlashOperationStatus_t single_flash_operation_status; + + single_flash_operation_status = SINGLE_FLASH_OPERATION_DONE; + + /** + * Take the semaphore to take ownership of the Flash IP + */ + while (LL_HSEM_1StepLock(HSEM, CFG_HW_FLASH_SEMID)) + ; + + HAL_FLASH_Unlock(); + + /** + * Notify the CPU2 that some flash erase activity may be executed + * On reception of this command, the CPU2 enables the BLE timing protection versus flash erase processing + * The Erase flash activity will be executed only when the BLE RF is idle for at least 25ms + * The CPU2 will prevent all flash activity (write or erase) in all cases when the BL RF Idle is shorter than 25ms. + */ + SHCI_C2_FLASH_EraseActivity(ERASE_ACTIVITY_ON); + + for (loop_flash = 0; (loop_flash < NbrOfSectors) && (single_flash_operation_status == SINGLE_FLASH_OPERATION_DONE); + loop_flash++) + { + single_flash_operation_status = FD_EraseSingleSector(FirstSector + loop_flash); + } + + if (single_flash_operation_status != SINGLE_FLASH_OPERATION_DONE) + { + return_value = NbrOfSectors - loop_flash + 1; + } + else + { + /** + * Notify the CPU2 there will be no request anymore to erase the flash + * On reception of this command, the CPU2 will disables the BLE timing protection versus flash erase processing + * The protection is active until next end of radio event. + */ + SHCI_C2_FLASH_EraseActivity(ERASE_ACTIVITY_OFF); + + HAL_FLASH_Lock(); + + /** + * Release the ownership of the Flash IP + */ + LL_HSEM_ReleaseLock(HSEM, CFG_HW_FLASH_SEMID, 0); + + return_value = 0; + } + + return return_value; +} + +uint32_t FD_WriteData(uint32_t DestAddress, uint64_t * pSrcBuffer, uint32_t NbrOfData) +{ + uint32_t loop_flash; + uint32_t return_value; + SingleFlashOperationStatus_t single_flash_operation_status; + + single_flash_operation_status = SINGLE_FLASH_OPERATION_DONE; + + /** + * Take the semaphore to take ownership of the Flash IP + */ + while (LL_HSEM_1StepLock(HSEM, CFG_HW_FLASH_SEMID)) + ; + + HAL_FLASH_Unlock(); + + for (loop_flash = 0; (loop_flash < NbrOfData) && (single_flash_operation_status == SINGLE_FLASH_OPERATION_DONE); loop_flash++) + { + single_flash_operation_status = FD_WriteSingleData(DestAddress + (8 * loop_flash), *(pSrcBuffer + loop_flash)); + } + + if (single_flash_operation_status != SINGLE_FLASH_OPERATION_DONE) + { + return_value = NbrOfData - loop_flash + 1; + } + else + { + HAL_FLASH_Lock(); + + /** + * Release the ownership of the Flash IP + */ + LL_HSEM_ReleaseLock(HSEM, CFG_HW_FLASH_SEMID, 0); + + return_value = 0; + } + + return return_value; +} + +SingleFlashOperationStatus_t FD_EraseSingleSector(uint32_t SectorNumber) +{ + SingleFlashOperationStatus_t return_value; + + /* The last parameter is unused in that case and set to 0 */ + return_value = ProcessSingleFlashOperation(FLASH_ERASE, SectorNumber, 0); + + return return_value; +} + +SingleFlashOperationStatus_t FD_WriteSingleData(uint32_t DestAddress, uint64_t Data) +{ + SingleFlashOperationStatus_t return_value; + + return_value = ProcessSingleFlashOperation(FLASH_WRITE, DestAddress, Data); + + return return_value; +} + +/************************************************************* + * + * LOCAL FUNCTIONS + * + *************************************************************/ +static SingleFlashOperationStatus_t ProcessSingleFlashOperation(FlashOperationType_t FlashOperationType, + uint32_t SectorNumberOrDestAddress, uint64_t Data) +{ + SemStatus_t cpu1_sem_status; + SemStatus_t cpu2_sem_status; + WaitedSemStatus_t waited_sem_status; + SingleFlashOperationStatus_t return_status; + + uint32_t page_error; + FLASH_EraseInitTypeDef p_erase_init; + + waited_sem_status = WAITED_SEM_FREE; + + p_erase_init.TypeErase = FLASH_TYPEERASE_PAGES; + p_erase_init.NbPages = 1; + p_erase_init.Page = SectorNumberOrDestAddress; + + do + { + /** + * When the PESD bit mechanism is used by CPU2 to protect its timing, the PESD bit should be polled here. + * If the PESD is set, the CPU1 will be stalled when reading literals from an ISR that may occur after + * the flash processing has been requested but suspended due to the PESD bit. + * + * Note: This code is required only when the PESD mechanism is used to protect the CPU2 timing. + * However, keeping that code make it compatible with the two mechanisms. + */ + while (LL_FLASH_IsActiveFlag_OperationSuspended()) + ; + + UTILS_ENTER_CRITICAL_SECTION(); + + /** + * Depending on the application implementation, in case a multitasking is possible with an OS, + * it should be checked here if another task in the application disallowed flash processing to protect + * some latency in critical code execution + * When flash processing is ongoing, the CPU cannot access the flash anymore. + * Trying to access the flash during that time stalls the CPU. + * The only way for CPU1 to disallow flash processing is to take CFG_HW_BLOCK_FLASH_REQ_BY_CPU1_SEMID. + */ + cpu1_sem_status = (SemStatus_t) LL_HSEM_GetStatus(HSEM, CFG_HW_BLOCK_FLASH_REQ_BY_CPU1_SEMID); + if (cpu1_sem_status == SEM_LOCK_SUCCESSFUL) + { + /** + * Check now if the CPU2 disallows flash processing to protect its timing. + * If the semaphore is locked, the CPU2 does not allow flash processing + * + * Note: By default, the CPU2 uses the PESD mechanism to protect its timing, + * therefore, it is useless to get/release the semaphore. + * + * However, keeping that code make it compatible with the two mechanisms. + * The protection by semaphore is enabled on CPU2 side with the command SHCI_C2_SetFlashActivityControl() + * + */ + cpu2_sem_status = (SemStatus_t) LL_HSEM_1StepLock(HSEM, CFG_HW_BLOCK_FLASH_REQ_BY_CPU2_SEMID); + if (cpu2_sem_status == SEM_LOCK_SUCCESSFUL) + { + /** + * When CFG_HW_BLOCK_FLASH_REQ_BY_CPU2_SEMID is taken, it is allowed to only erase one sector or + * write one single 64bits data + * When either several sectors need to be erased or several 64bits data need to be written, + * the application shall first exit from the critical section and try again. + */ + if (FlashOperationType == FLASH_ERASE) + { + HAL_FLASHEx_Erase(&p_erase_init, &page_error); + } + else + { + HAL_FLASH_Program(FLASH_TYPEPROGRAM_DOUBLEWORD, SectorNumberOrDestAddress, Data); + } + /** + * Release the semaphore to give the opportunity to CPU2 to protect its timing versus the next flash operation + * by taking this semaphore. + * Note that the CPU2 is polling on this semaphore so CPU1 shall release it as fast as possible. + * This is why this code is protected by a critical section. + */ + LL_HSEM_ReleaseLock(HSEM, CFG_HW_BLOCK_FLASH_REQ_BY_CPU2_SEMID, 0); + } + } + + UTILS_EXIT_CRITICAL_SECTION(); + + if (cpu1_sem_status != SEM_LOCK_SUCCESSFUL) + { + /** + * To avoid looping in ProcessSingleFlashOperation(), FD_WaitForSemAvailable() should implement a mechanism to + * continue only when CFG_HW_BLOCK_FLASH_REQ_BY_CPU1_SEMID is free + */ + waited_sem_status = FD_WaitForSemAvailable(WAIT_FOR_SEM_BLOCK_FLASH_REQ_BY_CPU1); + } + else if (cpu2_sem_status != SEM_LOCK_SUCCESSFUL) + { + /** + * To avoid looping in ProcessSingleFlashOperation(), FD_WaitForSemAvailable() should implement a mechanism to + * continue only when CFG_HW_BLOCK_FLASH_REQ_BY_CPU2_SEMID is free + */ + waited_sem_status = FD_WaitForSemAvailable(WAIT_FOR_SEM_BLOCK_FLASH_REQ_BY_CPU2); + } + } while (((cpu2_sem_status != SEM_LOCK_SUCCESSFUL) || (cpu1_sem_status != SEM_LOCK_SUCCESSFUL)) && + (waited_sem_status != WAITED_SEM_BUSY)); + + /** + * In most BLE application, the flash should not be blocked by the CPU2 longer than FLASH_TIMEOUT_VALUE (1000ms) + * However, it could be that for some marginal application, this time is longer. + * In that case either HAL_FLASHEx_Erase() or HAL_FLASH_Program() will exit with FLASH_TIMEOUT_VALUE value. + * This is not a failing case and there is no other way than waiting the operation to be completed. + * If for any reason this test is never passed, this means there is a failure in the system and there is no other + * way to recover than applying a device reset. + * + * Note: This code is required only when the PESD mechanism is used to protect the CPU2 timing. + * However, keeping that code make it compatible with the two mechanisms. + */ + while (__HAL_FLASH_GET_FLAG(FLASH_FLAG_CFGBSY)) + ; + + if (waited_sem_status != WAITED_SEM_BUSY) + { + /** + * The flash processing has been done. It has not been checked whether it has been successful or not. + * The only commitment is that it is possible to request a new flash processing + */ + return_status = SINGLE_FLASH_OPERATION_DONE; + } + else + { + /** + * The flash processing has not been executed due to timing protection from either the CPU1 or the CPU2. + * This status is reported up to the user that should retry after checking that each CPU do not + * protect its timing anymore. + */ + return_status = SINGLE_FLASH_OPERATION_NOT_EXECUTED; + } + + return return_status; +} + +/************************************************************* + * + * WEAK FUNCTIONS + * + *************************************************************/ +__WEAK WaitedSemStatus_t FD_WaitForSemAvailable(WaitedSemId_t WaitedSemId) +{ + /** + * The timing protection is enabled by either CPU1 or CPU2. It should be decided here if the driver shall + * keep trying to erase/write the flash until successful or if it shall exit and report to the user that the action + * has not been executed. + * WAITED_SEM_BUSY returns to the user + * WAITED_SEM_FREE keep looping in the driver until the action is executed. This will result in the current stack looping + * until this is done. In a bare metal implementation, only the code within interrupt handler can be executed. With an OS, + * only task with higher priority can be processed + * + */ + return WAITED_SEM_BUSY; +} diff --git a/examples/platform/stm32/common/STM32WB5MM-DK/Src/flash_wb.c b/examples/platform/stm32/common/STM32WB5MM-DK/Src/flash_wb.c new file mode 100644 index 00000000000000..d1e0f613b70b4b --- /dev/null +++ b/examples/platform/stm32/common/STM32WB5MM-DK/Src/flash_wb.c @@ -0,0 +1,357 @@ +/** + ****************************************************************************** + * @file flash_wb.c + * @author MCD Application Team + * @brief Middleware between keymanager and flahs_driver , + * to manage key needed for Matter + ****************************************************************************** + * @attention + * + * Copyright (c) 2023 STMicroelectronics. + * All rights reserved. + * + * This software is licensed under terms that can be found in the LICENSE file + * in the root directory of this software component. + * If no LICENSE file comes with this software, it is provided AS-IS. + * + ****************************************************************************** + */ + +/* Includes ------------------------------------------------------------------*/ +#include "flash_wb.h" +#include "flash_driver.h" + +#include +#include +#include + +/* Private defines -----------------------------------------------------------*/ +#define MATTER_KEY_NAME_MAX_LENGTH (15 * 2) // ADD Max key name string size is 30 "keyType...;KeyName..." +// ^ STM32STORE_MAX_KEY_SIZE +#define NVM_OFFSET_KEY 512 +#define NVM_END_FLASH +#define NVM_BLOCK_SIZE NVM_OFFSET_KEY +#define FLASH_START 0x08000000 +#define DEFAULT_VALUE 0xFF +#define NB_SECTOR 3 +#define NVM_MATTER_ADDR_INIT_SECURE 0x08082000 +#define NVM_MATTER_ADDR_INIT_SECURE_PTR ((void * const) NVM_MATTER_ADDR_INIT_SECURE) +#define SECTOR_SIZE_SECURE 4096 * 2 +#define NVM_MATTER_ADDR_INIT_NO_SECURE NVM_MATTER_ADDR_INIT_SECURE + SECTOR_SIZE_SECURE +#define NVM_MATTER_ADDR_INIT_NOSECURE_PTR ((void * const) NVM_MATTER_ADDR_INIT_NO_SECURE) +#define SECTOR_SIZE_NO_SECURE 4096 +#define NVM_SIZE_FLASH (SECTOR_SIZE_SECURE + SECTOR_SIZE_NO_SECURE) +#define NVM_MAX_KEY NVM_SIZE_FLASH / NVM_OFFSET_KEY + +typedef struct +{ + NVM_Sector id_sector; + uint8_t * ram_ptr; + size_t sector_size; + +} NVM_Sector_Struct; + +/* Private macros ------------------------------------------------------------*/ + +/* Private variables ---------------------------------------------------------*/ +uint8_t ram_nvm[SECTOR_SIZE_SECURE + SECTOR_SIZE_NO_SECURE] = { 0 }; + +const NVM_Sector_Struct sector_no_secure = { .id_sector = SECTOR_NO_SECURE, + .ram_ptr = ram_nvm + SECTOR_SIZE_SECURE, + .sector_size = SECTOR_SIZE_NO_SECURE }; + +//*SIMULATE TO EXAMPLE* +const NVM_Sector_Struct sector_secure = { .id_sector = SECTOR_SECURE, .ram_ptr = ram_nvm, .sector_size = SECTOR_SIZE_SECURE }; + +uint8_t CheckSanity = 0; +/* Global variables ----------------------------------------------------------*/ +/* Private function prototypes -----------------------------------------------*/ + +static uint8_t flash_get(uint8_t * KeyValue, uint8_t * KeyAddr, size_t KeySize, size_t * read_by_size); +static uint8_t flash_update(const NVM_Sector_Struct select_sector, uint8_t * KeyName, uint8_t * KeyValue, size_t KeySize); +static NVM_StatusTypeDef flash_replace(const NVM_Sector_Struct select_sector, uint8_t * PtKeyfind, uint8_t * KeyName, + uint8_t * KeyValue, size_t KeySize); +static NVM_StatusTypeDef flash_write(uint8_t * PtKeyFree, uint8_t * key, uint8_t * value, size_t value_size); +static uint8_t * SearchKey(uint8_t * PtPage, uint8_t * KeyName); +static NVM_StatusTypeDef delete_key(const NVM_Sector_Struct select_sector, uint8_t * PtkeyFind); + +/* Public functions ----------------------------------------------------------*/ + +void NM_Init(void) +{ + // Copy Nvm flash to ram, it used one time for boot + // copy no secure nvm to no secure ram + memcpy(sector_no_secure.ram_ptr, NVM_MATTER_ADDR_INIT_NOSECURE_PTR, sector_no_secure.sector_size); + + // copy secure nvm to secure ram *SIMULATE TO EXAMPLE* + memcpy(sector_secure.ram_ptr, NVM_MATTER_ADDR_INIT_SECURE_PTR, sector_secure.sector_size); +} + +NVM_StatusTypeDef NM_Check_Validity(void) +{ + NVM_StatusTypeDef err = NVM_OK; + if (CheckSanity != 0) + { + err = NVM_FLASH_CORRUPTION; + } + return err; +} + +NVM_StatusTypeDef NM_Dump(void) +{ + NVM_StatusTypeDef err = NVM_DELETE_FAILED; + + err = FD_EraseSectors((NVM_MATTER_ADDR_INIT_SECURE - FLASH_START) / (NVM_SIZE_FLASH / NB_SECTOR), NB_SECTOR); + if (err == 0) + { + err = FD_WriteData(NVM_MATTER_ADDR_INIT_SECURE, (uint64_t *) ram_nvm, (uint32_t)(NVM_SIZE_FLASH / sizeof(uint64_t))); + if (err != 0) + { + err = NVM_WRITE_FAILED; + } + else + { + if (memcmp(ram_nvm, (void *) NVM_MATTER_ADDR_INIT_SECURE, (size_t) NVM_SIZE_FLASH)) + { + err = NVM_WRITE_FAILED; + } + else + { + err = NVM_OK; + } + } + } + return err; +} + +NVM_StatusTypeDef NM_GetKeyValue(void * KeyValue, const char * KeyName, uint32_t KeySize, size_t * read_by_size, NVM_Sector sector) +{ + + NVM_Sector_Struct select_nvm = { 0 }; + switch (sector) + { + case SECTOR_NO_SECURE: + select_nvm = sector_no_secure; + break; + + case SECTOR_SECURE: + select_nvm = sector_secure; + break; + + default: + return NVM_WRITE_FAILED; + } + + uint8_t * key_search = SearchKey(select_nvm.ram_ptr, (uint8_t *) KeyName); + if (key_search != NULL) + { + // copy Keyname's value in KeyValue and copy the size of KeyValue in read_by_size + return flash_get(KeyValue, key_search, KeySize, read_by_size); + } + return NVM_KEY_NOT_FOUND; +} + +NVM_StatusTypeDef NM_SetKeyValue(char * KeyValue, char * KeyName, uint32_t KeySize, NVM_Sector sector) +{ + + NVM_Sector_Struct select_nvm = { 0 }; + void * Ptkey = NULL; + + switch (sector) + { + case SECTOR_NO_SECURE: + select_nvm = sector_no_secure; + break; + + case SECTOR_SECURE: + select_nvm = sector_secure; + break; + + default: + return NVM_WRITE_FAILED; + } + + if (KeySize > NVM_BLOCK_SIZE) + { + return NVM_BLOCK_SIZE_OVERFLOW; + } + // call function to search the pointer of key if it exist else return null + Ptkey = SearchKey(select_nvm.ram_ptr, (uint8_t *) KeyName); + + if (Ptkey == NULL) + { + return flash_update(select_nvm, (uint8_t *) KeyName, (uint8_t *) KeyValue, KeySize); + } + else + { + if (!flash_replace(select_nvm, Ptkey, (uint8_t *) KeyName, (uint8_t *) KeyValue, KeySize)) + { + return NVM_OK; + } + } + return NVM_WRITE_FAILED; +} + +uint8_t NM_DeleteKey(const char * Keyname, NVM_Sector sector) +{ + + NVM_Sector_Struct select_nvm = { 0 }; + switch (sector) + { + case SECTOR_NO_SECURE: + select_nvm = sector_no_secure; + break; + + case SECTOR_SECURE: + select_nvm = sector_secure; + break; + + default: + return NVM_WRITE_FAILED; + } + uint8_t * Ptkey = SearchKey(select_nvm.ram_ptr, (uint8_t *) Keyname); + if (Ptkey != NULL) + { + return delete_key(select_nvm, Ptkey); + } + return NVM_KEY_NOT_FOUND; +} + +void NM_ResetFactory(void) +{ + while (1) + { + FD_EraseSectors((NVM_MATTER_ADDR_INIT_SECURE - FLASH_START) / (NVM_SIZE_FLASH / NB_SECTOR), NB_SECTOR); + NVIC_SystemReset(); + } +} + +/************************************************************* + * + * LOCAL FUNCTIONS + * + *************************************************************/ + +static uint8_t * SearchKey(uint8_t * PtPage, uint8_t * KeyName) +{ + + uint8_t * i = PtPage; + size_t read_by_size = 0; + + while ((i >= PtPage) || (i < (PtPage + NVM_SIZE_FLASH))) + { + if (*i != DEFAULT_VALUE) + { + if (strcmp((char *) KeyName, (char *) i) == 0) + { + return i; + } + read_by_size = *(size_t *) ((uint8_t *) i + MATTER_KEY_NAME_MAX_LENGTH); + i += read_by_size + sizeof(size_t) + MATTER_KEY_NAME_MAX_LENGTH; + // Flash is corrupted + if ((i < PtPage) || (i > (PtPage + NVM_SIZE_FLASH))) + { + NM_ResetFactory(); + } + } + else + { + return NULL; + } + } + return NULL; +} + +static uint8_t flash_get(uint8_t * KeyValue, uint8_t * KeyAddr, size_t KeySize, size_t * read_by_size) +{ + *read_by_size = *(size_t *) ((uint8_t *) KeyAddr + MATTER_KEY_NAME_MAX_LENGTH); + if (KeySize >= *read_by_size) + { + memcpy(KeyValue, KeyAddr + MATTER_KEY_NAME_MAX_LENGTH + sizeof(size_t), *read_by_size); + return NVM_OK; + } + else + { + return NVM_BUFFER_TOO_SMALL; + } +} + +static NVM_StatusTypeDef flash_update(const NVM_Sector_Struct select_sector, uint8_t * KeyName, uint8_t * KeyValue, size_t KeySize) +{ + + uint8_t * i = select_sector.ram_ptr; + size_t read_by_size = 0; + while (i < (select_sector.ram_ptr + select_sector.sector_size)) + { + if (*i == DEFAULT_VALUE) + { + return flash_write(i, KeyName, KeyValue, KeySize); + } + read_by_size = *(size_t *) ((uint8_t *) i + MATTER_KEY_NAME_MAX_LENGTH); + if (read_by_size > NVM_BLOCK_SIZE) + { + return NVM_ERROR_BLOCK_ALIGN; + } + i += read_by_size + sizeof(size_t) + MATTER_KEY_NAME_MAX_LENGTH; + } + return NVM_SIZE_FULL; +} + +static NVM_StatusTypeDef flash_replace(const NVM_Sector_Struct select_sector, uint8_t * PtKeyfind, uint8_t * KeyName, + uint8_t * KeyValue, size_t KeySize) +{ + + NVM_StatusTypeDef err = NVM_OK; + if ((PtKeyfind != NULL) && (KeyName != NULL) && (KeyValue != NULL)) + { + err = delete_key(select_sector, PtKeyfind); + if (err != NVM_OK) + return err; + + err = flash_update(select_sector, KeyName, KeyValue, KeySize); + if (err != NVM_OK) + return err; + return err; + } + return NVM_WRITE_FAILED; +} + +static NVM_StatusTypeDef delete_key(const NVM_Sector_Struct select_sector, uint8_t * PtkeyFind) +{ + uint8_t * PtKeyNext = NULL; + uint8_t * PtKeyCpy = NULL; + size_t size_key = 0; + + if (PtkeyFind != NULL) + { + size_key = *(size_t *) ((uint8_t *) PtkeyFind + MATTER_KEY_NAME_MAX_LENGTH); + PtKeyNext = PtkeyFind + size_key + MATTER_KEY_NAME_MAX_LENGTH + sizeof(size_key); + PtKeyCpy = PtkeyFind; + while ((*PtKeyNext != 0xFF) && (PtKeyNext < (ram_nvm + NVM_SIZE_FLASH))) + { + size_key = *(size_t *) ((uint8_t *) PtKeyNext + MATTER_KEY_NAME_MAX_LENGTH); + memcpy(PtKeyCpy, PtKeyNext, size_key + sizeof(size_t) + MATTER_KEY_NAME_MAX_LENGTH); + PtKeyCpy += size_key + sizeof(size_t) + MATTER_KEY_NAME_MAX_LENGTH; + PtKeyNext += size_key + MATTER_KEY_NAME_MAX_LENGTH + sizeof(size_key); + } + memset(PtKeyCpy, DEFAULT_VALUE, (ram_nvm + NVM_SIZE_FLASH - PtKeyCpy)); + return NVM_OK; + } + return NVM_DELETE_FAILED; +} + +static NVM_StatusTypeDef flash_write(uint8_t * PtKeyFree, uint8_t * key, uint8_t * value, size_t value_size) +{ + + if ((PtKeyFree != NULL) && (key != NULL) && (value != NULL)) + { + + memset(PtKeyFree, DEFAULT_VALUE, value_size); + memset(PtKeyFree, 0x00, MATTER_KEY_NAME_MAX_LENGTH); + memcpy(PtKeyFree, key, strlen((char *) key)); + memcpy(PtKeyFree + MATTER_KEY_NAME_MAX_LENGTH, &value_size, sizeof(size_t)); + memcpy(PtKeyFree + MATTER_KEY_NAME_MAX_LENGTH + sizeof(size_t), value, value_size); + return NVM_OK; + } + return NVM_WRITE_FAILED; +} diff --git a/examples/platform/stm32/common/STM32WB5MM-DK/Src/freertos_port.c b/examples/platform/stm32/common/STM32WB5MM-DK/Src/freertos_port.c new file mode 100644 index 00000000000000..ab2043c9b9139f --- /dev/null +++ b/examples/platform/stm32/common/STM32WB5MM-DK/Src/freertos_port.c @@ -0,0 +1,322 @@ +/* USER CODE BEGIN Header */ +/** + ****************************************************************************** + * File Name : freertos_port.c + * Description : Custom porting of FreeRTOS functionalities + * + ****************************************************************************** + * @attention + * + * Copyright (c) 2019-2021 STMicroelectronics. + * All rights reserved. + * + * This software is licensed under terms that can be found in the LICENSE file + * in the root directory of this software component. + * If no LICENSE file comes with this software, it is provided AS-IS. + * + ****************************************************************************** + */ +/* USER CODE END Header */ + +/* Includes ------------------------------------------------------------------*/ +#include "app_common.h" + +#include "FreeRTOS.h" +#include "stm32_lpm.h" +#include "task.h" +#include + +/* Private typedef -----------------------------------------------------------*/ +typedef struct +{ + uint32_t LpTimeLeftOnEntry; + uint8_t LpTimerFreeRTOS_Id; +} LpTimerContext_t; + +/* Private defines -----------------------------------------------------------*/ +#ifndef configSYSTICK_CLOCK_HZ +#define configSYSTICK_CLOCK_HZ configCPU_CLOCK_HZ +/* Ensure the SysTick is clocked at the same frequency as the core. */ +#define portNVIC_SYSTICK_CLK_BIT (1UL << 2UL) +#else +/* The way the SysTick is clocked is not modified in case it is not the same + as the core. */ +#define portNVIC_SYSTICK_CLK_BIT (0) +#endif + +#define CPU_CLOCK_KHZ (configCPU_CLOCK_HZ / 1000) + +/* Constants required to manipulate the core. Registers first... */ +#define portNVIC_SYSTICK_CTRL_REG (*((volatile uint32_t *) 0xe000e010)) +#define portNVIC_SYSTICK_LOAD_REG (*((volatile uint32_t *) 0xe000e014)) +#define portNVIC_SYSTICK_CURRENT_VALUE_REG (*((volatile uint32_t *) 0xe000e018)) +#define portNVIC_SYSTICK_INT_BIT (1UL << 1UL) +#define portNVIC_SYSTICK_ENABLE_BIT (1UL << 0UL) +#define portNVIC_SYSTICK_COUNT_FLAG_BIT (1UL << 16UL) + +/* Private macros ------------------------------------------------------------*/ +/* Private variables ---------------------------------------------------------*/ +/* + * The number of SysTick increments that make up one tick period. + */ +#if (CFG_LPM_SUPPORTED != 0) +static uint32_t ulTimerCountsForOneTick; + +static LpTimerContext_t LpTimerContext; +#endif +/* Global variables ----------------------------------------------------------*/ +/* Private function prototypes -----------------------------------------------*/ +#if (CFG_LPM_SUPPORTED != 0) +static void LpTimerInit(void); +static void LpTimerCb(void); +static void LpTimerStart(uint32_t time_to_sleep); +static void LpEnter(void); +static uint32_t LpGetElapsedTime(void); +void vPortSetupTimerInterrupt(void); +#endif + +/* Functions Definition ------------------------------------------------------*/ + +/** + * @brief Implement the tickless feature + * + * + * @param: xExpectedIdleTime is given in number of FreeRTOS Ticks + * @retval: None + */ +void vPortSuppressTicksAndSleep(TickType_t xExpectedIdleTime) +{ + /* If low power is not used, do not stop the SysTick and continue execution */ +#if (CFG_LPM_SUPPORTED != 0) + /** + * Although this is not documented as such, when xExpectedIdleTime = 0xFFFFFFFF = (~0), + * it likely means the system may enter low power for ever ( from a FreeRTOS point of view ). + * Otherwise, for a FreeRTOS tick set to 1ms, that would mean it is requested to wakeup in 8 years from now. + * When the system may enter low power mode for ever, FreeRTOS is not really interested to maintain a + * systick count and when the system exits from low power mode, there is no need to update the count with + * the time spent in low power mode + */ + uint32_t ulCompleteTickPeriods; + + /* Stop the SysTick to avoid the interrupt to occur while in the critical section. + * Otherwise, this will prevent the device to enter low power mode + * At this time, an update of the systick will not be considered + * + */ + portNVIC_SYSTICK_CTRL_REG &= ~portNVIC_SYSTICK_ENABLE_BIT; + + /* Enter a critical section but don't use the taskENTER_CRITICAL() + method as that will mask interrupts that should exit sleep mode. */ + __disable_irq(); + __DSB(); + __ISB(); + + /* If a context switch is pending or a task is waiting for the scheduler + to be unsuspended then abandon the low power entry. */ + if (eTaskConfirmSleepModeStatus() == eAbortSleep) + { + /* Restart SysTick. */ + portNVIC_SYSTICK_CTRL_REG |= portNVIC_SYSTICK_ENABLE_BIT; + + /* Re-enable interrupts - see comments above __disable_interrupt() + call above. */ + __enable_irq(); + } + else + { + if (xExpectedIdleTime != (~0)) + { + /* Remove one tick to wake up before the event occurs */ + xExpectedIdleTime--; + /* Start the low power timer */ + LpTimerStart(xExpectedIdleTime); + } + + /* Enter low power mode */ + LpEnter(); + + if (xExpectedIdleTime != (~0)) + { + /** + * Get the number of FreeRTOS ticks that has been suppressed + * In the current implementation, this shall be kept in critical section + * so that the timer server return the correct elapsed time + */ + ulCompleteTickPeriods = LpGetElapsedTime(); + vTaskStepTick(ulCompleteTickPeriods); + } + + /* Restart SysTick */ + portNVIC_SYSTICK_CURRENT_VALUE_REG = 0UL; + portNVIC_SYSTICK_CTRL_REG |= portNVIC_SYSTICK_ENABLE_BIT; + portNVIC_SYSTICK_LOAD_REG = ulTimerCountsForOneTick - 1UL; + + /* Exit with interrUpts enabled. */ + __enable_irq(); + } +#endif +} + +/* + * Setup the systick timer to generate the tick interrupts at the required + * frequency and initialize a low power timer + * The current implementation is kept as close as possible to the default tickless + * mode provided. + * The systick is still used when there is no need to go in low power mode. + * When the system needs to enter low power mode, the tick is suppressed and a low power timer + * is used over that time + * Note that in sleep mode, the system clock is still running and the default tickless implementation + * using systick could have been kept. + * However, as at that time, it is not yet known whereas the low power mode that will be used is stop mode or + * sleep mode, it is easier and simpler to go with a low power timer as soon as the tick need to be + * suppressed. + */ +#if (CFG_LPM_SUPPORTED != 0) +void vPortSetupTimerInterrupt(void) +{ + LpTimerInit(); + + /* Calculate the constants required to configure the tick interrupt. */ + ulTimerCountsForOneTick = (configSYSTICK_CLOCK_HZ / configTICK_RATE_HZ); + + /* Stop and clear the SysTick. */ + portNVIC_SYSTICK_CTRL_REG = 0UL; + portNVIC_SYSTICK_CURRENT_VALUE_REG = 0UL; + + /* Configure SysTick to interrupt at the requested rate. */ + portNVIC_SYSTICK_LOAD_REG = (configSYSTICK_CLOCK_HZ / configTICK_RATE_HZ) - 1UL; + portNVIC_SYSTICK_CTRL_REG = (portNVIC_SYSTICK_CLK_BIT | portNVIC_SYSTICK_INT_BIT | portNVIC_SYSTICK_ENABLE_BIT); +} +#endif + +/** + * @brief The current implementation uses the hw_timerserver to provide a low power timer + * This may be replaced by another low power timer. + * + * @param None + * @retval None + */ +#if (CFG_LPM_SUPPORTED != 0) +static void LpTimerInit(void) +{ + (void) HW_TS_Create(CFG_TIM_PROC_ID_ISR, &(LpTimerContext.LpTimerFreeRTOS_Id), hw_ts_SingleShot, LpTimerCb); + + return; +} +#endif + +/** + * @brief Low power timer callback + * + * @param None + * @retval None + */ +#if (CFG_LPM_SUPPORTED != 0) +static void LpTimerCb(void) +{ + /** + * Nothing to be done + */ + + return; +} +#endif + +/** + * @brief Request to start a low power timer ( running is stop mode ) + * + * @param time_to_sleep : Number of FreeRTOS ticks + * @retval None + */ +#if (CFG_LPM_SUPPORTED != 0) +static void LpTimerStart(uint32_t time_to_sleep) +{ + uint64_t time; + + /* Converts the number of FreeRTOS ticks into hw timer tick */ + if (time_to_sleep > (ULLONG_MAX / 1e12)) /* Prevent overflow in else statement */ + { + time = 0xFFFF0000; /* Maximum value equal to 24 days */ + } + else + { + /* The result always fits in uint32_t and is always less than 0xFFFF0000 */ + time = time_to_sleep * 1000000000000ULL; + time = (uint64_t)(time / (CFG_TS_TICK_VAL_PS * configTICK_RATE_HZ)); + } + + HW_TS_Start(LpTimerContext.LpTimerFreeRTOS_Id, (uint32_t) time); + + /** + * There might be other timers already running in the timer server that may elapse + * before this one. + * Store how long before the next event so that on wakeup, it will be possible to calculate + * how long the tick has been suppressed + */ + LpTimerContext.LpTimeLeftOnEntry = HW_TS_RTC_ReadLeftTicksToCount(); + + return; +} +#endif + +/** + * @brief Enter low power mode + * + * @param None + * @retval None + */ +#if (CFG_LPM_SUPPORTED != 0) +static void LpEnter(void) +{ +#if (CFG_LPM_SUPPORTED == 1) + UTIL_LPM_EnterLowPower(); +#endif + return; +} +#endif + +/** + * @brief Read how long the tick has been suppressed + * + * @param None + * @retval The number of tick rate (FreeRTOS tick) + */ +#if (CFG_LPM_SUPPORTED != 0) +static uint32_t LpGetElapsedTime(void) +{ + uint64_t val_ticks, time_ps; + uint32_t LpTimeLeftOnExit; + + LpTimeLeftOnExit = HW_TS_RTC_ReadLeftTicksToCount(); + /* This cannot overflow. Max result is ~ 1.6e13 */ + time_ps = (uint64_t)((CFG_TS_TICK_VAL_PS) * (uint64_t)(LpTimerContext.LpTimeLeftOnEntry - LpTimeLeftOnExit)); + + /* time_ps can be less than 1 RTOS tick in following situations + * a) MCU didn't go to STOP2 due to wake-up unrelated to Timer Server or woke up from STOP2 very shortly after. + * Advancing RTOS clock by 1 FreeRTOS tick doesn't hurt in this case. + * b) vPortSuppressTicksAndSleep(xExpectedIdleTime) was called with xExpectedIdleTime = 2 which is minimum value defined by + * configEXPECTED_IDLE_TIME_BEFORE_SLEEP. The xExpectedIdleTime is decremented by one RTOS tick to wake-up in advance. Ex: RTOS + * tick is 1ms, the timer Server wakes the MCU in ~977 us. RTOS clock should be advanced by 1 ms. + * */ + if (time_ps <= (1e12 / configTICK_RATE_HZ)) /* time_ps < RTOS tick */ + { + val_ticks = 1; + } + else + { + /* Convert pS time into OS ticks */ + val_ticks = time_ps * configTICK_RATE_HZ; /* This cannot overflow. Max result is ~ 1.6e16 */ + val_ticks = (uint64_t)(val_ticks / (1e12)); /* The result always fits in uint32_t */ + } + + /** + * The system may have been out from another reason than the timer + * Stop the timer after the elapsed time is calculated other wise, HW_TS_RTC_ReadLeftTicksToCount() + * may return 0xFFFF ( TIMER LIST EMPTY ) + * It does not hurt stopping a timer that exists but is not running. + */ + HW_TS_Stop(LpTimerContext.LpTimerFreeRTOS_Id); + + return (uint32_t) val_ticks; +} +#endif diff --git a/examples/platform/stm32/common/STM32WB5MM-DK/Src/hw_timerserver.c b/examples/platform/stm32/common/STM32WB5MM-DK/Src/hw_timerserver.c new file mode 100644 index 00000000000000..7409e7f8910319 --- /dev/null +++ b/examples/platform/stm32/common/STM32WB5MM-DK/Src/hw_timerserver.c @@ -0,0 +1,899 @@ +/* USER CODE BEGIN Header */ +/** + ****************************************************************************** + * @file hw_timerserver.c + * @author MCD Application Team + * @brief Hardware timerserver source file for STM32WPAN Middleware. + ****************************************************************************** + * @attention + * + * Copyright (c) 2021 STMicroelectronics. + * All rights reserved. + * + * This software is licensed under terms that can be found in the LICENSE file + * in the root directory of this software component. + * If no LICENSE file comes with this software, it is provided AS-IS. + * + ****************************************************************************** + */ +/* USER CODE END Header */ + +/* Includes ------------------------------------------------------------------*/ +#include "app_common.h" +#include "hw_conf.h" + +/* Private typedef -----------------------------------------------------------*/ +typedef enum +{ + TimerID_Free, + TimerID_Created, + TimerID_Running +} TimerIDStatus_t; + +typedef enum +{ + SSR_Read_Requested, + SSR_Read_Not_Requested +} RequestReadSSR_t; + +typedef enum +{ + WakeupTimerValue_Overpassed, + WakeupTimerValue_LargeEnough +} WakeupTimerLimitation_Status_t; + +typedef struct +{ + HW_TS_pTimerCb_t pTimerCallBack; + uint32_t CounterInit; + uint32_t CountLeft; + TimerIDStatus_t TimerIDStatus; + HW_TS_Mode_t TimerMode; + uint32_t TimerProcessID; + uint8_t PreviousID; + uint8_t NextID; +} TimerContext_t; + +/* Private defines -----------------------------------------------------------*/ +#define SSR_FORBIDDEN_VALUE 0xFFFFFFFF +#define TIMER_LIST_EMPTY 0xFFFF + +/* Private macros ------------------------------------------------------------*/ +/* Private variables ---------------------------------------------------------*/ + +/** + * START of Section TIMERSERVER_CONTEXT + */ + +PLACE_IN_SECTION("TIMERSERVER_CONTEXT") static volatile TimerContext_t aTimerContext[CFG_HW_TS_MAX_NBR_CONCURRENT_TIMER]; +PLACE_IN_SECTION("TIMERSERVER_CONTEXT") static volatile uint8_t CurrentRunningTimerID; +PLACE_IN_SECTION("TIMERSERVER_CONTEXT") static volatile uint8_t PreviousRunningTimerID; +PLACE_IN_SECTION("TIMERSERVER_CONTEXT") static volatile uint32_t SSRValueOnLastSetup; +PLACE_IN_SECTION("TIMERSERVER_CONTEXT") static volatile WakeupTimerLimitation_Status_t WakeupTimerLimitation; + +/** + * END of Section TIMERSERVER_CONTEXT + */ + +static RTC_HandleTypeDef * phrtc; /**< RTC handle */ +static uint8_t WakeupTimerDivider; +static uint8_t AsynchPrescalerUserConfig; +static uint16_t SynchPrescalerUserConfig; +static volatile uint16_t MaxWakeupTimerSetup; + +/* Global variables ----------------------------------------------------------*/ +/* Private function prototypes -----------------------------------------------*/ +static void RestartWakeupCounter(uint16_t Value); +static uint16_t ReturnTimeElapsed(void); +static void RescheduleTimerList(void); +static void UnlinkTimer(uint8_t TimerID, RequestReadSSR_t RequestReadSSR); +static void LinkTimerBefore(uint8_t TimerID, uint8_t RefTimerID); +static void LinkTimerAfter(uint8_t TimerID, uint8_t RefTimerID); +static uint16_t linkTimer(uint8_t TimerID); +static uint32_t ReadRtcSsrValue(void); + +__weak void HW_TS_RTC_CountUpdated_AppNot(void); + +/* Functions Definition ------------------------------------------------------*/ + +/** + * @brief Read the RTC_SSR value + * As described in the reference manual, the RTC_SSR shall be read twice to ensure + * reliability of the value + * @param None + * @retval SSR value read + */ +static uint32_t ReadRtcSsrValue(void) +{ + uint32_t first_read; + uint32_t second_read; + + first_read = (uint32_t)(READ_BIT(RTC->SSR, RTC_SSR_SS)); + + second_read = (uint32_t)(READ_BIT(RTC->SSR, RTC_SSR_SS)); + + while (first_read != second_read) + { + first_read = second_read; + + second_read = (uint32_t)(READ_BIT(RTC->SSR, RTC_SSR_SS)); + } + + return second_read; +} + +/** + * @brief Insert a Timer in the list after the Timer ID specified + * @param TimerID: The ID of the Timer + * @param RefTimerID: The ID of the Timer to be linked after + * @retval None + */ +static void LinkTimerAfter(uint8_t TimerID, uint8_t RefTimerID) +{ + uint8_t next_id; + + next_id = aTimerContext[RefTimerID].NextID; + + if (next_id != CFG_HW_TS_MAX_NBR_CONCURRENT_TIMER) + { + aTimerContext[next_id].PreviousID = TimerID; + } + aTimerContext[TimerID].NextID = next_id; + aTimerContext[TimerID].PreviousID = RefTimerID; + aTimerContext[RefTimerID].NextID = TimerID; + + return; +} + +/** + * @brief Insert a Timer in the list before the ID specified + * @param TimerID: The ID of the Timer + * @param RefTimerID: The ID of the Timer to be linked before + * @retval None + */ +static void LinkTimerBefore(uint8_t TimerID, uint8_t RefTimerID) +{ + uint8_t previous_id; + + if (RefTimerID != CurrentRunningTimerID) + { + previous_id = aTimerContext[RefTimerID].PreviousID; + + aTimerContext[previous_id].NextID = TimerID; + aTimerContext[TimerID].NextID = RefTimerID; + aTimerContext[TimerID].PreviousID = previous_id; + aTimerContext[RefTimerID].PreviousID = TimerID; + } + else + { + aTimerContext[TimerID].NextID = RefTimerID; + aTimerContext[RefTimerID].PreviousID = TimerID; + } + + return; +} + +/** + * @brief Insert a Timer in the list + * @param TimerID: The ID of the Timer + * @retval None + */ +static uint16_t linkTimer(uint8_t TimerID) +{ + uint32_t time_left; + uint16_t time_elapsed; + uint8_t timer_id_lookup; + uint8_t next_id; + + if (CurrentRunningTimerID == CFG_HW_TS_MAX_NBR_CONCURRENT_TIMER) + { + /** + * No timer in the list + */ + PreviousRunningTimerID = CurrentRunningTimerID; + CurrentRunningTimerID = TimerID; + aTimerContext[TimerID].NextID = CFG_HW_TS_MAX_NBR_CONCURRENT_TIMER; + + SSRValueOnLastSetup = SSR_FORBIDDEN_VALUE; + time_elapsed = 0; + } + else + { + time_elapsed = ReturnTimeElapsed(); + + /** + * update count of the timer to be linked + */ + aTimerContext[TimerID].CountLeft += time_elapsed; + time_left = aTimerContext[TimerID].CountLeft; + + /** + * Search for index where the new timer shall be linked + */ + if (aTimerContext[CurrentRunningTimerID].CountLeft <= time_left) + { + /** + * Search for the ID after the first one + */ + timer_id_lookup = CurrentRunningTimerID; + next_id = aTimerContext[timer_id_lookup].NextID; + while ((next_id != CFG_HW_TS_MAX_NBR_CONCURRENT_TIMER) && (aTimerContext[next_id].CountLeft <= time_left)) + { + timer_id_lookup = aTimerContext[timer_id_lookup].NextID; + next_id = aTimerContext[timer_id_lookup].NextID; + } + + /** + * Link after the ID + */ + LinkTimerAfter(TimerID, timer_id_lookup); + } + else + { + /** + * Link before the first ID + */ + LinkTimerBefore(TimerID, CurrentRunningTimerID); + PreviousRunningTimerID = CurrentRunningTimerID; + CurrentRunningTimerID = TimerID; + } + } + + return time_elapsed; +} + +/** + * @brief Remove a Timer from the list + * @param TimerID: The ID of the Timer + * @param RequestReadSSR: Request to read the SSR register or not + * @retval None + */ +static void UnlinkTimer(uint8_t TimerID, RequestReadSSR_t RequestReadSSR) +{ + uint8_t previous_id; + uint8_t next_id; + + if (TimerID == CurrentRunningTimerID) + { + PreviousRunningTimerID = CurrentRunningTimerID; + CurrentRunningTimerID = aTimerContext[TimerID].NextID; + } + else + { + previous_id = aTimerContext[TimerID].PreviousID; + next_id = aTimerContext[TimerID].NextID; + + aTimerContext[previous_id].NextID = aTimerContext[TimerID].NextID; + if (next_id != CFG_HW_TS_MAX_NBR_CONCURRENT_TIMER) + { + aTimerContext[next_id].PreviousID = aTimerContext[TimerID].PreviousID; + } + } + + /** + * Timer is out of the list + */ + aTimerContext[TimerID].TimerIDStatus = TimerID_Created; + + if ((CurrentRunningTimerID == CFG_HW_TS_MAX_NBR_CONCURRENT_TIMER) && (RequestReadSSR == SSR_Read_Requested)) + { + SSRValueOnLastSetup = SSR_FORBIDDEN_VALUE; + } + + return; +} + +/** + * @brief Return the number of ticks counted by the wakeuptimer since it has been started + * @note The API is reading the SSR register to get how many ticks have been counted + * since the time the timer has been started + * @param None + * @retval Time expired in Ticks + */ +static uint16_t ReturnTimeElapsed(void) +{ + uint32_t return_value; + uint32_t wrap_counter; + + if (SSRValueOnLastSetup != SSR_FORBIDDEN_VALUE) + { + return_value = ReadRtcSsrValue(); /**< Read SSR register first */ + + if (SSRValueOnLastSetup >= return_value) + { + return_value = SSRValueOnLastSetup - return_value; + } + else + { + wrap_counter = SynchPrescalerUserConfig - return_value; + return_value = SSRValueOnLastSetup + wrap_counter; + } + + /** + * At this stage, ReturnValue holds the number of ticks counted by SSR + * Need to translate in number of ticks counted by the Wakeuptimer + */ + return_value = return_value * AsynchPrescalerUserConfig; + return_value = return_value >> WakeupTimerDivider; + } + else + { + return_value = 0; + } + + return (uint16_t) return_value; +} + +/** + * @brief Set the wakeup counter + * @note The API is writing the counter value so that the value is decreased by one to cope with the fact + * the interrupt is generated with 1 extra clock cycle (See RefManuel) + * It assumes all condition are met to be allowed to write the wakeup counter + * @param Value: Value to be written in the counter + * @retval None + */ +static void RestartWakeupCounter(uint16_t Value) +{ + /** + * The wakeuptimer has been disabled in the calling function to reduce the time to poll the WUTWF + * FLAG when the new value will have to be written + * __HAL_RTC_WAKEUPTIMER_DISABLE(phrtc); + */ + + if (Value == 0) + { + SSRValueOnLastSetup = ReadRtcSsrValue(); + + /** + * Simulate that the Timer expired + */ + HAL_NVIC_SetPendingIRQ(CFG_HW_TS_RTC_WAKEUP_HANDLER_ID); + } + else + { + if ((Value > 1) || (WakeupTimerDivider != 1)) + { + Value -= 1; + } + + while (__HAL_RTC_WAKEUPTIMER_GET_FLAG(phrtc, RTC_FLAG_WUTWF) == RESET) + ; + + /** + * make sure to clear the flags after checking the WUTWF. + * It takes 2 RTCCLK between the time the WUTE bit is disabled and the + * time the timer is disabled. The WUTWF bit somehow guarantee the system is stable + * Otherwise, when the timer is periodic with 1 Tick, it may generate an extra interrupt in between + * due to the autoreload feature + */ + __HAL_RTC_WAKEUPTIMER_CLEAR_FLAG(phrtc, RTC_FLAG_WUTF); /**< Clear flag in RTC module */ + __HAL_RTC_WAKEUPTIMER_EXTI_CLEAR_FLAG(); /**< Clear flag in EXTI module */ + HAL_NVIC_ClearPendingIRQ(CFG_HW_TS_RTC_WAKEUP_HANDLER_ID); /**< Clear pending bit in NVIC */ + + MODIFY_REG(RTC->WUTR, RTC_WUTR_WUT, Value); + + /** + * Update the value here after the WUTWF polling that may take some time + */ + SSRValueOnLastSetup = ReadRtcSsrValue(); + + __HAL_RTC_WAKEUPTIMER_ENABLE(phrtc); /**< Enable the Wakeup Timer */ + + HW_TS_RTC_CountUpdated_AppNot(); + } + + return; +} + +/** + * @brief Reschedule the list of timer + * @note 1) Update the count left for each timer in the list + * 2) Setup the wakeuptimer + * @param None + * @retval None + */ +static void RescheduleTimerList(void) +{ + uint8_t localTimerID; + uint32_t timecountleft; + uint16_t wakeup_timer_value; + uint16_t time_elapsed; + + /** + * The wakeuptimer is disabled now to reduce the time to poll the WUTWF + * FLAG when the new value will have to be written + */ + if ((READ_BIT(RTC->CR, RTC_CR_WUTE) == (RTC_CR_WUTE)) == SET) + { + /** + * Wait for the flag to be back to 0 when the wakeup timer is enabled + */ + while (__HAL_RTC_WAKEUPTIMER_GET_FLAG(phrtc, RTC_FLAG_WUTWF) == SET) + ; + } + __HAL_RTC_WAKEUPTIMER_DISABLE(phrtc); /**< Disable the Wakeup Timer */ + + localTimerID = CurrentRunningTimerID; + + /** + * Calculate what will be the value to write in the wakeuptimer + */ + timecountleft = aTimerContext[localTimerID].CountLeft; + + /** + * Read how much has been counted + */ + time_elapsed = ReturnTimeElapsed(); + + if (timecountleft < time_elapsed) + { + /** + * There is no tick left to count + */ + wakeup_timer_value = 0; + WakeupTimerLimitation = WakeupTimerValue_LargeEnough; + } + else + { + if (timecountleft > (time_elapsed + MaxWakeupTimerSetup)) + { + /** + * The number of tick left is greater than the Wakeuptimer maximum value + */ + wakeup_timer_value = MaxWakeupTimerSetup; + + WakeupTimerLimitation = WakeupTimerValue_Overpassed; + } + else + { + wakeup_timer_value = timecountleft - time_elapsed; + WakeupTimerLimitation = WakeupTimerValue_LargeEnough; + } + } + + /** + * update ticks left to be counted for each timer + */ + while (localTimerID != CFG_HW_TS_MAX_NBR_CONCURRENT_TIMER) + { + if (aTimerContext[localTimerID].CountLeft < time_elapsed) + { + aTimerContext[localTimerID].CountLeft = 0; + } + else + { + aTimerContext[localTimerID].CountLeft -= time_elapsed; + } + localTimerID = aTimerContext[localTimerID].NextID; + } + + /** + * Write next count + */ + RestartWakeupCounter(wakeup_timer_value); + + return; +} + +/* Public functions ----------------------------------------------------------*/ + +/** + * For all public interface except that may need write access to the RTC, the RTC + * shall be unlock at the beginning and locked at the output + * In order to ease maintainability, the unlock is done at the top and the lock at then end + * in case some new implementation is coming in the future + */ + +void HW_TS_RTC_Wakeup_Handler(void) +{ + HW_TS_pTimerCb_t ptimer_callback; + uint32_t timer_process_id; + uint8_t local_current_running_timer_id; +#if (CFG_HW_TS_USE_PRIMASK_AS_CRITICAL_SECTION == 1) + uint32_t primask_bit; +#endif + +#if (CFG_HW_TS_USE_PRIMASK_AS_CRITICAL_SECTION == 1) + primask_bit = __get_PRIMASK(); /**< backup PRIMASK bit */ + __disable_irq(); /**< Disable all interrupts by setting PRIMASK bit on Cortex*/ +#endif + + /* Disable the write protection for RTC registers */ + __HAL_RTC_WRITEPROTECTION_DISABLE(phrtc); + + /** + * Disable the Wakeup Timer + * This may speed up a bit the processing to wait the timer to be disabled + * The timer is still counting 2 RTCCLK + */ + __HAL_RTC_WAKEUPTIMER_DISABLE(phrtc); + + local_current_running_timer_id = CurrentRunningTimerID; + + if (aTimerContext[local_current_running_timer_id].TimerIDStatus == TimerID_Running) + { + ptimer_callback = aTimerContext[local_current_running_timer_id].pTimerCallBack; + timer_process_id = aTimerContext[local_current_running_timer_id].TimerProcessID; + + /** + * It should be good to check whether the TimeElapsed is greater or not than the tick left to be counted + * However, due to the inaccuracy of the reading of the time elapsed, it may return there is 1 tick + * to be left whereas the count is over + * A more secure implementation has been done with a flag to state whereas the full count has been written + * in the wakeuptimer or not + */ + if (WakeupTimerLimitation != WakeupTimerValue_Overpassed) + { + if (aTimerContext[local_current_running_timer_id].TimerMode == hw_ts_Repeated) + { + UnlinkTimer(local_current_running_timer_id, SSR_Read_Not_Requested); +#if (CFG_HW_TS_USE_PRIMASK_AS_CRITICAL_SECTION == 1) + __set_PRIMASK(primask_bit); /**< Restore PRIMASK bit*/ +#endif + HW_TS_Start(local_current_running_timer_id, aTimerContext[local_current_running_timer_id].CounterInit); + + /* Disable the write protection for RTC registers */ + __HAL_RTC_WRITEPROTECTION_DISABLE(phrtc); + } + else + { +#if (CFG_HW_TS_USE_PRIMASK_AS_CRITICAL_SECTION == 1) + __set_PRIMASK(primask_bit); /**< Restore PRIMASK bit*/ +#endif + HW_TS_Stop(local_current_running_timer_id); + + /* Disable the write protection for RTC registers */ + __HAL_RTC_WRITEPROTECTION_DISABLE(phrtc); + } + + HW_TS_RTC_Int_AppNot(timer_process_id, local_current_running_timer_id, ptimer_callback); + } + else + { + RescheduleTimerList(); +#if (CFG_HW_TS_USE_PRIMASK_AS_CRITICAL_SECTION == 1) + __set_PRIMASK(primask_bit); /**< Restore PRIMASK bit*/ +#endif + } + } + else + { + /** + * We should never end up in this case + * However, if due to any bug in the timer server this is the case, the mistake may not impact the user. + * We could just clean the interrupt flag and get out from this unexpected interrupt + */ + while (__HAL_RTC_WAKEUPTIMER_GET_FLAG(phrtc, RTC_FLAG_WUTWF) == RESET) + ; + + /** + * make sure to clear the flags after checking the WUTWF. + * It takes 2 RTCCLK between the time the WUTE bit is disabled and the + * time the timer is disabled. The WUTWF bit somehow guarantee the system is stable + * Otherwise, when the timer is periodic with 1 Tick, it may generate an extra interrupt in between + * due to the autoreload feature + */ + __HAL_RTC_WAKEUPTIMER_CLEAR_FLAG(phrtc, RTC_FLAG_WUTF); /**< Clear flag in RTC module */ + __HAL_RTC_WAKEUPTIMER_EXTI_CLEAR_FLAG(); /**< Clear flag in EXTI module */ + +#if (CFG_HW_TS_USE_PRIMASK_AS_CRITICAL_SECTION == 1) + __set_PRIMASK(primask_bit); /**< Restore PRIMASK bit*/ +#endif + } + + /* Enable the write protection for RTC registers */ + __HAL_RTC_WRITEPROTECTION_ENABLE(phrtc); + + return; +} + +void HW_TS_Init(HW_TS_InitMode_t TimerInitMode, RTC_HandleTypeDef * hrtc) +{ + uint8_t loop; + uint32_t localmaxwakeuptimersetup; + + /** + * Get RTC handler + */ + phrtc = hrtc; + + /* Disable the write protection for RTC registers */ + __HAL_RTC_WRITEPROTECTION_DISABLE(phrtc); + + SET_BIT(RTC->CR, RTC_CR_BYPSHAD); + + /** + * Readout the user config + */ + WakeupTimerDivider = (4 - ((uint32_t)(READ_BIT(RTC->CR, RTC_CR_WUCKSEL)))); + + AsynchPrescalerUserConfig = (uint8_t)(READ_BIT(RTC->PRER, RTC_PRER_PREDIV_A) >> (uint32_t) POSITION_VAL(RTC_PRER_PREDIV_A)) + 1; + + SynchPrescalerUserConfig = (uint16_t)(READ_BIT(RTC->PRER, RTC_PRER_PREDIV_S)) + 1; + + /** + * Margin is taken to avoid wrong calculation when the wrap around is there and some + * application interrupts may have delayed the reading + */ + localmaxwakeuptimersetup = + ((((SynchPrescalerUserConfig - 1) * AsynchPrescalerUserConfig) - CFG_HW_TS_RTC_HANDLER_MAX_DELAY) >> WakeupTimerDivider); + + if (localmaxwakeuptimersetup >= 0xFFFF) + { + MaxWakeupTimerSetup = 0xFFFF; + } + else + { + MaxWakeupTimerSetup = (uint16_t) localmaxwakeuptimersetup; + } + + /** + * Configure EXTI module + */ + LL_EXTI_EnableRisingTrig_0_31(RTC_EXTI_LINE_WAKEUPTIMER_EVENT); + LL_EXTI_EnableIT_0_31(RTC_EXTI_LINE_WAKEUPTIMER_EVENT); + + if (TimerInitMode == hw_ts_InitMode_Full) + { + WakeupTimerLimitation = WakeupTimerValue_LargeEnough; + SSRValueOnLastSetup = SSR_FORBIDDEN_VALUE; + + /** + * Initialize the timer server + */ + for (loop = 0; loop < CFG_HW_TS_MAX_NBR_CONCURRENT_TIMER; loop++) + { + aTimerContext[loop].TimerIDStatus = TimerID_Free; + } + + CurrentRunningTimerID = CFG_HW_TS_MAX_NBR_CONCURRENT_TIMER; /**< Set ID to non valid value */ + + __HAL_RTC_WAKEUPTIMER_DISABLE(phrtc); /**< Disable the Wakeup Timer */ + __HAL_RTC_WAKEUPTIMER_CLEAR_FLAG(phrtc, RTC_FLAG_WUTF); /**< Clear flag in RTC module */ + __HAL_RTC_WAKEUPTIMER_EXTI_CLEAR_FLAG(); /**< Clear flag in EXTI module */ + HAL_NVIC_ClearPendingIRQ(CFG_HW_TS_RTC_WAKEUP_HANDLER_ID); /**< Clear pending bit in NVIC */ + __HAL_RTC_WAKEUPTIMER_ENABLE_IT(phrtc, RTC_IT_WUT); /**< Enable interrupt in RTC module */ + } + else + { + if (__HAL_RTC_WAKEUPTIMER_GET_FLAG(phrtc, RTC_FLAG_WUTF) != RESET) + { + /** + * Simulate that the Timer expired + */ + HAL_NVIC_SetPendingIRQ(CFG_HW_TS_RTC_WAKEUP_HANDLER_ID); + } + } + + /* Enable the write protection for RTC registers */ + __HAL_RTC_WRITEPROTECTION_ENABLE(phrtc); + + HAL_NVIC_SetPriority(CFG_HW_TS_RTC_WAKEUP_HANDLER_ID, CFG_HW_TS_NVIC_RTC_WAKEUP_IT_PREEMPTPRIO, + CFG_HW_TS_NVIC_RTC_WAKEUP_IT_SUBPRIO); /**< Set NVIC priority */ + HAL_NVIC_EnableIRQ(CFG_HW_TS_RTC_WAKEUP_HANDLER_ID); /**< Enable NVIC */ + + return; +} + +HW_TS_ReturnStatus_t HW_TS_Create(uint32_t TimerProcessID, uint8_t * pTimerId, HW_TS_Mode_t TimerMode, + HW_TS_pTimerCb_t pftimeout_handler) +{ + HW_TS_ReturnStatus_t localreturnstatus; + uint8_t loop = 0; +#if (CFG_HW_TS_USE_PRIMASK_AS_CRITICAL_SECTION == 1) + uint32_t primask_bit; +#endif + +#if (CFG_HW_TS_USE_PRIMASK_AS_CRITICAL_SECTION == 1) + primask_bit = __get_PRIMASK(); /**< backup PRIMASK bit */ + __disable_irq(); /**< Disable all interrupts by setting PRIMASK bit on Cortex*/ +#endif + + while ((loop < CFG_HW_TS_MAX_NBR_CONCURRENT_TIMER) && (aTimerContext[loop].TimerIDStatus != TimerID_Free)) + { + loop++; + } + + if (loop != CFG_HW_TS_MAX_NBR_CONCURRENT_TIMER) + { + aTimerContext[loop].TimerIDStatus = TimerID_Created; + +#if (CFG_HW_TS_USE_PRIMASK_AS_CRITICAL_SECTION == 1) + __set_PRIMASK(primask_bit); /**< Restore PRIMASK bit*/ +#endif + + aTimerContext[loop].TimerProcessID = TimerProcessID; + aTimerContext[loop].TimerMode = TimerMode; + aTimerContext[loop].pTimerCallBack = pftimeout_handler; + *pTimerId = loop; + + localreturnstatus = hw_ts_Successful; + } + else + { +#if (CFG_HW_TS_USE_PRIMASK_AS_CRITICAL_SECTION == 1) + __set_PRIMASK(primask_bit); /**< Restore PRIMASK bit*/ +#endif + + localreturnstatus = hw_ts_Failed; + } + + return (localreturnstatus); +} + +void HW_TS_Delete(uint8_t timer_id) +{ + HW_TS_Stop(timer_id); + + aTimerContext[timer_id].TimerIDStatus = TimerID_Free; /**< release ID */ + + return; +} + +void HW_TS_Stop(uint8_t timer_id) +{ + uint8_t localcurrentrunningtimerid; + +#if (CFG_HW_TS_USE_PRIMASK_AS_CRITICAL_SECTION == 1) + uint32_t primask_bit; +#endif + +#if (CFG_HW_TS_USE_PRIMASK_AS_CRITICAL_SECTION == 1) + primask_bit = __get_PRIMASK(); /**< backup PRIMASK bit */ + __disable_irq(); /**< Disable all interrupts by setting PRIMASK bit on Cortex*/ +#endif + + HAL_NVIC_DisableIRQ(CFG_HW_TS_RTC_WAKEUP_HANDLER_ID); /**< Disable NVIC */ + + /* Disable the write protection for RTC registers */ + __HAL_RTC_WRITEPROTECTION_DISABLE(phrtc); + + if (aTimerContext[timer_id].TimerIDStatus == TimerID_Running) + { + UnlinkTimer(timer_id, SSR_Read_Requested); + localcurrentrunningtimerid = CurrentRunningTimerID; + + if (localcurrentrunningtimerid == CFG_HW_TS_MAX_NBR_CONCURRENT_TIMER) + { + /** + * List is empty + */ + + /** + * Disable the timer + */ + if ((READ_BIT(RTC->CR, RTC_CR_WUTE) == (RTC_CR_WUTE)) == SET) + { + /** + * Wait for the flag to be back to 0 when the wakeup timer is enabled + */ + while (__HAL_RTC_WAKEUPTIMER_GET_FLAG(phrtc, RTC_FLAG_WUTWF) == SET) + ; + } + __HAL_RTC_WAKEUPTIMER_DISABLE(phrtc); /**< Disable the Wakeup Timer */ + + while (__HAL_RTC_WAKEUPTIMER_GET_FLAG(phrtc, RTC_FLAG_WUTWF) == RESET) + ; + + /** + * make sure to clear the flags after checking the WUTWF. + * It takes 2 RTCCLK between the time the WUTE bit is disabled and the + * time the timer is disabled. The WUTWF bit somehow guarantee the system is stable + * Otherwise, when the timer is periodic with 1 Tick, it may generate an extra interrupt in between + * due to the autoreload feature + */ + __HAL_RTC_WAKEUPTIMER_CLEAR_FLAG(phrtc, RTC_FLAG_WUTF); /**< Clear flag in RTC module */ + __HAL_RTC_WAKEUPTIMER_EXTI_CLEAR_FLAG(); /**< Clear flag in EXTI module */ + HAL_NVIC_ClearPendingIRQ(CFG_HW_TS_RTC_WAKEUP_HANDLER_ID); /**< Clear pending bit in NVIC */ + } + else if (PreviousRunningTimerID != localcurrentrunningtimerid) + { + RescheduleTimerList(); + } + } + + /* Enable the write protection for RTC registers */ + __HAL_RTC_WRITEPROTECTION_ENABLE(phrtc); + + HAL_NVIC_EnableIRQ(CFG_HW_TS_RTC_WAKEUP_HANDLER_ID); /**< Enable NVIC */ + +#if (CFG_HW_TS_USE_PRIMASK_AS_CRITICAL_SECTION == 1) + __set_PRIMASK(primask_bit); /**< Restore PRIMASK bit*/ +#endif + + return; +} + +void HW_TS_Start(uint8_t timer_id, uint32_t timeout_ticks) +{ + uint16_t time_elapsed; + uint8_t localcurrentrunningtimerid; + +#if (CFG_HW_TS_USE_PRIMASK_AS_CRITICAL_SECTION == 1) + uint32_t primask_bit; +#endif + + if (aTimerContext[timer_id].TimerIDStatus == TimerID_Running) + { + HW_TS_Stop(timer_id); + } + +#if (CFG_HW_TS_USE_PRIMASK_AS_CRITICAL_SECTION == 1) + primask_bit = __get_PRIMASK(); /**< backup PRIMASK bit */ + __disable_irq(); /**< Disable all interrupts by setting PRIMASK bit on Cortex*/ +#endif + + HAL_NVIC_DisableIRQ(CFG_HW_TS_RTC_WAKEUP_HANDLER_ID); /**< Disable NVIC */ + + /* Disable the write protection for RTC registers */ + __HAL_RTC_WRITEPROTECTION_DISABLE(phrtc); + + aTimerContext[timer_id].TimerIDStatus = TimerID_Running; + + aTimerContext[timer_id].CountLeft = timeout_ticks; + aTimerContext[timer_id].CounterInit = timeout_ticks; + + time_elapsed = linkTimer(timer_id); + + localcurrentrunningtimerid = CurrentRunningTimerID; + + if (PreviousRunningTimerID != localcurrentrunningtimerid) + { + RescheduleTimerList(); + } + else + { + aTimerContext[timer_id].CountLeft -= time_elapsed; + } + + /* Enable the write protection for RTC registers */ + __HAL_RTC_WRITEPROTECTION_ENABLE(phrtc); + + HAL_NVIC_EnableIRQ(CFG_HW_TS_RTC_WAKEUP_HANDLER_ID); /**< Enable NVIC */ + +#if (CFG_HW_TS_USE_PRIMASK_AS_CRITICAL_SECTION == 1) + __set_PRIMASK(primask_bit); /**< Restore PRIMASK bit*/ +#endif + + return; +} + +uint16_t HW_TS_RTC_ReadLeftTicksToCount(void) +{ + uint32_t primask_bit; + uint16_t return_value, auro_reload_value, elapsed_time_value; + + primask_bit = __get_PRIMASK(); /**< backup PRIMASK bit */ + __disable_irq(); /**< Disable all interrupts by setting PRIMASK bit on Cortex*/ + + if ((READ_BIT(RTC->CR, RTC_CR_WUTE) == (RTC_CR_WUTE)) == SET) + { + auro_reload_value = (uint32_t)(READ_BIT(RTC->WUTR, RTC_WUTR_WUT)); + + elapsed_time_value = ReturnTimeElapsed(); + + if (auro_reload_value > elapsed_time_value) + { + return_value = auro_reload_value - elapsed_time_value; + } + else + { + return_value = 0; + } + } + else + { + return_value = TIMER_LIST_EMPTY; + } + + __set_PRIMASK(primask_bit); /**< Restore PRIMASK bit*/ + + return (return_value); +} + +__weak void HW_TS_RTC_Int_AppNot(uint32_t TimerProcessID, uint8_t TimerID, HW_TS_pTimerCb_t pTimerCallBack) +{ + pTimerCallBack(); + + return; +} diff --git a/examples/platform/stm32/common/STM32WB5MM-DK/Src/hw_uart.c b/examples/platform/stm32/common/STM32WB5MM-DK/Src/hw_uart.c new file mode 100644 index 00000000000000..f647dc4f87993f --- /dev/null +++ b/examples/platform/stm32/common/STM32WB5MM-DK/Src/hw_uart.c @@ -0,0 +1,469 @@ +/** + ****************************************************************************** + * @file hw_uart.c + * @author MCD Application Team + * @brief hardware access + ****************************************************************************** + * @attention + * + * Copyright (c) 2018(-2021) STMicroelectronics. + * All rights reserved. + * + * This software is licensed under terms that can be found in the LICENSE file + * in the root directory of this software component. + * If no LICENSE file comes with this software, it is provided AS-IS. + * + ****************************************************************************** + */ + +/* Includes ------------------------------------------------------------------*/ +#include "app_common.h" +#include "hw_conf.h" + +/* Macros --------------------------------------------------------------------*/ +#define HW_UART_INIT(__HANDLE__, __USART_BASE__) \ + do \ + { \ + (__HANDLE__).Instance = (__USART_BASE__); \ + (__HANDLE__).Init.BaudRate = CFG_HW_##__USART_BASE__##_BAUDRATE; \ + (__HANDLE__).Init.WordLength = CFG_HW_##__USART_BASE__##_WORDLENGTH; \ + (__HANDLE__).Init.StopBits = CFG_HW_##__USART_BASE__##_STOPBITS; \ + (__HANDLE__).Init.Parity = CFG_HW_##__USART_BASE__##_PARITY; \ + (__HANDLE__).Init.HwFlowCtl = CFG_HW_##__USART_BASE__##_HWFLOWCTL; \ + (__HANDLE__).Init.Mode = CFG_HW_##__USART_BASE__##_MODE; \ + (__HANDLE__).Init.OverSampling = CFG_HW_##__USART_BASE__##_OVERSAMPLING; \ + (__HANDLE__).AdvancedInit.AdvFeatureInit = CFG_HW_##__USART_BASE__##_ADVFEATUREINIT; \ + HAL_UART_Init(&(__HANDLE__)); \ + } while (0) + +#define HW_UART_RX_IT(__HANDLE__, __USART_BASE__) \ + do \ + { \ + HW_##__HANDLE__##RxCb = cb; \ + (__HANDLE__).Instance = (__USART_BASE__); \ + HAL_UART_Receive_IT(&(__HANDLE__), p_data, size); \ + } while (0) + +#define HW_UART_TX_IT(__HANDLE__, __USART_BASE__) \ + do \ + { \ + HW_##__HANDLE__##TxCb = cb; \ + (__HANDLE__).Instance = (__USART_BASE__); \ + HAL_UART_Transmit_IT(&(__HANDLE__), p_data, size); \ + } while (0) + +#define HW_UART_TX(__HANDLE__, __USART_BASE__) \ + do \ + { \ + (__HANDLE__).Instance = (__USART_BASE__); \ + hal_status = HAL_UART_Transmit(&(__HANDLE__), p_data, size, timeout); \ + } while (0) + +#define HW_UART_MSP_UART_INIT(__HANDLE__, __USART_BASE__) \ + do \ + { \ + /* Enable GPIO clock */ \ + CFG_HW_##__USART_BASE__##_TX_PORT_CLK_ENABLE(); \ + \ + /* Enable USART clock */ \ + __HAL_RCC_##__USART_BASE__##_CLK_ENABLE(); \ + \ + GPIO_InitStruct.Pin = CFG_HW_##__USART_BASE__##_TX_PIN; \ + GPIO_InitStruct.Mode = CFG_HW_##__USART_BASE__##_TX_MODE; \ + GPIO_InitStruct.Pull = CFG_HW_##__USART_BASE__##_TX_PULL; \ + GPIO_InitStruct.Speed = CFG_HW_##__USART_BASE__##_TX_SPEED; \ + GPIO_InitStruct.Alternate = CFG_HW_##__USART_BASE__##_TX_ALTERNATE; \ + \ + HAL_GPIO_Init(CFG_HW_##__USART_BASE__##_TX_PORT, &GPIO_InitStruct); \ + \ + CFG_HW_##__USART_BASE__##_RX_PORT_CLK_ENABLE(); \ + \ + GPIO_InitStruct.Pin = CFG_HW_##__USART_BASE__##_RX_PIN; \ + GPIO_InitStruct.Mode = CFG_HW_##__USART_BASE__##_RX_MODE; \ + GPIO_InitStruct.Pull = CFG_HW_##__USART_BASE__##_RX_PULL; \ + GPIO_InitStruct.Speed = CFG_HW_##__USART_BASE__##_RX_SPEED; \ + GPIO_InitStruct.Alternate = CFG_HW_##__USART_BASE__##_RX_ALTERNATE; \ + \ + HAL_GPIO_Init(CFG_HW_##__USART_BASE__##_RX_PORT, &GPIO_InitStruct); \ + \ + CFG_HW_##__USART_BASE__##_CTS_PORT_CLK_ENABLE(); \ + \ + GPIO_InitStruct.Pin = CFG_HW_##__USART_BASE__##_CTS_PIN; \ + GPIO_InitStruct.Mode = CFG_HW_##__USART_BASE__##_CTS_MODE; \ + GPIO_InitStruct.Pull = CFG_HW_##__USART_BASE__##_CTS_PULL; \ + GPIO_InitStruct.Speed = CFG_HW_##__USART_BASE__##_CTS_SPEED; \ + GPIO_InitStruct.Alternate = CFG_HW_##__USART_BASE__##_CTS_ALTERNATE; \ + \ + HAL_GPIO_Init(CFG_HW_##__USART_BASE__##_CTS_PORT, &GPIO_InitStruct); \ + \ + HAL_NVIC_SetPriority(__USART_BASE__##_IRQn, CFG_HW_##__USART_BASE__##_PREEMPTPRIORITY, \ + CFG_HW_##__USART_BASE__##_SUBPRIORITY); \ + HAL_NVIC_EnableIRQ(__USART_BASE__##_IRQn); \ + } while (0) + +#define HW_UART_MSP_TX_DMA_INIT(__HANDLE__, __USART_BASE__) \ + do \ + { \ + /* Configure the DMA handler for Transmission process */ \ + /* Enable DMA clock */ \ + CFG_HW_##__USART_BASE__##_DMA_CLK_ENABLE(); \ + /* Enable DMA MUX clock */ \ + CFG_HW_##__USART_BASE__##_DMAMUX_CLK_ENABLE(); \ + \ + HW_hdma_##__HANDLE__##_tx.Instance = CFG_HW_##__USART_BASE__##_TX_DMA_CHANNEL; \ + HW_hdma_##__HANDLE__##_tx.Init.Request = CFG_HW_##__USART_BASE__##_TX_DMA_REQ; \ + HW_hdma_##__HANDLE__##_tx.Init.Direction = DMA_MEMORY_TO_PERIPH; \ + HW_hdma_##__HANDLE__##_tx.Init.PeriphInc = DMA_PINC_DISABLE; \ + HW_hdma_##__HANDLE__##_tx.Init.MemInc = DMA_MINC_ENABLE; \ + HW_hdma_##__HANDLE__##_tx.Init.PeriphDataAlignment = DMA_PDATAALIGN_BYTE; \ + HW_hdma_##__HANDLE__##_tx.Init.MemDataAlignment = DMA_MDATAALIGN_BYTE; \ + HW_hdma_##__HANDLE__##_tx.Init.Mode = DMA_NORMAL; \ + HW_hdma_##__HANDLE__##_tx.Init.Priority = DMA_PRIORITY_LOW; \ + \ + HAL_DMA_Init(&HW_hdma_##__HANDLE__##_tx); \ + \ + /* Associate the initialized DMA handle to the UART handle */ \ + __HAL_LINKDMA(huart, hdmatx, HW_hdma_##__HANDLE__##_tx); \ + \ + /* NVIC configuration for DMA transfer complete interrupt */ \ + HAL_NVIC_SetPriority(CFG_HW_##__USART_BASE__##_TX_DMA_IRQn, CFG_HW_##__USART_BASE__##_DMA_TX_PREEMPTPRIORITY, \ + CFG_HW_##__USART_BASE__##_DMA_TX_SUBPRIORITY); \ + HAL_NVIC_EnableIRQ(CFG_HW_##__USART_BASE__##_TX_DMA_IRQn); \ + } while (0) + +/* Variables ------------------------------------------------------------------*/ +#if (CFG_HW_USART1_ENABLED == 1) +UART_HandleTypeDef huart1 = { 0 }; +#if (CFG_HW_USART1_DMA_TX_SUPPORTED == 1) +DMA_HandleTypeDef HW_hdma_huart1_tx = { 0 }; +#endif +void (*HW_huart1RxCb)(void); +void (*HW_huart1TxCb)(void); +#endif + +#if (CFG_HW_LPUART1_ENABLED == 1) +UART_HandleTypeDef lpuart1 = { 0 }; +#if (CFG_HW_LPUART1_DMA_TX_SUPPORTED == 1) +DMA_HandleTypeDef HW_hdma_lpuart1_tx = { 0 }; +#endif +void (*HW_lpuart1RxCb)(void); +void (*HW_lpuart1TxCb)(void); +#endif + +void HW_UART_Init(hw_uart_id_t hw_uart_id) +{ + switch (hw_uart_id) + { +#if (CFG_HW_USART1_ENABLED == 1) + case hw_uart1: + HW_UART_INIT(huart1, USART1); + break; +#endif + +#if (CFG_HW_LPUART1_ENABLED == 1) + case hw_lpuart1: + HW_UART_INIT(lpuart1, LPUART1); + break; +#endif + + default: + break; + } + + return; +} + +void HW_UART_Receive_IT(hw_uart_id_t hw_uart_id, uint8_t * p_data, uint16_t size, void (*cb)(void)) +{ + switch (hw_uart_id) + { +#if (CFG_HW_USART1_ENABLED == 1) + case hw_uart1: + HW_UART_RX_IT(huart1, USART1); + break; +#endif + +#if (CFG_HW_LPUART1_ENABLED == 1) + case hw_lpuart1: + HW_UART_RX_IT(lpuart1, LPUART1); + break; +#endif + + default: + break; + } + + return; +} + +void HW_UART_Transmit_IT(hw_uart_id_t hw_uart_id, uint8_t * p_data, uint16_t size, void (*cb)(void)) +{ + switch (hw_uart_id) + { +#if (CFG_HW_USART1_ENABLED == 1) + case hw_uart1: + HW_UART_TX_IT(huart1, USART1); + break; +#endif + +#if (CFG_HW_LPUART1_ENABLED == 1) + case hw_lpuart1: + HW_UART_TX_IT(lpuart1, LPUART1); + break; +#endif + + default: + break; + } + + return; +} + +hw_status_t HW_UART_Transmit(hw_uart_id_t hw_uart_id, uint8_t * p_data, uint16_t size, uint32_t timeout) +{ + HAL_StatusTypeDef hal_status = HAL_OK; + hw_status_t hw_status = hw_uart_ok; + + switch (hw_uart_id) + { +#if (CFG_HW_USART1_ENABLED == 1) + case hw_uart1: + HW_UART_TX(huart1, USART1); + break; +#endif + +#if (CFG_HW_LPUART1_ENABLED == 1) + case hw_lpuart1: + HW_UART_TX(lpuart1, LPUART1); + break; +#endif + + default: + break; + } + + switch (hal_status) + { + case HAL_OK: + hw_status = hw_uart_ok; + break; + + case HAL_ERROR: + hw_status = hw_uart_error; + break; + + case HAL_BUSY: + hw_status = hw_uart_busy; + break; + + case HAL_TIMEOUT: + hw_status = hw_uart_to; + break; + + default: + break; + } + + return hw_status; +} + +hw_status_t HW_UART_Transmit_DMA(hw_uart_id_t hw_uart_id, uint8_t * p_data, uint16_t size, void (*cb)(void)) +{ + HAL_StatusTypeDef hal_status = HAL_OK; + hw_status_t hw_status = hw_uart_ok; + + switch (hw_uart_id) + { +#if (CFG_HW_USART1_ENABLED == 1) + case hw_uart1: + HW_huart1TxCb = cb; + huart1.Instance = USART1; + hal_status = HAL_UART_Transmit_DMA(&huart1, p_data, size); + break; +#endif + +#if (CFG_HW_USART2_ENABLED == 1) + case hw_uart2: + HW_huart2TxCb = cb; + huart2.Instance = USART2; + hal_status = HAL_UART_Transmit_DMA(&huart2, p_data, size); + break; +#endif + +#if (CFG_HW_LPUART1_ENABLED == 1) + case hw_lpuart1: + HW_lpuart1TxCb = cb; + lpuart1.Instance = LPUART1; + hal_status = HAL_UART_Transmit_DMA(&lpuart1, p_data, size); + break; +#endif + + default: + break; + } + + switch (hal_status) + { + case HAL_OK: + hw_status = hw_uart_ok; + break; + + case HAL_ERROR: + hw_status = hw_uart_error; + break; + + case HAL_BUSY: + hw_status = hw_uart_busy; + break; + + case HAL_TIMEOUT: + hw_status = hw_uart_to; + break; + + default: + break; + } + + return hw_status; +} + +void HW_UART_Interrupt_Handler(hw_uart_id_t hw_uart_id) +{ + switch (hw_uart_id) + { +#if (CFG_HW_USART1_ENABLED == 1) + case hw_uart1: + HAL_UART_IRQHandler(&huart1); + break; +#endif + +#if (CFG_HW_LPUART1_ENABLED == 1) + case hw_lpuart1: + HAL_UART_IRQHandler(&lpuart1); + break; +#endif + + default: + break; + } + + return; +} + +void HW_UART_DMA_Interrupt_Handler(hw_uart_id_t hw_uart_id) +{ + switch (hw_uart_id) + { +#if (CFG_HW_USART1_DMA_TX_SUPPORTED == 1) + case hw_uart1: + HAL_DMA_IRQHandler(huart1.hdmatx); + break; +#endif + +#if (CFG_HW_USART2_DMA_TX_SUPPORTED == 1) + case hw_uart2: + HAL_DMA_IRQHandler(huart2.hdmatx); + break; +#endif + +#if (CFG_HW_LPUART1_DMA_TX_SUPPORTED == 1) + case hw_lpuart1: + HAL_DMA_IRQHandler(lpuart1.hdmatx); + break; +#endif + + default: + break; + } + + return; +} + +void HAL_UART_MspInit(UART_HandleTypeDef * huart) +{ + GPIO_InitTypeDef GPIO_InitStruct = { 0 }; + + switch ((uint32_t) huart->Instance) + { +#if (CFG_HW_USART1_ENABLED == 1) + case (uint32_t) USART1: + HW_UART_MSP_UART_INIT(huart1, USART1); +#if (CFG_HW_USART1_DMA_TX_SUPPORTED == 1) + HW_UART_MSP_TX_DMA_INIT(huart1, USART1); +#endif + break; +#endif + +#if (CFG_HW_LPUART1_ENABLED == 1) + case (uint32_t) LPUART1: + HW_UART_MSP_UART_INIT(lpuart1, LPUART1); +#if (CFG_HW_LPUART1_DMA_TX_SUPPORTED == 1) + HW_UART_MSP_TX_DMA_INIT(lpuart1, LPUART1); +#endif + break; +#endif + + default: + break; + } + + return; +} + +void HAL_UART_RxCpltCallback(UART_HandleTypeDef * huart) +{ + switch ((uint32_t) huart->Instance) + { +#if (CFG_HW_USART1_ENABLED == 1) + case (uint32_t) USART1: + if (HW_huart1RxCb) + { + HW_huart1RxCb(); + } + break; +#endif + +#if (CFG_HW_LPUART1_ENABLED == 1) + case (uint32_t) LPUART1: + if (HW_lpuart1RxCb) + { + HW_lpuart1RxCb(); + } + break; +#endif + + default: + break; + } + + return; +} + +void HAL_UART_TxCpltCallback(UART_HandleTypeDef * huart) +{ + switch ((uint32_t) huart->Instance) + { +#if (CFG_HW_USART1_ENABLED == 1) + case (uint32_t) USART1: + if (HW_huart1TxCb) + { + HW_huart1TxCb(); + } + break; +#endif + +#if (CFG_HW_LPUART1_ENABLED == 1) + case (uint32_t) LPUART1: + if (HW_lpuart1TxCb) + { + HW_lpuart1TxCb(); + } + break; +#endif + + default: + break; + } + + return; +} diff --git a/examples/platform/stm32/common/STM32WB5MM-DK/Src/main.cpp b/examples/platform/stm32/common/STM32WB5MM-DK/Src/main.cpp new file mode 100644 index 00000000000000..a48e8b88dc6101 --- /dev/null +++ b/examples/platform/stm32/common/STM32WB5MM-DK/Src/main.cpp @@ -0,0 +1,439 @@ +/** + ****************************************************************************** + * @file : app_main.cpp + * @author : MCD Application Team + * @brief : Main program body + ****************************************************************************** + * @attention + * + * Copyright (c) 2019-2021 STMicroelectronics. + * All rights reserved. + * + * This software is licensed under terms that can be found in the LICENSE file + * in the root directory of this software component. + * If no LICENSE file comes with this software, it is provided AS-IS. + * + ****************************************************************************** + @verbatim + ============================================================================== + ##### IMPORTANT NOTE ##### + ============================================================================== + + This application requests having the stm32wb5x_BLE_Thread_ForMatter_fw.bin binary + flashed on the Wireless Coprocessor. + If it is not the case, you need to use STM32CubeProgrammer to load the appropriate + binary. + + All available binaries are located under following directory: + /Projects/STM32_Copro_Wireless_Binaries + + Refer to UM2237 to learn how to use/install STM32CubeProgrammer. + Refer to /Projects/STM32_Copro_Wireless_Binaries/ReleaseNote.html for the + detailed procedure to change the Wireless Coprocessor binary. + + @endverbatim + ****************************************************************************** + ****************************************************************************** + */ + +/* Includes ------------------------------------------------------------------*/ +#include "main.h" +#include "AppTask.h" +#include "STM32FreeRtosHooks.h" +#include "app_common.h" +#include "app_entry.h" +#include "app_thread.h" +#include "cmsis_os.h" +#include "dbg_trace.h" +#include "flash_wb.h" +#include "stm32_lpm.h" + +/* Private typedef -----------------------------------------------------------*/ +/* Private defines -----------------------------------------------------------*/ +/* Private macros ------------------------------------------------------------*/ +/* Global variables ---------------------------------------------------------*/ + +RTC_HandleTypeDef hrtc = { 0 }; /**< RTC handler declaration */ +RNG_HandleTypeDef hrng; +IPCC_HandleTypeDef hipcc; + +void Error_Handler(void); +/* Private variables ---------------------------------------------------------*/ +/* Private function prototypes -----------------------------------------------*/ +static void Reset_BackupDomain(void); +static void Init_RTC(void); +static void Reset_Device(void); +static void Reset_IPCC(void); +static void Init_Exti(void); +static void MX_GPIO_Init(void); +static void MX_RNG_Init(void); +static void MX_IPCC_Init(void); +static void PeriphCommonClock_Config(void); +static void SystemClock_Config(void); +/* USER CODE BEGIN PFP */ + +/* Functions Definition ------------------------------------------------------*/ + +/** + * @brief Main program + * @param None + * @retval None + */ +int main(void) +{ + /* STM32WBxx HAL library initialization: + - Configure the Flash prefetch + - Systick timer is configured by default as source of time base, but user + can eventually implement his proper time base source (a general purpose + timer for example or other time source), keeping in mind that Time base + duration should be kept 1ms since PPP_TIMEOUT_VALUEs are defined and + handled in milliseconds basis. + - Set NVIC Group Priority to 4 + - Low Level Initialization + */ + /* USER CODE END 1 */ + /** + * The OPTVERR flag is wrongly set at power on + * It shall be cleared before using any HAL_FLASH_xxx() api + */ + __HAL_FLASH_CLEAR_FLAG(FLASH_FLAG_OPTVERR); + + /** + * Reset some configurations so that the system behave in the same way + * when either out of nReset or Power On + */ + Reset_Device(); + + /* Reset of all peripherals, Initializes the Flash interface and the Systick. */ + HAL_Init(); + /* USER CODE BEGIN Init */ + + /* USER CODE END Init */ + + /* Configure the system clock */ + SystemClock_Config(); + PeriphCommonClock_Config(); + /* USER CODE BEGIN SysInit */ + /* Set default off value for each leds */ + + /* USER CODE END SysInit */ + + /* Initialize all configured peripherals */ + Init_Exti(); + MX_RNG_Init(); + Init_RTC(); + osKernelInitialize(); + MX_GPIO_Init(); + /* IPCC initialisation */ + MX_IPCC_Init(); + NM_Init(); + freertos_mbedtls_init(); + + APPE_Init(); + GetAppTask().InitMatter(); + osKernelStart(); + while (1) + { + } +} + +static void MX_RNG_Init(void) +{ + + /* USER CODE BEGIN RNG_Init 0 */ + + /* USER CODE END RNG_Init 0 */ + + /* USER CODE BEGIN RNG_Init 1 */ + + /* USER CODE END RNG_Init 1 */ + hrng.Instance = RNG; + hrng.Init.ClockErrorDetection = RNG_CED_ENABLE; + if (HAL_RNG_Init(&hrng) != HAL_OK) + { + } + /* USER CODE BEGIN RNG_Init 2 */ + + /* USER CODE END RNG_Init 2 */ +} + +/** + * @brief IPCC Initialization Function + * @param None + * @retval None + */ +static void MX_IPCC_Init(void) +{ + + /* USER CODE BEGIN IPCC_Init 0 */ + + /* USER CODE END IPCC_Init 0 */ + + /* USER CODE BEGIN IPCC_Init 1 */ + + /* USER CODE END IPCC_Init 1 */ + hipcc.Instance = IPCC; + if (HAL_IPCC_Init(&hipcc) != HAL_OK) + { + Error_Handler(); + } + /* USER CODE BEGIN IPCC_Init 2 */ + + /* USER CODE END IPCC_Init 2 */ +} + +/************************************************************* + * + * LOCAL FUNCTIONS + * + *************************************************************/ +static void Init_Exti(void) +{ + /**< Disable all wakeup interrupt on CPU1 except LPUART(25), IPCC(36), HSEM(38) */ + LL_EXTI_DisableIT_0_31((~0) & (~(LL_EXTI_LINE_25))); + LL_EXTI_DisableIT_32_63((~0) & (~(LL_EXTI_LINE_36 | LL_EXTI_LINE_38))); + + return; +} + +static void Reset_Device(void) +{ +#if (CFG_HW_RESET_BY_FW == 1) + Reset_BackupDomain(); + + Reset_IPCC(); +#endif + + return; +} + +static void Reset_IPCC(void) +{ + LL_AHB3_GRP1_EnableClock(LL_AHB3_GRP1_PERIPH_IPCC); + + LL_C1_IPCC_ClearFlag_CHx(IPCC, + LL_IPCC_CHANNEL_1 | LL_IPCC_CHANNEL_2 | LL_IPCC_CHANNEL_3 | LL_IPCC_CHANNEL_4 | LL_IPCC_CHANNEL_5 | + LL_IPCC_CHANNEL_6); + + LL_C2_IPCC_ClearFlag_CHx(IPCC, + LL_IPCC_CHANNEL_1 | LL_IPCC_CHANNEL_2 | LL_IPCC_CHANNEL_3 | LL_IPCC_CHANNEL_4 | LL_IPCC_CHANNEL_5 | + LL_IPCC_CHANNEL_6); + + LL_C1_IPCC_DisableTransmitChannel(IPCC, + LL_IPCC_CHANNEL_1 | LL_IPCC_CHANNEL_2 | LL_IPCC_CHANNEL_3 | LL_IPCC_CHANNEL_4 | + LL_IPCC_CHANNEL_5 | LL_IPCC_CHANNEL_6); + + LL_C2_IPCC_DisableTransmitChannel(IPCC, + LL_IPCC_CHANNEL_1 | LL_IPCC_CHANNEL_2 | LL_IPCC_CHANNEL_3 | LL_IPCC_CHANNEL_4 | + LL_IPCC_CHANNEL_5 | LL_IPCC_CHANNEL_6); + + LL_C1_IPCC_DisableReceiveChannel(IPCC, + LL_IPCC_CHANNEL_1 | LL_IPCC_CHANNEL_2 | LL_IPCC_CHANNEL_3 | LL_IPCC_CHANNEL_4 | + LL_IPCC_CHANNEL_5 | LL_IPCC_CHANNEL_6); + + LL_C2_IPCC_DisableReceiveChannel(IPCC, + LL_IPCC_CHANNEL_1 | LL_IPCC_CHANNEL_2 | LL_IPCC_CHANNEL_3 | LL_IPCC_CHANNEL_4 | + LL_IPCC_CHANNEL_5 | LL_IPCC_CHANNEL_6); + + return; +} + +static void Reset_BackupDomain(void) +{ + if ((LL_RCC_IsActiveFlag_PINRST() != FALSE) && (LL_RCC_IsActiveFlag_SFTRST() == FALSE)) + { + HAL_PWR_EnableBkUpAccess(); /**< Enable access to the RTC registers */ + + /** + * Write twice the value to flush the APB-AHB bridge + * This bit shall be written in the register before writing the next one + */ + HAL_PWR_EnableBkUpAccess(); + + __HAL_RCC_BACKUPRESET_FORCE(); + __HAL_RCC_BACKUPRESET_RELEASE(); + } + + return; +} + +static void Init_RTC(void) +{ + HAL_PWR_EnableBkUpAccess(); /**< Enable access to the RTC registers */ + + /** + * Write twice the value to flush the APB-AHB bridge + * This bit shall be written in the register before writing the next one + */ + HAL_PWR_EnableBkUpAccess(); + + __HAL_RCC_RTC_CONFIG(RCC_RTCCLKSOURCE_LSE); /**< Select LSI as RTC Input */ + + __HAL_RCC_RTC_ENABLE(); /**< Enable RTC */ + + hrtc.Instance = RTC; /**< Define instance */ + + /** + * Set the Asynchronous prescaler + */ + hrtc.Init.AsynchPrediv = CFG_RTC_ASYNCH_PRESCALER; + hrtc.Init.SynchPrediv = CFG_RTC_SYNCH_PRESCALER; + HAL_RTC_Init(&hrtc); + + /* Disable RTC registers write protection */ + LL_RTC_DisableWriteProtection(RTC); + + LL_RTC_WAKEUP_SetClock(RTC, CFG_RTC_WUCKSEL_DIVIDER); + + /* Enable RTC registers write protection */ + LL_RTC_EnableWriteProtection(RTC); + + return; +} + +/** + * @brief Configure the system clock + * + * @note This API configures + * - The system clock source + * - The AHBCLK, APBCLK dividers + * - The flash latency + * - The PLL settings (when required) + * + * @param None + * @retval None + */ +static void PeriphCommonClock_Config(void) +{ + + RCC_PeriphCLKInitTypeDef PeriphClkInitStruct = { 0 }; + + /** Initializes the peripherals clock + */ + PeriphClkInitStruct.PeriphClockSelection = RCC_PERIPHCLK_SMPS; + PeriphClkInitStruct.SmpsClockSelection = RCC_SMPSCLKSOURCE_HSI; + PeriphClkInitStruct.SmpsDivSelection = RCC_SMPSCLKDIV_RANGE1; + + if (HAL_RCCEx_PeriphCLKConfig(&PeriphClkInitStruct) != HAL_OK) + { + Error_Handler(); + } +} + +static void SystemClock_Config(void) +{ + /** + * Write twice the value to flush the APB-AHB bridge to ensure the bit is written + */ + HAL_PWR_EnableBkUpAccess(); /**< Enable access to the RTC registers */ + HAL_PWR_EnableBkUpAccess(); + /** + * Select LSE clock + */ + LL_RCC_LSE_Enable(); + while (!LL_RCC_LSE_IsReady()) + ; + /** + * Select wakeup source of BLE RF + */ + LL_RCC_SetRFWKPClockSource(LL_RCC_RFWKP_CLKSOURCE_LSE); + + RCC_OscInitTypeDef RCC_OscInitStruct = { 0 }; + RCC_ClkInitTypeDef RCC_ClkInitStruct = { 0 }; + + /** Configure the main internal regulator output voltage + */ + __HAL_PWR_VOLTAGESCALING_CONFIG(PWR_REGULATOR_VOLTAGE_SCALE1); + /** Initializes the RCC Oscillators according to the specified parameters + * in the RCC_OscInitTypeDef structure. + */ + RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSI; + RCC_OscInitStruct.HSIState = RCC_HSI_ON; + RCC_OscInitStruct.HSICalibrationValue = RCC_HSICALIBRATION_DEFAULT; + RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON; + RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSI; + RCC_OscInitStruct.PLL.PLLM = RCC_PLLM_DIV1; + RCC_OscInitStruct.PLL.PLLN = 16; + RCC_OscInitStruct.PLL.PLLP = RCC_PLLP_DIV2; + RCC_OscInitStruct.PLL.PLLR = RCC_PLLR_DIV4; + RCC_OscInitStruct.PLL.PLLQ = RCC_PLLQ_DIV2; + if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK) + { + Error_Handler(); + } + /** Configure the SYSCLKSource, HCLK, PCLK1 and PCLK2 clocks dividers + */ + RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK4 | RCC_CLOCKTYPE_HCLK2 | RCC_CLOCKTYPE_HCLK | RCC_CLOCKTYPE_SYSCLK | + RCC_CLOCKTYPE_PCLK1 | RCC_CLOCKTYPE_PCLK2; + RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK; + RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1; + RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV1; + RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1; + RCC_ClkInitStruct.AHBCLK2Divider = RCC_SYSCLK_DIV2; + RCC_ClkInitStruct.AHBCLK4Divider = RCC_SYSCLK_DIV1; + + if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_3) != HAL_OK) + { + Error_Handler(); + } + + return; +} + +static void MX_GPIO_Init(void) +{ + + /* GPIO Ports Clock Enable */ + __HAL_RCC_GPIOA_CLK_ENABLE(); + __HAL_RCC_GPIOC_CLK_ENABLE(); + __HAL_RCC_GPIOB_CLK_ENABLE(); + __HAL_RCC_GPIOD_CLK_ENABLE(); + __HAL_RCC_GPIOE_CLK_ENABLE(); +} + +/************************************************************* + * + * WRAP FUNCTIONS + * + *************************************************************/ +/** + * @brief Period elapsed callback in non blocking mode + * @note This function is called when TIM17 interrupt took place, inside + * HAL_TIM_IRQHandler(). It makes a direct call to HAL_IncTick() to increment + * a global variable "uwTick" used as application time base. + * @param htim : TIM handle + * @retval None + */ +void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef * htim) +{ + /* USER CODE BEGIN Callback 0 */ + + /* USER CODE END Callback 0 */ + if (htim->Instance == TIM17) + { + HAL_IncTick(); + } + /* USER CODE BEGIN Callback 1 */ + + /* USER CODE END Callback 1 */ +} + +void Error_Handler(void) +{ + /* USER CODE BEGIN Error_Handler_Debug */ + /* User can add his own implementation to report the HAL error return state */ + while (1) + { + HAL_Delay(100); + } + /* USER CODE END Error_Handler_Debug */ +} + +void RTOS_AppConfigureTimerForRuntimeStats() {} + +uint32_t RTOS_AppGetRuntimeCounterValueFromISR() + +{ + + return HAL_GetTick(); +} diff --git a/examples/platform/stm32/common/STM32WB5MM-DK/Src/otp.c b/examples/platform/stm32/common/STM32WB5MM-DK/Src/otp.c new file mode 100644 index 00000000000000..ee2d71467514b5 --- /dev/null +++ b/examples/platform/stm32/common/STM32WB5MM-DK/Src/otp.c @@ -0,0 +1,49 @@ +/** + ****************************************************************************** + * @file otp.c + * @author MCD Application Team + * @brief OTP manager + ****************************************************************************** + * @attention + * + * Copyright (c) 2018-2021 STMicroelectronics. + * All rights reserved. + * + * This software is licensed under terms that can be found in the LICENSE file + * in the root directory of this software component. + * If no LICENSE file comes with this software, it is provided AS-IS. + * + ****************************************************************************** + */ + +/* Includes ------------------------------------------------------------------*/ +#include "utilities_common.h" + +#include "otp.h" + +/* Private typedef -----------------------------------------------------------*/ +/* Private defines -----------------------------------------------------------*/ +/* Private macros ------------------------------------------------------------*/ +/* Private variables ---------------------------------------------------------*/ +/* Global variables ----------------------------------------------------------*/ +/* Private function prototypes -----------------------------------------------*/ +/* Functions Definition ------------------------------------------------------*/ + +uint8_t * OTP_Read(uint8_t id) +{ + uint8_t * p_id; + + p_id = (uint8_t *) (CFG_OTP_END_ADDRESS - 7); + + while (((*(p_id + 7)) != id) && (p_id != (uint8_t *) CFG_OTP_BASE_ADDRESS)) + { + p_id -= 8; + } + + if ((*(p_id + 7)) != id) + { + p_id = 0; + } + + return p_id; +} diff --git a/examples/platform/stm32/common/STM32WB5MM-DK/Src/stm32_lpm_if.c b/examples/platform/stm32/common/STM32WB5MM-DK/Src/stm32_lpm_if.c new file mode 100644 index 00000000000000..93c75f71f6aa40 --- /dev/null +++ b/examples/platform/stm32/common/STM32WB5MM-DK/Src/stm32_lpm_if.c @@ -0,0 +1,349 @@ +/* USER CODE BEGIN Header */ +/** + *************************************************************************************** + * File Name : stm32_lpm_if.c + * Description : Low layer function to enter/exit low power modes (stop, sleep). + *************************************************************************************** + * @attention + * + * Copyright (c) 2019-2021 STMicroelectronics. + * All rights reserved. + * + * This software is licensed under terms that can be found in the LICENSE file + * in the root directory of this software component. + * If no LICENSE file comes with this software, it is provided AS-IS. + * + ****************************************************************************** + */ +/* USER CODE END Header */ + +/* Includes ------------------------------------------------------------------*/ +#include "stm32_lpm_if.h" +#include "app_conf.h" +#include "stm32_lpm.h" +/* USER CODE BEGIN include */ + +/* USER CODE END include */ + +/* Exported variables --------------------------------------------------------*/ +const struct UTIL_LPM_Driver_s UTIL_PowerDriver = { + PWR_EnterSleepMode, PWR_ExitSleepMode, + + PWR_EnterStopMode, PWR_ExitStopMode, + + PWR_EnterOffMode, PWR_ExitOffMode, +}; + +/* Private function prototypes -----------------------------------------------*/ +static void Switch_On_HSI(void); +static void EnterLowPower(void); +static void ExitLowPower(void); +/* USER CODE BEGIN Private_Function_Prototypes */ + +/* USER CODE END Private_Function_Prototypes */ +/* Private typedef -----------------------------------------------------------*/ +/* USER CODE BEGIN Private_Typedef */ + +/* USER CODE END Private_Typedef */ +/* Private define ------------------------------------------------------------*/ +/* USER CODE BEGIN Private_Define */ + +/* USER CODE END Private_Define */ +/* Private macro -------------------------------------------------------------*/ +/* USER CODE BEGIN Private_Macro */ + +/* USER CODE END Private_Macro */ +/* Private variables ---------------------------------------------------------*/ +/* USER CODE BEGIN Private_Variables */ + +/* USER CODE END Private_Variables */ + +/* Functions Definition ------------------------------------------------------*/ +/** + * @brief Enters Low Power Off Mode + * @param none + * @retval none + */ +void PWR_EnterOffMode(void) +{ + /* USER CODE BEGIN PWR_EnterOffMode_1 */ + + /* USER CODE END PWR_EnterOffMode_1 */ + /** + * The systick should be disabled for the same reason than when the device enters stop mode because + * at this time, the device may enter either OffMode or StopMode. + */ + HAL_SuspendTick(); + + EnterLowPower(); + + /************************************************************************************ + * ENTER OFF MODE + ***********************************************************************************/ + /* + * There is no risk to clear all the WUF here because in the current implementation, this API is called + * in critical section. If an interrupt occurs while in that critical section before that point, + * the flag is set and will be cleared here but the system will not enter Off Mode + * because an interrupt is pending in the NVIC. The ISR will be executed when moving out + * of this critical section + */ + LL_PWR_ClearFlag_WU(); + + LL_PWR_SetPowerMode(LL_PWR_MODE_STANDBY); + + LL_LPM_EnableDeepSleep(); /**< Set SLEEPDEEP bit of Cortex System Control Register */ + + /** + * This option is used to ensure that store operations are completed + */ +#if defined(__CC_ARM) + __force_stores(); +#endif + + __WFI(); + + /* USER CODE BEGIN PWR_EnterOffMode_2 */ + + /* USER CODE END PWR_EnterOffMode_2 */ + return; +} + +/** + * @brief Exits Low Power Off Mode + * @param none + * @retval none + */ +void PWR_ExitOffMode(void) +{ + /* USER CODE BEGIN PWR_ExitOffMode_1 */ + + /* USER CODE END PWR_ExitOffMode_1 */ + HAL_ResumeTick(); + /* USER CODE BEGIN PWR_ExitOffMode_2 */ + + /* USER CODE END PWR_ExitOffMode_2 */ + return; +} + +/** + * @brief Enters Low Power Stop Mode + * @note ARM exists the function when waking up + * @param none + * @retval none + */ +void PWR_EnterStopMode(void) +{ + /* USER CODE BEGIN PWR_EnterStopMode_1 */ + + /* USER CODE END PWR_EnterStopMode_1 */ + /** + * When HAL_DBGMCU_EnableDBGStopMode() is called to keep the debugger active in Stop Mode, + * the systick shall be disabled otherwise the cpu may crash when moving out from stop mode + * + * When in production, the HAL_DBGMCU_EnableDBGStopMode() is not called so that the device can reach best power consumption + * However, the systick should be disabled anyway to avoid the case when it is about to expire at the same time the device + * enters stop mode ( this will abort the Stop Mode entry ). + */ + HAL_SuspendTick(); + + /** + * This function is called from CRITICAL SECTION + */ + EnterLowPower(); + + /************************************************************************************ + * ENTER STOP MODE + ***********************************************************************************/ + LL_PWR_SetPowerMode(LL_PWR_MODE_STOP2); + + LL_LPM_EnableDeepSleep(); /**< Set SLEEPDEEP bit of Cortex System Control Register */ + + /** + * This option is used to ensure that store operations are completed + */ +#if defined(__CC_ARM) + __force_stores(); +#endif + + __WFI(); + + /* USER CODE BEGIN PWR_EnterStopMode_2 */ + + /* USER CODE END PWR_EnterStopMode_2 */ + return; +} + +/** + * @brief Exits Low Power Stop Mode + * @note Enable the pll at 32MHz + * @param none + * @retval none + */ +void PWR_ExitStopMode(void) +{ + /* USER CODE BEGIN PWR_ExitStopMode_1 */ + + /* USER CODE END PWR_ExitStopMode_1 */ + /** + * This function is called from CRITICAL SECTION + */ + ExitLowPower(); + + HAL_ResumeTick(); + /* USER CODE BEGIN PWR_ExitStopMode_2 */ + + /* USER CODE END PWR_ExitStopMode_2 */ + return; +} + +/** + * @brief Enters Low Power Sleep Mode + * @note ARM exits the function when waking up + * @param none + * @retval none + */ +void PWR_EnterSleepMode(void) +{ + /* USER CODE BEGIN PWR_EnterSleepMode_1 */ + + /* USER CODE END PWR_EnterSleepMode_1 */ + + HAL_SuspendTick(); + + /************************************************************************************ + * ENTER SLEEP MODE + ***********************************************************************************/ + LL_LPM_EnableSleep(); /**< Clear SLEEPDEEP bit of Cortex System Control Register */ + + /** + * This option is used to ensure that store operations are completed + */ +#if defined(__CC_ARM) + __force_stores(); +#endif + + __WFI(); + /* USER CODE BEGIN PWR_EnterSleepMode_2 */ + + /* USER CODE END PWR_EnterSleepMode_2 */ + return; +} + +/** + * @brief Exits Low Power Sleep Mode + * @note ARM exits the function when waking up + * @param none + * @retval none + */ +void PWR_ExitSleepMode(void) +{ + /* USER CODE BEGIN PWR_ExitSleepMode_1 */ + + /* USER CODE END PWR_ExitSleepMode_1 */ + HAL_ResumeTick(); + /* USER CODE BEGIN PWR_ExitSleepMode_2 */ + + /* USER CODE END PWR_ExitSleepMode_2 */ + return; +} + +/************************************************************* + * + * LOCAL FUNCTIONS + * + *************************************************************/ +/** + * @brief Setup the system to enter either stop or off mode + * @param none + * @retval none + */ +static void EnterLowPower(void) +{ + /** + * This function is called from CRITICAL SECTION + */ + + while (LL_HSEM_1StepLock(HSEM, CFG_HW_RCC_SEMID)) + ; + + if (!LL_HSEM_1StepLock(HSEM, CFG_HW_ENTRY_STOP_MODE_SEMID)) + { + if (LL_PWR_IsActiveFlag_C2DS() || LL_PWR_IsActiveFlag_C2SB()) + { + /* Release ENTRY_STOP_MODE semaphore */ + LL_HSEM_ReleaseLock(HSEM, CFG_HW_ENTRY_STOP_MODE_SEMID, 0); + + Switch_On_HSI(); + } + } + else + { + Switch_On_HSI(); + } + + /* Release RCC semaphore */ + LL_HSEM_ReleaseLock(HSEM, CFG_HW_RCC_SEMID, 0); + + return; +} + +/** + * @brief Restore the system to exit stop mode + * @param none + * @retval none + */ +static void ExitLowPower(void) +{ + /* Release ENTRY_STOP_MODE semaphore */ + LL_HSEM_ReleaseLock(HSEM, CFG_HW_ENTRY_STOP_MODE_SEMID, 0); + + while (LL_HSEM_1StepLock(HSEM, CFG_HW_RCC_SEMID)) + ; + + if (LL_RCC_GetSysClkSource() == LL_RCC_SYS_CLKSOURCE_STATUS_HSI) + { + /* Restore the clock configuration of the application in this user section */ + /* USER CODE BEGIN ExitLowPower_1 */ + LL_RCC_HSE_Enable(); + __HAL_FLASH_SET_LATENCY(FLASH_LATENCY_1); + while (!LL_RCC_HSE_IsReady()) + ; + LL_RCC_SetSysClkSource(LL_RCC_SYS_CLKSOURCE_HSE); + while (LL_RCC_GetSysClkSource() != LL_RCC_SYS_CLKSOURCE_STATUS_HSE) + ; + /* USER CODE END ExitLowPower_1 */ + } + else + { + /* If the application is not running on HSE restore the clock configuration in this user section */ + /* USER CODE BEGIN ExitLowPower_2 */ + + /* USER CODE END ExitLowPower_2 */ + } + + /* Release RCC semaphore */ + LL_HSEM_ReleaseLock(HSEM, CFG_HW_RCC_SEMID, 0); + + return; +} + +/** + * @brief Switch the system clock on HSI + * @param none + * @retval none + */ +static void Switch_On_HSI(void) +{ + LL_RCC_HSI_Enable(); + while (!LL_RCC_HSI_IsReady()) + ; + LL_RCC_SetSysClkSource(LL_RCC_SYS_CLKSOURCE_HSI); + LL_RCC_SetSMPSClockSource(LL_RCC_SMPS_CLKSOURCE_HSI); + while (LL_RCC_GetSysClkSource() != LL_RCC_SYS_CLKSOURCE_STATUS_HSI) + ; + return; +} + +/* USER CODE BEGIN Private_Functions */ + +/* USER CODE END Private_Functions */ diff --git a/examples/platform/stm32/common/STM32WB5MM-DK/Src/stm32wbxx_hal_msp.c b/examples/platform/stm32/common/STM32WB5MM-DK/Src/stm32wbxx_hal_msp.c new file mode 100644 index 00000000000000..b5fa5b234e778f --- /dev/null +++ b/examples/platform/stm32/common/STM32WB5MM-DK/Src/stm32wbxx_hal_msp.c @@ -0,0 +1,385 @@ +/* USER CODE BEGIN Header */ +/** + ****************************************************************************** + * File Name : stm32wbxx_hal_msp.c + * Description : This file provides code for the MSP Initialization + * and de-Initialization codes. + ****************************************************************************** + * @attention + * + * Copyright (c) 2019-2021 STMicroelectronics. + * All rights reserved. + * + * This software is licensed under terms that can be found in the LICENSE file + * in the root directory of this software component. + * If no LICENSE file comes with this software, it is provided AS-IS. + * + ****************************************************************************** + */ +/* USER CODE END Header */ + +/* Includes ------------------------------------------------------------------*/ +#include "main.h" +/* USER CODE BEGIN Includes */ +#include "app_conf.h" +/* USER CODE END Includes */ +extern DMA_HandleTypeDef hdma_lpuart1_tx; +extern DMA_HandleTypeDef hdma_quadspi; +extern DMA_HandleTypeDef hdma_usart1_tx; + +/* Private typedef -----------------------------------------------------------*/ +/* USER CODE BEGIN TD */ +void Error_Handler(void) +{ + /* USER CODE BEGIN Error_Handler_Debug */ + /* User can add his own implementation to report the HAL error return state */ + while (1) + { + HAL_Delay(100); + } + /* USER CODE END Error_Handler_Debug */ +} +/* USER CODE END TD */ + +/* Private define ------------------------------------------------------------*/ +/* USER CODE BEGIN Define */ + +/* USER CODE END Define */ + +/* Private macro -------------------------------------------------------------*/ +/* USER CODE BEGIN Macro */ + +/* USER CODE END Macro */ + +/* Private variables ---------------------------------------------------------*/ +/* USER CODE BEGIN PV */ + +/* USER CODE END PV */ + +/* Private function prototypes -----------------------------------------------*/ +/* USER CODE BEGIN PFP */ + +/* USER CODE END PFP */ + +/* External functions --------------------------------------------------------*/ +/* USER CODE BEGIN ExternalFunctions */ + +/* USER CODE END ExternalFunctions */ + +/* USER CODE BEGIN 0 */ + +/* USER CODE END 0 */ +/** + * Initializes the Global MSP. + */ +void HAL_MspInit(void) +{ + /* USER CODE BEGIN MspInit 0 */ + + /* USER CODE END MspInit 0 */ + + __HAL_RCC_HSEM_CLK_ENABLE(); + + /* System interrupt init*/ + /* PendSV_IRQn interrupt configuration */ + HAL_NVIC_SetPriority(PendSV_IRQn, 15, 0); + + /* Peripheral interrupt init */ + /* PVD_PVM_IRQn interrupt configuration */ + HAL_NVIC_SetPriority(PVD_PVM_IRQn, 5, 0); + HAL_NVIC_EnableIRQ(PVD_PVM_IRQn); + /* FLASH_IRQn interrupt configuration */ + HAL_NVIC_SetPriority(FLASH_IRQn, 5, 0); + HAL_NVIC_EnableIRQ(FLASH_IRQn); + /* RCC_IRQn interrupt configuration */ + HAL_NVIC_SetPriority(RCC_IRQn, 5, 0); + HAL_NVIC_EnableIRQ(RCC_IRQn); + /* C2SEV_PWR_C2H_IRQn interrupt configuration */ + HAL_NVIC_SetPriority(C2SEV_PWR_C2H_IRQn, 5, 0); + HAL_NVIC_EnableIRQ(C2SEV_PWR_C2H_IRQn); + /* PWR_SOTF_BLEACT_802ACT_RFPHASE_IRQn interrupt configuration */ + HAL_NVIC_SetPriority(PWR_SOTF_BLEACT_802ACT_RFPHASE_IRQn, 5, 0); + HAL_NVIC_EnableIRQ(PWR_SOTF_BLEACT_802ACT_RFPHASE_IRQn); + /* HSEM_IRQn interrupt configuration */ + HAL_NVIC_SetPriority(HSEM_IRQn, 5, 0); + HAL_NVIC_EnableIRQ(HSEM_IRQn); + /* FPU_IRQn interrupt configuration */ + HAL_NVIC_SetPriority(FPU_IRQn, 5, 0); + HAL_NVIC_EnableIRQ(FPU_IRQn); + + /* USER CODE BEGIN MspInit 1 */ + /* USER CODE END MspInit 1 */ +} + +/** + * @brief IPCC MSP Initialization + * This function configures the hardware resources used in this example + * @param hipcc: IPCC handle pointer + * @retval None + */ +void HAL_IPCC_MspInit(IPCC_HandleTypeDef * hipcc) +{ + if (hipcc->Instance == IPCC) + { + /* USER CODE BEGIN IPCC_MspInit 0 */ + + /* USER CODE END IPCC_MspInit 0 */ + /* Peripheral clock enable */ + __HAL_RCC_IPCC_CLK_ENABLE(); + /* IPCC interrupt Init */ + HAL_NVIC_SetPriority(IPCC_C1_RX_IRQn, 5, 0); + HAL_NVIC_EnableIRQ(IPCC_C1_RX_IRQn); + HAL_NVIC_SetPriority(IPCC_C1_TX_IRQn, 5, 0); + HAL_NVIC_EnableIRQ(IPCC_C1_TX_IRQn); + /* USER CODE BEGIN IPCC_MspInit 1 */ + + /* USER CODE END IPCC_MspInit 1 */ + } +} + +/** + * @brief IPCC MSP De-Initialization + * This function freeze the hardware resources used in this example + * @param hipcc: IPCC handle pointer + * @retval None + */ +void HAL_IPCC_MspDeInit(IPCC_HandleTypeDef * hipcc) +{ + if (hipcc->Instance == IPCC) + { + /* USER CODE BEGIN IPCC_MspDeInit 0 */ + + /* USER CODE END IPCC_MspDeInit 0 */ + /* Peripheral clock disable */ + __HAL_RCC_IPCC_CLK_DISABLE(); + + /* IPCC interrupt DeInit */ + HAL_NVIC_DisableIRQ(IPCC_C1_RX_IRQn); + HAL_NVIC_DisableIRQ(IPCC_C1_TX_IRQn); + /* USER CODE BEGIN IPCC_MspDeInit 1 */ + + /* USER CODE END IPCC_MspDeInit 1 */ + } +} + +/** + * @brief RTC MSP Initialization + * This function configures the hardware resources used in this example + * @param hrtc: RTC handle pointer + * @retval None + */ +void HAL_RTC_MspInit(RTC_HandleTypeDef * hrtc) +{ + RCC_PeriphCLKInitTypeDef PeriphClkInitStruct = { 0 }; + if (hrtc->Instance == RTC) + { + /* USER CODE BEGIN RTC_MspInit 0 */ + HAL_PWR_EnableBkUpAccess(); /**< Enable access to the RTC registers */ + + /** + * Write twice the value to flush the APB-AHB bridge + * This bit shall be written in the register before writing the next one + */ + HAL_PWR_EnableBkUpAccess(); + + __HAL_RCC_RTC_CONFIG(RCC_RTCCLKSOURCE_LSE); /**< Select LSE as RTC Input */ + + /* USER CODE END RTC_MspInit 0 */ + + /** Initializes the peripherals clock + */ + PeriphClkInitStruct.PeriphClockSelection = RCC_PERIPHCLK_RTC; + + PeriphClkInitStruct.RTCClockSelection = RCC_RTCCLKSOURCE_LSE; + if (HAL_RCCEx_PeriphCLKConfig(&PeriphClkInitStruct) != HAL_OK) + { + // Error_Handler(); + } + + /* Peripheral clock enable */ + __HAL_RCC_RTC_ENABLE(); + __HAL_RCC_RTCAPB_CLK_ENABLE(); + /* RTC interrupt Init */ + HAL_NVIC_SetPriority(RTC_WKUP_IRQn, 5, 0); + HAL_NVIC_EnableIRQ(RTC_WKUP_IRQn); + /* USER CODE BEGIN RTC_MspInit 1 */ + + MODIFY_REG(RTC->CR, RTC_CR_WUCKSEL, CFG_RTC_WUCKSEL_DIVIDER); + /* USER CODE END RTC_MspInit 1 */ + } +} + +/** + * @brief RTC MSP De-Initialization + * This function freeze the hardware resources used in this example + * @param hrtc: RTC handle pointer + * @retval None + */ +void HAL_RTC_MspDeInit(RTC_HandleTypeDef * hrtc) +{ + if (hrtc->Instance == RTC) + { + /* USER CODE BEGIN RTC_MspDeInit 0 */ + + /* USER CODE END RTC_MspDeInit 0 */ + /* Peripheral clock disable */ + __HAL_RCC_RTC_DISABLE(); + __HAL_RCC_RTCAPB_CLK_DISABLE(); + + /* RTC interrupt DeInit */ + HAL_NVIC_DisableIRQ(RTC_WKUP_IRQn); + /* USER CODE BEGIN RTC_MspDeInit 1 */ + + /* USER CODE END RTC_MspDeInit 1 */ + } +} + +/* USER CODE BEGIN 1 */ +/** + * @brief RNG MSP Initialization + * This function configures the hardware resources used in this example + * @param hrng: RNG handle pointer + * @retval None + */ +void HAL_RNG_MspInit(RNG_HandleTypeDef * hrng) +{ + RCC_PeriphCLKInitTypeDef PeriphClkInitStruct = { 0 }; + if (hrng->Instance == RNG) + { + /* USER CODE BEGIN RNG_MspInit 0 */ + + /* USER CODE END RNG_MspInit 0 */ + + /** Initializes the peripherals clock + */ + PeriphClkInitStruct.PeriphClockSelection = RCC_PERIPHCLK_RNG; + PeriphClkInitStruct.RngClockSelection = RCC_RNGCLKSOURCE_HSI48; + if (HAL_RCCEx_PeriphCLKConfig(&PeriphClkInitStruct) != HAL_OK) + { + } + + /* Peripheral clock enable */ + __HAL_RCC_RNG_CLK_ENABLE(); + /* USER CODE BEGIN RNG_MspInit 1 */ + + /* USER CODE END RNG_MspInit 1 */ + } +} + +/** + * @brief RNG MSP De-Initialization + * This function freeze the hardware resources used in this example + * @param hrng: RNG handle pointer + * @retval None + */ +void HAL_RNG_MspDeInit(RNG_HandleTypeDef * hrng) +{ + if (hrng->Instance == RNG) + { + /* USER CODE BEGIN RNG_MspDeInit 0 */ + + /* USER CODE END RNG_MspDeInit 0 */ + /* Peripheral clock disable */ + __HAL_RCC_RNG_CLK_DISABLE(); + /* USER CODE BEGIN RNG_MspDeInit 1 */ + + /* USER CODE END RNG_MspDeInit 1 */ + } +} + +/** + * @brief QSPI MSP Initialization + * This function configures the hardware resources used in this example + * @param hqspi: QSPI handle pointer + * @retval None + */ +void HAL_QSPI_MspInit(QSPI_HandleTypeDef * hqspi) +{ + GPIO_InitTypeDef GPIO_InitStruct = { 0 }; + if (hqspi->Instance == QUADSPI) + { + /* USER CODE BEGIN QUADSPI_MspInit 0 */ + + /* USER CODE END QUADSPI_MspInit 0 */ + /* Peripheral clock enable */ + __HAL_RCC_QSPI_CLK_ENABLE(); + + __HAL_RCC_GPIOB_CLK_ENABLE(); + __HAL_RCC_GPIOA_CLK_ENABLE(); + __HAL_RCC_GPIOD_CLK_ENABLE(); + /**QUADSPI GPIO Configuration + PB9 ------> QUADSPI_BK1_IO0 + PA3 ------> QUADSPI_CLK + PD7 ------> QUADSPI_BK1_IO3 + PD3 ------> QUADSPI_BK1_NCS + PD5 ------> QUADSPI_BK1_IO1 + PD6 ------> QUADSPI_BK1_IO2 + */ + GPIO_InitStruct.Pin = GPIO_PIN_9; + GPIO_InitStruct.Mode = GPIO_MODE_AF_PP; + GPIO_InitStruct.Pull = GPIO_NOPULL; + GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW; + GPIO_InitStruct.Alternate = GPIO_AF10_QUADSPI; + HAL_GPIO_Init(GPIOB, &GPIO_InitStruct); + + GPIO_InitStruct.Pin = GPIO_PIN_3; + GPIO_InitStruct.Mode = GPIO_MODE_AF_PP; + GPIO_InitStruct.Pull = GPIO_NOPULL; + GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW; + GPIO_InitStruct.Alternate = GPIO_AF10_QUADSPI; + HAL_GPIO_Init(GPIOA, &GPIO_InitStruct); + + GPIO_InitStruct.Pin = GPIO_PIN_7 | GPIO_PIN_3 | GPIO_PIN_5 | GPIO_PIN_6; + GPIO_InitStruct.Mode = GPIO_MODE_AF_PP; + GPIO_InitStruct.Pull = GPIO_NOPULL; + GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW; + GPIO_InitStruct.Alternate = GPIO_AF10_QUADSPI; + HAL_GPIO_Init(GPIOD, &GPIO_InitStruct); + + /* USER CODE BEGIN QUADSPI_MspInit 1 */ + + /* USER CODE END QUADSPI_MspInit 1 */ + } +} + +/** + * @brief QSPI MSP De-Initialization + * This function freeze the hardware resources used in this example + * @param hqspi: QSPI handle pointer + * @retval None + */ +void HAL_QSPI_MspDeInit(QSPI_HandleTypeDef * hqspi) +{ + if (hqspi->Instance == QUADSPI) + { + /* USER CODE BEGIN QUADSPI_MspDeInit 0 */ + + /* USER CODE END QUADSPI_MspDeInit 0 */ + /* Peripheral clock disable */ + __HAL_RCC_QSPI_CLK_DISABLE(); + + /**QUADSPI GPIO Configuration + PB9 ------> QUADSPI_BK1_IO0 + PA3 ------> QUADSPI_CLK + PD7 ------> QUADSPI_BK1_IO3 + PD3 ------> QUADSPI_BK1_NCS + PD5 ------> QUADSPI_BK1_IO1 + PD6 ------> QUADSPI_BK1_IO2 + */ + HAL_GPIO_DeInit(GPIOB, GPIO_PIN_9); + + HAL_GPIO_DeInit(GPIOA, GPIO_PIN_3); + + HAL_GPIO_DeInit(GPIOD, GPIO_PIN_7 | GPIO_PIN_3 | GPIO_PIN_5 | GPIO_PIN_6); + + /* QUADSPI DMA DeInit */ + HAL_DMA_DeInit(hqspi->hdma); + + /* QUADSPI interrupt DeInit */ + HAL_NVIC_DisableIRQ(QUADSPI_IRQn); + /* USER CODE BEGIN QUADSPI_MspDeInit 1 */ + + /* USER CODE END QUADSPI_MspDeInit 1 */ + } +} +/* USER CODE END 1 */ diff --git a/examples/platform/stm32/common/STM32WB5MM-DK/Src/stm32wbxx_hal_timebase_tim.c b/examples/platform/stm32/common/STM32WB5MM-DK/Src/stm32wbxx_hal_timebase_tim.c new file mode 100644 index 00000000000000..c2f795f4dd0c43 --- /dev/null +++ b/examples/platform/stm32/common/STM32WB5MM-DK/Src/stm32wbxx_hal_timebase_tim.c @@ -0,0 +1,149 @@ +/* USER CODE BEGIN Header */ +/** + ****************************************************************************** + * @file stm32wbxx_hal_timebase_tim.c + * @author MCD Application Team + * @brief HAL time base based on the hardware TIM. + * + * This file overrides the native HAL time base functions (defined as weak) + * the TIM time base: + * + Initializes the TIM peripheral to generate a Period elapsed Event each 1ms + * + HAL_IncTick is called inside HAL_TIM_PeriodElapsedCallback ie each 1ms + * + ****************************************************************************** + * @attention + * + * Copyright (c) STMicroelectronics +(-2021) STMicroelectronics. + * All rights reserved. + * + * This software is licensed under terms that can be found in the LICENSE file + * in the root directory of this software component. + * If no LICENSE file comes with this software, it is provided AS-IS. + * + ****************************************************************************** + @verbatim + ============================================================================== + ##### How to use this driver ##### + ============================================================================== + [..] + This file must be copied to the application folder and modified as follows: + (#) Rename it to 'stm32wbxx_hal_timebase_tim.c' + (#) Add this file and the TIM HAL driver files to your project and make sure + HAL_TIM_MODULE_ENABLED is defined in stm32wbxx_hal_conf.h + + [..] + (@) The application needs to ensure that the time base is always set to 1 millisecond + to have correct HAL operation. + + @endverbatim + ****************************************************************************** + * 3. Neither the name of STMicroelectronics nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************** + */ +/* USER CODE END Header */ + +/* Includes ------------------------------------------------------------------*/ +#include "stm32wbxx_hal.h" +#include "stm32wbxx_hal_tim.h" + +/* Private typedef -----------------------------------------------------------*/ +/* Private define ------------------------------------------------------------*/ +/* Private macro -------------------------------------------------------------*/ +/* Private variables ---------------------------------------------------------*/ +TIM_HandleTypeDef htim17; +/* Private function prototypes -----------------------------------------------*/ +/* Private functions ---------------------------------------------------------*/ + +/** + * @brief This function configures the TIM17 as a time base source. + * The time source is configured to have 1ms time base with a dedicated + * Tick interrupt priority. + * @note This function is called automatically at the beginning of program after + * reset by HAL_Init() or at any time when clock is configured, by HAL_RCC_ClockConfig(). + * @param TickPriority: Tick interrupt priority. + * @retval HAL status + */ +HAL_StatusTypeDef HAL_InitTick(uint32_t TickPriority) +{ + RCC_ClkInitTypeDef clkconfig; + uint32_t uwTimclock = 0; + uint32_t uwPrescalerValue = 0; + uint32_t pFLatency; + /*Configure the TIM17 IRQ priority */ + HAL_NVIC_SetPriority(TIM1_TRG_COM_TIM17_IRQn, TickPriority, 0); + + /* Enable the TIM17 global Interrupt */ + HAL_NVIC_EnableIRQ(TIM1_TRG_COM_TIM17_IRQn); + + /* Enable TIM17 clock */ + __HAL_RCC_TIM17_CLK_ENABLE(); + + /* Get clock configuration */ + HAL_RCC_GetClockConfig(&clkconfig, &pFLatency); + + /* Compute TIM17 clock */ + uwTimclock = HAL_RCC_GetPCLK2Freq(); + /* Compute the prescaler value to have TIM17 counter clock equal to 1MHz */ + uwPrescalerValue = (uint32_t)((uwTimclock / 1000000U) - 1U); + + /* Initialize TIM17 */ + htim17.Instance = TIM17; + + /* Initialize TIMx peripheral as follow: + + Period = [(TIM17CLK/1000) - 1]. to have a (1/1000) s time base. + + Prescaler = (uwTimclock/1000000 - 1) to have a 1MHz counter clock. + + ClockDivision = 0 + + Counter direction = Up + */ + htim17.Init.Period = (1000000U / 1000U) - 1U; + htim17.Init.Prescaler = uwPrescalerValue; + htim17.Init.ClockDivision = 0; + htim17.Init.CounterMode = TIM_COUNTERMODE_UP; + + if (HAL_TIM_Base_Init(&htim17) == HAL_OK) + { + /* Start the TIM time Base generation in interrupt mode */ + return HAL_TIM_Base_Start_IT(&htim17); + } + + return HAL_ERROR; +} + +/** + * @brief Suspend Tick increment. + * @note Disable the tick increment by disabling TIM17 update interrupt. + * @param None + * @retval None + */ +void HAL_SuspendTick(void) +{ + /* Disable TIM17 update Interrupt */ + __HAL_TIM_DISABLE_IT(&htim17, TIM_IT_UPDATE); +} + +/** + * @brief Resume Tick increment. + * @note Enable the tick increment by Enabling TIM17 update interrupt. + * @param None + * @retval None + */ +void HAL_ResumeTick(void) +{ + /* Enable TIM17 Update interrupt */ + __HAL_TIM_ENABLE_IT(&htim17, TIM_IT_UPDATE); +} diff --git a/examples/platform/stm32/common/STM32WB5MM-DK/Src/stm32wbxx_it.c b/examples/platform/stm32/common/STM32WB5MM-DK/Src/stm32wbxx_it.c new file mode 100644 index 00000000000000..aa13c0fb6ada54 --- /dev/null +++ b/examples/platform/stm32/common/STM32WB5MM-DK/Src/stm32wbxx_it.c @@ -0,0 +1,193 @@ +/** + ****************************************************************************** + * @file stm32wbxx_it.c + * @author MCD Application Team + * @brief Main Interrupt Service Routines. + * This file provides template for all exceptions handler and + * peripherals interrupt service routine. + ****************************************************************************** + * @attention + * + * Copyright (c) 2019-2021 STMicroelectronics. + * All rights reserved. + * + * This software is licensed under terms that can be found in the LICENSE file + * in the root directory of this software component. + * If no LICENSE file comes with this software, it is provided AS-IS. + * + ****************************************************************************** + */ + +/* Includes ------------------------------------------------------------------*/ +#include "stm32wbxx_it.h" +#include "app_common.h" + +/* CONCURRENT MODE BLE/THREAD */ +/* External variables -----------------------------------------------------------*/ +extern uint8_t ThreadEnable; +extern TIM_HandleTypeDef htim17; + +/* /THREAD */ + +/* Private typedef -----------------------------------------------------------*/ +/* Private define ------------------------------------------------------------*/ +/* Private macro -------------------------------------------------------------*/ +/* Private variables ---------------------------------------------------------*/ +/* Private function prototypes -----------------------------------------------*/ +/* Private functions ---------------------------------------------------------*/ + +/******************************************************************************/ +/* Cortex-M4 Processor Exceptions Handlers */ +/******************************************************************************/ + +/** + * @brief This function handles NMI exception. + * @param None + * @retval None + */ +void NMI_Handler(void) {} + +/** + * @brief This function handles Hard Fault exception. + * @param None + * @retval None + */ +void HardFault_Handler(void) +{ + /* Go to infinite loop when Hard Fault exception occurs */ + while (1) + { + } +} + +/** + * @brief This function handles Memory management fault. + */ +void MemManage_Handler(void) +{ + /* USER CODE BEGIN MemoryManagement_IRQn 0 */ + + /* USER CODE END MemoryManagement_IRQn 0 */ + while (1) + { + /* USER CODE BEGIN W1_MemoryManagement_IRQn 0 */ + /* USER CODE END W1_MemoryManagement_IRQn 0 */ + } +} +/** + * @brief This function handles SVCall exception. + * @param None + * @retval None + */ +/*void SVC_Handler(void) +{ +}*/ + +/** + * @brief This function handles Debug Monitor exception. + * @param None + * @retval None + */ +void DebugMon_Handler(void) {} + +/** + * @brief This function handles PendSVC exception. + * @param None + * @retval None + */ +/*void PendSV_Handler(void) +{ +}*/ + +/** + * @brief This function handles SysTick Handler. + * @param None + * @retval None + */ +/*void SysTick_Handler(void) +{ + HAL_IncTick(); +}*/ + +void IPCC_C1_TX_IRQHandler(void) +{ + HW_IPCC_Tx_Handler(); + + return; +} + +void IPCC_C1_RX_IRQHandler(void) +{ + HW_IPCC_Rx_Handler(); + return; +} + +/** + * @brief This function handles TIM1 trigger and commutation interrupts and TIM17 global interrupt. + */ +void TIM1_TRG_COM_TIM17_IRQHandler(void) +{ + /* USER CODE BEGIN TIM1_TRG_COM_TIM17_IRQn 0 */ + /* USER CODE END TIM1_TRG_COM_TIM17_IRQn 0 */ + + HAL_TIM_IRQHandler(&htim17); + + /* USER CODE BEGIN TIM1_TRG_COM_TIM17_IRQn 1 */ + /* USER CODE END TIM1_TRG_COM_TIM17_IRQn 1 */ +} + +/** + * @brief This function handles External line + * interrupt request. + * @param None + * @retval None + */ + +void EXTI15_10_IRQHandler(void) +{ + BSP_PB_IRQHandler(BUTTON_USER1); +} + +#if (CFG_HW_USART1_ENABLED == 1) +void USART1_IRQHandler(void) +{ + HW_UART_Interrupt_Handler(hw_uart1); +} +#endif + +#if (CFG_HW_USART1_DMA_TX_SUPPORTED == 1) +void CFG_HW_USART1_DMA_TX_IRQHandler(void) +{ + HW_UART_DMA_Interrupt_Handler(hw_uart1); +} +#endif + +#if (CFG_HW_LPUART1_ENABLED == 1) +void LPUART1_IRQHandler(void) +{ + HW_UART_Interrupt_Handler(hw_lpuart1); +} +#endif + +#if (CFG_HW_LPUART1_DMA_TX_SUPPORTED == 1) +void CFG_HW_LPUART1_DMA_TX_IRQHandler(void) +{ + HW_UART_DMA_Interrupt_Handler(hw_lpuart1); +} +#endif + +/******************************************************************************/ +/* STM32L0xx Peripherals Interrupt Handlers */ +/* Add here the Interrupt Handler for the used peripheral(s) (PPP), for the */ +/* available peripheral interrupt handler's name please refer to the startup */ +/* file (startup_stm32l0xx.s). */ +/******************************************************************************/ +/** + * @brief This function handles RTC Auto wake-up interrupt request. + * @param None + * @retval None + */ +void RTC_WKUP_IRQHandler(void) +{ + HW_TS_RTC_Wakeup_Handler(); +} diff --git a/examples/platform/stm32/common/STM32WB5MM-DK/Src/stm_logging.c b/examples/platform/stm32/common/STM32WB5MM-DK/Src/stm_logging.c new file mode 100644 index 00000000000000..910a401c70eef5 --- /dev/null +++ b/examples/platform/stm32/common/STM32WB5MM-DK/Src/stm_logging.c @@ -0,0 +1,207 @@ + +/** + ****************************************************************************** + * @file stm_logging.c + * @author MCD Application Team + * @brief This file contains all the defines and functions used for logging + * on Application examples. + * + ****************************************************************************** + * @attention + * + * Copyright (c) 2019-2021 STMicroelectronics. + * All rights reserved. + * + * This software is licensed under terms that can be found in the LICENSE file + * in the root directory of this software component. + * If no LICENSE file comes with this software, it is provided AS-IS. + * + ****************************************************************************** + */ + +/** + * @file + * This file implements logging functions to used in Application examples. + * + */ + +#include +#include +#include +#include +#include +#include + +#include "app_conf.h" +#include "stm_logging.h" + +#define LOG_PARSE_BUFFER_SIZE 256U + +#define LOG_TIMESTAMP_ENABLE 0 +#define LOG_REGION_ENABLE 1U +#define LOG_RTT_COLOR_ENABLE 1U + +#if (LOG_RTT_COLOR_ENABLE == 1U) +#define RTT_COLOR_CODE_DEFAULT "\x1b[0m" +#define RTT_COLOR_CODE_RED "\x1b[0;91m" +#define RTT_COLOR_CODE_GREEN "\x1b[0;92m" +#define RTT_COLOR_CODE_YELLOW "\x1b[0;93m" +#define RTT_COLOR_CODE_CYAN "\x1b[0;96m" + +#else /* LOG_RTT_COLOR_ENABLE == 1 */ +#define RTT_COLOR_CODE_DEFAULT "" +#define RTT_COLOR_CODE_RED "" +#define RTT_COLOR_CODE_GREEN "" +#define RTT_COLOR_CODE_YELLOW "" +#define RTT_COLOR_CODE_CYAN "" +#endif /* LOG_RTT_COLOR_ENABLE == 1 */ + +#if (CFG_DEBUG_TRACE != 0) +/** + * Function for outputting code region string. + * + * @param[inout] aLogString Pointer to log buffer. + * @param[in] aMaxSize Maximum size of log buffer. + * @param[in] otLogRegion The region ID. + * + * @returns String with a log level color value. + */ +static inline uint16_t logRegion(char * aLogString, uint16_t aMaxSize, appliLogRegion_t aLogRegion) +{ + char logRegionString[30U]; + + switch (aLogRegion) + { + case APPLI_LOG_REGION_GENERAL: + strcpy(logRegionString, "[M4 APPLICATION]"); + break; + case APPLI_LOG_REGION_OPENTHREAD_API: + strcpy(logRegionString, "[M4 OPENTHREAD API]"); + break; + case APPLI_LOG_REGION_OT_API_LINK: + strcpy(logRegionString, "[M4 LINK API]"); + break; + case APPLI_LOG_REGION_OT_API_INSTANCE: + strcpy(logRegionString, "[M4 INSTANCE API]"); + break; + case APPLI_LOG_REGION_OT_API_MESSAGE: + strcpy(logRegionString, "[M4 MESSAGE API]"); + break; + default: + strcpy(logRegionString, "[M4]"); + break; + } + + return snprintf(aLogString, aMaxSize, "%s ", logRegionString); +} +#endif /* CFG_DEBUG_TRACE */ + +#if (LOG_RTT_COLOR_ENABLE == 1U) +#if (CFG_DEBUG_TRACE != 0) +/** + * Function for getting color of a given level log. + * + * @param[in] aLogLevel The log level. + * + * @returns String with a log level color value. + */ +static inline const char * levelToString(appliLogLevel_t aLogLevel) +{ + switch (aLogLevel) + { + case LOG_LEVEL_CRIT: + return RTT_COLOR_CODE_RED; + + case LOG_LEVEL_WARN: + return RTT_COLOR_CODE_YELLOW; + + case LOG_LEVEL_INFO: + return RTT_COLOR_CODE_GREEN; + + case LOG_LEVEL_DEBG: + default: + return RTT_COLOR_CODE_DEFAULT; + } +} +#endif /* CFG_DEBUG_TRACE */ + +#if (CFG_DEBUG_TRACE != 0) +/** + * Function for printing log level. + * + * @param[inout] aLogString Pointer to log buffer. + * @param[in] aMaxSize Maximum size of log buffer. + * @param[in] aLogLevel Log level. + * + * @returns Number of bytes successfully written to the log buffer. + */ +static inline uint16_t logLevel(char * aLogString, uint16_t aMaxSize, appliLogLevel_t aLogLevel) +{ + return snprintf(aLogString, aMaxSize, "%s", levelToString(aLogLevel)); +} +#endif /* CFG_DEBUG_TRACE */ +#endif /* LOG_RTT_COLOR_ENABLE */ + +#if (LOG_TIMESTAMP_ENABLE == 1U) +/** + * Function for printing actual timestamp. + * + * @param[inout] aLogString Pointer to the log buffer. + * @param[in] aMaxSize Maximum size of the log buffer. + * + * @returns Number of bytes successfully written to the log buffer. + */ +static inline uint16_t logTimestamp(char * aLogString, uint16_t aMaxSize) +{ + return snprintf(aLogString, aMaxSize, "%s[%010ld]", RTT_COLOR_CODE_DEFAULT, otPlatAlarmMilliGetNow()); +} +#endif /* LOG_TIMESTAMP_ENABLE */ + +/** + * Function for printing application log + * + * @param[in] aLogLevel Log level. + * @param[in] aLogRegion The region ID. + * @param[in] aFormat User string format. + * + * @returns Number of bytes successfully written to the log buffer. + */ +void logApplication(appliLogLevel_t aLogLevel, appliLogRegion_t aLogRegion, const char * aFormat, ...) +{ +#if (CFG_DEBUG_TRACE != 0) /* Since the traces are disabled, there is nothing to print */ + uint16_t length = 0; + char logString[LOG_PARSE_BUFFER_SIZE + 1U]; + +#if (LOG_TIMESTAMP_ENABLE == 1U) + length += logTimestamp(logString, LOG_PARSE_BUFFER_SIZE); +#endif + +#if (LOG_RTT_COLOR_ENABLE == 1U) + /* Add level information */ + length += logLevel(&logString[length], (LOG_PARSE_BUFFER_SIZE - length), aLogLevel); +#endif + +#if (LOG_REGION_ENABLE == 1U) + /* Add Region information */ + length += logRegion(&logString[length], (LOG_PARSE_BUFFER_SIZE - length), aLogRegion); +#endif + + /* Parse user string */ + va_list paramList; + va_start(paramList, aFormat); + length += vsnprintf(&logString[length], (LOG_PARSE_BUFFER_SIZE - length), aFormat, paramList); + logString[length++] = '\r'; + logString[length++] = '\n'; + logString[length++] = 0; + va_end(paramList); + + if (aLogLevel <= APPLI_CONFIG_LOG_LEVEL) + { + printf("%s", logString); + } + else + { + /* Print nothing */ + } +#endif /* CFG_DEBUG_TRACE */ +} diff --git a/examples/platform/stm32/common/STM32WB5MM-DK/Src/syscalls.c b/examples/platform/stm32/common/STM32WB5MM-DK/Src/syscalls.c new file mode 100644 index 00000000000000..5e62d7dc9c33ff --- /dev/null +++ b/examples/platform/stm32/common/STM32WB5MM-DK/Src/syscalls.c @@ -0,0 +1,156 @@ +/** + ****************************************************************************** + * @file syscalls.c + * @author Auto-generated by STM32CubeIDE + * @brief STM32CubeIDE Minimal System calls file + * + * For more information about which c-functions + * need which of these lowlevel functions + * please consult the Newlib libc-manual + ****************************************************************************** + * @attention + * + * Copyright (c) 2020-2021 STMicroelectronics. + * All rights reserved. + * + * This software is licensed under terms that can be found in the LICENSE file + * in the root directory of this software component. + * If no LICENSE file comes with this software, it is provided AS-IS. + * + ****************************************************************************** + */ + +/* Includes */ +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/* Variables */ +//#undef errno +extern int errno; +extern int __io_putchar(int ch) __attribute__((weak)); +extern int __io_getchar(void) __attribute__((weak)); + +register char * stack_ptr asm("sp"); + +char * __env[1] = { 0 }; +char ** environ = __env; + +/* Functions */ +void initialise_monitor_handles() {} + +int _getpid(void) +{ + return 1; +} + +int _kill(int pid, int sig) +{ + errno = EINVAL; + return -1; +} + +void _exit(int status) +{ + _kill(status, -1); + while (1) + { + } /* Make sure we hang here */ +} + +__attribute__((weak)) int _read(int file, char * ptr, int len) +{ + int DataIdx; + + for (DataIdx = 0; DataIdx < len; DataIdx++) + { + *ptr++ = __io_getchar(); + } + + return len; +} + +__attribute__((weak)) int _write(int file, char * ptr, int len) +{ + int DataIdx; + + for (DataIdx = 0; DataIdx < len; DataIdx++) + { + __io_putchar(*ptr++); + } + return len; +} + +int _close(int file) +{ + return -1; +} + +int _fstat(int file, struct stat * st) +{ + st->st_mode = S_IFCHR; + return 0; +} + +int _isatty(int file) +{ + return 1; +} + +int _lseek(int file, int ptr, int dir) +{ + return 0; +} + +int _open(char * path, int flags, ...) +{ + /* Pretend like we always fail */ + return -1; +} + +int _wait(int * status) +{ + errno = ECHILD; + return -1; +} + +int _unlink(char * name) +{ + errno = ENOENT; + return -1; +} + +int _times(struct tms * buf) +{ + return -1; +} + +int _stat(char * file, struct stat * st) +{ + st->st_mode = S_IFCHR; + return 0; +} + +int _link(char * old, char * new) +{ + errno = EMLINK; + return -1; +} + +int _fork(void) +{ + errno = EAGAIN; + return -1; +} + +int _execve(char * name, char ** argv, char ** env) +{ + errno = ENOMEM; + return -1; +} diff --git a/examples/platform/stm32/common/STM32WB5MM-DK/Src/sysmem.c b/examples/platform/stm32/common/STM32WB5MM-DK/Src/sysmem.c new file mode 100644 index 00000000000000..7231d53efafcb2 --- /dev/null +++ b/examples/platform/stm32/common/STM32WB5MM-DK/Src/sysmem.c @@ -0,0 +1,57 @@ +/** + ****************************************************************************** + * @file sysmem.c + * @author Auto-generated by STM32CubeIDE + * @brief STM32CubeIDE Minimal System Memory calls file + * + * For more information about which c-functions + * need which of these lowlevel functions + * please consult the Newlib libc-manual + ****************************************************************************** + * @attention + * + * Copyright (c) 2020-2021 STMicroelectronics. + * All rights reserved. + * + * This software is licensed under terms that can be found in the LICENSE file + * in the root directory of this software component. + * If no LICENSE file comes with this software, it is provided AS-IS. + * + ****************************************************************************** + */ + +/* Includes */ +#include +#include +#include + +/* Variables */ +extern int errno; +register char * stack_ptr asm("sp"); + +/* Functions */ + +/** + _sbrk + Increase program data space. Malloc and related functions depend on this +**/ +caddr_t _sbrk(int incr) +{ + extern char end asm("end"); + static char * heap_end; + char * prev_heap_end; + + if (heap_end == 0) + heap_end = &end; + + prev_heap_end = heap_end; + if (heap_end + incr > stack_ptr) + { + errno = ENOMEM; + return (caddr_t) -1; + } + + heap_end += incr; + + return (caddr_t) prev_heap_end; +} diff --git a/examples/platform/stm32/common/STM32WB5MM-DK/Src/system_stm32wbxx.c b/examples/platform/stm32/common/STM32WB5MM-DK/Src/system_stm32wbxx.c new file mode 100644 index 00000000000000..533cc4f0aa9671 --- /dev/null +++ b/examples/platform/stm32/common/STM32WB5MM-DK/Src/system_stm32wbxx.c @@ -0,0 +1,345 @@ +/** + ****************************************************************************** + * @file system_stm32wbxx.c + * @author MCD Application Team + * @brief CMSIS Cortex Device Peripheral Access Layer System Source File + * + * This file provides two functions and one global variable to be called from + * user application: + * - SystemInit(): This function is called at startup just after reset and + * before branch to main program. This call is made inside + * the "startup_stm32wbxx.s" file. + * + * - SystemCoreClock variable: Contains the core clock (HCLK), it can be used + * by the user application to setup the SysTick + * timer or configure other parameters. + * + * - SystemCoreClockUpdate(): Updates the variable SystemCoreClock and must + * be called whenever the core clock is changed + * during program execution. + * + * After each device reset the MSI (4 MHz) is used as system clock source. + * Then SystemInit() function is called, in "startup_stm32wbxx.s" file, to + * configure the system clock before to branch to main program. + * + * This file configures the system clock as follows: + *============================================================================= + *----------------------------------------------------------------------------- + * System Clock source | MSI + *----------------------------------------------------------------------------- + * SYSCLK(Hz) | 4000000 + *----------------------------------------------------------------------------- + * HCLK(Hz) | 4000000 + *----------------------------------------------------------------------------- + * AHB Prescaler | 1 + *----------------------------------------------------------------------------- + * APB1 Prescaler | 1 + *----------------------------------------------------------------------------- + * APB2 Prescaler | 1 + *----------------------------------------------------------------------------- + * PLL_M | 1 + *----------------------------------------------------------------------------- + * PLL_N | 8 + *----------------------------------------------------------------------------- + * PLL_P | 7 + *----------------------------------------------------------------------------- + * PLL_Q | 2 + *----------------------------------------------------------------------------- + * PLL_R | 2 + *----------------------------------------------------------------------------- + * PLLSAI1_P | NA + *----------------------------------------------------------------------------- + * PLLSAI1_Q | NA + *----------------------------------------------------------------------------- + * PLLSAI1_R | NA + *----------------------------------------------------------------------------- + * Require 48MHz for USB OTG FS, | Disabled + * SDIO and RNG clock | + *----------------------------------------------------------------------------- + *============================================================================= + ****************************************************************************** + * @attention + * + * Copyright (c) 2019-2021 STMicroelectronics. + * All rights reserved. + * + * This software is licensed under terms that can be found in the LICENSE file + * in the root directory of this software component. + * If no LICENSE file comes with this software, it is provided AS-IS. + * + ****************************************************************************** + */ + +/** @addtogroup CMSIS + * @{ + */ + +/** @addtogroup stm32WBxx_system + * @{ + */ + +/** @addtogroup stm32WBxx_System_Private_Includes + * @{ + */ + +#include "app_common.h" +#include "otp.h" + +#if !defined(HSE_VALUE) +#define HSE_VALUE (32000000UL) /*!< Value of the External oscillator in Hz */ +#endif /* HSE_VALUE */ + +#if !defined(MSI_VALUE) +#define MSI_VALUE (4000000UL) /*!< Value of the Internal oscillator in Hz*/ +#endif /* MSI_VALUE */ + +#if !defined(HSI_VALUE) +#define HSI_VALUE (16000000UL) /*!< Value of the Internal oscillator in Hz*/ +#endif /* HSI_VALUE */ + +#if !defined(LSI_VALUE) +#define LSI_VALUE (32000UL) /*!< Value of LSI in Hz*/ +#endif /* LSI_VALUE */ + +#if !defined(LSE_VALUE) +#define LSE_VALUE (32768UL) /*!< Value of LSE in Hz*/ +#endif /* LSE_VALUE */ + +/** + * @} + */ + +/** @addtogroup STM32WBxx_System_Private_TypesDefinitions + * @{ + */ + +/** + * @} + */ + +/** @addtogroup STM32WBxx_System_Private_Defines + * @{ + */ + +/** + * @} + */ + +/** @addtogroup STM32WBxx_System_Private_Macros + * @{ + */ + +/** + * @} + */ + +/** @addtogroup STM32WBxx_System_Private_Variables + * @{ + */ +/* The SystemCoreClock variable is updated in three ways: + 1) by calling CMSIS function SystemCoreClockUpdate() + 2) by calling HAL API function HAL_RCC_GetHCLKFreq() + 3) each time HAL_RCC_ClockConfig() is called to configure the system clock frequency + Note: If you use this function to configure the system clock; then there + is no need to call the 2 first functions listed above, since SystemCoreClock + variable is updated automatically. + */ +uint32_t SystemCoreClock = 4000000UL; /*CPU1: M4 on MSI clock after startup (4MHz)*/ + +const uint32_t AHBPrescTable[16UL] = { 1UL, 3UL, 5UL, 1UL, 1UL, 6UL, 10UL, 32UL, 2UL, 4UL, 8UL, 16UL, 64UL, 128UL, 256UL, 512UL }; + +const uint32_t APBPrescTable[8UL] = { 0UL, 0UL, 0UL, 0UL, 1UL, 2UL, 3UL, 4UL }; + +const uint32_t MSIRangeTable[16UL] = { + 100000UL, 200000UL, 400000UL, 800000UL, 1000000UL, 2000000UL, 4000000UL, 8000000UL, + 16000000UL, 24000000UL, 32000000UL, 48000000UL, 0UL, 0UL, 0UL, 0UL +}; /* 0UL values are incorrect cases */ + +#if defined(STM32WB55xx) || defined(STM32WB5Mxx) || defined(STM32WB35xx) || defined(STM32WB15xx) +const uint32_t SmpsPrescalerTable[4UL][6UL] = { { 1UL, 3UL, 2UL, 2UL, 1UL, 2UL }, + { 2UL, 6UL, 4UL, 3UL, 2UL, 4UL }, + { 4UL, 12UL, 8UL, 6UL, 4UL, 8UL }, + { 4UL, 12UL, 8UL, 6UL, 4UL, 8UL } }; +#endif + +/** + * @} + */ + +/** @addtogroup STM32WBxx_System_Private_FunctionPrototypes + * @{ + */ + +/** + * @} + */ + +/** @addtogroup STM32WBxx_System_Private_Functions + * @{ + */ + +/** + * @brief Setup the microcontroller system. + * @param None + * @retval None + */ +void SystemInit(void) +{ + OTP_ID0_t * p_otp; + + /* FPU settings ------------------------------------------------------------*/ +#if (__FPU_PRESENT == 1) && (__FPU_USED == 1) + SCB->CPACR |= ((3UL << (10UL * 2UL)) | (3UL << (11UL * 2UL))); /* set CP10 and CP11 Full Access */ +#endif + + /** + * Read HSE_Tuning from OTP + */ + p_otp = (OTP_ID0_t *) OTP_Read(0); + if (p_otp) + { + LL_RCC_HSE_SetCapacitorTuning(p_otp->hse_tuning); + } + + LL_RCC_HSE_Enable(); + + /** + * Set FLASH latency to 1WS + */ + LL_FLASH_SetLatency(LL_FLASH_LATENCY_1); + while (LL_FLASH_GetLatency() != LL_FLASH_LATENCY_1) + ; + + /** + * Switch to HSE + * + */ + while (!LL_RCC_HSE_IsReady()) + ; + LL_RCC_SetSysClkSource(LL_RCC_SYS_CLKSOURCE_HSE); + while (LL_RCC_GetSysClkSource() != LL_RCC_SYS_CLKSOURCE_STATUS_HSE) + ; + + /** + * Switch OFF MSI + */ + LL_RCC_MSI_Disable(); +} + +/** + * @brief Update SystemCoreClock variable according to Clock Register Values. + * The SystemCoreClock variable contains the core clock (HCLK), it can + * be used by the user application to setup the SysTick timer or configure + * other parameters. + * + * @note Each time the core clock (HCLK) changes, this function must be called + * to update SystemCoreClock variable value. Otherwise, any configuration + * based on this variable will be incorrect. + * + * @note - The system frequency computed by this function is not the real + * frequency in the chip. It is calculated based on the predefined + * constant and the selected clock source: + * + * - If SYSCLK source is MSI, SystemCoreClock will contain the MSI_VALUE(*) + * + * - If SYSCLK source is HSI, SystemCoreClock will contain the HSI_VALUE(**) + * + * - If SYSCLK source is HSE, SystemCoreClock will contain the HSE_VALUE(***) + * + * - If SYSCLK source is PLL, SystemCoreClock will contain the HSE_VALUE(***) + * or HSI_VALUE(*) or MSI_VALUE(*) multiplied/divided by the PLL factors. + * + * (*) MSI_VALUE is a constant defined in stm32wbxx_hal.h file (default value + * 4 MHz) but the real value may vary depending on the variations + * in voltage and temperature. + * + * (**) HSI_VALUE is a constant defined in stm32wbxx_hal_conf.h file (default value + * 16 MHz) but the real value may vary depending on the variations + * in voltage and temperature. + * + * (***) HSE_VALUE is a constant defined in stm32wbxx_hal_conf.h file (default value + * 32 MHz), user has to ensure that HSE_VALUE is same as the real + * frequency of the crystal used. Otherwise, this function may + * have wrong result. + * + * - The result of this function could be not correct when using fractional + * value for HSE crystal. + * + * @param None + * @retval None + */ +void SystemCoreClockUpdate(void) +{ + uint32_t tmp, msirange, pllvco, pllr, pllsource, pllm; + + /* Get MSI Range frequency--------------------------------------------------*/ + + /*MSI frequency range in Hz*/ + msirange = MSIRangeTable[(RCC->CR & RCC_CR_MSIRANGE) >> RCC_CR_MSIRANGE_Pos]; + + /*SystemCoreClock=HAL_RCC_GetSysClockFreq();*/ + /* Get SYSCLK source -------------------------------------------------------*/ + switch (RCC->CFGR & RCC_CFGR_SWS) + { + case 0x00: /* MSI used as system clock source */ + SystemCoreClock = msirange; + break; + + case 0x04: /* HSI used as system clock source */ + /* HSI used as system clock source */ + SystemCoreClock = HSI_VALUE; + break; + + case 0x08: /* HSE used as system clock source */ + SystemCoreClock = HSE_VALUE; + break; + + case 0x0C: /* PLL used as system clock source */ + /* PLL_VCO = (HSE_VALUE or HSI_VALUE or MSI_VALUE/ PLLM) * PLLN + SYSCLK = PLL_VCO / PLLR + */ + pllsource = (RCC->PLLCFGR & RCC_PLLCFGR_PLLSRC); + pllm = ((RCC->PLLCFGR & RCC_PLLCFGR_PLLM) >> RCC_PLLCFGR_PLLM_Pos) + 1UL; + + if (pllsource == 0x02UL) /* HSI used as PLL clock source */ + { + pllvco = (HSI_VALUE / pllm); + } + else if (pllsource == 0x03UL) /* HSE used as PLL clock source */ + { + pllvco = (HSE_VALUE / pllm); + } + else /* MSI used as PLL clock source */ + { + pllvco = (msirange / pllm); + } + + pllvco = pllvco * ((RCC->PLLCFGR & RCC_PLLCFGR_PLLN) >> RCC_PLLCFGR_PLLN_Pos); + pllr = (((RCC->PLLCFGR & RCC_PLLCFGR_PLLR) >> RCC_PLLCFGR_PLLR_Pos) + 1UL); + + SystemCoreClock = pllvco / pllr; + break; + + default: + SystemCoreClock = msirange; + break; + } + + /* Compute HCLK clock frequency --------------------------------------------*/ + /* Get HCLK1 prescaler */ + tmp = AHBPrescTable[((RCC->CFGR & RCC_CFGR_HPRE) >> RCC_CFGR_HPRE_Pos)]; + /* HCLK clock frequency */ + SystemCoreClock = SystemCoreClock / tmp; +} + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ diff --git a/examples/platform/stm32/config_files/STM32WB5/FreeRTOSConfig.h b/examples/platform/stm32/config_files/STM32WB5/FreeRTOSConfig.h new file mode 100644 index 00000000000000..5423994ea0bc12 --- /dev/null +++ b/examples/platform/stm32/config_files/STM32WB5/FreeRTOSConfig.h @@ -0,0 +1,191 @@ +/* USER CODE BEGIN Header */ +/* + * FreeRTOS Kernel V10.0.1 + * Copyright (C) 2017 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy of + * this software and associated documentation files (the "Software"), to deal in + * the Software without restriction, including without limitation the rights to + * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of + * the Software, and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS + * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR + * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER + * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + * http://www.FreeRTOS.org + * http://aws.amazon.com/freertos + * + * 1 tab == 4 spaces! + */ +/* USER CODE END Header */ + +#ifndef FREERTOS_CONFIG_H +#define FREERTOS_CONFIG_H + +/*----------------------------------------------------------- + * Application specific definitions. + * + * These definitions should be adjusted for your particular hardware and + * application requirements. + * + * These parameters and more are described within the 'configuration' section of the + * FreeRTOS API documentation available on the FreeRTOS.org web site. + * + * See http://www.freertos.org/a00110.html + *----------------------------------------------------------*/ + +/* USER CODE BEGIN Includes */ +/* Section where include file can be added */ +/* USER CODE END Includes */ + +/* Ensure definitions are only used by the compiler, and not by the assembler. */ +#if defined(__ICCARM__) || defined(__CC_ARM) || defined(__GNUC__) +#include +extern uint32_t SystemCoreClock; +#endif +#ifndef CMSIS_device_header +#define CMSIS_device_header "stm32wbxx.h" +#endif /* CMSIS_device_header */ + +#define configENABLE_FPU 0 +#define configENABLE_MPU 0 + +#define configUSE_PREEMPTION 1 +#define configSUPPORT_STATIC_ALLOCATION 1 +#define configSUPPORT_DYNAMIC_ALLOCATION 1 +#define configUSE_IDLE_HOOK 0 +#define configUSE_TICK_HOOK 0 +#define configCPU_CLOCK_HZ (SystemCoreClock) +#define configTICK_RATE_HZ ((TickType_t) 1000) +#define configMAX_PRIORITIES (56) +#define configMINIMAL_STACK_SIZE ((uint16_t) 128) +#define configTOTAL_HEAP_SIZE ((size_t) 1024 * 25) +#define configMAX_TASK_NAME_LEN (32) +#define configUSE_TRACE_FACILITY 1 +#define configUSE_16_BIT_TICKS 0 +#define configUSE_MUTEXES 1 +#define configQUEUE_REGISTRY_SIZE 8 +#define configUSE_RECURSIVE_MUTEXES 1 +#define configUSE_COUNTING_SEMAPHORES 1 +#define configUSE_PORT_OPTIMISED_TASK_SELECTION 0 +#define configUSE_TICKLESS_IDLE 0 +/* USER CODE BEGIN MESSAGE_BUFFER_LENGTH_TYPE */ +/* Defaults to size_t for backward compatibility, but can be changed + if lengths will always be less than the number of bytes in a size_t. */ +#define configMESSAGE_BUFFER_LENGTH_TYPE size_t +/* USER CODE END MESSAGE_BUFFER_LENGTH_TYPE */ + +/* Co-routine definitions. */ +#define configUSE_CO_ROUTINES 0 +#define configMAX_CO_ROUTINE_PRIORITIES (2) + +/* Software timer definitions. */ +#define configUSE_TIMERS 1 +#define configTIMER_TASK_PRIORITY (2) +#define configTIMER_QUEUE_LENGTH 10 +#define configTIMER_TASK_STACK_DEPTH 256 + +/* CMSIS-RTOS V2 flags */ +#define configUSE_OS2_THREAD_SUSPEND_RESUME 1 +#define configUSE_OS2_THREAD_ENUMERATE 1 +#define configUSE_OS2_EVENTFLAGS_FROM_ISR 1 +#define configUSE_OS2_THREAD_FLAGS 1 +#define configUSE_OS2_TIMER 1 +#define configUSE_OS2_MUTEX 1 + +/* Set the following definitions to 1 to include the API function, or zero +to exclude the API function. */ +#define INCLUDE_vTaskPrioritySet 1 +#define INCLUDE_uxTaskPriorityGet 1 +#define INCLUDE_vTaskDelete 1 +#define INCLUDE_vTaskCleanUpResources 0 +#define INCLUDE_vTaskSuspend 1 +#define INCLUDE_vTaskDelayUntil 1 +#define INCLUDE_vTaskDelay 1 +#define INCLUDE_xTaskGetSchedulerState 1 +#define INCLUDE_xTimerPendFunctionCall 1 +#define INCLUDE_xQueueGetMutexHolder 1 +#define INCLUDE_uxTaskGetStackHighWaterMark 1 +#define INCLUDE_xTaskGetCurrentTaskHandle 1 +#define INCLUDE_eTaskGetState 1 + +/* + * The CMSIS-RTOS V2 FreeRTOS wrapper is dependent on the heap implementation used + * by the application thus the correct define need to be enabled below + */ +#define USE_FreeRTOS_HEAP_4 + +/* Cortex-M specific definitions. */ +#ifdef __NVIC_PRIO_BITS +/* __BVIC_PRIO_BITS will be specified when CMSIS is being used. */ +#define configPRIO_BITS __NVIC_PRIO_BITS +#else +#define configPRIO_BITS 4 +#endif + +/* The lowest interrupt priority that can be used in a call to a "set priority" +function. */ +#define configLIBRARY_LOWEST_INTERRUPT_PRIORITY 15 + +/* The highest interrupt priority that can be used by any interrupt service +routine that makes calls to interrupt safe FreeRTOS API functions. DO NOT CALL +INTERRUPT SAFE FREERTOS API FUNCTIONS FROM ANY INTERRUPT THAT HAS A HIGHER +PRIORITY THAN THIS! (higher priorities are lower numeric values. */ +#define configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY 5 + +/* Interrupt priorities used by the kernel port layer itself. These are generic +to all Cortex-M ports, and do not rely on any particular library functions. */ +#define configKERNEL_INTERRUPT_PRIORITY (configLIBRARY_LOWEST_INTERRUPT_PRIORITY << (8 - configPRIO_BITS)) +/* !!!! configMAX_SYSCALL_INTERRUPT_PRIORITY must not be set to zero !!!! +See http://www.FreeRTOS.org/RTOS-Cortex-M3-M4.html. */ +#define configMAX_SYSCALL_INTERRUPT_PRIORITY (configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY << (8 - configPRIO_BITS)) + +/* Normal assert() semantics without relying on the provision of an assert.h +header file. */ +/* USER CODE BEGIN 1 */ +#define configASSERT(x) \ + if ((x) == 0) \ + { \ + taskDISABLE_INTERRUPTS(); \ + for (;;) \ + ; \ + } +/* USER CODE END 1 */ + +/* Definitions that map the FreeRTOS port interrupt handlers to their CMSIS +standard names. */ +#define vPortSVCHandler SVC_Handler +#define xPortPendSVHandler PendSV_Handler + +/* IMPORTANT: After 10.3.1 update, Systick_Handler comes from NVIC (if SYS timebase = systick), otherwise from cmsis_os2.c */ + +#define USE_CUSTOM_SYSTICK_HANDLER_IMPLEMENTATION 0 + +/* USER CODE BEGIN Defines */ +/* Section where parameter definitions can be added (for instance, to override default ones in FreeRTOS.h) */ +//#define configOVERRIDE_DEFAULT_TICK_CONFIGURATION 1 /* required only for Keil but does not hurt otherwise */ +#define configGENERATE_RUN_TIME_STATS 1 + +#if (configGENERATE_RUN_TIME_STATS == 1) + +extern void RTOS_AppConfigureTimerForRuntimeStats(); + +extern uint32_t RTOS_AppGetRuntimeCounterValueFromISR(); + +#define portCONFIGURE_TIMER_FOR_RUN_TIME_STATS() RTOS_AppConfigureTimerForRuntimeStats() + +#define portGET_RUN_TIME_COUNTER_VALUE() RTOS_AppGetRuntimeCounterValueFromISR() + +#endif + +/* USER CODE END Defines */ + +#endif /* FREERTOS_CONFIG_H */ diff --git a/examples/platform/stm32/config_files/STM32WB5/matter_config.h b/examples/platform/stm32/config_files/STM32WB5/matter_config.h new file mode 100644 index 00000000000000..3ab112ea03b75a --- /dev/null +++ b/examples/platform/stm32/config_files/STM32WB5/matter_config.h @@ -0,0 +1,139 @@ +/** + ****************************************************************************** + * @file matter_config.h + * @author MCD Application Team + * @brief config file for mbedtls + ****************************************************************************** + * @attention + * + * Copyright (c) 2019-2021 STMicroelectronics. + * All rights reserved. + * + * This software is licensed under terms that can be found in the LICENSE file + * in the root directory of this software component. + * If no LICENSE file comes with this software, it is provided AS-IS. + * + ****************************************************************************** + */ + +#pragma once + +#include +#include +#include + +//#if CHIP_HAVE_CONFIG_H +//#include +//#endif // CHIP_HAVE_CONFIG_H + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * Enable H Crypto and Entropy modules + */ +#define MBEDTLS_AES_C +#define MBEDTLS_ECP_C +#define MBEDTLS_ECDH_C +#define MBEDTLS_ENTROPY_C +#define MBEDTLS_SHA224_C +#define MBEDTLS_SHA256_C + +#define MBEDTLS_PLATFORM_SNPRINTF_MACRO snprintf + +#define MBEDTLS_AES_ROM_TABLES +#define MBEDTLS_ASN1_PARSE_C +#define MBEDTLS_ASN1_WRITE_C +#define MBEDTLS_BASE64_C +#define MBEDTLS_BIGNUM_C +#define MBEDTLS_CCM_C +#define MBEDTLS_CIPHER_C +#define MBEDTLS_CMAC_C +#define MBEDTLS_CTR_DRBG_C +#define MBEDTLS_ECDH_LEGACY_CONTEXT +#define MBEDTLS_ECDSA_C +#define MBEDTLS_ECDSA_DETERMINISTIC +#define MBEDTLS_ECJPAKE_C +#define MBEDTLS_ECP_DP_SECP256R1_ENABLED +#define MBEDTLS_ECP_NIST_OPTIM +#define MBEDTLS_ENTROPY_FORCE_SHA256 +#define MBEDTLS_ENTROPY_HARDWARE_ALT +#define MBEDTLS_ERROR_STRERROR_DUMMY +#define MBEDTLS_HAVE_ASM +#define MBEDTLS_HKDF_C +#define MBEDTLS_HMAC_DRBG_C +#define MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED +#define MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED +#define MBEDTLS_KEY_EXCHANGE_PSK_ENABLED +#define MBEDTLS_MD_C + +#define MBEDTLS_NO_PLATFORM_ENTROPY +#define MBEDTLS_NO_DEFAULT_ENTROPY_SOURCES + +#define MBEDTLS_OID_C +#define MBEDTLS_PEM_PARSE_C +#define MBEDTLS_PEM_WRITE_C +#define MBEDTLS_PK_C +#define MBEDTLS_PK_PARSE_C +#define MBEDTLS_PK_WRITE_C +#if CHIP_CRYPTO_MBEDTLS +#define MBEDTLS_PKCS5_C +#endif +#define MBEDTLS_PLATFORM_C +#define MBEDTLS_PLATFORM_MEMORY +#define MBEDTLS_SHA256_SMALLER +#define MBEDTLS_SSL_CLI_C +#define MBEDTLS_SSL_COOKIE_C +#define MBEDTLS_SSL_DTLS_ANTI_REPLAY +#define MBEDTLS_SSL_DTLS_HELLO_VERIFY +#define MBEDTLS_SSL_EXPORT_KEYS +#define MBEDTLS_SSL_KEEP_PEER_CERTIFICATE +#define MBEDTLS_SSL_MAX_FRAGMENT_LENGTH +#define MBEDTLS_SSL_PROTO_TLS1_2 +#define MBEDTLS_SSL_PROTO_DTLS +#define MBEDTLS_SSL_SRV_C +#define MBEDTLS_SSL_TLS_C + +#if CHIP_CRYPTO_PLATFORM +#define MBEDTLS_USE_PSA_CRYPTO +#endif + +#define MBEDTLS_X509_CREATE_C +#define MBEDTLS_X509_CSR_WRITE_C +#define MBEDTLS_X509_CRL_PARSE_C +#define MBEDTLS_X509_CRT_PARSE_C +#define MBEDTLS_X509_CSR_PARSE_C +#define MBEDTLS_X509_USE_C + +#define MBEDTLS_MPI_WINDOW_SIZE 1 /**< Maximum windows size used. */ +#define MBEDTLS_MPI_MAX_SIZE 32 /**< Maximum number of bytes for usable MPIs. */ +#define MBEDTLS_ECP_MAX_BITS 256 /**< Maximum bit size of groups */ +#define MBEDTLS_ECP_WINDOW_SIZE 2 /**< Maximum window size used */ +#define MBEDTLS_ECP_FIXED_POINT_OPTIM 0 /**< Enable fixed-point speed-up */ +#define MBEDTLS_ENTROPY_MAX_SOURCES 2 /**< Maximum number of sources supported */ + +#if OPENTHREAD_CONFIG_COAP_SECURE_API_ENABLE +#define MBEDTLS_SSL_MAX_CONTENT_LEN 900 /**< Maxium fragment length in bytes */ +#else +#define MBEDTLS_SSL_MAX_CONTENT_LEN 768 /**< Maxium fragment length in bytes */ +#endif + +#define MBEDTLS_SSL_CIPHERSUITES MBEDTLS_TLS_ECJPAKE_WITH_AES_128_CCM_8 + +#define MBEDTLS_CIPHER_MODE_WITH_PADDING + +#define MBEDTLS_THREADING_ALT +#define MBEDTLS_THREADING_C +#define MBEDTLS_MEMORY_BUFFER_ALLOC_C +#define MBEDTLS_PKCS5_C + +#define MBEDTLS_ERROR_C 1 + +//#include "check_crypto_config.h" +#include "mbedtls/check_config.h" +#include "mbedtls/config_psa.h" + +#ifdef __cplusplus +} +#endif diff --git a/examples/platform/stm32/config_files/STM32WB5/threading_alt.h b/examples/platform/stm32/config_files/STM32WB5/threading_alt.h new file mode 100644 index 00000000000000..253ddd9c0048a0 --- /dev/null +++ b/examples/platform/stm32/config_files/STM32WB5/threading_alt.h @@ -0,0 +1,50 @@ +/* + * FreeRTOS PKCS #11 V2.0.3 + * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy of + * this software and associated documentation files (the "Software"), to deal in + * the Software without restriction, including without limitation the rights to + * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of + * the Software, and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS + * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR + * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER + * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + * http://aws.amazon.com/freertos + * http://www.FreeRTOS.org + */ + +#ifndef __THREADING_ALT_H__ +#define __THREADING_ALT_H__ + +#include "FreeRTOS.h" +#include "semphr.h" + +#ifdef __cplusplus +extern "C" { +#endif + +typedef struct +{ + SemaphoreHandle_t mutex; + char is_valid; +} mbedtls_threading_mutex_t; + +extern void mbedtls_threading_set_alt(void (*mutex_init)(mbedtls_threading_mutex_t *), + void (*mutex_free)(mbedtls_threading_mutex_t *), + int (*mutex_lock)(mbedtls_threading_mutex_t *), + int (*mutex_unlock)(mbedtls_threading_mutex_t *)); + +#ifdef __cplusplus +} +#endif +#endif /* ifndef __THREADING_ALT_H__ */ diff --git a/examples/platform/stm32/ldscripts/STM32WB5MMGHX_FLASH.ld b/examples/platform/stm32/ldscripts/STM32WB5MMGHX_FLASH.ld new file mode 100644 index 00000000000000..56292a5b88ac1b --- /dev/null +++ b/examples/platform/stm32/ldscripts/STM32WB5MMGHX_FLASH.ld @@ -0,0 +1,198 @@ +/* +****************************************************************************** +** +** File : LinkerScript.ld +** +** Author : STM32CubeIDE +** +** Abstract : Linker script for STM32WB5MMG Device +** 1024Kbytes FLASH +** 256Kbytes RAM +** +** Set heap size, stack size and stack location according +** to application requirements. +** +** Set memory bank area and size if external memory is used. +** +** Target : STMicroelectronics STM32 +** +** Distribution: The file is distributed as is without any warranty +** of any kind. +** +***************************************************************************** +** @attention +** +** Copyright (c) 2020 STMicroelectronics. +** All rights reserved. +** +** This software is licensed under terms that can be found in the LICENSE file +** in the root directory of this software component. +** If no LICENSE file comes with this software, it is provided AS-IS. +** +***************************************************************************** +*/ + +/* Entry Point */ +ENTRY(Reset_Handler) + +/* Highest address of the user mode stack */ +_estack = 0x20026EC4; /* end of RAM */ +/* Generate a link error if heap and stack don't fit into RAM */ +_Min_Heap_Size = 0x400 ; /* required amount of heap */ +_Min_Stack_Size = 0x1000 ; /* required amount of stack */ + +/* Specify the memory areas */ +MEMORY +{ +FLASH (rx) : ORIGIN = 0x08000000, LENGTH = 520K +NVM_MATTER : ORIGIN = 0x08082000, LENGTH = 0x3000 +RAM1 (xrw) : ORIGIN = 0x20000008, LENGTH = 0x26EC4 +RAM_SHARED (xrw) : ORIGIN = 0x20030000, LENGTH = 10K +} + +/* Define output sections */ +SECTIONS +{ + /* The startup code goes first into FLASH */ + .isr_vector : + { + . = ALIGN(4); + KEEP(*(.isr_vector)) /* Startup code */ + . = ALIGN(4); + } >FLASH + + /* The program code and other data goes into FLASH */ + .text : + { + . = ALIGN(4); + *(.text) /* .text sections (code) */ + *(.text*) /* .text* sections (code) */ + *(.glue_7) /* glue arm to thumb code */ + *(.glue_7t) /* glue thumb to arm code */ + *(.eh_frame) + + KEEP (*(.init)) + KEEP (*(.fini)) + + . = ALIGN(4); + _etext = .; /* define a global symbols at end of code */ + } >FLASH + + /* Constant data goes into FLASH */ + .rodata : + { + . = ALIGN(4); + *(.rodata) /* .rodata sections (constants, strings, etc.) */ + *(.rodata*) /* .rodata* sections (constants, strings, etc.) */ + . = ALIGN(4); + } >FLASH + + .ARM.extab : { *(.ARM.extab* .gnu.linkonce.armextab.*) } >FLASH + .ARM : { + __exidx_start = .; + *(.ARM.exidx*) + __exidx_end = .; + } >FLASH + +_nvm_matter_init_base = LOADADDR(.nvm_matter); +_nvm_matter_init_length = SIZEOF(.nvm_matter); + + .nvm_matter : + { + . = ALIGN(4); + _nvm_matter_start = .; /* create a global symbol at nvm_matter start */ + *(.nvm_matter) /* .nvm_matter sections */ + *(.nvm_matter*) /* .nvm_matter* sections */ + . = ALIGN(4); + _nvm_matter_end = .; /* define a global symbols at end of nvm_matter */ + + } >NVM_MATTER + + + .preinit_array : + { + PROVIDE_HIDDEN (__preinit_array_start = .); + KEEP (*(.preinit_array*)) + PROVIDE_HIDDEN (__preinit_array_end = .); + } >FLASH + .init_array : + { + PROVIDE_HIDDEN (__init_array_start = .); + KEEP (*(SORT(.init_array.*))) + KEEP (*(.init_array*)) + PROVIDE_HIDDEN (__init_array_end = .); + } >FLASH + .fini_array : + { + PROVIDE_HIDDEN (__fini_array_start = .); + KEEP (*(SORT(.fini_array.*))) + KEEP (*(.fini_array*)) + PROVIDE_HIDDEN (__fini_array_end = .); + } >FLASH + + /* used by the startup to initialize data */ + _sidata = LOADADDR(.data); + + /* Initialized data sections goes into RAM, load LMA copy after code */ + .data : + { + . = ALIGN(4); + _sdata = .; /* create a global symbol at data start */ + *(.data) /* .data sections */ + *(.data*) /* .data* sections */ + *(.RamFunc) /* .RamFunc sections */ + *(.RamFunc*) /* .RamFunc* sections */ + . = ALIGN(4); + _edata = .; /* define a global symbol at data end */ + } >RAM1 AT> FLASH + + /* Uninitialized data section */ + . = ALIGN(4); + .bss : + { + /* This is used by the startup in order to initialize the .bss section */ + _sbss = .; /* define a global symbol at bss start */ + __bss_start__ = _sbss; + *(.bss) + *(.bss*) + *(COMMON) + + . = ALIGN(4); + _ebss = .; /* define a global symbol at bss end */ + __bss_end__ = _ebss; + } >RAM1 + + /* User_heap_stack section, used to check that there is enough RAM left */ + ._user_heap_stack : + { + . = ALIGN(8); + PROVIDE ( end = . ); + PROVIDE ( _end = . ); + . = . + _Min_Heap_Size; + . = . + _Min_Stack_Size; + . = ALIGN(8); + } >RAM1 + + /* Remove information from the standard libraries */ + /DISCARD/ : + { + libc.a ( * ) + libm.a ( * ) + libgcc.a ( * ) + } + + .ARM.attributes 0 : { *(.ARM.attributes) } + MAPPING_TABLE (NOLOAD) : { *(MAPPING_TABLE) } >RAM_SHARED + MB_MEM1 (NOLOAD) : { *(MB_MEM1) } >RAM_SHARED + MB_MEM2 (NOLOAD) : { _sMB_MEM2 = . ; *(MB_MEM2) ; _eMB_MEM2 = . ; } >RAM_SHARED + + + + + + +} + + + + diff --git a/examples/platform/stm32/startup_files/startup_STM32WB5MMGHX.s b/examples/platform/stm32/startup_files/startup_STM32WB5MMGHX.s new file mode 100644 index 00000000000000..53c16dab9acbe4 --- /dev/null +++ b/examples/platform/stm32/startup_files/startup_STM32WB5MMGHX.s @@ -0,0 +1,443 @@ +/** + ****************************************************************************** + * @file startup_stm32wb5mxx_cm4.s + * @author MCD Application Team + * @brief STM32WB5Mxx devices vector table GCC toolchain. + * This module performs: + * - Set the initial SP + * - Set the initial PC == Reset_Handler, + * - Set the vector table entries with the exceptions ISR address + * - Branches to main in the C library (which eventually + * calls main()). + * After Reset the Cortex-M4 processor is in Thread mode, + * priority is Privileged, and the Stack is set to Main. + ****************************************************************************** + * @attention + * + * Copyright (c) 2019 STMicroelectronics. + * All rights reserved. + * + * This software is licensed under terms that can be found in the LICENSE file + * in the root directory of this software component. + * If no LICENSE file comes with this software, it is provided AS-IS. + * + ****************************************************************************** + */ + + .syntax unified + .cpu cortex-m4 + .fpu softvfp + .thumb + +.global g_pfnVectors +.global Default_Handler + +/* start address for the initialization values of the .data section. +defined in linker script */ +.word _sidata +/* start address for the .data section. defined in linker script */ +.word _sdata +/* end address for the .data section. defined in linker script */ +.word _edata +/* start address for the .bss section. defined in linker script */ +.word _sbss +/* end address for the .bss section. defined in linker script */ +.word _ebss +/* start address for the .MB_MEM2 section. defined in linker script */ +.word _sMB_MEM2 +/* end address for the .MB_MEM2 section. defined in linker script */ +.word _eMB_MEM2 + +/* INIT_BSS macro is used to fill the specified region [start : end] with zeros */ +.macro INIT_BSS start, end + ldr r0, =\start + ldr r1, =\end + movs r3, #0 + bl LoopFillZerobss +.endm + +/* INIT_DATA macro is used to copy data in the region [start : end] starting from 'src' */ +.macro INIT_DATA start, end, src + ldr r0, =\start + ldr r1, =\end + ldr r2, =\src + movs r3, #0 + bl LoopCopyDataInit +.endm + +.section .text.data_initializers +CopyDataInit: + ldr r4, [r2, r3] + str r4, [r0, r3] + adds r3, r3, #4 + +LoopCopyDataInit: + adds r4, r0, r3 + cmp r4, r1 + bcc CopyDataInit + bx lr + +FillZerobss: + str r3, [r0] + adds r0, r0, #4 + +LoopFillZerobss: + cmp r0, r1 + bcc FillZerobss + bx lr + + .section .text.Reset_Handler + .weak Reset_Handler + .type Reset_Handler, %function +Reset_Handler: +ldr r0, =_estack + mov sp, r0 /* set stack pointer */ +/* Call the clock system initialization function.*/ + bl SystemInit + +/* Copy the data segment initializers from flash to SRAM */ + INIT_DATA _sdata, _edata, _sidata + +/* Zero fill the bss segments. */ + INIT_BSS _sbss, _ebss + INIT_BSS _sMB_MEM2, _eMB_MEM2 + +/* Call static constructors */ + bl __libc_init_array +/* Call the application s entry point.*/ + bl main + +LoopForever: + b LoopForever + +.size Reset_Handler, .-Reset_Handler + +/** + * @brief This is the code that gets called when the processor receives an + * unexpected interrupt. This simply enters an infinite loop, preserving + * the system state for examination by a debugger. + * + * @param None + * @retval None +*/ + .section .text.Default_Handler,"ax",%progbits +Default_Handler: +Infinite_Loop: + b Infinite_Loop + .size Default_Handler, .-Default_Handler +/****************************************************************************** +* +* The minimal vector table for a Cortex-M4. Note that the proper constructs +* must be placed on this to ensure that it ends up at physical address +* 0x0000.0000. +* +******************************************************************************/ + .section .isr_vector,"a",%progbits + .type g_pfnVectors, %object + .size g_pfnVectors, .-g_pfnVectors + + +g_pfnVectors: + .word _estack + .word Reset_Handler + .word NMI_Handler + .word HardFault_Handler + .word MemManage_Handler + .word BusFault_Handler + .word UsageFault_Handler + .word 0 + .word 0 + .word 0 + .word 0 + .word SVC_Handler + .word DebugMon_Handler + .word 0 + .word PendSV_Handler + .word SysTick_Handler + .word WWDG_IRQHandler + .word PVD_PVM_IRQHandler + .word TAMP_STAMP_LSECSS_IRQHandler + .word RTC_WKUP_IRQHandler + .word FLASH_IRQHandler + .word RCC_IRQHandler + .word EXTI0_IRQHandler + .word EXTI1_IRQHandler + .word EXTI2_IRQHandler + .word EXTI3_IRQHandler + .word EXTI4_IRQHandler + .word DMA1_Channel1_IRQHandler + .word DMA1_Channel2_IRQHandler + .word DMA1_Channel3_IRQHandler + .word DMA1_Channel4_IRQHandler + .word DMA1_Channel5_IRQHandler + .word DMA1_Channel6_IRQHandler + .word DMA1_Channel7_IRQHandler + .word ADC1_IRQHandler + .word USB_HP_IRQHandler + .word USB_LP_IRQHandler + .word C2SEV_PWR_C2H_IRQHandler + .word COMP_IRQHandler + .word EXTI9_5_IRQHandler + .word TIM1_BRK_IRQHandler + .word TIM1_UP_TIM16_IRQHandler + .word TIM1_TRG_COM_TIM17_IRQHandler + .word TIM1_CC_IRQHandler + .word TIM2_IRQHandler + .word PKA_IRQHandler + .word I2C1_EV_IRQHandler + .word I2C1_ER_IRQHandler + .word I2C3_EV_IRQHandler + .word I2C3_ER_IRQHandler + .word SPI1_IRQHandler + .word SPI2_IRQHandler + .word USART1_IRQHandler + .word LPUART1_IRQHandler + .word SAI1_IRQHandler + .word TSC_IRQHandler + .word EXTI15_10_IRQHandler + .word RTC_Alarm_IRQHandler + .word CRS_IRQHandler + .word PWR_SOTF_BLEACT_802ACT_RFPHASE_IRQHandler + .word IPCC_C1_RX_IRQHandler + .word IPCC_C1_TX_IRQHandler + .word HSEM_IRQHandler + .word LPTIM1_IRQHandler + .word LPTIM2_IRQHandler + .word LCD_IRQHandler + .word QUADSPI_IRQHandler + .word AES1_IRQHandler + .word AES2_IRQHandler + .word RNG_IRQHandler + .word FPU_IRQHandler + .word DMA2_Channel1_IRQHandler + .word DMA2_Channel2_IRQHandler + .word DMA2_Channel3_IRQHandler + .word DMA2_Channel4_IRQHandler + .word DMA2_Channel5_IRQHandler + .word DMA2_Channel6_IRQHandler + .word DMA2_Channel7_IRQHandler + .word DMAMUX1_OVR_IRQHandler + +/******************************************************************************* +* +* Provide weak aliases for each Exception handler to the Default_Handler. +* As they are weak aliases, any function with the same name will override +* this definition. +* +*******************************************************************************/ + .weak NMI_Handler + .thumb_set NMI_Handler,Default_Handler + + .weak HardFault_Handler + .thumb_set HardFault_Handler,Default_Handler + + .weak MemManage_Handler + .thumb_set MemManage_Handler,Default_Handler + + .weak BusFault_Handler + .thumb_set BusFault_Handler,Default_Handler + + .weak UsageFault_Handler + .thumb_set UsageFault_Handler,Default_Handler + + .weak SVC_Handler + .thumb_set SVC_Handler,Default_Handler + + .weak DebugMon_Handler + .thumb_set DebugMon_Handler,Default_Handler + + .weak PendSV_Handler + .thumb_set PendSV_Handler,Default_Handler + + .weak SysTick_Handler + .thumb_set SysTick_Handler,Default_Handler + + .weak WWDG_IRQHandler + .thumb_set WWDG_IRQHandler,Default_Handler + + .weak PVD_PVM_IRQHandler + .thumb_set PVD_PVM_IRQHandler,Default_Handler + + .weak TAMP_STAMP_LSECSS_IRQHandler + .thumb_set TAMP_STAMP_LSECSS_IRQHandler,Default_Handler + + .weak RTC_WKUP_IRQHandler + .thumb_set RTC_WKUP_IRQHandler,Default_Handler + + .weak FLASH_IRQHandler + .thumb_set FLASH_IRQHandler,Default_Handler + + .weak RCC_IRQHandler + .thumb_set RCC_IRQHandler,Default_Handler + + .weak EXTI0_IRQHandler + .thumb_set EXTI0_IRQHandler,Default_Handler + + .weak EXTI1_IRQHandler + .thumb_set EXTI1_IRQHandler,Default_Handler + + .weak EXTI2_IRQHandler + .thumb_set EXTI2_IRQHandler,Default_Handler + + .weak EXTI3_IRQHandler + .thumb_set EXTI3_IRQHandler,Default_Handler + + .weak EXTI4_IRQHandler + .thumb_set EXTI4_IRQHandler,Default_Handler + + .weak DMA1_Channel1_IRQHandler + .thumb_set DMA1_Channel1_IRQHandler,Default_Handler + + .weak DMA1_Channel2_IRQHandler + .thumb_set DMA1_Channel2_IRQHandler,Default_Handler + + .weak DMA1_Channel3_IRQHandler + .thumb_set DMA1_Channel3_IRQHandler,Default_Handler + + .weak DMA1_Channel4_IRQHandler + .thumb_set DMA1_Channel4_IRQHandler,Default_Handler + + .weak DMA1_Channel5_IRQHandler + .thumb_set DMA1_Channel5_IRQHandler,Default_Handler + + .weak DMA1_Channel6_IRQHandler + .thumb_set DMA1_Channel6_IRQHandler,Default_Handler + + .weak DMA1_Channel7_IRQHandler + .thumb_set DMA1_Channel7_IRQHandler,Default_Handler + + .weak ADC1_IRQHandler + .thumb_set ADC1_IRQHandler,Default_Handler + + .weak USB_HP_IRQHandler + .thumb_set USB_HP_IRQHandler,Default_Handler + + .weak USB_LP_IRQHandler + .thumb_set USB_LP_IRQHandler,Default_Handler + + .weak C2SEV_PWR_C2H_IRQHandler + .thumb_set C2SEV_PWR_C2H_IRQHandler,Default_Handler + + .weak COMP_IRQHandler + .thumb_set COMP_IRQHandler,Default_Handler + + .weak EXTI9_5_IRQHandler + .thumb_set EXTI9_5_IRQHandler,Default_Handler + + .weak TIM1_BRK_IRQHandler + .thumb_set TIM1_BRK_IRQHandler,Default_Handler + + .weak TIM1_UP_TIM16_IRQHandler + .thumb_set TIM1_UP_TIM16_IRQHandler,Default_Handler + + .weak TIM1_TRG_COM_TIM17_IRQHandler + .thumb_set TIM1_TRG_COM_TIM17_IRQHandler,Default_Handler + + .weak TIM1_CC_IRQHandler + .thumb_set TIM1_CC_IRQHandler,Default_Handler + + .weak TIM2_IRQHandler + .thumb_set TIM2_IRQHandler,Default_Handler + + .weak PKA_IRQHandler + .thumb_set PKA_IRQHandler,Default_Handler + + .weak I2C1_EV_IRQHandler + .thumb_set I2C1_EV_IRQHandler,Default_Handler + + .weak I2C1_ER_IRQHandler + .thumb_set I2C1_ER_IRQHandler,Default_Handler + + .weak I2C3_EV_IRQHandler + .thumb_set I2C3_EV_IRQHandler,Default_Handler + + .weak I2C3_ER_IRQHandler + .thumb_set I2C3_ER_IRQHandler,Default_Handler + + .weak SPI1_IRQHandler + .thumb_set SPI1_IRQHandler,Default_Handler + + .weak SPI2_IRQHandler + .thumb_set SPI2_IRQHandler,Default_Handler + + .weak USART1_IRQHandler + .thumb_set USART1_IRQHandler,Default_Handler + + .weak LPUART1_IRQHandler + .thumb_set LPUART1_IRQHandler,Default_Handler + + .weak SAI1_IRQHandler + .thumb_set SAI1_IRQHandler,Default_Handler + + .weak TSC_IRQHandler + .thumb_set TSC_IRQHandler,Default_Handler + + .weak EXTI15_10_IRQHandler + .thumb_set EXTI15_10_IRQHandler,Default_Handler + + .weak RTC_Alarm_IRQHandler + .thumb_set RTC_Alarm_IRQHandler,Default_Handler + + .weak CRS_IRQHandler + .thumb_set CRS_IRQHandler,Default_Handler + + .weak PWR_SOTF_BLEACT_802ACT_RFPHASE_IRQHandler + .thumb_set PWR_SOTF_BLEACT_802ACT_RFPHASE_IRQHandler,Default_Handler + + .weak IPCC_C1_RX_IRQHandler + .thumb_set IPCC_C1_RX_IRQHandler,Default_Handler + + .weak IPCC_C1_TX_IRQHandler + .thumb_set IPCC_C1_TX_IRQHandler,Default_Handler + + .weak HSEM_IRQHandler + .thumb_set HSEM_IRQHandler,Default_Handler + + .weak LPTIM1_IRQHandler + .thumb_set LPTIM1_IRQHandler,Default_Handler + + .weak LPTIM2_IRQHandler + .thumb_set LPTIM2_IRQHandler,Default_Handler + + .weak LCD_IRQHandler + .thumb_set LCD_IRQHandler,Default_Handler + + .weak QUADSPI_IRQHandler + .thumb_set QUADSPI_IRQHandler,Default_Handler + + .weak AES1_IRQHandler + .thumb_set AES1_IRQHandler,Default_Handler + + .weak AES2_IRQHandler + .thumb_set AES2_IRQHandler,Default_Handler + + .weak RNG_IRQHandler + .thumb_set RNG_IRQHandler,Default_Handler + + .weak FPU_IRQHandler + .thumb_set FPU_IRQHandler,Default_Handler + + .weak DMA2_Channel1_IRQHandler + .thumb_set DMA2_Channel1_IRQHandler,Default_Handler + + .weak DMA2_Channel2_IRQHandler + .thumb_set DMA2_Channel2_IRQHandler,Default_Handler + + .weak DMA2_Channel3_IRQHandler + .thumb_set DMA2_Channel3_IRQHandler,Default_Handler + + .weak DMA2_Channel4_IRQHandler + .thumb_set DMA2_Channel4_IRQHandler,Default_Handler + + .weak DMA2_Channel5_IRQHandler + .thumb_set DMA2_Channel5_IRQHandler,Default_Handler + + .weak DMA2_Channel6_IRQHandler + .thumb_set DMA2_Channel6_IRQHandler,Default_Handler + + .weak DMA2_Channel7_IRQHandler + .thumb_set DMA2_Channel7_IRQHandler,Default_Handler + + .weak DMAMUX1_OVR_IRQHandler + .thumb_set DMAMUX1_OVR_IRQHandler,Default_Handler + diff --git a/scripts/build/build/targets.py b/scripts/build/build/targets.py index a87d26cd165cf8..7f8f3812b95e01 100755 --- a/scripts/build/build/targets.py +++ b/scripts/build/build/targets.py @@ -30,6 +30,7 @@ from builders.nrf import NrfApp, NrfBoard, NrfConnectBuilder from builders.openiotsdk import OpenIotSdkApp, OpenIotSdkBuilder, OpenIotSdkCryptoBackend from builders.qpg import QpgApp, QpgBoard, QpgBuilder +from builders.stm32 import stm32App, stm32Board, stm32Builder from builders.telink import TelinkApp, TelinkBoard, TelinkBuilder from builders.ti import TIApp, TIBoard, TIBuilder from builders.tizen import TizenApp, TizenBoard, TizenBuilder @@ -563,6 +564,22 @@ def BuildQorvoTarget(): return target +def BuildStm32Target(): + target = BuildTarget('stm32', stm32Builder) + + # board + target.AppendFixedTargets([ + TargetPart('STM32WB5MM-DK', board=stm32Board.STM32WB55XX), + ]) + + # apps + target.AppendFixedTargets([ + TargetPart('light', app=stm32App.LIGHT), + ]) + + return target + + def BuildTizenTarget(): target = BuildTarget('tizen', TizenBuilder) @@ -724,6 +741,7 @@ def BuildOpenIotSdkTargets(): BuildNrfTarget(), BuildNrfNativeTarget(), BuildQorvoTarget(), + BuildStm32Target(), BuildTizenTarget(), BuildTelinkTarget(), BuildOpenIotSdkTargets(), diff --git a/scripts/build/builders/stm32.py b/scripts/build/builders/stm32.py new file mode 100644 index 00000000000000..1613ecbbe42f39 --- /dev/null +++ b/scripts/build/builders/stm32.py @@ -0,0 +1,93 @@ +# Copyright (c) 2021 Project CHIP Authors +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +import os +from enum import Enum, auto + +from .gn import GnBuilder + + +class stm32App(Enum): + LIGHT = auto() + + def ExampleName(self): + if self == stm32App.LIGHT: + return 'lighting-app' + else: + raise Exception('Unknown app type: %r' % self) + + def AppNamePrefix(self): + if self == stm32App.LIGHT: + return 'chip-stm32-lighting-example' + else: + raise Exception('Unknown app type: %r' % self) + + def FlashBundleName(self): + if self == stm32App.LIGHT: + return 'lighting_app.out.flashbundle.txt' + else: + raise Exception('Unknown app type: %r' % self) + + def BuildRoot(self, root): + return os.path.join(root, 'examples', self.ExampleName(), 'stm32') + + +class stm32Board(Enum): + STM32WB55XX = auto() + + def GetIC(self): + if self == stm32Board.STM32WB55XX: + return 'STM32WB5MM-DK' + else: + raise Exception('Unknown board #: %r' % self) + + +class stm32Builder(GnBuilder): + + def __init__(self, + root, + runner, + app: stm32App = stm32App.LIGHT, + board: stm32Board = stm32Board.STM32WB55XX): + super(stm32Builder, self).__init__( + root=app.BuildRoot(root), + runner=runner) + + self.board = board + self.app = app + + stm32_chip = self.board.GetIC() + self.extra_gn_options = ['stm32_ic_family="%s"' % stm32_chip] + + self.extra_gn_options.append('chip_config_network_layer_ble=true') + self.extra_gn_options.append('treat_warnings_as_errors=false') + + def GnBuildArgs(self): + + return self.extra_gn_options + + def build_outputs(self): + items = {} + for extension in ["out", "out.map", "out.hex"]: + name = '%s.%s' % (self.app.AppNamePrefix(), extension) + items[name] = os.path.join(self.output_dir, name) + + # Figure out flash bundle files and build accordingly + with open(os.path.join(self.output_dir, self.app.FlashBundleName())) as f: + for line in f.readlines(): + name = line.strip() + items['flashbundle/%s' % + name] = os.path.join(self.output_dir, name) + + return items diff --git a/scripts/build/testdata/all_targets_linux_x64.txt b/scripts/build/testdata/all_targets_linux_x64.txt index 8311994a7c28b3..44ca9c3fe2480d 100644 --- a/scripts/build/testdata/all_targets_linux_x64.txt +++ b/scripts/build/testdata/all_targets_linux_x64.txt @@ -20,6 +20,7 @@ mw320-all-clusters-app nrf-{nrf5340dk,nrf52840dk,nrf52840dongle}-{all-clusters,all-clusters-minimal,lock,light,light-switch,shell,pump,pump-controller,window-covering}[-rpc] nrf-native-posix-64-tests qpg-qpg6105-{lock,light,shell,persistent-storage} +stm32-stm32wb5mm-dk-light tizen-arm-{all-clusters,all-clusters-minimal,chip-tool,light,tests}[-no-ble][-no-thread][-no-wifi][-asan][-ubsan] telink-tlsr9518adk80d-{all-clusters,all-clusters-minimal,bridge,contact-sensor,light,light-switch,lock,ota-requestor,pump,pump-controller,shell,smoke-co-alarm,temperature-measurement,thermostat,window-covering}[-shell][-rpc][-factory-data] openiotsdk-{shell,lock}[-mbedtls][-psa] diff --git a/scripts/checkout_submodules.py b/scripts/checkout_submodules.py index 22ac0fa754bbe9..22750fd40a8bff 100755 --- a/scripts/checkout_submodules.py +++ b/scripts/checkout_submodules.py @@ -41,6 +41,7 @@ 'mbed', 'nrfconnect', 'qpg', + 'stm32', 'telink', 'tizen', 'webos', diff --git a/scripts/examples/gn_stm32_example.sh b/scripts/examples/gn_stm32_example.sh new file mode 100755 index 00000000000000..62c19cc3470de6 --- /dev/null +++ b/scripts/examples/gn_stm32_example.sh @@ -0,0 +1,198 @@ +#!/usr/bin/env bash + +# +# Copyright (c) 2023 Project CHIP Authors +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +# Build script for GN STM32 examples GitHub workflow. + +set -e + +echo_green() { + echo -e "\033[0;32m$*\033[0m" +} + +echo_blue() { + echo -e "\033[1;34m$*\033[0m" +} + +if [[ -z "${MATTER_ROOT}" ]]; then + echo "Using default path for Matter root" + CHIP_ROOT="$(dirname "$0")/../.." +else + echo "Using ENV path for Matter root" + CHIP_ROOT="$MATTER_ROOT" +fi + +source "$CHIP_ROOT/scripts/activate.sh" + +set -x +env +USE_WIFI=false + +#ST_THREAD_TARGET=\""../st:ot-stm32-cert"\" +USAGE="./scripts/examples/gn_stm32_example.sh []" + +if [ "$#" == "0" ]; then + echo "Build script for stm32 Matter apps + Format: + $USAGE + + + Root Location of the app e.g: examples/lighting-app/stm32/ + + + Desired location for the output files + + + Identifier of the board for which this app is built + Currently Supported : + STM32WB5MM-DK + + - optional noteworthy build options for stm32 + chip_build_libshell + Enable libshell support. (Default false) + chip_logging + Current value (Default true) + chip_openthread_ftd + Use openthread Full Thread Device, else, use Minimal Thread Device. (Default true) + stm32_sdk_root + Location for an alternate or modified stm32 SDK + enable_heap_monitoring + Monitor & log memory usage at runtime. (Default false) + enable_openthread_cli + Enables openthread cli without matter shell. (Default true) + kvs_max_entries + Set the maxium Kvs entries that can be store in NVM (Default 75) + Thresholds: 30 <= kvs_max_entries <= 255 + show_qr_code + Enables QR code on LCD for devices with an LCD + setupDiscriminator + Discriminatoor value used for BLE connexion. (Default 3840) + setupPinCode + PIN code for PASE session establishment. (Default 20202021) + enable_sleepy_device + Enable Sleepy end device. (Default false) + Must also set chip_openthread_ftd=false + use_mxchip + Build wifi example with MXCHIP extension board. (Default false) + 'import("//with_pw_rpc.gni")' + Use to build the example with pigweed RPC + OTA_periodic_query_timeout + Periodic query timeout variable for OTA in seconds + wifi_wpa3_only + Support for WPA3 only mode + Presets + --sed + enable sleepy end device, set thread mtd + For minimum consumption, disable openthread cli and qr code + --wifi + build wifi example variant for given extension board + --additional_data_advertising + enable Addition data advertissing and rotating device ID + --use_ot_lib + use the STMicroelectronics openthread library + " +elif [ "$#" -lt "2" ]; then + echo "Invalid number of arguments + Format: + $USAGE" +else + ROOT=$1 + OUTDIR=$2 + + if [ "$#" -gt "2" ]; then + STM32_BOARD=$3 + shift + fi + + shift + shift + while [ $# -gt 0 ]; do + case $1 in + --wifi) + if [ -z "$2" ]; then + echo "--wifi requires mxchip" + exit 1 + fi + if [ "$2" = "mxchip" ]; then + optArgs+="use_mxchip=true" + else + echo "Wifi usage: --wifi mxchip" + exit 1 + fi + USE_WIFI=true + shift + shift + ;; + --sed) + optArgs+="enable_sleepy_device=true chip_openthread_ftd=false " + shift + ;; + --chip_enable_wifi_ipv4) + optArgs+="chip_enable_wifi_ipv4=true " + shift + ;; + --additional_data_advertising) + optArgs+="chip_enable_additional_data_advertising=true chip_enable_rotating_device_id=true " + shift + ;; + --use_ot_lib) + optArgs+="use_st_thread_lib=true chip_openthread_target=$ST_THREAD_TARGET openthread_external_platform=\"""\" " + shift + ;; + --use_ot_coap_lib) + optArgs+="use_st_thread_lib=true chip_openthread_target=$ST_THREAD_TARGET openthread_external_platform=\"""\" use_thread_coap_lib=true " + shift + ;; + *) + if [ "$1" =~ *"use_mxchip=true"* ]; then + USE_WIFI=true + fi + + optArgs+=$1" " + shift + ;; + esac + done + + if [ -z "$STM32_BOARD" ]; then + echo "STM32_BOARD not defined" + exit 1 + fi + + BUILD_DIR=$OUTDIR/$STM32_BOARD + echo BUILD_DIR="$BUILD_DIR" + if [ "$USE_WIFI" == true ]; then + gn gen --check --fail-on-unused-args --export-compile-commands --root="$ROOT" --dotfile="$ROOT"/build_for_wifi_gnfile.gn --args="stm32_board=\"$STM32_BOARD\" $optArgs" "$BUILD_DIR" + else + # thread build + # + if [ -z "$optArgs" ]; then + gn gen --check --fail-on-unused-args --export-compile-commands --root="$ROOT" --args="stm32_board=\"$STM32_BOARD\" treat_warnings_as_errors=false" --ide=json "$BUILD_DIR" + else + gn gen --check --fail-on-unused-args --export-compile-commands --root="$ROOT" --args="stm32_board=\"$STM32_BOARD\" $optArgs treat_warnings_as_errors=false" --ide=json "$BUILD_DIR" + fi + fi + ninja -v -C "$BUILD_DIR"/ + + #print stats + arm-none-eabi-size "$BUILD_DIR"/*.elf + + arm-none-eabi-objcopy -O binary "$BUILD_DIR"/*.elf """$BUILD_DIR/*.elf.bin" + + set +x + echo_green "Finished building target: ""$BUILD_DIR/*.elf" +fi diff --git a/scripts/flashing/stm32_firmware_utils.py b/scripts/flashing/stm32_firmware_utils.py new file mode 100644 index 00000000000000..2109f0347d144a --- /dev/null +++ b/scripts/flashing/stm32_firmware_utils.py @@ -0,0 +1,124 @@ +#!/usr/bin/env python3 +# Copyright (c) 2023 Project CHIP Authors +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +import sys + +import firmware_utils + +STM32_OPTIONS = { + 'configuration': { + 'stm32cubeprogrammer': { + 'help': 'Path to the STM32CubeProgrammer executable', + 'default': 'STM32_Programmer_CLI', + 'argparse': { + 'metavar': 'FILE' + }, + 'verify': ['{stm32cubeprogrammer}', '-v'], + 'error': + """\ + Unable to execute STM32CubeProgrammer. + + Please ensure that this tool is installed and + available. See the STM32 example README for + installation instructions. + + """, + }, + 'device': { + 'help': 'Device family or platform to target', + 'default': 'STM32', + 'alias': ['-d'], + 'argparse': { + 'metavar': 'DEVICE' + }, + }, + 'port': { + 'help': 'Serial port of the device to flash', + 'default': None, + 'alias': ['-p'], + 'argparse': { + 'metavar': 'PORT' + }, + }, + }, +} + + +class Flasher(firmware_utils.Flasher): + """Manage STM32 flashing.""" + + def __init__(self, **options): + super().__init__(platform='STM32', module=__name__, **options) + self.define_options(STM32_OPTIONS) + + def erase(self): + """Erase the device.""" + return self.run_tool( + 'stm32cubeprogrammer', + ['--connect', 'port={port}', '-c', 'port=SWD', '--erase', 'all'], + name='Erase device') + + def verify(self, image): + """Verify image.""" + return self.run_tool( + 'stm32cubeprogrammer', + ['--connect', 'port={port}', '-c', 'port=SWD', '--verify', image], + name='Verify', + pass_message='Verified', + fail_message='Not verified', + fail_level=2) + + def flash(self, image): + """Flash image.""" + return self.run_tool( + 'stm32cubeprogrammer', + ['--connect', 'port={port}', '-c', 'port=SWD', '--write', image, '--format', 'bin', '--start-address', + '0x8000000'], + name='Flash') + + def reset(self): + """Reset the device.""" + return self.run_tool( + 'stm32cubeprogrammer', + ['--connect', 'port={port}', '-c', 'port=SWD', '--rst'], + name='Reset') + + def actions(self): + """Perform actions on the device according to self.option.""" + self.log(3, 'Options:', self.option) + + if self.option.erase: + if self.erase().err: + return self + + if self.option.application: + application = self.option.application + if self.flash(application).err: + return self + if self.option.verify_application: + if self.verify(application).err: + return self + if self.option.reset is None: + self.option.reset = True + + if self.option.reset: + if self.reset().err: + return self + + return self + + +if __name__ == '__main__': + sys.exit(Flasher().flash_command(sys.argv)) diff --git a/src/platform/BUILD.gn b/src/platform/BUILD.gn index d0706b47ec91cd..5c1f079cef3cf9 100644 --- a/src/platform/BUILD.gn +++ b/src/platform/BUILD.gn @@ -316,6 +316,11 @@ if (chip_device_platform != "none" && chip_device_platform != "external") { "CHIP_DEVICE_LAYER_TARGET_ASR=1", "CHIP_DEVICE_LAYER_TARGET=ASR", ] + } else if (chip_device_platform == "stm32") { + defines += [ + "CHIP_DEVICE_LAYER_TARGET_STM32=1", + "CHIP_DEVICE_LAYER_TARGET=stm32", + ] } if (chip_device_config_device_software_version != "") { @@ -517,6 +522,8 @@ if (chip_device_platform != "none") { _platform_target = "openiotsdk" } else if (chip_device_platform == "asr") { _platform_target = "ASR" + } else if (chip_device_platform == "stm32") { + _platform_target = "stm32" } else { assert(false, "Unknown chip_device_platform: ${chip_device_platform}") } diff --git a/src/platform/device.gni b/src/platform/device.gni index b70b576644318e..bf243f26524839 100644 --- a/src/platform/device.gni +++ b/src/platform/device.gni @@ -52,7 +52,7 @@ declare_args() { chip_device_platform == "cc13x2_26x2" || chip_device_platform == "cc13x4_26x4" || chip_device_platform == "k32w0" || chip_device_platform == "tizen" || - chip_device_platform == "webos" + chip_device_platform == "webos" || chip_device_platform == "stm32" } declare_args() { @@ -181,6 +181,8 @@ if (chip_device_platform == "cc13x2_26x2") { _chip_device_layer = "openiotsdk" } else if (chip_device_platform == "asr") { _chip_device_layer = "ASR" +} else if (chip_device_platform == "stm32") { + _chip_device_layer = "stm32" } if (chip_device_platform != "external") { @@ -250,5 +252,6 @@ assert( chip_device_platform == "bl602" || chip_device_platform == "bl702" || chip_device_platform == "bl702l" || chip_device_platform == "mt793x" || chip_device_platform == "SiWx917" || - chip_device_platform == "openiotsdk" || chip_device_platform == "asr", + chip_device_platform == "openiotsdk" || chip_device_platform == "asr" || + chip_device_platform == "stm32", "Please select a valid value for chip_device_platform") diff --git a/src/platform/stm32/BLEManagerImpl.cpp b/src/platform/stm32/BLEManagerImpl.cpp new file mode 100644 index 00000000000000..1cffd11b783487 --- /dev/null +++ b/src/platform/stm32/BLEManagerImpl.cpp @@ -0,0 +1,743 @@ +/* + * + * Copyright (c) 2020-2021 Project CHIP Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * @file + * Provides an implementation of the BLEManager singleton object + * for the stm32wb55 platforms. + */ + +/* this file behaves like a config.h, comes first */ +#include + +#include +#include +#include + +#include +#include + +/**** STM32 api files for ble and led support ****/ +#include "app_ble.h" +#include "app_matter.h" +#include "ble_gap_aci.h" +#include "cmsis_os.h" + +using namespace ::chip; +using namespace ::chip::Ble; +using namespace ::chip::System; + +namespace chip { +namespace DeviceLayer { +namespace Internal { + +namespace { + +// Advertising data content definitions +#define CHIP_ADV_DATA_TYPE_FLAGS 0x01 +#define CHIP_ADV_DATA_TYPE_UUID 0x03 +#define CHIP_ADV_DATA_FLAGS 0x06 +#define CHIP_ADV_DATA_TYPE_NAME 0x09 +#define CHIP_ADV_DATA_TYPE_SERVICE_DATA 0x16 +#define STM32_MTU 247 +#define CHIP_ADV_SHORT_UUID_LEN 2 +#define CONNECTION_CLOSE 0x13 + +// FreeeRTOS sw timer +TimerHandle_t sbleAdvTimeoutTimer; + +// Full service UUID - CHIP_BLE_SVC_ID - taken from BleUUID.h header +const uint8_t chipUUID_CHIPoBLE_Service[CHIP_ADV_SHORT_UUID_LEN] = { 0xFF, 0xF6 }; + +const ChipBleUUID chipUUID_CHIPoBLEChar_RX = { { 0x18, 0xEE, 0x2E, 0xF5, 0x26, 0x3D, 0x45, 0x59, 0x95, 0x9F, 0x4F, 0x9C, 0x42, 0x9F, + 0x9D, 0x11 } }; + +const ChipBleUUID chipUUID_CHIPoBLEChar_TX = { { 0x18, 0xEE, 0x2E, 0xF5, 0x26, 0x3D, 0x45, 0x59, 0x95, 0x9F, 0x4F, 0x9C, 0x42, 0x9F, + 0x9D, 0x12 } }; + +} // unnamed namespace + +BLEManagerImpl BLEManagerImpl::sInstance; +uint16_t gconnid = 0; + +CHIP_ERROR BLEManagerImpl::_Init() +{ + CHIP_ERROR err; + + mServiceMode = ConnectivityManager::kCHIPoBLEServiceMode_Enabled; + mFlags.ClearAll().Set(Flags::kAdvertisingEnabled, CHIP_DEVICE_CONFIG_CHIPOBLE_ENABLE_ADVERTISING_AUTOSTART); + mFlags.Set(Flags::kFastAdvertisingEnabled); + mNumGAPCons = 0; + + for (int i = 0; i < kMaxConnections; i++) + { + mSubscribedConIds[i] = BLE_CONNECTION_UNINITIALIZED; + } + + // Initialize the CHIP BleLayer. + err = BleLayer::Init(this, this, &DeviceLayer::SystemLayer()); + SuccessOrExit(err); + + // Create FreeRTOS sw timer for BLE timeouts and interval change. + sbleAdvTimeoutTimer = xTimerCreate("BleAdvTimer", // Just a text name, not used by the RTOS kernel + pdMS_TO_TICKS(1), // == default timer period (mS) + false, // no timer reload (==one-shot) + (void *) this, // init timer id = ble obj context + BleAdvTimeoutHandler // timer callback handler + ); + VerifyOrExit(sbleAdvTimeoutTimer != NULL, err = CHIP_ERROR_INCORRECT_STATE); + + PlatformMgr().ScheduleWork(DriveBLEState, 0); + + APP_MATTER_BLE_Set_Receive_Callback(HandleRXCharWrite); + APP_MATTER_BLE_Set_Connection_Callback(HandleGAPConnect); + APP_MATTER_BLE_Set_Disconnection_Callback(HandleGAPDisconnect); + APP_MATTER_BLE_Set_TXCharCCCDWrite_Callback(HandleTXCharCCCDWrite); + APP_MATTER_BLE_Set_Ack_After_Indicate_Callback(HandleAck); + +exit: + ChipLogProgress(DeviceLayer, "BLEManagerImpl::Init() complete"); + + return err; +} + +CHIP_ERROR BLEManagerImpl::_SetCHIPoBLEServiceMode(CHIPoBLEServiceMode val) +{ + CHIP_ERROR err = CHIP_NO_ERROR; + + VerifyOrExit(val != ConnectivityManager::kCHIPoBLEServiceMode_NotSupported, err = CHIP_ERROR_INVALID_ARGUMENT); + VerifyOrExit(mServiceMode != ConnectivityManager::kCHIPoBLEServiceMode_NotSupported, err = CHIP_ERROR_UNSUPPORTED_CHIP_FEATURE); + + if (val != mServiceMode) + { + mServiceMode = val; + PlatformMgr().ScheduleWork(DriveBLEState, 0); + } + +exit: + return err; +} + +CHIP_ERROR BLEManagerImpl::_SetAdvertisingEnabled(bool val) +{ + CHIP_ERROR err = CHIP_NO_ERROR; + + VerifyOrExit(mServiceMode != ConnectivityManager::kCHIPoBLEServiceMode_NotSupported, err = CHIP_ERROR_UNSUPPORTED_CHIP_FEATURE); + ChipLogDetail(DeviceLayer, "CHIPoBLE advertising set to %s", val ? "on" : "off"); + if (mFlags.Has(Flags::kAdvertisingEnabled) != val) + { + mFlags.Set(Flags::kAdvertisingEnabled, val); + PlatformMgr().ScheduleWork(DriveBLEState, 0); + } + +exit: + return err; +} + +CHIP_ERROR BLEManagerImpl::_SetAdvertisingMode(BLEAdvertisingMode mode) +{ + switch (mode) + { + case BLEAdvertisingMode::kFastAdvertising: + mFlags.Set(Flags::kFastAdvertisingEnabled); + break; + case BLEAdvertisingMode::kSlowAdvertising: + mFlags.Clear(Flags::kFastAdvertisingEnabled); + break; + default: + return CHIP_ERROR_INVALID_ARGUMENT; + } + mFlags.Set(Flags::kAdvertisingRefreshNeeded); + PlatformMgr().ScheduleWork(DriveBLEState, 0); + return CHIP_NO_ERROR; +} + +CHIP_ERROR BLEManagerImpl::_GetDeviceName(char * buf, size_t bufSize) +{ + CHIP_ERROR err = CHIP_NO_ERROR; + + return err; +} + +CHIP_ERROR BLEManagerImpl::_SetDeviceName(const char * devName) +{ + CHIP_ERROR err = CHIP_NO_ERROR; + + VerifyOrExit(mServiceMode != ConnectivityManager::kCHIPoBLEServiceMode_NotSupported, err = CHIP_ERROR_UNSUPPORTED_CHIP_FEATURE); + + if (devName != nullptr && devName[0] != 0) + { + // TODO set device name + SuccessOrExit(err); + + mFlags.Set(Flags::kDeviceNameSet); + } + +exit: + return err; +} + +void BLEManagerImpl::_OnPlatformEvent(const ChipDeviceEvent * event) +{ + switch (event->Type) + { + // Platform specific events + case DeviceEventType::kCHIPoBLESubscribe: { + ChipDeviceEvent connEstEvent; + HandleSubscribeReceived(event->CHIPoBLESubscribe.ConId, &CHIP_BLE_SVC_ID, &chipUUID_CHIPoBLEChar_TX); + connEstEvent.Type = DeviceEventType::kCHIPoBLEConnectionEstablished; + PlatformMgr().PostEventOrDie(&connEstEvent); + } + break; + + case DeviceEventType::kCHIPoBLEUnsubscribe: { + HandleUnsubscribeReceived(event->CHIPoBLEUnsubscribe.ConId, &CHIP_BLE_SVC_ID, &chipUUID_CHIPoBLEChar_TX); + } + break; + + case DeviceEventType::kCHIPoBLEWriteReceived: { + HandleWriteReceived(event->CHIPoBLEWriteReceived.ConId, &CHIP_BLE_SVC_ID, &chipUUID_CHIPoBLEChar_RX, + PacketBufferHandle::Adopt(event->CHIPoBLEWriteReceived.Data)); + } + break; + + case DeviceEventType::kCHIPoBLEConnectionError: { + HandleConnectionError(event->CHIPoBLEConnectionError.ConId, event->CHIPoBLEConnectionError.Reason); + } + break; + + // Generic CHIP events + case DeviceEventType::kServiceProvisioningChange: + // Force the advertising state to be refreshed to reflect new provisioning state. + mFlags.Set(Flags::kAdvertisingRefreshNeeded); + + PlatformMgr().ScheduleWork(DriveBLEState, 0); + + break; + + case DeviceEventType::kCHIPoBLEIndicateConfirm: { + HandleIndicationConfirmation(event->CHIPoBLEIndicateConfirm.ConId, &CHIP_BLE_SVC_ID, &chipUUID_CHIPoBLEChar_TX); + } + break; + + default: + break; + } +} + +bool BLEManagerImpl::SubscribeCharacteristic(BLE_CONNECTION_OBJECT conId, const ChipBleUUID * svcId, const ChipBleUUID * charId) +{ + ChipLogProgress(DeviceLayer, "BLEManagerImpl::SubscribeCharacteristic() not supported"); + return false; +} + +bool BLEManagerImpl::UnsubscribeCharacteristic(BLE_CONNECTION_OBJECT conId, const ChipBleUUID * svcId, const ChipBleUUID * charId) +{ + ChipLogProgress(DeviceLayer, "BLEManagerImpl::UnsubscribeCharacteristic() not supported"); + return false; +} + +bool BLEManagerImpl::CloseConnection(BLE_CONNECTION_OBJECT conId) +{ + CHIP_ERROR err = CHIP_ERROR_UNSUPPORTED_CHIP_FEATURE; + + ChipLogProgress(DeviceLayer, "Closing BLE GATT connection con %u", *(uint16_t *) conId); + // aci_gap_terminate(gconnid, CONNECTION_CLOSE); + return (err == CHIP_NO_ERROR); +} + +uint16_t BLEManagerImpl::GetMTU(BLE_CONNECTION_OBJECT conId) const +{ + uint16_t retVal = 0; + // TODO get MTU from stm32 api + retVal = STM32_MTU; + return retVal; +} + +bool BLEManagerImpl::SendIndication(BLE_CONNECTION_OBJECT conId, const ChipBleUUID * svcId, const ChipBleUUID * charId, + PacketBufferHandle data) +{ + uint16_t dataLen = data->DataLength(); + + ChipLogDetail(DeviceLayer, "Sending notification for CHIPoBLE Client TX (con %u, len %u)", *(uint16_t *) conId, dataLen); + + APP_MATTER_Send_Notification(dataLen, data->Start()); + + return true; +} + +bool BLEManagerImpl::SendWriteRequest(BLE_CONNECTION_OBJECT conId, const ChipBleUUID * svcId, const ChipBleUUID * charId, + PacketBufferHandle pBuf) +{ + ChipLogProgress(DeviceLayer, "BLEManagerImpl::SendWriteRequest() not supported"); + return false; +} + +bool BLEManagerImpl::SendReadRequest(BLE_CONNECTION_OBJECT conId, const ChipBleUUID * svcId, const ChipBleUUID * charId, + PacketBufferHandle pBuf) +{ + ChipLogProgress(DeviceLayer, "BLEManagerImpl::SendReadRequest() not supported"); + return false; +} + +bool BLEManagerImpl::SendReadResponse(BLE_CONNECTION_OBJECT conId, BLE_READ_REQUEST_CONTEXT requestContext, + const ChipBleUUID * svcId, const ChipBleUUID * charId) +{ + ChipLogProgress(DeviceLayer, "BLEManagerImpl::SendReadResponse() not supported"); + return false; +} + +void BLEManagerImpl::NotifyChipConnectionClosed(BLE_CONNECTION_OBJECT conId) +{ + CloseConnection(conId); +} + +void BLEManagerImpl::DriveBLEState(void) +{ + CHIP_ERROR err = CHIP_NO_ERROR; + + // Perform any initialization actions that must occur after the CHIP task is running. + if (!mFlags.Has(Flags::kAsyncInitCompleted)) + { + mFlags.Set(Flags::kAsyncInitCompleted); + ChipLogProgress(DeviceLayer, "kAsyncInitCompleted done"); + // If CHIP_DEVICE_CONFIG_CHIPOBLE_DISABLE_ADVERTISING_WHEN_PROVISIONED is enabled, + // disable CHIPoBLE advertising if the device is fully provisioned. +#if CHIP_DEVICE_CONFIG_CHIPOBLE_DISABLE_ADVERTISING_WHEN_PROVISIONED + if (ConfigurationMgr().IsFullyProvisioned()) + { + mFlags.Clear(Flags::kAdvertisingEnabled); + ChipLogProgress(DeviceLayer, "CHIPoBLE advertising disabled because device is fully provisioned"); + } +#endif // CHIP_DEVICE_CONFIG_CHIPOBLE_DISABLE_ADVERTISING_WHEN_PROVISIONED + } + + // If the application has enabled CHIPoBLE and BLE advertising... + if (mServiceMode == ConnectivityManager::kCHIPoBLEServiceMode_Enabled && + mFlags.Has(Flags::kAdvertisingEnabled) +#if CHIP_DEVICE_CONFIG_CHIPOBLE_SINGLE_CONNECTION + // and no connections are active... + && (mNumGAPCons == 0) +#endif + ) + { + // Start/re-start BLE advertising if not already advertising, or if the + // advertising state of the underlying stack needs to be refreshed. + if (!mFlags.Has(Flags::kAdvertising) || mFlags.Has(Flags::kAdvertisingRefreshNeeded)) + { + mFlags.Clear(Flags::kAdvertisingRefreshNeeded); + err = StartAdvertising(); + SuccessOrExit(err); + } + } + + // Otherwise, stop advertising if currently active. + else if (mFlags.Has(Flags::kAdvertising)) + { + err = StopAdvertising(); + SuccessOrExit(err); + } + +exit: + if (err != CHIP_NO_ERROR) + { + ChipLogError(DeviceLayer, "Disabling CHIPoBLE service due to error: %s", ErrorStr(err)); + mServiceMode = ConnectivityManager::kCHIPoBLEServiceMode_Disabled; + } +} + +CHIP_ERROR BLEManagerImpl::ConfigureAdvertisingData(void) +{ + ChipBLEDeviceIdentificationInfo mDeviceIdInfo; + CHIP_ERROR err; + uint8_t index = 0; + uint8_t deviceNameLength = 0; + uint8_t deviceIdInfoLength = 0; + int ret = 0; + + char deviceName[kMaxDeviceNameLength + 1]; + uint8_t advDataBuf[kMaxAdvertisementDataSetSize]; + uint8_t scanRespDataBuf[kMaxAdvertisementDataSetSize]; + + memset(advDataBuf, 0, kMaxAdvertisementDataSetSize); + memset(scanRespDataBuf, 0, kMaxAdvertisementDataSetSize); + + err = ConfigurationMgr().GetBLEDeviceIdentificationInfo(mDeviceIdInfo); + SuccessOrExit(err); + + if (!mFlags.Has(Flags::kDeviceNameSet)) + { + snprintf(deviceName, sizeof(deviceName), "%s%04" PRIX32, CHIP_DEVICE_CONFIG_BLE_DEVICE_NAME_PREFIX, (uint32_t) 0); + deviceName[kMaxDeviceNameLength] = 0; + SuccessOrExit(err); + } + + deviceNameLength = static_cast(strlen(deviceName)); + deviceIdInfoLength = sizeof(mDeviceIdInfo); + + // Check sizes + static_assert(sizeof(mDeviceIdInfo) + CHIP_ADV_SHORT_UUID_LEN + 1 <= UINT8_MAX, "Our length won't fit in a uint8_t"); + static_assert(2 + CHIP_ADV_SHORT_UUID_LEN + sizeof(mDeviceIdInfo) + 1 <= kMaxAdvertisementDataSetSize, + "Advertisement data buffer is not big enough"); + + // Fill in advertising data + index = 0; + advDataBuf[index++] = 0x02; // length + advDataBuf[index++] = CHIP_ADV_DATA_TYPE_FLAGS; // AD type : flags + advDataBuf[index++] = CHIP_ADV_DATA_FLAGS; // AD value + + advDataBuf[index++] = static_cast(deviceIdInfoLength + CHIP_ADV_SHORT_UUID_LEN + 1); // AD length + advDataBuf[index++] = CHIP_ADV_DATA_TYPE_SERVICE_DATA; // AD type : Service Data + advDataBuf[index++] = chipUUID_CHIPoBLE_Service[1]; // AD value + advDataBuf[index++] = chipUUID_CHIPoBLE_Service[0]; + memcpy(&advDataBuf[index], (void *) &mDeviceIdInfo, deviceIdInfoLength); // AD value + + index = static_cast(index + deviceIdInfoLength); + + ChipLogError(DeviceLayer, "state return update adv: %d", ret); + // Fill in scan response data + index = 0; + scanRespDataBuf[index++] = CHIP_ADV_SHORT_UUID_LEN + 1; // AD length + scanRespDataBuf[index++] = CHIP_ADV_DATA_TYPE_UUID; // AD type : uuid + scanRespDataBuf[index++] = chipUUID_CHIPoBLE_Service[1]; // AD value + scanRespDataBuf[index++] = chipUUID_CHIPoBLE_Service[0]; + + VerifyOrExit(index + (deviceNameLength + 2) <= kMaxAdvertisementDataSetSize, err = CHIP_ERROR_BUFFER_TOO_SMALL); + + scanRespDataBuf[index++] = static_cast(deviceNameLength + 1); // length + scanRespDataBuf[index++] = CHIP_ADV_DATA_TYPE_NAME; // AD type : name + memcpy(&scanRespDataBuf[index], deviceName, deviceNameLength); // AD value + index = static_cast(index + deviceNameLength); + +exit: + return err; +} + +CHIP_ERROR BLEManagerImpl::StartAdvertising(void) +{ + CHIP_ERROR err; + + // If already advertising, stop it, before changing values + if (mFlags.Has(Flags::kAdvertising)) + { + APP_BLE_Adv_Cancel(); // ST ble api + } + else + { + ChipLogProgress(DeviceLayer, "CHIPoBLE start advertising"); + } + + err = ConfigureAdvertisingData(); + SuccessOrExit(err); + + mFlags.Clear(Flags::kRestartAdvertising); + + APP_BLE_Adv_Request(APP_BLE_FAST_ADV); + // Flag updated asynchronously by BLE host callback + mFlags.Set(Flags::kAdvertising); + + if (mFlags.Has(Flags::kFastAdvertisingEnabled)) + { + StartBleAdvTimeoutTimer(CHIP_DEVICE_CONFIG_BLE_ADVERTISING_INTERVAL_CHANGE_TIME); + } + +exit: + return err; +} + +CHIP_ERROR BLEManagerImpl::StopAdvertising(void) +{ + CHIP_ERROR err; + + APP_BLE_Adv_Cancel(); // ST ble api + CancelBleAdvTimeoutTimer(); + // Transition to the not Advertising state... + if (mFlags.Has(Flags::kAdvertising)) + { + mFlags.Clear(Flags::kAdvertising); + mFlags.Set(Flags::kFastAdvertisingEnabled); + + ChipLogProgress(DeviceLayer, "CHIPoBLE advertising stopped"); + + // Post a CHIPoBLEAdvertisingChange(Stopped) event. + ChipDeviceEvent advChange; + advChange.Type = DeviceEventType::kCHIPoBLEAdvertisingChange; + advChange.CHIPoBLEAdvertisingChange.Result = kActivity_Stopped; + err = PlatformMgr().PostEvent(&advChange); + } + + return err; +} + +uint16_t BLEManagerImpl::_NumConnections(void) +{ + uint16_t numCons = 0; + for (uint16_t i = 0; i < kMaxConnections; i++) + { + if (mSubscribedConIds[i] != BLE_CONNECTION_UNINITIALIZED) + { + numCons++; + } + } + return numCons; +} + +void BLEManagerImpl::DriveBLEState(intptr_t arg) +{ + sInstance.DriveBLEState(); +} + +void BLEManagerImpl::bleConnect(void) +{ + CHIP_ERROR err; + ChipLogProgress(DeviceLayer, "BLE GATT connection established "); + + mNumGAPCons++; + mFlags.Set(Flags::kAdvertisingRefreshNeeded); + ChipDeviceEvent connectEvent; + connectEvent.Type = DeviceEventType::kCHIPoBLEConnectionEstablished; + err = PlatformMgr().PostEvent(&connectEvent); + PlatformMgr().ScheduleWork(DriveBLEState, 0); +} + +void BLEManagerImpl::bleDisconnect(uint16_t connid) +{ + CHIP_ERROR err; + + ChipLogDetail(DeviceLayer, "BLE GATT connection closed (con %u)", connid); + ; + // Force a refresh of the advertising state. + if (mNumGAPCons > 0) + { + mNumGAPCons--; + } + + // If this was a CHIPoBLE connection, release the associated connection state record + // and post an event to deliver a connection error to the CHIPoBLE layer. + if (!BLEMgrImpl().IsSubscribed(connid)) + { + if (UnsetSubscribed(connid)) + { + ChipDeviceEvent event; + event.Type = DeviceEventType::kCHIPoBLEConnectionError; + event.CHIPoBLEConnectionError.ConId = connid; + PlatformMgr().PostEventOrDie(&event); + ChipLogDetail(DeviceLayer, "BLE unuset subscribed (con %u)", connid); + } + } + + mFlags.Set(Flags::kAdvertisingRefreshNeeded); + ChipDeviceEvent disconnectEvent; + disconnectEvent.Type = DeviceEventType::kCHIPoBLEConnectionClosed; + err = PlatformMgr().PostEvent(&disconnectEvent); + PlatformMgr().ScheduleWork(DriveBLEState, 0); +} + +void BLEManagerImpl::HandleGAPConnect(void) +{ + + ChipLogProgress(DeviceLayer, "Gap connect"); + sInstance.bleConnect(); +} +void BLEManagerImpl::HandleGAPDisconnect(uint16_t * connid) +{ + ChipLogProgress(DeviceLayer, "Gap disconnect"); + sInstance.bleDisconnect(gconnid); +} + +void BLEManagerImpl::HandleRXCharWrite(BLE_Matter_RX * aMessage) +{ + CHIP_ERROR err = CHIP_NO_ERROR; + + ChipLogProgress(DeviceLayer, "Write request received for CHIPoBLE Client RX characteristic (con %u, len %u)", aMessage->connid, + aMessage->Length); + // update connid + gconnid = aMessage->connid; + + PacketBufferHandle buf = System::PacketBufferHandle::NewWithData(aMessage->Payload, aMessage->Length, 0, 0); + VerifyOrExit(!buf.IsNull(), err = CHIP_ERROR_NO_MEMORY); + // Post an event to the Chip queue to deliver the data into the Chip stack. + { + ChipDeviceEvent event; + event.Type = DeviceEventType::kCHIPoBLEWriteReceived; + event.CHIPoBLEWriteReceived.ConId = aMessage->connid; + event.CHIPoBLEWriteReceived.Data = std::move(buf).UnsafeRelease(); + err = PlatformMgr().PostEvent(&event); + } +exit: + if (err != CHIP_NO_ERROR) + { + ChipLogError(DeviceLayer, "HandleRXCharWrite() failed: %s", ErrorStr(err)); + // TODO: fail connection??? + } +} + +void BLEManagerImpl::HandleTXCharCCCDWrite(BLE_Matter_TXCharCCCD * aMessage) +{ + CHIP_ERROR err = CHIP_NO_ERROR; + bool notificationsEnabled; + + ChipLogProgress(DeviceLayer, "Write request received for CHIPoBLE TX characteristic CCCD (con %u, len %u)", aMessage->connid, + 0); + + // Determine if the client is enabling or disabling notifications + notificationsEnabled = (aMessage->notif != 0); + // If the client has requested to enable notifications + if (notificationsEnabled) + { + // Set subcription only the first time + if (!BLEMgrImpl().IsSubscribed(aMessage->connid)) // conid + { + // Record that notifications have been enabled for this connection. + err = BLEMgrImpl().SetSubscribed(aMessage->connid); + VerifyOrExit(err != CHIP_ERROR_NO_MEMORY, err = CHIP_NO_ERROR); + SuccessOrExit(err); + } + } + + else + { + // If notifications had previously been enabled for this connection, record that they are no longer enabled + BLEMgrImpl().UnsetSubscribed(aMessage->connid); + } + + // Post an event to the Chip queue to process either a CHIPoBLE Subscribe or Unsubscribe based on + // whether the client is enabling or disabling notifications + { + ChipDeviceEvent event; + event.Type = (notificationsEnabled) ? DeviceEventType::kCHIPoBLESubscribe : DeviceEventType::kCHIPoBLEUnsubscribe; + event.CHIPoBLESubscribe.ConId = aMessage->connid; + err = PlatformMgr().PostEvent(&event); + } + + ChipLogProgress(DeviceLayer, "CHIPoBLE %s received", notificationsEnabled ? "subscribe" : "unsubscribe"); + +exit: + if (err != CHIP_NO_ERROR) + { + ChipLogError(DeviceLayer, "HandleTXCharCCCDWrite() failed: %s", ErrorStr(err)); + // TODO: fail connection??? + } +} + +void BLEManagerImpl::HandleAck(uint16_t * connid) +{ + ChipDeviceEvent event; + event.Type = DeviceEventType::kCHIPoBLEIndicateConfirm; + event.CHIPoBLEIndicateConfirm.ConId = gconnid; + PlatformMgr().PostEventOrDie(&event); +} + +CHIP_ERROR BLEManagerImpl::SetSubscribed(uint16_t conId) +{ + uint16_t freeIndex = kMaxConnections; + + for (uint16_t i = 0; i < kMaxConnections; i++) + { + if (mSubscribedConIds[i] == conId) + { + return CHIP_NO_ERROR; + } + else if (mSubscribedConIds[i] == BLE_CONNECTION_UNINITIALIZED && i < freeIndex) + { + freeIndex = i; + } + } + + if (freeIndex < kMaxConnections) + { + mSubscribedConIds[freeIndex] = conId; + return CHIP_NO_ERROR; + } + else + { + return CHIP_ERROR_NO_MEMORY; + } +} + +bool BLEManagerImpl::UnsetSubscribed(uint16_t conId) +{ + for (uint16_t i = 0; i < kMaxConnections; i++) + { + if (mSubscribedConIds[i] == conId) + { + mSubscribedConIds[i] = BLE_CONNECTION_UNINITIALIZED; + return true; + } + } + return false; +} + +bool BLEManagerImpl::IsSubscribed(uint16_t conId) +{ + if (conId != BLE_CONNECTION_UNINITIALIZED) + { + for (uint16_t i = 0; i < kMaxConnections; i++) + { + if (mSubscribedConIds[i] == conId) + { + return true; + } + } + } + return false; +} + +void BLEManagerImpl::BleAdvTimeoutHandler(TimerHandle_t xTimer) +{ + if (BLEMgrImpl().mFlags.Has(Flags::kFastAdvertisingEnabled)) + { + /* Stop advertising and defer restart for when stop confirmation is received from the stack */ + ChipLogDetail(DeviceLayer, "bleAdv Timeout : Stop advertissement"); + sInstance.StopAdvertising(); + sInstance.mFlags.Set(Flags::kRestartAdvertising); + } + else if (BLEMgrImpl().mFlags.Has(Flags::kAdvertising)) + { + // Advertisement time expired. Stop advertising + ChipLogDetail(DeviceLayer, "bleAdv Timeout : Stop advertissement"); + BLEMgr().SetAdvertisingEnabled(false); + } +} + +void BLEManagerImpl::CancelBleAdvTimeoutTimer(void) +{ + if (xTimerStop(sbleAdvTimeoutTimer, 0) == pdFAIL) + { + ChipLogError(DeviceLayer, "Failed to stop BledAdv timeout timer"); + } +} + +void BLEManagerImpl::StartBleAdvTimeoutTimer(uint32_t aTimeoutInMs) +{ + if (xTimerIsTimerActive(sbleAdvTimeoutTimer)) + { + CancelBleAdvTimeoutTimer(); + } + + // timer is not active, change its period to required value (== restart). + // FreeRTOS- Block for a maximum of 100 ticks if the change period command + // cannot immediately be sent to the timer command queue. + if (xTimerChangePeriod(sbleAdvTimeoutTimer, pdMS_TO_TICKS(aTimeoutInMs), 100) != pdPASS) + { + ChipLogError(DeviceLayer, "Failed to start BledAdv timeout timer"); + } +} + +} // namespace Internal +} // namespace DeviceLayer +} // namespace chip diff --git a/src/platform/stm32/BLEManagerImpl.h b/src/platform/stm32/BLEManagerImpl.h new file mode 100644 index 00000000000000..98812500eac0b0 --- /dev/null +++ b/src/platform/stm32/BLEManagerImpl.h @@ -0,0 +1,191 @@ +/* + * + * Copyright (c) 2020-2021 Project CHIP Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * @file + * Provides an implementation of the BLEManager singleton object + * for the stm32 platforms. + */ + +#pragma once + +#if CHIP_DEVICE_CONFIG_ENABLE_CHIPOBLE + +#include +#include + +#include "FreeRTOS.h" +#include "app_ble.h" +#include "app_matter.h" +#include "timers.h" + +namespace chip { +namespace DeviceLayer { +namespace Internal { +using namespace chip::Ble; + +/** + * Concrete implementation of the BLEManager singleton object for the platform. + */ +class BLEManagerImpl final : public BLEManager, private BleLayer, private BlePlatformDelegate, private BleApplicationDelegate +{ + // Allow the BLEManager interface class to delegate method calls to + // the implementation methods provided by this class. + friend BLEManager; + +private: + // ===== Members that implement the BLEManager internal interface. + + CHIP_ERROR _Init(void); + CHIP_ERROR _Shutdown() { return CHIP_NO_ERROR; } + CHIPoBLEServiceMode _GetCHIPoBLEServiceMode(void); + CHIP_ERROR _SetCHIPoBLEServiceMode(CHIPoBLEServiceMode val); + bool _IsAdvertisingEnabled(void); + CHIP_ERROR _SetAdvertisingEnabled(bool val); + bool _IsAdvertising(void); + CHIP_ERROR _SetAdvertisingMode(BLEAdvertisingMode mode); + CHIP_ERROR _GetDeviceName(char * buf, size_t bufSize); + CHIP_ERROR _SetDeviceName(const char * deviceName); + uint16_t _NumConnections(void); + void _OnPlatformEvent(const ChipDeviceEvent * event); + BleLayer * _GetBleLayer(void); + + // ===== Members that implement virtual methods on BlePlatformDelegate. + + bool SubscribeCharacteristic(BLE_CONNECTION_OBJECT conId, const ChipBleUUID * svcId, const ChipBleUUID * charId) override; + bool UnsubscribeCharacteristic(BLE_CONNECTION_OBJECT conId, const ChipBleUUID * svcId, const ChipBleUUID * charId) override; + bool CloseConnection(BLE_CONNECTION_OBJECT conId) override; + uint16_t GetMTU(BLE_CONNECTION_OBJECT conId) const override; + bool SendIndication(BLE_CONNECTION_OBJECT conId, const ChipBleUUID * svcId, const ChipBleUUID * charId, + PacketBufferHandle pBuf) override; + bool SendWriteRequest(BLE_CONNECTION_OBJECT conId, const ChipBleUUID * svcId, const ChipBleUUID * charId, + PacketBufferHandle pBuf) override; + bool SendReadRequest(BLE_CONNECTION_OBJECT conId, const ChipBleUUID * svcId, const ChipBleUUID * charId, + PacketBufferHandle pBuf) override; + bool SendReadResponse(BLE_CONNECTION_OBJECT conId, BLE_READ_REQUEST_CONTEXT requestContext, const ChipBleUUID * svcId, + const ChipBleUUID * charId) override; + + // ===== Members that implement virtual methods on BleApplicationDelegate. + + void NotifyChipConnectionClosed(BLE_CONNECTION_OBJECT conId) override; + + // ===== Members for internal use by the following friends. + + friend BLEManager & BLEMgr(void); + friend BLEManagerImpl & BLEMgrImpl(void); + + static BLEManagerImpl sInstance; + + // ===== Private members reserved for use by this class only. + + enum class Flags : uint16_t + { + kAsyncInitCompleted = 0x0001, /**< One-time asynchronous initialization actions have been performed. */ + kAdvertisingEnabled = 0x0002, /**< The application has enabled CHIPoBLE advertising. */ + kFastAdvertisingEnabled = 0x0004, /**< The application has enabled fast advertising. */ + kAdvertising = 0x0008, /**< The system is currently CHIPoBLE advertising. */ + kAdvertisingRefreshNeeded = 0x0010, /**< The advertising state/configuration state in the BLE layer needs to be updated. */ + kDeviceNameSet = 0x0020, /**< The device name has been set. */ + kRestartAdvertising = 0x0040, /**< The advertising will be restarted when stop advertising confirmation is received and this + flag is set*/ + }; + + enum + { + kMaxConnections = BLE_LAYER_NUM_BLE_ENDPOINTS, + kMaxDeviceNameLength = 20, // TODO: right-size this + kMaxAdvertisementDataSetSize = 31 + }; + + CHIPoBLEServiceMode mServiceMode; + BitFlags mFlags; + uint16_t mNumGAPCons; + uint16_t mSubscribedConIds[kMaxConnections]; + + void DriveBLEState(void); + CHIP_ERROR ConfigureAdvertisingData(void); + CHIP_ERROR StartAdvertising(void); + CHIP_ERROR StopAdvertising(void); + CHIP_ERROR SetSubscribed(uint16_t conId); + bool UnsetSubscribed(uint16_t conId); + bool IsSubscribed(uint16_t conId); + void bleConnect(void); + void bleDisconnect(uint16_t connid); + + CHIP_ERROR MapBLEError(int bleErr) const; + /* Callbacks from BLE stack*/ + static void HandleGAPConnect(void); + static void HandleGAPDisconnect(uint16_t * connid); + static void HandleRXCharWrite(BLE_Matter_RX * aMessage); + static void HandleTXCharCCCDWrite(BLE_Matter_TXCharCCCD * aMessage); + static void HandleAck(uint16_t * connid); + + static void DriveBLEState(intptr_t arg); + + /* Handlers for stack events */ + static void BleAdvTimeoutHandler(TimerHandle_t xTimer); + static void CancelBleAdvTimeoutTimer(void); + static void StartBleAdvTimeoutTimer(uint32_t aTimeoutInMs); +}; + +/** + * Returns a reference to the public interface of the BLEManager singleton object. + * + * Internal components should use this to access features of the BLEManager object + * that are common to all platforms. + */ +inline BLEManager & BLEMgr() +{ + return BLEManagerImpl::sInstance; +} + +/** + * Returns a reference to the public interface of the BLEManager singleton object. + * + * Internal components should use this to access features of the BLEManager object + * that are specific to the stm32 platforms. + */ +inline BLEManagerImpl & BLEMgrImpl(void) +{ + return BLEManagerImpl::sInstance; +} + +inline BleLayer * BLEManagerImpl::_GetBleLayer() +{ + return this; +} + +inline BLEManager::CHIPoBLEServiceMode BLEManagerImpl::_GetCHIPoBLEServiceMode(void) +{ + return mServiceMode; +} + +inline bool BLEManagerImpl::_IsAdvertisingEnabled(void) +{ + return mFlags.Has(Flags::kAdvertisingEnabled); +} + +inline bool BLEManagerImpl::_IsAdvertising(void) +{ + return mFlags.Has(Flags::kAdvertising); +} + +} // namespace Internal +} // namespace DeviceLayer +} // namespace chip + +#endif // CHIP_DEVICE_CONFIG_ENABLE_CHIPOBLE diff --git a/src/platform/stm32/BUILD.gn b/src/platform/stm32/BUILD.gn new file mode 100644 index 00000000000000..38290a49e2301d --- /dev/null +++ b/src/platform/stm32/BUILD.gn @@ -0,0 +1,112 @@ +# Copyright (c) 2021 Project CHIP Authors +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +import("//build_overrides/chip.gni") +import("//build_overrides/pigweed.gni") + +import("${chip_root}/src/platform/device.gni") + +import("${chip_root}/build/chip/buildconfig_header.gni") +import("${chip_root}/src/crypto/crypto.gni") + +import("${chip_root}/third_party/st/stm32_board.gni") + +assert(chip_device_platform == "stm32") + +if (chip_crypto == "platform") { + import("//build_overrides/mbedtls.gni") +} +if (chip_enable_openthread) { + import("//build_overrides/openthread.gni") +} + +static_library("stm32") { + if (stm32_board == "STM32WB5MM-DK") { + sources = [ + "../FreeRTOS/SystemTimeSupport.cpp", + "../SingletonConfigurationManager.cpp", + "../logging/impl/stdio/Logging.cpp", + "BLEManagerImpl.cpp", + "BLEManagerImpl.h", + "BlePlatformConfig.h", + "CHIPDevicePlatformConfig.h", + "CHIPDevicePlatformEvent.h", + "CHIPMem-Platform.cpp", + "CHIPPlatformConfig.h", + "ConfigurationManagerImpl.cpp", + "ConfigurationManagerImpl.h", + "DiagnosticDataProviderImpl.cpp", + "DiagnosticDataProviderImpl.h", + "FactoryDataProvider.cpp", + "FactoryDataProvider.h", + "InetPlatformConfig.h", + "KeyValueStoreManagerImpl.cpp", + "KeyValueStoreManagerImpl.h", + "PlatformManagerImpl.cpp", + "PlatformManagerImpl.h", + "STM32Config.cpp", + "STM32Config.h", + "STM32FreeRtosHooks.cpp", + "STM32FreeRtosHooks.h", + "SystemPlatformConfig.h", + ] + } + + deps = [ "${chip_root}/src/setup_payload" ] + public = [ "${chip_root}/src/credentials/DeviceAttestationCredsProvider.h" ] + public_deps = [ + "${chip_root}/src/crypto", + "${chip_root}/src/platform:platform_base", + ] + + if (chip_enable_openthread) { + sources += [ + "../OpenThread/DnssdImpl.cpp", + "../OpenThread/OpenThreadDnssdImpl.cpp", + "../OpenThread/OpenThreadUtils.cpp", + "ConnectivityManagerImpl.cpp", + "ConnectivityManagerImpl.h", + "ThreadStackManagerImpl.cpp", + "ThreadStackManagerImpl.h", + ] + + import("//build_overrides/stm32_sdk.gni") + import("${stm32_sdk_build_root}/stm32_sdk.gni") + public_deps += [ "${stm32_sdk_build_root}:stm32_sdk" ] + + deps += [ "${chip_root}/src/lib/dnssd:platform_header" ] + + public_configs = [ + "${chip_root}/src/lib/address_resolve:default_address_resolve_config", + ] + } + + # Set the compiler flags + cflags = [ + "-Wno-error=unused-parameter", + "-Wno-error=unused-variable", + "-Wno-error=format=", + "-Wno-error=return-type", + ] + + # Add platform crypto implementation + if (chip_crypto == "platform") { + sources += [] + + public_deps += [ + "${chip_root}/src/crypto", + "${mbedtls_root}:mbedtls", + ] + } +} diff --git a/src/platform/stm32/BlePlatformConfig.h b/src/platform/stm32/BlePlatformConfig.h new file mode 100644 index 00000000000000..f75b55d4f85ed8 --- /dev/null +++ b/src/platform/stm32/BlePlatformConfig.h @@ -0,0 +1,38 @@ +/* + * + * Copyright (c) 2020 Project CHIP Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * @file + * Platform-specific configuration overrides for the CHIP BLE + * Layer on stm32wb platforms. + * + */ + +#pragma once + +// ==================== Platform Adaptations ==================== + +#define BLE_CONNECTION_OBJECT uint16_t +#define BLE_CONNECTION_UNINITIALIZED (0xFFFF) +#define BLE_MAX_RECEIVE_WINDOW_SIZE 5 + +#define BLE_CONFIG_ERROR_MIN 6000000 +#define BLE_CONFIG_ERROR_MAX 6000999 + +// ========== Platform-specific Configuration Overrides ========= + +/* none so far */ diff --git a/src/platform/stm32/CHIPDevicePlatformConfig.h b/src/platform/stm32/CHIPDevicePlatformConfig.h new file mode 100644 index 00000000000000..6685bd8464f37b --- /dev/null +++ b/src/platform/stm32/CHIPDevicePlatformConfig.h @@ -0,0 +1,149 @@ +/* + * + * Copyright (c) 2020 Project CHIP Authors + * Copyright (c) 2018 Nest Labs, Inc. + * All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * @file + * Platform-specific configuration overrides for CHIP on + * the STM32 platform. + */ + +#pragma once + +// ==================== General Platform Adaptations ==================== + +#define CHIP_CONFIG_ABORT() abort() + +#define CHIP_CONFIG_ENABLE_TUNNELING 0 +#define CHIP_CONFIG_MAX_TUNNELS 0 +#define CHIP_CONFIG_ENABLE_SERVICE_DIRECTORY 0 + +#define CHIP_CONFIG_PERSISTED_STORAGE_KEY_TYPE uint16_t +#define CHIP_CONFIG_PERSISTED_STORAGE_ENC_MSG_CNTR_ID 1 +#define CHIP_CONFIG_PERSISTED_STORAGE_MAX_KEY_LENGTH 2 + +#define CHIP_CONFIG_LIFETIIME_PERSISTED_COUNTER_KEY 0x01 +#define CHIP_ADDRESS_RESOLVE_IMPL_INCLUDE_HEADER + +#if CHIP_ENABLE_OPENTHREAD +#define CHIP_DEVICE_CONFIG_THREAD_FTD 0 // 0 = MTD +#define CHIP_DEVICE_CONFIG_ENABLE_THREAD 1 +#define CHIP_DEVICE_CONFIG_ENABLE_THREAD_SRP_CLIENT 1 +#define CHIP_DEVICE_CONFIG_ENABLE_THREAD_DNS_CLIENT 1 +#define CHIP_DEVICE_CONFIG_ENABLE_THREAD_COMMISSIONABLE_DISCOVERY 1 +#endif + +// ========== Platform-specific Configuration ========= + +// These are configuration options that are unique to the platform. +// These can be overridden by the application as needed. + +// ... + +// ========== Platform-specific Configuration Overrides ========= + +#define CHIP_DEVICE_CONFIG_CHIP_TASK_NAME "STM32WB TASK" +#define CHIP_DEVICE_CONFIG_CHIP_TASK_STACK_SIZE (8 * 1024) + +/** + * CHIP_DEVICE_CONFIG_CHIP_TASK_PRIORITY + * + * The priority of the chip task. + */ +#define CHIP_DEVICE_CONFIG_CHIP_TASK_PRIORITY 24 +#define CHIP_DEVICE_CONFIG_THREAD_TASK_STACK_SIZE (4 * 1024) + +/** + * CHIP_DEVICE_CONFIG_THREAD_TASK_PRIORITY + * + * The priority of the OpenThread task. + */ +#define CHIP_DEVICE_CONFIG_THREAD_TASK_PRIORITY 24 + +#define CHIP_DEVICE_CONFIG_MAX_EVENT_QUEUE_SIZE 25 + +/** + * CHIP_SYSTEM_CONFIG_PACKETBUFFER_POOL_SIZE + * + * Reduce packet buffer pool size to 8 (default 15) to reduce ram consumption + */ +#define CHIP_SYSTEM_CONFIG_PACKETBUFFER_POOL_SIZE 8 + +#define CHIP_DEVICE_CONFIG_ENABLE_WIFI_TELEMETRY 0 +#define CHIP_DEVICE_CONFIG_ENABLE_THREAD_TELEMETRY 0 +#define CHIP_DEVICE_CONFIG_ENABLE_THREAD_TELEMETRY_FULL 0 + +// Per 5.2.5.2. Commencement Section of CHIP spec, BLE advertisement is +// disabled for Locks and Barrier Access Devices. +#define CHIP_DEVICE_CONFIG_CHIPOBLE_ENABLE_ADVERTISING_AUTOSTART 0 +#define CHIP_DEVICE_CONFIG_ENABLE_PAIRING_AUTOSTART 0 + +/** + * CHIP_DEVICE_CONFIG_BLE_ADVERTISING_INTERVAL_CHANGE_TIME + * + * The amount of time in miliseconds after which BLE advertisement should be switched from the fast + * advertising to the slow advertising, counting from the moment of advertisement commencement. + * + * Defaults to 30000 (30 seconds). + */ +#ifndef CHIP_DEVICE_CONFIG_BLE_ADVERTISING_INTERVAL_CHANGE_TIME +#define CHIP_DEVICE_CONFIG_BLE_ADVERTISING_INTERVAL_CHANGE_TIME 30000 +#endif +// ========== Platform-specific Cluster Overrides ========= +#define CHIP_CLUSTER_NETWORK_COMMISSIONING_MAX_NETWORKS 1 + +// EMBER_AF_OTA_SOFTWARE_UPDATE_PROVIDER_CLUSTER_SERVER_ENDPOINT_COUNT is only defined if the +// cluster is actually enabled in the ZAP config. To allow operation in setups +#define EMBER_AF_OTA_SOFTWARE_UPDATE_PROVIDER_CLUSTER_SERVER_ENDPOINT_COUNT 1 + +/** + * CHIP_DEVICE_CONFIG_ENABLE_CHIP_TIME_SERVICE_TIME_SYNC + * + * Enables synchronizing the device's real time clock with a remote Chip Time service + * using the Chip Time Sync protocol. + */ +#define CHIP_DEVICE_CONFIG_ENABLE_CHIP_TIME_SERVICE_TIME_SYNC 0 + +#define CHIP_SYSTEM_CONFIG_PLATFORM_PROVIDES_TIME 1 + +/** + * @def CHIP_CONFIG_MRP_LOCAL_ACTIVE_RETRY_INTERVAL + * + * @brief + * Active retransmit interval, or time to wait before retransmission after + * subsequent failures in milliseconds. + * + * This is the default value, that might be adjusted by end device depending on its + * needs (e.g. sleeping period) using Service Discovery TXT record CRA key. + * + */ +#define CHIP_CONFIG_MRP_LOCAL_ACTIVE_RETRY_INTERVAL (2000_ms32) + +#define OPENTHREAD_CONFIG_IP6_SLAAC_ENABLE 1 + +/** + * CHIP_DEVICE_CONFIG_ENABLE_CHIPOBLE + * + * Enable support for Chip-over-BLE (CHIPoBLE). + */ +#define CHIP_DEVICE_CONFIG_ENABLE_CHIPOBLE 1 + +#define CHIP_CONFIG_ENABLE_SESSION_RESUMPTION 1 + +#define CHIP_CONFIG_MEMORY_MGMT_PLATFORM 1 +#define CHIP_CONFIG_MEMORY_MGMT_MALLOC 0 diff --git a/src/platform/stm32/CHIPDevicePlatformEvent.h b/src/platform/stm32/CHIPDevicePlatformEvent.h new file mode 100644 index 00000000000000..b77798f92a7d6c --- /dev/null +++ b/src/platform/stm32/CHIPDevicePlatformEvent.h @@ -0,0 +1,76 @@ +/* + * + * Copyright (c) 2021 Project CHIP Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#pragma once + +#include +#include + +namespace chip { +namespace DeviceLayer { +namespace DeviceEventType { +/** + * Enumerates platform-specific event types that are visible to the application. + */ +enum PublicPlatformSpecificEventTypes +{ + /* None currently defined */ +}; + +/** + * Enumerates platform-specific event types that are internal to the chip Device Layer. + */ +enum InternalPlatformSpecificEventTypes +{ + kSTMBLEConnected = kRange_InternalPlatformSpecific, + kSTMBLEDisconnected, + kCHIPoBLECCCWriteEvent, + kCHIPoBLERXCharWriteEvent, + kCHIPoBLETXCharWriteEvent, +}; + +} // namespace DeviceEventType + +/** + * Represents platform-specific event information. + */ +struct ChipDevicePlatformEvent final +{ + // TODO - add platform specific definition extension + union + { + struct + { + uint8_t dummy; + } STMBLEConnected; + struct + { + uint8_t dummy; + } CHIPoBLECCCWriteEvent; + struct + { + uint8_t dummy; + } CHIPoBLERXCharWriteEvent; + struct + { + uint8_t dummy; + } CHIPoBLETXCharWriteEvent; + }; +}; + +} // namespace DeviceLayer +} // namespace chip diff --git a/src/platform/stm32/CHIPMem-Platform.cpp b/src/platform/stm32/CHIPMem-Platform.cpp new file mode 100644 index 00000000000000..2e37bafe7cf1b8 --- /dev/null +++ b/src/platform/stm32/CHIPMem-Platform.cpp @@ -0,0 +1,239 @@ +/* + * + * Copyright (c) 2020 Project CHIP Authors + * Copyright (c) 2019 Nest Labs, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* + * + * Copyright (c) 2020-2021 Project CHIP Authors + * All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * @file + * This file implements heap memory allocation APIs for CHIP. These functions are platform + * specific and might be C Standard Library heap functions re-direction in most of cases. + * + */ + +#include +#include + +#include "cmsis_os.h" +#include "mbedtls/platform.h" +#include "task.h" + +#include +#include +#include +#include + +#if CHIP_CONFIG_MEMORY_MGMT_PLATFORM + +extern "C" void memMonitoringTrackAlloc(void * ptr, size_t size); +extern "C" void memMonitoringTrackFree(void * ptr, size_t size); + +#ifndef trackAlloc +#define trackAlloc(pvAddress, uiSize) memMonitoringTrackAlloc(pvAddress, uiSize) +#endif +#ifndef trackFree +#define trackFree(pvAddress, uiSize) memMonitoringTrackFree(pvAddress, uiSize) +#endif + +#define USE_FREERTOS + +using namespace std; + +// Define the new operator for C++ to use the freeRTOS memory management +// functions. +// +void * operator new(size_t size) +{ + void * p; +#ifdef USE_FREERTOS + if (uxTaskGetNumberOfTasks()) + p = pvPortMalloc(size); + else + p = malloc(size); + +#else + p = malloc(size); + +#endif +#ifdef __EXCEPTIONS + if (p == 0) // did pvPortMalloc succeed? + throw std::bad_alloc(); // ANSI/ISO compliant behavior +#endif + return p; +} + +// +// Define the delete operator for C++ to use the freeRTOS memory +// functions. +// +void operator delete(void * p) +{ +#ifdef USE_FREERTOS + if (uxTaskGetNumberOfTasks()) + vPortFree(p); + else + free(p); +#else + free(p); +#endif + p = NULL; +} + +void * operator new[](size_t size) +{ + void * p; +#ifdef USE_FREERTOS + if (uxTaskGetNumberOfTasks()) + p = pvPortMalloc(size); + else + p = malloc(size); + +#else + p = malloc(size); + +#endif +#ifdef __EXCEPTIONS + if (p == 0) // did pvPortMalloc succeed? + throw std::bad_alloc(); // ANSI/ISO compliant behavior +#endif + return p; +} + +// +// Define the delete operator for C++ to use the freeRTOS memory +// functions. THIS IS NOT OPTIONAL! +// +void operator delete[](void * p) +{ +#ifdef USE_FREERTOS + if (uxTaskGetNumberOfTasks()) + vPortFree(p); + else + free(p); +#else + free(p); +#endif + p = NULL; +} + +namespace chip { +namespace Platform { + +#define VERIFY_INITIALIZED() VerifyInitialized(__func__) + +static std::atomic_int memoryInitialized{ 0 }; + +static void VerifyInitialized(const char * func) +{ + if (!memoryInitialized) + { + ChipLogError(DeviceLayer, "ABORT: chip::Platform::%s() called before chip::Platform::MemoryInit()\n", func); + abort(); + } +} + +CHIP_ERROR MemoryAllocatorInit(void * buf, size_t bufSize) +{ + if (memoryInitialized++ > 0) + { + ChipLogError(DeviceLayer, "ABORT: chip::Platform::MemoryInit() called twice.\n"); + abort(); + } + + return CHIP_NO_ERROR; +} + +void MemoryAllocatorShutdown() +{ + if (--memoryInitialized < 0) + { + ChipLogError(DeviceLayer, "ABORT: chip::Platform::MemoryShutdown() called twice.\n"); + abort(); + } +} + +void * MemoryAlloc(size_t size) +{ + void * ptr; + VERIFY_INITIALIZED(); + ptr = mbedtls_calloc(1, size); + trackAlloc(ptr, size); + return ptr; +} + +void * MemoryAlloc(size_t size, bool isLongTermAlloc) +{ + void * ptr; + VERIFY_INITIALIZED(); + ptr = mbedtls_calloc(1, size); + trackAlloc(ptr, size); + return ptr; +} + +void * MemoryCalloc(size_t num, size_t size) +{ + VERIFY_INITIALIZED(); + + void * ptr = mbedtls_calloc(1, size); + trackAlloc(ptr, size * num); + return ptr; +} + +void * MemoryRealloc(void * p, size_t size) +{ + VERIFY_INITIALIZED(); + + p = realloc(p, size); + return p; +} + +void MemoryFree(void * p) +{ + VERIFY_INITIALIZED(); + mbedtls_free(p); + trackFree(p, 0); +} + +bool MemoryInternalCheckPointer(const void * p, size_t min_size) +{ + return (p != nullptr); +} + +} // namespace Platform +} // namespace chip + +extern "C" void memMonitoringTrackAlloc(void * ptr, size_t size) {} + +extern "C" void memMonitoringTrackFree(void * ptr, size_t size) {} + +#endif // CHIP_CONFIG_MEMORY_MGMT_PLATFORM diff --git a/src/platform/stm32/CHIPPlatformConfig.h b/src/platform/stm32/CHIPPlatformConfig.h new file mode 100644 index 00000000000000..4db0ba07aa7d9b --- /dev/null +++ b/src/platform/stm32/CHIPPlatformConfig.h @@ -0,0 +1,81 @@ +/* + * + * Copyright (c) 2020 Project CHIP Authors + * Copyright (c) 2018 Nest Labs, Inc. + * All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * @file + * Platform-specific configuration overrides for CHIP on + * the STM32 platform. + */ + +#pragma once +#include "CHIPDevicePlatformConfig.h" +// ==================== General Configuration Overrides ==================== + +#ifndef CHIP_CONFIG_MAX_UNSOLICITED_MESSAGE_HANDLERS +#define CHIP_CONFIG_MAX_UNSOLICITED_MESSAGE_HANDLERS 8 +#endif // CHIP_CONFIG_MAX_UNSOLICITED_MESSAGE_HANDLERS + +#ifndef CHIP_CONFIG_MAX_EXCHANGE_CONTEXTS +#define CHIP_CONFIG_MAX_EXCHANGE_CONTEXTS 8 +#endif // CHIP_CONFIG_MAX_EXCHANGE_CONTEXTS + +#ifndef CHIP_CONFIG_WRMP_TIMER_DEFAULT_PERIOD +#define CHIP_CONFIG_WRMP_TIMER_DEFAULT_PERIOD 50 +#endif // CHIP_CONFIG_WRMP_TIMER_DEFAULT_PERIOD + +#ifndef CHIP_LOG_FILTERING +#define CHIP_LOG_FILTERING 0 +#endif // CHIP_LOG_FILTERING + +#ifndef CHIP_CONFIG_MAX_PEER_NODES +#define CHIP_CONFIG_MAX_PEER_NODES 16 +#endif // CHIP_CONFIG_MAX_PEER_NODES + +#ifndef CHIP_CONFIG_BDX_MAX_NUM_TRANSFERS +#define CHIP_CONFIG_BDX_MAX_NUM_TRANSFERS 1 +#endif // CHIP_CONFIG_BDX_MAX_NUM_TRANSFERS + +#ifndef CHIP_CONFIG_MAX_FABRICS +#define CHIP_CONFIG_MAX_FABRICS 5 +#endif // CHIP_CONFIG_MAX_FABRICS + +#ifndef CHIP_CONFIG_MAX_ACTIVE_CHANNELS +#define CHIP_CONFIG_MAX_ACTIVE_CHANNELS 8 +#endif // CHIP_CONFIG_MAX_ACTIVE_CHANNELS + +#ifndef CHIP_CONFIG_MAX_CHANNEL_HANDLES +#define CHIP_CONFIG_MAX_CHANNEL_HANDLES 16 +#endif // CHIP_CONFIG_MAX_CHANNEL_HANDLES + +#ifndef CHIP_CONFIG_RMP_TIMER_DEFAULT_PERIOD_SHIFT +#define CHIP_CONFIG_RMP_TIMER_DEFAULT_PERIOD_SHIFT 6 +#endif // CHIP_CONFIG_RMP_TIMER_DEFAULT_PERIOD_SHIFT +// ==================== Security Configuration Overrides ==================== + +#ifndef CHIP_CONFIG_FREERTOS_USE_STATIC_QUEUE +#define CHIP_CONFIG_FREERTOS_USE_STATIC_QUEUE 1 +#endif + +#ifndef CHIP_CONFIG_FREERTOS_USE_STATIC_TASK +#define CHIP_CONFIG_FREERTOS_USE_STATIC_TASK 1 +#endif + +#ifndef CHIP_CONFIG_FREERTOS_USE_STATIC_SEMAPHORE +#define CHIP_CONFIG_FREERTOS_USE_STATIC_SEMAPHORE 1 +#endif diff --git a/src/platform/stm32/ConfigurationManagerImpl.cpp b/src/platform/stm32/ConfigurationManagerImpl.cpp new file mode 100644 index 00000000000000..da8638460a78f3 --- /dev/null +++ b/src/platform/stm32/ConfigurationManagerImpl.cpp @@ -0,0 +1,168 @@ +/* + * + * Copyright (c) 2020 Project CHIP Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * @file + * Provides the implementation of the Device Layer ConfigurationManager object + * for stm32wb platforms. + */ +/* this file behaves like a config.h, comes first */ +#include + +#include +#include +#include + +#include +#include + +#if CHIP_DEVICE_CONFIG_ENABLE_FACTORY_PROVISIONING +#include +#endif // CHIP_DEVICE_CONFIG_ENABLE_FACTORY_PROVISIONING + +#include +#include + +namespace chip { +namespace DeviceLayer { + +using namespace ::chip::DeviceLayer::Internal; + +ConfigurationManagerImpl & ConfigurationManagerImpl::GetDefaultInstance() +{ + static ConfigurationManagerImpl sInstance; + return sInstance; +} + +CHIP_ERROR ConfigurationManagerImpl::Init() +{ + CHIP_ERROR err; + + // Initialize the generic implementation base class. + err = Internal::GenericConfigurationManagerImpl::Init(); + + return err; +} + +bool ConfigurationManagerImpl::CanFactoryReset() +{ + // TODO: query the application to determine if factory reset is allowed. + return true; +} + +void ConfigurationManagerImpl::InitiateFactoryReset() +{ + PlatformMgr().ScheduleWork(DoFactoryReset); +} + +CHIP_ERROR ConfigurationManagerImpl::ReadPersistedStorageValue(::chip::Platform::PersistedStorage::Key persistedStorageKey, + uint32_t & value) +{ + CHIP_ERROR err = CHIP_NO_ERROR; + ChipLogDetail(DataManagement, "ST => ReadPersistedStorageValue"); + + err = ReadConfigValue(persistedStorageKey, value); + if (err == CHIP_DEVICE_ERROR_CONFIG_NOT_FOUND) + { + err = CHIP_ERROR_PERSISTED_STORAGE_VALUE_NOT_FOUND; + } + SuccessOrExit(err); + +exit: + return err; +} + +CHIP_ERROR ConfigurationManagerImpl::WritePersistedStorageValue(::chip::Platform::PersistedStorage::Key persistedStorageKey, + uint32_t value) +{ + CHIP_ERROR err = CHIP_NO_ERROR; + ChipLogDetail(DataManagement, "ST => WritePersistedStorageValue"); + err = WriteConfigValue(persistedStorageKey, value); + SuccessOrExit(err); +exit: + return err; +} + +CHIP_ERROR ConfigurationManagerImpl::ReadConfigValue(Key key, bool & val) +{ + return STM32Config::ReadConfigValue(key, val); +} + +CHIP_ERROR ConfigurationManagerImpl::ReadConfigValue(Key key, uint32_t & val) +{ + return STM32Config::ReadConfigValue(key, val); +} + +CHIP_ERROR ConfigurationManagerImpl::ReadConfigValue(Key key, uint64_t & val) +{ + return STM32Config::ReadConfigValue(key, val); +} + +CHIP_ERROR ConfigurationManagerImpl::ReadConfigValueStr(Key key, char * buf, size_t bufSize, size_t & outLen) +{ + return STM32Config::ReadConfigValueStr(key, buf, bufSize, outLen); +} + +CHIP_ERROR ConfigurationManagerImpl::ReadConfigValueBin(Key key, uint8_t * buf, size_t bufSize, size_t & outLen) +{ + return STM32Config::ReadConfigValueBin(key, buf, bufSize, outLen); +} + +CHIP_ERROR ConfigurationManagerImpl::WriteConfigValue(Key key, bool val) +{ + return STM32Config::WriteConfigValue(key, val); +} + +CHIP_ERROR ConfigurationManagerImpl::WriteConfigValue(Key key, uint32_t val) +{ + return STM32Config::WriteConfigValue(key, val); +} + +CHIP_ERROR ConfigurationManagerImpl::WriteConfigValue(Key key, uint64_t val) +{ + return STM32Config::WriteConfigValue(key, val); +} + +CHIP_ERROR ConfigurationManagerImpl::WriteConfigValueStr(Key key, const char * str) +{ + return STM32Config::WriteConfigValueStr(key, str); +} + +CHIP_ERROR ConfigurationManagerImpl::WriteConfigValueStr(Key key, const char * str, size_t strLen) +{ + return STM32Config::WriteConfigValueStr(key, str, strLen); +} + +CHIP_ERROR ConfigurationManagerImpl::WriteConfigValueBin(Key key, const uint8_t * data, size_t dataLen) +{ + return STM32Config::WriteConfigValueBin(key, data, dataLen); +} + +void ConfigurationManagerImpl::RunConfigUnitTest(void) +{ + STM32Config::RunConfigUnitTest(); +} + +void ConfigurationManagerImpl::DoFactoryReset(intptr_t arg) {} + +ConfigurationManager & ConfigurationMgrImpl() +{ + return ConfigurationManagerImpl::GetDefaultInstance(); +} + +} // namespace DeviceLayer +} // namespace chip diff --git a/src/platform/stm32/ConfigurationManagerImpl.h b/src/platform/stm32/ConfigurationManagerImpl.h new file mode 100644 index 00000000000000..78b885581ce151 --- /dev/null +++ b/src/platform/stm32/ConfigurationManagerImpl.h @@ -0,0 +1,89 @@ +/* + * + * Copyright (c) 2020 Project CHIP Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * @file + * Provides an implementation of the ConfigurationManager object + * for stm32wb platforms. + */ + +#pragma once +#include +#include +#include + +namespace chip { +namespace DeviceLayer { + +/** + * Concrete implementation of the ConfigurationManager singleton object for the platform. + */ + +// class ConfigurationManagerImpl final : public Internal::GenericConfigurationManagerImpl, +// public Internal::STM32Config +class ConfigurationManagerImpl : public Internal::GenericConfigurationManagerImpl +{ +public: + // This returns an instance of this class. + static ConfigurationManagerImpl & GetDefaultInstance(); + +private: + // ===== Members that implement the ConfigurationManager public interface. + + CHIP_ERROR Init(void) override; + CHIP_ERROR GetPrimaryWiFiMACAddress(uint8_t * buf) override; + bool CanFactoryReset(void) override; + void InitiateFactoryReset(void) override; + CHIP_ERROR ReadPersistedStorageValue(::chip::Platform::PersistedStorage::Key key, uint32_t & value) override; + CHIP_ERROR WritePersistedStorageValue(::chip::Platform::PersistedStorage::Key key, uint32_t value) override; + + // NOTE: Other public interface methods are implemented by GenericConfigurationManagerImpl<>. + + // ===== Members that implement the GenericConfigurationManagerImpl protected interface. + CHIP_ERROR ReadConfigValue(Key key, bool & val) override; + CHIP_ERROR ReadConfigValue(Key key, uint32_t & val) override; + CHIP_ERROR ReadConfigValue(Key key, uint64_t & val) override; + CHIP_ERROR ReadConfigValueStr(Key key, char * buf, size_t bufSize, size_t & outLen) override; + CHIP_ERROR ReadConfigValueBin(Key key, uint8_t * buf, size_t bufSize, size_t & outLen) override; + CHIP_ERROR WriteConfigValue(Key key, bool val) override; + CHIP_ERROR WriteConfigValue(Key key, uint32_t val) override; + CHIP_ERROR WriteConfigValue(Key key, uint64_t val) override; + CHIP_ERROR WriteConfigValueStr(Key key, const char * str) override; + CHIP_ERROR WriteConfigValueStr(Key key, const char * str, size_t strLen) override; + CHIP_ERROR WriteConfigValueBin(Key key, const uint8_t * data, size_t dataLen) override; + void RunConfigUnitTest(void) override; + + // ===== Private members reserved for use by this class only. + + static void DoFactoryReset(intptr_t arg); +}; + +inline CHIP_ERROR ConfigurationManagerImpl::GetPrimaryWiFiMACAddress(uint8_t * buf) +{ + return CHIP_ERROR_UNSUPPORTED_CHIP_FEATURE; +} + +/** + * Returns the platform-specific implementation of the ConfigurationManager object. + * + * Applications can use this to gain access to features of the ConfigurationManager + * that are specific to the selected platform. + */ +ConfigurationManager & ConfigurationMgrImpl(); + +} // namespace DeviceLayer +} // namespace chip diff --git a/src/platform/stm32/ConnectivityManagerImpl.cpp b/src/platform/stm32/ConnectivityManagerImpl.cpp new file mode 100644 index 00000000000000..0a3f507a999532 --- /dev/null +++ b/src/platform/stm32/ConnectivityManagerImpl.cpp @@ -0,0 +1,72 @@ +/* + * + * Copyright (c) 2020 Project CHIP Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/* this file behaves like a config.h, comes first */ +#include + +#include + +#if INET_CONFIG_ENABLE_TCP_ENDPOINT +#include +#endif + +#if CHIP_DEVICE_CONFIG_ENABLE_CHIPOBLE +#include +#endif + +#if CHIP_DEVICE_CONFIG_ENABLE_THREAD +#include +#endif + +#include +#include +#include +#include + +using namespace ::chip; +using namespace ::chip::TLV; +using namespace ::chip::DeviceLayer::Internal; + +namespace chip { +namespace DeviceLayer { + +ConnectivityManagerImpl ConnectivityManagerImpl::sInstance; + +CHIP_ERROR ConnectivityManagerImpl::_Init() +{ + CHIP_ERROR err = CHIP_NO_ERROR; + + // Initialize the generic base classes that require it. +#if CHIP_DEVICE_CONFIG_ENABLE_THREAD + GenericConnectivityManagerImpl_Thread::_Init(); +#endif + + SuccessOrExit(err); + +exit: + return err; +} + +void ConnectivityManagerImpl::_OnPlatformEvent(const ChipDeviceEvent * event) +{ + // Forward the event to the generic base classes as needed. +#if CHIP_DEVICE_CONFIG_ENABLE_THREAD + GenericConnectivityManagerImpl_Thread::_OnPlatformEvent(event); +#endif +} + +} // namespace DeviceLayer +} // namespace chip diff --git a/src/platform/stm32/ConnectivityManagerImpl.h b/src/platform/stm32/ConnectivityManagerImpl.h new file mode 100644 index 00000000000000..f95110bb9c6af6 --- /dev/null +++ b/src/platform/stm32/ConnectivityManagerImpl.h @@ -0,0 +1,109 @@ +/* + * + * Copyright (c) 2020 Project CHIP Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#pragma once + +#include +#include +#include +#if INET_CONFIG_ENABLE_TCP_ENDPOINT +#include +#endif +#if CHIP_DEVICE_CONFIG_ENABLE_CHIPOBLE +#include +#else +#include +#endif +#if CHIP_DEVICE_CONFIG_ENABLE_THREAD +#include +#else +#include +#endif +#include + +namespace chip { +namespace Inet { +class IPAddress; +} // namespace Inet +} // namespace chip + +namespace chip { +namespace DeviceLayer { + +/** + * Concrete implementation of the ConnectivityManager singleton object for stm32 platforms. + */ +class ConnectivityManagerImpl final : public ConnectivityManager, + public Internal::GenericConnectivityManagerImpl, + public Internal::GenericConnectivityManagerImpl_UDP, +#if INET_CONFIG_ENABLE_TCP_ENDPOINT + public Internal::GenericConnectivityManagerImpl_TCP, +#endif +#if CHIP_DEVICE_CONFIG_ENABLE_CHIPOBLE + public Internal::GenericConnectivityManagerImpl_BLE, +#else + public Internal::GenericConnectivityManagerImpl_NoBLE, +#endif +#if CHIP_DEVICE_CONFIG_ENABLE_THREAD + public Internal::GenericConnectivityManagerImpl_Thread, +#else + public Internal::GenericConnectivityManagerImpl_NoThread, +#endif + public Internal::GenericConnectivityManagerImpl_NoWiFi +{ + // Allow the ConnectivityManager interface class to delegate method calls to + // the implementation methods provided by this class. + friend class ConnectivityManager; + +private: + // ===== Members that implement the ConnectivityManager abstract interface. + + CHIP_ERROR _Init(void); + void _OnPlatformEvent(const ChipDeviceEvent * event); + + // ===== Members for internal use by the following friends. + + friend ConnectivityManager & ConnectivityMgr(void); + friend ConnectivityManagerImpl & ConnectivityMgrImpl(void); + + static ConnectivityManagerImpl sInstance; +}; + +/** + * Returns the public interface of the ConnectivityManager singleton object. + * + * Chip applications should use this to access features of the ConnectivityManager object + * that are common to all platforms. + */ +inline ConnectivityManager & ConnectivityMgr(void) +{ + return ConnectivityManagerImpl::sInstance; +} + +/** + * Returns the platform-specific implementation of the ConnectivityManager singleton object. + * + * Chip applications can use this to gain access to features of the ConnectivityManager + * that are specific to the stm32 platform. + */ +inline ConnectivityManagerImpl & ConnectivityMgrImpl(void) +{ + return ConnectivityManagerImpl::sInstance; +} + +} // namespace DeviceLayer +} // namespace chip diff --git a/src/platform/stm32/DiagnosticDataProviderImpl.cpp b/src/platform/stm32/DiagnosticDataProviderImpl.cpp new file mode 100644 index 00000000000000..0c4a78efbc98d4 --- /dev/null +++ b/src/platform/stm32/DiagnosticDataProviderImpl.cpp @@ -0,0 +1,63 @@ +/* + * + * Copyright (c) 2021 Project CHIP Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * @file + * Provides an implementation of the DiagnosticDataProvider object + * for stm32 platforms. + */ + +#include + +#include +#include +#include + +namespace chip { +namespace DeviceLayer { + +DiagnosticDataProviderImpl & DiagnosticDataProviderImpl::GetDefaultInstance() +{ + static DiagnosticDataProviderImpl sInstance; + return sInstance; +} + +CHIP_ERROR DiagnosticDataProviderImpl::GetCurrentHeapFree(uint64_t & currentHeapFree) +{ + + return CHIP_ERROR_UNSUPPORTED_CHIP_FEATURE; +} + +CHIP_ERROR DiagnosticDataProviderImpl::GetCurrentHeapUsed(uint64_t & currentHeapUsed) +{ + + return CHIP_ERROR_UNSUPPORTED_CHIP_FEATURE; +} + +CHIP_ERROR DiagnosticDataProviderImpl::GetCurrentHeapHighWatermark(uint64_t & currentHeapHighWatermark) +{ + + return CHIP_ERROR_UNSUPPORTED_CHIP_FEATURE; +} + +DiagnosticDataProvider & GetDiagnosticDataProviderImpl() +{ + return DiagnosticDataProviderImpl::GetDefaultInstance(); +} + +} // namespace DeviceLayer +} // namespace chip diff --git a/src/platform/stm32/DiagnosticDataProviderImpl.h b/src/platform/stm32/DiagnosticDataProviderImpl.h new file mode 100644 index 00000000000000..85ac3fc206f8ae --- /dev/null +++ b/src/platform/stm32/DiagnosticDataProviderImpl.h @@ -0,0 +1,55 @@ +/* + * + * Copyright (c) 2021 Project CHIP Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * @file + * Provides an implementation of the DiagnosticDataProvider object. + */ + +#pragma once + +#include + +#include + +namespace chip { +namespace DeviceLayer { + +/** + * Concrete implementation of the PlatformManager singleton object for stm32 platforms. + */ + +class DiagnosticDataProviderImpl : public DiagnosticDataProvider +{ +public: + static DiagnosticDataProviderImpl & GetDefaultInstance(); + + // ===== Methods that implement the PlatformManager abstract interface. + + CHIP_ERROR GetCurrentHeapFree(uint64_t & currentHeapFree) override; + CHIP_ERROR GetCurrentHeapUsed(uint64_t & currentHeapUsed) override; + CHIP_ERROR GetCurrentHeapHighWatermark(uint64_t & currentHeapHighWatermark) override; +}; +/** + * Returns the platform-specific implementation of the DiagnosticDataProvider singleton object. + * + * Applications can use this to gain access to features of the DiagnosticDataProvider + * that are specific to the selected platform. + */ +DiagnosticDataProvider & GetDiagnosticDataProviderImpl(); +} // namespace DeviceLayer +} // namespace chip diff --git a/src/platform/stm32/FactoryDataProvider.cpp b/src/platform/stm32/FactoryDataProvider.cpp new file mode 100644 index 00000000000000..06801c32f4076a --- /dev/null +++ b/src/platform/stm32/FactoryDataProvider.cpp @@ -0,0 +1,394 @@ +/* + * + * Copyright (c) 2022 Project CHIP Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "FactoryDataProvider.h" + +#include +#include +#include +#include +#include + +namespace chip { +namespace { + +} // namespace + +namespace DeviceLayer { + +CHIP_ERROR FactoryDataProvider::Init() +{ + return CHIP_NO_ERROR; +} + +FactoryDataProvider & FactoryDataProvider::GetDefaultInstance() +{ + static FactoryDataProvider sInstance; + return sInstance; +} + +CHIP_ERROR FactoryDataProvider::SetSetupPasscode(uint32_t setupPasscode) +{ + return CHIP_ERROR_UNSUPPORTED_CHIP_FEATURE; +} + +CHIP_ERROR FactoryDataProvider::SetSetupDiscriminator(uint16_t setupDiscriminator) +{ + return CHIP_ERROR_UNSUPPORTED_CHIP_FEATURE; +} + +// TODO: This should be moved to a method of P256Keypair +CHIP_ERROR LoadKeypairFromRaw(ByteSpan private_key, ByteSpan public_key, Crypto::P256Keypair & keypair) +{ + Crypto::P256SerializedKeypair serialized_keypair; + ReturnErrorOnFailure(serialized_keypair.SetLength(private_key.size() + public_key.size())); + memcpy(serialized_keypair.Bytes(), public_key.data(), public_key.size()); + memcpy(serialized_keypair.Bytes() + public_key.size(), private_key.data(), private_key.size()); + return keypair.Deserialize(serialized_keypair); +} + +CHIP_ERROR FactoryDataProvider::SignWithDeviceAttestationKey(const ByteSpan & messageToSign, MutableByteSpan & outSignBuffer) +{ +#if !CONFIG_STM32_FACTORY_DATA_ENABLE + Crypto::P256ECDSASignature signature; + Crypto::P256Keypair keypair; + + const uint8_t kDevelopmentDAC_PublicKey_FFF1_8004[65] = { + 0x04, 0x50, 0x41, 0x38, 0xef, 0x31, 0xc9, 0xdd, 0x16, 0x0e, 0xb4, 0x6c, 0x6c, 0x17, 0x11, 0x4f, 0x9d, + 0x72, 0x88, 0x40, 0x80, 0x1f, 0x73, 0xbb, 0x9b, 0x5a, 0x2c, 0x51, 0x91, 0xc9, 0xb2, 0x06, 0x63, 0x01, + 0x9d, 0x94, 0x76, 0xd1, 0x93, 0x1b, 0x93, 0xff, 0x47, 0xf4, 0x32, 0x56, 0x37, 0x90, 0x35, 0xd2, 0x29, + 0x62, 0x0b, 0x7e, 0x21, 0x0e, 0x59, 0x2f, 0x26, 0x43, 0x7d, 0x2d, 0x57, 0x62, 0x05, + }; + const uint8_t kDevelopmentDAC_PrivateKey_FFF1_8004[32] = { + 0x82, 0x0a, 0x24, 0x2a, 0x03, 0x0e, 0xbc, 0xe1, 0x1f, 0x38, 0x73, 0x5a, 0xcf, 0x1a, 0x6f, 0x37, + 0xc3, 0xad, 0xa6, 0xe4, 0x32, 0xd2, 0x47, 0x0a, 0x8a, 0x41, 0x37, 0x43, 0xf8, 0x95, 0x63, 0xf3, + }; + ByteSpan kDacPrivateKey = ByteSpan(kDevelopmentDAC_PrivateKey_FFF1_8004); + ByteSpan kDacPublicKey = ByteSpan(kDevelopmentDAC_PublicKey_FFF1_8004); + + VerifyOrReturnError(IsSpanUsable(outSignBuffer), CHIP_ERROR_INVALID_ARGUMENT); + VerifyOrReturnError(IsSpanUsable(messageToSign), CHIP_ERROR_INVALID_ARGUMENT); + VerifyOrReturnError(outSignBuffer.size() >= signature.Capacity(), CHIP_ERROR_BUFFER_TOO_SMALL); + + // In a non-exemplary implementation, the public key is not needed here. It is used here merely because + // Crypto::P256Keypair is only (currently) constructable from raw keys if both private/public keys are present. + ReturnErrorOnFailure(LoadKeypairFromRaw(kDacPrivateKey, kDacPublicKey, keypair)); + ReturnErrorOnFailure(keypair.ECDSA_sign_msg(messageToSign.data(), messageToSign.size(), signature)); + + return CopySpanToMutableSpan(ByteSpan{ signature.ConstBytes(), signature.Length() }, outSignBuffer); +#else + return CHIP_ERROR_UNSUPPORTED_CHIP_FEATURE; +#endif +} + +CHIP_ERROR FactoryDataProvider::GetSetupDiscriminator(uint16_t & setupDiscriminator) +{ +#if !CONFIG_STM32_FACTORY_DATA_ENABLE + setupDiscriminator = CHIP_DEVICE_CONFIG_USE_TEST_SETUP_DISCRIMINATOR; + return CHIP_NO_ERROR; +#else + return CHIP_ERROR_UNSUPPORTED_CHIP_FEATURE; +#endif +} + +CHIP_ERROR FactoryDataProvider::GetSpake2pIterationCount(uint32_t & iterationCount) +{ +#if !CONFIG_STM32_FACTORY_DATA_ENABLE + constexpr uint32_t kDefaultTestVerifierIterationCount = 1000; + iterationCount = kDefaultTestVerifierIterationCount; + return CHIP_NO_ERROR; +#else + return CHIP_ERROR_UNSUPPORTED_CHIP_FEATURE; +#endif +} + +CHIP_ERROR FactoryDataProvider::GetSetupPasscode(uint32_t & setupPasscode) +{ +#if !CONFIG_STM32_FACTORY_DATA_ENABLE + setupPasscode = CHIP_DEVICE_CONFIG_USE_TEST_SETUP_PIN_CODE; + return CHIP_NO_ERROR; +#else + return CHIP_ERROR_UNSUPPORTED_CHIP_FEATURE; +#endif +} + +CHIP_ERROR FactoryDataProvider::GetVendorId(uint16_t & vendorId) +{ +#if !CONFIG_STM32_FACTORY_DATA_ENABLE + vendorId = CHIP_DEVICE_CONFIG_DEVICE_VENDOR_ID; + return CHIP_NO_ERROR; +#else + return CHIP_ERROR_UNSUPPORTED_CHIP_FEATURE; +#endif +} + +CHIP_ERROR FactoryDataProvider::GetProductId(uint16_t & productId) +{ +#if !CONFIG_STM32_FACTORY_DATA_ENABLE + productId = CHIP_DEVICE_CONFIG_DEVICE_PRODUCT_ID; + return CHIP_NO_ERROR; +#else + return CHIP_ERROR_UNSUPPORTED_CHIP_FEATURE; +#endif +} + +CHIP_ERROR FactoryDataProvider::GetHardwareVersion(uint16_t & hardwareVersion) +{ +#if !CONFIG_STM32_FACTORY_DATA_ENABLE + hardwareVersion = CHIP_DEVICE_CONFIG_DEVICE_HARDWARE_VERSION; + return CHIP_NO_ERROR; +#else + return CHIP_ERROR_UNSUPPORTED_CHIP_FEATURE; +#endif +} + +CHIP_ERROR FactoryDataProvider::GetManufacturingDate(uint16_t & year, uint8_t & month, uint8_t & day) +{ + return CHIP_ERROR_UNSUPPORTED_CHIP_FEATURE; +} + +CHIP_ERROR FactoryDataProvider::GetPartNumber(char * buf, size_t bufSize) +{ + return CHIP_ERROR_UNSUPPORTED_CHIP_FEATURE; +} + +CHIP_ERROR FactoryDataProvider::GetProductURL(char * buf, size_t bufSize) +{ + return CHIP_ERROR_UNSUPPORTED_CHIP_FEATURE; +} + +CHIP_ERROR FactoryDataProvider::GetProductLabel(char * buf, size_t bufSize) +{ + return CHIP_ERROR_UNSUPPORTED_CHIP_FEATURE; +} + +CHIP_ERROR FactoryDataProvider::GetVendorName(char * buf, size_t bufSize) +{ + return CHIP_ERROR_UNSUPPORTED_CHIP_FEATURE; +} + +CHIP_ERROR FactoryDataProvider::GetProductName(char * buf, size_t bufSize) +{ + return CHIP_ERROR_UNSUPPORTED_CHIP_FEATURE; +} + +CHIP_ERROR FactoryDataProvider::GetSerialNumber(char * buf, size_t bufSize) +{ +#if !CONFIG_STM32_FACTORY_DATA_ENABLE + memcpy(buf, CHIP_DEVICE_CONFIG_TEST_SERIAL_NUMBER, bufSize); + return CHIP_NO_ERROR; +#else + return CHIP_ERROR_UNSUPPORTED_CHIP_FEATURE; +#endif +} + +CHIP_ERROR FactoryDataProvider::GetHardwareVersionString(char * buf, size_t bufSize) +{ + return CHIP_ERROR_UNSUPPORTED_CHIP_FEATURE; +} + +CHIP_ERROR FactoryDataProvider::GetSpake2pVerifier(MutableByteSpan & verifierSpan, size_t & verifierLen) +{ +#if !CONFIG_STM32_FACTORY_DATA_ENABLE + static const uint8_t kDefaultTestVerifier[97] = { + 0xb9, 0x61, 0x70, 0xaa, 0xe8, 0x03, 0x34, 0x68, 0x84, 0x72, 0x4f, 0xe9, 0xa3, 0xb2, 0x87, 0xc3, 0x03, 0x30, 0xc2, 0xa6, + 0x60, 0x37, 0x5d, 0x17, 0xbb, 0x20, 0x5a, 0x8c, 0xf1, 0xae, 0xcb, 0x35, 0x04, 0x57, 0xf8, 0xab, 0x79, 0xee, 0x25, 0x3a, + 0xb6, 0xa8, 0xe4, 0x6b, 0xb0, 0x9e, 0x54, 0x3a, 0xe4, 0x22, 0x73, 0x6d, 0xe5, 0x01, 0xe3, 0xdb, 0x37, 0xd4, 0x41, 0xfe, + 0x34, 0x49, 0x20, 0xd0, 0x95, 0x48, 0xe4, 0xc1, 0x82, 0x40, 0x63, 0x0c, 0x4f, 0xf4, 0x91, 0x3c, 0x53, 0x51, 0x38, 0x39, + 0xb7, 0xc0, 0x7f, 0xcc, 0x06, 0x27, 0xa1, 0xb8, 0x57, 0x3a, 0x14, 0x9f, 0xcd, 0x1f, 0xa4, 0x66, 0xcf, + }; + + verifierLen = sizeof(kDefaultTestVerifier); + if (verifierSpan.size() < verifierLen) + { + return CHIP_ERROR_BUFFER_TOO_SMALL; + } + memcpy(verifierSpan.data(), &kDefaultTestVerifier[0], verifierLen); + verifierSpan.reduce_size(verifierLen); + return CHIP_NO_ERROR; +#else + return CHIP_ERROR_UNSUPPORTED_CHIP_FEATURE; +#endif +} + +CHIP_ERROR FactoryDataProvider::GetCertificationDeclaration(MutableByteSpan & outBufferSpan) +{ + +#if !CONFIG_STM32_FACTORY_DATA_ENABLE + //-> format_version = 1 + //-> vendor_id = 0xFFF1 + //-> product_id_array = [ 0x8000, 0x8001, 0x8002, 0x8003, 0x8004, 0x8005, 0x8006, 0x8007, 0x8008, 0x8009, 0x800A, 0x800B, + // 0x800C, 0x800D, 0x800E, 0x800F, 0x8010, 0x8011, 0x8012, 0x8013, 0x8014, 0x8015, 0x8016, 0x8017, 0x8018, 0x8019, 0x801A, + // 0x801B, 0x801C, 0x801D, 0x801E, 0x801F, 0x8020, 0x8021, 0x8022, 0x8023, 0x8024, 0x8025, 0x8026, 0x8027, 0x8028, 0x8029, + // 0x802A, 0x802B, 0x802C, 0x802D, 0x802E, 0x802F, 0x8030, 0x8031, 0x8032, 0x8033, 0x8034, 0x8035, 0x8036, 0x8037, 0x8038, + // 0x8039, 0x803A, 0x803B, 0x803C, 0x803D, 0x803E, 0x803F, 0x8040, 0x8041, 0x8042, 0x8043, 0x8044, 0x8045, 0x8046, 0x8047, + // 0x8048, 0x8049, 0x804A, 0x804B, 0x804C, 0x804D, 0x804E, 0x804F, 0x8050, 0x8051, 0x8052, 0x8053, 0x8054, 0x8055, 0x8056, + // 0x8057, 0x8058, 0x8059, 0x805A, 0x805B, 0x805C, 0x805D, 0x805E, 0x805F, 0x8060, 0x8061, 0x8062, 0x8063 ] + //-> device_type_id = 0x0016 + //-> certificate_id = "CSA00000SWC00000-00" + //-> security_level = 0 + //-> security_information = 0 + //-> version_number = 1 + //-> certification_type = 0 + //-> dac_origin_vendor_id is not present + //-> dac_origin_product_id is not present + static const uint8_t kCdForAllExamples[539] = { + 0x30, 0x82, 0x02, 0x17, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x07, 0x02, 0xa0, 0x82, 0x02, 0x08, 0x30, + 0x82, 0x02, 0x04, 0x02, 0x01, 0x03, 0x31, 0x0d, 0x30, 0x0b, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, + 0x01, 0x30, 0x82, 0x01, 0x70, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x07, 0x01, 0xa0, 0x82, 0x01, 0x61, + 0x04, 0x82, 0x01, 0x5d, 0x15, 0x24, 0x00, 0x01, 0x25, 0x01, 0xf1, 0xff, 0x36, 0x02, 0x05, 0x00, 0x80, 0x05, 0x01, 0x80, + 0x05, 0x02, 0x80, 0x05, 0x03, 0x80, 0x05, 0x04, 0x80, 0x05, 0x05, 0x80, 0x05, 0x06, 0x80, 0x05, 0x07, 0x80, 0x05, 0x08, + 0x80, 0x05, 0x09, 0x80, 0x05, 0x0a, 0x80, 0x05, 0x0b, 0x80, 0x05, 0x0c, 0x80, 0x05, 0x0d, 0x80, 0x05, 0x0e, 0x80, 0x05, + 0x0f, 0x80, 0x05, 0x10, 0x80, 0x05, 0x11, 0x80, 0x05, 0x12, 0x80, 0x05, 0x13, 0x80, 0x05, 0x14, 0x80, 0x05, 0x15, 0x80, + 0x05, 0x16, 0x80, 0x05, 0x17, 0x80, 0x05, 0x18, 0x80, 0x05, 0x19, 0x80, 0x05, 0x1a, 0x80, 0x05, 0x1b, 0x80, 0x05, 0x1c, + 0x80, 0x05, 0x1d, 0x80, 0x05, 0x1e, 0x80, 0x05, 0x1f, 0x80, 0x05, 0x20, 0x80, 0x05, 0x21, 0x80, 0x05, 0x22, 0x80, 0x05, + 0x23, 0x80, 0x05, 0x24, 0x80, 0x05, 0x25, 0x80, 0x05, 0x26, 0x80, 0x05, 0x27, 0x80, 0x05, 0x28, 0x80, 0x05, 0x29, 0x80, + 0x05, 0x2a, 0x80, 0x05, 0x2b, 0x80, 0x05, 0x2c, 0x80, 0x05, 0x2d, 0x80, 0x05, 0x2e, 0x80, 0x05, 0x2f, 0x80, 0x05, 0x30, + 0x80, 0x05, 0x31, 0x80, 0x05, 0x32, 0x80, 0x05, 0x33, 0x80, 0x05, 0x34, 0x80, 0x05, 0x35, 0x80, 0x05, 0x36, 0x80, 0x05, + 0x37, 0x80, 0x05, 0x38, 0x80, 0x05, 0x39, 0x80, 0x05, 0x3a, 0x80, 0x05, 0x3b, 0x80, 0x05, 0x3c, 0x80, 0x05, 0x3d, 0x80, + 0x05, 0x3e, 0x80, 0x05, 0x3f, 0x80, 0x05, 0x40, 0x80, 0x05, 0x41, 0x80, 0x05, 0x42, 0x80, 0x05, 0x43, 0x80, 0x05, 0x44, + 0x80, 0x05, 0x45, 0x80, 0x05, 0x46, 0x80, 0x05, 0x47, 0x80, 0x05, 0x48, 0x80, 0x05, 0x49, 0x80, 0x05, 0x4a, 0x80, 0x05, + 0x4b, 0x80, 0x05, 0x4c, 0x80, 0x05, 0x4d, 0x80, 0x05, 0x4e, 0x80, 0x05, 0x4f, 0x80, 0x05, 0x50, 0x80, 0x05, 0x51, 0x80, + 0x05, 0x52, 0x80, 0x05, 0x53, 0x80, 0x05, 0x54, 0x80, 0x05, 0x55, 0x80, 0x05, 0x56, 0x80, 0x05, 0x57, 0x80, 0x05, 0x58, + 0x80, 0x05, 0x59, 0x80, 0x05, 0x5a, 0x80, 0x05, 0x5b, 0x80, 0x05, 0x5c, 0x80, 0x05, 0x5d, 0x80, 0x05, 0x5e, 0x80, 0x05, + 0x5f, 0x80, 0x05, 0x60, 0x80, 0x05, 0x61, 0x80, 0x05, 0x62, 0x80, 0x05, 0x63, 0x80, 0x18, 0x24, 0x03, 0x16, 0x2c, 0x04, + 0x13, 0x43, 0x53, 0x41, 0x30, 0x30, 0x30, 0x30, 0x30, 0x53, 0x57, 0x43, 0x30, 0x30, 0x30, 0x30, 0x30, 0x2d, 0x30, 0x30, + 0x24, 0x05, 0x00, 0x24, 0x06, 0x00, 0x24, 0x07, 0x01, 0x24, 0x08, 0x00, 0x18, 0x31, 0x7c, 0x30, 0x7a, 0x02, 0x01, 0x03, + 0x80, 0x14, 0xfe, 0x34, 0x3f, 0x95, 0x99, 0x47, 0x76, 0x3b, 0x61, 0xee, 0x45, 0x39, 0x13, 0x13, 0x38, 0x49, 0x4f, 0xe6, + 0x7d, 0x8e, 0x30, 0x0b, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x01, 0x30, 0x0a, 0x06, 0x08, 0x2a, + 0x86, 0x48, 0xce, 0x3d, 0x04, 0x03, 0x02, 0x04, 0x46, 0x30, 0x44, 0x02, 0x20, 0x4a, 0x12, 0xf8, 0xd4, 0x2f, 0x90, 0x23, + 0x5c, 0x05, 0xa7, 0x71, 0x21, 0xcb, 0xeb, 0xae, 0x15, 0xd5, 0x90, 0x14, 0x65, 0x58, 0xe9, 0xc9, 0xb4, 0x7a, 0x1a, 0x38, + 0xf7, 0xa3, 0x6a, 0x7d, 0xc5, 0x02, 0x20, 0x20, 0xa4, 0x74, 0x28, 0x97, 0xc3, 0x0a, 0xed, 0xa0, 0xa5, 0x6b, 0x36, 0xe1, + 0x4e, 0xbb, 0xc8, 0x5b, 0xbd, 0xb7, 0x44, 0x93, 0xf9, 0x93, 0x58, 0x1e, 0xb0, 0x44, 0x4e, 0xd6, 0xca, 0x94, 0x0b + }; + + return CopySpanToMutableSpan(ByteSpan{ kCdForAllExamples }, outBufferSpan); +#else + return CHIP_ERROR_UNSUPPORTED_CHIP_FEATURE; +#endif +} + +CHIP_ERROR FactoryDataProvider::GetFirmwareInformation(MutableByteSpan & firmwareInformationSpan) +{ + return CHIP_ERROR_UNSUPPORTED_CHIP_FEATURE; +} + +CHIP_ERROR FactoryDataProvider::GetDeviceAttestationCert(MutableByteSpan & attestationCertSpan) +{ +#if !CONFIG_STM32_FACTORY_DATA_ENABLE + static const uint8_t kDevelopmentDAC_Cert_FFF1_8004[493] = { + 0x30, 0x82, 0x01, 0xe9, 0x30, 0x82, 0x01, 0x8e, 0xa0, 0x03, 0x02, 0x01, 0x02, 0x02, 0x08, 0x1e, 0x06, 0x7f, 0x3b, 0xfe, + 0xcd, 0xd8, 0x13, 0x30, 0x0a, 0x06, 0x08, 0x2a, 0x86, 0x48, 0xce, 0x3d, 0x04, 0x03, 0x02, 0x30, 0x3d, 0x31, 0x25, 0x30, + 0x23, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0c, 0x1c, 0x4d, 0x61, 0x74, 0x74, 0x65, 0x72, 0x20, 0x44, 0x65, 0x76, 0x20, 0x50, + 0x41, 0x49, 0x20, 0x30, 0x78, 0x46, 0x46, 0x46, 0x31, 0x20, 0x6e, 0x6f, 0x20, 0x50, 0x49, 0x44, 0x31, 0x14, 0x30, 0x12, + 0x06, 0x0a, 0x2b, 0x06, 0x01, 0x04, 0x01, 0x82, 0xa2, 0x7c, 0x02, 0x01, 0x0c, 0x04, 0x46, 0x46, 0x46, 0x31, 0x30, 0x20, + 0x17, 0x0d, 0x32, 0x32, 0x30, 0x32, 0x30, 0x35, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x5a, 0x18, 0x0f, 0x39, 0x39, 0x39, + 0x39, 0x31, 0x32, 0x33, 0x31, 0x32, 0x33, 0x35, 0x39, 0x35, 0x39, 0x5a, 0x30, 0x53, 0x31, 0x25, 0x30, 0x23, 0x06, 0x03, + 0x55, 0x04, 0x03, 0x0c, 0x1c, 0x4d, 0x61, 0x74, 0x74, 0x65, 0x72, 0x20, 0x44, 0x65, 0x76, 0x20, 0x44, 0x41, 0x43, 0x20, + 0x30, 0x78, 0x46, 0x46, 0x46, 0x31, 0x2f, 0x30, 0x78, 0x38, 0x30, 0x30, 0x34, 0x31, 0x14, 0x30, 0x12, 0x06, 0x0a, 0x2b, + 0x06, 0x01, 0x04, 0x01, 0x82, 0xa2, 0x7c, 0x02, 0x01, 0x0c, 0x04, 0x46, 0x46, 0x46, 0x31, 0x31, 0x14, 0x30, 0x12, 0x06, + 0x0a, 0x2b, 0x06, 0x01, 0x04, 0x01, 0x82, 0xa2, 0x7c, 0x02, 0x02, 0x0c, 0x04, 0x38, 0x30, 0x30, 0x34, 0x30, 0x59, 0x30, + 0x13, 0x06, 0x07, 0x2a, 0x86, 0x48, 0xce, 0x3d, 0x02, 0x01, 0x06, 0x08, 0x2a, 0x86, 0x48, 0xce, 0x3d, 0x03, 0x01, 0x07, + 0x03, 0x42, 0x00, 0x04, 0x50, 0x41, 0x38, 0xef, 0x31, 0xc9, 0xdd, 0x16, 0x0e, 0xb4, 0x6c, 0x6c, 0x17, 0x11, 0x4f, 0x9d, + 0x72, 0x88, 0x40, 0x80, 0x1f, 0x73, 0xbb, 0x9b, 0x5a, 0x2c, 0x51, 0x91, 0xc9, 0xb2, 0x06, 0x63, 0x01, 0x9d, 0x94, 0x76, + 0xd1, 0x93, 0x1b, 0x93, 0xff, 0x47, 0xf4, 0x32, 0x56, 0x37, 0x90, 0x35, 0xd2, 0x29, 0x62, 0x0b, 0x7e, 0x21, 0x0e, 0x59, + 0x2f, 0x26, 0x43, 0x7d, 0x2d, 0x57, 0x62, 0x05, 0xa3, 0x60, 0x30, 0x5e, 0x30, 0x0c, 0x06, 0x03, 0x55, 0x1d, 0x13, 0x01, + 0x01, 0xff, 0x04, 0x02, 0x30, 0x00, 0x30, 0x0e, 0x06, 0x03, 0x55, 0x1d, 0x0f, 0x01, 0x01, 0xff, 0x04, 0x04, 0x03, 0x02, + 0x07, 0x80, 0x30, 0x1d, 0x06, 0x03, 0x55, 0x1d, 0x0e, 0x04, 0x16, 0x04, 0x14, 0xa0, 0xa7, 0x1c, 0x2a, 0x5f, 0x74, 0x45, + 0x20, 0x5b, 0x12, 0xa6, 0x28, 0xca, 0xb7, 0x16, 0x45, 0xba, 0x2d, 0x5e, 0x72, 0x30, 0x1f, 0x06, 0x03, 0x55, 0x1d, 0x23, + 0x04, 0x18, 0x30, 0x16, 0x80, 0x14, 0x63, 0x54, 0x0e, 0x47, 0xf6, 0x4b, 0x1c, 0x38, 0xd1, 0x38, 0x84, 0xa4, 0x62, 0xd1, + 0x6c, 0x19, 0x5d, 0x8f, 0xfb, 0x3c, 0x30, 0x0a, 0x06, 0x08, 0x2a, 0x86, 0x48, 0xce, 0x3d, 0x04, 0x03, 0x02, 0x03, 0x49, + 0x00, 0x30, 0x46, 0x02, 0x21, 0x00, 0xe7, 0x79, 0xeb, 0x8b, 0xbb, 0xd8, 0xba, 0x28, 0x68, 0xd3, 0x7b, 0xfc, 0x3a, 0x0e, + 0x33, 0x87, 0x03, 0xdb, 0xe4, 0x5c, 0x54, 0x09, 0x8c, 0x8a, 0xe4, 0xa3, 0x84, 0x4e, 0xf5, 0xc8, 0x2b, 0x5b, 0x02, 0x21, + 0x00, 0x90, 0xe7, 0x6b, 0x2b, 0x83, 0x73, 0x92, 0xab, 0x29, 0x40, 0x39, 0x10, 0x40, 0xf6, 0x4d, 0xc7, 0x8c, 0x53, 0x01, + 0xac, 0x9d, 0x08, 0x66, 0x4f, 0xf6, 0xd0, 0x10, 0x4a, 0xfe, 0x98, 0xfc, 0x80, + }; + + return CopySpanToMutableSpan(ByteSpan(kDevelopmentDAC_Cert_FFF1_8004), attestationCertSpan); +#else + return CHIP_ERROR_UNSUPPORTED_CHIP_FEATURE; +#endif +} + +CHIP_ERROR FactoryDataProvider::GetProductAttestationIntermediateCert(MutableByteSpan & intermediateCertSpan) +{ +#if !CONFIG_STM32_FACTORY_DATA_ENABLE + static const uint8_t kDevelopmentPAI_Cert_FFF1[463] = { + 0x30, 0x82, 0x01, 0xcb, 0x30, 0x82, 0x01, 0x71, 0xa0, 0x03, 0x02, 0x01, 0x02, 0x02, 0x08, 0x56, 0xad, 0x82, 0x22, 0xad, + 0x94, 0x5b, 0x64, 0x30, 0x0a, 0x06, 0x08, 0x2a, 0x86, 0x48, 0xce, 0x3d, 0x04, 0x03, 0x02, 0x30, 0x30, 0x31, 0x18, 0x30, + 0x16, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0c, 0x0f, 0x4d, 0x61, 0x74, 0x74, 0x65, 0x72, 0x20, 0x54, 0x65, 0x73, 0x74, 0x20, + 0x50, 0x41, 0x41, 0x31, 0x14, 0x30, 0x12, 0x06, 0x0a, 0x2b, 0x06, 0x01, 0x04, 0x01, 0x82, 0xa2, 0x7c, 0x02, 0x01, 0x0c, + 0x04, 0x46, 0x46, 0x46, 0x31, 0x30, 0x20, 0x17, 0x0d, 0x32, 0x32, 0x30, 0x32, 0x30, 0x35, 0x30, 0x30, 0x30, 0x30, 0x30, + 0x30, 0x5a, 0x18, 0x0f, 0x39, 0x39, 0x39, 0x39, 0x31, 0x32, 0x33, 0x31, 0x32, 0x33, 0x35, 0x39, 0x35, 0x39, 0x5a, 0x30, + 0x3d, 0x31, 0x25, 0x30, 0x23, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0c, 0x1c, 0x4d, 0x61, 0x74, 0x74, 0x65, 0x72, 0x20, 0x44, + 0x65, 0x76, 0x20, 0x50, 0x41, 0x49, 0x20, 0x30, 0x78, 0x46, 0x46, 0x46, 0x31, 0x20, 0x6e, 0x6f, 0x20, 0x50, 0x49, 0x44, + 0x31, 0x14, 0x30, 0x12, 0x06, 0x0a, 0x2b, 0x06, 0x01, 0x04, 0x01, 0x82, 0xa2, 0x7c, 0x02, 0x01, 0x0c, 0x04, 0x46, 0x46, + 0x46, 0x31, 0x30, 0x59, 0x30, 0x13, 0x06, 0x07, 0x2a, 0x86, 0x48, 0xce, 0x3d, 0x02, 0x01, 0x06, 0x08, 0x2a, 0x86, 0x48, + 0xce, 0x3d, 0x03, 0x01, 0x07, 0x03, 0x42, 0x00, 0x04, 0x41, 0x9a, 0x93, 0x15, 0xc2, 0x17, 0x3e, 0x0c, 0x8c, 0x87, 0x6d, + 0x03, 0xcc, 0xfc, 0x94, 0x48, 0x52, 0x64, 0x7f, 0x7f, 0xec, 0x5e, 0x50, 0x82, 0xf4, 0x05, 0x99, 0x28, 0xec, 0xa8, 0x94, + 0xc5, 0x94, 0x15, 0x13, 0x09, 0xac, 0x63, 0x1e, 0x4c, 0xb0, 0x33, 0x92, 0xaf, 0x68, 0x4b, 0x0b, 0xaf, 0xb7, 0xe6, 0x5b, + 0x3b, 0x81, 0x62, 0xc2, 0xf5, 0x2b, 0xf9, 0x31, 0xb8, 0xe7, 0x7a, 0xaa, 0x82, 0xa3, 0x66, 0x30, 0x64, 0x30, 0x12, 0x06, + 0x03, 0x55, 0x1d, 0x13, 0x01, 0x01, 0xff, 0x04, 0x08, 0x30, 0x06, 0x01, 0x01, 0xff, 0x02, 0x01, 0x00, 0x30, 0x0e, 0x06, + 0x03, 0x55, 0x1d, 0x0f, 0x01, 0x01, 0xff, 0x04, 0x04, 0x03, 0x02, 0x01, 0x06, 0x30, 0x1d, 0x06, 0x03, 0x55, 0x1d, 0x0e, + 0x04, 0x16, 0x04, 0x14, 0x63, 0x54, 0x0e, 0x47, 0xf6, 0x4b, 0x1c, 0x38, 0xd1, 0x38, 0x84, 0xa4, 0x62, 0xd1, 0x6c, 0x19, + 0x5d, 0x8f, 0xfb, 0x3c, 0x30, 0x1f, 0x06, 0x03, 0x55, 0x1d, 0x23, 0x04, 0x18, 0x30, 0x16, 0x80, 0x14, 0x6a, 0xfd, 0x22, + 0x77, 0x1f, 0x51, 0x1f, 0xec, 0xbf, 0x16, 0x41, 0x97, 0x67, 0x10, 0xdc, 0xdc, 0x31, 0xa1, 0x71, 0x7e, 0x30, 0x0a, 0x06, + 0x08, 0x2a, 0x86, 0x48, 0xce, 0x3d, 0x04, 0x03, 0x02, 0x03, 0x48, 0x00, 0x30, 0x45, 0x02, 0x21, 0x00, 0xb2, 0xef, 0x27, + 0xf4, 0x9a, 0xe9, 0xb5, 0x0f, 0xb9, 0x1e, 0xea, 0xc9, 0x4c, 0x4d, 0x0b, 0xdb, 0xb8, 0xd7, 0x92, 0x9c, 0x6c, 0xb8, 0x8f, + 0xac, 0xe5, 0x29, 0x36, 0x8d, 0x12, 0x05, 0x4c, 0x0c, 0x02, 0x20, 0x65, 0x5d, 0xc9, 0x2b, 0x86, 0xbd, 0x90, 0x98, 0x82, + 0xa6, 0xc6, 0x21, 0x77, 0xb8, 0x25, 0xd7, 0xd0, 0x5e, 0xdb, 0xe7, 0xc2, 0x2f, 0x9f, 0xea, 0x71, 0x22, 0x0e, 0x7e, 0xa7, + 0x03, 0xf8, 0x91, + }; + + return CopySpanToMutableSpan(ByteSpan(kDevelopmentPAI_Cert_FFF1), intermediateCertSpan); +#else + return CHIP_ERROR_UNSUPPORTED_CHIP_FEATURE; +#endif +} + +CHIP_ERROR FactoryDataProvider::GetSpake2pSalt(MutableByteSpan & saltSpan) +{ +#if !CONFIG_STM32_FACTORY_DATA_ENABLE + static const uint8_t kDefaultTestVerifierSalt[16] = { + 0x53, 0x50, 0x41, 0x4b, 0x45, 0x32, 0x50, 0x20, 0x4b, 0x65, 0x79, 0x20, 0x53, 0x61, 0x6c, 0x74, + }; + + size_t saltLen = sizeof(kDefaultTestVerifierSalt); + if (saltSpan.size() < saltLen) + { + return CHIP_ERROR_BUFFER_TOO_SMALL; + } + memcpy(saltSpan.data(), &kDefaultTestVerifierSalt[0], saltLen); + saltSpan.reduce_size(saltLen); + return CHIP_NO_ERROR; +#else + return CHIP_ERROR_UNSUPPORTED_CHIP_FEATURE; +#endif +} + +CHIP_ERROR FactoryDataProvider::GetRotatingDeviceIdUniqueId(MutableByteSpan & uniqueIdSpan) +{ + return CHIP_ERROR_UNSUPPORTED_CHIP_FEATURE; +} + +CHIP_ERROR FactoryDataProvider::GetEnableKey(MutableByteSpan & enableKeySpan) +{ + return CHIP_ERROR_UNSUPPORTED_CHIP_FEATURE; +} + +} // namespace DeviceLayer +} // namespace chip diff --git a/src/platform/stm32/FactoryDataProvider.h b/src/platform/stm32/FactoryDataProvider.h new file mode 100644 index 00000000000000..2882b989e8902d --- /dev/null +++ b/src/platform/stm32/FactoryDataProvider.h @@ -0,0 +1,69 @@ +/* + * + * Copyright (c) 2022 Project CHIP Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#pragma once + +#include +#include +#include + +namespace chip { +namespace DeviceLayer { + +class FactoryDataProvider : public chip::Credentials::DeviceAttestationCredentialsProvider, + public CommissionableDataProvider, + public DeviceInstanceInfoProvider +{ +public: + CHIP_ERROR Init(); + static FactoryDataProvider & GetDefaultInstance(); + // ===== Members functions that implement the DeviceAttestationCredentialsProvider + CHIP_ERROR GetCertificationDeclaration(MutableByteSpan & outBuffer) override; + CHIP_ERROR GetFirmwareInformation(MutableByteSpan & out_firmware_info_buffer) override; + CHIP_ERROR GetDeviceAttestationCert(MutableByteSpan & outBuffer) override; + CHIP_ERROR GetProductAttestationIntermediateCert(MutableByteSpan & outBuffer) override; + CHIP_ERROR SignWithDeviceAttestationKey(const ByteSpan & messageToSign, MutableByteSpan & outSignBuffer) override; + + // ===== Members functions that implement the CommissionableDataProvider + CHIP_ERROR GetSetupDiscriminator(uint16_t & setupDiscriminator) override; + CHIP_ERROR SetSetupDiscriminator(uint16_t setupDiscriminator) override; + CHIP_ERROR GetSpake2pIterationCount(uint32_t & iterationCount) override; + CHIP_ERROR GetSpake2pSalt(MutableByteSpan & saltBuf) override; + CHIP_ERROR GetSpake2pVerifier(MutableByteSpan & verifierBuf, size_t & verifierLen) override; + CHIP_ERROR GetSetupPasscode(uint32_t & setupPasscode) override; + CHIP_ERROR SetSetupPasscode(uint32_t setupPasscode) override; + + // ===== Members functions that implement the DeviceInstanceInfoProvider + CHIP_ERROR GetVendorName(char * buf, size_t bufSize) override; + CHIP_ERROR GetVendorId(uint16_t & vendorId) override; + CHIP_ERROR GetProductName(char * buf, size_t bufSize) override; + CHIP_ERROR GetProductId(uint16_t & productId) override; + CHIP_ERROR GetPartNumber(char * buf, size_t bufSize) override; + CHIP_ERROR GetProductURL(char * buf, size_t bufSize) override; + CHIP_ERROR GetProductLabel(char * buf, size_t bufSize) override; + CHIP_ERROR GetSerialNumber(char * buf, size_t bufSize) override; + CHIP_ERROR GetManufacturingDate(uint16_t & year, uint8_t & month, uint8_t & day) override; + CHIP_ERROR GetHardwareVersion(uint16_t & hardwareVersion) override; + CHIP_ERROR GetHardwareVersionString(char * buf, size_t bufSize) override; + CHIP_ERROR GetRotatingDeviceIdUniqueId(MutableByteSpan & uniqueIdSpan) override; + + // ===== Members functions that are platform-specific + CHIP_ERROR GetEnableKey(MutableByteSpan & enableKey); +}; + +} // namespace DeviceLayer +} // namespace chip diff --git a/src/platform/stm32/InetPlatformConfig.h b/src/platform/stm32/InetPlatformConfig.h new file mode 100644 index 00000000000000..44e4719c99ed95 --- /dev/null +++ b/src/platform/stm32/InetPlatformConfig.h @@ -0,0 +1,41 @@ +/* + * + * Copyright (c) 2020 Project CHIP Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * @file + * Platform-specific configuration overrides for the Inet + * Layer on stm32 platforms. + * + */ + +#pragma once + +// ==================== Platform Adaptations ==================== + +#ifndef INET_CONFIG_ENABLE_IPV4 +#error Inet IPv4 configuration should be configured at build generation time +#endif + +// ========== Platform-specific Configuration Overrides ========= + +#ifndef INET_CONFIG_NUM_TCP_ENDPOINTS +#define INET_CONFIG_NUM_TCP_ENDPOINTS 4 +#endif // INET_CONFIG_NUM_TCP_ENDPOINTS + +#ifndef INET_CONFIG_NUM_UDP_ENDPOINTS +#define INET_CONFIG_NUM_UDP_ENDPOINTS 4 +#endif // INET_CONFIG_NUM_UDP_ENDPOINTS diff --git a/src/platform/stm32/KeyValueStoreManagerImpl.cpp b/src/platform/stm32/KeyValueStoreManagerImpl.cpp new file mode 100644 index 00000000000000..b68ea2c1c9adc9 --- /dev/null +++ b/src/platform/stm32/KeyValueStoreManagerImpl.cpp @@ -0,0 +1,121 @@ +/* + * + * Copyright (c) 2021 Project CHIP Authors + * All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "flash_wb.h" +#include +#include +#include +#include +#include + +#define MATTER_KEY_NAME_MAX_LENGTH (15 * 2) // ADD Max key name string size is 30 "keyType...;KeyName..." +namespace chip { +namespace DeviceLayer { +namespace PersistedStorage { +/** Singleton instance of the KeyValueStoreManager implementation object. + */ +KeyValueStoreManagerImpl KeyValueStoreManagerImpl::sInstance; + +CHIP_ERROR KeyValueStoreManagerImpl::_Get(const char * key, void * value, size_t value_size, size_t * read_bytes_size, + size_t offset) +{ + CHIP_ERROR err = CHIP_NO_ERROR; + + if ((key != NULL) && (value != NULL) && (read_bytes_size != NULL)) + { + return this->_PrintError(NM_GetKeyValue(value, key, (uint32_t) value_size, read_bytes_size, SECTOR_SECURE)); + } + else + { + err = CHIP_ERROR_PERSISTED_STORAGE_VALUE_NOT_FOUND; + } + return err; +} + +CHIP_ERROR KeyValueStoreManagerImpl::_Delete(const char * key) +{ + + ChipLogDetail(DataManagement, "DELETE=> %s", key); + if (key != NULL) + { + return this->_PrintError(NM_DeleteKey(key, SECTOR_SECURE)); + } + return CHIP_ERROR_PERSISTED_STORAGE_FAILED; +} + +CHIP_ERROR KeyValueStoreManagerImpl::_Put(const char * key, const void * value, size_t value_size) +{ + + if ((value_size != 0) && (key != NULL) && (value != NULL)) + { + + return this->_PrintError(NM_SetKeyValue((char *) value, (char *) key, (uint32_t) value_size, SECTOR_SECURE)); + } + + return CHIP_NO_ERROR; +} + +CHIP_ERROR KeyValueStoreManagerImpl::_PrintError(NVM_StatusTypeDef err) +{ + switch (err) + { + case NVM_OK: + ChipLogDetail(DataManagement, "NVM_OK"); + return CHIP_NO_ERROR; + + case NVM_KEY_NOT_FOUND: + ChipLogDetail(DataManagement, "CHIP_ERROR_PERSISTED_STORAGE_NOT_FOUND"); + return CHIP_ERROR_PERSISTED_STORAGE_VALUE_NOT_FOUND; + + case NVM_WRITE_FAILED: + ChipLogDetail(DataManagement, "NVM_WRITE_FAILED"); + return CHIP_ERROR_PERSISTED_STORAGE_FAILED; + + case NVM_READ_FAILED: + ChipLogDetail(DataManagement, "NVM_READ_FAILED"); + return CHIP_ERROR_PERSISTED_STORAGE_FAILED; + + case NVM_DELETE_FAILED: + ChipLogDetail(DataManagement, "NVM_DELETE_FAILED"); + return CHIP_ERROR_PERSISTED_STORAGE_FAILED; + + case NVM_SIZE_FULL: + ChipLogDetail(DataManagement, "NVM_SIZE_FULL"); + return CHIP_ERROR_PERSISTED_STORAGE_FAILED; + + case NVM_BLOCK_SIZE_OVERFLOW: + ChipLogDetail(DataManagement, "NVM_BLOCK_SIZE_OVERFLOW"); + return CHIP_ERROR_PERSISTED_STORAGE_FAILED; + + case NVM_ERROR_BLOCK_ALIGN: + ChipLogDetail(DataManagement, "NVM_ERROR_BLOCK_ALIGN"); + return CHIP_ERROR_PERSISTED_STORAGE_FAILED; + + case NVM_BUFFER_TOO_SMALL: + ChipLogDetail(DataManagement, "NVM_BUFFER_TOO_SMALL"); + return CHIP_ERROR_PERSISTED_STORAGE_FAILED; + + default: + ChipLogDetail(DataManagement, "NVM_UNKNOWN_ERROR "); + return CHIP_ERROR_PERSISTED_STORAGE_FAILED; + } +} + +} // namespace PersistedStorage +} // namespace DeviceLayer +} // namespace chip diff --git a/src/platform/stm32/KeyValueStoreManagerImpl.h b/src/platform/stm32/KeyValueStoreManagerImpl.h new file mode 100644 index 00000000000000..335ffb2b907df9 --- /dev/null +++ b/src/platform/stm32/KeyValueStoreManagerImpl.h @@ -0,0 +1,82 @@ +/* + * + * Copyright (c) 2021 Project CHIP Authors + * All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef MIDDLEWARES_MATTER_PLATFORM_STM32WB_KEYVALUESTOREMANAGERIMPL_H_ +#define MIDDLEWARES_MATTER_PLATFORM_STM32WB_KEYVALUESTOREMANAGERIMPL_H_ + +#pragma once + +#include + +#include "flash_wb.h" +#include "stm_logging.h" + +namespace chip { +namespace DeviceLayer { +namespace PersistedStorage { + +class KeyValueStoreManagerImpl : public KeyValueStoreManager +{ + // Allow the KeyValueStoreManager interface class to delegate method calls to + // the implementation methods provided by this class. + friend class KeyValueStoreManager; + +public: + CHIP_ERROR _Get(const char * key, void * value, size_t value_size, size_t * read_bytes_size, size_t offset); + + CHIP_ERROR _Delete(const char * key); + + CHIP_ERROR _Put(const char * key, const void * value, size_t value_size); + + CHIP_ERROR _PrintError(NVM_StatusTypeDef err); + +private: + // ===== Members for internal use by the following friends. + friend KeyValueStoreManager & KeyValueStoreMgr(); + friend KeyValueStoreManagerImpl & KeyValueStoreMgrImpl(); + + static KeyValueStoreManagerImpl sInstance; +}; + +/** + * Returns the public interface of the KeyValueStoreManager singleton object. + * + * Chip applications should use this to access features of the KeyValueStoreManager object + * that are common to all platforms. + */ +inline KeyValueStoreManager & KeyValueStoreMgr(void) +{ + return KeyValueStoreManagerImpl::sInstance; +} + +/** + * Returns the platform-specific implementation of the KeyValueStoreManager singleton object. + * + * Chip applications can use this to gain access to features of the KeyValueStoreManager + * that are specific to the STM32 platform. + */ +inline KeyValueStoreManagerImpl & KeyValueStoreMgrImpl(void) +{ + return KeyValueStoreManagerImpl::sInstance; +} + +} // namespace PersistedStorage +} // namespace DeviceLayer +} // namespace chip + +#endif /* MIDDLEWARES_MATTER_PLATFORM_STM32WB_KEYVALUESTOREMANAGERIMPL_H_ */ diff --git a/src/platform/stm32/PlatformManagerImpl.cpp b/src/platform/stm32/PlatformManagerImpl.cpp new file mode 100644 index 00000000000000..60148b07f6e4ca --- /dev/null +++ b/src/platform/stm32/PlatformManagerImpl.cpp @@ -0,0 +1,116 @@ +/* + * + * Copyright (c) 2021 Project CHIP Authors + * All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * @file + * Provides an implementation of the PlatformManager object + * for the stm32 platform. + */ + +#include +#include +#include +#include +#include +#include +#include + +namespace chip { +namespace DeviceLayer { + +PlatformManagerImpl PlatformManagerImpl::sInstance; +extern "C" int mbedtls_hardware_poll(void * data, unsigned char * output, size_t len, size_t * olen); + +CHIP_ERROR PlatformManagerImpl::_InitChipStack(void) +{ + System::Clock::InitClock_RealTime(); + chip::Crypto::add_entropy_source(mbedtls_hardware_poll, NULL, 16); + ReturnErrorOnFailure(Internal::GenericPlatformManagerImpl_FreeRTOS::_InitChipStack()); + return CHIP_NO_ERROR; +} + +void PlatformManagerImpl::_RunEventLoop(void) +{ + Internal::GenericPlatformManagerImpl_FreeRTOS::_RunEventLoop(); +} + +void PlatformManagerImpl::_Shutdown() +{ + uint64_t upTime = 0; + + if (GetDiagnosticDataProvider().GetUpTime(upTime) == CHIP_NO_ERROR) + { + uint32_t totalOperationalHours = 0; + + if (ConfigurationMgr().GetTotalOperationalHours(totalOperationalHours) == CHIP_NO_ERROR) + { + ConfigurationMgr().StoreTotalOperationalHours(totalOperationalHours + static_cast(upTime / 3600)); + } + else + { + ChipLogError(DeviceLayer, "Failed to get total operational hours of the Node"); + } + } + else + { + ChipLogError(DeviceLayer, "Failed to get current uptime since the Node’s last reboot"); + } + + Internal::GenericPlatformManagerImpl_FreeRTOS::_Shutdown(); +} + +CHIP_ERROR PlatformManagerImpl::_GetCurrentHeapFree(uint64_t & currentHeapFree) +{ + + return CHIP_ERROR_UNSUPPORTED_CHIP_FEATURE; +} + +CHIP_ERROR PlatformManagerImpl::_GetCurrentHeapUsed(uint64_t & currentHeapUsed) +{ + + return CHIP_ERROR_UNSUPPORTED_CHIP_FEATURE; +} + +CHIP_ERROR PlatformManagerImpl::_GetCurrentHeapHighWatermark(uint64_t & currentHeapHighWatermark) +{ + + return CHIP_ERROR_UNSUPPORTED_CHIP_FEATURE; +} + +CHIP_ERROR PlatformManagerImpl::_GetTotalOperationalHours(uint32_t & totalOperationalHours) +{ + return CHIP_ERROR_UNSUPPORTED_CHIP_FEATURE; +} + +CHIP_ERROR PlatformManagerImpl::_GetRebootCount(uint16_t & rebootCount) +{ + return CHIP_ERROR_UNSUPPORTED_CHIP_FEATURE; +} + +CHIP_ERROR PlatformManagerImpl::_GetUpTime(uint64_t & upTime) +{ + return CHIP_ERROR_UNSUPPORTED_CHIP_FEATURE; +} + +CHIP_ERROR PlatformManagerImpl::_GetBootReasons(uint8_t & bootReasons) +{ + return CHIP_ERROR_UNSUPPORTED_CHIP_FEATURE; +} + +} // namespace DeviceLayer +} // namespace chip diff --git a/src/platform/stm32/PlatformManagerImpl.h b/src/platform/stm32/PlatformManagerImpl.h new file mode 100644 index 00000000000000..8de9bfa4a24f48 --- /dev/null +++ b/src/platform/stm32/PlatformManagerImpl.h @@ -0,0 +1,101 @@ +/* + * + * Copyright (c) 2020 Project CHIP Authors + * Copyright (c) 2018 Nest Labs, Inc. + * All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * @file + * Provides an implementation of the PlatformManager object + * for the stm32 platforms. + */ + +#pragma once + +#include + +namespace chip { +namespace DeviceLayer { + +/** + * Concrete implementation of the PlatformManager singleton object for the stm32 platform. + */ +class PlatformManagerImpl final : public PlatformManager, public Internal::GenericPlatformManagerImpl_FreeRTOS +{ + // Allow the PlatformManager interface class to delegate method calls to + // the implementation methods provided by this class. + friend PlatformManager; + + // Allow the generic implementation base class to call helper methods on + // this class. +#ifndef DOXYGEN_SHOULD_SKIP_THIS + friend Internal::GenericPlatformManagerImpl_FreeRTOS; +#endif + +public: + // ===== Platform-specific members that may be accessed directly by the application. + + CHIP_ERROR InitLwIPCoreLock(void); + // static void HandleESPSystemEvent(void * arg, esp_event_base_t eventBase, int32_t eventId, void * eventData); + +private: + // ===== Methods that implement the PlatformManager abstract interface. + + CHIP_ERROR _InitChipStack(void); + void _RunEventLoop(void); + void _Shutdown(); + CHIP_ERROR _GetCurrentHeapFree(uint64_t & currentHeapFree); + CHIP_ERROR _GetCurrentHeapUsed(uint64_t & currentHeapUsed); + CHIP_ERROR _GetCurrentHeapHighWatermark(uint64_t & currentHeapHighWatermark); + + CHIP_ERROR _GetRebootCount(uint16_t & rebootCount); + CHIP_ERROR _GetUpTime(uint64_t & upTime); + CHIP_ERROR _GetTotalOperationalHours(uint32_t & totalOperationalHours); + CHIP_ERROR _GetBootReasons(uint8_t & bootReasons); + // ===== Members for internal use by the following friends. + + friend PlatformManager & PlatformMgr(void); + friend PlatformManagerImpl & PlatformMgrImpl(void); + + uint64_t mStartTimeMilliseconds = 0; + + static PlatformManagerImpl sInstance; +}; + +/** + * Returns the public interface of the PlatformManager singleton object. + * + * Chip applications should use this to access features of the PlatformManager object + * that are common to all platforms. + */ +inline PlatformManager & PlatformMgr(void) +{ + return PlatformManagerImpl::sInstance; +} + +/** + * Returns the platform-specific implementation of the PlatformManager singleton object. + * + * Chip applications can use this to gain access to features of the PlatformManager + * that are specific to the stm32 platform. + */ +inline PlatformManagerImpl & PlatformMgrImpl(void) +{ + return PlatformManagerImpl::sInstance; +} + +} // namespace DeviceLayer +} // namespace chip diff --git a/src/platform/stm32/STM32Config.cpp b/src/platform/stm32/STM32Config.cpp new file mode 100644 index 00000000000000..cf1a6bdc652e19 --- /dev/null +++ b/src/platform/stm32/STM32Config.cpp @@ -0,0 +1,105 @@ +/* + * + * Copyright (c) 2021 Project CHIP Authors + * All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "flash_wb.h" +#include +#include + +namespace chip { +namespace DeviceLayer { +namespace Internal { + +CHIP_ERROR STM32Config::Init() +{ + return CHIP_NO_ERROR; +} + +template +CHIP_ERROR STM32Config::ReadConfigValue(Key key, T & val) +{ + uint8_t * buffer_key[35] = { 0 }; + size_t * read_by_size = NULL; + + sprintf((char *) buffer_key, "Config%i", key); + NM_GetKeyValue((void *) &val, (char *) buffer_key, sizeof(val), read_by_size, SECTOR_NO_SECURE); + + return CHIP_NO_ERROR; +} + +CHIP_ERROR STM32Config::ReadConfigValueStr(Key key, char * buf, size_t bufSize, size_t & outLen) +{ + + return ReadConfigValueBin(key, reinterpret_cast(buf), bufSize, outLen); +} + +CHIP_ERROR STM32Config::ReadConfigValueBin(Key key, uint8_t * buf, size_t bufSize, size_t & outLen) +{ + + return CHIP_ERROR_UNSUPPORTED_CHIP_FEATURE; +} + +template CHIP_ERROR STM32Config::ReadConfigValue(Key key, bool & val); +template CHIP_ERROR STM32Config::ReadConfigValue(Key key, uint32_t & val); +template CHIP_ERROR STM32Config::ReadConfigValue(Key key, uint64_t & val); + +CHIP_ERROR STM32Config::WriteConfigValue(Key key, uint32_t val) +{ + uint8_t * buffer_key[35] = { 0 }; + size_t * read_by_size = NULL; + + sprintf((char *) buffer_key, "Config%i", key); + NM_SetKeyValue((char *) &val, (char *) buffer_key, sizeof(val), SECTOR_NO_SECURE); + return CHIP_NO_ERROR; +} + +CHIP_ERROR STM32Config::WriteConfigValueStr(Key key, const char * str) +{ + return WriteConfigValueStr(key, str, (str != NULL) ? strlen(str) : 0); +} + +CHIP_ERROR STM32Config::WriteConfigValueStr(Key key, const char * str, size_t strLen) +{ + return WriteConfigValueBin(key, reinterpret_cast(str), strLen); +} + +CHIP_ERROR STM32Config::WriteConfigValueBin(Key key, const uint8_t * data, size_t dataLen) +{ + uint8_t * buffer_key[35] = { 0 }; + size_t * read_by_size = NULL; + + sprintf((char *) buffer_key, "Config%i", key); + NM_SetKeyValue((char *) data, (char *) buffer_key, dataLen, SECTOR_NO_SECURE); + return CHIP_NO_ERROR; +} + +bool STM32Config::ConfigValueExists(Key key) +{ + return false; +} + +CHIP_ERROR STM32Config::FactoryResetConfig(void) +{ + + return CHIP_ERROR_UNSUPPORTED_CHIP_FEATURE; +} + +void STM32Config::RunConfigUnitTest(void) {} + +} // namespace Internal +} // namespace DeviceLayer +} // namespace chip diff --git a/src/platform/stm32/STM32Config.h b/src/platform/stm32/STM32Config.h new file mode 100644 index 00000000000000..98ddb844616342 --- /dev/null +++ b/src/platform/stm32/STM32Config.h @@ -0,0 +1,93 @@ +/* + * + * Copyright (c) 2020 Project CHIP Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * @file + * Utilities for accessing persisted device configuration on + * on STM32 platforms. + */ + +#pragma once + +#include + +namespace chip { +namespace DeviceLayer { +namespace Internal { + +/* Base for the category calculation when determining the key IDs */ + +class STM32Config +{ +public: + using Key = uint32_t; + + // Key definitions for well-known keys. + // Factory config keys + static constexpr Key kConfigKey_SerialNum = 0; + static constexpr Key kConfigKey_MfrDeviceId = 1; + static constexpr Key kConfigKey_MfrDeviceCert = 2; + static constexpr Key kConfigKey_MfrDevicePrivateKey = 3; + static constexpr Key kConfigKey_ManufacturingDate = 4; + static constexpr Key kConfigKey_SetupPinCode = 5; + static constexpr Key kConfigKey_MfrDeviceICACerts = 6; + static constexpr Key kConfigKey_SetupDiscriminator = 7; + static constexpr Key kConfigKey_Spake2pIterationCount = 8; + static constexpr Key kConfigKey_Spake2pSalt = 9; + static constexpr Key kConfigKey_Spake2pVerifier = 10; + // CHIP Config Keys + static constexpr Key kConfigKey_FabricId = 8; + static constexpr Key kConfigKey_ServiceConfig = 9; + static constexpr Key kConfigKey_PairedAccountId = 10; + static constexpr Key kConfigKey_ServiceId = 11; + static constexpr Key kConfigKey_FabricSecret = 12; + static constexpr Key kConfigKey_LastUsedEpochKeyId = 13; + static constexpr Key kConfigKey_FailSafeArmed = 14; + static constexpr Key kConfigKey_GroupKey = 15; + static constexpr Key kConfigKey_HardwareVersion = 16; + static constexpr Key kConfigKey_RegulatoryLocation = 17; + static constexpr Key kConfigKey_CountryCode = 18; + static constexpr Key kConfigKey_HourFormat = 20; + static constexpr Key kConfigKey_CalendarType = 21; + static constexpr Key kConfigKey_Breadcrumb = 22; + static constexpr Key kConfigKey_UniqueId = 23; + static constexpr Key kConfigKey_ProductRevision = 24; + // Set key id limits for each group. + static constexpr Key kConfigKey_Base = kConfigKey_SerialNum; + static constexpr Key kConfigKey_Max = kConfigKey_UniqueId; + + static CHIP_ERROR Init(); + // Config value accessors. + template + // Config value accessors. + static CHIP_ERROR ReadConfigValue(Key key, T & val); + // Configuration methods used by the GenericConfigurationManagerImpl<> template. + static CHIP_ERROR ReadConfigValueStr(Key key, char * buf, size_t bufSize, size_t & outLen); + static CHIP_ERROR ReadConfigValueBin(Key key, uint8_t * buf, size_t bufSize, size_t & outLen); + static CHIP_ERROR WriteConfigValue(Key key, uint32_t val); + static CHIP_ERROR WriteConfigValueStr(Key key, const char * str); + static CHIP_ERROR WriteConfigValueStr(Key key, const char * str, size_t strLen); + static CHIP_ERROR WriteConfigValueBin(Key key, const uint8_t * data, size_t dataLen); + static CHIP_ERROR ClearConfigValue(Key key); + static bool ConfigValueExists(Key key); + static CHIP_ERROR FactoryResetConfig(void); + static void RunConfigUnitTest(void); +}; + +} // namespace Internal +} // namespace DeviceLayer +} // namespace chip diff --git a/src/platform/stm32/STM32FreeRtosHooks.cpp b/src/platform/stm32/STM32FreeRtosHooks.cpp new file mode 100644 index 00000000000000..cdf1909e8c4393 --- /dev/null +++ b/src/platform/stm32/STM32FreeRtosHooks.cpp @@ -0,0 +1,120 @@ +/* + * + * Copyright (c) 2021 Project CHIP Authors + * All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#include "STM32FreeRtosHooks.h" +#include "FreeRTOS.h" +#include "mbedtls/memory_buffer_alloc.h" + +#if !defined(MBEDTLS_CONFIG_FILE) +#include "mbedtls/config.h" +#else +#include MBEDTLS_CONFIG_FILE +#endif + +#define MBEDTLS_HEAP_SIZE 15000 +#include "mbedtls/pk.h" +#include "mbedtls/platform.h" +#include "mbedtls/sha1.h" +#include "mbedtls/sha256.h" +#include "mbedtls/x509_crt.h" + +#include "mbedtls/threading.h" +#include "threading_alt.h" + +#include + +static uint8_t mdedtls_heap[MBEDTLS_HEAP_SIZE]; + +static void freertos_mbedtls_heap_init(void); + +static inline void mutex_init(mbedtls_threading_mutex_t * mutex) +{ + mutex->mutex = xSemaphoreCreateMutex(); + + if (mutex->mutex != NULL) + { + mutex->is_valid = 1; + } + else + { + mutex->is_valid = 0; + } +} + +static inline void mutex_free(mbedtls_threading_mutex_t * mutex) +{ + if (mutex->is_valid == 1) + { + vSemaphoreDelete(mutex->mutex); + mutex->is_valid = 0; + } +} + +static inline int mutex_lock(mbedtls_threading_mutex_t * mutex) +{ + int ret = MBEDTLS_ERR_THREADING_BAD_INPUT_DATA; + + if (mutex->is_valid == 1) + { + if (xSemaphoreTake(mutex->mutex, portMAX_DELAY)) + { + ret = 0; + } + else + { + ret = MBEDTLS_ERR_THREADING_MUTEX_ERROR; + } + } + + return ret; +} + +static inline int mutex_unlock(mbedtls_threading_mutex_t * mutex) +{ + int ret = MBEDTLS_ERR_THREADING_BAD_INPUT_DATA; + + if (mutex->is_valid == 1) + { + if (xSemaphoreGive(mutex->mutex)) + { + ret = 0; + } + else + { + ret = MBEDTLS_ERR_THREADING_MUTEX_ERROR; + } + } + + return ret; +} + +void freertos_mbedtls_mutex_init(void) +{ + // Configure mbedtls to use mutexes from FreeRTOS + mbedtls_threading_set_alt(mutex_init, mutex_free, mutex_lock, mutex_unlock); +} + +static void freertos_mbedtls_heap_init(void) +{ + mbedtls_memory_buffer_alloc_init(mdedtls_heap, sizeof(mdedtls_heap)); +} + +void freertos_mbedtls_init(void) +{ + freertos_mbedtls_mutex_init(); + freertos_mbedtls_heap_init(); +} diff --git a/src/platform/stm32/STM32FreeRtosHooks.h b/src/platform/stm32/STM32FreeRtosHooks.h new file mode 100644 index 00000000000000..d49d7ab05a4994 --- /dev/null +++ b/src/platform/stm32/STM32FreeRtosHooks.h @@ -0,0 +1,27 @@ +/* + * + * Copyright (c) 2021 Project CHIP Authors + * All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "FreeRTOS.h" +#include "semphr.h" +#ifdef __cplusplus +extern "C" { +#endif +void freertos_mbedtls_init(void); +#ifdef __cplusplus +} +#endif diff --git a/src/platform/stm32/SystemPlatformConfig.h b/src/platform/stm32/SystemPlatformConfig.h new file mode 100644 index 00000000000000..f2ed9d41b35d77 --- /dev/null +++ b/src/platform/stm32/SystemPlatformConfig.h @@ -0,0 +1,43 @@ +/* + * + * Copyright (c) 2020 Project CHIP Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * @file + * Platform-specific configuration overrides for the CHIP System + * Layer on stm32 platforms. + * + */ + +#pragma once + +#include + +namespace chip { +namespace DeviceLayer { +struct ChipDeviceEvent; +} // namespace DeviceLayer +} // namespace chip + +// ==================== Platform Adaptations ==================== +#define CHIP_SYSTEM_CONFIG_PLATFORM_PROVIDES_TIME 1 +#define CHIP_SYSTEM_CONFIG_EVENT_OBJECT_TYPE const struct ::chip::DeviceLayer::ChipDeviceEvent * + +// ========== Platform-specific Configuration Overrides ========= + +#ifndef CHIP_SYSTEM_CONFIG_NUM_TIMERS +#define CHIP_SYSTEM_CONFIG_NUM_TIMERS 16 +#endif // CHIP_SYSTEM_CONFIG_NUM_TIMERS diff --git a/src/platform/stm32/ThreadStackManagerImpl.cpp b/src/platform/stm32/ThreadStackManagerImpl.cpp new file mode 100644 index 00000000000000..ee97ff2ad0927b --- /dev/null +++ b/src/platform/stm32/ThreadStackManagerImpl.cpp @@ -0,0 +1,144 @@ +/* + * + * Copyright (c) 2020-2021 Project CHIP Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * @file + * Provides an implementation of the ThreadStackManager object for the + * STM32 platform using the OpenThread + * stack. + * + */ +/* this file behaves like a config.h, comes first */ +#include + +#include + +#include + +#include +#include +#include +#include +#include +#include + +#include "dbg_trace.h" +#include +#include + +//#include + +#include +#include +#include +#include +#include + +namespace chip { +namespace DeviceLayer { + +using namespace ::chip::DeviceLayer::Internal; + +ThreadStackManagerImpl ThreadStackManagerImpl::sInstance; + +CHIP_ERROR ThreadStackManagerImpl::_InitThreadStack(void) +{ + return InitThreadStack(NULL); +} + +CHIP_ERROR ThreadStackManagerImpl::InitThreadStack(otInstance * otInst) +{ + CHIP_ERROR err = CHIP_NO_ERROR; + + // Initialize the generic implementation base classes. + err = GenericThreadStackManagerImpl_FreeRTOS::DoInit(); + SuccessOrExit(err); + err = GenericThreadStackManagerImpl_OpenThread::DoInit(otInst); + SuccessOrExit(err); + +exit: + return err; +} + +CHIP_ERROR ThreadStackManagerImpl::_StartThreadTask() +{ + CHIP_ERROR err = CHIP_NO_ERROR; + + // Initialize the generic implementation base classes. + err = GenericThreadStackManagerImpl_FreeRTOS::_StartThreadTask(); + SuccessOrExit(err); + +exit: + return err; +} +CHIP_ERROR ThreadStackManagerImpl::SetThreadEnabled(bool val) +{ + CHIP_ERROR err = CHIP_NO_ERROR; + err = GenericThreadStackManagerImpl_OpenThread::_SetThreadEnabled(val); + + return err; +} + +bool ThreadStackManagerImpl::IsInitialized() +{ + return sInstance.mThreadStackLock != NULL; +} + +} // namespace DeviceLayer +} // namespace chip + +using namespace ::chip::DeviceLayer; + +void ThreadStackManagerImpl::_ProcessThreadActivity() +{ + GenericThreadStackManagerImpl_OpenThread::_ProcessThreadActivity(); +} + +/** + * Glue function called directly by the OpenThread stack when tasklet processing work + * is pending. +// */ +extern "C" void otTaskletsSignalPending(otInstance * p_instance) +{ + ThreadStackMgrImpl().SignalThreadActivityPending(); +} + +/** + * Glue function called directly by the OpenThread stack when system event processing work + * is pending. + */ +extern "C" { +void otSysEventSignalPending(void) +{ + ChipLogProgress(DeviceLayer, "otSysEventSignalPending DEBUG THIS "); + // BaseType_t yieldRequired = ThreadStackMgrImpl().SignalThreadActivityPendingFromISR(); + // portYIELD_FROM_ISR(yieldRequired); +} +} +extern "C" { +void * otPlatCAlloc(size_t aNum, size_t aSize) +{ + return CHIPPlatformMemoryCalloc(aNum, aSize); +} +} + +extern "C" { +void otPlatFree(void * aPtr) +{ + CHIPPlatformMemoryFree(aPtr); +} +} diff --git a/src/platform/stm32/ThreadStackManagerImpl.h b/src/platform/stm32/ThreadStackManagerImpl.h new file mode 100644 index 00000000000000..d721c7f32c9ce8 --- /dev/null +++ b/src/platform/stm32/ThreadStackManagerImpl.h @@ -0,0 +1,128 @@ +/* + * + * Copyright (c) 2020 Project CHIP Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * @file + * Provides an implementation of the ThreadStackManager object + * for stm32 platforms and the OpenThread + * stack. + */ + +#pragma once + +#include +#include +#include +#include + +#include +#include + +extern "C" void otSysEventSignalPending(void); + +namespace chip { +namespace DeviceLayer { + +class ThreadStackManager; +class ThreadStackManagerImpl; +namespace Internal { +extern int GetEntropy(uint8_t * buf, size_t bufSize); +} + +/** + * Concrete implementation of the ThreadStackManager singleton object for stm32 platforms + * using the OpenThread stack. + */ +class ThreadStackManagerImpl final : public ThreadStackManager, + public Internal::GenericThreadStackManagerImpl_OpenThread, + public Internal::GenericThreadStackManagerImpl_FreeRTOS +{ + // Allow the ThreadStackManager interface class to delegate method calls to + // the implementation methods provided by this class. + friend class ThreadStackManager; + + // Allow the generic implementation base classes to call helper methods on + // this class. +#ifndef DOXYGEN_SHOULD_SKIP_THIS + friend Internal::GenericThreadStackManagerImpl_OpenThread; + friend Internal::GenericThreadStackManagerImpl_OpenThread; + friend Internal::GenericThreadStackManagerImpl_FreeRTOS; +#endif + + // Allow glue functions called by OpenThread to call helper methods on this + // class. + friend void ::otTaskletsSignalPending(otInstance * otInst); + friend void ::otSysEventSignalPending(void); + +public: + // ===== Platform-specific members that may be accessed directly by the application. + + using ThreadStackManager::InitThreadStack; + CHIP_ERROR InitThreadStack(otInstance * otInst); + void SendThreadmsg(); + + CHIP_ERROR SetThreadEnabled(bool val); + +protected: + CHIP_ERROR _StartThreadTask(); + + void _ProcessThreadActivity(); + +private: + // ===== Methods that implement the ThreadStackManager abstract interface. + + CHIP_ERROR _InitThreadStack(void); + + // ===== Members for internal use by the following friends. + + friend ThreadStackManager & ::chip::DeviceLayer::ThreadStackMgr(void); + friend ThreadStackManagerImpl & ::chip::DeviceLayer::ThreadStackMgrImpl(void); + friend int Internal::GetEntropy(uint8_t * buf, size_t bufSize); + + static ThreadStackManagerImpl sInstance; + + static bool IsInitialized(); + + // ===== Private members for use by this class only. + + ThreadStackManagerImpl() = default; +}; + +/** + * Returns the public interface of the ThreadStackManager singleton object. + * + * chip applications should use this to access features of the ThreadStackManager object + * that are common to all platforms. + */ +inline ThreadStackManager & ThreadStackMgr(void) +{ + return ThreadStackManagerImpl::sInstance; +} + +/** + * Returns the platform-specific implementation of the ThreadStackManager singleton object. + * + * chip applications can use this to gain access to features of the ThreadStackManager + * that are specific to the platform. + */ +inline ThreadStackManagerImpl & ThreadStackMgrImpl(void) +{ + return ThreadStackManagerImpl::sInstance; +} + +} // namespace DeviceLayer +} // namespace chip diff --git a/src/platform/stm32/args.gni b/src/platform/stm32/args.gni new file mode 100644 index 00000000000000..38080e25dd39ad --- /dev/null +++ b/src/platform/stm32/args.gni @@ -0,0 +1,53 @@ +# Copyright (c) 2023 Project CHIP Authors +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +import("//build_overrides/chip.gni") +import("//build_overrides/stm32_sdk.gni") + +import("${chip_root}/examples/platform/stm32/args.gni") + +# ARM architecture flags will be set based on stm32_family. +arm_platform_config = "${stm32_sdk_build_root}/stm32_arm.gni" +chip_device_platform = "stm32" + +# add board protector for stm32wb +chip_with_lwip = false +mbedtls_target = "${stm32_sdk_build_root}:mbedtls" + +# GLOBAL CONFIG +chip_monolithic_tests = false +chip_system_config_provide_statistics = false +chip_config_memory_management = "platform" + +# FREERTOS CONFIG +chip_stack_lock_tracking = "fatal" + +# SHELL CONFIG +chip_build_libshell = false + +# OPENTHREAD CONFIG +chip_enable_openthread = true + +# NFC CONFIG +chip_enable_nfc = false + +# INET CONFIG for thread +chip_inet_config_enable_ipv4 = false +chip_inet_config_enable_dns_resolver = false +chip_inet_config_enable_tcp_endpoint = false +chip_system_config_use_open_thread_inet_endpoints = true +chip_mdns = "platform" + +# OTA CONFIG +chip_enable_ota_requestor = false diff --git a/src/system/BUILD.gn b/src/system/BUILD.gn index 7ce311d6499f19..2eae6348e0b12d 100644 --- a/src/system/BUILD.gn +++ b/src/system/BUILD.gn @@ -62,6 +62,8 @@ if (chip_device_platform == "cc13x2_26x2") { import("//build_overrides/cyw30739_sdk.gni") } else if (chip_device_platform == "mt793x") { import("//build_overrides/mt793x_sdk.gni") +} else if (chip_device_platform == "stm32") { + import("//build_overrides/stm32_sdk.gni") } buildconfig_header("system_buildconfig") { @@ -177,6 +179,9 @@ source_set("system_config_header") { if (chip_device_platform == "cyw30739") { public_deps += [ "${cyw30739_sdk_build_root}:cyw30739_sdk" ] } + if (chip_device_platform == "stm32") { + public_deps += [ "${stm32_sdk_build_root}:stm32_sdk" ] + } # Add platform here as needed. } diff --git a/third_party/st/BUILD.gn b/third_party/st/BUILD.gn new file mode 100644 index 00000000000000..2868aa880a6b45 --- /dev/null +++ b/third_party/st/BUILD.gn @@ -0,0 +1,45 @@ +# Copyright (c) 2023 Project CHIP Authors +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +import("//build_overrides/chip.gni") +import("//build_overrides/stm32_sdk.gni") + +import("${chip_root}/src/platform/device.gni") +import("${stm32_sdk_build_root}/stm32_sdk.gni") + +declare_args() { + # Build target to use for STM32 SDK. Use this to set global SDK defines. + stm32_sdk_target = "" +} + +assert(stm32_sdk_target != "", "stm32_sdk_target must be specified") + +group("stm32_sdk") { + public_deps = [ stm32_sdk_target ] +} + +config("stm32_mbedtls_config") { + if (stm32_family == "stm32wb5") { + defines = [ "MBEDTLS_USER_CONFIG_FILE=" ] + + include_dirs = [ + chip_root, + "${chip_root}/examples/platform/stm32/config_files/STM32WB5/", + ] + } +} +mbedtls_target("mbedtls") { + public_configs = [ ":stm32_mbedtls_config" ] + public_deps = [ "${stm32_sdk_build_root}:stm32_sdk" ] +} diff --git a/third_party/st/FAMILY/BOARD/STM32WB5MM-DK_sdk.gn_helper b/third_party/st/FAMILY/BOARD/STM32WB5MM-DK_sdk.gn_helper new file mode 100644 index 00000000000000..0c79564e0d8c0a --- /dev/null +++ b/third_party/st/FAMILY/BOARD/STM32WB5MM-DK_sdk.gn_helper @@ -0,0 +1,77 @@ +# STM32WB5MM-DK_sdk.gn_helper + +import("//build_overrides/build.gni") +import("//build_overrides/chip.gni") + +declare_args() { + ## PATHS FOR STM32WB BOARD ## + stm32_board_src = "${chip_root}/examples/platform/stm32/common/STM32WB5MM-DK" + bsp_stm32wb5mm_dk = "${chip_root}/third_party/st/STM32CubeWB/Drivers/BSP/STM32WB5MM-DK" + components_common = "${chip_root}/third_party/st/STM32CubeWB/Drivers/BSP/Components/Common" + components_ssd1315 = "${chip_root}/third_party/st/STM32CubeWB/Drivers/BSP/Components/ssd1315" + components_s25fl128s = "${chip_root}/third_party/st/STM32CubeWB/Drivers/BSP/Components/s25fl128s" + + ## PATHS FOR ST UTILITIES ## + stm32_fonts_util = "${chip_root}/third_party/st/STM32CubeWB/Utilities/Fonts" + stm32_lcd_util = "${chip_root}/third_party/st/STM32CubeWB/Utilities/LCD" + stm32_lpm_util = "${chip_root}/third_party/st/STM32CubeWB/Utilities/lpm/tiny_lpm" +} + +SOURCES = [ + # BOARD APPLICATION SRC(in examples/platform/stm32/common/STM32WB5MM-DK/) + "${stm32_board_src}/Src/entropy_hardware_poll.c", + "${stm32_board_src}/Src/flash_driver.c", + "${stm32_board_src}/Src/flash_wb.c", + "${stm32_board_src}/Src/freertos_port.c", + "${stm32_board_src}/Src/hw_timerserver.c", + "${stm32_board_src}/Src/hw_uart.c", + "${stm32_board_src}/Src/stm32_lpm_if.c", + "${stm32_board_src}/Src/stm32wbxx_hal_msp.c", + "${stm32_board_src}/Src/stm32wbxx_hal_timebase_tim.c", + "${stm32_board_src}/Src/stm32wbxx_it.c", + "${stm32_board_src}/Src/stm_logging.c", + "${stm32_board_src}/Src/syscalls.c", + "${stm32_board_src}/Src/system_stm32wbxx.c", + "${stm32_board_src}/Src/otp.c", + "${stm32_board_src}/STM32_WPAN/Target/hw_ipcc.c", + + "${chip_root}/examples/platform/stm32/config_files/STM32WB5/matter_config.h", + "${chip_root}/examples/platform/stm32/config_files/STM32WB5/FreeRTOSConfig.h", + + #BSP DRIVERS + "${bsp_stm32wb5mm_dk}/stm32wb5mm_dk_bus.c", + "${bsp_stm32wb5mm_dk}/stm32wb5mm_dk_lcd.c", + "${bsp_stm32wb5mm_dk}/stm32wb5mm_dk.c", + + #BSP COMPONENTS + "${components_ssd1315}/ssd1315_reg.c", + "${components_ssd1315}/ssd1315.c", + + # BOARD UTILITIES + "${stm32_lpm_util}/stm32_lpm.c", + "${stm32_lcd_util}/stm32_lcd.c", + ] + +INCLUDE_DIRS = [ + "${components_common}", + "${components_s25fl128s}", + "${components_ssd1315}", + + "${bsp_stm32wb5mm_dk}", + + "${stm32_lpm_util}", + "${stm32_fonts_util}", + "${stm32_lcd_util}", + + "${stm32_board_src}/Inc", + "${stm32_board_src}/STM32_WPAN/App", + ] + +DEFINES = [ + ] + +LIBS = [ + ] + +FLAGS = [ + ] diff --git a/third_party/st/FAMILY/stm32wb5_sdk.gn_helper b/third_party/st/FAMILY/stm32wb5_sdk.gn_helper new file mode 100644 index 00000000000000..eb660301f13344 --- /dev/null +++ b/third_party/st/FAMILY/stm32wb5_sdk.gn_helper @@ -0,0 +1,173 @@ +# stm32wb5_sdk.gn_helper + +import("//build_overrides/build.gni") +import("//build_overrides/chip.gni") + +import("//build_overrides/freertos.gni") +import("//build_overrides/mbedtls.gni") +import("//build_overrides/lwip.gni") + +declare_args() { + + # CSMSIS PATHS # + cmsis = "${chip_root}/third_party/st/STM32CubeWB/Drivers/CMSIS" + + ## PATHS FOR STM32WB FAMILY ## + stm32_wb_sdk = "${chip_root}/third_party/st/STM32CubeWB/Drivers" + stm32_wb_hal = "${chip_root}/third_party/st/STM32CubeWB/Drivers/STM32WBxx_HAL_Driver" + cmsis_device_wb = "${chip_root}/third_party/st/STM32CubeWB/Drivers/CMSIS/Device/ST/STM32WBxx" + stm32_wpan_sdk = "${chip_root}/third_party/st/STM32CubeWB/Middlewares/ST/STM32_WPAN" + stm32_config_files = "${chip_root}/examples/platform/stm32/config_files/STM32WB5" + + ## PATHS FOR FREERTOS ## + freertos_st = "${chip_root}/third_party/st/STM32CubeWB/Middlewares/Third_Party/FreeRTOS/Source" + +} + +SOURCES = [ + #HAL DRIVERS + "${stm32_wb_hal}/Src/stm32wbxx_hal_cortex.c", + "${stm32_wb_hal}/Src/stm32wbxx_hal_dma.c", + "${stm32_wb_hal}/Src/stm32wbxx_hal_exti.c", + "${stm32_wb_hal}/Src/stm32wbxx_hal_flash_ex.c", + "${stm32_wb_hal}/Src/stm32wbxx_hal_flash.c", + "${stm32_wb_hal}/Src/stm32wbxx_hal_gpio.c", + "${stm32_wb_hal}/Src/stm32wbxx_hal_ipcc.c", + "${stm32_wb_hal}/Src/stm32wbxx_hal_pwr_ex.c", + "${stm32_wb_hal}/Src/stm32wbxx_hal_pwr.c", + "${stm32_wb_hal}/Src/stm32wbxx_hal_qspi.c", + "${stm32_wb_hal}/Src/stm32wbxx_hal_rcc_ex.c", + "${stm32_wb_hal}/Src/stm32wbxx_hal_rcc.c", + "${stm32_wb_hal}/Src/stm32wbxx_hal_rng.c", + "${stm32_wb_hal}/Src/stm32wbxx_hal_rtc_ex.c", + "${stm32_wb_hal}/Src/stm32wbxx_hal_rtc.c", + "${stm32_wb_hal}/Src/stm32wbxx_hal_spi_ex.c", + "${stm32_wb_hal}/Src/stm32wbxx_hal_spi.c", + "${stm32_wb_hal}/Src/stm32wbxx_hal_tim_ex.c", + "${stm32_wb_hal}/Src/stm32wbxx_hal_tim.c", + "${stm32_wb_hal}/Src/stm32wbxx_hal_uart_ex.c", + "${stm32_wb_hal}/Src/stm32wbxx_hal_uart.c", + "${stm32_wb_hal}/Src/stm32wbxx_hal.c", + + #WPAN + "${stm32_wpan_sdk}/ble/core/auto/ble_events.c", + "${stm32_wpan_sdk}/ble/core/auto/ble_gap_aci.c", + "${stm32_wpan_sdk}/ble/core/auto/ble_gatt_aci.c", + "${stm32_wpan_sdk}/ble/core/auto/ble_hal_aci.c", + "${stm32_wpan_sdk}/ble/core/auto/ble_hci_le.c", + "${stm32_wpan_sdk}/ble/core/auto/ble_l2cap_aci.c", + "${stm32_wpan_sdk}/ble/core/template/osal.c", + "${stm32_wpan_sdk}/ble/svc/Src/svc_ctl.c", + "${stm32_wpan_sdk}/interface/patterns/ble_thread/shci/shci.c", + "${stm32_wpan_sdk}/interface/patterns/ble_thread/tl/hci_tl_if.c", + "${stm32_wpan_sdk}/interface/patterns/ble_thread/tl/hci_tl.c", + "${stm32_wpan_sdk}/interface/patterns/ble_thread/tl/shci_tl_if.c", + "${stm32_wpan_sdk}/interface/patterns/ble_thread/tl/shci_tl.c", + "${stm32_wpan_sdk}/interface/patterns/ble_thread/tl/tl_mbox.c", + "${stm32_wpan_sdk}/interface/patterns/ble_thread/tl/tl_thread_hci.c", + "${stm32_wpan_sdk}/thread/openthread/core/openthread_api/channel_manager.c", + "${stm32_wpan_sdk}/thread/openthread/core/openthread_api/channel_monitor.c", + "${stm32_wpan_sdk}/thread/openthread/core/openthread_api/child_supervision.c", + "${stm32_wpan_sdk}/thread/openthread/core/openthread_api/coap.c", + "${stm32_wpan_sdk}/thread/openthread/core/openthread_api/commissioner.c", + "${stm32_wpan_sdk}/thread/openthread/core/openthread_api/crypto.c", + "${stm32_wpan_sdk}/thread/openthread/core/openthread_api/dataset_ftd.c", + "${stm32_wpan_sdk}/thread/openthread/core/openthread_api/dataset.c", + "${stm32_wpan_sdk}/thread/openthread/core/openthread_api/diag.c", + "${stm32_wpan_sdk}/thread/openthread/core/openthread_api/dns.c", + "${stm32_wpan_sdk}/thread/openthread/core/openthread_api/dns_server.c", + "${stm32_wpan_sdk}/thread/openthread/core/openthread_api/errors.c", + "${stm32_wpan_sdk}/thread/openthread/core/openthread_api/icmp6.c", + "${stm32_wpan_sdk}/thread/openthread/core/openthread_api/instance.c", + "${stm32_wpan_sdk}/thread/openthread/core/openthread_api/ip6.c", + "${stm32_wpan_sdk}/thread/openthread/core/openthread_api/jam_detection.c", + "${stm32_wpan_sdk}/thread/openthread/core/openthread_api/joiner.c", + "${stm32_wpan_sdk}/thread/openthread/core/openthread_api/link_raw.c", + "${stm32_wpan_sdk}/thread/openthread/core/openthread_api/link.c", + "${stm32_wpan_sdk}/thread/openthread/core/openthread_api/message.c", + "${stm32_wpan_sdk}/thread/openthread/core/openthread_api/netdata.c", + "${stm32_wpan_sdk}/thread/openthread/core/openthread_api/network_time.c", + "${stm32_wpan_sdk}/thread/openthread/core/openthread_api/openthread_api_config_ftd.h", + "${stm32_wpan_sdk}/thread/openthread/core/openthread_api/openthread_api_wb.c", + "${stm32_wpan_sdk}/thread/openthread/core/openthread_api/openthread.c", + "${stm32_wpan_sdk}/thread/openthread/core/openthread_api/radio.c", + "${stm32_wpan_sdk}/thread/openthread/core/openthread_api/server.c", + "${stm32_wpan_sdk}/thread/openthread/core/openthread_api/srp_client.c", + "${stm32_wpan_sdk}/thread/openthread/core/openthread_api/tasklet.c", + "${stm32_wpan_sdk}/thread/openthread/core/openthread_api/thread_ftd.c", + "${stm32_wpan_sdk}/thread/openthread/core/openthread_api/thread.c", + "${stm32_wpan_sdk}/thread/openthread/core/openthread_api/udp.c", + "${stm32_wpan_sdk}/utilities/dbg_trace.c", + "${stm32_wpan_sdk}/utilities/stm_list.c", + "${stm32_wpan_sdk}/utilities/stm_queue.c", + + #FREERTOS + "${stm32_config_files}/FreeRTOSConfig.h", + "${freertos_st}/CMSIS_RTOS_V2/cmsis_os2.c", + "${freertos_st}/croutine.c", + "${freertos_st}/event_groups.c", + "${freertos_st}/list.c", + "${freertos_st}/portable/GCC/ARM_CM4F/port.c", + "${freertos_st}/portable/MemMang/heap_4.c", + "${freertos_st}/queue.c", + "${freertos_st}/stream_buffer.c", + "${freertos_st}/tasks.c", + "${freertos_st}/timers.c", +] + +INCLUDE_DIRS = [ + "${chip_root}/examples/platform/stm32/config_files/STM32WB5/", + "${chip_root}/src/include/", + "${cmsis}/Include", + "${cmsis_device_wb}/Include", + "${stm32_wb_hal}/Inc", + "${stm32_wb_hal}/Inc/Legacy", + "${chip_root}/src/platform/stm32", + "${chip_root}/src/include/", + + #WPAN + "${stm32_wpan_sdk}/", + "${stm32_wpan_sdk}/interface/patterns/ble_thread/", + "${stm32_wpan_sdk}/interface/patterns/ble_thread/tl/", + "${stm32_wpan_sdk}/interface/patterns/ble_thread/shci/", + "${stm32_wpan_sdk}/ble/core/", + "${stm32_wpan_sdk}/ble/core/auto/", + "${stm32_wpan_sdk}/ble/core/template/", + "${stm32_wpan_sdk}/ble/svc/Inc/", + "${stm32_wpan_sdk}/ble/svc/Src/", + "${stm32_wpan_sdk}/ble/", + "${stm32_wpan_sdk}/thread/openthread/stack/include/openthread/", + "${stm32_wpan_sdk}/thread/openthread/stack/src/core/", + "${stm32_wpan_sdk}/thread/openthread/stack/src/core/config/", + "${stm32_wpan_sdk}/thread/openthread/stack/include/", + "${stm32_wpan_sdk}/thread/openthread/core/openthread_api/", + "${stm32_wpan_sdk}/thread/openthread/", + "${stm32_wpan_sdk}/interface/patterns/ble-thread/tl/", + "${stm32_wpan_sdk}/utilities/", + + #FREERTOS INCLUDES + "${freertos_st}/include", + "${stm32_config_files}/", + "${freertos_st}/portable/GCC/ARM_CM4F", + "${freertos_st}/portable", + "${freertos_st}/CMSIS_RTOS_V2", + +] + +DEFINES = [ + "CHIP_PROJECT_CONFIG_INCLUDE=", + "CHIP_HAVE_CONFIG_H", + "OPENTHREAD_CONFIG_FILE=", + "MBEDTLS_CONFIG_FILE=", + "CORE_CM4", + "THREAD_WB", + "STM32WB55xx", + "USE_STM32WB5M_DK", +] + +LIBS = [ + # add any .o/.a library here +] + +FLAGS = [ +] diff --git a/third_party/st/STM32CubeWB b/third_party/st/STM32CubeWB new file mode 160000 index 00000000000000..d23878380596ba --- /dev/null +++ b/third_party/st/STM32CubeWB @@ -0,0 +1 @@ +Subproject commit d23878380596ba031e33fcfa4841ff91aa1ab024 diff --git a/third_party/st/stm32_arm.gni b/third_party/st/stm32_arm.gni new file mode 100644 index 00000000000000..580506c483b5ca --- /dev/null +++ b/third_party/st/stm32_arm.gni @@ -0,0 +1,23 @@ +# Copyright (c) 2023 Project CHIP Authors +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +import("stm32_board.gni") + +if (stm32_family == "stm32wb55" || stm32_family == "stm32wb5") { + arm_arch = "armv7e-m" + arm_abi = "aapcs" + arm_cpu = "cortex-m4" + arm_float_abi = "hard" + arm_fpu = "fpv4-sp-d16" +} diff --git a/third_party/st/stm32_board.gni b/third_party/st/stm32_board.gni new file mode 100644 index 00000000000000..3d95d3576fb174 --- /dev/null +++ b/third_party/st/stm32_board.gni @@ -0,0 +1,36 @@ +# Copyright (c) 2023 Project CHIP Authors +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +declare_args() { + # STM32 board used + stm32_board = "" +} + +if (stm32_board == "") { + stm32_board = "STM32WB5MM-DK" +} + +assert(stm32_board != "", "stm32_board must be specified") + +# Differentiate between boards +# - STM32WB5MMG-DK / STM32WB55... / ZigBee-Thread 2.4GHz + +board_defines = [] + +if (stm32_board == "STM32WB5MM-DK") { + stm32_family = "stm32wb5" + stm32_mcu = "STM32WB5MMGHX" +} else { + assert(false, "The board ${stm32_board} not currently supported") +} diff --git a/third_party/st/stm32_executable.gni b/third_party/st/stm32_executable.gni new file mode 100644 index 00000000000000..fa2c8d14e28ee9 --- /dev/null +++ b/third_party/st/stm32_executable.gni @@ -0,0 +1,75 @@ +# Copyright (c) 2023 Project CHIP Authors +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +import("//build_overrides/build.gni") +import("//build_overrides/chip.gni") + +import("${build_root}/toolchain/flashable_executable.gni") + +template("stm32_executable") { + # -+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+- + # (Add .bin + .hex to .elf + flashing scripts in output dir/) + # -+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+- + + output_base_name = get_path_info(invoker.output_name, "name") + + objcopy_image_name = output_base_name + ".hex" + objcopy_image_format = "ihex" + objcopy = "arm-none-eabi-objcopy" + + # Copy flashing dependencies to the output directory so that the output + # is collectively self-contained; this allows flashing to work reliably + # even if the build and flashing steps take place on different machines + # or in different containers. + + flashing_runtime_target = target_name + ".flashing_runtime" + flashing_script_inputs = [ + "${chip_root}/scripts/flashing/stm32_firmware_utils.py", + "${chip_root}/scripts/flashing/firmware_utils.py", + ] + copy(flashing_runtime_target) { + sources = flashing_script_inputs + outputs = [ "${root_out_dir}/{{source_file_part}}" ] + } + + flashing_script_generator = + "${chip_root}/scripts/flashing/gen_flashing_script.py" + flashing_script_name = output_base_name + ".flash.py" + flashing_options = [ "stm32" ] + + flash_target_name = target_name + ".flash_executable" + flashbundle_name = "${target_name}.flashbundle.txt" + flashable_executable(flash_target_name) { + forward_variables_from(invoker, "*") + data_deps = [ ":${flashing_runtime_target}" ] + } + + # Add a target which generates the .bin file in addition to .hex. + executable_target = "$flash_target_name.executable" + bin_image_name = output_base_name + ".bin" + bin_target_name = target_name + ".bin" + objcopy_convert(bin_target_name) { + conversion_input = "${root_out_dir}/${invoker.output_name}" + conversion_output = "${root_out_dir}/${bin_image_name}" + conversion_target_format = "binary" + deps = [ ":$executable_target" ] + } + + group(target_name) { + deps = [ + ":$bin_target_name", + ":$flash_target_name", + ] + } +} diff --git a/third_party/st/stm32_sdk.gni b/third_party/st/stm32_sdk.gni new file mode 100644 index 00000000000000..eaa7775761ccbe --- /dev/null +++ b/third_party/st/stm32_sdk.gni @@ -0,0 +1,182 @@ +# Copyright (c) 2023 Project CHIP Authors +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +import("//build_overrides/build.gni") +import("//build_overrides/chip.gni") +import("//build_overrides/freertos.gni") +import("//build_overrides/mbedtls.gni") +import("//build_overrides/stm32_sdk.gni") + +import("${freertos_root}/freertos.gni") +import("${mbedtls_root}/mbedtls.gni") +import("stm32_board.gni") + +#import("${lwip_root}/lwip.gni") + +declare_args() { + kvs_max_entries = 75 + + use_external_flash = false + + stm32_sdk_root = "${chip_root}/third_party/st" + + stm32_ic_family = "STM32WB5MM-DK" +} + +if (stm32_family == "stm32wb5") { + use_stm32_wpan = true +} + +assert(stm32_sdk_root != "", "ST SDK root must be specified") + +# +# Defines an stm32 SDK build target. +# +# Parameters: +# stm32_sdk_root - The location of the stm32 SDK. +# sources - The sources files to build. +# +template("stm32_sdk") { + if (defined(invoker.stm32_sdk_root)) { + stm32_sdk_root = invoker.stm32_sdk_root + } + + assert(stm32_sdk_root != "", "stm32_sdk_root must be specified") + + use_stm32_wpan = false + if (defined(invoker.use_stm32_wpan)) { + if (invoker.use_stm32_wpan) { + use_stm32_wpan = true + } + } + + if (defined(invoker.stm32_target_ic)) { + stm_target_ic = invoker.stm32_target_ic + } + + sdk_target_name = target_name + + slist_stm32_board = + read_file("${stm32_sdk_root}/FAMILY/BOARD/${stm32_board}_sdk.gn_helper", + "scope") + slist_stm32_family = + read_file("${stm32_sdk_root}/FAMILY/${stm32_family}_sdk.gn_helper", + "scope") + + config("${sdk_target_name}_config") { + include_dirs = [] + + if (defined(invoker.include_dirs)) { + include_dirs += invoker.include_dirs + } + + libs = [ + # add any common .o/.a library here + ] + + # Treat these includes as system includes, so warnings in them are not fatal. + _include_dirs = [ + # common .h used by STM32 + ] + + defines = [ + # common defines + "DEBUG", + "USE_HAL_DRIVER", + ] + + # Note that we're setting the mbedTLS and PSA configuration files through a + # define. This means the build system by default does not pick up changes in + # the content of these, only when changing the filename itself. + # To fix this, these files are also manually depended upon in the source set + # declared in stm32_mbedtls_config further down this file. + if (stm32_family == "stm32wb5") { + defines += [ "MBEDTLS_USER_CONFIG_FILE=" ] + } + + if (defined(invoker.enable_sleepy_device)) { + if (invoker.enable_sleepy_device) { + defines += [ + "CHIP_DEVICE_CONFIG_ENABLE_SED=1", + "STM32_SLEEP_DEVICE", + ] + } + } + + _include_dirs += slist_stm32_board.INCLUDE_DIRS + _include_dirs += slist_stm32_family.INCLUDE_DIRS + + defines += slist_stm32_board.DEFINES + defines += slist_stm32_family.DEFINES + + libs += slist_stm32_board.LIBS + libs += slist_stm32_family.LIBS + + cflags = [] + foreach(include_dir, _include_dirs) { + cflags += [ "-isystem" + rebase_path(include_dir, root_build_dir) ] + } + + cflags += [ + "-Wno-maybe-uninitialized", + "-Wno-shadow", + ] + + cflags += slist_stm32_board.FLAGS + cflags += slist_stm32_family.FLAGS + + if (defined(invoker.defines)) { + defines += invoker.defines + } + } + + source_set("stm32_mbedtls_config") { + # We're setting the mbedTLS config flags here as the stm32_sdk target + # acts as the mbedTLS target for stm32 builds. We need this for the build + # system to recompile mbedTLS (= the SDK) when the mbedTLS config gets + # edited. + if (stm32_family == "stm32wb5") { + sources = [ + "${chip_root}/examples/platform/stm32/config_files/STM32WB5/FreeRTOSConfig.h", + "${chip_root}/examples/platform/stm32/config_files/STM32WB5/matter_config.h", + ] + } + + public_deps = [ "${chip_root}/src/crypto:crypto_buildconfig" ] + } + + source_set(sdk_target_name) { + if (defined(invoker.enable_sleepy_device)) { + } + + sources = slist_stm32_family.SOURCES + sources += slist_stm32_board.SOURCES + + if ((defined(invoker.show_qr_code) && invoker.show_qr_code) || + (defined(invoker.disable_lcd) && !invoker.disable_lcd)) { + sources += [ + # + # + ] + } + + public_deps = [ ":stm32_mbedtls_config" ] + + if (defined(invoker.sources)) { + sources += invoker.sources + } + + public_configs = [ ":${sdk_target_name}_config" ] + } +}